From bddef2c767f6e17af43aa6efb13c5156ade851ac Mon Sep 17 00:00:00 2001 From: Benny Prijono Date: Wed, 31 Oct 2007 13:28:08 +0000 Subject: [PATCH] Ticket #407: keep-alive for UDP transports in PJSUA-LIB git-svn-id: https://svn.pjsip.org/repos/pjproject/trunk@1536 74dad513-b988-da41-8d7b-12977e46ad98 --- build.symbian/pjsua_libU.def | 235 ++++++++++++----------- pjsip/include/pjsua-lib/pjsua.h | 38 +++- pjsip/include/pjsua-lib/pjsua_internal.h | 6 +- pjsip/src/pjsip/sip_transport.c | 8 +- pjsip/src/pjsua-lib/pjsua_acc.c | 141 +++++++++++++- pjsip/src/pjsua-lib/pjsua_core.c | 2 + 6 files changed, 303 insertions(+), 127 deletions(-) diff --git a/build.symbian/pjsua_libU.def b/build.symbian/pjsua_libU.def index fd3a628aa..911efbc61 100644 --- a/build.symbian/pjsua_libU.def +++ b/build.symbian/pjsua_libU.def @@ -2,120 +2,121 @@ EXPORTS pjsua_acc_add @ 1 NONAME pjsua_acc_add_local @ 2 NONAME pjsua_acc_config_default @ 3 NONAME - pjsua_acc_create_request @ 4 NONAME - pjsua_acc_create_uac_contact @ 5 NONAME - pjsua_acc_create_uas_contact @ 6 NONAME - pjsua_acc_del @ 7 NONAME - pjsua_acc_enum_info @ 8 NONAME - pjsua_acc_find_for_incoming @ 9 NONAME - pjsua_acc_find_for_outgoing @ 10 NONAME - pjsua_acc_get_count @ 11 NONAME - pjsua_acc_get_default @ 12 NONAME - pjsua_acc_get_info @ 13 NONAME - pjsua_acc_is_valid @ 14 NONAME - pjsua_acc_modify @ 15 NONAME - pjsua_acc_set_default @ 16 NONAME - pjsua_acc_set_online_status @ 17 NONAME - pjsua_acc_set_online_status2 @ 18 NONAME - pjsua_acc_set_registration @ 19 NONAME - pjsua_acc_set_transport @ 20 NONAME - pjsua_buddy_add @ 21 NONAME - pjsua_buddy_config_default @ 22 NONAME - pjsua_buddy_del @ 23 NONAME - pjsua_buddy_get_info @ 24 NONAME - pjsua_buddy_is_valid @ 25 NONAME - pjsua_buddy_subscribe_pres @ 26 NONAME - pjsua_buddy_update_pres @ 27 NONAME - pjsua_call_answer @ 28 NONAME - pjsua_call_dial_dtmf @ 29 NONAME - pjsua_call_dump @ 30 NONAME - pjsua_call_get_conf_port @ 31 NONAME - pjsua_call_get_count @ 32 NONAME - pjsua_call_get_info @ 33 NONAME - pjsua_call_get_max_count @ 34 NONAME - pjsua_call_get_rem_nat_type @ 35 NONAME - pjsua_call_get_user_data @ 36 NONAME - pjsua_call_hangup @ 37 NONAME - pjsua_call_hangup_all @ 38 NONAME - pjsua_call_has_media @ 39 NONAME - pjsua_call_is_active @ 40 NONAME - pjsua_call_make_call @ 41 NONAME - pjsua_call_reinvite @ 42 NONAME - pjsua_call_send_im @ 43 NONAME - pjsua_call_send_request @ 44 NONAME - pjsua_call_send_typing_ind @ 45 NONAME - pjsua_call_set_hold @ 46 NONAME - pjsua_call_set_user_data @ 47 NONAME - pjsua_call_update @ 48 NONAME - pjsua_call_xfer @ 49 NONAME - pjsua_call_xfer_replaces @ 50 NONAME - pjsua_codec_get_param @ 51 NONAME - pjsua_codec_set_param @ 52 NONAME - pjsua_codec_set_priority @ 53 NONAME - pjsua_conf_add_port @ 54 NONAME - pjsua_conf_adjust_rx_level @ 55 NONAME - pjsua_conf_adjust_tx_level @ 56 NONAME - pjsua_conf_connect @ 57 NONAME - pjsua_conf_disconnect @ 58 NONAME - pjsua_conf_get_active_ports @ 59 NONAME - pjsua_conf_get_max_ports @ 60 NONAME - pjsua_conf_get_port_info @ 61 NONAME - pjsua_conf_get_signal_level @ 62 NONAME - pjsua_conf_remove_port @ 63 NONAME - pjsua_config_default @ 64 NONAME - pjsua_config_dup @ 65 NONAME - pjsua_create @ 66 NONAME - pjsua_destroy @ 67 NONAME - pjsua_detect_nat_type @ 68 NONAME - pjsua_dump @ 69 NONAME - pjsua_enum_accs @ 70 NONAME - pjsua_enum_buddies @ 71 NONAME - pjsua_enum_calls @ 72 NONAME - pjsua_enum_codecs @ 73 NONAME - pjsua_enum_conf_ports @ 74 NONAME - pjsua_enum_snd_devs @ 75 NONAME - pjsua_enum_transports @ 76 NONAME - pjsua_get_buddy_count @ 77 NONAME - pjsua_get_ec_tail @ 78 NONAME - pjsua_get_nat_type @ 79 NONAME - pjsua_get_pjmedia_endpt @ 80 NONAME - pjsua_get_pjsip_endpt @ 81 NONAME - pjsua_get_pool_factory @ 82 NONAME - pjsua_get_snd_dev @ 83 NONAME - pjsua_get_var @ 84 NONAME - pjsua_handle_events @ 85 NONAME - pjsua_im_send @ 86 NONAME - pjsua_im_typing @ 87 NONAME - pjsua_init @ 88 NONAME - pjsua_logging_config_default @ 89 NONAME - pjsua_logging_config_dup @ 90 NONAME - pjsua_media_config_default @ 91 NONAME - pjsua_media_transports_create @ 92 NONAME - pjsua_msg_data_init @ 93 NONAME - pjsua_perror @ 94 NONAME - pjsua_player_create @ 95 NONAME - pjsua_player_destroy @ 96 NONAME - pjsua_player_get_conf_port @ 97 NONAME - pjsua_player_get_port @ 98 NONAME - pjsua_player_set_pos @ 99 NONAME - pjsua_playlist_create @ 100 NONAME - pjsua_pool_create @ 101 NONAME - pjsua_pres_dump @ 102 NONAME - pjsua_reconfigure_logging @ 103 NONAME - pjsua_recorder_create @ 104 NONAME - pjsua_recorder_destroy @ 105 NONAME - pjsua_recorder_get_conf_port @ 106 NONAME - pjsua_recorder_get_port @ 107 NONAME - pjsua_set_ec @ 108 NONAME - pjsua_set_no_snd_dev @ 109 NONAME - pjsua_set_null_snd_dev @ 110 NONAME - pjsua_set_snd_dev @ 111 NONAME - pjsua_start @ 112 NONAME - pjsua_transport_close @ 113 NONAME - pjsua_transport_config_default @ 114 NONAME - pjsua_transport_config_dup @ 115 NONAME - pjsua_transport_create @ 116 NONAME - pjsua_transport_get_info @ 117 NONAME - pjsua_transport_register @ 118 NONAME - pjsua_transport_set_enable @ 119 NONAME - pjsua_verify_sip_url @ 120 NONAME + pjsua_acc_config_dup @ 4 NONAME + pjsua_acc_create_request @ 5 NONAME + pjsua_acc_create_uac_contact @ 6 NONAME + pjsua_acc_create_uas_contact @ 7 NONAME + pjsua_acc_del @ 8 NONAME + pjsua_acc_enum_info @ 9 NONAME + pjsua_acc_find_for_incoming @ 10 NONAME + pjsua_acc_find_for_outgoing @ 11 NONAME + pjsua_acc_get_count @ 12 NONAME + pjsua_acc_get_default @ 13 NONAME + pjsua_acc_get_info @ 14 NONAME + pjsua_acc_is_valid @ 15 NONAME + pjsua_acc_modify @ 16 NONAME + pjsua_acc_set_default @ 17 NONAME + pjsua_acc_set_online_status @ 18 NONAME + pjsua_acc_set_online_status2 @ 19 NONAME + pjsua_acc_set_registration @ 20 NONAME + pjsua_acc_set_transport @ 21 NONAME + pjsua_buddy_add @ 22 NONAME + pjsua_buddy_config_default @ 23 NONAME + pjsua_buddy_del @ 24 NONAME + pjsua_buddy_get_info @ 25 NONAME + pjsua_buddy_is_valid @ 26 NONAME + pjsua_buddy_subscribe_pres @ 27 NONAME + pjsua_buddy_update_pres @ 28 NONAME + pjsua_call_answer @ 29 NONAME + pjsua_call_dial_dtmf @ 30 NONAME + pjsua_call_dump @ 31 NONAME + pjsua_call_get_conf_port @ 32 NONAME + pjsua_call_get_count @ 33 NONAME + pjsua_call_get_info @ 34 NONAME + pjsua_call_get_max_count @ 35 NONAME + pjsua_call_get_rem_nat_type @ 36 NONAME + pjsua_call_get_user_data @ 37 NONAME + pjsua_call_hangup @ 38 NONAME + pjsua_call_hangup_all @ 39 NONAME + pjsua_call_has_media @ 40 NONAME + pjsua_call_is_active @ 41 NONAME + pjsua_call_make_call @ 42 NONAME + pjsua_call_reinvite @ 43 NONAME + pjsua_call_send_im @ 44 NONAME + pjsua_call_send_request @ 45 NONAME + pjsua_call_send_typing_ind @ 46 NONAME + pjsua_call_set_hold @ 47 NONAME + pjsua_call_set_user_data @ 48 NONAME + pjsua_call_update @ 49 NONAME + pjsua_call_xfer @ 50 NONAME + pjsua_call_xfer_replaces @ 51 NONAME + pjsua_codec_get_param @ 52 NONAME + pjsua_codec_set_param @ 53 NONAME + pjsua_codec_set_priority @ 54 NONAME + pjsua_conf_add_port @ 55 NONAME + pjsua_conf_adjust_rx_level @ 56 NONAME + pjsua_conf_adjust_tx_level @ 57 NONAME + pjsua_conf_connect @ 58 NONAME + pjsua_conf_disconnect @ 59 NONAME + pjsua_conf_get_active_ports @ 60 NONAME + pjsua_conf_get_max_ports @ 61 NONAME + pjsua_conf_get_port_info @ 62 NONAME + pjsua_conf_get_signal_level @ 63 NONAME + pjsua_conf_remove_port @ 64 NONAME + pjsua_config_default @ 65 NONAME + pjsua_config_dup @ 66 NONAME + pjsua_create @ 67 NONAME + pjsua_destroy @ 68 NONAME + pjsua_detect_nat_type @ 69 NONAME + pjsua_dump @ 70 NONAME + pjsua_enum_accs @ 71 NONAME + pjsua_enum_buddies @ 72 NONAME + pjsua_enum_calls @ 73 NONAME + pjsua_enum_codecs @ 74 NONAME + pjsua_enum_conf_ports @ 75 NONAME + pjsua_enum_snd_devs @ 76 NONAME + pjsua_enum_transports @ 77 NONAME + pjsua_get_buddy_count @ 78 NONAME + pjsua_get_ec_tail @ 79 NONAME + pjsua_get_nat_type @ 80 NONAME + pjsua_get_pjmedia_endpt @ 81 NONAME + pjsua_get_pjsip_endpt @ 82 NONAME + pjsua_get_pool_factory @ 83 NONAME + pjsua_get_snd_dev @ 84 NONAME + pjsua_get_var @ 85 NONAME + pjsua_handle_events @ 86 NONAME + pjsua_im_send @ 87 NONAME + pjsua_im_typing @ 88 NONAME + pjsua_init @ 89 NONAME + pjsua_logging_config_default @ 90 NONAME + pjsua_logging_config_dup @ 91 NONAME + pjsua_media_config_default @ 92 NONAME + pjsua_media_transports_create @ 93 NONAME + pjsua_msg_data_init @ 94 NONAME + pjsua_perror @ 95 NONAME + pjsua_player_create @ 96 NONAME + pjsua_player_destroy @ 97 NONAME + pjsua_player_get_conf_port @ 98 NONAME + pjsua_player_get_port @ 99 NONAME + pjsua_player_set_pos @ 100 NONAME + pjsua_playlist_create @ 101 NONAME + pjsua_pool_create @ 102 NONAME + pjsua_pres_dump @ 103 NONAME + pjsua_reconfigure_logging @ 104 NONAME + pjsua_recorder_create @ 105 NONAME + pjsua_recorder_destroy @ 106 NONAME + pjsua_recorder_get_conf_port @ 107 NONAME + pjsua_recorder_get_port @ 108 NONAME + pjsua_set_ec @ 109 NONAME + pjsua_set_no_snd_dev @ 110 NONAME + pjsua_set_null_snd_dev @ 111 NONAME + pjsua_set_snd_dev @ 112 NONAME + pjsua_start @ 113 NONAME + pjsua_transport_close @ 114 NONAME + pjsua_transport_config_default @ 115 NONAME + pjsua_transport_config_dup @ 116 NONAME + pjsua_transport_create @ 117 NONAME + pjsua_transport_get_info @ 118 NONAME + pjsua_transport_register @ 119 NONAME + pjsua_transport_set_enable @ 120 NONAME + pjsua_verify_sip_url @ 121 NONAME diff --git a/pjsip/include/pjsua-lib/pjsua.h b/pjsip/include/pjsua-lib/pjsua.h index 579d722f4..fb324f4d5 100644 --- a/pjsip/include/pjsua-lib/pjsua.h +++ b/pjsip/include/pjsua-lib/pjsua.h @@ -1768,7 +1768,7 @@ PJ_DECL(pj_status_t) pjsua_transport_close( pjsua_transport_id id, * Default registration interval. */ #ifndef PJSUA_REG_INTERVAL -# define PJSUA_REG_INTERVAL 55 +# define PJSUA_REG_INTERVAL 300 #endif @@ -1897,7 +1897,7 @@ typedef struct pjsua_acc_config /** * Optional interval for registration, in seconds. If the value is zero, - * default interval will be used (PJSUA_REG_INTERVAL, 55 seconds). + * default interval will be used (PJSUA_REG_INTERVAL, 300 seconds). */ unsigned reg_timeout; @@ -1947,6 +1947,28 @@ typedef struct pjsua_acc_config */ pj_bool_t auto_update_nat; + /** + * Set the interval for periodic keep-alive transmission for this account. + * If this value is zero, keep-alive will be disabled for this account. + * The keep-alive transmission will be sent to the registrar's address, + * after successful registration. + * + * Even if this setting is enabled, keep-alive transmission is only done + * when STUN is enabled in the global #pjsua_config, and the transport + * used for registration is UDP. For TCP and TLS transports, keep-alive + * is done by the transport themselves. + * + * Default: 15 (seconds) + */ + unsigned ka_interval; + + /** + * Specify the data to be transmitted as keep-alive packets. + * + * Default: CR-LF + */ + pj_str_t ka_data; + } pjsua_acc_config; @@ -1965,6 +1987,18 @@ typedef struct pjsua_acc_config PJ_DECL(void) pjsua_acc_config_default(pjsua_acc_config *cfg); +/** + * Duplicate account config. + * + * @param pool Pool to be used for duplicating the config. + * @param dst Destination configuration. + * @param src Source configuration. + */ +PJ_DECL(void) pjsua_acc_config_dup(pj_pool_t *pool, + pjsua_acc_config *dst, + const pjsua_acc_config *src); + + /** * Account info. Application can query account info by calling * #pjsua_acc_get_info(). diff --git a/pjsip/include/pjsua-lib/pjsua_internal.h b/pjsip/include/pjsua-lib/pjsua_internal.h index 004c1ca13..87d30b990 100644 --- a/pjsip/include/pjsua-lib/pjsua_internal.h +++ b/pjsip/include/pjsua-lib/pjsua_internal.h @@ -86,10 +86,14 @@ typedef struct pjsua_acc int srv_port; /**< Port number of reg server. */ pjsip_regc *regc; /**< Client registration session. */ - pj_timer_entry reg_timer; /**< Registration timer. */ pj_status_t reg_last_err; /**< Last registration error. */ int reg_last_code; /**< Last status last register. */ + pj_timer_entry ka_timer; /**< Keep-alive timer for UDP. */ + pjsip_transport *ka_transport; /**< Transport for keep-alive. */ + pj_sockaddr ka_target; /**< Destination address for K-A */ + unsigned ka_target_len; /**< Length of ka_target. */ + pjsip_route_hdr route_set; /**< Complete route set inc. outbnd.*/ unsigned cred_cnt; /**< Number of credentials. */ diff --git a/pjsip/src/pjsip/sip_transport.c b/pjsip/src/pjsip/sip_transport.c index 1ac9f6ffd..11191c54e 100644 --- a/pjsip/src/pjsip/sip_transport.c +++ b/pjsip/src/pjsip/sip_transport.c @@ -417,12 +417,12 @@ static char *get_msg_info(pj_pool_t *pool, const char *obj_name, PJ_DEF(char*) pjsip_tx_data_get_info( pjsip_tx_data *tdata ) { - if (tdata==NULL || tdata->msg==NULL) - return "NULL"; - if (tdata->info) return tdata->info; + if (tdata==NULL || tdata->msg==NULL) + return "NULL"; + pj_lock_acquire(tdata->lock); tdata->info = get_msg_info(tdata->pool, tdata->obj_name, tdata->msg); pj_lock_release(tdata->lock); @@ -653,6 +653,8 @@ PJ_DEF(pj_status_t) pjsip_tpmgr_send_raw(pjsip_tpmgr *mgr, return status; } + tdata->info = "raw"; + /* Add reference counter. */ pjsip_tx_data_add_ref(tdata); } diff --git a/pjsip/src/pjsua-lib/pjsua_acc.c b/pjsip/src/pjsua-lib/pjsua_acc.c index 012832c5f..a935300e9 100644 --- a/pjsip/src/pjsua-lib/pjsua_acc.c +++ b/pjsip/src/pjsua-lib/pjsua_acc.c @@ -64,9 +64,9 @@ PJ_DEF(pjsua_acc_id) pjsua_acc_get_default(void) /* * Copy account configuration. */ -static void copy_acc_config(pj_pool_t *pool, - pjsua_acc_config *dst, - const pjsua_acc_config *src) +PJ_DEF(void) pjsua_acc_config_dup( pj_pool_t *pool, + pjsua_acc_config *dst, + const pjsua_acc_config *src) { unsigned i; @@ -87,6 +87,9 @@ static void copy_acc_config(pj_pool_t *pool, for (i=0; icred_count; ++i) { pjsip_cred_dup(pool, &dst->cred_info[i], &src->cred_info[i]); } + + dst->ka_interval = src->ka_interval; + pj_strdup(pool, &dst->ka_data, &src->ka_data); } @@ -275,7 +278,7 @@ PJ_DEF(pj_status_t) pjsua_acc_add( const pjsua_acc_config *cfg, {PJSUA_UNLOCK(); return PJ_EBUG;}); /* Copy config */ - copy_acc_config(pjsua_var.pool, &pjsua_var.acc[id].cfg, cfg); + pjsua_acc_config_dup(pjsua_var.pool, &pjsua_var.acc[id].cfg, cfg); /* Normalize registration timeout */ if (pjsua_var.acc[id].cfg.reg_uri.slen && @@ -631,6 +634,123 @@ void update_service_route(pjsua_acc *acc, pjsip_rx_data *rdata) acc->index, uri_cnt)); } + +/* Keep alive timer callback */ +static void keep_alive_timer_cb(pj_timer_heap_t *th, pj_timer_entry *te) +{ + pjsua_acc *acc; + pjsip_tpselector tp_sel; + pj_time_val delay; + pj_status_t status; + + PJ_UNUSED_ARG(th); + + PJSUA_LOCK(); + + te->id = PJ_FALSE; + + acc = (pjsua_acc*) te->user_data; + + /* Select the transport to send the packet */ + pj_bzero(&tp_sel, sizeof(tp_sel)); + tp_sel.type = PJSIP_TPSELECTOR_TRANSPORT; + tp_sel.u.transport = acc->ka_transport; + + PJ_LOG(5,(THIS_FILE, + "Sending %d bytes keep-alive packet for acc %d to %s:%d", + acc->cfg.ka_data.slen, acc->index, + pj_inet_ntoa(acc->ka_target.ipv4.sin_addr), + pj_ntohs(acc->ka_target.ipv4.sin_port))); + + /* Send raw packet */ + status = pjsip_tpmgr_send_raw(pjsip_endpt_get_tpmgr(pjsua_var.endpt), + PJSIP_TRANSPORT_UDP, &tp_sel, + NULL, acc->cfg.ka_data.ptr, + acc->cfg.ka_data.slen, + &acc->ka_target, acc->ka_target_len, + NULL, NULL); + + if (status != PJ_SUCCESS && status != PJ_EPENDING) { + pjsua_perror(THIS_FILE, "Error sending keep-alive packet", status); + } + + /* Reschedule next timer */ + delay.sec = acc->cfg.ka_interval; + delay.msec = 0; + status = pjsip_endpt_schedule_timer(pjsua_var.endpt, te, &delay); + if (status == PJ_SUCCESS) { + te->id = PJ_TRUE; + } else { + pjsua_perror(THIS_FILE, "Error starting keep-alive timer", status); + } + + PJSUA_UNLOCK(); +} + + +/* Update keep-alive for the account */ +static void update_keep_alive(pjsua_acc *acc, pj_bool_t start, + struct pjsip_regc_cbparam *param) +{ + /* In all cases, stop keep-alive timer if it's running. */ + if (acc->ka_timer.id) { + pjsip_endpt_cancel_timer(pjsua_var.endpt, &acc->ka_timer); + acc->ka_timer.id = PJ_FALSE; + + pjsip_transport_dec_ref(acc->ka_transport); + acc->ka_transport = NULL; + } + + if (start) { + pj_time_val delay; + pj_status_t status; + + /* Only do keep-alive if: + * - STUN is enabled in global config, and + * - ka_interval is not zero in the account, and + * - transport is UDP. + */ + if (pjsua_var.stun_srv.ipv4.sin_family == 0 || + acc->cfg.ka_interval == 0 || + param->rdata->tp_info.transport->key.type != PJSIP_TRANSPORT_UDP) + { + /* Keep alive is not necessary */ + return; + } + + /* Save transport and destination address. */ + acc->ka_transport = param->rdata->tp_info.transport; + pjsip_transport_add_ref(acc->ka_transport); + pj_memcpy(&acc->ka_target, ¶m->rdata->pkt_info.src_addr, + param->rdata->pkt_info.src_addr_len); + acc->ka_target_len = param->rdata->pkt_info.src_addr_len; + + /* Setup and start the timer */ + acc->ka_timer.cb = &keep_alive_timer_cb; + acc->ka_timer.user_data = (void*)acc; + + delay.sec = acc->cfg.ka_interval; + delay.msec = 0; + status = pjsip_endpt_schedule_timer(pjsua_var.endpt, &acc->ka_timer, + &delay); + if (status == PJ_SUCCESS) { + acc->ka_timer.id = PJ_TRUE; + PJ_LOG(4,(THIS_FILE, "Keep-alive timer started for acc %d, " + "destination:%s:%d, interval:%ds", + acc->index, + param->rdata->pkt_info.src_name, + param->rdata->pkt_info.src_port, + acc->cfg.ka_interval)); + } else { + acc->ka_timer.id = PJ_FALSE; + pjsip_transport_dec_ref(acc->ka_transport); + acc->ka_transport = NULL; + pjsua_perror(THIS_FILE, "Error starting keep-alive timer", status); + } + } +} + + /* * This callback is called by pjsip_regc when outgoing register * request has completed. @@ -654,6 +774,9 @@ static void regc_cb(struct pjsip_regc_cbparam *param) pjsip_regc_destroy(acc->regc); acc->regc = NULL; + /* Stop keep-alive timer if any. */ + update_keep_alive(acc, PJ_FALSE, NULL); + } else if (param->code < 0 || param->code >= 300) { PJ_LOG(2, (THIS_FILE, "SIP registration failed, status=%d (%.*s)", param->code, @@ -661,11 +784,18 @@ static void regc_cb(struct pjsip_regc_cbparam *param) pjsip_regc_destroy(acc->regc); acc->regc = NULL; + /* Stop keep-alive timer if any. */ + update_keep_alive(acc, PJ_FALSE, NULL); + } else if (PJSIP_IS_STATUS_IN_CLASS(param->code, 200)) { if (param->expiration < 1) { pjsip_regc_destroy(acc->regc); acc->regc = NULL; + + /* Stop keep-alive timer if any. */ + update_keep_alive(acc, PJ_FALSE, NULL); + PJ_LOG(3,(THIS_FILE, "%s: unregistration success", pjsua_var.acc[acc->index].cfg.id.ptr)); } else { @@ -687,6 +817,9 @@ static void regc_cb(struct pjsip_regc_cbparam *param) (int)param->reason.slen, param->reason.ptr, param->expiration)); + /* Start keep-alive timer if necessary. */ + update_keep_alive(acc, PJ_TRUE, param); + /* Send initial PUBLISH if it is enabled */ if (acc->cfg.publish_enabled && acc->publish_sess==NULL) pjsua_pres_init_publish_acc(acc->index); diff --git a/pjsip/src/pjsua-lib/pjsua_core.c b/pjsip/src/pjsua-lib/pjsua_core.c index 2cfca8d94..472df6374 100644 --- a/pjsip/src/pjsua-lib/pjsua_core.c +++ b/pjsip/src/pjsua-lib/pjsua_core.c @@ -140,6 +140,8 @@ PJ_DEF(void) pjsua_acc_config_default(pjsua_acc_config *cfg) cfg->transport_id = PJSUA_INVALID_ID; cfg->auto_update_nat = PJ_TRUE; cfg->require_100rel = pjsua_var.ua_cfg.require_100rel; + cfg->ka_interval = 15; + cfg->ka_data = pj_str("\r\n"); } PJ_DEF(void) pjsua_buddy_config_default(pjsua_buddy_config *cfg)