]> granicus.if.org Git - esp-idf/blob - components/bt/bluedroid/btc/core/btc_task.c
Merge branch 'bugfix/spiram_malloc_reserve_internal_fragments' into 'master'
[esp-idf] / components / bt / bluedroid / btc / core / btc_task.c
1 // Copyright 2015-2016 Espressif Systems (Shanghai) PTE LTD
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6
7 //     http://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
14
15 #include <stdlib.h>
16 #include <string.h>
17 #include "common/bt_target.h"
18 #include "btc/btc_task.h"
19 #include "common/bt_trace.h"
20 #include "osi/thread.h"
21 #include "common/bt_defs.h"
22 #include "osi/allocator.h"
23 #include "btc/btc_main.h"
24 #include "btc/btc_dev.h"
25 #include "btc_gatts.h"
26 #include "btc_gattc.h"
27 #include "btc_gatt_common.h"
28 #include "btc_gap_ble.h"
29 #include "btc_blufi_prf.h"
30 #include "btc/btc_dm.h"
31 #include "btc/btc_alarm.h"
32 #include "bta/bta_gatt_api.h"
33 #if CONFIG_CLASSIC_BT_ENABLED
34 #include "btc/btc_profile_queue.h"
35 #if (BTC_GAP_BT_INCLUDED == TRUE)
36 #include "btc_gap_bt.h"
37 #endif /* BTC_GAP_BT_INCLUDED == TRUE */
38 #if BTC_AV_INCLUDED
39 #include "btc_av.h"
40 #include "btc_avrc.h"
41 #endif /* #if BTC_AV_INCLUDED */
42 #if CONFIG_BT_SPP_ENABLED
43 #include "btc_spp.h"
44 #endif /* #if CONFIG_BT_SPP_ENABLED */
45 #if BTC_HF_CLIENT_INCLUDED
46 #include "btc_hf_client.h"
47 #endif  /* #if BTC_HF_CLIENT_INCLUDED */
48 #endif /* #if CONFIG_CLASSIC_BT_ENABLED */
49
50
51 static xTaskHandle  xBtcTaskHandle = NULL;
52 static xQueueHandle xBtcQueue = 0;
53
54 static btc_func_t profile_tab[BTC_PID_NUM] = {
55     [BTC_PID_MAIN_INIT]   = {btc_main_call_handler,       NULL                    },
56     [BTC_PID_DEV]         = {btc_dev_call_handler,        NULL                    },
57 #if (GATTS_INCLUDED == TRUE)
58     [BTC_PID_GATTS]       = {btc_gatts_call_handler,      btc_gatts_cb_handler    },
59 #endif  ///GATTS_INCLUDED == TRUE
60 #if (GATTC_INCLUDED == TRUE)
61     [BTC_PID_GATTC]       = {btc_gattc_call_handler,      btc_gattc_cb_handler    },
62 #endif  ///GATTC_INCLUDED == TRUE
63 #if (GATTS_INCLUDED == TRUE || GATTC_INCLUDED == TRUE)
64     [BTC_PID_GATT_COMMON] = {btc_gatt_com_call_handler,   NULL                    },
65 #endif //GATTC_INCLUDED == TRUE || GATTS_INCLUDED == TRUE
66     [BTC_PID_GAP_BLE]     = {btc_gap_ble_call_handler,    btc_gap_ble_cb_handler  },
67     [BTC_PID_BLE_HID]     = {NULL, NULL},
68     [BTC_PID_SPPLIKE]     = {NULL, NULL},
69 #if (GATTS_INCLUDED == TRUE)
70     [BTC_PID_BLUFI]       = {btc_blufi_call_handler,      btc_blufi_cb_handler    },
71 #endif  ///GATTS_INCLUDED == TRUE
72     [BTC_PID_DM_SEC]      = {NULL,                        btc_dm_sec_cb_handler   },
73     [BTC_PID_ALARM]       = {btc_alarm_handler,           NULL                    },
74 #if CONFIG_CLASSIC_BT_ENABLED
75 #if (BTC_GAP_BT_INCLUDED == TRUE)
76     [BTC_PID_GAP_BT]    = {btc_gap_bt_call_handler,     btc_gap_bt_cb_handler   },
77 #endif /* (BTC_GAP_BT_INCLUDED == TRUE) */
78     [BTC_PID_PRF_QUE]     = {btc_profile_queue_handler,   NULL                    },
79 #if BTC_AV_INCLUDED
80     [BTC_PID_A2DP]        = {btc_a2dp_call_handler,       btc_a2dp_cb_handler     },
81     [BTC_PID_AVRC]        = {btc_avrc_call_handler,       NULL                    },
82 #endif /* #if BTC_AV_INCLUDED */
83 #if CONFIG_BT_SPP_ENABLED
84     [BTC_PID_SPP]         = {btc_spp_call_handler,        btc_spp_cb_handler      },
85 #endif /* #if CONFIG_BT_SPP_ENABLED */
86 #if BTC_HF_CLIENT_INCLUDED
87     [BTC_PID_HF_CLIENT]   = {btc_hf_client_call_handler,  btc_hf_client_cb_handler},
88 #endif  /* #if BTC_HF_CLIENT_INCLUDED */
89 #endif /* #if CONFIG_CLASSIC_BT_ENABLED */
90 };
91
92 /*****************************************************************************
93 **
94 ** Function         btc_task
95 **
96 ** Description      Process profile Task Thread.
97 ******************************************************************************/
98 static void btc_task(void *arg)
99 {
100     btc_msg_t msg;
101
102     for (;;) {
103         if (pdTRUE == xQueueReceive(xBtcQueue, &msg, (portTickType)portMAX_DELAY)) {
104             BTC_TRACE_DEBUG("%s msg %u %u %u %p\n", __func__, msg.sig, msg.pid, msg.act, msg.arg);
105             switch (msg.sig) {
106             case BTC_SIG_API_CALL:
107                 profile_tab[msg.pid].btc_call(&msg);
108                 break;
109             case BTC_SIG_API_CB:
110                 profile_tab[msg.pid].btc_cb(&msg);
111                 break;
112             default:
113                 break;
114             }
115             if (msg.arg) {
116                 osi_free(msg.arg);
117             }
118         }
119     }
120 }
121
122 static bt_status_t btc_task_post(btc_msg_t *msg, task_post_t timeout)
123 {
124     if (msg == NULL) {
125         return BT_STATUS_PARM_INVALID;
126     }
127
128     if (xQueueSend(xBtcQueue, msg, timeout) != pdTRUE) {
129         BTC_TRACE_ERROR("Btc Post failed\n");
130         return BT_STATUS_BUSY;
131     }
132
133     return BT_STATUS_SUCCESS;
134 }
135
136 bt_status_t btc_transfer_context(btc_msg_t *msg, void *arg, int arg_len, btc_arg_deep_copy_t copy_func)
137 {
138     btc_msg_t lmsg;
139
140     if (msg == NULL) {
141         return BT_STATUS_PARM_INVALID;
142     }
143
144     BTC_TRACE_DEBUG("%s msg %u %u %u %p\n", __func__, msg->sig, msg->pid, msg->act, arg);
145
146     memcpy(&lmsg, msg, sizeof(btc_msg_t));
147     if (arg) {
148         lmsg.arg = (void *)osi_malloc(arg_len);
149         if (lmsg.arg == NULL) {
150             return BT_STATUS_NOMEM;
151         }
152         memset(lmsg.arg, 0x00, arg_len);    //important, avoid arg which have no length
153         memcpy(lmsg.arg, arg, arg_len);
154         if (copy_func) {
155             copy_func(&lmsg, lmsg.arg, arg);
156         }
157     } else {
158         lmsg.arg = NULL;
159     }
160
161     return btc_task_post(&lmsg, TASK_POST_BLOCKING);
162 }
163
164
165 int btc_init(void)
166 {
167     xBtcQueue = xQueueCreate(BTC_TASK_QUEUE_LEN, sizeof(btc_msg_t));
168     xTaskCreatePinnedToCore(btc_task, "Btc_task", BTC_TASK_STACK_SIZE, NULL, BTC_TASK_PRIO, &xBtcTaskHandle, BTC_TASK_PINNED_TO_CORE);
169     if (xBtcTaskHandle == NULL || xBtcQueue == 0){
170         return BT_STATUS_NOMEM;
171     }
172     btc_gap_callback_init();
173 #if SCAN_QUEUE_CONGEST_CHECK
174     btc_adv_list_init();
175 #endif
176     /* TODO: initial the profile_tab */
177     return BT_STATUS_SUCCESS;
178 }
179
180 void btc_deinit(void)
181 {
182     vTaskDelete(xBtcTaskHandle);
183     vQueueDelete(xBtcQueue);
184 #if SCAN_QUEUE_CONGEST_CHECK
185     btc_adv_list_deinit();
186 #endif
187     xBtcTaskHandle = NULL;
188     xBtcQueue = 0;
189 }
190
191 bool btc_check_queue_is_congest(void)
192 {
193     UBaseType_t wait_size = uxQueueMessagesWaiting(xBtcQueue);
194     if(wait_size >= QUEUE_CONGEST_SIZE) {
195         return true;
196     }
197     return false;
198 }