1124758Semax/* 2124758Semax * provider.c 3124758Semax * 4124758Semax * Copyright (c) 2004 Maksim Yevmenkin <m_evmenkin@yahoo.com> 5124758Semax * All rights reserved. 6124758Semax * 7124758Semax * Redistribution and use in source and binary forms, with or without 8124758Semax * modification, are permitted provided that the following conditions 9124758Semax * are met: 10124758Semax * 1. Redistributions of source code must retain the above copyright 11124758Semax * notice, this list of conditions and the following disclaimer. 12124758Semax * 2. Redistributions in binary form must reproduce the above copyright 13124758Semax * notice, this list of conditions and the following disclaimer in the 14124758Semax * documentation and/or other materials provided with the distribution. 15124758Semax * 16124758Semax * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 17124758Semax * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 18124758Semax * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 19124758Semax * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 20124758Semax * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 21124758Semax * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 22124758Semax * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 23124758Semax * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 24124758Semax * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 25124758Semax * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 26124758Semax * SUCH DAMAGE. 27124758Semax * 28124758Semax * $Id: provider.c,v 1.5 2004/01/13 01:54:39 max Exp $ 29124758Semax * $FreeBSD$ 30124758Semax */ 31124758Semax 32124758Semax#include <sys/queue.h> 33124758Semax#include <bluetooth.h> 34124758Semax#include <string.h> 35124758Semax#include <stdlib.h> 36124758Semax#include "profile.h" 37124758Semax#include "provider.h" 38124758Semax 39124758Semaxstatic TAILQ_HEAD(, provider) providers = TAILQ_HEAD_INITIALIZER(providers); 40124758Semaxstatic uint32_t change_state = 0; 41124758Semaxstatic uint32_t handle = 0; 42124758Semax 43124758Semax/* 44124758Semax * Register Service Discovery provider. 45124758Semax * Should not be called more the once. 46124758Semax */ 47124758Semax 48124758Semaxint32_t 49124758Semaxprovider_register_sd(int32_t fd) 50124758Semax{ 51124758Semax extern profile_t sd_profile_descriptor; 52124758Semax extern profile_t bgd_profile_descriptor; 53124758Semax 54124758Semax provider_p sd = calloc(1, sizeof(*sd)); 55124758Semax provider_p bgd = calloc(1, sizeof(*bgd)); 56124758Semax 57124758Semax if (sd == NULL || bgd == NULL) { 58124758Semax if (sd != NULL) 59124758Semax free(sd); 60124758Semax 61124758Semax if (bgd != NULL) 62124758Semax free(bgd); 63124758Semax 64124758Semax return (-1); 65124758Semax } 66124758Semax 67124758Semax sd->profile = &sd_profile_descriptor; 68124758Semax bgd->handle = 0; 69124758Semax sd->fd = fd; 70124758Semax TAILQ_INSERT_HEAD(&providers, sd, provider_next); 71124758Semax 72124758Semax bgd->profile = &bgd_profile_descriptor; 73124758Semax bgd->handle = 1; 74124758Semax sd->fd = fd; 75124758Semax TAILQ_INSERT_AFTER(&providers, sd, bgd, provider_next); 76124758Semax 77124758Semax change_state ++; 78124758Semax 79124758Semax return (0); 80124758Semax} 81124758Semax 82124758Semax/* 83124758Semax * Register new provider for a given profile, bdaddr and session. 84124758Semax */ 85124758Semax 86124758Semaxprovider_p 87124758Semaxprovider_register(profile_p const profile, bdaddr_p const bdaddr, int32_t fd, 88124758Semax uint8_t const *data, uint32_t datalen) 89124758Semax{ 90124758Semax provider_p provider = calloc(1, sizeof(*provider)); 91124758Semax 92124758Semax if (provider != NULL) { 93124758Semax provider->data = malloc(datalen); 94124758Semax if (provider->data != NULL) { 95124758Semax provider->profile = profile; 96124758Semax memcpy(provider->data, data, datalen); 97124758Semax 98124758Semax /* 99124758Semax * Record handles 0x0 and 0x1 are reserved 100124758Semax * for SDP itself 101124758Semax */ 102124758Semax 103124758Semax if (++ handle <= 1) 104124758Semax handle = 2; 105124758Semax 106124758Semax provider->handle = handle; 107124758Semax 108124758Semax memcpy(&provider->bdaddr, bdaddr, 109124758Semax sizeof(provider->bdaddr)); 110124758Semax provider->fd = fd; 111124758Semax 112124758Semax TAILQ_INSERT_TAIL(&providers, provider, provider_next); 113124758Semax change_state ++; 114124758Semax } else { 115124758Semax free(provider); 116124758Semax provider = NULL; 117124758Semax } 118124758Semax } 119124758Semax 120124758Semax return (provider); 121124758Semax} 122124758Semax 123124758Semax/* 124124758Semax * Unregister provider 125124758Semax */ 126124758Semax 127124758Semaxvoid 128124758Semaxprovider_unregister(provider_p provider) 129124758Semax{ 130124758Semax TAILQ_REMOVE(&providers, provider, provider_next); 131124758Semax if (provider->data != NULL) 132124758Semax free(provider->data); 133124758Semax free(provider); 134124758Semax change_state ++; 135124758Semax} 136124758Semax 137124758Semax/* 138124758Semax * Update provider data 139124758Semax */ 140124758Semax 141124758Semaxint32_t 142124758Semaxprovider_update(provider_p provider, uint8_t const *data, uint32_t datalen) 143124758Semax{ 144124758Semax uint8_t *new_data = (uint8_t *) realloc(provider->data, datalen); 145124758Semax 146124758Semax if (new_data == NULL) 147124758Semax return (-1); 148124758Semax 149124758Semax memcpy(new_data, data, datalen); 150124758Semax provider->data = new_data; 151124758Semax 152124758Semax return (0); 153124758Semax} 154124758Semax 155124758Semax/* 156124758Semax * Get a provider for given record handle 157124758Semax */ 158124758Semax 159124758Semaxprovider_p 160124758Semaxprovider_by_handle(uint32_t handle) 161124758Semax{ 162124758Semax provider_p provider = NULL; 163124758Semax 164124758Semax TAILQ_FOREACH(provider, &providers, provider_next) 165124758Semax if (provider->handle == handle) 166124758Semax break; 167124758Semax 168124758Semax return (provider); 169124758Semax} 170124758Semax 171124758Semax/* 172124758Semax * Cursor access 173124758Semax */ 174124758Semax 175124758Semaxprovider_p 176124758Semaxprovider_get_first(void) 177124758Semax{ 178124758Semax return (TAILQ_FIRST(&providers)); 179124758Semax} 180124758Semax 181124758Semaxprovider_p 182124758Semaxprovider_get_next(provider_p provider) 183124758Semax{ 184124758Semax return (TAILQ_NEXT(provider, provider_next)); 185124758Semax} 186124758Semax 187124758Semax/* 188124758Semax * Return change state 189124758Semax */ 190124758Semax 191124758Semaxuint32_t 192124758Semaxprovider_get_change_state(void) 193124758Semax{ 194124758Semax return (change_state); 195124758Semax} 196124758Semax 197