/* * Copyright (C) 2021-2022 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_receive.c * * @brief implement receive function to be called. * */ #include "att_receive.h" #include <memory.h> #include "buffer.h" #include "list.h" #include "packet.h" #include "gap_le_if.h" #include "platform/include/allocator.h" #include "log.h" typedef struct SigedWriteCommandConfirmationContext { AttConnectInfo *connect; Buffer *bufferallPtr; uint8_t *data; uint16_t bufferSize; } SigedWriteCommandConfirmationContext; typedef struct AttGapSignatureConfirmationAsync { GAP_SignatureResult result; void *context; } AttGapSignatureConfirmationAsync; static void AttCount(uint8_t format, uint16_t *inforLenPtr, uint16_t *uuidLenPtr); static int AttJudgeInfoLen(uint16_t inforLen, size_t dataLen, uint16_t *inforNum); static void AttFindInformationResAssign(uint16_t inforNum, AttFind *attFindObj, const uint8_t *data, uint16_t inforLen); static void AttReadFree(AttRead *valueList, uint16_t num, uint8_t type); static void AttReadAttrAssign(const AttRead *attReadPtr, uint8_t len, const uint8_t *data); static void AttSignWriteCommConfContextAssign(SigedWriteCommandConfirmationContext *sigedWriteCommandConfirmContextPtr, const AttConnectInfo *connect, const uint8_t *data, const Buffer *bufferallPtr, size_t buffSize); static void AttSignWriteCommConfDataAssign( uint8_t *data, const uint8_t *dataBuffer, size_t buffSize, uint8_t signature[12]); static void AttSignedWriteCommandBufferFree(Buffer *bufferNew, Buffer *sigedWriteBuffPtr, Buffer *bufferallPtr); static void AttReadByTypeResErrorAssign(AttError *attErrorObjPtr, const AttConnectInfo *connect); static void AttGapSignatureConfirmationResultAsync(const void *context); static void AttGapSignatureConfirmationResultAsyncDestroy(const void *context); static void FindInformationResponseErrorAssign(AttError *attErrorObjPtr, const AttConnectInfo *connect); static void FindByTypeValueResponseErrorAssign(AttError *attErrorObjPtr, const AttConnectInfo *connect); static void ReadByGroupTypeResponseErrorAssign(AttError *attErrorObjPtr, const AttConnectInfo *connect); static void AttSignedWriteCommandGapRetErrorAssign(AttWrite *attWriteObjPtr, const uint8_t *data); /** * @brief gap security confirmation result async. * * @param context Indicates the pointer to context. */ static void AttGapSignatureConfirmationResultAsync(const void *context) { LOG_INFO("%{public}s enter", __FUNCTION__); if (context == NULL) { LOG_WARN("%{public}s:context == NULL, return.", __FUNCTION__); return; } AttGapSignatureConfirmationAsync *attGapSigConfirmationPtr = (AttGapSignatureConfirmationAsync *)context; Buffer *bufferSig = (Buffer *)(attGapSigConfirmationPtr->context); AttWrite attWriteObj; Buffer *bufferNew = NULL; AttServerDataCallback *attServerDataCallback = NULL; SigedWriteCommandConfirmationContext *sigedWriteCommandConfirmContextPtr = NULL; if (bufferSig == NULL) { goto GAPSIGNATURECONFIRMATIONRESULT_END; } attServerDataCallback = AttGetATTServerCallback(); if ((attServerDataCallback == NULL) || (attServerDataCallback->attServerCallback == NULL)) { LOG_WARN("%{public}s attServerDataCallback or attServerDataCallback->attServerCallback is NULL", __FUNCTION__); goto GAPSIGNATURECONFIRMATIONRESULT_END; } sigedWriteCommandConfirmContextPtr = (SigedWriteCommandConfirmationContext *)BufferPtr(bufferSig); attWriteObj.signedWriteCommand.attHandleValueObj.attHandle = ((uint16_t *)(sigedWriteCommandConfirmContextPtr->data + 1))[0]; (void)memcpy_s(attWriteObj.signedWriteCommand.authSignature, GAPSIGNATURESIZE, sigedWriteCommandConfirmContextPtr->data + STEP_TWO + sigedWriteCommandConfirmContextPtr->bufferSize, GAPSIGNATURESIZE); attWriteObj.signedWriteCommand.authSignatureLen = GAPSIGNATURESIZE; attWriteObj.signedWriteCommand.result = (AttSignedWriteCommandResult)attGapSigConfirmationPtr->result; bufferNew = BufferSliceMalloc( sigedWriteCommandConfirmContextPtr->bufferallPtr, STEP_THREE, sigedWriteCommandConfirmContextPtr->bufferSize); attServerDataCallback->attServerCallback(sigedWriteCommandConfirmContextPtr->connect->retGattConnectHandle, ATT_SIGNED_WRITE_COMMAND_ID, &attWriteObj, bufferNew, attServerDataCallback->context); BufferFree(bufferNew); BufferFree(sigedWriteCommandConfirmContextPtr->bufferallPtr); BufferFree(bufferSig); GAPSIGNATURECONFIRMATIONRESULT_END: MEM_MALLOC.free(attGapSigConfirmationPtr); return; } /** * @brief gap security confirmation result async destroy. * * @param context Indicates the pointer to context. */ static void AttGapSignatureConfirmationResultAsyncDestroy(const void *context) { LOG_INFO("%{public}s enter", __FUNCTION__); if (context == NULL) { LOG_WARN("%{public}s:context == NULL, return.", __FUNCTION__); return; } AttGapSignatureConfirmationAsync *attGapSigConfirmationPtr = (AttGapSignatureConfirmationAsync *)context; MEM_MALLOC.free(attGapSigConfirmationPtr); return; } /** * @brief gap security confirmation result. * * @param result Indicates the GAP_SignatureResult. * @param context Indicates the pointer to context. */ void AttGapSignatureConfirmationResult(GAP_SignatureResult result, void *context) { LOG_INFO("%{public}s enter, result = %{public}d", __FUNCTION__, result); AttGapSignatureConfirmationAsync *attGapSigConfirmationPtr = MEM_MALLOC.alloc(sizeof(AttGapSignatureConfirmationAsync)); if (attGapSigConfirmationPtr == NULL) { LOG_ERROR("point to NULL"); return; } attGapSigConfirmationPtr->result = result; attGapSigConfirmationPtr->context = context; AttAsyncProcess(AttGapSignatureConfirmationResultAsync, AttGapSignatureConfirmationResultAsyncDestroy, attGapSigConfirmationPtr); return; } /** * @brief count. * * @param1 format Indicates the format. * @param2 inforLenPtr Indicates the pointer to inforLenPtr. * @param3 uuidLenPtr Indicates the pointer to uuidLenPtr. */ static void AttCount(uint8_t format, uint16_t *inforLenPtr, uint16_t *uuidLenPtr) { if (inforLenPtr == NULL || uuidLenPtr == NULL) { LOG_WARN("%{public}s:inforLenPtr or uuidLenPtr is null, return.", __FUNCTION__); return; } LOG_INFO("%{public}s enter,format = %hhu,inforLenPtr = %hu,uuidLenPtr = %hu", __FUNCTION__, format, *inforLenPtr, *uuidLenPtr); if (format == HANDLEAND16BITBLUETOOTHUUID) { *inforLenPtr = FINDINFORRESINFOR16BITLEN; *uuidLenPtr = UUID16BITTYPELEN; } else if (format == HANDLEAND128BITUUID) { *inforLenPtr = FINDINFORRESINFOR128BITLEN; *uuidLenPtr = UUID128BITTYPELEN; } return; } /** * @brief judge information len. * * @param1 inforLen Indicates the inforLen. * @param2 dataLen Indicates the dataLen. * @param3 inforNum Indicates the pointer to inforNum. * @return Returns <b>0</b> if the operation is successful; returns <b>!0</b> if the operation fails. */ static int AttJudgeInfoLen(uint16_t inforLen, size_t dataLen, uint16_t *inforNum) { if (inforNum == NULL) { LOG_WARN("%{public}s:inforNum is null, return.", __FUNCTION__); return BT_OPERATION_FAILED; } LOG_INFO("%{public}s enter,inforLen = %hu,dataLen = %zu,inforNum = %hu ", __FUNCTION__, inforLen, dataLen, *inforNum); int ret = BT_OPERATION_FAILED; if (inforLen != 0) { if ((dataLen - 1) % inforLen) { ret = BT_OPERATION_FAILED; goto ATTJUDGEINFOLEN_END; } else { *inforNum = (dataLen - 1) / inforLen; } } else { ret = BT_OPERATION_FAILED; goto ATTJUDGEINFOLEN_END; } ret = BT_SUCCESS; ATTJUDGEINFOLEN_END: return ret; } /** * @brief assign find information response. * * @param1 inforNum Indicates the inforNum. * @param2 attFindObj Indicates the pointer to AttFind. * @param3 data Indicates the pointer to data. * @param4 inforLen Indicates the information len. */ static void AttFindInformationResAssign(uint16_t inforNum, AttFind *attFindObj, const uint8_t *data, uint16_t inforLen) { LOG_INFO("%{public}s enter,inforNum = %hu, inforLen = %hu", __FUNCTION__, inforNum, inforLen); if (attFindObj == NULL || data == NULL) { LOG_WARN("%{public}s:attFindObj or data is null, return.", __FUNCTION__); return; } uint16_t index = 0; for (; index < inforNum; ++index) { attFindObj->findInforRsponse.handleUuidPairs[index].attHandle = ((uint16_t *)(data + 1 + index * inforLen))[0]; if (attFindObj->findInforRsponse.format == HANDLEAND16BITBLUETOOTHUUID) { attFindObj->findInforRsponse.handleUuidPairs[index].uuid.type = BT_UUID_16; attFindObj->findInforRsponse.handleUuidPairs[index].uuid.uuid16 = ((uint16_t *)(data + STEP_THREE + index * inforLen))[0]; } else if (attFindObj->findInforRsponse.format == HANDLEAND128BITUUID) { attFindObj->findInforRsponse.handleUuidPairs[index].uuid.type = BT_UUID_128; if (memcpy_s(&(attFindObj->findInforRsponse.handleUuidPairs[index].uuid.uuid128), UUID128LEN, data + STEP_THREE + index * inforLen, UUID128LEN) != EOK) { LOG_ERROR("%{public}s enter, memcpy_s fail", __FUNCTION__); return; } } } return; } /** * @brief free read data memory. * * @param1 valueList Indicates the pointer to AttRead. * @param2 num Indicates the num. * @param3 type Indicates the type. */ static void AttReadFree(AttRead *valueList, uint16_t num, uint8_t type) { LOG_INFO("%{public}s enter,num = %{public}d, type = %{public}d", __FUNCTION__, num, type); if (valueList == NULL) { LOG_WARN("%{public}s:valueList is null, return.", __FUNCTION__); return; } uint16_t index = 0; for (; index < num; ++index) { if (type == READBYTYPERESPONSEFREE) { MEM_MALLOC.free(valueList->readHandleListNum.valueList[index].attributeValue); } else if (type == READBYGROUPTYPERESPONSEFREE) { MEM_MALLOC.free(valueList->readGroupResponse.attributeData[index].attributeValue); } } if (type == READBYTYPERESPONSEFREE) { MEM_MALLOC.free(valueList->readHandleListNum.valueList); } else if (type == READBYGROUPTYPERESPONSEFREE) { MEM_MALLOC.free(valueList->readGroupResponse.attributeData); } return; } /** * @brief read data attribute assign. * * @param1 attReadPtr Indicates the pointer to AttRead. * @param2 len Indicates the len. * @param3 data Indicates the pointer to data. */ static void AttReadAttrAssign(const AttRead *attReadPtr, uint8_t len, const uint8_t *data) { LOG_INFO("%{public}s enter,len = %hhu", __FUNCTION__, len); if (attReadPtr == NULL || data == NULL) { LOG_WARN("%{public}s:attReadPtr or data is null, return.", __FUNCTION__); return; } uint16_t indexNum = 0; for (; indexNum < attReadPtr->readGroupResponse.num; ++indexNum) { attReadPtr->readGroupResponse.attributeData[indexNum].attributeValue = MEM_MALLOC.alloc(len - STEP_FOUR); attReadPtr->readGroupResponse.attributeData[indexNum].attHandle = ((uint16_t *)data)[0]; attReadPtr->readGroupResponse.attributeData[indexNum].groupEndHandle = ((uint16_t *)(data + STEP_TWO))[0]; (void)memcpy_s(attReadPtr->readGroupResponse.attributeData[indexNum].attributeValue, len - STEP_FOUR, data + STEP_FOUR, len - STEP_FOUR); data += len; } return; } /** * @brief received error response. * * @param1 connect Indicates the pointer to const AttConnectInfo. * @param2 buffer Indicates the pointer to Buffer. */ void AttErrorResponse(AttConnectInfo *connect, const Buffer *buffer) { LOG_INFO("%{public}s enter", __FUNCTION__); if (connect == NULL) { LOG_WARN("%{public}s:connect == NULL, return.", __FUNCTION__); return; } AttError attErrorTObj; uint8_t *data = NULL; AttClientDataCallback *attClientDataCallback = NULL; AlarmCancel(connect->alarm); if (buffer == NULL) { LOG_WARN("%{public}s:buffer == NULL", __FUNCTION__); goto ATTERRORRESPONSE_END; } attClientDataCallback = AttGetATTClientCallback(); if ((attClientDataCallback == NULL) || (attClientDataCallback->attClientCallback == NULL)) { LOG_WARN("%{public}s attClientDataCallback or attClientDataCallback->attClientCallback is NULL", __FUNCTION__); goto ATTERRORRESPONSE_END; } data = (uint8_t *)BufferPtr(buffer); attErrorTObj.reqOpcode = data[0]; attErrorTObj.attHandleInError = ((uint16_t *)(data + 1))[0]; attErrorTObj.errorCode = data[STEP_THREE]; LOG_INFO("%{public}s connectHandle = %hu, callback para : reqOpcode = %{public}d, " "attHandleInError = %{public}d, errorCode = %{public}d", __FUNCTION__, connect->retGattConnectHandle, attErrorTObj.reqOpcode, attErrorTObj.attHandleInError, attErrorTObj.errorCode); attClientDataCallback->attClientCallback( connect->retGattConnectHandle, ATT_ERROR_RESPONSE_ID, &attErrorTObj, NULL, attClientDataCallback->context); ATTERRORRESPONSE_END: LOG_INFO("%{public}s return connect != NULL, connectHandle = %hu", __FUNCTION__, connect->retGattConnectHandle); ListRemoveFirst(connect->instruct); AttReceiveSequenceScheduling(connect); return; } /** * @brief received exchangeMTU request. * * @param1 connect Indicates the pointer to const AttConnectInfo. * @param2 buffer Indicates the pointer to Buffer. */ void AttExchangeMTURequest(AttConnectInfo *connect, const Buffer *buffer) { LOG_INFO("%{public}s enter", __FUNCTION__); if (connect == NULL) { LOG_WARN("%{public}s:connect == NULL, return.", __FUNCTION__); return; } AttExchangeMTUType attExchangeMTUObj; uint8_t *data = NULL; AttServerDataCallback *attServerDataCallback = NULL; if (buffer == NULL) { LOG_WARN("%{public}s:buffer == NULL", __FUNCTION__); goto ATTEXCHANGEMTUREQUEST_END; } attServerDataCallback = AttGetATTServerCallback(); if ((attServerDataCallback == NULL) || (attServerDataCallback->attServerCallback == NULL)) { LOG_WARN("%{public}s attServerDataCallback or attServerDataCallback->attServerCallback is NULL", __FUNCTION__); goto ATTEXCHANGEMTUREQUEST_END; } data = (uint8_t *)BufferPtr(buffer); attExchangeMTUObj.mtuSize = ((uint16_t *)data)[0]; connect->receiveMtu = attExchangeMTUObj.mtuSize; LOG_INFO("%{public}s connectHandle = %hu, callback para : mtuSize = %{public}d", __FUNCTION__, connect->retGattConnectHandle, attExchangeMTUObj.mtuSize); attServerDataCallback->attServerCallback(connect->retGattConnectHandle, ATT_EXCHANGE_MTU_REQUEST_ID, &attExchangeMTUObj, NULL, attServerDataCallback->context); ATTEXCHANGEMTUREQUEST_END: return; } /** * @brief received exchangeMTU response. * * @param1 connect Indicates the pointer to const AttConnectInfo. * @param2 buffer Indicates the pointer to Buffer. */ void AttExchangeMTUResponse(AttConnectInfo *connect, const Buffer *buffer) { LOG_INFO("%{public}s enter", __FUNCTION__); if (connect == NULL) { LOG_WARN("%{public}s:connect == NULL, return.", __FUNCTION__); return; } AttExchangeMTUType attExchangeMTUObj; uint16_t *data = NULL; AttClientDataCallback *attClientDataCallback = NULL; AlarmCancel(connect->alarm); if (buffer == NULL) { LOG_WARN("%{public}s:buffer == NULL", __FUNCTION__); goto ATTEXCHANGEMTURESPONSE_END; } attClientDataCallback = AttGetATTClientCallback(); if ((attClientDataCallback == NULL) || (attClientDataCallback->attClientCallback == NULL)) { LOG_WARN("%{public}s attClientDataCallback or attClientDataCallback->attClientCallback is NULL", __FUNCTION__); goto ATTEXCHANGEMTURESPONSE_END; } data = (uint16_t *)BufferPtr(buffer); attExchangeMTUObj.mtuSize = data[0]; connect->mtu = Min(connect->sendMtu, attExchangeMTUObj.mtuSize); LOG_INFO("%{public}s connectHandle = %hu,callback para : mtuSize = %{public}d", __FUNCTION__, connect->retGattConnectHandle, attExchangeMTUObj.mtuSize); attClientDataCallback->attClientCallback(connect->retGattConnectHandle, ATT_EXCHANGE_MTU_RESPONSE_ID, &attExchangeMTUObj, NULL, attClientDataCallback->context); ATTEXCHANGEMTURESPONSE_END: LOG_INFO("%{public}s return connect != NULL, connectHandle = %hu", __FUNCTION__, connect->retGattConnectHandle); ListRemoveFirst(connect->instruct); AttReceiveSequenceScheduling(connect); return; } /** * @brief received findinformation request. * * @param1 connect Indicates the pointer to const AttConnectInfo. * @param2 buffer Indicates the pointer to Buffer. */ void AttFindInformationRequest(AttConnectInfo *connect, const Buffer *buffer) { LOG_INFO("%{public}s enter", __FUNCTION__); if (connect == NULL) { LOG_WARN("%{public}s:connect == NULL, return.", __FUNCTION__); return; } AttFind attFindObj; uint8_t *data = NULL; AttServerDataCallback *attServerDataCallback = NULL; if (buffer == NULL) { LOG_WARN("%{public}s:buffer == NULL", __FUNCTION__); goto ATTFINDINFORMATIONREQUEST_END; } if ((connect->transportType == BT_TRANSPORT_LE && connect->mtu == DEFAULTLEATTMTU) || (connect->transportType == BT_TRANSPORT_BR_EDR && connect->mtu == DEFAULTBREDRMTU)) { ((AttConnectInfo *)connect)->mtuFlag = true; } attServerDataCallback = AttGetATTServerCallback(); if ((attServerDataCallback == NULL) || (attServerDataCallback->attServerCallback == NULL)) { LOG_WARN("%{public}s attServerDataCallback or attServerDataCallback->attServerCallback is NULL", __FUNCTION__); goto ATTFINDINFORMATIONREQUEST_END; } data = (uint8_t *)BufferPtr(buffer); attFindObj.findInformationRequest.startHandle = ((uint16_t *)data)[0]; attFindObj.findInformationRequest.endHandle = ((uint16_t *)(data + STEP_TWO))[0]; LOG_INFO("%{public}s connectHandle = %hu, callback para : startHandle = %{public}d, endHandle = %{public}d", __FUNCTION__, connect->retGattConnectHandle, attFindObj.findInformationRequest.startHandle, attFindObj.findInformationRequest.endHandle); attServerDataCallback->attServerCallback(connect->retGattConnectHandle, ATT_FIND_INFORMATION_REQUEST_ID, &attFindObj, NULL, attServerDataCallback->context); ATTFINDINFORMATIONREQUEST_END: return; } /** * @brief received findinformation response error assign. * * @param1 attErrorObjPtr Indicates the pointer to AttError. * @param2 connect Indicates the pointer to AttConnectInfo. */ static void FindInformationResponseErrorAssign(AttError *attErrorObjPtr, const AttConnectInfo *connect) { LOG_INFO("%{public}s enter", __FUNCTION__); if (attErrorObjPtr == NULL || connect == NULL) { LOG_WARN("%{public}s:attErrorObjPtr or connect is NULL, return.", __FUNCTION__); return; } attErrorObjPtr->reqOpcode = FIND_INFORMATION_REQUEST; attErrorObjPtr->errorCode = ATT_INVALID_ATTRIBUTE_VALUE_LENGTH; attErrorObjPtr->attHandleInError = connect->aclHandle; return; } /** * @brief received findinformation response. * * @param1 connect Indicates the pointer to const AttConnectInfo. * @param2 buffer Indicates the pointer to Buffer. */ void AttFindInformationResponse(AttConnectInfo *connect, const Buffer *buffer) { LOG_INFO("%{public}s enter", __FUNCTION__); if (connect == NULL) { LOG_WARN("%{public}s:connect == NULL and return", __FUNCTION__); return; } uint16_t inforLen = 0; uint16_t inforNum = 0; uint16_t uuidLen = 0; AttFind attFindObj; size_t dataLen; uint8_t *data = NULL; AttError attErrorObj; AttClientDataCallback *attClientDataCallback = NULL; AlarmCancel(connect->alarm); if (buffer == NULL) { LOG_WARN("%{public}s:buffer == NULL and goto ATTFINDINFORMATIONRESPONSE_END", __FUNCTION__); goto ATTFINDINFORMATIONRESPONSE_END; } attClientDataCallback = AttGetATTClientCallback(); if ((attClientDataCallback == NULL) || (attClientDataCallback->attClientCallback == NULL)) { LOG_WARN("%{public}s attClientDataCallback or attClientDataCallback->attClientCallback is NULL", __FUNCTION__); goto ATTFINDINFORMATIONRESPONSE_END; } dataLen = BufferGetSize(buffer); data = (uint8_t *)BufferPtr(buffer); attFindObj.findInforRsponse.format = data[0]; AttCount(attFindObj.findInforRsponse.format, &inforLen, &uuidLen); if (AttJudgeInfoLen(inforLen, dataLen, &inforNum) < 0) { FindInformationResponseErrorAssign(&attErrorObj, connect); attClientDataCallback->attClientCallback( connect->retGattConnectHandle, ATT_ERROR_RESPONSE_ID, &attErrorObj, NULL, attClientDataCallback->context); goto ATTFINDINFORMATIONRESPONSE_END; } attFindObj.findInforRsponse.handleUuidPairs = MEM_MALLOC.alloc(sizeof(AttHandleUuid) * inforNum); attFindObj.findInforRsponse.pairNum = inforNum; AttFindInformationResAssign(inforNum, &attFindObj, data, inforLen); attClientDataCallback->attClientCallback(connect->retGattConnectHandle, ATT_FIND_INFORMATION_RESPONSE_ID, &attFindObj, NULL, attClientDataCallback->context); MEM_MALLOC.free(attFindObj.findInforRsponse.handleUuidPairs); ATTFINDINFORMATIONRESPONSE_END: LOG_INFO("%{public}s return connect != NULL, connectHandle = %hu", __FUNCTION__, connect->retGattConnectHandle); ListRemoveFirst(connect->instruct); AttReceiveSequenceScheduling(connect); return; } /** * @brief received findbytypevalue request. * * @param1 connect Indicates the pointer to const AttConnectInfo. * @param2 buffer Indicates the pointer to Buffer. */ void AttFindByTypeValueRequest(AttConnectInfo *connect, const Buffer *buffer) { LOG_INFO("%{public}s enter", __FUNCTION__); if (connect == NULL) { LOG_WARN("%{public}s:connect == NULL and return", __FUNCTION__); return; } AttFind attFindObj; Buffer *bufferNew = NULL; uint8_t *data = NULL; size_t buffSize; AttServerDataCallback *attServerDataCallback = NULL; if (buffer == NULL) { LOG_WARN("%{public}s:buffer == NULL and goto ATTFINDBYTYPEVALUEREQUEST_END", __FUNCTION__); goto ATTFINDBYTYPEVALUEREQUEST_END; } if ((connect->transportType == BT_TRANSPORT_LE && connect->mtu == DEFAULTLEATTMTU) || (connect->transportType == BT_TRANSPORT_BR_EDR && connect->mtu == DEFAULTBREDRMTU)) { connect->mtuFlag = true; } attServerDataCallback = AttGetATTServerCallback(); if ((attServerDataCallback == NULL) || (attServerDataCallback->attServerCallback == NULL)) { LOG_WARN("%{public}s attServerDataCallback or attServerDataCallback->attServerCallback is NULL", __FUNCTION__); goto ATTFINDBYTYPEVALUEREQUEST_END; } buffSize = BufferGetSize(buffer); data = (uint8_t *)BufferPtr(buffer); if (data == NULL || buffSize < STEP_SIX) { LOG_ERROR("%{public}s error request", __FUNCTION__); return; } attFindObj.findByTypeValueRequest.handleRange.startHandle = ((uint16_t *)data)[0]; attFindObj.findByTypeValueRequest.handleRange.endHandle = ((uint16_t *)(data + STEP_TWO))[0]; attFindObj.findByTypeValueRequest.attType = ((uint16_t *)(data + STEP_FOUR))[0]; if (buffSize - STEP_SIX > 0) { bufferNew = BufferSliceMalloc(buffer, STEP_SIX, buffSize - STEP_SIX); attServerDataCallback->attServerCallback(connect->retGattConnectHandle, ATT_FIND_BY_TYPE_VALUE_REQUEST_ID, &attFindObj, bufferNew, attServerDataCallback->context); BufferFree(bufferNew); } else { attServerDataCallback->attServerCallback(connect->retGattConnectHandle, ATT_FIND_BY_TYPE_VALUE_REQUEST_ID, &attFindObj, NULL, attServerDataCallback->context); } ATTFINDBYTYPEVALUEREQUEST_END: return; } /** * @brief received findbytypevalue response error assign. * * @param1 attErrorObjPtr Indicates the pointer to AttError. * @param2 connect Indicates the pointer to AttConnectInfo. */ static void FindByTypeValueResponseErrorAssign(AttError *attErrorObjPtr, const AttConnectInfo *connect) { LOG_INFO("%{public}s enter", __FUNCTION__); if (attErrorObjPtr == NULL || connect == NULL) { LOG_WARN("%{public}s:attErrorObjPtr or connect is NULL, return.", __FUNCTION__); return; } attErrorObjPtr->reqOpcode = FIND_BY_TYPE_VALUE_REQUEST; attErrorObjPtr->errorCode = ATT_INVALID_ATTRIBUTE_VALUE_LENGTH; attErrorObjPtr->attHandleInError = connect->aclHandle; return; } /** * @brief received findbytypevalue response. * * @param1 connect Indicates the pointer to const AttConnectInfo. * @param2 buffer Indicates the pointer to Buffer. */ void AttFindByTypeValueResponse(AttConnectInfo *connect, const Buffer *buffer) { LOG_INFO("%{public}s enter", __FUNCTION__); if (connect == NULL) { LOG_WARN("%{public}s:connect == NULL and return", __FUNCTION__); return; } size_t dataLen; uint16_t inforNum = 0; AttFind attFindObj; uint8_t *data = NULL; AttClientDataCallback *attClientDataCallback = NULL; AttError attErrorObj; AlarmCancel(connect->alarm); attClientDataCallback = AttGetATTClientCallback(); if ((attClientDataCallback == NULL) || (attClientDataCallback->attClientCallback == NULL) || (buffer == NULL)) { LOG_WARN("%{public}s attClientDataCallback or attClientDataCallback->attClientCallback is NULL", __FUNCTION__); goto ATTFINDBYTYPEVALUERESPONSE_END; } dataLen = BufferGetSize(buffer); if (dataLen % STEP_FOUR) { FindByTypeValueResponseErrorAssign(&attErrorObj, connect); attClientDataCallback->attClientCallback( connect->retGattConnectHandle, ATT_ERROR_RESPONSE_ID, &attErrorObj, NULL, attClientDataCallback->context); goto ATTFINDBYTYPEVALUERESPONSE_END; } else { inforNum = dataLen / STEP_FOUR; } attFindObj.findByTypeValueResponse.handleInfoList = MEM_MALLOC.alloc(sizeof(AttHandleInfo) * inforNum); attFindObj.findByTypeValueResponse.listNum = inforNum; data = (uint8_t *)BufferPtr(buffer); AttHandleInfo *handleInfoList = attFindObj.findByTypeValueResponse.handleInfoList; for (uint16_t indexNumber = 0; indexNumber < inforNum; ++indexNumber) { handleInfoList[indexNumber].attHandle = ((uint16_t *)(data + indexNumber * STEP_FOUR))[0]; handleInfoList[indexNumber].groupEndHandle = ((uint16_t *)(data + STEP_TWO + indexNumber * STEP_FOUR))[0]; } attClientDataCallback->attClientCallback(connect->retGattConnectHandle, ATT_FIND_BY_TYPE_VALUE_RESPONSE_ID, &attFindObj, NULL, attClientDataCallback->context); MEM_MALLOC.free(attFindObj.findByTypeValueResponse.handleInfoList); ATTFINDBYTYPEVALUERESPONSE_END: ListRemoveFirst(connect->instruct); AttReceiveSequenceScheduling(connect); return; } /** * @brief received readbytype request. * * @param1 connect Indicates the pointer to const AttConnectInfo. * @param2 buffer Indicates the pointer to Buffer. */ void AttReadByTypeRequest(AttConnectInfo *connect, const Buffer *buffer) { LOG_INFO("%{public}s enter", __FUNCTION__); if (connect == NULL) { LOG_WARN("%{public}s:connect == NULL and return", __FUNCTION__); return; } size_t buffSize; AttRead attReadObj; uint8_t *data = NULL; uint16_t uuidLen; AttServerDataCallback *attServerDataCallback = NULL; if (buffer == NULL) { goto ATTREADBYTYPEREQUEST_END; } if ((connect->transportType == BT_TRANSPORT_LE && connect->mtu == DEFAULTLEATTMTU) || (connect->transportType == BT_TRANSPORT_BR_EDR && connect->mtu == DEFAULTBREDRMTU)) { connect->mtuFlag = true; } attServerDataCallback = AttGetATTServerCallback(); if ((attServerDataCallback == NULL) || (attServerDataCallback->attServerCallback == NULL)) { LOG_WARN("%{public}s attServerDataCallback or attServerDataCallback->attServerCallback is NULL", __FUNCTION__); goto ATTREADBYTYPEREQUEST_END; } buffSize = BufferGetSize(buffer); data = (uint8_t *)BufferPtr(buffer); attReadObj.readHandleRangeUuid.handleRange.startHandle = ((uint16_t *)data)[0]; attReadObj.readHandleRangeUuid.handleRange.endHandle = ((uint16_t *)(data + STEP_TWO))[0]; uuidLen = buffSize - STEP_FOUR; attReadObj.readHandleRangeUuid.uuid = MEM_MALLOC.alloc(sizeof(BtUuid)); if (uuidLen == (uint16_t)UUID16BITTYPELEN) { attReadObj.readHandleRangeUuid.uuid->type = BT_UUID_16; attReadObj.readHandleRangeUuid.uuid->uuid16 = ((uint16_t *)(data + STEP_FOUR))[0]; LOG_INFO("%{public}s enter, callback para : type = %{public}d, uuid = %{public}d", __FUNCTION__, attReadObj.readHandleRangeUuid.uuid->type, attReadObj.readHandleRangeUuid.uuid->uuid16); } else if (uuidLen == (uint16_t)UUID128BITTYPELEN) { attReadObj.readHandleRangeUuid.uuid->type = BT_UUID_128; (void)memcpy_s(attReadObj.readHandleRangeUuid.uuid->uuid128, uuidLen, data + STEP_FOUR, uuidLen); } attServerDataCallback->attServerCallback( connect->retGattConnectHandle, ATT_READ_BY_TYPE_REQUEST_ID, &attReadObj, NULL, attServerDataCallback->context); MEM_MALLOC.free(attReadObj.readHandleRangeUuid.uuid); ATTREADBYTYPEREQUEST_END: return; } /** * @brief received readbytype response. * * @param1 connect Indicates the pointer to const AttConnectInfo. * @param2 buffer Indicates the pointer to Buffer. */ void AttReadByTypeResponse(AttConnectInfo *connect, const Buffer *buffer) { LOG_INFO("%{public}s enter", __FUNCTION__); if (connect == NULL) { LOG_ERROR("%{public}s connect is NULL", __FUNCTION__); return; } size_t dataLen; AttRead attReadObj; uint8_t len; uint16_t indexNum = 0; uint8_t *data = NULL; AttClientDataCallback *attClientDataCallback = NULL; AttError attErrorObj; AlarmCancel(connect->alarm); attClientDataCallback = AttGetATTClientCallback(); if ((attClientDataCallback == NULL) || (attClientDataCallback->attClientCallback == NULL || (buffer == NULL))) { goto ATTREADBYTYPERESPONSE_END; } dataLen = BufferGetSize(buffer); attReadObj.readHandleListNum.len = *(uint8_t *)BufferPtr(buffer); len = attReadObj.readHandleListNum.len; LOG_INFO("%{public}s callback para : len = %hhu", __FUNCTION__, len); if (len <= STEP_TWO) { LOG_ERROR("%{public}s len is 0", __FUNCTION__); attReadObj.readHandleListNum.valueNum = 0; } else if ((dataLen - 1) % len) { AttReadByTypeResErrorAssign(&attErrorObj, connect); attClientDataCallback->attClientCallback( connect->retGattConnectHandle, ATT_ERROR_RESPONSE_ID, &attErrorObj, NULL, attClientDataCallback->context); goto ATTREADBYTYPERESPONSE_END; } else { attReadObj.readHandleListNum.valueNum = (dataLen - 1) / len; } data = (uint8_t *)BufferPtr(buffer) + 1; attReadObj.readHandleListNum.valueList = MEM_MALLOC.alloc(sizeof(AttReadByTypeRspDataList) * attReadObj.readHandleListNum.valueNum); for (; indexNum < attReadObj.readHandleListNum.valueNum; ++indexNum) { attReadObj.readHandleListNum.valueList[indexNum].attributeValue = MEM_MALLOC.alloc(len - STEP_TWO); (void)memcpy_s( &attReadObj.readHandleListNum.valueList[indexNum], sizeof(AttReadByTypeRspDataList), data, STEP_TWO); (void)memcpy_s(attReadObj.readHandleListNum.valueList[indexNum].attributeValue, len - STEP_TWO, data + STEP_TWO, len - STEP_TWO); data += len; } attClientDataCallback->attClientCallback( connect->retGattConnectHandle, ATT_READ_BY_TYPE_RESPONSE_ID, &attReadObj, NULL, attClientDataCallback->context); AttReadFree(&attReadObj, attReadObj.readHandleListNum.valueNum, READBYTYPERESPONSEFREE); ATTREADBYTYPERESPONSE_END: ListRemoveFirst(connect->instruct); AttReceiveSequenceScheduling(connect); return; } /** * @brief received read request. * * @param1 connect Indicates the pointer to const AttConnectInfo. * @param2 buffer Indicates the pointer to Buffer. */ void AttReadRequest(AttConnectInfo *connect, const Buffer *buffer) { LOG_INFO("%{public}s enter", __FUNCTION__); if (connect == NULL) { LOG_WARN("%{public}s:connect == NULL and return", __FUNCTION__); return; } AttRead attReadObj; uint8_t *data = NULL; AttServerDataCallback *attServerDataCallback = NULL; if (buffer == NULL) { LOG_WARN("%{public}s:buffer == NULL", __FUNCTION__); goto ATTREADREQUEST_END; } if ((connect->transportType == BT_TRANSPORT_LE && connect->mtu == DEFAULTLEATTMTU) || (connect->transportType == BT_TRANSPORT_BR_EDR && connect->mtu == DEFAULTBREDRMTU)) { connect->mtuFlag = true; } attServerDataCallback = AttGetATTServerCallback(); if ((attServerDataCallback == NULL) || (attServerDataCallback->attServerCallback == NULL)) { LOG_WARN("%{public}s attServerDataCallback or attServerDataCallback->attServerCallback is NULL", __FUNCTION__); goto ATTREADREQUEST_END; } data = (uint8_t *)BufferPtr(buffer); attReadObj.readHandle.attHandle = ((uint16_t *)data)[0]; LOG_INFO("%{public}s connectHandle = %hu, callback para : attHandle = %{public}d", __FUNCTION__, connect->retGattConnectHandle, attReadObj.readHandle.attHandle); attServerDataCallback->attServerCallback( connect->retGattConnectHandle, ATT_READ_REQUEST_ID, &attReadObj, NULL, attServerDataCallback->context); ATTREADREQUEST_END: return; } /** * @brief received read response. * * @param1 connect Indicates the pointer to const AttConnectInfo. * @param2 buffer Indicates the pointer to Buffer. */ void AttReadResponse(AttConnectInfo *connect, const Buffer *buffer) { LOG_INFO("%{public}s enter", __FUNCTION__); if (connect == NULL) { LOG_WARN("%{public}s:connect == NULL and return", __FUNCTION__); return; } AttClientDataCallback *attClientDataCallback = NULL; if (buffer == NULL) { LOG_WARN("%{public}s:buffer == NULL", __FUNCTION__); } AlarmCancel(connect->alarm); attClientDataCallback = AttGetATTClientCallback(); if ((attClientDataCallback == NULL) || (attClientDataCallback->attClientCallback == NULL)) { LOG_WARN("%{public}s attClientDataCallback or attClientDataCallback->attClientCallback is NULL", __FUNCTION__); goto ATTREADRESPONSE_END; } attClientDataCallback->attClientCallback( connect->retGattConnectHandle, ATT_READ_RESPONSE_ID, NULL, (Buffer *)buffer, attClientDataCallback->context); ATTREADRESPONSE_END: LOG_INFO("%{public}s return connect != NULL, connectHandle = %hu", __FUNCTION__, connect->retGattConnectHandle); ListRemoveFirst(connect->instruct); AttReceiveSequenceScheduling(connect); return; } /** * @brief received readblob request. * * @param1 connect Indicates the pointer to const AttConnectInfo. * @param2 buffer Indicates the pointer to Buffer. */ void AttReadBlobRequest(AttConnectInfo *connect, const Buffer *buffer) { LOG_INFO("%{public}s enter", __FUNCTION__); if (connect == NULL) { LOG_WARN("%{public}s:connect == NULL and return", __FUNCTION__); return; } AttRead attReadObj; uint8_t *data = NULL; AttServerDataCallback *attServerDataCallback = NULL; if (buffer == NULL) { LOG_WARN("%{public}s:buffer == NULL", __FUNCTION__); goto ATTREADBLOBREQUEST_END; } if ((connect->transportType == BT_TRANSPORT_LE && connect->mtu == DEFAULTLEATTMTU) || (connect->transportType == BT_TRANSPORT_BR_EDR && connect->mtu == DEFAULTBREDRMTU)) { connect->mtuFlag = true; } attServerDataCallback = AttGetATTServerCallback(); if ((attServerDataCallback == NULL) || (attServerDataCallback->attServerCallback == NULL)) { LOG_WARN("%{public}s attServerDataCallback or attServerDataCallback->attServerCallback is NULL", __FUNCTION__); goto ATTREADBLOBREQUEST_END; } data = (uint8_t *)BufferPtr(buffer); attReadObj.readBlob.attHandle = ((uint16_t *)data)[0]; attReadObj.readBlob.offset = ((uint16_t *)(data + STEP_TWO))[0]; LOG_INFO("%{public}s connectHandle = %hu, callback para : attHandle = %{public}d, offset = %{public}d", __FUNCTION__, connect->retGattConnectHandle, attReadObj.readBlob.attHandle, attReadObj.readBlob.offset); attServerDataCallback->attServerCallback( connect->retGattConnectHandle, ATT_READ_BLOB_REQUEST_ID, &attReadObj, NULL, attServerDataCallback->context); ATTREADBLOBREQUEST_END: return; } /** * @brief received readblob response. * * @param1 connect Indicates the pointer to const AttConnectInfo. * @param2 buffer Indicates the pointer to Buffer. */ void AttReadBlobResponse(AttConnectInfo *connect, const Buffer *buffer) { LOG_INFO("%{public}s enter", __FUNCTION__); if (connect == NULL) { LOG_WARN("%{public}s:connect == NULL and return", __FUNCTION__); return; } if (buffer == NULL) { LOG_WARN("%{public}s:buffer == NULL", __FUNCTION__); } AttClientDataCallback *attClientDataCallback = NULL; AlarmCancel(connect->alarm); attClientDataCallback = AttGetATTClientCallback(); if ((attClientDataCallback == NULL) || (attClientDataCallback->attClientCallback == NULL)) { LOG_WARN("%{public}s attClientDataCallback or attClientDataCallback->attClientCallback is NULL", __FUNCTION__); goto ATTREADBLOBRESPONSE_END; } attClientDataCallback->attClientCallback(connect->retGattConnectHandle, ATT_READ_BLOB_RESPONSE_ID, NULL, (Buffer *)buffer, attClientDataCallback->context); ATTREADBLOBRESPONSE_END: LOG_INFO("%{public}s return connect != NULL, connectHandle = %hu", __FUNCTION__, connect->retGattConnectHandle); ListRemoveFirst(connect->instruct); AttReceiveSequenceScheduling(connect); return; } /** * @brief received readmultiple request. * * @param1 connect Indicates the pointer to const AttConnectInfo. * @param2 buffer Indicates the pointer to Buffer. */ void AttReadMultipleRequest(AttConnectInfo *connect, const Buffer *buffer) { LOG_INFO("%{public}s enter", __FUNCTION__); if (connect == NULL) { LOG_WARN("%{public}s:connect == NULL and return", __FUNCTION__); return; } AttServerDataCallback *attServerDataCallback = NULL; if (buffer == NULL) { LOG_WARN("%{public}s:buffer == NULL", __FUNCTION__); goto ATTREADMULTIPLEREQUEST_END; } if ((connect->transportType == BT_TRANSPORT_LE && connect->mtu == DEFAULTLEATTMTU) || (connect->transportType == BT_TRANSPORT_BR_EDR && connect->mtu == DEFAULTBREDRMTU)) { connect->mtuFlag = true; } attServerDataCallback = AttGetATTServerCallback(); if ((attServerDataCallback == NULL) || (attServerDataCallback->attServerCallback == NULL)) { LOG_WARN("%{public}s attServerDataCallback or attServerDataCallback->attServerCallback is NULL", __FUNCTION__); goto ATTREADMULTIPLEREQUEST_END; } LOG_INFO("%{public}s connectHandle = %hu", __FUNCTION__, connect->retGattConnectHandle); attServerDataCallback->attServerCallback(connect->retGattConnectHandle, ATT_READ_MULTIPLE_REQUEST_ID, NULL, (Buffer *)buffer, attServerDataCallback->context); ATTREADMULTIPLEREQUEST_END: return; } /** * @brief received readmultiple response. * * @param1 connect Indicates the pointer to const AttConnectInfo. * @param2 buffer Indicates the pointer to Buffer. */ void AttReadMultipleResponse(AttConnectInfo *connect, const Buffer *buffer) { LOG_INFO("%{public}s enter", __FUNCTION__); if (connect == NULL) { LOG_WARN("%{public}s:connect == NULL and return", __FUNCTION__); return; } AttClientDataCallback *attClientDataCallback = NULL; AlarmCancel(connect->alarm); if (buffer == NULL) { LOG_WARN("%{public}s:buffer == NULL", __FUNCTION__); } attClientDataCallback = AttGetATTClientCallback(); if ((attClientDataCallback == NULL) || (attClientDataCallback->attClientCallback == NULL)) { LOG_WARN("%{public}s attClientDataCallback or attClientDataCallback->attClientCallback is NULL", __FUNCTION__); goto ATTREADMULTIPLERESPONSE_END; } attClientDataCallback->attClientCallback(connect->retGattConnectHandle, ATT_READ_MULTIPLE_RESPONSE_ID, NULL, (Buffer *)buffer, attClientDataCallback->context); ATTREADMULTIPLERESPONSE_END: LOG_INFO("%{public}s return connect != NULL, connectHandle = %hu", __FUNCTION__, connect->retGattConnectHandle); ListRemoveFirst(connect->instruct); AttReceiveSequenceScheduling(connect); return; } /** * @brief received readbygrouptype request. * * @param1 connect Indicates the pointer to const AttConnectInfo. * @param2 buffer Indicates the pointer to Buffer. */ void AttReadByGroupTypeRequest(AttConnectInfo *connect, const Buffer *buffer) { LOG_INFO("%{public}s enter", __FUNCTION__); if (connect == NULL) { LOG_WARN("%{public}s:connect == NULL and return", __FUNCTION__); return; } AttRead attReadObj; uint8_t *data = NULL; size_t buffSize; AttServerDataCallback *attServerDataCallback = NULL; if ((connect->transportType == BT_TRANSPORT_LE && connect->mtu == DEFAULTLEATTMTU) || (connect->transportType == BT_TRANSPORT_BR_EDR && connect->mtu == DEFAULTBREDRMTU)) { connect->mtuFlag = true; } attServerDataCallback = AttGetATTServerCallback(); if ((attServerDataCallback == NULL) || (attServerDataCallback->attServerCallback == NULL) || (buffer == NULL)) { LOG_WARN("%{public}s attServerDataCallback or attServerDataCallback->attServerCallback is NULL", __FUNCTION__); goto ATTREADBYGROUPTYPEREQUEST_END; } data = (uint8_t *)BufferPtr(buffer); attReadObj.readGroupRequest.handleRange.startHandle = ((uint16_t *)data)[0]; attReadObj.readGroupRequest.handleRange.endHandle = ((uint16_t *)(data + STEP_TWO))[0]; buffSize = BufferGetSize(buffer); attReadObj.readGroupRequest.uuid = MEM_MALLOC.alloc(sizeof(BtUuid)); if ((buffSize - STEP_FOUR) == UUID16BITTYPELEN) { attReadObj.readGroupRequest.uuid->type = BT_UUID_16; attReadObj.readGroupRequest.uuid->uuid16 = ((uint16_t *)(data + STEP_FOUR))[0]; LOG_INFO("%{public}s enter, callback para : uuid_type = %{public}d, uuid = %{public}d", __FUNCTION__, attReadObj.readGroupRequest.uuid->type, attReadObj.readGroupRequest.uuid->uuid16); } else if ((buffSize - STEP_FOUR) == UUID128BITTYPELEN) { attReadObj.readGroupRequest.uuid->type = BT_UUID_128; (void)memcpy_s( attReadObj.readGroupRequest.uuid->uuid128, UUID128BITTYPELEN, data + STEP_FOUR, UUID128BITTYPELEN); } attServerDataCallback->attServerCallback(connect->retGattConnectHandle, ATT_READ_BY_GROUP_TYPE_REQUEST_ID, &attReadObj, NULL, attServerDataCallback->context); MEM_MALLOC.free(attReadObj.readGroupRequest.uuid); ATTREADBYGROUPTYPEREQUEST_END: return; } /** * @brief received readbygrouptype response error assign. * * @param1 attErrorObjPtr Indicates the pointer to AttError. * @param2 connect Indicates the pointer to AttConnectInfo. */ static void ReadByGroupTypeResponseErrorAssign(AttError *attErrorObjPtr, const AttConnectInfo *connect) { LOG_INFO("%{public}s enter", __FUNCTION__); if (attErrorObjPtr == NULL || connect == NULL) { LOG_WARN("%{public}s:attErrorObjPtr or connect is NULL, return", __FUNCTION__); return; } attErrorObjPtr->reqOpcode = READ_BY_GROUP_TYPE_REQUEST; attErrorObjPtr->errorCode = ATT_INVALID_ATTRIBUTE_VALUE_LENGTH; attErrorObjPtr->attHandleInError = connect->aclHandle; return; } /** * @brief received readbygrouptype response. * * @param1 connect Indicates the pointer to const AttConnectInfo. * @param2 buffer Indicates the pointer to Buffer. */ void AttReadByGroupTypeResponse(AttConnectInfo *connect, const Buffer *buffer) { LOG_INFO("%{public}s enter", __FUNCTION__); if (connect == NULL) { LOG_ERROR("%{public}s connect is NULL", __FUNCTION__); return; } size_t dataLen; AttRead attReadObj; uint8_t len; uint8_t *data = NULL; AttClientDataCallback *attClientDataCallback = NULL; AttError attErrorObj; AlarmCancel(connect->alarm); attClientDataCallback = AttGetATTClientCallback(); if ((attClientDataCallback == NULL) || (attClientDataCallback->attClientCallback == NULL) || (buffer == NULL)) { LOG_WARN("%{public}s attClientDataCallback or attClientDataCallback->attClientCallback is NULL", __FUNCTION__); goto ATTREADBYGROUPTYPERESPONSE_END; } dataLen = BufferGetSize(buffer); data = ((uint8_t *)BufferPtr(buffer) + 1); attReadObj.readGroupResponse.length = *(uint8_t *)BufferPtr(buffer); len = attReadObj.readGroupResponse.length; if (len == 0) { LOG_ERROR("%{public}s len is 0", __FUNCTION__); attReadObj.readGroupResponse.num = 0; } else if ((dataLen - 1) % len) { ReadByGroupTypeResponseErrorAssign(&attErrorObj, connect); attClientDataCallback->attClientCallback( connect->retGattConnectHandle, ATT_ERROR_RESPONSE_ID, &attErrorObj, NULL, attClientDataCallback->context); goto ATTREADBYGROUPTYPERESPONSE_END; } else { attReadObj.readGroupResponse.num = (dataLen - 1) / len; } attReadObj.readGroupResponse.attributeData = (AttReadGoupAttributeData *)MEM_MALLOC.alloc( sizeof(AttReadGoupAttributeData) * attReadObj.readGroupResponse.num); AttReadAttrAssign(&attReadObj, len, data); attClientDataCallback->attClientCallback(connect->retGattConnectHandle, ATT_READ_BY_GROUP_TYPE_RESPONSE_ID, &attReadObj, NULL, attClientDataCallback->context); AttReadFree(&attReadObj, attReadObj.readGroupResponse.num, READBYGROUPTYPERESPONSEFREE); ATTREADBYGROUPTYPERESPONSE_END: ListRemoveFirst(connect->instruct); AttReceiveSequenceScheduling(connect); return; } /** * @brief received write request. * * @param1 connect Indicates the pointer to const AttConnectInfo. * @param2 buffer Indicates the pointer to Buffer. */ void AttWriteRequest(AttConnectInfo *connect, const Buffer *buffer) { LOG_INFO("%{public}s enter", __FUNCTION__); if (connect == NULL) { LOG_ERROR("%{public}s connect is NULL", __FUNCTION__); return; } size_t buffSize; AttWrite attWriteObj; uint8_t *data = NULL; Buffer *bufferNew = NULL; AttServerDataCallback *attServerDataCallback = NULL; if ((connect->transportType == BT_TRANSPORT_LE && connect->mtu == DEFAULTLEATTMTU) || (connect->transportType == BT_TRANSPORT_BR_EDR && connect->mtu == DEFAULTBREDRMTU)) { connect->mtuFlag = true; } attServerDataCallback = AttGetATTServerCallback(); if ((attServerDataCallback == NULL) || (attServerDataCallback->attServerCallback == NULL)) { LOG_WARN("%{public}s attServerDataCallback or attServerDataCallback->attServerCallback is NULL", __FUNCTION__); goto ATTWRITEREQUEST_END; } buffSize = BufferGetSize(buffer); data = (uint8_t *)BufferPtr(buffer); attWriteObj.writeRequest.attHandle = ((uint16_t *)data)[0]; bufferNew = BufferSliceMalloc(buffer, STEP_TWO, buffSize - STEP_TWO); LOG_INFO("%{public}s connectHandle = %hu, callback para : attHandle = %{public}d", __FUNCTION__, connect->retGattConnectHandle, attWriteObj.writeRequest.attHandle); attServerDataCallback->attServerCallback( connect->retGattConnectHandle, ATT_WRITE_REQUEST_ID, &attWriteObj, bufferNew, attServerDataCallback->context); BufferFree(bufferNew); ATTWRITEREQUEST_END: return; } /** * @brief received write response. * * @param1 connect Indicates the pointer to const AttConnectInfo. * @param2 buffer Indicates the pointer to Buffer. */ void AttWriteResponse(AttConnectInfo *connect, const Buffer *buffer) { LOG_INFO("%{public}s enter", __FUNCTION__); if (connect == NULL) { LOG_ERROR("%{public}s connect is NULL", __FUNCTION__); return; } AttClientDataCallback *attClientDataCallback = NULL; AlarmCancel(connect->alarm); attClientDataCallback = AttGetATTClientCallback(); if ((attClientDataCallback == NULL) || (attClientDataCallback->attClientCallback == NULL)) { LOG_WARN("%{public}s attClientDataCallback or attClientDataCallback->attClientCallback is NULL", __FUNCTION__); goto ATTWRITERESPONSE_END; } attClientDataCallback->attClientCallback( connect->retGattConnectHandle, ATT_WRITE_RESPONSE_ID, NULL, (Buffer *)buffer, attClientDataCallback->context); ATTWRITERESPONSE_END: LOG_INFO("%{public}s return connect != NULL, connectHandle = %hu", __FUNCTION__, connect->retGattConnectHandle); ListRemoveFirst(connect->instruct); AttReceiveSequenceScheduling(connect); return; } /** * @brief received write command. * * @param1 connect Indicates the pointer to const AttConnectInfo. * @param2 buffer Indicates the pointer to Buffer. */ void AttWriteCommand(AttConnectInfo *connect, const Buffer *buffer) { LOG_INFO("%{public}s enter", __FUNCTION__); if (connect == NULL) { LOG_ERROR("%{public}s connect is NULL", __FUNCTION__); return; } size_t buffSize; AttWrite attWriteObj; uint8_t *data = NULL; AttServerDataCallback *attServerDataCallback = NULL; if (buffer == NULL) { LOG_WARN("%{public}s:buffer == NULL", __FUNCTION__); goto ATTWRITECOMMAND_END; } attServerDataCallback = AttGetATTServerCallback(); if ((attServerDataCallback == NULL) || (attServerDataCallback->attServerCallback == NULL)) { LOG_WARN("%{public}s attServerDataCallback or attServerDataCallback->attServerCallback is NULL", __FUNCTION__); goto ATTWRITECOMMAND_END; } buffSize = BufferGetSize(buffer); data = (uint8_t *)BufferPtr(buffer); attWriteObj.writeCommand.attHandle = ((uint16_t *)data)[0]; Buffer *bufferNew = BufferSliceMalloc(buffer, STEP_TWO, buffSize - STEP_TWO); LOG_INFO("%{public}s connectHandle = %hu, callback para : attHandle = %{public}d", __FUNCTION__, connect->retGattConnectHandle, attWriteObj.writeCommand.attHandle); attServerDataCallback->attServerCallback( connect->retGattConnectHandle, ATT_WRITE_COMMAND_ID, &attWriteObj, bufferNew, attServerDataCallback->context); BufferFree(bufferNew); ATTWRITECOMMAND_END: return; } /** * @brief received signedwrite command gap return value error assign. * * @param1 attWriteObjPtr Indicates the pointer to AttWrite. * @param2 ret Indicates the ret. * @param3 data Indicates the pdata. */ static void AttSignedWriteCommandGapRetErrorAssign(AttWrite *attWriteObjPtr, const uint8_t *data) { LOG_INFO("%{public}s enter", __FUNCTION__); if (attWriteObjPtr == NULL || data == NULL) { LOG_WARN("%{public}s:attWriteObjPtr or data is NULL, return", __FUNCTION__); return; } attWriteObjPtr->signedWriteCommand.attHandleValueObj.attHandle = ((uint16_t *)(data + 1))[0]; attWriteObjPtr->signedWriteCommand.authSignatureLen = GAPSIGNATURESIZE; return; } /** * @brief received signedwrite command. * * @param1 connect Indicates the pointer to const AttConnectInfo. * @param2 buffer Indicates the pointer to Buffer. */ void AttSignedWriteCommand(AttConnectInfo *connect, const Buffer *buffer) { LOG_INFO("%{public}s enter", __FUNCTION__); if (connect == NULL) { LOG_ERROR("%{public}s connect is NULL", __FUNCTION__); return; } size_t buffSize; AttWrite attWriteObj; uint8_t *data = NULL; uint8_t *dataBuffer = NULL; Buffer *bufferNew = NULL; Buffer *bufferallPtr = NULL; Buffer *sigedWriteBuffPtr = NULL; int ret; GapSignatureData gapSignatureDataObj; uint8_t signature[12] = {0}; AttServerDataCallback *attServerDataCallback = NULL; SigedWriteCommandConfirmationContext *sigedWriteCommandConfirmContextPtr = NULL; attServerDataCallback = AttGetATTServerCallback(); if ((attServerDataCallback == NULL) || (attServerDataCallback->attServerCallback == NULL) || (buffer == NULL)) { goto ATTSIGNEDWRITECOMMAND_END; } dataBuffer = (uint8_t *)BufferPtr(buffer); buffSize = BufferGetSize(buffer); bufferallPtr = BufferMalloc(buffSize + 1); data = (uint8_t *)BufferPtr(bufferallPtr); AttSignWriteCommConfDataAssign(data, dataBuffer, buffSize, signature); gapSignatureDataObj.data = data; if (buffSize < (sizeof(signature) - 1)) { LOG_ERROR("%{public}s buffSize is invalid", __FUNCTION__); goto ATTSIGNEDWRITECOMMAND_END; } gapSignatureDataObj.dataLen = buffSize - (sizeof(signature) - 1); sigedWriteBuffPtr = BufferMalloc(sizeof(SigedWriteCommandConfirmationContext)); sigedWriteCommandConfirmContextPtr = (SigedWriteCommandConfirmationContext *)BufferPtr(sigedWriteBuffPtr); AttSignWriteCommConfContextAssign(sigedWriteCommandConfirmContextPtr, connect, data, bufferallPtr, buffSize); uint8_t *arrayPtr = signature; ret = GAPIF_LeDataSignatureConfirmationAsync( &(connect->addr), gapSignatureDataObj, arrayPtr, AttGapSignatureConfirmationResult, sigedWriteBuffPtr); if (ret != BT_SUCCESS) { AttSignedWriteCommandGapRetErrorAssign(&attWriteObj, data); attWriteObj.signedWriteCommand.result = GAP_REJECT; (void)memcpy_s(attWriteObj.signedWriteCommand.authSignature, sizeof(signature), data + (buffSize - sizeof(signature)), sizeof(signature)); bufferNew = BufferSliceMalloc(buffer, STEP_TWO, buffSize - sizeof(signature) - sizeof(uint16_t)); attServerDataCallback->attServerCallback(connect->retGattConnectHandle, ATT_SIGNED_WRITE_COMMAND_ID, &attWriteObj, bufferNew, attServerDataCallback->context); AttSignedWriteCommandBufferFree(bufferNew, sigedWriteBuffPtr, bufferallPtr); } ATTSIGNEDWRITECOMMAND_END: return; } /** * @brief received preparewrite request. * * @param1 connect Indicates the pointer to const AttConnectInfo. * @param2 buffer Indicates the pointer to Buffer. */ void AttPrepareWriteRequest(AttConnectInfo *connect, const Buffer *buffer) { LOG_INFO("%{public}s enter", __FUNCTION__); if (connect == NULL) { LOG_ERROR("%{public}s connect is NULL", __FUNCTION__); return; } size_t buffSize; AttWrite attWriteObj; uint8_t *data = NULL; Buffer *bufferNew = NULL; AttServerDataCallback *attServerDataCallback = NULL; if (buffer == NULL) { LOG_WARN("%{public}s:buffer == NULL", __FUNCTION__); goto ATTPREPAREWRITEREQUEST_END; } if ((connect->transportType == BT_TRANSPORT_LE && connect->mtu == DEFAULTLEATTMTU) || (connect->transportType == BT_TRANSPORT_BR_EDR && connect->mtu == DEFAULTBREDRMTU)) { connect->mtuFlag = true; } attServerDataCallback = AttGetATTServerCallback(); if ((attServerDataCallback == NULL) || (attServerDataCallback->attServerCallback == NULL)) { LOG_WARN("%{public}s attServerDataCallback or attServerDataCallback->attServerCallback is NULL", __FUNCTION__); goto ATTPREPAREWRITEREQUEST_END; } buffSize = BufferGetSize(buffer); data = (uint8_t *)BufferPtr(buffer); attWriteObj.prepareWrite.handleValue.attHandle = ((uint16_t *)data)[0]; attWriteObj.prepareWrite.offset = ((uint16_t *)(data + STEP_TWO))[0]; bufferNew = BufferSliceMalloc(buffer, STEP_FOUR, buffSize - STEP_FOUR); LOG_INFO("%{public}s connectHandle = %hu, callback para : attHandle = %{public}d, offset = %{public}d", __FUNCTION__, connect->retGattConnectHandle, attWriteObj.prepareWrite.handleValue.attHandle, attWriteObj.prepareWrite.offset); attServerDataCallback->attServerCallback(connect->retGattConnectHandle, ATT_PREPARE_WRITE_REQUEST_ID, &attWriteObj, bufferNew, attServerDataCallback->context); BufferFree(bufferNew); ATTPREPAREWRITEREQUEST_END: return; } /** * @brief received preparewrite response. * * @param1 connect Indicates the pointer to const AttConnectInfo. * @param2 buffer Indicates the pointer to Buffer. */ void AttPrepareWriteResponse(AttConnectInfo *connect, const Buffer *buffer) { LOG_INFO("%{public}s enter", __FUNCTION__); if (connect == NULL) { LOG_ERROR("%{public}s connect is NULL", __FUNCTION__); return; } size_t buffSize; AttWrite attWriteObj; uint8_t *data = NULL; Buffer *bufferNew = NULL; AttClientDataCallback *attClientDataCallback = NULL; AlarmCancel(connect->alarm); if (buffer == NULL) { goto ATTPREPAREWRITERESPONSE_END; } attClientDataCallback = AttGetATTClientCallback(); if ((attClientDataCallback == NULL) || (attClientDataCallback->attClientCallback == NULL)) { LOG_WARN("%{public}s attClientDataCallback or attClientDataCallback->attClientCallback is NULL", __FUNCTION__); goto ATTPREPAREWRITERESPONSE_END; } buffSize = BufferGetSize(buffer); data = (uint8_t *)BufferPtr(buffer); attWriteObj.prepareWrite.handleValue.attHandle = ((uint16_t *)data)[0]; attWriteObj.prepareWrite.offset = ((uint16_t *)(data + STEP_TWO))[0]; if (buffSize - STEP_FOUR > 0) { bufferNew = BufferSliceMalloc(buffer, STEP_FOUR, buffSize - STEP_FOUR); attClientDataCallback->attClientCallback(connect->retGattConnectHandle, ATT_PREPARE_WRITE_RESPONSE_ID, &attWriteObj, bufferNew, attClientDataCallback->context); BufferFree(bufferNew); } else { attClientDataCallback->attClientCallback(connect->retGattConnectHandle, ATT_PREPARE_WRITE_RESPONSE_ID, &attWriteObj, NULL, attClientDataCallback->context); } ATTPREPAREWRITERESPONSE_END: LOG_INFO("%{public}s return connect != NULL, connectHandle = %hu", __FUNCTION__, connect->retGattConnectHandle); ListRemoveFirst(connect->instruct); AttReceiveSequenceScheduling(connect); return; } /** * @brief received executewrite request. * * @param1 connect Indicates the pointer to const AttConnectInfo. * @param2 buffer Indicates the pointer to Buffer. */ void AttExecuteWriteRequest(AttConnectInfo *connect, const Buffer *buffer) { LOG_INFO("%{public}s enter", __FUNCTION__); if (connect == NULL) { LOG_ERROR("%{public}s connect is NULL", __FUNCTION__); return; } AttWrite attWriteObj; uint8_t *data = NULL; AttServerDataCallback *attServerDataCallback = NULL; if (buffer == NULL) { LOG_WARN("%{public}s:buffer == NULL", __FUNCTION__); goto ATTEXECUTEWRITEREQUEST_END; } if ((connect->transportType == BT_TRANSPORT_LE && connect->mtu == DEFAULTLEATTMTU) || (connect->transportType == BT_TRANSPORT_BR_EDR && connect->mtu == DEFAULTBREDRMTU)) { connect->mtuFlag = true; } attServerDataCallback = AttGetATTServerCallback(); if ((attServerDataCallback == NULL) || (attServerDataCallback->attServerCallback == NULL)) { LOG_WARN("%{public}s attServerDataCallback or attServerDataCallback->attServerCallback is NULL", __FUNCTION__); goto ATTEXECUTEWRITEREQUEST_END; } data = (uint8_t *)BufferPtr(buffer); attWriteObj.excuteWrite.flag = data[0]; LOG_INFO("%{public}s connecthandle = %{public}d, callback para : flag = %{public}d", __FUNCTION__, connect->retGattConnectHandle, attWriteObj.excuteWrite.flag); attServerDataCallback->attServerCallback(connect->retGattConnectHandle, ATT_EXECUTE_WRITE_REQUEST_ID, &attWriteObj, NULL, attServerDataCallback->context); ATTEXECUTEWRITEREQUEST_END: return; } /** * @brief received executewrite response. * * @param1 connect Indicates the pointer to const AttConnectInfo. * @param2 buffer Indicates the pointer to Buffer. */ void AttExecuteWriteResponse(AttConnectInfo *connect, const Buffer *buffer) { LOG_INFO("%{public}s enter", __FUNCTION__); if (connect == NULL) { LOG_ERROR("%{public}s connect is NULL", __FUNCTION__); return; } AttClientDataCallback *attClientDataCallback = NULL; AlarmCancel(connect->alarm); if (buffer == NULL) { LOG_WARN("%{public}s:buffer == NULL", __FUNCTION__); goto ATTEXECUTEWRITERESPONSE_END; } attClientDataCallback = AttGetATTClientCallback(); if ((attClientDataCallback == NULL) || (attClientDataCallback->attClientCallback == NULL)) { LOG_WARN("%{public}s attClientDataCallback or attClientDataCallback->attClientCallback is NULL", __FUNCTION__); goto ATTEXECUTEWRITERESPONSE_END; } attClientDataCallback->attClientCallback( connect->retGattConnectHandle, ATT_EXECUTE_WRITE_RESPONSE_ID, NULL, NULL, attClientDataCallback->context); ATTEXECUTEWRITERESPONSE_END: LOG_INFO("%{public}s return connect != NULL, connectHandle = %hu", __FUNCTION__, connect->retGattConnectHandle); ListRemoveFirst(connect->instruct); AttReceiveSequenceScheduling(connect); return; } /** * @brief received handlevalue notification. * * @param1 connect Indicates the pointer to const AttConnectInfo. * @param2 buffer Indicates the pointer to Buffer. */ void AttHandleValueNotification(AttConnectInfo *connect, const Buffer *buffer) { LOG_INFO("%{public}s enter", __FUNCTION__); if (connect == NULL) { LOG_ERROR("%{public}s connect is NULL", __FUNCTION__); return; } size_t buffNotiSize; AttHandleValue AttHandleValueObj; uint8_t *data = NULL; Buffer *bufferNew = NULL; AttClientDataCallback *attClientDataCallback = NULL; if (buffer == NULL) { LOG_WARN("%{public}s:buffer == NULL", __FUNCTION__); goto ATTHANDLEVALUENOTIFICATION_END; } attClientDataCallback = AttGetATTClientCallback(); if ((attClientDataCallback == NULL) || (attClientDataCallback->attClientCallback == NULL)) { LOG_WARN("%{public}s attClientDataCallback or attClientDataCallback->attClientCallback is NULL", __FUNCTION__); goto ATTHANDLEVALUENOTIFICATION_END; } buffNotiSize = BufferGetSize(buffer); data = (uint8_t *)BufferPtr(buffer); AttHandleValueObj.attHandle = ((uint16_t *)data)[0]; bufferNew = BufferSliceMalloc(buffer, STEP_TWO, buffNotiSize - STEP_TWO); LOG_INFO("%{public}s connectHandle = %hu, callback para : attHandle = %{public}d", __FUNCTION__, connect->retGattConnectHandle, AttHandleValueObj.attHandle); attClientDataCallback->attClientCallback(connect->retGattConnectHandle, ATT_HANDLE_VALUE_NOTIFICATION_ID, &AttHandleValueObj, bufferNew, attClientDataCallback->context); BufferFree(bufferNew); ATTHANDLEVALUENOTIFICATION_END: return; } /** * @brief received handlevalue indication. * * @param1 connect Indicates the pointer to const AttConnectInfo. * @param2 buffer Indicates the pointer to Buffer. */ void AttHandleValueIndication(AttConnectInfo *connect, const Buffer *buffer) { LOG_INFO("%{public}s enter", __FUNCTION__); if (connect == NULL) { LOG_ERROR("%{public}s connect is NULL", __FUNCTION__); return; } size_t buffIndiSize; AttHandleValue AttHandleValueObj; uint8_t *data = NULL; Buffer *bufferNew = NULL; AttClientDataCallback *attClientDataCallback = NULL; if (buffer == NULL) { LOG_WARN("%{public}s:buffer == NULL", __FUNCTION__); goto ATTHANDLEVALUEINDICATION_END; } attClientDataCallback = AttGetATTClientCallback(); if ((attClientDataCallback == NULL) || (attClientDataCallback->attClientCallback == NULL)) { LOG_WARN("%{public}s attClientDataCallback or attClientDataCallback->attClientCallback is NULL", __FUNCTION__); goto ATTHANDLEVALUEINDICATION_END; } buffIndiSize = BufferGetSize(buffer); data = (uint8_t *)BufferPtr(buffer); AttHandleValueObj.attHandle = ((uint16_t *)data)[0]; bufferNew = BufferSliceMalloc(buffer, STEP_TWO, buffIndiSize - STEP_TWO); LOG_INFO("%{public}s connectHandle = %hu, callback para : attHandle = %{public}d", __FUNCTION__, connect->retGattConnectHandle, AttHandleValueObj.attHandle); attClientDataCallback->attClientCallback(connect->retGattConnectHandle, ATT_HANDLE_VALUE_INDICATION_ID, &AttHandleValueObj, bufferNew, attClientDataCallback->context); BufferFree(bufferNew); ATTHANDLEVALUEINDICATION_END: return; } /** * @brief received handlevalue confirmation. * * @param1 connect Indicates the pointer to const AttConnectInfo. * @param2 buffer Indicates the pointer to Buffer. */ void AttHandleValueConfirmation(AttConnectInfo *connect, const Buffer *buffer) { LOG_INFO("%{public}s enter", __FUNCTION__); if (connect == NULL) { LOG_ERROR("%{public}s connect is NULL", __FUNCTION__); return; } AttServerDataCallback *attServerDataCallback = NULL; AttWrite attWrite; attWrite.confirmation.attHandle = 0x0000; AlarmCancel(connect->alarm); if (buffer == NULL) { LOG_WARN("%{public}s:buffer == NULL", __FUNCTION__); goto ATTHANDLEVALUECONFIRMATION_END; } attServerDataCallback = AttGetATTServerCallback(); if ((attServerDataCallback == NULL) || (attServerDataCallback->attServerCallback == NULL)) { LOG_WARN("%{public}s attServerDataCallback or attServerDataCallback->attServerCallback is NULL", __FUNCTION__); goto ATTHANDLEVALUECONFIRMATION_END; } if (connect->serverSendFlag) { connect->serverSendFlag = false; } attServerDataCallback->attServerCallback(connect->retGattConnectHandle, ATT_HANDLE_VALUE_CONFIRMATION_ID, &attWrite, NULL, attServerDataCallback->context); ATTHANDLEVALUECONFIRMATION_END: LOG_INFO("%{public}s return connect != NULL, connectHandle = %hu", __FUNCTION__, connect->retGattConnectHandle); ListRemoveFirst(connect->instruct); AttReceiveSequenceScheduling(connect); return; } /** * @brief assign signedWriteCommand context. * * @param1 sigedWriteCommandConfirmContextPtr Indicates the pointer to SigedWriteCommandConfirmationContext. * @param2 connect Indicates the pointer to AttConnectInfo. * @param3 data Indicates the pointer to uint8_t. * @param4 bufferallPtr Indicates the pointer to Buffer. * @param5 buffSize Indicates the size_t. */ static void AttSignWriteCommConfContextAssign(SigedWriteCommandConfirmationContext *sigedWriteCommandConfirmContextPtr, const AttConnectInfo *connect, const uint8_t *data, const Buffer *bufferallPtr, const size_t buffSize) { LOG_INFO("%{public}s enter", __FUNCTION__); if (sigedWriteCommandConfirmContextPtr == NULL) { LOG_ERROR("%{public}s sigedWriteCommandConfirmContextPtr is NULL", __FUNCTION__); return; } sigedWriteCommandConfirmContextPtr->connect = (AttConnectInfo *)connect; sigedWriteCommandConfirmContextPtr->data = (uint8_t *)data; sigedWriteCommandConfirmContextPtr->bufferallPtr = (Buffer *)bufferallPtr; sigedWriteCommandConfirmContextPtr->bufferSize = buffSize - STEP_TWO - GAPSIGNATURESIZE; return; } /** * @brief assign signedWriteCommand data. * * @param1 data Indicates the pointer to uint8_t. * @param2 dataBuffer Indicates the pointer to Buffer. * @param3 buffSize Indicates the size_t. * @param4 signature Indicates the pointer to uint8_t. */ static void AttSignWriteCommConfDataAssign( uint8_t *data, const uint8_t *dataBuffer, size_t buffSize, uint8_t signature[12]) { LOG_INFO("%{public}s enter", __FUNCTION__); if (data == NULL || dataBuffer == NULL) { LOG_ERROR("%{public}s data or dataBuffer is NULL", __FUNCTION__); return; } if (buffSize < STEP_TWO + GAPSIGNATURESIZE) { LOG_ERROR("%{public}s buffSize is small", __FUNCTION__); return; } data[0] = SIGNED_WRITE_COMMAND; (void)memcpy_s(data + 1, buffSize, dataBuffer, buffSize); (void)memcpy_s(signature, GAPSIGNATURESIZE, dataBuffer + STEP_TWO + (buffSize - STEP_TWO - GAPSIGNATURESIZE), GAPSIGNATURESIZE); return; } /** * @brief assign signedWriteCommand data. * * @param1 bufferNew Indicates the pointer to Buffer. * @param2 sigedWriteBuffPtr Indicates the pointer to Buffer. * @param3 bufferallPtr Indicates the pointer to Buffer. */ static void AttSignedWriteCommandBufferFree(Buffer *bufferNew, Buffer *sigedWriteBuffPtr, Buffer *bufferallPtr) { LOG_INFO("%{public}s enter", __FUNCTION__); BufferFree(bufferNew); BufferFree(sigedWriteBuffPtr); BufferFree(bufferallPtr); return; } /** * @brief assign signedWriteCommand data. * * @param1 attErrorObjPtr Indicates the pointer to AttError. * @param2 connect Indicates the pointer to AttConnectInfo. */ static void AttReadByTypeResErrorAssign(AttError *attErrorObjPtr, const AttConnectInfo *connect) { LOG_INFO("%{public}s enter", __FUNCTION__); if (attErrorObjPtr == NULL || connect == NULL) { LOG_ERROR("%{public}s attErrorObjPtr or connect is NULL", __FUNCTION__); return; } attErrorObjPtr->reqOpcode = READ_BY_TYPE_REQUEST; attErrorObjPtr->errorCode = ATT_INVALID_ATTRIBUTE_VALUE_LENGTH; attErrorObjPtr->attHandleInError = connect->aclHandle; return; } /** * @brief function list init. * */ void FunctionListInit() { LOG_INFO("%{public}s enter", __FUNCTION__); recvDataFunction *functionList = GetFunctionArrayDress(); functionList[ERROR_RESPONSE] = AttErrorResponse; functionList[FIND_INFORMATION_REQUEST] = AttFindInformationRequest; functionList[FIND_INFORMATION_RESPONSE] = AttFindInformationResponse; functionList[FIND_BY_TYPE_VALUE_REQUEST] = AttFindByTypeValueRequest; functionList[FIND_BY_TYPE_VALUE_RESPONSE] = AttFindByTypeValueResponse; functionList[READ_BY_TYPE_REQUEST] = AttReadByTypeRequest; functionList[READ_BY_TYPE_RESPONSE] = AttReadByTypeResponse; functionList[READ_REQUEST] = AttReadRequest; functionList[READ_RESPONSE] = AttReadResponse; functionList[READ_BLOB_REQUEST] = AttReadBlobRequest; functionList[READ_BLOB_RESPONSE] = AttReadBlobResponse; functionList[READ_MULTIPLE_REQUEST] = AttReadMultipleRequest; functionList[READ_MULTIPLE_RESPONSE] = AttReadMultipleResponse; functionList[READ_BY_GROUP_TYPE_REQUEST] = AttReadByGroupTypeRequest; functionList[READ_BY_GROUP_TYPE_RESPONSE] = AttReadByGroupTypeResponse; functionList[WRITE_REQUEST] = AttWriteRequest; functionList[WRITE_RESPONSE] = AttWriteResponse; functionList[WRITE_COMMAND] = AttWriteCommand; functionList[SIGNED_WRITE_COMMAND] = AttSignedWriteCommand; functionList[PREPARE_WRITE_REQUEST] = AttPrepareWriteRequest; functionList[PREPARE_WRITE_RESPONSE] = AttPrepareWriteResponse; functionList[EXECUTE_WRITE_REQUEST] = AttExecuteWriteRequest; functionList[EXECUTE_WRITE_RESPONSE] = AttExecuteWriteResponse; functionList[HANDLE_VALUE_NOTIFICATION] = AttHandleValueNotification; functionList[HANDLE_VALUE_INDICATION] = AttHandleValueIndication; functionList[HANDLE_VALUE_CONFIRMATION] = AttHandleValueConfirmation; functionList[EXCHANGE_MTU_REQUEST] = AttExchangeMTURequest; functionList[EXCHANGE_MTU_RESPONSE] = AttExchangeMTUResponse; return; }