1 /*
2  * Copyright (c) 2019 Nordic Semiconductor ASA
3  *
4  * SPDX-License-Identifier: Apache-2.0
5  */
6 #include <stdlib.h>
7 #include <string.h>
8 
9 #include "settings_test.h"
10 #include "settings_priv.h"
11 
12 
13 uint8_t val8;
14 uint16_t val16;
15 uint64_t val64;
16 
17 int test_get_called;
18 int test_set_called;
19 int test_commit_called;
20 int test_export_block;
21 
22 int c1_handle_get(const char *name, char *val, int val_len_max);
23 int c1_handle_set(const char *name, size_t len, settings_read_cb read_cb,
24 		  void *cb_arg);
25 int c1_handle_commit(void);
26 int c1_handle_export(int (*cb)(const char *name,
27 			       const void *value, size_t val_len));
28 
29 struct settings_handler c_test_handlers[] = {
30 	{
31 		.name = "myfoo",
32 		.h_get = c1_handle_get,
33 		.h_set = c1_handle_set,
34 		.h_commit = c1_handle_commit,
35 		.h_export = c1_handle_export
36 	},
37 };
38 
39 
40 
c1_handle_get(const char * name,char * val,int val_len_max)41 int c1_handle_get(const char *name, char *val, int val_len_max)
42 {
43 	test_get_called = 1;
44 	const char *next;
45 
46 	if (settings_name_steq(name, "mybar", &next) && !next) {
47 		val_len_max = MIN(val_len_max, sizeof(val8));
48 		memcpy(val, &val8, MIN(val_len_max, sizeof(val8)));
49 		return val_len_max;
50 	}
51 
52 	if (settings_name_steq(name, "mybar16", &next) && !next) {
53 		val_len_max = MIN(val_len_max, sizeof(val16));
54 		memcpy(val, &val16, MIN(val_len_max, sizeof(val16)));
55 		return val_len_max;
56 	}
57 
58 	if (settings_name_steq(name, "mybar64", &next) && !next) {
59 		val_len_max = MIN(val_len_max, sizeof(val64));
60 		memcpy(val, &val64, MIN(val_len_max, sizeof(val64)));
61 		return val_len_max;
62 	}
63 
64 	return -ENOENT;
65 }
66 
c1_handle_set(const char * name,size_t len,settings_read_cb read_cb,void * cb_arg)67 int c1_handle_set(const char *name, size_t len, settings_read_cb read_cb,
68 		  void *cb_arg)
69 {
70 	int rc;
71 	const char *next;
72 	size_t val_len;
73 
74 	test_set_called = 1;
75 	if (settings_name_steq(name, "mybar", &next) && !next) {
76 		val_len = len;
77 		zassert_true(val_len == 1, "bad set-value size");
78 
79 		rc = read_cb(cb_arg, &val8, sizeof(val8));
80 		zassert_true(rc >= 0, "SETTINGS_VALUE_SET callback");
81 		return 0;
82 	}
83 
84 	if (settings_name_steq(name, "mybar16", &next) && !next) {
85 		val_len = len;
86 		zassert_true(val_len == 2, "bad set-value size");
87 
88 		rc = read_cb(cb_arg, &val16, sizeof(val16));
89 		zassert_true(rc >= 0, "SETTINGS_VALUE_SET callback");
90 		return 0;
91 	}
92 
93 	if (settings_name_steq(name, "mybar64", &next) && !next) {
94 		val_len = len;
95 		zassert_true(val_len == 8, "bad set-value size");
96 
97 		rc = read_cb(cb_arg, &val64, sizeof(val64));
98 		zassert_true(rc >= 0, "SETTINGS_VALUE_SET callback");
99 		return 0;
100 	}
101 
102 	return -ENOENT;
103 }
104 
c1_handle_commit(void)105 int c1_handle_commit(void)
106 {
107 	test_commit_called = 1;
108 	return 0;
109 }
110 
c1_handle_export(int (* cb)(const char * name,const void * value,size_t val_len))111 int c1_handle_export(int (*cb)(const char *name,
112 			       const void *value, size_t val_len))
113 {
114 	if (test_export_block) {
115 		return 0;
116 	}
117 
118 	(void)cb("myfoo/mybar", &val8, sizeof(val8));
119 
120 	(void)cb("myfoo/mybar16", &val16, sizeof(val16));
121 
122 	(void)cb("myfoo/mybar64", &val64, sizeof(val64));
123 
124 	return 0;
125 }
126 
ctest_clear_call_state(void)127 void ctest_clear_call_state(void)
128 {
129 	test_get_called = 0;
130 	test_set_called = 0;
131 	test_commit_called = 0;
132 }
133 
ctest_get_call_state(void)134 int ctest_get_call_state(void)
135 {
136 	return test_get_called + test_set_called + test_commit_called;
137 }
138 
config_wipe_srcs(void)139 void config_wipe_srcs(void)
140 {
141 	sys_slist_init(&settings_load_srcs);
142 	settings_save_dst = NULL;
143 }
144 
fsutil_read_file(const char * path,off_t offset,size_t len,void * dst,size_t * out_len)145 int fsutil_read_file(const char *path, off_t offset, size_t len, void *dst,
146 		     size_t *out_len)
147 {
148 	struct fs_file_t file;
149 	int rc;
150 	ssize_t r_len = 0;
151 
152 	fs_file_t_init(&file);
153 
154 	rc = fs_open(&file, path, FS_O_CREATE | FS_O_RDWR);
155 	if (rc != 0) {
156 		return rc;
157 	}
158 
159 	r_len = fs_read(&file, dst, len);
160 	if (r_len < 0) {
161 		rc = -EIO;
162 	} else {
163 		*out_len = r_len;
164 	}
165 
166 	fs_close(&file);
167 	return rc;
168 }
169 
fsutil_write_file(const char * path,const void * data,size_t len)170 int fsutil_write_file(const char *path, const void *data, size_t len)
171 {
172 	struct fs_file_t file;
173 	int rc;
174 
175 	fs_file_t_init(&file);
176 
177 	rc = fs_open(&file, path, FS_O_CREATE | FS_O_RDWR);
178 	if (rc != 0) {
179 		return rc;
180 	}
181 
182 	if (fs_write(&file, data, len) != len) {
183 		rc = -EIO;
184 	}
185 
186 	fs_close(&file);
187 	return rc;
188 }
189 
memmem(char const * mem,size_t mem_len,char const * sub,size_t sub_len)190 char const *memmem(char const *mem, size_t mem_len, char const *sub,
191 		   size_t sub_len)
192 {
193 	int i;
194 
195 	if (sub_len <= mem_len && sub_len > 0) {
196 		for (i = 0; i <= mem_len - sub_len; i++) {
197 			if (!memcmp(&mem[i], sub, sub_len)) {
198 				return &mem[i];
199 			}
200 		}
201 	}
202 
203 	return NULL;
204 }
205 
settings_test_file_strstr(const char * fname,char const * string,size_t str_len)206 int settings_test_file_strstr(const char *fname, char const *string,
207 			      size_t str_len)
208 {
209 	int rc;
210 	uint32_t len;
211 	size_t rlen;
212 	char *buf;
213 	struct fs_dirent entry;
214 
215 	rc = fs_stat(fname, &entry);
216 	if (rc) {
217 		return rc;
218 	}
219 
220 	len = entry.size;
221 	buf = (char *)k_malloc(len + 1);
222 	zassert_not_null(buf, "out of memory");
223 
224 	rc = fsutil_read_file(fname, 0, len, buf, &rlen);
225 	zassert_true(rc == 0, "can't access the file\n'");
226 	zassert_true(rc == 0, "not enough data read\n'");
227 	buf[rlen] = '\0';
228 
229 	if (memmem(buf, len, string, str_len)) {
230 		return 0;
231 	}
232 
233 	return -1;
234 }
235