Add PSKc API (#1635)

* add pskc api

* add pskc cli

* add NCP api of PSKc

* apply PSKc from network

* implement PSKC api for windows

* add name for pskc property

* clear active and pending dataset when settings pskc
This commit is contained in:
Buke Po
2017-04-27 16:32:34 -07:00
committed by Jonathan Hui
parent 0759f874e0
commit 024c44de5c
18 changed files with 396 additions and 4 deletions
@@ -689,8 +689,13 @@ typedef struct otCommissionConfig
// GUID - InterfaceGuid
// uint8_t - aRouterId
#define IOCTL_OTLWF_OT_PSKC \
OTLWF_CTL_CODE(195, METHOD_BUFFERED, FILE_READ_DATA | FILE_WRITE_DATA)
// GUID - InterfaceGuid
// otPSKc - aPSKc
// OpenThread function IOCTL codes
#define MIN_OTLWF_IOCTL_FUNC_CODE 100
#define MAX_OTLWF_IOCTL_FUNC_CODE 194
#define MAX_OTLWF_IOCTL_FUNC_CODE 195
#endif //__OTLWFIOCTL_H__
+36
View File
@@ -1646,6 +1646,42 @@ otThreadSetMasterKey(
return DwordToThreadError(SendIOCTL(aInstance->ApiHandle, IOCTL_OTLWF_OT_MASTER_KEY, Buffer, sizeof(Buffer), nullptr, 0));
}
OTAPI
const uint8_t *
OTCALL
otThreadGetPSKc(
_In_ otInstance *aInstance
)
{
if (aInstance == nullptr) return nullptr;
uint8_t *Result = (uint8_t*)malloc(sizeof(otPSKc));
if (Result == nullptr) return nullptr;
if (QueryIOCTL(aInstance, IOCTL_OTLWF_OT_PSKC, Result) != ERROR_SUCCESS)
{
free(Result);
return nullptr;
}
return Result;
}
OTAPI
ThreadError
OTCALL
otThreadSetPSKc(
_In_ otInstance *aInstance,
const uint8_t *aPSKc
)
{
if (aInstance == nullptr) return kThreadError_InvalidArgs;
BYTE Buffer[sizeof(GUID) + sizeof(otPSKc)];
memcpy_s(Buffer, sizeof(Buffer), &aInstance->InterfaceGuid, sizeof(GUID));
memcpy_s(Buffer + sizeof(GUID), sizeof(Buffer) - sizeof(GUID), aPSKc, sizeof(otPSKc));
return DwordToThreadError(SendIOCTL(aInstance->ApiHandle, IOCTL_OTLWF_OT_PSKC, Buffer, sizeof(Buffer), nullptr, 0));
}
OTAPI
int8_t
OTCALL
+105
View File
@@ -140,6 +140,7 @@ OTLWF_IOCTL_HANDLER IoCtls[] =
{ "IOCTL_OTLWF_OT_FACTORY_RESET", REF_IOCTL_FUNC(otFactoryReset) },
{ "IOCTL_OTLWF_OT_THREAD_AUTO_START", REF_IOCTL_FUNC(otThreadAutoStart) },
{ "IOCTL_OTLWF_OT_PREFERRED_ROUTER_ID", REF_IOCTL_FUNC(otThreadPreferredRouterId) },
{ "IOCTL_OTLWF_OT_PSKC", REF_IOCTL_FUNC_WITH_TUN(otPSKc) },
};
static_assert(ARRAYSIZE(IoCtls) == (MAX_OTLWF_IOCTL_FUNC_CODE - MIN_OTLWF_IOCTL_FUNC_CODE) + 1,
@@ -1725,6 +1726,110 @@ otLwfTunIoCtl_otMasterKey_Handler(
return status;
}
_IRQL_requires_max_(PASSIVE_LEVEL)
NTSTATUS
otLwfIoCtl_otPSKc(
_In_ PMS_FILTER pFilter,
_In_reads_bytes_(InBufferLength)
PUCHAR InBuffer,
_In_ ULONG InBufferLength,
_Out_writes_bytes_(*OutBufferLength)
PVOID OutBuffer,
_Inout_ PULONG OutBufferLength
)
{
NTSTATUS status = STATUS_INVALID_PARAMETER;
if (InBufferLength >= sizeof(otPSKc))
{
status = ThreadErrorToNtstatus(otThreadSetPSKc(pFilter->otCtx, InBuffer));
*OutBufferLength = 0;
}
else if (*OutBufferLength >= sizeof(otPSKc))
{
const uint8_t* aPSKc = otThreadGetPSKc(pFilter->otCtx);
memcpy(OutBuffer, aPSKc, sizeof(otPSKc));
*OutBufferLength = sizeof(otPSKc);
status = STATUS_SUCCESS;
}
else
{
*OutBufferLength = 0;
}
return status;
}
_IRQL_requires_max_(PASSIVE_LEVEL)
NTSTATUS
otLwfTunIoCtl_otPSKc(
_In_ PMS_FILTER pFilter,
_In_ PIRP pIrp,
_In_reads_bytes_(InBufferLength)
PUCHAR InBuffer,
_In_ ULONG InBufferLength,
_In_ ULONG OutBufferLength
)
{
NTSTATUS status = STATUS_INVALID_PARAMETER;
if (InBufferLength >= sizeof(otPSKc))
{
status =
otLwfTunSendCommandForIrp(
pFilter,
pIrp,
NULL,
SPINEL_CMD_PROP_VALUE_SET,
SPINEL_PROP_NET_PSKC,
sizeof(otPSKc) + sizeof(uint16_t),
SPINEL_DATATYPE_DATA_S,
(otPSKc*)InBuffer,
OT_PSKC_MAX_SIZE);
}
else if (OutBufferLength >= sizeof(otPSKc))
{
status =
otLwfTunSendCommandForIrp(
pFilter,
pIrp,
otLwfTunIoCtl_otPSKc_Handler,
SPINEL_CMD_PROP_VALUE_GET,
SPINEL_PROP_NET_PSKC,
0,
NULL);
}
return status;
}
_IRQL_requires_max_(DISPATCH_LEVEL)
NTSTATUS
otLwfTunIoCtl_otPSKc_Handler(
_In_ spinel_prop_key_t Key,
_In_reads_bytes_(DataLength) const uint8_t* Data,
_In_ spinel_size_t DataLength,
_Out_writes_bytes_(*OutBufferLength)
PVOID OutBuffer,
_Inout_ PULONG OutBufferLength
)
{
NTSTATUS status = STATUS_INVALID_PARAMETER;
if (Key == SPINEL_PROP_NET_PSKC)
{
uint8_t *data = NULL;
spinel_size_t aPSKcLength;
if (try_spinel_datatype_unpack(Data, DataLength, SPINEL_DATATYPE_DATA_S, &data, &aPSKcLength) && data != NULL &&
aPSKcLength == sizeof(otPSKc))
{
memcpy(OutBuffer, data, sizeof(otPSKc));
*OutBufferLength = sizeof(otPSKc);
status = STATUS_SUCCESS;
}
}
return status;
}
_IRQL_requires_max_(PASSIVE_LEVEL)
NTSTATUS
otLwfIoCtl_otMeshLocalEid(
@@ -226,5 +226,6 @@ DECL_IOCTL_FUNC_WITH_TUN2(otKeySwitchGuardtime);
DECL_IOCTL_FUNC(otFactoryReset);
DECL_IOCTL_FUNC(otThreadAutoStart);
DECL_IOCTL_FUNC(otThreadPreferredRouterId);
DECL_IOCTL_FUNC_WITH_TUN2(otPSKc);
#endif // _IOCONTROL_H
@@ -1231,6 +1231,41 @@ OTNODEAPI const char* OTCALL otNodeGetMasterkey(otNode* aNode)
return str;
}
OTNODEAPI int32_t OTCALL otNodeSetPSKc(otNode* aNode, const char *aPSKc)
{
otLogFuncEntryMsg("[%d] %s", aNode->mId, aPSKc);
printf("%d: pskc %s\r\n", aNode->mId, aPSKc);
uint8_t pskc[OT_PSKC_MAX_SIZE];
if (Hex2Bin(aPSKc, pskc, sizeof(pskc)) != OT_PSKC_MAX_SIZE)
{
printf("invalid pskc %s\r\n", aPSKc);
return kThreadError_Parse;
}
auto error = otThreadSetPSKc(aNode->mInstance, pskc);
otLogFuncExit();
return error;
}
OTNODEAPI const char* OTCALL otNodeGetPSKc(otNode* aNode)
{
otLogFuncEntryMsg("[%d]", aNode->mId);
auto aPSKc = otThreadGetPSKc(aNode->mInstance);
uint8_t strLength = 2 * OT_PSKC_MAX_SIZE + 1;
char* str = (char*)malloc(strLength);
if (str != nullptr)
{
aNode->mMemoryToFree.push_back(str);
for (int i = 0; i < OT_PSKC_MAX_SIZE; i++)
sprintf_s(str + i * 2, strLength - (2 * i), "%02x", aPSKc[i]);
printf("%d: pskc\r\n%s\r\n", aNode->mId, str);
}
otFreeMemory(aPSKc);
otLogFuncExit();
return str;
}
OTNODEAPI uint32_t OTCALL otNodeGetKeySequenceCounter(otNode* aNode)
{
otLogFuncEntryMsg("[%d]", aNode->mId);