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 edited

Legend:

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

    r230 r236  
    2424 
    2525/* Current dialog */ 
    26 static struct pjsua_inv_data *inv_session; 
     26static int current_acc; 
     27static int current_call = -1; 
     28 
     29 
     30/* 
     31 * Find next call. 
     32 */ 
     33static pj_bool_t find_next_call(void) 
     34{ 
     35    int i; 
     36 
     37    for (i=current_call+1; i<(int)pjsua.max_calls; ++i) { 
     38        if (pjsua.calls[i].inv != NULL) { 
     39            current_call = i; 
     40            return PJ_TRUE; 
     41        } 
     42    } 
     43 
     44    for (i=0; i<current_call; ++i) { 
     45        if (pjsua.calls[i].inv != NULL) { 
     46            current_call = i; 
     47            return PJ_TRUE; 
     48        } 
     49    } 
     50 
     51    current_call = -1; 
     52    return PJ_FALSE; 
     53} 
     54 
     55 
     56/* 
     57 * Find previous call. 
     58 */ 
     59static pj_bool_t find_prev_call(void) 
     60{ 
     61    int i; 
     62 
     63    for (i=current_call-1; i>=0; --i) { 
     64        if (pjsua.calls[i].inv != NULL) { 
     65            current_call = i; 
     66            return PJ_TRUE; 
     67        } 
     68    } 
     69 
     70    for (i=pjsua.max_calls-1; i>current_call; --i) { 
     71        if (pjsua.calls[i].inv != NULL) { 
     72            current_call = i; 
     73            return PJ_TRUE; 
     74        } 
     75    } 
     76 
     77    current_call = -1; 
     78    return PJ_FALSE; 
     79} 
     80 
     81 
    2782 
    2883/* 
    2984 * Notify UI when invite state has changed. 
    3085 */ 
    31 void pjsua_ui_inv_on_state_changed(pjsip_inv_session *inv, pjsip_event *e) 
    32 { 
     86void pjsua_ui_inv_on_state_changed(int call_index, pjsip_event *e) 
     87{ 
     88    pjsua_call *call = &pjsua.calls[call_index]; 
     89 
    3390    PJ_UNUSED_ARG(e); 
    3491 
    35     PJ_LOG(3,(THIS_FILE, "INVITE session state changed to %s",  
    36               pjsua_inv_state_names[inv->state])); 
    37  
    38     if (inv->state == PJSIP_INV_STATE_DISCONNECTED) { 
    39         if (inv == inv_session->inv) { 
    40             inv_session = inv_session->next; 
    41             if (inv_session == &pjsua.inv_list) 
    42                 inv_session = pjsua.inv_list.next; 
     92    PJ_LOG(3,(THIS_FILE, "Call %d state changed to %s",  
     93              call_index, 
     94              pjsua_inv_state_names[call->inv->state])); 
     95 
     96    if (call->inv->state == PJSIP_INV_STATE_DISCONNECTED) { 
     97        call->inv = NULL; 
     98        if ((int)call->index == current_call) { 
     99            find_next_call(); 
    43100        } 
    44101 
    45102    } else { 
    46103 
    47         if (inv_session == &pjsua.inv_list || inv_session == NULL) 
    48             inv_session = inv->mod_data[pjsua.mod.id]; 
     104        if (call && current_call==-1) 
     105            current_call = call->index; 
    49106 
    50107    } 
     
    67124static void print_buddy_list(void) 
    68125{ 
    69     unsigned i; 
     126    int i; 
    70127 
    71128    puts("Buddy list:"); 
    72     //puts("-------------------------------------------------------------------------------"); 
     129 
    73130    if (pjsua.buddy_cnt == 0) 
    74131        puts(" -none-"); 
     
    94151} 
    95152 
     153 
    96154/* 
    97  * Show a bit of help. 
    98  */ 
    99 static void keystroke_help(void) 
     155 * Print account status. 
     156 */ 
     157static void print_acc_status(int acc_index) 
    100158{ 
    101159    char reg_status[128]; 
    102160 
    103     if (pjsua.regc == NULL) { 
     161    if (pjsua.acc[acc_index].regc == NULL) { 
    104162        pj_ansi_strcpy(reg_status, " -not registered to server-"); 
    105     } else if (pjsua.regc_last_err != PJ_SUCCESS) { 
    106         pj_strerror(pjsua.regc_last_err, reg_status, sizeof(reg_status)); 
    107     } else if (pjsua.regc_last_code>=200 && pjsua.regc_last_code<=699) { 
     163 
     164    } else if (pjsua.acc[acc_index].reg_last_err != PJ_SUCCESS) { 
     165        pj_strerror(pjsua.acc[acc_index].reg_last_err, reg_status, sizeof(reg_status)); 
     166 
     167    } else if (pjsua.acc[acc_index].reg_last_code>=200 &&  
     168               pjsua.acc[acc_index].reg_last_code<=699) { 
    108169 
    109170        pjsip_regc_info info; 
    110171 
    111         pjsip_regc_get_info(pjsua.regc, &info); 
     172        pjsip_regc_get_info(pjsua.acc[acc_index].regc, &info); 
    112173 
    113174        pj_snprintf(reg_status, sizeof(reg_status), 
    114175                    "%s (%.*s;expires=%d)", 
    115                     pjsip_get_status_text(pjsua.regc_last_code)->ptr, 
     176                    pjsip_get_status_text(pjsua.acc[acc_index].reg_last_code)->ptr, 
    116177                    (int)info.client_uri.slen, 
    117178                    info.client_uri.ptr, 
     
    119180 
    120181    } else { 
    121         pj_sprintf(reg_status, "in progress (%d)", pjsua.regc_last_code); 
    122     } 
    123  
    124     printf(">>>>\nRegistration status: %s\n", reg_status); 
    125     printf("Online status: %s\n",  
    126            (pjsua.online_status ? "Online" : "Invisible")); 
     182        pj_sprintf(reg_status, "in progress (%d)",  
     183                   pjsua.acc[acc_index].reg_last_code); 
     184    } 
     185 
     186    printf("[%2d] Registration status: %s\n", acc_index, reg_status); 
     187    printf("     Online status: %s\n",  
     188           (pjsua.acc[acc_index].online_status ? "Online" : "Invisible")); 
     189} 
     190 
     191/* 
     192 * Show a bit of help. 
     193 */ 
     194static void keystroke_help(void) 
     195{ 
     196    int i; 
     197 
     198    printf(">>>>\n"); 
     199 
     200    for (i=0; i<pjsua.acc_cnt; ++i) 
     201        print_acc_status(i); 
     202 
    127203    print_buddy_list(); 
    128204     
     
    135211    puts("|  h  Hangup call              |  u  Unsubscribe presence | ru  Unregister    |"); 
    136212    puts("|  ]  Select next dialog       |  t  ToGgle Online status |  d  Dump status   |"); 
    137     puts("|  [  Select previous dialog   |                          |                   |"); 
     213    puts("|  [  Select previous dialog   |                          | dc  Dump config   |"); 
    138214    puts("|                              +--------------------------+-------------------+"); 
    139215    puts("|  H  Hold call                |     Conference Command   |                   |"); 
     
    263339{ 
    264340    unsigned i, count; 
    265     pjmedia_conf_port_info info[16]; 
     341    pjmedia_conf_port_info info[PJSUA_MAX_CALLS]; 
    266342 
    267343    printf("Conference ports:\n"); 
     
    270346    pjmedia_conf_get_ports_info(pjsua.mconf, &count, info); 
    271347    for (i=0; i<count; ++i) { 
    272         char txlist[80]; 
    273         unsigned j; 
     348        char txlist[PJSUA_MAX_CALLS*4+10]; 
     349        int j; 
    274350        pjmedia_conf_port_info *port_info = &info[i];    
    275351         
    276352        txlist[0] = '\0'; 
    277         for (j=0; j<pjsua.max_ports; ++j) { 
     353        for (j=0; j<pjsua.max_calls+PJSUA_CONF_MORE_PORTS; ++j) { 
    278354            char s[10]; 
    279355            if (port_info->listener[j]) { 
     
    310386        case 'm': 
    311387            /* Make call! : */ 
    312             if (pj_list_size(&pjsua.inv_list)) 
    313                 printf("(You have %d calls)\n", pj_list_size(&pjsua.inv_list)); 
     388            printf("(You currently have %d calls)\n", pjsua.call_cnt); 
    314389             
    315390            ui_input_url("Make call", buf, sizeof(buf), &result); 
     
    318393                    puts("You can't do that with make call!"); 
    319394                else 
    320                     pjsua_invite(pjsua.buddies[result.nb_result].uri.ptr, NULL); 
     395                    pjsua_make_call( current_acc,  
     396                                     pjsua.buddies[result.nb_result].uri.ptr,  
     397                                     NULL); 
    321398            } else if (result.uri_result) 
    322                 pjsua_invite(result.uri_result, NULL); 
     399                pjsua_make_call( current_acc, result.uri_result, NULL); 
    323400             
    324401            break; 
     
    327404        case 'a': 
    328405 
    329             if (inv_session == &pjsua.inv_list ||  
    330                 inv_session->inv->role != PJSIP_ROLE_UAS || 
    331                 inv_session->inv->state >= PJSIP_INV_STATE_CONNECTING)  
     406            if (current_call == -1 ||  
     407                pjsua.calls[current_call].inv->role != PJSIP_ROLE_UAS || 
     408                pjsua.calls[current_call].inv->state >= PJSIP_INV_STATE_CONNECTING) 
    332409            { 
    333410                puts("No pending incoming call"); 
     
    350427                 * keyboard input. 
    351428                 */ 
    352                 if (inv_session == &pjsua.inv_list) { 
     429                if (current_call == -1) { 
    353430                    puts("Call has been disconnected"); 
    354431                    fflush(stdout); 
     
    356433                } 
    357434 
    358                 status = pjsip_inv_answer(inv_session->inv, atoi(buf),  
     435                status = pjsip_inv_answer(pjsua.calls[current_call].inv,  
     436                                          atoi(buf),  
    359437                                          NULL, NULL, &tdata); 
    360438                if (status == PJ_SUCCESS) 
    361                     status = pjsip_inv_send_msg(inv_session->inv, tdata, NULL); 
     439                    status = pjsip_inv_send_msg(pjsua.calls[current_call].inv, 
     440                                                tdata, NULL); 
    362441 
    363442                if (status != PJ_SUCCESS) 
     
    371450        case 'h': 
    372451 
    373             if (inv_session == &pjsua.inv_list) { 
     452            if (current_call == -1) { 
    374453                puts("No current call"); 
    375454                fflush(stdout); 
     
    377456 
    378457            } else { 
    379                 pjsua_inv_hangup(inv_session, PJSIP_SC_DECLINE); 
     458                pjsua_call_hangup(current_call, PJSIP_SC_DECLINE); 
    380459            } 
    381460            break; 
     
    387466             */ 
    388467            if (menuin[0] == ']') { 
    389                 inv_session = inv_session->next; 
    390                 if (inv_session == &pjsua.inv_list) 
    391                     inv_session = pjsua.inv_list.next; 
     468                find_next_call(); 
    392469 
    393470            } else { 
    394                 inv_session = inv_session->prev; 
    395                 if (inv_session == &pjsua.inv_list) 
    396                     inv_session = pjsua.inv_list.prev; 
    397             } 
    398  
    399             if (inv_session != &pjsua.inv_list) { 
     471                find_prev_call(); 
     472            } 
     473 
     474            if (current_call != -1) { 
    400475                char url[PJSIP_MAX_URL_SIZE]; 
    401476                int len; 
    402  
    403                 len = pjsip_uri_print(0, inv_session->inv->dlg->remote.info->uri, 
    404                                       url, sizeof(url)-1); 
     477                const pjsip_uri *u; 
     478 
     479                u = pjsua.calls[current_call].inv->dlg->remote.info->uri; 
     480                len = pjsip_uri_print(0, u, url, sizeof(url)-1); 
    405481                if (len < 1) { 
    406482                    pj_ansi_strcpy(url, "<uri is too long>"); 
     
    420496             * Hold call. 
    421497             */ 
    422             if (inv_session != &pjsua.inv_list) { 
     498            if (current_call != -1) { 
    423499                 
    424                 pjsua_inv_set_hold(inv_session); 
     500                pjsua_call_set_hold(current_call); 
    425501 
    426502            } else { 
     
    433509             * Send re-INVITE (to release hold, etc). 
    434510             */ 
    435             if (inv_session != &pjsua.inv_list) { 
     511            if (current_call != -1) { 
    436512                 
    437                 pjsua_inv_reinvite(inv_session); 
     513                pjsua_call_reinvite(current_call); 
    438514 
    439515            } else { 
     
    446522             * Transfer call. 
    447523             */ 
    448             if (inv_session == &pjsua.inv_list) { 
     524            if (current_call == -1) { 
    449525                 
    450526                PJ_LOG(3,(THIS_FILE, "No current call")); 
    451527 
    452528            } else { 
    453                 struct pjsua_inv_data *cur = inv_session; 
     529                int call = current_call; 
    454530 
    455531                ui_input_url("Transfer to URL", buf, sizeof(buf), &result); 
     
    457533                /* Check if call is still there. */ 
    458534 
    459                 if (cur != inv_session) { 
     535                if (call != current_call) { 
    460536                    puts("Call has been disconnected"); 
    461537                    continue; 
     
    466542                        puts("You can't do that with transfer call!"); 
    467543                    else 
    468                         pjsua_inv_xfer_call( inv_session, 
    469                                              pjsua.buddies[result.nb_result].uri.ptr); 
     544                        pjsua_call_xfer( current_call, 
     545                                         pjsua.buddies[result.nb_result].uri.ptr); 
    470546 
    471547                } else if (result.uri_result) { 
    472                     pjsua_inv_xfer_call( inv_session, result.uri_result); 
     548                    pjsua_call_xfer( current_call, result.uri_result); 
    473549                } 
    474550            } 
     
    479555             * Send DTMF strings. 
    480556             */ 
    481             if (inv_session == &pjsua.inv_list) { 
     557            if (current_call == -1) { 
    482558                 
    483559                PJ_LOG(3,(THIS_FILE, "No current call")); 
    484560 
    485             } else if (inv_session->session == NULL) { 
     561            } else if (pjsua.calls[current_call].session == NULL) { 
    486562 
    487563                PJ_LOG(3,(THIS_FILE, "Media is not established yet!")); 
     
    489565            } else { 
    490566                pj_str_t digits; 
    491                 struct pjsua_inv_data *cur = inv_session; 
     567                int call = current_call; 
    492568                pj_status_t status; 
    493569 
     
    498574                } 
    499575 
    500                 if (cur != inv_session) { 
     576                if (call != current_call) { 
    501577                    puts("Call has been disconnected"); 
    502578                    continue; 
     
    504580 
    505581                digits = pj_str(buf); 
    506                 status = pjmedia_session_dial_dtmf(inv_session->session, 0,  
     582                status = pjmedia_session_dial_dtmf(pjsua.calls[current_call].session, 0,  
    507583                                                   &digits); 
    508584                if (status != PJ_SUCCESS) { 
     
    522598            if (result.nb_result != NO_NB) { 
    523599                if (result.nb_result == -1) { 
    524                     unsigned i; 
     600                    int i; 
    525601                    for (i=0; i<pjsua.buddy_cnt; ++i) 
    526602                        pjsua.buddies[i].monitor = (menuin[0]=='s'); 
     
    529605                } 
    530606 
    531                 pjsua_pres_refresh(); 
     607                pjsua_pres_refresh(current_acc); 
    532608 
    533609            } else if (result.uri_result) { 
     
    544620                 * Re-Register. 
    545621                 */ 
    546                 pjsua_regc_update(PJ_TRUE); 
     622                pjsua_regc_update(current_acc, PJ_TRUE); 
    547623                break; 
    548624            case 'u': 
     
    550626                 * Unregister 
    551627                 */ 
    552                 pjsua_regc_update(PJ_FALSE); 
     628                pjsua_regc_update(current_acc, PJ_FALSE); 
    553629                break; 
    554630            } 
     
    556632             
    557633        case 't': 
    558             pjsua.online_status = !pjsua.online_status; 
    559             pjsua_pres_refresh(); 
     634            pjsua.acc[current_acc].online_status =  
     635                !pjsua.acc[current_acc].online_status; 
     636            pjsua_pres_refresh(current_acc); 
    560637            break; 
    561638 
     
    607684 
    608685        case 'd': 
    609             pjsua_dump(); 
     686            if (menuin[1] == 'c') { 
     687                char settings[2000]; 
     688                int len; 
     689 
     690                len = pjsua_dump_settings(settings, sizeof(settings)); 
     691                if (len < 1) 
     692                    PJ_LOG(3,(THIS_FILE, "Error: not enough buffer")); 
     693                else 
     694                    PJ_LOG(3,(THIS_FILE,  
     695                              "Dumping configuration (%d bytes):\n%s\n", 
     696                              len, settings)); 
     697            } else { 
     698                pjsua_dump(); 
     699            } 
    610700            break; 
    611701 
     
    766856 
    767857    /* Init default settings. */ 
    768  
    769858    pjsua_default(); 
    770859 
     
    772861    /* Initialize pjsua (to create pool etc). 
    773862     */ 
    774  
    775863    if (pjsua_init() != PJ_SUCCESS) 
    776864        return 1; 
     
    778866 
    779867    /* Parse command line arguments: */ 
    780  
    781868    if (pjsua_parse_args(argc, argv) != PJ_SUCCESS) 
    782869        return 1; 
     
    784871 
    785872    /* Init logging: */ 
    786  
    787873    app_logging_init(); 
    788874 
     
    791877     * messages. 
    792878     */ 
    793  
    794879    pjsip_endpt_register_module(pjsua.endpt, &console_msg_logger); 
    795880 
    796881 
    797882    /* Start pjsua! */ 
    798  
    799883    if (pjsua_start() != PJ_SUCCESS) { 
    800884 
     
    805889 
    806890    /* Sleep for a while, let any messages get printed to console: */ 
    807  
    808891    pj_thread_sleep(500); 
    809892 
    810893 
    811     /* No current call initially: */ 
    812  
    813     inv_session = &pjsua.inv_list; 
    814  
    815  
    816894    /* Start UI console main loop: */ 
    817  
    818895    ui_console_main(); 
    819896 
    820897 
    821898    /* Destroy pjsua: */ 
    822  
    823899    pjsua_destroy(); 
    824900 
    825901 
    826902    /* Close logging: */ 
    827  
    828903    app_logging_shutdown(); 
    829904 
Note: See TracChangeset for help on using the changeset viewer.