Changeset 141 for pjproject/trunk
- Timestamp:
- Feb 7, 2006 6:48:01 PM (19 years ago)
- Location:
- pjproject/trunk
- Files:
-
- 23 edited
Legend:
- Unmodified
- Added
- Removed
-
pjproject/trunk/pjlib/include/pj/config.h
r125 r141 176 176 * flag is set. 177 177 * 178 * Default: 800178 * Default: 1500 179 179 */ 180 180 #ifndef PJ_LOG_MAX_SIZE 181 # define PJ_LOG_MAX_SIZE 800181 # define PJ_LOG_MAX_SIZE 1500 182 182 #endif 183 183 -
pjproject/trunk/pjlib/include/pj/log.h
r125 r141 113 113 /** 114 114 * Default logging writer function used by front end logger function. 115 * This function will print the log message to stdout only. 115 116 * Application normally should NOT need to call this function, but 116 117 * rather use the PJ_LOG macro. -
pjproject/trunk/pjlib/src/pj/config.c
r108 r141 22 22 23 23 static const char *id = "config.c"; 24 const char *PJ_VERSION = "0.5 ";24 const char *PJ_VERSION = "0.5.1"; 25 25 26 26 PJ_DEF(void) pj_dump_config(void) -
pjproject/trunk/pjlib/src/pj/log.c
r125 r141 74 74 char log_buffer[PJ_LOG_MAX_SIZE]; 75 75 #endif 76 int len ;76 int len, print_len; 77 77 78 78 PJ_CHECK_STACK(); … … 138 138 139 139 /* Print the whole message to the string log_buffer. */ 140 len = len + vsnprintf(pre, sizeof(log_buffer)-len, format, marker); 140 print_len = vsnprintf(pre, sizeof(log_buffer)-len, format, marker); 141 if (print_len < 0) { 142 print_len = pj_snprintf(pre, sizeof(log_buffer)-len, 143 "<logging error: msg too long>"); 144 } 145 len = len + print_len; 141 146 if (len > 0 && len < sizeof(log_buffer)-2) { 142 147 if (log_decor & PJ_LOG_HAS_CR) { -
pjproject/trunk/pjsip/build/pjsip_core.dsp
r127 r141 180 180 181 181 SOURCE=..\src\pjsip\sip_util_statefull.c 182 # PROP Exclude_From_Build 1183 182 # End Source File 184 183 # End Group -
pjproject/trunk/pjsip/build/pjsip_ua.dsp
r139 r141 98 98 !ELSEIF "$(CFG)" == "pjsip_ua - Win32 Debug" 99 99 100 # PROP Exclude_From_Build 1101 102 100 !ENDIF 103 101 … … 107 105 108 106 # PROP Default_Filter "h;hpp;hxx;hm;inl" 107 # Begin Source File 108 109 SOURCE=..\include\pjsip_ua.h 110 # End Source File 109 111 # Begin Source File 110 112 -
pjproject/trunk/pjsip/build/pjsua.dsp
r139 r141 101 101 !ELSEIF "$(CFG)" == "pjsua - Win32 Debug" 102 102 103 !ENDIF 104 105 # End Source File 106 # Begin Source File 107 108 SOURCE=..\src\pjsua\main_old.c 109 110 !IF "$(CFG)" == "pjsua - Win32 Release" 111 112 !ELSEIF "$(CFG)" == "pjsua - Win32 Debug" 113 103 114 # PROP Exclude_From_Build 1 104 115 … … 111 122 # PROP Exclude_From_Build 1 112 123 # End Source File 124 # Begin Source File 125 126 SOURCE=..\src\pjsua\pjsua.c 127 # End Source File 128 # Begin Source File 129 130 SOURCE=..\src\pjsua\pjsua_reg.c 131 # End Source File 113 132 # End Group 114 133 # Begin Group "Header Files" … … 119 138 SOURCE=..\src\pjsua\getopt.h 120 139 # End Source File 140 # Begin Source File 141 142 SOURCE=..\src\pjsua\pjsua.h 143 # End Source File 121 144 # End Group 122 145 # Begin Group "Resource Files" -
pjproject/trunk/pjsip/include/pjsip-ua/sip_inv.h
r139 r141 39 39 PJSIP_INV_STATE_CONFIRMED, /**< After ACK is sent/received. */ 40 40 PJSIP_INV_STATE_DISCONNECTED, /**< Session is terminated. */ 41 PJSIP_INV_STATE_TERMINATED, /**< Session will be destroyed soon. */42 41 }; 43 42 -
pjproject/trunk/pjsip/include/pjsip-ua/sip_regc.h
r65 r141 27 27 #include <pjsip/sip_types.h> 28 28 #include <pjsip/sip_auth.h> 29 #include <pjsip_mod_ua/sip_ua.h>29 //#include <pjsip/sip_ua.h> 30 30 31 31 PJ_BEGIN_DECL … … 86 86 * @param token A data to be associated with the client registration struct. 87 87 * @param cb Pointer to callback function to receive registration status. 88 * 89 * @return client registration structure. 90 */ 91 PJ_DECL(pjsip_regc*) pjsip_regc_create( pjsip_endpoint *endpt, void *token, 92 pjsip_regc_cb *cb); 88 * @param p_regc Pointer to receive client registration structure. 89 * 90 * @return PJ_SUCCESS on success. 91 */ 92 PJ_DECL(pj_status_t) pjsip_regc_create( pjsip_endpoint *endpt, void *token, 93 pjsip_regc_cb *cb, 94 pjsip_regc **p_regc); 93 95 94 96 … … 99 101 * 100 102 * @param regc The client registration structure. 101 */ 102 PJ_DECL(void) pjsip_regc_destroy(pjsip_regc *regc); 103 * 104 * @return PJ_SUCCESS on success. 105 */ 106 PJ_DECL(pj_status_t) pjsip_regc_destroy(pjsip_regc *regc); 103 107 104 108 /** … … 138 142 * Set authentication credentials to use by this registration. 139 143 * 140 * @param dlg 141 * @param count 142 * @param cred 143 * 144 * @return Zeroon success.144 * @param dlg The registration structure. 145 * @param count Number of credentials in the array. 146 * @param cred Array of credentials. 147 * 148 * @return PJ_SUCCESS on success. 145 149 */ 146 150 PJ_DECL(pj_status_t) pjsip_regc_set_credentials( pjsip_regc *regc, … … 158 162 * @param autoreg If non zero, the library will automatically refresh the 159 163 * next registration until application unregister. 160 * 161 * @return SIP REGISTER request. 162 */ 163 PJ_DECL(pjsip_tx_data*) pjsip_regc_register(pjsip_regc *regc, pj_bool_t autoreg); 164 * @param p_tdata Pointer to receive the REGISTER request. 165 * 166 * @return PJ_SUCCESS on success. 167 */ 168 PJ_DECL(pj_status_t) pjsip_regc_register(pjsip_regc *regc, pj_bool_t autoreg, 169 pjsip_tx_data **p_tdata); 164 170 165 171 … … 168 174 * 169 175 * @param regc The client registration structure. 170 * 171 * @return SIP REGISTER request. 172 */ 173 PJ_DECL(pjsip_tx_data*) pjsip_regc_unregister(pjsip_regc *regc); 176 * @param p_tdata Pointer to receive the REGISTER request. 177 * 178 * @return PJ_SUCCESS on success. 179 */ 180 PJ_DECL(pj_status_t) pjsip_regc_unregister(pjsip_regc *regc, 181 pjsip_tx_data **p_tdata); 174 182 175 183 /** … … 202 210 * @param regc The client registration structure. 203 211 * @param tdata Transmit data. 204 */ 205 PJ_DECL(void) pjsip_regc_send(pjsip_regc *regc, pjsip_tx_data *tdata); 212 * 213 * @return PJ_SUCCESS on success. 214 */ 215 PJ_DECL(pj_status_t) pjsip_regc_send(pjsip_regc *regc, pjsip_tx_data *tdata); 206 216 207 217 -
pjproject/trunk/pjsip/include/pjsip/sip_dialog.h
r139 r141 68 68 69 69 /* Dialog's session properties. */ 70 pj_bool_t established;/**< Dialog is established? */ 70 71 pjsip_uri *target; /**< Current target. */ 71 72 pjsip_dlg_party local; /**< Local party info. */ -
pjproject/trunk/pjsip/include/pjsip_ua.h
r139 r141 21 21 22 22 #include <pjsip-ua/sip_inv.h> 23 #include <pjsip-ua/sip_regc.h> 24 23 25 24 26 #endif /* __PJSIP_UA_H__ */ -
pjproject/trunk/pjsip/src/pjsip-ua/sip_inv.c
r139 r141 107 107 static pj_bool_t mod_inv_on_rx_request(pjsip_rx_data *rdata) 108 108 { 109 pjsip_dialog *dlg; 110 109 111 /* Ignore requests outside dialog */ 110 if (pjsip_rdata_get_dlg(rdata) == NULL) 112 dlg = pjsip_rdata_get_dlg(rdata); 113 if (dlg == NULL) 111 114 return PJ_FALSE; 112 115 113 /* Ignore all. */ 116 /* Answer BYE with 200/OK. */ 117 if (rdata->msg_info.msg->line.req.method.id == PJSIP_BYE_METHOD) { 118 pj_status_t status; 119 pjsip_tx_data *tdata; 120 121 status = pjsip_dlg_create_response(dlg, rdata, 200, NULL, &tdata); 122 if (status == PJ_SUCCESS) 123 status = pjsip_dlg_send_response(dlg, pjsip_rdata_get_tsx(rdata), 124 tdata); 125 126 return status==PJ_SUCCESS ? PJ_TRUE : PJ_FALSE; 127 } 128 114 129 return PJ_FALSE; 115 130 } … … 915 930 916 931 case PJSIP_INV_STATE_DISCONNECTED: 917 case PJSIP_INV_STATE_TERMINATED:918 932 /* No need to do anything. */ 919 933 PJ_TODO(RETURN_A_PROPER_STATUS_CODE_HERE); … … 1067 1081 pjsip_transaction *tsx = e->body.tsx_state.tsx; 1068 1082 pjsip_dialog *dlg = pjsip_tsx_get_dlg(tsx); 1083 pj_status_t status; 1069 1084 1070 1085 PJ_ASSERT_ON_FAIL(tsx && dlg, return); 1071 1086 1072 if (tsx ->method.id == PJSIP_INVITE_METHOD) {1087 if (tsx == s->invite_tsx) { 1073 1088 1074 1089 switch (tsx->state) { … … 1093 1108 inv_set_state(s, PJSIP_INV_STATE_CONNECTING, e); 1094 1109 1110 } else if (tsx->status_code==401 || tsx->status_code==407) { 1111 1112 /* Handle authentication failure: 1113 * Resend the request with Authorization header. 1114 */ 1115 pjsip_tx_data *tdata; 1116 1117 status = pjsip_auth_clt_reinit_req(&s->dlg->auth_sess, 1118 e->body.tsx_state.src.rdata, 1119 tsx->last_tx, 1120 &tdata); 1121 1122 if (status != PJ_SUCCESS) { 1123 1124 /* Does not have proper credentials. 1125 * End the session. 1126 */ 1127 inv_set_state(s, PJSIP_INV_STATE_DISCONNECTED, e); 1128 1129 } else { 1130 1131 /* Restart session. */ 1132 s->state = PJSIP_INV_STATE_NULL; 1133 s->invite_tsx = NULL; 1134 1135 /* Send the request. */ 1136 status = pjsip_inv_send_msg(s, tdata, NULL ); 1137 } 1138 1095 1139 } else { 1140 1096 1141 inv_set_state(s, PJSIP_INV_STATE_DISCONNECTED, e); 1142 1097 1143 } 1098 1144 break; … … 1116 1162 } else { 1117 1163 inv_set_state(s, PJSIP_INV_STATE_DISCONNECTED, e); 1118 inv_set_state(s, PJSIP_INV_STATE_TERMINATED, e);1119 1164 } 1120 1165 break; … … 1136 1181 PJ_ASSERT_ON_FAIL(tsx && dlg, return); 1137 1182 1138 if (tsx ->method.id == PJSIP_INVITE_METHOD) {1183 if (tsx == s->invite_tsx) { 1139 1184 switch (tsx->state) { 1140 1185 case PJSIP_TSX_STATE_PROCEEDING: … … 1151 1196 /* This happens on transport error */ 1152 1197 inv_set_state(s, PJSIP_INV_STATE_DISCONNECTED, e); 1153 inv_set_state(s, PJSIP_INV_STATE_TERMINATED, e);1154 1198 break; 1155 1199 default: … … 1168 1212 PJ_ASSERT_ON_FAIL(tsx && dlg, return); 1169 1213 1170 if (tsx ->method.id == PJSIP_INVITE_METHOD) {1214 if (tsx == s->invite_tsx) { 1171 1215 1172 1216 switch (tsx->state) { … … 1207 1251 } else { 1208 1252 inv_set_state(s, PJSIP_INV_STATE_DISCONNECTED, e); 1209 inv_set_state(s, PJSIP_INV_STATE_TERMINATED, e);1210 1253 } 1211 1254 break; … … 1244 1287 } 1245 1288 1289 } else if (tsx->method.id == PJSIP_INVITE_METHOD) { 1290 1291 /* Ignore previously failed INVITE transaction event 1292 * (e.g. when rejected with 401/407) 1293 */ 1294 1246 1295 } else { 1247 1296 pj_assert(!"Unexpected transaction type"); … … 1256 1305 PJ_ASSERT_ON_FAIL(tsx && dlg, return); 1257 1306 1258 if (tsx ->method.id == PJSIP_INVITE_METHOD) {1307 if (tsx == s->invite_tsx) { 1259 1308 1260 1309 switch (tsx->state) { … … 1270 1319 if (tsx->status_code/100 != 2) { 1271 1320 inv_set_state(s, PJSIP_INV_STATE_DISCONNECTED, e); 1272 inv_set_state(s, PJSIP_INV_STATE_TERMINATED, e);1273 1321 } 1274 1322 break; … … 1297 1345 inv_set_state(s, PJSIP_INV_STATE_DISCONNECTED, e); 1298 1346 1299 } else if (tsx ->method.id == PJSIP_INVITE_METHOD) {1347 } else if (tsx == s->invite_tsx) { 1300 1348 1301 1349 switch (tsx->state) { … … 1308 1356 } 1309 1357 1358 } else if (tsx->method.id == PJSIP_INVITE_METHOD) { 1359 1360 /* Re-INVITE */ 1310 1361 1311 1362 } else { -
pjproject/trunk/pjsip/src/pjsip-ua/sip_reg.c
r65 r141 17 17 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 18 18 */ 19 #include <pjsip _mod_ua/sip_reg.h>19 #include <pjsip-ua/sip_regc.h> 20 20 #include <pjsip/sip_endpoint.h> 21 21 #include <pjsip/sip_parser.h> … … 25 25 #include <pjsip/sip_util.h> 26 26 #include <pjsip/sip_auth_msg.h> 27 #include <pjsip/sip_errno.h> 27 28 #include <pj/pool.h> 28 29 #include <pj/string.h> 29 30 #include <pj/guid.h> 30 31 #include <pj/log.h> 32 #include <pj/assert.h> 33 31 34 32 35 #define REFRESH_TIMER 1 … … 42 45 pjsip_endpoint *endpt; 43 46 pj_bool_t _delete_flag; 44 int pending_tsx;47 int pending_tsx; 45 48 46 49 void *token; 47 50 pjsip_regc_cb *cb; 48 51 49 pj_str_t str_srv_url;52 pj_str_t str_srv_url; 50 53 pjsip_uri *srv_url; 51 54 pjsip_cid_hdr *cid_hdr; … … 60 63 pj_uint32_t expires; 61 64 62 /* Credentials. */63 int cred_count;64 pjsip_cred_info *cred_info;65 66 65 /* Authorization sessions. */ 67 pjsip_auth_ session auth_sess_list;66 pjsip_auth_clt_sess auth_sess; 68 67 69 68 /* Auto refresh registration. */ … … 74 73 75 74 76 PJ_DEF(pjsip_regc*) pjsip_regc_create( pjsip_endpoint *endpt, void *token, 77 pjsip_regc_cb *cb) 75 PJ_DEF(pj_status_t) pjsip_regc_create( pjsip_endpoint *endpt, void *token, 76 pjsip_regc_cb *cb, 77 pjsip_regc **p_regc) 78 78 { 79 79 pj_pool_t *pool; 80 80 pjsip_regc *regc; 81 82 if (cb == NULL) 83 return NULL; 81 pj_status_t status; 82 83 /* Verify arguments. */ 84 PJ_ASSERT_RETURN(endpt && cb && p_regc, PJ_EINVAL); 84 85 85 86 pool = pjsip_endpt_create_pool(endpt, "regc%p", 1024, 1024); 86 regc = pj_pool_calloc(pool, 1, sizeof(struct pjsip_regc)); 87 PJ_ASSERT_RETURN(pool != NULL, PJ_ENOMEM); 88 89 regc = pj_pool_zalloc(pool, sizeof(struct pjsip_regc)); 87 90 88 91 regc->pool = pool; … … 93 96 regc->expires = PJSIP_REGC_EXPIRATION_NOT_SPECIFIED; 94 97 95 pj_list_init(®c->auth_sess_list); 96 97 return regc; 98 } 99 100 101 PJ_DEF(void) pjsip_regc_destroy(pjsip_regc *regc) 98 status = pjsip_auth_clt_init(®c->auth_sess, endpt, regc->pool, 0); 99 if (status != PJ_SUCCESS) 100 return status; 101 102 /* Done */ 103 *p_regc = regc; 104 return PJ_SUCCESS; 105 } 106 107 108 PJ_DEF(pj_status_t) pjsip_regc_destroy(pjsip_regc *regc) 102 109 { 103 110 if (regc->pending_tsx) { … … 105 112 regc->cb = NULL; 106 113 } else { 107 pjsip_endpt_destroy_pool(regc->endpt, regc->pool); 108 } 114 pjsip_endpt_release_pool(regc->endpt, regc->pool); 115 } 116 117 return PJ_SUCCESS; 109 118 } 110 119 … … 118 127 { 119 128 if (expires != regc->expires) { 120 regc->expires_hdr = pjsip_expires_hdr_create(regc->pool); 121 regc->expires_hdr->ivalue = expires; 129 regc->expires_hdr = pjsip_expires_hdr_create(regc->pool, expires); 122 130 } else { 123 131 regc->expires_hdr = NULL; … … 137 145 for (i=0, s=regc->contact_buf; i<contact_cnt; ++i) { 138 146 if ((s-regc->contact_buf) + contact[i].slen + 2 > PJSIP_REGC_CONTACT_BUF_SIZE) { 139 return -1;147 return PJSIP_EURITOOLONG; 140 148 } 141 149 pj_memcpy(s, contact[i].ptr, contact[i].slen); … … 149 157 150 158 /* Set "Contact" header. */ 151 regc->contact_hdr = pjsip_generic_string_hdr_create( regc->pool, &contact_STR); 159 regc->contact_hdr = pjsip_generic_string_hdr_create(regc->pool, 160 &contact_STR, 161 NULL); 152 162 regc->contact_hdr->hvalue.ptr = regc->contact_buf; 153 163 regc->contact_hdr->hvalue.slen = (s - regc->contact_buf); 154 164 155 return 0;165 return PJ_SUCCESS; 156 166 } 157 167 … … 166 176 { 167 177 pj_str_t tmp; 178 pj_status_t status; 179 180 PJ_ASSERT_RETURN(regc && srv_url && from_url && to_url && 181 contact_cnt && contact && expires, PJ_EINVAL); 168 182 169 183 /* Copy server URL. */ … … 174 188 regc->srv_url = pjsip_parse_uri( regc->pool, tmp.ptr, tmp.slen, 0); 175 189 if (regc->srv_url == NULL) { 176 return -1;190 return PJSIP_EINVALIDURI; 177 191 } 178 192 … … 183 197 PJSIP_PARSE_URI_AS_NAMEADDR); 184 198 if (!regc->from_hdr->uri) { 185 PJ_LOG(4,(THIS_FILE, "regc: invalid source URI %.*s", from_url->slen, from_url->ptr)); 186 return -1; 199 PJ_LOG(4,(THIS_FILE, "regc: invalid source URI %.*s", 200 from_url->slen, from_url->ptr)); 201 return PJSIP_EINVALIDURI; 187 202 } 188 203 … … 194 209 if (!regc->to_hdr->uri) { 195 210 PJ_LOG(4,(THIS_FILE, "regc: invalid target URI %.*s", to_url->slen, to_url->ptr)); 196 return -1;211 return PJSIP_EINVALIDURI; 197 212 } 198 213 199 214 200 215 /* Set "Contact" header. */ 201 if (set_contact( regc, contact_cnt, contact) != 0) 202 return -1; 216 status = set_contact( regc, contact_cnt, contact); 217 if (status != PJ_SUCCESS) 218 return status; 203 219 204 220 /* Set "Expires" header, if required. */ … … 219 235 220 236 /* Create "Expires" header used in unregistration. */ 221 regc->unreg_expires_hdr = pjsip_expires_hdr_create( regc->pool); 222 regc->unreg_expires_hdr->ivalue = 0; 237 regc->unreg_expires_hdr = pjsip_expires_hdr_create( regc->pool, 0); 223 238 224 239 /* Done. */ 225 return 0;240 return PJ_SUCCESS; 226 241 } 227 242 … … 230 245 const pjsip_cred_info cred[] ) 231 246 { 232 if (count > 0) { 233 regc->cred_info = pj_pool_alloc(regc->pool, count * sizeof(pjsip_cred_info)); 234 pj_memcpy(regc->cred_info, cred, count * sizeof(pjsip_cred_info)); 235 } 236 regc->cred_count = count; 237 return 0; 238 } 239 240 static pjsip_tx_data *create_request(pjsip_regc *regc) 241 { 247 PJ_ASSERT_RETURN(regc && count && cred, PJ_EINVAL); 248 return pjsip_auth_clt_set_credentials(®c->auth_sess, count, cred); 249 } 250 251 static pj_status_t create_request(pjsip_regc *regc, 252 pjsip_tx_data **p_tdata) 253 { 254 pj_status_t status; 242 255 pjsip_tx_data *tdata; 256 257 PJ_ASSERT_RETURN(regc && p_tdata, PJ_EINVAL); 258 259 /* Create the request. */ 260 status = pjsip_endpt_create_request_from_hdr( regc->endpt, 261 &pjsip_register_method, 262 regc->srv_url, 263 regc->from_hdr, 264 regc->to_hdr, 265 NULL, 266 regc->cid_hdr, 267 regc->cseq_hdr->cseq, 268 NULL, 269 &tdata); 270 if (status != PJ_SUCCESS) 271 return status; 272 273 /* Add cached authorization headers. */ 274 pjsip_auth_clt_init_req( ®c->auth_sess, tdata ); 275 276 /* Done. */ 277 *p_tdata = tdata; 278 return PJ_SUCCESS; 279 } 280 281 282 PJ_DEF(pj_status_t) pjsip_regc_register(pjsip_regc *regc, pj_bool_t autoreg, 283 pjsip_tx_data **p_tdata) 284 { 243 285 pjsip_msg *msg; 244 245 /* Create transmit data. */ 246 tdata = pjsip_endpt_create_tdata(regc->endpt); 247 if (!tdata) { 248 return NULL; 249 } 250 251 /* Create request message. */ 252 msg = pjsip_msg_create(tdata->pool, PJSIP_REQUEST_MSG); 253 tdata->msg = msg; 254 255 /* Initialize request line. */ 256 pjsip_method_set(&msg->line.req.method, PJSIP_REGISTER_METHOD); 257 msg->line.req.uri = regc->srv_url; 258 259 /* Add headers. */ 260 pjsip_msg_add_hdr(msg, (pjsip_hdr*) regc->from_hdr); 261 pjsip_msg_add_hdr(msg, (pjsip_hdr*) regc->to_hdr); 262 pjsip_msg_add_hdr(msg, (pjsip_hdr*) regc->cid_hdr); 263 pjsip_msg_add_hdr(msg, (pjsip_hdr*) regc->cseq_hdr); 264 265 /* Add cached authorization headers. */ 266 pjsip_auth_init_req( regc->pool, tdata, ®c->auth_sess_list, 267 regc->cred_count, regc->cred_info ); 268 269 /* Add reference counter to transmit data. */ 270 pjsip_tx_data_add_ref(tdata); 271 272 return tdata; 273 } 274 275 276 PJ_DEF(pjsip_tx_data*) pjsip_regc_register(pjsip_regc *regc, pj_bool_t autoreg) 277 { 278 pjsip_msg *msg; 286 pj_status_t status; 279 287 pjsip_tx_data *tdata; 280 288 281 tdata = create_request(regc); 282 if (!tdata) 283 return NULL; 284 289 status = create_request(regc, &tdata); 290 if (status != PJ_SUCCESS) 291 return status; 292 293 /* Add Contact header. */ 285 294 msg = tdata->msg; 286 295 pjsip_msg_add_hdr(msg, (pjsip_hdr*) regc->contact_hdr); … … 295 304 regc->auto_reg = autoreg; 296 305 297 return tdata; 298 } 299 300 301 PJ_DEF(pjsip_tx_data*) pjsip_regc_unregister(pjsip_regc *regc) 306 /* Done */ 307 *p_tdata = tdata; 308 return PJ_SUCCESS; 309 } 310 311 312 PJ_DEF(pj_status_t) pjsip_regc_unregister(pjsip_regc *regc, 313 pjsip_tx_data **p_tdata) 302 314 { 303 315 pjsip_tx_data *tdata; 304 316 pjsip_msg *msg; 317 pj_status_t status; 305 318 306 319 if (regc->timer.id != 0) { … … 309 322 } 310 323 311 tdata = create_request(regc);312 if ( !tdata)313 return NULL;324 status = create_request(regc, &tdata); 325 if (status != PJ_SUCCESS) 326 return status; 314 327 315 328 msg = tdata->msg; … … 317 330 pjsip_msg_add_hdr( msg, (pjsip_hdr*)regc->unreg_expires_hdr); 318 331 319 return tdata; 332 *p_tdata = tdata; 333 return PJ_SUCCESS; 320 334 } 321 335 … … 333 347 { 334 348 set_expires( regc, expires ); 335 return 0;349 return PJ_SUCCESS; 336 350 } 337 351 … … 364 378 pjsip_regc *regc = entry->user_data; 365 379 pjsip_tx_data *tdata; 380 pj_status_t status; 366 381 367 PJ_UNUSED_ARG(timer_heap) 382 PJ_UNUSED_ARG(timer_heap); 368 383 369 384 entry->id = 0; 370 tdata = pjsip_regc_register(regc, 1);371 if ( tdata) {385 status = pjsip_regc_register(regc, 1, &tdata); 386 if (status == PJ_SUCCESS) { 372 387 pjsip_regc_send(regc, tdata); 373 388 } else { 374 pj_str_t reason = pj_str("Unable to create txdata"); 389 char errmsg[PJ_ERR_MSG_SIZE]; 390 pj_str_t reason = pj_strerror(status, errmsg, sizeof(errmsg)); 375 391 call_callback(regc, -1, &reason, NULL, -1, 0, NULL); 376 392 } … … 379 395 static void tsx_callback(void *token, pjsip_event *event) 380 396 { 397 pj_status_t status; 381 398 pjsip_regc *regc = token; 382 pjsip_transaction *tsx = event-> obj.tsx;399 pjsip_transaction *tsx = event->body.tsx_state.tsx; 383 400 384 401 /* If registration data has been deleted by user then remove registration … … 391 408 tsx->status_code == PJSIP_SC_UNAUTHORIZED) 392 409 { 393 pjsip_rx_data *rdata = event-> src.rdata;410 pjsip_rx_data *rdata = event->body.tsx_state.src.rdata; 394 411 pjsip_tx_data *tdata; 395 412 396 tdata = pjsip_auth_reinit_req( regc->endpt,397 regc->pool, ®c->auth_sess_list,398 regc->cred_count, regc->cred_info,399 tsx->last_tx, event->src.rdata);400 401 if ( tdata) {413 status = pjsip_auth_clt_reinit_req( ®c->auth_sess, 414 rdata, 415 tsx->last_tx, 416 &tdata); 417 418 if (status == PJ_SUCCESS) { 402 419 --regc->pending_tsx; 403 420 pjsip_regc_send(regc, tdata); 404 421 return; 405 422 } else { 406 call_callback(regc, tsx->status_code, &rdata->msg ->line.status.reason,423 call_callback(regc, tsx->status_code, &rdata->msg_info.msg->line.status.reason, 407 424 rdata, -1, 0, NULL); 408 425 --regc->pending_tsx; … … 420 437 pjsip_expires_hdr *expires; 421 438 422 rdata = event-> src.rdata;423 msg = rdata->msg ;439 rdata = event->body.tsx_state.src.rdata; 440 msg = rdata->msg_info.msg; 424 441 hdr = pjsip_msg_find_hdr( msg, PJSIP_H_CONTACT, NULL); 425 442 while (hdr) { … … 460 477 461 478 } else { 462 rdata = (event->src_type==PJSIP_EVENT_RX_MSG) ? event->src.rdata : NULL; 479 rdata = (event->body.tsx_state.type==PJSIP_EVENT_RX_MSG) ? 480 event->body.tsx_state.src.rdata : NULL; 463 481 } 464 482 … … 467 485 if (expiration == 0xFFFF) expiration = -1; 468 486 call_callback(regc, tsx->status_code, 469 (rdata ? &rdata->msg ->line.status.reason487 (rdata ? &rdata->msg_info.msg->line.status.reason 470 488 : pjsip_get_status_text(tsx->status_code)), 471 489 rdata, expiration, … … 481 499 } 482 500 483 PJ_DEF( void) pjsip_regc_send(pjsip_regc *regc, pjsip_tx_data *tdata)484 { 485 int status;501 PJ_DEF(pj_status_t) pjsip_regc_send(pjsip_regc *regc, pjsip_tx_data *tdata) 502 { 503 pj_status_t status; 486 504 487 505 /* Make sure we don't have pending transaction. */ … … 490 508 call_callback(regc, -1, &reason, NULL, -1, 0, NULL); 491 509 pjsip_tx_data_dec_ref( tdata ); 492 return ;510 return PJ_EINVALIDOP; 493 511 } 494 512 … … 501 519 /* Send. */ 502 520 status = pjsip_endpt_send_request(regc->endpt, tdata, -1, regc, &tsx_callback); 503 if (status== 0)521 if (status==PJ_SUCCESS) 504 522 ++regc->pending_tsx; 505 523 else { 506 pj_str_t reason = pj_str("Unable to send request."); 524 char errmsg[PJ_ERR_MSG_SIZE]; 525 pj_str_t reason = pj_strerror(status, errmsg, sizeof(errmsg)); 507 526 call_callback(regc, status, &reason, NULL, -1, 0, NULL); 508 527 } 509 } 510 511 528 529 return status; 530 } 531 532 -
pjproject/trunk/pjsip/src/pjsip/sip_auth_client.c
r127 r141 395 395 const pjsip_cred_info *c) 396 396 { 397 PJ_ASSERT_RETURN(sess && cred_cnt && c, PJ_EINVAL); 398 399 sess->cred_info = pj_pool_alloc(sess->pool, cred_cnt * sizeof(*c)); 400 pj_memcpy(sess->cred_info, c, cred_cnt * sizeof(*c)); 401 sess->cred_cnt = cred_cnt; 397 PJ_ASSERT_RETURN(sess && c, PJ_EINVAL); 398 399 if (cred_cnt == 0) { 400 sess->cred_cnt = 0; 401 } else { 402 sess->cred_info = pj_pool_alloc(sess->pool, cred_cnt * sizeof(*c)); 403 pj_memcpy(sess->cred_info, c, cred_cnt * sizeof(*c)); 404 sess->cred_cnt = cred_cnt; 405 } 402 406 403 407 return PJ_SUCCESS; … … 522 526 } 523 527 } 528 529 # if defined(PJSIP_AUTH_AUTO_SEND_NEXT) && PJSIP_AUTH_AUTO_SEND_NEXT!=0 530 if (hdr != cached_auth->last_chal) { 531 cached_auth->last_chal = pjsip_hdr_clone(sess_pool, hdr); 532 } 533 # endif 524 534 } 525 535 # endif -
pjproject/trunk/pjsip/src/pjsip/sip_dialog.c
r139 r141 698 698 } 699 699 700 /* Copy authorization headers. */ 701 status = pjsip_auth_clt_init_req( &dlg->auth_sess, tdata ); 702 if (status != PJ_SUCCESS) 703 return status; 700 /* Copy authorization headers, if request is not ACK or CANCEL. */ 701 if (method->id != PJSIP_ACK_METHOD && method->id != PJSIP_CANCEL_METHOD) { 702 status = pjsip_auth_clt_init_req( &dlg->auth_sess, tdata ); 703 if (status != PJ_SUCCESS) 704 return status; 705 } 704 706 705 707 /* Done. */ … … 1133 1135 { 1134 1136 unsigned i; 1137 int res_code; 1135 1138 1136 1139 /* Lock the dialog. */ … … 1140 1143 pj_assert(pjsip_rdata_get_dlg(rdata) == dlg); 1141 1144 1142 /* Update the remote tag , if none is specified yet. */1143 if ( dlg->remote.info->tag.slen == 0 && rdata->msg_info.to->tag.slen!= 0) {1145 /* Update the remote tag if it is different. */ 1146 if (pj_strcmp(&dlg->remote.info->tag, &rdata->msg_info.to->tag) != 0) { 1144 1147 1145 1148 pj_strdup(dlg->pool, &dlg->remote.info->tag, &rdata->msg_info.to->tag); … … 1148 1151 } 1149 1152 1150 /* Update remote target when receiving certain response messages. */ 1151 if (pjsip_method_creates_dialog(&rdata->msg_info.cseq->method) && 1152 rdata->msg_info.msg->line.status.code/100 == 2) 1153 /* Keep the response's status code */ 1154 res_code = rdata->msg_info.msg->line.status.code; 1155 1156 /* When we receive response that establishes dialog, update the route 1157 * set and dialog target. 1158 */ 1159 if (!dlg->established && 1160 pjsip_method_creates_dialog(&rdata->msg_info.cseq->method) && 1161 (res_code > 100 && res_code < 300) && 1162 rdata->msg_info.to->tag.slen) 1153 1163 { 1164 /* RFC 3271 Section 12.1.2: 1165 * The route set MUST be set to the list of URIs in the Record-Route 1166 * header field from the response, taken in reverse order and 1167 * preserving all URI parameters. If no Record-Route header field 1168 * is present in the response, the route set MUST be set to the 1169 * empty set. This route set, even if empty, overrides any pre-existing 1170 * route set for future requests in this dialog. 1171 */ 1172 pjsip_hdr *hdr, *end_hdr; 1154 1173 pjsip_contact_hdr *contact; 1155 1174 1175 pj_list_init(&dlg->route_set); 1176 1177 end_hdr = &rdata->msg_info.msg->hdr; 1178 for (hdr=rdata->msg_info.msg->hdr.prev; hdr!=end_hdr; hdr=hdr->prev) { 1179 if (hdr->type == PJSIP_H_RECORD_ROUTE) { 1180 pjsip_route_hdr *r; 1181 r = pjsip_hdr_clone(dlg->pool, hdr); 1182 pjsip_routing_hdr_set_route(r); 1183 pj_list_push_back(&dlg->route_set, r); 1184 } 1185 } 1186 1187 /* The remote target MUST be set to the URI from the Contact header 1188 * field of the response. 1189 */ 1156 1190 contact = pjsip_msg_find_hdr(rdata->msg_info.msg, PJSIP_H_CONTACT, 1157 1191 NULL); … … 1160 1194 dlg->target = dlg->remote.contact->uri; 1161 1195 } 1162 } 1196 1197 dlg->established = 1; 1198 } 1199 1200 /* Update remote target (again) when receiving 2xx response messages 1201 * that's defined as target refresh. 1202 */ 1203 if (pjsip_method_creates_dialog(&rdata->msg_info.cseq->method) && 1204 res_code/100 == 2) 1205 { 1206 pjsip_contact_hdr *contact; 1207 1208 contact = pjsip_msg_find_hdr(rdata->msg_info.msg, PJSIP_H_CONTACT, 1209 NULL); 1210 if (contact) { 1211 dlg->remote.contact = pjsip_hdr_clone(dlg->pool, contact); 1212 dlg->target = dlg->remote.contact->uri; 1213 } 1214 } 1215 1163 1216 1164 1217 /* Pass to dialog usages. */ -
pjproject/trunk/pjsip/src/pjsip/sip_endpoint.c
r139 r141 104 104 pj_status_t pjsip_tel_uri_subsys_init(void); 105 105 106 /* Defined in sip_util_statefull.c */ 107 extern pjsip_module mod_stateful_util; 106 108 107 109 /* … … 490 492 /* Initialize capability header list. */ 491 493 pj_list_init(&endpt->cap_hdr); 494 495 /* Register mod_stateful_util module (sip_util_statefull.c) */ 496 status = pjsip_endpt_register_module(endpt, &mod_stateful_util); 497 if (status != PJ_SUCCESS) 498 goto on_error; 492 499 493 500 /* Done. */ -
pjproject/trunk/pjsip/src/pjsip/sip_transaction.c
r139 r141 2196 2196 2197 2197 } else if (tsx->status_code >= 300 && tsx->status_code <= 699) { 2198 2199 2200 #if 0 2201 /* XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX */ 2202 /* 2203 * This is the old code; it's broken for authentication. 2204 */ 2198 2205 pj_time_val timeout; 2199 2206 pj_status_t status; … … 2243 2250 tsx_set_state( tsx, PJSIP_TSX_STATE_COMPLETED, 2244 2251 PJSIP_EVENT_RX_MSG, event->body.rx_msg.rdata ); 2252 2253 /* XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX */ 2254 #endif 2255 2256 /* New code, taken from 0.2.9.x branch */ 2257 pj_time_val timeout; 2258 pjsip_tx_data *ack_tdata = NULL; 2259 2260 /* Stop timer B. */ 2261 pjsip_endpt_cancel_timer( tsx->endpt, &tsx->timeout_timer ); 2262 2263 /* Generate ACK now (for INVITE) but send it later because 2264 * dialog need to use last_tx. 2265 */ 2266 if (tsx->method.id == PJSIP_INVITE_METHOD) { 2267 pj_status_t status; 2268 2269 status = pjsip_endpt_create_ack( tsx->endpt, tsx->last_tx, 2270 event->body.rx_msg.rdata, 2271 &ack_tdata); 2272 if (status != PJ_SUCCESS) 2273 return status; 2274 } 2275 2276 /* Inform TU. */ 2277 tsx_set_state( tsx, PJSIP_TSX_STATE_COMPLETED, 2278 PJSIP_EVENT_RX_MSG, event->body.rx_msg.rdata); 2279 2280 /* Generate and send ACK for INVITE. */ 2281 if (tsx->method.id == PJSIP_INVITE_METHOD) { 2282 pj_status_t status; 2283 2284 status = tsx_send_msg( tsx, ack_tdata); 2285 2286 if (ack_tdata != tsx->last_tx) { 2287 pjsip_tx_data_dec_ref(tsx->last_tx); 2288 tsx->last_tx = ack_tdata; 2289 pjsip_tx_data_add_ref(ack_tdata); 2290 } 2291 2292 if (status != PJ_SUCCESS) { 2293 return status; 2294 } 2295 } 2296 2297 /* Start Timer D with TD/T4 timer if unreliable transport is used. */ 2298 if (PJSIP_TRANSPORT_IS_RELIABLE(tsx->transport) == 0) { 2299 if (tsx->method.id == PJSIP_INVITE_METHOD) { 2300 timeout = td_timer_val; 2301 } else { 2302 timeout = t4_timer_val; 2303 } 2304 } else { 2305 timeout.sec = timeout.msec = 0; 2306 } 2307 pjsip_endpt_schedule_timer( tsx->endpt, &tsx->timeout_timer, &timeout); 2245 2308 2246 2309 } else { -
pjproject/trunk/pjsip/src/pjsip/sip_ua_layer.c
r139 r141 618 618 * Request will fork only for the initial INVITE request. 619 619 */ 620 if (rdata->msg_info.cseq->method.id == PJSIP_INVITE_METHOD && 621 rdata->msg_info.cseq->cseq == dlg_set->dlg_list.next->local.first_cseq) 622 { 620 621 //This doesn't work when there is authentication challenge, since 622 //first_cseq evaluation will yield false. 623 //if (rdata->msg_info.cseq->method.id == PJSIP_INVITE_METHOD && 624 // rdata->msg_info.cseq->cseq == dlg_set->dlg_list.next->local.first_cseq) 625 626 if (rdata->msg_info.cseq->method.id == PJSIP_INVITE_METHOD) { 623 627 pj_str_t *to_tag = &rdata->msg_info.to->tag; 624 628 … … 627 631 628 632 dlg = dlg_set->dlg_list.next; 633 634 /* Forking handling is temporarily disabled. */ 635 PJ_TODO(UA_LAYER_HANDLE_FORKING); 636 637 #if 0 629 638 while (dlg != (pjsip_dialog*)&dlg_set->dlg_list) { 630 639 … … 670 679 } 671 680 } 681 #endif 672 682 673 683 /* Done with the dialog set. */ -
pjproject/trunk/pjsip/src/pjsip/sip_util.c
r139 r141 442 442 const pjsip_cseq_hdr *cseq_hdr; 443 443 const pjsip_hdr *hdr; 444 pjsip_hdr *via; 444 445 pjsip_to_hdr *to; 445 446 pj_status_t status; 446 447 447 /* rdata must be a final response. */448 /* rdata must be a non-2xx final response. */ 448 449 pj_assert(rdata->msg_info.msg->type==PJSIP_RESPONSE_MSG && 449 450 rdata->msg_info.msg->line.status.code >= 300); … … 488 489 pj_strdup(ack->pool, &to->tag, &rdata->msg_info.to->tag); 489 490 491 492 /* Clear Via headers in the new request. */ 493 while ((via=pjsip_msg_find_hdr(ack->msg, PJSIP_H_VIA, NULL)) != NULL) 494 pj_list_erase(via); 495 490 496 /* Must contain single Via, just as the original INVITE. */ 491 497 hdr = pjsip_msg_find_hdr( invite_msg, PJSIP_H_VIA, NULL); 492 if (hdr) { 493 pjsip_msg_insert_first_hdr( ack->msg, pjsip_hdr_clone(ack->pool,hdr) ); 494 } 498 pjsip_msg_insert_first_hdr( ack->msg, pjsip_hdr_clone(ack->pool,hdr) ); 495 499 496 500 /* If the original INVITE has Route headers, those header fields MUST -
pjproject/trunk/pjsip/src/pjsip/sip_util_statefull.c
r107 r141 22 22 #include <pjsip/sip_transaction.h> 23 23 #include <pjsip/sip_event.h> 24 #include <pjsip/sip_errno.h> 24 25 #include <pj/pool.h> 26 #include <pj/assert.h> 25 27 26 struct aux_tsx_data28 struct tsx_data 27 29 { 28 30 void *token; 29 void (*cb)(void*, pjsip_event*);31 void (*cb)(void*, pjsip_event*); 30 32 }; 31 33 32 static void aux_tsx_handler( pjsip_transaction *tsx, pjsip_event *event);34 static void mod_util_on_tsx_state(pjsip_transaction*, pjsip_event*); 33 35 34 pjsip_module aux_tsx_module = 36 /* This module will be registered in pjsip_endpt.c */ 37 38 pjsip_module mod_stateful_util = 35 39 { 36 NULL, NULL, /* prev and next*/37 { " Aux-Tsx", 7}, /* Name.*/38 -1, /* Id*/39 PJSIP_MOD_PRIORITY_APPLICATION -1, /* Priority*/40 NULL, /* User data.*/41 0, /* Number of methods supported (=0).*/42 { 0 }, /* Array of methods (none)*/43 NULL, /* load()*/44 NULL, /* start()*/45 NULL, /* stop()*/46 NULL, /* unload()*/47 NULL, /* on_rx_request()*/48 NULL, /* on_rx_response()*/49 & aux_tsx_handler, /* tsx_handler()*/40 NULL, NULL, /* prev, next. */ 41 { "mod-stateful-util", 17 }, /* Name. */ 42 -1, /* Id */ 43 PJSIP_MOD_PRIORITY_APPLICATION, /* Priority */ 44 NULL, /* User data. */ 45 NULL, /* load() */ 46 NULL, /* start() */ 47 NULL, /* stop() */ 48 NULL, /* unload() */ 49 NULL, /* on_rx_request() */ 50 NULL, /* on_rx_response() */ 51 NULL, /* on_tx_request. */ 52 NULL, /* on_tx_response() */ 53 &mod_util_on_tsx_state, /* on_tsx_state() */ 50 54 }; 51 55 52 static void aux_tsx_handler( pjsip_transaction *tsx, pjsip_event *event)56 static void mod_util_on_tsx_state(pjsip_transaction *tsx, pjsip_event *event) 53 57 { 54 struct aux_tsx_data *tsx_data;58 struct tsx_data *tsx_data; 55 59 56 60 if (event->type != PJSIP_EVENT_TSX_STATE) 57 61 return; 58 if (tsx->module_data[aux_tsx_module.id] == NULL) 62 63 tsx_data = tsx->mod_data[mod_stateful_util.id]; 64 if (tsx_data == NULL) 59 65 return; 66 60 67 if (tsx->status_code < 200) 61 68 return; … … 64 71 * by clearing the transaction's module_data. 65 72 */ 66 tsx_data = tsx->module_data[aux_tsx_module.id]; 67 tsx->module_data[aux_tsx_module.id] = NULL; 73 tsx->mod_data[mod_stateful_util.id] = NULL; 68 74 69 75 if (tsx_data->cb) { … … 80 86 { 81 87 pjsip_transaction *tsx; 82 struct aux_tsx_data *tsx_data;88 struct tsx_data *tsx_data; 83 89 pj_status_t status; 84 90 85 status = pjsip_endpt_create_tsx(endpt, &tsx); 86 if (!tsx) { 91 PJ_ASSERT_RETURN(endpt && tdata && (timeout==-1 || timeout>0), PJ_EINVAL); 92 93 status = pjsip_tsx_create_uac(&mod_stateful_util, tdata, &tsx); 94 if (status != PJ_SUCCESS) { 87 95 pjsip_tx_data_dec_ref(tdata); 88 return -1;96 return status; 89 97 } 90 98 91 tsx_data = pj_pool_alloc(tsx->pool, sizeof(struct aux_tsx_data));99 tsx_data = pj_pool_alloc(tsx->pool, sizeof(struct tsx_data)); 92 100 tsx_data->token = token; 93 101 tsx_data->cb = cb; 94 tsx->mod ule_data[aux_tsx_module.id] = tsx_data;102 tsx->mod_data[mod_stateful_util.id] = tsx_data; 95 103 96 if (pjsip_tsx_init_uac(tsx, tdata) != 0) { 97 pjsip_endpt_destroy_tsx(endpt, tsx); 98 pjsip_tx_data_dec_ref(tdata); 99 return -1; 100 } 104 PJ_TODO(IMPLEMENT_TIMEOUT_FOR_SEND_REQUEST); 101 105 102 pjsip_endpt_register_tsx(endpt, tsx); 103 pjsip_tx_data_invalidate_msg(tdata); 104 pjsip_tsx_on_tx_msg(tsx, tdata); 105 pjsip_tx_data_dec_ref(tdata); 106 return 0; 106 return pjsip_tsx_send_msg(tsx, NULL); 107 107 } 108 108 -
pjproject/trunk/pjsip/src/pjsua/main.c
r139 r141 18 18 */ 19 19 #include "pjsua.h" 20 #include "getopt.h" 21 20 22 21 23 /* For debugging, disable threading. */ … … 33 35 * Notify UI when invite state has changed. 34 36 */ 35 void ui_inv_on_state_changed(pjsip_inv_session *inv, pjsip_event *e)37 void pjsua_ui_inv_on_state_changed(pjsip_inv_session *inv, pjsip_event *e) 36 38 { 37 39 const char *state_names[] = … … 51 53 PJ_LOG(3,(THIS_FILE, "INVITE session state changed to %s", state_names[inv->state])); 52 54 53 if (inv->state == PJSIP_INV_STATE_DISCONNECTED || 54 inv->state == PJSIP_INV_STATE_TERMINATED) 55 { 55 if (inv->state == PJSIP_INV_STATE_DISCONNECTED) { 56 56 if (inv == inv_session) 57 57 inv_session = NULL; … … 104 104 } 105 105 106 #if 0106 #if 1 107 107 printf("Enter URL to call: "); 108 108 fgets(buf, sizeof(buf), stdin); … … 122 122 123 123 pjsua_invite(buf, &inv); 124 125 #else 126 127 pjsua_invite("sip:localhost:5061", &inv); 124 128 #endif 125 126 pjsua_invite("sip:localhost:5061", &inv);127 129 break; 128 130 … … 163 165 } 164 166 167 168 /***************************************************************************** 169 * This is a very simple PJSIP module, whose sole purpose is to display 170 * incoming and outgoing messages to log. This module will have priority 171 * higher than transport layer, which means: 172 * 173 * - incoming messages will come to this module first before reaching 174 * transaction layer. 175 * 176 * - outgoing messages will come to this module last, after the message 177 * has been 'printed' to contiguous buffer by transport layer and 178 * appropriate transport instance has been decided for this message. 179 * 180 */ 181 182 /* Notification on incoming messages */ 165 183 static pj_bool_t console_on_rx_msg(pjsip_rx_data *rdata) 166 184 { … … 174 192 rdata->msg_info.msg_buf)); 175 193 176 /* Must return false for logger! */194 /* Always return false, otherwise messages will not get processed! */ 177 195 return PJ_FALSE; 178 196 } 179 197 198 /* Notification on outgoing messages */ 180 199 static pj_status_t console_on_tx_msg(pjsip_tx_data *tdata) 181 200 { 201 202 /* Important note: 203 * tp_info field is only valid after outgoing messages has passed 204 * transport layer. So don't try to access tp_info when the module 205 * has lower priority than transport layer. 206 */ 207 182 208 PJ_LOG(4,(THIS_FILE, "TX %d bytes %s to %s:%d:\n" 183 209 "%s\n" … … 189 215 tdata->buf.start)); 190 216 217 /* Always return success, otherwise message will not get sent! */ 191 218 return PJ_SUCCESS; 192 219 } 193 220 221 /* The module instance. */ 194 222 static pjsip_module console_msg_logger = 195 223 { … … 212 240 213 241 214 int main() 242 243 /***************************************************************************** 244 * Console application custom logging: 245 */ 246 247 248 static FILE *log_file; 249 250 251 static void app_log_writer(int level, const char *buffer, int len) 252 { 253 /* Write to both stdout and file. */ 254 255 if (level <= pjsua.app_log_level) 256 pj_log_write(level, buffer, len); 257 258 if (log_file) { 259 fwrite(buffer, len, 1, log_file); 260 fflush(log_file); 261 } 262 } 263 264 265 void app_logging_init(void) 266 { 267 /* Redirect log function to ours */ 268 269 pj_log_set_log_func( &app_log_writer ); 270 271 /* If output log file is desired, create the file: */ 272 273 if (pjsua.log_filename) 274 log_file = fopen(pjsua.log_filename, "wt"); 275 } 276 277 278 void app_logging_shutdown(void) 279 { 280 /* Close logging file, if any: */ 281 282 if (log_file) { 283 fclose(log_file); 284 log_file = NULL; 285 } 286 } 287 288 /***************************************************************************** 289 * Command line argument processing: 290 */ 291 292 293 /* Show usage */ 294 static void usage(void) 295 { 296 puts("Usage:"); 297 puts(" pjsua [options] [sip-url]"); 298 puts(""); 299 puts(" [sip-url] Default URL to invite."); 300 puts(""); 301 puts("General options:"); 302 puts(" --config-file=file Read the config/arguments from file."); 303 puts(" --log-file=fname Log to filename (default stderr)"); 304 puts(" --log-level=N Set log max level to N (0(none) to 6(trace))"); 305 puts(" --app-log-level=N Set log max level for stdout display to N"); 306 puts(" --help Display this help screen"); 307 puts(" --version Display version info"); 308 puts(""); 309 puts("Media options:"); 310 puts(" --null-audio Use NULL audio device"); 311 puts(""); 312 puts("User Agent options:"); 313 puts(" --auto-answer=sec Auto-answer all incoming calls after sec seconds."); 314 puts(" --auto-hangup=sec Auto-hangup all calls after sec seconds."); 315 puts(""); 316 puts("SIP options:"); 317 puts(" --local-port=port Set TCP/UDP port"); 318 puts(" --id=url Set the URL of local ID (used in From header)"); 319 puts(" --contact=url Override the Contact information"); 320 puts(" --proxy=url Set the URL of proxy server"); 321 puts(" --outbound=url Set the URL of outbound proxy server"); 322 puts(" --registrar=url Set the URL of registrar server"); 323 puts(" --reg-timeout=secs Set registration interval to secs (default 3600)"); 324 puts(""); 325 puts("Authentication options:"); 326 puts(" --realm=string Set realm"); 327 puts(" --username=string Set authentication username"); 328 puts(" --password=string Set authentication password"); 329 puts(""); 330 puts("STUN options (all must be specified):"); 331 puts(" --use-stun1=host[:port]"); 332 puts(" --use-stun2=host[:port] Use STUN and set host name and port of STUN servers"); 333 puts(""); 334 puts("SIMPLE options (may be specified more than once):"); 335 puts(" --add-buddy url Add the specified URL to the buddy list."); 336 puts(" --offer-x-ms-msg Offer \"x-ms-message\" in outgoing INVITE"); 337 puts(" --no-presence Do not subscribe presence of buddies"); 338 puts(""); 339 fflush(stdout); 340 } 341 342 343 /* 344 * Verify that valid SIP url is given. 345 */ 346 static pj_status_t verify_sip_url(char *url) 347 { 348 pjsip_uri *p; 349 pj_pool_t *pool; 350 int len = (url ? strlen(url) : 0); 351 352 if (!len) return -1; 353 354 pool = pj_pool_create(&pjsua.cp.factory, "check%p", 1024, 0, NULL); 355 if (!pool) return -1; 356 357 p = pjsip_parse_uri(pool, url, len, 0); 358 if (!p || pj_stricmp2(pjsip_uri_get_scheme(p), "sip") != 0) 359 p = NULL; 360 361 pj_pool_release(pool); 362 return p ? 0 : -1; 363 } 364 365 366 /* 367 * Read command arguments from config file. 368 */ 369 static int read_config_file(pj_pool_t *pool, const char *filename, 370 int *app_argc, char ***app_argv) 371 { 372 int i; 373 FILE *fhnd; 374 char line[200]; 375 int argc = 0; 376 char **argv; 377 enum { MAX_ARGS = 64 }; 378 379 /* Allocate MAX_ARGS+1 (argv needs to be terminated with NULL argument) */ 380 argv = pj_pool_calloc(pool, MAX_ARGS+1, sizeof(char*)); 381 argv[argc++] = *app_argv[0]; 382 383 /* Open config file. */ 384 fhnd = fopen(filename, "rt"); 385 if (!fhnd) { 386 printf("Unable to open config file %s\n", filename); 387 return -1; 388 } 389 390 /* Scan tokens in the file. */ 391 while (argc < MAX_ARGS && !feof(fhnd)) { 392 char *token, *p = line; 393 394 if (fgets(line, sizeof(line), fhnd) == NULL) break; 395 396 for (token = strtok(p, " \t\r\n"); argc < MAX_ARGS; 397 token = strtok(NULL, " \t\r\n")) 398 { 399 int token_len; 400 401 if (!token) break; 402 if (*token == '#') break; 403 404 token_len = strlen(token); 405 if (!token_len) 406 continue; 407 argv[argc] = pj_pool_alloc(pool, token_len+1); 408 pj_memcpy(argv[argc], token, token_len+1); 409 ++argc; 410 } 411 } 412 413 /* Copy arguments from command line */ 414 for (i=1; i<*app_argc && argc < MAX_ARGS; ++i) 415 argv[argc++] = (*app_argv)[i]; 416 417 if (argc == MAX_ARGS && (i!=*app_argc || !feof(fhnd))) { 418 printf("Too many arguments specified in cmd line/config file\n"); 419 fclose(fhnd); 420 return -1; 421 } 422 423 fclose(fhnd); 424 425 /* Assign the new command line back to the original command line. */ 426 *app_argc = argc; 427 *app_argv = argv; 428 return 0; 429 430 } 431 432 433 /* Parse arguments. */ 434 static pj_status_t parse_args(int argc, char *argv[]) 435 { 436 int c; 437 int option_index; 438 enum { OPT_CONFIG_FILE, OPT_LOG_FILE, OPT_LOG_LEVEL, OPT_APP_LOG_LEVEL, 439 OPT_HELP, OPT_VERSION, OPT_NULL_AUDIO, 440 OPT_LOCAL_PORT, OPT_PROXY, OPT_OUTBOUND_PROXY, OPT_REGISTRAR, 441 OPT_REG_TIMEOUT, OPT_ID, OPT_CONTACT, 442 OPT_REALM, OPT_USERNAME, OPT_PASSWORD, 443 OPT_USE_STUN1, OPT_USE_STUN2, 444 OPT_ADD_BUDDY, OPT_OFFER_X_MS_MSG, OPT_NO_PRESENCE, 445 OPT_AUTO_ANSWER, OPT_AUTO_HANGUP}; 446 struct option long_options[] = { 447 { "config-file",1, 0, OPT_CONFIG_FILE}, 448 { "log-file", 1, 0, OPT_LOG_FILE}, 449 { "log-level", 1, 0, OPT_LOG_LEVEL}, 450 { "app-log-level",1,0,OPT_APP_LOG_LEVEL}, 451 { "help", 0, 0, OPT_HELP}, 452 { "version", 0, 0, OPT_VERSION}, 453 { "null-audio", 0, 0, OPT_NULL_AUDIO}, 454 { "local-port", 1, 0, OPT_LOCAL_PORT}, 455 { "proxy", 1, 0, OPT_PROXY}, 456 { "outbound", 1, 0, OPT_OUTBOUND_PROXY}, 457 { "registrar", 1, 0, OPT_REGISTRAR}, 458 { "reg-timeout",1, 0, OPT_REG_TIMEOUT}, 459 { "id", 1, 0, OPT_ID}, 460 { "contact", 1, 0, OPT_CONTACT}, 461 { "realm", 1, 0, OPT_REALM}, 462 { "username", 1, 0, OPT_USERNAME}, 463 { "password", 1, 0, OPT_PASSWORD}, 464 { "use-stun1", 1, 0, OPT_USE_STUN1}, 465 { "use-stun2", 1, 0, OPT_USE_STUN2}, 466 { "add-buddy", 1, 0, OPT_ADD_BUDDY}, 467 { "offer-x-ms-msg",0,0,OPT_OFFER_X_MS_MSG}, 468 { "no-presence", 0, 0, OPT_NO_PRESENCE}, 469 { "auto-answer",1, 0, OPT_AUTO_ANSWER}, 470 { "auto-hangup",1, 0, OPT_AUTO_HANGUP}, 471 { NULL, 0, 0, 0} 472 }; 473 pj_status_t status; 474 char *config_file = NULL; 475 476 /* Run getopt once to see if user specifies config file to read. */ 477 while ((c=getopt_long(argc, argv, "", long_options, &option_index)) != -1) { 478 switch (c) { 479 case OPT_CONFIG_FILE: 480 config_file = optarg; 481 break; 482 } 483 if (config_file) 484 break; 485 } 486 487 if (config_file) { 488 status = read_config_file(pjsua.pool, config_file, &argc, &argv); 489 if (status != 0) 490 return status; 491 } 492 493 494 /* Reinitialize and re-run getopt again, possibly with new arguments 495 * read from config file. 496 */ 497 optind = 0; 498 while ((c=getopt_long(argc, argv, "", long_options, &option_index)) != -1) { 499 char *p; 500 pj_str_t tmp; 501 long lval; 502 503 switch (c) { 504 505 case OPT_LOG_FILE: 506 pjsua.log_filename = optarg; 507 break; 508 509 case OPT_LOG_LEVEL: 510 c = pj_strtoul(pj_cstr(&tmp, optarg)); 511 if (c < 0 || c > 6) { 512 printf("Error: expecting integer value 0-6 for --log-level\n"); 513 return PJ_EINVAL; 514 } 515 pj_log_set_level( c ); 516 break; 517 518 case OPT_APP_LOG_LEVEL: 519 pjsua.app_log_level = pj_strtoul(pj_cstr(&tmp, optarg)); 520 if (pjsua.app_log_level < 0 || pjsua.app_log_level > 6) { 521 printf("Error: expecting integer value 0-6 for --app-log-level\n"); 522 return PJ_EINVAL; 523 } 524 break; 525 526 case OPT_HELP: 527 usage(); 528 return PJ_EINVAL; 529 530 case OPT_VERSION: /* version */ 531 pj_dump_config(); 532 return PJ_EINVAL; 533 534 case OPT_NULL_AUDIO: 535 pjsua.null_audio = 1; 536 break; 537 538 case OPT_LOCAL_PORT: /* local-port */ 539 lval = pj_strtoul(pj_cstr(&tmp, optarg)); 540 if (lval < 1 || lval > 65535) { 541 printf("Error: expecting integer value for --local-port\n"); 542 return PJ_EINVAL; 543 } 544 pjsua.sip_port = (pj_uint16_t)lval; 545 break; 546 547 case OPT_PROXY: /* proxy */ 548 if (verify_sip_url(optarg) != 0) { 549 printf("Error: invalid SIP URL '%s' in proxy argument\n", optarg); 550 return PJ_EINVAL; 551 } 552 pjsua.proxy = pj_str(optarg); 553 break; 554 555 case OPT_OUTBOUND_PROXY: /* outbound proxy */ 556 if (verify_sip_url(optarg) != 0) { 557 printf("Error: invalid SIP URL '%s' in outbound proxy argument\n", optarg); 558 return PJ_EINVAL; 559 } 560 pjsua.outbound_proxy = pj_str(optarg); 561 break; 562 563 case OPT_REGISTRAR: /* registrar */ 564 if (verify_sip_url(optarg) != 0) { 565 printf("Error: invalid SIP URL '%s' in registrar argument\n", optarg); 566 return PJ_EINVAL; 567 } 568 pjsua.registrar_uri = pj_str(optarg); 569 break; 570 571 case OPT_REG_TIMEOUT: /* reg-timeout */ 572 pjsua.reg_timeout = pj_strtoul(pj_cstr(&tmp,optarg)); 573 if (pjsua.reg_timeout < 1 || pjsua.reg_timeout > 3600) { 574 printf("Error: invalid value for --reg-timeout (expecting 1-3600)\n"); 575 return PJ_EINVAL; 576 } 577 break; 578 579 case OPT_ID: /* id */ 580 if (verify_sip_url(optarg) != 0) { 581 printf("Error: invalid SIP URL '%s' in local id argument\n", optarg); 582 return PJ_EINVAL; 583 } 584 pjsua.local_uri = pj_str(optarg); 585 break; 586 587 case OPT_CONTACT: /* contact */ 588 if (verify_sip_url(optarg) != 0) { 589 printf("Error: invalid SIP URL '%s' in contact argument\n", optarg); 590 return PJ_EINVAL; 591 } 592 pjsua.contact_uri = pj_str(optarg); 593 break; 594 595 case OPT_USERNAME: /* Default authentication user */ 596 if (!pjsua.cred_count) pjsua.cred_count = 1; 597 pjsua.cred_info[0].username = pj_str(optarg); 598 break; 599 600 case OPT_REALM: /* Default authentication realm. */ 601 if (!pjsua.cred_count) pjsua.cred_count = 1; 602 pjsua.cred_info[0].realm = pj_str(optarg); 603 break; 604 605 case OPT_PASSWORD: /* authentication password */ 606 if (!pjsua.cred_count) pjsua.cred_count = 1; 607 pjsua.cred_info[0].data_type = 0; 608 pjsua.cred_info[0].data = pj_str(optarg); 609 break; 610 611 case OPT_USE_STUN1: /* STUN server 1 */ 612 p = pj_native_strchr(optarg, ':'); 613 if (p) { 614 *p = '\0'; 615 pjsua.stun_srv1 = pj_str(optarg); 616 pjsua.stun_port1 = pj_strtoul(pj_cstr(&tmp, p+1)); 617 if (pjsua.stun_port1 < 1 || pjsua.stun_port1 > 65535) { 618 printf("Error: expecting port number with option --use-stun1\n"); 619 return PJ_EINVAL; 620 } 621 } else { 622 pjsua.stun_port1 = 3478; 623 pjsua.stun_srv1 = pj_str(optarg); 624 } 625 break; 626 627 case OPT_USE_STUN2: /* STUN server 2 */ 628 p = pj_native_strchr(optarg, ':'); 629 if (p) { 630 *p = '\0'; 631 pjsua.stun_srv2 = pj_str(optarg); 632 pjsua.stun_port2 = pj_strtoul(pj_cstr(&tmp,p+1)); 633 if (pjsua.stun_port2 < 1 || pjsua.stun_port2 > 65535) { 634 printf("Error: expecting port number with option --use-stun2\n"); 635 return PJ_EINVAL; 636 } 637 } else { 638 pjsua.stun_port2 = 3478; 639 pjsua.stun_srv2 = pj_str(optarg); 640 } 641 break; 642 } 643 } 644 645 if (optind != argc) { 646 printf("Error: unknown options %s\n", argv[optind]); 647 return PJ_EINVAL; 648 } 649 650 if (pjsua.reg_timeout == 0) 651 pjsua.reg_timeout = 3600; 652 653 654 return PJ_SUCCESS; 655 } 656 657 658 659 /***************************************************************************** 660 * main(): 661 */ 662 int main(int argc, char *argv[]) 215 663 { 216 664 /* Init default settings. */ … … 224 672 225 673 226 /* Initialize pjsua. 227 * This will start worker thread, client registration, etc. 674 /* Initialize pjsua (to create pool etc). 228 675 */ 229 676 230 677 if (pjsua_init() != PJ_SUCCESS) 231 678 return 1; 679 680 681 /* Parse command line arguments: */ 682 683 if (parse_args(argc, argv) != PJ_SUCCESS) 684 return 1; 685 686 687 /* Init logging: */ 688 689 app_logging_init(); 690 232 691 233 692 /* Register message logger to print incoming and outgoing … … 238 697 239 698 699 /* Start pjsua! */ 700 701 if (pjsua_start() != PJ_SUCCESS) { 702 703 pjsua_destroy(); 704 return 1; 705 } 706 707 240 708 /* Sleep for a while, let any messages get printed to console: */ 241 709 … … 252 720 pjsua_destroy(); 253 721 722 723 /* Close logging: */ 724 725 app_logging_shutdown(); 726 727 254 728 /* Exit... */ 255 729 -
pjproject/trunk/pjsip/src/pjsua/pjsua.c
r139 r141 24 24 25 25 26 #define PJSUA_LOCAL_URI "<sip:bennylp@192.168.0.7>" 27 #define PJSUA_CONTACT_URI "<sip:bennylp@192.168.0.7>" 26 #define PJSUA_LOCAL_URI "<sip:user@127.0.0.1>" 28 27 29 28 static char *PJSUA_DUMMY_SDP_OFFER = … … 72 71 73 72 pjsua.stun_port1 = pjsua.stun_port2 = 0; 73 74 /* Default URIs: */ 75 76 pjsua.local_uri = pj_str(PJSUA_LOCAL_URI); 74 77 } 75 78 … … 130 133 static void pjsua_inv_on_state_changed(pjsip_inv_session *inv, pjsip_event *e) 131 134 { 132 ui_inv_on_state_changed(inv, e);135 pjsua_ui_inv_on_state_changed(inv, e); 133 136 } 134 137 … … 397 400 398 401 402 /* Done */ 403 404 return PJ_SUCCESS; 405 406 407 on_error: 408 pjsip_endpt_destroy(pjsua.endpt); 409 pjsua.endpt = NULL; 410 return status; 411 } 412 413 414 static int PJ_THREAD_FUNC pjsua_worker_thread(void *arg) 415 { 416 PJ_UNUSED_ARG(arg); 417 418 while (!pjsua.quit_flag) { 419 pj_time_val timeout = { 0, 10 }; 420 pjsip_endpt_handle_events (pjsua.endpt, &timeout); 421 } 422 423 return 0; 424 } 425 426 /* 427 * Initialize pjsua application. 428 * This will initialize all libraries, create endpoint instance, and register 429 * pjsip modules. 430 */ 431 pj_status_t pjsua_init(void) 432 { 433 pj_status_t status; 434 435 /* Init PJLIB logging: */ 436 437 pj_log_set_level(pjsua.log_level); 438 pj_log_set_decor(pjsua.log_decor); 439 440 441 /* Init PJLIB: */ 442 443 status = pj_init(); 444 if (status != PJ_SUCCESS) { 445 pjsua_perror("pj_init() error", status); 446 return status; 447 } 448 449 /* Init memory pool: */ 450 451 /* Init caching pool. */ 452 pj_caching_pool_init(&pjsua.cp, &pj_pool_factory_default_policy, 0); 453 454 /* Create memory pool for application. */ 455 pjsua.pool = pj_pool_create(&pjsua.cp.factory, "pjsua", 4000, 4000, NULL); 456 457 458 /* Init PJSIP and all the modules: */ 459 460 status = init_stack(); 461 if (status != PJ_SUCCESS) { 462 pj_caching_pool_destroy(&pjsua.cp); 463 pjsua_perror("Stack initialization has returned error", status); 464 return status; 465 } 466 467 /* Done. */ 468 return PJ_SUCCESS; 469 } 470 471 472 473 /* 474 * Start pjsua stack. 475 * This will start the registration process, if registration is configured. 476 */ 477 pj_status_t pjsua_start(void) 478 { 479 int i; /* Must be signed */ 480 pjsip_transport *udp_transport; 481 pj_status_t status; 482 483 /* Init sockets (STUN etc): */ 484 485 status = init_sockets(); 486 if (status != PJ_SUCCESS) { 487 pj_caching_pool_destroy(&pjsua.cp); 488 pjsua_perror("init_sockets() has returned error", status); 489 return status; 490 } 491 492 399 493 /* Add UDP transport: */ 400 494 … … 413 507 414 508 status = pjsip_udp_transport_attach( pjsua.endpt, pjsua.sip_sock, 415 &addr_name, 1, NULL); 509 &addr_name, 1, 510 &udp_transport); 416 511 if (status != PJ_SUCCESS) { 417 512 pjsua_perror("Unable to start UDP transport", status); 418 goto on_error; 419 } 420 } 421 422 /* Initialize local user info and contact: */ 423 424 { 425 pj_strdup2(pjsua.pool, &pjsua.local_uri, PJSUA_LOCAL_URI); 426 pj_strdup2(pjsua.pool, &pjsua.contact_uri, PJSUA_CONTACT_URI); 513 return status; 514 } 515 } 516 517 /* Initialize Contact URI, if one is not specified: */ 518 519 if (pjsua.contact_uri.slen == 0 && pjsua.local_uri.slen) { 520 521 pjsip_uri *uri; 522 pjsip_sip_uri *sip_uri; 523 char contact[128]; 524 int len; 525 526 /* The local Contact is the username@ip-addr, where 527 * - username is taken from the local URI, 528 * - ip-addr in UDP transport's address name (which may have been 529 * resolved from STUN. 530 */ 531 532 /* Need to parse local_uri to get the elements: */ 533 534 uri = pjsip_parse_uri(pjsua.pool, pjsua.local_uri.ptr, 535 pjsua.local_uri.slen, 0); 536 if (uri == NULL) { 537 pjsua_perror("Invalid local URI", PJSIP_EINVALIDURI); 538 return PJSIP_EINVALIDURI; 539 } 540 541 542 /* Local URI MUST be a SIP or SIPS: */ 543 544 if (!PJSIP_URI_SCHEME_IS_SIP(uri) && !PJSIP_URI_SCHEME_IS_SIPS(uri)) { 545 pjsua_perror("Invalid local URI", PJSIP_EINVALIDSCHEME); 546 return PJSIP_EINVALIDSCHEME; 547 } 548 549 550 /* Get the SIP URI object: */ 551 552 sip_uri = (pjsip_sip_uri*) pjsip_uri_get_uri(uri); 553 554 555 /* Build temporary contact string. */ 556 557 if (sip_uri->user.slen) { 558 559 /* With the user part. */ 560 len = pj_snprintf(contact, sizeof(contact), 561 "<sip:%.*s@%.*s:%d>", 562 sip_uri->user.slen, 563 sip_uri->user.ptr, 564 udp_transport->local_name.host.slen, 565 udp_transport->local_name.host.ptr, 566 udp_transport->local_name.port); 567 } else { 568 569 /* Without user part */ 570 571 len = pj_snprintf(contact, sizeof(contact), 572 "<sip:%.*s:%d>", 573 udp_transport->local_name.host.slen, 574 udp_transport->local_name.host.ptr, 575 udp_transport->local_name.port); 576 } 577 578 if (len < 1 || len >= sizeof(contact)) { 579 pjsua_perror("Invalid Contact", PJSIP_EURITOOLONG); 580 return PJSIP_EURITOOLONG; 581 } 582 583 /* Duplicate Contact uri. */ 584 585 pj_strdup2(pjsua.pool, &pjsua.contact_uri, contact); 586 427 587 } 428 588 … … 431 591 PJ_TODO(INIT_GLOBAL_ROUTE_SET); 432 592 433 434 /* Start registration: */435 436 PJ_TODO(START_REGISTRATION);437 438 /* Done? */439 440 return PJ_SUCCESS;441 442 443 on_error:444 pjsip_endpt_destroy(pjsua.endpt);445 pjsua.endpt = NULL;446 return status;447 }448 449 450 static int PJ_THREAD_FUNC pjsua_worker_thread(void *arg)451 {452 PJ_UNUSED_ARG(arg);453 454 while (!pjsua.quit_flag) {455 pj_time_val timeout = { 0, 10 };456 pjsip_endpt_handle_events (pjsua.endpt, &timeout);457 }458 459 return 0;460 }461 462 /*463 * Initialize pjsua application.464 * This will start the registration process, if registration is configured.465 */466 pj_status_t pjsua_init(void)467 {468 int i; /* Must be signed */469 pj_status_t status;470 471 /* Init PJLIB logging: */472 473 pj_log_set_level(pjsua.log_level);474 pj_log_set_decor(pjsua.log_decor);475 476 477 /* Init PJLIB: */478 479 status = pj_init();480 if (status != PJ_SUCCESS) {481 pjsua_perror("pj_init() error", status);482 return status;483 }484 485 /* Init memory pool: */486 487 /* Init caching pool. */488 pj_caching_pool_init(&pjsua.cp, &pj_pool_factory_default_policy, 0);489 490 /* Create memory pool for application. */491 pjsua.pool = pj_pool_create(&pjsua.cp.factory, "pjsua", 4000, 4000, NULL);492 493 494 /* Init sockets (STUN etc): */495 496 status = init_sockets();497 if (status != PJ_SUCCESS) {498 pj_caching_pool_destroy(&pjsua.cp);499 pjsua_perror("init_sockets() has returned error", status);500 return status;501 }502 503 504 /* Init PJSIP and all the modules: */505 506 status = init_stack();507 if (status != PJ_SUCCESS) {508 pj_caching_pool_destroy(&pjsua.cp);509 pjsua_perror("Stack initialization has returned error", status);510 return status;511 }512 593 513 594 /* Create worker thread(s), if required: */ … … 527 608 } 528 609 529 /* Done. */ 610 /* Start registration: */ 611 612 /* Create client registration session: */ 613 614 status = pjsua_regc_init(); 615 if (status != PJ_SUCCESS) 616 return status; 617 618 /* Perform registration, if required. */ 619 if (pjsua.regc) { 620 pjsua_regc_update(1); 621 } 622 623 624 530 625 return PJ_SUCCESS; 531 626 } … … 538 633 { 539 634 int i; 635 636 /* Unregister, if required: */ 637 if (pjsua.regc) { 638 639 pjsua_regc_update(0); 640 641 /* Wait for some time to allow unregistration to complete: */ 642 643 pj_thread_sleep(500); 644 } 540 645 541 646 /* Signal threads to quit: */ … … 611 716 612 717 718 /* Set dialog Route-Set: */ 719 720 PJ_TODO(INIT_DIALOG_ROUTE_SET); 721 613 722 /* Set credentials: */ 614 723 615 PJ_TODO(SET_DIALOG_CREDENTIALS); 724 pjsip_auth_clt_set_credentials( &dlg->auth_sess, pjsua.cred_count, 725 pjsua.cred_info); 616 726 617 727 -
pjproject/trunk/pjsip/src/pjsua/pjsua.h
r139 r141 48 48 49 49 /* User info: */ 50 50 51 pj_str_t local_uri; /**< Uri in From: header. */ 51 52 pj_str_t contact_uri; /**< Uri in Contact: header. */ 53 54 /* Proxy URLs: */ 55 56 pj_str_t proxy; 57 pj_str_t outbound_proxy; 58 59 /* Registration: */ 60 61 pj_str_t registrar_uri; 62 pjsip_regc *regc; 63 pj_int32_t reg_timeout; 64 pj_timer_entry regc_timer; 65 66 67 /* Authentication credentials: */ 68 69 int cred_count; 70 pjsip_cred_info cred_info[4]; 71 52 72 53 73 /* Threading: */ … … 77 97 78 98 99 /* Media stack: */ 100 101 pj_bool_t null_audio; 102 pj_med_mgr_t *mmgr; 103 104 79 105 /* Misc: */ 80 106 … … 82 108 int app_log_level; /**< stdout log verbosity. */ 83 109 unsigned log_decor; /**< Log decoration. */ 110 char *log_filename; /**< Log filename. */ 84 111 85 112 } pjsua; … … 103 130 104 131 /** 105 * Initialize pjsua application. 106 * This will start the registration process, if registration is configured. 132 * Initialize pjsua application. Application can call this before parsing 133 * application settings. 134 * 135 * This will initialize all libraries, create endpoint instance, and register 136 * pjsip modules. Transport will NOT be created however. 137 * 138 * Application may register module after calling this function. 107 139 */ 108 140 pj_status_t pjsua_init(void); 141 142 143 /** 144 * Start pjsua stack. Application calls this after pjsua settings has been 145 * configured. 146 * 147 * This will start the transport, worker threads (if any), and registration 148 * process, if registration is configured. 149 */ 150 pj_status_t pjsua_start(void); 109 151 110 152 … … 123 165 124 166 /***************************************************************************** 167 * PJSUA Client Registration API. 168 */ 169 170 /** 171 * Initialize client registration session. 172 * 173 * @param app_callback Optional callback 174 */ 175 pj_status_t pjsua_regc_init(void); 176 177 /** 178 * Update registration or perform unregistration. If renew argument is zero, 179 * this will start unregistration process. 180 */ 181 void pjsua_regc_update(pj_bool_t renew); 182 183 184 /***************************************************************************** 125 185 * User Interface API. 126 186 * The UI API specifies functions that will be called by pjsua upon … … 131 191 * Notify UI when invite state has changed. 132 192 */ 133 void ui_inv_on_state_changed(pjsip_inv_session *inv, pjsip_event *e);193 void pjsua_ui_inv_on_state_changed(pjsip_inv_session *inv, pjsip_event *e); 134 194 135 195
Note: See TracChangeset
for help on using the changeset viewer.