Merge pull request #30 from Azure/shyamal/bridgefixes
Some more reliability and doc improvements
This commit is contained in:
Коммит
b21714766f
|
@ -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;
|
||||
}
|
||||
|
@ -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();
|
||||
|
|
Загрузка…
Ссылка в новой задаче