1 /* Bluetooth: Mesh Generic OnOff, Generic Level, Lighting & Vendor Models
2  *
3  * Copyright (c) 2018 Vikrant More
4  *
5  * SPDX-License-Identifier: Apache-2.0
6  */
7 
8 #include "ble_mesh.h"
9 #include "device_composition.h"
10 #include "storage.h"
11 
12 static uint8_t storage_id;
13 uint8_t reset_counter;
14 
save_reset_counter(void)15 static void save_reset_counter(void)
16 {
17 	settings_save_one("ps/rc", &reset_counter, sizeof(reset_counter));
18 }
19 
save_gen_def_trans_time_state(void)20 static void save_gen_def_trans_time_state(void)
21 {
22 	settings_save_one("ps/gdtt", &ctl->tt, sizeof(ctl->tt));
23 }
24 
save_gen_onpowerup_state(void)25 static void save_gen_onpowerup_state(void)
26 {
27 	settings_save_one("ps/gpo", &ctl->onpowerup, sizeof(ctl->onpowerup));
28 
29 	if (ctl->onpowerup == 0x02) {
30 		save_on_flash(LAST_TARGET_STATES);
31 	}
32 }
33 
save_def_states(void)34 static void save_def_states(void)
35 {
36 	settings_save_one("ps/ld", &ctl->light->def, sizeof(ctl->light->def));
37 	settings_save_one("ps/td", &ctl->temp->def, sizeof(ctl->temp->def));
38 	settings_save_one("ps/dd", &ctl->duv->def, sizeof(ctl->duv->def));
39 }
40 
save_lightness_last_state(void)41 static void save_lightness_last_state(void)
42 {
43 	settings_save_one("ps/ll", &ctl->light->last, sizeof(ctl->light->last));
44 
45 	printk("Lightness Last values have been saved !!\n");
46 }
47 
save_last_target_states(void)48 static void save_last_target_states(void)
49 {
50 	settings_save_one("ps/llt", &ctl->light->target,
51 			  sizeof(ctl->light->target));
52 
53 	settings_save_one("ps/tlt", &ctl->temp->target,
54 			  sizeof(ctl->temp->target));
55 
56 	settings_save_one("ps/dlt", &ctl->duv->target,
57 			  sizeof(ctl->duv->target));
58 }
59 
save_lightness_range(void)60 static void save_lightness_range(void)
61 {
62 	ctl->light->range = (uint32_t) ((ctl->light->range_max << 16) |
63 				     ctl->light->range_min);
64 
65 	settings_save_one("ps/lr", &ctl->light->range,
66 			  sizeof(ctl->light->range));
67 }
68 
save_temperature_range(void)69 static void save_temperature_range(void)
70 {
71 	ctl->temp->range = (uint32_t) ((ctl->temp->range_max << 16) |
72 				    ctl->temp->range_min);
73 
74 	settings_save_one("ps/tr", &ctl->temp->range, sizeof(ctl->temp->range));
75 }
76 
storage_work_handler(struct k_work * work)77 static void storage_work_handler(struct k_work *work)
78 {
79 	switch (storage_id) {
80 	case RESET_COUNTER:
81 		save_reset_counter();
82 		break;
83 	case GEN_DEF_TRANS_TIME_STATE:
84 		save_gen_def_trans_time_state();
85 		break;
86 	case GEN_ONPOWERUP_STATE:
87 		save_gen_onpowerup_state();
88 		break;
89 	case DEF_STATES:
90 		save_def_states();
91 		break;
92 	case LIGHTNESS_LAST_STATE:
93 		save_lightness_last_state();
94 		break;
95 	case LAST_TARGET_STATES:
96 		save_last_target_states();
97 		break;
98 	case LIGHTNESS_RANGE:
99 		save_lightness_range();
100 		break;
101 	case TEMPERATURE_RANGE:
102 		save_temperature_range();
103 		break;
104 	}
105 }
106 
107 K_WORK_DEFINE(storage_work, storage_work_handler);
108 
save_on_flash(uint8_t id)109 void save_on_flash(uint8_t id)
110 {
111 	storage_id = id;
112 	k_work_submit(&storage_work);
113 }
114 
ps_set(const char * key,size_t len_rd,settings_read_cb read_cb,void * cb_arg)115 static int ps_set(const char *key, size_t len_rd,
116 		  settings_read_cb read_cb, void *cb_arg)
117 {
118 	ssize_t len = 0;
119 	int key_len;
120 	const char *next;
121 
122 	key_len = settings_name_next(key, &next);
123 
124 	if (!next) {
125 		if (!strncmp(key, "rc", key_len)) {
126 			len = read_cb(cb_arg, &reset_counter,
127 				      sizeof(reset_counter));
128 		}
129 
130 		if (!strncmp(key, "gdtt", key_len)) {
131 			len = read_cb(cb_arg, &ctl->tt, sizeof(ctl->tt));
132 		}
133 
134 		if (!strncmp(key, "gpo", key_len)) {
135 			len = read_cb(cb_arg, &ctl->onpowerup,
136 				      sizeof(ctl->onpowerup));
137 		}
138 
139 		if (!strncmp(key, "ld", key_len)) {
140 			len = read_cb(cb_arg, &ctl->light->def,
141 				      sizeof(ctl->light->def));
142 		}
143 
144 		if (!strncmp(key, "td", key_len)) {
145 			len = read_cb(cb_arg, &ctl->temp->def,
146 				      sizeof(ctl->temp->def));
147 		}
148 
149 		if (!strncmp(key, "dd", key_len)) {
150 			len = read_cb(cb_arg, &ctl->duv->def,
151 				      sizeof(ctl->duv->def));
152 		}
153 
154 		if (!strncmp(key, "ll", key_len)) {
155 			len = read_cb(cb_arg, &ctl->light->last,
156 				      sizeof(ctl->light->last));
157 		}
158 
159 		if (!strncmp(key, "llt", key_len)) {
160 			len = read_cb(cb_arg, &ctl->light->target,
161 				      sizeof(ctl->light->target));
162 		}
163 
164 		if (!strncmp(key, "tlt", key_len)) {
165 			len = read_cb(cb_arg, &ctl->temp->target,
166 				      sizeof(ctl->temp->target));
167 		}
168 
169 		if (!strncmp(key, "dlt", key_len)) {
170 			len = read_cb(cb_arg, &ctl->duv->target,
171 				      sizeof(ctl->duv->target));
172 		}
173 
174 		if (!strncmp(key, "lr", key_len)) {
175 			len = read_cb(cb_arg, &ctl->light->range,
176 				      sizeof(ctl->light->range));
177 		}
178 
179 		if (!strncmp(key, "tr", key_len)) {
180 			len = read_cb(cb_arg, &ctl->temp->range,
181 				      sizeof(ctl->temp->range));
182 		}
183 
184 		return (len < 0) ? len : 0;
185 	}
186 
187 	return -ENOENT;
188 }
189 
190 static struct settings_handler ps_settings = {
191 	.name = "ps",
192 	.h_set = ps_set,
193 };
194 
ps_settings_init(void)195 int ps_settings_init(void)
196 {
197 	int err;
198 
199 	err = settings_subsys_init();
200 	if (err) {
201 		printk("settings_subsys_init failed (err %d)", err);
202 		return err;
203 	}
204 
205 	err = settings_register(&ps_settings);
206 	if (err) {
207 		printk("ps_settings_register failed (err %d)", err);
208 		return err;
209 	}
210 
211 	return 0;
212 }
213