@@ -498,8 +498,37 @@ void HCIClass::handleAclDataPkt(uint8_t /*plen*/, uint8_t pdata[])
498498 uint16_t cid;
499499 } *aclHdr = (HCIACLHdr*)pdata;
500500
501+ uint16_t aclFlags = (aclHdr->handle & 0xf000 ) >> 12 ;
502+
503+ if ((aclHdr->dlen - 4 ) != aclHdr->len ) {
504+ // packet is fragmented
505+ if (aclFlags != 0x01 ) {
506+ // copy into ACL buffer
507+ memcpy (_aclPktBuffer, &_recvBuffer[1 ], sizeof (HCIACLHdr) + aclHdr->dlen - 4 );
508+ } else {
509+ // copy next chunk into the buffer
510+ HCIACLHdr* aclBufferHeader = (HCIACLHdr*)_aclPktBuffer;
511+
512+ memcpy (&_aclPktBuffer[sizeof (HCIACLHdr) + aclBufferHeader->dlen - 4 ], &_recvBuffer[1 + sizeof (aclHdr->handle ) + sizeof (aclHdr->dlen )], aclHdr->dlen );
513+
514+ aclBufferHeader->dlen += aclHdr->dlen ;
515+ aclHdr = aclBufferHeader;
516+ }
517+ }
518+
519+ if ((aclHdr->dlen - 4 ) != aclHdr->len ) {
520+ // don't have the full packet yet
521+ return ;
522+ }
523+
501524 if (aclHdr->cid == ATT_CID) {
502- ATT.handleData (aclHdr->handle & 0x0fff , aclHdr->len , &_recvBuffer[1 + sizeof (HCIACLHdr)]);
525+ if (aclFlags == 0x01 ) {
526+ // use buffered packet
527+ ATT.handleData (aclHdr->handle & 0x0fff , aclHdr->len , &_aclPktBuffer[sizeof (HCIACLHdr)]);
528+ } else {
529+ // use the recv buffer
530+ ATT.handleData (aclHdr->handle & 0x0fff , aclHdr->len , &_recvBuffer[1 + sizeof (HCIACLHdr)]);
531+ }
503532 } else if (aclHdr->cid == SIGNALING_CID) {
504533 L2CAPSignaling.handleData (aclHdr->handle & 0x0fff , aclHdr->len , &_recvBuffer[1 + sizeof (HCIACLHdr)]);
505534 } else {
0 commit comments