1 /******************************************************************************
2  *
3  *  Copyright 2003-2012 Broadcom Corporation
4  *
5  *  Licensed under the Apache License, Version 2.0 (the "License");
6  *  you may not use this file except in compliance with the License.
7  *  You may obtain a copy of the License at:
8  *
9  *  http://www.apache.org/licenses/LICENSE-2.0
10  *
11  *  Unless required by applicable law or agreed to in writing, software
12  *  distributed under the License is distributed on an "AS IS" BASIS,
13  *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  *  See the License for the specific language governing permissions and
15  *  limitations under the License.
16  *
17  ******************************************************************************/
18 
19 /******************************************************************************
20  *
21  *  This is the main implementation file for the BTA system manager.
22  *
23  ******************************************************************************/
24 
25 #define LOG_TAG "bt_bta_sys_main"
26 
27 #include <base/functional/bind.h>
28 #include <bluetooth/log.h>
29 
30 #include <cstring>
31 
32 #include "bta/sys/bta_sys.h"
33 #include "bta/sys/bta_sys_int.h"
34 #include "include/hardware/bluetooth.h"
35 #include "internal_include/bt_target.h"
36 #include "os/log.h"
37 #include "osi/include/alarm.h"
38 #include "osi/include/allocator.h"
39 #include "stack/include/bt_hdr.h"
40 #include "stack/include/main_thread.h"
41 
42 using namespace bluetooth;
43 
44 /* system manager control block definition */
45 tBTA_SYS_CB bta_sys_cb;
46 
47 /*******************************************************************************
48  *
49  * Function         bta_sys_init
50  *
51  * Description      BTA initialization; called from task initialization.
52  *
53  *
54  * Returns          void
55  *
56  ******************************************************************************/
bta_sys_init(void)57 void bta_sys_init(void) {
58   memset(&bta_sys_cb, 0, sizeof(tBTA_SYS_CB));
59 }
60 
61 /*******************************************************************************
62  *
63  * Function         bta_sys_event
64  *
65  * Description      BTA event handler; called from task event handler.
66  *
67  *
68  * Returns          void
69  *
70  ******************************************************************************/
bta_sys_event(BT_HDR_RIGID * p_msg)71 static void bta_sys_event(BT_HDR_RIGID* p_msg) {
72   bool freebuf = true;
73 
74   log::verbose("Event 0x{:x}", p_msg->event);
75 
76   /* get subsystem id from event */
77   uint8_t id = (uint8_t)(p_msg->event >> 8);
78 
79   /* verify id and call subsystem event handler */
80   if ((id < BTA_ID_MAX) && (bta_sys_cb.reg[id] != NULL)) {
81     freebuf = (*bta_sys_cb.reg[id]->evt_hdlr)(p_msg);
82   } else {
83     log::info("Ignoring receipt of unregistered event id:{}[{}]",
84               BtaIdSysText(static_cast<tBTA_SYS_ID>(id)), id);
85   }
86 
87   if (freebuf) {
88     osi_free(p_msg);
89   }
90 }
91 
92 /*******************************************************************************
93  *
94  * Function         bta_sys_register
95  *
96  * Description      Called by other BTA subsystems to register their event
97  *                  handler.
98  *
99  *
100  * Returns          void
101  *
102  ******************************************************************************/
bta_sys_register(uint8_t id,const tBTA_SYS_REG * p_reg)103 void bta_sys_register(uint8_t id, const tBTA_SYS_REG* p_reg) {
104   bta_sys_cb.reg[id] = (tBTA_SYS_REG*)p_reg;
105   bta_sys_cb.is_reg[id] = true;
106 }
107 
108 /*******************************************************************************
109  *
110  * Function         bta_sys_deregister
111  *
112  * Description      Called by other BTA subsystems to de-register
113  *                  handler.
114  *
115  *
116  * Returns          void
117  *
118  ******************************************************************************/
bta_sys_deregister(uint8_t id)119 void bta_sys_deregister(uint8_t id) { bta_sys_cb.is_reg[id] = false; }
120 
121 /*******************************************************************************
122  *
123  * Function         bta_sys_is_register
124  *
125  * Description      Called by other BTA subsystems to get registeration
126  *                  status.
127  *
128  *
129  * Returns          void
130  *
131  ******************************************************************************/
bta_sys_is_register(uint8_t id)132 bool bta_sys_is_register(uint8_t id) { return bta_sys_cb.is_reg[id]; }
133 
134 /*******************************************************************************
135  *
136  * Function         bta_sys_sendmsg
137  *
138  * Description      Send a GKI message to BTA.  This function is designed to
139  *                  optimize sending of messages to BTA.  It is called by BTA
140  *                  API functions and call-in functions.
141  *
142  *                  TODO (apanicke): Add location object as parameter for easier
143  *                  future debugging when doing alarm refactor
144  *
145  *
146  * Returns          void
147  *
148  ******************************************************************************/
bta_sys_sendmsg(void * p_msg)149 void bta_sys_sendmsg(void* p_msg) {
150   if (do_in_main_thread(
151           FROM_HERE,
152           base::BindOnce(&bta_sys_event, static_cast<BT_HDR_RIGID*>(p_msg))) !=
153       BT_STATUS_SUCCESS) {
154     log::error("do_in_main_thread failed");
155   }
156 }
157 
bta_sys_sendmsg_delayed(void * p_msg,std::chrono::microseconds delay)158 void bta_sys_sendmsg_delayed(void* p_msg, std::chrono::microseconds delay) {
159   if (do_in_main_thread_delayed(
160           FROM_HERE,
161           base::Bind(&bta_sys_event, static_cast<BT_HDR_RIGID*>(p_msg)),
162           delay) != BT_STATUS_SUCCESS) {
163     log::error("do_in_main_thread_delayed failed");
164   }
165 }
166 
167 /*******************************************************************************
168  *
169  * Function         bta_sys_start_timer
170  *
171  * Description      Start a protocol timer for the specified amount
172  *                  of time in milliseconds.
173  *
174  * Returns          void
175  *
176  ******************************************************************************/
bta_sys_start_timer(alarm_t * alarm,uint64_t interval_ms,uint16_t event,uint16_t layer_specific)177 void bta_sys_start_timer(alarm_t* alarm, uint64_t interval_ms, uint16_t event,
178                          uint16_t layer_specific) {
179   BT_HDR_RIGID* p_buf = (BT_HDR_RIGID*)osi_malloc(sizeof(BT_HDR_RIGID));
180 
181   p_buf->event = event;
182   p_buf->layer_specific = layer_specific;
183 
184   alarm_set_on_mloop(alarm, interval_ms, bta_sys_sendmsg, p_buf);
185 }
186 
187 /*******************************************************************************
188  *
189  * Function         bta_sys_disable
190  *
191  * Description      For each registered subsystem execute its disable function.
192  *
193  * Returns          void
194  *
195  ******************************************************************************/
bta_sys_disable()196 void bta_sys_disable() {
197   int bta_id = BTA_ID_DM_SEC;
198   int bta_id_max = BTA_ID_BLUETOOTH_MAX;
199 
200   for (; bta_id <= bta_id_max; bta_id++) {
201     if (bta_sys_cb.reg[bta_id] != NULL) {
202       if (bta_sys_cb.is_reg[bta_id] &&
203           bta_sys_cb.reg[bta_id]->disable != NULL) {
204         (*bta_sys_cb.reg[bta_id]->disable)();
205       }
206     }
207   }
208 }
209