Allow publishing multiple interfaces from a CreateInterface PnpAdapter callback
This commit is contained in:
Родитель
880e01cb77
Коммит
d250c531fc
|
@ -11,9 +11,9 @@ PNP_ADAPTER CameraPnpInterface = {
|
|||
"camera-health-monitor",
|
||||
CameraPnpInterfaceInitialize,
|
||||
CameraPnpInterfaceBind,
|
||||
CameraPnpInterfaceRelease,
|
||||
CameraPnpInterfaceShutdown
|
||||
};
|
||||
// CameraPnpInterfaceRelease,
|
||||
|
||||
// Camera discovery API entry points.
|
||||
CameraPnpDiscovery* g_pPnpDiscovery = nullptr;
|
||||
|
@ -74,7 +74,7 @@ CameraPnpInterfaceShutdown(
|
|||
|
||||
int
|
||||
CameraPnpInterfaceBind(
|
||||
_In_ PNPADAPTER_INTERFACE_HANDLE Interface,
|
||||
_In_ PNPADAPTER_CONTEXT adapterHandle,
|
||||
_In_ PNP_DEVICE_CLIENT_HANDLE pnpDeviceClientHandle,
|
||||
_In_ PPNPBRIDGE_DEVICE_CHANGE_PAYLOAD payload
|
||||
)
|
||||
|
@ -87,6 +87,7 @@ CameraPnpInterfaceBind(
|
|||
JSON_Value* jmsg;
|
||||
JSON_Object* jobj;
|
||||
|
||||
PNPADAPTER_INTERFACE_HANDLE Interface = NULL;
|
||||
|
||||
if (nullptr == Interface || nullptr == payload || nullptr == payload->Context)
|
||||
{
|
||||
|
@ -103,13 +104,13 @@ CameraPnpInterfaceBind(
|
|||
pnpInterfaceClient = PnP_InterfaceClient_Create(pnpDeviceClientHandle, interfaceId, nullptr, nullptr, nullptr);
|
||||
RETURN_HR_IF_NULL (E_UNEXPECTED, pnpInterfaceClient);
|
||||
|
||||
PnpAdapter_SetPnpInterfaceClient(Interface, pnpInterfaceClient);
|
||||
//PnpAdapter_SetPnpInterfaceClient(Interface, pnpInterfaceClient);
|
||||
|
||||
pIotPnp = std::make_unique<CameraIotPnpDevice>();
|
||||
RETURN_IF_FAILED (pIotPnp->Initialize(PnpAdapter_GetPnpInterfaceClient(Interface), nullptr /* cameraName.c_str() */));
|
||||
RETURN_IF_FAILED (pIotPnp->Initialize(PnpAdapterInterface_GetPnpInterfaceClient(Interface), nullptr /* cameraName.c_str() */));
|
||||
RETURN_IF_FAILED (pIotPnp->StartTelemetryWorker());
|
||||
|
||||
RETURN_HR_IF (E_UNEXPECTED, 0 != PnpAdapter_SetContext(Interface, (void*)pIotPnp.get()));
|
||||
RETURN_HR_IF (E_UNEXPECTED, 0 != PnpAdapterInterface_SetContext(Interface, (void*)pIotPnp.get()));
|
||||
|
||||
// Our interface context now owns the object.
|
||||
pIotPnp.release();
|
||||
|
@ -122,7 +123,7 @@ CameraPnpInterfaceRelease(
|
|||
_In_ PNPADAPTER_INTERFACE_HANDLE Interface
|
||||
)
|
||||
{
|
||||
CameraIotPnpDevice* p = (CameraIotPnpDevice*)PnpAdapter_GetContext(Interface);
|
||||
CameraIotPnpDevice* p = (CameraIotPnpDevice*)PnpAdapterInterface_GetContext(Interface);
|
||||
|
||||
if (p != nullptr)
|
||||
{
|
||||
|
@ -135,7 +136,7 @@ CameraPnpInterfaceRelease(
|
|||
|
||||
// Clear our context to make sure we don't keep a stale
|
||||
// object around.
|
||||
(void) PnpAdapter_SetContext(Interface, nullptr);
|
||||
(void) PnpAdapterInterface_SetContext(Interface, nullptr);
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
|
|
@ -31,7 +31,7 @@ CameraPnpInterfaceShutdown(
|
|||
|
||||
int
|
||||
CameraPnpInterfaceBind(
|
||||
_In_ PNPADAPTER_INTERFACE_HANDLE Interface,
|
||||
_In_ PNPADAPTER_CONTEXT adapterHandle,
|
||||
_In_ PNP_DEVICE_CLIENT_HANDLE pnpDeviceClientHandle,
|
||||
_In_ PPNPBRIDGE_DEVICE_CHANGE_PAYLOAD payload
|
||||
);
|
||||
|
|
|
@ -83,9 +83,14 @@ CoreDevice_OnDeviceNotification(
|
|||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int CoreDevice_ReleaseInterface(PNPADAPTER_INTERFACE_HANDLE pnpInterface) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
HCMNOTIFICATION CoreDevice_hNotifyCtx = NULL;
|
||||
|
||||
int CoreDevice_CreatePnpInterface(PNPADAPTER_INTERFACE_HANDLE Interface, PNP_DEVICE_CLIENT_HANDLE pnpDeviceClientHandle, PPNPBRIDGE_DEVICE_CHANGE_PAYLOAD param) {
|
||||
int CoreDevice_CreatePnpInterface(PNPADAPTER_CONTEXT adapterHandle, PNP_DEVICE_CLIENT_HANDLE pnpDeviceClientHandle, PPNPBRIDGE_DEVICE_CHANGE_PAYLOAD param) {
|
||||
DWORD cmRet;
|
||||
CM_NOTIFY_FILTER cmFilter;
|
||||
PNP_INTERFACE_CLIENT_HANDLE pnpInterfaceClient;
|
||||
|
@ -95,17 +100,30 @@ int CoreDevice_CreatePnpInterface(PNPADAPTER_INTERFACE_HANDLE Interface, PNP_DEV
|
|||
const char* interfaceId = json_object_get_string(args, "InterfaceId");
|
||||
const char* hardwareId = json_object_get_string(args, "HardwareId");
|
||||
const char* symbolicLink = json_object_get_string(args, "SymbolicLink");
|
||||
const char* persistent = json_object_get_string(args, "Persistent");
|
||||
|
||||
if (Interface == NULL) {
|
||||
return -1;
|
||||
}
|
||||
PNPADAPTER_INTERFACE_HANDLE Interface = NULL;
|
||||
|
||||
pnpInterfaceClient = PnP_InterfaceClient_Create(pnpDeviceClientHandle, interfaceId, NULL, NULL, NULL);
|
||||
if (NULL == pnpInterfaceClient) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
PnpAdapter_SetPnpInterfaceClient(Interface, pnpInterfaceClient);
|
||||
// Create PnpAdapter Interface
|
||||
{
|
||||
PNPADPATER_INTERFACE_INIT_PARAMS interfaceParams = { 0 };
|
||||
interfaceParams.releaseInterface = CoreDevice_ReleaseInterface;
|
||||
PNPADAPTER_INTERFACE_HANDLE pnpAdapterInterface;
|
||||
|
||||
int result = PnpAdapterInterface_Create(adapterHandle, interfaceId, pnpInterfaceClient, &pnpAdapterInterface, &interfaceParams);
|
||||
if (result < 0) {
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
if (NULL != persistent && stricmp(persistent, "true") == 0) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
ZeroMemory(&cmFilter, sizeof(cmFilter));
|
||||
cmFilter.cbSize = sizeof(cmFilter);
|
||||
|
@ -181,10 +199,6 @@ int SendDeviceDisconnectedEventAsync(PNP_INTERFACE_CLIENT_HANDLE pnpInterfaceCor
|
|||
return result;
|
||||
}
|
||||
|
||||
int CoreDevice_ReleaseInterface(PNPADAPTER_INTERFACE_HANDLE pnpInterface) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
int CoreDevice_Initialize(const char* adapterArgs) {
|
||||
g_coreDeviceWatchers = singlylinkedlist_create();
|
||||
if (NULL == g_coreDeviceWatchers) {
|
||||
|
@ -202,9 +216,9 @@ int CoreDevice_Shutdown() {
|
|||
}
|
||||
|
||||
PNP_ADAPTER CoreDeviceHealthInterface = {
|
||||
.Identity = "core-device-health",
|
||||
.Initialize = CoreDevice_Initialize,
|
||||
.Shutdown = CoreDevice_Shutdown,
|
||||
.CreatePnpInterface = CoreDevice_CreatePnpInterface,
|
||||
.ReleaseInterface = CoreDevice_ReleaseInterface,
|
||||
.identity = "core-device-health",
|
||||
.initialize = CoreDevice_Initialize,
|
||||
.shutdown = CoreDevice_Shutdown,
|
||||
.createPnpInterface = CoreDevice_CreatePnpInterface,
|
||||
//.releaseInterface = CoreDevice_ReleaseInterface,
|
||||
};
|
Разница между файлами не показана из-за своего большого размера
Загрузить разницу
|
@ -5,94 +5,101 @@ extern "C"
|
|||
{
|
||||
#endif
|
||||
|
||||
typedef struct SerialPnPPacketHeader
|
||||
{
|
||||
byte StartOfFrame;
|
||||
USHORT Length;
|
||||
byte PacketType;
|
||||
} SerialPnPPacketHeader;
|
||||
typedef struct SerialPnPPacketHeader
|
||||
{
|
||||
byte StartOfFrame;
|
||||
USHORT Length;
|
||||
byte PacketType;
|
||||
} SerialPnPPacketHeader;
|
||||
|
||||
typedef enum Schema
|
||||
{
|
||||
Invalid = 0,
|
||||
Byte,
|
||||
Float,
|
||||
Double,
|
||||
Int,
|
||||
Long,
|
||||
Boolean,
|
||||
String
|
||||
} Schema;
|
||||
typedef enum Schema
|
||||
{
|
||||
Invalid = 0,
|
||||
Byte,
|
||||
Float,
|
||||
Double,
|
||||
Int,
|
||||
Long,
|
||||
Boolean,
|
||||
String
|
||||
} Schema;
|
||||
|
||||
typedef struct FieldDefinition
|
||||
{
|
||||
char* Name;
|
||||
char* DisplayName;
|
||||
char* Description;
|
||||
} FieldDefinition;
|
||||
typedef struct FieldDefinition
|
||||
{
|
||||
char* Name;
|
||||
char* DisplayName;
|
||||
char* Description;
|
||||
} FieldDefinition;
|
||||
|
||||
|
||||
typedef struct EventDefinition
|
||||
{
|
||||
FieldDefinition defintion;
|
||||
Schema DataSchema;
|
||||
char* Units;
|
||||
} EventDefinition;
|
||||
typedef struct EventDefinition
|
||||
{
|
||||
FieldDefinition defintion;
|
||||
Schema DataSchema;
|
||||
char* Units;
|
||||
} EventDefinition;
|
||||
|
||||
typedef struct PropertyDefinition
|
||||
{
|
||||
FieldDefinition defintion;
|
||||
char* Units;
|
||||
bool Required;
|
||||
bool Writeable;
|
||||
Schema DataSchema;
|
||||
} PropertyDefinition;
|
||||
typedef struct PropertyDefinition
|
||||
{
|
||||
FieldDefinition defintion;
|
||||
char* Units;
|
||||
bool Required;
|
||||
bool Writeable;
|
||||
Schema DataSchema;
|
||||
} PropertyDefinition;
|
||||
|
||||
typedef struct CommandDefinition
|
||||
{
|
||||
FieldDefinition defintion;
|
||||
Schema RequestSchema;
|
||||
Schema ResponseSchema;
|
||||
} CommandDefinition;
|
||||
typedef struct CommandDefinition
|
||||
{
|
||||
FieldDefinition defintion;
|
||||
Schema RequestSchema;
|
||||
Schema ResponseSchema;
|
||||
} CommandDefinition;
|
||||
|
||||
typedef struct InterfaceDefinition
|
||||
{
|
||||
char* Id;
|
||||
int Index;
|
||||
SINGLYLINKEDLIST_HANDLE Events;
|
||||
SINGLYLINKEDLIST_HANDLE Properties;
|
||||
SINGLYLINKEDLIST_HANDLE Commands;
|
||||
} InterfaceDefinition;
|
||||
typedef struct InterfaceDefinition
|
||||
{
|
||||
char* Id;
|
||||
int Index;
|
||||
SINGLYLINKEDLIST_HANDLE Events;
|
||||
SINGLYLINKEDLIST_HANDLE Properties;
|
||||
SINGLYLINKEDLIST_HANDLE Commands;
|
||||
} InterfaceDefinition;
|
||||
|
||||
typedef enum DefinitionType {
|
||||
Telemetry,
|
||||
Property,
|
||||
Command
|
||||
} DefinitionType;
|
||||
typedef enum DefinitionType {
|
||||
Telemetry,
|
||||
Property,
|
||||
Command
|
||||
} DefinitionType;
|
||||
|
||||
typedef struct _SERIAL_DEVICE_CONTEXT {
|
||||
HANDLE hSerial;
|
||||
PNP_INTERFACE_CLIENT_HANDLE* InterfaceHandle;
|
||||
byte RxBuffer[4096]; // Todo: maximum buffer size
|
||||
unsigned int RxBufferIndex;
|
||||
bool RxEscaped;
|
||||
THREAD_HANDLE SerialDeviceWorker;
|
||||
PNPBRIDGE_NOTIFY_DEVICE_CHANGE SerialDeviceChangeCallback;
|
||||
} SERIAL_DEVICE_CONTEXT, *PSERIAL_DEVICE_CONTEXT;
|
||||
typedef struct _SERIAL_DEVICE_CONTEXT {
|
||||
HANDLE hSerial;
|
||||
PNPADAPTER_INTERFACE_HANDLE pnpAdapterInterface;
|
||||
|
||||
void SerialPnp_RxPacket(PSERIAL_DEVICE_CONTEXT serialDevice, byte** receivedPacket, DWORD* length, char packetType);
|
||||
byte RxBuffer[4096]; // Todo: maximum buffer size
|
||||
unsigned int RxBufferIndex;
|
||||
bool RxEscaped;
|
||||
//OVERLAPPED osReader;
|
||||
THREAD_HANDLE SerialDeviceWorker;
|
||||
PNPBRIDGE_NOTIFY_DEVICE_CHANGE SerialDeviceChangeCallback;
|
||||
|
||||
// list of interface definitions on this serial device
|
||||
SINGLYLINKEDLIST_HANDLE InterfaceDefinitions;
|
||||
} SERIAL_DEVICE_CONTEXT, *PSERIAL_DEVICE_CONTEXT;
|
||||
|
||||
void SerialPnp_TxPacket(PSERIAL_DEVICE_CONTEXT serialDevice, byte* OutPacket, int Length);
|
||||
void SerialPnp_RxPacket(PSERIAL_DEVICE_CONTEXT serialDevice, byte** receivedPacket, DWORD* length, char packetType);
|
||||
|
||||
void SerialPnp_UnsolicitedPacket(PSERIAL_DEVICE_CONTEXT device, byte* packet, DWORD length);
|
||||
void SerialPnp_TxPacket(PSERIAL_DEVICE_CONTEXT serialDevice, byte* OutPacket, int Length);
|
||||
|
||||
void SerialPnp_ResetDevice(PSERIAL_DEVICE_CONTEXT serialDevice);
|
||||
void SerialPnp_UnsolicitedPacket(PSERIAL_DEVICE_CONTEXT device, byte* packet, DWORD length);
|
||||
|
||||
void SerialPnp_DeviceDescriptorRequest(PSERIAL_DEVICE_CONTEXT serialDevice, byte** desc, DWORD* length);
|
||||
void SerialPnp_ResetDevice(PSERIAL_DEVICE_CONTEXT serialDevice);
|
||||
|
||||
byte* SerialPnp_StringSchemaToBinary(Schema Schema, byte* data, int* length);
|
||||
void SerialPnp_DeviceDescriptorRequest(PSERIAL_DEVICE_CONTEXT serialDevice, byte** desc, DWORD* length);
|
||||
|
||||
int SerialPnp_SendEventAsync(PNP_INTERFACE_CLIENT_HANDLE pnpInterface, char* eventName, char* data);
|
||||
byte* SerialPnp_StringSchemaToBinary(Schema Schema, byte* data, int* length);
|
||||
|
||||
int SerialPnp_SendEventAsync(PNP_INTERFACE_CLIENT_HANDLE pnpInterface, char* eventName, char* data);
|
||||
|
||||
int SerialPnp_ReleasePnpInterface(PNPADAPTER_INTERFACE_HANDLE pnpInterface);
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
|
|
@ -41,10 +41,19 @@ JSON_Object* Configuration_GetPnpParametersForDevice(JSON_Object* device) {
|
|||
return NULL;
|
||||
}
|
||||
|
||||
JSON_Object* discoveryParams = json_object_dotget_object(device, "PnpParameters");
|
||||
return discoveryParams;
|
||||
JSON_Object* pnpParams = json_object_dotget_object(device, "PnpParameters");
|
||||
return pnpParams;
|
||||
}
|
||||
|
||||
JSON_Object* Configuration_GetMatchParametersForDevice(JSON_Object* device) {
|
||||
if (device == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
JSON_Object* filterParams = json_object_dotget_object(device, "MatchFilters");
|
||||
JSON_Object* matchParams = json_object_dotget_object(filterParams, "MatchParameters");
|
||||
return matchParams;
|
||||
}
|
||||
|
||||
JSON_Object* Configuration_GetDiscoveryParametersForDevice(JSON_Object* device) {
|
||||
if (device == NULL) {
|
||||
|
@ -79,7 +88,7 @@ JSON_Object* Configuration_GetAdapterParameters(JSON_Value* config, const char*
|
|||
|
||||
for (int j = 0; j < (int)json_array_get_count(params); j++) {
|
||||
JSON_Object *param = json_array_get_object(params, j);
|
||||
const char* id = json_object_dotget_string(param, "Identity");
|
||||
const char* id = json_object_dotget_string(param, PNP_CONFIG_IDENTITY_NAME);
|
||||
if (NULL != id) {
|
||||
if (strcmp(id, identity) == 0) {
|
||||
return param;
|
||||
|
@ -91,21 +100,22 @@ JSON_Object* Configuration_GetAdapterParameters(JSON_Value* config, const char*
|
|||
}
|
||||
|
||||
JSON_Object* Configuration_GetPnpParameters(JSON_Value* config, const char* identity) {
|
||||
return Configuration_GetAdapterParameters(config, identity, "PnpAdapters");
|
||||
return Configuration_GetAdapterParameters(config, identity, PNP_CONFIG_NAME_PNP_ADAPTERS);
|
||||
}
|
||||
|
||||
JSON_Object* Configuration_GetDiscoveryParameters(JSON_Value* config,const char* identity) {
|
||||
return Configuration_GetAdapterParameters(config, identity, "DiscoveryAdapters");
|
||||
return Configuration_GetAdapterParameters(config, identity, PNP_CONFIG_NAME_DISCOVERY_ADAPTERS);
|
||||
}
|
||||
|
||||
PNPBRIDGE_RESULT Configuration_IsDeviceConfigured(JSON_Value* config, JSON_Object* Message, JSON_Object** Device) {
|
||||
JSON_Array *devices = Configuration_GetConfiguredDevices(config);
|
||||
JSON_Object* discMatchParams;
|
||||
char* pnpAdapterIdentity = NULL;
|
||||
int res = -1;
|
||||
bool foundMatch = false;
|
||||
|
||||
// const char* formatId = json_object_dotget_string(Message, "Identity");
|
||||
discMatchParams = json_object_get_object(Message, "MatchParameters");
|
||||
// const char* formatId = json_object_dotget_string(Message, "Identity");
|
||||
discMatchParams = json_object_get_object(Message, PNP_CONFIG_NAME_MATCH_PARAMETERS);
|
||||
|
||||
// There needs to be only one match at the end.
|
||||
for (int i = 0; i < (int)json_array_get_count(devices); i++) {
|
||||
|
@ -117,18 +127,23 @@ PNPBRIDGE_RESULT Configuration_IsDeviceConfigured(JSON_Value* config, JSON_Objec
|
|||
|
||||
// const char* deviceFormatId = json_object_dotget_string(moduleParams, "Identity");
|
||||
if (true) { //strcmp(deviceFormatId, formatId) == 0) {
|
||||
JSON_Object* matchCriteria = json_object_dotget_object(device, "MatchFilters");
|
||||
const char* matchType = json_object_get_string(matchCriteria, "MatchType");
|
||||
JSON_Object* matchCriteria = json_object_dotget_object(device, PNP_CONFIG_MATCH_FILTERS_NAME);
|
||||
const char* matchType = json_object_get_string(matchCriteria, PNP_CONFIG_MATCH_TYPE_NAME);
|
||||
const char* currPnpAdapterId = json_object_get_string(moduleParams, PNP_CONFIG_IDENTITY_NAME);
|
||||
if (strcmp(matchType, "*") == 0) {
|
||||
if (true == foundMatch) {
|
||||
LogError("Found multiple devices in the config that match the filter");
|
||||
res = -1;
|
||||
goto end;
|
||||
if (0 == stricmp(pnpAdapterIdentity, currPnpAdapterId)) {
|
||||
LogError("Found multiple devices in the config that match the filter");
|
||||
res = -1;
|
||||
goto end;
|
||||
}
|
||||
}
|
||||
else {
|
||||
foundMatch = true;
|
||||
pnpAdapterIdentity = (char*) currPnpAdapterId;
|
||||
res = 0;
|
||||
*Device = device;
|
||||
}
|
||||
|
||||
foundMatch = true;
|
||||
res = 0;
|
||||
*Device = device;
|
||||
continue;
|
||||
}
|
||||
|
||||
|
@ -136,7 +151,7 @@ PNPBRIDGE_RESULT Configuration_IsDeviceConfigured(JSON_Value* config, JSON_Objec
|
|||
continue;
|
||||
}
|
||||
|
||||
JSON_Object* matchParameters = json_object_dotget_object(matchCriteria, "MatchParameters");
|
||||
JSON_Object* matchParameters = json_object_dotget_object(matchCriteria, PNP_CONFIG_NAME_MATCH_PARAMETERS);
|
||||
const size_t matchParameterCount = json_object_get_count(matchParameters);
|
||||
for (int j = 0; j < (int)matchParameterCount; j++) {
|
||||
const char* name = json_object_get_name(matchParameters, j);
|
||||
|
@ -148,26 +163,24 @@ PNPBRIDGE_RESULT Configuration_IsDeviceConfigured(JSON_Value* config, JSON_Objec
|
|||
}
|
||||
|
||||
const char* value2 = json_object_get_string(discMatchParams, name);
|
||||
if (strstr(value2, value) == 0) {
|
||||
res = -1;
|
||||
goto end;
|
||||
}
|
||||
else {
|
||||
if (strstr(value2, value) != 0) {
|
||||
if (true == foundMatch) {
|
||||
LogError("Found multiple devices in the config that match the filter");
|
||||
res = -1;
|
||||
goto end;
|
||||
if (0 == stricmp(pnpAdapterIdentity, currPnpAdapterId)) {
|
||||
LogError("Found multiple devices in the config that match the filter");
|
||||
res = -1;
|
||||
goto end;
|
||||
}
|
||||
}
|
||||
else {
|
||||
const char* interfaceId = json_object_dotget_string(device, PNP_CONFIG_INTERFACE_ID_NAME);
|
||||
json_object_set_string(Message, PNP_CONFIG_INTERFACE_ID_NAME, interfaceId);
|
||||
foundMatch = true;
|
||||
pnpAdapterIdentity = (char*) currPnpAdapterId;
|
||||
*Device = device;
|
||||
res = 0;
|
||||
}
|
||||
|
||||
const char* interfaceId = json_object_dotget_string(device, "InterfaceId");
|
||||
json_object_set_string(Message, "InterfaceId", interfaceId);
|
||||
foundMatch = true;
|
||||
*Device = device;
|
||||
res = 0;
|
||||
}
|
||||
}
|
||||
res = 0;
|
||||
goto end;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -26,6 +26,8 @@ PNPBRIDGE_RESULT PnpBridgeConfig_ReadConfigurationFromFile(const char *filename,
|
|||
*/
|
||||
PNPBRIDGE_RESULT PnpBridgeConfig_ReadConfigurationFromString(const char *configString, JSON_Value** config);
|
||||
|
||||
JSON_Object* Configuration_GetMatchParametersForDevice(JSON_Object* device);
|
||||
|
||||
JSON_Object* Configuration_GetDiscoveryParametersForDevice(JSON_Object* device);
|
||||
|
||||
JSON_Object* Configuration_GetPnpParametersForDevice(JSON_Object* device);
|
||||
|
|
|
@ -106,63 +106,108 @@ PNPBRIDGE_RESULT DiscoveryManager_StarDiscoveryAdapter(PDISCOVERY_MANAGER discov
|
|||
return PNPBRIDGE_OK;
|
||||
}
|
||||
|
||||
PNPBRIDGE_RESULT DiscoveryAdapterManager_Start(PDISCOVERY_MANAGER discoveryManager, JSON_Value* config) {
|
||||
const char* PnpBridge_DeviceChangeMessageformat = "{ \
|
||||
\"Identity\": \"pnpbridge-core\", \
|
||||
\"InterfaceId\": \"%s\", \
|
||||
\"Persistent\": \"true\", \
|
||||
\"MatchParameters\": %s \
|
||||
}";
|
||||
|
||||
PNPBRIDGE_RESULT DiscoveryAdapterManager_NotifyPersistentInterfaces(PDISCOVERY_MANAGER discoveryManager, JSON_Value* config) {
|
||||
JSON_Array *devices = Configuration_GetConfiguredDevices(config);
|
||||
|
||||
if (NULL == devices) {
|
||||
return PNPBRIDGE_INVALID_ARGS;
|
||||
}
|
||||
for (int i = 0; i < (int)json_array_get_count(devices); i++) {
|
||||
JSON_Object* device = json_array_get_object(devices, i);
|
||||
const char* persistentString = json_object_get_string(device, PNP_CONFIG_PERSISTENT_NAME);
|
||||
if (NULL != persistentString && stricmp(persistentString, "true") == 0) {
|
||||
PNPBRIDGE_DEVICE_CHANGE_PAYLOAD payload = { 0 };
|
||||
payload.ChangeType = PNPBRIDGE_INTERFACE_CHANGE_PERSIST;
|
||||
|
||||
for (int i = 0; i < DiscoveryAdapterCount; i++) {
|
||||
PDISCOVERY_ADAPTER discoveryInterface = DISCOVERY_ADAPTER_MANIFEST[i];
|
||||
JSON_Object* deviceParams = NULL;
|
||||
// Get the match filters and post a device change message
|
||||
JSON_Object* matchParams = Configuration_GetMatchParametersForDevice(device);
|
||||
const char* interfaceId = json_object_dotget_string(device, PNP_CONFIG_INTERFACE_ID_NAME);
|
||||
if (NULL != interfaceId && NULL != matchParams) {
|
||||
char msg[512] = { 0 };
|
||||
sprintf_s(msg, 512, PnpBridge_DeviceChangeMessageformat, interfaceId, json_serialize_to_string(json_object_get_wrapping_value(matchParams)));
|
||||
|
||||
payload.Message = msg;
|
||||
payload.MessageLength = (int)strlen(msg);
|
||||
|
||||
for (int j = 0; j < (int)json_array_get_count(devices); j++) {
|
||||
JSON_Object *device = json_array_get_object(devices, j);
|
||||
|
||||
// For this Identity check if there is any device
|
||||
// TODO: Create an array of device
|
||||
JSON_Object* params = Configuration_GetDiscoveryParametersForDevice(device);
|
||||
if (NULL != params) {
|
||||
const char* deviceFormatId = json_object_get_string(params, "Identity");
|
||||
if (strcmp(deviceFormatId, discoveryInterface->Identity) == 0) {
|
||||
deviceParams = params;
|
||||
break;
|
||||
}
|
||||
DiscoveryAdapterChangeHandler(&payload);
|
||||
}
|
||||
}
|
||||
|
||||
JSON_Object* adapterParams = NULL;
|
||||
adapterParams = Configuration_GetDiscoveryParameters(config, discoveryInterface->Identity);
|
||||
|
||||
//PSTART_DISCOVERY_PARAMS threadContext;
|
||||
|
||||
//// threadContext memory will be freed during cleanup.
|
||||
//threadContext = malloc(sizeof(START_DISCOVERY_PARAMS));
|
||||
//if (NULL == threadContext) {
|
||||
// return PNPBRIDGE_INSUFFICIENT_MEMORY;
|
||||
//}
|
||||
|
||||
//threadContext->adapterParams = adapterParams;
|
||||
//threadContext->deviceParams = deviceParams;
|
||||
//threadContext->discoveryInterface = discoveryInterface;
|
||||
//threadContext->key = i;
|
||||
//threadContext->discoveryManager = discoveryManager;
|
||||
|
||||
//if (THREADAPI_OK != ThreadAPI_Create(&threadContext->workerThreadHandle, DiscoveryManager_StarDiscovery_Worker_Thread, threadContext)) {
|
||||
// LogError("Failed to create PnpBridge_Worker_Thread \n");
|
||||
// threadContext->workerThreadHandle = NULL;
|
||||
// return PNPBRIDGE_FAILED;
|
||||
//}
|
||||
int result = DiscoveryManager_StarDiscoveryAdapter(discoveryManager, discoveryInterface, deviceParams, adapterParams, i);
|
||||
if (PNPBRIDGE_OK != result) {
|
||||
return result;
|
||||
}
|
||||
|
||||
//singlylinkedlist_add(discoveryManager->startDiscoveryThreadHandles, threadContext);
|
||||
}
|
||||
|
||||
return PNPBRIDGE_OK;
|
||||
return 0;
|
||||
}
|
||||
|
||||
PNPBRIDGE_RESULT DiscoveryAdapterManager_Start(PDISCOVERY_MANAGER discoveryManager, JSON_Value* config) {
|
||||
JSON_Array *devices = Configuration_GetConfiguredDevices(config);
|
||||
PNPBRIDGE_RESULT result = PNPBRIDGE_OK;
|
||||
|
||||
TRY
|
||||
{
|
||||
if (NULL == devices) {
|
||||
result = PNPBRIDGE_INVALID_ARGS;
|
||||
LEAVE;
|
||||
}
|
||||
|
||||
for (int i = 0; i < DiscoveryAdapterCount; i++) {
|
||||
PDISCOVERY_ADAPTER discoveryInterface = DISCOVERY_ADAPTER_MANIFEST[i];
|
||||
JSON_Object* deviceParams = NULL;
|
||||
|
||||
for (int j = 0; j < (int)json_array_get_count(devices); j++) {
|
||||
JSON_Object *device = json_array_get_object(devices, j);
|
||||
|
||||
// For this Identity check if there is any device
|
||||
// TODO: Create an array of device
|
||||
JSON_Object* params = Configuration_GetDiscoveryParametersForDevice(device);
|
||||
if (NULL != params) {
|
||||
const char* discoveryIdentity = json_object_get_string(params, PNP_CONFIG_IDENTITY_NAME);
|
||||
if (NULL != discoveryIdentity) {
|
||||
if (stricmp(discoveryIdentity, discoveryInterface->Identity) == 0) {
|
||||
deviceParams = params;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
JSON_Object* adapterParams = NULL;
|
||||
adapterParams = Configuration_GetDiscoveryParameters(config, discoveryInterface->Identity);
|
||||
|
||||
//PSTART_DISCOVERY_PARAMS threadContext;
|
||||
|
||||
//// threadContext memory will be freed during cleanup.
|
||||
//threadContext = malloc(sizeof(START_DISCOVERY_PARAMS));
|
||||
//if (NULL == threadContext) {
|
||||
// return PNPBRIDGE_INSUFFICIENT_MEMORY;
|
||||
//}
|
||||
|
||||
//threadContext->adapterParams = adapterParams;
|
||||
//threadContext->deviceParams = deviceParams;
|
||||
//threadContext->discoveryInterface = discoveryInterface;
|
||||
//threadContext->key = i;
|
||||
//threadContext->discoveryManager = discoveryManager;
|
||||
|
||||
//if (THREADAPI_OK != ThreadAPI_Create(&threadContext->workerThreadHandle, DiscoveryManager_StarDiscovery_Worker_Thread, threadContext)) {
|
||||
// LogError("Failed to create PnpBridge_Worker_Thread \n");
|
||||
// threadContext->workerThreadHandle = NULL;
|
||||
// return PNPBRIDGE_FAILED;
|
||||
//}
|
||||
int result = DiscoveryManager_StarDiscoveryAdapter(discoveryManager, discoveryInterface, deviceParams, adapterParams, i);
|
||||
if (PNPBRIDGE_OK != result) {
|
||||
return result;
|
||||
}
|
||||
|
||||
//singlylinkedlist_add(discoveryManager->startDiscoveryThreadHandles, threadContext);
|
||||
}
|
||||
}
|
||||
FINALLY
|
||||
{
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
void DiscoveryAdapterManager_Stop(PDISCOVERY_MANAGER discoveryManager) {
|
||||
|
|
|
@ -27,6 +27,8 @@ PNPBRIDGE_RESULT DiscoveryAdapterManager_Create(PDISCOVERY_MANAGER* discoveryMan
|
|||
*/
|
||||
PNPBRIDGE_RESULT DiscoveryAdapterManager_Start(PDISCOVERY_MANAGER discoveryManager, JSON_Value* config);
|
||||
|
||||
PNPBRIDGE_RESULT DiscoveryAdapterManager_NotifyPersistentInterfaces(PDISCOVERY_MANAGER discoveryManager, JSON_Value* config);
|
||||
|
||||
void DiscoveryAdapterManager_Stop(PDISCOVERY_MANAGER discoveryManager);
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
|
|
@ -0,0 +1,102 @@
|
|||
// Copyright (c) Microsoft. All rights reserved.
|
||||
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
|
||||
|
||||
// DeviceAggregator.cpp : Defines the entry point for the console application.
|
||||
|
||||
#include "PnpBridgeCommon.h"
|
||||
#include "ConfigurationParser.h"
|
||||
#include "DiscoveryManager.h"
|
||||
#include "PnpAdapterInterface.h"
|
||||
#include "PnpAdapterManager.h"
|
||||
|
||||
#include "PnpBridgeh.h"
|
||||
|
||||
// State of PnP registration process. We cannot proceed with PnP until we get into the state APP_PNP_REGISTRATION_SUCCEEDED.
|
||||
typedef enum APP_PNP_REGISTRATION_STATUS_TAG
|
||||
{
|
||||
APP_PNP_REGISTRATION_PENDING,
|
||||
APP_PNP_REGISTRATION_SUCCEEDED,
|
||||
APP_PNP_REGISTRATION_FAILED
|
||||
} APP_PNP_REGISTRATION_STATUS;
|
||||
|
||||
// appPnpInterfacesRegistered is invoked when the interfaces have been registered or failed.
|
||||
void appPnpInterfacesRegistered(PNP_REPORTED_INTERFACES_STATUS pnpInterfaceStatus, void *userContextCallback)
|
||||
{
|
||||
APP_PNP_REGISTRATION_STATUS* appPnpRegistrationStatus = (APP_PNP_REGISTRATION_STATUS*)userContextCallback;
|
||||
*appPnpRegistrationStatus = (pnpInterfaceStatus == PNP_REPORTED_INTERFACES_OK) ? APP_PNP_REGISTRATION_SUCCEEDED : APP_PNP_REGISTRATION_FAILED;
|
||||
}
|
||||
|
||||
// Invokes PnP_DeviceClient_RegisterInterfacesAsync, which indicates to Azure IoT which PnP interfaces this device supports.
|
||||
// The PnP Handle *is not valid* until this operation has completed (as indicated by the callback appPnpInterfacesRegistered being invoked).
|
||||
// In this sample, we block indefinitely but production code should include a timeout.
|
||||
int AppRegisterPnPInterfacesAndWait(PNP_DEVICE_CLIENT_HANDLE pnpDeviceClientHandle, PNP_INTERFACE_CLIENT_HANDLE* interfaces, int count)
|
||||
{
|
||||
APP_PNP_REGISTRATION_STATUS appPnpRegistrationStatus = APP_PNP_REGISTRATION_PENDING;
|
||||
PNPBRIDGE_RESULT result;
|
||||
PNP_CLIENT_RESULT pnpResult;
|
||||
|
||||
pnpResult = PnP_DeviceClient_RegisterInterfacesAsync(pnpDeviceClientHandle, interfaces, count, appPnpInterfacesRegistered, &appPnpRegistrationStatus);
|
||||
if (PNP_CLIENT_OK != pnpResult) {
|
||||
result = PNPBRIDGE_FAILED;
|
||||
goto end;
|
||||
}
|
||||
|
||||
while (appPnpRegistrationStatus == APP_PNP_REGISTRATION_PENDING) {
|
||||
ThreadAPI_Sleep(100);
|
||||
}
|
||||
|
||||
if (appPnpRegistrationStatus != APP_PNP_REGISTRATION_SUCCEEDED) {
|
||||
LogError("PnP has failed to register.\n");
|
||||
result = __FAILURE__;
|
||||
}
|
||||
else {
|
||||
result = 0;
|
||||
}
|
||||
|
||||
end:
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
// InitializeIotHubDeviceHandle initializes underlying IoTHub client, creates a device handle with the specified connection string,
|
||||
// and sets some options on this handle prior to beginning.
|
||||
IOTHUB_DEVICE_HANDLE InitializeIotHubDeviceHandle(const char* connectionString)
|
||||
{
|
||||
IOTHUB_DEVICE_HANDLE deviceHandle = NULL;
|
||||
IOTHUB_CLIENT_RESULT iothubClientResult;
|
||||
bool traceOn = false;
|
||||
bool urlEncodeOn = true;
|
||||
|
||||
// TODO: PnP SDK should auto-set OPTION_AUTO_URL_ENCODE_DECODE for MQTT as its strictly required. Need way for IoTHub handle to communicate this back.
|
||||
if (IoTHub_Init() != 0)
|
||||
{
|
||||
LogError("IoTHub_Init failed\n");
|
||||
}
|
||||
else
|
||||
{
|
||||
// Get connection string from config
|
||||
if ((deviceHandle = IoTHubDeviceClient_CreateFromConnectionString(connectionString, MQTT_Protocol)) == NULL)
|
||||
{
|
||||
LogError("Failed to create device handle\n");
|
||||
}
|
||||
else if ((iothubClientResult = IoTHubDeviceClient_SetOption(deviceHandle, OPTION_LOG_TRACE, &traceOn)) != IOTHUB_CLIENT_OK)
|
||||
{
|
||||
LogError("Failed to set option %s, error=%d\n", OPTION_LOG_TRACE, iothubClientResult);
|
||||
IoTHubDeviceClient_Destroy(deviceHandle);
|
||||
deviceHandle = NULL;
|
||||
}
|
||||
else if ((iothubClientResult = IoTHubDeviceClient_SetOption(deviceHandle, OPTION_AUTO_URL_ENCODE_DECODE, &urlEncodeOn)) != IOTHUB_CLIENT_OK)
|
||||
{
|
||||
LogError("Failed to set option %s, error=%d\n", OPTION_AUTO_URL_ENCODE_DECODE, iothubClientResult);
|
||||
IoTHubDeviceClient_Destroy(deviceHandle);
|
||||
deviceHandle = NULL;
|
||||
}
|
||||
|
||||
if (deviceHandle == NULL)
|
||||
{
|
||||
IoTHub_Deinit();
|
||||
}
|
||||
}
|
||||
|
||||
return deviceHandle;
|
||||
}
|
|
@ -0,0 +1,17 @@
|
|||
// Copyright (c) Microsoft. All rights reserved.
|
||||
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
|
||||
|
||||
#pragma once
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C"
|
||||
{
|
||||
#endif
|
||||
|
||||
IOTHUB_DEVICE_HANDLE InitializeIotHubDeviceHandle(const char* connectionString);
|
||||
|
||||
int AppRegisterPnPInterfacesAndWait(PNP_DEVICE_CLIENT_HANDLE pnpDeviceClientHandle, PNP_INTERFACE_CLIENT_HANDLE* interfaces, int count);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
|
@ -9,14 +9,10 @@ extern "C"
|
|||
{
|
||||
#endif
|
||||
|
||||
typedef struct _PNPADAPTER_INTERFACE {
|
||||
PNP_INTERFACE_CLIENT_HANDLE Interface;
|
||||
void* Context;
|
||||
int key;
|
||||
} PNPADAPTER_INTERFACE, *PPNPADAPTER_INTERFACE;
|
||||
|
||||
// Pnp adapter interface handle
|
||||
typedef void* PNPADAPTER_INTERFACE_HANDLE;
|
||||
|
||||
typedef PNPADAPTER_INTERFACE_HANDLE* PPNPADAPTER_INTERFACE_HANDLE;
|
||||
typedef void* PNPADAPTER_CONTEXT;
|
||||
|
||||
/**
|
||||
* @brief PNPADAPTER_PNP_INTERFACE_INITIALIZE callback uses to initialize a pnp adapter.
|
||||
|
@ -50,7 +46,23 @@ typedef int(*PNPADAPTER_PNP_INTERFACE_SHUTDOWN)();
|
|||
*
|
||||
* @returns integer greater than zero on success and other values on failure.
|
||||
*/
|
||||
typedef int(*PNPADAPTER_BIND_PNP_INTERFACE)(PNPADAPTER_INTERFACE_HANDLE pnpInterface, PNP_DEVICE_CLIENT_HANDLE pnpDeviceClientHandle, PPNPBRIDGE_DEVICE_CHANGE_PAYLOAD payload);
|
||||
//typedef int(*PNPADAPTER_BIND_PNP_INTERFACE)(PNPADAPTER_INTERFACE_HANDLE pnpInterface, PNP_DEVICE_CLIENT_HANDLE pnpDeviceClientHandle, PPNPBRIDGE_DEVICE_CHANGE_PAYLOAD payload);
|
||||
|
||||
typedef int(*PNPADAPTER_BIND_PNP_INTERFACE)(PNPADAPTER_CONTEXT adapterHandle,
|
||||
PNP_DEVICE_CLIENT_HANDLE pnpDeviceClientHandle,
|
||||
PPNPBRIDGE_DEVICE_CHANGE_PAYLOAD payload);
|
||||
|
||||
// NOTES TO SELF:
|
||||
|
||||
//
|
||||
// Config update requires bridge tear down and restart
|
||||
//
|
||||
|
||||
// Discovered Device -> Bind -> CreatePnpInterfaces -> Create Pnp Interface client ->
|
||||
// Create Pnp Adapter Interface -> Associate it with the adapter and store the device config pointer -> Get All interface for all adapters -> publish
|
||||
//
|
||||
|
||||
// ***************
|
||||
|
||||
/**
|
||||
* @brief PNPADAPTER_RELEASE_PNP_INTERFACE uninitializes the pnp interface.
|
||||
|
@ -61,9 +73,41 @@ typedef int(*PNPADAPTER_BIND_PNP_INTERFACE)(PNPADAPTER_INTERFACE_HANDLE pnpInter
|
|||
*
|
||||
* @returns integer greater than zero on success and other values on failure.
|
||||
*/
|
||||
typedef int(*PNPADAPTER_RELEASE_PNP_INTERFACE)(PNPADAPTER_INTERFACE_HANDLE pnpInterface);
|
||||
typedef int(*PNPADAPTER_INTERFACE_RELEASE)(PNPADAPTER_INTERFACE_HANDLE pnpInterface);
|
||||
|
||||
|
||||
typedef int(*PNPADAPTER_DEVICE_ARRIVED)(PPNPBRIDGE_DEVICE_CHANGE_PAYLOAD payload);
|
||||
|
||||
/**
|
||||
PnpAdapterInterface Methods
|
||||
**/
|
||||
|
||||
// Pnp adapter interface creation parameters
|
||||
typedef struct _PNPADPATER_INTERFACE_INIT_PARAMS {
|
||||
PNPADAPTER_DEVICE_ARRIVED deviceArrived;
|
||||
PNPADAPTER_INTERFACE_RELEASE releaseInterface;
|
||||
} PNPADPATER_INTERFACE_INIT_PARAMS, *PPNPADPATER_INTERFACE_INIT_PARAMS;
|
||||
|
||||
/**
|
||||
* @brief PnpAdapter_CreatePnpInterface creates a PnP Bridge adapter interface
|
||||
|
||||
* @param pnpAdapterInterface Handle to pnp adapter interface
|
||||
*
|
||||
* @returns Result indicating status of pnp adapter interface creation
|
||||
*/
|
||||
int PnpAdapterInterface_Create(PNPADAPTER_CONTEXT adapterHandle, const char* interfaceName,
|
||||
PNP_INTERFACE_CLIENT_HANDLE Interface,
|
||||
PPNPADAPTER_INTERFACE_HANDLE pnpAdapterInterface,
|
||||
PPNPADPATER_INTERFACE_INIT_PARAMS params);
|
||||
|
||||
/**
|
||||
* @brief PnpAdapter_DestroyPnpInterface destroys a PnP Bridge adapter interface
|
||||
|
||||
* @param pnpAdapterInterface Handle to pnp adapter interface
|
||||
*
|
||||
*/
|
||||
void PnpAdapterInterface_Destroy(PNPADAPTER_INTERFACE_HANDLE pnpAdapterInterface);
|
||||
|
||||
/**
|
||||
* @brief PnpAdapter_GetPnpInterfaceClient gets the Azure iot pnp interface client handle
|
||||
|
||||
|
@ -71,23 +115,7 @@ typedef int(*PNPADAPTER_RELEASE_PNP_INTERFACE)(PNPADAPTER_INTERFACE_HANDLE pnpIn
|
|||
*
|
||||
* @returns Handle to Azure Pnp Interface client
|
||||
*/
|
||||
PNP_INTERFACE_CLIENT_HANDLE PnpAdapter_GetPnpInterfaceClient(PNPADAPTER_INTERFACE_HANDLE pnpInterface);
|
||||
|
||||
/**
|
||||
* @brief PnpAdapter_SetPnpInterfaceClient seta the Azure iot pnp interface client handle
|
||||
*
|
||||
* @remarks This API is for private preview only. When PnpBridge calls CreatePnpInterface
|
||||
callback on a pnp adapter, the adapter should create the Azure PnpInterfaceClient
|
||||
using PnP_InterfaceClient_Create and then call PnpAdapter_SetPnpInterfaceClient with
|
||||
the PnpInterfaceClient
|
||||
|
||||
* @param pnpInterface Handle to pnp adapter interface
|
||||
*
|
||||
** @param pnpInterfaceClient Handle to Azure pnp interface client
|
||||
*
|
||||
* @returns VOID
|
||||
*/
|
||||
void PnpAdapter_SetPnpInterfaceClient(PNPADAPTER_INTERFACE_HANDLE pnpInterface, PNP_INTERFACE_CLIENT_HANDLE pnpInterfaceClient);
|
||||
PNP_INTERFACE_CLIENT_HANDLE PnpAdapterInterface_GetPnpInterfaceClient(PNPADAPTER_INTERFACE_HANDLE pnpAdapterInterface);
|
||||
|
||||
/**
|
||||
* @brief PnpAdapter_SetContext sets a context for pnp adapter interface handle
|
||||
|
@ -98,7 +126,7 @@ void PnpAdapter_SetPnpInterfaceClient(PNPADAPTER_INTERFACE_HANDLE pnpInterface,
|
|||
*
|
||||
* @returns integer greater than zero on success and other values on failure.
|
||||
*/
|
||||
int PnpAdapter_SetContext(PNPADAPTER_INTERFACE_HANDLE pnpInterface, void* context);
|
||||
int PnpAdapterInterface_SetContext(PNPADAPTER_INTERFACE_HANDLE pnpAdapterInterface, void* context);
|
||||
|
||||
/**
|
||||
* @brief PnpAdapter_GetContext gets context set by pnp adapter.
|
||||
|
@ -109,16 +137,23 @@ int PnpAdapter_SetContext(PNPADAPTER_INTERFACE_HANDLE pnpInterface, void* contex
|
|||
*
|
||||
* @returns void* context
|
||||
*/
|
||||
void* PnpAdapter_GetContext(PNPADAPTER_INTERFACE_HANDLE pnpInterface);
|
||||
void* PnpAdapterInterface_GetContext(PNPADAPTER_INTERFACE_HANDLE pnpAdapterInterface);
|
||||
|
||||
/*
|
||||
PnpAdapter Binding info
|
||||
*/
|
||||
typedef struct _PNP_ADAPTER {
|
||||
// Identity of the Pnp Adapter that will be used in the config
|
||||
// of a device under PnpParameters
|
||||
const char* Identity;
|
||||
PNPADAPTER_PNP_INTERFACE_INITIALIZE Initialize;
|
||||
PNPADAPTER_BIND_PNP_INTERFACE CreatePnpInterface;
|
||||
PNPADAPTER_RELEASE_PNP_INTERFACE ReleaseInterface;
|
||||
PNPADAPTER_PNP_INTERFACE_SHUTDOWN Shutdown;
|
||||
const char* identity;
|
||||
|
||||
PNPADAPTER_PNP_INTERFACE_INITIALIZE initialize;
|
||||
|
||||
PNPADAPTER_BIND_PNP_INTERFACE createPnpInterface;
|
||||
|
||||
//PNPADAPTER_RELEASE_PNP_INTERFACE releaseInterface;
|
||||
|
||||
PNPADAPTER_PNP_INTERFACE_SHUTDOWN shutdown;
|
||||
} PNP_ADAPTER, *PPNP_ADAPTER;
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
|
|
@ -8,11 +8,40 @@ extern "C"
|
|||
{
|
||||
#endif
|
||||
|
||||
// Represents a PNPADPTER and its configuration in PnpAdapterManger
|
||||
typedef struct _PNP_ADAPTER_TAG {
|
||||
PPNP_ADAPTER adapter;
|
||||
|
||||
// List of pnp interfaces created under this adapter
|
||||
SINGLYLINKEDLIST_HANDLE pnpInterfaceList;
|
||||
|
||||
// Lock to protect pnpInterfaceList modification
|
||||
LOCK_HANDLE pnpInterfaceListLock;
|
||||
} PNP_ADAPTER_TAG, *PPNP_ADAPTER_TAG;
|
||||
|
||||
// Structure uses to share context between adapter manager and adapter interface
|
||||
typedef struct _PNP_ADAPTER_CONTEXT_TAG {
|
||||
PPNP_ADAPTER_TAG adapter;
|
||||
JSON_Object* deviceConfig;
|
||||
} PNP_ADAPTER_CONTEXT_TAG, *PPNP_ADAPTER_CONTEXT_TAG;
|
||||
|
||||
// Structure used for an instance of Pnp Adapter Manager
|
||||
typedef struct _PNP_ADAPTER_MANAGER {
|
||||
SINGLYLINKEDLIST_HANDLE AdapterList;
|
||||
MAP_HANDLE PnpAdapterMap;
|
||||
MAP_HANDLE pnpAdapterMap;
|
||||
PPNP_ADAPTER_TAG* pnpAdapters;
|
||||
} PNP_ADAPTER_MANAGER, *PPNP_ADAPTER_MANAGER;
|
||||
|
||||
// Pnp adapter interface structure
|
||||
typedef struct _PNPADAPTER_INTERFACE {
|
||||
void* context;
|
||||
int key;
|
||||
bool persistent;
|
||||
char* interfaceId;
|
||||
PNP_INTERFACE_CLIENT_HANDLE pnpInterfaceClient;
|
||||
PNPADPATER_INTERFACE_INIT_PARAMS params;
|
||||
PNPADAPTER_CONTEXT adapterContext;
|
||||
LIST_ITEM_HANDLE adapterEntry;
|
||||
} PNPADAPTER_INTERFACE, *PPNPADAPTER_INTERFACE;
|
||||
|
||||
/**
|
||||
* @brief PnpAdapterManager_Create creates the Azure Pnp Interface adapter manager.
|
||||
|
@ -39,11 +68,17 @@ PNPBRIDGE_RESULT PnpAdapterManager_Create(PPNP_ADAPTER_MANAGER* adapter, JSON_Va
|
|||
*/
|
||||
void PnpAdapterManager_Release(PPNP_ADAPTER_MANAGER adapter);
|
||||
|
||||
|
||||
PNPBRIDGE_RESULT PnpAdapterManager_SupportsIdentity(PPNP_ADAPTER_MANAGER adapter, JSON_Object* Message, bool* supported, int* key);
|
||||
PNPBRIDGE_RESULT PnpAdapterManager_CreatePnpInterface(PPNP_ADAPTER_MANAGER adapter, PNP_DEVICE_CLIENT_HANDLE pnpDeviceClientHandle, int key, PNP_INTERFACE_CLIENT_HANDLE* InterfaceClient, PPNPBRIDGE_DEVICE_CHANGE_PAYLOAD DeviceChangePayload);
|
||||
PNPBRIDGE_RESULT PnpAdapterManager_CreatePnpInterface(PPNP_ADAPTER_MANAGER adapter, PNP_DEVICE_CLIENT_HANDLE pnpDeviceClientHandle, int key, JSON_Object* deviceConfig, PPNPBRIDGE_DEVICE_CHANGE_PAYLOAD DeviceChangePayload);
|
||||
PNPBRIDGE_RESULT PnpAdapterManager_ReleasePnpInterface(PPNP_ADAPTER_MANAGER adapter, PNPADAPTER_INTERFACE_HANDLE Interface);
|
||||
|
||||
PNPBRIDGE_RESULT PnpAdapterManager_GetAllInterfaces(PPNP_ADAPTER_MANAGER adapterMgr, PNP_INTERFACE_CLIENT_HANDLE** interfaces, int* count);
|
||||
bool PnpAdapterManager_IsInterfaceIdPublished(PPNP_ADAPTER_MANAGER adapterMgr, const char* interfaceId);
|
||||
void PnpAdapterManager_ReleaseAdapter(PPNP_ADAPTER_TAG adapterTag);
|
||||
|
||||
void PnpAdapterManager_AddInterface(PPNP_ADAPTER_TAG adapter, PNPADAPTER_INTERFACE_HANDLE pnpAdapterInterface);
|
||||
void PnpAdapterManager_RemoveInterface(PPNP_ADAPTER_TAG adapter, PNPADAPTER_INTERFACE_HANDLE pnpAdapterInterface);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
|
@ -10,19 +10,19 @@ extern const int PnpAdapterCount;
|
|||
|
||||
PNPBRIDGE_RESULT PnpAdapterManager_ValidatePnpAdapter(PPNP_ADAPTER pnpAdapter, MAP_HANDLE pnpAdapterMap) {
|
||||
bool containsKey = false;
|
||||
if (NULL == pnpAdapter->Identity) {
|
||||
if (NULL == pnpAdapter->identity) {
|
||||
LogError("PnpAdapter's Identity filed is not initialized");
|
||||
return PNPBRIDGE_INVALID_ARGS;
|
||||
}
|
||||
if (MAP_OK != Map_ContainsKey(pnpAdapterMap, pnpAdapter->Identity, &containsKey)) {
|
||||
if (MAP_OK != Map_ContainsKey(pnpAdapterMap, pnpAdapter->identity, &containsKey)) {
|
||||
LogError("Map_ContainsKey failed");
|
||||
return PNPBRIDGE_FAILED;
|
||||
}
|
||||
if (containsKey) {
|
||||
LogError("Found duplicate pnp adapter identity %s", pnpAdapter->Identity);
|
||||
LogError("Found duplicate pnp adapter identity %s", pnpAdapter->identity);
|
||||
return PNPBRIDGE_DUPLICATE_ENTRY;
|
||||
}
|
||||
if (NULL == pnpAdapter->Initialize || NULL == pnpAdapter->Shutdown || NULL == pnpAdapter->CreatePnpInterface || NULL == pnpAdapter->ReleaseInterface) {
|
||||
if (NULL == pnpAdapter->initialize || NULL == pnpAdapter->shutdown || NULL == pnpAdapter->createPnpInterface) {
|
||||
LogError("PnpAdapter's callbacks are not initialized");
|
||||
return PNPBRIDGE_INVALID_ARGS;
|
||||
}
|
||||
|
@ -30,6 +30,38 @@ PNPBRIDGE_RESULT PnpAdapterManager_ValidatePnpAdapter(PPNP_ADAPTER pnpAdapter,
|
|||
return PNPBRIDGE_OK;
|
||||
}
|
||||
|
||||
PNPBRIDGE_RESULT PnpAdapterManager_InitializeAdapter(PPNP_ADAPTER_TAG* adapterTag, PPNP_ADAPTER adapter) {
|
||||
PNPBRIDGE_RESULT result = PNPBRIDGE_OK;
|
||||
PPNP_ADAPTER_TAG adapterT = calloc(1, sizeof(PNP_ADAPTER_TAG));
|
||||
if (NULL == adapterT) {
|
||||
|
||||
}
|
||||
|
||||
adapterT->adapter = adapter;
|
||||
adapterT->pnpInterfaceList = singlylinkedlist_create();
|
||||
adapterT->pnpInterfaceListLock = Lock_Init();
|
||||
|
||||
if (!PNPBRIDGE_SUCCESS(result)) {
|
||||
PnpAdapterManager_ReleaseAdapter(adapterT);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
void PnpAdapterManager_ReleaseAdapter(PPNP_ADAPTER_TAG adapterTag) {
|
||||
if (NULL != adapterTag) {
|
||||
if (NULL != adapterTag->pnpInterfaceList) {
|
||||
singlylinkedlist_destroy(adapterTag->pnpInterfaceList);
|
||||
}
|
||||
|
||||
if (NULL != adapterTag->pnpInterfaceListLock) {
|
||||
Lock_Deinit(adapterTag->pnpInterfaceListLock);
|
||||
}
|
||||
|
||||
free(adapterTag);
|
||||
}
|
||||
}
|
||||
|
||||
PNPBRIDGE_RESULT PnpAdapterManager_Create(PPNP_ADAPTER_MANAGER* adapterMgr, JSON_Value* config) {
|
||||
PNPBRIDGE_RESULT result = PNPBRIDGE_OK;
|
||||
PPNP_ADAPTER_MANAGER adapter = NULL;
|
||||
|
@ -45,8 +77,15 @@ PNPBRIDGE_RESULT PnpAdapterManager_Create(PPNP_ADAPTER_MANAGER* adapterMgr, JSON
|
|||
goto exit;
|
||||
}
|
||||
|
||||
adapter->PnpAdapterMap = Map_Create(NULL);
|
||||
if (NULL == adapter->PnpAdapterMap) {
|
||||
adapter->pnpAdapterMap = Map_Create(NULL);
|
||||
if (NULL == adapter->pnpAdapterMap) {
|
||||
result = PNPBRIDGE_FAILED;
|
||||
goto exit;
|
||||
}
|
||||
|
||||
// Create PNP_ADAPTER_HANDLE's
|
||||
adapter->pnpAdapters = calloc(PnpAdapterCount, sizeof(PPNP_ADAPTER_TAG));
|
||||
if (NULL == adapter->pnpAdapters) {
|
||||
result = PNPBRIDGE_FAILED;
|
||||
goto exit;
|
||||
}
|
||||
|
@ -54,36 +93,45 @@ PNPBRIDGE_RESULT PnpAdapterManager_Create(PPNP_ADAPTER_MANAGER* adapterMgr, JSON
|
|||
// Load a list of static modules and build an interface map
|
||||
for (int i = 0; i < PnpAdapterCount; i++) {
|
||||
PPNP_ADAPTER pnpAdapter = PNP_ADAPTER_MANIFEST[i];
|
||||
adapter->pnpAdapters[i] = calloc(1, sizeof(PNP_ADAPTER_TAG));
|
||||
adapter->pnpAdapters[i]->adapter = pnpAdapter;
|
||||
adapter->pnpAdapters[i]->pnpInterfaceList = singlylinkedlist_create();
|
||||
adapter->pnpAdapters[i]->pnpInterfaceListLock = Lock_Init();
|
||||
|
||||
if (NULL == pnpAdapter->Identity) {
|
||||
if (NULL == pnpAdapter->identity) {
|
||||
LogError("Invalid Identity specified for a PnpAdapter");
|
||||
continue;
|
||||
}
|
||||
|
||||
// Validate Pnp Adapter Methods
|
||||
result = PnpAdapterManager_ValidatePnpAdapter(pnpAdapter, adapter->PnpAdapterMap);
|
||||
result = PnpAdapterManager_ValidatePnpAdapter(pnpAdapter, adapter->pnpAdapterMap);
|
||||
if (PNPBRIDGE_OK != result) {
|
||||
LogError("PnpAdapter structure is not initialized properly");
|
||||
goto exit;
|
||||
}
|
||||
|
||||
JSON_Object* initParams = Configuration_GetPnpParameters(config, pnpAdapter->Identity);
|
||||
JSON_Object* initParams = Configuration_GetPnpParameters(config, pnpAdapter->identity);
|
||||
const char* initParamstring = NULL;
|
||||
if (initParams != NULL) {
|
||||
initParamstring = json_serialize_to_string(json_object_get_wrapping_value(initParams));
|
||||
}
|
||||
result = pnpAdapter->Initialize(initParamstring);
|
||||
result = pnpAdapter->initialize(initParamstring);
|
||||
if (PNPBRIDGE_OK != result) {
|
||||
LogError("Failed to initialze a PnpAdapter");
|
||||
continue;
|
||||
}
|
||||
|
||||
Map_Add_Index(adapter->PnpAdapterMap, pnpAdapter->Identity, i);
|
||||
Map_Add_Index(adapter->pnpAdapterMap, pnpAdapter->identity, i);
|
||||
}
|
||||
|
||||
*adapterMgr = adapter;
|
||||
|
||||
exit:
|
||||
if (!PNPBRIDGE_SUCCESS(result)) {
|
||||
if (NULL != adapter) {
|
||||
PnpAdapterManager_Release(adapter);
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
|
@ -92,40 +140,47 @@ void PnpAdapterManager_Release(PPNP_ADAPTER_MANAGER adapter) {
|
|||
const char* const* values;
|
||||
size_t count;
|
||||
|
||||
// Call shutdown on all interfaces
|
||||
if (Map_GetInternals(adapter->PnpAdapterMap, &keys, &values, &count) != MAP_OK) {
|
||||
LogError("Map_GetInternals failed to get all pnp adapters");
|
||||
}
|
||||
else
|
||||
{
|
||||
for (int i = 0; i < (int)count; i++) {
|
||||
int index = values[i][0];
|
||||
PPNP_ADAPTER pnpAdapter = PNP_ADAPTER_MANIFEST[index];
|
||||
if (NULL != pnpAdapter->Shutdown) {
|
||||
pnpAdapter->Shutdown();
|
||||
if (NULL != adapter->pnpAdapterMap) {
|
||||
// Call shutdown on all interfaces
|
||||
if (Map_GetInternals(adapter->pnpAdapterMap, &keys, &values, &count) != MAP_OK) {
|
||||
LogError("Map_GetInternals failed to get all pnp adapters");
|
||||
}
|
||||
else
|
||||
{
|
||||
for (int i = 0; i < (int)count; i++) {
|
||||
int index = values[i][0];
|
||||
PPNP_ADAPTER pnpAdapter = PNP_ADAPTER_MANIFEST[index];
|
||||
if (NULL != pnpAdapter->shutdown) {
|
||||
pnpAdapter->shutdown();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Map_Destroy(adapter->PnpAdapterMap);
|
||||
if (NULL != adapter->pnpAdapters) {
|
||||
free(adapter->pnpAdapters);;
|
||||
}
|
||||
|
||||
Map_Destroy(adapter->pnpAdapterMap);
|
||||
free(adapter);
|
||||
}
|
||||
|
||||
PNPBRIDGE_RESULT PnpAdapterManager_SupportsIdentity(PPNP_ADAPTER_MANAGER adapter, JSON_Object* Message, bool* supported, int* key) {
|
||||
bool containsMessageKey = false;
|
||||
JSON_Object* pnpParams = json_object_get_object(Message, "PnpParameters");
|
||||
char* getIdentity = (char*) json_object_get_string(pnpParams, "Identity");
|
||||
char* interfaceId = NULL;
|
||||
JSON_Object* pnpParams = json_object_get_object(Message, PNP_CONFIG_NAME_PNP_PARAMETERS);
|
||||
char* getIdentity = (char*) json_object_get_string(pnpParams, PNP_CONFIG_IDENTITY_NAME);
|
||||
MAP_RESULT mapResult;
|
||||
|
||||
*supported = false;
|
||||
|
||||
mapResult = Map_ContainsKey(adapter->PnpAdapterMap, getIdentity, &containsMessageKey);
|
||||
mapResult = Map_ContainsKey(adapter->pnpAdapterMap, getIdentity, &containsMessageKey);
|
||||
if (MAP_OK != mapResult || !containsMessageKey) {
|
||||
return PNPBRIDGE_FAILED;
|
||||
}
|
||||
|
||||
// Get the interface ID
|
||||
int index = Map_GetIndexValueFromKey(adapter->PnpAdapterMap, getIdentity);
|
||||
int index = Map_GetIndexValueFromKey(adapter->pnpAdapterMap, getIdentity);
|
||||
|
||||
*supported = true;
|
||||
*key = index;
|
||||
|
@ -138,79 +193,117 @@ PNPBRIDGE_RESULT PnpAdapterManager_SupportsIdentity(PPNP_ADAPTER_MANAGER adapter
|
|||
method will take care of binding it to a module implementing
|
||||
PnP primitives
|
||||
*/
|
||||
PNPBRIDGE_RESULT PnpAdapterManager_CreatePnpInterface(PPNP_ADAPTER_MANAGER adapter, PNP_DEVICE_CLIENT_HANDLE pnpDeviceClientHandle, int key, PNP_INTERFACE_CLIENT_HANDLE* InterfaceClient, PPNPBRIDGE_DEVICE_CHANGE_PAYLOAD DeviceChangePayload) {
|
||||
PNPBRIDGE_RESULT PnpAdapterManager_CreatePnpInterface(PPNP_ADAPTER_MANAGER adapterMgr, PNP_DEVICE_CLIENT_HANDLE pnpDeviceClientHandle,
|
||||
int key, JSON_Object* deviceConfig,
|
||||
PPNPBRIDGE_DEVICE_CHANGE_PAYLOAD DeviceChangePayload)
|
||||
{
|
||||
// Get the module using the key as index
|
||||
PPNP_ADAPTER pnpAdapter = PNP_ADAPTER_MANIFEST[key];
|
||||
PPNP_ADAPTER_TAG pnpAdapter = adapterMgr->pnpAdapters[key];
|
||||
PNP_ADAPTER_CONTEXT_TAG context = { 0 };
|
||||
|
||||
AZURE_UNREFERENCED_PARAMETER(adapter);
|
||||
|
||||
PPNPADAPTER_INTERFACE pnpInterface = malloc(sizeof(PNPADAPTER_INTERFACE));
|
||||
|
||||
//pnpInterface->Interface = InterfaceClient;
|
||||
pnpInterface->key = key;
|
||||
context.adapter = pnpAdapter;
|
||||
context.deviceConfig = deviceConfig;
|
||||
|
||||
// Invoke interface binding method
|
||||
int ret = pnpAdapter->CreatePnpInterface(pnpInterface, pnpDeviceClientHandle, DeviceChangePayload);
|
||||
int ret = pnpAdapter->adapter->createPnpInterface(&context, pnpDeviceClientHandle, DeviceChangePayload);
|
||||
if (ret < 0) {
|
||||
return PNPBRIDGE_FAILED;
|
||||
}
|
||||
|
||||
*InterfaceClient = pnpInterface->Interface;
|
||||
|
||||
return PNPBRIDGE_OK;
|
||||
}
|
||||
|
||||
PNPBRIDGE_RESULT PnpAdapterManager_GetAllInterfaces(PPNP_ADAPTER_MANAGER adapterMgr, PNP_INTERFACE_CLIENT_HANDLE** interfaces , int* count) {
|
||||
int n = 0;
|
||||
|
||||
// Get the number of created interfaces
|
||||
for (int i = 0; i < PnpAdapterCount; i++) {
|
||||
PPNP_ADAPTER_TAG pnpAdapter = adapterMgr->pnpAdapters[i];
|
||||
|
||||
SINGLYLINKEDLIST_HANDLE pnpInterfaces = pnpAdapter->pnpInterfaceList;
|
||||
LIST_ITEM_HANDLE handle = singlylinkedlist_get_head_item(pnpInterfaces);
|
||||
while (NULL != handle) {
|
||||
handle = singlylinkedlist_get_next_item(handle);
|
||||
n++;
|
||||
}
|
||||
}
|
||||
|
||||
// create an array of interface handles
|
||||
PNP_INTERFACE_CLIENT_HANDLE* pnpClientHandles = NULL;
|
||||
{
|
||||
pnpClientHandles = calloc(n, sizeof(PNP_INTERFACE_CLIENT_HANDLE));
|
||||
int x = 0;
|
||||
for (int i = 0; i < PnpAdapterCount; i++) {
|
||||
PPNP_ADAPTER_TAG pnpAdapter = adapterMgr->pnpAdapters[i];
|
||||
|
||||
SINGLYLINKEDLIST_HANDLE pnpInterfaces = pnpAdapter->pnpInterfaceList;
|
||||
LIST_ITEM_HANDLE handle = singlylinkedlist_get_head_item(pnpInterfaces);
|
||||
while (NULL != handle) {
|
||||
PPNPADAPTER_INTERFACE adapterInterface = (PNP_INTERFACE_CLIENT_HANDLE) singlylinkedlist_item_get_value(handle);
|
||||
pnpClientHandles[x] = PnpAdapterInterface_GetPnpInterfaceClient(adapterInterface);
|
||||
handle = singlylinkedlist_get_next_item(handle);
|
||||
x++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
*count = n;
|
||||
*interfaces = pnpClientHandles;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
bool PnpAdapterManager_IsInterfaceIdPublished(PPNP_ADAPTER_MANAGER adapterMgr, const char* interfaceId) {
|
||||
for (int i = 0; i < PnpAdapterCount; i++) {
|
||||
PPNP_ADAPTER_TAG pnpAdapter = adapterMgr->pnpAdapters[i];
|
||||
|
||||
SINGLYLINKEDLIST_HANDLE pnpInterfaces = pnpAdapter->pnpInterfaceList;
|
||||
LIST_ITEM_HANDLE handle = singlylinkedlist_get_head_item(pnpInterfaces);
|
||||
while (NULL != handle) {
|
||||
PPNPADAPTER_INTERFACE adapterInterface = (PNP_INTERFACE_CLIENT_HANDLE)singlylinkedlist_item_get_value(handle);
|
||||
if (stricmp(adapterInterface->interfaceId, interfaceId)) {
|
||||
return true;
|
||||
}
|
||||
handle = singlylinkedlist_get_next_item(handle);
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
PNPBRIDGE_RESULT PnpAdapterManager_ReleasePnpInterface(PPNP_ADAPTER_MANAGER adapter, PNPADAPTER_INTERFACE_HANDLE interfaceClient) {
|
||||
if (NULL == interfaceClient) {
|
||||
return PNPBRIDGE_INVALID_ARGS;
|
||||
}
|
||||
|
||||
AZURE_UNREFERENCED_PARAMETER(adapter);
|
||||
|
||||
PPNPADAPTER_INTERFACE pnpInterface = (PPNPADAPTER_INTERFACE)interfaceClient;
|
||||
|
||||
// Get the module index
|
||||
PPNP_ADAPTER pnpAdapter = PNP_ADAPTER_MANIFEST[pnpInterface->key];
|
||||
pnpAdapter->ReleaseInterface(interfaceClient);
|
||||
//pnpAdapter->releaseInterface(interfaceClient);
|
||||
|
||||
return PNPBRIDGE_OK;
|
||||
}
|
||||
|
||||
PNP_INTERFACE_CLIENT_HANDLE PnpAdapter_GetPnpInterfaceClient(PNPADAPTER_INTERFACE_HANDLE pnpInterfaceClient) {
|
||||
if (pnpInterfaceClient == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
void PnpAdapterManager_AddInterface(PPNP_ADAPTER_TAG adapter, PNPADAPTER_INTERFACE_HANDLE pnpAdapterInterface) {
|
||||
LIST_ITEM_HANDLE handle = NULL;
|
||||
Lock(adapter->pnpInterfaceListLock);
|
||||
handle = singlylinkedlist_add(adapter->pnpInterfaceList, pnpAdapterInterface);
|
||||
Unlock(adapter->pnpInterfaceListLock);
|
||||
|
||||
PPNPADAPTER_INTERFACE interfaceClient = (PPNPADAPTER_INTERFACE)pnpInterfaceClient;
|
||||
return interfaceClient->Interface;
|
||||
if (NULL != handle) {
|
||||
PPNPADAPTER_INTERFACE interface = (PPNPADAPTER_INTERFACE)pnpAdapterInterface;
|
||||
interface->adapterEntry = handle;
|
||||
}
|
||||
}
|
||||
|
||||
void PnpAdapter_SetPnpInterfaceClient(PNPADAPTER_INTERFACE_HANDLE pnpInterface, PNP_INTERFACE_CLIENT_HANDLE pnpInterfaceClient) {
|
||||
if (pnpInterfaceClient == NULL) {
|
||||
LogError("pnpInterface argument is NULL");
|
||||
void PnpAdapterManager_RemoveInterface(PPNP_ADAPTER_TAG adapter, PNPADAPTER_INTERFACE_HANDLE pnpAdapterInterface) {
|
||||
PPNPADAPTER_INTERFACE interface = (PPNPADAPTER_INTERFACE)pnpAdapterInterface;
|
||||
if (NULL == interface->adapterEntry) {
|
||||
return;
|
||||
}
|
||||
|
||||
PPNPADAPTER_INTERFACE interfaceClient = (PPNPADAPTER_INTERFACE)pnpInterface;
|
||||
interfaceClient->Interface = pnpInterfaceClient;
|
||||
}
|
||||
|
||||
PNPBRIDGE_RESULT PnpAdapter_SetContext(PNPADAPTER_INTERFACE_HANDLE pnpInterfaceClient, void* Context) {
|
||||
if (NULL == pnpInterfaceClient) {
|
||||
return PNPBRIDGE_INVALID_ARGS;
|
||||
}
|
||||
|
||||
PPNPADAPTER_INTERFACE interfaceClient = (PPNPADAPTER_INTERFACE)pnpInterfaceClient;
|
||||
interfaceClient->Context = Context;
|
||||
|
||||
return PNPBRIDGE_OK;
|
||||
}
|
||||
|
||||
void* PnpAdapter_GetContext(PNPADAPTER_INTERFACE_HANDLE PnpInterfaceClient) {
|
||||
if (NULL == PnpInterfaceClient) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
PPNPADAPTER_INTERFACE pnpInterfaceClient = (PPNPADAPTER_INTERFACE)PnpInterfaceClient;
|
||||
return pnpInterfaceClient->Context;
|
||||
Lock(adapter->pnpInterfaceListLock);
|
||||
singlylinkedlist_remove(adapter->pnpInterfaceList, interface->adapterEntry);
|
||||
Unlock(adapter->pnpInterfaceListLock);
|
||||
}
|
|
@ -1,13 +1,12 @@
|
|||
// Copyright (c) Microsoft. All rights reserved.
|
||||
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
|
||||
|
||||
// DeviceAggregator.cpp : Defines the entry point for the console application.
|
||||
|
||||
#include "PnpBridgeCommon.h"
|
||||
#include "ConfigurationParser.h"
|
||||
#include "DiscoveryManager.h"
|
||||
#include "PnpAdapterInterface.h"
|
||||
#include "PnpAdapterManager.h"
|
||||
#include "IotHubComms.h"
|
||||
|
||||
#include "PnpBridgeh.h"
|
||||
|
||||
|
@ -16,159 +15,112 @@ PPNP_BRIDGE g_PnpBridge = NULL;
|
|||
bool g_Shutdown = false;
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
//const char* connectionString = "HostName=iot-pnp-hub1.azure-devices.net;DeviceId=win-gateway;SharedAccessKey=GfbYy7e2PikTf2qHyabvEDBaJB5S4T+H+b9TbLsXfns=";
|
||||
//const char* connectionString = "HostName=saas-iothub-1529564b-8f58-4871-b721-fe9459308cb1.azure-devices.net;DeviceId=956da476-8b3c-41ce-b405-d2d32bcf5e79;SharedAccessKey=sQcfPeDCZGEJWPI3M3SyB8pD60TNdOw10oFKuv5FBio=";
|
||||
|
||||
typedef struct _PNPBRIDGE_INTERFACE_TAG {
|
||||
PNP_INTERFACE_CLIENT_HANDLE Interface;
|
||||
char* InterfaceName;
|
||||
PPNPADAPTER_INTERFACE pnpAdapterInterface;
|
||||
} PNPBRIDGE_INTERFACE_TAG, *PPNPBRIDGE_INTERFACE_TAG;
|
||||
|
||||
// InitializeIotHubDeviceHandle initializes underlying IoTHub client, creates a device handle with the specified connection string,
|
||||
// and sets some options on this handle prior to beginning.
|
||||
IOTHUB_DEVICE_HANDLE InitializeIotHubDeviceHandle(const char* connectionString)
|
||||
{
|
||||
IOTHUB_DEVICE_HANDLE deviceHandle = NULL;
|
||||
IOTHUB_CLIENT_RESULT iothubClientResult;
|
||||
bool traceOn = true;
|
||||
bool urlEncodeOn = true;
|
||||
|
||||
// TODO: PnP SDK should auto-set OPTION_AUTO_URL_ENCODE_DECODE for MQTT as its strictly required. Need way for IoTHub handle to communicate this back.
|
||||
if (IoTHub_Init() != 0)
|
||||
{
|
||||
LogError("IoTHub_Init failed\n");
|
||||
}
|
||||
else
|
||||
{
|
||||
// Get connection string from config
|
||||
if ((deviceHandle = IoTHubDeviceClient_CreateFromConnectionString(connectionString, MQTT_Protocol)) == NULL)
|
||||
{
|
||||
LogError("Failed to create device handle\n");
|
||||
}
|
||||
else if ((iothubClientResult = IoTHubDeviceClient_SetOption(deviceHandle, OPTION_LOG_TRACE, &traceOn)) != IOTHUB_CLIENT_OK)
|
||||
{
|
||||
LogError("Failed to set option %s, error=%d\n", OPTION_LOG_TRACE, iothubClientResult);
|
||||
IoTHubDeviceClient_Destroy(deviceHandle);
|
||||
deviceHandle = NULL;
|
||||
}
|
||||
else if ((iothubClientResult = IoTHubDeviceClient_SetOption(deviceHandle, OPTION_AUTO_URL_ENCODE_DECODE, &urlEncodeOn)) != IOTHUB_CLIENT_OK)
|
||||
{
|
||||
LogError("Failed to set option %s, error=%d\n", OPTION_AUTO_URL_ENCODE_DECODE, iothubClientResult);
|
||||
IoTHubDeviceClient_Destroy(deviceHandle);
|
||||
deviceHandle = NULL;
|
||||
}
|
||||
|
||||
if (deviceHandle == NULL)
|
||||
{
|
||||
IoTHub_Deinit();
|
||||
}
|
||||
}
|
||||
|
||||
return deviceHandle;
|
||||
}
|
||||
|
||||
void PnpBridge_CoreCleanup() {
|
||||
if (g_PnpBridge->publishedInterfaces) {
|
||||
LIST_ITEM_HANDLE interfaceItem = singlylinkedlist_get_head_item(g_PnpBridge->publishedInterfaces);
|
||||
while (interfaceItem != NULL) {
|
||||
PPNPBRIDGE_INTERFACE_TAG interface = (PPNPBRIDGE_INTERFACE_TAG)singlylinkedlist_item_get_value(interfaceItem);
|
||||
free(interface->Interface);
|
||||
interfaceItem = singlylinkedlist_get_next_item(interfaceItem);
|
||||
}
|
||||
singlylinkedlist_destroy(g_PnpBridge->publishedInterfaces);
|
||||
}
|
||||
if (g_PnpBridge->dispatchLock) {
|
||||
Lock_Deinit(g_PnpBridge->dispatchLock);
|
||||
}
|
||||
}
|
||||
|
||||
PNPBRIDGE_RESULT PnpBridge_Initialize(JSON_Value* config) {
|
||||
const char* connectionString;
|
||||
PNPBRIDGE_RESULT result = PNPBRIDGE_OK;
|
||||
|
||||
connectionString = Configuration_GetConnectionString(config);
|
||||
|
||||
if (NULL == connectionString) {
|
||||
LogError("Connection string not specified in the config\n");
|
||||
return PNPBRIDGE_FAILED;
|
||||
}
|
||||
|
||||
g_PnpBridge = (PPNP_BRIDGE) calloc(1, sizeof(PNP_BRIDGE));
|
||||
|
||||
if (!g_PnpBridge) {
|
||||
LogError("Failed to allocate memory for PnpBridge global");
|
||||
PnpBridge_CoreCleanup();
|
||||
return PNPBRIDGE_INSUFFICIENT_MEMORY;
|
||||
}
|
||||
|
||||
g_PnpBridge->configuration = config;
|
||||
|
||||
g_PnpBridge->publishedInterfaces = singlylinkedlist_create();
|
||||
if (NULL == g_PnpBridge->publishedInterfaces) {
|
||||
LogError("Failed to allocate memory publish interface list");
|
||||
PnpBridge_CoreCleanup();
|
||||
return PNPBRIDGE_INSUFFICIENT_MEMORY;
|
||||
}
|
||||
|
||||
g_PnpBridge->publishedInterfaceCount = 0;
|
||||
|
||||
g_PnpBridge->dispatchLock = Lock_Init();
|
||||
if (NULL == g_PnpBridge->dispatchLock) {
|
||||
LogError("Failed to init PnpBridge lock");
|
||||
PnpBridge_CoreCleanup();
|
||||
return PNPBRIDGE_INSUFFICIENT_MEMORY;
|
||||
}
|
||||
|
||||
g_Shutdown = false;
|
||||
|
||||
// Connect to Iot Hub and create a PnP device client handle
|
||||
if ((g_PnpBridge->deviceHandle = InitializeIotHubDeviceHandle(connectionString)) == NULL)
|
||||
TRY
|
||||
{
|
||||
LogError("Could not allocate IoTHub Device handle\n");
|
||||
PnpBridge_CoreCleanup();
|
||||
return PNPBRIDGE_FAILED;
|
||||
}
|
||||
else if ((g_PnpBridge->pnpDeviceClientHandle = PnP_DeviceClient_CreateFromDeviceHandle(g_PnpBridge->deviceHandle)) == NULL)
|
||||
{
|
||||
LogError("PnP_DeviceClient_CreateFromDeviceHandle failed\n");
|
||||
PnpBridge_CoreCleanup();
|
||||
return PNPBRIDGE_FAILED;
|
||||
}
|
||||
if (NULL == connectionString) {
|
||||
LogError("Connection string not specified in the config\n");
|
||||
result = PNPBRIDGE_FAILED;
|
||||
LEAVE;
|
||||
}
|
||||
|
||||
return PNPBRIDGE_OK;
|
||||
g_PnpBridge = (PPNP_BRIDGE)calloc(1, sizeof(PNP_BRIDGE));
|
||||
|
||||
if (NULL == g_PnpBridge) {
|
||||
LogError("Failed to allocate memory for PnpBridge global");
|
||||
result = PNPBRIDGE_INSUFFICIENT_MEMORY;
|
||||
LEAVE;
|
||||
}
|
||||
|
||||
g_PnpBridge->configuration = config;
|
||||
|
||||
g_PnpBridge->dispatchLock = Lock_Init();
|
||||
if (NULL == g_PnpBridge->dispatchLock) {
|
||||
LogError("Failed to init PnpBridge lock");
|
||||
result = PNPBRIDGE_INSUFFICIENT_MEMORY;
|
||||
LEAVE;
|
||||
}
|
||||
|
||||
g_Shutdown = false;
|
||||
|
||||
// Connect to Iot Hub and create a PnP device client handle
|
||||
if ((g_PnpBridge->deviceHandle = InitializeIotHubDeviceHandle(connectionString)) == NULL)
|
||||
{
|
||||
LogError("Could not allocate IoTHub Device handle\n");
|
||||
result = PNPBRIDGE_FAILED;
|
||||
LEAVE;
|
||||
}
|
||||
else if ((g_PnpBridge->pnpDeviceClientHandle = PnP_DeviceClient_CreateFromDeviceHandle(g_PnpBridge->deviceHandle)) == NULL)
|
||||
{
|
||||
LogError("PnP_DeviceClient_CreateFromDeviceHandle failed\n");
|
||||
result = PNPBRIDGE_FAILED;
|
||||
LEAVE;
|
||||
}
|
||||
}
|
||||
FINALLY
|
||||
{
|
||||
if (PNPBRIDGE_OK != result) {
|
||||
PnpBridge_Release(g_PnpBridge);
|
||||
g_PnpBridge = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
void PnpBridge_Release() {
|
||||
void PnpBridge_Release(PPNP_BRIDGE pnpBridge) {
|
||||
if (NULL == pnpBridge) {
|
||||
return;
|
||||
}
|
||||
|
||||
LogInfo("Cleaning DeviceAggregator resources");
|
||||
|
||||
Lock(g_PnpBridge->dispatchLock);
|
||||
if (pnpBridge->dispatchLock) {
|
||||
Lock(g_PnpBridge->dispatchLock);
|
||||
}
|
||||
|
||||
// Stop Disovery Modules
|
||||
if (g_PnpBridge->discoveryMgr) {
|
||||
DiscoveryAdapterManager_Stop(g_PnpBridge->discoveryMgr);
|
||||
g_PnpBridge->discoveryMgr = NULL;
|
||||
if (pnpBridge->discoveryMgr) {
|
||||
DiscoveryAdapterManager_Stop(pnpBridge->discoveryMgr);
|
||||
pnpBridge->discoveryMgr = NULL;
|
||||
}
|
||||
|
||||
// Stop Pnp Modules
|
||||
if (g_PnpBridge->interfaceMgr) {
|
||||
PnpAdapterManager_Release(g_PnpBridge->interfaceMgr);
|
||||
g_PnpBridge->interfaceMgr = NULL;
|
||||
if (pnpBridge->adapterMgr) {
|
||||
PnpAdapterManager_Release(pnpBridge->adapterMgr);
|
||||
pnpBridge->adapterMgr = NULL;
|
||||
}
|
||||
|
||||
Unlock(g_PnpBridge->dispatchLock);
|
||||
if (pnpBridge->dispatchLock) {
|
||||
Unlock(pnpBridge->dispatchLock);
|
||||
Lock_Deinit(pnpBridge->dispatchLock);
|
||||
}
|
||||
|
||||
PnpBridge_CoreCleanup();
|
||||
|
||||
if (g_PnpBridge) {
|
||||
free(g_PnpBridge);
|
||||
if (pnpBridge) {
|
||||
free(pnpBridge);
|
||||
}
|
||||
}
|
||||
|
||||
int PnpBridge_Worker_Thread(void* threadArgument)
|
||||
{
|
||||
AZURE_UNREFERENCED_PARAMETER(threadArgument);
|
||||
PNPBRIDGE_RESULT result = PNPBRIDGE_OK;
|
||||
|
||||
// Publish persistent Pnp Interfaces
|
||||
result = DiscoveryAdapterManager_NotifyPersistentInterfaces(g_PnpBridge->discoveryMgr, g_PnpBridge->configuration);
|
||||
if (!PNPBRIDGE_SUCCESS(result)) {
|
||||
goto exit;
|
||||
}
|
||||
|
||||
// Start Device Discovery
|
||||
result = DiscoveryAdapterManager_Start(g_PnpBridge->discoveryMgr, g_PnpBridge->configuration);
|
||||
if (PNPBRIDGE_OK != result) {
|
||||
|
@ -188,65 +140,6 @@ exit:
|
|||
return result;
|
||||
}
|
||||
|
||||
// State of PnP registration process. We cannot proceed with PnP until we get into the state APP_PNP_REGISTRATION_SUCCEEDED.
|
||||
typedef enum APP_PNP_REGISTRATION_STATUS_TAG
|
||||
{
|
||||
APP_PNP_REGISTRATION_PENDING,
|
||||
APP_PNP_REGISTRATION_SUCCEEDED,
|
||||
APP_PNP_REGISTRATION_FAILED
|
||||
} APP_PNP_REGISTRATION_STATUS;
|
||||
|
||||
// appPnpInterfacesRegistered is invoked when the interfaces have been registered or failed.
|
||||
void appPnpInterfacesRegistered(PNP_REPORTED_INTERFACES_STATUS pnpInterfaceStatus, void *userContextCallback)
|
||||
{
|
||||
APP_PNP_REGISTRATION_STATUS* appPnpRegistrationStatus = (APP_PNP_REGISTRATION_STATUS*)userContextCallback;
|
||||
*appPnpRegistrationStatus = (pnpInterfaceStatus == PNP_REPORTED_INTERFACES_OK) ? APP_PNP_REGISTRATION_SUCCEEDED : APP_PNP_REGISTRATION_FAILED;
|
||||
}
|
||||
|
||||
// Invokes PnP_DeviceClient_RegisterInterfacesAsync, which indicates to Azure IoT which PnP interfaces this device supports.
|
||||
// The PnP Handle *is not valid* until this operation has completed (as indicated by the callback appPnpInterfacesRegistered being invoked).
|
||||
// In this sample, we block indefinitely but production code should include a timeout.
|
||||
int AppRegisterPnPInterfacesAndWait(PNP_DEVICE_CLIENT_HANDLE pnpDeviceClientHandle)
|
||||
{
|
||||
APP_PNP_REGISTRATION_STATUS appPnpRegistrationStatus = APP_PNP_REGISTRATION_PENDING;
|
||||
PNPBRIDGE_RESULT result;
|
||||
PNP_CLIENT_RESULT pnpResult;
|
||||
PPNPBRIDGE_INTERFACE_TAG* interfaceTags = malloc(sizeof(PPNPBRIDGE_INTERFACE_TAG)*g_PnpBridge->publishedInterfaceCount);
|
||||
PNP_INTERFACE_CLIENT_HANDLE* interfaceClients = malloc(sizeof(PNP_INTERFACE_CLIENT_HANDLE)*g_PnpBridge->publishedInterfaceCount);
|
||||
LIST_ITEM_HANDLE interfaceItem = singlylinkedlist_get_head_item(g_PnpBridge->publishedInterfaces);
|
||||
int i = 0;
|
||||
|
||||
while (interfaceItem != NULL) {
|
||||
PNP_INTERFACE_CLIENT_HANDLE interface = ((PPNPBRIDGE_INTERFACE_TAG) singlylinkedlist_item_get_value(interfaceItem))->Interface;
|
||||
interfaceClients[i++] = interface;
|
||||
interfaceItem = singlylinkedlist_get_next_item(interfaceItem);
|
||||
}
|
||||
|
||||
pnpResult = PnP_DeviceClient_RegisterInterfacesAsync(pnpDeviceClientHandle, interfaceClients, g_PnpBridge->publishedInterfaceCount, appPnpInterfacesRegistered, &appPnpRegistrationStatus);
|
||||
if (PNP_CLIENT_OK != pnpResult) {
|
||||
result = PNPBRIDGE_FAILED;
|
||||
goto end;
|
||||
}
|
||||
|
||||
while (appPnpRegistrationStatus == APP_PNP_REGISTRATION_PENDING) {
|
||||
ThreadAPI_Sleep(100);
|
||||
}
|
||||
|
||||
if (appPnpRegistrationStatus != APP_PNP_REGISTRATION_SUCCEEDED) {
|
||||
LogError("PnP has failed to register.\n");
|
||||
result = __FAILURE__;
|
||||
}
|
||||
else {
|
||||
result = 0;
|
||||
}
|
||||
|
||||
end:
|
||||
free(interfaceClients);
|
||||
free(interfaceTags);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
PNPBRIDGE_RESULT PnpBridge_ValidateDeviceChangePayload(PPNPBRIDGE_DEVICE_CHANGE_PAYLOAD DeviceChangePayload) {
|
||||
if (NULL == DeviceChangePayload) {
|
||||
return PNPBRIDGE_INVALID_ARGS;
|
||||
|
@ -260,10 +153,6 @@ PNPBRIDGE_RESULT PnpBridge_ValidateDeviceChangePayload(PPNPBRIDGE_DEVICE_CHANGE_
|
|||
return PNPBRIDGE_INVALID_ARGS;
|
||||
}
|
||||
|
||||
//if (PNPBRIDGE_INTERFACE_CHANGE_INVALID == DeviceChangePayload->ChangeType) {
|
||||
// return PNPBRIDGE_INVALID_ARGS;
|
||||
//}
|
||||
|
||||
return PNPBRIDGE_OK;
|
||||
}
|
||||
|
||||
|
@ -290,20 +179,23 @@ PNPBRIDGE_RESULT PnpBridge_DeviceChangeCallback(PPNPBRIDGE_DEVICE_CHANGE_PAYLOAD
|
|||
JSON_Object* jdevice;
|
||||
|
||||
jmsg = json_parse_string(DeviceChangePayload->Message);
|
||||
if (NULL == jmsg) {
|
||||
goto end;
|
||||
}
|
||||
|
||||
jobj = json_value_get_object(jmsg);
|
||||
if (Configuration_IsDeviceConfigured(g_PnpBridge->configuration, jobj, &jdevice) < 0) {
|
||||
LogInfo("Device is not configured. Dropping the change notification");
|
||||
goto end;
|
||||
}
|
||||
|
||||
result = PnpAdapterManager_SupportsIdentity(g_PnpBridge->interfaceMgr, jdevice, &containsFilter, &key);
|
||||
result = PnpAdapterManager_SupportsIdentity(g_PnpBridge->adapterMgr, jdevice, &containsFilter, &key);
|
||||
if (PNPBRIDGE_OK != result) {
|
||||
goto end;
|
||||
}
|
||||
|
||||
if (containsFilter) {
|
||||
// Create an Azure IoT PNP interface
|
||||
PPNPBRIDGE_INTERFACE_TAG pInt = malloc(sizeof(PNPBRIDGE_INTERFACE_TAG));
|
||||
// Create an Pnp interface
|
||||
char* interfaceId = (char*) json_object_get_string(jobj, "InterfaceId");
|
||||
|
||||
if (interfaceId != NULL) {
|
||||
|
@ -312,31 +204,27 @@ PNPBRIDGE_RESULT PnpBridge_DeviceChangeCallback(PPNPBRIDGE_DEVICE_CHANGE_PAYLOAD
|
|||
strcpy_s(id, idSize, interfaceId);
|
||||
id[idSize - 1] = '\0';
|
||||
|
||||
// check if interface is already published
|
||||
//PPNPBRIDGE_INTERFACE_TAG* interfaceTags = malloc(sizeof(PPNPBRIDGE_INTERFACE_TAG)*g_PnpBridge->publishedInterfaceCount);
|
||||
LIST_ITEM_HANDLE interfaceItem = singlylinkedlist_get_head_item(g_PnpBridge->publishedInterfaces);
|
||||
while (interfaceItem != NULL) {
|
||||
PPNPBRIDGE_INTERFACE_TAG interface = (PPNPBRIDGE_INTERFACE_TAG) singlylinkedlist_item_get_value(interfaceItem);
|
||||
if (strcmp(interface->InterfaceName, id) == 0) {
|
||||
LogError("PnP Interface has already been published. Dropping the change notification. \n");
|
||||
result = PNPBRIDGE_FAILED;
|
||||
goto end;
|
||||
}
|
||||
interfaceItem = singlylinkedlist_get_next_item(interfaceItem);
|
||||
if (PnpAdapterManager_IsInterfaceIdPublished(g_PnpBridge->adapterMgr, id)) {
|
||||
LogError("PnP Interface has already been published. Dropping the change notification. \n");
|
||||
result = PNPBRIDGE_FAILED;
|
||||
goto end;
|
||||
}
|
||||
|
||||
pInt->InterfaceName = id;
|
||||
|
||||
result = PnpAdapterManager_CreatePnpInterface(g_PnpBridge->interfaceMgr, g_PnpBridge->pnpDeviceClientHandle, key, &pInt->Interface, DeviceChangePayload);
|
||||
result = PnpAdapterManager_CreatePnpInterface(g_PnpBridge->adapterMgr, g_PnpBridge->pnpDeviceClientHandle, key, jdevice, DeviceChangePayload);
|
||||
if (PNPBRIDGE_OK != result) {
|
||||
goto end;
|
||||
}
|
||||
|
||||
g_PnpBridge->publishedInterfaceCount++;
|
||||
singlylinkedlist_add(g_PnpBridge->publishedInterfaces, pInt);
|
||||
// Query all the pnp interface clients and publish them
|
||||
{
|
||||
PNP_INTERFACE_CLIENT_HANDLE* interfaces = NULL;
|
||||
int count = 0;
|
||||
PnpAdapterManager_GetAllInterfaces(g_PnpBridge->adapterMgr, &interfaces, &count);
|
||||
|
||||
LogInfo("Publishing Azure Pnp Interface %s\n", interfaceId);
|
||||
AppRegisterPnPInterfacesAndWait(g_PnpBridge->pnpDeviceClientHandle);
|
||||
LogInfo("Publishing Azure Pnp Interface %s\n", interfaceId);
|
||||
AppRegisterPnPInterfacesAndWait(g_PnpBridge->pnpDeviceClientHandle, interfaces, count);
|
||||
free(interfaces);
|
||||
}
|
||||
|
||||
goto end;
|
||||
}
|
||||
|
@ -375,7 +263,7 @@ PNPBRIDGE_RESULT PnpBridge_Main() {
|
|||
// Load all the adapters in interface manifest that implement Azure IoT PnP Interface
|
||||
// PnpBridge will call into corresponding adapter when a device is reported by
|
||||
// DiscoveryExtension
|
||||
result = PnpAdapterManager_Create(&g_PnpBridge->interfaceMgr, g_PnpBridge->configuration);
|
||||
result = PnpAdapterManager_Create(&g_PnpBridge->adapterMgr, g_PnpBridge->configuration);
|
||||
if (PNPBRIDGE_OK != result) {
|
||||
LogError("PnpAdapterManager_Create failed: %d\n", result);
|
||||
goto exit;
|
||||
|
@ -399,7 +287,7 @@ PNPBRIDGE_RESULT PnpBridge_Main() {
|
|||
}
|
||||
|
||||
exit:
|
||||
PnpBridge_Release();
|
||||
PnpBridge_Release(g_PnpBridge);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
|
|
@ -1,6 +1,14 @@
|
|||
// Copyright (c) Microsoft. All rights reserved.
|
||||
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
|
||||
|
||||
/*
|
||||
___ ___ _ _
|
||||
| _ \_ _ _ __| _ )_ _(_)__| |__ _ ___
|
||||
| _/ ' \| '_ \ _ \ '_| / _` / _` / -_)
|
||||
|_| |_||_| .__/___/_| |_\__,_\__, \___|
|
||||
|_| |___/
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
@ -9,10 +17,12 @@ extern "C"
|
|||
#endif
|
||||
|
||||
#include <pnp_interface_client.h>
|
||||
#include <core/PnpBridgeMemory.h>
|
||||
|
||||
typedef enum _PNPBRIDGE_INTERFACE_CHANGE_TYPE {
|
||||
PNPBRIDGE_INTERFACE_CHANGE_INVALID,
|
||||
PNPBRIDGE_INTERFACE_CHANGE_ARRIVAL,
|
||||
PNPBRIDGE_INTERFACE_CHANGE_PERSIST,
|
||||
PNPBRIDGE_INTERFACE_CHANGE_REMOVAL
|
||||
} PNPBRIDGE_INTERFACE_CHANGE_TYPE;
|
||||
|
||||
|
|
|
@ -0,0 +1 @@
|
|||
C:\Program Files (x86)\Microsoft Visual Studio\2019\Preview\MSBuild\Current\Bin\Microsoft.Common.CurrentVersion.targets(775,5): error : The OutputPath property is not set for project 'PnpBridge.vcxproj'. Please check to make sure that you have specified a valid combination of Configuration and Platform for this project. Configuration='Debug' Platform='x64'. This error may also appear if some other project is trying to follow a project-to-project reference to this project, this project has been unloaded or is not included in the solution, and the referencing project does not build using the same or an equivalent Configuration or Platform.
|
|
@ -23,7 +23,7 @@
|
|||
<ProjectGuid>{8756FD40-34AF-4000-AAB9-C2A14E75B23B}</ProjectGuid>
|
||||
<Keyword>Win32Proj</Keyword>
|
||||
<RootNamespace>PnpBridge</RootNamespace>
|
||||
<WindowsTargetPlatformVersion>10.0.17134.0</WindowsTargetPlatformVersion>
|
||||
<WindowsTargetPlatformVersion>10.0.17763.0</WindowsTargetPlatformVersion>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
|
||||
|
@ -155,9 +155,6 @@
|
|||
<AdditionalDependencies>..\..\deps\azure-iot-sdk-c-pnp\$(Platform)_$(Configuration)\$(Configuration)\parson.lib;..\..\deps\azure-iot-sdk-c-pnp\$(Platform)_$(Configuration)\iothub_client\$(Configuration)\iothub_client.lib;..\..\deps\azure-iot-sdk-c-pnp\$(Platform)_$(Configuration)\pnp_client\$(Configuration)\pnp_client.lib;..\..\deps\azure-iot-sdk-c-pnp\$(Platform)_$(Configuration)\iothub_client\$(Configuration)\iothub_client_http_transport.lib;..\..\deps\azure-iot-sdk-c-pnp\$(Platform)_$(Configuration)\iothub_client\$(Configuration)\iothub_client_amqp_transport.lib;..\..\deps\azure-iot-sdk-c-pnp\$(Platform)_$(Configuration)\iothub_client\$(Configuration)\iothub_client_amqp_ws_transport.lib;..\..\deps\azure-iot-sdk-c-pnp\$(Platform)_$(Configuration)\iothub_client\$(Configuration)\iothub_client_mqtt_transport.lib;..\..\deps\azure-iot-sdk-c-pnp\$(Platform)_$(Configuration)\iothub_client\$(Configuration)\iothub_client_mqtt_ws_transport.lib;..\..\deps\azure-iot-sdk-c-pnp\$(Platform)_$(Configuration)\umqtt\$(Configuration)\umqtt.lib;..\..\deps\azure-iot-sdk-c-pnp\$(Platform)_$(Configuration)\$(Configuration)\parson.lib;..\..\deps\azure-iot-sdk-c-pnp\$(Platform)_$(Configuration)\c-utility\$(Configuration)\aziotsharedutil.lib;crypt32.lib;winhttp.lib;crypt32.lib;winhttp.lib;ws2_32.lib;secur32.lib;advapi32.lib;ncrypt.lib;rpcrt4.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;comdlg32.lib;advapi32.lib;Cfgmgr32.lib;mfplat.lib;mfsensorgroup.lib</AdditionalDependencies>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemGroup>
|
||||
<Text Include="ReadMe.txt" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="Adapters\Camera\CameraCaptureEngine.h" />
|
||||
<ClInclude Include="Adapters\Camera\CameraCaptureEngineCallbacks.h" />
|
||||
|
@ -167,8 +164,10 @@
|
|||
<ClInclude Include="Adapters\Camera\CameraStatConsumer.h" />
|
||||
<ClInclude Include="Adapters\Camera\JsonWrapper.h" />
|
||||
<ClInclude Include="Adapters\Camera\pch.h" />
|
||||
<ClInclude Include="adapters\CmdAndPropHandler.h" />
|
||||
<ClInclude Include="Adapters\CoreDeviceHealth\CoreDeviceHealth.h" />
|
||||
<ClInclude Include="Adapters\CoreDeviceHealth\WindowsPnpDeviceDiscovery.h" />
|
||||
<ClInclude Include="IotHubComms.h" />
|
||||
<ClInclude Include="PnpBridge.h" />
|
||||
<ClInclude Include="ConfigurationParser.h" />
|
||||
<ClInclude Include="DiscoveryAdapterInterface.h" />
|
||||
|
@ -193,6 +192,9 @@
|
|||
<ClCompile Include="Adapters\CoreDeviceHealth\WindowsPnPDeviceDiscovery.c" />
|
||||
<ClCompile Include="Adapters\SerialPnp\SerialPnp.c" />
|
||||
<ClCompile Include="ConfigurationParser.c" />
|
||||
<ClCompile Include="core\PnpAdapterInterface.c" />
|
||||
<ClCompile Include="core\PnpBridgeMemory.c" />
|
||||
<ClCompile Include="IotHubComms.c" />
|
||||
<ClCompile Include="PnpBridge.c" />
|
||||
<ClCompile Include="DiscoveryManager.c" />
|
||||
<ClCompile Include="PnpAdapterManger.c" />
|
||||
|
@ -200,7 +202,6 @@
|
|||
<ClCompile Include="utility.c" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<None Include="CmdAndPropHandler.h" />
|
||||
<None Include="config.json">
|
||||
<DeploymentContent>true</DeploymentContent>
|
||||
</None>
|
||||
|
|
|
@ -13,27 +13,24 @@
|
|||
<UniqueIdentifier>{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}</UniqueIdentifier>
|
||||
<Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms</Extensions>
|
||||
</Filter>
|
||||
<Filter Include="Source Files\Adapters">
|
||||
<UniqueIdentifier>{3524bf36-1d0b-46dc-ada9-78d0803fe1ec}</UniqueIdentifier>
|
||||
</Filter>
|
||||
<Filter Include="Source Files\Adapters\CoreDeviceHealth">
|
||||
<UniqueIdentifier>{28fe5595-e94e-4bac-ac50-03299b219cd8}</UniqueIdentifier>
|
||||
</Filter>
|
||||
<Filter Include="Source Files\inc">
|
||||
<UniqueIdentifier>{92a538f9-7056-4277-a567-906bc28ce6a8}</UniqueIdentifier>
|
||||
</Filter>
|
||||
<Filter Include="Source Files\Adapters\Camera">
|
||||
<Filter Include="Source Files\core">
|
||||
<UniqueIdentifier>{2ed2ef04-8f74-4d43-87b5-1da519b4d2f3}</UniqueIdentifier>
|
||||
</Filter>
|
||||
<Filter Include="Source Files\adapters">
|
||||
<UniqueIdentifier>{3524bf36-1d0b-46dc-ada9-78d0803fe1ec}</UniqueIdentifier>
|
||||
</Filter>
|
||||
<Filter Include="Source Files\adapters\CoreDeviceHealth">
|
||||
<UniqueIdentifier>{28fe5595-e94e-4bac-ac50-03299b219cd8}</UniqueIdentifier>
|
||||
</Filter>
|
||||
<Filter Include="Source Files\adapters\Camera">
|
||||
<UniqueIdentifier>{83239274-3c8a-4c29-a27a-4d7aafc2f2e3}</UniqueIdentifier>
|
||||
</Filter>
|
||||
<Filter Include="Source Files\Adapters\SerialPnp">
|
||||
<Filter Include="Source Files\adapters\SerialPnp">
|
||||
<UniqueIdentifier>{611fd0c7-a77f-4116-bf8a-c41bded6d8a3}</UniqueIdentifier>
|
||||
</Filter>
|
||||
<Filter Include="Source Files\Adapters\Sample">
|
||||
<UniqueIdentifier>{05fcc339-7478-4508-9685-0279a2e32c46}</UniqueIdentifier>
|
||||
</Filter>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Text Include="ReadMe.txt" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="targetver.h">
|
||||
|
@ -55,34 +52,34 @@
|
|||
<Filter>Source Files\inc</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="Adapters\CoreDeviceHealth\WindowsPnpDeviceDiscovery.h">
|
||||
<Filter>Source Files\Adapters\CoreDeviceHealth</Filter>
|
||||
<Filter>Source Files\adapters\CoreDeviceHealth</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="PnpBridgeCommon.h">
|
||||
<Filter>Source Files\inc</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="Adapters\CoreDeviceHealth\CoreDeviceHealth.h">
|
||||
<Filter>Source Files\Adapters\CoreDeviceHealth</Filter>
|
||||
<Filter>Source Files\adapters\CoreDeviceHealth</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="Adapters\Camera\CameraIotPnpDevice.h">
|
||||
<Filter>Source Files\Adapters\Camera</Filter>
|
||||
<Filter>Source Files\adapters\Camera</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="Adapters\Camera\CameraPnpDiscovery.h">
|
||||
<Filter>Source Files\Adapters\Camera</Filter>
|
||||
<Filter>Source Files\adapters\Camera</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="Adapters\Camera\CameraStatConsumer.h">
|
||||
<Filter>Source Files\Adapters\Camera</Filter>
|
||||
<Filter>Source Files\adapters\Camera</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="Adapters\Camera\pch.h">
|
||||
<Filter>Source Files\Adapters\Camera</Filter>
|
||||
<Filter>Source Files\adapters\Camera</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="Adapters\Camera\JsonWrapper.h">
|
||||
<Filter>Source Files\Adapters\Camera</Filter>
|
||||
<Filter>Source Files\adapters\Camera</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="Adapters\Camera\CameraIotPnpAPIs.h">
|
||||
<Filter>Source Files\Adapters\Camera</Filter>
|
||||
<Filter>Source Files\adapters\Camera</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="Adapters\SerialPnp\SerialPnp.h">
|
||||
<Filter>Source Files\Adapters\SerialPnp</Filter>
|
||||
<Filter>Source Files\adapters\SerialPnp</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="PnpBridgeh.h">
|
||||
<Filter>Source Files\inc</Filter>
|
||||
|
@ -91,10 +88,16 @@
|
|||
<Filter>Source Files\inc</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="Adapters\Camera\CameraCaptureEngine.h">
|
||||
<Filter>Source Files\Adapters\Camera</Filter>
|
||||
<Filter>Source Files\adapters\Camera</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="Adapters\Camera\CameraCaptureEngineCallbacks.h">
|
||||
<Filter>Source Files\Adapters\Camera</Filter>
|
||||
<Filter>Source Files\adapters\Camera</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="adapters\CmdAndPropHandler.h">
|
||||
<Filter>Source Files\adapters</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="IotHubComms.h">
|
||||
<Filter>Source Files\inc</Filter>
|
||||
</ClInclude>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
|
@ -108,7 +111,7 @@
|
|||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="Adapters\CoreDeviceHealth\WindowsPnPDeviceDiscovery.c">
|
||||
<Filter>Source Files\Adapters\CoreDeviceHealth</Filter>
|
||||
<Filter>Source Files\adapters\CoreDeviceHealth</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="PnpAdapterManger.c">
|
||||
<Filter>Source Files</Filter>
|
||||
|
@ -120,40 +123,46 @@
|
|||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="Adapters\CoreDeviceHealth\CoreDeviceHealth.c">
|
||||
<Filter>Source Files\Adapters\CoreDeviceHealth</Filter>
|
||||
<Filter>Source Files\adapters\CoreDeviceHealth</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="Adapters\Camera\CameraIotPnpDevice.cpp">
|
||||
<Filter>Source Files\Adapters\Camera</Filter>
|
||||
<Filter>Source Files\adapters\Camera</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="Adapters\Camera\CameraPnpDiscovery.cpp">
|
||||
<Filter>Source Files\Adapters\Camera</Filter>
|
||||
<Filter>Source Files\adapters\Camera</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="Adapters\Camera\CameraStatConsumer.cpp">
|
||||
<Filter>Source Files\Adapters\Camera</Filter>
|
||||
<Filter>Source Files\adapters\Camera</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="Adapters\Camera\JsonWrapper.cpp">
|
||||
<Filter>Source Files\Adapters\Camera</Filter>
|
||||
<Filter>Source Files\adapters\Camera</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="Adapters\Camera\CameraIotPnpAPIs.cpp">
|
||||
<Filter>Source Files\Adapters\Camera</Filter>
|
||||
<Filter>Source Files\adapters\Camera</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="Adapters\SerialPnp\SerialPnp.c">
|
||||
<Filter>Source Files\Adapters\SerialPnp</Filter>
|
||||
<Filter>Source Files\adapters\SerialPnp</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="Adapters\AdapterManifest.c">
|
||||
<Filter>Source Files\Adapters</Filter>
|
||||
<Filter>Source Files\adapters</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="Adapters\Camera\CameraCaptureEngine.cpp">
|
||||
<Filter>Source Files\Adapters\Camera</Filter>
|
||||
<Filter>Source Files\adapters\Camera</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="Adapters\Camera\CameraCaptureEngineCallbacks.cpp">
|
||||
<Filter>Source Files\Adapters\Camera</Filter>
|
||||
<Filter>Source Files\adapters\Camera</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="core\PnpBridgeMemory.c">
|
||||
<Filter>Source Files\core</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="core\PnpAdapterInterface.c">
|
||||
<Filter>Source Files\core</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="IotHubComms.c">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<None Include="config.json" />
|
||||
<None Include="CmdAndPropHandler.h">
|
||||
<Filter>Source Files\Adapters</Filter>
|
||||
</None>
|
||||
</ItemGroup>
|
||||
</Project>
|
|
@ -39,9 +39,11 @@ extern "C"
|
|||
|
||||
#include "parson.h"
|
||||
|
||||
|
||||
/** @brief Enumeration specifying the status of calls to various APIs in this module.
|
||||
*/
|
||||
#define TRY
|
||||
#define LEAVE goto __tryLabel;
|
||||
#define FINALLY goto __tryLabel; __tryLabel:
|
||||
#undef __try
|
||||
#undef __finally
|
||||
|
||||
#define PNPBRIDGE_RESULT_VALUES \
|
||||
PNPBRIDGE_OK, \
|
||||
|
@ -53,6 +55,8 @@ extern "C"
|
|||
|
||||
DEFINE_ENUM(PNPBRIDGE_RESULT, PNPBRIDGE_RESULT_VALUES);
|
||||
|
||||
#define PNPBRIDGE_SUCCESS(Result) (Result == PNPBRIDGE_OK)
|
||||
|
||||
#include "ConfigurationParser.h"
|
||||
|
||||
MAP_RESULT Map_Add_Index(MAP_HANDLE handle, const char* key, int value);
|
||||
|
@ -61,6 +65,17 @@ int Map_GetIndexValueFromKey(MAP_HANDLE handle, const char* key);
|
|||
|
||||
#include <PnpBridge.h>
|
||||
|
||||
#define PNP_CONFIG_IDENTITY_NAME "Identity"
|
||||
#define PNP_CONFIG_INTERFACE_ID_NAME "InterfaceId"
|
||||
#define PNP_CONFIG_PERSISTENT_NAME "Persistent"
|
||||
#define PNP_CONFIG_MATCH_FILTERS_NAME "MatchFilters"
|
||||
#define PNP_CONFIG_MATCH_TYPE_NAME "MatchType"
|
||||
#define PNP_CONFIG_NAME_MATCH_PARAMETERS "MatchParameters"
|
||||
#define PNP_CONFIG_DISCOVERY_ADAPTER_NAME "DiscoveryAdapter"
|
||||
#define PNP_CONFIG_NAME_PNP_PARAMETERS "PnpParameters"
|
||||
#define PNP_CONFIG_NAME_PNP_ADAPTERS "PnpAdapters"
|
||||
#define PNP_CONFIG_NAME_DISCOVERY_ADAPTERS "DiscoveryAdapters"
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
|
|
@ -18,13 +18,7 @@ typedef struct _PNP_BRIDGE {
|
|||
PDISCOVERY_MANAGER discoveryMgr;
|
||||
|
||||
// Manages loading all pnp adapter plugins and their lifetime
|
||||
PPNP_ADAPTER_MANAGER interfaceMgr;
|
||||
|
||||
// List of publised pnp interfaces
|
||||
SINGLYLINKEDLIST_HANDLE publishedInterfaces;
|
||||
|
||||
// Number of published pnp interfaces
|
||||
int publishedInterfaceCount;
|
||||
PPNP_ADAPTER_MANAGER adapterMgr;
|
||||
|
||||
LOCK_HANDLE dispatchLock;
|
||||
|
||||
|
@ -33,6 +27,8 @@ typedef struct _PNP_BRIDGE {
|
|||
|
||||
} PNP_BRIDGE, *PPNP_BRIDGE;
|
||||
|
||||
void PnpBridge_Release(PPNP_BRIDGE pnpBridge);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
|
@ -1,7 +0,0 @@
|
|||
#pragma once
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
#include <pnp_device_client.h>
|
||||
#include "PnPAdapterInterface.h"
|
||||
|
|
@ -18,6 +18,20 @@
|
|||
"Identity": "core-device-health"
|
||||
}
|
||||
},
|
||||
{
|
||||
"_comment": "DEVICE1 - RANDOM device",
|
||||
"MatchFilters": {
|
||||
"MatchType": "Exact",
|
||||
"MatchParameters": {
|
||||
"HardwareId": "USB\\VID_07DE&PID_11F3"
|
||||
}
|
||||
},
|
||||
"Persistent" : "true",
|
||||
"InterfaceId": "http://windows.com/coredevicehealth/v1",
|
||||
"PnpParameters": {
|
||||
"Identity": "core-device-health"
|
||||
}
|
||||
},
|
||||
{
|
||||
"_comment": "DEVICE2 - MCU sensor hub which reports Azure IoT Pnp interfaces",
|
||||
"MatchFilters": {
|
||||
|
|
|
@ -0,0 +1,114 @@
|
|||
// Copyright (c) Microsoft. All rights reserved.
|
||||
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
|
||||
|
||||
#include "PnpBridgeCommon.h"
|
||||
#include "PnpAdapterInterface.h"
|
||||
#include "PnpAdapterManager.h"
|
||||
|
||||
int PnpAdapterInterface_Create(PNPADAPTER_CONTEXT adapterHandle, const char* interfaceId,
|
||||
PNP_INTERFACE_CLIENT_HANDLE pnpInterface,
|
||||
PPNPADAPTER_INTERFACE_HANDLE pnpAdapterInterface,
|
||||
PPNPADPATER_INTERFACE_INIT_PARAMS params)
|
||||
{
|
||||
int result = 0;
|
||||
PPNPADAPTER_INTERFACE interface = NULL;
|
||||
|
||||
TRY
|
||||
{
|
||||
// validate params
|
||||
if (NULL == params) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (NULL == params->releaseInterface || NULL == pnpInterface) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
// Create a pnp adapter interface
|
||||
interface = calloc(1, sizeof(PNPADAPTER_INTERFACE));
|
||||
if (NULL == interface) {
|
||||
LEAVE;
|
||||
}
|
||||
|
||||
interface->pnpInterfaceClient = pnpInterface;
|
||||
interface->interfaceId = malloc(strlen(interfaceId) + 1);
|
||||
if (NULL == interface->interfaceId) {
|
||||
LEAVE;
|
||||
}
|
||||
|
||||
// Make a copy of interface id
|
||||
strcpy_s(interface->interfaceId, strlen(interfaceId)+1, interfaceId);
|
||||
|
||||
// Copy the params
|
||||
memcpy(&interface->params, params, sizeof(interface->params));
|
||||
|
||||
PPNP_ADAPTER_CONTEXT_TAG adapterContext = adapterHandle;
|
||||
|
||||
// Copy adapter context
|
||||
interface->adapterContext = calloc(1, sizeof(PPNP_ADAPTER_CONTEXT_TAG));
|
||||
if (NULL == interface->adapterContext) {
|
||||
LEAVE;
|
||||
}
|
||||
memcpy(&interface->adapterContext, adapterContext, sizeof(interface->adapterContext));
|
||||
|
||||
// Add this interface to the list of interfaces under the adapter context
|
||||
PnpAdapterManager_AddInterface(adapterContext->adapter, interface);
|
||||
|
||||
*pnpAdapterInterface = interface;
|
||||
}
|
||||
FINALLY
|
||||
{
|
||||
if (result < 0) {
|
||||
PnpAdapterInterface_Destroy(interface);
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
void PnpAdapterInterface_Destroy(PNPADAPTER_INTERFACE_HANDLE pnpAdapterInterface) {
|
||||
if (NULL == pnpAdapterInterface) {
|
||||
return;
|
||||
}
|
||||
|
||||
PPNPADAPTER_INTERFACE interface = (PPNPADAPTER_INTERFACE)pnpAdapterInterface;
|
||||
if (NULL != interface->interfaceId) {
|
||||
free(interface->interfaceId);
|
||||
}
|
||||
|
||||
if (NULL != interface->adapterContext) {
|
||||
PPNP_ADAPTER_CONTEXT_TAG adapterContext = (PPNP_ADAPTER_CONTEXT_TAG)interface->adapterContext;
|
||||
if (NULL != interface->adapterEntry) {
|
||||
PnpAdapterManager_RemoveInterface(adapterContext->adapter, pnpAdapterInterface);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
PNP_INTERFACE_CLIENT_HANDLE PnpAdapterInterface_GetPnpInterfaceClient(PNPADAPTER_INTERFACE_HANDLE pnpAdapterInterface) {
|
||||
if (NULL == pnpAdapterInterface) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
PPNPADAPTER_INTERFACE interfaceClient = (PPNPADAPTER_INTERFACE)pnpAdapterInterface;
|
||||
return interfaceClient->pnpInterfaceClient;
|
||||
}
|
||||
|
||||
PNPBRIDGE_RESULT PnpAdapterInterface_SetContext(PNPADAPTER_INTERFACE_HANDLE pnpAdapterInterface, void* context) {
|
||||
if (NULL == pnpAdapterInterface) {
|
||||
return PNPBRIDGE_INVALID_ARGS;
|
||||
}
|
||||
|
||||
PPNPADAPTER_INTERFACE interfaceClient = (PPNPADAPTER_INTERFACE)pnpAdapterInterface;
|
||||
interfaceClient->context = context;
|
||||
|
||||
return PNPBRIDGE_OK;
|
||||
}
|
||||
|
||||
void* PnpAdapterInterface_GetContext(PNPADAPTER_INTERFACE_HANDLE pnpAdapterInterface) {
|
||||
if (NULL == pnpAdapterInterface) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
PPNPADAPTER_INTERFACE adapterInterface = (PPNPADAPTER_INTERFACE)pnpAdapterInterface;
|
||||
return adapterInterface->context;
|
||||
}
|
|
@ -0,0 +1,41 @@
|
|||
#include <stdio.h>
|
||||
#include "azure_c_shared_utility/refcount.h"
|
||||
#include "core/PnpBridgeMemory.h"
|
||||
|
||||
int PnpBridgeMemory_Create(PPNPBRIDGE_OBJECT_PARAMS params, int size, PNPBRIDGE_MEMORY* memory) {
|
||||
if (NULL == params || NULL == params->destroyCallback) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
PPNPBRIDGE_MEMORY_TAG mem = calloc(1, sizeof(PNPBRIDGE_MEMORY_TAG) + size);
|
||||
if (NULL == mem) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
INIT_REF_VAR(mem->count);
|
||||
mem->size = size;
|
||||
|
||||
*memory = (PNPBRIDGE_MEMORY*)mem;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void PnpBridgeMemory_AddReference(PNPBRIDGE_MEMORY memory) {
|
||||
PPNPBRIDGE_MEMORY_TAG mem = (PPNPBRIDGE_MEMORY_TAG)memory;
|
||||
DEC_REF_VAR(mem->count);
|
||||
}
|
||||
|
||||
void PnpBridgeMemory_ReleaseReference(PNPBRIDGE_MEMORY memory) {
|
||||
PPNPBRIDGE_MEMORY_TAG mem = (PPNPBRIDGE_MEMORY_TAG)memory;
|
||||
if (DEC_RETURN_ZERO == DEC_REF_VAR(mem->count)) {
|
||||
mem->params.destroyCallback();
|
||||
}
|
||||
}
|
||||
|
||||
void* PnpMemory_GetBuffer(PNPBRIDGE_MEMORY memory, int* size) {
|
||||
PPNPBRIDGE_MEMORY_TAG mem = (PPNPBRIDGE_MEMORY_TAG)memory;
|
||||
if (NULL != size) {
|
||||
*size = mem->size;
|
||||
}
|
||||
return mem->memory;
|
||||
}
|
|
@ -0,0 +1,39 @@
|
|||
// Copyright (c) Microsoft. All rights reserved.
|
||||
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
|
||||
|
||||
#ifndef PNPBRIDGE_OBJECT_H
|
||||
#define PNPBRIDGE_OBJECT_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C"
|
||||
{
|
||||
#endif
|
||||
|
||||
typedef void* PNPBRIDGE_MEMORY;
|
||||
|
||||
typedef int(*PNPBRIDGE_MEMORY_DESTROY) ();
|
||||
|
||||
typedef struct _PNPBRIDGE_MEMORY_PARAMS {
|
||||
PNPBRIDGE_MEMORY_DESTROY destroyCallback;
|
||||
} PNPBRIDGE_MEMORY_PARAMS, *PPNPBRIDGE_OBJECT_PARAMS;
|
||||
|
||||
typedef struct _PNPBRIDGE_MEMORY_TAG {
|
||||
int count;
|
||||
int size;
|
||||
void* memory;
|
||||
PNPBRIDGE_MEMORY_PARAMS params;
|
||||
} PNPBRIDGE_MEMORY_TAG, *PPNPBRIDGE_MEMORY_TAG;
|
||||
|
||||
int PnpBridgeMemory_Create(PPNPBRIDGE_OBJECT_PARAMS params, int size, PNPBRIDGE_MEMORY* memory);
|
||||
|
||||
void PnpBridgeMemory_AddReference(PNPBRIDGE_MEMORY memory);
|
||||
|
||||
void PnpBridgeMemory_ReleaseReference(PNPBRIDGE_MEMORY memory);
|
||||
|
||||
void* PnpMemory_GetBuffer(PNPBRIDGE_MEMORY memory, int* size);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* PNPBRIDGE_OBJECT_H */
|
|
@ -1,8 +0,0 @@
|
|||
#pragma once
|
||||
|
||||
// Including SDKDDKVer.h defines the highest available Windows platform.
|
||||
|
||||
// If you wish to build your application for a previous Windows platform, include WinSDKVer.h and
|
||||
// set the _WIN32_WINNT macro to the platform you wish to support before including SDKDDKVer.h.
|
||||
|
||||
#include <SDKDDKVer.h>
|
Загрузка…
Ссылка в новой задаче