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