Exemplo n.º 1
0
/*
 * Generic data element sequence extractor. Builds
 * a list whose elements are those found in the
 * sequence. The data type of elements found in the
 * sequence is returned in the reference pDataType
 */
static int extract_des(uint8_t *buf, int len, sdp_list_t **svcReqSeq, uint8_t *pDataType, uint8_t expectedType)
{
	uint8_t seqType;
	int scanned, data_size = 0;
	short numberOfElements = 0;
	int seqlen = 0;
	sdp_list_t *pSeq = NULL;
	uint8_t dataType;
	int status = 0;
	const uint8_t *p;
	size_t bufsize;

	scanned = sdp_extract_seqtype(buf, len, &seqType, &data_size);

	SDPDBG("Seq type : %d", seqType);
	if (!scanned || (seqType != SDP_SEQ8 && seqType != SDP_SEQ16)) {
		error("Unknown seq type");
		return -1;
	}
	p = buf + scanned;
	bufsize = len - scanned;

	SDPDBG("Data size : %d", data_size);

	for (;;) {
		char *pElem = NULL;
		int localSeqLength = 0;

		if (bufsize < sizeof(uint8_t)) {
			SDPDBG("->Unexpected end of buffer");
			goto failed;
		}

		dataType = *p;

		SDPDBG("Data type: 0x%02x", dataType);

		if (expectedType == SDP_TYPE_UUID) {
			if (dataType != SDP_UUID16 && dataType != SDP_UUID32 && dataType != SDP_UUID128) {
				SDPDBG("->Unexpected Data type (expected UUID_ANY)");
				goto failed;
			}
		} else if (expectedType == SDP_TYPE_ATTRID &&
				(dataType != SDP_UINT16 && dataType != SDP_UINT32)) {
			SDPDBG("->Unexpected Data type (expected 0x%02x or 0x%02x)",
								SDP_UINT16, SDP_UINT32);
			goto failed;
		} else if (expectedType != SDP_TYPE_ATTRID && dataType != expectedType) {
			SDPDBG("->Unexpected Data type (expected 0x%02x)", expectedType);
			goto failed;
		}

		switch (dataType) {
		case SDP_UINT16:
			p += sizeof(uint8_t);
			seqlen += sizeof(uint8_t);
			bufsize -= sizeof(uint8_t);
			if (bufsize < sizeof(uint16_t)) {
				SDPDBG("->Unexpected end of buffer");
				goto failed;
			}

			if (expectedType == SDP_TYPE_ATTRID) {
				struct attrid *aid;
				aid = malloc(sizeof(struct attrid));
				aid->dtd = dataType;
				bt_put_unaligned(ntohs(bt_get_unaligned((uint16_t *)p)), (uint16_t *)&aid->uint16);
				pElem = (char *) aid;
			} else {
				pElem = malloc(sizeof(uint16_t));
				bt_put_unaligned(ntohs(bt_get_unaligned((uint16_t *)p)), (uint16_t *)pElem);
			}
			p += sizeof(uint16_t);
			seqlen += sizeof(uint16_t);
			bufsize -= sizeof(uint16_t);
			break;
		case SDP_UINT32:
			p += sizeof(uint8_t);
			seqlen += sizeof(uint8_t);
			bufsize -= sizeof(uint8_t);
			if (bufsize < (int)sizeof(uint32_t)) {
				SDPDBG("->Unexpected end of buffer");
				goto failed;
			}

			if (expectedType == SDP_TYPE_ATTRID) {
				struct attrid *aid;
				aid = malloc(sizeof(struct attrid));
				aid->dtd = dataType;
				bt_put_unaligned(ntohl(bt_get_unaligned((uint32_t *)p)), (uint32_t *)&aid->uint32);
				pElem = (char *) aid;
			} else {
				pElem = malloc(sizeof(uint32_t));
				bt_put_unaligned(ntohl(bt_get_unaligned((uint32_t *)p)), (uint32_t *)pElem);
			}
			p += sizeof(uint32_t);
			seqlen += sizeof(uint32_t);
			bufsize -= sizeof(uint32_t);
			break;
		case SDP_UUID16:
		case SDP_UUID32:
		case SDP_UUID128:
			pElem = malloc(sizeof(uuid_t));
			status = sdp_uuid_extract(p, bufsize, (uuid_t *) pElem, &localSeqLength);
			if (status < 0) {
				free(pElem);
				goto failed;
			}
			seqlen += localSeqLength;
			p += localSeqLength;
			bufsize -= localSeqLength;
			break;
		default:
			return -1;
		}
		if (status == 0) {
			pSeq = sdp_list_append(pSeq, pElem);
			numberOfElements++;
			SDPDBG("No of elements : %d", numberOfElements);

			if (seqlen == data_size)
				break;
			else if (seqlen > data_size || seqlen > len)
				goto failed;
		} else
			free(pElem);
	}
	*svcReqSeq = pSeq;
	scanned += seqlen;
	*pDataType = dataType;
	return scanned;

failed:
	sdp_list_free(pSeq, free);
	return -1;
}
Exemplo n.º 2
0
/*
 * Generic data element sequence extractor. Builds
 * a list whose elements are those found in the 
 * sequence. The data type of elements found in the
 * sequence is returned in the reference pDataType
 */
static int extract_des(uint8_t *buf, int len, sdp_list_t **svcReqSeq, uint8_t *pDataType, uint8_t expectedType)
{
	uint8_t seqType;
	int scanned, data_size = 0;
	short numberOfElements = 0;
	int seqlen = 0;
	sdp_list_t *pSeq = NULL;
	uint8_t dataType;
	int status = 0;
	const uint8_t *p;

	scanned = sdp_extract_seqtype(buf, &seqType, &data_size);

	debug("Seq type : %d", seqType);
	if (!scanned || (seqType != SDP_SEQ8 && seqType != SDP_SEQ16)) {
		error("Unknown seq type");
		return -1;
	}
	p = buf + scanned;

	debug("Data size : %d", data_size);

	for (;;) {
		char *pElem = NULL;
		int localSeqLength = 0;

		dataType = *(uint8_t *)p;
		debug("Data type: 0x%02x", dataType);

		if (expectedType == SDP_TYPE_UUID) {
			if (dataType != SDP_UUID16 && dataType != SDP_UUID32 && dataType != SDP_UUID128) {
				debug("->Unexpected Data type (expected UUID_ANY)");
				return -1;
			}
		} else if (expectedType != SDP_TYPE_ANY && dataType != expectedType) {
			debug("->Unexpected Data type (expected 0x%02x)", expectedType);
			return -1;
		}

		switch (dataType) {
		case SDP_UINT16:
			p += sizeof(uint8_t);
			seqlen += sizeof(uint8_t);
			pElem = malloc(sizeof(uint16_t));
			bt_put_unaligned(ntohs(bt_get_unaligned((uint16_t *)p)), (uint16_t *)pElem);
			p += sizeof(uint16_t);
			seqlen += sizeof(uint16_t);
			break;
		case SDP_UINT32:
			p += sizeof(uint8_t);
			seqlen += sizeof(uint8_t);
			pElem = malloc(sizeof(uint32_t));
			bt_put_unaligned(ntohl(bt_get_unaligned((uint32_t *)p)), (uint32_t *)pElem);
			p += sizeof(uint32_t);
			seqlen += sizeof(uint32_t);
			break;
		case SDP_UUID16:
		case SDP_UUID32:
		case SDP_UUID128:
			pElem = malloc(sizeof(uuid_t));
			status = sdp_uuid_extract(p, (uuid_t *)pElem, &localSeqLength);
			if (status == 0) {
				seqlen += localSeqLength;
				p += localSeqLength;
			}
			break;
		default:
			return -1;
		}
		if (status == 0) {
			pSeq = sdp_list_append(pSeq, pElem);
			numberOfElements++;
			debug("No of elements : %d", numberOfElements);

			if (seqlen == data_size)
				break;
			else if (seqlen > data_size || seqlen > len)
				return -1;
		} else
			free(pElem);
	}
	*svcReqSeq = pSeq;
	scanned += seqlen;
	*pDataType = dataType;
	return scanned;
}