Changeset 106 for pjproject/trunk/pjsip/src/pjsip/sip_util.c
- Timestamp:
- Dec 30, 2005 11:50:15 PM (18 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
pjproject/trunk/pjsip/src/pjsip/sip_util.c
r105 r106 24 24 #include <pjsip/sip_transaction.h> 25 25 #include <pjsip/sip_module.h> 26 #include <pjsip/sip_errno.h> 26 27 #include <pj/log.h> 27 28 #include <pj/string.h> … … 52 53 static pj_str_t str_TEXT = { "text", 4}, 53 54 str_PLAIN = { "plain", 5 }; 54 static int aux_mod_id;55 56 struct aux_tsx_data57 {58 void *token;59 void (*cb)(void*,pjsip_event*);60 };61 62 static pj_status_t aux_tsx_init( pjsip_endpoint *endpt,63 struct pjsip_module *mod, pj_uint32_t id )64 {65 PJ_UNUSED_ARG(endpt);66 PJ_UNUSED_ARG(mod);67 68 aux_mod_id = id;69 return 0;70 }71 72 static void aux_tsx_handler( struct pjsip_module *mod, pjsip_event *event )73 {74 pjsip_transaction *tsx;75 struct aux_tsx_data *tsx_data;76 77 PJ_UNUSED_ARG(mod);78 79 if (event->type != PJSIP_EVENT_TSX_STATE)80 return;81 82 pj_assert(event->body.tsx_state.tsx != NULL);83 tsx = event->body.tsx_state.tsx;84 if (tsx == NULL)85 return;86 if (tsx->module_data[aux_mod_id] == NULL)87 return;88 if (tsx->status_code < 200)89 return;90 91 /* Call the callback, if any, and prevent the callback to be called again92 * by clearing the transaction's module_data.93 */94 tsx_data = tsx->module_data[aux_mod_id];95 tsx->module_data[aux_mod_id] = NULL;96 97 if (tsx_data->cb) {98 (*tsx_data->cb)(tsx_data->token, event);99 }100 }101 102 pjsip_module aux_tsx_module =103 {104 { "Aux-Tsx", 7}, /* Name. */105 0, /* Flag */106 128, /* Priority */107 NULL, /* Arbitrary data. */108 0, /* Number of methods supported (none). */109 { 0 }, /* Array of methods (none) */110 &aux_tsx_init, /* init_module() */111 NULL, /* start_module() */112 NULL, /* deinit_module() */113 &aux_tsx_handler, /* tsx_handler() */114 };115 116 PJ_DEF(pj_status_t) pjsip_endpt_send_request( pjsip_endpoint *endpt,117 pjsip_tx_data *tdata,118 int timeout,119 void *token,120 void (*cb)(void*,pjsip_event*))121 {122 pjsip_transaction *tsx;123 struct aux_tsx_data *tsx_data;124 pj_status_t status;125 126 status = pjsip_endpt_create_tsx(endpt, &tsx);127 if (!tsx) {128 pjsip_tx_data_dec_ref(tdata);129 return -1;130 }131 132 tsx_data = pj_pool_alloc(tsx->pool, sizeof(struct aux_tsx_data));133 tsx_data->token = token;134 tsx_data->cb = cb;135 tsx->module_data[aux_mod_id] = tsx_data;136 137 if (pjsip_tsx_init_uac(tsx, tdata) != 0) {138 pjsip_endpt_destroy_tsx(endpt, tsx);139 pjsip_tx_data_dec_ref(tdata);140 return -1;141 }142 143 pjsip_endpt_register_tsx(endpt, tsx);144 pjsip_tx_data_invalidate_msg(tdata);145 pjsip_tsx_on_tx_msg(tsx, tdata);146 pjsip_tx_data_dec_ref(tdata);147 return 0;148 }149 55 150 56 /* … … 170 76 pjsip_msg *msg; 171 77 pjsip_msg_body *body; 78 pjsip_via_hdr *via; 172 79 const pjsip_hdr *endpt_hdr; 173 80 … … 205 112 /* Add CSeq header. */ 206 113 pjsip_msg_add_hdr(msg, (void*)param_cseq); 114 115 /* Add a blank Via header. */ 116 via = pjsip_via_hdr_create(tdata->pool); 117 via->rport_param = 0; 118 pjsip_msg_insert_first_hdr(msg, (void*)via); 207 119 208 120 /* Create message body. */ … … 217 129 msg->body = body; 218 130 } 131 132 PJ_LOG(4,(THIS_FILE, "Request %s (CSeq=%d/%.*s) created.", 133 tdata->obj_name, 134 param_cseq->cseq, 135 param_cseq->method.name.slen, 136 param_cseq->method.name.ptr)); 137 219 138 } 220 139 … … 329 248 PJ_END 330 249 331 PJ_LOG(4,(THIS_FILE, "Request %s (%d %.*s) created.",332 tdata->obj_name,333 cseq->cseq,334 cseq->method.name.slen,335 cseq->method.name.ptr));336 337 250 *p_tdata = tdata; 338 251 return PJ_SUCCESS; … … 367 280 PJ_LOG(5,(THIS_FILE, "Entering pjsip_endpt_create_request_from_hdr()")); 368 281 282 /* Check arguments. */ 283 PJ_ASSERT_RETURN(endpt && method && param_target && param_from && 284 param_to && p_tdata, PJ_EINVAL); 285 286 /* Create new transmit data. */ 369 287 status = pjsip_endpt_create_tdata(endpt, &tdata); 370 288 if (status != PJ_SUCCESS) 371 289 return status; 372 290 291 /* Set initial reference counter to 1. */ 373 292 pjsip_tx_data_add_ref(tdata); 374 293 375 294 PJ_TRY { 295 /* Duplicate target URI and headers. */ 376 296 target = pjsip_uri_clone(tdata->pool, param_target); 377 from = pjsip_hdr_ shallow_clone(tdata->pool, param_from);297 from = pjsip_hdr_clone(tdata->pool, param_from); 378 298 pjsip_fromto_set_from(from); 379 to = pjsip_hdr_ shallow_clone(tdata->pool, param_to);299 to = pjsip_hdr_clone(tdata->pool, param_to); 380 300 pjsip_fromto_set_to(to); 381 301 if (param_contact) 382 contact = pjsip_hdr_ shallow_clone(tdata->pool, param_contact);302 contact = pjsip_hdr_clone(tdata->pool, param_contact); 383 303 else 384 304 contact = NULL; 385 call_id = pjsip_hdr_ shallow_clone(tdata->pool, param_call_id);305 call_id = pjsip_hdr_clone(tdata->pool, param_call_id); 386 306 cseq = pjsip_cseq_hdr_create(tdata->pool); 387 307 if (param_cseq >= 0) … … 391 311 pjsip_method_copy(tdata->pool, &cseq->method, method); 392 312 313 /* Copy headers to the request. */ 393 314 init_request_throw(endpt, tdata, &cseq->method, target, from, to, 394 315 contact, call_id, cseq, param_text); … … 400 321 PJ_END; 401 322 402 PJ_LOG(4,(THIS_FILE, "Request %s (%d %.*s) created.",403 tdata->obj_name,404 cseq->cseq,405 cseq->method.name.slen,406 cseq->method.name.ptr));407 408 323 *p_tdata = tdata; 409 324 return PJ_SUCCESS; … … 419 334 PJ_DEF(pj_status_t) pjsip_endpt_create_response( pjsip_endpoint *endpt, 420 335 const pjsip_rx_data *rdata, 421 int code, 336 int st_code, 337 const pj_str_t *st_text, 422 338 pjsip_tx_data **p_tdata) 423 339 { … … 435 351 /* Log this action. */ 436 352 PJ_LOG(5,(THIS_FILE, "pjsip_endpt_create_response(rdata=%p, code=%d)", 437 rdata, code));353 rdata, st_code)); 438 354 439 355 /* Create a new transmit buffer. */ … … 442 358 return status; 443 359 360 /* Set initial reference count to 1. */ 361 pjsip_tx_data_add_ref(tdata); 362 444 363 /* Create new response message. */ 445 364 tdata->msg = msg = pjsip_msg_create(tdata->pool, PJSIP_RESPONSE_MSG); 446 365 447 366 /* Set status code and reason text. */ 448 msg->line.status.code = code; 449 msg->line.status.reason = *pjsip_get_status_text(code); 367 msg->line.status.code = st_code; 368 if (st_text) 369 pj_strdup(tdata->pool, &msg->line.status.reason, st_text); 370 else 371 msg->line.status.reason = *pjsip_get_status_text(st_code); 450 372 451 373 /* Set TX data attributes. */ … … 501 423 * and one must not use this function to generate such ACK. 502 424 */ 503 PJ_DEF(void) pjsip_endpt_create_ack(pjsip_endpoint *endpt, 504 pjsip_tx_data *tdata, 505 const pjsip_rx_data *rdata ) 506 { 507 pjsip_msg *ack_msg, *invite_msg; 425 PJ_DEF(pj_status_t) pjsip_endpt_create_ack( pjsip_endpoint *endpt, 426 const pjsip_tx_data *tdata, 427 const pjsip_rx_data *rdata, 428 pjsip_tx_data **ack_tdata) 429 { 430 pjsip_tx_data *ack = NULL; 431 const pjsip_msg *invite_msg; 432 const pjsip_from_hdr *from_hdr; 433 const pjsip_to_hdr *to_hdr; 434 const pjsip_cid_hdr *cid_hdr; 435 const pjsip_cseq_hdr *cseq_hdr; 436 const pjsip_hdr *hdr; 508 437 pjsip_to_hdr *to; 509 pjsip_from_hdr *from; 510 pjsip_cseq_hdr *cseq; 511 pjsip_hdr *hdr; 512 513 /* Make compiler happy. */ 514 PJ_UNUSED_ARG(endpt); 438 pj_status_t status; 439 440 /* Log this action. */ 441 PJ_LOG(5,(THIS_FILE, "pjsip_endpt_create_ack(rdata=%p)", rdata)); 515 442 516 443 /* rdata must be a final response. */ … … 518 445 rdata->msg_info.msg->line.status.code >= 300); 519 446 520 /* Log this action. */ 521 PJ_LOG(5,(THIS_FILE, "pjsip_endpt_create_ack(rdata=%p)", rdata)); 522 523 /* Create new request message. */ 524 ack_msg = pjsip_msg_create(tdata->pool, PJSIP_REQUEST_MSG); 525 pjsip_method_set( &ack_msg->line.req.method, PJSIP_ACK_METHOD ); 447 /* Initialize return value to NULL. */ 448 *ack_tdata = NULL; 526 449 527 450 /* The original INVITE message. */ 528 451 invite_msg = tdata->msg; 529 452 530 /* Copy Request-Uri from the original INVITE. */ 531 ack_msg->line.req.uri = invite_msg->line.req.uri; 532 533 /* Copy Call-ID from the original INVITE */ 534 hdr = pjsip_msg_find_remove_hdr( invite_msg, PJSIP_H_CALL_ID, NULL); 535 pjsip_msg_add_hdr( ack_msg, hdr ); 536 537 /* Copy From header from the original INVITE. */ 538 from = (pjsip_from_hdr*)pjsip_msg_find_remove_hdr(invite_msg, 539 PJSIP_H_FROM, NULL); 540 pjsip_msg_add_hdr( ack_msg, (pjsip_hdr*)from ); 541 542 /* Copy To header from the original INVITE. */ 543 to = (pjsip_to_hdr*)pjsip_msg_find_remove_hdr( invite_msg, 544 PJSIP_H_TO, NULL); 545 pj_strdup(tdata->pool, &to->tag, &rdata->msg_info.to->tag); 546 pjsip_msg_add_hdr( ack_msg, (pjsip_hdr*)to ); 453 /* Get the headers from original INVITE request. */ 454 # define FIND_HDR(m,HNAME) pjsip_msg_find_hdr(m, PJSIP_H_##HNAME, NULL) 455 456 from_hdr = (const pjsip_from_hdr*) FIND_HDR(invite_msg, FROM); 457 PJ_ASSERT_ON_FAIL(from_hdr != NULL, goto on_missing_hdr); 458 459 to_hdr = (const pjsip_to_hdr*) FIND_HDR(invite_msg, TO); 460 PJ_ASSERT_ON_FAIL(to_hdr != NULL, goto on_missing_hdr); 461 462 cid_hdr = (const pjsip_cid_hdr*) FIND_HDR(invite_msg, CALL_ID); 463 PJ_ASSERT_ON_FAIL(to_hdr != NULL, goto on_missing_hdr); 464 465 cseq_hdr = (const pjsip_cseq_hdr*) FIND_HDR(invite_msg, CSEQ); 466 PJ_ASSERT_ON_FAIL(to_hdr != NULL, goto on_missing_hdr); 467 468 # undef FIND_HDR 469 470 /* Create new request message from the headers. */ 471 status = pjsip_endpt_create_request_from_hdr(endpt, 472 &pjsip_ack_method, 473 tdata->msg->line.req.uri, 474 from_hdr, to_hdr, 475 NULL, cid_hdr, 476 cseq_hdr->cseq, NULL, 477 &ack); 478 479 if (status != PJ_SUCCESS) 480 return status; 481 482 /* Update tag in To header with the one from the response (if any). */ 483 to = (pjsip_to_hdr*) pjsip_msg_find_hdr(ack->msg, PJSIP_H_TO, NULL); 484 pj_strdup(ack->pool, &to->tag, &rdata->msg_info.to->tag); 547 485 548 486 /* Must contain single Via, just as the original INVITE. */ 549 hdr = pjsip_msg_find_remove_hdr( invite_msg, PJSIP_H_VIA, NULL); 550 pjsip_msg_insert_first_hdr( ack_msg, hdr ); 551 552 /* Must have the same CSeq value as the original INVITE, but method 553 * changed to ACK 554 */ 555 cseq = (pjsip_cseq_hdr*) pjsip_msg_find_remove_hdr( invite_msg, 556 PJSIP_H_CSEQ, NULL); 557 pjsip_method_set( &cseq->method, PJSIP_ACK_METHOD ); 558 pjsip_msg_add_hdr( ack_msg, (pjsip_hdr*) cseq ); 487 hdr = pjsip_msg_find_hdr( invite_msg, PJSIP_H_VIA, NULL); 488 if (hdr) { 489 pjsip_msg_insert_first_hdr( ack->msg, pjsip_hdr_clone(ack->pool,hdr) ); 490 } 559 491 560 492 /* If the original INVITE has Route headers, those header fields MUST 561 493 * appear in the ACK. 562 494 */ 563 hdr = pjsip_msg_find_ remove_hdr( invite_msg, PJSIP_H_ROUTE, NULL);495 hdr = pjsip_msg_find_hdr( invite_msg, PJSIP_H_ROUTE, NULL); 564 496 while (hdr != NULL) { 565 pjsip_msg_add_hdr( ack_msg, hdr ); 566 hdr = pjsip_msg_find_remove_hdr( invite_msg, PJSIP_H_ROUTE, NULL); 567 } 568 569 /* Set the message in the "tdata" to point to the ACK message. */ 570 tdata->msg = ack_msg; 571 572 /* Reset transmit packet buffer, to force 're-printing' of message. */ 573 tdata->buf.cur = tdata->buf.start; 497 pjsip_msg_add_hdr( ack->msg, pjsip_hdr_clone(ack->pool, hdr) ); 498 hdr = hdr->next; 499 if (hdr == &invite_msg->hdr) 500 break; 501 hdr = pjsip_msg_find_hdr( invite_msg, PJSIP_H_ROUTE, hdr); 502 } 574 503 575 504 /* We're done. 576 505 * "tdata" parameter now contains the ACK message. 577 506 */ 507 *ack_tdata = ack; 508 return PJ_SUCCESS; 509 510 on_missing_hdr: 511 if (ack) 512 pjsip_tx_data_dec_ref(ack); 513 return PJSIP_EMISSINGHDR; 578 514 } 579 515 … … 584 520 */ 585 521 PJ_DEF(pj_status_t) pjsip_endpt_create_cancel( pjsip_endpoint *endpt, 586 pjsip_tx_data *req_tdata,522 const pjsip_tx_data *req_tdata, 587 523 pjsip_tx_data **p_tdata) 588 524 { 589 pjsip_ msg *req_msg; /* the original request. */590 pjsip_tx_data *cancel_tdata;591 pjsip_msg *cancel_msg;592 pjsip_hdr *hdr;593 pjsip_cseq_hdr *req_cseq, *cseq;594 pjsip_uri *req_uri;525 pjsip_tx_data *cancel_tdata = NULL; 526 const pjsip_from_hdr *from_hdr; 527 const pjsip_to_hdr *to_hdr; 528 const pjsip_cid_hdr *cid_hdr; 529 const pjsip_cseq_hdr *cseq_hdr; 530 const pjsip_hdr *hdr; 595 531 pj_status_t status; 596 532 … … 598 534 PJ_LOG(5,(THIS_FILE, "pjsip_endpt_create_cancel(tdata=%p)", req_tdata)); 599 535 600 /* Get the original request. */601 req_msg = req_tdata->msg;602 603 536 /* The transmit buffer must INVITE request. */ 604 PJ_ASSERT_RETURN(req_ msg->type == PJSIP_REQUEST_MSG &&605 req_ msg->line.req.method.id == PJSIP_INVITE_METHOD,537 PJ_ASSERT_RETURN(req_tdata->msg->type == PJSIP_REQUEST_MSG && 538 req_tdata->msg->line.req.method.id == PJSIP_INVITE_METHOD, 606 539 PJ_EINVAL); 607 540 608 /* Create new transmit buffer. */ 609 status = pjsip_endpt_create_tdata( endpt, &cancel_tdata); 610 if (status != PJ_SUCCESS) { 541 /* Get the headers from original INVITE request. */ 542 # define FIND_HDR(m,HNAME) pjsip_msg_find_hdr(m, PJSIP_H_##HNAME, NULL) 543 544 from_hdr = (const pjsip_from_hdr*) FIND_HDR(req_tdata->msg, FROM); 545 PJ_ASSERT_ON_FAIL(from_hdr != NULL, goto on_missing_hdr); 546 547 to_hdr = (const pjsip_to_hdr*) FIND_HDR(req_tdata->msg, TO); 548 PJ_ASSERT_ON_FAIL(to_hdr != NULL, goto on_missing_hdr); 549 550 cid_hdr = (const pjsip_cid_hdr*) FIND_HDR(req_tdata->msg, CALL_ID); 551 PJ_ASSERT_ON_FAIL(to_hdr != NULL, goto on_missing_hdr); 552 553 cseq_hdr = (const pjsip_cseq_hdr*) FIND_HDR(req_tdata->msg, CSEQ); 554 PJ_ASSERT_ON_FAIL(to_hdr != NULL, goto on_missing_hdr); 555 556 # undef FIND_HDR 557 558 /* Create new request message from the headers. */ 559 status = pjsip_endpt_create_request_from_hdr(endpt, 560 &pjsip_cancel_method, 561 req_tdata->msg->line.req.uri, 562 from_hdr, to_hdr, 563 NULL, cid_hdr, 564 cseq_hdr->cseq, NULL, 565 &cancel_tdata); 566 567 if (status != PJ_SUCCESS) 611 568 return status; 612 }613 614 /* Create CANCEL request message. */615 cancel_msg = pjsip_msg_create(cancel_tdata->pool, PJSIP_REQUEST_MSG);616 cancel_tdata->msg = cancel_msg;617 618 /* Request-URI, Call-ID, From, To, and the numeric part of the CSeq are619 * copied from the original request.620 */621 /* Set request line. */622 pjsip_method_set(&cancel_msg->line.req.method, PJSIP_CANCEL_METHOD);623 req_uri = req_msg->line.req.uri;624 cancel_msg->line.req.uri = pjsip_uri_clone(cancel_tdata->pool, req_uri);625 626 /* Copy Call-ID */627 hdr = pjsip_msg_find_hdr(req_msg, PJSIP_H_CALL_ID, NULL);628 pjsip_msg_add_hdr(cancel_msg, pjsip_hdr_clone(cancel_tdata->pool, hdr));629 630 /* Copy From header. */631 hdr = pjsip_msg_find_hdr(req_msg, PJSIP_H_FROM, NULL);632 pjsip_msg_add_hdr(cancel_msg, pjsip_hdr_clone(cancel_tdata->pool, hdr));633 634 /* Copy To header. */635 hdr = pjsip_msg_find_hdr(req_msg, PJSIP_H_TO, NULL);636 pjsip_msg_add_hdr(cancel_msg, pjsip_hdr_clone(cancel_tdata->pool, hdr));637 638 /* Create new CSeq with equal number, but method set to CANCEL. */639 req_cseq = (pjsip_cseq_hdr*) pjsip_msg_find_hdr(req_msg, PJSIP_H_CSEQ, NULL);640 cseq = pjsip_cseq_hdr_create(cancel_tdata->pool);641 cseq->cseq = req_cseq->cseq;642 pjsip_method_set(&cseq->method, PJSIP_CANCEL_METHOD);643 pjsip_msg_add_hdr(cancel_msg, (pjsip_hdr*)cseq);644 569 645 570 /* Must only have single Via which matches the top-most Via in the 646 571 * request being cancelled. 647 572 */ 648 hdr = pjsip_msg_find_hdr(req_msg, PJSIP_H_VIA, NULL); 649 pjsip_msg_insert_first_hdr(cancel_msg, 650 pjsip_hdr_clone(cancel_tdata->pool, hdr)); 573 hdr = pjsip_msg_find_hdr(req_tdata->msg, PJSIP_H_VIA, NULL); 574 if (hdr) { 575 pjsip_msg_insert_first_hdr(cancel_tdata->msg, 576 pjsip_hdr_clone(cancel_tdata->pool, hdr)); 577 } 651 578 652 579 /* If the original request has Route header, the CANCEL request must also … … 654 581 * Copy "Route" header from the request. 655 582 */ 656 hdr = pjsip_msg_find_hdr(req_ msg, PJSIP_H_ROUTE, NULL);583 hdr = pjsip_msg_find_hdr(req_tdata->msg, PJSIP_H_ROUTE, NULL); 657 584 while (hdr != NULL) { 658 pjsip_msg_add_hdr(cancel_msg, pjsip_hdr_clone(cancel_tdata->pool, hdr)); 585 pjsip_msg_add_hdr(cancel_tdata->msg, 586 pjsip_hdr_clone(cancel_tdata->pool, hdr)); 659 587 hdr = hdr->next; 660 if (hdr != &cancel_ msg->hdr)661 hdr = pjsip_msg_find_hdr( req_msg, PJSIP_H_ROUTE, hdr);588 if (hdr != &cancel_tdata->msg->hdr) 589 hdr = pjsip_msg_find_hdr(cancel_tdata->msg, PJSIP_H_ROUTE, hdr); 662 590 else 663 591 break; … … 669 597 *p_tdata = cancel_tdata; 670 598 return PJ_SUCCESS; 671 } 672 673 /* Get the address parameters (host, port, flag, TTL, etc) to send the 674 * response. 675 */ 676 PJ_DEF(pj_status_t) pjsip_get_response_addr(pj_pool_t *pool, 677 const pjsip_transport *req_transport, 678 const pjsip_via_hdr *via, 679 pjsip_host_info *send_addr) 680 { 681 /* Determine the destination address (section 18.2.2): 682 * - for TCP, SCTP, or TLS, send the response using the transport where 683 * the request was received. 684 * - if maddr parameter is present, send to this address using the port 685 * in sent-by or 5060. If multicast is used, the TTL in the Via must 686 * be used, or 1 if ttl parameter is not present. 687 * - otherwise if received parameter is present, set to this address. 688 * - otherwise send to the address in sent-by. 599 600 on_missing_hdr: 601 if (cancel_tdata) 602 pjsip_tx_data_dec_ref(cancel_tdata); 603 return PJSIP_EMISSINGHDR; 604 } 605 606 607 /* 608 * Find which destination to be used to send the request message, based 609 * on the request URI and Route headers in the message. The procedure 610 * used here follows the guidelines on sending the request in RFC 3261 611 * chapter 8.1.2. 612 */ 613 PJ_DEF(pj_status_t) pjsip_get_request_addr( pjsip_tx_data *tdata, 614 pjsip_host_info *dest_info ) 615 { 616 const pjsip_uri *new_request_uri, *target_uri; 617 const pjsip_name_addr *topmost_route_uri; 618 pjsip_route_hdr *first_route_hdr, *last_route_hdr; 619 620 PJ_ASSERT_RETURN(tdata->msg->type == PJSIP_REQUEST_MSG, 621 PJSIP_ENOTREQUESTMSG); 622 PJ_ASSERT_RETURN(dest_info != NULL, PJ_EINVAL); 623 624 /* Get the first "Route" header from the message. If the message doesn't 625 * have any "Route" headers but the endpoint has, then copy the "Route" 626 * headers from the endpoint first. 689 627 */ 690 send_addr->flag = req_transport->flag; 691 send_addr->type = req_transport->key.type; 692 693 if (PJSIP_TRANSPORT_IS_RELIABLE(req_transport)) { 694 pj_strdup( pool, &send_addr->addr.host, 695 &req_transport->remote_name.host); 696 send_addr->addr.port = req_transport->remote_name.port; 697 628 last_route_hdr = first_route_hdr = 629 pjsip_msg_find_hdr(tdata->msg, PJSIP_H_ROUTE, NULL); 630 if (first_route_hdr) { 631 topmost_route_uri = &first_route_hdr->name_addr; 632 while (last_route_hdr->next != (void*)&tdata->msg->hdr) { 633 pjsip_route_hdr *hdr; 634 hdr = pjsip_msg_find_hdr(tdata->msg, PJSIP_H_ROUTE, 635 last_route_hdr->next); 636 if (!hdr) 637 break; 638 last_route_hdr = hdr; 639 } 698 640 } else { 699 /* Set the host part */ 700 if (via->maddr_param.slen) { 701 pj_strdup(pool, &send_addr->addr.host, &via->maddr_param); 702 } else if (via->recvd_param.slen) { 703 pj_strdup(pool, &send_addr->addr.host, &via->recvd_param); 641 topmost_route_uri = NULL; 642 } 643 644 /* If Route headers exist, and the first element indicates loose-route, 645 * the URI is taken from the Request-URI, and we keep all existing Route 646 * headers intact. 647 * If Route headers exist, and the first element DOESN'T indicate loose 648 * route, the URI is taken from the first Route header, and remove the 649 * first Route header from the message. 650 * Otherwise if there's no Route headers, the URI is taken from the 651 * Request-URI. 652 */ 653 if (topmost_route_uri) { 654 pj_bool_t has_lr_param; 655 656 if (PJSIP_URI_SCHEME_IS_SIP(topmost_route_uri) || 657 PJSIP_URI_SCHEME_IS_SIPS(topmost_route_uri)) 658 { 659 const pjsip_url *url = pjsip_uri_get_uri((void*)topmost_route_uri); 660 has_lr_param = url->lr_param; 704 661 } else { 705 pj_strdup(pool, &send_addr->addr.host, &via->sent_by.host); 706 } 707 708 /* Set the port */ 709 send_addr->addr.port = via->sent_by.port; 710 } 711 662 has_lr_param = 0; 663 } 664 665 if (has_lr_param) { 666 new_request_uri = tdata->msg->line.req.uri; 667 /* We shouldn't need to delete topmost Route if it has lr param. 668 * But seems like it breaks some proxy implementation, so we 669 * delete it anyway. 670 */ 671 /* 672 pj_list_erase(first_route_hdr); 673 if (first_route_hdr == last_route_hdr) 674 last_route_hdr = NULL; 675 */ 676 } else { 677 new_request_uri = pjsip_uri_get_uri((void*)topmost_route_uri); 678 pj_list_erase(first_route_hdr); 679 if (first_route_hdr == last_route_hdr) 680 last_route_hdr = NULL; 681 } 682 683 target_uri = (pjsip_uri*)topmost_route_uri; 684 685 } else { 686 target_uri = new_request_uri = tdata->msg->line.req.uri; 687 } 688 689 /* The target URI must be a SIP/SIPS URL so we can resolve it's address. 690 * Otherwise we're in trouble (i.e. there's no host part in tel: URL). 691 */ 692 pj_memset(dest_info, 0, sizeof(*dest_info)); 693 694 if (PJSIP_URI_SCHEME_IS_SIPS(target_uri)) { 695 pjsip_uri *uri = (pjsip_uri*) target_uri; 696 const pjsip_url *url = (const pjsip_url*)pjsip_uri_get_uri(uri); 697 dest_info->flag |= (PJSIP_TRANSPORT_SECURE | PJSIP_TRANSPORT_RELIABLE); 698 pj_strdup(tdata->pool, &dest_info->addr.host, &url->host); 699 dest_info->addr.port = url->port; 700 dest_info->type = 701 pjsip_transport_get_type_from_name(&url->transport_param); 702 703 } else if (PJSIP_URI_SCHEME_IS_SIP(target_uri)) { 704 pjsip_uri *uri = (pjsip_uri*) target_uri; 705 const pjsip_url *url = (const pjsip_url*)pjsip_uri_get_uri(uri); 706 pj_strdup(tdata->pool, &dest_info->addr.host, &url->host); 707 dest_info->addr.port = url->port; 708 dest_info->type = 709 pjsip_transport_get_type_from_name(&url->transport_param); 710 #if PJ_HAS_TCP 711 if (dest_info->type == PJSIP_TRANSPORT_TCP || 712 dest_info->type == PJSIP_TRANSPORT_SCTP) 713 { 714 dest_info->flag |= PJSIP_TRANSPORT_RELIABLE; 715 } 716 #endif 717 } else { 718 pj_assert(!"Unsupported URI scheme!"); 719 PJ_TODO(SUPPORT_REQUEST_ADDR_RESOLUTION_FOR_TEL_URI); 720 return PJSIP_EINVALIDSCHEME; 721 } 722 723 /* If target URI is different than request URI, replace 724 * request URI add put the original URI in the last Route header. 725 */ 726 if (new_request_uri && new_request_uri!=tdata->msg->line.req.uri) { 727 pjsip_route_hdr *route = pjsip_route_hdr_create(tdata->pool); 728 route->name_addr.uri = tdata->msg->line.req.uri; 729 if (last_route_hdr) 730 pj_list_insert_after(last_route_hdr, route); 731 else 732 pjsip_msg_add_hdr(tdata->msg, (pjsip_hdr*)route); 733 tdata->msg->line.req.uri = (pjsip_uri*)new_request_uri; 734 } 735 736 /* Success. */ 737 return PJ_SUCCESS; 738 } 739 740 741 /* Transport callback for sending stateless request. 742 * This is one of the most bizzare function in pjsip, so 743 * good luck if you happen to debug this function!! 744 */ 745 static void stateless_send_transport_cb( void *token, 746 pjsip_tx_data *tdata, 747 pj_ssize_t sent ) 748 { 749 pjsip_send_state *stateless_data = token; 750 751 PJ_UNUSED_ARG(tdata); 752 pj_assert(tdata == stateless_data->tdata); 753 754 for (;;) { 755 pj_status_t status; 756 pj_bool_t cont; 757 758 pj_sockaddr_t *cur_addr; 759 pjsip_transport_type_e cur_addr_type; 760 int cur_addr_len; 761 762 pjsip_via_hdr *via; 763 764 if (sent == -PJ_EPENDING) { 765 /* This is the initial process. 766 * When the process started, this function will be called by 767 * stateless_send_resolver_callback() with sent argument set to 768 * -PJ_EPENDING. 769 */ 770 cont = PJ_TRUE; 771 } else { 772 /* There are two conditions here: 773 * (1) Message is sent (i.e. sent > 0), 774 * (2) Failure (i.e. sent <= 0) 775 */ 776 cont = (sent > 0) ? PJ_FALSE : 777 (stateless_data->cur_addr<stateless_data->addr.count-1); 778 if (stateless_data->app_cb) { 779 (*stateless_data->app_cb)(stateless_data, sent, &cont); 780 } else { 781 /* Doesn't have application callback. 782 * Terminate the process. 783 */ 784 cont = PJ_FALSE; 785 } 786 } 787 788 /* Finished with this transport. */ 789 if (stateless_data->cur_transport) { 790 pjsip_transport_dec_ref(stateless_data->cur_transport); 791 stateless_data->cur_transport = NULL; 792 } 793 794 /* Done if application doesn't want to continue. */ 795 if (sent > 0 || !cont) { 796 pjsip_tx_data_dec_ref(tdata); 797 return; 798 } 799 800 /* Try next address, if any, and only when this is not the 801 * first invocation. 802 */ 803 if (sent != -PJ_EPENDING) { 804 stateless_data->cur_addr++; 805 } 806 807 /* Have next address? */ 808 if (stateless_data->cur_addr >= stateless_data->addr.count) { 809 /* This only happens when a rather buggy application has 810 * sent 'cont' to PJ_TRUE when the initial value was PJ_FALSE. 811 * In this case just stop the processing; we don't need to 812 * call the callback again as application has been informed 813 * before. 814 */ 815 pjsip_tx_data_dec_ref(tdata); 816 return; 817 } 818 819 /* Keep current server address information handy. */ 820 cur_addr = &stateless_data->addr.entry[stateless_data->cur_addr].addr; 821 cur_addr_type = stateless_data->addr.entry[stateless_data->cur_addr].type; 822 cur_addr_len = stateless_data->addr.entry[stateless_data->cur_addr].addr_len; 823 824 /* Acquire transport. */ 825 status = pjsip_endpt_acquire_transport( stateless_data->endpt, 826 cur_addr_type, 827 cur_addr, 828 cur_addr_len, 829 &stateless_data->cur_transport); 830 if (status != PJ_SUCCESS) { 831 sent = -status; 832 continue; 833 } 834 835 /* Modify Via header. */ 836 via = (pjsip_via_hdr*) pjsip_msg_find_hdr( tdata->msg, 837 PJSIP_H_VIA, NULL); 838 if (!via) { 839 /* Shouldn't happen if request was created with PJSIP API! 840 * But we handle the case anyway for robustness. 841 */ 842 pj_assert(!"Via header not found!"); 843 via = pjsip_via_hdr_create(tdata->pool); 844 pjsip_msg_insert_first_hdr(tdata->msg, (pjsip_hdr*)via); 845 } 846 847 if (via->branch_param.slen == 0) { 848 pj_str_t tmp; 849 via->branch_param.ptr = pj_pool_alloc(tdata->pool, 850 PJSIP_MAX_BRANCH_LEN); 851 via->branch_param.slen = PJSIP_MAX_BRANCH_LEN; 852 pj_memcpy(via->branch_param.ptr, PJSIP_RFC3261_BRANCH_ID, 853 PJSIP_RFC3261_BRANCH_LEN); 854 tmp.ptr = via->branch_param.ptr + PJSIP_RFC3261_BRANCH_LEN; 855 pj_generate_unique_string(&tmp); 856 } 857 858 via->transport = pj_str(stateless_data->cur_transport->type_name); 859 via->sent_by = stateless_data->cur_transport->local_name; 860 via->rport_param = 0; 861 862 /* Send message using this transport. */ 863 status = pjsip_transport_send( stateless_data->cur_transport, 864 tdata, 865 cur_addr, 866 cur_addr_len, 867 stateless_data, 868 &stateless_send_transport_cb); 869 if (status == PJ_SUCCESS) { 870 /* Recursively call this function. */ 871 sent = tdata->buf.cur - tdata->buf.start; 872 stateless_send_transport_cb( stateless_data, tdata, sent ); 873 return; 874 } else if (status == PJ_EPENDING) { 875 /* This callback will be called later. */ 876 return; 877 } else { 878 /* Recursively call this function. */ 879 sent = -status; 880 stateless_send_transport_cb( stateless_data, tdata, sent ); 881 return; 882 } 883 } 884 885 } 886 887 /* Resolver callback for sending stateless request. */ 888 static void 889 stateless_send_resolver_callback( pj_status_t status, 890 void *token, 891 const struct pjsip_server_addresses *addr) 892 { 893 pjsip_send_state *stateless_data = token; 894 895 /* Fail on server resolution. */ 896 if (status != PJ_SUCCESS) { 897 if (stateless_data->app_cb) { 898 pj_bool_t cont = PJ_FALSE; 899 (*stateless_data->app_cb)(stateless_data, -status, &cont); 900 } 901 pjsip_tx_data_dec_ref(stateless_data->tdata); 902 return; 903 } 904 905 /* Copy server addresses */ 906 pj_memcpy( &stateless_data->addr, addr, sizeof(pjsip_server_addresses)); 907 908 /* Process the addresses. */ 909 stateless_send_transport_cb( stateless_data, stateless_data->tdata, 910 -PJ_EPENDING); 911 } 912 913 /* 914 * Send stateless request. 915 * The sending process consists of several stages: 916 * - determine which host to contact (#pjsip_get_request_addr). 917 * - resolve the host (#pjsip_endpt_resolve) 918 * - establish transport (#pjsip_endpt_acquire_transport) 919 * - send the message (#pjsip_transport_send) 920 */ 921 PJ_DEF(pj_status_t) 922 pjsip_endpt_send_request_stateless(pjsip_endpoint *endpt, 923 pjsip_tx_data *tdata, 924 void *token, 925 void (*cb)(pjsip_send_state*, 926 pj_ssize_t sent, 927 pj_bool_t *cont)) 928 { 929 pjsip_host_info dest_info; 930 pjsip_send_state *stateless_data; 931 pj_status_t status; 932 933 PJ_ASSERT_RETURN(endpt && tdata, PJ_EINVAL); 934 935 /* Get destination name to contact. */ 936 status = pjsip_get_request_addr(tdata, &dest_info); 937 if (status != PJ_SUCCESS) 938 return status; 939 940 /* Keep stateless data. */ 941 stateless_data = pj_pool_zalloc(tdata->pool, sizeof(pjsip_send_state)); 942 stateless_data->token = token; 943 stateless_data->endpt = endpt; 944 stateless_data->tdata = tdata; 945 stateless_data->app_cb = cb; 946 947 /* Resolve destination host. 948 * The processing then resumed when the resolving callback is called. 949 */ 950 pjsip_endpt_resolve( endpt, tdata->pool, &dest_info, stateless_data, 951 &stateless_send_resolver_callback); 712 952 return PJ_SUCCESS; 713 953 } 954 955 /* 956 * Determine which address (and transport) to use to send response message 957 * based on the received request. This function follows the specification 958 * in section 18.2.2 of RFC 3261 and RFC 3581 for calculating the destination 959 * address and transport. 960 */ 961 PJ_DEF(pj_status_t) pjsip_get_response_addr( pj_pool_t *pool, 962 pjsip_rx_data *rdata, 963 pjsip_response_addr *res_addr ) 964 { 965 pjsip_transport *src_transport = rdata->tp_info.transport; 966 967 /* Check arguments. */ 968 PJ_ASSERT_RETURN(pool && rdata && res_addr, PJ_EINVAL); 969 970 /* All requests must have "received" parameter. 971 * This must always be done in transport layer. 972 */ 973 pj_assert(rdata->msg_info.via->recvd_param.slen != 0); 974 975 /* Do the calculation based on RFC 3261 Section 18.2.2 and RFC 3581 */ 976 977 if (PJSIP_TRANSPORT_IS_RELIABLE(src_transport)) { 978 /* For reliable protocol such as TCP or SCTP, or TLS over those, the 979 * response MUST be sent using the existing connection to the source 980 * of the original request that created the transaction, if that 981 * connection is still open. 982 * If that connection is no longer open, the server SHOULD open a 983 * connection to the IP address in the received parameter, if present, 984 * using the port in the sent-by value, or the default port for that 985 * transport, if no port is specified. 986 * If that connection attempt fails, the server SHOULD use the 987 * procedures in [4] for servers in order to determine the IP address 988 * and port to open the connection and send the response to. 989 */ 990 res_addr->transport = rdata->tp_info.transport; 991 pj_memcpy(&res_addr->addr, &rdata->pkt_info.src_addr, 992 rdata->pkt_info.src_addr_len); 993 res_addr->addr_len = rdata->pkt_info.src_addr_len; 994 res_addr->dst_host.type = src_transport->key.type; 995 res_addr->dst_host.flag = src_transport->flag; 996 pj_strdup( pool, &res_addr->dst_host.addr.host, 997 &rdata->msg_info.via->recvd_param); 998 res_addr->dst_host.addr.port = rdata->msg_info.via->sent_by.port; 999 if (res_addr->dst_host.addr.port == 0) { 1000 res_addr->dst_host.addr.port = 1001 pjsip_transport_get_default_port_for_type(res_addr->dst_host.type); 1002 } 1003 1004 } else if (rdata->msg_info.via->maddr_param.slen) { 1005 /* Otherwise, if the Via header field value contains a maddr parameter, 1006 * the response MUST be forwarded to the address listed there, using 1007 * the port indicated in sent-by, or port 5060 if none is present. 1008 * If the address is a multicast address, the response SHOULD be sent 1009 * using the TTL indicated in the ttl parameter, or with a TTL of 1 if 1010 * that parameter is not present. 1011 */ 1012 res_addr->transport = NULL; 1013 res_addr->dst_host.type = src_transport->key.type; 1014 res_addr->dst_host.flag = src_transport->flag; 1015 pj_strdup( pool, &res_addr->dst_host.addr.host, 1016 &rdata->msg_info.via->maddr_param); 1017 res_addr->dst_host.addr.port = rdata->msg_info.via->sent_by.port; 1018 if (res_addr->dst_host.addr.port == 0) 1019 res_addr->dst_host.addr.port = 5060; 1020 1021 } else if (rdata->msg_info.via->rport_param >= 0) { 1022 /* There is both a "received" parameter and an "rport" parameter, 1023 * the response MUST be sent to the IP address listed in the "received" 1024 * parameter, and the port in the "rport" parameter. 1025 * The response MUST be sent from the same address and port that the 1026 * corresponding request was received on. 1027 */ 1028 res_addr->transport = rdata->tp_info.transport; 1029 pj_memcpy(&res_addr->addr, &rdata->pkt_info.src_addr, 1030 rdata->pkt_info.src_addr_len); 1031 res_addr->addr_len = rdata->pkt_info.src_addr_len; 1032 res_addr->dst_host.type = src_transport->key.type; 1033 res_addr->dst_host.flag = src_transport->flag; 1034 pj_strdup( pool, &res_addr->dst_host.addr.host, 1035 &rdata->msg_info.via->recvd_param); 1036 res_addr->dst_host.addr.port = rdata->msg_info.via->sent_by.port; 1037 if (res_addr->dst_host.addr.port == 0) { 1038 res_addr->dst_host.addr.port = 1039 pjsip_transport_get_default_port_for_type(res_addr->dst_host.type); 1040 } 1041 1042 } else { 1043 res_addr->transport = NULL; 1044 res_addr->dst_host.type = src_transport->key.type; 1045 res_addr->dst_host.flag = src_transport->flag; 1046 pj_strdup( pool, &res_addr->dst_host.addr.host, 1047 &rdata->msg_info.via->recvd_param); 1048 res_addr->dst_host.addr.port = rdata->msg_info.via->sent_by.port; 1049 if (res_addr->dst_host.addr.port == 0) { 1050 res_addr->dst_host.addr.port = 1051 pjsip_transport_get_default_port_for_type(res_addr->dst_host.type); 1052 } 1053 } 1054 1055 return PJ_SUCCESS; 1056 } 1057 1058 /* 1059 * Callback called by transport during send_response. 1060 */ 1061 static void send_response_transport_cb(void *token, pjsip_tx_data *tdata, 1062 pj_ssize_t sent) 1063 { 1064 pjsip_send_state *send_state = token; 1065 pj_bool_t cont = PJ_FALSE; 1066 1067 /* Call callback, if any. */ 1068 if (send_state->app_cb) 1069 (*send_state->app_cb)(send_state, sent, &cont); 1070 1071 /* Decrement transport reference counter. */ 1072 pjsip_transport_dec_ref(send_state->cur_transport); 1073 1074 /* Decrement transmit data ref counter. */ 1075 pjsip_tx_data_dec_ref(tdata); 1076 } 1077 1078 /* 1079 * Resolver calback during send_response. 1080 */ 1081 static void send_response_resolver_cb( pj_status_t status, void *token, 1082 const pjsip_server_addresses *addr ) 1083 { 1084 pjsip_send_state *send_state = token; 1085 1086 if (status != PJ_SUCCESS) { 1087 if (send_state->app_cb) { 1088 pj_bool_t cont = PJ_FALSE; 1089 (*send_state->app_cb)(send_state, -status, &cont); 1090 } 1091 pjsip_tx_data_dec_ref(send_state->tdata); 1092 return; 1093 } 1094 1095 /* Only handle the first address resolved. */ 1096 1097 /* Acquire transport. */ 1098 status = pjsip_endpt_acquire_transport( send_state->endpt, 1099 addr->entry[0].type, 1100 &addr->entry[0].addr, 1101 addr->entry[0].addr_len, 1102 &send_state->cur_transport); 1103 if (status != PJ_SUCCESS) { 1104 if (send_state->app_cb) { 1105 pj_bool_t cont = PJ_FALSE; 1106 (*send_state->app_cb)(send_state, -status, &cont); 1107 } 1108 pjsip_tx_data_dec_ref(send_state->tdata); 1109 return; 1110 } 1111 1112 /* Send response using the transoprt. */ 1113 status = pjsip_transport_send( send_state->cur_transport, 1114 send_state->tdata, 1115 &addr->entry[0].addr, 1116 addr->entry[0].addr_len, 1117 send_state, 1118 &send_response_transport_cb); 1119 if (status == PJ_SUCCESS) { 1120 pj_ssize_t sent = send_state->tdata->buf.cur - 1121 send_state->tdata->buf.start; 1122 send_response_transport_cb(send_state, send_state->tdata, sent); 1123 1124 } else if (status == PJ_EPENDING) { 1125 /* Transport callback will be called later. */ 1126 } else { 1127 send_response_transport_cb(send_state, send_state->tdata, -status); 1128 } 1129 } 1130 1131 /* 1132 * Send response. 1133 */ 1134 PJ_DEF(pj_status_t) pjsip_endpt_send_response( pjsip_endpoint *endpt, 1135 pjsip_response_addr *res_addr, 1136 pjsip_tx_data *tdata, 1137 void *token, 1138 void (*cb)(pjsip_send_state*, 1139 pj_ssize_t sent, 1140 pj_bool_t *cont)) 1141 { 1142 /* Determine which transports and addresses to send the response, 1143 * based on Section 18.2.2 of RFC 3261. 1144 */ 1145 pjsip_send_state *send_state; 1146 pj_status_t status; 1147 1148 /* Create structure to keep the sending state. */ 1149 send_state = pj_pool_zalloc(tdata->pool, sizeof(pjsip_send_state)); 1150 send_state->endpt = endpt; 1151 send_state->tdata = tdata; 1152 send_state->token = token; 1153 send_state->app_cb = cb; 1154 1155 if (res_addr->transport != NULL) { 1156 send_state->cur_transport = res_addr->transport; 1157 pjsip_transport_add_ref(send_state->cur_transport); 1158 1159 status = pjsip_transport_send( send_state->cur_transport, tdata, 1160 &res_addr->addr, 1161 res_addr->addr_len, 1162 send_state, 1163 &send_response_transport_cb ); 1164 if (status == PJ_SUCCESS) { 1165 pj_ssize_t sent = tdata->buf.cur - tdata->buf.start; 1166 send_response_transport_cb(send_state, tdata, sent); 1167 return PJ_SUCCESS; 1168 } else if (status == PJ_EPENDING) { 1169 /* Callback will be called later. */ 1170 return PJ_SUCCESS; 1171 } else { 1172 send_response_transport_cb(send_state, tdata, -status); 1173 return status; 1174 } 1175 } else { 1176 pjsip_endpt_resolve(endpt, tdata->pool, &res_addr->dst_host, 1177 send_state, &send_response_resolver_cb); 1178 return PJ_SUCCESS; 1179 } 1180 } 1181 714 1182 715 1183 /*
Note: See TracChangeset
for help on using the changeset viewer.