Test version of BlueUSB stack. Includes SDP and RFCOMM. As Client it allows to connect to my fischertechnik TX Controller. As Server it echo\\\\\\\'s characters to Putty. PIN=1234
Dependencies: mbed myUSBHost AvailableMemory
Dependents: mbed_TANK_Kinect myBlueUSB_ros ftusbClass
Revision 1:0dde58e0cccf, committed 2011-04-04
- Comitter:
- networker
- Date:
- Mon Apr 04 16:47:10 2011 +0000
- Parent:
- 0:81ed8b6e4a8b
- Child:
- 2:0118da9e5169
- Commit message:
- initial revision
Changed in this revision
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/FATFileSystem.lib Mon Apr 04 16:47:10 2011 +0000 @@ -0,0 +1,1 @@ +http://mbed.org/users/mbed_unsupported/code/fatfilesystem/ \ No newline at end of file
--- a/HCITransportUSB.h Mon Apr 04 16:41:03 2011 +0000
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,46 +0,0 @@
-#ifndef HCITRANSPORTUSB_H
-#define HCITRANSPORTUSB_H
-#define MAX_HCL_SIZE 260
-#define MAX_ACL_SIZE 400
-#include "USBHost.h"
-
-extern int bulk;
-
-class HCITransportUSB : public HCITransport {
- int _device;
- u8* _hciBuffer;
- u8* _aclBuffer;
-
-public:
- void Open(int device, u8* hciBuffer, u8* aclBuffer) {
- _device = device;
- _hciBuffer = hciBuffer;
- _aclBuffer = aclBuffer;
- USBInterruptTransfer(_device,0x81,_hciBuffer,MAX_HCL_SIZE,HciCallback,this);
- USBBulkTransfer(_device,0x82,_aclBuffer,MAX_ACL_SIZE,AclCallback,this);
- }
-
- static void HciCallback(int device, int endpoint, int status, u8* data, int len, void* userData) {
- HCI* t = ((HCITransportUSB*)userData)->_target;
- if (t)
- t->HCIRecv(data,len);
- USBInterruptTransfer(device,0x81,data,MAX_HCL_SIZE,HciCallback,userData);
- }
-
- static void AclCallback(int device, int endpoint, int status, u8* data, int len, void* userData) {
- HCI* t = ((HCITransportUSB*)userData)->_target; //printf("ACL: %d bytes avail\n", len);
- if (t)
- t->ACLRecv(data,len);
- USBBulkTransfer(device,0x82,data,MAX_ACL_SIZE,AclCallback,userData);
- }
-
- virtual void HCISend(const u8* data, int len) {
- USBControlTransfer(_device,REQUEST_TYPE_CLASS, 0, 0, 0,(u8*)data,len);
- }
-
- virtual void ACLSend(const u8* data, int len) {
- USBBulkTransfer(_device,0x02,(u8*)data,len);
- }
-};
-
-#endif
--- a/L2CAP.cpp Mon Apr 04 16:41:03 2011 +0000
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,569 +0,0 @@
-/*
-Copyright (c) 2010 Peter Barrett
-
-Permission is hereby granted, free of charge, to any person obtaining a copy
-of this software and associated documentation files (the "Software"), to deal
-in the Software without restriction, including without limitation the rights
-to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-copies of the Software, and to permit persons to whom the Software is
-furnished to do so, subject to the following conditions:
-
-The above copyright notice and this permission notice shall be included in
-all copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
-THE SOFTWARE.
-*/
-
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <stdio.h>
-#include <string.h>
-
-#include "Utils.h"
-#include "hci.h"
-#include "HCITransportUSB.h"
-
-#define L2CAP_COMMAND_REJ 0x01
-#define L2CAP_CONN_REQ 0x02
-#define L2CAP_CONN_RSP 0x03
-#define L2CAP_CONF_REQ 0x04
-#define L2CAP_CONF_RSP 0x05
-#define L2CAP_DISCONN_REQ 0x06
-#define L2CAP_DISCONN_RSP 0x07
-#define L2CAP_ECHO_REQ 0x08
-#define L2CAP_ECHO_RSP 0x09
-#define L2CAP_INFO_REQ 0x0a
-#define L2CAP_INFO_RSP 0x0b
-
-//template <class T> T min(T a, T b) { return a<b ? a : b;}
-
-/* L2CAP command codes */
-const char* L2CAP_ComandCodeStr(int c) {
- switch (c) {
- case L2CAP_COMMAND_REJ:
- return "L2CAP_COMMAND_REJ";
- case L2CAP_CONN_REQ:
- return "L2CAP_CONN_REQ";
- case L2CAP_CONN_RSP:
- return "L2CAP_CONN_RSP";
- case L2CAP_CONF_REQ:
- return "L2CAP_CONF_REQ";
- case L2CAP_CONF_RSP:
- return "L2CAP_CONF_RSP";
- case L2CAP_DISCONN_REQ:
- return "L2CAP_DISCONN_REQ";
- case L2CAP_DISCONN_RSP:
- return "L2CAP_DISCONN_RSP";
- case L2CAP_ECHO_REQ:
- return "L2CAP_ECHO_REQ";
- case L2CAP_ECHO_RSP:
- return "L2CAP_ECHO_RSP";
- case L2CAP_INFO_REQ:
- return "L2CAP_INFO_REQ";
- case L2CAP_INFO_RSP:
- return "L2CAP_INFO_RSP";
- }
- return "unknown";
-}
-
-#define OFFSET 8 //means the buffer also has space for the l2cap/hci headers and need not be allocated and copied
-//#define OFFSET 0 //means the buffer only has space for the payload which need to be copied
-#if OFFSET == 0
-#define L2CAPBUFSIZE 128
-#else
-#define L2CAPBUFSIZE 0
-#endif
-
-typedef struct {
- u16 handle;
- u16 length; // total
- u16 l2capLength; // length -4
- u16 cid; // Signaling packet CID = 1
- u8 data[L2CAPBUFSIZE]; // Largest thing to send!!! todo
-} L2CAPData;
-
-//
-void BTDevice::Init() {
- memset(&_info,0,sizeof(inquiry_info));
- _handle = 0;
- _name[0] = 0;
- _state = 0;
-}
-
-// virtual SocketHandler
-int BTDevice::Open(SocketInternal* sock, SocketAddrHdr* addr) {
- L2CAPSocket* s = (L2CAPSocket*)sock;
- L2CAPAddr* a = (L2CAPAddr*)addr;
- s->scid = 0x40 + sock->ID-1; // are these reserved?
- s->dcid = 0;
- Connect(s->scid,a->psm);
- sock->State = SocketState_L2CAP_WaitConnectRsp;
- contState = 0;
- return sock->ID;
-}
-
-// virtual SocketHandler, called from HCI which is ABOVE L2CAP
-int BTDevice::Send(SocketInternal* sock, const u8* data, int len) {
- L2CAPSocket* s = (L2CAPSocket*)sock;
-#if OFFSET == 8 //sizeof L2CAPData header
- L2CAPData &d = *const_cast<L2CAPData*>((L2CAPData*)data);
-#else
- L2CAPData d;
-#endif
- if (len > peer_mtu) {//mtu concerns the l2cap mtu, because we use basic mode we cannot segment
- printf("MTU (%d) for outgoing packet (%d) exceeded\n", peer_mtu, len);
- return 0;
- }
- d.handle = _handle | 0x2000;
- d.length = 4 + len - OFFSET;
- d.l2capLength = len - OFFSET;
- d.cid = s->dcid;
- printf("cid=%d: ", d.cid);
- printfBytes("sending: ", data, len);
-
-#if OFFSET == 0
- if (len > L2CAPBUFSIZE)
- return -1;
- memcpy(d.data,data,len);
- return Send((u8*)&d,len+8);
-#else
- return Send(data, len);
-#endif
-}
-
-// virtual SocketHandler
-int BTDevice::Close(SocketInternal* sock) {
- printf("L2CAP close %d\n",sock->ID);
- sock->State = SocketState_L2CAP_WaitDisconnect;
- L2CAPSocket* s = (L2CAPSocket*)sock;
- return Disconnect(s->scid,s->dcid);
-}
-
-L2CAPSocket* BTDevice::SCIDToSocket(int scid) {
- return (L2CAPSocket*)GetSocketInternal(scid-0x40+1);
-}
-
-int BTDevice::Send(const u8* data, int len) {//printfBytes("Transport : ", data, len);
- _transport->ACLSend(data,len);
- return 0;
-}
-
-void BTDevice::repeat_cmd() {
-printf("Cmd on handle %#x timed out, resending txid=%d\n", _handle, last_req.id);
- Send ((u8*)&last_req, last_req.length+4);//danger! interrupt context, Send is not reentrant
- //optionally set new larger timeout
-}
-
-int BTDevice::Send(u8 c, u8 id, u16* params, int count) {
- L2CAPCmd cmd;
- cmd.handle = _handle | 0x2000;
- cmd.length = 8 + count*2;
-
- cmd.l2capLength = cmd.length-4;
- cmd.cid = 1; // Signaling packet
-
- cmd.cmd = c;
- cmd.id = id;
- cmd.cmdLength = count*2;
- for (int i = 0; i < count; i++)
- cmd.params[i] = params[i];
- if ((c & 1) == 0) { //this is a request
- last_req = cmd;
- rtx.attach(this, &BTDevice::repeat_cmd, 5.0);
- printf("Starting timeout for %#x, txid=%d\n", _handle, id);
- }
- return Send((u8*)&cmd,cmd.length+4);
-}
-
-int BTDevice::Connect(int scid, int psm) {
- u16 p[2];
- p[0] = psm;
- p[1] = scid;
- return Send(L2CAP_CONN_REQ,_txid++,p,2);
-}
-
-int BTDevice::Disconnect(int scid, int dcid) {
- u16 p[2];
- p[0] = dcid;
- p[1] = scid;
- return Send(L2CAP_DISCONN_REQ,_txid++,p,2);
-}
-
-int BTDevice::ConfigureRequest(int dcid) {
- u16 p[4];
- p[0] = dcid;
- p[1] = 0;
- p[2] = 0x0201; // Options
- p[3] = min(0x02A0, MAX_ACL_SIZE); // my receiving MTU 672
- return Send(L2CAP_CONF_REQ,_txid++,p,4);
-}
-
-int BTDevice::ConfigureResponse(u8 rxid, int dcid) {
- u16 p[3];
- p[0] = dcid; //source cid
- p[1] = 0; //flags (no continuation)
- p[2] = 0; //result (success)
- return Send(L2CAP_CONF_RSP,rxid,p,3);
-}
-
-int BTDevice::DisconnectResponse(u8 rxid, int scid, int dcid) {
- u16 p[2];
- p[0] = dcid;
- p[1] = scid;
- return Send(L2CAP_DISCONN_RSP,rxid,p,2);
-}
-#if 0
-//handle16, length16, lengthL2CAP16, cid16, code8, tid8, lengthData16
-// 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11
-void BTDevice::Control(const u8* data, int len) { //control channel receive
- printf("\x1B[%dm", 31);
- int cc = data[8];//command code
- printf(L2CAP_ComandCodeStr(cc));
- //int result = LE16(data+16);//conn_rsp, and conf_resp only
- //printf(" Result %d\n",result);
- switch (cc) {
- case L2CAP_COMMAND_REJ://bad command, eg. MTU, check (reason)
- printf(" rejection reason=%d\n", LE16(data+12));
- break;
- case L2CAP_CONN_REQ://incoming connection request, not expected but should reply with proper rejection (or accept)
- //when a connection is accepted a new socket must be opened
- break;
- // Response to our initial connect from Remote
- case L2CAP_CONN_RSP: {
- int dcid = LE16(data+12);
- int scid = LE16(data+14);
- L2CAPSocket* s = SCIDToSocket(scid);
- int result = LE16(data+16);
- printf("Result=%d, Status = %d\n", result, LE16(data+18));
- if (s->si.State != SocketState_L2CAP_WaitConnectRsp) {
- printf("Unexpected event ignored\n");
- break;
- }
- if (result == 0) {
- if (s) {
- s->si.State = SocketState_L2CAP_Config_wait;
- s->dcid = dcid;
- ConfigureRequest(dcid);
- s->si.State = SocketState_L2CAP_Config_wait_reqrsp;
- printf("Sent ConfigureRequest, state=WAIT_CONFIG_REQ-RSP\n");
- }
- } else {
- s->si.SetState(SocketState_Closed);
- printf("Connect failed?\n");
- }
- }
- break;
-
- case L2CAP_CONF_RSP: {
- int result = LE16(data+16);
- printf("Result=%d, datalen=%d, %smore conf to follow\n", result, LE16(data+10), LE16(data+14)?"":"No ");
- //should parse the config
- printfBytes("CONF RSP:", data+8, LE16(data+10)+4);
- int scid = LE16(data+12);
- SocketInternal* s = (SocketInternal*)SCIDToSocket(scid);
- if (s == 0) break;
- if (s->State != SocketState_L2CAP_Config_wait_reqrsp && s->State != SocketState_L2CAP_Config_wait_rsp) {
- printf("Unexpected event ignored\n");
- break;
- }
- if (result == 0) { //configuration acceptable
- if (s->State == SocketState_L2CAP_Config_wait_reqrsp) {
- s->State = SocketState_L2CAP_Config_wait_req;
- printf("State=WAIT_CONFIG_REQ\n");
- } else {
- ConfigureResponse(data[9],((L2CAPSocket*)s)->dcid);//data[9]==txid
- printf("Sent ConfigureResponse, state=Open\n");
- s->SetState(SocketState_Open);
- }
- } else {
- printf("Renegotiate configuration\n");
- }
- }
- break;
-
- case L2CAP_CONF_REQ: {
- int scid = LE16(data+12);//flags (data[14] LSB is continuation flag, data[18],[19] are the MTU
- L2CAPSocket* s = SCIDToSocket(scid);
- printfBytes("CONF REQ: ", data+8, LE16(data+10)+4);//data+16 contains option type 1-4 1=MTU, 2=flush timeout, 3=QoS, 4=FCM
- if (s == 0) break;
- if (s->si.State == SocketState_Closed ||
- s->si.State == SocketState_L2CAP_WaitConnectRsp ||
- s->si.State == SocketState_L2CAP_WaitDisconnect) {
- //Send Reject command
- break;
- }
- switch (data[16]) {
- case 1:
- peer_mtu = LE16(data+18);
- printf("MTU = %d bytes\n", peer_mtu);
- break;
- default:
- printf("Unsupported configuration option %d, value = %#X\n", data[16], LE16(data+18));
- break;
- }
- if (1 /* options acceptable */) {
- printf("Sending ConfigureResponse, old state=%d ", s->si.State);
- ConfigureResponse(data[9],s->dcid);//data[9]==txid, success
- switch (s->si.State) {
- case SocketState_L2CAP_Config_wait:
- s->si.State = SocketState_L2CAP_Config_wait_send;
- break;
- case SocketState_L2CAP_Config_wait_req:
- ((SocketInternal*)s)->SetState(SocketState_Open);
- break;
- case SocketState_L2CAP_Config_wait_rsp:
- break;
- case SocketState_L2CAP_Config_wait_reqrsp:
- s->si.State = SocketState_L2CAP_Config_wait_rsp;
- break;
- }
- printf("new state=%d\n", s->si.State);
- } else { //options not acceptable
- ConfigureResponse(data[9],s->dcid);//indicates success but should indicate fail
- }
- }
- break;
- case L2CAP_DISCONN_REQ: {
- int dcid = LE16(data+12);
- int scid = LE16(data+14);
- L2CAPSocket* s = SCIDToSocket(scid);
- s->si.SetState(SocketState_Closed);
- DisconnectResponse(data[9], scid, dcid);
- }
- break;
- case L2CAP_DISCONN_RSP: {
- int scid = LE16(data+14);
- L2CAPSocket* s = SCIDToSocket(scid);
- if (s->si.State == SocketState_L2CAP_WaitDisconnect)
- s->si.SetState(SocketState_Closed);
- }
- break;
- }
- printf("\x1b[0m");
-}
-#else
-//code8, tid8, lengthData16
-// 0, 1, 2, 3
-void BTDevice::Control(const u8* data, int len) { //control channel receive
- printf("\x1B[%dm", 31);
- int cc = data[0];//command code
- if (cc & 1) { //it is a response or a reject
- rtx.detach(); //kill the timeout
- printf("timeout cancelled for handle %#x, txid=%d\n", _handle, data[1]);
- }
- printf(L2CAP_ComandCodeStr(cc));
- switch (cc) {
- case L2CAP_COMMAND_REJ://bad command, eg. MTU, check (reason)
- printf(" rejection reason=%d\n", LE16(data+4));
- break;
- case L2CAP_CONN_REQ://incoming connection request, not expected but should reply with proper rejection (or accept)
- //when a connection is accepted a new socket must be opened
- printf("Remote side requested a connection\n");
- break;
- // Response to our initial connect from Remote
- case L2CAP_CONN_RSP: {
- int dcid = LE16(data+4);
- int scid = LE16(data+6);
- L2CAPSocket* s = SCIDToSocket(scid);
- int result = LE16(data+10);
- printf(" Result=%d, Status = %d\n", result, LE16(data+10));
- if (s->si.State != SocketState_L2CAP_WaitConnectRsp) {
- printf("Unexpected event ignored\n");
- break;
- }
- if (result == 0) {
- if (s) {
- s->si.State = SocketState_L2CAP_Config_wait;
- s->dcid = dcid;
- ConfigureRequest(dcid);
- s->si.State = SocketState_L2CAP_Config_wait_reqrsp;
- printf("Sent ConfigureRequest, state=WAIT_CONFIG_REQ_RSP\n");
- }
- } else {
- s->si.SetState(SocketState_Closed);
- printf("Connect failed?\n");
- }
- }
- break;
-
- case L2CAP_CONF_RSP: {
- int result = LE16(data+8);
- printf("Result=%d, datalen=%d, %smore conf to follow\n", result, LE16(data+2), LE16(data+6)?"":"No ");
- //should parse the config
- printfBytes("CONF RSP:", data, LE16(data+2)+4);
- int scid = LE16(data+4);
- SocketInternal* s = (SocketInternal*)SCIDToSocket(scid);
- if (s == 0) break;
- if (s->State != SocketState_L2CAP_Config_wait_reqrsp && s->State != SocketState_L2CAP_Config_wait_rsp) {
- printf("Unexpected event ignored\n");
- break;
- }
- if (result == 0) { //configuration acceptable
- if (s->State == SocketState_L2CAP_Config_wait_reqrsp) {
- s->State = SocketState_L2CAP_Config_wait_req;
- printf("State=WAIT_CONFIG_REQ\n");
- } else {
- ConfigureResponse(data[1],((L2CAPSocket*)s)->dcid);//data[1]==txid
- printf("Sent ConfigureResponse, state=Open\n");
- s->SetState(SocketState_Open);
- }
- } else {
- printf("Renegotiate configuration\n");
- }
- }
- break;
-
- case L2CAP_CONF_REQ: {
- int scid = LE16(data+4);//flags (data[6] LSB is continuation flag, data[10],[11] are the MTU
- L2CAPSocket* s = SCIDToSocket(scid);
- printfBytes("CONF REQ: ", data, LE16(data+2)+4);//data+8 contains option type 1-4 1=MTU, 2=flush timeout, 3=QoS, 4=FCM
- if (s == 0) break;
- if (s->si.State == SocketState_Closed ||
- s->si.State == SocketState_L2CAP_WaitConnectRsp ||
- s->si.State == SocketState_L2CAP_WaitDisconnect) {
- //Send Reject command
- break;
- }
- switch (data[8]) {
- case 1:
- peer_mtu = LE16(data+10);
- printf("MTU = %d bytes\n", peer_mtu);
- break;
- default:
- printf("Unsupported configuration option %d, value = %#X\n", data[8], LE16(data+10));
- break;
- }
- if (1 /* options acceptable */) {
- printf("Sending ConfigureResponse, old state=%d ", s->si.State);
- ConfigureResponse(data[1],s->dcid);//data[1]==txid, success
- switch (s->si.State) {
- case SocketState_L2CAP_Config_wait:
- s->si.State = SocketState_L2CAP_Config_wait_send;
- break;
- case SocketState_L2CAP_Config_wait_req:
- ((SocketInternal*)s)->SetState(SocketState_Open);
- break;
- case SocketState_L2CAP_Config_wait_rsp:
- break;
- case SocketState_L2CAP_Config_wait_reqrsp:
- s->si.State = SocketState_L2CAP_Config_wait_rsp;
- break;
- }
- printf("new state=%d\n", s->si.State);
- } else { //options not acceptable
- ConfigureResponse(data[1],s->dcid);//indicates success but should indicate fail
- }
- }
- break;
- case L2CAP_DISCONN_REQ: {
- int dcid = LE16(data+4);
- int scid = LE16(data+6);
- L2CAPSocket* s = SCIDToSocket(scid);
- s->si.SetState(SocketState_Closed);
- DisconnectResponse(data[1], scid, dcid);
- }
- break;
- case L2CAP_DISCONN_RSP: {
- int scid = LE16(data+6);
- L2CAPSocket* s = SCIDToSocket(scid);
- if (s->si.State == SocketState_L2CAP_WaitDisconnect)
- s->si.SetState(SocketState_Closed);
- }
- break;
- default: printf("Unsupported L2CAP message %d\n", cc);
- }
- printf("\x1b[0m");
-}
-#endif
-
-void BTDevice::ACLFwd(const u8* data, int len) {
- if (l2cap_sock == 1) {
- //printf("cannot handle segmented ACL control packets\n");
- Control(data, len);
- return;
- }
- SocketInternal* s = (SocketInternal*)SCIDToSocket(l2cap_sock);
- if (s)
- s->Recv(data,len);
- else
- printf("Bad event cid %d\n",l2cap_sock);
-}
-//sometimes acl packets are segmented, in that case the l2cap payload length does not correspond to the acl pkt length
-//and the l2cap packet length. L2CAP works in basic mode and cannot be segmented hence the l2cap pkt size corresponds to
-//the acl pkt size
-void BTDevice::ACLRecv(const u8* data, int acllen) {
- printfBytes("L2CP",data,acllen);
- u16 handle = LE16(data);
- if ((handle&0x0fff) != _handle) {
- printf("unexpected handle %#x, this _handle=%#x\n", handle, _handle);
- return;
- }
- char pb = (handle>>12) & 3;
- int p = 4; //start of l2cap packet
- int len = LE16(data+2); //length of l2cap pkt
- while (p < len)
- switch (contState) {
- case 0:
- plen = data[p++];
- contState = 1;
- break;
- case 1:
- plen += data[p++]<<8;
- if (pb == 2 && plen == acllen-8) {//normal case, l2cap pkt is contained completely in this hci pkt
- l2cap_sock = data[p] + (data[p+1]<<8);
- contState = 0;
- ACLFwd(data+8, plen); //forward the packet in its original buffer
- return; //all data was dealt with
- } else { //packet is segmented
- printf("ACL packet is segmented\n");
- contState = 2;
- contBuf = new unsigned char[plen];//allocate recombination buffer
- contPos = 0;
- }
- break;
- case 2:
- l2cap_sock = data[p++];
- contState = 3;
- break;
- case 3:
- l2cap_sock += data[p++]<<8;
- contState = 4;
- break;
- case 4: //data, recombine segmented ACL (not l2cap!) frames
- if (contPos < plen) {//buffer not yet full
- int datalen = acllen - p; //data in this incoming pkt
- int remcap = plen - contPos; //remaining capacity in the recombination buffer
- if (datalen <= remcap) {
- memcpy(contBuf+contPos, data+p, datalen);
- contPos += datalen;
- p = acllen;//end of data, stop the while loop
- if (contPos == plen) {//buffer is full now
- printfBytes("Recombined packet is:", contBuf, plen);
- ACLFwd(contBuf, plen); //forward the recombination buffer
- delete[] contBuf;//and free the buffer
- contState = 0;
- }//else stay in this state to wait for the rest
- } else {//data contains (part of) next packet
- memcpy(contBuf+contPos, data+p, plen-contPos);//this packet is complete
- p += plen-contPos;
- printfBytes("Recombined packet is:", contBuf, plen);
- printfBytes("Next packet starts with:", data+p, acllen-p);
- ACLFwd(contBuf, plen); //forward the recombination buffer
- delete[] contBuf;//and free the buffer
- contState = 0; //continue with the next packet
- }
- } else {
- printf("Cannot append to buffer (size=%d, pos=%d, datalen = %d)\n", plen, contPos, len-p);
- contState = 0;
- return;
- }
- break;
- }//switch (and while)
-}
--- a/Socket.cpp Mon Apr 04 16:41:03 2011 +0000
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,145 +0,0 @@
-/*
-Copyright (c) 2010 Peter Barrett
-
-Permission is hereby granted, free of charge, to any person obtaining a copy
-of this software and associated documentation files (the "Software"), to deal
-in the Software without restriction, including without limitation the rights
-to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-copies of the Software, and to permit persons to whom the Software is
-furnished to do so, subject to the following conditions:
-
-The above copyright notice and this permission notice shall be included in
-all copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
-THE SOFTWARE.
-*/
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <stdio.h>
-#include <string.h>
-
-#include "Utils.h"
-#include "Socket.h"
-
-#define MAX_SOCKET_HANDLERS 4
-#define MAX_SOCKETS 16
-
-class SocketInternalPad
-{
- public:
- SocketInternal si;
- u8 pad[8];
-};
-
-class SocketManager
-{
- SocketHandler* _handlers[MAX_SOCKET_HANDLERS];
- SocketInternalPad _sockets[MAX_SOCKETS];
-
- public:
- SocketManager()
- {
- memset(_handlers,0,sizeof(_handlers));
- memset(_sockets,0,sizeof(_sockets));
- }
-
- SocketHandler* GetHandler(int type)
- {
- if (type < 1 || type > MAX_SOCKET_HANDLERS)
- return 0;
- return _handlers[type - 1];
- }
-
- SocketInternal* GetInternal(int s)
- {
- if (s < 1 || s > MAX_SOCKETS)
- return 0;
- return &_sockets[s - 1].si;
- }
-
- int RegisterSocketHandler(int type, SocketHandler* handler)
- {
- if (type < 1 || type > MAX_SOCKET_HANDLERS)
- return ERR_SOCKET_TYPE_NOT_FOUND;
- _handlers[type - 1] = handler;
- return 0;
- }
-
- int Open(int type, SocketAddrHdr* addr, SocketCallback callback, void* userData)
- {
- SocketHandler* h = GetHandler(type);
- if (!h)
- return ERR_SOCKET_TYPE_NOT_FOUND;
-
- for (int i = 0; i < MAX_SOCKETS; i++)
- {
- SocketInternal* si = (SocketInternal*)(_sockets+i);
- if (si->ID == 0)
- {
- si->ID = i+1;
- si->Type = type;
- si->Callback = callback;
- si->userData = userData;
- printf("Opening socket %d for type %d, invoking 'Open' on %p (=%s)\n", si->ID, type, h, h->Name());
- return h->Open(si,addr);
- }
- }
- return ERR_SOCKET_NONE_LEFT;
- }
-
- int Send(int socket, const u8* data, int len)
- {
- SocketInternal* si = GetInternal(socket);
- if (!si || si->ID != socket)
- return ERR_SOCKET_NOT_FOUND;
- // printf("sending %d bytes to socket %d (ID=%d)\n", len, socket, si->ID);
- return GetHandler(si->Type)->Send(si,data,len);
- }
-
- int Close(int socket)
- {
- SocketInternal* si = GetInternal(socket);
- if (!si || si->ID != socket)
- return ERR_SOCKET_NOT_FOUND;
- si->SetState(SocketState_Closing);
- int retval = GetHandler(si->Type)->Close(si);
- //si->SetState(Socket_Closed);
- //si->ID = 0;
- return retval;
- }
-};
-
-SocketManager gSocketManager;
-
-int Socket_Open(int type, SocketAddrHdr* addr, SocketCallback callback, void* userData)
-{
- return gSocketManager.Open(type,addr,callback,userData);
-}
-
-int Socket_Send(int socket, const u8* data, int len)
-{
- return gSocketManager.Send(socket,data,len);
-}
-
-int Socket_Close(int socket)
-{
- return gSocketManager.Close(socket);
-}
-
-int RegisterSocketHandler(int type, SocketHandler* handler)
-{
- return gSocketManager.RegisterSocketHandler(type,handler);
-}
-
-SocketInternal* GetSocketInternal(int socket)
-{
- return gSocketManager.GetInternal(socket);
-}
-
--- a/Socket.h Mon Apr 04 16:41:03 2011 +0000
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,108 +0,0 @@
-/*
-Copyright (c) 2010 Peter Barrett
-
-Permission is hereby granted, free of charge, to any person obtaining a copy
-of this software and associated documentation files (the "Software"), to deal
-in the Software without restriction, including without limitation the rights
-to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-copies of the Software, and to permit persons to whom the Software is
-furnished to do so, subject to the following conditions:
-
-The above copyright notice and this permission notice shall be included in
-all copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
-THE SOFTWARE.
-*/
-
-#ifndef SOCKET_H_INCLUDED
-#define SOCKET_H_INCLUDED
-
-#define SOCKET_HCI 1
-#define SOCKET_L2CAP 2
-#define SOCKET_RFCOM 3
-#define SOCKET_SDP 4
-
-typedef struct
-{
- u8 AddressSpecific[0]; // BDADDR,psm etc
-} SocketAddrHdr;
-
-enum SocketState
-{
- SocketState_Unknown,
- SocketState_Opening,
- SocketState_Open,
- SocketState_Closing,
- SocketState_Closed,
- SocketState_L2CAP_WaitConnect,
- SocketState_L2CAP_WaitConnectRsp,
- SocketState_L2CAP_WaitDisconnect,
- SocketState_L2CAP_Config_wait = 16,
- SocketState_L2CAP_Config_wait_send,
- SocketState_L2CAP_Config_wait_req,
- SocketState_L2CAP_Config_wait_rsp,
- SocketState_L2CAP_Config_wait_reqrsp
-};
-
-typedef void (*SocketCallback)(int socket, SocketState state, const u8* data, int len, void* userData);
-
-int Socket_Open(int type, SocketAddrHdr* addr, SocketCallback callback, void* userData); // Open a socket
-int Socket_Send(int socket, const u8* data, int len);
-int Socket_State(int socket);
-int Socket_Close(int socket);
-
-//===========================================================================
-//===========================================================================
-// Don't need to look at or use anything below this line:
-// Internal representation of socket
-
-class SocketHandler;
-class SocketInternal
-{
- public:
-
- u8 ID;
- u8 State;
- u8 Type;
- u8 B0;
- SocketCallback Callback;
- void* userData;
- u8 Data[0]; // Extra socket data starts here
-
- void Recv(const u8* data, int len)
- {
- Callback(ID,(SocketState)State,data,len,userData);
- }
-
- void SetState(SocketState state)
- {
- State = state;
- Callback(ID,(SocketState)State,0,0,userData);
- if (state == SocketState_Closed)
- ID = 0;
- }
-};
-
-class SocketHandler
-{
- public:
- virtual int Open(SocketInternal* sock, SocketAddrHdr* addr) = 0;
- virtual int Send(SocketInternal* sock, const u8* data, int len) = 0;
- virtual int Close(SocketInternal* sock) = 0;
- virtual char* Name() { return "Base SocketHandler";}
-};
-
-int RegisterSocketHandler(int type, SocketHandler* handler);
-SocketInternal* GetSocketInternal(int socket);
-
-#define ERR_SOCKET_TYPE_NOT_FOUND -200
-#define ERR_SOCKET_NOT_FOUND -201
-#define ERR_SOCKET_NONE_LEFT -202
-
-#endif // SOCKET_H_INCLUDED
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/TestShell.cpp Mon Apr 04 16:47:10 2011 +0000
@@ -0,0 +1,223 @@
+
+/*
+Copyright (c) 2010 Peter Barrett
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+THE SOFTWARE.
+*/
+#include "mbed.h"
+#include <vector>
+#include "Utils.h"
+#include "USBHost.h"
+#include "hci.h"
+#include "HCITransportUSB.h"
+#include "RFCOMM.h"
+#include "ftclasslibusbdevbt.h"
+#include "sdp_data.h"
+#include "sdp.h"
+
+/************************************************
+TODO:
+mtu and credits are completely unhandled - in progress
+multiple rfcomm sessions should be possible - done
+SDP would be nice - beta
+multiple rfcomm channels are untested
+decoupling of rfcomm and application - much better
+packets are not reassembled - some are (HCI and ft application level)
+disconnect and timeouts
+************************************************/
+#define DEBUG 1
+int state = 0;
+
+void printf(const BD_ADDR* addr) {
+ const u8* a = addr->addr;
+ printf("%02X:%02X:%02X:%02X:%02X:%02X",a[5],a[4],a[3],a[2],a[1],a[0]);
+}
+
+//int bulk = 0;
+
+char FtDevClass[3] = {0x00, 0x1F, 0x82 };
+
+// Instance
+RFCOMMManager rfcomm_manager;
+
+class application : public HCI {
+ BTDevice* devs[8];
+ int count, i, pending;
+public:
+ // We have connected to a device
+ void ConnectionComplete(connection_info* info) {
+ printf("ConnectionComplete ");
+ BD_ADDR* a = &info->bdaddr;
+ printf(a);
+ printf("\n");
+ RemoteNameRequest(a);
+ for (i++; i < count; i++) {//find the next device to open
+ printfBytes("DEVICE CLASS",devs[i]->_info.dev_class,3);
+ if (devs[i]->_handle == 0 && memcmp(devs[i]->_info.dev_class, FtDevClass, 3)==0) {//or some other way to connect to RFCOMM devices
+ BD_ADDR* bd = &devs[i]->_info.bdaddr;
+ printf("Connecting to ");
+ printf(bd);
+ printf("\n");
+ pending++;
+ CreateConnection(bd); //some low level connect, just let it happen for now (sets pin, mtu etc.)
+ printf("connection cmd was sent\n");
+ return;
+ }
+ }
+ //state = 1; //start the real application
+ }
+
+ void ConnectDevices() {
+ count = GetDevices(devs,8);//get pointers to all bluetooth devices
+ pending = 0;
+ for (i = 0; i < count; i++) {
+ printfBytes("DEVICE CLASS",devs[i]->_info.dev_class,3);
+ if (devs[i]->_handle == 0 && memcmp(devs[i]->_info.dev_class, FtDevClass, 3)==0) {//or some other way to connect to RFCOMM devices
+ BD_ADDR* bd = &devs[i]->_info.bdaddr;
+ printf("Connecting to ");
+ printf(bd);
+ printf("\n");
+ pending++;
+ CreateConnection(bd); //some low level connect, just let it happen for now (sets pin, mtu etc.)
+ printf("connection cmd was sent\n");
+ return;
+ }
+ }
+ if (pending == 0) state = 1;//for the case when there are no ft devices
+ }
+ virtual void Callback(HCI_CALLBACK_EVENT c, const u8* data, int len);
+} App; //application instance
+
+
+void application::Callback(HCI_CALLBACK_EVENT evt, const u8* data, int len) {//these events are forwarded (in)directly from HCIRecv
+ unsigned char pin[] = "1234";
+ printf("\x1b[%dm", 33);
+ switch (evt) {
+ case CALLBACK_READY:
+ printf("CALLBACK_READY\n");
+ Inquiry();//start the second phase of the discovery
+ break;
+
+ case CALLBACK_INQUIRY_RESULT: //optionally build the list of FT devices here
+ printf("CALLBACK_INQUIRY_RESULT ");
+ printf((BD_ADDR*)data);
+ printf("\n");//data points to inquiry_info struct
+// RemoteNameRequest((BD_ADDR*)data);
+ break;
+
+ case CALLBACK_INQUIRY_DONE:
+ printf("CALLBACK_INQUIRY_DONE\n");
+ ConnectDevices();
+ break;
+
+ case CALLBACK_REMOTE_NAME: {
+ BD_ADDR* addr = (BD_ADDR*)data;
+ const char* name = (const char*)(data + 6);
+ printf(addr);
+ printf(" = % s\n",name);
+ pending--;
+ if (pending == 0) state = 1;
+ }
+ break;
+
+ case CALLBACK_CONNECTION_COMPLETE:
+ ConnectionComplete((connection_info*)data);
+ {
+ printf("Going to open sdp socket\n");
+ L2CAPAddr addr;
+ connection_info *ci = (connection_info*)data;
+ memcpy(&addr.bdaddr, &ci->bdaddr, 6);
+ addr.psm = 1;//should not matter
+ int s = Socket_Open(SOCKET_SDP, &addr.hdr, &SDP.OnSockCallback, &SDP);
+ }
+ break;
+ case CALLBACK_PIN_REQ:
+ printf("Enter PIN for ");
+ printf((BD_ADDR*)data);
+ printf(" : submitting %s\n", pin);
+ PinCodeReply(data, pin);
+ break;
+ };
+ printf("\x1b[%dm", 0);
+}
+
+// these should be placed in the DMA SRAM
+typedef struct {
+ u8 _hciBuffer[MAX_HCL_SIZE];
+ u8 _aclBuffer[MAX_ACL_SIZE];
+} SRAMPlacement;
+
+HCITransportUSB _HCITransportUSB; //use USB as the transport to the radio
+
+int OnBluetoothInsert(int device) {//install the HCI and start discovery, user callbacks are made to HciCalback
+ printf("Bluetooth inserted of %d\n",device);
+ u32 sramLen;
+ u8* sram = USBGetBuffer(&sramLen);
+ sram = (u8*)(((u32)sram + 1023) & ~1023);
+ SRAMPlacement* s = (SRAMPlacement*)sram;
+ _HCITransportUSB.Open(device,s->_hciBuffer,s->_aclBuffer);//setup buffers for USB host, incoming data goes first to HCIRecv and ACLRecv
+ RegisterSocketHandler(SOCKET_L2CAP,&App); //register the application::hci as handler for L2CAP events
+ RegisterSocketHandler(SOCKET_RFCOM, &rfcomm_manager);//set the RFCOMMManager as the RFCOM socket handler
+ if (RegisterSocketHandler(SOCKET_SDP, &SDP))
+ printf("Could not register SDP socket type\n");
+ App.Open(&_HCITransportUSB);
+ App.Inquiry();//start discovery of BT devices phase 0
+ return 0;
+}
+
+DigitalOut led(LED1), loop(LED2);
+
+void TestShell() {
+ int n=0;
+ USBInit();
+ for (;;) {
+ switch (state) {
+ case 0: //inquiry and low-level connection
+ break;
+ case 1: {//initialisation
+ printf("Ready to open ports\n");
+ InitFtBtDeviceList();
+ int n = GetNrOfFtBtDevices();
+ printf("%d ft BT devices have been found\n", n);
+ if (n > 0) {
+ ftbtdev *d = GetFtUsbDeviceHandle(0);
+ if (d==0) printf("could not get device handle\n");
+ int sock = OpenFtBtDevice(d);
+ }
+ state = 2;
+ }
+ break;
+ case 2://main loop
+ break;
+ default:
+ break;
+ }
+ loop=1;
+ USBLoop();
+ loop=0;
+ n++;
+ if (n>=500000) {
+ n=0;
+ led = !led;
+ }
+ }
+ //printf("Dropped out of main loop!\n");
+}
+
+//********************************************************************************************************************************
--- a/Utils.cpp Mon Apr 04 16:41:03 2011 +0000
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,48 +0,0 @@
-
-
-#include "mbed.h"
-#include "Utils.h"
-
-void printfBytes(const char* s, const u8* data, int len)
-{
- printf("%s %d:",s,len);
- if (len > 256)
- len = 256;
- while (len-- > 0)
- printf(" %02X",*data++);
- printf("\n");
-}
-
-void printHexLine(const u8* d, int addr, int len)
-{
- printf("%04X ",addr);
- int i;
- for (i = 0; i < len; i++)
- printf("%02X ",d[i]);
- for (;i < 16; i++)
- printf(" ");
- char s[16+1];
- memset(s,0,sizeof(s));
- for (i = 0; i < len; i++)
- {
- int c = d[i];
- if (c < 0x20 || c > 0x7E)
- c = '.';
- s[i] = c;
- }
- printf("%s\n",s);
-}
-
-void printHex(const u8* d, int len)
-{
- int addr = 0;
- while (len)
- {
- int count = len;
- if (count > 16)
- count = 16;
- printHexLine(d+addr,addr,count);
- addr += 16;
- len -= count;
- }
-}
--- a/Utils.h Mon Apr 04 16:41:03 2011 +0000
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,37 +0,0 @@
-
-typedef unsigned char u8;
-typedef unsigned short u16;
-typedef unsigned long u32;
-
-void DelayMS(int ms);
-
-void printfBytes(const char* label,const u8* data, int len);
-void printHex(const u8* d, int len);
-
-#ifndef min
-#define min(_a,_b) ((_a) < (_b) ? (_a) : (_b))
-#endif
-
-inline int LE16(const u8* d)
-{
- return d[0] | (d[1] << 8);
-}
-
-inline u32 BE32(const u8* d)
-{
- return (d[0] << 24) | (d[1] << 16) | (d[2] << 8) | d[3];
-}
-
-inline void BE32(u32 n, u8* d)
-{
- d[0] = (u8)(n >> 24);
- d[1] = (u8)(n >> 16);
- d[2] = (u8)(n >> 8);
- d[3] = (u8)n;
-}
-
-inline void BE16(u32 n, u8* d)
-{
- d[0] = (u8)(n >> 8);
- d[1] = (u8)n;
-}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/ftclasslibusbdevbt.cpp Mon Apr 04 16:47:10 2011 +0000
@@ -0,0 +1,133 @@
+#include "mbed.h"
+#include <vector>
+#include "Utils.h"
+#include "hci.h"
+#include "ftclasslibusbdevbt.h"
+
+//extern HCI* gHCI;
+class application;
+extern application App;
+
+void printf(const BD_ADDR* addr);
+
+void ftdev::receive(int socket, SocketState state, const u8* data, int len) {
+ printf("ftdev::receive was called: socket %d, state=%d, length=%d\n", socket, state, len);
+ unsigned char req[] = "\xdget_ser_num\xd";
+ if (len==0) {
+ switch (state) {
+ case SocketState_Opening:
+ break;
+ case SocketState_Open:
+ printf("sending request \n%s\n", req);
+ Socket_Send(sock, req, strlen((char*)req));
+ break;
+ case SocketState_Closing:
+ case SocketState_Closed:
+ return;
+ }
+ } else {
+ //printHex(data, len);
+ parse(data, len);
+ if (state==SocketState_Open)
+ ;//Socket_Close(sock);//replace with ft primitive
+ }
+}
+
+unsigned short ftdev::chksum() {
+ unsigned short sum = (X1_len & 0xFF) + (X1_len >> 8);
+ for (int i = 0; i < X1_len; i++)
+ sum += X1_pkt[i];
+ return -sum;
+}
+
+void ftdev::parse (const unsigned char *buf, unsigned len) {
+ unsigned i = 0;
+ while (i < len) {
+ char c = buf[i++];
+ switch (parseState) {
+ case 0: //ascii state
+ if (c==2)
+ parseState = 1;
+ else
+ putc(c, stdout);
+ break;
+ case 1:
+ if (c==0x55)
+ parseState = 2;
+ else {
+ parseState = 0;
+ printf("expected 0x55 in X1 header, found %02X\n", c);
+ }
+ break;
+ case 2:
+ X1_len = c<<8;
+ parseState= 3;
+ break;
+ case 3:
+ X1_len += c;
+ parseState= 4;
+ X1_pkt = new unsigned char[X1_len];
+ X1_pos = 0;
+ break;
+ case 4:
+ if (X1_pos < X1_len) X1_pkt[X1_pos++] = c;
+ else parseState = 5;
+ break;
+ case 5:
+ X1_crc = c<<8;
+ parseState= 6;
+ break;
+ case 6:
+ X1_crc += c;
+ parseState= 7;
+ break;
+ case 7:
+ if (c == 3 && X1_crc == chksum()) {
+ //handlePkt();
+ printHex(X1_pkt, X1_len);
+ }else
+ printf("framing or checksum error, end char = %02X\n", c);
+
+ parseState = 0;
+ break;
+ }
+ }
+}
+
+vector<ftbtdev*> ft_devs;
+ftdev _ftdev; //single instance, just for test
+
+int GetNrOfFtBtDevices() {
+ return ft_devs.size();
+}
+
+unsigned InitFtBtDeviceList() {//assume inquiry has been done
+ static char FtDevClass[3] = {0x00, 0x1F, 0x82 };
+ BTDevice* devs[8];
+ int count = ((HCI*)&App)->GetDevices(devs,8);
+ int n = 0;
+ for (int i = 0; i < count; i++) {
+ if (memcmp(devs[i]->_info.dev_class, FtDevClass, 3)==0) {
+ ft_devs.push_back(new ftbtdev(&devs[i]->_info));
+ printf("%d: %s\n", n++, devs[i]->_name);
+ }
+// printf("device %d (handle=%d) ", i, devs[i]->_handle);
+// printfBytes("devclass: ", devs[i]->_info.dev_class, 3);
+ }
+ return n;
+}
+
+ftbtdev* GetFtUsbDeviceHandle(unsigned Num) {
+ if (Num < ft_devs.size()) {
+ return ft_devs[Num];
+ }
+ return 0;
+}
+
+unsigned OpenFtBtDevice(ftbtdev* d) {
+ BD_ADDR* bd = d->BtAddr();
+ printf("Connecting to ");
+ printf(bd);
+ printf("\n");
+ return _ftdev.Open(bd, 1); //TODO: everything can go wrong here
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/ftclasslibusbdevbt.h Mon Apr 04 16:47:10 2011 +0000
@@ -0,0 +1,47 @@
+#ifndef FTCLASSLIBUSBDEVBT_H
+#define FTCLASSLIBUSBDEVBT_H
+
+
+class ftbtdev {//small object for ft BT enumeration
+ inquiry_info info;
+public:
+ ftbtdev(inquiry_info* ii) {
+ info = *ii;
+ }
+ BD_ADDR* BtAddr() {
+ return &info.bdaddr;
+ }
+};
+
+class ftdev {//this should in the future encapsulate the real TXC
+ int sock;
+ int parseState;
+ unsigned short X1_crc, X1_len, X1_pos;
+ unsigned char *X1_pkt;
+ unsigned short chksum();
+ void parse(const unsigned char *, unsigned);
+public:
+ ftdev(): sock(0) { parseState = 0;}
+ int Open(BD_ADDR *bt_addr, int chan=1, SocketCallback cb=&ftdev::recv) {
+ L2CAPAddr s;
+ s.bdaddr = *bt_addr;
+ s.psm = chan;//abuse the psm for the channelID
+ sock = Socket_Open(SOCKET_RFCOM, &s.hdr, cb, this);//Open the serial connection via RFCOMM
+ if (sock<=0)
+ printf("Opening of RFCOMM socket for ftdevice failed (%d)\n", sock);
+ return sock;
+ }
+ static void recv(int socket, SocketState state, const u8* data, int len, void* userData) {
+ if (userData) ((ftdev*)userData)->receive(socket, state, data, len);
+ }
+ void receive(int socket, SocketState state, const u8* data, int len);// {printf("ftdev::receive was called: socket %d, state=%d, length=%d\n", socket, state, len);}
+};
+
+extern ftdev _ftdev;
+
+unsigned InitFtBtDeviceList();
+int GetNrOfFtBtDevices();
+ftbtdev* GetFtUsbDeviceHandle(unsigned Num);
+unsigned OpenFtBtDevice(ftbtdev* d);
+
+#endif
--- a/hci.cpp Mon Apr 04 16:41:03 2011 +0000
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,421 +0,0 @@
-
-/*
-Copyright (c) 2010 Peter Barrett
-
-Permission is hereby granted, free of charge, to any person obtaining a copy
-of this software and associated documentation files (the "Software"), to deal
-in the Software without restriction, including without limitation the rights
-to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-copies of the Software, and to permit persons to whom the Software is
-furnished to do so, subject to the following conditions:
-
-The above copyright notice and this permission notice shall be included in
-all copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
-THE SOFTWARE.
-*/
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <stdio.h>
-#include <string.h>
-
-#include "Utils.h"
-#include "hci.h"
-#include "hci_private.h"
-#include "USBHost.h" //for USBLoop
-
-enum hci_callback_evt {
- NONE,
- CONNECT,
- DISCONECT,
- INQUIRYRESULT
-};
-
-#define MAX_BLUETOOTH_ADAPTERS 1
-
-enum StateMask {
- MASK_RESET = 1,
- MASK_READ_BUFFER_SIZE = 2,
- MASK_READ_BD_ADDR = 4,
- MASK_INITED = 8,
- MASK_INQUIRY = 16,
- MASK_REMOTE_NAME = 32,
- MASK_CREATE_CONNECTION = 64
-};
-
-int HCI::Open(HCITransport* transport, HCICallback callback) {
- _transport = transport;
- _transport->Set(this);
- _callback = callback;
- _state = 0;
- for (int i = 0; i < MAX_BTDEVICES; i++) {
- _devices[i].Init();
- _devices[i]._transport = transport;
- }
- cmd_credits = 1;
- return SendCmd(HCI_OP_RESET);
-}
-
-void printf(const BD_ADDR* addr);
-
-BTDevice* HCI::Find(const BD_ADDR* addr) {
- for (int i = 0; i < MAX_BTDEVICES; i++)
- if (_devices[i]._state != 0 && memcmp(addr,&_devices[i]._info.bdaddr,6) == 0)
- return &_devices[i];
- return 0;
-}
-
-BTDevice* HCI::Find(int handle) {
- for (int i = 0; i < MAX_BTDEVICES; i++)
- if (_devices[i]._state != 0 && handle == _devices[i]._handle)
- return &_devices[i];
- return 0;
-}
-//
-bool HCI::Busy() {
- return (_state & (MASK_INQUIRY | MASK_REMOTE_NAME | MASK_CREATE_CONNECTION)) != 0;
-}
-
-int HCI::Inquiry(int duration) {
- _state |= MASK_INQUIRY;
- u8 buf[5];
- buf[0] = 0x33;//LAP=0x9e8b33
- buf[1] = 0x8B;
- buf[2] = 0x9E;
- buf[3] = duration;
- buf[4] = 5; // 5 results
- SendCmd(HCI_OP_INQUIRY,buf,sizeof(buf));
- return 0;
-}
-
-int HCI::SendCmd(int cmd, const u8* params, int len) {
- u8 b[32];
- b[0] = cmd;
- b[1] = (cmd >> 8);
- b[2] = len;
- if (params)
- memcpy(b+3,params,len);
- //printf("%d cmd_credits\n", cmd_credits);
- while (cmd_credits == 0) {
- USBLoop();
- putc('_', stdout);
- }
- _transport->HCISend(b,len+3);
- return 0;
-}
-
-void HCI::OnCommandComplete(int cmd, const u8* data, int len) {
- printf("%04X %s",cmd,CmdStr(cmd));
- if (len < 0)
- return;
- printfBytes(" complete",data,min(16,len));
-
- switch (cmd) {
- // Init phase 0
- case HCI_OP_RESET: // Reset done, init chain to HCI_OP_READ_LOCAL_NAME
- SendCmd(HCI_OP_READ_BUFFER_SIZE);
- _state |= MASK_RESET;
- break;
-
- // Init phase 1
- case HCI_OP_READ_BUFFER_SIZE:
- _acl_mtu = LE16(data);
- _sco_mtu = data[2];
- _acl_max_pkt = LE16(data+3);
- _sco_max_pkt = LE16(data+5);
- printf("acl_mtu=%d, acl_max_pkt=%d\n", _acl_mtu, _acl_max_pkt);
- SendCmd(HCI_OP_READ_BD_ADDR);
- _state |= MASK_READ_BUFFER_SIZE;
- break;
-
- // Init phase 2
- case HCI_OP_READ_BD_ADDR:
- _localAddr = *((BD_ADDR*)data); // Local Address
- _state |= MASK_READ_BD_ADDR;
- _state |= MASK_INITED;
- Callback(CALLBACK_READY,data,6);
- break;
-
- // 0CXX
- case HCI_OP_READ_LOCAL_NAME:
- case HCI_OP_LINK_KEY_NEG_REPLY:
- break;
-
- case HCI_OP_READ_LOCAL_VERSION:
- // params
- //SendCmd(HCI_OP_READ_LOCAL_NAME);
- break;
-
- case HCI_OP_READ_LOCAL_COMMANDS:
- break;
-
- case HCI_OP_READ_LOCAL_FEATURES:
- //SendCmd(HCI_OP_READ_LOCAL_VERSION);
- break;
-
- case HCI_OP_READ_LOCAL_EXT_FEATURES:
- break;
-
- case HCI_OP_PIN_CODE_REPLY:
- printf("Got pin reply\n");
- break;
-
- default:
- printf("Unrecognized Command %04X\n",cmd);
- break;
- }
-}
-
-void HCI::Callback(HCI_CALLBACK_EVENT c, const u8* data, int len) {
- if (_callback) _callback(this,c,data,len);
-// (this->*_callback)(c, data, len);
-}
-
-int HCI::RemoteNameRequest(const BD_ADDR* addr) {
- _state |= MASK_REMOTE_NAME;
- u8 buf[6+4];
- memset(buf,0,sizeof(buf));
- memcpy(buf,addr,6);
- //buf[7] = 1;
- return SendCmd(HCI_OP_REMOTE_NAME_REQ,buf,sizeof(buf));
-}
-int HCI::RemoteNameRequest(inquiry_info *ii) {
- _state |= MASK_REMOTE_NAME;
- u8 buf[6+4];
- //memset(buf,0,sizeof(buf));
- memcpy(buf,&ii->bdaddr,6);
- buf[6] = ii->pscan_rep_mode;
- buf[7] = 0;
- *(unsigned short*)(buf+8) = 0;
- return SendCmd(HCI_OP_REMOTE_NAME_REQ,buf,sizeof(buf));
-}
-
-
-int HCI::CreateConnection(const BD_ADDR* remoteAddr) {
- _state |= MASK_CREATE_CONNECTION;
- u8 buf[6+7];
- memset(buf,0,sizeof(buf));
- memcpy(buf,remoteAddr,6);
- buf[6] = 0x18; // DM1,DH1
- buf[7] = 0xCC; // DM3, DH3, DM5, DH5
- buf[8] = 1; // Page Repetition R1
- return SendCmd(HCI_OP_CREATE_CONN,buf,sizeof(buf));
-}
-
-int HCI::Disconnect(const BD_ADDR* bdaddr) {
- BTDevice* d = Find(bdaddr);
- if (!d)
- return ERR_HCI_DEVICE_NOT_FOUND;
- int handle = d->_handle;
- printf("Disconnect from %d\n",handle);
- _state |= MASK_CREATE_CONNECTION;
- u8 buf[3];
- buf[0] = handle;
- buf[1] = (handle >> 8);
- buf[2] = 0x13;
- return SendCmd(HCI_OP_DISCONNECT,buf,sizeof(buf));
-}
-
-void HCI::DisconnectComplete(int handle) {
- BTDevice* d = Find(handle);
- if (!d)
- return;
- d->_handle = 0;
-}
-
-int HCI::DisconnectAll() {
- BTDevice* devs[8];
- int count = GetDevices(devs,8);
- for (int i = 0; i < count; i++)
- Disconnect(&devs[i]->_info.bdaddr);
- return 0;
-}
-
-int HCI::PinCodeReply(const u8* data, const u8* pin) {
- u8 b[6+1+16];
- memset(b,0,sizeof(b));
- memcpy(b,data,6);
- b[6] = 4;
- memcpy(b+7, pin, 4);
- return SendCmd(HCI_OP_PIN_CODE_REPLY,b,sizeof(b));
-}
-
-void HCI::InquiryResult(const inquiry_info* info) {
- BTDevice* bt = Find(&info->bdaddr);
- if (!bt) { // new device
- for (int i = 0; i < MAX_BTDEVICES; i++) {
- if (_devices[i]._state == 0) {
- bt = _devices + i;
- bt->_state = 1;
- break;
- }
- }
- if (!bt) {
- printf("HCI::InquiryResult too many devices\n");
- return; // Too many devices!
- }
- }
-
- bt->_info = *info;
-}
-
-int HCI::GetDevices(BTDevice** devices, int maxDevices) {
- int j = 0;
- for (int i = 0; i < MAX_BTDEVICES; i++) {
- if (_devices[i]._state != 0) {
- devices[j++] = _devices + i;
- if (j == maxDevices)
- break;
- }
- }
- return j;
-}
-
-void HCI::RemoteName(const BD_ADDR* addr, const char* name) {
- BTDevice* d = Find(addr);
- if (d) {
- strncpy(d->_name,name,sizeof(d->_name)-1);
- d->_name[sizeof(d->_name)-1] = 0;
- }
-}
-
-void HCI::ConnectComplete(const connection_info* info) {
- BTDevice* d = Find(&info->bdaddr);
- if (!d)
- return;
- if (info->status == 0) {
- d->_handle = info->handle;
- printf("Connected on %04X\n",info->handle);
- } else
- printf("Connection failed with %d\n",info->status);
-}
-
-void HCI::HCIRecv(const u8* data, int len) {
- // printfBytes(EvtStr(data[0]),data,min(len,16));
- switch (data[0]) {
- case HCI_EV_INQUIRY_COMPLETE:
- printfBytes("Inquiry Complete",data,data[1]);
- _state &= ~MASK_INQUIRY;
- Callback(CALLBACK_INQUIRY_DONE,0,0);
- break;
-
- case HCI_EV_INQUIRY_RESULT: {
- const u8* end = data[1] + data + 2;
- data += 3;
- while (data < end) {
- inquiry_info align;
- memcpy(&align,data,sizeof(inquiry_info));
- InquiryResult(&align);
- Callback(CALLBACK_INQUIRY_RESULT,(u8*)&align,sizeof(inquiry_info));
- data += 14;
- }
- }
- break;
-
- case HCI_EV_CONN_COMPLETE:
- _state &= ~MASK_CREATE_CONNECTION;
- {
- connection_info align;
- memcpy(&align,data+2,sizeof(connection_info));
- ConnectComplete(&align);
- Callback(CALLBACK_CONNECTION_COMPLETE,(u8*)&align,sizeof(connection_info));
- }
- break;
-
- case HCI_EV_CONN_REQUEST:
- break;
-
- case HCI_EV_DISCONN_COMPLETE:
- DisconnectComplete(LE16(data+3));
- break;
-
- case HCI_EV_REMOTE_NAME: {
- BD_ADDR* addr = (BD_ADDR*)(data+3);
- const char* name = (const char*)(data + 9);
- RemoteName(addr,name);
- }
- Callback(CALLBACK_REMOTE_NAME,data+3,LE16(data+1)); // addr is in here too
- _state &= ~MASK_REMOTE_NAME;
- break;
-
- case HCI_EV_CMD_STATUS: {
- const char* errs = HCIErrStr(data[2]);
- printf("Status %s %s %d cmd pkts\n",CmdStr(LE16(data+4)),errs, data[3]);
- cmd_credits = data[3];
- }
- Callback(CALLBACK_CMD_STATUS, data+2, 4);
- break;
-
- case HCI_EV_CMD_COMPLETE:
- OnCommandComplete(data[3] | (data[4] << 8),data+6,data[1]-4);
- cmd_credits = data[2];
- break;
-
- case HCI_EV_PIN_CODE_REQ:
- Callback(CALLBACK_PIN_REQ, data+2, 6);
- //PinCodeReply(data+2);
- break;
-
- case HCI_EV_LINK_KEY_REQ:
- SendCmd(HCI_OP_LINK_KEY_NEG_REPLY,data+2,6);
- break;
- case HCI_EV_NUM_COMP_PKTS:
- case HCI_EV_LINK_KEY_NOTIFY:
- break;
- default:
-
- printfBytes("HCIRecv:",data,data[1]+2);
- break;
- }
-}
-
-int HCI::Open(SocketInternal* sock, SocketAddrHdr* addr) {
- L2CAPSocket* l2capsock = (L2CAPSocket*)sock;
- L2CAPAddr* l2capaddr = (L2CAPAddr*)addr;
- BTDevice* bt = Find(&l2capaddr->bdaddr);
- if (!bt) {
- printf("Can't open l2cap %d on ",l2capaddr->psm);
- printf(&l2capaddr->bdaddr);
- printf("\n");
- return ERR_HCI_DEVICE_NOT_FOUND;
- }
- l2capsock->btdevice = bt;
- return bt->Open(sock,addr);
-}
-
-int HCI::Send(SocketInternal* sock, const u8* data, int len) {//check here for appropriate buffersize on the device
-//assume acl packet
-#if OFFSET==8 //sizeof ACL/L2CAP is include in data/len
- if (len > _acl_max_pkt)
-#else //OFFSET==0, data is bare application frame
- if (len+8 > _acl_mtu)
-#endif
- { printf("Max outgoing packet(%d) size exceeded, segmenting necessary, pktlen = %d\n", _acl_mtu, len);
- }
- L2CAPSocket* l2capsock = (L2CAPSocket*)sock;
- return l2capsock->btdevice->Send(sock,data,len); // Pointless double dispatch
-}
-
-int HCI::Close(SocketInternal* sock) {
- L2CAPSocket* l2capsock = (L2CAPSocket*)sock;
- return l2capsock->btdevice->Close(sock); // Pointless double dispatch
-}
-
-void HCI::ACLRecv(const u8* data, int len) {
- int handle = LE16(data);
- BTDevice* d = Find(handle & 0x0FFF);
- if (d)
- d->ACLRecv(data,len);
- else
- printfBytes("HCI:ACLRecv ", data, len);
-}
-
-//===================================================================
-//===================================================================
--- a/hci.h Mon Apr 04 16:41:03 2011 +0000
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,253 +0,0 @@
-/*
-Copyright (c) 2010 Peter Barrett
-
-Permission is hereby granted, free of charge, to any person obtaining a copy
-of this software and associated documentation files (the "Software"), to deal
-in the Software without restriction, including without limitation the rights
-to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-copies of the Software, and to permit persons to whom the Software is
-furnished to do so, subject to the following conditions:
-
-The above copyright notice and this permission notice shall be included in
-all copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
-THE SOFTWARE.
-*/
-
-#ifndef HCI_H_INCLUDED
-#define HCI_H_INCLUDED
-
-#include "mbed.h"
-#include "Socket.h"
-
-#pragma pack(1)
-
-#define ERR_HCI_DEVICE_NOT_FOUND -300
-
-class HCI;
-class HCITransport;
-class BTDevice;
-
-typedef struct
-{
- u8 addr[6];
-} BD_ADDR;
-
-typedef struct
-{
- BD_ADDR bdaddr;
- u8 pscan_rep_mode;
- u8 pscan_period_mode;
- u8 pscan_mode;
- u8 dev_class[3];
- u16 clock_offset;
-} inquiry_info;
-
-typedef struct
-{
- u8 status;
- u16 handle;
- BD_ADDR bdaddr;
- u8 link_type;
- u8 encr_mode;
-} connection_info;
-
-// Address struct for creating L2CAP sockets
-typedef struct {
- SocketAddrHdr hdr;
- BD_ADDR bdaddr;
- u16 psm;
-} L2CAPAddr;
-
-typedef struct {
- u16 handle;
- u16 length; // total
- u16 l2capLength; // length -4
- u16 cid; // Signaling packet CID = 1
-
- // Payload
- u8 cmd; //
- u8 id;
- u16 cmdLength; // total-8
- u16 params[4]; // Params
-} L2CAPCmd;
-
-#pragma pack(4)
-
-class BTDevice;
-typedef struct
-{
- public:
- SocketInternal si;
- BTDevice* btdevice;
- u16 scid;
- u16 dcid;
-} L2CAPSocket;
-
-#define MAX_HCL_NAME_LENGTH 20 // TODO - BTDevice wants to be a multiple of 4
-
-// BTDevice encapsulates individual device state
-// It provides L2CAP layer sockets
-
-class BTDevice : public SocketHandler
-{
- public:
- HCITransport* _transport;
- inquiry_info _info;
- u16 _handle; // acl connection handle
- u8 _state; // connection state
- u8 _txid;
- u16 peer_mtu;
- char _name[MAX_HCL_NAME_LENGTH];
-
- void Init();
-
- BD_ADDR* GetAddress() { return &_info.bdaddr; }
-
- // Called from HCI
- void ACLRecv(const u8* data, int len);
- void ACLFwd(const u8* data, int len);
-
- // SocketHandler
- virtual int Open(SocketInternal* sock, SocketAddrHdr* addr);
- virtual int Send(SocketInternal* sock, const u8* data, int len);
- virtual int Close(SocketInternal* sock);
- virtual char* Name() { return "BTDevice SocketHandler";}
-
-private:
- int l2cap_sock, plen, contPos, contState;
- unsigned char *contBuf;
- Timeout rtx;
- L2CAPCmd last_req;
- void repeat_cmd();
-
- L2CAPSocket* SCIDToSocket(int scid);
- int Send(const u8* data, int len);
- int Send(u8 c, u8 id, u16* params, int count);
- int Connect(int scid, int psm);
- int Disconnect(int scid, int dcid);
- int ConfigureRequest(int dcid);
- int ConfigureResponse(u8 rxid, int dcid);
- int DisconnectResponse(u8 rxid, int scid, int dcid);
- void Control(const u8* data, int len);
-};
-
-enum HCI_CALLBACK_EVENT
-{
- CALLBACK_NONE,
- CALLBACK_READY,
- CALLBACK_INQUIRY_RESULT,
- CALLBACK_INQUIRY_DONE,
- CALLBACK_REMOTE_NAME,
- CALLBACK_CONNECTION_COMPLETE,
- CALLBACK_CONNECTION_FAILED,
- CALLBACK_PIN_REQ,
- CALLBACK_CMD_STATUS
-};
-
-// L2CAP Protocol/Service Multiplexor (PSM) values
-
-#define L2CAP_PSM_ANY 0x0000 /* Any/Invalid PSM */
-#define L2CAP_PSM_SDP 0x0001 /* Service Discovery Protocol */
-#define L2CAP_PSM_RFCOMM 0x0003 /* RFCOMM protocol */
-#define L2CAP_PSM_TCP 0x0005 /* Telephony Control Protocol */
-#define L2CAP_PSM_TCS 0x0007 /* TCS cordless */
-#define L2CAP_PSM_BNEP 0x000f /* Bluetooth Network Encapsulation Protocol*/
-#define L2CAP_PSM_HID_CNTL 0x0011 /* HID Control */
-#define L2CAP_PSM_HID_INTR 0x0013 /* HID Interrupt */
-#define L2CAP_PSM_ESDP 0x0015 /* Extended Service Discovery Profile */
-#define L2CAP_PSM_AVCTP 0x0017 /* Audio/Visual Control Transport Protocol */
-#define L2CAP_PSM_AVDTP 0x0019 /* Audio/Visual Distribution */
-
-// Callback from inquiry
-typedef int (*HCICallback)(HCI* hci, HCI_CALLBACK_EVENT evt, const u8* data, int len);
-//typedef int (HCI::*HCICallback)(HCI_CALLBACK_EVENT evt, const u8* data, int len);
-
-#define MAX_BTDEVICES 8
-
-class HCITransport;
-class HCI : public SocketHandler
-{
- HCITransport* _transport;
- HCICallback _callback;
- BD_ADDR _localAddr;
-
- BTDevice _devices[MAX_BTDEVICES];
- int _deviceCount;
-
- int _acl_mtu;
- int _acl_max_pkt;
- int _sco_mtu;
- int _sco_max_pkt;
-
- int _state;
-char cmd_credits, data_credits;
- public:
-
- // Open a local adapter
- int Open(HCITransport* transport, HCICallback callback=0);
-
- // Return list of discovered addreses
- int GetDevices(BTDevice** devices, int maxDevices);
-
- // Lookup a device by address or handle
- BTDevice* Find(const BD_ADDR* addr);
- BTDevice* Find(int handle);
-
- // Disconnect from a remote device
- int Disconnect(const BD_ADDR* addr);
- int DisconnectAll();
-
- // see what devies are in the system
- int Inquiry(int duration = 10);
-
- // get a name, delivered in callback
- int RemoteNameRequest(const BD_ADDR* addr);
- int RemoteNameRequest(inquiry_info* ii);
-
- // Connect to a remote device
- int CreateConnection(const BD_ADDR* remoteAddr);
-
- bool Busy();
-
- // called from transport
- void HCIRecv(const u8* data, int len);
-
- // called from transport
- void ACLRecv(const u8* data, int len);
-
- // SocketHandler methods for maintaining L2CAP sockets
- virtual int Open(SocketInternal* sock, SocketAddrHdr* addr);
- virtual int Send(SocketInternal* sock, const u8* data, int len);
- virtual int Close(SocketInternal* sock);
- virtual char* Name() { return "HCI SocketHandler";}
-
-private:
- void InquiryResult(const inquiry_info* info);
- void RemoteName(const BD_ADDR* addr, const char* name);
- void ConnectComplete(const connection_info* info);
- void DisconnectComplete(int handle);
- int SendCmd(int cmd, const u8* params = 0, int len = 0);
- void OnCommandComplete(int cmd, const u8* data, int len);
- virtual void Callback(HCI_CALLBACK_EVENT c, const u8* data, int len);
-protected:
- int PinCodeReply(const u8* data, const u8* pin = "0000");
-};
-
-class HCITransport
-{
-protected:
- HCI* _target;
-public:
- void Set(HCI* target) { _target = target; };
- virtual void HCISend(const u8* data, int len) = 0;
- virtual void ACLSend(const u8* data, int len) = 0;
-};
-
-#endif
--- a/hci_private.h Mon Apr 04 16:41:03 2011 +0000
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,323 +0,0 @@
-/*
-Copyright (c) 2010 Peter Barrett
-
-Permission is hereby granted, free of charge, to any person obtaining a copy
-of this software and associated documentation files (the "Software"), to deal
-in the Software without restriction, including without limitation the rights
-to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-copies of the Software, and to permit persons to whom the Software is
-furnished to do so, subject to the following conditions:
-
-The above copyright notice and this permission notice shall be included in
-all copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
-THE SOFTWARE.
-*/
-
-#ifndef HCI_PRIVATE_H_INCLUDED
-#define HCI_PRIVATE_H_INCLUDED
-
-#define HCI_OP_INQUIRY 0x0401
-#define HCI_OP_INQUIRY_CANCEL 0x0402
-#define HCI_OP_EXIT_PERIODIC_INQ 0x0404
-#define HCI_OP_CREATE_CONN 0x0405
-#define HCI_OP_DISCONNECT 0x0406
-#define HCI_OP_ADD_SCO 0x0407
-#define HCI_OP_CREATE_CONN_CANCEL 0x0408
-#define HCI_OP_ACCEPT_CONN_REQ 0x0409
-#define HCI_OP_REJECT_CONN_REQ 0x040a
-#define HCI_OP_LINK_KEY_REPLY 0x040b
-#define HCI_OP_LINK_KEY_NEG_REPLY 0x040c
-#define HCI_OP_PIN_CODE_REPLY 0x040d
-#define HCI_OP_PIN_CODE_NEG_REPLY 0x040e
-#define HCI_OP_CHANGE_CONN_PTYPE 0x040f
-#define HCI_OP_AUTH_REQUESTED 0x0411
-#define HCI_OP_SET_CONN_ENCRYPT 0x0413
-#define HCI_OP_CHANGE_CONN_LINK_KEY 0x0415
-#define HCI_OP_REMOTE_NAME_REQ 0x0419
-#define HCI_OP_REMOTE_NAME_REQ_CANCEL 0x041a
-#define HCI_OP_READ_REMOTE_FEATURES 0x041b
-#define HCI_OP_READ_REMOTE_EXT_FEATURES 0x041c
-#define HCI_OP_READ_REMOTE_VERSION 0x041d
-#define HCI_OP_SETUP_SYNC_CONN 0x0428
-#define HCI_OP_ACCEPT_SYNC_CONN_REQ 0x0429
-#define HCI_OP_REJECT_SYNC_CONN_REQ 0x042a
-
-#define HCI_OP_SNIFF_MODE 0x0803
-#define HCI_OP_EXIT_SNIFF_MODE 0x0804
-#define HCI_OP_ROLE_DISCOVERY 0x0809
-#define HCI_OP_SWITCH_ROLE 0x080b
-#define HCI_OP_READ_LINK_POLICY 0x080c
-#define HCI_OP_WRITE_LINK_POLICY 0x080d
-#define HCI_OP_READ_DEF_LINK_POLICY 0x080e
-#define HCI_OP_WRITE_DEF_LINK_POLICY 0x080f
-#define HCI_OP_SNIFF_SUBRATE 0x0811
-
-
-#define HCI_OP_SET_EVENT_MASK 0x0c01
-#define HCI_OP_RESET 0x0c03
-#define HCI_OP_SET_EVENT_FLT 0x0c05
-#define HCI_OP_WRITE_LOCAL_NAME 0x0c13
-#define HCI_OP_READ_LOCAL_NAME 0x0c14
-#define HCI_OP_WRITE_CA_TIMEOUT 0x0c16
-#define HCI_OP_WRITE_PG_TIMEOUT 0x0c18
-#define HCI_OP_WRITE_SCAN_ENABLE 0x0c1a
-#define HCI_OP_READ_AUTH_ENABLE 0x0c1f
-#define HCI_OP_WRITE_AUTH_ENABLE 0x0c20
-#define HCI_OP_READ_ENCRYPT_MODE 0x0c21
-#define HCI_OP_WRITE_ENCRYPT_MODE 0x0c22
- #define ENCRYPT_DISABLED 0x00
- #define ENCRYPT_P2P 0x01
- #define ENCRYPT_BOTH 0x02
-#define HCI_OP_READ_CLASS_OF_DEV 0x0c23
-#define HCI_OP_WRITE_CLASS_OF_DEV 0x0c24
-#define HCI_OP_READ_VOICE_SETTING 0x0c25
-#define HCI_OP_WRITE_VOICE_SETTING 0x0c26
-#define HCI_OP_HOST_BUFFER_SIZE 0x0c33
-#define HCI_OP_READ_SSP_MODE 0x0c55
-#define HCI_OP_WRITE_SSP_MODE 0x0c56
-
-#define HCI_OP_READ_LOCAL_VERSION 0x1001
-#define HCI_OP_READ_LOCAL_COMMANDS 0x1002
-#define HCI_OP_READ_LOCAL_FEATURES 0x1003
-#define HCI_OP_READ_LOCAL_EXT_FEATURES 0x1004
-#define HCI_OP_READ_BUFFER_SIZE 0x1005
-#define HCI_OP_READ_BD_ADDR 0x1009
-
-// events
-#define HCI_EV_INQUIRY_COMPLETE 0x01
-#define HCI_EV_INQUIRY_RESULT 0x02
-#define HCI_EV_CONN_COMPLETE 0x03
-#define HCI_EV_CONN_REQUEST 0x04
-#define HCI_EV_DISCONN_COMPLETE 0x05
-#define HCI_EV_AUTH_COMPLETE 0x06
-#define HCI_EV_REMOTE_NAME 0x07
-#define HCI_EV_ENCRYPT_CHANGE 0x08
-#define HCI_EV_CHANGE_LINK_KEY_COMPLETE 0x09
-#define HCI_EV_REMOTE_FEATURES 0x0b
-#define HCI_EV_REMOTE_VERSION 0x0c
-#define HCI_EV_QOS_SETUP_COMPLETE 0x0d
-#define HCI_EV_CMD_COMPLETE 0x0e
-#define HCI_EV_CMD_STATUS 0x0f
-#define HCI_EV_ROLE_CHANGE 0x12
-#define HCI_EV_NUM_COMP_PKTS 0x13
-#define HCI_EV_MODE_CHANGE 0x14
-#define HCI_EV_PIN_CODE_REQ 0x16
-#define HCI_EV_LINK_KEY_REQ 0x17
-#define HCI_EV_LINK_KEY_NOTIFY 0x18
-#define HCI_EV_CLOCK_OFFSET 0x1c
-#define HCI_EV_PKT_TYPE_CHANGE 0x1d
-#define HCI_EV_PSCAN_REP_MODE 0x20
-#define HCI_EV_INQUIRY_RESULT_WITH_RSSI 0x22
-#define HCI_EV_REMOTE_EXT_FEATURES 0x23
-#define HCI_EV_SYNC_CONN_COMPLETE 0x2c
-#define HCI_EV_SYNC_CONN_CHANGED 0x2d
-#define HCI_EV_SNIFF_SUBRATE 0x2e
-#define HCI_EV_EXTENDED_INQUIRY_RESULT 0x2f
-#define HCI_EV_IO_CAPA_REQUEST 0x31
-#define HCI_EV_SIMPLE_PAIR_COMPLETE 0x36
-#define HCI_EV_REMOTE_HOST_FEATURES 0x3d
-
-/* Possible error codes */
-#define HCI_UNKNOWN_HCI_COMMAND 0x01
-#define HCI_NO_CONNECTION 0x02
-#define HCI_HW_FAILURE 0x03
-#define HCI_PAGE_TIMEOUT 0x04
-#define HCI_AUTHENTICATION_FAILURE 0x05
-#define HCI_KEY_MISSING 0x06
-#define HCI_MEMORY_FULL 0x07
-#define HCI_CONN_TIMEOUT 0x08
-#define HCI_MAX_NUMBER_OF_CONNECTIONS 0x09
-#define HCI_MAX_NUMBER_OF_SCO_CONNECTIONS_TO_DEVICE 0x0A
-#define HCI_ACL_CONNECTION_EXISTS 0x0B
-#define HCI_COMMAND_DISSALLOWED 0x0C
-#define HCI_HOST_REJECTED_DUE_TO_LIMITED_RESOURCES 0x0D
-#define HCI_HOST_REJECTED_DUE_TO_SECURITY_REASONS 0x0E
-#define HCI_HOST_REJECTED_DUE_TO_REMOTE_DEVICE_ONLY_PERSONAL_SERVICE 0x0F
-#define HCI_HOST_TIMEOUT 0x10
-#define HCI_UNSUPPORTED_FEATURE_OR_PARAMETER_VALUE 0x11
-#define HCI_INVALID_HCI_COMMAND_PARAMETERS 0x12
-#define HCI_OTHER_END_TERMINATED_CONN_USER_ENDED 0x13
-#define HCI_OTHER_END_TERMINATED_CONN_LOW_RESOURCES 0x14
-#define HCI_OTHER_END_TERMINATED_CONN_ABOUT_TO_POWER_OFF 0x15
-#define HCI_CONN_TERMINATED_BY_LOCAL_HOST 0x16
-#define HCI_REPETED_ATTEMPTS 0x17
-#define HCI_PAIRING_NOT_ALLOWED 0x18
-#define HCI_UNKNOWN_LMP_PDU 0x19
-#define HCI_UNSUPPORTED_REMOTE_FEATURE 0x1A
-#define HCI_SCO_OFFSET_REJECTED 0x1B
-#define HCI_SCO_INTERVAL_REJECTED 0x1C
-#define HCI_SCO_AIR_MODE_REJECTED 0x1D
-#define HCI_INVALID_LMP_PARAMETERS 0x1E
-#define HCI_UNSPECIFIED_ERROR 0x1F
-#define HCI_UNSUPPORTED_LMP_PARAMETER_VALUE 0x20
-#define HCI_ROLE_CHANGE_NOT_ALLOWED 0x21
-#define HCI_LMP_RESPONSE_TIMEOUT 0x22
-#define HCI_LMP_ERROR_TRANSACTION_COLLISION 0x23
-#define HCI_LMP_PDU_NOT_ALLOWED 0x24
-#define HCI_ENCRYPTION_MODE_NOT_ACCEPTABLE 0x25
-#define HCI_UNIT_KEY_USED 0x26
-#define HCI_QOS_NOT_SUPPORTED 0x27
-#define HCI_INSTANT_PASSED 0x28
-#define HCI_PAIRING_UNIT_KEY_NOT_SUPPORTED 0x29
-
-const char* EvtStr(int evt)
-{
- switch (evt)
- {
- case HCI_EV_INQUIRY_COMPLETE: return "HCI_EV_INQUIRY_COMPLETE";
- case HCI_EV_INQUIRY_RESULT: return "HCI_EV_INQUIRY_RESULT";
- case HCI_EV_CONN_COMPLETE: return "HCI_EV_CONN_COMPLETE";
- case HCI_EV_CONN_REQUEST: return "HCI_EV_CONN_REQUEST";
- case HCI_EV_DISCONN_COMPLETE: return "HCI_EV_DISCONN_COMPLETE";
- case HCI_EV_AUTH_COMPLETE: return "HCI_EV_AUTH_COMPLETE";
- case HCI_EV_REMOTE_NAME: return "HCI_EV_REMOTE_NAME";
- case HCI_EV_ENCRYPT_CHANGE: return "HCI_EV_ENCRYPT_CHANGE";
- case HCI_EV_CHANGE_LINK_KEY_COMPLETE : return "HCI_EV_CHANGE_LINK_KEY_COMPLETE";
- case HCI_EV_REMOTE_FEATURES: return "HCI_EV_REMOTE_FEATURES";
- case HCI_EV_REMOTE_VERSION: return "HCI_EV_REMOTE_VERSION";
- case HCI_EV_QOS_SETUP_COMPLETE : return "HCI_EV_QOS_SETUP_COMPLETE";
- case HCI_EV_CMD_COMPLETE: return "HCI_EV_CMD_COMPLETE";
- case HCI_EV_CMD_STATUS: return "HCI_EV_CMD_STATUS";
- case HCI_EV_ROLE_CHANGE: return "HCI_EV_ROLE_CHANGE";
- case HCI_EV_NUM_COMP_PKTS: return "HCI_EV_NUM_COMP_PKTS";
- case HCI_EV_MODE_CHANGE: return "HCI_EV_MODE_CHANGE";
- case HCI_EV_PIN_CODE_REQ: return "HCI_EV_PIN_CODE_REQ";
- case HCI_EV_LINK_KEY_REQ: return "HCI_EV_LINK_KEY_REQ";
- case HCI_EV_LINK_KEY_NOTIFY: return "HCI_EV_LINK_KEY_NOTIFY";
- case HCI_EV_CLOCK_OFFSET: return "HCI_EV_CLOCK_OFFSET";
- case HCI_EV_PKT_TYPE_CHANGE: return "HCI_EV_PKT_TYPE_CHANGE";
- case HCI_EV_PSCAN_REP_MODE: return "HCI_EV_PSCAN_REP_MODE";
- case HCI_EV_INQUIRY_RESULT_WITH_RSSI : return "HCI_EV_INQUIRY_RESULT_WITH_RSSI";
- case HCI_EV_REMOTE_EXT_FEATURES: return "HCI_EV_REMOTE_EXT_FEATURES";
- case HCI_EV_SYNC_CONN_COMPLETE: return "HCI_EV_SYNC_CONN_COMPLETE";
- case HCI_EV_SYNC_CONN_CHANGED: return "HCI_EV_SYNC_CONN_CHANGED";
- case HCI_EV_SNIFF_SUBRATE: return "HCI_EV_SNIFF_SUBRATE";
- case HCI_EV_EXTENDED_INQUIRY_RESULT: return "HCI_EV_EXTENDED_INQUIRY_RESULT";
- case HCI_EV_IO_CAPA_REQUEST: return "HCI_EV_IO_CAPA_REQUEST";
- case HCI_EV_SIMPLE_PAIR_COMPLETE: return "HCI_EV_SIMPLE_PAIR_COMPLETE";
- case HCI_EV_REMOTE_HOST_FEATURES: return "HCI_EV_REMOTE_HOST_FEATURES";
- }
- return "Unknown Event";
-}
-
-const char* CmdStr(int cmd)
-{
- switch (cmd)
- {
- // 0x04XX
- case HCI_OP_INQUIRY: return "HCI_OP_INQUIRY";
- case HCI_OP_INQUIRY_CANCEL: return "HCI_OP_INQUIRY_CANCEL";
- case HCI_OP_EXIT_PERIODIC_INQ: return "HCI_OP_EXIT_PERIODIC_INQ";
- case HCI_OP_CREATE_CONN: return "HCI_OP_CREATE_CONN";
- case HCI_OP_DISCONNECT: return "HCI_OP_DISCONNECT";
- case HCI_OP_ADD_SCO: return "HCI_OP_ADD_SCO";
- case HCI_OP_CREATE_CONN_CANCEL: return "HCI_OP_CREATE_CONN_CANCEL";
- case HCI_OP_ACCEPT_CONN_REQ: return "HCI_OP_ACCEPT_CONN_REQ";
- case HCI_OP_REJECT_CONN_REQ: return "HCI_OP_REJECT_CONN_REQ";
- case HCI_OP_LINK_KEY_REPLY: return "HCI_OP_LINK_KEY_REPLY";
- case HCI_OP_LINK_KEY_NEG_REPLY: return "HCI_OP_LINK_KEY_NEG_REPLY";
- case HCI_OP_PIN_CODE_REPLY: return "HCI_OP_PIN_CODE_REPLY";
- case HCI_OP_PIN_CODE_NEG_REPLY: return "HCI_OP_PIN_CODE_NEG_REPLY";
- case HCI_OP_CHANGE_CONN_PTYPE: return "HCI_OP_CHANGE_CONN_PTYPE";
- case HCI_OP_AUTH_REQUESTED: return "HCI_OP_AUTH_REQUESTED";
- case HCI_OP_SET_CONN_ENCRYPT: return "HCI_OP_SET_CONN_ENCRYPT";
- case HCI_OP_CHANGE_CONN_LINK_KEY: return "HCI_OP_CHANGE_CONN_LINK_KEY";
- case HCI_OP_REMOTE_NAME_REQ: return "HCI_OP_REMOTE_NAME_REQ";
- case HCI_OP_REMOTE_NAME_REQ_CANCEL: return "HCI_OP_REMOTE_NAME_REQ_CANCEL";
- case HCI_OP_READ_REMOTE_FEATURES: return "HCI_OP_READ_REMOTE_FEATURES";
- case HCI_OP_READ_REMOTE_EXT_FEATURES: return "HCI_OP_READ_REMOTE_EXT_FEATURES";
- case HCI_OP_READ_REMOTE_VERSION: return "HCI_OP_READ_REMOTE_VERSION";
- case HCI_OP_SETUP_SYNC_CONN: return "HCI_OP_SETUP_SYNC_CONN";
- case HCI_OP_ACCEPT_SYNC_CONN_REQ: return "HCI_OP_ACCEPT_SYNC_CONN_REQ";
- case HCI_OP_REJECT_SYNC_CONN_REQ: return "HCI_OP_REJECT_SYNC_CONN_REQ";
- // 0x0CXX
- case HCI_OP_SET_EVENT_MASK: return "HCI_OP_SET_EVENT_MASK";
- case HCI_OP_RESET: return "HCI_OP_RESET";
- case HCI_OP_SET_EVENT_FLT: return "HCI_OP_SET_EVENT_FLT";
- case HCI_OP_WRITE_LOCAL_NAME: return "HCI_OP_WRITE_LOCAL_NAME";
- case HCI_OP_READ_LOCAL_NAME: return "HCI_OP_READ_LOCAL_NAME";
- case HCI_OP_WRITE_CA_TIMEOUT: return "HCI_OP_WRITE_CA_TIMEOUT";
- case HCI_OP_WRITE_PG_TIMEOUT: return "HCI_OP_WRITE_PG_TIMEOUT";
- case HCI_OP_WRITE_SCAN_ENABLE: return "HCI_OP_WRITE_SCAN_ENABLE";
- case HCI_OP_READ_AUTH_ENABLE: return "HCI_OP_READ_AUTH_ENABLE";
- case HCI_OP_WRITE_AUTH_ENABLE: return "HCI_OP_WRITE_AUTH_ENABLE";
- case HCI_OP_READ_ENCRYPT_MODE: return "HCI_OP_READ_ENCRYPT_MODE";
- case HCI_OP_WRITE_ENCRYPT_MODE: return "HCI_OP_WRITE_ENCRYPT_MODE";
- case HCI_OP_READ_CLASS_OF_DEV: return "HCI_OP_READ_CLASS_OF_DEV";
- case HCI_OP_WRITE_CLASS_OF_DEV: return "HCI_OP_WRITE_CLASS_OF_DEV";
- case HCI_OP_READ_VOICE_SETTING: return "HCI_OP_READ_VOICE_SETTING";
- case HCI_OP_WRITE_VOICE_SETTING: return "HCI_OP_WRITE_VOICE_SETTING";
- case HCI_OP_HOST_BUFFER_SIZE: return "HCI_OP_HOST_BUFFER_SIZE";
- case HCI_OP_READ_SSP_MODE: return "HCI_OP_READ_SSP_MODE";
- case HCI_OP_WRITE_SSP_MODE: return "HCI_OP_WRITE_SSP_MODE";
-
- // 10xx
- case HCI_OP_READ_LOCAL_VERSION: return "HCI_OP_READ_LOCAL_VERSION";
- case HCI_OP_READ_LOCAL_COMMANDS: return "HCI_OP_READ_LOCAL_COMMANDS";
- case HCI_OP_READ_LOCAL_FEATURES: return "HCI_OP_READ_LOCAL_FEATURES";
- case HCI_OP_READ_LOCAL_EXT_FEATURES: return "HCI_OP_READ_LOCAL_EXT_FEATURES";
- case HCI_OP_READ_BUFFER_SIZE: return "HCI_OP_READ_BUFFER_SIZE";
- case HCI_OP_READ_BD_ADDR: return "HCI_OP_READ_BD_ADDR";
- }
- return "Unknown Cmd";
-}
-
-const char* HCIErrStr(int err)
-{
- switch (err)
- {
- case 0: return "OK";
- case HCI_UNKNOWN_HCI_COMMAND: return "HCI_UNKNOWN_HCI_COMMAND";
- case HCI_NO_CONNECTION: return "HCI_NO_CONNECTION";
- case HCI_HW_FAILURE: return "HCI_HW_FAILURE";
- case HCI_PAGE_TIMEOUT: return "HCI_PAGE_TIMEOUT";
- case HCI_AUTHENTICATION_FAILURE: return "HCI_AUTHENTICATION_FAILURE";
- case HCI_KEY_MISSING: return "HCI_KEY_MISSING";
- case HCI_MEMORY_FULL: return "HCI_MEMORY_FULL";
- case HCI_CONN_TIMEOUT: return "HCI_CONN_TIMEOUT";
- case HCI_MAX_NUMBER_OF_CONNECTIONS: return "HCI_CONN_TIMEOUT";
- case HCI_MAX_NUMBER_OF_SCO_CONNECTIONS_TO_DEVICE: return "HCI_MAX_NUMBER_OF_SCO_CONNECTIONS_TO_DEVICE";
- case HCI_ACL_CONNECTION_EXISTS: return "HCI_ACL_CONNECTION_EXISTS";
- case HCI_COMMAND_DISSALLOWED: return "HCI_COMMAND_DISSALLOWED";
- case HCI_HOST_REJECTED_DUE_TO_LIMITED_RESOURCES: return "HCI_HOST_REJECTED_DUE_TO_LIMITED_RESOURCES";
- case HCI_HOST_REJECTED_DUE_TO_SECURITY_REASONS: return "HCI_HOST_REJECTED_DUE_TO_SECURITY_REASONS";
- case HCI_HOST_REJECTED_DUE_TO_REMOTE_DEVICE_ONLY_PERSONAL_SERVICE: return "HCI_HOST_REJECTED_DUE_TO_REMOTE_DEVICE_ONLY_PERSONAL_SERVICE";
- case HCI_HOST_TIMEOUT: return "HCI_HOST_TIMEOUT";
- case HCI_UNSUPPORTED_FEATURE_OR_PARAMETER_VALUE: return "HCI_UNSUPPORTED_FEATURE_OR_PARAMETER_VALUE";
- case HCI_INVALID_HCI_COMMAND_PARAMETERS: return "HCI_INVALID_HCI_COMMAND_PARAMETERS";
- case HCI_OTHER_END_TERMINATED_CONN_USER_ENDED: return "HCI_OTHER_END_TERMINATED_CONN_USER_ENDED";
- case HCI_OTHER_END_TERMINATED_CONN_LOW_RESOURCES: return "HCI_OTHER_END_TERMINATED_CONN_LOW_RESOURCES";
- case HCI_OTHER_END_TERMINATED_CONN_ABOUT_TO_POWER_OFF: return "HCI_OTHER_END_TERMINATED_CONN_ABOUT_TO_POWER_OFF";
- case HCI_CONN_TERMINATED_BY_LOCAL_HOST: return "HCI_CONN_TERMINATED_BY_LOCAL_HOST";
- case HCI_REPETED_ATTEMPTS: return "HCI_REPETED_ATTEMPTS";
- case HCI_PAIRING_NOT_ALLOWED: return "HCI_PAIRING_NOT_ALLOWED";
- case HCI_UNKNOWN_LMP_PDU: return "HCI_UNKNOWN_LMP_PDU";
- case HCI_UNSUPPORTED_REMOTE_FEATURE: return "HCI_UNSUPPORTED_REMOTE_FEATURE";
- case HCI_SCO_OFFSET_REJECTED: return "HCI_SCO_OFFSET_REJECTED";
- case HCI_SCO_INTERVAL_REJECTED: return "HCI_SCO_INTERVAL_REJECTED";
- case HCI_SCO_AIR_MODE_REJECTED: return "HCI_SCO_AIR_MODE_REJECTED";
- case HCI_INVALID_LMP_PARAMETERS: return "HCI_INVALID_LMP_PARAMETERS";
- case HCI_UNSPECIFIED_ERROR: return "HCI_UNSPECIFIED_ERROR";
- case HCI_UNSUPPORTED_LMP_PARAMETER_VALUE: return "HCI_UNSUPPORTED_LMP_PARAMETER_VALUE";
- case HCI_ROLE_CHANGE_NOT_ALLOWED: return "HCI_ROLE_CHANGE_NOT_ALLOWED";
- case HCI_LMP_RESPONSE_TIMEOUT: return "HCI_LMP_RESPONSE_TIMEOUT";
- case HCI_LMP_ERROR_TRANSACTION_COLLISION: return "HCI_LMP_ERROR_TRANSACTION_COLLISION";
- case HCI_LMP_PDU_NOT_ALLOWED: return "HCI_LMP_PDU_NOT_ALLOWED";
- case HCI_ENCRYPTION_MODE_NOT_ACCEPTABLE: return "HCI_ENCRYPTION_MODE_NOT_ACCEPTABLE";
- case HCI_UNIT_KEY_USED: return "HCI_UNIT_KEY_USED";
- case HCI_QOS_NOT_SUPPORTED: return "HCI_QOS_NOT_SUPPORTED";
- case HCI_INSTANT_PASSED: return "HCI_INSTANT_PASSED";
- case HCI_PAIRING_UNIT_KEY_NOT_SUPPORTED: return "HCI_PAIRING_UNIT_KEY_NOT_SUPPORTED";
- };
- return "Unknow HCI err";
-};
-
-
-#endif // HCI_PRIVATE_H_INCLUDED
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/main.cpp Mon Apr 04 16:47:10 2011 +0000
@@ -0,0 +1,121 @@
+/*
+Copyright (c) 2010 Peter Barrett
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+THE SOFTWARE.
+*/
+
+#include "mbed.h"
+#include "USBHost.h"
+#include "Utils.h"
+#include "FATFileSystem.h"
+
+int MassStorage_ReadCapacity(int device, u32* blockCount, u32* blockSize);
+int MassStorage_Read(int device, u32 blockAddr, u32 blockCount, u8* dst, u32 blockSize);
+int MassStorage_Write(int device, u32 blockAddr, u32 blockCount, u8* dst, u32 blockSize);
+
+class USBFileSystem : public FATFileSystem
+{
+ int _device;
+ u32 _blockSize;
+ u32 _blockCount;
+
+public:
+ USBFileSystem() : FATFileSystem("usb"),_device(0),_blockSize(0),_blockCount(0)
+ {
+ }
+
+ void SetDevice(int device)
+ {
+ _device = device;
+ }
+
+ virtual int disk_initialize()
+ {
+ return MassStorage_ReadCapacity(_device,&_blockCount,&_blockSize);
+ }
+
+ virtual int disk_write(const char *buffer, int block_number)
+ {
+ return MassStorage_Write(_device,block_number,1,(u8*)buffer,_blockSize);
+ }
+
+ virtual int disk_read(char *buffer, int block_number)
+ {
+ return MassStorage_Read(_device,block_number,1,(u8*)buffer,_blockSize);
+ }
+
+ virtual int disk_sectors()
+ {
+ return _blockCount;
+ }
+};
+
+void DumpFS(int depth, int count)
+{
+ DIR *d = opendir("/usb");
+ if (!d)
+ {
+ printf("USB file system borked\n");
+ return;
+ }
+
+ printf("\nDumping root dir\n");
+ struct dirent *p;
+ for(;;)
+ {
+ p = readdir(d);
+ if (!p)
+ break;
+ int len = sizeof( dirent);
+ printf("%s %d\n", p->d_name, len);
+ }
+ closedir(d);
+}
+
+int OnDiskInsert(int device)
+{
+ USBFileSystem fs;
+ fs.SetDevice(device);
+ DumpFS(0,0);
+ return 0;
+}
+
+/*
+ Simple test shell to exercise mouse,keyboard,mass storage and hubs.
+ Add 2 15k pulldown resistors between D+/D- and ground, attach a usb socket and have at it.
+*/
+
+Serial pc(USBTX, USBRX);
+int GetConsoleChar()
+{
+ if (!pc.readable())
+ return -1;
+ char c = pc.getc();
+ pc.putc(c); // echo
+ return c;
+}
+
+void TestShell();
+
+int main()
+{
+ pc.baud(460800);
+ printf("BlueUSB\nNow get a bunch of usb or bluetooth things and plug them in\n");
+ TestShell();
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed.bld Mon Apr 04 16:47:10 2011 +0000 @@ -0,0 +1,1 @@ +http://mbed.org/users/mbed_official/code/mbed/builds/49a220cc26e0
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/myUSBHost.lib Mon Apr 04 16:47:10 2011 +0000 @@ -0,0 +1,1 @@ +http://mbed.org/users/networker/code/myUSBHost/#d6bff1c2dab1
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/rfcomm.lib Mon Apr 04 16:47:10 2011 +0000 @@ -0,0 +1,1 @@ +http://mbed.org/users/networker/code/rfcomm/#8d7b47ceb9f5
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/sdp.lib Mon Apr 04 16:47:10 2011 +0000 @@ -0,0 +1,1 @@ +http://mbed.org/users/networker/code/sdp/#7493bf6bb1b9