* [Bluez-devel] [PATCH] implement RFCOMM Connect and Disconnect methods
@ 2006-08-17 10:06 Matthew Garrett
2006-08-17 13:04 ` Marcel Holtmann
0 siblings, 1 reply; 14+ messages in thread
From: Matthew Garrett @ 2006-08-17 10:06 UTC (permalink / raw)
To: bluez-devel
Hi,
I sent this a couple of weeks ago, but didn't get any feedback. This
patch implements the Connect and Disconnect methods in the
org.bluez.RFCOMM namespace. I've changed it to use integers for services
rather than the string identifiers for a couple of reasons:
1) Nothing else seems to actually use the strings right now, even when
the docs suggest they do
2) The service values don't appear to be complete and don't deal with
the case of having multiple services of the same general type on a
device
Based on previous discussion with Marcel, this patch may not be ideal
since it doesn't deal with the case of the whether or not cached values
are valid. However, if the API is considered correct, then it would be
nice to add it with a note that it may not work under certain
circumstances and then fix that at some later stage.
? .deps
? Makefile
? Makefile.in
Index: dbus-api.txt
===================================================================
RCS file: /cvsroot/bluez/utils/hcid/dbus-api.txt,v
retrieving revision 1.40
diff -u -r1.40 dbus-api.txt
--- dbus-api.txt 9 Aug 2006 20:10:50 -0000 1.40
+++ dbus-api.txt 17 Aug 2006 09:55:18 -0000
@@ -895,11 +895,11 @@
Interface org.bluez.RFCOMM
Object path /org/bluez/{hci0,hci1,...}
-Methods string Connect(string address, string service)
+Methods string Connect(string address, int service)
This creates a connection to a remote RFCOMM based
- service. The service string can either be a UUID-16,
- a UUID-32, a UUID-128 or a service abbreviation.
+ service. The service should be a serviceid as
+ provided by the org.bluez.SDP methods.
The return value will be the path of the newly
created RFCOMM TTY device (for example /dev/rfcomm0).
@@ -907,11 +907,7 @@
If the application disconnects from the D-Bus this
connection will be terminated.
- Valid service values: "vcp", "map", "pbap", "sap",
- "ftp", "bpp", "bip", "synch",
- "dun", "opp", "fax", "spp"
-
- void CancelConnect(string address, string service)
+ void CancelConnect(string address, int service)
This method cancels a previous Connect method call.
@@ -971,13 +967,13 @@
Interface org.bluez.SDP
Object path /org/bluez/{hci0,hci1,...}
-Methods array{string} GetIdentifiers(string address)
+Methods array{int} GetIdentifiers(string address)
- array{string} GetIdentifiersByService(string address, string service)
+ array{int} GetIdentifiersByService(string address, string service)
- string GetUUID(string identifier)
+ string GetUUID(int identifier)
- string GetName(string identifier)
+ string GetName(int identifier)
string RegisterRFCOMM(string service, byte channel)
Index: dbus-rfcomm.c
===================================================================
RCS file: /cvsroot/bluez/utils/hcid/dbus-rfcomm.c,v
retrieving revision 1.9
diff -u -r1.9 dbus-rfcomm.c
--- dbus-rfcomm.c 2 Jun 2006 10:27:57 -0000 1.9
+++ dbus-rfcomm.c 17 Aug 2006 09:55:19 -0000
@@ -38,6 +38,8 @@
#include <bluetooth/rfcomm.h>
#include <bluetooth/hci.h>
#include <bluetooth/hci_lib.h>
+#include <bluetooth/sdp.h>
+#include <bluetooth/sdp_lib.h>
#include <dbus/dbus.h>
@@ -452,18 +454,87 @@
return node;
}
-static DBusHandlerResult rfcomm_connect_req(DBusConnection *conn,
- DBusMessage *msg, void *data)
+static DBusHandlerResult rfcomm_cancel_connect_req(DBusConnection *conn,
+ DBusMessage *msg, void *data)
{
- error("RFCOMM.Connect not implemented");
- return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
+ const char *dst;
+ int ch = -1;
+ uint32_t service;
+ DBusMessage *reply;
+ struct pending_connect *pending;
+ sdp_record_t *rec;
+ sdp_list_t *protos;
+
+ if (!dbus_message_get_args(msg, NULL,
+ DBUS_TYPE_STRING, &dst,
+ DBUS_TYPE_UINT32, &service,
+ DBUS_TYPE_INVALID))
+ return error_invalid_arguments(conn, msg);
+
+ /* Now we need to find a channel */
+
+ rec = find_record (dst, service);
+ if (!rec)
+ return error_record_does_not_exist (conn, msg);
+
+ if (sdp_get_access_protos(rec, &protos) == 0)
+ ch = sdp_get_proto_port (protos, RFCOMM_UUID);
+
+ if (ch == -1)
+ return error_record_does_not_exist (conn, msg);
+
+ pending = find_pending_connect(dst, ch);
+ if (!pending)
+ return error_connect_not_in_progress(conn, msg);
+
+ reply = dbus_message_new_method_return(msg);
+ if (!reply)
+ return DBUS_HANDLER_RESULT_NEED_MEMORY;
+
+ pending->canceled = 1;
+
+ return send_reply_and_unref(conn, reply);
}
-static DBusHandlerResult rfcomm_cancel_connect_req(DBusConnection *conn,
- DBusMessage *msg, void *data)
+static DBusHandlerResult rfcomm_connect_req(DBusConnection *conn,
+ DBusMessage *msg, void *data)
{
- error("RFCOMM.CancelConnect not implemented");
- return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
+ bdaddr_t bdaddr;
+ const char *dst;
+ uint32_t service;
+ int ch = -1;
+ int err;
+ struct hci_dbus_data *dbus_data = data;
+ sdp_record_t *rec;
+ sdp_list_t *protos;
+
+ hci_devba(dbus_data->dev_id, &bdaddr);
+
+ if (!dbus_message_get_args(msg, NULL,
+ DBUS_TYPE_STRING, &dst,
+ DBUS_TYPE_UINT32, &service,
+ DBUS_TYPE_INVALID))
+ return error_invalid_arguments(conn, msg);
+
+ /* Now we need to find a channel */
+
+ rec = find_record (dst, service);
+ if (!rec)
+ return error_record_does_not_exist (conn, msg);
+
+ if (sdp_get_access_protos(rec, &protos) == 0)
+ ch = sdp_get_proto_port (protos, RFCOMM_UUID);
+
+ if (ch == -1)
+ return error_record_does_not_exist (conn, msg);
+
+ if (find_pending_connect(dst, ch))
+ return error_connect_in_progress(conn, msg);
+
+ if (rfcomm_connect(conn, msg, &bdaddr, dst, NULL, ch, &err) < 0)
+ return error_failed(conn, msg, err);
+
+ return DBUS_HANDLER_RESULT_HANDLED;
}
static DBusHandlerResult rfcomm_connect_by_ch_req(DBusConnection *conn,
Index: dbus-sdp.c
===================================================================
RCS file: /cvsroot/bluez/utils/hcid/dbus-sdp.c,v
retrieving revision 1.8
diff -u -r1.8 dbus-sdp.c
--- dbus-sdp.c 1 Aug 2006 18:14:36 -0000 1.8
+++ dbus-sdp.c 17 Aug 2006 09:55:19 -0000
@@ -855,7 +855,7 @@
}
-static sdp_record_t *find_record(const char *address, int id)
+sdp_record_t *find_record(const char *address, int id)
{
struct slist *lp, *lr;
struct service_provider *p;
Index: dbus-test
===================================================================
RCS file: /cvsroot/bluez/utils/hcid/dbus-test,v
retrieving revision 1.22
diff -u -r1.22 dbus-test
--- dbus-test 9 Aug 2006 20:10:50 -0000 1.22
+++ dbus-test 17 Aug 2006 09:55:19 -0000
@@ -45,6 +45,7 @@
"ClearRemoteAlias",
"LastSeen",
"LastUsed",
+ "ConnectRemoteDevice",
"DisconnectRemoteDevice",
"CreateBonding",
"CancelBondingProcess",
@@ -343,9 +344,14 @@
print self.device.LastUsed(self.cmd_args[0])
else:
print 'Usage: %s -i <dev> LastUsed address' % self.name
+ elif self.cmd == 'ConnectRemoteDevice':
+ if len(self.cmd_args) == 1:
+ print self.device.ConnectRemoteDevice(self.cmd_args[0])
+ else:
+ print 'Usage: %s -i <dev> ConnectRemoteDevice address' % self.name
elif self.cmd == 'DisconnectRemoteDevice':
if len(self.cmd_args) == 1:
- print self.device.LastUsed(self.cmd_args[0])
+ print self.device.DisconnectRemoteDevice(self.cmd_args[0])
else:
print 'Usage: %s -i <dev> DisconnectRemoteDevice address' % self.name
elif self.cmd == 'CreateBonding':
Index: dbus.h
===================================================================
RCS file: /cvsroot/bluez/utils/hcid/dbus.h,v
retrieving revision 1.96
diff -u -r1.96 dbus.h
--- dbus.h 16 Aug 2006 18:43:50 -0000 1.96
+++ dbus.h 17 Aug 2006 09:55:19 -0000
@@ -200,4 +200,6 @@
int discoverable_timeout_handler(void *data);
+sdp_record_t *find_record(const char *address, int identifier);
+
#endif /* __H_BLUEZ_DBUS_H__ */
--
Matthew Garrett | mjg59@srcf.ucam.org
-------------------------------------------------------------------------
Using Tomcat but need to do more? Need to support web services, security?
Get stuff done quickly with pre-integrated technology to make your job easier
Download IBM WebSphere Application Server v.1.0.1 based on Apache Geronimo
http://sel.as-us.falkag.net/sel?cmd=lnk&kid=120709&bid=263057&dat=121642
_______________________________________________
Bluez-devel mailing list
Bluez-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/bluez-devel
^ permalink raw reply [flat|nested] 14+ messages in thread* Re: [Bluez-devel] [PATCH] implement RFCOMM Connect and Disconnect methods 2006-08-17 10:06 [Bluez-devel] [PATCH] implement RFCOMM Connect and Disconnect methods Matthew Garrett @ 2006-08-17 13:04 ` Marcel Holtmann 2006-08-17 11:41 ` Matthew Garrett 0 siblings, 1 reply; 14+ messages in thread From: Marcel Holtmann @ 2006-08-17 13:04 UTC (permalink / raw) To: BlueZ development; +Cc: bluez-devel Hi Matthew, > I sent this a couple of weeks ago, but didn't get any feedback. This > patch implements the Connect and Disconnect methods in the > org.bluez.RFCOMM namespace. I've changed it to use integers for services > rather than the string identifiers for a couple of reasons: > > 1) Nothing else seems to actually use the strings right now, even when > the docs suggest they do > 2) The service values don't appear to be complete and don't deal with > the case of having multiple services of the same general type on a > device > > Based on previous discussion with Marcel, this patch may not be ideal > since it doesn't deal with the case of the whether or not cached values > are valid. However, if the API is considered correct, then it would be > nice to add it with a note that it may not work under certain > circumstances and then fix that at some later stage. I haven't payed much attention to the RFCOMM parts of our D-Bus API since I declared it as experimental and it might still change. However one thing is that we wanna use strings. They are more flexible and if you use languages like Python they can come in handy. In this case for example you might use "spp" (service name) or "0x10000" (record handle) to connect to a specific RFCOMM channel. The SDP caching is still something that needs a lot of thinking before we will finally solve it. It is not as easy as people thing and always requesting a SDP record first is not a good idea either. However a lot of this depends on how broken the SDP records of the remote devices are. Regards Marcel ------------------------------------------------------------------------- Using Tomcat but need to do more? Need to support web services, security? Get stuff done quickly with pre-integrated technology to make your job easier Download IBM WebSphere Application Server v.1.0.1 based on Apache Geronimo http://sel.as-us.falkag.net/sel?cmd=lnk&kid=120709&bid=263057&dat=121642 _______________________________________________ Bluez-devel mailing list Bluez-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/bluez-devel ^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: [Bluez-devel] [PATCH] implement RFCOMM Connect and Disconnect methods 2006-08-17 13:04 ` Marcel Holtmann @ 2006-08-17 11:41 ` Matthew Garrett 2006-08-17 11:59 ` Johan Hedberg 0 siblings, 1 reply; 14+ messages in thread From: Matthew Garrett @ 2006-08-17 11:41 UTC (permalink / raw) To: BlueZ development On Thu, Aug 17, 2006 at 03:04:18PM +0200, Marcel Holtmann wrote: > I haven't payed much attention to the RFCOMM parts of our D-Bus API > since I declared it as experimental and it might still change. However > one thing is that we wanna use strings. They are more flexible and if > you use languages like Python they can come in handy. > > In this case for example you might use "spp" (service name) or > "0x10000" (record handle) to connect to a specific RFCOMM channel. I'm not entirely clear on what a service name represents. Is it a specific service, or is it the profile implemented by that service? What string should represent non-standard services? As an example, my phone has a service called "Nokia OBEX PC Suite Services". If I want to use that via the DBus interface, I'll presumably need to use the record handle anyway? > The SDP caching is still something that needs a lot of thinking before > we will finally solve it. It is not as easy as people thing and always > requesting a SDP record first is not a good idea either. However a lot > of this depends on how broken the SDP records of the remote devices are. I agree that always requesting the SDP record first is less than ideal, but I'd argue that it's better to have suboptimal functionality than no functionality :) Thanks, -- Matthew Garrett | mjg59@srcf.ucam.org ------------------------------------------------------------------------- Using Tomcat but need to do more? Need to support web services, security? Get stuff done quickly with pre-integrated technology to make your job easier Download IBM WebSphere Application Server v.1.0.1 based on Apache Geronimo http://sel.as-us.falkag.net/sel?cmd=lnk&kid=120709&bid=263057&dat=121642 _______________________________________________ Bluez-devel mailing list Bluez-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/bluez-devel ^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: [Bluez-devel] [PATCH] implement RFCOMM Connect and Disconnect methods 2006-08-17 11:41 ` Matthew Garrett @ 2006-08-17 11:59 ` Johan Hedberg 2006-08-17 12:01 ` Matthew Garrett 2006-08-19 14:36 ` Matthew Garrett 0 siblings, 2 replies; 14+ messages in thread From: Johan Hedberg @ 2006-08-17 11:59 UTC (permalink / raw) To: BlueZ development Hi Matthew, On Thu, Aug 17, 2006, Matthew Garrett wrote: > I'm not entirely clear on what a service name represents. Is it a > specific service, or is it the profile implemented by that service? What > string should represent non-standard services? As an example, my phone > has a service called "Nokia OBEX PC Suite Services". If I want to use > that via the DBus interface, I'll presumably need to use the record > handle anyway? Or its UUID (presumably 128bit) in string format. It seems that we'd have three different ways for specifying the target service: 1. friendly name (e.g. "ftp") 2. record handle 3. UUID Johan ------------------------------------------------------------------------- Using Tomcat but need to do more? Need to support web services, security? Get stuff done quickly with pre-integrated technology to make your job easier Download IBM WebSphere Application Server v.1.0.1 based on Apache Geronimo http://sel.as-us.falkag.net/sel?cmd=lnk&kid=120709&bid=263057&dat=121642 _______________________________________________ Bluez-devel mailing list Bluez-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/bluez-devel ^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: [Bluez-devel] [PATCH] implement RFCOMM Connect and Disconnect methods 2006-08-17 11:59 ` Johan Hedberg @ 2006-08-17 12:01 ` Matthew Garrett 2006-08-19 14:36 ` Matthew Garrett 1 sibling, 0 replies; 14+ messages in thread From: Matthew Garrett @ 2006-08-17 12:01 UTC (permalink / raw) To: BlueZ development On Thu, Aug 17, 2006 at 02:59:12PM +0300, Johan Hedberg wrote: > Or its UUID (presumably 128bit) in string format. It seems that we'd > have three different ways for specifying the target service: > 1. friendly name (e.g. "ftp") > 2. record handle > 3. UUID Ok. So we pass all of these as strings, parse them in the method and then connect to the appropriate channel? That seems doable. -- Matthew Garrett | mjg59@srcf.ucam.org ------------------------------------------------------------------------- Using Tomcat but need to do more? Need to support web services, security? Get stuff done quickly with pre-integrated technology to make your job easier Download IBM WebSphere Application Server v.1.0.1 based on Apache Geronimo http://sel.as-us.falkag.net/sel?cmd=lnk&kid=120709&bid=263057&dat=121642 _______________________________________________ Bluez-devel mailing list Bluez-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/bluez-devel ^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: [Bluez-devel] [PATCH] implement RFCOMM Connect and Disconnect methods 2006-08-17 11:59 ` Johan Hedberg 2006-08-17 12:01 ` Matthew Garrett @ 2006-08-19 14:36 ` Matthew Garrett 2006-08-20 1:39 ` Marcel Holtmann 1 sibling, 1 reply; 14+ messages in thread From: Matthew Garrett @ 2006-08-19 14:36 UTC (permalink / raw) To: BlueZ development Right. How about this (not heavily tested, more proof of concept) - it removes the unimplemented Connect and CancelConnect methods, and replaces them with ConnectByUUID, ConnectByService and ConnectByHandle methods with the appropriate CancelConnect methods. Index: dbus-api.txt =================================================================== RCS file: /cvsroot/bluez/utils/hcid/dbus-api.txt,v retrieving revision 1.41 diff -u -r1.41 dbus-api.txt --- dbus-api.txt 18 Aug 2006 19:50:27 -0000 1.41 +++ dbus-api.txt 19 Aug 2006 14:34:32 -0000 @@ -901,11 +901,11 @@ Interface org.bluez.RFCOMM Object path /org/bluez/{hci0,hci1,...} -Methods string Connect(string address, string service) +Methods string ConnectByService(string address, string service) This creates a connection to a remote RFCOMM based - service. The service string can either be a UUID-16, - a UUID-32, a UUID-128 or a service abbreviation. + service. The service string must be a service + abbreviation. The return value will be the path of the newly created RFCOMM TTY device (for example /dev/rfcomm0). @@ -917,9 +917,46 @@ "ftp", "bpp", "bip", "synch", "dun", "opp", "fax", "spp" - void CancelConnect(string address, string service) + void CancelConnectByService(string address, string service) - This method cancels a previous Connect method call. + This method cancels a previous ConnectByService method + call. + + string ConnectByUUID(string address, string uuid) + + This creates a connection to a remote RFCOMM based + service. The uuid string must be a UUID-128. + + The return value will be the path of the newly + created RFCOMM TTY device (for example /dev/rfcomm0). + + If the application disconnects from the D-Bus this + connection will be terminated. + + void CancelConnectByUUID(string address, string uuid) + + This method cancels a previous ConnectByUUID method + call. + + string ConnectByHandle(string address, uint32 handle) + + This creates a connection to a remote RFCOMM based + service. The handle must be a servicerecord handle. + + The return value will be the path of the newly + created RFCOMM TTY device (for example /dev/rfcomm0). + + If the application disconnects from the D-Bus this + connection will be terminated. + + Valid service values: "vcp", "map", "pbap", "sap", + "ftp", "bpp", "bip", "synch", + "dun", "opp", "fax", "spp" + + void CancelConnectByHandle(string address, string uuid) + + This method cancels a previous ConnectByHandle method + call. string ConnectByChannel(string address, byte channel) Index: dbus-rfcomm.c =================================================================== RCS file: /cvsroot/bluez/utils/hcid/dbus-rfcomm.c,v retrieving revision 1.10 diff -u -r1.10 dbus-rfcomm.c --- dbus-rfcomm.c 18 Aug 2006 18:29:40 -0000 1.10 +++ dbus-rfcomm.c 19 Aug 2006 14:34:32 -0000 @@ -33,11 +33,14 @@ #include <fcntl.h> #include <sys/ioctl.h> #include <sys/socket.h> +#include <arpa/inet.h> #include <bluetooth/bluetooth.h> #include <bluetooth/rfcomm.h> #include <bluetooth/hci.h> #include <bluetooth/hci_lib.h> +#include <bluetooth/sdp.h> +#include <bluetooth/sdp_lib.h> #include <dbus/dbus.h> @@ -452,18 +455,308 @@ return node; } -static DBusHandlerResult rfcomm_connect_req(DBusConnection *conn, - DBusMessage *msg, void *data) +static DBusHandlerResult rfcomm_get_ch_from_uuid_t(DBusConnection *conn, + DBusMessage *msg, + const char *dst, + uuid_t *uuid, + int *ch, + void *data) +{ + sdp_record_t *rec; + sdp_list_t *protos; + + rec = find_record_by_uuid (dst, uuid); + if (!rec) + return error_record_does_not_exist (conn, msg); + + if (sdp_get_access_protos(rec, &protos) == 0) + *ch = sdp_get_proto_port (protos, RFCOMM_UUID); + + if (*ch == -1) + return error_record_does_not_exist (conn, msg); + + return DBUS_HANDLER_RESULT_HANDLED; +} + +static DBusHandlerResult rfcomm_get_ch_from_handle(DBusConnection *conn, + DBusMessage *msg, + const char *dst, + int handle, + int *ch, + void *data) { - error("RFCOMM.Connect not implemented"); - return DBUS_HANDLER_RESULT_NOT_YET_HANDLED; + bdaddr_t bdaddr; + sdp_record_t *rec; + sdp_list_t *protos; + struct hci_dbus_data *dbus_data = data; + + hci_devba(dbus_data->dev_id, &bdaddr); + + rec = find_record_by_handle (dst, handle); + if (!rec) + return error_record_does_not_exist (conn, msg); + + if (sdp_get_access_protos(rec, &protos) == 0) + *ch = sdp_get_proto_port (protos, RFCOMM_UUID); + + if (*ch == -1) + return error_record_does_not_exist (conn, msg); + + return DBUS_HANDLER_RESULT_HANDLED; } -static DBusHandlerResult rfcomm_cancel_connect_req(DBusConnection *conn, - DBusMessage *msg, void *data) +static DBusHandlerResult rfcomm_connect_uuid_t(DBusConnection *conn, + DBusMessage *msg, + const char *dst, uuid_t *uuid, + void *data) { - error("RFCOMM.CancelConnect not implemented"); - return DBUS_HANDLER_RESULT_NOT_YET_HANDLED; + int ch = -1; + DBusHandlerResult ret; + struct hci_dbus_data *dbus_data = data; + bdaddr_t bdaddr; + int err; + + hci_devba(dbus_data->dev_id, &bdaddr); + + ret = rfcomm_get_ch_from_uuid_t(conn, msg, dst, uuid, &ch, data); + + if (ret != DBUS_HANDLER_RESULT_HANDLED) + return ret; + + if (find_pending_connect(dst, ch)) + return error_connect_in_progress(conn, msg); + + if (rfcomm_connect(conn, msg, &bdaddr, dst, NULL, ch, &err) < 0) + return error_failed(conn, msg, err); + + return DBUS_HANDLER_RESULT_HANDLED; +} + +static DBusHandlerResult rfcomm_cancel_connect_uuid_t(DBusConnection *conn, + DBusMessage *msg, + const char *dst, + uuid_t *uuid, + void *data) +{ + int ch = -1; + DBusHandlerResult ret; + DBusMessage *reply; + struct hci_dbus_data *dbus_data = data; + struct pending_connect *pending; + bdaddr_t bdaddr; + + hci_devba(dbus_data->dev_id, &bdaddr); + + ret = rfcomm_get_ch_from_uuid_t(conn, msg, dst, uuid, &ch, data); + + if (ret != DBUS_HANDLER_RESULT_HANDLED) + return ret; + + reply = dbus_message_new_method_return(msg); + if (!reply) + return DBUS_HANDLER_RESULT_NEED_MEMORY; + + pending = find_pending_connect(dst, ch); + if (!pending) + return error_connect_in_progress(conn, msg); + + pending->canceled = 1; + + return send_reply_and_unref(conn, reply); + + return DBUS_HANDLER_RESULT_HANDLED; +} + +static DBusHandlerResult rfcomm_connect_uuid_req(DBusConnection *conn, + DBusMessage *msg, void *data) +{ + uuid_t uuid; + const char *dst; + const char *string_uuid; + unsigned int data0, data4; + unsigned short data1, data2, data3, data5; + + if (!dbus_message_get_args(msg, NULL, + DBUS_TYPE_STRING, &dst, + DBUS_TYPE_STRING, &string_uuid, + DBUS_TYPE_INVALID)) + return error_invalid_arguments(conn, msg); + + sscanf (string_uuid, "%8x-%4hx-%4hx-%4hx-%8x%4hx", &data0, &data1, + &data2, &data3, &data4, &data5); + + data0 = htonl(data0); + data1 = htons(data1); + data2 = htons(data2); + data3 = htons(data3); + data4 = htonl(data4); + data5 = htons(data5); + + uuid.type = SDP_UUID128; + memcpy (&uuid.value.uuid128.data[0], &data0, 4); + memcpy (&uuid.value.uuid128.data[4], &data1, 2); + memcpy (&uuid.value.uuid128.data[6], &data2, 2); + memcpy (&uuid.value.uuid128.data[8], &data3, 2); + memcpy (&uuid.value.uuid128.data[10], &data4, 4); + memcpy (&uuid.value.uuid128.data[14], &data5, 2); + + return rfcomm_connect_uuid_t(conn, msg, dst, &uuid, data); +} + +static DBusHandlerResult rfcomm_cancel_connect_uuid_req(DBusConnection *conn, + DBusMessage *msg, + void *data) +{ + uuid_t uuid; + const char *dst; + const char *string_uuid; + unsigned int data0, data4; + unsigned short data1, data2, data3, data5; + + if (!dbus_message_get_args(msg, NULL, + DBUS_TYPE_STRING, &dst, + DBUS_TYPE_STRING, &string_uuid, + DBUS_TYPE_INVALID)) + return error_invalid_arguments(conn, msg); + + sscanf (string_uuid, "%8x-%4hx-%4hx-%4hx-%8x%4hx", &data0, &data1, + &data2, &data3, &data4, &data5); + + data0 = htonl(data0); + data1 = htons(data1); + data2 = htons(data2); + data3 = htons(data3); + data4 = htonl(data4); + data5 = htons(data5); + + uuid.type = SDP_UUID128; + memcpy (&uuid.value.uuid128.data[0], &data0, 4); + memcpy (&uuid.value.uuid128.data[4], &data1, 2); + memcpy (&uuid.value.uuid128.data[6], &data2, 2); + memcpy (&uuid.value.uuid128.data[8], &data3, 2); + memcpy (&uuid.value.uuid128.data[10], &data4, 4); + memcpy (&uuid.value.uuid128.data[14], &data5, 2); + + return rfcomm_cancel_connect_uuid_t(conn, msg, dst, &uuid, data); +} + +static DBusHandlerResult rfcomm_connect_service_req(DBusConnection *conn, + DBusMessage *msg, + void *data) +{ + char *dst; + char *service; + uuid_t short_uuid; + uuid_t *uuid; + + if (!dbus_message_get_args(msg, NULL, + DBUS_TYPE_STRING, &dst, + DBUS_TYPE_STRING, &service, + DBUS_TYPE_INVALID)) + return error_invalid_arguments(conn, msg); + + short_uuid.type = SDP_UUID16; + short_uuid.value.uuid16 = sdp_str2svclass (service); + + uuid = sdp_uuid_to_uuid128 (&short_uuid); + + return rfcomm_connect_uuid_t(conn, msg, dst, uuid, data); +} + +static DBusHandlerResult rfcomm_cancel_connect_service_req(DBusConnection *conn, + DBusMessage *msg, + void *data) +{ + char *dst; + char *service; + uuid_t short_uuid; + uuid_t *uuid; + + if (!dbus_message_get_args(msg, NULL, + DBUS_TYPE_STRING, &dst, + DBUS_TYPE_STRING, &service, + DBUS_TYPE_INVALID)) + return error_invalid_arguments(conn, msg); + + short_uuid.type = SDP_UUID16; + short_uuid.value.uuid16 = sdp_str2svclass (service); + + uuid = sdp_uuid_to_uuid128 (&short_uuid); + + return rfcomm_cancel_connect_uuid_t(conn, msg, dst, uuid, data); +} + +static DBusHandlerResult rfcomm_connect_handle_req (DBusConnection *conn, + DBusMessage *msg, + void *data) +{ + int ch = -1; + const char *dst; + DBusHandlerResult ret; + int handle; + struct hci_dbus_data *dbus_data = data; + bdaddr_t bdaddr; + int err; + + hci_devba(dbus_data->dev_id, &bdaddr); + + if (!dbus_message_get_args(msg, NULL, + DBUS_TYPE_STRING, &dst, + DBUS_TYPE_UINT32, &handle, + DBUS_TYPE_INVALID)) + return error_invalid_arguments(conn, msg); + + ret = rfcomm_get_ch_from_handle(conn, msg, dst, handle, &ch, data); + + if (ret != DBUS_HANDLER_RESULT_HANDLED) + return ret; + + if (find_pending_connect(dst, ch)) + return error_connect_in_progress(conn, msg); + + if (rfcomm_connect(conn, msg, &bdaddr, dst, NULL, ch, &err) < 0) + return error_failed(conn, msg, err); + + return DBUS_HANDLER_RESULT_HANDLED; +} + +static DBusHandlerResult rfcomm_cancel_connect_handle_req (DBusConnection *conn, + DBusMessage *msg, + void *data) +{ + int ch = -1; + const char *dst; + DBusHandlerResult ret; + DBusMessage *reply; + int handle; + struct hci_dbus_data *dbus_data = data; + bdaddr_t bdaddr; + struct pending_connect *pending; + + hci_devba(dbus_data->dev_id, &bdaddr); + + if (!dbus_message_get_args(msg, NULL, + DBUS_TYPE_STRING, &dst, + DBUS_TYPE_UINT32, &handle, + DBUS_TYPE_INVALID)) + return error_invalid_arguments(conn, msg); + + ret = rfcomm_get_ch_from_handle(conn, msg, dst, handle, &ch, data); + + if (ret != DBUS_HANDLER_RESULT_HANDLED) + return ret; + + reply = dbus_message_new_method_return(msg); + if (!reply) + return DBUS_HANDLER_RESULT_NEED_MEMORY; + + pending = find_pending_connect(dst, ch); + if (!pending) + return error_connect_in_progress(conn, msg); + + pending->canceled = 1; + + return send_reply_and_unref(conn, reply); } static DBusHandlerResult rfcomm_connect_by_ch_req(DBusConnection *conn, @@ -685,8 +978,12 @@ } static struct service_data rfcomm_services[] = { - { "Connect", rfcomm_connect_req, }, - { "CancelConnect", rfcomm_cancel_connect_req, }, + { "ConnectByUUID", rfcomm_connect_uuid_req, }, + { "ConnectByService", rfcomm_connect_service_req, }, + { "ConnectByHandle", rfcomm_connect_handle_req, }, + { "CancelConnectByUUID", rfcomm_cancel_connect_uuid_req, }, + { "CancelConnectByService", rfcomm_cancel_connect_service_req, }, + { "CancelConnectByHandle", rfcomm_cancel_connect_handle_req, }, { "ConnectByChannel", rfcomm_connect_by_ch_req, }, { "CancelConnectByChannel", rfcomm_cancel_connect_by_ch_req, }, { "Disconnect", rfcomm_disconnect_req, }, Index: dbus-sdp.c =================================================================== RCS file: /cvsroot/bluez/utils/hcid/dbus-sdp.c,v retrieving revision 1.9 diff -u -r1.9 dbus-sdp.c --- dbus-sdp.c 18 Aug 2006 18:29:40 -0000 1.9 +++ dbus-sdp.c 19 Aug 2006 14:34:33 -0000 @@ -855,6 +855,77 @@ } +static int sdp_uuid_comp_func(const void *key1, const void *key2) +{ + const uuid_t *a = (const uuid_t *)key1; + const uuid_t *b = (const uuid_t *)key2; + + if (a->type != b->type) + return 1; + + switch (a->type) { + case SDP_UUID16: + return !(a->value.uuid16 == b->value.uuid16); + break; + case SDP_UUID32: + return !(a->value.uuid32 == b->value.uuid32); + break; + case SDP_UUID128: + return !memcmp(&a->value.uuid128, &b->value.uuid128, + sizeof(uint128_t)); + break; + } + return 1; +} + +sdp_record_t *find_record_by_uuid(const char *address, uuid_t *uuid) +{ + struct slist *lp, *lr; + struct service_provider *p; + struct service_record *r; + sdp_list_t *list = 0; + + + for (lp = sdp_cache; lp; lp = lp->next) { + p = lp->data; + if (strcmp(p->prov, address)) + continue; + + for (lr = p->lrec; lr; lr = lr->next) { + r = lr->data; + /* Check whether the record has the correct uuid */ + if (sdp_get_service_classes(r->record, &list) !=0) + continue; + + if (sdp_list_find (list, &uuid, sdp_uuid_comp_func)) + return r->record; + } + } + + return NULL; +} + +sdp_record_t *find_record_by_handle(const char *address, int handle) +{ + struct slist *lp, *lr; + struct service_provider *p; + struct service_record *r; + + for (lp = sdp_cache; lp; lp = lp->next) { + p = lp->data; + if (strcmp(p->prov, address)) + continue; + + for (lr = p->lrec; lr; lr = lr->next) { + r = lr->data; + if (r->record->handle == handle) + return r->record; + } + } + + return NULL; +} + static sdp_record_t *find_record(const char *address, int id) { struct slist *lp, *lr; Index: dbus.h =================================================================== RCS file: /cvsroot/bluez/utils/hcid/dbus.h,v retrieving revision 1.98 diff -u -r1.98 dbus.h --- dbus.h 19 Aug 2006 00:30:46 -0000 1.98 +++ dbus.h 19 Aug 2006 14:34:33 -0000 @@ -214,4 +214,8 @@ int discoverable_timeout_handler(void *data); +sdp_record_t *find_record_by_uuid(const char *address, uuid_t *uuid); +sdp_record_t *find_record_by_handle(const char *address, int handle); +uint16_t sdp_str2svclass(const char *str); + #endif /* __H_BLUEZ_DBUS_H__ */ -- Matthew Garrett | mjg59@srcf.ucam.org ------------------------------------------------------------------------- Using Tomcat but need to do more? Need to support web services, security? Get stuff done quickly with pre-integrated technology to make your job easier Download IBM WebSphere Application Server v.1.0.1 based on Apache Geronimo http://sel.as-us.falkag.net/sel?cmd=lnk&kid=120709&bid=263057&dat=121642 _______________________________________________ Bluez-devel mailing list Bluez-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/bluez-devel ^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: [Bluez-devel] [PATCH] implement RFCOMM Connect and Disconnect methods 2006-08-19 14:36 ` Matthew Garrett @ 2006-08-20 1:39 ` Marcel Holtmann 2006-08-19 23:53 ` Matthew Garrett 0 siblings, 1 reply; 14+ messages in thread From: Marcel Holtmann @ 2006-08-20 1:39 UTC (permalink / raw) To: BlueZ development Hi Matthew, > Right. How about this (not heavily tested, more proof of concept) - it > removes the unimplemented Connect and CancelConnect methods, and > replaces them with ConnectByUUID, ConnectByService and ConnectByHandle > methods with the appropriate CancelConnect methods. thanks for the patch, but what is the problem with sticking to Connect and CancelConnect and use their service string to identify UUID, handle or service name bases connections. Remember that the goal of the D-Bus based API is to make it easy for the applications. So they can give us whatever they have and we then request the right information from the remote device and then connect to the right RFCOMM channel. Regards Marcel ------------------------------------------------------------------------- Using Tomcat but need to do more? Need to support web services, security? Get stuff done quickly with pre-integrated technology to make your job easier Download IBM WebSphere Application Server v.1.0.1 based on Apache Geronimo http://sel.as-us.falkag.net/sel?cmd=lnk&kid=120709&bid=263057&dat=121642 _______________________________________________ Bluez-devel mailing list Bluez-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/bluez-devel ^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: [Bluez-devel] [PATCH] implement RFCOMM Connect and Disconnect methods 2006-08-20 1:39 ` Marcel Holtmann @ 2006-08-19 23:53 ` Matthew Garrett 2006-08-20 2:13 ` Marcel Holtmann 0 siblings, 1 reply; 14+ messages in thread From: Matthew Garrett @ 2006-08-19 23:53 UTC (permalink / raw) To: BlueZ development On Sun, Aug 20, 2006 at 03:39:33AM +0200, Marcel Holtmann wrote: > thanks for the patch, but what is the problem with sticking to Connect > and CancelConnect and use their service string to identify UUID, handle > or service name bases connections. I'm not quite clear on what you mean here. The service string seems unacceptable because it requires bluez to have a table of every possible service and UUID in existence. Or are we talking about different things? Right now, the API gives us the following things that potentially identify an object: 1) The identifiers returned by GetIdentifiers (currently an arbitrary but unique integer, despite dbus-api.txt claiming it returns strings) 2) The UUID 3) The service handle 4) The ascii service string My implementation provides connect methods for (2), (3) and (4). You didn't seem too happy about my patch providing support for (1), so I've dropped it :) Or do you just mean that there should be a single method and it should work out which piece of information has been passed by the app? In that case, I didn't implement it that way because determining the type was a bit of a pain and struck me as potentially fragile. -- Matthew Garrett | mjg59@srcf.ucam.org ------------------------------------------------------------------------- Using Tomcat but need to do more? Need to support web services, security? Get stuff done quickly with pre-integrated technology to make your job easier Download IBM WebSphere Application Server v.1.0.1 based on Apache Geronimo http://sel.as-us.falkag.net/sel?cmd=lnk&kid=120709&bid=263057&dat=121642 _______________________________________________ Bluez-devel mailing list Bluez-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/bluez-devel ^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: [Bluez-devel] [PATCH] implement RFCOMM Connect and Disconnect methods 2006-08-19 23:53 ` Matthew Garrett @ 2006-08-20 2:13 ` Marcel Holtmann 2006-08-20 0:31 ` Matthew Garrett 0 siblings, 1 reply; 14+ messages in thread From: Marcel Holtmann @ 2006-08-20 2:13 UTC (permalink / raw) To: BlueZ development Hi Matthew, > > thanks for the patch, but what is the problem with sticking to Connect > > and CancelConnect and use their service string to identify UUID, handle > > or service name bases connections. > > I'm not quite clear on what you mean here. The service string seems > unacceptable because it requires bluez to have a table of every possible > service and UUID in existence. Or are we talking about different things? > Right now, the API gives us the following things that potentially > identify an object: > > 1) The identifiers returned by GetIdentifiers (currently an arbitrary > but unique integer, despite dbus-api.txt claiming it returns strings) > 2) The UUID > 3) The service handle > 4) The ascii service string > > My implementation provides connect methods for (2), (3) and (4). You > didn't seem too happy about my patch providing support for (1), so I've > dropped it :) Or do you just mean that there should be a single method > and it should work out which piece of information has been passed by the > app? In that case, I didn't implement it that way because determining > the type was a bit of a pain and struck me as potentially fragile. I meant exactly that. The method should work out what information got passed to it. Of course this might not be easy to implement, but that is not the point behind this API. The whole API is designed to make it easy for all kind of applications. And the main focus is not the C language. We have been through a lot of trouble and parts of hcid look really horrible, but for the end user (the application) the interface is easy to use. I also don't see the problem here. The ASCII service string are a predefined list of names that actually match to specific UUID. Since in the end we will implement all needed service names for all known profiles, we only need to support UUID128. These have a unique form and are kinda easy to detect. If the provided UUID128 matches the Bluetooth base string, then we can internally use UUID32 or UUID16. As simple as that. For the record handles we give them in hex and so they are also easy to identify. And I would check the string in this order. And as said, this might require a little bit more code in hcid, but that is the price to pay if we wanna have a simple API for the application and I am paying it gladly. Regards Marcel ------------------------------------------------------------------------- Using Tomcat but need to do more? Need to support web services, security? Get stuff done quickly with pre-integrated technology to make your job easier Download IBM WebSphere Application Server v.1.0.1 based on Apache Geronimo http://sel.as-us.falkag.net/sel?cmd=lnk&kid=120709&bid=263057&dat=121642 _______________________________________________ Bluez-devel mailing list Bluez-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/bluez-devel ^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: [Bluez-devel] [PATCH] implement RFCOMM Connect and Disconnect methods 2006-08-20 2:13 ` Marcel Holtmann @ 2006-08-20 0:31 ` Matthew Garrett 2006-08-20 3:15 ` Marcel Holtmann 0 siblings, 1 reply; 14+ messages in thread From: Matthew Garrett @ 2006-08-20 0:31 UTC (permalink / raw) To: BlueZ development On Sun, Aug 20, 2006 at 04:13:48AM +0200, Marcel Holtmann wrote: > I meant exactly that. The method should work out what information got > passed to it. Of course this might not be easy to implement, but that is > not the point behind this API. The whole API is designed to make it easy > for all kind of applications. And the main focus is not the C language. Ok, cool. Now I know what to aim for, I'll head back to that :) > I also don't see the problem here. The ASCII service string are a > predefined list of names that actually match to specific UUID. Since in > the end we will implement all needed service names for all known > profiles, we only need to support UUID128. These have a unique form and > are kinda easy to detect. If the provided UUID128 matches the Bluetooth > base string, then we can internally use UUID32 or UUID16. As simple as > that. For the record handles we give them in hex and so they are also > easy to identify. And I would check the string in this order. Ok, makes sense. > And as said, this might require a little bit more code in hcid, but that > is the price to pay if we wanna have a simple API for the application > and I am paying it gladly. Sure. I'll send a new patch tomorrow. -- Matthew Garrett | mjg59@srcf.ucam.org ------------------------------------------------------------------------- Using Tomcat but need to do more? Need to support web services, security? Get stuff done quickly with pre-integrated technology to make your job easier Download IBM WebSphere Application Server v.1.0.1 based on Apache Geronimo http://sel.as-us.falkag.net/sel?cmd=lnk&kid=120709&bid=263057&dat=121642 _______________________________________________ Bluez-devel mailing list Bluez-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/bluez-devel ^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: [Bluez-devel] [PATCH] implement RFCOMM Connect and Disconnect methods 2006-08-20 0:31 ` Matthew Garrett @ 2006-08-20 3:15 ` Marcel Holtmann 2006-08-20 17:59 ` Matthew Garrett 0 siblings, 1 reply; 14+ messages in thread From: Marcel Holtmann @ 2006-08-20 3:15 UTC (permalink / raw) To: BlueZ development Hi Matthew, > > I meant exactly that. The method should work out what information got > > passed to it. Of course this might not be easy to implement, but that is > > not the point behind this API. The whole API is designed to make it easy > > for all kind of applications. And the main focus is not the C language. > > Ok, cool. Now I know what to aim for, I'll head back to that :) I think a lot of people missed the discussions behind the API since we did them basically behind closed doors. The main focus will always be the client application. You really have to think the other way around. > > I also don't see the problem here. The ASCII service string are a > > predefined list of names that actually match to specific UUID. Since in > > the end we will implement all needed service names for all known > > profiles, we only need to support UUID128. These have a unique form and > > are kinda easy to detect. If the provided UUID128 matches the Bluetooth > > base string, then we can internally use UUID32 or UUID16. As simple as > > that. For the record handles we give them in hex and so they are also > > easy to identify. And I would check the string in this order. > > Ok, makes sense. And the weird indentifiers are free formed strings that doesn't match any of the other categories. And since the server will hand them out it is an easy requirement to fulfill. These are also not meant to have any meaning. In general they can be random garbage. The server knows what to do with them. You will also see that we love using strings, because in languages like Python they are so easy to handle. If it is not an integer by definition we might go with a string as type, because it is more flexible. Regards Marcel ------------------------------------------------------------------------- Using Tomcat but need to do more? Need to support web services, security? Get stuff done quickly with pre-integrated technology to make your job easier Download IBM WebSphere Application Server v.1.0.1 based on Apache Geronimo http://sel.as-us.falkag.net/sel?cmd=lnk&kid=120709&bid=263057&dat=121642 _______________________________________________ Bluez-devel mailing list Bluez-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/bluez-devel ^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: [Bluez-devel] [PATCH] implement RFCOMM Connect and Disconnect methods 2006-08-20 3:15 ` Marcel Holtmann @ 2006-08-20 17:59 ` Matthew Garrett 2006-08-23 6:21 ` [Bluez-devel] RFComm auth/encrypt Denis KENZIOR 2006-08-23 20:13 ` [Bluez-devel] [PATCH] implement RFCOMM Connect and Disconnect methods Johan Hedberg 0 siblings, 2 replies; 14+ messages in thread From: Matthew Garrett @ 2006-08-20 17:59 UTC (permalink / raw) To: BlueZ development Ok, how's this? Again not heavily tested, but just to make sure that the style is right. Index: dbus-api.txt =================================================================== RCS file: /cvsroot/bluez/utils/hcid/dbus-api.txt,v retrieving revision 1.41 diff -u -r1.41 dbus-api.txt --- dbus-api.txt 18 Aug 2006 19:50:27 -0000 1.41 +++ dbus-api.txt 20 Aug 2006 17:58:03 -0000 @@ -904,8 +904,8 @@ Methods string Connect(string address, string service) This creates a connection to a remote RFCOMM based - service. The service string can either be a UUID-16, - a UUID-32, a UUID-128 or a service abbreviation. + service. The service string can either be a UUID-128, + a service abbreviation or a record handle. The return value will be the path of the newly created RFCOMM TTY device (for example /dev/rfcomm0). Index: dbus-rfcomm.c =================================================================== RCS file: /cvsroot/bluez/utils/hcid/dbus-rfcomm.c,v retrieving revision 1.10 diff -u -r1.10 dbus-rfcomm.c --- dbus-rfcomm.c 18 Aug 2006 18:29:40 -0000 1.10 +++ dbus-rfcomm.c 20 Aug 2006 17:58:06 -0000 @@ -33,11 +33,15 @@ #include <fcntl.h> #include <sys/ioctl.h> #include <sys/socket.h> +#include <arpa/inet.h> #include <bluetooth/bluetooth.h> #include <bluetooth/rfcomm.h> #include <bluetooth/hci.h> #include <bluetooth/hci_lib.h> +#include <bluetooth/sdp.h> +#include <bluetooth/sdp_lib.h> + #include <dbus/dbus.h> @@ -452,18 +456,132 @@ return node; } +static sdp_record_t *get_record_from_string (const char *dst, + const char *string) +{ + uuid_t short_uuid; + uuid_t *uuid; + sdp_record_t *rec = NULL; + unsigned int data0, data4; + unsigned short data1, data2, data3, data5; + long handle; + + /* Check if the string is a service name */ + short_uuid.value.uuid16 = sdp_str2svclass (string); + + if (short_uuid.value.uuid16) { + short_uuid.type = SDP_UUID16; + uuid = sdp_uuid_to_uuid128 (&short_uuid); + rec = find_record_by_uuid (dst, uuid); + } else if (sscanf (string, "%8x-%4hx-%4hx-%4hx-%8x%4hx", &data0, + &data1, &data2, &data3, &data4, &data5) == 6) { + data0 = htonl(data0); + data1 = htons(data1); + data2 = htons(data2); + data3 = htons(data3); + data4 = htonl(data4); + data5 = htons(data5); + + uuid = malloc (sizeof(uuid_t)); + uuid->type = SDP_UUID128; + memcpy (&uuid->value.uuid128.data[0], &data0, 4); + memcpy (&uuid->value.uuid128.data[4], &data1, 2); + memcpy (&uuid->value.uuid128.data[6], &data2, 2); + memcpy (&uuid->value.uuid128.data[8], &data3, 2); + memcpy (&uuid->value.uuid128.data[10], &data4, 4); + memcpy (&uuid->value.uuid128.data[14], &data5, 2); + + rec = find_record_by_uuid (dst, uuid); + } else if ((handle = strtol (string, (char **)NULL, 0))) { + rec = find_record_by_handle (dst, handle); + } + + return rec; +} + static DBusHandlerResult rfcomm_connect_req(DBusConnection *conn, DBusMessage *msg, void *data) { - error("RFCOMM.Connect not implemented"); - return DBUS_HANDLER_RESULT_NOT_YET_HANDLED; + int ch = -1; + const char *dst; + const char *string; + sdp_record_t *rec; + sdp_list_t *protos; + bdaddr_t bdaddr; + struct hci_dbus_data *dbus_data = data; + int err; + + if (!dbus_message_get_args(msg, NULL, + DBUS_TYPE_STRING, &dst, + DBUS_TYPE_STRING, &string, + DBUS_TYPE_INVALID)) + return error_invalid_arguments(conn, msg); + + hci_devba(dbus_data->dev_id, &bdaddr); + + rec = get_record_from_string (dst, string); + + if (!rec) + return error_record_does_not_exist (conn, msg); + + if (sdp_get_access_protos(rec, &protos) == 0) + ch = sdp_get_proto_port (protos, RFCOMM_UUID); + + if (ch == -1) + return error_record_does_not_exist (conn, msg); + + if (find_pending_connect(dst, ch)) + return error_connect_in_progress(conn, msg); + + if (rfcomm_connect(conn, msg, &bdaddr, dst, NULL, ch, &err) < 0) + return error_failed(conn, msg, err); + + return DBUS_HANDLER_RESULT_HANDLED; } static DBusHandlerResult rfcomm_cancel_connect_req(DBusConnection *conn, DBusMessage *msg, void *data) { - error("RFCOMM.CancelConnect not implemented"); - return DBUS_HANDLER_RESULT_NOT_YET_HANDLED; + int ch = -1; + const char *dst; + const char *string; + sdp_record_t *rec; + sdp_list_t *protos; + bdaddr_t bdaddr; + struct hci_dbus_data *dbus_data = data; + DBusMessage *reply; + struct pending_connect *pending; + + if (!dbus_message_get_args(msg, NULL, + DBUS_TYPE_STRING, &dst, + DBUS_TYPE_STRING, &string, + DBUS_TYPE_INVALID)) + return error_invalid_arguments(conn, msg); + + hci_devba(dbus_data->dev_id, &bdaddr); + + rec = get_record_from_string (dst, string); + + if (!rec) + return error_record_does_not_exist (conn, msg); + + if (sdp_get_access_protos(rec, &protos) == 0) + ch = sdp_get_proto_port (protos, RFCOMM_UUID); + + if (ch == -1) + return error_record_does_not_exist (conn, msg); + + reply = dbus_message_new_method_return (msg); + if (!reply) + return DBUS_HANDLER_RESULT_NEED_MEMORY; + + pending = find_pending_connect(dst, ch); + if (!pending) + return error_connect_in_progress(conn, msg); + + pending->canceled = 1; + + return send_reply_and_unref(conn, reply); } static DBusHandlerResult rfcomm_connect_by_ch_req(DBusConnection *conn, Index: dbus-sdp.c =================================================================== RCS file: /cvsroot/bluez/utils/hcid/dbus-sdp.c,v retrieving revision 1.9 diff -u -r1.9 dbus-sdp.c --- dbus-sdp.c 18 Aug 2006 18:29:40 -0000 1.9 +++ dbus-sdp.c 20 Aug 2006 17:58:11 -0000 @@ -855,6 +855,77 @@ } +static int sdp_uuid_comp_func(const void *key1, const void *key2) +{ + const uuid_t *a = (const uuid_t *)key1; + const uuid_t *b = (const uuid_t *)key2; + + if (a->type != b->type) + return 1; + + switch (a->type) { + case SDP_UUID16: + return !(a->value.uuid16 == b->value.uuid16); + break; + case SDP_UUID32: + return !(a->value.uuid32 == b->value.uuid32); + break; + case SDP_UUID128: + return !memcmp(&a->value.uuid128, &b->value.uuid128, + sizeof(uint128_t)); + break; + } + return 1; +} + +sdp_record_t *find_record_by_uuid(const char *address, uuid_t *uuid) +{ + struct slist *lp, *lr; + struct service_provider *p; + struct service_record *r; + sdp_list_t *list = 0; + + + for (lp = sdp_cache; lp; lp = lp->next) { + p = lp->data; + if (strcmp(p->prov, address)) + continue; + + for (lr = p->lrec; lr; lr = lr->next) { + r = lr->data; + /* Check whether the record has the correct uuid */ + if (sdp_get_service_classes(r->record, &list) !=0) + continue; + + if (sdp_list_find (list, &uuid, sdp_uuid_comp_func)) + return r->record; + } + } + + return NULL; +} + +sdp_record_t *find_record_by_handle(const char *address, int handle) +{ + struct slist *lp, *lr; + struct service_provider *p; + struct service_record *r; + + for (lp = sdp_cache; lp; lp = lp->next) { + p = lp->data; + if (strcmp(p->prov, address)) + continue; + + for (lr = p->lrec; lr; lr = lr->next) { + r = lr->data; + if (r->record->handle == handle) + return r->record; + } + } + + return NULL; +} + static sdp_record_t *find_record(const char *address, int id) { struct slist *lp, *lr; Index: dbus.h =================================================================== RCS file: /cvsroot/bluez/utils/hcid/dbus.h,v retrieving revision 1.98 diff -u -r1.98 dbus.h --- dbus.h 19 Aug 2006 00:30:46 -0000 1.98 +++ dbus.h 20 Aug 2006 17:58:12 -0000 @@ -214,4 +214,8 @@ int discoverable_timeout_handler(void *data); +sdp_record_t *find_record_by_uuid(const char *address, uuid_t *uuid); +sdp_record_t *find_record_by_handle(const char *address, int handle); +uint16_t sdp_str2svclass(const char *str); + #endif /* __H_BLUEZ_DBUS_H__ */ -- Matthew Garrett | mjg59@srcf.ucam.org ------------------------------------------------------------------------- Using Tomcat but need to do more? Need to support web services, security? Get stuff done quickly with pre-integrated technology to make your job easier Download IBM WebSphere Application Server v.1.0.1 based on Apache Geronimo http://sel.as-us.falkag.net/sel?cmd=lnk&kid=120709&bid=263057&dat=121642 _______________________________________________ Bluez-devel mailing list Bluez-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/bluez-devel ^ permalink raw reply [flat|nested] 14+ messages in thread
* [Bluez-devel] RFComm auth/encrypt 2006-08-20 17:59 ` Matthew Garrett @ 2006-08-23 6:21 ` Denis KENZIOR 2006-08-23 20:13 ` [Bluez-devel] [PATCH] implement RFCOMM Connect and Disconnect methods Johan Hedberg 1 sibling, 0 replies; 14+ messages in thread From: Denis KENZIOR @ 2006-08-23 6:21 UTC (permalink / raw) To: bluez-devel Marcel, I'm trying to use the OpenOBEX bluetooth functions, but want to control the service level security options. Since OpenOBEX does a listen for me, I can't set the security options before a listen occurs. So my question is: On a rfcomm server socket, when is the right time to set the link_mode flags? E.g. do I have to set it before the listen call? Or setting them at any point after the listen is OK (and actually works) as well? E.g. Here's what I'm trying to do: BtOBEX_ServerRegister(self, &bdaddr, channel); setsockopt(OBEX_GetFD(self), SOL_RFCOMM, RFCOMM_LM, &lm, sizeof(lm)); And on the client side, it seems that the client can request security options to be set as well. Again, when is the right time to do this? After the socket call but before the connect? Can authentication be requested after the client socket is connected? -Denis ------------------------------------------------------------------------- Using Tomcat but need to do more? Need to support web services, security? Get stuff done quickly with pre-integrated technology to make your job easier Download IBM WebSphere Application Server v.1.0.1 based on Apache Geronimo http://sel.as-us.falkag.net/sel?cmd=lnk&kid=120709&bid=263057&dat=121642 _______________________________________________ Bluez-devel mailing list Bluez-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/bluez-devel ^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: [Bluez-devel] [PATCH] implement RFCOMM Connect and Disconnect methods 2006-08-20 17:59 ` Matthew Garrett 2006-08-23 6:21 ` [Bluez-devel] RFComm auth/encrypt Denis KENZIOR @ 2006-08-23 20:13 ` Johan Hedberg 1 sibling, 0 replies; 14+ messages in thread From: Johan Hedberg @ 2006-08-23 20:13 UTC (permalink / raw) To: BlueZ development Hi Matthew, On Sun, Aug 20, 2006, Matthew Garrett wrote: > Ok, how's this? Again not heavily tested, but just to make sure that the > style is right. The patch is now commited to the CVS along with some coding style changes and a few other fixes. It's a good start, but one major thing missing is that the Connect method should initiate an SDP query to the remote device if necessary (if the record isn't found in the local cache) to find out the correct channel to connect to. Johan ------------------------------------------------------------------------- Using Tomcat but need to do more? Need to support web services, security? Get stuff done quickly with pre-integrated technology to make your job easier Download IBM WebSphere Application Server v.1.0.1 based on Apache Geronimo http://sel.as-us.falkag.net/sel?cmd=lnk&kid=120709&bid=263057&dat=121642 _______________________________________________ Bluez-devel mailing list Bluez-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/bluez-devel ^ permalink raw reply [flat|nested] 14+ messages in thread
end of thread, other threads:[~2006-08-23 20:13 UTC | newest] Thread overview: 14+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2006-08-17 10:06 [Bluez-devel] [PATCH] implement RFCOMM Connect and Disconnect methods Matthew Garrett 2006-08-17 13:04 ` Marcel Holtmann 2006-08-17 11:41 ` Matthew Garrett 2006-08-17 11:59 ` Johan Hedberg 2006-08-17 12:01 ` Matthew Garrett 2006-08-19 14:36 ` Matthew Garrett 2006-08-20 1:39 ` Marcel Holtmann 2006-08-19 23:53 ` Matthew Garrett 2006-08-20 2:13 ` Marcel Holtmann 2006-08-20 0:31 ` Matthew Garrett 2006-08-20 3:15 ` Marcel Holtmann 2006-08-20 17:59 ` Matthew Garrett 2006-08-23 6:21 ` [Bluez-devel] RFComm auth/encrypt Denis KENZIOR 2006-08-23 20:13 ` [Bluez-devel] [PATCH] implement RFCOMM Connect and Disconnect methods Johan Hedberg
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox