dbus: Split message_handler() into readable helper functions
authorJouni Malinen <j@w1.fi>
Sat, 26 Dec 2009 19:26:56 +0000 (21:26 +0200)
committerJouni Malinen <j@w1.fi>
Sat, 26 Dec 2009 19:27:24 +0000 (21:27 +0200)
wpa_supplicant/dbus/dbus_new_helpers.c

index 99552cb..5620171 100644 (file)
@@ -997,6 +997,174 @@ static int is_signature_correct(DBusMessage *message,
 }
 
 
+static DBusMessage * properties_get_all(DBusMessage *message, char *interface,
+                                       struct wpa_dbus_object_desc *obj_dsc)
+{
+       if (os_strcmp(dbus_message_get_signature(message), "s") != 0)
+               return dbus_message_new_error(message, DBUS_ERROR_INVALID_ARGS,
+                                             NULL);
+
+       return get_all_properties(message, interface,
+                                 obj_dsc->properties);
+}
+
+
+static DBusMessage * properties_get(DBusMessage *message,
+                                   struct wpa_dbus_property_desc *dsc)
+{
+       if (os_strcmp(dbus_message_get_signature(message), "ss"))
+               return dbus_message_new_error(message, DBUS_ERROR_INVALID_ARGS,
+                                             NULL);
+
+       if (dsc->access != W && dsc->getter)
+               return dsc->getter(message, dsc->user_data);
+
+       return dbus_message_new_error(message, DBUS_ERROR_INVALID_ARGS,
+                                     "Property is write-only");
+}
+
+
+static DBusMessage * properties_set(DBusMessage *message,
+                                   struct wpa_dbus_property_desc *dsc)
+{
+       if (os_strcmp(dbus_message_get_signature(message), "ssv"))
+               return dbus_message_new_error(message, DBUS_ERROR_INVALID_ARGS,
+                                             NULL);
+
+       if (dsc->access != R && dsc->setter)
+               return dsc->setter(message, dsc->user_data);
+
+       return dbus_message_new_error(message, DBUS_ERROR_INVALID_ARGS,
+                                     "Property is read-only");
+}
+
+
+static DBusMessage *
+properties_get_or_set(DBusMessage *message, DBusMessageIter *iter,
+                     char *interface,
+                     struct wpa_dbus_object_desc *obj_dsc)
+{
+       struct wpa_dbus_property_desc *property_dsc;
+       char *property;
+       const char *method;
+
+       method = dbus_message_get_member(message);
+       property_dsc = obj_dsc->properties;
+
+       /* Second argument: property name (DBUS_TYPE_STRING) */
+       if (!dbus_message_iter_next(iter) ||
+           dbus_message_iter_get_arg_type(iter) != DBUS_TYPE_STRING) {
+               return dbus_message_new_error(message, DBUS_ERROR_INVALID_ARGS,
+                                             NULL);
+       }
+       dbus_message_iter_get_basic(iter, &property);
+
+       while (property_dsc) {
+               /* compare property names and
+                * interfaces */
+               if (!os_strncmp(property_dsc->dbus_property, property,
+                               WPAS_DBUS_METHOD_SIGNAL_PROP_MAX) &&
+                   !os_strncmp(property_dsc->dbus_interface, interface,
+                               WPAS_DBUS_INTERFACE_MAX))
+                       break;
+
+               property_dsc = property_dsc->next;
+       }
+       if (property_dsc == NULL) {
+               wpa_printf(MSG_DEBUG, "no property handler for %s.%s on %s",
+                          interface, property,
+                          dbus_message_get_path(message));
+               return dbus_message_new_error(message, DBUS_ERROR_INVALID_ARGS,
+                                             "No such property");
+       }
+
+       if (os_strncmp(WPA_DBUS_PROPERTIES_GET, method,
+                      WPAS_DBUS_METHOD_SIGNAL_PROP_MAX) == 0)
+               return properties_get(message, property_dsc);
+
+       return properties_set(message, property_dsc);
+}
+
+
+static DBusMessage * properties_handler(DBusMessage *message,
+                                       struct wpa_dbus_object_desc *obj_dsc)
+{
+       DBusMessageIter iter;
+       char *interface;
+       const char *method;
+
+       method = dbus_message_get_member(message);
+       dbus_message_iter_init(message, &iter);
+
+       if (!os_strncmp(WPA_DBUS_PROPERTIES_GET, method,
+                       WPAS_DBUS_METHOD_SIGNAL_PROP_MAX) ||
+           !os_strncmp(WPA_DBUS_PROPERTIES_SET, method,
+                       WPAS_DBUS_METHOD_SIGNAL_PROP_MAX) ||
+           !os_strncmp(WPA_DBUS_PROPERTIES_GETALL, method,
+                       WPAS_DBUS_METHOD_SIGNAL_PROP_MAX)) {
+               /* First argument: interface name (DBUS_TYPE_STRING) */
+               if (dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_STRING)
+               {
+                       return dbus_message_new_error(message,
+                                                     DBUS_ERROR_INVALID_ARGS,
+                                                     NULL);
+               }
+
+               dbus_message_iter_get_basic(&iter, &interface);
+
+               if (!os_strncmp(WPA_DBUS_PROPERTIES_GETALL, method,
+                               WPAS_DBUS_METHOD_SIGNAL_PROP_MAX)) {
+                       /* GetAll */
+                       return properties_get_all(message, interface, obj_dsc);
+               }
+               /* Get or Set */
+               return properties_get_or_set(message, &iter, interface,
+                                            obj_dsc);
+       }
+       return dbus_message_new_error(message, DBUS_ERROR_UNKNOWN_METHOD,
+                                     NULL);
+}
+
+
+static DBusMessage * msg_method_handler(DBusMessage *message,
+                                       struct wpa_dbus_object_desc *obj_dsc)
+{
+       struct wpa_dbus_method_desc *method_dsc = obj_dsc->methods;
+       const char *method;
+       const char *msg_interface;
+
+       method = dbus_message_get_member(message);
+       msg_interface = dbus_message_get_interface(message);
+
+       /* try match call to any registered method */
+       while (method_dsc) {
+               /* compare method names and interfaces */
+               if (!os_strncmp(method_dsc->dbus_method, method,
+                               WPAS_DBUS_METHOD_SIGNAL_PROP_MAX) &&
+                   !os_strncmp(method_dsc->dbus_interface, msg_interface,
+                               WPAS_DBUS_INTERFACE_MAX))
+                       break;
+
+               method_dsc = method_dsc->next;
+       }
+       if (method_dsc == NULL) {
+               wpa_printf(MSG_DEBUG, "no method handler for %s.%s on %s",
+                          msg_interface, method,
+                          dbus_message_get_path(message));
+               return dbus_message_new_error(message,
+                                             DBUS_ERROR_UNKNOWN_METHOD, NULL);
+       }
+
+       if (!is_signature_correct(message, method_dsc)) {
+               return dbus_message_new_error(message, DBUS_ERROR_INVALID_ARGS,
+                                             NULL);
+       }
+
+       return method_dsc->method_handler(message,
+                                         method_dsc->handler_argument);
+}
+
+
 /**
  * message_handler - Handles incoming DBus messages
  * @connection: DBus connection on which message was received
@@ -1008,8 +1176,8 @@ static int is_signature_correct(DBusMessage *message,
  * of the special cases i.e. introspection call or properties get/getall/set
  * methods and handles it. Else it iterates over registered methods list
  * and tries to match method's name and interface to those read from message
- * If appropriate method was found it's handler function is called and
- * response is sent. Otherwise the DBUS_ERROR_UNKNOWN_METHOD error message
+ * If appropriate method was found its handler function is called and
+ * response is sent. Otherwise, the DBUS_ERROR_UNKNOWN_METHOD error message
  * will be sent.
  */
 static DBusHandlerResult message_handler(DBusConnection *connection,
@@ -1019,17 +1187,15 @@ static DBusHandlerResult message_handler(DBusConnection *connection,
        const char *method;
        const char *path;
        const char *msg_interface;
-
-#define MESSAGE_UNHANDLED (DBusMessage *) 1
-
-       DBusMessage *reply = MESSAGE_UNHANDLED;
+       DBusMessage *reply;
 
        /* get method, interface and path the message is addressed to */
        method = dbus_message_get_member(message);
        path = dbus_message_get_path(message);
        msg_interface = dbus_message_get_interface(message);
        if (!method || !path || !msg_interface)
-               goto out;
+               return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
+
        wpa_printf(MSG_MSGDUMP, "dbus: %s.%s (%s)",
                   msg_interface, method, path);
 
@@ -1039,162 +1205,23 @@ static DBusHandlerResult message_handler(DBusConnection *connection,
            !os_strncmp(WPA_DBUS_INTROSPECTION_INTERFACE, msg_interface,
                        WPAS_DBUS_INTERFACE_MAX))
                reply = introspect(message, obj_dsc);
-       else if (!strncmp(WPA_DBUS_PROPERTIES_INTERFACE, msg_interface,
-                         WPAS_DBUS_INTERFACE_MAX)) {
+       else if (!os_strncmp(WPA_DBUS_PROPERTIES_INTERFACE, msg_interface,
+                            WPAS_DBUS_INTERFACE_MAX)) {
                /* if message is properties method call */
-               DBusMessageIter iter;
-               char *interface;
-               char *property;
-
-               dbus_message_iter_init(message, &iter);
-
-               if (!os_strncmp(WPA_DBUS_PROPERTIES_GET, method,
-                               WPAS_DBUS_METHOD_SIGNAL_PROP_MAX) ||
-                   !os_strncmp(WPA_DBUS_PROPERTIES_SET, method,
-                               WPAS_DBUS_METHOD_SIGNAL_PROP_MAX) ||
-                   !os_strncmp(WPA_DBUS_PROPERTIES_GETALL, method,
-                               WPAS_DBUS_METHOD_SIGNAL_PROP_MAX)) {
-                       /* First argument: interface name (DBUS_TYPE_STRING) */
-                       if (dbus_message_iter_get_arg_type(&iter) !=
-                           DBUS_TYPE_STRING) {
-                               reply = dbus_message_new_error(
-                                       message, DBUS_ERROR_INVALID_ARGS,
-                                       NULL);
-                               goto out;
-                       }
-
-                       dbus_message_iter_get_basic(&iter, &interface);
-
-                       /* GetAll */
-                       if (!os_strncmp(WPA_DBUS_PROPERTIES_GETALL, method,
-                                       WPAS_DBUS_METHOD_SIGNAL_PROP_MAX)) {
-                               if (os_strcmp(dbus_message_get_signature(
-                                                     message), "s"))
-                                       reply = dbus_message_new_error(
-                                               message,
-                                               DBUS_ERROR_INVALID_ARGS, NULL);
-                               else
-                                       reply = get_all_properties(
-                                               message, interface,
-                                               obj_dsc->properties);
-                       } else {
-                               /* Get or Set */
-                               struct wpa_dbus_property_desc *property_dsc;
-                               property_dsc = obj_dsc->properties;
-
-                               /* Second argument: property name
-                                * (DBUS_TYPE_STRING) */
-                               if (!dbus_message_iter_next(&iter) ||
-                                   dbus_message_iter_get_arg_type(&iter) !=
-                                   DBUS_TYPE_STRING) {
-                                       reply = dbus_message_new_error(
-                                               message,
-                                               DBUS_ERROR_INVALID_ARGS, NULL);
-                                       goto out;
-                               }
-                               dbus_message_iter_get_basic(&iter, &property);
-
-                               while (property_dsc) {
-                                       /* compare property names and
-                                        * interfaces */
-                                       if (!os_strncmp(property_dsc->dbus_property,
-                                                       property,
-                                                       WPAS_DBUS_METHOD_SIGNAL_PROP_MAX) &&
-                                           !os_strncmp(property_dsc->dbus_interface, interface,
-                                                       WPAS_DBUS_INTERFACE_MAX))
-                                               break;
-
-                                       property_dsc = property_dsc->next;
-                               }
-                               if (property_dsc) {
-                                       /* Get */
-                                       if (!os_strncmp(WPA_DBUS_PROPERTIES_GET, method,
-                                                       WPAS_DBUS_METHOD_SIGNAL_PROP_MAX)) {
-                                               if (os_strcmp(dbus_message_get_signature(message), "ss"))
-                                                       reply = dbus_message_new_error(message,
-                                                                                      DBUS_ERROR_INVALID_ARGS, NULL);
-                                               else if (property_dsc->access != W &&
-                                                        property_dsc->getter)
-                                                       reply = property_dsc->getter(message,
-                                                                                    property_dsc->user_data);
-                                               else
-                                                       reply = dbus_message_new_error(message,
-                                                                                      DBUS_ERROR_INVALID_ARGS,
-                                                                                      "Property is write-only");
-                                       } else {
-                                               /* Set */
-                                               if (os_strcmp(dbus_message_get_signature(message), "ssv"))
-                                                       reply = dbus_message_new_error(message,
-                                                                                      DBUS_ERROR_INVALID_ARGS, NULL);
-                                               else if (property_dsc->access != R &&
-                                                        property_dsc->setter) {
-                                                       reply = property_dsc->setter
-                                                               (message, property_dsc->user_data);
-                                               } else {
-                                                       reply = dbus_message_new_error(message,
-                                                                                      DBUS_ERROR_INVALID_ARGS,
-                                                                                      "Property is read-only");
-                                               }
-                                       }
-                               } else {
-                                       wpa_printf(MSG_DEBUG, "no property handler for %s.%s\n"
-                                                  "on %s", interface, property, path);
-                                       reply = dbus_message_new_error(message,
-                                                                      DBUS_ERROR_INVALID_ARGS,
-                                                                      "No such property");
-                               }
-                       }
-               } else {
-                       reply = dbus_message_new_error(
-                               message, DBUS_ERROR_UNKNOWN_METHOD, NULL);
-                       goto out;
-               }
+               reply = properties_handler(message, obj_dsc);
        } else {
-               struct wpa_dbus_method_desc *method_dsc = obj_dsc->methods;
-
-               /* try match call to any registered method */
-               while (method_dsc) {
-                       /* compare method names and interfaces */
-                       if (!os_strncmp(method_dsc->dbus_method, method,
-                                       WPAS_DBUS_METHOD_SIGNAL_PROP_MAX) &&
-                           !os_strncmp(method_dsc->dbus_interface,
-                                       msg_interface,
-                                       WPAS_DBUS_INTERFACE_MAX))
-                               break;
-
-                       method_dsc = method_dsc->next;
-               }
-               if (method_dsc) {
-                       if (is_signature_correct(message, method_dsc)) {
-                               reply = method_dsc->method_handler(
-                                       message, method_dsc->handler_argument);
-                       } else {
-                               reply = dbus_message_new_error(
-                                       message, DBUS_ERROR_INVALID_ARGS,
-                                       NULL);
-                       }
-               } else {
-                       wpa_printf(MSG_DEBUG, "no method handler for %s.%s "
-                                  "on %s", msg_interface, method, path);
-                       reply = dbus_message_new_error(
-                               message, DBUS_ERROR_UNKNOWN_METHOD, NULL);
-               }
+               reply = msg_method_handler(message, obj_dsc);
        }
 
-out:
-       /* If the message was handled, send back the reply */
-       if (reply != MESSAGE_UNHANDLED) {
-               /* If handler succeed returning NULL, reply empty message */
-               if (!reply)
-                       reply = dbus_message_new_method_return(message);
-               if (reply) {
-                       if (!dbus_message_get_no_reply(message))
-                               dbus_connection_send(connection, reply, NULL);
-                       dbus_message_unref(reply);
-               }
-               return DBUS_HANDLER_RESULT_HANDLED;
-       } else
-               return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
+       /* If handler succeed returning NULL, reply empty message */
+       if (!reply)
+               reply = dbus_message_new_method_return(message);
+       if (reply) {
+               if (!dbus_message_get_no_reply(message))
+                       dbus_connection_send(connection, reply, NULL);
+               dbus_message_unref(reply);
+       }
+       return DBUS_HANDLER_RESULT_HANDLED;
 }