[spinel] add vendor hook for the spinel host side (#9560)

Allow out-of-tree compilation of vendor specific changes to the host
side of spinel.  By setting `OT_SPINEL_VENDOR_HOOK_SOURCE_DIR`,
`OT_SPINEL_VENDOR_HOOK_SOURCE` and `OT_SPINEL_VENDOR_HOOK_HEADER`, the
corresponding compile flags
`OPENTHREAD_SPINEL_CONFIG_ENABLE_VENDOR_HOOK` and
`OPENTHREAD_SPINEL_CONFIG_VENDOR_HOOK_HEADER` get set which force the
use of the `VendorRadioSpinel` class instead of the regular
`RadioSpinel` in `src/Posix/platform/radio`.
This commit is contained in:
Thomas
2023-12-04 09:28:05 -08:00
committed by GitHub
parent 2d030c4a8e
commit 3d01ffa65c
9 changed files with 196 additions and 3 deletions
+11
View File
@@ -62,6 +62,17 @@ set(COMMON_SOURCES
spinel_encoder.cpp
)
set(OT_SPINEL_VENDOR_HOOK_SOURCE "" CACHE STRING "set vendor hook source file for Spinel")
set(OT_SPINEL_VENDOR_HOOK_HEADER "" CACHE STRING "set vendor hook header file for Spinel")
if(OT_SPINEL_VENDOR_HOOK_SOURCE)
target_compile_definitions(openthread-spinel-rcp PUBLIC "OPENTHREAD_SPINEL_CONFIG_ENABLE_VENDOR_HOOK=1")
target_compile_definitions(openthread-spinel-ncp PUBLIC "OPENTHREAD_SPINEL_CONFIG_ENABLE_VENDOR_HOOK=1")
target_compile_definitions(openthread-spinel-rcp PUBLIC "OPENTHREAD_SPINEL_CONFIG_VENDOR_HOOK_HEADER=\"${OT_SPINEL_VENDOR_HOOK_HEADER}\"")
target_compile_definitions(openthread-spinel-ncp PUBLIC "OPENTHREAD_SPINEL_CONFIG_VENDOR_HOOK_HEADER=\"${OT_SPINEL_VENDOR_HOOK_HEADER}\"")
list(APPEND COMMON_SOURCES ${OT_SPINEL_VENDOR_HOOK_SOURCE_DIR}${OT_SPINEL_VENDOR_HOOK_SOURCE})
list(APPEND COMMON_INCLUDES ${OT_SPINEL_VENDOR_HOOK_SOURCE_DIR})
endif()
target_include_directories(openthread-radio-spinel PUBLIC ${OT_PUBLIC_INCLUDES} PRIVATE ${COMMON_INCLUDES})
target_include_directories(openthread-spinel-ncp PUBLIC ${OT_PUBLIC_INCLUDES} PRIVATE ${COMMON_INCLUDES})
target_include_directories(openthread-spinel-rcp PUBLIC ${OT_PUBLIC_INCLUDES} PRIVATE ${COMMON_INCLUDES})
+67
View File
@@ -0,0 +1,67 @@
/*
* Copyright (c) 2023, The OpenThread Authors.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the copyright holder nor the
* names of its contributors may be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/**
* @file
* This file shows how to implement the Radio Spinel vendor hook.
*/
#if OPENTHREAD_SPINEL_CONFIG_ENABLE_VENDOR_HOOK
#include OPENTRHEAD_SPINEL_CONFIG_VENDOR_HOOK_HEADER
#include "common/log.hpp"
#include "lib/platform/exit_code.h"
namespace ot {
namespace Spinel {
otError RadioSpinel::VendorHandleValueIs(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;
}
exit:
return error;
}
} // namespace Spinel
} // namespace ot
extern ot::Spinel::RadioSpinel &GetRadioSpinel(void);
#endif // OPENTHREAD_SPINEL_CONFIG_ENABLE_VENDOR_HOOK
+59
View File
@@ -0,0 +1,59 @@
/*
* Copyright (c) 2023, The OpenThread Authors.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the copyright holder nor the
* names of its contributors may be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/**
* @file
* This file shows how to implement the Radio Spinel vendor hook.
*/
#ifndef SPINEL_EXTENSION_H
#define SPINEL_EXTENSION_H
#if OPENTHREAD_SPINEL_CONFIG_ENABLE_VENDOR_HOOK
#include <openthread/thread_ftd.h>
#include "lib/spinel/radio_spinel.hpp"
namespace ot {
namespace Spinel {
class VendorRadioSpinel : public ot::Spinel::RadioSpinel
{
public:
VendorRadioSpinel(void)
: ot::Spinel::RadioSpinel()
{
}
// Add public/private methods or member variables
};
} // namespace Spinel
} // namespace ot
#endif // OPENTHREAD_SPINEL_CONFIG_ENABLE_VENDOR_HOOK
#endif // SPINEL_EXTENSION_H
+20
View File
@@ -89,4 +89,24 @@
#define OPENTHREAD_SPINEL_CONFIG_BROADCAST_IID SPINEL_HEADER_IID_3
#endif
/**
* @def OPENTHREAD_SPINEL_CONFIG_ENABLE_VENDOR_HOOK
*
* Enables compilation of vendor specific code for Spinel
*
*/
#ifndef OPENTHREAD_SPINEL_CONFIG_ENABLE_VENDOR_HOOK
#define OPENTHREAD_SPINEL_CONFIG_ENABLE_VENDOR_HOOK 0
#endif
/**
* @def OPENTHREAD_SPINEL_CONFIG_VENDOR_HOOK_HEADER
*
* Header file defining class VendorRadioSpinel
*
*/
#ifndef OPENTHREAD_SPINEL_CONFIG_VENDOR_HOOK_HEADER
#define OPENTHREAD_SPINEL_CONFIG_VENDOR_HOOK_HEADER "lib/spinel/example_vendor_hook.hpp"
#endif
#endif // OPENTHREAD_SPINEL_CONFIG_H_
+6
View File
@@ -747,6 +747,12 @@ void RadioSpinel::HandleValueIs(spinel_prop_key_t aKey, const uint8_t *aBuffer,
break;
}
}
#if OPENTHREAD_SPINEL_CONFIG_ENABLE_VENDOR_HOOK
else if (aKey >= SPINEL_PROP_VENDOR__BEGIN && aKey < SPINEL_PROP_VENDOR__END)
{
error = VendorHandleValueIs(aKey);
}
#endif
exit:
UpdateParseErrorCount(error);
+20
View File
@@ -1065,6 +1065,26 @@ public:
*/
void RestoreProperties(void);
#endif
#if OPENTHREAD_SPINEL_CONFIG_ENABLE_VENDOR_HOOK
/**
* 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 VendorHandleValueIs(spinel_prop_key_t aPropKey);
#endif
private:
enum
+1
View File
@@ -195,6 +195,7 @@ target_include_directories(openthread-posix PRIVATE
${PROJECT_SOURCE_DIR}/src
${PROJECT_SOURCE_DIR}/src/core
${PROJECT_SOURCE_DIR}/third_party/mbedtls/repo/include
${OT_SPINEL_VENDOR_HOOK_SOURCE_DIR}
PUBLIC
${PROJECT_SOURCE_DIR}/src/posix/platform/include
)
+1 -1
View File
@@ -296,7 +296,7 @@ void Radio::GetIidListFromRadioUrl(spinel_iid_t (&aIidList)[Spinel::kSpinelHeade
} // namespace Posix
} // namespace ot
static ot::Spinel::RadioSpinel &GetRadioSpinel(void) { return sRadio.GetRadioSpinel(); }
ot::Spinel::RadioSpinel &GetRadioSpinel(void) { return sRadio.GetRadioSpinel(); }
void platformRadioDeinit(void) { GetRadioSpinel().Deinit(); }
+11 -2
View File
@@ -35,6 +35,11 @@
#include "posix/platform/radio_url.hpp"
#include "posix/platform/spi_interface.hpp"
#include "posix/platform/vendor_interface.hpp"
#if OPENTHREAD_SPINEL_CONFIG_ENABLE_VENDOR_HOOK
#ifdef OPENTHREAD_SPINEL_CONFIG_VENDOR_HOOK_HEADER
#include OPENTHREAD_SPINEL_CONFIG_VENDOR_HOOK_HEADER
#endif
#endif
namespace ot {
namespace Posix {
@@ -104,8 +109,12 @@ private:
#error "No Spinel interface is specified!"
#endif
RadioUrl mRadioUrl;
Spinel::RadioSpinel mRadioSpinel;
RadioUrl mRadioUrl;
#if OPENTHREAD_ENABLE_SPINEL_VENDOR_HOOK
Spinel::VendorRadioSpinel mRadioSpinel;
#else
Spinel::RadioSpinel mRadioSpinel;
#endif
Spinel::SpinelInterface *mSpinelInterface;
OT_DEFINE_ALIGNED_VAR(mSpinelInterfaceRaw, kSpinelInterfaceRawSize, uint64_t);