some more reliability and doc improvements

This commit is contained in:
Shyamal Varma 2019-09-13 16:07:44 -07:00
Родитель 3b49a5bf31
Коммит 9f315e8358
9 изменённых файлов: 355 добавлений и 335 удалений

Просмотреть файл

@ -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",

Просмотреть файл

@ -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

Просмотреть файл

@ -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);

Просмотреть файл

@ -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();

Просмотреть файл

@ -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");

Просмотреть файл

@ -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 <pnpbridge.h>
#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 <Windows.h>
#include <cfgmgr32.h>
#include <ctype.h>
#include <winerror.h>
#else
typedef unsigned int DWORD;
typedef uint8_t byte;
typedef int HANDLE;
typedef short USHORT;
typedef uint16_t UINT16;
#include <errno.h>
#include <string.h>
#include <fcntl.h>
#include <termios.h>
#include <unistd.h>
#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 <pnpbridge.h>
#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 <Windows.h>
#include <cfgmgr32.h>
#include <ctype.h>
#include <winerror.h>
#else
typedef unsigned int DWORD;
typedef uint8_t byte;
typedef int HANDLE;
typedef short USHORT;
typedef uint16_t UINT16;
#include <errno.h>
#include <string.h>
#include <fcntl.h>
#include <termios.h>
#include <unistd.h>
#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
};

Просмотреть файл

@ -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;

Просмотреть файл

@ -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,

Просмотреть файл

@ -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();