Skip to content

Commit

Permalink
Making user input to select commissioner for UDC async
Browse files Browse the repository at this point in the history
  • Loading branch information
sharadb-amazon committed Aug 23, 2021
1 parent 409f147 commit 3e591f8
Showing 1 changed file with 65 additions and 34 deletions.
99 changes: 65 additions & 34 deletions examples/tv-casting-app/linux/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -17,26 +17,68 @@
*/

#include <app/server/Mdns.h>
#include <app/server/OnboardingCodesUtil.h>
#include <app/server/Server.h>
#include <controller/CHIPCommissionableNodeController.h>
#include <platform/CHIPDeviceLayer.h>
#include <platform/ConfigurationManager.h>
#include <setup_payload/SetupPayload.h>
#include <system/SystemLayer.h>
#include <transport/raw/PeerAddress.h>

using namespace chip;
using namespace chip::Controller;

#define TV_DEVICE_TYPE 35

chip::Controller::CommissionableNodeController commissionableNodeController;
CommissionableNodeController commissionableNodeController;
chip::System::SocketWatchToken token;

void RequestCommissioning(intptr_t commandArg)
/**
* Enters commissioning mode, opens commissioning window, logs onboarding payload.
* If non-null selectedCommissioner is provided, sends user directed commissioning
* request to the selectedCommissioner and advertises self commissionable node over DNS-SD
*/
void PrepareForCommissioning(const Mdns::DiscoveredNodeData * selectedCommissioner = nullptr)
{
// Enter commissioning mode, open commissioning window
InitServer();
ReturnOnFailure(OpenBasicCommissioningWindow(ResetFabrics::kYes, 3 * 60));

// Display onboarding payload
chip::DeviceLayer::ConfigurationMgr().LogDeviceConfig();

#if CHIP_DEVICE_CONFIG_ENABLE_COMMISSIONER_DISCOVERY_CLIENT
if (selectedCommissioner != nullptr)
{
// Advertise self as Commissionable Node over mDNS
ReturnOnFailure(app::Mdns::AdvertiseCommissionableNode(app::Mdns::CommissioningMode::kEnabledBasic));

// Send User Directed commissioning request
ReturnOnFailure(SendUserDirectedCommissioningRequest(chip::Transport::PeerAddress::UDP(
selectedCommissioner->ipAddress[0], selectedCommissioner->port, selectedCommissioner->interfaceId[0])));
}
#endif // CHIP_DEVICE_CONFIG_ENABLE_COMMISSIONER_DISCOVERY_CLIENT
}

/**
* Accepts user input of selected commissioner and calls PrepareForCommissioning with
* the selected commissioner
*/
void RequestUserDirectedCommisisioning(System::SocketEvents events, intptr_t data)
{
// Accept user selection for commissioner to request commissioning from
int selectedCommissionerNumber = CHIP_DEVICE_CONFIG_MAX_DISCOVERED_NODES;
scanf("%d", &selectedCommissionerNumber);
chip::DeviceLayer::SystemLayer.StopWatchingSocket(&token);

const Mdns::DiscoveredNodeData * selectedCommissioner =
commissionableNodeController.GetDiscoveredCommissioner(selectedCommissionerNumber - 1);
VerifyOrReturn(selectedCommissioner != nullptr, ChipLogError(Zcl, "No such commissioner!"));
PrepareForCommissioning(selectedCommissioner);
}

void InitCommissioningFlow(intptr_t commandArg)
{
int commissionerCount = 0, selectedCommissionerNumber = CHIP_DEVICE_CONFIG_MAX_DISCOVERED_NODES;
chip::SetupPayload payload;
const Mdns::DiscoveredNodeData * selectedCommissioner = nullptr;
int commissionerCount = 0;

// Display discovered commissioner TVs to ask user to select one
for (int i = 0; i < CHIP_DEVICE_CONFIG_MAX_DISCOVERED_NODES; i++)
Expand All @@ -48,38 +90,25 @@ void RequestCommissioning(intptr_t commandArg)
commissioner->LogDetail();
}
}
ChipLogProgress(Zcl, "%d commissioner(s) discovered", commissionerCount);

if (commissionerCount > 0)
{
ChipLogProgress(Zcl, "Choose a commissioner (by number# above) to request commissioning from: ");
scanf("%d", &selectedCommissionerNumber);
selectedCommissioner = commissionableNodeController.GetDiscoveredCommissioner(selectedCommissionerNumber - 1);
VerifyOrReturn(selectedCommissioner != nullptr, ChipLogError(Zcl, "No such commissioner!"));
ChipLogProgress(
Zcl, "%d commissioner(s) discovered. Select one (by number# above) to request commissioning from: ", commissionerCount);

// Setup for async/non-blocking user input from stdin
int flags = fcntl(0, F_GETFL, 0);
VerifyOrReturn(fcntl(0, F_SETFL, flags | O_NONBLOCK) == 0,
ChipLogError(Zcl, "Could not set non-blocking mode for user input!"));
ReturnOnFailure(chip::DeviceLayer::SystemLayer.StartWatchingSocket(0, &token));
ReturnOnFailure(chip::DeviceLayer::SystemLayer.SetCallback(token, RequestUserDirectedCommisisioning, (intptr_t) NULL));
ReturnOnFailure(chip::DeviceLayer::SystemLayer.RequestCallbackOnPendingRead(token));
}
else
{
ChipLogError(Zcl, "No commissioner discovered, commissioning must be initiated manually!");
PrepareForCommissioning();
}

// Enter commissioning mode, open commissioning window
InitServer();
ReturnOnFailure(OpenBasicCommissioningWindow(ResetFabrics::kYes, 3 * 60));

// Display onboarding payload
chip::DeviceLayer::ConfigurationMgr().LogDeviceConfig();

#if CHIP_DEVICE_CONFIG_ENABLE_COMMISSIONER_DISCOVERY_CLIENT
if (selectedCommissioner != nullptr)
{
// Advertise self as Commissionable Node over mDNS
ReturnOnFailure(app::Mdns::AdvertiseCommissionableNode(app::Mdns::CommissioningMode::kEnabledBasic));

// Send User Directed commissioning request
ReturnOnFailure(SendUserDirectedCommissioningRequest(chip::Transport::PeerAddress::UDP(
selectedCommissioner->ipAddress[0], selectedCommissioner->port, selectedCommissioner->interfaceId[0])));
}
#endif // CHIP_DEVICE_CONFIG_ENABLE_COMMISSIONER_DISCOVERY_CLIENT
}

int main(int argc, char * argv[])
Expand All @@ -88,13 +117,15 @@ int main(int argc, char * argv[])
SuccessOrExit(err = chip::Platform::MemoryInit());
SuccessOrExit(err = chip::DeviceLayer::PlatformMgr().InitChipStack());

// Send discover commissioner TVs request
// Send discover commissioners request
SuccessOrExit(err = commissionableNodeController.DiscoverCommissioners(
Mdns::DiscoveryFilter(Mdns::DiscoveryFilterType::kDeviceType, TV_DEVICE_TYPE)));

// Give commissioner TVs some time to respond and then ScheduleWork to get commissioned
// Give commissioners some time to respond and then ScheduleWork to initiate commissioning
DeviceLayer::SystemLayer.StartTimer(
5 * 1000, [](System::Layer *, void *) { chip::DeviceLayer::PlatformMgr().ScheduleWork(RequestCommissioning); }, nullptr);
5 * 1000, [](System::Layer *, void *) { chip::DeviceLayer::PlatformMgr().ScheduleWork(InitCommissioningFlow); }, nullptr);

// TBD: Content casting commands

DeviceLayer::PlatformMgr().RunEventLoop();
exit:
Expand Down

0 comments on commit 3e591f8

Please sign in to comment.