@@ -95,6 +95,7 @@ ATTClass::ATTClass() :
9595 memset (_peers[i].address , 0x00 , sizeof (_peers[i].address ));
9696 _peers[i].mtu = 23 ;
9797 _peers[i].device = NULL ;
98+ _peers[i].encryption = 0x0 ;
9899 }
99100
100101 memset (_eventHandlers, 0x00 , sizeof (_eventHandlers));
@@ -267,12 +268,22 @@ void ATTClass::handleData(uint16_t connectionHandle, uint8_t dlen, uint8_t data[
267268
268269 uint16_t mtu = this ->mtu (connectionHandle);
269270
271+ #ifdef _BLE_TRACE_
272+ Serial.print (" data opcode: 0x" );
273+ Serial.println (opcode, HEX);
274+ #endif
270275 switch (opcode) {
271276 case ATT_OP_ERROR:
277+ #ifdef _BLE_TRACE_
278+ Serial.println (" [Info] data error" );
279+ #endif
272280 error (connectionHandle, dlen, data);
273281 break ;
274282
275283 case ATT_OP_MTU_REQ:
284+ #ifdef _BLE_TRACE_
285+ Serial.println (" MTU" );
286+ #endif
276287 mtuReq (connectionHandle, dlen, data);
277288 break ;
278289
@@ -281,6 +292,9 @@ void ATTClass::handleData(uint16_t connectionHandle, uint8_t dlen, uint8_t data[
281292 break ;
282293
283294 case ATT_OP_FIND_INFO_REQ:
295+ #ifdef _BLE_TRACE_
296+ Serial.println (" Find info" );
297+ #endif
284298 findInfoReq (connectionHandle, mtu, dlen, data);
285299 break ;
286300
@@ -293,6 +307,9 @@ void ATTClass::handleData(uint16_t connectionHandle, uint8_t dlen, uint8_t data[
293307 break ;
294308
295309 case ATT_OP_READ_BY_TYPE_REQ:
310+ #ifdef _BLE_TRACE_
311+ Serial.println (" By type" );
312+ #endif
296313 readByTypeReq (connectionHandle, mtu, dlen, data);
297314 break ;
298315
@@ -319,6 +336,9 @@ void ATTClass::handleData(uint16_t connectionHandle, uint8_t dlen, uint8_t data[
319336
320337 case ATT_OP_WRITE_REQ:
321338 case ATT_OP_WRITE_CMD:
339+ #ifdef _BLE_TRACE_
340+ Serial.println (" Write req" );
341+ #endif
322342 writeReqOrCmd (connectionHandle, mtu, opcode, dlen, data);
323343 break ;
324344
@@ -346,6 +366,9 @@ void ATTClass::handleData(uint16_t connectionHandle, uint8_t dlen, uint8_t data[
346366 case ATT_OP_READ_MULTI_REQ:
347367 case ATT_OP_SIGNED_WRITE_CMD:
348368 default :
369+ #ifdef _BLE_TRACE_
370+ Serial.println (" [Info] Unhandled dara" );
371+ #endif
349372 sendError (connectionHandle, opcode, 0x00 , ATT_ECODE_REQ_NOT_SUPP);
350373 break ;
351374 }
@@ -398,6 +421,10 @@ void ATTClass::removeConnection(uint16_t handle, uint8_t /*reason*/)
398421 _peers[peerIndex].addressType = 0x00 ;
399422 memset (_peers[peerIndex].address , 0x00 , sizeof (_peers[peerIndex].address ));
400423 _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 ;
401428
402429 if (_peers[peerIndex].device ) {
403430 delete _peers[peerIndex].device ;
@@ -807,6 +834,14 @@ void ATTClass::readByGroupReq(uint16_t connectionHandle, uint16_t mtu, uint8_t d
807834 uint16_t endHandle;
808835 uint16_t uuid;
809836 } *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
810845
811846 if (dlen != sizeof (ReadByGroupReq) || (readByGroupReq->uuid != BLETypeService && readByGroupReq->uuid != 0x2801 )) {
812847 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
819854 response[0 ] = ATT_OP_READ_BY_GROUP_RESP;
820855 response[1 ] = 0x00 ;
821856 responseLength = 2 ;
822-
857+ #ifdef _BLE_TRACE_
858+ Serial.print (" readByGroupReq: attrcount: " );
859+ Serial.println (GATT.attributeCount ());
860+ #endif
823861 for (uint16_t i = (readByGroupReq->startHandle - 1 ); i < GATT.attributeCount () && i <= (readByGroupReq->endHandle - 1 ); i++) {
824862 BLELocalAttribute* attribute = GATT.attribute (i);
825863
@@ -906,6 +944,8 @@ void ATTClass::readOrReadBlobReq(uint16_t connectionHandle, uint16_t mtu, uint8_
906944 return ;
907945 }
908946 }
947+ // / if auth error, hold the response in a buffer.
948+ bool holdResponse = false ;
909949
910950 uint16_t handle = *(uint16_t *)data;
911951 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_
9621002 sendError (connectionHandle, opcode, handle, ATT_ECODE_READ_NOT_PERM);
9631003 return ;
9641004 }
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+ }
9651010
9661011 uint16_t valueLength = characteristic->valueLength ();
9671012
@@ -994,8 +1039,12 @@ void ATTClass::readOrReadBlobReq(uint16_t connectionHandle, uint16_t mtu, uint8_
9941039 memcpy (&response[responseLength], descriptor->value () + offset, valueLength);
9951040 responseLength += valueLength;
9961041 }
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+ }
9991048}
10001049
10011050void 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_
16871736 sendReq (connectionHandle, &writeReq, 3 + dataLen, NULL );
16881737}
16891738
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+ }
16901816ATTClass ATT;
0 commit comments