mirror of
https://github.com/bettse/seader.git
synced 2026-09-01 20:08:26 +00:00
Integrate SNMP probe into SAM API
This commit is contained in:
@@ -15,19 +15,23 @@ test-host:
|
||||
lib/host_tests/vendor/munit/munit.c \
|
||||
lib/host_tests/test_main.c \
|
||||
lib/host_tests/test_lrc.c \
|
||||
lib/host_tests/test_sam_key_label.c \
|
||||
lib/host_tests/test_ccid_logic.c \
|
||||
lib/host_tests/test_t1_existing.c \
|
||||
lib/host_tests/test_t1_protocol.c \
|
||||
lib/host_tests/test_snmp.c \
|
||||
lib/host_tests/test_uhf_status_label.c \
|
||||
lib/host_tests/t1_test_stubs.c \
|
||||
lib/host_tests/bit_buffer_mock.c \
|
||||
lrc.c \
|
||||
ccid_logic.c \
|
||||
t_1_logic.c \
|
||||
t_1.c \
|
||||
sam_key_label.c \
|
||||
snmp_ber_view.c \
|
||||
snmp_codec.c \
|
||||
snmp_response_view.c \
|
||||
uhf_status_label.c \
|
||||
uhf_tag_config_view.c \
|
||||
uhf_snmp_probe.c \
|
||||
-o build/host_tests/seader_tests
|
||||
|
||||
@@ -2,17 +2,21 @@
|
||||
|
||||
extern MunitSuite test_lrc_suite;
|
||||
extern MunitSuite test_ccid_logic_suite;
|
||||
extern MunitSuite test_sam_key_label_suite;
|
||||
extern MunitSuite test_t1_existing_suite;
|
||||
extern MunitSuite test_t1_protocol_suite;
|
||||
extern MunitSuite test_snmp_suite;
|
||||
extern MunitSuite test_uhf_status_label_suite;
|
||||
|
||||
int main(int argc, char* argv[]) {
|
||||
MunitSuite child_suites[] = {
|
||||
{"/lrc", test_lrc_suite.tests, NULL, 1, MUNIT_SUITE_OPTION_NONE},
|
||||
{"/sam-key-label", test_sam_key_label_suite.tests, NULL, 1, MUNIT_SUITE_OPTION_NONE},
|
||||
{"/t1", test_t1_existing_suite.tests, NULL, 1, MUNIT_SUITE_OPTION_NONE},
|
||||
{"/t1", test_t1_protocol_suite.tests, NULL, 1, MUNIT_SUITE_OPTION_NONE},
|
||||
{"/ccid", test_ccid_logic_suite.tests, NULL, 1, MUNIT_SUITE_OPTION_NONE},
|
||||
{"/snmp", test_snmp_suite.tests, NULL, 1, MUNIT_SUITE_OPTION_NONE},
|
||||
{"/uhf-status-label", test_uhf_status_label_suite.tests, NULL, 1, MUNIT_SUITE_OPTION_NONE},
|
||||
{NULL, NULL, NULL, 0, 0},
|
||||
};
|
||||
MunitSuite main_suite = {
|
||||
|
||||
@@ -0,0 +1,80 @@
|
||||
#include "munit.h"
|
||||
#include "sam_key_label.h"
|
||||
|
||||
static MunitResult test_formats_no_sam(const MunitParameter params[], void* fixture) {
|
||||
(void)params;
|
||||
(void)fixture;
|
||||
char label[SEADER_SAM_KEY_LABEL_MAX_LEN] = {0};
|
||||
|
||||
seader_sam_key_label_format(false, NULL, 0U, label, sizeof(label));
|
||||
munit_assert_string_equal(label, "NO SAM");
|
||||
return MUNIT_OK;
|
||||
}
|
||||
|
||||
static MunitResult test_formats_standard_key_for_missing_value(
|
||||
const MunitParameter params[],
|
||||
void* fixture) {
|
||||
(void)params;
|
||||
(void)fixture;
|
||||
char label[SEADER_SAM_KEY_LABEL_MAX_LEN] = {0};
|
||||
const uint8_t zeros[] = {0x00, 0x00, 0x00};
|
||||
|
||||
seader_sam_key_label_format(true, NULL, 0U, label, sizeof(label));
|
||||
munit_assert_string_equal(label, "SAM: Standard Key");
|
||||
|
||||
seader_sam_key_label_format(true, zeros, sizeof(zeros), label, sizeof(label));
|
||||
munit_assert_string_equal(label, "SAM: Standard Key");
|
||||
return MUNIT_OK;
|
||||
}
|
||||
|
||||
static MunitResult test_formats_standard_key_for_eight_zero_bytes(
|
||||
const MunitParameter params[],
|
||||
void* fixture) {
|
||||
(void)params;
|
||||
(void)fixture;
|
||||
char label[SEADER_SAM_KEY_LABEL_MAX_LEN] = {0};
|
||||
const uint8_t zero64[] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
|
||||
|
||||
seader_sam_key_label_format(true, zero64, sizeof(zero64), label, sizeof(label));
|
||||
munit_assert_string_equal(label, "SAM: Standard Key");
|
||||
return MUNIT_OK;
|
||||
}
|
||||
|
||||
static MunitResult test_formats_ascii_ice_value(const MunitParameter params[], void* fixture) {
|
||||
(void)params;
|
||||
(void)fixture;
|
||||
char label[SEADER_SAM_KEY_LABEL_MAX_LEN] = {0};
|
||||
const uint8_t ice[] = {'I', 'C', 'E', '1', '8', '0', '3'};
|
||||
|
||||
seader_sam_key_label_format(true, ice, sizeof(ice), label, sizeof(label));
|
||||
munit_assert_string_equal(label, "SAM: ICE1803");
|
||||
return MUNIT_OK;
|
||||
}
|
||||
|
||||
static MunitResult test_sanitizes_non_printable_bytes(const MunitParameter params[], void* fixture) {
|
||||
(void)params;
|
||||
(void)fixture;
|
||||
char label[SEADER_SAM_KEY_LABEL_MAX_LEN] = {0};
|
||||
const uint8_t mixed[] = {'A', 0x00, 0x1F, 'Z'};
|
||||
|
||||
seader_sam_key_label_format(true, mixed, sizeof(mixed), label, sizeof(label));
|
||||
munit_assert_string_equal(label, "SAM: A??Z");
|
||||
return MUNIT_OK;
|
||||
}
|
||||
|
||||
static MunitTest test_sam_key_label_cases[] = {
|
||||
{(char*)"/no-sam", test_formats_no_sam, NULL, NULL, MUNIT_TEST_OPTION_NONE, NULL},
|
||||
{(char*)"/standard-key", test_formats_standard_key_for_missing_value, NULL, NULL, MUNIT_TEST_OPTION_NONE, NULL},
|
||||
{(char*)"/standard-key-zero64", test_formats_standard_key_for_eight_zero_bytes, NULL, NULL, MUNIT_TEST_OPTION_NONE, NULL},
|
||||
{(char*)"/ascii", test_formats_ascii_ice_value, NULL, NULL, MUNIT_TEST_OPTION_NONE, NULL},
|
||||
{(char*)"/sanitize", test_sanitizes_non_printable_bytes, NULL, NULL, MUNIT_TEST_OPTION_NONE, NULL},
|
||||
{NULL, NULL, NULL, NULL, 0, NULL},
|
||||
};
|
||||
|
||||
MunitSuite test_sam_key_label_suite = {
|
||||
"",
|
||||
test_sam_key_label_cases,
|
||||
NULL,
|
||||
1,
|
||||
MUNIT_SUITE_OPTION_NONE,
|
||||
};
|
||||
@@ -0,0 +1,34 @@
|
||||
#include "munit.h"
|
||||
#include "uhf_status_label.h"
|
||||
|
||||
static MunitResult test_formats_none(const MunitParameter params[], void* fixture) {
|
||||
(void)params;
|
||||
(void)fixture;
|
||||
char label[SEADER_UHF_STATUS_LABEL_MAX_LEN] = {0};
|
||||
seader_uhf_status_label_format(false, false, false, false, label, sizeof(label));
|
||||
munit_assert_string_equal(label, "UHF: none");
|
||||
return MUNIT_OK;
|
||||
}
|
||||
|
||||
static MunitResult test_formats_supported_key_states(const MunitParameter params[], void* fixture) {
|
||||
(void)params;
|
||||
(void)fixture;
|
||||
char label[SEADER_UHF_STATUS_LABEL_MAX_LEN] = {0};
|
||||
seader_uhf_status_label_format(true, false, true, true, label, sizeof(label));
|
||||
munit_assert_string_equal(label, "UHF: Monza 4QT [no key]/Higgs 3");
|
||||
return MUNIT_OK;
|
||||
}
|
||||
|
||||
static MunitTest test_uhf_status_label_cases[] = {
|
||||
{(char*)"/none", test_formats_none, NULL, NULL, MUNIT_TEST_OPTION_NONE, NULL},
|
||||
{(char*)"/supported-key-states", test_formats_supported_key_states, NULL, NULL, MUNIT_TEST_OPTION_NONE, NULL},
|
||||
{NULL, NULL, NULL, NULL, 0, NULL},
|
||||
};
|
||||
|
||||
MunitSuite test_uhf_status_label_suite = {
|
||||
"",
|
||||
test_uhf_status_label_cases,
|
||||
NULL,
|
||||
1,
|
||||
MUNIT_SUITE_OPTION_NONE,
|
||||
};
|
||||
@@ -1,5 +1,8 @@
|
||||
#include "sam_api.h"
|
||||
#include "sam_key_label.h"
|
||||
#include "trace_log.h"
|
||||
#include "uhf_snmp_probe.h"
|
||||
#include "uhf_status_label.h"
|
||||
#include <toolbox/path.h>
|
||||
#include <toolbox/version.h>
|
||||
#include <bit_lib/bit_lib.h>
|
||||
@@ -16,6 +19,99 @@ const uint8_t picopass_iclass_key[] = {0xaf, 0xa7, 0x85, 0xa7, 0xda, 0xb3, 0x33,
|
||||
const uint8_t seader_oid[] =
|
||||
{0x2B, 0x06, 0x01, 0x04, 0x01, 0x81, 0xE4, 0x38, 0x01, 0x01, 0x02, 0x04};
|
||||
|
||||
static void seader_sam_set_state(
|
||||
Seader* seader,
|
||||
SeaderSamState state,
|
||||
SeaderSamIntent intent,
|
||||
SamCommand_PR command);
|
||||
|
||||
static void seader_publish_sam_status(Seader* seader) {
|
||||
if(seader && seader->view_dispatcher) {
|
||||
view_dispatcher_send_custom_event(
|
||||
seader->view_dispatcher, SeaderCustomEventSamStatusUpdated);
|
||||
}
|
||||
}
|
||||
|
||||
static void seader_update_sam_key_label(Seader* seader, const uint8_t* value, size_t value_len) {
|
||||
if(!seader) {
|
||||
return;
|
||||
}
|
||||
|
||||
seader_sam_key_label_format(
|
||||
seader->sam_present,
|
||||
value,
|
||||
value_len,
|
||||
seader->sam_key_label,
|
||||
sizeof(seader->sam_key_label));
|
||||
seader_publish_sam_status(seader);
|
||||
}
|
||||
|
||||
static void seader_update_uhf_status_label(Seader* seader) {
|
||||
if(!seader) {
|
||||
return;
|
||||
}
|
||||
|
||||
seader_uhf_status_label_format(
|
||||
seader->snmp_probe.has_monza4qt,
|
||||
seader->snmp_probe.monza4qt_key_present,
|
||||
seader->snmp_probe.has_higgs3,
|
||||
seader->snmp_probe.higgs3_key_present,
|
||||
seader->uhf_status_label,
|
||||
sizeof(seader->uhf_status_label));
|
||||
seader_publish_sam_status(seader);
|
||||
}
|
||||
|
||||
static bool seader_snmp_probe_send_next_request(Seader* seader) {
|
||||
SeaderWorker* seader_worker = seader ? seader->worker : NULL;
|
||||
SeaderUartBridge* seader_uart = seader_worker ? seader_worker->uart : NULL;
|
||||
uint8_t* scratch = seader_uart ? (seader_uart->tx_buf + MAX_FRAME_HEADERS) : NULL;
|
||||
uint8_t* message = seader_uart ? seader_uart->rx_buf : NULL;
|
||||
size_t message_len = 0U;
|
||||
|
||||
if(!seader || !scratch || !message) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if(!seader_uhf_snmp_probe_build_next_request(
|
||||
&seader->snmp_probe,
|
||||
scratch,
|
||||
SEADER_UART_RX_BUF_SIZE - MAX_FRAME_HEADERS,
|
||||
message,
|
||||
SEADER_UART_RX_BUF_SIZE,
|
||||
&message_len)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return seader_worker_send_process_snmp_message(seader, message, message_len);
|
||||
}
|
||||
|
||||
static void seader_snmp_probe_finish(Seader* seader) {
|
||||
if(!seader) {
|
||||
return;
|
||||
}
|
||||
|
||||
seader_sam_set_state(seader, SeaderSamStateIdle, SeaderSamIntentNone, SamCommand_PR_NOTHING);
|
||||
}
|
||||
|
||||
static void seader_start_snmp_probe(Seader* seader) {
|
||||
if(!seader || !seader->sam_present) {
|
||||
return;
|
||||
}
|
||||
|
||||
seader_uhf_snmp_probe_init(&seader->snmp_probe);
|
||||
seader_uhf_status_label_format(
|
||||
false, false, false, false, seader->uhf_status_label, sizeof(seader->uhf_status_label));
|
||||
seader_sam_set_state(
|
||||
seader,
|
||||
SeaderSamStateCapabilityPending,
|
||||
SeaderSamIntentMaintenance,
|
||||
SamCommand_PR_processSNMPMessage);
|
||||
|
||||
if(!seader_snmp_probe_send_next_request(seader)) {
|
||||
seader_snmp_probe_finish(seader);
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef ASN1_DEBUG
|
||||
char asn1_log[SEADER_UART_RX_BUF_SIZE] = {0};
|
||||
#endif
|
||||
@@ -539,6 +635,8 @@ void seader_worker_send_serial_number(Seader* seader) {
|
||||
void seader_worker_send_version(Seader* seader) {
|
||||
SamCommand_t samCommand = {0};
|
||||
samCommand.present = SamCommand_PR_version;
|
||||
seader->sam_present = true;
|
||||
seader_update_sam_key_label(seader, NULL, 0U);
|
||||
seader_sam_set_state(
|
||||
seader, SeaderSamStateVersionPending, SeaderSamIntentMaintenance, samCommand.present);
|
||||
|
||||
@@ -550,6 +648,26 @@ void seader_worker_send_version(Seader* seader) {
|
||||
seader, &payload, ExternalApplicationA, SAMInterface, ExternalApplicationA);
|
||||
}
|
||||
|
||||
bool seader_worker_send_process_snmp_message(
|
||||
Seader* seader,
|
||||
const uint8_t* message,
|
||||
size_t message_len) {
|
||||
if(!seader || !message || message_len == 0U || message_len > UINT16_MAX) return false;
|
||||
|
||||
SamCommand_t samCommand = {0};
|
||||
samCommand.present = SamCommand_PR_processSNMPMessage;
|
||||
samCommand.choice.processSNMPMessage.buf = (uint8_t*)message;
|
||||
samCommand.choice.processSNMPMessage.size = message_len;
|
||||
|
||||
Payload_t payload = {0};
|
||||
payload.present = Payload_PR_samCommand;
|
||||
payload.choice.samCommand = samCommand;
|
||||
|
||||
seader_send_payload(
|
||||
seader, &payload, ExternalApplicationA, SAMInterface, ExternalApplicationA);
|
||||
return true;
|
||||
}
|
||||
|
||||
void seader_send_card_detected(Seader* seader, CardDetails_t* cardDetails) {
|
||||
CardDetected_t cardDetected = {
|
||||
.detectedCardDetails = *cardDetails,
|
||||
@@ -792,7 +910,7 @@ bool seader_sam_save_serial_QR(Seader* seader, char* serial) {
|
||||
bool seader_parse_serial_number(Seader* seader, uint8_t* buf, size_t size) {
|
||||
// Create hex string for QR code (needs to be persistent)
|
||||
char hex_string[size * 2 + 1];
|
||||
for(uint8_t i = 0; i < size; i++) {
|
||||
for(size_t i = 0; i < size; i++) {
|
||||
snprintf(hex_string + (i * 2), sizeof(hex_string) - (i * 2), "%02x", buf[i]);
|
||||
}
|
||||
hex_string[size * 2] = '\0';
|
||||
@@ -888,8 +1006,30 @@ bool seader_parse_sam_response(Seader* seader, SamResponse_t* samResponse) {
|
||||
case SeaderSamStateSerialPending:
|
||||
FURI_LOG_I(TAG, "samResponse serial");
|
||||
seader_parse_serial_number(seader, samResponse->buf, samResponse->size);
|
||||
seader_sam_set_state(
|
||||
seader, SeaderSamStateIdle, SeaderSamIntentNone, SamCommand_PR_NOTHING);
|
||||
seader_start_snmp_probe(seader);
|
||||
break;
|
||||
case SeaderSamStateCapabilityPending:
|
||||
FURI_LOG_I(TAG, "samResponse processSNMPMessage");
|
||||
if(!seader_uhf_snmp_probe_consume_response(
|
||||
&seader->snmp_probe, samResponse->buf, samResponse->size)) {
|
||||
seader_update_sam_key_label(seader, NULL, 0U);
|
||||
seader_snmp_probe_finish(seader);
|
||||
break;
|
||||
}
|
||||
|
||||
if(seader->snmp_probe.stage >= SeaderUhfSnmpProbeStageReadTagConfig) {
|
||||
seader_update_sam_key_label(
|
||||
seader, seader->snmp_probe.ice_value_storage, seader->snmp_probe.ice_value_len);
|
||||
seader_update_uhf_status_label(seader);
|
||||
}
|
||||
|
||||
if(seader->snmp_probe.stage == SeaderUhfSnmpProbeStageDone) {
|
||||
seader_snmp_probe_finish(seader);
|
||||
} else if(
|
||||
seader->snmp_probe.stage == SeaderUhfSnmpProbeStageFailed ||
|
||||
!seader_snmp_probe_send_next_request(seader)) {
|
||||
seader_snmp_probe_finish(seader);
|
||||
}
|
||||
break;
|
||||
case SeaderSamStateDetectPending:
|
||||
FURI_LOG_I(TAG, "samResponse cardDetected");
|
||||
@@ -1199,7 +1339,7 @@ void seader_mfc_transmit(
|
||||
size_t tx_size = bit_buffer_get_size_bytes(tx_buffer);
|
||||
uint8_t* tx_data = malloc(tx_size);
|
||||
if(tx_data) {
|
||||
for(uint8_t i = 0; i < tx_size; i++) {
|
||||
for(size_t i = 0; i < tx_size; i++) {
|
||||
tx_data[i] = bit_buffer_get_byte(tx_buffer, i);
|
||||
}
|
||||
seader_log_hex_data(TAG, "NFC Send without parity", tx_data, tx_size);
|
||||
@@ -1230,7 +1370,7 @@ void seader_mfc_transmit(
|
||||
// Log the BitBuffer contents efficiently
|
||||
uint8_t* rx_data = malloc(length);
|
||||
if(rx_data) {
|
||||
for(uint8_t i = 0; i < length; i++) {
|
||||
for(size_t i = 0; i < length; i++) {
|
||||
rx_data[i] = bit_buffer_get_byte(rx_buffer, i);
|
||||
}
|
||||
seader_log_hex_data(TAG, "NFC Response without parity", rx_data, length);
|
||||
@@ -1277,7 +1417,7 @@ void seader_mfc_transmit(
|
||||
// Log the BitBuffer contents efficiently
|
||||
uint8_t* rx_data_parity = malloc(length);
|
||||
if(rx_data_parity) {
|
||||
for(uint8_t i = 0; i < length; i++) {
|
||||
for(size_t i = 0; i < length; i++) {
|
||||
rx_data_parity[i] = bit_buffer_get_byte(rx_buffer, i);
|
||||
}
|
||||
seader_log_hex_data(TAG, "NFC Response with parity", rx_data_parity, length);
|
||||
@@ -1410,7 +1550,23 @@ bool seader_worker_state_machine(
|
||||
case Payload_PR_errorResponse:
|
||||
FURI_LOG_W(TAG, "Payload_PR_errorResponse");
|
||||
processed = true;
|
||||
view_dispatcher_send_custom_event(seader->view_dispatcher, SeaderCustomEventWorkerExit);
|
||||
if(seader->sam_state == SeaderSamStateCapabilityPending) {
|
||||
ErrorResponse_t* err = &payload->choice.errorResponse;
|
||||
if(seader_uhf_snmp_probe_consume_error(
|
||||
&seader->snmp_probe, err->errorCode, err->data.buf, err->data.size)) {
|
||||
seader_update_uhf_status_label(seader);
|
||||
if(seader->snmp_probe.stage == SeaderUhfSnmpProbeStageDone) {
|
||||
seader_snmp_probe_finish(seader);
|
||||
} else if(!seader_snmp_probe_send_next_request(seader)) {
|
||||
seader_snmp_probe_finish(seader);
|
||||
}
|
||||
} else {
|
||||
seader_snmp_probe_finish(seader);
|
||||
}
|
||||
} else {
|
||||
view_dispatcher_send_custom_event(
|
||||
seader->view_dispatcher, SeaderCustomEventWorkerExit);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
FURI_LOG_W(TAG, "unhandled payload");
|
||||
|
||||
@@ -36,3 +36,8 @@ bool seader_process_success_response_i(
|
||||
size_t len,
|
||||
bool online,
|
||||
SeaderPollerContainer* spc);
|
||||
|
||||
bool seader_worker_send_process_snmp_message(
|
||||
Seader* seader,
|
||||
const uint8_t* message,
|
||||
size_t message_len);
|
||||
|
||||
@@ -0,0 +1,56 @@
|
||||
#include "sam_key_label.h"
|
||||
|
||||
#include <ctype.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
static bool seader_sam_key_label_is_missing(const uint8_t* value, size_t value_len) {
|
||||
if(!value || value_len == 0U) {
|
||||
return true;
|
||||
}
|
||||
|
||||
for(size_t i = 0; i < value_len; i++) {
|
||||
if(value[i] != 0x00U) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void seader_sam_key_label_format(
|
||||
bool sam_present,
|
||||
const uint8_t* elite_ice_value,
|
||||
size_t elite_ice_value_len,
|
||||
char* out,
|
||||
size_t out_size) {
|
||||
if(!out || out_size == 0U) {
|
||||
return;
|
||||
}
|
||||
|
||||
out[0] = '\0';
|
||||
|
||||
if(!sam_present) {
|
||||
snprintf(out, out_size, "NO SAM");
|
||||
return;
|
||||
}
|
||||
|
||||
if(seader_sam_key_label_is_missing(elite_ice_value, elite_ice_value_len)) {
|
||||
snprintf(out, out_size, "SAM: Standard Key");
|
||||
return;
|
||||
}
|
||||
|
||||
size_t pos = 0U;
|
||||
pos += (size_t)snprintf(out + pos, out_size - pos, "SAM: ");
|
||||
if(pos >= out_size) {
|
||||
out[out_size - 1U] = '\0';
|
||||
return;
|
||||
}
|
||||
|
||||
for(size_t i = 0; i < elite_ice_value_len && pos + 1U < out_size; i++) {
|
||||
unsigned char ch = elite_ice_value[i];
|
||||
out[pos++] = isprint(ch) ? (char)ch : '?';
|
||||
}
|
||||
|
||||
out[pos] = '\0';
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
#pragma once
|
||||
|
||||
#include <stdbool.h>
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#define SEADER_SAM_KEY_LABEL_MAX_LEN 32U
|
||||
|
||||
void seader_sam_key_label_format(
|
||||
bool sam_present,
|
||||
const uint8_t* elite_ice_value,
|
||||
size_t elite_ice_value_len,
|
||||
char* out,
|
||||
size_t out_size);
|
||||
@@ -33,9 +33,15 @@ Seader* seader_alloc() {
|
||||
seader->samCommand = SamCommand_PR_NOTHING;
|
||||
seader->sam_state = SeaderSamStateIdle;
|
||||
seader->sam_intent = SeaderSamIntentNone;
|
||||
seader->sam_present = false;
|
||||
seader_sam_key_label_format(
|
||||
false, NULL, 0U, seader->sam_key_label, sizeof(seader->sam_key_label));
|
||||
seader_uhf_status_label_format(
|
||||
false, false, false, false, seader->uhf_status_label, sizeof(seader->uhf_status_label));
|
||||
memset(seader->detected_card_types, 0, sizeof(seader->detected_card_types));
|
||||
seader->detected_card_type_count = 0;
|
||||
seader->selected_read_type = SeaderCredentialTypeNone;
|
||||
seader_uhf_snmp_probe_init(&seader->snmp_probe);
|
||||
|
||||
seader->worker = seader_worker_alloc();
|
||||
seader->view_dispatcher = view_dispatcher_alloc();
|
||||
|
||||
@@ -56,6 +56,9 @@
|
||||
#include "seader_worker.h"
|
||||
#include "seader_credential.h"
|
||||
#include "apdu_log.h"
|
||||
#include "sam_key_label.h"
|
||||
#include "uhf_snmp_probe.h"
|
||||
#include "uhf_status_label.h"
|
||||
|
||||
#define WORKER_ALL_RX_EVENTS \
|
||||
(WorkerEvtStop | WorkerEvtRxDone | WorkerEvtCfgChange | WorkerEvtLineCfgSet | \
|
||||
@@ -78,6 +81,7 @@ enum SeaderCustomEvent {
|
||||
|
||||
SeaderCustomEventPollerDetect,
|
||||
SeaderCustomEventPollerSuccess,
|
||||
SeaderCustomEventSamStatusUpdated,
|
||||
};
|
||||
|
||||
typedef enum {
|
||||
@@ -107,6 +111,7 @@ typedef enum {
|
||||
SeaderSamStateClearPending,
|
||||
SeaderSamStateVersionPending,
|
||||
SeaderSamStateSerialPending,
|
||||
SeaderSamStateCapabilityPending,
|
||||
} SeaderSamState;
|
||||
|
||||
typedef enum {
|
||||
@@ -129,8 +134,12 @@ struct Seader {
|
||||
SamCommand_PR samCommand;
|
||||
SeaderSamState sam_state;
|
||||
SeaderSamIntent sam_intent;
|
||||
bool sam_present;
|
||||
uint8_t ATR[SEADER_MAX_ATR_SIZE];
|
||||
size_t ATR_len;
|
||||
char sam_key_label[SEADER_SAM_KEY_LABEL_MAX_LEN];
|
||||
char uhf_status_label[SEADER_UHF_STATUS_LABEL_MAX_LEN];
|
||||
SeaderUhfSnmpProbe snmp_probe;
|
||||
|
||||
char text_store[SEADER_TEXT_STORE_SIZE + 1];
|
||||
char read_error[SEADER_TEXT_STORE_SIZE + 1];
|
||||
|
||||
@@ -0,0 +1,57 @@
|
||||
#include "uhf_status_label.h"
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
static size_t seader_uhf_append_family(
|
||||
char* out,
|
||||
size_t out_size,
|
||||
size_t pos,
|
||||
bool* wrote_any,
|
||||
const char* name,
|
||||
bool key_present) {
|
||||
if(*wrote_any) {
|
||||
pos += (size_t)snprintf(out + pos, out_size - pos, "/");
|
||||
} else {
|
||||
pos += (size_t)snprintf(out + pos, out_size - pos, "UHF: ");
|
||||
*wrote_any = true;
|
||||
}
|
||||
|
||||
pos += (size_t)snprintf(out + pos, out_size - pos, "%s", name);
|
||||
if(!key_present) {
|
||||
pos += (size_t)snprintf(out + pos, out_size - pos, " [no key]");
|
||||
}
|
||||
return pos;
|
||||
}
|
||||
|
||||
void seader_uhf_status_label_format(
|
||||
bool has_monza4qt,
|
||||
bool monza4qt_key_present,
|
||||
bool has_higgs3,
|
||||
bool higgs3_key_present,
|
||||
char* out,
|
||||
size_t out_size) {
|
||||
bool wrote_any = false;
|
||||
size_t pos = 0U;
|
||||
|
||||
if(!out || out_size == 0U) {
|
||||
return;
|
||||
}
|
||||
|
||||
out[0] = '\0';
|
||||
|
||||
if(has_monza4qt) {
|
||||
pos = seader_uhf_append_family(
|
||||
out, out_size, pos, &wrote_any, "Monza 4QT", monza4qt_key_present);
|
||||
}
|
||||
if(has_higgs3) {
|
||||
pos = seader_uhf_append_family(
|
||||
out, out_size, pos, &wrote_any, "Higgs 3", higgs3_key_present);
|
||||
}
|
||||
|
||||
if(!wrote_any) {
|
||||
snprintf(out, out_size, "UHF: none");
|
||||
} else if(pos >= out_size) {
|
||||
out[out_size - 1U] = '\0';
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
#pragma once
|
||||
|
||||
#include <stdbool.h>
|
||||
#include <stddef.h>
|
||||
|
||||
#define SEADER_UHF_STATUS_LABEL_MAX_LEN 64U
|
||||
|
||||
void seader_uhf_status_label_format(
|
||||
bool has_monza4qt,
|
||||
bool monza4qt_key_present,
|
||||
bool has_higgs3,
|
||||
bool higgs3_key_present,
|
||||
char* out,
|
||||
size_t out_size);
|
||||
Reference in New Issue
Block a user