// Copyright 2018 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#ifndef SRC_CONNECTIVITY_OPENTHREAD_DRIVERS_OT_RADIO_OT_RADIO_H_
#define SRC_CONNECTIVITY_OPENTHREAD_DRIVERS_OT_RADIO_OT_RADIO_H_

#ifndef _ALL_SOURCE
#define _ALL_SOURCE  // Enables thrd_create_with_name in <threads.h>.
#endif
#include <fuchsia/hardware/gpio/cpp/banjo.h>
#include <fuchsia/hardware/spi/cpp/banjo.h>
#include <fuchsia/lowpan/spinel/llcpp/fidl.h>
#include <lib/async-loop/cpp/loop.h>
#include <lib/ddk/device.h>
#include <lib/sync/completion.h>
#include <lib/zx/interrupt.h>
#include <threads.h>
#include <zircon/compiler.h>
#include <zircon/types.h>

#include <array>
#include <atomic>
#include <vector>

#include <ddktl/device.h>
#include <fbl/mutex.h>

#include "spinel_framer.h"

enum {
  OT_RADIO_INT_PIN,
  OT_RADIO_RESET_PIN,
  OT_RADIO_BOOTLOADER_PIN,
  OT_RADIO_PIN_COUNT,
};

typedef enum {
  OT_SPINEL_DEVICE_ON,
  OT_SPINEL_DEVICE_OFF,
} ot_radio_power_status_e;

namespace ot {
constexpr uint32_t kOutboundAllowanceInit = 4;
constexpr uint32_t kOutboundAllowanceInc = 2;
constexpr uint32_t kMaxFrameSize = 2048;
constexpr uint8_t kGetNcpVersionTID = 0xc;  // 4 bit TID for GetNCP version spinel cmd
                                            // chosen arbitrarily
constexpr int kGetNcpVersionMaxRetries = 5;

enum {
  PORT_KEY_RADIO_IRQ,
  PORT_KEY_TX_TO_APP,
  PORT_KEY_RX_FROM_APP,
  PORT_KEY_TX_TO_RADIO,
  PORT_KEY_EXIT_THREAD,
};

#ifdef INTERNAL_ACCESS
// Function defind in a generated source file
// generated by parsing firmware to return new firmware version
std::string GetNewFirmwareVersion();
#endif

class OtRadioDevice : public ddk::Device<OtRadioDevice, ddk::Unbindable, ddk::Messageable>,
                      public fidl::WireInterface<fuchsia_lowpan_spinel::DeviceSetup> {
 public:
  explicit OtRadioDevice(zx_device_t* device);

  static constexpr size_t spi_tx_rx_buffer_size = 2048;
  static zx_status_t Create(void* ctx, zx_device_t* parent, std::unique_ptr<OtRadioDevice>* out);
  static zx_status_t CreateBindAndStart(void* ctx, zx_device_t* parent);
  zx_status_t CreateAndBindPortToIntr();
  zx_status_t Bind();
  zx_status_t Start();
  void StartRadioThread();
  static bool RunUnitTests(void* ctx, zx_device_t* parent, zx_handle_t channel);
  zx_status_t Init();

  void DdkRelease();
  void DdkUnbind(ddk::UnbindTxn txn);
  zx_status_t DdkMessage(fidl_incoming_msg_t* msg, fidl_txn_t* txn);
  zx_status_t ShutDown();
  void RemoveDevice();
  void FreeDevice();
  zx_status_t AssertResetPin();
  zx_status_t Reset();
  zx_status_t GetNCPVersion();
  zx_status_t DriverUnitTestGetNCPVersion();
  zx_status_t DriverUnitTestGetResetEvent();

  zx::port port_;
  zx::interrupt interrupt_;
  ddk::SpiProtocolClient spi_;
  sync_completion_t spi_rx_complete_;

  uint8_t spi_rx_buffer_[kMaxFrameSize];

  std::array<ddk::GpioProtocolClient, OT_RADIO_PIN_COUNT> gpio_;

 private:
  zx_status_t RadioThread();
  zx_status_t StartLoopThread();
  void StopLoopThread();
  void StopRadioThread();
  zx_status_t ReadRadioPacket();
  zx_status_t HandleRadioRxFrame(uint8_t* frameBuffer, uint16_t length);
  zx_status_t RadioPacketTx(uint8_t* frameBuffer, uint16_t length);
  zx_status_t InvokeInterruptHandler();
  bool IsInterruptAsserted();
#ifdef INTERNAL_ACCESS
  zx_status_t CheckFWUpdateRequired(bool* update_fw);
#endif

  // Status indicators set in Start function which are later used by
  // ShutDown to determine what was running to shut down
  struct ThrdStatus {
    bool radio_thrd_running;
    bool loop_thrd_running;
  } thrd_status_ = {false, false};

  // FIDL request handlers
  void SetChannel(fidl::ServerEnd<fuchsia_lowpan_spinel::Device> request,
                  SetChannelCompleter::Sync& _completer) override;

  thrd_t thread_;
  async::Loop loop_;
  std::unique_ptr<ot::SpinelFramer> spinel_framer_;

  uint16_t spi_rx_buffer_len_ = 0;
  uint16_t spi_tx_buffer_len_ = 0;
  uint8_t spi_tx_buffer_[kMaxFrameSize];

  class LowpanSpinelDeviceFidlImpl : public fidl::WireInterface<fuchsia_lowpan_spinel::Device> {
   public:
    LowpanSpinelDeviceFidlImpl(OtRadioDevice& ot_radio);
    void Bind(async_dispatcher_t* dispatcher,
              fidl::ServerEnd<fuchsia_lowpan_spinel::Device> channel);

   private:
    // FIDL request handlers
    void Open(OpenCompleter::Sync& completer);
    void Close(CloseCompleter::Sync& completer);
    void GetMaxFrameSize(GetMaxFrameSizeCompleter::Sync& completer);
    void SendFrame(::fidl::VectorView<uint8_t> data, SendFrameCompleter::Sync& completer);
    void ReadyToReceiveFrames(uint32_t number_of_frames,
                              ReadyToReceiveFramesCompleter::Sync& completer);

    OtRadioDevice& ot_radio_obj_;
  };

  uint32_t inbound_allowance_ = 0;
  uint32_t outbound_allowance_ = kOutboundAllowanceInit;
  uint64_t inbound_cnt_ = 0;
  uint64_t outbound_cnt_ = 0;
  std::optional<fidl::ServerBindingRef<fuchsia_lowpan_spinel::Device>> fidl_binding_;
  std::unique_ptr<LowpanSpinelDeviceFidlImpl> fidl_impl_obj_ = 0;
  ot_radio_power_status_e power_status_ = OT_SPINEL_DEVICE_OFF;
  bool interrupt_is_asserted_ = false;
};

}  // namespace ot

#endif  // SRC_CONNECTIVITY_OPENTHREAD_DRIVERS_OT_RADIO_OT_RADIO_H_
