Fixes for otJoinerStart on Windows (#1294)

This commit is contained in:
Nick Banks
2017-02-09 13:11:02 -08:00
committed by Jonathan Hui
parent efc4599d62
commit 4d28e765fe
6 changed files with 140 additions and 26 deletions
+14 -7
View File
@@ -59,7 +59,8 @@ typedef enum _OTLWF_NOTIF_TYPE
OTLWF_NOTIF_ACTIVE_SCAN,
OTLWF_NOTIF_ENERGY_SCAN,
OTLWF_NOTIF_COMMISSIONER_ENERGY_REPORT,
OTLWF_NOTIF_COMMISSIONER_PANID_QUERY
OTLWF_NOTIF_COMMISSIONER_PANID_QUERY,
OTLWF_NOTIF_JOINER_COMPLETE
} OTLWF_NOTIF_TYPE;
@@ -123,6 +124,12 @@ typedef enum _OTLWF_NOTIF_TYPE
uint16_t PanId;
uint32_t ChannelMask;
} CommissionerPanIdQueryPayload;
// Payload for OTLWF_NOTIF_JOINER_COMPLETE
struct
{
ThreadError Error;
} JoinerCompletePayload;
};
} OTLWF_NOTIFICATION, *POTLWF_NOTIFICATION;
@@ -517,12 +524,12 @@ typedef enum _OTLWF_NOTIF_TYPE
#define OPENTHREAD_VENDOR_DATA_MAX_LENGTH 64
typedef struct otCommissionConfig
{
uint8_t PSKd[OPENTHREAD_PSK_MAX_LENGTH + 1];
uint8_t ProvisioningUrl[OPENTHREAD_PROV_URL_MAX_LENGTH + 1];
uint8_t VendorName[OPENTHREAD_VENDOR_NAME_MAX_LENGTH + 1];
uint8_t VendorModel[OPENTHREAD_VENDOR_MODEL_MAX_LENGTH + 1];
uint8_t VendorSwVersion[OPENTHREAD_VENDOR_SW_VERSION_MAX_LENGTH + 1];
uint8_t VendorData[OPENTHREAD_VENDOR_DATA_MAX_LENGTH + 1];
char PSKd[OPENTHREAD_PSK_MAX_LENGTH + 1];
char ProvisioningUrl[OPENTHREAD_PROV_URL_MAX_LENGTH + 1];
char VendorName[OPENTHREAD_VENDOR_NAME_MAX_LENGTH + 1];
char VendorModel[OPENTHREAD_VENDOR_MODEL_MAX_LENGTH + 1];
char VendorSwVersion[OPENTHREAD_VENDOR_SW_VERSION_MAX_LENGTH + 1];
char VendorData[OPENTHREAD_VENDOR_DATA_MAX_LENGTH + 1];
} otCommissionConfig;
#define IOCTL_OTLWF_OT_JOINER_START \
+65 -7
View File
@@ -105,6 +105,7 @@ typedef otCallback<otHandleEnergyScanResult> otApiEnergyScanCallback;
typedef otCallback<otStateChangedCallback> otApiStateChangeCallback;
typedef otCallback<otCommissionerEnergyReportCallback> otApiCommissionerEnergyReportCallback;
typedef otCallback<otCommissionerPanIdConflictCallback> otApiCommissionerPanIdConflictCallback;
typedef otCallback<otJoinerCallback> otApiJoinerCallback;
typedef struct otApiInstance
{
@@ -127,6 +128,7 @@ typedef struct otApiInstance
vector<otApiStateChangeCallback*> StateChangedCallbacks;
vector<otApiCommissionerEnergyReportCallback*> CommissionerEnergyReportCallbacks;
vector<otApiCommissionerPanIdConflictCallback*> CommissionerPanIdConflictCallbacks;
vector<otApiJoinerCallback*> JoinerCallbacks;
// Constructor
otApiInstance() :
@@ -358,6 +360,9 @@ otApiFinalize(
vector<otApiCommissionerPanIdConflictCallback*> CommissionerPanIdConflictCallbacks(aApitInstance->CommissionerPanIdConflictCallbacks);
aApitInstance->CommissionerPanIdConflictCallbacks.clear();
vector<otApiJoinerCallback*> JoinerCallbacks(aApitInstance->JoinerCallbacks);
aApitInstance->JoinerCallbacks.clear();
#ifdef DEBUG_ASYNC_IO
otLogDebgApi("Clearing Threadpool Wait");
#endif
@@ -404,6 +409,11 @@ otApiFinalize(
CommissionerPanIdConflictCallbacks[i]->Release(true);
delete CommissionerPanIdConflictCallbacks[i];
}
for (size_t i = 0; i < JoinerCallbacks.size(); i++)
{
JoinerCallbacks[i]->Release(true);
delete JoinerCallbacks[i];
}
// Clean up threadpool wait
if (tpWait)
@@ -654,6 +664,39 @@ ProcessNotification(
Callback->Release();
}
}
else if (Notif->NotifType == OTLWF_NOTIF_JOINER_COMPLETE)
{
otCallback<otJoinerCallback>* Callback = nullptr;
EnterCriticalSection(&aApitInstance->CallbackLock);
for (size_t i = 0; i < aApitInstance->JoinerCallbacks.size(); i++)
{
if (aApitInstance->JoinerCallbacks[i]->InterfaceGuid == Notif->InterfaceGuid)
{
aApitInstance->JoinerCallbacks[i]->AddRef();
Callback = aApitInstance->JoinerCallbacks[i];
break;
}
}
LeaveCriticalSection(&aApitInstance->CallbackLock);
// Invoke the callback outside the lock and release ref when done
if (Callback)
{
aApitInstance->SetCallback(
aApitInstance->JoinerCallbacks,
Notif->InterfaceGuid, (otJoinerCallback)nullptr, (PVOID)nullptr
);
Callback->Callback(
Notif->JoinerCompletePayload.Error,
Callback->CallbackContext);
Callback->Release();
}
}
else
{
// Unexpected notif type
@@ -3652,12 +3695,12 @@ ThreadError
OTCALL
otJoinerStart(
_In_ otInstance *aInstance,
const char *aPSKd,
const char *aProvisioningUrl,
const char *aVendorName,
const char *aVendorModel,
const char *aVendorSwVersion,
const char *aVendorData,
_Null_terminated_ const char *aPSKd,
_Null_terminated_ const char *aProvisioningUrl,
_Null_terminated_ const char *aVendorName,
_Null_terminated_ const char *aVendorModel,
_Null_terminated_ const char *aVendorSwVersion,
_Null_terminated_ const char *aVendorData,
_In_ otJoinerCallback aCallback,
_In_ void *aCallbackContext
)
@@ -3690,7 +3733,22 @@ otJoinerStart(
memcpy_s(config.VendorSwVersion, sizeof(config.VendorSwVersion), aVendorSwVersion, aVendorSwVersionLength);
memcpy_s(config.VendorData, sizeof(config.VendorData), aVendorData, aVendorDataLength);
return DwordToThreadError(SetIOCTL(aInstance, IOCTL_OTLWF_OT_JOINER_START, (const otCommissionConfig*)&config));
aInstance->ApiHandle->SetCallback(
aInstance->ApiHandle->JoinerCallbacks,
aInstance->InterfaceGuid, aCallback, aCallbackContext
);
auto ret = DwordToThreadError(SetIOCTL(aInstance, IOCTL_OTLWF_OT_JOINER_START, (const otCommissionConfig*)&config));
if (ret != kThreadError_None)
{
aInstance->ApiHandle->SetCallback(
aInstance->ApiHandle->JoinerCallbacks,
aInstance->InterfaceGuid, (otJoinerCallback)nullptr, (PVOID)nullptr
);
}
return ret;
}
OTAPI
+8
View File
@@ -252,6 +252,14 @@ typedef struct _MS_FILTER
ULONG otAllocationID;
#endif
//
// OpenThread Joiner Vendor Info
//
char otVendorName[OPENTHREAD_VENDOR_NAME_MAX_LENGTH + 1];
char otVendorModel[OPENTHREAD_VENDOR_MODEL_MAX_LENGTH + 1];
char otVendorSwVersion[OPENTHREAD_VENDOR_SW_VERSION_MAX_LENGTH + 1];
char otVendorData[OPENTHREAD_VENDOR_DATA_MAX_LENGTH + 1];
//
// OpenThread context buffer
//
+32 -12
View File
@@ -5254,18 +5254,38 @@ otLwfIoCtl_otJoinerStart(
if (InBufferLength >= sizeof(otCommissionConfig))
{
otCommissionConfig *aConfig = (otCommissionConfig*)InBuffer;
status = ThreadErrorToNtstatus(
otJoinerStart(
pFilter->otCtx,
(const char*)aConfig->PSKd,
(const char*)aConfig->ProvisioningUrl,
(const char*)aConfig->VendorName,
(const char*)aConfig->VendorModel,
(const char*)aConfig->VendorSwVersion,
(const char*)aConfig->VendorData,
NULL, // TODO: handle the joiner completion callback
NULL)
);
#define IsNotNullTerminated(buf) (strnlen(buf, sizeof(buf)) == sizeof(buf))
if (IsNotNullTerminated(aConfig->PSKd) ||
IsNotNullTerminated(aConfig->ProvisioningUrl) ||
IsNotNullTerminated(aConfig->VendorName) ||
IsNotNullTerminated(aConfig->VendorModel) ||
IsNotNullTerminated(aConfig->VendorSwVersion) ||
IsNotNullTerminated(aConfig->VendorData))
{
status = STATUS_INVALID_PARAMETER;
}
else
{
strcpy_s(pFilter->otVendorName, sizeof(pFilter->otVendorName), aConfig->VendorName);
strcpy_s(pFilter->otVendorModel, sizeof(pFilter->otVendorModel), aConfig->VendorModel);
strcpy_s(pFilter->otVendorSwVersion, sizeof(pFilter->otVendorSwVersion), aConfig->VendorSwVersion);
strcpy_s(pFilter->otVendorData, sizeof(pFilter->otVendorData), aConfig->VendorData);
status = ThreadErrorToNtstatus(
otJoinerStart(
pFilter->otCtx,
aConfig->PSKd,
aConfig->ProvisioningUrl,
pFilter->otVendorName,
pFilter->otVendorModel,
pFilter->otVendorSwVersion,
pFilter->otVendorData,
otLwfJoinerCallback,
pFilter)
);
}
}
return status;
+20
View File
@@ -531,6 +531,26 @@ void otLwfCommissionerPanIdConflictCallback(uint16_t aPanId, uint32_t aChannelMa
LogFuncExit(DRIVER_DEFAULT);
}
void otLwfJoinerCallback(ThreadError aError, _In_ void *aContext)
{
LogFuncEntry(DRIVER_DEFAULT);
PMS_FILTER pFilter = (PMS_FILTER)aContext;
PFILTER_NOTIFICATION_ENTRY NotifEntry = FILTER_ALLOC_NOTIF(pFilter);
if (NotifEntry)
{
RtlZeroMemory(NotifEntry, sizeof(FILTER_NOTIFICATION_ENTRY));
NotifEntry->Notif.InterfaceGuid = pFilter->InterfaceGuid;
NotifEntry->Notif.NotifType = OTLWF_NOTIF_JOINER_COMPLETE;
NotifEntry->Notif.JoinerCompletePayload.Error = aError;
otLwfIndicateNotification(NotifEntry);
}
LogFuncExit(DRIVER_DEFAULT);
}
_IRQL_requires_max_(DISPATCH_LEVEL)
void
otLwfThreadValueIs(
+1
View File
@@ -152,6 +152,7 @@ void otLwfEnergyScanCallback(_In_ otEnergyScanResult *aResult, _In_ void *aConte
void otLwfDiscoverCallback(_In_ otActiveScanResult *aResult, _In_ void *aContext);
void otLwfCommissionerEnergyReportCallback(uint32_t aChannelMask, const uint8_t *aEnergyList, uint8_t aEnergyListLength, void *aContext);
void otLwfCommissionerPanIdConflictCallback(uint16_t aPanId, uint32_t aChannelMask, _In_ void *aContext);
void otLwfJoinerCallback(ThreadError aError, _In_ void *aContext);
//
// Value Callbacks