mirror of
https://github.com/Next-Flip/Momentum-Firmware.git
synced 2026-04-24 03:29:57 -07:00
Merge branch 'dev' into astra/3746-mfp-detect
This commit is contained in:
13
.clangd
Normal file
13
.clangd
Normal file
@@ -0,0 +1,13 @@
|
||||
CompileFlags:
|
||||
Add:
|
||||
- -Wno-unknown-warning-option
|
||||
- -Wno-format
|
||||
Remove:
|
||||
- -mword-relocations
|
||||
|
||||
---
|
||||
|
||||
If:
|
||||
PathMatch: .*\.h
|
||||
Diagnostics:
|
||||
UnusedIncludes: None
|
||||
3
.gitignore
vendored
3
.gitignore
vendored
@@ -12,6 +12,9 @@ compile_commands.json
|
||||
# JetBrains IDEs
|
||||
.idea/
|
||||
|
||||
# Sublime Text
|
||||
.sublime-project.sublime-workspace
|
||||
|
||||
# Python VirtEnvironments
|
||||
.env
|
||||
.venv
|
||||
|
||||
21
.sublime-project
vendored
Normal file
21
.sublime-project
vendored
Normal file
@@ -0,0 +1,21 @@
|
||||
{
|
||||
"folders":
|
||||
[
|
||||
{
|
||||
"path": ".",
|
||||
}
|
||||
],
|
||||
"settings": {
|
||||
"LSP": {
|
||||
"clangd": {
|
||||
"initializationOptions": {
|
||||
"clangd.compile-commands-dir": "build/latest",
|
||||
"clangd.header-insertion": null,
|
||||
"clangd.query-driver": "**",
|
||||
"clangd.clang-tidy": true,
|
||||
},
|
||||
"enabled": true,
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
4
.vscode/example/settings.json
vendored
4
.vscode/example/settings.json
vendored
@@ -19,6 +19,8 @@
|
||||
"clangd.arguments": [
|
||||
// We might be able to tighten this a bit more to only include the correct toolchain.
|
||||
"--query-driver=**",
|
||||
"--compile-commands-dir=${workspaceFolder}/build/latest"
|
||||
"--compile-commands-dir=${workspaceFolder}/build/latest",
|
||||
"--clang-tidy",
|
||||
"--header-insertion=never"
|
||||
]
|
||||
}
|
||||
@@ -6,8 +6,9 @@
|
||||
#include <gui/view_dispatcher.h>
|
||||
#include <gui/modules/submenu.h>
|
||||
#include <gui/gui.h>
|
||||
|
||||
#include "iso7816_callbacks.h"
|
||||
#include "iso7816_t0_apdu.h"
|
||||
#include "iso7816_atr.h"
|
||||
|
||||
typedef enum {
|
||||
EventTypeInput,
|
||||
@@ -33,38 +34,6 @@ typedef enum {
|
||||
CcidTestSubmenuIndexInsertSmartcardReader
|
||||
} SubmenuIndex;
|
||||
|
||||
void icc_power_on_callback(uint8_t* atrBuffer, uint32_t* atrlen, void* context) {
|
||||
UNUSED(context);
|
||||
|
||||
iso7816_answer_to_reset(atrBuffer, atrlen);
|
||||
}
|
||||
|
||||
//dataBlock points to the buffer
|
||||
//dataBlockLen tells reader how nany bytes should be read
|
||||
void xfr_datablock_callback(
|
||||
const uint8_t* dataBlock,
|
||||
uint32_t dataBlockLen,
|
||||
uint8_t* responseDataBlock,
|
||||
uint32_t* responseDataBlockLen,
|
||||
void* context) {
|
||||
UNUSED(context);
|
||||
|
||||
struct ISO7816_Command_APDU commandAPDU;
|
||||
iso7816_read_command_apdu(&commandAPDU, dataBlock, dataBlockLen);
|
||||
|
||||
struct ISO7816_Response_APDU responseAPDU;
|
||||
//class not supported
|
||||
responseAPDU.SW1 = 0x6E;
|
||||
responseAPDU.SW2 = 0x00;
|
||||
|
||||
iso7816_write_response_apdu(&responseAPDU, responseDataBlock, responseDataBlockLen);
|
||||
}
|
||||
|
||||
static const CcidCallbacks ccid_cb = {
|
||||
icc_power_on_callback,
|
||||
xfr_datablock_callback,
|
||||
};
|
||||
|
||||
static void ccid_test_app_render_callback(Canvas* canvas, void* ctx) {
|
||||
UNUSED(ctx);
|
||||
canvas_clear(canvas);
|
||||
@@ -127,6 +96,86 @@ void ccid_test_app_free(CcidTestApp* app) {
|
||||
free(app);
|
||||
}
|
||||
|
||||
void ccid_icc_power_on_callback(uint8_t* atrBuffer, uint32_t* atrlen, void* context) {
|
||||
UNUSED(context);
|
||||
|
||||
iso7816_icc_power_on_callback(atrBuffer, atrlen);
|
||||
}
|
||||
|
||||
void ccid_xfr_datablock_callback(
|
||||
const uint8_t* pcToReaderDataBlock,
|
||||
uint32_t pcToReaderDataBlockLen,
|
||||
uint8_t* readerToPcDataBlock,
|
||||
uint32_t* readerToPcDataBlockLen,
|
||||
void* context) {
|
||||
UNUSED(context);
|
||||
|
||||
iso7816_xfr_datablock_callback(
|
||||
pcToReaderDataBlock, pcToReaderDataBlockLen, readerToPcDataBlock, readerToPcDataBlockLen);
|
||||
}
|
||||
|
||||
static const CcidCallbacks ccid_cb = {
|
||||
ccid_icc_power_on_callback,
|
||||
ccid_xfr_datablock_callback,
|
||||
};
|
||||
|
||||
void iso7816_answer_to_reset(Iso7816Atr* atr) {
|
||||
//minimum valid ATR: https://smartcard-atr.apdu.fr/parse?ATR=3B+00
|
||||
atr->TS = 0x3B;
|
||||
atr->T0 = 0x00;
|
||||
}
|
||||
|
||||
void iso7816_process_command(
|
||||
const struct ISO7816_Command_APDU* commandAPDU,
|
||||
struct ISO7816_Response_APDU* responseAPDU,
|
||||
const uint8_t* commandApduDataBuffer,
|
||||
uint8_t commandApduDataBufferLen,
|
||||
uint8_t* responseApduDataBuffer,
|
||||
uint8_t* responseApduDataBufferLen) {
|
||||
//example 1: sends a command with no body, receives a response with no body
|
||||
//sends APDU 0x01:0x02:0x00:0x00
|
||||
//receives SW1=0x90, SW2=0x00
|
||||
if(commandAPDU->CLA == 0x01 && commandAPDU->INS == 0x01) {
|
||||
responseAPDU->SW1 = 0x90;
|
||||
responseAPDU->SW2 = 0x00;
|
||||
}
|
||||
//example 2: sends a command with no body, receives a response with a body with two bytes
|
||||
//sends APDU 0x01:0x02:0x00:0x00
|
||||
//receives 'bc' (0x62, 0x63) SW1=0x80, SW2=0x10
|
||||
else if(commandAPDU->CLA == 0x01 && commandAPDU->INS == 0x02) {
|
||||
responseApduDataBuffer[0] = 0x62;
|
||||
responseApduDataBuffer[1] = 0x63;
|
||||
|
||||
*responseApduDataBufferLen = 2;
|
||||
|
||||
responseAPDU->SW1 = 0x90;
|
||||
responseAPDU->SW2 = 0x00;
|
||||
}
|
||||
//example 3: ends a command with a body with two bytes, receives a response with a body with two bytes
|
||||
//sends APDU 0x01:0x03:0x00:0x00:0x02:CA:FE
|
||||
//receives (0xCA, 0xFE) SW1=0x90, SW2=0x02
|
||||
else if(
|
||||
commandAPDU->CLA == 0x01 && commandAPDU->INS == 0x03 && commandApduDataBufferLen == 2 &&
|
||||
commandAPDU->Lc == 2) {
|
||||
//echo command body to response body
|
||||
responseApduDataBuffer[0] = commandApduDataBuffer[0];
|
||||
responseApduDataBuffer[1] = commandApduDataBuffer[1];
|
||||
|
||||
*responseApduDataBufferLen = 2;
|
||||
|
||||
responseAPDU->SW1 = 0x90;
|
||||
responseAPDU->SW2 = 0x00;
|
||||
} else {
|
||||
responseAPDU->SW1 = 0x6A;
|
||||
responseAPDU->SW2 = 0x00;
|
||||
}
|
||||
}
|
||||
|
||||
static const Iso7816Callbacks iso87816_cb = {
|
||||
iso7816_answer_to_reset,
|
||||
iso7816_process_command,
|
||||
};
|
||||
|
||||
int32_t ccid_test_app(void* p) {
|
||||
UNUSED(p);
|
||||
|
||||
@@ -135,14 +184,16 @@ int32_t ccid_test_app(void* p) {
|
||||
|
||||
//setup CCID USB
|
||||
// On linux: set VID PID using: /usr/lib/pcsc/drivers/ifd-ccid.bundle/Contents/Info.plist
|
||||
app->ccid_cfg.vid = 0x1234;
|
||||
app->ccid_cfg.pid = 0x5678;
|
||||
app->ccid_cfg.vid = 0x076B;
|
||||
app->ccid_cfg.pid = 0x3A21;
|
||||
|
||||
FuriHalUsbInterface* usb_mode_prev = furi_hal_usb_get_config();
|
||||
furi_hal_usb_unlock();
|
||||
furi_hal_ccid_set_callbacks((CcidCallbacks*)&ccid_cb);
|
||||
furi_hal_ccid_set_callbacks((CcidCallbacks*)&ccid_cb, NULL);
|
||||
furi_check(furi_hal_usb_set_config(&usb_ccid, &app->ccid_cfg) == true);
|
||||
|
||||
iso7816_set_callbacks((Iso7816Callbacks*)&iso87816_cb);
|
||||
|
||||
//handle button events
|
||||
CcidTestAppEvent event;
|
||||
while(1) {
|
||||
@@ -161,7 +212,9 @@ int32_t ccid_test_app(void* p) {
|
||||
|
||||
//tear down USB
|
||||
furi_hal_usb_set_config(usb_mode_prev, NULL);
|
||||
furi_hal_ccid_set_callbacks(NULL);
|
||||
furi_hal_ccid_set_callbacks(NULL, NULL);
|
||||
|
||||
iso7816_set_callbacks(NULL);
|
||||
|
||||
//teardown view
|
||||
ccid_test_app_free(app);
|
||||
|
||||
9
applications/debug/ccid_test/iso7816_atr.h
Normal file
9
applications/debug/ccid_test/iso7816_atr.h
Normal file
@@ -0,0 +1,9 @@
|
||||
#ifndef _ISO7816_ATR_H_
|
||||
#define _ISO7816_ATR_H_
|
||||
|
||||
typedef struct {
|
||||
uint8_t TS;
|
||||
uint8_t T0;
|
||||
} Iso7816Atr;
|
||||
|
||||
#endif //_ISO7816_ATR_H_
|
||||
76
applications/debug/ccid_test/iso7816_callbacks.c
Normal file
76
applications/debug/ccid_test/iso7816_callbacks.c
Normal file
@@ -0,0 +1,76 @@
|
||||
// transforms low level calls such as XFRCallback or ICC Power on to a structured one
|
||||
// an application can register these calls and listen for the callbacks defined in Iso7816Callbacks
|
||||
|
||||
#include "iso7816_t0_apdu.h"
|
||||
#include "iso7816_atr.h"
|
||||
#include "iso7816_callbacks.h"
|
||||
#include <stdint.h>
|
||||
#include <stddef.h>
|
||||
#include <furi.h>
|
||||
|
||||
#define ISO7816_RESPONSE_BUFFER_SIZE 255
|
||||
|
||||
static Iso7816Callbacks* callbacks = NULL;
|
||||
|
||||
void iso7816_set_callbacks(Iso7816Callbacks* cb) {
|
||||
callbacks = cb;
|
||||
}
|
||||
|
||||
void iso7816_icc_power_on_callback(uint8_t* atrBuffer, uint32_t* atrlen) {
|
||||
Iso7816Atr atr;
|
||||
callbacks->iso7816_answer_to_reset(&atr);
|
||||
|
||||
furi_assert(atr.T0 == 0x00);
|
||||
|
||||
uint8_t AtrBuffer[2] = {atr.TS, atr.T0};
|
||||
|
||||
*atrlen = 2;
|
||||
|
||||
memcpy(atrBuffer, AtrBuffer, sizeof(uint8_t) * (*atrlen));
|
||||
}
|
||||
|
||||
//dataBlock points to the buffer
|
||||
//dataBlockLen tells reader how nany bytes should be read
|
||||
void iso7816_xfr_datablock_callback(
|
||||
const uint8_t* pcToReaderDataBlock,
|
||||
uint32_t pcToReaderDataBlockLen,
|
||||
uint8_t* readerToPcDataBlock,
|
||||
uint32_t* readerToPcDataBlockLen) {
|
||||
struct ISO7816_Response_APDU responseAPDU;
|
||||
uint8_t responseApduDataBuffer[ISO7816_RESPONSE_BUFFER_SIZE];
|
||||
uint8_t responseApduDataBufferLen = 0;
|
||||
|
||||
if(callbacks != NULL) {
|
||||
struct ISO7816_Command_APDU commandAPDU;
|
||||
|
||||
const uint8_t* commandApduDataBuffer = NULL;
|
||||
uint8_t commandApduDataBufferLen = 0;
|
||||
|
||||
iso7816_read_command_apdu(&commandAPDU, pcToReaderDataBlock, pcToReaderDataBlockLen);
|
||||
|
||||
if(commandAPDU.Lc > 0) {
|
||||
commandApduDataBufferLen = commandAPDU.Lc;
|
||||
commandApduDataBuffer = &pcToReaderDataBlock[5];
|
||||
}
|
||||
|
||||
callbacks->iso7816_process_command(
|
||||
&commandAPDU,
|
||||
&responseAPDU,
|
||||
commandApduDataBuffer,
|
||||
commandApduDataBufferLen,
|
||||
responseApduDataBuffer,
|
||||
&responseApduDataBufferLen);
|
||||
|
||||
} else {
|
||||
//class not supported
|
||||
responseAPDU.SW1 = 0x6E;
|
||||
responseAPDU.SW2 = 0x00;
|
||||
}
|
||||
|
||||
iso7816_write_response_apdu(
|
||||
&responseAPDU,
|
||||
readerToPcDataBlock,
|
||||
readerToPcDataBlockLen,
|
||||
responseApduDataBuffer,
|
||||
responseApduDataBufferLen);
|
||||
}
|
||||
28
applications/debug/ccid_test/iso7816_callbacks.h
Normal file
28
applications/debug/ccid_test/iso7816_callbacks.h
Normal file
@@ -0,0 +1,28 @@
|
||||
#ifndef _ISO7816_CALLBACKS_H_
|
||||
#define _ISO7816_CALLBACKS_H_
|
||||
|
||||
#include <stdint.h>
|
||||
#include "iso7816_atr.h"
|
||||
#include "iso7816_t0_apdu.h"
|
||||
|
||||
typedef struct {
|
||||
void (*iso7816_answer_to_reset)(Iso7816Atr* atr);
|
||||
void (*iso7816_process_command)(
|
||||
const struct ISO7816_Command_APDU* command,
|
||||
struct ISO7816_Response_APDU* response,
|
||||
const uint8_t* commandApduDataBuffer,
|
||||
uint8_t commandApduDataBufferLen,
|
||||
uint8_t* responseApduDataBuffer,
|
||||
uint8_t* responseApduDataBufferLen);
|
||||
} Iso7816Callbacks;
|
||||
|
||||
void iso7816_set_callbacks(Iso7816Callbacks* cb);
|
||||
|
||||
void iso7816_icc_power_on_callback(uint8_t* atrBuffer, uint32_t* atrlen);
|
||||
void iso7816_xfr_datablock_callback(
|
||||
const uint8_t* dataBlock,
|
||||
uint32_t dataBlockLen,
|
||||
uint8_t* responseDataBlock,
|
||||
uint32_t* responseDataBlockLen);
|
||||
|
||||
#endif //_ISO7816_CALLBACKS_H_
|
||||
@@ -4,22 +4,14 @@
|
||||
#include <furi.h>
|
||||
#include "iso7816_t0_apdu.h"
|
||||
|
||||
void iso7816_answer_to_reset(uint8_t* dataBuffer, uint32_t* atrlen) {
|
||||
//minimum valid ATR: https://smartcard-atr.apdu.fr/parse?ATR=3B+00
|
||||
uint8_t AtrBuffer[2] = {
|
||||
0x3B, //TS (direct convention)
|
||||
0x00 // T0 (Y(1): b0000, K: 0 (historical bytes))
|
||||
};
|
||||
*atrlen = 2;
|
||||
|
||||
memcpy(dataBuffer, AtrBuffer, sizeof(uint8_t) * (*atrlen));
|
||||
}
|
||||
|
||||
//reads dataBuffer with dataLen size, translate it into a ISO7816_Command_APDU type
|
||||
//extra data will be pointed to commandDataBuffer
|
||||
void iso7816_read_command_apdu(
|
||||
struct ISO7816_Command_APDU* command,
|
||||
const uint8_t* dataBuffer,
|
||||
uint32_t dataLen) {
|
||||
UNUSED(dataLen);
|
||||
|
||||
command->CLA = dataBuffer[0];
|
||||
command->INS = dataBuffer[1];
|
||||
command->P1 = dataBuffer[2];
|
||||
@@ -27,11 +19,30 @@ void iso7816_read_command_apdu(
|
||||
command->Lc = dataBuffer[4];
|
||||
}
|
||||
|
||||
//data buffer countains the whole APU response (response + trailer (SW1+SW2))
|
||||
void iso7816_write_response_apdu(
|
||||
const struct ISO7816_Response_APDU* response,
|
||||
uint8_t* dataBuffer,
|
||||
uint32_t* dataLen) {
|
||||
dataBuffer[0] = response->SW1;
|
||||
dataBuffer[1] = response->SW2;
|
||||
*dataLen = 2;
|
||||
uint8_t* readerToPcDataBlock,
|
||||
uint32_t* readerToPcDataBlockLen,
|
||||
uint8_t* responseDataBuffer,
|
||||
uint32_t responseDataLen) {
|
||||
uint32_t responseDataBufferIndex = 0;
|
||||
|
||||
//response body
|
||||
if(responseDataLen > 0) {
|
||||
while(responseDataBufferIndex < responseDataLen) {
|
||||
readerToPcDataBlock[responseDataBufferIndex] =
|
||||
responseDataBuffer[responseDataBufferIndex];
|
||||
responseDataBufferIndex++;
|
||||
}
|
||||
}
|
||||
|
||||
//trailer
|
||||
readerToPcDataBlock[responseDataBufferIndex] = response->SW1;
|
||||
responseDataBufferIndex++;
|
||||
|
||||
readerToPcDataBlock[responseDataBufferIndex] = response->SW2;
|
||||
responseDataBufferIndex++;
|
||||
|
||||
*readerToPcDataBlockLen = responseDataBufferIndex;
|
||||
}
|
||||
@@ -2,6 +2,8 @@
|
||||
#define _ISO7816_T0_APDU_H_
|
||||
|
||||
#include <stdint.h>
|
||||
#include "iso7816_atr.h"
|
||||
#include "core/common_defines.h"
|
||||
|
||||
struct ISO7816_Command_APDU {
|
||||
//header
|
||||
@@ -20,13 +22,15 @@ struct ISO7816_Response_APDU {
|
||||
uint8_t SW2;
|
||||
} FURI_PACKED;
|
||||
|
||||
void iso7816_answer_to_reset(uint8_t* atrBuffer, uint32_t* atrlen);
|
||||
void iso7816_answer_to_reset(Iso7816Atr* atr);
|
||||
void iso7816_read_command_apdu(
|
||||
struct ISO7816_Command_APDU* command,
|
||||
const uint8_t* dataBuffer,
|
||||
uint32_t dataLen);
|
||||
void iso7816_write_response_apdu(
|
||||
const struct ISO7816_Response_APDU* response,
|
||||
uint8_t* dataBuffer,
|
||||
uint32_t* dataLen);
|
||||
uint8_t* readerToPcDataBlock,
|
||||
uint32_t* readerToPcDataBlockLen,
|
||||
uint8_t* responseDataBuffer,
|
||||
uint32_t responseDataLen);
|
||||
#endif //_ISO7816_T0_APDU_H_
|
||||
|
||||
@@ -80,6 +80,14 @@ SubGhzProtocolStatus subghz_txrx_gen_data_protocol_and_te(
|
||||
FURI_LOG_E(TAG, "Unable to update Te");
|
||||
}
|
||||
}
|
||||
if(ret == SubGhzProtocolStatusOk) {
|
||||
uint32_t guard_time = 30;
|
||||
if(!flipper_format_update_uint32(
|
||||
instance->fff_data, "Guard_time", (uint32_t*)&guard_time, 1)) {
|
||||
ret = SubGhzProtocolStatusErrorParserOthers;
|
||||
FURI_LOG_E(TAG, "Unable to update Guard_time");
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
@@ -20,6 +20,7 @@ env = ENV.Clone(
|
||||
"fbt_resources",
|
||||
],
|
||||
COMPILATIONDB_USE_ABSPATH=False,
|
||||
COMPILATIONDB_USE_BINARY_ABSPATH=True,
|
||||
BUILD_DIR=fw_build_meta["build_dir"],
|
||||
IS_BASE_FIRMWARE=fw_build_meta["type"] == "firmware",
|
||||
FW_FLAVOR=fw_build_meta["flavor"],
|
||||
|
||||
@@ -13,6 +13,7 @@
|
||||
*/
|
||||
|
||||
#define TAG "SubGhzProtocolPrinceton"
|
||||
#define PRINCETON_GUARD_TIME_DEFALUT 30 //GUARD_TIME = PRINCETON_GUARD_TIME_DEFALUT * TE
|
||||
|
||||
static const SubGhzBlockConst subghz_protocol_princeton_const = {
|
||||
.te_short = 390,
|
||||
@@ -29,6 +30,7 @@ struct SubGhzProtocolDecoderPrinceton {
|
||||
|
||||
uint32_t te;
|
||||
uint32_t last_data;
|
||||
uint32_t guard_time;
|
||||
};
|
||||
|
||||
struct SubGhzProtocolEncoderPrinceton {
|
||||
@@ -38,6 +40,7 @@ struct SubGhzProtocolEncoderPrinceton {
|
||||
SubGhzBlockGeneric generic;
|
||||
|
||||
uint32_t te;
|
||||
uint32_t guard_time;
|
||||
};
|
||||
|
||||
typedef enum {
|
||||
@@ -135,8 +138,9 @@ static bool
|
||||
|
||||
//Send Stop bit
|
||||
instance->encoder.upload[index++] = level_duration_make(true, (uint32_t)instance->te);
|
||||
//Send PT_GUARD
|
||||
instance->encoder.upload[index++] = level_duration_make(false, (uint32_t)instance->te * 30);
|
||||
//Send PT_GUARD_TIME
|
||||
instance->encoder.upload[index++] =
|
||||
level_duration_make(false, (uint32_t)instance->te * instance->guard_time);
|
||||
|
||||
return true;
|
||||
}
|
||||
@@ -165,6 +169,11 @@ SubGhzProtocolStatus
|
||||
break;
|
||||
}
|
||||
//optional parameter parameter
|
||||
if(!flipper_format_read_uint32(
|
||||
flipper_format, "Guard_time", (uint32_t*)&instance->guard_time, 1)) {
|
||||
instance->guard_time = PRINCETON_GUARD_TIME_DEFALUT;
|
||||
}
|
||||
|
||||
flipper_format_read_uint32(
|
||||
flipper_format, "Repeat", (uint32_t*)&instance->encoder.repeat, 1);
|
||||
|
||||
@@ -235,6 +244,7 @@ void subghz_protocol_decoder_princeton_feed(void* context, bool level, uint32_t
|
||||
instance->decoder.decode_data = 0;
|
||||
instance->decoder.decode_count_bit = 0;
|
||||
instance->te = 0;
|
||||
instance->guard_time = PRINCETON_GUARD_TIME_DEFALUT;
|
||||
}
|
||||
break;
|
||||
case PrincetonDecoderStepSaveDuration:
|
||||
@@ -257,6 +267,7 @@ void subghz_protocol_decoder_princeton_feed(void* context, bool level, uint32_t
|
||||
|
||||
instance->generic.data = instance->decoder.decode_data;
|
||||
instance->generic.data_count_bit = instance->decoder.decode_count_bit;
|
||||
instance->guard_time = round((float)duration / instance->te);
|
||||
|
||||
if(instance->base.callback)
|
||||
instance->base.callback(&instance->base, instance->base.context);
|
||||
@@ -323,6 +334,12 @@ SubGhzProtocolStatus subghz_protocol_decoder_princeton_serialize(
|
||||
FURI_LOG_E(TAG, "Unable to add TE");
|
||||
ret = SubGhzProtocolStatusErrorParserTe;
|
||||
}
|
||||
if((ret == SubGhzProtocolStatusOk) &&
|
||||
!flipper_format_write_uint32(flipper_format, "Guard_time", &instance->guard_time, 1)) {
|
||||
FURI_LOG_E(TAG, "Unable to add Guard_time");
|
||||
ret = SubGhzProtocolStatusErrorParserOthers;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
@@ -349,6 +366,10 @@ SubGhzProtocolStatus
|
||||
ret = SubGhzProtocolStatusErrorParserTe;
|
||||
break;
|
||||
}
|
||||
if(!flipper_format_read_uint32(
|
||||
flipper_format, "Guard_time", (uint32_t*)&instance->guard_time, 1)) {
|
||||
instance->guard_time = PRINCETON_GUARD_TIME_DEFALUT;
|
||||
}
|
||||
} while(false);
|
||||
|
||||
return ret;
|
||||
|
||||
@@ -12,3 +12,4 @@ def generate(env):
|
||||
env["LINK"] = env["CXX"]
|
||||
env["CXX_NOCACHE"] = env["CXX"]
|
||||
env["CXX"] = "$CCACHE $CXX_NOCACHE"
|
||||
env.AppendUnique(COMPILATIONDB_OMIT_BINARIES=["ccache"])
|
||||
|
||||
@@ -32,7 +32,7 @@ which is the name that most clang tools search for by default.
|
||||
import fnmatch
|
||||
import itertools
|
||||
import json
|
||||
from shlex import quote
|
||||
from shlex import join, split
|
||||
|
||||
import SCons
|
||||
from SCons.Tool.asm import ASPPSuffixes, ASSuffixes
|
||||
@@ -108,6 +108,10 @@ def make_emit_compilation_DB_entry(comstr):
|
||||
return emit_compilation_db_entry
|
||||
|
||||
|
||||
def __is_value_true(value):
|
||||
return value in [True, 1, "True", "true"]
|
||||
|
||||
|
||||
def compilation_db_entry_action(target, source, env, **kw):
|
||||
"""
|
||||
Create a dictionary with evaluated command line, target, source
|
||||
@@ -126,16 +130,19 @@ def compilation_db_entry_action(target, source, env, **kw):
|
||||
env=env["__COMPILATIONDB_ENV"],
|
||||
)
|
||||
|
||||
# We assume first non-space character is the executable
|
||||
executable = command.split(" ", 1)[0]
|
||||
if not (tool_path := _TOOL_PATH_CACHE.get(executable, None)):
|
||||
tool_path = env.WhereIs(executable) or executable
|
||||
_TOOL_PATH_CACHE[executable] = tool_path
|
||||
# If there are spaces in the executable path, we need to quote it
|
||||
if " " in tool_path:
|
||||
tool_path = quote(tool_path)
|
||||
# Replacing the executable with the full path
|
||||
command = tool_path + command[len(executable) :]
|
||||
cmdline = split(command)
|
||||
binaries_to_omit = env["COMPILATIONDB_OMIT_BINARIES"]
|
||||
while (executable := cmdline[0]) in binaries_to_omit:
|
||||
cmdline.pop(0)
|
||||
|
||||
if __is_value_true(env["COMPILATIONDB_USE_BINARY_ABSPATH"]):
|
||||
if not (tool_path := _TOOL_PATH_CACHE.get(executable, None)):
|
||||
tool_path = env.WhereIs(executable) or executable
|
||||
_TOOL_PATH_CACHE[executable] = tool_path
|
||||
# Replacing the executable with the full path
|
||||
executable = tool_path
|
||||
|
||||
command = join((executable, *cmdline[1:]))
|
||||
|
||||
entry = {
|
||||
"directory": env.Dir("#").abspath,
|
||||
@@ -150,7 +157,7 @@ def compilation_db_entry_action(target, source, env, **kw):
|
||||
def write_compilation_db(target, source, env):
|
||||
entries = []
|
||||
|
||||
use_abspath = env["COMPILATIONDB_USE_ABSPATH"] in [True, 1, "True", "true"]
|
||||
use_abspath = __is_value_true(env["COMPILATIONDB_USE_ABSPATH"])
|
||||
use_path_filter = env.subst("$COMPILATIONDB_PATH_FILTER")
|
||||
use_srcpath_filter = env.subst("$COMPILATIONDB_SRCPATH_FILTER")
|
||||
|
||||
@@ -225,6 +232,8 @@ def generate(env, **kwargs):
|
||||
COMPILATIONDB_USE_ABSPATH=False,
|
||||
COMPILATIONDB_PATH_FILTER="",
|
||||
COMPILATIONDB_SRCPATH_FILTER="",
|
||||
COMPILATIONDB_OMIT_BINARIES=[],
|
||||
COMPILATIONDB_USE_BINARY_ABSPATH=False,
|
||||
)
|
||||
|
||||
components_by_suffix = itertools.chain(
|
||||
|
||||
@@ -102,6 +102,7 @@ env = core_env.Clone(
|
||||
core_env.subst("$SDK_DEFINITION"), load_version_only=True
|
||||
).version,
|
||||
APPCHECK_COMSTR="\tAPPCHK\t${SOURCE}\n\t\tTarget: ${TARGET_HW}, API: ${UFBT_API_VERSION}",
|
||||
COMPILATIONDB_USE_BINARY_ABSPATH=True,
|
||||
)
|
||||
|
||||
wrap_tempfile(env, "LINKCOM")
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
entry,status,name,type,params
|
||||
Version,+,62.3,,
|
||||
Version,+,63.0,,
|
||||
Header,+,applications/services/bt/bt_service/bt.h,,
|
||||
Header,+,applications/services/bt/bt_service/bt_keys_storage.h,,
|
||||
Header,+,applications/services/cli/cli.h,,
|
||||
@@ -1157,7 +1157,7 @@ Function,+,furi_hal_bus_is_enabled,_Bool,FuriHalBus
|
||||
Function,+,furi_hal_bus_reset,void,FuriHalBus
|
||||
Function,+,furi_hal_ccid_ccid_insert_smartcard,void,
|
||||
Function,+,furi_hal_ccid_ccid_remove_smartcard,void,
|
||||
Function,+,furi_hal_ccid_set_callbacks,void,CcidCallbacks*
|
||||
Function,+,furi_hal_ccid_set_callbacks,void,"CcidCallbacks*, void*"
|
||||
Function,+,furi_hal_cdc_get_ctrl_line_state,uint8_t,uint8_t
|
||||
Function,+,furi_hal_cdc_get_port_settings,usb_cdc_line_coding*,uint8_t
|
||||
Function,+,furi_hal_cdc_receive,int32_t,"uint8_t, uint8_t*, uint16_t"
|
||||
|
||||
|
@@ -1,5 +1,5 @@
|
||||
entry,status,name,type,params
|
||||
Version,+,62.3,,
|
||||
Version,+,63.0,,
|
||||
Header,+,applications/drivers/subghz/cc1101_ext/cc1101_ext_interconnect.h,,
|
||||
Header,+,applications/services/bt/bt_service/bt.h,,
|
||||
Header,+,applications/services/bt/bt_service/bt_keys_storage.h,,
|
||||
@@ -1258,7 +1258,7 @@ Function,+,furi_hal_bus_is_enabled,_Bool,FuriHalBus
|
||||
Function,+,furi_hal_bus_reset,void,FuriHalBus
|
||||
Function,+,furi_hal_ccid_ccid_insert_smartcard,void,
|
||||
Function,+,furi_hal_ccid_ccid_remove_smartcard,void,
|
||||
Function,+,furi_hal_ccid_set_callbacks,void,CcidCallbacks*
|
||||
Function,+,furi_hal_ccid_set_callbacks,void,"CcidCallbacks*, void*"
|
||||
Function,+,furi_hal_cdc_get_ctrl_line_state,uint8_t,uint8_t
|
||||
Function,+,furi_hal_cdc_get_port_settings,usb_cdc_line_coding*,uint8_t
|
||||
Function,+,furi_hal_cdc_receive,int32_t,"uint8_t, uint8_t*, uint16_t"
|
||||
|
||||
|
@@ -184,6 +184,7 @@ static usbd_device* usb_dev;
|
||||
static bool connected = false;
|
||||
static bool smartcard_inserted = true;
|
||||
static CcidCallbacks* callbacks[CCID_TOTAL_SLOTS] = {NULL};
|
||||
static void* cb_ctx[CCID_TOTAL_SLOTS];
|
||||
|
||||
static void* ccid_set_string_descr(char* str) {
|
||||
furi_check(str);
|
||||
@@ -330,7 +331,9 @@ void CALLBACK_CCID_IccPowerOn(
|
||||
if(smartcard_inserted) {
|
||||
if(callbacks[CCID_SLOT_INDEX] != NULL) {
|
||||
callbacks[CCID_SLOT_INDEX]->icc_power_on_callback(
|
||||
responseDataBlock->abData, &responseDataBlock->dwLength, NULL);
|
||||
responseDataBlock->abData,
|
||||
&responseDataBlock->dwLength,
|
||||
cb_ctx[CCID_SLOT_INDEX]);
|
||||
responseDataBlock->bStatus = CCID_COMMANDSTATUS_PROCESSEDWITHOUTERROR |
|
||||
CCID_ICCSTATUS_PRESENTANDACTIVE;
|
||||
} else {
|
||||
@@ -364,7 +367,7 @@ void CALLBACK_CCID_XfrBlock(
|
||||
receivedXfrBlock->dwLength,
|
||||
responseDataBlock->abData,
|
||||
&responseDataBlock->dwLength,
|
||||
NULL);
|
||||
cb_ctx[CCID_SLOT_INDEX]);
|
||||
responseDataBlock->bStatus = CCID_COMMANDSTATUS_PROCESSEDWITHOUTERROR |
|
||||
CCID_ICCSTATUS_PRESENTANDACTIVE;
|
||||
} else {
|
||||
@@ -389,8 +392,9 @@ void furi_hal_ccid_ccid_remove_smartcard(void) {
|
||||
smartcard_inserted = false;
|
||||
}
|
||||
|
||||
void furi_hal_ccid_set_callbacks(CcidCallbacks* cb) {
|
||||
void furi_hal_ccid_set_callbacks(CcidCallbacks* cb, void* context) {
|
||||
callbacks[CCID_SLOT_INDEX] = cb;
|
||||
cb_ctx[CCID_SLOT_INDEX] = context;
|
||||
}
|
||||
|
||||
static void ccid_rx_ep_callback(usbd_device* dev, uint8_t event, uint8_t ep) {
|
||||
|
||||
@@ -78,21 +78,21 @@ static bool flipper_update_load_stage(const FuriString* work_dir, UpdateManifest
|
||||
furi_string_free(loader_img_path);
|
||||
|
||||
void* img = malloc(stat.fsize);
|
||||
uint32_t bytes_read = 0;
|
||||
uint32_t read_total = 0;
|
||||
uint16_t read_current = 0;
|
||||
const uint16_t MAX_READ = 0xFFFF;
|
||||
|
||||
uint32_t crc = 0;
|
||||
do {
|
||||
uint16_t size_read = 0;
|
||||
if(f_read(&file, img + bytes_read, MAX_READ, &size_read) != FR_OK) { //-V769
|
||||
if(f_read(&file, img + read_total, MAX_READ, &read_current) != FR_OK) { //-V769
|
||||
break;
|
||||
}
|
||||
crc = crc32_calc_buffer(crc, img + bytes_read, size_read);
|
||||
bytes_read += size_read;
|
||||
} while(bytes_read == MAX_READ);
|
||||
crc = crc32_calc_buffer(crc, img + read_total, read_current);
|
||||
read_total += read_current;
|
||||
} while(read_current == MAX_READ);
|
||||
|
||||
do {
|
||||
if((bytes_read != stat.fsize) || (crc != manifest->staged_loader_crc)) {
|
||||
if((read_total != stat.fsize) || (crc != manifest->staged_loader_crc)) {
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
@@ -19,14 +19,14 @@ typedef struct {
|
||||
typedef struct {
|
||||
void (*icc_power_on_callback)(uint8_t* dataBlock, uint32_t* dataBlockLen, void* context);
|
||||
void (*xfr_datablock_callback)(
|
||||
const uint8_t* dataBlock,
|
||||
uint32_t dataBlockLen,
|
||||
uint8_t* responseDataBlock,
|
||||
uint32_t* responseDataBlockLen,
|
||||
const uint8_t* pcToReaderDataBlock,
|
||||
uint32_t pcToReaderDataBlockLen,
|
||||
uint8_t* readerToPcDataBlock,
|
||||
uint32_t* readerToPcDataBlockLen,
|
||||
void* context);
|
||||
} CcidCallbacks;
|
||||
|
||||
void furi_hal_ccid_set_callbacks(CcidCallbacks* cb);
|
||||
void furi_hal_ccid_set_callbacks(CcidCallbacks* cb, void* context);
|
||||
|
||||
void furi_hal_ccid_ccid_insert_smartcard(void);
|
||||
void furi_hal_ccid_ccid_remove_smartcard(void);
|
||||
|
||||
Reference in New Issue
Block a user