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
Diff: sdp.h
- Revision:
- 3:e8d2ebb7392e
- Parent:
- 2:d5a27b2d2e08
- Child:
- 4:d5c3e499603d
--- a/sdp.h Thu Apr 07 21:01:39 2011 +0000
+++ b/sdp.h Wed May 04 09:27:32 2011 +0000
@@ -1,6 +1,7 @@
#ifndef SDP_H
#define SDP_H
#include "AvailableMemory.h"
+#include "sdp_data.h"
#include <map>
#define OFFSET 8
@@ -9,13 +10,15 @@
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
-//TODO: add support for multiple connections
-//TODO: add server support, now only client
-//at the moment, SDP can handle only one connection at a time
-class SDPManager: public SocketHandler {
- int _l2cap;
- int sdp_socket; //at the moment the only socket
+
+class SDPHandler: public SocketHandler {
+// int _l2cap;
+ int sdp_socket;
unsigned char l2cap_buf[100+OFFSET];
unsigned char* buf;
unsigned txid;
@@ -26,81 +29,27 @@
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:
- SDPManager(): _l2cap(0), txid(1), tree(0) {
- ErrorResponse=errorhandler;
- ServiceSearchResponse=0;
- ServiceAttributeResponse=attribHandler;
- ServiceSearchAttributeResponse=0;
- buf = l2cap_buf+OFFSET;
- contBuf = 0;
- byteCount = 0;
- contState[0] = 0;
- _state = 0;
- }
-
- void Clear() {
- for (index = services.begin(); index != services.end(); index++) {//for all services
- for (serv_rec::iterator it = index->second->begin(); it != index->second->end(); it++)//for all attributes
- delete it->second; //delete the attribute value tree
- delete (*index).second; //delete the attribute list
- }
- services.clear();//and empty the services list
+ 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";
}
-
- //Called as: Socket_Open(SOCKET_SDP, addr, callback, userdata(this))
- virtual int Open(SocketInternal* sock, SocketAddrHdr* addr) {
- L2CAPAddr* ad = (L2CAPAddr*)addr;
- if (_l2cap) {
- printf("This SDP supports only one connection at a time\n");
- return 0;
- }
- //BD_ADDR* a = &ad->bdaddr;
- sdp_socket = sock->ID;
- ad->psm = L2CAP_PSM_SDP;//open the l2cap channel
- _l2cap = Socket_Open(SOCKET_L2CAP, addr, OnSdpRsp, this);//this is the socket between SDP and the L2CAP layer
- if (_l2cap <= 0) {
- printf("Opening L2CAP channel failed\n");
- return _l2cap;
- }
- printf("Successfully opened L2CAP channel for SDP on socket %d\n", _l2cap);
- return sock->ID;
- }
-
- virtual int Send(SocketInternal* sock, const u8* data, int len) {
- printf("SDPManager::Send should not be called directly\n");
- return Socket_Send(_l2cap, data, len);
- }
-
- virtual int Close(SocketInternal* sock) {
- Clear();
- printf("SDP socket %d and L2CAP socket %d closed, freemem=%d\n", sock->ID, _l2cap, AvailableMemory(1));
- int retval = Socket_Close(_l2cap);//could also keep it open for the next connection
- _l2cap = 0;
- return retval;
- }
-
- virtual char* Name() {
- return "SDPManager SocketHandler";
- }
-
void OnSdpRsp(const u8* data, int len);
- //this function is called when the L2CAP layer receives SDP packets (see SDPManager::Open), userdata is the sdpmanager instance
- static void OnSdpRsp(int socket, SocketState state, const u8* data, int len, void* userData) {
- printf("\x1B[%dm", 35);
-// printf("OnSdpRsp(socket=%d, state=%d, len=%d)\n", socket, state, len);
- printf("OnSdpRsp(socket=%d, state=%d, len=%d, freemem=%d\n", socket, state, len, AvailableMemory(1));
- SDPManager *self = (SDPManager*)userData;
- if (state == SocketState_Open) {
- self->OnSdpRsp(data, len);
- }
- printf("\x1B[%dm", 0);
- }
+ 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) ;
- static void errorhandler(unsigned err);
+ //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)() ;
@@ -109,14 +58,127 @@
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:
- unsigned length(const unsigned char *el, unsigned &p);
- unsigned getval(const unsigned char *p, int n) ;
+// 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 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
\ No newline at end of file