add generic keepalive system and implement it in sofia to send MESSAGE or INFO packets in-dialog at specified interval.

Adds app: enable_keepalive 0|<seconds>
This app can be run in the dialplan or with execute_on_* type variables for B-legs.

Adds sofia param: keepalive-method  : defaults to MESSAGE can also be "INFO"
This param sets which SIP method to use.
This commit is contained in:
Anthony Minessale 2014-04-16 06:02:44 +05:00
parent ae69c5a7b0
commit a4a792488b
7 changed files with 82 additions and 1 deletions

View File

@ -1009,6 +1009,7 @@ typedef enum {
SWITCH_MESSAGE_INDICATE_BLIND_TRANSFER_RESPONSE,
SWITCH_MESSAGE_INDICATE_STUN_ERROR,
SWITCH_MESSAGE_INDICATE_MEDIA_RENEG,
SWITCH_MESSAGE_INDICATE_KEEPALIVE,
SWITCH_MESSAGE_REFER_EVENT,
SWITCH_MESSAGE_ANSWER_EVENT,
SWITCH_MESSAGE_PROGRESS_EVENT,

View File

@ -552,6 +552,31 @@ SWITCH_STANDARD_APP(heartbeat_function)
if (data) {
seconds = atoi(data);
if (seconds >= 0) {
switch_core_session_enable_heartbeat(session, seconds);
return;
}
}
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "Usage: %s\n", HEARTBEAT_SYNTAX);
}
#define KEEPALIVE_SYNTAX "[0|<seconds>]"
SWITCH_STANDARD_APP(keepalive_function)
{
int seconds = 0;
if (data) {
seconds = atoi(data);
if (seconds >= 0) {
switch_core_session_message_t msg = { 0 };
msg.message_id = SWITCH_MESSAGE_INDICATE_KEEPALIVE;
msg.numeric_arg = seconds;
switch_core_session_receive_message(session, &msg);
switch_core_session_enable_heartbeat(session, seconds);
return;
}
@ -5777,6 +5802,10 @@ SWITCH_MODULE_LOAD_FUNCTION(mod_dptools_load)
sched_heartbeat_function, SCHED_HEARTBEAT_SYNTAX, SAF_SUPPORT_NOMEDIA);
SWITCH_ADD_APP(app_interface, "enable_heartbeat", "Enable Media Heartbeat", "Enable Media Heartbeat",
heartbeat_function, HEARTBEAT_SYNTAX, SAF_SUPPORT_NOMEDIA);
SWITCH_ADD_APP(app_interface, "enable_keepalive", "Enable Keepalive", "Enable Keepalive",
keepalive_function, KEEPALIVE_SYNTAX, SAF_SUPPORT_NOMEDIA);
SWITCH_ADD_APP(app_interface, "media_reset", "Reset all bypass/proxy media flags", "Reset all bypass/proxy media flags", media_reset_function, "", SAF_SUPPORT_NOMEDIA);
SWITCH_ADD_APP(app_interface, "mkdir", "Create a directory", "Create a directory", mkdir_function, MKDIR_SYNTAX, SAF_SUPPORT_NOMEDIA);
SWITCH_ADD_APP(app_interface, "rename", "Rename file", "Rename file", rename_function, RENAME_SYNTAX, SAF_SUPPORT_NOMEDIA | SAF_ZOMBIE_EXEC);

View File

@ -1124,6 +1124,38 @@ static switch_status_t sofia_receive_message(switch_core_session_t *session, swi
/* ones that do not need to lock sofia mutex */
switch (msg->message_id) {
case SWITCH_MESSAGE_INDICATE_KEEPALIVE:
{
if (msg->numeric_arg) {
sofia_set_flag_locked(tech_pvt, TFLAG_KEEPALIVE);
} else {
sofia_clear_flag_locked(tech_pvt, TFLAG_KEEPALIVE);
}
}
break;
case SWITCH_MESSAGE_HEARTBEAT_EVENT:
{
char pl[160] = "";
switch_snprintf(pl, sizeof(pl), "KEEP-ALIVE %d\n", ++tech_pvt->keepalive);
if (sofia_test_flag(tech_pvt, TFLAG_KEEPALIVE)) {
if (tech_pvt->profile->keepalive == KA_MESSAGE) {
nua_message(tech_pvt->nh,
SIPTAG_CONTENT_TYPE_STR("text/plain"),
TAG_IF(!zstr(tech_pvt->user_via), SIPTAG_VIA_STR(tech_pvt->user_via)),
SIPTAG_PAYLOAD_STR(pl),
TAG_END());
} else if (tech_pvt->profile->keepalive == KA_INFO) {
nua_info(tech_pvt->nh,
SIPTAG_CONTENT_TYPE_STR("text/plain"),
TAG_IF(!zstr(tech_pvt->user_via), SIPTAG_VIA_STR(tech_pvt->user_via)),
SIPTAG_PAYLOAD_STR(pl),
TAG_END());
}
}
}
break;
case SWITCH_MESSAGE_INDICATE_RECOVERY_REFRESH:
case SWITCH_MESSAGE_INDICATE_APPLICATION_EXEC:
break;

View File

@ -322,6 +322,7 @@ typedef enum {
TFLAG_CAPTURE,
TFLAG_REINVITED,
TFLAG_PASS_ACK,
TFLAG_KEEPALIVE,
/* No new flags below this line */
TFLAG_MAX
} TFLAGS;
@ -534,6 +535,11 @@ typedef enum {
#define MAX_RTPIP 50
typedef enum {
KA_MESSAGE,
KA_INFO
} ka_type_t;
struct sofia_profile {
int debug;
int parse_invite_tel_params;
@ -706,6 +712,7 @@ struct sofia_profile {
int tcp_keepalive;
int tcp_pingpong;
int tcp_ping2pong;
ka_type_t keepalive;
};
@ -772,6 +779,7 @@ struct private_object {
int respond_code;
char *respond_dest;
time_t last_vid_info;
uint32_t keepalive;
};

View File

@ -4025,6 +4025,14 @@ switch_status_t config_sofia(sofia_config_t reload, char *profile_name)
profile->debug = atoi(val);
} else if (!strcasecmp(var, "parse-invite-tel-params")) {
profile->parse_invite_tel_params = switch_true(val);
} else if (!strcasecmp(var, "keepalive-method")) {
if (!zstr(val)) {
if (!strcasecmp(val, "info")) {
profile->keepalive = KA_INFO;
} else {
profile->keepalive = KA_MESSAGE;
}
}
} else if (!strcasecmp(var, "shutdown-on-fail")) {
profile->shutdown_type = switch_core_strdup(profile->pool, val);
} else if (!strcasecmp(var, "sip-trace") && switch_true(val)) {

View File

@ -231,8 +231,9 @@ SWITCH_DECLARE(switch_status_t) switch_core_session_read_frame(switch_core_sessi
session->read_frame_count = (session->read_impl.actual_samples_per_second / session->read_impl.samples_per_packet) * session->track_duration;
msg.message_id = SWITCH_MESSAGE_HEARTBEAT_EVENT;
msg.numeric_arg = session->track_duration;
switch_core_session_receive_message(session, &msg);
switch_event_create(&event, SWITCH_EVENT_SESSION_HEARTBEAT);
switch_channel_event_set_data(session->channel, event);
switch_event_fire(&event);

View File

@ -751,6 +751,7 @@ static const char *message_names[] = {
"BLIND_TRANSFER_RESPONSE",
"STUN_ERROR",
"MEDIA_RENEG",
"KEEPALIVE",
"ANSWER_EVENT",
"PROGRESS_EVENT",
"RING_EVENT",
@ -1506,6 +1507,7 @@ SWITCH_STANDARD_SCHED_FUNC(sch_heartbeat_callback)
task->runtime = switch_epoch_time_now(NULL) + session->track_duration;
msg.message_id = SWITCH_MESSAGE_HEARTBEAT_EVENT;
msg.numeric_arg = session->track_duration;
switch_core_session_receive_message(session, &msg);
switch_core_session_rwunlock(session);