/*-1* srr.c2*3* SPDX-License-Identifier: BSD-2-Clause4*5* Copyright (c) 2004 Maksim Yevmenkin <[email protected]>6* 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 AND CONTRIBUTORS ``AS IS'' AND18* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE19* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE20* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE21* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL22* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS23* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)24* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT25* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY26* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF27* SUCH DAMAGE.28*29* $Id: srr.c,v 1.1 2004/01/13 01:54:39 max Exp $30*/3132#include <sys/param.h>33#include <sys/queue.h>34#include <sys/uio.h>35#include <netinet/in.h>36#include <arpa/inet.h>37#include <assert.h>38#define L2CAP_SOCKET_CHECKED39#include <bluetooth.h>40#include <errno.h>41#include <sdp.h>42#include <string.h>43#include "profile.h"44#include "provider.h"45#include "server.h"4647/*48* Prepare Service Register response49*/5051int32_t52server_prepare_service_register_response(server_p srv, int32_t fd)53{54uint8_t const *req = srv->req + sizeof(sdp_pdu_t);55uint8_t const *req_end = req + ((sdp_pdu_p)(srv->req))->len;56uint8_t *rsp = srv->fdidx[fd].rsp;5758profile_t *profile = NULL;59provider_t *provider = NULL;60bdaddr_t *bdaddr = NULL;61int32_t uuid;6263/*64* Minimal Service Register Request65*66* value16 - uuid 2 bytes67* bdaddr - BD_ADDR 6 bytes68*/6970if (!srv->fdidx[fd].control ||71!srv->fdidx[fd].priv || req_end - req < 8)72return (SDP_ERROR_CODE_INVALID_REQUEST_SYNTAX);7374/* Get ServiceClass UUID */75SDP_GET16(uuid, req);7677/* Get BD_ADDR */78bdaddr = (bdaddr_p) req;79req += sizeof(*bdaddr);8081/* Lookup profile descriptror */82profile = profile_get_descriptor(uuid);83if (profile == NULL)84return (SDP_ERROR_CODE_INVALID_REQUEST_SYNTAX);8586/* Validate user data */87if (req_end - req < profile->dsize ||88profile->valid == NULL ||89(profile->valid)(req, req_end - req) == 0)90return (SDP_ERROR_CODE_INVALID_REQUEST_SYNTAX);9192/* Register provider */93provider = provider_register(profile, bdaddr, fd, req, req_end - req);94if (provider == NULL)95return (SDP_ERROR_CODE_INSUFFICIENT_RESOURCES);9697SDP_PUT16(0, rsp);98SDP_PUT32(provider->handle, rsp);99100/* Set reply size */101srv->fdidx[fd].rsp_limit = srv->fdidx[fd].omtu - sizeof(sdp_pdu_t);102srv->fdidx[fd].rsp_size = rsp - srv->fdidx[fd].rsp;103srv->fdidx[fd].rsp_cs = 0;104105return (0);106}107108/*109* Send Service Register Response110*/111112int32_t113server_send_service_register_response(server_p srv, int32_t fd)114{115struct iovec iov[2];116sdp_pdu_t pdu;117int32_t size;118119assert(srv->fdidx[fd].rsp_size < srv->fdidx[fd].rsp_limit);120121pdu.pid = SDP_PDU_ERROR_RESPONSE;122pdu.tid = ((sdp_pdu_p)(srv->req))->tid;123pdu.len = htons(srv->fdidx[fd].rsp_size);124125iov[0].iov_base = &pdu;126iov[0].iov_len = sizeof(pdu);127128iov[1].iov_base = srv->fdidx[fd].rsp;129iov[1].iov_len = srv->fdidx[fd].rsp_size;130131do {132size = writev(fd, (struct iovec const *) &iov, nitems(iov));133} while (size < 0 && errno == EINTR);134135srv->fdidx[fd].rsp_cs = 0;136srv->fdidx[fd].rsp_size = 0;137srv->fdidx[fd].rsp_limit = 0;138139return ((size < 0)? errno : 0);140}141142143144