Revision
16749
Author
sathieu
Date
2010-02-24 05:58:00 -0600 (Wed, 24 Feb 2010)

Log Message

Skinny: Milestone 1 : device level (Register)

- handle RegisterMessage
- keep device infos (attached to listener)
- respond with RegisterAckMessage
- handle port message (do nothing)
- handle keepalive message (do nothing for now)

and:
- clean memory pools usage
- date_format is fixed length

Modified Paths

Diff

Modified: freeswitch/trunk/src/mod/endpoints/mod_skinny/mod_skinny.c (16748 => 16749)


--- freeswitch/trunk/src/mod/endpoints/mod_skinny/mod_skinny.c	2010-02-24 11:57:53 UTC (rev 16748)
+++ freeswitch/trunk/src/mod/endpoints/mod_skinny/mod_skinny.c	2010-02-24 11:58:00 UTC (rev 16749)
@@ -71,7 +71,7 @@
 	char *codec_rates[SWITCH_MAX_CODECS];
 	int codec_rates_last;
 	int keep_alive;
-	char *date_format;
+	char date_format[6];
 	/* data */
 	switch_event_node_t *heartbeat_node;
 	unsigned int flags;
@@ -101,16 +101,43 @@
 SWITCH_DECLARE_GLOBAL_STRING_FUNC(set_global_dialplan, globals.dialplan);
 SWITCH_DECLARE_GLOBAL_STRING_FUNC(set_global_codec_string, globals.codec_string);
 SWITCH_DECLARE_GLOBAL_STRING_FUNC(set_global_codec_rates_string, globals.codec_rates_string);
-SWITCH_DECLARE_GLOBAL_STRING_FUNC(set_global_date_format, globals.date_format);
 
 /*****************************************************************************/
 /* SKINNY TYPES */
 /*****************************************************************************/
+
+#define KEEP_ALIVE_MESSAGE 0x0000
+
+#define REGISTER_MESSAGE 0x0001
+struct register_message {
+	char deviceName[16];
+	uint32_t userId;
+	uint32_t instance;
+	uint32_t ip;
+	uint32_t deviceType;
+	uint32_t maxStreams;
+};
+
+#define PORT_MESSAGE 0x0002
+
+#define REGISTER_ACK_MESSAGE 0x0081
+struct register_ack_message {
+	uint32_t keepAlive;
+	char dateFormat[6];
+	char reserved[2];
+	uint32_t secondaryKeepAlive;
+	char reserved2[4];
+};
+
 #define SKINNY_MESSAGE_FIELD_SIZE 4 /* 4-bytes field */
 #define SKINNY_MESSAGE_HEADERSIZE 12 /* three 4-bytes fields */
 #define SKINNY_MESSAGE_MAXSIZE 1000
 
 union skinny_data {
+	struct register_message reg;
+	struct register_ack_message reg_ack;
+	
+	char as_char;
 	void *raw;
 };
 
@@ -122,6 +149,18 @@
 };
 typedef struct skinny_message skinny_message_t;
 
+
+struct skinny_device {
+	char deviceName[16];
+	uint32_t userId;
+	uint32_t instance;
+	uint32_t ip;
+	uint32_t deviceType;
+	uint32_t maxStreams;
+	uint16_t port;
+};
+typedef struct skinny_device skinny_device_t;
+
 /*****************************************************************************/
 /* LISTENERS TYPES */
 /*****************************************************************************/
@@ -131,6 +170,7 @@
 } event_flag_t;
 
 struct listener {
+	skinny_device_t *device;
 	switch_socket_t *sock;
 	switch_memory_pool_t *pool;
 	switch_core_session_t *session;
@@ -578,7 +618,7 @@
 	char *ptr;
 	switch_status_t status = SWITCH_STATUS_SUCCESS;
 
-	request = switch_core_alloc(module_pool, SKINNY_MESSAGE_MAXSIZE);
+	request = switch_core_alloc(listener->pool, SKINNY_MESSAGE_MAXSIZE);
 
 	if (!request) {
 		switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Unable to allocate memory.\n");
@@ -656,9 +696,48 @@
 static switch_status_t skinny_parse_request(listener_t *listener, skinny_message_t *request, skinny_message_t **rep)
 {
     skinny_message_t *reply;
-	switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "Parsing request.\n");
+    skinny_device_t *device;
 	reply = NULL;
+	switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO,
+		"Received message of type %d.\n", request->type);
+	if(!listener->device && request->type != REGISTER_MESSAGE) {
+		switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR,
+			"Device should send a register message first.\n");
+		return SWITCH_STATUS_FALSE;
+	}
+	device = listener->device;
 	switch(request->type) {
+		case REGISTER_MESSAGE:
+			/* TODO : check directory */
+			if(listener->device) {
+				switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR,
+					"Device already registred.\n");
+				return SWITCH_STATUS_FALSE;
+			}
+			device = switch_core_alloc(listener->pool, sizeof(skinny_device_t));
+			memcpy(device->deviceName, request->data.reg.deviceName, 16);
+			device->userId = request->data.reg.userId;
+			device->instance = request->data.reg.instance;
+			device->ip = request->data.reg.ip;
+			device->deviceType = request->data.reg.deviceType;
+			device->maxStreams = request->data.reg.maxStreams;
+			listener->device = device;
+
+			reply = switch_core_alloc(listener->pool, 12+sizeof(reply->data.reg_ack));
+			reply->type = REGISTER_ACK_MESSAGE;
+			reply->length = 4 + sizeof(reply->data.reg_ack);
+			reply->data.reg_ack.keepAlive = globals.keep_alive;
+			memcpy(reply->data.reg_ack.dateFormat, globals.date_format, 6);
+			reply->data.reg_ack.secondaryKeepAlive = globals.keep_alive;
+			/* TODO send CapabilitiesReqMessage (and parse the CapabilitiesResMessage) */
+			/* TODO event */
+			break;
+		case PORT_MESSAGE:
+			/* Nothing to do */
+			break;
+		case KEEP_ALIVE_MESSAGE:
+			/* TODO */
+			break;
 		/* TODO */
 		default:
 			switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, 
@@ -670,8 +749,13 @@
 
 static switch_status_t skinny_send_reply(listener_t *listener, skinny_message_t *reply)
 {
-	switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "Sending reply.\n");
-	//TODO switch_socket_send(listener->sock, buf, &len);
+	char *ptr;
+	switch_size_t len;
+	switch_assert(reply != NULL);
+	len = reply->length+4;
+	ptr = (char *) reply;
+	switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "Sending reply (length=%d).\n", len);
+	switch_socket_send(listener->sock, ptr, &len);
 	return SWITCH_STATUS_SUCCESS;
 }
 
@@ -963,6 +1047,7 @@
 		listener->sock = inbound_socket;
 		listener->pool = listener_pool;
 		listener_pool = NULL;
+		listener->device = NULL;
 
 		switch_mutex_init(&listener->flag_mutex, SWITCH_MUTEX_NESTED, listener->pool);
 
@@ -1031,7 +1116,7 @@
 			} else if (!strcmp(var, "keep-alive")) {
 				globals.keep_alive = atoi(val);
 			} else if (!strcmp(var, "date-format")) {
-				set_global_date_format(val);
+				memcpy(globals.date_format, val, 6);
 			}
 		}
 	}
@@ -1064,10 +1149,10 @@
 
 	load_skinny_config();
 
-	switch_mutex_init(&globals.listener_mutex, SWITCH_MUTEX_NESTED, pool);
+	switch_mutex_init(&globals.listener_mutex, SWITCH_MUTEX_NESTED, module_pool);
 
 	memset(&listen_list, 0, sizeof(listen_list));
-	switch_mutex_init(&listen_list.sock_mutex, SWITCH_MUTEX_NESTED, pool);
+	switch_mutex_init(&listen_list.sock_mutex, SWITCH_MUTEX_NESTED, module_pool);
 
 	if ((switch_event_bind_removable(modname, SWITCH_EVENT_HEARTBEAT, NULL, event_handler, NULL, &globals.heartbeat_node) != SWITCH_STATUS_SUCCESS)) {
 		switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Couldn't bind our heartbeat handler!\n");
@@ -1116,7 +1201,6 @@
 	switch_safe_free(globals.dialplan);
 	switch_safe_free(globals.codec_string);
 	switch_safe_free(globals.codec_rates_string);
-	switch_safe_free(globals.date_format);
 	
 	return SWITCH_STATUS_SUCCESS;
 }