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@2:d5a27b2d2e08, 2011-04-07 (annotated)
- Committer:
- networker
- Date:
- Thu Apr 07 21:01:39 2011 +0000
- Revision:
- 2:d5a27b2d2e08
- Parent:
- 1:70ee392bcfd4
- Child:
- 3:e8d2ebb7392e
fixed some memory problems; able to read my iPhone services
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 | 0:7493bf6bb1b9 | 4 | #include <map> | 
| networker | 0:7493bf6bb1b9 | 5 | #define OFFSET 8 | 
| networker | 0:7493bf6bb1b9 | 6 | |
| networker | 0:7493bf6bb1b9 | 7 | class SDPManager; | 
| networker | 0:7493bf6bb1b9 | 8 | extern SDPManager SDP; | 
| networker | 0:7493bf6bb1b9 | 9 | typedef map<unsigned short, sdp_data*> serv_rec; | 
| networker | 0:7493bf6bb1b9 | 10 | |
| networker | 0:7493bf6bb1b9 | 11 | void attribHandler(serv_rec *r); | 
| networker | 0:7493bf6bb1b9 | 12 | |
| networker | 2:d5a27b2d2e08 | 13 | //TODO: add support for multiple connections | 
| networker | 2:d5a27b2d2e08 | 14 | //TODO: add server support, now only client | 
| networker | 0:7493bf6bb1b9 | 15 | //at the moment, SDP can handle only one connection at a time | 
| networker | 0:7493bf6bb1b9 | 16 | class SDPManager: public SocketHandler { | 
| networker | 0:7493bf6bb1b9 | 17 | int _l2cap; | 
| networker | 0:7493bf6bb1b9 | 18 | int sdp_socket; //at the moment the only socket | 
| networker | 0:7493bf6bb1b9 | 19 | unsigned char l2cap_buf[100+OFFSET]; | 
| networker | 0:7493bf6bb1b9 | 20 | unsigned char* buf; | 
| networker | 0:7493bf6bb1b9 | 21 | unsigned txid; | 
| networker | 1:70ee392bcfd4 | 22 | unsigned char contState[17];//maximum size, in practive it is 3 | 
| networker | 1:70ee392bcfd4 | 23 | unsigned char *contBuf; | 
| networker | 1:70ee392bcfd4 | 24 | unsigned byteCount; | 
| networker | 1:70ee392bcfd4 | 25 | int _state; | 
| networker | 0:7493bf6bb1b9 | 26 | sdp_data *tree;//root of the entire service tree | 
| networker | 0:7493bf6bb1b9 | 27 | map<unsigned, serv_rec*> services;//the set of supported services <handle, service> | 
| networker | 0:7493bf6bb1b9 | 28 | map<unsigned, serv_rec*>::iterator index; | 
| networker | 0:7493bf6bb1b9 | 29 | public: | 
| networker | 0:7493bf6bb1b9 | 30 | SDPManager(): _l2cap(0), txid(1), tree(0) { | 
| networker | 0:7493bf6bb1b9 | 31 | ErrorResponse=errorhandler; | 
| networker | 0:7493bf6bb1b9 | 32 | ServiceSearchResponse=0; | 
| networker | 0:7493bf6bb1b9 | 33 | ServiceAttributeResponse=attribHandler; | 
| networker | 0:7493bf6bb1b9 | 34 | ServiceSearchAttributeResponse=0; | 
| networker | 0:7493bf6bb1b9 | 35 | buf = l2cap_buf+OFFSET; | 
| networker | 1:70ee392bcfd4 | 36 | contBuf = 0; | 
| networker | 1:70ee392bcfd4 | 37 | byteCount = 0; | 
| networker | 1:70ee392bcfd4 | 38 | contState[0] = 0; | 
| networker | 1:70ee392bcfd4 | 39 | _state = 0; | 
| networker | 0:7493bf6bb1b9 | 40 | } | 
| networker | 0:7493bf6bb1b9 | 41 | |
| networker | 2:d5a27b2d2e08 | 42 | void Clear() { | 
| networker | 2:d5a27b2d2e08 | 43 | for (index = services.begin(); index != services.end(); index++) {//for all services | 
| networker | 2:d5a27b2d2e08 | 44 | for (serv_rec::iterator it = index->second->begin(); it != index->second->end(); it++)//for all attributes | 
| networker | 2:d5a27b2d2e08 | 45 | delete it->second; //delete the attribute value tree | 
| networker | 2:d5a27b2d2e08 | 46 | delete (*index).second; //delete the attribute list | 
| networker | 2:d5a27b2d2e08 | 47 | } | 
| networker | 2:d5a27b2d2e08 | 48 | services.clear();//and empty the services list | 
| networker | 2:d5a27b2d2e08 | 49 | } | 
| networker | 2:d5a27b2d2e08 | 50 | |
| networker | 0:7493bf6bb1b9 | 51 | //Called as: Socket_Open(SOCKET_SDP, addr, callback, userdata(this)) | 
| networker | 0:7493bf6bb1b9 | 52 | virtual int Open(SocketInternal* sock, SocketAddrHdr* addr) { | 
| networker | 0:7493bf6bb1b9 | 53 | L2CAPAddr* ad = (L2CAPAddr*)addr; | 
| networker | 0:7493bf6bb1b9 | 54 | if (_l2cap) { | 
| networker | 2:d5a27b2d2e08 | 55 | printf("This SDP supports only one connection at a time\n"); | 
| networker | 2:d5a27b2d2e08 | 56 | return 0; | 
| networker | 1:70ee392bcfd4 | 57 | } | 
| networker | 0:7493bf6bb1b9 | 58 | //BD_ADDR* a = &ad->bdaddr; | 
| networker | 0:7493bf6bb1b9 | 59 | sdp_socket = sock->ID; | 
| networker | 0:7493bf6bb1b9 | 60 | ad->psm = L2CAP_PSM_SDP;//open the l2cap channel | 
| networker | 0:7493bf6bb1b9 | 61 | _l2cap = Socket_Open(SOCKET_L2CAP, addr, OnSdpRsp, this);//this is the socket between SDP and the L2CAP layer | 
| networker | 0:7493bf6bb1b9 | 62 | if (_l2cap <= 0) { | 
| networker | 0:7493bf6bb1b9 | 63 | printf("Opening L2CAP channel failed\n"); | 
| networker | 0:7493bf6bb1b9 | 64 | return _l2cap; | 
| networker | 0:7493bf6bb1b9 | 65 | } | 
| networker | 0:7493bf6bb1b9 | 66 | printf("Successfully opened L2CAP channel for SDP on socket %d\n", _l2cap); | 
| networker | 0:7493bf6bb1b9 | 67 | return sock->ID; | 
| networker | 0:7493bf6bb1b9 | 68 | } | 
| networker | 0:7493bf6bb1b9 | 69 | |
| networker | 0:7493bf6bb1b9 | 70 | virtual int Send(SocketInternal* sock, const u8* data, int len) { | 
| networker | 0:7493bf6bb1b9 | 71 | printf("SDPManager::Send should not be called directly\n"); | 
| networker | 0:7493bf6bb1b9 | 72 | return Socket_Send(_l2cap, data, len); | 
| networker | 0:7493bf6bb1b9 | 73 | } | 
| networker | 0:7493bf6bb1b9 | 74 | |
| networker | 0:7493bf6bb1b9 | 75 | virtual int Close(SocketInternal* sock) { | 
| networker | 2:d5a27b2d2e08 | 76 | Clear(); | 
| networker | 2:d5a27b2d2e08 | 77 | printf("SDP socket %d and L2CAP socket %d closed, freemem=%d\n", sock->ID, _l2cap, AvailableMemory(1)); | 
| networker | 2:d5a27b2d2e08 | 78 | int retval = Socket_Close(_l2cap);//could also keep it open for the next connection | 
| networker | 2:d5a27b2d2e08 | 79 | _l2cap = 0; | 
| networker | 2:d5a27b2d2e08 | 80 | return retval; | 
| networker | 0:7493bf6bb1b9 | 81 | } | 
| networker | 0:7493bf6bb1b9 | 82 | |
| networker | 0:7493bf6bb1b9 | 83 | virtual char* Name() { | 
| networker | 0:7493bf6bb1b9 | 84 | return "SDPManager SocketHandler"; | 
| networker | 0:7493bf6bb1b9 | 85 | } | 
| networker | 0:7493bf6bb1b9 | 86 | |
| networker | 1:70ee392bcfd4 | 87 | void OnSdpRsp(const u8* data, int len); | 
| networker | 0:7493bf6bb1b9 | 88 | //this function is called when the L2CAP layer receives SDP packets (see SDPManager::Open), userdata is the sdpmanager instance | 
| networker | 1:70ee392bcfd4 | 89 | static void OnSdpRsp(int socket, SocketState state, const u8* data, int len, void* userData) { | 
| networker | 1:70ee392bcfd4 | 90 | printf("\x1B[%dm", 35); | 
| networker | 2:d5a27b2d2e08 | 91 | // printf("OnSdpRsp(socket=%d, state=%d, len=%d)\n", socket, state, len); | 
| networker | 2:d5a27b2d2e08 | 92 | printf("OnSdpRsp(socket=%d, state=%d, len=%d, freemem=%d\n", socket, state, len, AvailableMemory(1)); | 
| networker | 1:70ee392bcfd4 | 93 | SDPManager *self = (SDPManager*)userData; | 
| networker | 2:d5a27b2d2e08 | 94 | if (state == SocketState_Open) { | 
| networker | 1:70ee392bcfd4 | 95 | self->OnSdpRsp(data, len); | 
| networker | 1:70ee392bcfd4 | 96 | } | 
| networker | 1:70ee392bcfd4 | 97 | printf("\x1B[%dm", 0); | 
| networker | 1:70ee392bcfd4 | 98 | } | 
| networker | 2:d5a27b2d2e08 | 99 | |
| networker | 0:7493bf6bb1b9 | 100 | //this function is called when the SDP sockets receives data (see HCICallback in TestShell), | 
| networker | 0:7493bf6bb1b9 | 101 | //currently does not happen because not forwarded from OnSdpRsp, can be used to handle multiple connections | 
| networker | 0:7493bf6bb1b9 | 102 | static void OnSockCallback(int socket, SocketState state, const u8* data, int len, void* userData) ; | 
| networker | 0:7493bf6bb1b9 | 103 | static void errorhandler(unsigned err); | 
| networker | 0:7493bf6bb1b9 | 104 | |
| networker | 0:7493bf6bb1b9 | 105 | void (*ErrorResponse)(unsigned) ; | 
| networker | 0:7493bf6bb1b9 | 106 | void (*ServiceSearchResponse)() ; | 
| networker | 0:7493bf6bb1b9 | 107 | void (*ServiceAttributeResponse)(serv_rec*) ; | 
| networker | 0:7493bf6bb1b9 | 108 | void (*ServiceSearchAttributeResponse)() ; | 
| networker | 0:7493bf6bb1b9 | 109 | int ServiceSearchRequest(sdp_data *sp, unsigned count, unsigned cs=0); | 
| networker | 0:7493bf6bb1b9 | 110 | int ServiceAttributeRequest(unsigned handle, unsigned count, sdp_data* al, unsigned cs=0) ; | 
| networker | 0:7493bf6bb1b9 | 111 | int ServiceSearchAttributeRequest(sdp_data *sp, unsigned count, sdp_data* al, unsigned cs=0); | 
| networker | 0:7493bf6bb1b9 | 112 | private: | 
| networker | 0:7493bf6bb1b9 | 113 | unsigned length(const unsigned char *el, unsigned &p); | 
| networker | 0:7493bf6bb1b9 | 114 | unsigned getval(const unsigned char *p, int n) ; | 
| networker | 0:7493bf6bb1b9 | 115 | unsigned parse (const unsigned char *el, unsigned count, sdp_data* &result, serv_rec* &record) ; | 
| networker | 1:70ee392bcfd4 | 116 | unsigned parseLight (const unsigned char *el, unsigned count, sdp_data* &result, serv_rec* &record) ; | 
| networker | 0:7493bf6bb1b9 | 117 | int parseRsp(const unsigned char*rsp, int len) ; | 
| networker | 1:70ee392bcfd4 | 118 | void append(const unsigned char*rsp, int len) ; | 
| networker | 1:70ee392bcfd4 | 119 | void freeBuf(); | 
| networker | 0:7493bf6bb1b9 | 120 | }; | 
| networker | 0:7493bf6bb1b9 | 121 | |
| networker | 0:7493bf6bb1b9 | 122 | #endif |