Update the PnP SDK submodule and modify pnpbridge to work with new API changes (#21)
* Update headers * Pulled latest commit from public-preview-utopia * Updated pnpbridge to work with latest changes from public-preview-utopia * Missing linker deps * add missing files * remove connection string from config * update the sample config * Fix lx build
This commit is contained in:
Родитель
2bc2ab14ef
Коммит
11e5ebe662
|
@ -6,3 +6,4 @@
|
|||
/PnpBridge/src/PnpBridge/Debug
|
||||
/PnpBridge/src/PnpBridge/x64/Debug
|
||||
/PnpBridge/src/PnpBridge/PnpBridge.sln
|
||||
.vscode
|
||||
|
|
|
@ -1,6 +1,3 @@
|
|||
[submodule "PnpBridge/deps/azure-iot-sdk-c-pnp"]
|
||||
path = PnpBridge/deps/azure-iot-sdk-c-pnp
|
||||
url = https://github.com/Azure/azure-iot-sdk-c-pnp
|
||||
[submodule "pnpbridge/deps/azure-iot-sdk-c-pnp"]
|
||||
path = pnpbridge/deps/azure-iot-sdk-c-pnp
|
||||
url = https://github.com/Azure/azure-iot-sdk-c-pnp
|
||||
|
|
|
@ -6,12 +6,6 @@ if (POLICY CMP0042)
|
|||
cmake_policy(SET CMP0042 NEW)
|
||||
endif()
|
||||
|
||||
# Include the common build rules for the C SDK
|
||||
include("${CMAKE_CURRENT_LIST_DIR}/deps/azure-iot-sdk-c-pnp/c-utility/configs/azure_iot_build_rules.cmake")
|
||||
include("${CMAKE_CURRENT_LIST_DIR}/deps/azure-iot-sdk-c-pnp/c-utility/configs/azure_c_shared_utilityFunctions.cmake")
|
||||
include("${CMAKE_CURRENT_LIST_DIR}/deps/azure-iot-sdk-c-pnp/configs/azure_iot_sdksFunctions.cmake")
|
||||
|
||||
#2
|
||||
#set(run_e2e_tests OFF CACHE BOOL "skip e2e tests" FORCE)
|
||||
# TODO: Skip azure c sdk unit tests
|
||||
|
||||
|
@ -24,8 +18,17 @@ set(original_run_unittests ${run_unittests})
|
|||
|
||||
set(run_e2e_tests OFF)
|
||||
set(run_unittests OFF)
|
||||
# TODO check where this is getting set
|
||||
set(use_installed_dependencies OFF)
|
||||
|
||||
set(compileOption_C "" CACHE STRING "passes a string to the command line of the C compiler")
|
||||
set(compileOption_CXX "" CACHE STRING "passes a string to the command line of the C++ compiler")
|
||||
set(linkerOption "" CACHE STRING "passes a string to the shared and exe linker options of the C compiler")
|
||||
|
||||
# Include the common build rules for the C SDK
|
||||
include("${CMAKE_CURRENT_LIST_DIR}/deps/azure-iot-sdk-c-pnp/c-utility/configs/azure_iot_build_rules.cmake")
|
||||
include("${CMAKE_CURRENT_LIST_DIR}/deps/azure-iot-sdk-c-pnp/c-utility/configs/azure_c_shared_utilityFunctions.cmake")
|
||||
include("${CMAKE_CURRENT_LIST_DIR}/deps/azure-iot-sdk-c-pnp/configs/azure_iot_sdksFunctions.cmake")
|
||||
|
||||
#set(use_installed_dependencies OFF)
|
||||
|
||||
if(${original_run_e2e_tests} OR ${original_run_unittests})
|
||||
set(SHARED_UTIL_REAL_TEST_FOLDER ${CMAKE_CURRENT_LIST_DIR}/deps/azure-iot-sdk-c-pnp/c-utility/tests/real_test_files CACHE INTERNAL "this is what needs to be included when doing test sources" FORCE)
|
||||
|
@ -33,19 +36,16 @@ if(${original_run_e2e_tests} OR ${original_run_unittests})
|
|||
enable_testing()
|
||||
endif()
|
||||
|
||||
# Now add the pnp C sdk with test dir flags disabled
|
||||
add_subdirectory(deps/azure-iot-sdk-c-pnp)
|
||||
|
||||
set(run_e2e_tests ${original_run_e2e_tests})
|
||||
set(run_unittests ${original_run_unittests})
|
||||
|
||||
#2
|
||||
|
||||
|
||||
option(run_e2e_tests "set run_e2e_tests to ON to run e2e tests (default is OFF)" OFF)
|
||||
option(run_unittests "set run_unittests to ON to run unittests (default is OFF)" OFF)
|
||||
option(run_int_tests "set run_int_tests to ON to integration tests (default is OFF)." OFF)
|
||||
|
||||
|
||||
# Enable IoT SDK to act as a module for Edge
|
||||
if(${use_edge_modules})
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -DUSE_EDGE_MODULES")
|
||||
|
|
|
@ -1 +1 @@
|
|||
Subproject commit e5f5a95a8ac92ac4e834639d5b41e048ab7d36b6
|
||||
Subproject commit 8a594e43ff6ff16a32a2ebb788708d6e6e21e4da
|
|
@ -271,7 +271,7 @@ echo build.cmd [options]
|
|||
echo options:
|
||||
echo -c, --clean delete artifacts from previous build before building
|
||||
echo --config ^<value^> [Debug] build configuration (e.g. Debug, Release)
|
||||
echo --platform ^<value^> [x64] build platform (e.g. Win32, x64, arm, ...)
|
||||
echo --platform ^<value^> [Win32] build platform (e.g. Win32, x64, arm, ...)
|
||||
echo --winsdkver [10.0.17763.0] windows sdk version
|
||||
echo --make_nuget ^<value^> [no] generates the binaries to be used for nuget packaging (e.g. yes, no)
|
||||
echo --run-e2e-tests run end-to-end tests
|
||||
|
|
|
@ -49,6 +49,8 @@ set(pnp_bridge_INC_FOLDER ${CMAKE_CURRENT_LIST_DIR}/../pnpbridge/inc CACHE INTER
|
|||
include_directories(inc)
|
||||
include_directories(../../deps/azure-iot-sdk-c-pnp/deps/parson)
|
||||
include_directories(../../deps/azure-iot-sdk-c-pnp/c-utility/inc)
|
||||
include_directories(../../deps/azure-iot-sdk-c-pnp/c-utility/deps/azure-macro-utils-c/inc)
|
||||
include_directories(../../deps/azure-iot-sdk-c-pnp/c-utility/deps/umock-c/inc)
|
||||
include_directories(../../deps/azure-iot-sdk-c-pnp/digitaltwin_client/inc)
|
||||
include_directories(../../deps/azure-iot-sdk-c-pnp/iothub_client/inc)
|
||||
|
||||
|
|
|
@ -16,6 +16,7 @@ set(pnpbridge_adaptersample_c_files
|
|||
./environmental_sensor.c
|
||||
./environmental_sensor_pnpbridge_discovery.c
|
||||
./environmental_sensor_pnpbridge.c
|
||||
./adapter_manifest_pnpbridge.c
|
||||
)
|
||||
|
||||
set(pnpbridge_adaptersample_h_files
|
||||
|
@ -30,6 +31,8 @@ set(pnp_bridge_INC_FOLDER ${CMAKE_CURRENT_LIST_DIR}/../pnpbridge/inc CACHE INTER
|
|||
|
||||
include_directories(../../deps/azure-iot-sdk-c-pnp/deps/parson)
|
||||
include_directories(../../deps/azure-iot-sdk-c-pnp/c-utility/inc)
|
||||
include_directories(../../deps/azure-iot-sdk-c-pnp/c-utility/deps/azure-macro-utils-c/inc)
|
||||
include_directories(../../deps/azure-iot-sdk-c-pnp/c-utility/deps/umock-c/inc)
|
||||
include_directories(../../deps/azure-iot-sdk-c-pnp/digitaltwin_client/inc)
|
||||
include_directories(../../deps/azure-iot-sdk-c-pnp/iothub_client/inc)
|
||||
|
||||
|
|
|
@ -30,7 +30,8 @@
|
|||
"sensor_id": "10"
|
||||
}
|
||||
},
|
||||
"interface_id": "http://contoso.com/EnvironmentalSensor/1.0.0",
|
||||
"interface_id": "urn:contoso:com:EnvironmentalSensor:1",
|
||||
"component_name": "MyComponent",
|
||||
"pnp_parameters": {
|
||||
"identity": "environment-sensor-sample-pnp-adapter"
|
||||
},
|
||||
|
|
|
@ -15,11 +15,12 @@
|
|||
#include "azure_c_shared_utility/xlogging.h"
|
||||
#include "azure_c_shared_utility/crt_abstractions.h"
|
||||
|
||||
#include "azure_c_shared_utility/const_defines.h"
|
||||
|
||||
|
||||
// DigitalTwin interface name from service perspective.
|
||||
static const char DigitalTwinSampleEnvironmentalSensor_InterfaceName[] = "http://contoso.com/environmentalsensor/1.0.0";
|
||||
|
||||
static const char DigitalTwinSampleEnvironmentalSensor_InterfaceId[] = "urn:contoso:com:EnvironmentalSensor:1";
|
||||
static const char DigitalTwinSampleEnvironmentalSensor_ComponentName[] = "environmentalSensor";
|
||||
|
||||
//
|
||||
// Telemetry names for this interface.
|
||||
|
@ -37,96 +38,43 @@ static const char digitaltwinSample_DeviceStateData[] = "true";
|
|||
static const int digitaltwinSample_DeviceStateDataLen = sizeof(digitaltwinSample_DeviceStateData) - 1;
|
||||
|
||||
//
|
||||
// Callback function declarations and DigitalTwin synchronous command names for this interface.
|
||||
// Callback command names for this interface.
|
||||
//
|
||||
static void DigitalTwinSampleEnvironmentalSensor_BlinkCallback(const DIGITALTWIN_CLIENT_COMMAND_REQUEST* dtClientCommandContext, DIGITALTWIN_CLIENT_COMMAND_RESPONSE* dtClientCommandResponseContext, void* userContextCallback);
|
||||
static void DigitalTwinSampleEnvironmentalSensor_TurnOnLightCallback(const DIGITALTWIN_CLIENT_COMMAND_REQUEST* dtClientCommandContext, DIGITALTWIN_CLIENT_COMMAND_RESPONSE* dtClientCommandResponseContext, void* userContextCallback);
|
||||
static void DigitalTwinSampleEnvironmentalSensor_TurnOffLightCallback(const DIGITALTWIN_CLIENT_COMMAND_REQUEST* dtClientCommandContext, DIGITALTWIN_CLIENT_COMMAND_RESPONSE* dtClientCommandResponseContext, void* userContextCallback);
|
||||
|
||||
#define digitaltwinSample_EnvironmentalSensorCommandBlink "blink"
|
||||
#define digitaltwinSample_EnvironmentalSensorCommandTurnOn "turnon"
|
||||
#define digitaltwinSample_EnvironmentalSensorCommandTurnOff "turnoff"
|
||||
|
||||
static const char* digitaltwinSample_EnvironmentalSensorCommandNames[] = {
|
||||
digitaltwinSample_EnvironmentalSensorCommandBlink,
|
||||
digitaltwinSample_EnvironmentalSensorCommandTurnOn,
|
||||
digitaltwinSample_EnvironmentalSensorCommandTurnOff
|
||||
};
|
||||
|
||||
static const DIGITALTWIN_COMMAND_EXECUTE_CALLBACK digitaltwinSample_EnvironmentalSensorCommandCallbacks[] = {
|
||||
DigitalTwinSampleEnvironmentalSensor_BlinkCallback,
|
||||
DigitalTwinSampleEnvironmentalSensor_TurnOnLightCallback,
|
||||
DigitalTwinSampleEnvironmentalSensor_TurnOffLightCallback
|
||||
};
|
||||
static const char digitaltwinSample_EnvironmentalSensorCommandBlink[] = "blink";
|
||||
static const char digitaltwinSample_EnvironmentalSensorCommandTurnOn[] = "turnon";
|
||||
static const char digitaltwinSample_EnvironmentalSensorCommandTurnOff[] = "turnoff";
|
||||
static const char digitaltwinSample_EnvironmentalSensorCommandRunDiagnostics[] = "rundiagnostics";
|
||||
|
||||
//
|
||||
// Callback function declarations and DigitalTwin asynchronous command names for this interface.
|
||||
// Command status codes
|
||||
//
|
||||
static void DigitalTwinSampleEnvironmentalSensor_RunDiagnosticsCallback(const DIGITALTWIN_CLIENT_ASYNC_COMMAND_REQUEST* dtClientAsyncCommandContext, DIGITALTWIN_CLIENT_ASYNC_COMMAND_RESPONSE* dtClientAsyncCommandResponseContext, void* userContextCallback);
|
||||
|
||||
#define digitaltwinSample_EnvironmentalSensorCommandRunDiagnostics "rundiagnostics"
|
||||
|
||||
static const char* digitaltwinSample_EnvironmentalSensorAsyncCommandNames[] = {
|
||||
digitaltwinSample_EnvironmentalSensorCommandRunDiagnostics
|
||||
};
|
||||
|
||||
static const DIGITALTWIN_ASYNC_COMMAND_EXECUTE_CALLBACK digitaltwinSample_EnvironmentalSensorAsyncCommandCallbacks[] = {
|
||||
DigitalTwinSampleEnvironmentalSensor_RunDiagnosticsCallback
|
||||
};
|
||||
|
||||
|
||||
static const int commandStatusSuccess = 200;
|
||||
static const int commandStatusPending = 202;
|
||||
static const int commandStatusFailure = 500;
|
||||
static const int commandStatusNotPresent = 501;
|
||||
|
||||
//
|
||||
// What we respond to various commands with. Must be valid JSON.
|
||||
//
|
||||
static const char digitaltwinSample_EnviromentalSensor_BlinkResponse[] = "{ \"status\": 12, \"description\": \"leds blinking\" }";
|
||||
static const char digitaltwinSample_EnviromentalSensor_TurnOnLightResponse[] = "{ \"status\": 1, \"description\": \"light on\" }";
|
||||
static const char digitaltwinSample_EnviromentalSensor_TurnOffLightResponse[] = "{ \"status\": 1, \"description\": \"light off\" }";
|
||||
static const char digitaltwinSample_EnviromentalSensor_EmptyBody[] = "\" \"";
|
||||
|
||||
static const char digitaltwinSample_EnviromentalSensor_RunDiagnosticsStarted[] = "\"Started diagnostics run\"";
|
||||
static const char digitaltwinSample_EnviromentalSensor_OutOfMemory[] = "\"Out of memory\"";
|
||||
static const char digitaltwinSample_EnviromentalSensor_NotImplemented[] = "\"Requested command not implemented on this interface\"";
|
||||
static const char digitaltwinSample_EnviromentalSensor_RunDiagnosticsBusy[] = "\"Running of diagnostics already active. Only one request may be active at a time\"";
|
||||
static const char digitaltwinSample_EnviromentalSensor_DiagnosticInProgress[] = "\"Diagnostic still in progress\"";
|
||||
static const char digitaltwinSample_EnviromentalSensor_DiagnosticsComplete[] = "\"Successfully run diagnostics\"";
|
||||
|
||||
// DIGITALTWIN_CLIENT_COMMAND_CALLBACK_TABLE provides the environmental sensor with all callbacks
|
||||
// required to process commands. Note that unlike IoTHub API's - where various callbacks may
|
||||
// be added and removed dynamically over a handle's lifetime - DIGITALTWIN_INTERFACE_CLIENT_HANDLE's require all callbacks
|
||||
// for the lifetime of the object be specified at DigitalTwin_InterfaceClient_Create() time.
|
||||
static const DIGITALTWIN_CLIENT_COMMAND_CALLBACK_TABLE digitaltwinSample_EnvironmentalSensorCommandTable =
|
||||
{
|
||||
DIGITALTWIN_CLIENT_COMMAND_CALLBACK_VERSION_1, // version of structure
|
||||
sizeof(digitaltwinSample_EnvironmentalSensorCommandNames) / sizeof(digitaltwinSample_EnvironmentalSensorCommandNames[0]),
|
||||
(const char**)digitaltwinSample_EnvironmentalSensorCommandNames,
|
||||
(const DIGITALTWIN_COMMAND_EXECUTE_CALLBACK*)digitaltwinSample_EnvironmentalSensorCommandCallbacks,
|
||||
sizeof(digitaltwinSample_EnvironmentalSensorAsyncCommandNames) / sizeof(digitaltwinSample_EnvironmentalSensorAsyncCommandNames[0]),
|
||||
digitaltwinSample_EnvironmentalSensorAsyncCommandNames,
|
||||
digitaltwinSample_EnvironmentalSensorAsyncCommandCallbacks,
|
||||
};
|
||||
|
||||
//
|
||||
// Callback function declarations and DigitalTwin updateable (from service side) properties for this interface
|
||||
// Property names that are updatebale from the server application/operator.
|
||||
//
|
||||
static void DigitalTwinSampleEnvironmentalSensor_BrightnessCallback(const DIGITALTWIN_CLIENT_PROPERTY_UPDATE* dtClientPropertyUpdate, void* userContextCallback);
|
||||
static void DigitalTwinSampleEnvironmentalSensor_CustomerNameCallback(const DIGITALTWIN_CLIENT_PROPERTY_UPDATE* dtClientPropertyUpdate, void* userContextCallback);
|
||||
|
||||
#define digitaltwinSample_EnvironmentalSensorPropertyCustomerName "name"
|
||||
#define digitaltwinSample_EnvironmentalSensorPropertyBrightness "brightness"
|
||||
|
||||
static const char* digitaltwinSample_EnvironmentalSensorPropertyNames[] = {
|
||||
digitaltwinSample_EnvironmentalSensorPropertyCustomerName,
|
||||
digitaltwinSample_EnvironmentalSensorPropertyBrightness
|
||||
};
|
||||
|
||||
static const DIGITALTWIN_PROPERTY_UPDATE_CALLBACK digitaltwinSample_EnvironmentalSensorPropertyCallbacks[] = {
|
||||
DigitalTwinSampleEnvironmentalSensor_CustomerNameCallback,
|
||||
DigitalTwinSampleEnvironmentalSensor_BrightnessCallback
|
||||
};
|
||||
|
||||
// DIGITALTWIN_CLIENT_PROPERTY_UPDATED_CALLBACK_TABLE provides the environmental sensor with all
|
||||
// property callbacks required to process commands. Like DIGITALTWIN_CLIENT_COMMAND_CALLBACK_TABLE, all
|
||||
// these callbacks must be specified during handle creation time.
|
||||
static const DIGITALTWIN_CLIENT_PROPERTY_UPDATED_CALLBACK_TABLE digitaltwinSample_propertyTable =
|
||||
{
|
||||
DIGITALTWIN_CLIENT_PROPERTY_UPDATE_VERSION_1, // version of structure
|
||||
sizeof(digitaltwinSample_EnvironmentalSensorPropertyNames) / sizeof(digitaltwinSample_EnvironmentalSensorPropertyNames[0]), // number of properties and callbacks to map to
|
||||
(const char**)digitaltwinSample_EnvironmentalSensorPropertyNames,
|
||||
(const DIGITALTWIN_PROPERTY_UPDATE_CALLBACK*)digitaltwinSample_EnvironmentalSensorPropertyCallbacks
|
||||
};
|
||||
static const char digitaltwinSample_EnvironmentalSensorPropertyCustomerName[] = "name";
|
||||
static const char digitaltwinSample_EnvironmentalSensorPropertyBrightness[] = "brightness";
|
||||
|
||||
// State of simulated diagnostic run.
|
||||
typedef enum DIGITALTWIN_SAMPLE_DIAGNOSTIC_STATE_TAG
|
||||
|
@ -155,97 +103,79 @@ typedef struct DIGITALTWIN_SAMPLE_ENVIRONMENTAL_SENSOR_STATE_TAG
|
|||
// callbacks of this interface don't reference it directly but instead use userContextCallback passed to them.
|
||||
static DIGITALTWIN_SAMPLE_ENVIRONMENTAL_SENSOR_STATE digitaltwinSample_EnvironmentalSensorState;
|
||||
|
||||
static const int commandStatusSuccess = 200;
|
||||
static const int commandStatusFailure = 500;
|
||||
|
||||
// DigitalTwinSampleEnvironmentalSensor_SetCommandResponse is a helper that fills out a DIGITALTWIN_CLIENT_COMMAND_RESPONSE
|
||||
static void DigitalTwinSampleEnvironmentalSensor_SetCommandResponse(DIGITALTWIN_CLIENT_COMMAND_RESPONSE* dtClientCommandResponseContext, const char* responseData, int status)
|
||||
static int DigitalTwinSampleEnvironmentalSensor_SetCommandResponse(DIGITALTWIN_CLIENT_COMMAND_RESPONSE* dtCommandResponse, const char* responseData, int status)
|
||||
{
|
||||
size_t responseLen = strlen(responseData);
|
||||
memset(dtClientCommandResponseContext, 0, sizeof(*dtClientCommandResponseContext));
|
||||
dtClientCommandResponseContext->version = DIGITALTWIN_CLIENT_COMMAND_RESPONSE_VERSION_1;
|
||||
memset(dtCommandResponse, 0, sizeof(*dtCommandResponse));
|
||||
dtCommandResponse->version = DIGITALTWIN_CLIENT_COMMAND_RESPONSE_VERSION_1;
|
||||
int result;
|
||||
|
||||
// Allocate a copy of the response data to return to the invoker. The DigitalTwin layer that invoked the application callback
|
||||
// takes responsibility for freeing this data.
|
||||
if (mallocAndStrcpy_s((char**)&dtClientCommandResponseContext->responseData, responseData) != 0)
|
||||
if (mallocAndStrcpy_s((char**)&dtCommandResponse->responseData, responseData) != 0)
|
||||
{
|
||||
LogError("ENVIRONMENTAL_SENSOR_INTERFACE: Unable to allocate response data");
|
||||
dtClientCommandResponseContext->status = commandStatusFailure;
|
||||
dtCommandResponse->status = commandStatusFailure;
|
||||
result = MU_FAILURE;
|
||||
}
|
||||
else
|
||||
{
|
||||
dtClientCommandResponseContext->responseDataLen = responseLen;
|
||||
dtClientCommandResponseContext->status = status;
|
||||
dtCommandResponse->responseDataLen = responseLen;
|
||||
dtCommandResponse->status = status;
|
||||
result = 0;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
// Implement the callback to process the command "blink". Information pertaining to the request is specified in DIGITALTWIN_CLIENT_COMMAND_REQUEST,
|
||||
// and the callback fills out data it wishes to return to the caller on the service in DIGITALTWIN_CLIENT_COMMAND_RESPONSE.
|
||||
static void DigitalTwinSampleEnvironmentalSensor_BlinkCallback(const DIGITALTWIN_CLIENT_COMMAND_REQUEST* dtClientCommandContext, DIGITALTWIN_CLIENT_COMMAND_RESPONSE* dtClientCommandResponseContext, void* userContextCallback)
|
||||
static void DigitalTwinSampleEnvironmentalSensor_BlinkCallback(const DIGITALTWIN_CLIENT_COMMAND_REQUEST* dtCommandRequest, DIGITALTWIN_CLIENT_COMMAND_RESPONSE* dtCommandResponse, void* userInterfaceContext)
|
||||
{
|
||||
DIGITALTWIN_SAMPLE_ENVIRONMENTAL_SENSOR_STATE* sensorState = (DIGITALTWIN_SAMPLE_ENVIRONMENTAL_SENSOR_STATE*)userContextCallback;
|
||||
DIGITALTWIN_SAMPLE_ENVIRONMENTAL_SENSOR_STATE* sensorState = (DIGITALTWIN_SAMPLE_ENVIRONMENTAL_SENSOR_STATE*)userInterfaceContext;
|
||||
|
||||
LogInfo("ENVIRONMENTAL_SENSOR_INTERFACE: Blink command invoked. It has been invoked %d times previously", sensorState->numTimesBlinkCommandCalled);
|
||||
LogInfo("ENVIRONMENTAL_SENSOR_INTERFACE: Blink data=<%.*s>", (int)dtClientCommandContext->requestDataLen, dtClientCommandContext->requestData);
|
||||
LogInfo("ENVIRONMENTAL_SENSOR_INTERFACE: Blink data=<%.*s>", (int)dtCommandRequest->requestDataLen, dtCommandRequest->requestData);
|
||||
|
||||
sensorState->numTimesBlinkCommandCalled++;
|
||||
|
||||
DigitalTwinSampleEnvironmentalSensor_SetCommandResponse(dtClientCommandResponseContext, digitaltwinSample_EnviromentalSensor_BlinkResponse, commandStatusSuccess);
|
||||
(void)DigitalTwinSampleEnvironmentalSensor_SetCommandResponse(dtCommandResponse, digitaltwinSample_EnviromentalSensor_BlinkResponse, commandStatusSuccess);
|
||||
}
|
||||
|
||||
// Implement the callback to process the command "turnon".
|
||||
static void DigitalTwinSampleEnvironmentalSensor_TurnOnLightCallback(const DIGITALTWIN_CLIENT_COMMAND_REQUEST* dtClientCommandContext, DIGITALTWIN_CLIENT_COMMAND_RESPONSE* dtClientCommandResponseContext, void* userContextCallback)
|
||||
static void DigitalTwinSampleEnvironmentalSensor_TurnOnLightCallback(const DIGITALTWIN_CLIENT_COMMAND_REQUEST* dtCommandRequest, DIGITALTWIN_CLIENT_COMMAND_RESPONSE* dtCommandResponse, void* userInterfaceContext)
|
||||
{
|
||||
DIGITALTWIN_SAMPLE_ENVIRONMENTAL_SENSOR_STATE* sensorState = (DIGITALTWIN_SAMPLE_ENVIRONMENTAL_SENSOR_STATE*)userContextCallback;
|
||||
DIGITALTWIN_SAMPLE_ENVIRONMENTAL_SENSOR_STATE* sensorState = (DIGITALTWIN_SAMPLE_ENVIRONMENTAL_SENSOR_STATE*)userInterfaceContext;
|
||||
(void)sensorState; // Sensor state not used in this sample
|
||||
|
||||
LogInfo("ENVIRONMENTAL_SENSOR_INTERFACE: Turn on light command invoked");
|
||||
LogInfo("ENVIRONMENTAL_SENSOR_INTERFACE: Turn on light data=<%.*s>", (int)dtClientCommandContext->requestDataLen, dtClientCommandContext->requestData);
|
||||
LogInfo("ENVIRONMENTAL_SENSOR_INTERFACE: Turn on light data=<%.*s>", (int)dtCommandRequest->requestDataLen, dtCommandRequest->requestData);
|
||||
|
||||
DigitalTwinSampleEnvironmentalSensor_SetCommandResponse(dtClientCommandResponseContext, digitaltwinSample_EnviromentalSensor_TurnOnLightResponse, commandStatusSuccess);
|
||||
(void)DigitalTwinSampleEnvironmentalSensor_SetCommandResponse(dtCommandResponse, digitaltwinSample_EnviromentalSensor_TurnOnLightResponse, commandStatusSuccess);
|
||||
}
|
||||
|
||||
// Implement the callback to process the command "turnoff".
|
||||
static void DigitalTwinSampleEnvironmentalSensor_TurnOffLightCallback(const DIGITALTWIN_CLIENT_COMMAND_REQUEST* dtClientCommandContext, DIGITALTWIN_CLIENT_COMMAND_RESPONSE* dtClientCommandResponseContext, void* userContextCallback)
|
||||
static void DigitalTwinSampleEnvironmentalSensor_TurnOffLightCallback(const DIGITALTWIN_CLIENT_COMMAND_REQUEST* dtCommandRequest, DIGITALTWIN_CLIENT_COMMAND_RESPONSE* dtCommandResponse, void* userInterfaceContext)
|
||||
{
|
||||
DIGITALTWIN_SAMPLE_ENVIRONMENTAL_SENSOR_STATE* sensorState = (DIGITALTWIN_SAMPLE_ENVIRONMENTAL_SENSOR_STATE*)userContextCallback;
|
||||
DIGITALTWIN_SAMPLE_ENVIRONMENTAL_SENSOR_STATE* sensorState = (DIGITALTWIN_SAMPLE_ENVIRONMENTAL_SENSOR_STATE*)userInterfaceContext;
|
||||
(void)sensorState; // Sensor state not used in this sample
|
||||
|
||||
LogInfo("ENVIRONMENTAL_SENSOR_INTERFACE: Turn off light command invoked");
|
||||
LogInfo("ENVIRONMENTAL_SENSOR_INTERFACE: Turn off light data=<%.*s>", (int)dtClientCommandContext->requestDataLen, dtClientCommandContext->requestData);
|
||||
LogInfo("ENVIRONMENTAL_SENSOR_INTERFACE: Turn off light data=<%.*s>", (int)dtCommandRequest->requestDataLen, dtCommandRequest->requestData);
|
||||
|
||||
DigitalTwinSampleEnvironmentalSensor_SetCommandResponse(dtClientCommandResponseContext, digitaltwinSample_EnviromentalSensor_TurnOffLightResponse, commandStatusSuccess);
|
||||
(void)DigitalTwinSampleEnvironmentalSensor_SetCommandResponse(dtCommandResponse, digitaltwinSample_EnviromentalSensor_TurnOffLightResponse, commandStatusSuccess);
|
||||
}
|
||||
|
||||
// Fills in DIGITALTWIN_CLIENT_ASYNC_COMMAND_RESPONSE with appropriate status code. Note that we do NOT return payload body at this time, but
|
||||
// instead (on success cases at least) rely on subsequent calls to DigitalTwin_InterfaceClient_UpdateAsyncCommandStatus to send data as modeled.
|
||||
static void DigitalTwinSampleEnvironmentalSensor_SetAsyncCommandResponse(DIGITALTWIN_CLIENT_ASYNC_COMMAND_RESPONSE* dtClientAsyncCommandResponseContext, int status)
|
||||
{
|
||||
memset(dtClientAsyncCommandResponseContext, 0, sizeof(*dtClientAsyncCommandResponseContext));
|
||||
dtClientAsyncCommandResponseContext->version = DIGITALTWIN_CLIENT_ASYNC_COMMAND_RESPONSE_VERSION_1;
|
||||
|
||||
// Allocate a copy of the response data to return to the invoker. The DigitalTwin layer that invoked the application callback
|
||||
// takes responsibility for freeing this data.
|
||||
if (mallocAndStrcpy_s((char**)&dtClientAsyncCommandResponseContext->responseData, digitaltwinSample_EnviromentalSensor_EmptyBody) != 0)
|
||||
{
|
||||
LogError("ENVIRONMENTAL_SENSOR_INTERFACE: Unable to allocate response data");
|
||||
dtClientAsyncCommandResponseContext->status = 500;
|
||||
}
|
||||
else
|
||||
{
|
||||
dtClientAsyncCommandResponseContext->responseDataLen = strlen(digitaltwinSample_EnviromentalSensor_EmptyBody);
|
||||
dtClientAsyncCommandResponseContext->status = status;
|
||||
}
|
||||
}
|
||||
|
||||
// Implement the callback to process the command "rundiagnostic". Note that this is an asyncronous command, so all we do in this
|
||||
// stage is to do some rudimentary checks and to store off the fact we're async for later.
|
||||
static void DigitalTwinSampleEnvironmentalSensor_RunDiagnosticsCallback(const DIGITALTWIN_CLIENT_ASYNC_COMMAND_REQUEST* dtClientAsyncCommandContext, DIGITALTWIN_CLIENT_ASYNC_COMMAND_RESPONSE* dtClientAsyncCommandResponseContext, void* userContextCallback)
|
||||
static void DigitalTwinSampleEnvironmentalSensor_RunDiagnosticsCallback(const DIGITALTWIN_CLIENT_COMMAND_REQUEST* dtCommandRequest, DIGITALTWIN_CLIENT_COMMAND_RESPONSE* dtCommandResponse, void* userInterfaceContext)
|
||||
{
|
||||
DIGITALTWIN_SAMPLE_ENVIRONMENTAL_SENSOR_STATE *sensorState = (DIGITALTWIN_SAMPLE_ENVIRONMENTAL_SENSOR_STATE*)userContextCallback;
|
||||
DIGITALTWIN_SAMPLE_ENVIRONMENTAL_SENSOR_STATE *sensorState = (DIGITALTWIN_SAMPLE_ENVIRONMENTAL_SENSOR_STATE*)userInterfaceContext;
|
||||
|
||||
LogInfo("ENVIRONMENTAL_SENSOR_INTERFACE: Run diagnostics command invoked");
|
||||
LogInfo("ENVIRONMENTAL_SENSOR_INTERFACE: Diagnostics data=<%.*s>, requestId=<%s>", (int)dtClientAsyncCommandContext->requestDataLen, dtClientAsyncCommandContext->requestData, dtClientAsyncCommandContext->requestId);
|
||||
LogInfo("ENVIRONMENTAL_SENSOR_INTERFACE: Diagnostics data=<%.*s>, requestId=<%s>", (int)dtCommandRequest->requestDataLen, dtCommandRequest->requestData, dtCommandRequest->requestId);
|
||||
|
||||
if (sensorState->diagnosticState != DIGITALTWIN_SAMPLE_ENVIRONMENTAL_SENSOR_DIAGNOSTIC_STATE_INACTIVE)
|
||||
{
|
||||
|
@ -254,26 +184,31 @@ static void DigitalTwinSampleEnvironmentalSensor_RunDiagnosticsCallback(const DI
|
|||
// The underlying DigitalTwin protocol will allow multiple simultaneous requests to be sent to the client; whether the
|
||||
// device allows this or not is a decision for the interface & device implementors.
|
||||
LogError("ENVIRONMENTAL_SENSOR_INTERFACE: Run diagnostics already active. Cannot support multiple in parallel.");
|
||||
DigitalTwinSampleEnvironmentalSensor_SetAsyncCommandResponse(dtClientAsyncCommandResponseContext, 500);
|
||||
DigitalTwinSampleEnvironmentalSensor_SetCommandResponse(dtCommandResponse, digitaltwinSample_EnviromentalSensor_RunDiagnosticsBusy, commandStatusFailure);
|
||||
}
|
||||
// At this point we need to save the requestId. This is what the server uses to correlate subsequent responses from this operation.
|
||||
else if (mallocAndStrcpy_s(&sensorState->requestId, dtCommandRequest->requestId) != 0)
|
||||
{
|
||||
LogError("ENVIRONMENTAL_SENSOR_INTERFACE: Cannot allocate requestId.");
|
||||
(void)DigitalTwinSampleEnvironmentalSensor_SetCommandResponse(dtCommandResponse, digitaltwinSample_EnviromentalSensor_OutOfMemory, commandStatusFailure);
|
||||
}
|
||||
else if (DigitalTwinSampleEnvironmentalSensor_SetCommandResponse(dtCommandResponse, digitaltwinSample_EnviromentalSensor_RunDiagnosticsStarted, commandStatusPending) != 0)
|
||||
{
|
||||
// Because DigitalTwinSampleEnvironmentalSensor_SetCommandResponse failed, it means
|
||||
// the server will get an error response back. Do NOT change our diagnosticState
|
||||
// variable in this case or else server and client will be in different states.
|
||||
LogError("ENVIRONMENTAL_SENSOR_INTERFACE: Failed setting response to server.");
|
||||
free(sensorState->requestId);
|
||||
}
|
||||
else
|
||||
{
|
||||
// At this point we need to save the requestId. This is what the server uses to correlate subsequent responses from this operation.
|
||||
if (mallocAndStrcpy_s(&sensorState->requestId, dtClientAsyncCommandContext->requestId) != 0)
|
||||
{
|
||||
LogError("ENVIRONMENTAL_SENSOR_INTERFACE: Cannot allocate requestId.");
|
||||
DigitalTwinSampleEnvironmentalSensor_SetAsyncCommandResponse(dtClientAsyncCommandResponseContext, 500);
|
||||
}
|
||||
else
|
||||
{
|
||||
LogInfo("ENVIRONMENTAL_SENSOR_INTERFACE: Successfully set sensorState to run diagnostics. Will run later.");
|
||||
DigitalTwinSampleEnvironmentalSensor_SetAsyncCommandResponse(dtClientAsyncCommandResponseContext, 202);
|
||||
// Moving us into DIGITALTWIN_SAMPLE_ENVIRONMENTAL_SENSOR_DIAGNOSTIC_STATE_PHASE1 will mean our periodic wakeup will process this.
|
||||
sensorState->diagnosticState = DIGITALTWIN_SAMPLE_ENVIRONMENTAL_SENSOR_DIAGNOSTIC_STATE_PHASE1;
|
||||
}
|
||||
// Moving us into DIGITALTWIN_SAMPLE_ENVIRONMENTAL_SENSOR_DIAGNOSTIC_STATE_PHASE1 will mean our periodic wakeup will process this.
|
||||
LogInfo("ENVIRONMENTAL_SENSOR_INTERFACE: Successfully set sensorState to run diagnostics. Will run later.");
|
||||
sensorState->diagnosticState = DIGITALTWIN_SAMPLE_ENVIRONMENTAL_SENSOR_DIAGNOSTIC_STATE_PHASE1;
|
||||
}
|
||||
}
|
||||
|
||||
// DigitalTwinSampleEnvironmentalSensor_SetAsyncUpdateState is a helper to fill in a DIGITALTWIN_CLIENT_ASYNC_COMMAND_UPDATE structure.
|
||||
static void DigitalTwinSampleEnvironmentalSensor_SetAsyncUpdateState(DIGITALTWIN_CLIENT_ASYNC_COMMAND_UPDATE *asyncCommandUpdate, const char* propertyData, int status)
|
||||
{
|
||||
memset(asyncCommandUpdate, 0, sizeof(*asyncCommandUpdate));
|
||||
|
@ -284,18 +219,16 @@ static void DigitalTwinSampleEnvironmentalSensor_SetAsyncUpdateState(DIGITALTWIN
|
|||
asyncCommandUpdate->statusCode = status;
|
||||
}
|
||||
|
||||
// DigitalTwinSampleEnvironmentalSensor_ProcessDiagnosticIfNecessary is periodically invoked in this sample by the main()
|
||||
// DigitalTwinSampleEnvironmentalSensor_ProcessDiagnosticIfNecessaryAsync is periodically invoked in this sample by the main()
|
||||
// thread. It will evaluate whether the service has requested diagnostics to be run, which is an async operation. If so,
|
||||
// it will send the server an update status message depending on the state that we're at.
|
||||
//
|
||||
// Threading note: When this interface is invoked on the convenience layer (../digitaltwin_sample_device), this operation can
|
||||
// THREADING NOTE: When this interface is invoked on the convenience layer (../digitaltwin_sample_device), this operation can
|
||||
// run on any thread - while processing a callback, on the main() thread itself, or on a new thread spun up by the process.
|
||||
// When running on the _LL_ layer (../digitaltwin_sample_ll_device) it *must* run on the main() thread because the the _LL_ is not
|
||||
// thread safe by design.
|
||||
DIGITALTWIN_CLIENT_RESULT DigitalTwinSampleEnvironmentalSensor_ProcessDiagnosticIfNecessary(DIGITALTWIN_INTERFACE_CLIENT_HANDLE interfaceHandle)
|
||||
DIGITALTWIN_CLIENT_RESULT DigitalTwinSampleEnvironmentalSensor_ProcessDiagnosticIfNecessaryAsync(DIGITALTWIN_INTERFACE_CLIENT_HANDLE interfaceHandle)
|
||||
{
|
||||
(void)interfaceHandle;
|
||||
|
||||
DIGITALTWIN_CLIENT_RESULT result = DIGITALTWIN_CLIENT_ERROR;
|
||||
|
||||
if (digitaltwinSample_EnvironmentalSensorState.diagnosticState == DIGITALTWIN_SAMPLE_ENVIRONMENTAL_SENSOR_DIAGNOSTIC_STATE_INACTIVE)
|
||||
|
@ -309,11 +242,14 @@ DIGITALTWIN_CLIENT_RESULT DigitalTwinSampleEnvironmentalSensor_ProcessDiagnostic
|
|||
|
||||
// In phase1 of the diagnostic, we *only* report that the diagnostic is in progress but not yet complete. We also transition to the next stage.
|
||||
DIGITALTWIN_CLIENT_ASYNC_COMMAND_UPDATE asyncCommandUpdate;
|
||||
DigitalTwinSampleEnvironmentalSensor_SetAsyncUpdateState(&asyncCommandUpdate, "\"Diagnostic still in progress\"", 202);
|
||||
DigitalTwinSampleEnvironmentalSensor_SetAsyncUpdateState(&asyncCommandUpdate, digitaltwinSample_EnviromentalSensor_DiagnosticInProgress, commandStatusPending);
|
||||
|
||||
if ((result = DigitalTwin_InterfaceClient_UpdateAsyncCommandStatus(digitaltwinSample_EnvironmentalSensorState.interfaceClientHandle, &asyncCommandUpdate)) != DIGITALTWIN_CLIENT_OK)
|
||||
if ((result = DigitalTwin_InterfaceClient_UpdateAsyncCommandStatusAsync(interfaceHandle, &asyncCommandUpdate)) != DIGITALTWIN_CLIENT_OK)
|
||||
{
|
||||
LogError("ENVIRONMENTAL_SENSOR_INTERFACE: DigitalTwin_InterfaceClient_UpdateAsyncCommandStatus failed, error=<%s>", MU_ENUM_TO_STRING(DIGITALTWIN_CLIENT_RESULT, result));
|
||||
// We continue processing the diagnostic run even on DigitalTwin_InterfaceClient_UpdateAsyncCommandStatusAsync failure.
|
||||
// The UpdateAsync command is just a notification to server of state; the underlying diagnostic should not
|
||||
// be blocked as it has already been initiated.
|
||||
LogError("ENVIRONMENTAL_SENSOR_INTERFACE: DigitalTwin_InterfaceClient_UpdateAsyncCommandStatusAsync failed, error=<%s>", MU_ENUM_TO_STRING(DIGITALTWIN_CLIENT_RESULT, result));
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -328,11 +264,12 @@ DIGITALTWIN_CLIENT_RESULT DigitalTwinSampleEnvironmentalSensor_ProcessDiagnostic
|
|||
|
||||
// In phase2 of the diagnostic, we're complete. Indicate to service, free resources, and move us to inactive phase so subsequent commands can arrive.
|
||||
DIGITALTWIN_CLIENT_ASYNC_COMMAND_UPDATE asyncCommandUpdate;
|
||||
DigitalTwinSampleEnvironmentalSensor_SetAsyncUpdateState(&asyncCommandUpdate, "\"Successfully run diagnostics\"", 200);
|
||||
DigitalTwinSampleEnvironmentalSensor_SetAsyncUpdateState(&asyncCommandUpdate, digitaltwinSample_EnviromentalSensor_DiagnosticsComplete, commandStatusSuccess);
|
||||
|
||||
if ((result = DigitalTwin_InterfaceClient_UpdateAsyncCommandStatus(digitaltwinSample_EnvironmentalSensorState.interfaceClientHandle, &asyncCommandUpdate)) != DIGITALTWIN_CLIENT_OK)
|
||||
if ((result = DigitalTwin_InterfaceClient_UpdateAsyncCommandStatusAsync(interfaceHandle, &asyncCommandUpdate)) != DIGITALTWIN_CLIENT_OK)
|
||||
{
|
||||
LogError("ENVIRONMENTAL_SENSOR_INTERFACE: DigitalTwin_InterfaceClient_UpdateAsyncCommandStatus failed, error=<%s>", MU_ENUM_TO_STRING(DIGITALTWIN_CLIENT_RESULT, result));
|
||||
// See comments for DigitalTwin_InterfaceClient_UpdateAsyncCommandStatusAsync above for error handling (or lack thereof) motivation.
|
||||
LogError("ENVIRONMENTAL_SENSOR_INTERFACE: DigitalTwin_InterfaceClient_UpdateAsyncCommandStatusAsync failed, error=<%s>", MU_ENUM_TO_STRING(DIGITALTWIN_CLIENT_RESULT, result));
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -347,8 +284,6 @@ DIGITALTWIN_CLIENT_RESULT DigitalTwinSampleEnvironmentalSensor_ProcessDiagnostic
|
|||
return result;
|
||||
}
|
||||
|
||||
|
||||
|
||||
// DigitalTwinSampleEnvironmentalSensor_PropertyCallback is invoked when a property is updated (or failed) going to server.
|
||||
// In this sample, we route ALL property callbacks to this function and just have the userContextCallback set
|
||||
// to the propertyName. Product code will potentially have context stored in this userContextCallback.
|
||||
|
@ -365,9 +300,9 @@ static void DigitalTwinSampleEnvironmentalSensor_PropertyCallback(DIGITALTWIN_CL
|
|||
}
|
||||
|
||||
// Processes a property update, which the server initiated, for customer name.
|
||||
static void DigitalTwinSampleEnvironmentalSensor_CustomerNameCallback(const DIGITALTWIN_CLIENT_PROPERTY_UPDATE* dtClientPropertyUpdate, void* userContextCallback)
|
||||
static void DigitalTwinSampleEnvironmentalSensor_CustomerNameCallback(const DIGITALTWIN_CLIENT_PROPERTY_UPDATE* dtClientPropertyUpdate, void* userInterfaceContext)
|
||||
{
|
||||
DIGITALTWIN_SAMPLE_ENVIRONMENTAL_SENSOR_STATE *sensorState = (DIGITALTWIN_SAMPLE_ENVIRONMENTAL_SENSOR_STATE*)userContextCallback;
|
||||
DIGITALTWIN_SAMPLE_ENVIRONMENTAL_SENSOR_STATE *sensorState = (DIGITALTWIN_SAMPLE_ENVIRONMENTAL_SENSOR_STATE*)userInterfaceContext;
|
||||
DIGITALTWIN_CLIENT_RESULT result;
|
||||
|
||||
LogInfo("ENVIRONMENTAL_SENSOR_INTERFACE: CustomerName property invoked...");
|
||||
|
@ -405,7 +340,7 @@ static void DigitalTwinSampleEnvironmentalSensor_CustomerNameCallback(const DIGI
|
|||
// DigitalTwin_InterfaceClient_ReportPropertyAsync takes the DIGITALTWIN_CLIENT_PROPERTY_RESPONSE and returns information back to service.
|
||||
//
|
||||
result = DigitalTwin_InterfaceClient_ReportPropertyAsync(sensorState->interfaceClientHandle, digitaltwinSample_EnvironmentalSensorPropertyCustomerName, (const char*)dtClientPropertyUpdate->propertyDesired,
|
||||
&propertyResponse, DigitalTwinSampleEnvironmentalSensor_PropertyCallback, digitaltwinSample_EnvironmentalSensorPropertyCustomerName);
|
||||
&propertyResponse, DigitalTwinSampleEnvironmentalSensor_PropertyCallback, (void*)digitaltwinSample_EnvironmentalSensorPropertyCustomerName);
|
||||
if (result != DIGITALTWIN_CLIENT_OK)
|
||||
{
|
||||
LogError("ENVIRONMENTAL_SENSOR_INTERFACE: DigitalTwin_InterfaceClient_ReportPropertyAsync for CustomerName failed, error=<%s>", MU_ENUM_TO_STRING(DIGITALTWIN_CLIENT_RESULT, result));
|
||||
|
@ -437,9 +372,9 @@ static int DigitalTwinSampleEnvironmentalSensor_ParseBrightness(const char* prop
|
|||
}
|
||||
|
||||
// Process a property update for bright level.
|
||||
static void DigitalTwinSampleEnvironmentalSensor_BrightnessCallback(const DIGITALTWIN_CLIENT_PROPERTY_UPDATE* dtClientPropertyUpdate, void* userContextCallback)
|
||||
static void DigitalTwinSampleEnvironmentalSensor_BrightnessCallback(const DIGITALTWIN_CLIENT_PROPERTY_UPDATE* dtClientPropertyUpdate, void* userInterfaceContext)
|
||||
{
|
||||
DIGITALTWIN_SAMPLE_ENVIRONMENTAL_SENSOR_STATE *sensorState = (DIGITALTWIN_SAMPLE_ENVIRONMENTAL_SENSOR_STATE*)userContextCallback;
|
||||
DIGITALTWIN_SAMPLE_ENVIRONMENTAL_SENSOR_STATE *sensorState = (DIGITALTWIN_SAMPLE_ENVIRONMENTAL_SENSOR_STATE*)userInterfaceContext;
|
||||
DIGITALTWIN_CLIENT_RESULT result;
|
||||
|
||||
LogInfo("ENVIRONMENTAL_SENSOR_INTERFACE: Brightness property invoked...");
|
||||
|
@ -476,7 +411,7 @@ static void DigitalTwinSampleEnvironmentalSensor_BrightnessCallback(const DIGITA
|
|||
// DigitalTwin_InterfaceClient_ReportPropertyAsync takes the DIGITALTWIN_CLIENT_PROPERTY_RESPONSE and returns information back to service.
|
||||
//
|
||||
result = DigitalTwin_InterfaceClient_ReportPropertyAsync(sensorState->interfaceClientHandle, digitaltwinSample_EnvironmentalSensorPropertyBrightness, (const char*)dtClientPropertyUpdate->propertyDesired, &propertyResponse,
|
||||
DigitalTwinSampleEnvironmentalSensor_PropertyCallback, digitaltwinSample_EnvironmentalSensorPropertyBrightness);
|
||||
DigitalTwinSampleEnvironmentalSensor_PropertyCallback, (void*)digitaltwinSample_EnvironmentalSensorPropertyBrightness);
|
||||
if (result != DIGITALTWIN_CLIENT_OK)
|
||||
{
|
||||
LogError("ENVIRONMENTAL_SENSOR_INTERFACE: DigitalTwin_InterfaceClient_ReportPropertyAsync for Brightness failed, error=<%s>", MU_ENUM_TO_STRING(DIGITALTWIN_CLIENT_RESULT, result));
|
||||
|
@ -488,7 +423,7 @@ static void DigitalTwinSampleEnvironmentalSensor_BrightnessCallback(const DIGITA
|
|||
}
|
||||
|
||||
// Sends a reported property for device state of this simulated device.
|
||||
static DIGITALTWIN_CLIENT_RESULT DigitalTwinSampleEnvironmentalSensor_ReportDeviceState(DIGITALTWIN_INTERFACE_CLIENT_HANDLE interfaceHandle)
|
||||
static DIGITALTWIN_CLIENT_RESULT DigitalTwinSampleEnvironmentalSensor_ReportDeviceStateAsync(DIGITALTWIN_INTERFACE_CLIENT_HANDLE interfaceHandle)
|
||||
{
|
||||
DIGITALTWIN_CLIENT_RESULT result;
|
||||
|
||||
|
@ -509,16 +444,16 @@ static DIGITALTWIN_CLIENT_RESULT DigitalTwinSampleEnvironmentalSensor_ReportDevi
|
|||
|
||||
// DigitalTwinSampleEnvironmentalSensor_InterfaceRegisteredCallback is invoked when this interface
|
||||
// is successfully or unsuccessfully registered with the service, and also when the interface is deleted.
|
||||
static void DigitalTwinSampleEnvironmentalSensor_InterfaceRegisteredCallback(DIGITALTWIN_CLIENT_RESULT dtInterfaceStatus, void* userContextCallback)
|
||||
static void DigitalTwinSampleEnvironmentalSensor_InterfaceRegisteredCallback(DIGITALTWIN_CLIENT_RESULT dtInterfaceStatus, void* userInterfaceContext)
|
||||
{
|
||||
DIGITALTWIN_SAMPLE_ENVIRONMENTAL_SENSOR_STATE *sensorState = (DIGITALTWIN_SAMPLE_ENVIRONMENTAL_SENSOR_STATE*)userContextCallback;
|
||||
DIGITALTWIN_SAMPLE_ENVIRONMENTAL_SENSOR_STATE *sensorState = (DIGITALTWIN_SAMPLE_ENVIRONMENTAL_SENSOR_STATE*)userInterfaceContext;
|
||||
if (dtInterfaceStatus == DIGITALTWIN_CLIENT_OK)
|
||||
{
|
||||
// Once the interface is registered, send our reported properties to the service.
|
||||
// It *IS* safe to invoke most DigitalTwin API calls from a callback thread like this, though it
|
||||
// is NOT safe to create/destroy/register interfaces now.
|
||||
LogInfo("ENVIRONMENTAL_SENSOR_INTERFACE: Interface successfully registered.");
|
||||
DigitalTwinSampleEnvironmentalSensor_ReportDeviceState(sensorState->interfaceClientHandle);
|
||||
DigitalTwinSampleEnvironmentalSensor_ReportDeviceStateAsync(sensorState->interfaceClientHandle);
|
||||
}
|
||||
else if (dtInterfaceStatus == DIGITALTWIN_CLIENT_ERROR_INTERFACE_UNREGISTERING)
|
||||
{
|
||||
|
@ -531,6 +466,55 @@ static void DigitalTwinSampleEnvironmentalSensor_InterfaceRegisteredCallback(DIG
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
// DigitalTwinSample_ProcessCommandUpdate receives commands from the server. This implementation acts as a simple dispatcher
|
||||
// to the functions to perform the actual processing.
|
||||
void DigitalTwinSample_ProcessCommandUpdate(const DIGITALTWIN_CLIENT_COMMAND_REQUEST* dtCommandRequest, DIGITALTWIN_CLIENT_COMMAND_RESPONSE* dtCommandResponse, void* userInterfaceContext)
|
||||
{
|
||||
if (strcmp(dtCommandRequest->commandName, digitaltwinSample_EnvironmentalSensorCommandBlink) == 0)
|
||||
{
|
||||
DigitalTwinSampleEnvironmentalSensor_BlinkCallback(dtCommandRequest, dtCommandResponse, userInterfaceContext);
|
||||
}
|
||||
else if (strcmp(dtCommandRequest->commandName, digitaltwinSample_EnvironmentalSensorCommandTurnOn) == 0)
|
||||
{
|
||||
DigitalTwinSampleEnvironmentalSensor_TurnOnLightCallback(dtCommandRequest, dtCommandResponse, userInterfaceContext);
|
||||
}
|
||||
else if (strcmp(dtCommandRequest->commandName, digitaltwinSample_EnvironmentalSensorCommandTurnOff) == 0)
|
||||
{
|
||||
DigitalTwinSampleEnvironmentalSensor_TurnOffLightCallback(dtCommandRequest, dtCommandResponse, userInterfaceContext);
|
||||
}
|
||||
else if (strcmp(dtCommandRequest->commandName, digitaltwinSample_EnvironmentalSensorCommandRunDiagnostics) == 0)
|
||||
{
|
||||
DigitalTwinSampleEnvironmentalSensor_RunDiagnosticsCallback(dtCommandRequest, dtCommandResponse, userInterfaceContext);
|
||||
}
|
||||
else
|
||||
{
|
||||
// If the command is not implemented by this interface, by convention we return a 501 error to server.
|
||||
LogError("ENVIRONMENTAL_SENSOR_INTERFACE: Command name <%s> is not associated with this interface", dtCommandRequest->commandName);
|
||||
(void)DigitalTwinSampleEnvironmentalSensor_SetCommandResponse(dtCommandResponse, digitaltwinSample_EnviromentalSensor_NotImplemented, commandStatusNotPresent);
|
||||
}
|
||||
}
|
||||
|
||||
// DigitalTwinSampleEnvironmentalSensor_ProcessPropertyUpdate receives updated properties from the server. This implementation
|
||||
// acts as a simple dispatcher to the functions to perform the actual processing.
|
||||
static void DigitalTwinSampleEnvironmentalSensor_ProcessPropertyUpdate(const DIGITALTWIN_CLIENT_PROPERTY_UPDATE* dtClientPropertyUpdate, void* userInterfaceContext)
|
||||
{
|
||||
if (strcmp(dtClientPropertyUpdate->propertyName, digitaltwinSample_EnvironmentalSensorPropertyCustomerName) == 0)
|
||||
{
|
||||
DigitalTwinSampleEnvironmentalSensor_CustomerNameCallback(dtClientPropertyUpdate, userInterfaceContext);
|
||||
}
|
||||
else if (strcmp(dtClientPropertyUpdate->propertyName, digitaltwinSample_EnvironmentalSensorPropertyBrightness) == 0)
|
||||
{
|
||||
DigitalTwinSampleEnvironmentalSensor_BrightnessCallback(dtClientPropertyUpdate, userInterfaceContext);
|
||||
}
|
||||
else
|
||||
{
|
||||
// If the property is not implemented by this interface, presently we only record a log message but do not have a mechanism to report back to the service
|
||||
LogError("ENVIRONMENTAL_SENSOR_INTERFACE: Property name <%s> is not associated with this interface", dtClientPropertyUpdate->propertyName);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// DigitalTwinSampleEnvironmentalSensor_CreateInterface is the initial entry point into the DigitalTwin Sample Environmental Sensor interface.
|
||||
// It simply creates a DIGITALTWIN_INTERFACE_CLIENT_HANDLE that is mapped to the environmental sensor interface name.
|
||||
|
@ -539,7 +523,7 @@ static void DigitalTwinSampleEnvironmentalSensor_InterfaceRegisteredCallback(DIG
|
|||
// NOTE: The actual registration of this interface is left to the caller, which may register
|
||||
// multiple interfaces on one DIGITALTWIN_DEVICE_CLIENT_HANDLE.
|
||||
//
|
||||
DIGITALTWIN_INTERFACE_CLIENT_HANDLE DigitalTwinSampleEnvironmentalSensor_CreateInterface(char* interfaceId)
|
||||
DIGITALTWIN_INTERFACE_CLIENT_HANDLE DigitalTwinSampleEnvironmentalSensor_CreateInterface(char* InterfaceId, char* ComponentName)
|
||||
{
|
||||
DIGITALTWIN_INTERFACE_CLIENT_HANDLE interfaceHandle;
|
||||
DIGITALTWIN_CLIENT_RESULT result;
|
||||
|
@ -547,26 +531,26 @@ DIGITALTWIN_INTERFACE_CLIENT_HANDLE DigitalTwinSampleEnvironmentalSensor_CreateI
|
|||
memset(&digitaltwinSample_EnvironmentalSensorState, 0, sizeof(digitaltwinSample_EnvironmentalSensorState));
|
||||
digitaltwinSample_EnvironmentalSensorState.diagnosticState = DIGITALTWIN_SAMPLE_ENVIRONMENTAL_SENSOR_DIAGNOSTIC_STATE_INACTIVE;
|
||||
|
||||
if ((result = DigitalTwin_InterfaceClient_Create(interfaceId, DigitalTwinSampleEnvironmentalSensor_InterfaceRegisteredCallback, (void*)&digitaltwinSample_EnvironmentalSensorState, &interfaceHandle)) != DIGITALTWIN_CLIENT_OK)
|
||||
if ((result = DigitalTwin_InterfaceClient_Create(InterfaceId, ComponentName, DigitalTwinSampleEnvironmentalSensor_InterfaceRegisteredCallback, (void*)&digitaltwinSample_EnvironmentalSensorState, &interfaceHandle)) != DIGITALTWIN_CLIENT_OK)
|
||||
{
|
||||
LogError("ENVIRONMENTAL_SENSOR_INTERFACE: Unable to allocate interface client handle for <%s>, error=<%s>", DigitalTwinSampleEnvironmentalSensor_InterfaceName, MU_ENUM_TO_STRING(DIGITALTWIN_CLIENT_RESULT, result));
|
||||
LogError("ENVIRONMENTAL_SENSOR_INTERFACE: Unable to allocate interface client handle for interfaceId=<%s>, componentName=<%s>, error=<%s>", DigitalTwinSampleEnvironmentalSensor_InterfaceId, DigitalTwinSampleEnvironmentalSensor_ComponentName, MU_ENUM_TO_STRING(DIGITALTWIN_CLIENT_RESULT, result));
|
||||
interfaceHandle = NULL;
|
||||
}
|
||||
else if ((result = DigitalTwin_InterfaceClient_SetPropertiesUpdatedCallbacks(interfaceHandle, &digitaltwinSample_propertyTable)) != DIGITALTWIN_CLIENT_OK)
|
||||
else if ((result = DigitalTwin_InterfaceClient_SetPropertiesUpdatedCallback(interfaceHandle, DigitalTwinSampleEnvironmentalSensor_ProcessPropertyUpdate)) != DIGITALTWIN_CLIENT_OK)
|
||||
{
|
||||
LogError("ENVIRONMENTAL_SENSOR_INTERFACE: DigitalTwin_InterfaceClient_SetPropertiesUpdatedCallbacks failed. error=<%s>", MU_ENUM_TO_STRING(DIGITALTWIN_CLIENT_RESULT, result));
|
||||
LogError("ENVIRONMENTAL_SENSOR_INTERFACE: DigitalTwin_InterfaceClient_SetPropertiesUpdatedCallback failed. error=<%s>", MU_ENUM_TO_STRING(DIGITALTWIN_CLIENT_RESULT, result));
|
||||
DigitalTwinSampleEnvironmentalSensor_Close(interfaceHandle);
|
||||
interfaceHandle = NULL;
|
||||
}
|
||||
else if ((result = DigitalTwin_InterfaceClient_SetCommandsCallbacks(interfaceHandle, &digitaltwinSample_EnvironmentalSensorCommandTable)) != DIGITALTWIN_CLIENT_OK)
|
||||
else if ((result = DigitalTwin_InterfaceClient_SetCommandsCallback(interfaceHandle, DigitalTwinSample_ProcessCommandUpdate)) != DIGITALTWIN_CLIENT_OK)
|
||||
{
|
||||
LogError("ENVIRONMENTAL_SENSOR_INTERFACE: DigitalTwin_InterfaceClient_SetCommandsCallbacks failed. error=<%s>", MU_ENUM_TO_STRING(DIGITALTWIN_CLIENT_RESULT, result));
|
||||
LogError("ENVIRONMENTAL_SENSOR_INTERFACE: DigitalTwin_InterfaceClient_SetCommandsCallback failed. error=<%s>", MU_ENUM_TO_STRING(DIGITALTWIN_CLIENT_RESULT, result));
|
||||
DigitalTwinSampleEnvironmentalSensor_Close(interfaceHandle);
|
||||
interfaceHandle = NULL;
|
||||
}
|
||||
else
|
||||
{
|
||||
LogInfo("ENVIRONMENTAL_SENSOR_INTERFACE: Created DIGITALTWIN_INTERFACE_CLIENT_HANDLE. InterfaceName=<%s>, handle=<%p>", DigitalTwinSampleEnvironmentalSensor_InterfaceName, interfaceHandle);
|
||||
LogInfo("ENVIRONMENTAL_SENSOR_INTERFACE: Created DIGITALTWIN_INTERFACE_CLIENT_HANDLE. interfaceId=<%s>, componentName=<%s>, handle=<%p>", DigitalTwinSampleEnvironmentalSensor_InterfaceId, DigitalTwinSampleEnvironmentalSensor_ComponentName, interfaceHandle);
|
||||
digitaltwinSample_EnvironmentalSensorState.interfaceClientHandle = interfaceHandle;
|
||||
}
|
||||
|
||||
|
@ -592,11 +576,11 @@ static void DigitalTwinSampleEnvironmentalSensor_TelemetryCallback(DIGITALTWIN_C
|
|||
}
|
||||
|
||||
//
|
||||
// DigitalTwinSampleEnvironmentalSensor_SendTelemetryMessages is periodically invoked by the caller to
|
||||
// DigitalTwinSampleEnvironmentalSensor_SendTelemetryMessagesAsync is periodically invoked by the caller to
|
||||
// send telemetry containing the current temperature and humidity (in both cases random numbers
|
||||
// so this sample will work on platforms without these sensors).
|
||||
//
|
||||
DIGITALTWIN_CLIENT_RESULT DigitalTwinSampleEnvironmentalSensor_SendTelemetryMessages(DIGITALTWIN_INTERFACE_CLIENT_HANDLE interfaceHandle)
|
||||
DIGITALTWIN_CLIENT_RESULT DigitalTwinSampleEnvironmentalSensor_SendTelemetryMessagesAsync(DIGITALTWIN_INTERFACE_CLIENT_HANDLE interfaceHandle)
|
||||
{
|
||||
DIGITALTWIN_CLIENT_RESULT result;
|
||||
|
||||
|
@ -644,4 +628,3 @@ void DigitalTwinSampleEnvironmentalSensor_Close(DIGITALTWIN_INTERFACE_CLIENT_HAN
|
|||
free(digitaltwinSample_EnvironmentalSensorState.requestId);
|
||||
digitaltwinSample_EnvironmentalSensorState.requestId = NULL;
|
||||
}
|
||||
|
||||
|
|
|
@ -14,13 +14,12 @@ extern "C"
|
|||
#endif
|
||||
|
||||
// Creates a new DIGITALTWIN_INTERFACE_CLIENT_HANDLE for this interface.
|
||||
DIGITALTWIN_INTERFACE_CLIENT_HANDLE DigitalTwinSampleEnvironmentalSensor_CreateInterface(char* interfaceId);
|
||||
DIGITALTWIN_INTERFACE_CLIENT_HANDLE DigitalTwinSampleEnvironmentalSensor_CreateInterface(char* interfaceId, char* ComponentName);
|
||||
// Sends DigitalTwin telemetry messages about current environment
|
||||
DIGITALTWIN_CLIENT_RESULT DigitalTwinSampleEnvironmentalSensor_SendTelemetryMessages(DIGITALTWIN_INTERFACE_CLIENT_HANDLE interfaceHandle);
|
||||
DIGITALTWIN_CLIENT_RESULT DigitalTwinSampleEnvironmentalSensor_SendTelemetryMessagesAsync(DIGITALTWIN_INTERFACE_CLIENT_HANDLE interfaceHandle);
|
||||
|
||||
// Periodically checks to see if an asychronous command for running diagnostics has been queued, and process it if so.
|
||||
DIGITALTWIN_CLIENT_RESULT DigitalTwinSampleEnvironmentalSensor_ProcessDiagnosticIfNecessary(DIGITALTWIN_INTERFACE_CLIENT_HANDLE interfaceHandle);
|
||||
|
||||
DIGITALTWIN_CLIENT_RESULT DigitalTwinSampleEnvironmentalSensor_ProcessDiagnosticIfNecessaryAsync(DIGITALTWIN_INTERFACE_CLIENT_HANDLE interfaceHandle);
|
||||
|
||||
// Closes down resources associated with device info interface.
|
||||
void DigitalTwinSampleEnvironmentalSensor_Close(DIGITALTWIN_INTERFACE_CLIENT_HANDLE interfaceHandle);
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
|
||||
#include <pnpbridge.h>
|
||||
|
||||
#include "azure_c_shared_utility/base32.h"
|
||||
#include "azure_c_shared_utility/azure_base32.h"
|
||||
#include "azure_c_shared_utility/gballoc.h"
|
||||
#include "azure_c_shared_utility/xlogging.h"
|
||||
#include "azure_c_shared_utility/threadapi.h"
|
||||
|
@ -32,7 +32,7 @@ int EnvironmentSensor_TelemetryWorker(void* context) {
|
|||
return 0;
|
||||
}
|
||||
|
||||
DigitalTwinSampleEnvironmentalSensor_SendTelemetryMessages(device->pnpinterfaceHandle);
|
||||
DigitalTwinSampleEnvironmentalSensor_SendTelemetryMessagesAsync(device->pnpinterfaceHandle);
|
||||
|
||||
// Sleep for 5 sec
|
||||
ThreadAPI_Sleep(5000);
|
||||
|
@ -77,8 +77,10 @@ EnvironmentSensor_CreatePnpInterface(
|
|||
PNPADPATER_INTERFACE_PARAMS interfaceParams = { 0 };
|
||||
PNPADAPTER_INTERFACE_HANDLE pnpAdapterInterface;
|
||||
int res = 0;
|
||||
PNPMESSAGE_PROPERTIES* props = NULL;
|
||||
|
||||
interfaceId = PnpMessage_GetInterfaceId(Message);
|
||||
props = PnpMessage_AccessProperties(Message);
|
||||
|
||||
device = calloc(1, sizeof(ENVIRONMENT_SENSOR));
|
||||
if (NULL == device) {
|
||||
|
@ -89,7 +91,7 @@ EnvironmentSensor_CreatePnpInterface(
|
|||
device->ShuttingDown = false;
|
||||
|
||||
// Create PNP interface using PNP device SDK
|
||||
pnpInterfaceClient = DigitalTwinSampleEnvironmentalSensor_CreateInterface((char*)interfaceId);
|
||||
pnpInterfaceClient = DigitalTwinSampleEnvironmentalSensor_CreateInterface((char*)interfaceId, props->ComponentName);
|
||||
if (NULL == pnpInterfaceClient) {
|
||||
res = -1;
|
||||
goto end;
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
|
||||
#include <pnpbridge.h>
|
||||
|
||||
#include "azure_c_shared_utility/base32.h"
|
||||
#include "azure_c_shared_utility/azure_base32.h"
|
||||
#include "azure_c_shared_utility/gballoc.h"
|
||||
#include "azure_c_shared_utility/xlogging.h"
|
||||
#include "azure_c_shared_utility/threadapi.h"
|
||||
|
|
|
@ -40,6 +40,8 @@ set(pnpbridge_INC_FOLDER ${CMAKE_CURRENT_LIST_DIR}/../../pnpbridge/inc CACHE INT
|
|||
include_directories(../inc)
|
||||
include_directories(../../../deps/azure-iot-sdk-c-pnp/deps/parson)
|
||||
include_directories(../../../deps/azure-iot-sdk-c-pnp/c-utility/inc)
|
||||
include_directories(../../deps/azure-iot-sdk-c-pnp/c-utility/deps/azure-macro-utils-c/inc)
|
||||
include_directories(../../deps/azure-iot-sdk-c-pnp/c-utility/deps/umock-c/inc)
|
||||
include_directories(../../../deps/azure-iot-sdk-c-pnp/digitaltwin_client/inc)
|
||||
|
||||
include_directories(${pnpbridge_INC_FOLDER})
|
||||
|
|
|
@ -14,6 +14,21 @@ PNP_ADAPTER CameraPnpInterface = {
|
|||
CameraPnpInterfaceShutdown
|
||||
};
|
||||
|
||||
void
|
||||
CameraPnpCallback_ProcessCommandUpdate(
|
||||
const DIGITALTWIN_CLIENT_COMMAND_REQUEST* dtCommandRequest,
|
||||
DIGITALTWIN_CLIENT_COMMAND_RESPONSE* dtCommandResponse,
|
||||
void* userInterfaceContext
|
||||
)
|
||||
{
|
||||
if (strcmp(dtCommandRequest->commandName, "takephoto") == 0) {
|
||||
CameraPnpCallback_TakePhoto(dtCommandRequest, dtCommandResponse, userInterfaceContext);
|
||||
}
|
||||
else {
|
||||
LogError("Unknown command request");
|
||||
}
|
||||
}
|
||||
|
||||
// Forward decls for callback functions:
|
||||
void
|
||||
CameraPnpCallback_TakePhoto(
|
||||
|
@ -42,23 +57,6 @@ CameraPnpCallback_TakePhoto(
|
|||
}
|
||||
}
|
||||
|
||||
static const char* s_CameraPnpCommandNames[] = {
|
||||
"takephoto"
|
||||
};
|
||||
|
||||
static const DIGITALTWIN_COMMAND_EXECUTE_CALLBACK s_CameraPnpCommandCallbacks[] = {
|
||||
CameraPnpCallback_TakePhoto
|
||||
};
|
||||
|
||||
static const DIGITALTWIN_CLIENT_COMMAND_CALLBACK_TABLE s_CameraPnpCommandTable =
|
||||
{
|
||||
DIGITALTWIN_CLIENT_COMMAND_CALLBACK_VERSION_1, // version of structure
|
||||
sizeof(s_CameraPnpCommandNames) / sizeof(s_CameraPnpCommandNames[0]),
|
||||
(const char**)s_CameraPnpCommandNames,
|
||||
(const DIGITALTWIN_COMMAND_EXECUTE_CALLBACK*)s_CameraPnpCommandCallbacks
|
||||
};
|
||||
|
||||
|
||||
// Camera discovery API entry points.
|
||||
CameraPnpDiscovery* g_pPnpDiscovery = nullptr;
|
||||
|
||||
|
@ -133,6 +131,7 @@ CameraPnpInterfaceBind(
|
|||
PNPADAPTER_INTERFACE_HANDLE adapterInterface = nullptr;
|
||||
PNPMESSAGE_PROPERTIES* pnpMsgProps = nullptr;
|
||||
DIGITALTWIN_CLIENT_RESULT dtRes;
|
||||
PNPMESSAGE_PROPERTIES* props;
|
||||
|
||||
pnpMsgProps = PnpMessage_AccessProperties(payload);
|
||||
|
||||
|
@ -151,13 +150,14 @@ CameraPnpInterfaceBind(
|
|||
jmsg = json_parse_string(PnpMessage_GetMessage(payload));
|
||||
jobj = json_value_get_object(jmsg);
|
||||
interfaceId = PnpMessage_GetInterfaceId(payload);
|
||||
props = PnpMessage_AccessProperties(payload);
|
||||
|
||||
//s_CameraPnpCommandTable
|
||||
dtRes = DigitalTwin_InterfaceClient_Create(interfaceId,
|
||||
dtRes = DigitalTwin_InterfaceClient_Create(interfaceId, props->ComponentName,
|
||||
nullptr, pIotPnp.get(), &pnpInterfaceClient);
|
||||
RETURN_HR_IF(E_UNEXPECTED, DIGITALTWIN_CLIENT_OK != dtRes);
|
||||
|
||||
dtRes = DigitalTwin_InterfaceClient_SetCommandsCallbacks(pnpInterfaceClient, &s_CameraPnpCommandTable);
|
||||
dtRes = DigitalTwin_InterfaceClient_SetCommandsCallback(pnpInterfaceClient, CameraPnpCallback_ProcessCommandUpdate);
|
||||
RETURN_HR_IF(E_UNEXPECTED, DIGITALTWIN_CLIENT_OK != dtRes);
|
||||
|
||||
// Create PnpAdapter Interface
|
||||
|
|
|
@ -28,6 +28,8 @@ set(pnpbridge_INC_FOLDER ${CMAKE_CURRENT_LIST_DIR}/../../pnpbridge/inc CACHE INT
|
|||
include_directories(../inc)
|
||||
include_directories(../../../deps/azure-iot-sdk-c-pnp/deps/parson)
|
||||
include_directories(../../../deps/azure-iot-sdk-c-pnp/c-utility/inc)
|
||||
include_directories(../../deps/azure-iot-sdk-c-pnp/c-utility/deps/azure-macro-utils-c/inc)
|
||||
include_directories(../../deps/azure-iot-sdk-c-pnp/c-utility/deps/umock-c/inc)
|
||||
include_directories(../../../deps/azure-iot-sdk-c-pnp/digitaltwin_client/inc)
|
||||
|
||||
include_directories(${pnpbridge_INC_FOLDER})
|
||||
|
|
|
@ -7,7 +7,7 @@
|
|||
#include <initguid.h>
|
||||
#include <devpkey.h>
|
||||
|
||||
#include "azure_c_shared_utility/base32.h"
|
||||
#include "azure_c_shared_utility/azure_base32.h"
|
||||
#include "azure_c_shared_utility/gballoc.h"
|
||||
#include "azure_c_shared_utility/xlogging.h"
|
||||
#include "azure_c_shared_utility/threadapi.h"
|
||||
|
@ -191,8 +191,8 @@ CoreDeviceDiscovery_Enumerate(
|
|||
|
||||
int
|
||||
CoreDevice_StartDiscovery(
|
||||
const PNPMEMORY DeviceArgs,
|
||||
const PNPMEMORY AdapterArgs
|
||||
_In_ const PNPMEMORY DeviceArgs,
|
||||
_In_ const PNPMEMORY AdapterArgs
|
||||
)
|
||||
{
|
||||
DWORD cmRet;
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
|
||||
#include <PnpBridge.h>
|
||||
|
||||
#include "azure_c_shared_utility/base32.h"
|
||||
#include "azure_c_shared_utility/azure_base32.h"
|
||||
#include "azure_c_shared_utility/gballoc.h"
|
||||
#include "azure_c_shared_utility/xlogging.h"
|
||||
#include "azure_c_shared_utility/threadapi.h"
|
||||
|
@ -146,6 +146,7 @@ CoreDevice_CreatePnpInterface(
|
|||
const char* interfaceId = PnpMessage_GetInterfaceId(param);
|
||||
const char* symbolicLink = json_object_get_string(args, "symbolic_link");
|
||||
const char* publishMode = json_object_get_string(args, "PublishMode");
|
||||
PNPMESSAGE_PROPERTIES* props = PnpMessage_AccessProperties(param);
|
||||
|
||||
device = calloc(1, sizeof(CORE_DEVICE_TAG));
|
||||
if (NULL == device) {
|
||||
|
@ -153,7 +154,7 @@ CoreDevice_CreatePnpInterface(
|
|||
goto exit;
|
||||
}
|
||||
|
||||
dtres = DigitalTwin_InterfaceClient_Create(interfaceId,
|
||||
dtres = DigitalTwin_InterfaceClient_Create(interfaceId, props->ComponentName,
|
||||
NULL, NULL, &pnpInterfaceClient);
|
||||
if (DIGITALTWIN_CLIENT_OK != dtres) {
|
||||
result = -1;
|
||||
|
|
|
@ -38,6 +38,8 @@ set(pnpbridge_INC_FOLDER ${CMAKE_CURRENT_LIST_DIR}/../../pnpbridge/inc CACHE INT
|
|||
include_directories(../inc)
|
||||
include_directories(../../../deps/azure-iot-sdk-c-pnp/deps/parson)
|
||||
include_directories(../../../deps/azure-iot-sdk-c-pnp/c-utility/inc)
|
||||
include_directories(../../deps/azure-iot-sdk-c-pnp/c-utility/deps/azure-macro-utils-c/inc)
|
||||
include_directories(../../deps/azure-iot-sdk-c-pnp/c-utility/deps/umock-c/inc)
|
||||
include_directories(../../../deps/azure-iot-sdk-c-pnp/digitaltwin_client/inc)
|
||||
|
||||
include_directories(${pnpbridge_INC_FOLDER})
|
||||
|
|
|
@ -62,8 +62,12 @@ const ModbusCommand* ModbusPnp_LookupCommand(SINGLYLINKEDLIST_HANDLE interfaceDe
|
|||
return NULL;
|
||||
}
|
||||
|
||||
void ModbusPnp_CommandHandler(const DIGITALTWIN_CLIENT_COMMAND_REQUEST* dtClientCommandContext, DIGITALTWIN_CLIENT_COMMAND_RESPONSE* dtClientCommandResponseContext, void* userContextCallback)
|
||||
//PMODBUS_DEVICE_CONTEXT modbusDevice, const char* commandName, char* data, char** response)
|
||||
void
|
||||
ModbusPnp_CommandHandler(
|
||||
const DIGITALTWIN_CLIENT_COMMAND_REQUEST* dtClientCommandContext,
|
||||
DIGITALTWIN_CLIENT_COMMAND_RESPONSE* dtClientCommandResponseContext,
|
||||
void* userContextCallback
|
||||
)
|
||||
{
|
||||
PMODBUS_DEVICE_CONTEXT modbusDevice = (PMODBUS_DEVICE_CONTEXT) userContextCallback;
|
||||
const ModbusCommand* command = ModbusPnp_LookupCommand(modbusDevice->InterfaceDefinitions, dtClientCommandContext->commandName, 0);
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
#include <PnpBridge.h>
|
||||
|
||||
#include "azure_c_shared_utility/base32.h"
|
||||
#include "azure_c_shared_utility/azure_base32.h"
|
||||
#include "azure_c_shared_utility/gballoc.h"
|
||||
#include "azure_c_shared_utility/xlogging.h"
|
||||
#include "azure_c_shared_utility/threadapi.h"
|
||||
|
@ -14,7 +14,7 @@
|
|||
|
||||
|
||||
const char* modbusDeviceChangeMessageformat = "{ \
|
||||
\"Identity\": \"modbus-pnp-discovery\" \
|
||||
\"identity\": \"modbus-pnp-discovery\" \
|
||||
}";
|
||||
|
||||
#pragma region PnpDiscovery
|
||||
|
@ -678,17 +678,26 @@ cleanup:
|
|||
|
||||
#pragma region PnpDiscovery
|
||||
|
||||
int ModbusPnp_StartDiscovery(const char* deviceArgs, const char* adapterArgs) {
|
||||
if (deviceArgs == NULL) {
|
||||
int
|
||||
ModbusPnp_StartDiscovery(
|
||||
_In_ PNPMEMORY DeviceArgs,
|
||||
_In_ PNPMEMORY AdapterArgs
|
||||
)
|
||||
{
|
||||
if (DeviceArgs == NULL) {
|
||||
return -1;
|
||||
}
|
||||
UNREFERENCED_PARAMETER(adapterArgs);
|
||||
UNREFERENCED_PARAMETER(AdapterArgs);
|
||||
|
||||
LogInfo("Starting modbus discovery adapter");
|
||||
|
||||
// Parse Modbus DeviceConfig
|
||||
ModbusDeviceConfig* deviceConfig = calloc(1, sizeof(ModbusDeviceConfig));
|
||||
deviceConfig->ConnectionType = UNKOWN;
|
||||
|
||||
JSON_Value* jvalue = json_parse_string(deviceArgs);
|
||||
PDEVICE_ADAPTER_PARMAETERS deviceParams = (PDEVICE_ADAPTER_PARMAETERS) PnpMemory_GetBuffer(DeviceArgs, NULL);
|
||||
|
||||
JSON_Value* jvalue = json_parse_string(deviceParams->AdapterParameters[0]);
|
||||
JSON_Object* args = json_value_get_object(jvalue);
|
||||
JSON_Object* deviceConfigObj = json_object_dotget_object(args, "deviceConfig");
|
||||
|
||||
|
@ -707,9 +716,8 @@ int ModbusPnp_StartDiscovery(const char* deviceArgs, const char* adapterArgs) {
|
|||
return -1;
|
||||
}
|
||||
|
||||
if (UNKOWN == deviceConfig->ConnectionType)
|
||||
{
|
||||
LogError("Mssing Modbus connection settings.");
|
||||
if (UNKOWN == deviceConfig->ConnectionType) {
|
||||
LogError("Missing Modbus connection settings.");
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
@ -864,11 +872,9 @@ ModbusPnp_CreatePnpInterface(
|
|||
char** propertyNames = NULL;
|
||||
int propertyCount = 0;
|
||||
DIGITALTWIN_PROPERTY_UPDATE_CALLBACK* propertyUpdateTable = NULL;
|
||||
DIGITALTWIN_CLIENT_PROPERTY_UPDATED_CALLBACK_TABLE modbusPropertyTable = { 0 };
|
||||
char** commandNames = NULL;
|
||||
int commandCount = 0;
|
||||
DIGITALTWIN_COMMAND_EXECUTE_CALLBACK* commandUpdateTable = NULL;
|
||||
DIGITALTWIN_CLIENT_COMMAND_CALLBACK_TABLE modbusCommandTable = { 0 };
|
||||
const ModbusInterfaceConfig* interfaceConfig = singlylinkedlist_item_get_value(interfaceDefHandle);
|
||||
DIGITALTWIN_CLIENT_RESULT dtRes;
|
||||
|
||||
|
@ -934,10 +940,10 @@ ModbusPnp_CreatePnpInterface(
|
|||
propertyUpdateTable[i] = ModbusPnp_PropertyHandler;
|
||||
}
|
||||
|
||||
modbusPropertyTable.numCallbacks = readWritePropertyCount;
|
||||
/* modbusPropertyTable.numCallbacks = readWritePropertyCount;
|
||||
modbusPropertyTable.propertyNames = propertyNames;
|
||||
modbusPropertyTable.callbacks = propertyUpdateTable;
|
||||
modbusPropertyTable.version = 1;
|
||||
modbusPropertyTable.version = 1;*/
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -979,14 +985,15 @@ ModbusPnp_CreatePnpInterface(
|
|||
}
|
||||
}
|
||||
|
||||
modbusCommandTable.numCommandCallbacks = commandCount;
|
||||
/*modbusCommandTable.numCommandCallbacks = commandCount;
|
||||
modbusCommandTable.commandNames = commandNames;
|
||||
modbusCommandTable.commandCallbacks = commandUpdateTable;
|
||||
modbusCommandTable.version = 1;
|
||||
modbusCommandTable.version = 1;*/
|
||||
}
|
||||
}
|
||||
|
||||
dtRes = DigitalTwin_InterfaceClient_Create(interfaceId,
|
||||
"modbus",
|
||||
NULL,
|
||||
deviceContext,
|
||||
&pnpInterfaceClient);
|
||||
|
@ -996,7 +1003,7 @@ ModbusPnp_CreatePnpInterface(
|
|||
}
|
||||
|
||||
if (propertyCount > 0) {
|
||||
dtRes = DigitalTwin_InterfaceClient_SetPropertiesUpdatedCallbacks(pnpInterfaceClient, &modbusPropertyTable);
|
||||
dtRes = DigitalTwin_InterfaceClient_SetPropertiesUpdatedCallback(pnpInterfaceClient, ModbusPnp_PropertyHandler);
|
||||
if (DIGITALTWIN_CLIENT_OK != dtRes) {
|
||||
result = -1;
|
||||
goto exit;
|
||||
|
@ -1004,7 +1011,7 @@ ModbusPnp_CreatePnpInterface(
|
|||
}
|
||||
|
||||
if (commandCount > 0) {
|
||||
dtRes = DigitalTwin_InterfaceClient_SetCommandsCallbacks(pnpInterfaceClient, &modbusCommandTable);
|
||||
dtRes = DigitalTwin_InterfaceClient_SetCommandsCallback(pnpInterfaceClient, ModbusPnp_CommandHandler);
|
||||
if (DIGITALTWIN_CLIENT_OK != dtRes) {
|
||||
result = -1;
|
||||
goto exit;
|
||||
|
|
|
@ -27,6 +27,8 @@ set(pnpbridge_INC_FOLDER ${CMAKE_CURRENT_LIST_DIR}/../../pnpbridge/inc CACHE INT
|
|||
include_directories(../inc)
|
||||
include_directories(../../../deps/azure-iot-sdk-c-pnp/deps/parson)
|
||||
include_directories(../../../deps/azure-iot-sdk-c-pnp/c-utility/inc)
|
||||
include_directories(../../deps/azure-iot-sdk-c-pnp/c-utility/deps/azure-macro-utils-c/inc)
|
||||
include_directories(../../deps/azure-iot-sdk-c-pnp/c-utility/deps/umock-c/inc)
|
||||
include_directories(../../../deps/azure-iot-sdk-c-pnp/pnp_client/inc)
|
||||
|
||||
include_directories(${pnpbridge_INC_FOLDER})
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
|
||||
#include <pnpbridge.h>
|
||||
|
||||
#include "azure_c_shared_utility/base32.h"
|
||||
#include "azure_c_shared_utility/azure_base32.h"
|
||||
#include "azure_c_shared_utility/gballoc.h"
|
||||
#include "azure_c_shared_utility/xlogging.h"
|
||||
#include "azure_c_shared_utility/threadapi.h"
|
||||
|
@ -38,15 +38,6 @@ typedef uint16_t UINT16;
|
|||
|
||||
#include "serial_pnp.h"
|
||||
|
||||
// BEGIN - PNPCSDK#20
|
||||
// https://github.com/Azure/azure-iot-sdk-c-pnp/issues/20
|
||||
// Temporary redirection for property and command handling since PnP C SDK property change
|
||||
// callback doesn't provide the command name.
|
||||
|
||||
//#define CMD_PROP_HANDLER_ADAPTER_NAME SerialPnp
|
||||
//#include <cmdandprophandler.h>
|
||||
// END - PNPCSDK#20
|
||||
|
||||
int SerialPnp_UartReceiver(void* context)
|
||||
{
|
||||
int result = 0;
|
||||
|
@ -877,7 +868,12 @@ void SerialPnp_DeviceDescriptorRequest(PSERIAL_DEVICE_CONTEXT serialDevice, byte
|
|||
LogInfo("Receieved descriptor response, of length %d", *length);
|
||||
}
|
||||
|
||||
int SerialPnp_StartDiscovery(PNPMEMORY deviceArgs, PNPMEMORY adapterArgs) {
|
||||
int
|
||||
SerialPnp_StartDiscovery(
|
||||
_In_ PNPMEMORY deviceArgs,
|
||||
_In_ PNPMEMORY adapterArgs
|
||||
)
|
||||
{
|
||||
if (deviceArgs == NULL) {
|
||||
return -1;
|
||||
}
|
||||
|
@ -1017,7 +1013,13 @@ static void SerialPnp_SetCommandResponse(DIGITALTWIN_CLIENT_COMMAND_RESPONSE* pn
|
|||
}
|
||||
|
||||
|
||||
void SerialPnp_CommandUpdateHandler(const DIGITALTWIN_CLIENT_COMMAND_REQUEST* dtClientCommandContext, DIGITALTWIN_CLIENT_COMMAND_RESPONSE* dtClientCommandResponseContext, void* userContextCallback) {
|
||||
void
|
||||
SerialPnp_CommandUpdateHandler(
|
||||
const DIGITALTWIN_CLIENT_COMMAND_REQUEST* dtClientCommandContext,
|
||||
DIGITALTWIN_CLIENT_COMMAND_RESPONSE* dtClientCommandResponseContext,
|
||||
void* userContextCallback
|
||||
)
|
||||
{
|
||||
PSERIAL_DEVICE_CONTEXT deviceContext;
|
||||
|
||||
// LogInfo("Processed command frequency property updated. propertyUpdated = %.*s", (int)propertyDataUpdatedLen, propertyDataUpdated);
|
||||
|
@ -1077,94 +1079,17 @@ int SerialPnp_CreatePnpInterface(PNPADAPTER_CONTEXT AdapterHandle, PNPMESSAGE ms
|
|||
while (interfaceDefHandle != NULL) {
|
||||
PNPADAPTER_INTERFACE_HANDLE pnpAdapterInterface = NULL;
|
||||
DIGITALTWIN_INTERFACE_CLIENT_HANDLE pnpInterfaceClient = NULL;
|
||||
char** propertyNames = NULL;
|
||||
int propertyCount = 0;
|
||||
DIGITALTWIN_PROPERTY_UPDATE_CALLBACK* propertyUpdateTable = NULL;
|
||||
DIGITALTWIN_CLIENT_PROPERTY_UPDATED_CALLBACK_TABLE serialPropertyTable = { 0 };
|
||||
char** commandNames = NULL;
|
||||
int commandCount = 0;
|
||||
DIGITALTWIN_COMMAND_EXECUTE_CALLBACK* commandUpdateTable = NULL;
|
||||
DIGITALTWIN_CLIENT_COMMAND_CALLBACK_TABLE serialCommandTable = { 0 };
|
||||
const InterfaceDefinition* interfaceDef = singlylinkedlist_item_get_value(interfaceDefHandle);
|
||||
|
||||
// Construct property table
|
||||
{
|
||||
SINGLYLINKEDLIST_HANDLE property = interfaceDef->Properties;
|
||||
propertyCount = SerialPnp_GetListCount(interfaceDef->Properties);
|
||||
|
||||
if (propertyCount > 0) {
|
||||
LIST_ITEM_HANDLE eventDef = singlylinkedlist_get_head_item(property);
|
||||
const PropertyDefinition* ev;
|
||||
|
||||
propertyNames = malloc(sizeof(char*)*propertyCount);
|
||||
if (NULL == propertyNames) {
|
||||
result = -1;
|
||||
goto exit;
|
||||
}
|
||||
|
||||
propertyUpdateTable = malloc(sizeof(DIGITALTWIN_PROPERTY_UPDATE_CALLBACK*)*propertyCount);
|
||||
if (NULL == propertyUpdateTable) {
|
||||
result = -1;
|
||||
goto exit;
|
||||
}
|
||||
|
||||
eventDef = singlylinkedlist_get_head_item(property);
|
||||
int x = 0;
|
||||
while (eventDef != NULL) {
|
||||
ev = singlylinkedlist_item_get_value(eventDef);
|
||||
propertyNames[x] = ev->defintion.Name;
|
||||
propertyUpdateTable[x] = SerialPnp_PropertyUpdateHandler;
|
||||
x++;
|
||||
eventDef = singlylinkedlist_get_next_item(eventDef);
|
||||
}
|
||||
|
||||
serialPropertyTable.numCallbacks = propertyCount;
|
||||
serialPropertyTable.propertyNames = (const char **)propertyNames;
|
||||
serialPropertyTable.callbacks = propertyUpdateTable;
|
||||
serialPropertyTable.version = 1;
|
||||
}
|
||||
}
|
||||
|
||||
// Construct command table
|
||||
{
|
||||
SINGLYLINKEDLIST_HANDLE command = interfaceDef->Commands;
|
||||
commandCount = SerialPnp_GetListCount(command);
|
||||
|
||||
if (commandCount > 0) {
|
||||
LIST_ITEM_HANDLE cmdDef;
|
||||
int x = 0;
|
||||
const CommandDefinition* cv;
|
||||
|
||||
commandNames = malloc(sizeof(char*)*commandCount);
|
||||
if (NULL == commandNames) {
|
||||
result = -1;
|
||||
goto exit;
|
||||
}
|
||||
|
||||
commandUpdateTable = malloc(sizeof(DIGITALTWIN_COMMAND_EXECUTE_CALLBACK*)*commandCount);
|
||||
if (NULL == commandUpdateTable) {
|
||||
result = -1;
|
||||
goto exit;
|
||||
}
|
||||
|
||||
cmdDef = singlylinkedlist_get_head_item(command);
|
||||
while (cmdDef != NULL) {
|
||||
cv = singlylinkedlist_item_get_value(cmdDef);
|
||||
commandNames[x] = cv->defintion.Name;
|
||||
commandUpdateTable[x] = SerialPnp_CommandUpdateHandler;
|
||||
x++;
|
||||
cmdDef = singlylinkedlist_get_next_item(cmdDef);
|
||||
}
|
||||
|
||||
serialCommandTable.numCommandCallbacks = commandCount;
|
||||
serialCommandTable.commandNames = (const char **)commandNames;
|
||||
serialCommandTable.commandCallbacks = commandUpdateTable;
|
||||
serialCommandTable.version = 1;
|
||||
}
|
||||
}
|
||||
propertyCount = SerialPnp_GetListCount(interfaceDef->Properties);
|
||||
commandCount = SerialPnp_GetListCount(interfaceDef->Commands);
|
||||
|
||||
DIGITALTWIN_CLIENT_RESULT dtRes;
|
||||
PNPMESSAGE_PROPERTIES* props = PnpMessage_AccessProperties(msg);
|
||||
dtRes = DigitalTwin_InterfaceClient_Create(interfaceId,
|
||||
props->ComponentName,
|
||||
NULL,
|
||||
deviceContext,
|
||||
&pnpInterfaceClient);
|
||||
|
@ -1174,7 +1099,8 @@ int SerialPnp_CreatePnpInterface(PNPADAPTER_CONTEXT AdapterHandle, PNPMESSAGE ms
|
|||
}
|
||||
|
||||
if (propertyCount > 0) {
|
||||
dtRes = DigitalTwin_InterfaceClient_SetPropertiesUpdatedCallbacks(pnpInterfaceClient, &serialPropertyTable);
|
||||
dtRes = DigitalTwin_InterfaceClient_SetPropertiesUpdatedCallback(pnpInterfaceClient,
|
||||
SerialPnp_PropertyUpdateHandler);
|
||||
if (DIGITALTWIN_CLIENT_OK != dtRes) {
|
||||
result = -1;
|
||||
goto exit;
|
||||
|
@ -1182,7 +1108,8 @@ int SerialPnp_CreatePnpInterface(PNPADAPTER_CONTEXT AdapterHandle, PNPMESSAGE ms
|
|||
}
|
||||
|
||||
if (commandCount > 0) {
|
||||
dtRes = DigitalTwin_InterfaceClient_SetCommandsCallbacks(pnpInterfaceClient, &serialCommandTable);
|
||||
dtRes = DigitalTwin_InterfaceClient_SetCommandsCallback(pnpInterfaceClient,
|
||||
SerialPnp_CommandUpdateHandler);
|
||||
if (DIGITALTWIN_CLIENT_OK != dtRes) {
|
||||
result = -1;
|
||||
goto exit;
|
||||
|
@ -1203,20 +1130,6 @@ int SerialPnp_CreatePnpInterface(PNPADAPTER_CONTEXT AdapterHandle, PNPMESSAGE ms
|
|||
}
|
||||
}
|
||||
|
||||
if (NULL != propertyUpdateTable) {
|
||||
free(propertyUpdateTable);
|
||||
}
|
||||
if (NULL != propertyNames) {
|
||||
free(propertyNames);
|
||||
}
|
||||
|
||||
if (NULL != commandUpdateTable) {
|
||||
free(commandUpdateTable);
|
||||
}
|
||||
if (NULL != commandNames) {
|
||||
free(commandNames);
|
||||
}
|
||||
|
||||
// Save the PnpAdapterInterface in device context
|
||||
deviceContext->pnpAdapterInterface = pnpAdapterInterface;
|
||||
|
||||
|
|
|
@ -62,6 +62,8 @@ set(pnp_bridge_INC_FOLDER ${CMAKE_CURRENT_LIST_DIR} CACHE INTERNAL "this is what
|
|||
include_directories(inc)
|
||||
include_directories(../../deps/azure-iot-sdk-c-pnp/deps/parson)
|
||||
include_directories(../../deps/azure-iot-sdk-c-pnp/c-utility/inc)
|
||||
include_directories(../../deps/azure-iot-sdk-c-pnp/c-utility/deps/azure-macro-utils-c/inc)
|
||||
include_directories(../../deps/azure-iot-sdk-c-pnp/c-utility/deps/umock-c/inc)
|
||||
include_directories(../../deps/azure-iot-sdk-c-pnp/digitaltwin_client/inc)
|
||||
include_directories(../../deps/azure-iot-sdk-c-pnp/iothub_client/inc)
|
||||
include_directories(../../deps/azure-iot-sdk-c-pnp/provisioning_client/inc)
|
||||
|
@ -87,17 +89,11 @@ set(pnp_bridge_common_libs
|
|||
prov_device_client
|
||||
prov_mqtt_transport
|
||||
utpm
|
||||
pnpbridge_adapters
|
||||
pnpbridge_serial
|
||||
digitaltwin_client
|
||||
)
|
||||
|
||||
if(WIN32)
|
||||
set(pnp_bridge_common_libs
|
||||
${pnp_bridge_common_libs}
|
||||
pnpbridge_modbus
|
||||
pnpbridge_camera
|
||||
pnpbridge_coredevicehealth
|
||||
)
|
||||
endif()
|
||||
|
||||
|
|
|
@ -8,6 +8,9 @@ extern "C"
|
|||
{
|
||||
#endif
|
||||
|
||||
#include "azure_macro_utils/macro_utils.h"
|
||||
#include "umock_c/umock_c_prod.h"
|
||||
|
||||
// AUTH mechanisms for connecting to IOT device
|
||||
typedef enum AUTH_TYPE {
|
||||
AUTH_TYPE_TPM,
|
||||
|
@ -125,21 +128,53 @@ PCONNECTION_PARAMETERS PnpBridgeConfig_GetConnectionDetails(JSON_Object* Connect
|
|||
*
|
||||
* @returns PNPBRIDGE_OK on success and other PNPBRIDGE_RESULT values on failure.
|
||||
*/
|
||||
PNPBRIDGE_RESULT PnpBridgeConfig_RetrieveConfiguration(JSON_Value* ConfigJson, PNPBRIDGE_CONFIGURATION* BridgeConfig);
|
||||
MOCKABLE_FUNCTION(,
|
||||
PNPBRIDGE_RESULT,
|
||||
PnpBridgeConfig_RetrieveConfiguration,
|
||||
JSON_Value*, ConfigJson,
|
||||
PNPBRIDGE_CONFIGURATION*, BridgeConfig
|
||||
);
|
||||
|
||||
JSON_Object* Configuration_GetMatchParametersForDevice(JSON_Object* device);
|
||||
MOCKABLE_FUNCTION(,
|
||||
JSON_Object*,
|
||||
Configuration_GetMatchParametersForDevice,
|
||||
JSON_Object*, device
|
||||
);
|
||||
|
||||
JSON_Object* Configuration_GetDiscoveryParametersForDevice(JSON_Object* device);
|
||||
MOCKABLE_FUNCTION(,
|
||||
JSON_Object*,
|
||||
Configuration_GetDiscoveryParametersForDevice,
|
||||
_In_ JSON_Object*, device
|
||||
);
|
||||
|
||||
JSON_Object* Configuration_GetPnpParametersForDevice(JSON_Object* device);
|
||||
MOCKABLE_FUNCTION(,
|
||||
JSON_Object*,
|
||||
Configuration_GetPnpParametersForDevice,
|
||||
JSON_Object*, device
|
||||
);
|
||||
|
||||
JSON_Object* Configuration_GetPnpParameters(JSON_Value* config, const char* identity);
|
||||
MOCKABLE_FUNCTION(,
|
||||
JSON_Object*,
|
||||
Configuration_GetPnpParameters,
|
||||
JSON_Value*, config, const char*, identity
|
||||
);
|
||||
|
||||
JSON_Object* Configuration_GetDiscoveryParameters(JSON_Value* config, const char *identity);
|
||||
MOCKABLE_FUNCTION(,
|
||||
JSON_Object*,
|
||||
Configuration_GetDiscoveryParameters,
|
||||
JSON_Value*, config, const char, *identity
|
||||
);
|
||||
|
||||
JSON_Array* Configuration_GetConfiguredDevices(JSON_Value* config);
|
||||
MOCKABLE_FUNCTION(,
|
||||
JSON_Array*,
|
||||
Configuration_GetConfiguredDevices, JSON_Value*, config
|
||||
);
|
||||
|
||||
PNPBRIDGE_RESULT Configuration_IsDeviceConfigured(JSON_Value* config, JSON_Object* Message, JSON_Object** Device);
|
||||
MOCKABLE_FUNCTION(,
|
||||
PNPBRIDGE_RESULT,
|
||||
Configuration_IsDeviceConfigured,
|
||||
JSON_Value*, config, JSON_Object*, Message, JSON_Object**, Device
|
||||
);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
|
|
@ -13,6 +13,9 @@ TODOC: PROVIDE DETAILS OF PNPMESSAGE
|
|||
#ifndef PNPBRIDGE_DISCOVERY_ADAPTER_INTERFACE_H
|
||||
#define PNPBRIDGE_DISCOVERY_ADAPTER_INTERFACE_H
|
||||
|
||||
#include "azure_macro_utils/macro_utils.h"
|
||||
#include "umock_c/umock_c_prod.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C"
|
||||
{
|
||||
|
@ -78,9 +81,11 @@ typedef int
|
|||
|
||||
* @returns integer greater than zero on success and other values on failure.
|
||||
*/
|
||||
int
|
||||
DiscoveryAdapter_ReportDevice(
|
||||
_In_ PNPMESSAGE Message
|
||||
|
||||
MOCKABLE_FUNCTION(,
|
||||
int,
|
||||
DiscoveryAdapter_ReportDevice,
|
||||
_In_ PNPMESSAGE, Message
|
||||
);
|
||||
|
||||
typedef struct _DISCOVERY_ADAPTER {
|
||||
|
|
|
@ -1,6 +1,9 @@
|
|||
// Copyright (c) Microsoft. All rights reserved.
|
||||
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
|
||||
|
||||
#ifndef PNPBRIDGE_NOSAL_H
|
||||
#define PNPBRIDGE_NOSAL_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C"
|
||||
{
|
||||
|
@ -34,4 +37,6 @@ extern "C"
|
|||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#endif //PNPBRIDGE_NOSAL_H
|
||||
|
|
|
@ -4,6 +4,9 @@
|
|||
#ifndef PNPBRIDGE_PNP_ADAPTER_INTERFACE_H
|
||||
#define PNPBRIDGE_PNP_ADAPTER_INTERFACE_H
|
||||
|
||||
#include "azure_macro_utils/macro_utils.h"
|
||||
#include "umock_c/umock_c_prod.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C"
|
||||
{
|
||||
|
@ -121,10 +124,11 @@ PNPADPATER_INTERFACE_PARAMS_INIT(
|
|||
*
|
||||
* @returns Result indicating status of pnp adapter interface creation
|
||||
*/
|
||||
int
|
||||
PnpAdapterInterface_Create(
|
||||
PPNPADPATER_INTERFACE_PARAMS params,
|
||||
PPNPADAPTER_INTERFACE_HANDLE pnpAdapterInterface
|
||||
MOCKABLE_FUNCTION(,
|
||||
int,
|
||||
PnpAdapterInterface_Create,
|
||||
PPNPADPATER_INTERFACE_PARAMS, params,
|
||||
PPNPADAPTER_INTERFACE_HANDLE, pnpAdapterInterface
|
||||
);
|
||||
|
||||
/**
|
||||
|
@ -133,7 +137,11 @@ PnpAdapterInterface_Create(
|
|||
* @param pnpAdapterInterface Handle to pnp adapter interface
|
||||
*
|
||||
*/
|
||||
void PnpAdapterInterface_Destroy(PNPADAPTER_INTERFACE_HANDLE pnpAdapterInterface);
|
||||
MOCKABLE_FUNCTION(,
|
||||
void,
|
||||
PnpAdapterInterface_Destroy,
|
||||
PNPADAPTER_INTERFACE_HANDLE, pnpAdapterInterface
|
||||
);
|
||||
|
||||
/**
|
||||
* @brief PnpAdapter_GetPnpInterfaceClient gets the Azure iot pnp interface client handle
|
||||
|
@ -142,7 +150,11 @@ void PnpAdapterInterface_Destroy(PNPADAPTER_INTERFACE_HANDLE pnpAdapterInterface
|
|||
*
|
||||
* @returns Handle to Azure Pnp Interface client
|
||||
*/
|
||||
DIGITALTWIN_INTERFACE_CLIENT_HANDLE PnpAdapterInterface_GetPnpInterfaceClient(PNPADAPTER_INTERFACE_HANDLE pnpAdapterInterface);
|
||||
MOCKABLE_FUNCTION(,
|
||||
DIGITALTWIN_INTERFACE_CLIENT_HANDLE,
|
||||
PnpAdapterInterface_GetPnpInterfaceClient,
|
||||
PNPADAPTER_INTERFACE_HANDLE, pnpAdapterInterface
|
||||
);
|
||||
|
||||
/**
|
||||
* @brief PnpAdapter_SetContext sets a context for pnp adapter interface handle
|
||||
|
@ -153,7 +165,12 @@ DIGITALTWIN_INTERFACE_CLIENT_HANDLE PnpAdapterInterface_GetPnpInterfaceClient(PN
|
|||
*
|
||||
* @returns integer greater than zero on success and other values on failure.
|
||||
*/
|
||||
int PnpAdapterInterface_SetContext(PNPADAPTER_INTERFACE_HANDLE pnpAdapterInterface, void* context);
|
||||
MOCKABLE_FUNCTION(,
|
||||
int,
|
||||
PnpAdapterInterface_SetContext,
|
||||
PNPADAPTER_INTERFACE_HANDLE, pnpAdapterInterface,
|
||||
void*, context
|
||||
);
|
||||
|
||||
/**
|
||||
* @brief PnpAdapter_GetContext gets context set by pnp adapter.
|
||||
|
@ -164,7 +181,11 @@ int PnpAdapterInterface_SetContext(PNPADAPTER_INTERFACE_HANDLE pnpAdapterInterfa
|
|||
*
|
||||
* @returns void* context
|
||||
*/
|
||||
void* PnpAdapterInterface_GetContext(PNPADAPTER_INTERFACE_HANDLE pnpAdapterInterface);
|
||||
MOCKABLE_FUNCTION(,
|
||||
void*,
|
||||
PnpAdapterInterface_GetContext,
|
||||
PNPADAPTER_INTERFACE_HANDLE, pnpAdapterInterface
|
||||
);
|
||||
|
||||
/*
|
||||
PnpAdapter Binding info
|
||||
|
|
|
@ -12,41 +12,47 @@
|
|||
#ifndef PNPBRIDGE_H
|
||||
#define PNPBRIDGE_H
|
||||
|
||||
#if !defined(_MSC_VER)
|
||||
#include <nosal.h>
|
||||
#endif
|
||||
|
||||
#include "azure_macro_utils/macro_utils.h"
|
||||
#include "umock_c/umock_c_prod.h"
|
||||
|
||||
#include <digitaltwin_interface_client.h>
|
||||
|
||||
#include <pnpbridge_memory.h>
|
||||
#include <pnpmessage_api.h>
|
||||
#include <discoveryadapter_api.h>
|
||||
#include <pnpadapter_api.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C"
|
||||
{
|
||||
#endif
|
||||
|
||||
#if !defined(_MSC_VER)
|
||||
#include <nosal.h>
|
||||
#endif
|
||||
|
||||
#include <pnpbridge_memory.h>
|
||||
|
||||
typedef void* MX_IOT_HANDLE;
|
||||
|
||||
DIGITALTWIN_DEVICE_CLIENT_HANDLE IotHandle_GetPnpDeviceClient(MX_IOT_HANDLE IotHandle);
|
||||
// Getter method for DigitalTwin client handle from a device/module
|
||||
MOCKABLE_FUNCTION(,
|
||||
DIGITALTWIN_DEVICE_CLIENT_HANDLE,
|
||||
IotHandle_GetPnpDeviceClient,
|
||||
_In_ MX_IOT_HANDLE, IotHandle
|
||||
);
|
||||
|
||||
#include <pnpmessage_api.h>
|
||||
#include <discoveryadapter_api.h>
|
||||
#include <pnpadapter_api.h>
|
||||
MOCKABLE_FUNCTION(, int, PnpBridge_Main);
|
||||
|
||||
int
|
||||
PnpBridge_Main();
|
||||
MOCKABLE_FUNCTION(, void, PnpBridge_Stop);
|
||||
|
||||
void
|
||||
PnpBridge_Stop();
|
||||
|
||||
int
|
||||
PnpBridge_UploadToBlobAsync(
|
||||
const char* pszDestination,
|
||||
const unsigned char* pbData,
|
||||
size_t cbData,
|
||||
IOTHUB_CLIENT_FILE_UPLOAD_CALLBACK iotHubClientFileUploadCallback,
|
||||
void* context
|
||||
);
|
||||
MOCKABLE_FUNCTION(,
|
||||
int,
|
||||
PnpBridge_UploadToBlobAsync,
|
||||
const char*, pszDestination,
|
||||
const unsigned char*, pbData,
|
||||
size_t, cbData,
|
||||
IOTHUB_CLIENT_FILE_UPLOAD_CALLBACK, iotHubClientFileUploadCallback,
|
||||
void*, context
|
||||
);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
|
|
@ -13,11 +13,15 @@ extern "C"
|
|||
|
||||
#include <stdio.h>
|
||||
|
||||
#if !defined(_MSC_VER)
|
||||
#include <nosal.h>
|
||||
#endif
|
||||
|
||||
#include "azure_c_shared_utility/gballoc.h"
|
||||
#include "azure_c_shared_utility/xlogging.h"
|
||||
|
||||
#include "azure_c_shared_utility/macro_utils.h"
|
||||
#include "azure_c_shared_utility/umock_c_prod.h"
|
||||
#include "azure_macro_utils/macro_utils.h"
|
||||
#include "umock_c/umock_c_prod.h"
|
||||
|
||||
#include "iothub_transport_ll.h"
|
||||
#include "iothub_message.h"
|
||||
|
@ -38,13 +42,14 @@ extern "C"
|
|||
#include <iothubtransportmqtt.h>
|
||||
|
||||
#include <digitaltwin_device_client.h>
|
||||
#include <digitaltwin_module_client.h>
|
||||
#include <digitaltwin_interface_client.h>
|
||||
|
||||
#include "parson.h"
|
||||
|
||||
#include <assert.h>
|
||||
|
||||
#define DIGITALTWIN_MODULE_CLIENT_HANDLE void*
|
||||
|
||||
#define TRY
|
||||
#define LEAVE goto __tryLabel;
|
||||
#define FINALLY goto __tryLabel; __tryLabel:
|
||||
|
@ -55,6 +60,7 @@ extern "C"
|
|||
PNPBRIDGE_OK, \
|
||||
PNPBRIDGE_INSUFFICIENT_MEMORY, \
|
||||
PNPBRIDGE_FILE_NOT_FOUND, \
|
||||
PNPBRIDGE_NOT_SUPPORTED, \
|
||||
PNPBRIDGE_INVALID_ARGS, \
|
||||
PNPBRIDGE_CONFIG_READ_FAILED, \
|
||||
PNPBRIDGE_DUPLICATE_ENTRY, \
|
||||
|
@ -99,6 +105,7 @@ int Map_GetIndexValueFromKey(MAP_HANDLE handle, const char* key);
|
|||
#define PNP_CONFIG_DEVICES "devices"
|
||||
#define PNP_CONFIG_IDENTITY "identity"
|
||||
#define PNP_CONFIG_INTERFACE_ID "interface_id"
|
||||
#define PNP_CONFIG_COMPONENT_NAME "component_name"
|
||||
#define PNP_CONFIG_PUBLISH_MODE "publish_mode"
|
||||
#define PNP_CONFIG_MATCH_FILTERS "match_filters"
|
||||
#define PNP_CONFIG_MATCH_TYPE "match_type"
|
||||
|
@ -159,7 +166,9 @@ typedef struct _MESSAGE_QUEUE {
|
|||
|
||||
LOCK_HANDLE QueueLock;
|
||||
|
||||
int PublishCount;
|
||||
volatile int PublishCount;
|
||||
|
||||
volatile int InCount;
|
||||
|
||||
THREAD_HANDLE Worker;
|
||||
|
||||
|
@ -177,6 +186,11 @@ PnpMessageQueue_Create(
|
|||
PMESSAGE_QUEUE* PnpMessageQueue
|
||||
);
|
||||
|
||||
void
|
||||
PnpMessageQueue_Release(
|
||||
PMESSAGE_QUEUE Queue
|
||||
);
|
||||
|
||||
// Thread entry callback
|
||||
int
|
||||
PnpMessageQueue_Worker(
|
||||
|
@ -195,22 +209,12 @@ PnpMesssageQueue_Remove(
|
|||
PNPMESSAGE* PnpMessage
|
||||
);
|
||||
|
||||
PDLIST_ENTRY
|
||||
PnpMesssageQueue_GetPublishQ(
|
||||
PMESSAGE_QUEUE Queue
|
||||
);
|
||||
|
||||
PNPBRIDGE_RESULT
|
||||
PnpMesssageQueue_AddToPublishQ(
|
||||
PMESSAGE_QUEUE Queue,
|
||||
PNPMESSAGE PnpMessage
|
||||
);
|
||||
|
||||
void
|
||||
PnpMessageQueue_Release(
|
||||
PMESSAGE_QUEUE Queue
|
||||
);
|
||||
|
||||
int PnpBridge_ProcessPnpMessage(PNPMESSAGE PnpMessage);
|
||||
|
||||
int
|
||||
|
|
|
@ -35,8 +35,6 @@ typedef struct _PNP_BRIDGE {
|
|||
|
||||
void PnpBridge_Release(PPNP_BRIDGE pnpBridge);
|
||||
|
||||
int PnpMessage_SetInterfaceId(PNPMESSAGE Message, const char* InterfaceId);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
|
@ -20,10 +20,22 @@ typedef enum _PNPMESSAGE_CHANGE_TYPE {
|
|||
typedef struct _PNPMESSAGE_CHANGE_PROPERTIES {
|
||||
void* Context;
|
||||
PNPMESSAGE_CHANGE_TYPE ChangeType;
|
||||
char* ComponentName;
|
||||
} PNPMESSAGE_PROPERTIES;
|
||||
|
||||
typedef void* PNPMESSAGE;
|
||||
|
||||
const char*
|
||||
PnpMessage_GetInterfaceId(
|
||||
_In_ PNPMESSAGE Message
|
||||
);
|
||||
|
||||
int
|
||||
PnpMessage_SetInterfaceId(
|
||||
PNPMESSAGE Message,
|
||||
const char* InterfaceId
|
||||
);
|
||||
|
||||
int
|
||||
PnpMessage_CreateMessage(
|
||||
_Out_ PNPMESSAGE* Message
|
||||
|
@ -35,18 +47,7 @@ PnpMessage_SetMessage(
|
|||
const char* Payload
|
||||
);
|
||||
|
||||
int
|
||||
PnpMessage_SetInterfaceId(
|
||||
_In_ PNPMESSAGE Message,
|
||||
_In_ const char* InterfaceId
|
||||
);
|
||||
|
||||
char*
|
||||
PnpMessage_GetInterfaceId(
|
||||
_In_ PNPMESSAGE Message
|
||||
);
|
||||
|
||||
char*
|
||||
const char*
|
||||
PnpMessage_GetMessage(
|
||||
_In_ PNPMESSAGE Message
|
||||
);
|
||||
|
|
|
@ -43,6 +43,8 @@ set(pnp_bridge_INC_FOLDER ${CMAKE_CURRENT_LIST_DIR} CACHE INTERNAL "this is what
|
|||
include_directories(inc)
|
||||
include_directories(../../../../deps/azure-iot-sdk-c-pnp/deps/parson)
|
||||
include_directories(../../../../deps/azure-iot-sdk-c-pnp/c-utility/inc)
|
||||
include_directories(../../deps/azure-iot-sdk-c-pnp/c-utility/deps/azure-macro-utils-c/inc)
|
||||
include_directories(../../deps/azure-iot-sdk-c-pnp/c-utility/deps/umock-c/inc)
|
||||
include_directories(../../../../deps/azure-iot-sdk-c-pnp/digitaltwin_client/inc)
|
||||
include_directories(../../../../deps/azure-iot-sdk-c-pnp/iothub_client/inc)
|
||||
include_directories(../../../../deps/azure-iot-sdk-c-pnp/provisioning_client/inc)
|
||||
|
@ -70,8 +72,8 @@ set(pnp_bridge_common_libs
|
|||
utpm
|
||||
pnpbridge
|
||||
pnpbridge_adapters
|
||||
pnpbridge_serial
|
||||
digitaltwin_client
|
||||
pnpbridge_serial
|
||||
)
|
||||
|
||||
if(WIN32)
|
||||
|
|
|
@ -30,7 +30,8 @@
|
|||
"hardware_id": "USB\\VID_06CB&PID_00B3"
|
||||
}
|
||||
},
|
||||
"interface_id": "http://windows.com/coredevicehealth/1.0.0",
|
||||
"interface_id": "urn:contoso:com:coredevicehealth:1",
|
||||
"component_name": "MyComponent1",
|
||||
"pnp_parameters": {
|
||||
"identity": "core-device-health"
|
||||
}
|
||||
|
@ -41,6 +42,7 @@
|
|||
"match_type": "exact"
|
||||
},
|
||||
"self_describing": "true",
|
||||
"component_name": "MyComponent2",
|
||||
"pnp_parameters": {
|
||||
"identity": "modbus-pnp-interface"
|
||||
},
|
||||
|
@ -56,7 +58,7 @@
|
|||
}
|
||||
},
|
||||
"interfaceConfig": {
|
||||
"interfaceId": "http://contoso.com/Co2Detector/1.0.0",
|
||||
"interfaceId": "urn:contoso:com:Co2Detector:1",
|
||||
"telemetry": {
|
||||
"co2": {
|
||||
"startAddress": "40001",
|
||||
|
@ -124,6 +126,7 @@
|
|||
"match_type": "exact"
|
||||
},
|
||||
"self_describing": "true",
|
||||
"component_name": "MyComponent3",
|
||||
"pnp_parameters": {
|
||||
"identity": "serial-pnp-interface"
|
||||
},
|
||||
|
@ -143,7 +146,8 @@
|
|||
"hardware_id": "UVC_Webcam_00"
|
||||
}
|
||||
},
|
||||
"interface_id": "http://windows.com/camera_health_monitor/1.0.0",
|
||||
"interface_id": "urn:contoso:com:camera_health_monitor:1",
|
||||
"component_name": "MyComponent4",
|
||||
"pnp_parameters": {
|
||||
"identity": "camera-health-monitor"
|
||||
}
|
||||
|
|
|
@ -15,6 +15,7 @@ BOOL WINAPI CtrlHandler(DWORD fdwCtrlType)
|
|||
|
||||
default:
|
||||
return FALSE;
|
||||
//
|
||||
}
|
||||
}
|
||||
#else
|
||||
|
|
|
@ -49,6 +49,8 @@ set(pnp_bridge_INC_FOLDER ${CMAKE_CURRENT_LIST_DIR} CACHE INTERNAL "this is what
|
|||
include_directories(inc)
|
||||
include_directories(../../deps/azure-iot-sdk-c-pnp/deps/parson)
|
||||
include_directories(../../deps/azure-iot-sdk-c-pnp/c-utility/inc)
|
||||
include_directories(../../deps/azure-iot-sdk-c-pnp/c-utility/deps/azure-macro-utils-c/inc)
|
||||
include_directories(../../deps/azure-iot-sdk-c-pnp/c-utility/deps/umock-c/inc)
|
||||
include_directories(../../deps/azure-iot-sdk-c-pnp/digitaltwin_client/inc)
|
||||
include_directories(../../deps/azure-iot-sdk-c-pnp/iothub_client/inc)
|
||||
include_directories(../../deps/azure-iot-sdk-c-pnp/provisioning_client/inc)
|
||||
|
|
|
@ -382,7 +382,10 @@ JSON_Object* Configuration_GetMatchParametersForDevice(JSON_Object* device)
|
|||
return matchParams;
|
||||
}
|
||||
|
||||
JSON_Object* Configuration_GetDiscoveryParametersForDevice(JSON_Object* device)
|
||||
JSON_Object*
|
||||
Configuration_GetDiscoveryParametersForDevice(
|
||||
_In_ JSON_Object* device
|
||||
)
|
||||
{
|
||||
if (device == NULL) {
|
||||
return NULL;
|
||||
|
|
|
@ -59,8 +59,15 @@ PNPBRIDGE_RESULT DiscoveryAdapterManager_Create(PDISCOVERY_MANAGER* discoveryMan
|
|||
return PNPBRIDGE_OK;
|
||||
}
|
||||
|
||||
PNPBRIDGE_RESULT DiscoveryManager_StarDiscoveryAdapter(PDISCOVERY_MANAGER discoveryManager, PDISCOVERY_ADAPTER discoveryInterface,
|
||||
SINGLYLINKEDLIST_HANDLE DeviceAdapterParamsList, int DeviceAdapterParamsCount, JSON_Object* adapterParams, int key)
|
||||
PNPBRIDGE_RESULT
|
||||
DiscoveryManager_StarDiscoveryAdapter(
|
||||
PDISCOVERY_MANAGER discoveryManager,
|
||||
PDISCOVERY_ADAPTER discoveryInterface,
|
||||
SINGLYLINKEDLIST_HANDLE DeviceAdapterParamsList,
|
||||
int DeviceAdapterParamsCount,
|
||||
JSON_Object* adapterParams,
|
||||
int key
|
||||
)
|
||||
{
|
||||
PNPBRIDGE_RESULT result = PNPBRIDGE_OK;
|
||||
char* adapterParamString = NULL;
|
||||
|
|
|
@ -248,7 +248,9 @@ IotComms_PnPInterfaceRegisteredCallback(
|
|||
{
|
||||
PPNP_REGISTRATION_CONTEXT registrationContext = (PPNP_REGISTRATION_CONTEXT)userContextCallback;
|
||||
registrationContext->RegistrationStatus = (pnpInterfaceStatus == DIGITALTWIN_CLIENT_OK) ? APP_PNP_REGISTRATION_SUCCEEDED : APP_PNP_REGISTRATION_FAILED;
|
||||
Lock(registrationContext->Lock);
|
||||
Condition_Post(registrationContext->Condition);
|
||||
Unlock(registrationContext->Lock);
|
||||
}
|
||||
|
||||
#define DIGITALTWIN_SAMPLE_DEVICE_CAPABILITY_MODEL_URI "http://azureiot.com/TestDeviceCapabilityModule/1.0.0"
|
||||
|
@ -270,7 +272,6 @@ IotComms_RegisterPnPInterfaces(
|
|||
callbackContext.RegistrationStatus = APP_PNP_REGISTRATION_PENDING;
|
||||
callbackContext.Condition = Condition_Init();
|
||||
callbackContext.Lock = Lock_Init();
|
||||
Lock(callbackContext.Lock);
|
||||
|
||||
// DigitalTwinClient doesn't support incremental publishing of PnP Interface
|
||||
// Inorder to workaround this we will destroy the DigitalTwinClient and recreate it
|
||||
|
@ -283,9 +284,8 @@ IotComms_RegisterPnPInterfaces(
|
|||
InterfaceCount, IotComms_PnPInterfaceRegisteredCallback, &callbackContext);
|
||||
}
|
||||
else {
|
||||
pnpResult = DigitalTwin_ModuleClient_RegisterInterfacesAsync(
|
||||
IotHandle->u1.IotModule.pnpModuleClientHandle, DIGITALTWIN_SAMPLE_DEVICE_CAPABILITY_MODEL_URI, Interfaces,
|
||||
InterfaceCount, IotComms_PnPInterfaceRegisteredCallback, &callbackContext);
|
||||
LogError("Module support is not present in public preview");
|
||||
pnpResult = PNPBRIDGE_NOT_SUPPORTED;
|
||||
}
|
||||
|
||||
if (DIGITALTWIN_CLIENT_OK != pnpResult) {
|
||||
|
@ -293,7 +293,9 @@ IotComms_RegisterPnPInterfaces(
|
|||
goto end;
|
||||
}
|
||||
|
||||
Lock(callbackContext.Lock);
|
||||
Condition_Wait(callbackContext.Condition, callbackContext.Lock, 0);
|
||||
Unlock(callbackContext.Lock);
|
||||
|
||||
if (callbackContext.RegistrationStatus != APP_PNP_REGISTRATION_SUCCEEDED) {
|
||||
LogError("PnP has failed to register.\n");
|
||||
|
@ -385,44 +387,6 @@ IOTHUB_DEVICE_HANDLE IotComms_InitializeIotDevice(bool TraceOn, PCONNECTION_PARA
|
|||
return NULL;
|
||||
}
|
||||
|
||||
PNPBRIDGE_RESULT IotComms_InitializeIotModuleHandle(MX_IOT_HANDLE_TAG* IotHandle, bool TraceOn, PCONNECTION_PARAMETERS ConnectionParams)
|
||||
{
|
||||
PNPBRIDGE_RESULT result = PNPBRIDGE_OK;
|
||||
|
||||
TRY {
|
||||
// Mark this handle as module
|
||||
IotHandle->IsModule = true;
|
||||
|
||||
AZURE_UNREFERENCED_PARAMETER(TraceOn);
|
||||
AZURE_UNREFERENCED_PARAMETER(ConnectionParams);
|
||||
|
||||
// Connect to Iot Hub Module
|
||||
IotHandle->u1.IotModule.moduleHandle = IoTHubModuleClient_CreateFromEnvironment(MQTT_Protocol);
|
||||
if (NULL == IotHandle->u1.IotModule.moduleHandle) {
|
||||
LogError("IoTHubModuleClient_CreateFromEnvironment failed\n");
|
||||
result = PNPBRIDGE_FAILED;
|
||||
LEAVE;
|
||||
}
|
||||
|
||||
// Create PnpModuleClient
|
||||
if (DIGITALTWIN_CLIENT_OK != DigitalTwin_ModuleClient_CreateFromModuleHandle(
|
||||
IotHandle->u1.IotModule.moduleHandle, &IotHandle->u1.IotModule.pnpModuleClientHandle))
|
||||
{
|
||||
LogError("PnP_ModuleClient_CreateFromModuleHandle failed\n");
|
||||
result = PNPBRIDGE_FAILED;
|
||||
LEAVE;
|
||||
}
|
||||
|
||||
// We have completed initializing the pnp client
|
||||
IotHandle->DeviceClientInitialized = true;
|
||||
|
||||
} FINALLY {
|
||||
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
PNPBRIDGE_RESULT
|
||||
IotComms_InitializeIotDeviceHandle(
|
||||
MX_IOT_HANDLE_TAG* IotHandle,
|
||||
|
@ -470,12 +434,7 @@ IotComms_DigitalTwinClient_Initalize(
|
|||
}
|
||||
}
|
||||
else {
|
||||
if (DIGITALTWIN_CLIENT_OK != DigitalTwin_ModuleClient_CreateFromModuleHandle(
|
||||
IotHandle->u1.IotDevice.deviceHandle, &IotHandle->u1.IotModule.pnpModuleClientHandle))
|
||||
{
|
||||
LogError("DigitalTwin_ModuleClient_CreateFromModuleHandle failed\n");
|
||||
result = PNPBRIDGE_FAILED;
|
||||
}
|
||||
result = PNPBRIDGE_NOT_SUPPORTED;
|
||||
}
|
||||
|
||||
IotHandle->DigitalTwinClientInitialized = (PNPBRIDGE_OK == result);
|
||||
|
@ -493,7 +452,7 @@ IotComms_DigitalTwinClient_Destroy(
|
|||
DigitalTwin_DeviceClient_Destroy(IotHandle->u1.IotDevice.PnpDeviceClientHandle);
|
||||
}
|
||||
else {
|
||||
DigitalTwin_ModuleClient_Destroy(IotHandle->u1.IotModule.moduleHandle);
|
||||
LogError("Module support is not present in public preview");
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -503,7 +462,7 @@ IotComms_DigitalTwinClient_Destroy(
|
|||
PNPBRIDGE_RESULT IotComms_InitializeIotHandle(MX_IOT_HANDLE_TAG* IotHandle, bool TraceOn, PCONNECTION_PARAMETERS ConnectionParams)
|
||||
{
|
||||
if (ConnectionParams->ConnectionType == CONNECTION_TYPE_EDGE_MODULE) {
|
||||
return IotComms_InitializeIotModuleHandle(IotHandle, TraceOn, ConnectionParams);
|
||||
return PNPBRIDGE_NOT_SUPPORTED;
|
||||
}
|
||||
else {
|
||||
return IotComms_InitializeIotDeviceHandle(IotHandle, TraceOn, ConnectionParams);
|
||||
|
|
|
@ -126,7 +126,11 @@ void* PnpAdapterInterface_GetContext(PNPADAPTER_INTERFACE_HANDLE pnpAdapterInter
|
|||
return adapterInterface->context;
|
||||
}
|
||||
|
||||
DIGITALTWIN_DEVICE_CLIENT_HANDLE IotHandle_GetPnpDeviceClient(MX_IOT_HANDLE IotHandle) {
|
||||
DIGITALTWIN_DEVICE_CLIENT_HANDLE
|
||||
IotHandle_GetPnpDeviceClient(
|
||||
MX_IOT_HANDLE IotHandle
|
||||
)
|
||||
{
|
||||
MX_IOT_HANDLE_TAG* iotHandle = (MX_IOT_HANDLE_TAG*)IotHandle;
|
||||
|
||||
return iotHandle->u1.IotDevice.PnpDeviceClientHandle;
|
||||
|
|
|
@ -251,9 +251,10 @@ PnpBridge_ProcessPnpMessage(
|
|||
|
||||
// Create an Pnp interface
|
||||
char* interfaceId = NULL;
|
||||
char* componentName = NULL;
|
||||
char* selfDescribing = (char*)json_object_get_string(jdevice, PNP_CONFIG_SELF_DESCRIBING);
|
||||
if (NULL != selfDescribing && 0 == strcmp(selfDescribing, "true")) {
|
||||
interfaceId = (char*)json_object_get_string(jobj, "InterfaceId");
|
||||
interfaceId = msg->InterfaceId;
|
||||
if (NULL == interfaceId) {
|
||||
LogError("Interface id is missing for self descrbing device");
|
||||
result = PNPBRIDGE_INVALID_ARGS;
|
||||
|
@ -268,8 +269,18 @@ PnpBridge_ProcessPnpMessage(
|
|||
LEAVE;
|
||||
}
|
||||
|
||||
componentName = (char*)json_object_get_string(jdevice, PNP_CONFIG_COMPONENT_NAME);
|
||||
if (NULL == interfaceId) {
|
||||
LogError("Interface Id is missing in config for the device");
|
||||
result = PNPBRIDGE_INVALID_ARGS;
|
||||
LEAVE;
|
||||
}
|
||||
|
||||
// Add interfaceId to the message
|
||||
PnpMessage_SetInterfaceId(PnpMessage, interfaceId);
|
||||
|
||||
// Add the component name
|
||||
mallocAndStrcpy_s(&PnpMessage_AccessProperties(PnpMessage)->ComponentName, componentName);
|
||||
}
|
||||
|
||||
if (PnpAdapterManager_IsInterfaceIdPublished(pnpBridge->PnpMgr, interfaceId)) {
|
||||
|
@ -355,10 +366,9 @@ DiscoveryAdapter_ReportDevice(
|
|||
PnpMesssageQueue_Add(queue, PnpMessage);
|
||||
|
||||
// Notify the worker
|
||||
Lock(queue->WaitConditionLock);
|
||||
Condition_Post(queue->WaitCondition);
|
||||
Lock(queue->WaitCondition);
|
||||
Condition_Post(queue->WaitCondition);
|
||||
Unlock(queue->WaitCondition);
|
||||
Unlock(queue->WaitConditionLock);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -404,7 +414,9 @@ PnpBridge_Main()
|
|||
// Prevent main thread from returning by waiting for the
|
||||
// exit condition to be set. This condition will be set when
|
||||
// the bridge has received a stop signal
|
||||
Lock(pnpBridge->ExitLock);
|
||||
Condition_Wait(pnpBridge->ExitCondition, pnpBridge->ExitLock, 0);
|
||||
Unlock(pnpBridge->ExitLock);
|
||||
} FINALLY {
|
||||
g_PnpBridge = NULL;
|
||||
|
||||
|
@ -424,7 +436,9 @@ PnpBridge_Stop()
|
|||
|
||||
if (PNP_BRIDGE_TEARING_DOWN != g_PnpBridgeState) {
|
||||
g_PnpBridgeState = PNP_BRIDGE_TEARING_DOWN;
|
||||
Lock(g_PnpBridge->ExitLock);
|
||||
Condition_Post(g_PnpBridge->ExitCondition);
|
||||
Unlock(g_PnpBridge->ExitLock);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
// Custom destroy method for PNPMESSAGE's PNPMEMORY
|
||||
void
|
||||
PnpMessage_Destroy(
|
||||
PNPMEMORY Message
|
||||
_In_ PNPMEMORY Message
|
||||
)
|
||||
{
|
||||
PPNPBRIDGE_CHANGE_PAYLOAD msg = (PPNPBRIDGE_CHANGE_PAYLOAD)PnpMemory_GetBuffer(Message, NULL);
|
||||
|
@ -15,10 +15,21 @@ PnpMessage_Destroy(
|
|||
if (msg->InterfaceId) {
|
||||
free((void*)msg->InterfaceId);
|
||||
}
|
||||
|
||||
if (msg->Properties.ComponentName) {
|
||||
free(msg->Properties.ComponentName);
|
||||
}
|
||||
}
|
||||
|
||||
const char* PnpMessage_GetMessageBuffer(PNPMESSAGE Message, int *Length) {
|
||||
PPNPBRIDGE_CHANGE_PAYLOAD msg = (PPNPBRIDGE_CHANGE_PAYLOAD) PnpMemory_GetBuffer(Message, NULL);
|
||||
const char*
|
||||
PnpMessage_GetMessageBuffer(
|
||||
_In_ PNPMESSAGE Message,
|
||||
_Out_opt_ int *Length
|
||||
)
|
||||
{
|
||||
PPNPBRIDGE_CHANGE_PAYLOAD msg;
|
||||
|
||||
msg = (PPNPBRIDGE_CHANGE_PAYLOAD) PnpMemory_GetBuffer(Message, NULL);
|
||||
|
||||
if (Length) {
|
||||
*Length = msg->MessageLength;
|
||||
|
@ -26,7 +37,11 @@ const char* PnpMessage_GetMessageBuffer(PNPMESSAGE Message, int *Length) {
|
|||
return msg->Message;
|
||||
}
|
||||
|
||||
int PnpMessage_CreateMessage(PNPMESSAGE* Message) {
|
||||
int
|
||||
PnpMessage_CreateMessage(
|
||||
_In_ PNPMESSAGE* Message
|
||||
)
|
||||
{
|
||||
PNPMEMORY_ATTRIBUTES attrib = { 0 };
|
||||
PNPMESSAGE* message = NULL;
|
||||
attrib.destroyCallback = PnpMessage_Destroy;
|
||||
|
@ -44,8 +59,17 @@ int PnpMessage_CreateMessage(PNPMESSAGE* Message) {
|
|||
return 0;
|
||||
}
|
||||
|
||||
int PnpMessage_SetMessage(PNPMESSAGE Message, const char* payload) {
|
||||
PPNPBRIDGE_CHANGE_PAYLOAD msg = (PPNPBRIDGE_CHANGE_PAYLOAD)PnpMemory_GetBuffer(Message, NULL);
|
||||
int
|
||||
PnpMessage_SetMessage(
|
||||
_In_ PNPMESSAGE Message,
|
||||
_In_ const char* payload
|
||||
)
|
||||
{
|
||||
PPNPBRIDGE_CHANGE_PAYLOAD msg;
|
||||
|
||||
assert(NULL != Message);
|
||||
|
||||
msg = (PPNPBRIDGE_CHANGE_PAYLOAD)PnpMemory_GetBuffer(Message, NULL);
|
||||
|
||||
// Allocate memory for the payload
|
||||
int length = (int) strlen(payload);
|
||||
|
@ -60,9 +84,16 @@ int PnpMessage_SetMessage(PNPMESSAGE Message, const char* payload) {
|
|||
return 0;
|
||||
}
|
||||
|
||||
char* PnpMessage_GetMessage(PNPMESSAGE Message)
|
||||
const char*
|
||||
PnpMessage_GetMessage(
|
||||
_In_ PNPMESSAGE Message
|
||||
)
|
||||
{
|
||||
PPNPBRIDGE_CHANGE_PAYLOAD msg = (PPNPBRIDGE_CHANGE_PAYLOAD)PnpMemory_GetBuffer(Message, NULL);
|
||||
PPNPBRIDGE_CHANGE_PAYLOAD msg;
|
||||
|
||||
assert(NULL != Message);
|
||||
|
||||
msg = (PPNPBRIDGE_CHANGE_PAYLOAD)PnpMemory_GetBuffer(Message, NULL);
|
||||
|
||||
return (char*) msg->Message;
|
||||
}
|
||||
|
@ -73,7 +104,11 @@ PnpMessage_SetInterfaceId(
|
|||
const char* InterfaceId
|
||||
)
|
||||
{
|
||||
PPNPBRIDGE_CHANGE_PAYLOAD msg = (PPNPBRIDGE_CHANGE_PAYLOAD)PnpMemory_GetBuffer(Message, NULL);
|
||||
PPNPBRIDGE_CHANGE_PAYLOAD msg;
|
||||
|
||||
assert(NULL != Message);
|
||||
|
||||
msg = (PPNPBRIDGE_CHANGE_PAYLOAD)PnpMemory_GetBuffer(Message, NULL);
|
||||
|
||||
// Allocate memory for the payload
|
||||
int length = (int) strlen(InterfaceId);
|
||||
|
@ -87,9 +122,9 @@ PnpMessage_SetInterfaceId(
|
|||
return 0;
|
||||
}
|
||||
|
||||
char*
|
||||
const char*
|
||||
PnpMessage_GetInterfaceId(
|
||||
PNPMESSAGE Message
|
||||
_In_ PNPMESSAGE Message
|
||||
)
|
||||
{
|
||||
PPNPBRIDGE_CHANGE_PAYLOAD msg = NULL;
|
||||
|
@ -102,7 +137,7 @@ PnpMessage_GetInterfaceId(
|
|||
|
||||
PNPMESSAGE_PROPERTIES*
|
||||
PnpMessage_AccessProperties(
|
||||
PNPMESSAGE Message
|
||||
_In_ PNPMESSAGE Message
|
||||
)
|
||||
{
|
||||
PPNPBRIDGE_CHANGE_PAYLOAD msg = NULL;
|
||||
|
@ -115,15 +150,15 @@ PnpMessage_AccessProperties(
|
|||
|
||||
void
|
||||
PnpMessage_AddReference(
|
||||
PNPMESSAGE Message
|
||||
)
|
||||
_In_ PNPMESSAGE Message
|
||||
)
|
||||
{
|
||||
PnpMemory_AddReference(Message);
|
||||
}
|
||||
|
||||
void
|
||||
PnpMessage_ReleaseReference(
|
||||
PNPMESSAGE Message
|
||||
_In_ PNPMESSAGE Message
|
||||
)
|
||||
{
|
||||
PnpMemory_ReleaseReference(Message);
|
||||
|
@ -131,7 +166,7 @@ PnpMessage_ReleaseReference(
|
|||
|
||||
int
|
||||
PnpMessageQueue_Worker(
|
||||
void* threadArgument
|
||||
_In_ void* threadArgument
|
||||
)
|
||||
{
|
||||
PMESSAGE_QUEUE queue = NULL;
|
||||
|
@ -143,11 +178,19 @@ PnpMessageQueue_Worker(
|
|||
PNPMESSAGE message = NULL;
|
||||
|
||||
// TODO: check status
|
||||
Condition_Wait(queue->WaitCondition, queue->WaitConditionLock, 0);
|
||||
Lock(queue->WaitConditionLock);
|
||||
|
||||
if (queue->TearDown) {
|
||||
Unlock(queue->WaitConditionLock);
|
||||
ThreadAPI_Exit(0);
|
||||
}
|
||||
|
||||
if (0 == queue->InCount) {
|
||||
Condition_Wait(queue->WaitCondition, queue->WaitConditionLock, 0);
|
||||
}
|
||||
|
||||
Unlock(queue->WaitConditionLock);
|
||||
|
||||
// Due to SDK limitation of not being able to incrementally publish
|
||||
// interface unload all Pnp adapters and re-init the interface
|
||||
// Steps for this:
|
||||
|
@ -169,7 +212,7 @@ PnpMessageQueue_Worker(
|
|||
PnpMesssageQueue_AddToPublishQ(queue, message);
|
||||
}
|
||||
|
||||
PDLIST_ENTRY head = PnpMesssageQueue_GetPublishQ(queue);
|
||||
PDLIST_ENTRY head = &queue->PublishQueue;
|
||||
PDLIST_ENTRY current = head->Flink;
|
||||
while (current->Blink != head->Blink) {
|
||||
PDLIST_ENTRY next = current->Flink;
|
||||
|
@ -196,7 +239,7 @@ PnpMessageQueue_Worker(
|
|||
|
||||
PNPBRIDGE_RESULT
|
||||
PnpMessageQueue_Create(
|
||||
PMESSAGE_QUEUE* PnpMessageQueue
|
||||
_In_ PMESSAGE_QUEUE* PnpMessageQueue
|
||||
)
|
||||
{
|
||||
PMESSAGE_QUEUE queue = NULL;
|
||||
|
@ -227,8 +270,6 @@ PnpMessageQueue_Create(
|
|||
LEAVE;
|
||||
}
|
||||
|
||||
Lock(queue->WaitConditionLock);
|
||||
|
||||
queue->WaitCondition = Condition_Init();
|
||||
if (NULL == queue->WaitCondition) {
|
||||
LogError("Failed to queue WaitCondition");
|
||||
|
@ -278,6 +319,8 @@ PnpMesssageQueue_Add(
|
|||
|
||||
DList_AppendTailList(&Queue->IngressQueue, &msg->Entry);
|
||||
|
||||
Queue->InCount++;
|
||||
|
||||
// Release the queue lock
|
||||
Unlock(Queue->QueueLock);
|
||||
|
||||
|
@ -286,11 +329,13 @@ PnpMesssageQueue_Add(
|
|||
|
||||
PNPBRIDGE_RESULT
|
||||
PnpMesssageQueue_AddToPublishQ(
|
||||
PMESSAGE_QUEUE Queue,
|
||||
PNPMESSAGE PnpMessage
|
||||
_In_ PMESSAGE_QUEUE Queue,
|
||||
_In_ PNPMESSAGE PnpMessage
|
||||
)
|
||||
{
|
||||
PPNPBRIDGE_CHANGE_PAYLOAD msg = (PPNPBRIDGE_CHANGE_PAYLOAD)PnpMemory_GetBuffer(PnpMessage, NULL);
|
||||
PPNPBRIDGE_CHANGE_PAYLOAD msg;
|
||||
|
||||
msg = (PPNPBRIDGE_CHANGE_PAYLOAD) PnpMemory_GetBuffer(PnpMessage, NULL);
|
||||
|
||||
DList_InitializeListHead(&msg->Entry);
|
||||
|
||||
|
@ -301,18 +346,10 @@ PnpMesssageQueue_AddToPublishQ(
|
|||
return PNPBRIDGE_OK;
|
||||
}
|
||||
|
||||
PDLIST_ENTRY
|
||||
PnpMesssageQueue_GetPublishQ(
|
||||
PMESSAGE_QUEUE Queue
|
||||
)
|
||||
{
|
||||
return &Queue->PublishQueue;
|
||||
}
|
||||
|
||||
PNPBRIDGE_RESULT
|
||||
PnpMesssageQueue_Remove(
|
||||
PMESSAGE_QUEUE Queue,
|
||||
PNPMESSAGE* PnpMessage
|
||||
_In_ PMESSAGE_QUEUE Queue,
|
||||
_Out_ PNPMESSAGE* PnpMessage
|
||||
)
|
||||
{
|
||||
*PnpMessage = NULL;
|
||||
|
@ -327,6 +364,7 @@ PnpMesssageQueue_Remove(
|
|||
if (NULL != currentEntry) {
|
||||
msg = containingRecord(currentEntry, PNPBRIDGE_CHANGE_PAYLOAD, Entry);
|
||||
*PnpMessage = msg->Self;
|
||||
Queue->InCount--;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -337,13 +375,16 @@ PnpMesssageQueue_Remove(
|
|||
|
||||
void
|
||||
PnpMessageQueue_Release(
|
||||
PMESSAGE_QUEUE Queue
|
||||
_In_ PMESSAGE_QUEUE Queue
|
||||
)
|
||||
{
|
||||
assert(NULL != Queue);
|
||||
|
||||
Queue->TearDown = true;
|
||||
|
||||
Lock(Queue->WaitConditionLock);
|
||||
Condition_Post(Queue->WaitCondition);
|
||||
Lock(Queue->WaitConditionLock);
|
||||
|
||||
// Wait for message queue worker to complete
|
||||
if (NULL != Queue->Worker) {
|
||||
|
|
|
@ -3,14 +3,25 @@
|
|||
|
||||
#include "pnpbridge_common.h"
|
||||
|
||||
MAP_RESULT Map_Add_Index(MAP_HANDLE handle, const char* key, int value) {
|
||||
MAP_RESULT
|
||||
Map_Add_Index(
|
||||
MAP_HANDLE handle,
|
||||
const char* key,
|
||||
int value
|
||||
)
|
||||
{
|
||||
char str[12];
|
||||
sprintf(str, "%d", value);
|
||||
|
||||
return Map_Add(handle, key, str);
|
||||
}
|
||||
|
||||
int Map_GetIndexValueFromKey(MAP_HANDLE handle, const char* key) {
|
||||
int
|
||||
Map_GetIndexValueFromKey(
|
||||
MAP_HANDLE handle,
|
||||
const char* key
|
||||
)
|
||||
{
|
||||
const char* index = Map_GetValueFromKey(handle, key);
|
||||
return atoi(index);
|
||||
}
|
|
@ -37,15 +37,13 @@ static void my_gballoc_free(void* ptr)
|
|||
#include "azure_c_shared_utility/crt_abstractions.h"
|
||||
#include "azure_c_shared_utility/strings.h"
|
||||
#include "iothub_module_client.h"
|
||||
#include "internal/pnp_client_core.h"
|
||||
#include "internal/lock_thread_binding_impl.h"
|
||||
|
||||
|
||||
//#include "pnp_module_client.h"
|
||||
|
||||
#include "pnpbridge.h"
|
||||
#include "pnpbridge_common.h"
|
||||
#include "discovery_manager.h"
|
||||
#include "discoveryadapter_manager.h"
|
||||
#undef ENABLE_MOCKS
|
||||
|
||||
DISCOVERY_ADAPTER EnvironmentSensorDiscovery = {
|
||||
|
@ -60,66 +58,19 @@ PDISCOVERY_ADAPTER DISCOVERY_ADAPTER_MANIFEST[] = {
|
|||
|
||||
const int DiscoveryAdapterCount = sizeof(DISCOVERY_ADAPTER_MANIFEST) / sizeof(PDISCOVERY_ADAPTER);
|
||||
|
||||
TEST_DEFINE_ENUM_TYPE(PNP_CLIENT_RESULT, PNP_CLIENT_RESULT_VALUES);
|
||||
IMPLEMENT_UMOCK_C_ENUM_TYPE(PNP_CLIENT_RESULT, PNP_CLIENT_RESULT_VALUES);
|
||||
|
||||
#define PNP_TEST_INTERFACE_HANDLE1 ((PNP_INTERFACE_CLIENT_HANDLE)0x1001)
|
||||
#define PNP_TEST_INTERFACE_HANDLE2 ((PNP_INTERFACE_CLIENT_HANDLE)0x1002)
|
||||
#define PNP_TEST_INTERFACE_HANDLE3 ((PNP_INTERFACE_CLIENT_HANDLE)0x1003)
|
||||
|
||||
static PNP_INTERFACE_CLIENT_HANDLE testPnPInterfacesToRegister[] = {PNP_TEST_INTERFACE_HANDLE1, PNP_TEST_INTERFACE_HANDLE2, PNP_TEST_INTERFACE_HANDLE3 };
|
||||
static const int testPnPInterfacesToRegisterLen = sizeof(testPnPInterfacesToRegister) / sizeof(testPnPInterfacesToRegister[0]);
|
||||
static void* pnpTestModuleRegisterInterfaceCallbackContext = (void*)0x1236;
|
||||
|
||||
static const IOTHUB_MODULE_CLIENT_HANDLE testIotHubModuleHandle = (IOTHUB_MODULE_CLIENT_HANDLE)0x1236;
|
||||
|
||||
static void on_umock_c_error(UMOCK_C_ERROR_CODE error_code)
|
||||
{
|
||||
char temp_str[256];
|
||||
(void)snprintf(temp_str, sizeof(temp_str), "umock_c reported error :%s", ENUM_TO_STRING(UMOCK_C_ERROR_CODE, error_code));
|
||||
(void)snprintf(temp_str, sizeof(temp_str), "umock_c reported error :%s", MU_ENUM_TO_STRING(UMOCK_C_ERROR_CODE, error_code));
|
||||
ASSERT_FAIL(temp_str);
|
||||
}
|
||||
|
||||
DEFINE_ENUM_STRINGS(UMOCK_C_ERROR_CODE, UMOCK_C_ERROR_CODE_VALUES)
|
||||
|
||||
// Create a custom mock function to allocate a single byte (with a corresponding free mock function).
|
||||
// This will make sure when Valgrind runs, it would catch handle leaks (which it wouldn't if this was the default mock)
|
||||
static PNP_CLIENT_CORE_HANDLE test_PnP_ClientCore_Create(PNP_IOTHUB_BINDING* iotHubBinding)
|
||||
{
|
||||
(void)iotHubBinding;
|
||||
return (PNP_CLIENT_CORE_HANDLE)my_gballoc_malloc(1);
|
||||
}
|
||||
|
||||
static void test_PnP_ClientCore_Destroy(PNP_CLIENT_CORE_HANDLE pnpClientCoreHandle)
|
||||
{
|
||||
(void)pnpClientCoreHandle;
|
||||
my_gballoc_free(pnpClientCoreHandle);
|
||||
}
|
||||
MU_DEFINE_ENUM_STRINGS(UMOCK_C_ERROR_CODE, UMOCK_C_ERROR_CODE_VALUES)
|
||||
|
||||
BEGIN_TEST_SUITE(pnpbridge_discovery_manager_ut)
|
||||
|
||||
TEST_SUITE_INITIALIZE(suite_init)
|
||||
{
|
||||
int result;
|
||||
|
||||
result = umock_c_init(on_umock_c_error);
|
||||
ASSERT_ARE_EQUAL(int, 0, result);
|
||||
|
||||
REGISTER_UMOCK_ALIAS_TYPE(PNP_CLIENT_CORE_HANDLE, void*);
|
||||
REGISTER_UMOCK_ALIAS_TYPE(PNP_INTERFACE_REGISTERED_CALLBACK, void*);
|
||||
|
||||
|
||||
REGISTER_GLOBAL_MOCK_HOOK(gballoc_malloc, my_gballoc_malloc);
|
||||
REGISTER_GLOBAL_MOCK_FAIL_RETURN(gballoc_malloc, NULL);
|
||||
REGISTER_GLOBAL_MOCK_HOOK(gballoc_calloc, my_gballoc_calloc);
|
||||
REGISTER_GLOBAL_MOCK_FAIL_RETURN(gballoc_calloc, NULL);
|
||||
REGISTER_GLOBAL_MOCK_HOOK(gballoc_free, my_gballoc_free);
|
||||
|
||||
REGISTER_GLOBAL_MOCK_HOOK(PnP_ClientCore_Create, test_PnP_ClientCore_Create);
|
||||
REGISTER_GLOBAL_MOCK_FAIL_RETURN(PnP_ClientCore_Create, NULL);
|
||||
REGISTER_GLOBAL_MOCK_HOOK(PnP_ClientCore_Destroy, test_PnP_ClientCore_Destroy);
|
||||
REGISTER_GLOBAL_MOCK_RETURN(PnP_ClientCore_RegisterInterfacesAsync, PNP_CLIENT_OK);
|
||||
REGISTER_GLOBAL_MOCK_FAIL_RETURN(PnP_ClientCore_RegisterInterfacesAsync, PNP_CLIENT_ERROR);
|
||||
}
|
||||
|
||||
TEST_FUNCTION_INITIALIZE(TestMethodInit)
|
||||
|
@ -161,139 +112,5 @@ TEST_FUNCTION(PnpAdapterManager_InitializeAdapter_ok)
|
|||
DiscoveryAdapterManager_Release(discoveryMgr);
|
||||
}
|
||||
|
||||
// TEST_FUNCTION(PnP_ModuleClient_CreateFromModuleHandle_NULL_handle_fails)
|
||||
// {
|
||||
// // arrange
|
||||
// PNP_MODULE_CLIENT_HANDLE h;
|
||||
|
||||
// //act
|
||||
// h = PnP_ModuleClient_CreateFromModuleHandle(NULL);
|
||||
|
||||
// //assert
|
||||
// ASSERT_IS_NULL(h);
|
||||
// }
|
||||
|
||||
// TEST_FUNCTION(PnP_ModuleClient_CreateFromModuleHandle_fail)
|
||||
// {
|
||||
// // arrange
|
||||
// int negativeTestsInitResult = umock_c_negative_tests_init();
|
||||
// ASSERT_ARE_EQUAL(int, 0, negativeTestsInitResult);
|
||||
|
||||
// PNP_MODULE_CLIENT_HANDLE h;
|
||||
|
||||
// set_expected_calls_for_PnP_ModuleClient_CreateFromModuleHandle();
|
||||
// umock_c_negative_tests_snapshot();
|
||||
|
||||
// size_t count = umock_c_negative_tests_call_count();
|
||||
// for (size_t i = 0; i < count; i++)
|
||||
// {
|
||||
// char message[256];
|
||||
// sprintf(message, "PnP_ModuleClient_CreateFromModuleHandle failure in test %lu", (unsigned long)i);
|
||||
|
||||
// umock_c_negative_tests_reset();
|
||||
// umock_c_negative_tests_fail_call(i);
|
||||
|
||||
// h = PnP_ModuleClient_CreateFromModuleHandle(testIotHubModuleHandle);
|
||||
|
||||
// //assert
|
||||
// ASSERT_IS_NULL(h);
|
||||
// }
|
||||
|
||||
// //cleanup
|
||||
// umock_c_negative_tests_deinit();
|
||||
// }
|
||||
|
||||
|
||||
// static PNP_MODULE_CLIENT_HANDLE allocate_PNP_MODULE_CLIENT_HANDLE_for_test()
|
||||
// {
|
||||
// PNP_MODULE_CLIENT_HANDLE h = PnP_ModuleClient_CreateFromModuleHandle(testIotHubModuleHandle);
|
||||
// ASSERT_IS_NOT_NULL(h);
|
||||
// umock_c_reset_all_calls();
|
||||
// return h;
|
||||
// }
|
||||
|
||||
// ///////////////////////////////////////////////////////////////////////////////
|
||||
// // PnP_ModuleClient_Destroy
|
||||
// ///////////////////////////////////////////////////////////////////////////////
|
||||
// static void set_expected_calls_for_PnP_ModuleClient_Destroy()
|
||||
// {
|
||||
// STRICT_EXPECTED_CALL(PnP_ClientCore_Destroy(IGNORED_PTR_ARG));
|
||||
// }
|
||||
|
||||
// TEST_FUNCTION(PnP_ModuleClient_Destroy_ok)
|
||||
// {
|
||||
// //arrange
|
||||
// PNP_MODULE_CLIENT_HANDLE h = allocate_PNP_MODULE_CLIENT_HANDLE_for_test();
|
||||
// set_expected_calls_for_PnP_ModuleClient_Destroy();
|
||||
|
||||
// //act
|
||||
// PnP_ModuleClient_Destroy(h);
|
||||
|
||||
// //assert
|
||||
// ASSERT_ARE_EQUAL(char_ptr, umock_c_get_expected_calls(), umock_c_get_actual_calls());
|
||||
// }
|
||||
|
||||
// ///////////////////////////////////////////////////////////////////////////////
|
||||
// // PnP_ModuleClient_RegisterInterfacesAsync
|
||||
// ///////////////////////////////////////////////////////////////////////////////
|
||||
// static void pnpTestModuleRegisterInterfaceCallback(PNP_REPORTED_INTERFACES_STATUS pnpInterfaceStatus, void* userContextCallback)
|
||||
// {
|
||||
// (void)pnpInterfaceStatus;
|
||||
// (void)userContextCallback;
|
||||
// }
|
||||
|
||||
// static void set_expected_calls_for_PnP_ModuleClient_RegisterInterfacesAsync()
|
||||
// {
|
||||
// STRICT_EXPECTED_CALL(PnP_ClientCore_RegisterInterfacesAsync(IGNORED_PTR_ARG, testPnPInterfacesToRegister, testPnPInterfacesToRegisterLen, pnpTestModuleRegisterInterfaceCallback, pnpTestModuleRegisterInterfaceCallbackContext));
|
||||
// }
|
||||
|
||||
// TEST_FUNCTION(PnP_ModuleClient_RegisterInterfacesAsync_ok)
|
||||
// {
|
||||
// // arrange
|
||||
// PNP_MODULE_CLIENT_HANDLE h = allocate_PNP_MODULE_CLIENT_HANDLE_for_test();
|
||||
// PNP_CLIENT_RESULT result;
|
||||
|
||||
// //act
|
||||
// set_expected_calls_for_PnP_ModuleClient_RegisterInterfacesAsync();
|
||||
// result = PnP_ModuleClient_RegisterInterfacesAsync(h, testPnPInterfacesToRegister, testPnPInterfacesToRegisterLen, pnpTestModuleRegisterInterfaceCallback, pnpTestModuleRegisterInterfaceCallbackContext);
|
||||
|
||||
// //assert
|
||||
// ASSERT_ARE_EQUAL(PNP_CLIENT_RESULT, result, PNP_CLIENT_OK);
|
||||
// ASSERT_ARE_EQUAL(char_ptr, umock_c_get_expected_calls(), umock_c_get_actual_calls());
|
||||
|
||||
// //cleanup
|
||||
// PnP_ModuleClient_Destroy(h);
|
||||
// }
|
||||
|
||||
// TEST_FUNCTION(PnP_ModuleClient_RegisterInterfacesAsync_fail)
|
||||
// {
|
||||
// // arrange
|
||||
// int negativeTestsInitResult = umock_c_negative_tests_init();
|
||||
// ASSERT_ARE_EQUAL(int, 0, negativeTestsInitResult);
|
||||
|
||||
// PNP_MODULE_CLIENT_HANDLE h = allocate_PNP_MODULE_CLIENT_HANDLE_for_test();
|
||||
// PNP_CLIENT_RESULT result;
|
||||
|
||||
// set_expected_calls_for_PnP_ModuleClient_RegisterInterfacesAsync();
|
||||
// umock_c_negative_tests_snapshot();
|
||||
|
||||
// size_t count = umock_c_negative_tests_call_count();
|
||||
// for (size_t i = 0; i < count; i++)
|
||||
// {
|
||||
// umock_c_negative_tests_reset();
|
||||
// umock_c_negative_tests_fail_call(i);
|
||||
|
||||
// //act
|
||||
// result = PnP_ModuleClient_RegisterInterfacesAsync(h, testPnPInterfacesToRegister, testPnPInterfacesToRegisterLen, pnpTestModuleRegisterInterfaceCallback, pnpTestModuleRegisterInterfaceCallbackContext);
|
||||
|
||||
// //assert
|
||||
// ASSERT_ARE_NOT_EQUAL(PNP_CLIENT_RESULT, result, PNP_CLIENT_OK, "PnP_ModuleClient_RegisterInterfacesAsync failure in test %lu", (unsigned long)i);
|
||||
// }
|
||||
|
||||
// //cleanup
|
||||
// umock_c_negative_tests_deinit();
|
||||
// PnP_ModuleClient_Destroy(h);
|
||||
// }
|
||||
|
||||
END_TEST_SUITE(pnpbridge_discovery_manager_ut)
|
||||
|
||||
|
|
Загрузка…
Ссылка в новой задаче