BTstack Bluetooth stack

Dependencies:   mbed USBHost

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers remote_device_db_memory.c Source File

remote_device_db_memory.c

00001 /*
00002  * Copyright (C) 2009-2012 by Matthias Ringwald
00003  *
00004  * Redistribution and use in source and binary forms, with or without
00005  * modification, are permitted provided that the following conditions
00006  * are met:
00007  *
00008  * 1. Redistributions of source code must retain the above copyright
00009  *    notice, this list of conditions and the following disclaimer.
00010  * 2. Redistributions in binary form must reproduce the above copyright
00011  *    notice, this list of conditions and the following disclaimer in the
00012  *    documentation and/or other materials provided with the distribution.
00013  * 3. Neither the name of the copyright holders nor the names of
00014  *    contributors may be used to endorse or promote products derived
00015  *    from this software without specific prior written permission.
00016  * 4. Any redistribution, use, or modification is done solely for
00017  *    personal benefit and not for any commercial purpose or for
00018  *    monetary gain.
00019  *
00020  * THIS SOFTWARE IS PROVIDED BY MATTHIAS RINGWALD AND CONTRIBUTORS
00021  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
00022  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
00023  * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL MATTHIAS
00024  * RINGWALD OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
00025  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
00026  * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
00027  * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
00028  * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
00029  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
00030  * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
00031  * SUCH DAMAGE.
00032  *
00033  * Please inquire about commercial licensing options at btstack@ringwald.ch
00034  *
00035  */
00036 
00037 #include <string.h>
00038 #include <stdlib.h>
00039 
00040 #include "remote_device_db.h"
00041 #include "btstack_memory.h"
00042 #include "debug.h"
00043 
00044 #include <btstack/utils.h>
00045 #include <btstack/linked_list.h>
00046 
00047 // This lists should be only accessed by tests.
00048 linked_list_t db_mem_link_keys = NULL;
00049 linked_list_t db_mem_names = NULL;
00050 static linked_list_t db_mem_services = NULL;
00051 
00052 // Device info
00053 static void db_open(void){
00054 }
00055 
00056 static void db_close(void){ 
00057 }
00058 
00059 static db_mem_device_t * get_item(linked_list_t list, bd_addr_t *bd_addr) {
00060     linked_item_t *it;
00061     for (it = (linked_item_t *) list; it ; it = it->next){
00062         db_mem_device_t * item = (db_mem_device_t *) it;
00063         if (BD_ADDR_CMP(item->bd_addr, *bd_addr) == 0) {
00064             return item;
00065         }
00066     }
00067     return NULL;
00068 }
00069 
00070 static int get_name(bd_addr_t *bd_addr, device_name_t *device_name) {
00071     db_mem_device_name_t * item = (db_mem_device_name_t *) get_item(db_mem_names, bd_addr);
00072     
00073     if (!item) return 0;
00074     
00075     strncpy((char*)device_name, item->device_name, MAX_NAME_LEN);
00076     
00077     linked_list_remove(&db_mem_names, (linked_item_t *) item);
00078     linked_list_add(&db_mem_names, (linked_item_t *) item);
00079     
00080     return 1;
00081 }
00082 
00083 static int get_link_key(bd_addr_t *bd_addr, link_key_t *link_key) {
00084     db_mem_device_link_key_t * item = (db_mem_device_link_key_t *) get_item(db_mem_link_keys, bd_addr);
00085     
00086     if (!item) return 0;
00087     
00088     memcpy(link_key, item->link_key, LINK_KEY_LEN);
00089     
00090     linked_list_remove(&db_mem_link_keys, (linked_item_t *) item);
00091     linked_list_add(&db_mem_link_keys, (linked_item_t *) item);
00092 
00093     return 1;
00094 }
00095 
00096 static void delete_link_key(bd_addr_t *bd_addr){
00097     db_mem_device_t * item = get_item(db_mem_link_keys, bd_addr);
00098     
00099     if (!item) return;
00100     
00101     linked_list_remove(&db_mem_link_keys, (linked_item_t *) item);
00102     btstack_memory_db_mem_device_link_key_free(item);
00103 }
00104 
00105 
00106 static void put_link_key(bd_addr_t *bd_addr, link_key_t *link_key){
00107     db_mem_device_link_key_t * existingRecord = (db_mem_device_link_key_t *) get_item(db_mem_link_keys, bd_addr);
00108     
00109     if (existingRecord){
00110         memcpy(existingRecord->link_key, link_key, LINK_KEY_LEN);
00111         return;
00112     }
00113     
00114     // Record not found, create new one for this device
00115     db_mem_device_link_key_t * newItem = (db_mem_device_link_key_t*) btstack_memory_db_mem_device_link_key_get();
00116     if (!newItem){
00117         newItem = (db_mem_device_link_key_t*)linked_list_get_last_item(&db_mem_link_keys);
00118     }
00119     
00120     if (!newItem) return;
00121     
00122     memcpy(newItem->device.bd_addr, bd_addr, sizeof(bd_addr_t));
00123     memcpy(newItem->link_key, link_key, LINK_KEY_LEN);
00124     linked_list_add(&db_mem_link_keys, (linked_item_t *) newItem);
00125 }
00126 
00127 static void delete_name(bd_addr_t *bd_addr){
00128     db_mem_device_t * item = get_item(db_mem_names, bd_addr);
00129     
00130     if (!item) return;
00131     
00132     linked_list_remove(&db_mem_names, (linked_item_t *) item);
00133     btstack_memory_db_mem_device_name_free(item);    
00134 }
00135 
00136 static void put_name(bd_addr_t *bd_addr, device_name_t *device_name){
00137     db_mem_device_name_t * existingRecord = (db_mem_device_name_t *) get_item(db_mem_names, bd_addr);
00138     
00139     if (existingRecord){
00140         strncpy(existingRecord->device_name, (const char*) device_name, MAX_NAME_LEN);
00141         return;
00142     }
00143     
00144     // Record not found, create a new one for this device
00145     db_mem_device_name_t * newItem = (db_mem_device_name_t *) btstack_memory_db_mem_device_name_get();
00146     if (!newItem) {
00147         newItem = (db_mem_device_name_t*)linked_list_get_last_item(&db_mem_names);
00148     };
00149 
00150     if (!newItem) return;
00151     
00152     memcpy(newItem->device.bd_addr, bd_addr, sizeof(bd_addr_t));
00153     strncpy(newItem->device_name, (const char*) device_name, MAX_NAME_LEN);
00154     linked_list_add(&db_mem_names, (linked_item_t *) newItem);
00155 }
00156 
00157 
00158 // MARK: PERSISTENT RFCOMM CHANNEL ALLOCATION
00159 
00160 static uint8_t persistent_rfcomm_channel(char *serviceName){
00161     linked_item_t *it;
00162     db_mem_service_t * item;
00163     uint8_t max_channel = 1;
00164 
00165     for (it = (linked_item_t *) db_mem_services; it ; it = it->next){
00166         item = (db_mem_service_t *) it;
00167         if (strncmp(item->service_name, serviceName, MAX_NAME_LEN) == 0) {
00168             // Match found
00169             return item->channel;
00170         }
00171 
00172         // TODO prevent overflow
00173         if (item->channel >= max_channel) max_channel = item->channel + 1;
00174     }
00175 
00176     // Allocate new persistant channel
00177     db_mem_service_t * newItem = (db_mem_service_t *) btstack_memory_db_mem_service_get();
00178 
00179     if (!newItem) return 0;
00180     
00181     strncpy(newItem->service_name, serviceName, MAX_NAME_LEN);
00182     newItem->channel = max_channel;
00183     linked_list_add(&db_mem_services, (linked_item_t *) newItem);
00184     return max_channel;
00185 }
00186 
00187 
00188 const remote_device_db_t remote_device_db_memory = {
00189     db_open,
00190     db_close,
00191     get_link_key,
00192     put_link_key,
00193     delete_link_key,
00194     get_name,
00195     put_name,
00196     delete_name,
00197     persistent_rfcomm_channel
00198 };