local fix version of myBlueUSB (http://mbed.org/users/networker/code/myBlueUSB/). - merge deleted files which are required to compile. - enable echo back of received data via RFCOMM.

Dependencies:   AvailableMemory FatFileSystem mbed myUSBHost

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers RFCOMM.h Source File

RFCOMM.h

00001 #ifndef RFCOMM_H
00002 #define RFCOMM_H
00003 #include "USBHost.h"
00004 #include "hci.h"
00005 #include "Utils.h"
00006 
00007 #define MAX_RFCOMM_SCKTS    4
00008 //#define MAX_FRAME_SIZE  350  //ACL buffer - some headroom
00009 #define MAX_FRAME_SIZE  127  //ft size
00010 
00011 /*
00012 template <class T>
00013 T min(T a, T b) {
00014   return a<b ? a : b;
00015 }
00016 */
00017 
00018 #define MASK_BITRATE    0X0001
00019 #define MASK_DATABITS   0X0002
00020 #define MASK_STOPBITS   0X0004
00021 #define MASK_PARITYBITS 0X0008
00022 #define MASK_PARITYTYPE 0X0010
00023 #define MASK_XONCHAR    0X0020
00024 #define MASK_XOFFCHAR   0X0040
00025 #define MASK_XONXOFFIN  0X0100
00026 #define MASK_XONXOFFOUT 0X0200
00027 #define MASK_RTRIN      0X0400
00028 #define MASK_RTROUT     0X0800
00029 #define MASK_RTCIN      0X1000
00030 #define MASK_RTCOUT     0X2000
00031 
00032 struct port_settings {
00033     unsigned char baud;
00034 unsigned char bits:
00035     2;
00036 unsigned char stop:
00037     1;
00038 unsigned char par:
00039     1;
00040 unsigned char par_t:
00041     2;
00042 unsigned char :
00043     2;
00044 unsigned char flow:
00045     6;
00046 unsigned char :
00047     2;
00048     unsigned char xon;
00049     unsigned char xoff;
00050     unsigned short mask;
00051 };
00052 
00053 class rfcomm;
00054 class RFCOMMManager;
00055 #define MAX_RFCOMM_DEVICES 8    //physical devices
00056 
00057 class RFCOMMSocket: public SocketInternal {//this object must not be larger than SocketInternalPad (socketinternal + 8 bytes)
00058 public:
00059     rfcomm* serdevice;
00060     u8 dlci; //channel + D bit, D bit is inverted initiator bit
00061     u8 my_credits, peer_credits;
00062 };
00063 
00064 class rfcomm: public SocketHandler {
00065     int _l2cap; //socket to the l2cap layer
00066     int _devClass;
00067     BD_ADDR _addr;
00068     u8 initiator;
00069     u8  _pad[0];    // Struct align
00070     char sckts[MAX_RFCOMM_SCKTS];
00071     //static 
00072     unsigned maxframesize;
00073     int find_slot(unsigned ch);
00074     RFCOMMSocket* find_socket(unsigned dlci);
00075     void initChannels(int socket);
00076     unsigned release_channel(unsigned dlci);
00077     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
00078     int Disconnect(RFCOMMSocket*);
00079 public:
00080     rfcomm() : _l2cap(0), _devClass(0) {
00081         for (int i = 0; i < MAX_RFCOMM_SCKTS; i++) sckts[i] = 0;
00082         maxframesize = MAX_FRAME_SIZE;
00083     }
00084 
00085     bool InUse() {
00086         return _l2cap != 0;
00087     }
00088     virtual int Open(SocketInternal* sock, SocketAddrHdr* addr);
00089     virtual int Send(SocketInternal* sock, const u8* data, int len);//wrap data in RFCOMM frame and dispatch
00090     virtual int SetOpt(SocketInternal *sock, int so, int* data, int len);
00091     virtual int GetOpt(SocketInternal *sock, int so, int* data, int len);
00092     virtual int Close(SocketInternal* sock);
00093     virtual char* Name() {
00094         return "rfcomm SocketHandler";
00095     }
00096     void Recv(const u8* data, int len) {
00097         printf("rfcomm::Recv was called\n");
00098     }
00099 #if 0
00100     int Listen(unsigned char ch=0) {//passive open, similar semantics to 'Open' but connection is only made at request of the peer
00101         RFCOMMSocket *s = 0;//this entity may or may not be bound to a remote entity
00102         if (ch>0) {//specific channel
00103             s = find_socket(ch<<1);
00104             if (s) { //socket for this channel already in use
00105                 printf("rfcomm::Listen: channel %d already in use\n", ch);
00106                 return 0;
00107             } //else s==0, no socket for channel ch
00108         }//else listen to any channel
00109         int sn = find_slot(ch);
00110         if (sn<0) {
00111             printf("No socket could be found for channel %d\n", ch);
00112             return 0;
00113         } //else use slot 'sn' for the new rfcomm socket
00114         int sock = Socket_Create(SOCKET_RFCOM, OnRfCommControl, this);//allocate an rfcomm socket
00115         sckts[sn] = sock; //claim the socket
00116         RFCOMMSocket *rs = (RFCOMMSocket*)GetSocketInternal(sock);
00117         rs->serdevice = this;
00118         rs->dlci = (ch<<1)|1;//server socket
00119         //initiator = 0; what to do if already connected actively on different channel???
00120         /*l2cap is already present or is created when accepting the connection
00121                 if (_l2cap == 0) { //no rfcomm -> l2cap connection yet
00122                     printf("Need to open L2CAP channel first before opening RFCOMM channel %d\n", rs->dlci);
00123                     ((L2CAPAddr*)addr)->psm = L2CAP_PSM_RFCOMM;//open the l2cap channel and the rfcomm_ch channel
00124                     initiator = 0;
00125                     _l2cap = Socket_Create(SOCKET_L2CAP, addr, OnRfCommControl, this);//this is the socket between the RFCOMM and the L2CAP layer
00126                     if (_l2cap)
00127                         printf("Successfully opened L2CAP channel on socket %d\n", _l2cap);
00128                     else {
00129                         printf("Opening L2CAP channel failed\n");
00130                         return 0;
00131                     }
00132                 }
00133         */
00134         return sock;
00135     }
00136 #endif
00137     //int Open(BD_ADDR* bdAddr, inquiry_info* info);
00138     int set_remote_port_parameters(unsigned char dlci, port_settings *p);
00139     friend RFCOMMManager;
00140 };
00141 
00142 class RFCOMMManager: public SocketHandler {
00143     rfcomm _devs[MAX_RFCOMM_DEVICES];
00144     int serverSock;
00145     char sckts[MAX_RFCOMM_SCKTS];//listening sockets
00146 public:
00147     virtual int Open(SocketInternal* sock, SocketAddrHdr* addr) {
00148         L2CAPAddr* ad = (L2CAPAddr*)addr;
00149         BD_ADDR* a = &ad->bdaddr;
00150         rfcomm *r = FindRfCommDevice(a);
00151         if (r==0)
00152             r = NewRfCommDevice();
00153         if (r==0)
00154             return 0;
00155         return r->Open(sock, addr);
00156     }
00157 
00158     int FindSocket(BTDevice* dev) {//finds the l2cap socket for a certain rfcomm-btdevice connection
00159         for (int i = 0; i < MAX_RFCOMM_DEVICES; i++) {
00160             rfcomm *r = _devs+i;
00161             int l2cap = r->_l2cap;
00162             if (l2cap) {
00163                 L2CAPSocket *p = (L2CAPSocket*)GetSocketInternal(l2cap);
00164                 if (p->btdevice == dev)
00165                     return l2cap;
00166             }
00167         }
00168         return 0;
00169     }
00170 
00171     rfcomm* FindDev(BTDevice* dev) {//finds the rfcomm entity for a certain rfcomm-btdevice connection
00172         for (int i = 0; i < MAX_RFCOMM_DEVICES; i++) {
00173             rfcomm *r = _devs+i;
00174             int l2cap = r->_l2cap;
00175             if (l2cap) {
00176                 L2CAPSocket *p = (L2CAPSocket*)GetSocketInternal(l2cap);
00177                 if (p->btdevice == dev)
00178                     return r;
00179             }
00180         }
00181         return 0;
00182     }
00183 
00184     int BindSocket(int s) {
00185         L2CAPSocket *ls = (L2CAPSocket*)GetSocketInternal(s);
00186         printf("Binding l2cap socket %d to a new rfcomm server entity\n", s);
00187         rfcomm *r = NewRfCommDevice();
00188         r->_l2cap = s;
00189         r->initiator = 0;//we are server
00190         ls->si.userData = r;//was BTDevice, make rfcomm
00191         return 0;
00192     }
00193 
00194     int new_slot(unsigned ch) {
00195         for (int i = 0; i < MAX_RFCOMM_SCKTS; i++) {
00196             if (sckts[i] != 0) { //socket is in use
00197                 RFCOMMSocket *s = (RFCOMMSocket*)GetSocketInternal(sckts[i]);
00198                 if (s==0) {
00199                     printf("find_slot: socket  %d not found\n", sckts[i]);
00200                     continue;
00201                 }
00202                 if ((s->dlci >> 1) == ch) {
00203                     printf("Channel %d is already in use on socket %d\n", ch, sckts[i]);
00204                     return -1;
00205                 }
00206             } else //slot is free
00207                 return i;
00208         }
00209         return -2; //no free slots
00210     }
00211 
00212     int find_socket(unsigned ch) {
00213         for (int i = 0; i < MAX_RFCOMM_SCKTS; i++) {
00214             if (sckts[i] != 0) { //socket is in use
00215                 RFCOMMSocket *s = (RFCOMMSocket*)GetSocketInternal(sckts[i]);
00216                 if (s==0) {
00217                     printf("find_slot: socket  %d not found\n", sckts[i]);
00218                     continue;
00219                 }
00220                 if ((s->dlci >> 1) == ch) {
00221                     printf("Found Channel %d on socket %d\n", ch, sckts[i]);
00222                     return sckts[i];
00223                 }
00224                 else
00225                   printf("slot %d has socket %d has dlci %d\n", i, sckts[i], s->dlci);
00226             }
00227             else
00228               printf("Slot %d is free\n", i);
00229         }
00230         printf("channel %d not found\n", ch);
00231         return 0; //channel not found
00232     }
00233 
00234     int remove_socket(int sock) {
00235         for (int i = 0; i < MAX_RFCOMM_SCKTS; i++) {
00236           if (sckts[i] == sock) {
00237             sckts[i] = 0;
00238             return 0;
00239           }
00240         }
00241         return -1;
00242     }
00243 
00244     virtual int Listen(SocketInternal* sock, int ch) {//called by Socket_Listen(SOCKET_RFCOM, channel, callback, userData)
00245         int slot = new_slot(ch);
00246         switch (slot) {
00247             case -1:
00248                 printf("There is already someone listening on ch %d\n", ch);
00249                 return ERR_SOCKET_CANT_LISTEN;//channel is occupied
00250             case -2:
00251                 printf("All listener sockets are in use\n");
00252                 return ERR_SOCKET_NONE_LEFT;
00253         }
00254         RFCOMMSocket *rs = (RFCOMMSocket*)sock;
00255         const char dir = 0;
00256         rs->dlci = (ch<<1)|dir;
00257         rs->State = SocketState_Listen;
00258         rs->serdevice = 0;//don't know yet
00259         sckts[slot] = rs->ID;
00260         printf("RFCOMM listener socket %d for ch %d (dlci 0x%02X) is assigned to slot %d\n", rs->ID, ch, rs->dlci, slot);
00261         return rs->ID;
00262     }
00263 /*
00264     virtual int Accept(SocketInternal *sock, int scid, int rxid) { //called indirectly from BTDevice::Control
00265         //sock is registered as an RFCOMM sock but we use it as an L2CAP sock
00266         //sock->type=RFCOM, meaning open/close/send/accept go to RFCOMMManager first
00267         //sock->userData = BTDevice, necessary to make the call back to BTDevice::Accept
00268         //Internal = L2CAPSocket, for scid, dcid
00269         BTDevice *l2cap = (BTDevice*)sock->userData;
00270         //sock->si.dcid = scid
00271         //sock->si.scid = something based on sock->ID
00272         serverSock = sock->ID;
00273         printf("Invoking accept on %p (%s) for sock %d and scid=%d\n", l2cap, l2cap->Name(), sock->ID, scid);
00274         return l2cap->Accept(sock, scid, rxid); //connect 'serverSock' to the remote RFCOMM client
00275     }
00276 */
00277     virtual int Send(SocketInternal* sock, const u8* data, int len) {
00278         RFCOMMSocket *s = (RFCOMMSocket*)sock;
00279         return s->serdevice->Send(sock, data, len);
00280     }
00281 
00282     virtual int Close(SocketInternal* sock) {
00283         RFCOMMSocket *s = (RFCOMMSocket*)sock;
00284         return s->serdevice->Close(sock);
00285     }
00286 
00287     virtual int SetOpt(SocketInternal* sock, int so, int* data, int len) {
00288         RFCOMMSocket *s = (RFCOMMSocket*)sock;
00289         return s->serdevice->SetOpt(sock, so, data, len);
00290     }
00291 
00292     virtual int GetOpt(SocketInternal* sock, int so, int* data, int len) {
00293         RFCOMMSocket *s = (RFCOMMSocket*)sock;
00294         return s->serdevice->GetOpt(sock, so, data, len);
00295     }
00296 
00297     virtual char* Name() {
00298         return "RFCOMMManager SocketHandler";
00299     }
00300 
00301     rfcomm* NewRfCommDevice() {//allocate a new RFCOMM device from the pool
00302         for (int i = 0; i < MAX_RFCOMM_DEVICES; i++)
00303             if (!_devs[i].InUse())
00304                 return _devs+i;
00305         return 0;
00306     }
00307 
00308     rfcomm* FindRfCommDevice(BD_ADDR* ad) {//get a specific RFCOMM device from the pool
00309         for (int i = 0; i < MAX_RFCOMM_DEVICES; i++)
00310             if (_devs[i].InUse() && memcmp(ad, &_devs[i]._addr, 6)==0)
00311                 return _devs+i;
00312         return 0;
00313     }
00314 
00315     static void SerServer(int socket, SocketState state, const u8* data, int len, void* userData) {
00316         printfBytes("SerServer: ", data, len);
00317         //userData is the rfcomm
00318         rfcomm::OnRfCommControl(socket, state, data, len, userData);
00319     }
00320     //friend rfcomm;
00321 };
00322 
00323 int set_remote_port_parameters(int socket, port_settings *p);
00324 extern RFCOMMManager rfcomm_manager;
00325 
00326 #endif