mirror of
https://github.com/espressif/openthread.git
synced 2026-08-31 14:29:54 +00:00
[ncp] add vendor hook for property get/set handlers for vendor properties (#2725)
This commit is contained in:
committed by
Jonathan Hui
parent
67d68009b7
commit
8f7dfead41
@@ -41,7 +41,8 @@ otError NcpBase::VendorCommandHandler(uint8_t aHeader, unsigned int aCommand)
|
||||
{
|
||||
otError error = OT_ERROR_NONE;
|
||||
|
||||
switch (aCommand) {
|
||||
switch (aCommand)
|
||||
{
|
||||
|
||||
// TODO: Implement your command handlers here.
|
||||
|
||||
@@ -52,6 +53,69 @@ otError NcpBase::VendorCommandHandler(uint8_t aHeader, unsigned int aCommand)
|
||||
return error;
|
||||
}
|
||||
|
||||
void NcpBase::VendorHandleFrameRemovedFromNcpBuffer(NcpFrameBuffer::FrameTag aFrameTag)
|
||||
{
|
||||
// This method is a callback which mirrors `NcpBase::HandleFrameRemovedFromNcpBuffer()`.
|
||||
// It is called when a spinel frame is sent and removed from NCP buffer.
|
||||
//
|
||||
// (a) This can be used to track and verify that a vendor spinel frame response is
|
||||
// delivered to the host (tracking the frame using its tag).
|
||||
//
|
||||
// (b) It indicates that NCP buffer space is now available (since a spinel frame is
|
||||
// removed). This can be used to implement reliability mechanisms to re-send
|
||||
// a failed spinel command response (or an async spinel frame) transmission
|
||||
// (failed earlier due to NCP buffer being full).
|
||||
|
||||
OT_UNUSED_VARIABLE(aFrameTag);
|
||||
}
|
||||
|
||||
otError NcpBase::VendorGetPropertyHandler(spinel_prop_key_t aPropKey)
|
||||
{
|
||||
otError error = OT_ERROR_NONE;
|
||||
|
||||
switch (aPropKey)
|
||||
{
|
||||
|
||||
// TODO: Implement your property get handlers here.
|
||||
//
|
||||
// Get handler should retrieve the property value and then encode and write the
|
||||
// value into the NCP buffer. If the "get" operation itself fails, handler should
|
||||
// write a `LAST_STATUS` with the error status into the NCP buffer. `OT_ERROR_NO_BUFS`
|
||||
// should be returned if NCP buffer is full and response cannot be written.
|
||||
|
||||
default:
|
||||
error = OT_ERROR_NOT_FOUND;
|
||||
break;
|
||||
}
|
||||
|
||||
return error;
|
||||
}
|
||||
|
||||
otError NcpBase::VendorSetPropertyHandler(spinel_prop_key_t aPropKey)
|
||||
{
|
||||
otError error = OT_ERROR_NONE;
|
||||
|
||||
switch (aPropKey)
|
||||
{
|
||||
|
||||
// TODO: Implement your property set handlers here.
|
||||
//
|
||||
// Set handler should first decode the value from the input Spinel frame and then
|
||||
// perform the corresponding set operation. The handler should not prepare the
|
||||
// spinel response and therefore should not write anything to the NCP buffer.
|
||||
// The error returned from handler (other than `OT_ERROR_NOT_FOUND`) indicates the
|
||||
// error in either parsing of the input or the error of the set operation. In case
|
||||
// of a successful "set", `NcpBase` set command handler will invoke the
|
||||
// `VendorGetPropertyHandler()` for the same property key to prepare the response.
|
||||
|
||||
default:
|
||||
error = OT_ERROR_NOT_FOUND;
|
||||
break;
|
||||
}
|
||||
|
||||
return error;
|
||||
}
|
||||
|
||||
} // namespace Ncp
|
||||
} // namespace ot
|
||||
|
||||
|
||||
+44
-8
@@ -1383,7 +1383,13 @@ otError NcpBase::HandleCommandPropertySet(uint8_t aHeader, spinel_prop_key_t aKe
|
||||
otError error = OT_ERROR_NONE;
|
||||
PropertyHandler handler = FindSetPropertyHandler(aKey);
|
||||
|
||||
if (handler == NULL)
|
||||
if (handler != NULL)
|
||||
{
|
||||
mDisableStreamWrite = false;
|
||||
error = (this->*handler)();
|
||||
mDisableStreamWrite = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
// If there is no "set" handler, check if this property is one of the
|
||||
// ones that require different treatment.
|
||||
@@ -1392,15 +1398,26 @@ otError NcpBase::HandleCommandPropertySet(uint8_t aHeader, spinel_prop_key_t aKe
|
||||
|
||||
VerifyOrExit(!didHandle);
|
||||
|
||||
ExitNow(error = PrepareLastStatusResponse(aHeader, SPINEL_STATUS_PROP_NOT_FOUND));
|
||||
#if OPENTHREAD_ENABLE_NCP_VENDOR_HOOK
|
||||
if (aKey >= SPINEL_PROP_VENDOR__BEGIN && aKey < SPINEL_PROP_VENDOR__END)
|
||||
{
|
||||
mDisableStreamWrite = false;
|
||||
error = VendorSetPropertyHandler(aKey);
|
||||
mDisableStreamWrite = true;
|
||||
|
||||
// An `OT_ERROR_NOT_FOUND` status from vendor handler indicates
|
||||
// that it does not support the given property key. In that
|
||||
// case, `didHandle` is set to `false` so a `LAST_STATUS` with
|
||||
// `PROP_NOT_FOUND` is emitted. Otherwise, we fall through to
|
||||
// prepare the response.
|
||||
|
||||
didHandle = (error != OT_ERROR_NOT_FOUND);
|
||||
}
|
||||
#endif
|
||||
|
||||
VerifyOrExit(didHandle, error = PrepareLastStatusResponse(aHeader, SPINEL_STATUS_PROP_NOT_FOUND));
|
||||
}
|
||||
|
||||
mDisableStreamWrite = false;
|
||||
|
||||
error = (this->*handler)();
|
||||
|
||||
mDisableStreamWrite = true;
|
||||
|
||||
if (error == OT_ERROR_NONE)
|
||||
{
|
||||
error = PrepareSetResponse(aHeader, aKey);
|
||||
@@ -1505,6 +1522,25 @@ otError NcpBase::WritePropertyValueIsFrame(uint8_t aHeader, spinel_prop_key_t aP
|
||||
ExitNow(error = mEncoder.EndFrame());
|
||||
}
|
||||
|
||||
#if OPENTHREAD_ENABLE_NCP_VENDOR_HOOK
|
||||
if (aPropKey >= SPINEL_PROP_VENDOR__BEGIN && aPropKey < SPINEL_PROP_VENDOR__END)
|
||||
{
|
||||
SuccessOrExit(error = mEncoder.BeginFrame(aHeader, SPINEL_CMD_PROP_VALUE_IS, aPropKey));
|
||||
|
||||
error = VendorGetPropertyHandler(aPropKey);
|
||||
|
||||
// An `OT_ERROR_NOT_FOUND` status from vendor handler indicates that
|
||||
// it did not support the given property key. In that case, we fall
|
||||
// through to prepare a `LAST_STATUS` response.
|
||||
|
||||
if (error != OT_ERROR_NOT_FOUND)
|
||||
{
|
||||
SuccessOrExit(error);
|
||||
ExitNow(error = mEncoder.EndFrame());
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
if (aIsGetResponse)
|
||||
{
|
||||
SuccessOrExit(error = WriteLastStatusFrame(aHeader, SPINEL_STATUS_PROP_NOT_FOUND));
|
||||
|
||||
+66
-5
@@ -303,11 +303,6 @@ protected:
|
||||
void HandleTmfProxyStream(otMessage *aMessage, uint16_t aLocator, uint16_t aPort);
|
||||
#endif // OPENTHREAD_FTD && OPENTHREAD_ENABLE_TMF_PROXY
|
||||
|
||||
#if OPENTHREAD_ENABLE_NCP_VENDOR_HOOK
|
||||
otError VendorCommandHandler(uint8_t aHeader, unsigned int aCommand);
|
||||
void VendorHandleFrameRemovedFromNcpBuffer(NcpFrameBuffer::FrameTag aFrameTag);
|
||||
#endif // OPENTHREAD_ENABLE_NCP_VENDOR_HOOK
|
||||
|
||||
otError CommandHandler_NOOP(uint8_t aHeader);
|
||||
otError CommandHandler_RESET(uint8_t aHeader);
|
||||
// Combined command handler for `VALUE_GET`, `VALUE_SET`, `VALUE_INSERT` and `VALUE_REMOVE`.
|
||||
@@ -723,6 +718,72 @@ protected:
|
||||
static uint8_t ConvertLogLevel(otLogLevel aLogLevel);
|
||||
static unsigned int ConvertLogRegion(otLogRegion aLogRegion);
|
||||
|
||||
#if OPENTHREAD_ENABLE_NCP_VENDOR_HOOK
|
||||
/**
|
||||
* This method defines a vendor "command handler" hook to process vendor-specific spinel commands.
|
||||
*
|
||||
* @param[in] aHeader The spinel frame header.
|
||||
* @param[in] aCommand The spinel command key.
|
||||
*
|
||||
* @retval OT_ERROR_NONE The response is prepared.
|
||||
* @retval OT_ERROR_NO_BUFS Out of buffer while preparing the response.
|
||||
*
|
||||
*/
|
||||
otError VendorCommandHandler(uint8_t aHeader, unsigned int aCommand);
|
||||
|
||||
/**
|
||||
* This method is a callback which mirrors `NcpBase::HandleFrameRemovedFromNcpBuffer()`. It is called when a
|
||||
* spinel frame is sent and removed from NCP buffer.
|
||||
*
|
||||
* (a) This can be used to track and verify that a vendor spinel frame response is delivered to the host (tracking
|
||||
* the frame using its tag).
|
||||
*
|
||||
* (b) It indicates that NCP buffer space is now available (since a spinel frame is removed). This can be used to
|
||||
* implement mechanisms to re-send a failed/pending response or an async spinel frame.
|
||||
*
|
||||
* @param[in] aFrameTag The tag of the frame removed from NCP buffer.
|
||||
*
|
||||
*/
|
||||
void VendorHandleFrameRemovedFromNcpBuffer(NcpFrameBuffer::FrameTag aFrameTag);
|
||||
|
||||
/**
|
||||
* This method defines a vendor "get property handler" hook to process vendor spinel properties.
|
||||
*
|
||||
* The vendor handler should return `OT_ERROR_NOT_FOUND` status if it does not support "get" operation for the
|
||||
* given property key. Otherwise, the vendor handler should behave like other property get handlers, i.e., it
|
||||
* should retrieve the property value and then encode and write the value into the NCP buffer. If the "get"
|
||||
* operation itself fails, handler should write a `LAST_STATUS` with the error status into the NCP buffer.
|
||||
*
|
||||
* @param[in] aPropKey The spinel property key.
|
||||
*
|
||||
* @retval OT_ERROR_NONE Successfully retrieved the property value and prepared the response.
|
||||
* @retval OT_ERROR_NOT_FOUND Does not support the given property key.
|
||||
* @retval OT_ERROR_NO_BUFS Out of buffer while preparing the response.
|
||||
*
|
||||
*/
|
||||
otError VendorGetPropertyHandler(spinel_prop_key_t aPropKey);
|
||||
|
||||
/**
|
||||
* This method defines a vendor "set property handler" hook to process vendor spinel properties.
|
||||
*
|
||||
* The vendor handler should return `OT_ERROR_NOT_FOUND` status if it does not support "set" operation for the
|
||||
* given property key. Otherwise, the vendor handler should behave like other property set handlers, i.e., it
|
||||
* should first decode the value from the input spinel frame and then perform the corresponding set operation. The
|
||||
* handler should not prepare the spinel response and therefore should not write anything to the NCP buffer. The
|
||||
* `otError` returned from handler (other than `OT_ERROR_NOT_FOUND`) indicates the error in either parsing of the
|
||||
* input or the error of the set operation. In case of a successful "set", `NcpBase` set command handler will call
|
||||
* the `VendorGetPropertyHandler()` for the same property key to prepare the response.
|
||||
*
|
||||
* @param[in] aPropKey The spinel property key.
|
||||
*
|
||||
* @returns OT_ERROR_NOT_FOUND if it does not support the given property key, otherwise the error in either parsing
|
||||
* of the input or the "set" operation.
|
||||
*
|
||||
*/
|
||||
otError VendorSetPropertyHandler(spinel_prop_key_t aPropKey);
|
||||
|
||||
#endif // OPENTHREAD_ENABLE_NCP_VENDOR_HOOK
|
||||
|
||||
protected:
|
||||
static NcpBase *sNcpInstance;
|
||||
static spinel_status_t ThreadErrorToSpinelStatus(otError aError);
|
||||
|
||||
Reference in New Issue
Block a user