Changeset 797 for pjproject/trunk/pjsip/src/pjsua-lib/pjsua_call.c
- Timestamp:
- Nov 11, 2006 4:16:04 PM (17 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
pjproject/trunk/pjsip/src/pjsua-lib/pjsua_call.c
r782 r797 373 373 pj_str_t contact; 374 374 pjsip_dialog *dlg = pjsip_rdata_get_dlg(rdata); 375 pjsip_dialog *replaced_dlg = NULL; 375 376 pjsip_transaction *tsx = pjsip_rdata_get_tsx(rdata); 376 377 pjsip_msg *msg = rdata->msg_info.msg; … … 420 421 pj_gettimeofday(&call->start_time); 421 422 423 /* Check INVITE request for Replaces header. If Replaces header is 424 * present, the function will make sure that we can handle the request. 425 */ 426 status = pjsip_replaces_verify_request(rdata, &replaced_dlg, PJ_FALSE, 427 &response); 428 if (status != PJ_SUCCESS) { 429 /* 430 * Something wrong with the Replaces header. 431 */ 432 if (response) { 433 pjsip_response_addr res_addr; 434 435 pjsip_get_response_addr(response->pool, rdata, &res_addr); 436 pjsip_endpt_send_response(pjsua_var.endpt, &res_addr, response, 437 NULL, NULL); 438 439 } else { 440 441 /* Respond with 500 (Internal Server Error) */ 442 pjsip_endpt_respond_stateless(pjsua_var.endpt, rdata, 500, NULL, 443 NULL, NULL); 444 } 445 446 PJSUA_UNLOCK(); 447 return PJ_TRUE; 448 } 449 450 /* If this INVITE request contains Replaces header, notify application 451 * about the request so that application can do subsequent checking 452 * if it wants to. 453 */ 454 if (replaced_dlg != NULL && pjsua_var.ua_cfg.cb.on_call_replace_request) { 455 pjsua_call *replaced_call; 456 int st_code = 200; 457 pj_str_t st_text = { "OK", 2 }; 458 459 /* Get the replaced call instance */ 460 replaced_call = replaced_dlg->mod_data[pjsua_var.mod.id]; 461 462 /* Notify application */ 463 pjsua_var.ua_cfg.cb.on_call_replace_request(replaced_call->index, 464 rdata, &st_code, &st_text); 465 466 /* Must specify final response */ 467 PJ_ASSERT_ON_FAIL(st_code >= 200, st_code = 200); 468 469 /* Check if application rejects this request. */ 470 if (st_code >= 300) { 471 472 if (st_text.slen == 2) 473 st_text = *pjsip_get_status_text(st_code); 474 475 pjsip_endpt_respond(pjsua_var.endpt, NULL, rdata, 476 st_code, &st_text, NULL, NULL, NULL); 477 PJSUA_UNLOCK(); 478 return PJ_TRUE; 479 } 480 } 481 482 422 483 /* Get media capability from media endpoint: */ 423 484 status = pjmedia_endpt_create_sdp( pjsua_var.med_endpt, … … 546 607 547 608 548 /* Notify application */ 549 if (pjsua_var.ua_cfg.cb.on_incoming_call) 550 pjsua_var.ua_cfg.cb.on_incoming_call(acc_id, call_id, rdata); 609 /* Check if this request should replace existing call */ 610 if (replaced_dlg) { 611 pjsip_inv_session *replaced_inv; 612 struct pjsua_call *replaced_call; 613 pjsip_tx_data *tdata; 614 615 /* Get the invite session in the dialog */ 616 replaced_inv = pjsip_dlg_get_inv_session(replaced_dlg); 617 618 /* Get the replaced call instance */ 619 replaced_call = replaced_dlg->mod_data[pjsua_var.mod.id]; 620 621 /* Notify application */ 622 if (pjsua_var.ua_cfg.cb.on_call_replaced) 623 pjsua_var.ua_cfg.cb.on_call_replaced(replaced_call->index, 624 call_id); 625 626 PJ_LOG(4,(THIS_FILE, "Answering replacement call %d with 200/OK", 627 call_id)); 628 629 /* Answer the new call with 200 response */ 630 status = pjsip_inv_answer(inv, 200, NULL, NULL, &tdata); 631 if (status == PJ_SUCCESS) 632 status = pjsip_inv_send_msg(inv, tdata); 633 634 if (status != PJ_SUCCESS) 635 pjsua_perror(THIS_FILE, "Error answering session", status); 636 637 638 PJ_LOG(4,(THIS_FILE, "Disconnecting replaced call %d", 639 replaced_call->index)); 640 641 /* Disconnect replaced invite session */ 642 status = pjsip_inv_end_session(replaced_inv, PJSIP_SC_GONE, NULL, 643 &tdata); 644 if (status == PJ_SUCCESS && tdata) 645 status = pjsip_inv_send_msg(replaced_inv, tdata); 646 647 if (status != PJ_SUCCESS) 648 pjsua_perror(THIS_FILE, "Error terminating session", status); 649 650 651 } else { 652 653 /* Notify application */ 654 if (pjsua_var.ua_cfg.cb.on_incoming_call) 655 pjsua_var.ua_cfg.cb.on_incoming_call(acc_id, call_id, rdata); 656 657 } 658 551 659 552 660 /* This INVITE request has been handled. */ … … 1066 1174 pjsua_call *call; 1067 1175 pjsip_dialog *dlg; 1176 pjsip_generic_string_hdr *gs_hdr; 1177 const pj_str_t str_ref_by = { "Referred-By", 11 }; 1068 1178 struct pjsip_evsub_user xfer_cb; 1069 1179 pj_status_t status; … … 1102 1212 } 1103 1213 1214 /* Add Referred-By header */ 1215 gs_hdr = pjsip_generic_string_hdr_create(tdata->pool, &str_ref_by, 1216 &dlg->local.info_str); 1217 pjsip_msg_add_hdr(tdata->msg, (pjsip_hdr*)gs_hdr); 1218 1219 1104 1220 /* Add additional headers etc */ 1105 1221 pjsua_process_msg_data( tdata, msg_data); … … 1122 1238 return PJ_SUCCESS; 1123 1239 1240 } 1241 1242 1243 /* 1244 * Initiate attended call transfer to the specified address. 1245 */ 1246 PJ_DEF(pj_status_t) pjsua_call_xfer_replaces( pjsua_call_id call_id, 1247 pjsua_call_id dest_call_id, 1248 unsigned options, 1249 const pjsua_msg_data *msg_data) 1250 { 1251 pjsua_call *dest_call; 1252 pjsip_dialog *dest_dlg; 1253 char str_dest_buf[512]; 1254 pj_str_t str_dest; 1255 int len; 1256 pjsip_uri *uri; 1257 pj_status_t status; 1258 1259 1260 PJ_ASSERT_RETURN(call_id>=0 && call_id<(int)pjsua_var.ua_cfg.max_calls, 1261 PJ_EINVAL); 1262 PJ_ASSERT_RETURN(dest_call_id>=0 && 1263 dest_call_id<(int)pjsua_var.ua_cfg.max_calls, 1264 PJ_EINVAL); 1265 1266 status = acquire_call("pjsua_call_xfer_replaces()", dest_call_id, 1267 &dest_call, &dest_dlg); 1268 if (status != PJ_SUCCESS) 1269 return status; 1270 1271 /* 1272 * Create REFER destination URI with Replaces field. 1273 */ 1274 1275 /* Make sure we have sufficient buffer's length */ 1276 PJ_ASSERT_RETURN( dest_dlg->remote.info_str.slen + 1277 dest_dlg->call_id->id.slen + 1278 dest_dlg->remote.info->tag.slen + 1279 dest_dlg->local.info->tag.slen + 32 1280 < sizeof(str_dest_buf), PJSIP_EURITOOLONG); 1281 1282 /* Print URI */ 1283 str_dest_buf[0] = '<'; 1284 str_dest.slen = 1; 1285 1286 uri = pjsip_uri_get_uri(dest_dlg->remote.info->uri); 1287 len = pjsip_uri_print(PJSIP_URI_IN_REQ_URI, uri, 1288 str_dest_buf+1, sizeof(str_dest_buf)-1); 1289 if (len < 0) 1290 return PJSIP_EURITOOLONG; 1291 1292 str_dest.slen += len; 1293 1294 1295 /* Build the URI */ 1296 len = pj_ansi_snprintf(str_dest_buf + str_dest.slen, 1297 sizeof(str_dest_buf) - str_dest.slen, 1298 "?%s" 1299 "Replaces=%.*s" 1300 "%%3Bto-tag%%3D%.*s" 1301 "%%3Bfrom-tag%%3D%.*s>", 1302 ((options&PJSUA_XFER_NO_REQUIRE_REPLACES) ? 1303 "" : "Require=replaces&"), 1304 (int)dest_dlg->call_id->id.slen, 1305 dest_dlg->call_id->id.ptr, 1306 (int)dest_dlg->remote.info->tag.slen, 1307 dest_dlg->remote.info->tag.ptr, 1308 (int)dest_dlg->local.info->tag.slen, 1309 dest_dlg->local.info->tag.ptr); 1310 1311 PJ_ASSERT_RETURN(len > 0 && len <= (int)sizeof(str_dest_buf)-str_dest.slen, 1312 PJSIP_EURITOOLONG); 1313 1314 str_dest.ptr = str_dest_buf; 1315 str_dest.slen += len; 1316 1317 pjsip_dlg_dec_lock(dest_dlg); 1318 1319 return pjsua_call_xfer(call_id, &str_dest, msg_data); 1124 1320 } 1125 1321 … … 2341 2537 const pj_str_t str_refer_to = { "Refer-To", 8}; 2342 2538 const pj_str_t str_refer_sub = { "Refer-Sub", 9 }; 2539 const pj_str_t str_ref_by = { "Referred-By", 11 }; 2343 2540 pjsip_generic_string_hdr *refer_to; 2344 2541 pjsip_generic_string_hdr *refer_sub; 2542 pjsip_hdr *ref_by_hdr; 2345 2543 pj_bool_t no_refer_sub = PJ_FALSE; 2346 2544 char *uri; 2545 pjsua_msg_data msg_data; 2347 2546 pj_str_t tmp; 2348 2547 pjsip_status_code code; … … 2373 2572 } 2374 2573 2574 /* Find optional Referred-By header (to be copied onto outgoing INVITE 2575 * request. 2576 */ 2577 ref_by_hdr = pjsip_msg_find_hdr_by_name(rdata->msg_info.msg, &str_ref_by, 2578 NULL); 2375 2579 2376 2580 /* Notify callback */ … … 2491 2695 uri[refer_to->hvalue.slen] = '\0'; 2492 2696 2697 /* Init msg_data */ 2698 pjsua_msg_data_init(&msg_data); 2699 2700 /* If Referred-By header is present in the REFER request, copy this 2701 * to the outgoing INVITE request. 2702 */ 2703 if (ref_by_hdr != NULL) { 2704 pjsip_hdr *dup = pjsip_hdr_clone(rdata->tp_info.pool, ref_by_hdr); 2705 pj_list_push_back(&msg_data.hdr_list, dup); 2706 } 2707 2493 2708 /* Now make the outgoing call. */ 2494 2709 tmp = pj_str(uri); 2495 2710 status = pjsua_call_make_call(existing_call->acc_id, &tmp, 0, 2496 existing_call->user_data, NULL,2711 existing_call->user_data, &msg_data, 2497 2712 &new_call); 2498 2713 if (status != PJ_SUCCESS) {
Note: See TracChangeset
for help on using the changeset viewer.