Skip to content

Commit f075b9b

Browse files
authored
Unit tests for BLE layer class (#33359)
* Unit tests for BLE layer class * Check for mBleTransport NULL before dereference * Return false in case of handle error in BLE layer * Check for NULL UUIDs match * Test for exceeding max number of BLE connections * Fix compilation on ESP32 * More compilation fixes * Mark SetUp and TearDown as overrides * Update includes
1 parent 2d6d403 commit f075b9b

File tree

6 files changed

+484
-191
lines changed

6 files changed

+484
-191
lines changed

src/ble/BLEEndPoint.cpp

+3-3
Original file line numberDiff line numberDiff line change
@@ -346,7 +346,7 @@ void BLEEndPoint::DoClose(uint8_t flags, CHIP_ERROR err)
346346
DoCloseCallback(oldState, flags, err);
347347
}
348348

349-
if ((flags & kBleCloseFlag_SuppressCallback) != 0)
349+
if (mBleTransport != nullptr && (flags & kBleCloseFlag_SuppressCallback) != 0)
350350
{
351351
mBleTransport->OnEndPointConnectionClosed(this, err);
352352
}
@@ -367,7 +367,7 @@ void BLEEndPoint::FinalizeClose(uint8_t oldState, uint8_t flags, CHIP_ERROR err)
367367
DoCloseCallback(oldState, flags, err);
368368
}
369369

370-
if ((flags & kBleCloseFlag_SuppressCallback) != 0)
370+
if (mBleTransport != nullptr && (flags & kBleCloseFlag_SuppressCallback) != 0)
371371
{
372372
mBleTransport->OnEndPointConnectionClosed(this, err);
373373
}
@@ -1290,7 +1290,7 @@ CHIP_ERROR BLEEndPoint::Receive(PacketBufferHandle && data)
12901290
// Take ownership of message buffer
12911291
System::PacketBufferHandle full_packet = mBtpEngine.TakeRxPacket();
12921292

1293-
ChipLogDebugBleEndPoint(Ble, "reassembled whole msg, len = %d", full_packet->DataLength());
1293+
ChipLogDebugBleEndPoint(Ble, "reassembled whole msg, len = %u", static_cast<unsigned>(full_packet->DataLength()));
12941294

12951295
// If we have a message received callback, and end point is not closing...
12961296
if (mBleTransport != nullptr && mState != kState_Closing)

src/ble/BleLayer.cpp

+70-186
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@
2222
* a platform's Bluetooth Low Energy (BLE) implementation and the CHIP
2323
* stack.
2424
*
25-
* The BleLayer obect accepts BLE data and control input from the
25+
* The BleLayer object accepts BLE data and control input from the
2626
* application via a functional interface. It performs the fragmentation
2727
* and reassembly required to transmit CHIP message via a BLE GATT
2828
* characteristic interface, and drives incoming messages up the CHIP
@@ -485,43 +485,24 @@ CHIP_ERROR BleLayer::HandleBleTransportConnectionInitiated(BLE_CONNECTION_OBJECT
485485
bool BleLayer::HandleWriteReceived(BLE_CONNECTION_OBJECT connObj, const ChipBleUUID * svcId, const ChipBleUUID * charId,
486486
PacketBufferHandle && pBuf)
487487
{
488-
if (!UUIDsMatch(&CHIP_BLE_SVC_ID, svcId))
489-
{
490-
ChipLogError(Ble, "ble write rcvd on unknown svc id");
491-
return true;
492-
}
488+
VerifyOrReturnError(UUIDsMatch(&CHIP_BLE_SVC_ID, svcId), false, ChipLogError(Ble, "Write received on unknown svc"));
489+
VerifyOrReturnError(UUIDsMatch(&CHIP_BLE_CHAR_1_ID, charId), false, ChipLogError(Ble, "Write received on unknown char"));
490+
VerifyOrReturnError(!pBuf.IsNull(), false, ChipLogError(Ble, "Write received null buffer"));
493491

494-
if (UUIDsMatch(&CHIP_BLE_CHAR_1_ID, charId))
495-
{
496-
if (pBuf.IsNull())
497-
{
498-
ChipLogError(Ble, "rcvd null ble write");
499-
return true;
500-
}
501-
502-
// Find matching connection end point.
503-
BLEEndPoint * endPoint = sBLEEndPointPool.Find(connObj);
492+
// Find matching connection end point.
493+
BLEEndPoint * endPoint = sBLEEndPointPool.Find(connObj);
504494

505-
if (endPoint != nullptr)
506-
{
507-
CHIP_ERROR status = endPoint->Receive(std::move(pBuf));
508-
if (status != CHIP_NO_ERROR)
509-
{
510-
ChipLogError(Ble, "BLEEndPoint rcv failed, err = %" CHIP_ERROR_FORMAT, status.Format());
511-
}
512-
}
513-
else
514-
{
515-
CHIP_ERROR status = HandleBleTransportConnectionInitiated(connObj, std::move(pBuf));
516-
if (status != CHIP_NO_ERROR)
517-
{
518-
ChipLogError(Ble, "failed handle new chip BLE connection, status = %" CHIP_ERROR_FORMAT, status.Format());
519-
}
520-
}
495+
if (endPoint != nullptr)
496+
{
497+
CHIP_ERROR err = endPoint->Receive(std::move(pBuf));
498+
VerifyOrReturnError(err == CHIP_NO_ERROR, false,
499+
ChipLogError(Ble, "Receive failed, err = %" CHIP_ERROR_FORMAT, err.Format()));
521500
}
522501
else
523502
{
524-
ChipLogError(Ble, "ble write rcvd on unknown char");
503+
CHIP_ERROR err = HandleBleTransportConnectionInitiated(connObj, std::move(pBuf));
504+
VerifyOrReturnError(err == CHIP_NO_ERROR, false,
505+
ChipLogError(Ble, "Handle new BLE connection failed, err = %" CHIP_ERROR_FORMAT, err.Format()));
525506
}
526507

527508
return true;
@@ -530,217 +511,120 @@ bool BleLayer::HandleWriteReceived(BLE_CONNECTION_OBJECT connObj, const ChipBleU
530511
bool BleLayer::HandleIndicationReceived(BLE_CONNECTION_OBJECT connObj, const ChipBleUUID * svcId, const ChipBleUUID * charId,
531512
PacketBufferHandle && pBuf)
532513
{
533-
if (!UUIDsMatch(&CHIP_BLE_SVC_ID, svcId))
534-
{
535-
return false;
536-
}
514+
VerifyOrReturnError(UUIDsMatch(&CHIP_BLE_SVC_ID, svcId), false, ChipLogError(Ble, "Indication received on unknown svc"));
515+
VerifyOrReturnError(UUIDsMatch(&CHIP_BLE_CHAR_2_ID, charId), false, ChipLogError(Ble, "Indication received on unknown char"));
516+
VerifyOrReturnError(!pBuf.IsNull(), false, ChipLogError(Ble, "Indication received null buffer"));
537517

538-
if (UUIDsMatch(&CHIP_BLE_CHAR_2_ID, charId))
539-
{
540-
if (pBuf.IsNull())
541-
{
542-
ChipLogError(Ble, "rcvd null ble indication");
543-
return true;
544-
}
545-
546-
// find matching connection end point.
547-
BLEEndPoint * endPoint = sBLEEndPointPool.Find(connObj);
518+
// Find matching connection end point.
519+
BLEEndPoint * endPoint = sBLEEndPointPool.Find(connObj);
520+
VerifyOrReturnError(endPoint != nullptr, false, ChipLogDetail(Ble, "No endpoint for received indication"));
548521

549-
if (endPoint != nullptr)
550-
{
551-
CHIP_ERROR status = endPoint->Receive(std::move(pBuf));
552-
if (status != CHIP_NO_ERROR)
553-
{
554-
ChipLogError(Ble, "BLEEndPoint rcv failed, err = %" CHIP_ERROR_FORMAT, status.Format());
555-
}
556-
}
557-
else
558-
{
559-
ChipLogDetail(Ble, "no endpoint for rcvd indication");
560-
}
561-
}
562-
else
563-
{
564-
ChipLogError(Ble, "ble ind rcvd on unknown char");
565-
}
522+
CHIP_ERROR err = endPoint->Receive(std::move(pBuf));
523+
VerifyOrReturnError(err == CHIP_NO_ERROR, false, ChipLogError(Ble, "Receive failed, err = %" CHIP_ERROR_FORMAT, err.Format()));
566524

567525
return true;
568526
}
569527

570528
bool BleLayer::HandleWriteConfirmation(BLE_CONNECTION_OBJECT connObj, const ChipBleUUID * svcId, const ChipBleUUID * charId)
571529
{
572-
if (!UUIDsMatch(&CHIP_BLE_SVC_ID, svcId))
573-
{
574-
return false;
575-
}
576-
577-
if (UUIDsMatch(&CHIP_BLE_CHAR_1_ID, charId))
578-
{
579-
HandleAckReceived(connObj);
580-
}
581-
else
582-
{
583-
ChipLogError(Ble, "ble write con rcvd on unknown char");
584-
}
530+
VerifyOrReturnError(UUIDsMatch(&CHIP_BLE_SVC_ID, svcId), false, ChipLogError(Ble, "Write confirmation on unknown svc"));
531+
VerifyOrReturnError(UUIDsMatch(&CHIP_BLE_CHAR_1_ID, charId), false, ChipLogError(Ble, "Write confirmation on unknown char"));
585532

533+
HandleAckReceived(connObj);
586534
return true;
587535
}
588536

589537
bool BleLayer::HandleIndicationConfirmation(BLE_CONNECTION_OBJECT connObj, const ChipBleUUID * svcId, const ChipBleUUID * charId)
590538
{
591-
if (!UUIDsMatch(&CHIP_BLE_SVC_ID, svcId))
592-
{
593-
return false;
594-
}
595-
596-
if (UUIDsMatch(&CHIP_BLE_CHAR_2_ID, charId))
597-
{
598-
HandleAckReceived(connObj);
599-
}
600-
else
601-
{
602-
ChipLogError(Ble, "ble ind con rcvd on unknown char");
603-
}
539+
VerifyOrReturnError(UUIDsMatch(&CHIP_BLE_SVC_ID, svcId), false, ChipLogError(Ble, "Indication confirmation on unknown svc"));
540+
VerifyOrReturnError(UUIDsMatch(&CHIP_BLE_CHAR_2_ID, charId), false,
541+
ChipLogError(Ble, "Indication confirmation on unknown char"));
604542

543+
HandleAckReceived(connObj);
605544
return true;
606545
}
607546

608547
void BleLayer::HandleAckReceived(BLE_CONNECTION_OBJECT connObj)
609548
{
610-
// find matching connection end point.
549+
// Find matching connection end point.
611550
BLEEndPoint * endPoint = sBLEEndPointPool.Find(connObj);
551+
VerifyOrReturn(endPoint != nullptr, ChipLogDetail(Ble, "No endpoint for received ack"));
612552

613-
if (endPoint != nullptr)
614-
{
615-
CHIP_ERROR status = endPoint->HandleGattSendConfirmationReceived();
616-
617-
if (status != CHIP_NO_ERROR)
618-
{
619-
ChipLogError(Ble, "endpoint conf recvd failed, err = %" CHIP_ERROR_FORMAT, status.Format());
620-
}
621-
}
622-
else
623-
{
624-
ChipLogError(Ble, "no endpoint for BLE sent data ack");
625-
}
553+
CHIP_ERROR err = endPoint->HandleGattSendConfirmationReceived();
554+
VerifyOrReturn(err == CHIP_NO_ERROR,
555+
ChipLogError(Ble, "Send ack confirmation failed, err = %" CHIP_ERROR_FORMAT, err.Format()));
626556
}
627557

628558
bool BleLayer::HandleSubscribeReceived(BLE_CONNECTION_OBJECT connObj, const ChipBleUUID * svcId, const ChipBleUUID * charId)
629559
{
630-
if (!UUIDsMatch(&CHIP_BLE_SVC_ID, svcId))
631-
{
632-
return false;
633-
}
560+
VerifyOrReturnError(UUIDsMatch(&CHIP_BLE_SVC_ID, svcId), false, ChipLogError(Ble, "Subscribe received on unknown svc"));
561+
VerifyOrReturnError(UUIDsMatch(&CHIP_BLE_CHAR_2_ID, charId) || UUIDsMatch(&CHIP_BLE_CHAR_3_ID, charId), false,
562+
ChipLogError(Ble, "Subscribe received on unknown char"));
634563

635-
if (UUIDsMatch(&CHIP_BLE_CHAR_2_ID, charId) || UUIDsMatch(&CHIP_BLE_CHAR_3_ID, charId))
636-
{
637-
// Find end point already associated with BLE connection, if any.
638-
BLEEndPoint * endPoint = sBLEEndPointPool.Find(connObj);
639-
640-
if (endPoint != nullptr)
641-
{
642-
endPoint->HandleSubscribeReceived();
643-
}
644-
else
645-
{
646-
ChipLogError(Ble, "no endpoint for sub recvd");
647-
}
648-
}
564+
// Find end point already associated with BLE connection, if any.
565+
BLEEndPoint * endPoint = sBLEEndPointPool.Find(connObj);
566+
VerifyOrReturnError(endPoint != nullptr, false, ChipLogDetail(Ble, "No endpoint for received subscribe"));
649567

568+
endPoint->HandleSubscribeReceived();
650569
return true;
651570
}
652571

653572
bool BleLayer::HandleSubscribeComplete(BLE_CONNECTION_OBJECT connObj, const ChipBleUUID * svcId, const ChipBleUUID * charId)
654573
{
655-
if (!UUIDsMatch(&CHIP_BLE_SVC_ID, svcId))
656-
{
657-
return false;
658-
}
574+
VerifyOrReturnError(UUIDsMatch(&CHIP_BLE_SVC_ID, svcId), false, ChipLogError(Ble, "Subscribe complete on unknown svc"));
575+
VerifyOrReturnError(UUIDsMatch(&CHIP_BLE_CHAR_2_ID, charId) || UUIDsMatch(&CHIP_BLE_CHAR_3_ID, charId), false,
576+
ChipLogError(Ble, "Subscribe complete on unknown char"));
659577

660-
if (UUIDsMatch(&CHIP_BLE_CHAR_2_ID, charId) || UUIDsMatch(&CHIP_BLE_CHAR_3_ID, charId))
661-
{
662-
BLEEndPoint * endPoint = sBLEEndPointPool.Find(connObj);
663-
664-
if (endPoint != nullptr)
665-
{
666-
endPoint->HandleSubscribeComplete();
667-
}
668-
else
669-
{
670-
ChipLogError(Ble, "no endpoint for sub complete");
671-
}
672-
}
578+
BLEEndPoint * endPoint = sBLEEndPointPool.Find(connObj);
579+
VerifyOrReturnError(endPoint != nullptr, false, ChipLogDetail(Ble, "No endpoint for subscribe complete"));
673580

581+
endPoint->HandleSubscribeComplete();
674582
return true;
675583
}
676584

677585
bool BleLayer::HandleUnsubscribeReceived(BLE_CONNECTION_OBJECT connObj, const ChipBleUUID * svcId, const ChipBleUUID * charId)
678586
{
679-
if (!UUIDsMatch(&CHIP_BLE_SVC_ID, svcId))
680-
{
681-
return false;
682-
}
587+
VerifyOrReturnError(UUIDsMatch(&CHIP_BLE_SVC_ID, svcId), false, ChipLogError(Ble, "Unsubscribe received on unknown svc"));
588+
VerifyOrReturnError(UUIDsMatch(&CHIP_BLE_CHAR_2_ID, charId) || UUIDsMatch(&CHIP_BLE_CHAR_3_ID, charId), false,
589+
ChipLogError(Ble, "Unsubscribe received on unknown char"));
683590

684-
if (UUIDsMatch(&CHIP_BLE_CHAR_2_ID, charId) || UUIDsMatch(&CHIP_BLE_CHAR_3_ID, charId))
685-
{
686-
// Find end point already associated with BLE connection, if any.
687-
BLEEndPoint * endPoint = sBLEEndPointPool.Find(connObj);
688-
689-
if (endPoint != nullptr)
690-
{
691-
endPoint->DoClose(kBleCloseFlag_AbortTransmission, BLE_ERROR_CENTRAL_UNSUBSCRIBED);
692-
}
693-
else
694-
{
695-
ChipLogError(Ble, "no endpoint for unsub recvd");
696-
}
697-
}
591+
// Find end point already associated with BLE connection, if any.
592+
BLEEndPoint * endPoint = sBLEEndPointPool.Find(connObj);
593+
VerifyOrReturnError(endPoint != nullptr, false, ChipLogDetail(Ble, "No endpoint for unsubscribe received"));
698594

595+
endPoint->DoClose(kBleCloseFlag_AbortTransmission, BLE_ERROR_CENTRAL_UNSUBSCRIBED);
699596
return true;
700597
}
701598

702599
bool BleLayer::HandleUnsubscribeComplete(BLE_CONNECTION_OBJECT connObj, const ChipBleUUID * svcId, const ChipBleUUID * charId)
703600
{
704-
if (!UUIDsMatch(&CHIP_BLE_SVC_ID, svcId))
705-
{
706-
return false;
707-
}
601+
VerifyOrReturnError(UUIDsMatch(&CHIP_BLE_SVC_ID, svcId), false, ChipLogError(Ble, "Unsubscribe complete on unknown svc"));
602+
VerifyOrReturnError(UUIDsMatch(&CHIP_BLE_CHAR_2_ID, charId) || UUIDsMatch(&CHIP_BLE_CHAR_3_ID, charId), false,
603+
ChipLogError(Ble, "Unsubscribe complete on unknown char"));
708604

709-
if (UUIDsMatch(&CHIP_BLE_CHAR_2_ID, charId) || UUIDsMatch(&CHIP_BLE_CHAR_3_ID, charId))
710-
{
711-
// Find end point already associated with BLE connection, if any.
712-
BLEEndPoint * endPoint = sBLEEndPointPool.Find(connObj);
713-
714-
if (endPoint != nullptr)
715-
{
716-
endPoint->HandleUnsubscribeComplete();
717-
}
718-
else
719-
{
720-
ChipLogError(Ble, "no endpoint for unsub complete");
721-
}
722-
}
605+
// Find end point already associated with BLE connection, if any.
606+
BLEEndPoint * endPoint = sBLEEndPointPool.Find(connObj);
607+
VerifyOrReturnError(endPoint != nullptr, false, ChipLogDetail(Ble, "No endpoint for unsubscribe complete"));
723608

609+
endPoint->HandleUnsubscribeComplete();
724610
return true;
725611
}
726612

727613
void BleLayer::HandleConnectionError(BLE_CONNECTION_OBJECT connObj, CHIP_ERROR err)
728614
{
729615
// BLE connection has failed somehow, we must find and abort matching connection end point.
730616
BLEEndPoint * endPoint = sBLEEndPointPool.Find(connObj);
617+
VerifyOrReturn(endPoint != nullptr, ChipLogDetail(Ble, "No endpoint for connection error"));
731618

732-
if (endPoint != nullptr)
619+
if (err == BLE_ERROR_GATT_UNSUBSCRIBE_FAILED && endPoint->IsUnsubscribePending())
733620
{
734-
if (err == BLE_ERROR_GATT_UNSUBSCRIBE_FAILED && endPoint->IsUnsubscribePending())
735-
{
736-
// If end point was already closed and just waiting for unsubscribe to complete, free it. Call to Free()
737-
// stops unsubscribe timer.
738-
endPoint->Free();
739-
}
740-
else
741-
{
742-
endPoint->DoClose(kBleCloseFlag_AbortTransmission, err);
743-
}
621+
// If end point was already closed and just waiting for unsubscribe to complete, free it. Call to Free()
622+
// stops unsubscribe timer.
623+
endPoint->Free();
624+
}
625+
else
626+
{
627+
endPoint->DoClose(kBleCloseFlag_AbortTransmission, err);
744628
}
745629
}
746630

src/ble/BleLayer.h

-1
Original file line numberDiff line numberDiff line change
@@ -327,7 +327,6 @@ class DLL_EXPORT BleLayer
327327

328328
// Private functions:
329329
void HandleAckReceived(BLE_CONNECTION_OBJECT connObj);
330-
void DriveSending();
331330
CHIP_ERROR HandleBleTransportConnectionInitiated(BLE_CONNECTION_OBJECT connObj, System::PacketBufferHandle && pBuf);
332331

333332
static BleTransportProtocolVersion GetHighestSupportedProtocolVersion(const BleTransportCapabilitiesRequestMessage & reqMsg);

src/ble/tests/BUILD.gn

+5-1
Original file line numberDiff line numberDiff line change
@@ -22,11 +22,15 @@ chip_test_suite("tests") {
2222

2323
test_sources = [
2424
"TestBleErrorStr.cpp",
25+
"TestBleLayer.cpp",
2526
"TestBleUUID.cpp",
2627
"TestBtpEngine.cpp",
2728
]
2829

2930
cflags = [ "-Wconversion" ]
3031

31-
public_deps = [ "${chip_root}/src/ble" ]
32+
public_deps = [
33+
"${chip_root}/src/ble",
34+
"${chip_root}/src/platform",
35+
]
3236
}

0 commit comments

Comments
 (0)