/* * Copyright (C) 2021 Huawei Device Co., 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. */ /** * @file att_init.c * * @brief implement initialize function to be called. * */ #include #include "att_connect.h" #include "att_common.h" #include "att_receive.h" #include "alarm.h" #include "btstack.h" #include "module.h" #include "packet.h" #include "log.h" #include "../btm/btm_thread.h" static void AttInstructListInit(); static void AttListDataFree(const void *data); static void AttAlarmListInit(); static void L2cifLeRisterFixChannelCallback(uint16_t cid, int result); static void L2cifRegisterServiceCallback(uint16_t lpsm, int result); static void AttDelete(AttConnectInfo *connectInfo, AttConnectingInfo *connectingInfo); static void ATT_Init(const int traceLevel); static void ATT_StartUp(); static void ATT_StartUpAsync(const void *context); static void ATT_StartUpAsyncDestroy(const void *context); static void ATT_ShutDown(); static void ATT_ShutDownAsync(const void *context); static void ATT_Clearup(); /** * @brief att instructions list initialization. * */ static void AttInstructListInit() { LOG_INFO("%{public}s enter", __FUNCTION__); uint16_t index = 0; AttConnectInfo *connectInfoPtr = NULL; connectInfoPtr = AttGetConnectStart(); for (; index < MAXCONNECT; ++index) { connectInfoPtr[index].instruct = ListCreate((void *)AttListDataFree); } return; } /** * @brief att list data free. * * @param data Indicates the pointer to dta. */ static void AttListDataFree(const void *data) { LOG_INFO("%{public}s enter", __FUNCTION__); Packet *packet = (Packet *)data; PacketFree(packet); return; } /** * @brief att alarm list initialization. * */ static void AttAlarmListInit() { LOG_INFO("%{public}s enter", __FUNCTION__); uint16_t index = 0; uint16_t increaseIndex; AttConnectInfo *connectInfo = NULL; AttConnectingInfo *connectingInfo = NULL; connectInfo = AttGetConnectStart(); connectingInfo = AttGetConnectingStart(); for (; index < MAXCONNECT; ++index) { connectInfo[index].alarm = AlarmCreate((char *)&index, 0); } for (increaseIndex = MAXCONNECT, index = 0; (increaseIndex < STEP_TWO * MAXCONNECT) && (index < MAXCONNECT); ++increaseIndex, ++index) { connectingInfo[index].bredrAlarm = AlarmCreate((char *)&increaseIndex, 0); } for (increaseIndex = STEP_TWO * MAXCONNECT, index = 0; (increaseIndex < STEP_THREE * MAXCONNECT) && (index < MAXCONNECT); ++increaseIndex, ++index) { connectingInfo[index].leAlarm = AlarmCreate((char *)&increaseIndex, 0); } return; } /** * @brief att start up async. * * @param context Indicates the pointer to context. */ static void ATT_StartUpAsync(const void *context) { LOG_INFO("%{public}s enter", __FUNCTION__); AttInstructListInit(); AttAlarmListInit(); FunctionListInit(); L2capLeFixChannel lel2capLeFixChannelObj; lel2capLeFixChannelObj.cid = LE_CID; lel2capLeFixChannelObj.leConnected = AttLeConnected; lel2capLeFixChannelObj.leDisconnected = AttLeDisconnected; lel2capLeFixChannelObj.recvLeData = AttRecvLeData; L2CIF_LeRegisterFixChannel(LE_CID, &lel2capLeFixChannelObj, L2cifLeRisterFixChannelCallback); return; } /** * @brief att start up async destroy. * * @param context Indicates the pointer to context. */ static void ATT_StartUpAsyncDestroy(const void *context) { LOG_INFO("%{public}s enter", __FUNCTION__); return; } /** * @brief att start up. * */ static void ATT_StartUp() { LOG_INFO("%{public}s enter", __FUNCTION__); int result; result = BTM_CreateProcessingQueue(PROCESSING_QUEUE_ID_ATT, BTM_PROCESSING_QUEUE_SIZE_DEFAULT); if (result != BT_SUCCESS) { return; } AttAsyncProcess(ATT_StartUpAsync, ATT_StartUpAsyncDestroy, NULL); return; } /** * @brief att initialization. * * @param trace_level Indicates the level. */ static void ATT_Init(const int traceLevel) { LOG_INFO("%{public}s enter", __FUNCTION__); return; } /** * @brief att shutdown async. * */ static void ATT_ShutDownAsync(const void *context) { LOG_INFO("%{public}s enter", __FUNCTION__); uint16_t index = 0; AttConnectInfo *connectInfo = AttGetConnectStart(); AttConnectingInfo *connectingInfo = AttGetConnectingStart(); for (; index < MAXCONNECT; ++index) { AttShutDownClearConnectInfo(&connectInfo[index]); ListClear(connectInfo[index].instruct); if (connectInfo[index].alarm) { AlarmCancel(connectInfo[index].alarm); } if (connectingInfo[index].bredrAlarm) { AlarmCancel(connectingInfo[index].bredrAlarm); } if (connectingInfo[index].leAlarm) { AlarmCancel(connectingInfo[index].leAlarm); } } AttDelete(AttGetConnectStart(), AttGetConnectingStart()); BTM_DeleteProcessingQueue(PROCESSING_QUEUE_ID_ATT); return; } /** * @brief att shutdown. * */ static void ATT_ShutDown() { LOG_INFO("%{public}s enter", __FUNCTION__); AttAsyncProcess(ATT_ShutDownAsync, NULL, NULL); return; } /** * @brief att clear up. * */ static void ATT_Clearup() { LOG_INFO("%{public}s enter", __FUNCTION__); return; } /** * @brief callback of att register l2caple. * * @param1 cid Indicates the cid. * @param2 result Indicates the result of callback. */ static void L2cifLeRisterFixChannelCallback(uint16_t cid, int result) { LOG_INFO("%{public}s enter, cid = %hu, result = %{public}d", __FUNCTION__, cid, result); L2capService bredrl2capServiceTObj; bredrl2capServiceTObj.recvConnectionReq = (void (*)(uint16_t, uint8_t, const L2capConnectionInfo *, uint16_t, void *))AttReceiveConnectionReq; bredrl2capServiceTObj.recvConnectionRsp = (void (*)(uint16_t, const L2capConnectionInfo *, uint16_t, uint16_t, void *))AttReceiveConnectionRsp; bredrl2capServiceTObj.recvConfigReq = (void (*)(uint16_t, uint8_t, const L2capConfigInfo *, void *))AttReceiveConfigReq; bredrl2capServiceTObj.recvConfigRsp = (void (*)(uint16_t, const L2capConfigInfo *, uint16_t, void *))AttReceiveConfigRsp; bredrl2capServiceTObj.recvDisconnectionReq = (void (*)(uint16_t, uint8_t, void *))AttReceiveDisconnectionReq; bredrl2capServiceTObj.recvDisconnectionRsp = (void (*)(uint16_t, void *))AttRecvDisconnectionRsp; bredrl2capServiceTObj.disconnectAbnormal = (void (*)(uint16_t, uint8_t, void *))AttDisconnectAbnormal; bredrl2capServiceTObj.recvData = (void (*)(uint16_t, Packet *, void *))AttRecvData; L2CIF_RegisterService(BT_PSM_ATT, &bredrl2capServiceTObj, NULL, L2cifRegisterServiceCallback); return; } /** * @brief callback of att register l2capbredr. * * @param1 lpsm Indicates the lpsm. * @param2 result Indicates the result of callback. */ void L2cifRegisterServiceCallback(uint16_t lpsm, int result) { LOG_INFO("%{public}s enter, lpsm = %hu, result = %{public}d", __FUNCTION__, lpsm, result); return; } /** * @brief att delete information. * * @param1 connectInfo Indicates the pointer of AttConnectInfo. * @param2 connectingInfo Indicates the pointer of AttConnectingInfo. */ static void AttDelete(AttConnectInfo *connectInfo, AttConnectingInfo *connectingInfo) { LOG_INFO("%{public}s enter", __FUNCTION__); uint16_t index = 0; for (; index < MAXCONNECT; ++index) { ListDelete(connectInfo[index].instruct); connectInfo[index].instruct = NULL; if (connectInfo[index].alarm) { AlarmDelete(connectInfo[index].alarm); connectInfo[index].alarm = NULL; } if (connectingInfo[index].bredrAlarm) { AlarmDelete(connectingInfo[index].bredrAlarm); connectingInfo[index].bredrAlarm = NULL; } if (connectingInfo[index].leAlarm) { AlarmDelete(connectingInfo[index].leAlarm); connectingInfo[index].leAlarm = NULL; } } return; } static Module g_att = { .name = MODULE_NAME_ATT, .init = ATT_Init, .startup = ATT_StartUp, .shutdown = ATT_ShutDown, .cleanup = ATT_Clearup, .dependencies = {MODULE_NAME_L2CAP}, }; MODULE_DECL(g_att);