[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[bluetooth-dev] Bluetooth USB Update




This is a cross-post between the usb-devel list and the Axis Bluetooth
list.  Let me know if I have committed a sin. This will be a long post as
it contains some instructions and some patches.  Greg, perhaps we should
make a FAQ based on this?  This should be considered a draft and I would
like feedback.

Axis guys: Please note 5a and 5b for some requested changes in the stack.

Sorry for being out of the loop for a little while on the Bluetooth stuff.
I was between jobs of sorts.  In the meantime I have picked up three (one
dead, two good) SigmaComtec modules, which turn out to be resold Ericsson
modules.  The firmware statement:

Ericsson HW revision info:
Generated: 2000-04-28 15:54
Comment: CXC 125 244 P9A

and have P3D on the shield, which I think is the baseband version.

I have managed to get them talking to each other using the Axis stack
after a few tweaks which people will need to use these suckers.
Except where noted, these instructions must be carried out on two separate
machines.

1) Download a 2.2.18pre15 kernel to use.  This includes the most recent
version of the Bluetooth usb driver.  I had bad luck with pre16 and pre17,
your mileage may vary.  Be sure to enable ppp, usb and the Bluetooth usb
driver.  Make and install as usual

2) Download a copy of the axis software stack from www.developer.axis.com
I use the 8/14/00 version which is the latest as of this time.

3) Make two character devices:
	mknod /dev/ttyBLUE0 c 240 0
	mknod /dev/ttyBT0 c 124 0

   The first is a tty device the interfaces directly with the usb driver.
Bad things will probably happen if you write to this directly.  The other
tty is used by the axis stack for the RFCOMM service.  Similar to the
IRCOMM service for IR, basically a comm port emulator.

4) Create a file /etc/ppp/options.ttyBT0

On one machine, referred to as the "server" it should contain something
like this:

crtscts
debug
local
nodetach
silent
passive
noauth
192.168.1.1:192.168.1.2

And on the other machine, referred to as the "client"

crtscts
debug
local
nodetach
noauth
192.168.1.2:192.168.1.1

Some of these lines are optional, but just go with these at first.

5) Unpack the axis stack somewhere.  Two parts of the stack must be
patched to get things working.  Hopeful axis will integrate these in the
next release of the stack.

5a) First patch the bluetooth/apps/btd.c to include options for
initializing USB hardware:

diff -ruw bluetooth.orig/apps/btd.c bluetooth/apps/btd.c
--- bluetooth.orig/apps/btd.c	Wed Oct 25 17:13:16 2000
+++ bluetooth/apps/btd.c	Wed Oct 25 17:29:53 2000
@@ -197,6 +197,7 @@
 #define UNKNOWN_HW      0
 #define DIGIDONGLE      1
 #define ERICSSON_MODULE 2 
+#define USB_MODULE      3 
 
 #define PPPDCMD "pppd"
 
@@ -1134,6 +1135,11 @@
     fd_setup(fd, 9600, USE_FLOW_CTRL);
     hw_init = DIGIDONGLE;
   }
+  else if (strncmp(hw, "usb", 3) == 0)
+  {
+    printf("Initializing usb HW\n");
+    hw_init = USB_MODULE;
+  }
   else
   {
     /* No HW initialization */
@@ -1215,6 +1221,14 @@
     set_digi_baudrate(spd);
     break;
 		
+   case USB_MODULE:
+    sleep(1);
+    printf("Setting write_scan_enable in usb module!\n");
+    write_scan_enable(PAGE_SCAN_ENABLE|INQUIRY_SCAN_ENABLE);
+
+    sleep(1); /* wait for HW... */
+    break;
+		
    default:
     printf("No hw init done\n");
     break;
@@ -1271,6 +1285,16 @@
     }
     break;
 		
+   case USB_MODULE:
+    sleep(1);
+    printf("Setting write_scan_enable in usb module!\n");
+    if (ioctl(bt_fd, BTWRITESCANENABLE, &spd) < 0)
+    { 
+      perror("BTWRITESCANENABLE");
+      exit(1);
+    }
+    break;
+
    default:
     printf("No hw init done\n");
     break;

5b) Then patch hci.c.  When writing to the USB layer we shouldn't be in
interrupt context.  If we were to be in interrupt context, the usb layer
must queue the packets for later transmission since submitting urbs can
block.  Queueing at the usb layer is the wrong answer because it would add
complexity and another buffer copy to the transmission path.  In fact the
USB driver will REJECT anything sent from interrupt context.  So a small,
but required, change is made to the Axis stack to delay packet
transmission using the scheduler task queue.  If there is a better way,
then let me know, but this seems to work.

diff -ruw bluetooth.orig/src/hci.c bluetooth/src/hci.c
--- bluetooth.orig/src/hci.c	Wed Oct 25 17:12:52 2000
+++ bluetooth/src/hci.c	Wed Oct 25 19:02:44 2000
@@ -38,6 +38,7 @@
 #include <linux/bluetooth/tcs.h>
 #include <linux/bluetooth/btmem.h>
 #include <linux/delay.h>
+#include <linux/interrupt.h>
 #else /* user mode */
 #include <stdlib.h>
 #include <string.h>
@@ -413,6 +414,7 @@
 #endif
 
 struct wait_queue *hci_wq = NULL;
+struct tq_struct send_cmd_task;
 static u8 local_bd[6];
 
 /****************** FUNCTION DEFINITION SECTION *****************************/
@@ -2112,6 +2114,19 @@
 	D_CMD("send_cmd_queue: start (cmd_num:%d)\n", 
 	      hci_ctrl.hc_buf.cmd_num);
   
+#ifdef __KERNEL__
+	/* If we are in interrupt context then queue this packet for later */
+	if (in_interrupt()){
+
+		send_cmd_task.routine = send_cmd_queue;
+		send_cmd_task.data = NULL;
+
+		queue_task(&send_cmd_task, &tq_scheduler);
+
+		return 0;
+	}
+#endif
+
 	while ((hci_ctrl.hc_buf.cmd_num > 0)
 	       && ((tmp = get_next_cmd()) != NULL)) {
     
@@ -2136,8 +2151,21 @@
 
 	D_CMD("send_cmd : cmd_num %d\n", hci_ctrl.hc_buf.cmd_num);
    
-	/* if cmd buffer hold data, try to send those first */
+#ifdef __KERNEL__
+	/* If we are in interrupt context then queue this packet for later */
+	if (in_interrupt()){
+		insert_cmd(cmd,len);
+
+		send_cmd_task.routine = send_cmd_queue;
+		send_cmd_task.data = NULL;
+
+		queue_task(&send_cmd_task, &tq_scheduler);
+
+		return 0;
+	}
+#endif
 
+ 	/* if cmd buffer hold data, try to send those first */
 	if ((send_cmd_queue() > 0) || (hci_ctrl.hc_buf.cmd_num <= 0)) {
 		/* More cmds in queue and we couldn't send any now, 
 		   queue this one aswell */

6) Do a make in bluetooth/src and bluetooth/apps

7) Insert usb modules, then the bluetooth usb driver module, then
bluetooth/src/bt.o

8) On the server run bluetooth/apps/btd -u /dev/ttyBLUE0 -i usb

9) On the client run bluetooth/apps/btd -u /dev/ttyBLUE0 -i usr -r client

10) Look in the log on the server machine and find a line that looks
something like this:

BT SYS: Local bd [00:d0:b7:03:28:c4]

11) At the menu on the client put in 
connect 00:d0:b7:03:28:c4 0

Obviously adjust for your particular hw address.  Make sure that you type
it in exactly with the same number of spaces etc.

12) Cross your fingers and it will connect.

13) Type in ppp at the client menu and you are off and running.


Known Bugs:
There are quite a few bugs that I hope to stomp out in the upcoming weeks.

1) Interface claiming.  The isoc and firmware interfaces are not claimed
by the usb driver.  This shows up as eror messages in the log.  This is
harmless but I will fix it.

2) ^C during stack initilization hoses the machine.  Possibly only when 
there is no device present.  Not sure about this one yet.

3) Unplugging the device hoses the machine often.  (I think this has
something to do with the tty_hangup call in the driver)  Still working on
it.

4) This error message is probably harmless:
weir kernel: usb-uhci.c: interrupt, status 3, frame#870

5) Erm, the setup process is a bit manual, eh?

Well, good luck.  Please, please let me know if you get this to work!


----                                                                   
Mark Corner                                      
mcorner@xxxxxxx.edu


-
To unsubscribe from this list: send the line "unsubscribe bluetooth-dev" in
the body of a message to majordomo@xxxxxxx.com