diff options
Diffstat (limited to 'library/ADK2/btSDP.c')
-rw-r--r-- | library/ADK2/btSDP.c | 746 |
1 files changed, 0 insertions, 746 deletions
diff --git a/library/ADK2/btSDP.c b/library/ADK2/btSDP.c deleted file mode 100644 index 75a6035..0000000 --- a/library/ADK2/btSDP.c +++ /dev/null @@ -1,746 +0,0 @@ -/* - * Copyright (C) 2012 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -#define ADK_INTERNAL -#include "fwk.h" -#include "btSDP.h" -#include <string.h> -#include "sgBuf.h" -#include "btL2CAP.h" - - -#define SDP_PDU_Error_Response 1 -#define SDP_PDU_Service_Search_Request 2 -#define SDP_PDU_Service_Search_Response 3 -#define SDP_PDU_Service_Attribute_Request 4 -#define SDP_PDU_Service_Attribute_Response 5 -#define SDP_PDU_Service_Search_Attribute_Request 6 -#define SDP_PDU_Service_Search_Attribute_Response 7 - -#define SDP_ERR_Invalid_SDP_Version 0x0001 -#define SDP_ERR_Invalid_Service_Record_Handle 0x0002 -#define SDP_ERR_Invalid_Request_Syntax 0x0003 -#define SDP_ERR_Invalid_PDU_Size 0x0004 -#define SDP_ERR_Invalid_Continuation_State 0x0005 -#define SDP_ERR_Insufficient_Resources 0x0006 - - -typedef struct{ - - uint64_t hi, lo; - -}uuid; - -#define MAX_UUIDS_IN_SEARCH 12 //as per spec -#define MAX_ATTRS_IN_SEARCH_STRING 8 //as per my opinion -#define MAX_SEARCH_RESULTS 16 //no more than this will ever be returned - -typedef struct SdpService{ - - struct SdpService* next; - - uint32_t handle; - const uint8_t* descriptor; - uint16_t descrLen; - -}SdpService; - -typedef struct{ - - uint16_t aclConn; - uint16_t remChan; - - uint32_t contDescr; //which continuation descriptor we expect - uint8_t* result; - uint32_t resultSz; - uint16_t numMatches; //for servicesearch - -}SdpInstance; - - -static SdpService* knownServices = NULL; -static uint32_t sdpContVal = 0x12345678; -static uint32_t sdpNextHandle = 0; - -static const uint8_t sdpDescrSdp[] = -{ - //define the SDP service itself - //service class ID list - SDP_ITEM_DESC(SDP_TYPE_UINT, SDP_SZ_2), 0x00, 0x01, SDP_ITEM_DESC(SDP_TYPE_ARRAY, SDP_SZ_u8), 3, - SDP_ITEM_DESC(SDP_TYPE_UUID, SDP_SZ_2), 0x10, 0x00, // ServiceDiscoveryServerServiceClassID - //ProtocolDescriptorList - SDP_ITEM_DESC(SDP_TYPE_UINT, SDP_SZ_2), 0x00, 0x04, SDP_ITEM_DESC(SDP_TYPE_ARRAY, SDP_SZ_u8), 8, - SDP_ITEM_DESC(SDP_TYPE_ARRAY, SDP_SZ_u8), 6, - SDP_ITEM_DESC(SDP_TYPE_UUID, SDP_SZ_2), 0x01, 0x00, // L2CAP - SDP_ITEM_DESC(SDP_TYPE_UINT, SDP_SZ_2), L2CAP_PSM_SDP >> 8, L2CAP_PSM_SDP & 0xFF, // L2CAP PSM - - //browse group list - SDP_ITEM_DESC(SDP_TYPE_UINT, SDP_SZ_2), 0x00, 0x05, SDP_ITEM_DESC(SDP_TYPE_ARRAY, SDP_SZ_u8), 3, - SDP_ITEM_DESC(SDP_TYPE_UUID, SDP_SZ_2), 0x10, 0x02, // Public Browse Group - - //magic data #1 - SDP_ITEM_DESC(SDP_TYPE_UINT, SDP_SZ_2), 0xDD, 0xDD, SDP_ITEM_DESC(SDP_TYPE_TEXT, SDP_SZ_u8), 19, 0x53, 0x57, 0x3A, 0x20, 0x44, 0x6D, 0x69, 0x74, 0x72, 0x79, 0x20, 0x47, 0x72, 0x69, 0x6e, 0x62, 0x65, 0x72, 0x67, - //magic data #2 - SDP_ITEM_DESC(SDP_TYPE_UINT, SDP_SZ_2), 0xDD, 0xDE, SDP_ITEM_DESC(SDP_TYPE_TEXT, SDP_SZ_u8), 19, 0x48, 0x57, 0x3A, 0x20, 0x45, 0x72, 0x69, 0x63, 0x20, 0x53, 0x63, 0x68, 0x6c, 0x61, 0x65, 0x70, 0x66, 0x65, 0x72 -}; - -static const uuid bt_base_uuid = {0x0000000000001000ULL, 0x800000805F9B34FBULL}; - -static void sdpIntToUUID(uuid* dst, uint32_t val){ - - *dst = bt_base_uuid; - dst->hi += ((uint64_t)val) << 32; -} - -static char sdpUuidEqual(const uuid* a, const uuid* b){ - - return a->lo == b->lo && a->hi == b->hi; -} - -static uint32_t btSdpGetElemSz(const uint8_t** descr){ - - const uint8_t* ptr = *descr; - uint8_t item = *ptr++; - uint32_t sz = 0; - - if((item >> 3) != SDP_TYPE_NIL){ - - switch(item & 7){ - - case SDP_SZ_1: - case SDP_SZ_2: - case SDP_SZ_4: - case SDP_SZ_8: - case SDP_SZ_16: - - sz = 1 << (item & 7); - break; - - case SDP_SZ_u8: - - sz = *ptr++; - break; - - case SDP_SZ_u16: - - sz = ptr[0]; - sz = (sz << 8) | ptr[1]; - ptr += 2; - break; - - case SDP_SZ_u32: - - sz = ptr[0]; - sz = (sz << 8) | ptr[1]; - sz = (sz << 8) | ptr[2]; - sz = (sz << 8) | ptr[3]; - ptr += 4; - break; - } - } - *descr = ptr; - return sz; -} - -static uint8_t btSdpGetUUID(const uint8_t** descr, uuid* dst){ //return num bytes consumed - - uint32_t sz, i; - const uint8_t* orig = *descr; - - if(((**descr) >> 3) != SDP_TYPE_UUID) return 0; //not valid UUID type - sz = btSdpGetElemSz(descr); - - switch(sz){ - - case 2: - - sdpIntToUUID(dst, (((uint32_t)((*descr)[0])) << 8) | ((*descr)[1])); - break; - - case 4: - - sdpIntToUUID(dst, (((uint32_t)((*descr)[0])) << 24) | (((uint32_t)((*descr)[1])) << 16) | (((uint32_t)((*descr)[2])) << 8) | ((*descr)[3])); - break; - - case 16: - - dst->lo = 0; - dst->hi = 0; - - for(i = 0; i < 8; i++){ - - dst->lo = (dst->lo << 8) | (*descr)[i]; - dst->hi = (dst->lo << 8) | (*descr)[i + 8]; - } - break; - - default: - - return 0; - } - *descr += sz; - - return (*descr) - orig; -} - -static void btStdRecursiveWalk(void* itemList, uint8_t* listSzP, sg_buf** walkResultP, const uint8_t** ptr, uint32_t len){ - - uint32_t sz; - uint8_t typ, numWantedIDs; - const uint8_t* end = (*ptr) + len; - uuid id; - sg_buf* result = NULL; - char isID = 1, skipNext = 0; - uuid* wantedIDs; - uint8_t* numWantedIDsP; - uint32_t* wantedRanges; - uint8_t wantedRangesListSz; - - - if(walkResultP){ //copy-traversal - - result = sg_alloc(); - if(!result) return; - - wantedIDs = NULL; - numWantedIDsP = NULL; - wantedRanges = itemList; - wantedRangesListSz = *listSzP; - } - else{ //search for UUIDs - - wantedIDs = itemList; - numWantedIDsP = listSzP; - numWantedIDs = *numWantedIDsP; - wantedRanges = NULL; - wantedRangesListSz = 0; - } - - while((*ptr) < end){ - - typ = (**ptr) >> 3; - - if(wantedIDs && typ == SDP_TYPE_UUID){ - - sz = btSdpGetUUID(ptr, &id); - if(end < (*ptr)){ - - dbgPrintf("SDP: UUID size > allowed size (%d, %d)\n", sz, end - (*ptr)); - goto out; - } - - for(sz = 0; sz < numWantedIDs; sz++){ - - if(sdpUuidEqual(wantedIDs + sz, &id)){ - - wantedIDs[sz] = wantedIDs[numWantedIDs - 1]; - numWantedIDs--; - sz--; - } - } - } - else{ - - const uint8_t* itemStart = *ptr; - - sz = btSdpGetElemSz(ptr); - - if(sz > (unsigned)(end - (*ptr))){ - - dbgPrintf("SDP: element size > allowed size (%d, %d)\n", sz, end - (*ptr)); - goto out; - } - - if(typ == SDP_TYPE_ARRAY || typ == SDP_TYPE_OR_LIST){ - - btStdRecursiveWalk(wantedIDs, &numWantedIDs, NULL, ptr, sz); - } - else{ - - (*ptr) += sz; - } - if(walkResultP){ - - if(isID){ - - uint16_t attrID; - uint8_t i; - - if(sz != 2) dbgPrintf("SDP: attrib ID not 16 bits!\n"); - - attrID = (*ptr)[-2]; - attrID = (attrID << 8) | (*ptr)[-1]; - - skipNext = 2; - for(i = 0; i < wantedRangesListSz && skipNext; i++){ - - if(attrID >= (wantedRanges[i] >> 16) && attrID <= (wantedRanges[i] & 0xFFFF)) skipNext = 0; //in range - } - } - isID ^= 1; - - if(skipNext){ - - skipNext--; - } - else{ - - if(!sg_add_back(result, itemStart, (*ptr) - itemStart, SG_FLAG_MAKE_A_COPY)){ - - sg_free(result); - return; - } - } - } - } - } - -out: - if(walkResultP) *walkResultP = result; - if(numWantedIDsP) *numWantedIDsP = numWantedIDs; -} - -static char btSdpPutIntoGroup(sg_buf* buf){ - - uint8_t i, sizeFieldSz, sizeFieldName; - uint32_t sz = sg_length(buf); - uint8_t res[5]; - - //figure out needed header size field - if(sz < 0x100){ - - sizeFieldSz = 1; - sizeFieldName = SDP_SZ_u8; - sz <<= 24; - } - else if(sz < 0x10000){ - - sizeFieldSz = 2; - sizeFieldName = SDP_SZ_u16; - sz <<= 16; - } - else{ - - sizeFieldSz = 4; - sizeFieldName = SDP_SZ_u32; - } - - //add the header - res[0] = SDP_ITEM_DESC(SDP_TYPE_ARRAY, sizeFieldName); - for(i = 0; i < sizeFieldSz; i++, sz <<= 8) res[1 + i] = sz >> 24; - return sg_add_front(buf, res, 1 + sizeFieldSz, SG_FLAG_MAKE_A_COPY); -} - -static sg_buf* btSdpError(const uint8_t* trans, uint16_t errNum){ - - sg_buf* buf; - uint8_t data[] = {SDP_PDU_Error_Response, trans[0], trans[1], errNum >> 8, errNum, 0, 0}; - - buf = sg_alloc(); - if(buf){ - - if(!sg_add_front(buf, data, sizeof(data), SG_FLAG_MAKE_A_COPY)){ - - sg_free(buf); - buf = NULL; - } - } - return NULL; -} - -static sg_buf* btSdpProcessRequest(SdpInstance* inst, const uint8_t* req, uint16_t reqSz){ - uint8_t trans[2] ,cmd, contStateSz, numIDs = 0, numAttrs = 0; - uint32_t maxReplSz = 0, wantedHandle = 0, sz; - uint32_t attrs[MAX_ATTRS_IN_SEARCH_STRING]; - SdpService* results[MAX_SEARCH_RESULTS]; - uuid ids[MAX_UUIDS_IN_SEARCH]; - const uint8_t* end; - sg_buf* result; - unsigned i, j; - - cmd = *req++; - trans[0] = *req++; - trans[1] = *req++; - - reqSz -= 5; - if(reqSz != (((uint16_t)req[0]) << 8) + req[1]) return btSdpError(trans, SDP_ERR_Invalid_PDU_Size); - req += 2; - - //dbgPrintf("SDP request cmd %d (session %02X%02X) with %d bytes of data\n", cmd, trans[0], trans[1], reqSz); - - if(cmd == SDP_PDU_Service_Search_Request || cmd == SDP_PDU_Service_Search_Attribute_Request){ - - if((*req) >> 3 != SDP_TYPE_ARRAY) return btSdpError(trans, SDP_ERR_Invalid_Request_Syntax); - sz = btSdpGetElemSz(&req); - end = req + sz; - - while(req < end){ - - if(numIDs == MAX_UUIDS_IN_SEARCH) return btSdpError(trans, SDP_ERR_Invalid_Request_Syntax); //too many requests - if(!btSdpGetUUID(&req, &ids[numIDs++])) return btSdpError(trans, SDP_ERR_Invalid_Request_Syntax); //malformed UUID - } - } - else if(cmd == SDP_PDU_Service_Attribute_Request){ - - for(i = 0; i < 4; i++) wantedHandle = (wantedHandle << 8) | *req++; - } - else{ - - dbgPrintf("SDP: invalid request: %d\n", cmd); - return btSdpError(trans, SDP_ERR_Invalid_Request_Syntax); - } - - for(i = 0; i < 2; i++) maxReplSz = (maxReplSz << 8) | *req++; - - if(cmd == SDP_PDU_Service_Attribute_Request || cmd == SDP_PDU_Service_Search_Attribute_Request){ - - if((*req) >> 3 != SDP_TYPE_ARRAY) return btSdpError(trans, SDP_ERR_Invalid_Request_Syntax); - sz = btSdpGetElemSz(&req); - end = req + sz; - - while(req < end){ - - if(numAttrs == MAX_UUIDS_IN_SEARCH) return btSdpError(trans, SDP_ERR_Insufficient_Resources); //too many -> unsupported request -> fail - sz = btSdpGetElemSz(&req); - if(sz == 2){ - - sz = 0; - for(i =0; i < 2; i++) sz = (sz << 8) | *req++; - sz |= sz << 16; - } - else if(sz == 4){ - - sz = 0; - for(i =0; i < 4; i++) sz = (sz << 8) | *req++; - } - else return btSdpError(trans, SDP_ERR_Invalid_Request_Syntax); //fail -> invalid number format - attrs[numAttrs++] = sz; - } - } - - contStateSz = *req++; - - if(contStateSz){ // verify continuation is valid or fail - uint32_t contState = 0; - - if(contStateSz != sizeof(uint32_t)) return btSdpError(trans, SDP_ERR_Invalid_Continuation_State); - for(i = 0; i < 4; i++) contState = (contState << 8) | *req++; - - if(contState != inst->contDescr || !inst->result){ - - dbgPrintf("SDP: invalid continuation state. Wanted %08X, got %08X\n", inst->contDescr, contState); - if(inst->result){ - - free(inst->result); - inst->result = NULL; - } - return btSdpError(trans, SDP_ERR_Invalid_Continuation_State); - } - } - else{ //perform the actual search - - SdpService* curSvc = knownServices; - uint8_t numFound = 0; - - //cleanup first - if(inst->result){ - - free(inst->result); - inst->result = NULL; - } - - //perform the search - if(cmd == SDP_PDU_Service_Search_Request || cmd == SDP_PDU_Service_Search_Attribute_Request){ - - for(curSvc = knownServices; curSvc && numFound < MAX_SEARCH_RESULTS; curSvc = curSvc->next){ - - const uint8_t* ptr = curSvc->descriptor; - uuid uuids_copy[MAX_UUIDS_IN_SEARCH]; - uint8_t num; - - for(num = 0; num < numIDs; num++) uuids_copy[num] = ids[num]; - - btStdRecursiveWalk(uuids_copy, &num, NULL, &ptr, curSvc->descrLen); - if(!num) results[numFound++] = curSvc; - } - } - else if(cmd == SDP_PDU_Service_Attribute_Request){ - - for(curSvc = knownServices; curSvc && !numFound; curSvc = curSvc->next){ - - if(curSvc->handle == wantedHandle) results[numFound++] = curSvc; - } - if(!numFound) return btSdpError(trans, SDP_ERR_Invalid_Service_Record_Handle); - } - - //gather & prepare results - if(cmd == SDP_PDU_Service_Attribute_Request || cmd == SDP_PDU_Service_Search_Attribute_Request){ - - //we'll assemble the whole result in this buffer - sg_buf* resultSoFar = sg_alloc(); - if(!resultSoFar) return btSdpError(trans, SDP_ERR_Insufficient_Resources); - - //process each match - for(i = 0; i < numFound; i++){ - - const uint8_t* ptr = results[i]->descriptor; - sg_buf* res; - - //collect wanted attributes - btStdRecursiveWalk(attrs, &numAttrs, &res, &ptr, results[i]->descrLen); - if(!res) continue; - - //if requested, add the handle attribute - for(j = 0; j < numAttrs; j++) if(SDP_ATTR_HANDLE >= (attrs[j] >> 16) && SDP_ATTR_HANDLE <= (attrs[j] & 0xFFFF)) break; - if(j != numAttrs){ - uint8_t buf[8] = {SDP_ITEM_DESC(SDP_TYPE_UINT, SDP_SZ_2), 0x00, 0x00, SDP_ITEM_DESC(SDP_TYPE_UINT, SDP_SZ_4)}; - - buf[4] = results[i]->handle >> 24; - buf[5] = results[i]->handle >> 16; - buf[6] = results[i]->handle >> 8; - buf[7] = results[i]->handle; - - if(!sg_add_back(res, buf, sizeof(buf), SG_FLAG_MAKE_A_COPY)){ - - sg_free(res); - free(res); - continue; - } - } - - //wrap and append to the full results list - if(btSdpPutIntoGroup(res)) sg_concat_back(resultSoFar, res); - sg_free(res); - free(res); - } - - //wrap the whole thing if required - if((cmd == SDP_PDU_Service_Search_Attribute_Request) && !btSdpPutIntoGroup(resultSoFar)){ - dbgPrintf("SDP: Failed to put results into a group\n"); - sg_free(resultSoFar); - free(resultSoFar); - return btSdpError(trans, SDP_ERR_Insufficient_Resources); - } - - //flatten to a buffer - uint8_t* buf = malloc(sg_length(resultSoFar)); - if(!buf){ - - dbgPrintf("SDP: Failed to allocate flattened result array (%ub)\n", sg_length(resultSoFar)); - sg_free(resultSoFar); - free(resultSoFar); - return btSdpError(trans, SDP_ERR_Insufficient_Resources); - } - inst->resultSz = sg_length(resultSoFar); - inst->result = buf; - inst->contDescr = sdpContVal; - sg_copyto(resultSoFar, buf); - sg_free(resultSoFar); - free(resultSoFar); - } - else if(cmd == SDP_PDU_Service_Search_Request){ - - //allocate the array - inst->resultSz = sizeof(uint32_t[numFound]); - uint8_t* buf = malloc(inst->resultSz); - - if(!buf){ - - dbgPrintf("SDP: Failed to allocate flattened result array (%ub)\n", sizeof(uint32_t[numFound])); - return btSdpError(trans, SDP_ERR_Insufficient_Resources); - } - - //process each match - for(i = 0; i < numFound; i++){ - - buf[i * 4 + 0] = results[i]->handle >> 24; - buf[i * 4 + 1] = results[i]->handle >> 16; - buf[i * 4 + 2] = results[i]->handle >> 8; - buf[i * 4 + 3] = results[i]->handle; - } - - //put everything in the right place - inst->result = buf; - inst->contDescr = sdpContVal; - inst->numMatches = numFound; - } - } - if(++sdpContVal == 0) sdpContVal = 0x01234567; //update continuation state to the next value - - //produce the packet to send - uint8_t bufPrepend[9], bufPostpend[5] = {0, }, preSz = 5, postSz = 1; - uint32_t sendSz = 0; - result = sg_alloc(); - if(!result) return btSdpError(trans, SDP_ERR_Insufficient_Resources); - - if(cmd == SDP_PDU_Service_Attribute_Request || cmd == SDP_PDU_Service_Search_Attribute_Request){ - - if(maxReplSz > 256) maxReplSz = 256; //no harm in fragmenting - keep the packets small - - sendSz = inst->resultSz; - if(sendSz > maxReplSz) sendSz = maxReplSz; - - bufPrepend[preSz++] = sendSz >> 8; - bufPrepend[preSz++] = sendSz & 0xFF; - } - else if(cmd == SDP_PDU_Service_Search_Request){ - - if(maxReplSz > 64) maxReplSz = 64; //no harm in fragmenting - keep the packets small - - sendSz = inst->resultSz; - if(sendSz > maxReplSz * sizeof(uint32_t)) sendSz = maxReplSz * sizeof(uint32_t); - - bufPrepend[preSz++] = inst->numMatches >> 8; - bufPrepend[preSz++] = inst->numMatches & 0xFF; - bufPrepend[preSz++] = (sendSz / sizeof(uint32_t)) >> 8; - bufPrepend[preSz++] = (sendSz / sizeof(uint32_t)) & 0xFF; - } - - if(!sg_add_back(result, inst->result, sendSz, SG_FLAG_MAKE_A_COPY)){ - - dbgPrintf("SDP: Failed to attach reply. Droping"); - free(inst->result); - inst->result = NULL; - sg_free(result); - free(result); - return btSdpError(trans, SDP_ERR_Insufficient_Resources); - } - else{ - - inst->resultSz -= sendSz; - if(inst->resultSz){ - - memcpy(inst->result, inst->result + sendSz, inst->resultSz); - inst->result = realloc(inst->result, inst->resultSz); - } - else{ - free(inst->result); - inst->result = NULL; - } - } - - if(inst->result){ //have more - - bufPostpend[0] = 4; - for(i = 0; i < 4; i++) bufPostpend[i + 1] = inst->contDescr >> ((3 - i) << 3); - postSz = 5; - } - - bufPrepend[0] = cmd + 1; //response to this request - bufPrepend[1] = trans[0]; - bufPrepend[2] = trans[1]; - bufPrepend[3] = (sendSz + preSz + postSz - 5) >> 8; - bufPrepend[4] = (sendSz + preSz + postSz - 5) & 0xFF; - - if(sg_add_front(result, bufPrepend, preSz, SG_FLAG_MAKE_A_COPY) && sg_add_back(result, bufPostpend, postSz, SG_FLAG_MAKE_A_COPY)){ - - return result; - } - sg_free(result); - free(result); - return btSdpError(trans, SDP_ERR_Insufficient_Resources); -} - -static void* sdpServiceAlloc(uint16_t conn, uint16_t chan, uint16_t remChan){ - - SdpInstance* inst = malloc(sizeof(SdpInstance)); - if(inst){ - - inst->result = NULL; - inst->aclConn = conn; - inst->remChan = remChan; - } - return inst; -} - -static void sdpServiceFree(void* service){ - - SdpInstance* inst = (SdpInstance*)service; - - if(inst->result) free(inst->result); - free(inst); -} - -static void sdpServiceDataRx(void* service, const uint8_t* data, uint16_t size){ - - SdpInstance* inst = (SdpInstance*)service; - uint16_t conn = inst->aclConn; - uint16_t remChan = inst->remChan; - - sg_buf* reply = btSdpProcessRequest(inst, data, size); - if(reply){ - -/*// -- ugly debugging code -- - unsigned i; - uint8_t buf[256]; - sg_copyto(reply, buf); - - dbgPrintf("SDP req got (0x%x): ", size); - for(i = 0; i < size; i++) dbgPrintf(" %02X", data[i]); - dbgPrintf("\n"); - - dbgPrintf("SDP reply sent (0x%x): ", sg_length(reply)); - for(i = 0; i < sg_length(reply); i++) dbgPrintf(" %02X", buf[i]); - dbgPrintf("\n"); -*/ - l2capServiceTx(conn, remChan, reply); - } -} - -void btSdpRegisterL2capService(){ - - const L2capService sdp = {L2CAP_FLAG_SUPPORT_CONNECTIONS, sdpServiceAlloc, sdpServiceFree, sdpServiceDataRx}; - if(!l2capServiceRegister(L2CAP_PSM_SDP, &sdp)) dbgPrintf("SDP L2CAP registration failed\n"); - - btSdpServiceDescriptorAdd(sdpDescrSdp, sizeof(sdpDescrSdp)); -} - -void btSdpServiceDescriptorAdd(const uint8_t* descriptor, uint16_t descrLen){ - - SdpService *t, *s = malloc(sizeof(SdpService)); - if(s){ - - s->handle = sdpNextHandle; - - if(sdpNextHandle) sdpNextHandle++; - else sdpNextHandle = SDP_FIRST_USER_HANDLE; //first add is special - it adds the SDP service itself - - s->descriptor = descriptor; - s->descrLen = descrLen; - s->next = NULL; - - t = knownServices; //add at end - while(t && t->next) t = t->next; - if(t) t->next = s; - else knownServices = s; - } -} - -void btSdpServiceDescriptorDel(const uint8_t* descriptor){ - - SdpService *s = knownServices, *p = NULL; - - while(s && s->descriptor != descriptor){ - - p = s; - s = s->next; - } - if(p) p->next = s->next; - else knownServices = s->next; - - free(s); -} - - |