Changeset 163 for pjproject/trunk/pjsip/src/pjsip-ua/sip_inv.c
- Timestamp:
- Feb 9, 2006 1:26:14 AM (18 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
pjproject/trunk/pjsip/src/pjsip-ua/sip_inv.c
r162 r163 29 29 #include <pj/assert.h> 30 30 #include <pj/os.h> 31 #include <pj/log.h> 32 31 33 32 34 #define THIS_FILE "sip_invite_session.c" … … 87 89 88 90 91 /* Invite session data to be attached to transaction. */ 92 struct tsx_inv_data 93 { 94 pjsip_inv_session *inv; 95 pj_bool_t sdp_done; 96 }; 97 98 89 99 /* 90 100 * Module load() … … 705 715 { 706 716 pjsip_inv_session *inv; 717 struct tsx_inv_data *tsx_inv_data; 707 718 pjsip_msg *msg; 708 719 pjmedia_sdp_session *rem_sdp = NULL; … … 778 789 /* Save the invite transaction. */ 779 790 inv->invite_tsx = pjsip_rdata_get_tsx(rdata); 780 inv->invite_tsx->mod_data[mod_inv.mod.id] = inv; 791 792 /* Attach our data to the transaction. */ 793 tsx_inv_data = pj_pool_zalloc(inv->invite_tsx->pool, 794 sizeof(struct tsx_inv_data)); 795 tsx_inv_data->inv = inv; 796 inv->invite_tsx->mod_data[mod_inv.mod.id] = tsx_inv_data; 781 797 782 798 /* Done */ … … 892 908 return status; 893 909 } 910 911 /* 912 * Check in incoming message for SDP offer/answer. 913 */ 914 static void inv_check_sdp_in_incoming_msg( pjsip_inv_session *inv, 915 pjsip_transaction *tsx, 916 pjsip_rx_data *rdata) 917 { 918 struct tsx_inv_data *tsx_inv_data; 919 static const pj_str_t str_application = { "application", 11 }; 920 static const pj_str_t str_sdp = { "sdp", 3 }; 921 pj_status_t status; 922 pjsip_msg *msg; 923 pjmedia_sdp_session *sdp; 924 925 /* Get/attach invite session's transaction data */ 926 tsx_inv_data = tsx->mod_data[mod_inv.mod.id]; 927 if (tsx_inv_data == NULL) { 928 tsx_inv_data = pj_pool_zalloc(tsx->pool, sizeof(struct tsx_inv_data)); 929 tsx_inv_data->inv = inv; 930 tsx->mod_data[mod_inv.mod.id] = tsx_inv_data; 931 } 932 933 /* MUST NOT do multiple SDP offer/answer in a single transaction. 934 */ 935 936 if (tsx_inv_data->sdp_done) 937 return; 938 939 /* Check if SDP is present in the message. */ 940 941 msg = rdata->msg_info.msg; 942 if (msg->body == NULL) { 943 /* Message doesn't have body. */ 944 return; 945 } 946 947 if (pj_stricmp(&msg->body->content_type.type, &str_application) || 948 pj_stricmp(&msg->body->content_type.subtype, &str_sdp)) 949 { 950 /* Message body is not "application/sdp" */ 951 return; 952 } 953 954 /* Parse the SDP body. */ 955 956 status = pjmedia_sdp_parse(rdata->tp_info.pool, msg->body->data, 957 msg->body->len, &sdp); 958 if (status != PJ_SUCCESS) { 959 char errmsg[PJ_ERR_MSG_SIZE]; 960 pj_strerror(status, errmsg, sizeof(errmsg)); 961 PJ_LOG(4,(THIS_FILE, "Error parsing SDP in %s: %s", 962 pjsip_rx_data_get_info(rdata), errmsg)); 963 return; 964 } 965 966 /* The SDP can be an offer or answer, depending on negotiator's state */ 967 968 if (inv->neg == NULL || 969 pjmedia_sdp_neg_get_state(inv->neg) == PJMEDIA_SDP_NEG_STATE_DONE) 970 { 971 972 /* This is an offer. */ 973 974 if (inv->neg == NULL) { 975 status=pjmedia_sdp_neg_create_w_remote_offer(inv->pool, NULL, 976 sdp, &inv->neg); 977 } else { 978 status=pjmedia_sdp_neg_set_remote_offer(inv->pool, inv->neg, sdp); 979 } 980 981 if (status != PJ_SUCCESS) { 982 char errmsg[PJ_ERR_MSG_SIZE]; 983 pj_strerror(status, errmsg, sizeof(errmsg)); 984 PJ_LOG(4,(THIS_FILE, "Error processing SDP offer in %s: %s", 985 pjsip_rx_data_get_info(rdata), errmsg)); 986 return; 987 } 988 989 /* Inform application about remote offer. */ 990 991 if (mod_inv.cb.on_rx_offer) 992 (*mod_inv.cb.on_rx_offer)(inv); 993 994 } else if (pjmedia_sdp_neg_get_state(inv->neg) == 995 PJMEDIA_SDP_NEG_STATE_LOCAL_OFFER) 996 { 997 998 /* This is an answer. 999 * Process and negotiate remote answer. 1000 */ 1001 1002 status = pjmedia_sdp_neg_set_remote_answer(inv->pool, inv->neg, sdp); 1003 1004 if (status != PJ_SUCCESS) { 1005 char errmsg[PJ_ERR_MSG_SIZE]; 1006 pj_strerror(status, errmsg, sizeof(errmsg)); 1007 PJ_LOG(4,(THIS_FILE, "Error processing SDP answer in %s: %s", 1008 pjsip_rx_data_get_info(rdata), errmsg)); 1009 return; 1010 } 1011 1012 /* Negotiate SDP */ 1013 1014 inv_negotiate_sdp(inv); 1015 1016 /* Mark this transaction has having SDP offer/answer done. */ 1017 1018 tsx_inv_data->sdp_done = 1; 1019 1020 } else { 1021 1022 PJ_LOG(5,(THIS_FILE, "Ignored SDP in %s: negotiator state is %s", 1023 pjsip_rx_data_get_info(rdata), 1024 pjmedia_sdp_neg_state_str(pjmedia_sdp_neg_get_state(inv->neg)))); 1025 } 1026 1027 } 1028 1029 894 1030 895 1031 /* … … 949 1085 */ 950 1086 if (st_code/10 == 18 || st_code/10 == 20) { 951 const pjmedia_sdp_session *local; 952 953 status = pjmedia_sdp_neg_get_neg_local(inv->neg, &local); 954 if (status == PJ_SUCCESS) 955 last_res->msg->body = create_sdp_body(last_res->pool, local); 1087 1088 pjmedia_sdp_neg_state neg_state; 1089 1090 neg_state = inv->neg ? pjmedia_sdp_neg_get_state(inv->neg) : 1091 PJMEDIA_SDP_NEG_STATE_NULL; 1092 1093 if (neg_state == PJMEDIA_SDP_NEG_STATE_LOCAL_OFFER || 1094 neg_state == PJMEDIA_SDP_NEG_STATE_WAIT_NEGO) 1095 { 1096 const pjmedia_sdp_session *local; 1097 1098 status = pjmedia_sdp_neg_get_neg_local(inv->neg, &local); 1099 if (status == PJ_SUCCESS) 1100 last_res->msg->body = create_sdp_body(last_res->pool, local); 1101 } 956 1102 957 1103 /* Start negotiation, if ready. */ 958 if ( pjmedia_sdp_neg_get_state(inv->neg)== PJMEDIA_SDP_NEG_STATE_WAIT_NEGO) {1104 if (neg_state == PJMEDIA_SDP_NEG_STATE_WAIT_NEGO) { 959 1105 status = inv_negotiate_sdp(inv); 960 1106 if (status != PJ_SUCCESS) { … … 1107 1253 if (tdata->msg->type == PJSIP_REQUEST_MSG) { 1108 1254 pjsip_transaction *tsx; 1255 struct tsx_inv_data *tsx_inv_data; 1109 1256 1110 1257 status = pjsip_dlg_send_request(inv->dlg, tdata, &tsx); … … 1112 1259 return status; 1113 1260 1114 tsx->mod_data[mod_inv.mod.id] = inv; 1261 tsx_inv_data = pj_pool_zalloc(tsx->pool, sizeof(struct tsx_inv_data)); 1262 tsx_inv_data->inv = inv; 1263 1264 tsx->mod_data[mod_inv.mod.id] = tsx_inv_data; 1115 1265 tsx->mod_data[mod_inv.app_user->id] = token; 1116 1266 … … 1332 1482 case PJSIP_TSX_STATE_PROCEEDING: 1333 1483 if (dlg->remote.info->tag.slen) { 1484 1334 1485 inv_set_state(inv, PJSIP_INV_STATE_EARLY, e); 1486 1487 inv_check_sdp_in_incoming_msg(inv, tsx, 1488 e->body.tsx_state.src.rdata); 1489 1335 1490 } else { 1336 1491 /* Ignore 100 (Trying) response, as it doesn't change … … 1348 1503 pj_assert(0); 1349 1504 inv_set_state(inv, PJSIP_INV_STATE_CONNECTING, e); 1505 1506 inv_check_sdp_in_incoming_msg(inv, tsx, 1507 e->body.tsx_state.src.rdata); 1350 1508 1351 1509 } else if (tsx->status_code==401 || tsx->status_code==407) { … … 1396 1554 inv_set_state(inv, PJSIP_INV_STATE_CONNECTING, e); 1397 1555 1556 inv_check_sdp_in_incoming_msg(inv, tsx, 1557 e->body.tsx_state.src.rdata); 1558 1398 1559 /* Send ACK */ 1399 1560 pj_assert(e->body.tsx_state.type == PJSIP_EVENT_RX_MSG); 1400 1561 1401 1562 inv_send_ack(inv, e->body.tsx_state.src.rdata); 1563 1402 1564 1403 1565 } else { … … 1497 1659 /* Send/received another provisional response. */ 1498 1660 inv_set_state(inv, PJSIP_INV_STATE_EARLY, e); 1661 1662 if (e->body.tsx_state.type == PJSIP_EVENT_RX_MSG) { 1663 inv_check_sdp_in_incoming_msg(inv, tsx, 1664 e->body.tsx_state.src.rdata); 1665 } 1499 1666 break; 1500 1667 1501 1668 case PJSIP_TSX_STATE_COMPLETED: 1502 if (tsx->status_code/100 == 2) 1669 if (tsx->status_code/100 == 2) { 1503 1670 inv_set_state(inv, PJSIP_INV_STATE_CONNECTING, e); 1504 else 1671 if (e->body.tsx_state.type == PJSIP_EVENT_RX_MSG) { 1672 inv_check_sdp_in_incoming_msg(inv, tsx, 1673 e->body.tsx_state.src.rdata); 1674 } 1675 1676 } else 1505 1677 inv_set_state(inv, PJSIP_INV_STATE_DISCONNECTED, e); 1506 1678 break; … … 1517 1689 /* Set state to CONNECTING */ 1518 1690 inv_set_state(inv, PJSIP_INV_STATE_CONNECTING, e); 1691 1692 if (e->body.tsx_state.type == PJSIP_EVENT_RX_MSG) { 1693 inv_check_sdp_in_incoming_msg(inv, tsx, 1694 e->body.tsx_state.src.rdata); 1695 } 1519 1696 1520 1697 /* if UAC, send ACK and move state to confirmed. */ … … 1606 1783 } else if (tsx->method.id == PJSIP_BYE_METHOD && 1607 1784 tsx->role == PJSIP_ROLE_UAC && 1608 tsx->state == PJSIP_TSX_STATE_COMPLETED) 1785 (tsx->state == PJSIP_TSX_STATE_COMPLETED || 1786 tsx->state == PJSIP_TSX_STATE_TERMINATED)) 1609 1787 { 1610 1788 … … 1631 1809 if (tsx->method.id == PJSIP_BYE_METHOD && 1632 1810 tsx->role == PJSIP_ROLE_UAC && 1633 tsx->state == PJSIP_TSX_STATE_COMPLETED) 1811 (tsx->state == PJSIP_TSX_STATE_COMPLETED || 1812 tsx->state == PJSIP_TSX_STATE_TERMINATED)) 1634 1813 { 1635 1814 … … 1638 1817 */ 1639 1818 1640 if (e->body.tsx_state.type == PJSIP_EVENT_RX_MSG) 1641 inv_handle_bye_response( inv, tsx, e->body.tsx_state.src.rdata, e); 1642 else 1643 inv_set_state(inv, PJSIP_INV_STATE_DISCONNECTED, e); 1819 inv_handle_bye_response( inv, tsx, e->body.tsx_state.src.rdata, e); 1644 1820 1645 1821 }
Note: See TracChangeset
for help on using the changeset viewer.