Skip site navigation (1)Skip section navigation (2)
Date:      Mon, 10 Mar 2008 21:06:11 -0200
From:      Rako <rako29@gmail.com>
To:        freebsd-bluetooth@freebsd.org, maksim.yevmenkin@gmail.com
Subject:   Bluetooth PAN support for FreeBSD
Message-ID:  <47D5BEE3.80109@gmail.com>
References:  15413101.post@talk.nabble.com

next in thread | raw e-mail | index | archive | help
This is a multi-part message in MIME format.
--------------050706010301070608000808
Content-Type: text/plain; charset=ISO-8859-1; format=flowed
Content-Transfer-Encoding: 7bit

Hi, I write the code to teach sdpd and libsdp about pan profiles. Also 
write the registration of NAP service on btpand daemon.

Tested with sony ericsson w850i.

Thanks Maksim for the btpand work!
Rako


--------------050706010301070608000808
Content-Type: text/plain;
 name="sdpd.patch"
Content-Transfer-Encoding: 7bit
Content-Disposition: inline;
 filename="sdpd.patch"

diff -Nua sdpd.orig/Makefile sdpd/Makefile
--- sdpd.orig/Makefile	2005-01-05 15:37:37.000000000 -0300
+++ sdpd/Makefile	2008-03-10 20:11:59.000000000 -0300
@@ -4,7 +4,7 @@
 PROG=		sdpd
 MAN=		sdpd.8
 SRCS=		bgd.c dun.c ftrn.c irmc.c irmc_command.c lan.c log.c main.c \
-		opush.c profile.c provider.c sar.c scr.c sd.c server.c sp.c \
+		opush.c profile.c provider.c sar.c scr.c sd.c server.c sp.c pan.c \
 		srr.c ssar.c ssr.c sur.c uuid.c
 
 CFLAGS+=	-I${.CURDIR}
diff -Nua sdpd.orig/pan.c sdpd/pan.c
--- sdpd.orig/pan.c	1969-12-31 21:00:00.000000000 -0300
+++ sdpd/pan.c	2008-03-10 20:11:59.000000000 -0300
@@ -0,0 +1,209 @@
+/*
+ * pan.c
+ *
+ */
+
+#include <arpa/inet.h>
+#include <sys/queue.h>
+#include <bluetooth.h>
+#include <sdp.h>
+#include <stdio.h>
+#include <string.h>
+#include "profile.h"
+#include "provider.h"
+
+static int32_t
+pan_profile_create_service_class_id_list(
+		uint8_t *buf, uint8_t const * const eob,
+		uint8_t const *data, uint32_t datalen)
+{
+	provider_p		provider = (provider_p) data;
+	sdp_pan_profile_p 	 pan = (sdp_pan_profile_p) provider->data;
+	
+	return (common_profile_create_service_class_id_list(
+			buf, eob,
+			(uint8_t const *)&pan->service,
+			sizeof(pan->security)));
+}
+
+/*
+ * seq8 len8			- 2 bytes
+ *	seq 8 len8		    - 2 bytes
+ *		uuid16 value16	- 3 bytes
+ *		uint16 value16	- 3 bytes
+ */
+static int32_t
+pan_profile_create_bluetooth_profile_descriptor_list(
+		uint8_t *buf, uint8_t const * const eob,
+		uint8_t const *data, uint32_t datalen)
+{
+	provider_p		provider = (provider_p) data;
+	sdp_pan_profile_p 	 pan = (sdp_pan_profile_p) provider->data;
+	
+	SDP_PUT8(SDP_DATA_SEQ8, buf);
+	SDP_PUT8(8, buf);
+
+	SDP_PUT8(SDP_DATA_SEQ8, buf);
+	SDP_PUT8(6, buf);
+	SDP_PUT8(SDP_DATA_UUID16, buf);
+	SDP_PUT16(pan->service, buf);
+	SDP_PUT8(SDP_DATA_UINT16, buf);
+	SDP_PUT16(0x100, buf);
+	
+	return 10;
+}
+
+static int32_t
+pan_profile_create_service_name(
+		uint8_t *buf, uint8_t const * const eob,
+		uint8_t const *data, uint32_t datalen)
+{
+	static char	service_name[] = "NAP";
+
+	return (common_profile_create_string8(
+			buf, eob,
+			(uint8_t const *) service_name, strlen(service_name)));
+}
+
+/*
+ * seq8 len8			- 2 bytes
+ *	seq8 len8		    - 2 bytes
+ *		uuid16 value16	- 3 bytes
+ *      uint16 value16  - 3 bytes
+ *	seq8 len8		    - 2 bytes
+ *		uuid16 value16	- 3 bytes
+ *      uint16 value16  - 3 bytes
+ *		seq16 len16   	- 3 bytes
+ *       uint16 value16 - 3 bytes
+ *       uint16 value16 - 3 bytes
+ */
+static int32_t
+pan_profile_create_protocol_descriptor_list(
+		uint8_t *buf, uint8_t const * const eob,
+		uint8_t const *data, uint32_t datalen)
+{
+	provider_p		provider = (provider_p) data;
+	sdp_pan_profile_p 	 nap = (sdp_pan_profile_p) provider->data;
+
+	SDP_PUT8(SDP_DATA_SEQ8, buf);
+#ifndef INET6	
+	SDP_PUT8(25, buf);
+#else
+	SDP_PUT8(28, buf);	
+#endif
+
+	SDP_PUT8(SDP_DATA_SEQ8, buf);
+	SDP_PUT8(6, buf);
+	SDP_PUT8(SDP_DATA_UUID16, buf);
+	SDP_PUT16(SDP_UUID_PROTOCOL_L2CAP, buf);
+	SDP_PUT8(SDP_DATA_UINT16, buf);
+	SDP_PUT16(nap->psm, buf);
+
+	SDP_PUT8(SDP_DATA_SEQ8, buf);
+	SDP_PUT8(15, buf);
+	SDP_PUT8(SDP_DATA_UUID16, buf);
+	SDP_PUT16(SDP_UUID_PROTOCOL_BNEP, buf);
+	SDP_PUT8(SDP_DATA_UINT16, buf);
+	SDP_PUT16(0x0100, buf);
+	SDP_PUT8(SDP_DATA_SEQ16, buf);
+#ifndef INET6
+	SDP_PUT16(6,buf);
+#else
+	SDP_PUT16(9,buf);	
+#endif
+	SDP_PUT8(SDP_DATA_UINT16, buf);
+	SDP_PUT16(0x0800, buf);
+	SDP_PUT8(SDP_DATA_UINT16, buf);
+	SDP_PUT16(0x0806, buf);
+#ifdef INET6
+	SDP_PUT8(SDP_DATA_UINT16, buf);
+	SDP_PUT16(0x86dd, buf);	
+#endif
+
+#ifndef INET6
+	return (27);
+#else
+	return (29);
+#endif
+}
+
+/* 
+ *   uint16 value16  - 3 bytes
+ */
+static int32_t
+pan_profile_create_security_description(
+	uint8_t *buf, uint8_t const * const eob,
+	uint8_t const *data, uint32_t datalen)
+{
+	provider_p		provider = (provider_p) data;
+	sdp_pan_profile_p 	 nap = (sdp_pan_profile_p) provider->data;
+	
+	SDP_PUT8(SDP_DATA_UINT16, buf);
+	SDP_PUT16(nap->security, buf);
+	return (3);
+}
+
+/* 
+ *   uint16 value16  - 3 bytes
+ */
+static int32_t
+pan_profile_create_net_access_type(
+	uint8_t *buf, uint8_t const * const eob,
+	uint8_t const *data, uint32_t datalen)
+{
+	provider_p		provider = (provider_p) data;
+	sdp_pan_profile_p 	 pan = (sdp_pan_profile_p) provider->data;
+	
+	SDP_PUT8(SDP_DATA_UINT16, buf);	
+	SDP_PUT16(pan->net, buf);
+	return (3);
+}
+
+/* 
+ *   uint32 value32  - 5 bytes
+ */
+static int32_t
+pan_profile_create_max_net_access_rate(
+	uint8_t *buf, uint8_t const * const eob,
+	uint8_t const *data, uint32_t datalen)
+{
+	provider_p		provider = (provider_p) data;
+	sdp_pan_profile_p 	 pan = (sdp_pan_profile_p) provider->data;
+	
+	SDP_PUT8(SDP_DATA_UINT32, buf);	
+	SDP_PUT32(pan->rate, buf);
+	return (5);
+}
+
+
+static attr_t	pan_profile_attrs[] = {
+	{ SDP_ATTR_SERVICE_RECORD_HANDLE,
+	  common_profile_create_service_record_handle },
+	{ SDP_ATTR_SERVICE_CLASS_ID_LIST,
+	  pan_profile_create_service_class_id_list },
+	{ SDP_ATTR_PROTOCOL_DESCRIPTOR_LIST,
+	  pan_profile_create_protocol_descriptor_list },
+	{ SDP_ATTR_LANGUAGE_BASE_ATTRIBUTE_ID_LIST,
+	  common_profile_create_language_base_attribute_id_list },
+	{ SDP_ATTR_PRIMARY_LANGUAGE_BASE_ID + SDP_ATTR_SERVICE_NAME_OFFSET, 
+	  pan_profile_create_service_name },
+	{ SDP_ATTR_PRIMARY_LANGUAGE_BASE_ID + SDP_ATTR_SERVICE_DESCRIPTION_OFFSET, 
+	  pan_profile_create_service_name },
+	{ SDP_ATTR_BLUETOOTH_PROFILE_DESCRIPTOR_LIST,
+	  pan_profile_create_bluetooth_profile_descriptor_list },
+	{ SDP_ATTR_SECURITY_DESCRIPTION,
+	  pan_profile_create_security_description },
+	{ SDP_ATTR_NET_ACCESS_TYPE,
+	  pan_profile_create_net_access_type },
+	{ SDP_ATTR_MAX_NET_ACCESS_RATE,
+	  pan_profile_create_max_net_access_rate },		
+	{ 0, NULL } /* end entry */
+};
+
+profile_t	pan_profile_descriptor = {
+	SDP_SERVICE_CLASS_NAP,
+	sizeof(sdp_pan_profile_t),
+	common_profile_server_channel_valid,
+	(attr_t const * const) &pan_profile_attrs
+};
+
diff -Nua sdpd.orig/profile.c sdpd/profile.c
--- sdpd.orig/profile.c	2004-07-28 04:15:44.000000000 -0300
+++ sdpd/profile.c	2008-03-10 20:11:59.000000000 -0300
@@ -50,6 +50,7 @@
 	extern	profile_t	lan_profile_descriptor;
 	extern	profile_t	opush_profile_descriptor;
 	extern	profile_t	sp_profile_descriptor;
+	extern	profile_t	pan_profile_descriptor;
 
 	static const profile_p	profiles[] = {
 		&dun_profile_descriptor,
@@ -58,7 +59,8 @@
 		&irmc_command_profile_descriptor,
 		&lan_profile_descriptor,
 		&opush_profile_descriptor,
-		&sp_profile_descriptor
+		&sp_profile_descriptor,
+		&pan_profile_descriptor
 	};
 
 	int32_t			i;

--------------050706010301070608000808
Content-Type: text/plain;
 name="main.patch"
Content-Transfer-Encoding: 7bit
Content-Disposition: inline;
 filename="main.patch"

--- main.c.orig	2008-03-10 19:30:26.000000000 -0300
+++ main.c	2008-03-10 20:01:10.000000000 -0300
@@ -39,6 +39,8 @@
 #include <syslog.h>
 #include <sys/param.h>
 #include <unistd.h>
+#include <bluetooth.h>
+#include <sdp.h>
 #include "btpand.h"
 
 
@@ -64,14 +66,45 @@
       if( !serv->detached )
 	fprintf(stderr,"[%d] %s\n",level,msg);
       free(msg);
-    }
+    }	
   }
 }
 
+/* SDP registration */
+static void sdp_register( int psm ) {
+	void             *xss;
+	bdaddr_t          bt_addr_any;
+	sdp_pan_profile_t pan;
+
+	xss = sdp_open_local(NULL);
+	if (xss == NULL)
+		errx(1, "Unable to create local SDP session");
+
+	if (sdp_error(xss) != 0)
+		errx(1, "Unable to open local SDP session. %s (%d)",
+			 strerror(sdp_error(xss)), sdp_error(xss));
+
+	/* setup service */
+	memset(&pan, 0, sizeof(pan));
+	pan.service  = SDP_SERVICE_CLASS_NAP;
+	pan.psm      = psm;
+	pan.version  = 0x0100;
+	pan.security = 0;
+	pan.net      = 0x0005;
+	pan.rate     = 0xffffffff;
+
+	memcpy(&bt_addr_any, NG_HCI_BDADDR_ANY, sizeof(bt_addr_any));
+	if (sdp_register_service(xss, SDP_SERVICE_CLASS_NAP, &bt_addr_any,
+							 (void *)&pan, sizeof(pan), NULL) != 0) {
+		errx(1, "Unable to register PAN service with "
+			 "local SDP daemon. %s (%d)",
+			 strerror(sdp_error(xss)), sdp_error(xss));
+	}
+}
+
 
 /* Server initialization
    --------------------- */
-
 static int init_btpand(btpand_t* serv, const char* ifname, bdaddr_t* addr,
 		       uint16_t psm, int verbosity, int detached)
 {
@@ -222,6 +255,8 @@
     }
   }
 
+  sdp_register( psm );
+
   if( ( rv = init_btpand(&serv,ifname,&addr,psm,verbosity,detached) ) )
     return rv;
 

--------------050706010301070608000808
Content-Type: text/plain;
 name="sdp.h.patch"
Content-Transfer-Encoding: 7bit
Content-Disposition: inline;
 filename="sdp.h.patch"

--- sdp.h.orig	2006-08-26 20:16:35.000000000 -0300
+++ sdp.h	2008-03-10 20:04:50.000000000 -0300
@@ -629,6 +629,18 @@
 typedef struct sdp_lan_profile		sdp_lan_profile_t;
 typedef struct sdp_lan_profile *	sdp_lan_profile_p;
 
+struct sdp_pan_profile
+{
+	uint16_t	psm;
+	uint16_t    version;
+	uint16_t    security;
+	uint16_t    service;
+	uint16_t    net;
+	uint32_t    rate;
+};
+typedef struct sdp_pan_profile		sdp_pan_profile_t;
+typedef struct sdp_pan_profile *	sdp_pan_profile_p;
+
 /* Keep this in sync with sdp_irmc_profile */
 struct sdp_opush_profile
 {

--------------050706010301070608000808--



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?47D5BEE3.80109>