From 03f91afd34da3ace3f0a2c213fa1b2de4b108ed9 Mon Sep 17 00:00:00 2001 From: Mathieu Parent Date: Fri, 16 Apr 2010 17:30:49 +0200 Subject: [PATCH] Skinny: VersionMessage per device type --- src/mod/endpoints/mod_skinny/mod_skinny.c | 32 +++++++++++++++++-- src/mod/endpoints/mod_skinny/mod_skinny.h | 8 ++++- .../endpoints/mod_skinny/skinny_protocol.c | 15 +++++++++ src/mod/endpoints/mod_skinny/skinny_tables.c | 18 +++++++++++ src/mod/endpoints/mod_skinny/skinny_tables.h | 5 +++ src/mod/endpoints/mod_skinny/test-skinny.pl | 5 +++ 6 files changed, 80 insertions(+), 3 deletions(-) diff --git a/src/mod/endpoints/mod_skinny/mod_skinny.c b/src/mod/endpoints/mod_skinny/mod_skinny.c index 63cc514429..a90df113d8 100644 --- a/src/mod/endpoints/mod_skinny/mod_skinny.c +++ b/src/mod/endpoints/mod_skinny/mod_skinny.c @@ -1460,13 +1460,14 @@ 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_child(xprofile, "settings"); + switch_xml_t xsettings; + switch_xml_t xdevice_types; if (zstr(profile_name)) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, " is missing name attribute\n"); continue; } - if (xsettings) { + if ((xsettings = switch_xml_child(xprofile, "settings"))) { switch_memory_pool_t *profile_pool = NULL; char dbname[256]; switch_core_db_t *db; @@ -1521,6 +1522,7 @@ static switch_status_t load_skinny_config(void) profile->port = 2000; } + /* Database */ switch_snprintf(dbname, sizeof(dbname), "skinny_%s", profile->name); profile->dbname = switch_core_strdup(profile->pool, dbname); @@ -1558,6 +1560,32 @@ 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); + } + } + } + + /* Register profile */ switch_mutex_lock(globals.mutex); switch_core_hash_insert(globals.profile_hash, profile->name, profile); 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 61ded754a3..d8728510a6 100644 --- a/src/mod/endpoints/mod_skinny/mod_skinny.h +++ b/src/mod/endpoints/mod_skinny/mod_skinny.h @@ -67,6 +67,7 @@ struct skinny_profile { uint32_t keep_alive; char date_format[6]; int debug; + switch_hash_t *device_type_params_hash; /* db */ char *dbname; char *odbc_dsn; @@ -93,6 +94,10 @@ struct skinny_profile { }; typedef struct skinny_profile skinny_profile_t; +struct skinny_device_type_params { + char firmware_version[16]; +}; +typedef struct skinny_device_type_params skinny_device_type_params_t; /*****************************************************************************/ /* LISTENERS TYPES */ @@ -107,8 +112,9 @@ struct listener { skinny_profile_t *profile; char device_name[16]; uint32_t device_instance; + uint32_t device_type; - char firmware_version[16]; + char firmware_version[16]; switch_socket_t *sock; switch_memory_pool_t *pool; diff --git a/src/mod/endpoints/mod_skinny/skinny_protocol.c b/src/mod/endpoints/mod_skinny/skinny_protocol.c index f1bb313fa3..0c0396e7f6 100644 --- a/src/mod/endpoints/mod_skinny/skinny_protocol.c +++ b/src/mod/endpoints/mod_skinny/skinny_protocol.c @@ -1394,6 +1394,8 @@ switch_status_t send_version(listener_t *listener, { skinny_message_t *message; message = switch_core_alloc(listener->pool, 12+sizeof(message->data.version)); + message->type = VERSION_MESSAGE; + message->length = 4+ sizeof(message->data.version); strncpy(message->data.version.version, version, 16); return skinny_send_reply(listener, message); } @@ -1655,6 +1657,7 @@ switch_status_t skinny_handle_register(listener_t *listener, skinny_message_t *r strncpy(listener->device_name, request->data.reg.device_name, 16); listener->device_instance = request->data.reg.instance; + listener->device_type = request->data.reg.device_type; xskinny = switch_xml_child(xuser, "skinny"); if (xskinny) { @@ -2126,6 +2129,18 @@ switch_status_t skinny_handle_button_template_request(listener_t *listener, skin switch_status_t skinny_handle_version_request(listener_t *listener, skinny_message_t *request) { + if (zstr(listener->firmware_version)) { + char *id_str; + skinny_device_type_params_t *params; + id_str = switch_mprintf("%d", listener->device_type); + params = (skinny_device_type_params_t *) switch_core_hash_find(listener->profile->device_type_params_hash, id_str); + if (params) { + if (!zstr(params->firmware_version)) { + strncpy(listener->firmware_version, params->firmware_version, 16); + } + } + } + if (!zstr(listener->firmware_version)) { return send_version(listener, listener->firmware_version); } else { diff --git a/src/mod/endpoints/mod_skinny/skinny_tables.c b/src/mod/endpoints/mod_skinny/skinny_tables.c index 42e8bb96b3..ac16b6509f 100644 --- a/src/mod/endpoints/mod_skinny/skinny_tables.c +++ b/src/mod/endpoints/mod_skinny/skinny_tables.c @@ -98,6 +98,24 @@ struct skinny_table SKINNY_MESSAGE_TYPES[] = { SKINNY_DECLARE_ID2STR(skinny_message_type2str, SKINNY_MESSAGE_TYPES, "UnknownMessage") SKINNY_DECLARE_STR2ID(skinny_str2message_type, SKINNY_MESSAGE_TYPES, -1) +struct skinny_table SKINNY_DEVICE_TYPES[] = { + {"Cisco 30 SP+", 0x0001}, + {"Cisco 12 SP+", 0x0002}, + {"Cisco 12 SP", 0x0003}, + {"Cisco 12", 0x0004}, + {"Cisco 30 VIP", 0x0005}, + {"Cisco IP Phone 7910", 0x0006}, + {"Cisco IP Phone 7960", 0x0007}, + {"Cisco IP Phone 7940", 0x0008}, + {"Cisco IP Phone 7935", 0x0009}, + {"Cisco ATA 186", 0x000c}, + {"Cisco IP Phone 7961", 0x4275}, + {"Cisco IP Phone 7936", 0x4276}, + {NULL, 0} +}; +SKINNY_DECLARE_ID2STR(skinny_device_type2str, SKINNY_DEVICE_TYPES, "UnknownDeviceType") +SKINNY_DECLARE_STR2ID(skinny_str2device_type, SKINNY_DEVICE_TYPES, -1) + struct skinny_table SKINNY_RING_TYPES[] = { {"RingOff", SKINNY_RING_OFF}, {"RingInside", SKINNY_RING_INSIDE}, diff --git a/src/mod/endpoints/mod_skinny/skinny_tables.h b/src/mod/endpoints/mod_skinny/skinny_tables.h index 90bc45ef91..5efd774648 100644 --- a/src/mod/endpoints/mod_skinny/skinny_tables.h +++ b/src/mod/endpoints/mod_skinny/skinny_tables.h @@ -89,6 +89,11 @@ const char *skinny_message_type2str(uint32_t id); uint32_t skinny_str2message_type(const char *str); #define SKINNY_PUSH_MESSAGE_TYPES SKINNY_DECLARE_PUSH_MATCH(SKINNY_MESSAGE_TYPES) +struct skinny_table SKINNY_DEVICE_TYPES[13]; +const char *skinny_device_type2str(uint32_t id); +uint32_t skinny_str2device_type(const char *str); +#define SKINNY_PUSH_DEVICE_TYPES SKINNY_DECLARE_PUSH_MATCH(SKINNY_DEVICE_TYPES) + enum skinny_tone { SKINNY_TONE_SILENCE = 0x00, SKINNY_TONE_DIALTONE = 0x21, diff --git a/src/mod/endpoints/mod_skinny/test-skinny.pl b/src/mod/endpoints/mod_skinny/test-skinny.pl index a8c7bb5d68..a44afa33dc 100644 --- a/src/mod/endpoints/mod_skinny/test-skinny.pl +++ b/src/mod/endpoints/mod_skinny/test-skinny.pl @@ -64,6 +64,11 @@ $socket->send_message( ) ); +if(0) { + $socket->send_message(VERSION_REQ_MESSAGE); + $socket->receive_message(); # VersionMessage +} + $socket->send_message(BUTTON_TEMPLATE_REQ_MESSAGE); $socket->receive_message(); # ButtonTemplateMessage