Parcourir la source

dbus: Split message_handler() into readable helper functions

Jouni Malinen il y a 15 ans
Parent
commit
5a464ff86e
1 fichiers modifiés avec 186 ajouts et 159 suppressions
  1. 186 159
      wpa_supplicant/dbus/dbus_new_helpers.c

+ 186 - 159
wpa_supplicant/dbus/dbus_new_helpers.c

@@ -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;
 }