Просмотр исходного кода

component/bt: implement classic Bluetooth profiles A2DP(sink) and AVRCP(controller)

wangmengyang 8 лет назад
Родитель
Сommit
b503d68045

+ 1 - 1
components/bt/bluedroid/api/include/esp_a2dp_api.h

@@ -290,7 +290,7 @@ bool btc_a2dp_start_media_task(void)
         goto error_exit;
     }
 
-    xTaskCreatePinnedToCore(btc_media_task_handler, "BtcMediaT\n", 2048, NULL, configMAX_PRIORITIES - 1, &xBtcMediaTaskHandle, 0);
+    xTaskCreatePinnedToCore(btc_media_task_handler, "BtcMediaT\n", 2048, NULL, configMAX_PRIORITIES - 3, &xBtcMediaTaskHandle, 0);
     if (xBtcMediaTaskHandle == NULL) {
         goto error_exit;
     }

+ 0 - 2
components/bt/bluedroid/btc/profile/std/include/bt_sdp.h

@@ -5,7 +5,5 @@
 
 PROJECT_NAME := a2dp_sink
 
-COMPONENT_ADD_INCLUDEDIRS := components/include
-
 include $(IDF_PATH)/make/project.mk
 

+ 0 - 158
examples/bluetooth/a2dp_sink/components/bt_app/app_project/SampleAV.c

@@ -1,158 +0,0 @@
-#include <stdint.h>
-#include <stdbool.h>
-#include <stdlib.h>
-#include <string.h>
-#include "freertos/FreeRTOS.h"
-#include "freertos/task.h"
-#include "freertos/timers.h"
-#include "esp_system.h"
-#include "bt_app_common.h"
-#include "esp_bt_main.h"
-#include "esp_bt_device.h"
-#include "esp_gap_bt_api.h"
-#include "esp_a2dp_api.h"
-#include "esp_avrc_api.h"
-
-
-
-typedef enum {
-    BT_APP_EVT_STACK_ON = 0xa0,
-    BT_APP_EVT_MAX
-} bt_app_evt_t;
-
-typedef union {
-    esp_a2d_cb_param_t a2d;
-    esp_avrc_ct_cb_event_t rc;
-} bt_app_evt_arg;
-
-
-static uint32_t m_pkt_cnt = 0;
-static esp_a2d_audio_state_t m_audio_state = ESP_A2D_AUDIO_STATE_STOPPED;
-
-static void bt_app_handle_evt(uint16_t event, void *p_param);
-static void bt_app_handle_rc_evt(uint16_t event, void *p_param);
-static void bt_app_a2d_cb(esp_a2d_cb_event_t event, esp_a2d_cb_param_t *param);
-static void bt_app_a2d_data_cb(const uint8_t *data, uint32_t len);
-static void bt_app_rc_ct_cb(esp_avrc_ct_cb_event_t event, esp_avrc_ct_cb_param_t *param);
-static void bt_app_handle_evt(uint16_t event, void *p_param);
-
-static void bt_app_a2d_cb(esp_a2d_cb_event_t event, esp_a2d_cb_param_t *param)
-{
-    switch (event) {
-    case ESP_A2D_CONNECTION_STATE_EVT:
-    case ESP_A2D_AUDIO_STATE_EVT:
-    case ESP_A2D_AUDIO_CFG_EVT: {
-        bt_app_transfer_context(bt_app_handle_evt, event, param, sizeof(bt_app_evt_arg), NULL);
-        break;
-    }
-    default:
-        BT_APP_TRACE_ERROR("===a2dp invalid cb event: %d===\n", event);
-        break;
-    }
-}
-
-static void bt_app_a2d_data_cb(const uint8_t *data, uint32_t len)
-{
-    if (++m_pkt_cnt % 100 == 0) {
-        BT_APP_TRACE_ERROR("audio data pkt cnt %u\n", m_pkt_cnt);
-    }
-}
-
-static void bt_app_rc_ct_cb(esp_avrc_ct_cb_event_t event, esp_avrc_ct_cb_param_t *param)
-{
-    switch (event) {
-    case ESP_AVRC_CT_CONNECTION_STATE_EVT:
-    case ESP_AVRC_CT_PASSTHROUGH_RSP_EVT: {
-        bt_app_transfer_context(bt_app_handle_rc_evt, event, param, sizeof(bt_app_evt_arg), NULL);
-        break;
-    }
-    default:
-        BT_APP_TRACE_ERROR("===a2dp invalid cb event: %d===\n", event);
-        break;
-    }
-}
-
-static void bt_app_handle_evt(uint16_t event, void *p_param)
-{
-    BT_APP_TRACE_DEBUG("===bt_app_handle_evt 0x%x===\n", event);
-    esp_a2d_cb_param_t *a2d = NULL;
-    switch (event) {
-    case BT_APP_EVT_STACK_ON: {
-        char *dev_name = "ESP_SPEAKER";
-
-        esp_bt_dev_set_device_name(dev_name);
-
-        esp_a2d_register_callback(&bt_app_a2d_cb);
-        esp_a2d_register_data_callback(bt_app_a2d_data_cb);
-
-        esp_a2d_sink_init();
-
-        esp_avrc_ct_init();
-        esp_avrc_ct_register_callback(bt_app_rc_ct_cb);
-
-        esp_bt_gap_set_scan_mode(ESP_BT_SCAN_MODE_CONNECTABLE_DISCOVERABLE);
-        break;
-    }
-    case ESP_A2D_CONNECTION_STATE_EVT: {
-        a2d = (esp_a2d_cb_param_t *)(p_param);
-        BT_APP_TRACE_EVENT("===a2dp conn_state_cb %d ===\n", a2d->conn_stat.state);
-        break;
-    }
-    case ESP_A2D_AUDIO_STATE_EVT: {
-        a2d = (esp_a2d_cb_param_t *)(p_param);
-        BT_APP_TRACE_EVENT("===a2dp audio_state_cb %d===\n", a2d->audio_stat.state);
-        m_audio_state = a2d->audio_stat.state;
-        break;
-    }
-    case ESP_A2D_AUDIO_CFG_EVT: {
-        a2d = (esp_a2d_cb_param_t *)(p_param);
-        BT_APP_TRACE_EVENT("===a2dp audio_cfg_cb type %d===\n", a2d->audio_cfg.mcc.type);
-        // for now only SBC stream is supported
-        if (a2d->audio_cfg.mcc.type == ESP_A2D_MCT_SBC) {
-            BT_APP_TRACE_EVENT("configure audio player\n");
-        }
-        break;
-    }
-    default:
-        BT_APP_TRACE_ERROR("===application invalid event: %d===\n", event);
-        break;
-    }
-
-}
-
-void bt_app_handle_rc_evt(uint16_t event, void *p_param)
-{
-    BT_APP_TRACE_DEBUG("bt_app_handle_avrc_evt 0x%x\n", event);
-    esp_avrc_ct_cb_param_t *rc = (esp_avrc_ct_cb_param_t *)(p_param);
-    switch (event) {
-    case ESP_AVRC_CT_CONNECTION_STATE_EVT: {
-        uint8_t *bda = rc->conn_stat.remote_bda;
-        BT_APP_TRACE_EVENT("===avrc conn_state evt: state %d, feature 0x%x, [%02x:%02x:%02x:%02x:%02x:%02x]===\n",
-                           rc->conn_stat.connected, rc->conn_stat.feat_mask, bda[0], bda[1], bda[2], bda[3], bda[4], bda[5]);
-        break;
-    }
-    case ESP_AVRC_CT_PASSTHROUGH_RSP_EVT: {
-        BT_APP_TRACE_EVENT("===avrc passthrough rsp: key_code 0x%x, key_state %d===\n", rc->psth_rsp.key_code, rc->psth_rsp.key_state);
-        break;
-    }
-    default:
-        BT_APP_TRACE_ERROR("===application invalid event: %d===\n", event);
-        break;
-    }
-}
-
-void app_main_entry(void)
-{
-    esp_err_t init, enable;
-    init = esp_bluedroid_init();
-    if (init != ESP_OK) {
-        return;
-    }
-
-    enable = esp_bluedroid_enable();
-    if (enable != ESP_OK) {
-        return;
-    }
-
-    bt_app_transfer_context(bt_app_handle_evt, BT_APP_EVT_STACK_ON, NULL, 0, NULL);
-}

+ 0 - 21
examples/bluetooth/a2dp_sink/components/bt_app/component.mk

@@ -1,21 +0,0 @@
-#
-# Main Makefile. This is basically the same as a component makefile.
-#
-# This Makefile should, at the very least, just include $(SDK_PATH)/make/component_common.mk. By default, 
-# this will take the sources in the src/ directory, compile them and link them into 
-# lib(subdirectory_name).a in the build directory. This behaviour is entirely configurable,
-# please read the ESP-IDF documents if you need to do this.
-#
-
-COMPONENT_ADD_INCLUDEDIRS :=	\
-				include
-
-COMPONENT_SRCDIRS :=	\
-			app_core				\
-			app_project
-
-
-CFLAGS += -Wno-error=unused-label -Wno-error=return-type -Wno-error=missing-braces -Wno-error=pointer-sign -Wno-error=parentheses -I./include
-
-
-#include $(IDF_PATH)/make/component_common.mk

+ 0 - 44
examples/bluetooth/a2dp_sink/components/bt_app/include/bt_app_common.h

@@ -1,44 +0,0 @@
-#ifndef __BT_APP_COMMON_H__
-#define __BT_APP_COMMON_H__
-
-#include <stdint.h>
-#include <stdbool.h>
-#include <stdio.h>
-
-#define BT_APP_TRACE_LEVEL_NONE    0          /* No trace messages to be generated    */
-#define BT_APP_TRACE_LEVEL_ERROR   1          /* Error condition trace messages       */
-#define BT_APP_TRACE_LEVEL_WARNING 2          /* Warning condition trace messages     */
-#define BT_APP_TRACE_LEVEL_API     3          /* API traces                           */
-#define BT_APP_TRACE_LEVEL_EVENT   4          /* Debug messages for events            */
-#define BT_APP_TRACE_LEVEL_DEBUG   5          /* Full debug messages                  */
-#define BT_APP_TRACE_LEVEL_VERBOSE 6          /* Verbose debug messages               */
-
-#define BT_APP_PRINTF      printf
-
-extern int bt_app_trace_level;
-
-#define BT_APP_TRACE_ERROR(fmt, args...)       {if (bt_app_trace_level >= BT_APP_TRACE_LEVEL_ERROR) BT_APP_PRINTF(fmt, ## args);}
-#define BT_APP_TRACE_WARNING(fmt, args...)     {if (bt_app_trace_level >= BT_APP_TRACE_LEVEL_WARNING) BT_APP_PRINTF(fmt, ## args);}
-#define BT_APP_TRACE_API(fmt, args...)         {if (bt_app_trace_level >= BT_APP_TRACE_LEVEL_API) BT_APP_PRINTF(fmt, ## args);}
-#define BT_APP_TRACE_EVENT(fmt, args...)       {if (bt_app_trace_level >= BT_APP_TRACE_LEVEL_EVENT) BT_APP_PRINTF(fmt, ## args);}
-#define BT_APP_TRACE_DEBUG(fmt, args...)       {if (bt_app_trace_level >= BT_APP_TRACE_LEVEL_DEBUG) BT_APP_PRINTF(fmt, ## args);}
-
-#define BT_APP_SIG_CONTEXT_SWITCH         (0x90)
-
-typedef void (* bt_app_cb_t) (uint16_t event, void *param);
-/* context switch message */
-typedef struct {
-    uint16_t             sig;      /* signal to bt_app_task */
-    uint16_t             event;    /* message event id */
-    bt_app_cb_t          cb;       /* context switch callback */
-    void                 *param;   /* parameter area needs to be last */
-} bt_app_msg_t;
-
-typedef void (* bt_app_copy_cb_t) (bt_app_msg_t *msg, void *p_dest, void *p_src);
-
-bool bt_app_transfer_context (bt_app_cb_t p_cback, uint16_t event, void *p_params, int param_len, bt_app_copy_cb_t p_copy_cback);
-
-void bt_app_task_start_up(void);
-
-void bt_app_task_shut_down(void);
-#endif /* __BT_APP_COMMON_H__ */

+ 0 - 22
examples/bluetooth/a2dp_sink/gen_misch.sh

@@ -1,22 +0,0 @@
-set -e
-export IDF_PATH=$(pwd)/../../esp-idf
-echo "----------------------"
-echo "PLease Check IDF_PATH"
-echo "IDF_PATH"
-echo $IDF_PATH 
-echo "---------------------"
-
-# make bootloader
-# make partitio
-#make clean
-make
-
-
-echo "------------------------------"
-echo "the testje_bin copy to bin "
-echo "the bootloader_bin copy to bin"
-echo "the partication_bin copy to bin"
-echo "--------------------------------"
-cp ./build/bluedroid_demos.bin ../bin/
-cp ./build/bootloader/bootloader.bin ../bin
-cp ./build/partitions_singleapp.bin ../bin

+ 128 - 0
examples/bluetooth/a2dp_sink/main/bt_app_av.c

@@ -0,0 +1,128 @@
+// 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 <stdint.h>
+#include <stdbool.h>
+#include <stdlib.h>
+#include <string.h>
+#include "esp_log.h"
+
+#include "bt_app_core.h"
+#include "bt_app_av.h"
+#include "esp_bt_main.h"
+#include "esp_bt_device.h"
+#include "esp_gap_bt_api.h"
+#include "esp_a2dp_api.h"
+#include "esp_avrc_api.h"
+
+/* a2dp event handler */
+static void bt_av_hdl_a2d_evt(uint16_t event, void *p_param);
+/* avrc event handler */
+static void bt_av_hdl_avrc_evt(uint16_t event, void *p_param);
+
+
+static uint32_t m_pkt_cnt = 0;
+static esp_a2d_audio_state_t m_audio_state = ESP_A2D_AUDIO_STATE_STOPPED;
+
+/* callback for A2DP sink */
+void bt_app_a2d_cb(esp_a2d_cb_event_t event, esp_a2d_cb_param_t *param)
+{
+    switch (event) {
+    case ESP_A2D_CONNECTION_STATE_EVT:
+    case ESP_A2D_AUDIO_STATE_EVT:
+    case ESP_A2D_AUDIO_CFG_EVT: {
+        bt_app_work_dispatch(bt_av_hdl_a2d_evt, event, param, sizeof(esp_a2d_cb_param_t), NULL);
+        break;
+    }
+    default:
+        ESP_LOGE(BT_AV_TAG, "a2dp invalid cb event: %d", event);
+        break;
+    }
+}
+
+void bt_app_a2d_data_cb(const uint8_t *data, uint32_t len)
+{
+    if (++m_pkt_cnt % 100 == 0) {
+        ESP_LOGE(BT_AV_TAG, "audio data pkt cnt %u", m_pkt_cnt);
+    }
+}
+
+void bt_app_rc_ct_cb(esp_avrc_ct_cb_event_t event, esp_avrc_ct_cb_param_t *param)
+{
+    switch (event) {
+    case ESP_AVRC_CT_CONNECTION_STATE_EVT:
+    case ESP_AVRC_CT_PASSTHROUGH_RSP_EVT: {
+        bt_app_work_dispatch(bt_av_hdl_avrc_evt, event, param, sizeof(esp_avrc_ct_cb_param_t), NULL);
+        break;
+    }
+    default:
+        ESP_LOGE(BT_AV_TAG, "avrc invalid cb event: %d", event);
+        break;
+    }
+}
+
+static void bt_av_hdl_a2d_evt(uint16_t event, void *p_param)
+{
+    ESP_LOGD(BT_AV_TAG, "%s evt %d", __func__, event);
+    esp_a2d_cb_param_t *a2d = NULL;
+    switch (event) {
+    case ESP_A2D_CONNECTION_STATE_EVT: {
+        a2d = (esp_a2d_cb_param_t *)(p_param);
+        ESP_LOGI(BT_AV_TAG, "a2dp conn_state_cb, state %d", a2d->conn_stat.state);
+        break;
+    }
+    case ESP_A2D_AUDIO_STATE_EVT: {
+        a2d = (esp_a2d_cb_param_t *)(p_param);
+        ESP_LOGI(BT_AV_TAG, "a2dp audio_state_cb state %d", a2d->audio_stat.state);
+        m_audio_state = a2d->audio_stat.state;
+        if (ESP_A2D_AUDIO_STATE_STARTED == a2d->audio_stat.state) {
+            m_pkt_cnt = 0;
+        }
+        break;
+    }
+    case ESP_A2D_AUDIO_CFG_EVT: {
+        a2d = (esp_a2d_cb_param_t *)(p_param);
+        ESP_LOGI(BT_AV_TAG, "a2dp audio_cfg_cb , codec type %d", a2d->audio_cfg.mcc.type);
+        // for now only SBC stream is supported
+        if (a2d->audio_cfg.mcc.type == ESP_A2D_MCT_SBC) {
+            ESP_LOGI(BT_AV_TAG, "audio player configured");
+        }
+        break;
+    }
+    default:
+        ESP_LOGE(BT_AV_TAG, "%s unhandled evt %d", __func__, event);
+        break;
+    }
+}
+
+static void bt_av_hdl_avrc_evt(uint16_t event, void *p_param)
+{
+    ESP_LOGD(BT_AV_TAG, "%s evt %d", __func__, event);
+    esp_avrc_ct_cb_param_t *rc = (esp_avrc_ct_cb_param_t *)(p_param);
+    switch (event) {
+    case ESP_AVRC_CT_CONNECTION_STATE_EVT: {
+        uint8_t *bda = rc->conn_stat.remote_bda;
+        ESP_LOGI(BT_AV_TAG, "avrc conn_state evt: state %d, feature 0x%x, [%02x:%02x:%02x:%02x:%02x:%02x]",
+                           rc->conn_stat.connected, rc->conn_stat.feat_mask, bda[0], bda[1], bda[2], bda[3], bda[4], bda[5]);
+        break;
+    }
+    case ESP_AVRC_CT_PASSTHROUGH_RSP_EVT: {
+        ESP_LOGI(BT_AV_TAG, "avrc passthrough rsp: key_code 0x%x, key_state %d", rc->psth_rsp.key_code, rc->psth_rsp.key_state);
+        break;
+    }
+    default:
+        ESP_LOGE(BT_AV_TAG, "%s unhandled evt %d", __func__, event);
+        break;
+    }
+}

+ 39 - 0
examples/bluetooth/a2dp_sink/main/bt_app_av.h

@@ -0,0 +1,39 @@
+// 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.
+
+#ifndef __BT_APP_AV_H__
+#define __BT_APP_AV_H__
+
+#include <stdint.h>
+#include "esp_a2dp_api.h"
+#include "esp_avrc_api.h"
+
+#define BT_AV_TAG               "BT_AV"
+
+/**
+ * @brief     callback function for A2DP sink
+ */
+void bt_app_a2d_cb(esp_a2d_cb_event_t event, esp_a2d_cb_param_t *param);
+
+/**
+ * @brief     callback function for A2DP sink audio data stream
+ */
+void bt_app_a2d_data_cb(const uint8_t *data, uint32_t len);
+
+/**
+ * @brief     callback function for AVRCP controller
+ */
+void bt_app_rc_ct_cb(esp_avrc_ct_cb_event_t event, esp_avrc_ct_cb_param_t *param);
+
+#endif /* __BT_APP_AV_H__*/

+ 31 - 22
examples/bluetooth/a2dp_sink/components/bt_app/app_core/bt_app_main.c → examples/bluetooth/a2dp_sink/main/bt_app_core.c

@@ -1,37 +1,48 @@
+// 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 <stdint.h>
 #include <string.h>
 #include <stdbool.h>
-
-#include "bt_app_common.h"
 #include "freertos/xtensa_api.h"
 #include "freertos/FreeRTOSConfig.h"
 #include "freertos/FreeRTOS.h"
 #include "freertos/queue.h"
 #include "freertos/task.h"
+#include "esp_log.h"
+#include "bt_app_core.h"
 
-int bt_app_trace_level = BT_APP_TRACE_LEVEL_DEBUG;
-
-static bool bt_app_post_msg(bt_app_msg_t *msg);
-static void bt_app_context_switched(bt_app_msg_t *msg);
 static void bt_app_task_handler(void *arg);
-extern void app_main_entry(void);
+static bool bt_app_send_msg(bt_app_msg_t *msg);
+static void bt_app_work_dispatched(bt_app_msg_t *msg);
 
 static xQueueHandle bt_app_task_queue = NULL;
 static xTaskHandle bt_app_task_handle = NULL;
 
-bool bt_app_transfer_context (bt_app_cb_t p_cback, uint16_t event, void *p_params, int param_len, bt_app_copy_cb_t p_copy_cback)
+bool bt_app_work_dispatch(bt_app_cb_t p_cback, uint16_t event, void *p_params, int param_len, bt_app_copy_cb_t p_copy_cback)
 {
+    ESP_LOGD(BT_APP_CORE_TAG, "%s event 0x%x, param len %d", __func__, event, param_len);
+    
     bt_app_msg_t msg;
-
     memset(&msg, 0, sizeof(bt_app_msg_t));
-    BT_APP_TRACE_EVENT("btapp_transfer_context evt 0x%x, len %d\n", event, param_len);
 
-    msg.sig = BT_APP_SIG_CONTEXT_SWITCH;
+    msg.sig = BT_APP_SIG_WORK_DISPATCH;
     msg.event = event;
     msg.cb = p_cback;
 
     if (param_len == 0) {
-        return bt_app_post_msg(&msg);
+        return bt_app_send_msg(&msg);
     } else if (p_params && param_len > 0) {
         if ((msg.param = malloc(param_len)) != NULL) {
             memcpy(msg.param, p_params, param_len);
@@ -39,29 +50,28 @@ bool bt_app_transfer_context (bt_app_cb_t p_cback, uint16_t event, void *p_param
             if (p_copy_cback) {
                 p_copy_cback(&msg, msg.param, p_params);
             }
-            return bt_app_post_msg(&msg);
+            return bt_app_send_msg(&msg);
         }
     }
 
     return false;
 }
 
-static bool bt_app_post_msg(bt_app_msg_t *msg)
+static bool bt_app_send_msg(bt_app_msg_t *msg)
 {
     if (msg == NULL) {
         return false;
     }
 
     if (xQueueSend(bt_app_task_queue, msg, 10 / portTICK_RATE_MS) != pdTRUE) {
-        BT_APP_TRACE_ERROR("bt_app msg post failed\n");
+        ESP_LOGE(BT_APP_CORE_TAG, "%s xQueue send failed", __func__);
         return false;
     }
     return true;
 }
 
-static void bt_app_context_switched(bt_app_msg_t *msg)
+static void bt_app_work_dispatched(bt_app_msg_t *msg)
 {
-    BT_APP_TRACE_DEBUG("bt app context switched\n");
     if (msg->cb) {
         msg->cb(msg->event, msg->param);
     }
@@ -69,17 +79,16 @@ static void bt_app_context_switched(bt_app_msg_t *msg)
 
 static void bt_app_task_handler(void *arg)
 {
-    app_main_entry();
     bt_app_msg_t msg;
     for (;;) {
         if (pdTRUE == xQueueReceive(bt_app_task_queue, &msg, (portTickType)portMAX_DELAY)) {
-            BT_APP_TRACE_EVENT("btapp handle evt, sig 0x%x, 0x%x\n", msg.sig, msg.event);
+            ESP_LOGD(BT_APP_CORE_TAG, "%s, sig 0x%x, 0x%x", __func__, msg.sig, msg.event);
             switch (msg.sig) {
-            case BT_APP_SIG_CONTEXT_SWITCH:
-                bt_app_context_switched(&msg);
+            case BT_APP_SIG_WORK_DISPATCH:
+                bt_app_work_dispatched(&msg);
                 break;
             default:
-                BT_APP_TRACE_WARNING("unhandled BT_APP event (%d)\n", msg.sig);
+                ESP_LOGW(BT_APP_CORE_TAG, "%s, unhandled sig: %d", __func__, msg.sig);
                 break;
             } // switch (msg.sig)
 

+ 53 - 0
examples/bluetooth/a2dp_sink/main/bt_app_core.h

@@ -0,0 +1,53 @@
+// 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.
+
+#ifndef __BT_APP_CORE_H__
+#define __BT_APP_CORE_H__
+
+#include <stdint.h>
+#include <stdbool.h>
+#include <stdio.h>
+
+#define BT_APP_CORE_TAG                   "BT_APP_CORE"
+
+#define BT_APP_SIG_WORK_DISPATCH          (0x01)
+
+/**
+ * @brief     handler for the dispatched work
+ */
+typedef void (* bt_app_cb_t) (uint16_t event, void *param);
+
+/* message to be sent */
+typedef struct {
+    uint16_t             sig;      /*!< signal to bt_app_task */
+    uint16_t             event;    /*!< message event id */
+    bt_app_cb_t          cb;       /*!< context switch callback */
+    void                 *param;   /*!< parameter area needs to be last */
+} bt_app_msg_t;
+
+/**
+ * @brief     parameter deep-copy function to be customized
+ */
+typedef void (* bt_app_copy_cb_t) (bt_app_msg_t *msg, void *p_dest, void *p_src);
+
+/**
+ * @brief     work dispatcher for the application task
+ */
+bool bt_app_work_dispatch(bt_app_cb_t p_cback, uint16_t event, void *p_params, int param_len, bt_app_copy_cb_t p_copy_cback);
+
+void bt_app_task_start_up(void);
+
+void bt_app_task_shut_down(void);
+
+#endif /* __BT_APP_CORE_H__ */

+ 2 - 7
examples/bluetooth/a2dp_sink/main/component.mk

@@ -1,10 +1,5 @@
 #
-# Main Makefile. This is basically the same as a component makefile.
-#
-# This Makefile should, at the very least, just include $(SDK_PATH)/make/component_common.mk. By default, 
-# this will take the sources in the src/ directory, compile them and link them into 
-# lib(subdirectory_name).a in the build directory. This behaviour is entirely configurable,
-# please read the ESP-IDF documents if you need to do this.
+# "main" pseudo-component makefile.
 #
+# (Uses default behaviour of compiling all source files in directory, adding 'include' to include path.)
 
-#include $(IDF_PATH)/make/component_common.mk

+ 0 - 38
examples/bluetooth/a2dp_sink/main/demo_main.c

@@ -1,38 +0,0 @@
-#include <stdio.h>
-#include <stdlib.h>
-#include <unistd.h>
-#include <string.h>
-#include "bt.h"
-#include "freertos/FreeRTOS.h"
-#include "freertos/task.h"
-
-#include "nvs_flash.h"
-#include "esp_system.h"
-#include "esp_log.h"
-
-#define A2DP_SINK_TAG    "A2DP_SINK"
-
-extern void bte_main_boot_entry(void *);
-extern void bt_app_task_start_up(void);
-extern void bt_app_core_start(void);
-
-void app_main()
-{
-    esp_err_t ret;
-    nvs_flash_init();
-
-    esp_bt_controller_config_t bt_cfg = BT_CONTROLLER_INIT_CONFIG_DEFAULT();
-    ret = esp_bt_controller_init(&bt_cfg);
-    if (ret) {
-        ESP_LOGE(A2DP_SINK_TAG, "%s initialize controller failed\n", __func__);
-        return;
-    }
-
-    ret = esp_bt_controller_enable(ESP_BT_MODE_BTDM);
-    if (ret) {
-        ESP_LOGE(A2DP_SINK_TAG, "%s enable controller failed\n", __func__);
-        return;
-    }
-    
-    bt_app_task_start_up();
-}

+ 103 - 0
examples/bluetooth/a2dp_sink/main/main.c

@@ -0,0 +1,103 @@
+// 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 <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <string.h>
+#include "freertos/FreeRTOS.h"
+#include "freertos/task.h"
+#include "nvs.h"
+#include "nvs_flash.h"
+#include "esp_system.h"
+#include "esp_log.h"
+
+#include "bt.h"
+#include "bt_app_core.h"
+#include "bt_app_av.h"
+#include "esp_bt_main.h"
+#include "esp_bt_device.h"
+#include "esp_gap_bt_api.h"
+#include "esp_a2dp_api.h"
+#include "esp_avrc_api.h"
+
+/* event for handler "bt_av_hdl_stack_up */
+enum {
+    BT_APP_EVT_STACK_UP = 0,
+};
+
+/* handler for bluetooth stack enabled events */
+static void bt_av_hdl_stack_evt(uint16_t event, void *p_param);
+
+
+void app_main()
+{
+    nvs_flash_init();
+
+    esp_bt_controller_config_t bt_cfg = BT_CONTROLLER_INIT_CONFIG_DEFAULT();
+    if (esp_bt_controller_init(&bt_cfg) != ESP_OK) {
+        ESP_LOGE(BT_AV_TAG, "%s initialize controller failed\n", __func__);
+        return;
+    }
+
+    if (esp_bt_controller_enable(ESP_BT_MODE_BTDM) != ESP_OK) {
+        ESP_LOGE(BT_AV_TAG, "%s enable controller failed\n", __func__);
+        return;
+    }
+
+    if (esp_bluedroid_init() != ESP_OK) {
+        ESP_LOGE(BT_AV_TAG, "%s initialize bluedroid failed\n", __func__);
+        return;
+    }
+
+    if (esp_bluedroid_enable() != ESP_OK) {
+        ESP_LOGE(BT_AV_TAG, "%s enable bluedroid failed\n", __func__);
+        return;
+    }
+
+    /* create application task */
+    bt_app_task_start_up();
+
+    /* Bluetooth device name, connection mode and profile set up */
+    bt_app_work_dispatch(bt_av_hdl_stack_evt, BT_APP_EVT_STACK_UP, NULL, 0, NULL);
+}
+
+
+static void bt_av_hdl_stack_evt(uint16_t event, void *p_param)
+{
+    ESP_LOGD(BT_AV_TAG, "%s evt %d", __func__, event);
+    switch (event) {
+    case BT_APP_EVT_STACK_UP: {
+        /* set up device name */
+        char *dev_name = "ESP_SPEAKER";
+        esp_bt_dev_set_device_name(dev_name);
+
+        /* initialize A2DP sink */
+        esp_a2d_register_callback(&bt_app_a2d_cb);
+        esp_a2d_register_data_callback(bt_app_a2d_data_cb);
+        esp_a2d_sink_init();
+
+        /* initialize AVRCP controller */
+        esp_avrc_ct_init();
+        esp_avrc_ct_register_callback(bt_app_rc_ct_cb);
+
+        /* set discoverable and connectable mode, wait to be connected */
+        esp_bt_gap_set_scan_mode(ESP_BT_SCAN_MODE_CONNECTABLE_DISCOVERABLE);
+        break;
+    }
+    default:
+        ESP_LOGE(BT_AV_TAG, "%s unhandled evt %d", __func__, event);
+        break;
+    }
+}

+ 1 - 1
tools/unit-test-app/tools/UnitTestParser.py

@@ -76,7 +76,7 @@ class Parser(object):
                     if tc["test environment"] in self.test_env_tags:
                         self.test_env_tags[tc["test environment"]].append(tc["ID"])
                     else:
-                        self.test_env_tags.update({tc["test environment"]: [tc]})
+                        self.test_env_tags.update({tc["test environment"]: [tc["ID"]]})
                 test_cases.append(tc)
 
         os.remove("section_table.tmp")