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
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
Generated on Tue Jul 12 2022 18:48:53 by 1.7.2