Kenji Arai / mbed-os_TYBLE16

Dependents:   TYBLE16_simple_data_logger TYBLE16_MP3_Air

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers KVMap.cpp Source File

KVMap.cpp

00001 /*
00002  * Copyright (c) 2018 ARM Limited. All rights reserved.
00003  * SPDX-License-Identifier: Apache-2.0
00004  * Licensed under the Apache License, Version 2.0 (the License); you may
00005  * not use this file except in compliance with the License.
00006  * You may obtain a copy of the License at
00007  *
00008  * http://www.apache.org/licenses/LICENSE-2.0
00009  *
00010  * Unless required by applicable law or agreed to in writing, software
00011  * distributed under the License is distributed on an AS IS BASIS, WITHOUT
00012  * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
00013  * See the License for the specific language governing permissions and
00014  * limitations under the License.
00015  */
00016 
00017 #include "features/storage/kvstore/include/KVStore.h"
00018 #include "features/storage/kvstore/kv_map/KVMap.h"
00019 #include "features/storage/kvstore/conf/kv_config.h"
00020 #include <stdlib.h>
00021 #include "string.h"
00022 #include "mbed_error.h"
00023 
00024 namespace mbed {
00025 
00026 KVMap::~KVMap()
00027 {
00028     deinit();
00029 }
00030 
00031 int KVMap::init()
00032 {
00033     int ret = MBED_SUCCESS;
00034 
00035     _mutex->lock();
00036 
00037     if (_is_initialized) {
00038         goto exit;
00039     }
00040 
00041     _kv_num_attached_kvs = 0;
00042     memset(&_kv_map_table, 0, sizeof(_kv_map_table));
00043 
00044     _is_initialized = 1;
00045 
00046 exit:
00047     _mutex->unlock();
00048     return ret;
00049 }
00050 
00051 int KVMap::attach(const char *partition_name, kvstore_config_t *kv_config)
00052 {
00053     int ret = MBED_SUCCESS;
00054     char *kv_partition_name = NULL;
00055 
00056     _mutex->lock();
00057 
00058     if (!_is_initialized) {
00059         ret = MBED_ERROR_NOT_READY;
00060         goto exit;
00061     }
00062 
00063     if (_kv_num_attached_kvs >= MAX_ATTACHED_KVS) {
00064         ret =  MBED_ERROR_OUT_OF_MEMORY;
00065         goto exit;
00066     }
00067 
00068     kv_partition_name = new char[strlen(partition_name) + 1];
00069     strcpy(kv_partition_name, partition_name);
00070     _kv_map_table[_kv_num_attached_kvs].partition_name = kv_partition_name;
00071     _kv_map_table[_kv_num_attached_kvs].kv_config = kv_config;
00072     _kv_num_attached_kvs++;
00073 
00074 exit:
00075     _mutex->unlock();
00076     return ret;
00077 }
00078 
00079 void KVMap::deinit_partition(kv_map_entry_t *partition)
00080 {
00081     if (partition->kv_config == NULL) {
00082         return;
00083     }
00084 
00085     if (partition->kv_config->external_store != NULL) {
00086         partition->kv_config->external_store->deinit();
00087     }
00088 
00089     // TODO: this should be removed after FS APIs are standardized
00090     if (partition->kv_config->external_fs != NULL) {
00091         partition->kv_config->external_fs->unmount();
00092     }
00093 
00094     if (partition->kv_config->internal_store != NULL) {
00095         partition->kv_config->internal_store->deinit();
00096     }
00097 
00098     if (partition->kv_config->kvstore_main_instance != NULL) {
00099         partition->kv_config->kvstore_main_instance->deinit();
00100     }
00101 
00102     delete [] partition->partition_name;
00103     partition->partition_name = NULL;
00104     partition->kv_config = NULL;
00105 }
00106 
00107 
00108 int KVMap::detach(const char *partition_name)
00109 {
00110     int ret = MBED_SUCCESS;
00111 
00112     _mutex->lock();
00113 
00114     if (!_is_initialized) {
00115         ret = MBED_ERROR_NOT_READY;
00116         goto exit;
00117     }
00118 
00119     ret = MBED_ERROR_ITEM_NOT_FOUND;
00120     for (int i = 0; i < _kv_num_attached_kvs; i++) {
00121 
00122         if (strcmp(partition_name, _kv_map_table[i].partition_name) != 0) {
00123             continue;
00124         }
00125 
00126         deinit_partition(&_kv_map_table[i]);
00127 
00128         memcpy(&_kv_map_table[i], &_kv_map_table[i + 1], sizeof(kv_map_entry_t) * (MAX_ATTACHED_KVS - i - 1));
00129         _kv_map_table[MAX_ATTACHED_KVS - 1].partition_name = NULL;
00130         _kv_map_table[MAX_ATTACHED_KVS - 1].kv_config->kvstore_main_instance = NULL;
00131         _kv_num_attached_kvs--;
00132         ret = MBED_SUCCESS;
00133         break;
00134     }
00135 
00136 exit:
00137     _mutex->unlock();
00138     return ret;
00139 }
00140 
00141 int KVMap::deinit()
00142 {
00143     int ret = MBED_SUCCESS;
00144 
00145     _mutex->lock();
00146 
00147     if (!_is_initialized) {
00148         ret = MBED_ERROR_NOT_READY;
00149         goto exit;
00150     }
00151 
00152     for (int i = 0; i < _kv_num_attached_kvs; i++) {
00153 
00154         if (_kv_map_table[i].kv_config->kvstore_main_instance == NULL) {
00155             goto exit;
00156         }
00157 
00158         deinit_partition(&_kv_map_table[i]);
00159     }
00160 
00161 exit:
00162     _kv_num_attached_kvs = 0;
00163     _mutex->unlock();
00164     return ret;
00165 }
00166 
00167 // Full name lookup and then break it into KVStore instance and key
00168 int KVMap::lookup(const char *full_name, KVStore **kv_instance, size_t *key_index, uint32_t *flags_mask)
00169 {
00170     _mutex->lock();
00171 
00172     kvstore_config_t *kv_config;
00173     int ret = config_lookup(full_name, &kv_config, key_index);
00174     if (ret != MBED_SUCCESS) {
00175         goto exit;
00176     }
00177 
00178     *kv_instance = kv_config->kvstore_main_instance;
00179     if (flags_mask != NULL) {
00180         *flags_mask = kv_config->flags_mask;
00181     }
00182 
00183 exit:
00184     _mutex->unlock();
00185     return ret;
00186 }
00187 
00188 // Full name lookup and then break it into KVStore configuration struct and key
00189 int KVMap::config_lookup(const char *full_name, kvstore_config_t **kv_config, size_t *key_index)
00190 {
00191     int ret = MBED_SUCCESS;
00192     int delimiter_index;
00193     int i;
00194     const char *delimiter_position;
00195 
00196     const char *temp_str = full_name;
00197 
00198     if (!_is_initialized) {
00199         ret = MBED_ERROR_NOT_READY;
00200         goto exit;
00201     }
00202 
00203     if (temp_str != NULL) {
00204         *key_index = 0;
00205         if (*temp_str == '/') {
00206             temp_str++;
00207             (*key_index)++;
00208         }
00209 
00210         delimiter_position = strchr(temp_str, '/');
00211         if (delimiter_position == NULL) {  //delimiter not found
00212             delimiter_index = -1;
00213             *kv_config = _kv_map_table[0].kv_config;
00214             goto exit;
00215         }
00216     } else {
00217         delimiter_index = -1;
00218         *kv_config = _kv_map_table[0].kv_config;
00219         goto exit;
00220     }
00221 
00222 
00223     delimiter_index = delimiter_position - temp_str;
00224     for (i = 0; i < _kv_num_attached_kvs; i++) {
00225 
00226         if (strncmp(temp_str, _kv_map_table[i].partition_name, delimiter_index) != 0) {
00227             continue;
00228         }
00229 
00230         *kv_config = _kv_map_table[i].kv_config;
00231         break;
00232     }
00233     if (i == _kv_num_attached_kvs) {
00234         ret = MBED_ERROR_ITEM_NOT_FOUND;
00235         goto exit;
00236     }
00237 exit:
00238     if (ret == MBED_SUCCESS) {
00239         //if success extract the key
00240         *key_index = *key_index + delimiter_index + 1;
00241     }
00242     return ret;
00243 }
00244 
00245 KVStore *KVMap::get_internal_kv_instance(const char *name)
00246 {
00247 
00248     _mutex->lock();
00249 
00250     kvstore_config_t *kv_config;
00251     size_t key_index = 0;
00252 
00253     int ret = config_lookup(name, &kv_config, &key_index);
00254 
00255     _mutex->unlock();
00256 
00257     return ret != MBED_SUCCESS ? NULL : kv_config->internal_store;
00258 }
00259 
00260 KVStore *KVMap::get_external_kv_instance(const char *name)
00261 {
00262 
00263     _mutex->lock();
00264 
00265     kvstore_config_t *kv_config;
00266     size_t key_index = 0;
00267 
00268     int ret = config_lookup(name, &kv_config, &key_index);
00269 
00270     _mutex->unlock();
00271 
00272     return ret != MBED_SUCCESS ? NULL : kv_config->external_store;
00273 }
00274 
00275 KVStore *KVMap::get_main_kv_instance(const char *name)
00276 {
00277 
00278     _mutex->lock();
00279 
00280     kvstore_config_t *kv_config;
00281     size_t key_index = 0;
00282 
00283     int ret = config_lookup(name, &kv_config, &key_index);
00284 
00285     _mutex->unlock();
00286 
00287     return ret != MBED_SUCCESS ? NULL : kv_config->kvstore_main_instance;
00288 }
00289 
00290 BlockDevice *KVMap::get_internal_blockdevice_instance(const char *name)
00291 {
00292 
00293     _mutex->lock();
00294 
00295     kvstore_config_t *kv_config;
00296     size_t key_index = 0;
00297 
00298     int ret = config_lookup(name, &kv_config, &key_index);
00299 
00300     _mutex->unlock();
00301 
00302     return ret != MBED_SUCCESS ? NULL : kv_config->internal_bd;
00303 }
00304 
00305 BlockDevice *KVMap::get_external_blockdevice_instance(const char *name)
00306 {
00307 
00308     _mutex->lock();
00309 
00310     kvstore_config_t *kv_config;
00311     size_t key_index = 0;
00312 
00313     int ret = config_lookup(name, &kv_config, &key_index);
00314 
00315     _mutex->unlock();
00316 
00317     return ret != MBED_SUCCESS ? NULL : kv_config->external_bd;
00318 }
00319 
00320 FileSystem *KVMap::get_external_filesystem_instance(const char *name)
00321 {
00322 
00323     _mutex->lock();
00324 
00325     kvstore_config_t *kv_config;
00326     size_t key_index = 0;
00327 
00328     int ret = config_lookup(name, &kv_config, &key_index);
00329 
00330     _mutex->unlock();
00331 
00332     return ret != MBED_SUCCESS ? NULL : kv_config->external_fs;
00333 }
00334 
00335 } // namespace mbed
00336