Dependents:   mbed_TANK_Kinect ftusbClass

RFCOMM.h

Committer:
networker
Date:
2011-04-04
Revision:
0:8d7b47ceb9f5
Child:
1:9f3821db3048

File content as of revision 0:8d7b47ceb9f5:

#ifndef RFCOMM_H
#define RFCOMM_H
#include "USBHost.h"
#include "hci.h"

#define MAX_RFCOMM_SCKTS    4
/*
template <class T> 
T min(T a, T b) { 
  return a<b ? a : b;
}
*/

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; //for dlci0
    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;
    }

    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 Close(SocketInternal* sock);
    virtual char* Name() { return "rfcomm SocketHandler";}
    void Recv(const u8* data, int len) {
        printf("rfcomm::Recv was called\n");
    }
  //int Open(BD_ADDR* bdAddr, inquiry_info* info);  
  friend RFCOMMManager;
};

class RFCOMMManager: public SocketHandler {
    rfcomm _devs[MAX_RFCOMM_DEVICES];
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();
        return r->Open(sock, addr);
    }
    
    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 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;
    }
};


#endif