1 /*
2 * Copyright (C) 2019 BlueKitchen GmbH
3 *
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions
6 * are met:
7 *
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
13 * 3. Neither the name of the copyright holders nor the names of
14 * contributors may be used to endorse or promote products derived
15 * from this software without specific prior written permission.
16 * 4. Any redistribution, use, or modification is done solely for
17 * personal benefit and not for any commercial purpose or for
18 * monetary gain.
19 *
20 * THIS SOFTWARE IS PROVIDED BY BLUEKITCHEN GMBH AND CONTRIBUTORS
21 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
22 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
23 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BLUEKITCHEN
24 * GMBH OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
25 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
26 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
27 * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
28 * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
29 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
30 * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
31 * SUCH DAMAGE.
32 *
33 * Please inquire about commercial licensing options at
34 * [email protected]
35 *
36 */
37
38 #define BTSTACK_FILE__ "mesh_generic_default_transition_time_server.c"
39
40 #include "mesh/mesh_generic_default_transition_time_server.h"
41
42 #include <string.h>
43 #include <stdio.h>
44
45 #include "bluetooth_company_id.h"
46 #include "btstack_debug.h"
47 #include "btstack_memory.h"
48 #include "btstack_util.h"
49
50 #include "mesh/mesh_access.h"
51 #include "mesh/mesh_foundation.h"
52 #include "mesh/mesh_generic_model.h"
53 #include "mesh/mesh_keys.h"
54 #include "mesh/mesh_network.h"
55 #include "mesh/mesh_upper_transport.h"
56
generic_server_send_message(uint16_t src,uint16_t dest,uint16_t netkey_index,uint16_t appkey_index,mesh_pdu_t * pdu)57 static void generic_server_send_message(uint16_t src, uint16_t dest, uint16_t netkey_index, uint16_t appkey_index, mesh_pdu_t *pdu){
58 uint8_t ttl = mesh_foundation_default_ttl_get();
59 mesh_upper_transport_setup_access_pdu_header(pdu, netkey_index, appkey_index, ttl, src, dest, 0);
60 mesh_access_send_unacknowledged_pdu(pdu);
61 }
62
63 // Generic Generic Default Transition Time State
64
65 const mesh_access_message_t mesh_generic_default_transition_time_status = {
66 MESH_GENERIC_DEFAULT_TRANSITION_TIME_STATUS, "1"
67 };
68
mesh_generic_default_transition_time_status_message(mesh_model_t * generic_default_transition_time_server_model)69 static mesh_pdu_t * mesh_generic_default_transition_time_status_message(mesh_model_t *generic_default_transition_time_server_model){
70 btstack_assert(generic_default_transition_time_server_model->model_data != NULL);
71
72 mesh_generic_default_transition_time_state_t * state = (mesh_generic_default_transition_time_state_t *) generic_default_transition_time_server_model->model_data;
73 // setup message
74 mesh_upper_transport_pdu_t * transport_pdu = NULL;
75
76 log_info("Default transition time status: value %u", state->value);
77 transport_pdu = mesh_access_setup_message(&mesh_generic_default_transition_time_status, state->value);
78
79 return (mesh_pdu_t *) transport_pdu;
80 }
81
generic_default_transition_time_get_handler(mesh_model_t * generic_default_transition_time_server_model,mesh_pdu_t * pdu)82 static void generic_default_transition_time_get_handler(mesh_model_t *generic_default_transition_time_server_model, mesh_pdu_t * pdu){
83 mesh_upper_transport_pdu_t * transport_pdu = (mesh_upper_transport_pdu_t *) mesh_generic_default_transition_time_status_message(generic_default_transition_time_server_model);
84 if (!transport_pdu) return;
85 generic_server_send_message(mesh_access_get_element_address(generic_default_transition_time_server_model), mesh_pdu_src(pdu), mesh_pdu_netkey_index(pdu), mesh_pdu_appkey_index(pdu),(mesh_pdu_t *) transport_pdu);
86 mesh_access_message_processed(pdu);
87 }
88
89 // returns if set message was valid
generic_default_transition_time_handle_set_message(mesh_model_t * mesh_model,mesh_pdu_t * pdu)90 static bool generic_default_transition_time_handle_set_message(mesh_model_t *mesh_model, mesh_pdu_t * pdu){
91 btstack_assert(mesh_model != NULL);
92 btstack_assert(mesh_model->model_data != NULL);
93
94 mesh_access_parser_state_t parser;
95 mesh_access_parser_init(&parser, (mesh_pdu_t*) pdu);
96 uint8_t time_gdtt = mesh_access_parser_get_uint8(&parser);
97
98 uint8_t num_steps = mesh_access_transitions_num_steps_from_gdtt(time_gdtt);
99 // check for valid value
100 if (num_steps > 0x3E) return false;
101 mesh_generic_default_transition_time_state_t * generic_default_transition_time_server_state = (mesh_generic_default_transition_time_state_t *)mesh_model->model_data;
102 generic_default_transition_time_server_state->value = time_gdtt;
103
104 return true;
105 }
106
generic_default_transition_time_set_handler(mesh_model_t * generic_default_transition_time_server_model,mesh_pdu_t * pdu)107 static void generic_default_transition_time_set_handler(mesh_model_t *generic_default_transition_time_server_model, mesh_pdu_t * pdu){
108 bool send_status = generic_default_transition_time_handle_set_message(generic_default_transition_time_server_model, pdu);
109 if (send_status){
110 mesh_upper_transport_pdu_t * transport_pdu = (mesh_upper_transport_pdu_t *) mesh_generic_default_transition_time_status_message(generic_default_transition_time_server_model);
111 if (transport_pdu) {
112 generic_server_send_message(mesh_access_get_element_address(generic_default_transition_time_server_model), mesh_pdu_src(pdu), mesh_pdu_netkey_index(pdu), mesh_pdu_appkey_index(pdu),(mesh_pdu_t *) transport_pdu);
113 }
114 }
115 mesh_access_message_processed(pdu);
116 }
117
generic_default_transition_time_set_unacknowledged_handler(mesh_model_t * generic_default_transition_time_server_model,mesh_pdu_t * pdu)118 static void generic_default_transition_time_set_unacknowledged_handler(mesh_model_t *generic_default_transition_time_server_model, mesh_pdu_t * pdu){
119 generic_default_transition_time_handle_set_message(generic_default_transition_time_server_model, pdu);
120 mesh_access_message_processed(pdu);
121 }
122
123 // Generic On Off Message
124 static const mesh_operation_t mesh_generic_default_transition_time_model_operations[] = {
125 { MESH_GENERIC_DEFAULT_TRANSITION_TIME_GET, 0, generic_default_transition_time_get_handler },
126 { MESH_GENERIC_DEFAULT_TRANSITION_TIME_SET, 1, generic_default_transition_time_set_handler },
127 { MESH_GENERIC_DEFAULT_TRANSITION_TIME_SET_UNACKNOWLEDGED, 1, generic_default_transition_time_set_unacknowledged_handler },
128 { 0, 0, NULL }
129 };
130
mesh_generic_default_transition_time_server_get_operations(void)131 const mesh_operation_t * mesh_generic_default_transition_time_server_get_operations(void){
132 return mesh_generic_default_transition_time_model_operations;
133 }
134
mesh_generic_default_transition_time_server_set(mesh_model_t * mesh_model,uint8_t transition_time_gdtt)135 void mesh_generic_default_transition_time_server_set(mesh_model_t * mesh_model, uint8_t transition_time_gdtt){
136 mesh_generic_default_transition_time_state_t * generic_default_transition_time_server_state = (mesh_generic_default_transition_time_state_t *)mesh_model->model_data;
137 generic_default_transition_time_server_state->value = transition_time_gdtt;
138 }
139
mesh_generic_default_transition_time_server_get(mesh_model_t * generic_default_transition_time_server_model)140 uint8_t mesh_generic_default_transition_time_server_get(mesh_model_t *generic_default_transition_time_server_model){
141 mesh_generic_default_transition_time_state_t * generic_default_transition_time_server_state = (mesh_generic_default_transition_time_state_t *)generic_default_transition_time_server_model->model_data;
142 return generic_default_transition_time_server_state->value;
143 }
144
145
146