Based on myBlueUSB and rosserial_mbed

Dependencies:   mbed myUSBHost AvailableMemory myBlueUSB

Committer:
OTL
Date:
Sat Sep 17 14:24:13 2011 +0000
Revision:
1:18139954944b
Parent:
0:7684b95768c7
remove m3pi and main

Who changed what in which revision?

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