Pulse Oximeter (NONIN) communicates with mbed via Bluetooth dongle and sends Heart Rate and Oxygen Saturation via GPRS module
Dependencies: C12832 GPS GSM mbed
Fork of myBlueUSB_localfix by
rfcomm/RFCOMM.h
- Committer:
- nobukuma
- Date:
- 2013-12-07
- Revision:
- 0:003889bc474f
File content as of revision 0:003889bc474f:
#ifndef RFCOMM_H #define RFCOMM_H #include "USBHost.h" #include "hci.h" #include "Utils.h" #define MAX_RFCOMM_SCKTS 4 //#define MAX_FRAME_SIZE 350 //ACL buffer - some headroom #define MAX_FRAME_SIZE 127 //ft size /* template <class T> T min(T a, T b) { return a<b ? a : b; } */ #define MASK_BITRATE 0X0001 #define MASK_DATABITS 0X0002 #define MASK_STOPBITS 0X0004 #define MASK_PARITYBITS 0X0008 #define MASK_PARITYTYPE 0X0010 #define MASK_XONCHAR 0X0020 #define MASK_XOFFCHAR 0X0040 #define MASK_XONXOFFIN 0X0100 #define MASK_XONXOFFOUT 0X0200 #define MASK_RTRIN 0X0400 #define MASK_RTROUT 0X0800 #define MASK_RTCIN 0X1000 #define MASK_RTCOUT 0X2000 struct port_settings { unsigned char baud; unsigned char bits: 2; unsigned char stop: 1; unsigned char par: 1; unsigned char par_t: 2; unsigned char : 2; unsigned char flow: 6; unsigned char : 2; unsigned char xon; unsigned char xoff; unsigned short mask; }; class rfcomm; class RFCOMMManager; #define MAX_RFCOMM_DEVICES 8 //physical devices class RFCOMMSocket: public SocketInternal {//this object must not be larger than SocketInternalPad (socketinternal + 8 bytes) public: rfcomm* serdevice; u8 dlci; //channel + D bit, D bit is inverted initiator bit u8 my_credits, peer_credits; }; class rfcomm: public SocketHandler { int _l2cap; //socket to the l2cap layer int _devClass; BD_ADDR _addr; u8 initiator; u8 _pad[0]; // Struct align char sckts[MAX_RFCOMM_SCKTS]; //static unsigned maxframesize; int find_slot(unsigned ch); RFCOMMSocket* find_socket(unsigned dlci); void initChannels(int socket); unsigned release_channel(unsigned dlci); 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 int Disconnect(RFCOMMSocket*); public: rfcomm() : _l2cap(0), _devClass(0) { for (int i = 0; i < MAX_RFCOMM_SCKTS; i++) sckts[i] = 0; maxframesize = MAX_FRAME_SIZE; } bool InUse() { return _l2cap != 0; } virtual int Open(SocketInternal* sock, SocketAddrHdr* addr); virtual int Send(SocketInternal* sock, const u8* data, int len);//wrap data in RFCOMM frame and dispatch virtual int SetOpt(SocketInternal *sock, int so, int* data, int len); virtual int GetOpt(SocketInternal *sock, int so, int* data, int len); virtual int Close(SocketInternal* sock); virtual char* Name() { return "rfcomm SocketHandler"; } void Recv(const u8* data, int len) { printf("rfcomm::Recv was called\n"); } #if 0 int Listen(unsigned char ch=0) {//passive open, similar semantics to 'Open' but connection is only made at request of the peer RFCOMMSocket *s = 0;//this entity may or may not be bound to a remote entity if (ch>0) {//specific channel s = find_socket(ch<<1); if (s) { //socket for this channel already in use printf("rfcomm::Listen: channel %d already in use\n", ch); return 0; } //else s==0, no socket for channel ch }//else listen to any channel int sn = find_slot(ch); if (sn<0) { printf("No socket could be found for channel %d\n", ch); return 0; } //else use slot 'sn' for the new rfcomm socket int sock = Socket_Create(SOCKET_RFCOM, OnRfCommControl, this);//allocate an rfcomm socket sckts[sn] = sock; //claim the socket RFCOMMSocket *rs = (RFCOMMSocket*)GetSocketInternal(sock); rs->serdevice = this; rs->dlci = (ch<<1)|1;//server socket //initiator = 0; what to do if already connected actively on different channel??? /*l2cap is already present or is created when accepting the connection if (_l2cap == 0) { //no rfcomm -> l2cap connection yet printf("Need to open L2CAP channel first before opening RFCOMM channel %d\n", rs->dlci); ((L2CAPAddr*)addr)->psm = L2CAP_PSM_RFCOMM;//open the l2cap channel and the rfcomm_ch channel initiator = 0; _l2cap = Socket_Create(SOCKET_L2CAP, addr, OnRfCommControl, this);//this is the socket between the RFCOMM and the L2CAP layer if (_l2cap) printf("Successfully opened L2CAP channel on socket %d\n", _l2cap); else { printf("Opening L2CAP channel failed\n"); return 0; } } */ return sock; } #endif //int Open(BD_ADDR* bdAddr, inquiry_info* info); int set_remote_port_parameters(unsigned char dlci, port_settings *p); friend RFCOMMManager; }; class RFCOMMManager: public SocketHandler { rfcomm _devs[MAX_RFCOMM_DEVICES]; int serverSock; char sckts[MAX_RFCOMM_SCKTS];//listening sockets public: virtual int Open(SocketInternal* sock, SocketAddrHdr* addr) { L2CAPAddr* ad = (L2CAPAddr*)addr; BD_ADDR* a = &ad->bdaddr; rfcomm *r = FindRfCommDevice(a); if (r==0) r = NewRfCommDevice(); if (r==0) return 0; return r->Open(sock, addr); } int FindSocket(BTDevice* dev) {//finds the l2cap socket for a certain rfcomm-btdevice connection for (int i = 0; i < MAX_RFCOMM_DEVICES; i++) { rfcomm *r = _devs+i; int l2cap = r->_l2cap; if (l2cap) { L2CAPSocket *p = (L2CAPSocket*)GetSocketInternal(l2cap); if (p->btdevice == dev) return l2cap; } } return 0; } rfcomm* FindDev(BTDevice* dev) {//finds the rfcomm entity for a certain rfcomm-btdevice connection for (int i = 0; i < MAX_RFCOMM_DEVICES; i++) { rfcomm *r = _devs+i; int l2cap = r->_l2cap; if (l2cap) { L2CAPSocket *p = (L2CAPSocket*)GetSocketInternal(l2cap); if (p->btdevice == dev) return r; } } return 0; } int BindSocket(int s) { L2CAPSocket *ls = (L2CAPSocket*)GetSocketInternal(s); printf("Binding l2cap socket %d to a new rfcomm server entity\n", s); rfcomm *r = NewRfCommDevice(); r->_l2cap = s; r->initiator = 0;//we are server ls->si.userData = r;//was BTDevice, make rfcomm return 0; } int new_slot(unsigned ch) { for (int i = 0; i < MAX_RFCOMM_SCKTS; i++) { if (sckts[i] != 0) { //socket is in use RFCOMMSocket *s = (RFCOMMSocket*)GetSocketInternal(sckts[i]); if (s==0) { printf("find_slot: socket %d not found\n", sckts[i]); continue; } if ((s->dlci >> 1) == ch) { printf("Channel %d is already in use on socket %d\n", ch, sckts[i]); return -1; } } else //slot is free return i; } return -2; //no free slots } int find_socket(unsigned ch) { for (int i = 0; i < MAX_RFCOMM_SCKTS; i++) { if (sckts[i] != 0) { //socket is in use RFCOMMSocket *s = (RFCOMMSocket*)GetSocketInternal(sckts[i]); if (s==0) { printf("find_slot: socket %d not found\n", sckts[i]); continue; } if ((s->dlci >> 1) == ch) { printf("Found Channel %d on socket %d\n", ch, sckts[i]); return sckts[i]; } else printf("slot %d has socket %d has dlci %d\n", i, sckts[i], s->dlci); } else printf("Slot %d is free\n", i); } printf("channel %d not found\n", ch); return 0; //channel not found } int remove_socket(int sock) { for (int i = 0; i < MAX_RFCOMM_SCKTS; i++) { if (sckts[i] == sock) { sckts[i] = 0; return 0; } } return -1; } virtual int Listen(SocketInternal* sock, int ch) {//called by Socket_Listen(SOCKET_RFCOM, channel, callback, userData) int slot = new_slot(ch); switch (slot) { case -1: printf("There is already someone listening on ch %d\n", ch); return ERR_SOCKET_CANT_LISTEN;//channel is occupied case -2: printf("All listener sockets are in use\n"); return ERR_SOCKET_NONE_LEFT; } RFCOMMSocket *rs = (RFCOMMSocket*)sock; const char dir = 0; rs->dlci = (ch<<1)|dir; rs->State = SocketState_Listen; rs->serdevice = 0;//don't know yet sckts[slot] = rs->ID; printf("RFCOMM listener socket %d for ch %d (dlci 0x%02X) is assigned to slot %d\n", rs->ID, ch, rs->dlci, slot); return rs->ID; } /* virtual int Accept(SocketInternal *sock, int scid, int rxid) { //called indirectly from BTDevice::Control //sock is registered as an RFCOMM sock but we use it as an L2CAP sock //sock->type=RFCOM, meaning open/close/send/accept go to RFCOMMManager first //sock->userData = BTDevice, necessary to make the call back to BTDevice::Accept //Internal = L2CAPSocket, for scid, dcid BTDevice *l2cap = (BTDevice*)sock->userData; //sock->si.dcid = scid //sock->si.scid = something based on sock->ID serverSock = sock->ID; printf("Invoking accept on %p (%s) for sock %d and scid=%d\n", l2cap, l2cap->Name(), sock->ID, scid); return l2cap->Accept(sock, scid, rxid); //connect 'serverSock' to the remote RFCOMM client } */ virtual int Send(SocketInternal* sock, const u8* data, int len) { RFCOMMSocket *s = (RFCOMMSocket*)sock; return s->serdevice->Send(sock, data, len); } virtual int Close(SocketInternal* sock) { RFCOMMSocket *s = (RFCOMMSocket*)sock; return s->serdevice->Close(sock); } virtual int SetOpt(SocketInternal* sock, int so, int* data, int len) { RFCOMMSocket *s = (RFCOMMSocket*)sock; return s->serdevice->SetOpt(sock, so, data, len); } virtual int GetOpt(SocketInternal* sock, int so, int* data, int len) { RFCOMMSocket *s = (RFCOMMSocket*)sock; return s->serdevice->GetOpt(sock, so, data, len); } virtual char* Name() { return "RFCOMMManager SocketHandler"; } rfcomm* NewRfCommDevice() {//allocate a new RFCOMM device from the pool for (int i = 0; i < MAX_RFCOMM_DEVICES; i++) if (!_devs[i].InUse()) return _devs+i; return 0; } rfcomm* FindRfCommDevice(BD_ADDR* ad) {//get a specific RFCOMM device from the pool for (int i = 0; i < MAX_RFCOMM_DEVICES; i++) if (_devs[i].InUse() && memcmp(ad, &_devs[i]._addr, 6)==0) return _devs+i; return 0; } static void SerServer(int socket, SocketState state, const u8* data, int len, void* userData) { printfBytes("SerServer: ", data, len); //userData is the rfcomm rfcomm::OnRfCommControl(socket, state, data, len, userData); } //friend rfcomm; }; int set_remote_port_parameters(int socket, port_settings *p); extern RFCOMMManager rfcomm_manager; #endif