Adds RX prcessing in UART link manager

Bug: 160899751
Test: Verify RX interrupt triggers notifier, and that we can
subsequently pull RX data from UART

Change-Id: Iabf19dd0973d98090281209521c3646ec10c0c4c
diff --git a/chpp/platform/aoc/chpp_uart_link_manager.cc b/chpp/platform/aoc/chpp_uart_link_manager.cc
index 2eb847d..f7400ac 100644
--- a/chpp/platform/aoc/chpp_uart_link_manager.cc
+++ b/chpp/platform/aoc/chpp_uart_link_manager.cc
@@ -21,12 +21,29 @@
 
 namespace chpp {
 
-UartLinkManager::UartLinkManager(UART *uart, uint8_t wakeOutPinNumber)
-    : mUart(uart), mWakeOutGpio(wakeOutPinNumber) {
+namespace {
+
+void onUartRxInterrupt(void *context) {
+  UartLinkManager *manager = static_cast<UartLinkManager *>(context);
+  manager->getUart()->DisableRxInterrupt();
+  chppWorkThreadSignalFromLink(&manager->getTransportContext()->linkParams,
+                               CHPP_TRANSPORT_SIGNAL_LINK_RX_PROCESS);
+}
+
+}  // anonymous namespace
+
+UartLinkManager::UartLinkManager(struct ChppTransportState *context, UART *uart,
+                                 uint8_t wakeOutPinNumber)
+    : mTransportContext(context), mUart(uart), mWakeOutGpio(wakeOutPinNumber) {
   mWakeOutGpio.SetDirection(GPIO::DIRECTION::OUTPUT);
   mWakeOutGpio.Clear();
 }
 
+void UartLinkManager::init() {
+  mUart->RegisterRxCallback(onUartRxInterrupt, this);
+  mUart->EnableRxInterrupt();
+}
+
 bool UartLinkManager::prepareTxPacket(uint8_t *buf, size_t len) {
   bool success = !hasTxPacket();
   if (!success) {
@@ -65,6 +82,17 @@
   return success;
 }
 
+void UartLinkManager::processRxSamples() {
+  int ch;
+  while ((ch = mUart->GetChar()) != EOF && mRxBufIndex < kRxBufSize) {
+    mRxBuf[mRxBufIndex++] = static_cast<uint8_t>(ch);
+  }
+
+  chppRxDataCb(mTransportContext, mRxBuf, mRxBufIndex);
+  mRxBufIndex = 0;
+  mUart->EnableRxInterrupt();
+}
+
 bool UartLinkManager::hasTxPacket() const {
   return mCurrentBuffer != nullptr && mUart != nullptr;
 }
diff --git a/chpp/platform/aoc/include/chpp/platform/chpp_uart_link_manager.h b/chpp/platform/aoc/include/chpp/platform/chpp_uart_link_manager.h
index f6ade41..f74a7b7 100644
--- a/chpp/platform/aoc/include/chpp/platform/chpp_uart_link_manager.h
+++ b/chpp/platform/aoc/include/chpp/platform/chpp_uart_link_manager.h
@@ -18,6 +18,7 @@
 #define CHPP_PLATFORM_UART_LINK_MANAGER_H_
 
 #include "chpp/link.h"
+#include "chpp/transport.h"
 #include "chre/util/non_copyable.h"
 #include "gpio_aoc.h"
 #include "uart.h"
@@ -50,10 +51,18 @@
 class UartLinkManager : public chre::NonCopyable {
  public:
   /**
+   * @param context The context pointer of the CHPP transport.
    * @param uart The pointer to the UART instance.
    * @param wakeOutPinNumber The pin number of the wake_out GPIO.
    */
-  UartLinkManager(UART *uart, uint8_t wakeOutPinNumber);
+  UartLinkManager(struct ChppTransportState *context, UART *uart,
+                  uint8_t wakeOutPinNumber);
+
+  /**
+   * This method must be called before invoking the rest of the public methods
+   * in this class.
+   */
+  void init();
 
   /**
    * @param buf The non-null pointer to the buffer.
@@ -73,7 +82,23 @@
    */
   bool startTransaction();
 
+  /**
+   * Pulls RX data from the UART peripheral, and sends them to the CHPP
+   * transport layer.
+   */
+  void processRxSamples();
+
+  struct ChppTransportState *getTransportContext() const {
+    return mTransportContext;
+  }
+
+  UART *getUart() const {
+    return mUart;
+  }
+
  private:
+  struct ChppTransportState *mTransportContext = nullptr;
+
   UART *mUart = nullptr;
 
   GPIOAoC mWakeOutGpio;
@@ -82,6 +107,11 @@
   uint8_t *mCurrentBuffer = nullptr;
   size_t mCurrentBufferLen = 0;
 
+  //! UART FIFO length is 256 bytes.
+  static constexpr size_t kRxBufSize = 256;
+  uint8_t mRxBuf[kRxBufSize];
+  size_t mRxBufIndex = 0;
+
   /**
    * @return if a TX packet is pending transmission.
    */
diff --git a/chpp/platform/aoc/include/chpp/platform/platform_link.h b/chpp/platform/aoc/include/chpp/platform/platform_link.h
index 7a3c14e..cbd3489 100644
--- a/chpp/platform/aoc/include/chpp/platform/platform_link.h
+++ b/chpp/platform/aoc/include/chpp/platform/platform_link.h
@@ -21,6 +21,9 @@
 extern "C" {
 #endif
 
+//! A signal to use when there is RX data to process at the UART.
+#define CHPP_TRANSPORT_SIGNAL_LINK_RX_PROCESS UINT32_C(1 << 16)
+
 #define CHPP_PLATFORM_LINK_TX_MTU_BYTES 1280
 #define CHPP_PLATFORM_LINK_RX_MTU_BYTES 1280
 
diff --git a/chpp/platform/aoc/link.cc b/chpp/platform/aoc/link.cc
index e06d737..2b89493 100644
--- a/chpp/platform/aoc/link.cc
+++ b/chpp/platform/aoc/link.cc
@@ -18,10 +18,15 @@
 
 #include "chpp/macros.h"
 #include "chpp/platform/chpp_uart_link_manager.h"
+#include "chpp/transport.h"
 
 using chpp::UartLinkManager;
 
-void chppPlatformLinkInit(struct ChppPlatformLinkParameters *params) {}
+void chppPlatformLinkInit(struct ChppPlatformLinkParameters *params) {
+  UartLinkManager *manager =
+      static_cast<UartLinkManager *>(params->uartLinkManager);
+  manager->init();
+}
 
 void chppPlatformLinkDeinit(struct ChppPlatformLinkParameters *params) {
   // TODO: Implement this
@@ -45,7 +50,12 @@
 
 void chppPlatformLinkDoWork(struct ChppPlatformLinkParameters *params,
                             uint32_t signal) {
-  // TODO: Implement this
+  UartLinkManager *manager =
+      static_cast<UartLinkManager *>(params->uartLinkManager);
+
+  if (signal & CHPP_TRANSPORT_SIGNAL_LINK_RX_PROCESS) {
+    manager->processRxSamples();
+  }
 }
 
 void chppPlatformLinkReset(struct ChppPlatformLinkParameters *params) {