[BACK]Return to sdp_put.c CVS log [TXT][DIR] Up to [cvs.NetBSD.org] / src / lib / libbluetooth

Annotation of src/lib/libbluetooth/sdp_put.c, Revision 1.6

1.6     ! plunky      1: /*     $NetBSD: sdp_put.c,v 1.5 2011/04/05 18:19:04 plunky Exp $       */
1.1       plunky      2:
                      3: /*-
                      4:  * Copyright (c) 2009 The NetBSD Foundation, Inc.
                      5:  * All rights reserved.
                      6:  *
                      7:  * This code is derived from software contributed to The NetBSD Foundation
                      8:  * by Iain Hibbert.
                      9:  *
                     10:  * Redistribution and use in source and binary forms, with or without
                     11:  * modification, are permitted provided that the following conditions
                     12:  * are met:
                     13:  * 1. Redistributions of source code must retain the above copyright
                     14:  *    notice, this list of conditions and the following disclaimer.
                     15:  * 2. Redistributions in binary form must reproduce the above copyright
                     16:  *    notice, this list of conditions and the following disclaimer in the
                     17:  *    documentation and/or other materials provided with the distribution.
                     18:  *
                     19:  * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
                     20:  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
                     21:  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
                     22:  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
                     23:  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
                     24:  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
                     25:  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
                     26:  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
                     27:  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
                     28:  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
                     29:  * POSSIBILITY OF SUCH DAMAGE.
                     30:  */
                     31:
                     32: #include <sys/cdefs.h>
1.6     ! plunky     33: __RCSID("$NetBSD: sdp_put.c,v 1.5 2011/04/05 18:19:04 plunky Exp $");
1.1       plunky     34:
                     35: #include <bluetooth.h>
                     36: #include <limits.h>
                     37: #include <sdp.h>
                     38: #include <string.h>
                     39:
                     40: /******************************************************************************
                     41:  *     sdp_put_xxxx(data, value)
                     42:  *
                     43:  * write a value to data space and advance data pointers,
                     44:  * fail if data space is not large enough
                     45:  */
                     46:
                     47: bool
                     48: sdp_put_data(sdp_data_t *data, sdp_data_t *value)
                     49: {
                     50:        ssize_t len;
                     51:
                     52:        len = value->end - value->next;
                     53:
1.5       plunky     54:        if (len > data->end - data->next)
1.1       plunky     55:                return false;
                     56:
                     57:        memcpy(data->next, value->next, (size_t)len);
                     58:        data->next += len;
                     59:        return true;
                     60: }
                     61:
                     62: bool
                     63: sdp_put_attr(sdp_data_t *data, uint16_t attr, sdp_data_t *value)
                     64: {
                     65:        sdp_data_t d = *data;
                     66:
                     67:        if (!sdp_put_uint16(&d, attr)
1.6     ! plunky     68:            || sdp_data_size(value) != (value->end - value->next)
1.4       plunky     69:            || !sdp_put_data(&d, value))
1.1       plunky     70:                return false;
                     71:
                     72:        *data = d;
                     73:        return true;
                     74: }
                     75:
                     76: bool
                     77: sdp_put_uuid(sdp_data_t *data, const uuid_t *uuid)
                     78: {
                     79:        uuid_t u = *uuid;
                     80:
                     81:        u.time_low = 0;
                     82:
                     83:        if (uuid_equal(&u, &BLUETOOTH_BASE_UUID, NULL) == 0)
                     84:                return sdp_put_uuid128(data, uuid);
                     85:
                     86:        if (uuid->time_low > UINT16_MAX)
                     87:                return sdp_put_uuid32(data, (uint32_t)uuid->time_low);
                     88:
                     89:        return sdp_put_uuid16(data, (uint16_t)uuid->time_low);
                     90: }
                     91:
                     92: bool
                     93: sdp_put_uuid16(sdp_data_t *data, uint16_t uuid)
                     94: {
                     95:
                     96:        if (data->next + 3 > data->end)
                     97:                return false;
                     98:
                     99:        data->next[0] = SDP_DATA_UUID16;
                    100:        be16enc(data->next + 1, uuid);
                    101:        data->next += 3;
                    102:        return true;
                    103: }
                    104:
                    105: bool
                    106: sdp_put_uuid32(sdp_data_t *data, uint32_t uuid)
                    107: {
                    108:
                    109:        if (data->next + 5 > data->end)
                    110:                return false;
                    111:
                    112:        data->next[0] = SDP_DATA_UUID32;
                    113:        be32enc(data->next + 1, uuid);
                    114:        data->next += 5;
                    115:        return true;
                    116: }
                    117:
                    118: bool
                    119: sdp_put_uuid128(sdp_data_t *data, const uuid_t *uuid)
                    120: {
                    121:
                    122:        if (data->next + 17 > data->end)
                    123:                return false;
                    124:
                    125:        data->next[0] = SDP_DATA_UUID128;
                    126:        uuid_enc_be(data->next + 1, uuid);
                    127:        data->next += 17;
                    128:        return true;
                    129: }
                    130:
                    131: bool
                    132: sdp_put_bool(sdp_data_t *data, bool value)
                    133: {
                    134:
                    135:        if (data->next + 2 > data->end)
                    136:                return false;
                    137:
                    138:        data->next[0] = SDP_DATA_BOOL;
                    139:        data->next[1] = (value ? 0x01 : 0x00);
                    140:        data->next += 2;
                    141:        return true;
                    142: }
                    143:
                    144: bool
                    145: sdp_put_uint(sdp_data_t *data, uintmax_t value)
                    146: {
                    147:
                    148:        if (value > UINT64_MAX)
                    149:                return false;
                    150:
                    151:        if (value > UINT32_MAX)
                    152:                return sdp_put_uint64(data, (uint64_t)value);
                    153:
                    154:        if (value > UINT16_MAX)
                    155:                return sdp_put_uint32(data, (uint32_t)value);
                    156:
                    157:        if (value > UINT8_MAX)
                    158:                return sdp_put_uint16(data, (uint16_t)value);
                    159:
                    160:        return sdp_put_uint8(data, (uint8_t)value);
                    161: }
                    162:
                    163: bool
                    164: sdp_put_uint8(sdp_data_t *data, uint8_t value)
                    165: {
                    166:
                    167:        if (data->next + 2 > data->end)
                    168:                return false;
                    169:
                    170:        data->next[0] = SDP_DATA_UINT8;
                    171:        data->next[1] = value;
                    172:        data->next += 2;
                    173:        return true;
                    174: }
                    175:
                    176: bool
                    177: sdp_put_uint16(sdp_data_t *data, uint16_t value)
                    178: {
                    179:
                    180:        if (data->next + 3 > data->end)
                    181:                return false;
                    182:
                    183:        data->next[0] = SDP_DATA_UINT16;
                    184:        be16enc(data->next + 1, value);
                    185:        data->next += 3;
                    186:        return true;
                    187: }
                    188:
                    189: bool
                    190: sdp_put_uint32(sdp_data_t *data, uint32_t value)
                    191: {
                    192:
                    193:        if (data->next + 5 > data->end)
                    194:                return false;
                    195:
                    196:        data->next[0] = SDP_DATA_UINT32;
                    197:        be32enc(data->next + 1, value);
                    198:        data->next += 5;
                    199:        return true;
                    200: }
                    201:
                    202: bool
                    203: sdp_put_uint64(sdp_data_t *data, uint64_t value)
                    204: {
                    205:
                    206:        if (data->next + 9 > data->end)
                    207:                return false;
                    208:
                    209:        data->next[0] = SDP_DATA_UINT64;
                    210:        be64enc(data->next + 1, value);
                    211:        data->next += 9;
                    212:        return true;
                    213: }
                    214:
                    215: bool
                    216: sdp_put_int(sdp_data_t *data, intmax_t value)
                    217: {
                    218:
                    219:        if (value > INT64_MAX || value < INT64_MIN)
                    220:                return false;
                    221:
                    222:        if (value > INT32_MAX || value < INT32_MIN)
                    223:                return sdp_put_int64(data, (int64_t)value);
                    224:
                    225:        if (value > INT16_MAX || value < INT16_MIN)
                    226:                return sdp_put_int32(data, (int32_t)value);
                    227:
                    228:        if (value > INT8_MAX || value < INT8_MIN)
                    229:                return sdp_put_int16(data, (int16_t)value);
                    230:
                    231:        return sdp_put_int8(data, (int8_t)value);
                    232: }
                    233:
                    234: bool
                    235: sdp_put_int8(sdp_data_t *data, int8_t value)
                    236: {
                    237:
                    238:        if (data->next + 2 > data->end)
                    239:                return false;
                    240:
                    241:        data->next[0] = SDP_DATA_INT8;
                    242:        data->next[1] = (uint8_t)value;
                    243:        data->next += 2;
                    244:        return true;
                    245: }
                    246:
                    247: bool
                    248: sdp_put_int16(sdp_data_t *data, int16_t value)
                    249: {
                    250:
                    251:        if (data->next + 3 > data->end)
                    252:                return false;
                    253:
                    254:        data->next[0] = SDP_DATA_INT16;
                    255:        be16enc(data->next + 1, (uint16_t)value);
                    256:        data->next += 3;
                    257:        return true;
                    258: }
                    259:
                    260: bool
                    261: sdp_put_int32(sdp_data_t *data, int32_t value)
                    262: {
                    263:
                    264:        if (data->next + 5 > data->end)
                    265:                return false;
                    266:
                    267:        data->next[0] = SDP_DATA_INT32;
                    268:        be32enc(data->next + 1, (uint32_t)value);
                    269:        data->next += 5;
                    270:        return true;
                    271: }
                    272:
                    273: bool
                    274: sdp_put_int64(sdp_data_t *data, int64_t value)
                    275: {
                    276:
                    277:        if (data->next + 9 > data->end)
                    278:                return false;
                    279:
                    280:        data->next[0] = SDP_DATA_INT64;
                    281:        be64enc(data->next + 1, (uint64_t)value);
                    282:        data->next += 9;
                    283:        return true;
                    284: }
                    285:
                    286: static bool
                    287: _sdp_put_ext(uint8_t type, sdp_data_t *data, ssize_t len)
                    288: {
                    289:        uint8_t *p = data->next;
                    290:
                    291:        if (len == -1) {
                    292:                if (p + 2 > data->end)
                    293:                        return false;
                    294:
                    295:                len = data->end - p - 2;
                    296:
                    297:                if (len > UINT8_MAX)
                    298:                        len -= 1;
                    299:
                    300:                if (len > UINT16_MAX)
                    301:                        len -= 2;
                    302:        }
                    303:
1.2       plunky    304:        if ((size_t)len > UINT32_MAX)
1.1       plunky    305:                return false;
                    306:
1.2       plunky    307:        if ((size_t)len > UINT16_MAX) {
1.5       plunky    308:                if (len > data->end - 5 - p)
1.1       plunky    309:                        return false;
                    310:
                    311:                p[0] = type | SDP_DATA_EXT32;
                    312:                be32enc(p + 1, (uint32_t)len);
                    313:                p += 5;
1.2       plunky    314:        } else if ((size_t)len > UINT8_MAX) {
1.5       plunky    315:                if (len > data->end - 3 - p)
1.1       plunky    316:                        return false;
                    317:
                    318:                p[0] = type | SDP_DATA_EXT16;
                    319:                be16enc(p + 1, (uint16_t)len);
                    320:                p += 3;
                    321:        } else {
1.5       plunky    322:                if (len > data->end - 2 - p)
1.1       plunky    323:                        return false;
                    324:
                    325:                p[0] = type | SDP_DATA_EXT8;
                    326:                p[1] = (uint8_t)len;
                    327:                p += 2;
                    328:        }
                    329:
                    330:        data->next = p;
                    331:        return true;
                    332: }
                    333:
                    334: bool
                    335: sdp_put_seq(sdp_data_t *data, ssize_t len)
                    336: {
                    337:
                    338:        return _sdp_put_ext(SDP_DATA_SEQ, data, len);
                    339: }
                    340:
                    341: bool
                    342: sdp_put_alt(sdp_data_t *data, ssize_t len)
                    343: {
                    344:
                    345:        return _sdp_put_ext(SDP_DATA_ALT, data, len);
                    346: }
                    347:
                    348: bool
                    349: sdp_put_str(sdp_data_t *data, const char *str, ssize_t len)
                    350: {
                    351:
                    352:        if (len == -1)
                    353:                len = strlen(str);
                    354:
                    355:        if (!_sdp_put_ext(SDP_DATA_STR, data, len))
                    356:                return false;
                    357:
1.3       plunky    358:        memcpy(data->next, str, (size_t)len);
1.1       plunky    359:        data->next += len;
                    360:        return true;
                    361: }
                    362:
                    363: bool
                    364: sdp_put_url(sdp_data_t *data, const char *url, ssize_t len)
                    365: {
                    366:
                    367:        if (len == -1)
                    368:                len = strlen(url);
                    369:
                    370:        if (!_sdp_put_ext(SDP_DATA_URL, data, len))
                    371:                return false;
                    372:
1.3       plunky    373:        memcpy(data->next, url, (size_t)len);
1.1       plunky    374:        data->next += len;
                    375:        return true;
                    376: }

CVSweb <webmaster@jp.NetBSD.org>