Changeset 4586 for pjproject/trunk
- Timestamp:
- Sep 4, 2013 10:07:45 AM (11 years ago)
- Location:
- pjproject/trunk
- Files:
-
- 5 edited
Legend:
- Unmodified
- Added
- Removed
-
pjproject/trunk/pjsip/include/pjsip-ua/sip_regc.h
r4173 r4586 83 83 /** Type declaration for callback to receive registration result. */ 84 84 typedef void pjsip_regc_cb(struct pjsip_regc_cbparam *param); 85 86 /** 87 * Structure to hold parameters when calling application's callback 88 * specified in #pjsip_regc_set_reg_tsx_cb(). 89 * To update contact address, application can set the field contact_cnt 90 * and contact inside the callback. 91 */ 92 struct pjsip_regc_tsx_cb_param 93 { 94 struct pjsip_regc_cbparam cbparam; 95 int contact_cnt; 96 pj_str_t contact[PJSIP_REGC_MAX_CONTACT]; 97 }; 98 99 /** Type declaration for callback set in #pjsip_regc_set_reg_tsx_cb(). */ 100 typedef void pjsip_regc_tsx_cb(struct pjsip_regc_tsx_cb_param *param); 85 101 86 102 /** … … 192 208 193 209 /** 210 * Set callback to be called when the registration received a final response. 211 * This callback is different with the one specified during creation via 212 * #pjsip_regc_create(). This callback will be called for any final response 213 * (including 401/407/423) and before any subsequent requests are sent. 214 * In case of unregistration, this callback will not be called. 215 * 216 * @param regc The client registration structure. 217 * @param tsx_cb Pointer to callback function to receive registration status. 218 * 219 * @return PJ_SUCCESS on success. 220 */ 221 PJ_DECL(pj_status_t) pjsip_regc_set_reg_tsx_cb(pjsip_regc *regc, 222 pjsip_regc_tsx_cb *tsx_cb); 223 224 /** 194 225 * Set the "sent-by" field of the Via header for outgoing requests. 195 226 * -
pjproject/trunk/pjsip/include/pjsua-lib/pjsua.h
r4580 r4586 567 567 568 568 } pjsua_create_media_transport_flag; 569 570 571 /** 572 * This enumeration specifies the contact rewrite method. 573 */ 574 typedef enum pjsua_contact_rewrite_method 575 { 576 /** 577 * The Contact update will be done by sending unregistration 578 * to the currently registered Contact, while simultaneously sending new 579 * registration (with different Call-ID) for the updated Contact. 580 */ 581 PJSUA_CONTACT_REWRITE_UNREGISTER = 1, 582 583 /** 584 * The Contact update will be done in a single, current 585 * registration session, by removing the current binding (by setting its 586 * Contact's expires parameter to zero) and adding a new Contact binding, 587 * all done in a single request. 588 */ 589 PJSUA_CONTACT_REWRITE_NO_UNREG = 2, 590 591 /** 592 * The Contact update will be done when receiving any registration final 593 * response. If this flag is not specified, contact update will only be 594 * done upon receiving 2xx response. This flag MUST be used with 595 * PJSUA_CONTACT_REWRITE_UNREGISTER or PJSUA_CONTACT_REWRITE_NO_UNREG 596 * above to specify how the Contact update should be performed when 597 * receiving 2xx response. 598 */ 599 PJSUA_CONTACT_REWRITE_ALWAYS_UPDATE = 4 600 601 } pjsua_contact_rewrite_method; 569 602 570 603 … … 2541 2574 /** 2542 2575 * This macro specifies the default value for \a contact_rewrite_method 2543 * field in pjsua_acc_config. I specifieshow Contact update will be2576 * field in pjsua_acc_config. It specifies how Contact update will be 2544 2577 * done with the registration, if \a allow_contact_rewrite is enabled in 2545 * the account config. 2546 * 2547 * If set to 1, the Contact update will be done by sending unregistration 2548 * to the currently registered Contact, while simultaneously sending new 2549 * registration (with different Call-ID) for the updated Contact. 2550 * 2551 * If set to 2, the Contact update will be done in a single, current 2552 * registration session, by removing the current binding (by setting its 2553 * Contact's expires parameter to zero) and adding a new Contact binding, 2554 * all done in a single request. 2555 * 2556 * Value 1 is the legacy behavior. 2557 * 2558 * Default value: 2 2578 * the account config. See \a pjsua_contact_rewrite_method for the options. 2579 * 2580 * Value PJSUA_CONTACT_REWRITE_UNREGISTER(1) is the legacy behavior. 2581 * 2582 * Default value: PJSUA_CONTACT_REWRITE_NO_UNREG(2) | 2583 * PJSUA_CONTACT_REWRITE_ALWAYS_UPDATE(4) 2559 2584 */ 2560 2585 #ifndef PJSUA_CONTACT_REWRITE_METHOD 2561 # define PJSUA_CONTACT_REWRITE_METHOD 2 2586 # define PJSUA_CONTACT_REWRITE_METHOD (PJSUA_CONTACT_REWRITE_NO_UNREG | \ 2587 PJSUA_CONTACT_REWRITE_ALWAYS_UPDATE) 2562 2588 #endif 2563 2589 … … 3011 3037 /** 3012 3038 * Specify how Contact update will be done with the registration, if 3013 * \a allow_contact_rewrite is enabled. 3014 * 3015 * If set to 1, the Contact update will be done by sending unregistration 3016 * to the currently registered Contact, while simultaneously sending new 3017 * registration (with different Call-ID) for the updated Contact. 3018 * 3019 * If set to 2, the Contact update will be done in a single, current 3020 * registration session, by removing the current binding (by setting its 3021 * Contact's expires parameter to zero) and adding a new Contact binding, 3022 * all done in a single request. 3023 * 3024 * Value 1 is the legacy behavior. 3025 * 3026 * Default value: PJSUA_CONTACT_REWRITE_METHOD (2) 3039 * \a allow_contact_rewrite is enabled. The value is bitmask combination of 3040 * \a pjsua_contact_rewrite_method. See also pjsua_contact_rewrite_method. 3041 * 3042 * Value PJSUA_CONTACT_REWRITE_UNREGISTER(1) is the legacy behavior. 3043 * 3044 * Default value: PJSUA_CONTACT_REWRITE_METHOD 3045 * (PJSUA_CONTACT_REWRITE_NO_UNREG | PJSUA_CONTACT_REWRITE_ALWAYS_UPDATE) 3027 3046 */ 3028 3047 int contact_rewrite_method; -
pjproject/trunk/pjsip/src/pjsip-ua/sip_reg.c
r4548 r4586 76 76 void *token; 77 77 pjsip_regc_cb *cb; 78 pjsip_regc_tsx_cb *tsx_cb; 78 79 79 80 pj_str_t str_srv_url; … … 728 729 } 729 730 731 static void cbparam_init( struct pjsip_regc_cbparam *cbparam, 732 pjsip_regc *regc, 733 pj_status_t status, int st_code, 734 const pj_str_t *reason, 735 pjsip_rx_data *rdata, pj_int32_t expiration, 736 int contact_cnt, pjsip_contact_hdr *contact[]) 737 { 738 cbparam->regc = regc; 739 cbparam->token = regc->token; 740 cbparam->status = status; 741 cbparam->code = st_code; 742 cbparam->reason = *reason; 743 cbparam->rdata = rdata; 744 cbparam->contact_cnt = contact_cnt; 745 cbparam->expiration = expiration; 746 if (contact_cnt) { 747 pj_memcpy( cbparam->contact, contact, 748 contact_cnt*sizeof(pjsip_contact_hdr*)); 749 } 750 } 730 751 731 752 static void call_callback(pjsip_regc *regc, pj_status_t status, int st_code, … … 736 757 struct pjsip_regc_cbparam cbparam; 737 758 738 739 759 if (!regc->cb) 740 760 return; 741 761 742 cbparam.regc = regc; 743 cbparam.token = regc->token; 744 cbparam.status = status; 745 cbparam.code = st_code; 746 cbparam.reason = *reason; 747 cbparam.rdata = rdata; 748 cbparam.contact_cnt = contact_cnt; 749 cbparam.expiration = expiration; 750 if (contact_cnt) { 751 pj_memcpy( cbparam.contact, contact, 752 contact_cnt*sizeof(pjsip_contact_hdr*)); 753 } 754 762 cbparam_init(&cbparam, regc, status, st_code, reason, rdata, expiration, 763 contact_cnt, contact); 755 764 (*regc->cb)(&cbparam); 756 765 } … … 813 822 } 814 823 } 824 825 PJ_DEF(pj_status_t) pjsip_regc_set_reg_tsx_cb( pjsip_regc *regc, 826 pjsip_regc_tsx_cb *tsx_cb) 827 { 828 PJ_ASSERT_RETURN(regc, PJ_EINVAL); 829 regc->tsx_cb = tsx_cb; 830 return PJ_SUCCESS; 831 } 832 815 833 816 834 PJ_DEF(pj_status_t) pjsip_regc_set_via_sent_by( pjsip_regc *regc, … … 1036 1054 pjsip_transaction *tsx = event->body.tsx_state.tsx; 1037 1055 pj_bool_t handled = PJ_TRUE; 1056 pj_bool_t update_contact = PJ_FALSE; 1038 1057 1039 1058 pj_atomic_inc(regc->busy_ctr); … … 1055 1074 pjsip_transport_add_ref(regc->last_transport); 1056 1075 } 1076 } 1077 1078 if (regc->_delete_flag == 0 && regc->tsx_cb && 1079 regc->current_op == REGC_REGISTERING) 1080 { 1081 struct pjsip_regc_tsx_cb_param param; 1082 1083 param.contact_cnt = -1; 1084 cbparam_init(¶m.cbparam, regc, PJ_SUCCESS, tsx->status_code, 1085 &tsx->status_text, 1086 (event->body.tsx_state.type==PJSIP_EVENT_RX_MSG) ? 1087 event->body.tsx_state.src.rdata : NULL, 1088 -1, 0, NULL); 1089 1090 /* Call regc tsx callback before handling any response */ 1091 pj_lock_release(regc->lock); 1092 (*regc->tsx_cb)(¶m); 1093 pj_lock_acquire(regc->lock); 1094 1095 if (param.contact_cnt >= 0) { 1096 /* Since we receive non-2xx response, it means that (some) contact 1097 * bindings haven't been established so we can safely remove these 1098 * contact headers. This is to avoid removing non-existent contact 1099 * bindings later. 1100 */ 1101 if (tsx->status_code/100 != 2) { 1102 pjsip_contact_hdr *h; 1103 1104 h = regc->contact_hdr_list.next; 1105 while (h != ®c->contact_hdr_list) { 1106 pjsip_contact_hdr *next = h->next; 1107 1108 if (h->expires == -1) { 1109 pj_list_erase(h); 1110 } 1111 h = next; 1112 } 1113 } 1114 1115 /* Update contact address */ 1116 pjsip_regc_update_contact(regc, param.contact_cnt, param.contact); 1117 update_contact = PJ_TRUE; 1118 } 1057 1119 } 1058 1120 … … 1067 1129 regc->current_op = REGC_IDLE; 1068 1130 1069 status = pjsip_auth_clt_reinit_req( ®c->auth_sess, 1131 if (update_contact) { 1132 pjsip_msg *msg; 1133 pjsip_hdr *hdr, *ins_hdr; 1134 pjsip_contact_hdr *chdr; 1135 1136 /* Delete Contact headers, but we shouldn't delete headers 1137 * which are supposed to remove contact bindings since 1138 * we cannot reconstruct those headers. 1139 */ 1140 msg = tsx->last_tx->msg; 1141 hdr = msg->hdr.next; 1142 ins_hdr = &msg->hdr; 1143 while (hdr != &msg->hdr) { 1144 pjsip_hdr *next = hdr->next; 1145 1146 if (hdr->type == PJSIP_H_CONTACT) { 1147 chdr = (pjsip_contact_hdr *)hdr; 1148 if (chdr->expires != 0) { 1149 pj_list_erase(hdr); 1150 ins_hdr = next; 1151 } 1152 } 1153 hdr = next; 1154 } 1155 1156 /* Add Contact headers. */ 1157 chdr = regc->contact_hdr_list.next; 1158 while (chdr != ®c->contact_hdr_list) { 1159 pj_list_insert_before(ins_hdr, (pjsip_hdr*) 1160 pjsip_hdr_shallow_clone(tsx->last_tx->pool, chdr)); 1161 chdr = chdr->next; 1162 } 1163 1164 /* Also add bindings which are to be removed */ 1165 while (!pj_list_empty(®c->removed_contact_hdr_list)) { 1166 chdr = regc->removed_contact_hdr_list.next; 1167 pj_list_insert_before(ins_hdr, (pjsip_hdr*) 1168 pjsip_hdr_clone(tsx->last_tx->pool, chdr)); 1169 pj_list_erase(chdr); 1170 } 1171 } 1172 1173 status = pjsip_auth_clt_reinit_req( ®c->auth_sess, 1070 1174 rdata, 1071 1175 tsx->last_tx, -
pjproject/trunk/pjsip/src/pjsua-lib/pjsua_acc.c
r4580 r4586 1495 1495 /* Update NAT address from the REGISTER response */ 1496 1496 static pj_bool_t acc_check_nat_addr(pjsua_acc *acc, 1497 int contact_rewrite_method, 1497 1498 struct pjsip_regc_cbparam *param) 1498 1499 { … … 1679 1680 via_addr->ptr, 1680 1681 rport, 1681 acc->cfg.contact_rewrite_method)); 1682 1683 pj_assert(acc->cfg.contact_rewrite_method == 1 || 1684 acc->cfg.contact_rewrite_method == 2); 1685 1686 if (acc->cfg.contact_rewrite_method == 1) { 1682 contact_rewrite_method)); 1683 1684 pj_assert(contact_rewrite_method == PJSUA_CONTACT_REWRITE_UNREGISTER || 1685 contact_rewrite_method == PJSUA_CONTACT_REWRITE_NO_UNREG || 1686 contact_rewrite_method == PJSUA_CONTACT_REWRITE_ALWAYS_UPDATE); 1687 1688 if (contact_rewrite_method == PJSUA_CONTACT_REWRITE_UNREGISTER) { 1687 1689 /* Unregister current contact */ 1688 1690 pjsua_acc_set_registration(acc->index, PJ_FALSE); … … 1762 1764 } 1763 1765 1764 if (acc->cfg.contact_rewrite_method == 2 && acc->regc != NULL) { 1766 if (contact_rewrite_method == PJSUA_CONTACT_REWRITE_NO_UNREG && 1767 acc->regc != NULL) 1768 { 1765 1769 pjsip_regc_update_contact(acc->regc, 1, &acc->reg_contact); 1766 1770 } 1767 1771 1768 1772 /* Perform new registration */ 1769 pjsua_acc_set_registration(acc->index, PJ_TRUE); 1773 if (contact_rewrite_method < PJSUA_CONTACT_REWRITE_ALWAYS_UPDATE) { 1774 pjsua_acc_set_registration(acc->index, PJ_TRUE); 1775 } 1770 1776 1771 1777 pj_pool_release(pool); … … 2059 2065 } 2060 2066 2067 static void regc_tsx_cb(struct pjsip_regc_tsx_cb_param *param) 2068 { 2069 pjsua_acc *acc = (pjsua_acc*) param->cbparam.token; 2070 2071 PJSUA_LOCK(); 2072 2073 if (param->cbparam.regc != acc->regc) { 2074 PJSUA_UNLOCK(); 2075 return; 2076 } 2077 2078 pj_log_push_indent(); 2079 2080 if ((acc->cfg.contact_rewrite_method & 2081 PJSUA_CONTACT_REWRITE_ALWAYS_UPDATE) == 2082 PJSUA_CONTACT_REWRITE_ALWAYS_UPDATE && 2083 param->cbparam.code >= 400 && 2084 param->cbparam.rdata) 2085 { 2086 if (acc_check_nat_addr(acc, PJSUA_CONTACT_REWRITE_ALWAYS_UPDATE, 2087 ¶m->cbparam)) 2088 { 2089 param->contact_cnt = 1; 2090 param->contact[0] = acc->reg_contact; 2091 } 2092 } 2093 2094 PJSUA_UNLOCK(); 2095 pj_log_pop_indent(); 2096 } 2097 2061 2098 /* 2062 2099 * This callback is called by pjsip_regc when outgoing register … … 2127 2164 2128 2165 /* Check NAT bound address */ 2129 if (acc_check_nat_addr(acc, param)) { 2166 if (acc_check_nat_addr(acc, (acc->cfg.contact_rewrite_method & 3), 2167 param)) 2168 { 2130 2169 PJSUA_UNLOCK(); 2131 2170 pj_log_pop_indent(); … … 2271 2310 return status; 2272 2311 } 2312 2313 pjsip_regc_set_reg_tsx_cb(acc->regc, regc_tsx_cb); 2273 2314 2274 2315 /* If account is locked to specific transport, then set transport to -
pjproject/trunk/tests/pjsua/scripts-sipp/uas-register-ip-change.xml
r4547 r4586 8 8 <send> 9 9 <![CDATA[ 10 SIP/2.0 100 Trying 11 [last_Via:];received=1.1.1.1;rport=1111 12 [last_From:] 13 [last_To:];tag=[call_number] 14 [last_Call-ID:] 15 [last_CSeq:] 16 WWW-Authenticate: digest realm="test" 17 Content-Length: 0 18 ]]> 19 </send> 20 21 <pause milliseconds="2000"/> 22 23 <send> 24 <![CDATA[ 10 25 SIP/2.0 401 Unauthorized 11 [last_Via:];received= 1.1.1.1;rport=111126 [last_Via:];received=2.2.2.2;rport=2222 12 27 [last_From:] 13 28 [last_To:];tag=[call_number] … … 24 39 <send> 25 40 <![CDATA[ 41 SIP/2.0 401 Unauthorized again 42 [last_Via:];received=3.3.3.3;rport=3333 43 [last_From:] 44 [last_To:];tag=[call_number] 45 [last_Call-ID:] 46 [last_CSeq:] 47 [last_Contact:] 48 WWW-Authenticate: digest realm="test", stale=true 49 Content-Length: 0 50 ]]> 51 </send> 52 53 54 <recv request="REGISTER" crlf="true"> 55 </recv> 56 57 <send> 58 <![CDATA[ 26 59 SIP/2.0 200 OK 27 [last_Via:];received= 1.1.1.1;rport=111160 [last_Via:];received=4.4.4.4;rport=4444 28 61 [last_From:] 29 62 [last_To:];tag=[call_number] … … 35 68 </send> 36 69 37 <!-- REREGISTER --> 70 <!-- IP CHANGE FOR 200/OK --> 71 72 <recv request="REGISTER" crlf="true"> 73 </recv> 74 75 <send> 76 <![CDATA[ 77 SIP/2.0 401 Unauthorized 78 [last_Via:];received=5.5.5.5;rport=5555 79 [last_From:] 80 [last_To:];tag=[call_number] 81 [last_Call-ID:] 82 [last_CSeq:] 83 [last_Contact:] 84 WWW-Authenticate: digest realm="test" 85 Content-Length: 0 86 ]]> 87 </send> 88 89 <recv request="REGISTER" crlf="true"> 90 </recv> 91 92 <send> 93 <![CDATA[ 94 SIP/2.0 401 Nasty Unauthorized 95 [last_Via:];received=6.6.6.6;rport=6666 96 [last_From:] 97 [last_To:];tag=[call_number] 98 [last_Call-ID:] 99 [last_CSeq:] 100 [last_Contact:] 101 WWW-Authenticate: digest realm="test", stale=true 102 Content-Length: 0 103 ]]> 104 </send> 105 38 106 <recv request="REGISTER" crlf="true"> 39 107 </recv> … … 42 110 <![CDATA[ 43 111 SIP/2.0 200 OK 44 [last_Via:];received= 1.1.1.1;rport=1111112 [last_Via:];received=8.8.8.8;rport=8888 45 113 [last_From:] 46 114 [last_To:];tag=[call_number] … … 48 116 [last_CSeq:] 49 117 [last_Contact:] 50 Subject: Reregister due to IP change, this has two Contacts51 118 Content-Length: 0 52 119 ]]> 53 120 </send> 54 121 55 56 <!-- REFRESH, GOT IP CHANGE AGAIN -->57 122 <recv request="REGISTER" crlf="true"> 58 123 </recv> … … 61 126 <![CDATA[ 62 127 SIP/2.0 200 OK 63 [last_Via:];received= 2.2.2.2;rport=2222128 [last_Via:];received=8.8.8.8;rport=8888 64 129 [last_From:] 65 130 [last_To:];tag=[call_number] … … 67 132 [last_CSeq:] 68 133 [last_Contact:] 69 Subject: Refresh, got IP change again70 Content-Length: 071 ]]>72 </send>73 74 75 <!-- REREGISTER -->76 <recv request="REGISTER" crlf="true">77 </recv>78 79 <send>80 <![CDATA[81 SIP/2.0 200 OK82 [last_Via:];received=2.2.2.2;rport=222283 [last_From:]84 [last_To:];tag=[call_number]85 [last_Call-ID:]86 [last_CSeq:]87 [last_Contact:]88 Subject: Reregister due to IP change to 2.2.2.2, this has two Contacts89 Content-Length: 090 ]]>91 </send>92 93 94 <!-- WHATEVER -->95 <recv request="REGISTER" crlf="true">96 </recv>97 98 <send>99 <![CDATA[100 SIP/2.0 200 OK101 [last_Via:];received=2.2.2.2;rport=2222102 [last_From:]103 [last_To:];tag=[call_number]104 [last_Call-ID:]105 [last_CSeq:]106 [last_Contact:]107 Subject: Whatever 1108 Content-Length: 0109 ]]>110 </send>111 112 <!-- WHATEVER -->113 <recv request="REGISTER" crlf="true">114 </recv>115 116 <send>117 <![CDATA[118 SIP/2.0 200 OK119 [last_Via:];received=2.2.2.2;rport=2222120 [last_From:]121 [last_To:];tag=[call_number]122 [last_Call-ID:]123 [last_CSeq:]124 [last_Contact:]125 Subject: Whatever 2126 134 Content-Length: 0 127 135 ]]>
Note: See TracChangeset
for help on using the changeset viewer.