1/******************************************************************************
2 *
3 *  Copyright (C) 2014 Google, Inc.
4 *
5 *  Licensed under the Apache License, Version 2.0 (the "License");
6 *  you may not use this file except in compliance with the License.
7 *  You may obtain a copy of the License at:
8 *
9 *  http://www.apache.org/licenses/LICENSE-2.0
10 *
11 *  Unless required by applicable law or agreed to in writing, software
12 *  distributed under the License is distributed on an "AS IS" BASIS,
13 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 *  See the License for the specific language governing permissions and
15 *  limitations under the License.
16 *
17 ******************************************************************************/
18
19#include "base.h"
20#include "support/callbacks.h"
21
22// Bluetooth callbacks
23void acl_state_changed(bt_status_t status, bt_bdaddr_t *remote_bd_addr, bt_acl_state_t state);
24void adapter_properties(bt_status_t status, int num_properties, bt_property_t *properties);
25void adapter_state_changed(bt_state_t state);
26void bond_state_changed(bt_status_t status, bt_bdaddr_t *remote_bd_addr, bt_bond_state_t state);
27
28void device_found(int num_properties, bt_property_t *properties);
29void discovery_state_changed(bt_discovery_state_t state);
30void remote_device_properties(bt_status_t status, bt_bdaddr_t *bd_addr, int num_properties, bt_property_t *properties);
31void ssp_request(bt_bdaddr_t *remote_bd_addr, bt_bdname_t *bd_name, uint32_t cod, bt_ssp_variant_t pairing_variant, uint32_t pass_key);
32void thread_evt(bt_cb_thread_evt evt);
33
34// PAN callbacks
35void pan_connection_state_changed(btpan_connection_state_t state, bt_status_t error, const bt_bdaddr_t *bd_addr, int local_role, int remote_role);
36void pan_control_state_changed(btpan_control_state_t state, int local_role, bt_status_t error, const char *ifname);
37
38// GATT client callbacks
39void btgattc_register_app_cb(int status, int clientIf, bt_uuid_t *app_uuid);
40void btgattc_scan_result_cb(bt_bdaddr_t* bda, int rssi, uint8_t* adv_data);
41void btgattc_open_cb(int conn_id, int status, int clientIf, bt_bdaddr_t* bda);
42void btgattc_close_cb(int conn_id, int status, int clientIf, bt_bdaddr_t* bda);
43void btgattc_search_complete_cb(int conn_id, int status);
44void btgattc_search_result_cb(int conn_id, btgatt_srvc_id_t *srvc_id);
45void btgattc_get_characteristic_cb(int conn_id, int status, btgatt_srvc_id_t *srvc_id, btgatt_gatt_id_t *char_id, int char_prop);
46void btgattc_get_descriptor_cb(int conn_id, int status, btgatt_srvc_id_t *srvc_id, btgatt_gatt_id_t *char_id, btgatt_gatt_id_t *descr_id);
47void btgattc_get_included_service_cb(int conn_id, int status, btgatt_srvc_id_t *srvc_id, btgatt_srvc_id_t *incl_srvc_id);
48void btgattc_register_for_notification_cb(int conn_id, int registered, int status, btgatt_srvc_id_t *srvc_id, btgatt_gatt_id_t *char_id);
49void btgattc_notify_cb(int conn_id, btgatt_notify_params_t *p_data);
50void btgattc_read_characteristic_cb(int conn_id, int status, btgatt_read_params_t *p_data);
51void btgattc_write_characteristic_cb(int conn_id, int status, btgatt_write_params_t *p_data);
52void btgattc_execute_write_cb(int conn_id, int status);
53void btgattc_read_descriptor_cb(int conn_id, int status, btgatt_read_params_t *p_data);
54void btgattc_write_descriptor_cb(int conn_id, int status, btgatt_write_params_t *p_data);
55void btgattc_remote_rssi_cb(int client_if,bt_bdaddr_t* bda, int rssi, int status);
56void btgattc_advertise_cb(int status, int client_if);
57
58// GATT server callbacks
59void btgatts_register_app_cb(int status, int server_if, bt_uuid_t *uuid);
60void btgatts_connection_cb(int conn_id, int server_if, int connected, bt_bdaddr_t *bda);
61void btgatts_service_added_cb(int status, int server_if, btgatt_srvc_id_t *srvc_id, int srvc_handle);
62void btgatts_included_service_added_cb(int status, int server_if, int srvc_handle, int incl_srvc_handle);
63void btgatts_characteristic_added_cb(int status, int server_if, bt_uuid_t *char_id, int srvc_handle, int char_handle);
64void btgatts_descriptor_added_cb(int status, int server_if, bt_uuid_t *descr_id, int srvc_handle, int descr_handle);
65void btgatts_service_started_cb(int status, int server_if, int srvc_handle);
66void btgatts_service_stopped_cb(int status, int server_if, int srvc_handle);
67void btgatts_service_deleted_cb(int status, int server_if, int srvc_handle);
68void btgatts_request_read_cb(int conn_id, int trans_id, bt_bdaddr_t *bda, int attr_handle, int offset, bool is_long);
69void btgatts_request_write_cb(int conn_id, int trans_id, bt_bdaddr_t *bda, int attr_handle, int offset, int length, bool need_rsp, bool is_prep, uint8_t* value);
70void btgatts_request_exec_write_cb(int conn_id, int trans_id, bt_bdaddr_t *bda, int exec_write);
71void btgatts_response_confirmation_cb(int status, int handle);
72
73static struct {
74  const char *name;
75  sem_t semaphore;
76} callback_data[] = {
77  // Adapter callbacks
78  { "adapter_state_changed" },
79  { "adapter_properties" },
80  { "remote_device_properties" },
81  { "device_found" },
82  { "discovery_state_changed" },
83  {},
84  { "ssp_request" },
85  { "bond_state_changed" },
86  { "acl_state_changed" },
87  { "thread_evt" },
88  {},
89  {},
90
91  // PAN callbacks
92  { "pan_control_state_changed" },
93  { "pan_connection_state_changed" },
94
95  // GATT client callbacks
96  { "btgattc_register_app_cb" },
97  { "btgattc_scan_result_cb" },
98  { "btgattc_open_cb" },
99  { "btgattc_close_cb" },
100  { "btgattc_search_complete_cb" },
101  { "btgattc_search_result_cb" },
102  { "btgattc_get_characteristic_cb" },
103  { "btgattc_get_descriptor_cb" },
104  { "btgattc_get_included_service_cb" },
105  { "btgattc_register_for_notification_cb" },
106  { "btgattc_notify_cb" },
107  { "btgattc_read_characteristic_cb" },
108  { "btgattc_write_characteristic_cb" },
109  { "btgattc_execute_write_cb" },
110  { "btgattc_read_descriptor_cb" },
111  { "btgattc_write_descriptor_cb" },
112  { "btgattc_remote_rssi_cb" },
113  { "btgattc_advertise_cb" },
114  {},
115  {},
116  {},
117  {},
118  {},
119  {},
120
121  // GATT server callbacks
122  { "btgatts_register_app_cb" },
123  { "btgatts_connection_cb" },
124  { "btgatts_service_added_cb" },
125  { "btgatts_included_service_added_cb" },
126  { "btgatts_characteristic_added_cb" },
127  { "btgatts_descriptor_added_cb" },
128  { "btgatts_service_started_cb" },
129  { "btgatts_service_stopped_cb" },
130  { "btgatts_service_deleted_cb" },
131  { "btgatts_request_read_cb" },
132  { "btgatts_request_write_cb" },
133  { "btgatts_request_exec_write_cb" },
134  { "btgatts_response_confirmation_cb" },
135
136};
137
138static bt_callbacks_t bt_callbacks = {
139  sizeof(bt_callbacks_t),
140  adapter_state_changed,     // adapter_state_changed_callback
141  adapter_properties,        // adapter_properties_callback
142  remote_device_properties,  // remote_device_properties_callback
143  device_found,              // device_found_callback
144  discovery_state_changed,   // discovery_state_changed_callback
145  NULL,                      // pin_request_callback
146  ssp_request,               // ssp_request_callback
147  bond_state_changed,        // bond_state_changed_callback
148  acl_state_changed,         // acl_state_changed_callback
149  thread_evt,                // callback_thread_event
150  NULL,                      // dut_mode_recv_callback
151  NULL,                      // le_test_mode_callback
152  NULL,
153};
154
155static btpan_callbacks_t pan_callbacks = {
156  sizeof(btpan_callbacks_t),
157  pan_control_state_changed,     // btpan_control_state_callback
158  pan_connection_state_changed,  // btpan_connection_state_callback
159};
160
161static const btgatt_client_callbacks_t gatt_client_callbacks = {
162  btgattc_register_app_cb,
163  btgattc_scan_result_cb,
164  btgattc_open_cb,
165  btgattc_close_cb,
166  btgattc_search_complete_cb,
167  btgattc_search_result_cb,
168  btgattc_get_characteristic_cb,
169  btgattc_get_descriptor_cb,
170  btgattc_get_included_service_cb,
171  btgattc_register_for_notification_cb,
172  btgattc_notify_cb,
173  btgattc_read_characteristic_cb,
174  btgattc_write_characteristic_cb,
175  btgattc_read_descriptor_cb,
176  btgattc_write_descriptor_cb,
177  btgattc_execute_write_cb,
178  btgattc_remote_rssi_cb,
179  btgattc_advertise_cb,
180  NULL,
181  NULL,
182  NULL,
183  NULL,
184  NULL,
185  NULL,
186};
187
188static const btgatt_server_callbacks_t gatt_server_callbacks = {
189  btgatts_register_app_cb,
190  btgatts_connection_cb,
191  btgatts_service_added_cb,
192  btgatts_included_service_added_cb,
193  btgatts_characteristic_added_cb,
194  btgatts_descriptor_added_cb,
195  btgatts_service_started_cb,
196  btgatts_service_stopped_cb,
197  btgatts_service_deleted_cb,
198  btgatts_request_read_cb,
199  btgatts_request_write_cb,
200  btgatts_request_exec_write_cb,
201  btgatts_response_confirmation_cb
202};
203
204static btgatt_callbacks_t gatt_callbacks = {
205  sizeof(btgatt_callbacks_t),
206  &gatt_client_callbacks,
207  &gatt_server_callbacks
208};
209
210void callbacks_init() {
211  for (size_t i = 0; i < ARRAY_SIZE(callback_data); ++i) {
212    sem_init(&callback_data[i].semaphore, 0, 0);
213  }
214}
215
216void callbacks_cleanup() {
217  for (size_t i = 0; i < ARRAY_SIZE(callback_data); ++i) {
218    sem_destroy(&callback_data[i].semaphore);
219  }
220}
221
222bt_callbacks_t *callbacks_get_adapter_struct() {
223  return &bt_callbacks;
224}
225
226btpan_callbacks_t *callbacks_get_pan_struct() {
227  return &pan_callbacks;
228}
229
230btgatt_callbacks_t *callbacks_get_gatt_struct() {
231  return &gatt_callbacks;
232}
233
234sem_t *callbacks_get_semaphore(const char *name) {
235  for (size_t i = 0; i < ARRAY_SIZE(callback_data); ++i) {
236    if (callback_data[i].name && !strcmp(name, callback_data[i].name)) {
237      return &callback_data[i].semaphore;
238    }
239  }
240  return NULL;
241}
242