From 9f315e8358ab5786b50e263163d319255b1cef29 Mon Sep 17 00:00:00 2001 From: Shyamal Varma Date: Fri, 13 Sep 2019 16:07:44 -0700 Subject: [PATCH] some more reliability and doc improvements --- pnpbridge/docs/discovery_adapters.md | 7 +- pnpbridge/docs/pnpmessage.md | 3 +- ...environmental_sensor_pnpbridge_discovery.c | 37 +- .../core_device_discovery.c | 4 +- .../src/adapters/src/modbus_pnp/ModbusPnp.c | 4 +- .../src/adapters/src/serial_pnp/serial_pnp.c | 609 +++++++++--------- .../pnpbridge/src/discoveryadapter_manager.c | 4 +- pnpbridge/src/pnpbridge/src/pnpbridge.c | 20 +- pnpbridge/src/pnpbridge/src/pnpmessage.c | 2 +- 9 files changed, 355 insertions(+), 335 deletions(-) diff --git a/pnpbridge/docs/discovery_adapters.md b/pnpbridge/docs/discovery_adapters.md index 8b6fbba..8cf64b5 100644 --- a/pnpbridge/docs/discovery_adapters.md +++ b/pnpbridge/docs/discovery_adapters.md @@ -8,7 +8,7 @@ DISCOVERY_ADAPTER EnvironmentSensorDiscovery = { .StopDiscovery = EnvironmentSensor_StopDiscovery }; -There is only one instance of a discovery adapter create by pnpbridge, which is uniquely identified by .Identity. Here are few of the common properties that apply to the callbacks: +There is only one instance of a discovery adapter created by the Bridge, which is uniquely identified by .Identity. Here are few of the common properties that apply to the callbacks: 1. The StartDiscovery/StopDiscovery are called sequentially for each adapter i.e If there is adapter A and adapter B, B's StartDiscovery will be called after A's is complete. The order is not guaranteed. 2. Failure to initialize any adapter is fatal and will cause pnpbridge start failure. @@ -33,8 +33,7 @@ When a new device is discovered, the adapter should call DiscoveryAdapter_Report **Constructing a PNPMESSAGE** -A PNPMESSAGE is a device discovery message that a discovery adapter will report using the DiscoveryAdapter_ReportDevice API. This message is backed by the PNPMEMORY. When the DiscoveryAdapter_ReportDevice returns, the adapter should release reference -on the PNPMESSAGE. +A PNPMESSAGE is a device discovery message that a discovery adapter will report to the Bridge using the DiscoveryAdapter_ReportDevice. The discovery adapter should use PnpMessage_CreateMessage to allocate this message followed by PnpMessage_SetMessage to set the message payload. This message is backed by the PNPMEMORY. When the DiscoveryAdapter_ReportDevice returns, the adapter should release reference on the PNPMESSAGE. **Per-Device DiscoveryAdapter Parameters** @@ -42,7 +41,7 @@ Every device can provide discovery adapter specific parameters. This could be fo **DiscoveryAdapter Parameters** -There is a per discovery adapter wide parameters that can be specified under root/discovery_adapters/parameters in the json config. The unique identifier is identity and there should be only one instance per adapter identity. +There are discovery adapter wide parameters that can be specified under root/discovery_adapters/parameters in the json config. The unique identifier is identity and there should be only one instance of this per adapter identity. { "identity": "environment-sensor-sample-discovery-adapter", diff --git a/pnpbridge/docs/pnpmessage.md b/pnpbridge/docs/pnpmessage.md index 178fa24..be73bdc 100644 --- a/pnpbridge/docs/pnpmessage.md +++ b/pnpbridge/docs/pnpmessage.md @@ -1,6 +1,7 @@ # PnpMessage -A pnpmessage is packet sent from a discovery adapter to pnpbridge to notify a device arrival or removal. +A PNPMESSAGE is a device discovery message that a discovery adapter will report to the Bridge using the DiscoveryAdapter_ReportDevice. +The discovery adapter should use PnpMessage_CreateMessage to allocate this message followed by PnpMessage_SetMessage to set the message payload. Charactersitics of PnpMessage diff --git a/pnpbridge/src/adapters/samples/environmental_sensor/environmental_sensor_pnpbridge_discovery.c b/pnpbridge/src/adapters/samples/environmental_sensor/environmental_sensor_pnpbridge_discovery.c index 8c3cb55..2d0b000 100644 --- a/pnpbridge/src/adapters/samples/environmental_sensor/environmental_sensor_pnpbridge_discovery.c +++ b/pnpbridge/src/adapters/samples/environmental_sensor/environmental_sensor_pnpbridge_discovery.c @@ -26,20 +26,36 @@ ENVIRONMENTSENSOR_DISCOVERY EnvironmentSensor_Context = { 0 }; // being called. int EnvironmentSensor_DiscoveryWorker(void* context) { ENVIRONMENTSENSOR_DISCOVERY* envContext = context; + PDEVICE_ADAPTER_PARMAETERS deviceArgs; + char* str; + JSON_Value* jdeviceArgsValue; - // Parse the discovery parameters from the pnpbridge config and publish the device discovery notification - PDEVICE_ADAPTER_PARMAETERS deviceArgs = PnpMemory_GetBuffer(envContext->DeviceArgs, NULL); - char* str = deviceArgs->AdapterParameters[0]; - JSON_Value* jdeviceArgsValue = json_parse_string(str); + if (NULL == envContext->DeviceArgs) { + LogInfo("EnvironmentSensor_DiscoveryWorker: No device discovery parameters found in configuration."); + return 0; + } + // The discovery adapter will parse the discovery parameters from the Bridge's + // configuration and report discovered devices to the bridge using + // DiscoveryAdapter_ReportDevice + deviceArgs = PnpMemory_GetBuffer(envContext->DeviceArgs, NULL); + + LogInfo("EnvironmentSensor_DiscoveryWorker: Found configuration parameters for %d devices", deviceArgs->Count); + + // This discovery adapter examines the parameters reported for the first device at AdapterParameters[0] + // It obtains the "sensor_id" parameter and reports a fake device to the bridge using + // DiscoveryAdapter_ReportDevice + str = deviceArgs->AdapterParameters[0]; + + jdeviceArgsValue = json_parse_string(str); if (NULL == jdeviceArgsValue) { - LogError("EnvironmentSensor_DiscoveryWorker: json_parse_string failed"); + LogError("EnvironmentSensor_DiscoveryWorker: json_parse_string failed. Invalid discovery parameters"); return -1; } JSON_Object* jDeviceArgObject = json_value_get_object(jdeviceArgsValue); if (NULL == jDeviceArgObject) { - LogError("EnvironmentSensor_DiscoveryWorker: json_value_get_object failed"); + LogError("EnvironmentSensor_DiscoveryWorker: json_value_get_object failed. Invalid discovery parameters"); return -1; } @@ -48,11 +64,11 @@ int EnvironmentSensor_DiscoveryWorker(void* context) { // Device change format const char* deviceChangeMessageformat = "{ \ - \"identity\": \"environment-sensor-sample-discovery-adapter\", \ - \"match_parameters\": { \ - \"sensor_id\": \"%s\" \ + \"identity\": \"environment-sensor-sample-discovery-adapter\", \ + \"match_parameters\": { \ + \"sensor_id\": \"%s\" \ } \ - }"; + }"; // Create the device change PnP notification message PNPMESSAGE msg = NULL; @@ -66,6 +82,7 @@ int EnvironmentSensor_DiscoveryWorker(void* context) { PnpMessage_SetMessage(msg, deviceChangeBuff); // Notify the pnpbridge of device discovery + LogInfo("EnvironmentSensor_DiscoveryWorker: Reporting sensor ID %s to bridge", sensorId); DiscoveryAdapter_ReportDevice(msg); free(deviceChangeBuff); diff --git a/pnpbridge/src/adapters/src/core_device_health/core_device_discovery.c b/pnpbridge/src/adapters/src/core_device_health/core_device_discovery.c index a56dfd7..b983b5b 100644 --- a/pnpbridge/src/adapters/src/core_device_health/core_device_discovery.c +++ b/pnpbridge/src/adapters/src/core_device_health/core_device_discovery.c @@ -206,8 +206,8 @@ CoreDevice_StartDiscovery( UNREFERENCED_PARAMETER(DeviceArgs); if (NULL == AdapterArgs) { - LogError("Missing adapter parameters"); - return -1; + LogError("CoreDevice_StartDiscovery: No adapter parameters specified for device discovery"); + return 0; } g_CoreDeviceDiscovery_DeviceWatchers = singlylinkedlist_create(); diff --git a/pnpbridge/src/adapters/src/modbus_pnp/ModbusPnp.c b/pnpbridge/src/adapters/src/modbus_pnp/ModbusPnp.c index e5c0a74..34367a2 100644 --- a/pnpbridge/src/adapters/src/modbus_pnp/ModbusPnp.c +++ b/pnpbridge/src/adapters/src/modbus_pnp/ModbusPnp.c @@ -685,8 +685,10 @@ ModbusPnp_StartDiscovery( ) { if (DeviceArgs == NULL) { - return -1; + LogInfo("ModbusPnp_StartDiscovery: No device discovery parameters found in configuration."); + return 0; } + UNREFERENCED_PARAMETER(AdapterArgs); LogInfo("Starting modbus discovery adapter"); diff --git a/pnpbridge/src/adapters/src/serial_pnp/serial_pnp.c b/pnpbridge/src/adapters/src/serial_pnp/serial_pnp.c index 5362610..dbc91d3 100644 --- a/pnpbridge/src/adapters/src/serial_pnp/serial_pnp.c +++ b/pnpbridge/src/adapters/src/serial_pnp/serial_pnp.c @@ -1,64 +1,64 @@ -// Copyright (c) Microsoft. All rights reserved. -// Licensed under the MIT license. See LICENSE file in the project root for full license information. - -#include - -#include "azure_c_shared_utility/azure_base32.h" -#include "azure_c_shared_utility/gballoc.h" -#include "azure_c_shared_utility/xlogging.h" -#include "azure_c_shared_utility/threadapi.h" -#include "azure_c_shared_utility/singlylinkedlist.h" -#include "azure_c_shared_utility/lock.h" - -// TODO: Fix this missing reference -#ifndef AZURE_UNREFERENCED_PARAMETER -#define AZURE_UNREFERENCED_PARAMETER(param) (void)(param) -#endif - -#ifdef WIN32 -#include -#include -#include -#include -#else -typedef unsigned int DWORD; -typedef uint8_t byte; -typedef int HANDLE; -typedef short USHORT; -typedef uint16_t UINT16; - -#include -#include -#include - -#include -#include -#endif - -#include "parson.h" - -#include "serial_pnp.h" - -int SerialPnp_UartReceiver(void* context) -{ - int result = 0; - PSERIAL_DEVICE_CONTEXT deviceContext = (PSERIAL_DEVICE_CONTEXT)context; - - while (result >= 0) { - byte* desc = NULL; - DWORD length; - - SerialPnp_RxPacket(deviceContext, &desc, &length, 0x00); - if (desc != NULL) - { - SerialPnp_UnsolicitedPacket(deviceContext, desc, length); - free(desc); - } - } - - return 0; -} - +// Copyright (c) Microsoft. All rights reserved. +// Licensed under the MIT license. See LICENSE file in the project root for full license information. + +#include + +#include "azure_c_shared_utility/azure_base32.h" +#include "azure_c_shared_utility/gballoc.h" +#include "azure_c_shared_utility/xlogging.h" +#include "azure_c_shared_utility/threadapi.h" +#include "azure_c_shared_utility/singlylinkedlist.h" +#include "azure_c_shared_utility/lock.h" + +// TODO: Fix this missing reference +#ifndef AZURE_UNREFERENCED_PARAMETER +#define AZURE_UNREFERENCED_PARAMETER(param) (void)(param) +#endif + +#ifdef WIN32 +#include +#include +#include +#include +#else +typedef unsigned int DWORD; +typedef uint8_t byte; +typedef int HANDLE; +typedef short USHORT; +typedef uint16_t UINT16; + +#include +#include +#include + +#include +#include +#endif + +#include "parson.h" + +#include "serial_pnp.h" + +int SerialPnp_UartReceiver(void* context) +{ + int result = 0; + PSERIAL_DEVICE_CONTEXT deviceContext = (PSERIAL_DEVICE_CONTEXT)context; + + while (result >= 0) { + byte* desc = NULL; + DWORD length; + + SerialPnp_RxPacket(deviceContext, &desc, &length, 0x00); + if (desc != NULL) + { + SerialPnp_UnsolicitedPacket(deviceContext, desc, length); + free(desc); + } + } + + return 0; +} + int SerialPnp_TxPacket(PSERIAL_DEVICE_CONTEXT serialDevice, byte* OutPacket, int Length) { DWORD write_size = 0; @@ -133,8 +133,8 @@ int SerialPnp_TxPacket(PSERIAL_DEVICE_CONTEXT serialDevice, byte* OutPacket, int } free(SerialPnp_TxPacket); return 0; - } - + } + const EventDefinition* SerialPnp_LookupEvent(SINGLYLINKEDLIST_HANDLE interfaceDefinitions, char* EventName, int InterfaceId) { const InterfaceDefinition* interfaceDef; @@ -164,8 +164,8 @@ const EventDefinition* SerialPnp_LookupEvent(SINGLYLINKEDLIST_HANDLE interfaceDe } return NULL; -} - +} + byte* SerialPnp_StringSchemaToBinary(Schema schema, byte* buffer, int* length) { byte* bd = NULL; @@ -225,8 +225,8 @@ byte* SerialPnp_StringSchemaToBinary(Schema schema, byte* buffer, int* length) } return bd; -} - +} + char* SerialPnp_BinarySchemaToString(Schema schema, byte* Data, byte length) { const int MAXRXSTRLEN = 12; // longest case INT_MIN = -2147483648 (11 characters + 1) @@ -257,8 +257,8 @@ char* SerialPnp_BinarySchemaToString(Schema schema, byte* Data, byte length) } return rxstrdata; -} - +} + void SerialPnp_UnsolicitedPacket(PSERIAL_DEVICE_CONTEXT device, byte* packet, DWORD length) { // Got an event @@ -315,8 +315,8 @@ void SerialPnp_UnsolicitedPacket(PSERIAL_DEVICE_CONTEXT device, byte* packet, DW { // TODO } -} - +} + const PropertyDefinition* SerialPnp_LookupProperty(SINGLYLINKEDLIST_HANDLE interfaceDefinitions, const char* propertyName, int InterfaceId) { LIST_ITEM_HANDLE interfaceDefHandle = singlylinkedlist_get_head_item(interfaceDefinitions); @@ -350,8 +350,8 @@ const PropertyDefinition* SerialPnp_LookupProperty(SINGLYLINKEDLIST_HANDLE inter } return NULL; -} - +} + const CommandDefinition* SerialPnp_LookupCommand(SINGLYLINKEDLIST_HANDLE interfaceDefinitions, const char* commandName, int InterfaceId) { LIST_ITEM_HANDLE interfaceDefHandle = singlylinkedlist_get_head_item(interfaceDefinitions); @@ -381,8 +381,8 @@ const CommandDefinition* SerialPnp_LookupCommand(SINGLYLINKEDLIST_HANDLE interfa } return NULL; -} - +} + int SerialPnp_PropertyHandler(PSERIAL_DEVICE_CONTEXT serialDevice, const char* property, char* data) { const PropertyDefinition* prop = SerialPnp_LookupProperty(serialDevice->InterfaceDefinitions, property, 0); @@ -429,8 +429,8 @@ int SerialPnp_PropertyHandler(PSERIAL_DEVICE_CONTEXT serialDevice, const char* p free(txPacket); return 0; -} - +} + int SerialPnp_CommandHandler(PSERIAL_DEVICE_CONTEXT serialDevice, const char* command, char* data, char** response) { Lock(serialDevice->CommandLock); @@ -514,8 +514,8 @@ int SerialPnp_CommandHandler(PSERIAL_DEVICE_CONTEXT serialDevice, const char* co *response = stval; Unlock(serialDevice->CommandLock); return 0; -} - +} + void SerialPnp_ParseDescriptor(SINGLYLINKEDLIST_HANDLE interfaceDefinitions, byte* descriptor, DWORD length) { int c = 4; @@ -745,17 +745,17 @@ void SerialPnp_ParseDescriptor(SINGLYLINKEDLIST_HANDLE interfaceDefinitions, byt LogError("Unsupported descriptor\n"); } } -} - -typedef struct _SERIAL_DEVICE -{ - char* InterfaceName; -} SERIAL_DEVICE, *PSERIAL_DEVICE; - -SINGLYLINKEDLIST_HANDLE SerialDeviceList = NULL; -int SerialDeviceCount = 0; - -#ifdef WIN32 +} + +typedef struct _SERIAL_DEVICE +{ + char* InterfaceName; +} SERIAL_DEVICE, *PSERIAL_DEVICE; + +SINGLYLINKEDLIST_HANDLE SerialDeviceList = NULL; +int SerialDeviceCount = 0; + +#ifdef WIN32 int SerialPnp_FindSerialDevices() { CONFIGRET cmResult = CR_SUCCESS; @@ -817,13 +817,13 @@ int SerialPnp_FindSerialDevices() } return 0; -} -#endif - -const char* serialDeviceChangeMessageformat = "{ \ - \"identity\": \"serial-pnp-discovery\" \ - }"; - +} +#endif + +const char* serialDeviceChangeMessageformat = "{ \ + \"identity\": \"serial-pnp-discovery\" \ + }"; + int SerialPnp_OpenDeviceWorker(void* context) { byte* desc; @@ -885,9 +885,9 @@ int SerialPnp_OpenDeviceWorker(void* context) SerialPnp_UartReceiver(deviceContext); return 0; -} - -#ifndef WIN32 +} + +#ifndef WIN32 int set_interface_attribs(int fd, int speed, int parity) { struct termios tty; @@ -944,9 +944,9 @@ set_blocking(int fd, int should_block) if (tcsetattr(fd, TCSANOW, &tty) != 0) LogError("error %d setting term attributes", errno); -} -#endif - +} +#endif + int SerialPnp_OpenDevice(const char* port, DWORD baudRate) { #ifdef WIN32 @@ -1074,8 +1074,8 @@ int SerialPnp_OpenDevice(const char* port, DWORD baudRate) } return 0; -} - +} + int SerialPnp_RxPacket(PSERIAL_DEVICE_CONTEXT serialDevice, byte** receivedPacket, DWORD* length, char packetType) { byte inb = 0; @@ -1183,8 +1183,8 @@ int SerialPnp_RxPacket(PSERIAL_DEVICE_CONTEXT serialDevice, byte** receivedPacke } } return 0; -} - +} + int SerialPnp_ResetDevice(PSERIAL_DEVICE_CONTEXT serialDevice) { int error = 0; @@ -1228,8 +1228,8 @@ int SerialPnp_ResetDevice(PSERIAL_DEVICE_CONTEXT serialDevice) } free(responsePacket); return error; -} - +} + int SerialPnp_DeviceDescriptorRequest(PSERIAL_DEVICE_CONTEXT serialDevice, byte** desc, DWORD* length) { // Prepare packet @@ -1270,17 +1270,18 @@ int SerialPnp_DeviceDescriptorRequest(PSERIAL_DEVICE_CONTEXT serialDevice, byte* LogInfo("Receieved descriptor response, of length %d", *length); return 0; -} - -int -SerialPnp_StartDiscovery( - _In_ PNPMEMORY deviceArgs, - _In_ PNPMEMORY adapterArgs - ) -{ +} + +int +SerialPnp_StartDiscovery( + _In_ PNPMEMORY deviceArgs, + _In_ PNPMEMORY adapterArgs + ) +{ if (NULL == deviceArgs) { - return -1; + LogInfo("SerialPnp_StartDiscovery: No device discovery parameters found in configuration."); + return 0; } AZURE_UNREFERENCED_PARAMETER(adapterArgs); @@ -1342,18 +1343,18 @@ SerialPnp_StartDiscovery( SerialPnp_OpenDevice(useComDeviceInterface ? seriaDevice->InterfaceName : port, baudRate); return 0; -} - -int SerialPnp_StopDiscovery() -{ - return 0; -} - -void SerialPnp_SendEventCallback(DIGITALTWIN_CLIENT_RESULT pnpSendEventStatus, void* userContextCallback) -{ - LogInfo("SerialDataSendEventCallback called, result=%d, userContextCallback=%p", pnpSendEventStatus, userContextCallback); -} - +} + +int SerialPnp_StopDiscovery() +{ + return 0; +} + +void SerialPnp_SendEventCallback(DIGITALTWIN_CLIENT_RESULT pnpSendEventStatus, void* userContextCallback) +{ + LogInfo("SerialDataSendEventCallback called, result=%d, userContextCallback=%p", pnpSendEventStatus, userContextCallback); +} + int SerialPnp_SendEventAsync(DIGITALTWIN_INTERFACE_CLIENT_HANDLE pnpInterface, char* eventName, char* data) { int result; @@ -1375,8 +1376,8 @@ int SerialPnp_SendEventAsync(DIGITALTWIN_INTERFACE_CLIENT_HANDLE pnpInterface, c } return result; -} - +} + static void SerialPnp_PropertyUpdateHandler(const DIGITALTWIN_CLIENT_PROPERTY_UPDATE* dtClientPropertyUpdate, void* userContextCallback) { DIGITALTWIN_CLIENT_RESULT pnpClientResult; @@ -1401,8 +1402,8 @@ static void SerialPnp_PropertyUpdateHandler(const DIGITALTWIN_CLIENT_PROPERTY_UP pnpClientResult = DigitalTwin_InterfaceClient_ReportPropertyAsync( PnpAdapterInterface_GetPnpInterfaceClient(deviceContext->pnpAdapterInterface), dtClientPropertyUpdate->propertyName, (const char*)dtClientPropertyUpdate->propertyDesired, &propertyResponse, NULL, NULL); -} - +} + // PnPSampleEnvironmentalSensor_SetCommandResponse is a helper that fills out a PNP_CLIENT_COMMAND_RESPONSE static void SerialPnp_SetCommandResponse(DIGITALTWIN_CLIENT_COMMAND_RESPONSE* pnpClientCommandResponseContext, const char* responseData, int status) { @@ -1424,26 +1425,26 @@ static void SerialPnp_SetCommandResponse(DIGITALTWIN_CLIENT_COMMAND_RESPONSE* pn pnpClientCommandResponseContext->responseDataLen = responseLen; pnpClientCommandResponseContext->status = status; } -} - -void -SerialPnp_CommandUpdateHandler( - const DIGITALTWIN_CLIENT_COMMAND_REQUEST* dtClientCommandContext, - DIGITALTWIN_CLIENT_COMMAND_RESPONSE* dtClientCommandResponseContext, - void* userContextCallback - ) -{ - PSERIAL_DEVICE_CONTEXT deviceContext; - - // LogInfo("Processed command frequency property updated. propertyUpdated = %.*s", (int)propertyDataUpdatedLen, propertyDataUpdated); - - deviceContext = (PSERIAL_DEVICE_CONTEXT)userContextCallback; - - char* response = NULL; - SerialPnp_CommandHandler(deviceContext, dtClientCommandContext->commandName, (char*)dtClientCommandContext->requestData, &response); - SerialPnp_SetCommandResponse(dtClientCommandResponseContext, response, 200); -} - +} + +void +SerialPnp_CommandUpdateHandler( + const DIGITALTWIN_CLIENT_COMMAND_REQUEST* dtClientCommandContext, + DIGITALTWIN_CLIENT_COMMAND_RESPONSE* dtClientCommandResponseContext, + void* userContextCallback + ) +{ + PSERIAL_DEVICE_CONTEXT deviceContext; + + // LogInfo("Processed command frequency property updated. propertyUpdated = %.*s", (int)propertyDataUpdatedLen, propertyDataUpdated); + + deviceContext = (PSERIAL_DEVICE_CONTEXT)userContextCallback; + + char* response = NULL; + SerialPnp_CommandHandler(deviceContext, dtClientCommandContext->commandName, (char*)dtClientCommandContext->requestData, &response); + SerialPnp_SetCommandResponse(dtClientCommandResponseContext, response, 200); +} + const InterfaceDefinition* SerialPnp_GetInterface(PSERIAL_DEVICE_CONTEXT deviceContext, const char* interfaceId) { LIST_ITEM_HANDLE interfaceDefHandle = singlylinkedlist_get_head_item(deviceContext->InterfaceDefinitions); @@ -1457,8 +1458,8 @@ const InterfaceDefinition* SerialPnp_GetInterface(PSERIAL_DEVICE_CONTEXT deviceC interfaceDefHandle = singlylinkedlist_get_next_item(interfaceDefHandle); } return NULL; -} - +} + int SerialPnp_GetListCount(SINGLYLINKEDLIST_HANDLE list) { if (NULL == list) @@ -1474,122 +1475,122 @@ int SerialPnp_GetListCount(SINGLYLINKEDLIST_HANDLE list) item = singlylinkedlist_get_next_item(item); } return count; -} - -int -SerialPnp_StartPnpInterface( - _In_ PNPADAPTER_INTERFACE_HANDLE PnpInterface - ) -{ - AZURE_UNREFERENCED_PARAMETER(PnpInterface); - return 0; -} - -int SerialPnp_CreatePnpInterface(PNPADAPTER_CONTEXT AdapterHandle, PNPMESSAGE msg) -{ - PNPMESSAGE_PROPERTIES* pnpMsgProps = NULL; - pnpMsgProps = PnpMessage_AccessProperties(msg); - PSERIAL_DEVICE_CONTEXT deviceContext = (PSERIAL_DEVICE_CONTEXT)pnpMsgProps->Context; - const char* interfaceId = PnpMessage_GetInterfaceId(msg); - int result = 0; - - // Create an Azure Pnp interface for each interface in the SerialPnp descriptor - LIST_ITEM_HANDLE interfaceDefHandle = singlylinkedlist_get_head_item(deviceContext->InterfaceDefinitions); - while (interfaceDefHandle != NULL) - { - PNPADAPTER_INTERFACE_HANDLE pnpAdapterInterface = NULL; - DIGITALTWIN_INTERFACE_CLIENT_HANDLE pnpInterfaceClient = NULL; - int propertyCount = 0; - int commandCount = 0; - const InterfaceDefinition* interfaceDef = singlylinkedlist_item_get_value(interfaceDefHandle); - - propertyCount = SerialPnp_GetListCount(interfaceDef->Properties); - commandCount = SerialPnp_GetListCount(interfaceDef->Commands); - - DIGITALTWIN_CLIENT_RESULT dtRes; - //PNPMESSAGE_PROPERTIES* props = PnpMessage_AccessProperties(msg); - dtRes = DigitalTwin_InterfaceClient_Create(interfaceId, - "serial" /* props->ComponentName */, // TODO: add component name into serial interface definition - NULL, - deviceContext, - &pnpInterfaceClient); - if (DIGITALTWIN_CLIENT_OK != dtRes) - { - result = -1; - goto exit; - } - - if (propertyCount > 0) { - dtRes = DigitalTwin_InterfaceClient_SetPropertiesUpdatedCallback(pnpInterfaceClient, - SerialPnp_PropertyUpdateHandler); - if (DIGITALTWIN_CLIENT_OK != dtRes) - { - result = -1; - goto exit; - } - } - - if (commandCount > 0) { - dtRes = DigitalTwin_InterfaceClient_SetCommandsCallback(pnpInterfaceClient, - SerialPnp_CommandUpdateHandler); - if (DIGITALTWIN_CLIENT_OK != dtRes) - { - result = -1; - goto exit; - } - } - - // Create PnpAdapter Interface - { - PNPADPATER_INTERFACE_PARAMS interfaceParams = { 0 }; - PNPADPATER_INTERFACE_PARAMS_INIT(&interfaceParams, AdapterHandle, pnpInterfaceClient); - interfaceParams.InterfaceId = (char*)interfaceId; - interfaceParams.ReleaseInterface = SerialPnp_ReleasePnpInterface; - interfaceParams.StartInterface = SerialPnp_StartPnpInterface; - - result = PnpAdapterInterface_Create(&interfaceParams, &pnpAdapterInterface); - if (result < 0) - { - goto exit; - } - } - - // Save the PnpAdapterInterface in device context - deviceContext->pnpAdapterInterface = pnpAdapterInterface; - - interfaceDefHandle = singlylinkedlist_get_next_item(interfaceDefHandle); - } - -exit: - - // Cleanup incase of failure - if (result < 0) { - // Destroy PnpInterfaceClient - //if (NULL != pnpInterfaceClient) { - //PnP_InterfaceClient_Destroy(pnpInterfaceClient); - //} - } - - return 0; -} - -void SerialPnp_FreeFieldDefinition(FieldDefinition* fdef) { - if (NULL != fdef->Description) - { - free(fdef->Description); - } - - if (NULL != fdef->DisplayName) - { - free(fdef->DisplayName); - } - - if (NULL != fdef->Name) - { - free(fdef->Name); - } -} - +} + +int +SerialPnp_StartPnpInterface( + _In_ PNPADAPTER_INTERFACE_HANDLE PnpInterface + ) +{ + AZURE_UNREFERENCED_PARAMETER(PnpInterface); + return 0; +} + +int SerialPnp_CreatePnpInterface(PNPADAPTER_CONTEXT AdapterHandle, PNPMESSAGE msg) +{ + PNPMESSAGE_PROPERTIES* pnpMsgProps = NULL; + pnpMsgProps = PnpMessage_AccessProperties(msg); + PSERIAL_DEVICE_CONTEXT deviceContext = (PSERIAL_DEVICE_CONTEXT)pnpMsgProps->Context; + const char* interfaceId = PnpMessage_GetInterfaceId(msg); + int result = 0; + + // Create an Azure Pnp interface for each interface in the SerialPnp descriptor + LIST_ITEM_HANDLE interfaceDefHandle = singlylinkedlist_get_head_item(deviceContext->InterfaceDefinitions); + while (interfaceDefHandle != NULL) + { + PNPADAPTER_INTERFACE_HANDLE pnpAdapterInterface = NULL; + DIGITALTWIN_INTERFACE_CLIENT_HANDLE pnpInterfaceClient = NULL; + int propertyCount = 0; + int commandCount = 0; + const InterfaceDefinition* interfaceDef = singlylinkedlist_item_get_value(interfaceDefHandle); + + propertyCount = SerialPnp_GetListCount(interfaceDef->Properties); + commandCount = SerialPnp_GetListCount(interfaceDef->Commands); + + DIGITALTWIN_CLIENT_RESULT dtRes; + //PNPMESSAGE_PROPERTIES* props = PnpMessage_AccessProperties(msg); + dtRes = DigitalTwin_InterfaceClient_Create(interfaceId, + "serial" /* props->ComponentName */, // TODO: add component name into serial interface definition + NULL, + deviceContext, + &pnpInterfaceClient); + if (DIGITALTWIN_CLIENT_OK != dtRes) + { + result = -1; + goto exit; + } + + if (propertyCount > 0) { + dtRes = DigitalTwin_InterfaceClient_SetPropertiesUpdatedCallback(pnpInterfaceClient, + SerialPnp_PropertyUpdateHandler); + if (DIGITALTWIN_CLIENT_OK != dtRes) + { + result = -1; + goto exit; + } + } + + if (commandCount > 0) { + dtRes = DigitalTwin_InterfaceClient_SetCommandsCallback(pnpInterfaceClient, + SerialPnp_CommandUpdateHandler); + if (DIGITALTWIN_CLIENT_OK != dtRes) + { + result = -1; + goto exit; + } + } + + // Create PnpAdapter Interface + { + PNPADPATER_INTERFACE_PARAMS interfaceParams = { 0 }; + PNPADPATER_INTERFACE_PARAMS_INIT(&interfaceParams, AdapterHandle, pnpInterfaceClient); + interfaceParams.InterfaceId = (char*)interfaceId; + interfaceParams.ReleaseInterface = SerialPnp_ReleasePnpInterface; + interfaceParams.StartInterface = SerialPnp_StartPnpInterface; + + result = PnpAdapterInterface_Create(&interfaceParams, &pnpAdapterInterface); + if (result < 0) + { + goto exit; + } + } + + // Save the PnpAdapterInterface in device context + deviceContext->pnpAdapterInterface = pnpAdapterInterface; + + interfaceDefHandle = singlylinkedlist_get_next_item(interfaceDefHandle); + } + +exit: + + // Cleanup incase of failure + if (result < 0) { + // Destroy PnpInterfaceClient + //if (NULL != pnpInterfaceClient) { + //PnP_InterfaceClient_Destroy(pnpInterfaceClient); + //} + } + + return 0; +} + +void SerialPnp_FreeFieldDefinition(FieldDefinition* fdef) { + if (NULL != fdef->Description) + { + free(fdef->Description); + } + + if (NULL != fdef->DisplayName) + { + free(fdef->DisplayName); + } + + if (NULL != fdef->Name) + { + free(fdef->Name); + } +} + void SerialPnp_FreeEventDefinition(SINGLYLINKEDLIST_HANDLE events) { if (NULL == events) @@ -1609,8 +1610,8 @@ void SerialPnp_FreeEventDefinition(SINGLYLINKEDLIST_HANDLE events) free(e); eventItem = singlylinkedlist_get_next_item(eventItem); } -} - +} + void SerialPnp_FreeCommandDefinition(SINGLYLINKEDLIST_HANDLE cmds) { if (NULL == cmds) @@ -1626,8 +1627,8 @@ void SerialPnp_FreeCommandDefinition(SINGLYLINKEDLIST_HANDLE cmds) free(c); cmdItem = singlylinkedlist_get_next_item(cmdItem); } -} - +} + void SerialPnp_FreePropertiesDefinition(SINGLYLINKEDLIST_HANDLE props) { if (NULL == props) @@ -1647,8 +1648,8 @@ void SerialPnp_FreePropertiesDefinition(SINGLYLINKEDLIST_HANDLE props) free(p); propItem = singlylinkedlist_get_next_item(propItem); } -} - +} + int SerialPnp_ReleasePnpInterface(PNPADAPTER_INTERFACE_HANDLE pnpInterface) { PSERIAL_DEVICE_CONTEXT deviceContext = PnpAdapterInterface_GetContext(pnpInterface); @@ -1701,29 +1702,29 @@ int SerialPnp_ReleasePnpInterface(PNPADAPTER_INTERFACE_HANDLE pnpInterface) free(deviceContext); return 0; -} - -int SerialPnp_Initialize(const char* adapterArgs) -{ - AZURE_UNREFERENCED_PARAMETER(adapterArgs); - return 0; -} - -int SerialPnp_Shutdown() -{ - return 0; -} - -DISCOVERY_ADAPTER SerialPnpDiscovery = { - .Identity = "serial-pnp-discovery", - .StartDiscovery = SerialPnp_StartDiscovery, - .StopDiscovery = SerialPnp_StopDiscovery -}; - -PNP_ADAPTER SerialPnpInterface = { - .identity = "serial-pnp-interface", - .initialize = SerialPnp_Initialize, - .shutdown = SerialPnp_Shutdown, - .createPnpInterface = SerialPnp_CreatePnpInterface -}; - +} + +int SerialPnp_Initialize(const char* adapterArgs) +{ + AZURE_UNREFERENCED_PARAMETER(adapterArgs); + return 0; +} + +int SerialPnp_Shutdown() +{ + return 0; +} + +DISCOVERY_ADAPTER SerialPnpDiscovery = { + .Identity = "serial-pnp-discovery", + .StartDiscovery = SerialPnp_StartDiscovery, + .StopDiscovery = SerialPnp_StopDiscovery +}; + +PNP_ADAPTER SerialPnpInterface = { + .identity = "serial-pnp-interface", + .initialize = SerialPnp_Initialize, + .shutdown = SerialPnp_Shutdown, + .createPnpInterface = SerialPnp_CreatePnpInterface +}; + diff --git a/pnpbridge/src/pnpbridge/src/discoveryadapter_manager.c b/pnpbridge/src/pnpbridge/src/discoveryadapter_manager.c index 1f7f0a9..ca967a1 100644 --- a/pnpbridge/src/pnpbridge/src/discoveryadapter_manager.c +++ b/pnpbridge/src/pnpbridge/src/discoveryadapter_manager.c @@ -60,7 +60,7 @@ PNPBRIDGE_RESULT DiscoveryAdapterManager_Create(PDISCOVERY_MANAGER* discoveryMan } PNPBRIDGE_RESULT -DiscoveryManager_StarDiscoveryAdapter( +DiscoveryManager_StartDiscoveryAdapter( PDISCOVERY_MANAGER discoveryManager, PDISCOVERY_ADAPTER discoveryInterface, SINGLYLINKEDLIST_HANDLE DeviceAdapterParamsList, @@ -249,7 +249,7 @@ PNPBRIDGE_RESULT DiscoveryAdapterManager_Start(PDISCOVERY_MANAGER DiscoveryManag JSON_Object* adapterParams = NULL; adapterParams = Configuration_GetDiscoveryParameters(Config->JsonConfig, discoveryInterface->Identity); - result = DiscoveryManager_StarDiscoveryAdapter(DiscoveryManager, discoveryInterface, + result = DiscoveryManager_StartDiscoveryAdapter(DiscoveryManager, discoveryInterface, deviceParamsList, deviceParamsCount, adapterParams, i); if (PNPBRIDGE_OK != result) { LEAVE; diff --git a/pnpbridge/src/pnpbridge/src/pnpbridge.c b/pnpbridge/src/pnpbridge/src/pnpbridge.c index 395482e..40c9553 100644 --- a/pnpbridge/src/pnpbridge/src/pnpbridge.c +++ b/pnpbridge/src/pnpbridge/src/pnpbridge.c @@ -224,20 +224,20 @@ PnpBridge_ProcessPnpMessage( jmsg = json_parse_string(msg->Message); if (NULL == jmsg) { - LogError("PNPMESSAGE payload is not a valid json"); + LogError("PNPMESSAGE reported by discovery adapter is not valid."); result = PNPBRIDGE_INVALID_ARGS; LEAVE; } jobj = json_value_get_object(jmsg); if (NULL == jobj) { - LogError("PNPMESSAGE payload is not a valid json"); + LogError("PNPMESSAGE payload reported by discovery adapter is not valid."); result = PNPBRIDGE_INVALID_ARGS; LEAVE; } if (PNPBRIDGE_OK != Configuration_IsDeviceConfigured(pnpBridge->Configuration.JsonConfig, jobj, &jdevice)) { - LogInfo("Device is not configured. Dropping the change notification"); + LogInfo("Dropping the change notification reported by a discovery adapter"); result = PNPBRIDGE_INVALID_ARGS; LEAVE; } @@ -261,7 +261,7 @@ PnpBridge_ProcessPnpMessage( if (NULL != selfDescribing && 0 == strcmp(selfDescribing, "true")) { interfaceId = msg->InterfaceId; if (NULL == interfaceId) { - LogError("Interface id is missing for self descrbing device"); + LogError("Interface id is missing for self describing device"); result = PNPBRIDGE_INVALID_ARGS; LEAVE; } @@ -269,14 +269,14 @@ PnpBridge_ProcessPnpMessage( else { interfaceId = (char*)json_object_get_string(jdevice, PNP_CONFIG_INTERFACE_ID); if (NULL == interfaceId) { - LogError("Interface Id is missing in config for the device"); + LogError(PNP_CONFIG_INTERFACE_ID " is missing in config for the device"); result = PNPBRIDGE_INVALID_ARGS; LEAVE; } componentName = (char*)json_object_get_string(jdevice, PNP_CONFIG_COMPONENT_NAME); - if (NULL == interfaceId) { - LogError("Interface Id is missing in config for the device"); + if (NULL == componentName) { + LogError(PNP_CONFIG_COMPONENT_NAME " is missing in config for the device"); result = PNPBRIDGE_INVALID_ARGS; LEAVE; } @@ -288,8 +288,8 @@ PnpBridge_ProcessPnpMessage( mallocAndStrcpy_s(&PnpMessage_AccessProperties(PnpMessage)->ComponentName, componentName); } - if (PnpAdapterManager_IsInterfaceIdPublished(pnpBridge->PnpMgr, interfaceId)) { - LogError("PnP Interface has already been published. Dropping the change notification. \n"); + if (PnpAdapterManager_IsInterfaceIdPublished(pnpBridge->PnpMgr, interfaceId, componentName)) { + LogError("PnP Interface %s instance %s has already been published. Dropping notification", interfaceId, componentName); result = PNPBRIDGE_FAILED; LEAVE; } @@ -320,7 +320,7 @@ DiscoveryAdapter_PublishInterfaces() { DIGITALTWIN_INTERFACE_CLIENT_HANDLE* interfaces = NULL; PnpAdapterManager_GetAllInterfaces(pnpBridge->PnpMgr, &interfaces, &interfaceCount); - LogInfo("Publishing Azure Pnp Interface, count %d", interfaceCount); + LogInfo("Publishing %d Azure Pnp Interface(s)", interfaceCount); result = IotComms_RegisterPnPInterfaces(&pnpBridge->IotHandle, pnpBridge->Configuration.ConnParams->DeviceCapabilityModelUri, diff --git a/pnpbridge/src/pnpbridge/src/pnpmessage.c b/pnpbridge/src/pnpbridge/src/pnpmessage.c index df39aa0..86d14ae 100644 --- a/pnpbridge/src/pnpbridge/src/pnpmessage.c +++ b/pnpbridge/src/pnpbridge/src/pnpmessage.c @@ -202,7 +202,7 @@ PnpMessageQueue_Worker( // 1. Unload all the pnp adapters // 2. Destroy the Digital twin client // 3. Recreate Digital twin client - // 4. replay all messages + // 4. Replay all messages from devices reported by discovery adapters // 5. Publish the interface PnpBridge_ReinitPnpAdapters();