Index: channels/chan_sip.c =================================================================== --- channels/chan_sip.c (revision 167893) +++ channels/chan_sip.c (working copy) @@ -2402,7 +2402,7 @@ static int handle_common_options(struct ast_flags *flags, struct ast_flags *mask, struct ast_variable *v); /* Realtime device support */ -static void realtime_update_peer(const char *peername, struct sockaddr_in *sin, const char *username, const char *fullcontact, const char *useragent, int expirey, int deprecated_username); +static void realtime_update_peer(const char *peername, struct sockaddr_in *sin, const char *username, const char *fullcontact, const char *useragent, int expirey, int deprecated_username, int lastms); static void update_peer(struct sip_peer *p, int expire); static struct ast_variable *get_insecure_variable_from_config(struct ast_config *config); static const char *get_name_from_variable(struct ast_variable *var, const char *newpeername); @@ -4057,12 +4057,13 @@ that name and store that in the "regserver" field in the sippeers table to facilitate multi-server setups. */ -static void realtime_update_peer(const char *peername, struct sockaddr_in *sin, const char *defaultuser, const char *fullcontact, const char *useragent, int expirey, int deprecated_username) +static void realtime_update_peer(const char *peername, struct sockaddr_in *sin, const char *defaultuser, const char *fullcontact, const char *useragent, int expirey, int deprecated_username, int lastms) { char port[10]; char ipaddr[INET_ADDRSTRLEN]; char regseconds[20]; char *tablename = NULL; + char str_lastms[20]; const char *sysname = ast_config_AST_SYSTEM_NAME; char *syslabel = NULL; @@ -4073,7 +4074,8 @@ int realtimeregs = ast_check_realtime("sipregs"); tablename = realtimeregs ? "sipregs" : "sippeers"; - + + snprintf(str_lastms, sizeof(str_lastms), "%d", lastms); snprintf(regseconds, sizeof(regseconds), "%d", (int)nowtime); /* Expiration time */ ast_copy_string(ipaddr, ast_inet_ntoa(sin->sin_addr), sizeof(ipaddr)); snprintf(port, sizeof(port), "%d", ntohs(sin->sin_port)); @@ -4086,13 +4088,13 @@ if (fc) { ast_update_realtime(tablename, "name", peername, "ipaddr", ipaddr, "port", port, "regseconds", regseconds, + "lastms", str_lastms, "useragent", useragent, deprecated_username ? "username" : "defaultuser", defaultuser, - "useragent", useragent, fc, fullcontact, syslabel, sysname, SENTINEL); /* note fc and syslabel _can_ be NULL */ } else { ast_update_realtime(tablename, "name", peername, "ipaddr", ipaddr, "port", port, "regseconds", regseconds, - "useragent", useragent, + "lastms", str_lastms, "useragent", useragent, deprecated_username ? "username" : "defaultuser", defaultuser, syslabel, sysname, SENTINEL); /* note syslabel _can_ be NULL */ } @@ -4215,7 +4217,7 @@ int rtcachefriends = ast_test_flag(&p->flags[1], SIP_PAGE2_RTCACHEFRIENDS); if (sip_cfg.peer_rtupdate && (p->is_realtime || rtcachefriends)) { - realtime_update_peer(p->name, &p->addr, p->username, rtcachefriends ? p->fullcontact : NULL, p->useragent, expire, p->deprecated_username); + realtime_update_peer(p->name, &p->addr, p->username, rtcachefriends ? p->fullcontact : NULL, p->useragent, expire, p->deprecated_username, p->lastms); } } @@ -10887,7 +10889,7 @@ if (!sip_cfg.ignore_regexpire) { if (peer->rt_fromcontact) - ast_update_realtime(tablename, "name", peer->name, "fullcontact", "", "ipaddr", "", "port", "", "regseconds", "0", peer->deprecated_username ? "username" : "defaultuser", "", "regserver", "", "useragent", "", SENTINEL); + ast_update_realtime(tablename, "name", peer->name, "fullcontact", "", "ipaddr", "", "port", "", "regseconds", "0", peer->deprecated_username ? "username" : "defaultuser", "", "regserver", "", "useragent", "", "lastms", "", SENTINEL); else ast_db_del("SIP/Registry", peer->name); } @@ -22371,6 +22373,8 @@ ast_log(LOG_WARNING, "Invalid qualifyfreq number '%s' at line %d of %s\n", v->value, v->lineno, config); peer->qualifyfreq = global_qualifyfreq; } + } else if (realtime && !strcasecmp(v->name, "lastms")) { + sscanf(v->value, "%d", &peer->lastms); } else if (!strcasecmp(v->name, "maxcallbitrate")) { peer->maxcallbitrate = atoi(v->value); if (peer->maxcallbitrate < 0) @@ -22459,10 +22463,17 @@ if ((nowtime - regseconds) > 0) { destroy_association(peer); + peer->lastms = -1; memset(&peer->addr, 0, sizeof(peer->addr)); ast_debug(1, "Bah, we're expired (%d/%d/%d)!\n", (int)(nowtime - regseconds), (int)regseconds, (int)nowtime); } } + + if (realtime && peer->lastms > 0) { + ref_peer(peer, "ref peer poke"); + sip_poke_peer(peer, 0); + } + ast_copy_flags(&peer->flags[0], &peerflags[0], mask[0].flags); ast_copy_flags(&peer->flags[1], &peerflags[1], mask[1].flags); if (ast_test_flag(&peer->flags[1], SIP_PAGE2_ALLOWSUBSCRIBE)) @@ -24101,6 +24112,7 @@ "fullcontact", RQ_CHAR, 35, "regserver", RQ_CHAR, 20, "useragent", RQ_CHAR, 20, + "lastms", RQ_INTEGER4, 11, SENTINEL); return AST_MODULE_LOAD_SUCCESS; Index: UPGRADE.txt =================================================================== --- UPGRADE.txt (revision 167893) +++ UPGRADE.txt (working copy) @@ -100,3 +100,4 @@ func_sprintf, and is no longer included in func_strings. If you use this function and do not use 'autoload=yes' in modules.conf, you will need to explicitly load func_sprintf for it to be available. +