Changeset 156
- Timestamp:
- Feb 8, 2006 11:16:05 AM (19 years ago)
- Location:
- pjproject/trunk/pjsip
- Files:
-
- 3 edited
Legend:
- Unmodified
- Added
- Removed
-
pjproject/trunk/pjsip/build/pjsua.dsp
r147 r156 100 100 101 101 SOURCE=..\src\pjsua\main_old.c 102 103 !IF "$(CFG)" == "pjsua - Win32 Release"104 105 !ELSEIF "$(CFG)" == "pjsua - Win32 Debug"106 107 102 # PROP Exclude_From_Build 1 108 109 !ENDIF110 111 103 # End Source File 112 104 # Begin Source File -
pjproject/trunk/pjsip/src/pjsip-ua/sip_inv.c
r145 r156 27 27 #include <pj/pool.h> 28 28 #include <pj/assert.h> 29 #include <pj/os.h> 29 30 30 31 #define THIS_FILE "sip_invite_session.c" … … 39 40 static void mod_inv_on_tsx_state(pjsip_transaction*, pjsip_event*); 40 41 41 static void inv_on_state_null( pjsip_inv_session *s, pjsip_event *e); 42 static void inv_on_state_calling( pjsip_inv_session *s, pjsip_event *e); 43 static void inv_on_state_incoming( pjsip_inv_session *s, pjsip_event *e); 44 static void inv_on_state_early( pjsip_inv_session *s, pjsip_event *e); 45 static void inv_on_state_connecting( pjsip_inv_session *s, pjsip_event *e); 46 static void inv_on_state_confirmed( pjsip_inv_session *s, pjsip_event *e); 47 static void inv_on_state_disconnected( pjsip_inv_session *s, pjsip_event *e); 48 static void inv_on_state_terminated( pjsip_inv_session *s, pjsip_event *e); 49 50 static void (*inv_state_handler[])( pjsip_inv_session *s, pjsip_event *e) = 42 static void inv_on_state_null( pjsip_inv_session *inv, pjsip_event *e); 43 static void inv_on_state_calling( pjsip_inv_session *inv, pjsip_event *e); 44 static void inv_on_state_incoming( pjsip_inv_session *inv, pjsip_event *e); 45 static void inv_on_state_early( pjsip_inv_session *inv, pjsip_event *e); 46 static void inv_on_state_connecting( pjsip_inv_session *inv, pjsip_event *e); 47 static void inv_on_state_confirmed( pjsip_inv_session *inv, pjsip_event *e); 48 static void inv_on_state_disconnected( pjsip_inv_session *inv, pjsip_event *e); 49 50 static void (*inv_state_handler[])( pjsip_inv_session *inv, pjsip_event *e) = 51 51 { 52 52 &inv_on_state_null, … … 57 57 &inv_on_state_confirmed, 58 58 &inv_on_state_disconnected, 59 &inv_on_state_terminated,60 59 }; 61 60 … … 87 86 88 87 89 88 /* 89 * Module load() 90 */ 90 91 static pj_status_t mod_inv_load(pjsip_endpoint *endpt) 91 92 { … … 99 100 } 100 101 102 /* 103 * Module unload() 104 */ 101 105 static pj_status_t mod_inv_unload(void) 102 106 { … … 105 109 } 106 110 107 static pj_bool_t mod_inv_on_rx_request(pjsip_rx_data *rdata) 108 { 109 pjsip_dialog *dlg; 110 111 /* Ignore requests outside dialog */ 112 dlg = pjsip_rdata_get_dlg(rdata); 113 if (dlg == NULL) 114 return PJ_FALSE; 115 116 /* Answer BYE with 200/OK. */ 117 if (rdata->msg_info.msg->line.req.method.id == PJSIP_BYE_METHOD) { 118 pj_status_t status; 119 pjsip_tx_data *tdata; 120 121 status = pjsip_dlg_create_response(dlg, rdata, 200, NULL, &tdata); 122 if (status == PJ_SUCCESS) 123 status = pjsip_dlg_send_response(dlg, pjsip_rdata_get_tsx(rdata), 124 tdata); 125 126 return status==PJ_SUCCESS ? PJ_TRUE : PJ_FALSE; 127 } 128 129 return PJ_FALSE; 130 } 131 132 static pj_status_t send_ack(pjsip_inv_session *inv, pjsip_rx_data *rdata) 111 /* 112 * Send ACK for 2xx response. 113 */ 114 static pj_status_t inv_send_ack(pjsip_inv_session *inv, pjsip_rx_data *rdata) 133 115 { 134 116 pjsip_tx_data *tdata; … … 153 135 } 154 136 137 /* 138 * Module on_rx_request() 139 * 140 * This callback is called for these events: 141 * - endpoint receives request which was unhandled by higher priority 142 * modules (e.g. transaction layer, dialog layer). 143 * - dialog distributes incoming request to its usages. 144 */ 145 static pj_bool_t mod_inv_on_rx_request(pjsip_rx_data *rdata) 146 { 147 pjsip_method *method; 148 149 /* Only wants to receive request from a dialog. */ 150 if (pjsip_rdata_get_dlg(rdata) == NULL) 151 return PJ_FALSE; 152 153 /* Report to dialog that we handle INVITE, CANCEL, BYE, ACK. 154 * If we need to send response, it will be sent in the state 155 * handlers. 156 */ 157 method = &rdata->msg_info.msg->line.req.method; 158 159 if (method->id == PJSIP_INVITE_METHOD || 160 method->id == PJSIP_CANCEL_METHOD || 161 method->id == PJSIP_ACK_METHOD || 162 method->id == PJSIP_BYE_METHOD) 163 { 164 return PJ_TRUE; 165 } 166 167 return PJ_FALSE; 168 } 169 170 /* 171 * Module on_rx_response(). 172 * 173 * This callback is called for these events: 174 * - dialog distributes incoming 2xx response to INVITE (outside 175 * transaction) to its usages. 176 * - endpoint distributes strayed responses. 177 */ 155 178 static pj_bool_t mod_inv_on_rx_response(pjsip_rx_data *rdata) 156 179 { … … 176 199 rdata->msg_info.cseq->method.id == PJSIP_INVITE_METHOD) { 177 200 178 send_ack(inv, rdata);201 inv_send_ack(inv, rdata); 179 202 return PJ_TRUE; 180 203 … … 185 208 } 186 209 210 /* 211 * Module on_tsx_state() 212 * 213 * This callback is called by dialog framework for all transactions 214 * inside the dialog for all its dialog usages. 215 */ 187 216 static void mod_inv_on_tsx_state(pjsip_transaction *tsx, pjsip_event *e) 188 217 { … … 210 239 } 211 240 241 242 /* 243 * Initialize the invite module. 244 */ 212 245 PJ_DEF(pj_status_t) pjsip_inv_usage_init( pjsip_endpoint *endpt, 213 246 pjsip_module *app_module, … … 237 270 } 238 271 272 /* 273 * Get the instance of invite module. 274 */ 239 275 PJ_DEF(pjsip_module*) pjsip_inv_usage_instance(void) 240 276 { … … 243 279 244 280 281 /* 282 * Return the invite session for the specified dialog. 283 */ 245 284 PJ_DEF(pjsip_inv_session*) pjsip_dlg_get_inv_session(pjsip_dialog *dlg) 246 285 { … … 248 287 } 249 288 250 /* 251 * Create UAC session. 289 290 /* 291 * Create UAC invite session. 252 292 */ 253 293 PJ_DEF(pj_status_t) pjsip_inv_create_uac( pjsip_dialog *dlg, … … 349 389 pj_list_init(&res_hdr_list); 350 390 351 /* Check the request body, see if it' ssomething that we support391 /* Check the request body, see if it'inv something that we support 352 392 * (i.e. SDP). 353 393 */ … … 624 664 625 665 /* 626 * Create UAS session.666 * Create UAS invite session. 627 667 */ 628 668 PJ_DEF(pj_status_t) pjsip_inv_create_uas( pjsip_dialog *dlg, … … 663 703 inv->pool = dlg->pool; 664 704 inv->role = PJSIP_ROLE_UAS; 665 inv->state = PJSIP_INV_STATE_ NULL;705 inv->state = PJSIP_INV_STATE_INCOMING; 666 706 inv->dlg = dlg; 667 707 inv->options = options; … … 855 895 } 856 896 857 /* Do we need to increment tdata' sreference counter? */897 /* Do we need to increment tdata'inv reference counter? */ 858 898 PJ_TODO(INV_ANSWER_MAY_HAVE_TO_INCREMENT_REF_COUNTER); 859 899 … … 1038 1078 } 1039 1079 1040 static void inv_on_state_null( pjsip_inv_session *s, pjsip_event *e) 1080 1081 1082 /* 1083 * Respond to incoming CANCEL request. 1084 */ 1085 static void inv_respond_incoming_cancel(pjsip_inv_session *inv, 1086 pjsip_transaction *cancel_tsx, 1087 pjsip_rx_data *rdata) 1088 { 1089 pjsip_tx_data *tdata; 1090 pjsip_transaction *invite_tsx; 1091 pj_str_t key; 1092 pj_status_t status; 1093 1094 /* See if we have matching INVITE server transaction: */ 1095 1096 pjsip_tsx_create_key(rdata->tp_info.pool, &key, PJSIP_ROLE_UAS, 1097 &pjsip_invite_method, rdata); 1098 invite_tsx = pjsip_tsx_layer_find_tsx(&key, PJ_TRUE); 1099 1100 if (invite_tsx == NULL) { 1101 1102 /* Invite transaction not found! 1103 * Respond CANCEL with 491 (RFC 3261 Section 9.2 page 42) 1104 */ 1105 status = pjsip_dlg_create_response( inv->dlg, rdata, 200, NULL, 1106 &tdata); 1107 1108 } else { 1109 /* Always answer CANCEL will 200 (OK) regardless of 1110 * the state of the INVITE transaction. 1111 */ 1112 status = pjsip_dlg_create_response( inv->dlg, rdata, 200, NULL, 1113 &tdata); 1114 } 1115 1116 /* See if we have created the response successfully. */ 1117 if (status != PJ_SUCCESS) return; 1118 1119 /* Send the CANCEL response */ 1120 status = pjsip_dlg_send_response(inv->dlg, cancel_tsx, tdata); 1121 if (status != PJ_SUCCESS) return; 1122 1123 1124 /* See if we need to terminate the UAS INVITE transaction 1125 * with 487 (Request Terminated) response. 1126 */ 1127 if (invite_tsx && invite_tsx->status_code < 200) { 1128 1129 pj_assert(invite_tsx->last_tx != NULL); 1130 1131 tdata = invite_tsx->last_tx; 1132 1133 status = pjsip_dlg_modify_response(inv->dlg, tdata, 487, NULL); 1134 if (status == PJ_SUCCESS) 1135 pjsip_dlg_send_response(inv->dlg, invite_tsx, tdata); 1136 } 1137 1138 if (invite_tsx) 1139 pj_mutex_unlock(invite_tsx->mutex); 1140 } 1141 1142 1143 /* 1144 * Respond to incoming BYE request. 1145 */ 1146 static void inv_respond_incoming_bye( pjsip_inv_session *inv, 1147 pjsip_transaction *bye_tsx, 1148 pjsip_rx_data *rdata, 1149 pjsip_event *e ) 1150 { 1151 pj_status_t status; 1152 pjsip_tx_data *tdata; 1153 1154 /* Respond BYE with 200: */ 1155 1156 status = pjsip_dlg_create_response(inv->dlg, rdata, 200, NULL, &tdata); 1157 if (status != PJ_SUCCESS) return; 1158 1159 status = pjsip_dlg_send_response(inv->dlg, bye_tsx, tdata); 1160 if (status != PJ_SUCCESS) return; 1161 1162 /* Terminate session: */ 1163 1164 if (inv->state != PJSIP_INV_STATE_DISCONNECTED) 1165 inv_set_state(inv, PJSIP_INV_STATE_DISCONNECTED, e); 1166 } 1167 1168 /* 1169 * State NULL is before anything is sent/received. 1170 */ 1171 static void inv_on_state_null( pjsip_inv_session *inv, pjsip_event *e) 1041 1172 { 1042 1173 pjsip_transaction *tsx = e->body.tsx_state.tsx; … … 1050 1181 1051 1182 /* Keep the initial INVITE transaction. */ 1052 if ( s->invite_tsx == NULL)1053 s->invite_tsx = tsx;1183 if (inv->invite_tsx == NULL) 1184 inv->invite_tsx = tsx; 1054 1185 1055 1186 switch (tsx->state) { 1056 1187 case PJSIP_TSX_STATE_CALLING: 1057 inv_set_state( s, PJSIP_INV_STATE_CALLING, e);1188 inv_set_state(inv, PJSIP_INV_STATE_CALLING, e); 1058 1189 break; 1059 1190 default: … … 1065 1196 switch (tsx->state) { 1066 1197 case PJSIP_TSX_STATE_TRYING: 1067 inv_set_state( s, PJSIP_INV_STATE_INCOMING, e);1198 inv_set_state(inv, PJSIP_INV_STATE_INCOMING, e); 1068 1199 break; 1069 1200 default: … … 1077 1208 } 1078 1209 1079 static void inv_on_state_calling( pjsip_inv_session *s, pjsip_event *e) 1210 /* 1211 * State CALLING is after sending initial INVITE request but before 1212 * any response (with tag) is received. 1213 */ 1214 static void inv_on_state_calling( pjsip_inv_session *inv, pjsip_event *e) 1080 1215 { 1081 1216 pjsip_transaction *tsx = e->body.tsx_state.tsx; … … 1085 1220 PJ_ASSERT_ON_FAIL(tsx && dlg, return); 1086 1221 1087 if (tsx == s->invite_tsx) {1222 if (tsx == inv->invite_tsx) { 1088 1223 1089 1224 switch (tsx->state) { … … 1091 1226 case PJSIP_TSX_STATE_PROCEEDING: 1092 1227 if (dlg->remote.info->tag.slen) { 1093 inv_set_state( s, PJSIP_INV_STATE_EARLY, e);1228 inv_set_state(inv, PJSIP_INV_STATE_EARLY, e); 1094 1229 } else { 1095 1230 /* Ignore 100 (Trying) response, as it doesn't change … … 1106 1241 */ 1107 1242 pj_assert(0); 1108 inv_set_state( s, PJSIP_INV_STATE_CONNECTING, e);1243 inv_set_state(inv, PJSIP_INV_STATE_CONNECTING, e); 1109 1244 1110 1245 } else if (tsx->status_code==401 || tsx->status_code==407) { … … 1115 1250 pjsip_tx_data *tdata; 1116 1251 1117 status = pjsip_auth_clt_reinit_req(& s->dlg->auth_sess,1252 status = pjsip_auth_clt_reinit_req(&inv->dlg->auth_sess, 1118 1253 e->body.tsx_state.src.rdata, 1119 1254 tsx->last_tx, … … 1125 1260 * End the session. 1126 1261 */ 1127 inv_set_state( s, PJSIP_INV_STATE_DISCONNECTED, e);1262 inv_set_state(inv, PJSIP_INV_STATE_DISCONNECTED, e); 1128 1263 1129 1264 } else { 1130 1265 1131 1266 /* Restart session. */ 1132 s->state = PJSIP_INV_STATE_NULL;1133 s->invite_tsx = NULL;1267 inv->state = PJSIP_INV_STATE_NULL; 1268 inv->invite_tsx = NULL; 1134 1269 1135 1270 /* Send the request. */ 1136 status = pjsip_inv_send_msg( s, tdata, NULL );1271 status = pjsip_inv_send_msg(inv, tdata, NULL ); 1137 1272 } 1138 1273 1139 1274 } else { 1140 1275 1141 inv_set_state( s, PJSIP_INV_STATE_DISCONNECTED, e);1276 inv_set_state(inv, PJSIP_INV_STATE_DISCONNECTED, e); 1142 1277 1143 1278 } … … 1153 1288 1154 1289 /* Set state to CONNECTING */ 1155 inv_set_state( s, PJSIP_INV_STATE_CONNECTING, e);1290 inv_set_state(inv, PJSIP_INV_STATE_CONNECTING, e); 1156 1291 1157 1292 /* Send ACK */ 1158 1293 pj_assert(e->body.tsx_state.type == PJSIP_EVENT_RX_MSG); 1159 1294 1160 send_ack(s, e->body.tsx_state.src.rdata);1295 inv_send_ack(inv, e->body.tsx_state.src.rdata); 1161 1296 1162 1297 } else { 1163 inv_set_state( s, PJSIP_INV_STATE_DISCONNECTED, e);1298 inv_set_state(inv, PJSIP_INV_STATE_DISCONNECTED, e); 1164 1299 } 1165 1300 break; 1166 1301 1167 default: 1168 pj_assert(!"Unexpected state"); 1169 } 1170 1171 } else { 1172 pj_assert(!"Unexpected transaction type"); 1173 } 1174 } 1175 1176 static void inv_on_state_incoming( pjsip_inv_session *s, pjsip_event *e) 1302 } 1303 } 1304 } 1305 1306 /* 1307 * State INCOMING is after we received the request, but before 1308 * responses with tag are sent. 1309 */ 1310 static void inv_on_state_incoming( pjsip_inv_session *inv, pjsip_event *e) 1177 1311 { 1178 1312 pjsip_transaction *tsx = e->body.tsx_state.tsx; … … 1181 1315 PJ_ASSERT_ON_FAIL(tsx && dlg, return); 1182 1316 1183 if (tsx == s->invite_tsx) { 1317 if (tsx == inv->invite_tsx) { 1318 1319 /* 1320 * Handle the INVITE state transition. 1321 */ 1322 1184 1323 switch (tsx->state) { 1324 1185 1325 case PJSIP_TSX_STATE_PROCEEDING: 1326 /* 1327 * Transaction sent provisional response. 1328 */ 1186 1329 if (tsx->status_code > 100) 1187 inv_set_state( s, PJSIP_INV_STATE_EARLY, e);1330 inv_set_state(inv, PJSIP_INV_STATE_EARLY, e); 1188 1331 break; 1332 1333 case PJSIP_TSX_STATE_COMPLETED: 1334 /* 1335 * Transaction sent final response. 1336 */ 1337 if (tsx->status_code/100 == 2) 1338 inv_set_state(inv, PJSIP_INV_STATE_CONNECTING, e); 1339 else 1340 inv_set_state(inv, PJSIP_INV_STATE_DISCONNECTED, e); 1341 break; 1342 1343 case PJSIP_TSX_STATE_TERMINATED: 1344 /* 1345 * This happens on transport error (e.g. failed to send 1346 * response) 1347 */ 1348 inv_set_state(inv, PJSIP_INV_STATE_DISCONNECTED, e); 1349 break; 1350 1351 default: 1352 pj_assert(!"Unexpected INVITE state"); 1353 break; 1354 } 1355 1356 } else if (tsx->method.id == PJSIP_CANCEL_METHOD && 1357 tsx->role == PJSIP_ROLE_UAS && 1358 tsx->state < PJSIP_TSX_STATE_COMPLETED && 1359 e->body.tsx_state.type == PJSIP_EVENT_RX_MSG ) 1360 { 1361 1362 /* 1363 * Handle incoming CANCEL request. 1364 */ 1365 1366 inv_respond_incoming_cancel(inv, tsx, e->body.tsx_state.src.rdata); 1367 1368 } 1369 } 1370 1371 /* 1372 * State EARLY is for both UAS and UAC, after response with To tag 1373 * is sent/received. 1374 */ 1375 static void inv_on_state_early( pjsip_inv_session *inv, pjsip_event *e) 1376 { 1377 pjsip_transaction *tsx = e->body.tsx_state.tsx; 1378 pjsip_dialog *dlg = pjsip_tsx_get_dlg(tsx); 1379 1380 PJ_ASSERT_ON_FAIL(tsx && dlg, return); 1381 1382 if (tsx == inv->invite_tsx) { 1383 1384 /* 1385 * Handle the INVITE state progress. 1386 */ 1387 1388 switch (tsx->state) { 1389 1390 case PJSIP_TSX_STATE_PROCEEDING: 1391 /* Send/received another provisional response. */ 1392 inv_set_state(inv, PJSIP_INV_STATE_EARLY, e); 1393 break; 1394 1189 1395 case PJSIP_TSX_STATE_COMPLETED: 1190 1396 if (tsx->status_code/100 == 2) 1191 inv_set_state( s, PJSIP_INV_STATE_CONNECTING, e);1397 inv_set_state(inv, PJSIP_INV_STATE_CONNECTING, e); 1192 1398 else 1193 inv_set_state(s, PJSIP_INV_STATE_DISCONNECTED, e); 1194 break; 1195 case PJSIP_TSX_STATE_TERMINATED: 1196 /* This happens on transport error */ 1197 inv_set_state(s, PJSIP_INV_STATE_DISCONNECTED, e); 1198 break; 1199 default: 1200 pj_assert(!"Unexpected state"); 1201 } 1202 } else { 1203 pj_assert(!"Unexpected transaction type"); 1204 } 1205 } 1206 1207 static void inv_on_state_early( pjsip_inv_session *s, pjsip_event *e) 1208 { 1209 pjsip_transaction *tsx = e->body.tsx_state.tsx; 1210 pjsip_dialog *dlg = pjsip_tsx_get_dlg(tsx); 1211 1212 PJ_ASSERT_ON_FAIL(tsx && dlg, return); 1213 1214 if (tsx == s->invite_tsx) { 1215 1216 switch (tsx->state) { 1217 1218 case PJSIP_TSX_STATE_PROCEEDING: 1219 /* Send/received another provisional response. */ 1220 inv_set_state(s, PJSIP_INV_STATE_EARLY, e); 1221 break; 1222 1223 case PJSIP_TSX_STATE_COMPLETED: 1224 if (tsx->status_code/100 == 2) 1225 inv_set_state(s, PJSIP_INV_STATE_CONNECTING, e); 1226 else 1227 inv_set_state(s, PJSIP_INV_STATE_DISCONNECTED, e); 1399 inv_set_state(inv, PJSIP_INV_STATE_DISCONNECTED, e); 1228 1400 break; 1229 1401 … … 1238 1410 1239 1411 /* Set state to CONNECTING */ 1240 inv_set_state( s, PJSIP_INV_STATE_CONNECTING, e);1412 inv_set_state(inv, PJSIP_INV_STATE_CONNECTING, e); 1241 1413 1242 1414 /* if UAC, send ACK and move state to confirmed. */ … … 1244 1416 pj_assert(e->body.tsx_state.type == PJSIP_EVENT_RX_MSG); 1245 1417 1246 send_ack(s, e->body.tsx_state.src.rdata);1247 1248 inv_set_state( s, PJSIP_INV_STATE_CONFIRMED, e);1418 inv_send_ack(inv, e->body.tsx_state.src.rdata); 1419 1420 inv_set_state(inv, PJSIP_INV_STATE_CONFIRMED, e); 1249 1421 } 1250 1422 1251 1423 } else { 1252 inv_set_state( s, PJSIP_INV_STATE_DISCONNECTED, e);1424 inv_set_state(inv, PJSIP_INV_STATE_DISCONNECTED, e); 1253 1425 } 1254 1426 break; 1255 1427 1256 1428 default: 1257 pj_assert(!"Unexpected state"); 1258 } 1259 1260 } else if (tsx->method.id == PJSIP_CANCEL_METHOD) { 1261 1262 /* Handle incoming CANCEL request. */ 1263 if (tsx->role == PJSIP_ROLE_UAS && s->role == PJSIP_ROLE_UAS && 1264 e->body.tsx_state.type == PJSIP_EVENT_RX_MSG) 1265 { 1266 1267 pj_status_t status; 1268 pjsip_tx_data *tdata; 1269 1270 /* Respond CANCEL with 200 (OK) */ 1271 status = pjsip_dlg_create_response(dlg, e->body.tsx_state.src.rdata, 1272 200, NULL, &tdata); 1273 if (status == PJ_SUCCESS) { 1274 pjsip_dlg_send_response(dlg, tsx, tdata); 1275 } 1276 1277 /* Respond the original UAS transaction with 487 (Request 1278 * Terminated) response. 1279 */ 1280 pj_assert(s->invite_tsx && s->invite_tsx->last_tx); 1281 tdata = s->invite_tsx->last_tx; 1282 1283 status = pjsip_dlg_modify_response(dlg, tdata, 487, NULL); 1284 if (status == PJ_SUCCESS) { 1285 pjsip_dlg_send_response(dlg, s->invite_tsx, tdata); 1286 } 1287 } 1288 1289 } else if (tsx->method.id == PJSIP_INVITE_METHOD) { 1290 1291 /* Ignore previously failed INVITE transaction event 1292 * (e.g. when rejected with 401/407) 1429 pj_assert(!"Unexpected INVITE tsx state"); 1430 } 1431 1432 } else if (inv->role == PJSIP_ROLE_UAS && 1433 tsx->role == PJSIP_ROLE_UAS && 1434 tsx->method.id == PJSIP_CANCEL_METHOD && 1435 tsx->state < PJSIP_TSX_STATE_COMPLETED && 1436 e->body.tsx_state.type == PJSIP_EVENT_RX_MSG ) 1437 { 1438 1439 /* 1440 * Handle incoming CANCEL request. 1293 1441 */ 1294 1442 1295 } else { 1296 pj_assert(!"Unexpected transaction type"); 1297 } 1298 } 1299 1300 static void inv_on_state_connecting( pjsip_inv_session *s, pjsip_event *e) 1443 inv_respond_incoming_cancel(inv, tsx, e->body.tsx_state.src.rdata); 1444 1445 } 1446 } 1447 1448 /* 1449 * State CONNECTING is after 2xx response to INVITE is sent/received. 1450 */ 1451 static void inv_on_state_connecting( pjsip_inv_session *inv, pjsip_event *e) 1301 1452 { 1302 1453 pjsip_transaction *tsx = e->body.tsx_state.tsx; … … 1305 1456 PJ_ASSERT_ON_FAIL(tsx && dlg, return); 1306 1457 1307 if (tsx == s->invite_tsx) { 1308 1458 if (tsx == inv->invite_tsx) { 1459 1460 /* 1461 * Handle INVITE state progression. 1462 */ 1309 1463 switch (tsx->state) { 1310 1464 … … 1318 1472 */ 1319 1473 if (tsx->status_code/100 != 2) { 1320 inv_set_state( s, PJSIP_INV_STATE_DISCONNECTED, e);1474 inv_set_state(inv, PJSIP_INV_STATE_DISCONNECTED, e); 1321 1475 } 1322 1476 break; … … 1330 1484 } 1331 1485 1332 } else { 1333 pj_assert(!"Unexpected transaction type"); 1334 } 1335 } 1336 1337 static void inv_on_state_confirmed( pjsip_inv_session *s, pjsip_event *e) 1486 } else if (tsx->role == PJSIP_ROLE_UAS && 1487 tsx->method.id == PJSIP_BYE_METHOD && 1488 tsx->status_code < 200 && 1489 e->body.tsx_state.type == PJSIP_EVENT_RX_MSG) 1490 { 1491 1492 /* 1493 * Handle incoming BYE. 1494 */ 1495 1496 inv_respond_incoming_bye( inv, tsx, e->body.tsx_state.src.rdata, e ); 1497 1498 } 1499 } 1500 1501 /* 1502 * State CONFIRMED is after ACK is sent/received. 1503 */ 1504 static void inv_on_state_confirmed( pjsip_inv_session *inv, pjsip_event *e) 1338 1505 { 1339 1506 pjsip_transaction *tsx = e->body.tsx_state.tsx; … … 1342 1509 PJ_ASSERT_ON_FAIL(tsx && dlg, return); 1343 1510 1344 if (tsx->method.id == PJSIP_BYE_METHOD) { 1345 inv_set_state(s, PJSIP_INV_STATE_DISCONNECTED, e); 1346 1347 } else if (tsx == s->invite_tsx) { 1511 1512 if (tsx->method.id == PJSIP_BYE_METHOD && 1513 tsx->role == PJSIP_ROLE_UAC && 1514 tsx->state == PJSIP_TSX_STATE_COMPLETED) 1515 { 1516 /* 1517 * Outgoing BYE. 1518 */ 1519 pj_status_t status; 1348 1520 1349 switch (tsx->state) { 1350 case PJSIP_TSX_STATE_TERMINATED: 1351 case PJSIP_TSX_STATE_DESTROYED: 1352 break; 1353 default: 1354 pj_assert(!"Unexpected state"); 1355 break; 1356 } 1357 1358 } else if (tsx->method.id == PJSIP_INVITE_METHOD) { 1359 1360 /* Re-INVITE */ 1361 1362 } else { 1363 pj_assert(!"Unexpected transaction type"); 1364 } 1365 } 1366 1367 static void inv_on_state_disconnected( pjsip_inv_session *s, pjsip_event *e) 1368 { 1369 PJ_UNUSED_ARG(s); 1370 PJ_UNUSED_ARG(e); 1371 } 1372 1373 static void inv_on_state_terminated( pjsip_inv_session *s, pjsip_event *e) 1374 { 1375 PJ_UNUSED_ARG(s); 1376 PJ_UNUSED_ARG(e); 1377 } 1378 1521 /* Handle 401/407 challenge. */ 1522 if (tsx->status_code == 401 || tsx->status_code == 407) { 1523 1524 pjsip_tx_data *tdata; 1525 1526 status = pjsip_auth_clt_reinit_req( &inv->dlg->auth_sess, 1527 e->body.tsx_state.src.rdata, 1528 tsx->last_tx, 1529 &tdata); 1530 1531 if (status != PJ_SUCCESS) { 1532 1533 /* Does not have proper credentials. 1534 * End the session anyway. 1535 */ 1536 inv_set_state(inv, PJSIP_INV_STATE_DISCONNECTED, e); 1537 1538 } else { 1539 /* Re-send BYE. */ 1540 status = pjsip_inv_send_msg(inv, tdata, NULL ); 1541 } 1542 1543 } else { 1544 1545 /* End the session. */ 1546 1547 inv_set_state(inv, PJSIP_INV_STATE_DISCONNECTED, e); 1548 } 1549 1550 } 1551 else if (tsx->method.id == PJSIP_BYE_METHOD && 1552 tsx->role == PJSIP_ROLE_UAS && 1553 tsx->status_code < 200 && 1554 e->body.tsx_state.type == PJSIP_EVENT_RX_MSG) 1555 { 1556 1557 /* 1558 * Handle incoming BYE. 1559 */ 1560 1561 inv_respond_incoming_bye( inv, tsx, e->body.tsx_state.src.rdata, e ); 1562 1563 } 1564 } 1565 1566 /* 1567 * After session has been terminated, but before dialog is destroyed 1568 * (because dialog has other usages, or because dialog is waiting for 1569 * the last transaction to terminate). 1570 */ 1571 static void inv_on_state_disconnected( pjsip_inv_session *inv, pjsip_event *e) 1572 { 1573 pjsip_transaction *tsx = e->body.tsx_state.tsx; 1574 pjsip_dialog *dlg = pjsip_tsx_get_dlg(tsx); 1575 1576 PJ_ASSERT_ON_FAIL(tsx && dlg, return); 1577 1578 if (tsx->method.id == PJSIP_BYE_METHOD && 1579 tsx->role == PJSIP_ROLE_UAS && 1580 tsx->status_code < 200 && 1581 e->body.tsx_state.type == PJSIP_EVENT_RX_MSG) 1582 { 1583 1584 /* 1585 * Be nice, handle incoming BYE. 1586 */ 1587 1588 inv_respond_incoming_bye( inv, tsx, e->body.tsx_state.src.rdata, e ); 1589 1590 } 1591 } 1592 -
pjproject/trunk/pjsip/src/pjsip/sip_util.c
r141 r156 537 537 const pjsip_cseq_hdr *cseq_hdr; 538 538 const pjsip_hdr *hdr; 539 pjsip_hdr *via; 539 540 pj_status_t status; 540 541 … … 572 573 if (status != PJ_SUCCESS) 573 574 return status; 575 576 /* Clear Via headers in the new request. */ 577 while ((via=pjsip_msg_find_hdr(cancel_tdata->msg, PJSIP_H_VIA, NULL)) != NULL) 578 pj_list_erase(via); 579 574 580 575 581 /* Must only have single Via which matches the top-most Via in the
Note: See TracChangeset
for help on using the changeset viewer.