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

sdp/sdp.h

Committer:
nobukuma
Date:
2013-12-08
Revision:
2:9f25a7fa1a54
Parent:
0:003889bc474f

File content as of revision 2:9f25a7fa1a54:

#ifndef SDP_H
#define SDP_H
#include "AvailableMemory.h"
#include "sdp_data.h"
#include <map>
#define OFFSET  8

class SDPManager;
extern SDPManager SDP;
typedef map<unsigned short, sdp_data*> serv_rec;

void attribHandler(serv_rec *r);
unsigned parseUUID(const u8* data, int len, unsigned &p);
unsigned length(const unsigned char *el, unsigned &p);
unsigned getval(const unsigned char *p, int n) ;
void errorhandler(unsigned err);//default error handler


class SDPHandler: public SocketHandler {
//    int _l2cap;
    int sdp_socket;
    unsigned char l2cap_buf[100+OFFSET];
    unsigned char* buf;
    unsigned txid;
    unsigned char contState[17];//maximum size, in practive it is 3
    unsigned char *contBuf;
    unsigned byteCount;
    int _state;
    sdp_data *tree;//root of the entire service tree
    map<unsigned, serv_rec*> services;//the set of supported services <handle, service>
    map<unsigned, serv_rec*>::iterator index;
//server properties
//    static map<unsigned, serv_rec*> server;
//    static int serverSock;
public:
    SDPHandler();
    void Clear();
    virtual int Open(SocketInternal* sock, SocketAddrHdr* addr);
//    virtual int Accept(SocketInternal *sock, int scid, int rxid); //called indirectly from BTDevice::Control
    virtual int Send(SocketInternal* sock, const u8* data, int len);
    virtual int Close(SocketInternal* sock);
    virtual char* Name() {
        return "SDPHandler SocketHandler";
    }
    void OnSdpRsp(const u8* data, int len);
    static void OnSdpRsp(int socket, SocketState state, const u8* data, int len, void* userData);

    //this function is called when the SDP sockets receives data (see HCICallback in TestShell),
    //currently does not happen because not forwarded from OnSdpRsp, can be used to handle multiple connections
    static void OnSockCallback(int socket, SocketState state, const u8* data, int len, void* userData) ;
    //The SDP server is stateless hence can be static
//    static void SDPServer(int socket, SocketState state, const u8* data, int len, void* userData) ;

    void (*ErrorResponse)(unsigned) ;
    void (*ServiceSearchResponse)() ;
    void (*ServiceAttributeResponse)(serv_rec*) ;
    void (*ServiceSearchAttributeResponse)() ;
    int ServiceSearchRequest(sdp_data *sp, unsigned count, unsigned cs=0);
    int ServiceAttributeRequest(unsigned handle, unsigned count, sdp_data* al, unsigned cs=0) ;
    int ServiceSearchAttributeRequest(sdp_data *sp, unsigned count, sdp_data* al, unsigned cs=0);
//server
//    static int ServiceSearchAttributeReply(unsigned rxid, sdp_data* al, unsigned count, unsigned cs=0);
private:
//    static unsigned length(const unsigned char *el, unsigned &p);
//    static unsigned getval(const unsigned char *p, int n) ;
//    static unsigned parseUUID(const u8* data, int len, unsigned &p);
    unsigned parse (const unsigned char *el, unsigned count, sdp_data* &result, serv_rec* &record) ;
    unsigned parseLight (const unsigned char *el, unsigned count, sdp_data* &result, serv_rec* &record) ;
    int parseRsp(const unsigned char*rsp, int len) ;
    void append(const unsigned char*rsp, int len) ;
    void freeBuf();
};
/*
class SDPClient: public SDPHandler {
};

class SDPServer: public SDPHandler {
};
*/
class SDPManager: public SocketHandler {
    map<int, SDPHandler*> handlers;
//server properties
//    SDPHandler *Server;
    static map<unsigned, serv_rec*> server;
    static int serverSock;
    bool once;
public:
    SDPManager() {
        once = true;
    }
    virtual int Open(SocketInternal* sock, SocketAddrHdr* addr) {
        printf("SDPManager::Open(sock (ID=%d, type=%d), addr): should not be called\n", sock->ID, sock->Type);
        return sock->ID;//((SDPHandler*)sock->userData)->Open(sock, addr);
    }
    int Open(SocketAddrHdr* addr) {
        L2CAPAddr* ad = (L2CAPAddr*)addr;
        ad->psm = L2CAP_PSM_SDP;//open the l2cap channel
        SDPHandler *h = new SDPHandler;
        int s = Socket_Open(SOCKET_L2CAP, addr, &SDPHandler::OnSdpRsp, h);
        handlers[s] = h;
        return s;
    }
    virtual int Accept(SocketInternal *sock, int scid, int rxid) { //called indirectly from BTDevice::Control
        if (once) {
            once = false;
            buildServer();//build the DB on the first connection
        }
        //sock is registered as an SDP sock but we use it as an L2CAP sock
        //type=SDP
        //userData = BTDevice
        //Internal = L2CAPSocket
        BTDevice *l2cap = (BTDevice*)sock->userData;
        //sock->dcid = scid
        //sock->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);
    }
    virtual int Send(SocketInternal* sock, const u8* data, int len) {//called by the server
        BTDevice *l2cap = (BTDevice*)sock->userData;
        return l2cap->Send(sock, data, len);
    }
    virtual int Close(SocketInternal* sock) {
        printf("SDPManager::Close() closing  socket %d\n", sock->ID);
        SDPHandler *h = handlers[sock->ID];
        int retval = h->Close(sock);
        delete h;
        handlers[sock->ID] = 0;
        return retval;
    }
    void Destroy(int s) {
        printf("Deleting handler for socket %d\n", s);
        delete handlers[s];
        handlers[s] = 0;
    }
    virtual char* Name() {
        return "SDPManager SocketHandler";
    }
    //void OnSdpRsp(const u8* data, int len);
    static void OnSdpRsp(int socket, SocketState state, const u8* data, int len, void* userData) {
        printf("SDPManager::OnSdpRsp(socket %d, state %d, len %d)\n", socket, state, len);
    }
    //The SDP server is (almost) stateless hence can be static
    static void SDPServer(int socket, SocketState state, const u8* data, int len, void* userData) ;
    static void match(bool elig[], unsigned uuid);
    static bool isInList(unsigned short id, const unsigned char* list, int end);
    static void addToReply(sdp_data *svc, serv_rec *list, const unsigned char* att, int end);
    static int findUUID(unsigned h, unsigned uuid);
    void buildServer();
    static int ServiceSearchReply(unsigned rxid, unsigned *handles, unsigned count, unsigned cs=0);
    static int ServiceAttributeReply(unsigned rxid, sdp_data* al, unsigned count, unsigned cs=0);
    static int ServiceSearchAttributeReply(unsigned rxid, sdp_data* al, unsigned count, unsigned cs=0);
    /*
        //this function is called when the SDP sockets receives data (see HCICallback in TestShell),
        //currently does not happen because not forwarded from OnSdpRsp, can be used to handle multiple connections
        static void OnSockCallback(int socket, SocketState state, const u8* data, int len, void* userData) ;

        static void errorhandler(unsigned err);

        void (*ErrorResponse)(unsigned) ;
        void (*ServiceSearchResponse)() ;
        void (*ServiceAttributeResponse)(serv_rec*) ;
        void (*ServiceSearchAttributeResponse)() ;
        int ServiceSearchRequest(sdp_data *sp, unsigned count, unsigned cs=0);
        int ServiceAttributeRequest(unsigned handle, unsigned count, sdp_data* al, unsigned cs=0) ;
        int ServiceSearchAttributeRequest(sdp_data *sp, unsigned count, sdp_data* al, unsigned cs=0);
    //server
    private:
        static unsigned length(const unsigned char *el, unsigned &p);
        static unsigned getval(const unsigned char *p, int n) ;
        static unsigned parseUUID(const u8* data, int len, unsigned &p);
        static void addAttrib(unsigned h, unsigned short id, sdp_data *attrib);
        static void addIndex(unsigned h, unsigned uuid);
        static int findUUID(unsigned h, unsigned uuid);
        static void match(bool elig[], unsigned uuid);
        static bool isInList(unsigned short id, const unsigned char* list, int end);
        void buildServer();
        unsigned parse (const unsigned char *el, unsigned count, sdp_data* &result, serv_rec* &record) ;
        unsigned parseLight (const unsigned char *el, unsigned count, sdp_data* &result, serv_rec* &record) ;
        int parseRsp(const unsigned char*rsp, int len) ;
        void append(const unsigned char*rsp, int len) ;
        void freeBuf();
    */
};

#endif