Modified: freeswitch/trunk/src/mod/endpoints/mod_skinny/mod_skinny.c (16749 => 16750)
--- freeswitch/trunk/src/mod/endpoints/mod_skinny/mod_skinny.c 2010-02-24 11:58:00 UTC (rev 16749)
+++ freeswitch/trunk/src/mod/endpoints/mod_skinny/mod_skinny.c 2010-02-24 11:58:07 UTC (rev 16750)
@@ -70,7 +70,7 @@
char *codec_rates_string;
char *codec_rates[SWITCH_MAX_CODECS];
int codec_rates_last;
- int keep_alive;
+ uint32_t keep_alive;
char date_format[6];
/* data */
switch_event_node_t *heartbeat_node;
@@ -129,6 +129,8 @@
char reserved2[4];
};
+#define KEEP_ALIVE_ACK_MESSAGE 0x0100
+
#define SKINNY_MESSAGE_FIELD_SIZE 4 /* 4-bytes field */
#define SKINNY_MESSAGE_HEADERSIZE 12 /* three 4-bytes fields */
#define SKINNY_MESSAGE_MAXSIZE 1000
@@ -197,9 +199,10 @@
} listen_list;
/*****************************************************************************/
-/* CHANNEL FUNCTIONS */
+/* FUNCTIONS */
/*****************************************************************************/
+/* CHANNEL FUNCTIONS */
static switch_status_t channel_on_init(switch_core_session_t *session);
static switch_status_t channel_on_hangup(switch_core_session_t *session);
static switch_status_t channel_on_destroy(switch_core_session_t *session);
@@ -214,6 +217,13 @@
static switch_status_t channel_kill_channel(switch_core_session_t *session, int sig);
+/* LISTENER FUNCTIONS */
+static switch_status_t keepalive_listener(listener_t *listener);
+
+/*****************************************************************************/
+/* CHANNEL FUNCTIONS */
+/*****************************************************************************/
+
static void tech_init(private_t *tech_pvt, switch_core_session_t *session)
{
tech_pvt->read_frame.data = tech_pvt->databuf;
@@ -608,11 +618,9 @@
/* SKINNY FUNCTIONS */
/*****************************************************************************/
-static switch_status_t skinny_read_packet(listener_t *listener, skinny_message_t **req, uint32_t timeout)
+static switch_status_t skinny_read_packet(listener_t *listener, skinny_message_t **req)
{
skinny_message_t *request;
- uint32_t elapsed = 0;
- time_t start = 0;
switch_size_t mlen, bytes = 0;
char mbuf[SKINNY_MESSAGE_MAXSIZE] = "";
char *ptr;
@@ -629,7 +637,6 @@
return SWITCH_STATUS_FALSE;
}
- start = switch_epoch_time_now(NULL);
ptr = mbuf;
while (listener->sock && running) {
@@ -681,13 +688,10 @@
}
}
}
- if (timeout) {
- elapsed = (uint32_t) (switch_epoch_time_now(NULL) - start);
- if (elapsed >= timeout) {
- switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "Socket timed out.\n");
- switch_clear_flag_locked(listener, LFLAG_RUNNING);
- return SWITCH_STATUS_FALSE;
- }
+ if (listener->expire_time && listener->expire_time < switch_epoch_time_now(NULL)) {
+ switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "Listener timed out.\n");
+ switch_clear_flag_locked(listener, LFLAG_RUNNING);
+ return SWITCH_STATUS_FALSE;
}
}
return SWITCH_STATUS_SUCCESS;
@@ -731,12 +735,16 @@
reply->data.reg_ack.secondaryKeepAlive = globals.keep_alive;
/* TODO send CapabilitiesReqMessage (and parse the CapabilitiesResMessage) */
/* TODO event */
+ keepalive_listener(listener);
break;
case PORT_MESSAGE:
/* Nothing to do */
break;
case KEEP_ALIVE_MESSAGE:
- /* TODO */
+ reply = switch_core_alloc(listener->pool, 12);
+ reply->type = KEEP_ALIVE_ACK_MESSAGE;
+ reply->length = 4;
+ keepalive_listener(listener);
break;
/* TODO */
default:
@@ -817,26 +825,6 @@
/* TODO */
}
-static switch_status_t expire_listener(listener_t *listener)
-{
- if (!listener->expire_time) {
- listener->expire_time = switch_epoch_time_now(NULL);
- }
-
- if (switch_thread_rwlock_trywrlock(listener->rwlock) != SWITCH_STATUS_SUCCESS) {
- return SWITCH_STATUS_FALSE;
- }
-
- switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(listener->session), SWITCH_LOG_CRIT, "Stateful Listener %u has expired\n", listener->id);
-
- flush_listener(listener, SWITCH_TRUE, SWITCH_TRUE);
-
- switch_thread_rwlock_unlock(listener->rwlock);
- switch_core_destroy_memory_pool(&listener->pool);
-
- return SWITCH_STATUS_SUCCESS;
-}
-
static void close_socket(switch_socket_t **sock)
{
switch_mutex_lock(listen_list.sock_mutex);
@@ -850,11 +838,29 @@
static switch_status_t kill_listener(listener_t *listener)
{
+ switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "Killing listener.\n");
switch_clear_flag(listener, LFLAG_RUNNING);
close_socket(&listener->sock);
return SWITCH_STATUS_SUCCESS;
}
+static switch_status_t kill_expired_listener(listener_t *listener)
+{
+ if(listener->expire_time < switch_epoch_time_now(NULL)) {
+ return kill_listener(listener);
+ }
+ return SWITCH_STATUS_SUCCESS;
+}
+
+static switch_status_t keepalive_listener(listener_t *listener)
+{
+ switch_assert(listener);
+
+ listener->expire_time = switch_epoch_time_now(NULL)+globals.keep_alive*110/100;
+
+ return SWITCH_STATUS_SUCCESS;
+}
+
static void *SWITCH_THREAD_FUNC listener_run(switch_thread_t *thread, void *obj)
{
listener_t *listener = (listener_t *) obj;
@@ -889,11 +895,12 @@
switch_socket_opt_set(listener->sock, SWITCH_SO_NONBLOCK, TRUE);
switch_set_flag_locked(listener, LFLAG_RUNNING);
+ keepalive_listener(listener);
add_listener(listener);
while (running && switch_test_flag(listener, LFLAG_RUNNING) && listen_list.ready) {
- status = skinny_read_packet(listener, &request, 30);
+ status = skinny_read_packet(listener, &request);
if (status != SWITCH_STATUS_SUCCESS) {
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_CRIT, "Socket Error!\n");
@@ -1136,7 +1143,7 @@
static void event_handler(switch_event_t *event)
{
if (event->event_id == SWITCH_EVENT_HEARTBEAT) {
- walk_listeners(expire_listener);
+ walk_listeners(kill_expired_listener);
}
}