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;
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;
};
};
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 */
/*****************************************************************************/
} event_flag_t;
struct listener {
+ skinny_device_t *device;
switch_socket_t *sock;
switch_memory_pool_t *pool;
switch_core_session_t *session;
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");
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,
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;
}
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);
} 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);
}
}
}
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");
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;
}