1 /*
2 * Copyright (c) 2017 Intel Corporation
3 *
4 * SPDX-License-Identifier: Apache-2.0
5 */
6
7 #include "syscfg/syscfg.h"
8 #define MESH_LOG_MODULE BLE_MESH_MODEL_LOG
9
10 #include "mesh/mesh.h"
11 #include "mesh_priv.h"
12 #include "mesh/model_srv.h"
13
14 static struct bt_mesh_gen_onoff_srv *gen_onoff_srv;
15 static struct bt_mesh_gen_level_srv *gen_level_srv;
16 static struct bt_mesh_light_lightness_srv *light_lightness_srv;
17
gen_onoff_status(struct bt_mesh_model * model,struct bt_mesh_msg_ctx * ctx)18 static void gen_onoff_status(struct bt_mesh_model *model,
19 struct bt_mesh_msg_ctx *ctx)
20 {
21 struct bt_mesh_gen_onoff_srv *cb = model->user_data;
22 struct os_mbuf *msg = NET_BUF_SIMPLE(3);
23 u8_t *state;
24 bt_mesh_model_msg_init(msg, OP_GEN_ONOFF_STATUS);
25 state = net_buf_simple_add(msg, 1);
26
27 if (cb && cb->get) {
28 cb->get(model, state);
29 }
30
31 BT_DBG("state: %d", *state);
32
33 if (bt_mesh_model_send(model, ctx, msg, NULL, NULL)) {
34 BT_ERR("Send status failed");
35 }
36
37 os_mbuf_free_chain(msg);
38 }
39
gen_onoff_get(struct bt_mesh_model * model,struct bt_mesh_msg_ctx * ctx,struct os_mbuf * buf)40 static void gen_onoff_get(struct bt_mesh_model *model,
41 struct bt_mesh_msg_ctx *ctx,
42 struct os_mbuf *buf)
43 {
44 BT_DBG("");
45 gen_onoff_status(model, ctx);
46 }
47
gen_onoff_set_unack(struct bt_mesh_model * model,struct bt_mesh_msg_ctx * ctx,struct os_mbuf * buf)48 static void gen_onoff_set_unack(struct bt_mesh_model *model,
49 struct bt_mesh_msg_ctx *ctx,
50 struct os_mbuf *buf)
51 {
52 struct bt_mesh_gen_onoff_srv *cb = model->user_data;
53 u8_t state;
54 state = buf->om_data[0];
55 BT_DBG("state: %d", state);
56
57 if (cb && cb->set) {
58 cb->set(model, state);
59 }
60 }
61
gen_onoff_set(struct bt_mesh_model * model,struct bt_mesh_msg_ctx * ctx,struct os_mbuf * buf)62 static void gen_onoff_set(struct bt_mesh_model *model,
63 struct bt_mesh_msg_ctx *ctx,
64 struct os_mbuf *buf)
65 {
66 BT_DBG("");
67 gen_onoff_set_unack(model, ctx, buf);
68 gen_onoff_status(model, ctx);
69 }
70
gen_level_status(struct bt_mesh_model * model,struct bt_mesh_msg_ctx * ctx)71 static void gen_level_status(struct bt_mesh_model *model,
72 struct bt_mesh_msg_ctx *ctx)
73 {
74 struct bt_mesh_gen_level_srv *cb = model->user_data;
75 struct os_mbuf *msg = NET_BUF_SIMPLE(4);
76 s16_t *level;
77 bt_mesh_model_msg_init(msg, OP_GEN_LEVEL_STATUS);
78 level = net_buf_simple_add(msg, 2); // 2:len
79
80 if (cb && cb->get) {
81 cb->get(model, level);
82 }
83
84 BT_DBG("level: %d", *level);
85
86 if (bt_mesh_model_send(model, ctx, msg, NULL, NULL)) {
87 BT_ERR("Send status failed");
88 }
89
90 os_mbuf_free_chain(msg);
91 }
92
gen_level_get(struct bt_mesh_model * model,struct bt_mesh_msg_ctx * ctx,struct os_mbuf * buf)93 static void gen_level_get(struct bt_mesh_model *model,
94 struct bt_mesh_msg_ctx *ctx,
95 struct os_mbuf *buf)
96 {
97 BT_DBG("");
98 gen_level_status(model, ctx);
99 }
100
gen_level_set_unack(struct bt_mesh_model * model,struct bt_mesh_msg_ctx * ctx,struct os_mbuf * buf)101 static void gen_level_set_unack(struct bt_mesh_model *model,
102 struct bt_mesh_msg_ctx *ctx,
103 struct os_mbuf *buf)
104 {
105 struct bt_mesh_gen_level_srv *cb = model->user_data;
106 s16_t level;
107 level = (s16_t) net_buf_simple_pull_le16(buf);
108 BT_DBG("level: %d", level);
109
110 if (cb && cb->set) {
111 cb->set(model, level);
112 }
113 }
114
gen_level_set(struct bt_mesh_model * model,struct bt_mesh_msg_ctx * ctx,struct os_mbuf * buf)115 static void gen_level_set(struct bt_mesh_model *model,
116 struct bt_mesh_msg_ctx *ctx,
117 struct os_mbuf *buf)
118 {
119 gen_level_set_unack(model, ctx, buf);
120 gen_level_status(model, ctx);
121 }
122
light_lightness_status(struct bt_mesh_model * model,struct bt_mesh_msg_ctx * ctx)123 static void light_lightness_status(struct bt_mesh_model *model,
124 struct bt_mesh_msg_ctx *ctx)
125 {
126 struct bt_mesh_light_lightness_srv *cb = model->user_data;
127 struct os_mbuf *msg = NET_BUF_SIMPLE(4);
128 s16_t *lightness;
129 bt_mesh_model_msg_init(msg, OP_LIGHT_LIGHTNESS_STATUS);
130 lightness = net_buf_simple_add(msg, 2); // 2:len
131
132 if (cb && cb->get) {
133 cb->get(model, lightness);
134 }
135
136 BT_DBG("lightness: %d", *lightness);
137
138 if (bt_mesh_model_send(model, ctx, msg, NULL, NULL)) {
139 BT_ERR("Send status failed");
140 }
141
142 os_mbuf_free_chain(msg);
143 }
144
light_lightness_get(struct bt_mesh_model * model,struct bt_mesh_msg_ctx * ctx,struct os_mbuf * buf)145 static void light_lightness_get(struct bt_mesh_model *model,
146 struct bt_mesh_msg_ctx *ctx,
147 struct os_mbuf *buf)
148 {
149 BT_DBG("");
150 light_lightness_status(model, ctx);
151 }
152
light_lightness_set_unack(struct bt_mesh_model * model,struct bt_mesh_msg_ctx * ctx,struct os_mbuf * buf)153 static void light_lightness_set_unack(struct bt_mesh_model *model,
154 struct bt_mesh_msg_ctx *ctx,
155 struct os_mbuf *buf)
156 {
157 struct bt_mesh_light_lightness_srv *cb = model->user_data;
158 s16_t lightness;
159 lightness = (s16_t) net_buf_simple_pull_le16(buf);
160 BT_DBG("lightness: %d", lightness);
161
162 if (cb && cb->set) {
163 cb->set(model, lightness);
164 }
165 }
166
light_lightness_set(struct bt_mesh_model * model,struct bt_mesh_msg_ctx * ctx,struct os_mbuf * buf)167 static void light_lightness_set(struct bt_mesh_model *model,
168 struct bt_mesh_msg_ctx *ctx,
169 struct os_mbuf *buf)
170 {
171 light_lightness_set_unack(model, ctx, buf);
172 light_lightness_status(model, ctx);
173 }
174
175 const struct bt_mesh_model_op gen_onoff_srv_op[] = {
176 { OP_GEN_ONOFF_GET, 0, gen_onoff_get },
177 { OP_GEN_ONOFF_SET, 2, gen_onoff_set },
178 { OP_GEN_ONOFF_SET_UNACK, 2, gen_onoff_set_unack },
179 BT_MESH_MODEL_OP_END,
180 };
181
182 const struct bt_mesh_model_op gen_level_srv_op[] = {
183 { OP_GEN_LEVEL_GET, 0, gen_level_get },
184 { OP_GEN_LEVEL_SET, 3, gen_level_set },
185 { OP_GEN_LEVEL_SET_UNACK, 3, gen_level_set_unack },
186 BT_MESH_MODEL_OP_END,
187 };
188
189 const struct bt_mesh_model_op light_lightness_srv_op[] = {
190 { OP_LIGHT_LIGHTNESS_GET, 0, light_lightness_get },
191 { OP_LIGHT_LIGHTNESS_SET, 3, light_lightness_set },
192 { OP_LIGHT_LIGHTNESS_SET_UNACK, 3, light_lightness_set_unack },
193 BT_MESH_MODEL_OP_END,
194 };
195
onoff_srv_init(struct bt_mesh_model * model)196 static int onoff_srv_init(struct bt_mesh_model *model)
197 {
198 struct bt_mesh_gen_onoff_srv *cfg = model->user_data;
199 BT_DBG("");
200
201 if (!cfg) {
202 BT_ERR("No Generic OnOff Server context provided");
203 return -EINVAL;
204 }
205
206 cfg->model = model;
207 gen_onoff_srv = cfg;
208 return 0;
209 }
210
211 const struct bt_mesh_model_cb gen_onoff_srv_cb = {
212 .init = onoff_srv_init,
213 };
214
level_srv_init(struct bt_mesh_model * model)215 static int level_srv_init(struct bt_mesh_model *model)
216 {
217 struct bt_mesh_gen_level_srv *cfg = model->user_data;
218 BT_DBG("");
219
220 if (!cfg) {
221 BT_ERR("No Generic Level Server context provided");
222 return -EINVAL;
223 }
224
225 cfg->model = model;
226 gen_level_srv = cfg;
227 return 0;
228 }
229
230 const struct bt_mesh_model_cb gen_level_srv_cb = {
231 .init = level_srv_init,
232 };
233
lightness_srv_init(struct bt_mesh_model * model)234 static int lightness_srv_init(struct bt_mesh_model *model)
235 {
236 struct bt_mesh_light_lightness_srv *cfg = model->user_data;
237 BT_DBG("");
238
239 if (!cfg) {
240 BT_ERR("No Light Lightness Server context provided");
241 return -EINVAL;
242 }
243
244 cfg->model = model;
245 light_lightness_srv = cfg;
246 return 0;
247 }
248
249 const struct bt_mesh_model_cb light_lightness_srv_cb = {
250 .init = lightness_srv_init,
251 };
252