add Spinel SPI interface support
This commit enables the Thread Network HAL to support the Spinel SPI interface. Bug: 277286756 Test: Build and run otbr-agent on the emulator. Change-Id: I6726eead5686f0afb33e5e2035ebc9021eca5afa
This commit is contained in:
parent
59b018679b
commit
7ae6d6f4ff
4 changed files with 75 additions and 16 deletions
|
@ -29,6 +29,7 @@ cc_defaults {
|
|||
"openthread-hdlc",
|
||||
"openthread-platform",
|
||||
"openthread-posix",
|
||||
"openthread-spi",
|
||||
"openthread-url",
|
||||
],
|
||||
|
||||
|
@ -68,6 +69,7 @@ cc_fuzz {
|
|||
"openthread-hdlc",
|
||||
"openthread-platform",
|
||||
"openthread-posix",
|
||||
"openthread-spi",
|
||||
"openthread-url",
|
||||
],
|
||||
|
||||
|
|
|
@ -21,17 +21,36 @@
|
|||
#include <android/binder_process.h>
|
||||
#include <utils/Log.h>
|
||||
|
||||
#include "hdlc_interface.hpp"
|
||||
#include "spi_interface.hpp"
|
||||
|
||||
namespace aidl {
|
||||
namespace android {
|
||||
namespace hardware {
|
||||
namespace threadnetwork {
|
||||
|
||||
ThreadChip::ThreadChip(char* url)
|
||||
: mUrl(),
|
||||
mInterface(handleReceivedFrame, this, mRxFrameBuffer),
|
||||
mRxFrameBuffer(),
|
||||
mCallback(nullptr) {
|
||||
ThreadChip::ThreadChip(char* url) : mUrl(), mRxFrameBuffer(), mCallback(nullptr) {
|
||||
static const char kHdlcProtocol[] = "spinel+hdlc";
|
||||
static const char kSpiProtocol[] = "spinel+spi";
|
||||
const char* protocol;
|
||||
|
||||
CHECK_EQ(mUrl.Init(url), 0);
|
||||
|
||||
protocol = mUrl.GetProtocol();
|
||||
CHECK_NE(protocol, nullptr);
|
||||
|
||||
if (memcmp(protocol, kSpiProtocol, strlen(kSpiProtocol)) == 0) {
|
||||
mSpinelInterface = std::make_shared<ot::Posix::SpiInterface>(handleReceivedFrameJump, this,
|
||||
mRxFrameBuffer);
|
||||
} else if (memcmp(protocol, kHdlcProtocol, strlen(kHdlcProtocol)) == 0) {
|
||||
mSpinelInterface = std::make_shared<ot::Posix::HdlcInterface>(handleReceivedFrameJump, this,
|
||||
mRxFrameBuffer);
|
||||
} else {
|
||||
ALOGE("The protocol \"%s\" is not supported!", protocol);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
CHECK_NE(mSpinelInterface, nullptr);
|
||||
}
|
||||
|
||||
void ThreadChip::clientDeathCallback(void* context) {
|
||||
|
@ -43,7 +62,7 @@ void ThreadChip::clientDeathCallback(void) {
|
|||
close();
|
||||
}
|
||||
|
||||
void ThreadChip::handleReceivedFrame(void* context) {
|
||||
void ThreadChip::handleReceivedFrameJump(void* context) {
|
||||
static_cast<ThreadChip*>(context)->handleReceivedFrame();
|
||||
}
|
||||
|
||||
|
@ -70,7 +89,7 @@ ndk::ScopedAStatus ThreadChip::open(const std::shared_ptr<IThreadChipCallback>&
|
|||
mBinderDeathRecipient = AIBinder_DeathRecipient_new(clientDeathCallback);
|
||||
VerifyOrExit(AIBinder_linkToDeath(binder, mBinderDeathRecipient, this) == STATUS_OK,
|
||||
status = errorStatus(ERROR_FAILED, "Failed to link the binder to death"));
|
||||
VerifyOrExit(mInterface.Init(mUrl) == OT_ERROR_NONE,
|
||||
VerifyOrExit(mSpinelInterface->Init(mUrl) == OT_ERROR_NONE,
|
||||
status = errorStatus(ERROR_FAILED, "Failed to initialize the interface"));
|
||||
|
||||
mCallback = in_callback;
|
||||
|
@ -94,7 +113,7 @@ exit:
|
|||
ndk::ScopedAStatus ThreadChip::close() {
|
||||
VerifyOrExit(mCallback != nullptr);
|
||||
mCallback = nullptr;
|
||||
mInterface.Deinit();
|
||||
mSpinelInterface->Deinit();
|
||||
|
||||
ot::Posix::Mainloop::Manager::Get().Remove(*this);
|
||||
|
||||
|
@ -113,8 +132,8 @@ ndk::ScopedAStatus ThreadChip::sendSpinelFrame(const std::vector<uint8_t>& in_fr
|
|||
VerifyOrExit(mCallback != nullptr,
|
||||
status = errorStatus(ERROR_FAILED, "The interface is not open"));
|
||||
|
||||
error = mInterface.SendFrame(reinterpret_cast<const uint8_t*>(in_frame.data()),
|
||||
in_frame.size());
|
||||
error = mSpinelInterface->SendFrame(reinterpret_cast<const uint8_t*>(in_frame.data()),
|
||||
in_frame.size());
|
||||
if (error == OT_ERROR_NONE) {
|
||||
status = ndk::ScopedAStatus::ok();
|
||||
} else if (error == OT_ERROR_NO_BUFS) {
|
||||
|
@ -134,20 +153,20 @@ exit:
|
|||
}
|
||||
|
||||
ndk::ScopedAStatus ThreadChip::reset() {
|
||||
mInterface.HardwareReset();
|
||||
mSpinelInterface->HardwareReset();
|
||||
ALOGI("reset()");
|
||||
return ndk::ScopedAStatus::ok();
|
||||
}
|
||||
|
||||
void ThreadChip::Update(otSysMainloopContext& context) {
|
||||
if (mCallback != nullptr) {
|
||||
mInterface.UpdateFdSet(&context);
|
||||
mSpinelInterface->UpdateFdSet(&context);
|
||||
}
|
||||
}
|
||||
|
||||
void ThreadChip::Process(const otSysMainloopContext& context) {
|
||||
if (mCallback != nullptr) {
|
||||
mInterface.Process(&context);
|
||||
mSpinelInterface->Process(&context);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -19,7 +19,6 @@
|
|||
#include <aidl/android/hardware/threadnetwork/BnThreadChip.h>
|
||||
#include <aidl/android/hardware/threadnetwork/IThreadChipCallback.h>
|
||||
|
||||
#include "hdlc_interface.hpp"
|
||||
#include "lib/spinel/spinel_interface.hpp"
|
||||
#include "mainloop.hpp"
|
||||
|
||||
|
@ -45,12 +44,12 @@ class ThreadChip : public BnThreadChip, ot::Posix::Mainloop::Source {
|
|||
private:
|
||||
static void clientDeathCallback(void* context);
|
||||
void clientDeathCallback(void);
|
||||
static void handleReceivedFrame(void* context);
|
||||
static void handleReceivedFrameJump(void* context);
|
||||
void handleReceivedFrame(void);
|
||||
ndk::ScopedAStatus errorStatus(int32_t error, const char* message);
|
||||
|
||||
ot::Url::Url mUrl;
|
||||
ot::Posix::HdlcInterface mInterface;
|
||||
std::shared_ptr<ot::Spinel::SpinelInterface> mSpinelInterface;
|
||||
ot::Spinel::SpinelInterface::RxFrameBuffer mRxFrameBuffer;
|
||||
std::shared_ptr<IThreadChipCallback> mCallback;
|
||||
AIBinder_DeathRecipient* mBinderDeathRecipient;
|
||||
|
|
|
@ -36,6 +36,45 @@ void otLogWarnPlat(const char* format, ...) {
|
|||
va_end(args);
|
||||
}
|
||||
|
||||
void otLogNotePlat(const char* format, ...) {
|
||||
va_list args;
|
||||
|
||||
va_start(args, format);
|
||||
__android_log_vprint(ANDROID_LOG_INFO, LOG_TAG, format, args);
|
||||
va_end(args);
|
||||
}
|
||||
|
||||
void otLogInfoPlat(const char* format, ...) {
|
||||
va_list args;
|
||||
|
||||
va_start(args, format);
|
||||
__android_log_vprint(ANDROID_LOG_INFO, LOG_TAG, format, args);
|
||||
va_end(args);
|
||||
}
|
||||
|
||||
void otLogDebgPlat(const char* format, ...) {
|
||||
va_list args;
|
||||
|
||||
va_start(args, format);
|
||||
__android_log_vprint(ANDROID_LOG_DEBUG, LOG_TAG, format, args);
|
||||
va_end(args);
|
||||
}
|
||||
|
||||
void otDumpDebgPlat(const char* aText, const void* aData, uint16_t aDataLength) {
|
||||
constexpr uint16_t kBufSize = 512;
|
||||
char buf[kBufSize];
|
||||
|
||||
if ((aText != nullptr) && (aData != nullptr)) {
|
||||
const uint8_t* data = reinterpret_cast<const uint8_t*>(aData);
|
||||
|
||||
for (uint16_t i = 0; (i < aDataLength) && (i < (kBufSize - 1) / 3); i++) {
|
||||
snprintf(buf + (i * 3), (kBufSize - 1) - (i * 3), "%02x ", data[i]);
|
||||
}
|
||||
|
||||
__android_log_print(ANDROID_LOG_DEBUG, LOG_TAG, "%s: %s", aText, buf);
|
||||
}
|
||||
}
|
||||
|
||||
OT_TOOL_WEAK void otPlatAlarmMilliFired(otInstance* aInstance) {
|
||||
OT_UNUSED_VARIABLE(aInstance);
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue