Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Dependents: mbed_TANK_Kinect ftusbClass
sdp.h@3:e8d2ebb7392e, 2011-05-04 (annotated)
- Committer:
- networker
- Date:
- Wed May 04 09:27:32 2011 +0000
- Revision:
- 3:e8d2ebb7392e
- Parent:
- 2:d5a27b2d2e08
- Child:
- 4:d5c3e499603d
SDP server partially implemented. Provides SPP compatible with Windows BT stack.
Who changed what in which revision?
| User | Revision | Line number | New contents of line | 
|---|---|---|---|
| networker | 0:7493bf6bb1b9 | 1 | #ifndef SDP_H | 
| networker | 0:7493bf6bb1b9 | 2 | #define SDP_H | 
| networker | 1:70ee392bcfd4 | 3 | #include "AvailableMemory.h" | 
| networker | 3:e8d2ebb7392e | 4 | #include "sdp_data.h" | 
| networker | 0:7493bf6bb1b9 | 5 | #include <map> | 
| networker | 0:7493bf6bb1b9 | 6 | #define OFFSET 8 | 
| networker | 0:7493bf6bb1b9 | 7 | |
| networker | 0:7493bf6bb1b9 | 8 | class SDPManager; | 
| networker | 0:7493bf6bb1b9 | 9 | extern SDPManager SDP; | 
| networker | 0:7493bf6bb1b9 | 10 | typedef map<unsigned short, sdp_data*> serv_rec; | 
| networker | 0:7493bf6bb1b9 | 11 | |
| networker | 0:7493bf6bb1b9 | 12 | void attribHandler(serv_rec *r); | 
| networker | 3:e8d2ebb7392e | 13 | unsigned parseUUID(const u8* data, int len, unsigned &p); | 
| networker | 3:e8d2ebb7392e | 14 | unsigned length(const unsigned char *el, unsigned &p); | 
| networker | 3:e8d2ebb7392e | 15 | unsigned getval(const unsigned char *p, int n) ; | 
| networker | 3:e8d2ebb7392e | 16 | void errorhandler(unsigned err);//default error handler | 
| networker | 0:7493bf6bb1b9 | 17 | |
| networker | 3:e8d2ebb7392e | 18 | |
| networker | 3:e8d2ebb7392e | 19 | class SDPHandler: public SocketHandler { | 
| networker | 3:e8d2ebb7392e | 20 | // int _l2cap; | 
| networker | 3:e8d2ebb7392e | 21 | int sdp_socket; | 
| networker | 0:7493bf6bb1b9 | 22 | unsigned char l2cap_buf[100+OFFSET]; | 
| networker | 0:7493bf6bb1b9 | 23 | unsigned char* buf; | 
| networker | 0:7493bf6bb1b9 | 24 | unsigned txid; | 
| networker | 1:70ee392bcfd4 | 25 | unsigned char contState[17];//maximum size, in practive it is 3 | 
| networker | 1:70ee392bcfd4 | 26 | unsigned char *contBuf; | 
| networker | 1:70ee392bcfd4 | 27 | unsigned byteCount; | 
| networker | 1:70ee392bcfd4 | 28 | int _state; | 
| networker | 0:7493bf6bb1b9 | 29 | sdp_data *tree;//root of the entire service tree | 
| networker | 0:7493bf6bb1b9 | 30 | map<unsigned, serv_rec*> services;//the set of supported services <handle, service> | 
| networker | 0:7493bf6bb1b9 | 31 | map<unsigned, serv_rec*>::iterator index; | 
| networker | 3:e8d2ebb7392e | 32 | //server properties | 
| networker | 3:e8d2ebb7392e | 33 | // static map<unsigned, serv_rec*> server; | 
| networker | 3:e8d2ebb7392e | 34 | // static int serverSock; | 
| networker | 0:7493bf6bb1b9 | 35 | public: | 
| networker | 3:e8d2ebb7392e | 36 | SDPHandler(); | 
| networker | 3:e8d2ebb7392e | 37 | void Clear(); | 
| networker | 3:e8d2ebb7392e | 38 | virtual int Open(SocketInternal* sock, SocketAddrHdr* addr); | 
| networker | 3:e8d2ebb7392e | 39 | // virtual int Accept(SocketInternal *sock, int scid, int rxid); //called indirectly from BTDevice::Control | 
| networker | 3:e8d2ebb7392e | 40 | virtual int Send(SocketInternal* sock, const u8* data, int len); | 
| networker | 3:e8d2ebb7392e | 41 | virtual int Close(SocketInternal* sock); | 
| networker | 3:e8d2ebb7392e | 42 | virtual char* Name() { | 
| networker | 3:e8d2ebb7392e | 43 | return "SDPHandler SocketHandler"; | 
| networker | 2:d5a27b2d2e08 | 44 | } | 
| networker | 1:70ee392bcfd4 | 45 | void OnSdpRsp(const u8* data, int len); | 
| networker | 3:e8d2ebb7392e | 46 | static void OnSdpRsp(int socket, SocketState state, const u8* data, int len, void* userData); | 
| networker | 2:d5a27b2d2e08 | 47 | |
| networker | 0:7493bf6bb1b9 | 48 | //this function is called when the SDP sockets receives data (see HCICallback in TestShell), | 
| networker | 0:7493bf6bb1b9 | 49 | //currently does not happen because not forwarded from OnSdpRsp, can be used to handle multiple connections | 
| networker | 0:7493bf6bb1b9 | 50 | static void OnSockCallback(int socket, SocketState state, const u8* data, int len, void* userData) ; | 
| networker | 3:e8d2ebb7392e | 51 | //The SDP server is stateless hence can be static | 
| networker | 3:e8d2ebb7392e | 52 | // static void SDPServer(int socket, SocketState state, const u8* data, int len, void* userData) ; | 
| networker | 0:7493bf6bb1b9 | 53 | |
| networker | 0:7493bf6bb1b9 | 54 | void (*ErrorResponse)(unsigned) ; | 
| networker | 0:7493bf6bb1b9 | 55 | void (*ServiceSearchResponse)() ; | 
| networker | 0:7493bf6bb1b9 | 56 | void (*ServiceAttributeResponse)(serv_rec*) ; | 
| networker | 0:7493bf6bb1b9 | 57 | void (*ServiceSearchAttributeResponse)() ; | 
| networker | 0:7493bf6bb1b9 | 58 | int ServiceSearchRequest(sdp_data *sp, unsigned count, unsigned cs=0); | 
| networker | 0:7493bf6bb1b9 | 59 | int ServiceAttributeRequest(unsigned handle, unsigned count, sdp_data* al, unsigned cs=0) ; | 
| networker | 0:7493bf6bb1b9 | 60 | int ServiceSearchAttributeRequest(sdp_data *sp, unsigned count, sdp_data* al, unsigned cs=0); | 
| networker | 3:e8d2ebb7392e | 61 | //server | 
| networker | 3:e8d2ebb7392e | 62 | // static int ServiceSearchAttributeReply(unsigned rxid, sdp_data* al, unsigned count, unsigned cs=0); | 
| networker | 0:7493bf6bb1b9 | 63 | private: | 
| networker | 3:e8d2ebb7392e | 64 | // static unsigned length(const unsigned char *el, unsigned &p); | 
| networker | 3:e8d2ebb7392e | 65 | // static unsigned getval(const unsigned char *p, int n) ; | 
| networker | 3:e8d2ebb7392e | 66 | // static unsigned parseUUID(const u8* data, int len, unsigned &p); | 
| networker | 0:7493bf6bb1b9 | 67 | unsigned parse (const unsigned char *el, unsigned count, sdp_data* &result, serv_rec* &record) ; | 
| networker | 1:70ee392bcfd4 | 68 | unsigned parseLight (const unsigned char *el, unsigned count, sdp_data* &result, serv_rec* &record) ; | 
| networker | 0:7493bf6bb1b9 | 69 | int parseRsp(const unsigned char*rsp, int len) ; | 
| networker | 1:70ee392bcfd4 | 70 | void append(const unsigned char*rsp, int len) ; | 
| networker | 1:70ee392bcfd4 | 71 | void freeBuf(); | 
| networker | 0:7493bf6bb1b9 | 72 | }; | 
| networker | 3:e8d2ebb7392e | 73 | /* | 
| networker | 3:e8d2ebb7392e | 74 | class SDPClient: public SDPHandler { | 
| networker | 3:e8d2ebb7392e | 75 | }; | 
| networker | 3:e8d2ebb7392e | 76 | |
| networker | 3:e8d2ebb7392e | 77 | class SDPServer: public SDPHandler { | 
| networker | 3:e8d2ebb7392e | 78 | }; | 
| networker | 3:e8d2ebb7392e | 79 | */ | 
| networker | 3:e8d2ebb7392e | 80 | class SDPManager: public SocketHandler { | 
| networker | 3:e8d2ebb7392e | 81 | map<int, SDPHandler*> handlers; | 
| networker | 3:e8d2ebb7392e | 82 | //server properties | 
| networker | 3:e8d2ebb7392e | 83 | // SDPHandler *Server; | 
| networker | 3:e8d2ebb7392e | 84 | static map<unsigned, serv_rec*> server; | 
| networker | 3:e8d2ebb7392e | 85 | static int serverSock; | 
| networker | 3:e8d2ebb7392e | 86 | bool once; | 
| networker | 3:e8d2ebb7392e | 87 | public: | 
| networker | 3:e8d2ebb7392e | 88 | SDPManager() { | 
| networker | 3:e8d2ebb7392e | 89 | once = true; | 
| networker | 3:e8d2ebb7392e | 90 | } | 
| networker | 3:e8d2ebb7392e | 91 | virtual int Open(SocketInternal* sock, SocketAddrHdr* addr) { | 
| networker | 3:e8d2ebb7392e | 92 | printf("SDPManager::Open(sock (ID=%d, type=%d), addr): should not be called\n", sock->ID, sock->Type); | 
| networker | 3:e8d2ebb7392e | 93 | return sock->ID;//((SDPHandler*)sock->userData)->Open(sock, addr); | 
| networker | 3:e8d2ebb7392e | 94 | } | 
| networker | 3:e8d2ebb7392e | 95 | int Open(SocketAddrHdr* addr) { | 
| networker | 3:e8d2ebb7392e | 96 | L2CAPAddr* ad = (L2CAPAddr*)addr; | 
| networker | 3:e8d2ebb7392e | 97 | ad->psm = L2CAP_PSM_SDP;//open the l2cap channel | 
| networker | 3:e8d2ebb7392e | 98 | SDPHandler *h = new SDPHandler; | 
| networker | 3:e8d2ebb7392e | 99 | int s = Socket_Open(SOCKET_L2CAP, addr, &SDPHandler::OnSdpRsp, h); | 
| networker | 3:e8d2ebb7392e | 100 | handlers[s] = h; | 
| networker | 3:e8d2ebb7392e | 101 | return s; | 
| networker | 3:e8d2ebb7392e | 102 | } | 
| networker | 3:e8d2ebb7392e | 103 | virtual int Accept(SocketInternal *sock, int scid, int rxid) { //called indirectly from BTDevice::Control | 
| networker | 3:e8d2ebb7392e | 104 | if (once) { | 
| networker | 3:e8d2ebb7392e | 105 | once = false; | 
| networker | 3:e8d2ebb7392e | 106 | buildServer();//build the DB on the first connection | 
| networker | 3:e8d2ebb7392e | 107 | } | 
| networker | 3:e8d2ebb7392e | 108 | //sock is registered as an SDP sock but we use it as an L2CAP sock | 
| networker | 3:e8d2ebb7392e | 109 | //type=SDP | 
| networker | 3:e8d2ebb7392e | 110 | //userData = BTDevice | 
| networker | 3:e8d2ebb7392e | 111 | //Internal = L2CAPSocket | 
| networker | 3:e8d2ebb7392e | 112 | BTDevice *l2cap = (BTDevice*)sock->userData; | 
| networker | 3:e8d2ebb7392e | 113 | //sock->dcid = scid | 
| networker | 3:e8d2ebb7392e | 114 | //sock->scid = something based on sock->ID | 
| networker | 3:e8d2ebb7392e | 115 | serverSock = sock->ID; | 
| networker | 3:e8d2ebb7392e | 116 | printf("Invoking accept on %p (%s) for sock %d and scid=%d\n", l2cap, l2cap->Name(), sock->ID, scid); | 
| networker | 3:e8d2ebb7392e | 117 | return l2cap->Accept(sock, scid, rxid); | 
| networker | 3:e8d2ebb7392e | 118 | } | 
| networker | 3:e8d2ebb7392e | 119 | virtual int Send(SocketInternal* sock, const u8* data, int len) {//called by the server | 
| networker | 3:e8d2ebb7392e | 120 | BTDevice *l2cap = (BTDevice*)sock->userData; | 
| networker | 3:e8d2ebb7392e | 121 | return l2cap->Send(sock, data, len); | 
| networker | 3:e8d2ebb7392e | 122 | } | 
| networker | 3:e8d2ebb7392e | 123 | virtual int Close(SocketInternal* sock) { | 
| networker | 3:e8d2ebb7392e | 124 | printf("SDPManager::Close() closing socket %d\n", sock->ID); | 
| networker | 3:e8d2ebb7392e | 125 | SDPHandler *h = handlers[sock->ID]; | 
| networker | 3:e8d2ebb7392e | 126 | int retval = h->Close(sock); | 
| networker | 3:e8d2ebb7392e | 127 | delete h; | 
| networker | 3:e8d2ebb7392e | 128 | handlers[sock->ID] = 0; | 
| networker | 3:e8d2ebb7392e | 129 | return retval; | 
| networker | 3:e8d2ebb7392e | 130 | } | 
| networker | 3:e8d2ebb7392e | 131 | void Destroy(int s) { | 
| networker | 3:e8d2ebb7392e | 132 | printf("Deleting handler for socket %d\n", s); | 
| networker | 3:e8d2ebb7392e | 133 | delete handlers[s]; | 
| networker | 3:e8d2ebb7392e | 134 | handlers[s] = 0; | 
| networker | 3:e8d2ebb7392e | 135 | } | 
| networker | 3:e8d2ebb7392e | 136 | virtual char* Name() { | 
| networker | 3:e8d2ebb7392e | 137 | return "SDPManager SocketHandler"; | 
| networker | 3:e8d2ebb7392e | 138 | } | 
| networker | 3:e8d2ebb7392e | 139 | //void OnSdpRsp(const u8* data, int len); | 
| networker | 3:e8d2ebb7392e | 140 | static void OnSdpRsp(int socket, SocketState state, const u8* data, int len, void* userData) { | 
| networker | 3:e8d2ebb7392e | 141 | printf("SDPManager::OnSdpRsp(socket %d, state %d, len %d)\n", socket, state, len); | 
| networker | 3:e8d2ebb7392e | 142 | } | 
| networker | 3:e8d2ebb7392e | 143 | //The SDP server is (almost) stateless hence can be static | 
| networker | 3:e8d2ebb7392e | 144 | static void SDPServer(int socket, SocketState state, const u8* data, int len, void* userData) ; | 
| networker | 3:e8d2ebb7392e | 145 | static void match(bool elig[], unsigned uuid); | 
| networker | 3:e8d2ebb7392e | 146 | static bool isInList(unsigned short id, const unsigned char* list, int end); | 
| networker | 3:e8d2ebb7392e | 147 | static void addToReply(sdp_data *svc, serv_rec *list, const unsigned char* att, int end); | 
| networker | 3:e8d2ebb7392e | 148 | static int findUUID(unsigned h, unsigned uuid); | 
| networker | 3:e8d2ebb7392e | 149 | void buildServer(); | 
| networker | 3:e8d2ebb7392e | 150 | static int ServiceSearchAttributeReply(unsigned rxid, sdp_data* al, unsigned count, unsigned cs=0); | 
| networker | 3:e8d2ebb7392e | 151 | /* | 
| networker | 3:e8d2ebb7392e | 152 | //this function is called when the SDP sockets receives data (see HCICallback in TestShell), | 
| networker | 3:e8d2ebb7392e | 153 | //currently does not happen because not forwarded from OnSdpRsp, can be used to handle multiple connections | 
| networker | 3:e8d2ebb7392e | 154 | static void OnSockCallback(int socket, SocketState state, const u8* data, int len, void* userData) ; | 
| networker | 3:e8d2ebb7392e | 155 | |
| networker | 3:e8d2ebb7392e | 156 | static void errorhandler(unsigned err); | 
| networker | 3:e8d2ebb7392e | 157 | |
| networker | 3:e8d2ebb7392e | 158 | void (*ErrorResponse)(unsigned) ; | 
| networker | 3:e8d2ebb7392e | 159 | void (*ServiceSearchResponse)() ; | 
| networker | 3:e8d2ebb7392e | 160 | void (*ServiceAttributeResponse)(serv_rec*) ; | 
| networker | 3:e8d2ebb7392e | 161 | void (*ServiceSearchAttributeResponse)() ; | 
| networker | 3:e8d2ebb7392e | 162 | int ServiceSearchRequest(sdp_data *sp, unsigned count, unsigned cs=0); | 
| networker | 3:e8d2ebb7392e | 163 | int ServiceAttributeRequest(unsigned handle, unsigned count, sdp_data* al, unsigned cs=0) ; | 
| networker | 3:e8d2ebb7392e | 164 | int ServiceSearchAttributeRequest(sdp_data *sp, unsigned count, sdp_data* al, unsigned cs=0); | 
| networker | 3:e8d2ebb7392e | 165 | //server | 
| networker | 3:e8d2ebb7392e | 166 | private: | 
| networker | 3:e8d2ebb7392e | 167 | static unsigned length(const unsigned char *el, unsigned &p); | 
| networker | 3:e8d2ebb7392e | 168 | static unsigned getval(const unsigned char *p, int n) ; | 
| networker | 3:e8d2ebb7392e | 169 | static unsigned parseUUID(const u8* data, int len, unsigned &p); | 
| networker | 3:e8d2ebb7392e | 170 | static void addAttrib(unsigned h, unsigned short id, sdp_data *attrib); | 
| networker | 3:e8d2ebb7392e | 171 | static void addIndex(unsigned h, unsigned uuid); | 
| networker | 3:e8d2ebb7392e | 172 | static int findUUID(unsigned h, unsigned uuid); | 
| networker | 3:e8d2ebb7392e | 173 | static void match(bool elig[], unsigned uuid); | 
| networker | 3:e8d2ebb7392e | 174 | static bool isInList(unsigned short id, const unsigned char* list, int end); | 
| networker | 3:e8d2ebb7392e | 175 | void buildServer(); | 
| networker | 3:e8d2ebb7392e | 176 | unsigned parse (const unsigned char *el, unsigned count, sdp_data* &result, serv_rec* &record) ; | 
| networker | 3:e8d2ebb7392e | 177 | unsigned parseLight (const unsigned char *el, unsigned count, sdp_data* &result, serv_rec* &record) ; | 
| networker | 3:e8d2ebb7392e | 178 | int parseRsp(const unsigned char*rsp, int len) ; | 
| networker | 3:e8d2ebb7392e | 179 | void append(const unsigned char*rsp, int len) ; | 
| networker | 3:e8d2ebb7392e | 180 | void freeBuf(); | 
| networker | 3:e8d2ebb7392e | 181 | */ | 
| networker | 3:e8d2ebb7392e | 182 | }; | 
| networker | 0:7493bf6bb1b9 | 183 | |
| networker | 0:7493bf6bb1b9 | 184 | #endif |