1187938Semax/* $NetBSD: sdp.c,v 1.2 2008/12/06 20:01:14 plunky Exp $ */ 2187938Semax 3187938Semax/*- 4187938Semax * Copyright (c) 2008 Iain Hibbert 5187938Semax * All rights reserved. 6187938Semax * 7187938Semax * Redistribution and use in source and binary forms, with or without 8187938Semax * modification, are permitted provided that the following conditions 9187938Semax * are met: 10187938Semax * 1. Redistributions of source code must retain the above copyright 11187938Semax * notice, this list of conditions and the following disclaimer. 12187938Semax * 2. Redistributions in binary form must reproduce the above copyright 13187938Semax * notice, this list of conditions and the following disclaimer in the 14187938Semax * documentation and/or other materials provided with the distribution. 15187938Semax * 16187938Semax * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 17187938Semax * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 18187938Semax * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 19187938Semax * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 20187938Semax * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 21187938Semax * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 22187938Semax * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 23187938Semax * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 24187938Semax * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 25187938Semax * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 26187938Semax */ 27187938Semax 28187938Semax/* $FreeBSD$ */ 29187938Semax 30187938Semax#include <sys/cdefs.h> 31187938Semax__RCSID("$NetBSD: sdp.c,v 1.2 2008/12/06 20:01:14 plunky Exp $"); 32187938Semax 33187938Semax#include <string.h> 34187938Semax 35187938Semax#include "sdp.h" 36187938Semax 37187938Semax/* 38187938Semax * SDP data stream manipulation routines 39187938Semax */ 40187938Semax 41187938Semax/* Bluetooth Base UUID */ 42187938Semaxstatic const uuid_t BASE_UUID = { 43187938Semax 0x00000000, 44187938Semax 0x0000, 45187938Semax 0x1000, 46187938Semax 0x80, 47187938Semax 0x00, 48187938Semax { 0x00, 0x80, 0x5f, 0x9b, 0x34, 0xfb } 49187938Semax}; 50187938Semax 51187938Semax/* 52187938Semax * _sdp_match_uuid16(ptr, limit, uuid) 53187938Semax * 54187938Semax * examine SDP data stream at ptr for a UUID, and return 55187938Semax * true if it matches the supplied short alias bluetooth UUID. 56187938Semax * limit is the first address past the end of valid data. 57187938Semax */ 58187938Semaxbool 59187938Semax_sdp_match_uuid16(uint8_t **ptr, uint8_t *limit, uint16_t uuid) 60187938Semax{ 61187938Semax uint8_t *p = *ptr; 62187938Semax uuid_t u1, u2; 63187938Semax 64187938Semax memcpy(&u1, &BASE_UUID, sizeof(uuid_t)); 65187938Semax u1.time_low = uuid; 66187938Semax 67187938Semax if (!_sdp_get_uuid(&p, limit, &u2) 68187938Semax || !uuid_equal(&u1, &u2, NULL)) 69187938Semax return false; 70187938Semax 71187938Semax *ptr = p; 72187938Semax return true; 73187938Semax} 74187938Semax 75187938Semax/* 76187938Semax * _sdp_get_uuid(ptr, limit, uuid) 77187938Semax * 78187938Semax * examine SDP data stream at ptr for a UUID, and extract 79187938Semax * to given storage, advancing ptr. 80187938Semax * limit is the first address past the end of valid data. 81187938Semax */ 82187938Semaxbool 83187938Semax_sdp_get_uuid(uint8_t **ptr, uint8_t *limit, uuid_t *uuid) 84187938Semax{ 85187938Semax uint8_t *p = *ptr; 86187938Semax 87187938Semax if (p + 1 > limit) 88187938Semax return false; 89187938Semax 90187938Semax switch (*p++) { 91187938Semax case SDP_DATA_UUID16: 92187938Semax if (p + 2 > limit) 93187938Semax return false; 94187938Semax 95187938Semax memcpy(uuid, &BASE_UUID, sizeof(uuid_t)); 96187938Semax uuid->time_low = be16dec(p); 97187938Semax p += 2; 98187938Semax break; 99187938Semax 100187938Semax case SDP_DATA_UUID32: 101187938Semax if (p + 4 > limit) 102187938Semax return false; 103187938Semax 104187938Semax memcpy(uuid, &BASE_UUID, sizeof(uuid_t)); 105187938Semax uuid->time_low = be32dec(p); 106187938Semax p += 4; 107187938Semax break; 108187938Semax 109187938Semax case SDP_DATA_UUID128: 110187938Semax if (p + 16 > limit) 111187938Semax return false; 112187938Semax 113187938Semax uuid_dec_be(p, uuid); 114187938Semax p += 16; 115187938Semax break; 116187938Semax 117187938Semax default: 118187938Semax return false; 119187938Semax } 120187938Semax 121187938Semax *ptr = p; 122187938Semax return true; 123187938Semax} 124187938Semax 125187938Semax/* 126187938Semax * _sdp_get_seq(ptr, limit, seq) 127187938Semax * 128187938Semax * examine SDP data stream at ptr for a sequence. return 129187938Semax * seq pointer if found and advance ptr to next object. 130187938Semax * limit is the first address past the end of valid data. 131187938Semax */ 132187938Semaxbool 133187938Semax_sdp_get_seq(uint8_t **ptr, uint8_t *limit, uint8_t **seq) 134187938Semax{ 135187938Semax uint8_t *p = *ptr; 136187938Semax int32_t l; 137187938Semax 138187938Semax if (p + 1 > limit) 139187938Semax return false; 140187938Semax 141187938Semax switch (*p++) { 142187938Semax case SDP_DATA_SEQ8: 143187938Semax if (p + 1 > limit) 144187938Semax return false; 145187938Semax 146187938Semax l = *p; 147187938Semax p += 1; 148187938Semax break; 149187938Semax 150187938Semax case SDP_DATA_SEQ16: 151187938Semax if (p + 2 > limit) 152187938Semax return false; 153187938Semax 154187938Semax l = be16dec(p); 155187938Semax p += 2; 156187938Semax break; 157187938Semax 158187938Semax case SDP_DATA_SEQ32: 159187938Semax if (p + 4 > limit) 160187938Semax return false; 161187938Semax 162187938Semax l = be32dec(p); 163187938Semax p += 4; 164187938Semax break; 165187938Semax 166187938Semax default: 167187938Semax return false; 168187938Semax } 169187938Semax if (p + l > limit) 170187938Semax return false; 171187938Semax 172187938Semax *seq = p; 173187938Semax *ptr = p + l; 174187938Semax return true; 175187938Semax} 176187938Semax 177187938Semax/* 178187938Semax * _sdp_get_uint16(ptr, limit, value) 179187938Semax * 180187938Semax * examine SDP data stream at ptr for a uint16_t, and 181187938Semax * extract to given storage, advancing ptr. 182187938Semax * limit is the first address past the end of valid data. 183187938Semax */ 184187938Semaxbool 185187938Semax_sdp_get_uint16(uint8_t **ptr, uint8_t *limit, uint16_t *value) 186187938Semax{ 187187938Semax uint8_t *p = *ptr; 188187938Semax uint16_t v; 189187938Semax 190187938Semax if (p + 1 > limit) 191187938Semax return false; 192187938Semax 193187938Semax switch (*p++) { 194187938Semax case SDP_DATA_UINT16: 195187938Semax if (p + 2 > limit) 196187938Semax return false; 197187938Semax 198187938Semax v = be16dec(p); 199187938Semax p += 2; 200187938Semax break; 201187938Semax 202187938Semax default: 203187938Semax return false; 204187938Semax } 205187938Semax 206187938Semax *value = v; 207187938Semax *ptr = p; 208187938Semax return true; 209187938Semax} 210