]> git.ipfire.org Git - thirdparty/freeswitch.git/commitdiff
Skinny: allow configuration of softkeys via xml
authorMathieu Parent <math.parent@gmail.com>
Sat, 4 Sep 2010 07:29:01 +0000 (09:29 +0200)
committerMathieu Parent <math.parent@gmail.com>
Sat, 4 Sep 2010 07:35:43 +0000 (09:35 +0200)
- 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
src/mod/endpoints/mod_skinny/mod_skinny.c
src/mod/endpoints/mod_skinny/mod_skinny.h
src/mod/endpoints/mod_skinny/skinny_protocol.h
src/mod/endpoints/mod_skinny/skinny_server.c
src/mod/endpoints/mod_skinny/skinny_tables.c

index e48557b2344f9c4abbcd391ce2fffeec2045dae5..5feac1ffbf7a1372c0408b1f1e7a1f3b57cc0bc0 100644 (file)
     <param name="debug" value="4"/>
     <param name="auto-restart" value="true"/>
   </settings>
+  <soft-key-set-sets>
+    <soft-key-set-set name="default">
+      <soft-key-set name="KeySetOnHook" value="SoftkeyNewcall,SoftkeyRedial"/>
+      <soft-key-set name="KeySetOffHook" value=",SoftkeyNewcall,SoftkeyEndcall"/>
+      <soft-key-set name="KeySetDigitsAfterDialingFirstDigit" value="SoftkeyBackspace,,SoftkeyEndcall"/>
+      <soft-key-set name="KeySetConnected" value="SoftkeyEndcall,SoftkeyHold,SoftkeyNewcall,SoftkeyTransfer"/>
+      <soft-key-set name="KeySetRingIn" value="SoftkeyAnswer,SoftkeyEndcall,SoftkeyNewcall"/>
+      <soft-key-set name="KeySetOnHold" value="SoftkeyNewcall,SoftkeyResume,SoftkeyEndcall"/>
+      <soft-key-set name="KeySetOffHookWithFeatures" value=",SoftkeyRedial,SoftkeyEndcall"/>
+    </soft-key-set-set>
+  </soft-key-set-sets>
   <device-types>
     <device-type id="Cisco ATA 186">
         <param name="firmware-version" value="ATA030101SCCP04"/>
index 0f7b370a99b00da1b505b00e46ea24ce3b0d2ecd..165815078b21d32c3d29cf06d153f95ceb756b98 100644 (file)
@@ -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,
                                        "<profile> 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,
+                                                               "<soft-key-set-set> 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,
+                                               "<soft-key-set-sets> 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 <soft-key-set-set>. 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 */
        }
 
index accb7e6c6937d66c004de3e45c410e64e947f588..99b52b6fb88afa2ce3a8893bfdf1e39d0c47de66 100644 (file)
@@ -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;
index fe001c7b4d191e5bcc9a7031a3725b9ded8a4333..236c667509ef63a82ae1b83fb87d4853509b945f 100644 (file)
@@ -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;
 };
index 2f640a834587057d1d2a777a078a09e31a93470c..de4fdbd1cc22a22b868b64188ffe38c1dbd1398b 100644 (file)
@@ -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 <soft-key-set-set>. Profile ignored.\n", listener->profile->name);
+       }
 
        /* Init the states */
        send_select_soft_keys(listener, 0, 0, SKINNY_KEY_SET_ON_HOOK, 0xffff);
index 07be7c454c08f43a922d29246406b21fc21cf8cd..43b22905609c175f26caae8f11facc99be46f95a 100644 (file)
@@ -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},