property_cache.c 5.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256
  1. /*
  2. * Copyright (c) 2017 Actions Semiconductor Co., Ltd
  3. *
  4. * SPDX-License-Identifier: Apache-2.0
  5. */
  6. /**
  7. * @file property cache interface
  8. */
  9. #include <os_common_api.h>
  10. #include <string.h>
  11. #include <stdint.h>
  12. #include <errno.h>
  13. #include <stdlib.h>
  14. #include <mem_manager.h>
  15. #include <property_inner.h>
  16. #define SYS_LOG_DOMAIN "property"
  17. #ifndef SYS_LOG_LEVEL
  18. #define SYS_LOG_LEVEL CONFIG_SYS_LOG_DEFAULT_LEVEL
  19. #endif
  20. #define MAX_NVRAM_ITEM_CACHE_NUM 15
  21. struct cahce_item_data {
  22. char *name;
  23. char *data;
  24. uint32_t data_len:16;
  25. uint32_t used_flag:2;
  26. uint32_t flush_req:1;
  27. };
  28. OS_MUTEX_DEFINE(nvram_cache_mutex);
  29. static struct cahce_item_data globle_property_cache[MAX_NVRAM_ITEM_CACHE_NUM];
  30. static struct cahce_item_data *find_property_cache(const char *name)
  31. {
  32. int i;
  33. struct cahce_item_data *item = NULL;
  34. for (i = 0; i < MAX_NVRAM_ITEM_CACHE_NUM; i++) {
  35. item = &globle_property_cache[i];
  36. if (item->used_flag && !memcmp(item->name, name, strlen(name))) {
  37. SYS_LOG_INF(" %d %s\n", i, item->name);
  38. return item;
  39. }
  40. }
  41. return NULL;
  42. }
  43. static struct cahce_item_data *get_property_cache(const char *name, int len)
  44. {
  45. int i;
  46. struct cahce_item_data *item = NULL;
  47. for (i = 0; i < MAX_NVRAM_ITEM_CACHE_NUM; i++) {
  48. item = &globle_property_cache[i];
  49. if (!item->used_flag) {
  50. item->name = mem_malloc(strlen(name) + 1);
  51. if (!item->name) {
  52. item = NULL;
  53. goto exit;
  54. }
  55. memset(item->name, 0, strlen(name) + 1);
  56. if (len > 0) {
  57. item->data = mem_malloc(len);
  58. if (!item->data) {
  59. mem_free(item->name);
  60. item = NULL;
  61. goto exit;
  62. }
  63. memset(item->data, 0, len);
  64. }
  65. exit:
  66. return item;
  67. }
  68. }
  69. return NULL;
  70. }
  71. static int put_property_cache(struct cahce_item_data *item)
  72. {
  73. if (item) {
  74. if (item->data) {
  75. mem_free(item->data);
  76. }
  77. if (item->name) {
  78. mem_free(item->name);
  79. }
  80. item->data = NULL;
  81. item->name = NULL;
  82. item->used_flag = 0;
  83. item->data_len = 0;
  84. item->flush_req = 0;
  85. }
  86. return 0;
  87. }
  88. int property_cache_get(const char *name, void *data, int len)
  89. {
  90. int read_len = 0;
  91. struct cahce_item_data *item = NULL;
  92. os_mutex_lock(&nvram_cache_mutex, OS_FOREVER);
  93. item = find_property_cache(name);
  94. /**read from nvram cache */
  95. if (item) {
  96. if (item->data_len > len) {
  97. read_len = len;
  98. } else {
  99. read_len = item->data_len;
  100. }
  101. memcpy(data, item->data, read_len);
  102. } else {
  103. #ifdef CONFIG_NVRAM_CONFIG
  104. /** read from nvram*/
  105. read_len = nvram_config_get(name, data, len);
  106. #endif
  107. }
  108. os_mutex_unlock(&nvram_cache_mutex);
  109. return read_len;
  110. }
  111. int property_cache_set(const char *name, const void *data, int len)
  112. {
  113. int ret = 0;
  114. struct cahce_item_data *item = NULL;
  115. os_mutex_lock(&nvram_cache_mutex, OS_FOREVER);
  116. item = find_property_cache(name);
  117. /**write to old nvram cache */
  118. if (item) {
  119. if (item->data_len == len) {
  120. memcpy(item->data, data, len);
  121. ret = 0;
  122. } else {
  123. void *old_data = item->data;
  124. if (len > 0) {
  125. item->data = mem_malloc(len);
  126. memcpy(item->data, data, len);
  127. }
  128. item->data_len = len;
  129. ret = 0;
  130. mem_free(old_data);
  131. }
  132. goto exit;
  133. }
  134. /**write to new nvram cache */
  135. item = get_property_cache(name, len);
  136. if (item) {
  137. /** new item */
  138. memcpy(item->name, name, strlen(name));
  139. memcpy(item->data, data, len);
  140. item->data_len = len;
  141. item->used_flag = 1;
  142. ret = 0;
  143. goto exit;
  144. }
  145. /** direct write to nvram*/
  146. SYS_LOG_INF("direct write to nvram\n");
  147. #ifdef CONFIG_NVRAM_CONFIG
  148. ret = nvram_config_set(name, data, len);
  149. #endif
  150. exit:
  151. os_mutex_unlock(&nvram_cache_mutex);
  152. return ret;
  153. }
  154. int property_cache_flush(const char *name)
  155. {
  156. int i;
  157. struct cahce_item_data *item = NULL;
  158. os_mutex_lock(&nvram_cache_mutex, OS_FOREVER);
  159. for (i = 0; i < MAX_NVRAM_ITEM_CACHE_NUM; i++) {
  160. item = &globle_property_cache[i];
  161. if (item->used_flag &&
  162. ((!name) || memcmp(item->name, name, strlen(name)) == 0)) {
  163. #ifdef CONFIG_NVRAM_CONFIG
  164. if (!nvram_config_set(item->name, item->data, item->data_len)) {
  165. put_property_cache(item);
  166. item->flush_req = false;
  167. }
  168. #endif
  169. }
  170. }
  171. os_mutex_unlock(&nvram_cache_mutex);
  172. SYS_LOG_INF("ok\n");
  173. return 0;
  174. }
  175. int property_cache_flush_req(const char *name)
  176. {
  177. int i;
  178. struct cahce_item_data *item = NULL;
  179. os_mutex_lock(&nvram_cache_mutex, OS_FOREVER);
  180. for (i = 0; i < MAX_NVRAM_ITEM_CACHE_NUM; i++) {
  181. item = &globle_property_cache[i];
  182. if (item->used_flag &&
  183. ((!name) || memcmp(item->name, name, strlen(name)) == 0)) {
  184. item->flush_req = true;
  185. }
  186. }
  187. os_mutex_unlock(&nvram_cache_mutex);
  188. SYS_LOG_INF("ok\n");
  189. return 0;
  190. }
  191. int property_cache_flush_req_deal(void)
  192. {
  193. int i;
  194. struct cahce_item_data *item = NULL;
  195. os_mutex_lock(&nvram_cache_mutex, OS_FOREVER);
  196. for (i = 0; i < MAX_NVRAM_ITEM_CACHE_NUM; i++) {
  197. item = &globle_property_cache[i];
  198. if (item->used_flag && item->flush_req) {
  199. #ifdef CONFIG_NVRAM_CONFIG
  200. if (!nvram_config_set(item->name, item->data, item->data_len)) {
  201. put_property_cache(item);
  202. }
  203. #endif
  204. item->flush_req = false;
  205. }
  206. }
  207. os_mutex_unlock(&nvram_cache_mutex);
  208. SYS_LOG_INF("flush ok\n");
  209. return 0;
  210. }
  211. int property_cache_init(void)
  212. {
  213. memset(globle_property_cache, 0, sizeof(globle_property_cache));
  214. return 0;
  215. }