From 54e73c774fbeb29f94d9f9aff3625977ff537dae Mon Sep 17 00:00:00 2001 From: Mathieu Parent Date: Thu, 1 Apr 2010 19:50:55 +0200 Subject: [PATCH] Skinny: Check for socket to see if listener is alive also, use tab to indent --- src/mod/endpoints/mod_skinny/mod_skinny.c | 357 +- src/mod/endpoints/mod_skinny/mod_skinny.h | 194 +- .../endpoints/mod_skinny/skinny_protocol.c | 3222 ++++++++--------- .../endpoints/mod_skinny/skinny_protocol.h | 694 ++-- src/mod/endpoints/mod_skinny/skinny_tables.c | 222 +- src/mod/endpoints/mod_skinny/skinny_tables.h | 218 +- 6 files changed, 2454 insertions(+), 2453 deletions(-) diff --git a/src/mod/endpoints/mod_skinny/mod_skinny.c b/src/mod/endpoints/mod_skinny/mod_skinny.c index 1bcd6013c7..cd7e4f5965 100644 --- a/src/mod/endpoints/mod_skinny/mod_skinny.c +++ b/src/mod/endpoints/mod_skinny/mod_skinny.c @@ -132,7 +132,7 @@ switch_status_t skinny_profile_dump(const skinny_profile_t *profile, switch_stre skinny_profile_t *skinny_find_profile(const char *profile_name) { - skinny_profile_t *profile; + skinny_profile_t *profile; switch_mutex_lock(globals.mutex); profile = (skinny_profile_t *) switch_core_hash_find(globals.profile_hash, profile_name); switch_mutex_unlock(globals.mutex); @@ -166,7 +166,7 @@ switch_status_t skinny_profile_find_listener_by_device_name_and_instance(skinny_ } struct skinny_profile_find_session_uuid_helper { - skinny_profile_t *profile; + skinny_profile_t *profile; char *channel_uuid; uint32_t line_instance; }; @@ -178,12 +178,12 @@ int skinny_profile_find_session_uuid_callback(void *pArg, int argc, char **argv, char *channel_uuid = argv[0]; uint32_t line_instance = atoi(argv[1]); - if(helper->channel_uuid == NULL) { - helper->channel_uuid = switch_mprintf("%s", channel_uuid); - helper->line_instance = line_instance; - } + if(helper->channel_uuid == NULL) { + helper->channel_uuid = switch_mprintf("%s", channel_uuid); + helper->line_instance = line_instance; + } - return 0; + return 0; } char * skinny_profile_find_session_uuid(skinny_profile_t *profile, listener_t *listener, uint32_t *line_instance_p, uint32_t call_id) @@ -193,28 +193,28 @@ char * skinny_profile_find_session_uuid(skinny_profile_t *profile, listener_t *l char *device_condition = NULL; char *line_instance_condition = NULL; char *call_id_condition = NULL; - + switch_assert(profile); helper.profile = profile; helper.channel_uuid = NULL; - + if(listener) { - device_condition = switch_mprintf("device_name='%s' AND device_instance=%d", - listener->device_name, listener->device_instance); + device_condition = switch_mprintf("device_name='%s' AND device_instance=%d", + listener->device_name, listener->device_instance); } else { - device_condition = switch_mprintf("1=1"); + device_condition = switch_mprintf("1=1"); } switch_assert(device_condition); if(*line_instance_p > 0) { - line_instance_condition = switch_mprintf("line_instance=%d", *line_instance_p); + line_instance_condition = switch_mprintf("line_instance=%d", *line_instance_p); } else { - line_instance_condition = switch_mprintf("1=1"); + line_instance_condition = switch_mprintf("1=1"); } switch_assert(line_instance_condition); if(call_id > 0) { - call_id_condition = switch_mprintf("call_id=%d", call_id); + call_id_condition = switch_mprintf("call_id=%d", call_id); } else { - call_id_condition = switch_mprintf("1=1"); + call_id_condition = switch_mprintf("1=1"); } switch_assert(call_id_condition); if((sql = switch_mprintf( @@ -225,7 +225,7 @@ char * skinny_profile_find_session_uuid(skinny_profile_t *profile, listener_t *l device_condition, line_instance_condition, call_id_condition ))) { skinny_execute_sql_callback(profile, profile->sql_mutex, sql, - skinny_profile_find_session_uuid_callback, &helper); + skinny_profile_find_session_uuid_callback, &helper); switch_safe_free(sql); } switch_safe_free(device_condition); @@ -237,21 +237,21 @@ char * skinny_profile_find_session_uuid(skinny_profile_t *profile, listener_t *l switch_core_session_t * skinny_profile_find_session(skinny_profile_t *profile, listener_t *listener, uint32_t *line_instance_p, uint32_t call_id) { - char *uuid; - switch_core_session_t *result = NULL; - uuid = skinny_profile_find_session_uuid(profile, listener, line_instance_p, call_id); + char *uuid; + switch_core_session_t *result = NULL; + uuid = skinny_profile_find_session_uuid(profile, listener, line_instance_p, call_id); - if(!zstr(uuid)) { - /* TODO Why should we force? */ - result = switch_core_session_force_locate(uuid); + if(!zstr(uuid)) { + /* TODO Why should we force? */ + result = switch_core_session_force_locate(uuid); if(!result) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, - "Unable to find session %s on %s:%d, line %d\n", - uuid, listener->device_name, listener->device_instance, *line_instance_p); + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, + "Unable to find session %s on %s:%d, line %d\n", + uuid, listener->device_name, listener->device_instance, *line_instance_p); } switch_safe_free(uuid); - } - return result; + } + return result; } /*****************************************************************************/ @@ -337,7 +337,7 @@ switch_bool_t skinny_execute_sql_callback(skinny_profile_t *profile, void skinny_line_perform_set_state(const char *file, const char *func, int line, listener_t *listener, uint32_t line_instance, uint32_t call_id, uint32_t call_state) { switch_event_t *event = NULL; - switch_assert(listener); + switch_assert(listener); skinny_device_event(listener, &event, SWITCH_EVENT_CUSTOM, SKINNY_EVENT_CALL_STATE); switch_event_add_header(event, SWITCH_STACK_BOTTOM, "Skinny-Line-Instance", "%d", line_instance); @@ -359,30 +359,30 @@ int skinny_line_get_state_callback(void *pArg, int argc, char **argv, char **col { struct skinny_line_get_state_helper *helper = pArg; helper->call_state = atoi(argv[0]); - return 0; + return 0; } uint32_t skinny_line_get_state(listener_t *listener, uint32_t line_instance, uint32_t call_id) { - char *line_instance_condition; - char *call_id_condition; - char *sql; + char *line_instance_condition; + char *call_id_condition; + char *sql; struct skinny_line_get_state_helper helper = {0}; - switch_assert(listener); - - if(line_instance > 0) { - line_instance_condition = switch_mprintf("line_instance=%d", line_instance); - } else { - line_instance_condition = switch_mprintf("1=1"); - } - switch_assert(line_instance_condition); - if(call_id > 0) { - call_id_condition = switch_mprintf("call_id=%d", call_id); - } else { - call_id_condition = switch_mprintf("1=1"); - } - switch_assert(call_id_condition); + switch_assert(listener); + + if(line_instance > 0) { + line_instance_condition = switch_mprintf("line_instance=%d", line_instance); + } else { + line_instance_condition = switch_mprintf("1=1"); + } + switch_assert(line_instance_condition); + if(call_id > 0) { + call_id_condition = switch_mprintf("call_id=%d", call_id); + } else { + call_id_condition = switch_mprintf("1=1"); + } + switch_assert(call_id_condition); if ((sql = switch_mprintf( "SELECT call_state FROM skinny_active_lines " @@ -396,7 +396,7 @@ uint32_t skinny_line_get_state(listener_t *listener, uint32_t line_instance, uin } switch_safe_free(line_instance_condition); switch_safe_free(call_id_condition); - + return helper.call_state; } @@ -419,11 +419,11 @@ switch_status_t skinny_tech_set_codec(private_t *tech_pvt, int force) if (strcasecmp(tech_pvt->read_impl.iananame, tech_pvt->iananame) || tech_pvt->read_impl.samples_per_second != tech_pvt->rm_rate || tech_pvt->codec_ms != (uint32_t)tech_pvt->read_impl.microseconds_per_packet / 1000) { - + switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(tech_pvt->session), SWITCH_LOG_DEBUG, "Changing Codec from %s@%dms to %s@%dms\n", tech_pvt->read_impl.iananame, tech_pvt->read_impl.microseconds_per_packet / 1000, tech_pvt->rm_encoding, tech_pvt->codec_ms); - + switch_core_session_lock_codec_write(tech_pvt->session); switch_core_session_lock_codec_read(tech_pvt->session); resetting = 1; @@ -434,7 +434,7 @@ switch_status_t skinny_tech_set_codec(private_t *tech_pvt, int force) switch_goto_status(SWITCH_STATUS_SUCCESS, end); } } - + if (switch_core_codec_init(&tech_pvt->read_codec, tech_pvt->iananame, tech_pvt->rm_fmtp, @@ -526,7 +526,7 @@ void tech_init(private_t *tech_pvt, skinny_profile_t *profile, switch_core_sessi { switch_assert(tech_pvt); switch_assert(session); - + tech_pvt->read_frame.data = tech_pvt->databuf; tech_pvt->read_frame.buflen = sizeof(tech_pvt->databuf); switch_mutex_init(&tech_pvt->mutex, SWITCH_MUTEX_NESTED, switch_core_session_get_pool(session)); @@ -562,7 +562,7 @@ switch_status_t channel_on_init(switch_core_session_t *session) switch_status_t channel_on_routing(switch_core_session_t *session) { - switch_channel_t *channel = switch_core_session_get_channel(session); + switch_channel_t *channel = switch_core_session_get_channel(session); switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "%s CHANNEL ROUTING\n", switch_channel_get_name(channel)); @@ -571,7 +571,7 @@ switch_status_t channel_on_routing(switch_core_session_t *session) switch_status_t channel_on_execute(switch_core_session_t *session) { - switch_channel_t *channel = switch_core_session_get_channel(session); + switch_channel_t *channel = switch_core_session_get_channel(session); switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "%s CHANNEL EXECUTE\n", switch_channel_get_name(channel)); @@ -588,7 +588,7 @@ switch_status_t channel_on_destroy(switch_core_session_t *session) if (switch_core_codec_ready(&tech_pvt->read_codec)) { switch_core_codec_destroy(&tech_pvt->read_codec); } - + if (switch_core_codec_ready(&tech_pvt->write_codec)) { switch_core_codec_destroy(&tech_pvt->write_codec); } @@ -627,33 +627,33 @@ int channel_on_hangup_callback(void *pArg, int argc, char **argv, char **columnN uint32_t call_state = atoi(argv[16]); skinny_profile_find_listener_by_device_name_and_instance(helper->tech_pvt->profile, device_name, device_instance, &listener); - if(listener) { - if(call_state == SKINNY_CONNECTED) { - stop_tone(listener, line_instance, call_id); - } - set_lamp(listener, SKINNY_BUTTON_LINE, line_instance, SKINNY_LAMP_OFF); - clear_prompt_status(listener, line_instance, call_id); - if(call_state == SKINNY_CONNECTED) { /* calling parties */ - close_receive_channel(listener, - call_id, /* uint32_t conference_id, */ - helper->tech_pvt->party_id, /* uint32_t pass_thru_party_id, */ - call_id /* uint32_t conference_id2, */ - ); - stop_media_transmission(listener, - call_id, /* uint32_t conference_id, */ - helper->tech_pvt->party_id, /* uint32_t pass_thru_party_id, */ - call_id /* uint32_t conference_id2, */ - ); - } + if(listener) { + if(call_state == SKINNY_CONNECTED) { + stop_tone(listener, line_instance, call_id); + } + set_lamp(listener, SKINNY_BUTTON_LINE, line_instance, SKINNY_LAMP_OFF); + clear_prompt_status(listener, line_instance, call_id); + if(call_state == SKINNY_CONNECTED) { /* calling parties */ + close_receive_channel(listener, + call_id, /* uint32_t conference_id, */ + helper->tech_pvt->party_id, /* uint32_t pass_thru_party_id, */ + call_id /* uint32_t conference_id2, */ + ); + stop_media_transmission(listener, + call_id, /* uint32_t conference_id, */ + helper->tech_pvt->party_id, /* uint32_t pass_thru_party_id, */ + call_id /* uint32_t conference_id2, */ + ); + } - skinny_line_set_state(listener, line_instance, call_id, SKINNY_ON_HOOK); - send_select_soft_keys(listener, line_instance, call_id, SKINNY_KEY_SET_ON_HOOK, 0xffff); - /* TODO: DefineTimeDate */ - set_speaker_mode(listener, SKINNY_SPEAKER_OFF); - set_ringer(listener, SKINNY_RING_OFF, SKINNY_RING_FOREVER, 0, call_id); - - } - return 0; + skinny_line_set_state(listener, line_instance, call_id, SKINNY_ON_HOOK); + send_select_soft_keys(listener, line_instance, call_id, SKINNY_KEY_SET_ON_HOOK, 0xffff); + /* TODO: DefineTimeDate */ + set_speaker_mode(listener, SKINNY_SPEAKER_OFF); + set_ringer(listener, SKINNY_RING_OFF, SKINNY_RING_FOREVER, 0, call_id); + + } + return 0; } switch_status_t channel_on_hangup(switch_core_session_t *session) @@ -668,9 +668,9 @@ switch_status_t channel_on_hangup(switch_core_session_t *session) switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "%s CHANNEL HANGUP\n", switch_channel_get_name(channel)); - helper.tech_pvt= tech_pvt; + helper.tech_pvt= tech_pvt; - skinny_session_walk_lines(tech_pvt->profile, switch_core_session_get_uuid(session), channel_on_hangup_callback, &helper); + skinny_session_walk_lines(tech_pvt->profile, switch_core_session_get_uuid(session), channel_on_hangup_callback, &helper); if ((sql = switch_mprintf( "DELETE FROM skinny_active_lines WHERE channel_uuid='%s'", switch_core_session_get_uuid(session) @@ -698,7 +698,7 @@ switch_status_t channel_kill_channel(switch_core_session_t *session, int sig) default: break; } - + switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "%s CHANNEL KILL %d\n", switch_channel_get_name(channel), sig); return SWITCH_STATUS_SUCCESS; @@ -728,7 +728,7 @@ switch_status_t channel_send_dtmf(switch_core_session_t *session, const switch_d switch_status_t channel_read_frame(switch_core_session_t *session, switch_frame_t **frame, switch_io_flag_t flags, int stream_id) { - switch_channel_t *channel = switch_core_session_get_channel(session); + switch_channel_t *channel = switch_core_session_get_channel(session); private_t *tech_pvt = switch_core_session_get_private(session); int payload = 0; @@ -799,7 +799,7 @@ switch_status_t channel_write_frame(switch_core_session_t *session, switch_frame private_t *tech_pvt = switch_core_session_get_private(session); //switch_frame_t *pframe; switch_status_t status = SWITCH_STATUS_SUCCESS; - + if (!switch_test_flag(tech_pvt, TFLAG_IO)) { return SWITCH_STATUS_FALSE; } @@ -850,7 +850,7 @@ switch_call_cause_t channel_outgoing_channel(switch_core_session_t *session, swi switch_call_cause_t cause = SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER; switch_core_session_t *nsession = NULL; private_t *tech_pvt; - + char *profile_name, *dest; skinny_profile_t *profile = NULL; char *sql; @@ -891,12 +891,12 @@ switch_call_cause_t channel_outgoing_channel(switch_core_session_t *session, swi cause = SWITCH_CAUSE_UNALLOCATED_NUMBER; goto error; } - + snprintf(name, sizeof(name), "SKINNY/%s/%s", profile->name, dest); channel = switch_core_session_get_channel(nsession); switch_channel_set_name(channel, name); - + tech_init(tech_pvt, profile, nsession); caller_profile = switch_caller_profile_clone(nsession, outbound_profile); @@ -917,9 +917,9 @@ switch_call_cause_t channel_outgoing_channel(switch_core_session_t *session, swi skinny_execute_sql(profile, sql, profile->sql_mutex); switch_safe_free(sql); } - + cause = skinny_ring_lines(tech_pvt); - + if(cause != SWITCH_CAUSE_SUCCESS) { goto error; } @@ -1001,10 +1001,11 @@ switch_io_routines_t skinny_io_routines = { uint8_t listener_is_ready(listener_t *listener) { - return globals.running - && listener - && switch_test_flag(listener, LFLAG_RUNNING) - && listener->profile->listener_ready; + return globals.running + && listener + && listener->sock + && switch_test_flag(listener, LFLAG_RUNNING) + && listener->profile->listener_ready; } static void add_listener(listener_t *listener) @@ -1049,7 +1050,7 @@ static void walk_listeners(skinny_listener_callback_func_t callback, void *pvt) void *val; skinny_profile_t *profile; listener_t *l; - + /* walk listeners */ switch_mutex_lock(globals.mutex); for (hi = switch_hash_first(NULL, globals.profile_hash); hi; hi = switch_hash_next(hi)) { @@ -1071,7 +1072,7 @@ static void flush_listener(listener_t *listener, switch_bool_t flush_log, switch if(!zstr(listener->device_name)) { skinny_profile_t *profile = listener->profile; char *sql; - + if ((sql = switch_mprintf( "DELETE FROM skinny_devices " "WHERE name='%s' and instance=%d", @@ -1180,7 +1181,7 @@ switch_status_t keepalive_listener(listener_t *listener, void *pvt) switch_assert(listener); assert(listener->profile); profile = listener->profile; - + listener->expire_time = switch_epoch_time_now(NULL)+profile->keep_alive*110/100; return SWITCH_STATUS_SUCCESS; @@ -1201,9 +1202,9 @@ static void *SWITCH_THREAD_FUNC listener_run(switch_thread_t *thread, void *obj) switch_mutex_lock(profile->listener_mutex); profile->listener_threads++; switch_mutex_unlock(profile->listener_mutex); - + switch_assert(listener != NULL); - + switch_socket_opt_set(listener->sock, SWITCH_SO_TCP_NODELAY, TRUE); switch_socket_opt_set(listener->sock, SWITCH_SO_NONBLOCK, TRUE); @@ -1260,7 +1261,7 @@ static void *SWITCH_THREAD_FUNC listener_run(switch_thread_t *thread, void *obj) switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Connection Closed\n"); } - /* TODO + /* TODO for(int line = 0 ; line < SKINNY_MAX_BUTTON_COUNT ; line++) { if(listener->session[line]) { switch_channel_clear_flag(switch_core_session_get_channel(listener->session[line]), CF_CONTROLLED); @@ -1362,7 +1363,7 @@ static void *SWITCH_THREAD_FUNC skinny_profile_run(switch_thread_t *thread, void errs = 0; } - + if (!(listener = switch_core_alloc(listener_pool, sizeof(*listener)))) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Memory Error\n"); break; @@ -1388,7 +1389,7 @@ static void *SWITCH_THREAD_FUNC skinny_profile_run(switch_thread_t *thread, void end: close_socket(&profile->sock, profile); - + if (tmp_pool) { switch_core_destroy_memory_pool(&tmp_pool); } @@ -1461,23 +1462,23 @@ static switch_status_t load_skinny_config(void) continue; } if (xsettings) { - switch_memory_pool_t *profile_pool = NULL; + switch_memory_pool_t *profile_pool = NULL; char dbname[256]; switch_core_db_t *db; skinny_profile_t *profile = NULL; switch_xml_t param; - - if (switch_core_new_memory_pool(&profile_pool) != SWITCH_STATUS_SUCCESS) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "OH OH no pool\n"); - return SWITCH_STATUS_TERM; - } + + if (switch_core_new_memory_pool(&profile_pool) != SWITCH_STATUS_SUCCESS) { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "OH OH no pool\n"); + return SWITCH_STATUS_TERM; + } profile = switch_core_alloc(profile_pool, sizeof(skinny_profile_t)); profile->pool = profile_pool; profile->name = profile_name; - switch_mutex_init(&profile->listener_mutex, SWITCH_MUTEX_NESTED, profile->pool); - switch_mutex_init(&profile->sql_mutex, SWITCH_MUTEX_NESTED, profile->pool); - switch_mutex_init(&profile->sock_mutex, SWITCH_MUTEX_NESTED, profile->pool); - + switch_mutex_init(&profile->listener_mutex, SWITCH_MUTEX_NESTED, profile->pool); + switch_mutex_init(&profile->sql_mutex, SWITCH_MUTEX_NESTED, profile->pool); + switch_mutex_init(&profile->sock_mutex, SWITCH_MUTEX_NESTED, profile->pool); + for (param = switch_xml_child(xsettings, "param"); param; param = param->next) { char *var = (char *) switch_xml_attr_soft(param, "name"); char *val = (char *) switch_xml_attr_soft(param, "value"); @@ -1502,7 +1503,7 @@ static switch_status_t load_skinny_config(void) profile->debug = atoi(val); } } /* param */ - + if (!profile->dialplan) { skinny_profile_set(profile, "dialplan","default"); } @@ -1546,15 +1547,15 @@ static switch_status_t load_skinny_config(void) } switch_core_db_close(db); } - + skinny_execute_sql_callback(profile, profile->sql_mutex, "DELETE FROM skinny_devices", NULL, NULL); skinny_execute_sql_callback(profile, profile->sql_mutex, "DELETE FROM skinny_lines", NULL, NULL); skinny_execute_sql_callback(profile, profile->sql_mutex, "DELETE FROM skinny_buttons", NULL, NULL); skinny_execute_sql_callback(profile, profile->sql_mutex, "DELETE FROM skinny_active_lines", NULL, NULL); - switch_mutex_lock(globals.mutex); - switch_core_hash_insert(globals.profile_hash, profile->name, profile); - switch_mutex_unlock(globals.mutex); + switch_mutex_lock(globals.mutex); + switch_core_hash_insert(globals.profile_hash, profile->name, profile); + switch_mutex_unlock(globals.mutex); profile = NULL; } else { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, @@ -1575,50 +1576,50 @@ static void event_handler(switch_event_t *event) if (event->event_id == SWITCH_EVENT_HEARTBEAT) { walk_listeners(kill_expired_listener, NULL); } else if ((subclass = switch_event_get_header_nil(event, "Event-Subclass")) && !strcasecmp(subclass, SKINNY_EVENT_CALL_STATE)) { - char *profile_name = switch_event_get_header_nil(event, "Skinny-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-Device-Instance")); + char *profile_name = switch_event_get_header_nil(event, "Skinny-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-Device-Instance")); uint32_t line_instance = atoi(switch_event_get_header_nil(event, "Skinny-Line-Instance")); uint32_t call_id = atoi(switch_event_get_header_nil(event, "Skinny-Call-Id")); uint32_t call_state = atoi(switch_event_get_header_nil(event, "Skinny-Call-State")); - skinny_profile_t *profile; - listener_t *listener = NULL; - char *line_instance_condition, *call_id_condition; - char *sql; + skinny_profile_t *profile; + listener_t *listener = NULL; + char *line_instance_condition, *call_id_condition; + char *sql; - if ((profile = skinny_find_profile(profile_name))) { - skinny_profile_find_listener_by_device_name_and_instance(profile, device_name, device_instance, &listener); - if(listener) { - if(line_instance > 0) { - line_instance_condition = switch_mprintf("line_instance=%d", line_instance); - } else { - line_instance_condition = switch_mprintf("1=1"); - } - switch_assert(line_instance_condition); - if(call_id > 0) { - call_id_condition = switch_mprintf("call_id=%d", call_id); - } else { - call_id_condition = switch_mprintf("1=1"); - } - switch_assert(call_id_condition); + if ((profile = skinny_find_profile(profile_name))) { + skinny_profile_find_listener_by_device_name_and_instance(profile, device_name, device_instance, &listener); + if(listener) { + if(line_instance > 0) { + line_instance_condition = switch_mprintf("line_instance=%d", line_instance); + } else { + line_instance_condition = switch_mprintf("1=1"); + } + switch_assert(line_instance_condition); + if(call_id > 0) { + call_id_condition = switch_mprintf("call_id=%d", call_id); + } else { + call_id_condition = switch_mprintf("1=1"); + } + switch_assert(call_id_condition); - if ((sql = switch_mprintf( - "UPDATE skinny_active_lines " - "SET call_state=%d " - "WHERE device_name='%s' AND device_instance=%d " - "AND %s AND %s", - call_state, - listener->device_name, listener->device_instance, - line_instance_condition, call_id_condition - ))) { - skinny_execute_sql(listener->profile, sql, listener->profile->sql_mutex); - switch_safe_free(sql); - send_call_state(listener, call_state, line_instance, call_id); - } - switch_safe_free(line_instance_condition); - switch_safe_free(call_id_condition); - } - } + if ((sql = switch_mprintf( + "UPDATE skinny_active_lines " + "SET call_state=%d " + "WHERE device_name='%s' AND device_instance=%d " + "AND %s AND %s", + call_state, + listener->device_name, listener->device_instance, + line_instance_condition, call_id_condition + ))) { + skinny_execute_sql(listener->profile, sql, listener->profile->sql_mutex); + switch_safe_free(sql); + send_call_state(listener, call_state, line_instance, call_id); + } + switch_safe_free(line_instance_condition); + switch_safe_free(call_id_condition); + } + } } } @@ -1627,20 +1628,20 @@ static void event_handler(switch_event_t *event) SWITCH_MODULE_LOAD_FUNCTION(mod_skinny_load) { switch_hash_index_t *hi; - /* globals init */ + /* globals init */ memset(&globals, 0, sizeof(globals)); - if (switch_core_new_memory_pool(&globals.pool) != SWITCH_STATUS_SUCCESS) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "OH OH no pool\n"); - return SWITCH_STATUS_TERM; - } + if (switch_core_new_memory_pool(&globals.pool) != SWITCH_STATUS_SUCCESS) { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "OH OH no pool\n"); + return SWITCH_STATUS_TERM; + } switch_mutex_init(&globals.mutex, SWITCH_MUTEX_NESTED, globals.pool); switch_core_hash_init(&globals.profile_hash, globals.pool); globals.running = 1; - + load_skinny_config(); - /* bind to events */ + /* bind to events */ 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"); /* Not such severe to prevent loading */ @@ -1650,7 +1651,7 @@ SWITCH_MODULE_LOAD_FUNCTION(mod_skinny_load) return SWITCH_STATUS_TERM; } - /* reserve events */ + /* reserve events */ if (switch_event_reserve_subclass(SKINNY_EVENT_REGISTER) != SWITCH_STATUS_SUCCESS) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Couldn't register subclass %s!\n", SKINNY_EVENT_REGISTER); return SWITCH_STATUS_TERM; @@ -1679,23 +1680,23 @@ SWITCH_MODULE_LOAD_FUNCTION(mod_skinny_load) skinny_endpoint_interface->io_routines = &skinny_io_routines; skinny_endpoint_interface->state_handler = &skinny_state_handlers; - skinny_api_register(module_interface); + skinny_api_register(module_interface); /* launch listeners */ switch_mutex_lock(globals.mutex); for (hi = switch_hash_first(NULL, globals.profile_hash); hi; hi = switch_hash_next(hi)) { - void *val; - skinny_profile_t *profile; - switch_thread_t *thread; - switch_threadattr_t *thd_attr = NULL; + void *val; + skinny_profile_t *profile; + switch_thread_t *thread; + switch_threadattr_t *thd_attr = NULL; switch_hash_this(hi, NULL, NULL, &val); profile = (skinny_profile_t *) val; - - switch_threadattr_create(&thd_attr, profile->pool); - switch_threadattr_detach_set(thd_attr, 1); - switch_threadattr_stacksize_set(thd_attr, SWITCH_THREAD_STACKSIZE); - switch_thread_create(&thread, thd_attr, skinny_profile_run, profile, profile->pool); + + switch_threadattr_create(&thd_attr, profile->pool); + switch_threadattr_detach_set(thd_attr, 1); + switch_threadattr_stacksize_set(thd_attr, SWITCH_THREAD_STACKSIZE); + switch_thread_create(&thread, thd_attr, skinny_profile_run, profile, profile->pool); } switch_mutex_unlock(globals.mutex); @@ -1711,7 +1712,7 @@ SWITCH_MODULE_SHUTDOWN_FUNCTION(mod_skinny_shutdown) switch_mutex_t *mutex = globals.mutex; int sanity = 0; - /* release events */ + /* release events */ switch_event_unbind(&globals.heartbeat_node); switch_event_unbind(&globals.call_state_node); switch_event_free_subclass(SKINNY_EVENT_REGISTER); @@ -1730,7 +1731,7 @@ SWITCH_MODULE_SHUTDOWN_FUNCTION(mod_skinny_shutdown) /* close sockets */ switch_mutex_lock(globals.mutex); for (hi = switch_hash_first(NULL, globals.profile_hash); hi; hi = switch_hash_next(hi)) { - skinny_profile_t *profile; + skinny_profile_t *profile; switch_hash_this(hi, NULL, NULL, &val); profile = (skinny_profile_t *) val; @@ -1743,7 +1744,7 @@ SWITCH_MODULE_SHUTDOWN_FUNCTION(mod_skinny_shutdown) break; } } - switch_core_destroy_memory_pool(&profile->pool); + switch_core_destroy_memory_pool(&profile->pool); } switch_mutex_unlock(globals.mutex); diff --git a/src/mod/endpoints/mod_skinny/mod_skinny.h b/src/mod/endpoints/mod_skinny/mod_skinny.h index 80a2040946..7bcc40b96c 100644 --- a/src/mod/endpoints/mod_skinny/mod_skinny.h +++ b/src/mod/endpoints/mod_skinny/mod_skinny.h @@ -45,51 +45,51 @@ #define SKINNY_EVENT_CALL_STATE "skinny::call_state" struct skinny_globals { - int running; - switch_memory_pool_t *pool; - switch_mutex_t *mutex; - switch_hash_t *profile_hash; - switch_event_node_t *heartbeat_node; - switch_event_node_t *call_state_node; + int running; + switch_memory_pool_t *pool; + switch_mutex_t *mutex; + switch_hash_t *profile_hash; + switch_event_node_t *heartbeat_node; + switch_event_node_t *call_state_node; }; typedef struct skinny_globals skinny_globals_t; skinny_globals_t globals; struct skinny_profile { - /* prefs */ - char *name; - char *domain; - char *ip; - unsigned int port; - char *dialplan; - char *context; - uint32_t keep_alive; - char date_format[6]; - int debug; - /* db */ - char *dbname; - char *odbc_dsn; - char *odbc_user; - char *odbc_pass; - switch_odbc_handle_t *master_odbc; - switch_mutex_t *sql_mutex; - /* stats */ - uint32_t ib_calls; - uint32_t ob_calls; - uint32_t ib_failed_calls; - uint32_t ob_failed_calls; - /* listener */ - int listener_threads; - switch_mutex_t *listener_mutex; - switch_socket_t *sock; - switch_mutex_t *sock_mutex; - struct listener *listeners; - uint8_t listener_ready; - /* call id */ - uint32_t next_call_id; - /* others */ - switch_memory_pool_t *pool; + /* prefs */ + char *name; + char *domain; + char *ip; + unsigned int port; + char *dialplan; + char *context; + uint32_t keep_alive; + char date_format[6]; + int debug; + /* db */ + char *dbname; + char *odbc_dsn; + char *odbc_user; + char *odbc_pass; + switch_odbc_handle_t *master_odbc; + switch_mutex_t *sql_mutex; + /* stats */ + uint32_t ib_calls; + uint32_t ob_calls; + uint32_t ib_failed_calls; + uint32_t ob_failed_calls; + /* listener */ + int listener_threads; + switch_mutex_t *listener_mutex; + switch_socket_t *sock; + switch_mutex_t *sock_mutex; + struct listener *listeners; + uint8_t listener_ready; + /* call id */ + uint32_t next_call_id; + /* others */ + switch_memory_pool_t *pool; }; typedef struct skinny_profile skinny_profile_t; @@ -99,26 +99,26 @@ typedef struct skinny_profile skinny_profile_t; /*****************************************************************************/ typedef enum { - LFLAG_RUNNING = (1 << 0), + LFLAG_RUNNING = (1 << 0), } event_flag_t; #define SKINNY_MAX_LINES 42 struct listener { - skinny_profile_t *profile; - char device_name[16]; - uint32_t device_instance; + skinny_profile_t *profile; + char device_name[16]; + uint32_t device_instance; - switch_socket_t *sock; - switch_memory_pool_t *pool; - switch_thread_rwlock_t *rwlock; - switch_sockaddr_t *sa; - char remote_ip[50]; - switch_mutex_t *flag_mutex; - uint32_t flags; - switch_port_t remote_port; - uint32_t id; - time_t expire_time; - struct listener *next; + switch_socket_t *sock; + switch_memory_pool_t *pool; + switch_thread_rwlock_t *rwlock; + switch_sockaddr_t *sa; + char remote_ip[50]; + switch_mutex_t *flag_mutex; + uint32_t flags; + switch_port_t remote_port; + uint32_t id; + time_t expire_time; + struct listener *next; }; typedef struct listener listener_t; @@ -129,54 +129,54 @@ typedef switch_status_t (*skinny_listener_callback_func_t) (listener_t *listener /* CHANNEL TYPES */ /*****************************************************************************/ typedef enum { - TFLAG_IO = (1 << 0), - TFLAG_INBOUND = (1 << 1), - TFLAG_OUTBOUND = (1 << 2), - TFLAG_DTMF = (1 << 3), - TFLAG_VOICE = (1 << 4), - TFLAG_HANGUP = (1 << 5), - TFLAG_LINEAR = (1 << 6), - TFLAG_CODEC = (1 << 7), - - TFLAG_READING = (1 << 9), - TFLAG_WRITING = (1 << 10) + TFLAG_IO = (1 << 0), + TFLAG_INBOUND = (1 << 1), + TFLAG_OUTBOUND = (1 << 2), + TFLAG_DTMF = (1 << 3), + TFLAG_VOICE = (1 << 4), + TFLAG_HANGUP = (1 << 5), + TFLAG_LINEAR = (1 << 6), + TFLAG_CODEC = (1 << 7), + + TFLAG_READING = (1 << 9), + TFLAG_WRITING = (1 << 10) } TFLAGS; typedef enum { - GFLAG_MY_CODEC_PREFS = (1 << 0) + GFLAG_MY_CODEC_PREFS = (1 << 0) } GFLAGS; struct private_object { - unsigned int flags; - switch_frame_t read_frame; - unsigned char databuf[SWITCH_RECOMMENDED_BUFFER_SIZE]; - switch_core_session_t *session; - switch_caller_profile_t *caller_profile; - switch_mutex_t *mutex; - switch_mutex_t *flag_mutex; - /* identification */ - uint32_t call_id; - uint32_t party_id; + unsigned int flags; + switch_frame_t read_frame; + unsigned char databuf[SWITCH_RECOMMENDED_BUFFER_SIZE]; + switch_core_session_t *session; + switch_caller_profile_t *caller_profile; + switch_mutex_t *mutex; + switch_mutex_t *flag_mutex; + /* identification */ + uint32_t call_id; + uint32_t party_id; - skinny_profile_t *profile; + skinny_profile_t *profile; - /* codec */ - char *iananame; - switch_codec_t read_codec; - switch_codec_t write_codec; - switch_codec_implementation_t read_impl; - switch_codec_implementation_t write_impl; - unsigned long rm_rate; - uint32_t codec_ms; - char *rm_encoding; - char *rm_fmtp; - switch_payload_t agreed_pt; - /* RTP */ - switch_rtp_t *rtp_session; - char *local_sdp_audio_ip; - switch_port_t local_sdp_audio_port; - char *remote_sdp_audio_ip; - switch_port_t remote_sdp_audio_port; + /* codec */ + char *iananame; + switch_codec_t read_codec; + switch_codec_t write_codec; + switch_codec_implementation_t read_impl; + switch_codec_implementation_t write_impl; + unsigned long rm_rate; + uint32_t codec_ms; + char *rm_encoding; + char *rm_fmtp; + switch_payload_t agreed_pt; + /* RTP */ + switch_rtp_t *rtp_session; + char *local_sdp_audio_ip; + switch_port_t local_sdp_audio_port; + char *remote_sdp_audio_ip; + switch_port_t remote_sdp_audio_port; }; typedef struct private_object private_t; @@ -197,7 +197,7 @@ switch_status_t dump_device(skinny_profile_t *profile, const char *device_name, /*****************************************************************************/ void skinny_execute_sql(skinny_profile_t *profile, char *sql, switch_mutex_t *mutex); switch_bool_t skinny_execute_sql_callback(skinny_profile_t *profile, - switch_mutex_t *mutex, char *sql, switch_core_db_callback_func_t callback, void *pdata); + switch_mutex_t *mutex, char *sql, switch_core_db_callback_func_t callback, void *pdata); /*****************************************************************************/ /* LISTENER FUNCTIONS */ @@ -222,8 +222,8 @@ switch_status_t channel_on_routing(switch_core_session_t *session); switch_status_t channel_on_exchange_media(switch_core_session_t *session); switch_status_t channel_on_soft_execute(switch_core_session_t *session); switch_call_cause_t channel_outgoing_channel(switch_core_session_t *session, switch_event_t *var_event, - switch_caller_profile_t *outbound_profile, - switch_core_session_t **new_session, switch_memory_pool_t **pool, switch_originate_flag_t flags, switch_call_cause_t *cancel_cause); + switch_caller_profile_t *outbound_profile, + switch_core_session_t **new_session, switch_memory_pool_t **pool, switch_originate_flag_t flags, switch_call_cause_t *cancel_cause); switch_status_t channel_read_frame(switch_core_session_t *session, switch_frame_t **frame, switch_io_flag_t flags, int stream_id); switch_status_t channel_write_frame(switch_core_session_t *session, switch_frame_t *frame, switch_io_flag_t flags, int stream_id); switch_status_t channel_kill_channel(switch_core_session_t *session, int sig); diff --git a/src/mod/endpoints/mod_skinny/skinny_protocol.c b/src/mod/endpoints/mod_skinny/skinny_protocol.c index 1211e7fce4..974398fd5b 100644 --- a/src/mod/endpoints/mod_skinny/skinny_protocol.c +++ b/src/mod/endpoints/mod_skinny/skinny_protocol.c @@ -37,26 +37,26 @@ skinny_globals_t globals; struct soft_key_template_definition soft_key_template_default[] = { - { "\200\001", SOFTKEY_REDIAL }, - { "\200\002", SOFTKEY_NEWCALL }, - { "\200\003", SOFTKEY_HOLD }, - { "\200\004", SOFTKEY_TRANSFER }, - { "\200\005", SOFTKEY_CFWDALL }, - { "\200\006", SOFTKEY_CFWDBUSY }, - { "\200\007", SOFTKEY_CFWDNOANSWER }, - { "\200\010", SOFTKEY_BACKSPACE }, - { "\200\011", SOFTKEY_ENDCALL }, - { "\200\012", SOFTKEY_RESUME }, - { "\200\013", SOFTKEY_ANSWER }, - { "\200\014", SOFTKEY_INFO }, - { "\200\015", SOFTKEY_CONFRM }, - { "\200\016", SOFTKEY_PARK }, - { "\200\017", SOFTKEY_JOIN }, - { "\200\020", SOFTKEY_MEETMECONFRM }, - { "\200\021", SOFTKEY_CALLPICKUP }, - { "\200\022", SOFTKEY_GRPCALLPICKUP }, - { "\200\077", SOFTKEY_DND }, - { "\200\120", SOFTKEY_IDIVERT }, + { "\200\001", SOFTKEY_REDIAL }, + { "\200\002", SOFTKEY_NEWCALL }, + { "\200\003", SOFTKEY_HOLD }, + { "\200\004", SOFTKEY_TRANSFER }, + { "\200\005", SOFTKEY_CFWDALL }, + { "\200\006", SOFTKEY_CFWDBUSY }, + { "\200\007", SOFTKEY_CFWDNOANSWER }, + { "\200\010", SOFTKEY_BACKSPACE }, + { "\200\011", SOFTKEY_ENDCALL }, + { "\200\012", SOFTKEY_RESUME }, + { "\200\013", SOFTKEY_ANSWER }, + { "\200\014", SOFTKEY_INFO }, + { "\200\015", SOFTKEY_CONFRM }, + { "\200\016", SOFTKEY_PARK }, + { "\200\017", SOFTKEY_JOIN }, + { "\200\020", SOFTKEY_MEETMECONFRM }, + { "\200\021", SOFTKEY_CALLPICKUP }, + { "\200\022", SOFTKEY_GRPCALLPICKUP }, + { "\200\077", SOFTKEY_DND }, + { "\200\120", SOFTKEY_IDIVERT }, }; /*****************************************************************************/ @@ -64,391 +64,391 @@ struct soft_key_template_definition soft_key_template_default[] = { /*****************************************************************************/ char* skinny_codec2string(enum skinny_codecs skinnycodec) { - switch (skinnycodec) { - case SKINNY_CODEC_ALAW_64K: - case SKINNY_CODEC_ALAW_56K: - return "ALAW"; - case SKINNY_CODEC_ULAW_64K: - case SKINNY_CODEC_ULAW_56K: - return "ULAW"; - case SKINNY_CODEC_G722_64K: - case SKINNY_CODEC_G722_56K: - case SKINNY_CODEC_G722_48K: - return "G722"; - case SKINNY_CODEC_G723_1: - return "G723"; - case SKINNY_CODEC_G728: - return "G728"; - case SKINNY_CODEC_G729: - case SKINNY_CODEC_G729A: - return "G729"; - case SKINNY_CODEC_IS11172: - return "IS11172"; - case SKINNY_CODEC_IS13818: - return "IS13818"; - case SKINNY_CODEC_G729B: - case SKINNY_CODEC_G729AB: - return "G729"; - case SKINNY_CODEC_GSM_FULL: - case SKINNY_CODEC_GSM_HALF: - case SKINNY_CODEC_GSM_EFULL: - return "GSM"; - case SKINNY_CODEC_WIDEBAND_256K: - return "WIDEBAND"; - case SKINNY_CODEC_DATA_64K: - case SKINNY_CODEC_DATA_56K: - return "DATA"; - case SKINNY_CODEC_GSM: - return "GSM"; - case SKINNY_CODEC_ACTIVEVOICE: - return "ACTIVEVOICE"; - case SKINNY_CODEC_G726_32K: - case SKINNY_CODEC_G726_24K: - case SKINNY_CODEC_G726_16K: - return "G726"; - case SKINNY_CODEC_G729B_BIS: - case SKINNY_CODEC_G729B_LOW: - return "G729"; - case SKINNY_CODEC_H261: - return "H261"; - case SKINNY_CODEC_H263: - return "H263"; - case SKINNY_CODEC_VIDEO: - return "VIDEO"; - case SKINNY_CODEC_T120: - return "T120"; - case SKINNY_CODEC_H224: - return "H224"; - case SKINNY_CODEC_RFC2833_DYNPAYLOAD: - return "RFC2833_DYNPAYLOAD"; - default: - return ""; - } + switch (skinnycodec) { + case SKINNY_CODEC_ALAW_64K: + case SKINNY_CODEC_ALAW_56K: + return "ALAW"; + case SKINNY_CODEC_ULAW_64K: + case SKINNY_CODEC_ULAW_56K: + return "ULAW"; + case SKINNY_CODEC_G722_64K: + case SKINNY_CODEC_G722_56K: + case SKINNY_CODEC_G722_48K: + return "G722"; + case SKINNY_CODEC_G723_1: + return "G723"; + case SKINNY_CODEC_G728: + return "G728"; + case SKINNY_CODEC_G729: + case SKINNY_CODEC_G729A: + return "G729"; + case SKINNY_CODEC_IS11172: + return "IS11172"; + case SKINNY_CODEC_IS13818: + return "IS13818"; + case SKINNY_CODEC_G729B: + case SKINNY_CODEC_G729AB: + return "G729"; + case SKINNY_CODEC_GSM_FULL: + case SKINNY_CODEC_GSM_HALF: + case SKINNY_CODEC_GSM_EFULL: + return "GSM"; + case SKINNY_CODEC_WIDEBAND_256K: + return "WIDEBAND"; + case SKINNY_CODEC_DATA_64K: + case SKINNY_CODEC_DATA_56K: + return "DATA"; + case SKINNY_CODEC_GSM: + return "GSM"; + case SKINNY_CODEC_ACTIVEVOICE: + return "ACTIVEVOICE"; + case SKINNY_CODEC_G726_32K: + case SKINNY_CODEC_G726_24K: + case SKINNY_CODEC_G726_16K: + return "G726"; + case SKINNY_CODEC_G729B_BIS: + case SKINNY_CODEC_G729B_LOW: + return "G729"; + case SKINNY_CODEC_H261: + return "H261"; + case SKINNY_CODEC_H263: + return "H263"; + case SKINNY_CODEC_VIDEO: + return "VIDEO"; + case SKINNY_CODEC_T120: + return "T120"; + case SKINNY_CODEC_H224: + return "H224"; + case SKINNY_CODEC_RFC2833_DYNPAYLOAD: + return "RFC2833_DYNPAYLOAD"; + default: + return ""; + } } /*****************************************************************************/ switch_status_t skinny_read_packet(listener_t *listener, skinny_message_t **req) { - skinny_message_t *request; - switch_size_t mlen, bytes = 0; - char mbuf[SKINNY_MESSAGE_MAXSIZE] = ""; - char *ptr; - switch_status_t status = SWITCH_STATUS_SUCCESS; + skinny_message_t *request; + switch_size_t mlen, bytes = 0; + char mbuf[SKINNY_MESSAGE_MAXSIZE] = ""; + char *ptr; + switch_status_t status = SWITCH_STATUS_SUCCESS; - request = switch_core_alloc(listener->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"); - return SWITCH_STATUS_MEMERR; - } + if (!request) { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Unable to allocate memory.\n"); + return SWITCH_STATUS_MEMERR; + } + + if (!listener_is_ready(listener)) { + return SWITCH_STATUS_FALSE; + } + + ptr = mbuf; + + while (listener_is_ready(listener)) { + uint8_t do_sleep = 1; + if(bytes < SKINNY_MESSAGE_FIELD_SIZE) { + /* We have nothing yet, get length header field */ + mlen = SKINNY_MESSAGE_FIELD_SIZE - bytes; + } else { + /* We now know the message size */ + mlen = request->length + 2*SKINNY_MESSAGE_FIELD_SIZE - bytes; + } + + status = switch_socket_recv(listener->sock, ptr, &mlen); - if (!listener_is_ready(listener)) { - return SWITCH_STATUS_FALSE; - } - - ptr = mbuf; - - while (listener->sock && listener_is_ready(listener)) { - uint8_t do_sleep = 1; - if(bytes < SKINNY_MESSAGE_FIELD_SIZE) { - /* We have nothing yet, get length header field */ - mlen = SKINNY_MESSAGE_FIELD_SIZE - bytes; - } else { - /* We now know the message size */ - mlen = request->length + 2*SKINNY_MESSAGE_FIELD_SIZE - bytes; - } - - status = switch_socket_recv(listener->sock, ptr, &mlen); + if (!listener_is_ready(listener) || (!SWITCH_STATUS_IS_BREAK(status) && status != SWITCH_STATUS_SUCCESS)) { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "Socket break.\n"); + return SWITCH_STATUS_FALSE; + } + + if(mlen) { + bytes += mlen; - if (!listener_is_ready(listener) || (!SWITCH_STATUS_IS_BREAK(status) && status != SWITCH_STATUS_SUCCESS)) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "Socket break.\n"); - return SWITCH_STATUS_FALSE; - } - - if(mlen) { - bytes += mlen; - - if(bytes >= SKINNY_MESSAGE_FIELD_SIZE) { - do_sleep = 0; - ptr += mlen; - memcpy(request, mbuf, bytes); + if(bytes >= SKINNY_MESSAGE_FIELD_SIZE) { + do_sleep = 0; + ptr += mlen; + memcpy(request, mbuf, bytes); #ifdef SKINNY_MEGA_DEBUG - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, - "Got request: length=%d,reserved=%x,type=%x\n", - request->length,request->reserved,request->type); + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, + "Got request: length=%d,reserved=%x,type=%x\n", + request->length,request->reserved,request->type); #endif - if(request->length < SKINNY_MESSAGE_FIELD_SIZE) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, - "Skinny client sent invalid data. Length should be greater than 4 but got %d.\n", - request->length); - return SWITCH_STATUS_FALSE; - } - if(request->length + 2*SKINNY_MESSAGE_FIELD_SIZE > SKINNY_MESSAGE_MAXSIZE) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, - "Skinny client sent too huge data. Got %d which is above threshold %d.\n", - request->length, SKINNY_MESSAGE_MAXSIZE - 2*SKINNY_MESSAGE_FIELD_SIZE); - return SWITCH_STATUS_FALSE; - } - if(bytes >= request->length + 2*SKINNY_MESSAGE_FIELD_SIZE) { - /* Message body */ + if(request->length < SKINNY_MESSAGE_FIELD_SIZE) { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, + "Skinny client sent invalid data. Length should be greater than 4 but got %d.\n", + request->length); + return SWITCH_STATUS_FALSE; + } + if(request->length + 2*SKINNY_MESSAGE_FIELD_SIZE > SKINNY_MESSAGE_MAXSIZE) { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, + "Skinny client sent too huge data. Got %d which is above threshold %d.\n", + request->length, SKINNY_MESSAGE_MAXSIZE - 2*SKINNY_MESSAGE_FIELD_SIZE); + return SWITCH_STATUS_FALSE; + } + if(bytes >= request->length + 2*SKINNY_MESSAGE_FIELD_SIZE) { + /* Message body */ #ifdef SKINNY_MEGA_DEBUG - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, - "Got complete request: length=%d,reserved=%x,type=%x,data=%d\n", - request->length,request->reserved,request->type,request->data.as_char); + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, + "Got complete request: length=%d,reserved=%x,type=%x,data=%d\n", + request->length,request->reserved,request->type,request->data.as_char); #endif - *req = request; - return SWITCH_STATUS_SUCCESS; - } - } - } - 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; - } - if (do_sleep) { - switch_cond_next(); - } - } - return SWITCH_STATUS_SUCCESS; + *req = request; + return SWITCH_STATUS_SUCCESS; + } + } + } + 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; + } + if (do_sleep) { + switch_cond_next(); + } + } + return SWITCH_STATUS_SUCCESS; } /*****************************************************************************/ int skinny_device_event_callback(void *pArg, int argc, char **argv, char **columnNames) { - switch_event_t *event = (switch_event_t *) pArg; + switch_event_t *event = (switch_event_t *) pArg; - char *profile_name = argv[0]; - char *device_name = argv[1]; - char *user_id = argv[2]; - char *device_instance = argv[3]; - char *ip = argv[4]; - char *device_type = argv[5]; - char *max_streams = argv[6]; - char *port = argv[7]; - char *codec_string = argv[8]; + char *profile_name = argv[0]; + char *device_name = argv[1]; + char *user_id = argv[2]; + char *device_instance = argv[3]; + char *ip = argv[4]; + char *device_type = argv[5]; + char *max_streams = argv[6]; + char *port = argv[7]; + char *codec_string = argv[8]; - switch_event_add_header(event, SWITCH_STACK_BOTTOM, "Skinny-Profile-Name", "%s", profile_name); - switch_event_add_header(event, SWITCH_STACK_BOTTOM, "Skinny-Device-Name", "%s", device_name); - switch_event_add_header(event, SWITCH_STACK_BOTTOM, "Skinny-Station-User-Id", "%s", user_id); - switch_event_add_header(event, SWITCH_STACK_BOTTOM, "Skinny-Station-Instance", "%s", device_instance); - switch_event_add_header(event, SWITCH_STACK_BOTTOM, "Skinny-IP-Address", "%s", ip); - switch_event_add_header(event, SWITCH_STACK_BOTTOM, "Skinny-Device-Type", "%s", device_type); - switch_event_add_header(event, SWITCH_STACK_BOTTOM, "Skinny-Max-Streams", "%s", max_streams); - switch_event_add_header(event, SWITCH_STACK_BOTTOM, "Skinny-Port", "%s", port); - switch_event_add_header(event, SWITCH_STACK_BOTTOM, "Skinny-Codecs", "%s", codec_string); + switch_event_add_header(event, SWITCH_STACK_BOTTOM, "Skinny-Profile-Name", "%s", profile_name); + switch_event_add_header(event, SWITCH_STACK_BOTTOM, "Skinny-Device-Name", "%s", device_name); + switch_event_add_header(event, SWITCH_STACK_BOTTOM, "Skinny-Station-User-Id", "%s", user_id); + switch_event_add_header(event, SWITCH_STACK_BOTTOM, "Skinny-Station-Instance", "%s", device_instance); + switch_event_add_header(event, SWITCH_STACK_BOTTOM, "Skinny-IP-Address", "%s", ip); + switch_event_add_header(event, SWITCH_STACK_BOTTOM, "Skinny-Device-Type", "%s", device_type); + switch_event_add_header(event, SWITCH_STACK_BOTTOM, "Skinny-Max-Streams", "%s", max_streams); + switch_event_add_header(event, SWITCH_STACK_BOTTOM, "Skinny-Port", "%s", port); + switch_event_add_header(event, SWITCH_STACK_BOTTOM, "Skinny-Codecs", "%s", codec_string); - return 0; + return 0; } switch_status_t skinny_device_event(listener_t *listener, switch_event_t **ev, switch_event_types_t event_id, const char *subclass_name) { - switch_event_t *event = NULL; - char *sql; - skinny_profile_t *profile; - assert(listener->profile); - profile = listener->profile; + switch_event_t *event = NULL; + char *sql; + skinny_profile_t *profile; + assert(listener->profile); + profile = listener->profile; - switch_event_create_subclass(&event, event_id, subclass_name); - switch_assert(event); - if ((sql = switch_mprintf("SELECT '%s', name, user_id, instance, ip, type, max_streams, port, codec_string " - "FROM skinny_devices " - "WHERE name='%s' AND instance=%d", - listener->profile->name, - listener->device_name, listener->device_instance))) { - skinny_execute_sql_callback(profile, profile->sql_mutex, sql, skinny_device_event_callback, event); - switch_safe_free(sql); - } + switch_event_create_subclass(&event, event_id, subclass_name); + switch_assert(event); + if ((sql = switch_mprintf("SELECT '%s', name, user_id, instance, ip, type, max_streams, port, codec_string " + "FROM skinny_devices " + "WHERE name='%s' AND instance=%d", + listener->profile->name, + listener->device_name, listener->device_instance))) { + skinny_execute_sql_callback(profile, profile->sql_mutex, sql, skinny_device_event_callback, event); + switch_safe_free(sql); + } - *ev = event; - return SWITCH_STATUS_SUCCESS; + *ev = event; + return SWITCH_STATUS_SUCCESS; } /*****************************************************************************/ switch_status_t skinny_send_call_info(switch_core_session_t *session, listener_t *listener, uint32_t line_instance) { - private_t *tech_pvt; - switch_channel_t *channel; - - char calling_party_name[40] = "UNKNOWN"; - char calling_party[24] = "0000000000"; - char called_party_name[40] = "UNKNOWN"; - char called_party[24] = "0000000000"; - - channel = switch_core_session_get_channel(session); - tech_pvt = switch_core_session_get_private(session); + private_t *tech_pvt; + switch_channel_t *channel; - switch_assert(tech_pvt->caller_profile != NULL); - - if( switch_channel_test_flag(channel, CF_OUTBOUND) ) { - struct line_stat_res_message *button = NULL; + char calling_party_name[40] = "UNKNOWN"; + char calling_party[24] = "0000000000"; + char called_party_name[40] = "UNKNOWN"; + char called_party[24] = "0000000000"; - skinny_line_get(listener, line_instance, &button); + channel = switch_core_session_get_channel(session); + tech_pvt = switch_core_session_get_private(session); - if (button) { - strncpy(calling_party_name, button->displayname, 40); - strncpy(calling_party, button->name, 24); - } - strncpy(called_party_name, tech_pvt->caller_profile->caller_id_name, 40); - strncpy(called_party, tech_pvt->caller_profile->caller_id_number, 24); - } else { - strncpy(calling_party_name, tech_pvt->caller_profile->caller_id_name, 40); - strncpy(calling_party, tech_pvt->caller_profile->caller_id_number, 24); - /* TODO called party */ - } - send_call_info(listener, - calling_party_name, /* char calling_party_name[40], */ - calling_party, /* char calling_party[24], */ - called_party_name, /* char called_party_name[40], */ - called_party, /* char called_party[24], */ - line_instance, /* uint32_t line_instance, */ - tech_pvt->call_id, /* uint32_t call_id, */ - SKINNY_OUTBOUND_CALL, /* uint32_t call_type, */ - "", /* TODO char original_called_party_name[40], */ - "", /* TODO char original_called_party[24], */ - "", /* TODO char last_redirecting_party_name[40], */ - "", /* TODO char last_redirecting_party[24], */ - 0, /* TODO uint32_t original_called_party_redirect_reason, */ - 0, /* TODO uint32_t last_redirecting_reason, */ - "", /* TODO char calling_party_voice_mailbox[24], */ - "", /* TODO char called_party_voice_mailbox[24], */ - "", /* TODO char original_called_party_voice_mailbox[24], */ - "", /* TODO char last_redirecting_voice_mailbox[24], */ - 1, /* uint32_t call_instance, */ - 1, /* uint32_t call_security_status, */ - 0 /* uint32_t party_pi_restriction_bits */ - ); - return SWITCH_STATUS_SUCCESS; + switch_assert(tech_pvt->caller_profile != NULL); + + if( switch_channel_test_flag(channel, CF_OUTBOUND) ) { + struct line_stat_res_message *button = NULL; + + skinny_line_get(listener, line_instance, &button); + + if (button) { + strncpy(calling_party_name, button->displayname, 40); + strncpy(calling_party, button->name, 24); + } + strncpy(called_party_name, tech_pvt->caller_profile->caller_id_name, 40); + strncpy(called_party, tech_pvt->caller_profile->caller_id_number, 24); + } else { + strncpy(calling_party_name, tech_pvt->caller_profile->caller_id_name, 40); + strncpy(calling_party, tech_pvt->caller_profile->caller_id_number, 24); + /* TODO called party */ + } + send_call_info(listener, + calling_party_name, /* char calling_party_name[40], */ + calling_party, /* char calling_party[24], */ + called_party_name, /* char called_party_name[40], */ + called_party, /* char called_party[24], */ + line_instance, /* uint32_t line_instance, */ + tech_pvt->call_id, /* uint32_t call_id, */ + SKINNY_OUTBOUND_CALL, /* uint32_t call_type, */ + "", /* TODO char original_called_party_name[40], */ + "", /* TODO char original_called_party[24], */ + "", /* TODO char last_redirecting_party_name[40], */ + "", /* TODO char last_redirecting_party[24], */ + 0, /* TODO uint32_t original_called_party_redirect_reason, */ + 0, /* TODO uint32_t last_redirecting_reason, */ + "", /* TODO char calling_party_voice_mailbox[24], */ + "", /* TODO char called_party_voice_mailbox[24], */ + "", /* TODO char original_called_party_voice_mailbox[24], */ + "", /* TODO char last_redirecting_voice_mailbox[24], */ + 1, /* uint32_t call_instance, */ + 1, /* uint32_t call_security_status, */ + 0 /* uint32_t party_pi_restriction_bits */ + ); + return SWITCH_STATUS_SUCCESS; } /*****************************************************************************/ switch_status_t skinny_session_walk_lines(skinny_profile_t *profile, char *channel_uuid, switch_core_db_callback_func_t callback, void *data) { - char *sql; - if ((sql = switch_mprintf( - "SELECT skinny_lines.*, channel_uuid, call_id, call_state " - "FROM skinny_active_lines " - "INNER JOIN skinny_lines " - "ON skinny_active_lines.device_name = skinny_lines.device_name " - "AND skinny_active_lines.device_instance = skinny_lines.device_instance " - "AND skinny_active_lines.line_instance = skinny_lines.line_instance " - "WHERE channel_uuid='%s'", - channel_uuid))) { - skinny_execute_sql_callback(profile, profile->sql_mutex, sql, callback, data); - switch_safe_free(sql); - } - return SWITCH_STATUS_SUCCESS; + char *sql; + if ((sql = switch_mprintf( + "SELECT skinny_lines.*, channel_uuid, call_id, call_state " + "FROM skinny_active_lines " + "INNER JOIN skinny_lines " + "ON skinny_active_lines.device_name = skinny_lines.device_name " + "AND skinny_active_lines.device_instance = skinny_lines.device_instance " + "AND skinny_active_lines.line_instance = skinny_lines.line_instance " + "WHERE channel_uuid='%s'", + channel_uuid))) { + skinny_execute_sql_callback(profile, profile->sql_mutex, sql, callback, data); + switch_safe_free(sql); + } + return SWITCH_STATUS_SUCCESS; } switch_status_t skinny_session_walk_lines_by_call_id(skinny_profile_t *profile, uint32_t call_id, switch_core_db_callback_func_t callback, void *data) { - char *sql; - if ((sql = switch_mprintf( - "SELECT skinny_lines.*, channel_uuid, call_id, call_state " - "FROM skinny_active_lines " - "INNER JOIN skinny_lines " - "ON skinny_active_lines.device_name = skinny_lines.device_name " - "AND skinny_active_lines.device_instance = skinny_lines.device_instance " - "AND skinny_active_lines.line_instance = skinny_lines.line_instance " - "WHERE call_id='%d'", - call_id))) { - skinny_execute_sql_callback(profile, profile->sql_mutex, sql, callback, data); - switch_safe_free(sql); - } - return SWITCH_STATUS_SUCCESS; + char *sql; + if ((sql = switch_mprintf( + "SELECT skinny_lines.*, channel_uuid, call_id, call_state " + "FROM skinny_active_lines " + "INNER JOIN skinny_lines " + "ON skinny_active_lines.device_name = skinny_lines.device_name " + "AND skinny_active_lines.device_instance = skinny_lines.device_instance " + "AND skinny_active_lines.line_instance = skinny_lines.line_instance " + "WHERE call_id='%d'", + call_id))) { + skinny_execute_sql_callback(profile, profile->sql_mutex, sql, callback, data); + switch_safe_free(sql); + } + return SWITCH_STATUS_SUCCESS; } /*****************************************************************************/ struct skinny_ring_lines_helper { - private_t *tech_pvt; - uint32_t lines_count; + private_t *tech_pvt; + uint32_t lines_count; }; int skinny_ring_lines_callback(void *pArg, int argc, char **argv, char **columnNames) { - struct skinny_ring_lines_helper *helper = pArg; - char *tmp; + struct skinny_ring_lines_helper *helper = pArg; + char *tmp; - char *device_name = argv[0]; - uint32_t device_instance = atoi(argv[1]); - /* uint32_t position = atoi(argv[2]); */ - uint32_t line_instance = atoi(argv[3]); - /* char *label = argv[4]; */ - /* char *value = argv[5]; */ - /* char *caller_name = argv[6]; */ - /* uint32_t ring_on_idle = atoi(argv[7]); */ - /* uint32_t ring_on_active = atoi(argv[8]); */ - /* uint32_t busy_trigger = atoi(argv[9]); */ - /* char *forward_all = argv[10]; */ - /* char *forward_busy = argv[11]; */ - /* char *forward_noanswer = argv[12]; */ - /* uint32_t noanswer_duration = atoi(argv[13]); */ - /* char *channel_uuid = argv[14]; */ - /* uint32_t call_id = atoi(argv[15]); */ - /* uint32_t call_state = atoi(argv[16]); */ + char *device_name = argv[0]; + uint32_t device_instance = atoi(argv[1]); + /* uint32_t position = atoi(argv[2]); */ + uint32_t line_instance = atoi(argv[3]); + /* char *label = argv[4]; */ + /* char *value = argv[5]; */ + /* char *caller_name = argv[6]; */ + /* uint32_t ring_on_idle = atoi(argv[7]); */ + /* uint32_t ring_on_active = atoi(argv[8]); */ + /* uint32_t busy_trigger = atoi(argv[9]); */ + /* char *forward_all = argv[10]; */ + /* char *forward_busy = argv[11]; */ + /* char *forward_noanswer = argv[12]; */ + /* uint32_t noanswer_duration = atoi(argv[13]); */ + /* char *channel_uuid = argv[14]; */ + /* uint32_t call_id = atoi(argv[15]); */ + /* uint32_t call_state = atoi(argv[16]); */ - listener_t *listener = NULL; + listener_t *listener = NULL; skinny_profile_find_listener_by_device_name_and_instance(helper->tech_pvt->profile, - device_name, device_instance, &listener); - if(listener) { - helper->lines_count++; - skinny_line_set_state(listener, line_instance, helper->tech_pvt->call_id, SKINNY_RING_IN); - send_select_soft_keys(listener, line_instance, helper->tech_pvt->call_id, SKINNY_KEY_SET_RING_IN, 0xffff); - if ((tmp = switch_mprintf("\200\027%s", helper->tech_pvt->caller_profile->destination_number))) { - display_prompt_status(listener, 0, tmp, line_instance, helper->tech_pvt->call_id); - switch_safe_free(tmp); - } - if ((tmp = switch_mprintf("\005\000\000\000%s", helper->tech_pvt->caller_profile->destination_number))) { + device_name, device_instance, &listener); + if(listener) { + helper->lines_count++; + skinny_line_set_state(listener, line_instance, helper->tech_pvt->call_id, SKINNY_RING_IN); + send_select_soft_keys(listener, line_instance, helper->tech_pvt->call_id, SKINNY_KEY_SET_RING_IN, 0xffff); + if ((tmp = switch_mprintf("\200\027%s", helper->tech_pvt->caller_profile->destination_number))) { + display_prompt_status(listener, 0, tmp, line_instance, helper->tech_pvt->call_id); + switch_safe_free(tmp); + } + if ((tmp = switch_mprintf("\005\000\000\000%s", helper->tech_pvt->caller_profile->destination_number))) { send_display_pri_notify(listener, 10 /* message_timeout */, 5 /* priority */, tmp); - switch_safe_free(tmp); - } - skinny_send_call_info(helper->tech_pvt->session, listener, line_instance); - set_lamp(listener, SKINNY_BUTTON_LINE, line_instance, SKINNY_LAMP_BLINK); - set_ringer(listener, SKINNY_RING_INSIDE, SKINNY_RING_FOREVER, 0, helper->tech_pvt->call_id); - } - return 0; + switch_safe_free(tmp); + } + skinny_send_call_info(helper->tech_pvt->session, listener, line_instance); + set_lamp(listener, SKINNY_BUTTON_LINE, line_instance, SKINNY_LAMP_BLINK); + set_ringer(listener, SKINNY_RING_INSIDE, SKINNY_RING_FOREVER, 0, helper->tech_pvt->call_id); + } + return 0; } switch_call_cause_t skinny_ring_lines(private_t *tech_pvt) { - switch_status_t status; - struct skinny_ring_lines_helper helper = {0}; + switch_status_t status; + struct skinny_ring_lines_helper helper = {0}; - switch_assert(tech_pvt); - switch_assert(tech_pvt->profile); - switch_assert(tech_pvt->session); - - helper.tech_pvt = tech_pvt; - helper.lines_count = 0; - - status = skinny_session_walk_lines(tech_pvt->profile, - switch_core_session_get_uuid(tech_pvt->session), skinny_ring_lines_callback, &helper); - if(status != SWITCH_STATUS_SUCCESS) { - return SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER; - } else if(helper.lines_count == 0) { - return SWITCH_CAUSE_UNALLOCATED_NUMBER; - } else { - return SWITCH_CAUSE_SUCCESS; - } + switch_assert(tech_pvt); + switch_assert(tech_pvt->profile); + switch_assert(tech_pvt->session); + + helper.tech_pvt = tech_pvt; + helper.lines_count = 0; + + status = skinny_session_walk_lines(tech_pvt->profile, + switch_core_session_get_uuid(tech_pvt->session), skinny_ring_lines_callback, &helper); + if(status != SWITCH_STATUS_SUCCESS) { + return SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER; + } else if(helper.lines_count == 0) { + return SWITCH_CAUSE_UNALLOCATED_NUMBER; + } else { + return SWITCH_CAUSE_SUCCESS; + } } /*****************************************************************************/ switch_status_t skinny_create_ingoing_session(listener_t *listener, uint32_t *line_instance_p, switch_core_session_t **session) { - switch_core_session_t *nsession; - switch_channel_t *channel; - private_t *tech_pvt; - char name[128]; - char *sql; - struct line_stat_res_message *button = NULL; + switch_core_session_t *nsession; + switch_channel_t *channel; + private_t *tech_pvt; + char name[128]; + char *sql; + struct line_stat_res_message *button = NULL; if((nsession = skinny_profile_find_session(listener->profile, listener, line_instance_p, 0))) { switch_core_session_rwunlock(nsession); if(skinny_line_get_state(listener, *line_instance_p, 0) == SKINNY_OFF_HOOK) { /* Reuse existing session */ *session = nsession; - return SWITCH_STATUS_SUCCESS; + return SWITCH_STATUS_SUCCESS; } skinny_session_hold_line(nsession, listener, *line_instance_p); } @@ -456,108 +456,108 @@ switch_status_t skinny_create_ingoing_session(listener_t *listener, uint32_t *li *line_instance_p = 1; } - skinny_line_get(listener, *line_instance_p, &button); + skinny_line_get(listener, *line_instance_p, &button); - if (!button || !button->shortname) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Line %d not found on device %s %d\n", - *line_instance_p, listener->device_name, listener->device_instance); - goto error; - } - - if (!(nsession = switch_core_session_request(skinny_get_endpoint_interface(), - SWITCH_CALL_DIRECTION_INBOUND, NULL))) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Error Creating Session\n"); - goto error; - } + if (!button || !button->shortname) { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Line %d not found on device %s %d\n", + *line_instance_p, listener->device_name, listener->device_instance); + goto error; + } - if (!(tech_pvt = (struct private_object *) switch_core_session_alloc(nsession, sizeof(*tech_pvt)))) { - switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(nsession), SWITCH_LOG_CRIT, - "Error Creating Session private object\n"); - goto error; - } + if (!(nsession = switch_core_session_request(skinny_get_endpoint_interface(), + SWITCH_CALL_DIRECTION_INBOUND, NULL))) { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Error Creating Session\n"); + goto error; + } - switch_core_session_add_stream(nsession, NULL); - - tech_init(tech_pvt, listener->profile, nsession); - - channel = switch_core_session_get_channel(nsession); - - snprintf(name, sizeof(name), "SKINNY/%s/%s:%d/%d", listener->profile->name, - listener->device_name, listener->device_instance, *line_instance_p); - switch_channel_set_name(channel, name); - - if (switch_core_session_thread_launch(nsession) != SWITCH_STATUS_SUCCESS) { - switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(nsession), SWITCH_LOG_CRIT, - "Error Creating Session thread\n"); - goto error; - } - - if (!(tech_pvt->caller_profile = switch_caller_profile_new(switch_core_session_get_pool(nsession), - NULL, listener->profile->dialplan, - button->shortname, button->name, - listener->remote_ip, NULL, NULL, NULL, - "skinny" /* modname */, - listener->profile->context, - "")) != 0) { + if (!(tech_pvt = (struct private_object *) switch_core_session_alloc(nsession, sizeof(*tech_pvt)))) { switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(nsession), SWITCH_LOG_CRIT, - "Error Creating Session caller profile\n"); - goto error; - } + "Error Creating Session private object\n"); + goto error; + } - switch_channel_set_caller_profile(channel, tech_pvt->caller_profile); + switch_core_session_add_stream(nsession, NULL); - if ((sql = switch_mprintf( - "INSERT INTO skinny_active_lines " - "(device_name, device_instance, line_instance, channel_uuid, call_id, call_state) " - "SELECT device_name, device_instance, line_instance, '%s', %d, %d " - "FROM skinny_lines " - "WHERE value='%s'", - switch_core_session_get_uuid(nsession), tech_pvt->call_id, SKINNY_ON_HOOK, button->shortname - ))) { - skinny_execute_sql(listener->profile, sql, listener->profile->sql_mutex); - switch_safe_free(sql); - } + tech_init(tech_pvt, listener->profile, nsession); - set_ringer(listener, SKINNY_RING_OFF, SKINNY_RING_FOREVER, 0, tech_pvt->call_id); - set_speaker_mode(listener, SKINNY_SPEAKER_ON); - set_lamp(listener, SKINNY_BUTTON_LINE, *line_instance_p, SKINNY_LAMP_ON); + channel = switch_core_session_get_channel(nsession); + + snprintf(name, sizeof(name), "SKINNY/%s/%s:%d/%d", listener->profile->name, + listener->device_name, listener->device_instance, *line_instance_p); + switch_channel_set_name(channel, name); + + if (switch_core_session_thread_launch(nsession) != SWITCH_STATUS_SUCCESS) { + switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(nsession), SWITCH_LOG_CRIT, + "Error Creating Session thread\n"); + goto error; + } + + if (!(tech_pvt->caller_profile = switch_caller_profile_new(switch_core_session_get_pool(nsession), + NULL, listener->profile->dialplan, + button->shortname, button->name, + listener->remote_ip, NULL, NULL, NULL, + "skinny" /* modname */, + listener->profile->context, + "")) != 0) { + switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(nsession), SWITCH_LOG_CRIT, + "Error Creating Session caller profile\n"); + goto error; + } + + switch_channel_set_caller_profile(channel, tech_pvt->caller_profile); + + if ((sql = switch_mprintf( + "INSERT INTO skinny_active_lines " + "(device_name, device_instance, line_instance, channel_uuid, call_id, call_state) " + "SELECT device_name, device_instance, line_instance, '%s', %d, %d " + "FROM skinny_lines " + "WHERE value='%s'", + switch_core_session_get_uuid(nsession), tech_pvt->call_id, SKINNY_ON_HOOK, button->shortname + ))) { + skinny_execute_sql(listener->profile, sql, listener->profile->sql_mutex); + switch_safe_free(sql); + } + + set_ringer(listener, SKINNY_RING_OFF, SKINNY_RING_FOREVER, 0, tech_pvt->call_id); + set_speaker_mode(listener, SKINNY_SPEAKER_ON); + set_lamp(listener, SKINNY_BUTTON_LINE, *line_instance_p, SKINNY_LAMP_ON); skinny_line_set_state(listener, *line_instance_p, tech_pvt->call_id, SKINNY_OFF_HOOK); send_select_soft_keys(listener, *line_instance_p, tech_pvt->call_id, SKINNY_KEY_SET_OFF_HOOK, 0xffff); - display_prompt_status(listener, 0, "\200\000", - *line_instance_p, tech_pvt->call_id); - activate_call_plane(listener, *line_instance_p); + display_prompt_status(listener, 0, "\200\000", + *line_instance_p, tech_pvt->call_id); + activate_call_plane(listener, *line_instance_p); - goto done; + goto done; error: - if (nsession) { - switch_core_session_destroy(&nsession); - } + if (nsession) { + switch_core_session_destroy(&nsession); + } - return SWITCH_STATUS_FALSE; + return SWITCH_STATUS_FALSE; done: - *session = nsession; - return SWITCH_STATUS_SUCCESS; + *session = nsession; + return SWITCH_STATUS_SUCCESS; } switch_status_t skinny_session_process_dest(switch_core_session_t *session, listener_t *listener, uint32_t line_instance, char *dest, char append_dest, uint32_t backspace) { - switch_channel_t *channel = NULL; - private_t *tech_pvt = NULL; + switch_channel_t *channel = NULL; + private_t *tech_pvt = NULL; switch_assert(session); switch_assert(listener); switch_assert(listener->profile); - channel = switch_core_session_get_channel(session); - tech_pvt = switch_core_session_get_private(session); + channel = switch_core_session_get_channel(session); + tech_pvt = switch_core_session_get_private(session); - if(!dest) { + if(!dest) { if(append_dest == '\0') {/* no digit yet */ start_tone(listener, SKINNY_TONE_DIALTONE, 0, line_instance, tech_pvt->call_id); } else { if(strlen(tech_pvt->caller_profile->destination_number) == 0) {/* first digit */ - stop_tone(listener, line_instance, tech_pvt->call_id); + stop_tone(listener, line_instance, tech_pvt->call_id); send_select_soft_keys(listener, line_instance, tech_pvt->call_id, SKINNY_KEY_SET_DIGITS_AFTER_DIALING_FIRST_DIGIT, 0xffff); } @@ -565,91 +565,91 @@ switch_status_t skinny_session_process_dest(switch_core_session_t *session, list "%s%c", tech_pvt->caller_profile->destination_number, append_dest); } } else { - tech_pvt->caller_profile->destination_number = switch_core_strdup(tech_pvt->caller_profile->pool, - dest); + tech_pvt->caller_profile->destination_number = switch_core_strdup(tech_pvt->caller_profile->pool, + dest); } /* TODO Number is complete -> check against dialplan */ - if((strlen(tech_pvt->caller_profile->destination_number) >= 4) || dest) { - send_dialed_number(listener, tech_pvt->caller_profile->destination_number, line_instance, tech_pvt->call_id); + if((strlen(tech_pvt->caller_profile->destination_number) >= 4) || dest) { + send_dialed_number(listener, tech_pvt->caller_profile->destination_number, line_instance, tech_pvt->call_id); skinny_line_set_state(listener, line_instance, tech_pvt->call_id, SKINNY_PROCEED); - skinny_send_call_info(session, listener, line_instance); + skinny_send_call_info(session, listener, line_instance); skinny_session_start_media(session, listener, line_instance); - } + } - switch_core_session_rwunlock(session); - - return SWITCH_STATUS_SUCCESS; + switch_core_session_rwunlock(session); + + return SWITCH_STATUS_SUCCESS; } switch_status_t skinny_session_ring_out(switch_core_session_t *session, listener_t *listener, uint32_t line_instance) { - switch_channel_t *channel = NULL; - private_t *tech_pvt = NULL; + switch_channel_t *channel = NULL; + private_t *tech_pvt = NULL; switch_assert(session); switch_assert(listener); switch_assert(listener->profile); - channel = switch_core_session_get_channel(session); - tech_pvt = switch_core_session_get_private(session); + channel = switch_core_session_get_channel(session); + tech_pvt = switch_core_session_get_private(session); skinny_line_set_state(listener, line_instance, tech_pvt->call_id, SKINNY_RING_OUT); send_select_soft_keys(listener, line_instance, tech_pvt->call_id, SKINNY_KEY_SET_RING_OUT, 0xffff); - display_prompt_status(listener, 0, "\200\026", - line_instance, tech_pvt->call_id); + display_prompt_status(listener, 0, "\200\026", + line_instance, tech_pvt->call_id); skinny_send_call_info(session, listener, line_instance); - switch_core_session_rwunlock(session); - - return SWITCH_STATUS_SUCCESS; + switch_core_session_rwunlock(session); + + return SWITCH_STATUS_SUCCESS; } struct skinny_session_answer_helper { - private_t *tech_pvt; - listener_t *listener; - uint32_t line_instance; + private_t *tech_pvt; + listener_t *listener; + uint32_t line_instance; }; int skinny_session_answer_callback(void *pArg, int argc, char **argv, char **columnNames) { - struct skinny_session_answer_helper *helper = pArg; - listener_t *listener = NULL; + struct skinny_session_answer_helper *helper = pArg; + listener_t *listener = NULL; - char *device_name = argv[0]; - uint32_t device_instance = atoi(argv[1]); - /* uint32_t position = atoi(argv[2]); */ - uint32_t line_instance = atoi(argv[3]); - /* char *label = argv[4]; */ - /* char *value = argv[5]; */ - /* char *caller_name = argv[6]; */ - /* uint32_t ring_on_idle = atoi(argv[7]); */ - /* uint32_t ring_on_active = atoi(argv[8]); */ - /* uint32_t busy_trigger = atoi(argv[9]); */ - /* char *forward_all = argv[10]; */ - /* char *forward_busy = argv[11]; */ - /* char *forward_noanswer = argv[12]; */ - /* uint32_t noanswer_duration = atoi(argv[13]); */ - /* char *channel_uuid = argv[14]; */ - /* uint32_t call_id = atoi(argv[15]); */ - /* uint32_t call_state = atoi(argv[16]); */ + char *device_name = argv[0]; + uint32_t device_instance = atoi(argv[1]); + /* uint32_t position = atoi(argv[2]); */ + uint32_t line_instance = atoi(argv[3]); + /* char *label = argv[4]; */ + /* char *value = argv[5]; */ + /* char *caller_name = argv[6]; */ + /* uint32_t ring_on_idle = atoi(argv[7]); */ + /* uint32_t ring_on_active = atoi(argv[8]); */ + /* uint32_t busy_trigger = atoi(argv[9]); */ + /* char *forward_all = argv[10]; */ + /* char *forward_busy = argv[11]; */ + /* char *forward_noanswer = argv[12]; */ + /* uint32_t noanswer_duration = atoi(argv[13]); */ + /* char *channel_uuid = argv[14]; */ + /* uint32_t call_id = atoi(argv[15]); */ + /* uint32_t call_state = atoi(argv[16]); */ - skinny_profile_find_listener_by_device_name_and_instance(helper->tech_pvt->profile, device_name, device_instance, &listener); + skinny_profile_find_listener_by_device_name_and_instance(helper->tech_pvt->profile, device_name, device_instance, &listener); if(listener) { if(!strcmp(device_name, helper->listener->device_name) && (device_instance == helper->listener->device_instance) && (line_instance == helper->line_instance)) {/* the answering line */ - set_ringer(listener, SKINNY_RING_OFF, SKINNY_RING_FOREVER, 0, helper->tech_pvt->call_id); - set_speaker_mode(listener, SKINNY_SPEAKER_ON); - set_lamp(listener, SKINNY_BUTTON_LINE, line_instance, SKINNY_LAMP_ON); + set_ringer(listener, SKINNY_RING_OFF, SKINNY_RING_FOREVER, 0, helper->tech_pvt->call_id); + set_speaker_mode(listener, SKINNY_SPEAKER_ON); + set_lamp(listener, SKINNY_BUTTON_LINE, line_instance, SKINNY_LAMP_ON); skinny_line_set_state(listener, line_instance, helper->tech_pvt->call_id, SKINNY_OFF_HOOK); /* send_select_soft_keys(listener, line_instance, helper->tech_pvt->call_id, SKINNY_KEY_SET_OFF_HOOK, 0xffff); */ - /* display_prompt_status(listener, 0, "\200\000", - line_instance, tech_pvt->call_id); */ - activate_call_plane(listener, line_instance); + /* display_prompt_status(listener, 0, "\200\000", + line_instance, tech_pvt->call_id); */ + activate_call_plane(listener, line_instance); } } return 0; @@ -657,41 +657,41 @@ int skinny_session_answer_callback(void *pArg, int argc, char **argv, char **col switch_status_t skinny_session_answer(switch_core_session_t *session, listener_t *listener, uint32_t line_instance) { - struct skinny_session_answer_helper helper = {0}; - switch_channel_t *channel = NULL; - private_t *tech_pvt = NULL; + struct skinny_session_answer_helper helper = {0}; + switch_channel_t *channel = NULL; + private_t *tech_pvt = NULL; switch_assert(session); switch_assert(listener); switch_assert(listener->profile); - channel = switch_core_session_get_channel(session); - tech_pvt = switch_core_session_get_private(session); - + channel = switch_core_session_get_channel(session); + tech_pvt = switch_core_session_get_private(session); + helper.tech_pvt = tech_pvt; helper.listener = listener; helper.line_instance = line_instance; skinny_session_walk_lines(tech_pvt->profile, switch_core_session_get_uuid(session), skinny_session_answer_callback, &helper); - skinny_session_start_media(session, listener, line_instance); + skinny_session_start_media(session, listener, line_instance); - switch_core_session_rwunlock(session); - - return SWITCH_STATUS_SUCCESS; + switch_core_session_rwunlock(session); + + return SWITCH_STATUS_SUCCESS; } switch_status_t skinny_session_start_media(switch_core_session_t *session, listener_t *listener, uint32_t line_instance) { - switch_channel_t *channel = NULL; - private_t *tech_pvt = NULL; + switch_channel_t *channel = NULL; + private_t *tech_pvt = NULL; switch_assert(session); switch_assert(listener); switch_assert(listener->profile); - channel = switch_core_session_get_channel(session); - tech_pvt = switch_core_session_get_private(session); + channel = switch_core_session_get_channel(session); + tech_pvt = switch_core_session_get_private(session); stop_tone(listener, line_instance, tech_pvt->call_id); open_receive_channel(listener, @@ -714,1390 +714,1390 @@ switch_status_t skinny_session_start_media(switch_core_session_t *session, liste tech_pvt->call_id); skinny_send_call_info(session, listener, line_instance); - switch_core_session_rwunlock(session); - - return SWITCH_STATUS_SUCCESS; + switch_core_session_rwunlock(session); + + return SWITCH_STATUS_SUCCESS; } switch_status_t skinny_session_hold_line(switch_core_session_t *session, listener_t *listener, uint32_t line_instance) { - switch_channel_t *channel = NULL; - private_t *tech_pvt = NULL; + switch_channel_t *channel = NULL; + private_t *tech_pvt = NULL; switch_assert(session); switch_assert(listener); switch_assert(listener->profile); - channel = switch_core_session_get_channel(session); - tech_pvt = switch_core_session_get_private(session); - - /* TODO */ - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Hold is not implemented yet. Hanging up the line.\n"); - - switch_channel_hangup(channel, SWITCH_CAUSE_NORMAL_CLEARING); - - switch_core_session_rwunlock(session); + channel = switch_core_session_get_channel(session); + tech_pvt = switch_core_session_get_private(session); - return SWITCH_STATUS_SUCCESS; + /* TODO */ + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Hold is not implemented yet. Hanging up the line.\n"); + + switch_channel_hangup(channel, SWITCH_CAUSE_NORMAL_CLEARING); + + switch_core_session_rwunlock(session); + + return SWITCH_STATUS_SUCCESS; } switch_status_t skinny_session_unhold_line(switch_core_session_t *session, listener_t *listener, uint32_t line_instance) { - /* TODO */ - return SWITCH_STATUS_SUCCESS; + /* TODO */ + return SWITCH_STATUS_SUCCESS; } /*****************************************************************************/ /* SKINNY BUTTONS */ /*****************************************************************************/ struct line_get_helper { - uint32_t pos; - struct line_stat_res_message *button; + uint32_t pos; + struct line_stat_res_message *button; }; int skinny_line_get_callback(void *pArg, int argc, char **argv, char **columnNames) { - struct line_get_helper *helper = pArg; + struct line_get_helper *helper = pArg; - helper->pos++; - if (helper->pos == atoi(argv[0])) { /* wanted_position */ - helper->button->number = helper->pos; - strncpy(helper->button->name, argv[2], 24); /* label */ - strncpy(helper->button->shortname, argv[3], 40); /* value */ - strncpy(helper->button->displayname, argv[4], 44); /* caller_name */ - } - return 0; + helper->pos++; + if (helper->pos == atoi(argv[0])) { /* wanted_position */ + helper->button->number = helper->pos; + strncpy(helper->button->name, argv[2], 24); /* label */ + strncpy(helper->button->shortname, argv[3], 40); /* value */ + strncpy(helper->button->displayname, argv[4], 44); /* caller_name */ + } + return 0; } void skinny_line_get(listener_t *listener, uint32_t instance, struct line_stat_res_message **button) { - struct line_get_helper helper = {0}; - char *sql; + struct line_get_helper helper = {0}; + char *sql; - switch_assert(listener); - switch_assert(listener->profile); - switch_assert(listener->device_name); + switch_assert(listener); + switch_assert(listener->profile); + switch_assert(listener->device_name); - helper.button = switch_core_alloc(listener->pool, sizeof(struct line_stat_res_message)); - - if ((sql = switch_mprintf( - "SELECT '%d' AS wanted_position, position, label, value, caller_name " - "FROM skinny_lines " - "WHERE device_name='%s' AND device_instance=%d " - "ORDER BY position", - instance, - listener->device_name, listener->device_instance - ))) { - skinny_execute_sql_callback(listener->profile, listener->profile->sql_mutex, sql, skinny_line_get_callback, &helper); - switch_safe_free(sql); - } - *button = helper.button; + helper.button = switch_core_alloc(listener->pool, sizeof(struct line_stat_res_message)); + + if ((sql = switch_mprintf( + "SELECT '%d' AS wanted_position, position, label, value, caller_name " + "FROM skinny_lines " + "WHERE device_name='%s' AND device_instance=%d " + "ORDER BY position", + instance, + listener->device_name, listener->device_instance + ))) { + skinny_execute_sql_callback(listener->profile, listener->profile->sql_mutex, sql, skinny_line_get_callback, &helper); + switch_safe_free(sql); + } + *button = helper.button; } struct speed_dial_get_helper { - uint32_t pos; - struct speed_dial_stat_res_message *button; + uint32_t pos; + struct speed_dial_stat_res_message *button; }; int skinny_speed_dial_get_callback(void *pArg, int argc, char **argv, char **columnNames) { - struct speed_dial_get_helper *helper = pArg; + struct speed_dial_get_helper *helper = pArg; - helper->pos++; - if (helper->pos == atoi(argv[0])) { /* wanted_position */ - helper->button->number = helper->pos; /* value */ - strncpy(helper->button->line, argv[3], 24); /* value */ - strncpy(helper->button->label, argv[2], 40); /* label */ - } - return 0; + helper->pos++; + if (helper->pos == atoi(argv[0])) { /* wanted_position */ + helper->button->number = helper->pos; /* value */ + strncpy(helper->button->line, argv[3], 24); /* value */ + strncpy(helper->button->label, argv[2], 40); /* label */ + } + return 0; } void skinny_speed_dial_get(listener_t *listener, uint32_t instance, struct speed_dial_stat_res_message **button) { - struct speed_dial_get_helper helper = {0}; - char *sql; + struct speed_dial_get_helper helper = {0}; + char *sql; - switch_assert(listener); - switch_assert(listener->profile); - switch_assert(listener->device_name); + switch_assert(listener); + switch_assert(listener->profile); + switch_assert(listener->device_name); - helper.button = switch_core_alloc(listener->pool, sizeof(struct speed_dial_stat_res_message)); - - if ((sql = switch_mprintf( - "SELECT '%d' AS wanted_position, position, label, value, settings " - "FROM skinny_buttons " - "WHERE device_name='%s' AND device_instance=%d AND type=%d " - "ORDER BY position", - instance, - listener->device_name, listener->device_instance, - SKINNY_BUTTON_SPEED_DIAL - ))) { - skinny_execute_sql_callback(listener->profile, listener->profile->sql_mutex, sql, skinny_speed_dial_get_callback, &helper); - switch_safe_free(sql); - } - *button = helper.button; + helper.button = switch_core_alloc(listener->pool, sizeof(struct speed_dial_stat_res_message)); + + if ((sql = switch_mprintf( + "SELECT '%d' AS wanted_position, position, label, value, settings " + "FROM skinny_buttons " + "WHERE device_name='%s' AND device_instance=%d AND type=%d " + "ORDER BY position", + instance, + listener->device_name, listener->device_instance, + SKINNY_BUTTON_SPEED_DIAL + ))) { + skinny_execute_sql_callback(listener->profile, listener->profile->sql_mutex, sql, skinny_speed_dial_get_callback, &helper); + switch_safe_free(sql); + } + *button = helper.button; } struct service_url_get_helper { - uint32_t pos; - struct service_url_stat_res_message *button; + uint32_t pos; + struct service_url_stat_res_message *button; }; int skinny_service_url_get_callback(void *pArg, int argc, char **argv, char **columnNames) { - struct service_url_get_helper *helper = pArg; + struct service_url_get_helper *helper = pArg; - helper->pos++; - if (helper->pos == atoi(argv[0])) { /* wanted_position */ - helper->button->index = helper->pos; - strncpy(helper->button->url, argv[3], 256); /* value */ - strncpy(helper->button->display_name, argv[2], 40); /* label */ - } - return 0; + helper->pos++; + if (helper->pos == atoi(argv[0])) { /* wanted_position */ + helper->button->index = helper->pos; + strncpy(helper->button->url, argv[3], 256); /* value */ + strncpy(helper->button->display_name, argv[2], 40); /* label */ + } + return 0; } void skinny_service_url_get(listener_t *listener, uint32_t instance, struct service_url_stat_res_message **button) { - struct service_url_get_helper helper = {0}; - char *sql; + struct service_url_get_helper helper = {0}; + char *sql; - switch_assert(listener); - switch_assert(listener->profile); - switch_assert(listener->device_name); + switch_assert(listener); + switch_assert(listener->profile); + switch_assert(listener->device_name); - helper.button = switch_core_alloc(listener->pool, sizeof(struct service_url_stat_res_message)); - - if ((sql = switch_mprintf( - "SELECT '%d' AS wanted_position, position, label, value, settings " - "FROM skinny_buttons " - "WHERE device_name='%s' AND device_instance=%d AND type=%d " - "ORDER BY position", - instance, - listener->device_name, - listener->device_instance, - SKINNY_BUTTON_SERVICE_URL - ))) { - skinny_execute_sql_callback(listener->profile, listener->profile->sql_mutex, sql, skinny_service_url_get_callback, &helper); - switch_safe_free(sql); - } - *button = helper.button; + helper.button = switch_core_alloc(listener->pool, sizeof(struct service_url_stat_res_message)); + + if ((sql = switch_mprintf( + "SELECT '%d' AS wanted_position, position, label, value, settings " + "FROM skinny_buttons " + "WHERE device_name='%s' AND device_instance=%d AND type=%d " + "ORDER BY position", + instance, + listener->device_name, + listener->device_instance, + SKINNY_BUTTON_SERVICE_URL + ))) { + skinny_execute_sql_callback(listener->profile, listener->profile->sql_mutex, sql, skinny_service_url_get_callback, &helper); + switch_safe_free(sql); + } + *button = helper.button; } struct feature_get_helper { - uint32_t pos; - struct feature_stat_res_message *button; + uint32_t pos; + struct feature_stat_res_message *button; }; int skinny_feature_get_callback(void *pArg, int argc, char **argv, char **columnNames) { - struct feature_get_helper *helper = pArg; + struct feature_get_helper *helper = pArg; - helper->pos++; - if (helper->pos == atoi(argv[0])) { /* wanted_position */ - helper->button->index = helper->pos; - helper->button->id = helper->pos; - strncpy(helper->button->text_label, argv[2], 40); /* label */ - helper->button->status = atoi(argv[3]); /* value */ - } - return 0; + helper->pos++; + if (helper->pos == atoi(argv[0])) { /* wanted_position */ + helper->button->index = helper->pos; + helper->button->id = helper->pos; + strncpy(helper->button->text_label, argv[2], 40); /* label */ + helper->button->status = atoi(argv[3]); /* value */ + } + return 0; } void skinny_feature_get(listener_t *listener, uint32_t instance, struct feature_stat_res_message **button) { - struct feature_get_helper helper = {0}; - char *sql; + struct feature_get_helper helper = {0}; + char *sql; - switch_assert(listener); - switch_assert(listener->profile); - switch_assert(listener->device_name); + switch_assert(listener); + switch_assert(listener->profile); + switch_assert(listener->device_name); - helper.button = switch_core_alloc(listener->pool, sizeof(struct feature_stat_res_message)); - - if ((sql = switch_mprintf( - "SELECT '%d' AS wanted_position, position, label, value, settings " - "FROM skinny_buttons " - "WHERE device_name='%s' AND device_instance=%d AND NOT (type=%d OR type=%d) " - "ORDER BY position", - instance, - listener->device_name, - listener->device_instance, - SKINNY_BUTTON_SPEED_DIAL, SKINNY_BUTTON_SERVICE_URL - ))) { - skinny_execute_sql_callback(listener->profile, listener->profile->sql_mutex, sql, skinny_feature_get_callback, &helper); - switch_safe_free(sql); - } - *button = helper.button; + helper.button = switch_core_alloc(listener->pool, sizeof(struct feature_stat_res_message)); + + if ((sql = switch_mprintf( + "SELECT '%d' AS wanted_position, position, label, value, settings " + "FROM skinny_buttons " + "WHERE device_name='%s' AND device_instance=%d AND NOT (type=%d OR type=%d) " + "ORDER BY position", + instance, + listener->device_name, + listener->device_instance, + SKINNY_BUTTON_SPEED_DIAL, SKINNY_BUTTON_SERVICE_URL + ))) { + skinny_execute_sql_callback(listener->profile, listener->profile->sql_mutex, sql, skinny_feature_get_callback, &helper); + switch_safe_free(sql); + } + *button = helper.button; } /*****************************************************************************/ /* SKINNY MESSAGE SENDER */ /*****************************************************************************/ switch_status_t start_tone(listener_t *listener, - uint32_t tone, - uint32_t reserved, - uint32_t line_instance, - uint32_t call_id) + uint32_t tone, + uint32_t reserved, + uint32_t line_instance, + uint32_t call_id) { - skinny_message_t *message; - message = switch_core_alloc(listener->pool, 12+sizeof(message->data.start_tone)); - message->type = START_TONE_MESSAGE; - message->length = 4 + sizeof(message->data.start_tone); - message->data.start_tone.tone = tone; - message->data.start_tone.reserved = reserved; - message->data.start_tone.line_instance = line_instance; - message->data.start_tone.call_id = call_id; - skinny_send_reply(listener, message); - return SWITCH_STATUS_SUCCESS; + skinny_message_t *message; + message = switch_core_alloc(listener->pool, 12+sizeof(message->data.start_tone)); + message->type = START_TONE_MESSAGE; + message->length = 4 + sizeof(message->data.start_tone); + message->data.start_tone.tone = tone; + message->data.start_tone.reserved = reserved; + message->data.start_tone.line_instance = line_instance; + message->data.start_tone.call_id = call_id; + skinny_send_reply(listener, message); + return SWITCH_STATUS_SUCCESS; } switch_status_t stop_tone(listener_t *listener, - uint32_t line_instance, - uint32_t call_id) + uint32_t line_instance, + uint32_t call_id) { - skinny_message_t *message; - message = switch_core_alloc(listener->pool, 12+sizeof(message->data.stop_tone)); - message->type = STOP_TONE_MESSAGE; - message->length = 4 + sizeof(message->data.stop_tone); - message->data.stop_tone.line_instance = line_instance; - message->data.stop_tone.call_id = call_id; - skinny_send_reply(listener, message); - return SWITCH_STATUS_SUCCESS; + skinny_message_t *message; + message = switch_core_alloc(listener->pool, 12+sizeof(message->data.stop_tone)); + message->type = STOP_TONE_MESSAGE; + message->length = 4 + sizeof(message->data.stop_tone); + message->data.stop_tone.line_instance = line_instance; + message->data.stop_tone.call_id = call_id; + skinny_send_reply(listener, message); + return SWITCH_STATUS_SUCCESS; } switch_status_t set_ringer(listener_t *listener, - uint32_t ring_type, - uint32_t ring_mode, - uint32_t line_instance, - uint32_t call_id) + uint32_t ring_type, + uint32_t ring_mode, + uint32_t line_instance, + uint32_t call_id) { - skinny_message_t *message; - message = switch_core_alloc(listener->pool, 12+sizeof(message->data.ringer)); - message->type = SET_RINGER_MESSAGE; - message->length = 4 + sizeof(message->data.ringer); - message->data.ringer.ring_type = ring_type; - message->data.ringer.ring_mode = ring_mode; - message->data.ringer.line_instance = line_instance; - message->data.ringer.call_id = call_id; - skinny_send_reply(listener, message); - return SWITCH_STATUS_SUCCESS; + skinny_message_t *message; + message = switch_core_alloc(listener->pool, 12+sizeof(message->data.ringer)); + message->type = SET_RINGER_MESSAGE; + message->length = 4 + sizeof(message->data.ringer); + message->data.ringer.ring_type = ring_type; + message->data.ringer.ring_mode = ring_mode; + message->data.ringer.line_instance = line_instance; + message->data.ringer.call_id = call_id; + skinny_send_reply(listener, message); + return SWITCH_STATUS_SUCCESS; } switch_status_t set_lamp(listener_t *listener, - uint32_t stimulus, - uint32_t stimulus_instance, - uint32_t mode) + uint32_t stimulus, + uint32_t stimulus_instance, + uint32_t mode) { - skinny_message_t *message; - message = switch_core_alloc(listener->pool, 12+sizeof(message->data.lamp)); - message->type = SET_LAMP_MESSAGE; - message->length = 4 + sizeof(message->data.lamp); - message->data.lamp.stimulus = stimulus; - message->data.lamp.stimulus_instance = stimulus_instance; - message->data.lamp.mode = mode; - skinny_send_reply(listener, message); - return SWITCH_STATUS_SUCCESS; + skinny_message_t *message; + message = switch_core_alloc(listener->pool, 12+sizeof(message->data.lamp)); + message->type = SET_LAMP_MESSAGE; + message->length = 4 + sizeof(message->data.lamp); + message->data.lamp.stimulus = stimulus; + message->data.lamp.stimulus_instance = stimulus_instance; + message->data.lamp.mode = mode; + skinny_send_reply(listener, message); + return SWITCH_STATUS_SUCCESS; } switch_status_t set_speaker_mode(listener_t *listener, - uint32_t mode) + uint32_t mode) { - skinny_message_t *message; - message = switch_core_alloc(listener->pool, 12+sizeof(message->data.speaker_mode)); - message->type = SET_SPEAKER_MODE_MESSAGE; - message->length = 4 + sizeof(message->data.speaker_mode); - message->data.speaker_mode.mode = mode; - skinny_send_reply(listener, message); - return SWITCH_STATUS_SUCCESS; + skinny_message_t *message; + message = switch_core_alloc(listener->pool, 12+sizeof(message->data.speaker_mode)); + message->type = SET_SPEAKER_MODE_MESSAGE; + message->length = 4 + sizeof(message->data.speaker_mode); + message->data.speaker_mode.mode = mode; + skinny_send_reply(listener, message); + return SWITCH_STATUS_SUCCESS; } switch_status_t start_media_transmission(listener_t *listener, - uint32_t conference_id, - uint32_t pass_thru_party_id, - uint32_t remote_ip, - uint32_t remote_port, - uint32_t ms_per_packet, - uint32_t payload_capacity, - uint32_t precedence, - uint32_t silence_suppression, - uint16_t max_frames_per_packet, - uint32_t g723_bitrate) + uint32_t conference_id, + uint32_t pass_thru_party_id, + uint32_t remote_ip, + uint32_t remote_port, + uint32_t ms_per_packet, + uint32_t payload_capacity, + uint32_t precedence, + uint32_t silence_suppression, + uint16_t max_frames_per_packet, + uint32_t g723_bitrate) { - skinny_message_t *message; - message = switch_core_alloc(listener->pool, 12+sizeof(message->data.start_media)); - message->type = START_MEDIA_TRANSMISSION_MESSAGE; - message->length = 4 + sizeof(message->data.start_media); - message->data.start_media.conference_id = conference_id; - message->data.start_media.pass_thru_party_id = pass_thru_party_id; - message->data.start_media.remote_ip = remote_ip; - message->data.start_media.remote_port = remote_port; - message->data.start_media.ms_per_packet = ms_per_packet; - message->data.start_media.payload_capacity = payload_capacity; - message->data.start_media.precedence = precedence; - message->data.start_media.silence_suppression = silence_suppression; - message->data.start_media.max_frames_per_packet = max_frames_per_packet; - message->data.start_media.g723_bitrate = g723_bitrate; - /* ... */ - skinny_send_reply(listener, message); - return SWITCH_STATUS_SUCCESS; + skinny_message_t *message; + message = switch_core_alloc(listener->pool, 12+sizeof(message->data.start_media)); + message->type = START_MEDIA_TRANSMISSION_MESSAGE; + message->length = 4 + sizeof(message->data.start_media); + message->data.start_media.conference_id = conference_id; + message->data.start_media.pass_thru_party_id = pass_thru_party_id; + message->data.start_media.remote_ip = remote_ip; + message->data.start_media.remote_port = remote_port; + message->data.start_media.ms_per_packet = ms_per_packet; + message->data.start_media.payload_capacity = payload_capacity; + message->data.start_media.precedence = precedence; + message->data.start_media.silence_suppression = silence_suppression; + message->data.start_media.max_frames_per_packet = max_frames_per_packet; + message->data.start_media.g723_bitrate = g723_bitrate; + /* ... */ + skinny_send_reply(listener, message); + return SWITCH_STATUS_SUCCESS; } switch_status_t stop_media_transmission(listener_t *listener, - uint32_t conference_id, - uint32_t pass_thru_party_id, - uint32_t conference_id2) + uint32_t conference_id, + uint32_t pass_thru_party_id, + uint32_t conference_id2) { - skinny_message_t *message; - message = switch_core_alloc(listener->pool, 12+sizeof(message->data.stop_media)); - message->type = STOP_MEDIA_TRANSMISSION_MESSAGE; - message->length = 4 + sizeof(message->data.stop_media); - message->data.stop_media.conference_id = conference_id; - message->data.stop_media.pass_thru_party_id = pass_thru_party_id; - message->data.stop_media.conference_id2 = conference_id2; - /* ... */ - skinny_send_reply(listener, message); - return SWITCH_STATUS_SUCCESS; + skinny_message_t *message; + message = switch_core_alloc(listener->pool, 12+sizeof(message->data.stop_media)); + message->type = STOP_MEDIA_TRANSMISSION_MESSAGE; + message->length = 4 + sizeof(message->data.stop_media); + message->data.stop_media.conference_id = conference_id; + message->data.stop_media.pass_thru_party_id = pass_thru_party_id; + message->data.stop_media.conference_id2 = conference_id2; + /* ... */ + skinny_send_reply(listener, message); + return SWITCH_STATUS_SUCCESS; } switch_status_t send_call_info(listener_t *listener, - char calling_party_name[40], - char calling_party[24], - char called_party_name[40], - char called_party[24], - uint32_t line_instance, - uint32_t call_id, - uint32_t call_type, - char original_called_party_name[40], - char original_called_party[24], - char last_redirecting_party_name[40], - char last_redirecting_party[24], - uint32_t original_called_party_redirect_reason, - uint32_t last_redirecting_reason, - char calling_party_voice_mailbox[24], - char called_party_voice_mailbox[24], - char original_called_party_voice_mailbox[24], - char last_redirecting_voice_mailbox[24], - uint32_t call_instance, - uint32_t call_security_status, - uint32_t party_pi_restriction_bits) + char calling_party_name[40], + char calling_party[24], + char called_party_name[40], + char called_party[24], + uint32_t line_instance, + uint32_t call_id, + uint32_t call_type, + char original_called_party_name[40], + char original_called_party[24], + char last_redirecting_party_name[40], + char last_redirecting_party[24], + uint32_t original_called_party_redirect_reason, + uint32_t last_redirecting_reason, + char calling_party_voice_mailbox[24], + char called_party_voice_mailbox[24], + char original_called_party_voice_mailbox[24], + char last_redirecting_voice_mailbox[24], + uint32_t call_instance, + uint32_t call_security_status, + uint32_t party_pi_restriction_bits) { - skinny_message_t *message; - message = switch_core_alloc(listener->pool, 12+sizeof(message->data.call_info)); - message->type = CALL_INFO_MESSAGE; - message->length = 4 + sizeof(message->data.call_info); - strcpy(message->data.call_info.calling_party_name, calling_party_name); - strcpy(message->data.call_info.calling_party, calling_party); - strcpy(message->data.call_info.called_party_name, called_party_name); - strcpy(message->data.call_info.called_party, called_party); - message->data.call_info.line_instance = line_instance; - message->data.call_info.call_id = call_id; - message->data.call_info.call_type = call_type; - strcpy(message->data.call_info.original_called_party_name, original_called_party_name); - strcpy(message->data.call_info.original_called_party, original_called_party); - strcpy(message->data.call_info.last_redirecting_party_name, last_redirecting_party_name); - strcpy(message->data.call_info.last_redirecting_party, last_redirecting_party); - message->data.call_info.original_called_party_redirect_reason = original_called_party_redirect_reason; - message->data.call_info.last_redirecting_reason = last_redirecting_reason; - strcpy(message->data.call_info.calling_party_voice_mailbox, calling_party_voice_mailbox); - strcpy(message->data.call_info.called_party_voice_mailbox, called_party_voice_mailbox); - strcpy(message->data.call_info.original_called_party_voice_mailbox, original_called_party_voice_mailbox); - strcpy(message->data.call_info.last_redirecting_voice_mailbox, last_redirecting_voice_mailbox); - message->data.call_info.call_instance = call_instance; - message->data.call_info.call_security_status = call_security_status; - message->data.call_info.party_pi_restriction_bits = party_pi_restriction_bits; - skinny_send_reply(listener, message); - return SWITCH_STATUS_SUCCESS; + skinny_message_t *message; + message = switch_core_alloc(listener->pool, 12+sizeof(message->data.call_info)); + message->type = CALL_INFO_MESSAGE; + message->length = 4 + sizeof(message->data.call_info); + strcpy(message->data.call_info.calling_party_name, calling_party_name); + strcpy(message->data.call_info.calling_party, calling_party); + strcpy(message->data.call_info.called_party_name, called_party_name); + strcpy(message->data.call_info.called_party, called_party); + message->data.call_info.line_instance = line_instance; + message->data.call_info.call_id = call_id; + message->data.call_info.call_type = call_type; + strcpy(message->data.call_info.original_called_party_name, original_called_party_name); + strcpy(message->data.call_info.original_called_party, original_called_party); + strcpy(message->data.call_info.last_redirecting_party_name, last_redirecting_party_name); + strcpy(message->data.call_info.last_redirecting_party, last_redirecting_party); + message->data.call_info.original_called_party_redirect_reason = original_called_party_redirect_reason; + message->data.call_info.last_redirecting_reason = last_redirecting_reason; + strcpy(message->data.call_info.calling_party_voice_mailbox, calling_party_voice_mailbox); + strcpy(message->data.call_info.called_party_voice_mailbox, called_party_voice_mailbox); + strcpy(message->data.call_info.original_called_party_voice_mailbox, original_called_party_voice_mailbox); + strcpy(message->data.call_info.last_redirecting_voice_mailbox, last_redirecting_voice_mailbox); + message->data.call_info.call_instance = call_instance; + message->data.call_info.call_security_status = call_security_status; + message->data.call_info.party_pi_restriction_bits = party_pi_restriction_bits; + skinny_send_reply(listener, message); + return SWITCH_STATUS_SUCCESS; } switch_status_t open_receive_channel(listener_t *listener, - uint32_t conference_id, - uint32_t pass_thru_party_id, - uint32_t packets, - uint32_t payload_capacity, - uint32_t echo_cancel_type, - uint32_t g723_bitrate, - uint32_t conference_id2, - uint32_t reserved[10]) + uint32_t conference_id, + uint32_t pass_thru_party_id, + uint32_t packets, + uint32_t payload_capacity, + uint32_t echo_cancel_type, + uint32_t g723_bitrate, + uint32_t conference_id2, + uint32_t reserved[10]) { - skinny_message_t *message; - message = switch_core_alloc(listener->pool, 12+sizeof(message->data.open_receive_channel)); - message->type = OPEN_RECEIVE_CHANNEL_MESSAGE; - message->length = 4 + sizeof(message->data.open_receive_channel); - message->data.open_receive_channel.conference_id = conference_id; - message->data.open_receive_channel.pass_thru_party_id = pass_thru_party_id; - message->data.open_receive_channel.packets = packets; - message->data.open_receive_channel.payload_capacity = payload_capacity; - message->data.open_receive_channel.echo_cancel_type = echo_cancel_type; - message->data.open_receive_channel.g723_bitrate = g723_bitrate; - message->data.open_receive_channel.conference_id2 = conference_id2; - /* - message->data.open_receive_channel.reserved[0] = reserved[0]; - message->data.open_receive_channel.reserved[1] = reserved[1]; - message->data.open_receive_channel.reserved[2] = reserved[2]; - message->data.open_receive_channel.reserved[3] = reserved[3]; - message->data.open_receive_channel.reserved[4] = reserved[4]; - message->data.open_receive_channel.reserved[5] = reserved[5]; - message->data.open_receive_channel.reserved[6] = reserved[6]; - message->data.open_receive_channel.reserved[7] = reserved[7]; - message->data.open_receive_channel.reserved[8] = reserved[8]; - message->data.open_receive_channel.reserved[9] = reserved[9]; - */ - skinny_send_reply(listener, message); - return SWITCH_STATUS_SUCCESS; + skinny_message_t *message; + message = switch_core_alloc(listener->pool, 12+sizeof(message->data.open_receive_channel)); + message->type = OPEN_RECEIVE_CHANNEL_MESSAGE; + message->length = 4 + sizeof(message->data.open_receive_channel); + message->data.open_receive_channel.conference_id = conference_id; + message->data.open_receive_channel.pass_thru_party_id = pass_thru_party_id; + message->data.open_receive_channel.packets = packets; + message->data.open_receive_channel.payload_capacity = payload_capacity; + message->data.open_receive_channel.echo_cancel_type = echo_cancel_type; + message->data.open_receive_channel.g723_bitrate = g723_bitrate; + message->data.open_receive_channel.conference_id2 = conference_id2; + /* + message->data.open_receive_channel.reserved[0] = reserved[0]; + message->data.open_receive_channel.reserved[1] = reserved[1]; + message->data.open_receive_channel.reserved[2] = reserved[2]; + message->data.open_receive_channel.reserved[3] = reserved[3]; + message->data.open_receive_channel.reserved[4] = reserved[4]; + message->data.open_receive_channel.reserved[5] = reserved[5]; + message->data.open_receive_channel.reserved[6] = reserved[6]; + message->data.open_receive_channel.reserved[7] = reserved[7]; + message->data.open_receive_channel.reserved[8] = reserved[8]; + message->data.open_receive_channel.reserved[9] = reserved[9]; + */ + skinny_send_reply(listener, message); + return SWITCH_STATUS_SUCCESS; } switch_status_t close_receive_channel(listener_t *listener, - uint32_t conference_id, - uint32_t pass_thru_party_id, - uint32_t conference_id2) + uint32_t conference_id, + uint32_t pass_thru_party_id, + uint32_t conference_id2) { - skinny_message_t *message; - message = switch_core_alloc(listener->pool, 12+sizeof(message->data.close_receive_channel)); - message->type = CLOSE_RECEIVE_CHANNEL_MESSAGE; - message->length = 4 + sizeof(message->data.close_receive_channel); - message->data.close_receive_channel.conference_id = conference_id; - message->data.close_receive_channel.pass_thru_party_id = pass_thru_party_id; - message->data.close_receive_channel.conference_id2 = conference_id2; - skinny_send_reply(listener, message); - return SWITCH_STATUS_SUCCESS; + skinny_message_t *message; + message = switch_core_alloc(listener->pool, 12+sizeof(message->data.close_receive_channel)); + message->type = CLOSE_RECEIVE_CHANNEL_MESSAGE; + message->length = 4 + sizeof(message->data.close_receive_channel); + message->data.close_receive_channel.conference_id = conference_id; + message->data.close_receive_channel.pass_thru_party_id = pass_thru_party_id; + message->data.close_receive_channel.conference_id2 = conference_id2; + skinny_send_reply(listener, message); + return SWITCH_STATUS_SUCCESS; } switch_status_t send_select_soft_keys(listener_t *listener, - uint32_t line_instance, - uint32_t call_id, - uint32_t soft_key_set, - uint32_t valid_key_mask) + uint32_t line_instance, + uint32_t call_id, + uint32_t soft_key_set, + uint32_t valid_key_mask) { - skinny_message_t *message; - message = switch_core_alloc(listener->pool, 12+sizeof(message->data.select_soft_keys)); - message->type = SELECT_SOFT_KEYS_MESSAGE; - message->length = 4 + sizeof(message->data.select_soft_keys); - message->data.select_soft_keys.line_instance = line_instance; - message->data.select_soft_keys.call_id = call_id; - message->data.select_soft_keys.soft_key_set = soft_key_set; - message->data.select_soft_keys.valid_key_mask = valid_key_mask; - skinny_send_reply(listener, message); - return SWITCH_STATUS_SUCCESS; + skinny_message_t *message; + message = switch_core_alloc(listener->pool, 12+sizeof(message->data.select_soft_keys)); + message->type = SELECT_SOFT_KEYS_MESSAGE; + message->length = 4 + sizeof(message->data.select_soft_keys); + message->data.select_soft_keys.line_instance = line_instance; + message->data.select_soft_keys.call_id = call_id; + message->data.select_soft_keys.soft_key_set = soft_key_set; + message->data.select_soft_keys.valid_key_mask = valid_key_mask; + skinny_send_reply(listener, message); + return SWITCH_STATUS_SUCCESS; } switch_status_t send_call_state(listener_t *listener, - uint32_t call_state, - uint32_t line_instance, - uint32_t call_id) + uint32_t call_state, + uint32_t line_instance, + uint32_t call_id) { - skinny_message_t *message; - message = switch_core_alloc(listener->pool, 12+sizeof(message->data.call_state)); - message->type = CALL_STATE_MESSAGE; - message->length = 4 + sizeof(message->data.call_state); - message->data.call_state.call_state = call_state; - message->data.call_state.line_instance = line_instance; - message->data.call_state.call_id = call_id; - skinny_send_reply(listener, message); - return SWITCH_STATUS_SUCCESS; + skinny_message_t *message; + message = switch_core_alloc(listener->pool, 12+sizeof(message->data.call_state)); + message->type = CALL_STATE_MESSAGE; + message->length = 4 + sizeof(message->data.call_state); + message->data.call_state.call_state = call_state; + message->data.call_state.line_instance = line_instance; + message->data.call_state.call_id = call_id; + skinny_send_reply(listener, message); + return SWITCH_STATUS_SUCCESS; } switch_status_t display_prompt_status(listener_t *listener, - uint32_t timeout, - char display[32], - uint32_t line_instance, - uint32_t call_id) + uint32_t timeout, + char display[32], + uint32_t line_instance, + uint32_t call_id) { - skinny_message_t *message; - message = switch_core_alloc(listener->pool, 12+sizeof(message->data.display_prompt_status)); - message->type = DISPLAY_PROMPT_STATUS_MESSAGE; - message->length = 4 + sizeof(message->data.display_prompt_status); - message->data.display_prompt_status.timeout = timeout; - strcpy(message->data.display_prompt_status.display, display); - message->data.display_prompt_status.line_instance = line_instance; - message->data.display_prompt_status.call_id = call_id; - skinny_send_reply(listener, message); - return SWITCH_STATUS_SUCCESS; + skinny_message_t *message; + message = switch_core_alloc(listener->pool, 12+sizeof(message->data.display_prompt_status)); + message->type = DISPLAY_PROMPT_STATUS_MESSAGE; + message->length = 4 + sizeof(message->data.display_prompt_status); + message->data.display_prompt_status.timeout = timeout; + strcpy(message->data.display_prompt_status.display, display); + message->data.display_prompt_status.line_instance = line_instance; + message->data.display_prompt_status.call_id = call_id; + skinny_send_reply(listener, message); + return SWITCH_STATUS_SUCCESS; } switch_status_t clear_prompt_status(listener_t *listener, - uint32_t line_instance, - uint32_t call_id) + uint32_t line_instance, + uint32_t call_id) { - skinny_message_t *message; - message = switch_core_alloc(listener->pool, 12+sizeof(message->data.clear_prompt_status)); - message->type = CLEAR_PROMPT_STATUS_MESSAGE; - message->length = 4 + sizeof(message->data.clear_prompt_status); - message->data.clear_prompt_status.line_instance = line_instance; - message->data.clear_prompt_status.call_id = call_id; - skinny_send_reply(listener, message); - return SWITCH_STATUS_SUCCESS; + skinny_message_t *message; + message = switch_core_alloc(listener->pool, 12+sizeof(message->data.clear_prompt_status)); + message->type = CLEAR_PROMPT_STATUS_MESSAGE; + message->length = 4 + sizeof(message->data.clear_prompt_status); + message->data.clear_prompt_status.line_instance = line_instance; + message->data.clear_prompt_status.call_id = call_id; + skinny_send_reply(listener, message); + return SWITCH_STATUS_SUCCESS; } switch_status_t activate_call_plane(listener_t *listener, - uint32_t line_instance) + uint32_t line_instance) { - skinny_message_t *message; - message = switch_core_alloc(listener->pool, 12+sizeof(message->data.activate_call_plane)); - message->type = ACTIVATE_CALL_PLANE_MESSAGE; - message->length = 4 + sizeof(message->data.activate_call_plane); - message->data.activate_call_plane.line_instance = line_instance; - skinny_send_reply(listener, message); - return SWITCH_STATUS_SUCCESS; + skinny_message_t *message; + message = switch_core_alloc(listener->pool, 12+sizeof(message->data.activate_call_plane)); + message->type = ACTIVATE_CALL_PLANE_MESSAGE; + message->length = 4 + sizeof(message->data.activate_call_plane); + message->data.activate_call_plane.line_instance = line_instance; + skinny_send_reply(listener, message); + return SWITCH_STATUS_SUCCESS; } switch_status_t send_dialed_number(listener_t *listener, - char called_party[24], - uint32_t line_instance, - uint32_t call_id) + char called_party[24], + uint32_t line_instance, + uint32_t call_id) { - skinny_message_t *message; - message = switch_core_alloc(listener->pool, 12+sizeof(message->data.dialed_number)); - message->type = DIALED_NUMBER_MESSAGE; - message->length = 4 + sizeof(message->data.dialed_number); - strcpy(message->data.dialed_number.called_party, called_party); - message->data.dialed_number.line_instance = line_instance; - message->data.dialed_number.call_id = call_id; - skinny_send_reply(listener, message); - return SWITCH_STATUS_SUCCESS; + skinny_message_t *message; + message = switch_core_alloc(listener->pool, 12+sizeof(message->data.dialed_number)); + message->type = DIALED_NUMBER_MESSAGE; + message->length = 4 + sizeof(message->data.dialed_number); + strcpy(message->data.dialed_number.called_party, called_party); + message->data.dialed_number.line_instance = line_instance; + message->data.dialed_number.call_id = call_id; + skinny_send_reply(listener, message); + return SWITCH_STATUS_SUCCESS; } switch_status_t send_display_pri_notify(listener_t *listener, - uint32_t message_timeout, - uint32_t priority, - char *notify) + uint32_t message_timeout, + uint32_t priority, + char *notify) { - skinny_message_t *message; - message = switch_core_alloc(listener->pool, 12+sizeof(message->data.display_pri_notify)); - message->type = DISPLAY_PRI_NOTIFY_MESSAGE; - message->length = 4 + sizeof(message->data.display_pri_notify); - message->data.display_pri_notify.message_timeout = message_timeout; - message->data.display_pri_notify.priority = priority; - strncpy(message->data.display_pri_notify.notify, notify, 32); - skinny_send_reply(listener, message); - return SWITCH_STATUS_SUCCESS; + skinny_message_t *message; + message = switch_core_alloc(listener->pool, 12+sizeof(message->data.display_pri_notify)); + message->type = DISPLAY_PRI_NOTIFY_MESSAGE; + message->length = 4 + sizeof(message->data.display_pri_notify); + message->data.display_pri_notify.message_timeout = message_timeout; + message->data.display_pri_notify.priority = priority; + strncpy(message->data.display_pri_notify.notify, notify, 32); + skinny_send_reply(listener, message); + return SWITCH_STATUS_SUCCESS; } switch_status_t send_reset(listener_t *listener, uint32_t reset_type) { - skinny_message_t *message; - message = switch_core_alloc(listener->pool, 12+sizeof(message->data.reset)); - message->type = RESET_MESSAGE; - message->length = 4 + sizeof(message->data.reset); - message->data.reset.reset_type = reset_type; - skinny_send_reply(listener, message); - return SWITCH_STATUS_SUCCESS; + skinny_message_t *message; + message = switch_core_alloc(listener->pool, 12+sizeof(message->data.reset)); + message->type = RESET_MESSAGE; + message->length = 4 + sizeof(message->data.reset); + message->data.reset.reset_type = reset_type; + skinny_send_reply(listener, message); + return SWITCH_STATUS_SUCCESS; } /* Message handling */ switch_status_t skinny_handle_alarm(listener_t *listener, skinny_message_t *request) { - switch_event_t *event = NULL; + switch_event_t *event = NULL; - skinny_check_data_length(request, sizeof(request->data.alarm)); + skinny_check_data_length(request, sizeof(request->data.alarm)); - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, - "Received alarm: Severity=%d, DisplayMessage=%s, Param1=%d, Param2=%d.\n", - request->data.alarm.alarm_severity, request->data.alarm.display_message, - request->data.alarm.alarm_param1, request->data.alarm.alarm_param2); - /* skinny::alarm event */ - skinny_device_event(listener, &event, SWITCH_EVENT_CUSTOM, SKINNY_EVENT_ALARM); - switch_event_add_header(event, SWITCH_STACK_BOTTOM, "Skinny-Alarm-Severity", "%d", request->data.alarm.alarm_severity); - switch_event_add_header(event, SWITCH_STACK_BOTTOM, "Skinny-Alarm-DisplayMessage", "%s", request->data.alarm.display_message); - switch_event_add_header(event, SWITCH_STACK_BOTTOM, "Skinny-Alarm-Param1", "%d", request->data.alarm.alarm_param1); - switch_event_add_header(event, SWITCH_STACK_BOTTOM, "Skinny-Alarm-Param2", "%d", request->data.alarm.alarm_param2); - switch_event_fire(&event); - - return SWITCH_STATUS_SUCCESS; + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, + "Received alarm: Severity=%d, DisplayMessage=%s, Param1=%d, Param2=%d.\n", + request->data.alarm.alarm_severity, request->data.alarm.display_message, + request->data.alarm.alarm_param1, request->data.alarm.alarm_param2); + /* skinny::alarm event */ + skinny_device_event(listener, &event, SWITCH_EVENT_CUSTOM, SKINNY_EVENT_ALARM); + switch_event_add_header(event, SWITCH_STACK_BOTTOM, "Skinny-Alarm-Severity", "%d", request->data.alarm.alarm_severity); + switch_event_add_header(event, SWITCH_STACK_BOTTOM, "Skinny-Alarm-DisplayMessage", "%s", request->data.alarm.display_message); + switch_event_add_header(event, SWITCH_STACK_BOTTOM, "Skinny-Alarm-Param1", "%d", request->data.alarm.alarm_param1); + switch_event_add_header(event, SWITCH_STACK_BOTTOM, "Skinny-Alarm-Param2", "%d", request->data.alarm.alarm_param2); + switch_event_fire(&event); + + return SWITCH_STATUS_SUCCESS; } switch_status_t skinny_handle_register(listener_t *listener, skinny_message_t *request) { - switch_status_t status = SWITCH_STATUS_FALSE; - skinny_message_t *message; - skinny_profile_t *profile; - switch_event_t *event = NULL; - switch_event_t *params = NULL; - switch_xml_t xroot, xdomain, xgroup, xuser, xskinny, xbuttons, xbutton; - char *sql; - assert(listener->profile); - profile = listener->profile; + switch_status_t status = SWITCH_STATUS_FALSE; + skinny_message_t *message; + skinny_profile_t *profile; + switch_event_t *event = NULL; + switch_event_t *params = NULL; + switch_xml_t xroot, xdomain, xgroup, xuser, xskinny, xbuttons, xbutton; + char *sql; + assert(listener->profile); + profile = listener->profile; - skinny_check_data_length(request, sizeof(request->data.reg)); + skinny_check_data_length(request, sizeof(request->data.reg)); - if(!zstr(listener->device_name)) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, - "A device is already registred on this listener.\n"); - message = switch_core_alloc(listener->pool, 12+sizeof(message->data.reg_rej)); - message->type = REGISTER_REJ_MESSAGE; - message->length = 4 + sizeof(message->data.reg_rej); - strcpy(message->data.reg_rej.error, "A device is already registred on this listener"); - skinny_send_reply(listener, message); - return SWITCH_STATUS_FALSE; - } + if(!zstr(listener->device_name)) { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, + "A device is already registred on this listener.\n"); + message = switch_core_alloc(listener->pool, 12+sizeof(message->data.reg_rej)); + message->type = REGISTER_REJ_MESSAGE; + message->length = 4 + sizeof(message->data.reg_rej); + strcpy(message->data.reg_rej.error, "A device is already registred on this listener"); + skinny_send_reply(listener, message); + return SWITCH_STATUS_FALSE; + } - /* Check directory */ - skinny_device_event(listener, ¶ms, SWITCH_EVENT_REQUEST_PARAMS, SWITCH_EVENT_SUBCLASS_ANY); - switch_event_add_header_string(params, SWITCH_STACK_BOTTOM, "action", "skinny-auth"); + /* Check directory */ + skinny_device_event(listener, ¶ms, SWITCH_EVENT_REQUEST_PARAMS, SWITCH_EVENT_SUBCLASS_ANY); + switch_event_add_header_string(params, SWITCH_STACK_BOTTOM, "action", "skinny-auth"); - if (switch_xml_locate_user("id", request->data.reg.device_name, profile->domain, "", &xroot, &xdomain, &xuser, &xgroup, params) != SWITCH_STATUS_SUCCESS) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Can't find device [%s@%s]\n" - "You must define a domain called '%s' in your directory and add a user with id=\"%s\".\n" - , request->data.reg.device_name, profile->domain, profile->domain, request->data.reg.device_name); - message = switch_core_alloc(listener->pool, 12+sizeof(message->data.reg_rej)); - message->type = REGISTER_REJ_MESSAGE; - message->length = 4 + sizeof(message->data.reg_rej); - strcpy(message->data.reg_rej.error, "Device not found"); - skinny_send_reply(listener, message); - status = SWITCH_STATUS_FALSE; - goto end; - } + if (switch_xml_locate_user("id", request->data.reg.device_name, profile->domain, "", &xroot, &xdomain, &xuser, &xgroup, params) != SWITCH_STATUS_SUCCESS) { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Can't find device [%s@%s]\n" + "You must define a domain called '%s' in your directory and add a user with id=\"%s\".\n" + , request->data.reg.device_name, profile->domain, profile->domain, request->data.reg.device_name); + message = switch_core_alloc(listener->pool, 12+sizeof(message->data.reg_rej)); + message->type = REGISTER_REJ_MESSAGE; + message->length = 4 + sizeof(message->data.reg_rej); + strcpy(message->data.reg_rej.error, "Device not found"); + skinny_send_reply(listener, message); + status = SWITCH_STATUS_FALSE; + goto end; + } - if ((sql = switch_mprintf( - "INSERT INTO skinny_devices " - "(name, user_id, instance, ip, type, max_streams, codec_string) " - "VALUES ('%s','%d','%d', '%s', '%d', '%d', '%s')", - request->data.reg.device_name, - request->data.reg.user_id, - request->data.reg.instance, - inet_ntoa(request->data.reg.ip), - request->data.reg.device_type, - request->data.reg.max_streams, - "" /* codec_string */ - ))) { - skinny_execute_sql(profile, sql, profile->sql_mutex); - switch_safe_free(sql); - } + if ((sql = switch_mprintf( + "INSERT INTO skinny_devices " + "(name, user_id, instance, ip, type, max_streams, codec_string) " + "VALUES ('%s','%d','%d', '%s', '%d', '%d', '%s')", + request->data.reg.device_name, + request->data.reg.user_id, + request->data.reg.instance, + inet_ntoa(request->data.reg.ip), + request->data.reg.device_type, + request->data.reg.max_streams, + "" /* codec_string */ + ))) { + skinny_execute_sql(profile, sql, profile->sql_mutex); + switch_safe_free(sql); + } - strcpy(listener->device_name, request->data.reg.device_name); - listener->device_instance = request->data.reg.instance; + strcpy(listener->device_name, request->data.reg.device_name); + listener->device_instance = request->data.reg.instance; - xskinny = switch_xml_child(xuser, "skinny"); - if (xskinny) { - xbuttons = switch_xml_child(xskinny, "buttons"); - if (xbuttons) { - uint32_t line_instance = 1; - for (xbutton = switch_xml_child(xbuttons, "button"); xbutton; xbutton = xbutton->next) { - uint32_t position = atoi(switch_xml_attr_soft(xbutton, "position")); - uint32_t type = skinny_str2button(switch_xml_attr_soft(xbutton, "type")); - const char *label = switch_xml_attr_soft(xbutton, "label"); - const char *value = switch_xml_attr_soft(xbutton, "value"); - if(type == SKINNY_BUTTON_LINE) { - const char *caller_name = switch_xml_attr_soft(xbutton, "caller-name"); - uint32_t ring_on_idle = atoi(switch_xml_attr_soft(xbutton, "ring-on-idle")); - uint32_t ring_on_active = atoi(switch_xml_attr_soft(xbutton, "ring-on-active")); - uint32_t busy_trigger = atoi(switch_xml_attr_soft(xbutton, "busy-trigger")); - const char *forward_all = switch_xml_attr_soft(xbutton, "forward-all"); - const char *forward_busy = switch_xml_attr_soft(xbutton, "forward-busy"); - const char *forward_noanswer = switch_xml_attr_soft(xbutton, "forward-noanswer"); - uint32_t noanswer_duration = atoi(switch_xml_attr_soft(xbutton, "noanswer-duration")); - if ((sql = switch_mprintf( - "INSERT INTO skinny_lines " - "(device_name, device_instance, position, line_instance, " - "label, value, caller_name, " - "ring_on_idle, ring_on_active, busy_trigger, " + xskinny = switch_xml_child(xuser, "skinny"); + if (xskinny) { + xbuttons = switch_xml_child(xskinny, "buttons"); + if (xbuttons) { + uint32_t line_instance = 1; + for (xbutton = switch_xml_child(xbuttons, "button"); xbutton; xbutton = xbutton->next) { + uint32_t position = atoi(switch_xml_attr_soft(xbutton, "position")); + uint32_t type = skinny_str2button(switch_xml_attr_soft(xbutton, "type")); + const char *label = switch_xml_attr_soft(xbutton, "label"); + const char *value = switch_xml_attr_soft(xbutton, "value"); + if(type == SKINNY_BUTTON_LINE) { + const char *caller_name = switch_xml_attr_soft(xbutton, "caller-name"); + uint32_t ring_on_idle = atoi(switch_xml_attr_soft(xbutton, "ring-on-idle")); + uint32_t ring_on_active = atoi(switch_xml_attr_soft(xbutton, "ring-on-active")); + uint32_t busy_trigger = atoi(switch_xml_attr_soft(xbutton, "busy-trigger")); + const char *forward_all = switch_xml_attr_soft(xbutton, "forward-all"); + const char *forward_busy = switch_xml_attr_soft(xbutton, "forward-busy"); + const char *forward_noanswer = switch_xml_attr_soft(xbutton, "forward-noanswer"); + uint32_t noanswer_duration = atoi(switch_xml_attr_soft(xbutton, "noanswer-duration")); + if ((sql = switch_mprintf( + "INSERT INTO skinny_lines " + "(device_name, device_instance, position, line_instance, " + "label, value, caller_name, " + "ring_on_idle, ring_on_active, busy_trigger, " "forward_all, forward_busy, forward_noanswer, noanswer_duration) " - "VALUES('%s', %d, %d, %d, '%s', '%s', '%s', %d, %d, %d, '%s', '%s', '%s', %d)", - request->data.reg.device_name, request->data.reg.instance, position, line_instance++, - label, value, caller_name, - ring_on_idle, ring_on_active, busy_trigger, + "VALUES('%s', %d, %d, %d, '%s', '%s', '%s', %d, %d, %d, '%s', '%s', '%s', %d)", + request->data.reg.device_name, request->data.reg.instance, position, line_instance++, + label, value, caller_name, + ring_on_idle, ring_on_active, busy_trigger, forward_all, forward_busy, forward_noanswer, noanswer_duration))) { - skinny_execute_sql(profile, sql, profile->sql_mutex); - switch_safe_free(sql); - } - } else { - const char *settings = switch_xml_attr_soft(xbutton, "settings"); - if ((sql = switch_mprintf( - "INSERT INTO skinny_buttons " - "(device_name, device_instance, position, type, label, value, settings) " - "VALUES('%s', %d, %d, %d, '%s', '%s', '%s')", - request->data.reg.device_name, - request->data.reg.instance, - position, - type, - label, - value, - settings))) { - skinny_execute_sql(profile, sql, profile->sql_mutex); - switch_safe_free(sql); - } - } - } - } - } + skinny_execute_sql(profile, sql, profile->sql_mutex); + switch_safe_free(sql); + } + } else { + const char *settings = switch_xml_attr_soft(xbutton, "settings"); + if ((sql = switch_mprintf( + "INSERT INTO skinny_buttons " + "(device_name, device_instance, position, type, label, value, settings) " + "VALUES('%s', %d, %d, %d, '%s', '%s', '%s')", + request->data.reg.device_name, + request->data.reg.instance, + position, + type, + label, + value, + settings))) { + skinny_execute_sql(profile, sql, profile->sql_mutex); + switch_safe_free(sql); + } + } + } + } + } - status = SWITCH_STATUS_SUCCESS; + status = SWITCH_STATUS_SUCCESS; - /* Reply with RegisterAckMessage */ - message = switch_core_alloc(listener->pool, 12+sizeof(message->data.reg_ack)); - message->type = REGISTER_ACK_MESSAGE; - message->length = 4 + sizeof(message->data.reg_ack); - message->data.reg_ack.keep_alive = profile->keep_alive; - memcpy(message->data.reg_ack.date_format, profile->date_format, 6); - message->data.reg_ack.secondary_keep_alive = profile->keep_alive; - skinny_send_reply(listener, message); + /* Reply with RegisterAckMessage */ + message = switch_core_alloc(listener->pool, 12+sizeof(message->data.reg_ack)); + message->type = REGISTER_ACK_MESSAGE; + message->length = 4 + sizeof(message->data.reg_ack); + message->data.reg_ack.keep_alive = profile->keep_alive; + memcpy(message->data.reg_ack.date_format, profile->date_format, 6); + message->data.reg_ack.secondary_keep_alive = profile->keep_alive; + skinny_send_reply(listener, message); - /* Send CapabilitiesReqMessage */ - message = switch_core_alloc(listener->pool, 12); - message->type = CAPABILITIES_REQ_MESSAGE; - message->length = 4; - skinny_send_reply(listener, message); + /* Send CapabilitiesReqMessage */ + message = switch_core_alloc(listener->pool, 12); + message->type = CAPABILITIES_REQ_MESSAGE; + message->length = 4; + skinny_send_reply(listener, message); - /* skinny::register event */ - skinny_device_event(listener, &event, SWITCH_EVENT_CUSTOM, SKINNY_EVENT_REGISTER); - switch_event_fire(&event); - - keepalive_listener(listener, NULL); + /* skinny::register event */ + skinny_device_event(listener, &event, SWITCH_EVENT_CUSTOM, SKINNY_EVENT_REGISTER); + switch_event_fire(&event); + + keepalive_listener(listener, NULL); end: - if(params) { - switch_event_destroy(¶ms); - } - - return status; + if(params) { + switch_event_destroy(¶ms); + } + + return status; } switch_status_t skinny_headset_status_message(listener_t *listener, skinny_message_t *request) { - skinny_check_data_length(request, sizeof(request->data.headset_status)); - - /* Nothing to do */ - return SWITCH_STATUS_SUCCESS; + skinny_check_data_length(request, sizeof(request->data.headset_status)); + + /* Nothing to do */ + return SWITCH_STATUS_SUCCESS; } int skinny_config_stat_res_callback(void *pArg, int argc, char **argv, char **columnNames) { - skinny_message_t *message = pArg; - char *device_name = argv[0]; - int user_id = atoi(argv[1]); - int instance = atoi(argv[2]); - char *user_name = argv[3]; - char *server_name = argv[4]; - int number_lines = atoi(argv[5]); - int number_speed_dials = atoi(argv[6]); - - strcpy(message->data.config_res.device_name, device_name); - message->data.config_res.user_id = user_id; - message->data.config_res.instance = instance; - strcpy(message->data.config_res.user_name, user_name); - strcpy(message->data.config_res.server_name, server_name); - message->data.config_res.number_lines = number_lines; - message->data.config_res.number_speed_dials = number_speed_dials; + skinny_message_t *message = pArg; + char *device_name = argv[0]; + int user_id = atoi(argv[1]); + int instance = atoi(argv[2]); + char *user_name = argv[3]; + char *server_name = argv[4]; + int number_lines = atoi(argv[5]); + int number_speed_dials = atoi(argv[6]); - return 0; + strcpy(message->data.config_res.device_name, device_name); + message->data.config_res.user_id = user_id; + message->data.config_res.instance = instance; + strcpy(message->data.config_res.user_name, user_name); + strcpy(message->data.config_res.server_name, server_name); + message->data.config_res.number_lines = number_lines; + message->data.config_res.number_speed_dials = number_speed_dials; + + return 0; } switch_status_t skinny_handle_config_stat_request(listener_t *listener, skinny_message_t *request) { - char *sql; - skinny_message_t *message; - skinny_profile_t *profile; + char *sql; + skinny_message_t *message; + skinny_profile_t *profile; - switch_assert(listener->profile); - switch_assert(listener->device_name); + switch_assert(listener->profile); + switch_assert(listener->device_name); - profile = listener->profile; + profile = listener->profile; - message = switch_core_alloc(listener->pool, 12+sizeof(message->data.config_res)); - message->type = CONFIG_STAT_RES_MESSAGE; - message->length = 4 + sizeof(message->data.config_res); + message = switch_core_alloc(listener->pool, 12+sizeof(message->data.config_res)); + message->type = CONFIG_STAT_RES_MESSAGE; + message->length = 4 + sizeof(message->data.config_res); - if ((sql = switch_mprintf( - "SELECT name, user_id, instance, '' AS user_name, '' AS server_name, " - "(SELECT COUNT(*) FROM skinny_lines WHERE device_name='%s' AND device_instance=%d) AS number_lines, " - "(SELECT COUNT(*) FROM skinny_buttons WHERE device_name='%s' AND device_instance=%d AND type=%d) AS number_speed_dials " - "FROM skinny_devices WHERE name='%s' ", - listener->device_name, - listener->device_instance, - listener->device_name, - listener->device_instance, - SKINNY_BUTTON_SPEED_DIAL, - listener->device_name - ))) { - skinny_execute_sql_callback(profile, profile->sql_mutex, sql, skinny_config_stat_res_callback, message); - switch_safe_free(sql); - } - skinny_send_reply(listener, message); + if ((sql = switch_mprintf( + "SELECT name, user_id, instance, '' AS user_name, '' AS server_name, " + "(SELECT COUNT(*) FROM skinny_lines WHERE device_name='%s' AND device_instance=%d) AS number_lines, " + "(SELECT COUNT(*) FROM skinny_buttons WHERE device_name='%s' AND device_instance=%d AND type=%d) AS number_speed_dials " + "FROM skinny_devices WHERE name='%s' ", + listener->device_name, + listener->device_instance, + listener->device_name, + listener->device_instance, + SKINNY_BUTTON_SPEED_DIAL, + listener->device_name + ))) { + skinny_execute_sql_callback(profile, profile->sql_mutex, sql, skinny_config_stat_res_callback, message); + switch_safe_free(sql); + } + skinny_send_reply(listener, message); - return SWITCH_STATUS_SUCCESS; + return SWITCH_STATUS_SUCCESS; } switch_status_t skinny_handle_capabilities_response(listener_t *listener, skinny_message_t *request) { - char *sql; - skinny_profile_t *profile; + char *sql; + skinny_profile_t *profile; - uint32_t i = 0; - uint32_t n = 0; - char *codec_order[SWITCH_MAX_CODECS]; - char *codec_string; - - size_t string_len, string_pos, pos; + uint32_t i = 0; + uint32_t n = 0; + char *codec_order[SWITCH_MAX_CODECS]; + char *codec_string; - switch_assert(listener->profile); - switch_assert(listener->device_name); + size_t string_len, string_pos, pos; - profile = listener->profile; + switch_assert(listener->profile); + switch_assert(listener->device_name); - skinny_check_data_length(request, sizeof(request->data.cap_res.count)); + profile = listener->profile; - n = request->data.cap_res.count; - if (n > SWITCH_MAX_CODECS) { - n = SWITCH_MAX_CODECS; - } - string_len = -1; + skinny_check_data_length(request, sizeof(request->data.cap_res.count)); - skinny_check_data_length(request, sizeof(request->data.cap_res.count) + n * sizeof(request->data.cap_res.caps[0])); + n = request->data.cap_res.count; + if (n > SWITCH_MAX_CODECS) { + n = SWITCH_MAX_CODECS; + } + string_len = -1; - for (i = 0; i < n; i++) { - char *codec = skinny_codec2string(request->data.cap_res.caps[i].codec); - codec_order[i] = codec; - string_len += strlen(codec)+1; - } - i = 0; - pos = 0; - codec_string = switch_core_alloc(listener->pool, string_len+1); - for (string_pos = 0; string_pos < string_len; string_pos++) { - char *codec = codec_order[i]; - switch_assert(i < n); - if(pos == strlen(codec)) { - codec_string[string_pos] = ','; - i++; - pos = 0; - } else { - codec_string[string_pos] = codec[pos++]; - } - } - codec_string[string_len] = '\0'; - if ((sql = switch_mprintf( - "UPDATE skinny_devices SET codec_string='%s' WHERE name='%s'", - codec_string, - listener->device_name - ))) { - skinny_execute_sql(profile, sql, profile->sql_mutex); - switch_safe_free(sql); - } - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, - "Codecs %s supported.\n", codec_string); - return SWITCH_STATUS_SUCCESS; + skinny_check_data_length(request, sizeof(request->data.cap_res.count) + n * sizeof(request->data.cap_res.caps[0])); + + for (i = 0; i < n; i++) { + char *codec = skinny_codec2string(request->data.cap_res.caps[i].codec); + codec_order[i] = codec; + string_len += strlen(codec)+1; + } + i = 0; + pos = 0; + codec_string = switch_core_alloc(listener->pool, string_len+1); + for (string_pos = 0; string_pos < string_len; string_pos++) { + char *codec = codec_order[i]; + switch_assert(i < n); + if(pos == strlen(codec)) { + codec_string[string_pos] = ','; + i++; + pos = 0; + } else { + codec_string[string_pos] = codec[pos++]; + } + } + codec_string[string_len] = '\0'; + if ((sql = switch_mprintf( + "UPDATE skinny_devices SET codec_string='%s' WHERE name='%s'", + codec_string, + listener->device_name + ))) { + skinny_execute_sql(profile, sql, profile->sql_mutex); + switch_safe_free(sql); + } + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, + "Codecs %s supported.\n", codec_string); + return SWITCH_STATUS_SUCCESS; } switch_status_t skinny_handle_port_message(listener_t *listener, skinny_message_t *request) { - char *sql; - skinny_profile_t *profile; + char *sql; + skinny_profile_t *profile; - switch_assert(listener->profile); - switch_assert(listener->device_name); + switch_assert(listener->profile); + switch_assert(listener->device_name); - profile = listener->profile; + profile = listener->profile; - skinny_check_data_length(request, sizeof(request->data.as_uint16)); + skinny_check_data_length(request, sizeof(request->data.as_uint16)); - if ((sql = switch_mprintf( - "UPDATE skinny_devices SET port=%d WHERE name='%s' and instance=%d", - request->data.port.port, - listener->device_name, - listener->device_instance - ))) { - skinny_execute_sql(profile, sql, profile->sql_mutex); - switch_safe_free(sql); - } - return SWITCH_STATUS_SUCCESS; + if ((sql = switch_mprintf( + "UPDATE skinny_devices SET port=%d WHERE name='%s' and instance=%d", + request->data.port.port, + listener->device_name, + listener->device_instance + ))) { + skinny_execute_sql(profile, sql, profile->sql_mutex); + switch_safe_free(sql); + } + return SWITCH_STATUS_SUCCESS; } struct button_template_helper { - skinny_message_t *message; - int count[SKINNY_BUTTON_UNDEFINED+1]; - int max_position; + skinny_message_t *message; + int count[SKINNY_BUTTON_UNDEFINED+1]; + int max_position; }; int skinny_handle_button_template_request_callback(void *pArg, int argc, char **argv, char **columnNames) { - struct button_template_helper *helper = pArg; - skinny_message_t *message = helper->message; - /* char *device_name = argv[0]; */ - /* uint32_t device_instance = argv[1]; */ - int position = atoi(argv[2]); - uint32_t type = atoi(argv[3]); - /* int relative_position = atoi(argv[4]); */ + struct button_template_helper *helper = pArg; + skinny_message_t *message = helper->message; + /* char *device_name = argv[0]; */ + /* uint32_t device_instance = argv[1]; */ + int position = atoi(argv[2]); + uint32_t type = atoi(argv[3]); + /* int relative_position = atoi(argv[4]); */ - message->data.button_template.btn[position-1].instance_number = ++helper->count[type]; - message->data.button_template.btn[position-1].button_definition = type; + message->data.button_template.btn[position-1].instance_number = ++helper->count[type]; + message->data.button_template.btn[position-1].button_definition = type; - message->data.button_template.button_count++; - message->data.button_template.total_button_count++; - if(position > helper->max_position) { - helper->max_position = position; - } + message->data.button_template.button_count++; + message->data.button_template.total_button_count++; + if(position > helper->max_position) { + helper->max_position = position; + } - return 0; + return 0; } switch_status_t skinny_handle_button_template_request(listener_t *listener, skinny_message_t *request) { - skinny_message_t *message; - struct button_template_helper helper = {0}; - skinny_profile_t *profile; - char *sql; + skinny_message_t *message; + struct button_template_helper helper = {0}; + skinny_profile_t *profile; + char *sql; - switch_assert(listener->profile); - switch_assert(listener->device_name); + switch_assert(listener->profile); + switch_assert(listener->device_name); - profile = listener->profile; + profile = listener->profile; - message = switch_core_alloc(listener->pool, 12+sizeof(message->data.button_template)); - message->type = BUTTON_TEMPLATE_RES_MESSAGE; - message->length = 4 + sizeof(message->data.button_template); + message = switch_core_alloc(listener->pool, 12+sizeof(message->data.button_template)); + message->type = BUTTON_TEMPLATE_RES_MESSAGE; + message->length = 4 + sizeof(message->data.button_template); - message->data.button_template.button_offset = 0; - message->data.button_template.button_count = 0; - message->data.button_template.total_button_count = 0; - - helper.message = message; + message->data.button_template.button_offset = 0; + message->data.button_template.button_count = 0; + message->data.button_template.total_button_count = 0; - /* Add buttons */ - if ((sql = switch_mprintf( - "SELECT device_name, device_instance, position, MIN(type, %d) AS type " - "FROM skinny_buttons " - "WHERE device_name='%s' AND device_instance=%d " - "ORDER BY position", - SKINNY_BUTTON_UNDEFINED, - listener->device_name, listener->device_instance - ))) { - skinny_execute_sql_callback(profile, profile->sql_mutex, sql, skinny_handle_button_template_request_callback, &helper); - switch_safe_free(sql); - } - - /* Add lines */ - if ((sql = switch_mprintf( - "SELECT device_name, device_instance, position, %d AS type " - "FROM skinny_lines " - "WHERE device_name='%s' AND device_instance=%d " - "ORDER BY position", - SKINNY_BUTTON_LINE, - listener->device_name, listener->device_instance - ))) { - skinny_execute_sql_callback(profile, profile->sql_mutex, sql, skinny_handle_button_template_request_callback, &helper); - switch_safe_free(sql); - } - - /* Fill remaining buttons with Undefined */ - for(int i = 0; i+1 < helper.max_position; i++) { - if(message->data.button_template.btn[i].button_definition == SKINNY_BUTTON_UNKNOWN) { - message->data.button_template.btn[i].instance_number = ++helper.count[SKINNY_BUTTON_UNDEFINED]; - message->data.button_template.btn[i].button_definition = SKINNY_BUTTON_UNDEFINED; - message->data.button_template.button_count++; - message->data.button_template.total_button_count++; - } - } + helper.message = message; - skinny_send_reply(listener, message); + /* Add buttons */ + if ((sql = switch_mprintf( + "SELECT device_name, device_instance, position, MIN(type, %d) AS type " + "FROM skinny_buttons " + "WHERE device_name='%s' AND device_instance=%d " + "ORDER BY position", + SKINNY_BUTTON_UNDEFINED, + listener->device_name, listener->device_instance + ))) { + skinny_execute_sql_callback(profile, profile->sql_mutex, sql, skinny_handle_button_template_request_callback, &helper); + switch_safe_free(sql); + } - return SWITCH_STATUS_SUCCESS; + /* Add lines */ + if ((sql = switch_mprintf( + "SELECT device_name, device_instance, position, %d AS type " + "FROM skinny_lines " + "WHERE device_name='%s' AND device_instance=%d " + "ORDER BY position", + SKINNY_BUTTON_LINE, + listener->device_name, listener->device_instance + ))) { + skinny_execute_sql_callback(profile, profile->sql_mutex, sql, skinny_handle_button_template_request_callback, &helper); + switch_safe_free(sql); + } + + /* Fill remaining buttons with Undefined */ + for(int i = 0; i+1 < helper.max_position; i++) { + if(message->data.button_template.btn[i].button_definition == SKINNY_BUTTON_UNKNOWN) { + message->data.button_template.btn[i].instance_number = ++helper.count[SKINNY_BUTTON_UNDEFINED]; + message->data.button_template.btn[i].button_definition = SKINNY_BUTTON_UNDEFINED; + message->data.button_template.button_count++; + message->data.button_template.total_button_count++; + } + } + + skinny_send_reply(listener, message); + + return SWITCH_STATUS_SUCCESS; } switch_status_t skinny_handle_soft_key_template_request(listener_t *listener, skinny_message_t *request) { - skinny_message_t *message; - skinny_profile_t *profile; + skinny_message_t *message; + skinny_profile_t *profile; - switch_assert(listener->profile); - switch_assert(listener->device_name); + switch_assert(listener->profile); + switch_assert(listener->device_name); - profile = listener->profile; + profile = listener->profile; - message = switch_core_alloc(listener->pool, 12+sizeof(message->data.soft_key_template)); - message->type = SOFT_KEY_TEMPLATE_RES_MESSAGE; - message->length = 4 + sizeof(message->data.soft_key_template); + message = switch_core_alloc(listener->pool, 12+sizeof(message->data.soft_key_template)); + message->type = SOFT_KEY_TEMPLATE_RES_MESSAGE; + message->length = 4 + sizeof(message->data.soft_key_template); - message->data.soft_key_template.soft_key_offset = 0; - message->data.soft_key_template.soft_key_count = 21; - message->data.soft_key_template.total_soft_key_count = 21; - - memcpy(message->data.soft_key_template.soft_key, - soft_key_template_default, - sizeof(soft_key_template_default)); - - skinny_send_reply(listener, message); + message->data.soft_key_template.soft_key_offset = 0; + message->data.soft_key_template.soft_key_count = 21; + message->data.soft_key_template.total_soft_key_count = 21; - return SWITCH_STATUS_SUCCESS; + memcpy(message->data.soft_key_template.soft_key, + soft_key_template_default, + sizeof(soft_key_template_default)); + + skinny_send_reply(listener, message); + + return SWITCH_STATUS_SUCCESS; } switch_status_t skinny_handle_soft_key_set_request(listener_t *listener, skinny_message_t *request) { - skinny_message_t *message; - skinny_profile_t *profile; + skinny_message_t *message; + skinny_profile_t *profile; - switch_assert(listener->profile); - switch_assert(listener->device_name); + switch_assert(listener->profile); + switch_assert(listener->device_name); - profile = listener->profile; + profile = listener->profile; - message = switch_core_alloc(listener->pool, 12+sizeof(message->data.soft_key_set)); - message->type = SOFT_KEY_SET_RES_MESSAGE; - message->length = 4 + sizeof(message->data.soft_key_set); + message = switch_core_alloc(listener->pool, 12+sizeof(message->data.soft_key_set)); + message->type = SOFT_KEY_SET_RES_MESSAGE; + message->length = 4 + sizeof(message->data.soft_key_set); - message->data.soft_key_set.soft_key_set_offset = 0; - message->data.soft_key_set.soft_key_set_count = 11; - message->data.soft_key_set.total_soft_key_set_count = 11; - - /* TODO fill the set */ - message->data.soft_key_set.soft_key_set[SKINNY_KEY_SET_ON_HOOK].soft_key_template_index[0] = SOFTKEY_REDIAL; - message->data.soft_key_set.soft_key_set[SKINNY_KEY_SET_ON_HOOK].soft_key_template_index[1] = SOFTKEY_NEWCALL; - message->data.soft_key_set.soft_key_set[SKINNY_KEY_SET_CONNECTED].soft_key_template_index[0] = SOFTKEY_ENDCALL; - message->data.soft_key_set.soft_key_set[SKINNY_KEY_SET_RING_IN].soft_key_template_index[0] = SOFTKEY_ENDCALL; + message->data.soft_key_set.soft_key_set_offset = 0; + message->data.soft_key_set.soft_key_set_count = 11; + message->data.soft_key_set.total_soft_key_set_count = 11; - skinny_send_reply(listener, message); + /* TODO fill the set */ + message->data.soft_key_set.soft_key_set[SKINNY_KEY_SET_ON_HOOK].soft_key_template_index[0] = SOFTKEY_REDIAL; + message->data.soft_key_set.soft_key_set[SKINNY_KEY_SET_ON_HOOK].soft_key_template_index[1] = SOFTKEY_NEWCALL; + message->data.soft_key_set.soft_key_set[SKINNY_KEY_SET_CONNECTED].soft_key_template_index[0] = SOFTKEY_ENDCALL; + message->data.soft_key_set.soft_key_set[SKINNY_KEY_SET_RING_IN].soft_key_template_index[0] = SOFTKEY_ENDCALL; - /* Init the states */ + skinny_send_reply(listener, message); + + /* Init the states */ send_select_soft_keys(listener, 0, 0, SKINNY_KEY_SET_ON_HOOK, 0xffff); - - return SWITCH_STATUS_SUCCESS; + + return SWITCH_STATUS_SUCCESS; } switch_status_t skinny_handle_line_stat_request(listener_t *listener, skinny_message_t *request) { - skinny_message_t *message; - struct line_stat_res_message *button = NULL; + skinny_message_t *message; + struct line_stat_res_message *button = NULL; - skinny_check_data_length(request, sizeof(request->data.line_req)); + skinny_check_data_length(request, sizeof(request->data.line_req)); - message = switch_core_alloc(listener->pool, 12+sizeof(message->data.line_res)); - message->type = LINE_STAT_RES_MESSAGE; - message->length = 4 + sizeof(message->data.line_res); - - skinny_line_get(listener, request->data.line_req.number, &button); + message = switch_core_alloc(listener->pool, 12+sizeof(message->data.line_res)); + message->type = LINE_STAT_RES_MESSAGE; + message->length = 4 + sizeof(message->data.line_res); - memcpy(&message->data.line_res, button, sizeof(struct line_stat_res_message)); + skinny_line_get(listener, request->data.line_req.number, &button); - skinny_send_reply(listener, message); + memcpy(&message->data.line_res, button, sizeof(struct line_stat_res_message)); - return SWITCH_STATUS_SUCCESS; + skinny_send_reply(listener, message); + + return SWITCH_STATUS_SUCCESS; } switch_status_t skinny_handle_speed_dial_stat_request(listener_t *listener, skinny_message_t *request) { - skinny_message_t *message; - struct speed_dial_stat_res_message *button = NULL; + skinny_message_t *message; + struct speed_dial_stat_res_message *button = NULL; - skinny_check_data_length(request, sizeof(request->data.speed_dial_req)); + skinny_check_data_length(request, sizeof(request->data.speed_dial_req)); - message = switch_core_alloc(listener->pool, 12+sizeof(message->data.speed_dial_res)); - message->type = SPEED_DIAL_STAT_RES_MESSAGE; - message->length = 4 + sizeof(message->data.speed_dial_res); - - skinny_speed_dial_get(listener, request->data.speed_dial_req.number, &button); + message = switch_core_alloc(listener->pool, 12+sizeof(message->data.speed_dial_res)); + message->type = SPEED_DIAL_STAT_RES_MESSAGE; + message->length = 4 + sizeof(message->data.speed_dial_res); - memcpy(&message->data.speed_dial_res, button, sizeof(struct speed_dial_stat_res_message)); + skinny_speed_dial_get(listener, request->data.speed_dial_req.number, &button); - skinny_send_reply(listener, message); + memcpy(&message->data.speed_dial_res, button, sizeof(struct speed_dial_stat_res_message)); - return SWITCH_STATUS_SUCCESS; + skinny_send_reply(listener, message); + + return SWITCH_STATUS_SUCCESS; } switch_status_t skinny_handle_service_url_stat_request(listener_t *listener, skinny_message_t *request) { - skinny_message_t *message; - struct service_url_stat_res_message *button = NULL; + skinny_message_t *message; + struct service_url_stat_res_message *button = NULL; - skinny_check_data_length(request, sizeof(request->data.service_url_req)); + skinny_check_data_length(request, sizeof(request->data.service_url_req)); - message = switch_core_alloc(listener->pool, 12+sizeof(message->data.service_url_res)); - message->type = SERVICE_URL_STAT_RES_MESSAGE; - message->length = 4 + sizeof(message->data.service_url_res); - - skinny_service_url_get(listener, request->data.service_url_req.service_url_index, &button); + message = switch_core_alloc(listener->pool, 12+sizeof(message->data.service_url_res)); + message->type = SERVICE_URL_STAT_RES_MESSAGE; + message->length = 4 + sizeof(message->data.service_url_res); - memcpy(&message->data.service_url_res, button, sizeof(struct service_url_stat_res_message)); + skinny_service_url_get(listener, request->data.service_url_req.service_url_index, &button); - skinny_send_reply(listener, message); + memcpy(&message->data.service_url_res, button, sizeof(struct service_url_stat_res_message)); - return SWITCH_STATUS_SUCCESS; + skinny_send_reply(listener, message); + + return SWITCH_STATUS_SUCCESS; } switch_status_t skinny_handle_feature_stat_request(listener_t *listener, skinny_message_t *request) { - skinny_message_t *message; - struct feature_stat_res_message *button = NULL; + skinny_message_t *message; + struct feature_stat_res_message *button = NULL; - skinny_check_data_length(request, sizeof(request->data.feature_req)); + skinny_check_data_length(request, sizeof(request->data.feature_req)); - message = switch_core_alloc(listener->pool, 12+sizeof(message->data.feature_res)); - message->type = FEATURE_STAT_RES_MESSAGE; - message->length = 4 + sizeof(message->data.feature_res); - - skinny_feature_get(listener, request->data.feature_req.feature_index, &button); + message = switch_core_alloc(listener->pool, 12+sizeof(message->data.feature_res)); + message->type = FEATURE_STAT_RES_MESSAGE; + message->length = 4 + sizeof(message->data.feature_res); - memcpy(&message->data.feature_res, button, sizeof(struct feature_stat_res_message)); + skinny_feature_get(listener, request->data.feature_req.feature_index, &button); - skinny_send_reply(listener, message); + memcpy(&message->data.feature_res, button, sizeof(struct feature_stat_res_message)); - return SWITCH_STATUS_SUCCESS; + skinny_send_reply(listener, message); + + return SWITCH_STATUS_SUCCESS; } switch_status_t skinny_handle_register_available_lines_message(listener_t *listener, skinny_message_t *request) { - skinny_check_data_length(request, sizeof(request->data.reg_lines)); + skinny_check_data_length(request, sizeof(request->data.reg_lines)); - /* Do nothing */ - return SWITCH_STATUS_SUCCESS; + /* Do nothing */ + return SWITCH_STATUS_SUCCESS; } switch_status_t skinny_handle_time_date_request(listener_t *listener, skinny_message_t *request) { - skinny_message_t *message; - switch_time_t ts; - switch_time_exp_t tm; - - message = switch_core_alloc(listener->pool, 12+sizeof(message->data.define_time_date)); - message->type = DEFINE_TIME_DATE_MESSAGE; - message->length = 4+sizeof(message->data.define_time_date); - ts = switch_micro_time_now(); - switch_time_exp_lt(&tm, ts); - message->data.define_time_date.year = tm.tm_year + 1900; - message->data.define_time_date.month = tm.tm_mon + 1; - message->data.define_time_date.day_of_week = tm.tm_wday; - message->data.define_time_date.day = tm.tm_yday + 1; - message->data.define_time_date.hour = tm.tm_hour; - message->data.define_time_date.minute = tm.tm_min; - message->data.define_time_date.seconds = tm.tm_sec + 1; - message->data.define_time_date.milliseconds = tm.tm_usec / 1000; - message->data.define_time_date.timestamp = ts / 1000000; - skinny_send_reply(listener, message); - return SWITCH_STATUS_SUCCESS; + skinny_message_t *message; + switch_time_t ts; + switch_time_exp_t tm; + + message = switch_core_alloc(listener->pool, 12+sizeof(message->data.define_time_date)); + message->type = DEFINE_TIME_DATE_MESSAGE; + message->length = 4+sizeof(message->data.define_time_date); + ts = switch_micro_time_now(); + switch_time_exp_lt(&tm, ts); + message->data.define_time_date.year = tm.tm_year + 1900; + message->data.define_time_date.month = tm.tm_mon + 1; + message->data.define_time_date.day_of_week = tm.tm_wday; + message->data.define_time_date.day = tm.tm_yday + 1; + message->data.define_time_date.hour = tm.tm_hour; + message->data.define_time_date.minute = tm.tm_min; + message->data.define_time_date.seconds = tm.tm_sec + 1; + message->data.define_time_date.milliseconds = tm.tm_usec / 1000; + message->data.define_time_date.timestamp = ts / 1000000; + skinny_send_reply(listener, message); + return SWITCH_STATUS_SUCCESS; } switch_status_t skinny_handle_keep_alive_message(listener_t *listener, skinny_message_t *request) { - skinny_message_t *message; + skinny_message_t *message; - message = switch_core_alloc(listener->pool, 12); - message->type = KEEP_ALIVE_ACK_MESSAGE; - message->length = 4; - keepalive_listener(listener, NULL); - skinny_send_reply(listener, message); - return SWITCH_STATUS_SUCCESS; + message = switch_core_alloc(listener->pool, 12); + message->type = KEEP_ALIVE_ACK_MESSAGE; + message->length = 4; + keepalive_listener(listener, NULL); + skinny_send_reply(listener, message); + return SWITCH_STATUS_SUCCESS; } switch_status_t skinny_handle_soft_key_event_message(listener_t *listener, skinny_message_t *request) { - switch_status_t status = SWITCH_STATUS_SUCCESS; - uint32_t line_instance = 0; - switch_core_session_t *session = NULL; - switch_channel_t *channel = NULL; - private_t *tech_pvt = NULL; + switch_status_t status = SWITCH_STATUS_SUCCESS; + uint32_t line_instance = 0; + switch_core_session_t *session = NULL; + switch_channel_t *channel = NULL; + private_t *tech_pvt = NULL; switch_assert(listener); switch_assert(listener->profile); - skinny_check_data_length(request, sizeof(request->data.soft_key_event)); + skinny_check_data_length(request, sizeof(request->data.soft_key_event)); - line_instance = request->data.soft_key_event.line_instance; + line_instance = request->data.soft_key_event.line_instance; - switch(request->data.soft_key_event.event) { - case SOFTKEY_REDIAL: - status = skinny_create_ingoing_session(listener, &line_instance, &session); + switch(request->data.soft_key_event.event) { + case SOFTKEY_REDIAL: + status = skinny_create_ingoing_session(listener, &line_instance, &session); - skinny_session_process_dest(session, listener, line_instance, "redial", '\0', 0); - break; - case SOFTKEY_NEWCALL: - status = skinny_create_ingoing_session(listener, &line_instance, &session); - tech_pvt = switch_core_session_get_private(session); - assert(tech_pvt != NULL); + skinny_session_process_dest(session, listener, line_instance, "redial", '\0', 0); + break; + case SOFTKEY_NEWCALL: + status = skinny_create_ingoing_session(listener, &line_instance, &session); + tech_pvt = switch_core_session_get_private(session); + assert(tech_pvt != NULL); - skinny_session_process_dest(session, listener, line_instance, NULL, '\0', 0); - break; - case SOFTKEY_HOLD: + skinny_session_process_dest(session, listener, line_instance, NULL, '\0', 0); + break; + case SOFTKEY_HOLD: session = skinny_profile_find_session(listener->profile, listener, &line_instance, request->data.soft_key_event.call_id); - if(session) { + if(session) { status = skinny_session_hold_line(session, listener, line_instance); } - break; - case SOFTKEY_ENDCALL: + break; + case SOFTKEY_ENDCALL: session = skinny_profile_find_session(listener->profile, listener, &line_instance, request->data.soft_key_event.call_id); - if(session) { - channel = switch_core_session_get_channel(session); + if(session) { + channel = switch_core_session_get_channel(session); - switch_channel_hangup(channel, SWITCH_CAUSE_NORMAL_CLEARING); + switch_channel_hangup(channel, SWITCH_CAUSE_NORMAL_CLEARING); } - break; - case SOFTKEY_RESUME: + break; + case SOFTKEY_RESUME: session = skinny_profile_find_session(listener->profile, listener, &line_instance, request->data.soft_key_event.call_id); - if(session) { + if(session) { status = skinny_session_unhold_line(session, listener, line_instance); } - break; - case SOFTKEY_ANSWER: + break; + case SOFTKEY_ANSWER: session = skinny_profile_find_session(listener->profile, listener, &line_instance, request->data.soft_key_event.call_id); - if(session) { + if(session) { status = skinny_session_answer(session, listener, line_instance); - } - break; - default: - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, - "Unknown SoftKeyEvent type while busy: %d.\n", request->data.soft_key_event.event); - } + } + break; + default: + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, + "Unknown SoftKeyEvent type while busy: %d.\n", request->data.soft_key_event.event); + } if(session) { switch_core_session_rwunlock(session); } - - return status; + + return status; } switch_status_t skinny_handle_off_hook_message(listener_t *listener, skinny_message_t *request) { - uint32_t line_instance; - switch_core_session_t *session = NULL; - private_t *tech_pvt = NULL; + uint32_t line_instance; + switch_core_session_t *session = NULL; + private_t *tech_pvt = NULL; - skinny_check_data_length(request, sizeof(request->data.off_hook)); + skinny_check_data_length(request, sizeof(request->data.off_hook)); - if(request->data.off_hook.line_instance > 0) { - line_instance = request->data.off_hook.line_instance; - } else { - line_instance = 1; - } + if(request->data.off_hook.line_instance > 0) { + line_instance = request->data.off_hook.line_instance; + } else { + line_instance = 1; + } session = skinny_profile_find_session(listener->profile, listener, &line_instance, request->data.off_hook.call_id); - if(session) { /*answering a call */ - skinny_session_answer(session, listener, line_instance); - } else { /* start a new call */ - skinny_create_ingoing_session(listener, &line_instance, &session); - tech_pvt = switch_core_session_get_private(session); - assert(tech_pvt != NULL); + if(session) { /*answering a call */ + skinny_session_answer(session, listener, line_instance); + } else { /* start a new call */ + skinny_create_ingoing_session(listener, &line_instance, &session); + tech_pvt = switch_core_session_get_private(session); + assert(tech_pvt != NULL); - skinny_session_process_dest(session, listener, line_instance, NULL, '\0', 0); - } - return SWITCH_STATUS_SUCCESS; + skinny_session_process_dest(session, listener, line_instance, NULL, '\0', 0); + } + return SWITCH_STATUS_SUCCESS; } switch_status_t skinny_handle_stimulus_message(listener_t *listener, skinny_message_t *request) { - struct speed_dial_stat_res_message *button = NULL; - uint32_t line_instance = 0; - uint32_t call_id = 0; - switch_core_session_t *session = NULL; + struct speed_dial_stat_res_message *button = NULL; + uint32_t line_instance = 0; + uint32_t call_id = 0; + switch_core_session_t *session = NULL; - skinny_check_data_length(request, sizeof(request->data.stimulus)-sizeof(request->data.stimulus.call_id)); + skinny_check_data_length(request, sizeof(request->data.stimulus)-sizeof(request->data.stimulus.call_id)); - if(skinny_check_data_length_soft(request, sizeof(request->data.stimulus))) { - call_id = request->data.stimulus.call_id; - } + if(skinny_check_data_length_soft(request, sizeof(request->data.stimulus))) { + call_id = request->data.stimulus.call_id; + } - switch(request->data.stimulus.instance_type) { - case SKINNY_BUTTON_LAST_NUMBER_REDIAL: - skinny_create_ingoing_session(listener, &line_instance, &session); - skinny_session_process_dest(session, listener, line_instance, "redial", '\0', 0); - break; - case SKINNY_BUTTON_VOICEMAIL: - skinny_create_ingoing_session(listener, &line_instance, &session); - skinny_session_process_dest(session, listener, line_instance, "vmain", '\0', 0); - break; - case SKINNY_BUTTON_SPEED_DIAL: - skinny_speed_dial_get(listener, request->data.stimulus.instance, &button); - if(strlen(button->line) > 0) { - skinny_create_ingoing_session(listener, &line_instance, &session); - skinny_session_process_dest(session, listener, line_instance, button->line, '\0', 0); - } - break; - default: - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Unknown Stimulus Type Received [%d]\n", request->data.stimulus.instance_type); - } - return SWITCH_STATUS_SUCCESS; + switch(request->data.stimulus.instance_type) { + case SKINNY_BUTTON_LAST_NUMBER_REDIAL: + skinny_create_ingoing_session(listener, &line_instance, &session); + skinny_session_process_dest(session, listener, line_instance, "redial", '\0', 0); + break; + case SKINNY_BUTTON_VOICEMAIL: + skinny_create_ingoing_session(listener, &line_instance, &session); + skinny_session_process_dest(session, listener, line_instance, "vmain", '\0', 0); + break; + case SKINNY_BUTTON_SPEED_DIAL: + skinny_speed_dial_get(listener, request->data.stimulus.instance, &button); + if(strlen(button->line) > 0) { + skinny_create_ingoing_session(listener, &line_instance, &session); + skinny_session_process_dest(session, listener, line_instance, button->line, '\0', 0); + } + break; + default: + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Unknown Stimulus Type Received [%d]\n", request->data.stimulus.instance_type); + } + return SWITCH_STATUS_SUCCESS; } switch_status_t skinny_handle_open_receive_channel_ack_message(listener_t *listener, skinny_message_t *request) { - switch_status_t status = SWITCH_STATUS_SUCCESS; - uint32_t line_instance = 0; - switch_core_session_t *session; + switch_status_t status = SWITCH_STATUS_SUCCESS; + uint32_t line_instance = 0; + switch_core_session_t *session; - skinny_check_data_length(request, sizeof(request->data.open_receive_channel_ack)); + skinny_check_data_length(request, sizeof(request->data.open_receive_channel_ack)); session = skinny_profile_find_session(listener->profile, listener, &line_instance, request->data.open_receive_channel_ack.pass_thru_party_id); - if(session) { - const char *err = NULL; - private_t *tech_pvt = NULL; - switch_channel_t *channel = NULL; - struct in_addr addr; + if(session) { + const char *err = NULL; + private_t *tech_pvt = NULL; + switch_channel_t *channel = NULL; + struct in_addr addr; - tech_pvt = switch_core_session_get_private(session); - channel = switch_core_session_get_channel(session); + tech_pvt = switch_core_session_get_private(session); + channel = switch_core_session_get_channel(session); - /* Codec */ - tech_pvt->iananame = "PCMU"; /* TODO */ - tech_pvt->codec_ms = 10; /* TODO */ - tech_pvt->rm_rate = 8000; /* TODO */ - tech_pvt->rm_fmtp = NULL; /* TODO */ - tech_pvt->agreed_pt = (switch_payload_t) 0; /* TODO */ - tech_pvt->rm_encoding = switch_core_strdup(switch_core_session_get_pool(session), ""); - skinny_tech_set_codec(tech_pvt, 0); - if ((status = skinny_tech_set_codec(tech_pvt, 0)) != SWITCH_STATUS_SUCCESS) { - goto end; - } - - /* Request a local port from the core's allocator */ - if (!(tech_pvt->local_sdp_audio_port = switch_rtp_request_port(listener->profile->ip))) { - switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(tech_pvt->session), SWITCH_LOG_CRIT, "No RTP ports available!\n"); - return SWITCH_STATUS_FALSE; - } - tech_pvt->local_sdp_audio_ip = switch_core_strdup(switch_core_session_get_pool(session), listener->profile->ip); - - tech_pvt->remote_sdp_audio_ip = inet_ntoa(request->data.open_receive_channel_ack.ip); - tech_pvt->remote_sdp_audio_port = request->data.open_receive_channel_ack.port; - - tech_pvt->rtp_session = switch_rtp_new(tech_pvt->local_sdp_audio_ip, - tech_pvt->local_sdp_audio_port, - tech_pvt->remote_sdp_audio_ip, - tech_pvt->remote_sdp_audio_port, - tech_pvt->agreed_pt, - tech_pvt->read_impl.samples_per_packet, - tech_pvt->codec_ms * 1000, - (switch_rtp_flag_t) 0, "soft", &err, - switch_core_session_get_pool(session)); - switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(tech_pvt->session), SWITCH_LOG_DEBUG, - "AUDIO RTP [%s] %s:%d->%s:%d codec: %u ms: %d [%s]\n", - switch_channel_get_name(channel), - tech_pvt->local_sdp_audio_ip, - tech_pvt->local_sdp_audio_port, - tech_pvt->remote_sdp_audio_ip, - tech_pvt->remote_sdp_audio_port, - tech_pvt->agreed_pt, - tech_pvt->read_impl.microseconds_per_packet / 1000, - switch_rtp_ready(tech_pvt->rtp_session) ? "SUCCESS" : err); - inet_aton(tech_pvt->local_sdp_audio_ip, &addr); - start_media_transmission(listener, - tech_pvt->call_id, /* uint32_t conference_id, */ - tech_pvt->party_id, /* uint32_t pass_thru_party_id, */ - addr.s_addr, /* uint32_t remote_ip, */ - tech_pvt->local_sdp_audio_port, /* uint32_t remote_port, */ - 20, /* uint32_t ms_per_packet, */ - SKINNY_CODEC_ULAW_64K, /* uint32_t payload_capacity, */ - 184, /* uint32_t precedence, */ - 0, /* uint32_t silence_suppression, */ - 0, /* uint16_t max_frames_per_packet, */ - 0 /* uint32_t g723_bitrate */ - ); - if (switch_channel_get_state(channel) == CS_NEW) { - switch_channel_set_state(channel, CS_INIT); + /* Codec */ + tech_pvt->iananame = "PCMU"; /* TODO */ + tech_pvt->codec_ms = 10; /* TODO */ + tech_pvt->rm_rate = 8000; /* TODO */ + tech_pvt->rm_fmtp = NULL; /* TODO */ + tech_pvt->agreed_pt = (switch_payload_t) 0; /* TODO */ + tech_pvt->rm_encoding = switch_core_strdup(switch_core_session_get_pool(session), ""); + skinny_tech_set_codec(tech_pvt, 0); + if ((status = skinny_tech_set_codec(tech_pvt, 0)) != SWITCH_STATUS_SUCCESS) { + goto end; } - switch_channel_mark_answered(channel); - - switch_core_session_rwunlock(session); - } + + /* Request a local port from the core's allocator */ + if (!(tech_pvt->local_sdp_audio_port = switch_rtp_request_port(listener->profile->ip))) { + switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(tech_pvt->session), SWITCH_LOG_CRIT, "No RTP ports available!\n"); + return SWITCH_STATUS_FALSE; + } + tech_pvt->local_sdp_audio_ip = switch_core_strdup(switch_core_session_get_pool(session), listener->profile->ip); + + tech_pvt->remote_sdp_audio_ip = inet_ntoa(request->data.open_receive_channel_ack.ip); + tech_pvt->remote_sdp_audio_port = request->data.open_receive_channel_ack.port; + + tech_pvt->rtp_session = switch_rtp_new(tech_pvt->local_sdp_audio_ip, + tech_pvt->local_sdp_audio_port, + tech_pvt->remote_sdp_audio_ip, + tech_pvt->remote_sdp_audio_port, + tech_pvt->agreed_pt, + tech_pvt->read_impl.samples_per_packet, + tech_pvt->codec_ms * 1000, + (switch_rtp_flag_t) 0, "soft", &err, + switch_core_session_get_pool(session)); + switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(tech_pvt->session), SWITCH_LOG_DEBUG, + "AUDIO RTP [%s] %s:%d->%s:%d codec: %u ms: %d [%s]\n", + switch_channel_get_name(channel), + tech_pvt->local_sdp_audio_ip, + tech_pvt->local_sdp_audio_port, + tech_pvt->remote_sdp_audio_ip, + tech_pvt->remote_sdp_audio_port, + tech_pvt->agreed_pt, + tech_pvt->read_impl.microseconds_per_packet / 1000, + switch_rtp_ready(tech_pvt->rtp_session) ? "SUCCESS" : err); + inet_aton(tech_pvt->local_sdp_audio_ip, &addr); + start_media_transmission(listener, + tech_pvt->call_id, /* uint32_t conference_id, */ + tech_pvt->party_id, /* uint32_t pass_thru_party_id, */ + addr.s_addr, /* uint32_t remote_ip, */ + tech_pvt->local_sdp_audio_port, /* uint32_t remote_port, */ + 20, /* uint32_t ms_per_packet, */ + SKINNY_CODEC_ULAW_64K, /* uint32_t payload_capacity, */ + 184, /* uint32_t precedence, */ + 0, /* uint32_t silence_suppression, */ + 0, /* uint16_t max_frames_per_packet, */ + 0 /* uint32_t g723_bitrate */ + ); + if (switch_channel_get_state(channel) == CS_NEW) { + switch_channel_set_state(channel, CS_INIT); + } + switch_channel_mark_answered(channel); + + switch_core_session_rwunlock(session); + } end: - return status; + return status; } switch_status_t skinny_handle_keypad_button_message(listener_t *listener, skinny_message_t *request) { - uint32_t line_instance = 0; - switch_core_session_t *session; + uint32_t line_instance = 0; + switch_core_session_t *session; - skinny_check_data_length(request, sizeof(request->data.keypad_button)); + skinny_check_data_length(request, sizeof(request->data.keypad_button)); if(request->data.keypad_button.line_instance) { line_instance = request->data.keypad_button.line_instance; @@ -2107,169 +2107,169 @@ switch_status_t skinny_handle_keypad_button_message(listener_t *listener, skinny session = skinny_profile_find_session(listener->profile, listener, &line_instance, request->data.keypad_button.call_id); - if(session) { - switch_channel_t *channel = NULL; - private_t *tech_pvt = NULL; - char digit = '\0'; + if(session) { + switch_channel_t *channel = NULL; + private_t *tech_pvt = NULL; + char digit = '\0'; - channel = switch_core_session_get_channel(session); - tech_pvt = switch_core_session_get_private(session); + channel = switch_core_session_get_channel(session); + tech_pvt = switch_core_session_get_private(session); + + switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "SEND DTMF ON CALL %d [%d]\n", tech_pvt->call_id, request->data.keypad_button.button); + + if (request->data.keypad_button.button == 14) { + digit = '*'; + } else if (request->data.keypad_button.button == 15) { + digit = '#'; + } else if (request->data.keypad_button.button >= 0 && request->data.keypad_button.button <= 9) { + digit = '0' + request->data.keypad_button.button; + } else { + switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_WARNING, "UNKNOW DTMF RECEIVED ON CALL %d [%d]\n", tech_pvt->call_id, request->data.keypad_button.button); + } + + /* TODO check call_id and line */ + + if((skinny_line_get_state(listener, line_instance, tech_pvt->call_id) == SKINNY_OFF_HOOK)) { - switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "SEND DTMF ON CALL %d [%d]\n", tech_pvt->call_id, request->data.keypad_button.button); - - if (request->data.keypad_button.button == 14) { - digit = '*'; - } else if (request->data.keypad_button.button == 15) { - digit = '#'; - } else if (request->data.keypad_button.button >= 0 && request->data.keypad_button.button <= 9) { - digit = '0' + request->data.keypad_button.button; - } else { - switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_WARNING, "UNKNOW DTMF RECEIVED ON CALL %d [%d]\n", tech_pvt->call_id, request->data.keypad_button.button); - } - - /* TODO check call_id and line */ - - if((skinny_line_get_state(listener, line_instance, tech_pvt->call_id) == SKINNY_OFF_HOOK)) { - - skinny_session_process_dest(session, listener, line_instance, NULL, digit, 0); - } else { - if(digit != '\0') { - switch_dtmf_t dtmf = { 0, switch_core_default_dtmf_duration(0)}; - dtmf.digit = digit; - switch_channel_queue_dtmf(channel, &dtmf); - } - } + skinny_session_process_dest(session, listener, line_instance, NULL, digit, 0); + } else { + if(digit != '\0') { + switch_dtmf_t dtmf = { 0, switch_core_default_dtmf_duration(0)}; + dtmf.digit = digit; + switch_channel_queue_dtmf(channel, &dtmf); + } + } switch_core_session_rwunlock(session); - } + } - return SWITCH_STATUS_SUCCESS; + return SWITCH_STATUS_SUCCESS; } switch_status_t skinny_handle_on_hook_message(listener_t *listener, skinny_message_t *request) { - switch_status_t status = SWITCH_STATUS_SUCCESS; - switch_core_session_t *session = NULL; - uint32_t line_instance = 0; + switch_status_t status = SWITCH_STATUS_SUCCESS; + switch_core_session_t *session = NULL; + uint32_t line_instance = 0; - skinny_check_data_length(request, sizeof(request->data.on_hook)); + skinny_check_data_length(request, sizeof(request->data.on_hook)); line_instance = request->data.on_hook.line_instance; session = skinny_profile_find_session(listener->profile, listener, &line_instance, request->data.on_hook.call_id); - if(session) { - switch_channel_t *channel = NULL; + if(session) { + switch_channel_t *channel = NULL; - channel = switch_core_session_get_channel(session); + channel = switch_core_session_get_channel(session); - switch_channel_hangup(channel, SWITCH_CAUSE_NORMAL_CLEARING); - - switch_core_session_rwunlock(session); - } - return status; + switch_channel_hangup(channel, SWITCH_CAUSE_NORMAL_CLEARING); + + switch_core_session_rwunlock(session); + } + return status; } switch_status_t skinny_handle_unregister(listener_t *listener, skinny_message_t *request) { - switch_event_t *event = NULL; - skinny_message_t *message; + switch_event_t *event = NULL; + skinny_message_t *message; - /* skinny::unregister event */ - skinny_device_event(listener, &event, SWITCH_EVENT_CUSTOM, SKINNY_EVENT_UNREGISTER); - switch_event_fire(&event); + /* skinny::unregister event */ + skinny_device_event(listener, &event, SWITCH_EVENT_CUSTOM, SKINNY_EVENT_UNREGISTER); + switch_event_fire(&event); - message = switch_core_alloc(listener->pool, 12+sizeof(message->data.unregister_ack)); - message->type = UNREGISTER_ACK_MESSAGE; - message->length = 4 + sizeof(message->data.unregister_ack); - message->data.unregister_ack.unregister_status = 0; /* OK */ - skinny_send_reply(listener, message); + message = switch_core_alloc(listener->pool, 12+sizeof(message->data.unregister_ack)); + message->type = UNREGISTER_ACK_MESSAGE; + message->length = 4 + sizeof(message->data.unregister_ack); + message->data.unregister_ack.unregister_status = 0; /* OK */ + skinny_send_reply(listener, message); - /* Close socket */ - switch_clear_flag_locked(listener, LFLAG_RUNNING); + /* Close socket */ + switch_clear_flag_locked(listener, LFLAG_RUNNING); - return SWITCH_STATUS_SUCCESS; + return SWITCH_STATUS_SUCCESS; } switch_status_t skinny_handle_request(listener_t *listener, skinny_message_t *request) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, - "Received %s (type=%x,length=%d).\n", skinny_message_type2str(request->type), request->type, request->length); - if(zstr(listener->device_name) && request->type != REGISTER_MESSAGE && request->type != ALARM_MESSAGE) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, - "Device should send a register message first.\n"); - return SWITCH_STATUS_FALSE; - } - switch(request->type) { - case ALARM_MESSAGE: - return skinny_handle_alarm(listener, request); - /* registering phase */ - case REGISTER_MESSAGE: - return skinny_handle_register(listener, request); - case HEADSET_STATUS_MESSAGE: - return skinny_headset_status_message(listener, request); - case CONFIG_STAT_REQ_MESSAGE: - return skinny_handle_config_stat_request(listener, request); - case CAPABILITIES_RES_MESSAGE: - return skinny_handle_capabilities_response(listener, request); - case PORT_MESSAGE: - return skinny_handle_port_message(listener, request); - case BUTTON_TEMPLATE_REQ_MESSAGE: - return skinny_handle_button_template_request(listener, request); - case SOFT_KEY_TEMPLATE_REQ_MESSAGE: - return skinny_handle_soft_key_template_request(listener, request); - case SOFT_KEY_SET_REQ_MESSAGE: - return skinny_handle_soft_key_set_request(listener, request); - case LINE_STAT_REQ_MESSAGE: - return skinny_handle_line_stat_request(listener, request); - case SPEED_DIAL_STAT_REQ_MESSAGE: - return skinny_handle_speed_dial_stat_request(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 REGISTER_AVAILABLE_LINES_MESSAGE: - return skinny_handle_register_available_lines_message(listener, request); - case TIME_DATE_REQ_MESSAGE: - return skinny_handle_time_date_request(listener, request); - /* live phase */ - case KEEP_ALIVE_MESSAGE: - return skinny_handle_keep_alive_message(listener, request); - case SOFT_KEY_EVENT_MESSAGE: - return skinny_handle_soft_key_event_message(listener, request); - case OFF_HOOK_MESSAGE: - return skinny_handle_off_hook_message(listener, request); - case STIMULUS_MESSAGE: - return skinny_handle_stimulus_message(listener, request); - case OPEN_RECEIVE_CHANNEL_ACK_MESSAGE: - return skinny_handle_open_receive_channel_ack_message(listener, request); - case KEYPAD_BUTTON_MESSAGE: - return skinny_handle_keypad_button_message(listener, request); - case ON_HOOK_MESSAGE: - return skinny_handle_on_hook_message(listener, request); - /* end phase */ - case UNREGISTER_MESSAGE: - return skinny_handle_unregister(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); - return SWITCH_STATUS_SUCCESS; - } + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, + "Received %s (type=%x,length=%d).\n", skinny_message_type2str(request->type), request->type, request->length); + if(zstr(listener->device_name) && request->type != REGISTER_MESSAGE && request->type != ALARM_MESSAGE) { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, + "Device should send a register message first.\n"); + return SWITCH_STATUS_FALSE; + } + switch(request->type) { + case ALARM_MESSAGE: + return skinny_handle_alarm(listener, request); + /* registering phase */ + case REGISTER_MESSAGE: + return skinny_handle_register(listener, request); + case HEADSET_STATUS_MESSAGE: + return skinny_headset_status_message(listener, request); + case CONFIG_STAT_REQ_MESSAGE: + return skinny_handle_config_stat_request(listener, request); + case CAPABILITIES_RES_MESSAGE: + return skinny_handle_capabilities_response(listener, request); + case PORT_MESSAGE: + return skinny_handle_port_message(listener, request); + case BUTTON_TEMPLATE_REQ_MESSAGE: + return skinny_handle_button_template_request(listener, request); + case SOFT_KEY_TEMPLATE_REQ_MESSAGE: + return skinny_handle_soft_key_template_request(listener, request); + case SOFT_KEY_SET_REQ_MESSAGE: + return skinny_handle_soft_key_set_request(listener, request); + case LINE_STAT_REQ_MESSAGE: + return skinny_handle_line_stat_request(listener, request); + case SPEED_DIAL_STAT_REQ_MESSAGE: + return skinny_handle_speed_dial_stat_request(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 REGISTER_AVAILABLE_LINES_MESSAGE: + return skinny_handle_register_available_lines_message(listener, request); + case TIME_DATE_REQ_MESSAGE: + return skinny_handle_time_date_request(listener, request); + /* live phase */ + case KEEP_ALIVE_MESSAGE: + return skinny_handle_keep_alive_message(listener, request); + case SOFT_KEY_EVENT_MESSAGE: + return skinny_handle_soft_key_event_message(listener, request); + case OFF_HOOK_MESSAGE: + return skinny_handle_off_hook_message(listener, request); + case STIMULUS_MESSAGE: + return skinny_handle_stimulus_message(listener, request); + case OPEN_RECEIVE_CHANNEL_ACK_MESSAGE: + return skinny_handle_open_receive_channel_ack_message(listener, request); + case KEYPAD_BUTTON_MESSAGE: + return skinny_handle_keypad_button_message(listener, request); + case ON_HOOK_MESSAGE: + return skinny_handle_on_hook_message(listener, request); + /* end phase */ + case UNREGISTER_MESSAGE: + return skinny_handle_unregister(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); + return SWITCH_STATUS_SUCCESS; + } } switch_status_t skinny_perform_send_reply(listener_t *listener, const char *file, const char *func, int line, skinny_message_t *reply) { - char *ptr; - switch_size_t len; - switch_assert(reply != NULL); - len = reply->length+8; - ptr = (char *) reply; + char *ptr; + switch_size_t len; + switch_assert(reply != NULL); + len = reply->length+8; + ptr = (char *) reply; - switch_log_printf(SWITCH_CHANNEL_ID_LOG, file, func, line, NULL, SWITCH_LOG_DEBUG, - "Sending %s (type=%x,length=%d).\n", - skinny_message_type2str(reply->type), reply->type, reply->length); - switch_socket_send(listener->sock, ptr, &len); + switch_log_printf(SWITCH_CHANNEL_ID_LOG, file, func, line, NULL, SWITCH_LOG_DEBUG, + "Sending %s (type=%x,length=%d).\n", + skinny_message_type2str(reply->type), reply->type, reply->length); + switch_socket_send(listener->sock, ptr, &len); - return SWITCH_STATUS_SUCCESS; + return SWITCH_STATUS_SUCCESS; } /* For Emacs: diff --git a/src/mod/endpoints/mod_skinny/skinny_protocol.h b/src/mod/endpoints/mod_skinny/skinny_protocol.h index 1a28b66ee9..401ad8b220 100644 --- a/src/mod/endpoints/mod_skinny/skinny_protocol.h +++ b/src/mod/endpoints/mod_skinny/skinny_protocol.h @@ -49,60 +49,60 @@ /* RegisterMessage */ #define REGISTER_MESSAGE 0x0001 struct register_message { - char device_name[16]; - uint32_t user_id; - uint32_t instance; - struct in_addr ip; - uint32_t device_type; - uint32_t max_streams; + char device_name[16]; + uint32_t user_id; + uint32_t instance; + struct in_addr ip; + uint32_t device_type; + uint32_t max_streams; }; /* PortMessage */ #define PORT_MESSAGE 0x0002 struct port_message { - uint16_t port; + uint16_t port; }; /* KeypadButtonMessage */ #define KEYPAD_BUTTON_MESSAGE 0x0003 struct keypad_button_message { - uint32_t button; - uint32_t line_instance; - uint32_t call_id; + uint32_t button; + uint32_t line_instance; + uint32_t call_id; }; /* StimulusMessage */ #define STIMULUS_MESSAGE 0x0005 struct stimulus_message { - uint32_t instance_type; /* See enum skinny_button_definition */ - uint32_t instance; - uint32_t call_id; + uint32_t instance_type; /* See enum skinny_button_definition */ + uint32_t instance; + uint32_t call_id; }; /* OffHookMessage */ #define OFF_HOOK_MESSAGE 0x0006 struct off_hook_message { - uint32_t line_instance; - uint32_t call_id; + uint32_t line_instance; + uint32_t call_id; }; /* OnHookMessage */ #define ON_HOOK_MESSAGE 0x0007 struct on_hook_message { - uint32_t line_instance; - uint32_t call_id; + uint32_t line_instance; + uint32_t call_id; }; /* SpeedDialStatReqMessage */ #define SPEED_DIAL_STAT_REQ_MESSAGE 0x000A struct speed_dial_stat_req_message { - uint32_t number; + uint32_t number; }; /* LineStatReqMessage */ #define LINE_STAT_REQ_MESSAGE 0x000B struct line_stat_req_message { - uint32_t number; + uint32_t number; }; /* ConfigStatReqMessage */ @@ -117,32 +117,32 @@ struct line_stat_req_message { /* CapabilitiesResMessage */ #define CAPABILITIES_RES_MESSAGE 0x0010 struct station_capabilities { - uint32_t codec; - uint16_t frames; - char reserved[10]; + uint32_t codec; + uint16_t frames; + char reserved[10]; }; struct capabilities_res_message { - uint32_t count; - struct station_capabilities caps[SWITCH_MAX_CODECS]; + uint32_t count; + struct station_capabilities caps[SWITCH_MAX_CODECS]; }; /* AlarmMessage */ #define ALARM_MESSAGE 0x0020 struct alarm_message { - uint32_t alarm_severity; - char display_message[80]; - uint32_t alarm_param1; - uint32_t alarm_param2; + uint32_t alarm_severity; + char display_message[80]; + uint32_t alarm_param1; + uint32_t alarm_param2; }; /* OpenReceiveChannelAck */ #define OPEN_RECEIVE_CHANNEL_ACK_MESSAGE 0x0022 struct open_receive_channel_ack_message { - uint32_t status; - struct in_addr ip; - uint32_t port; - uint32_t pass_thru_party_id; + uint32_t status; + struct in_addr ip; + uint32_t port; + uint32_t pass_thru_party_id; }; /* SoftKeySetReqMessage */ @@ -151,9 +151,9 @@ struct open_receive_channel_ack_message { /* SoftKeyEventMessage */ #define SOFT_KEY_EVENT_MESSAGE 0x0026 struct soft_key_event_message { - uint32_t event; - uint32_t line_instance; - uint32_t call_id; + uint32_t event; + uint32_t line_instance; + uint32_t call_id; }; /* UnregisterMessage */ @@ -165,182 +165,182 @@ struct soft_key_event_message { /* ServiceUrlStatReqMessage */ #define SERVICE_URL_STAT_REQ_MESSAGE 0x0033 struct service_url_stat_req_message { - uint32_t service_url_index; + uint32_t service_url_index; }; /* FeatureStatReqMessage */ #define FEATURE_STAT_REQ_MESSAGE 0x0034 struct feature_stat_req_message { - uint32_t feature_index; + uint32_t feature_index; }; /* HeadsetStatusMessage */ #define HEADSET_STATUS_MESSAGE 0x002B struct headset_status_message { - uint32_t mode; + uint32_t mode; }; /* RegisterAvailableLinesMessage */ #define REGISTER_AVAILABLE_LINES_MESSAGE 0x002D struct register_available_lines_message { - uint32_t count; + uint32_t count; }; /* RegisterAckMessage */ #define REGISTER_ACK_MESSAGE 0x0081 struct register_ack_message { - uint32_t keep_alive; - char date_format[6]; - char reserved[2]; - uint32_t secondary_keep_alive; - char reserved2[4]; + uint32_t keep_alive; + char date_format[6]; + char reserved[2]; + uint32_t secondary_keep_alive; + char reserved2[4]; }; /* StartToneMessage */ #define START_TONE_MESSAGE 0x0082 struct start_tone_message { - uint32_t tone; /* see enum skinny_tone */ - uint32_t reserved; - uint32_t line_instance; - uint32_t call_id; + uint32_t tone; /* see enum skinny_tone */ + uint32_t reserved; + uint32_t line_instance; + uint32_t call_id; }; /* StopToneMessage */ #define STOP_TONE_MESSAGE 0x0083 struct stop_tone_message { - uint32_t line_instance; - uint32_t call_id; + uint32_t line_instance; + uint32_t call_id; }; /* SetRingerMessage */ #define SET_RINGER_MESSAGE 0x0085 struct set_ringer_message { - uint32_t ring_type; /* See enum skinny_ring_type */ - uint32_t ring_mode; /* See enum skinny_ring_mode */ - uint32_t line_instance; - uint32_t call_id; + uint32_t ring_type; /* See enum skinny_ring_type */ + uint32_t ring_mode; /* See enum skinny_ring_mode */ + uint32_t line_instance; + uint32_t call_id; }; /* SetLampMessage */ #define SET_LAMP_MESSAGE 0x0086 struct set_lamp_message { - uint32_t stimulus; /* See enum skinny_button_definition */ - uint32_t stimulus_instance; - uint32_t mode; /* See enum skinny_lamp_mode */ + uint32_t stimulus; /* See enum skinny_button_definition */ + uint32_t stimulus_instance; + uint32_t mode; /* See enum skinny_lamp_mode */ }; /* SetSpeakerModeMessage */ #define SET_SPEAKER_MODE_MESSAGE 0x0088 struct set_speaker_mode_message { - uint32_t mode; /* See enum skinny_speaker_mode */ + uint32_t mode; /* See enum skinny_speaker_mode */ }; /* StartMediaTransmissionMessage */ #define START_MEDIA_TRANSMISSION_MESSAGE 0x008A struct start_media_transmission_message { - uint32_t conference_id; - uint32_t pass_thru_party_id; - uint32_t remote_ip; - uint32_t remote_port; - uint32_t ms_per_packet; - uint32_t payload_capacity; - uint32_t precedence; - uint32_t silence_suppression; - uint16_t max_frames_per_packet; - uint32_t g723_bitrate; - /* ... */ + uint32_t conference_id; + uint32_t pass_thru_party_id; + uint32_t remote_ip; + uint32_t remote_port; + uint32_t ms_per_packet; + uint32_t payload_capacity; + uint32_t precedence; + uint32_t silence_suppression; + uint16_t max_frames_per_packet; + uint32_t g723_bitrate; + /* ... */ }; /* StopMediaTransmissionMessage */ #define STOP_MEDIA_TRANSMISSION_MESSAGE 0x008B struct stop_media_transmission_message { - uint32_t conference_id; - uint32_t pass_thru_party_id; - uint32_t conference_id2; - /* ... */ + uint32_t conference_id; + uint32_t pass_thru_party_id; + uint32_t conference_id2; + /* ... */ }; /* CallInfoMessage */ #define CALL_INFO_MESSAGE 0x008F struct call_info_message { - char calling_party_name[40]; - char calling_party[24]; - char called_party_name[40]; - char called_party[24]; - uint32_t line_instance; - uint32_t call_id; - uint32_t call_type; /* See enum skinny_call_type */ - char original_called_party_name[40]; - char original_called_party[24]; - char last_redirecting_party_name[40]; - char last_redirecting_party[24]; - uint32_t original_called_party_redirect_reason; - uint32_t last_redirecting_reason; - char calling_party_voice_mailbox[24]; - char called_party_voice_mailbox[24]; - char original_called_party_voice_mailbox[24]; - char last_redirecting_voice_mailbox[24]; - uint32_t call_instance; - uint32_t call_security_status; - uint32_t party_pi_restriction_bits; + char calling_party_name[40]; + char calling_party[24]; + char called_party_name[40]; + char called_party[24]; + uint32_t line_instance; + uint32_t call_id; + uint32_t call_type; /* See enum skinny_call_type */ + char original_called_party_name[40]; + char original_called_party[24]; + char last_redirecting_party_name[40]; + char last_redirecting_party[24]; + uint32_t original_called_party_redirect_reason; + uint32_t last_redirecting_reason; + char calling_party_voice_mailbox[24]; + char called_party_voice_mailbox[24]; + char original_called_party_voice_mailbox[24]; + char last_redirecting_voice_mailbox[24]; + uint32_t call_instance; + uint32_t call_security_status; + uint32_t party_pi_restriction_bits; }; /* SpeedDialStatMessage */ #define SPEED_DIAL_STAT_RES_MESSAGE 0x0091 struct speed_dial_stat_res_message { - uint32_t number; - char line[24]; - char label[40]; + uint32_t number; + char line[24]; + char label[40]; }; /* LineStatMessage */ #define LINE_STAT_RES_MESSAGE 0x0092 struct line_stat_res_message { - uint32_t number; - char name[24]; - char shortname[40]; - char displayname[44]; + uint32_t number; + char name[24]; + char shortname[40]; + char displayname[44]; }; /* ConfigStatMessage */ #define CONFIG_STAT_RES_MESSAGE 0x0093 struct config_stat_res_message { - char device_name[16]; - uint32_t user_id; - uint32_t instance; - char user_name[40]; - char server_name[40]; - uint32_t number_lines; - uint32_t number_speed_dials; + char device_name[16]; + uint32_t user_id; + uint32_t instance; + char user_name[40]; + char server_name[40]; + uint32_t number_lines; + uint32_t number_speed_dials; }; /* DefineTimeDate */ #define DEFINE_TIME_DATE_MESSAGE 0x0094 struct define_time_date_message { - uint32_t year; - uint32_t month; - uint32_t day_of_week; /* monday = 1 */ - uint32_t day; - uint32_t hour; - uint32_t minute; - uint32_t seconds; - uint32_t milliseconds; - uint32_t timestamp; + uint32_t year; + uint32_t month; + uint32_t day_of_week; /* monday = 1 */ + uint32_t day; + uint32_t hour; + uint32_t minute; + uint32_t seconds; + uint32_t milliseconds; + uint32_t timestamp; }; /* ButtonTemplateMessage */ #define BUTTON_TEMPLATE_RES_MESSAGE 0x0097 struct button_definition { - uint8_t instance_number; - uint8_t button_definition; /* See enum skinny_button_definition */ + uint8_t instance_number; + uint8_t button_definition; /* See enum skinny_button_definition */ }; #define SKINNY_MAX_BUTTON_COUNT 42 struct button_template_message { - uint32_t button_offset; - uint32_t button_count; - uint32_t total_button_count; - struct button_definition btn[SKINNY_MAX_BUTTON_COUNT]; + uint32_t button_offset; + uint32_t button_count; + uint32_t total_button_count; + struct button_definition btn[SKINNY_MAX_BUTTON_COUNT]; }; /* CapabilitiesReqMessage */ @@ -349,13 +349,13 @@ struct button_template_message { /* RegisterRejectMessage */ #define REGISTER_REJ_MESSAGE 0x009D struct register_rej_message { - char error[33]; + char error[33]; }; /* ResetMessage */ #define RESET_MESSAGE 0x009F struct reset_message { - uint32_t reset_type; /* See enum skinny_device_reset_types */ + uint32_t reset_type; /* See enum skinny_device_reset_types */ }; /* KeepAliveAckMessage */ @@ -364,130 +364,130 @@ struct reset_message { /* OpenReceiveChannelMessage */ #define OPEN_RECEIVE_CHANNEL_MESSAGE 0x0105 struct open_receive_channel_message { - uint32_t conference_id; - uint32_t pass_thru_party_id; - uint32_t packets; - uint32_t payload_capacity; - uint32_t echo_cancel_type; - uint32_t g723_bitrate; - uint32_t conference_id2; - uint32_t reserved[10]; + uint32_t conference_id; + uint32_t pass_thru_party_id; + uint32_t packets; + uint32_t payload_capacity; + uint32_t echo_cancel_type; + uint32_t g723_bitrate; + uint32_t conference_id2; + uint32_t reserved[10]; }; /* CloseReceiveChannelMessage */ #define CLOSE_RECEIVE_CHANNEL_MESSAGE 0x0106 struct close_receive_channel_message { - uint32_t conference_id; - uint32_t pass_thru_party_id; - uint32_t conference_id2; + uint32_t conference_id; + uint32_t pass_thru_party_id; + uint32_t conference_id2; }; /* SoftKeyTemplateResMessage */ #define SOFT_KEY_TEMPLATE_RES_MESSAGE 0x0108 struct soft_key_template_definition { - char soft_key_label[16]; - uint32_t soft_key_event; + char soft_key_label[16]; + uint32_t soft_key_event; }; struct soft_key_template_res_message { - uint32_t soft_key_offset; - uint32_t soft_key_count; - uint32_t total_soft_key_count; - struct soft_key_template_definition soft_key[32]; + uint32_t soft_key_offset; + uint32_t soft_key_count; + uint32_t total_soft_key_count; + struct soft_key_template_definition soft_key[32]; }; /* SoftKeySetResMessage */ #define SOFT_KEY_SET_RES_MESSAGE 0x0109 struct soft_key_set_definition { - uint8_t soft_key_template_index[16]; /* See enum skinny_soft_key_event */ - uint16_t soft_key_info_index[16]; + uint8_t soft_key_template_index[16]; /* See enum skinny_soft_key_event */ + uint16_t soft_key_info_index[16]; }; struct soft_key_set_res_message { - uint32_t soft_key_set_offset; - uint32_t soft_key_set_count; - uint32_t total_soft_key_set_count; - struct soft_key_set_definition soft_key_set[16]; - uint32_t res; + uint32_t soft_key_set_offset; + uint32_t soft_key_set_count; + uint32_t total_soft_key_set_count; + struct soft_key_set_definition soft_key_set[16]; + uint32_t res; }; /* SelectSoftKeysMessage */ #define SELECT_SOFT_KEYS_MESSAGE 0x0110 struct select_soft_keys_message { - uint32_t line_instance; - uint32_t call_id; - uint32_t soft_key_set; /* See enum skinny_key_set */ - uint32_t valid_key_mask; + uint32_t line_instance; + uint32_t call_id; + uint32_t soft_key_set; /* See enum skinny_key_set */ + uint32_t valid_key_mask; }; /* CallStateMessage */ #define CALL_STATE_MESSAGE 0x0111 struct call_state_message { - uint32_t call_state; /* See enum skinny_call_state */ - uint32_t line_instance; - uint32_t call_id; + uint32_t call_state; /* See enum skinny_call_state */ + uint32_t line_instance; + uint32_t call_id; }; /* DisplayPromptStatusMessage */ #define DISPLAY_PROMPT_STATUS_MESSAGE 0x0112 struct display_prompt_status_message { - uint32_t timeout; - char display[32]; - uint32_t line_instance; - uint32_t call_id; + uint32_t timeout; + char display[32]; + uint32_t line_instance; + uint32_t call_id; }; /* ClearPromptStatusMessage */ #define CLEAR_PROMPT_STATUS_MESSAGE 0x0113 struct clear_prompt_status_message { - uint32_t line_instance; - uint32_t call_id; + uint32_t line_instance; + uint32_t call_id; }; /* ActivateCallPlaneMessage */ #define ACTIVATE_CALL_PLANE_MESSAGE 0x0116 struct activate_call_plane_message { - uint32_t line_instance; + uint32_t line_instance; }; /* UnregisterAckMessage */ #define UNREGISTER_ACK_MESSAGE 0x0118 struct unregister_ack_message { - uint32_t unregister_status; + uint32_t unregister_status; }; /* DialedNumberMessage */ #define DIALED_NUMBER_MESSAGE 0x011D struct dialed_number_message { - char called_party[24]; - uint32_t line_instance; - uint32_t call_id; + char called_party[24]; + uint32_t line_instance; + uint32_t call_id; }; /* FeatureStatMessage */ #define FEATURE_STAT_RES_MESSAGE 0x011F struct feature_stat_res_message { - uint32_t index; - uint32_t id; - char text_label[40]; - uint32_t status; + uint32_t index; + uint32_t id; + char text_label[40]; + uint32_t status; }; /* DisplayPriNotifyMessage */ #define DISPLAY_PRI_NOTIFY_MESSAGE 0x0120 struct display_pri_notify_message { - uint32_t message_timeout; - uint32_t priority; - char notify[32]; + uint32_t message_timeout; + uint32_t priority; + char notify[32]; }; /* ServiceUrlStatMessage */ #define SERVICE_URL_STAT_RES_MESSAGE 0x012F struct service_url_stat_res_message { - uint32_t index; - char url[256]; - char display_name[40]; + uint32_t index; + char url[256]; + char display_name[40]; }; /*****************************************************************************/ @@ -498,56 +498,56 @@ struct service_url_stat_res_message { #define SKINNY_MESSAGE_MAXSIZE 1000 union skinny_data { - struct register_message reg; - struct port_message port; - struct keypad_button_message keypad_button; - struct stimulus_message stimulus; - struct off_hook_message off_hook; - struct on_hook_message on_hook; - struct speed_dial_stat_req_message speed_dial_req; - struct line_stat_req_message line_req; - struct capabilities_res_message cap_res; - struct alarm_message alarm; - struct open_receive_channel_ack_message open_receive_channel_ack; - struct soft_key_event_message soft_key_event; - struct service_url_stat_req_message service_url_req; - struct feature_stat_req_message feature_req; - struct headset_status_message headset_status; - struct register_available_lines_message reg_lines; - struct register_ack_message reg_ack; - struct start_tone_message start_tone; - struct stop_tone_message stop_tone; - struct set_ringer_message ringer; - struct set_lamp_message lamp; - struct set_speaker_mode_message speaker_mode; - struct start_media_transmission_message start_media; - struct stop_media_transmission_message stop_media; - struct call_info_message call_info; - struct speed_dial_stat_res_message speed_dial_res; - struct line_stat_res_message line_res; - struct config_stat_res_message config_res; - struct define_time_date_message define_time_date; - struct button_template_message button_template; - struct register_rej_message reg_rej; - struct reset_message reset; - struct open_receive_channel_message open_receive_channel; - struct close_receive_channel_message close_receive_channel; - struct soft_key_template_res_message soft_key_template; - struct soft_key_set_res_message soft_key_set; - struct select_soft_keys_message select_soft_keys; - struct call_state_message call_state; - struct display_prompt_status_message display_prompt_status; - struct clear_prompt_status_message clear_prompt_status; - struct activate_call_plane_message activate_call_plane; - struct unregister_ack_message unregister_ack; - struct dialed_number_message dialed_number; - struct feature_stat_res_message feature_res; - struct display_pri_notify_message display_pri_notify; - struct service_url_stat_res_message service_url_res; - - uint16_t as_uint16; - char as_char; - void *raw; + struct register_message reg; + struct port_message port; + struct keypad_button_message keypad_button; + struct stimulus_message stimulus; + struct off_hook_message off_hook; + struct on_hook_message on_hook; + struct speed_dial_stat_req_message speed_dial_req; + struct line_stat_req_message line_req; + struct capabilities_res_message cap_res; + struct alarm_message alarm; + struct open_receive_channel_ack_message open_receive_channel_ack; + struct soft_key_event_message soft_key_event; + struct service_url_stat_req_message service_url_req; + struct feature_stat_req_message feature_req; + struct headset_status_message headset_status; + struct register_available_lines_message reg_lines; + struct register_ack_message reg_ack; + struct start_tone_message start_tone; + struct stop_tone_message stop_tone; + struct set_ringer_message ringer; + struct set_lamp_message lamp; + struct set_speaker_mode_message speaker_mode; + struct start_media_transmission_message start_media; + struct stop_media_transmission_message stop_media; + struct call_info_message call_info; + struct speed_dial_stat_res_message speed_dial_res; + struct line_stat_res_message line_res; + struct config_stat_res_message config_res; + struct define_time_date_message define_time_date; + struct button_template_message button_template; + struct register_rej_message reg_rej; + struct reset_message reset; + struct open_receive_channel_message open_receive_channel; + struct close_receive_channel_message close_receive_channel; + struct soft_key_template_res_message soft_key_template; + struct soft_key_set_res_message soft_key_set; + struct select_soft_keys_message select_soft_keys; + struct call_state_message call_state; + struct display_prompt_status_message display_prompt_status; + struct clear_prompt_status_message clear_prompt_status; + struct activate_call_plane_message activate_call_plane; + struct unregister_ack_message unregister_ack; + struct dialed_number_message dialed_number; + struct feature_stat_res_message feature_res; + struct display_pri_notify_message display_pri_notify; + struct service_url_stat_res_message service_url_res; + + uint16_t as_uint16; + char as_char; + void *raw; }; /* @@ -555,10 +555,10 @@ union skinny_data { * body is type+data */ struct skinny_message { - uint32_t length; - uint32_t reserved; - uint32_t type; - union skinny_data data; + uint32_t length; + uint32_t reserved; + uint32_t type; + union skinny_data data; }; typedef struct skinny_message skinny_message_t; @@ -566,40 +566,40 @@ typedef struct skinny_message skinny_message_t; /* SKINNY TYPES */ /*****************************************************************************/ enum skinny_codecs { - SKINNY_CODEC_ALAW_64K = 2, - SKINNY_CODEC_ALAW_56K = 3, - SKINNY_CODEC_ULAW_64K = 4, - SKINNY_CODEC_ULAW_56K = 5, - SKINNY_CODEC_G722_64K = 6, - SKINNY_CODEC_G722_56K = 7, - SKINNY_CODEC_G722_48K = 8, - SKINNY_CODEC_G723_1 = 9, - SKINNY_CODEC_G728 = 10, - SKINNY_CODEC_G729 = 11, - SKINNY_CODEC_G729A = 12, - SKINNY_CODEC_IS11172 = 13, - SKINNY_CODEC_IS13818 = 14, - SKINNY_CODEC_G729B = 15, - SKINNY_CODEC_G729AB = 16, - SKINNY_CODEC_GSM_FULL = 18, - SKINNY_CODEC_GSM_HALF = 19, - SKINNY_CODEC_GSM_EFULL = 20, - SKINNY_CODEC_WIDEBAND_256K = 25, - SKINNY_CODEC_DATA_64K = 32, - SKINNY_CODEC_DATA_56K = 33, - SKINNY_CODEC_GSM = 80, - SKINNY_CODEC_ACTIVEVOICE = 81, - SKINNY_CODEC_G726_32K = 82, - SKINNY_CODEC_G726_24K = 83, - SKINNY_CODEC_G726_16K = 84, - SKINNY_CODEC_G729B_BIS = 85, - SKINNY_CODEC_G729B_LOW = 86, - SKINNY_CODEC_H261 = 100, - SKINNY_CODEC_H263 = 101, - SKINNY_CODEC_VIDEO = 102, - SKINNY_CODEC_T120 = 105, - SKINNY_CODEC_H224 = 106, - SKINNY_CODEC_RFC2833_DYNPAYLOAD = 257 + SKINNY_CODEC_ALAW_64K = 2, + SKINNY_CODEC_ALAW_56K = 3, + SKINNY_CODEC_ULAW_64K = 4, + SKINNY_CODEC_ULAW_56K = 5, + SKINNY_CODEC_G722_64K = 6, + SKINNY_CODEC_G722_56K = 7, + SKINNY_CODEC_G722_48K = 8, + SKINNY_CODEC_G723_1 = 9, + SKINNY_CODEC_G728 = 10, + SKINNY_CODEC_G729 = 11, + SKINNY_CODEC_G729A = 12, + SKINNY_CODEC_IS11172 = 13, + SKINNY_CODEC_IS13818 = 14, + SKINNY_CODEC_G729B = 15, + SKINNY_CODEC_G729AB = 16, + SKINNY_CODEC_GSM_FULL = 18, + SKINNY_CODEC_GSM_HALF = 19, + SKINNY_CODEC_GSM_EFULL = 20, + SKINNY_CODEC_WIDEBAND_256K = 25, + SKINNY_CODEC_DATA_64K = 32, + SKINNY_CODEC_DATA_56K = 33, + SKINNY_CODEC_GSM = 80, + SKINNY_CODEC_ACTIVEVOICE = 81, + SKINNY_CODEC_G726_32K = 82, + SKINNY_CODEC_G726_24K = 83, + SKINNY_CODEC_G726_16K = 84, + SKINNY_CODEC_G729B_BIS = 85, + SKINNY_CODEC_G729B_LOW = 86, + SKINNY_CODEC_H261 = 100, + SKINNY_CODEC_H263 = 101, + SKINNY_CODEC_VIDEO = 102, + SKINNY_CODEC_T120 = 105, + SKINNY_CODEC_H224 = 106, + SKINNY_CODEC_RFC2833_DYNPAYLOAD = 257 }; typedef switch_status_t (*skinny_command_t) (char **argv, int argc, switch_stream_handle_t *stream); @@ -608,10 +608,10 @@ typedef switch_status_t (*skinny_command_t) (char **argv, int argc, switch_strea /* SKINNY FUNCTIONS */ /*****************************************************************************/ #define skinny_check_data_length(message, len) \ - if (message->length < len+4) {\ - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Received Too Short Skinny Message (Expected %" SWITCH_SIZE_T_FMT ", got %d).\n", len+4, message->length);\ - return SWITCH_STATUS_FALSE;\ - } + if (message->length < len+4) {\ + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Received Too Short Skinny Message (Expected %" SWITCH_SIZE_T_FMT ", got %d).\n", len+4, message->length);\ + return SWITCH_STATUS_FALSE;\ + } #define skinny_check_data_length_soft(message, len) \ (message->length >= len+4) @@ -643,102 +643,102 @@ switch_status_t skinny_handle_request(listener_t *listener, skinny_message_t *re /* SKINNY MESSAGE HELPER */ /*****************************************************************************/ switch_status_t start_tone(listener_t *listener, - uint32_t tone, - uint32_t reserved, - uint32_t line_instance, - uint32_t call_id); + uint32_t tone, + uint32_t reserved, + uint32_t line_instance, + uint32_t call_id); switch_status_t stop_tone(listener_t *listener, - uint32_t line_instance, - uint32_t call_id); + uint32_t line_instance, + uint32_t call_id); switch_status_t set_ringer(listener_t *listener, - uint32_t ring_type, - uint32_t ring_mode, - uint32_t line_instance, - uint32_t call_id); + uint32_t ring_type, + uint32_t ring_mode, + uint32_t line_instance, + uint32_t call_id); switch_status_t set_lamp(listener_t *listener, - uint32_t stimulus, - uint32_t stimulus_instance, - uint32_t mode); + uint32_t stimulus, + uint32_t stimulus_instance, + uint32_t mode); switch_status_t set_speaker_mode(listener_t *listener, - uint32_t mode); + uint32_t mode); switch_status_t start_media_transmission(listener_t *listener, - uint32_t conference_id, - uint32_t pass_thru_party_id, - uint32_t remote_ip, - uint32_t remote_port, - uint32_t ms_per_packet, - uint32_t payload_capacity, - uint32_t precedence, - uint32_t silence_suppression, - uint16_t max_frames_per_packet, - uint32_t g723_bitrate); + uint32_t conference_id, + uint32_t pass_thru_party_id, + uint32_t remote_ip, + uint32_t remote_port, + uint32_t ms_per_packet, + uint32_t payload_capacity, + uint32_t precedence, + uint32_t silence_suppression, + uint16_t max_frames_per_packet, + uint32_t g723_bitrate); switch_status_t stop_media_transmission(listener_t *listener, - uint32_t conference_id, - uint32_t pass_thru_party_id, - uint32_t conference_id2); + uint32_t conference_id, + uint32_t pass_thru_party_id, + uint32_t conference_id2); switch_status_t send_call_info(listener_t *listener, - char calling_party_name[40], - char calling_party[24], - char called_party_name[40], - char called_party[24], - uint32_t line_instance, - uint32_t call_id, - uint32_t call_type, - char original_called_party_name[40], - char original_called_party[24], - char last_redirecting_party_name[40], - char last_redirecting_party[24], - uint32_t original_called_party_redirect_reason, - uint32_t last_redirecting_reason, - char calling_party_voice_mailbox[24], - char called_party_voice_mailbox[24], - char original_called_party_voice_mailbox[24], - char last_redirecting_voice_mailbox[24], - uint32_t call_instance, - uint32_t call_security_status, - uint32_t party_pi_restriction_bits); + char calling_party_name[40], + char calling_party[24], + char called_party_name[40], + char called_party[24], + uint32_t line_instance, + uint32_t call_id, + uint32_t call_type, + char original_called_party_name[40], + char original_called_party[24], + char last_redirecting_party_name[40], + char last_redirecting_party[24], + uint32_t original_called_party_redirect_reason, + uint32_t last_redirecting_reason, + char calling_party_voice_mailbox[24], + char called_party_voice_mailbox[24], + char original_called_party_voice_mailbox[24], + char last_redirecting_voice_mailbox[24], + uint32_t call_instance, + uint32_t call_security_status, + uint32_t party_pi_restriction_bits); switch_status_t open_receive_channel(listener_t *listener, - uint32_t conference_id, - uint32_t pass_thru_party_id, - uint32_t packets, - uint32_t payload_capacity, - uint32_t echo_cancel_type, - uint32_t g723_bitrate, - uint32_t conference_id2, - uint32_t reserved[10]); + uint32_t conference_id, + uint32_t pass_thru_party_id, + uint32_t packets, + uint32_t payload_capacity, + uint32_t echo_cancel_type, + uint32_t g723_bitrate, + uint32_t conference_id2, + uint32_t reserved[10]); switch_status_t close_receive_channel(listener_t *listener, - uint32_t conference_id, - uint32_t pass_thru_party_id, - uint32_t conference_id2); + uint32_t conference_id, + uint32_t pass_thru_party_id, + uint32_t conference_id2); switch_status_t send_select_soft_keys(listener_t *listener, - uint32_t line_instance, - uint32_t call_id, - uint32_t soft_key_set, - uint32_t valid_key_mask); + uint32_t line_instance, + uint32_t call_id, + uint32_t soft_key_set, + uint32_t valid_key_mask); switch_status_t send_call_state(listener_t *listener, - uint32_t call_state, - uint32_t line_instance, - uint32_t call_id); + uint32_t call_state, + uint32_t line_instance, + uint32_t call_id); switch_status_t display_prompt_status(listener_t *listener, - uint32_t timeout, - char display[32], - uint32_t line_instance, - uint32_t call_id); + uint32_t timeout, + char display[32], + uint32_t line_instance, + uint32_t call_id); switch_status_t clear_prompt_status(listener_t *listener, - uint32_t line_instance, - uint32_t call_id); + uint32_t line_instance, + uint32_t call_id); switch_status_t activate_call_plane(listener_t *listener, - uint32_t line_instance); + uint32_t line_instance); switch_status_t send_dialed_number(listener_t *listener, - char called_party[24], - uint32_t line_instance, - uint32_t call_id); + char called_party[24], + uint32_t line_instance, + uint32_t call_id); switch_status_t send_display_pri_notify(listener_t *listener, - uint32_t message_timeout, - uint32_t priority, - char *notify); + uint32_t message_timeout, + uint32_t priority, + char *notify); switch_status_t send_reset(listener_t *listener, - uint32_t reset_type); + uint32_t reset_type); #endif /* _SKINNY_PROTOCOL_H */ diff --git a/src/mod/endpoints/mod_skinny/skinny_tables.c b/src/mod/endpoints/mod_skinny/skinny_tables.c index b503e78d33..7ad5f9be50 100644 --- a/src/mod/endpoints/mod_skinny/skinny_tables.c +++ b/src/mod/endpoints/mod_skinny/skinny_tables.c @@ -35,157 +35,157 @@ /* Translation tables */ struct skinny_table SKINNY_MESSAGE_TYPES[] = { - {"KeepAliveMessage", KEEP_ALIVE_MESSAGE}, - {"RegisterMessage", REGISTER_MESSAGE}, - {"PortMessage", PORT_MESSAGE}, - {"KeypadButtonMessage", KEYPAD_BUTTON_MESSAGE}, - {"StimulusMessage", STIMULUS_MESSAGE}, - {"OffHookMessage", OFF_HOOK_MESSAGE}, - {"OnHookMessage", ON_HOOK_MESSAGE}, - {"SpeedDialStatReqMessage", SPEED_DIAL_STAT_REQ_MESSAGE}, - {"LineStatReqMessage", LINE_STAT_REQ_MESSAGE}, - {"ConfigStatReqMessage", CONFIG_STAT_REQ_MESSAGE}, - {"TimeDateReqMessage", TIME_DATE_REQ_MESSAGE}, - {"ButtonTemplateReqMessage", BUTTON_TEMPLATE_REQ_MESSAGE}, - {"CapabilitiesReqMessage", CAPABILITIES_RES_MESSAGE}, - {"AlarmMessage", ALARM_MESSAGE}, - {"OpenReceiveChannelAckMessage", OPEN_RECEIVE_CHANNEL_ACK_MESSAGE}, - {"SoftKeySetReqMessage", SOFT_KEY_SET_REQ_MESSAGE}, - {"SoftKeyEventMessage", SOFT_KEY_EVENT_MESSAGE}, - {"UnregisterMessage", UNREGISTER_MESSAGE}, - {"SoftKeyTemplateReqMessage", SOFT_KEY_TEMPLATE_REQ_MESSAGE}, - {"ServiceUrlStatReqMessage", SERVICE_URL_STAT_REQ_MESSAGE}, - {"FeatureStatReqMessage", FEATURE_STAT_REQ_MESSAGE}, - {"HeadsetStatusMessage", HEADSET_STATUS_MESSAGE}, - {"RegisterAvailableLinesMessage", REGISTER_AVAILABLE_LINES_MESSAGE}, - {"RegisterAckMessage", REGISTER_ACK_MESSAGE}, - {"StartToneMessage", START_TONE_MESSAGE}, - {"StopToneMessage", STOP_TONE_MESSAGE}, - {"SetRingerMessage", SET_RINGER_MESSAGE}, - {"SetLampMessage", SET_LAMP_MESSAGE}, - {"SetSpeakerModeMessage", SET_SPEAKER_MODE_MESSAGE}, - {"StartMediaTransmissionMessage", START_MEDIA_TRANSMISSION_MESSAGE}, - {"StopMediaTransmissionMessage", STOP_MEDIA_TRANSMISSION_MESSAGE}, - {"CallInfoMessage", CALL_INFO_MESSAGE}, - {"SpeedDialStatResMessage", SPEED_DIAL_STAT_RES_MESSAGE}, - {"LineStatResMessage", LINE_STAT_RES_MESSAGE}, - {"ConfigStatResMessage", CONFIG_STAT_RES_MESSAGE}, - {"DefineTimeDateMessage", DEFINE_TIME_DATE_MESSAGE}, - {"ButtonTemplateResMessage", BUTTON_TEMPLATE_RES_MESSAGE}, - {"CapabilitiesReqMessage", CAPABILITIES_REQ_MESSAGE}, - {"RegisterRejMessage", REGISTER_REJ_MESSAGE}, - {"ResetMessage", RESET_MESSAGE}, - {"KeepAliveAckMessage", KEEP_ALIVE_ACK_MESSAGE}, - {"OpenReceiveChannelMessage", OPEN_RECEIVE_CHANNEL_MESSAGE}, - {"CloseReceiveChannelMessage", CLOSE_RECEIVE_CHANNEL_MESSAGE}, - {"SoftKeyTemplateResMessage", SOFT_KEY_TEMPLATE_RES_MESSAGE}, - {"SoftKeySetResMessage", SOFT_KEY_SET_RES_MESSAGE}, - {"SelectSoftKeysMessage", SELECT_SOFT_KEYS_MESSAGE}, - {"CallStateMessage", CALL_STATE_MESSAGE}, - {"DisplayPromptStatusMessage", DISPLAY_PROMPT_STATUS_MESSAGE}, - {"ClearPromptStatusMessage", CLEAR_PROMPT_STATUS_MESSAGE}, - {"ActivateCallPlaneMessage", ACTIVATE_CALL_PLANE_MESSAGE}, - {"UnregisterAckMessage", UNREGISTER_ACK_MESSAGE}, - {"DialedNumberMessage", DIALED_NUMBER_MESSAGE}, - {"FeatureResMessage", FEATURE_STAT_RES_MESSAGE}, - {"DisplayPriNotifyMessage", DISPLAY_PRI_NOTIFY_MESSAGE}, - {"ServiceUrlStatMessage", SERVICE_URL_STAT_RES_MESSAGE}, - {NULL, 0} + {"KeepAliveMessage", KEEP_ALIVE_MESSAGE}, + {"RegisterMessage", REGISTER_MESSAGE}, + {"PortMessage", PORT_MESSAGE}, + {"KeypadButtonMessage", KEYPAD_BUTTON_MESSAGE}, + {"StimulusMessage", STIMULUS_MESSAGE}, + {"OffHookMessage", OFF_HOOK_MESSAGE}, + {"OnHookMessage", ON_HOOK_MESSAGE}, + {"SpeedDialStatReqMessage", SPEED_DIAL_STAT_REQ_MESSAGE}, + {"LineStatReqMessage", LINE_STAT_REQ_MESSAGE}, + {"ConfigStatReqMessage", CONFIG_STAT_REQ_MESSAGE}, + {"TimeDateReqMessage", TIME_DATE_REQ_MESSAGE}, + {"ButtonTemplateReqMessage", BUTTON_TEMPLATE_REQ_MESSAGE}, + {"CapabilitiesReqMessage", CAPABILITIES_RES_MESSAGE}, + {"AlarmMessage", ALARM_MESSAGE}, + {"OpenReceiveChannelAckMessage", OPEN_RECEIVE_CHANNEL_ACK_MESSAGE}, + {"SoftKeySetReqMessage", SOFT_KEY_SET_REQ_MESSAGE}, + {"SoftKeyEventMessage", SOFT_KEY_EVENT_MESSAGE}, + {"UnregisterMessage", UNREGISTER_MESSAGE}, + {"SoftKeyTemplateReqMessage", SOFT_KEY_TEMPLATE_REQ_MESSAGE}, + {"ServiceUrlStatReqMessage", SERVICE_URL_STAT_REQ_MESSAGE}, + {"FeatureStatReqMessage", FEATURE_STAT_REQ_MESSAGE}, + {"HeadsetStatusMessage", HEADSET_STATUS_MESSAGE}, + {"RegisterAvailableLinesMessage", REGISTER_AVAILABLE_LINES_MESSAGE}, + {"RegisterAckMessage", REGISTER_ACK_MESSAGE}, + {"StartToneMessage", START_TONE_MESSAGE}, + {"StopToneMessage", STOP_TONE_MESSAGE}, + {"SetRingerMessage", SET_RINGER_MESSAGE}, + {"SetLampMessage", SET_LAMP_MESSAGE}, + {"SetSpeakerModeMessage", SET_SPEAKER_MODE_MESSAGE}, + {"StartMediaTransmissionMessage", START_MEDIA_TRANSMISSION_MESSAGE}, + {"StopMediaTransmissionMessage", STOP_MEDIA_TRANSMISSION_MESSAGE}, + {"CallInfoMessage", CALL_INFO_MESSAGE}, + {"SpeedDialStatResMessage", SPEED_DIAL_STAT_RES_MESSAGE}, + {"LineStatResMessage", LINE_STAT_RES_MESSAGE}, + {"ConfigStatResMessage", CONFIG_STAT_RES_MESSAGE}, + {"DefineTimeDateMessage", DEFINE_TIME_DATE_MESSAGE}, + {"ButtonTemplateResMessage", BUTTON_TEMPLATE_RES_MESSAGE}, + {"CapabilitiesReqMessage", CAPABILITIES_REQ_MESSAGE}, + {"RegisterRejMessage", REGISTER_REJ_MESSAGE}, + {"ResetMessage", RESET_MESSAGE}, + {"KeepAliveAckMessage", KEEP_ALIVE_ACK_MESSAGE}, + {"OpenReceiveChannelMessage", OPEN_RECEIVE_CHANNEL_MESSAGE}, + {"CloseReceiveChannelMessage", CLOSE_RECEIVE_CHANNEL_MESSAGE}, + {"SoftKeyTemplateResMessage", SOFT_KEY_TEMPLATE_RES_MESSAGE}, + {"SoftKeySetResMessage", SOFT_KEY_SET_RES_MESSAGE}, + {"SelectSoftKeysMessage", SELECT_SOFT_KEYS_MESSAGE}, + {"CallStateMessage", CALL_STATE_MESSAGE}, + {"DisplayPromptStatusMessage", DISPLAY_PROMPT_STATUS_MESSAGE}, + {"ClearPromptStatusMessage", CLEAR_PROMPT_STATUS_MESSAGE}, + {"ActivateCallPlaneMessage", ACTIVATE_CALL_PLANE_MESSAGE}, + {"UnregisterAckMessage", UNREGISTER_ACK_MESSAGE}, + {"DialedNumberMessage", DIALED_NUMBER_MESSAGE}, + {"FeatureResMessage", FEATURE_STAT_RES_MESSAGE}, + {"DisplayPriNotifyMessage", DISPLAY_PRI_NOTIFY_MESSAGE}, + {"ServiceUrlStatMessage", SERVICE_URL_STAT_RES_MESSAGE}, + {NULL, 0} }; SKINNY_DECLARE_ID2STR(skinny_message_type2str, SKINNY_MESSAGE_TYPES, "UnknownMessage") SKINNY_DECLARE_STR2ID(skinny_str2message_type, SKINNY_MESSAGE_TYPES, -1) struct skinny_table SKINNY_RING_TYPES[] = { - {"RingOff", SKINNY_RING_OFF}, - {"RingInside", SKINNY_RING_INSIDE}, - {"RingOutside", SKINNY_RING_OUTSIDE}, - {"RingFeature", SKINNY_RING_FEATURE}, - {NULL, 0} + {"RingOff", SKINNY_RING_OFF}, + {"RingInside", SKINNY_RING_INSIDE}, + {"RingOutside", SKINNY_RING_OUTSIDE}, + {"RingFeature", SKINNY_RING_FEATURE}, + {NULL, 0} }; SKINNY_DECLARE_ID2STR(skinny_ring_type2str, SKINNY_RING_TYPES, "RingTypeUnknown") SKINNY_DECLARE_STR2ID(skinny_str2ring_type, SKINNY_RING_TYPES, -1) struct skinny_table SKINNY_RING_MODES[] = { - {"RingForever", SKINNY_RING_FOREVER}, - {"RingOnce", SKINNY_RING_ONCE}, - {NULL, 0} + {"RingForever", SKINNY_RING_FOREVER}, + {"RingOnce", SKINNY_RING_ONCE}, + {NULL, 0} }; SKINNY_DECLARE_ID2STR(skinny_ring_mode2str, SKINNY_RING_MODES, "RingModeUnknown") SKINNY_DECLARE_STR2ID(skinny_str2ring_mode, SKINNY_RING_MODES, -1) struct skinny_table SKINNY_BUTTONS[] = { - {"Unknown", SKINNY_BUTTON_UNKNOWN}, - {"LastNumberRedial", SKINNY_BUTTON_LAST_NUMBER_REDIAL}, - {"SpeedDial", SKINNY_BUTTON_SPEED_DIAL}, - {"Line", SKINNY_BUTTON_LINE}, - {"Voicemail", SKINNY_BUTTON_VOICEMAIL}, - {"Privacy", SKINNY_BUTTON_PRIVACY}, - {"ServiceUrl", SKINNY_BUTTON_SERVICE_URL}, - {"Undefined", SKINNY_BUTTON_UNDEFINED}, - {NULL, 0} + {"Unknown", SKINNY_BUTTON_UNKNOWN}, + {"LastNumberRedial", SKINNY_BUTTON_LAST_NUMBER_REDIAL}, + {"SpeedDial", SKINNY_BUTTON_SPEED_DIAL}, + {"Line", SKINNY_BUTTON_LINE}, + {"Voicemail", SKINNY_BUTTON_VOICEMAIL}, + {"Privacy", SKINNY_BUTTON_PRIVACY}, + {"ServiceUrl", SKINNY_BUTTON_SERVICE_URL}, + {"Undefined", SKINNY_BUTTON_UNDEFINED}, + {NULL, 0} }; SKINNY_DECLARE_ID2STR(skinny_button2str, SKINNY_BUTTONS, "Unknown") SKINNY_DECLARE_STR2ID(skinny_str2button, SKINNY_BUTTONS, -1) struct skinny_table SKINNY_LAMP_MODES[] = { - {"Off", SKINNY_LAMP_OFF}, - {"On", SKINNY_LAMP_ON}, - {"Wink", SKINNY_LAMP_WINK}, - {"Flash", SKINNY_LAMP_FLASH}, - {"Blink", SKINNY_LAMP_BLINK}, - {NULL, 0} + {"Off", SKINNY_LAMP_OFF}, + {"On", SKINNY_LAMP_ON}, + {"Wink", SKINNY_LAMP_WINK}, + {"Flash", SKINNY_LAMP_FLASH}, + {"Blink", SKINNY_LAMP_BLINK}, + {NULL, 0} }; SKINNY_DECLARE_ID2STR(skinny_lamp_mode2str, SKINNY_LAMP_MODES, "Unknown") SKINNY_DECLARE_STR2ID(skinny_str2lamp_mode, SKINNY_LAMP_MODES, -1) struct skinny_table SKINNY_SPEAKER_MODES[] = { - {"SpeakerOn", SKINNY_SPEAKER_ON}, - {"SpeakerOff", SKINNY_SPEAKER_OFF}, - {NULL, 0} + {"SpeakerOn", SKINNY_SPEAKER_ON}, + {"SpeakerOff", SKINNY_SPEAKER_OFF}, + {NULL, 0} }; SKINNY_DECLARE_ID2STR(skinny_speaker_mode2str, SKINNY_SPEAKER_MODES, "Unknown") SKINNY_DECLARE_STR2ID(skinny_str2speaker_mode, SKINNY_SPEAKER_MODES, -1) struct skinny_table SKINNY_KEY_SETS[] = { - {"KeySetOnHook", SKINNY_KEY_SET_ON_HOOK}, - {"KeySetConnected", SKINNY_KEY_SET_CONNECTED}, - {"KeySetOnHold", SKINNY_KEY_SET_ON_HOLD}, - {"KeySetRingIn", SKINNY_KEY_SET_RING_IN}, - {"KeySetOffHook", SKINNY_KEY_SET_OFF_HOOK}, - {"KeySetConnectedWithTransfer", SKINNY_KEY_SET_CONNECTED_WITH_TRANSFER}, - {"KeySetDigitsAfterDialingFirstDigit", SKINNY_KEY_SET_DIGITS_AFTER_DIALING_FIRST_DIGIT}, - {"KeySetConnectedWithConference", SKINNY_KEY_SET_CONNECTED_WITH_CONFERENCE}, - {"KeySetRingOut", SKINNY_KEY_SET_RING_OUT}, - {"KeySetOffHookWithFeatures", SKINNY_KEY_SET_OFF_HOOK_WITH_FEATURES}, - {NULL, 0} + {"KeySetOnHook", SKINNY_KEY_SET_ON_HOOK}, + {"KeySetConnected", SKINNY_KEY_SET_CONNECTED}, + {"KeySetOnHold", SKINNY_KEY_SET_ON_HOLD}, + {"KeySetRingIn", SKINNY_KEY_SET_RING_IN}, + {"KeySetOffHook", SKINNY_KEY_SET_OFF_HOOK}, + {"KeySetConnectedWithTransfer", SKINNY_KEY_SET_CONNECTED_WITH_TRANSFER}, + {"KeySetDigitsAfterDialingFirstDigit", SKINNY_KEY_SET_DIGITS_AFTER_DIALING_FIRST_DIGIT}, + {"KeySetConnectedWithConference", SKINNY_KEY_SET_CONNECTED_WITH_CONFERENCE}, + {"KeySetRingOut", SKINNY_KEY_SET_RING_OUT}, + {"KeySetOffHookWithFeatures", SKINNY_KEY_SET_OFF_HOOK_WITH_FEATURES}, + {NULL, 0} }; SKINNY_DECLARE_ID2STR(skinny_soft_key_set2str, SKINNY_KEY_SETS, "UNKNOWN_SOFT_KEY_SET") SKINNY_DECLARE_STR2ID(skinny_str2soft_key_set, SKINNY_KEY_SETS, -1) struct skinny_table SKINNY_CALL_STATES[] = { - {"OffHook", SKINNY_OFF_HOOK}, - {"OnHook", SKINNY_ON_HOOK}, - {"RingOut", SKINNY_RING_OUT}, - {"RingIn", SKINNY_RING_IN}, - {"Connected", SKINNY_CONNECTED}, - {"Busy", SKINNY_BUSY}, - {"LineInUse", SKINNY_LINE_IN_USE}, - {"Hold", SKINNY_HOLD}, - {"CallWaiting", SKINNY_CALL_WAITING}, - {"CallTransfer", SKINNY_CALL_TRANSFER}, - {"CallPark", SKINNY_CALL_PARK}, - {"Proceed", SKINNY_PROCEED}, - {"InUseRemotely", SKINNY_IN_USE_REMOTELY}, - {"InvalidNumber", SKINNY_INVALID_NUMBER}, - {NULL, 0} + {"OffHook", SKINNY_OFF_HOOK}, + {"OnHook", SKINNY_ON_HOOK}, + {"RingOut", SKINNY_RING_OUT}, + {"RingIn", SKINNY_RING_IN}, + {"Connected", SKINNY_CONNECTED}, + {"Busy", SKINNY_BUSY}, + {"LineInUse", SKINNY_LINE_IN_USE}, + {"Hold", SKINNY_HOLD}, + {"CallWaiting", SKINNY_CALL_WAITING}, + {"CallTransfer", SKINNY_CALL_TRANSFER}, + {"CallPark", SKINNY_CALL_PARK}, + {"Proceed", SKINNY_PROCEED}, + {"InUseRemotely", SKINNY_IN_USE_REMOTELY}, + {"InvalidNumber", SKINNY_INVALID_NUMBER}, + {NULL, 0} }; SKINNY_DECLARE_ID2STR(skinny_call_state2str, SKINNY_CALL_STATES, "CallStateUnknown") SKINNY_DECLARE_STR2ID(skinny_str2call_state, SKINNY_CALL_STATES, -1) struct skinny_table SKINNY_DEVICE_RESET_TYPES[] = { - {"DeviceReset", SKINNY_DEVICE_RESET}, - {"DeviceRestart", SKINNY_DEVICE_RESTART}, - {NULL, 0} + {"DeviceReset", SKINNY_DEVICE_RESET}, + {"DeviceRestart", SKINNY_DEVICE_RESTART}, + {NULL, 0} }; SKINNY_DECLARE_ID2STR(skinny_device_reset_type2str, SKINNY_DEVICE_RESET_TYPES, "DeviceResetTypeUnknown") SKINNY_DECLARE_STR2ID(skinny_str2device_reset_type, SKINNY_DEVICE_RESET_TYPES, -1) diff --git a/src/mod/endpoints/mod_skinny/skinny_tables.h b/src/mod/endpoints/mod_skinny/skinny_tables.h index 82d7816d1f..9e3ab3be4c 100644 --- a/src/mod/endpoints/mod_skinny/skinny_tables.h +++ b/src/mod/endpoints/mod_skinny/skinny_tables.h @@ -36,53 +36,53 @@ /* SKINNY TABLES */ /*****************************************************************************/ struct skinny_table { - const char *name; - uint32_t id; + const char *name; + uint32_t id; }; #define SKINNY_DECLARE_ID2STR(func, TABLE, DEFAULT_STR) \ const char *func(uint32_t id) \ { \ - const char *str = DEFAULT_STR; \ - \ - for (uint8_t x = 0; x < (sizeof(TABLE) / sizeof(struct skinny_table)) - 1; x++) {\ - if (TABLE[x].id == id) {\ - str = TABLE[x].name;\ - break;\ - }\ - }\ - \ - return str;\ + const char *str = DEFAULT_STR; \ + \ + for (uint8_t x = 0; x < (sizeof(TABLE) / sizeof(struct skinny_table)) - 1; x++) {\ + if (TABLE[x].id == id) {\ + str = TABLE[x].name;\ + break;\ + }\ + }\ + \ + return str;\ } #define SKINNY_DECLARE_STR2ID(func, TABLE, DEFAULT_ID) \ uint32_t func(const char *str)\ {\ - uint32_t id = DEFAULT_ID;\ - \ - if (*str > 47 && *str < 58) {\ - id = atoi(str);\ - } else {\ - for (uint8_t x = 0; x < (sizeof(TABLE) / sizeof(struct skinny_table)) - 1 && TABLE[x].name; x++) {\ - if (!strcasecmp(TABLE[x].name, str)) {\ - id = TABLE[x].id;\ - break;\ - }\ - }\ - }\ - return id;\ + uint32_t id = DEFAULT_ID;\ + \ + if (*str > 47 && *str < 58) {\ + id = atoi(str);\ + } else {\ + for (uint8_t x = 0; x < (sizeof(TABLE) / sizeof(struct skinny_table)) - 1 && TABLE[x].name; x++) {\ + if (!strcasecmp(TABLE[x].name, str)) {\ + id = TABLE[x].id;\ + break;\ + }\ + }\ + }\ + return id;\ } #define SKINNY_DECLARE_PUSH_MATCH(TABLE) \ - switch_console_callback_match_t *my_matches = NULL;\ - for (uint8_t x = 0; x < (sizeof(TABLE) / sizeof(struct skinny_table)) - 1; x++) {\ - switch_console_push_match(&my_matches, TABLE[x].name);\ - }\ - if (my_matches) {\ - *matches = my_matches;\ - status = SWITCH_STATUS_SUCCESS;\ - } - + switch_console_callback_match_t *my_matches = NULL;\ + for (uint8_t x = 0; x < (sizeof(TABLE) / sizeof(struct skinny_table)) - 1; x++) {\ + switch_console_push_match(&my_matches, TABLE[x].name);\ + }\ + if (my_matches) {\ + *matches = my_matches;\ + status = SWITCH_STATUS_SUCCESS;\ + } + struct skinny_table SKINNY_MESSAGE_TYPES[56]; const char *skinny_message_type2str(uint32_t id); @@ -90,20 +90,20 @@ uint32_t skinny_str2message_type(const char *str); #define SKINNY_PUSH_MESSAGE_TYPES SKINNY_DECLARE_PUSH_MATCH(SKINNY_MESSAGE_TYPES) enum skinny_tone { - SKINNY_TONE_SILENCE = 0x00, - SKINNY_TONE_DIALTONE = 0x21, - SKINNY_TONE_BUSYTONE = 0x23, - SKINNY_TONE_ALERT = 0x24, - SKINNY_TONE_REORDER = 0x25, - SKINNY_TONE_CALLWAITTONE = 0x2D, - SKINNY_TONE_NOTONE = 0x7F, + SKINNY_TONE_SILENCE = 0x00, + SKINNY_TONE_DIALTONE = 0x21, + SKINNY_TONE_BUSYTONE = 0x23, + SKINNY_TONE_ALERT = 0x24, + SKINNY_TONE_REORDER = 0x25, + SKINNY_TONE_CALLWAITTONE = 0x2D, + SKINNY_TONE_NOTONE = 0x7F, }; enum skinny_ring_type { - SKINNY_RING_OFF = 1, - SKINNY_RING_INSIDE = 2, - SKINNY_RING_OUTSIDE = 3, - SKINNY_RING_FEATURE = 4 + SKINNY_RING_OFF = 1, + SKINNY_RING_INSIDE = 2, + SKINNY_RING_OUTSIDE = 3, + SKINNY_RING_FEATURE = 4 }; struct skinny_table SKINNY_RING_TYPES[5]; const char *skinny_ring_type2str(uint32_t id); @@ -111,8 +111,8 @@ uint32_t skinny_str2ring_type(const char *str); #define SKINNY_PUSH_RING_TYPES SKINNY_DECLARE_PUSH_MATCH(SKINNY_RING_TYPES) enum skinny_ring_mode { - SKINNY_RING_FOREVER = 1, - SKINNY_RING_ONCE = 2, + SKINNY_RING_FOREVER = 1, + SKINNY_RING_ONCE = 2, }; struct skinny_table SKINNY_RING_MODES[3]; const char *skinny_ring_mode2str(uint32_t id); @@ -121,11 +121,11 @@ uint32_t skinny_str2ring_mode(const char *str); enum skinny_lamp_mode { - SKINNY_LAMP_OFF = 1, - SKINNY_LAMP_ON = 2, - SKINNY_LAMP_WINK = 3, - SKINNY_LAMP_FLASH = 4, - SKINNY_LAMP_BLINK = 5, + SKINNY_LAMP_OFF = 1, + SKINNY_LAMP_ON = 2, + SKINNY_LAMP_WINK = 3, + SKINNY_LAMP_FLASH = 4, + SKINNY_LAMP_BLINK = 5, }; struct skinny_table SKINNY_LAMP_MODES[6]; const char *skinny_lamp_mode2str(uint32_t id); @@ -133,8 +133,8 @@ uint32_t skinny_str2lamp_mode(const char *str); #define SKINNY_PUSH_LAMP_MODES SKINNY_DECLARE_PUSH_MATCH(SKINNY_LAMP_MODES) enum skinny_speaker_mode { - SKINNY_SPEAKER_ON = 1, - SKINNY_SPEAKER_OFF = 2, + SKINNY_SPEAKER_ON = 1, + SKINNY_SPEAKER_OFF = 2, }; struct skinny_table SKINNY_SPEAKER_MODES[3]; const char *skinny_speaker_mode2str(uint32_t id); @@ -142,20 +142,20 @@ uint32_t skinny_str2speaker_mode(const char *str); #define SKINNY_PUSH_SPEAKER_MODES SKINNY_DECLARE_PUSH_MATCH(SKINNY_SPEAKER_MODES) enum skinny_call_type { - SKINNY_INBOUND_CALL = 1, - SKINNY_OUTBOUND_CALL = 2, - SKINNY_FORWARD_CALL = 3, + SKINNY_INBOUND_CALL = 1, + SKINNY_OUTBOUND_CALL = 2, + SKINNY_FORWARD_CALL = 3, }; enum skinny_button_definition { - SKINNY_BUTTON_UNKNOWN = 0x00, - SKINNY_BUTTON_LAST_NUMBER_REDIAL = 0x01, - SKINNY_BUTTON_SPEED_DIAL = 0x02, - SKINNY_BUTTON_LINE = 0x09, - SKINNY_BUTTON_VOICEMAIL = 0x0F, - SKINNY_BUTTON_PRIVACY = 0x13, - SKINNY_BUTTON_SERVICE_URL = 0x14, - SKINNY_BUTTON_UNDEFINED = 0xFF, + SKINNY_BUTTON_UNKNOWN = 0x00, + SKINNY_BUTTON_LAST_NUMBER_REDIAL = 0x01, + SKINNY_BUTTON_SPEED_DIAL = 0x02, + SKINNY_BUTTON_LINE = 0x09, + SKINNY_BUTTON_VOICEMAIL = 0x0F, + SKINNY_BUTTON_PRIVACY = 0x13, + SKINNY_BUTTON_SERVICE_URL = 0x14, + SKINNY_BUTTON_UNDEFINED = 0xFF, }; struct skinny_table SKINNY_BUTTONS[9]; const char *skinny_button2str(uint32_t id); @@ -163,39 +163,39 @@ uint32_t skinny_str2button(const char *str); #define SKINNY_PUSH_STIMULI SKINNY_DECLARE_PUSH_MATCH(SKINNY_BUTTONS) enum skinny_soft_key_event { - SOFTKEY_REDIAL = 0x01, - SOFTKEY_NEWCALL = 0x02, - SOFTKEY_HOLD = 0x03, - SOFTKEY_TRANSFER = 0x04, - SOFTKEY_CFWDALL = 0x05, - SOFTKEY_CFWDBUSY = 0x06, - SOFTKEY_CFWDNOANSWER = 0x07, - SOFTKEY_BACKSPACE = 0x08, - SOFTKEY_ENDCALL = 0x09, - SOFTKEY_RESUME = 0x0A, - SOFTKEY_ANSWER = 0x0B, - SOFTKEY_INFO = 0x0C, - SOFTKEY_CONFRM = 0x0D, - SOFTKEY_PARK = 0x0E, - SOFTKEY_JOIN = 0x0F, - SOFTKEY_MEETMECONFRM = 0x10, - SOFTKEY_CALLPICKUP = 0x11, - SOFTKEY_GRPCALLPICKUP = 0x12, - SOFTKEY_DND = 0x13, - SOFTKEY_IDIVERT = 0x14, + SOFTKEY_REDIAL = 0x01, + SOFTKEY_NEWCALL = 0x02, + SOFTKEY_HOLD = 0x03, + SOFTKEY_TRANSFER = 0x04, + SOFTKEY_CFWDALL = 0x05, + SOFTKEY_CFWDBUSY = 0x06, + SOFTKEY_CFWDNOANSWER = 0x07, + SOFTKEY_BACKSPACE = 0x08, + SOFTKEY_ENDCALL = 0x09, + SOFTKEY_RESUME = 0x0A, + SOFTKEY_ANSWER = 0x0B, + SOFTKEY_INFO = 0x0C, + SOFTKEY_CONFRM = 0x0D, + SOFTKEY_PARK = 0x0E, + SOFTKEY_JOIN = 0x0F, + SOFTKEY_MEETMECONFRM = 0x10, + SOFTKEY_CALLPICKUP = 0x11, + SOFTKEY_GRPCALLPICKUP = 0x12, + SOFTKEY_DND = 0x13, + SOFTKEY_IDIVERT = 0x14, }; enum skinny_key_set { - SKINNY_KEY_SET_ON_HOOK = 0, - SKINNY_KEY_SET_CONNECTED = 1, - SKINNY_KEY_SET_ON_HOLD = 2, - SKINNY_KEY_SET_RING_IN = 3, - SKINNY_KEY_SET_OFF_HOOK = 4, - SKINNY_KEY_SET_CONNECTED_WITH_TRANSFER = 5, - SKINNY_KEY_SET_DIGITS_AFTER_DIALING_FIRST_DIGIT = 6, - SKINNY_KEY_SET_CONNECTED_WITH_CONFERENCE = 7, - SKINNY_KEY_SET_RING_OUT = 8, - SKINNY_KEY_SET_OFF_HOOK_WITH_FEATURES = 9, + SKINNY_KEY_SET_ON_HOOK = 0, + SKINNY_KEY_SET_CONNECTED = 1, + SKINNY_KEY_SET_ON_HOLD = 2, + SKINNY_KEY_SET_RING_IN = 3, + SKINNY_KEY_SET_OFF_HOOK = 4, + SKINNY_KEY_SET_CONNECTED_WITH_TRANSFER = 5, + SKINNY_KEY_SET_DIGITS_AFTER_DIALING_FIRST_DIGIT = 6, + SKINNY_KEY_SET_CONNECTED_WITH_CONFERENCE = 7, + SKINNY_KEY_SET_RING_OUT = 8, + SKINNY_KEY_SET_OFF_HOOK_WITH_FEATURES = 9, }; struct skinny_table SKINNY_KEY_SETS[11]; const char *skinny_soft_key_set2str(uint32_t id); @@ -204,20 +204,20 @@ uint32_t skinny_str2soft_key_set(const char *str); enum skinny_call_state { - SKINNY_OFF_HOOK = 1, - SKINNY_ON_HOOK = 2, - SKINNY_RING_OUT = 3, - SKINNY_RING_IN = 4, - SKINNY_CONNECTED = 5, - SKINNY_BUSY = 6, - SKINNY_LINE_IN_USE = 7, - SKINNY_HOLD = 8, - SKINNY_CALL_WAITING = 9, - SKINNY_CALL_TRANSFER = 10, - SKINNY_CALL_PARK = 11, - SKINNY_PROCEED = 12, - SKINNY_IN_USE_REMOTELY = 13, - SKINNY_INVALID_NUMBER = 14 + SKINNY_OFF_HOOK = 1, + SKINNY_ON_HOOK = 2, + SKINNY_RING_OUT = 3, + SKINNY_RING_IN = 4, + SKINNY_CONNECTED = 5, + SKINNY_BUSY = 6, + SKINNY_LINE_IN_USE = 7, + SKINNY_HOLD = 8, + SKINNY_CALL_WAITING = 9, + SKINNY_CALL_TRANSFER = 10, + SKINNY_CALL_PARK = 11, + SKINNY_PROCEED = 12, + SKINNY_IN_USE_REMOTELY = 13, + SKINNY_INVALID_NUMBER = 14 }; struct skinny_table SKINNY_CALL_STATES[15]; const char *skinny_call_state2str(uint32_t id);