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
diff --git a/threadnetwork/aidl/default/Android.bp b/threadnetwork/aidl/default/Android.bp
index 736e808..8b938d2 100644
--- a/threadnetwork/aidl/default/Android.bp
+++ b/threadnetwork/aidl/default/Android.bp
@@ -29,6 +29,7 @@
"openthread-hdlc",
"openthread-platform",
"openthread-posix",
+ "openthread-spi",
"openthread-url",
],
@@ -68,6 +69,7 @@
"openthread-hdlc",
"openthread-platform",
"openthread-posix",
+ "openthread-spi",
"openthread-url",
],
diff --git a/threadnetwork/aidl/default/thread_chip.cpp b/threadnetwork/aidl/default/thread_chip.cpp
index e542c7c..94d1e93 100644
--- a/threadnetwork/aidl/default/thread_chip.cpp
+++ b/threadnetwork/aidl/default/thread_chip.cpp
@@ -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 @@
close();
}
-void ThreadChip::handleReceivedFrame(void* context) {
+void ThreadChip::handleReceivedFrameJump(void* context) {
static_cast<ThreadChip*>(context)->handleReceivedFrame();
}
@@ -70,7 +89,7 @@
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 @@
ndk::ScopedAStatus ThreadChip::close() {
VerifyOrExit(mCallback != nullptr);
mCallback = nullptr;
- mInterface.Deinit();
+ mSpinelInterface->Deinit();
ot::Posix::Mainloop::Manager::Get().Remove(*this);
@@ -113,8 +132,8 @@
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 @@
}
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);
}
}
diff --git a/threadnetwork/aidl/default/thread_chip.hpp b/threadnetwork/aidl/default/thread_chip.hpp
index d93dfef..294190a 100644
--- a/threadnetwork/aidl/default/thread_chip.hpp
+++ b/threadnetwork/aidl/default/thread_chip.hpp
@@ -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 @@
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;
diff --git a/threadnetwork/aidl/default/utils.cpp b/threadnetwork/aidl/default/utils.cpp
index b4da7d7..1cb42ec 100644
--- a/threadnetwork/aidl/default/utils.cpp
+++ b/threadnetwork/aidl/default/utils.cpp
@@ -36,6 +36,45 @@
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);
}