Spinel: Radio Source Match Support (#1371)

* Add Spinel Source Match Properties

* Wrap Source Match NCP code with OPENTHREAD_ENABLE_RAW_LINK_API

* Update spinel docs

* Handle SendPropertyUpdate errors
This commit is contained in:
Nick Banks
2017-02-28 21:52:41 -08:00
committed by Jonathan Hui
parent ffeeeb96d2
commit 95ff7b55dc
10 changed files with 611 additions and 203 deletions
@@ -124,3 +124,34 @@ Structure Parameters:
* Type: Read-Write
* Packed-Encoding: `b`
### PROP 4867: SPINEL_PROP_MAC_SRC_MATCH_ENABLED {#prop-mac-src-match-enabled}
* Type: Write
* Packed-Encoding: `b`
Set to true to enable radio source matching or false to disable it. This property
is only available if the `SPINEL_CAP_MAC_RAW` capability is present. The source match
functionality is used by radios when generating ACKs. The short and extended address
lists are used for settings the Frame Pending bit in the ACKs.
### PROP 4868: SPINEL_PROP_MAC_SRC_MATCH_SHORT_ADDRESSES {#prop-mac-src-match-short-addresses}
* Type: Write
* Packed-Encoding: `A(S)`
Configures the list of short addresses used for source matching. This property
is only available if the `SPINEL_CAP_MAC_RAW` capability is present.
Structure Parameters:
* `S`: Short address for hardware generated ACKs
### PROP 4869: SPINEL_PROP_MAC_SRC_MATCH_EXTENDED_ADDRESSES {#prop-mac-src-match-extended-addresses}
* Type: Write
* Packed-Encoding: `A(E)`
Configures the list of extended addresses used for source matching. This property
is only available if the `SPINEL_CAP_MAC_RAW` capability is present.
Structure Parameters:
* `E`: EUI64 address for hardware generated ACKs
+2 -1
View File
@@ -7,7 +7,8 @@
Set to 1 if the PHY is enabled, set to 0 otherwise.
May be directly enabled to bypass higher-level packet processing
in order to implement things like packet sniffers.
in order to implement things like packet sniffers. This property
can only be written if the `SPINEL_CAP_MAC_RAW` capability is present.
### PROP 33: PROP_PHY_CHAN {#prop-phy-chan}
* Type: Read-Write
+78 -14
View File
@@ -1113,6 +1113,7 @@ otLwfCmdGetProp(
typedef struct _SPINEL_SET_PROP_CONTEXT
{
KEVENT CompletionEvent;
UINT ExpectedResultCommand;
spinel_prop_key_t Key;
NTSTATUS Status;
} SPINEL_SET_PROP_CONTEXT;
@@ -1138,11 +1139,7 @@ otLwfSetPropHandler(
{
CmdContext->Status = STATUS_CANCELLED;
}
else if (Command != SPINEL_CMD_PROP_VALUE_IS)
{
CmdContext->Status = STATUS_INVALID_PARAMETER;
}
else if (Key == SPINEL_PROP_LAST_STATUS)
else if (Command == SPINEL_CMD_PROP_VALUE_IS && Key == SPINEL_PROP_LAST_STATUS)
{
spinel_status_t spinel_status = SPINEL_STATUS_OK;
spinel_ssize_t packed_len = spinel_datatype_unpack(Data, DataLength, "i", &spinel_status);
@@ -1157,12 +1154,18 @@ otLwfSetPropHandler(
CmdContext->Status = ThreadErrorToNtstatus(errorCode);
}
}
else if (Command != CmdContext->ExpectedResultCommand)
{
NT_ASSERT(FALSE);
CmdContext->Status = STATUS_INVALID_PARAMETER;
}
else if (Key == CmdContext->Key)
{
CmdContext->Status = STATUS_SUCCESS;
}
else
{
NT_ASSERT(FALSE);
CmdContext->Status = STATUS_INVALID_PARAMETER;
}
@@ -1174,11 +1177,12 @@ otLwfSetPropHandler(
_IRQL_requires_max_(PASSIVE_LEVEL)
NTSTATUS
otLwfCmdSetProp(
otLwfCmdSetPropV(
_In_ PMS_FILTER pFilter,
_In_ UINT Command,
_In_ spinel_prop_key_t Key,
_In_ const char *pack_format,
...
_In_opt_ const char *pack_format,
_In_opt_ va_list args
)
{
NTSTATUS status;
@@ -1191,10 +1195,24 @@ otLwfCmdSetProp(
Context.Key = Key;
Context.Status = STATUS_SUCCESS;
LogFuncEntryMsg(DRIVER_DEFAULT, "Key=%u", (ULONG)Key);
LogFuncEntryMsg(DRIVER_DEFAULT, "Cmd=%u Key=%u", Command, (ULONG)Key);
va_list args;
va_start(args, pack_format);
if (Command == SPINEL_CMD_PROP_VALUE_SET)
{
Context.ExpectedResultCommand = SPINEL_CMD_PROP_VALUE_IS;
}
else if (Command == SPINEL_CMD_PROP_VALUE_INSERT)
{
Context.ExpectedResultCommand = SPINEL_CMD_PROP_VALUE_INSERTED;
}
else if (Command == SPINEL_CMD_PROP_VALUE_REMOVE)
{
Context.ExpectedResultCommand = SPINEL_CMD_PROP_VALUE_REMOVED;
}
else
{
ASSERT(FALSE);
}
// Send the request transaction
status =
@@ -1203,7 +1221,7 @@ otLwfCmdSetProp(
otLwfSetPropHandler,
&Context,
&tid,
SPINEL_CMD_PROP_VALUE_SET,
Command,
Key,
8,
pack_format,
@@ -1236,14 +1254,60 @@ otLwfCmdSetProp(
{
Context.Status = status;
}
va_end(args);
LogFuncExitNT(DRIVER_DEFAULT, Context.Status);
return Context.Status;
}
_IRQL_requires_max_(PASSIVE_LEVEL)
NTSTATUS
otLwfCmdSetProp(
_In_ PMS_FILTER pFilter,
_In_ spinel_prop_key_t Key,
_In_opt_ const char *pack_format,
...
)
{
va_list args;
va_start(args, pack_format);
NTSTATUS status = otLwfCmdSetPropV(pFilter, SPINEL_CMD_PROP_VALUE_SET, Key, pack_format, args);
va_end(args);
return status;
}
_IRQL_requires_max_(PASSIVE_LEVEL)
NTSTATUS
otLwfCmdInsertProp(
_In_ PMS_FILTER pFilter,
_In_ spinel_prop_key_t Key,
_In_opt_ const char *pack_format,
...
)
{
va_list args;
va_start(args, pack_format);
NTSTATUS status = otLwfCmdSetPropV(pFilter, SPINEL_CMD_PROP_VALUE_INSERT, Key, pack_format, args);
va_end(args);
return status;
}
_IRQL_requires_max_(PASSIVE_LEVEL)
NTSTATUS
otLwfCmdRemoveProp(
_In_ PMS_FILTER pFilter,
_In_ spinel_prop_key_t Key,
_In_opt_ const char *pack_format,
...
)
{
va_list args;
va_start(args, pack_format);
NTSTATUS status = otLwfCmdSetPropV(pFilter, SPINEL_CMD_PROP_VALUE_REMOVE, Key, pack_format, args);
va_end(args);
return status;
}
//
// General Spinel Helpers
//
+19 -1
View File
@@ -162,7 +162,25 @@ NTSTATUS
otLwfCmdSetProp(
_In_ PMS_FILTER pFilter,
_In_ spinel_prop_key_t Key,
_In_ const char *pack_format,
_In_opt_ const char *pack_format,
...
);
_IRQL_requires_max_(PASSIVE_LEVEL)
NTSTATUS
otLwfCmdInsertProp(
_In_ PMS_FILTER pFilter,
_In_ spinel_prop_key_t Key,
_In_opt_ const char *pack_format,
...
);
_IRQL_requires_max_(PASSIVE_LEVEL)
NTSTATUS
otLwfCmdRemoveProp(
_In_ PMS_FILTER pFilter,
_In_ spinel_prop_key_t Key,
_In_opt_ const char *pack_format,
...
);
-6
View File
@@ -111,8 +111,6 @@ typedef enum OTLWF_DEVICE_STATUS
#define OT_EVENT_TIMER_RUNNING 1
#define OT_EVENT_TIMER_FIRED 2
#define MAX_PENDING_MAC_SIZE 32 // TODO
//
// Define the filter struct
//
@@ -245,10 +243,6 @@ typedef struct _MS_FILTER
uint16_t otShortAddress;
BOOLEAN otPendingMacOffloadEnabled;
uint8_t otPendingShortAddressCount;
uint16_t otPendingShortAddresses[MAX_PENDING_MAC_SIZE];
uint8_t otPendingExtendedAddressCount;
uint64_t otPendingExtendedAddresses[MAX_PENDING_MAC_SIZE];
#if DEBUG_ALLOC
// Used for tracking memory allocations
+80 -170
View File
@@ -73,8 +73,6 @@ otPlatReset(
pFilter->otCurrentListenChannel = 0xFF;
pFilter->otPromiscuous = false;
pFilter->otPendingMacOffloadEnabled = FALSE;
pFilter->otPendingShortAddressCount = 0;
pFilter->otPendingExtendedAddressCount = 0;
// Reinitialize the OpenThread library
pFilter->otCachedRole = kDeviceRoleDisabled;
@@ -169,8 +167,6 @@ otLwfRadioInit(
pFilter->otTransmitFrame.mPsdu = pFilter->otTransmitMessage;
pFilter->otPendingMacOffloadEnabled = FALSE;
pFilter->otPendingShortAddressCount = 0;
pFilter->otPendingExtendedAddressCount = 0;
// Cache the factory address
otLwfRadioGetFactoryAddress(pFilter);
@@ -569,64 +565,6 @@ otLwfRadioTransmitFrameDone(
LogFuncExit(DRIVER_DATA_PATH);
}
NDIS_STATUS
otPlatRadioSendPendingMacOffload(
_In_ PMS_FILTER pFilter
)
{
// TODO
UNREFERENCED_PARAMETER(pFilter);
return STATUS_NOT_SUPPORTED;
/*NDIS_STATUS status;
ULONG bytesProcessed;
UCHAR ShortAddressCount = pFilter->otPendingMacOffloadEnabled == TRUE ? pFilter->otPendingShortAddressCount : 0;
UCHAR ExtendedAddressCount = pFilter->otPendingMacOffloadEnabled == TRUE ? pFilter->otPendingExtendedAddressCount : 0;
USHORT OidBufferSize = COMPLETE_SIZEOF_OT_PENDING_MAC_OFFLOAD_REVISION_1(ShortAddressCount, ExtendedAddressCount);
POT_PENDING_MAC_OFFLOAD OidBuffer = (POT_PENDING_MAC_OFFLOAD)FILTER_ALLOC_MEM(pFilter->FilterHandle, OidBufferSize);
PUCHAR Offset = (PUCHAR)(OidBuffer + 1);
ULONG BufferSizeLeft = OidBufferSize - sizeof(OT_PENDING_MAC_OFFLOAD);
OidBuffer->Header.Type = NDIS_OBJECT_TYPE_DEFAULT;
OidBuffer->Header.Revision = OT_PENDING_MAC_OFFLOAD_REVISION_1;
OidBuffer->Header.Size = OidBufferSize;
OidBuffer->ShortAddressCount = ShortAddressCount;
OidBuffer->ExtendedAddressCount = ExtendedAddressCount;
if (ShortAddressCount != 0)
{
memcpy_s(Offset, BufferSizeLeft, pFilter->otPendingShortAddresses, sizeof(USHORT) * ShortAddressCount);
Offset += sizeof(USHORT) * ShortAddressCount;
BufferSizeLeft -= sizeof(USHORT) * ShortAddressCount;
}
if (ExtendedAddressCount != 0)
{
memcpy_s(Offset, BufferSizeLeft, pFilter->otPendingExtendedAddresses, sizeof(ULONGLONG) * ExtendedAddressCount);
}
LogInfo(DRIVER_DEFAULT, "Interface %!GUID! indicating updated Pending Mac Offload", &pFilter->InterfaceGuid);
// Indicate to the miniport
status =
otLwfSendInternalRequest(
pFilter,
NdisRequestSetInformation,
OID_OT_PENDING_MAC_OFFLOAD,
OidBuffer,
OidBufferSize,
&bytesProcessed
);
if (status != NDIS_STATUS_SUCCESS)
{
LogError(DRIVER_DEFAULT, "Set for OID_OT_PENDING_MAC_OFFLOAD failed, %!NDIS_STATUS!", status);
}
FILTER_FREE_MEM(OidBuffer);
return status;*/
}
void otPlatRadioEnableSrcMatch(_In_ otInstance *otCtx, bool aEnable)
{
NT_ASSERT(otCtx);
@@ -635,9 +573,21 @@ void otPlatRadioEnableSrcMatch(_In_ otInstance *otCtx, bool aEnable)
// Ignore if we are already in the correct state
if (aEnable == pFilter->otPendingMacOffloadEnabled) return;
// Set the new value and update the miniport
// Cache the new value
pFilter->otPendingMacOffloadEnabled = aEnable ? TRUE : FALSE;
otPlatRadioSendPendingMacOffload(pFilter);
// Indicate to the miniport
NTSTATUS status =
otLwfCmdSetProp(
pFilter,
SPINEL_PROP_MAC_SRC_MATCH_ENABLED,
SPINEL_DATATYPE_BOOL_S,
(aEnable ? TRUE : FALSE)
);
if (!NT_SUCCESS(status))
{
LogError(DRIVER_DEFAULT, "Set SPINEL_PROP_MAC_SRC_MATCH_ENABLED failed, %!STATUS!", status);
}
}
ThreadError otPlatRadioAddSrcMatchShortEntry(_In_ otInstance *otCtx, const uint16_t aShortAddress)
@@ -645,34 +595,20 @@ ThreadError otPlatRadioAddSrcMatchShortEntry(_In_ otInstance *otCtx, const uint1
NT_ASSERT(otCtx);
PMS_FILTER pFilter = otCtxToFilter(otCtx);
// Check to see if it is in the list
BOOLEAN Found = false;
for (ULONG i = 0; i < pFilter->otPendingShortAddressCount; i++)
// Indicate to the miniport
NTSTATUS status =
otLwfCmdInsertProp(
pFilter,
SPINEL_PROP_MAC_SRC_MATCH_SHORT_ADDRESSES,
SPINEL_DATATYPE_UINT16_S,
aShortAddress
);
if (!NT_SUCCESS(status))
{
if (aShortAddress == pFilter->otPendingShortAddresses[i])
{
Found = TRUE;
break;
}
LogError(DRIVER_DEFAULT, "Insert SPINEL_PROP_MAC_SRC_MATCH_SHORT_ADDRESSES failed, %!STATUS!", status);
}
// Already in the list, return success
if (Found) return kThreadError_None;
// Make sure we have room
if (pFilter->otPendingShortAddressCount == MAX_PENDING_MAC_SIZE) return kThreadError_NoBufs;
// Copy to the list
pFilter->otPendingShortAddresses[pFilter->otPendingShortAddressCount] = aShortAddress;
pFilter->otPendingShortAddressCount++;
// Update the miniport if enabled
if (pFilter->otPendingMacOffloadEnabled)
{
otPlatRadioSendPendingMacOffload(pFilter);
}
return kThreadError_None;
return NT_SUCCESS(status) ? kThreadError_None : kThreadError_Failed;
}
ThreadError otPlatRadioAddSrcMatchExtEntry(_In_ otInstance *otCtx, const uint8_t *aExtAddress)
@@ -680,34 +616,20 @@ ThreadError otPlatRadioAddSrcMatchExtEntry(_In_ otInstance *otCtx, const uint8_t
NT_ASSERT(otCtx);
PMS_FILTER pFilter = otCtxToFilter(otCtx);
// Check to see if it is in the list
BOOLEAN Found = false;
for (ULONG i = 0; i < pFilter->otPendingExtendedAddressCount; i++)
// Indicate to the miniport
NTSTATUS status =
otLwfCmdInsertProp(
pFilter,
SPINEL_PROP_MAC_SRC_MATCH_EXTENDED_ADDRESSES,
SPINEL_DATATYPE_EUI64_S,
aExtAddress
);
if (!NT_SUCCESS(status))
{
if (memcmp(aExtAddress, &pFilter->otPendingExtendedAddresses[i], sizeof(ULONGLONG)) == 0)
{
Found = TRUE;
break;
}
LogError(DRIVER_DEFAULT, "Insert SPINEL_PROP_MAC_SRC_MATCH_EXTENDED_ADDRESSES failed, %!STATUS!", status);
}
// Already in the list, return success
if (Found) return kThreadError_None;
// Make sure we have room
if (pFilter->otPendingExtendedAddressCount == MAX_PENDING_MAC_SIZE) return kThreadError_NoBufs;
// Copy to the list
memcpy(&pFilter->otPendingExtendedAddresses[pFilter->otPendingExtendedAddressCount], aExtAddress, sizeof(ULONGLONG));
pFilter->otPendingExtendedAddressCount++;
// Update the miniport if enabled
if (pFilter->otPendingMacOffloadEnabled)
{
otPlatRadioSendPendingMacOffload(pFilter);
}
return kThreadError_None;
return NT_SUCCESS(status) ? kThreadError_None : kThreadError_Failed;
}
ThreadError otPlatRadioClearSrcMatchShortEntry(_In_ otInstance *otCtx, const uint16_t aShortAddress)
@@ -715,31 +637,20 @@ ThreadError otPlatRadioClearSrcMatchShortEntry(_In_ otInstance *otCtx, const uin
NT_ASSERT(otCtx);
PMS_FILTER pFilter = otCtxToFilter(otCtx);
// Check to see if it is in the list
BOOLEAN Found = false;
for (ULONG i = 0; i < pFilter->otPendingShortAddressCount; i++)
// Indicate to the miniport
NTSTATUS status =
otLwfCmdRemoveProp(
pFilter,
SPINEL_PROP_MAC_SRC_MATCH_SHORT_ADDRESSES,
SPINEL_DATATYPE_UINT16_S,
aShortAddress
);
if (!NT_SUCCESS(status))
{
if (aShortAddress == pFilter->otPendingShortAddresses[i])
{
// Remove it from the list
if (i + 1 != pFilter->otPendingShortAddressCount)
pFilter->otPendingShortAddresses[i] = pFilter->otPendingShortAddresses[pFilter->otPendingShortAddressCount - 1];
pFilter->otPendingShortAddressCount--;
Found = TRUE;
break;
}
LogError(DRIVER_DEFAULT, "Remove SPINEL_PROP_MAC_SRC_MATCH_SHORT_ADDRESSES failed, %!STATUS!", status);
}
// Wasn't in the list, return failure
if (Found == FALSE) return kThreadError_NotFound;
// Update the miniport if enabled
if (pFilter->otPendingMacOffloadEnabled)
{
otPlatRadioSendPendingMacOffload(pFilter);
}
return kThreadError_None;
return NT_SUCCESS(status) ? kThreadError_None : kThreadError_Failed;
}
ThreadError otPlatRadioClearSrcMatchExtEntry(_In_ otInstance *otCtx, const uint8_t *aExtAddress)
@@ -747,31 +658,20 @@ ThreadError otPlatRadioClearSrcMatchExtEntry(_In_ otInstance *otCtx, const uint8
NT_ASSERT(otCtx);
PMS_FILTER pFilter = otCtxToFilter(otCtx);
// Check to see if it is in the list
BOOLEAN Found = false;
for (ULONG i = 0; i < pFilter->otPendingExtendedAddressCount; i++)
// Indicate to the miniport
NTSTATUS status =
otLwfCmdRemoveProp(
pFilter,
SPINEL_PROP_MAC_SRC_MATCH_EXTENDED_ADDRESSES,
SPINEL_DATATYPE_EUI64_S,
aExtAddress
);
if (!NT_SUCCESS(status))
{
if (memcmp(aExtAddress, &pFilter->otPendingExtendedAddresses[i], sizeof(ULONGLONG)) == 0)
{
// Remove it from the list
if (i + 1 != pFilter->otPendingExtendedAddressCount)
pFilter->otPendingExtendedAddresses[i] = pFilter->otPendingExtendedAddresses[pFilter->otPendingExtendedAddressCount - 1];
pFilter->otPendingExtendedAddressCount--;
Found = TRUE;
break;
}
}
// Wasn't in the list, return failure
if (Found == FALSE) return kThreadError_NotFound;
// Update the miniport if enabled
if (pFilter->otPendingMacOffloadEnabled)
{
otPlatRadioSendPendingMacOffload(pFilter);
LogError(DRIVER_DEFAULT, "Remove SPINEL_PROP_MAC_SRC_MATCH_EXTENDED_ADDRESSES failed, %!STATUS!", status);
}
return kThreadError_None;
return NT_SUCCESS(status) ? kThreadError_None : kThreadError_Failed;
}
void otPlatRadioClearSrcMatchShortEntries(_In_ otInstance *otCtx)
@@ -779,12 +679,17 @@ void otPlatRadioClearSrcMatchShortEntries(_In_ otInstance *otCtx)
NT_ASSERT(otCtx);
PMS_FILTER pFilter = otCtxToFilter(otCtx);
// Ignore if we are already in the correct state
if (pFilter->otPendingShortAddressCount == 0) return;
// Set the new value and update the miniport
pFilter->otPendingShortAddressCount = 0;
otPlatRadioSendPendingMacOffload(pFilter);
// Indicate to the miniport
NTSTATUS status =
otLwfCmdSetProp(
pFilter,
SPINEL_PROP_MAC_SRC_MATCH_SHORT_ADDRESSES,
NULL
);
if (!NT_SUCCESS(status))
{
LogError(DRIVER_DEFAULT, "Set SPINEL_PROP_MAC_SRC_MATCH_SHORT_ADDRESSES failed, %!STATUS!", status);
}
}
void otPlatRadioClearSrcMatchExtEntries(_In_ otInstance *otCtx)
@@ -792,12 +697,17 @@ void otPlatRadioClearSrcMatchExtEntries(_In_ otInstance *otCtx)
NT_ASSERT(otCtx);
PMS_FILTER pFilter = otCtxToFilter(otCtx);
// Ignore if we are already in the correct state
if (pFilter->otPendingExtendedAddressCount == 0) return;
// Set the new value and update the miniport
pFilter->otPendingExtendedAddressCount = 0;
otPlatRadioSendPendingMacOffload(pFilter);
// Indicate to the miniport
NTSTATUS status =
otLwfCmdSetProp(
pFilter,
SPINEL_PROP_MAC_SRC_MATCH_EXTENDED_ADDRESSES,
NULL
);
if (!NT_SUCCESS(status))
{
LogError(DRIVER_DEFAULT, "Set SPINEL_PROP_MAC_SRC_MATCH_EXTENDED_ADDRESSES failed, %!STATUS!", status);
}
}
ThreadError otPlatRadioEnergyScan(_In_ otInstance *otCtx, uint8_t aScanChannel, uint16_t aScanDuration)
+18
View File
@@ -1492,6 +1492,24 @@ exit:
return error;
}
/**
* Function documented in platform/radio.h
*/
void otPlatRadioClearSrcMatchShortEntries(otInstance *aInstance)
{
(void)aInstance;
// TODO - This function needs to be implemented
}
/**
* Function documented in platform/radio.h
*/
void otPlatRadioClearSrcMatchExtEntries(otInstance *aInstance)
{
(void)aInstance;
// TODO - This function needs to be implemented
}
/**
* Function documented in platform/radio.h
*/
+346 -11
View File
@@ -145,8 +145,8 @@ const NcpBase::GetPropertyHandlerEntry NcpBase::mGetPropertyHandlerTable[] =
{ SPINEL_PROP_THREAD_STABLE_NETWORK_DATA_VERSION, &NcpBase::GetPropertyHandler_THREAD_STABLE_NETWORK_DATA_VERSION },
{ SPINEL_PROP_THREAD_LEADER_NETWORK_DATA, &NcpBase::GetPropertyHandler_THREAD_LEADER_NETWORK_DATA },
{ SPINEL_PROP_THREAD_STABLE_LEADER_NETWORK_DATA, &NcpBase::GetPropertyHandler_THREAD_STABLE_LEADER_NETWORK_DATA },
{ SPINEL_PROP_THREAD_LOCAL_ROUTES, &NcpBase::NcpBase::GetPropertyHandler_THREAD_LOCAL_ROUTES },
{ SPINEL_PROP_THREAD_ASSISTING_PORTS, &NcpBase::NcpBase::GetPropertyHandler_THREAD_ASSISTING_PORTS },
{ SPINEL_PROP_THREAD_LOCAL_ROUTES, &NcpBase::GetPropertyHandler_THREAD_LOCAL_ROUTES },
{ SPINEL_PROP_THREAD_ASSISTING_PORTS, &NcpBase::GetPropertyHandler_THREAD_ASSISTING_PORTS },
{ SPINEL_PROP_THREAD_ALLOW_LOCAL_NET_DATA_CHANGE, &NcpBase::GetPropertyHandler_THREAD_ALLOW_LOCAL_NET_DATA_CHANGE },
{ SPINEL_PROP_THREAD_ROUTER_ROLE_ENABLED, &NcpBase::GetPropertyHandler_THREAD_ROUTER_ROLE_ENABLED },
@@ -160,7 +160,7 @@ const NcpBase::GetPropertyHandlerEntry NcpBase::mGetPropertyHandlerTable[] =
{ SPINEL_PROP_THREAD_ROUTER_DOWNGRADE_THRESHOLD, &NcpBase::GetPropertyHandler_THREAD_ROUTER_DOWNGRADE_THRESHOLD },
{ SPINEL_PROP_THREAD_CONTEXT_REUSE_DELAY, &NcpBase::GetPropertyHandler_THREAD_CONTEXT_REUSE_DELAY },
{ SPINEL_PROP_THREAD_NETWORK_ID_TIMEOUT, &NcpBase::GetPropertyHandler_THREAD_NETWORK_ID_TIMEOUT },
{ SPINEL_PROP_THREAD_ON_MESH_NETS, &NcpBase::NcpBase::GetPropertyHandler_THREAD_ON_MESH_NETS },
{ SPINEL_PROP_THREAD_ON_MESH_NETS, &NcpBase::GetPropertyHandler_THREAD_ON_MESH_NETS },
{ SPINEL_PROP_NET_REQUIRE_JOIN_EXISTING, &NcpBase::GetPropertyHandler_NET_REQUIRE_JOIN_EXISTING },
{ SPINEL_PROP_THREAD_ROUTER_SELECTION_JITTER, &NcpBase::GetPropertyHandler_THREAD_ROUTER_SELECTION_JITTER },
@@ -275,6 +275,11 @@ const NcpBase::SetPropertyHandlerEntry NcpBase::mSetPropertyHandlerTable[] =
{ SPINEL_PROP_MAC_WHITELIST, &NcpBase::SetPropertyHandler_MAC_WHITELIST },
{ SPINEL_PROP_MAC_WHITELIST_ENABLED, &NcpBase::SetPropertyHandler_MAC_WHITELIST_ENABLED },
#if OPENTHREAD_ENABLE_RAW_LINK_API
{ SPINEL_PROP_MAC_SRC_MATCH_ENABLED, &NcpBase::SetPropertyHandler_MAC_SRC_MATCH_ENABLED },
{ SPINEL_PROP_MAC_SRC_MATCH_SHORT_ADDRESSES, &NcpBase::SetPropertyHandler_MAC_SRC_MATCH_SHORT_ADDRESSES },
{ SPINEL_PROP_MAC_SRC_MATCH_EXTENDED_ADDRESSES, &NcpBase::SetPropertyHandler_MAC_SRC_MATCH_EXTENDED_ADDRESSES },
#endif
{ SPINEL_PROP_THREAD_MODE, &NcpBase::SetPropertyHandler_THREAD_MODE },
{ SPINEL_PROP_THREAD_CHILD_COUNT_MAX, &NcpBase::SetPropertyHandler_THREAD_CHILD_COUNT_MAX },
{ SPINEL_PROP_THREAD_CHILD_TIMEOUT, &NcpBase::SetPropertyHandler_THREAD_CHILD_TIMEOUT },
@@ -303,10 +308,14 @@ const NcpBase::SetPropertyHandlerEntry NcpBase::mSetPropertyHandlerTable[] =
const NcpBase::InsertPropertyHandlerEntry NcpBase::mInsertPropertyHandlerTable[] =
{
{ SPINEL_PROP_IPV6_ADDRESS_TABLE, &NcpBase::NcpBase::InsertPropertyHandler_IPV6_ADDRESS_TABLE },
{ SPINEL_PROP_THREAD_LOCAL_ROUTES, &NcpBase::NcpBase::InsertPropertyHandler_THREAD_LOCAL_ROUTES },
{ SPINEL_PROP_THREAD_ON_MESH_NETS, &NcpBase::NcpBase::InsertPropertyHandler_THREAD_ON_MESH_NETS },
{ SPINEL_PROP_THREAD_ASSISTING_PORTS, &NcpBase::NcpBase::InsertPropertyHandler_THREAD_ASSISTING_PORTS },
#if OPENTHREAD_ENABLE_RAW_LINK_API
{ SPINEL_PROP_MAC_SRC_MATCH_SHORT_ADDRESSES, &NcpBase::InsertPropertyHandler_MAC_SRC_MATCH_SHORT_ADDRESSES },
{ SPINEL_PROP_MAC_SRC_MATCH_EXTENDED_ADDRESSES, &NcpBase::InsertPropertyHandler_MAC_SRC_MATCH_EXTENDED_ADDRESSES },
#endif
{ SPINEL_PROP_IPV6_ADDRESS_TABLE, &NcpBase::InsertPropertyHandler_IPV6_ADDRESS_TABLE },
{ SPINEL_PROP_THREAD_LOCAL_ROUTES, &NcpBase::InsertPropertyHandler_THREAD_LOCAL_ROUTES },
{ SPINEL_PROP_THREAD_ON_MESH_NETS, &NcpBase::InsertPropertyHandler_THREAD_ON_MESH_NETS },
{ SPINEL_PROP_THREAD_ASSISTING_PORTS, &NcpBase::InsertPropertyHandler_THREAD_ASSISTING_PORTS },
{ SPINEL_PROP_CNTR_RESET, &NcpBase::SetPropertyHandler_CNTR_RESET },
@@ -315,10 +324,14 @@ const NcpBase::InsertPropertyHandlerEntry NcpBase::mInsertPropertyHandlerTable[]
const NcpBase::RemovePropertyHandlerEntry NcpBase::mRemovePropertyHandlerTable[] =
{
{ SPINEL_PROP_IPV6_ADDRESS_TABLE, &NcpBase::NcpBase::RemovePropertyHandler_IPV6_ADDRESS_TABLE },
{ SPINEL_PROP_THREAD_LOCAL_ROUTES, &NcpBase::NcpBase::RemovePropertyHandler_THREAD_LOCAL_ROUTES },
{ SPINEL_PROP_THREAD_ON_MESH_NETS, &NcpBase::NcpBase::RemovePropertyHandler_THREAD_ON_MESH_NETS },
{ SPINEL_PROP_THREAD_ASSISTING_PORTS, &NcpBase::NcpBase::RemovePropertyHandler_THREAD_ASSISTING_PORTS },
#if OPENTHREAD_ENABLE_RAW_LINK_API
{ SPINEL_PROP_MAC_SRC_MATCH_SHORT_ADDRESSES, &NcpBase::RemovePropertyHandler_MAC_SRC_MATCH_SHORT_ADDRESSES },
{ SPINEL_PROP_MAC_SRC_MATCH_EXTENDED_ADDRESSES, &NcpBase::RemovePropertyHandler_MAC_SRC_MATCH_EXTENDED_ADDRESSES },
#endif
{ SPINEL_PROP_IPV6_ADDRESS_TABLE, &NcpBase::RemovePropertyHandler_IPV6_ADDRESS_TABLE },
{ SPINEL_PROP_THREAD_LOCAL_ROUTES, &NcpBase::RemovePropertyHandler_THREAD_LOCAL_ROUTES },
{ SPINEL_PROP_THREAD_ON_MESH_NETS, &NcpBase::RemovePropertyHandler_THREAD_ON_MESH_NETS },
{ SPINEL_PROP_THREAD_ASSISTING_PORTS, &NcpBase::RemovePropertyHandler_THREAD_ASSISTING_PORTS },
{ SPINEL_PROP_MAC_WHITELIST, &NcpBase::RemovePropertyHandler_MAC_WHITELIST },
{ SPINEL_PROP_THREAD_ACTIVE_ROUTER_IDS, &NcpBase::RemovePropertyHandler_THREAD_ACTIVE_ROUTER_IDS },
};
@@ -4736,6 +4749,158 @@ ThreadError NcpBase::SetPropertyHandler_MAC_WHITELIST_ENABLED(uint8_t header, sp
return errorCode;
}
#if OPENTHREAD_ENABLE_RAW_LINK_API
ThreadError NcpBase::SetPropertyHandler_MAC_SRC_MATCH_ENABLED(uint8_t header, spinel_prop_key_t key,
const uint8_t *value_ptr, uint16_t value_len)
{
bool isEnabled;
spinel_ssize_t parsedLength;
ThreadError errorCode = kThreadError_None;
parsedLength = spinel_datatype_unpack(
value_ptr,
value_len,
SPINEL_DATATYPE_BOOL_S,
&isEnabled
);
if (parsedLength > 0)
{
errorCode = otLinkRawSrcMatchEnable(mInstance, isEnabled);
if (errorCode == kThreadError_None)
{
errorCode = HandleCommandPropertyGet(header, key);
}
else
{
errorCode = SendLastStatus(header, ThreadErrorToSpinelStatus(errorCode));
}
}
else
{
errorCode = SendLastStatus(header, SPINEL_STATUS_PARSE_ERROR);
}
return errorCode;
}
ThreadError NcpBase::SetPropertyHandler_MAC_SRC_MATCH_SHORT_ADDRESSES(uint8_t header, spinel_prop_key_t key,
const uint8_t *value_ptr, uint16_t value_len)
{
ThreadError errorCode = kThreadError_None;
spinel_status_t errorStatus = SPINEL_STATUS_OK;
const uint8_t *data = value_ptr;
uint16_t data_len = value_len;
// Clear the list first
errorCode = otLinkRawSrcMatchClearShortEntries(mInstance);
VerifyOrExit(errorCode == kThreadError_None,
errorStatus = ThreadErrorToSpinelStatus(errorCode));
// Loop through the addresses and add them
while (data_len >= sizeof(uint16_t))
{
spinel_ssize_t parsedLength;
uint16_t short_address;
parsedLength = spinel_datatype_unpack(
data,
data_len,
SPINEL_DATATYPE_UINT16_S,
&short_address
);
VerifyOrExit(parsedLength > 0, errorStatus = SPINEL_STATUS_PARSE_ERROR);
data += parsedLength;
data_len -= (uint16_t)parsedLength;
errorCode = otLinkRawSrcMatchAddShortEntry(mInstance, short_address);
VerifyOrExit(errorCode == kThreadError_None,
errorStatus = ThreadErrorToSpinelStatus(errorCode));
}
errorCode =
SendPropertyUpdate(
header,
SPINEL_CMD_PROP_VALUE_IS,
key,
value_ptr,
value_len
);
exit:
if (errorStatus != SPINEL_STATUS_OK)
{
errorCode = SendLastStatus(header, errorStatus);
}
return errorCode;
}
ThreadError NcpBase::SetPropertyHandler_MAC_SRC_MATCH_EXTENDED_ADDRESSES(uint8_t header, spinel_prop_key_t key,
const uint8_t *value_ptr, uint16_t value_len)
{
ThreadError errorCode = kThreadError_None;
spinel_status_t errorStatus = SPINEL_STATUS_OK;
const uint8_t *data = value_ptr;
uint16_t data_len = value_len;
// Clear the list first
errorCode = otLinkRawSrcMatchClearExtEntries(mInstance);
VerifyOrExit(errorCode == kThreadError_None,
errorStatus = ThreadErrorToSpinelStatus(errorCode));
// Loop through the addresses and add them
while (data_len >= sizeof(otExtAddress))
{
spinel_ssize_t parsedLength;
uint8_t *ext_address;
parsedLength = spinel_datatype_unpack(
data,
data_len,
SPINEL_DATATYPE_EUI64_S,
&ext_address
);
VerifyOrExit(parsedLength > 0, errorStatus = SPINEL_STATUS_PARSE_ERROR);
data += parsedLength;
data_len -= (uint16_t)parsedLength;
errorCode = otLinkRawSrcMatchAddExtEntry(mInstance, ext_address);
VerifyOrExit(errorCode == kThreadError_None,
errorStatus = ThreadErrorToSpinelStatus(errorCode));
}
errorCode =
SendPropertyUpdate(
header,
SPINEL_CMD_PROP_VALUE_IS,
key,
value_ptr,
value_len
);
exit:
if (errorStatus != SPINEL_STATUS_OK)
{
errorCode = SendLastStatus(header, errorStatus);
}
return errorCode;
}
#endif
ThreadError NcpBase::SetPropertyHandler_THREAD_MODE(uint8_t header, spinel_prop_key_t key, const uint8_t *value_ptr,
uint16_t value_len)
{
@@ -5268,6 +5433,91 @@ ThreadError NcpBase::SetPropertyHandler_NEST_LEGACY_ULA_PREFIX(uint8_t header, s
// MARK: Individual Property Inserters
// ----------------------------------------------------------------------------
#if OPENTHREAD_ENABLE_RAW_LINK_API
ThreadError NcpBase::InsertPropertyHandler_MAC_SRC_MATCH_SHORT_ADDRESSES(uint8_t header, spinel_prop_key_t key,
const uint8_t *value_ptr, uint16_t value_len)
{
spinel_ssize_t parsedLength;
ThreadError errorCode = kThreadError_None;
spinel_status_t errorStatus = SPINEL_STATUS_OK;
uint16_t short_address;
parsedLength = spinel_datatype_unpack(
value_ptr,
value_len,
SPINEL_DATATYPE_UINT16_S,
&short_address
);
VerifyOrExit(parsedLength > 0, errorStatus = SPINEL_STATUS_PARSE_ERROR);
errorCode = otLinkRawSrcMatchAddShortEntry(mInstance, short_address);
VerifyOrExit(errorCode == kThreadError_None,
errorStatus = ThreadErrorToSpinelStatus(errorCode));
errorCode =
SendPropertyUpdate(
header,
SPINEL_CMD_PROP_VALUE_INSERTED,
key,
value_ptr,
value_len
);
exit:
if (errorStatus != SPINEL_STATUS_OK)
{
errorCode = SendLastStatus(header, errorStatus);
}
return errorCode;
}
ThreadError NcpBase::InsertPropertyHandler_MAC_SRC_MATCH_EXTENDED_ADDRESSES(uint8_t header, spinel_prop_key_t key,
const uint8_t *value_ptr, uint16_t value_len)
{
spinel_ssize_t parsedLength;
ThreadError errorCode = kThreadError_None;
spinel_status_t errorStatus = SPINEL_STATUS_OK;
uint8_t *ext_address = NULL;
parsedLength = spinel_datatype_unpack(
value_ptr,
value_len,
SPINEL_DATATYPE_EUI64_S,
&ext_address
);
VerifyOrExit(parsedLength > 0, errorStatus = SPINEL_STATUS_PARSE_ERROR);
errorCode = otLinkRawSrcMatchAddExtEntry(mInstance, ext_address);
VerifyOrExit(errorCode == kThreadError_None,
errorStatus = ThreadErrorToSpinelStatus(errorCode));
errorCode =
SendPropertyUpdate(
header,
SPINEL_CMD_PROP_VALUE_INSERTED,
key,
value_ptr,
value_len
);
exit:
if (errorStatus != SPINEL_STATUS_OK)
{
errorCode = SendLastStatus(header, errorStatus);
}
return errorCode;
}
#endif
ThreadError NcpBase::InsertPropertyHandler_IPV6_ADDRESS_TABLE(uint8_t header, spinel_prop_key_t key,
const uint8_t *value_ptr, uint16_t value_len)
@@ -5568,6 +5818,91 @@ ThreadError NcpBase::InsertPropertyHandler_MAC_WHITELIST(uint8_t header, spinel_
// MARK: Individual Property Removers
// ----------------------------------------------------------------------------
#if OPENTHREAD_ENABLE_RAW_LINK_API
ThreadError NcpBase::RemovePropertyHandler_MAC_SRC_MATCH_SHORT_ADDRESSES(uint8_t header, spinel_prop_key_t key,
const uint8_t *value_ptr, uint16_t value_len)
{
spinel_ssize_t parsedLength;
ThreadError errorCode = kThreadError_None;
uint16_t short_address;
parsedLength = spinel_datatype_unpack(
value_ptr,
value_len,
SPINEL_DATATYPE_UINT16_S,
&short_address
);
if (parsedLength > 0)
{
errorCode = otLinkRawSrcMatchClearShortEntry(mInstance, short_address);
if (errorCode == kThreadError_None)
{
errorCode = SendPropertyUpdate(
header,
SPINEL_CMD_PROP_VALUE_REMOVED,
key,
value_ptr,
value_len
);
}
else
{
errorCode = SendLastStatus(header, ThreadErrorToSpinelStatus(errorCode));
}
}
else
{
errorCode = SendLastStatus(header, SPINEL_STATUS_PARSE_ERROR);
}
return errorCode;
}
ThreadError NcpBase::RemovePropertyHandler_MAC_SRC_MATCH_EXTENDED_ADDRESSES(uint8_t header, spinel_prop_key_t key,
const uint8_t *value_ptr, uint16_t value_len)
{
spinel_ssize_t parsedLength;
ThreadError errorCode = kThreadError_None;
uint8_t *ext_address;
parsedLength = spinel_datatype_unpack(
value_ptr,
value_len,
SPINEL_DATATYPE_EUI64_S,
&ext_address
);
if (parsedLength > 0)
{
errorCode = otLinkRawSrcMatchClearExtEntry(mInstance, ext_address);
if (errorCode == kThreadError_None)
{
errorCode = SendPropertyUpdate(
header,
SPINEL_CMD_PROP_VALUE_REMOVED,
key,
value_ptr,
value_len
);
}
else
{
errorCode = SendLastStatus(header, ThreadErrorToSpinelStatus(errorCode));
}
}
else
{
errorCode = SendLastStatus(header, SPINEL_STATUS_PARSE_ERROR);
}
return errorCode;
}
#endif
ThreadError NcpBase::RemovePropertyHandler_IPV6_ADDRESS_TABLE(uint8_t header, spinel_prop_key_t key,
const uint8_t *value_ptr, uint16_t value_len)
+20
View File
@@ -467,6 +467,14 @@ private:
uint16_t value_len);
ThreadError SetPropertyHandler_MAC_WHITELIST_ENABLED(uint8_t header, spinel_prop_key_t key,
const uint8_t *value_ptr, uint16_t value_len);
#if OPENTHREAD_ENABLE_RAW_LINK_API
ThreadError SetPropertyHandler_MAC_SRC_MATCH_ENABLED(uint8_t header, spinel_prop_key_t key,
const uint8_t *value_ptr, uint16_t value_len);
ThreadError SetPropertyHandler_MAC_SRC_MATCH_SHORT_ADDRESSES(uint8_t header, spinel_prop_key_t key,
const uint8_t *value_ptr, uint16_t value_len);
ThreadError SetPropertyHandler_MAC_SRC_MATCH_EXTENDED_ADDRESSES(uint8_t header, spinel_prop_key_t key,
const uint8_t *value_ptr, uint16_t value_len);
#endif
ThreadError SetPropertyHandler_THREAD_MODE(uint8_t header, spinel_prop_key_t key, const uint8_t *value_ptr,
uint16_t value_len);
ThreadError SetPropertyHandler_THREAD_CHILD_COUNT_MAX(uint8_t header, spinel_prop_key_t key,
@@ -518,6 +526,12 @@ private:
const uint8_t *value_ptr, uint16_t value_len);
#endif
#if OPENTHREAD_ENABLE_RAW_LINK_API
ThreadError InsertPropertyHandler_MAC_SRC_MATCH_SHORT_ADDRESSES(uint8_t header, spinel_prop_key_t key,
const uint8_t *value_ptr, uint16_t value_len);
ThreadError InsertPropertyHandler_MAC_SRC_MATCH_EXTENDED_ADDRESSES(uint8_t header, spinel_prop_key_t key,
const uint8_t *value_ptr, uint16_t value_len);
#endif
ThreadError InsertPropertyHandler_IPV6_ADDRESS_TABLE(uint8_t header, spinel_prop_key_t key,
const uint8_t *value_ptr, uint16_t value_len);
ThreadError InsertPropertyHandler_THREAD_LOCAL_ROUTES(uint8_t header, spinel_prop_key_t key,
@@ -529,6 +543,12 @@ private:
ThreadError InsertPropertyHandler_MAC_WHITELIST(uint8_t header, spinel_prop_key_t key, const uint8_t *value_ptr,
uint16_t value_len);
#if OPENTHREAD_ENABLE_RAW_LINK_API
ThreadError RemovePropertyHandler_MAC_SRC_MATCH_SHORT_ADDRESSES(uint8_t header, spinel_prop_key_t key,
const uint8_t *value_ptr, uint16_t value_len);
ThreadError RemovePropertyHandler_MAC_SRC_MATCH_EXTENDED_ADDRESSES(uint8_t header, spinel_prop_key_t key,
const uint8_t *value_ptr, uint16_t value_len);
#endif
ThreadError RemovePropertyHandler_IPV6_ADDRESS_TABLE(uint8_t header, spinel_prop_key_t key,
const uint8_t *value_ptr, uint16_t value_len);
ThreadError RemovePropertyHandler_THREAD_LOCAL_ROUTES(uint8_t header, spinel_prop_key_t key,
+17
View File
@@ -614,6 +614,23 @@ typedef enum
* Specified by Thread. Randomly-chosen, but non-volatile EUI-64.
*/
SPINEL_PROP_MAC_EXTENDED_ADDR = SPINEL_PROP_MAC_EXT__BEGIN + 2,
/// MAC Source Match Enabled Flag
/** Format: `b`
*/
SPINEL_PROP_MAC_SRC_MATCH_ENABLED = SPINEL_PROP_MAC_EXT__BEGIN + 3,
/// MAC Source Match Short Address List
/** Format: `A(S)`
*/
SPINEL_PROP_MAC_SRC_MATCH_SHORT_ADDRESSES
= SPINEL_PROP_MAC_EXT__BEGIN + 4,
/// MAC Source Match Extended Address List
/** Format: `A(E)`
*/
SPINEL_PROP_MAC_SRC_MATCH_EXTENDED_ADDRESSES
= SPINEL_PROP_MAC_EXT__BEGIN + 5,
SPINEL_PROP_MAC_EXT__END = 0x1400,
SPINEL_PROP_NET__BEGIN = 0x40,