1*1663a09dSMatthias Ringwald /*
2*1663a09dSMatthias Ringwald * Copyright (C) 2024 BlueKitchen GmbH
3*1663a09dSMatthias Ringwald *
4*1663a09dSMatthias Ringwald * Redistribution and use in source and binary forms, with or without
5*1663a09dSMatthias Ringwald * modification, are permitted provided that the following conditions
6*1663a09dSMatthias Ringwald * are met:
7*1663a09dSMatthias Ringwald *
8*1663a09dSMatthias Ringwald * 1. Redistributions of source code must retain the above copyright
9*1663a09dSMatthias Ringwald * notice, this list of conditions and the following disclaimer.
10*1663a09dSMatthias Ringwald * 2. Redistributions in binary form must reproduce the above copyright
11*1663a09dSMatthias Ringwald * notice, this list of conditions and the following disclaimer in the
12*1663a09dSMatthias Ringwald * documentation and/or other materials provided with the distribution.
13*1663a09dSMatthias Ringwald * 3. Neither the name of the copyright holders nor the names of
14*1663a09dSMatthias Ringwald * contributors may be used to endorse or promote products derived
15*1663a09dSMatthias Ringwald * from this software without specific prior written permission.
16*1663a09dSMatthias Ringwald * 4. Any redistribution, use, or modification is done solely for
17*1663a09dSMatthias Ringwald * personal benefit and not for any commercial purpose or for
18*1663a09dSMatthias Ringwald * monetary gain.
19*1663a09dSMatthias Ringwald *
20*1663a09dSMatthias Ringwald * THIS SOFTWARE IS PROVIDED BY BLUEKITCHEN GMBH AND CONTRIBUTORS
21*1663a09dSMatthias Ringwald * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
22*1663a09dSMatthias Ringwald * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
23*1663a09dSMatthias Ringwald * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BLUEKITCHEN
24*1663a09dSMatthias Ringwald * GMBH OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
25*1663a09dSMatthias Ringwald * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
26*1663a09dSMatthias Ringwald * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
27*1663a09dSMatthias Ringwald * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
28*1663a09dSMatthias Ringwald * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
29*1663a09dSMatthias Ringwald * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
30*1663a09dSMatthias Ringwald * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
31*1663a09dSMatthias Ringwald * SUCH DAMAGE.
32*1663a09dSMatthias Ringwald *
33*1663a09dSMatthias Ringwald * Please inquire about commercial licensing options at
34*1663a09dSMatthias Ringwald * [email protected]
35*1663a09dSMatthias Ringwald *
36*1663a09dSMatthias Ringwald */
37*1663a09dSMatthias Ringwald
38*1663a09dSMatthias Ringwald #define BTSTACK_FILE__ "immediate_alert_service_client.c"
39*1663a09dSMatthias Ringwald
40*1663a09dSMatthias Ringwald #include "btstack_config.h"
41*1663a09dSMatthias Ringwald
42*1663a09dSMatthias Ringwald #ifdef ENABLE_TESTING_SUPPORT
43*1663a09dSMatthias Ringwald #include <stdio.h>
44*1663a09dSMatthias Ringwald #include <unistd.h>
45*1663a09dSMatthias Ringwald #endif
46*1663a09dSMatthias Ringwald
47*1663a09dSMatthias Ringwald #include <stdint.h>
48*1663a09dSMatthias Ringwald #include <string.h>
49*1663a09dSMatthias Ringwald
50*1663a09dSMatthias Ringwald #include "ble/gatt_service_client.h"
51*1663a09dSMatthias Ringwald #include "ble/gatt-service/immediate_alert_service_client.h"
52*1663a09dSMatthias Ringwald
53*1663a09dSMatthias Ringwald #include "bluetooth_gatt.h"
54*1663a09dSMatthias Ringwald #include "btstack_debug.h"
55*1663a09dSMatthias Ringwald #include "btstack_event.h"
56*1663a09dSMatthias Ringwald
57*1663a09dSMatthias Ringwald // IAS Client
58*1663a09dSMatthias Ringwald static gatt_service_client_t ias_client;
59*1663a09dSMatthias Ringwald static btstack_linked_list_t ias_connections;
60*1663a09dSMatthias Ringwald
61*1663a09dSMatthias Ringwald static btstack_context_callback_registration_t ias_client_handle_can_send_now;
62*1663a09dSMatthias Ringwald
63*1663a09dSMatthias Ringwald static void ias_client_packet_handler_internal(uint8_t packet_type, uint16_t channel, uint8_t *packet, uint16_t size);
64*1663a09dSMatthias Ringwald static void ias_client_run_for_connection(void * context);
65*1663a09dSMatthias Ringwald
66*1663a09dSMatthias Ringwald // list of uuids
67*1663a09dSMatthias Ringwald static const uint16_t ias_uuid16s[IMMEDIATE_ALERT_SERVICE_CLIENT_NUM_CHARACTERISTICS] = {
68*1663a09dSMatthias Ringwald ORG_BLUETOOTH_CHARACTERISTIC_ALERT_LEVEL
69*1663a09dSMatthias Ringwald };
70*1663a09dSMatthias Ringwald
71*1663a09dSMatthias Ringwald typedef enum {
72*1663a09dSMatthias Ringwald IAS_CLIENT_CHARACTERISTIC_INDEX_ALERT_LEVEL = 0,
73*1663a09dSMatthias Ringwald IAS_CLIENT_CHARACTERISTIC_INDEX_RFU
74*1663a09dSMatthias Ringwald } ias_client_characteristic_index_t;
75*1663a09dSMatthias Ringwald
76*1663a09dSMatthias Ringwald #ifdef ENABLE_TESTING_SUPPORT
77*1663a09dSMatthias Ringwald static char * ias_client_characteristic_name[] = {
78*1663a09dSMatthias Ringwald "ALERT_LEVEL",
79*1663a09dSMatthias Ringwald "RFU"
80*1663a09dSMatthias Ringwald };
81*1663a09dSMatthias Ringwald #endif
82*1663a09dSMatthias Ringwald
ias_client_get_connection_for_cid(uint16_t connection_cid)83*1663a09dSMatthias Ringwald static ias_client_connection_t * ias_client_get_connection_for_cid(uint16_t connection_cid){
84*1663a09dSMatthias Ringwald btstack_linked_list_iterator_t it;
85*1663a09dSMatthias Ringwald btstack_linked_list_iterator_init(&it, &ias_connections);
86*1663a09dSMatthias Ringwald while (btstack_linked_list_iterator_has_next(&it)){
87*1663a09dSMatthias Ringwald ias_client_connection_t * connection = (ias_client_connection_t *)btstack_linked_list_iterator_next(&it);
88*1663a09dSMatthias Ringwald if (gatt_service_client_get_connection_id(&connection->basic_connection) == connection_cid) {
89*1663a09dSMatthias Ringwald return connection;
90*1663a09dSMatthias Ringwald }
91*1663a09dSMatthias Ringwald }
92*1663a09dSMatthias Ringwald return NULL;
93*1663a09dSMatthias Ringwald }
94*1663a09dSMatthias Ringwald
ias_client_add_connection(ias_client_connection_t * connection)95*1663a09dSMatthias Ringwald static void ias_client_add_connection(ias_client_connection_t * connection){
96*1663a09dSMatthias Ringwald btstack_linked_list_add(&ias_connections, (btstack_linked_item_t*) connection);
97*1663a09dSMatthias Ringwald }
98*1663a09dSMatthias Ringwald
ias_client_finalize_connection(ias_client_connection_t * connection)99*1663a09dSMatthias Ringwald static void ias_client_finalize_connection(ias_client_connection_t * connection){
100*1663a09dSMatthias Ringwald btstack_linked_list_remove(&ias_connections, (btstack_linked_item_t*) connection);
101*1663a09dSMatthias Ringwald }
102*1663a09dSMatthias Ringwald
ias_client_replace_subevent_id_and_emit(btstack_packet_handler_t callback,uint8_t * packet,uint16_t size,uint8_t subevent_id)103*1663a09dSMatthias Ringwald static void ias_client_replace_subevent_id_and_emit(btstack_packet_handler_t callback, uint8_t * packet, uint16_t size, uint8_t subevent_id){
104*1663a09dSMatthias Ringwald UNUSED(size);
105*1663a09dSMatthias Ringwald btstack_assert(callback != NULL);
106*1663a09dSMatthias Ringwald // execute callback
107*1663a09dSMatthias Ringwald packet[2] = subevent_id;
108*1663a09dSMatthias Ringwald (*callback)(HCI_EVENT_PACKET, 0, packet, size);
109*1663a09dSMatthias Ringwald }
110*1663a09dSMatthias Ringwald
ias_client_connected(ias_client_connection_t * connection,uint8_t status,uint8_t * packet,uint16_t size)111*1663a09dSMatthias Ringwald static void ias_client_connected(ias_client_connection_t * connection, uint8_t status, uint8_t * packet, uint16_t size) {
112*1663a09dSMatthias Ringwald if (status == ERROR_CODE_SUCCESS){
113*1663a09dSMatthias Ringwald connection->state = IMMEDIATE_ALERT_SERVICE_CLIENT_STATE_READY;
114*1663a09dSMatthias Ringwald } else {
115*1663a09dSMatthias Ringwald connection->state = IMMEDIATE_ALERT_SERVICE_CLIENT_STATE_IDLE;
116*1663a09dSMatthias Ringwald }
117*1663a09dSMatthias Ringwald ias_client_replace_subevent_id_and_emit(connection->packet_handler, packet, size,
118*1663a09dSMatthias Ringwald GATTSERVICE_SUBEVENT_IAS_CLIENT_CONNECTED);
119*1663a09dSMatthias Ringwald }
120*1663a09dSMatthias Ringwald
121*1663a09dSMatthias Ringwald
ias_client_value_handle_for_index(ias_client_connection_t * connection)122*1663a09dSMatthias Ringwald static uint16_t ias_client_value_handle_for_index(ias_client_connection_t * connection){
123*1663a09dSMatthias Ringwald return connection->basic_connection.characteristics[connection->characteristic_index].value_handle;
124*1663a09dSMatthias Ringwald }
125*1663a09dSMatthias Ringwald
ias_client_can_query_characteristic(ias_client_connection_t * connection,ias_client_characteristic_index_t characteristic_index)126*1663a09dSMatthias Ringwald static uint8_t ias_client_can_query_characteristic(ias_client_connection_t * connection, ias_client_characteristic_index_t characteristic_index){
127*1663a09dSMatthias Ringwald uint8_t status = gatt_service_client_can_query_characteristic(&connection->basic_connection,
128*1663a09dSMatthias Ringwald (uint8_t) characteristic_index);
129*1663a09dSMatthias Ringwald if (status != ERROR_CODE_SUCCESS){
130*1663a09dSMatthias Ringwald return status;
131*1663a09dSMatthias Ringwald }
132*1663a09dSMatthias Ringwald return connection->state == IMMEDIATE_ALERT_SERVICE_CLIENT_STATE_READY ? ERROR_CODE_SUCCESS : ERROR_CODE_CONTROLLER_BUSY;
133*1663a09dSMatthias Ringwald }
134*1663a09dSMatthias Ringwald
ias_client_request_send_gatt_query(ias_client_connection_t * connection,ias_client_characteristic_index_t characteristic_index)135*1663a09dSMatthias Ringwald static uint8_t ias_client_request_send_gatt_query(ias_client_connection_t * connection, ias_client_characteristic_index_t characteristic_index){
136*1663a09dSMatthias Ringwald connection->characteristic_index = characteristic_index;
137*1663a09dSMatthias Ringwald
138*1663a09dSMatthias Ringwald ias_client_handle_can_send_now.context = (void *)(uintptr_t)connection->basic_connection.cid;
139*1663a09dSMatthias Ringwald uint8_t status = gatt_client_request_to_send_gatt_query(&ias_client_handle_can_send_now, connection->basic_connection.con_handle);
140*1663a09dSMatthias Ringwald if (status != ERROR_CODE_SUCCESS){
141*1663a09dSMatthias Ringwald connection->state = IMMEDIATE_ALERT_SERVICE_CLIENT_STATE_READY;
142*1663a09dSMatthias Ringwald }
143*1663a09dSMatthias Ringwald return status;
144*1663a09dSMatthias Ringwald }
145*1663a09dSMatthias Ringwald
ias_client_request_write_without_response_characteristic(ias_client_connection_t * connection,ias_client_characteristic_index_t characteristic_index)146*1663a09dSMatthias Ringwald static uint8_t ias_client_request_write_without_response_characteristic(ias_client_connection_t * connection, ias_client_characteristic_index_t characteristic_index){
147*1663a09dSMatthias Ringwald connection->state = IMMEDIATE_ALERT_SERVICE_CLIENT_STATE_W2_WRITE_WITHOUT_RESPONSE_CHARACTERISTIC_VALUE;
148*1663a09dSMatthias Ringwald return ias_client_request_send_gatt_query(connection, characteristic_index);
149*1663a09dSMatthias Ringwald }
150*1663a09dSMatthias Ringwald
ias_client_packet_handler_internal(uint8_t packet_type,uint16_t channel,uint8_t * packet,uint16_t size)151*1663a09dSMatthias Ringwald static void ias_client_packet_handler_internal(uint8_t packet_type, uint16_t channel, uint8_t *packet, uint16_t size){
152*1663a09dSMatthias Ringwald UNUSED(channel);
153*1663a09dSMatthias Ringwald UNUSED(size);
154*1663a09dSMatthias Ringwald
155*1663a09dSMatthias Ringwald if (packet_type != HCI_EVENT_PACKET) return;
156*1663a09dSMatthias Ringwald ias_client_connection_t * connection;
157*1663a09dSMatthias Ringwald uint16_t cid;
158*1663a09dSMatthias Ringwald uint8_t status;
159*1663a09dSMatthias Ringwald
160*1663a09dSMatthias Ringwald switch(hci_event_packet_get_type(packet)){
161*1663a09dSMatthias Ringwald case HCI_EVENT_GATTSERVICE_META:
162*1663a09dSMatthias Ringwald switch (hci_event_gattservice_meta_get_subevent_code(packet)) {
163*1663a09dSMatthias Ringwald case GATTSERVICE_SUBEVENT_CLIENT_CONNECTED:
164*1663a09dSMatthias Ringwald cid = gattservice_subevent_client_connected_get_cid(packet);
165*1663a09dSMatthias Ringwald connection = ias_client_get_connection_for_cid(cid);
166*1663a09dSMatthias Ringwald btstack_assert(connection != NULL);
167*1663a09dSMatthias Ringwald
168*1663a09dSMatthias Ringwald #ifdef ENABLE_TESTING_SUPPORT
169*1663a09dSMatthias Ringwald {
170*1663a09dSMatthias Ringwald uint8_t i;
171*1663a09dSMatthias Ringwald for (i = IAS_CLIENT_CHARACTERISTIC_INDEX_ALERT_LEVEL;
172*1663a09dSMatthias Ringwald i < IAS_CLIENT_CHARACTERISTIC_INDEX_RFU; i++) {
173*1663a09dSMatthias Ringwald printf("0x%04X %s\n", connection->basic_connection.characteristics[i].value_handle,
174*1663a09dSMatthias Ringwald ias_client_characteristic_name[i]);
175*1663a09dSMatthias Ringwald }
176*1663a09dSMatthias Ringwald };
177*1663a09dSMatthias Ringwald #endif
178*1663a09dSMatthias Ringwald status = gattservice_subevent_client_connected_get_status(packet);
179*1663a09dSMatthias Ringwald ias_client_connected(connection, status, packet, size);
180*1663a09dSMatthias Ringwald break;
181*1663a09dSMatthias Ringwald
182*1663a09dSMatthias Ringwald case GATTSERVICE_SUBEVENT_CLIENT_DISCONNECTED:
183*1663a09dSMatthias Ringwald cid = gattservice_subevent_client_disconnected_get_cid(packet);
184*1663a09dSMatthias Ringwald connection = ias_client_get_connection_for_cid(cid);
185*1663a09dSMatthias Ringwald btstack_assert(connection != NULL);
186*1663a09dSMatthias Ringwald ias_client_finalize_connection(connection);
187*1663a09dSMatthias Ringwald ias_client_replace_subevent_id_and_emit(connection->packet_handler,
188*1663a09dSMatthias Ringwald packet, size,
189*1663a09dSMatthias Ringwald GATTSERVICE_SUBEVENT_IAS_CLIENT_DISCONNECTED);
190*1663a09dSMatthias Ringwald break;
191*1663a09dSMatthias Ringwald
192*1663a09dSMatthias Ringwald default:
193*1663a09dSMatthias Ringwald break;
194*1663a09dSMatthias Ringwald }
195*1663a09dSMatthias Ringwald break;
196*1663a09dSMatthias Ringwald
197*1663a09dSMatthias Ringwald default:
198*1663a09dSMatthias Ringwald break;
199*1663a09dSMatthias Ringwald }
200*1663a09dSMatthias Ringwald }
201*1663a09dSMatthias Ringwald
ias_client_serialize_characteristic_value_for_write(ias_client_connection_t * connection,uint8_t ** out_value)202*1663a09dSMatthias Ringwald static uint16_t ias_client_serialize_characteristic_value_for_write(ias_client_connection_t * connection, uint8_t ** out_value){
203*1663a09dSMatthias Ringwald uint16_t characteristic_uuid16 = gatt_service_client_characteristic_uuid16_for_index(&ias_client,
204*1663a09dSMatthias Ringwald connection->characteristic_index);
205*1663a09dSMatthias Ringwald *out_value = (uint8_t *)connection->write_buffer;
206*1663a09dSMatthias Ringwald
207*1663a09dSMatthias Ringwald switch (characteristic_uuid16){
208*1663a09dSMatthias Ringwald case ORG_BLUETOOTH_CHARACTERISTIC_ALERT_LEVEL:
209*1663a09dSMatthias Ringwald return 1;
210*1663a09dSMatthias Ringwald default:
211*1663a09dSMatthias Ringwald btstack_assert(false);
212*1663a09dSMatthias Ringwald break;
213*1663a09dSMatthias Ringwald }
214*1663a09dSMatthias Ringwald return 0;
215*1663a09dSMatthias Ringwald }
216*1663a09dSMatthias Ringwald
ias_client_run_for_connection(void * context)217*1663a09dSMatthias Ringwald static void ias_client_run_for_connection(void * context){
218*1663a09dSMatthias Ringwald uint16_t connection_id = (uint16_t)(uintptr_t)context;
219*1663a09dSMatthias Ringwald ias_client_connection_t * connection = ias_client_get_connection_for_cid(connection_id);
220*1663a09dSMatthias Ringwald
221*1663a09dSMatthias Ringwald btstack_assert(connection != NULL);
222*1663a09dSMatthias Ringwald uint16_t value_length;
223*1663a09dSMatthias Ringwald uint8_t * value;
224*1663a09dSMatthias Ringwald
225*1663a09dSMatthias Ringwald switch (connection->state){
226*1663a09dSMatthias Ringwald case IMMEDIATE_ALERT_SERVICE_CLIENT_STATE_W2_WRITE_WITHOUT_RESPONSE_CHARACTERISTIC_VALUE:
227*1663a09dSMatthias Ringwald connection->state = IMMEDIATE_ALERT_SERVICE_CLIENT_STATE_READY;
228*1663a09dSMatthias Ringwald
229*1663a09dSMatthias Ringwald value_length = ias_client_serialize_characteristic_value_for_write(connection, &value);
230*1663a09dSMatthias Ringwald gatt_client_write_value_of_characteristic_without_response(
231*1663a09dSMatthias Ringwald gatt_service_client_get_con_handle(&connection->basic_connection),
232*1663a09dSMatthias Ringwald ias_client_value_handle_for_index(connection),
233*1663a09dSMatthias Ringwald value_length, value);
234*1663a09dSMatthias Ringwald
235*1663a09dSMatthias Ringwald break;
236*1663a09dSMatthias Ringwald
237*1663a09dSMatthias Ringwald default:
238*1663a09dSMatthias Ringwald break;
239*1663a09dSMatthias Ringwald }
240*1663a09dSMatthias Ringwald }
241*1663a09dSMatthias Ringwald
immediate_alert_service_client_init(void)242*1663a09dSMatthias Ringwald void immediate_alert_service_client_init(void){
243*1663a09dSMatthias Ringwald gatt_service_client_register_client(&ias_client, &ias_client_packet_handler_internal, ias_uuid16s, sizeof(ias_uuid16s)/sizeof(uint16_t));
244*1663a09dSMatthias Ringwald
245*1663a09dSMatthias Ringwald ias_client_handle_can_send_now.callback = &ias_client_run_for_connection;
246*1663a09dSMatthias Ringwald }
247*1663a09dSMatthias Ringwald
immediate_alert_service_client_connect(hci_con_handle_t con_handle,btstack_packet_handler_t packet_handler,ias_client_connection_t * ias_connection,uint16_t * ias_cid)248*1663a09dSMatthias Ringwald uint8_t immediate_alert_service_client_connect(hci_con_handle_t con_handle,
249*1663a09dSMatthias Ringwald btstack_packet_handler_t packet_handler,
250*1663a09dSMatthias Ringwald ias_client_connection_t * ias_connection,
251*1663a09dSMatthias Ringwald uint16_t * ias_cid
252*1663a09dSMatthias Ringwald ){
253*1663a09dSMatthias Ringwald
254*1663a09dSMatthias Ringwald btstack_assert(packet_handler != NULL);
255*1663a09dSMatthias Ringwald btstack_assert(ias_connection != NULL);
256*1663a09dSMatthias Ringwald
257*1663a09dSMatthias Ringwald *ias_cid = 0;
258*1663a09dSMatthias Ringwald
259*1663a09dSMatthias Ringwald ias_connection->state = IMMEDIATE_ALERT_SERVICE_CLIENT_STATE_W4_CONNECTION;
260*1663a09dSMatthias Ringwald ias_connection->packet_handler = packet_handler;
261*1663a09dSMatthias Ringwald
262*1663a09dSMatthias Ringwald uint8_t status = gatt_service_client_connect_primary_service_with_uuid16(con_handle,
263*1663a09dSMatthias Ringwald &ias_client,
264*1663a09dSMatthias Ringwald &ias_connection->basic_connection,
265*1663a09dSMatthias Ringwald ORG_BLUETOOTH_SERVICE_IMMEDIATE_ALERT, 0,
266*1663a09dSMatthias Ringwald ias_connection->characteristics_storage,
267*1663a09dSMatthias Ringwald IMMEDIATE_ALERT_SERVICE_CLIENT_NUM_CHARACTERISTICS);
268*1663a09dSMatthias Ringwald
269*1663a09dSMatthias Ringwald if (status == ERROR_CODE_SUCCESS){
270*1663a09dSMatthias Ringwald ias_client_add_connection(ias_connection);
271*1663a09dSMatthias Ringwald *ias_cid = ias_connection->basic_connection.cid;
272*1663a09dSMatthias Ringwald }
273*1663a09dSMatthias Ringwald
274*1663a09dSMatthias Ringwald return status;
275*1663a09dSMatthias Ringwald }
276*1663a09dSMatthias Ringwald
immediate_alert_service_client_write_alert_level(uint16_t ias_cid,ias_alert_level_t alert_level)277*1663a09dSMatthias Ringwald uint8_t immediate_alert_service_client_write_alert_level(uint16_t ias_cid, ias_alert_level_t alert_level){
278*1663a09dSMatthias Ringwald ias_client_connection_t * connection = ias_client_get_connection_for_cid(ias_cid);
279*1663a09dSMatthias Ringwald if (connection == NULL){
280*1663a09dSMatthias Ringwald return ERROR_CODE_UNKNOWN_CONNECTION_IDENTIFIER;
281*1663a09dSMatthias Ringwald }
282*1663a09dSMatthias Ringwald if (alert_level >= IAS_ALERT_LEVEL_RFU){
283*1663a09dSMatthias Ringwald return ERROR_CODE_PARAMETER_OUT_OF_MANDATORY_RANGE;
284*1663a09dSMatthias Ringwald }
285*1663a09dSMatthias Ringwald
286*1663a09dSMatthias Ringwald ias_client_characteristic_index_t index = IAS_CLIENT_CHARACTERISTIC_INDEX_ALERT_LEVEL;
287*1663a09dSMatthias Ringwald
288*1663a09dSMatthias Ringwald uint8_t status = ias_client_can_query_characteristic(connection, index);
289*1663a09dSMatthias Ringwald if (status != ERROR_CODE_SUCCESS){
290*1663a09dSMatthias Ringwald return status;
291*1663a09dSMatthias Ringwald }
292*1663a09dSMatthias Ringwald
293*1663a09dSMatthias Ringwald connection->write_buffer[0] = (uint8_t)alert_level;
294*1663a09dSMatthias Ringwald return ias_client_request_write_without_response_characteristic(connection, index);
295*1663a09dSMatthias Ringwald }
296*1663a09dSMatthias Ringwald
immediate_alert_service_client_disconnect(uint16_t ias_cid)297*1663a09dSMatthias Ringwald uint8_t immediate_alert_service_client_disconnect(uint16_t ias_cid){
298*1663a09dSMatthias Ringwald ias_client_connection_t * connection = ias_client_get_connection_for_cid(ias_cid);
299*1663a09dSMatthias Ringwald if (connection == NULL){
300*1663a09dSMatthias Ringwald return ERROR_CODE_UNKNOWN_CONNECTION_IDENTIFIER;
301*1663a09dSMatthias Ringwald }
302*1663a09dSMatthias Ringwald return gatt_service_client_disconnect(&connection->basic_connection);
303*1663a09dSMatthias Ringwald }
304*1663a09dSMatthias Ringwald
immediate_alert_service_client_deinit(void)305*1663a09dSMatthias Ringwald void immediate_alert_service_client_deinit(void){
306*1663a09dSMatthias Ringwald gatt_service_client_unregister_client(&ias_client);
307*1663a09dSMatthias Ringwald }
308*1663a09dSMatthias Ringwald
309