1 /*
2 * Copyright (C) 2019-2020 Alibaba Group Holding Limited
3 */
4
5 #include <api/mesh.h>
6 #include <mesh_model.h>
7
8 #define TAG "MESH BIND"
9
10 typedef u16_t (*BIND_OPS_HANDLER)(S_ELEM_STATE *p_elem, u8_t type);
11
12 u16_t model_bind_operation(BIND_OPERATION_ID id, S_ELEM_STATE *p_elem, u8_t type);
13
14
15 static u16_t _gen_onoff_operation(S_ELEM_STATE *p_elem, u8_t type);
16 static u16_t _gen_onpowerup_operation(S_ELEM_STATE *p_elem, u8_t type);
17
18 static u16_t _gen_level_operation(S_ELEM_STATE *p_elem, u8_t type);
19 static u16_t _gen_power_actual_operation(S_ELEM_STATE *p_elem, u8_t type);
20 static u16_t _gen_lightness_linear_operation(S_ELEM_STATE *p_elem, u8_t type);
21 static u16_t _gen_lightness_actual_operation(S_ELEM_STATE *p_elem, u8_t type);
22 static u16_t _gen_power_range_operation(S_ELEM_STATE *p_elem, u8_t type);
23
24
25 BIND_OPS_HANDLER bind_handler[B_OPS_END_ID] = {
26 /* !!!START!!! --- Don't add new ID before this one */
27 //B_OPS_START_ID = -1,
28
29 /* Generic OnOff */
30 _gen_onoff_operation,//B_GEN_ONOFF_ID = 0,
31
32 /* Generic Level */
33 NULL,//B_GEN_LEVEL_ID,
34 NULL,//B_GEN_DELTA_ID,
35 NULL,//B_GEN_MOVE_ID,
36
37 /* Generic Default Transition Time */
38 NULL,//B_GEN_DFT_TRANS_TIME_ID,
39
40 /* Generic Power OnOff */
41 _gen_onpowerup_operation,//B_GEN_ON_PWR_UP_ID,
42
43 /* Generic Power Level */
44 _gen_power_actual_operation,//B_GEN_PWR_ACTUAL_ID,
45 NULL,//B_GEN_PWR_LAST_ID,
46 NULL,//B_GEN_PWR_DFT_ID,
47 _gen_power_range_operation,//B_GEN_PWR_RANGE_ID,
48 /*lightness*/
49 _gen_lightness_linear_operation,//B_GEN_LIGHTNESS_LINEAR_ID
50 _gen_lightness_actual_operation,//B_GEN_LIGHTNESS_ACTUAL_ID
51 /* !!!END!!! --- Don't add new ID after this one */
52 NULL
53 };
54
model_bind_operation(BIND_OPERATION_ID id,S_ELEM_STATE * p_elem,u8_t type)55 u16_t model_bind_operation(BIND_OPERATION_ID id, S_ELEM_STATE *p_elem, u8_t type)
56 {
57 BIND_OPS_HANDLER p_func = NULL;
58
59 LOGD(TAG, "bind ops - id: %d, ele:%p\n", id, p_elem);
60
61 if (id <= B_OPS_START_ID || id >= B_OPS_END_ID || !p_elem) {
62 LOGE(TAG, "invalid args, ignore\n");
63 return -1;
64 }
65
66 #if 1
67 p_func = bind_handler[id];
68 LOGD(TAG, "p_func:%p\n", p_func);
69
70 return p_func ? p_func(p_elem, type) : -1;
71 #else
72 {
73 u8_t i = 0;
74
75 for (i = 0; i < sizeof(bind_handler) / sizeof(bind_handler[0]); i++) {
76 func = bind_handler[i];
77
78 if (func) {
79 func(i, p_elem, type);
80 } else {
81 LOGD(TAG, "id:%d, func is NULL\n", i);
82 }
83 }
84
85 return 0;
86 }
87 #endif
88 }
89
90 /*
91 static u16_t _constrain_actual(S_ELEM_STATE *p_elem, u16_t var)
92 {
93
94 S_MESH_STATE *p_state = &p_elem->state;
95
96 if (var > 0 && var < p_state->power_range.range_min) {
97 var = p_state->power_range.range_min;
98 } else if (var > p_state->power_range.range_max) {
99 var = p_state->power_range.range_max;
100 }
101 return var;
102 }*/
103
104 /*
105 static u16_t _constrain_lightness(S_ELEM_STATE *p_elem, u16_t var)
106 {
107
108 S_MESH_STATE *p_state = &p_elem->state;
109 S_MESH_POWERUP *p_powerup = &p_elem->powerup;
110 if (var > 0 && var < p_powerup->lightness_range.range_min) {
111 var = p_powerup->lightness_range.range_min;
112 } else if (var > p_powerup->lightness_range.range_max) {
113 var = p_powerup->lightness_range.range_max;
114 }
115 return var;
116 }
117
118 static u16_t _gen_onoff_operation(S_ELEM_STATE *p_elem, u8_t type) {
119 S_MESH_STATE *p_state = &p_elem->state;
120 S_MESH_POWERUP *p_power_up = &p_elem->powerup;
121 u16_t actual = 0;
122
123 if (p_state->onoff[T_CUR]){
124 if(!p_power_up->lightness_default){
125 p_state->lightness_actual[T_CUR] = p_power_up->lightness_last;
126 }else{
127 p_state->lightness_actual[T_CUR] = p_power_up->lightness_default;
128 }
129 }
130 else{
131 p_state->actual[T_CUR] = p_state->actual[T_TAR] = actual;
132 p_state->lightness_actual[T_CUR] = 0;
133 }
134
135 BT_INFO("onoff[T_TAR]:%d, onoff[T_CUR]:%d, actual[TAR]:0x%02x", p_state->onoff[T_TAR], p_state->onoff[T_CUR], p_state->actual[T_TAR]);
136
137 return 0;
138 }
139
140 static u16_t _gen_level_operation(S_ELEM_STATE *p_elem, u8_t type) {
141 LOGD(TAG, "");
142 S_MESH_STATE *p_state = &p_elem->state;
143 p_state->actual[T_TAR] = p_state->level[T_CUR] + 32768;
144 p_state->lightness_actual[T_TAR] = p_state->level[T_CUR] + 32768;
145 return 0;
146 }
147
148 /*
149 static u16_t _gen_onpowerup_operation(S_ELEM_STATE *p_elem, u8_t type) {
150 S_MESH_STATE *p_state = &p_elem->state;
151 S_MESH_POWERUP *p_powerUp = &p_elem->powerup;
152 //Ethan: not supported, give 1 for the moment, don't need to adjust target actual here, will only take affect when next power on cycle
153
154 if(p_state->powerUp_status == 0x00){
155 p_state->actual[T_CUR] = 0;
156 p_state->lightness_actual[T_CUR] = 0;
157 }else if(p_state->powerUp_status == 0x01 ){
158 if(p_state->power_default != 0x00){
159 p_state->actual[T_CUR] = p_state->power_default;
160 }else{
161 p_state->actual[T_CUR] = p_state->power_last;
162 }
163 if(p_powerUp->lightness_default != 0x00){
164 p_state->lightness_actual[T_CUR] = p_powerUp->lightness_default;
165 }else{
166 p_state->lightness_actual[T_CUR] = p_powerUp->lightness_last;
167 }
168 }else if(p_state->powerUp_status == 0x02){
169 p_state->actual[T_CUR] = p_state->power_last;
170 p_state->lightness_actual[T_CUR] = p_powerUp->lightness_last;
171 }
172
173 BT_INFO("onpowerup ops, actual[TAR]:0x%02x\n", p_state->actual[type]);
174
175 return 0;
176 }*/
177
178 /*
179 static u16_t _gen_power_actual_operation(S_ELEM_STATE *p_elem, u8_t type)
180 {
181 LOGD(TAG, "");
182 S_MESH_STATE *p_state = &p_elem->state;
183 p_state->actual[type] = _constrain_actual(p_elem , p_state->actual[type]);
184 p_state->level[T_CUR] = p_state->actual - 32768;
185 if(p_state->actual == 0X0000){
186 p_state->onoff[T_TAR] = 0X00;
187 }else{
188 p_state->onoff[T_TAR] = 0X01;
189 }
190 p_state->power_last = p_state->actual[type];
191 return 0;
192 }*/
193
194 /*
195 static u16_t _gen_power_range_operation(S_ELEM_STATE *p_elem, u8_t type)
196 {
197 LOGD(TAG, "");
198
199 }
200
201 static u16_t _gen_lightness_linear_operation(S_ELEM_STATE *p_elem, u8_t type)
202 {
203 LOGD(TAG, "");
204 S_MESH_STATE *p_state = &p_elem->state;
205 p_state->lightness_actual[type] = (uint16_t)(sqrt(p_state->lightness_linear / 65535) * 65535);
206 }
207
208 static u16_t _gen_lightness_actual_operation(S_ELEM_STATE *p_elem, u8_t type)
209 {
210 LOGD(TAG, "");
211 S_MESH_STATE *p_state = &p_elem->state;
212 p_state->lightness_linear = p_state->lightness_actual[type] * p_state->lightness_actual[type] / 65535;
213 p_state->level = p_state->lightness_actual[type] - 32768;
214 if(!p_state->lightness_actual[T_CUR]){
215 p_state->onoff[type]= 0x00;
216 }else{
217 p_state->onoff[type]= 0x01;
218 }
219 }*/
220
221
222
223