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

Committer:
networker
Date:
Fri Jul 01 09:16:00 2011 +0000
Revision:
13:327622e38551
made some improvements to get massstorage functioning

Who changed what in which revision?

UserRevisionLine numberNew contents of line
networker 13:327622e38551 1 #ifndef RFCOMM_H
networker 13:327622e38551 2 #define RFCOMM_H
networker 13:327622e38551 3 #include "USBHost.h"
networker 13:327622e38551 4 #include "hci.h"
networker 13:327622e38551 5 #include "Utils.h"
networker 13:327622e38551 6
networker 13:327622e38551 7 #define MAX_RFCOMM_SCKTS 4
networker 13:327622e38551 8 //#define MAX_FRAME_SIZE 350 //ACL buffer - some headroom
networker 13:327622e38551 9 #define MAX_FRAME_SIZE 127 //ft size
networker 13:327622e38551 10
networker 13:327622e38551 11 /*
networker 13:327622e38551 12 template <class T>
networker 13:327622e38551 13 T min(T a, T b) {
networker 13:327622e38551 14 return a<b ? a : b;
networker 13:327622e38551 15 }
networker 13:327622e38551 16 */
networker 13:327622e38551 17
networker 13:327622e38551 18 #define MASK_BITRATE 0X0001
networker 13:327622e38551 19 #define MASK_DATABITS 0X0002
networker 13:327622e38551 20 #define MASK_STOPBITS 0X0004
networker 13:327622e38551 21 #define MASK_PARITYBITS 0X0008
networker 13:327622e38551 22 #define MASK_PARITYTYPE 0X0010
networker 13:327622e38551 23 #define MASK_XONCHAR 0X0020
networker 13:327622e38551 24 #define MASK_XOFFCHAR 0X0040
networker 13:327622e38551 25 #define MASK_XONXOFFIN 0X0100
networker 13:327622e38551 26 #define MASK_XONXOFFOUT 0X0200
networker 13:327622e38551 27 #define MASK_RTRIN 0X0400
networker 13:327622e38551 28 #define MASK_RTROUT 0X0800
networker 13:327622e38551 29 #define MASK_RTCIN 0X1000
networker 13:327622e38551 30 #define MASK_RTCOUT 0X2000
networker 13:327622e38551 31
networker 13:327622e38551 32 struct port_settings {
networker 13:327622e38551 33 unsigned char baud;
networker 13:327622e38551 34 unsigned char bits:
networker 13:327622e38551 35 2;
networker 13:327622e38551 36 unsigned char stop:
networker 13:327622e38551 37 1;
networker 13:327622e38551 38 unsigned char par:
networker 13:327622e38551 39 1;
networker 13:327622e38551 40 unsigned char par_t:
networker 13:327622e38551 41 2;
networker 13:327622e38551 42 unsigned char :
networker 13:327622e38551 43 2;
networker 13:327622e38551 44 unsigned char flow:
networker 13:327622e38551 45 6;
networker 13:327622e38551 46 unsigned char :
networker 13:327622e38551 47 2;
networker 13:327622e38551 48 unsigned char xon;
networker 13:327622e38551 49 unsigned char xoff;
networker 13:327622e38551 50 unsigned short mask;
networker 13:327622e38551 51 };
networker 13:327622e38551 52
networker 13:327622e38551 53 class rfcomm;
networker 13:327622e38551 54 class RFCOMMManager;
networker 13:327622e38551 55 #define MAX_RFCOMM_DEVICES 8 //physical devices
networker 13:327622e38551 56
networker 13:327622e38551 57 class RFCOMMSocket: public SocketInternal {//this object must not be larger than SocketInternalPad (socketinternal + 8 bytes)
networker 13:327622e38551 58 public:
networker 13:327622e38551 59 rfcomm* serdevice;
networker 13:327622e38551 60 u8 dlci; //channel + D bit, D bit is inverted initiator bit
networker 13:327622e38551 61 u8 my_credits, peer_credits;
networker 13:327622e38551 62 };
networker 13:327622e38551 63
networker 13:327622e38551 64 class rfcomm: public SocketHandler {
networker 13:327622e38551 65 int _l2cap; //socket to the l2cap layer
networker 13:327622e38551 66 int _devClass;
networker 13:327622e38551 67 BD_ADDR _addr;
networker 13:327622e38551 68 u8 initiator;
networker 13:327622e38551 69 u8 _pad[0]; // Struct align
networker 13:327622e38551 70 char sckts[MAX_RFCOMM_SCKTS];
networker 13:327622e38551 71 //static
networker 13:327622e38551 72 unsigned maxframesize;
networker 13:327622e38551 73 int find_slot(unsigned ch);
networker 13:327622e38551 74 RFCOMMSocket* find_socket(unsigned dlci);
networker 13:327622e38551 75 void initChannels(int socket);
networker 13:327622e38551 76 unsigned release_channel(unsigned dlci);
networker 13:327622e38551 77 static void OnRfCommControl(int socket, SocketState state, const u8* data, int len, void* userData);//I guess this is called when data comes out of the socket
networker 13:327622e38551 78 int Disconnect(RFCOMMSocket*);
networker 13:327622e38551 79 public:
networker 13:327622e38551 80 rfcomm() : _l2cap(0), _devClass(0) {
networker 13:327622e38551 81 for (int i = 0; i < MAX_RFCOMM_SCKTS; i++) sckts[i] = 0;
networker 13:327622e38551 82 maxframesize = MAX_FRAME_SIZE;
networker 13:327622e38551 83 }
networker 13:327622e38551 84
networker 13:327622e38551 85 bool InUse() {
networker 13:327622e38551 86 return _l2cap != 0;
networker 13:327622e38551 87 }
networker 13:327622e38551 88 virtual int Open(SocketInternal* sock, SocketAddrHdr* addr);
networker 13:327622e38551 89 virtual int Send(SocketInternal* sock, const u8* data, int len);//wrap data in RFCOMM frame and dispatch
networker 13:327622e38551 90 virtual int SetOpt(SocketInternal *sock, int so, int* data, int len);
networker 13:327622e38551 91 virtual int GetOpt(SocketInternal *sock, int so, int* data, int len);
networker 13:327622e38551 92 virtual int Close(SocketInternal* sock);
networker 13:327622e38551 93 virtual char* Name() {
networker 13:327622e38551 94 return "rfcomm SocketHandler";
networker 13:327622e38551 95 }
networker 13:327622e38551 96 void Recv(const u8* data, int len) {
networker 13:327622e38551 97 printf("rfcomm::Recv was called\n");
networker 13:327622e38551 98 }
networker 13:327622e38551 99 #if 0
networker 13:327622e38551 100 int Listen(unsigned char ch=0) {//passive open, similar semantics to 'Open' but connection is only made at request of the peer
networker 13:327622e38551 101 RFCOMMSocket *s = 0;//this entity may or may not be bound to a remote entity
networker 13:327622e38551 102 if (ch>0) {//specific channel
networker 13:327622e38551 103 s = find_socket(ch<<1);
networker 13:327622e38551 104 if (s) { //socket for this channel already in use
networker 13:327622e38551 105 printf("rfcomm::Listen: channel %d already in use\n", ch);
networker 13:327622e38551 106 return 0;
networker 13:327622e38551 107 } //else s==0, no socket for channel ch
networker 13:327622e38551 108 }//else listen to any channel
networker 13:327622e38551 109 int sn = find_slot(ch);
networker 13:327622e38551 110 if (sn<0) {
networker 13:327622e38551 111 printf("No socket could be found for channel %d\n", ch);
networker 13:327622e38551 112 return 0;
networker 13:327622e38551 113 } //else use slot 'sn' for the new rfcomm socket
networker 13:327622e38551 114 int sock = Socket_Create(SOCKET_RFCOM, OnRfCommControl, this);//allocate an rfcomm socket
networker 13:327622e38551 115 sckts[sn] = sock; //claim the socket
networker 13:327622e38551 116 RFCOMMSocket *rs = (RFCOMMSocket*)GetSocketInternal(sock);
networker 13:327622e38551 117 rs->serdevice = this;
networker 13:327622e38551 118 rs->dlci = (ch<<1)|1;//server socket
networker 13:327622e38551 119 //initiator = 0; what to do if already connected actively on different channel???
networker 13:327622e38551 120 /*l2cap is already present or is created when accepting the connection
networker 13:327622e38551 121 if (_l2cap == 0) { //no rfcomm -> l2cap connection yet
networker 13:327622e38551 122 printf("Need to open L2CAP channel first before opening RFCOMM channel %d\n", rs->dlci);
networker 13:327622e38551 123 ((L2CAPAddr*)addr)->psm = L2CAP_PSM_RFCOMM;//open the l2cap channel and the rfcomm_ch channel
networker 13:327622e38551 124 initiator = 0;
networker 13:327622e38551 125 _l2cap = Socket_Create(SOCKET_L2CAP, addr, OnRfCommControl, this);//this is the socket between the RFCOMM and the L2CAP layer
networker 13:327622e38551 126 if (_l2cap)
networker 13:327622e38551 127 printf("Successfully opened L2CAP channel on socket %d\n", _l2cap);
networker 13:327622e38551 128 else {
networker 13:327622e38551 129 printf("Opening L2CAP channel failed\n");
networker 13:327622e38551 130 return 0;
networker 13:327622e38551 131 }
networker 13:327622e38551 132 }
networker 13:327622e38551 133 */
networker 13:327622e38551 134 return sock;
networker 13:327622e38551 135 }
networker 13:327622e38551 136 #endif
networker 13:327622e38551 137 //int Open(BD_ADDR* bdAddr, inquiry_info* info);
networker 13:327622e38551 138 int set_remote_port_parameters(unsigned char dlci, port_settings *p);
networker 13:327622e38551 139 friend RFCOMMManager;
networker 13:327622e38551 140 };
networker 13:327622e38551 141
networker 13:327622e38551 142 class RFCOMMManager: public SocketHandler {
networker 13:327622e38551 143 rfcomm _devs[MAX_RFCOMM_DEVICES];
networker 13:327622e38551 144 int serverSock;
networker 13:327622e38551 145 char sckts[MAX_RFCOMM_SCKTS];//listening sockets
networker 13:327622e38551 146 public:
networker 13:327622e38551 147 virtual int Open(SocketInternal* sock, SocketAddrHdr* addr) {
networker 13:327622e38551 148 L2CAPAddr* ad = (L2CAPAddr*)addr;
networker 13:327622e38551 149 BD_ADDR* a = &ad->bdaddr;
networker 13:327622e38551 150 rfcomm *r = FindRfCommDevice(a);
networker 13:327622e38551 151 if (r==0)
networker 13:327622e38551 152 r = NewRfCommDevice();
networker 13:327622e38551 153 if (r==0)
networker 13:327622e38551 154 return 0;
networker 13:327622e38551 155 return r->Open(sock, addr);
networker 13:327622e38551 156 }
networker 13:327622e38551 157
networker 13:327622e38551 158 int FindSocket(BTDevice* dev) {//finds the l2cap socket for a certain rfcomm-btdevice connection
networker 13:327622e38551 159 for (int i = 0; i < MAX_RFCOMM_DEVICES; i++) {
networker 13:327622e38551 160 rfcomm *r = _devs+i;
networker 13:327622e38551 161 int l2cap = r->_l2cap;
networker 13:327622e38551 162 if (l2cap) {
networker 13:327622e38551 163 L2CAPSocket *p = (L2CAPSocket*)GetSocketInternal(l2cap);
networker 13:327622e38551 164 if (p->btdevice == dev)
networker 13:327622e38551 165 return l2cap;
networker 13:327622e38551 166 }
networker 13:327622e38551 167 }
networker 13:327622e38551 168 return 0;
networker 13:327622e38551 169 }
networker 13:327622e38551 170
networker 13:327622e38551 171 rfcomm* FindDev(BTDevice* dev) {//finds the rfcomm entity for a certain rfcomm-btdevice connection
networker 13:327622e38551 172 for (int i = 0; i < MAX_RFCOMM_DEVICES; i++) {
networker 13:327622e38551 173 rfcomm *r = _devs+i;
networker 13:327622e38551 174 int l2cap = r->_l2cap;
networker 13:327622e38551 175 if (l2cap) {
networker 13:327622e38551 176 L2CAPSocket *p = (L2CAPSocket*)GetSocketInternal(l2cap);
networker 13:327622e38551 177 if (p->btdevice == dev)
networker 13:327622e38551 178 return r;
networker 13:327622e38551 179 }
networker 13:327622e38551 180 }
networker 13:327622e38551 181 return 0;
networker 13:327622e38551 182 }
networker 13:327622e38551 183
networker 13:327622e38551 184 int BindSocket(int s) {
networker 13:327622e38551 185 L2CAPSocket *ls = (L2CAPSocket*)GetSocketInternal(s);
networker 13:327622e38551 186 printf("Binding l2cap socket %d to a new rfcomm server entity\n", s);
networker 13:327622e38551 187 rfcomm *r = NewRfCommDevice();
networker 13:327622e38551 188 r->_l2cap = s;
networker 13:327622e38551 189 r->initiator = 0;//we are server
networker 13:327622e38551 190 ls->si.userData = r;//was BTDevice, make rfcomm
networker 13:327622e38551 191 return 0;
networker 13:327622e38551 192 }
networker 13:327622e38551 193
networker 13:327622e38551 194 int new_slot(unsigned ch) {
networker 13:327622e38551 195 for (int i = 0; i < MAX_RFCOMM_SCKTS; i++) {
networker 13:327622e38551 196 if (sckts[i] != 0) { //socket is in use
networker 13:327622e38551 197 RFCOMMSocket *s = (RFCOMMSocket*)GetSocketInternal(sckts[i]);
networker 13:327622e38551 198 if (s==0) {
networker 13:327622e38551 199 printf("find_slot: socket %d not found\n", sckts[i]);
networker 13:327622e38551 200 continue;
networker 13:327622e38551 201 }
networker 13:327622e38551 202 if ((s->dlci >> 1) == ch) {
networker 13:327622e38551 203 printf("Channel %d is already in use on socket %d\n", ch, sckts[i]);
networker 13:327622e38551 204 return -1;
networker 13:327622e38551 205 }
networker 13:327622e38551 206 } else //slot is free
networker 13:327622e38551 207 return i;
networker 13:327622e38551 208 }
networker 13:327622e38551 209 return -2; //no free slots
networker 13:327622e38551 210 }
networker 13:327622e38551 211
networker 13:327622e38551 212 int find_socket(unsigned ch) {
networker 13:327622e38551 213 for (int i = 0; i < MAX_RFCOMM_SCKTS; i++) {
networker 13:327622e38551 214 if (sckts[i] != 0) { //socket is in use
networker 13:327622e38551 215 RFCOMMSocket *s = (RFCOMMSocket*)GetSocketInternal(sckts[i]);
networker 13:327622e38551 216 if (s==0) {
networker 13:327622e38551 217 printf("find_slot: socket %d not found\n", sckts[i]);
networker 13:327622e38551 218 continue;
networker 13:327622e38551 219 }
networker 13:327622e38551 220 if ((s->dlci >> 1) == ch) {
networker 13:327622e38551 221 printf("Found Channel %d on socket %d\n", ch, sckts[i]);
networker 13:327622e38551 222 return sckts[i];
networker 13:327622e38551 223 }
networker 13:327622e38551 224 else
networker 13:327622e38551 225 printf("slot %d has socket %d has dlci %d\n", i, sckts[i], s->dlci);
networker 13:327622e38551 226 }
networker 13:327622e38551 227 else
networker 13:327622e38551 228 printf("Slot %d is free\n", i);
networker 13:327622e38551 229 }
networker 13:327622e38551 230 printf("channel %d not found\n", ch);
networker 13:327622e38551 231 return 0; //channel not found
networker 13:327622e38551 232 }
networker 13:327622e38551 233
networker 13:327622e38551 234 int remove_socket(int sock) {
networker 13:327622e38551 235 for (int i = 0; i < MAX_RFCOMM_SCKTS; i++) {
networker 13:327622e38551 236 if (sckts[i] == sock) {
networker 13:327622e38551 237 sckts[i] = 0;
networker 13:327622e38551 238 return 0;
networker 13:327622e38551 239 }
networker 13:327622e38551 240 }
networker 13:327622e38551 241 return -1;
networker 13:327622e38551 242 }
networker 13:327622e38551 243
networker 13:327622e38551 244 virtual int Listen(SocketInternal* sock, int ch) {//called by Socket_Listen(SOCKET_RFCOM, channel, callback, userData)
networker 13:327622e38551 245 int slot = new_slot(ch);
networker 13:327622e38551 246 switch (slot) {
networker 13:327622e38551 247 case -1:
networker 13:327622e38551 248 printf("There is already someone listening on ch %d\n", ch);
networker 13:327622e38551 249 return ERR_SOCKET_CANT_LISTEN;//channel is occupied
networker 13:327622e38551 250 case -2:
networker 13:327622e38551 251 printf("All listener sockets are in use\n");
networker 13:327622e38551 252 return ERR_SOCKET_NONE_LEFT;
networker 13:327622e38551 253 }
networker 13:327622e38551 254 RFCOMMSocket *rs = (RFCOMMSocket*)sock;
networker 13:327622e38551 255 const char dir = 0;
networker 13:327622e38551 256 rs->dlci = (ch<<1)|dir;
networker 13:327622e38551 257 rs->State = SocketState_Listen;
networker 13:327622e38551 258 rs->serdevice = 0;//don't know yet
networker 13:327622e38551 259 sckts[slot] = rs->ID;
networker 13:327622e38551 260 printf("RFCOMM listener socket %d for ch %d (dlci 0x%02X) is assigned to slot %d\n", rs->ID, ch, rs->dlci, slot);
networker 13:327622e38551 261 return rs->ID;
networker 13:327622e38551 262 }
networker 13:327622e38551 263 /*
networker 13:327622e38551 264 virtual int Accept(SocketInternal *sock, int scid, int rxid) { //called indirectly from BTDevice::Control
networker 13:327622e38551 265 //sock is registered as an RFCOMM sock but we use it as an L2CAP sock
networker 13:327622e38551 266 //sock->type=RFCOM, meaning open/close/send/accept go to RFCOMMManager first
networker 13:327622e38551 267 //sock->userData = BTDevice, necessary to make the call back to BTDevice::Accept
networker 13:327622e38551 268 //Internal = L2CAPSocket, for scid, dcid
networker 13:327622e38551 269 BTDevice *l2cap = (BTDevice*)sock->userData;
networker 13:327622e38551 270 //sock->si.dcid = scid
networker 13:327622e38551 271 //sock->si.scid = something based on sock->ID
networker 13:327622e38551 272 serverSock = sock->ID;
networker 13:327622e38551 273 printf("Invoking accept on %p (%s) for sock %d and scid=%d\n", l2cap, l2cap->Name(), sock->ID, scid);
networker 13:327622e38551 274 return l2cap->Accept(sock, scid, rxid); //connect 'serverSock' to the remote RFCOMM client
networker 13:327622e38551 275 }
networker 13:327622e38551 276 */
networker 13:327622e38551 277 virtual int Send(SocketInternal* sock, const u8* data, int len) {
networker 13:327622e38551 278 RFCOMMSocket *s = (RFCOMMSocket*)sock;
networker 13:327622e38551 279 return s->serdevice->Send(sock, data, len);
networker 13:327622e38551 280 }
networker 13:327622e38551 281
networker 13:327622e38551 282 virtual int Close(SocketInternal* sock) {
networker 13:327622e38551 283 RFCOMMSocket *s = (RFCOMMSocket*)sock;
networker 13:327622e38551 284 return s->serdevice->Close(sock);
networker 13:327622e38551 285 }
networker 13:327622e38551 286
networker 13:327622e38551 287 virtual int SetOpt(SocketInternal* sock, int so, int* data, int len) {
networker 13:327622e38551 288 RFCOMMSocket *s = (RFCOMMSocket*)sock;
networker 13:327622e38551 289 return s->serdevice->SetOpt(sock, so, data, len);
networker 13:327622e38551 290 }
networker 13:327622e38551 291
networker 13:327622e38551 292 virtual int GetOpt(SocketInternal* sock, int so, int* data, int len) {
networker 13:327622e38551 293 RFCOMMSocket *s = (RFCOMMSocket*)sock;
networker 13:327622e38551 294 return s->serdevice->GetOpt(sock, so, data, len);
networker 13:327622e38551 295 }
networker 13:327622e38551 296
networker 13:327622e38551 297 virtual char* Name() {
networker 13:327622e38551 298 return "RFCOMMManager SocketHandler";
networker 13:327622e38551 299 }
networker 13:327622e38551 300
networker 13:327622e38551 301 rfcomm* NewRfCommDevice() {//allocate a new RFCOMM device from the pool
networker 13:327622e38551 302 for (int i = 0; i < MAX_RFCOMM_DEVICES; i++)
networker 13:327622e38551 303 if (!_devs[i].InUse())
networker 13:327622e38551 304 return _devs+i;
networker 13:327622e38551 305 return 0;
networker 13:327622e38551 306 }
networker 13:327622e38551 307
networker 13:327622e38551 308 rfcomm* FindRfCommDevice(BD_ADDR* ad) {//get a specific RFCOMM device from the pool
networker 13:327622e38551 309 for (int i = 0; i < MAX_RFCOMM_DEVICES; i++)
networker 13:327622e38551 310 if (_devs[i].InUse() && memcmp(ad, &_devs[i]._addr, 6)==0)
networker 13:327622e38551 311 return _devs+i;
networker 13:327622e38551 312 return 0;
networker 13:327622e38551 313 }
networker 13:327622e38551 314
networker 13:327622e38551 315 static void SerServer(int socket, SocketState state, const u8* data, int len, void* userData) {
networker 13:327622e38551 316 printfBytes("SerServer: ", data, len);
networker 13:327622e38551 317 //userData is the rfcomm
networker 13:327622e38551 318 rfcomm::OnRfCommControl(socket, state, data, len, userData);
networker 13:327622e38551 319 }
networker 13:327622e38551 320 //friend rfcomm;
networker 13:327622e38551 321 };
networker 13:327622e38551 322
networker 13:327622e38551 323 int set_remote_port_parameters(int socket, port_settings *p);
networker 13:327622e38551 324 extern RFCOMMManager rfcomm_manager;
networker 13:327622e38551 325
networker 13:327622e38551 326 #endif