@@ -95,6 +95,7 @@ ATTClass::ATTClass() :
95
95
memset (_peers[i].address , 0x00 , sizeof (_peers[i].address ));
96
96
_peers[i].mtu = 23 ;
97
97
_peers[i].device = NULL ;
98
+ _peers[i].encryption = 0x0 ;
98
99
}
99
100
100
101
memset (_eventHandlers, 0x00 , sizeof (_eventHandlers));
@@ -267,12 +268,22 @@ void ATTClass::handleData(uint16_t connectionHandle, uint8_t dlen, uint8_t data[
267
268
268
269
uint16_t mtu = this ->mtu (connectionHandle);
269
270
271
+ #ifdef _BLE_TRACE_
272
+ Serial.print (" data opcode: 0x" );
273
+ Serial.println (opcode, HEX);
274
+ #endif
270
275
switch (opcode) {
271
276
case ATT_OP_ERROR:
277
+ #ifdef _BLE_TRACE_
278
+ Serial.println (" [Info] data error" );
279
+ #endif
272
280
error (connectionHandle, dlen, data);
273
281
break ;
274
282
275
283
case ATT_OP_MTU_REQ:
284
+ #ifdef _BLE_TRACE_
285
+ Serial.println (" MTU" );
286
+ #endif
276
287
mtuReq (connectionHandle, dlen, data);
277
288
break ;
278
289
@@ -281,6 +292,9 @@ void ATTClass::handleData(uint16_t connectionHandle, uint8_t dlen, uint8_t data[
281
292
break ;
282
293
283
294
case ATT_OP_FIND_INFO_REQ:
295
+ #ifdef _BLE_TRACE_
296
+ Serial.println (" Find info" );
297
+ #endif
284
298
findInfoReq (connectionHandle, mtu, dlen, data);
285
299
break ;
286
300
@@ -293,6 +307,9 @@ void ATTClass::handleData(uint16_t connectionHandle, uint8_t dlen, uint8_t data[
293
307
break ;
294
308
295
309
case ATT_OP_READ_BY_TYPE_REQ:
310
+ #ifdef _BLE_TRACE_
311
+ Serial.println (" By type" );
312
+ #endif
296
313
readByTypeReq (connectionHandle, mtu, dlen, data);
297
314
break ;
298
315
@@ -319,6 +336,9 @@ void ATTClass::handleData(uint16_t connectionHandle, uint8_t dlen, uint8_t data[
319
336
320
337
case ATT_OP_WRITE_REQ:
321
338
case ATT_OP_WRITE_CMD:
339
+ #ifdef _BLE_TRACE_
340
+ Serial.println (" Write req" );
341
+ #endif
322
342
writeReqOrCmd (connectionHandle, mtu, opcode, dlen, data);
323
343
break ;
324
344
@@ -346,6 +366,9 @@ void ATTClass::handleData(uint16_t connectionHandle, uint8_t dlen, uint8_t data[
346
366
case ATT_OP_READ_MULTI_REQ:
347
367
case ATT_OP_SIGNED_WRITE_CMD:
348
368
default :
369
+ #ifdef _BLE_TRACE_
370
+ Serial.println (" [Info] Unhandled dara" );
371
+ #endif
349
372
sendError (connectionHandle, opcode, 0x00 , ATT_ECODE_REQ_NOT_SUPP);
350
373
break ;
351
374
}
@@ -398,6 +421,10 @@ void ATTClass::removeConnection(uint16_t handle, uint8_t /*reason*/)
398
421
_peers[peerIndex].addressType = 0x00 ;
399
422
memset (_peers[peerIndex].address , 0x00 , sizeof (_peers[peerIndex].address ));
400
423
_peers[peerIndex].mtu = 23 ;
424
+ _peers[peerIndex].encryption = PEER_ENCRYPTION::NO_ENCRYPTION;
425
+ _peers[peerIndex].IOCap [0 ] = 0 ;
426
+ _peers[peerIndex].IOCap [1 ] = 0 ;
427
+ _peers[peerIndex].IOCap [2 ] = 0 ;
401
428
402
429
if (_peers[peerIndex].device ) {
403
430
delete _peers[peerIndex].device ;
@@ -807,6 +834,14 @@ void ATTClass::readByGroupReq(uint16_t connectionHandle, uint16_t mtu, uint8_t d
807
834
uint16_t endHandle;
808
835
uint16_t uuid;
809
836
} *readByGroupReq = (ReadByGroupReq*)data;
837
+ #ifdef _BLE_TRACE_
838
+ Serial.print (" readByGroupReq: start: 0x" );
839
+ Serial.println (readByGroupReq->startHandle ,HEX);
840
+ Serial.print (" readByGroupReq: end: 0x" );
841
+ Serial.println (readByGroupReq->endHandle ,HEX);
842
+ Serial.print (" readByGroupReq: UUID: 0x" );
843
+ Serial.println (readByGroupReq->uuid ,HEX);
844
+ #endif
810
845
811
846
if (dlen != sizeof (ReadByGroupReq) || (readByGroupReq->uuid != BLETypeService && readByGroupReq->uuid != 0x2801 )) {
812
847
sendError (connectionHandle, ATT_OP_READ_BY_GROUP_REQ, readByGroupReq->startHandle , ATT_ECODE_UNSUPP_GRP_TYPE);
@@ -819,7 +854,10 @@ void ATTClass::readByGroupReq(uint16_t connectionHandle, uint16_t mtu, uint8_t d
819
854
response[0 ] = ATT_OP_READ_BY_GROUP_RESP;
820
855
response[1 ] = 0x00 ;
821
856
responseLength = 2 ;
822
-
857
+ #ifdef _BLE_TRACE_
858
+ Serial.print (" readByGroupReq: attrcount: " );
859
+ Serial.println (GATT.attributeCount ());
860
+ #endif
823
861
for (uint16_t i = (readByGroupReq->startHandle - 1 ); i < GATT.attributeCount () && i <= (readByGroupReq->endHandle - 1 ); i++) {
824
862
BLELocalAttribute* attribute = GATT.attribute (i);
825
863
@@ -906,6 +944,8 @@ void ATTClass::readOrReadBlobReq(uint16_t connectionHandle, uint16_t mtu, uint8_
906
944
return ;
907
945
}
908
946
}
947
+ // / if auth error, hold the response in a buffer.
948
+ bool holdResponse = false ;
909
949
910
950
uint16_t handle = *(uint16_t *)data;
911
951
uint16_t offset = (opcode == ATT_OP_READ_REQ) ? 0 : *(uint16_t *)&data[sizeof (handle)];
@@ -962,6 +1002,11 @@ void ATTClass::readOrReadBlobReq(uint16_t connectionHandle, uint16_t mtu, uint8_
962
1002
sendError (connectionHandle, opcode, handle, ATT_ECODE_READ_NOT_PERM);
963
1003
return ;
964
1004
}
1005
+ // If characteristic requires encryption send error & hold response until encrypted
1006
+ if ((characteristic->properties () & BLEAuth) > 0 && (getPeerEncryption (connectionHandle) & PEER_ENCRYPTION::ENCRYPTED_AES)==0 ) {
1007
+ holdResponse = true ;
1008
+ sendError (connectionHandle, opcode, handle, ATT_ECODE_INSUFF_ENC);
1009
+ }
965
1010
966
1011
uint16_t valueLength = characteristic->valueLength ();
967
1012
@@ -994,8 +1039,12 @@ void ATTClass::readOrReadBlobReq(uint16_t connectionHandle, uint16_t mtu, uint8_
994
1039
memcpy (&response[responseLength], descriptor->value () + offset, valueLength);
995
1040
responseLength += valueLength;
996
1041
}
997
-
998
- HCI.sendAclPkt (connectionHandle, ATT_CID, responseLength, response);
1042
+ if (holdResponse){
1043
+ memcpy (holdBuffer, response, responseLength);
1044
+ holdBufferSize = responseLength;
1045
+ }else {
1046
+ HCI.sendAclPkt (connectionHandle, ATT_CID, responseLength, response);
1047
+ }
999
1048
}
1000
1049
1001
1050
void ATTClass::readResp (uint16_t connectionHandle, uint8_t dlen, uint8_t data[])
@@ -1687,4 +1736,81 @@ void ATTClass::writeCmd(uint16_t connectionHandle, uint16_t handle, const uint8_
1687
1736
sendReq (connectionHandle, &writeReq, 3 + dataLen, NULL );
1688
1737
}
1689
1738
1739
+ // Set encryption state for a peer
1740
+ int ATTClass::setPeerEncryption (uint16_t connectionHandle, uint8_t encryption){
1741
+ for (int i=0 ; i<ATT_MAX_PEERS; i++){
1742
+ if (_peers[i].connectionHandle != connectionHandle){
1743
+ continue ;
1744
+ }
1745
+ _peers[i].encryption = encryption;
1746
+ return 1 ;
1747
+ }
1748
+ return 0 ;
1749
+ }
1750
+ // Set the IO capabilities for a peer
1751
+ int ATTClass::setPeerIOCap (uint16_t connectionHandle, uint8_t IOCap[3 ]){
1752
+ for (int i=0 ; i<ATT_MAX_PEERS; i++){
1753
+ if (_peers[i].connectionHandle != connectionHandle){
1754
+ continue ;
1755
+ }
1756
+ memcpy (_peers[i].IOCap , IOCap, 3 );
1757
+ return 1 ;
1758
+ }
1759
+ return 0 ;
1760
+ }
1761
+ // Return the connection handle for the first peer that is requesting encryption
1762
+ uint16_t ATTClass::getPeerEncrptingConnectionHandle (){
1763
+ for (int i=0 ; i<ATT_MAX_PEERS; i++){
1764
+ if (_peers[i].encryption & PEER_ENCRYPTION::REQUESTED_ENCRYPTION > 0 ){
1765
+ return _peers[i].connectionHandle ;
1766
+ }
1767
+ }
1768
+ return ATT_MAX_PEERS + 1 ;
1769
+ }
1770
+ // Get the encryption state for a particular peer / connection handle
1771
+ uint8_t ATTClass::getPeerEncryption (uint16_t connectionHandle) {
1772
+ for (int i=0 ; i<ATT_MAX_PEERS; i++){
1773
+ if (_peers[i].connectionHandle != connectionHandle){continue ;}
1774
+ return _peers[i].encryption ;
1775
+ }
1776
+ return 0 ;
1777
+ }
1778
+ // Get the IOCapabilities for a peer
1779
+ int ATTClass::getPeerIOCap (uint16_t connectionHandle, uint8_t IOCap[3 ]) {
1780
+ for (int i=0 ; i<ATT_MAX_PEERS; i++){
1781
+ if (_peers[i].connectionHandle != connectionHandle){continue ;}
1782
+ // return _peers[i].encryption;
1783
+ memcpy (IOCap, _peers[i].IOCap , 3 );
1784
+ }
1785
+ return 0 ;
1786
+ }
1787
+ // Get the BD_ADDR for a peer
1788
+ int ATTClass::getPeerAddr (uint16_t connectionHandle, uint8_t peerAddr[])
1789
+ {
1790
+ for (int i=0 ; i<ATT_MAX_PEERS; i++)
1791
+ {
1792
+ if (_peers[i].connectionHandle != connectionHandle){continue ;}
1793
+ memcpy (peerAddr, _peers[i].address ,6 );
1794
+ return 1 ;
1795
+ }
1796
+ return 0 ;
1797
+ }
1798
+ // Get the BD_ADDR for a peer in the format needed by f6 for pairing.
1799
+ int ATTClass::getPeerAddrWithType (uint16_t connectionHandle, uint8_t peerAddr[])
1800
+ {
1801
+ for (int i=0 ; i<ATT_MAX_PEERS; i++)
1802
+ {
1803
+ if (_peers[i].connectionHandle != connectionHandle){continue ;}
1804
+ for (int k=0 ; k<6 ; k++){
1805
+ peerAddr[6 -k] = _peers[i].address [k];
1806
+ }
1807
+ if (_peers[i].addressType ){
1808
+ peerAddr[0 ] = 0x01 ;
1809
+ }else {
1810
+ peerAddr[0 ] = 0x00 ;
1811
+ }
1812
+ return 1 ;
1813
+ }
1814
+ return 0 ;
1815
+ }
1690
1816
ATTClass ATT;
0 commit comments