diff --git a/pjlib/include/pj/list.h b/pjlib/include/pj/list.h index fa667296d..1ca6445c7 100644 --- a/pjlib/include/pj/list.h +++ b/pjlib/include/pj/list.h @@ -170,6 +170,27 @@ PJ_IDECL(void) pj_list_insert_nodes_after(pj_list_type *lst, pj_list_type *nodes); +/** + * Insert a list to another list before the specified element position. + * + * @param pos The element to which the node will be inserted before. + * @param lst The list to be inserted. + */ +PJ_IDECL(void) pj_list_insert_list_before(pj_list_type *pos, + pj_list_type *lst); + + +/** + * Insert a list to another list after the specified element position. + * + * @param pos The element in the list which will precede the inserted + * list. + * @param lst The list to be inserted. + */ +PJ_IDECL(void) pj_list_insert_list_after(pj_list_type *pos, + pj_list_type *lst); + + /** * Remove elements from the source list, and insert them to the destination * list. The elements of the source list will occupy the diff --git a/pjlib/include/pj/list_i.h b/pjlib/include/pj/list_i.h index 90718d74d..cb134f264 100644 --- a/pjlib/include/pj/list_i.h +++ b/pjlib/include/pj/list_i.h @@ -54,6 +54,23 @@ PJ_IDEF(void) pj_list_insert_nodes_before(pj_list_type *pos, pj_list_type *lst) pj_list_insert_nodes_after(((pj_list*)pos)->prev, lst); } +PJ_IDEF(void) pj_list_insert_list_after(pj_list_type *pos, pj_list_type *lst) +{ + if (!pj_list_empty(lst)) { + pj_list *lst_last = (pj_list *) ((pj_list*)lst)->prev; + pj_list *pos_next = (pj_list *) ((pj_list*)pos)->next; + + pj_link_node(pos, (pj_list *) ((pj_list*)lst)->next); + pj_link_node(lst_last, pos_next); + pj_list_init(lst); + } +} + +PJ_IDEF(void) pj_list_insert_list_before(pj_list_type *pos, pj_list_type *lst) +{ + pj_list_insert_list_after(((pj_list*)pos)->prev, lst); +} + PJ_IDEF(void) pj_list_merge_last(pj_list_type *lst1, pj_list_type *lst2) { if (!pj_list_empty(lst2)) { diff --git a/pjsip/src/pjsua-lib/pjsua_acc.c b/pjsip/src/pjsua-lib/pjsua_acc.c index a72d1a278..b2a4df929 100644 --- a/pjsip/src/pjsua-lib/pjsua_acc.c +++ b/pjsip/src/pjsua-lib/pjsua_acc.c @@ -834,8 +834,7 @@ PJ_DEF(pj_status_t) pjsua_acc_modify( pjsua_acc_id acc_id, pjsip_name_addr *id_name_addr = NULL; pjsip_sip_uri *id_sip_uri = NULL; pjsip_sip_uri *reg_sip_uri = NULL; - pj_uint32_t local_route_crc, global_route_crc; - pjsip_route_hdr global_route; + pj_uint32_t local_route_crc; pjsip_route_hdr local_route; pj_str_t acc_proxy[PJSUA_ACC_MAX_PROXIES]; pj_bool_t update_reg = PJ_FALSE; @@ -887,6 +886,7 @@ PJ_DEF(pj_status_t) pjsua_acc_modify( pjsua_acc_id acc_id, /* Registrar URI */ if (pj_strcmp(&acc->cfg.reg_uri, &cfg->reg_uri) && cfg->reg_uri.slen) { pjsip_uri *reg_uri; + unsigned rcnt; /* Need to parse reg_uri to get the elements: */ reg_uri = pjsip_parse_uri(acc->pool, cfg->reg_uri.ptr, @@ -907,6 +907,23 @@ PJ_DEF(pj_status_t) pjsua_acc_modify( pjsua_acc_id acc_id, } reg_sip_uri = (pjsip_sip_uri*) pjsip_uri_get_uri(reg_uri); + + /* Clear route headers from the previous registrar. */ + rcnt = (unsigned)pj_list_size(&acc->route_set); + if (rcnt != pjsua_var.ua_cfg.outbound_proxy_cnt + acc->cfg.proxy_cnt) { + pjsip_route_hdr *hr; + unsigned i; + + for (i=pjsua_var.ua_cfg.outbound_proxy_cnt + acc->cfg.proxy_cnt, + hr=acc->route_set.prev; + iprev; + pj_list_erase(hr); + hr = prev; + } + } } /* REGISTER header list */ @@ -918,22 +935,6 @@ PJ_DEF(pj_status_t) pjsua_acc_modify( pjsua_acc_id acc_id, /* SUBSCRIBE header list */ update_hdr_list(acc->pool, &acc->cfg.sub_hdr_list, &cfg->sub_hdr_list); - /* Global outbound proxy */ - global_route_crc = calc_proxy_crc(pjsua_var.ua_cfg.outbound_proxy, - pjsua_var.ua_cfg.outbound_proxy_cnt); - if (global_route_crc != acc->global_route_crc) { - pjsip_route_hdr *r; - - /* Copy from global outbound proxies */ - pj_list_init(&global_route); - r = pjsua_var.outbound_proxy.next; - while (r != &pjsua_var.outbound_proxy) { - pj_list_push_back(&global_route, - pjsip_hdr_shallow_clone(acc->pool, r)); - r = r->next; - } - } - /* Account proxy */ local_route_crc = calc_proxy_crc(cfg->proxy, cfg->proxy_cnt); if (local_route_crc != acc->local_route_crc) { @@ -966,6 +967,33 @@ PJ_DEF(pj_status_t) pjsua_acc_modify( pjsua_acc_id acc_id, local_route_crc = calc_proxy_crc(acc_proxy, cfg->proxy_cnt); } + if (local_route_crc != acc->local_route_crc) { + unsigned i; + pjsip_route_hdr *r = &acc->route_set; + + /* Remove the current account proxies from the route set */ + for (i = 0; i < pjsua_var.ua_cfg.outbound_proxy_cnt; i++) + r = r->next; + for (i = 0; i < acc->cfg.proxy_cnt; ++i) { + pjsip_route_hdr *r_ = r->next; + pj_list_erase(r_); + } + + /* Insert new proxy setting to the route set */ + pj_list_insert_list_after(r, &local_route); + + /* Update the proxy setting */ + acc->cfg.proxy_cnt = cfg->proxy_cnt; + for (i = 0; i < cfg->proxy_cnt; ++i) + acc->cfg.proxy[i] = acc_proxy[i]; + + /* Update local route CRC */ + acc->local_route_crc = local_route_crc; + + update_reg = PJ_TRUE; + unreg_first = PJ_TRUE; + } + /* == Apply the new config == */ @@ -1160,53 +1188,6 @@ PJ_DEF(pj_status_t) pjsua_acc_modify( pjsua_acc_id acc_id, unreg_first = PJ_TRUE; } - /* Global outbound proxy */ - if (global_route_crc != acc->global_route_crc) { - unsigned i; - pj_size_t rcnt; - - /* Remove the outbound proxies from the route set */ - rcnt = pj_list_size(&acc->route_set); - for (i=0; i < rcnt - acc->cfg.proxy_cnt; ++i) { - pjsip_route_hdr *r = acc->route_set.next; - pj_list_erase(r); - } - - /* Insert the outbound proxies to the beginning of route set */ - pj_list_merge_first(&acc->route_set, &global_route); - - /* Update global route CRC */ - acc->global_route_crc = global_route_crc; - - update_reg = PJ_TRUE; - unreg_first = PJ_TRUE; - } - - /* Account proxy */ - if (local_route_crc != acc->local_route_crc) { - unsigned i; - - /* Remove the current account proxies from the route set */ - for (i=0; i < acc->cfg.proxy_cnt; ++i) { - pjsip_route_hdr *r = acc->route_set.prev; - pj_list_erase(r); - } - - /* Insert new proxy setting to the route set */ - pj_list_merge_last(&acc->route_set, &local_route); - - /* Update the proxy setting */ - acc->cfg.proxy_cnt = cfg->proxy_cnt; - for (i = 0; i < cfg->proxy_cnt; ++i) - acc->cfg.proxy[i] = acc_proxy[i]; - - /* Update local route CRC */ - acc->local_route_crc = local_route_crc; - - update_reg = PJ_TRUE; - unreg_first = PJ_TRUE; - } - /* Credential info */ { unsigned i;