Changeset 5928 for pjproject/trunk/pjsip/src/pjsua-lib/pjsua_call.c
- Timestamp:
- Jan 8, 2019 9:43:21 AM (6 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
pjproject/trunk/pjsip/src/pjsua-lib/pjsua_call.c
r5918 r5928 1085 1085 } 1086 1086 1087 pj_status_t create_temp_sdp(pj_pool_t *pool, 1088 const pjmedia_sdp_session *rem_sdp, 1089 pjmedia_sdp_session **p_sdp) 1090 { 1091 const pj_str_t STR_AUDIO = { "audio", 5 }; 1092 const pj_str_t STR_VIDEO = { "video", 5 }; 1093 const pj_str_t STR_IP6 = { "IP6", 3}; 1094 1095 pjmedia_sdp_session *sdp; 1096 pj_sockaddr origin; 1097 pj_uint16_t tmp_port = 50123; 1098 pj_status_t status = PJ_SUCCESS; 1099 pj_str_t tmp_st; 1100 unsigned i = 0; 1101 pj_bool_t sess_use_ipv4 = PJ_TRUE; 1102 1103 /* Get one address to use in the origin field */ 1104 pj_sockaddr_init(PJ_AF_INET, &origin, pj_strset2(&tmp_st, "127.0.0.1"), 0); 1105 1106 /* Create the base (blank) SDP */ 1107 status = pjmedia_endpt_create_base_sdp(pjsua_var.med_endpt, pool, NULL, 1108 &origin, &sdp); 1109 if (status != PJ_SUCCESS) 1110 return status; 1111 1112 if (rem_sdp->conn && pj_stricmp(&rem_sdp->conn->addr_type, &STR_IP6)==0) { 1113 sess_use_ipv4 = PJ_FALSE; 1114 } 1115 1116 for (; i< rem_sdp->media_count ; ++i) { 1117 pjmedia_sdp_media *m = NULL; 1118 pjmedia_sock_info sock_info; 1119 pj_bool_t med_use_ipv4 = sess_use_ipv4; 1120 1121 if (rem_sdp->media[i]->conn && 1122 pj_stricmp(&rem_sdp->media[i]->conn->addr_type, &STR_IP6) == 0) 1123 { 1124 med_use_ipv4 = PJ_FALSE; 1125 } 1126 1127 pj_sockaddr_init(med_use_ipv4?PJ_AF_INET:PJ_AF_INET6, 1128 &sock_info.rtp_addr_name, 1129 med_use_ipv4?pj_strset2(&tmp_st, "127.0.0.1"): 1130 pj_strset2(&tmp_st, "::1"), 1131 tmp_port++); 1132 1133 pj_sockaddr_init(med_use_ipv4?PJ_AF_INET:PJ_AF_INET6, 1134 &sock_info.rtcp_addr_name, 1135 med_use_ipv4?pj_strset2(&tmp_st, "127.0.0.1"): 1136 pj_strset2(&tmp_st, "::1"), 1137 tmp_port++); 1138 1139 if (pj_stricmp(&rem_sdp->media[i]->desc.media, &STR_AUDIO)==0) { 1140 m = PJ_POOL_ZALLOC_T(pool, pjmedia_sdp_media); 1141 status = pjmedia_endpt_create_audio_sdp(pjsua_var.med_endpt, 1142 pool, &sock_info, 0, &m); 1143 1144 if (status != PJ_SUCCESS) 1145 return status; 1146 1147 } else if (pj_stricmp(&rem_sdp->media[i]->desc.media, &STR_VIDEO)==0) { 1148 #if defined(PJMEDIA_HAS_VIDEO) && (PJMEDIA_HAS_VIDEO != 0) 1149 m = PJ_POOL_ZALLOC_T(pool, pjmedia_sdp_media); 1150 1151 pj_sockaddr_set_port(&sock_info.rtp_addr_name, ++tmp_port); 1152 status = pjmedia_endpt_create_video_sdp(pjsua_var.med_endpt, pool, 1153 &sock_info, 0, &m); 1154 if (status != PJ_SUCCESS) 1155 return status; 1156 #else 1157 m = pjmedia_sdp_media_clone_deactivate(pool, rem_sdp->media[i]); 1158 #endif 1159 } else { 1160 m = pjmedia_sdp_media_clone_deactivate(pool, rem_sdp->media[i]); 1161 } 1162 if (status != PJ_SUCCESS) 1163 return status; 1164 sdp->media[sdp->media_count++] = m; 1165 } 1166 1167 *p_sdp = sdp; 1168 return PJ_SUCCESS; 1169 } 1170 1171 static pj_status_t verify_request(const pjsua_call *call, 1172 pjsip_rx_data *rdata, 1173 pj_bool_t use_tmp_sdp, 1174 int *sip_err_code, 1175 pjsip_tx_data **response) 1176 { 1177 const pjmedia_sdp_session *offer = NULL; 1178 pjmedia_sdp_session *answer; 1179 int err_code = 0; 1180 pj_status_t status; 1181 1182 /* Get remote SDP offer (if any). */ 1183 if (call->inv->neg) 1184 { 1185 pjmedia_sdp_neg_get_neg_remote(call->inv->neg, &offer); 1186 } 1187 1188 if (use_tmp_sdp) { 1189 if (offer == NULL) 1190 return PJ_SUCCESS; 1191 1192 /* Create temporary SDP to check for codec support and capability 1193 * to handle the required SIP extensions. 1194 */ 1195 status = create_temp_sdp(call->inv->pool_prov, offer, &answer); 1196 1197 if (status != PJ_SUCCESS) { 1198 err_code = PJSIP_SC_NOT_ACCEPTABLE_HERE; 1199 pjsua_perror(THIS_FILE, "Error creating SDP answer", status); 1200 } 1201 } else { 1202 status = pjsua_media_channel_create_sdp(call->index, 1203 call->async_call.dlg->pool, 1204 offer, &answer, sip_err_code); 1205 1206 if (status != PJ_SUCCESS) { 1207 pjsua_perror(THIS_FILE, "Error creating SDP answer", status); 1208 } else { 1209 status = pjsip_inv_set_local_sdp(call->inv, answer); 1210 if (status != PJ_SUCCESS) { 1211 pjsua_perror(THIS_FILE, "Error setting local SDP", status); 1212 err_code = PJSIP_SC_NOT_ACCEPTABLE_HERE; 1213 } 1214 } 1215 } 1216 1217 if (status == PJ_SUCCESS) { 1218 unsigned options = 0; 1219 1220 /* Verify that we can handle the request. */ 1221 status = pjsip_inv_verify_request3(rdata, 1222 call->inv->pool_prov, &options, 1223 offer, answer, NULL, 1224 pjsua_var.endpt, response); 1225 if (status != PJ_SUCCESS) { 1226 /* 1227 * No we can't handle the incoming INVITE request. 1228 */ 1229 if (response) 1230 err_code = (*response)->msg->line.status.code; 1231 else 1232 err_code = PJSIP_ERRNO_TO_SIP_STATUS(status); 1233 } 1234 } 1235 if (sip_err_code) 1236 *sip_err_code = err_code; 1237 1238 return status; 1239 } 1087 1240 1088 1241 /* Incoming call callback when media transport creation is completed. */ 1089 1242 static pj_status_t 1090 on_incoming_call_med_tp_complete(pjsua_call_id call_id, 1091 const pjsua_med_tp_state_info *info) 1243 on_incoming_call_med_tp_complete2(pjsua_call_id call_id, 1244 const pjsua_med_tp_state_info *info, 1245 pjsip_rx_data *rdata, 1246 int *sip_err_code, 1247 pjsip_tx_data **tdata) 1092 1248 { 1093 1249 pjsua_call *call = &pjsua_var.calls[call_id]; 1094 const pjmedia_sdp_session *offer=NULL; 1095 pjmedia_sdp_session *answer; 1250 pjsip_dialog *dlg = call->async_call.dlg; 1251 pj_status_t status = (info? info->status: PJ_SUCCESS); 1252 int err_code = (info? info->sip_err_code: 0); 1096 1253 pjsip_tx_data *response = NULL; 1097 unsigned options = 0;1098 pjsip_dialog *dlg = call->async_call.dlg;1099 int sip_err_code = (info? info->sip_err_code: 0);1100 pj_status_t status = (info? info->status: PJ_SUCCESS);1101 1254 1102 1255 PJSUA_LOCK(); 1103 1256 1257 if (sip_err_code) 1258 *sip_err_code = err_code; 1259 1104 1260 /* Increment the dialog's lock to prevent it to be destroyed prematurely, 1105 1261 * such as in case of transport error. … … 1124 1280 } 1125 1281 1126 /* Get remote SDP offer (if any). */ 1127 if (call->inv->neg) 1128 pjmedia_sdp_neg_get_neg_remote(call->inv->neg, &offer); 1129 1130 status = pjsua_media_channel_create_sdp(call_id, 1131 call->async_call.dlg->pool, 1132 offer, &answer, &sip_err_code); 1133 if (status != PJ_SUCCESS) { 1134 pjsua_perror(THIS_FILE, "Error creating SDP answer", status); 1135 goto on_return; 1136 } 1137 1138 status = pjsip_inv_set_local_sdp(call->inv, answer); 1139 if (status != PJ_SUCCESS) { 1140 pjsua_perror(THIS_FILE, "Error setting local SDP", status); 1141 sip_err_code = PJSIP_SC_NOT_ACCEPTABLE_HERE; 1142 goto on_return; 1143 } 1144 1145 /* Verify that we can handle the request. */ 1146 status = pjsip_inv_verify_request3(NULL, 1147 call->inv->pool_prov, &options, offer, 1148 answer, NULL, pjsua_var.endpt, &response); 1149 if (status != PJ_SUCCESS) { 1150 /* 1151 * No we can't handle the incoming INVITE request. 1152 */ 1153 sip_err_code = PJSIP_ERRNO_TO_SIP_STATUS(status); 1154 goto on_return; 1155 } 1282 status = verify_request(call, rdata, PJ_FALSE, &err_code, &response); 1156 1283 1157 1284 on_return: … … 1161 1288 * will be terminated later, otherwise we end the session here. 1162 1289 */ 1163 if (call->inv->state > PJSIP_INV_STATE_NULL) { 1164 pjsip_tx_data *tdata; 1165 pj_status_t status_; 1166 1167 status_ = pjsip_inv_end_session(call->inv, sip_err_code, NULL, 1168 &tdata); 1169 if (status_ == PJ_SUCCESS && tdata) 1170 status_ = pjsip_inv_send_msg(call->inv, tdata); 1171 } 1172 1290 if (call->inv->state > PJSIP_INV_STATE_NULL) { 1291 pj_status_t status_ = PJ_SUCCESS; 1292 1293 if (response == NULL) { 1294 status_ = pjsip_inv_end_session(call->inv, err_code, NULL, 1295 &response); 1296 } 1297 1298 if (status_ == PJ_SUCCESS && response) 1299 status_ = pjsip_inv_send_msg(call->inv, response); 1300 } 1173 1301 pjsua_media_channel_deinit(call->index); 1174 1302 } … … 1193 1321 1194 1322 pjsip_dlg_dec_lock(dlg); 1323 1324 if (sip_err_code) 1325 *sip_err_code = err_code; 1326 1327 if (tdata) 1328 *tdata = response; 1195 1329 1196 1330 PJSUA_UNLOCK(); 1197 1331 return status; 1332 } 1333 1334 static pj_status_t 1335 on_incoming_call_med_tp_complete(pjsua_call_id call_id, 1336 const pjsua_med_tp_state_info *info) 1337 { 1338 return on_incoming_call_med_tp_complete2(call_id, info, NULL, NULL, NULL); 1198 1339 } 1199 1340 … … 1611 1752 */ 1612 1753 if (offer || replaced_dlg) { 1754 1755 /* This is only for initial verification, it will check the SDP for 1756 * codec support and the capability to handle the required 1757 * SIP extensions. 1758 */ 1759 status = verify_request(call, rdata, PJ_TRUE, &sip_err_code, 1760 &response); 1761 1762 if (status != PJ_SUCCESS) { 1763 pjsip_dlg_inc_lock(dlg); 1764 1765 if (response) { 1766 pjsip_dlg_send_response(dlg, call->inv->invite_tsx, response); 1767 1768 } else { 1769 pjsip_dlg_respond(dlg, rdata, sip_err_code, NULL, NULL, NULL); 1770 } 1771 1772 if (call->inv && call->inv->dlg) { 1773 pjsip_inv_terminate(call->inv, sip_err_code, PJ_FALSE); 1774 } 1775 pjsip_dlg_dec_lock(dlg); 1776 1777 call->inv = NULL; 1778 call->async_call.dlg = NULL; 1779 goto on_return; 1780 } 1613 1781 status = pjsua_media_channel_init(call->index, PJSIP_ROLE_UAS, 1614 1782 call->secure_level, … … 1618 1786 &on_incoming_call_med_tp_complete); 1619 1787 if (status == PJ_SUCCESS) { 1620 status = on_incoming_call_med_tp_complete(call_id, NULL); 1621 if (status != PJ_SUCCESS) { 1622 sip_err_code = PJSIP_SC_NOT_ACCEPTABLE; 1788 status = on_incoming_call_med_tp_complete2(call_id, NULL, 1789 rdata, &sip_err_code, 1790 &response); 1791 if (status != PJ_SUCCESS) { 1623 1792 /* Since the call invite's state is still PJSIP_INV_STATE_NULL, 1624 1793 * the invite session was not ended in … … 1627 1796 */ 1628 1797 pjsip_dlg_inc_lock(dlg); 1629 pjsip_dlg_respond(dlg, rdata, sip_err_code, NULL, NULL, NULL); 1798 1799 if (response) { 1800 pjsip_dlg_send_response(dlg, call->inv->invite_tsx, 1801 response); 1802 1803 } else { 1804 pjsip_dlg_respond(dlg, rdata, sip_err_code, NULL, NULL, 1805 NULL); 1806 } 1807 1630 1808 if (call->inv && call->inv->dlg) { 1631 1809 pjsip_inv_terminate(call->inv, sip_err_code, PJ_FALSE); … … 1734 1912 * above) 1735 1913 */ 1736 dlg->mod_data[pjsua_var.mod.id] = call; 1737 inv->mod_data[pjsua_var.mod.id] = call; 1738 1739 ++pjsua_var.call_cnt; 1914 if (dlg->mod_data[pjsua_var.mod.id] == NULL) { 1915 /* In PJSUA2, on_incoming_call() may be called from 1916 * on_media_transport_created() hence this might already set 1917 * to allow notification about fail events via on_call_state() and 1918 * on_call_tsx_state(). 1919 */ 1920 dlg->mod_data[pjsua_var.mod.id] = call; 1921 inv->mod_data[pjsua_var.mod.id] = call; 1922 ++pjsua_var.call_cnt; 1923 } 1740 1924 1741 1925 /* Check if this request should replace existing call */
Note: See TracChangeset
for help on using the changeset viewer.