Kaynağa Gözat

components/bt: Merge branch 'feature/wechat_prf' into feature/btdm_bluedroid

warning: example 07 has complier errors;

# Conflicts:
#	components/bt/bluedroid/profiles/esp/ble_button/button_pro.c
#	components/bt/bluedroid/stack/btu/btu_init.c
wangmengyang 9 yıl önce
ebeveyn
işleme
9476dc2eb8
57 değiştirilmiş dosya ile 6006 ekleme ve 1130 silme
  1. 1 1
      components/bt/bluedroid/bta/dm/bta_dm_api.c
  2. 0 1
      components/bt/bluedroid/bta/dm/bta_dm_pm.c
  3. 1 1
      components/bt/bluedroid/bta/gatt/bta_gatts_act.c
  4. 3 3
      components/bt/bluedroid/bta/sys/bta_sys_main.c
  5. 461 461
      components/bt/bluedroid/device/controller.c
  6. 2 2
      components/bt/bluedroid/hci/hci_hal_h4.c
  7. 1 1
      components/bt/bluedroid/hci/hci_layer.c
  8. 1 1
      components/bt/bluedroid/include/bt_defs.h
  9. 100 100
      components/bt/bluedroid/osi/future.c
  10. 45 45
      components/bt/bluedroid/osi/include/future.h
  11. 2 0
      components/bt/bluedroid/osi/include/thread.h
  12. 154 0
      components/bt/bluedroid/profiles/core/bt_prf_sys_main.c
  13. 133 0
      components/bt/bluedroid/profiles/core/bt_prf_task.c
  14. 17 0
      components/bt/bluedroid/profiles/core/bt_profile_act.c
  15. 134 0
      components/bt/bluedroid/profiles/core/include/bt_prf_evt.h
  16. 86 0
      components/bt/bluedroid/profiles/core/include/bt_prf_sys.h
  17. 50 0
      components/bt/bluedroid/profiles/core/include/bt_prf_task.h
  18. 13 6
      components/bt/bluedroid/profiles/esp/ble_button/button_pro.c
  19. 3 0
      components/bt/bluedroid/profiles/esp/include/button_pro.h
  20. 115 0
      components/bt/bluedroid/profiles/esp/include/wx_airsync_prf.h
  21. 286 0
      components/bt/bluedroid/profiles/esp/wechat_AirSync/wx_airsync_prf.c
  22. 475 115
      components/bt/bluedroid/profiles/std/hid_le/hid_le_prf.c
  23. 65 8
      components/bt/bluedroid/profiles/std/include/hid_le_prf.h
  24. 6 1
      components/bt/bluedroid/profiles/std/include/prf_defs.h
  25. 1 1
      components/bt/bluedroid/stack/btm/btm_acl.c
  26. 2 2
      components/bt/bluedroid/stack/btm/btm_ble_cont_energy.c
  27. 4 4
      components/bt/bluedroid/stack/btu/btu_init.c
  28. 1 1
      components/bt/bluedroid/stack/l2cap/l2c_main.c
  29. 88 87
      components/bt/bluedroid/stack/smp/smp_act.c
  30. 2 2
      components/bt/bluedroid/stack/smp/smp_api.c
  31. 51 48
      components/bt/bluedroid/stack/smp/smp_keys.c
  32. 5 5
      components/bt/bluedroid/stack/smp/smp_l2c.c
  33. 7 8
      components/bt/bluedroid/stack/smp/smp_main.c
  34. 60 60
      components/bt/bluedroid/stack/smp/smp_utils.c
  35. 134 134
      components/bt/bt.c
  36. 3 0
      components/bt/component.mk
  37. 43 22
      examples/06_bluedroid_demos/components/bluedroid_demos/app_core/bt_app_core.c
  38. 108 0
      examples/06_bluedroid_demos/components/bluedroid_demos/app_core/bt_app_sec.c
  39. 130 0
      examples/06_bluedroid_demos/components/bluedroid_demos/app_profiles/app_WX_airsync/app_airsync_md5.c
  40. 160 0
      examples/06_bluedroid_demos/components/bluedroid_demos/app_profiles/app_WX_airsync/app_airsync_prf.c
  41. 414 0
      examples/06_bluedroid_demos/components/bluedroid_demos/app_profiles/app_WX_airsync/epb.c
  42. 565 0
      examples/06_bluedroid_demos/components/bluedroid_demos/app_profiles/app_WX_airsync/epb_mmbp.c
  43. 586 0
      examples/06_bluedroid_demos/components/bluedroid_demos/app_profiles/app_WX_airsync/mpbledemo2.c
  44. 51 0
      examples/06_bluedroid_demos/components/bluedroid_demos/app_profiles/app_WX_airsync/wechar_crc.c
  45. 450 0
      examples/06_bluedroid_demos/components/bluedroid_demos/app_profiles/app_WX_airsync/wechat_aes.c
  46. 97 8
      examples/06_bluedroid_demos/components/bluedroid_demos/app_project/SampleServerProject.c
  47. 3 2
      examples/06_bluedroid_demos/components/bluedroid_demos/component.mk
  48. 52 0
      examples/06_bluedroid_demos/components/bluedroid_demos/include/app_airsync_md5.h
  49. 47 0
      examples/06_bluedroid_demos/components/bluedroid_demos/include/app_airsync_prf.h
  50. 85 0
      examples/06_bluedroid_demos/components/bluedroid_demos/include/app_wechat_util.h
  51. 18 0
      examples/06_bluedroid_demos/components/bluedroid_demos/include/bt_app_api.h
  52. 78 0
      examples/06_bluedroid_demos/components/bluedroid_demos/include/bt_app_sec.h
  53. 117 0
      examples/06_bluedroid_demos/components/bluedroid_demos/include/epb.h
  54. 248 0
      examples/06_bluedroid_demos/components/bluedroid_demos/include/epb_mmbp.h
  55. 140 0
      examples/06_bluedroid_demos/components/bluedroid_demos/include/mpbledemo2.h
  56. 29 0
      examples/06_bluedroid_demos/components/bluedroid_demos/include/wechar_crc.h
  57. 73 0
      examples/06_bluedroid_demos/components/bluedroid_demos/include/wechat_aes.h

+ 1 - 1
components/bt/bluedroid/bta/dm/bta_dm_api.c

@@ -983,7 +983,7 @@ void BTA_DmSetBleAdvParams (UINT16 adv_int_min, UINT16 adv_int_max,
 #if BLE_INCLUDED == TRUE
     tBTA_DM_API_BLE_ADV_PARAMS    *p_msg;
 
-    APPL_TRACE_API ("BTA_DmSetBleAdvParam: %d, %d", adv_int_min, adv_int_max);
+    APPL_TRACE_API ("BTA_DmSetBleAdvParam: %d, %d\n", adv_int_min, adv_int_max);
 
     if ((p_msg = (tBTA_DM_API_BLE_ADV_PARAMS *) GKI_getbuf(sizeof(tBTA_DM_API_BLE_ADV_PARAMS))) != NULL)
     {

+ 0 - 1
components/bt/bluedroid/bta/dm/bta_dm_pm.c

@@ -636,7 +636,6 @@ static void bta_dm_pm_set_mode(BD_ADDR peer_addr, tBTA_DM_PM_ACTION pm_request,
                     remaining_ticks = bta_dm_pm_get_remaining_ticks(&bta_dm_cb.pm_timer[i].timer[timer_idx]);
                     if (remaining_ticks < timeout)
                     {
-			ets_printf("remain 00\n");
                         /* Cancel and restart the timer */
                         /*
                          * TODO: The value of pm_action[timer_idx] is

+ 1 - 1
components/bt/bluedroid/bta/gatt/bta_gatts_act.c

@@ -620,7 +620,7 @@ void bta_gatts_send_rsp (tBTA_GATTS_CB *p_cb, tBTA_GATTS_DATA * p_msg)
                         p_msg->api_rsp.status,
                         (tGATTS_RSP *)p_msg->api_rsp.p_rsp) != GATT_SUCCESS)
     {
-        APPL_TRACE_ERROR("Sending response failed");
+        APPL_TRACE_ERROR("Sending response failed\n");
     }
 
 }

+ 3 - 3
components/bt/bluedroid/bta/sys/bta_sys_main.c

@@ -224,7 +224,7 @@ BOOLEAN bta_sys_sm_execute(BT_HDR *p_msg)
     UINT8               action;
     int                 i;
 
-    APPL_TRACE_EVENT("bta_sys_sm_execute state:%d, event:0x%x",  bta_sys_cb.state, p_msg->event);
+    APPL_TRACE_EVENT("bta_sys_sm_execute state:%d, event:0x%x\n",  bta_sys_cb.state, p_msg->event);
 
     /* look up the state table for the current state */
     state_table = bta_sys_st_tbl[bta_sys_cb.state];
@@ -512,7 +512,7 @@ void bta_sys_event(BT_HDR *p_msg)
     UINT8       id;
     BOOLEAN     freebuf = TRUE;
 
-    APPL_TRACE_EVENT("BTA got event 0x%x", p_msg->event);
+    APPL_TRACE_EVENT("BTA got event 0x%x\n", p_msg->event);
 
     /* get subsystem id from event */
     id = (UINT8) (p_msg->event >> 8);
@@ -524,7 +524,7 @@ void bta_sys_event(BT_HDR *p_msg)
     }
     else
     {
-        APPL_TRACE_WARNING("BTA got unregistered event id %d", id);
+        APPL_TRACE_WARNING("BTA got unregistered event id %d\n", id);
     }
 
     if (freebuf)

+ 461 - 461
components/bt/bluedroid/device/controller.c

@@ -1,461 +1,461 @@
-/******************************************************************************
- *
- *  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;
-}
-
+/******************************************************************************
+ *
+ *  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;
+}
+

+ 2 - 2
components/bt/bluedroid/hci/hci_hal_h4.c

@@ -82,7 +82,7 @@ static void hci_hal_env_init(
   if (hci_hal_env.rx_q)
     fixed_queue_register_dequeue(hci_hal_env.rx_q, event_uart_has_bytes);
   else
-    LOG_ERROR("%s unable to create rx queue.", __func__);
+    LOG_ERROR("%s unable to create rx queue.\n", __func__);
 
   return;
 }
@@ -97,7 +97,7 @@ static bool hal_open(const hci_hal_callbacks_t *upper_callbacks) {
 
   hci_hal_env_init(HCI_HAL_SERIAL_BUFFER_SIZE, SIZE_MAX);
   
-  xHciH4Queue = xQueueCreate(3, sizeof(void *));
+  xHciH4Queue = xQueueCreate(60, sizeof(void *));
   xTaskCreate(hci_hal_h4_rx_handler, "HciH4T", 4096+2048, NULL, configMAX_PRIORITIES - 3, &xHciH4TaskHandle);
 
   //register vhci host cb

+ 1 - 1
components/bt/bluedroid/hci/hci_layer.c

@@ -111,7 +111,7 @@ int hci_start_up(void) {
   if (hci_layer_init_env())
     goto error;
 
-  xHciHostQueue = xQueueCreate(3, sizeof(void *));
+  xHciHostQueue = xQueueCreate(60, sizeof(void *));
   xTaskCreate(hci_host_thread_handler, "HciHostT", (4096+2048), NULL, configMAX_PRIORITIES - 3, &xHciHostTaskHandle);
 
   packet_fragmenter->init(&packet_fragmenter_callbacks);

+ 1 - 1
components/bt/bluedroid/include/bt_defs.h

@@ -14,7 +14,7 @@
 #define UNUSED(x)                   (void)(x)
 
 #ifndef SIZE_MAX
-#define SIZE_MAX                    128
+#define SIZE_MAX                    254
 #endif
 /*Timer Related Defination*/
 

+ 100 - 100
components/bt/bluedroid/osi/future.c

@@ -1,100 +1,100 @@
-/******************************************************************************
- *
- *  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);
-}
+/******************************************************************************
+ *
+ *  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);
+}

+ 45 - 45
components/bt/bluedroid/osi/include/future.h

@@ -1,45 +1,45 @@
-/******************************************************************************
- *
- *  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__ */
+/******************************************************************************
+ *
+ *  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__ */

+ 2 - 0
components/bt/bluedroid/osi/include/thread.h

@@ -16,6 +16,8 @@ struct task_evt {
 typedef struct task_evt TaskEvt_t;
 
 enum {
+	SIG_PRF_START_UP = 0xfc,
+	SIG_PRF_WORK	= 0xfd,
     SIG_BTU_START_UP = 0xfe,
     SIG_BTU_WORK = 0xff
 };

+ 154 - 0
components/bt/bluedroid/profiles/core/bt_prf_sys_main.c

@@ -0,0 +1,154 @@
+/**
+ ****************************************************************************************
+ *
+ * @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);
+    }
+}
+
+
+
+

+ 133 - 0
components/bt/bluedroid/profiles/core/bt_prf_task.c

@@ -0,0 +1,133 @@
+/**
+ ****************************************************************************************
+ *
+ * @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)
+        return;
+
+    evt->sig = sig;
+    evt->par = 0;
+
+    if (xQueueSend(xProfileQueue, &evt, 10/portTICK_RATE_MS) != pdTRUE) {
+            ets_printf("xProfileQueue failed\n");
+    }
+}
+
+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);
+		if(p_msg != NULL)
+		{
+			bt_prf_sys_event(p_msg);
+		}
+    }
+}
+
+
+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)
+{
+	
+}
+
+
+

+ 17 - 0
components/bt/bluedroid/profiles/core/bt_profile_act.c

@@ -0,0 +1,17 @@
+/**
+ ****************************************************************************************
+ *
+ * @file bt_profile_act.c
+ *
+ * @brief Application entry point
+ *
+ * Copyright (C) Espressif 2016
+ * Created by Yulong at 2016/10/13
+ *
+ *
+ ****************************************************************************************
+ */
+
+
+ 
+

+ 134 - 0
components/bt/bluedroid/profiles/core/include/bt_prf_evt.h

@@ -0,0 +1,134 @@
+/**
+ ****************************************************************************************
+ *
+ * @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
+
+
+                      
+};
+
+

+ 86 - 0
components/bt/bluedroid/profiles/core/include/bt_prf_sys.h

@@ -0,0 +1,86 @@
+/**
+ ****************************************************************************************
+ *
+ * @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);
+/* 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;
+    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__

+ 50 - 0
components/bt/bluedroid/profiles/core/include/bt_prf_task.h

@@ -0,0 +1,50 @@
+/**
+ ****************************************************************************************
+ *
+ * @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
+************************************
+*/
+
+
+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__

+ 13 - 6
components/bt/bluedroid/profiles/esp/ble_button/button_pro.c

@@ -26,9 +26,13 @@
 #include "bta_api.h"
 #include "bta_gatt_api.h"
 #include "bta_gatts_int.h"
-
 #include "button_pro.h"
 
+#include "prf_defs.h"
+
+#if (BUT_PROFILE_CFG)
+
+
 #define ARRAY_SIZE(x)	(sizeof(x)/sizeof((x)[0]))
 
 tBUTTON_CB_ENV button_cb_env;
@@ -66,7 +70,7 @@ static void button_profile_cb(tBTA_GATTS_EVT event, tBTA_GATTS *p_data)
 	LOG_ERROR("button profile cb event = %x\n",event);
 	switch(event)	
 	{
-		case BTA_GATTS_REG_EVT:
+		case BTA_GATTS_REG_EVT:
 			
 			LOG_ERROR("p_data->reg_oper.status = %x\n",p_data->reg_oper.status);
 			LOG_ERROR("(p_data->reg_oper.uuid.uu.uuid16=%x\n",p_data->reg_oper.uuid.uu.uuid16);
@@ -104,7 +108,8 @@ static void button_profile_cb(tBTA_GATTS_EVT event, tBTA_GATTS *p_data)
 			p_rec_data = &p_data->req_data.p_data->write_req.value[0];
 			//	button_msg_notify(len,p_rec_data);	
 			(*p_inst->p_cback)(button_cb_env.button_inst.app_id,net_event,len,p_rec_data);
-			}
+				
+		}		
 			break;
 		case BTA_GATTS_CONF_EVT:
 			
@@ -193,7 +198,7 @@ void Button_CreateService(void)
 {
 	tBTA_GATTS_IF server_if ;
 	tBT_UUID uuid = {LEN_UUID_16, {ATT_SVC_BUTTON}};
-	UINT16 num_handle = KEY_IDX_NB;
+	UINT16 num_handle = KEY_IDX_NB;
 	UINT8 inst = 0x00;
 	server_if = button_cb_env.gatt_if;
 	button_cb_env.inst_id = inst;
@@ -201,7 +206,7 @@ void Button_CreateService(void)
 	//{
 	//	LOG_ERROR("button service added error.");
 	//}	
-	BTA_GATTS_CreateService(server_if,&uuid,inst,num_handle,true);
+	BTA_GATTS_CreateService(server_if,&uuid,inst,num_handle,true);
 	
 }
 
@@ -321,7 +326,7 @@ tGATT_STATUS button_init (tBU_CBACK *call_back)
         }
 
 	
-	/* register the button profile to the BTA_GATTS module*/
+	/* register the button profile to the BTA_GATTS module*/
 	 BTA_GATTS_AppRegister(&app_uuid,button_profile_cb);
 
 	button_cb_env.enabled = TRUE;
@@ -345,3 +350,5 @@ void button_msg_notify(UINT8 len, UINT8 *button_msg)
 	 BTA_GATTS_HandleValueIndication (conn_id, attr_id, len,
                                       button_msg, rsp);
 }
+
+#endif	///BUT_PROFILE_CFG

+ 3 - 0
components/bt/bluedroid/profiles/esp/include/button_pro.h

@@ -11,7 +11,9 @@
  *
  ****************************************************************************************
  */
+#include "prf_defs.h"
 
+#if (BUT_PROFILE_CFG)
 #include "bt_target.h"
 #include "gatt_api.h"
 #include "gattdefs.h"
@@ -117,3 +119,4 @@ void button_msg_notify(UINT8 len, UINT8 *button_msg);
 
 extern tBUTTON_CB_ENV button_cb_env;
 
+#endif ///BUT_PROFILE_CFG

+ 115 - 0
components/bt/bluedroid/profiles/esp/include/wx_airsync_prf.h

@@ -0,0 +1,115 @@
+/**
+ ****************************************************************************************
+ *
+ * @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
+ 

+ 286 - 0
components/bt/bluedroid/profiles/esp/wechat_AirSync/wx_airsync_prf.c

@@ -0,0 +1,286 @@
+/**
+ ****************************************************************************************
+ *
+ * @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
+

+ 475 - 115
components/bt/bluedroid/profiles/std/hid_le/hid_le_prf.c

@@ -14,13 +14,173 @@
 #include <string.h>
 #include "hid_le_prf.h"
 #include "prf_defs.h"
-#include "bta_gatt_api.h"
 
+#if	(HIDD_LE_PROFILE_CFG)
 tHIDD_LE_ENV hidd_le_env;
 
+#define HI_UINT16(a) (((a) >> 8) & 0xFF)
+#define LO_UINT16(a) ((a) & 0xFF)
+
+
+// HID Information characteristic value
+static const UINT8 hidInfo[HID_INFORMATION_LEN] =
+{
+  LO_UINT16(0x0111), HI_UINT16(0x0111),             // bcdHID (USB HID version)
+  0x00,                                             // bCountryCode
+  HID_KBD_FLAGS                                     // Flags
+};
+
+// HID Report Map characteristic value
+// Keyboard report descriptor (using format for Boot interface descriptor)
+static const UINT8 hidReportMap[] =
+{
+  0x05, 0x01,  // Usage Page (Generic Desktop)
+  0x09, 0x02,  // Usage (Mouse)
+  0xA1, 0x01,  // Collection (Application)
+  0x85, 0x01,  // Report Id (1)
+  0x09, 0x01,  //   Usage (Pointer)
+  0xA1, 0x00,  //   Collection (Physical)
+  0x05, 0x09,  //     Usage Page (Buttons)
+  0x19, 0x01,  //     Usage Minimum (01) - Button 1
+  0x29, 0x03,  //     Usage Maximum (03) - Button 3
+  0x15, 0x00,  //     Logical Minimum (0)
+  0x25, 0x01,  //     Logical Maximum (1)
+  0x75, 0x01,  //     Report Size (1)
+  0x95, 0x03,  //     Report Count (3)
+  0x81, 0x02,  //     Input (Data, Variable, Absolute) - Button states
+  0x75, 0x05,  //     Report Size (5)
+  0x95, 0x01,  //     Report Count (1)
+  0x81, 0x01,  //     Input (Constant) - Padding or Reserved bits
+  0x05, 0x01,  //     Usage Page (Generic Desktop)
+  0x09, 0x30,  //     Usage (X)
+  0x09, 0x31,  //     Usage (Y)
+  0x09, 0x38,  //     Usage (Wheel)
+  0x15, 0x81,  //     Logical Minimum (-127)
+  0x25, 0x7F,  //     Logical Maximum (127)
+  0x75, 0x08,  //     Report Size (8)
+  0x95, 0x03,  //     Report Count (3)
+  0x81, 0x06,  //     Input (Data, Variable, Relative) - X & Y coordinate
+  0xC0,        //   End Collection
+  0xC0,        // End Collection
+
+  0x05, 0x01,  // Usage Pg (Generic Desktop)
+  0x09, 0x06,  // Usage (Keyboard)
+  0xA1, 0x01,  // Collection: (Application)
+  0x85, 0x02,  // Report Id (2)
+               //
+  0x05, 0x07,  //   Usage Pg (Key Codes)
+  0x19, 0xE0,  //   Usage Min (224)
+  0x29, 0xE7,  //   Usage Max (231)
+  0x15, 0x00,  //   Log Min (0)
+  0x25, 0x01,  //   Log Max (1)
+               //
+               //   Modifier byte
+  0x75, 0x01,  //   Report Size (1)
+  0x95, 0x08,  //   Report Count (8)
+  0x81, 0x02,  //   Input: (Data, Variable, Absolute)
+               //
+               //   Reserved byte
+  0x95, 0x01,  //   Report Count (1)
+  0x75, 0x08,  //   Report Size (8)
+  0x81, 0x01,  //   Input: (Constant)
+               //
+               //   LED report
+  0x95, 0x05,  //   Report Count (5)
+  0x75, 0x01,  //   Report Size (1)
+  0x05, 0x08,  //   Usage Pg (LEDs)
+  0x19, 0x01,  //   Usage Min (1)
+  0x29, 0x05,  //   Usage Max (5)
+  0x91, 0x02,  //   Output: (Data, Variable, Absolute)
+               //
+               //   LED report padding
+  0x95, 0x01,  //   Report Count (1)
+  0x75, 0x03,  //   Report Size (3)
+  0x91, 0x01,  //   Output: (Constant)
+               //
+               //   Key arrays (6 bytes)
+  0x95, 0x06,  //   Report Count (6)
+  0x75, 0x08,  //   Report Size (8)
+  0x15, 0x00,  //   Log Min (0)
+  0x25, 0x65,  //   Log Max (101)
+  0x05, 0x07,  //   Usage Pg (Key Codes)
+  0x19, 0x00,  //   Usage Min (0)
+  0x29, 0x65,  //   Usage Max (101)
+  0x81, 0x00,  //   Input: (Data, Array)
+               //
+  0xC0,        // End Collection
+               //
+  0x05, 0x0C,   // Usage Pg (Consumer Devices)
+  0x09, 0x01,   // Usage (Consumer Control)
+  0xA1, 0x01,   // Collection (Application)
+  0x85, 0x03,   // Report Id (3)
+  0x09, 0x02,   //   Usage (Numeric Key Pad)
+  0xA1, 0x02,   //   Collection (Logical)
+  0x05, 0x09,   //     Usage Pg (Button)
+  0x19, 0x01,   //     Usage Min (Button 1)
+  0x29, 0x0A,   //     Usage Max (Button 10)
+  0x15, 0x01,   //     Logical Min (1)
+  0x25, 0x0A,   //     Logical Max (10)
+  0x75, 0x04,   //     Report Size (4)
+  0x95, 0x01,   //     Report Count (1)
+  0x81, 0x00,   //     Input (Data, Ary, Abs)
+  0xC0,         //   End Collection
+  0x05, 0x0C,   //   Usage Pg (Consumer Devices)
+  0x09, 0x86,   //   Usage (Channel)
+  0x15, 0xFF,   //   Logical Min (-1)
+  0x25, 0x01,   //   Logical Max (1)
+  0x75, 0x02,   //   Report Size (2)
+  0x95, 0x01,   //   Report Count (1)
+  0x81, 0x46,   //   Input (Data, Var, Rel, Null)
+  0x09, 0xE9,   //   Usage (Volume Up)
+  0x09, 0xEA,   //   Usage (Volume Down)
+  0x15, 0x00,   //   Logical Min (0)
+  0x75, 0x01,   //   Report Size (1)
+  0x95, 0x02,   //   Report Count (2)
+  0x81, 0x02,   //   Input (Data, Var, Abs)
+  0x09, 0xE2,   //   Usage (Mute)
+  0x09, 0x30,   //   Usage (Power)
+  0x09, 0x83,   //   Usage (Recall Last)
+  0x09, 0x81,   //   Usage (Assign Selection)
+  0x09, 0xB0,   //   Usage (Play)
+  0x09, 0xB1,   //   Usage (Pause)
+  0x09, 0xB2,   //   Usage (Record)
+  0x09, 0xB3,   //   Usage (Fast Forward)
+  0x09, 0xB4,   //   Usage (Rewind)
+  0x09, 0xB5,   //   Usage (Scan Next)
+  0x09, 0xB6,   //   Usage (Scan Prev)
+  0x09, 0xB7,   //   Usage (Stop)
+  0x15, 0x01,   //   Logical Min (1)
+  0x25, 0x0C,   //   Logical Max (12)
+  0x75, 0x04,   //   Report Size (4)
+  0x95, 0x01,   //   Report Count (1)
+  0x81, 0x00,   //   Input (Data, Ary, Abs)
+  0x09, 0x80,   //   Usage (Selection)
+  0xA1, 0x02,   //   Collection (Logical)
+  0x05, 0x09,   //     Usage Pg (Button)
+  0x19, 0x01,   //     Usage Min (Button 1)
+  0x29, 0x03,   //     Usage Max (Button 3)
+  0x15, 0x01,   //     Logical Min (1)
+  0x25, 0x03,   //     Logical Max (3)
+  0x75, 0x02,   //     Report Size (2)
+  0x81, 0x00,   //     Input (Data, Ary, Abs)
+  0xC0,         //   End Collection
+  0x81, 0x03,   //   Input (Const, Var, Abs)
+  0xC0         // End Collection
+};
+
+// HID report map length
+UINT8 hidReportMapLen = sizeof(hidReportMap);
+
+UINT8 hidProtocolMode = HID_PROTOCOL_MODE_REPORT;
+
+// HID report mapping table
+static hidRptMap_t  hidRptMap[HID_NUM_REPORTS];
+
+
 tBT_UUID char_info_uuid = {LEN_UUID_16, {CHAR_HID_INFO_UUID}};
 tBT_UUID char_ctnl_pt_uuid = {LEN_UUID_16, {CHAR_HID_CTNL_PT_UUID}};
 tBT_UUID char_report_map_uuid = {LEN_UUID_16, {CHAR_REPORT_MAP_UUID}};
+tBT_UUID char_report_uuid = {LEN_UUID_16, {CHAR_REPORT_UUID}};
 tBT_UUID char_proto_mode_uuid = {LEN_UUID_16, {CHAR_PROTOCOL_MODE_UUID}};
 tBT_UUID char_kb_in_report_uuid = {LEN_UUID_16, {CHAR_BOOT_KB_IN_REPORT_UUID}};
 tBT_UUID char_kb_out_report_uuid = {LEN_UUID_16,{CHAR_BOOT_KB_OUT_REPORT_UUID}};
@@ -31,88 +191,90 @@ tBT_UUID char_mouse_in_report_uuid = {LEN_UUID_16,{CHAR_BOOT_MOUSE_IN_REPORT_UUI
 /// Full HID device Database Description - Used to add attributes into the database
 const  tCHAR_DESC hids_char_db[HIDD_LE_CHAR_MAX] =
 {
-	// HID Information Characteristic Value
-	[HIDD_LE_INFO_CHAR]                        = {
-		&char_info_uuid,
-		GATT_PERM_READ,
-		GATT_CHAR_PROP_BIT_READ
-	},
-
-	// HID Control Point Characteristic Value
-	[HIDD_LE_CTNL_PT_CHAR]                     = {
-		&char_ctnl_pt_uuid,
-		GATT_PERM_WRITE,
-		GATT_CHAR_PROP_BIT_WRITE_NR
-	},
-
-	// Report Map Characteristic Value
-	[HIDD_LE_REPORT_MAP_CHAR]                  = {
-		&char_report_map_uuid,
-		GATT_PERM_READ,
-		GATT_CHAR_PROP_BIT_READ
-	},
-
-	// Protocol Mode Characteristic Declaration
-	[HIDD_LE_PROTO_MODE_CHAR]                  = {
-		&char_proto_mode_uuid,
-		GATT_PERM_READ,
-		GATT_CHAR_PROP_BIT_READ,
-	},
-
-	// Boot Keyboard Input Report Characteristic Value
-	[HIDD_LE_BOOT_KB_IN_REPORT_CHAR]           = {
-		&char_kb_in_report_uuid,
-		GATT_PERM_READ,
-		(GATT_CHAR_PROP_BIT_READ|GATT_CHAR_PROP_BIT_NOTIFY),
-
-	},
-
-	// Boot Keyboard Output Report Characteristic Value
-	[HIDD_LE_BOOT_KB_OUT_REPORT_CHAR]          = {
-		&char_kb_out_report_uuid,
-		GATT_PERM_READ,
-		(GATT_CHAR_PROP_BIT_READ|GATT_CHAR_PROP_BIT_WRITE|GATT_CHAR_PROP_BIT_WRITE_NR)
-	},
-
-	// Boot Mouse Input Report Characteristic Value
-	[HIDD_LE_BOOT_MOUSE_IN_REPORT_CHAR]        = {
-		&char_mouse_in_report_uuid,
-		GATT_PERM_READ,
-		(GATT_CHAR_PROP_BIT_READ|GATT_CHAR_PROP_BIT_NOTIFY),
-	},
+    // HID Information Characteristic Value
+    [HIDD_LE_INFO_CHAR]                   		 = {
+    												&char_info_uuid,
+                                                   	GATT_PERM_READ,
+                                                   	GATT_CHAR_PROP_BIT_READ
+                                                   },
+
+    // HID Control Point Characteristic Value
+    [HIDD_LE_CTNL_PT_CHAR]                 = {
+    											   &char_ctnl_pt_uuid,
+                                                   GATT_PERM_WRITE,
+												   GATT_CHAR_PROP_BIT_WRITE_NR
+											 },
+
+    // Report Map Characteristic Value
+    [HIDD_LE_REPORT_MAP_CHAR]               = {
+    											   &char_report_map_uuid,
+                                                   GATT_PERM_READ,
+                                                   GATT_CHAR_PROP_BIT_READ
+                                               },
+    // Report Characteristic Value                                             
+	[HIDD_LE_REPORT_CHAR]				 	= {
+													&char_report_uuid,
+													 (GATT_PERM_READ|GATT_PERM_WRITE),
+													 (GATT_CHAR_PROP_BIT_READ|GATT_CHAR_PROP_BIT_WRITE|GATT_CHAR_PROP_BIT_WRITE_NR)
+											   },	
+    // Protocol Mode Characteristic Declaration
+    [HIDD_LE_PROTO_MODE_CHAR]                 = {
+                                                   &char_proto_mode_uuid,
+                                                   GATT_PERM_READ,
+                                                   GATT_CHAR_PROP_BIT_READ,
+    											},
+    											
+    // Boot Keyboard Input Report Characteristic Value
+    [HIDD_LE_BOOT_KB_IN_REPORT_CHAR]           = {
+    											   &char_kb_in_report_uuid,
+    											   GATT_PERM_READ,
+                                                   (GATT_CHAR_PROP_BIT_READ|GATT_CHAR_PROP_BIT_NOTIFY),
+                                                   
+                                                 },
+    
+    // Boot Keyboard Output Report Characteristic Value
+    [HIDD_LE_BOOT_KB_OUT_REPORT_CHAR]          = {
+    												&char_kb_out_report_uuid,
+                                                   GATT_PERM_READ,
+												   (GATT_CHAR_PROP_BIT_READ|GATT_CHAR_PROP_BIT_WRITE|GATT_CHAR_PROP_BIT_WRITE_NR)
+												   },
+
+    // Boot Mouse Input Report Characteristic Value
+    [HIDD_LE_BOOT_MOUSE_IN_REPORT_CHAR]        = {
+    												&char_mouse_in_report_uuid,
+                                                   GATT_PERM_READ,
+                                                   (GATT_CHAR_PROP_BIT_READ|GATT_CHAR_PROP_BIT_NOTIFY),
+                                                 },
 };
 
-
-//tBT_UUID hid_uuid = {LEN_UUID_16, {ATT_SVC_BUTTON}};
-
 static void HID_AddCharacteristic(const tCHAR_DESC *char_desc);
 
 /*****************************************************************************
- **  Constants
- *****************************************************************************/
+**  Constants
+*****************************************************************************/
 static void hidd_le_profile_cb(tBTA_GATTS_EVT event,  tBTA_GATTS *p_data);
 
 /*******************************************************************************
- **
- ** Function         hidd_le_profile_cb
- **
- ** Description      the callback function after the hid device profile has been register to the BTA manager module
- **
- ** Returns          NULL 
- **
- *******************************************************************************/
+**
+** Function         hidd_le_profile_cb
+**
+** Description      the callback function after the hid device profile has been register to the BTA manager module
+**
+** Returns          NULL 
+**
+*******************************************************************************/
 static void HID_AddCharacteristic(const tCHAR_DESC *char_desc)
 {	
 	UINT16 service_id;
 	if(char_desc == NULL)
 	{
-		LOG_ERROR("Invalid hid characteristic");
+		LOG_ERROR("Invalid hid characteristic\n");
 		return;
 	}
 	//check the hid device serivce has been register to the data base or not
 	if(!hidd_le_env.enabled) 
 	{
-		LOG_ERROR("The hid device didn't register yet");
+		LOG_ERROR("The hid device didn't register yet\n");
 		return;
 	}
 	//get the service id from the env whitch has been register
@@ -121,36 +283,39 @@ static void HID_AddCharacteristic(const tCHAR_DESC *char_desc)
 	{
 		// start added the charact to the data base
 		BTA_GATTS_AddCharacteristic(service_id,
-				char_desc->char_uuid,
-				char_desc->perm,
-				char_desc->prop);
+								char_desc->char_uuid,
+								char_desc->perm,
+								char_desc->prop);
 	}
 }
 
 
 /*******************************************************************************
- **
- ** Function         hidd_le_profile_cb
- **
- ** Description      the callback function after the hid device profile has been register to the BTA manager module
- **
- ** Returns          NULL 
- **
- *******************************************************************************/
+**
+** Function         hidd_le_profile_cb
+**
+** Description      the callback function after the hid device profile has been register to the BTA manager module
+**
+** Returns          NULL 
+**
+*******************************************************************************/
 static void hidd_le_profile_cb(tBTA_GATTS_EVT event, tBTA_GATTS *p_data)
 {
 	tBTA_GATTS_RSP rsp;
 	tBT_UUID uuid = {LEN_UUID_16, {ATT_SVC_HID}};
 	static UINT8 hid_char_idx;
 	tHIDD_CLCB *p_clcb = NULL;
+	UINT8 app_id = 0xff;
+	
 	switch(event)
 	{
 		case BTA_GATTS_REG_EVT:
 			//check the register of the hid device profile has been succeess or not
 			if(p_data->reg_oper.status != BTA_GATT_OK)
 			{
-				LOG_ERROR("button profile register failed\n");
+				LOG_ERROR("hidd profile register failed\n");
 			}
+			hidd_le_env.hidd_inst.app_id = app_id;
 			//save the gatt interface in the hid device ENV
 			hidd_le_env.gatt_if = p_data->reg_oper.server_if;
 			//set the env flag to enable
@@ -158,9 +323,9 @@ static void hidd_le_profile_cb(tBTA_GATTS_EVT event, tBTA_GATTS *p_data)
 			//create the hid device service to the service data base.
 			if(p_data->reg_oper.uuid.uu.uuid16 == ATT_SVC_HID)
 			{
-				hidd_le_CreateService(true);
+				 hidd_le_CreateService(true);
 			}
-			break;
+		    break;
 		case BTA_GATTS_CREATE_EVT:
 			if(p_data->create.uuid.uu.uuid16 == ATT_SVC_HID)
 			{
@@ -173,39 +338,78 @@ static void hidd_le_profile_cb(tBTA_GATTS_EVT event, tBTA_GATTS *p_data)
 				HID_AddCharacteristic(&hids_char_db[hid_char_idx]);
 				hid_char_idx++;
 			}
-
+			
 			break;
 		case BTA_GATTS_ADD_INCL_SRVC_EVT:
-
+			
 			break;
 		case BTA_GATTS_ADD_CHAR_EVT:
-			if(hid_char_idx < HIDD_LE_CHAR_MAX)	//added the characteristic until the index overflow
+			//save the charateristic handle to the env
+			hidd_le_env.hidd_inst.att_tbl[hid_char_idx-1] = p_data->add_result.attr_id;
+			LOG_ERROR("hanlder = %x, p_data->add_result.char_uuid.uu.uuid16 = %x\n",p_data->add_result.attr_id,
+				p_data->add_result.char_uuid.uu.uuid16);
+			LOG_ERROR("hid_char_idx=%x\n",hid_char_idx);
+			if(hid_char_idx <= HIDD_LE_CHAR_MAX)	//added the characteristic until the index overflow
 			{
-				HID_AddCharacteristic(&hids_char_db[hid_char_idx]);
+				
 				if((p_data->add_result.char_uuid.uu.uuid16 == CHAR_BOOT_KB_IN_REPORT_UUID) ||
-						(p_data->add_result.char_uuid.uu.uuid16 == CHAR_BOOT_MOUSE_IN_REPORT_UUID))
+					(p_data->add_result.char_uuid.uu.uuid16 == CHAR_BOOT_MOUSE_IN_REPORT_UUID))
 				{ 
 					// add the gattc config descriptor to the notify charateristic
 					//tBTA_GATT_PERM perm = (GATT_PERM_WRITE|GATT_PERM_WRITE);
 					uuid.uu.uuid16 = GATT_UUID_CHAR_CLIENT_CONFIG;
-
+					LOG_ERROR("p_data->add_result.char_uuid.uu.uuid16 = %x\n",
+						p_data->add_result.char_uuid.uu.uuid16);
 					BTA_GATTS_AddCharDescriptor (hidd_le_env.hidd_clcb.cur_srvc_id,
-							GATT_PERM_WRITE,
-							&uuid);
+                                  			 	GATT_PERM_WRITE,
+                                  				&uuid);
+					
+					
+					break;
 				}
+				HID_AddCharacteristic(&hids_char_db[hid_char_idx]);
 			}
 			hid_char_idx++;
 			break;
 		case BTA_GATTS_ADD_CHAR_DESCR_EVT:
-
+			if(p_data->add_result.char_uuid.uu.uuid16 == GATT_UUID_CHAR_CLIENT_CONFIG)
+			{ 
+				uuid.uu.uuid16 = GATT_UUID_RPT_REF_DESCR;
+				BTA_GATTS_AddCharDescriptor (hidd_le_env.hidd_clcb.cur_srvc_id,
+                                			 	GATT_PERM_READ,
+                                  				&uuid);
+				LOG_ERROR("p_data->add_result.char_uuid.uu.uuid16 = %x\n",
+					p_data->add_result.char_uuid.uu.uuid16);
+			}
+			if(p_data->add_result.char_uuid.uu.uuid16 == GATT_UUID_RPT_REF_DESCR)
+			{
+				if(hid_char_idx < HIDD_LE_CHAR_MAX)
+				{
+					HID_AddCharacteristic(&hids_char_db[hid_char_idx]);
+					hid_char_idx++;
+				}
+			}
+			break;
+		case BTA_GATTS_READ_EVT:
+		{
+			LOG_ERROR("Hidd profile  BTA_GATTS_READ_EVT\n");
+			UINT32 trans_id = p_data->req_data.trans_id;
+            UINT16 conn_id = p_data->req_data.conn_id;
+            UINT16 handle = p_data->req_data.p_data->read_req.handle;
+            bool   is_long = p_data->req_data.p_data->read_req.is_long;
+            LOG_ERROR("read request:event=0x%x,handle=0x%x,trans_id=0x%x,conn_id=0x%x\n",
+                event, handle, trans_id, conn_id);
+        
+			hidd_read_attr_value(p_data->req_data.p_data,trans_id);
+		}
 			break;
 		case BTA_GATTS_WRITE_EVT:
 			BTA_GATTS_SendRsp(p_data->req_data.conn_id,p_data->req_data.trans_id,
-					p_data->req_data.status,NULL);
+								p_data->req_data.status,NULL);
 			break;
 		case BTA_GATTS_CONNECT_EVT: 
 			p_clcb = &hidd_le_env.hidd_clcb; 
-
+	
 			if(!p_clcb->in_use)
 			{
 				p_clcb->in_use = TRUE;
@@ -237,41 +441,195 @@ static void hidd_le_profile_cb(tBTA_GATTS_EVT event, tBTA_GATTS *p_data)
 }
 
 /*******************************************************************************
- **
- ** Function         hidd_le_CreateService
- **
- ** Description      Create a Service for the hid device profile
- **
- ** Parameters       is_primary: this service is the primary service or not,true is the primary service
- **								false is not the primary service
- **                  p_service_uuid: service UUID.
- **                
- ** Returns          NULL 
- **
- *******************************************************************************/
+**
+** Function         hidd_le_CreateService
+**
+** Description      Create a Service for the hid device profile
+**
+** Parameters       is_primary: this service is the primary service or not,true is the primary service
+**								false is not the primary service
+**                  p_service_uuid: service UUID.
+**                
+** Returns          NULL 
+**
+*******************************************************************************/
 void hidd_le_CreateService(BOOLEAN is_primary)
 {
 	tBTA_GATTS_IF server_if ;
 	tBT_UUID uuid = {LEN_UUID_16, {ATT_SVC_HID}};
 	//the number of the hid device attributes in the hid service.
-	UINT16 num_handle = HIDD_LE_IDX_NB;
-		UINT8 inst = 0x00;
+	UINT16 num_handle = HIDD_LE_IDX_NB+5;
+	UINT8 inst = 0x00;
 	server_if = hidd_le_env.gatt_if;
 	hidd_le_env.inst_id = inst;
 	//start create the hid device service
-	BTA_GATTS_CreateService(server_if,&uuid,inst,num_handle,is_primary);
+	BTA_GATTS_CreateService(server_if,&uuid,inst,num_handle,is_primary);
 }
 
 
+/*****************************************************************************
+** Function      hidd_read_attr_value
+**
+** Description   it will be called when client sends a read request
+******************************************************************************/
+void hidd_read_attr_value(tGATTS_DATA *p_data, UINT32 trans_id)
+{
+	tHIDD_INST     *p_inst = &hidd_le_env.hidd_inst;
+    UINT8        i;
+	UINT8		 status = GATT_SUCCESS;
+	UINT8 app_id = hidd_le_env.hidd_inst.app_id;
+	
+    tGATT_STATUS st = GATT_NOT_FOUND;
+    UINT16       handle = p_data->read_req.handle;
+	UINT16		 conn_id = hidd_le_env.hidd_clcb.conn_id;
+
+    if (handle == p_inst->att_tbl[HIDD_LE_INFO_CHAR])
+    {
+    	//read hid device info evt
+		 p_inst->pending_evt = HIDD_LE_READ_INFO_EVT;
+		
+	}else if(handle == p_inst->att_tbl[HIDD_LE_CTNL_PT_CHAR]){
+		//read hid device contol point evt
+		p_inst->pending_evt = HIDD_LE_READ_CTNL_PT_EVT;
+	}else if(handle == p_inst->att_tbl[HIDD_LE_REPORT_MAP_CHAR]){
+		//read hid device report map value evt
+		p_inst->pending_evt = HIDD_LE_READ_REPORT_MAP_EVT;
+	}else if(handle == p_inst->att_tbl[HIDD_LE_REPORT_CHAR]){
+		//read hid device report evt
+		p_inst->pending_evt = HIDD_LE_READ_REPORT_EVT;
+	}else if(handle == p_inst->att_tbl[HIDD_LE_PROTO_MODE_CHAR]){
+		//read hid device mode evt
+		p_inst->pending_evt = HIDD_LE_READ_PROTO_MODE_EVT;
+	}else if(handle == p_inst->att_tbl[HIDD_LE_BOOT_KB_IN_REPORT_CHAR]){
+		//read hid boot keyboard in report evt
+		p_inst->pending_evt = HIDD_LE_BOOT_KB_IN_REPORT_EVT;
+	}else if(handle == p_inst->att_tbl[HIDD_LE_BOOT_KB_OUT_REPORT_CHAR]){
+		//read hid boot keyboard out report evt
+		p_inst->pending_evt = HIDD_LE_BOOT_KB_OUT_REPORT_EVT;
+	}else if(handle == p_inst->att_tbl[HIDD_LE_BOOT_MOUSE_IN_REPORT_CHAR]){
+		//read hid device boot mouse in report evt
+		p_inst->pending_evt = HIDD_LE_BOOT_MOUSE_IN_REPORT_EVT;
+	}
 
+	//start build the rsp message
+	Hidd_Rsp(trans_id,conn_id,app_id,status, p_inst->pending_evt,p_data);
+}
 
 /*******************************************************************************
- **
- ** Function         hidd_le_init
- **
- ** Description      Initializa the GATT Service for button profiles.
- ** Returns          NULL 
- *******************************************************************************/
+**
+** Function         Hidd_Rsp
+**
+** Description      Respond to a hid device service request
+**
+*******************************************************************************/
+void Hidd_Rsp (UINT32 trans_id, UINT16 conn_id, UINT8 app_id,
+    tGATT_STATUS status, UINT8 event, tGATTS_DATA *p_rsp)
+{
+    tHIDD_INST *p_inst = &hidd_le_env.hidd_inst;
+    tGATTS_RSP  rsp;
+    UINT8   *pp;
+	LOG_ERROR("conn_id = %x, trans_id = %x, event = %x\n",
+		conn_id,trans_id,event);
+	
+    if (p_inst->app_id == app_id)
+       return ;
+       
+    memset(&rsp, 0, sizeof(tGATTS_RSP));
+
+    if (p_inst->pending_evt == event)
+    {
+        switch (event)
+        {
+        case HIDD_LE_READ_INFO_EVT:
+			LOG_ERROR(" p_inst->att_tbl[HIDD_LE_INFO_CHAR] = %x\n",
+				 p_inst->att_tbl[HIDD_LE_INFO_CHAR]);
+            rsp.attr_value.handle = p_inst->att_tbl[HIDD_LE_INFO_CHAR];
+            rsp.attr_value.len = HID_INFORMATION_LEN;
+			//copy the infomation value to the att value to sent to the peer device
+			memcpy(rsp.attr_value.value,hidInfo,HID_INFORMATION_LEN);
+          	//start send the rsp to the peer device
+            BTA_GATTS_SendRsp(conn_id, trans_id, status, &rsp);
+            break;
+
+        case HIDD_LE_READ_CTNL_PT_EVT:
+			LOG_ERROR(" p_inst->att_tbl[HIDD_LE_CTNL_PT_CHAR] = %x\n",
+				 p_inst->att_tbl[HIDD_LE_CTNL_PT_CHAR]);
+            rsp.attr_value.handle = p_inst->att_tbl[HIDD_LE_CTNL_PT_CHAR];
+            rsp.attr_value.len = 0;
+          	//start send the rsp to the peer device
+            BTA_GATTS_SendRsp(conn_id, trans_id, status, &rsp);
+            break;
+
+        case HIDD_LE_READ_REPORT_MAP_EVT:
+			LOG_ERROR("p_inst->att_tbl[HIDD_LE_REPORT_MAP_CHAR] = %x\n",
+				p_inst->att_tbl[HIDD_LE_REPORT_MAP_CHAR]);
+            rsp.attr_value.handle = p_inst->att_tbl[HIDD_LE_REPORT_MAP_CHAR];
+            rsp.attr_value.len = hidReportMapLen;
+            //copy the infomation value to the att value to sent to the peer device
+			memcpy(rsp.attr_value.value,hidReportMap,hidReportMapLen);
+          	//start send the rsp to the peer device
+            BTA_GATTS_SendRsp(conn_id, trans_id, status, &rsp);
+            break;
+		case HIDD_LE_READ_REPORT_EVT:
+			LOG_ERROR("p_inst->att_tbl[HIDD_LE_BOOT_KB_IN_REPORT_CHAR] = %x\n",
+				p_inst->att_tbl[HIDD_LE_BOOT_KB_IN_REPORT_CHAR]);
+			rsp.attr_value.handle = p_inst->att_tbl[HIDD_LE_BOOT_KB_IN_REPORT_CHAR];
+            rsp.attr_value.len = 0;
+            
+            BTA_GATTS_SendRsp(conn_id, trans_id, status, &rsp);
+			break;
+        case HIDD_LE_READ_PROTO_MODE_EVT:
+			LOG_ERROR("p_inst->att_tbl[HIDD_LE_PROTO_MODE_CHAR] = %x\n",
+				p_inst->att_tbl[HIDD_LE_PROTO_MODE_CHAR]);
+            rsp.attr_value.handle = p_inst->att_tbl[HIDD_LE_PROTO_MODE_CHAR];
+            rsp.attr_value.len = 1;
+            pp = rsp.attr_value.value;
+			//copy the infomation value to the att value to sent to the peer device
+			memcpy(rsp.attr_value.value,&hidProtocolMode,rsp.attr_value.len);
+            BTA_GATTS_SendRsp(conn_id, trans_id, status, &rsp);
+            break;
+		case HIDD_LE_BOOT_KB_IN_REPORT_EVT:
+			LOG_ERROR("p_inst->att_tbl[HIDD_LE_BOOT_KB_IN_REPORT_CHAR] = %x\n",
+				p_inst->att_tbl[HIDD_LE_BOOT_KB_IN_REPORT_CHAR]);
+			rsp.attr_value.handle = p_inst->att_tbl[HIDD_LE_BOOT_KB_IN_REPORT_CHAR];
+            rsp.attr_value.len = 0;
+            
+            BTA_GATTS_SendRsp(conn_id, trans_id, status, &rsp);
+			break;
+		case HIDD_LE_BOOT_KB_OUT_REPORT_EVT:
+			LOG_ERROR("p_inst->att_tbl[HIDD_LE_BOOT_KB_IN_REPORT_CHAR] = %x\n",
+				p_inst->att_tbl[HIDD_LE_BOOT_KB_IN_REPORT_CHAR]);
+			rsp.attr_value.handle = p_inst->att_tbl[HIDD_LE_BOOT_KB_IN_REPORT_CHAR];
+            rsp.attr_value.len = 0;
+			
+            BTA_GATTS_SendRsp(conn_id, trans_id, status, &rsp);
+			break;
+		case HIDD_LE_BOOT_MOUSE_IN_REPORT_EVT:
+			LOG_ERROR("p_inst->att_tbl[HIDD_LE_BOOT_KB_IN_REPORT_CHAR] = %x\n",
+				p_inst->att_tbl[HIDD_LE_BOOT_KB_IN_REPORT_CHAR]);
+			rsp.attr_value.handle = p_inst->att_tbl[HIDD_LE_BOOT_KB_IN_REPORT_CHAR];
+            rsp.attr_value.len = 0;
+			
+            BTA_GATTS_SendRsp(conn_id, trans_id, status, &rsp);
+			break;
+        default:
+            break;
+        }
+       // p_inst->pending_clcb_idx = 0;
+        p_inst->pending_evt = 0;
+        p_inst->pending_hal = 0;
+    }
+    return;
+}
+
+
+/*******************************************************************************
+**
+** Function         hidd_le_init
+**
+** Description      Initializa the GATT Service for button profiles.
+** Returns          NULL 
+*******************************************************************************/
 tGATT_STATUS hidd_le_init (void)
 {
 	tBT_UUID app_uuid = {LEN_UUID_16,{ATT_SVC_HID}};
@@ -285,10 +643,11 @@ tGATT_STATUS hidd_le_init (void)
 	{
 		memset(&hidd_le_env,0,sizeof(tHIDD_LE_ENV));
 	}
-
-
-	/* register the hid deivce profile to the BTA_GATTS module*/
-		BTA_GATTS_AppRegister(&app_uuid,hidd_le_profile_cb);
+	
+	
+	/*
+ register the hid deivce profile to the BTA_GATTS module*/
+	 BTA_GATTS_AppRegister(&app_uuid,hidd_le_profile_cb);
 
 	hidd_le_env.enabled = TRUE;
 
@@ -296,5 +655,6 @@ tGATT_STATUS hidd_le_init (void)
 }
 
 
+#endif	///HIDD_LE_PROFILE_CFG
 
 

+ 65 - 8
components/bt/bluedroid/profiles/std/include/hid_le_prf.h

@@ -12,9 +12,11 @@
  ****************************************************************************************
  */
 
+#include "prf_defs.h"
 
+#if (HIDD_LE_PROFILE_CFG)
 #include "bta_gatts_int.h"
-
+#include "bt_types.h"
 #include "bta_api.h"
 #include "gatt_api.h"
 
@@ -25,6 +27,10 @@
 #define HIDD_LE_NB_HIDS_INST_MAX              (1)
 #endif
 
+// Number of HID reports defined in the service
+#define HID_NUM_REPORTS          9
+
+
 #define ATT_SVC_HID 	0x1812
 
 /// Maximal number of Report Char. that can be added in the DB for one HIDS - Up to 11
@@ -46,7 +52,26 @@
 #define HIDD_LE_REPORT_NTF_CFG_MASK           (0x20)
 
 
+/* HID information flags */
+#define HID_FLAGS_REMOTE_WAKE           0x01      // RemoteWake
+#define HID_FLAGS_NORMALLY_CONNECTABLE  0x02      // NormallyConnectable
+
+/* Control point commands */
+#define HID_CMD_SUSPEND                 0x00      // Suspend
+#define HID_CMD_EXIT_SUSPEND            0x01      // Exit Suspend
+
+/* HID protocol mode values */
+#define HID_PROTOCOL_MODE_BOOT          0x00      // Boot Protocol Mode
+#define HID_PROTOCOL_MODE_REPORT        0x01      // Report Protocol Mode
 
+/* Attribute value lengths */
+#define HID_PROTOCOL_MODE_LEN           1         // HID Protocol Mode
+#define HID_INFORMATION_LEN             4         // HID Information
+#define HID_REPORT_REF_LEN              2         // HID Report Reference Descriptor
+#define HID_EXT_REPORT_REF_LEN          2         // External Report Reference Descriptor
+
+// HID feature flags
+#define HID_KBD_FLAGS             HID_FLAGS_REMOTE_WAKE
 
 
 /// HID Service Attributes Indexes
@@ -104,15 +129,29 @@ enum
     HIDD_LE_INFO_CHAR,
     HIDD_LE_CTNL_PT_CHAR,
     HIDD_LE_REPORT_MAP_CHAR,
+    HIDD_LE_REPORT_CHAR,
     HIDD_LE_PROTO_MODE_CHAR,
     HIDD_LE_BOOT_KB_IN_REPORT_CHAR,
     HIDD_LE_BOOT_KB_OUT_REPORT_CHAR,
     HIDD_LE_BOOT_MOUSE_IN_REPORT_CHAR,
-    HIDD_LE_REPORT_CHAR,
-
     HIDD_LE_CHAR_MAX //= HIDD_LE_REPORT_CHAR + HIDD_LE_NB_REPORT_INST_MAX,
 };
 
+///att read event table Indexs
+enum
+{
+	HIDD_LE_READ_INFO_EVT,
+	HIDD_LE_READ_CTNL_PT_EVT,
+	HIDD_LE_READ_REPORT_MAP_EVT,
+	HIDD_LE_READ_REPORT_EVT,
+	HIDD_LE_READ_PROTO_MODE_EVT,
+	HIDD_LE_BOOT_KB_IN_REPORT_EVT,
+	HIDD_LE_BOOT_KB_OUT_REPORT_EVT,
+	HIDD_LE_BOOT_MOUSE_IN_REPORT_EVT,
+
+	HID_LE_EVT_MAX
+};
+
 /// Client Characteristic Configuration Codes
 enum
 {
@@ -176,22 +215,33 @@ enum
  
  }tHIDD_CLCB;
 
+ // HID report mapping table
+typedef struct
+{
+  UINT16    handle;           // Handle of report characteristic
+  UINT16    cccdHandle;       // Handle of CCCD for report characteristic
+  UINT8     id;               // Report ID
+  UINT8     type;             // Report type
+  UINT8     mode;             // Protocol mode (report or boot)
+} hidRptMap_t;
+
 
  typedef struct
  {
  	/// hidd profile id
-	UINT8			 app_id;
+	UINT8 app_id;
 	 /// Notified handle
-    uint16_t ntf_handle;
-	///Attribute Table
-    uint8_t att_tbl[HIDD_LE_NB_HIDS_INST_MAX][HIDD_LE_CHAR_MAX];
+    UINT16 ntf_handle;
+	///Attribute handle Table
+    UINT16 att_tbl[HIDD_LE_CHAR_MAX];
 	/// Supported Features
 	tHIDD_FEATURE	 hidd_feature[HIDD_LE_NB_HIDS_INST_MAX];
 	/// Current Protocol Mode
     UINT8 proto_mode[HIDD_LE_NB_HIDS_INST_MAX];
     /// Number of HIDS added in the database
     UINT8 hids_nb;
- 
+ 	UINT8 pending_evt;
+	UINT16 pending_hal;
  }tHIDD_INST;
 
 
@@ -211,8 +261,15 @@ enum
 
  void hidd_le_CreateService(BOOLEAN is_primary);
 
+ void Hidd_Rsp (UINT32 trans_id, UINT16 conn_id, UINT8 app_id,
+    tGATT_STATUS status, UINT8 event, tGATTS_DATA *p_rsp);
+
+ void hidd_read_attr_value(tGATTS_DATA *p_data, UINT32 trans_id);
+
  
  tGATT_STATUS hidd_le_init (void);
 
+
+#endif	///HIDD_LE_PROFILE_CFG
  
 

+ 6 - 1
components/bt/bluedroid/profiles/std/include/prf_defs.h

@@ -11,6 +11,8 @@
  *
  ****************************************************************************************
  */
+#ifndef PRF_DEFS_H_
+#define PRF_DEFS_H_
 
 #include "bta_api.h"
 #include "bta_gattc_int.h"
@@ -24,6 +26,9 @@
 #define ATT_UUID_128_LEN                        0x0010
 #define ATT_UUID_32_LEN                         0x0004
 
+#define WX_AIRSYNC_CFG			0
+#define BUT_PROFILE_CFG			0
+#define HIDD_LE_PROFILE_CFG		1
 
 /*
  * Type Definition
@@ -626,5 +631,5 @@ enum {
 };
 
 
-
+#endif	///PRF_DEFS_H_
 

+ 1 - 1
components/bt/bluedroid/stack/btm/btm_acl.c

@@ -105,7 +105,7 @@ tACL_CONN *btm_bda_to_acl (BD_ADDR bda, tBT_TRANSPORT transport)
 #endif
                 )
             {
-                BTM_TRACE_DEBUG ("btm_bda_to_acl found");
+                BTM_TRACE_DEBUG ("btm_bda_to_acl found\n");
                 return(p);
             }
         }

+ 2 - 2
components/bt/bluedroid/stack/btm/btm_ble_cont_energy.c

@@ -88,11 +88,11 @@ tBTM_STATUS BTM_BleGetEnergyInfo(tBTM_BLE_ENERGY_INFO_CBACK *p_ener_cback)
 
     BTM_BleGetVendorCapabilities(&cmn_ble_vsc_cb);
 
-    BTM_TRACE_EVENT("BTM_BleGetEnergyInfo");
+    BTM_TRACE_EVENT("BTM_BleGetEnergyInfo\n");
 
     if (0 == cmn_ble_vsc_cb.energy_support)
     {
-        BTM_TRACE_ERROR("Controller does not support get energy info");
+        BTM_TRACE_ERROR("Controller does not support get energy info\n");
         return BTM_ERR_PROCESSING;
     }
 

+ 4 - 4
components/bt/bluedroid/stack/btu/btu_init.c

@@ -56,19 +56,19 @@ extern fixed_queue_t *btu_hci_msg_queue;
 fixed_queue_t *btu_general_alarm_queue;
 hash_map_t *btu_general_alarm_hash_map;
 pthread_mutex_t btu_general_alarm_lock;
-static const size_t BTU_GENERAL_ALARM_HASH_MAP_SIZE = 17;
+static const size_t BTU_GENERAL_ALARM_HASH_MAP_SIZE = 34;
 
 // Oneshot timer queue.
 fixed_queue_t *btu_oneshot_alarm_queue;
 hash_map_t *btu_oneshot_alarm_hash_map;
 pthread_mutex_t btu_oneshot_alarm_lock;
-static const size_t BTU_ONESHOT_ALARM_HASH_MAP_SIZE = 17;
+static const size_t BTU_ONESHOT_ALARM_HASH_MAP_SIZE = 34;
 
 // l2cap timer queue.
 fixed_queue_t *btu_l2cap_alarm_queue;
 hash_map_t *btu_l2cap_alarm_hash_map;
 pthread_mutex_t btu_l2cap_alarm_lock;
-static const size_t BTU_L2CAP_ALARM_HASH_MAP_SIZE = 17;
+static const size_t BTU_L2CAP_ALARM_HASH_MAP_SIZE = 34;
 
 //thread_t *bt_workqueue_thread;
 //static const char *BT_WORKQUEUE_NAME = "bt_workqueue";
@@ -193,7 +193,7 @@ void BTU_StartUp(void)
     if (btu_l2cap_alarm_queue == NULL)
          goto error_exit;
 
-    xBtuQueue = xQueueCreate(30, sizeof(void *));
+    xBtuQueue = xQueueCreate(60, sizeof(void *));
     xTaskCreate(btu_task_thread_handler, "BtuT", 8192, NULL, configMAX_PRIORITIES - 1, &xBtuTaskHandle);
     btu_task_post(SIG_BTU_START_UP);
 /*

+ 1 - 1
components/bt/bluedroid/stack/l2cap/l2c_main.c

@@ -192,7 +192,7 @@ void l2c_rcv_acl_data (BT_HDR *p_msg)
       /* only process fixed channel data as channel open indication when link is not in disconnecting mode */
         l2cble_notify_le_connection(p_lcb->remote_bd_addr);
 #endif
-
+	 L2CAP_TRACE_WARNING ("L2CAP - rcv_cid CID: 0x%04x\n", rcv_cid);
     /* Find the CCB for this CID */
     if (rcv_cid >= L2CAP_BASE_APPL_CID)
     {

+ 88 - 87
components/bt/bluedroid/stack/smp/smp_act.c

@@ -69,7 +69,7 @@ static bool lmp_version_below(BD_ADDR bda, uint8_t version)
 *******************************************************************************/
 static void smp_update_key_mask (tSMP_CB *p_cb, UINT8 key_type, BOOLEAN recv)
 {
-    SMP_TRACE_DEBUG("%s before update role=%d recv=%d local_i_key = %02x, local_r_key = %02x",
+    SMP_TRACE_DEBUG("%s before update role=%d recv=%d local_i_key = %02x, local_r_key = %02x\n",
         __func__, p_cb->role, recv, p_cb->local_i_key, p_cb->local_r_key);
 
     if (((p_cb->le_secure_connections_mode_is_used) ||
@@ -97,7 +97,7 @@ static void smp_update_key_mask (tSMP_CB *p_cb, UINT8 key_type, BOOLEAN recv)
             p_cb->local_i_key &= ~key_type;
     }
 
-    SMP_TRACE_DEBUG("updated local_i_key = %02x, local_r_key = %02x", p_cb->local_i_key,
+    SMP_TRACE_DEBUG("updated local_i_key = %02x, local_r_key = %02x\n", p_cb->local_i_key,
                       p_cb->local_r_key);
 }
 
@@ -109,7 +109,7 @@ void smp_send_app_cback(tSMP_CB *p_cb, tSMP_INT_DATA *p_data)
 {
     tSMP_EVT_DATA   cb_data;
     tSMP_STATUS callback_rc;
-    SMP_TRACE_DEBUG("%s p_cb->cb_evt=%d", __func__, p_cb->cb_evt);
+    SMP_TRACE_DEBUG("%s p_cb->cb_evt=%d\n", __func__, p_cb->cb_evt);
     if (p_cb->p_callback && p_cb->cb_evt != 0)
     {
         switch (p_cb->cb_evt)
@@ -149,7 +149,7 @@ void smp_send_app_cback(tSMP_CB *p_cb, tSMP_INT_DATA *p_data)
 
         callback_rc = (*p_cb->p_callback)(p_cb->cb_evt, p_cb->pairing_bda, &cb_data);
 
-        SMP_TRACE_DEBUG("callback_rc=%d  p_cb->cb_evt=%d",callback_rc, p_cb->cb_evt );
+        SMP_TRACE_DEBUG("callback_rc=%d  p_cb->cb_evt=%d\n",callback_rc, p_cb->cb_evt );
 
         if (callback_rc == SMP_SUCCESS)
         {
@@ -172,7 +172,7 @@ void smp_send_app_cback(tSMP_CB *p_cb, tSMP_INT_DATA *p_data)
 
                     SMP_TRACE_WARNING ( "rcvd auth_req: 0x%02x, io_cap: %d \
                         loc_oob_flag: %d loc_enc_size: %d,"
-                        "local_i_key: 0x%02x, local_r_key: 0x%02x",
+                        "local_i_key: 0x%02x, local_r_key: 0x%02x\n",
                         p_cb->loc_auth_req, p_cb->local_io_capability, p_cb->loc_oob_flag,
                         p_cb->loc_enc_size, p_cb->local_i_key, p_cb->local_r_key);
 
@@ -194,7 +194,7 @@ void smp_send_app_cback(tSMP_CB *p_cb, tSMP_INT_DATA *p_data)
                         p_cb->local_r_key &= ~SMP_SEC_KEY_TYPE_LK;
                     }
 
-                    SMP_TRACE_WARNING("set auth_req: 0x%02x, local_i_key: 0x%02x, local_r_key: 0x%02x",
+                    SMP_TRACE_WARNING("set auth_req: 0x%02x, local_i_key: 0x%02x, local_r_key: 0x%02x\n",
                         p_cb->loc_auth_req, p_cb->local_i_key, p_cb->local_r_key);
 
                     smp_sm_event(p_cb, SMP_IO_RSP_EVT, NULL);
@@ -209,7 +209,7 @@ void smp_send_app_cback(tSMP_CB *p_cb, tSMP_INT_DATA *p_data)
                     p_cb->local_r_key &= ~SMP_SEC_KEY_TYPE_LK;
 
                     SMP_TRACE_WARNING ( "for SMP over BR max_key_size: 0x%02x,\
-                        local_i_key: 0x%02x, local_r_key: 0x%02x",
+                        local_i_key: 0x%02x, local_r_key: 0x%02x\n",
                         p_cb->loc_enc_size, p_cb->local_i_key, p_cb->local_r_key);
 
                     smp_br_state_machine_event(p_cb, SMP_BR_KEYS_RSP_EVT, NULL);
@@ -224,7 +224,7 @@ void smp_send_app_cback(tSMP_CB *p_cb, tSMP_INT_DATA *p_data)
         smp_sm_event(p_cb, SMP_DISCARD_SEC_REQ_EVT, NULL);
     }
 
-    SMP_TRACE_DEBUG("%s return", __func__);
+    SMP_TRACE_DEBUG("%s return\n", __func__);
 }
 
 /*******************************************************************************
@@ -252,7 +252,7 @@ void smp_send_pair_fail(tSMP_CB *p_cb, tSMP_INT_DATA *p_data)
 void smp_send_pair_req(tSMP_CB *p_cb, tSMP_INT_DATA *p_data)
 {
     tBTM_SEC_DEV_REC *p_dev_rec = btm_find_dev (p_cb->pairing_bda);
-    SMP_TRACE_DEBUG("%s", __func__);
+    SMP_TRACE_DEBUG("%s\n", __func__);
 
     /* erase all keys when master sends pairing req*/
     if (p_dev_rec)
@@ -268,7 +268,7 @@ void smp_send_pair_req(tSMP_CB *p_cb, tSMP_INT_DATA *p_data)
 *******************************************************************************/
 void smp_send_pair_rsp(tSMP_CB *p_cb, tSMP_INT_DATA *p_data)
 {
-    SMP_TRACE_DEBUG("%s", __func__);
+    SMP_TRACE_DEBUG("%s\n", __func__);
 
     p_cb->local_i_key &= p_cb->peer_i_key;
     p_cb->local_r_key &= p_cb->peer_r_key;
@@ -288,7 +288,7 @@ void smp_send_pair_rsp(tSMP_CB *p_cb, tSMP_INT_DATA *p_data)
 *******************************************************************************/
 void smp_send_confirm(tSMP_CB *p_cb, tSMP_INT_DATA *p_data)
 {
-    SMP_TRACE_DEBUG("%s", __func__);
+    SMP_TRACE_DEBUG("%s\n", __func__);
     smp_send_cmd(SMP_OPCODE_CONFIRM, p_cb);
 }
 
@@ -298,7 +298,7 @@ void smp_send_confirm(tSMP_CB *p_cb, tSMP_INT_DATA *p_data)
 *******************************************************************************/
 void smp_send_init(tSMP_CB *p_cb, tSMP_INT_DATA *p_data)
 {
-    SMP_TRACE_DEBUG("%s", __func__);
+    SMP_TRACE_DEBUG("%s\n", __func__);
     smp_send_cmd(SMP_OPCODE_INIT, p_cb);
 }
 
@@ -308,7 +308,7 @@ void smp_send_init(tSMP_CB *p_cb, tSMP_INT_DATA *p_data)
 *******************************************************************************/
 void smp_send_rand(tSMP_CB *p_cb, tSMP_INT_DATA *p_data)
 {
-    SMP_TRACE_DEBUG("%s", __func__);
+    SMP_TRACE_DEBUG("%s\n", __func__);
     smp_send_cmd(SMP_OPCODE_RAND, p_cb);
 }
 
@@ -318,7 +318,7 @@ void smp_send_rand(tSMP_CB *p_cb, tSMP_INT_DATA *p_data)
 *******************************************************************************/
 void smp_send_pair_public_key(tSMP_CB *p_cb, tSMP_INT_DATA *p_data)
 {
-    SMP_TRACE_DEBUG("%s", __func__);
+    SMP_TRACE_DEBUG("%s\n", __func__);
     smp_send_cmd(SMP_OPCODE_PAIR_PUBLIC_KEY, p_cb);
 }
 
@@ -360,7 +360,7 @@ void smp_send_enc_info(tSMP_CB *p_cb, tSMP_INT_DATA *p_data)
 {
     tBTM_LE_LENC_KEYS   le_key;
 
-    SMP_TRACE_DEBUG("%s p_cb->loc_enc_size = %d", __func__, p_cb->loc_enc_size);
+    SMP_TRACE_DEBUG("%s p_cb->loc_enc_size = %d\n", __func__, p_cb->loc_enc_size);
     smp_update_key_mask (p_cb, SMP_SEC_KEY_TYPE_ENC, FALSE);
 
     smp_send_cmd(SMP_OPCODE_ENCRYPT_INFO, p_cb);
@@ -376,7 +376,7 @@ void smp_send_enc_info(tSMP_CB *p_cb, tSMP_INT_DATA *p_data)
         btm_sec_save_le_key(p_cb->pairing_bda, BTM_LE_KEY_LENC,
                             (tBTM_LE_KEY_VALUE *)&le_key, TRUE);
 
-    SMP_TRACE_WARNING ("%s", __func__);
+    SMP_TRACE_WARNING ("%s\n", __func__);
 
     smp_key_distribution(p_cb, NULL);
 }
@@ -388,7 +388,7 @@ void smp_send_enc_info(tSMP_CB *p_cb, tSMP_INT_DATA *p_data)
 void smp_send_id_info(tSMP_CB *p_cb, tSMP_INT_DATA *p_data)
 {
     tBTM_LE_KEY_VALUE   le_key;
-    SMP_TRACE_DEBUG("%s", __func__);
+    SMP_TRACE_DEBUG("%s\n", __func__);
     smp_update_key_mask (p_cb, SMP_SEC_KEY_TYPE_ID, FALSE);
 
     smp_send_cmd(SMP_OPCODE_IDENTITY_INFO, p_cb);
@@ -398,7 +398,7 @@ void smp_send_id_info(tSMP_CB *p_cb, tSMP_INT_DATA *p_data)
         btm_sec_save_le_key(p_cb->pairing_bda, BTM_LE_KEY_LID,
                             &le_key, TRUE);
 
-    SMP_TRACE_WARNING ("%s", __func__);
+    SMP_TRACE_WARNING ("%s\n", __func__);
     smp_key_distribution_by_transport(p_cb, NULL);
 }
 
@@ -409,7 +409,7 @@ void smp_send_id_info(tSMP_CB *p_cb, tSMP_INT_DATA *p_data)
 void smp_send_csrk_info(tSMP_CB *p_cb, tSMP_INT_DATA *p_data)
 {
     tBTM_LE_LCSRK_KEYS  key;
-    SMP_TRACE_DEBUG("%s", __func__);
+    SMP_TRACE_DEBUG("%s\n", __func__);
     smp_update_key_mask (p_cb, SMP_SEC_KEY_TYPE_CSRK, FALSE);
 
     if (smp_send_cmd(SMP_OPCODE_SIGN_INFO, p_cb))
@@ -529,7 +529,7 @@ void smp_proc_pair_cmd(tSMP_CB *p_cb, tSMP_INT_DATA *p_data)
     UINT8   reason = SMP_ENC_KEY_SIZE;
     tBTM_SEC_DEV_REC *p_dev_rec = btm_find_dev (p_cb->pairing_bda);
 
-    SMP_TRACE_DEBUG("%s", __func__);
+    SMP_TRACE_DEBUG("%s\n", __func__);
     /* erase all keys if it is slave proc pairing req*/
     if (p_dev_rec && (p_cb->role == HCI_ROLE_SLAVE))
         btm_sec_clear_ble_keys(p_dev_rec);
@@ -623,7 +623,7 @@ void smp_proc_confirm(tSMP_CB *p_cb, tSMP_INT_DATA *p_data)
     UINT8 *p = (UINT8 *)p_data;
     UINT8 reason = SMP_INVALID_PARAMETERS;
 
-    SMP_TRACE_DEBUG("%s", __func__);
+    SMP_TRACE_DEBUG("%s\n", __func__);
 
     if (smp_command_has_invalid_parameters(p_cb))
     {
@@ -670,7 +670,7 @@ void smp_proc_rand(tSMP_CB *p_cb, tSMP_INT_DATA *p_data)
     UINT8 *p = (UINT8 *)p_data;
     UINT8 reason = SMP_INVALID_PARAMETERS;
 
-    SMP_TRACE_DEBUG("%s", __func__);
+    SMP_TRACE_DEBUG("%s\n", __func__);
 
     if (smp_command_has_invalid_parameters(p_cb))
     {
@@ -953,7 +953,7 @@ void smp_proc_enc_info(tSMP_CB *p_cb, tSMP_INT_DATA *p_data)
 {
     UINT8   *p = (UINT8 *)p_data;
 
-    SMP_TRACE_DEBUG("%s", __func__);
+    SMP_TRACE_DEBUG("%s\n", __func__);
     STREAM_TO_ARRAY(p_cb->ltk, p, BT_OCTET16_LEN);
 
     smp_key_distribution(p_cb, NULL);
@@ -967,7 +967,8 @@ void smp_proc_master_id(tSMP_CB *p_cb, tSMP_INT_DATA *p_data)
     UINT8   *p = (UINT8 *)p_data;
     tBTM_LE_PENC_KEYS   le_key;
 
-    SMP_TRACE_DEBUG("%s", __func__);
+    SMP_TRACE_DEBUG("%s\np_cb->peer_auth_req = %d,p_cb->loc_auth_req= %d\n", __func__,
+					p_cb->peer_auth_req,p_cb->loc_auth_req);
     smp_update_key_mask (p_cb, SMP_SEC_KEY_TYPE_ENC, TRUE);
 
     STREAM_TO_UINT16(le_key.ediv, p);
@@ -1058,7 +1059,7 @@ void smp_proc_compare(tSMP_CB *p_cb, tSMP_INT_DATA *p_data)
 {
     UINT8   reason;
 
-    SMP_TRACE_DEBUG("%s", __func__);
+    SMP_TRACE_DEBUG("%s\n", __func__);
     if (!memcmp(p_cb->rconfirm, p_data->key.p_data, BT_OCTET16_LEN))
     {
         /* compare the max encryption key size, and save the smaller one for the link */
@@ -1092,7 +1093,7 @@ void smp_proc_sl_key(tSMP_CB *p_cb, tSMP_INT_DATA *p_data)
 {
     UINT8 key_type = p_data->key.key_type;
 
-    SMP_TRACE_DEBUG("%s", __func__);
+    SMP_TRACE_DEBUG("%s\n", __func__);
     if (key_type == SMP_KEY_TYPE_TK)
     {
         smp_generate_srand_mrand_confirm(p_cb, NULL);
@@ -1115,7 +1116,7 @@ void smp_start_enc(tSMP_CB *p_cb, tSMP_INT_DATA *p_data)
     tBTM_STATUS cmd;
     UINT8 reason = SMP_ENC_FAIL;
 
-    SMP_TRACE_DEBUG("%s", __func__);
+    SMP_TRACE_DEBUG("%s\n", __func__);
     if (p_data != NULL)
         cmd = btm_ble_start_encrypt(p_cb->pairing_bda, TRUE, p_data->key.p_data);
     else
@@ -1131,7 +1132,7 @@ void smp_start_enc(tSMP_CB *p_cb, tSMP_INT_DATA *p_data)
 *******************************************************************************/
 void smp_proc_discard(tSMP_CB *p_cb, tSMP_INT_DATA *p_data)
 {
-    SMP_TRACE_DEBUG("%s", __func__);
+    SMP_TRACE_DEBUG("%s\n", __func__);
     if (!(p_cb->flags & SMP_PAIR_FLAGS_WE_STARTED_DD))
         smp_reset_control_value(p_cb);
 }
@@ -1145,7 +1146,7 @@ void smp_enc_cmpl(tSMP_CB *p_cb, tSMP_INT_DATA *p_data)
     UINT8 enc_enable = *(UINT8 *)p_data;
     UINT8 reason = enc_enable ? SMP_SUCCESS : SMP_ENC_FAIL;
 
-    SMP_TRACE_DEBUG("%s", __func__);
+    SMP_TRACE_DEBUG("%s\n", __func__);
     smp_sm_event(p_cb, SMP_AUTH_CMPL_EVT, &reason);
 }
 
@@ -1159,7 +1160,7 @@ void smp_check_auth_req(tSMP_CB *p_cb, tSMP_INT_DATA *p_data)
     UINT8 reason = enc_enable ? SMP_SUCCESS : SMP_ENC_FAIL;
 
     SMP_TRACE_DEBUG("%s rcvs enc_enable=%d i_keys=0x%x r_keys=0x%x "
-                      "(i-initiator r-responder)",
+                      "(i-initiator r-responder)\n",
                       __func__, enc_enable, p_cb->local_i_key, p_cb->local_r_key);
     if (enc_enable == 1)
     {
@@ -1192,7 +1193,7 @@ void smp_check_auth_req(tSMP_CB *p_cb, tSMP_INT_DATA *p_data)
             p_cb->local_r_key &= ~SMP_SEC_KEY_TYPE_LK;
         }
         SMP_TRACE_DEBUG("%s rcvs upgrades: i_keys=0x%x r_keys=0x%x "
-                          "(i-initiator r-responder)",
+                          "(i-initiator r-responder)\n",
                           __func__, p_cb->local_i_key, p_cb->local_r_key);
 
         if (/*((p_cb->peer_auth_req & SMP_AUTH_BOND) ||
@@ -1227,14 +1228,14 @@ void smp_key_pick_key(tSMP_CB *p_cb, tSMP_INT_DATA *p_data)
     UINT8   key_to_dist = (p_cb->role == HCI_ROLE_SLAVE) ? p_cb->local_r_key : p_cb->local_i_key;
     UINT8   i = 0;
 
-    SMP_TRACE_DEBUG("%s key_to_dist=0x%x", __func__, key_to_dist);
+    SMP_TRACE_DEBUG("%s key_to_dist=0x%x\n", __func__, key_to_dist);
     while (i < SMP_KEY_DIST_TYPE_MAX)
     {
-        SMP_TRACE_DEBUG("key to send = %02x, i = %d",  key_to_dist, i);
+        SMP_TRACE_DEBUG("key to send = %02x, i = %d\n",  key_to_dist, i);
 
         if (key_to_dist & (1 << i))
         {
-            SMP_TRACE_DEBUG("smp_distribute_act[%d]", i);
+            SMP_TRACE_DEBUG("smp_distribute_act[%d]\n", i);
             (* smp_distribute_act[i])(p_cb, p_data);
             break;
         }
@@ -1248,7 +1249,7 @@ void smp_key_pick_key(tSMP_CB *p_cb, tSMP_INT_DATA *p_data)
 void smp_key_distribution(tSMP_CB *p_cb, tSMP_INT_DATA *p_data)
 {
     UINT8   reason = SMP_SUCCESS;
-    SMP_TRACE_DEBUG("%s role=%d (0-master) r_keys=0x%x i_keys=0x%x",
+    SMP_TRACE_DEBUG("\n%s role=%d (0-master) r_keys=0x%x i_keys=0x%x\n",
                       __func__, p_cb->role, p_cb->local_r_key, p_cb->local_i_key);
 
     if (p_cb->role == HCI_ROLE_SLAVE ||
@@ -1289,7 +1290,7 @@ void smp_decide_association_model(tSMP_CB *p_cb, tSMP_INT_DATA *p_data)
     tSMP_KEY key;
     tSMP_INT_DATA   *p = NULL;
 
-    SMP_TRACE_DEBUG("%s Association Model = %d", __func__, p_cb->selected_association_model);
+    SMP_TRACE_DEBUG("%s Association Model = %d\n", __func__, p_cb->selected_association_model);
 
     switch (p_cb->selected_association_model)
     {
@@ -1298,7 +1299,7 @@ void smp_decide_association_model(tSMP_CB *p_cb, tSMP_INT_DATA *p_data)
                 ((p_cb->peer_auth_req & SMP_AUTH_YN_BIT) != 0) &&
                 ((p_cb->loc_auth_req & SMP_AUTH_YN_BIT) == 0))
             {
-                SMP_TRACE_ERROR ("IO capability does not meet authentication requirement");
+                SMP_TRACE_ERROR ("IO capability does not meet authentication requirement\n");
                 failure = SMP_PAIR_AUTH_FAIL;
                 p = (tSMP_INT_DATA *)&failure;
                 int_evt = SMP_AUTH_CMPL_EVT;
@@ -1306,7 +1307,7 @@ void smp_decide_association_model(tSMP_CB *p_cb, tSMP_INT_DATA *p_data)
             else
             {
                 p_cb->sec_level = SMP_SEC_UNAUTHENTICATE;
-                SMP_TRACE_EVENT ("p_cb->sec_level =%d (SMP_SEC_UNAUTHENTICATE) ", p_cb->sec_level );
+                SMP_TRACE_EVENT ("p_cb->sec_level =%d (SMP_SEC_UNAUTHENTICATE) \n", p_cb->sec_level );
 
                 key.key_type = SMP_KEY_TYPE_TK;
                 key.p_data = p_cb->tk;
@@ -1320,16 +1321,16 @@ void smp_decide_association_model(tSMP_CB *p_cb, tSMP_INT_DATA *p_data)
 
         case SMP_MODEL_PASSKEY:
             p_cb->sec_level = SMP_SEC_AUTHENTICATED;
-            SMP_TRACE_EVENT ("p_cb->sec_level =%d (SMP_SEC_AUTHENTICATED) ", p_cb->sec_level );
+            SMP_TRACE_EVENT ("p_cb->sec_level =%d (SMP_SEC_AUTHENTICATED) \n", p_cb->sec_level );
 
             p_cb->cb_evt = SMP_PASSKEY_REQ_EVT;
             int_evt = SMP_TK_REQ_EVT;
             break;
 
         case SMP_MODEL_OOB:
-            SMP_TRACE_ERROR ("Association Model = SMP_MODEL_OOB");
+            SMP_TRACE_ERROR ("Association Model = SMP_MODEL_OOB\n");
             p_cb->sec_level = SMP_SEC_AUTHENTICATED;
-            SMP_TRACE_EVENT ("p_cb->sec_level =%d (SMP_SEC_AUTHENTICATED) ", p_cb->sec_level );
+            SMP_TRACE_EVENT ("p_cb->sec_level =%d (SMP_SEC_AUTHENTICATED) \n", p_cb->sec_level );
 
             p_cb->cb_evt = SMP_OOB_REQ_EVT;
             int_evt = SMP_TK_REQ_EVT;
@@ -1337,7 +1338,7 @@ void smp_decide_association_model(tSMP_CB *p_cb, tSMP_INT_DATA *p_data)
 
         case SMP_MODEL_KEY_NOTIF:
             p_cb->sec_level = SMP_SEC_AUTHENTICATED;
-            SMP_TRACE_DEBUG("Need to generate Passkey");
+            SMP_TRACE_DEBUG("Need to generate Passkey\n");
 
             /* generate passkey and notify application */
             smp_generate_passkey(p_cb, NULL);
@@ -1352,19 +1353,19 @@ void smp_decide_association_model(tSMP_CB *p_cb, tSMP_INT_DATA *p_data)
             break;
 
         case SMP_MODEL_OUT_OF_RANGE:
-            SMP_TRACE_ERROR("Association Model = SMP_MODEL_OUT_OF_RANGE (failed)");
+            SMP_TRACE_ERROR("Association Model = SMP_MODEL_OUT_OF_RANGE (failed)\n");
             p = (tSMP_INT_DATA *)&failure;
             int_evt = SMP_AUTH_CMPL_EVT;
             break;
 
         default:
-            SMP_TRACE_ERROR("Association Model = %d (SOMETHING IS WRONG WITH THE CODE)",
+            SMP_TRACE_ERROR("Association Model = %d (SOMETHING IS WRONG WITH THE CODE)\n",
                              p_cb->selected_association_model);
             p = (tSMP_INT_DATA *)&failure;
             int_evt = SMP_AUTH_CMPL_EVT;
     }
 
-    SMP_TRACE_EVENT ("sec_level=%d ", p_cb->sec_level );
+    SMP_TRACE_EVENT ("sec_level=%d \n", p_cb->sec_level );
     if (int_evt)
         smp_sm_event(p_cb, int_evt, p);
 }
@@ -1377,7 +1378,7 @@ void smp_process_io_response(tSMP_CB *p_cb, tSMP_INT_DATA *p_data)
 {
     uint8_t reason = SMP_PAIR_AUTH_FAIL;
 
-    SMP_TRACE_DEBUG("%s", __func__);
+    SMP_TRACE_DEBUG("%s\n", __func__);
     if (p_cb->flags & SMP_PAIR_FLAGS_WE_STARTED_DD)
     {
         /* pairing started by local (slave) Security Request */
@@ -1394,7 +1395,7 @@ void smp_process_io_response(tSMP_CB *p_cb, tSMP_INT_DATA *p_data)
             (p_cb->selected_association_model == SMP_MODEL_SEC_CONN_JUSTWORKS)))
         {
             SMP_TRACE_ERROR ("Slave requires secure connection only mode \
-                              but it can't be provided -> Slave fails pairing");
+                              but it can't be provided -> Slave fails pairing\n");
             smp_sm_event(p_cb, SMP_AUTH_CMPL_EVT, &reason);
             return;
         }
@@ -1423,7 +1424,7 @@ void smp_br_process_slave_keys_response(tSMP_CB *p_cb, tSMP_INT_DATA *p_data)
 *******************************************************************************/
 void smp_br_send_pair_response(tSMP_CB *p_cb, tSMP_INT_DATA *p_data)
 {
-    SMP_TRACE_DEBUG("%s", __func__);
+    SMP_TRACE_DEBUG("%s\n", __func__);
 
     p_cb->local_i_key &= p_cb->peer_i_key;
     p_cb->local_r_key &= p_cb->peer_r_key;
@@ -1454,7 +1455,7 @@ void smp_pairing_cmpl(tSMP_CB *p_cb, tSMP_INT_DATA *p_data)
 *******************************************************************************/
 void smp_pair_terminate(tSMP_CB *p_cb, tSMP_INT_DATA *p_data)
 {
-    SMP_TRACE_DEBUG("%s", __func__);
+    SMP_TRACE_DEBUG("%s\n", __func__);
     p_cb->status = SMP_CONN_TOUT;
     smp_proc_pairing_cmpl(p_cb);
 }
@@ -1468,7 +1469,7 @@ void smp_idle_terminate(tSMP_CB *p_cb, tSMP_INT_DATA *p_data)
 {
     if (p_cb->flags & SMP_PAIR_FLAGS_WE_STARTED_DD)
     {
-        SMP_TRACE_DEBUG("Pairing terminated at IDLE state.");
+        SMP_TRACE_DEBUG("Pairing terminated at IDLE state.\n");
         p_cb->status = SMP_FAIL;
         smp_proc_pairing_cmpl(p_cb);
     }
@@ -1495,7 +1496,7 @@ void smp_fast_conn_param(tSMP_CB *p_cb, tSMP_INT_DATA *p_data)
 *******************************************************************************/
 void smp_both_have_public_keys(tSMP_CB *p_cb, tSMP_INT_DATA *p_data)
 {
-    SMP_TRACE_DEBUG("%s",__func__);
+    SMP_TRACE_DEBUG("%s\n",__func__);
 
     /* invokes DHKey computation */
     smp_compute_dhkey(p_cb);
@@ -1515,17 +1516,17 @@ void smp_both_have_public_keys(tSMP_CB *p_cb, tSMP_INT_DATA *p_data)
 *******************************************************************************/
 void smp_start_secure_connection_phase1(tSMP_CB *p_cb, tSMP_INT_DATA *p_data)
 {
-    SMP_TRACE_DEBUG("%s", __func__);
+    SMP_TRACE_DEBUG("%s\n", __func__);
 
     if (p_cb->selected_association_model == SMP_MODEL_SEC_CONN_JUSTWORKS)
     {
         p_cb->sec_level = SMP_SEC_UNAUTHENTICATE;
-        SMP_TRACE_EVENT ("p_cb->sec_level =%d (SMP_SEC_UNAUTHENTICATE) ", p_cb->sec_level );
+        SMP_TRACE_EVENT ("p_cb->sec_level =%d (SMP_SEC_UNAUTHENTICATE)\n ", p_cb->sec_level );
     }
     else
     {
         p_cb->sec_level = SMP_SEC_AUTHENTICATED;
-        SMP_TRACE_EVENT ("p_cb->sec_level =%d (SMP_SEC_AUTHENTICATED) ", p_cb->sec_level );
+        SMP_TRACE_EVENT ("p_cb->sec_level =%d (SMP_SEC_AUTHENTICATED)\n ", p_cb->sec_level );
     }
 
     switch(p_cb->selected_association_model)
@@ -1542,7 +1543,7 @@ void smp_start_secure_connection_phase1(tSMP_CB *p_cb, tSMP_INT_DATA *p_data)
             break;
         case SMP_MODEL_SEC_CONN_PASSKEY_DISP:
             /* passkey has to be provided to user */
-            SMP_TRACE_DEBUG("Need to generate SC Passkey");
+            SMP_TRACE_DEBUG("Need to generate SC Passkey\n");
             smp_generate_passkey(p_cb, NULL);
             break;
         case SMP_MODEL_SEC_CONN_OOB:
@@ -1550,7 +1551,7 @@ void smp_start_secure_connection_phase1(tSMP_CB *p_cb, tSMP_INT_DATA *p_data)
             smp_process_secure_connection_oob_data(p_cb, NULL);
             break;
         default:
-            SMP_TRACE_ERROR ("Association Model = %d is not used in LE SC",
+            SMP_TRACE_ERROR ("Association Model = %d is not used in LE SC\n",
                               p_cb->selected_association_model);
             break;
     }
@@ -1564,7 +1565,7 @@ void smp_start_secure_connection_phase1(tSMP_CB *p_cb, tSMP_INT_DATA *p_data)
 *******************************************************************************/
 void smp_process_local_nonce(tSMP_CB *p_cb, tSMP_INT_DATA *p_data)
 {
-    SMP_TRACE_DEBUG("%s", __func__);
+    SMP_TRACE_DEBUG("%s\n", __func__);
 
     switch(p_cb->selected_association_model)
     {
@@ -1584,7 +1585,7 @@ void smp_process_local_nonce(tSMP_CB *p_cb, tSMP_INT_DATA *p_data)
                 {
                     /* slave commitment is already received, send local nonce, wait for remote nonce*/
                     SMP_TRACE_DEBUG("master in assoc mode = %d \
-                    already rcvd slave commitment - race condition",
+                    already rcvd slave commitment - race condition\n",
                                       p_cb->selected_association_model);
                     p_cb->flags &= ~SMP_PAIR_FLAG_HAVE_PEER_COMM;
                     smp_send_rand(p_cb, NULL);
@@ -1619,7 +1620,7 @@ void smp_process_local_nonce(tSMP_CB *p_cb, tSMP_INT_DATA *p_data)
             smp_set_state(SMP_STATE_WAIT_NONCE);
             break;
         default:
-            SMP_TRACE_ERROR ("Association Model = %d is not used in LE SC",
+            SMP_TRACE_ERROR ("Association Model = %d is not used in LE SC\n",
                               p_cb->selected_association_model);
             break;
     }
@@ -1636,7 +1637,7 @@ void smp_process_peer_nonce(tSMP_CB *p_cb, tSMP_INT_DATA *p_data)
 {
     UINT8   reason;
 
-    SMP_TRACE_DEBUG("%s start ", __func__);
+    SMP_TRACE_DEBUG("%s start \n", __func__);
 
     switch(p_cb->selected_association_model)
     {
@@ -1702,12 +1703,12 @@ void smp_process_peer_nonce(tSMP_CB *p_cb, tSMP_INT_DATA *p_data)
             smp_sm_event(p_cb, SMP_SC_PHASE1_CMPLT_EVT, NULL);
             break;
         default:
-            SMP_TRACE_ERROR ("Association Model = %d is not used in LE SC",
+            SMP_TRACE_ERROR ("Association Model = %d is not used in LE SC\n",
                               p_cb->selected_association_model);
             break;
     }
 
-    SMP_TRACE_DEBUG("%s end ",__FUNCTION__);
+    SMP_TRACE_DEBUG("%s end\n ",__FUNCTION__);
 }
 
 /*******************************************************************************
@@ -1719,17 +1720,17 @@ void smp_match_dhkey_checks(tSMP_CB *p_cb, tSMP_INT_DATA *p_data)
 {
     UINT8 reason = SMP_DHKEY_CHK_FAIL;
 
-    SMP_TRACE_DEBUG("%s", __func__);
+    SMP_TRACE_DEBUG("%s\n", __func__);
 
     if (memcmp(p_data->key.p_data, p_cb->remote_dhkey_check, BT_OCTET16_LEN))
     {
-        SMP_TRACE_WARNING ("dhkey chcks do no match");
+        SMP_TRACE_WARNING ("dhkey chcks do no match\n");
         p_cb->failure = reason;
         smp_sm_event(p_cb, SMP_AUTH_CMPL_EVT, &reason);
         return;
     }
 
-    SMP_TRACE_EVENT ("dhkey chcks match");
+    SMP_TRACE_EVENT ("dhkey chcks match\n");
 
     /* compare the max encryption key size, and save the smaller one for the link */
     if (p_cb->peer_enc_size < p_cb->loc_enc_size)
@@ -1757,7 +1758,7 @@ void smp_match_dhkey_checks(tSMP_CB *p_cb, tSMP_INT_DATA *p_data)
 *******************************************************************************/
 void smp_move_to_secure_connections_phase2(tSMP_CB *p_cb, tSMP_INT_DATA *p_data)
 {
-    SMP_TRACE_DEBUG("%s",__func__);
+    SMP_TRACE_DEBUG("%s\n",__func__);
     smp_sm_event(p_cb, SMP_SC_PHASE1_CMPLT_EVT, NULL);
 }
 
@@ -1770,7 +1771,7 @@ void smp_move_to_secure_connections_phase2(tSMP_CB *p_cb, tSMP_INT_DATA *p_data)
 *******************************************************************************/
 void smp_phase_2_dhkey_checks_are_present(tSMP_CB *p_cb, tSMP_INT_DATA *p_data)
 {
-    SMP_TRACE_DEBUG("%s",__func__);
+    SMP_TRACE_DEBUG("%s\n",__func__);
 
     if (p_cb->flags & SMP_PAIR_FLAG_HAVE_PEER_DHK_CHK)
         smp_sm_event(p_cb, SMP_SC_2_DHCK_CHKS_PRES_EVT, NULL);
@@ -1786,7 +1787,7 @@ void smp_phase_2_dhkey_checks_are_present(tSMP_CB *p_cb, tSMP_INT_DATA *p_data)
 *******************************************************************************/
 void smp_wait_for_both_public_keys(tSMP_CB *p_cb, tSMP_INT_DATA *p_data)
 {
-    SMP_TRACE_DEBUG("%s",__func__);
+    SMP_TRACE_DEBUG("%s\n",__func__);
 
     if ((p_cb->flags & SMP_PAIR_FLAG_HAVE_PEER_PUBL_KEY) &&
         (p_cb->flags & SMP_PAIR_FLAG_HAVE_LOCAL_PUBL_KEY))
@@ -1808,7 +1809,7 @@ void smp_start_passkey_verification(tSMP_CB *p_cb, tSMP_INT_DATA *p_data)
 {
     UINT8 *p = NULL;
 
-    SMP_TRACE_DEBUG("%s", __func__);
+    SMP_TRACE_DEBUG("%s\n", __func__);
     p = p_cb->local_random;
     UINT32_TO_STREAM(p, p_data->passkey);
 
@@ -1825,7 +1826,7 @@ void smp_start_passkey_verification(tSMP_CB *p_cb, tSMP_INT_DATA *p_data)
 *******************************************************************************/
 void smp_process_secure_connection_oob_data(tSMP_CB *p_cb, tSMP_INT_DATA *p_data)
 {
-    SMP_TRACE_DEBUG("%s", __func__);
+    SMP_TRACE_DEBUG("%s\n", __func__);
 
     tSMP_SC_OOB_DATA *p_sc_oob_data = &p_cb->sc_oob_data;
     if (p_sc_oob_data->loc_oob_data.present)
@@ -1835,13 +1836,13 @@ void smp_process_secure_connection_oob_data(tSMP_CB *p_cb, tSMP_INT_DATA *p_data
     }
     else
     {
-        SMP_TRACE_EVENT ("local OOB randomizer is absent");
+        SMP_TRACE_EVENT ("local OOB randomizer is absent\n");
         memset(p_cb->local_random, 0, sizeof (p_cb->local_random));
     }
 
     if (!p_sc_oob_data->peer_oob_data.present)
     {
-        SMP_TRACE_EVENT ("peer OOB data is absent");
+        SMP_TRACE_EVENT ("peer OOB data is absent\n");
         memset(p_cb->peer_random, 0, sizeof (p_cb->peer_random));
     }
     else
@@ -1863,7 +1864,7 @@ void smp_process_secure_connection_oob_data(tSMP_CB *p_cb, tSMP_INT_DATA *p_data
         if (p_cb->peer_oob_flag != SMP_OOB_PRESENT)
         {
             /* the peer doesn't have local randomiser */
-            SMP_TRACE_EVENT ("peer didn't receive local OOB data, set local randomizer to 0");
+            SMP_TRACE_EVENT ("peer didn't receive local OOB data, set local randomizer to 0\n");
             memset(p_cb->local_random, 0, sizeof (p_cb->local_random));
         }
     }
@@ -1881,7 +1882,7 @@ void smp_process_secure_connection_oob_data(tSMP_CB *p_cb, tSMP_INT_DATA *p_data
 *******************************************************************************/
 void smp_set_local_oob_keys(tSMP_CB *p_cb, tSMP_INT_DATA *p_data)
 {
-    SMP_TRACE_DEBUG("%s", __func__);
+    SMP_TRACE_DEBUG("%s\n", __func__);
 
     memcpy(p_cb->sc_oob_data.loc_oob_data.private_key_used, p_cb->private_key,
            BT_OCTET32_LEN);
@@ -1896,7 +1897,7 @@ void smp_set_local_oob_keys(tSMP_CB *p_cb, tSMP_INT_DATA *p_data)
 *******************************************************************************/
 void smp_set_local_oob_random_commitment(tSMP_CB *p_cb, tSMP_INT_DATA *p_data)
 {
-    SMP_TRACE_DEBUG("%s", __func__);
+    SMP_TRACE_DEBUG("%s\n", __func__);
     memcpy(p_cb->sc_oob_data.loc_oob_data.randomizer, p_cb->rand,
            BT_OCTET16_LEN);
 
@@ -1907,7 +1908,7 @@ void smp_set_local_oob_random_commitment(tSMP_CB *p_cb, tSMP_INT_DATA *p_data)
 
 #if SMP_DEBUG == TRUE
     UINT8   *p_print = NULL;
-    SMP_TRACE_DEBUG("local SC OOB data set:");
+    SMP_TRACE_DEBUG("local SC OOB data set:\n");
     p_print = (UINT8*) &p_cb->sc_oob_data.loc_oob_data.addr_sent_to;
     smp_debug_print_nbyte_little_endian (p_print, (const UINT8 *)"addr_sent_to",
                                          sizeof(tBLE_BD_ADDR));
@@ -1952,7 +1953,7 @@ void smp_link_encrypted(BD_ADDR bda, UINT8 encr_enable)
 {
     tSMP_CB *p_cb = &smp_cb;
 
-    SMP_TRACE_DEBUG("%s encr_enable=%d", __func__, encr_enable);
+    SMP_TRACE_DEBUG("%s encr_enable=%d\n", __func__, encr_enable);
 
     if (memcmp(&smp_cb.pairing_bda[0], bda, BD_ADDR_LEN) == 0)
     {
@@ -1980,7 +1981,7 @@ void smp_link_encrypted(BD_ADDR bda, UINT8 encr_enable)
 *******************************************************************************/
 BOOLEAN smp_proc_ltk_request(BD_ADDR bda)
 {
-    SMP_TRACE_DEBUG("%s state = %d",  __func__, smp_cb.state);
+    SMP_TRACE_DEBUG("%s state = %d\n",  __func__, smp_cb.state);
     BOOLEAN match = FALSE;
 
     if (!memcmp(bda, smp_cb.pairing_bda, BD_ADDR_LEN))
@@ -2021,7 +2022,7 @@ void smp_process_secure_connection_long_term_key(void)
 {
     tSMP_CB     *p_cb = &smp_cb;
 
-    SMP_TRACE_DEBUG("%s", __func__);
+    SMP_TRACE_DEBUG("%s\n", __func__);
     smp_save_secure_connections_long_term_key(p_cb);
 
     smp_update_key_mask (p_cb, SMP_SEC_KEY_TYPE_ENC, FALSE);
@@ -2041,7 +2042,7 @@ void smp_process_secure_connection_long_term_key(void)
 *******************************************************************************/
 void smp_set_derive_link_key(tSMP_CB *p_cb, tSMP_INT_DATA *p_data)
 {
-    SMP_TRACE_DEBUG ("%s", __func__);
+    SMP_TRACE_DEBUG ("%s\n", __func__);
     p_cb->derive_lk = TRUE;
     smp_update_key_mask (p_cb, SMP_SEC_KEY_TYPE_LK, FALSE);
     smp_key_distribution(p_cb, NULL);
@@ -2060,10 +2061,10 @@ void smp_derive_link_key_from_long_term_key(tSMP_CB *p_cb, tSMP_INT_DATA *p_data
 {
     tSMP_STATUS status = SMP_PAIR_FAIL_UNKNOWN;
 
-    SMP_TRACE_DEBUG("%s", __func__);
+    SMP_TRACE_DEBUG("%s\n", __func__);
     if (!smp_calculate_link_key_from_long_term_key(p_cb))
     {
-        SMP_TRACE_ERROR("%s failed", __FUNCTION__);
+        SMP_TRACE_ERROR("%s failed\n", __FUNCTION__);
         smp_sm_event(p_cb, SMP_AUTH_CMPL_EVT, &status);
         return;
     }
@@ -2084,15 +2085,15 @@ void smp_br_process_link_key(tSMP_CB *p_cb, tSMP_INT_DATA *p_data)
 {
     tSMP_STATUS status = SMP_PAIR_FAIL_UNKNOWN;
 
-    SMP_TRACE_DEBUG("%s", __func__);
+    SMP_TRACE_DEBUG("%s\n", __func__);
     if (!smp_calculate_long_term_key_from_link_key(p_cb))
     {
-        SMP_TRACE_ERROR ("%s failed",__FUNCTION__);
+        SMP_TRACE_ERROR ("%s failed\n",__FUNCTION__);
         smp_sm_event(p_cb, SMP_BR_AUTH_CMPL_EVT, &status);
         return;
     }
 
-    SMP_TRACE_DEBUG("%s: LTK derivation from LK successfully completed", __FUNCTION__);
+    SMP_TRACE_DEBUG("%s: LTK derivation from LK successfully completed\n", __FUNCTION__);
     smp_save_secure_connections_long_term_key(p_cb);
     smp_update_key_mask (p_cb, SMP_SEC_KEY_TYPE_ENC, FALSE);
     smp_br_select_next_key(p_cb, NULL);
@@ -2105,7 +2106,7 @@ void smp_br_process_link_key(tSMP_CB *p_cb, tSMP_INT_DATA *p_data)
 *******************************************************************************/
 void smp_key_distribution_by_transport(tSMP_CB *p_cb, tSMP_INT_DATA *p_data)
 {
-    SMP_TRACE_DEBUG("%s", __func__);
+    SMP_TRACE_DEBUG("%s\n", __func__);
     if (p_cb->smp_over_br)
     {
         smp_br_select_next_key(p_cb, NULL);
@@ -2123,7 +2124,7 @@ void smp_key_distribution_by_transport(tSMP_CB *p_cb, tSMP_INT_DATA *p_data)
 *******************************************************************************/
 void smp_br_pairing_complete(tSMP_CB *p_cb, tSMP_INT_DATA *p_data)
 {
-    SMP_TRACE_DEBUG("%s", __func__);
+    SMP_TRACE_DEBUG("%s\n", __func__);
 
     if (p_cb->total_tx_unacked == 0)
     {

+ 2 - 2
components/bt/bluedroid/stack/smp/smp_api.c

@@ -132,7 +132,7 @@ tSMP_STATUS SMP_Pair (BD_ADDR bd_addr)
     tSMP_CB   *p_cb = &smp_cb;
     UINT8     status = SMP_PAIR_INTERNAL_ERR;
 
-    SMP_TRACE_EVENT ("%s state=%d br_state=%d flag=0x%x ",
+    SMP_TRACE_EVENT ("%s state=%d br_state=%d flag=0x%x \n",
                       __FUNCTION__, p_cb->state, p_cb->br_state, p_cb->flags);
     if (p_cb->state != SMP_STATE_IDLE || p_cb->flags & SMP_PAIR_FLAGS_WE_STARTED_DD ||
         p_cb->smp_over_br)
@@ -148,7 +148,7 @@ tSMP_STATUS SMP_Pair (BD_ADDR bd_addr)
 
         if (!L2CA_ConnectFixedChnl (L2CAP_SMP_CID, bd_addr))
         {
-            SMP_TRACE_ERROR("%s: L2C connect fixed channel failed.", __FUNCTION__);
+            SMP_TRACE_ERROR("%s: L2C connect fixed channel failed.\n", __FUNCTION__);
             smp_sm_event(p_cb, SMP_AUTH_CMPL_EVT, &status);
             return status;
         }

+ 51 - 48
components/bt/bluedroid/stack/smp/smp_keys.c

@@ -82,7 +82,7 @@ void smp_debug_print_nbyte_little_endian(UINT8 *p, const UINT8 *key_name, UINT8
     int     row_count;
     UINT8   p_buf[512];
 
-    SMP_TRACE_WARNING("%s(LSB ~ MSB):", key_name);
+    SMP_TRACE_WARNING("%s(LSB ~ MSB):\n", key_name);
     memset(p_buf, 0, sizeof(p_buf));
     row_count = len % col_count ? len / col_count + 1: len / col_count;
 
@@ -145,16 +145,16 @@ BOOLEAN smp_encrypt_data (UINT8 *key, UINT8 key_len,
     UINT8 *p_rev_key = NULL;     /* input key in big endilan format */
     UINT8 *p_rev_output = NULL;  /* encrypted output in big endilan format */
 
-    SMP_TRACE_DEBUG ("%s", __func__);
+    SMP_TRACE_DEBUG ("%s\n", __func__);
     if ( (p_out == NULL ) || (key_len != SMP_ENCRYT_KEY_SIZE) )
     {
-        SMP_TRACE_ERROR ("%s failed", __func__);
+        SMP_TRACE_ERROR ("%s failed\n", __func__);
         return FALSE;
     }
 
     if ((p_start = (UINT8 *)GKI_getbuf((SMP_ENCRYT_DATA_SIZE*4))) == NULL)
     {
-        SMP_TRACE_ERROR ("%s failed unable to allocate buffer", __func__);
+        SMP_TRACE_ERROR ("%s failed unable to allocate buffer\n", __func__);
         return FALSE;
     }
 
@@ -277,7 +277,7 @@ void smp_generate_stk(tSMP_CB *p_cb, tSMP_INT_DATA *p_data)
     tSMP_ENC output;
     tSMP_STATUS status = SMP_PAIR_FAIL_UNKNOWN;
 
-    SMP_TRACE_DEBUG ("%s", __func__);
+    SMP_TRACE_DEBUG ("%s\n", __func__);
 
     if (p_cb->le_secure_connections_mode_is_used)
     {
@@ -312,7 +312,7 @@ void smp_generate_srand_mrand_confirm(tSMP_CB *p_cb, tSMP_INT_DATA *p_data)
 {
     UNUSED(p_data);
 
-    SMP_TRACE_DEBUG ("%s", __func__);
+    SMP_TRACE_DEBUG ("%s\n", __func__);
     p_cb->rand_enc_proc_state = SMP_GEN_SRAND_MRAND;
     /* generate MRand or SRand */
     if (!btsnd_hcic_ble_rand((void *)smp_rand_back))
@@ -333,7 +333,7 @@ void smp_generate_rand_cont(tSMP_CB *p_cb, tSMP_INT_DATA *p_data)
 {
     UNUSED(p_data);
 
-    SMP_TRACE_DEBUG ("%s", __func__);
+    SMP_TRACE_DEBUG ("%s\n", __func__);
     p_cb->rand_enc_proc_state = SMP_GEN_SRAND_MRAND_CONT;
     /* generate 64 MSB of MRand or SRand */
     if (!btsnd_hcic_ble_rand((void *)smp_rand_back))
@@ -360,7 +360,7 @@ void smp_generate_ltk(tSMP_CB *p_cb, tSMP_INT_DATA *p_data)
     UNUSED(p_data);
 
     BOOLEAN div_status;
-    SMP_TRACE_DEBUG ("%s", __FUNCTION__);
+    SMP_TRACE_DEBUG ("%s\n", __FUNCTION__);
     if (smp_get_br_state() == SMP_BR_STATE_BOND_PENDING)
     {
         smp_br_process_link_key(p_cb, NULL);
@@ -380,7 +380,7 @@ void smp_generate_ltk(tSMP_CB *p_cb, tSMP_INT_DATA *p_data)
     }
     else
     {
-        SMP_TRACE_DEBUG ("Generate DIV for LTK");
+        SMP_TRACE_DEBUG ("Generate DIV for LTK\n");
         p_cb->rand_enc_proc_state = SMP_GEN_DIV_LTK;
         /* generate MRand or SRand */
         if (!btsnd_hcic_ble_rand((void *)smp_rand_back))
@@ -409,7 +409,7 @@ void smp_compute_csrk(tSMP_CB *p_cb, tSMP_INT_DATA *p_data)
     tSMP_ENC    output;
     tSMP_STATUS   status = SMP_PAIR_FAIL_UNKNOWN;
 
-    SMP_TRACE_DEBUG ("smp_compute_csrk div=%x", p_cb->div);
+    SMP_TRACE_DEBUG ("smp_compute_csrk div=%x\n", p_cb->div);
     BTM_GetDeviceEncRoot(er);
     /* CSRK = d1(ER, DIV, 1) */
     UINT16_TO_STREAM(p, p_cb->div);
@@ -417,7 +417,7 @@ void smp_compute_csrk(tSMP_CB *p_cb, tSMP_INT_DATA *p_data)
 
     if (!SMP_Encrypt(er, BT_OCTET16_LEN, buffer, 4, &output))
     {
-        SMP_TRACE_ERROR("smp_generate_csrk failed");
+        SMP_TRACE_ERROR("smp_generate_csrk failed\n");
         if (p_cb->smp_over_br)
         {
             smp_br_state_machine_event(p_cb, SMP_BR_AUTH_CMPL_EVT, &status);
@@ -475,7 +475,7 @@ void smp_concatenate_local( tSMP_CB *p_cb, UINT8 **p_data, UINT8 op_code)
 {
     UINT8   *p = *p_data;
 
-    SMP_TRACE_DEBUG ("%s", __func__);
+    SMP_TRACE_DEBUG ("%s\n", __func__);
     UINT8_TO_STREAM(p, op_code);
     UINT8_TO_STREAM(p, p_cb->local_io_capability);
     UINT8_TO_STREAM(p, p_cb->loc_oob_flag);
@@ -495,7 +495,7 @@ void smp_concatenate_peer( tSMP_CB *p_cb, UINT8 **p_data, UINT8 op_code)
 {
     UINT8   *p = *p_data;
 
-    SMP_TRACE_DEBUG ("smp_concatenate_peer ");
+    SMP_TRACE_DEBUG ("smp_concatenate_peer \n");
     UINT8_TO_STREAM(p, op_code);
     UINT8_TO_STREAM(p, p_cb->peer_io_caps);
     UINT8_TO_STREAM(p, p_cb->peer_oob_flag);
@@ -523,11 +523,11 @@ void smp_gen_p1_4_confirm( tSMP_CB *p_cb, BT_OCTET16 p1)
     tBLE_ADDR_TYPE    addr_type = 0;
     BD_ADDR           remote_bda;
 
-    SMP_TRACE_DEBUG ("smp_gen_p1_4_confirm");
+    SMP_TRACE_DEBUG ("smp_gen_p1_4_confirm\n");
 
     if (!BTM_ReadRemoteConnectionAddr(p_cb->pairing_bda, remote_bda, &addr_type))
     {
-        SMP_TRACE_ERROR("can not generate confirm for unknown device");
+        SMP_TRACE_ERROR("can not generate confirm for unknown device\n");
         return;
     }
 
@@ -556,7 +556,7 @@ void smp_gen_p1_4_confirm( tSMP_CB *p_cb, BT_OCTET16 p1)
         smp_concatenate_local(p_cb, &p, SMP_OPCODE_PAIRING_RSP);
     }
 #if SMP_DEBUG == TRUE
-    SMP_TRACE_DEBUG("p1 = pres || preq || rat' || iat'");
+    SMP_TRACE_DEBUG("p1 = pres || preq || rat' || iat'\n");
     smp_debug_print_nbyte_little_endian ((UINT8 *)p1, (const UINT8 *)"P1", 16);
 #endif
 }
@@ -576,14 +576,14 @@ void smp_gen_p2_4_confirm( tSMP_CB *p_cb, BT_OCTET16 p2)
     UINT8       *p = (UINT8 *)p2;
     BD_ADDR     remote_bda;
     tBLE_ADDR_TYPE  addr_type = 0;
-
+	SMP_TRACE_DEBUG ("smp_gen_p2_4_confirm\n");
     if (!BTM_ReadRemoteConnectionAddr(p_cb->pairing_bda, remote_bda, &addr_type))
     {
-        SMP_TRACE_ERROR("can not generate confirm p2 for unknown device");
+        SMP_TRACE_ERROR("can not generate confirm p2 for unknown device\n");
         return;
     }
 
-    SMP_TRACE_DEBUG ("smp_gen_p2_4_confirm");
+    SMP_TRACE_DEBUG ("smp_gen_p2_4_confirm\n");
 
     memset(p, 0, sizeof(BT_OCTET16));
 
@@ -624,7 +624,7 @@ void smp_calculate_comfirm (tSMP_CB *p_cb, BT_OCTET16 rand, BD_ADDR bda)
     tSMP_ENC       output;
     tSMP_STATUS     status = SMP_PAIR_FAIL_UNKNOWN;
 
-    SMP_TRACE_DEBUG ("smp_calculate_comfirm ");
+    SMP_TRACE_DEBUG ("smp_calculate_comfirm \n");
     /* generate p1 = pres || preq || rat' || iat' */
     smp_gen_p1_4_confirm(p_cb, p1);
 
@@ -661,9 +661,9 @@ static void smp_calculate_comfirm_cont(tSMP_CB *p_cb, tSMP_ENC *p)
     tSMP_ENC      output;
     tSMP_STATUS     status = SMP_PAIR_FAIL_UNKNOWN;
 
-    SMP_TRACE_DEBUG ("smp_calculate_comfirm_cont ");
+    SMP_TRACE_DEBUG ("smp_calculate_comfirm_cont \n");
 #if SMP_DEBUG == TRUE
-    SMP_TRACE_DEBUG("Confirm step 1 p1' = e(k, r XOR p1)  Generated");
+    SMP_TRACE_DEBUG("Confirm step 1 p1' = e(k, r XOR p1)  Generated\n");
     smp_debug_print_nbyte_little_endian (p->param_buf, (const UINT8 *)"C1", 16);
 #endif
 
@@ -676,11 +676,12 @@ static void smp_calculate_comfirm_cont(tSMP_CB *p_cb, tSMP_ENC *p)
     /* calculate: Confirm = E(k, p1' XOR p2) */
     if (!SMP_Encrypt(p_cb->tk, BT_OCTET16_LEN, p2, BT_OCTET16_LEN, &output))
     {
-        SMP_TRACE_ERROR("smp_calculate_comfirm_cont failed");
+        SMP_TRACE_ERROR("smp_calculate_comfirm_cont failed\n");
         smp_sm_event(p_cb, SMP_AUTH_CMPL_EVT, &status);
     }
     else
     {
+    	SMP_TRACE_DEBUG("p_cb->rand_enc_proc_state=%d\n",p_cb->rand_enc_proc_state);
         switch (p_cb->rand_enc_proc_state)
         {
             case SMP_GEN_CONFIRM:
@@ -708,7 +709,7 @@ static void smp_generate_confirm(tSMP_CB *p_cb, tSMP_INT_DATA *p_data)
 {
     UNUSED(p_data);
 
-    SMP_TRACE_DEBUG ("%s", __func__);
+    SMP_TRACE_DEBUG ("%s\n", __func__);
     p_cb->rand_enc_proc_state = SMP_GEN_CONFIRM;
     smp_debug_print_nbyte_little_endian ((UINT8 *)p_cb->rand,  (const UINT8 *)"local rand", 16);
     smp_calculate_comfirm(p_cb, p_cb->rand, p_cb->pairing_bda);
@@ -729,7 +730,7 @@ void smp_generate_compare (tSMP_CB *p_cb, tSMP_INT_DATA *p_data)
 {
     UNUSED(p_data);
 
-    SMP_TRACE_DEBUG ("smp_generate_compare ");
+    SMP_TRACE_DEBUG ("smp_generate_compare \n");
     p_cb->rand_enc_proc_state = SMP_GEN_COMPARE;
     smp_debug_print_nbyte_little_endian ((UINT8 *)p_cb->rrand,  (const UINT8 *)"peer rand", 16);
     smp_calculate_comfirm(p_cb, p_cb->rrand, p_cb->local_bda);
@@ -749,7 +750,7 @@ static void smp_process_confirm(tSMP_CB *p_cb, tSMP_ENC *p)
 {
     tSMP_KEY    key;
 
-    SMP_TRACE_DEBUG ("%s", __FUNCTION__);
+    SMP_TRACE_DEBUG ("%s\n", __FUNCTION__);
     memcpy(p_cb->confirm, p->param_buf, BT_OCTET16_LEN);
 
 #if (SMP_DEBUG == TRUE)
@@ -759,7 +760,9 @@ static void smp_process_confirm(tSMP_CB *p_cb, tSMP_ENC *p)
 
     key.key_type = SMP_KEY_TYPE_CFM;
     key.p_data = p->param_buf;
+	
     smp_sm_event(p_cb, SMP_KEY_READY_EVT, &key);
+
 }
 
 /*******************************************************************************
@@ -776,14 +779,14 @@ static void smp_process_compare(tSMP_CB *p_cb, tSMP_ENC *p)
 {
     tSMP_KEY    key;
 
-    SMP_TRACE_DEBUG ("smp_process_compare ");
+    SMP_TRACE_DEBUG ("smp_process_compare \n");
 #if (SMP_DEBUG == TRUE)
-    SMP_TRACE_DEBUG("Compare Generated");
+    SMP_TRACE_DEBUG("Compare Generated\n");
     smp_debug_print_nbyte_little_endian (p->param_buf,  (const UINT8 *)"Compare", 16);
 #endif
     key.key_type = SMP_KEY_TYPE_CMP;
     key.p_data   = p->param_buf;
-
+	//smp_set_state(SMP_STATE_CONFIRM);
     smp_sm_event(p_cb, SMP_KEY_READY_EVT, &key);
 }
 
@@ -830,14 +833,14 @@ static void smp_generate_ltk_cont(tSMP_CB *p_cb, tSMP_INT_DATA *p_data)
     tSMP_ENC    output;
     tSMP_STATUS     status = SMP_PAIR_FAIL_UNKNOWN;
 
-    SMP_TRACE_DEBUG ("%s", __func__);
+    SMP_TRACE_DEBUG ("%s\n", __func__);
     BTM_GetDeviceEncRoot(er);
 
     /* LTK = d1(ER, DIV, 0)= e(ER, DIV)*/
     if (!SMP_Encrypt(er, BT_OCTET16_LEN, (UINT8 *)&p_cb->div,
                      sizeof(UINT16), &output))
     {
-        SMP_TRACE_ERROR("%s failed", __func__);
+        SMP_TRACE_ERROR("%s failed\n", __func__);
         smp_sm_event(p_cb, SMP_AUTH_CMPL_EVT, &status);
     }
     else
@@ -867,7 +870,7 @@ static void smp_generate_y(tSMP_CB *p_cb, tSMP_INT_DATA *p)
     tSMP_STATUS     status = SMP_PAIR_FAIL_UNKNOWN;
 
 
-    SMP_TRACE_DEBUG ("smp_generate_y ");
+    SMP_TRACE_DEBUG ("smp_generate_y \n");
     BTM_GetDeviceDHK(dhk);
 
     if (!SMP_Encrypt(dhk, BT_OCTET16_LEN, p_cb->enc_rand,
@@ -898,7 +901,7 @@ static void smp_generate_rand_vector (tSMP_CB *p_cb, tSMP_INT_DATA *p)
 
     /* generate EDIV and rand now */
     /* generate random vector */
-    SMP_TRACE_DEBUG ("smp_generate_rand_vector ");
+    SMP_TRACE_DEBUG ("smp_generate_rand_vector\n");
     p_cb->rand_enc_proc_state = SMP_GEN_RAND_V;
     if (!btsnd_hcic_ble_rand((void *)smp_rand_back))
         smp_rand_back(NULL);
@@ -946,7 +949,7 @@ BOOLEAN smp_calculate_legacy_short_term_key(tSMP_CB *p_cb, tSMP_ENC *output)
     BT_OCTET16 ptext;
     UINT8 *p = ptext;
 
-    SMP_TRACE_DEBUG ("%s", __func__);
+    SMP_TRACE_DEBUG ("%s\n", __func__);
     memset(p, 0, BT_OCTET16_LEN);
     if (p_cb->role == HCI_ROLE_MASTER)
     {
@@ -964,7 +967,7 @@ BOOLEAN smp_calculate_legacy_short_term_key(tSMP_CB *p_cb, tSMP_ENC *output)
     encrypted = SMP_Encrypt( p_cb->tk, BT_OCTET16_LEN, ptext, BT_OCTET16_LEN, output);
     if (!encrypted)
     {
-        SMP_TRACE_ERROR("%s failed", __func__);
+        SMP_TRACE_ERROR("%s failed\n", __func__);
     }
     return encrypted;
 }
@@ -1007,19 +1010,19 @@ void smp_create_private_key(tSMP_CB *p_cb, tSMP_INT_DATA *p_data)
 *******************************************************************************/
 void smp_use_oob_private_key(tSMP_CB *p_cb, tSMP_INT_DATA *p_data)
 {
-    SMP_TRACE_DEBUG ("%s req_oob_type: %d, role: %d",
+    SMP_TRACE_DEBUG ("%s req_oob_type: %d, role: %d\n",
                       __func__, p_cb->req_oob_type, p_cb->role);
 
     switch (p_cb->req_oob_type)
     {
         case SMP_OOB_BOTH:
         case SMP_OOB_LOCAL:
-            SMP_TRACE_DEBUG("%s restore secret key", __func__)
+            SMP_TRACE_DEBUG("%s restore secret key\n", __func__);
             memcpy(p_cb->private_key, p_cb->sc_oob_data.loc_oob_data.private_key_used, BT_OCTET32_LEN);
             smp_process_private_key(p_cb);
             break;
         default:
-            SMP_TRACE_DEBUG("%s create secret key anew", __func__);
+            SMP_TRACE_DEBUG("%s create secret key anew\n", __func__);
             smp_set_state(SMP_STATE_PAIR_REQ_RSP);
             smp_decide_association_model(p_cb, NULL);
             break;
@@ -1038,7 +1041,7 @@ void smp_use_oob_private_key(tSMP_CB *p_cb, tSMP_INT_DATA *p_data)
 void smp_continue_private_key_creation (tSMP_CB *p_cb, tBTM_RAND_ENC *p)
 {
     UINT8   state = p_cb->rand_enc_proc_state & ~0x80;
-    SMP_TRACE_DEBUG ("%s state=0x%x", __func__, state);
+    SMP_TRACE_DEBUG ("%s state=0x%x\n", __func__, state);
 
     switch (state)
     {
@@ -1125,7 +1128,7 @@ void smp_compute_dhkey (tSMP_CB *p_cb)
     Point       peer_publ_key, new_publ_key;
     BT_OCTET32  private_key;
 
-    SMP_TRACE_DEBUG ("%s", __FUNCTION__);
+    SMP_TRACE_DEBUG ("%s\n", __FUNCTION__);
 
     memcpy(private_key, p_cb->private_key, BT_OCTET32_LEN);
     memcpy(peer_publ_key.x, p_cb->peer_publ_key.x, BT_OCTET32_LEN);
@@ -1161,7 +1164,7 @@ void smp_calculate_local_commitment(tSMP_CB *p_cb)
 {
     UINT8 random_input;
 
-    SMP_TRACE_DEBUG("%s", __FUNCTION__);
+    SMP_TRACE_DEBUG("%s\n", __FUNCTION__);
 
     switch (p_cb->selected_association_model)
     {
@@ -1169,7 +1172,7 @@ void smp_calculate_local_commitment(tSMP_CB *p_cb)
         case SMP_MODEL_SEC_CONN_NUM_COMP:
             if (p_cb->role  == HCI_ROLE_MASTER)
                 SMP_TRACE_WARNING ("local commitment calc on master is not expected \
-                                    for Just Works/Numeric Comparison models");
+                                    for Just Works/Numeric Comparison models\n");
             smp_calculate_f4(p_cb->loc_publ_key.x, p_cb->peer_publ_key.x, p_cb->rand, 0,
                              p_cb->commitment);
             break;
@@ -1180,12 +1183,12 @@ void smp_calculate_local_commitment(tSMP_CB *p_cb)
                              random_input, p_cb->commitment);
             break;
         case SMP_MODEL_SEC_CONN_OOB:
-            SMP_TRACE_WARNING ("local commitment calc is expected for OOB model BEFORE pairing");
+            SMP_TRACE_WARNING ("local commitment calc is expected for OOB model BEFORE pairing\n");
             smp_calculate_f4(p_cb->loc_publ_key.x, p_cb->loc_publ_key.x, p_cb->local_random, 0,
                              p_cb->commitment);
             break;
         default:
-            SMP_TRACE_ERROR("Association Model = %d is not used in LE SC",
+            SMP_TRACE_ERROR("Association Model = %d is not used in LE SC\n",
                              p_cb->selected_association_model);
             return;
     }
@@ -1215,7 +1218,7 @@ void smp_calculate_peer_commitment(tSMP_CB *p_cb, BT_OCTET16 output_buf)
         case SMP_MODEL_SEC_CONN_NUM_COMP:
             if (p_cb->role  == HCI_ROLE_SLAVE)
                 SMP_TRACE_WARNING ("peer commitment calc on slave is not expected \
-                for Just Works/Numeric Comparison models");
+                for Just Works/Numeric Comparison models\n");
             smp_calculate_f4(p_cb->peer_publ_key.x, p_cb->loc_publ_key.x, p_cb->rrand, 0,
                              output_buf);
             break;
@@ -1230,12 +1233,12 @@ void smp_calculate_peer_commitment(tSMP_CB *p_cb, BT_OCTET16 output_buf)
                              output_buf);
             break;
         default:
-            SMP_TRACE_ERROR("Association Model = %d is not used in LE SC",
+            SMP_TRACE_ERROR("Association Model = %d is not used in LE SC\n",
                              p_cb->selected_association_model);
             return;
     }
 
-    SMP_TRACE_EVENT ("peer commitment calculation is completed");
+    SMP_TRACE_EVENT ("peer commitment calculation is completed\n");
 }
 
 /*******************************************************************************
@@ -1386,7 +1389,7 @@ UINT32 smp_calculate_g2(UINT8 *u, UINT8 *v, UINT8 *x, UINT8 *y)
     UINT8   *p_prnt = NULL;
 #endif
 
-    SMP_TRACE_DEBUG ("%s", __FUNCTION__);
+    SMP_TRACE_DEBUG ("%s\n", __FUNCTION__);
 
     p = msg;
     ARRAY_TO_STREAM(p, y, BT_OCTET16_LEN);

+ 5 - 5
components/bt/bluedroid/stack/smp/smp_l2c.c

@@ -93,14 +93,14 @@ static void smp_connect_callback (UINT16 channel, BD_ADDR bd_addr, BOOLEAN conne
     tSMP_INT_DATA   int_data;
     BD_ADDR dummy_bda = {0};
 
-    SMP_TRACE_EVENT ("SMDBG l2c %s", __FUNCTION__);
+    SMP_TRACE_EVENT ("SMDBG l2c %s\n", __FUNCTION__);
 
     if (transport == BT_TRANSPORT_BR_EDR || memcmp(bd_addr, dummy_bda, BD_ADDR_LEN) == 0)
         return;
 
     if (memcmp(bd_addr, p_cb->pairing_bda, BD_ADDR_LEN) == 0)
     {
-        SMP_TRACE_EVENT ("%s()  for pairing BDA: %08x%04x  Event: %s",
+        SMP_TRACE_EVENT ("%s()  for pairing BDA: %08x%04x  Event: %s\n",
                         __FUNCTION__,
                         (bd_addr[0]<<24)+(bd_addr[1]<<16)+(bd_addr[2]<<8) + bd_addr[3],
                         (bd_addr[4]<<8)+bd_addr[5],
@@ -146,14 +146,14 @@ static void smp_data_received(UINT16 channel, BD_ADDR bd_addr, BT_HDR *p_buf)
     tSMP_CB *p_cb = &smp_cb;
     UINT8   *p = (UINT8 *)(p_buf + 1) + p_buf->offset;
     UINT8   cmd ;
-    SMP_TRACE_EVENT ("SMDBG l2c %s", __FUNCTION__);
+    SMP_TRACE_EVENT ("\nSMDBG l2c %s\n", __FUNCTION__);
 
     STREAM_TO_UINT8(cmd, p);
 
     /* sanity check */
     if ((SMP_OPCODE_MAX < cmd) || (SMP_OPCODE_MIN > cmd))
     {
-        SMP_TRACE_WARNING( "Ignore received command with RESERVED code 0x%02x", cmd);
+        SMP_TRACE_WARNING( "Ignore received command with RESERVED code 0x%02x\n", cmd);
         GKI_freebuf (p_buf);
         return;
     }
@@ -184,7 +184,7 @@ static void smp_data_received(UINT16 channel, BD_ADDR bd_addr, BT_HDR *p_buf)
         if (cmd == SMP_OPCODE_CONFIRM)
         {
             SMP_TRACE_DEBUG ("in %s cmd = 0x%02x, peer_auth_req = 0x%02x,"
-                              "loc_auth_req = 0x%02x",
+                              "loc_auth_req = 0x%02x\n",
                               __FUNCTION__, cmd, p_cb->peer_auth_req, p_cb->loc_auth_req);
 
             if ((p_cb->peer_auth_req  & SMP_SC_SUPPORT_BIT) &&

+ 7 - 8
components/bt/bluedroid/stack/smp/smp_main.c

@@ -442,7 +442,7 @@ static const UINT8 smp_slave_entry_map[][SMP_STATE_MAX] =
 {
 /* state name:             Idle WaitApp SecReq Pair   Wait Confirm Rand PublKey SCPhs1  Wait  Wait  SCPhs2  Wait   DHKChk Enc   Bond  CrLocSc
                                  Rsp    Pend   ReqRsp Cfm               Exch    Strt    Cmtm  Nonce Strt    DHKChk        Pend  Pend  OobData   */
-/* PAIR_REQ             */{ 2,    0,     1,      0,     0,   0,    0,   0,      0,      0,    0,    0,      0,     0,     0,    0,     0   },
+/* PAIR_REQ             */{ 2,    1,     1,      0,     0,   0,    0,   0,      0,      0,    0,    0,      0,     0,     0,    0,     0   },
 /* PAIR_RSP             */{ 0,    0,     0,      0,     0,   0,    0,   0,      0,      0,    0,    0,      0,     0,     0,    0,     0   },
 /* CONFIRM              */{ 0,    4,     0,      1,     1,   0,    0,   0,      0,      0,    0,    0,      0,     0,     0,    0,     0   },
 /* RAND                 */{ 0,    0,     0,      0,     0,   1,    2,   0,      0,      0,    1,    0,      0,     0,     0,    0,     0   },
@@ -491,7 +491,7 @@ static const UINT8 smp_slave_idle_table[][SMP_SM_NUM_COLS] =
 /* PAIR_REQ */      {SMP_PROC_PAIR_CMD,   SMP_SEND_APP_CBACK,     SMP_STATE_WAIT_APP_RSP}
 /* CR_LOC_SC_OOB_DATA   */ ,{SMP_CREATE_PRIVATE_KEY, SMP_SM_NO_ACTION, SMP_STATE_CREATE_LOCAL_SEC_CONN_OOB_DATA}
 };
-
+ 
 static const UINT8 smp_slave_wait_for_app_response_table [][SMP_SM_NUM_COLS] =
 {
 /*               Event                   Action                 Next State */
@@ -525,7 +525,6 @@ static const UINT8 smp_slave_pair_request_response_table[][SMP_SM_NUM_COLS] =
 /*                          Event                  Action                 Next State */
 /* CONFIRM  */ {SMP_PROC_CONFIRM,       SMP_SM_NO_ACTION,   SMP_STATE_CONFIRM},
 /* TK_REQ   */ {SMP_SEND_APP_CBACK,     SMP_SM_NO_ACTION,   SMP_STATE_WAIT_APP_RSP},
-
                     /* TK/Confirm ready */
 /* KEY_READY */{SMP_PROC_SL_KEY,        SMP_SM_NO_ACTION,   SMP_STATE_PAIR_REQ_RSP}
 /* PUBL_KEY_EXCH_REQ    */,{ SMP_CREATE_PRIVATE_KEY, SMP_SM_NO_ACTION, SMP_STATE_PUBLIC_KEY_EXCH},
@@ -772,15 +771,15 @@ void smp_sm_event(tSMP_CB *p_cb, tSMP_EVENT event, void *p_data)
     UINT8           action, entry, i;
     tSMP_ENTRY_TBL  entry_table =  smp_entry_table[p_cb->role];
 
-    SMP_TRACE_EVENT("main smp_sm_event");
+    SMP_TRACE_EVENT("main smp_sm_event\n");
     if (curr_state >= SMP_STATE_MAX)
     {
-        SMP_TRACE_DEBUG( "Invalid state: %d", curr_state) ;
+        SMP_TRACE_DEBUG( "Invalid state: %d\n", curr_state) ;
         return;
     }
 
     SMP_TRACE_DEBUG( "SMP Role: %s State: [%s (%d)], Event: [%s (%d)]",\
-                      (p_cb->role == 0x01) ?"Slave" : "Master", smp_get_state_name( p_cb->state),
+                      (p_cb->role == 0x01) ?"Slave" : "Master\n", smp_get_state_name( p_cb->state),
                       p_cb->state, smp_get_event_name(event), event) ;
 
     /* look up the state table for the current state */
@@ -799,7 +798,7 @@ void smp_sm_event(tSMP_CB *p_cb, tSMP_EVENT event, void *p_data)
     }
     else
     {
-        SMP_TRACE_DEBUG( "Ignore event [%s (%d)] in state [%s (%d)]",
+        SMP_TRACE_DEBUG( "Ignore event [%s (%d)] in state [%s (%d)]\n",
                           smp_get_event_name(event), event, smp_get_state_name(curr_state),
                           curr_state);
         return;
@@ -825,7 +824,7 @@ void smp_sm_event(tSMP_CB *p_cb, tSMP_EVENT event, void *p_data)
             break;
         }
     }
-    SMP_TRACE_DEBUG( "result state = %s", smp_get_state_name( p_cb->state ) ) ;
+    SMP_TRACE_DEBUG( "result state = %s\n", smp_get_state_name( p_cb->state ) ) ;
 }
 
 /*******************************************************************************

+ 60 - 60
components/bt/bluedroid/stack/smp/smp_utils.c

@@ -314,7 +314,7 @@ BOOLEAN smp_send_cmd(UINT8 cmd_code, tSMP_CB *p_cb)
     BT_HDR *p_buf;
     BOOLEAN sent = FALSE;
     UINT8 failure = SMP_PAIR_INTERNAL_ERR;
-    SMP_TRACE_EVENT("smp_send_cmd on l2cap cmd_code=0x%x", cmd_code);
+    SMP_TRACE_EVENT("smp_send_cmd on l2cap cmd_code=0x%x\n", cmd_code);
     if ( cmd_code <= (SMP_OPCODE_MAX + 1 /* for SMP_OPCODE_PAIR_COMMITM */) &&
          smp_cmd_build_act[cmd_code] != NULL)
     {
@@ -418,7 +418,7 @@ static BT_HDR * smp_build_confirm_cmd(UINT8 cmd_code, tSMP_CB *p_cb)
     UINT8       *p;
     UNUSED(cmd_code);
 
-    SMP_TRACE_EVENT("smp_build_confirm_cmd");
+    SMP_TRACE_EVENT("smp_build_confirm_cmd\n");
     if ((p_buf = (BT_HDR *)GKI_getbuf(sizeof(BT_HDR) + SMP_CONFIRM_CMD_SIZE + L2CAP_MIN_OFFSET)) != NULL)
     {
         p = (UINT8 *)(p_buf + 1) + L2CAP_MIN_OFFSET;
@@ -445,7 +445,7 @@ static BT_HDR * smp_build_rand_cmd(UINT8 cmd_code, tSMP_CB *p_cb)
     UINT8       *p;
     UNUSED(cmd_code);
 
-    SMP_TRACE_EVENT("%s", __func__);
+    SMP_TRACE_EVENT("%s\n", __func__);
     if ((p_buf = (BT_HDR *)GKI_getbuf(sizeof(BT_HDR) + SMP_RAND_CMD_SIZE + L2CAP_MIN_OFFSET))
          != NULL)
     {
@@ -473,7 +473,7 @@ static BT_HDR * smp_build_encrypt_info_cmd(UINT8 cmd_code, tSMP_CB *p_cb)
     UINT8       *p;
     UNUSED(cmd_code);
 
-    SMP_TRACE_EVENT("smp_build_encrypt_info_cmd");
+    SMP_TRACE_EVENT("smp_build_encrypt_info_cmd\n");
     if ((p_buf = (BT_HDR *)GKI_getbuf(sizeof(BT_HDR) + SMP_ENC_INFO_SIZE + L2CAP_MIN_OFFSET)) != NULL)
     {
         p = (UINT8 *)(p_buf + 1) + L2CAP_MIN_OFFSET;
@@ -501,7 +501,7 @@ static BT_HDR * smp_build_master_id_cmd(UINT8 cmd_code, tSMP_CB *p_cb)
     UINT8       *p;
     UNUSED(cmd_code);
 
-    SMP_TRACE_EVENT("%s", __func__);
+    SMP_TRACE_EVENT("%s\n", __func__);
 
     if ((p_buf = (BT_HDR *)GKI_getbuf(sizeof(BT_HDR) + SMP_MASTER_ID_SIZE + L2CAP_MIN_OFFSET)) != NULL)
     {
@@ -533,7 +533,7 @@ static BT_HDR * smp_build_identity_info_cmd(UINT8 cmd_code, tSMP_CB *p_cb)
     UNUSED(cmd_code);
     UNUSED(p_cb);
 
-    SMP_TRACE_EVENT("smp_build_identity_info_cmd");
+    SMP_TRACE_EVENT("smp_build_identity_info_cmd\n");
     if ((p_buf = (BT_HDR *)GKI_getbuf(sizeof(BT_HDR) + SMP_ID_INFO_SIZE + L2CAP_MIN_OFFSET)) != NULL)
     {
         p = (UINT8 *)(p_buf + 1) + L2CAP_MIN_OFFSET;
@@ -564,7 +564,7 @@ static BT_HDR * smp_build_id_addr_cmd(UINT8 cmd_code, tSMP_CB *p_cb)
 
     UNUSED(cmd_code);
     UNUSED(p_cb);
-    SMP_TRACE_EVENT("smp_build_id_addr_cmd");
+    SMP_TRACE_EVENT("smp_build_id_addr_cmd\n");
     if ((p_buf = (BT_HDR *)GKI_getbuf(sizeof(BT_HDR) + SMP_ID_ADDR_SIZE + L2CAP_MIN_OFFSET)) != NULL)
     {
         p = (UINT8 *)(p_buf + 1) + L2CAP_MIN_OFFSET;
@@ -593,7 +593,7 @@ static BT_HDR * smp_build_signing_info_cmd(UINT8 cmd_code, tSMP_CB *p_cb)
     UINT8       *p;
     UNUSED(cmd_code);
 
-    SMP_TRACE_EVENT("smp_build_signing_info_cmd");
+    SMP_TRACE_EVENT("smp_build_signing_info_cmd\n");
     if ((p_buf = (BT_HDR *)GKI_getbuf(sizeof(BT_HDR) + SMP_SIGN_INFO_SIZE + L2CAP_MIN_OFFSET)) != NULL)
     {
         p = (UINT8 *)(p_buf + 1) + L2CAP_MIN_OFFSET;
@@ -621,7 +621,7 @@ static BT_HDR * smp_build_pairing_fail(UINT8 cmd_code, tSMP_CB *p_cb)
     UINT8       *p;
     UNUSED(cmd_code);
 
-    SMP_TRACE_EVENT("%s", __func__);
+    SMP_TRACE_EVENT("%s\n", __func__);
     if ((p_buf = (BT_HDR *)GKI_getbuf(sizeof(BT_HDR) + SMP_PAIR_FAIL_SIZE + L2CAP_MIN_OFFSET)) != NULL)
     {
         p = (UINT8 *)(p_buf + 1) + L2CAP_MIN_OFFSET;
@@ -649,7 +649,7 @@ static BT_HDR *smp_build_security_request(UINT8 cmd_code, tSMP_CB *p_cb)
     UINT8       *p;
     UNUSED(cmd_code);
 
-    SMP_TRACE_EVENT("%s", __func__);
+    SMP_TRACE_EVENT("%s\n", __func__);
     if ((p_buf = (BT_HDR *)GKI_getbuf(sizeof(BT_HDR) + 2 + L2CAP_MIN_OFFSET)) != NULL)
     {
         p = (UINT8 *)(p_buf + 1) + L2CAP_MIN_OFFSET;
@@ -682,7 +682,7 @@ static BT_HDR *smp_build_pair_public_key_cmd(UINT8 cmd_code, tSMP_CB *p_cb)
     UINT8   *p_publ_key = publ_key;
     UNUSED(cmd_code);
 
-    SMP_TRACE_EVENT("%s", __FUNCTION__);
+    SMP_TRACE_EVENT("%s\n", __FUNCTION__);
 
     memcpy(p_publ_key, p_cb->loc_publ_key.x, BT_OCTET32_LEN);
     memcpy(p_publ_key + BT_OCTET32_LEN, p_cb->loc_publ_key.y, BT_OCTET32_LEN);
@@ -715,7 +715,7 @@ static BT_HDR *smp_build_pairing_commitment_cmd(UINT8 cmd_code, tSMP_CB *p_cb)
     UINT8 *p;
     UNUSED(cmd_code);
 
-    SMP_TRACE_EVENT("%s", __func__);
+    SMP_TRACE_EVENT("%s\n", __func__);
     if ((p_buf = (BT_HDR *)GKI_getbuf(sizeof(BT_HDR) + SMP_PAIR_COMMITM_SIZE + L2CAP_MIN_OFFSET))
         != NULL)
     {
@@ -744,7 +744,7 @@ static BT_HDR *smp_build_pair_dhkey_check_cmd(UINT8 cmd_code, tSMP_CB *p_cb)
     UINT8 *p;
     UNUSED(cmd_code);
 
-    SMP_TRACE_EVENT("%s", __FUNCTION__);
+    SMP_TRACE_EVENT("%s\n", __FUNCTION__);
     if ((p_buf = (BT_HDR *)GKI_getbuf(sizeof(BT_HDR) +
         SMP_PAIR_DHKEY_CHECK_SIZE + L2CAP_MIN_OFFSET)) != NULL)
     {
@@ -773,7 +773,7 @@ static BT_HDR * smp_build_pairing_keypress_notification_cmd(UINT8 cmd_code, tSMP
     UINT8       *p;
     UNUSED(cmd_code);
 
-    SMP_TRACE_EVENT("%s", __FUNCTION__);
+    SMP_TRACE_EVENT("%s\n", __FUNCTION__);
     if ((p_buf = (BT_HDR *)GKI_getbuf(sizeof(BT_HDR)\
         + SMP_PAIR_KEYPR_NOTIF_SIZE + L2CAP_MIN_OFFSET)) != NULL)
     {
@@ -804,7 +804,7 @@ void smp_convert_string_to_tk(BT_OCTET16 tk, UINT32 passkey)
 {
     UINT8   *p = tk;
     tSMP_KEY    key;
-    SMP_TRACE_EVENT("smp_convert_string_to_tk");
+    SMP_TRACE_EVENT("smp_convert_string_to_tk\n");
     UINT32_TO_STREAM(p, passkey);
 
     key.key_type    = SMP_KEY_TYPE_TK;
@@ -826,7 +826,7 @@ void smp_convert_string_to_tk(BT_OCTET16 tk, UINT32 passkey)
 *******************************************************************************/
 void smp_mask_enc_key(UINT8 loc_enc_size, UINT8 * p_data)
 {
-    SMP_TRACE_EVENT("smp_mask_enc_key");
+    SMP_TRACE_EVENT("smp_mask_enc_key\n");
     if (loc_enc_size < BT_OCTET16_LEN)
     {
         for (; loc_enc_size < BT_OCTET16_LEN; loc_enc_size ++)
@@ -849,7 +849,7 @@ void smp_xor_128(BT_OCTET16 a, BT_OCTET16 b)
 {
     UINT8 i, *aa = a, *bb = b;
 
-    SMP_TRACE_EVENT("smp_xor_128");
+    SMP_TRACE_EVENT("smp_xor_128\n");
     for (i = 0; i < BT_OCTET16_LEN; i++)
     {
         aa[i] = aa[i] ^ bb[i];
@@ -870,7 +870,7 @@ void smp_cb_cleanup(tSMP_CB   *p_cb)
     tSMP_CALLBACK   *p_callback = p_cb->p_callback;
     UINT8           trace_level = p_cb->trace_level;
 
-    SMP_TRACE_EVENT("smp_cb_cleanup");
+    SMP_TRACE_EVENT("smp_cb_cleanup\n");
 
     memset(p_cb, 0, sizeof(tSMP_CB));
     p_cb->p_callback = p_callback;
@@ -888,7 +888,7 @@ void smp_cb_cleanup(tSMP_CB   *p_cb)
 *******************************************************************************/
 void smp_remove_fixed_channel(tSMP_CB *p_cb)
 {
-    SMP_TRACE_DEBUG("%s", __func__);
+    SMP_TRACE_DEBUG("%s\n", __func__);
 
     if (p_cb->smp_over_br)
         L2CA_RemoveFixedChnl (L2CAP_SMP_BR_CID, p_cb->pairing_bda);
@@ -909,7 +909,7 @@ void smp_remove_fixed_channel(tSMP_CB *p_cb)
 *******************************************************************************/
 void smp_reset_control_value(tSMP_CB *p_cb)
 {
-    SMP_TRACE_EVENT("smp_reset_control_value");
+    SMP_TRACE_EVENT("smp_reset_control_value\n");
     btu_stop_timer (&p_cb->rsp_timer_ent);
     p_cb->flags = 0;
     /* set the link idle timer to drop the link when pairing is done
@@ -939,7 +939,7 @@ void smp_proc_pairing_cmpl(tSMP_CB *p_cb)
     tSMP_CALLBACK   *p_callback = p_cb->p_callback;
     BD_ADDR         pairing_bda;
 
-    SMP_TRACE_DEBUG ("smp_proc_pairing_cmpl ");
+    SMP_TRACE_DEBUG ("smp_proc_pairing_cmpl \n");
 
     evt_data.cmplt.reason = p_cb->status;
     evt_data.cmplt.smp_over_br = p_cb->smp_over_br;
@@ -953,7 +953,7 @@ void smp_proc_pairing_cmpl(tSMP_CB *p_cb)
         evt_data.cmplt.is_pair_cancel = TRUE;
 
 
-    SMP_TRACE_DEBUG ("send SMP_COMPLT_EVT reason=0x%0x sec_level=0x%0x",
+    SMP_TRACE_DEBUG ("send SMP_COMPLT_EVT reason=0x%0x sec_level=0x%0x\n",
                       evt_data.cmplt.reason,
                       evt_data.cmplt.sec_level );
 
@@ -981,12 +981,12 @@ BOOLEAN smp_command_has_invalid_parameters(tSMP_CB *p_cb)
 {
     UINT8 cmd_code = p_cb->rcvd_cmd_code;
 
-    SMP_TRACE_DEBUG("%s for cmd code 0x%02x", __func__, cmd_code);
+    SMP_TRACE_DEBUG("%s for cmd code 0x%02x\n", __func__, cmd_code);
 
     if ((cmd_code > (SMP_OPCODE_MAX + 1 /* for SMP_OPCODE_PAIR_COMMITM */)) ||
         (cmd_code < SMP_OPCODE_MIN))
     {
-        SMP_TRACE_WARNING("Somehow received command with the RESERVED code 0x%02x", cmd_code);
+        SMP_TRACE_WARNING("Somehow received command with the RESERVED code 0x%02x\n", cmd_code);
         return TRUE;
     }
 
@@ -1014,12 +1014,12 @@ BOOLEAN smp_command_has_valid_fixed_length(tSMP_CB *p_cb)
 {
     UINT8   cmd_code = p_cb->rcvd_cmd_code;
 
-    SMP_TRACE_DEBUG("%s for cmd code 0x%02x", __func__, cmd_code);
+    SMP_TRACE_DEBUG("%s for cmd code 0x%02x\n", __func__, cmd_code);
 
     if (p_cb->rcvd_cmd_len != smp_cmd_size_per_spec[cmd_code])
     {
         SMP_TRACE_WARNING("Rcvd from the peer cmd 0x%02x with invalid length\
-            0x%02x (per spec the length is 0x%02x).",
+            0x%02x (per spec the length is 0x%02x).\n",
             cmd_code, p_cb->rcvd_cmd_len, smp_cmd_size_per_spec[cmd_code]);
         return FALSE;
     }
@@ -1048,12 +1048,12 @@ BOOLEAN smp_pairing_request_response_parameters_are_valid(tSMP_CB *p_cb)
     UINT8   bond_flag = p_cb->peer_auth_req & 0x03; //0x03 is gen bond with appropriate mask
     UINT8   enc_size = p_cb->peer_enc_size;
 
-    SMP_TRACE_DEBUG("%s for cmd code 0x%02x", __func__, p_cb->rcvd_cmd_code);
+    SMP_TRACE_DEBUG("%s for cmd code 0x%02x\n", __func__, p_cb->rcvd_cmd_code);
 
     if (io_caps >= BTM_IO_CAP_MAX)
     {
         SMP_TRACE_WARNING("Rcvd from the peer cmd 0x%02x with IO Capabilty \
-            value (0x%02x) out of range).",
+            value (0x%02x) out of range).\n",
             p_cb->rcvd_cmd_code, io_caps);
         return FALSE;
     }
@@ -1061,7 +1061,7 @@ BOOLEAN smp_pairing_request_response_parameters_are_valid(tSMP_CB *p_cb)
     if (!((oob_flag == SMP_OOB_NONE) || (oob_flag == SMP_OOB_PRESENT)))
     {
         SMP_TRACE_WARNING("Rcvd from the peer cmd 0x%02x with OOB data flag value \
-            (0x%02x) out of range).",
+            (0x%02x) out of range).\n",
              p_cb->rcvd_cmd_code, oob_flag);
         return FALSE;
     }
@@ -1069,7 +1069,7 @@ BOOLEAN smp_pairing_request_response_parameters_are_valid(tSMP_CB *p_cb)
     if (!((bond_flag == SMP_AUTH_NO_BOND) || (bond_flag == SMP_AUTH_BOND)))
     {
         SMP_TRACE_WARNING("Rcvd from the peer cmd 0x%02x with Bonding_Flags value (0x%02x)\
-                           out of range).",
+                           out of range).\n",
                            p_cb->rcvd_cmd_code, bond_flag);
         return FALSE;
     }
@@ -1077,7 +1077,7 @@ BOOLEAN smp_pairing_request_response_parameters_are_valid(tSMP_CB *p_cb)
     if ((enc_size < SMP_ENCR_KEY_SIZE_MIN) || (enc_size > SMP_ENCR_KEY_SIZE_MAX))
     {
         SMP_TRACE_WARNING("Rcvd from the peer cmd 0x%02x with Maximum Encryption \
-            Key value (0x%02x) out of range).",
+            Key value (0x%02x) out of range).\n",
             p_cb->rcvd_cmd_code, enc_size);
         return FALSE;
     }
@@ -1098,12 +1098,12 @@ BOOLEAN smp_pairing_keypress_notification_is_valid(tSMP_CB *p_cb)
 {
     tBTM_SP_KEY_TYPE keypress_notification = p_cb->peer_keypress_notification;
 
-    SMP_TRACE_DEBUG("%s for cmd code 0x%02x", __func__, p_cb->rcvd_cmd_code);
+    SMP_TRACE_DEBUG("%s for cmd code 0x%02x\n", __func__, p_cb->rcvd_cmd_code);
 
     if (keypress_notification >= BTM_SP_KEY_OUT_OF_RANGE)
     {
         SMP_TRACE_WARNING("Rcvd from the peer cmd 0x%02x with Pairing Keypress \
-            Notification value (0x%02x) out of range).",
+            Notification value (0x%02x) out of range).\n",
             p_cb->rcvd_cmd_code, keypress_notification);
         return FALSE;
     }
@@ -1150,7 +1150,7 @@ void smp_reject_unexpected_pairing_command(BD_ADDR bd_addr)
     BT_HDR *p_buf;
     UINT8   *p;
 
-    SMP_TRACE_DEBUG ("%s", __FUNCTION__);
+    SMP_TRACE_DEBUG ("%s\n", __FUNCTION__);
 
     if ((p_buf = (BT_HDR *)GKI_getbuf(sizeof(BT_HDR) +\
         SMP_PAIR_FAIL_SIZE + L2CAP_MIN_OFFSET)) != NULL)
@@ -1188,14 +1188,14 @@ tSMP_ASSO_MODEL smp_select_association_model(tSMP_CB *p_cb)
     tSMP_ASSO_MODEL model = SMP_MODEL_OUT_OF_RANGE;
     p_cb->le_secure_connections_mode_is_used = FALSE;
 
-    SMP_TRACE_EVENT("%s", __FUNCTION__);
-    SMP_TRACE_DEBUG("%s p_cb->peer_io_caps = %d p_cb->local_io_capability = %d",
+    SMP_TRACE_EVENT("%s\n", __FUNCTION__);
+    SMP_TRACE_DEBUG("%s p_cb->peer_io_caps = %d p_cb->local_io_capability = %d\n",
                        __FUNCTION__, p_cb->peer_io_caps, p_cb->local_io_capability);
-    SMP_TRACE_DEBUG("%s p_cb->peer_oob_flag = %d p_cb->loc_oob_flag = %d",
+    SMP_TRACE_DEBUG("%s p_cb->peer_oob_flag = %d p_cb->loc_oob_flag = %d\n",
                        __FUNCTION__, p_cb->peer_oob_flag, p_cb->loc_oob_flag);
-    SMP_TRACE_DEBUG("%s p_cb->peer_auth_req = 0x%02x p_cb->loc_auth_req = 0x%02x",
+    SMP_TRACE_DEBUG("%s p_cb->peer_auth_req = 0x%02x p_cb->loc_auth_req = 0x%02x\n",
                        __FUNCTION__, p_cb->peer_auth_req, p_cb->loc_auth_req);
-    SMP_TRACE_DEBUG("%s p_cb->secure_connections_only_mode_required = %s",
+    SMP_TRACE_DEBUG("%s p_cb->secure_connections_only_mode_required = %s\n",
                        __FUNCTION__, p_cb->secure_connections_only_mode_required ?
                                     "TRUE" : "FALSE");
 
@@ -1204,7 +1204,7 @@ tSMP_ASSO_MODEL smp_select_association_model(tSMP_CB *p_cb)
         p_cb->le_secure_connections_mode_is_used = TRUE;
     }
 
-    SMP_TRACE_DEBUG("use_sc_process = %d", p_cb->le_secure_connections_mode_is_used);
+    SMP_TRACE_DEBUG("use_sc_process = %d\n", p_cb->le_secure_connections_mode_is_used);
 
     if (p_cb->le_secure_connections_mode_is_used)
     {
@@ -1228,7 +1228,7 @@ tSMP_ASSO_MODEL smp_select_legacy_association_model(tSMP_CB *p_cb)
 {
     tSMP_ASSO_MODEL model = SMP_MODEL_OUT_OF_RANGE;
 
-    SMP_TRACE_DEBUG("%s", __func__);
+    SMP_TRACE_DEBUG("%s\n", __func__);
     /* if OOB data is present on both devices, then use OOB association model */
     if (p_cb->peer_oob_flag == SMP_OOB_PRESENT && p_cb->loc_oob_flag == SMP_OOB_PRESENT)
         return SMP_MODEL_OOB;
@@ -1266,7 +1266,7 @@ tSMP_ASSO_MODEL smp_select_association_model_secure_connections(tSMP_CB *p_cb)
 {
     tSMP_ASSO_MODEL model = SMP_MODEL_OUT_OF_RANGE;
 
-    SMP_TRACE_DEBUG("%s", __func__);
+    SMP_TRACE_DEBUG("%s\n", __func__);
     /* if OOB data is present on at least one device, then use OOB association model */
     if (p_cb->peer_oob_flag == SMP_OOB_PRESENT || p_cb->loc_oob_flag == SMP_OOB_PRESENT)
         return SMP_MODEL_SEC_CONN_OOB;
@@ -1303,7 +1303,7 @@ void smp_reverse_array(UINT8 *arr, UINT8 len)
 {
     UINT8 i =0, tmp;
 
-    SMP_TRACE_DEBUG("smp_reverse_array");
+    SMP_TRACE_DEBUG("smp_reverse_array\n");
 
     for (i = 0; i < len/2; i ++)
     {
@@ -1330,9 +1330,9 @@ UINT8 smp_calculate_random_input(UINT8 *random, UINT8 round)
     UINT8 j = round%8;
     UINT8 ri;
 
-    SMP_TRACE_DEBUG("random: 0x%02x, round: %d, i: %d, j: %d", random[i], round, i, j);
+    SMP_TRACE_DEBUG("random: 0x%02x, round: %d, i: %d, j: %d\n", random[i], round, i, j);
     ri = ((random[i] >> j) & 1) | 0x80;
-    SMP_TRACE_DEBUG("%s ri=0x%02x", __func__, ri);
+    SMP_TRACE_DEBUG("%s ri=0x%02x\n", __func__, ri);
     return ri;
 }
 
@@ -1347,7 +1347,7 @@ UINT8 smp_calculate_random_input(UINT8 *random, UINT8 round)
 *******************************************************************************/
 void smp_collect_local_io_capabilities(UINT8 *iocap, tSMP_CB *p_cb)
 {
-    SMP_TRACE_DEBUG("%s", __func__);
+    SMP_TRACE_DEBUG("%s\n", __func__);
 
     iocap[0] = p_cb->local_io_capability;
     iocap[1] = p_cb->loc_oob_flag;
@@ -1365,7 +1365,7 @@ void smp_collect_local_io_capabilities(UINT8 *iocap, tSMP_CB *p_cb)
 *******************************************************************************/
 void smp_collect_peer_io_capabilities(UINT8 *iocap, tSMP_CB *p_cb)
 {
-    SMP_TRACE_DEBUG("%s", __func__);
+    SMP_TRACE_DEBUG("%s\n", __func__);
 
     iocap[0] = p_cb->peer_io_caps;
     iocap[1] = p_cb->peer_oob_flag;
@@ -1388,7 +1388,7 @@ void smp_collect_local_ble_address(UINT8 *le_addr, tSMP_CB *p_cb)
     BD_ADDR         bda;
     UINT8           *p = le_addr;
 
-    SMP_TRACE_DEBUG("%s", __func__);
+    SMP_TRACE_DEBUG("%s\n", __func__);
 
     BTM_ReadConnectionAddr( p_cb->pairing_bda, bda, &addr_type);
     BDADDR_TO_STREAM(p, bda);
@@ -1411,11 +1411,11 @@ void smp_collect_peer_ble_address(UINT8 *le_addr, tSMP_CB *p_cb)
     BD_ADDR         bda;
     UINT8           *p = le_addr;
 
-    SMP_TRACE_DEBUG("%s", __func__);
+    SMP_TRACE_DEBUG("%s\n", __func__);
 
     if (!BTM_ReadRemoteConnectionAddr(p_cb->pairing_bda, bda, &addr_type))
     {
-        SMP_TRACE_ERROR("can not collect peer le addr information for unknown device");
+        SMP_TRACE_ERROR("can not collect peer le addr information for unknown device\n");
         return;
     }
 
@@ -1438,7 +1438,7 @@ BOOLEAN smp_check_commitment(tSMP_CB *p_cb)
 {
     BT_OCTET16 expected;
 
-    SMP_TRACE_DEBUG("%s", __func__);
+    SMP_TRACE_DEBUG("%s\n", __func__);
 
     smp_calculate_peer_commitment(p_cb, expected);
     print128(expected, (const UINT8 *)"calculated peer commitment");
@@ -1446,11 +1446,11 @@ BOOLEAN smp_check_commitment(tSMP_CB *p_cb)
 
     if (memcmp(p_cb->remote_commitment, expected, BT_OCTET16_LEN))
     {
-        SMP_TRACE_WARNING("Commitment check fails");
+        SMP_TRACE_WARNING("Commitment check fails\n");
         return FALSE;
     }
 
-    SMP_TRACE_DEBUG("Commitment check succeeds");
+    SMP_TRACE_DEBUG("Commitment check succeeds\n");
     return TRUE;
 }
 
@@ -1469,14 +1469,14 @@ void smp_save_secure_connections_long_term_key(tSMP_CB *p_cb)
     tBTM_LE_LENC_KEYS   lle_key;
     tBTM_LE_PENC_KEYS   ple_key;
 
-    SMP_TRACE_DEBUG("%s-Save LTK as local LTK key", __func__);
+    SMP_TRACE_DEBUG("%s-Save LTK as local LTK key\n", __func__);
     memcpy(lle_key.ltk, p_cb->ltk, BT_OCTET16_LEN);
     lle_key.div = 0;
     lle_key.key_size = p_cb->loc_enc_size;
     lle_key.sec_level = p_cb->sec_level;
     btm_sec_save_le_key(p_cb->pairing_bda, BTM_LE_KEY_LENC, (tBTM_LE_KEY_VALUE *)&lle_key, TRUE);
 
-    SMP_TRACE_DEBUG("%s-Save LTK as peer LTK key", __func__);
+    SMP_TRACE_DEBUG("%s-Save LTK as peer LTK key\n", __func__);
     ple_key.ediv = 0;
     memset(ple_key.rand, 0, BT_OCTET8_LEN);
     memcpy(ple_key.ltk, p_cb->ltk, BT_OCTET16_LEN);
@@ -1504,7 +1504,7 @@ BOOLEAN smp_calculate_f5_mackey_and_long_term_key(tSMP_CB *p_cb)
     UINT8 *p_na;
     UINT8 *p_nb;
 
-    SMP_TRACE_DEBUG("%s", __func__);
+    SMP_TRACE_DEBUG("%s\n", __func__);
 
     if (p_cb->role == HCI_ROLE_MASTER)
     {
@@ -1523,11 +1523,11 @@ BOOLEAN smp_calculate_f5_mackey_and_long_term_key(tSMP_CB *p_cb)
 
     if(!smp_calculate_f5(p_cb->dhkey, p_na, p_nb, a, b, p_cb->mac_key, p_cb->ltk))
     {
-        SMP_TRACE_ERROR("%s failed", __func__);
+        SMP_TRACE_ERROR("%s failed\n", __func__);
         return FALSE;
     }
 
-    SMP_TRACE_EVENT ("%s is completed", __func__);
+    SMP_TRACE_EVENT ("%s is completed\n", __func__);
     return TRUE;
 }
 
@@ -1545,7 +1545,7 @@ BOOLEAN smp_request_oob_data(tSMP_CB *p_cb)
 {
     tSMP_OOB_DATA_TYPE req_oob_type = SMP_OOB_INVALID_TYPE;
 
-    SMP_TRACE_DEBUG("%s", __func__);
+    SMP_TRACE_DEBUG("%s\n", __func__);
 
     if (p_cb->peer_oob_flag == SMP_OOB_PRESENT && p_cb->loc_oob_flag == SMP_OOB_PRESENT)
     {
@@ -1562,7 +1562,7 @@ BOOLEAN smp_request_oob_data(tSMP_CB *p_cb)
         req_oob_type = SMP_OOB_PEER;
     }
 
-    SMP_TRACE_DEBUG("req_oob_type = %d", req_oob_type);
+    SMP_TRACE_DEBUG("req_oob_type = %d\n", req_oob_type);
 
     if (req_oob_type == SMP_OOB_INVALID_TYPE)
         return FALSE;

+ 134 - 134
components/bt/bt.c

@@ -1,134 +1,134 @@
-// 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
+// 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

+ 3 - 0
components/bt/component.mk

@@ -9,6 +9,7 @@ COMPONENT_ADD_INCLUDEDIRS :=	bluedroid/bta/include			\
 				bluedroid/gki/include			\
 				bluedroid/hci/include			\
 				bluedroid/osi/include			\
+				bluedroid/profiles/core/include			\
 				bluedroid/profiles/esp/include		\
 				bluedroid/profiles/std/avrc/include	\
 				bluedroid/profiles/std/battery/include	\
@@ -48,7 +49,9 @@ COMPONENT_SRCDIRS := 	bluedroid/bta/dm			\
 			bluedroid/hci				\
 			bluedroid/main				\
 			bluedroid/osi				\
+			bluedroid/profiles/core		\
 			bluedroid/profiles/esp/ble_button	\
+			bluedroid/profiles/esp/wechat_AirSync	\
 			bluedroid/profiles/esp			\
 			bluedroid/profiles/std/avrc		\
 			bluedroid/profiles/std/battery		\

+ 43 - 22
examples/06_bluedroid_demos/components/bluedroid_demos/app_core/bt_app_core.c

@@ -14,12 +14,14 @@
 #include "bt_app_common.h"
 
 #include "controller.h"
-
+//#include "prf_defs.h"
 #include "hash_map.h"
 #include "hash_functions.h"
 #include "alarm.h"
-#include "app_button.h"
+//#include "app_button.h"
+#if	(BUT_PROFILE_CFG)
 #include "button_pro.h"
+#endif	///BUT_PROFILE_CFG
 #include "thread.h"
 #include "bt_app_common.h"
 #include "dis_api.h"
@@ -64,12 +66,17 @@ static void bt_app_task_handler(void *arg)
             if (e->sig == 0xff) {
                 fixed_queue_process(bta_app_msg_queue);
                 fixed_queue_process(bt_app_general_alarm_queue);
-            }else if(e->sig == BUTTON_PRESS_EVT){
-                LOG_ERROR("button_press_event come in,button_value=%x\n",e->par);
-                button_msg[1] = e->par;
-                button_msg_notify(2,button_msg);		
             }
-            osi_free(e);
+#if (BUT_PROFILE_CFG)
+			else if(e->sig == BUTTON_PRESS_EVT){
+			LOG_ERROR("button_press_event come in,button_value=%x\n",e->par);
+		  button_msg[1] = e->par;
+          button_msg_notify(2,button_msg);	
+
+
+	}
+#endif	///BUT_PROFILE_CFG
+
         }
     }
 }
@@ -187,7 +194,7 @@ void bt_app_task_start_up(void)
     return;
 
 error_exit:
-    LOG_ERROR("%s Unable to allocate resources for bt_app", __func__);
+    LOG_ERROR("%s Unable to allocate resources for bt_app\n", __func__);
     bt_app_task_shut_down();
 }
 
@@ -243,13 +250,13 @@ static void bt_app_dm_upstreams_evt(UINT16 event, char *p_param)
 
 
         /*set connectable,discoverable, pairable and paired only modes of local device*/
-        tBTA_DM_DISC disc_mode = BTA_DM_GENERAL_DISC | BTA_DM_BLE_GENERAL_DISCOVERABLE;
-        tBTA_DM_CONN conn_mode = BTA_DM_CONN | BTA_DM_BLE_CONNECTABLE;
-        BTA_DmSetVisibility(disc_mode, conn_mode, BTA_DM_IGNORE, BTA_DM_IGNORE);
+        tBTA_DM_DISC disc_mode =  BTA_DM_BLE_GENERAL_DISCOVERABLE;
+        tBTA_DM_CONN conn_mode =  BTA_DM_BLE_CONNECTABLE;
+        BTA_DmSetVisibility(disc_mode, conn_mode, (UINT8)BTA_DM_NON_PAIRABLE, (UINT8)BTA_DM_CONN_ALL);
 
 #if (defined(BLE_INCLUDED) && (BLE_INCLUDED == TRUE))
         /* Enable local privacy */
-        BTA_DmBleConfigLocalPrivacy(BLE_LOCAL_PRIVACY_ENABLED);
+        //BTA_DmBleConfigLocalPrivacy(BLE_LOCAL_PRIVACY_ENABLED);
         do {
             const controller_t *controller = controller_get_interface();
             char bdstr[18];
@@ -261,17 +268,27 @@ static void bt_app_dm_upstreams_evt(UINT16 event, char *p_param)
 	break;
 	case BTA_DM_BLE_SEC_REQ_EVT:
 		
-		smp_cmd.local_io_capability = 0x03;		//no input no output
-		smp_cmd.loc_oob_flag = 0x00;		//oob data not present
-		smp_cmd.loc_auth_req = 0x05;
-		smp_cmd.loc_enc_size = 0x10;
-		smp_cmd.local_i_key = 0x07;
-		smp_cmd.local_r_key = 0x07;
-		memcpy(smp_cmd.pairing_bda,p_data->ble_req.bd_addr,0x06);
-		smp_send_cmd(SMP_OPCODE_PAIRING_RSP,&smp_cmd);
-		smp_set_state(SMP_STATE_WAIT_CONFIRM);
+		smp_cb.local_io_capability = 0x03;		//no input no output
+		smp_cb.loc_oob_flag = 0x00;		//oob data not present
+		smp_cb.loc_auth_req = 0x01;
+		smp_cb.loc_enc_size = 0x10;
+		smp_cb.local_i_key = 0x01;
+		smp_cb.local_r_key = 0x01;		//1101
+		
+		//memcpy(smp_cb.pairing_bda,p_data->ble_req.bd_addr,0x06);
+
+		smp_sm_event(&smp_cb,SMP_PAIRING_REQ_EVT,NULL);
+		//smp_send_cmd(SMP_OPCODE_PAIRING_RSP,&smp_cb);
+		//smp_generate_srand_mrand_confirm(&smp_cb,NULL);
+		//smp_set_state(SMP_STATE_PAIR_REQ_RSP,SMP_BR_PAIRING_REQ_EVT);
 		//BTA_DmConfirm(p_data->ble_req.bd_addr,true);
 			break;
+	case BTA_DM_BLE_KEY_EVT:
+		if(p_data->ble_key.key_type == BTM_LE_KEY_PENC)
+		{
+			smp_set_state(SMP_STATE_IDLE);
+		}
+		break;
 	default:
 		break;
     }
@@ -320,7 +337,7 @@ void bt_app_start_timer(TIMER_LIST_ENT *p_tle, UINT16 type, UINT32 timeout_sec)
     alarm = hash_map_get(bt_app_general_alarm_hash_map, p_tle);
     pthread_mutex_unlock(&bt_app_general_alarm_lock);
     if (alarm == NULL) {
-        LOG_ERROR("%s Unable to create alarm", __func__);
+        LOG_ERROR("%s Unable to create alarm\n", __func__);
 
         return;
     }
@@ -364,6 +381,10 @@ static void bt_app_general_alarm_process(TIMER_LIST_ENT *p_tle)
  
 
   //     bt_test_start_inquiry();
+ 	 /*set connectable,discoverable, pairable and paired only modes of local device*/
+      //  tBTA_DM_DISC disc_mode = BTA_DM_BLE_GENERAL_DISCOVERABLE;
+     //  	tBTA_DM_CONN conn_mode = BTA_DM_BLE_CONNECTABLE;
+      //  BTA_DmSetVisibility(disc_mode, conn_mode, (UINT8)BTA_DM_NON_PAIRABLE, (UINT8)BTA_DM_CONN_ALL);
 
        gatts_server_test();
        //gattc_client_test();

+ 108 - 0
examples/06_bluedroid_demos/components/bluedroid_demos/app_core/bt_app_sec.c

@@ -0,0 +1,108 @@
+/**
+ ****************************************************************************************
+ *
+ * @file bt_app_sec.c
+ *
+ * @brief Application entry point
+ *
+ * Copyright (C) Espressif 2016
+ * Created by Yulong at 2016/10/13
+ *
+ *
+ ****************************************************************************************
+ */
+
+#include "bt_app_sec.h"
+#include <stdlib.h>        // standard library
+#include <string.h>
+
+
+
+extern void srand (unsigned int seed);
+extern int random (void);
+
+/// Application Security Environment Structure
+tAPP_SEC_ENV app_sec_env;
+
+
+/*******************************************************************************
+**
+** Function         app_ble_sec_gen_tk
+**
+** Description      This function is called to generate the ble tk 
+**
+** Returns          the generate tk value
+**
+*******************************************************************************/
+UINT32 app_ble_sec_gen_tk(void)
+{
+    // Generate a PIN Code (Between 100000 and 999999)
+    return (100000 + (random()%900000));
+}
+
+/*******************************************************************************
+**
+** Function         app_ble_sec_gen_ltk
+**
+** Description      This function is called to generate the ble ltk 
+**
+** Returns          NULL
+**
+*******************************************************************************/
+void app_ble_sec_gen_ltk(UINT8 key_size)
+{
+    // Counter
+    UINT8 i;
+    app_sec_env.key_size = key_size;
+
+    // Randomly generate the LTK and the Random Number
+    for (i = 0; i < RAND_NB_LEN; i++)
+    {
+        app_sec_env.rand_nb.nb[i] = random()%256;
+    }
+
+    // Randomly generate the end of the LTK
+    for (i = 0; i < SEC_KEY_LEN; i++)
+    {
+        app_sec_env.ltk.key[i] = (((key_size) < (16 - i)) ? 0 : random()%256);
+    }
+
+    // Randomly generate the EDIV
+    app_sec_env.ediv = random()%65536;
+}
+
+
+/*******************************************************************************
+**
+** Function         app_ble_sec_init
+**
+** Description      This function is init the security env and function
+**
+** Returns          NULL
+**
+*******************************************************************************/
+void app_ble_sec_init()
+{
+    // Reset Security Environment
+    memset(&app_sec_env, 0, sizeof(app_sec_env));
+}
+
+
+/*******************************************************************************
+**
+** Function         app_ble_security_start
+**
+** Description      This function is called by the slave when the seurity start 
+**
+** Returns          NULL
+**
+*******************************************************************************/
+void app_ble_security_start(void)
+{
+    
+}
+
+
+
+
+

+ 130 - 0
examples/06_bluedroid_demos/components/bluedroid_demos/app_profiles/app_WX_airsync/app_airsync_md5.c

@@ -0,0 +1,130 @@
+/**
+ ****************************************************************************************
+ *
+ * @file app_airsync_md5.h
+ *
+ * @brief Application airsync md5 generation Entry Point
+ *
+ * Copyright (C) ESPRESSIF 2016
+ * Created by Yulong at 2016/10/9
+ *
+ ****************************************************************************************
+ */
+
+#include "prf_defs.h"
+#if (WX_AIRSYNC_CFG)
+
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <math.h>
+#include "gki.h"
+#include "app_airsync_md5.h"
+
+const uint32_t X[4][2] = {{0, 1}, {1, 5}, {5, 3}, {0, 7}};
+const uint32_t S[4][4] = {{ 7, 12, 17, 22 },{ 5, 9 , 14, 20 },{ 4, 11, 16, 23 },{ 6, 10, 15, 21 }};
+uint32_t F( uint32_t X, uint32_t Y, uint32_t Z )
+{
+	return ( X & Y ) | ( ~X & Z );
+}
+uint32_t G( uint32_t X, uint32_t Y, uint32_t Z )
+ {
+	return ( X & Z ) | ( Y & ~Z );
+ }
+uint32_t H( uint32_t X, uint32_t Y, uint32_t Z )
+{
+	return X ^ Y ^ Z;
+}
+uint32_t I( uint32_t X, uint32_t Y, uint32_t Z )
+{
+	return Y ^ ( X | ~Z );
+}
+  // rotates x left s bits.
+uint32_t rotate_left( uint32_t x, uint32_t s )
+{
+	return ( x << s ) | ( x >> ( 32 - s ) );
+}
+
+ // Pre-processin
+uint32_t count_padding_bits ( uint32_t length )
+{
+//	uint32_t div = length * BITS / BLOCK_SIZE;
+	uint32_t mod = length * BITS % BLOCK_SIZE;
+	uint32_t c_bits;
+	if ( mod == 0 )
+	{
+			c_bits = MOD_SIZE;
+	}
+	else
+	{
+		c_bits = ( MOD_SIZE + BLOCK_SIZE - mod ) % BLOCK_SIZE;
+	}
+	return c_bits / BITS;
+}
+
+MD5String append_padding_bits ( char * argv )
+{
+	uint32_t msg_length = strlen ( argv );
+	uint32_t bit_length = count_padding_bits ( msg_length );
+	uint64_t app_length = msg_length * BITS;
+	MD5String string;
+	string.str = (char *)GKI_getbuf(msg_length + bit_length + APP_SIZE / BITS);
+	strncpy ( string.str, argv, msg_length );
+	memset ( string.str + msg_length, 0, bit_length );
+	string.str [ msg_length ] = SINGLE_ONE_BIT;
+	memmove ( string.str + msg_length + bit_length, (char *)&app_length, sizeof( uint64_t ) );
+	string.len = msg_length + bit_length + sizeof( uint64_t );
+	return string;
+}
+
+int32_t wechat_md5 (char *argv, uint8_t *md5_32)
+{
+	MD5String string;
+	uint32_t w[16];
+	uint32_t chain[4];
+	uint32_t state[4];
+
+	uint32_t ( *auxi[ 4 ])( uint32_t, uint32_t, uint32_t ) = { F, G, H, I };
+	int sIdx;
+	int wIdx;
+	string = append_padding_bits ( argv );
+	chain[0] = A;
+	chain[1] = B;
+	chain[2] = C;
+	chain[3] = D;
+	for (uint32_t j = 0; j < string.len; j += BLOCK_SIZE / BITS)
+	{
+		memmove ( (char *)w, string.str + j, BLOCK_SIZE / BITS );
+		memmove ( state, chain, sizeof(chain) );
+		for ( uint8_t roundIdx = 0; roundIdx < 4; roundIdx++ )
+		{
+			wIdx = X[ roundIdx ][ 0 ];
+			sIdx = 0;
+			for (uint8_t i = 0; i < 16; i++ )
+			{	
+				state[sIdx] = state [(sIdx + 1)%4] + rotate_left( state[sIdx] +(*auxi[ roundIdx])( state[(sIdx+1) % 4],
+				state[(sIdx+2) % 4], 
+				state[(sIdx+3) % 4]) + w[ wIdx ] + (uint32_t)floor((1ULL << 32) * fabs(sin( roundIdx * 16 + i + 1 )) ),
+				S[ roundIdx ][ i % 4 ]);
+				sIdx = ( sIdx + 3 ) % 4;
+				wIdx = ( wIdx + X[ roundIdx ][ 1 ] ) & 0xF;
+			}
+		}
+		chain[ 0 ] += state[ 0 ];
+		chain[ 1 ] += state[ 1 ];
+		chain[ 2 ] += state[ 2 ];
+		chain[ 3 ] += state[ 3 ];
+	}
+	memmove ( md5_32 + 0, (char *)&chain[0], sizeof(uint32_t) );
+	memmove ( md5_32 + 4, (char *)&chain[1], sizeof(uint32_t) );
+	memmove ( md5_32 + 8, (char *)&chain[2], sizeof(uint32_t) );
+	memmove ( md5_32 + 12, (char *)&chain[3], sizeof(uint32_t) );
+	free(string.str);
+	string.str = NULL;
+  return EXIT_SUCCESS;
+
+}
+
+
+#endif	///WX_AIRSYNC_CFG
+

+ 160 - 0
examples/06_bluedroid_demos/components/bluedroid_demos/app_profiles/app_WX_airsync/app_airsync_prf.c

@@ -0,0 +1,160 @@
+/**
+ ****************************************************************************************
+ *
+ * @file app_airsync_prf.c
+ *
+ * @brief Application Security Entry Point
+ *
+ * Copyright (C) ESPRESSIF 2016
+ * Created by Yulong at 2016/9/30
+ *
+ ****************************************************************************************
+ */
+
+#include "prf_defs.h"
+#if (WX_AIRSYNC_CFG)
+
+#include "app_airsync_prf.h"
+#include "wx_airsync_prf.h"
+#include "app_wechat_util.h"
+#include "gki.h"
+#include "mpbledemo2.h"
+
+/*****************************************************************************
+* data handle
+*****************************************************************************/
+data_info g_send_data;
+
+static data_info g_rcv_data;
+data_handler *pDataHandler;
+
+
+static void airsync_process_msgreceive_cb(UINT8 app_id,
+											UINT8 conn_id,uint8_t *pData, uint16_t length);
+
+///function for register all products
+static void register_all_products(void)
+{
+	REGISTER(mpbledemo2);
+	// could register more products if defined
+}
+
+void app_wechat_init(void)
+{
+	register_all_products();
+
+	data_handler_init(&m_mpbledemo2_handler,PRODUCT_TYPE_MPBLEDEMO2);
+	m_mpbledemo2_handler->m_data_init_func();
+	m_mpbledemo2_handler->m_data_init_peripheral_func();
+
+	app_wechat_SetDatahandler(m_mpbledemo2_handler);
+}
+
+int ble_wechat_indicate_data_chunk(void)
+{
+	uint16_t chunk_len = 0;
+	chunk_len = g_send_data.len - g_send_data.offset;
+	chunk_len = chunk_len > BLE_WECHAT_MAX_DATA_LEN?BLE_WECHAT_MAX_DATA_LEN:chunk_len;
+
+	if(chunk_len == 0)
+	{
+		app_wechat_datahandler()->m_data_free_func(g_send_data.data,g_send_data.len);
+		g_send_data.data = NULL;
+		g_send_data.len = 0;
+		g_send_data.offset = 0;
+		return 0;
+	}
+
+	g_send_data.offset += chunk_len;
+	return 1;
+}
+
+
+ /*******************************************************************************
+**
+** Function         airsync_msgreceive_cb
+**
+** Description      the callback function after the airsync profile have been 
+**					receive the data from the peer device
+** parms			appid:the appid have been register to the gatt database
+**					conn_id:the current connection index
+**					msg_val:the airsync value receive from peer device
+** Returns          NULL 
+**
+*******************************************************************************/
+static void airsync_process_msgreceive_cb(UINT8 app_id,
+											UINT8 conn_id,uint8_t *pData, uint16_t length)
+{
+	int error_code;
+	int chunk_size = 0;
+	if(length <= BLE_WECHAT_MAX_DATA_LEN)
+	{
+		if(g_rcv_data.len == 0)
+		{
+			BpFixHead *fix_head = (BpFixHead *)pData;
+			g_rcv_data.len = ntohs(fix_head->nLength);
+			g_rcv_data.offset = 0;
+			g_rcv_data.data = (uint8_t *)GKI_getbuf(g_rcv_data.len);
+		}
+
+		chunk_size = g_rcv_data.len - g_rcv_data.offset;
+		chunk_size = chunk_size < length ? chunk_size : length;
+		memcpy(g_rcv_data.data + g_rcv_data.offset, pData, chunk_size);
+		g_rcv_data.offset += chunk_size;
+
+		if (g_rcv_data.len <= g_rcv_data.offset) 
+		{
+			error_code = app_wechat_datahandler()->m_data_consume_func(g_rcv_data.data, g_rcv_data.len);
+			app_wechat_datahandler()->m_data_free_func(g_rcv_data.data,g_rcv_data.len);
+			wechat_error_chack(app_wechat_datahandler(), error_code);
+			g_rcv_data.len = 0;
+			g_rcv_data.offset = 0;	
+
+            app_wechat_datahandler()->m_data_main_process_func();
+		}	
+
+		
+	}
+	
+	
+}
+
+ void app_wechat_SetDatahandler(data_handler* pHandler)
+{
+    pDataHandler = pHandler;
+}
+
+bool ble_wechat_is_last_data_sent_out(void)
+{
+	return (g_send_data.len == 0 && g_send_data.offset == 0 ) || \
+		(g_send_data.len != 0 && g_send_data.len == g_send_data.offset);
+}
+
+//device sent data on the indicate characteristic
+int ble_wechat_indicate_data(uint8_t *data, int len)
+{
+	if(data == NULL || len == 0)
+	{
+		return 0;
+	}
+
+	if(!ble_wechat_is_last_data_sent_out())
+	{
+		return 0;
+	}
+
+	g_send_data.data = data;
+	g_send_data.len = len;
+	g_send_data.offset = 0;
+
+	return (ble_wechat_indicate_data_chunk());
+}
+
+data_handler *app_wechat_datahandler(void)
+{
+	return pDataHandler;
+}
+
+
+#endif	///WX_AIRSYNC_CFG
+

+ 414 - 0
examples/06_bluedroid_demos/components/bluedroid_demos/app_profiles/app_WX_airsync/epb.c

@@ -0,0 +1,414 @@
+//  epb.c
+//  WeChat Embedded Proto Buffer
+//
+//  Created by harlliu@tencent.com on 14-02-15.
+//  Copyright 2014 Tencent. All rights reserved.
+//
+
+//  Version : 1.0.2
+
+#include "prf_defs.h"
+#if (WX_AIRSYNC_CFG)
+
+
+#include <string.h>
+#include "epb.h"
+
+
+#define __LITTLE_ENDIAN__		1 //Need Test
+
+typedef enum {
+    WIRETYPE_VARINT = 0,
+    WIRETYPE_FIXED64 = 1,
+    WIRETYPE_LENGTH_DELIMITED = 2,
+    WIRETYPE_FIXED32 = 5
+} WireType;
+
+#define CONTINUOUS_MASK 		0x80
+#define WIRETYPE_MASK			0x07
+
+static int epb_get_varint32_bits(const uint8_t *data, int len, uint32_t *value);
+
+inline static int sizeof_tag(uint16_t tag)
+{
+    return ((tag&0xff00) == 0) ? 1 : 2; //TODO:Tag more then two bytes
+}
+
+static uint16_t epb_get_wire_type(uint16_t tag) {
+    uint16_t wire_type = tag & WIRETYPE_MASK;
+    if ((tag>>8) != 0)
+        wire_type = (tag>>8) & WIRETYPE_MASK;
+
+    return wire_type;
+}
+
+static int epb_get_value_length(const uint8_t *data, int len, uint32_t wire_type)
+{
+    int offset = 0;
+    switch(wire_type) {
+    case WIRETYPE_VARINT:
+        while ((data[offset++]&CONTINUOUS_MASK)!=0 && offset<len);
+        break;
+    case WIRETYPE_FIXED64:
+        offset += 8;
+        break;
+    case WIRETYPE_LENGTH_DELIMITED:
+    {
+        int32_t l = 0;
+        offset += epb_get_varint32_bits(data+offset, len-offset, (uint32_t *)&l);
+        offset += l;
+    }
+        break;
+    case WIRETYPE_FIXED32:
+        offset += 4;
+        break;
+    default:
+        return -1;
+    }
+    return offset;
+}
+
+static int epb_get_tag_value_offset(const uint8_t *data, int len, uint16_t tag)
+{
+    int offset = 0;
+    uint32_t p_tag;
+    while (offset < len) {
+        p_tag = data[offset++];
+        while ((data[offset-1]&CONTINUOUS_MASK)!=0 && offset<len) {
+            p_tag = (p_tag<<8)|(data[offset++]&0x7f); //TODO:Tag more then two bytes
+        }
+        if (p_tag == tag)
+            return offset;
+
+        uint32_t wire_type = epb_get_wire_type(p_tag);
+        int ret = epb_get_value_length(data+offset, len-offset, wire_type);
+        if (ret < 0) {
+            offset++;
+            continue;
+        }
+
+        offset += ret;
+    }
+    return -1;
+}
+
+static int epb_get_varint32_bits(const uint8_t *data, int len, uint32_t *value)
+{
+    int offset = 0;
+    uint32_t p_value = data[offset++] & 0x7F;
+    while ((data[offset-1]&CONTINUOUS_MASK) != 0) {
+        if (offset >= len)
+            return -1;
+
+        if (offset >= 5)
+            break;
+
+        p_value |= ((uint32_t)data[offset]&0x7F) << (offset*7);
+        ++offset;
+    }
+    *value = p_value;
+    return offset;
+}
+
+static uint32_t epb_get_fixed32_bits(const uint8_t *data, int len)
+{
+    if(len < 4)
+        return 0;
+
+    uint32_t value = 0;
+#ifdef __LITTLE_ENDIAN__
+    memcpy(&value, data, sizeof(uint32_t));
+#else 
+    value = (data[3]<<24)|(data[2]<<16)|(data[1]<<8)|data[0];
+#endif
+    return value;
+}
+
+void epb_unpack_init(Epb *e, const uint8_t *buf, int len)
+{
+    e->unpack_buf = buf;
+    e->buf_len = len;
+}
+
+bool epb_has_tag(Epb *e, uint16_t tag)
+{
+    int offset = epb_get_tag_value_offset(e->unpack_buf, e->buf_len, tag);
+    if (offset < 0)
+        return false;
+    else
+        return true;
+}
+
+uint32_t epb_get_uint32(Epb *e, uint16_t tag)
+{
+    int offset = epb_get_tag_value_offset(e->unpack_buf, e->buf_len, tag);
+    if (offset < 0)
+        return 0;
+
+    uint32_t value = 0;
+    epb_get_varint32_bits(e->unpack_buf+offset, e->buf_len-offset, &value);
+    return value;
+}
+
+int32_t epb_get_int32(Epb *e, uint16_t tag)
+{
+    return epb_get_uint32(e, tag);
+}
+
+int32_t epb_get_sint32(Epb *e, uint16_t tag)
+{
+    uint32_t value = epb_get_uint32(e, tag);
+    if (value&1)
+        return -(value>>1) - 1;
+    else
+        return value>>1;
+}
+
+bool epb_get_bool(Epb *e, uint16_t tag)
+{
+    return epb_get_uint32(e, tag);
+}
+
+int epb_get_enum(Epb *e, uint16_t tag)
+{
+    return epb_get_uint32(e, tag);
+}
+
+const uint8_t *epb_get_bytes(Epb *e, uint16_t tag, int *len)
+{
+    int offset = epb_get_tag_value_offset(e->unpack_buf, e->buf_len, tag);
+    if (offset < 0)
+        return NULL;
+
+    uint32_t l;
+    offset += epb_get_varint32_bits(e->unpack_buf+offset, e->buf_len-offset, &l);
+    *len = (int)l;
+
+    return e->unpack_buf+offset;
+}
+
+const char *epb_get_string(Epb *e, uint16_t tag, int *len)
+{
+    return (char *)epb_get_bytes(e, tag, len);
+}
+
+const Message *epb_get_message(Epb *e, uint16_t tag, int *len)
+{
+    return (Message *)epb_get_bytes(e, tag, len);
+}
+
+uint32_t epb_get_fixed32(Epb *e, uint16_t tag)
+{
+    int offset = epb_get_tag_value_offset(e->unpack_buf, e->buf_len, tag);
+    if (offset < 0)
+        return 0;
+
+    return epb_get_fixed32_bits(e->unpack_buf+offset, e->buf_len-offset);
+}
+
+int32_t epb_get_sfixed32(Epb *e, uint16_t tag)
+{
+    return epb_get_fixed32(e, tag);
+}
+
+float epb_get_float(Epb *e, uint16_t tag)
+{
+    uint32_t bits = epb_get_fixed32(e, tag);
+    return *(float *)&bits;
+}
+
+/*
+    epb pack functions
+*/
+
+inline static int epb_pack_buf_remain(Epb *e)
+{
+    return e->buf_len - e->buf_offset;
+}
+
+static int epb_pack_tag(Epb *e, uint16_t tag)
+{
+    int tag_len = sizeof_tag(tag);
+    if (epb_pack_buf_remain(e) >= tag_len) {
+        uint8_t *buf = e->pack_buf + e->buf_offset;
+        if (tag_len == 2) //TODO
+            *(buf++) = 0xff&(tag>>8);
+        *buf = 0xff&tag;
+        e->buf_offset += tag_len;
+        return tag_len;
+    }
+    return -1;
+}
+
+static int epb_pack_varint32_bits(Epb *e, uint32_t value)
+{
+    uint8_t buf[5] = {0};
+    int i = 0;
+    do {
+        buf[i] = value&0x7f;
+        if (i-1 >= 0)
+            buf[i-1] |= 0x80;
+        value = value >> 7;
+        ++i;
+    } while (value!=0 && i<5);
+    if (epb_pack_buf_remain(e) >= i) {
+        memcpy(e->pack_buf+e->buf_offset, buf, i);
+        e->buf_offset += i;
+        return i;
+    }
+    return -1;
+}
+
+void epb_pack_init(Epb *e, uint8_t *buf, int len)
+{
+    e->pack_buf = buf;
+    e->buf_len = len;
+    e->buf_offset = 0;
+}
+
+int epb_get_packed_size(Epb *e)
+{
+    return e->buf_offset;
+}
+
+int epb_set_uint32(Epb *e, uint16_t tag, uint32_t value)
+{
+    int len = 0;
+    int ret = epb_pack_tag(e, tag);
+    if (ret < 0) return ret;
+    len += ret;
+
+    ret = epb_pack_varint32_bits(e, value);
+    if (ret < 0) return ret;
+    len += ret;
+
+    return len;
+}
+
+int epb_set_int32(Epb *e, uint16_t tag, int32_t value)
+{
+    return epb_set_uint32(e, tag, value);
+}
+
+int epb_set_sint32(Epb *e, uint16_t tag, int32_t value)
+{
+    uint32_t v = (value << 1) ^ (value >> 31);
+    return epb_set_uint32(e, tag, v);
+}
+
+int epb_set_bool(Epb *e, uint16_t tag, bool value)
+{
+    return epb_set_uint32(e, tag, value);
+}
+
+int epb_set_enum(Epb *e, uint16_t tag, int value)
+{
+    return epb_set_uint32(e, tag, value);
+}
+
+static int epb_set_fixed32_bits(Epb *e, uint32_t value)
+{
+    if (epb_pack_buf_remain(e) >= 4) {
+#ifdef __LITTLE_ENDIAN__
+        memcpy(e->pack_buf+e->buf_offset, &value, 4);
+#else
+        uint8_t *data = (uint8_t *)&value;
+        for (int i=0; i<4; i++) {
+            *(e->pack_buf+e->buf_offset+i) = data[4-i];
+        }
+#endif
+        e->buf_offset += 4;
+        return 4;
+    }
+    return -1;
+}
+
+static int epb_pack_length_delimited(Epb *e, const uint8_t *data, int len)
+{
+    if (epb_pack_buf_remain(e) >= len) {
+        memcpy(e->pack_buf + e->buf_offset, data, len);
+        e->buf_offset += len;
+        return len;
+    }
+    return -1;
+}
+
+int epb_set_bytes(Epb *e, uint16_t tag, const uint8_t *data, int length)
+{
+    int len = 0;
+    int ret = epb_pack_tag(e, tag);
+    if (ret < 0) return ret;
+    len += ret;
+
+    ret = epb_pack_varint32_bits(e, length);
+    if (ret < 0) return ret;
+    len += ret;
+
+    ret = epb_pack_length_delimited(e, data, length);
+    if (ret < 0) return ret;
+    len += ret;
+
+    return len;
+}
+
+int epb_set_string(Epb *e, uint16_t tag, const char *data, int len)
+{
+    return epb_set_bytes(e, tag, (const uint8_t *)data, len);
+}
+
+int epb_set_message(Epb *e, uint16_t tag, const Message *data, int len)
+{
+    return epb_set_bytes(e, tag, data, len);
+}
+
+int epb_set_fixed32(Epb *e, uint16_t tag, uint32_t value)
+{
+    int len = 0;
+    int ret = epb_pack_tag(e, tag);
+    if (ret < 0) return ret;
+    len += ret;
+
+    ret = epb_set_fixed32_bits(e, value);
+    if (ret < 0) return ret;
+    len += ret;
+
+    return len;
+}
+
+int epb_set_sfixed32(Epb *e, uint16_t tag, int32_t value)
+{
+    return epb_set_fixed32(e, tag, value);
+}
+
+int epb_set_float(Epb *e, uint16_t tag, float value)
+{
+    uint32_t v = *(uint32_t *)&value;
+    return epb_set_fixed32(e, tag, v);
+}
+
+int epb_varint32_pack_size(uint16_t tag, uint32_t value, bool is_signed)
+{
+    if (is_signed)
+        value = (value << 1) ^ (value >> 31);
+
+    int i = 0;
+    do {
+        value = value >> 7;
+        ++i;
+    } while (value!=0 && i<5);
+
+    return sizeof_tag(tag) + i;
+}
+
+int epb_fixed32_pack_size(uint16_t tag)
+{
+    return sizeof_tag(tag) + 4;
+}
+
+int epb_length_delimited_pack_size(uint16_t tag, int len)
+{
+    return epb_varint32_pack_size(tag, len, false) + len;
+}
+
+
+#endif	///WX_AIRSYNC_CFG

+ 565 - 0
examples/06_bluedroid_demos/components/bluedroid_demos/app_profiles/app_WX_airsync/epb_mmbp.c

@@ -0,0 +1,565 @@
+//  epb_MmBp.c
+//  WeChat Embedded Proto Buffer
+//
+//  Generated by harlliu@tencent.com on 14-11-26.
+//  Copyright 2014 Tencent. All rights reserved.
+//
+
+//  Version : 1.0.4
+
+#include "prf_defs.h"
+#if (WX_AIRSYNC_CFG)
+
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include "epb_MmBp.h"
+#include "gki.h"
+
+#define TAG_BaseResponse_ErrCode												0x08
+#define TAG_BaseResponse_ErrMsg													0x12
+
+#define TAG_AuthRequest_BaseRequest												0x0a
+#define TAG_AuthRequest_Md5DeviceTypeAndDeviceId								0x12
+#define TAG_AuthRequest_ProtoVersion											0x18
+#define TAG_AuthRequest_AuthProto												0x20
+#define TAG_AuthRequest_AuthMethod												0x28
+#define TAG_AuthRequest_AesSign													0x32
+#define TAG_AuthRequest_MacAddress												0x3a
+#define TAG_AuthRequest_TimeZone												0x52
+#define TAG_AuthRequest_Language												0x5a
+#define TAG_AuthRequest_DeviceName												0x62
+
+#define TAG_AuthResponse_BaseResponse											0x0a
+#define TAG_AuthResponse_AesSessionKey											0x12
+
+#define TAG_InitRequest_BaseRequest												0x0a
+#define TAG_InitRequest_RespFieldFilter											0x12
+#define TAG_InitRequest_Challenge												0x1a
+
+#define TAG_InitResponse_BaseResponse											0x0a
+#define TAG_InitResponse_UserIdHigh												0x10
+#define TAG_InitResponse_UserIdLow												0x18
+#define TAG_InitResponse_ChalleangeAnswer										0x20
+#define TAG_InitResponse_InitScence												0x28
+#define TAG_InitResponse_AutoSyncMaxDurationSecond								0x30
+#define TAG_InitResponse_UserNickName											0x5a
+#define TAG_InitResponse_PlatformType											0x60
+#define TAG_InitResponse_Model													0x6a
+#define TAG_InitResponse_Os														0x72
+#define TAG_InitResponse_Time													0x78
+#define TAG_InitResponse_TimeZone												0x8001
+#define TAG_InitResponse_TimeString												0x8a01
+
+#define TAG_SendDataRequest_BaseRequest											0x0a
+#define TAG_SendDataRequest_Data												0x12
+#define TAG_SendDataRequest_Type												0x18
+
+#define TAG_SendDataResponse_BaseResponse										0x0a
+#define TAG_SendDataResponse_Data												0x12
+
+#define TAG_RecvDataPush_BasePush												0x0a
+#define TAG_RecvDataPush_Data													0x12
+#define TAG_RecvDataPush_Type													0x18
+
+#define TAG_SwitchViewPush_BasePush												0x0a
+#define TAG_SwitchViewPush_SwitchViewOp											0x10
+#define TAG_SwitchViewPush_ViewId												0x18
+
+#define TAG_SwitchBackgroudPush_BasePush										0x0a
+#define TAG_SwitchBackgroudPush_SwitchBackgroundOp								0x10
+
+
+int epb_base_request_pack_size(BaseRequest *request)
+{
+	int pack_size = 0;
+
+	return pack_size;
+}
+
+int epb_pack_base_request(BaseRequest *request, uint8_t *buf, int buf_len)
+{
+	Epb epb;
+	epb_pack_init(&epb, buf, buf_len);
+
+	return epb_get_packed_size(&epb);
+}
+
+BaseResponse *epb_unpack_base_response(const uint8_t *buf, int buf_len)
+{
+	Epb epb;
+	epb_unpack_init(&epb, buf, buf_len);
+
+	if (!epb_has_tag(&epb, TAG_BaseResponse_ErrCode)) {
+		return NULL;
+	}
+
+	BaseResponse *response = (BaseResponse *)GKI_getbuf(sizeof(BaseResponse));
+	memset(response, 0, sizeof(BaseResponse));
+	response->err_code = epb_get_int32(&epb, TAG_BaseResponse_ErrCode);
+	if (epb_has_tag(&epb, TAG_BaseResponse_ErrMsg)) {
+		response->err_msg.str = epb_get_string(&epb, TAG_BaseResponse_ErrMsg, &response->err_msg.len);
+		response->has_err_msg = true;
+	}
+
+	return response;
+}
+
+void epb_unpack_base_response_free(BaseResponse *response)
+{
+	GKI_freebuf(response);
+}
+
+BasePush *epb_unpack_base_push(const uint8_t *buf, int buf_len)
+{
+	Epb epb;
+	epb_unpack_init(&epb, buf, buf_len);
+
+	BasePush *push = (BasePush *)GKI_getbuf(sizeof(BasePush));
+	memset(push, 0, sizeof(BasePush));
+
+	return push;
+}
+
+void epb_unpack_base_push_free(BasePush *push)
+{
+	GKI_freebuf(push);
+}
+
+int epb_auth_request_pack_size(AuthRequest *request)
+{
+	int pack_size = 0;
+	int len = 0;
+
+	len = epb_base_request_pack_size(request->base_request);
+	pack_size += epb_length_delimited_pack_size(TAG_AuthRequest_BaseRequest, len);
+	if (request->has_md5_device_type_and_device_id) {
+		pack_size += epb_length_delimited_pack_size(TAG_AuthRequest_Md5DeviceTypeAndDeviceId, request->md5_device_type_and_device_id.len);
+	}
+	pack_size += epb_varint32_pack_size(TAG_AuthRequest_ProtoVersion, request->proto_version, false);
+	pack_size += epb_varint32_pack_size(TAG_AuthRequest_AuthProto, request->auth_proto, false);
+	pack_size += epb_varint32_pack_size(TAG_AuthRequest_AuthMethod, request->auth_method, false);
+	if (request->has_aes_sign) {
+		pack_size += epb_length_delimited_pack_size(TAG_AuthRequest_AesSign, request->aes_sign.len);
+	}
+	if (request->has_mac_address) {
+		pack_size += epb_length_delimited_pack_size(TAG_AuthRequest_MacAddress, request->mac_address.len);
+	}
+	if (request->has_time_zone) {
+		pack_size += epb_length_delimited_pack_size(TAG_AuthRequest_TimeZone, request->time_zone.len);
+	}
+	if (request->has_language) {
+		pack_size += epb_length_delimited_pack_size(TAG_AuthRequest_Language, request->language.len);
+	}
+	if (request->has_device_name) {
+		pack_size += epb_length_delimited_pack_size(TAG_AuthRequest_DeviceName, request->device_name.len);
+	}
+
+	return pack_size;
+}
+
+int epb_pack_auth_request(AuthRequest *request, uint8_t *buf, int buf_len)
+{
+	Epb epb;
+	epb_pack_init(&epb, buf, buf_len);
+
+	int ret;
+	int tmp_len;
+	uint8_t *tmp;
+
+	tmp_len = epb_base_request_pack_size(request->base_request);
+	tmp = (uint8_t *)GKI_getbuf(tmp_len);
+	ret = epb_pack_base_request(request->base_request, tmp, tmp_len);
+	if (ret < 0) {
+		GKI_freebuf(tmp);
+		return ret;
+	}
+	ret = epb_set_message(&epb, TAG_AuthRequest_BaseRequest, tmp, tmp_len);
+	GKI_freebuf(tmp);
+	if (ret < 0) return ret;
+	if (request->has_md5_device_type_and_device_id) {
+		ret = epb_set_bytes(&epb, TAG_AuthRequest_Md5DeviceTypeAndDeviceId, request->md5_device_type_and_device_id.data, request->md5_device_type_and_device_id.len);
+		if (ret < 0) return ret;
+	}
+	ret = epb_set_int32(&epb, TAG_AuthRequest_ProtoVersion, request->proto_version);
+	if (ret < 0) return ret;
+	ret = epb_set_int32(&epb, TAG_AuthRequest_AuthProto, request->auth_proto);
+	if (ret < 0) return ret;
+	ret = epb_set_enum(&epb, TAG_AuthRequest_AuthMethod, request->auth_method);
+	if (ret < 0) return ret;
+	if (request->has_aes_sign) {
+		ret = epb_set_bytes(&epb, TAG_AuthRequest_AesSign, request->aes_sign.data, request->aes_sign.len);
+		if (ret < 0) return ret;
+	}
+	if (request->has_mac_address) {
+		ret = epb_set_bytes(&epb, TAG_AuthRequest_MacAddress, request->mac_address.data, request->mac_address.len);
+		if (ret < 0) return ret;
+	}
+	if (request->has_time_zone) {
+		ret = epb_set_string(&epb, TAG_AuthRequest_TimeZone, request->time_zone.str, request->time_zone.len);
+		if (ret < 0) return ret;
+	}
+	if (request->has_language) {
+		ret = epb_set_string(&epb, TAG_AuthRequest_Language, request->language.str, request->language.len);
+		if (ret < 0) return ret;
+	}
+	if (request->has_device_name) {
+		ret = epb_set_string(&epb, TAG_AuthRequest_DeviceName, request->device_name.str, request->device_name.len);
+		if (ret < 0) return ret;
+	}
+
+	return epb_get_packed_size(&epb);
+}
+
+AuthResponse *epb_unpack_auth_response(const uint8_t *buf, int buf_len)
+{
+	Epb epb;
+	epb_unpack_init(&epb, buf, buf_len);
+
+	const uint8_t *tmp;
+	int tmp_len;
+
+	if (!epb_has_tag(&epb, TAG_AuthResponse_BaseResponse)) {
+		return NULL;
+	}
+	if (!epb_has_tag(&epb, TAG_AuthResponse_AesSessionKey)) {
+		return NULL;
+	}
+
+	AuthResponse *response = (AuthResponse *)GKI_getbuf(sizeof(AuthResponse));
+	memset(response, 0, sizeof(AuthResponse));
+	tmp = epb_get_message(&epb, TAG_AuthResponse_BaseResponse, &tmp_len);
+	response->base_response = epb_unpack_base_response(tmp, tmp_len);
+	if (response->base_response == NULL) {
+		GKI_freebuf(response);
+		return NULL;
+	}
+	response->aes_session_key.data = epb_get_bytes(&epb, TAG_AuthResponse_AesSessionKey, &response->aes_session_key.len);
+
+	return response;
+}
+
+void epb_unpack_auth_response_free(AuthResponse *response)
+{
+	epb_unpack_base_response_free(response->base_response);
+	GKI_freebuf(response);
+}
+
+int epb_init_request_pack_size(InitRequest *request)
+{
+	int pack_size = 0;
+	int len = 0;
+
+	len = epb_base_request_pack_size(request->base_request);
+	pack_size += epb_length_delimited_pack_size(TAG_InitRequest_BaseRequest, len);
+	if (request->has_resp_field_filter) {
+		pack_size += epb_length_delimited_pack_size(TAG_InitRequest_RespFieldFilter, request->resp_field_filter.len);
+	}
+	if (request->has_challenge) {
+		pack_size += epb_length_delimited_pack_size(TAG_InitRequest_Challenge, request->challenge.len);
+	}
+
+	return pack_size;
+}
+
+int epb_pack_init_request(InitRequest *request, uint8_t *buf, int buf_len)
+{
+	Epb epb;
+	epb_pack_init(&epb, buf, buf_len);
+
+	int ret;
+	int tmp_len;
+	uint8_t *tmp;
+
+	tmp_len = epb_base_request_pack_size(request->base_request);
+	tmp = (uint8_t *)GKI_getbuf(tmp_len);
+	ret = epb_pack_base_request(request->base_request, tmp, tmp_len);
+	if (ret < 0) {
+		GKI_freebuf(tmp);
+		return ret;
+	}
+	ret = epb_set_message(&epb, TAG_InitRequest_BaseRequest, tmp, tmp_len);
+	GKI_freebuf(tmp);
+	if (ret < 0) return ret;
+	if (request->has_resp_field_filter) {
+		ret = epb_set_bytes(&epb, TAG_InitRequest_RespFieldFilter, request->resp_field_filter.data, request->resp_field_filter.len);
+		if (ret < 0) return ret;
+	}
+	if (request->has_challenge) {
+		ret = epb_set_bytes(&epb, TAG_InitRequest_Challenge, request->challenge.data, request->challenge.len);
+		if (ret < 0) return ret;
+	}
+
+	return epb_get_packed_size(&epb);
+}
+
+InitResponse *epb_unpack_init_response(const uint8_t *buf, int buf_len)
+{
+	Epb epb;
+	epb_unpack_init(&epb, buf, buf_len);
+
+	const uint8_t *tmp;
+	int tmp_len;
+
+	if (!epb_has_tag(&epb, TAG_InitResponse_BaseResponse)) {
+		return NULL;
+	}
+	if (!epb_has_tag(&epb, TAG_InitResponse_UserIdHigh)) {
+		return NULL;
+	}
+	if (!epb_has_tag(&epb, TAG_InitResponse_UserIdLow)) {
+		return NULL;
+	}
+
+	InitResponse *response = (InitResponse *)GKI_getbuf(sizeof(InitResponse));
+	memset(response, 0, sizeof(InitResponse));
+	tmp = epb_get_message(&epb, TAG_InitResponse_BaseResponse, &tmp_len);
+	response->base_response = epb_unpack_base_response(tmp, tmp_len);
+	if (response->base_response == NULL) {
+		GKI_freebuf(response);
+		return NULL;
+	}
+	response->user_id_high = epb_get_uint32(&epb, TAG_InitResponse_UserIdHigh);
+	response->user_id_low = epb_get_uint32(&epb, TAG_InitResponse_UserIdLow);
+	if (epb_has_tag(&epb, TAG_InitResponse_ChalleangeAnswer)) {
+		response->challeange_answer = epb_get_uint32(&epb, TAG_InitResponse_ChalleangeAnswer);
+		response->has_challeange_answer = true;
+	}
+	if (epb_has_tag(&epb, TAG_InitResponse_InitScence)) {
+		response->init_scence = (EmInitScence)epb_get_enum(&epb, TAG_InitResponse_InitScence);
+		response->has_init_scence = true;
+	}
+	if (epb_has_tag(&epb, TAG_InitResponse_AutoSyncMaxDurationSecond)) {
+		response->auto_sync_max_duration_second = epb_get_uint32(&epb, TAG_InitResponse_AutoSyncMaxDurationSecond);
+		response->has_auto_sync_max_duration_second = true;
+	}
+	if (epb_has_tag(&epb, TAG_InitResponse_UserNickName)) {
+		response->user_nick_name.str = epb_get_string(&epb, TAG_InitResponse_UserNickName, &response->user_nick_name.len);
+		response->has_user_nick_name = true;
+	}
+	if (epb_has_tag(&epb, TAG_InitResponse_PlatformType)) {
+		response->platform_type = (EmPlatformType)epb_get_enum(&epb, TAG_InitResponse_PlatformType);
+		response->has_platform_type = true;
+	}
+	if (epb_has_tag(&epb, TAG_InitResponse_Model)) {
+		response->model.str = epb_get_string(&epb, TAG_InitResponse_Model, &response->model.len);
+		response->has_model = true;
+	}
+	if (epb_has_tag(&epb, TAG_InitResponse_Os)) {
+		response->os.str = epb_get_string(&epb, TAG_InitResponse_Os, &response->os.len);
+		response->has_os = true;
+	}
+	if (epb_has_tag(&epb, TAG_InitResponse_Time)) {
+		response->time = epb_get_int32(&epb, TAG_InitResponse_Time);
+		response->has_time = true;
+	}
+	if (epb_has_tag(&epb, TAG_InitResponse_TimeZone)) {
+		response->time_zone = epb_get_int32(&epb, TAG_InitResponse_TimeZone);
+		response->has_time_zone = true;
+	}
+	if (epb_has_tag(&epb, TAG_InitResponse_TimeString)) {
+		response->time_string.str = epb_get_string(&epb, TAG_InitResponse_TimeString, &response->time_string.len);
+		response->has_time_string = true;
+	}
+
+	return response;
+}
+
+void epb_unpack_init_response_free(InitResponse *response)
+{
+	epb_unpack_base_response_free(response->base_response);
+	GKI_freebuf((void *)response);
+}
+
+int epb_send_data_request_pack_size(SendDataRequest *request)
+{
+	int pack_size = 0;
+	int len = 0;
+
+	len = epb_base_request_pack_size(request->base_request);
+	pack_size += epb_length_delimited_pack_size(TAG_SendDataRequest_BaseRequest, len);
+	pack_size += epb_length_delimited_pack_size(TAG_SendDataRequest_Data, request->data.len);
+	if (request->has_type) {
+		pack_size += epb_varint32_pack_size(TAG_SendDataRequest_Type, request->type, false);
+	}
+
+	return pack_size;
+}
+
+int epb_pack_send_data_request(SendDataRequest *request, uint8_t *buf, int buf_len)
+{
+	Epb epb;
+	epb_pack_init(&epb, buf, buf_len);
+
+	int ret;
+	int tmp_len;
+	uint8_t *tmp;
+
+	tmp_len = epb_base_request_pack_size(request->base_request);
+	tmp = (uint8_t *)GKI_getbuf(tmp_len);
+	ret = epb_pack_base_request(request->base_request, tmp, tmp_len);
+	if (ret < 0) {
+		GKI_freebuf(tmp);
+		return ret;
+	}
+	ret = epb_set_message(&epb, TAG_SendDataRequest_BaseRequest, tmp, tmp_len);
+	GKI_freebuf(tmp);
+	if (ret < 0) return ret;
+	ret = epb_set_bytes(&epb, TAG_SendDataRequest_Data, request->data.data, request->data.len);
+	if (ret < 0) return ret;
+	if (request->has_type) {
+		ret = epb_set_enum(&epb, TAG_SendDataRequest_Type, request->type);
+		if (ret < 0) return ret;
+	}
+
+	return epb_get_packed_size(&epb);
+}
+
+SendDataResponse *epb_unpack_send_data_response(const uint8_t *buf, int buf_len)
+{
+	Epb epb;
+	epb_unpack_init(&epb, buf, buf_len);
+
+	const uint8_t *tmp;
+	int tmp_len;
+
+	if (!epb_has_tag(&epb, TAG_SendDataResponse_BaseResponse)) {
+		return NULL;
+	}
+
+	SendDataResponse *response = (SendDataResponse *)GKI_getbuf(sizeof(SendDataResponse));
+	memset(response, 0, sizeof(SendDataResponse));
+	tmp = epb_get_message(&epb, TAG_SendDataResponse_BaseResponse, &tmp_len);
+	response->base_response = epb_unpack_base_response(tmp, tmp_len);
+	if (response->base_response == NULL) {
+		GKI_freebuf(response);
+		return NULL;
+	}
+	if (epb_has_tag(&epb, TAG_SendDataResponse_Data)) {
+		response->data.data = epb_get_bytes(&epb, TAG_SendDataResponse_Data, &response->data.len);
+		response->has_data = true;
+	}
+
+	return response;
+}
+
+void epb_unpack_send_data_response_free(SendDataResponse *response)
+{
+	epb_unpack_base_response_free(response->base_response);
+	GKI_freebuf(response);
+}
+
+RecvDataPush *epb_unpack_recv_data_push(const uint8_t *buf, int buf_len)
+{
+	Epb epb;
+	epb_unpack_init(&epb, buf, buf_len);
+
+	const uint8_t *tmp;
+	int tmp_len;
+
+	if (!epb_has_tag(&epb, TAG_RecvDataPush_BasePush)) {
+		return NULL;
+	}
+	if (!epb_has_tag(&epb, TAG_RecvDataPush_Data)) {
+		return NULL;
+	}
+
+	RecvDataPush *push = (RecvDataPush *)GKI_getbuf(sizeof(RecvDataPush));
+	memset(push, 0, sizeof(RecvDataPush));
+	tmp = epb_get_message(&epb, TAG_RecvDataPush_BasePush, &tmp_len);
+	push->base_push = epb_unpack_base_push(tmp, tmp_len);
+	if (push->base_push == NULL) {
+		GKI_freebuf(push);
+		return NULL;
+	}
+	push->data.data = epb_get_bytes(&epb, TAG_RecvDataPush_Data, &push->data.len);
+	if (epb_has_tag(&epb, TAG_RecvDataPush_Type)) {
+		push->type = (EmDeviceDataType)epb_get_enum(&epb, TAG_RecvDataPush_Type);
+		push->has_type = true;
+	}
+
+	return push;
+}
+
+void epb_unpack_recv_data_push_free(RecvDataPush *push)
+{
+	epb_unpack_base_push_free(push->base_push);
+    push->base_push = NULL;
+	GKI_freebuf(push);
+}
+
+SwitchViewPush *epb_unpack_switch_view_push(const uint8_t *buf, int buf_len)
+{
+	Epb epb;
+	epb_unpack_init(&epb, buf, buf_len);
+
+	const uint8_t *tmp;
+	int tmp_len;
+
+	if (!epb_has_tag(&epb, TAG_SwitchViewPush_BasePush)) {
+		return NULL;
+	}
+	if (!epb_has_tag(&epb, TAG_SwitchViewPush_SwitchViewOp)) {
+		return NULL;
+	}
+	if (!epb_has_tag(&epb, TAG_SwitchViewPush_ViewId)) {
+		return NULL;
+	}
+
+	SwitchViewPush *push = (SwitchViewPush *)GKI_getbuf(sizeof(SwitchViewPush));
+	memset(push, 0, sizeof(SwitchViewPush));
+	tmp = epb_get_message(&epb, TAG_SwitchViewPush_BasePush, &tmp_len);
+	push->base_push = epb_unpack_base_push(tmp, tmp_len);
+	if (push->base_push == NULL) {
+		GKI_freebuf(push);
+		return NULL;
+	}
+	push->switch_view_op = (EmSwitchViewOp)epb_get_enum(&epb, TAG_SwitchViewPush_SwitchViewOp);
+	push->view_id = (EmViewId)epb_get_enum(&epb, TAG_SwitchViewPush_ViewId);
+
+	return push;
+}
+
+void epb_unpack_switch_view_push_free(SwitchViewPush *push)
+{
+	epb_unpack_base_push_free(push->base_push);
+	GKI_freebuf(push);
+}
+
+SwitchBackgroudPush *epb_unpack_switch_backgroud_push(const uint8_t *buf, int buf_len)
+{
+	Epb epb;
+	epb_unpack_init(&epb, buf, buf_len);
+
+	const uint8_t *tmp;
+	int tmp_len;
+
+	if (!epb_has_tag(&epb, TAG_SwitchBackgroudPush_BasePush)) {
+		return NULL;
+	}
+	if (!epb_has_tag(&epb, TAG_SwitchBackgroudPush_SwitchBackgroundOp)) {
+		return NULL;
+	}
+
+	SwitchBackgroudPush *push = (SwitchBackgroudPush *)GKI_getbuf(sizeof(SwitchBackgroudPush));
+	memset(push, 0, sizeof(SwitchBackgroudPush));
+	tmp = epb_get_message(&epb, TAG_SwitchBackgroudPush_BasePush, &tmp_len);
+	push->base_push = epb_unpack_base_push(tmp, tmp_len);
+	if (push->base_push == NULL) {
+		GKI_freebuf(push);
+		return NULL;
+	}
+	push->switch_background_op = (EmSwitchBackgroundOp)epb_get_enum(&epb, TAG_SwitchBackgroudPush_SwitchBackgroundOp);
+
+	return push;
+}
+
+void epb_unpack_switch_backgroud_push_free(SwitchBackgroudPush *push)
+{
+	epb_unpack_base_push_free(push->base_push);
+	GKI_freebuf(push);
+}
+
+#endif	///WX_AIRSYNC_CFG
+

+ 586 - 0
examples/06_bluedroid_demos/components/bluedroid_demos/app_profiles/app_WX_airsync/mpbledemo2.c

@@ -0,0 +1,586 @@
+/*
+*	WeChat mpbledemo2 
+*
+*	author by anqiren  2014/12/02  V1.0bat
+*
+**/
+
+#include "prf_defs.h"
+
+#if	(WX_AIRSYNC_CFG)
+
+#include <string.h>
+#include <stdlib.h>
+#include <stdint.h>
+#include <stdio.h>
+#include "app_airsync_prf.h"
+#include "wechat_aes.h"
+#include "epb_MmBp.h"
+#include "wechar_crc.h"
+#include "app_wechat_util.h"
+#include "app_airsync_md5.h"
+#include "mpbledemo2.h"
+#include "gki.h"
+
+
+mpbledemo2_info m_info = {CMD_NULL, {NULL, 0}};
+
+#if defined EAM_md5AndNoEnrypt || EAM_md5AndAesEnrypt
+	uint8_t md5_type_and_id[16];
+#endif
+
+uint8_t challeange[CHALLENAGE_LENGTH] = {0x11,0x22,0x33,0x44}; //为了方便这里填了一组确定的数组,使用过程中请自行生成随机数
+
+mpbledemo2_state mpbledemo2Sta = {false, false, false, false, false, false,0,0,0};
+const uint8_t key[16] = DEVICE_KEY;
+uint8_t session_key[32] = {0};
+data_handler *m_mpbledemo2_handler = NULL;
+uint8_t isLightOn;
+/**** NOTIFICATION BITS ***********/
+uint8_t FirstNotificationBit ;
+uint8_t SecondNotificationBit;
+
+
+//static void mpbledemo2_handleCmdFromServer(BleDemo2CmdID cmd, uint8_t *ptrData, uint32_t lengthInByte);
+
+/**@brief   Function for the light initialization.
+ *
+ * @details Initializes all lights used by this application.
+ */
+
+int32_t mpbledemo2_get_md5(void)
+{
+	int32_t error_code = 0;
+#if defined EAM_md5AndNoEnrypt || EAM_md5AndAesEnrypt
+	char device_type[] = DEVICE_TYPE;
+	char device_id[] = DEVICE_ID;
+	char argv[sizeof(DEVICE_TYPE) + sizeof(DEVICE_ID) - 1];
+	memcpy(argv,device_type,sizeof(DEVICE_TYPE));
+/*when add the DEVICE_ID to DEVICE_TYPE, the offset shuld -1 to overwrite '\0'  at the end of DEVICE_TYPE */
+	memcpy(argv + sizeof(DEVICE_TYPE)-1,device_id,sizeof(DEVICE_ID));
+
+	error_code = wechat_md5(argv, md5_type_and_id);
+
+#endif
+	return error_code;
+}
+
+void mpbledemo2_reset()
+{
+	mpbledemo2Sta.auth_send = false;
+	mpbledemo2Sta.auth_state = false;
+	mpbledemo2Sta.indication_state = false;
+	mpbledemo2Sta.init_send = false;
+	mpbledemo2Sta.init_state = false;
+	mpbledemo2Sta.send_data_seq = 0;
+	mpbledemo2Sta.push_data_seq = 0;
+	mpbledemo2Sta.seq = 0;
+}
+    
+int32_t mpbledemo2_init(void)
+{
+	mpbledemo2_reset();
+	return (mpbledemo2_get_md5());
+}
+
+
+void mpbledemo2_indication_state(bool isEnable)
+{
+    mpbledemo2Sta.indication_state = isEnable;
+    if (false == isEnable)
+    {
+        mpbledemo2Sta.auth_send = false;
+    }
+}
+
+int32_t device_auth()
+{	
+	if (m_mpbledemo2_handler == NULL) {
+			m_mpbledemo2_handler = get_handler_by_type(PRODUCT_TYPE_MPBLEDEMO2);
+		}
+		uint8_t *data = NULL;
+		uint32_t len = 0;
+		
+		ARGS_ITEM_SET(mpbledemo2_info, m_mpbledemo2_handler->m_data_produce_args, cmd, CMD_AUTH);	
+		m_mpbledemo2_handler->m_data_produce_func(m_mpbledemo2_handler->m_data_produce_args, &data, &len);
+		if(data == NULL)
+		{
+			return errorCodeProduce;
+		}
+        
+		//sent data
+		ble_wechat_indicate_data(data, len);
+		return 0;
+	}
+	
+
+int32_t	device_init()
+	{
+		uint8_t *data = NULL;
+		uint32_t len = 0;
+		ARGS_ITEM_SET(mpbledemo2_info, m_mpbledemo2_handler->m_data_produce_args, cmd, CMD_INIT);
+		m_mpbledemo2_handler->m_data_produce_func(m_mpbledemo2_handler->m_data_produce_args, &data, &len);
+		if(data == NULL)
+		{
+			return errorCodeProduce;
+		}
+        
+		//sent data
+		ble_wechat_indicate_data(data, len);
+	
+		return 0;
+}
+
+void mpbledemo2_main_process()
+{
+	int error_code = 0;
+	if((mpbledemo2Sta.indication_state) && (!mpbledemo2Sta.auth_state) && (!mpbledemo2Sta.auth_send) )
+	{
+		error_code = device_auth();
+        if (0 == error_code)
+        {
+            mpbledemo2Sta.auth_send = true;	
+        }
+	}
+	if((mpbledemo2Sta.auth_state) && (!mpbledemo2Sta.init_state) && (!mpbledemo2Sta.init_send))
+	{
+		error_code = device_init();
+        if (0 == error_code)
+        {
+            mpbledemo2Sta.init_send = true;            
+        }
+	}
+}
+
+void mpbledemo2_data_free_func(uint8_t *data, uint32_t len)
+{
+	if(data)
+    {
+		GKI_freebuf(data);
+		data = NULL;
+    }
+}
+
+void mpbledemo2_data_produce_func(void *args, uint8_t **r_data, uint32_t *r_len)
+{	
+		static uint16_t bleDemoHeadLen = sizeof(BlueDemoHead);
+		mpbledemo2_info *info = (mpbledemo2_info *)args;
+		BaseRequest basReq = {NULL};
+		static uint8_t fix_head_len = sizeof(BpFixHead);
+		BpFixHead fix_head = {0xFE, 1, 0, htons(ECI_req_auth), 0};
+		mpbledemo2Sta.seq++;
+		switch (info->cmd)
+		{
+		case CMD_AUTH:
+			{
+			#if defined EAM_md5AndAesEnrypt
+				uint8_t deviceid[] = DEVICE_ID;
+				static uint32_t seq = 0x00000001;		//
+				uint32_t ran = 0x11223344;		//为了方便起见这里放了一个固定值做为随机数,在使用时请自行生成随机数。
+				ran = t_htonl(ran);
+				seq = t_htonl(seq);
+				uint8_t id_len = strlen(DEVICE_ID);
+				uint8_t* data = GKI_getbuf(id_len+8);
+				if(!data){return;}
+				memcpy(data,deviceid,id_len);
+				memcpy(data+id_len,(uint8_t*)&ran,4);
+				memcpy(data+id_len+4,(uint8_t*)&seq,4);
+				uint32_t crc = crc32(0, data, id_len+8);
+				crc = t_htonl(crc);
+				memset(data,0x00,id_len+8);
+				memcpy(data,(uint8_t*)&ran,4);
+				memcpy(data+4,(uint8_t*)&seq,4);
+				memcpy(data+8,(uint8_t*)&crc,4);	
+				uint8_t CipherText[16];
+				AES_Init(key);
+				AES_Encrypt_PKCS7 (data, CipherText, 12, key);
+				if(data){GKI_freebuf(data);data = NULL;}
+				AuthRequest authReq = {&basReq, true,{md5_type_and_id, MD5_TYPE_AND_ID_LENGTH}, 
+                PROTO_VERSION, AUTH_PROTO, (EmAuthMethod)AUTH_METHOD, true ,
+                {CipherText, CIPHER_TEXT_LENGTH}, false, {NULL, 0}, false, {NULL, 0}, false, 
+                {NULL, 0},true,{DEVICE_ID,sizeof(DEVICE_ID)}};
+				seq++;
+			#endif
+				
+			#if defined EAM_macNoEncrypt
+				static uint8_t mac_address[MAC_ADDRESS_LENGTH];
+				//get_mac_addr(mac_address);
+				AuthRequest authReq = {&basReq, false,{NULL, 0}, PROTO_VERSION, AUTH_PROTO, (EmAuthMethod)AUTH_METHOD, false,{NULL, 0}, true, {mac_address, MAC_ADDRESS_LENGTH}, false, {NULL, 0}, false, {NULL, 0},true,{DEVICE_ID,sizeof(DEVICE_ID)}};
+			#endif
+				
+			#if defined EAM_md5AndNoEnrypt
+				AuthRequest authReq = {&basReq, true,{md5_type_and_id, MD5_TYPE_AND_ID_LENGTH}, PROTO_VERSION, (EmAuthMethod)AUTH_PROTO, (EmAuthMethod)AUTH_METHOD, false ,{NULL, 0}, false, {NULL, 0}, false, {NULL, 0}, false, {NULL, 0},true,{DEVICE_ID,sizeof(DEVICE_ID)}};
+			#endif
+				*r_len = epb_auth_request_pack_size(&authReq) + fix_head_len;
+				*r_data = (uint8_t *)GKI_getbuf(*r_len);
+				if(!(*r_data)){return;}
+				if(epb_pack_auth_request(&authReq, *r_data+fix_head_len, *r_len-fix_head_len)<0)
+				{
+					*r_data = NULL;
+					return;
+				}
+				fix_head.nCmdId = htons(ECI_req_auth);
+				fix_head.nLength = htons(*r_len);
+				fix_head.nSeq = htons(mpbledemo2Sta.seq);
+				memcpy(*r_data, &fix_head, fix_head_len);                
+				return ;
+		}
+		case CMD_INIT:
+			{
+				//has challeange
+				InitRequest initReq = {&basReq,false, {NULL, 0},true, {challeange, CHALLENAGE_LENGTH}};
+				*r_len = epb_init_request_pack_size(&initReq) + fix_head_len;
+			#if defined EAM_md5AndAesEnrypt
+				uint8_t length = *r_len;				
+				uint8_t *p = GKI_getbuf(AES_get_length( *r_len-fix_head_len));
+				if(!p){return;}
+				*r_len = AES_get_length( *r_len-fix_head_len)+fix_head_len;
+			#endif
+			//pack data
+				*r_data = (uint8_t *)GKI_getbuf(*r_len);
+				if(!(*r_data)){return;}
+				if(epb_pack_init_request(&initReq, *r_data+fix_head_len, *r_len-fix_head_len)<0)
+				{*r_data = NULL;return;}
+				//encrypt body
+			#if defined EAM_md5AndAesEnrypt
+				AES_Init(session_key);
+				AES_Encrypt_PKCS7(*r_data+fix_head_len,p,length-fix_head_len,session_key);//原始数据长度
+				memcpy(*r_data + fix_head_len, p, *r_len-fix_head_len);
+				if(p)GKI_freebuf(p);
+			#endif
+				fix_head.nCmdId = htons(ECI_req_init);
+				fix_head.nLength = htons(*r_len);
+				fix_head.nSeq = htons(mpbledemo2Sta.seq);
+				memcpy(*r_data, &fix_head, fix_head_len);
+				return  ;
+		}
+		case CMD_SENDDAT:
+			{
+			
+				BlueDemoHead  *bleDemoHead = (BlueDemoHead*)GKI_getbuf(bleDemoHeadLen+info->send_msg.len);
+				if (!bleDemoHead)
+                {
+                    return;
+                }
+                
+                // header of sent data
+				bleDemoHead->m_magicCode[0] = MPBLEDEMO2_MAGICCODE_H;
+				bleDemoHead->m_magicCode[1] = MPBLEDEMO2_MAGICCODE_L;
+				bleDemoHead->m_version      = htons(MPBLEDEMO2_VERSION);
+				bleDemoHead->m_totalLength  = htons(bleDemoHeadLen + info->send_msg.len);
+				bleDemoHead->m_cmdid        = htons(sendTextReq);
+				bleDemoHead->m_seq          = htons(mpbledemo2Sta.seq);
+				bleDemoHead->m_errorCode    = 0;	
+                
+				/*connect body and head.*/
+				/*turn to uint8_t* befort offset.*/
+				memcpy((uint8_t*)bleDemoHead + bleDemoHeadLen, info->send_msg.str, info->send_msg.len);		
+                
+				SendDataRequest sendDatReq = 
+                    {
+                        &basReq, 
+                        { (uint8_t*) bleDemoHead, (bleDemoHeadLen + info->send_msg.len)},  // define the data content wrapped in epb
+                        false,      // no type, the data is directly sent to vendor server
+                        (EmDeviceDataType)NULL
+                    };
+				*r_len = epb_send_data_request_pack_size(&sendDatReq) + fix_head_len;
+                    
+			#if defined EAM_md5AndAesEnrypt
+				uint16_t length = *r_len;
+				uint8_t *p = GKI_getbuf(AES_get_length( *r_len-fix_head_len));
+				if(!p){return;}
+				*r_len = AES_get_length( *r_len-fix_head_len)+fix_head_len;
+			#endif
+                
+				*r_data = (uint8_t *)GKI_getbuf(*r_len);
+				if(!(*r_data)){return;}
+				if(epb_pack_send_data_request(&sendDatReq, *r_data+fix_head_len, *r_len-fix_head_len)<0)
+				{
+					*r_data = NULL;
+				#if defined EAM_md5AndAesEnrypt
+					if(p){GKI_freebuf(p);
+					p = NULL;}
+				#endif
+					return;
+				}
+                
+			#if defined EAM_md5AndAesEnrypt
+				//encrypt body
+				AES_Init(session_key);
+				AES_Encrypt_PKCS7(*r_data+fix_head_len,p,length-fix_head_len,session_key);//原始数据长度
+				memcpy(*r_data + fix_head_len, p, *r_len-fix_head_len);
+				if(p){GKI_freebuf(p); p = NULL;}
+			#endif
+                
+                // header of epb
+				fix_head.nCmdId = htons(ECI_req_sendData);
+				fix_head.nLength = htons(*r_len);
+				fix_head.nSeq = htons(mpbledemo2Sta.seq);
+                
+				memcpy(*r_data, &fix_head, fix_head_len);
+				if(bleDemoHead){GKI_freebuf(bleDemoHead);bleDemoHead = NULL;}
+                
+                // increase sequence by 1
+                mpbledemo2Sta.send_data_seq++;				
+				return ;
+		}
+	}	
+}
+
+int mpbledemo2_data_consume_func(uint8_t *data, uint32_t len)
+{
+		BpFixHead *fix_head = (BpFixHead *)data;
+		uint8_t fix_head_len = sizeof(BpFixHead);
+		switch(ntohs(fix_head->nCmdId))
+		{
+			case ECI_none:
+			{
+
+
+			}
+				break;
+			case ECI_resp_auth:
+				{
+					AuthResponse* authResp;
+					authResp = epb_unpack_auth_response(data+fix_head_len,len-fix_head_len);
+					if(authResp->base_response)
+					{
+						if(authResp->base_response->err_code == 0)
+						{
+							mpbledemo2Sta.auth_state = true;
+						}
+						else
+						{
+                            int32_t returnedErrCode = authResp->base_response->err_code;
+							epb_unpack_auth_response_free(authResp);
+							return returnedErrCode;
+						}
+					}
+				#if defined EAM_md5AndAesEnrypt		// get sessionkey
+					if(authResp->aes_session_key.len)
+					{
+						AES_Init(key);
+						AES_Decrypt(session_key,authResp->aes_session_key.data,authResp->aes_session_key.len,key);
+					}
+				#endif
+					epb_unpack_auth_response_free(authResp);
+				}
+				break;
+			case ECI_resp_sendData:
+				{
+				
+			#if defined EAM_md5AndAesEnrypt		
+					uint32_t length = len- fix_head_len;//加密后数据长度
+					uint8_t *p = GKI_getbuf (length);
+					if(!p){ if(data)GKI_freebuf(data);data = NULL; return 0;}
+					AES_Init(session_key);
+					//解密数据
+					AES_Decrypt(p,data+fix_head_len,len- fix_head_len,session_key);
+					
+					uint8_t temp;
+					temp = p[length - 1];//算出填充长度
+					len = len - temp;//取加密前数据总长度
+					memcpy(data + fix_head_len, p ,length -temp);//把明文放回
+					if(p){GKI_freebuf(p);p = NULL;}
+			#endif	
+				SendDataResponse *sendDataResp;
+				sendDataResp = epb_unpack_send_data_response(data+fix_head_len,len-fix_head_len);
+				if (!sendDataResp)
+				{
+					return errorCodeUnpackSendDataResp;
+				}
+
+					if(sendDataResp->base_response->err_code)
+					{
+						epb_unpack_send_data_response_free(sendDataResp);
+						return sendDataResp->base_response->err_code;
+					}
+					epb_unpack_send_data_response_free(sendDataResp);
+			}
+				break;
+			case ECI_resp_init:
+				{
+				FirstNotificationBit = 0;
+				SecondNotificationBit = 0; 
+		
+			#if defined EAM_md5AndAesEnrypt		
+					uint32_t length = len- fix_head_len;		//加密后数据长度
+					uint8_t *p = GKI_getbuf (length);
+					if(!p){if(data)GKI_freebuf(data);data = NULL; return 0;}
+					AES_Init(session_key);
+					//解密数据
+					AES_Decrypt(p,data+fix_head_len,len- fix_head_len,session_key);
+					
+					uint8_t temp;
+					temp = p[length - 1];			//算出填充长度
+					len = len - temp;				//取加密前数据总长度
+					memcpy(data + fix_head_len, p ,length -temp);		//把明文放回
+					if(p){GKI_freebuf(p);p = NULL;}
+			#endif		
+				InitResponse *initResp = epb_unpack_init_response(data+fix_head_len, len-fix_head_len);
+				if(!initResp)
+				{
+					return errorCodeUnpackInitResp;
+				}
+			
+					if(initResp->base_response)
+					{
+						if(initResp->base_response->err_code == 0)
+						{
+							if(initResp->has_challeange_answer)
+							{
+								if(crc32(0,challeange,CHALLENAGE_LENGTH) == initResp->challeange_answer)
+								{
+									mpbledemo2Sta.init_state = true;
+								}
+							}
+							else mpbledemo2Sta.init_state = true;
+							mpbledemo2Sta.wechats_switch_state = true;
+						}
+						else
+						{
+							epb_unpack_init_response_free(initResp);
+							return initResp->base_response->err_code;
+						}
+					}
+				epb_unpack_init_response_free(initResp);
+			}
+				break;
+			case ECI_push_recvData:
+				{
+				#if defined EAM_md5AndAesEnrypt
+					uint32_t length = len- fix_head_len;//加密后数据长度
+					uint8_t *p = GKI_getbuf (length);
+					if(!p){if(data)GKI_freebuf(data); data =NULL; return 0;}
+					AES_Init(session_key);
+					//解密数据
+					AES_Decrypt(p,data+fix_head_len,len- fix_head_len,session_key);
+					
+					uint8_t temp;
+					temp = p[length - 1];//算出填充长度
+					len = len - temp;//取加密前数据总长度
+					memcpy(data + fix_head_len, p ,length -temp);//把明文放回
+					if(p){GKI_freebuf(p);p = NULL;}
+				#endif
+			RecvDataPush *recvDatPush;
+			recvDatPush = epb_unpack_recv_data_push(data+fix_head_len, len-fix_head_len);
+		
+			if(!recvDatPush)
+			{
+				return errorCodeUnpackRecvDataPush;
+			}
+		
+			BlueDemoHead *bledemohead = (BlueDemoHead*)recvDatPush->data.data;
+		
+            
+            // ble demo command handle
+  
+			epb_unpack_recv_data_push_free(recvDatPush);
+			mpbledemo2Sta.push_data_seq++;
+		}
+				break;
+			case ECI_push_switchView:
+				{
+			
+					mpbledemo2Sta.wechats_switch_state = !mpbledemo2Sta.wechats_switch_state;
+			
+			#if defined EAM_md5AndAesEnrypt		
+					uint32_t length = len- fix_head_len;//加密后数据长度
+					uint8_t *p = GKI_getbuf (length);
+					if(!p){if(data)GKI_freebuf(data);data = NULL; return 0;}
+					AES_Init(session_key);
+					//解密数据
+					AES_Decrypt(p,data+fix_head_len,len- fix_head_len,session_key);
+					
+					uint8_t temp;
+					temp = p[length - 1];//算出填充长度
+					len = len - temp;//取加密前数据总长度
+					memcpy(data + fix_head_len, p ,length -temp);//把明文放回
+					if(p){GKI_freebuf(p);p = NULL;}
+			#endif		
+				SwitchViewPush *swichViewPush;
+				swichViewPush = epb_unpack_switch_view_push(data+fix_head_len,len-fix_head_len);
+				if(!swichViewPush)
+				{
+					return errorCodeUnpackSwitchViewPush;
+				}
+				epb_unpack_switch_view_push_free(swichViewPush);
+			}
+				break;
+			case ECI_push_switchBackgroud:
+				{
+			
+			#if defined EAM_md5AndAesEnrypt
+					uint32_t length = len- fix_head_len;//加密后数据长度
+					uint8_t *p = GKI_getbuf (length);
+					if(!p){if(data)GKI_freebuf(data);data = NULL;  return 0;}
+					AES_Init(session_key);
+					//解密数据
+					AES_Decrypt(p,data+fix_head_len,len- fix_head_len,session_key);
+					uint8_t temp;
+					temp = p[length - 1];//算出填充长度
+					len = len - temp;//取加密前数据总长度
+					memcpy(data + fix_head_len, p ,length -temp);//把明文放回
+					if(data){GKI_freebuf(p);p = NULL;}
+			#endif
+				SwitchBackgroudPush *switchBackgroundPush = epb_unpack_switch_backgroud_push(data+fix_head_len,len-fix_head_len);
+				if(! switchBackgroundPush)
+				{
+					return errorCodeUnpackSwitchBackgroundPush;
+				}	
+				epb_unpack_switch_backgroud_push_free(switchBackgroundPush);
+			}
+				break;
+			case ECI_err_decode:
+				break;
+			default:
+				{
+	
+			}
+				break;
+		}
+		return 0;
+}
+void mpbledemo2_data_error_func(int error_code)
+{
+	if(error_code)
+	{
+        
+		//NVIC_SystemReset();
+	}
+}
+
+data_handler mpbledemo2_data_handler = {
+		.m_product_type                 = PRODUCT_TYPE_MPBLEDEMO2,
+		.m_data_produce_func            = &mpbledemo2_data_produce_func,
+		.m_data_free_func               = &mpbledemo2_data_free_func,
+		.m_data_consume_func            = &mpbledemo2_data_consume_func,
+		.m_data_error_func              = &mpbledemo2_data_error_func,
+        .m_data_init_peripheral_func    = NULL,
+		.m_data_init_func               = &mpbledemo2_init,
+		.m_data_main_process_func       = &mpbledemo2_main_process,
+		.m_data_button_handler_func     = NULL,
+		.m_data_produce_args            = &m_info,
+		.next                           = NULL
+};
+
+// send data to wechat server
+int32_t mpbledemo2_sendData(uint8_t* ptrData, uint32_t lengthInByte)
+{
+    uint8_t *data = NULL;
+	uint32_t len = 0;
+	ARGS_ITEM_SET(mpbledemo2_info, m_mpbledemo2_handler->m_data_produce_args, cmd, CMD_SENDDAT);   
+	ARGS_ITEM_SET(mpbledemo2_info, m_mpbledemo2_handler->m_data_produce_args, send_msg.len, lengthInByte);
+	ARGS_ITEM_SET(mpbledemo2_info, m_mpbledemo2_handler->m_data_produce_args, send_msg.str, (const char *)ptrData);    
+    
+	m_mpbledemo2_handler->m_data_produce_func(m_mpbledemo2_handler->m_data_produce_args, &data, &len);
+	if(data == NULL)
+	{
+		return errorCodeProduce;
+	}
+	ble_wechat_indicate_data(data, len);
+    return 0;
+}
+
+#endif	///WX_AIRSYNC_CFG
+

+ 51 - 0
examples/06_bluedroid_demos/components/bluedroid_demos/app_profiles/app_WX_airsync/wechar_crc.c

@@ -0,0 +1,51 @@
+//  crc32.c
+//  WeChat Embedded
+//
+//  Created by harlliu on 14-03-03.
+//  Copyright 2014 Tencent. All rights reserved.
+//
+
+
+#include "prf_defs.h"
+#if (WX_AIRSYNC_CFG)
+
+#include <stdio.h>
+#include "wechar_crc.h"
+
+#define DO1(buf) crc = crc_table(((int)crc ^ (*buf++)) & 0xff) ^ (crc >> 8);
+#define DO2(buf)  DO1(buf); DO1(buf);
+#define DO4(buf)  DO2(buf); DO2(buf);
+#define DO8(buf)  DO4(buf); DO4(buf);
+
+
+static uint32_t crc_table(uint32_t index)
+{
+	uint32_t c = index;
+	uint32_t poly = 0xedb88320L;
+	int k;
+
+	for (k = 0; k < 8; k++)
+		c = c & 1 ? poly ^ (c >> 1) : c >> 1;
+
+	return c;
+}
+
+uint32_t crc32(uint32_t crc, const uint8_t *buf, int len)
+{
+    if (buf == NULL) return 0L;
+
+    crc = crc ^ 0xffffffffL;
+    while (len >= 8)
+    {
+      DO8(buf);
+      len -= 8;
+    }
+    if (len) do {
+      DO1(buf);
+    } while (--len);
+    return crc ^ 0xffffffffL;
+}
+
+
+#endif	///WX_AIRSYNC_CFG
+

+ 450 - 0
examples/06_bluedroid_demos/components/bluedroid_demos/app_profiles/app_WX_airsync/wechat_aes.c

@@ -0,0 +1,450 @@
+///////////////////////////////////////////////////////////////////////////////
+// 文 件 名:wechat_aes.c
+// 描    述:AES加密算法
+// 创 建 人:Liangbofu
+// 创建日期:2009-07-17
+///////////////////////////////////////////////////////////////////////////////
+
+#include "prf_defs.h"
+#if (WX_AIRSYNC_CFG)
+
+#include "wechat_aes.h"
+#include <string.h>
+#include <stdlib.h>
+#include <stdint.h>
+#include <stdio.h>
+
+// 为了能针对C51进行优化,并且又使代码可用于ARM和PC等环境,
+// 在非C51环境(没有定义__C51__)下需要把C51特定的关键字定义为空
+#ifndef __C51__
+	#define code
+	#define data
+	#define idata
+	#define xdata
+	#define pdata
+	typedef unsigned char BOOL;
+#else
+	typedef bit BOOL;
+#endif
+
+
+#define Nk	(AES_KEY_LENGTH / 32)		// 以“字”(4字节)为单位的密钥长度
+#define Nb	4							// 以“字”(4字节)为单位的加解密数据块大小,固定为4
+
+// Nr:加密的轮数
+#if   AES_KEY_LENGTH == 128
+	#define Nr	10
+#elif AES_KEY_LENGTH == 192
+	#define Nr	12
+#elif AES_KEY_LENGTH == 256
+	#define Nr	14
+#else
+	#error AES_KEY_LENGTH must be 128, 192 or 256 BOOLs!
+#endif
+
+// GF(28) 多项式
+#define BPOLY 0x1B // Lower 8 BOOLs of (x^8 + x^4 + x^3 + x + 1), ie. (x^4 + x^3 + x + 1).
+
+// AES子密钥表,当密钥长度为128位时,占用176字节空间
+static xdata unsigned char g_roundKeyTable[4*Nb*(Nr+1)];
+
+// 加密用的SBox
+static code const unsigned char SBox[256] = 
+{
+	0x63, 0x7c, 0x77, 0x7b, 0xf2, 0x6b, 0x6f, 0xc5, 0x30, 0x01, 0x67, 0x2b, 0xfe, 0xd7, 0xab, 0x76,
+	0xca, 0x82, 0xc9, 0x7d, 0xfa, 0x59, 0x47, 0xf0, 0xad, 0xd4, 0xa2, 0xaf, 0x9c, 0xa4, 0x72, 0xc0,
+	0xb7, 0xfd, 0x93, 0x26, 0x36, 0x3f, 0xf7, 0xcc, 0x34, 0xa5, 0xe5, 0xf1, 0x71, 0xd8, 0x31, 0x15,
+	0x04, 0xc7, 0x23, 0xc3, 0x18, 0x96, 0x05, 0x9a, 0x07, 0x12, 0x80, 0xe2, 0xeb, 0x27, 0xb2, 0x75,
+	0x09, 0x83, 0x2c, 0x1a, 0x1b, 0x6e, 0x5a, 0xa0, 0x52, 0x3b, 0xd6, 0xb3, 0x29, 0xe3, 0x2f, 0x84,
+	0x53, 0xd1, 0x00, 0xed, 0x20, 0xfc, 0xb1, 0x5b, 0x6a, 0xcb, 0xbe, 0x39, 0x4a, 0x4c, 0x58, 0xcf,
+	0xd0, 0xef, 0xaa, 0xfb, 0x43, 0x4d, 0x33, 0x85, 0x45, 0xf9, 0x02, 0x7f, 0x50, 0x3c, 0x9f, 0xa8,
+	0x51, 0xa3, 0x40, 0x8f, 0x92, 0x9d, 0x38, 0xf5, 0xbc, 0xb6, 0xda, 0x21, 0x10, 0xff, 0xf3, 0xd2,
+	0xcd, 0x0c, 0x13, 0xec, 0x5f, 0x97, 0x44, 0x17, 0xc4, 0xa7, 0x7e, 0x3d, 0x64, 0x5d, 0x19, 0x73,
+	0x60, 0x81, 0x4f, 0xdc, 0x22, 0x2a, 0x90, 0x88, 0x46, 0xee, 0xb8, 0x14, 0xde, 0x5e, 0x0b, 0xdb,
+	0xe0, 0x32, 0x3a, 0x0a, 0x49, 0x06, 0x24, 0x5c, 0xc2, 0xd3, 0xac, 0x62, 0x91, 0x95, 0xe4, 0x79,
+	0xe7, 0xc8, 0x37, 0x6d, 0x8d, 0xd5, 0x4e, 0xa9, 0x6c, 0x56, 0xf4, 0xea, 0x65, 0x7a, 0xae, 0x08,
+	0xba, 0x78, 0x25, 0x2e, 0x1c, 0xa6, 0xb4, 0xc6, 0xe8, 0xdd, 0x74, 0x1f, 0x4b, 0xbd, 0x8b, 0x8a,
+	0x70, 0x3e, 0xb5, 0x66, 0x48, 0x03, 0xf6, 0x0e, 0x61, 0x35, 0x57, 0xb9, 0x86, 0xc1, 0x1d, 0x9e,
+	0xe1, 0xf8, 0x98, 0x11, 0x69, 0xd9, 0x8e, 0x94, 0x9b, 0x1e, 0x87, 0xe9, 0xce, 0x55, 0x28, 0xdf,
+	0x8c, 0xa1, 0x89, 0x0d, 0xbf, 0xe6, 0x42, 0x68, 0x41, 0x99, 0x2d, 0x0f, 0xb0, 0x54, 0xbb, 0x16 
+};
+
+// 解密用的SBox
+static code const unsigned char InvSBox[256] = 
+{
+	0x52, 0x09, 0x6a, 0xd5, 0x30, 0x36, 0xa5, 0x38, 0xbf, 0x40, 0xa3, 0x9e, 0x81, 0xf3, 0xd7, 0xfb,
+	0x7c, 0xe3, 0x39, 0x82, 0x9b, 0x2f, 0xff, 0x87, 0x34, 0x8e, 0x43, 0x44, 0xc4, 0xde, 0xe9, 0xcb,
+	0x54, 0x7b, 0x94, 0x32, 0xa6, 0xc2, 0x23, 0x3d, 0xee, 0x4c, 0x95, 0x0b, 0x42, 0xfa, 0xc3, 0x4e,
+	0x08, 0x2e, 0xa1, 0x66, 0x28, 0xd9, 0x24, 0xb2, 0x76, 0x5b, 0xa2, 0x49, 0x6d, 0x8b, 0xd1, 0x25,
+	0x72, 0xf8, 0xf6, 0x64, 0x86, 0x68, 0x98, 0x16, 0xd4, 0xa4, 0x5c, 0xcc, 0x5d, 0x65, 0xb6, 0x92,
+	0x6c, 0x70, 0x48, 0x50, 0xfd, 0xed, 0xb9, 0xda, 0x5e, 0x15, 0x46, 0x57, 0xa7, 0x8d, 0x9d, 0x84,
+	0x90, 0xd8, 0xab, 0x00, 0x8c, 0xbc, 0xd3, 0x0a, 0xf7, 0xe4, 0x58, 0x05, 0xb8, 0xb3, 0x45, 0x06,
+	0xd0, 0x2c, 0x1e, 0x8f, 0xca, 0x3f, 0x0f, 0x02, 0xc1, 0xaf, 0xbd, 0x03, 0x01, 0x13, 0x8a, 0x6b,
+	0x3a, 0x91, 0x11, 0x41, 0x4f, 0x67, 0xdc, 0xea, 0x97, 0xf2, 0xcf, 0xce, 0xf0, 0xb4, 0xe6, 0x73,
+	0x96, 0xac, 0x74, 0x22, 0xe7, 0xad, 0x35, 0x85, 0xe2, 0xf9, 0x37, 0xe8, 0x1c, 0x75, 0xdf, 0x6e,
+	0x47, 0xf1, 0x1a, 0x71, 0x1d, 0x29, 0xc5, 0x89, 0x6f, 0xb7, 0x62, 0x0e, 0xaa, 0x18, 0xbe, 0x1b,
+	0xfc, 0x56, 0x3e, 0x4b, 0xc6, 0xd2, 0x79, 0x20, 0x9a, 0xdb, 0xc0, 0xfe, 0x78, 0xcd, 0x5a, 0xf4,
+	0x1f, 0xdd, 0xa8, 0x33, 0x88, 0x07, 0xc7, 0x31, 0xb1, 0x12, 0x10, 0x59, 0x27, 0x80, 0xec, 0x5f,
+	0x60, 0x51, 0x7f, 0xa9, 0x19, 0xb5, 0x4a, 0x0d, 0x2d, 0xe5, 0x7a, 0x9f, 0x93, 0xc9, 0x9c, 0xef,
+	0xa0, 0xe0, 0x3b, 0x4d, 0xae, 0x2a, 0xf5, 0xb0, 0xc8, 0xeb, 0xbb, 0x3c, 0x83, 0x53, 0x99, 0x61,
+	0x17, 0x2b, 0x04, 0x7e, 0xba, 0x77, 0xd6, 0x26, 0xe1, 0x69, 0x14, 0x63, 0x55, 0x21, 0x0c, 0x7d	
+};
+
+
+///////////////////////////////////////////////////////////////////////////////
+//	函数名:	RotationWord
+//	描述:		对一个“字”数据进行循环右移。
+//	输入参数:	pWord -- 要右移的4字节数据。
+//	输出参数:	pWord -- 右移后的4字节数据。
+//	返回值:	无。
+///////////////////////////////////////////////////////////////////////////////
+static void RotationWord(unsigned char *pWord)
+{
+	unsigned char temp = pWord[0];
+	pWord[0]  = pWord[1];
+	pWord[1]  = pWord[2];
+	pWord[2]  = pWord[3];
+	pWord[3]  = temp;
+}
+
+///////////////////////////////////////////////////////////////////////////////
+//	函数名:	XorBytes
+//	描述:		批量异或两组数据。
+//	输入参数:	pData1 -- 要异或的第一组数据。
+//				pData1 -- 要异或的第二组数据。
+//				nCount -- 要异或的数据长度。
+//	输出参数:	pData1 -- 异或后的结果。
+//	返回值:	无。
+///////////////////////////////////////////////////////////////////////////////
+static void XorBytes(unsigned char *pData1, const unsigned char *pData2, unsigned char nCount)
+{
+	unsigned char i;
+	
+	for (i = 0; i < nCount; i++)
+	{
+		pData1[i] ^= pData2[i];
+	}
+}
+
+///////////////////////////////////////////////////////////////////////////////
+//	函数名:	AddRoundKey
+//	描述:		把 中间状态数据 加上(异或)子密钥,数据长度为16字节。
+//	输入参数:	pState	  -- 状态数据。
+//				pRoundKey -- 子密钥数据。
+//	输出参数:	pState	  -- 加上子密钥后的状态数据。
+//	返回值:	无。
+///////////////////////////////////////////////////////////////////////////////
+// static void AddRoundKey(unsigned char *pState, const unsigned char *pRoundKey)
+// {
+// 	XorBytes(pState, pRoundKey, 4*Nb);
+// }
+
+// AddRoundKey的宏形式,比函数形式可以节省4字节的data数据
+#define AddRoundKey(pState, pRoundKey) \
+	XorBytes((pState), (pRoundKey), 4*Nb)
+
+
+///////////////////////////////////////////////////////////////////////////////
+//	函数名:	SubBytes
+//	描述:		通过S盒子置换状态数据。
+//	输入参数:	pState	-- 状态数据。
+//				nCount  -- 状态数据长度。
+//				bInvert	-- 是否使用反向S盒子(解密时使用)。
+//	输出参数:	pState	-- 置换后的状态数据。
+//	返回值:	无。
+///////////////////////////////////////////////////////////////////////////////
+static void SubBytes(unsigned char *pState, unsigned char nCount, BOOL bInvert)
+{
+	unsigned char i;
+	const unsigned char code *pSBox = bInvert ? InvSBox : SBox;
+	
+	for (i = 0; i < nCount; i++)
+	{
+		pState[i] = pSBox[pState[i]];
+	}
+}
+
+///////////////////////////////////////////////////////////////////////////////
+//	函数名:	ShiftRows
+//	描述:		把状态数据移行。
+//	输入参数:	pState	-- 状态数据。
+//				bInvert	-- 是否反向移行(解密时使用)。
+//	输出参数:	pState	-- 移行后的状态数据。
+//	返回值:	无。
+///////////////////////////////////////////////////////////////////////////////
+static void ShiftRows(unsigned char *pState, BOOL bInvert)
+{
+	// 注意:状态数据以列形式存放!
+
+	unsigned char r;	// row,   行
+	unsigned char c;	// column,列
+	unsigned char temp;
+	unsigned char rowData[4];
+	
+	for (r = 1; r < 4; r++)
+	{
+		// 备份一行数据
+		for (c = 0; c < 4; c++)
+		{
+			rowData[c] = pState[r + 4*c];
+		}
+		
+		temp = bInvert ? (4 - r) : r;
+		for (c = 0; c < 4; c++)
+		{
+			pState[r + 4*c] = rowData[(c + temp) % 4];
+		}
+	}
+}
+
+///////////////////////////////////////////////////////////////////////////////
+//	函数名:	GfMultBy02
+//	描述:		在GF(28)域的 乘2 运算。
+//	输入参数:	num	-- 乘数。
+//	输出参数:	无。
+//	返回值:	num乘以2的结果。
+///////////////////////////////////////////////////////////////////////////////
+static unsigned char GfMultBy02(unsigned char num)
+{
+	if ((num & 0x80) == 0)
+	{
+		num = num << 1;
+	}
+	else
+	{
+		num = (num << 1) ^ BPOLY;
+	}
+	
+	return num;
+}
+
+///////////////////////////////////////////////////////////////////////////////
+//	函数名:	MixColumns
+//	描述:		混合状态各列数据。
+//	输入参数:	pState	-- 状态数据。
+//				bInvert	-- 是否反向混合(解密时使用)。
+//	输出参数:	pState	-- 混合列后的状态数据。
+//	返回值:	无。
+///////////////////////////////////////////////////////////////////////////////
+static void MixColumns(unsigned char *pState, BOOL bInvert)
+{
+	unsigned char i;
+	unsigned char temp;
+	unsigned char a0Pa2_M4;	// 4(a0 + a2)
+	unsigned char a1Pa3_M4;	// 4(a1 + a3)
+	unsigned char result[4];
+
+	for (i = 0; i < 4; i++, pState += 4)
+	{
+		// b0 = 2a0 + 3a1 + a2 + a3 
+		//    = (a0 + a1 + a2 + a3) + 2(a0 + a1) + a0
+
+		temp = pState[0] ^ pState[1] ^ pState[2] ^ pState[3];
+		result[0] = temp ^ pState[0] ^ GfMultBy02((unsigned char) (pState[0] ^ pState[1]));
+		result[1] = temp ^ pState[1] ^ GfMultBy02((unsigned char) (pState[1] ^ pState[2]));
+		result[2] = temp ^ pState[2] ^ GfMultBy02((unsigned char) (pState[2] ^ pState[3]));
+		result[3] = temp ^ pState[3] ^ GfMultBy02((unsigned char) (pState[3] ^ pState[0]));
+
+		if (bInvert)
+		{
+		// b0' = 14a0 + 11a1 + 13a2 + 9a3 
+		//     = (a0 + a1 + a2 + a3) + 2(a0 + a1) + a0	(这部分为b0)
+		//       + 2(4(a0 + a2) + 4(a1 + a3))
+		//       +   4(a0 + a2)
+
+			a0Pa2_M4 = GfMultBy02(GfMultBy02((unsigned char) (pState[0] ^ pState[2])));
+			a1Pa3_M4 = GfMultBy02(GfMultBy02((unsigned char) (pState[1] ^ pState[3])));
+			temp	 = GfMultBy02((unsigned char) (a0Pa2_M4 ^ a1Pa3_M4));
+			result[0] ^= temp ^ a0Pa2_M4;
+			result[1] ^= temp ^ a1Pa3_M4;
+			result[2] ^= temp ^ a0Pa2_M4;
+			result[3] ^= temp ^ a1Pa3_M4;
+		}
+
+		memcpy(pState, result, 4);
+	}
+}
+
+///////////////////////////////////////////////////////////////////////////////
+//	函数名:	BlockEncrypt
+//	描述:		对单块数据加密。
+//	输入参数:	pState -- 状态数据。
+//	输出参数:	pState -- 加密后的状态数据。
+//	返回值:	无。
+///////////////////////////////////////////////////////////////////////////////
+static void BlockEncrypt(unsigned char *pState)
+{
+	unsigned char i;
+	
+	AddRoundKey(pState, g_roundKeyTable);
+	
+	for (i = 1; i <= Nr; i++)	// i = [1, Nr]
+	{
+		SubBytes(pState, 4*Nb, 0);
+		ShiftRows(pState, 0);
+
+		if (i != Nr)
+		{
+			MixColumns(pState, 0);
+		}
+
+		AddRoundKey(pState, &g_roundKeyTable[4*Nb*i]);
+	}
+	
+// 为了节省代码,合并到循化执行
+// 	SubBytes(pState, 4*Nb);
+//	ShiftRows(pState, 0);
+// 	AddRoundKey(pState, &g_roundKeyTable[4*Nb*Nr]);
+}
+
+///////////////////////////////////////////////////////////////////////////////
+//	函数名:	BlockDecrypt
+//	描述:		对单块数据解密。
+//	输入参数:	pState -- 状态数据。
+//	输出参数:	pState -- 解密后的状态数据。
+//	返回值:	无。
+///////////////////////////////////////////////////////////////////////////////
+static void BlockDecrypt(unsigned char *pState)
+{
+	unsigned char i;
+	
+	AddRoundKey(pState, &g_roundKeyTable[4*Nb*Nr]);
+	
+	for (i = Nr; i > 0; i--)	// i = [Nr, 1]
+	{
+		ShiftRows(pState, 1);
+		SubBytes(pState, 4*Nb, 1);
+		AddRoundKey(pState, &g_roundKeyTable[4*Nb*(i-1)]);
+
+		if (i != 1)
+		{
+			MixColumns(pState, 1);
+		}
+	}
+}
+
+
+///////////////////////////////////////////////////////////////////////////////
+//	函数名:	AES_Init
+//	描述:		初始化,在此执行扩展密钥操作。
+//	输入参数:	pKey -- 原始密钥,其长度必须为 AES_KEY_LENGTH/8 字节。
+//	输出参数:	无。
+//	返回值:	无。
+///////////////////////////////////////////////////////////////////////////////
+void AES_Init(const void *pKey)
+{
+	// 扩展密钥
+	unsigned char i;
+	unsigned char *pRoundKey;
+	unsigned char Rcon[4] = {0x01, 0x00, 0x00, 0x00};
+
+	memcpy(g_roundKeyTable, pKey, 4*Nk);
+
+	pRoundKey = &g_roundKeyTable[4*Nk];
+
+	for (i = Nk; i < Nb*(Nr+1); pRoundKey += 4, i++)
+	{
+		memcpy(pRoundKey, pRoundKey - 4, 4);
+
+		if (i % Nk == 0)
+		{
+			RotationWord(pRoundKey);
+			SubBytes(pRoundKey, 4, 0);
+			XorBytes(pRoundKey, Rcon, 4);
+
+			Rcon[0] = GfMultBy02(Rcon[0]);
+		}
+		else if (Nk > 6 && i % Nk == Nb)
+		{
+			SubBytes(pRoundKey, 4, 0);
+		}
+
+		XorBytes(pRoundKey, pRoundKey - 4*Nk, 4);
+	}
+}
+
+unsigned int AES_get_length(unsigned int length)
+{
+	return ((length>>4) + 1)<<4;
+}
+//////////////////////////////////////////////////////////////////////////
+//	函数名:	AES_Encrypt
+//	描述:		加密数据
+//	输入参数:	pPlainText	-- 明文,即需加密的数据,其长度为nDataLen字节。
+//				nDataLen	-- 数据长度,以字节为单位
+//				pIV			-- 初始化向量,如果使用ECB模式,可设为NULL。
+//	输出参数:	pCipherText	-- 密文,即由明文加密后的数据,可以与pPlainText相同。
+//	返回值:	无。
+//////////////////////////////////////////////////////////////////////////
+unsigned int AES_Encrypt_PKCS7(const unsigned char *pPlainText, unsigned char *pCipherText, 
+				 unsigned int nDataLen, const unsigned char *pIV)
+{
+	unsigned int i;
+	//长度调整
+	unsigned int length = nDataLen;
+	nDataLen = ((nDataLen>>4) + 1)<<4;
+	uint8_t p=(Nb<<2)-(length%(Nb<<2));
+	if (pPlainText != pCipherText){memcpy(pCipherText,pPlainText,length);}
+	//填充
+	unsigned char temp[16];
+	memset(temp,p,16);
+	if(length<nDataLen)
+	{
+		memcpy(pCipherText + length,temp,nDataLen - length);
+	}
+	if(length == nDataLen)
+	{
+		memcpy(pCipherText + length,temp,16);
+	}
+
+	for (i = nDataLen/(4*Nb); i > 0 ; i--, pCipherText += 4*Nb)
+	{
+		#if AES_MODE == AES_MODE_CBC
+			XorBytes(pCipherText, pIV, 4*Nb);
+		#endif
+		BlockEncrypt(pCipherText);
+		pIV = pCipherText;
+	}
+	return(nDataLen);
+}
+//////////////////////////////////////////////////////////////////////////
+//	函数名:	AES_Decrypt
+//	描述:		解密数据
+//	输入参数:	pCipherText -- 密文,即需解密的数据,其长度为nDataLen字节。
+//				nDataLen	-- 数据长度,以字节为单位,必须为AES_KEY_LENGTH/8的整倍数。
+//				pIV			-- 初始化向量,如果使用ECB模式,可设为NULL。
+//	输出参数:	pPlainText  -- 明文,即由密文解密后的数据,可以与pCipherText相同。
+//	返回值:	无。
+//////////////////////////////////////////////////////////////////////////
+void AES_Decrypt(unsigned char *pPlainText, const unsigned char *pCipherText, 
+				 unsigned int nDataLen, const unsigned char *pIV)
+{
+	unsigned int i;
+
+	if (pPlainText != pCipherText)
+	{
+		memcpy(pPlainText, pCipherText, nDataLen);
+	}
+
+	// 从最后一块数据开始解密,这样不用开辟空间来保存IV
+	pPlainText += nDataLen - 4*Nb;
+	for (i = nDataLen/(4*Nb); i > 0 ; i--, pPlainText -= 4*Nb)
+	{
+		BlockDecrypt(pPlainText);
+
+		#if AES_MODE == AES_MODE_CBC
+			if (i == 1)
+			{// 最后一块数据
+				XorBytes(pPlainText, pIV, 4*Nb);
+			}
+			else
+			{
+				XorBytes(pPlainText, pPlainText - 4*Nb, 4*Nb);
+			}
+		#endif
+	}
+}
+
+
+#endif	///WX_AIRSYNC_CFG
+

+ 97 - 8
examples/06_bluedroid_demos/components/bluedroid_demos/app_project/SampleServerProject.c

@@ -12,6 +12,8 @@
 #include <stdbool.h>
 #include <stdio.h>
 
+#include "prf_defs.h"
+
 #include "bta_api.h"
 #include "bta_gatt_api.h"
 #include "controller.h"
@@ -23,10 +25,16 @@
 #include "dis_api.h"
 #include "bt_app_common.h"
 
-//#include "app_button.h"
-//#include "button_pro.h"
+//#include "prf_defs.h"
+
+#include "wx_airsync_prf.h"
+
+#include "button_pro.h"
+
 #include "hid_le_prf.h"
-#include "prf_defs.h"
+
+//
+
 #include "hcimsgs.h"
 #include "bt_app_defs.h"
 
@@ -45,12 +53,20 @@ static unsigned char BASE_UUID[16] = {
     };
 
 UINT16 ijiazu_uuid = 0xffff;
+UINT16 wechat_uuid = 0xfee7;
 tBTA_BLE_SERVICE ijiazu_service = {
 							0x01,		//only one service in the ijiazu button profile
 							false,
 							&ijiazu_uuid
 							};        /* 16 bits services */
 
+tBTA_BLE_SERVICE wechat_service = {
+							0x01,		//only one service in the ijiazu button profile
+							false,
+							&wechat_uuid
+							};        /* 16 bits services */
+
+
 
 UINT8 beacon_manu[25] = {0x4c, 0x00,0x02, 0x15, 0xfd, 0xa5, 0x06, 0x93, 0xa4, 0xe2, 
                   0x4f, 0xb1, 0xaf, 0xcf, 0xc6, 0xeb, 0x07, 0x64, 0x78, 0x25,
@@ -58,8 +74,9 @@ UINT8 beacon_manu[25] = {0x4c, 0x00,0x02, 0x15, 0xfd, 0xa5, 0x06, 0x93, 0xa4, 0x
 
 //UINT8 ijiazu_manu[17] = {0xff,0x20,0x14,0x07,0x22,0x00,0x02,0x5B,0x00,0x33,0x49,0x31,0x30,0x4a,0x30,0x30,0x31};
 UINT8 ijiazu_manu[17] = {0xff,0x20,0x14,0x07,0x22,0x00,0x02,0x5B,0x00,0x33,0x49,0x31,0x30,0x4a,0x30,0x30,0x31};
+UINT8 wechat_manu[] = {0x00,0x00,0x18,0xfe,0x34,0x6a,0x86,0x2e};
 tBTA_BLE_MANU	p_ijiazu_manu = {sizeof(ijiazu_manu),ijiazu_manu};			/* manufacturer data */
-
+tBTA_BLE_MANU   p_wechat_manu = {sizeof(wechat_manu),wechat_manu};
 
 BD_ADDR rand_ijiazu_addr = {0x00,0x02,0x5B,0x00,0x32,0x55};
 
@@ -104,6 +121,50 @@ tESP_BLE_ADV_DATA ijiazu_adv_data[ADV_SCAN_IDX_MAX] =
 								}
 };
 
+tESP_BLE_ADV_DATA wechat_adv_data[ADV_SCAN_IDX_MAX] = 
+{
+	[BLE_ADV_DATA_IDX] 		= {
+										.adv_name = NULL,
+										{
+										{0,0},
+										NULL,			//no manufature data to be setting in the ijiazu adervetisiing datas
+										&wechat_service,
+										NULL,					//the  128 bits service uuid set to null(not used)
+										NULL,					//the 32 bits Service UUID set to null(not used)
+										NULL,					//16 bits services Solicitation UUIDs set to null(not used)
+										NULL,					//List of 32 bit Service Solicitation UUIDs set to null(not used)
+										NULL,					//List of 128 bit Service Solicitation UUIDs set to null(not used)
+										NULL,					//proprietary data set to null(not used)
+										NULL,					//service data set not null(no service data to be sent)
+										0x0200,         		//device type : generic display
+										BTA_DM_GENERAL_DISC,	// General discoverable. 
+										0xFE					//the tx power value,defult value is 0
+										},
+									
+								},
+	[BLE_SCAN_RSP_DATA_IDX] = {
+										.adv_name = "wechat_demo",	
+										{
+										{0,0},
+										&p_wechat_manu,
+										NULL,
+										NULL,					//the  128 bits service uuid set to null(not used)
+										NULL,					//the 32 bits Service UUID set to null(not used)
+										NULL,					//16 bits services Solicitation UUIDs set to null(not used)
+										NULL,					//List of 32 bit Service Solicitation UUIDs set to null(not used)
+										NULL,					//List of 128 bit Service Solicitation UUIDs set to null(not used)
+										NULL,					//proprietary data set to null(not used)
+										NULL,					//service data set not null(no service data to be sent)
+										0x0000,         		//device type : generic display
+										0x00,					// General discoverable. 
+										0x00},					//the tx power value,defult value is 0
+									
+								}
+};
+
+#if	(BUT_PROFILE_CFG)
+static void SimpleDataCallBack(UINT8 app_id, UINT8 event, UINT8 len, UINT8 *p_data);
+#endif
                   
 typedef struct {
     uint8_t uu[16];
@@ -177,13 +238,22 @@ static void bta_gatts_set_adv_data_cback(tBTA_STATUS call_status)
     DIS_SrInit(dis_attr_mask);
 */
     /*instantiate a battery service*/
-    bas_register();  
+    //bas_register();  
 	/*instantiate the driver for button profile*/
 	//app_button_init();
+#if (BUT_PROFILE_CFG)
 	/*instantiate a button service*/
-	//button_init();
+	button_init(SimpleDataCallBack);
+#endif	///BUT_PROFILE_CFG
+
+#if (HIDD_LE_PROFILE_CFG)
 	/*instantiate a hid device service*/
 	hidd_le_init();
+#endif	///HIDD_LE_PROFILE_CFG
+
+#if (WX_AIRSYNC_CFG)
+	AirSync_Init(NULL);
+#endif	///WX_AIRSYNC_CFG
     /*start advetising*/
 //    BTA_GATTS_Listen(server_if, true, NULL);
 }
@@ -202,10 +272,10 @@ void bta_gatts_callback(tBTA_GATTS_EVT event, tBTA_GATTS* p_data)
             
             LOG_ERROR("set advertising parameters\n");
 			//set the advertising data to the btm layer
-			ESP_AppBleConfigadvData(&ijiazu_adv_data[BLE_ADV_DATA_IDX],
+			ESP_AppBleConfigadvData(&wechat_adv_data[BLE_ADV_DATA_IDX],
 								bta_gatts_set_adv_data_cback);
 			//set the adversting data to the btm layer
-			ESP_AppBleSetScanRsp(&ijiazu_adv_data[BLE_SCAN_RSP_DATA_IDX],NULL);
+			ESP_AppBleSetScanRsp(&wechat_adv_data[BLE_SCAN_RSP_DATA_IDX],NULL);
            	
         }
         break;
@@ -227,6 +297,25 @@ void bta_gatts_callback(tBTA_GATTS_EVT event, tBTA_GATTS* p_data)
 
 }
 
+#if	(BUT_PROFILE_CFG)
+static void SimpleDataCallBack(UINT8 app_id, UINT8 event, UINT8 len, UINT8 *p_data)
+{
+	LOG_ERROR("the event value is:%x\n",event);
+	switch(event)
+	{
+		case RECEIVE_NET_PASSWD_EVT:
+		LOG_ERROR("Received the network passwork");
+		break;
+		case RECEIVE_NET_SSD_EVT:
+		 LOG_ERROR("Received the network SSID");
+		break;
+		default:
+		break;
+	}
+}
+#endif	///BUT_PROFILE_CFG
+
+
 static void ble_server_appRegister(void)
 {    
     bt_uuid_t uuid;

+ 3 - 2
examples/06_bluedroid_demos/components/bluedroid_demos/component.mk

@@ -12,9 +12,10 @@ COMPONENT_SRCDIRS :=	\
 			app_client_profiles/battery_c		\
 			app_client_profiles			\
 			app_profiles/app_sample_button		\
+			app_profiles/app_WX_airsync		\
 			app_profiles				\
-			app_project
-
+			app_project				
+	
 CFLAGS += -Wno-error=unused-label -Wno-error=return-type -Wno-error=missing-braces -Wno-error=pointer-sign -Wno-error=parentheses -I./include
 
 

+ 52 - 0
examples/06_bluedroid_demos/components/bluedroid_demos/include/app_airsync_md5.h

@@ -0,0 +1,52 @@
+/**
+ ****************************************************************************************
+ *
+ * @file app_airsync_md5.h
+ *
+ * @brief Application airsync md5 generation head Entry Point
+ *
+ * Copyright (C) ESPRESSIF 2016
+ * Created by Yulong at 2016/10/9
+ *
+ ****************************************************************************************
+ */
+
+#ifndef __APP_AIRSYNC_MD5__
+#define __APP_AIRSYNC_MD5__
+
+#include "prf_defs.h"
+#if (WX_AIRSYNC_CFG)
+
+
+#include <stdlib.h>
+#include <string.h>
+#include <stdio.h>
+#include <math.h>
+
+#define SINGLE_ONE_BIT 0x80
+#define BLOCK_SIZE 512
+#define MOD_SIZE 448
+#define APP_SIZE 64
+#define BITS 8
+
+// MD5 Chaining Variable
+#define A 0x67452301UL
+#define B 0xEFCDAB89UL
+#define C 0x98BADCFEUL
+#define D 0x10325476UL
+
+typedef struct
+{
+	char *str;
+	uint32_t len;
+}MD5String;
+
+
+int32_t wechat_md5 ( char *argv, uint8_t *md5_32);
+
+
+#endif	///WX_AIRSYNC_CFG
+
+#endif /// __APP_AIRSYNC_MD5__
+ 
+

+ 47 - 0
examples/06_bluedroid_demos/components/bluedroid_demos/include/app_airsync_prf.h

@@ -0,0 +1,47 @@
+/**
+ ****************************************************************************************
+ *
+ * @file app_airsync_prf.h
+ *
+ * @brief Application Security Entry Point
+ *
+ * Copyright (C) ESPRESSIF 2016
+ * Created by Yulong at 2016/9/30
+ *
+ ****************************************************************************************
+ */
+#ifndef _APP_AIRSYNC_PRF_H__
+#define _APP_AIRSYNC_PRF_H__
+
+#include "prf_defs.h"
+#if (WX_AIRSYNC_CFG)
+
+
+#include "app_wechat_util.h"
+#include <stdint.h>
+#include <stdbool.h>
+
+#define MAGIC_NUMBER	0xFE
+
+/**
+ ****************************************************************************************
+ * @brief Create Wechat Database
+ *
+ ****************************************************************************************
+ */
+void app_wechat_create_db(void);
+
+void app_wechat_SetDatahandler(data_handler* pHandler);
+int ble_wechat_indicate_data(uint8_t *data, int len);
+int ble_wechat_indicate_data_chunk(void);
+void ble_wechat_process_received_data(uint8_t* pData, uint32_t length);
+data_handler* app_wechat_datahandler(void);
+bool ble_wechat_is_last_data_sent_out(void);
+
+
+#endif	///WX_AIRSYNC_CFG
+
+#endif	///_APP_AIRSYNC_PRF_H__
+
+
+

+ 85 - 0
examples/06_bluedroid_demos/components/bluedroid_demos/include/app_wechat_util.h

@@ -0,0 +1,85 @@
+#ifndef __APP_WECHAT_UTIL_H__
+#define __APP_WECHAT_UTIL_H__
+
+#include "prf_defs.h"
+if (WX_AIRSYNC_CFG)
+#include <stdint.h>
+#include <string.h>
+
+#define PRODUCT_TYPE_UNKNOWN 0
+#define PRODUCT_TYPE_MPBLEDEMO2 1
+
+typedef void (*data_produce_func)(void *args, uint8_t **r_data, uint32_t *r_len);
+typedef void (*data_free_func)(uint8_t *data, uint32_t len);
+typedef int (*data_consume_func)(uint8_t *data, uint32_t len);
+typedef void (*data_error_func)(int error_code);
+
+typedef int32_t (*data_button_handler_func)(uint8_t pin_no);
+typedef void (*data_main_process_func)(void);
+typedef int32_t (*data_init_func)(void);
+typedef int32_t (*data_init_peripheral_func)(void);
+
+typedef struct data_handler{
+		int m_product_type;
+		data_produce_func 				m_data_produce_func;
+		data_free_func 						m_data_free_func;
+		data_consume_func 				m_data_consume_func;
+		data_error_func 					m_data_error_func;
+        data_init_peripheral_func          m_data_init_peripheral_func;
+		data_init_func 						m_data_init_func;
+		data_main_process_func 		m_data_main_process_func;
+		data_button_handler_func 	m_data_button_handler_func;
+		void *m_data_produce_args;
+		struct data_handler *next;
+} data_handler;
+
+extern data_handler first_handler;
+
+#define REGISTER(NAME)	\
+		do {								\
+				data_handler *tmp = &NAME##_data_handler;	\
+				tmp->next = first_handler.next; \
+				first_handler.next = tmp;	\
+		} while(0)
+
+#define ARGS_ITEM_SET(ARGS_TYPE, ARGS_POINTER, ITEM_NAME, ITEM_VALUE)	\
+		do {	\
+				ARGS_TYPE *tmp = (ARGS_TYPE *)(ARGS_POINTER);	\
+				tmp->ITEM_NAME = (ITEM_VALUE);	\
+		} while(0)
+
+
+typedef struct
+{
+		unsigned char bMagicNumber;
+		unsigned char bVer;
+		unsigned short nLength;
+		unsigned short nCmdId;
+		unsigned short nSeq;
+} BpFixHead;
+
+/*
+ * TYPE DEFINITIONS
+ ****************************************************************************************
+ */
+
+typedef struct
+{
+		uint8_t *data;
+		uint16_t len;
+		uint16_t offset;
+} data_info;
+
+data_handler* get_handler_by_type(int type);
+unsigned short htons(unsigned short val);
+unsigned short ntohs(unsigned short val);
+unsigned long t_htonl(unsigned long h);
+unsigned long t_ntohl(unsigned long n);
+
+void wechat_error_chack(data_handler *p_data_handler, int error_code);
+void data_handler_init(data_handler** p_data_handler, uint8_t product_type);
+
+#endif	///WX_AIRSYNC_CFG
+
+#endif	///__APP_WECHAT_UTIL_H__
+

+ 18 - 0
examples/06_bluedroid_demos/components/bluedroid_demos/include/bt_app_api.h

@@ -0,0 +1,18 @@
+/**
+ ****************************************************************************************
+ *
+ * @file bt_app_api.h
+ *
+ * @brief Application entry point
+ *
+ * Copyright (C) Espressif 2016
+ * Created by Yulong at 2016/10/13
+ *
+ *
+ ****************************************************************************************
+ */
+
+
+ 
+
+ 

+ 78 - 0
examples/06_bluedroid_demos/components/bluedroid_demos/include/bt_app_sec.h

@@ -0,0 +1,78 @@
+/**
+ ****************************************************************************************
+ *
+ * @file bt_app_sec.h
+ *
+ * @brief Application entry point
+ *
+ * Copyright (C) Espressif 2016
+ * Created by Yulong at 2016/10/13
+ *
+ *
+ ****************************************************************************************
+ */
+
+#include "bt_types.h"
+
+#define APP_SEC_IRK_FLAG        (0)
+#define RAND_NB_LEN         0x08
+#define SEC_KEY_LEN			0x10
+ 
+ /*
+  * STRUCTURES DEFINITIONS
+  ****************************************************************************************
+  */
+
+ 
+ /// Generic Security key structure
+typedef struct 
+ {
+	 /// Key value MSB -> LSB
+	 UINT8 key[SEC_KEY_LEN];
+ }smp_sec_key;
+
+ ///Random number structure
+typedef struct 
+{
+    ///8-byte array for random number
+    UINT8     nb[RAND_NB_LEN];
+}rand_nb;
+ 
+ typedef struct 
+ {
+	 // LTK
+	 smp_sec_key ltk;
+	 // Random Number
+	 rand_nb rand_nb;
+	 // EDIV
+	 UINT16 ediv;
+	 // LTK key size
+	 UINT8 key_size;
+	 
+	 // Last paired peer address type 
+	 UINT8 peer_addr_type;
+	 // Last paired peer address 
+	 BD_ADDR peer_addr;
+	 
+	 // authentication level
+	 UINT8 auth;
+ 
+ }tAPP_SEC_ENV;
+
+ extern tAPP_SEC_ENV app_sec_env;
+
+ /*
+ * GLOBAL FUNCTIONS DECLARATIONS
+ ****************************************************************************************
+ */
+
+void app_ble_sec_init(void);
+
+void app_ble_sec_pairing_cmp_evt_send(UINT8);
+
+UINT32 app_ble_sec_gen_tk(void);
+
+void app_ble_sec_gen_ltk(UINT8 key_size);
+
+void app_ble_security_start(void);
+

+ 117 - 0
examples/06_bluedroid_demos/components/bluedroid_demos/include/epb.h

@@ -0,0 +1,117 @@
+//  epb.h
+//  MicroMessenger
+//
+//  Created by harlliu@tencent.com on 14-02-15.
+//  Copyright 2014 Tencent. All rights reserved.
+//
+
+//  Version : 1.0.2
+
+#ifndef __EPB_H__
+#define __EPB_H__
+
+#include "prf_defs.h"
+#if (WX_AIRSYNC_CFG)
+
+
+#include <stdint.h>
+#include <stdbool.h>
+
+typedef struct
+{
+    uint8_t *data;
+    int len;
+} Bytes;
+
+typedef struct
+{
+    const uint8_t *data;
+    int len;
+} CBytes;
+
+typedef struct
+{
+    char *str;
+    int len;
+} String;
+
+typedef struct
+{
+    const char *str;
+    int len;
+} CString;
+
+typedef uint8_t Message;
+
+typedef struct 
+{
+    const uint8_t *unpack_buf;
+    uint8_t *pack_buf;
+    int buf_len;
+    int buf_offset;
+} Epb;
+
+/*
+ * embeded protobuf unpack functions
+ */
+
+void epb_unpack_init(Epb *e, const uint8_t *buf, int len);
+bool epb_has_tag(Epb *e, uint16_t tag);
+
+//Varint
+int32_t epb_get_int32(Epb *e, uint16_t tag);
+uint32_t epb_get_uint32(Epb *e, uint16_t tag);
+int32_t epb_get_sint32(Epb *e, uint16_t tag);
+bool epb_get_bool(Epb *e, uint16_t tag);
+int epb_get_enum(Epb *e, uint16_t tag);
+
+//Length Delimited
+const char *epb_get_string(Epb *e, uint16_t tag, int *len);
+const uint8_t *epb_get_bytes(Epb *e, uint16_t tag, int *len);
+const Message *epb_get_message(Epb *e, uint16_t tag, int *len);
+
+//Length Delimited Packed Repeadted Field
+//TODO
+
+//Fixed32
+uint32_t epb_get_fixed32(Epb *e, uint16_t tag);
+int32_t epb_get_sfixed32(Epb *e, uint16_t tag);
+float epb_get_float(Epb *e, uint16_t tag);
+
+/*
+ * embeded protobuf pack functions
+ */
+
+void epb_pack_init(Epb *e, uint8_t *buf, int len);
+int epb_get_packed_size(Epb *e);
+
+//Varint
+int epb_set_int32(Epb *e, uint16_t tag, int32_t value);
+int epb_set_uint32(Epb *e, uint16_t tag, uint32_t value);
+int epb_set_sint32(Epb *e, uint16_t tag, int32_t value);
+int epb_set_bool(Epb *e, uint16_t tag, bool value);
+int epb_set_enum(Epb *e, uint16_t tag, int value);
+
+//Length Delimited
+int epb_set_string(Epb *e, uint16_t tag, const char *data, int len);
+int epb_set_bytes(Epb *e, uint16_t tag, const uint8_t *data, int len);
+int epb_set_message(Epb *e, uint16_t tag, const Message *data, int len);
+
+//Length Delimited Packed Repeadted Field
+//TODO
+
+//Fixed32
+int epb_set_fixed32(Epb *e, uint16_t tag, uint32_t value);
+int epb_set_sfixed32(Epb *e, uint16_t tag, int32_t value);
+int epb_set_float(Epb *e, uint16_t tag, float value);
+
+//Pack size
+int epb_varint32_pack_size(uint16_t tag, uint32_t value, bool is_signed);
+int epb_fixed32_pack_size(uint16_t tag);
+int epb_length_delimited_pack_size(uint16_t tag, int len);
+
+
+#endif	///WX_AIRSYNC_CFG
+
+#endif	///__EPB_H__
+

+ 248 - 0
examples/06_bluedroid_demos/components/bluedroid_demos/include/epb_mmbp.h

@@ -0,0 +1,248 @@
+//  epb_MmBp.h
+//  WeChat Embedded Proto Buffer
+//
+//  Generated by harlliu@tencent.com on 14-11-26.
+//  Copyright 2014 Tencent. All rights reserved.
+//
+
+//  Version : 1.0.4
+
+#ifndef __EPB_MMBP_H__
+#define __EPB_MMBP_H__
+
+#include "prf_defs.h"
+#if (WX_AIRSYNC_CFG)
+
+
+#include "epb.h"
+
+typedef enum
+{
+	ECI_none = 0,
+	ECI_req_auth = 10001,
+	ECI_req_sendData = 10002,
+	ECI_req_init = 10003,
+	ECI_resp_auth = 20001,
+	ECI_resp_sendData = 20002,
+	ECI_resp_init = 20003,
+	ECI_push_recvData = 30001,
+	ECI_push_switchView = 30002,
+	ECI_push_switchBackgroud = 30003,
+	ECI_err_decode = 29999
+} EmCmdId;
+
+typedef enum
+{
+	EEC_system = -1,
+	EEC_needAuth = -2,
+	EEC_sessionTimeout = -3,
+	EEC_decode = -4,
+	EEC_deviceIsBlock = -5,
+	EEC_serviceUnAvalibleInBackground = -6,
+	EEC_deviceProtoVersionNeedUpdate = -7,
+	EEC_phoneProtoVersionNeedUpdate = -8,
+	EEC_maxReqInQueue = -9,
+	EEC_userExitWxAccount = -10
+} EmErrorCode;
+
+typedef enum
+{
+	EAM_md5 = 1,
+	EAM_macNoEncrypt = 2
+} EmAuthMethod;
+
+typedef enum
+{
+	EIRFF_userNickName = 0x1,
+	EIRFF_platformType = 0x2,
+	EIRFF_model = 0x4,
+	EIRFF_os = 0x8,
+	EIRFF_time = 0x10,
+	EIRFF_timeZone = 0x20,
+	EIRFF_timeString = 0x40
+} EmInitRespFieldFilter;
+
+typedef enum
+{
+	EIS_deviceChat = 1,
+	EIS_autoSync = 2
+} EmInitScence;
+
+typedef enum
+{
+	EPT_ios = 1,
+	EPT_andriod = 2,
+	EPT_wp = 3,
+	EPT_s60v3 = 4,
+	EPT_s60v5 = 5,
+	EPT_s40 = 6,
+	EPT_bb = 7
+} EmPlatformType;
+
+typedef enum
+{
+	EDDT_manufatureSvr = 0,
+	EDDT_wxWristBand = 1,
+	EDDT_wxDeviceHtmlChatView = 10001
+} EmDeviceDataType;
+
+typedef enum
+{
+	ESVO_enter = 1,
+	ESVO_exit = 2
+} EmSwitchViewOp;
+
+typedef enum
+{
+	EVI_deviceChatView = 1,
+	EVI_deviceChatHtmlView = 2
+} EmViewId;
+
+typedef enum
+{
+	ESBO_enterBackground = 1,
+	ESBO_enterForground = 2,
+	ESBO_sleep = 3
+} EmSwitchBackgroundOp;
+
+typedef struct
+{
+	void *none;
+} BaseRequest;
+
+typedef struct
+{
+	int32_t err_code;
+	bool has_err_msg;
+	CString err_msg;
+} BaseResponse;
+
+typedef struct
+{
+	void *none;
+} BasePush;
+
+typedef struct
+{
+	BaseRequest *base_request;
+	bool has_md5_device_type_and_device_id;
+	Bytes md5_device_type_and_device_id;
+	int32_t proto_version;
+	int32_t auth_proto;
+	EmAuthMethod auth_method;
+	bool has_aes_sign;
+	Bytes aes_sign;
+	bool has_mac_address;
+	Bytes mac_address;
+	bool has_time_zone;
+	String time_zone;
+	bool has_language;
+	String language;
+	bool has_device_name;
+	String device_name;
+} AuthRequest;
+
+typedef struct
+{
+	BaseResponse *base_response;
+	CBytes aes_session_key;
+} AuthResponse;
+
+typedef struct
+{
+	BaseRequest *base_request;
+	bool has_resp_field_filter;
+	Bytes resp_field_filter;
+	bool has_challenge;
+	Bytes challenge;
+} InitRequest;
+
+typedef struct
+{
+	BaseResponse *base_response;
+	uint32_t user_id_high;
+	uint32_t user_id_low;
+	bool has_challeange_answer;
+	uint32_t challeange_answer;
+	bool has_init_scence;
+	EmInitScence init_scence;
+	bool has_auto_sync_max_duration_second;
+	uint32_t auto_sync_max_duration_second;
+	bool has_user_nick_name;
+	CString user_nick_name;
+	bool has_platform_type;
+	EmPlatformType platform_type;
+	bool has_model;
+	CString model;
+	bool has_os;
+	CString os;
+	bool has_time;
+	int32_t time;
+	bool has_time_zone;
+	int32_t time_zone;
+	bool has_time_string;
+	CString time_string;
+} InitResponse;
+
+typedef struct
+{
+	BaseRequest *base_request;
+	Bytes data;
+	bool has_type;
+	EmDeviceDataType type;
+} SendDataRequest;
+
+typedef struct
+{
+	BaseResponse *base_response;
+	bool has_data;
+	CBytes data;
+} SendDataResponse;
+
+typedef struct
+{
+	BasePush *base_push;
+	CBytes data;
+	bool has_type;
+	EmDeviceDataType type;
+} RecvDataPush;
+
+typedef struct
+{
+	BasePush *base_push;
+	EmSwitchViewOp switch_view_op;
+	EmViewId view_id;
+} SwitchViewPush;
+
+typedef struct
+{
+	BasePush *base_push;
+	EmSwitchBackgroundOp switch_background_op;
+} SwitchBackgroudPush;
+
+BaseResponse *epb_unpack_base_response(const uint8_t *buf, int buf_len);
+void epb_unpack_base_response_free(BaseResponse *response);
+int epb_auth_request_pack_size(AuthRequest *request);
+int epb_pack_auth_request(AuthRequest *request, uint8_t *buf, int buf_len);
+AuthResponse *epb_unpack_auth_response(const uint8_t *buf, int buf_len);
+void epb_unpack_auth_response_free(AuthResponse *response);
+int epb_init_request_pack_size(InitRequest *request);
+int epb_pack_init_request(InitRequest *request, uint8_t *buf, int buf_len);
+InitResponse *epb_unpack_init_response(const uint8_t *buf, int buf_len);
+void epb_unpack_init_response_free(InitResponse *response);
+int epb_send_data_request_pack_size(SendDataRequest *request);
+int epb_pack_send_data_request(SendDataRequest *request, uint8_t *buf, int buf_len);
+SendDataResponse *epb_unpack_send_data_response(const uint8_t *buf, int buf_len);
+void epb_unpack_send_data_response_free(SendDataResponse *response);
+RecvDataPush *epb_unpack_recv_data_push(const uint8_t *buf, int buf_len);
+void epb_unpack_recv_data_push_free(RecvDataPush *push);
+SwitchViewPush *epb_unpack_switch_view_push(const uint8_t *buf, int buf_len);
+void epb_unpack_switch_view_push_free(SwitchViewPush *push);
+SwitchBackgroudPush *epb_unpack_switch_backgroud_push(const uint8_t *buf, int buf_len);
+void epb_unpack_switch_backgroud_push_free(SwitchBackgroudPush *push);
+
+
+#endif	///WX_AIRSYNC_CFG
+
+#endif	///__EPB_MMBP_H__
+

+ 140 - 0
examples/06_bluedroid_demos/components/bluedroid_demos/include/mpbledemo2.h

@@ -0,0 +1,140 @@
+
+#ifndef __MPBLEDEMO2_H__
+#define __MPBLEDEMO2_H__
+
+#include "prf_defs.h"
+
+#if	(WX_AIRSYNC_CFG)
+
+
+#include <string.h>
+#include <stdlib.h>
+#include <stdint.h>
+#include <stdio.h>
+#include <stdbool.h>
+#include "epb_MmBp.h"
+#include "app_airsync_prf.h"
+
+#define CMD_NULL    0
+#define CMD_AUTH    1
+#define CMD_INIT    2
+#define CMD_SENDDAT 3
+
+#define DEVICE_TYPE "gh_b57f1be552dd" 
+#define DEVICE_ID  "gh_b57f1be552dd_8ecc3b117f8c05112638289b0952c797" //"wechat_dialog"   
+#define PROTO_VERSION   0x010004
+#define AUTH_PROTO      1
+
+#define MAC_ADDRESS_LENGTH  6
+
+//#define EAM_md5AndNoEnrypt 1     
+#define EAM_md5AndAesEnrypt 1
+//#define EAM_macNoEncrypt 2
+
+#define DEVICE_KEY {0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f};
+
+#ifdef EAM_macNoEncrypt
+	#define AUTH_METHOD EAM_macNoEncrypt
+	#define MD5_TYPE_AND_ID_LENGTH 0
+	#define CIPHER_TEXT_LENGTH 0
+#endif
+
+#ifdef EAM_md5AndAesEnrypt
+	#define AUTH_METHOD EAM_md5AndAesEnrypt
+	#define MD5_TYPE_AND_ID_LENGTH 16
+	#define CIPHER_TEXT_LENGTH 16
+#endif
+#ifdef EAM_md5AndNoEnrypt
+	#define AUTH_METHOD             EAM_md5AndNoEnrypt
+	#define MD5_TYPE_AND_ID_LENGTH  16
+	#define CIPHER_TEXT_LENGTH      0
+#endif
+
+#define CHALLENAGE_LENGTH       4
+
+#define MPBLEDEMO2_MAGICCODE_H  0xfe
+#define MPBLEDEMO2_MAGICCODE_L  0xcf
+#define MPBLEDEMO2_VERSION      0x01
+#define SEND_HELLO_WECHAT       "Hello, WeChat!"
+
+/* Hardware Resources define */
+#define MPBLEDEMO2_LIGHT        19
+#define MPBLEDEMO2_BUTTON_1     17
+
+typedef enum
+{
+	errorCodeUnpackAuthResp             = 0x9990,
+	errorCodeUnpackInitResp             = 0x9991,
+	errorCodeUnpackSendDataResp         = 0x9992,
+	errorCodeUnpackCtlCmdResp           = 0x9993,
+	errorCodeUnpackRecvDataPush         = 0x9994,
+	errorCodeUnpackSwitchViewPush       = 0x9995,
+	errorCodeUnpackSwitchBackgroundPush = 0x9996,
+	errorCodeUnpackErrorDecode          = 0x9997,
+} mpbledemo2UnpackErrorCode;
+
+typedef enum
+{
+	errorCodeProduce = 0x9980,
+} mpbledemo2PackErrorCode;
+
+
+// command ID between device and vendor server
+typedef enum
+{
+	sendTextReq     = 0x01,
+        
+	sendTextResp    = 0x1001,
+	openLightPush   = 0x2001,
+	closeLightPush  = 0x2002,
+} BleDemo2CmdID;
+
+typedef struct
+{
+	uint8_t     m_magicCode[2];
+	uint16_t    m_version;
+	uint16_t    m_totalLength;
+	uint16_t    m_cmdid;
+	uint16_t    m_seq;
+	uint16_t    m_errorCode;
+} BlueDemoHead;
+
+typedef struct 
+{
+	int     cmd;
+	CString send_msg;
+} mpbledemo2_info;
+
+ typedef struct 
+{
+	bool wechats_switch_state; //公众账号切换到前台的状态
+	bool indication_state;
+	bool auth_state;
+	bool init_state;
+	bool auth_send;
+	bool init_send;
+	unsigned short send_data_seq;
+	unsigned short push_data_seq;
+	unsigned short seq; 
+}mpbledemo2_state;
+
+typedef void (*mpbledemo2_handler_func)(uint8_t *ptrData, uint32_t lengthInByte);
+
+typedef struct
+{
+    BleDemo2CmdID               commandCode;
+    mpbledemo2_handler_func     handler; 
+} MPBLEDEMO2_RECEIVED_CMD_HANDLER_T;
+
+extern data_handler mpbledemo2_data_handler;
+extern data_handler *m_mpbledemo2_handler;
+
+extern void mpbledemo2_reset(void);
+extern void mpbledemo2_indication_state(bool isEnable);
+extern int32_t mpbledemo2_sendData(uint8_t* ptrData, uint32_t lengthInByte);
+
+
+#endif	///WX_AIRSYNC_CFG
+
+#endif	///__MPBLEDEMO2_H__
+

+ 29 - 0
examples/06_bluedroid_demos/components/bluedroid_demos/include/wechar_crc.h

@@ -0,0 +1,29 @@
+//  crc32.h
+//  WeChat Embedded
+//
+//  Created by harlliu on 14-03-03.
+//  Copyright 2014 Tencent. All rights reserved.
+//
+
+#ifndef __CRC32_H__
+#define __CRC32_H__
+
+
+#include "prf_defs.h"
+#if (WX_AIRSYNC_CFG)
+
+#include <stdint.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+uint32_t crc32(uint32_t crc, const uint8_t *buf, int len);
+
+#ifdef __cplusplus
+}
+#endif		///__cplusplus
+
+#endif		///WX_AIRSYNC_CFG
+
+#endif	///__CRC32_H__
+

+ 73 - 0
examples/06_bluedroid_demos/components/bluedroid_demos/include/wechat_aes.h

@@ -0,0 +1,73 @@
+///////////////////////////////////////////////////////////////////////////////
+// 文 件 名:AES.h
+// 描    述:AES加密算法
+// 创 建 人:Liangbofu
+// 创建日期:2009-07-17
+///////////////////////////////////////////////////////////////////////////////
+#ifndef __WECHAT_AES_H
+#define __WECHAT_AES_H
+
+#include "prf_defs.h"
+#if (WX_AIRSYNC_CFG)
+
+#ifdef __cplusplus
+	extern "C" {
+#endif
+
+// 以bit为单位的密钥长度,只能为 128,192 和 256 三种
+#define AES_KEY_LENGTH	128
+
+// 加解密模式
+#define AES_MODE_ECB	0				// 电子密码本模式(一般模式)
+#define AES_MODE_CBC	1				// 密码分组链接模式
+#define AES_MODE		AES_MODE_CBC
+
+
+///////////////////////////////////////////////////////////////////////////////
+//	函数名:	AES_Init
+//	描述:		初始化,在此执行扩展密钥操作。
+//	输入参数:	pKey -- 原始密钥,其长度必须为 AES_KEY_LENGTH/8 字节。
+//	输出参数:	无。
+//	返回值:	无。
+///////////////////////////////////////////////////////////////////////////////
+void AES_Init(const void *pKey);
+
+//////////////////////////////////////////////////////////////////////////
+//	函数名:	AES_Encrypt
+//	描述:		加密数据
+//	输入参数:	pPlainText	-- 明文,即需加密的数据,其长度为nDataLen字节。
+//				nDataLen	-- 数据长度,以字节为单位,必须为AES_KEY_LENGTH/8的整倍数。
+//				pIV			-- 初始化向量,如果使用ECB模式,可设为NULL。
+//	输出参数:	pCipherText	-- 密文,即由明文加密后的数据,可以与pPlainText相同。
+//	返回值:	无。
+//////////////////////////////////////////////////////////////////////////
+void  AES_Encrypt(const unsigned char *pPlainText, unsigned char *pCipherText, 
+				 unsigned int nDataLen, const unsigned char *pIV);
+
+//////////////////////////////////////////////////////////////////////////
+//	函数名:	AES_Decrypt
+//	描述:		解密数据
+//	输入参数:	pCipherText -- 密文,即需解密的数据,其长度为nDataLen字节。
+//				nDataLen	-- 数据长度,以字节为单位,必须为AES_KEY_LENGTH/8的整倍数。
+//				pIV			-- 初始化向量,如果使用ECB模式,可设为NULL。
+//	输出参数:	pPlainText  -- 明文,即由密文解密后的数据,可以与pCipherText相同。
+//	返回值:	无。
+//////////////////////////////////////////////////////////////////////////
+void AES_Decrypt(unsigned char *pPlainText, const unsigned char *pCipherText, 
+				 unsigned int nDataLen, const unsigned char *pIV);
+
+//对数据进行解密操作,成功返回1,失败返回0
+unsigned char app_data_encode_aes(char *input, char *output, unsigned short *slen);
+unsigned char app_data_decode_aes(unsigned char *input, char *output, unsigned short *slen);
+unsigned int AES_Encrypt_PKCS7(const unsigned char *pPlainText, unsigned char *pCipherText, 
+				 unsigned int nDataLen, const unsigned char *pIV);
+unsigned int AES_get_length(unsigned int length);
+void AES_free(unsigned char* p);
+#ifdef __cplusplus
+	}
+#endif	///__cplusplus
+
+#endif	///WX_AIRSYNC_CFG
+
+#endif	// __WECHAT_AES_H
+