#include "fuzz.h" void hal_inject_event(uint8_t hal_evt, tHAL_NFC_STATUS status) { tNFC_HAL_EVT_MSG msg = {}; msg.hdr.len = 0; msg.hdr.event = BT_EVT_TO_NFC_MSGS; msg.hdr.offset = 0; msg.hdr.layer_specific = 0; msg.hal_evt = hal_evt; msg.status = status; FUZZLOG("Injecting event to NFC code: event=%d, status=%d", hal_evt, status); nfc_main_handle_hal_evt(&msg); } bool hal_inject_data(const uint8_t* p_data, uint16_t data_len) { FUZZLOG("Injecting data to NFC stack: %s", BytesToHex(p_data, data_len).c_str()); // For NCI responses, nfc_ncif_process_event checks the response OID matches // the command being sent last time. So mimic this by always copying the first // two bytes into last header. if (data_len >= sizeof(nfc_cb.last_hdr)) { memcpy(nfc_cb.last_hdr, p_data, sizeof(nfc_cb.last_hdr)); } NFC_HDR* p_msg; p_msg = (NFC_HDR*)GKI_getbuf(sizeof(NFC_HDR) + NFC_RECEIVE_MSGS_OFFSET + data_len); if (p_msg != nullptr) { /* Initialize NFC_HDR */ p_msg->len = data_len; p_msg->event = BT_EVT_TO_NFC_NCI; p_msg->offset = NFC_RECEIVE_MSGS_OFFSET; uint8_t* p = (uint8_t*)(p_msg + 1) + p_msg->offset; memcpy(p, p_data, p_msg->len); if (nfc_ncif_process_event(p_msg)) { GKI_freebuf(p_msg); } return true; } else { LOG(ERROR) << StringPrintf("No buffer"); return false; } } static void HalInitialize() { FUZZLOG("HAL_OP: type=initialize"); } static void HalTerminate() { FUZZLOG("HAL_OP: type=terminate"); } static void HalOpen(tHAL_NFC_CBACK* /*p_hal_inject_event*/, tHAL_NFC_DATA_CBACK* /*p_data_cback*/) { FUZZLOG("HAL_OP, type=open"); hal_inject_event(HAL_NFC_OPEN_CPLT_EVT, HAL_NFC_STATUS_OK); } static void HalClose() { FUZZLOG("HAL_OP, type=close"); hal_inject_event(HAL_NFC_CLOSE_CPLT_EVT, HAL_NFC_STATUS_OK); } const uint8_t reset_req[] = {0x20, 0x00, 0x01, 0x01}; const uint8_t reset_rsp[] = {0x40, 0x00, 0x01, 0x00}; const uint8_t reset_ntf[] = {0x60, 0x00, 0x09, 0x02, 0x01, 0x20, 0x04, 0x04, 0x51, 0x12, 0x01, 0x90}; const uint8_t init_req[] = {0x20, 0x01, 0x02, 0x00, 0x00}; const uint8_t init_rsp[] = { 0x40, 0x01, 0x1E, 0x00, 0x1A, 0x7E, 0x06, 0x01, 0x01, 0x5C, 0x03, 0xFF, 0xFF, 0x01, 0xFF, 0x00, 0x08, 0x00, 0x00, 0x01, 0x00, 0x02, 0x00, 0x03, 0x00, 0x80, 0x00, 0x82, 0x00, 0x83, 0x00, 0x84, 0x00}; static void HalWrite(uint16_t data_len, uint8_t* p_data) { FUZZLOG("HAL_OP: type=write, data=%s", BytesToHex(p_data, data_len).c_str()); if (data_len == sizeof(reset_req) && memcmp(reset_req, p_data, data_len) == 0) { hal_inject_data(reset_rsp, sizeof(reset_rsp)); hal_inject_data(reset_ntf, sizeof(reset_ntf)); } else if (data_len == sizeof(init_req) && memcmp(init_req, p_data, data_len) == 0) { hal_inject_data(init_rsp, sizeof(init_rsp)); } } static void HalCoreInitialized(uint16_t data_len, uint8_t* p_core_init_rsp_params) { FUZZLOG("HAL_OP: type=coreInitialized, data=%s", BytesToHex(p_core_init_rsp_params, data_len).c_str()); hal_inject_event(HAL_NFC_POST_INIT_CPLT_EVT, HAL_NFC_STATUS_OK); } static bool HalPrediscover() { FUZZLOG("HAL_OP: type=prediscover, return=false"); return false; } static void HalControlGranted() { FUZZLOG("HAL_OP: type=controlGranted"); } static void HalPowerCycle() { FUZZLOG("HAL_OP: type=powerCycle"); } // Magic value from the real NFC code. #define MAX_NFC_EE 2 static uint8_t HalGetMaxNfcee() { FUZZLOG("HAL_OP: type=getMaxNfcee, return=%d", MAX_NFC_EE); return MAX_NFC_EE; } static tHAL_NFC_ENTRY s_halFuncEntries = { .initialize = HalInitialize, .terminate = HalTerminate, .open = HalOpen, .close = HalClose, .core_initialized = HalCoreInitialized, .write = HalWrite, .prediscover = HalPrediscover, .control_granted = HalControlGranted, .power_cycle = HalPowerCycle, .get_max_ee = HalGetMaxNfcee, }; tHAL_NFC_ENTRY* get_hal_func_entries() { return &s_halFuncEntries; }