/*
 * Service Discover Protocol server for QEMU L2CAP devices
 *
 * Copyright (C) 2008 Andrzej Zaborowski  <balrog@zabor.org>
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License as
 * published by the Free Software Foundation; either version 2 of
 * the License, or (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License along
 * with this program; if not, see <http://www.gnu.org/licenses/>.
 */

#include "qemu-common.h"
#include "hw/bt.h"

struct bt_l2cap_sdp_state_s {
    struct bt_l2cap_conn_params_s *channel;

    struct sdp_service_record_s {
        int match;

        int *uuid;
        int uuids;
        struct sdp_service_attribute_s {
            int match;

            int attribute_id;
            int len;
            void *pair;
        } *attribute_list;
        int attributes;
    } *service_list;
    int services;
};

static ssize_t sdp_datalen(const uint8_t **element, ssize_t *left)
{
    size_t len = *(*element) ++ & SDP_DSIZE_MASK;

    if (!*left)
        return -1;
    (*left) --;

    if (len < SDP_DSIZE_NEXT1)
        return 1 << len;
    else if (len == SDP_DSIZE_NEXT1) {
        if (*left < 1)
            return -1;
        (*left) --;

        return *(*element) ++;
    } else if (len == SDP_DSIZE_NEXT2) {
        if (*left < 2)
            return -1;
        (*left) -= 2;

        len = (*(*element) ++) << 8;
        return len | (*(*element) ++);
    } else {
        if (*left < 4)
            return -1;
        (*left) -= 4;

        len = (*(*element) ++) << 24;
        len |= (*(*element) ++) << 16;
        len |= (*(*element) ++) << 8;
        return len | (*(*element) ++);
    }
}

static const uint8_t bt_base_uuid[12] = {
    0x00, 0x00, 0x10, 0x00, 0x80, 0x00, 0x00, 0x80, 0x5f, 0x9b, 0x34, 0xfb,
};

static int sdp_uuid_match(struct sdp_service_record_s *record,
                const uint8_t *uuid, ssize_t datalen)
{
    int *lo, hi, val;

    if (datalen == 16 || datalen == 4) {
        if (datalen == 16 && memcmp(uuid + 4, bt_base_uuid, 12))
            return 0;

        if (uuid[0] | uuid[1])
            return 0;
        uuid += 2;
    }

    val = (uuid[0] << 8) | uuid[1];
    lo = record->uuid;
    hi = record->uuids;
    while (hi >>= 1)
        if (lo[hi] <= val)
            lo += hi;

    return *lo == val;
}

#define CONTINUATION_PARAM_SIZE	(1 + sizeof(int))
#define MAX_PDU_OUT_SIZE	96	/* Arbitrary */
#define PDU_HEADER_SIZE		5
#define MAX_RSP_PARAM_SIZE	(MAX_PDU_OUT_SIZE - PDU_HEADER_SIZE - \
                CONTINUATION_PARAM_SIZE)

static int sdp_svc_match(struct bt_l2cap_sdp_state_s *sdp,
                const uint8_t **req, ssize_t *len)
{
    size_t datalen;
    int i;

    if ((**req & ~SDP_DSIZE_MASK) != SDP_DTYPE_UUID)
        return 1;

    datalen = sdp_datalen(req, len);
    if (datalen != 2 && datalen != 4 && datalen != 16)
        return 1;

    for (i = 0; i < sdp->services; i ++)
        if (sdp_uuid_match(&sdp->service_list[i], *req, datalen))
            sdp->service_list[i].match = 1;

    (*req) += datalen;
    (*len) -= datalen;

    return 0;
}

static ssize_t sdp_svc_search(struct bt_l2cap_sdp_state_s *sdp,
                uint8_t *rsp, const uint8_t *req, ssize_t len)
{
    ssize_t seqlen;
    int i, count, start, end, max;
    int32_t handle;

    /* Perform the search */
    for (i = 0; i < sdp->services; i ++)
        sdp->service_list[i].match = 0;

    if (len < 1)
        return -SDP_INVALID_SYNTAX;
    if ((*req & ~SDP_DSIZE_MASK) == SDP_DTYPE_SEQ) {
        seqlen = sdp_datalen(&req, &len);
        if (seqlen < 3 || len < seqlen)
            return -SDP_INVALID_SYNTAX;
        len -= seqlen;
        while (seqlen)
            if (sdp_svc_match(sdp, &req, &seqlen))
                return -SDP_INVALID_SYNTAX;
    } else {
        if (sdp_svc_match(sdp, &req, &len)) {
            return -SDP_INVALID_SYNTAX;
        }
    }

    if (len < 3)
        return -SDP_INVALID_SYNTAX;
    max = (req[0] << 8) | req[1];
    req += 2;
    len -= 2;

    if (*req) {
        if (len <= sizeof(int))
            return -SDP_INVALID_SYNTAX;
        len -= sizeof(int);
        memcpy(&start, req + 1, sizeof(int));
    } else
        start = 0;

    if (len > 1)
        return -SDP_INVALID_SYNTAX;

    /* Output the results */
    len = 4;
    count = 0;
    end = start;
    for (i = 0; i < sdp->services; i ++)
        if (sdp->service_list[i].match) {
            if (count >= start && count < max && len + 4 < MAX_RSP_PARAM_SIZE) {
                handle = i;
                memcpy(rsp + len, &handle, 4);
                len += 4;
                end = count + 1;
            }

            count ++;
        }

    rsp[0] = count >> 8;
    rsp[1] = count & 0xff;
    rsp[2] = (end - start) >> 8;
    rsp[3] = (end - start) & 0xff;

    if (end < count) {
        rsp[len ++] = sizeof(int);
        memcpy(rsp + len, &end, sizeof(int));
        len += 4;
    } else
        rsp[len ++] = 0;

    return len;
}

static int sdp_attr_match(struct sdp_service_record_s *record,
                const uint8_t **req, ssize_t *len)
{
    int i, start, end;

    if (**req == (SDP_DTYPE_UINT | SDP_DSIZE_2)) {
        (*req) ++;
        if (*len < 3)
            return 1;

        start = (*(*req) ++) << 8;
        start |= *(*req) ++;
        end = start;
        *len -= 3;
    } else if (**req == (SDP_DTYPE_UINT | SDP_DSIZE_4)) {
        (*req) ++;
        if (*len < 5)
            return 1;

        start = (*(*req) ++) << 8;
        start |= *(*req) ++;
        end = (*(*req) ++) << 8;
        end |= *(*req) ++;
        *len -= 5;
    } else
        return 1;

    for (i = 0; i < record->attributes; i ++)
        if (record->attribute_list[i].attribute_id >= start &&
                        record->attribute_list[i].attribute_id <= end)
            record->attribute_list[i].match = 1;

    return 0;
}

static ssize_t sdp_attr_get(struct bt_l2cap_sdp_state_s *sdp,
                uint8_t *rsp, const uint8_t *req, ssize_t len)
{
    ssize_t seqlen;
    int i, start, end, max;
    int32_t handle;
    struct sdp_service_record_s *record;
    uint8_t *lst;

    /* Perform the search */
    if (len < 7)
        return -SDP_INVALID_SYNTAX;
    memcpy(&handle, req, 4);
    req += 4;
    len -= 4;

    if (handle < 0 || handle > sdp->services)
        return -SDP_INVALID_RECORD_HANDLE;
    record = &sdp->service_list[handle];

    for (i = 0; i < record->attributes; i ++)
        record->attribute_list[i].match = 0;

    max = (req[0] << 8) | req[1];
    req += 2;
    len -= 2;
    if (max < 0x0007)
        return -SDP_INVALID_SYNTAX;

    if ((*req & ~SDP_DSIZE_MASK) == SDP_DTYPE_SEQ) {
        seqlen = sdp_datalen(&req, &len);
        if (seqlen < 3 || len < seqlen)
            return -SDP_INVALID_SYNTAX;
        len -= seqlen;

        while (seqlen)
            if (sdp_attr_match(record, &req, &seqlen))
                return -SDP_INVALID_SYNTAX;
    } else {
        if (sdp_attr_match(record, &req, &len)) {
            return -SDP_INVALID_SYNTAX;
        }
    }

    if (len < 1)
        return -SDP_INVALID_SYNTAX;

    if (*req) {
        if (len <= sizeof(int))
            return -SDP_INVALID_SYNTAX;
        len -= sizeof(int);
        memcpy(&start, req + 1, sizeof(int));
    } else
        start = 0;

    if (len > 1)
        return -SDP_INVALID_SYNTAX;

    /* Output the results */
    lst = rsp + 2;
    max = MIN(max, MAX_RSP_PARAM_SIZE);
    len = 3 - start;
    end = 0;
    for (i = 0; i < record->attributes; i ++)
        if (record->attribute_list[i].match) {
            if (len >= 0 && len + record->attribute_list[i].len < max) {
                memcpy(lst + len, record->attribute_list[i].pair,
                                record->attribute_list[i].len);
                end = len + record->attribute_list[i].len;
            }
            len += record->attribute_list[i].len;
        }
    if (0 >= start) {
       lst[0] = SDP_DTYPE_SEQ | SDP_DSIZE_NEXT2;
       lst[1] = (len + start - 3) >> 8;
       lst[2] = (len + start - 3) & 0xff;
    }

    rsp[0] = end >> 8;
    rsp[1] = end & 0xff;

    if (end < len) {
        len = end + start;
        lst[end ++] = sizeof(int);
        memcpy(lst + end, &len, sizeof(int));
        end += sizeof(int);
    } else
        lst[end ++] = 0;

    return end + 2;
}

static int sdp_svc_attr_match(struct bt_l2cap_sdp_state_s *sdp,
                const uint8_t **req, ssize_t *len)
{
    int i, j, start, end;
    struct sdp_service_record_s *record;

    if (**req == (SDP_DTYPE_UINT | SDP_DSIZE_2)) {
        (*req) ++;
        if (*len < 3)
            return 1;

        start = (*(*req) ++) << 8;
        start |= *(*req) ++;
        end = start;
        *len -= 3;
    } else if (**req == (SDP_DTYPE_UINT | SDP_DSIZE_4)) {
        (*req) ++;
        if (*len < 5)
            return 1;

        start = (*(*req) ++) << 8;
        start |= *(*req) ++;
        end = (*(*req) ++) << 8;
        end |= *(*req) ++;
        *len -= 5;
    } else
        return 1;

    for (i = 0; i < sdp->services; i ++)
        if ((record = &sdp->service_list[i])->match)
            for (j = 0; j < record->attributes; j ++)
                if (record->attribute_list[j].attribute_id >= start &&
                                record->attribute_list[j].attribute_id <= end)
                    record->attribute_list[j].match = 1;

    return 0;
}

static ssize_t sdp_svc_search_attr_get(struct bt_l2cap_sdp_state_s *sdp,
                uint8_t *rsp, const uint8_t *req, ssize_t len)
{
    ssize_t seqlen;
    int i, j, start, end, max;
    struct sdp_service_record_s *record;
    uint8_t *lst;

    /* Perform the search */
    for (i = 0; i < sdp->services; i ++) {
        sdp->service_list[i].match = 0;
            for (j = 0; j < sdp->service_list[i].attributes; j ++)
                sdp->service_list[i].attribute_list[j].match = 0;
    }

    if (len < 1)
        return -SDP_INVALID_SYNTAX;
    if ((*req & ~SDP_DSIZE_MASK) == SDP_DTYPE_SEQ) {
        seqlen = sdp_datalen(&req, &len);
        if (seqlen < 3 || len < seqlen)
            return -SDP_INVALID_SYNTAX;
        len -= seqlen;

        while (seqlen)
            if (sdp_svc_match(sdp, &req, &seqlen))
                return -SDP_INVALID_SYNTAX;
    } else {
        if (sdp_svc_match(sdp, &req, &len)) {
            return -SDP_INVALID_SYNTAX;
        }
    }

    if (len < 3)
        return -SDP_INVALID_SYNTAX;
    max = (req[0] << 8) | req[1];
    req += 2;
    len -= 2;
    if (max < 0x0007)
        return -SDP_INVALID_SYNTAX;

    if ((*req & ~SDP_DSIZE_MASK) == SDP_DTYPE_SEQ) {
        seqlen = sdp_datalen(&req, &len);
        if (seqlen < 3 || len < seqlen)
            return -SDP_INVALID_SYNTAX;
        len -= seqlen;

        while (seqlen)
            if (sdp_svc_attr_match(sdp, &req, &seqlen))
                return -SDP_INVALID_SYNTAX;
    } else {
        if (sdp_svc_attr_match(sdp, &req, &len)) {
            return -SDP_INVALID_SYNTAX;
        }
    }

    if (len < 1)
        return -SDP_INVALID_SYNTAX;

    if (*req) {
        if (len <= sizeof(int))
            return -SDP_INVALID_SYNTAX;
        len -= sizeof(int);
        memcpy(&start, req + 1, sizeof(int));
    } else
        start = 0;

    if (len > 1)
        return -SDP_INVALID_SYNTAX;

    /* Output the results */
    /* This assumes empty attribute lists are never to be returned even
     * for matching Service Records.  In practice this shouldn't happen
     * as the requestor will usually include the always present
     * ServiceRecordHandle AttributeID in AttributeIDList.  */
    lst = rsp + 2;
    max = MIN(max, MAX_RSP_PARAM_SIZE);
    len = 3 - start;
    end = 0;
    for (i = 0; i < sdp->services; i ++)
        if ((record = &sdp->service_list[i])->match) {
            len += 3;
            seqlen = len;
            for (j = 0; j < record->attributes; j ++)
                if (record->attribute_list[j].match) {
                    if (len >= 0)
                        if (len + record->attribute_list[j].len < max) {
                            memcpy(lst + len, record->attribute_list[j].pair,
                                            record->attribute_list[j].len);
                            end = len + record->attribute_list[j].len;
                        }
                    len += record->attribute_list[j].len;
                }
            if (seqlen == len)
                len -= 3;
            else if (seqlen >= 3 && seqlen < max) {
                lst[seqlen - 3] = SDP_DTYPE_SEQ | SDP_DSIZE_NEXT2;
                lst[seqlen - 2] = (len - seqlen) >> 8;
                lst[seqlen - 1] = (len - seqlen) & 0xff;
            }
        }
    if (len == 3 - start)
        len -= 3;
    else if (0 >= start) {
       lst[0] = SDP_DTYPE_SEQ | SDP_DSIZE_NEXT2;
       lst[1] = (len + start - 3) >> 8;
       lst[2] = (len + start - 3) & 0xff;
    }

    rsp[0] = end >> 8;
    rsp[1] = end & 0xff;

    if (end < len) {
        len = end + start;
        lst[end ++] = sizeof(int);
        memcpy(lst + end, &len, sizeof(int));
        end += sizeof(int);
    } else
        lst[end ++] = 0;

    return end + 2;
}

static void bt_l2cap_sdp_sdu_in(void *opaque, const uint8_t *data, int len)
{
    struct bt_l2cap_sdp_state_s *sdp = opaque;
    enum bt_sdp_cmd pdu_id;
    uint8_t rsp[MAX_PDU_OUT_SIZE - PDU_HEADER_SIZE], *sdu_out;
    int transaction_id, plen;
    int err = 0;
    int rsp_len = 0;

    if (len < 5) {
        fprintf(stderr, "%s: short SDP PDU (%iB).\n", __FUNCTION__, len);
        return;
    }

    pdu_id = *data ++;
    transaction_id = (data[0] << 8) | data[1];
    plen = (data[2] << 8) | data[3];
    data += 4;
    len -= 5;

    if (len != plen) {
        fprintf(stderr, "%s: wrong SDP PDU length (%iB != %iB).\n",
                        __FUNCTION__, plen, len);
        err = SDP_INVALID_PDU_SIZE;
        goto respond;
    }

    switch (pdu_id) {
    case SDP_SVC_SEARCH_REQ:
        rsp_len = sdp_svc_search(sdp, rsp, data, len);
        pdu_id = SDP_SVC_SEARCH_RSP;
        break;

    case SDP_SVC_ATTR_REQ:
        rsp_len = sdp_attr_get(sdp, rsp, data, len);
        pdu_id = SDP_SVC_ATTR_RSP;
        break;

    case SDP_SVC_SEARCH_ATTR_REQ:
        rsp_len = sdp_svc_search_attr_get(sdp, rsp, data, len);
        pdu_id = SDP_SVC_SEARCH_ATTR_RSP;
        break;

    case SDP_ERROR_RSP:
    case SDP_SVC_ATTR_RSP:
    case SDP_SVC_SEARCH_RSP:
    case SDP_SVC_SEARCH_ATTR_RSP:
    default:
        fprintf(stderr, "%s: unexpected SDP PDU ID %02x.\n",
                        __FUNCTION__, pdu_id);
        err = SDP_INVALID_SYNTAX;
        break;
    }

    if (rsp_len < 0) {
        err = -rsp_len;
        rsp_len = 0;
    }

respond:
    if (err) {
        pdu_id = SDP_ERROR_RSP;
        rsp[rsp_len ++] = err >> 8;
        rsp[rsp_len ++] = err & 0xff;
    }

    sdu_out = sdp->channel->sdu_out(sdp->channel, rsp_len + PDU_HEADER_SIZE);

    sdu_out[0] = pdu_id;
    sdu_out[1] = transaction_id >> 8;
    sdu_out[2] = transaction_id & 0xff;
    sdu_out[3] = rsp_len >> 8;
    sdu_out[4] = rsp_len & 0xff;
    memcpy(sdu_out + PDU_HEADER_SIZE, rsp, rsp_len);

    sdp->channel->sdu_submit(sdp->channel);
}

static void bt_l2cap_sdp_close_ch(void *opaque)
{
    struct bt_l2cap_sdp_state_s *sdp = opaque;
    int i;

    for (i = 0; i < sdp->services; i ++) {
        g_free(sdp->service_list[i].attribute_list->pair);
        g_free(sdp->service_list[i].attribute_list);
        g_free(sdp->service_list[i].uuid);
    }
    g_free(sdp->service_list);
    g_free(sdp);
}

struct sdp_def_service_s {
    uint16_t class_uuid;
    struct sdp_def_attribute_s {
        uint16_t id;
        struct sdp_def_data_element_s {
            uint8_t type;
            union {
                uint32_t uint;
                const char *str;
                struct sdp_def_data_element_s *list;
            } value;
        } data;
    } attributes[];
};

/* Calculate a safe byte count to allocate that will store the given
 * element, at the same time count elements of a UUID type.  */
static int sdp_attr_max_size(struct sdp_def_data_element_s *element,
                int *uuids)
{
    int type = element->type & ~SDP_DSIZE_MASK;
    int len;

    if (type == SDP_DTYPE_UINT || type == SDP_DTYPE_UUID ||
                    type == SDP_DTYPE_BOOL) {
        if (type == SDP_DTYPE_UUID)
            (*uuids) ++;
        return 1 + (1 << (element->type & SDP_DSIZE_MASK));
    }

    if (type == SDP_DTYPE_STRING || type == SDP_DTYPE_URL) {
        if (element->type & SDP_DSIZE_MASK) {
            for (len = 0; element->value.str[len] |
                            element->value.str[len + 1]; len ++);
            return len;
        } else
            return 2 + strlen(element->value.str);
    }

    if (type != SDP_DTYPE_SEQ)
        exit(-1);
    len = 2;
    element = element->value.list;
    while (element->type)
        len += sdp_attr_max_size(element ++, uuids);
    if (len > 255)
        exit (-1);

    return len;
}

static int sdp_attr_write(uint8_t *data,
                struct sdp_def_data_element_s *element, int **uuid)
{
    int type = element->type & ~SDP_DSIZE_MASK;
    int len = 0;

    if (type == SDP_DTYPE_UINT || type == SDP_DTYPE_BOOL) {
        data[len ++] = element->type;
        if ((element->type & SDP_DSIZE_MASK) == SDP_DSIZE_1)
            data[len ++] = (element->value.uint >>  0) & 0xff;
        else if ((element->type & SDP_DSIZE_MASK) == SDP_DSIZE_2) {
            data[len ++] = (element->value.uint >>  8) & 0xff;
            data[len ++] = (element->value.uint >>  0) & 0xff;
        } else if ((element->type & SDP_DSIZE_MASK) == SDP_DSIZE_4) {
            data[len ++] = (element->value.uint >>  24) & 0xff;
            data[len ++] = (element->value.uint >>  16) & 0xff;
            data[len ++] = (element->value.uint >>  8) & 0xff;
            data[len ++] = (element->value.uint >>  0) & 0xff;
        }

        return len;
    }

    if (type == SDP_DTYPE_UUID) {
        *(*uuid) ++ = element->value.uint;

        data[len ++] = element->type;
        data[len ++] = (element->value.uint >>  24) & 0xff;
        data[len ++] = (element->value.uint >>  16) & 0xff;
        data[len ++] = (element->value.uint >>  8) & 0xff;
        data[len ++] = (element->value.uint >>  0) & 0xff;
        memcpy(data + len, bt_base_uuid, 12);

        return len + 12;
    }

    data[0] = type | SDP_DSIZE_NEXT1;
    if (type == SDP_DTYPE_STRING || type == SDP_DTYPE_URL) {
        if (element->type & SDP_DSIZE_MASK)
            for (len = 0; element->value.str[len] |
                            element->value.str[len + 1]; len ++);
        else
            len = strlen(element->value.str);
        memcpy(data + 2, element->value.str, data[1] = len);

        return len + 2;
    }

    len = 2;
    element = element->value.list;
    while (element->type)
        len += sdp_attr_write(data + len, element ++, uuid);
    data[1] = len - 2;

    return len;
}

static int sdp_attributeid_compare(const struct sdp_service_attribute_s *a,
                const struct sdp_service_attribute_s *b)
{
    return (int) b->attribute_id - a->attribute_id;
}

static int sdp_uuid_compare(const int *a, const int *b)
{
    return *a - *b;
}

static void sdp_service_record_build(struct sdp_service_record_s *record,
                struct sdp_def_service_s *def, int handle)
{
    int len = 0;
    uint8_t *data;
    int *uuid;

    record->uuids = 0;
    while (def->attributes[record->attributes].data.type) {
        len += 3;
        len += sdp_attr_max_size(&def->attributes[record->attributes ++].data,
                        &record->uuids);
    }
    record->uuids = pow2ceil(record->uuids);
    record->attribute_list =
            g_malloc0(record->attributes * sizeof(*record->attribute_list));
    record->uuid =
            g_malloc0(record->uuids * sizeof(*record->uuid));
    data = g_malloc(len);

    record->attributes = 0;
    uuid = record->uuid;
    while (def->attributes[record->attributes].data.type) {
        record->attribute_list[record->attributes].pair = data;

        len = 0;
        data[len ++] = SDP_DTYPE_UINT | SDP_DSIZE_2;
        data[len ++] = def->attributes[record->attributes].id >> 8;
        data[len ++] = def->attributes[record->attributes].id & 0xff;
        len += sdp_attr_write(data + len,
                        &def->attributes[record->attributes].data, &uuid);

        /* Special case: assign a ServiceRecordHandle in sequence */
        if (def->attributes[record->attributes].id == SDP_ATTR_RECORD_HANDLE)
            def->attributes[record->attributes].data.value.uint = handle;
        /* Note: we could also assign a ServiceDescription based on
         * sdp->device.device->lmp_name.  */

        record->attribute_list[record->attributes ++].len = len;
        data += len;
    }

    /* Sort the attribute list by the AttributeID */
    qsort(record->attribute_list, record->attributes,
                    sizeof(*record->attribute_list),
                    (void *) sdp_attributeid_compare);
    /* Sort the searchable UUIDs list for bisection */
    qsort(record->uuid, record->uuids,
                    sizeof(*record->uuid),
                    (void *) sdp_uuid_compare);
}

static void sdp_service_db_build(struct bt_l2cap_sdp_state_s *sdp,
                struct sdp_def_service_s **service)
{
    sdp->services = 0;
    while (service[sdp->services])
        sdp->services ++;
    sdp->service_list =
            g_malloc0(sdp->services * sizeof(*sdp->service_list));

    sdp->services = 0;
    while (*service) {
        sdp_service_record_build(&sdp->service_list[sdp->services],
                        *service, sdp->services);
        service ++;
        sdp->services ++;
    }
}

#define LAST { .type = 0 }
#define SERVICE(name, attrs)				\
    static struct sdp_def_service_s glue(glue(sdp_service_, name), _s) = { \
        .attributes = { attrs { .data = LAST } },	\
    };
#define ATTRIBUTE(attrid, val)	{ .id = glue(SDP_ATTR_, attrid), .data = val },
#define UINT8(val)	{				\
        .type       = SDP_DTYPE_UINT | SDP_DSIZE_1,	\
        .value.uint = val,				\
    },
#define UINT16(val)	{				\
        .type       = SDP_DTYPE_UINT | SDP_DSIZE_2,	\
        .value.uint = val,				\
    },
#define UINT32(val)	{				\
        .type       = SDP_DTYPE_UINT | SDP_DSIZE_4,	\
        .value.uint = val,				\
    },
#define UUID128(val)	{				\
        .type       = SDP_DTYPE_UUID | SDP_DSIZE_16,	\
        .value.uint = val,				\
    },
#define SDP_TRUE	{				\
        .type       = SDP_DTYPE_BOOL | SDP_DSIZE_1,	\
        .value.uint = 1,				\
    },
#define SDP_FALSE	{				\
        .type       = SDP_DTYPE_BOOL | SDP_DSIZE_1,	\
        .value.uint = 0,				\
    },
#define STRING(val)	{				\
        .type       = SDP_DTYPE_STRING,			\
        .value.str  = val,				\
    },
#define ARRAY(...)	{				\
        .type       = SDP_DTYPE_STRING | SDP_DSIZE_2,	\
        .value.str  = (char []) { __VA_ARGS__, 0, 0 },	\
    },
#define URL(val)	{				\
        .type       = SDP_DTYPE_URL,			\
        .value.str  = val,				\
    },
#if 1
#define LIST(val)	{				\
        .type       = SDP_DTYPE_SEQ,			\
        .value.list = (struct sdp_def_data_element_s []) { val LAST }, \
    },
#endif

/* Try to keep each single attribute below MAX_PDU_OUT_SIZE bytes
 * in resulting SDP data representation size.  */

SERVICE(hid,
    ATTRIBUTE(RECORD_HANDLE,   UINT32(0))	/* Filled in later */
    ATTRIBUTE(SVCLASS_ID_LIST, LIST(UUID128(HID_SVCLASS_ID)))
    ATTRIBUTE(RECORD_STATE,    UINT32(1))
    ATTRIBUTE(PROTO_DESC_LIST, LIST(
        LIST(UUID128(L2CAP_UUID) UINT16(BT_PSM_HID_CTRL))
        LIST(UUID128(HIDP_UUID))
    ))
    ATTRIBUTE(BROWSE_GRP_LIST, LIST(UUID128(0x1002)))
    ATTRIBUTE(LANG_BASE_ATTR_ID_LIST, LIST(
        UINT16(0x656e) UINT16(0x006a) UINT16(0x0100)
    ))
    ATTRIBUTE(PFILE_DESC_LIST, LIST(
        LIST(UUID128(HID_PROFILE_ID) UINT16(0x0100))
    ))
    ATTRIBUTE(DOC_URL,         URL("http://bellard.org/qemu/user-doc.html"))
    ATTRIBUTE(SVCNAME_PRIMARY, STRING("QEMU Bluetooth HID"))
    ATTRIBUTE(SVCDESC_PRIMARY, STRING("QEMU Keyboard/Mouse"))
    ATTRIBUTE(SVCPROV_PRIMARY, STRING("QEMU"))

    /* Profile specific */
    ATTRIBUTE(DEVICE_RELEASE_NUMBER,	UINT16(0x0091)) /* Deprecated, remove */
    ATTRIBUTE(PARSER_VERSION,		UINT16(0x0111))
    /* TODO: extract from l2cap_device->device.class[0] */
    ATTRIBUTE(DEVICE_SUBCLASS,		UINT8(0x40))
    ATTRIBUTE(COUNTRY_CODE,		UINT8(0x15))
    ATTRIBUTE(VIRTUAL_CABLE,		SDP_TRUE)
    ATTRIBUTE(RECONNECT_INITIATE,	SDP_FALSE)
    /* TODO: extract from hid->usbdev->report_desc */
    ATTRIBUTE(DESCRIPTOR_LIST,		LIST(
        LIST(UINT8(0x22) ARRAY(
            0x05, 0x01,	/* Usage Page (Generic Desktop) */
            0x09, 0x06,	/* Usage (Keyboard) */
            0xa1, 0x01,	/* Collection (Application) */
            0x75, 0x01,	/*   Report Size (1) */
            0x95, 0x08,	/*   Report Count (8) */
            0x05, 0x07,	/*   Usage Page (Key Codes) */
            0x19, 0xe0,	/*   Usage Minimum (224) */
            0x29, 0xe7,	/*   Usage Maximum (231) */
            0x15, 0x00,	/*   Logical Minimum (0) */
            0x25, 0x01,	/*   Logical Maximum (1) */
            0x81, 0x02,	/*   Input (Data, Variable, Absolute) */
            0x95, 0x01,	/*   Report Count (1) */
            0x75, 0x08,	/*   Report Size (8) */
            0x81, 0x01,	/*   Input (Constant) */
            0x95, 0x05,	/*   Report Count (5) */
            0x75, 0x01,	/*   Report Size (1) */
            0x05, 0x08,	/*   Usage Page (LEDs) */
            0x19, 0x01,	/*   Usage Minimum (1) */
            0x29, 0x05,	/*   Usage Maximum (5) */
            0x91, 0x02,	/*   Output (Data, Variable, Absolute) */
            0x95, 0x01,	/*   Report Count (1) */
            0x75, 0x03,	/*   Report Size (3) */
            0x91, 0x01,	/*   Output (Constant) */
            0x95, 0x06,	/*   Report Count (6) */
            0x75, 0x08,	/*   Report Size (8) */
            0x15, 0x00,	/*   Logical Minimum (0) */
            0x25, 0xff,	/*   Logical Maximum (255) */
            0x05, 0x07,	/*   Usage Page (Key Codes) */
            0x19, 0x00,	/*   Usage Minimum (0) */
            0x29, 0xff,	/*   Usage Maximum (255) */
            0x81, 0x00,	/*   Input (Data, Array) */
            0xc0	/* End Collection */
    ))))
    ATTRIBUTE(LANG_ID_BASE_LIST,	LIST(
        LIST(UINT16(0x0409) UINT16(0x0100))
    ))
    ATTRIBUTE(SDP_DISABLE,		SDP_FALSE)
    ATTRIBUTE(BATTERY_POWER,		SDP_TRUE)
    ATTRIBUTE(REMOTE_WAKEUP,		SDP_TRUE)
    ATTRIBUTE(BOOT_DEVICE,		SDP_TRUE)	/* XXX: untested */
    ATTRIBUTE(SUPERVISION_TIMEOUT,	UINT16(0x0c80))
    ATTRIBUTE(NORMALLY_CONNECTABLE,	SDP_TRUE)
    ATTRIBUTE(PROFILE_VERSION,		UINT16(0x0100))
)

SERVICE(sdp,
    ATTRIBUTE(RECORD_HANDLE,   UINT32(0))	/* Filled in later */
    ATTRIBUTE(SVCLASS_ID_LIST, LIST(UUID128(SDP_SERVER_SVCLASS_ID)))
    ATTRIBUTE(RECORD_STATE,    UINT32(1))
    ATTRIBUTE(PROTO_DESC_LIST, LIST(
        LIST(UUID128(L2CAP_UUID) UINT16(BT_PSM_SDP))
        LIST(UUID128(SDP_UUID))
    ))
    ATTRIBUTE(BROWSE_GRP_LIST, LIST(UUID128(0x1002)))
    ATTRIBUTE(LANG_BASE_ATTR_ID_LIST, LIST(
        UINT16(0x656e) UINT16(0x006a) UINT16(0x0100)
    ))
    ATTRIBUTE(PFILE_DESC_LIST, LIST(
        LIST(UUID128(SDP_SERVER_PROFILE_ID) UINT16(0x0100))
    ))
    ATTRIBUTE(DOC_URL,         URL("http://bellard.org/qemu/user-doc.html"))
    ATTRIBUTE(SVCPROV_PRIMARY, STRING("QEMU"))

    /* Profile specific */
    ATTRIBUTE(VERSION_NUM_LIST, LIST(UINT16(0x0100)))
    ATTRIBUTE(SVCDB_STATE    , UINT32(1))
)

SERVICE(pnp,
    ATTRIBUTE(RECORD_HANDLE,   UINT32(0))	/* Filled in later */
    ATTRIBUTE(SVCLASS_ID_LIST, LIST(UUID128(PNP_INFO_SVCLASS_ID)))
    ATTRIBUTE(RECORD_STATE,    UINT32(1))
    ATTRIBUTE(PROTO_DESC_LIST, LIST(
        LIST(UUID128(L2CAP_UUID) UINT16(BT_PSM_SDP))
        LIST(UUID128(SDP_UUID))
    ))
    ATTRIBUTE(BROWSE_GRP_LIST, LIST(UUID128(0x1002)))
    ATTRIBUTE(LANG_BASE_ATTR_ID_LIST, LIST(
        UINT16(0x656e) UINT16(0x006a) UINT16(0x0100)
    ))
    ATTRIBUTE(PFILE_DESC_LIST, LIST(
        LIST(UUID128(PNP_INFO_PROFILE_ID) UINT16(0x0100))
    ))
    ATTRIBUTE(DOC_URL,         URL("http://bellard.org/qemu/user-doc.html"))
    ATTRIBUTE(SVCPROV_PRIMARY, STRING("QEMU"))

    /* Profile specific */
    ATTRIBUTE(SPECIFICATION_ID, UINT16(0x0100))
    ATTRIBUTE(VERSION,         UINT16(0x0100))
    ATTRIBUTE(PRIMARY_RECORD,  SDP_TRUE)
)

static int bt_l2cap_sdp_new_ch(struct bt_l2cap_device_s *dev,
                struct bt_l2cap_conn_params_s *params)
{
    struct bt_l2cap_sdp_state_s *sdp = g_malloc0(sizeof(*sdp));
    struct sdp_def_service_s *services[] = {
        &sdp_service_sdp_s,
        &sdp_service_hid_s,
        &sdp_service_pnp_s,
        NULL,
    };

    sdp->channel = params;
    sdp->channel->opaque = sdp;
    sdp->channel->close = bt_l2cap_sdp_close_ch;
    sdp->channel->sdu_in = bt_l2cap_sdp_sdu_in;

    sdp_service_db_build(sdp, services);

    return 0;
}

void bt_l2cap_sdp_init(struct bt_l2cap_device_s *dev)
{
    bt_l2cap_psm_register(dev, BT_PSM_SDP,
                    MAX_PDU_OUT_SIZE, bt_l2cap_sdp_new_ch);
}
