Ignore:
Timestamp:
Feb 26, 2006 9:23:45 PM (18 years ago)
Author:
bennylp
Message:

Major redesign in pjsua: call is indexed by number, multiple accounts, configurable max-calls, more auto-xxx features, fixed bugs in save_settings(), etc.

File:
1 moved

Legend:

Unmodified
Added
Removed
  • pjproject/trunk/pjsip/src/pjsua/pjsua_call.c

    r226 r236  
    3333 * Make outgoing call. 
    3434 */ 
    35 pj_status_t pjsua_invite(const char *cstr_dest_uri, 
    36                          struct pjsua_inv_data **p_inv_data) 
     35pj_status_t pjsua_make_call(int acc_index, 
     36                            const char *cstr_dest_uri, 
     37                            int *p_call_index) 
    3738{ 
    3839    pj_str_t dest_uri; 
     
    4041    pjmedia_sdp_session *offer; 
    4142    pjsip_inv_session *inv; 
    42     struct pjsua_inv_data *inv_data; 
     43    int call_index = -1; 
    4344    pjsip_tx_data *tdata; 
    44     int med_sk_index = 0; 
    4545    pj_status_t status; 
    4646 
     
    4949    dest_uri = pj_str((char*)cstr_dest_uri); 
    5050 
    51     /* Find free socket. */ 
    52     for (med_sk_index=0; med_sk_index<PJSUA_MAX_CALLS; ++med_sk_index) { 
    53         if (!pjsua.med_sock_use[med_sk_index]) 
     51    /* Find free call slot. */ 
     52    for (call_index=0; call_index<pjsua.max_calls; ++call_index) { 
     53        if (pjsua.calls[call_index].inv == NULL) 
    5454            break; 
    5555    } 
    5656 
    57     if (med_sk_index == PJSUA_MAX_CALLS) { 
     57    if (call_index == pjsua.max_calls) { 
    5858        PJ_LOG(3,(THIS_FILE, "Error: too many calls!")); 
    5959        return PJ_ETOOMANY; 
    6060    } 
    6161 
    62     pjsua.med_sock_use[med_sk_index] = 1; 
    63  
    6462    /* Create outgoing dialog: */ 
    6563 
    66     status = pjsip_dlg_create_uac( pjsip_ua_instance(), &pjsua.local_uri, 
    67                                    &pjsua.contact_uri, &dest_uri, &dest_uri, 
     64    status = pjsip_dlg_create_uac( pjsip_ua_instance(),  
     65                                   &pjsua.acc[acc_index].local_uri, 
     66                                   &pjsua.acc[acc_index].contact_uri,  
     67                                   &dest_uri, &dest_uri, 
    6868                                   &dlg); 
    6969    if (status != PJ_SUCCESS) { 
     
    7474    /* Get media capability from media endpoint: */ 
    7575 
    76     status = pjmedia_endpt_create_sdp( pjsua.med_endpt, dlg->pool, 
    77                                        1, &pjsua.med_sock_info[med_sk_index],  
     76    status = pjmedia_endpt_create_sdp( pjsua.med_endpt, dlg->pool, 1,  
     77                                       &pjsua.calls[call_index].skinfo,  
    7878                                       &offer); 
    7979    if (status != PJ_SUCCESS) { 
     
    9393    /* Create and associate our data in the session. */ 
    9494 
    95     inv_data = pj_pool_zalloc( dlg->pool, sizeof(struct pjsua_inv_data)); 
    96     inv_data->inv = inv; 
    97     inv_data->call_slot = med_sk_index; 
    98     dlg->mod_data[pjsua.mod.id] = inv_data; 
    99     inv->mod_data[pjsua.mod.id] = inv_data; 
     95    pjsua.calls[call_index].inv = inv; 
     96 
     97    dlg->mod_data[pjsua.mod.id] = &pjsua.calls[call_index]; 
     98    inv->mod_data[pjsua.mod.id] = &pjsua.calls[call_index]; 
    10099 
    101100 
    102101    /* Set dialog Route-Set: */ 
    103102 
    104     if (!pj_list_empty(&pjsua.route_set)) 
    105         pjsip_dlg_set_route_set(dlg, &pjsua.route_set); 
     103    if (!pj_list_empty(&pjsua.acc[acc_index].route_set)) 
     104        pjsip_dlg_set_route_set(dlg, &pjsua.acc[acc_index].route_set); 
    106105 
    107106 
     
    122121 
    123122 
    124     /* Add invite session to the list. */ 
    125      
    126     pj_list_push_back(&pjsua.inv_list, inv_data); 
    127  
    128  
    129123    /* Send initial INVITE: */ 
    130124 
    131125    status = pjsip_inv_send_msg(inv, tdata, NULL); 
    132126    if (status != PJ_SUCCESS) { 
    133         /* 
    134          * Note: 
    135          *  inv_data will be removed from the list in the callback 
    136          */ 
    137127        pjsua_perror(THIS_FILE, "Unable to send initial INVITE request",  
    138128                     status); 
     
    142132 
    143133    /* Done. */ 
    144     if (p_inv_data) 
    145         *p_inv_data = inv_data; 
     134 
     135    ++pjsua.call_cnt; 
     136 
     137    if (p_call_index) 
     138        *p_call_index = call_index; 
    146139 
    147140    return PJ_SUCCESS; 
     
    149142 
    150143on_error: 
    151  
    152144    PJ_TODO(DESTROY_DIALOG_ON_FAIL); 
    153     pjsua.med_sock_use[med_sk_index] = 0; 
     145    if (call_index != -1) { 
     146        pjsua.calls[call_index].inv = NULL; 
     147    } 
    154148    return status; 
    155149} 
     
    159153 * Handle incoming INVITE request. 
    160154 */ 
    161 pj_bool_t pjsua_inv_on_incoming(pjsip_rx_data *rdata) 
     155pj_bool_t pjsua_call_on_incoming(pjsip_rx_data *rdata) 
    162156{ 
    163157    pjsip_dialog *dlg = pjsip_rdata_get_dlg(rdata); 
     
    167161    unsigned options = 0; 
    168162    pjsip_inv_session *inv; 
    169     struct pjsua_inv_data *inv_data; 
     163    int acc_index; 
     164    int call_index = -1; 
    170165    pjmedia_sdp_session *answer; 
    171     int med_sk_index; 
    172166    pj_status_t status; 
    173167 
     
    215209 
    216210    /* Find free call slot. */ 
    217     for (med_sk_index=0; med_sk_index<PJSUA_MAX_CALLS; ++med_sk_index) { 
    218         if (!pjsua.med_sock_use[med_sk_index]) 
     211    for (call_index=0; call_index < pjsua.max_calls; ++call_index) { 
     212        if (pjsua.calls[call_index].inv == NULL) 
    219213            break; 
    220214    } 
    221215 
    222     if (med_sk_index == PJSUA_MAX_CALLS) { 
     216    if (call_index == PJSUA_MAX_CALLS) { 
    223217        pjsip_endpt_respond_stateless(pjsua.endpt, rdata,  
    224218                                      PJSIP_SC_BUSY_HERE, NULL, 
     
    228222 
    229223 
    230     pjsua.med_sock_use[med_sk_index] = 1; 
    231  
    232224    /* Get media capability from media endpoint: */ 
    233225 
    234     status = pjmedia_endpt_create_sdp( pjsua.med_endpt, rdata->tp_info.pool, 
    235                                        1, &pjsua.med_sock_info[med_sk_index],  
     226    status = pjmedia_endpt_create_sdp( pjsua.med_endpt, rdata->tp_info.pool, 1, 
     227                                       &pjsua.calls[call_index].skinfo,  
    236228                                       &answer ); 
    237229    if (status != PJ_SUCCESS) { 
     
    239231                                      NULL, NULL); 
    240232 
    241         /* Free call socket. */ 
    242         pjsua.med_sock_use[med_sk_index] = 0; 
    243233        return PJ_TRUE; 
    244234    } 
    245235 
     236    /* TODO:  
     237     * 
     238     * Get which account is most likely to be associated with this incoming 
     239     * call. We need the account to find which contact URI to put for 
     240     * the call. 
     241     */ 
     242    acc_index = 0; 
     243 
    246244    /* Create dialog: */ 
    247245 
    248246    status = pjsip_dlg_create_uas( pjsip_ua_instance(), rdata, 
    249                                    &pjsua.contact_uri, &dlg); 
     247                                   &pjsua.acc[acc_index].contact_uri,  
     248                                   &dlg); 
    250249    if (status != PJ_SUCCESS) { 
    251250        pjsip_endpt_respond_stateless(pjsua.endpt, rdata, 500, NULL, 
    252251                                      NULL, NULL); 
    253252 
    254         /* Free call socket. */ 
    255         pjsua.med_sock_use[med_sk_index] = 0; 
    256253        return PJ_TRUE; 
    257254    } 
     
    264261 
    265262        pjsip_dlg_respond(dlg, rdata, 500, NULL); 
    266  
    267         /* Free call socket. */ 
    268         pjsua.med_sock_use[med_sk_index] = 0; 
    269263 
    270264        // TODO: Need to delete dialog 
     
    275269    /* Create and attach pjsua data to the dialog: */ 
    276270 
    277     inv_data = pj_pool_zalloc(dlg->pool, sizeof(struct pjsua_inv_data)); 
    278     inv_data->inv = inv; 
    279     inv_data->call_slot = inv_data->call_slot = med_sk_index; 
    280     dlg->mod_data[pjsua.mod.id] = inv_data; 
    281     inv->mod_data[pjsua.mod.id] = inv_data; 
    282  
    283     pj_list_push_back(&pjsua.inv_list, inv_data); 
     271    pjsua.calls[call_index].inv = inv; 
     272 
     273    dlg->mod_data[pjsua.mod.id] = &pjsua.calls[call_index]; 
     274    inv->mod_data[pjsua.mod.id] = &pjsua.calls[call_index]; 
    284275 
    285276 
     
    296287 
    297288        pjsip_dlg_respond(dlg, rdata, 500, NULL); 
    298  
    299         /* Free call socket. */ 
    300         pjsua.med_sock_use[med_sk_index] = 0; 
    301289 
    302290        // TODO: Need to delete dialog 
     
    329317    } 
    330318 
     319    ++pjsua.call_cnt; 
     320 
    331321    /* This INVITE request has been handled. */ 
    332322    return PJ_TRUE; 
     
    338328 * session state has changed. 
    339329 */ 
    340 void pjsua_inv_on_state_changed(pjsip_inv_session *inv, pjsip_event *e) 
    341 { 
    342     struct pjsua_inv_data *inv_data; 
    343  
    344     inv_data = inv->dlg->mod_data[pjsua.mod.id]; 
     330static void pjsua_call_on_state_changed(pjsip_inv_session *inv,  
     331                                        pjsip_event *e) 
     332{ 
     333    pjsua_call *call = inv->dlg->mod_data[pjsua.mod.id]; 
    345334 
    346335    /* If this is an outgoing INVITE that was created because of 
    347336     * REFER/transfer, send NOTIFY to transferer. 
    348337     */ 
    349     if (inv_data && inv_data->xfer_sub && e->type==PJSIP_EVENT_TSX_STATE)  
    350     { 
     338    if (call && call->xfer_sub && e->type==PJSIP_EVENT_TSX_STATE)  { 
    351339        int st_code = -1; 
    352340        pjsip_evsub_state ev_state = PJSIP_EVSUB_STATE_ACTIVE; 
    353341         
    354342 
    355         switch (inv->state) { 
     343        switch (call->inv->state) { 
    356344        case PJSIP_INV_STATE_NULL: 
    357345        case PJSIP_INV_STATE_CALLING: 
     
    383371            pj_status_t status; 
    384372 
    385             status = pjsip_xfer_notify( inv_data->xfer_sub, 
     373            status = pjsip_xfer_notify( call->xfer_sub, 
    386374                                        ev_state, st_code, 
    387375                                        NULL, &tdata); 
     
    389377                pjsua_perror(THIS_FILE, "Unable to create NOTIFY", status); 
    390378            } else { 
    391                 status = pjsip_xfer_send_request(inv_data->xfer_sub, tdata); 
     379                status = pjsip_xfer_send_request(call->xfer_sub, tdata); 
    392380                if (status != PJ_SUCCESS) { 
    393381                    pjsua_perror(THIS_FILE, "Unable to send NOTIFY", status); 
     
    398386 
    399387 
     388    pjsua_ui_inv_on_state_changed(call->index, e); 
     389 
     390    /* call->inv may be NULL now */ 
     391 
    400392    /* Destroy media session when invite session is disconnected. */ 
    401393    if (inv->state == PJSIP_INV_STATE_DISCONNECTED) { 
    402394 
    403         pj_assert(inv_data != NULL); 
    404  
    405         if (inv_data && inv_data->session) { 
    406             pjmedia_conf_remove_port(pjsua.mconf, inv_data->conf_slot); 
    407             pjmedia_session_destroy(inv_data->session); 
    408             pjsua.med_sock_use[inv_data->call_slot] = 0; 
    409             inv_data->session = NULL; 
     395        pj_assert(call != NULL); 
     396 
     397        if (call && call->session) { 
     398            pjmedia_conf_remove_port(pjsua.mconf, call->conf_slot); 
     399            pjmedia_session_destroy(call->session); 
     400            call->session = NULL; 
    410401 
    411402            PJ_LOG(3,(THIS_FILE,"Media session is destroyed")); 
    412403        } 
    413404 
    414         if (inv_data) { 
    415  
    416             pj_list_erase(inv_data); 
    417  
    418         } 
    419     } 
    420  
    421     pjsua_ui_inv_on_state_changed(inv, e); 
     405        call->inv = NULL; 
     406        --pjsua.call_cnt; 
     407    } 
    422408} 
    423409 
     
    437423     */ 
    438424    if (pjsip_evsub_get_state(sub) == PJSIP_EVSUB_STATE_TERMINATED) { 
    439         struct pjsua_inv_data *inv_data; 
    440  
    441         inv_data = pjsip_evsub_get_mod_data(sub, pjsua.mod.id); 
    442         if (!inv_data) 
     425        pjsua_call *call; 
     426 
     427        call = pjsip_evsub_get_mod_data(sub, pjsua.mod.id); 
     428        if (!call) 
    443429            return; 
    444430 
    445431        pjsip_evsub_set_mod_data(sub, pjsua.mod.id, NULL); 
    446         inv_data->xfer_sub = NULL; 
     432        call->xfer_sub = NULL; 
    447433 
    448434        PJ_LOG(3,(THIS_FILE, "Xfer subscription terminated")); 
     
    459445    pj_status_t status; 
    460446    pjsip_tx_data *tdata; 
    461     struct pjsua_inv_data *inv_data; 
     447    pjsua_call *existing_call; 
     448    int new_call; 
    462449    const pj_str_t str_refer_to = { "Refer-To", 8}; 
    463450    pjsip_generic_string_hdr *refer_to; 
     
    465452    struct pjsip_evsub_user xfer_cb; 
    466453    pjsip_evsub *sub; 
     454 
     455    existing_call = inv->dlg->mod_data[pjsua.mod.id]; 
    467456 
    468457    /* Find the Refer-To header */ 
     
    524513 
    525514    /* Now make the outgoing call. */ 
    526     status = pjsua_invite(uri, &inv_data); 
     515    status = pjsua_make_call(existing_call->acc_index, uri, &new_call); 
    527516    if (status != PJ_SUCCESS) { 
    528517 
     
    548537     * reported back to the server subscription. 
    549538     */ 
    550     inv_data->xfer_sub = sub; 
     539    pjsua.calls[new_call].xfer_sub = sub; 
    551540 
    552541    /* Put the invite_data in the subscription. */ 
    553     pjsip_evsub_set_mod_data(sub, pjsua.mod.id, inv_data); 
     542    pjsip_evsub_set_mod_data(sub, pjsua.mod.id, &pjsua.calls[new_call]); 
    554543} 
    555544 
     
    559548 * session. We use this to trap incoming REFER request. 
    560549 */ 
    561 void pjsua_inv_on_tsx_state_changed(pjsip_inv_session *inv, 
    562                                     pjsip_transaction *tsx, 
    563                                     pjsip_event *e) 
    564 { 
     550static void pjsua_call_on_tsx_state_changed(pjsip_inv_session *inv, 
     551                                            pjsip_transaction *tsx, 
     552                                            pjsip_event *e) 
     553{ 
     554    pjsua_call *call = inv->dlg->mod_data[pjsua.mod.id]; 
     555 
    565556    if (tsx->role==PJSIP_ROLE_UAS && 
    566557        tsx->state==PJSIP_TSX_STATE_TRYING && 
     
    570561         * Incoming REFER request. 
    571562         */ 
    572         on_call_transfered(inv, e->body.tsx_state.src.rdata); 
     563        on_call_transfered(call->inv, e->body.tsx_state.src.rdata); 
    573564    } 
    574565} 
     
    579570 * has forked. 
    580571 */ 
    581 void pjsua_inv_on_new_session(pjsip_inv_session *inv, pjsip_event *e) 
     572static void pjsua_call_on_forked( pjsip_inv_session *inv,  
     573                                  pjsip_event *e) 
    582574{ 
    583575    PJ_UNUSED_ARG(inv); 
     
    591583 * Create inactive SDP for call hold. 
    592584 */ 
    593 static pj_status_t create_inactive_sdp(struct pjsua_inv_data *inv_session, 
     585static pj_status_t create_inactive_sdp(pjsua_call *call, 
    594586                                       pjmedia_sdp_session **p_answer) 
    595587{ 
     
    601593    /* Create new offer */ 
    602594    status = pjmedia_endpt_create_sdp(pjsua.med_endpt, pjsua.pool, 1, 
    603                                       &pjsua.med_sock_info[inv_session->call_slot], 
    604                                       &sdp); 
     595                                      &call->skinfo, &sdp); 
    605596    if (status != PJ_SUCCESS) { 
    606597        pjsua_perror(THIS_FILE, "Unable to create local SDP", status); 
     
    634625 * Called when session received new offer. 
    635626 */ 
    636 void pjsua_inv_on_rx_offer( pjsip_inv_session *inv, 
    637                             const pjmedia_sdp_session *offer) 
    638 { 
    639     struct pjsua_inv_data *inv_data; 
     627static void pjsua_call_on_rx_offer(pjsip_inv_session *inv, 
     628                                   const pjmedia_sdp_session *offer) 
     629{ 
     630    pjsua_call *call; 
    640631    pjmedia_sdp_conn *conn; 
    641632    pjmedia_sdp_session *answer; 
     
    643634    pj_status_t status; 
    644635 
    645     inv_data = inv->dlg->mod_data[pjsua.mod.id]; 
     636    call = inv->dlg->mod_data[pjsua.mod.id]; 
    646637 
    647638    /* 
     
    670661    /* Supply candidate answer */ 
    671662    if (is_remote_active) { 
    672         status = pjmedia_endpt_create_sdp( pjsua.med_endpt, inv->pool, 1, 
    673                                            &pjsua.med_sock_info[inv_data->call_slot], 
    674                                            &answer); 
     663        status = pjmedia_endpt_create_sdp( pjsua.med_endpt, call->inv->pool, 1, 
     664                                           &call->skinfo, &answer); 
    675665    } else { 
    676         status = create_inactive_sdp( inv_data, &answer ); 
     666        status = create_inactive_sdp( call, &answer ); 
    677667    } 
    678668 
     
    682672    } 
    683673 
    684     status = pjsip_inv_set_sdp_answer(inv, answer); 
     674    status = pjsip_inv_set_sdp_answer(call->inv, answer); 
    685675    if (status != PJ_SUCCESS) { 
    686676        pjsua_perror(THIS_FILE, "Unable to set answer", status); 
     
    696686 * has succeeded. 
    697687 */ 
    698 void pjsua_inv_on_media_update(pjsip_inv_session *inv, pj_status_t status) 
    699 { 
    700     struct pjsua_inv_data *inv_data; 
     688static void pjsua_call_on_media_update(pjsip_inv_session *inv, 
     689                                       pj_status_t status) 
     690{ 
     691    pjsua_call *call; 
    701692    const pjmedia_sdp_session *local_sdp; 
    702693    const pjmedia_sdp_session *remote_sdp; 
     
    705696    char tmp[PJSIP_MAX_URL_SIZE]; 
    706697 
     698    call = inv->dlg->mod_data[pjsua.mod.id]; 
     699 
    707700    if (status != PJ_SUCCESS) { 
    708701 
     
    714707    /* Destroy existing media session, if any. */ 
    715708 
    716     inv_data = inv->dlg->mod_data[pjsua.mod.id]; 
    717     if (inv_data && inv_data->session) { 
    718         pjmedia_conf_remove_port(pjsua.mconf, inv_data->conf_slot); 
    719         pjmedia_session_destroy(inv_data->session); 
    720         pjsua.med_sock_use[inv_data->call_slot] = 0; 
    721         inv_data->session = NULL; 
     709    if (call && call->session) { 
     710        pjmedia_conf_remove_port(pjsua.mconf, call->conf_slot); 
     711        pjmedia_session_destroy(call->session); 
     712        call->session = NULL; 
    722713    } 
    723714 
    724715    /* Get local and remote SDP */ 
    725716 
    726     status = pjmedia_sdp_neg_get_active_local(inv->neg, &local_sdp); 
     717    status = pjmedia_sdp_neg_get_active_local(call->inv->neg, &local_sdp); 
    727718    if (status != PJ_SUCCESS) { 
    728719        pjsua_perror(THIS_FILE,  
     
    733724 
    734725 
    735     status = pjmedia_sdp_neg_get_active_remote(inv->neg, &remote_sdp); 
     726    status = pjmedia_sdp_neg_get_active_remote(call->inv->neg, &remote_sdp); 
    736727    if (status != PJ_SUCCESS) { 
    737728        pjsua_perror(THIS_FILE,  
     
    748739     
    749740    status = pjmedia_session_create( pjsua.med_endpt, 1,  
    750                                      &pjsua.med_sock_info[inv_data->call_slot], 
     741                                     &call->skinfo, 
    751742                                     local_sdp, remote_sdp,  
    752                                      inv_data, 
    753                                      &inv_data->session ); 
     743                                     call, 
     744                                     &call->session ); 
    754745    if (status != PJ_SUCCESS) { 
    755746        pjsua_perror(THIS_FILE, "Unable to create media session",  
     
    762753     * We need the port interface to add to the conference bridge. 
    763754     */ 
    764     pjmedia_session_get_port(inv_data->session, 0, &media_port); 
     755    pjmedia_session_get_port(call->session, 0, &media_port); 
    765756 
    766757 
     
    770761    port_name.ptr = tmp; 
    771762    port_name.slen = pjsip_uri_print(PJSIP_URI_IN_REQ_URI, 
    772                                      inv_data->inv->dlg->remote.info->uri, 
     763                                     call->inv->dlg->remote.info->uri, 
    773764                                     tmp, sizeof(tmp)); 
    774765    if (port_name.slen < 1) { 
    775766        port_name = pj_str("call"); 
    776767    } 
    777     status = pjmedia_conf_add_port( pjsua.mconf, inv->pool, 
     768    status = pjmedia_conf_add_port( pjsua.mconf, call->inv->pool, 
    778769                                    media_port,  
    779770                                    &port_name, 
    780                                     &inv_data->conf_slot); 
     771                                    &call->conf_slot); 
    781772    if (status != PJ_SUCCESS) { 
    782773        pjsua_perror(THIS_FILE, "Unable to create conference slot",  
    783774                     status); 
    784         pjmedia_session_destroy(inv_data->session); 
    785         inv_data->session = NULL; 
     775        pjmedia_session_destroy(call->session); 
     776        call->session = NULL; 
    786777        return; 
    787778    } 
     
    790781     * port  
    791782     */ 
    792     if (pjsua.wav_file && inv->role == PJSIP_ROLE_UAS) { 
     783    if (pjsua.auto_play && pjsua.wav_file &&  
     784        call->inv->role == PJSIP_ROLE_UAS)  
     785    { 
    793786 
    794787        pjmedia_conf_connect_port( pjsua.mconf, pjsua.wav_slot,  
    795                                    inv_data->conf_slot); 
     788                                   call->conf_slot); 
     789 
     790    } else if (pjsua.auto_loop && call->inv->role == PJSIP_ROLE_UAS) { 
     791 
     792        pjmedia_conf_connect_port( pjsua.mconf, call->conf_slot,  
     793                                   call->conf_slot); 
     794 
     795    } else if (pjsua.auto_conf) { 
     796 
     797        int i; 
     798 
     799        pjmedia_conf_connect_port( pjsua.mconf, 0, call->conf_slot); 
     800        pjmedia_conf_connect_port( pjsua.mconf, call->conf_slot, 0); 
     801 
     802        for (i=0; i < pjsua.max_calls; ++i) { 
     803 
     804            if (!pjsua.calls[i].session) 
     805                continue; 
     806 
     807            pjmedia_conf_connect_port( pjsua.mconf, call->conf_slot,  
     808                                       pjsua.calls[i].conf_slot); 
     809            pjmedia_conf_connect_port( pjsua.mconf, pjsua.calls[i].conf_slot, 
     810                                       call->conf_slot); 
     811        } 
    796812 
    797813    } else { 
     
    800816         * main conference bridge. 
    801817         */ 
    802         pjmedia_conf_connect_port( pjsua.mconf, 0, inv_data->conf_slot); 
    803         pjmedia_conf_connect_port( pjsua.mconf, inv_data->conf_slot, 0); 
     818        pjmedia_conf_connect_port( pjsua.mconf, 0, call->conf_slot); 
     819        pjmedia_conf_connect_port( pjsua.mconf, call->conf_slot, 0); 
    804820    } 
    805821 
     
    812828        unsigned i; 
    813829 
    814         pjmedia_session_get_info(inv_data->session, &sess_info); 
     830        pjmedia_session_get_info(call->session, &sess_info); 
    815831        for (i=0; i<sess_info.stream_cnt; ++i) { 
    816832            int len; 
     
    851867 * Hangup call. 
    852868 */ 
    853 void pjsua_inv_hangup(struct pjsua_inv_data *inv_session, int code) 
    854 { 
     869void pjsua_call_hangup(int call_index, int code) 
     870{ 
     871    pjsua_call *call; 
    855872    pj_status_t status; 
    856873    pjsip_tx_data *tdata; 
    857874 
    858     status = pjsip_inv_end_session(inv_session->inv,  
    859                                    code, NULL, &tdata); 
     875 
     876    call = &pjsua.calls[call_index]; 
     877 
     878    if (!call->inv) { 
     879        PJ_LOG(3,(THIS_FILE,"Call has been disconnected")); 
     880        return; 
     881    } 
     882 
     883    status = pjsip_inv_end_session(call->inv, code, NULL, &tdata); 
    860884    if (status != PJ_SUCCESS) { 
    861885        pjsua_perror(THIS_FILE,  
     
    872896        return; 
    873897 
    874     status = pjsip_inv_send_msg(inv_session->inv, tdata, NULL); 
     898    status = pjsip_inv_send_msg(call->inv, tdata, NULL); 
    875899    if (status != PJ_SUCCESS) { 
    876900        pjsua_perror(THIS_FILE,  
     
    885909 * Put call on-Hold. 
    886910 */ 
    887 void pjsua_inv_set_hold(struct pjsua_inv_data *inv_session) 
     911void pjsua_call_set_hold(int call_index) 
    888912{ 
    889913    pjmedia_sdp_session *sdp; 
    890     pjsip_inv_session *inv = inv_session->inv; 
     914    pjsua_call *call; 
    891915    pjsip_tx_data *tdata; 
    892916    pj_status_t status; 
    893917 
    894     if (inv->state != PJSIP_INV_STATE_CONFIRMED) { 
     918    call = &pjsua.calls[call_index]; 
     919     
     920    if (!call->inv) { 
     921        PJ_LOG(3,(THIS_FILE,"Call has been disconnected")); 
     922        return; 
     923    } 
     924 
     925    if (call->inv->state != PJSIP_INV_STATE_CONFIRMED) { 
    895926        PJ_LOG(3,(THIS_FILE, "Can not hold call that is not confirmed")); 
    896927        return; 
    897928    } 
    898929 
    899     status = create_inactive_sdp(inv_session, &sdp); 
     930    status = create_inactive_sdp(call, &sdp); 
    900931    if (status != PJ_SUCCESS) 
    901932        return; 
    902933 
    903934    /* Send re-INVITE with new offer */ 
    904     status = pjsip_inv_reinvite( inv_session->inv, NULL, sdp, &tdata); 
     935    status = pjsip_inv_reinvite( call->inv, NULL, sdp, &tdata); 
    905936    if (status != PJ_SUCCESS) { 
    906937        pjsua_perror(THIS_FILE, "Unable to create re-INVITE", status); 
     
    908939    } 
    909940 
    910     status = pjsip_inv_send_msg( inv_session->inv, tdata, NULL); 
     941    status = pjsip_inv_send_msg( call->inv, tdata, NULL); 
    911942    if (status != PJ_SUCCESS) { 
    912943        pjsua_perror(THIS_FILE, "Unable to send re-INVITE", status); 
     
    919950 * re-INVITE. 
    920951 */ 
    921 void pjsua_inv_reinvite(struct pjsua_inv_data *inv_session) 
     952void pjsua_call_reinvite(int call_index) 
    922953{ 
    923954    pjmedia_sdp_session *sdp; 
    924955    pjsip_tx_data *tdata; 
    925     pjsip_inv_session *inv = inv_session->inv; 
     956    pjsua_call *call; 
    926957    pj_status_t status; 
    927958 
    928  
    929     if (inv->state != PJSIP_INV_STATE_CONFIRMED) { 
     959    call = &pjsua.calls[call_index]; 
     960 
     961    if (!call->inv) { 
     962        PJ_LOG(3,(THIS_FILE,"Call has been disconnected")); 
     963        return; 
     964    } 
     965 
     966 
     967    if (call->inv->state != PJSIP_INV_STATE_CONFIRMED) { 
    930968        PJ_LOG(3,(THIS_FILE, "Can not re-INVITE call that is not confirmed")); 
    931969        return; 
     
    933971 
    934972    /* Create SDP */ 
    935     status = pjmedia_endpt_create_sdp( pjsua.med_endpt, inv->pool, 1, 
    936                                        &pjsua.med_sock_info[inv_session->call_slot], 
    937                                        &sdp); 
    938     if (status != PJ_SUCCESS) { 
    939         pjsua_perror(THIS_FILE, "Unable to get SDP from media endpoint", status); 
     973    status = pjmedia_endpt_create_sdp( pjsua.med_endpt, call->inv->pool, 1, 
     974                                       &call->skinfo, &sdp); 
     975    if (status != PJ_SUCCESS) { 
     976        pjsua_perror(THIS_FILE, "Unable to get SDP from media endpoint",  
     977                    status); 
    940978        return; 
    941979    } 
    942980 
    943981    /* Send re-INVITE with new offer */ 
    944     status = pjsip_inv_reinvite( inv_session->inv, NULL, sdp, &tdata); 
     982    status = pjsip_inv_reinvite( call->inv, NULL, sdp, &tdata); 
    945983    if (status != PJ_SUCCESS) { 
    946984        pjsua_perror(THIS_FILE, "Unable to create re-INVITE", status); 
     
    948986    } 
    949987 
    950     status = pjsip_inv_send_msg( inv_session->inv, tdata, NULL); 
     988    status = pjsip_inv_send_msg( call->inv, tdata, NULL); 
    951989    if (status != PJ_SUCCESS) { 
    952990        pjsua_perror(THIS_FILE, "Unable to send re-INVITE", status); 
     
    959997 * Transfer call. 
    960998 */ 
    961 void pjsua_inv_xfer_call(struct pjsua_inv_data *inv_session, 
    962                          const char *dest) 
     999void pjsua_call_xfer(int call_index, const char *dest) 
    9631000{ 
    9641001    pjsip_evsub *sub; 
    9651002    pjsip_tx_data *tdata; 
     1003    pjsua_call *call; 
    9661004    pj_str_t tmp; 
    9671005    pj_status_t status; 
    968   
     1006 
    9691007     
     1008    call = &pjsua.calls[call_index]; 
     1009 
     1010    if (!call->inv) { 
     1011        PJ_LOG(3,(THIS_FILE,"Call has been disconnected")); 
     1012        return; 
     1013    } 
     1014    
    9701015    /* Create xfer client subscription. 
    9711016     * We're not interested in knowing the transfer result, so we 
    9721017     * put NULL as the callback. 
    9731018     */ 
    974     status = pjsip_xfer_create_uac(inv_session->inv->dlg, NULL, &sub); 
     1019    status = pjsip_xfer_create_uac(call->inv->dlg, NULL, &sub); 
    9751020    if (status != PJ_SUCCESS) { 
    9761021        pjsua_perror(THIS_FILE, "Unable to create xfer", status); 
     
    10061051void pjsua_inv_shutdown() 
    10071052{ 
    1008     struct pjsua_inv_data *inv_data, *next; 
    1009  
    1010     inv_data = pjsua.inv_list.next; 
    1011     while (inv_data != &pjsua.inv_list) { 
     1053    int i; 
     1054 
     1055    for (i=0; i<pjsua.max_calls; ++i) { 
    10121056        pjsip_tx_data *tdata; 
    1013  
    1014         next = inv_data->next; 
    1015  
    1016         if (pjsip_inv_end_session(inv_data->inv, 410, NULL, &tdata)==0) { 
     1057        pjsua_call *call; 
     1058 
     1059        if (pjsua.calls[i].inv == NULL) 
     1060            continue; 
     1061 
     1062        call = &pjsua.calls[i]; 
     1063 
     1064        if (pjsip_inv_end_session(call->inv, 410, NULL, &tdata)==0) { 
    10171065            if (tdata) 
    1018                 pjsip_inv_send_msg(inv_data->inv, tdata, NULL); 
     1066                pjsip_inv_send_msg(call->inv, tdata, NULL); 
    10191067        } 
    1020  
    1021         inv_data = next; 
    1022     } 
    1023 } 
    1024  
    1025  
     1068    } 
     1069} 
     1070 
     1071 
     1072pj_status_t pjsua_call_init(void) 
     1073{ 
     1074    /* Initialize invite session callback. */ 
     1075    pjsip_inv_callback inv_cb; 
     1076    pj_status_t status; 
     1077 
     1078    pj_memset(&inv_cb, 0, sizeof(inv_cb)); 
     1079    inv_cb.on_state_changed = &pjsua_call_on_state_changed; 
     1080    inv_cb.on_new_session = &pjsua_call_on_forked; 
     1081    inv_cb.on_media_update = &pjsua_call_on_media_update; 
     1082    inv_cb.on_rx_offer = &pjsua_call_on_rx_offer; 
     1083    inv_cb.on_tsx_state_changed = &pjsua_call_on_tsx_state_changed; 
     1084 
     1085 
     1086    /* Initialize invite session module: */ 
     1087    status = pjsip_inv_usage_init(pjsua.endpt, &pjsua.mod, &inv_cb); 
     1088     
     1089    return status; 
     1090} 
Note: See TracChangeset for help on using the changeset viewer.