Skinny: add support to DeviceToUser and UserToDevice messages

This commit is contained in:
Mathieu Parent 2010-09-24 01:55:20 +02:00
parent f5e7284d39
commit 25ddef504d
6 changed files with 262 additions and 50 deletions

View File

@ -1911,6 +1911,55 @@ static switch_status_t load_skinny_config(void)
return SWITCH_STATUS_SUCCESS;
}
static void skinny_user_to_device_event_handler(switch_event_t *event)
{
char *profile_name = switch_event_get_header_nil(event, "Skinny-Profile-Name");
skinny_profile_t *profile;
if ((profile = skinny_find_profile(profile_name))) {
char *device_name = switch_event_get_header_nil(event, "Skinny-Device-Name");
uint32_t device_instance = atoi(switch_event_get_header_nil(event, "Skinny-Station-Instance"));
listener_t *listener = NULL;
skinny_profile_find_listener_by_device_name_and_instance(profile, device_name, device_instance, &listener);
if(listener) {
uint32_t message_type = atoi(switch_event_get_header_nil(event, "Skinny-UserToDevice-Message-Id"));
uint32_t application_id = atoi(switch_event_get_header_nil(event, "Skinny-UserToDevice-Application-Id"));
uint32_t line_instance = atoi(switch_event_get_header_nil(event, "Skinny-UserToDevice-Line-Instance"));
uint32_t call_id = atoi(switch_event_get_header_nil(event, "Skinny-UserToDevice-Call-Id"));
uint32_t transaction_id = atoi(switch_event_get_header_nil(event, "Skinny-UserToDevice-Transaction-Id"));
uint32_t data_length = atoi(switch_event_get_header_nil(event, "Skinny-UserToDevice-Data-Length"));
uint32_t sequence_flag = atoi(switch_event_get_header_nil(event, "Skinny-UserToDevice-Sequence-Flag"));
uint32_t display_priority = atoi(switch_event_get_header_nil(event, "Skinny-UserToDevice-Display-Priority"));
uint32_t conference_id = atoi(switch_event_get_header_nil(event, "Skinny-UserToDevice-Conference-Id"));
uint32_t app_instance_id = atoi(switch_event_get_header_nil(event, "Skinny-UserToDevice-App-Instance-Id"));
uint32_t routing_id = atoi(switch_event_get_header_nil(event, "Skinny-UserToDevice-Routing-Id"));
char *data = switch_event_get_body(event);
if (message_type == 0) {
message_type = skinny_str2message_type(switch_event_get_header_nil(event, "Skinny-UserToDevice-Message-Id-String"));
}
switch(message_type) {
case USER_TO_DEVICE_DATA_MESSAGE:
case USER_TO_DEVICE_DATA_VERSION1_MESSAGE:
data_length = strlen(data); /* we ignore data_length sent */
send_extended_data(listener, message_type,
application_id, line_instance, call_id, transaction_id, data_length,
sequence_flag, display_priority, conference_id, app_instance_id, routing_id,
data);
break;
default:
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING,
"Incorrect message type %s (%d).\n", skinny_message_type2str(message_type), message_type);
}
} else {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING,
"Device %s:%d in profile '%s' not found.\n", device_name, device_instance, profile_name);
}
} else {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING,
"Profile '%s' not found.\n", profile_name);
}
}
static void skinny_call_state_event_handler(switch_event_t *event)
{
char *subclass;
@ -2130,6 +2179,10 @@ SWITCH_MODULE_LOAD_FUNCTION(mod_skinny_load)
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Couldn't bind our trap handler!\n");
/* Not such severe to prevent loading */
}
if ((switch_event_bind_removable(modname, SWITCH_EVENT_CUSTOM, SKINNY_EVENT_USER_TO_DEVICE, skinny_user_to_device_event_handler, NULL, &globals.user_to_device_node) != SWITCH_STATUS_SUCCESS)) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Couldn't bind our user_to_device handler!\n");
/* Not such severe to prevent loading */
}
/* reserve events */
if (switch_event_reserve_subclass(SKINNY_EVENT_REGISTER) != SWITCH_STATUS_SUCCESS) {
@ -2152,6 +2205,14 @@ SWITCH_MODULE_LOAD_FUNCTION(mod_skinny_load)
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Couldn't register subclass %s!\n", SKINNY_EVENT_CALL_STATE);
return SWITCH_STATUS_TERM;
}
if (switch_event_reserve_subclass(SKINNY_EVENT_USER_TO_DEVICE) != SWITCH_STATUS_SUCCESS) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Couldn't register subclass %s!\n", SKINNY_EVENT_USER_TO_DEVICE);
return SWITCH_STATUS_TERM;
}
if (switch_event_reserve_subclass(SKINNY_EVENT_DEVICE_TO_USER) != SWITCH_STATUS_SUCCESS) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Couldn't register subclass %s!\n", SKINNY_EVENT_DEVICE_TO_USER);
return SWITCH_STATUS_TERM;
}
/* connect my internal structure to the blank pointer passed to me */
*module_interface = switch_loadable_module_create_module_interface(globals.pool, modname);
@ -2190,6 +2251,7 @@ SWITCH_MODULE_SHUTDOWN_FUNCTION(mod_skinny_shutdown)
skinny_api_unregister();
/* release events */
switch_event_unbind(&globals.user_to_device_node);
switch_event_unbind(&globals.call_state_node);
switch_event_unbind(&globals.message_waiting_node);
switch_event_unbind(&globals.trap_node);
@ -2198,6 +2260,8 @@ SWITCH_MODULE_SHUTDOWN_FUNCTION(mod_skinny_shutdown)
switch_event_free_subclass(SKINNY_EVENT_EXPIRE);
switch_event_free_subclass(SKINNY_EVENT_ALARM);
switch_event_free_subclass(SKINNY_EVENT_CALL_STATE);
switch_event_free_subclass(SKINNY_EVENT_USER_TO_DEVICE);
switch_event_free_subclass(SKINNY_EVENT_DEVICE_TO_USER);
switch_mutex_lock(mutex);

View File

@ -43,12 +43,15 @@
#define SKINNY_EVENT_EXPIRE "skinny::expire"
#define SKINNY_EVENT_ALARM "skinny::alarm"
#define SKINNY_EVENT_CALL_STATE "skinny::call_state"
#define SKINNY_EVENT_USER_TO_DEVICE "skinny::user_to_device"
#define SKINNY_EVENT_DEVICE_TO_USER "skinny::device_to_user"
struct skinny_globals {
int running;
switch_memory_pool_t *pool;
switch_mutex_t *mutex;
switch_hash_t *profile_hash;
switch_event_node_t *user_to_device_node;
switch_event_node_t *call_state_node;
switch_event_node_t *message_waiting_node;
switch_event_node_t *trap_node;

View File

@ -366,6 +366,62 @@ static switch_status_t skinny_api_cmd_profile_device_send_reset_message(const ch
return SWITCH_STATUS_SUCCESS;
}
static switch_status_t skinny_api_cmd_profile_device_send_data(const char *profile_name, const char *device_name, const char *message_type, char *params, const char *body, switch_stream_handle_t *stream)
{
skinny_profile_t *profile;
if ((profile = skinny_find_profile(profile_name))) {
listener_t *listener = NULL;
skinny_profile_find_listener_by_device_name(profile, device_name, &listener);
if(listener) {
switch_event_t *event = NULL;
char *argv[64] = { 0 };
int argc = 0;
int x = 0;
/* skinny::user_to_device event */
skinny_device_event(listener, &event, SWITCH_EVENT_CUSTOM, SKINNY_EVENT_USER_TO_DEVICE);
switch_event_add_header(event, SWITCH_STACK_BOTTOM, "Skinny-UserToDevice-Message-Id-String", "%s", message_type);
argc = switch_separate_string(params, ';', argv, (sizeof(argv) / sizeof(argv[0])));
for (x = 0; x < argc; x++) {
char *var_name, *var_value = NULL;
var_name = argv[x];
if (var_name && (var_value = strchr(var_name, '='))) {
*var_value++ = '\0';
}
if (zstr(var_name)) {
stream->write_function(stream, "-ERR No variable specified\n");
} else {
char *tmp = switch_mprintf("Skinny-UserToDevice-%s", var_name);
switch_event_add_header(event, SWITCH_STACK_BOTTOM, tmp, "%s", var_value);
switch_safe_free(tmp);
/*
switch_event_add_header(event, SWITCH_STACK_BOTTOM, "Skinny-UserToDevice-Application-Id", "%d", request->data.extended_data.application_id);
switch_event_add_header(event, SWITCH_STACK_BOTTOM, "Skinny-UserToDevice-Line-Instance", "%d", request->data.extended_data.line_instance);
switch_event_add_header(event, SWITCH_STACK_BOTTOM, "Skinny-UserToDevice-Call-Id", "%d", request->data.extended_data.call_id);
switch_event_add_header(event, SWITCH_STACK_BOTTOM, "Skinny-UserToDevice-Transaction-Id", "%d", request->data.extended_data.transaction_id);
switch_event_add_header(event, SWITCH_STACK_BOTTOM, "Skinny-UserToDevice-Data-Length", "%d", request->data.extended_data.data_length);
switch_event_add_header(event, SWITCH_STACK_BOTTOM, "Skinny-UserToDevice-Sequence-Flag", "%d", request->data.extended_data.sequence_flag);
switch_event_add_header(event, SWITCH_STACK_BOTTOM, "Skinny-UserToDevice-Display-Priority", "%d", request->data.extended_data.display_priority);
switch_event_add_header(event, SWITCH_STACK_BOTTOM, "Skinny-UserToDevice-Conference-Id", "%d", request->data.extended_data.conference_id);
switch_event_add_header(event, SWITCH_STACK_BOTTOM, "Skinny-UserToDevice-App-Instance-Id", "%d", request->data.extended_data.app_instance_id);
switch_event_add_header(event, SWITCH_STACK_BOTTOM, "Skinny-UserToDevice-Routing-Id", "%d", request->data.extended_data.routing_id);
*/
}
}
switch_event_add_body(event, body);
switch_event_fire(&event);
stream->write_function(stream, "+OK\n");
} else {
stream->write_function(stream, "Listener not found!\n");
}
} else {
stream->write_function(stream, "Profile not found!\n");
}
return SWITCH_STATUS_SUCCESS;
}
static switch_status_t skinny_api_cmd_profile_set(const char *profile_name, const char *name, const char *value, switch_stream_handle_t *stream)
{
skinny_profile_t *profile;
@ -403,6 +459,7 @@ SWITCH_STANDARD_API(skinny_function)
"skinny profile <profile_name> device <device_name> send SetLampMessage <stimulus> <instance> <lamp_mode>\n"
"skinny profile <profile_name> device <device_name> send SetSpeakerModeMessage <speaker_mode>\n"
"skinny profile <profile_name> device <device_name> send CallStateMessage <call_state> <line_instance> <call_id>\n"
"skinny profile <profile_name> device <device_name> send <UserToDeviceDataMessage|UserToDeviceDataVersion1Message> [ <param>=<value>;... ] <data>\n"
"skinny profile <profile_name> set <name> <value>\n"
"--------------------------------------------------------------------------------\n";
if (session) {
@ -465,6 +522,16 @@ SWITCH_STANDARD_API(skinny_function)
status = skinny_api_cmd_profile_device_send_reset_message(argv[1], argv[3], argv[6], stream);
}
break;
case USER_TO_DEVICE_DATA_MESSAGE:
case USER_TO_DEVICE_DATA_VERSION1_MESSAGE:
if(argc == 8) {
/* <UserToDeviceDataMessage|UserToDeviceDataVersion1Message> [ <param>=<value>;... ] <data> */
status = skinny_api_cmd_profile_device_send_data(argv[1], argv[3], argv[5], argv[6], argv[7], stream);
} else if(argc == 7) {
/* <UserToDeviceDataMessage|UserToDeviceDataVersion1Message> <data> */
status = skinny_api_cmd_profile_device_send_data(argv[1], argv[3], argv[5], "", argv[6], stream);
}
break;
default:
stream->write_function(stream, "Unhandled message %s\n", argv[5]);
}
@ -495,6 +562,8 @@ switch_status_t skinny_api_register(switch_loadable_module_interface_t **module_
switch_console_set_complete("add skinny profile ::skinny::list_profiles device ::skinny::list_devices send SetLampMessage ::skinny::list_stimuli ::skinny::list_stimulus_instances ::skinny::list_stimulus_modes");
switch_console_set_complete("add skinny profile ::skinny::list_profiles device ::skinny::list_devices send SetSpeakerModeMessage ::skinny::list_speaker_modes");
switch_console_set_complete("add skinny profile ::skinny::list_profiles device ::skinny::list_devices send CallStateMessage ::skinny::list_call_states ::skinny::list_line_instances ::skinny::list_call_ids");
switch_console_set_complete("add skinny profile ::skinny::list_profiles device ::skinny::list_devices send UserToDeviceDataMessage");
switch_console_set_complete("add skinny profile ::skinny::list_profiles device ::skinny::list_devices send UserToDeviceDataVersion1Message");
switch_console_set_complete("add skinny profile ::skinny::list_profiles set ::skinny::list_settings");
switch_console_add_complete_func("::skinny::list_profiles", skinny_api_list_profiles);

View File

@ -902,6 +902,42 @@ switch_status_t send_reset(listener_t *listener, uint32_t reset_type)
return skinny_send_reply(listener, message);
}
switch_status_t send_extended_data(listener_t *listener, uint32_t message_type,
uint32_t application_id,
uint32_t line_instance,
uint32_t call_id,
uint32_t transaction_id,
uint32_t data_length,
uint32_t sequence_flag,
uint32_t display_priority,
uint32_t conference_id,
uint32_t app_instance_id,
uint32_t routing_id,
const char *data)
{
skinny_message_t *message;
switch_assert(data_length == strlen(data));
/* data_length should be a multiple of 4 */
if ((data_length % 4) != 0) {
data_length = (data_length / 4 + 1) * 4;
}
message = switch_core_alloc(listener->pool, 12+sizeof(message->data.extended_data)+data_length-1);
message->type = message_type;
message->length = 4 + sizeof(message->data.extended_data)+data_length-1;
message->data.extended_data.application_id = application_id;
message->data.extended_data.line_instance = line_instance;
message->data.extended_data.call_id = call_id;
message->data.extended_data.transaction_id = transaction_id;
message->data.extended_data.data_length = data_length;
message->data.extended_data.sequence_flag = sequence_flag;
message->data.extended_data.display_priority = display_priority;
message->data.extended_data.conference_id = conference_id;
message->data.extended_data.app_instance_id = app_instance_id;
message->data.extended_data.routing_id = routing_id;
strncpy(message->data.extended_data.data, data, data_length);
return skinny_send_reply(listener, message);
}
switch_status_t skinny_perform_send_reply(listener_t *listener, const char *file, const char *func, int line, skinny_message_t *reply)
{
char *ptr;

View File

@ -176,7 +176,7 @@ struct PACKED register_available_lines_message {
/* DeviceToUserDataMessage */
#define DEVICE_TO_USER_DATA_MESSAGE 0x002E
struct PACKED device_to_user_data_message {
struct PACKED data_message {
uint32_t application_id;
uint32_t line_instance;
uint32_t call_id;
@ -187,14 +187,7 @@ struct PACKED device_to_user_data_message {
/* DeviceToUserDataResponseMessage */
#define DEVICE_TO_USER_DATA_RESPONSE_MESSAGE 0x002F
struct PACKED device_to_user_data_response_message {
uint32_t application_id;
uint32_t line_instance;
uint32_t call_id;
uint32_t transaction_id;
uint32_t data_length;
char data[1];
};
/* See struct PACKED data_message */
/* ServiceUrlStatReqMessage */
#define SERVICE_URL_STAT_REQ_MESSAGE 0x0033
@ -210,7 +203,7 @@ struct PACKED feature_stat_req_message {
/* DeviceToUserDataVersion1Message */
#define DEVICE_TO_USER_DATA_VERSION1_MESSAGE 0x0041
struct PACKED device_to_user_data_version1_message {
struct PACKED extended_data_message {
uint32_t application_id;
uint32_t line_instance;
uint32_t call_id;
@ -226,19 +219,7 @@ struct PACKED device_to_user_data_version1_message {
/* DeviceToUserDataResponseVersion1Message */
#define DEVICE_TO_USER_DATA_RESPONSE_VERSION1_MESSAGE 0x0042
struct PACKED device_to_user_data_response_version1_message {
uint32_t application_id;
uint32_t line_instance;
uint32_t call_id;
uint32_t transaction_id;
uint32_t data_length;
uint32_t sequence_flag;
uint32_t display_priority;
uint32_t conference_id;
uint32_t app_instance_id;
uint32_t routing_id;
char data[1];
};
/* See struct PACKED extended_data_message */
/* RegisterAckMessage */
#define REGISTER_ACK_MESSAGE 0x0081
@ -535,14 +516,7 @@ struct PACKED dialed_number_message {
/* UserToDeviceDataMessage */
#define USER_TO_DEVICE_DATA_MESSAGE 0x011E
struct PACKED user_to_device_data_message {
uint32_t application_id;
uint32_t line_instance;
uint32_t call_id;
uint32_t transaction_id;
uint32_t data_length;
char data[1];
};
/* See struct PACKED data_message */
/* FeatureStatMessage */
#define FEATURE_STAT_RES_MESSAGE 0x011F
@ -571,19 +545,7 @@ struct PACKED service_url_stat_res_message {
/* UserToDeviceDataVersion1Message */
#define USER_TO_DEVICE_DATA_VERSION1_MESSAGE 0x013F
struct PACKED user_to_device_data_version1_message {
uint32_t application_id;
uint32_t line_instance;
uint32_t call_id;
uint32_t transaction_id;
uint32_t data_length;
uint32_t sequence_flag;
uint32_t display_priority;
uint32_t conference_id;
uint32_t app_instance_id;
uint32_t routing_id;
char data[1];
};
/* See struct PACKED extended_data_message */
/*****************************************************************************/
/* SKINNY MESSAGE */
@ -615,12 +577,12 @@ union skinny_data {
/* no data for SOFT_KEY_TEMPLATE_REQ_MESSAGE */
struct headset_status_message headset_status;
struct register_available_lines_message reg_lines;
struct device_to_user_data_message d2u_data;
struct device_to_user_data_response_message d2u_data_response;
/* see field "data" for DEVICE_TO_USER_DATA_MESSAGE */
/* see field "data" for DEVICE_TO_USER_DATA_RESPONSE_MESSAGE */
struct service_url_stat_req_message service_url_req;
struct feature_stat_req_message feature_req;
struct device_to_user_data_version1_message d2u_data_v1;
struct device_to_user_data_response_version1_message d2u_data_response_v1;
/* see field "extended_data" for DEVICE_TO_USER_DATA_VERSION1_MESSAGE */
/* see field "extended_data" for DEVICE_TO_USER_DATA_RESPONSE_VERSION1_MESSAGE */
struct register_ack_message reg_ack;
struct start_tone_message start_tone;
struct stop_tone_message stop_tone;
@ -652,11 +614,15 @@ union skinny_data {
struct unregister_ack_message unregister_ack;
struct back_space_req_message back_space_req;
struct dialed_number_message dialed_number;
struct user_to_device_data_message u2d_data;
/* see field "data" for USER_TO_DEVICE_DATA_MESSAGE */
struct feature_stat_res_message feature_res;
struct display_pri_notify_message display_pri_notify;
struct service_url_stat_res_message service_url_res;
struct user_to_device_data_version1_message u2d_data_v1;
/* see field "extended_data" for USER_TO_DEVICE_DATA_VERSION1_MESSAGE */
struct data_message data;
struct extended_data_message extended_data;
uint16_t as_uint16;
char as_char;
void *raw;
@ -873,6 +839,19 @@ switch_status_t send_display_pri_notify(listener_t *listener,
switch_status_t send_reset(listener_t *listener,
uint32_t reset_type);
switch_status_t send_extended_data(listener_t *listener, uint32_t message_type,
uint32_t application_id,
uint32_t line_instance,
uint32_t call_id,
uint32_t transaction_id,
uint32_t data_length,
uint32_t sequence_flag,
uint32_t display_priority,
uint32_t conference_id,
uint32_t app_instance_id,
uint32_t routing_id,
const char *data);
#endif /* _SKINNY_PROTOCOL_H */
/* For Emacs:

View File

@ -1864,6 +1864,30 @@ switch_status_t skinny_handle_register_available_lines_message(listener_t *liste
return SWITCH_STATUS_SUCCESS;
}
switch_status_t skinny_handle_data_message(listener_t *listener, skinny_message_t *request)
{
switch_event_t *event = NULL;
char *tmp = NULL;
skinny_check_data_length(request, sizeof(request->data.data));
skinny_check_data_length(request, sizeof(request->data.data) + request->data.data.data_length - 1);
/* skinny::device_to_user event */
skinny_device_event(listener, &event, SWITCH_EVENT_CUSTOM, SKINNY_EVENT_DEVICE_TO_USER);
switch_event_add_header(event, SWITCH_STACK_BOTTOM, "Skinny-DeviceToUser-Message-Id", "%d", request->type);
switch_event_add_header(event, SWITCH_STACK_BOTTOM, "Skinny-DeviceToUser-Message-Id-String", "%s", skinny_message_type2str(request->type));
switch_event_add_header(event, SWITCH_STACK_BOTTOM, "Skinny-DeviceToUser-Application-Id", "%d", request->data.data.application_id);
switch_event_add_header(event, SWITCH_STACK_BOTTOM, "Skinny-DeviceToUser-Line-Instance", "%d", request->data.data.line_instance);
switch_event_add_header(event, SWITCH_STACK_BOTTOM, "Skinny-DeviceToUser-Call-Id", "%d", request->data.data.call_id);
switch_event_add_header(event, SWITCH_STACK_BOTTOM, "Skinny-DeviceToUser-Transaction-Id", "%d", request->data.data.transaction_id);
switch_event_add_header(event, SWITCH_STACK_BOTTOM, "Skinny-DeviceToUser-Data-Length", "%d", request->data.data.data_length);
tmp = strndup(request->data.data.data, request->data.data.data_length);
switch_event_add_body(event, tmp);
switch_safe_free(tmp);
switch_event_fire(&event);
return SWITCH_STATUS_SUCCESS;
}
switch_status_t skinny_handle_service_url_stat_request(listener_t *listener, skinny_message_t *request)
{
skinny_message_t *message;
@ -1904,6 +1928,35 @@ switch_status_t skinny_handle_feature_stat_request(listener_t *listener, skinny_
return SWITCH_STATUS_SUCCESS;
}
switch_status_t skinny_handle_extended_data_message(listener_t *listener, skinny_message_t *request)
{
switch_event_t *event = NULL;
char *tmp = NULL;
skinny_check_data_length(request, sizeof(request->data.extended_data));
skinny_check_data_length(request, sizeof(request->data.extended_data)+request->data.extended_data.data_length-1);
/* skinny::device_to_user event */
skinny_device_event(listener, &event, SWITCH_EVENT_CUSTOM, SKINNY_EVENT_DEVICE_TO_USER);
switch_event_add_header(event, SWITCH_STACK_BOTTOM, "Skinny-DeviceToUser-Message-Id", "%d", request->type);
switch_event_add_header(event, SWITCH_STACK_BOTTOM, "Skinny-DeviceToUser-Message-Id-String", "%s", skinny_message_type2str(request->type));
switch_event_add_header(event, SWITCH_STACK_BOTTOM, "Skinny-DeviceToUser-Application-Id", "%d", request->data.extended_data.application_id);
switch_event_add_header(event, SWITCH_STACK_BOTTOM, "Skinny-DeviceToUser-Line-Instance", "%d", request->data.extended_data.line_instance);
switch_event_add_header(event, SWITCH_STACK_BOTTOM, "Skinny-DeviceToUser-Call-Id", "%d", request->data.extended_data.call_id);
switch_event_add_header(event, SWITCH_STACK_BOTTOM, "Skinny-DeviceToUser-Transaction-Id", "%d", request->data.extended_data.transaction_id);
switch_event_add_header(event, SWITCH_STACK_BOTTOM, "Skinny-DeviceToUser-Data-Length", "%d", request->data.extended_data.data_length);
switch_event_add_header(event, SWITCH_STACK_BOTTOM, "Skinny-DeviceToUser-Sequence-Flag", "%d", request->data.extended_data.sequence_flag);
switch_event_add_header(event, SWITCH_STACK_BOTTOM, "Skinny-DeviceToUser-Display-Priority", "%d", request->data.extended_data.display_priority);
switch_event_add_header(event, SWITCH_STACK_BOTTOM, "Skinny-DeviceToUser-Conference-Id", "%d", request->data.extended_data.conference_id);
switch_event_add_header(event, SWITCH_STACK_BOTTOM, "Skinny-DeviceToUser-App-Instance-Id", "%d", request->data.extended_data.app_instance_id);
switch_event_add_header(event, SWITCH_STACK_BOTTOM, "Skinny-DeviceToUser-Routing-Id", "%d", request->data.extended_data.routing_id);
tmp = strndup(request->data.extended_data.data, request->data.extended_data.data_length);
switch_event_add_body(event, tmp);
switch_safe_free(tmp);
switch_event_fire(&event);
return SWITCH_STATUS_SUCCESS;
}
switch_status_t skinny_handle_request(listener_t *listener, skinny_message_t *request)
{
if (listener->profile->debug >= 10 || request->type != KEEP_ALIVE_MESSAGE) {
@ -1961,10 +2014,18 @@ switch_status_t skinny_handle_request(listener_t *listener, skinny_message_t *re
return skinny_headset_status_message(listener, request);
case REGISTER_AVAILABLE_LINES_MESSAGE:
return skinny_handle_register_available_lines_message(listener, request);
case DEVICE_TO_USER_DATA_MESSAGE:
return skinny_handle_data_message(listener, request);
case DEVICE_TO_USER_DATA_RESPONSE_MESSAGE:
return skinny_handle_data_message(listener, request);
case SERVICE_URL_STAT_REQ_MESSAGE:
return skinny_handle_service_url_stat_request(listener, request);
case FEATURE_STAT_REQ_MESSAGE:
return skinny_handle_feature_stat_request(listener, request);
case DEVICE_TO_USER_DATA_VERSION1_MESSAGE:
return skinny_handle_extended_data_message(listener, request);
case DEVICE_TO_USER_DATA_RESPONSE_VERSION1_MESSAGE:
return skinny_handle_extended_data_message(listener, request);
default:
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING,
"Unhandled request %s (type=%x,length=%d).\n", skinny_message_type2str(request->type), request->type, request->length);