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_send.c
18  *
19  * @brief implement send function to be called.
20  *
21  */
22 
23 #include "att_common.h"
24 #include "att_receive.h"
25 
26 #include <memory.h>
27 
28 #include "buffer.h"
29 #include "list.h"
30 #include "packet.h"
31 
32 #include "log.h"
33 
34 #include "gap_if.h"
35 #include "gap_le_if.h"
36 
37 #include "platform/include/allocator.h"
38 
39 static AttServerSendDataCallback g_attServerSendDataCB;
40 
41 static void AttAssignMTU(uint16_t *mtu, AttConnectInfo *connect);
42 static void AttFindInformationResDataAssign(
43     uint8_t format, uint16_t *inforDataLenPtr, uint16_t *dataLenPtr, uint16_t pairNum);
44 
45 static void AttErrorResponseAsync(const void *context);
46 static void AttErrorResponseAsyncDestroy(const void *context);
47 static void AttExchangeMTUResponseAsync(const void *context);
48 static void AttExchangeMTUResponseAsyncDestroy(const void *context);
49 static void AttFindInformationResponseAsync(const void *context);
50 static void AttFindInformationResponseAsyncDestroy(const void *context);
51 static void AttFindByTypeValueResponseAsync(const void *context);
52 static void AttFindByTypeValueResponseAsyncDestroy(const void *context);
53 static void AttReadByTypeResponseAsync(const void *context);
54 static void AttReadByTypeResponseAsyncDestroy(const void *context);
55 static void AttReadResponseAsync(const void *context);
56 static void AttReadResponseAsyncDestroy(const void *context);
57 static void AttReadBlobResponseAsync(const void *context);
58 static void AttReadBlobResponseAsyncDestroy(const void *context);
59 static void AttReadMultipleResponseAsync(const void *context);
60 static void AttReadMultipleResponseAsyncDestroy(const void *context);
61 static void AttReadByGroupTypeResponseAsync(const void *context);
62 static void AttReadByGroupTypeResponseAsyncDestroy(const void *context);
63 static void AttWriteResponseAsync(const void *context);
64 static void AttWriteResponseAsyncDestroy(const void *context);
65 static void AttPrepareWriteResponseAsync(const void *context);
66 static void AttPrepareWriteResponseAsyncDestroy(const void *context);
67 static void AttExecuteWriteResponseAsync(const void *context);
68 static void AttExecuteWriteResponseAsyncDestroy(const void *context);
69 static void AttHandleValueNotificationAsync(const void *context);
70 static void AttHandleValueNotificationAsyncDestroy(const void *context);
71 static void AttHandleValueIndicationAsync(const void *context);
72 static void AttHandleValueIndicationAsyncDestroy(const void *context);
73 
74 static void AttReadByTypeResponseFree(ReadByTypeResponseAsync *readByTypeResAsyncPtr);
75 static void AttFindInformationResponsePacketDataAssign(
76     uint8_t *data, FindInformationResponseAsync *findInforPtr, uint16_t dataLen);
77 static void AttReadByGroupTypeResponseAsyncFree(
78     ReadByGroupTypeResponseAsync *attReadByGroupResponseAsyncPtr, uint16_t num);
79 
80 static void AttServerSendDataRegisterAsync(const void *context);
81 static void AttServerSendDataRegisterAsyncDestroy(const void *context);
82 static void AttServerSendDataDeRegisterAsync(const void *context);
83 static void AttServerSendDataDeRegisterAsyncDestroy(const void *context);
84 
85 /**
86  * @brief Assign to mtu.
87  *
88  * @param1 mtu Indicates the pointer to mtu.
89  * @param2 connect Indicates the pointer to AttConnectInfo.
90  */
AttAssignMTU(uint16_t * mtu,AttConnectInfo * connect)91 void AttAssignMTU(uint16_t *mtu, AttConnectInfo *connect)
92 {
93     LOG_INFO("%{public}s enter", __FUNCTION__);
94 
95     if (connect == NULL) {
96         LOG_INFO("%{public}s connect == NULL", __FUNCTION__);
97         return;
98     }
99 
100     if (connect->mtuFlag) {
101         connect->mtuFlag = false;
102         if (connect->transportType == BT_TRANSPORT_BR_EDR) {
103             *mtu = DEFAULTBREDRMTU;
104         }
105         if (connect->transportType == BT_TRANSPORT_LE) {
106             *mtu = DEFAULTLEATTMTU;
107         }
108     } else {
109         *mtu = connect->mtu;
110     }
111 
112     return;
113 }
114 
115 /**
116  * @brief error response in self thread..
117  *
118  * @param context Indicates the pointer to context.
119  */
AttErrorResponseAsync(const void * context)120 static void AttErrorResponseAsync(const void *context)
121 {
122     LOG_INFO("%{public}s enter", __FUNCTION__);
123 
124     uint16_t index = 0;
125     int ret;
126     uint8_t *data = NULL;
127     Packet *packet = NULL;
128     AttConnectInfo *connect = NULL;
129     ErrorResponseAsync *errorResAsyncPtr = NULL;
130 
131     errorResAsyncPtr = (ErrorResponseAsync *)context;
132 
133     AttGetConnectInfoIndexByConnectHandle(errorResAsyncPtr->connectHandle, &index, &connect);
134 
135     if (connect == NULL) {
136         LOG_INFO("%{public}s connect == NULL, and goto ATT_ERRORRESPONSE_END", __FUNCTION__);
137         goto ATT_ERRORRESPONSE_END;
138     }
139 
140     packet = PacketMalloc(0, 0, sizeof(uint8_t) + STEP_FOUR);
141     if (packet == NULL) {
142         LOG_ERROR("point to NULL");
143         return;
144     }
145     data = BufferPtr(PacketContinuousPayload(packet));
146     data[0] = ERROR_RESPONSE;
147     data[1] = errorResAsyncPtr->ATTErrorPtr->reqOpcode;
148     ((uint16_t *)(data + STEP_TWO))[0] = errorResAsyncPtr->ATTErrorPtr->attHandleInError;
149     data[STEP_FOUR] = errorResAsyncPtr->ATTErrorPtr->errorCode;
150 
151     ret = AttResponseSendData(connect, packet);
152     ServerCallbackReturnValue(ret, connect);
153     PacketFree(packet);
154 
155 ATT_ERRORRESPONSE_END:
156     MEM_MALLOC.free(errorResAsyncPtr->ATTErrorPtr);
157     MEM_MALLOC.free(errorResAsyncPtr);
158     return;
159 }
160 
161 /**
162  * @brief destroy error response in self thread..
163  *
164  * @param context Indicates the pointer to context.
165  */
AttErrorResponseAsyncDestroy(const void * context)166 static void AttErrorResponseAsyncDestroy(const void *context)
167 {
168     LOG_INFO("%{public}s enter", __FUNCTION__);
169 
170     ErrorResponseAsync *errorResAsyncPtr = (ErrorResponseAsync *)context;
171 
172     MEM_MALLOC.free(errorResAsyncPtr->ATTErrorPtr);
173     MEM_MALLOC.free(errorResAsyncPtr);
174 
175     return;
176 }
177 
178 /**
179  * @brief gatt send error response to att.
180  *
181  * @param1 connectHandle Indicates the connect handle.
182  * @param2 attErrorPtr Indicates the pointer to const error response parameter.
183  * @return Returns <b>0</b> if the operation is successful; returns <b>!0</b> if the operation fails.
184  */
ATT_ErrorResponse(uint16_t connectHandle,const AttError * attErrorPtr)185 void ATT_ErrorResponse(uint16_t connectHandle, const AttError *attErrorPtr)
186 {
187     LOG_INFO("%{public}s enter, connectHandle = %hu, reqOpcode = %{public}d, "
188         "attHandleInError = %{public}d, errorCode = %{public}d",
189         __FUNCTION__,
190         connectHandle,
191         attErrorPtr->reqOpcode,
192         attErrorPtr->attHandleInError,
193         attErrorPtr->errorCode);
194 
195     AttError *attErrorAsyncPtr = NULL;
196     ErrorResponseAsync *errorResAsyncPtr = NULL;
197 
198     attErrorAsyncPtr = MEM_MALLOC.alloc(sizeof(AttError));
199     if (attErrorAsyncPtr == NULL) {
200         LOG_ERROR("point to NULL");
201         return;
202     }
203     attErrorAsyncPtr->reqOpcode = attErrorPtr->reqOpcode;
204     attErrorAsyncPtr->attHandleInError = attErrorPtr->attHandleInError;
205     attErrorAsyncPtr->errorCode = attErrorPtr->errorCode;
206 
207     errorResAsyncPtr = MEM_MALLOC.alloc(sizeof(ErrorResponseAsync));
208     if (errorResAsyncPtr == NULL) {
209         LOG_ERROR("point to NULL");
210         return;
211     }
212     errorResAsyncPtr->connectHandle = connectHandle;
213     errorResAsyncPtr->ATTErrorPtr = attErrorAsyncPtr;
214 
215     AttAsyncProcess(AttErrorResponseAsync, AttErrorResponseAsyncDestroy, errorResAsyncPtr);
216 
217     return;
218 }
219 
220 /**
221  * @brief exchange mtu response in self thread..
222  *
223  * @param context Indicates the pointer to context.
224  */
AttExchangeMTUResponseAsync(const void * context)225 static void AttExchangeMTUResponseAsync(const void *context)
226 {
227     LOG_INFO("%{public}s enter", __FUNCTION__);
228 
229     int ret;
230     uint16_t index = 0;
231     ExchangeMTUAsync *exchangeMtuResPtr = (ExchangeMTUAsync *)context;
232     AttConnectInfo *connect = NULL;
233     Packet *packet = NULL;
234     uint8_t *data = NULL;
235 
236     AttGetConnectInfoIndexByConnectHandle(exchangeMtuResPtr->connectHandle, &index, &connect);
237 
238     if (connect == NULL) {
239         LOG_INFO("%{public}s connect == NULL and goto ATTEXCHANGEMTURESPONSE_END", __FUNCTION__);
240         goto ATTEXCHANGEMTURESPONSE_END;
241     }
242 
243     packet = PacketMalloc(0, 0, sizeof(uint8_t) + sizeof(exchangeMtuResPtr->mtu));
244     if (packet == NULL) {
245         LOG_ERROR("point to NULL");
246         return;
247     }
248     data = BufferPtr(PacketContinuousPayload(packet));
249     data[0] = EXCHANGE_MTU_RESPONSE;
250     ((uint16_t *)(data + 1))[0] = exchangeMtuResPtr->mtu;
251     connect->mtu = Min(connect->receiveMtu, exchangeMtuResPtr->mtu);
252 
253     ret = AttResponseSendData(connect, packet);
254     ServerCallbackReturnValue(ret, connect);
255 
256     PacketFree(packet);
257 
258 ATTEXCHANGEMTURESPONSE_END:
259     MEM_MALLOC.free(exchangeMtuResPtr);
260     return;
261 }
262 
263 /**
264  * @brief destroy exchange mtu response in self thread..
265  *
266  * @param context Indicates the pointer to context.
267  */
AttExchangeMTUResponseAsyncDestroy(const void * context)268 static void AttExchangeMTUResponseAsyncDestroy(const void *context)
269 {
270     LOG_INFO("%{public}s enter", __FUNCTION__);
271 
272     ExchangeMTUAsync *exchangeMtuResPtr = (ExchangeMTUAsync *)context;
273 
274     MEM_MALLOC.free(exchangeMtuResPtr);
275 
276     return;
277 }
278 
279 /**
280  * @brief gatt send exchangeMTU response to att.
281  *
282  * @param1 connectHandle Indicates the connect handle.
283  * @param2 serverRxMTU Indicates the attribute server receive MTU size.
284  * @return Returns <b>0</b> if the operation is successful; returns <b>!0</b> if the operation fails.
285  */
ATT_ExchangeMTUResponse(uint16_t connectHandle,uint16_t serverRxMTU)286 void ATT_ExchangeMTUResponse(uint16_t connectHandle, uint16_t serverRxMTU)
287 {
288     LOG_INFO("%{public}s enter, connectHandle = %hu, serverRxMTU = %hu", __FUNCTION__, connectHandle, serverRxMTU);
289 
290     ExchangeMTUAsync *exchangeMtuResPtr = MEM_MALLOC.alloc(sizeof(ExchangeMTUAsync));
291     if (exchangeMtuResPtr == NULL) {
292         if (g_attServerSendDataCB.attSendDataCB != NULL) {
293             g_attServerSendDataCB.attSendDataCB(connectHandle, BT_NO_MEMORY, g_attServerSendDataCB.context);
294         }
295         return;
296     }
297     exchangeMtuResPtr->connectHandle = connectHandle;
298     exchangeMtuResPtr->mtu = serverRxMTU;
299     AttAsyncProcess(AttExchangeMTUResponseAsync, AttExchangeMTUResponseAsyncDestroy, exchangeMtuResPtr);
300 
301     return;
302 }
303 
304 /**
305  * @brief find information response data assign.
306  *
307  * @param1 inforDataLenPtr Indicates the pointer of uint16_t.
308  * @param2 dataLenPtr Indicates the pointer of uint16_t.
309  */
AttFindInformationResDataAssign(uint8_t format,uint16_t * inforDataLenPtr,uint16_t * dataLenPtr,uint16_t pairNum)310 void AttFindInformationResDataAssign(uint8_t format, uint16_t *inforDataLenPtr, uint16_t *dataLenPtr, uint16_t pairNum)
311 {
312     LOG_INFO("%{public}s enter", __FUNCTION__);
313 
314     if (format == HANDLEAND16BITBLUETOOTHUUID) {
315         *inforDataLenPtr = FINDINFORRESINFOR16BITLEN * pairNum;
316         *dataLenPtr = FINDINFORRESINFOR16BITLEN;
317     } else if (format == HANDLEAND128BITUUID) {
318         *inforDataLenPtr = FINDINFORRESINFOR128BITLEN * pairNum;
319         *dataLenPtr = FINDINFORRESINFOR128BITLEN;
320     }
321 
322     return;
323 }
324 
AttFindInformationResponsePacketDataAssign(uint8_t * data,FindInformationResponseAsync * findInforPtr,uint16_t dataLen)325 void AttFindInformationResponsePacketDataAssign(
326     uint8_t *data, FindInformationResponseAsync *findInforPtr, uint16_t dataLen)
327 {
328     LOG_INFO("%{public}s enter", __FUNCTION__);
329 
330     uint16_t index;
331 
332     data[0] = FIND_INFORMATION_RESPONSE;
333     data[1] = findInforPtr->attFindInformationResContext.format;
334     data += STEP_TWO;
335     for (index = 0; index < findInforPtr->attFindInformationResContext.pairNum; ++index) {
336         ((uint16_t *)(data))[0] = findInforPtr->attFindInformationResContext.handleUuidPairs[index].attHandle;
337         if (findInforPtr->attFindInformationResContext.format == HANDLEAND16BITBLUETOOTHUUID) {
338             ((uint16_t *)(data + STEP_TWO))[0] =
339                 findInforPtr->attFindInformationResContext.handleUuidPairs[index].uuid.uuid16;
340         } else if (findInforPtr->attFindInformationResContext.format == HANDLEAND128BITUUID) {
341             if (memcpy_s(data + STEP_TWO,
342                 UUID128BITTYPELEN,
343                 findInforPtr->attFindInformationResContext.handleUuidPairs[index].uuid.uuid128,
344                 UUID128BITTYPELEN) != EOK) {
345                     LOG_ERROR("%{public}s memcpy_s fail", __FUNCTION__);
346                     return;
347                 }
348         }
349         data += dataLen;
350     }
351 
352     return;
353 }
354 
355 /**
356  * @brief find information response in self thread..
357  *
358  * @param context Indicates the pointer to context.
359  */
AttFindInformationResponseAsync(const void * context)360 static void AttFindInformationResponseAsync(const void *context)
361 {
362     LOG_INFO("%{public}s enter", __FUNCTION__);
363 
364     uint16_t index = 0;
365     int ret;
366     FindInformationResponseAsync *findInforPtr = (FindInformationResponseAsync *)context;
367     Packet *packet = NULL;
368     uint8_t *data = NULL;
369     uint16_t mtu = 0;
370     uint16_t inforDataLen = 0;
371     AttConnectInfo *connect = NULL;
372     uint16_t dataLen = 0;
373 
374     AttGetConnectInfoIndexByConnectHandle(findInforPtr->connectHandle, &index, &connect);
375     if (connect == NULL) {
376         LOG_INFO("%{public}s connect == NULL and goto ATTFINDINFORMATIONRESPONSE_END", __FUNCTION__);
377         goto ATTFINDINFORMATIONRESPONSE_END;
378     }
379     AttAssignMTU(&mtu, connect);
380     AttFindInformationResDataAssign(findInforPtr->attFindInformationResContext.format,
381         &inforDataLen,
382         &dataLen,
383         findInforPtr->attFindInformationResContext.pairNum);
384 
385     if (inforDataLen > (mtu - STEP_TWO)) {
386         LOG_INFO("%{public}s inforDataLen > (mtu - 2)", __FUNCTION__);
387         ServerCallbackBTBADPARAM(connect);
388         goto ATTFINDINFORMATIONRESPONSE_END;
389     }
390 
391     packet = PacketMalloc(0, 0, sizeof(uint8_t) + sizeof(uint8_t) + inforDataLen);
392     if (packet == NULL) {
393         LOG_ERROR("point to NULL");
394         return;
395     }
396     data = BufferPtr(PacketContinuousPayload(packet));
397     AttFindInformationResponsePacketDataAssign(data, findInforPtr, dataLen);
398 
399     ret = AttResponseSendData(connect, packet);
400     ServerCallbackReturnValue(ret, connect);
401     PacketFree(packet);
402 
403 ATTFINDINFORMATIONRESPONSE_END:
404     MEM_MALLOC.free(findInforPtr->attFindInformationResContext.handleUuidPairs);
405     MEM_MALLOC.free(findInforPtr);
406     return;
407 }
408 
409 /**
410  * @brief find information response in self thread..
411  *
412  * @param context Indicates the pointer to context.
413  */
AttFindInformationResponseAsyncDestroy(const void * context)414 static void AttFindInformationResponseAsyncDestroy(const void *context)
415 {
416     LOG_INFO("%{public}s enter", __FUNCTION__);
417 
418     FindInformationResponseAsync *findInforPtr = (FindInformationResponseAsync *)context;
419 
420     MEM_MALLOC.free(findInforPtr->attFindInformationResContext.handleUuidPairs);
421     MEM_MALLOC.free(findInforPtr);
422 
423     return;
424 }
425 
426 /**
427  * @brief gatt send findInformation response to att.
428  *
429  * @param1 connectHandle Indicates the connect handle.
430  * @param2 format Indicates the format of the information data.
431  * @param3 handleUUIDPairs Indicates the pointer to const information data whose format is determined by the Format
432  * field.
433  * @param4 pairNum Indicates the paris number of the Information Data.
434  * @return Returns <b>0</b> if the operation is successful; returns <b>!0</b> if the operation fails.
435  */
ATT_FindInformationResponse(uint16_t connectHandle,uint8_t format,AttHandleUuid * handleUUIDPairs,uint16_t pairNum)436 void ATT_FindInformationResponse(
437     uint16_t connectHandle, uint8_t format, AttHandleUuid *handleUUIDPairs, uint16_t pairNum)
438 {
439     LOG_INFO("%{public}s enter, connectHandle = %hu, format=%hhu, pairNum=%hu",
440         __FUNCTION__, connectHandle, format, pairNum);
441 
442     uint16_t index;
443 
444     AttHandleUuid *attHandleUuidPtr = MEM_MALLOC.alloc(sizeof(AttHandleUuid) * pairNum);
445     if (attHandleUuidPtr == NULL) {
446         LOG_WARN("attHandleUuidPtr is null");
447         return;
448     }
449 
450     for (index = 0; index < pairNum; ++index) {
451         attHandleUuidPtr[index].attHandle = handleUUIDPairs[index].attHandle;
452         if (format == HANDLEAND16BITBLUETOOTHUUID) {
453             attHandleUuidPtr[index].uuid.uuid16 = handleUUIDPairs[index].uuid.uuid16;
454         } else if (format == HANDLEAND128BITUUID) {
455             (void)memcpy_s(attHandleUuidPtr[index].uuid.uuid128,
456                 UUID128BITTYPELEN,
457                 handleUUIDPairs[index].uuid.uuid128,
458                 UUID128BITTYPELEN);
459         }
460     }
461     FindInformationResponseAsync *findInfor = MEM_MALLOC.alloc(sizeof(FindInformationResponseAsync));
462     if (findInfor == NULL) {
463         LOG_ERROR("point to NULL");
464         return;
465     }
466     findInfor->connectHandle = connectHandle;
467     findInfor->attFindInformationResContext.format = format;
468     findInfor->attFindInformationResContext.pairNum = pairNum;
469     findInfor->attFindInformationResContext.handleUuidPairs = attHandleUuidPtr;
470 
471     AttAsyncProcess(AttFindInformationResponseAsync, AttFindInformationResponseAsyncDestroy, findInfor);
472 
473     return;
474 }
475 
476 /**
477  * @brief find by type value response in self thread..
478  *
479  * @param context Indicates the pointer to context.
480  */
AttFindByTypeValueResponseAsync(const void * context)481 static void AttFindByTypeValueResponseAsync(const void *context)
482 {
483     LOG_INFO("%{public}s enter", __FUNCTION__);
484 
485     uint16_t index = 0;
486     uint16_t mtu = 0;
487     AttConnectInfo *connect = NULL;
488     FindByTypeValueResponseAsync *findByTypeResAsyncPtr = (FindByTypeValueResponseAsync *)context;
489     uint16_t handleInfoListLen = (findByTypeResAsyncPtr->attFindByTypeResContext.listNum) * sizeof(AttHandleInfo);
490     int ret;
491 
492     AttGetConnectInfoIndexByConnectHandle(findByTypeResAsyncPtr->connectHandle, &index, &connect);
493 
494     if (connect == NULL) {
495         LOG_INFO("%{public}s connect == NULL and goto ATTFINDBYTYPEVALUERESPONSE_END", __FUNCTION__);
496         goto ATTFINDBYTYPEVALUERESPONSE_END;
497     }
498 
499     AttAssignMTU(&mtu, connect);
500 
501     if (handleInfoListLen > (mtu - 1)) {
502         ServerCallbackBTBADPARAM(connect);
503         goto ATTFINDBYTYPEVALUERESPONSE_END;
504     }
505 
506     uint16_t handlesInforLen = sizeof(AttHandleInfo) * (findByTypeResAsyncPtr->attFindByTypeResContext.listNum);
507     Packet *packet = PacketMalloc(0, 0, sizeof(uint8_t) + handlesInforLen);
508     if (packet == NULL) {
509         LOG_ERROR("point to NULL");
510         return;
511     }
512     uint8_t *data = BufferPtr(PacketContinuousPayload(packet));
513     data[0] = FIND_BY_TYPE_VALUE_RESPONSE;
514     (void)memcpy_s(
515         data + 1, handleInfoListLen, findByTypeResAsyncPtr->attFindByTypeResContext.handleInfoList, handleInfoListLen);
516 
517     ret = AttResponseSendData(connect, packet);
518     ServerCallbackReturnValue(ret, connect);
519     PacketFree(packet);
520 
521 ATTFINDBYTYPEVALUERESPONSE_END:
522     MEM_MALLOC.free(findByTypeResAsyncPtr->attFindByTypeResContext.handleInfoList);
523     MEM_MALLOC.free(findByTypeResAsyncPtr);
524     return;
525 }
526 
527 /**
528  * @brief destroy find by type value response in self thread..
529  *
530  * @param context Indicates the pointer to context.
531  */
AttFindByTypeValueResponseAsyncDestroy(const void * context)532 static void AttFindByTypeValueResponseAsyncDestroy(const void *context)
533 {
534     LOG_INFO("%{public}s enter", __FUNCTION__);
535 
536     FindByTypeValueResponseAsync *findByTypeResAsyncDesPtr = (FindByTypeValueResponseAsync *)context;
537 
538     MEM_MALLOC.free(findByTypeResAsyncDesPtr->attFindByTypeResContext.handleInfoList);
539     MEM_MALLOC.free(findByTypeResAsyncDesPtr);
540 
541     return;
542 }
543 
544 /**
545  * @brief gatt send findbytypevalue response to att.
546  *
547  * @param1 connectHandle Indicates the connect handle.
548  * @param2 handleInfoList Indicates the pointer to const a list of 1 or more Handle Informations.
549  * @param3 listNum Indicates the number of handles information list.
550  * @return Returns <b>0</b> if the operation is successful; returns <b>!0</b> if the operation fails.
551  */
ATT_FindByTypeValueResponse(uint16_t connectHandle,const AttHandleInfo * handleInfoList,uint16_t listNum)552 void ATT_FindByTypeValueResponse(uint16_t connectHandle, const AttHandleInfo *handleInfoList, uint16_t listNum)
553 {
554     LOG_INFO("%{public}s enter,connectHandle = %hu,listNum=%hu", __FUNCTION__, connectHandle, listNum);
555 
556     AttHandleInfo *attHandleInfoPtr = MEM_MALLOC.alloc(sizeof(AttHandleInfo) * listNum);
557     if (attHandleInfoPtr == NULL) {
558         LOG_ERROR("point to NULL");
559         return;
560     }
561     (void)memcpy_s(attHandleInfoPtr, sizeof(AttHandleInfo) * listNum, handleInfoList, sizeof(AttHandleInfo) * listNum);
562     FindByTypeValueResponseAsync *findByTypeResAsyncPtr = MEM_MALLOC.alloc(sizeof(FindByTypeValueResponseAsync));
563     if (findByTypeResAsyncPtr == NULL) {
564         LOG_ERROR("point to NULL");
565         return;
566     }
567     findByTypeResAsyncPtr->connectHandle = connectHandle;
568     findByTypeResAsyncPtr->attFindByTypeResContext.listNum = listNum;
569     findByTypeResAsyncPtr->attFindByTypeResContext.handleInfoList = attHandleInfoPtr;
570 
571     AttAsyncProcess(AttFindByTypeValueResponseAsync, AttFindByTypeValueResponseAsyncDestroy, findByTypeResAsyncPtr);
572 
573     return;
574 }
575 
AttReadByTypeResponseFree(ReadByTypeResponseAsync * readByTypeResAsyncPtr)576 static void AttReadByTypeResponseFree(ReadByTypeResponseAsync *readByTypeResAsyncPtr)
577 {
578     LOG_INFO("%{public}s enter", __FUNCTION__);
579 
580     uint16_t index = 0;
581 
582     for (; index < readByTypeResAsyncPtr->attReadByTypeRspContext.valueNum; ++index) {
583         MEM_MALLOC.free(readByTypeResAsyncPtr->attReadByTypeRspContext.valueList[index].attributeValue);
584     }
585     MEM_MALLOC.free(readByTypeResAsyncPtr->attReadByTypeRspContext.valueList);
586     MEM_MALLOC.free(readByTypeResAsyncPtr);
587 
588     return;
589 }
590 
591 /**
592  * @brief read by type response in self thread..
593  *
594  * @param context Indicates the pointer to context.
595  */
AttReadByTypeResponseAsync(const void * context)596 static void AttReadByTypeResponseAsync(const void *context)
597 {
598     LOG_INFO("%{public}s enter", __FUNCTION__);
599 
600     uint16_t index = 0;
601     uint16_t mtu = 0;
602 
603     ReadByTypeResponseAsync *readByTypeResAsyncPtr = (ReadByTypeResponseAsync *)context;
604     Buffer *bufferPtr = NULL;
605     AttConnectInfo *connect = NULL;
606 
607     uint8_t len = readByTypeResAsyncPtr->attReadByTypeRspContext.len;
608     uint16_t num = readByTypeResAsyncPtr->attReadByTypeRspContext.valueNum;
609     AttGetConnectInfoIndexByConnectHandle(readByTypeResAsyncPtr->connectHandle, &index, &connect);
610 
611     if (connect == NULL) {
612         LOG_INFO("%{public}s connect == NULL and goto ATT_READBYTYPERESPONSE_END", __FUNCTION__);
613         goto ATT_READBYTYPERESPONSE_END;
614     }
615 
616     AttAssignMTU(&mtu, connect);
617 
618     if ((len * num) > (mtu - STEP_TWO)) {
619         ServerCallbackBTBADPARAM(connect);
620         goto ATT_READBYTYPERESPONSE_END;
621     }
622     if (((len - STEP_TWO) > (mtu - STEP_FOUR)) || ((len - STEP_TWO) > MAXREADBYTYPERESLEN)) {
623         len = Min(mtu - STEP_FOUR, MAXREADBYTYPERESLEN);
624     }
625 
626     Packet *packet = PacketMalloc(0, 0, sizeof(uint8_t) + sizeof(len));
627     if (packet == NULL) {
628         LOG_ERROR("point to NULL");
629         return;
630     }
631     *(uint8_t *)BufferPtr(PacketContinuousPayload(packet)) = READ_BY_TYPE_RESPONSE;
632     *((uint8_t *)BufferPtr(PacketContinuousPayload(packet)) + 1) = len;
633 
634     for (index = 0; index < num; index++) {
635         bufferPtr = BufferMalloc(len);
636         (void)memcpy_s(BufferPtr(bufferPtr),
637             BufferGetSize(bufferPtr),
638             &(readByTypeResAsyncPtr->attReadByTypeRspContext.valueList[index]),
639             STEP_TWO);
640         (void)memcpy_s((uint8_t *)BufferPtr(bufferPtr) + STEP_TWO,
641             BufferGetSize(bufferPtr) - STEP_TWO,
642             readByTypeResAsyncPtr->attReadByTypeRspContext.valueList[index].attributeValue,
643             len - STEP_TWO);
644         PacketPayloadAddLast(packet, bufferPtr);
645         BufferFree(bufferPtr);
646     }
647 
648     int ret = AttResponseSendData(connect, packet);
649     ServerCallbackReturnValue(ret, connect);
650     PacketFree(packet);
651 
652 ATT_READBYTYPERESPONSE_END:
653     AttReadByTypeResponseFree(readByTypeResAsyncPtr);
654     return;
655 }
656 
657 /**
658  * @brief destroy read by type response in self thread..
659  *
660  * @param context Indicates the pointer to context.
661  */
AttReadByTypeResponseAsyncDestroy(const void * context)662 static void AttReadByTypeResponseAsyncDestroy(const void *context)
663 {
664     LOG_INFO("%{public}s enter", __FUNCTION__);
665 
666     ReadByTypeResponseAsync *readByTypeResAsyncPtr = (ReadByTypeResponseAsync *)context;
667 
668     AttReadByTypeResponseFree(readByTypeResAsyncPtr);
669 
670     return;
671 }
672 
673 /**
674  * @brief gatt send readbytype response to att.
675  *
676  * @param1 connectHandle Indicates the connect handle.
677  * @param2 length Indicates the size of each attribute handlevalue pair.
678  * @param3 valueList Indicates the pointer to const a list of attribute data.
679  * @param4 attrValueNum Indicates the value of attribute value number.
680  * @return Returns <b>0</b> if the operation is successful; returns <b>!0</b> if the operation fails.
681  */
ATT_ReadByTypeResponse(uint16_t connectHandle,uint8_t length,const AttReadByTypeRspDataList * valueList,uint16_t attrValueNum)682 void ATT_ReadByTypeResponse(
683     uint16_t connectHandle, uint8_t length, const AttReadByTypeRspDataList *valueList, uint16_t attrValueNum)
684 {
685     LOG_INFO("%{public}s enter, connectHandle = %hu, length=%hhu, attrValueNum = %hu",
686         __FUNCTION__,
687         connectHandle,
688         length,
689         attrValueNum);
690 
691     uint16_t index = 0;
692     AttReadByTypeRspDataList *attReadByTypeDataPtr = MEM_MALLOC.alloc(sizeof(AttReadByTypeRspDataList) * attrValueNum);
693     if (attReadByTypeDataPtr == NULL) {
694         LOG_ERROR("point to NULL");
695         return;
696     }
697 
698     for (; index < attrValueNum; ++index) {
699         attReadByTypeDataPtr[index].attHandle = valueList[index].attHandle;
700         attReadByTypeDataPtr[index].attributeValue = MEM_MALLOC.alloc(length - STEP_TWO);
701         if (attReadByTypeDataPtr[index].attributeValue == NULL) {
702             LOG_WARN("point is null");
703             return;
704         }
705 
706         (void)memcpy_s(attReadByTypeDataPtr[index].attributeValue,
707             length - STEP_TWO,
708             valueList[index].attributeValue,
709             length - STEP_TWO);
710     }
711 
712     ReadByTypeResponseAsync *readByTypeResAsyncPtr = MEM_MALLOC.alloc(sizeof(ReadByTypeResponseAsync));
713     readByTypeResAsyncPtr->connectHandle = connectHandle;
714     readByTypeResAsyncPtr->attReadByTypeRspContext.len = length;
715     readByTypeResAsyncPtr->attReadByTypeRspContext.valueNum = attrValueNum;
716     readByTypeResAsyncPtr->attReadByTypeRspContext.valueList = attReadByTypeDataPtr;
717 
718     AttAsyncProcess(AttReadByTypeResponseAsync, AttReadByTypeResponseAsyncDestroy, readByTypeResAsyncPtr);
719 
720     return;
721 }
722 
723 /**
724  * @brief read response in self thread..
725  *
726  * @param context Indicates the pointer to context.
727  */
AttReadResponseAsync(const void * context)728 static void AttReadResponseAsync(const void *context)
729 {
730     LOG_INFO("%{public}s enter", __FUNCTION__);
731 
732     uint16_t index = 0;
733     uint16_t mtu = 0;
734     int ret;
735     uint16_t bufferSize;
736     ReadResponseAsync *readResAsyncPtr = (ReadResponseAsync *)context;
737     Packet *packet = NULL;
738     Buffer *bufferNew = NULL;
739     AttConnectInfo *connect = NULL;
740     uint8_t *data = NULL;
741 
742     AttGetConnectInfoIndexByConnectHandle(readResAsyncPtr->connectHandle, &index, &connect);
743 
744     if (connect == NULL) {
745         LOG_INFO("%{public}s connect == NULL and goto ATT_READRESPONSE_END", __FUNCTION__);
746         goto ATT_READRESPONSE_END;
747     }
748 
749     AttAssignMTU(&mtu, connect);
750 
751     bufferSize = BufferGetSize(readResAsyncPtr->attValue);
752     packet = PacketMalloc(0, 0, sizeof(uint8_t));
753     if (packet == NULL) {
754         LOG_ERROR("point to NULL");
755         return;
756     }
757     data = BufferPtr(PacketContinuousPayload(packet));
758     data[0] = READ_RESPONSE;
759 
760     if (bufferSize > (mtu - 1)) {
761         bufferNew = BufferSliceMalloc(readResAsyncPtr->attValue, 0, mtu - 1);
762         PacketPayloadAddLast(packet, bufferNew);
763         BufferFree(bufferNew);
764     } else if ((bufferSize <= (mtu - 1)) && (bufferSize > 0)) {
765         PacketPayloadAddLast(packet, readResAsyncPtr->attValue);
766     }
767 
768     ret = AttResponseSendData(connect, packet);
769     ServerCallbackReturnValue(ret, connect);
770     PacketFree(packet);
771 
772 ATT_READRESPONSE_END:
773     BufferFree(readResAsyncPtr->attValue);
774     MEM_MALLOC.free(readResAsyncPtr);
775     return;
776 }
777 
778 /**
779  * @brief destroy read response in self thread..
780  *
781  * @param context Indicates the pointer to context.
782  */
AttReadResponseAsyncDestroy(const void * context)783 static void AttReadResponseAsyncDestroy(const void *context)
784 {
785     LOG_INFO("%{public}s enter", __FUNCTION__);
786 
787     ReadResponseAsync *readResAsyncPtr = (ReadResponseAsync *)context;
788 
789     BufferFree(readResAsyncPtr->attValue);
790     MEM_MALLOC.free(readResAsyncPtr);
791 
792     return;
793 }
794 
795 /**
796  * @brief gatt send read response to att.
797  *
798  * @param1 connectHandle Indicates the connect handle.
799  * @param2 attValue Indicates the pointer to the value of the attribute with the handle given.
800  * @return Returns <b>0</b> if the operation is successful; returns <b>!0</b> if the operation fails.
801  */
ATT_ReadResponse(uint16_t connectHandle,const Buffer * attValue)802 void ATT_ReadResponse(uint16_t connectHandle, const Buffer *attValue)
803 {
804     LOG_INFO("%{public}s enter,connectHandle = %hu", __FUNCTION__, connectHandle);
805 
806     Buffer *bufferPtr = NULL;
807     ReadResponseAsync *readResAsyncPtr = NULL;
808 
809     bufferPtr = BufferRefMalloc(attValue);
810     readResAsyncPtr = MEM_MALLOC.alloc(sizeof(ReadResponseAsync));
811     if (readResAsyncPtr == NULL) {
812         LOG_ERROR("point to NULL");
813         return;
814     }
815     readResAsyncPtr->connectHandle = connectHandle;
816     readResAsyncPtr->attValue = bufferPtr;
817 
818     AttAsyncProcess(AttReadResponseAsync, AttReadResponseAsyncDestroy, readResAsyncPtr);
819 
820     return;
821 }
822 
823 /**
824  * @brief read blob response in self thread..
825  *
826  * @param context Indicates the pointer to context.
827  */
AttReadBlobResponseAsync(const void * context)828 static void AttReadBlobResponseAsync(const void *context)
829 {
830     LOG_INFO("%{public}s enter", __FUNCTION__);
831 
832     uint16_t index = 0;
833     int ret;
834     uint16_t mtu = 0;
835     uint8_t *data = NULL;
836     ReadResponseAsync *readBlobResAsyncPtr = NULL;
837     AttConnectInfo *connect = NULL;
838     uint16_t bufferSize;
839     Packet *packet = NULL;
840     Buffer *bufferNew = NULL;
841 
842     readBlobResAsyncPtr = (ReadResponseAsync *)context;
843     AttGetConnectInfoIndexByConnectHandle(readBlobResAsyncPtr->connectHandle, &index, &connect);
844 
845     if (connect == NULL) {
846         LOG_INFO("%{public}s connect == NULL and goto ATT_READBLOBRESPONSE_END", __FUNCTION__);
847         goto ATT_READBLOBRESPONSE_END;
848     }
849 
850     AttAssignMTU(&mtu, connect);
851 
852     bufferSize = BufferGetSize(readBlobResAsyncPtr->attValue);
853     packet = PacketMalloc(0, 0, sizeof(uint8_t));
854     if (packet == NULL) {
855         LOG_ERROR("point to NULL");
856         return;
857     }
858     data = BufferPtr(PacketContinuousPayload(packet));
859     data[0] = READ_BLOB_RESPONSE;
860 
861     if (bufferSize > (mtu - 1)) {
862         bufferNew = BufferSliceMalloc(readBlobResAsyncPtr->attValue, 0, mtu - 1);
863         PacketPayloadAddLast(packet, bufferNew);
864         BufferFree(bufferNew);
865     } else if ((bufferSize <= (mtu - 1)) && (bufferSize > 0)) {
866         PacketPayloadAddLast(packet, readBlobResAsyncPtr->attValue);
867     }
868 
869     ret = AttResponseSendData(connect, packet);
870     ServerCallbackReturnValue(ret, connect);
871     PacketFree(packet);
872 
873 ATT_READBLOBRESPONSE_END:
874     BufferFree(readBlobResAsyncPtr->attValue);
875     MEM_MALLOC.free(readBlobResAsyncPtr);
876     return;
877 }
878 
879 /**
880  * @brief destroy read blob response in self thread..
881  *
882  * @param context Indicates the pointer to context.
883  */
AttReadBlobResponseAsyncDestroy(const void * context)884 static void AttReadBlobResponseAsyncDestroy(const void *context)
885 {
886     LOG_INFO("%{public}s enter", __FUNCTION__);
887 
888     ReadResponseAsync *readBlobResAsyncPtr = (ReadResponseAsync *)context;
889 
890     BufferFree(readBlobResAsyncPtr->attValue);
891     MEM_MALLOC.free(readBlobResAsyncPtr);
892 
893     return;
894 }
895 
896 /**
897  * @brief gatt send readblob response to att.
898  *
899  * @param1 connectHandle Indicates the connect handle.
900  * @param2 attReadBlobResObj Indicates the pointer to part of the value of the attribute with the handle given.
901  * @return Returns <b>0</b> if the operation is successful; returns <b>!0</b> if the operation fails.
902  */
ATT_ReadBlobResponse(uint16_t connectHandle,const Buffer * attReadBlobResObj)903 void ATT_ReadBlobResponse(uint16_t connectHandle, const Buffer *attReadBlobResObj)
904 {
905     LOG_INFO("%{public}s enter,connectHandle = %hu", __FUNCTION__, connectHandle);
906 
907     Buffer *bufferPtr = NULL;
908     ReadResponseAsync *readBlobResAsyncPtr = NULL;
909 
910     bufferPtr = BufferRefMalloc(attReadBlobResObj);
911     readBlobResAsyncPtr = MEM_MALLOC.alloc(sizeof(ReadResponseAsync));
912     if (readBlobResAsyncPtr == NULL) {
913         LOG_ERROR("point to NULL");
914         return;
915     }
916     readBlobResAsyncPtr->connectHandle = connectHandle;
917     readBlobResAsyncPtr->attValue = bufferPtr;
918 
919     AttAsyncProcess(AttReadBlobResponseAsync, AttReadBlobResponseAsyncDestroy, readBlobResAsyncPtr);
920 
921     return;
922 }
923 
924 /**
925  * @brief read multiple response in self thread..
926  *
927  * @param context Indicates the pointer to context.
928  */
AttReadMultipleResponseAsync(const void * context)929 static void AttReadMultipleResponseAsync(const void *context)
930 {
931     LOG_INFO("%{public}s enter", __FUNCTION__);
932 
933     uint16_t index = 0;
934     int ret;
935     uint16_t bufferSize;
936     Packet *packet = NULL;
937     uint16_t mtu = 0;
938     ReadResponseAsync *readMultipleResponseAsyncPtr = NULL;
939     uint8_t *data = NULL;
940     Buffer *bufferNew = NULL;
941     AttConnectInfo *connect = NULL;
942 
943     readMultipleResponseAsyncPtr = (ReadResponseAsync *)context;
944 
945     AttGetConnectInfoIndexByConnectHandle(readMultipleResponseAsyncPtr->connectHandle, &index, &connect);
946 
947     if (connect == NULL) {
948         LOG_INFO("%{public}s connect == NULL and goto ATT_READMULTIPLERESPONSE_END", __FUNCTION__);
949         goto ATT_READMULTIPLERESPONSE_END;
950     }
951 
952     AttAssignMTU(&mtu, connect);
953 
954     bufferSize = BufferGetSize(readMultipleResponseAsyncPtr->attValue);
955     packet = PacketMalloc(0, 0, sizeof(uint8_t));
956     if (packet == NULL) {
957         LOG_ERROR("point to NULL");
958         return;
959     }
960     data = BufferPtr(PacketContinuousPayload(packet));
961     data[0] = READ_MULTIPLE_RESPONSE;
962 
963     if (bufferSize > (mtu - 1)) {
964         bufferNew = BufferSliceMalloc(readMultipleResponseAsyncPtr->attValue, 0, mtu - 1);
965         PacketPayloadAddLast(packet, bufferNew);
966         BufferFree(bufferNew);
967     } else if ((bufferSize <= (mtu - 1)) && (bufferSize > 0)) {
968         PacketPayloadAddLast(packet, readMultipleResponseAsyncPtr->attValue);
969     }
970 
971     ret = AttResponseSendData(connect, packet);
972     ServerCallbackReturnValue(ret, connect);
973     PacketFree(packet);
974 
975 ATT_READMULTIPLERESPONSE_END:
976     BufferFree(readMultipleResponseAsyncPtr->attValue);
977     MEM_MALLOC.free(readMultipleResponseAsyncPtr);
978     return;
979 }
980 
981 /**
982  * @brief destroy read multiple response in self thread..
983  *
984  * @param context Indicates the pointer to context.
985  */
AttReadMultipleResponseAsyncDestroy(const void * context)986 static void AttReadMultipleResponseAsyncDestroy(const void *context)
987 {
988     LOG_INFO("%{public}s enter", __FUNCTION__);
989 
990     ReadResponseAsync *readMultipleResponseAsyncPtr = (ReadResponseAsync *)context;
991 
992     BufferFree(readMultipleResponseAsyncPtr->attValue);
993     MEM_MALLOC.free(readMultipleResponseAsyncPtr);
994 
995     return;
996 }
997 
998 /**
999  * @brief gatt send readmultiple response to att.
1000  *
1001  * @param1 connectHandle Indicates the connect handle.
1002  * @param2 valueList Indicates the pointer to a set of two or more values.
1003  * @return Returns <b>0</b> if the operation is successful; returns <b>!0</b> if the operation fails.
1004  */
ATT_ReadMultipleResponse(uint16_t connectHandle,const Buffer * valueList)1005 void ATT_ReadMultipleResponse(uint16_t connectHandle, const Buffer *valueList)
1006 {
1007     LOG_INFO("%{public}s enter,connectHandle = %hu", __FUNCTION__, connectHandle);
1008 
1009     Buffer *bufferPtr = NULL;
1010     ReadResponseAsync *readMultipleResAsyncPtr = NULL;
1011 
1012     bufferPtr = BufferRefMalloc(valueList);
1013     readMultipleResAsyncPtr = MEM_MALLOC.alloc(sizeof(ReadResponseAsync));
1014     if (readMultipleResAsyncPtr == NULL) {
1015         LOG_ERROR("point to NULL");
1016         return;
1017     }
1018     readMultipleResAsyncPtr->connectHandle = connectHandle;
1019     readMultipleResAsyncPtr->attValue = bufferPtr;
1020 
1021     AttAsyncProcess(AttReadMultipleResponseAsync, AttReadMultipleResponseAsyncDestroy, readMultipleResAsyncPtr);
1022 
1023     return;
1024 }
1025 
AttReadByGroupTypeResponseAsyncFree(ReadByGroupTypeResponseAsync * attReadByGroupResponseAsyncPtr,uint16_t num)1026 void AttReadByGroupTypeResponseAsyncFree(ReadByGroupTypeResponseAsync *attReadByGroupResponseAsyncPtr, uint16_t num)
1027 {
1028     LOG_INFO("%{public}s enter", __FUNCTION__);
1029 
1030     uint16_t index;
1031 
1032     for (index = 0; index < num; index++) {
1033         MEM_MALLOC.free(attReadByGroupResponseAsyncPtr->attReadGroupResContext.attributeData[index].attributeValue);
1034     }
1035     MEM_MALLOC.free(attReadByGroupResponseAsyncPtr->attReadGroupResContext.attributeData);
1036     MEM_MALLOC.free(attReadByGroupResponseAsyncPtr);
1037 
1038     return;
1039 }
1040 
1041 /**
1042  * @brief read by group type response in self thread..
1043  *
1044  * @param context Indicates the pointer to context.
1045  */
AttReadByGroupTypeResponseAsync(const void * context)1046 static void AttReadByGroupTypeResponseAsync(const void *context)
1047 {
1048     LOG_INFO("%{public}s enter", __FUNCTION__);
1049 
1050     uint16_t index = 0;
1051     AttConnectInfo *connect = NULL;
1052     uint16_t mtu = 0;
1053 
1054     ReadByGroupTypeResponseAsync *attReadByGroupResponseAsyncPtr = (ReadByGroupTypeResponseAsync *)context;
1055 
1056     uint8_t len = attReadByGroupResponseAsyncPtr->attReadGroupResContext.length;
1057     uint16_t num = attReadByGroupResponseAsyncPtr->attReadGroupResContext.num;
1058     AttGetConnectInfoIndexByConnectHandle(attReadByGroupResponseAsyncPtr->connectHandle, &index, &connect);
1059 
1060     if (connect == NULL) {
1061         LOG_INFO("%{public}s connect == NULL and goto ATTREADBYGROUPTYPERESONSE_END", __FUNCTION__);
1062         goto ATTREADBYGROUPTYPERESONSE_END;
1063     }
1064 
1065     AttAssignMTU(&mtu, connect);
1066 
1067     if ((len * num) > (mtu - STEP_TWO)) {
1068         ServerCallbackBTBADPARAM(connect);
1069         goto ATTREADBYGROUPTYPERESONSE_END;
1070     }
1071     if (((len - STEP_FOUR) > (mtu - STEP_SIX)) || ((len - STEP_FOUR) > MAXREADBYGROUPRESLEN)) {
1072         len = Min(mtu - STEP_SIX, MAXREADBYGROUPRESLEN);
1073     }
1074 
1075     Packet *packet = PacketMalloc(0, 0, sizeof(uint8_t) + sizeof(len));
1076     if (packet == NULL) {
1077         LOG_ERROR("point to NULL");
1078         return;
1079     }
1080     *(uint8_t *)BufferPtr(PacketContinuousPayload(packet)) = READ_BY_GROUP_TYPE_RESPONSE;
1081     *((uint8_t *)BufferPtr(PacketContinuousPayload(packet)) + 1) = len;
1082 
1083     for (index = 0; index < num; index++) {
1084         Buffer *bufferNew = BufferMalloc(len);
1085         (void)memcpy_s(BufferPtr(bufferNew),
1086             BufferGetSize(bufferNew),
1087             &(attReadByGroupResponseAsyncPtr->attReadGroupResContext.attributeData[index]),
1088             STEP_FOUR);
1089         (void)memcpy_s(((uint8_t *)BufferPtr(bufferNew) + STEP_FOUR),
1090             BufferGetSize(bufferNew) - STEP_FOUR,
1091             attReadByGroupResponseAsyncPtr->attReadGroupResContext.attributeData[index].attributeValue,
1092             len - STEP_FOUR);
1093         PacketPayloadAddLast(packet, bufferNew);
1094         BufferFree(bufferNew);
1095     }
1096 
1097     int ret = AttResponseSendData(connect, packet);
1098     ServerCallbackReturnValue(ret, connect);
1099     PacketFree(packet);
1100 
1101 ATTREADBYGROUPTYPERESONSE_END:
1102     AttReadByGroupTypeResponseAsyncFree(attReadByGroupResponseAsyncPtr, num);
1103     return;
1104 }
1105 
1106 /**
1107  * @brief destroy read by group type response in self thread..
1108  *
1109  * @param context Indicates the pointer to context.
1110  */
AttReadByGroupTypeResponseAsyncDestroy(const void * context)1111 static void AttReadByGroupTypeResponseAsyncDestroy(const void *context)
1112 {
1113     LOG_INFO("%{public}s enter", __FUNCTION__);
1114 
1115     uint16_t num = 0;
1116 
1117     ReadByGroupTypeResponseAsync *attReadByGroupResponseAsyncPtr = NULL;
1118 
1119     attReadByGroupResponseAsyncPtr = (ReadByGroupTypeResponseAsync *)context;
1120     num = attReadByGroupResponseAsyncPtr->attReadGroupResContext.num;
1121 
1122     AttReadByGroupTypeResponseAsyncFree(attReadByGroupResponseAsyncPtr, num);
1123 
1124     return;
1125 }
1126 
1127 /**
1128  * @brief gatt send readbygrouptype response to att.
1129  *
1130  * @param1 connectHandle Indicates the connect handle.
1131  * @param2 length Indicates the size of each attribute data.
1132  * @param3 serviceList Indicates the pointer to const a list of attribute data.
1133  * @param4 serviceNum Indicates the number of attribute data.
1134  * @return Returns <b>0</b> if the operation is successful; returns <b>!0</b> if the operation fails.
1135  */
ATT_ReadByGroupTypeResponse(uint16_t connectHandle,uint8_t length,const AttReadGoupAttributeData * serviceList,uint16_t serviceNum)1136 void ATT_ReadByGroupTypeResponse(
1137     uint16_t connectHandle, uint8_t length, const AttReadGoupAttributeData *serviceList, uint16_t serviceNum)
1138 {
1139     LOG_INFO("%{public}s enter, connectHandle = %hu,length = %{public}d,serviceNum = %{public}d",
1140         __FUNCTION__, connectHandle, length, serviceNum);
1141 
1142     uint16_t index = 0;
1143     AttReadGoupAttributeData *attReadGroupAttrDataPtr = NULL;
1144     ReadByGroupTypeResponseAsync *attReadByGroupResAsyncPtr = NULL;
1145 
1146     attReadGroupAttrDataPtr = MEM_MALLOC.alloc(sizeof(AttReadGoupAttributeData) * serviceNum);
1147     if (attReadGroupAttrDataPtr == NULL) {
1148         LOG_ERROR("point to NULL");
1149         return;
1150     }
1151     for (; index < serviceNum; ++index) {
1152         attReadGroupAttrDataPtr[index].attributeValue = MEM_MALLOC.alloc(length - STEP_FOUR);
1153         attReadGroupAttrDataPtr[index].attHandle = serviceList[index].attHandle;
1154         attReadGroupAttrDataPtr[index].groupEndHandle = serviceList[index].groupEndHandle;
1155         (void)memcpy_s(attReadGroupAttrDataPtr[index].attributeValue,
1156             length - STEP_FOUR,
1157             serviceList[index].attributeValue,
1158             length - STEP_FOUR);
1159     }
1160 
1161     attReadByGroupResAsyncPtr = MEM_MALLOC.alloc(sizeof(ReadByGroupTypeResponseAsync));
1162     attReadByGroupResAsyncPtr->connectHandle = connectHandle;
1163     attReadByGroupResAsyncPtr->attReadGroupResContext.length = length;
1164     attReadByGroupResAsyncPtr->attReadGroupResContext.num = serviceNum;
1165     attReadByGroupResAsyncPtr->attReadGroupResContext.attributeData = attReadGroupAttrDataPtr;
1166 
1167     AttAsyncProcess(AttReadByGroupTypeResponseAsync, AttReadByGroupTypeResponseAsyncDestroy, attReadByGroupResAsyncPtr);
1168 
1169     return;
1170 }
1171 
1172 /**
1173  * @brief write response in self thread..
1174  *
1175  * @param context Indicates the pointer to context.
1176  */
AttWriteResponseAsync(const void * context)1177 static void AttWriteResponseAsync(const void *context)
1178 {
1179     LOG_INFO("%{public}s enter", __FUNCTION__);
1180 
1181     uint16_t index = 0;
1182     int ret;
1183     Packet *packet = NULL;
1184     WriteResponseAsync *writeResponseAsyncPtr = NULL;
1185     uint8_t *data = NULL;
1186     uint16_t mtu = 0;
1187     AttConnectInfo *connect = NULL;
1188 
1189     writeResponseAsyncPtr = (WriteResponseAsync *)context;
1190 
1191     AttGetConnectInfoIndexByConnectHandle(writeResponseAsyncPtr->connectHandle, &index, &connect);
1192 
1193     if (connect == NULL) {
1194         LOG_INFO("%{public}s connect == NULL and goto ATTWRITERESPONSE_END", __FUNCTION__);
1195         goto ATTWRITERESPONSE_END;
1196     }
1197 
1198     AttAssignMTU(&mtu, connect);
1199 
1200     packet = PacketMalloc(0, 0, sizeof(uint8_t));
1201     if (packet == NULL) {
1202         LOG_ERROR("point to NULL");
1203         return;
1204     }
1205     data = BufferPtr(PacketContinuousPayload(packet));
1206     data[0] = WRITE_RESPONSE;
1207 
1208     ret = AttResponseSendData(connect, packet);
1209     ServerCallbackReturnValue(ret, connect);
1210     PacketFree(packet);
1211 
1212 ATTWRITERESPONSE_END:
1213     MEM_MALLOC.free(writeResponseAsyncPtr);
1214     return;
1215 }
1216 
1217 /**
1218  * @brief destroy write response in self thread..
1219  *
1220  * @param context Indicates the pointer to context.
1221  */
AttWriteResponseAsyncDestroy(const void * context)1222 static void AttWriteResponseAsyncDestroy(const void *context)
1223 {
1224     LOG_INFO("%{public}s enter", __FUNCTION__);
1225 
1226     WriteResponseAsync *writeResponseAsyncPtr = (WriteResponseAsync *)context;
1227 
1228     MEM_MALLOC.free(writeResponseAsyncPtr);
1229 
1230     return;
1231 }
1232 
1233 /**
1234  * @brief gatt send write response to att.
1235  *
1236  * @param connectHandle Indicates the connect handle.
1237  * @return Returns <b>0</b> if the operation is successful; returns <b>!0</b> if the operation fails.
1238  */
ATT_WriteResponse(uint16_t connectHandle)1239 void ATT_WriteResponse(uint16_t connectHandle)
1240 {
1241     LOG_INFO("%{public}s enter, connectHandle = %hu", __FUNCTION__, connectHandle);
1242 
1243     WriteResponseAsync *writeResAsyncPtr = MEM_MALLOC.alloc(sizeof(WriteResponseAsync));
1244     if (writeResAsyncPtr == NULL) {
1245         LOG_ERROR("point to NULL");
1246         return;
1247     }
1248     writeResAsyncPtr->connectHandle = connectHandle;
1249 
1250     AttAsyncProcess(AttWriteResponseAsync, AttWriteResponseAsyncDestroy, writeResAsyncPtr);
1251 
1252     return;
1253 }
1254 
1255 /**
1256  * @brief prepare write response in self thread..
1257  *
1258  * @param context Indicates the pointer to context.
1259  */
AttPrepareWriteResponseAsync(const void * context)1260 static void AttPrepareWriteResponseAsync(const void *context)
1261 {
1262     LOG_INFO("%{public}s enter", __FUNCTION__);
1263 
1264     uint16_t index = 0;
1265     int ret;
1266     uint16_t bufferSize;
1267     Packet *packet = NULL;
1268     uint8_t *data = NULL;
1269     uint16_t mtu = 0;
1270     AttConnectInfo *connect = NULL;
1271     PrepareWriteAsync *prepareWriteResAsyncPtr = NULL;
1272 
1273     prepareWriteResAsyncPtr = (PrepareWriteAsync *)context;
1274     bufferSize = BufferGetSize(prepareWriteResAsyncPtr->attValue);
1275 
1276     AttGetConnectInfoIndexByConnectHandle(prepareWriteResAsyncPtr->connectHandle, &index, &connect);
1277 
1278     if (connect == NULL) {
1279         LOG_INFO("%{public}s connect == NULL and goto ATTPREPAREWRITERESPONSE_END", __FUNCTION__);
1280         goto ATTPREPAREWRITERESPONSE_END;
1281     }
1282 
1283     AttAssignMTU(&mtu, connect);
1284 
1285     if (bufferSize > (mtu - STEP_FIVE)) {
1286         LOG_INFO("%{public}s bufferSize > (mtu - 5)", __FUNCTION__);
1287         ServerCallbackBTBADPARAM(connect);
1288         goto ATTPREPAREWRITERESPONSE_END;
1289     }
1290 
1291     packet = PacketMalloc(0, 0, sizeof(uint8_t) + sizeof(prepareWriteResAsyncPtr->attReadBlobObj));
1292     if (packet == NULL) {
1293         LOG_ERROR("point to NULL");
1294         return;
1295     }
1296     data = BufferPtr(PacketContinuousPayload(packet));
1297     data[0] = PREPARE_WRITE_RESPONSE;
1298     ((uint16_t *)(data + 1))[0] = prepareWriteResAsyncPtr->attReadBlobObj.attHandle;
1299     ((uint16_t *)(data + STEP_THREE))[0] = prepareWriteResAsyncPtr->attReadBlobObj.offset;
1300 
1301     if ((bufferSize < (mtu - STEP_FIVE)) && (bufferSize > 0)) {
1302         PacketPayloadAddLast(packet, prepareWriteResAsyncPtr->attValue);
1303     }
1304 
1305     ret = AttResponseSendData(connect, packet);
1306     ServerCallbackReturnValue(ret, connect);
1307     PacketFree(packet);
1308 
1309 ATTPREPAREWRITERESPONSE_END:
1310     BufferFree(prepareWriteResAsyncPtr->attValue);
1311     MEM_MALLOC.free(prepareWriteResAsyncPtr);
1312     return;
1313 }
1314 
1315 /**
1316  * @brief destroy prepare write response in self thread..
1317  *
1318  * @param context Indicates the pointer to context.
1319  */
AttPrepareWriteResponseAsyncDestroy(const void * context)1320 static void AttPrepareWriteResponseAsyncDestroy(const void *context)
1321 {
1322     LOG_INFO("%{public}s enter", __FUNCTION__);
1323 
1324     PrepareWriteAsync *prepareWriteResAsyncPtr = (PrepareWriteAsync *)context;
1325 
1326     BufferFree(prepareWriteResAsyncPtr->attValue);
1327     MEM_MALLOC.free(prepareWriteResAsyncPtr);
1328 
1329     return;
1330 }
1331 
1332 /**
1333  * @brief gatt send preparewrite response to att.
1334  *
1335  * @param1 connectHandle Indicates the connect handle.
1336  * @param2 attReadBlobObj Indicates the value of the struct AttReadBlobReqPrepareWriteValue.
1337  * @param3 attValue Indicates the pointer to the value of the attribute to be written.
1338  * @return Returns <b>0</b> if the operation is successful; returns <b>!0</b> if the operation fails.
1339  */
ATT_PrepareWriteResponse(uint16_t connectHandle,AttReadBlobReqPrepareWriteValue attReadBlobObj,const Buffer * attValue)1340 void ATT_PrepareWriteResponse(
1341     uint16_t connectHandle, AttReadBlobReqPrepareWriteValue attReadBlobObj, const Buffer *attValue)
1342 {
1343     LOG_INFO("%{public}s enter, connectHandle = %hu, attHandle = %{public}d, offset = %{public}d",
1344         __FUNCTION__,
1345         connectHandle,
1346         attReadBlobObj.attHandle,
1347         attReadBlobObj.offset);
1348 
1349     Buffer *bufferPtr = NULL;
1350     PrepareWriteAsync *prepareWriteResAsyncPtr = NULL;
1351 
1352     bufferPtr = BufferRefMalloc(attValue);
1353     prepareWriteResAsyncPtr = MEM_MALLOC.alloc(sizeof(PrepareWriteAsync));
1354     if (prepareWriteResAsyncPtr == NULL) {
1355         LOG_ERROR("point to NULL");
1356         return;
1357     }
1358     prepareWriteResAsyncPtr->connectHandle = connectHandle;
1359     prepareWriteResAsyncPtr->attReadBlobObj.attHandle = attReadBlobObj.attHandle;
1360     prepareWriteResAsyncPtr->attReadBlobObj.offset = attReadBlobObj.offset;
1361     prepareWriteResAsyncPtr->attValue = bufferPtr;
1362 
1363     AttAsyncProcess(AttPrepareWriteResponseAsync, AttPrepareWriteResponseAsyncDestroy, prepareWriteResAsyncPtr);
1364 
1365     return;
1366 }
1367 
1368 /**
1369  * @brief execute write response in self thread..
1370  *
1371  * @param context Indicates the pointer to context.
1372  */
AttExecuteWriteResponseAsync(const void * context)1373 static void AttExecuteWriteResponseAsync(const void *context)
1374 {
1375     LOG_INFO("%{public}s enter", __FUNCTION__);
1376 
1377     uint16_t index = 0;
1378     int ret;
1379     Packet *packet = NULL;
1380     uint8_t *data = NULL;
1381     uint16_t mtu = 0;
1382     AttConnectInfo *connect = NULL;
1383     WriteResponseAsync *executeWriteResAsyncPtr = (WriteResponseAsync *)context;
1384 
1385     AttGetConnectInfoIndexByConnectHandle(executeWriteResAsyncPtr->connectHandle, &index, &connect);
1386 
1387     if (connect == NULL) {
1388         LOG_INFO("%{public}s connect == NULL and goto ATTEXECUTEWRITERESPONSE_END", __FUNCTION__);
1389         goto ATTEXECUTEWRITERESPONSE_END;
1390     }
1391 
1392     AttAssignMTU(&mtu, connect);
1393 
1394     packet = PacketMalloc(0, 0, sizeof(uint8_t));
1395     if (packet == NULL) {
1396         LOG_ERROR("point to NULL");
1397         return;
1398     }
1399     data = BufferPtr(PacketContinuousPayload(packet));
1400     data[0] = EXECUTE_WRITE_RESPONSE;
1401 
1402     ret = AttResponseSendData(connect, packet);
1403     ServerCallbackReturnValue(ret, connect);
1404     PacketFree(packet);
1405 
1406 ATTEXECUTEWRITERESPONSE_END:
1407     MEM_MALLOC.free(executeWriteResAsyncPtr);
1408     return;
1409 }
1410 
1411 /**
1412  * @brief destroy execute write response in self thread..
1413  *
1414  * @param context Indicates the pointer to context.
1415  */
AttExecuteWriteResponseAsyncDestroy(const void * context)1416 static void AttExecuteWriteResponseAsyncDestroy(const void *context)
1417 {
1418     LOG_INFO("%{public}s enter", __FUNCTION__);
1419 
1420     WriteResponseAsync *executeWriteResAsyncPtr = (WriteResponseAsync *)context;
1421 
1422     MEM_MALLOC.free(executeWriteResAsyncPtr);
1423 
1424     return;
1425 }
1426 
1427 /**
1428  * @brief gatt send executewrite response to att.
1429  *
1430  * @param connectHandle Indicates the connect handle.
1431  * @return Returns <b>0</b> if the operation is successful; returns <b>!0</b> if the operation fails.
1432  */
ATT_ExecuteWriteResponse(uint16_t connectHandle)1433 void ATT_ExecuteWriteResponse(uint16_t connectHandle)
1434 {
1435     LOG_INFO("%{public}s enter,connectHandle = %hu", __FUNCTION__, connectHandle);
1436 
1437     WriteResponseAsync *executeWriteResAsyncPtr = MEM_MALLOC.alloc(sizeof(WriteResponseAsync));
1438     if (executeWriteResAsyncPtr == NULL) {
1439         LOG_ERROR("point to NULL");
1440         return;
1441     }
1442     executeWriteResAsyncPtr->connectHandle = connectHandle;
1443 
1444     AttAsyncProcess(AttExecuteWriteResponseAsync, AttExecuteWriteResponseAsyncDestroy, executeWriteResAsyncPtr);
1445 
1446     return;
1447 }
1448 
1449 /**
1450  * @brief handle value notification in self thread..
1451  *
1452  * @param context Indicates the pointer to context.
1453  */
AttHandleValueNotificationAsync(const void * context)1454 static void AttHandleValueNotificationAsync(const void *context)
1455 {
1456     LOG_INFO("%{public}s enter", __FUNCTION__);
1457 
1458     uint16_t index = 0;
1459     int ret;
1460     Packet *packet = NULL;
1461     Buffer *bufferNew = NULL;
1462     AttConnectInfo *connect = NULL;
1463     WriteAsync *handleNotificationAsyncPtr = NULL;
1464     uint16_t bufferSizenoti;
1465     uint8_t *data = NULL;
1466 
1467     handleNotificationAsyncPtr = (WriteAsync *)context;
1468 
1469     AttGetConnectInfoIndexByConnectHandle(handleNotificationAsyncPtr->connectHandle, &index, &connect);
1470 
1471     if (connect == NULL) {
1472         LOG_INFO("%{public}s connect == NULL and goto ATT_HANDLEVALUENOTIFICATION_END", __FUNCTION__);
1473         goto ATT_HANDLEVALUENOTIFICATION_END;
1474     }
1475 
1476     bufferSizenoti = BufferGetSize(handleNotificationAsyncPtr->attValue);
1477     packet = PacketMalloc(0, 0, sizeof(uint8_t) + sizeof(uint16_t));
1478     if (packet == NULL) {
1479         LOG_ERROR("point to NULL");
1480         return;
1481     }
1482     data = BufferPtr(PacketContinuousPayload(packet));
1483     data[0] = HANDLE_VALUE_NOTIFICATION;
1484     ((uint16_t *)(data + 1))[0] = handleNotificationAsyncPtr->attHandle;
1485 
1486     if ((bufferSizenoti > 0) && (bufferSizenoti <= (connect->mtu - STEP_THREE))) {
1487         PacketPayloadAddLast(packet, handleNotificationAsyncPtr->attValue);
1488     } else if (bufferSizenoti > (connect->mtu - STEP_THREE)) {
1489         uint16_t len = connect->mtu - STEP_THREE;
1490         bufferNew = BufferSliceMalloc(handleNotificationAsyncPtr->attValue, 0, len);
1491         PacketPayloadAddLast(packet, bufferNew);
1492         BufferFree(bufferNew);
1493     }
1494 
1495     ret = AttResponseSendData(connect, packet);
1496     ServerCallbackReturnValue(ret, connect);
1497     PacketFree(packet);
1498 
1499 ATT_HANDLEVALUENOTIFICATION_END:
1500     BufferFree(handleNotificationAsyncPtr->attValue);
1501     MEM_MALLOC.free(handleNotificationAsyncPtr);
1502     return;
1503 }
1504 
1505 /**
1506  * @brief destroy handle value notification in self thread..
1507  *
1508  * @param context Indicates the pointer to context.
1509  */
AttHandleValueNotificationAsyncDestroy(const void * context)1510 static void AttHandleValueNotificationAsyncDestroy(const void *context)
1511 {
1512     LOG_INFO("%{public}s enter", __FUNCTION__);
1513 
1514     WriteAsync *handleNotificationAsyncPtr = (WriteAsync *)context;
1515 
1516     BufferFree(handleNotificationAsyncPtr->attValue);
1517     MEM_MALLOC.free(handleNotificationAsyncPtr);
1518 
1519     return;
1520 }
1521 
1522 /**
1523  * @brief gatt send handlevalue notification to att.
1524  *
1525  * @param1 connectHandle Indicates the connect handle.
1526  * @param2 attHandle Indicates the handle of the attribute.
1527  * @param3 attValue Indicates the pointer to the current value of the attribute.
1528  * @return Returns <b>0</b> if the operation is successful; returns <b>!0</b> if the operation fails.
1529  */
ATT_HandleValueNotification(uint16_t connectHandle,uint16_t attHandle,const Buffer * attValue)1530 void ATT_HandleValueNotification(uint16_t connectHandle, uint16_t attHandle, const Buffer *attValue)
1531 {
1532     LOG_INFO("%{public}s enter, connectHandle = %hu, attHandle=%{public}d", __FUNCTION__, connectHandle, attHandle);
1533 
1534     Buffer *bufferPtr = NULL;
1535     WriteAsync *handleNotificationAsyncPtr = NULL;
1536 
1537     bufferPtr = BufferRefMalloc(attValue);
1538     handleNotificationAsyncPtr = MEM_MALLOC.alloc(sizeof(WriteAsync));
1539     if (handleNotificationAsyncPtr == NULL) {
1540         LOG_ERROR("point to NULL");
1541         return;
1542     }
1543     handleNotificationAsyncPtr->connectHandle = connectHandle;
1544     handleNotificationAsyncPtr->attHandle = attHandle;
1545     handleNotificationAsyncPtr->attValue = bufferPtr;
1546 
1547     AttAsyncProcess(
1548         AttHandleValueNotificationAsync, AttHandleValueNotificationAsyncDestroy, handleNotificationAsyncPtr);
1549 
1550     return;
1551 }
1552 
1553 /**
1554  * @brief handle value indication in self thread..
1555  *
1556  * @param context Indicates the pointer to context.
1557  */
AttHandleValueIndicationAsync(const void * context)1558 static void AttHandleValueIndicationAsync(const void *context)
1559 {
1560     LOG_INFO("%{public}s enter", __FUNCTION__);
1561 
1562     uint16_t index = 0;
1563     int ret;
1564     uint16_t bufferSize;
1565     Packet *packet = NULL;
1566     uint8_t *data = NULL;
1567     Buffer *bufferNew = NULL;
1568     WriteAsync *handleIndicationAsyncPtr = NULL;
1569     uint16_t len;
1570     AttConnectInfo *connect = NULL;
1571 
1572     handleIndicationAsyncPtr = (WriteAsync *)context;
1573 
1574     AttGetConnectInfoIndexByConnectHandle(handleIndicationAsyncPtr->connectHandle, &index, &connect);
1575 
1576     if (connect == NULL) {
1577         LOG_INFO("%{public}s connect == NULL and goto ATTHANDLEVALUEINDICATION_END", __FUNCTION__);
1578         goto ATTHANDLEVALUEINDICATION_END;
1579     }
1580 
1581     connect->serverSendFlag = true;
1582     bufferSize = BufferGetSize(handleIndicationAsyncPtr->attValue);
1583     packet = PacketMalloc(0, 0, sizeof(uint8_t) + sizeof(handleIndicationAsyncPtr->attHandle));
1584     if (packet == NULL) {
1585         LOG_ERROR("point to NULL");
1586         return;
1587     }
1588     data = BufferPtr(PacketContinuousPayload(packet));
1589     data[0] = HANDLE_VALUE_INDICATION;
1590     ((uint16_t *)(data + 1))[0] = handleIndicationAsyncPtr->attHandle;
1591     if ((bufferSize > 0) && (bufferSize <= (connect->mtu - STEP_THREE))) {
1592         PacketPayloadAddLast(packet, handleIndicationAsyncPtr->attValue);
1593     } else if (bufferSize > (connect->mtu - STEP_THREE)) {
1594         len = connect->mtu - STEP_THREE;
1595         bufferNew = BufferSliceMalloc(handleIndicationAsyncPtr->attValue, 0, len);
1596         PacketPayloadAddLast(packet, bufferNew);
1597         BufferFree(bufferNew);
1598     }
1599 
1600     ret = AttResponseSendData(connect, packet);
1601     ServerCallbackReturnValue(ret, connect);
1602     PacketFree(packet);
1603 
1604 ATTHANDLEVALUEINDICATION_END:
1605     BufferFree(handleIndicationAsyncPtr->attValue);
1606     MEM_MALLOC.free(handleIndicationAsyncPtr);
1607     return;
1608 }
1609 
1610 /**
1611  * @brief destroy handle value indication in self thread..
1612  *
1613  * @param context Indicates the pointer to context.
1614  */
AttHandleValueIndicationAsyncDestroy(const void * context)1615 static void AttHandleValueIndicationAsyncDestroy(const void *context)
1616 {
1617     LOG_INFO("%{public}s enter", __FUNCTION__);
1618 
1619     WriteAsync *handleIndicationAsyncPtr = (WriteAsync *)context;
1620 
1621     BufferFree(handleIndicationAsyncPtr->attValue);
1622     MEM_MALLOC.free(handleIndicationAsyncPtr);
1623 
1624     return;
1625 }
1626 
1627 /**
1628  * @brief gatt send handlevalue indication to att.
1629  *
1630  * @param1 connectHandle Indicates the connect handle.
1631  * @param2 attHandle Indicates the handle of the attribute.
1632  * @param3 attValue Indicates the pointer to the current value of the attribute.
1633  * @return Returns <b>0</b> if the operation is successful; returns <b>!0</b> if the operation fails.
1634  */
ATT_HandleValueIndication(uint16_t connectHandle,uint16_t attHandle,const Buffer * attValue)1635 void ATT_HandleValueIndication(uint16_t connectHandle, uint16_t attHandle, const Buffer *attValue)
1636 {
1637     LOG_INFO("%{public}s enter, connectHandle = %hu, attHandle=%{public}d", __FUNCTION__, connectHandle, attHandle);
1638 
1639     Buffer *bufferPtr = NULL;
1640     WriteAsync *handleIndicationAsyncPtr = NULL;
1641 
1642     bufferPtr = BufferRefMalloc(attValue);
1643     handleIndicationAsyncPtr = MEM_MALLOC.alloc(sizeof(WriteAsync));
1644     if (handleIndicationAsyncPtr == NULL) {
1645         LOG_ERROR("point to NULL");
1646         return;
1647     }
1648     handleIndicationAsyncPtr->connectHandle = connectHandle;
1649     handleIndicationAsyncPtr->attHandle = attHandle;
1650     handleIndicationAsyncPtr->attValue = bufferPtr;
1651 
1652     AttAsyncProcess(AttHandleValueIndicationAsync, AttHandleValueIndicationAsyncDestroy, handleIndicationAsyncPtr);
1653 
1654     return;
1655 }
1656 
1657 /**
1658  * @brief server send data register..
1659  *
1660  * @param context Indicates the pointer to context.
1661  */
AttServerSendDataRegisterAsync(const void * context)1662 void AttServerSendDataRegisterAsync(const void *context)
1663 {
1664     LOG_INFO("%{public}s enter", __FUNCTION__);
1665 
1666     AttServerSendDataCallback *attServerSendDataCallbackPtr = (AttServerSendDataCallback *)context;
1667 
1668     g_attServerSendDataCB.attSendDataCB = attServerSendDataCallbackPtr->attSendDataCB;
1669     g_attServerSendDataCB.context = attServerSendDataCallbackPtr->context;
1670 
1671     AttServerCallBackCopyToCommon(attServerSendDataCallbackPtr->attSendDataCB, attServerSendDataCallbackPtr->context);
1672 
1673     MEM_MALLOC.free(attServerSendDataCallbackPtr);
1674 
1675     return;
1676 }
1677 
1678 /**
1679  * @brief server send data register.destroy.
1680  *
1681  * @param context Indicates the pointer to context.
1682  */
AttServerSendDataRegisterAsyncDestroy(const void * context)1683 void AttServerSendDataRegisterAsyncDestroy(const void *context)
1684 {
1685     LOG_INFO("%{public}s enter", __FUNCTION__);
1686 
1687     AttServerSendDataCallback *attServerSendDataCallbackPtr = (AttServerSendDataCallback *)context;
1688 
1689     MEM_MALLOC.free(attServerSendDataCallbackPtr);
1690 
1691     return;
1692 }
1693 
1694 /**
1695  * @brief server gatt send data register.
1696  *
1697  * @param1 attSendDataCB Indicates the pointer of attSendDataCallback.
1698  * @param2 context Indicates the pointer of context.
1699  */
ATT_ServerSendDataRegister(attSendDataCallback attSendDataCB,void * context)1700 void ATT_ServerSendDataRegister(attSendDataCallback attSendDataCB, void *context)
1701 {
1702     LOG_INFO("%{public}s enter", __FUNCTION__);
1703 
1704     AttServerSendDataCallback *attServerSendDataCallbackPtr = MEM_MALLOC.alloc(sizeof(AttServerSendDataCallback));
1705     if (attServerSendDataCallbackPtr == NULL) {
1706         LOG_ERROR("point to NULL");
1707         return;
1708     }
1709     attServerSendDataCallbackPtr->attSendDataCB = attSendDataCB;
1710     attServerSendDataCallbackPtr->context = context;
1711 
1712     AttAsyncProcess(
1713         AttServerSendDataRegisterAsync, AttServerSendDataRegisterAsyncDestroy, attServerSendDataCallbackPtr);
1714 
1715     return;
1716 }
1717 
1718 /**
1719  * @brief server send data deregister.
1720  *
1721  * @param context Indicates the pointer to context.
1722  */
AttServerSendDataDeRegisterAsync(const void * context)1723 void AttServerSendDataDeRegisterAsync(const void *context)
1724 {
1725     LOG_INFO("%{public}s enter", __FUNCTION__);
1726 
1727     g_attServerSendDataCB.attSendDataCB = NULL;
1728     g_attServerSendDataCB.context = NULL;
1729 
1730     AttCallBackDelectCopyToCommon();
1731 
1732     return;
1733 }
1734 
1735 /**
1736  * @brief server send data deregister.destroy.
1737  *
1738  * @param context Indicates the pointer to context.
1739  */
AttServerSendDataDeRegisterAsyncDestroy(const void * context)1740 void AttServerSendDataDeRegisterAsyncDestroy(const void *context)
1741 {
1742     LOG_INFO("%{public}s enter", __FUNCTION__);
1743 
1744     return;
1745 }
1746 
1747 /**
1748  * @brief server gatt send data deregister.
1749  *
1750  */
ATT_ServerSendDataDeRegister()1751 void ATT_ServerSendDataDeRegister()
1752 {
1753     LOG_INFO("%{public}s enter", __FUNCTION__);
1754 
1755     AttAsyncProcess(AttServerSendDataDeRegisterAsync, AttServerSendDataDeRegisterAsyncDestroy, NULL);
1756 
1757     return;
1758 }
1759