someone use editor in windows, so use "LF" in your editor, please.
-/******************************************************************************\r
- *\r
- * Copyright (C) 2014 Google, Inc.\r
- *\r
- * Licensed under the Apache License, Version 2.0 (the "License");\r
- * you may not use this file except in compliance with the License.\r
- * You may obtain a copy of the License at:\r
- *\r
- * http://www.apache.org/licenses/LICENSE-2.0\r
- *\r
- * Unless required by applicable law or agreed to in writing, software\r
- * distributed under the License is distributed on an "AS IS" BASIS,\r
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
- * See the License for the specific language governing permissions and\r
- * limitations under the License.\r
- *\r
- ******************************************************************************/\r
-#include <stdbool.h>\r
-#include "bt_trace.h"\r
-#include "bdaddr.h"\r
-#include "bt_types.h"\r
-#include "controller.h"\r
-#include "event_mask.h"\r
-#include "hcimsgs.h"\r
-#include "hci_layer.h"\r
-#include "hci_packet_factory.h"\r
-#include "hci_packet_parser.h"\r
-#include "btm_ble_api.h"\r
-#include "version.h"\r
-#include "future.h"\r
-\r
-const bt_event_mask_t BLE_EVENT_MASK = { "\x00\x00\x00\x00\x00\x00\x06\x7f" };\r
-\r
-#if (BLE_INCLUDED)\r
-const bt_event_mask_t CLASSIC_EVENT_MASK = { HCI_DUMO_EVENT_MASK_EXT };\r
-#else\r
-const bt_event_mask_t CLASSIC_EVENT_MASK = { HCI_LISBON_EVENT_MASK_EXT };\r
-#endif\r
-\r
-// TODO(zachoverflow): factor out into common module\r
-const uint8_t SCO_HOST_BUFFER_SIZE = 0xff;\r
-\r
-#define HCI_SUPPORTED_COMMANDS_ARRAY_SIZE 64\r
-#define MAX_FEATURES_CLASSIC_PAGE_COUNT 3\r
-#define BLE_SUPPORTED_STATES_SIZE 8\r
-#define BLE_SUPPORTED_FEATURES_SIZE 8\r
-\r
-static const hci_t *hci;\r
-static const hci_packet_factory_t *packet_factory;\r
-static const hci_packet_parser_t *packet_parser;\r
-\r
-static bt_bdaddr_t address;\r
-static bt_version_t bt_version;\r
-\r
-static uint8_t supported_commands[HCI_SUPPORTED_COMMANDS_ARRAY_SIZE];\r
-static bt_device_features_t features_classic[MAX_FEATURES_CLASSIC_PAGE_COUNT];\r
-static uint8_t last_features_classic_page_index;\r
-\r
-static uint16_t acl_data_size_classic;\r
-static uint16_t acl_data_size_ble;\r
-static uint16_t acl_buffer_count_classic;\r
-static uint8_t acl_buffer_count_ble;\r
-\r
-static uint8_t ble_white_list_size;\r
-static uint8_t ble_resolving_list_max_size;\r
-static uint8_t ble_supported_states[BLE_SUPPORTED_STATES_SIZE];\r
-static bt_device_features_t features_ble;\r
-static uint16_t ble_suggested_default_data_length;\r
-\r
-static bool readable;\r
-static bool ble_supported;\r
-static bool simple_pairing_supported;\r
-static bool secure_connections_supported;\r
-\r
-#define AWAIT_COMMAND(command) future_await(hci->transmit_command_futured(command))\r
-\r
-// Module lifecycle functions\r
-\r
-static void start_up(void) {\r
- BT_HDR *response;\r
-\r
- // Send the initial reset command\r
- response = AWAIT_COMMAND(packet_factory->make_reset());\r
- packet_parser->parse_generic_command_complete(response);\r
-\r
- // Request the classic buffer size next\r
- response = AWAIT_COMMAND(packet_factory->make_read_buffer_size());\r
- packet_parser->parse_read_buffer_size_response(\r
- response, &acl_data_size_classic, &acl_buffer_count_classic);\r
-\r
- // Tell the controller about our buffer sizes and buffer counts next\r
- // TODO(zachoverflow): factor this out. eww l2cap contamination. And why just a hardcoded 10?\r
- response = AWAIT_COMMAND(\r
- packet_factory->make_host_buffer_size(\r
- L2CAP_MTU_SIZE,\r
- SCO_HOST_BUFFER_SIZE,\r
- L2CAP_HOST_FC_ACL_BUFS,\r
- 10\r
- )\r
- );\r
-\r
- packet_parser->parse_generic_command_complete(response);\r
-\r
- // Read the local version info off the controller next, including\r
- // information such as manufacturer and supported HCI version\r
- response = AWAIT_COMMAND(packet_factory->make_read_local_version_info());\r
- packet_parser->parse_read_local_version_info_response(response, &bt_version);\r
-\r
- // Read the bluetooth address off the controller next\r
- response = AWAIT_COMMAND(packet_factory->make_read_bd_addr());\r
- packet_parser->parse_read_bd_addr_response(response, &address);\r
-\r
- // Request the controller's supported commands next\r
- response = AWAIT_COMMAND(packet_factory->make_read_local_supported_commands());\r
- packet_parser->parse_read_local_supported_commands_response(\r
- response,\r
- supported_commands,\r
- HCI_SUPPORTED_COMMANDS_ARRAY_SIZE\r
- );\r
-\r
- // Read page 0 of the controller features next\r
- uint8_t page_number = 0;\r
- response = AWAIT_COMMAND(packet_factory->make_read_local_extended_features(page_number));\r
- packet_parser->parse_read_local_extended_features_response(\r
- response,\r
- &page_number,\r
- &last_features_classic_page_index,\r
- features_classic,\r
- MAX_FEATURES_CLASSIC_PAGE_COUNT\r
- );\r
-\r
- assert(page_number == 0);\r
- page_number++;\r
-\r
- // Inform the controller what page 0 features we support, based on what\r
- // it told us it supports. We need to do this first before we request the\r
- // next page, because the controller's response for page 1 may be\r
- // dependent on what we configure from page 0\r
- simple_pairing_supported = HCI_SIMPLE_PAIRING_SUPPORTED(features_classic[0].as_array);\r
- if (simple_pairing_supported) {\r
- response = AWAIT_COMMAND(packet_factory->make_write_simple_pairing_mode(HCI_SP_MODE_ENABLED));\r
- packet_parser->parse_generic_command_complete(response);\r
- }\r
-\r
-#if (BLE_INCLUDED == TRUE)\r
- if (HCI_LE_SPT_SUPPORTED(features_classic[0].as_array)) {\r
- uint8_t simultaneous_le_host = HCI_SIMUL_LE_BREDR_SUPPORTED(features_classic[0].as_array) ? BTM_BLE_SIMULTANEOUS_HOST : 0;\r
- response = AWAIT_COMMAND(\r
- packet_factory->make_ble_write_host_support(BTM_BLE_HOST_SUPPORT, simultaneous_le_host)\r
- );\r
-\r
- packet_parser->parse_generic_command_complete(response);\r
- }\r
-#endif\r
-\r
- // Done telling the controller about what page 0 features we support\r
- // Request the remaining feature pages\r
- while (page_number <= last_features_classic_page_index &&\r
- page_number < MAX_FEATURES_CLASSIC_PAGE_COUNT) {\r
- response = AWAIT_COMMAND(packet_factory->make_read_local_extended_features(page_number));\r
- packet_parser->parse_read_local_extended_features_response(\r
- response,\r
- &page_number,\r
- &last_features_classic_page_index,\r
- features_classic,\r
- MAX_FEATURES_CLASSIC_PAGE_COUNT\r
- );\r
-\r
- page_number++;\r
- }\r
-\r
-#if (SC_MODE_INCLUDED == TRUE)\r
- secure_connections_supported = HCI_SC_CTRLR_SUPPORTED(features_classic[2].as_array);\r
- if (secure_connections_supported) {\r
- response = AWAIT_COMMAND(packet_factory->make_write_secure_connections_host_support(HCI_SC_MODE_ENABLED));\r
- packet_parser->parse_generic_command_complete(response);\r
- }\r
-#endif\r
-\r
-#if (BLE_INCLUDED == TRUE)\r
- ble_supported = last_features_classic_page_index >= 1 && HCI_LE_HOST_SUPPORTED(features_classic[1].as_array);\r
- if (ble_supported) {\r
- // Request the ble white list size next\r
- response = AWAIT_COMMAND(packet_factory->make_ble_read_white_list_size());\r
- packet_parser->parse_ble_read_white_list_size_response(response, &ble_white_list_size);\r
-\r
- // Request the ble buffer size next\r
- response = AWAIT_COMMAND(packet_factory->make_ble_read_buffer_size());\r
- packet_parser->parse_ble_read_buffer_size_response(\r
- response,\r
- &acl_data_size_ble,\r
- &acl_buffer_count_ble\r
- );\r
-\r
- // Response of 0 indicates ble has the same buffer size as classic\r
- if (acl_data_size_ble == 0)\r
- acl_data_size_ble = acl_data_size_classic;\r
-\r
- // Request the ble supported states next\r
- response = AWAIT_COMMAND(packet_factory->make_ble_read_supported_states());\r
- packet_parser->parse_ble_read_supported_states_response(\r
- response,\r
- ble_supported_states,\r
- sizeof(ble_supported_states)\r
- );\r
-\r
- // Request the ble supported features next\r
- response = AWAIT_COMMAND(packet_factory->make_ble_read_local_supported_features());\r
- packet_parser->parse_ble_read_local_supported_features_response(\r
- response,\r
- &features_ble\r
- );\r
-\r
- if (HCI_LE_ENHANCED_PRIVACY_SUPPORTED(features_ble.as_array)) {\r
- response = AWAIT_COMMAND(packet_factory->make_ble_read_resolving_list_size());\r
- packet_parser->parse_ble_read_resolving_list_size_response(\r
- response,\r
- &ble_resolving_list_max_size);\r
- }\r
-\r
- if (HCI_LE_DATA_LEN_EXT_SUPPORTED(features_ble.as_array)) {\r
- response = AWAIT_COMMAND(packet_factory->make_ble_read_suggested_default_data_length());\r
- packet_parser->parse_ble_read_suggested_default_data_length_response(\r
- response,\r
- &ble_suggested_default_data_length);\r
- }\r
-\r
- // Set the ble event mask next\r
- response = AWAIT_COMMAND(packet_factory->make_ble_set_event_mask(&BLE_EVENT_MASK));\r
- packet_parser->parse_generic_command_complete(response);\r
- }\r
-#endif\r
-\r
- if (simple_pairing_supported) {\r
- response = AWAIT_COMMAND(packet_factory->make_set_event_mask(&CLASSIC_EVENT_MASK));\r
- packet_parser->parse_generic_command_complete(response);\r
- }\r
-\r
- readable = true;\r
- // return future_new_immediate(FUTURE_SUCCESS);\r
- return;\r
-}\r
-\r
-static void shut_down(void) {\r
- readable = false;\r
-}\r
-\r
-static bool get_is_ready(void) {\r
- return readable;\r
-}\r
-\r
-static const bt_bdaddr_t *get_address(void) {\r
- assert(readable);\r
- return &address;\r
-}\r
-\r
-static const bt_version_t *get_bt_version(void) {\r
- assert(readable);\r
- return &bt_version;\r
-}\r
-\r
-// TODO(zachoverflow): hide inside, move decoder inside too\r
-static const bt_device_features_t *get_features_classic(int index) {\r
- assert(readable);\r
- assert(index < MAX_FEATURES_CLASSIC_PAGE_COUNT);\r
- return &features_classic[index];\r
-}\r
-\r
-static uint8_t get_last_features_classic_index(void) {\r
- assert(readable);\r
- return last_features_classic_page_index;\r
-}\r
-\r
-static const bt_device_features_t *get_features_ble(void) {\r
- assert(readable);\r
- assert(ble_supported);\r
- return &features_ble;\r
-}\r
-\r
-static const uint8_t *get_ble_supported_states(void) {\r
- assert(readable);\r
- assert(ble_supported);\r
- return ble_supported_states;\r
-}\r
-\r
-static bool supports_simple_pairing(void) {\r
- assert(readable);\r
- return simple_pairing_supported;\r
-}\r
-\r
-static bool supports_secure_connections(void) {\r
- assert(readable);\r
- return secure_connections_supported;\r
-}\r
-\r
-static bool supports_simultaneous_le_bredr(void) {\r
- assert(readable);\r
- return HCI_SIMUL_LE_BREDR_SUPPORTED(features_classic[0].as_array);\r
-}\r
-\r
-static bool supports_reading_remote_extended_features(void) {\r
- assert(readable);\r
- return HCI_READ_REMOTE_EXT_FEATURES_SUPPORTED(supported_commands);\r
-}\r
-\r
-static bool supports_interlaced_inquiry_scan(void) {\r
- assert(readable);\r
- return HCI_LMP_INTERLACED_INQ_SCAN_SUPPORTED(features_classic[0].as_array);\r
-}\r
-\r
-static bool supports_rssi_with_inquiry_results(void) {\r
- assert(readable);\r
- return HCI_LMP_INQ_RSSI_SUPPORTED(features_classic[0].as_array);\r
-}\r
-\r
-static bool supports_extended_inquiry_response(void) {\r
- assert(readable);\r
- return HCI_EXT_INQ_RSP_SUPPORTED(features_classic[0].as_array);\r
-}\r
-\r
-static bool supports_master_slave_role_switch(void) {\r
- assert(readable);\r
- return HCI_SWITCH_SUPPORTED(features_classic[0].as_array);\r
-}\r
-\r
-static bool supports_ble(void) {\r
- assert(readable);\r
- return ble_supported;\r
-}\r
-\r
-static bool supports_ble_privacy(void) {\r
- assert(readable);\r
- assert(ble_supported);\r
- return HCI_LE_ENHANCED_PRIVACY_SUPPORTED(features_ble.as_array);\r
-}\r
-\r
-static bool supports_ble_packet_extension(void) {\r
- assert(readable);\r
- assert(ble_supported);\r
- return HCI_LE_DATA_LEN_EXT_SUPPORTED(features_ble.as_array);\r
-}\r
-\r
-static bool supports_ble_connection_parameters_request(void) {\r
- assert(readable);\r
- assert(ble_supported);\r
- return HCI_LE_CONN_PARAM_REQ_SUPPORTED(features_ble.as_array);\r
-}\r
-\r
-static uint16_t get_acl_data_size_classic(void) {\r
- assert(readable);\r
- return acl_data_size_classic;\r
-}\r
-\r
-static uint16_t get_acl_data_size_ble(void) {\r
- assert(readable);\r
- assert(ble_supported);\r
- return acl_data_size_ble;\r
-}\r
-\r
-static uint16_t get_acl_packet_size_classic(void) {\r
- assert(readable);\r
- return acl_data_size_classic + HCI_DATA_PREAMBLE_SIZE;\r
-}\r
-\r
-static uint16_t get_acl_packet_size_ble(void) {\r
- assert(readable);\r
- return acl_data_size_ble + HCI_DATA_PREAMBLE_SIZE;\r
-}\r
-\r
-static uint16_t get_ble_suggested_default_data_length(void) {\r
- assert(readable);\r
- assert(ble_supported);\r
- return ble_suggested_default_data_length;\r
-}\r
-\r
-static uint16_t get_acl_buffer_count_classic(void) {\r
- assert(readable);\r
- return acl_buffer_count_classic;\r
-}\r
-\r
-static uint8_t get_acl_buffer_count_ble(void) {\r
- assert(readable);\r
- assert(ble_supported);\r
- return acl_buffer_count_ble;\r
-}\r
-\r
-static uint8_t get_ble_white_list_size(void) {\r
- assert(readable);\r
- assert(ble_supported);\r
- return ble_white_list_size;\r
-}\r
-\r
-static uint8_t get_ble_resolving_list_max_size(void) {\r
- assert(readable);\r
- assert(ble_supported);\r
- return ble_resolving_list_max_size;\r
-}\r
-\r
-static void set_ble_resolving_list_max_size(int resolving_list_max_size) {\r
- assert(readable);\r
- assert(ble_supported);\r
- ble_resolving_list_max_size = resolving_list_max_size;\r
-}\r
-\r
-static const controller_t interface = {\r
- start_up,\r
- shut_down,\r
- get_is_ready,\r
-\r
- get_address,\r
- get_bt_version,\r
-\r
- get_features_classic,\r
- get_last_features_classic_index,\r
-\r
- get_features_ble,\r
- get_ble_supported_states,\r
-\r
- supports_simple_pairing,\r
- supports_secure_connections,\r
- supports_simultaneous_le_bredr,\r
- supports_reading_remote_extended_features,\r
- supports_interlaced_inquiry_scan,\r
- supports_rssi_with_inquiry_results,\r
- supports_extended_inquiry_response,\r
- supports_master_slave_role_switch,\r
-\r
- supports_ble,\r
- supports_ble_packet_extension,\r
- supports_ble_connection_parameters_request,\r
- supports_ble_privacy,\r
-\r
- get_acl_data_size_classic,\r
- get_acl_data_size_ble,\r
-\r
- get_acl_packet_size_classic,\r
- get_acl_packet_size_ble,\r
- get_ble_suggested_default_data_length,\r
-\r
- get_acl_buffer_count_classic,\r
- get_acl_buffer_count_ble,\r
-\r
- get_ble_white_list_size,\r
-\r
- get_ble_resolving_list_max_size,\r
- set_ble_resolving_list_max_size\r
-};\r
-\r
-const controller_t *controller_get_interface() {\r
- static bool loaded = false;\r
- if (!loaded) {\r
- loaded = true;\r
-\r
- hci = hci_layer_get_interface();\r
- packet_factory = hci_packet_factory_get_interface();\r
- packet_parser = hci_packet_parser_get_interface();\r
- }\r
-\r
- return &interface;\r
-}\r
-\r
+/******************************************************************************
+ *
+ * Copyright (C) 2014 Google, Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ ******************************************************************************/
+#include <stdbool.h>
+#include "bt_trace.h"
+#include "bdaddr.h"
+#include "bt_types.h"
+#include "controller.h"
+#include "event_mask.h"
+#include "hcimsgs.h"
+#include "hci_layer.h"
+#include "hci_packet_factory.h"
+#include "hci_packet_parser.h"
+#include "btm_ble_api.h"
+#include "version.h"
+#include "future.h"
+
+const bt_event_mask_t BLE_EVENT_MASK = { "\x00\x00\x00\x00\x00\x00\x06\x7f" };
+
+#if (BLE_INCLUDED)
+const bt_event_mask_t CLASSIC_EVENT_MASK = { HCI_DUMO_EVENT_MASK_EXT };
+#else
+const bt_event_mask_t CLASSIC_EVENT_MASK = { HCI_LISBON_EVENT_MASK_EXT };
+#endif
+
+// TODO(zachoverflow): factor out into common module
+const uint8_t SCO_HOST_BUFFER_SIZE = 0xff;
+
+#define HCI_SUPPORTED_COMMANDS_ARRAY_SIZE 64
+#define MAX_FEATURES_CLASSIC_PAGE_COUNT 3
+#define BLE_SUPPORTED_STATES_SIZE 8
+#define BLE_SUPPORTED_FEATURES_SIZE 8
+
+static const hci_t *hci;
+static const hci_packet_factory_t *packet_factory;
+static const hci_packet_parser_t *packet_parser;
+
+static bt_bdaddr_t address;
+static bt_version_t bt_version;
+
+static uint8_t supported_commands[HCI_SUPPORTED_COMMANDS_ARRAY_SIZE];
+static bt_device_features_t features_classic[MAX_FEATURES_CLASSIC_PAGE_COUNT];
+static uint8_t last_features_classic_page_index;
+
+static uint16_t acl_data_size_classic;
+static uint16_t acl_data_size_ble;
+static uint16_t acl_buffer_count_classic;
+static uint8_t acl_buffer_count_ble;
+
+static uint8_t ble_white_list_size;
+static uint8_t ble_resolving_list_max_size;
+static uint8_t ble_supported_states[BLE_SUPPORTED_STATES_SIZE];
+static bt_device_features_t features_ble;
+static uint16_t ble_suggested_default_data_length;
+
+static bool readable;
+static bool ble_supported;
+static bool simple_pairing_supported;
+static bool secure_connections_supported;
+
+#define AWAIT_COMMAND(command) future_await(hci->transmit_command_futured(command))
+
+// Module lifecycle functions
+
+static void start_up(void) {
+ BT_HDR *response;
+
+ // Send the initial reset command
+ response = AWAIT_COMMAND(packet_factory->make_reset());
+ packet_parser->parse_generic_command_complete(response);
+
+ // Request the classic buffer size next
+ response = AWAIT_COMMAND(packet_factory->make_read_buffer_size());
+ packet_parser->parse_read_buffer_size_response(
+ response, &acl_data_size_classic, &acl_buffer_count_classic);
+
+ // Tell the controller about our buffer sizes and buffer counts next
+ // TODO(zachoverflow): factor this out. eww l2cap contamination. And why just a hardcoded 10?
+ response = AWAIT_COMMAND(
+ packet_factory->make_host_buffer_size(
+ L2CAP_MTU_SIZE,
+ SCO_HOST_BUFFER_SIZE,
+ L2CAP_HOST_FC_ACL_BUFS,
+ 10
+ )
+ );
+
+ packet_parser->parse_generic_command_complete(response);
+
+ // Read the local version info off the controller next, including
+ // information such as manufacturer and supported HCI version
+ response = AWAIT_COMMAND(packet_factory->make_read_local_version_info());
+ packet_parser->parse_read_local_version_info_response(response, &bt_version);
+
+ // Read the bluetooth address off the controller next
+ response = AWAIT_COMMAND(packet_factory->make_read_bd_addr());
+ packet_parser->parse_read_bd_addr_response(response, &address);
+
+ // Request the controller's supported commands next
+ response = AWAIT_COMMAND(packet_factory->make_read_local_supported_commands());
+ packet_parser->parse_read_local_supported_commands_response(
+ response,
+ supported_commands,
+ HCI_SUPPORTED_COMMANDS_ARRAY_SIZE
+ );
+
+ // Read page 0 of the controller features next
+ uint8_t page_number = 0;
+ response = AWAIT_COMMAND(packet_factory->make_read_local_extended_features(page_number));
+ packet_parser->parse_read_local_extended_features_response(
+ response,
+ &page_number,
+ &last_features_classic_page_index,
+ features_classic,
+ MAX_FEATURES_CLASSIC_PAGE_COUNT
+ );
+
+ assert(page_number == 0);
+ page_number++;
+
+ // Inform the controller what page 0 features we support, based on what
+ // it told us it supports. We need to do this first before we request the
+ // next page, because the controller's response for page 1 may be
+ // dependent on what we configure from page 0
+ simple_pairing_supported = HCI_SIMPLE_PAIRING_SUPPORTED(features_classic[0].as_array);
+ if (simple_pairing_supported) {
+ response = AWAIT_COMMAND(packet_factory->make_write_simple_pairing_mode(HCI_SP_MODE_ENABLED));
+ packet_parser->parse_generic_command_complete(response);
+ }
+
+#if (BLE_INCLUDED == TRUE)
+ if (HCI_LE_SPT_SUPPORTED(features_classic[0].as_array)) {
+ uint8_t simultaneous_le_host = HCI_SIMUL_LE_BREDR_SUPPORTED(features_classic[0].as_array) ? BTM_BLE_SIMULTANEOUS_HOST : 0;
+ response = AWAIT_COMMAND(
+ packet_factory->make_ble_write_host_support(BTM_BLE_HOST_SUPPORT, simultaneous_le_host)
+ );
+
+ packet_parser->parse_generic_command_complete(response);
+ }
+#endif
+
+ // Done telling the controller about what page 0 features we support
+ // Request the remaining feature pages
+ while (page_number <= last_features_classic_page_index &&
+ page_number < MAX_FEATURES_CLASSIC_PAGE_COUNT) {
+ response = AWAIT_COMMAND(packet_factory->make_read_local_extended_features(page_number));
+ packet_parser->parse_read_local_extended_features_response(
+ response,
+ &page_number,
+ &last_features_classic_page_index,
+ features_classic,
+ MAX_FEATURES_CLASSIC_PAGE_COUNT
+ );
+
+ page_number++;
+ }
+
+#if (SC_MODE_INCLUDED == TRUE)
+ secure_connections_supported = HCI_SC_CTRLR_SUPPORTED(features_classic[2].as_array);
+ if (secure_connections_supported) {
+ response = AWAIT_COMMAND(packet_factory->make_write_secure_connections_host_support(HCI_SC_MODE_ENABLED));
+ packet_parser->parse_generic_command_complete(response);
+ }
+#endif
+
+#if (BLE_INCLUDED == TRUE)
+ ble_supported = last_features_classic_page_index >= 1 && HCI_LE_HOST_SUPPORTED(features_classic[1].as_array);
+ if (ble_supported) {
+ // Request the ble white list size next
+ response = AWAIT_COMMAND(packet_factory->make_ble_read_white_list_size());
+ packet_parser->parse_ble_read_white_list_size_response(response, &ble_white_list_size);
+
+ // Request the ble buffer size next
+ response = AWAIT_COMMAND(packet_factory->make_ble_read_buffer_size());
+ packet_parser->parse_ble_read_buffer_size_response(
+ response,
+ &acl_data_size_ble,
+ &acl_buffer_count_ble
+ );
+
+ // Response of 0 indicates ble has the same buffer size as classic
+ if (acl_data_size_ble == 0)
+ acl_data_size_ble = acl_data_size_classic;
+
+ // Request the ble supported states next
+ response = AWAIT_COMMAND(packet_factory->make_ble_read_supported_states());
+ packet_parser->parse_ble_read_supported_states_response(
+ response,
+ ble_supported_states,
+ sizeof(ble_supported_states)
+ );
+
+ // Request the ble supported features next
+ response = AWAIT_COMMAND(packet_factory->make_ble_read_local_supported_features());
+ packet_parser->parse_ble_read_local_supported_features_response(
+ response,
+ &features_ble
+ );
+
+ if (HCI_LE_ENHANCED_PRIVACY_SUPPORTED(features_ble.as_array)) {
+ response = AWAIT_COMMAND(packet_factory->make_ble_read_resolving_list_size());
+ packet_parser->parse_ble_read_resolving_list_size_response(
+ response,
+ &ble_resolving_list_max_size);
+ }
+
+ if (HCI_LE_DATA_LEN_EXT_SUPPORTED(features_ble.as_array)) {
+ response = AWAIT_COMMAND(packet_factory->make_ble_read_suggested_default_data_length());
+ packet_parser->parse_ble_read_suggested_default_data_length_response(
+ response,
+ &ble_suggested_default_data_length);
+ }
+
+ // Set the ble event mask next
+ response = AWAIT_COMMAND(packet_factory->make_ble_set_event_mask(&BLE_EVENT_MASK));
+ packet_parser->parse_generic_command_complete(response);
+ }
+#endif
+
+ if (simple_pairing_supported) {
+ response = AWAIT_COMMAND(packet_factory->make_set_event_mask(&CLASSIC_EVENT_MASK));
+ packet_parser->parse_generic_command_complete(response);
+ }
+
+ readable = true;
+ // return future_new_immediate(FUTURE_SUCCESS);
+ return;
+}
+
+static void shut_down(void) {
+ readable = false;
+}
+
+static bool get_is_ready(void) {
+ return readable;
+}
+
+static const bt_bdaddr_t *get_address(void) {
+ assert(readable);
+ return &address;
+}
+
+static const bt_version_t *get_bt_version(void) {
+ assert(readable);
+ return &bt_version;
+}
+
+// TODO(zachoverflow): hide inside, move decoder inside too
+static const bt_device_features_t *get_features_classic(int index) {
+ assert(readable);
+ assert(index < MAX_FEATURES_CLASSIC_PAGE_COUNT);
+ return &features_classic[index];
+}
+
+static uint8_t get_last_features_classic_index(void) {
+ assert(readable);
+ return last_features_classic_page_index;
+}
+
+static const bt_device_features_t *get_features_ble(void) {
+ assert(readable);
+ assert(ble_supported);
+ return &features_ble;
+}
+
+static const uint8_t *get_ble_supported_states(void) {
+ assert(readable);
+ assert(ble_supported);
+ return ble_supported_states;
+}
+
+static bool supports_simple_pairing(void) {
+ assert(readable);
+ return simple_pairing_supported;
+}
+
+static bool supports_secure_connections(void) {
+ assert(readable);
+ return secure_connections_supported;
+}
+
+static bool supports_simultaneous_le_bredr(void) {
+ assert(readable);
+ return HCI_SIMUL_LE_BREDR_SUPPORTED(features_classic[0].as_array);
+}
+
+static bool supports_reading_remote_extended_features(void) {
+ assert(readable);
+ return HCI_READ_REMOTE_EXT_FEATURES_SUPPORTED(supported_commands);
+}
+
+static bool supports_interlaced_inquiry_scan(void) {
+ assert(readable);
+ return HCI_LMP_INTERLACED_INQ_SCAN_SUPPORTED(features_classic[0].as_array);
+}
+
+static bool supports_rssi_with_inquiry_results(void) {
+ assert(readable);
+ return HCI_LMP_INQ_RSSI_SUPPORTED(features_classic[0].as_array);
+}
+
+static bool supports_extended_inquiry_response(void) {
+ assert(readable);
+ return HCI_EXT_INQ_RSP_SUPPORTED(features_classic[0].as_array);
+}
+
+static bool supports_master_slave_role_switch(void) {
+ assert(readable);
+ return HCI_SWITCH_SUPPORTED(features_classic[0].as_array);
+}
+
+static bool supports_ble(void) {
+ assert(readable);
+ return ble_supported;
+}
+
+static bool supports_ble_privacy(void) {
+ assert(readable);
+ assert(ble_supported);
+ return HCI_LE_ENHANCED_PRIVACY_SUPPORTED(features_ble.as_array);
+}
+
+static bool supports_ble_packet_extension(void) {
+ assert(readable);
+ assert(ble_supported);
+ return HCI_LE_DATA_LEN_EXT_SUPPORTED(features_ble.as_array);
+}
+
+static bool supports_ble_connection_parameters_request(void) {
+ assert(readable);
+ assert(ble_supported);
+ return HCI_LE_CONN_PARAM_REQ_SUPPORTED(features_ble.as_array);
+}
+
+static uint16_t get_acl_data_size_classic(void) {
+ assert(readable);
+ return acl_data_size_classic;
+}
+
+static uint16_t get_acl_data_size_ble(void) {
+ assert(readable);
+ assert(ble_supported);
+ return acl_data_size_ble;
+}
+
+static uint16_t get_acl_packet_size_classic(void) {
+ assert(readable);
+ return acl_data_size_classic + HCI_DATA_PREAMBLE_SIZE;
+}
+
+static uint16_t get_acl_packet_size_ble(void) {
+ assert(readable);
+ return acl_data_size_ble + HCI_DATA_PREAMBLE_SIZE;
+}
+
+static uint16_t get_ble_suggested_default_data_length(void) {
+ assert(readable);
+ assert(ble_supported);
+ return ble_suggested_default_data_length;
+}
+
+static uint16_t get_acl_buffer_count_classic(void) {
+ assert(readable);
+ return acl_buffer_count_classic;
+}
+
+static uint8_t get_acl_buffer_count_ble(void) {
+ assert(readable);
+ assert(ble_supported);
+ return acl_buffer_count_ble;
+}
+
+static uint8_t get_ble_white_list_size(void) {
+ assert(readable);
+ assert(ble_supported);
+ return ble_white_list_size;
+}
+
+static uint8_t get_ble_resolving_list_max_size(void) {
+ assert(readable);
+ assert(ble_supported);
+ return ble_resolving_list_max_size;
+}
+
+static void set_ble_resolving_list_max_size(int resolving_list_max_size) {
+ assert(readable);
+ assert(ble_supported);
+ ble_resolving_list_max_size = resolving_list_max_size;
+}
+
+static const controller_t interface = {
+ start_up,
+ shut_down,
+ get_is_ready,
+
+ get_address,
+ get_bt_version,
+
+ get_features_classic,
+ get_last_features_classic_index,
+
+ get_features_ble,
+ get_ble_supported_states,
+
+ supports_simple_pairing,
+ supports_secure_connections,
+ supports_simultaneous_le_bredr,
+ supports_reading_remote_extended_features,
+ supports_interlaced_inquiry_scan,
+ supports_rssi_with_inquiry_results,
+ supports_extended_inquiry_response,
+ supports_master_slave_role_switch,
+
+ supports_ble,
+ supports_ble_packet_extension,
+ supports_ble_connection_parameters_request,
+ supports_ble_privacy,
+
+ get_acl_data_size_classic,
+ get_acl_data_size_ble,
+
+ get_acl_packet_size_classic,
+ get_acl_packet_size_ble,
+ get_ble_suggested_default_data_length,
+
+ get_acl_buffer_count_classic,
+ get_acl_buffer_count_ble,
+
+ get_ble_white_list_size,
+
+ get_ble_resolving_list_max_size,
+ set_ble_resolving_list_max_size
+};
+
+const controller_t *controller_get_interface() {
+ static bool loaded = false;
+ if (!loaded) {
+ loaded = true;
+
+ hci = hci_layer_get_interface();
+ packet_factory = hci_packet_factory_get_interface();
+ packet_parser = hci_packet_parser_get_interface();
+ }
+
+ return &interface;
+}
+
-/******************************************************************************\r
- *\r
- * Copyright (C) 2014 Google, Inc.\r
- *\r
- * Licensed under the Apache License, Version 2.0 (the "License");\r
- * you may not use this file except in compliance with the License.\r
- * You may obtain a copy of the License at:\r
- *\r
- * http://www.apache.org/licenses/LICENSE-2.0\r
- *\r
- * Unless required by applicable law or agreed to in writing, software\r
- * distributed under the License is distributed on an "AS IS" BASIS,\r
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
- * See the License for the specific language governing permissions and\r
- * limitations under the License.\r
- *\r
- ******************************************************************************/\r
-\r
-// #define LOG_TAG "bt_osi_future"\r
-// #include <assert.h>\r
-#include "bt_trace.h"\r
-\r
-#include "allocator.h"\r
-#include "future.h"\r
-#include "osi.h"\r
-//#include "osi/include/log.h"\r
-#include "osi_arch.h"\r
-\r
-struct future_t {\r
- bool ready_can_be_called;\r
- osi_sem_t semaphore; // NULL semaphore means immediate future\r
- void *result;\r
-};\r
-\r
-static void future_free(future_t *future);\r
-\r
-future_t *future_new(void) {\r
- future_t *ret = osi_calloc(sizeof(future_t));\r
- if (!ret) {\r
- LOG_ERROR("%s unable to allocate memory for return value.", __func__);\r
- goto error;\r
- }\r
-\r
- if (osi_sem_new(&ret->semaphore, 1, 0)!=0) {\r
- LOG_ERROR("%s unable to allocate memory for the semaphore.", __func__);\r
- goto error;\r
- }\r
-\r
- ret->ready_can_be_called = true;\r
- return ret;\r
-error:;\r
- future_free(ret);\r
- return NULL;\r
-}\r
-\r
-future_t *future_new_immediate(void *value) {\r
- future_t *ret = osi_calloc(sizeof(future_t));\r
- if (!ret) {\r
- LOG_ERROR("%s unable to allocate memory for return value.", __func__);\r
- goto error;\r
- }\r
-\r
- ret->result = value;\r
- ret->ready_can_be_called = false;\r
- return ret;\r
-error:;\r
- future_free(ret);\r
- return NULL;\r
-}\r
-\r
-void future_ready(future_t *future, void *value) {\r
- assert(future != NULL);\r
- assert(future->ready_can_be_called);\r
-\r
- future->ready_can_be_called = false;\r
- future->result = value;\r
- osi_sem_signal(&future->semaphore);\r
-}\r
-\r
-void *future_await(future_t *future) {\r
- assert(future != NULL);\r
-\r
- // If the future is immediate, it will not have a semaphore\r
- if (future->semaphore)\r
- osi_sem_wait(&future->semaphore, 0);\r
-\r
- void *result = future->result;\r
- future_free(future);\r
- return result;\r
-}\r
-\r
-static void future_free(future_t *future) {\r
- if (!future)\r
- return;\r
-\r
- if (!future->semaphore)\r
- osi_sem_free(&future->semaphore);\r
-\r
- osi_free(future);\r
-}\r
+/******************************************************************************
+ *
+ * Copyright (C) 2014 Google, Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ ******************************************************************************/
+
+// #define LOG_TAG "bt_osi_future"
+// #include <assert.h>
+#include "bt_trace.h"
+
+#include "allocator.h"
+#include "future.h"
+#include "osi.h"
+//#include "osi/include/log.h"
+#include "osi_arch.h"
+
+struct future_t {
+ bool ready_can_be_called;
+ osi_sem_t semaphore; // NULL semaphore means immediate future
+ void *result;
+};
+
+static void future_free(future_t *future);
+
+future_t *future_new(void) {
+ future_t *ret = osi_calloc(sizeof(future_t));
+ if (!ret) {
+ LOG_ERROR("%s unable to allocate memory for return value.", __func__);
+ goto error;
+ }
+
+ if (osi_sem_new(&ret->semaphore, 1, 0)!=0) {
+ LOG_ERROR("%s unable to allocate memory for the semaphore.", __func__);
+ goto error;
+ }
+
+ ret->ready_can_be_called = true;
+ return ret;
+error:;
+ future_free(ret);
+ return NULL;
+}
+
+future_t *future_new_immediate(void *value) {
+ future_t *ret = osi_calloc(sizeof(future_t));
+ if (!ret) {
+ LOG_ERROR("%s unable to allocate memory for return value.", __func__);
+ goto error;
+ }
+
+ ret->result = value;
+ ret->ready_can_be_called = false;
+ return ret;
+error:;
+ future_free(ret);
+ return NULL;
+}
+
+void future_ready(future_t *future, void *value) {
+ assert(future != NULL);
+ assert(future->ready_can_be_called);
+
+ future->ready_can_be_called = false;
+ future->result = value;
+ osi_sem_signal(&future->semaphore);
+}
+
+void *future_await(future_t *future) {
+ assert(future != NULL);
+
+ // If the future is immediate, it will not have a semaphore
+ if (future->semaphore)
+ osi_sem_wait(&future->semaphore, 0);
+
+ void *result = future->result;
+ future_free(future);
+ return result;
+}
+
+static void future_free(future_t *future) {
+ if (!future)
+ return;
+
+ if (!future->semaphore)
+ osi_sem_free(&future->semaphore);
+
+ osi_free(future);
+}
-/******************************************************************************\r
- *\r
- * Copyright (C) 2014 Google, Inc.\r
- *\r
- * Licensed under the Apache License, Version 2.0 (the "License");\r
- * you may not use this file except in compliance with the License.\r
- * You may obtain a copy of the License at:\r
- *\r
- * http://www.apache.org/licenses/LICENSE-2.0\r
- *\r
- * Unless required by applicable law or agreed to in writing, software\r
- * distributed under the License is distributed on an "AS IS" BASIS,\r
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
- * See the License for the specific language governing permissions and\r
- * limitations under the License.\r
- *\r
- ******************************************************************************/\r
-\r
-#ifndef __FUTURE_H__\r
-#define __FUTURE_H__\r
-// #pragma once\r
-\r
-typedef struct future_t future_t;\r
-\r
-#define FUTURE_SUCCESS ((void *)1)\r
-#define FUTURE_FAIL ((void *)0)\r
-\r
-// Constructs a new future_t object. Returns NULL on failure.\r
-future_t *future_new(void);\r
-\r
-// Constructs a new future_t object with an immediate |value|. No waiting will\r
-// occur in the call to |future_await| because the value is already present.\r
-// Returns NULL on failure.\r
-future_t *future_new_immediate(void *value);\r
-\r
-// Signals that the |future| is ready, passing |value| back to the context\r
-// waiting for the result. Must only be called once for every future.\r
-// |future| may not be NULL.\r
-void future_ready(future_t *future, void *value);\r
-\r
-// Waits for the |future| to be ready. Returns the value set in |future_ready|.\r
-// Frees the future before return. |future| may not be NULL.\r
-void *future_await(future_t *async_result);\r
-\r
-#endif /* __FUTURE_H__ */\r
+/******************************************************************************
+ *
+ * Copyright (C) 2014 Google, Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ ******************************************************************************/
+
+#ifndef __FUTURE_H__
+#define __FUTURE_H__
+// #pragma once
+
+typedef struct future_t future_t;
+
+#define FUTURE_SUCCESS ((void *)1)
+#define FUTURE_FAIL ((void *)0)
+
+// Constructs a new future_t object. Returns NULL on failure.
+future_t *future_new(void);
+
+// Constructs a new future_t object with an immediate |value|. No waiting will
+// occur in the call to |future_await| because the value is already present.
+// Returns NULL on failure.
+future_t *future_new_immediate(void *value);
+
+// Signals that the |future| is ready, passing |value| back to the context
+// waiting for the result. Must only be called once for every future.
+// |future| may not be NULL.
+void future_ready(future_t *future, void *value);
+
+// Waits for the |future| to be ready. Returns the value set in |future_ready|.
+// Frees the future before return. |future| may not be NULL.
+void *future_await(future_t *async_result);
+
+#endif /* __FUTURE_H__ */
-/**\r
- ****************************************************************************************\r
- *\r
- * @file bt_prf_sys_main.c\r
- *\r
- * @brief Application entry point\r
- *\r
- * Copyright (C) Espressif 2016\r
- * Created by Yulong at 2016/10/13\r
- *\r
- *\r
- ****************************************************************************************\r
- */\r
- \r
-#include "thread.h"\r
-#include "bt_prf_sys.h"\r
-#include "fixed_queue.h"\r
-#include "bt_prf_task.h"\r
-#include "gki.h"\r
-\r
-#include <string.h>\r
-\r
-\r
-tBT_PRF_SYS_CB bt_prf_sys_cb;\r
-fixed_queue_t *bt_profile_msg_queue;\r
-\r
-\r
-static const tBT_PRF_SYS_REG bt_prf_sys_reg =\r
-{\r
- NULL,\r
- NULL\r
-};\r
-\r
-\r
-void bt_prf_sys_init(void)\r
-{\r
- memset(&bt_prf_sys_cb,0,sizeof(tBT_PRF_SYS_CB));\r
-}\r
-\r
-\r
-/*******************************************************************************\r
-**\r
-** Function bt_prf_sys_event\r
-**\r
-** Description profile task event handler; called from task event handler.\r
-**\r
-**\r
-** Returns void\r
-**\r
-*******************************************************************************/\r
-void bt_prf_sys_event(BT_HDR *p_msg)\r
-{\r
- UINT8 id;\r
- BOOLEAN freebuf = TRUE;\r
-\r
- APPL_TRACE_EVENT("profile task got event 0x%x\n", p_msg->event);\r
-\r
- /* get subsystem id from event */\r
- id = (UINT8) (p_msg->event >> 8);\r
-\r
- /* verify id and call subsystem event handler */\r
- if ((id < PRF_ID_MAX) && (bt_prf_sys_cb.reg[id] != NULL))\r
- {\r
- freebuf = (*bt_prf_sys_cb.reg[id]->evt_hdlr)(p_msg);\r
- }\r
- else\r
- {\r
- APPL_TRACE_WARNING("profile task got unregistered event id %d\n", id);\r
- }\r
-\r
- if (freebuf)\r
- {\r
- GKI_freebuf(p_msg);\r
- }\r
-\r
-}\r
-\r
-\r
-/*******************************************************************************\r
-**\r
-** Function bt_prf_sys_register\r
-**\r
-** Description Called by other profile subsystems to register their event\r
-** handler.\r
-**\r
-** Parameters id:the Identifiers index of the profile\r
-** p_reg:the callback event which has been register to the profile task \r
-** Returns void\r
-**\r
-*******************************************************************************/\r
-void bt_prf_sys_register(UINT8 id, const tBT_PRF_SYS_REG *p_reg)\r
-{\r
- bt_prf_sys_cb.reg[id] = (tBT_PRF_SYS_REG *) p_reg;\r
- bt_prf_sys_cb.is_reg[id] = TRUE;\r
-}\r
-\r
-/*******************************************************************************\r
-**\r
-** Function bt_prf_sys_deregister\r
-**\r
-** Description Called by other profile subsystems to de-register\r
-** handler.\r
-**\r
-** Parameters id:Identifiers index of the profile\r
-** Returns void\r
-**\r
-*******************************************************************************/\r
-void bt_prf_sys_deregister(UINT8 id)\r
-{\r
- bt_prf_sys_cb.is_reg[id] = FALSE;\r
-}\r
-\r
-/*******************************************************************************\r
-**\r
-** Function bt_prf_sys_is_register\r
-**\r
-** Description Called by other profile subsystems to get registeration\r
-** status.\r
-**\r
-**\r
-** Returns void\r
-**\r
-*******************************************************************************/\r
-BOOLEAN bt_prf_sys_is_register(UINT8 id)\r
-{\r
- return bt_prf_sys_cb.is_reg[id];\r
-}\r
-\r
-/*******************************************************************************\r
-**\r
-** Function bt_prf_sys_sendmsg\r
-**\r
-** Description Send a GKI message to the profile task.\r
-**\r
-**\r
-** Returns void\r
-**\r
-*******************************************************************************/\r
-void bt_prf_sys_sendmsg(void *p_msg)\r
-{\r
- // There is a race condition that occurs if the stack is shut down while\r
- // there is a procedure in progress that can schedule a task via this\r
- // message queue. This causes |btu_bta_msg_queue| to get cleaned up before\r
- // it gets used here; hence we check for NULL before using it.\r
- if (bt_profile_msg_queue) {\r
- fixed_queue_enqueue(bt_profile_msg_queue, p_msg);\r
-\r
- bt_prf_task_post(SIG_PRF_WORK);\r
- }\r
-}\r
-\r
-\r
-\r
-\r
+/**
+ ****************************************************************************************
+ *
+ * @file bt_prf_sys_main.c
+ *
+ * @brief Application entry point
+ *
+ * Copyright (C) Espressif 2016
+ * Created by Yulong at 2016/10/13
+ *
+ *
+ ****************************************************************************************
+ */
+
+#include "thread.h"
+#include "bt_prf_sys.h"
+#include "fixed_queue.h"
+#include "bt_prf_task.h"
+#include "gki.h"
+
+#include <string.h>
+
+
+tBT_PRF_SYS_CB bt_prf_sys_cb;
+fixed_queue_t *bt_profile_msg_queue;
+
+
+static const tBT_PRF_SYS_REG bt_prf_sys_reg =
+{
+ NULL,
+ NULL
+};
+
+
+void bt_prf_sys_init(void)
+{
+ memset(&bt_prf_sys_cb,0,sizeof(tBT_PRF_SYS_CB));
+}
+
+
+/*******************************************************************************
+**
+** Function bt_prf_sys_event
+**
+** Description profile task event handler; called from task event handler.
+**
+**
+** Returns void
+**
+*******************************************************************************/
+void bt_prf_sys_event(BT_HDR *p_msg)
+{
+ UINT8 id;
+ BOOLEAN freebuf = TRUE;
+
+ APPL_TRACE_EVENT("profile task got event 0x%x\n", p_msg->event);
+
+ /* get subsystem id from event */
+ id = (UINT8) (p_msg->event >> 8);
+
+ /* verify id and call subsystem event handler */
+ if ((id < PRF_ID_MAX) && (bt_prf_sys_cb.reg[id] != NULL))
+ {
+ freebuf = (*bt_prf_sys_cb.reg[id]->evt_hdlr)(p_msg);
+ }
+ else
+ {
+ APPL_TRACE_WARNING("profile task got unregistered event id %d\n", id);
+ }
+
+ if (freebuf)
+ {
+ GKI_freebuf(p_msg);
+ }
+
+}
+
+
+/*******************************************************************************
+**
+** Function bt_prf_sys_register
+**
+** Description Called by other profile subsystems to register their event
+** handler.
+**
+** Parameters id:the Identifiers index of the profile
+** p_reg:the callback event which has been register to the profile task
+** Returns void
+**
+*******************************************************************************/
+void bt_prf_sys_register(UINT8 id, const tBT_PRF_SYS_REG *p_reg)
+{
+ bt_prf_sys_cb.reg[id] = (tBT_PRF_SYS_REG *) p_reg;
+ bt_prf_sys_cb.is_reg[id] = TRUE;
+}
+
+/*******************************************************************************
+**
+** Function bt_prf_sys_deregister
+**
+** Description Called by other profile subsystems to de-register
+** handler.
+**
+** Parameters id:Identifiers index of the profile
+** Returns void
+**
+*******************************************************************************/
+void bt_prf_sys_deregister(UINT8 id)
+{
+ bt_prf_sys_cb.is_reg[id] = FALSE;
+}
+
+/*******************************************************************************
+**
+** Function bt_prf_sys_is_register
+**
+** Description Called by other profile subsystems to get registeration
+** status.
+**
+**
+** Returns void
+**
+*******************************************************************************/
+BOOLEAN bt_prf_sys_is_register(UINT8 id)
+{
+ return bt_prf_sys_cb.is_reg[id];
+}
+
+/*******************************************************************************
+**
+** Function bt_prf_sys_sendmsg
+**
+** Description Send a GKI message to the profile task.
+**
+**
+** Returns void
+**
+*******************************************************************************/
+void bt_prf_sys_sendmsg(void *p_msg)
+{
+ // There is a race condition that occurs if the stack is shut down while
+ // there is a procedure in progress that can schedule a task via this
+ // message queue. This causes |btu_bta_msg_queue| to get cleaned up before
+ // it gets used here; hence we check for NULL before using it.
+ if (bt_profile_msg_queue) {
+ fixed_queue_enqueue(bt_profile_msg_queue, p_msg);
+
+ bt_prf_task_post(SIG_PRF_WORK);
+ }
+}
+
+
+
+
-/**\r
- ****************************************************************************************\r
- *\r
- * @file bt_prf_task.c\r
- *\r
- * @brief Application entry point\r
- *\r
- * Copyright (C) Espressif 2016\r
- * Created by Yulong at 2016/10/11\r
- *\r
- *\r
- ****************************************************************************************\r
- */\r
-\r
-#include "bt_prf_task.h"\r
-#include "bt_prf_sys.h"\r
-#include "allocator.h"\r
-#include "thread.h"\r
-#include "gki.h"\r
-\r
- //thread_t *bt_workqueue_thread;\r
- //static const char *BT_WORKQUEUE_NAME = "bt_workqueue";\r
- xTaskHandle xProfileTaskHandle = NULL;\r
- xQueueHandle xProfileQueue = 0;\r
-\r
- // Communication queue between bt_proflie_task and app.\r
- extern fixed_queue_t *bt_profile_msg_queue;\r
-\r
- \r
- /*****************************************************************************\r
- **\r
- ** Function bt_prf_task_thread_handler\r
- **\r
- ** Description Process profile Task Thread.\r
- ******************************************************************************/\r
- void bt_prf_task_thread_handler(void *arg)\r
- {\r
- //ke_event_clear(KE_EVENT_BTU_TASK_THREAD);\r
- \r
- TaskEvt_t *e;\r
- for (;;) {\r
- if (pdTRUE == xQueueReceive(xProfileQueue, &e, (portTickType)portMAX_DELAY)) {\r
- \r
- if (e->sig == SIG_BTU_WORK) {\r
- fixed_queue_process(bt_profile_msg_queue);\r
- \r
- }\r
- else if (e->sig == SIG_BTU_START_UP) {\r
- bt_prf_task_start_up();\r
- }\r
- osi_free(e); \r
- }\r
- }\r
- }\r
-\r
- void bt_prf_task_post(uint32_t sig)\r
+/**
+ ****************************************************************************************
+ *
+ * @file bt_prf_task.c
+ *
+ * @brief Application entry point
+ *
+ * Copyright (C) Espressif 2016
+ * Created by Yulong at 2016/10/11
+ *
+ *
+ ****************************************************************************************
+ */
+
+#include "bt_prf_task.h"
+#include "bt_prf_sys.h"
+#include "allocator.h"
+#include "thread.h"
+#include "gki.h"
+
+ //thread_t *bt_workqueue_thread;
+ //static const char *BT_WORKQUEUE_NAME = "bt_workqueue";
+ xTaskHandle xProfileTaskHandle = NULL;
+ xQueueHandle xProfileQueue = 0;
+
+ // Communication queue between bt_proflie_task and app.
+ extern fixed_queue_t *bt_profile_msg_queue;
+
+
+ /*****************************************************************************
+ **
+ ** Function bt_prf_task_thread_handler
+ **
+ ** Description Process profile Task Thread.
+ ******************************************************************************/
+ void bt_prf_task_thread_handler(void *arg)
+ {
+ //ke_event_clear(KE_EVENT_BTU_TASK_THREAD);
+
+ TaskEvt_t *e;
+ for (;;) {
+ if (pdTRUE == xQueueReceive(xProfileQueue, &e, (portTickType)portMAX_DELAY)) {
+
+ if (e->sig == SIG_BTU_WORK) {
+ fixed_queue_process(bt_profile_msg_queue);
+
+ }
+ else if (e->sig == SIG_BTU_START_UP) {
+ bt_prf_task_start_up();
+ }
+ osi_free(e);
+ }
+ }
+ }
+
+ void bt_prf_task_post(uint32_t sig)
{
TaskEvt_t *evt = (TaskEvt_t *)osi_malloc(sizeof(TaskEvt_t));
if (evt == NULL)
evt->sig = sig;
evt->par = 0;
- if (xQueueSend(xProfileQueue, &evt, 10/portTICK_RATE_MS) != pdTRUE) {\r
- ets_printf("xProfileQueue failed\n");\r
+ if (xQueueSend(xProfileQueue, &evt, 10/portTICK_RATE_MS) != pdTRUE) {
+ ets_printf("xProfileQueue failed\n");
}
-}\r
-\r
-void bt_profile_msg_ready(fixed_queue_t *queue) {\r
+}
+
+void bt_profile_msg_ready(fixed_queue_t *queue) {
BT_HDR *p_msg;
while (!fixed_queue_is_empty(queue)) {
- p_msg = (BT_HDR *)fixed_queue_dequeue(queue);\r
- if(p_msg != NULL)\r
- {\r
- bt_prf_sys_event(p_msg);\r
- }\r
+ p_msg = (BT_HDR *)fixed_queue_dequeue(queue);
+ if(p_msg != NULL)
+ {
+ bt_prf_sys_event(p_msg);
+ }
}
-}\r
-\r
-\r
-void bt_prf_task_start_up(void)\r
-{\r
- fixed_queue_register_dequeue(bt_profile_msg_queue, bt_profile_msg_ready);\r
-}\r
-\r
-void bt_prf_task_shut_down(void) \r
-{\r
- fixed_queue_unregister_dequeue(bt_profile_msg_queue);\r
- \r
- bt_prf_free_core();\r
-}\r
-\r
-\r
-void bt_prf_StartUp(void)\r
-{\r
- bt_profile_msg_queue = fixed_queue_new(SIZE_MAX);\r
- if (bt_profile_msg_queue == NULL)\r
- goto error_exit;\r
-\r
- return;\r
-\r
-error_exit:;\r
- LOG_ERROR("%s Unable to allocate resources for bt_workqueue\n", __func__);\r
- bt_prf_ShutDown();\r
-\r
-}\r
-\r
-void bt_prf_ShutDown(void)\r
-{\r
- \r
- bt_prf_task_shut_down();\r
-\r
- //thread_free(bt_workqueue_thread);\r
- vTaskDelete(xProfileTaskHandle);\r
- vQueueDelete(xProfileQueue);\r
-\r
- bt_profile_msg_queue = NULL;\r
-\r
- // bt_workqueue_thread = NULL;\r
- xProfileTaskHandle = NULL;\r
- xProfileQueue = 0;\r
-}\r
-\r
-\r
-void bt_prf_free_core(void)\r
-{\r
- \r
-}\r
-\r
-\r
-\r
+}
+
+
+void bt_prf_task_start_up(void)
+{
+ fixed_queue_register_dequeue(bt_profile_msg_queue, bt_profile_msg_ready);
+}
+
+void bt_prf_task_shut_down(void)
+{
+ fixed_queue_unregister_dequeue(bt_profile_msg_queue);
+
+ bt_prf_free_core();
+}
+
+
+void bt_prf_StartUp(void)
+{
+ bt_profile_msg_queue = fixed_queue_new(SIZE_MAX);
+ if (bt_profile_msg_queue == NULL)
+ goto error_exit;
+
+ return;
+
+error_exit:;
+ LOG_ERROR("%s Unable to allocate resources for bt_workqueue\n", __func__);
+ bt_prf_ShutDown();
+
+}
+
+void bt_prf_ShutDown(void)
+{
+
+ bt_prf_task_shut_down();
+
+ //thread_free(bt_workqueue_thread);
+ vTaskDelete(xProfileTaskHandle);
+ vQueueDelete(xProfileQueue);
+
+ bt_profile_msg_queue = NULL;
+
+ // bt_workqueue_thread = NULL;
+ xProfileTaskHandle = NULL;
+ xProfileQueue = 0;
+}
+
+
+void bt_prf_free_core(void)
+{
+
+}
+
+
+
-/**\r
- ****************************************************************************************\r
- *\r
- * @file bt_profile_act.c\r
- *\r
- * @brief Application entry point\r
- *\r
- * Copyright (C) Espressif 2016\r
- * Created by Yulong at 2016/10/13\r
- *\r
- *\r
- ****************************************************************************************\r
- */\r
-\r
-\r
- \r
-\r
+/**
+ ****************************************************************************************
+ *
+ * @file bt_profile_act.c
+ *
+ * @brief Application entry point
+ *
+ * Copyright (C) Espressif 2016
+ * Created by Yulong at 2016/10/13
+ *
+ *
+ ****************************************************************************************
+ */
+
+
+
+
-/**\r
- ****************************************************************************************\r
- *\r
- * @file bt_prf_task.h\r
- *\r
- * @brief Application entry point\r
- *\r
- * Copyright (C) Espressif 2016\r
- * Created by Yulong at 2016/10/12\r
- *\r
- *\r
- ****************************************************************************************\r
- */\r
-\r
-#include <string.h>\r
-\r
-enum\r
-{\r
- API_BLE_DEVICE_READY_IND,\r
- API_BLE_DM_CMP_EVT,\r
- API_BLE_CONN_CMP_EVT,\r
- API_BLE_CONN_REQ_IND,\r
- API_BLE_DISCONN_IND,\r
- API_BLE_MODULE_INIT_CMP_EVT,\r
- API_BLE_ADV_REPORT_IND,\r
-\r
-#if (BLE_SEC)\r
- API_BLE_BOND_REQ_IND,\r
- API_BLE_BOND_REQ_IND,\r
- API_BLE_ENCRYPT_REQ_IND,\r
- API_BLE_ENCRYPT_IND,\r
-#endif ///BLE_SEC\r
-\r
-#if (BLE_DISS_SERVER)\r
- API_BLE_CREATE_DB_CFM,\r
- API_BLE_DISABLE_IND,\r
-#endif ///BLE_DISS_SERVER\r
-\r
-#if (BLE_PROX_REPORTER)\r
- API_BLE_PROXR_ALERT_IND,\r
- API_BLE_PXP_TIMER,\r
- API_BLE_PROXR_CREATE_DB_CFM,\r
- API_BLE_PROXR_DISABLE_IND,\r
-#endif ///BLE_PROX_REPORTER\r
-\r
-#if (BLE_BUT_SERVER)\r
- API_BLE_BUT_VAL_RECEIVCE,\r
- API_BLE_CREATE_DB_CFM,\r
- API_BLE_VAL_SEND_CFM,\r
-#endif ///BLE_BUT_SERVER\r
-\r
-#if (BLE_APP_KEYBOARD)\r
- API_BLE_HIDD_CREATE_DB_CFM,\r
- API_BLE_DISABLE_IND,\r
- API_BLE_NTF_SENT_CFM,\r
- API_BLE_HIDD_TIMER,\r
- API_BLE_GREEN_LED_TIMER,\r
- API_BLE_RED_LED_TIMER,\r
-#ifndef MITM_ON\r
- API_BLE_HIDD_ENC_TIMER,\r
-#endif ///MITM_ON\r
- API_BLE_UPDATED_PRIVACY_IND,\r
- API_BLE_UPDATED_RECON_ADDR_IND,\r
- API_BLE_HID_MSG,\r
-#endif ///BLE_APP_KEYBOARD\r
-\r
-#if (BLE_BATT_SERVER)\r
- API_BLE_BATT_CREATE_DB_CFM,\r
- API_BLE_BATT_LEVEL_UPD_CFM,\r
- API_BLE_BATT_LEVEL_NTF_CFG_IND,\r
- API_BLE_BATT_TIMER,\r
- APP_BLE_ALERT_TIMER,\r
-#endif ///BLE_BATT_SERVER\r
-\r
-#if (BLE_FINDME_TARGET)\r
- API_BLE_FINDT_ALERT_IND,\r
-#endif ///BLE_FINDME_TARGET\r
-\r
-#if (BLE_FINDME_LOCATOR)\r
- API_BLE_FINDL_ENABLE_CFM,\r
-#endif ///BLE_FINDME_LOCATOR\r
-\r
-#if (HAS_MULTI_BOND)\r
- API_BLE_PAIR_TIMER,\r
-#endif ///HAS_MULTI_BOND\r
-\r
-#if (BLE_SPOTA_RECEIVER)\r
- API_BLE_SPOTAR_PATCH_MEM_DEV_IND,\r
- API_BLE_SPOTAR_GPIO_MAP_IND,\r
- API_BLE_SPOTAR_PATCH_LEN_IND,\r
- API_BLE_SPOTAR_PATCH_DATA_IND,\r
- API_BLE_SPOTAR_CREATE_DB_CFM,\r
-#endif ///BLE_SPOTA_RECEIVER\r
-\r
-#if (BLE_APP_SMARTTAG)\r
- API_BLE_ADV_TIMER,\r
- API_BLE_ADV_BLINK_TIMER,\r
- API_BLE_WAKEUP_MSG,\r
-#endif ///BLE_APP_SMARTTAG\r
-\r
-#if (BLE_APP_PROXR)\r
- API_BLE_ADV_TIMER,\r
- API_BLE_WAKEUP_MSG,\r
-#endif ///BLE_APP_PROXR\r
-\r
-#if (BLE_INTEGRATED_HOST_GTL_CENTRAL)\r
- API_BLE_EXT_TEST_REQ,\r
- API_BLE_EXT_SCAN_CMD,\r
- API_BLE_EXT_CONNECT_CMD,\r
- API_BLE_EXT_DISCONNECT_CMD,\r
- API_BLE_EXT_TRANSMIT_CMD,\r
-#endif ///BLE_INTEGRATED_HOST_GTL\r
-\r
-#if (BLE_APP_THROUGHPUT_PERIPHERAL)\r
- API_BLE_EXT_TEST_REQ,\r
- API_BLE_EXT_DISCONNECT_CMD,\r
- API_BLE_EXT_TRANSMIT_CMD,\r
-#endif ///BLE_APP_THROUGHPUT_PERIPHERAL\r
-\r
-#if (BLE_STREAMDATA_HOST)\r
- API_BLE_STREAMDATAH_ENABLE_CFM,\r
- API_BLE_STREAMDATAH_RCV_DATA_PACKET_IND,\r
-#endif ///BLE_STREAMDATA_HOST\r
-\r
-#if (BLE_STREAMDATA_DEVICE)\r
- API_BLE_STREAMDATAD_CREATE_DB_CFM,\r
- API_BLE_STREAMDATAD_RCV_DATA_PACKET_IND,\r
-#endif ///BLE_STREAMDATA_DEVICE\r
-\r
-\r
- \r
-};\r
-\r
-\r
+/**
+ ****************************************************************************************
+ *
+ * @file bt_prf_task.h
+ *
+ * @brief Application entry point
+ *
+ * Copyright (C) Espressif 2016
+ * Created by Yulong at 2016/10/12
+ *
+ *
+ ****************************************************************************************
+ */
+
+#include <string.h>
+
+enum
+{
+ API_BLE_DEVICE_READY_IND,
+ API_BLE_DM_CMP_EVT,
+ API_BLE_CONN_CMP_EVT,
+ API_BLE_CONN_REQ_IND,
+ API_BLE_DISCONN_IND,
+ API_BLE_MODULE_INIT_CMP_EVT,
+ API_BLE_ADV_REPORT_IND,
+
+#if (BLE_SEC)
+ API_BLE_BOND_REQ_IND,
+ API_BLE_BOND_REQ_IND,
+ API_BLE_ENCRYPT_REQ_IND,
+ API_BLE_ENCRYPT_IND,
+#endif ///BLE_SEC
+
+#if (BLE_DISS_SERVER)
+ API_BLE_CREATE_DB_CFM,
+ API_BLE_DISABLE_IND,
+#endif ///BLE_DISS_SERVER
+
+#if (BLE_PROX_REPORTER)
+ API_BLE_PROXR_ALERT_IND,
+ API_BLE_PXP_TIMER,
+ API_BLE_PROXR_CREATE_DB_CFM,
+ API_BLE_PROXR_DISABLE_IND,
+#endif ///BLE_PROX_REPORTER
+
+#if (BLE_BUT_SERVER)
+ API_BLE_BUT_VAL_RECEIVCE,
+ API_BLE_CREATE_DB_CFM,
+ API_BLE_VAL_SEND_CFM,
+#endif ///BLE_BUT_SERVER
+
+#if (BLE_APP_KEYBOARD)
+ API_BLE_HIDD_CREATE_DB_CFM,
+ API_BLE_DISABLE_IND,
+ API_BLE_NTF_SENT_CFM,
+ API_BLE_HIDD_TIMER,
+ API_BLE_GREEN_LED_TIMER,
+ API_BLE_RED_LED_TIMER,
+#ifndef MITM_ON
+ API_BLE_HIDD_ENC_TIMER,
+#endif ///MITM_ON
+ API_BLE_UPDATED_PRIVACY_IND,
+ API_BLE_UPDATED_RECON_ADDR_IND,
+ API_BLE_HID_MSG,
+#endif ///BLE_APP_KEYBOARD
+
+#if (BLE_BATT_SERVER)
+ API_BLE_BATT_CREATE_DB_CFM,
+ API_BLE_BATT_LEVEL_UPD_CFM,
+ API_BLE_BATT_LEVEL_NTF_CFG_IND,
+ API_BLE_BATT_TIMER,
+ APP_BLE_ALERT_TIMER,
+#endif ///BLE_BATT_SERVER
+
+#if (BLE_FINDME_TARGET)
+ API_BLE_FINDT_ALERT_IND,
+#endif ///BLE_FINDME_TARGET
+
+#if (BLE_FINDME_LOCATOR)
+ API_BLE_FINDL_ENABLE_CFM,
+#endif ///BLE_FINDME_LOCATOR
+
+#if (HAS_MULTI_BOND)
+ API_BLE_PAIR_TIMER,
+#endif ///HAS_MULTI_BOND
+
+#if (BLE_SPOTA_RECEIVER)
+ API_BLE_SPOTAR_PATCH_MEM_DEV_IND,
+ API_BLE_SPOTAR_GPIO_MAP_IND,
+ API_BLE_SPOTAR_PATCH_LEN_IND,
+ API_BLE_SPOTAR_PATCH_DATA_IND,
+ API_BLE_SPOTAR_CREATE_DB_CFM,
+#endif ///BLE_SPOTA_RECEIVER
+
+#if (BLE_APP_SMARTTAG)
+ API_BLE_ADV_TIMER,
+ API_BLE_ADV_BLINK_TIMER,
+ API_BLE_WAKEUP_MSG,
+#endif ///BLE_APP_SMARTTAG
+
+#if (BLE_APP_PROXR)
+ API_BLE_ADV_TIMER,
+ API_BLE_WAKEUP_MSG,
+#endif ///BLE_APP_PROXR
+
+#if (BLE_INTEGRATED_HOST_GTL_CENTRAL)
+ API_BLE_EXT_TEST_REQ,
+ API_BLE_EXT_SCAN_CMD,
+ API_BLE_EXT_CONNECT_CMD,
+ API_BLE_EXT_DISCONNECT_CMD,
+ API_BLE_EXT_TRANSMIT_CMD,
+#endif ///BLE_INTEGRATED_HOST_GTL
+
+#if (BLE_APP_THROUGHPUT_PERIPHERAL)
+ API_BLE_EXT_TEST_REQ,
+ API_BLE_EXT_DISCONNECT_CMD,
+ API_BLE_EXT_TRANSMIT_CMD,
+#endif ///BLE_APP_THROUGHPUT_PERIPHERAL
+
+#if (BLE_STREAMDATA_HOST)
+ API_BLE_STREAMDATAH_ENABLE_CFM,
+ API_BLE_STREAMDATAH_RCV_DATA_PACKET_IND,
+#endif ///BLE_STREAMDATA_HOST
+
+#if (BLE_STREAMDATA_DEVICE)
+ API_BLE_STREAMDATAD_CREATE_DB_CFM,
+ API_BLE_STREAMDATAD_RCV_DATA_PACKET_IND,
+#endif ///BLE_STREAMDATA_DEVICE
+
+
+
+};
+
+
-/**\r
- ****************************************************************************************\r
- *\r
- * @file bt_prf_sys.h\r
- *\r
- * @brief Application entry point\r
- *\r
- * Copyright (C) Espressif 2016\r
- * Created by Yulong at 2016/10/12\r
- *\r
- *\r
- ****************************************************************************************\r
- */\r
-\r
-#ifndef _PROFILE_SYS_H__\r
-#define _PROFILE_SYS_H__\r
-\r
-#include "bt_types.h"\r
-\r
-enum\r
-{\r
- PRF_ID_SYS,\r
- PRF_ID_CONN,\r
- PRF_ID_HIDD_LE,\r
- PRF_ID_HIDH_LE,\r
- PRF_ID_DISS_LE,\r
- PRF_ID_DISC_LE,\r
- PRF_ID_AIRSYNC_LE,\r
- PRF_ID_ANCC_LE,\r
- PRF_ID_BUT_LE,\r
-\r
- PRF_ID_MAX\r
-};\r
-\r
-typedef UINT8 tBT_PRF_SYS_CONN_STATUS;\r
-\r
-\r
+/**
+ ****************************************************************************************
+ *
+ * @file bt_prf_sys.h
+ *
+ * @brief Application entry point
+ *
+ * Copyright (C) Espressif 2016
+ * Created by Yulong at 2016/10/12
+ *
+ *
+ ****************************************************************************************
+ */
+
+#ifndef _PROFILE_SYS_H__
+#define _PROFILE_SYS_H__
+
+#include "bt_types.h"
+
+enum
+{
+ PRF_ID_SYS,
+ PRF_ID_CONN,
+ PRF_ID_HIDD_LE,
+ PRF_ID_HIDH_LE,
+ PRF_ID_DISS_LE,
+ PRF_ID_DISC_LE,
+ PRF_ID_AIRSYNC_LE,
+ PRF_ID_ANCC_LE,
+ PRF_ID_BUT_LE,
+
+ PRF_ID_MAX
+};
+
+typedef UINT8 tBT_PRF_SYS_CONN_STATUS;
+
+
/* disable function type */
-typedef void (tBT_PRF_SYS_DISABLE)(void);\r
-/* event handler function type */\r
-typedef BOOLEAN (tBT_PRF_SYS_EVT_HDLR)(BT_HDR *p_msg);\r
-\r
-/* conn callback for role / low power manager*/\r
-typedef void (tBT_PRF_SYS_CONN_CBACK)(tBT_PRF_SYS_CONN_STATUS status,\r
- UINT8 id, UINT8 app_id, BD_ADDR peer_addr);\r
-\r
-/* Calculate start of event enumeration; id is top 8 bits of event */\r
-#define BT_PRF_SYS_EVT_START(id) ((id) << 8)\r
-\r
-\r
-\r
+typedef void (tBT_PRF_SYS_DISABLE)(void);
+/* event handler function type */
+typedef BOOLEAN (tBT_PRF_SYS_EVT_HDLR)(BT_HDR *p_msg);
+
+/* conn callback for role / low power manager*/
+typedef void (tBT_PRF_SYS_CONN_CBACK)(tBT_PRF_SYS_CONN_STATUS status,
+ UINT8 id, UINT8 app_id, BD_ADDR peer_addr);
+
+/* Calculate start of event enumeration; id is top 8 bits of event */
+#define BT_PRF_SYS_EVT_START(id) ((id) << 8)
+
+
+
/* registration structure */
typedef struct
{
- tBT_PRF_SYS_EVT_HDLR *evt_hdlr;\r
- tBT_PRF_SYS_DISABLE *disable;\r
-} tBT_PRF_SYS_REG;\r
-\r
-/* system manager control block */\r
-typedef struct\r
-{\r
- tBT_PRF_SYS_REG *reg[PRF_ID_MAX]; /* registration structures */\r
- BOOLEAN is_reg[PRF_ID_MAX]; /* registration structures */\r
- tBT_PRF_SYS_CONN_CBACK *prm_cb; /* role management callback registered by DM */\r
- tBT_PRF_SYS_CONN_CBACK *ppm_cb; /* low power management callback registered by DM */\r
- tBT_PRF_SYS_CONN_CBACK *p_policy_cb; /* link policy change callback registered by DM */\r
-\r
-} tBT_PRF_SYS_CB;\r
-\r
-\r
-extern tBT_PRF_SYS_CB bt_prf_sys_cb;\r
-\r
-\r
-extern void bt_prf_sys_init(void);\r
-extern void bt_prf_sys_free(void);\r
-extern void bt_prf_sys_event(BT_HDR *p_msg);\r
-\r
-extern void bt_prf_sys_register(UINT8 id, const tBT_PRF_SYS_REG *p_reg);\r
-extern void bt_prf_sys_deregister(UINT8 id);\r
-extern BOOLEAN bt_prf_sys_is_register(UINT8 id);\r
-\r
-extern void bt_prf_sys_idle(UINT8 id, UINT8 app_id, BD_ADDR peer_addr);\r
-extern void bt_prf_sys_busy(UINT8 id, UINT8 app_id, BD_ADDR peer_addr);\r
-\r
-\r
-#endif ///_PROFILE_SYS_H__\r
+ tBT_PRF_SYS_EVT_HDLR *evt_hdlr;
+ tBT_PRF_SYS_DISABLE *disable;
+} tBT_PRF_SYS_REG;
+
+/* system manager control block */
+typedef struct
+{
+ tBT_PRF_SYS_REG *reg[PRF_ID_MAX]; /* registration structures */
+ BOOLEAN is_reg[PRF_ID_MAX]; /* registration structures */
+ tBT_PRF_SYS_CONN_CBACK *prm_cb; /* role management callback registered by DM */
+ tBT_PRF_SYS_CONN_CBACK *ppm_cb; /* low power management callback registered by DM */
+ tBT_PRF_SYS_CONN_CBACK *p_policy_cb; /* link policy change callback registered by DM */
+
+} tBT_PRF_SYS_CB;
+
+
+extern tBT_PRF_SYS_CB bt_prf_sys_cb;
+
+
+extern void bt_prf_sys_init(void);
+extern void bt_prf_sys_free(void);
+extern void bt_prf_sys_event(BT_HDR *p_msg);
+
+extern void bt_prf_sys_register(UINT8 id, const tBT_PRF_SYS_REG *p_reg);
+extern void bt_prf_sys_deregister(UINT8 id);
+extern BOOLEAN bt_prf_sys_is_register(UINT8 id);
+
+extern void bt_prf_sys_idle(UINT8 id, UINT8 app_id, BD_ADDR peer_addr);
+extern void bt_prf_sys_busy(UINT8 id, UINT8 app_id, BD_ADDR peer_addr);
+
+
+#endif ///_PROFILE_SYS_H__
-/**\r
- ****************************************************************************************\r
- *\r
- * @file bt_prf_task.h\r
- *\r
- * @brief Application entry point\r
- *\r
- * Copyright (C) Espressif 2016\r
- * Created by Yulong at 2016/10/11\r
- *\r
- *\r
- ****************************************************************************************\r
- */\r
-\r
-#include <stddef.h> \r
-#include "bt_defs.h"\r
-#include "fixed_queue.h"\r
-\r
-#ifndef BT_PRF_TASK_H__\r
-#define BT_PRF_TASK_H__\r
-\r
+/**
+ ****************************************************************************************
+ *
+ * @file bt_prf_task.h
+ *
+ * @brief Application entry point
+ *
+ * Copyright (C) Espressif 2016
+ * Created by Yulong at 2016/10/11
+ *
+ *
+ ****************************************************************************************
+ */
+
+#include <stddef.h>
+#include "bt_defs.h"
+#include "fixed_queue.h"
+
+#ifndef BT_PRF_TASK_H__
+#define BT_PRF_TASK_H__
+
/* Functions provided by btu_core.c
************************************
-*/\r
-\r
-\r
-void bt_prf_task_thread_handler(void *arg);\r
-\r
-void bt_prf_init_core(void);\r
-void bt_prf_free_core(void);\r
-
-void bt_prf_task_post(uint32_t sig);\r
-\r
-\r
-void bt_prf_StartUp(void);\r
-void bt_prf_ShutDown(void);\r
-
-void bt_prf_task_start_up(void);\r
-void bt_prf_task_shut_down(void);\r
-\r
-void bt_profile_msg_ready(fixed_queue_t *queue);\r
-\r
-\r
-\r
-\r
-\r
-\r
-\r
-\r
-#endif /// BT_PRF_TASK_H__\r
+*/
+
+
+void bt_prf_task_thread_handler(void *arg);
+
+void bt_prf_init_core(void);
+void bt_prf_free_core(void);
+
+void bt_prf_task_post(uint32_t sig);
+
+
+void bt_prf_StartUp(void);
+void bt_prf_ShutDown(void);
+
+void bt_prf_task_start_up(void);
+void bt_prf_task_shut_down(void);
+
+void bt_profile_msg_ready(fixed_queue_t *queue);
+
+
+
+
+
+
+
+
+#endif /// BT_PRF_TASK_H__
-/**\r
- ****************************************************************************************\r
- *\r
- * @file wx_airsync_prf.h\r
- *\r
- * @brief Application entry point\r
- *\r
- * Copyright (C) Espressif 2016\r
- * Created by Yulong at 2016/9/29\r
- *\r
- *\r
- ****************************************************************************************\r
- */\r
-\r
-#include "prf_defs.h"\r
- \r
-#if (WX_AIRSYNC_CFG)\r
-\r
-#include "bt_target.h"\r
-#include "gatt_api.h"\r
-#include "gattdefs.h"\r
-\r
-\r
-/// Maximum Transmission Unit\r
-#define ATT_DEFAULT_MTU (23)\r
-\r
-#define BLE_WECHAT_MAX_DATA_LEN (ATT_DEFAULT_MTU - 3) \r
-\r
- \r
- //define the key serivce uuid\r
-#define ATT_SVC_AIRSYNC 0xFEE7\r
- //define the airsync Char uuid\r
-#define ATT_CHAR_AIRSYNC_WIT 0xFEC7\r
-#define ATT_CHAR_AIRSYBC_NTF 0xFEC8\r
-#define ATT_CHAR_AIRSYNC_READ 0xFEC9\r
- \r
- \r
-typedef void (tAIRSYNC_CBACK)(UINT8 app_id, UINT8 event, UINT8 len, UINT8 *data);\r
- \r
- \r
- /// WX AirSync Service Attributes Indexes\r
- enum\r
- {\r
- WX_IDX_SVC,\r
- WX_IDX_AIRSYNC_WIT_CHAR,\r
- WX_IDX_AIRSYNC_WIT_VAL,\r
- WX_IDX_AIRSYNC_NTF_CHAR,\r
- WX_IDX_AIRSYNC_NTF_VAL,\r
- WX_IDX_AIRSYNC_READ_CHAR,\r
- WX_IDX_AIRSYNC_READ_VAL,\r
- WX_IDX_AIRSYNC_NTF_CFG,\r
- \r
- KEY_IDX_NB,\r
- };\r
- \r
- typedef struct\r
- {\r
- BD_ADDR remote_bda;\r
- BOOLEAN need_rsp;\r
- UINT16 clt_cfg;\r
- }tAirSync_WRITE_DATA;\r
- \r
- typedef struct\r
- {\r
- BOOLEAN in_use;\r
- BOOLEAN congest;\r
- UINT16 conn_id;\r
- BOOLEAN connected;\r
- BD_ADDR remote_bda;\r
- UINT32 trans_id;\r
- UINT8 cur_srvc_id;\r
- \r
- }tAirSync_CLCB;\r
- \r
- \r
- typedef struct\r
- {\r
- UINT8 app_id;\r
- UINT16 airsync_wirt_hdl;\r
- UINT16 airsync_ntf_hdl;\r
- UINT16 airsync_read_hdl;\r
- UINT16 airsync_cfg_hdl;\r
- \r
- tAIRSYNC_CBACK *p_cback;\r
- \r
- }tAirSync_INST;\r
- \r
- \r
- /* service engine control block */\r
- typedef struct\r
- {\r
- tAirSync_CLCB clcb; /* connection link*/\r
- tGATT_IF gatt_if;\r
- BOOLEAN enabled;\r
- BOOLEAN is_primery;\r
- tAirSync_INST airsync_inst;\r
- UINT8 inst_id;\r
- }tAIRSYNC_CB_ENV;\r
- \r
- void AirSync_CreateService(void);\r
- \r
- tAirSync_CLCB *airsync_env_clcb_alloc (UINT16 conn_id, BD_ADDR remote_bda);\r
- \r
- UINT16 AirSync_env_find_conn_id_by_bd_adddr(BD_ADDR bda);\r
- \r
- BOOLEAN AirSync_env_clcb_dealloc(UINT16 conn_id);\r
- \r
- tGATT_STATUS AirSync_Init(tAIRSYNC_CBACK *call_back);\r
- \r
- void AirSync_msg_notify(UINT8 len, UINT8 *button_msg);\r
- \r
- extern tAIRSYNC_CB_ENV airsync_cb_env;\r
-\r
- #endif ///WX_AIRSYNC_CFG\r
- \r
+/**
+ ****************************************************************************************
+ *
+ * @file wx_airsync_prf.h
+ *
+ * @brief Application entry point
+ *
+ * Copyright (C) Espressif 2016
+ * Created by Yulong at 2016/9/29
+ *
+ *
+ ****************************************************************************************
+ */
+
+#include "prf_defs.h"
+
+#if (WX_AIRSYNC_CFG)
+
+#include "bt_target.h"
+#include "gatt_api.h"
+#include "gattdefs.h"
+
+
+/// Maximum Transmission Unit
+#define ATT_DEFAULT_MTU (23)
+
+#define BLE_WECHAT_MAX_DATA_LEN (ATT_DEFAULT_MTU - 3)
+
+
+ //define the key serivce uuid
+#define ATT_SVC_AIRSYNC 0xFEE7
+ //define the airsync Char uuid
+#define ATT_CHAR_AIRSYNC_WIT 0xFEC7
+#define ATT_CHAR_AIRSYBC_NTF 0xFEC8
+#define ATT_CHAR_AIRSYNC_READ 0xFEC9
+
+
+typedef void (tAIRSYNC_CBACK)(UINT8 app_id, UINT8 event, UINT8 len, UINT8 *data);
+
+
+ /// WX AirSync Service Attributes Indexes
+ enum
+ {
+ WX_IDX_SVC,
+ WX_IDX_AIRSYNC_WIT_CHAR,
+ WX_IDX_AIRSYNC_WIT_VAL,
+ WX_IDX_AIRSYNC_NTF_CHAR,
+ WX_IDX_AIRSYNC_NTF_VAL,
+ WX_IDX_AIRSYNC_READ_CHAR,
+ WX_IDX_AIRSYNC_READ_VAL,
+ WX_IDX_AIRSYNC_NTF_CFG,
+
+ KEY_IDX_NB,
+ };
+
+ typedef struct
+ {
+ BD_ADDR remote_bda;
+ BOOLEAN need_rsp;
+ UINT16 clt_cfg;
+ }tAirSync_WRITE_DATA;
+
+ typedef struct
+ {
+ BOOLEAN in_use;
+ BOOLEAN congest;
+ UINT16 conn_id;
+ BOOLEAN connected;
+ BD_ADDR remote_bda;
+ UINT32 trans_id;
+ UINT8 cur_srvc_id;
+
+ }tAirSync_CLCB;
+
+
+ typedef struct
+ {
+ UINT8 app_id;
+ UINT16 airsync_wirt_hdl;
+ UINT16 airsync_ntf_hdl;
+ UINT16 airsync_read_hdl;
+ UINT16 airsync_cfg_hdl;
+
+ tAIRSYNC_CBACK *p_cback;
+
+ }tAirSync_INST;
+
+
+ /* service engine control block */
+ typedef struct
+ {
+ tAirSync_CLCB clcb; /* connection link*/
+ tGATT_IF gatt_if;
+ BOOLEAN enabled;
+ BOOLEAN is_primery;
+ tAirSync_INST airsync_inst;
+ UINT8 inst_id;
+ }tAIRSYNC_CB_ENV;
+
+ void AirSync_CreateService(void);
+
+ tAirSync_CLCB *airsync_env_clcb_alloc (UINT16 conn_id, BD_ADDR remote_bda);
+
+ UINT16 AirSync_env_find_conn_id_by_bd_adddr(BD_ADDR bda);
+
+ BOOLEAN AirSync_env_clcb_dealloc(UINT16 conn_id);
+
+ tGATT_STATUS AirSync_Init(tAIRSYNC_CBACK *call_back);
+
+ void AirSync_msg_notify(UINT8 len, UINT8 *button_msg);
+
+ extern tAIRSYNC_CB_ENV airsync_cb_env;
+
+ #endif ///WX_AIRSYNC_CFG
+
-/**\r
- ****************************************************************************************\r
- *\r
- * @file wx_airsync_prf.c\r
- *\r
- * @brief Application entry point\r
- *\r
- * Copyright (C) Espressif 2016\r
- * Created by Yulong at 2016/9/29\r
- *\r
- *\r
- ****************************************************************************************\r
- */\r
-#include "wx_airsync_prf.h"\r
-\r
-#if (WX_AIRSYNC_CFG)\r
-\r
-#include <stdint.h>\r
- \r
-#include <string.h>\r
-#include <stdbool.h>\r
-#include <stdio.h>\r
-\r
-#include "bt_target.h"\r
-#include "bt_trace.h"\r
-#include "bt_types.h"\r
-#include "gatt_api.h"\r
-#include "bta_api.h"\r
-#include "bta_gatt_api.h"\r
-#include "bta_gatts_int.h"\r
-\r
-\r
-\r
-tAIRSYNC_CB_ENV airsync_cb_env;\r
-\r
-\r
-/*****************************************************************************\r
-** Constants\r
-*****************************************************************************/\r
-static void airsync_profile_cb(tBTA_GATTS_EVT event, tBTA_GATTS *p_data);\r
-\r
-\r
-/*******************************************************************************\r
-**\r
-** Function airsync_profile_cb\r
-**\r
-** Description the callback function after the profile has been register to the BTA manager module\r
-**\r
-** Returns NULL \r
-**\r
-*******************************************************************************/\r
-static void airsync_profile_cb(tBTA_GATTS_EVT event, tBTA_GATTS *p_data)\r
-{\r
- tBTA_GATTS_RSP rsp;\r
- tBT_UUID uuid = {LEN_UUID_16, {ATT_SVC_AIRSYNC}};\r
- tAirSync_INST *p_inst = &airsync_cb_env.airsync_inst;\r
- \r
- \r
- LOG_ERROR("airsync profile cb event = %x\n",event);\r
- switch(event) \r
- {\r
- case BTA_GATTS_REG_EVT:\r
- \r
- if(p_data->reg_oper.status != BTA_GATT_OK)\r
- {\r
- LOG_ERROR("button profile register failed\n");\r
- }\r
- airsync_cb_env.gatt_if = p_data->reg_oper.server_if;\r
- airsync_cb_env.enabled = true;\r
- \r
- if(p_data->reg_oper.uuid.uu.uuid16 == ATT_SVC_AIRSYNC)\r
- {\r
- AirSync_CreateService();\r
- }\r
- break;\r
- case BTA_GATTS_READ_EVT:\r
- \r
- if(airsync_cb_env.clcb.connected && airsync_cb_env.enabled){\r
- //tBTA_GATTS_RSP rsp;\r
- memset(&rsp,0,sizeof(tBTA_GATTS_API_RSP));\r
- rsp.attr_value.handle = p_data->req_data.p_data->read_req.handle;\r
- rsp.attr_value.len = 2;\r
- BTA_GATTS_SendRsp(p_data->req_data.conn_id,p_data->req_data.trans_id,\r
- p_data->req_data.status,&rsp);\r
- }\r
- break;\r
- case BTA_GATTS_WRITE_EVT:\r
- if(airsync_cb_env.clcb.connected && airsync_cb_env.enabled){\r
- BTA_GATTS_SendRsp(p_data->req_data.conn_id,p_data->req_data.trans_id,\r
- p_data->req_data.status,NULL);\r
-\r
- }\r
- break;\r
- case BTA_GATTS_CONF_EVT:\r
- \r
- break;\r
- case BTA_GATTS_CREATE_EVT:\r
- uuid.uu.uuid16 = ATT_CHAR_AIRSYNC_WIT;\r
- \r
- airsync_cb_env.clcb.cur_srvc_id= p_data->create.service_id;\r
- airsync_cb_env.is_primery = p_data->create.is_primary;\r
- //start the airsync service after created\r
- BTA_GATTS_StartService(p_data->create.service_id,BTA_GATT_TRANSPORT_LE);\r
- //add the frist airsync characteristic --> write characteristic\r
- BTA_GATTS_AddCharacteristic(airsync_cb_env.clcb.cur_srvc_id,&uuid,\r
- (GATT_PERM_WRITE|GATT_PERM_READ),\r
- (GATT_CHAR_PROP_BIT_READ|GATT_CHAR_PROP_BIT_WRITE));\r
- break;\r
- \r
- case BTA_GATTS_ADD_CHAR_EVT:\r
- if(p_data->add_result.char_uuid.uu.uuid16 == ATT_CHAR_AIRSYNC_WIT)\r
- {\r
- uuid.uu.uuid16 = ATT_CHAR_AIRSYBC_NTF;\r
- //tBTA_GATT_PERM perm = GATT_PERM_READ;\r
- //tBTA_GATT_CHAR_PROP prop = (GATT_CHAR_PROP_BIT_READ|GATT_CHAR_PROP_BIT_NOTIFY);\r
- //save the att handle to the env\r
- airsync_cb_env.airsync_inst.airsync_wirt_hdl = p_data->add_result.attr_id;\r
- //add the second airsync characteristic --> Notify characteristic\r
- BTA_GATTS_AddCharacteristic(airsync_cb_env.clcb.cur_srvc_id,&uuid,\r
- GATT_PERM_READ,(GATT_CHAR_PROP_BIT_READ|GATT_CHAR_PROP_BIT_INDICATE));\r
- }else if(p_data->add_result.char_uuid.uu.uuid16 == ATT_CHAR_AIRSYBC_NTF){ \r
- //tBTA_GATT_PERM perm = (GATT_PERM_WRITE|GATT_PERM_WRITE);\r
- uuid.uu.uuid16 = GATT_UUID_CHAR_CLIENT_CONFIG;\r
- airsync_cb_env.airsync_inst.airsync_ntf_hdl = p_data->add_result.attr_id;\r
- BTA_GATTS_AddCharDescriptor (airsync_cb_env.clcb.cur_srvc_id,\r
- (GATT_PERM_WRITE|GATT_PERM_WRITE),\r
- &uuid);\r
-\r
- uuid.uu.uuid16 = ATT_CHAR_AIRSYNC_READ;\r
- //add the third airsync characteristic --> Read characteristic\r
- BTA_GATTS_AddCharacteristic(airsync_cb_env.clcb.cur_srvc_id,&uuid,\r
- GATT_PERM_READ,\r
- GATT_CHAR_PROP_BIT_READ);\r
- }else if(p_data->add_result.char_uuid.uu.uuid16 == ATT_CHAR_AIRSYNC_READ){\r
- airsync_cb_env.airsync_inst.airsync_read_hdl = p_data->add_result.attr_id;\r
- }\r
- \r
- break;\r
- case BTA_GATTS_ADD_CHAR_DESCR_EVT:\r
- if(p_data->add_result.char_uuid.uu.uuid16 == GATT_UUID_CHAR_CLIENT_CONFIG)\r
- {\r
- airsync_cb_env.airsync_inst.airsync_cfg_hdl = p_data->add_result.attr_id;\r
- }\r
- break;\r
- case BTA_GATTS_CONNECT_EVT:\r
- //set the connection flag to true\r
- airsync_env_clcb_alloc(p_data->conn.conn_id, p_data->conn.remote_bda);\r
- break;\r
- case BTA_GATTS_DISCONNECT_EVT:\r
- //set the connection flag to true\r
- airsync_cb_env.clcb.connected = false;\r
- break;\r
- case BTA_GATTS_OPEN_EVT:\r
- break;\r
- case BTA_GATTS_CLOSE_EVT:\r
- if(airsync_cb_env.clcb.connected && (airsync_cb_env.clcb.conn_id == p_data->conn.conn_id))\r
- {\r
- //set the connection channal congested flag to true\r
- airsync_cb_env.clcb.congest = p_data->congest.congested;\r
- }\r
- break;\r
- case BTA_GATTS_LISTEN_EVT:\r
- break;\r
- case BTA_GATTS_CONGEST_EVT: \r
- //set the congest flag\r
- airsync_cb_env.clcb.congest = p_data->congest.congested;\r
- break;\r
- default:\r
- break;\r
- }\r
-}\r
-\r
-\r
-/*******************************************************************************\r
-**\r
-** Function AirSync_CreateService\r
-**\r
-** Description Create a Service for the airsync profile\r
-**\r
-** Returns NULL \r
-**\r
-*******************************************************************************/\r
-void AirSync_CreateService(void)\r
-{\r
- tBTA_GATTS_IF server_if ;\r
- tBT_UUID uuid = {LEN_UUID_16, {ATT_SVC_AIRSYNC}};\r
- UINT16 num_handle = KEY_IDX_NB;\r
- UINT8 inst = 0x00;\r
- server_if = airsync_cb_env.gatt_if;\r
- airsync_cb_env.inst_id = inst;\r
- \r
- BTA_GATTS_CreateService(server_if,&uuid,inst,num_handle,true);\r
- \r
-}\r
-\r
-/*******************************************************************************\r
-**\r
-** Function airsync_env_clcb_alloc\r
-**\r
-** Description The function allocates a GATT profile connection link control block\r
-**\r
-** Returns NULL if not found. Otherwise pointer to the connection link block.\r
-**\r
-*******************************************************************************/\r
-tAirSync_CLCB *airsync_env_clcb_alloc (UINT16 conn_id, BD_ADDR remote_bda)\r
-{\r
- tAirSync_CLCB *p_clcb = NULL;\r
- p_clcb = &airsync_cb_env.clcb; \r
- \r
- if(!p_clcb->in_use)\r
- {\r
- p_clcb->in_use = TRUE;\r
- p_clcb->conn_id = conn_id;\r
- LOG_ERROR("p_clcb->conn_id = %x\n",conn_id);\r
- p_clcb->connected = TRUE;\r
- memcpy(p_clcb->remote_bda,remote_bda,BD_ADDR_LEN); \r
- }\r
-\r
- return p_clcb;\r
-}\r
-\r
-/*******************************************************************************\r
-**\r
-** Function airsync_env_find_conn_id_by_bd_adddr\r
-**\r
-** Description The function searches all LCB with macthing bd address\r
-**\r
-** Returns total number of clcb found.\r
-**\r
-*******************************************************************************/\r
-UINT16 airsync_env_find_conn_id_by_bd_adddr(BD_ADDR remote_bda)\r
-{\r
- UINT8 i_clcb;\r
- tAirSync_CLCB *p_clcb = NULL;\r
-\r
- for(i_clcb = 0, p_clcb = &airsync_cb_env.clcb; i_clcb < 1; i_clcb++, p_clcb++)\r
- {\r
- if(p_clcb->in_use && p_clcb->connected &&memcmp(p_clcb->remote_bda,remote_bda,BD_ADDR_LEN))\r
- {\r
- return p_clcb->conn_id;\r
- }\r
- }\r
-\r
- return GATT_INVALID_CONN_ID;\r
-}\r
-\r
-\r
-/*******************************************************************************\r
-**\r
-** Function airsync_init\r
-**\r
-** Description Initializa the GATT Service for airsync profiles.\r
-**\r
-*******************************************************************************/\r
-tGATT_STATUS AirSync_Init(tAIRSYNC_CBACK *call_back)\r
-{\r
- tBT_UUID app_uuid = {LEN_UUID_16,{ATT_SVC_AIRSYNC}};\r
- \r
-\r
- if(airsync_cb_env.enabled)\r
- {\r
- LOG_ERROR("airsync svc already initaliezd\n");\r
- return GATT_ERROR;\r
- }\r
- else\r
- {\r
- memset(&airsync_cb_env,0,sizeof(tAIRSYNC_CB_ENV));\r
- }\r
- \r
-\r
- if(call_back != NULL)\r
- {\r
- airsync_cb_env.airsync_inst.p_cback = call_back;\r
- }\r
-\r
- \r
- /* register the airsync profile to the BTA_GATTS module*/\r
- BTA_GATTS_AppRegister(&app_uuid,airsync_profile_cb);\r
-\r
- airsync_cb_env.enabled = TRUE;\r
-\r
- return GATT_SUCCESS;\r
-}\r
-\r
-#endif ///WX_AIRSYNC_CFG\r
-\r
+/**
+ ****************************************************************************************
+ *
+ * @file wx_airsync_prf.c
+ *
+ * @brief Application entry point
+ *
+ * Copyright (C) Espressif 2016
+ * Created by Yulong at 2016/9/29
+ *
+ *
+ ****************************************************************************************
+ */
+#include "wx_airsync_prf.h"
+
+#if (WX_AIRSYNC_CFG)
+
+#include <stdint.h>
+
+#include <string.h>
+#include <stdbool.h>
+#include <stdio.h>
+
+#include "bt_target.h"
+#include "bt_trace.h"
+#include "bt_types.h"
+#include "gatt_api.h"
+#include "bta_api.h"
+#include "bta_gatt_api.h"
+#include "bta_gatts_int.h"
+
+
+
+tAIRSYNC_CB_ENV airsync_cb_env;
+
+
+/*****************************************************************************
+** Constants
+*****************************************************************************/
+static void airsync_profile_cb(tBTA_GATTS_EVT event, tBTA_GATTS *p_data);
+
+
+/*******************************************************************************
+**
+** Function airsync_profile_cb
+**
+** Description the callback function after the profile has been register to the BTA manager module
+**
+** Returns NULL
+**
+*******************************************************************************/
+static void airsync_profile_cb(tBTA_GATTS_EVT event, tBTA_GATTS *p_data)
+{
+ tBTA_GATTS_RSP rsp;
+ tBT_UUID uuid = {LEN_UUID_16, {ATT_SVC_AIRSYNC}};
+ tAirSync_INST *p_inst = &airsync_cb_env.airsync_inst;
+
+
+ LOG_ERROR("airsync profile cb event = %x\n",event);
+ switch(event)
+ {
+ case BTA_GATTS_REG_EVT:
+
+ if(p_data->reg_oper.status != BTA_GATT_OK)
+ {
+ LOG_ERROR("button profile register failed\n");
+ }
+ airsync_cb_env.gatt_if = p_data->reg_oper.server_if;
+ airsync_cb_env.enabled = true;
+
+ if(p_data->reg_oper.uuid.uu.uuid16 == ATT_SVC_AIRSYNC)
+ {
+ AirSync_CreateService();
+ }
+ break;
+ case BTA_GATTS_READ_EVT:
+
+ if(airsync_cb_env.clcb.connected && airsync_cb_env.enabled){
+ //tBTA_GATTS_RSP rsp;
+ memset(&rsp,0,sizeof(tBTA_GATTS_API_RSP));
+ rsp.attr_value.handle = p_data->req_data.p_data->read_req.handle;
+ rsp.attr_value.len = 2;
+ BTA_GATTS_SendRsp(p_data->req_data.conn_id,p_data->req_data.trans_id,
+ p_data->req_data.status,&rsp);
+ }
+ break;
+ case BTA_GATTS_WRITE_EVT:
+ if(airsync_cb_env.clcb.connected && airsync_cb_env.enabled){
+ BTA_GATTS_SendRsp(p_data->req_data.conn_id,p_data->req_data.trans_id,
+ p_data->req_data.status,NULL);
+
+ }
+ break;
+ case BTA_GATTS_CONF_EVT:
+
+ break;
+ case BTA_GATTS_CREATE_EVT:
+ uuid.uu.uuid16 = ATT_CHAR_AIRSYNC_WIT;
+
+ airsync_cb_env.clcb.cur_srvc_id= p_data->create.service_id;
+ airsync_cb_env.is_primery = p_data->create.is_primary;
+ //start the airsync service after created
+ BTA_GATTS_StartService(p_data->create.service_id,BTA_GATT_TRANSPORT_LE);
+ //add the frist airsync characteristic --> write characteristic
+ BTA_GATTS_AddCharacteristic(airsync_cb_env.clcb.cur_srvc_id,&uuid,
+ (GATT_PERM_WRITE|GATT_PERM_READ),
+ (GATT_CHAR_PROP_BIT_READ|GATT_CHAR_PROP_BIT_WRITE));
+ break;
+
+ case BTA_GATTS_ADD_CHAR_EVT:
+ if(p_data->add_result.char_uuid.uu.uuid16 == ATT_CHAR_AIRSYNC_WIT)
+ {
+ uuid.uu.uuid16 = ATT_CHAR_AIRSYBC_NTF;
+ //tBTA_GATT_PERM perm = GATT_PERM_READ;
+ //tBTA_GATT_CHAR_PROP prop = (GATT_CHAR_PROP_BIT_READ|GATT_CHAR_PROP_BIT_NOTIFY);
+ //save the att handle to the env
+ airsync_cb_env.airsync_inst.airsync_wirt_hdl = p_data->add_result.attr_id;
+ //add the second airsync characteristic --> Notify characteristic
+ BTA_GATTS_AddCharacteristic(airsync_cb_env.clcb.cur_srvc_id,&uuid,
+ GATT_PERM_READ,(GATT_CHAR_PROP_BIT_READ|GATT_CHAR_PROP_BIT_INDICATE));
+ }else if(p_data->add_result.char_uuid.uu.uuid16 == ATT_CHAR_AIRSYBC_NTF){
+ //tBTA_GATT_PERM perm = (GATT_PERM_WRITE|GATT_PERM_WRITE);
+ uuid.uu.uuid16 = GATT_UUID_CHAR_CLIENT_CONFIG;
+ airsync_cb_env.airsync_inst.airsync_ntf_hdl = p_data->add_result.attr_id;
+ BTA_GATTS_AddCharDescriptor (airsync_cb_env.clcb.cur_srvc_id,
+ (GATT_PERM_WRITE|GATT_PERM_WRITE),
+ &uuid);
+
+ uuid.uu.uuid16 = ATT_CHAR_AIRSYNC_READ;
+ //add the third airsync characteristic --> Read characteristic
+ BTA_GATTS_AddCharacteristic(airsync_cb_env.clcb.cur_srvc_id,&uuid,
+ GATT_PERM_READ,
+ GATT_CHAR_PROP_BIT_READ);
+ }else if(p_data->add_result.char_uuid.uu.uuid16 == ATT_CHAR_AIRSYNC_READ){
+ airsync_cb_env.airsync_inst.airsync_read_hdl = p_data->add_result.attr_id;
+ }
+
+ break;
+ case BTA_GATTS_ADD_CHAR_DESCR_EVT:
+ if(p_data->add_result.char_uuid.uu.uuid16 == GATT_UUID_CHAR_CLIENT_CONFIG)
+ {
+ airsync_cb_env.airsync_inst.airsync_cfg_hdl = p_data->add_result.attr_id;
+ }
+ break;
+ case BTA_GATTS_CONNECT_EVT:
+ //set the connection flag to true
+ airsync_env_clcb_alloc(p_data->conn.conn_id, p_data->conn.remote_bda);
+ break;
+ case BTA_GATTS_DISCONNECT_EVT:
+ //set the connection flag to true
+ airsync_cb_env.clcb.connected = false;
+ break;
+ case BTA_GATTS_OPEN_EVT:
+ break;
+ case BTA_GATTS_CLOSE_EVT:
+ if(airsync_cb_env.clcb.connected && (airsync_cb_env.clcb.conn_id == p_data->conn.conn_id))
+ {
+ //set the connection channal congested flag to true
+ airsync_cb_env.clcb.congest = p_data->congest.congested;
+ }
+ break;
+ case BTA_GATTS_LISTEN_EVT:
+ break;
+ case BTA_GATTS_CONGEST_EVT:
+ //set the congest flag
+ airsync_cb_env.clcb.congest = p_data->congest.congested;
+ break;
+ default:
+ break;
+ }
+}
+
+
+/*******************************************************************************
+**
+** Function AirSync_CreateService
+**
+** Description Create a Service for the airsync profile
+**
+** Returns NULL
+**
+*******************************************************************************/
+void AirSync_CreateService(void)
+{
+ tBTA_GATTS_IF server_if ;
+ tBT_UUID uuid = {LEN_UUID_16, {ATT_SVC_AIRSYNC}};
+ UINT16 num_handle = KEY_IDX_NB;
+ UINT8 inst = 0x00;
+ server_if = airsync_cb_env.gatt_if;
+ airsync_cb_env.inst_id = inst;
+
+ BTA_GATTS_CreateService(server_if,&uuid,inst,num_handle,true);
+
+}
+
+/*******************************************************************************
+**
+** Function airsync_env_clcb_alloc
+**
+** Description The function allocates a GATT profile connection link control block
+**
+** Returns NULL if not found. Otherwise pointer to the connection link block.
+**
+*******************************************************************************/
+tAirSync_CLCB *airsync_env_clcb_alloc (UINT16 conn_id, BD_ADDR remote_bda)
+{
+ tAirSync_CLCB *p_clcb = NULL;
+ p_clcb = &airsync_cb_env.clcb;
+
+ if(!p_clcb->in_use)
+ {
+ p_clcb->in_use = TRUE;
+ p_clcb->conn_id = conn_id;
+ LOG_ERROR("p_clcb->conn_id = %x\n",conn_id);
+ p_clcb->connected = TRUE;
+ memcpy(p_clcb->remote_bda,remote_bda,BD_ADDR_LEN);
+ }
+
+ return p_clcb;
+}
+
+/*******************************************************************************
+**
+** Function airsync_env_find_conn_id_by_bd_adddr
+**
+** Description The function searches all LCB with macthing bd address
+**
+** Returns total number of clcb found.
+**
+*******************************************************************************/
+UINT16 airsync_env_find_conn_id_by_bd_adddr(BD_ADDR remote_bda)
+{
+ UINT8 i_clcb;
+ tAirSync_CLCB *p_clcb = NULL;
+
+ for(i_clcb = 0, p_clcb = &airsync_cb_env.clcb; i_clcb < 1; i_clcb++, p_clcb++)
+ {
+ if(p_clcb->in_use && p_clcb->connected &&memcmp(p_clcb->remote_bda,remote_bda,BD_ADDR_LEN))
+ {
+ return p_clcb->conn_id;
+ }
+ }
+
+ return GATT_INVALID_CONN_ID;
+}
+
+
+/*******************************************************************************
+**
+** Function airsync_init
+**
+** Description Initializa the GATT Service for airsync profiles.
+**
+*******************************************************************************/
+tGATT_STATUS AirSync_Init(tAIRSYNC_CBACK *call_back)
+{
+ tBT_UUID app_uuid = {LEN_UUID_16,{ATT_SVC_AIRSYNC}};
+
+
+ if(airsync_cb_env.enabled)
+ {
+ LOG_ERROR("airsync svc already initaliezd\n");
+ return GATT_ERROR;
+ }
+ else
+ {
+ memset(&airsync_cb_env,0,sizeof(tAIRSYNC_CB_ENV));
+ }
+
+
+ if(call_back != NULL)
+ {
+ airsync_cb_env.airsync_inst.p_cback = call_back;
+ }
+
+
+ /* register the airsync profile to the BTA_GATTS module*/
+ BTA_GATTS_AppRegister(&app_uuid,airsync_profile_cb);
+
+ airsync_cb_env.enabled = TRUE;
+
+ return GATT_SUCCESS;
+}
+
+#endif ///WX_AIRSYNC_CFG
+
-// Copyright 2015-2016 Espressif Systems (Shanghai) PTE LTD\r
-//\r
-// Licensed under the Apache License, Version 2.0 (the "License");\r
-// you may not use this file except in compliance with the License.\r
-// You may obtain a copy of the License at\r
-\r
-// http://www.apache.org/licenses/LICENSE-2.0\r
-//\r
-// Unless required by applicable law or agreed to in writing, software\r
-// distributed under the License is distributed on an "AS IS" BASIS,\r
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
-// See the License for the specific language governing permissions and\r
-// limitations under the License.\r
-\r
-#include <stddef.h>\r
-#include <stdlib.h>\r
-#include <stdio.h>\r
-\r
-#include "freertos/FreeRTOS.h"\r
-#include "freertos/task.h"\r
-#include "freertos/queue.h"\r
-#include "freertos/semphr.h"\r
-#include "freertos/xtensa_api.h"\r
-#include "freertos/portmacro.h"\r
-#include "esp_types.h"\r
-#include "esp_system.h"\r
-#include "esp_task.h"\r
-#include "esp_intr.h"\r
-#include "esp_attr.h"\r
-#include "bt.h"\r
-\r
-#if CONFIG_BT_ENABLED\r
-\r
-/* not for user call, so don't put to include file */\r
-extern void btdm_osi_funcs_register(void *osi_funcs);\r
-extern void btdm_controller_init(void);\r
-\r
-\r
-#define BT_DEBUG(...)\r
-#define BT_API_CALL_CHECK(info, api_call, ret) \\r
-do{\\r
- esp_err_t __err = (api_call);\\r
- if ((ret) != __err) {\\r
- BT_DEBUG("%s %d %s ret=%d\n", __FUNCTION__, __LINE__, (info), __err);\\r
- return __err;\\r
- }\\r
-} while(0)\r
-\r
-struct osi_funcs_t {\r
- xt_handler (*_set_isr)(int n, xt_handler f, void *arg);\r
- void (*_ints_on)(unsigned int mask);\r
- void (*_interrupt_disable)(void);\r
- void (*_interrupt_restore)(void);\r
- void (*_task_yield)(void);\r
- void *(*_semphr_create)(uint32_t max, uint32_t init);\r
- int32_t (*_semphr_give_from_isr)(void *semphr, void *hptw);\r
- int32_t (*_semphr_take)(void *semphr, uint32_t block_time_ms);\r
- void *(*_mutex_create)(void);\r
- int32_t (*_mutex_lock)(void *mutex);\r
- int32_t (*_mutex_unlock)(void *mutex);\r
- esp_err_t (* _read_efuse_mac)(uint8_t mac[6]);\r
-};\r
-\r
-static portMUX_TYPE global_int_mux = portMUX_INITIALIZER_UNLOCKED;\r
-\r
-static void IRAM_ATTR interrupt_disable(void)\r
-{\r
- portENTER_CRITICAL(&global_int_mux);\r
-}\r
-\r
-static void IRAM_ATTR interrupt_restore(void)\r
-{\r
- portEXIT_CRITICAL(&global_int_mux);\r
-}\r
-\r
-static void * IRAM_ATTR semphr_create_wrapper(uint32_t max, uint32_t init)\r
-{\r
- return (void *)xSemaphoreCreateCounting(max, init);\r
-}\r
-\r
-static int32_t IRAM_ATTR semphr_give_from_isr_wrapper(void *semphr, void *hptw)\r
-{\r
- return (int32_t)xSemaphoreGiveFromISR(semphr, hptw);\r
-}\r
-\r
-static int32_t IRAM_ATTR semphr_take_wrapper(void *semphr, uint32_t block_time_ms)\r
-{\r
- return (int32_t)xSemaphoreTake(semphr, block_time_ms / portTICK_RATE_MS);\r
-}\r
-\r
-static void * IRAM_ATTR mutex_create_wrapper(void)\r
-{\r
- return (void *)xSemaphoreCreateMutex();\r
-}\r
-\r
-static int32_t IRAM_ATTR mutex_lock_wrapper(void *mutex)\r
-{\r
- return (int32_t)xSemaphoreTake(mutex, portMAX_DELAY);\r
-}\r
-\r
-static int32_t IRAM_ATTR mutex_unlock_wrapper(void *mutex)\r
-{\r
- return (int32_t)xSemaphoreGive(mutex);\r
-}\r
-\r
-static struct osi_funcs_t osi_funcs = {\r
- ._set_isr = xt_set_interrupt_handler,\r
- ._ints_on = xt_ints_on,\r
- ._interrupt_disable = interrupt_disable,\r
- ._interrupt_restore = interrupt_restore,\r
- ._task_yield = vPortYield,\r
- ._semphr_create = semphr_create_wrapper,\r
- ._semphr_give_from_isr = semphr_give_from_isr_wrapper,\r
- ._semphr_take = semphr_take_wrapper,\r
- ._mutex_create = mutex_create_wrapper,\r
- ._mutex_lock = mutex_lock_wrapper,\r
- ._mutex_unlock = mutex_unlock_wrapper,\r
- ._read_efuse_mac = system_efuse_read_mac,\r
-};\r
-\r
-static void bt_controller_task(void *pvParam)\r
-{\r
- btdm_osi_funcs_register(&osi_funcs);\r
- btdm_controller_init();\r
-}\r
-\r
-void bt_controller_init()\r
-{\r
- xTaskCreatePinnedToCore(bt_controller_task, "btController",\r
- ESP_TASK_BT_CONTROLLER_STACK, NULL,\r
- ESP_TASK_BT_CONTROLLER_PRIO, NULL, 0);\r
-}\r
-\r
-#endif\r
+// Copyright 2015-2016 Espressif Systems (Shanghai) PTE LTD
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+#include <stddef.h>
+#include <stdlib.h>
+#include <stdio.h>
+
+#include "freertos/FreeRTOS.h"
+#include "freertos/task.h"
+#include "freertos/queue.h"
+#include "freertos/semphr.h"
+#include "freertos/xtensa_api.h"
+#include "freertos/portmacro.h"
+#include "esp_types.h"
+#include "esp_system.h"
+#include "esp_task.h"
+#include "esp_intr.h"
+#include "esp_attr.h"
+#include "bt.h"
+
+#if CONFIG_BT_ENABLED
+
+/* not for user call, so don't put to include file */
+extern void btdm_osi_funcs_register(void *osi_funcs);
+extern void btdm_controller_init(void);
+
+
+#define BT_DEBUG(...)
+#define BT_API_CALL_CHECK(info, api_call, ret) \
+do{\
+ esp_err_t __err = (api_call);\
+ if ((ret) != __err) {\
+ BT_DEBUG("%s %d %s ret=%d\n", __FUNCTION__, __LINE__, (info), __err);\
+ return __err;\
+ }\
+} while(0)
+
+struct osi_funcs_t {
+ xt_handler (*_set_isr)(int n, xt_handler f, void *arg);
+ void (*_ints_on)(unsigned int mask);
+ void (*_interrupt_disable)(void);
+ void (*_interrupt_restore)(void);
+ void (*_task_yield)(void);
+ void *(*_semphr_create)(uint32_t max, uint32_t init);
+ int32_t (*_semphr_give_from_isr)(void *semphr, void *hptw);
+ int32_t (*_semphr_take)(void *semphr, uint32_t block_time_ms);
+ void *(*_mutex_create)(void);
+ int32_t (*_mutex_lock)(void *mutex);
+ int32_t (*_mutex_unlock)(void *mutex);
+ esp_err_t (* _read_efuse_mac)(uint8_t mac[6]);
+};
+
+static portMUX_TYPE global_int_mux = portMUX_INITIALIZER_UNLOCKED;
+
+static void IRAM_ATTR interrupt_disable(void)
+{
+ portENTER_CRITICAL(&global_int_mux);
+}
+
+static void IRAM_ATTR interrupt_restore(void)
+{
+ portEXIT_CRITICAL(&global_int_mux);
+}
+
+static void * IRAM_ATTR semphr_create_wrapper(uint32_t max, uint32_t init)
+{
+ return (void *)xSemaphoreCreateCounting(max, init);
+}
+
+static int32_t IRAM_ATTR semphr_give_from_isr_wrapper(void *semphr, void *hptw)
+{
+ return (int32_t)xSemaphoreGiveFromISR(semphr, hptw);
+}
+
+static int32_t IRAM_ATTR semphr_take_wrapper(void *semphr, uint32_t block_time_ms)
+{
+ return (int32_t)xSemaphoreTake(semphr, block_time_ms / portTICK_RATE_MS);
+}
+
+static void * IRAM_ATTR mutex_create_wrapper(void)
+{
+ return (void *)xSemaphoreCreateMutex();
+}
+
+static int32_t IRAM_ATTR mutex_lock_wrapper(void *mutex)
+{
+ return (int32_t)xSemaphoreTake(mutex, portMAX_DELAY);
+}
+
+static int32_t IRAM_ATTR mutex_unlock_wrapper(void *mutex)
+{
+ return (int32_t)xSemaphoreGive(mutex);
+}
+
+static struct osi_funcs_t osi_funcs = {
+ ._set_isr = xt_set_interrupt_handler,
+ ._ints_on = xt_ints_on,
+ ._interrupt_disable = interrupt_disable,
+ ._interrupt_restore = interrupt_restore,
+ ._task_yield = vPortYield,
+ ._semphr_create = semphr_create_wrapper,
+ ._semphr_give_from_isr = semphr_give_from_isr_wrapper,
+ ._semphr_take = semphr_take_wrapper,
+ ._mutex_create = mutex_create_wrapper,
+ ._mutex_lock = mutex_lock_wrapper,
+ ._mutex_unlock = mutex_unlock_wrapper,
+ ._read_efuse_mac = system_efuse_read_mac,
+};
+
+static void bt_controller_task(void *pvParam)
+{
+ btdm_osi_funcs_register(&osi_funcs);
+ btdm_controller_init();
+}
+
+void bt_controller_init()
+{
+ xTaskCreatePinnedToCore(bt_controller_task, "btController",
+ ESP_TASK_BT_CONTROLLER_STACK, NULL,
+ ESP_TASK_BT_CONTROLLER_PRIO, NULL, 0);
+}
+
+#endif