Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Get device capabilities #104

Merged
merged 10 commits into from
Sep 7, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,9 @@ All notable changes to this project will be documented in this file.
This project uses the changelog in accordance with [keepchangelog](http://keepachangelog.com/). Please use this to write notable changes, which is not the same as git commit log...

## [unreleased][unreleased]
- Add `hf mf info` command to get UID/SAK/ATQA from slot (@Foxushka)
- Add `hw raw` to send raw command to Chameleon (@Foxushka)
- Implement command to fetch all available commands from Chameleon and test if Chameleon supports it (@Foxushka)
- ChameleonLite emulation bug fixed (@spp2000)
- Fixed MFC emulation issues with OEM readers, also temporarily disabling NFC_MF1_FAST_SIM (@xianglin1998)
- Fixed Chameleon crash during BLE pairing (@Foxushka)
Expand Down
75 changes: 73 additions & 2 deletions firmware/application/src/app_cmd.c
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
#include "nrf_pwr_mgmt.h"
#include "settings.h"
#include "delayed_reset.h"
#include "lwip_def.h"


#define NRF_LOG_MODULE_NAME app_cmd
Expand All @@ -35,6 +36,16 @@ data_frame_tx_t *cmd_processor_get_git_version(uint16_t cmd, uint16_t status, ui
}


data_frame_tx_t *cmd_processor_get_device(uint16_t cmd, uint16_t status, uint16_t length, uint8_t *data) {
#if defined(PROJECT_CHAMELEON_ULTRA)
uint8_t device = 1;
#else
uint8_t device = 0;
#endif
return data_frame_make(cmd, status, 1, &device);
}


data_frame_tx_t *cmd_processor_change_device_mode(uint16_t cmd, uint16_t status, uint16_t length, uint8_t *data) {
if (length == 1) {
if (data[0] == 1) {
Expand Down Expand Up @@ -106,6 +117,19 @@ data_frame_tx_t *cmd_processor_reset_settings(uint16_t cmd, uint16_t status, uin
return data_frame_make(cmd, status, 0, NULL);
}

data_frame_tx_t *cmd_processor_get_settings(uint16_t cmd, uint16_t status, uint16_t length, uint8_t *data) {
uint8_t settings[6 + BLE_CONNECT_KEY_LEN_MAX] = {};
settings[0] = SETTINGS_CURRENT_VERSION; // current version
settings[1] = settings_get_animation_config(); // animation mode
settings[2] = settings_get_button_press_config('A'); // short A button press mode
settings[3] = settings_get_button_press_config('B'); // short B button press mode
settings[4] = settings_get_long_button_press_config('A'); // long A button press mode
settings[5] = settings_get_long_button_press_config('B'); // long B button press mode
memcpy(settings + 6, settings_get_ble_connect_key(), BLE_CONNECT_KEY_LEN_MAX);
return data_frame_make(cmd, STATUS_DEVICE_SUCCESS, 6 + BLE_CONNECT_KEY_LEN_MAX, settings);
}


data_frame_tx_t *cmd_processor_set_animation_mode(uint16_t cmd, uint16_t status, uint16_t length, uint8_t *data) {
if (length == 1) {
status = STATUS_DEVICE_SUCCESS;
Expand Down Expand Up @@ -435,11 +459,30 @@ data_frame_tx_t *cmd_processor_set_em410x_emu_id(uint16_t cmd, uint16_t status,
}

data_frame_tx_t *cmd_processor_get_em410x_emu_id(uint16_t cmd, uint16_t status, uint16_t length, uint8_t *data) {
tag_specific_type_t tag_type[2];
tag_emulation_get_specific_type_by_slot(tag_emulation_get_slot(), tag_type);
if (tag_type[1] == TAG_TYPE_UNKNOWN) {
return data_frame_make(cmd, STATUS_PAR_ERR, 0, data); // no data in slot, don't send garbage
}
tag_data_buffer_t *buffer = get_buffer_by_tag_type(TAG_TYPE_EM410X);
uint8_t responseData[LF_EM410X_TAG_ID_SIZE];
memcpy(responseData, buffer->buffer, LF_EM410X_TAG_ID_SIZE);
status = STATUS_DEVICE_SUCCESS;
return data_frame_make(cmd, status, LF_EM410X_TAG_ID_SIZE, responseData);
return data_frame_make(cmd, STATUS_DEVICE_SUCCESS, LF_EM410X_TAG_ID_SIZE, responseData);
}

data_frame_tx_t *cmd_processor_get_mf1_anti_coll_data(uint16_t cmd, uint16_t status, uint16_t length, uint8_t *data) {
tag_specific_type_t tag_type[2];
tag_emulation_get_specific_type_by_slot(tag_emulation_get_slot(), tag_type);
if (tag_type[0] == TAG_TYPE_UNKNOWN) {
return data_frame_make(cmd, STATUS_PAR_ERR, 0, data); // no data in slot, don't send garbage
}
uint8_t responseData[16] = {};
nfc_tag_14a_coll_res_reference_t *info = get_saved_mifare_coll_res();
memcpy(responseData, info->uid, *info->size);
responseData[10] = *info->size; // size is 2 byte len, but...
responseData[12] = info->sak[0];
memcpy(&responseData[13], info->atqa, 2);
return data_frame_make(cmd, STATUS_DEVICE_SUCCESS, 16, responseData);
}

data_frame_tx_t *cmd_processor_set_mf1_detection_enable(uint16_t cmd, uint16_t status, uint16_t length, uint8_t *data) {
Expand Down Expand Up @@ -843,6 +886,9 @@ static cmd_data_map_t m_data_cmd_map[] = {
{ DATA_CMD_GET_BLE_CONNECT_KEY_CONFIG, NULL, cmd_processor_get_ble_connect_key, NULL },
{ DATA_CMD_SET_BLE_CONNECT_KEY_CONFIG, NULL, cmd_processor_set_ble_connect_key, NULL },
{ DATA_CMD_DELETE_ALL_BLE_BONDS, NULL, cmd_processor_del_ble_all_bonds, NULL },
{ DATA_CMD_GET_DEVICE, NULL, cmd_processor_get_device, NULL },
{ DATA_CMD_GET_SETTINGS, NULL, cmd_processor_get_settings, NULL },
{ DATA_CMD_GET_DEVICE_CAPABILITIES, NULL, NULL, NULL },

#if defined(PROJECT_CHAMELEON_ULTRA)

Expand Down Expand Up @@ -896,12 +942,37 @@ static cmd_data_map_t m_data_cmd_map[] = {
{ DATA_CMD_SET_MF1_USE_FIRST_BLOCK_COLL, NULL, cmd_processor_set_mf1_use_coll_res, NULL },
{ DATA_CMD_GET_MF1_WRITE_MODE, NULL, cmd_processor_get_mf1_write_mode, NULL },
{ DATA_CMD_SET_MF1_WRITE_MODE, NULL, cmd_processor_set_mf1_write_mode, NULL },
{ DATA_CMD_GET_MF1_ANTI_COLL_DATA, NULL, cmd_processor_get_mf1_anti_coll_data, NULL },

{ DATA_CMD_SET_SLOT_TAG_NICK, NULL, cmd_processor_set_slot_tag_nick_name, NULL },
{ DATA_CMD_GET_SLOT_TAG_NICK, NULL, cmd_processor_get_slot_tag_nick_name, NULL },
};


data_frame_tx_t *cmd_processor_get_capabilities(uint16_t cmd, uint16_t status, uint16_t length, uint8_t *data) {
size_t count = sizeof(m_data_cmd_map) / sizeof(m_data_cmd_map[0]);
uint16_t commands[count];
memset(commands, 0, count * sizeof(uint16_t));

for (size_t i = 0; i < count; i++) {
commands[i] = PP_HTONS(m_data_cmd_map[i].cmd);
}

return data_frame_make(cmd, status, count * sizeof(uint16_t), (uint8_t *)commands);
}


void cmd_map_init() {
size_t count = sizeof(m_data_cmd_map) / sizeof(m_data_cmd_map[0]);

for (size_t i = 0; i < count; i++) {
if (m_data_cmd_map[i].cmd == DATA_CMD_GET_DEVICE_CAPABILITIES) {
m_data_cmd_map[i].cmd_processor = cmd_processor_get_capabilities;
return;
}
}
}

/**
* @brief Auto select source to response
*
Expand Down
1 change: 1 addition & 0 deletions firmware/application/src/app_cmd.h
Original file line number Diff line number Diff line change
Expand Up @@ -15,5 +15,6 @@ typedef struct {
} cmd_data_map_t;

void on_data_frame_received(uint16_t cmd, uint16_t status, uint16_t length, uint8_t *data);
void cmd_map_init();

#endif
1 change: 1 addition & 0 deletions firmware/application/src/app_main.c
Original file line number Diff line number Diff line change
Expand Up @@ -767,6 +767,7 @@ static void ble_passkey_init(void) {
*/
int main(void) {
hw_connect_init(); // Remember to initialize the pins first
cmd_map_init(); // Set function in CMD map for DATA_CMD_GET_DEVICE_CAPABILITIES

init_leds(); // LED initialization
log_init(); // Log initialization
Expand Down
7 changes: 6 additions & 1 deletion firmware/application/src/data_cmd.h
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,10 @@
#define DATA_CMD_SET_BLE_CONNECT_KEY_CONFIG (1030)
#define DATA_CMD_GET_BLE_CONNECT_KEY_CONFIG (1031)
#define DATA_CMD_DELETE_ALL_BLE_BONDS (1032)
#define DATA_CMD_GET_DEVICE (1033)
#define DATA_CMD_GET_SETTINGS (1034)
#define DATA_CMD_GET_DEVICE_CAPABILITIES (1035)


//
// ******************************************************************
Expand Down Expand Up @@ -80,7 +84,7 @@
//
#define DATA_CMD_LOAD_MF1_EMU_BLOCK_DATA (4000)
#define DATA_CMD_SET_MF1_ANTI_COLLISION_RES (4001)
#define DATA_CMD_SET_MF1_ANTICOLLISION_INFO (4002)
#define DATA_CMD_SET_MF1_ANTI_COLLISION_INFO (4002)
#define DATA_CMD_SET_MF1_ATS_RESOURCE (4003)
#define DATA_CMD_SET_MF1_DETECTION_ENABLE (4004)
#define DATA_CMD_GET_MF1_DETECTION_COUNT (4005)
Expand All @@ -96,6 +100,7 @@
#define DATA_CMD_SET_MF1_USE_FIRST_BLOCK_COLL (4015)
#define DATA_CMD_GET_MF1_WRITE_MODE (4016)
#define DATA_CMD_SET_MF1_WRITE_MODE (4017)
#define DATA_CMD_GET_MF1_ANTI_COLL_DATA (4018)
//
// ******************************************************************

Expand Down
11 changes: 11 additions & 0 deletions firmware/application/src/rfid/nfctag/hf/nfc_mf1.c
Original file line number Diff line number Diff line change
Expand Up @@ -1070,6 +1070,17 @@ nfc_tag_14a_coll_res_reference_t *get_mifare_coll_res() {
return &m_shadow_coll_res;
}


nfc_tag_14a_coll_res_reference_t *get_saved_mifare_coll_res() {
// Always give saved data, not from block 0
m_shadow_coll_res.sak = m_tag_information->res_coll.sak;
m_shadow_coll_res.atqa = m_tag_information->res_coll.atqa;
m_shadow_coll_res.uid = m_tag_information->res_coll.uid;
m_shadow_coll_res.size = &(m_tag_information->res_coll.size);
m_shadow_coll_res.ats = &(m_tag_information->res_coll.ats);
return &m_shadow_coll_res;
}

/**
* @brief Reconcile when the parameter label needs to be reset
*/
Expand Down
1 change: 1 addition & 0 deletions firmware/application/src/rfid/nfctag/hf/nfc_mf1.h
Original file line number Diff line number Diff line change
Expand Up @@ -145,6 +145,7 @@ bool nfc_tag_mf1_is_detection_enable(void);
void nfc_tag_mf1_detection_log_clear(void);
uint32_t nfc_tag_mf1_detection_log_count(void);
nfc_tag_14a_coll_res_reference_t *get_mifare_coll_res(void);
nfc_tag_14a_coll_res_reference_t *get_saved_mifare_coll_res(void);
void nfc_tag_mf1_set_gen1a_magic_mode(bool enable);
bool nfc_tag_mf1_is_gen1a_magic_mode(void);
void nfc_tag_mf1_set_gen2_magic_mode(bool enable);
Expand Down
142 changes: 142 additions & 0 deletions firmware/common/lwip_def.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,142 @@
/**
* @file
* various utility macros
*/

/*
* Copyright (c) 2001-2004 Swedish Institute of Computer Science.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
* 3. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
* SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
* OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
* OF SUCH DAMAGE.
*
* This file is part of the lwIP TCP/IP stack.
*
* Author: Adam Dunkels <adam@sics.se>
*
*/

/**
* @defgroup perf Performance measurement
* @ingroup sys_layer
* All defines related to this section must not be placed in lwipopts.h,
* but in arch/perf.h!
* Measurement calls made throughout lwip, these can be defined to nothing.
* - PERF_START: start measuring something.
* - PERF_STOP(x): stop measuring something, and record the result.
*/

#ifndef LWIP_HDR_DEF_H
#define LWIP_HDR_DEF_H

/* arch.h might define NULL already */
#define PERF_START /* null definition */
#define PERF_STOP(x) /* null definition */

#ifdef __cplusplus
extern "C" {
#endif

#define LWIP_MAX(x , y) (((x) > (y)) ? (x) : (y))
#define LWIP_MIN(x , y) (((x) < (y)) ? (x) : (y))

/* Get the number of entries in an array ('x' must NOT be a pointer!) */
#define LWIP_ARRAYSIZE(x) (sizeof(x)/sizeof((x)[0]))

/** Create uint32_t value from bytes */
#define LWIP_MAKEU32(a,b,c,d) (((uint32_t)((a) & 0xff) << 24) | \
((uint32_t)((b) & 0xff) << 16) | \
((uint32_t)((c) & 0xff) << 8) | \
(uint32_t)((d) & 0xff))

#ifndef NULL
#ifdef __cplusplus
#define NULL 0
#else
#define NULL ((void *)0)
#endif
#endif

#if BYTE_ORDER == BIG_ENDIAN
#define lwip_htons(x) ((uint16_t)(x))
#define lwip_ntohs(x) ((uint16_t)(x))
#define lwip_htonl(x) ((uint32_t)(x))
#define lwip_ntohl(x) ((uint32_t)(x))
#define PP_HTONS(x) ((uint16_t)(x))
#define PP_NTOHS(x) ((uint16_t)(x))
#define PP_HTONL(x) ((uint32_t)(x))
#define PP_NTOHL(x) ((uint32_t)(x))
#else /* BYTE_ORDER != BIG_ENDIAN */
#ifndef lwip_htons
uint16_t lwip_htons(uint16_t x);
#endif
#define lwip_ntohs(x) lwip_htons(x)

#ifndef lwip_htonl
uint32_t lwip_htonl(uint32_t x);
#endif
#define lwip_ntohl(x) lwip_htonl(x)

/* These macros should be calculated by the preprocessor and are used
with compile-time constants only (so that there is no little-endian
overhead at runtime). */
#define PP_HTONS(x) ((uint16_t)((((x) & (uint16_t)0x00ffU) << 8) | (((x) & (uint16_t)0xff00U) >> 8)))
#define PP_NTOHS(x) PP_HTONS(x)
#define PP_HTONL(x) ((((x) & (uint32_t)0x000000ffUL) << 24) | \
(((x) & (uint32_t)0x0000ff00UL) << 8) | \
(((x) & (uint32_t)0x00ff0000UL) >> 8) | \
(((x) & (uint32_t)0xff000000UL) >> 24))
#define PP_NTOHL(x) PP_HTONL(x)
#endif /* BYTE_ORDER == BIG_ENDIAN */

/* Functions that are not available as standard implementations.
* In cc.h, you can #define these to implementations available on
* your platform to save some code bytes if you use these functions
* in your application, too.
*/

#ifndef lwip_itoa
/* This can be #defined to itoa() or snprintf(result, bufsize, "%d", number) depending on your platform */
void lwip_itoa(char* result, size_t bufsize, int number);
#endif
#ifndef lwip_strnicmp
/* This can be #defined to strnicmp() or strncasecmp() depending on your platform */
int lwip_strnicmp(const char* str1, const char* str2, size_t len);
#endif
#ifndef lwip_stricmp
/* This can be #defined to stricmp() or strcasecmp() depending on your platform */
int lwip_stricmp(const char* str1, const char* str2);
#endif
#ifndef lwip_strnstr
/* This can be #defined to strnstr() depending on your platform */
char* lwip_strnstr(const char* buffer, const char* token, size_t n);
#endif
#ifndef lwip_strnistr
/* This can be #defined to strnistr() depending on your platform */
char* lwip_strnistr(const char* buffer, const char* token, size_t n);
#endif

#ifdef __cplusplus
}
#endif

#endif /* LWIP_HDR_DEF_H */
2 changes: 1 addition & 1 deletion resource/tools/make_style.sh
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ find . \( -not -path "./.git/*" -and -not -path "./firmware/nrf52_sdk/*" -and -n
# Apply autopep8 on *py
find . \( -not -path "./.git/*" -and -not -path "./firmware/nrf52_sdk/*" -and -not -path "*/venv/*" -and -not -path "*/tmp/*" -and \
-name "*.py" \) \
-exec autopep8 -i {} \;
-exec autopep8 --in-place --max-line-length 120 {} \;


# Detecting tabs.
Expand Down
Loading
Loading