diff options
| author | Claudio Takahasi <claudio.takahasi@openbossa.org> | 2007-01-19 18:31:11 +0000 | 
|---|---|---|
| committer | Claudio Takahasi <claudio.takahasi@openbossa.org> | 2007-01-19 18:31:11 +0000 | 
| commit | ed95fffdbb414013f3dd29f8e400b0064f152793 (patch) | |
| tree | 4f4f61f603ec5e30cedefd3658e801417d8e06e9 | |
| parent | 4f411bad65f2725f628ea610a49310da97c28d30 (diff) | |
Added function to search PnP handle
| -rw-r--r-- | input/input-service.c | 117 | 
1 files changed, 108 insertions, 9 deletions
| diff --git a/input/input-service.c b/input/input-service.c index 8ca06ecf..cec55dc2 100644 --- a/input/input-service.c +++ b/input/input-service.c @@ -47,13 +47,45 @@  #define INPUT_DEVICE_INTERFACE	"org.bluez.input.Device"  #define INPUT_ERROR_INTERFACE	"org.bluez.Error" -  static DBusConnection *connection = NULL;  struct input_device {  	char addr[18];  }; +struct pending_req { +	char addr[18]; +	DBusConnection *conn; +	DBusMessage *msg; +}; + +struct pending_req *pending_req_new(DBusConnection *conn, +				DBusMessage *msg, const char *addr) +{ +	struct pending_req *pr; +	pr = malloc(sizeof(struct pending_req)); +	if (!pr) +		return NULL; + +	memset(pr, 0, sizeof(struct pending_req)); +	memcpy(pr->addr, addr, 18); +	pr->conn = dbus_connection_ref(conn); +	pr->msg = dbus_message_ref(msg); + +	return pr; +} + +void pending_req_free(struct pending_req *pr) +{ +	if (!pr) +		return; +	if (pr->conn) +		dbus_connection_unref(pr->conn); +	if (pr->msg) +		dbus_message_unref(pr->msg); +	free(pr); +} +  struct input_device *input_device_new(const char *addr)  {  	struct input_device *idev; @@ -136,13 +168,6 @@ static int has_hid_record(const char *local, const char *peer)  	return 1;  } -static int search_request(DBusConnection *conn, -		DBusMessage *msg, const char *peer) -{ -	info("FIXME: service search"); -	return 0; -} -  /*   * Input Device methods   */ @@ -283,6 +308,72 @@ static int path_addr_cmp(const char *path, const char *addr)  	return strcasecmp(idev->addr, addr);  } +static void pnp_handle_reply(DBusPendingCall *call, void *data) +{ +	DBusMessage *reply = dbus_pending_call_steal_reply(call); +	struct pending_req *pr = data; +	DBusError derr; +	uint32_t *phandle; +	int len; + +	dbus_error_init(&derr); +	if (dbus_set_error_from_message(&derr, reply)) { +		err_generic(pr->conn, pr->msg, derr.name, derr.message); +		dbus_error_free(&derr); +		goto fail; +	} + +	if (!dbus_message_get_args(reply, &derr, +				DBUS_TYPE_ARRAY, DBUS_TYPE_UINT32, &phandle, &len, +				DBUS_TYPE_INVALID)) { + +		err_generic(pr->conn, pr->msg, derr.name, derr.message); +		dbus_error_free(&derr); +		goto fail; +	} + +	if (len == 0) { +		/* PnP is optional */ +		info("FIXME: PnP is optional, request HID record"); +	} else { +		/* Request PnP record */ +		info("FIXME: Request PnP Record"); +	} +fail: +	dbus_message_unref(reply); +	dbus_pending_call_unref(call); +} + +static int get_handles(struct input_manager *mgr, struct pending_req *pr, +		const char *uuid, DBusPendingCallNotifyFunction cb) +{ +	DBusMessage *msg; +	DBusPendingCall *pending; +	const char *paddr; + +	msg  = dbus_message_new_method_call("org.bluez", mgr->adapter_path, +			"org.bluez.Adapter", "GetRemoteServiceHandles"); +	if (!msg) +		return -1; + +	paddr = pr->addr; +	dbus_message_append_args(msg, +			DBUS_TYPE_STRING, &paddr, +			DBUS_TYPE_STRING, &uuid, +			DBUS_TYPE_INVALID); +	 +	if (dbus_connection_send_with_reply(pr->conn, msg, &pending, -1) == FALSE) { +		error("Can't send D-Bus message."); +		return -1; +	} + +	dbus_pending_call_set_notify(pending, cb, pr, +			(DBusFreeFunction) pending_req_free); +	dbus_message_unref(msg); + +	return 0; +} +  static DBusHandlerResult manager_create_device(DBusConnection *conn,  				DBusMessage *msg, void *data)  { @@ -292,6 +383,7 @@ static DBusHandlerResult manager_create_device(DBusConnection *conn,  	DBusError derr;  	const char *addr;  	const char *keyb_path = "/org/bluez/input/keyboard0"; +	const char *pnp_uuid = "00001200-0000-1000-8000-00805f9b34fb";  	GList *path;  	dbus_error_init(&derr); @@ -309,8 +401,15 @@ static DBusHandlerResult manager_create_device(DBusConnection *conn,  		return err_already_exists(conn, msg, "Input Already exists");  	if (!has_hid_record(mgr->adapter, addr)) { -		if (search_request(conn, msg, addr) < 0) +		struct pending_req *pr; +		pr = pending_req_new(conn, msg, addr); +		if (!pr) +			return DBUS_HANDLER_RESULT_NEED_MEMORY; + +		if (get_handles(mgr, pr, pnp_uuid, pnp_handle_reply) < 0) { +			pending_req_free(pr);  			return err_failed(conn, msg, "SDP error"); +		}  		return DBUS_HANDLER_RESULT_HANDLED;  	} | 
