Home | History | Annotate | Download | only in src
      1 /*
      2  *
      3  *  BlueZ - Bluetooth protocol stack for Linux
      4  *
      5  *  Copyright (C) 2001-2002  Nokia Corporation
      6  *  Copyright (C) 2002-2003  Maxim Krasnyansky <maxk (at) qualcomm.com>
      7  *  Copyright (C) 2002-2010  Marcel Holtmann <marcel (at) holtmann.org>
      8  *  Copyright (C) 2002-2003  Stephen Crane <steve.crane (at) rococosoft.com>
      9  *
     10  *
     11  *  This program is free software; you can redistribute it and/or modify
     12  *  it under the terms of the GNU General Public License as published by
     13  *  the Free Software Foundation; either version 2 of the License, or
     14  *  (at your option) any later version.
     15  *
     16  *  This program is distributed in the hope that it will be useful,
     17  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
     18  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     19  *  GNU General Public License for more details.
     20  *
     21  *  You should have received a copy of the GNU General Public License
     22  *  along with this program; if not, write to the Free Software
     23  *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
     24  *
     25  */
     26 
     27 #ifdef HAVE_CONFIG_H
     28 #include <config.h>
     29 #endif
     30 
     31 #include <stdio.h>
     32 #include <errno.h>
     33 #include <stdlib.h>
     34 #include <string.h>
     35 #include <limits.h>
     36 #include <sys/socket.h>
     37 
     38 #include <bluetooth/bluetooth.h>
     39 #include <bluetooth/l2cap.h>
     40 #include <bluetooth/sdp.h>
     41 #include <bluetooth/sdp_lib.h>
     42 
     43 #include <netinet/in.h>
     44 
     45 #include "sdpd.h"
     46 #include "log.h"
     47 
     48 typedef struct {
     49 	uint32_t timestamp;
     50 	union {
     51 		uint16_t maxBytesSent;
     52 		uint16_t lastIndexSent;
     53 	} cStateValue;
     54 } sdp_cont_state_t;
     55 
     56 #define SDP_CONT_STATE_SIZE (sizeof(uint8_t) + sizeof(sdp_cont_state_t))
     57 
     58 #define MIN(x, y) ((x) < (y)) ? (x): (y)
     59 
     60 typedef struct _sdp_cstate_list sdp_cstate_list_t;
     61 
     62 struct _sdp_cstate_list {
     63 	sdp_cstate_list_t *next;
     64 	uint32_t timestamp;
     65 	sdp_buf_t buf;
     66 };
     67 
     68 static sdp_cstate_list_t *cstates;
     69 
     70 /* FIXME: should probably remove it when it's found */
     71 static sdp_buf_t *sdp_get_cached_rsp(sdp_cont_state_t *cstate)
     72 {
     73 	sdp_cstate_list_t *p;
     74 
     75 	for (p = cstates; p; p = p->next)
     76 		if (p->timestamp == cstate->timestamp)
     77 			return &p->buf;
     78 	return 0;
     79 }
     80 
     81 static uint32_t sdp_cstate_alloc_buf(sdp_buf_t *buf)
     82 {
     83 	sdp_cstate_list_t *cstate = malloc(sizeof(sdp_cstate_list_t));
     84 	uint8_t *data = malloc(buf->data_size);
     85 
     86 	memcpy(data, buf->data, buf->data_size);
     87 	memset((char *)cstate, 0, sizeof(sdp_cstate_list_t));
     88 	cstate->buf.data = data;
     89 	cstate->buf.data_size = buf->data_size;
     90 	cstate->buf.buf_size = buf->data_size;
     91 	cstate->timestamp = sdp_get_time();
     92 	cstate->next = cstates;
     93 	cstates = cstate;
     94 	return cstate->timestamp;
     95 }
     96 
     97 /* Additional values for checking datatype (not in spec) */
     98 #define SDP_TYPE_UUID	0xfe
     99 #define SDP_TYPE_ATTRID	0xff
    100 
    101 struct attrid {
    102 	uint8_t dtd;
    103 	union {
    104 		uint16_t uint16;
    105 		uint32_t uint32;
    106 	};
    107 };
    108 
    109 /*
    110  * Generic data element sequence extractor. Builds
    111  * a list whose elements are those found in the
    112  * sequence. The data type of elements found in the
    113  * sequence is returned in the reference pDataType
    114  */
    115 static int extract_des(uint8_t *buf, int len, sdp_list_t **svcReqSeq, uint8_t *pDataType, uint8_t expectedType)
    116 {
    117 	uint8_t seqType;
    118 	int scanned, data_size = 0;
    119 	short numberOfElements = 0;
    120 	int seqlen = 0;
    121 	sdp_list_t *pSeq = NULL;
    122 	uint8_t dataType;
    123 	int status = 0;
    124 	const uint8_t *p;
    125 	size_t bufsize;
    126 
    127 	scanned = sdp_extract_seqtype(buf, len, &seqType, &data_size);
    128 
    129 	SDPDBG("Seq type : %d", seqType);
    130 	if (!scanned || (seqType != SDP_SEQ8 && seqType != SDP_SEQ16)) {
    131 		error("Unknown seq type");
    132 		return -1;
    133 	}
    134 	p = buf + scanned;
    135 	bufsize = len - scanned;
    136 
    137 	SDPDBG("Data size : %d", data_size);
    138 
    139 	for (;;) {
    140 		char *pElem = NULL;
    141 		int localSeqLength = 0;
    142 
    143 		if (bufsize < sizeof(uint8_t)) {
    144 			SDPDBG("->Unexpected end of buffer");
    145 			goto failed;
    146 		}
    147 
    148 		dataType = *p;
    149 
    150 		SDPDBG("Data type: 0x%02x", dataType);
    151 
    152 		if (expectedType == SDP_TYPE_UUID) {
    153 			if (dataType != SDP_UUID16 && dataType != SDP_UUID32 && dataType != SDP_UUID128) {
    154 				SDPDBG("->Unexpected Data type (expected UUID_ANY)");
    155 				goto failed;
    156 			}
    157 		} else if (expectedType == SDP_TYPE_ATTRID &&
    158 				(dataType != SDP_UINT16 && dataType != SDP_UINT32)) {
    159 			SDPDBG("->Unexpected Data type (expected 0x%02x or 0x%02x)",
    160 								SDP_UINT16, SDP_UINT32);
    161 			goto failed;
    162 		} else if (expectedType != SDP_TYPE_ATTRID && dataType != expectedType) {
    163 			SDPDBG("->Unexpected Data type (expected 0x%02x)", expectedType);
    164 			goto failed;
    165 		}
    166 
    167 		switch (dataType) {
    168 		case SDP_UINT16:
    169 			p += sizeof(uint8_t);
    170 			seqlen += sizeof(uint8_t);
    171 			bufsize -= sizeof(uint8_t);
    172 			if (bufsize < sizeof(uint16_t)) {
    173 				SDPDBG("->Unexpected end of buffer");
    174 				goto failed;
    175 			}
    176 
    177 			if (expectedType == SDP_TYPE_ATTRID) {
    178 				struct attrid *aid;
    179 				aid = malloc(sizeof(struct attrid));
    180 				aid->dtd = dataType;
    181 				bt_put_unaligned(ntohs(bt_get_unaligned((uint16_t *)p)), (uint16_t *)&aid->uint16);
    182 				pElem = (char *) aid;
    183 			} else {
    184 				pElem = malloc(sizeof(uint16_t));
    185 				bt_put_unaligned(ntohs(bt_get_unaligned((uint16_t *)p)), (uint16_t *)pElem);
    186 			}
    187 			p += sizeof(uint16_t);
    188 			seqlen += sizeof(uint16_t);
    189 			bufsize -= sizeof(uint16_t);
    190 			break;
    191 		case SDP_UINT32:
    192 			p += sizeof(uint8_t);
    193 			seqlen += sizeof(uint8_t);
    194 			bufsize -= sizeof(uint8_t);
    195 			if (bufsize < (int)sizeof(uint32_t)) {
    196 				SDPDBG("->Unexpected end of buffer");
    197 				goto failed;
    198 			}
    199 
    200 			if (expectedType == SDP_TYPE_ATTRID) {
    201 				struct attrid *aid;
    202 				aid = malloc(sizeof(struct attrid));
    203 				aid->dtd = dataType;
    204 				bt_put_unaligned(ntohl(bt_get_unaligned((uint32_t *)p)), (uint32_t *)&aid->uint32);
    205 				pElem = (char *) aid;
    206 			} else {
    207 				pElem = malloc(sizeof(uint32_t));
    208 				bt_put_unaligned(ntohl(bt_get_unaligned((uint32_t *)p)), (uint32_t *)pElem);
    209 			}
    210 			p += sizeof(uint32_t);
    211 			seqlen += sizeof(uint32_t);
    212 			bufsize -= sizeof(uint32_t);
    213 			break;
    214 		case SDP_UUID16:
    215 		case SDP_UUID32:
    216 		case SDP_UUID128:
    217 			pElem = malloc(sizeof(uuid_t));
    218 			status = sdp_uuid_extract(p, bufsize, (uuid_t *) pElem, &localSeqLength);
    219 			if (status < 0) {
    220 				free(pElem);
    221 				goto failed;
    222 			}
    223 			seqlen += localSeqLength;
    224 			p += localSeqLength;
    225 			bufsize -= localSeqLength;
    226 			break;
    227 		default:
    228 			return -1;
    229 		}
    230 		if (status == 0) {
    231 			pSeq = sdp_list_append(pSeq, pElem);
    232 			numberOfElements++;
    233 			SDPDBG("No of elements : %d", numberOfElements);
    234 
    235 			if (seqlen == data_size)
    236 				break;
    237 			else if (seqlen > data_size || seqlen > len)
    238 				goto failed;
    239 		} else
    240 			free(pElem);
    241 	}
    242 	*svcReqSeq = pSeq;
    243 	scanned += seqlen;
    244 	*pDataType = dataType;
    245 	return scanned;
    246 
    247 failed:
    248 	sdp_list_free(pSeq, free);
    249 	return -1;
    250 }
    251 
    252 static int sdp_set_cstate_pdu(sdp_buf_t *buf, sdp_cont_state_t *cstate)
    253 {
    254 	uint8_t *pdata = buf->data + buf->data_size;
    255 	int length = 0;
    256 
    257 	if (cstate) {
    258 		SDPDBG("Non null sdp_cstate_t id : 0x%x", cstate->timestamp);
    259 		*pdata = sizeof(sdp_cont_state_t);
    260 		pdata += sizeof(uint8_t);
    261 		length += sizeof(uint8_t);
    262 		memcpy(pdata, cstate, sizeof(sdp_cont_state_t));
    263 		length += sizeof(sdp_cont_state_t);
    264 	} else {
    265 		/* set "null" continuation state */
    266 		*pdata = 0;
    267 		length += sizeof(uint8_t);
    268 	}
    269 	buf->data_size += length;
    270 	return length;
    271 }
    272 
    273 static int sdp_cstate_get(uint8_t *buffer, size_t len,
    274 						sdp_cont_state_t **cstate)
    275 {
    276 	uint8_t cStateSize = *buffer;
    277 
    278 	SDPDBG("Continuation State size : %d", cStateSize);
    279 
    280 	if (cStateSize == 0) {
    281 		*cstate = NULL;
    282 		return 0;
    283 	}
    284 
    285 	buffer++;
    286 	len--;
    287 
    288 	if (len < sizeof(sdp_cont_state_t))
    289 		return -EINVAL;
    290 
    291 	/*
    292 	 * Check if continuation state exists, if yes attempt
    293 	 * to get response remainder from cache, else send error
    294 	 */
    295 
    296 	*cstate = malloc(sizeof(sdp_cont_state_t));
    297 	if (!(*cstate))
    298 		return -ENOMEM;
    299 
    300 	memcpy(*cstate, buffer, sizeof(sdp_cont_state_t));
    301 
    302 	SDPDBG("Cstate TS : 0x%x", (*cstate)->timestamp);
    303 	SDPDBG("Bytes sent : %d", (*cstate)->cStateValue.maxBytesSent);
    304 
    305 	return 0;
    306 }
    307 
    308 /*
    309  * The matching process is defined as "each and every UUID
    310  * specified in the "search pattern" must be present in the
    311  * "target pattern". Here "search pattern" is the set of UUIDs
    312  * specified by the service discovery client and "target pattern"
    313  * is the set of UUIDs present in a service record.
    314  *
    315  * Return 1 if each and every UUID in the search
    316  * pattern exists in the target pattern, 0 if the
    317  * match succeeds and -1 on error.
    318  */
    319 static int sdp_match_uuid(sdp_list_t *search, sdp_list_t *pattern)
    320 {
    321 	/*
    322 	 * The target is a sorted list, so we need not look
    323 	 * at all elements to confirm existence of an element
    324 	 * from the search pattern
    325 	 */
    326 	int patlen = sdp_list_len(pattern);
    327 
    328 	if (patlen < sdp_list_len(search))
    329 		return -1;
    330 	for (; search; search = search->next) {
    331 		uuid_t *uuid128;
    332 		void *data = search->data;
    333 		sdp_list_t *list;
    334 		if (data == NULL)
    335 			return -1;
    336 
    337 		/* create 128-bit form of the search UUID */
    338 		uuid128 = sdp_uuid_to_uuid128((uuid_t *)data);
    339 		list = sdp_list_find(pattern, uuid128, sdp_uuid128_cmp);
    340 		bt_free(uuid128);
    341 		if (!list)
    342 			return 0;
    343 	}
    344 	return 1;
    345 }
    346 
    347 /*
    348  * Service search request PDU. This method extracts the search pattern
    349  * (a sequence of UUIDs) and calls the matching function
    350  * to find matching services
    351  */
    352 static int service_search_req(sdp_req_t *req, sdp_buf_t *buf)
    353 {
    354 	int status = 0, i, plen, mlen, mtu, scanned;
    355 	sdp_list_t *pattern = NULL;
    356 	uint16_t expected, actual, rsp_count = 0;
    357 	uint8_t dtd;
    358 	sdp_cont_state_t *cstate = NULL;
    359 	uint8_t *pCacheBuffer = NULL;
    360 	int handleSize = 0;
    361 	uint32_t cStateId = 0;
    362 	short *pTotalRecordCount, *pCurrentRecordCount;
    363 	uint8_t *pdata = req->buf + sizeof(sdp_pdu_hdr_t);
    364 	size_t data_left = req->len - sizeof(sdp_pdu_hdr_t);
    365 
    366 	scanned = extract_des(pdata, data_left, &pattern, &dtd, SDP_TYPE_UUID);
    367 
    368 	if (scanned == -1) {
    369 		status = SDP_INVALID_SYNTAX;
    370 		goto done;
    371 	}
    372 	pdata += scanned;
    373 	data_left -= scanned;
    374 
    375 	plen = ntohs(((sdp_pdu_hdr_t *)(req->buf))->plen);
    376 	mlen = scanned + sizeof(uint16_t) + 1;
    377 	/* ensure we don't read past buffer */
    378 	if (plen < mlen || plen != mlen + *(uint8_t *)(pdata+sizeof(uint16_t))) {
    379 		status = SDP_INVALID_SYNTAX;
    380 		goto done;
    381 	}
    382 
    383 	if (data_left < sizeof(uint16_t)) {
    384 		status = SDP_INVALID_SYNTAX;
    385 		goto done;
    386 	}
    387 
    388 	expected = ntohs(bt_get_unaligned((uint16_t *)pdata));
    389 
    390 	SDPDBG("Expected count: %d", expected);
    391 	SDPDBG("Bytes scanned : %d", scanned);
    392 
    393 	pdata += sizeof(uint16_t);
    394 	data_left -= sizeof(uint16_t);
    395 
    396 	/*
    397 	 * Check if continuation state exists, if yes attempt
    398 	 * to get rsp remainder from cache, else send error
    399 	 */
    400 	if (sdp_cstate_get(pdata, data_left, &cstate) < 0) {
    401 		status = SDP_INVALID_SYNTAX;
    402 		goto done;
    403 	}
    404 
    405 	mtu = req->mtu - sizeof(sdp_pdu_hdr_t) - sizeof(uint16_t) - sizeof(uint16_t) - SDP_CONT_STATE_SIZE;
    406 	actual = MIN(expected, mtu >> 2);
    407 
    408 	/* make space in the rsp buffer for total and current record counts */
    409 	pdata = buf->data;
    410 
    411 	/* total service record count = 0 */
    412 	pTotalRecordCount = (short *)pdata;
    413 	bt_put_unaligned(0, (uint16_t *)pdata);
    414 	pdata += sizeof(uint16_t);
    415 	buf->data_size += sizeof(uint16_t);
    416 
    417 	/* current service record count = 0 */
    418 	pCurrentRecordCount = (short *)pdata;
    419 	bt_put_unaligned(0, (uint16_t *)pdata);
    420 	pdata += sizeof(uint16_t);
    421 	buf->data_size += sizeof(uint16_t);
    422 
    423 	if (cstate == NULL) {
    424 		/* for every record in the DB, do a pattern search */
    425 		sdp_list_t *list = sdp_get_record_list();
    426 
    427 		handleSize = 0;
    428 		for (; list && rsp_count < expected; list = list->next) {
    429 			sdp_record_t *rec = list->data;
    430 
    431 			SDPDBG("Checking svcRec : 0x%x", rec->handle);
    432 
    433 			if (sdp_match_uuid(pattern, rec->pattern) > 0 &&
    434 					sdp_check_access(rec->handle, &req->device)) {
    435 				rsp_count++;
    436 				bt_put_unaligned(htonl(rec->handle), (uint32_t *)pdata);
    437 				pdata += sizeof(uint32_t);
    438 				handleSize += sizeof(uint32_t);
    439 			}
    440 		}
    441 
    442 		SDPDBG("Match count: %d", rsp_count);
    443 
    444 		buf->data_size += handleSize;
    445 		bt_put_unaligned(htons(rsp_count), (uint16_t *)pTotalRecordCount);
    446 		bt_put_unaligned(htons(rsp_count), (uint16_t *)pCurrentRecordCount);
    447 
    448 		if (rsp_count > actual) {
    449 			/* cache the rsp and generate a continuation state */
    450 			cStateId = sdp_cstate_alloc_buf(buf);
    451 			/*
    452 			 * subtract handleSize since we now send only
    453 			 * a subset of handles
    454 			 */
    455 			buf->data_size -= handleSize;
    456 		} else {
    457 			/* NULL continuation state */
    458 			sdp_set_cstate_pdu(buf, NULL);
    459 		}
    460 	}
    461 
    462 	/* under both the conditions below, the rsp buffer is not built yet */
    463 	if (cstate || cStateId > 0) {
    464 		short lastIndex = 0;
    465 
    466 		if (cstate) {
    467 			/*
    468 			 * Get the previous sdp_cont_state_t and obtain
    469 			 * the cached rsp
    470 			 */
    471 			sdp_buf_t *pCache = sdp_get_cached_rsp(cstate);
    472 			if (pCache) {
    473 				pCacheBuffer = pCache->data;
    474 				/* get the rsp_count from the cached buffer */
    475 				rsp_count = ntohs(bt_get_unaligned((uint16_t *)pCacheBuffer));
    476 
    477 				/* get index of the last sdp_record_t sent */
    478 				lastIndex = cstate->cStateValue.lastIndexSent;
    479 			} else {
    480 				status = SDP_INVALID_CSTATE;
    481 				goto done;
    482 			}
    483 		} else {
    484 			pCacheBuffer = buf->data;
    485 			lastIndex = 0;
    486 		}
    487 
    488 		/*
    489 		 * Set the local buffer pointer to after the
    490 		 * current record count and increment the cached
    491 		 * buffer pointer to beyond the counters
    492 		 */
    493 		pdata = (uint8_t *) pCurrentRecordCount + sizeof(uint16_t);
    494 
    495 		/* increment beyond the totalCount and the currentCount */
    496 		pCacheBuffer += 2 * sizeof(uint16_t);
    497 
    498 		if (cstate) {
    499 			handleSize = 0;
    500 			for (i = lastIndex; (i - lastIndex) < actual && i < rsp_count; i++) {
    501 				bt_put_unaligned(bt_get_unaligned((uint32_t *)(pCacheBuffer + i * sizeof(uint32_t))), (uint32_t *)pdata);
    502 				pdata += sizeof(uint32_t);
    503 				handleSize += sizeof(uint32_t);
    504 			}
    505 		} else {
    506 			handleSize = actual << 2;
    507 			i = actual;
    508 		}
    509 
    510 		buf->data_size += handleSize;
    511 		bt_put_unaligned(htons(rsp_count), (uint16_t *)pTotalRecordCount);
    512 		bt_put_unaligned(htons(i - lastIndex), (uint16_t *)pCurrentRecordCount);
    513 
    514 		if (i == rsp_count) {
    515 			/* set "null" continuationState */
    516 			sdp_set_cstate_pdu(buf, NULL);
    517 		} else {
    518 			/*
    519 			 * there's more: set lastIndexSent to
    520 			 * the new value and move on
    521 			 */
    522 			sdp_cont_state_t newState;
    523 
    524 			SDPDBG("Setting non-NULL sdp_cstate_t");
    525 
    526 			if (cstate)
    527 				memcpy(&newState, cstate, sizeof(sdp_cont_state_t));
    528 			else {
    529 				memset(&newState, 0, sizeof(sdp_cont_state_t));
    530 				newState.timestamp = cStateId;
    531 			}
    532 			newState.cStateValue.lastIndexSent = i;
    533 			sdp_set_cstate_pdu(buf, &newState);
    534 		}
    535 	}
    536 
    537 done:
    538 	free(cstate);
    539 	if (pattern)
    540 		sdp_list_free(pattern, free);
    541 
    542 	return status;
    543 }
    544 
    545 /*
    546  * Extract attribute identifiers from the request PDU.
    547  * Clients could request a subset of attributes (by id)
    548  * from a service record, instead of the whole set. The
    549  * requested identifiers are present in the PDU form of
    550  * the request
    551  */
    552 static int extract_attrs(sdp_record_t *rec, sdp_list_t *seq, sdp_buf_t *buf)
    553 {
    554 	sdp_buf_t pdu;
    555 
    556 	if (!rec)
    557 		return SDP_INVALID_RECORD_HANDLE;
    558 
    559 	if (seq == NULL) {
    560 		SDPDBG("Attribute sequence is NULL");
    561 		return 0;
    562 	}
    563 
    564 	SDPDBG("Entries in attr seq : %d", sdp_list_len(seq));
    565 
    566 	sdp_gen_record_pdu(rec, &pdu);
    567 
    568 	for (; seq; seq = seq->next) {
    569 		struct attrid *aid = seq->data;
    570 
    571 		SDPDBG("AttrDataType : %d", aid->dtd);
    572 
    573 		if (aid->dtd == SDP_UINT16) {
    574 			uint16_t attr = bt_get_unaligned((uint16_t *)&aid->uint16);
    575 			sdp_data_t *a = sdp_data_get(rec, attr);
    576 			if (a)
    577 				sdp_append_to_pdu(buf, a);
    578 		} else if (aid->dtd == SDP_UINT32) {
    579 			uint32_t range = bt_get_unaligned((uint32_t *)&aid->uint32);
    580 			uint16_t attr;
    581 			uint16_t low = (0xffff0000 & range) >> 16;
    582 			uint16_t high = 0x0000ffff & range;
    583 			sdp_data_t *data;
    584 
    585 			SDPDBG("attr range : 0x%x", range);
    586 			SDPDBG("Low id : 0x%x", low);
    587 			SDPDBG("High id : 0x%x", high);
    588 
    589 			if (low == 0x0000 && high == 0xffff && pdu.data_size <= buf->buf_size) {
    590 				/* copy it */
    591 				memcpy(buf->data, pdu.data, pdu.data_size);
    592 				buf->data_size = pdu.data_size;
    593 				break;
    594 			}
    595 			/* (else) sub-range of attributes */
    596 			for (attr = low; attr < high; attr++) {
    597 				data = sdp_data_get(rec, attr);
    598 				if (data)
    599 					sdp_append_to_pdu(buf, data);
    600 			}
    601 			data = sdp_data_get(rec, high);
    602 			if (data)
    603 				sdp_append_to_pdu(buf, data);
    604 		} else {
    605 			error("Unexpected data type : 0x%x", aid->dtd);
    606 			error("Expect uint16_t or uint32_t");
    607 			free(pdu.data);
    608 			return SDP_INVALID_SYNTAX;
    609 		}
    610 	}
    611 
    612 	free(pdu.data);
    613 
    614 	return 0;
    615 }
    616 
    617 /*
    618  * A request for the attributes of a service record.
    619  * First check if the service record (specified by
    620  * service record handle) exists, then call the attribute
    621  * streaming function
    622  */
    623 static int service_attr_req(sdp_req_t *req, sdp_buf_t *buf)
    624 {
    625 	sdp_cont_state_t *cstate = NULL;
    626 	uint8_t *pResponse = NULL;
    627 	short cstate_size = 0;
    628 	sdp_list_t *seq = NULL;
    629 	uint8_t dtd = 0;
    630 	int scanned = 0;
    631 	unsigned int max_rsp_size;
    632 	int status = 0, plen, mlen;
    633 	uint8_t *pdata = req->buf + sizeof(sdp_pdu_hdr_t);
    634 	size_t data_left = req->len - sizeof(sdp_pdu_hdr_t);
    635 	uint32_t handle;
    636 
    637 	if (data_left < sizeof(uint32_t)) {
    638 		status = SDP_INVALID_SYNTAX;
    639 		goto done;
    640 	}
    641 
    642 	handle = ntohl(bt_get_unaligned((uint32_t *)pdata));
    643 
    644 	pdata += sizeof(uint32_t);
    645 	data_left -= sizeof(uint32_t);
    646 
    647 	if (data_left < sizeof(uint16_t)) {
    648 		status = SDP_INVALID_SYNTAX;
    649 		goto done;
    650 	}
    651 
    652 	max_rsp_size = ntohs(bt_get_unaligned((uint16_t *)pdata));
    653 
    654 	pdata += sizeof(uint16_t);
    655 	data_left -= sizeof(uint16_t);
    656 
    657 	if (data_left < sizeof(sdp_pdu_hdr_t)) {
    658 		status = SDP_INVALID_SYNTAX;
    659 		goto done;
    660 	}
    661 
    662 	/* extract the attribute list */
    663 	scanned = extract_des(pdata, data_left, &seq, &dtd, SDP_TYPE_ATTRID);
    664 	if (scanned == -1) {
    665 		status = SDP_INVALID_SYNTAX;
    666 		goto done;
    667 	}
    668 	pdata += scanned;
    669 	data_left -= scanned;
    670 
    671 	plen = ntohs(((sdp_pdu_hdr_t *)(req->buf))->plen);
    672 	mlen = scanned + sizeof(uint32_t) + sizeof(uint16_t) + 1;
    673 	/* ensure we don't read past buffer */
    674 	if (plen < mlen || plen != mlen + *(uint8_t *)pdata) {
    675 		status = SDP_INVALID_PDU_SIZE;
    676 		goto done;
    677 	}
    678 
    679 	/*
    680 	 * if continuation state exists, attempt
    681 	 * to get rsp remainder from cache, else send error
    682 	 */
    683 	if (sdp_cstate_get(pdata, data_left, &cstate) < 0) {
    684 		status = SDP_INVALID_SYNTAX;
    685 		goto done;
    686 	}
    687 
    688 	SDPDBG("SvcRecHandle : 0x%x", handle);
    689 	SDPDBG("max_rsp_size : %d", max_rsp_size);
    690 
    691 	/*
    692 	 * Check that max_rsp_size is within valid range
    693 	 * a minimum size of 0x0007 has to be used for data field
    694 	 */
    695 	if (max_rsp_size < 0x0007) {
    696 		status = SDP_INVALID_SYNTAX;
    697 		goto done;
    698 	}
    699 
    700 	/*
    701 	 * Calculate Attribute size acording to MTU
    702 	 * We can send only (MTU - sizeof(sdp_pdu_hdr_t) - sizeof(sdp_cont_state_t))
    703 	 */
    704 	max_rsp_size = MIN(max_rsp_size, req->mtu - sizeof(sdp_pdu_hdr_t) -
    705 			sizeof(uint32_t) - SDP_CONT_STATE_SIZE - sizeof(uint16_t));
    706 
    707 	/* pull header for AttributeList byte count */
    708 	buf->data += sizeof(uint16_t);
    709 	buf->buf_size -= sizeof(uint16_t);
    710 
    711 	if (cstate) {
    712 		sdp_buf_t *pCache = sdp_get_cached_rsp(cstate);
    713 
    714 		SDPDBG("Obtained cached rsp : %p", pCache);
    715 
    716 		if (pCache) {
    717 			short sent = MIN(max_rsp_size, pCache->data_size - cstate->cStateValue.maxBytesSent);
    718 			pResponse = pCache->data;
    719 			memcpy(buf->data, pResponse + cstate->cStateValue.maxBytesSent, sent);
    720 			buf->data_size += sent;
    721 			cstate->cStateValue.maxBytesSent += sent;
    722 
    723 			SDPDBG("Response size : %d sending now : %d bytes sent so far : %d",
    724 				pCache->data_size, sent, cstate->cStateValue.maxBytesSent);
    725 			if (cstate->cStateValue.maxBytesSent == pCache->data_size)
    726 				cstate_size = sdp_set_cstate_pdu(buf, NULL);
    727 			else
    728 				cstate_size = sdp_set_cstate_pdu(buf, cstate);
    729 		} else {
    730 			status = SDP_INVALID_CSTATE;
    731 			error("NULL cache buffer and non-NULL continuation state");
    732 		}
    733 	} else {
    734 		sdp_record_t *rec = sdp_record_find(handle);
    735 		status = extract_attrs(rec, seq, buf);
    736 		if (buf->data_size > max_rsp_size) {
    737 			sdp_cont_state_t newState;
    738 
    739 			memset((char *)&newState, 0, sizeof(sdp_cont_state_t));
    740 			newState.timestamp = sdp_cstate_alloc_buf(buf);
    741 			/*
    742 			 * Reset the buffer size to the maximum expected and
    743 			 * set the sdp_cont_state_t
    744 			 */
    745 			SDPDBG("Creating continuation state of size : %d", buf->data_size);
    746 			buf->data_size = max_rsp_size;
    747 			newState.cStateValue.maxBytesSent = max_rsp_size;
    748 			cstate_size = sdp_set_cstate_pdu(buf, &newState);
    749 		} else {
    750 			if (buf->data_size == 0)
    751 				sdp_append_to_buf(buf, 0, 0);
    752 			cstate_size = sdp_set_cstate_pdu(buf, NULL);
    753 		}
    754 	}
    755 
    756 	/* push header */
    757 	buf->data -= sizeof(uint16_t);
    758 	buf->buf_size += sizeof(uint16_t);
    759 
    760 done:
    761 	free(cstate);
    762 	if (seq)
    763 		sdp_list_free(seq, free);
    764 	if (status)
    765 		return status;
    766 
    767 	/* set attribute list byte count */
    768 	bt_put_unaligned(htons(buf->data_size - cstate_size), (uint16_t *)buf->data);
    769 	buf->data_size += sizeof(uint16_t);
    770 	return 0;
    771 }
    772 
    773 /*
    774  * combined service search and attribute extraction
    775  */
    776 static int service_search_attr_req(sdp_req_t *req, sdp_buf_t *buf)
    777 {
    778 	int status = 0, plen, totscanned;
    779 	uint8_t *pdata, *pResponse = NULL;
    780 	unsigned int max;
    781 	int scanned, rsp_count = 0;
    782 	sdp_list_t *pattern = NULL, *seq = NULL, *svcList;
    783 	sdp_cont_state_t *cstate = NULL;
    784 	short cstate_size = 0;
    785 	uint8_t dtd = 0;
    786 	sdp_buf_t tmpbuf;
    787 	size_t data_left;
    788 
    789 	tmpbuf.data = NULL;
    790 	pdata = req->buf + sizeof(sdp_pdu_hdr_t);
    791 	data_left = req->len - sizeof(sdp_pdu_hdr_t);
    792 	scanned = extract_des(pdata, data_left, &pattern, &dtd, SDP_TYPE_UUID);
    793 	if (scanned == -1) {
    794 		status = SDP_INVALID_SYNTAX;
    795 		goto done;
    796 	}
    797 	totscanned = scanned;
    798 
    799 	SDPDBG("Bytes scanned: %d", scanned);
    800 
    801 	pdata += scanned;
    802 	data_left -= scanned;
    803 
    804 	if (data_left < sizeof(uint16_t)) {
    805 		status = SDP_INVALID_SYNTAX;
    806 		goto done;
    807 	}
    808 
    809 	max = ntohs(bt_get_unaligned((uint16_t *)pdata));
    810 
    811 	pdata += sizeof(uint16_t);
    812 	data_left -= sizeof(uint16_t);
    813 
    814 	SDPDBG("Max Attr expected: %d", max);
    815 
    816 	if (data_left < sizeof(sdp_pdu_hdr_t)) {
    817 		status = SDP_INVALID_SYNTAX;
    818 		goto done;
    819 	}
    820 
    821 	/* extract the attribute list */
    822 	scanned = extract_des(pdata, data_left, &seq, &dtd, SDP_TYPE_ATTRID);
    823 	if (scanned == -1) {
    824 		status = SDP_INVALID_SYNTAX;
    825 		goto done;
    826 	}
    827 
    828 	pdata += scanned;
    829 	data_left -= scanned;
    830 
    831 	totscanned += scanned + sizeof(uint16_t) + 1;
    832 
    833 	plen = ntohs(((sdp_pdu_hdr_t *)(req->buf))->plen);
    834 	if (plen < totscanned || plen != totscanned + *(uint8_t *)pdata) {
    835 		status = SDP_INVALID_PDU_SIZE;
    836 		goto done;
    837 	}
    838 
    839 	/*
    840 	 * if continuation state exists attempt
    841 	 * to get rsp remainder from cache, else send error
    842 	 */
    843 	if (sdp_cstate_get(pdata, data_left, &cstate) < 0) {
    844 		status = SDP_INVALID_SYNTAX;
    845 		goto done;
    846 	}
    847 
    848 	svcList = sdp_get_record_list();
    849 
    850 	tmpbuf.data = malloc(USHRT_MAX);
    851 	tmpbuf.data_size = 0;
    852 	tmpbuf.buf_size = USHRT_MAX;
    853 	memset(tmpbuf.data, 0, USHRT_MAX);
    854 
    855 	/*
    856 	 * Calculate Attribute size acording to MTU
    857 	 * We can send only (MTU - sizeof(sdp_pdu_hdr_t) - sizeof(sdp_cont_state_t))
    858 	 */
    859 	max = MIN(max, req->mtu - sizeof(sdp_pdu_hdr_t) - SDP_CONT_STATE_SIZE - sizeof(uint16_t));
    860 
    861 	/* pull header for AttributeList byte count */
    862 	buf->data += sizeof(uint16_t);
    863 	buf->buf_size -= sizeof(uint16_t);
    864 
    865 	if (cstate == NULL) {
    866 		/* no continuation state -> create new response */
    867 		sdp_list_t *p;
    868 		for (p = svcList; p; p = p->next) {
    869 			sdp_record_t *rec = p->data;
    870 			if (sdp_match_uuid(pattern, rec->pattern) > 0 &&
    871 					sdp_check_access(rec->handle, &req->device)) {
    872 				rsp_count++;
    873 				status = extract_attrs(rec, seq, &tmpbuf);
    874 
    875 				SDPDBG("Response count : %d", rsp_count);
    876 				SDPDBG("Local PDU size : %d", tmpbuf.data_size);
    877 				if (status) {
    878 					SDPDBG("Extract attr from record returns err");
    879 					break;
    880 				}
    881 				if (buf->data_size + tmpbuf.data_size < buf->buf_size) {
    882 					/* to be sure no relocations */
    883 					sdp_append_to_buf(buf, tmpbuf.data, tmpbuf.data_size);
    884 					tmpbuf.data_size = 0;
    885 					memset(tmpbuf.data, 0, USHRT_MAX);
    886 				} else {
    887 					error("Relocation needed");
    888 					break;
    889 				}
    890 				SDPDBG("Net PDU size : %d", buf->data_size);
    891 			}
    892 		}
    893 		if (buf->data_size > max) {
    894 			sdp_cont_state_t newState;
    895 
    896 			memset((char *)&newState, 0, sizeof(sdp_cont_state_t));
    897 			newState.timestamp = sdp_cstate_alloc_buf(buf);
    898 			/*
    899 			 * Reset the buffer size to the maximum expected and
    900 			 * set the sdp_cont_state_t
    901 			 */
    902 			buf->data_size = max;
    903 			newState.cStateValue.maxBytesSent = max;
    904 			cstate_size = sdp_set_cstate_pdu(buf, &newState);
    905 		} else
    906 			cstate_size = sdp_set_cstate_pdu(buf, NULL);
    907 	} else {
    908 		/* continuation State exists -> get from cache */
    909 		sdp_buf_t *pCache = sdp_get_cached_rsp(cstate);
    910 		if (pCache) {
    911 			uint16_t sent = MIN(max, pCache->data_size - cstate->cStateValue.maxBytesSent);
    912 			pResponse = pCache->data;
    913 			memcpy(buf->data, pResponse + cstate->cStateValue.maxBytesSent, sent);
    914 			buf->data_size += sent;
    915 			cstate->cStateValue.maxBytesSent += sent;
    916 			if (cstate->cStateValue.maxBytesSent == pCache->data_size)
    917 				cstate_size = sdp_set_cstate_pdu(buf, NULL);
    918 			else
    919 				cstate_size = sdp_set_cstate_pdu(buf, cstate);
    920 		} else {
    921 			status = SDP_INVALID_CSTATE;
    922 			SDPDBG("Non-null continuation state, but null cache buffer");
    923 		}
    924 	}
    925 
    926 	if (!rsp_count && !cstate) {
    927 		/* found nothing */
    928 		buf->data_size = 0;
    929 		sdp_append_to_buf(buf, tmpbuf.data, tmpbuf.data_size);
    930 		sdp_set_cstate_pdu(buf, NULL);
    931 	}
    932 
    933 	/* push header */
    934 	buf->data -= sizeof(uint16_t);
    935 	buf->buf_size += sizeof(uint16_t);
    936 
    937 	if (!status) {
    938 		/* set attribute list byte count */
    939 		bt_put_unaligned(htons(buf->data_size - cstate_size), (uint16_t *)buf->data);
    940 		buf->data_size += sizeof(uint16_t);
    941 	}
    942 
    943 done:
    944 	free(cstate);
    945 	free(tmpbuf.data);
    946 	if (pattern)
    947 		sdp_list_free(pattern, free);
    948 	if (seq)
    949 		sdp_list_free(seq, free);
    950 	return status;
    951 }
    952 
    953 /*
    954  * Top level request processor. Calls the appropriate processing
    955  * function based on request type. Handles service registration
    956  * client requests also.
    957  */
    958 static void process_request(sdp_req_t *req)
    959 {
    960 	sdp_pdu_hdr_t *reqhdr = (sdp_pdu_hdr_t *)req->buf;
    961 	sdp_pdu_hdr_t *rsphdr;
    962 	sdp_buf_t rsp;
    963 	uint8_t *buf = malloc(USHRT_MAX);
    964 	int status = SDP_INVALID_SYNTAX;
    965 
    966 	memset(buf, 0, USHRT_MAX);
    967 	rsp.data = buf + sizeof(sdp_pdu_hdr_t);
    968 	rsp.data_size = 0;
    969 	rsp.buf_size = USHRT_MAX - sizeof(sdp_pdu_hdr_t);
    970 	rsphdr = (sdp_pdu_hdr_t *)buf;
    971 
    972 	if (ntohs(reqhdr->plen) != req->len - sizeof(sdp_pdu_hdr_t)) {
    973 		status = SDP_INVALID_PDU_SIZE;
    974 		goto send_rsp;
    975 	}
    976 	switch (reqhdr->pdu_id) {
    977 	case SDP_SVC_SEARCH_REQ:
    978 		SDPDBG("Got a svc srch req");
    979 		status = service_search_req(req, &rsp);
    980 		rsphdr->pdu_id = SDP_SVC_SEARCH_RSP;
    981 		break;
    982 	case SDP_SVC_ATTR_REQ:
    983 		SDPDBG("Got a svc attr req");
    984 		status = service_attr_req(req, &rsp);
    985 		rsphdr->pdu_id = SDP_SVC_ATTR_RSP;
    986 		break;
    987 	case SDP_SVC_SEARCH_ATTR_REQ:
    988 		SDPDBG("Got a svc srch attr req");
    989 		status = service_search_attr_req(req, &rsp);
    990 		rsphdr->pdu_id = SDP_SVC_SEARCH_ATTR_RSP;
    991 		break;
    992 	/* Following requests are allowed only for local connections */
    993 	case SDP_SVC_REGISTER_REQ:
    994 		SDPDBG("Service register request");
    995 		if (req->local) {
    996 			status = service_register_req(req, &rsp);
    997 			rsphdr->pdu_id = SDP_SVC_REGISTER_RSP;
    998 		}
    999 		break;
   1000 	case SDP_SVC_UPDATE_REQ:
   1001 		SDPDBG("Service update request");
   1002 		if (req->local) {
   1003 			status = service_update_req(req, &rsp);
   1004 			rsphdr->pdu_id = SDP_SVC_UPDATE_RSP;
   1005 		}
   1006 		break;
   1007 	case SDP_SVC_REMOVE_REQ:
   1008 		SDPDBG("Service removal request");
   1009 		if (req->local) {
   1010 			status = service_remove_req(req, &rsp);
   1011 			rsphdr->pdu_id = SDP_SVC_REMOVE_RSP;
   1012 		}
   1013 		break;
   1014 	default:
   1015 		error("Unknown PDU ID : 0x%x received", reqhdr->pdu_id);
   1016 		status = SDP_INVALID_SYNTAX;
   1017 		break;
   1018 	}
   1019 
   1020 send_rsp:
   1021 	if (status) {
   1022 		rsphdr->pdu_id = SDP_ERROR_RSP;
   1023 		bt_put_unaligned(htons(status), (uint16_t *)rsp.data);
   1024 		rsp.data_size = sizeof(uint16_t);
   1025 	}
   1026 
   1027 	SDPDBG("Sending rsp. status %d", status);
   1028 
   1029 	rsphdr->tid  = reqhdr->tid;
   1030 	rsphdr->plen = htons(rsp.data_size);
   1031 
   1032 	/* point back to the real buffer start and set the real rsp length */
   1033 	rsp.data_size += sizeof(sdp_pdu_hdr_t);
   1034 	rsp.data = buf;
   1035 
   1036 	/* stream the rsp PDU */
   1037 	if (send(req->sock, rsp.data, rsp.data_size, 0) < 0)
   1038 		error("send: %s (%d)", strerror(errno), errno);
   1039 
   1040 	SDPDBG("Bytes Sent : %d", sent);
   1041 
   1042 	free(rsp.data);
   1043 	free(req->buf);
   1044 }
   1045 
   1046 void handle_request(int sk, uint8_t *data, int len)
   1047 {
   1048 	struct sockaddr_l2 sa;
   1049 	socklen_t size;
   1050 	sdp_req_t req;
   1051 
   1052 	size = sizeof(sa);
   1053 	if (getpeername(sk, (struct sockaddr *) &sa, &size) < 0) {
   1054 		error("getpeername: %s", strerror(errno));
   1055 		return;
   1056 	}
   1057 
   1058 	if (sa.l2_family == AF_BLUETOOTH) {
   1059 		struct l2cap_options lo;
   1060 
   1061 		memset(&lo, 0, sizeof(lo));
   1062 		size = sizeof(lo);
   1063 
   1064 		if (getsockopt(sk, SOL_L2CAP, L2CAP_OPTIONS, &lo, &size) < 0) {
   1065 			error("getsockopt: %s", strerror(errno));
   1066 			return;
   1067 		}
   1068 
   1069 		bacpy(&req.bdaddr, &sa.l2_bdaddr);
   1070 		req.mtu = lo.omtu;
   1071 		req.local = 0;
   1072 		memset(&sa, 0, sizeof(sa));
   1073 		size = sizeof(sa);
   1074 
   1075 		if (getsockname(sk, (struct sockaddr *) &sa, &size) < 0) {
   1076 			error("getsockname: %s", strerror(errno));
   1077 			return;
   1078 		}
   1079 
   1080 		bacpy(&req.device, &sa.l2_bdaddr);
   1081 	} else {
   1082 		bacpy(&req.device, BDADDR_ANY);
   1083 		bacpy(&req.bdaddr, BDADDR_LOCAL);
   1084 		req.mtu = 2048;
   1085 		req.local = 1;
   1086 	}
   1087 
   1088 	req.sock = sk;
   1089 	req.buf  = data;
   1090 	req.len  = len;
   1091 
   1092 	process_request(&req);
   1093 }
   1094