Skinny: add support to DeviceToUser and UserToDevice messages
This commit is contained in:
parent
f5e7284d39
commit
25ddef504d
|
@ -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);
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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:
|
||||
|
|
|
@ -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);
|
||||
|
|
Loading…
Reference in New Issue