/* $NetBSD: sdp.c,v 1.2 2008/12/06 20:01:14 plunky Exp $ */12/*-3* SPDX-License-Identifier: BSD-2-Clause4*5* Copyright (c) 2008 Iain Hibbert6* All rights reserved.7*8* Redistribution and use in source and binary forms, with or without9* modification, are permitted provided that the following conditions10* are met:11* 1. Redistributions of source code must retain the above copyright12* notice, this list of conditions and the following disclaimer.13* 2. Redistributions in binary form must reproduce the above copyright14* notice, this list of conditions and the following disclaimer in the15* documentation and/or other materials provided with the distribution.16*17* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR18* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES19* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.20* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,21* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT22* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,23* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY24* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT25* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF26* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.27*/282930#include <sys/cdefs.h>31__RCSID("$NetBSD: sdp.c,v 1.2 2008/12/06 20:01:14 plunky Exp $");3233#include <string.h>3435#define L2CAP_SOCKET_CHECKED36#include "sdp.h"3738/*39* SDP data stream manipulation routines40*/4142/* Bluetooth Base UUID */43static const uuid_t BASE_UUID = {440x00000000,450x0000,460x1000,470x80,480x00,49{ 0x00, 0x80, 0x5f, 0x9b, 0x34, 0xfb }50};5152/*53* _sdp_match_uuid16(ptr, limit, uuid)54*55* examine SDP data stream at ptr for a UUID, and return56* true if it matches the supplied short alias bluetooth UUID.57* limit is the first address past the end of valid data.58*/59bool60_sdp_match_uuid16(uint8_t **ptr, uint8_t *limit, uint16_t uuid)61{62uint8_t *p = *ptr;63uuid_t u1, u2;6465memcpy(&u1, &BASE_UUID, sizeof(uuid_t));66u1.time_low = uuid;6768if (!_sdp_get_uuid(&p, limit, &u2)69|| !uuid_equal(&u1, &u2, NULL))70return false;7172*ptr = p;73return true;74}7576/*77* _sdp_get_uuid(ptr, limit, uuid)78*79* examine SDP data stream at ptr for a UUID, and extract80* to given storage, advancing ptr.81* limit is the first address past the end of valid data.82*/83bool84_sdp_get_uuid(uint8_t **ptr, uint8_t *limit, uuid_t *uuid)85{86uint8_t *p = *ptr;8788if (p + 1 > limit)89return false;9091switch (*p++) {92case SDP_DATA_UUID16:93if (p + 2 > limit)94return false;9596memcpy(uuid, &BASE_UUID, sizeof(uuid_t));97uuid->time_low = be16dec(p);98p += 2;99break;100101case SDP_DATA_UUID32:102if (p + 4 > limit)103return false;104105memcpy(uuid, &BASE_UUID, sizeof(uuid_t));106uuid->time_low = be32dec(p);107p += 4;108break;109110case SDP_DATA_UUID128:111if (p + 16 > limit)112return false;113114uuid_dec_be(p, uuid);115p += 16;116break;117118default:119return false;120}121122*ptr = p;123return true;124}125126/*127* _sdp_get_seq(ptr, limit, seq)128*129* examine SDP data stream at ptr for a sequence. return130* seq pointer if found and advance ptr to next object.131* limit is the first address past the end of valid data.132*/133bool134_sdp_get_seq(uint8_t **ptr, uint8_t *limit, uint8_t **seq)135{136uint8_t *p = *ptr;137int32_t l;138139if (p + 1 > limit)140return false;141142switch (*p++) {143case SDP_DATA_SEQ8:144if (p + 1 > limit)145return false;146147l = *p;148p += 1;149break;150151case SDP_DATA_SEQ16:152if (p + 2 > limit)153return false;154155l = be16dec(p);156p += 2;157break;158159case SDP_DATA_SEQ32:160if (p + 4 > limit)161return false;162163l = be32dec(p);164p += 4;165break;166167default:168return false;169}170if (p + l > limit)171return false;172173*seq = p;174*ptr = p + l;175return true;176}177178/*179* _sdp_get_uint16(ptr, limit, value)180*181* examine SDP data stream at ptr for a uint16_t, and182* extract to given storage, advancing ptr.183* limit is the first address past the end of valid data.184*/185bool186_sdp_get_uint16(uint8_t **ptr, uint8_t *limit, uint16_t *value)187{188uint8_t *p = *ptr;189uint16_t v;190191if (p + 1 > limit)192return false;193194switch (*p++) {195case SDP_DATA_UINT16:196if (p + 2 > limit)197return false;198199v = be16dec(p);200p += 2;201break;202203default:204return false;205}206207*value = v;208*ptr = p;209return true;210}211212213