Changeset 1379
- Timestamp:
- Jun 20, 2007 10:03:46 AM (17 years ago)
- Location:
- pjproject/trunk
- Files:
-
- 1 added
- 5 edited
Legend:
- Unmodified
- Added
- Removed
-
pjproject/trunk/pjmedia/include/pjmedia/sdp_neg.h
r1072 r1379 51 51 * create_w_local_offer() +-------------+ send_local_offer() 52 52 * ----------------------->| LOCAL_OFFER |<----------------------- 53 * | +-------------+ 54 * | | 55 * | set_remote_answer() | 56 * | V 57 * +--+---+ +-----------+ negotiate() +- -----+53 * | +-------------+______ | 54 * | | \______ cancel() | 55 * | set_remote_answer() | \______ | 56 * | V \ | 57 * +--+---+ +-----------+ negotiate() +-~----+ 58 58 * | NULL | | WAIT_NEGO |-------------------->| DONE | 59 59 * +------+ +-----------+ +------+ … … 173 173 * the negotiator state will move to PJMEDIA_SDP_NEG_STATE_DONE. 174 174 * 175 * 176 * \subsection sdpneg_cancel_offer Cancelling an Offer 177 * 178 * In other case, after an offer is generated (negotiator state is in 179 * PJMEDIA_SDP_NEG_STATE_LOCAL_OFFER), the answer may not be received, and 180 * application wants the negotiator to reset itself to its previous state. 181 * Consider this example: 182 * 183 * - media has been established, and negotiator state is 184 * PJMEDIA_SDP_NEG_STATE_DONE. 185 * - application generates a new offer for re-INVITE, so in this case 186 * it would either call #pjmedia_sdp_neg_send_local_offer() or 187 * #pjmedia_sdp_neg_modify_local_offer() 188 * - the negotiator state moves to PJMEDIA_SDP_NEG_STATE_LOCAL_OFFER 189 * - the re-INVITE was rejected with an error 190 * 191 * Since an answer is not received, it is necessary to reset the negotiator 192 * state back to PJMEDIA_SDP_NEG_STATE_DONE so that the negotiator can 193 * create or receive new offer. 194 * 195 * This can be accomplished by calling #pjmedia_sdp_neg_cancel_offer(), 196 * to reset the negotiator state back to PJMEDIA_SDP_NEG_STATE_DONE. In 197 * this case, both active local and active remote will not be modified. 175 198 * 176 199 * \subsection sdpneg_create_answer Generating SDP Answer … … 599 622 600 623 /** 624 * Cancel previously sent offer, and move negotiator state back to 625 * previous stable state (PJMEDIA_SDP_NEG_STATE_DONE). The negotiator 626 * must be in PJMEDIA_SDP_NEG_STATE_LOCAL_OFFER state. 627 * 628 * @param neg The negotiator. 629 * 630 * @return PJ_SUCCESS or the appropriate error code. 631 */ 632 PJ_DECL(pj_status_t) pjmedia_sdp_neg_cancel_offer(pjmedia_sdp_neg *neg); 633 634 635 /** 601 636 * Negotiate local and remote answer. Before calling this function, the 602 637 * SDP negotiator must be in PJMEDIA_SDP_NEG_STATE_WAIT_NEGO state. -
pjproject/trunk/pjmedia/src/pjmedia/sdp_neg.c
r1266 r1379 986 986 } 987 987 988 /* Cancel offer */ 989 PJ_DEF(pj_status_t) pjmedia_sdp_neg_cancel_offer(pjmedia_sdp_neg *neg) 990 { 991 PJ_ASSERT_RETURN(neg, PJ_EINVAL); 992 993 /* Must be in LOCAL_OFFER state. */ 994 PJ_ASSERT_RETURN(neg->state == PJMEDIA_SDP_NEG_STATE_LOCAL_OFFER, 995 PJMEDIA_SDPNEG_EINSTATE); 996 997 /* Reset state to done */ 998 neg->state = PJMEDIA_SDP_NEG_STATE_DONE; 999 1000 /* Clear temporary SDP */ 1001 neg->neg_local_sdp = neg->neg_remote_sdp = NULL; 1002 neg->has_remote_answer = PJ_FALSE; 1003 1004 return PJ_SUCCESS; 1005 } 1006 1007 988 1008 /* The best bit: SDP negotiation function! */ 989 1009 PJ_DEF(pj_status_t) pjmedia_sdp_neg_negotiate( pj_pool_t *pool, -
pjproject/trunk/pjsip/include/pjsip-ua/sip_inv.h
r1319 r1379 150 150 * This callback is called when the invite session has received 151 151 * new offer from peer. Application can inspect the remote offer 152 * in "offer". 152 * in "offer", and set the SDP answer with #pjsip_inv_set_sdp_answer(). 153 * When the application sends a SIP message to send the answer, 154 * this SDP answer will be negotiated with the offer, and the result 155 * will be sent with the SIP message. 153 156 * 154 157 * @param inv The invite session. … … 157 160 void (*on_rx_offer)(pjsip_inv_session *inv, 158 161 const pjmedia_sdp_session *offer); 162 163 /** 164 * This callback is optional, and it is used to ask the application 165 * to create a fresh offer, when the invite session has received 166 * re-INVITE without offer. This offer then will be sent in the 167 * 200/OK response to the re-INVITE request. 168 * 169 * If application doesn't implement this callback, the invite session 170 * will send the currently active SDP as the offer. 171 * 172 * @param inv The invite session. 173 * @param p_offer Pointer to receive the SDP offer created by 174 * application. 175 */ 176 void (*on_create_offer)(pjsip_inv_session *inv, 177 pjmedia_sdp_session **p_offer); 159 178 160 179 /** -
pjproject/trunk/pjsip/src/pjsip-ua/sip_inv.c
r1377 r1379 1226 1226 */ 1227 1227 1228 if (tsx_inv_data->sdp_done) 1228 if (tsx_inv_data->sdp_done) { 1229 if (rdata->msg_info.msg->body) { 1230 PJ_LOG(4,(inv->obj_name, "SDP negotiation done, message " 1231 "body is ignored")); 1232 } 1229 1233 return PJ_SUCCESS; 1234 } 1230 1235 1231 1236 /* Check if SDP is present in the message. */ … … 1384 1389 pjmedia_sdp_neg_has_local_answer(inv->neg) ) 1385 1390 { 1391 struct tsx_inv_data *tsx_inv_data; 1392 1393 /* Get invite session's transaction data */ 1394 tsx_inv_data = (struct tsx_inv_data*) 1395 inv->invite_tsx->mod_data[mod_inv.mod.id]; 1386 1396 1387 1397 status = inv_negotiate_sdp(inv); … … 1389 1399 return status; 1390 1400 1401 /* Mark this transaction has having SDP offer/answer done. */ 1402 tsx_inv_data->sdp_done = 1; 1403 1391 1404 status = pjmedia_sdp_neg_get_active_local(inv->neg, &sdp); 1392 1405 } … … 2504 2517 status = process_answer(inv, 200, tdata, NULL); 2505 2518 } else { 2506 const pjmedia_sdp_session *active_sdp; 2507 status = pjmedia_sdp_neg_send_local_offer(dlg->pool, 2508 inv->neg, 2509 &active_sdp); 2510 if (status == PJ_SUCCESS) { 2511 tdata->msg->body = create_sdp_body(tdata->pool, active_sdp); 2519 /* INVITE does not have SDP. 2520 * If on_create_offer() callback is implemented, ask app. 2521 * to generate an offer, otherwise just send active local 2522 * SDP to signal that nothing gets modified. 2523 */ 2524 pjmedia_sdp_session *sdp = NULL; 2525 2526 if (mod_inv.cb.on_create_offer) { 2527 (*mod_inv.cb.on_create_offer)(inv, &sdp); 2528 if (sdp) { 2529 status = pjmedia_sdp_neg_modify_local_offer(dlg->pool, 2530 inv->neg, 2531 sdp); 2532 } 2533 } 2534 2535 if (sdp == NULL) { 2536 const pjmedia_sdp_session *active_sdp = NULL; 2537 status = pjmedia_sdp_neg_send_local_offer(dlg->pool, 2538 inv->neg, 2539 &active_sdp); 2540 if (status == PJ_SUCCESS) 2541 sdp = (pjmedia_sdp_session*) active_sdp; 2542 } 2543 2544 if (sdp) { 2545 tdata->msg->body = create_sdp_body(tdata->pool, sdp); 2512 2546 } 2513 2547 } … … 2605 2639 inv_set_cause(inv, tsx->status_code, &tsx->status_text); 2606 2640 inv_set_state(inv, PJSIP_INV_STATE_DISCONNECTED, e); 2641 2642 } else if (tsx->status_code >= 300 && tsx->status_code < 700) { 2643 2644 pjmedia_sdp_neg_state neg_state; 2645 2646 /* Outgoing INVITE transaction has failed, cancel SDP nego */ 2647 neg_state = pjmedia_sdp_neg_get_state(inv->neg); 2648 if (neg_state == PJMEDIA_SDP_NEG_STATE_LOCAL_OFFER) { 2649 pjmedia_sdp_neg_cancel_offer(inv->neg); 2650 } 2607 2651 } 2608 2652 } -
pjproject/trunk/pjsip/src/pjsua-lib/pjsua_call.c
r1291 r1379 51 51 52 52 /* 53 * Called to generate new offer. 54 */ 55 static void pjsua_call_on_create_offer(pjsip_inv_session *inv, 56 pjmedia_sdp_session **offer); 57 58 /* 53 59 * This callback is called when transaction state has changed in INVITE 54 60 * session. We use this to trap: … … 119 125 inv_cb.on_media_update = &pjsua_call_on_media_update; 120 126 inv_cb.on_rx_offer = &pjsua_call_on_rx_offer; 127 inv_cb.on_create_offer = &pjsua_call_on_create_offer; 121 128 inv_cb.on_tsx_state_changed = &pjsua_call_on_tsx_state_changed; 122 129 … … 2296 2303 2297 2304 /* 2305 * Called to generate new offer. 2306 */ 2307 static void pjsua_call_on_create_offer(pjsip_inv_session *inv, 2308 pjmedia_sdp_session **offer) 2309 { 2310 pjsua_call *call; 2311 pj_status_t status; 2312 2313 PJSUA_LOCK(); 2314 2315 call = (pjsua_call*) inv->dlg->mod_data[pjsua_var.mod.id]; 2316 2317 /* See if we've put call on hold. */ 2318 if (call->media_st == PJSUA_CALL_MEDIA_LOCAL_HOLD) { 2319 PJ_LOG(4,(THIS_FILE, 2320 "Call %d: call is on-hold locally, creating inactive SDP ", 2321 call->index)); 2322 status = create_inactive_sdp( call, offer ); 2323 } else { 2324 2325 PJ_LOG(4,(THIS_FILE, "Call %d: asked to send a new offer", 2326 call->index)); 2327 2328 /* Init media channel */ 2329 status = pjsua_media_channel_init(call->index, PJSIP_ROLE_UAC); 2330 if (status != PJ_SUCCESS) { 2331 pjsua_perror(THIS_FILE, "Error initializing media channel", status); 2332 PJSUA_UNLOCK(); 2333 return; 2334 } 2335 2336 status = pjsua_media_channel_create_sdp(call->index, call->inv->pool, offer); 2337 } 2338 2339 if (status != PJ_SUCCESS) { 2340 pjsua_perror(THIS_FILE, "Unable to create local SDP", status); 2341 PJSUA_UNLOCK(); 2342 return; 2343 } 2344 2345 2346 PJSUA_UNLOCK(); 2347 } 2348 2349 2350 /* 2298 2351 * Callback called by event framework when the xfer subscription state 2299 2352 * has changed.
Note: See TracChangeset
for help on using the changeset viewer.