Ignore:
Timestamp:
Sep 15, 2017 5:32:08 AM (7 years ago)
Author:
riza
Message:

Re #2041: Implement API to handle IP address change.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • pjproject/trunk/pjsip/src/pjsua-lib/pjsua_acc.c

    r5636 r5649  
    402402        acc->tp_type = pjsua_var.tpdata[acc_cfg->transport_id].type; 
    403403 
     404    acc->ip_change_op = PJSUA_IP_CHANGE_OP_NULL; 
     405 
    404406    return PJ_SUCCESS; 
    405407} 
     
    688690    acc->via_tp = NULL; 
    689691    acc->next_rtp_port = 0; 
     692    acc->ip_change_op = PJSUA_IP_CHANGE_OP_NULL;     
    690693 
    691694    /* Remove from array */ 
     
    14171420        } 
    14181421    } 
     1422 
     1423    /* IP Change config */ 
     1424    acc->cfg.ip_change_cfg.shutdown_tp = cfg->ip_change_cfg.shutdown_tp; 
     1425    acc->cfg.ip_change_cfg.hangup_calls = cfg->ip_change_cfg.hangup_calls;     
     1426    acc->cfg.ip_change_cfg.reinvite_flags = cfg->ip_change_cfg.reinvite_flags; 
    14191427 
    14201428on_return: 
     
    22002208 
    22012209/* 
     2210 * Timer callback to handle call on IP change process. 
     2211 */ 
     2212static void handle_call_on_ip_change_cb(void *user_data) 
     2213{ 
     2214    pjsua_acc *acc = (pjsua_acc*)user_data; 
     2215    pjsua_acc_handle_call_on_ip_change(acc); 
     2216} 
     2217 
     2218/* 
    22022219 * This callback is called by pjsip_regc when outgoing register 
    22032220 * request has completed. 
     
    22662283            PJ_LOG(3,(THIS_FILE, "%s: unregistration success", 
    22672284                      pjsua_var.acc[acc->index].cfg.id.ptr)); 
    2268         } else { 
     2285 
     2286        } else {             
    22692287            /* Check and update SIP outbound status first, since the result 
    22702288             * will determine if we should update re-registration 
     
    23062324            if (acc->cfg.mwi_enabled) 
    23072325                pjsua_start_mwi(acc->index, PJ_FALSE); 
    2308         } 
    2309  
     2326 
     2327        } 
    23102328    } else { 
    23112329        PJ_LOG(4, (THIS_FILE, "SIP registration updated status=%d", param->code)); 
     
    23492367        reg_info.renew = !param->is_unreg; 
    23502368        (*pjsua_var.ua_cfg.cb.on_reg_state2)(acc->index, &reg_info); 
     2369    } 
     2370 
     2371    if (acc->ip_change_op == PJSUA_IP_CHANGE_OP_ACC_UPDATE_CONTACT) { 
     2372        if (pjsua_var.ua_cfg.cb.on_ip_change_progress) { 
     2373            pjsua_ip_change_op_info ip_chg_info; 
     2374            pjsip_regc_info rinfo; 
     2375 
     2376            pj_bzero(&ip_chg_info, sizeof(ip_chg_info)); 
     2377            pjsip_regc_get_info(param->regc, &rinfo);        
     2378            ip_chg_info.acc_update_contact.acc_id = acc->index; 
     2379            ip_chg_info.acc_update_contact.code = param->code; 
     2380            ip_chg_info.acc_update_contact.is_register = !param->is_unreg; 
     2381            (*pjsua_var.ua_cfg.cb.on_ip_change_progress)(acc->ip_change_op,  
     2382                                                         param->status,  
     2383                                                         &ip_chg_info); 
     2384        } 
     2385 
     2386        if (PJSIP_IS_STATUS_IN_CLASS(param->code, 200)) { 
     2387            if (param->expiration < 1) { 
     2388                pj_status_t status; 
     2389                /* Send re-register. */ 
     2390                PJ_LOG(3, (THIS_FILE, "%.*s: send registration triggered by IP" 
     2391                           " change", pjsua_var.acc[acc->index].cfg.id.slen, 
     2392                           pjsua_var.acc[acc->index].cfg.id.ptr)); 
     2393 
     2394                status = pjsua_acc_set_registration(acc->index, PJ_TRUE); 
     2395                if ((status != PJ_SUCCESS) &&  
     2396                    pjsua_var.ua_cfg.cb.on_ip_change_progress)  
     2397                { 
     2398                    pjsua_ip_change_op_info ip_chg_info; 
     2399 
     2400                    pj_bzero(&ip_chg_info, sizeof(ip_chg_info)); 
     2401                    ip_chg_info.acc_update_contact.acc_id = acc->index; 
     2402                    ip_chg_info.acc_update_contact.is_register = PJ_TRUE; 
     2403                    (*pjsua_var.ua_cfg.cb.on_ip_change_progress)( 
     2404                                                            acc->ip_change_op,  
     2405                                                            status,  
     2406                                                            &ip_chg_info); 
     2407                } 
     2408            } else { 
     2409                /* Avoid deadlock issue when sending BYE or Re-INVITE.  */ 
     2410                pjsua_schedule_timer2(&handle_call_on_ip_change_cb,  
     2411                                      (void*)acc, 0); 
     2412            } 
     2413        }  
    23512414    } 
    23522415     
     
    26762739        //pjsip_regc_get_info(pjsua_var.acc[acc_id].regc, &reg_info); 
    26772740        //pjsua_var.acc[acc_id].auto_rereg.reg_tp = reg_info.transport; 
    2678          
     2741 
    26792742        if (pjsua_var.ua_cfg.cb.on_reg_started) { 
    26802743            (*pjsua_var.ua_cfg.cb.on_reg_started)(acc_id, renew); 
     
    37703833            pjsip_regc_release_transport(pjsua_var.acc[i].regc); 
    37713834 
    3772             /* Schedule reregistration for this account */ 
    3773             if (acc->cfg.reg_retry_interval) { 
     3835            if (pjsua_var.acc[i].ip_change_op ==  
     3836                                            PJSUA_IP_CHANGE_OP_ACC_SHUTDOWN_TP) 
     3837            { 
     3838                if (acc->cfg.allow_contact_rewrite) { 
     3839                    pjsua_acc_update_contact_on_ip_change(acc); 
     3840                } else { 
     3841                    pjsua_acc_handle_call_on_ip_change(acc); 
     3842                } 
     3843            } else if (acc->cfg.reg_retry_interval) { 
     3844                /* Schedule reregistration for this account */ 
    37743845                schedule_reregistration(acc); 
    37753846            } 
     
    37803851    pj_log_pop_indent(); 
    37813852} 
     3853 
     3854 
     3855/* 
     3856 * Internal function to update contact on ip change process. 
     3857 */ 
     3858pj_status_t pjsua_acc_update_contact_on_ip_change(pjsua_acc *acc) 
     3859{ 
     3860    pj_status_t status; 
     3861    pj_bool_t need_unreg = ((acc->cfg.contact_rewrite_method & 
     3862                             PJSUA_CONTACT_REWRITE_UNREGISTER) != 0); 
     3863 
     3864    acc->ip_change_op = PJSUA_IP_CHANGE_OP_ACC_UPDATE_CONTACT; 
     3865 
     3866    PJ_LOG(3, (THIS_FILE, "%.*s: send %sregistration triggered " 
     3867               "by IP change", acc->cfg.id.slen, 
     3868               acc->cfg.id.ptr, (need_unreg ? "un-" : ""))); 
     3869 
     3870    status = pjsua_acc_set_registration(acc->index, !need_unreg); 
     3871 
     3872    if ((status != PJ_SUCCESS) && (pjsua_var.ua_cfg.cb.on_ip_change_progress))  
     3873    { 
     3874        pjsua_ip_change_op_info info; 
     3875         
     3876        pj_bzero(&info, sizeof(info)); 
     3877        info.acc_update_contact.acc_id = acc->index; 
     3878        info.acc_update_contact.is_register = !need_unreg;       
     3879 
     3880        pjsua_var.ua_cfg.cb.on_ip_change_progress(acc->ip_change_op, 
     3881                                                  status, 
     3882                                                  &info); 
     3883    } 
     3884    return status; 
     3885} 
     3886 
     3887 
     3888/* 
     3889 * Internal function to handle call on ip change process. 
     3890 */ 
     3891pj_status_t pjsua_acc_handle_call_on_ip_change(pjsua_acc *acc) 
     3892{ 
     3893    pj_status_t status = PJ_SUCCESS; 
     3894    unsigned i = 0; 
     3895 
     3896    if (acc->cfg.ip_change_cfg.hangup_calls ||  
     3897        acc->cfg.ip_change_cfg.reinvite_flags) 
     3898    { 
     3899        for (i = 0; i < (int)pjsua_var.ua_cfg.max_calls; ++i) { 
     3900            pjsua_call_info call_info; 
     3901            pjsua_call_get_info(i, &call_info); 
     3902 
     3903            if (pjsua_var.calls[i].acc_id != acc->index) 
     3904            { 
     3905                continue; 
     3906            } 
     3907 
     3908            if (acc->cfg.ip_change_cfg.hangup_calls) { 
     3909                acc->ip_change_op = PJSUA_IP_CHANGE_OP_ACC_HANGUP_CALLS; 
     3910                PJ_LOG(3, (THIS_FILE, "call to %.*s: hangup " 
     3911                           "triggered by IP change", 
     3912                           call_info.remote_info.slen, 
     3913                           call_info.remote_info.ptr)); 
     3914 
     3915                status = pjsua_call_hangup(i, PJSIP_SC_GONE, NULL, NULL); 
     3916 
     3917                if (pjsua_var.ua_cfg.cb.on_ip_change_progress) { 
     3918                    pjsua_ip_change_op_info info; 
     3919 
     3920                    pj_bzero(&info, sizeof(info)); 
     3921                    info.acc_hangup_calls.acc_id = acc->index; 
     3922                    info.acc_hangup_calls.call_id = call_info.id; 
     3923 
     3924                    pjsua_var.ua_cfg.cb.on_ip_change_progress( 
     3925                                                             acc->ip_change_op, 
     3926                                                             status, 
     3927                                                             &info); 
     3928                } 
     3929            } else if ((acc->cfg.ip_change_cfg.reinvite_flags) && 
     3930                (call_info.state == PJSIP_INV_STATE_CONFIRMED)) 
     3931            { 
     3932                acc->ip_change_op = PJSUA_IP_CHANGE_OP_ACC_REINVITE_CALLS; 
     3933 
     3934                call_info.setting.flag |= 
     3935                                         acc->cfg.ip_change_cfg.reinvite_flags; 
     3936 
     3937                PJ_LOG(3, (THIS_FILE, "call to %.*s: send " 
     3938                           "re-INVITE with flags 0x%x triggered " 
     3939                           "by IP change", 
     3940                           call_info.remote_info.slen, 
     3941                           call_info.remote_info.ptr, 
     3942                           acc->cfg.ip_change_cfg.reinvite_flags)); 
     3943 
     3944                status = pjsua_call_reinvite(i, call_info.setting.flag, NULL); 
     3945 
     3946                if (pjsua_var.ua_cfg.cb.on_ip_change_progress) { 
     3947                    pjsua_ip_change_op_info info; 
     3948 
     3949                    pj_bzero(&info, sizeof(info)); 
     3950                    info.acc_reinvite_calls.acc_id = acc->index; 
     3951                    info.acc_reinvite_calls.call_id = call_info.id; 
     3952 
     3953                    pjsua_var.ua_cfg.cb.on_ip_change_progress( 
     3954                                                             acc->ip_change_op, 
     3955                                                             status, 
     3956                                                             &info); 
     3957                } 
     3958 
     3959            } 
     3960        } 
     3961    }     
     3962    acc->ip_change_op = PJSUA_IP_CHANGE_OP_NULL; 
     3963    return status; 
     3964} 
Note: See TracChangeset for help on using the changeset viewer.