1 /*
2 * Copyright (C) 2021 Huawei Device Co., Ltd.
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
16 /**
17 * @file att_init.c
18 *
19 * @brief implement initialize function to be called.
20 *
21 */
22
23 #include <string.h>
24
25 #include "att_connect.h"
26 #include "att_common.h"
27 #include "att_receive.h"
28
29 #include "alarm.h"
30 #include "btstack.h"
31 #include "module.h"
32 #include "packet.h"
33
34 #include "log.h"
35
36 #include "../btm/btm_thread.h"
37
38 static void AttInstructListInit();
39 static void AttListDataFree(const void *data);
40 static void AttAlarmListInit();
41
42 static void L2cifLeRisterFixChannelCallback(uint16_t cid, int result);
43
44 static void L2cifRegisterServiceCallback(uint16_t lpsm, int result);
45 static void AttDelete(AttConnectInfo *connectInfo, AttConnectingInfo *connectingInfo);
46
47 static void ATT_Init(const int traceLevel);
48
49 static void ATT_StartUp();
50 static void ATT_StartUpAsync(const void *context);
51 static void ATT_StartUpAsyncDestroy(const void *context);
52
53 static void ATT_ShutDown();
54 static void ATT_ShutDownAsync(const void *context);
55
56 static void ATT_Clearup();
57
58 /**
59 * @brief att instructions list initialization.
60 *
61 */
AttInstructListInit()62 static void AttInstructListInit()
63 {
64 LOG_INFO("%{public}s enter", __FUNCTION__);
65
66 uint16_t index = 0;
67 AttConnectInfo *connectInfoPtr = NULL;
68
69 connectInfoPtr = AttGetConnectStart();
70
71 for (; index < MAXCONNECT; ++index) {
72 connectInfoPtr[index].instruct = ListCreate((void *)AttListDataFree);
73 }
74
75 return;
76 }
77
78 /**
79 * @brief att list data free.
80 *
81 * @param data Indicates the pointer to dta.
82 */
AttListDataFree(const void * data)83 static void AttListDataFree(const void *data)
84 {
85 LOG_INFO("%{public}s enter", __FUNCTION__);
86
87 Packet *packet = (Packet *)data;
88 PacketFree(packet);
89
90 return;
91 }
92
93 /**
94 * @brief att alarm list initialization.
95 *
96 */
AttAlarmListInit()97 static void AttAlarmListInit()
98 {
99 LOG_INFO("%{public}s enter", __FUNCTION__);
100
101 uint16_t index = 0;
102 uint16_t increaseIndex;
103 AttConnectInfo *connectInfo = NULL;
104 AttConnectingInfo *connectingInfo = NULL;
105
106 connectInfo = AttGetConnectStart();
107 connectingInfo = AttGetConnectingStart();
108
109 for (; index < MAXCONNECT; ++index) {
110 connectInfo[index].alarm = AlarmCreate((char *)&index, 0);
111 }
112
113 for (increaseIndex = MAXCONNECT, index = 0; (increaseIndex < STEP_TWO * MAXCONNECT) && (index < MAXCONNECT);
114 ++increaseIndex, ++index) {
115 connectingInfo[index].bredrAlarm = AlarmCreate((char *)&increaseIndex, 0);
116 }
117
118 for (increaseIndex = STEP_TWO * MAXCONNECT, index = 0;
119 (increaseIndex < STEP_THREE * MAXCONNECT) && (index < MAXCONNECT);
120 ++increaseIndex, ++index) {
121 connectingInfo[index].leAlarm = AlarmCreate((char *)&increaseIndex, 0);
122 }
123
124 return;
125 }
126
127 /**
128 * @brief att start up async.
129 *
130 * @param context Indicates the pointer to context.
131 */
ATT_StartUpAsync(const void * context)132 static void ATT_StartUpAsync(const void *context)
133 {
134 LOG_INFO("%{public}s enter", __FUNCTION__);
135
136 AttInstructListInit();
137 AttAlarmListInit();
138 FunctionListInit();
139
140 L2capLeFixChannel lel2capLeFixChannelObj;
141 lel2capLeFixChannelObj.cid = LE_CID;
142 lel2capLeFixChannelObj.leConnected = AttLeConnected;
143 lel2capLeFixChannelObj.leDisconnected = AttLeDisconnected;
144 lel2capLeFixChannelObj.recvLeData = AttRecvLeData;
145 L2CIF_LeRegisterFixChannel(LE_CID, &lel2capLeFixChannelObj, L2cifLeRisterFixChannelCallback);
146
147 return;
148 }
149
150 /**
151 * @brief att start up async destroy.
152 *
153 * @param context Indicates the pointer to context.
154 */
ATT_StartUpAsyncDestroy(const void * context)155 static void ATT_StartUpAsyncDestroy(const void *context)
156 {
157 LOG_INFO("%{public}s enter", __FUNCTION__);
158
159 return;
160 }
161
162 /**
163 * @brief att start up.
164 *
165 */
ATT_StartUp()166 static void ATT_StartUp()
167 {
168 LOG_INFO("%{public}s enter", __FUNCTION__);
169
170 int result;
171
172 result = BTM_CreateProcessingQueue(PROCESSING_QUEUE_ID_ATT, BTM_PROCESSING_QUEUE_SIZE_DEFAULT);
173 if (result != BT_SUCCESS) {
174 return;
175 }
176
177 AttAsyncProcess(ATT_StartUpAsync, ATT_StartUpAsyncDestroy, NULL);
178
179 return;
180 }
181
182 /**
183 * @brief att initialization.
184 *
185 * @param trace_level Indicates the level.
186 */
ATT_Init(const int traceLevel)187 static void ATT_Init(const int traceLevel)
188 {
189 LOG_INFO("%{public}s enter", __FUNCTION__);
190
191 return;
192 }
193
194 /**
195 * @brief att shutdown async.
196 *
197 */
ATT_ShutDownAsync(const void * context)198 static void ATT_ShutDownAsync(const void *context)
199 {
200 LOG_INFO("%{public}s enter", __FUNCTION__);
201
202 uint16_t index = 0;
203 AttConnectInfo *connectInfo = AttGetConnectStart();
204 AttConnectingInfo *connectingInfo = AttGetConnectingStart();
205
206 for (; index < MAXCONNECT; ++index) {
207 AttShutDownClearConnectInfo(&connectInfo[index]);
208 ListClear(connectInfo[index].instruct);
209 if (connectInfo[index].alarm) {
210 AlarmCancel(connectInfo[index].alarm);
211 }
212 if (connectingInfo[index].bredrAlarm) {
213 AlarmCancel(connectingInfo[index].bredrAlarm);
214 }
215 if (connectingInfo[index].leAlarm) {
216 AlarmCancel(connectingInfo[index].leAlarm);
217 }
218 }
219
220 AttDelete(AttGetConnectStart(), AttGetConnectingStart());
221
222 BTM_DeleteProcessingQueue(PROCESSING_QUEUE_ID_ATT);
223
224 return;
225 }
226
227 /**
228 * @brief att shutdown.
229 *
230 */
ATT_ShutDown()231 static void ATT_ShutDown()
232 {
233 LOG_INFO("%{public}s enter", __FUNCTION__);
234
235 AttAsyncProcess(ATT_ShutDownAsync, NULL, NULL);
236
237 return;
238 }
239
240 /**
241 * @brief att clear up.
242 *
243 */
ATT_Clearup()244 static void ATT_Clearup()
245 {
246 LOG_INFO("%{public}s enter", __FUNCTION__);
247
248 return;
249 }
250
251 /**
252 * @brief callback of att register l2caple.
253 *
254 * @param1 cid Indicates the cid.
255 * @param2 result Indicates the result of callback.
256 */
L2cifLeRisterFixChannelCallback(uint16_t cid,int result)257 static void L2cifLeRisterFixChannelCallback(uint16_t cid, int result)
258 {
259 LOG_INFO("%{public}s enter, cid = %hu, result = %{public}d", __FUNCTION__, cid, result);
260
261 L2capService bredrl2capServiceTObj;
262 bredrl2capServiceTObj.recvConnectionReq =
263 (void (*)(uint16_t, uint8_t, const L2capConnectionInfo *, uint16_t, void *))AttReceiveConnectionReq;
264 bredrl2capServiceTObj.recvConnectionRsp =
265 (void (*)(uint16_t, const L2capConnectionInfo *, uint16_t, uint16_t, void *))AttReceiveConnectionRsp;
266 bredrl2capServiceTObj.recvConfigReq =
267 (void (*)(uint16_t, uint8_t, const L2capConfigInfo *, void *))AttReceiveConfigReq;
268 bredrl2capServiceTObj.recvConfigRsp =
269 (void (*)(uint16_t, const L2capConfigInfo *, uint16_t, void *))AttReceiveConfigRsp;
270 bredrl2capServiceTObj.recvDisconnectionReq = (void (*)(uint16_t, uint8_t, void *))AttReceiveDisconnectionReq;
271 bredrl2capServiceTObj.recvDisconnectionRsp = (void (*)(uint16_t, void *))AttRecvDisconnectionRsp;
272 bredrl2capServiceTObj.disconnectAbnormal = (void (*)(uint16_t, uint8_t, void *))AttDisconnectAbnormal;
273 bredrl2capServiceTObj.recvData = (void (*)(uint16_t, Packet *, void *))AttRecvData;
274
275 L2CIF_RegisterService(BT_PSM_ATT, &bredrl2capServiceTObj, NULL, L2cifRegisterServiceCallback);
276
277 return;
278 }
279
280 /**
281 * @brief callback of att register l2capbredr.
282 *
283 * @param1 lpsm Indicates the lpsm.
284 * @param2 result Indicates the result of callback.
285 */
L2cifRegisterServiceCallback(uint16_t lpsm,int result)286 void L2cifRegisterServiceCallback(uint16_t lpsm, int result)
287 {
288 LOG_INFO("%{public}s enter, lpsm = %hu, result = %{public}d", __FUNCTION__, lpsm, result);
289
290 return;
291 }
292
293 /**
294 * @brief att delete information.
295 *
296 * @param1 connectInfo Indicates the pointer of AttConnectInfo.
297 * @param2 connectingInfo Indicates the pointer of AttConnectingInfo.
298 */
AttDelete(AttConnectInfo * connectInfo,AttConnectingInfo * connectingInfo)299 static void AttDelete(AttConnectInfo *connectInfo, AttConnectingInfo *connectingInfo)
300 {
301 LOG_INFO("%{public}s enter", __FUNCTION__);
302
303 uint16_t index = 0;
304
305 for (; index < MAXCONNECT; ++index) {
306 ListDelete(connectInfo[index].instruct);
307 connectInfo[index].instruct = NULL;
308 if (connectInfo[index].alarm) {
309 AlarmDelete(connectInfo[index].alarm);
310 connectInfo[index].alarm = NULL;
311 }
312 if (connectingInfo[index].bredrAlarm) {
313 AlarmDelete(connectingInfo[index].bredrAlarm);
314 connectingInfo[index].bredrAlarm = NULL;
315 }
316 if (connectingInfo[index].leAlarm) {
317 AlarmDelete(connectingInfo[index].leAlarm);
318 connectingInfo[index].leAlarm = NULL;
319 }
320 }
321
322 return;
323 }
324
325 static Module g_att = {
326 .name = MODULE_NAME_ATT,
327 .init = ATT_Init,
328 .startup = ATT_StartUp,
329 .shutdown = ATT_ShutDown,
330 .cleanup = ATT_Clearup,
331 .dependencies = {MODULE_NAME_L2CAP},
332 };
333
334 MODULE_DECL(g_att);
335