Changeset 163
- Timestamp:
- Feb 9, 2006 1:26:14 AM (19 years ago)
- Location:
- pjproject/trunk
- Files:
-
- 7 edited
Legend:
- Unmodified
- Added
- Removed
-
pjproject/trunk/pjmedia/include/pjmedia/sdp_neg.h
r140 r163 98 98 }; 99 99 100 101 /** 102 * Get the state string description of the specified state. 103 * 104 * @param state Negotiator state. 105 * 106 * @return String description of the state. 107 */ 108 PJ_DECL(const char*) pjmedia_sdp_neg_state_str(pjmedia_sdp_neg_state state); 109 110 100 111 /** 101 112 * Create the SDP negotiator with local offer. The SDP negotiator then -
pjproject/trunk/pjmedia/src/pjmedia/sdp.c
r162 r163 402 402 p = tempbuf; 403 403 endbuf = tempbuf+sizeof(tempbuf); 404 405 /* Add colon */ 406 *p++ = ':'; 404 407 405 408 /* Add payload type. */ -
pjproject/trunk/pjmedia/src/pjmedia/sdp_neg.c
r140 r163 40 40 *neg_remote_sdp; /**< Temporary remote SDP. */ 41 41 }; 42 43 static const char *state_str[] = 44 { 45 "STATE_NULL", 46 "STATE_LOCAL_OFFER", 47 "STATE_REMOTE_OFFER", 48 "STATE_WAIT_NEGO", 49 "STATE_DONE", 50 }; 51 52 /* 53 * Get string representation of negotiator state. 54 */ 55 PJ_DEF(const char*) pjmedia_sdp_neg_state_str(pjmedia_sdp_neg_state state) 56 { 57 if (state >=0 && state < PJ_ARRAY_SIZE(state_str)) 58 return state_str[state]; 59 60 return "<?UNKNOWN?>"; 61 } 42 62 43 63 -
pjproject/trunk/pjsip/include/pjsip-ua/sip_inv.h
r141 r163 378 378 379 379 380 #if 0 381 If we implement this, we need to send SDP answer automatically on 382 subsequent request/response. Something like "has_answer" flag. 383 384 /** 385 * Set local answer to respond to remote SDP offer. By calling this function, 386 * application can start SDP negotiation immediately without having to 387 * send any request or response message. This function is normally called 388 * when on_rx_offer() callback is called. 389 * 390 * @param inv The invite session. 391 * @param sdp The SDP description which will be set as answer 392 * to remote. 393 */ 394 PJ_DECL(pj_status_t) pjsip_inv_set_sdp_answer( pjsip_inv_session *inv, 395 const pjmedia_sdp_session *sdp ); 396 #endif 397 380 398 /** 381 399 * Create a SIP message to initiate invite session termination. Depending on -
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 } -
pjproject/trunk/pjsip/src/pjsip/sip_transport.c
r145 r163 794 794 * destroyed). 795 795 */ 796 pj_assert(pj_atomic_get(mgr->tdata_counter) == 0); 796 //pj_assert(pj_atomic_get(mgr->tdata_counter) == 0); 797 if (pj_atomic_get(mgr->tdata_counter) != 0) { 798 PJ_LOG(4,(THIS_FILE, "Warning: %d transmit buffers are not freed!", 799 pj_atomic_get(mgr->tdata_counter))); 800 } 797 801 #endif 798 802 -
pjproject/trunk/pjsip/src/pjsua/pjsua_core.c
r162 r163 78 78 pj_strerror(status, errmsg, sizeof(errmsg)); 79 79 80 PJ_LOG(1,(THIS_FILE, "%s: %s ", title, errmsg));80 PJ_LOG(1,(THIS_FILE, "%s: %s [code=%d]", title, errmsg, status)); 81 81 } 82 82 … … 230 230 pjmedia_session_destroy(inv_data->session); 231 231 inv_data->session = NULL; 232 233 PJ_LOG(3,(THIS_FILE,"Media session is destroyed")); 232 234 } 233 235 … … 302 304 } 303 305 306 PJ_LOG(3,(THIS_FILE,"Media has been started successfully")); 304 307 } 305 308
Note: See TracChangeset
for help on using the changeset viewer.