From f5a6831ffcd01ce948edea25197b8d920fec1f07 Mon Sep 17 00:00:00 2001 From: Mathieu Parent Date: Sat, 4 Sep 2010 09:29:01 +0200 Subject: [PATCH] Skinny: allow configuration of softkeys via xml - enhance conf/skinny_profiles/internal.xml - Sanity checks + softKeySet id < 16 + less than 16 buttons per softKeySet + at least the default soft-key-set to load the profile + at least one profile to load mod_skinny - Lower some ERRORs to WARNINGs as they don't prevent module loading - Default skinny_str2soft_key_event to 0 --- conf/skinny_profiles/internal.xml | 11 ++ src/mod/endpoints/mod_skinny/mod_skinny.c | 128 ++++++++++++++---- src/mod/endpoints/mod_skinny/mod_skinny.h | 1 + .../endpoints/mod_skinny/skinny_protocol.h | 2 +- src/mod/endpoints/mod_skinny/skinny_server.c | 48 +------ src/mod/endpoints/mod_skinny/skinny_tables.c | 2 +- 6 files changed, 120 insertions(+), 72 deletions(-) diff --git a/conf/skinny_profiles/internal.xml b/conf/skinny_profiles/internal.xml index e48557b234..5feac1ffbf 100644 --- a/conf/skinny_profiles/internal.xml +++ b/conf/skinny_profiles/internal.xml @@ -13,6 +13,17 @@ + + + + + + + + + + + diff --git a/src/mod/endpoints/mod_skinny/mod_skinny.c b/src/mod/endpoints/mod_skinny/mod_skinny.c index 0f7b370a99..165815078b 100644 --- a/src/mod/endpoints/mod_skinny/mod_skinny.c +++ b/src/mod/endpoints/mod_skinny/mod_skinny.c @@ -1714,8 +1714,7 @@ static switch_status_t load_skinny_config(void) if ((xprofiles = switch_xml_child(xcfg, "profiles"))) { for (xprofile = switch_xml_child(xprofiles, "profile"); xprofile; xprofile = xprofile->next) { char *profile_name = (char *) switch_xml_attr_soft(xprofile, "name"); - switch_xml_t xsettings; - switch_xml_t xdevice_types; + switch_xml_t xsettings, xdevice_types, xsoft_key_set_sets; if (zstr(profile_name)) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, " is missing name attribute\n"); @@ -1771,6 +1770,96 @@ static switch_status_t load_skinny_config(void) profile->port = 2000; } + /* Soft Key Set Sets */ + switch_core_hash_init(&profile->soft_key_set_sets_hash, profile->pool); + if ((xsoft_key_set_sets = switch_xml_child(xprofile, "soft-key-set-sets"))) { + switch_xml_t xsoft_key_set_set; + for (xsoft_key_set_set = switch_xml_child(xsoft_key_set_sets, "soft-key-set-set"); xsoft_key_set_set; xsoft_key_set_set = xsoft_key_set_set->next) { + char *soft_key_set_set_name = (char *) switch_xml_attr_soft(xsoft_key_set_set, "name"); + if (soft_key_set_set_name) { + switch_xml_t xsoft_key_set; + skinny_message_t *message; + message = switch_core_alloc(profile->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; + for (xsoft_key_set = switch_xml_child(xsoft_key_set_set, "soft-key-set"); xsoft_key_set; xsoft_key_set = xsoft_key_set->next) { + uint32_t soft_key_set_id; + if ((soft_key_set_id = skinny_str2soft_key_set(switch_xml_attr_soft(xsoft_key_set, "name"))) != -1) { + char *val =switch_core_strdup(profile->pool, switch_xml_attr_soft(xsoft_key_set, "value")); + size_t string_len = strlen(val); + size_t string_pos, start = 0; + int field_no = 0; + if (soft_key_set_id > 15) { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, + "soft-key-set name '%s' is greater than 15 in soft-key-set-set '%s' in profile %s.\n", + switch_xml_attr_soft(xsoft_key_set, "name"), soft_key_set_set_name, profile->name); + continue; + } + for (string_pos = 0; string_pos <= string_len; string_pos++) { + if ((val[string_pos] == ',') || (string_pos == string_len)) { + val[string_pos] = '\0'; + if (field_no > 15) { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, + "soft-key-set name '%s' is limited to 16 buttons in soft-key-set-set '%s' in profile %s.\n", + switch_xml_attr_soft(xsoft_key_set, "name"), soft_key_set_set_name, profile->name); + break; + } + message->data.soft_key_set.soft_key_set[soft_key_set_id].soft_key_template_index[field_no++] = skinny_str2soft_key_event(&val[start]); + start = string_pos+1; + } + } + } else { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, + "Unknown soft-key-set name '%s' in soft-key-set-set '%s' in profile %s.\n", + switch_xml_attr_soft(xsoft_key_set, "name"), soft_key_set_set_name, profile->name); + } + } /* soft-key-set */ + switch_core_hash_insert(profile->soft_key_set_sets_hash, soft_key_set_set_name, message); + } else { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, + " is missing a name attribute in profile %s.\n", profile->name); + } + } /* soft-key-set-set */ + } else { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, + " is missing in profile %s.\n", profile->name); + } /* soft-key-set-sets */ + if (!switch_core_hash_find(profile->soft_key_set_sets_hash, "default")) { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, + "Profile %s doesn't have a default . Profile ignored.\n", profile->name); + switch_core_destroy_memory_pool(&profile_pool); + continue; + } + + + /* Device types */ + switch_core_hash_init(&profile->device_type_params_hash, profile->pool); + if ((xdevice_types = switch_xml_child(xprofile, "device-types"))) { + switch_xml_t xdevice_type; + for (xdevice_type = switch_xml_child(xdevice_types, "device-type"); xdevice_type; xdevice_type = xdevice_type->next) { + uint32_t id = skinny_str2device_type(switch_xml_attr_soft(xdevice_type, "id")); + if (id != 0) { + char *id_str = switch_mprintf("%d", id); + skinny_device_type_params_t *params = switch_core_alloc(profile->pool, sizeof(skinny_device_type_params_t)); + for (param = switch_xml_child(xdevice_type, "param"); param; param = param->next) { + char *var = (char *) switch_xml_attr_soft(param, "name"); + char *val = (char *) switch_xml_attr_soft(param, "value"); + + if (!strcasecmp(var, "firmware-version")) { + strncpy(params->firmware_version, val, 16); + } + } /* param */ + switch_core_hash_insert(profile->device_type_params_hash, id_str, params); + } else { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, + "Unknow device type %s in profile %s.\n", switch_xml_attr_soft(xdevice_type, "id"), profile->name); + } + } + } + /* Database */ switch_snprintf(dbname, sizeof(dbname), "skinny_%s", profile->name); profile->dbname = switch_core_strdup(profile->pool, dbname); @@ -1809,30 +1898,6 @@ static switch_status_t load_skinny_config(void) 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); - /* Device types */ - switch_core_hash_init(&profile->device_type_params_hash, profile->pool); - if ((xdevice_types = switch_xml_child(xprofile, "device-types"))) { - switch_xml_t xdevice_type; - for (xdevice_type = switch_xml_child(xdevice_types, "device-type"); xdevice_type; xdevice_type = xdevice_type->next) { - uint32_t id = skinny_str2device_type(switch_xml_attr_soft(xdevice_type, "id")); - if (id != 0) { - char *id_str = switch_mprintf("%d", id); - skinny_device_type_params_t *params = switch_core_alloc(profile->pool, sizeof(skinny_device_type_params_t)); - for (param = switch_xml_child(xdevice_type, "param"); param; param = param->next) { - char *var = (char *) switch_xml_attr_soft(param, "name"); - char *val = (char *) switch_xml_attr_soft(param, "value"); - - if (!strcasecmp(var, "firmware-version")) { - strncpy(params->firmware_version, val, 16); - } - } /* param */ - switch_core_hash_insert(profile->device_type_params_hash, id_str, params); - } else { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, - "Unknow device type %s in profile %s.\n", switch_xml_attr_soft(xdevice_type, "id"), profile->name); - } - } - } skinny_profile_respawn(profile, 0); /* Register profile */ @@ -2058,9 +2123,14 @@ SWITCH_MODULE_LOAD_FUNCTION(mod_skinny_load) load_skinny_config(); + /* at least one profile */ + if (!switch_hash_first(NULL, globals.profile_hash)) { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "No profile found!\n"); + return SWITCH_STATUS_TERM; + } /* bind to events */ if ((switch_event_bind_removable(modname, SWITCH_EVENT_HEARTBEAT, NULL, skinny_heartbeat_event_handler, NULL, &globals.heartbeat_node) != SWITCH_STATUS_SUCCESS)) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Couldn't bind our heartbeat handler!\n"); + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Couldn't bind our heartbeat handler!\n"); /* Not such severe to prevent loading */ } if ((switch_event_bind_removable(modname, SWITCH_EVENT_CUSTOM, SKINNY_EVENT_CALL_STATE, skinny_call_state_event_handler, NULL, &globals.call_state_node) != SWITCH_STATUS_SUCCESS)) { @@ -2068,11 +2138,11 @@ SWITCH_MODULE_LOAD_FUNCTION(mod_skinny_load) return SWITCH_STATUS_TERM; } if ((switch_event_bind_removable(modname, SWITCH_EVENT_MESSAGE_WAITING, NULL, skinny_message_waiting_event_handler, NULL, &globals.message_waiting_node) != SWITCH_STATUS_SUCCESS)) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Couldn't bind our message waiting handler!\n"); + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Couldn't bind our message waiting handler!\n"); /* Not such severe to prevent loading */ } if ((switch_event_bind_removable(modname, SWITCH_EVENT_TRAP, NULL, skinny_trap_event_handler, NULL, &globals.trap_node) != SWITCH_STATUS_SUCCESS)) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Couldn't bind our trap handler!\n"); + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Couldn't bind our trap handler!\n"); /* Not such severe to prevent loading */ } diff --git a/src/mod/endpoints/mod_skinny/mod_skinny.h b/src/mod/endpoints/mod_skinny/mod_skinny.h index accb7e6c69..99b52b6fb8 100644 --- a/src/mod/endpoints/mod_skinny/mod_skinny.h +++ b/src/mod/endpoints/mod_skinny/mod_skinny.h @@ -79,6 +79,7 @@ struct skinny_profile { char date_format[6]; int debug; int auto_restart; + switch_hash_t *soft_key_set_sets_hash; switch_hash_t *device_type_params_hash; /* db */ char *dbname; diff --git a/src/mod/endpoints/mod_skinny/skinny_protocol.h b/src/mod/endpoints/mod_skinny/skinny_protocol.h index fe001c7b4d..236c667509 100644 --- a/src/mod/endpoints/mod_skinny/skinny_protocol.h +++ b/src/mod/endpoints/mod_skinny/skinny_protocol.h @@ -151,7 +151,7 @@ struct PACKED open_receive_channel_ack_message { /* SoftKeyEventMessage */ #define SOFT_KEY_EVENT_MESSAGE 0x0026 struct PACKED soft_key_event_message { - uint32_t event; + uint32_t event; /* See enum skinny_soft_key_event */ uint32_t line_instance; uint32_t call_id; }; diff --git a/src/mod/endpoints/mod_skinny/skinny_server.c b/src/mod/endpoints/mod_skinny/skinny_server.c index 2f640a8345..de4fdbd1cc 100644 --- a/src/mod/endpoints/mod_skinny/skinny_server.c +++ b/src/mod/endpoints/mod_skinny/skinny_server.c @@ -1694,48 +1694,14 @@ end: switch_status_t skinny_handle_soft_key_set_request(listener_t *listener, skinny_message_t *request) { skinny_message_t *message; - skinny_profile_t *profile; - switch_assert(listener->profile); - switch_assert(listener->device_name); - - 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->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_NEWCALL; - message->data.soft_key_set.soft_key_set[SKINNY_KEY_SET_ON_HOOK].soft_key_template_index[1] = SOFTKEY_REDIAL; - - message->data.soft_key_set.soft_key_set[SKINNY_KEY_SET_OFF_HOOK].soft_key_template_index[1] = SOFTKEY_REDIAL; - message->data.soft_key_set.soft_key_set[SKINNY_KEY_SET_OFF_HOOK].soft_key_template_index[2] = SOFTKEY_ENDCALL; - - message->data.soft_key_set.soft_key_set[SKINNY_KEY_SET_DIGITS_AFTER_DIALING_FIRST_DIGIT].soft_key_template_index[0] = SOFTKEY_BACKSPACE; - message->data.soft_key_set.soft_key_set[SKINNY_KEY_SET_DIGITS_AFTER_DIALING_FIRST_DIGIT].soft_key_template_index[2] = SOFTKEY_ENDCALL; - - 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_CONNECTED].soft_key_template_index[1] = SOFTKEY_HOLD; - message->data.soft_key_set.soft_key_set[SKINNY_KEY_SET_CONNECTED].soft_key_template_index[2] = SOFTKEY_NEWCALL; - message->data.soft_key_set.soft_key_set[SKINNY_KEY_SET_CONNECTED].soft_key_template_index[3] = SOFTKEY_TRANSFER; - - message->data.soft_key_set.soft_key_set[SKINNY_KEY_SET_RING_IN].soft_key_template_index[0] = SOFTKEY_ANSWER; - message->data.soft_key_set.soft_key_set[SKINNY_KEY_SET_RING_IN].soft_key_template_index[1] = SOFTKEY_ENDCALL; - message->data.soft_key_set.soft_key_set[SKINNY_KEY_SET_RING_IN].soft_key_template_index[2] = SOFTKEY_NEWCALL; - - message->data.soft_key_set.soft_key_set[SKINNY_KEY_SET_ON_HOLD].soft_key_template_index[0] = SOFTKEY_NEWCALL; - message->data.soft_key_set.soft_key_set[SKINNY_KEY_SET_ON_HOLD].soft_key_template_index[1] = SOFTKEY_RESUME; - message->data.soft_key_set.soft_key_set[SKINNY_KEY_SET_ON_HOLD].soft_key_template_index[2] = SOFTKEY_ENDCALL; - - message->data.soft_key_set.soft_key_set[SKINNY_KEY_SET_OFF_HOOK_WITH_FEATURES].soft_key_template_index[1] = SOFTKEY_REDIAL; - message->data.soft_key_set.soft_key_set[SKINNY_KEY_SET_OFF_HOOK_WITH_FEATURES].soft_key_template_index[2] = SOFTKEY_ENDCALL; - - skinny_send_reply(listener, message); + message = switch_core_hash_find(listener->profile->soft_key_set_sets_hash, "default"); + if (message) { + skinny_send_reply(listener, message); + } else { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, + "Profile %s doesn't have a default . Profile ignored.\n", listener->profile->name); + } /* Init the states */ send_select_soft_keys(listener, 0, 0, SKINNY_KEY_SET_ON_HOOK, 0xffff); diff --git a/src/mod/endpoints/mod_skinny/skinny_tables.c b/src/mod/endpoints/mod_skinny/skinny_tables.c index 07be7c454c..43b2290560 100644 --- a/src/mod/endpoints/mod_skinny/skinny_tables.c +++ b/src/mod/endpoints/mod_skinny/skinny_tables.c @@ -176,7 +176,7 @@ struct skinny_table SKINNY_SOFT_KEY_EVENTS[] = { {NULL, 0} }; SKINNY_DECLARE_ID2STR(skinny_soft_key_event2str, SKINNY_SOFT_KEY_EVENTS, "SoftkeyUnknown") -SKINNY_DECLARE_STR2ID(skinny_str2soft_key_event, SKINNY_SOFT_KEY_EVENTS, -1) +SKINNY_DECLARE_STR2ID(skinny_str2soft_key_event, SKINNY_SOFT_KEY_EVENTS, 0) struct skinny_table SKINNY_LAMP_MODES[] = { {"Off", SKINNY_LAMP_OFF},