]> git.ipfire.org Git - thirdparty/asterisk.git/commitdiff
Fix case-sensitivity for device-specific event subscriptions and CCSS
authorKinsey Moore <kmoore@digium.com>
Fri, 2 Mar 2012 21:02:21 +0000 (21:02 +0000)
committerKinsey Moore <kmoore@digium.com>
Fri, 2 Mar 2012 21:02:21 +0000 (21:02 +0000)
This change fixes case-sensitivity for device-specific subscriptions such that
the technology identifier is case-insensitive while the remainder of the device
string is still case-sensitive.  This should also preserve the original case of
the device string as passed in to the event system.  CCSS is the only feature
affected as it is the only consumer of device-specific event subscriptions.

The second part of this patch addresses similar case-sensitivity issues within
CCSS itself that prevented it from functioning correctly after the fix to the
events system.

This adds a unit test to verify that the event system works as expected.

(closes issue ASTERISK-19422)
Review: https://reviewboard.asterisk.org/r/1780/

git-svn-id: https://origsvn.digium.com/svn/asterisk/branches/1.8@357940 65c4cc65-6c06-0410-ace0-fbb531ad65f3

include/asterisk/strings.h
main/ccss.c
main/event.c
tests/test_event.c

index 5827dda9ba2a806fc87b3d0a3ec8ac9d3ebac3e4..6764125d135298f543396b52c5bb70a21befe93e 100644 (file)
@@ -896,6 +896,26 @@ int ast_check_digits(const char *arg),
 }
 )
 
+/*!
+ * \brief Convert the tech portion of a device string to upper case
+ *
+ * \retval dev_str Returns the char* passed in for convenience
+ */
+AST_INLINE_API(
+char *ast_tech_to_upper(char *dev_str),
+{
+       char *pos;
+       if (!dev_str || !strchr(dev_str, '/')) {
+               return dev_str;
+       }
+
+       for (pos = dev_str; *pos && *pos != '/'; pos++) {
+               *pos = toupper(*pos);
+       }
+       return dev_str;
+}
+)
+
 /*!
  * \brief Compute a hash value on a string
  *
index e3e2ec1dc61daf80780cabe57f072ed0518a06c1..d20c8361cd3f0d2badc27c7e688e4452d696751c 100644 (file)
@@ -1103,7 +1103,10 @@ static int generic_monitor_cmp_fn(void *obj, void *arg, int flags)
 
 static struct generic_monitor_instance_list *find_generic_monitor_instance_list(const char * const device_name)
 {
-       struct generic_monitor_instance_list finder = {.device_name = device_name};
+       struct generic_monitor_instance_list finder = {0};
+       char *uppertech = ast_strdupa(device_name);
+       ast_tech_to_upper(uppertech);
+       finder.device_name = uppertech;
 
        return ao2_t_find(generic_monitors, &finder, OBJ_POINTER, "Finding generic monitor instance list");
 }
@@ -1125,15 +1128,18 @@ static struct generic_monitor_instance_list *create_new_generic_list(struct ast_
 {
        struct generic_monitor_instance_list *generic_list = ao2_t_alloc(sizeof(*generic_list),
                        generic_monitor_instance_list_destructor, "allocate generic monitor instance list");
+       char * device_name;
 
        if (!generic_list) {
                return NULL;
        }
 
-       if (!(generic_list->device_name = ast_strdup(monitor->interface->device_name))) {
+       if (!(device_name = ast_strdup(monitor->interface->device_name))) {
                cc_unref(generic_list, "Failed to strdup the monitor's device name");
                return NULL;
        }
+       ast_tech_to_upper(device_name);
+       generic_list->device_name = device_name;
 
        if (!(generic_list->sub = ast_event_subscribe(AST_EVENT_DEVICE_STATE,
                generic_monitor_devstate_cb, "Requesting CC", NULL,
index a62e736376abc17971e36856fef9ef7ed4b49143..e8af16ad34d2adc66e3182afa545988d2b98a66a 100644 (file)
@@ -411,8 +411,16 @@ static int match_sub_ie_val_to_event(const struct ast_event_ie_val *sub_ie_val,
                res = (sub_ie_val->payload.uint & event_ie_val->payload.uint);
                break;
        case AST_EVENT_IE_PLTYPE_STR:
-               res = !strcmp(sub_ie_val->payload.str, event_ie_val->payload.str);
+       {
+               const char *substr = sub_ie_val->payload.str;
+               const char *estr = event_ie_val->payload.str;
+               if (sub_ie_val->ie_type == AST_EVENT_IE_DEVICE) {
+                       substr = ast_tech_to_upper(ast_strdupa(substr));
+                       estr = ast_tech_to_upper(ast_strdupa(estr));
+               }
+               res = !strcmp(substr, estr);
                break;
+       }
        case AST_EVENT_IE_PLTYPE_RAW:
                res = (sub_ie_val->raw_datalen == event_ie_val->raw_datalen
                        && !memcmp(sub_ie_val->payload.raw, event_ie_val->payload.raw,
@@ -576,8 +584,19 @@ static int match_ie_val(const struct ast_event *event,
                }
 
                str = event2 ? ast_event_get_ie_str(event2, ie_val->ie_type) : ie_val->payload.str;
-               if (str && !strcmp(str, ast_event_get_ie_str(event, ie_val->ie_type))) {
-                       return 1;
+               if (str) {
+                       const char *e1str, *e2str;
+                       e1str = ast_event_get_ie_str(event, ie_val->ie_type);
+                       e2str = str;
+
+                       if (ie_val->ie_type == AST_EVENT_IE_DEVICE) {
+                               e1str = ast_tech_to_upper(ast_strdupa(e1str));
+                               e2str = ast_tech_to_upper(ast_strdupa(e2str));
+                       }
+
+                       if (!strcmp(e1str, e2str)) {
+                               return 1;
+                       }
                }
 
                return 0;
@@ -820,7 +839,13 @@ int ast_event_sub_append_ie_str(struct ast_event_sub *sub,
                return -1;
        }
 
-       ie_val->payload.hash = ast_str_hash(str);
+       if (ie_type == AST_EVENT_IE_DEVICE) {
+               char *uppertech = ast_strdupa(str);
+               ast_tech_to_upper(uppertech);
+               ie_val->payload.hash = ast_str_hash(uppertech);
+       } else {
+               ie_val->payload.hash = ast_str_hash(str);
+       }
 
        AST_LIST_INSERT_TAIL(&sub->ie_vals, ie_val, entry);
 
@@ -1116,7 +1141,13 @@ int ast_event_append_ie_str(struct ast_event **event, enum ast_event_ie_type ie_
        str_payload = alloca(payload_len);
 
        strcpy(str_payload->str, str);
-       str_payload->hash = ast_str_hash(str);
+       if (ie_type == AST_EVENT_IE_DEVICE) {
+               char *uppertech = ast_strdupa(str);
+               ast_tech_to_upper(uppertech);
+               str_payload->hash = ast_str_hash(uppertech);
+       } else {
+               str_payload->hash = ast_str_hash(str);
+       }
 
        return ast_event_append_ie_raw(event, ie_type, str_payload, payload_len);
 }
index 4924e3f20f4d390740d01995c17b04c4adace632..92fb4ec78aa55c44dcc489ffc1a852f69de054ff 100644 (file)
@@ -606,6 +606,25 @@ AST_TEST_DEFINE(event_sub_test)
                res = AST_TEST_FAIL;
        }
 
+       /* Make sure that the tech portion of the device string is case-insensitive */
+       sub_res = ast_event_check_subscriber(AST_EVENT_CUSTOM,
+               AST_EVENT_IE_DEVICE, AST_EVENT_IE_PLTYPE_STR, "foo/bar",
+               AST_EVENT_IE_END);
+       if (sub_res != AST_EVENT_SUB_EXISTS) {
+               ast_test_status_update(test, "Str FOO/bar subscription lacks proper case-sensitivity for device strings\n");
+               res = AST_TEST_FAIL;
+       }
+
+       /* Make sure that the non-tech portion of the device string is case-sensitive
+        * and fails to match appropriately */
+       sub_res = ast_event_check_subscriber(AST_EVENT_CUSTOM,
+               AST_EVENT_IE_DEVICE, AST_EVENT_IE_PLTYPE_STR, "FOO/BAR",
+               AST_EVENT_IE_END);
+       if (sub_res == AST_EVENT_SUB_EXISTS) {
+               ast_test_status_update(test, "Str FOO/bar subscription lacks proper case-sensitivity for device strings\n");
+               res = AST_TEST_FAIL;
+       }
+
        sub_res = ast_event_check_subscriber(AST_EVENT_CUSTOM,
                AST_EVENT_IE_DEVICE, AST_EVENT_IE_PLTYPE_STR, "Money",
                AST_EVENT_IE_END);