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/pjsua_core.c

    r230 r236  
    4646void pjsua_default(void) 
    4747{ 
     48    unsigned i; 
     49 
    4850 
    4951    /* Normally need another thread for console application, because main  
     
    5456 
    5557    /* Default transport settings: */ 
    56  
    5758    pjsua.sip_port = 5060; 
    5859 
    5960 
    6061    /* Default logging settings: */ 
    61  
    6262    pjsua.log_level = 5; 
    6363    pjsua.app_log_level = 4; 
     
    6565                      PJ_LOG_HAS_MICRO_SEC | PJ_LOG_HAS_NEWLINE; 
    6666 
     67 
    6768    /* Default: do not use STUN: */ 
    68  
    6969    pjsua.stun_port1 = pjsua.stun_port2 = 0; 
    7070 
    71     /* Default URIs: */ 
    72  
    73     pjsua.local_uri = pj_str(PJSUA_LOCAL_URI); 
    74  
    75     /* Default registration timeout: */ 
    76  
    77     pjsua.reg_timeout = 55; 
    78  
    79     /* Default maximum conference ports: */ 
    80  
    81     pjsua.max_ports = 8; 
    82  
    83     /* Init route set list: */ 
    84  
    85     pj_list_init(&pjsua.route_set); 
    86  
    87     /* Init invite session list: */ 
    88  
    89     pj_list_init(&pjsua.inv_list); 
     71    /* Init accounts: */ 
     72    pjsua.acc_cnt = 1; 
     73    for (i=0; i<PJ_ARRAY_SIZE(pjsua.acc); ++i) { 
     74        pjsua.acc[i].index = i; 
     75        pjsua.acc[i].local_uri = pj_str(PJSUA_LOCAL_URI); 
     76        pjsua.acc[i].reg_timeout = 55; 
     77        pj_list_init(&pjsua.acc[i].route_set); 
     78        pj_list_init(&pjsua.acc[i].pres_srv_list); 
     79    } 
     80 
     81    /* Init call array: */ 
     82    for (i=0; i<PJ_ARRAY_SIZE(pjsua.calls); ++i) 
     83        pjsua.calls[i].index = i; 
     84 
     85    /* Default max nb of calls. */ 
     86    pjsua.max_calls = 4; 
    9087 
    9188    /* Init server presence subscription list: */ 
    9289     
    93     pj_list_init(&pjsua.pres_srv_list); 
    9490 
    9591} 
     
    111107    if (rdata->msg_info.msg->line.req.method.id == PJSIP_INVITE_METHOD) { 
    112108 
    113         return pjsua_inv_on_incoming(rdata); 
    114  
     109        return pjsua_call_on_incoming(rdata); 
    115110    } 
    116111 
     
    146141        RTP_START_PORT = 4000, 
    147142        RTP_RANDOM_START = 2, 
    148         RTP_RETRY = 20  
     143        RTP_RETRY = 100 
    149144    }; 
    150145    enum { 
     
    241236                pj_memcpy(&mapped_addr[i], &addr, sizeof(addr)); 
    242237 
    243             if (sip) 
    244                 mapped_addr[SIP_SOCK].sin_port = pj_htons((pj_uint16_t)pjsua.sip_port); 
    245             mapped_addr[RTP_SOCK].sin_port = pj_htons((pj_uint16_t)rtp_port); 
    246             mapped_addr[RTCP_SOCK].sin_port = pj_htons((pj_uint16_t)(rtp_port+1)); 
     238            if (sip) { 
     239                mapped_addr[SIP_SOCK].sin_port =  
     240                    pj_htons((pj_uint16_t)pjsua.sip_port); 
     241            } 
     242            mapped_addr[RTP_SOCK].sin_port=pj_htons((pj_uint16_t)rtp_port); 
     243            mapped_addr[RTCP_SOCK].sin_port=pj_htons((pj_uint16_t)(rtp_port+1)); 
    247244            break; 
     245 
    248246        } else { 
    249             status = pj_stun_get_mapped_addr( &pjsua.cp.factory, 3, sock, 
    250                                               &pjsua.stun_srv1, pjsua.stun_port1, 
    251                                               &pjsua.stun_srv2, pjsua.stun_port2, 
    252                                               mapped_addr); 
     247            status=pj_stun_get_mapped_addr(&pjsua.cp.factory, 3, sock, 
     248                                           &pjsua.stun_srv1, pjsua.stun_port1, 
     249                                           &pjsua.stun_srv2, pjsua.stun_port2, 
     250                                           mapped_addr); 
    253251            if (status != PJ_SUCCESS) { 
    254252                pjsua_perror(THIS_FILE, "STUN error", status); 
     
    256254            } 
    257255 
    258             if (pj_ntohs(mapped_addr[2].sin_port) == pj_ntohs(mapped_addr[1].sin_port)+1) 
     256            if (pj_ntohs(mapped_addr[2].sin_port) ==  
     257                pj_ntohs(mapped_addr[1].sin_port)+1) 
     258            { 
    259259                break; 
    260  
    261             pj_sock_close(sock[RTP_SOCK]); sock[RTP_SOCK] = PJ_INVALID_SOCKET; 
    262             pj_sock_close(sock[RTCP_SOCK]); sock[RTCP_SOCK] = PJ_INVALID_SOCKET; 
     260            } 
     261 
     262            pj_sock_close(sock[RTP_SOCK]);  
     263            sock[RTP_SOCK] = PJ_INVALID_SOCKET; 
     264 
     265            pj_sock_close(sock[RTCP_SOCK]);  
     266            sock[RTCP_SOCK] = PJ_INVALID_SOCKET; 
    263267        } 
    264268    } 
    265269 
    266270    if (sock[RTP_SOCK] == PJ_INVALID_SOCKET) { 
    267         PJ_LOG(1,(THIS_FILE, "Unable to find appropriate RTP/RTCP ports combination")); 
     271        PJ_LOG(1,(THIS_FILE,  
     272                  "Unable to find appropriate RTP/RTCP ports combination")); 
    268273        goto on_error; 
    269274    } 
     
    271276    if (sip) { 
    272277        pjsua.sip_sock = sock[SIP_SOCK]; 
    273         pj_memcpy(&pjsua.sip_sock_name, &mapped_addr[SIP_SOCK], sizeof(pj_sockaddr_in)); 
     278        pj_memcpy(&pjsua.sip_sock_name,  
     279                  &mapped_addr[SIP_SOCK],  
     280                  sizeof(pj_sockaddr_in)); 
    274281    } else { 
    275282        pj_sock_close(sock[0]); 
     
    392399    /* Initialize invite session module: */ 
    393400 
    394     { 
    395          
    396         /* Initialize invite session callback. */ 
    397         pjsip_inv_callback inv_cb; 
    398  
    399         pj_memset(&inv_cb, 0, sizeof(inv_cb)); 
    400         inv_cb.on_state_changed = &pjsua_inv_on_state_changed; 
    401         inv_cb.on_new_session = &pjsua_inv_on_new_session; 
    402         inv_cb.on_media_update = &pjsua_inv_on_media_update; 
    403         inv_cb.on_rx_offer = &pjsua_inv_on_rx_offer; 
    404         inv_cb.on_tsx_state_changed = &pjsua_inv_on_tsx_state_changed; 
    405  
    406  
    407         /* Initialize invite session module: */ 
    408         status = pjsip_inv_usage_init(pjsua.endpt, &pjsua.mod, &inv_cb); 
    409         if (status != PJ_SUCCESS) { 
    410             pjsua_perror(THIS_FILE, "Invite usage initialization error",  
    411                          status); 
    412             goto on_error; 
    413         } 
    414  
    415     } 
    416  
     401    status = pjsua_call_init(); 
     402    if (status != PJ_SUCCESS) { 
     403        pjsua_perror(THIS_FILE, "Invite usage initialization error",  
     404                     status); 
     405        goto on_error; 
     406    } 
    417407 
    418408    /* Done */ 
     
    521511    /* Init conference bridge. */ 
    522512 
    523     status = pjmedia_conf_create(pjsua.pool, pjsua.max_ports,  
     513    status = pjmedia_conf_create(pjsua.pool,  
     514                                 pjsua.max_calls+PJSUA_CONF_MORE_PORTS,  
    524515                                 8000, 160, 16, &pjsua.mconf); 
    525516    if (status != PJ_SUCCESS) { 
     
    548539 
    549540 
     541/* 
     542 * Find account for incoming request. 
     543 */ 
     544int pjsua_find_account_for_incoming(pjsip_rx_data *rdata) 
     545{ 
     546    pjsip_uri *uri; 
     547    pjsip_sip_uri *sip_uri; 
     548    int acc_index; 
     549 
     550    uri = rdata->msg_info.to->uri; 
     551 
     552    /* Just return account #0 if To URI is not SIP: */ 
     553    if (!PJSIP_URI_SCHEME_IS_SIP(uri) &&  
     554        !PJSIP_URI_SCHEME_IS_SIPS(uri))  
     555    { 
     556        return 0; 
     557    } 
     558 
     559 
     560    sip_uri = (pjsip_sip_uri*)pjsip_uri_get_uri(uri); 
     561 
     562    /* Find account which has matching username and domain. */ 
     563    for (acc_index=0; acc_index < pjsua.acc_cnt; ++acc_index) { 
     564 
     565        pjsua_acc *acc = &pjsua.acc[acc_index]; 
     566 
     567        if (pj_stricmp(&acc->user_part, &sip_uri->user)==0 && 
     568            pj_stricmp(&acc->host_part, &sip_uri->host)==0)  
     569        { 
     570            /* Match ! */ 
     571            return acc_index; 
     572        } 
     573    } 
     574 
     575    /* No matching, try match domain part only. */ 
     576    for (acc_index=0; acc_index < pjsua.acc_cnt; ++acc_index) { 
     577 
     578        pjsua_acc *acc = &pjsua.acc[acc_index]; 
     579 
     580        if (pj_stricmp(&acc->host_part, &sip_uri->host)==0) { 
     581            /* Match ! */ 
     582            return acc_index; 
     583        } 
     584    } 
     585 
     586    /* Still no match, just return account #0 */ 
     587    return 0; 
     588} 
     589 
     590 
     591/* 
     592 * Find account for outgoing request. 
     593 */ 
     594int pjsua_find_account_for_outgoing(const pj_str_t *url) 
     595{ 
     596    PJ_UNUSED_ARG(url); 
     597 
     598    /* Just use account #0 */ 
     599    return 0; 
     600} 
     601 
    550602 
    551603/* 
     
    589641 
    590642    /* Init sockets (STUN etc): */ 
    591     for (i=0; i<PJ_ARRAY_SIZE(pjsua.med_sock_info); ++i) { 
    592         status = init_sockets(i==0, &pjsua.med_sock_info[i]); 
     643    for (i=0; i<(int)pjsua.max_calls; ++i) { 
     644        status = init_sockets(i==0, &pjsua.calls[i].skinfo); 
    593645        if (status != PJ_SUCCESS) { 
    594646            pjsua_perror(THIS_FILE, "init_sockets() has returned error",  
    595647                         status); 
     648            --i; 
     649            if (i >= 0) 
     650                pj_sock_close(pjsua.sip_sock); 
     651            while (i >= 0) { 
     652                pj_sock_close(pjsua.calls[i].skinfo.rtp_sock); 
     653                pj_sock_close(pjsua.calls[i].skinfo.rtcp_sock); 
     654            } 
    596655            return status; 
    597656        } 
     
    624683 
    625684    /* Initialize Contact URI, if one is not specified: */ 
    626  
    627     if (pjsua.contact_uri.slen == 0 && pjsua.local_uri.slen) { 
     685    for (i=0; i<pjsua.acc_cnt; ++i) { 
    628686 
    629687        pjsip_uri *uri; 
    630688        pjsip_sip_uri *sip_uri; 
    631         char contact[128]; 
    632         int len; 
    633  
    634         /* The local Contact is the username@ip-addr, where 
    635          *  - username is taken from the local URI, 
    636          *  - ip-addr in UDP transport's address name (which may have been 
    637          *    resolved from STUN. 
    638          */ 
    639          
     689 
    640690        /* Need to parse local_uri to get the elements: */ 
    641691 
    642         uri = pjsip_parse_uri(pjsua.pool, pjsua.local_uri.ptr,  
    643                               pjsua.local_uri.slen, 0); 
     692        uri = pjsip_parse_uri(pjsua.pool, pjsua.acc[i].local_uri.ptr, 
     693                              pjsua.acc[i].local_uri.slen, 0); 
    644694        if (uri == NULL) { 
    645695            pjsua_perror(THIS_FILE, "Invalid local URI",  
     
    648698        } 
    649699 
    650  
    651700        /* Local URI MUST be a SIP or SIPS: */ 
    652701 
    653         if (!PJSIP_URI_SCHEME_IS_SIP(uri) && !PJSIP_URI_SCHEME_IS_SIPS(uri)) { 
     702        if (!PJSIP_URI_SCHEME_IS_SIP(uri) &&  
     703            !PJSIP_URI_SCHEME_IS_SIPS(uri))  
     704        { 
    654705            pjsua_perror(THIS_FILE, "Invalid local URI",  
    655706                         PJSIP_EINVALIDSCHEME); 
     
    662713        sip_uri = (pjsip_sip_uri*) pjsip_uri_get_uri(uri); 
    663714 
    664          
    665         /* Build temporary contact string. */ 
    666  
    667         if (sip_uri->user.slen) { 
    668  
    669             /* With the user part. */ 
    670             len = pj_snprintf(contact, sizeof(contact), 
    671                               "<sip:%.*s@%.*s:%d>", 
    672                               (int)sip_uri->user.slen, 
    673                               sip_uri->user.ptr, 
    674                               (int)udp_transport->local_name.host.slen, 
    675                               udp_transport->local_name.host.ptr, 
    676                               udp_transport->local_name.port); 
    677         } else { 
    678  
    679             /* Without user part */ 
    680  
    681             len = pj_snprintf(contact, sizeof(contact), 
    682                               "<sip:%.*s:%d>", 
    683                               (int)udp_transport->local_name.host.slen, 
    684                               udp_transport->local_name.host.ptr, 
    685                               udp_transport->local_name.port); 
    686         } 
    687  
    688         if (len < 1 || len >= sizeof(contact)) { 
    689             pjsua_perror(THIS_FILE, "Invalid Contact", PJSIP_EURITOOLONG); 
    690             return PJSIP_EURITOOLONG; 
    691         } 
    692  
    693         /* Duplicate Contact uri. */ 
    694  
    695         pj_strdup2(pjsua.pool, &pjsua.contact_uri, contact); 
    696  
     715        pjsua.acc[i].user_part = sip_uri->user; 
     716        pjsua.acc[i].host_part = sip_uri->host; 
     717 
     718        if (pjsua.acc[i].contact_uri.slen == 0 &&  
     719            pjsua.acc[i].local_uri.slen)  
     720        { 
     721            char contact[128]; 
     722            int len; 
     723 
     724            /* The local Contact is the username@ip-addr, where 
     725             *  - username is taken from the local URI, 
     726             *  - ip-addr in UDP transport's address name (which may have been 
     727             *    resolved from STUN. 
     728             */ 
     729             
     730            /* Build temporary contact string. */ 
     731 
     732            if (sip_uri->user.slen) { 
     733 
     734                /* With the user part. */ 
     735                len = pj_snprintf(contact, sizeof(contact), 
     736                                  "<sip:%.*s@%.*s:%d>", 
     737                                  (int)sip_uri->user.slen, 
     738                                  sip_uri->user.ptr, 
     739                                  (int)udp_transport->local_name.host.slen, 
     740                                  udp_transport->local_name.host.ptr, 
     741                                  udp_transport->local_name.port); 
     742            } else { 
     743 
     744                /* Without user part */ 
     745 
     746                len = pj_snprintf(contact, sizeof(contact), 
     747                                  "<sip:%.*s:%d>", 
     748                                  (int)udp_transport->local_name.host.slen, 
     749                                  udp_transport->local_name.host.ptr, 
     750                                  udp_transport->local_name.port); 
     751            } 
     752 
     753            if (len < 1 || len >= sizeof(contact)) { 
     754                pjsua_perror(THIS_FILE, "Invalid Contact", PJSIP_EURITOOLONG); 
     755                return PJSIP_EURITOOLONG; 
     756            } 
     757 
     758            /* Duplicate Contact uri. */ 
     759 
     760            pj_strdup2(pjsua.pool, &pjsua.acc[i].contact_uri, contact); 
     761 
     762        } 
    697763    } 
    698764 
     
    715781        } 
    716782 
    717         pj_list_push_back(&pjsua.route_set, route); 
     783        for (i=0; i<pjsua.acc_cnt; ++i) { 
     784            pj_list_push_front(&pjsua.acc[i].route_set, route); 
     785        } 
    718786    } 
    719787 
     
    737805 
    738806    /* Create client registration session: */ 
    739  
    740     status = pjsua_regc_init(); 
    741     if (status != PJ_SUCCESS) 
    742         return status; 
    743  
    744     /* Perform registration, if required. */ 
    745     if (pjsua.regc) { 
    746         pjsua_regc_update(1); 
     807    for (i=0; i<pjsua.acc_cnt; ++i) { 
     808        status = pjsua_regc_init(i); 
     809        if (status != PJ_SUCCESS) 
     810            return status; 
     811 
     812        /* Perform registration, if required. */ 
     813        if (pjsua.acc[i].regc) { 
     814            pjsua_regc_update(i, 1); 
     815        } 
     816    } 
     817 
     818 
     819    /* Find account for outgoing preence subscription */ 
     820    for (i=0; i<pjsua.buddy_cnt; ++i) { 
     821        pjsua.buddies[i].acc_index =  
     822            pjsua_find_account_for_outgoing(&pjsua.buddies[i].uri); 
    747823    } 
    748824 
     
    777853    /* Signal threads to quit: */ 
    778854    pjsua.quit_flag = 1; 
     855 
     856    /* Terminate all calls. */ 
     857    pjsua_inv_shutdown(); 
     858 
     859    /* Terminate all presence subscriptions. */ 
     860    pjsua_pres_shutdown(); 
     861 
     862    /* Unregister, if required: */ 
     863    for (i=0; i<pjsua.acc_cnt; ++i) { 
     864        if (pjsua.acc[i].regc) { 
     865            pjsua_regc_update(i, 0); 
     866        } 
     867    } 
    779868 
    780869    /* Wait worker threads to quit: */ 
     
    789878 
    790879 
    791     /* Terminate all calls. */ 
    792     pjsua_inv_shutdown(); 
    793  
    794     /* Terminate all presence subscriptions. */ 
    795     pjsua_pres_shutdown(); 
    796  
    797     /* Unregister, if required: */ 
    798     if (pjsua.regc) { 
    799         pjsua_regc_update(0); 
    800     } 
    801  
    802880    /* Wait for some time to allow unregistration to complete: */ 
    803881    PJ_LOG(4,(THIS_FILE, "Shutting down...")); 
Note: See TracChangeset for help on using the changeset viewer.