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