Changeset 503 for pjproject/trunk/pjsip/src/pjsua-lib/pjsua_im.c
- Timestamp:
- Jun 13, 2006 10:57:13 PM (18 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
pjproject/trunk/pjsip/src/pjsua-lib/pjsua_im.c
r492 r503 18 18 */ 19 19 #include <pjsua-lib/pjsua.h> 20 #include <pj/log.h> 21 #include "pjsua_imp.h" 22 23 /* 24 * pjsua_im.c 25 * 26 * To handle incoming MESSAGE outside dialog. 27 * Incoming MESSAGE inside dialog is hanlded in pjsua_call.c. 28 */ 29 30 #define THIS_FILE "pjsua_im.c" 20 #include <pjsua-lib/pjsua_internal.h> 21 22 23 #define THIS_FILE "pjsua_im.h" 31 24 32 25 … … 50 43 /* Proto */ 51 44 static pj_bool_t im_on_rx_request(pjsip_rx_data *rdata); 45 52 46 53 47 /* The module instance. */ … … 137 131 * This may trigger pjsua_ui_on_pager() or pjsua_ui_on_typing(). 138 132 */ 139 void pjsua_im_process_pager(int call_i ndex, const pj_str_t *from,133 void pjsua_im_process_pager(int call_id, const pj_str_t *from, 140 134 const pj_str_t *to, pjsip_rx_data *rdata) 141 135 { 136 pjsip_contact_hdr *contact_hdr; 137 pj_str_t contact; 142 138 pjsip_msg_body *body = rdata->msg_info.msg->body; 143 139 144 140 /* Body MUST have been checked before */ 145 141 pj_assert(body != NULL); 142 143 144 /* Build remote contact */ 145 contact_hdr = pjsip_msg_find_hdr(rdata->msg_info.msg, PJSIP_H_CONTACT, 146 NULL); 147 if (contact_hdr) { 148 contact.ptr = pj_pool_alloc(rdata->tp_info.pool, 149 PJSIP_MAX_URL_SIZE); 150 contact.slen = pjsip_uri_print(PJSIP_URI_IN_CONTACT_HDR, 151 contact_hdr->uri, contact.ptr, 152 PJSIP_MAX_URL_SIZE); 153 } else { 154 contact.slen = 0; 155 } 156 146 157 147 158 if (pj_stricmp(&body->content_type.type, &STR_MIME_TEXT)==0 && 148 159 pj_stricmp(&body->content_type.subtype, &STR_MIME_PLAIN)==0) 149 160 { 150 pj_str_t text; 151 152 /* Build the text. */ 153 text.ptr = rdata->msg_info.msg->body->data; 154 text.slen = rdata->msg_info.msg->body->len; 155 156 if (pjsua.cb.on_pager) 157 (*pjsua.cb.on_pager)(call_index, from, to, &text); 161 const pj_str_t mime_text_plain = pj_str("text/plain"); 162 pj_str_t text_body; 163 164 /* Save text body */ 165 text_body.ptr = rdata->msg_info.msg->body->data; 166 text_body.slen = rdata->msg_info.msg->body->len; 167 168 if (pjsua_var.ua_cfg.cb.on_pager) { 169 (*pjsua_var.ua_cfg.cb.on_pager)(call_id, from, to, &contact, 170 &mime_text_plain, &text_body); 171 } 158 172 159 173 } else { 160 161 174 /* Expecting typing indication */ 162 163 175 pj_status_t status; 164 176 pj_bool_t is_typing; … … 172 184 } 173 185 174 if (pjsua.cb.on_typing) 175 (*pjsua.cb.on_typing)(call_index, from, to, is_typing); 186 if (pjsua_var.ua_cfg.cb.on_typing) { 187 (*pjsua_var.ua_cfg.cb.on_typing)(call_id, from, to, &contact, 188 is_typing); 189 } 176 190 } 177 191 … … 211 225 pj_list_push_back(&hdr_list, accept_hdr); 212 226 213 pjsip_endpt_respond_stateless(pjsua .endpt, rdata,227 pjsip_endpt_respond_stateless(pjsua_var.endpt, rdata, 214 228 PJSIP_SC_NOT_ACCEPTABLE_HERE, NULL, 215 229 &hdr_list, NULL); … … 220 234 * the UI takes too long to process the message. 221 235 */ 222 status = pjsip_endpt_respond( pjsua .endpt, NULL, rdata, 200, NULL,236 status = pjsip_endpt_respond( pjsua_var.endpt, NULL, rdata, 200, NULL, 223 237 NULL, NULL, NULL); 224 238 … … 262 276 static void im_callback(void *token, pjsip_event *e) 263 277 { 264 pj _str_t *text= token;278 pjsua_im_data *im_data = token; 265 279 266 280 if (e->type == PJSIP_EVENT_TSX_STATE) { 267 281 268 282 pjsip_transaction *tsx = e->body.tsx_state.tsx; 283 284 /* Ignore provisional response, if any */ 285 if (tsx->status_code < 200) 286 return; 287 288 289 /* Handle authentication challenges */ 290 if (e->body.tsx_state.type == PJSIP_EVENT_RX_MSG && 291 (tsx->status_code == 401 || tsx->status_code == 407)) 292 { 293 pjsip_rx_data *rdata = e->body.tsx_state.src.rdata; 294 pjsip_tx_data *tdata; 295 pjsip_auth_clt_sess auth; 296 pj_status_t status; 297 298 PJ_LOG(4,(THIS_FILE, "Resending IM with authentication")); 299 300 /* Create temporary authentication session */ 301 pjsip_auth_clt_init(&auth,pjsua_var.endpt,rdata->tp_info.pool, 0); 302 303 pjsip_auth_clt_set_credentials(&auth, 304 pjsua_var.acc[im_data->acc_id].cred_cnt, 305 pjsua_var.acc[im_data->acc_id].cred); 306 307 status = pjsip_auth_clt_reinit_req(&auth, rdata, tsx->last_tx, 308 &tdata); 309 if (status == PJ_SUCCESS) { 310 pjsua_im_data *im_data2; 311 312 /* Must duplicate im_data */ 313 im_data2 = pjsua_im_data_dup(tdata->pool, im_data); 314 315 /* Re-send request */ 316 status = pjsip_endpt_send_request( pjsua_var.endpt, tdata, -1, 317 im_data2, &im_callback); 318 if (status == PJ_SUCCESS) { 319 /* Done */ 320 return; 321 } 322 } 323 } 269 324 270 325 if (tsx->status_code/100 == 2) { 271 326 PJ_LOG(4,(THIS_FILE, 272 327 "Message \'%s\' delivered successfully", 273 text->ptr));328 im_data->body.ptr)); 274 329 } else { 275 330 PJ_LOG(3,(THIS_FILE, 276 "Failed to deliver message \'%s\': %s [st_code=%d]", 277 text->ptr, 278 pjsip_get_status_text(tsx->status_code)->ptr, 279 tsx->status_code)); 331 "Failed to deliver message \'%s\': %d/%.*s", 332 im_data->body.ptr, 333 tsx->status_code, 334 (int)tsx->status_text.slen, 335 tsx->status_text.ptr)); 280 336 } 281 } 282 } 283 284 285 /** 286 * Send IM outside dialog. 287 */ 288 PJ_DEF(pj_status_t) pjsua_im_send(int acc_index, const pj_str_t *dst_uri, 289 const pj_str_t *str) 337 338 if (pjsua_var.ua_cfg.cb.on_pager_status) 339 pjsua_var.ua_cfg.cb.on_pager_status(im_data->call_id, 340 &im_data->to, 341 &im_data->body, 342 im_data->user_data, 343 tsx->status_code, 344 &tsx->status_text); 345 } 346 } 347 348 349 /* Outgoing typing indication callback. 350 * (used to reauthenticate request) 351 */ 352 static void typing_callback(void *token, pjsip_event *e) 353 { 354 pjsua_im_data *im_data = token; 355 356 if (e->type == PJSIP_EVENT_TSX_STATE) { 357 358 pjsip_transaction *tsx = e->body.tsx_state.tsx; 359 360 /* Ignore provisional response, if any */ 361 if (tsx->status_code < 200) 362 return; 363 364 /* Handle authentication challenges */ 365 if (e->body.tsx_state.type == PJSIP_EVENT_RX_MSG && 366 (tsx->status_code == 401 || tsx->status_code == 407)) 367 { 368 pjsip_rx_data *rdata = e->body.tsx_state.src.rdata; 369 pjsip_tx_data *tdata; 370 pjsip_auth_clt_sess auth; 371 pj_status_t status; 372 373 PJ_LOG(4,(THIS_FILE, "Resending IM with authentication")); 374 375 /* Create temporary authentication session */ 376 pjsip_auth_clt_init(&auth,pjsua_var.endpt,rdata->tp_info.pool, 0); 377 378 pjsip_auth_clt_set_credentials(&auth, 379 pjsua_var.acc[im_data->acc_id].cred_cnt, 380 pjsua_var.acc[im_data->acc_id].cred); 381 382 status = pjsip_auth_clt_reinit_req(&auth, rdata, tsx->last_tx, 383 &tdata); 384 if (status == PJ_SUCCESS) { 385 pjsua_im_data *im_data2; 386 387 /* Must duplicate im_data */ 388 im_data2 = pjsua_im_data_dup(tdata->pool, im_data); 389 390 /* Re-send request */ 391 status = pjsip_endpt_send_request( pjsua_var.endpt, tdata, -1, 392 im_data2, &typing_callback); 393 if (status == PJ_SUCCESS) { 394 /* Done */ 395 return; 396 } 397 } 398 } 399 400 } 401 } 402 403 404 /* 405 * Send instant messaging outside dialog, using the specified account for 406 * route set and authentication. 407 */ 408 PJ_DEF(pj_status_t) pjsua_im_send( pjsua_acc_id acc_id, 409 const pj_str_t *to, 410 const pj_str_t *mime_type, 411 const pj_str_t *content, 412 const pjsua_msg_data *msg_data, 413 void *user_data) 290 414 { 291 415 pjsip_tx_data *tdata; 416 const pj_str_t mime_text_plain = pj_str("text/plain"); 292 417 const pj_str_t STR_CONTACT = { "Contact", 7 }; 293 const pj_str_t mime_text = pj_str("text"); 294 const pj_str_t mime_plain = pj_str("plain"); 295 pj_str_t *text; 418 pjsip_media_type media_type; 419 pjsua_im_data *im_data; 296 420 pj_status_t status; 297 421 422 /* To and message body must be specified. */ 423 PJ_ASSERT_RETURN(to && content, PJ_EINVAL); 424 298 425 /* Create request. */ 299 status = pjsip_endpt_create_request(pjsua .endpt, &pjsip_message_method,300 dst_uri,301 &pjsua .config.acc_config[acc_index].id,302 dst_uri, NULL, NULL, -1, NULL, &tdata);426 status = pjsip_endpt_create_request(pjsua_var.endpt, 427 &pjsip_message_method, to, 428 &pjsua_var.acc[acc_id].cfg.id, 429 to, NULL, NULL, -1, NULL, &tdata); 303 430 if (status != PJ_SUCCESS) { 304 431 pjsua_perror(THIS_FILE, "Unable to create request", status); … … 314 441 pjsip_generic_string_hdr_create(tdata->pool, 315 442 &STR_CONTACT, 316 &pjsua.config.acc_config[acc_index].contact)); 317 318 /* Duplicate text. 319 * We need to keep the text because we will display it when we fail to 320 * send the message. 443 &pjsua_var.acc[acc_id].cfg.contact)); 444 445 /* Create IM data to keep message details and give it back to 446 * application on the callback 321 447 */ 322 text = pj_pool_alloc(tdata->pool, sizeof(pj_str_t)); 323 pj_strdup_with_null(tdata->pool, text, str); 448 im_data = pj_pool_zalloc(tdata->pool, sizeof(*im_data)); 449 im_data->acc_id = acc_id; 450 im_data->call_id = PJSUA_INVALID_ID; 451 pj_strdup_with_null(tdata->pool, &im_data->to, to); 452 pj_strdup_with_null(tdata->pool, &im_data->body, content); 453 im_data->user_data = user_data; 454 455 456 /* Set default media type if none is specified */ 457 if (mime_type == NULL) { 458 mime_type = &mime_text_plain; 459 } 460 461 /* Parse MIME type */ 462 pjsua_parse_media_type(tdata->pool, mime_type, &media_type); 324 463 325 464 /* Add message body */ 326 tdata->msg->body = pjsip_msg_body_create( tdata->pool, &mime_text, 327 &mime_plain, text); 465 tdata->msg->body = pjsip_msg_body_create( tdata->pool, &media_type.type, 466 &media_type.subtype, 467 &im_data->body); 328 468 if (tdata->msg->body == NULL) { 329 469 pjsua_perror(THIS_FILE, "Unable to create msg body", PJ_ENOMEM); … … 332 472 } 333 473 474 /* Add additional headers etc. */ 475 pjsua_process_msg_data(tdata, msg_data); 476 477 /* Add route set */ 478 pjsua_set_msg_route_set(tdata, &pjsua_var.acc[acc_id].route_set); 479 334 480 /* Send request (statefully) */ 335 status = pjsip_endpt_send_request( pjsua .endpt, tdata, -1,336 text, &im_callback);481 status = pjsip_endpt_send_request( pjsua_var.endpt, tdata, -1, 482 im_data, &im_callback); 337 483 if (status != PJ_SUCCESS) { 338 484 pjsua_perror(THIS_FILE, "Unable to send request", status); … … 344 490 345 491 346 /* *492 /* 347 493 * Send typing indication outside dialog. 348 494 */ 349 PJ_DEF(pj_status_t) pjsua_im_typing(int acc_index, const pj_str_t *dst_uri, 350 pj_bool_t is_typing) 495 PJ_DEF(pj_status_t) pjsua_im_typing( pjsua_acc_id acc_id, 496 const pj_str_t *to, 497 pj_bool_t is_typing, 498 const pjsua_msg_data *msg_data) 351 499 { 352 500 const pj_str_t STR_CONTACT = { "Contact", 7 }; 501 pjsua_im_data *im_data; 353 502 pjsip_tx_data *tdata; 354 503 pj_status_t status; 355 504 356 505 /* Create request. */ 357 status = pjsip_endpt_create_request( pjsua.endpt, &pjsip_message_method, 358 dst_uri, 359 &pjsua.config.acc_config[acc_index].id, 360 dst_uri, NULL, NULL, -1, NULL, &tdata); 506 status = pjsip_endpt_create_request( pjsua_var.endpt, &pjsip_message_method, 507 to, &pjsua_var.acc[acc_id].cfg.id, 508 to, NULL, NULL, -1, NULL, &tdata); 361 509 if (status != PJ_SUCCESS) { 362 510 pjsua_perror(THIS_FILE, "Unable to create request", status); … … 374 522 pjsip_generic_string_hdr_create(tdata->pool, 375 523 &STR_CONTACT, 376 &pjsua .config.acc_config[acc_index].contact));524 &pjsua_var.acc[acc_id].cfg.contact)); 377 525 378 526 … … 381 529 NULL, NULL, -1); 382 530 531 /* Add additional headers etc. */ 532 pjsua_process_msg_data(tdata, msg_data); 533 534 /* Create data to reauthenticate */ 535 im_data = pj_pool_zalloc(tdata->pool, sizeof(*im_data)); 536 im_data->acc_id = acc_id; 537 383 538 /* Send request (statefully) */ 384 status = pjsip_endpt_send_request( pjsua .endpt, tdata, -1,385 NULL, NULL);539 status = pjsip_endpt_send_request( pjsua_var.endpt, tdata, -1, 540 im_data, &typing_callback); 386 541 if (status != PJ_SUCCESS) { 387 542 pjsua_perror(THIS_FILE, "Unable to send request", status); … … 402 557 403 558 /* Register module */ 404 status = pjsip_endpt_register_module(pjsua .endpt, &mod_pjsua_im);559 status = pjsip_endpt_register_module(pjsua_var.endpt, &mod_pjsua_im); 405 560 if (status != PJ_SUCCESS) 406 561 return status; 407 562 408 563 /* Register support for MESSAGE method. */ 409 pjsip_endpt_add_capability( pjsua .endpt, &mod_pjsua_im, PJSIP_H_ALLOW,564 pjsip_endpt_add_capability( pjsua_var.endpt, &mod_pjsua_im, PJSIP_H_ALLOW, 410 565 NULL, 1, &msg_tag); 411 566
Note: See TracChangeset
for help on using the changeset viewer.