Path: blob/main/usr.sbin/bluetooth/sdpd/provider.c
103499 views
/*-1* provider.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: provider.c,v 1.5 2004/01/13 01:54:39 max Exp $30*/3132#include <sys/queue.h>33#define L2CAP_SOCKET_CHECKED34#include <bluetooth.h>35#include <string.h>36#include <stdlib.h>37#include "profile.h"38#include "provider.h"3940static TAILQ_HEAD(, provider) providers = TAILQ_HEAD_INITIALIZER(providers);41static uint32_t change_state = 0;42static uint32_t handle = 0;4344/*45* Register Service Discovery provider.46* Should not be called more the once.47*/4849int32_t50provider_register_sd(int32_t fd)51{52extern profile_t sd_profile_descriptor;53extern profile_t bgd_profile_descriptor;5455provider_p sd = calloc(1, sizeof(*sd));56provider_p bgd = calloc(1, sizeof(*bgd));5758if (sd == NULL || bgd == NULL) {59if (sd != NULL)60free(sd);6162if (bgd != NULL)63free(bgd);6465return (-1);66}6768sd->profile = &sd_profile_descriptor;69bgd->handle = 0;70sd->fd = fd;71TAILQ_INSERT_HEAD(&providers, sd, provider_next);7273bgd->profile = &bgd_profile_descriptor;74bgd->handle = 1;75sd->fd = fd;76TAILQ_INSERT_AFTER(&providers, sd, bgd, provider_next);7778change_state ++;7980return (0);81}8283/*84* Register new provider for a given profile, bdaddr and session.85*/8687provider_p88provider_register(profile_p const profile, bdaddr_p const bdaddr, int32_t fd,89uint8_t const *data, uint32_t datalen)90{91provider_p provider = calloc(1, sizeof(*provider));9293if (provider != NULL) {94provider->data = malloc(datalen);95if (provider->data != NULL) {96provider->profile = profile;97memcpy(provider->data, data, datalen);9899/*100* Record handles 0x0 and 0x1 are reserved101* for SDP itself102*/103104if (++ handle <= 1)105handle = 2;106107provider->handle = handle;108109memcpy(&provider->bdaddr, bdaddr,110sizeof(provider->bdaddr));111provider->fd = fd;112113TAILQ_INSERT_TAIL(&providers, provider, provider_next);114change_state ++;115} else {116free(provider);117provider = NULL;118}119}120121return (provider);122}123124/*125* Unregister provider126*/127128void129provider_unregister(provider_p provider)130{131TAILQ_REMOVE(&providers, provider, provider_next);132if (provider->data != NULL)133free(provider->data);134free(provider);135change_state ++;136}137138/*139* Update provider data140*/141142int32_t143provider_update(provider_p provider, uint8_t const *data, uint32_t datalen)144{145uint8_t *new_data = (uint8_t *) realloc(provider->data, datalen);146147if (new_data == NULL)148return (-1);149150memcpy(new_data, data, datalen);151provider->data = new_data;152153return (0);154}155156/*157* Get a provider for given record handle158*/159160provider_p161provider_by_handle(uint32_t handle)162{163provider_p provider = NULL;164165TAILQ_FOREACH(provider, &providers, provider_next)166if (provider->handle == handle)167break;168169return (provider);170}171172/*173* Cursor access174*/175176provider_p177provider_get_first(void)178{179return (TAILQ_FIRST(&providers));180}181182provider_p183provider_get_next(provider_p provider)184{185return (TAILQ_NEXT(provider, provider_next));186}187188/*189* Return change state190*/191192uint32_t193provider_get_change_state(void)194{195return (change_state);196}197198199200