From 5a380eb2d32435ff557864167eb88fe9617d8bf2 Mon Sep 17 00:00:00 2001 From: RogueMaster Date: Sun, 16 Oct 2022 14:53:08 -0400 Subject: [PATCH] dtmf upd --- .../plugins/blackjack/application.fam | 2 +- applications/plugins/dtmf_dolphin/README.md | 7 + .../plugins/dtmf_dolphin/application.fam | 5 +- .../plugins/dtmf_dolphin/dtmf_10px.png | Bin 1715 -> 0 bytes .../plugins/dtmf_dolphin/dtmf_dolphin.c | 9 +- .../plugins/dtmf_dolphin/dtmf_dolphin_audio.c | 53 ++++---- .../plugins/dtmf_dolphin/dtmf_dolphin_audio.h | 10 +- .../plugins/dtmf_dolphin/dtmf_dolphin_data.c | 93 +++++++------ .../plugins/dtmf_dolphin/dtmf_dolphin_data.h | 2 +- .../plugins/dtmf_dolphin/dtmf_dolphin_i.h | 6 +- applications/plugins/dtmf_dolphin/phone.png | Bin 0 -> 306 bytes .../scenes/dtmf_dolphin_scene_dialer.c | 8 +- .../scenes/dtmf_dolphin_scene_start.c | 49 ++++--- .../dtmf_dolphin/views/dtmf_dolphin_common.h | 2 +- .../dtmf_dolphin/views/dtmf_dolphin_dialer.c | 122 +++++++++--------- .../dtmf_dolphin/views/dtmf_dolphin_dialer.h | 5 +- 16 files changed, 201 insertions(+), 172 deletions(-) delete mode 100644 applications/plugins/dtmf_dolphin/dtmf_10px.png create mode 100644 applications/plugins/dtmf_dolphin/phone.png diff --git a/applications/plugins/blackjack/application.fam b/applications/plugins/blackjack/application.fam index 8f14015aa..2088e50a7 100644 --- a/applications/plugins/blackjack/application.fam +++ b/applications/plugins/blackjack/application.fam @@ -1,5 +1,5 @@ App( - appid="blackjack", + appid="Blackjack", name="Blackjack", apptype=FlipperAppType.EXTERNAL, entry_point="blackjack_app", diff --git a/applications/plugins/dtmf_dolphin/README.md b/applications/plugins/dtmf_dolphin/README.md index 68d123616..60f513573 100644 --- a/applications/plugins/dtmf_dolphin/README.md +++ b/applications/plugins/dtmf_dolphin/README.md @@ -7,3 +7,10 @@ DTMF (Dual-Tone Multi-Frequency) dialer, Bluebox, and future Redbox. Now in a release-ready state for both Dialer and Bluebox functionality. Redbox functionality awaits some changes for modulation. Please note that using the current tone output method, the 2600 tone is scaled about 33 Hz higher than it should be. This is a limitation of the current sample rate. + +### Educational Links: + +* http://www.phrack.org/issues/25/7.html#article +* https://en.wikipedia.org/wiki/Dual-tone_multi-frequency_signaling +* https://en.wikipedia.org/wiki/Blue_box +* https://en.wikipedia.org/wiki/Red_box_(phreaking) diff --git a/applications/plugins/dtmf_dolphin/application.fam b/applications/plugins/dtmf_dolphin/application.fam index 90f01ef87..98fbe7363 100644 --- a/applications/plugins/dtmf_dolphin/application.fam +++ b/applications/plugins/dtmf_dolphin/application.fam @@ -5,11 +5,12 @@ App( entry_point="dtmf_dolphin_app", cdefines=["DTMF_DOLPHIN"], requires=[ + "storage", "gui", "dialogs", ], + fap_icon="phone.png", stack_size=8 * 1024, order=20, - fap_icon="dtmf_10px.png", - fap_category="Misc", + fap_category="Tools", ) diff --git a/applications/plugins/dtmf_dolphin/dtmf_10px.png b/applications/plugins/dtmf_dolphin/dtmf_10px.png deleted file mode 100644 index 2ca0be4ffcab5e64119ee735cd697688cf9ebe7f..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1715 zcmcIlOK;;;6n23@keNyd!DxhL#Fb|Q0^8Tm#8ym|X-X4mT&gyxo!wmDd!1N~eU0rl zX%{Tmu^Pm0nAI#sVhal%KY$HuB*YF0i3MAvavUcii&C<|QhXoz&UfC&pYQMOZZ_U( zNRqVK?{yDgt@e#qUWE78zi&N(WurLQeIPym@$PSMcxl)PI+FC&lbe5$8*qMk|KVWg z^70b4AOG;vr?9-5^&SNL0c^$kl0*0a}vUTholt z6JDZ_598FA|M=!x8O6+(kL&;k*)|`=y^EY5UhEC%#R+wpy!F9mqdoP2A>k!K(`1|$ z-qe?8#2)OcYfVNoNO|JRok}A*4))Qu$T@1NhC(sMsOhSD=-8y`zK;xS7#emo-Bk3Z zXE~m3q4^_&K7`sii@byGhjV>!^5s!kW}c=^CKGjHsv;k1y6d_cHZ;Rf0HGA;X-TF^ zTHLQm<}_Vi&^*q{Sfr?;C80PieHl!yeMzz{Uul-!rA>?zn)bbFv< z&$K+V^&U1ojB98B1;I#3)&mO`N9XH6gTU*jMM+Z1`(0lKqtrNNo^G3lgAEKtMh&H9 zS&`z>R!hMSrr2x|SLe~pE|BjEdRm3AlCSHR2?`v`2zjn;IR80?m8*FR zjAJybM~~2|4Sbna`R7cYU&mJjc0Ctr+R2Cm={0px!wM0V6O!}J5R&lUb*HW2NI}l7 zcVoT!_&?pKx#@_cLk^P`+IH2kwpPug)vUF(s}fw}R%Tf}CuhX6=wW= diff --git a/applications/plugins/dtmf_dolphin/dtmf_dolphin.c b/applications/plugins/dtmf_dolphin/dtmf_dolphin.c index 2ff8ce0ba..94d78bc49 100644 --- a/applications/plugins/dtmf_dolphin/dtmf_dolphin.c +++ b/applications/plugins/dtmf_dolphin/dtmf_dolphin.c @@ -67,15 +67,10 @@ static void app_free(DTMFDolphinApp* app) { variable_item_list_free(app->main_menu_list); dtmf_dolphin_dialer_free(app->dtmf_dolphin_dialer); - // widget_free(app->dtmf_dolphin_play); view_dispatcher_free(app->view_dispatcher); scene_manager_free(app->scene_manager); - // button_panel_free(app->dialer_button_panel); - // button_panel_free(app->bluebox_button_panel); - // button_panel_free(app->redbox_button_panel); - notification_message(app->notification, &sequence_display_backlight_enforce_auto); furi_record_close(RECORD_GUI); @@ -83,10 +78,10 @@ static void app_free(DTMFDolphinApp* app) { free(app); } -int32_t dtmf_dolphin_app(void* p) { +int32_t dtmf_dolphin_app(void *p) { UNUSED(p); DTMFDolphinApp* app = app_alloc(); - + view_dispatcher_run(app->view_dispatcher); app_free(app); diff --git a/applications/plugins/dtmf_dolphin/dtmf_dolphin_audio.c b/applications/plugins/dtmf_dolphin/dtmf_dolphin_audio.c index e7778b328..6d6341bf1 100644 --- a/applications/plugins/dtmf_dolphin/dtmf_dolphin_audio.c +++ b/applications/plugins/dtmf_dolphin/dtmf_dolphin_audio.c @@ -1,11 +1,11 @@ #include "dtmf_dolphin_audio.h" -DTMFDolphinAudio* current_player; +DTMFDolphinAudio *current_player; static void dtmf_dolphin_audio_dma_isr(void* ctx) { - FuriMessageQueue* event_queue = ctx; + FuriMessageQueue *event_queue = ctx; - if(LL_DMA_IsActiveFlag_HT1(DMA1)) { + if (LL_DMA_IsActiveFlag_HT1(DMA1)) { LL_DMA_ClearFlag_HT1(DMA1); DTMFDolphinCustomEvent event = {.type = DTMFDolphinEventDMAHalfTransfer}; @@ -21,13 +21,13 @@ static void dtmf_dolphin_audio_dma_isr(void* ctx) { } void dtmf_dolphin_audio_clear_samples(DTMFDolphinAudio* player) { - for(size_t i = 0; i < player->buffer_length; i++) { + for (size_t i = 0; i < player->buffer_length; i++) { player->sample_buffer[i] = 0; } } DTMFDolphinOsc* dtmf_dolphin_osc_alloc() { - DTMFDolphinOsc* osc = malloc(sizeof(DTMFDolphinOsc)); + DTMFDolphinOsc *osc = malloc(sizeof(DTMFDolphinOsc)); osc->cached_freq = 0; osc->offset = 0; osc->period = 0; @@ -36,7 +36,7 @@ DTMFDolphinOsc* dtmf_dolphin_osc_alloc() { } DTMFDolphinAudio* dtmf_dolphin_audio_alloc() { - DTMFDolphinAudio* player = malloc(sizeof(DTMFDolphinAudio)); + DTMFDolphinAudio *player = malloc(sizeof(DTMFDolphinAudio)); player->buffer_length = SAMPLE_BUFFER_LENGTH; player->half_buffer_length = SAMPLE_BUFFER_LENGTH / 2; player->sample_buffer = malloc(sizeof(uint16_t) * player->buffer_length); @@ -50,32 +50,34 @@ DTMFDolphinAudio* dtmf_dolphin_audio_alloc() { } size_t calc_waveform_period(float freq) { - if(!freq) { + if (!freq) { return 0; } // DMA Rate calculation, thanks to Dr_Zlo - float dma_rate = CPU_CLOCK_FREQ / 2 / DTMF_DOLPHIN_HAL_DMA_PRESCALER / - (DTMF_DOLPHIN_HAL_DMA_AUTORELOAD + 1); + float dma_rate = CPU_CLOCK_FREQ \ + / 2 \ + / DTMF_DOLPHIN_HAL_DMA_PRESCALER \ + / (DTMF_DOLPHIN_HAL_DMA_AUTORELOAD + 1); // Using a constant scaling modifier, which likely represents // the combined system overhead and isr latency. - return (uint16_t)dma_rate * 2 / freq * 0.801923; + return (uint16_t) dma_rate * 2 / freq * 0.801923; } void osc_generate_lookup_table(DTMFDolphinOsc* osc, float freq) { - if(osc->lookup_table != NULL) { + if (osc->lookup_table != NULL) { free(osc->lookup_table); } osc->offset = 0; osc->cached_freq = freq; osc->period = calc_waveform_period(freq); - if(!osc->period) { + if (!osc->period) { osc->lookup_table = NULL; return; } osc->lookup_table = malloc(sizeof(float) * osc->period); - for(size_t i = 0; i < osc->period; i++) { + for (size_t i = 0; i < osc->period; i++) { osc->lookup_table[i] = sin(i * PERIOD_2_PI / osc->period) + 1; } } @@ -83,7 +85,7 @@ void osc_generate_lookup_table(DTMFDolphinOsc* osc, float freq) { float sample_frame(DTMFDolphinOsc* osc) { float frame = 0.0; - if(osc->period) { + if (osc->period) { frame = osc->lookup_table[osc->offset]; osc->offset = (osc->offset + 1) % osc->period; } @@ -101,7 +103,7 @@ void dtmf_dolphin_audio_free(DTMFDolphinAudio* player) { } void dtmf_dolphin_osc_free(DTMFDolphinOsc* osc) { - if(osc->lookup_table != NULL) { + if (osc->lookup_table != NULL) { free(osc->lookup_table); } free(osc); @@ -110,16 +112,18 @@ void dtmf_dolphin_osc_free(DTMFDolphinOsc* osc) { bool generate_waveform(DTMFDolphinAudio* player, uint16_t buffer_index) { uint16_t* sample_buffer_start = &player->sample_buffer[buffer_index]; - for(size_t i = 0; i < player->half_buffer_length; i++) { + for (size_t i = 0; i < player->half_buffer_length; i++) { float data = 0; - if(player->osc2->period) { - data = (sample_frame(player->osc1) / 2) + (sample_frame(player->osc2) / 2); + if (player->osc2->period) { + data = \ + (sample_frame(player->osc1) / 2) + \ + (sample_frame(player->osc2) / 2); } else { data = (sample_frame(player->osc1)); } data *= player->volume; - data *= UINT8_MAX / 2; // scale -128..127 - data += UINT8_MAX / 2; // to unsigned + data *= UINT8_MAX / 2; // scale -128..127 + data += UINT8_MAX / 2; // to unsigned if(data < 0) { data = 0; @@ -147,8 +151,7 @@ bool dtmf_dolphin_audio_play_tones(float freq1, float freq2) { dtmf_dolphin_speaker_init(); dtmf_dolphin_dma_init((uint32_t)current_player->sample_buffer, current_player->buffer_length); - furi_hal_interrupt_set_isr( - FuriHalInterruptIdDma1Ch1, dtmf_dolphin_audio_dma_isr, current_player->queue); + furi_hal_interrupt_set_isr(FuriHalInterruptIdDma1Ch1, dtmf_dolphin_audio_dma_isr, current_player->queue); dtmf_dolphin_dma_start(); dtmf_dolphin_speaker_start(); @@ -162,20 +165,20 @@ bool dtmf_dolphin_audio_stop_tones() { furi_hal_interrupt_set_isr(FuriHalInterruptIdDma1Ch1, NULL, NULL); dtmf_dolphin_audio_free(current_player); - + return true; } bool dtmf_dolphin_audio_handle_tick() { bool handled = false; - if(current_player) { + if (current_player) { DTMFDolphinCustomEvent event; if(furi_message_queue_get(current_player->queue, &event, 250) == FuriStatusOk) { if(event.type == DTMFDolphinEventDMAHalfTransfer) { generate_waveform(current_player, 0); handled = true; - } else if(event.type == DTMFDolphinEventDMAFullTransfer) { + } else if (event.type == DTMFDolphinEventDMAFullTransfer) { generate_waveform(current_player, current_player->half_buffer_length); handled = true; } diff --git a/applications/plugins/dtmf_dolphin/dtmf_dolphin_audio.h b/applications/plugins/dtmf_dolphin/dtmf_dolphin_audio.h index 3c6cc4904..071323a6c 100644 --- a/applications/plugins/dtmf_dolphin/dtmf_dolphin_audio.h +++ b/applications/plugins/dtmf_dolphin/dtmf_dolphin_audio.h @@ -17,12 +17,12 @@ typedef struct { typedef struct { size_t buffer_length; size_t half_buffer_length; - uint8_t* buffer_buffer; - uint16_t* sample_buffer; + uint8_t *buffer_buffer; + uint16_t *sample_buffer; float volume; - FuriMessageQueue* queue; - DTMFDolphinOsc* osc1; - DTMFDolphinOsc* osc2; + FuriMessageQueue *queue; + DTMFDolphinOsc *osc1; + DTMFDolphinOsc *osc2; } DTMFDolphinAudio; DTMFDolphinOsc* dtmf_dolphin_osc_alloc(); diff --git a/applications/plugins/dtmf_dolphin/dtmf_dolphin_data.c b/applications/plugins/dtmf_dolphin/dtmf_dolphin_data.c index a99c13baa..d0a85800c 100644 --- a/applications/plugins/dtmf_dolphin/dtmf_dolphin_data.c +++ b/applications/plugins/dtmf_dolphin/dtmf_dolphin_data.c @@ -7,13 +7,13 @@ typedef struct { } DTMFDolphinTonePos; typedef struct { - const char* name; + const char *name; const float frequency_1; const float frequency_2; const DTMFDolphinTonePos pos; - const uint16_t pulses; // for Redbox - const uint16_t pulse_ms; // for Redbox - const uint16_t gap_duration; // for Redbox + const uint16_t pulses; // for Redbox + const uint16_t pulse_ms; // for Redbox + const uint16_t gap_duration; // for Redbox } DTMFDolphinTones; typedef struct { @@ -44,38 +44,41 @@ DTMFDolphinSceneData DTMFDolphinSceneDataDialer = { {"0", 941.0, 1336.0, {3, 1, 1}, 0, 0, 0}, {"#", 941.0, 1477.0, {3, 2, 1}, 0, 0, 0}, {"D", 941.0, 1633.0, {3, 3, 1}, 0, 0, 0}, - }}; + } +}; DTMFDolphinSceneData DTMFDolphinSceneDataBluebox = { .name = "Bluebox", .block = DTMF_DOLPHIN_TONE_BLOCK_BLUEBOX, .tone_count = 13, .tones = { - {"1", 700.0, 900.0, {0, 0, 1}, 0, 0, 0}, - {"2", 700.0, 1100.0, {0, 1, 1}, 0, 0, 0}, - {"3", 900.0, 1100.0, {0, 2, 1}, 0, 0, 0}, - {"4", 700.0, 1300.0, {1, 0, 1}, 0, 0, 0}, - {"5", 900.0, 1300.0, {1, 1, 1}, 0, 0, 0}, - {"6", 1100.0, 1300.0, {1, 2, 1}, 0, 0, 0}, - {"7", 700.0, 1500.0, {2, 0, 1}, 0, 0, 0}, - {"8", 900.0, 1500.0, {2, 1, 1}, 0, 0, 0}, - {"9", 1100.0, 1500.0, {2, 2, 1}, 0, 0, 0}, - {"0", 1300.0, 1500.0, {3, 1, 1}, 0, 0, 0}, - {"KP", 1100.0, 1700.0, {0, 3, 2}, 0, 0, 0}, - {"ST", 1500.0, 1700.0, {1, 3, 2}, 0, 0, 0}, - {"2600", 2600.0, 0.0, {3, 2, 3}, 0, 0, 0}, - }}; + {"1", 700.0, 900.0, {0, 0, 1}, 0, 0, 0}, + {"2", 700.0, 1100.0, {0, 1, 1}, 0, 0, 0}, + {"3", 900.0, 1100.0, {0, 2, 1}, 0, 0, 0}, + {"4", 700.0, 1300.0, {1, 0, 1}, 0, 0, 0}, + {"5", 900.0, 1300.0, {1, 1, 1}, 0, 0, 0}, + {"6", 1100.0, 1300.0, {1, 2, 1}, 0, 0, 0}, + {"7", 700.0, 1500.0, {2, 0, 1}, 0, 0, 0}, + {"8", 900.0, 1500.0, {2, 1, 1}, 0, 0, 0}, + {"9", 1100.0, 1500.0, {2, 2, 1}, 0, 0, 0}, + {"0", 1300.0, 1500.0, {3, 1, 1}, 0, 0, 0}, + {"KP", 1100.0, 1700.0, {0, 3, 2}, 0, 0, 0}, + {"ST", 1500.0, 1700.0, {1, 3, 2}, 0, 0, 0}, + {"2600", 2600.0, 0.0, {3, 2, 3}, 0, 0, 0}, + } +}; DTMFDolphinSceneData DTMFDolphinSceneDataRedboxUS = { .name = "Redbox (US)", .block = DTMF_DOLPHIN_TONE_BLOCK_REDBOX_US, .tone_count = 4, .tones = { - {"Nickel", 1700.0, 2200.0, {0, 0, 5}, 1, 66, 0}, - {"Dime", 1700.0, 2200.0, {1, 0, 5}, 2, 66, 66}, + {"Nickel", 1700.0, 2200.0, {0, 0, 5}, 1, 66, 0}, + {"Dime", 1700.0, 2200.0, {1, 0, 5}, 2, 66, 66}, {"Quarter", 1700.0, 2200.0, {2, 0, 5}, 5, 33, 33}, - {"Dollar", 1700.0, 2200.0, {3, 0, 5}, 1, 650, 0}, - }}; + {"Dollar", 1700.0, 2200.0, {3, 0, 5}, 1, 650, 0}, + } +}; DTMFDolphinSceneData DTMFDolphinSceneDataRedboxUK = { .name = "Redbox (UK)", @@ -84,25 +87,28 @@ DTMFDolphinSceneData DTMFDolphinSceneDataRedboxUK = { .tones = { {"10p", 1000.0, 0.0, {0, 0, 3}, 1, 200, 0}, {"50p", 1000.0, 0.0, {1, 0, 3}, 1, 350, 0}, - }}; + } +}; DTMFDolphinSceneData DTMFDolphinSceneDataMisc = { .name = "Misc", .block = DTMF_DOLPHIN_TONE_BLOCK_MISC, .tone_count = 3, .tones = { - {"CCITT 11", 700.0, 1700.0, {0, 0, 5}, 0, 0, 0}, - {"CCITT 12", 900.0, 1700.0, {1, 0, 5}, 0, 0, 0}, + {"CCITT 11", 700.0, 1700.0, {0, 0, 5}, 0, 0, 0}, + {"CCITT 12", 900.0, 1700.0, {1, 0, 5}, 0, 0, 0}, {"CCITT KP2", 1300.0, 1700.0, {2, 0, 5}, 0, 0, 0}, - }}; + } +}; DTMFDolphinToneSection current_section; -DTMFDolphinSceneData* current_scene_data; +DTMFDolphinSceneData *current_scene_data; void dtmf_dolphin_data_set_current_section(DTMFDolphinToneSection section) { current_section = section; - switch(current_section) { + switch (current_section) + { case DTMF_DOLPHIN_TONE_BLOCK_BLUEBOX: current_scene_data = &DTMFDolphinSceneDataBluebox; break; @@ -125,14 +131,14 @@ DTMFDolphinToneSection dtmf_dolphin_data_get_current_section() { return current_section; } -DTMFDolphinSceneData* dtmf_dolphin_data_get_current_scene_data() { +DTMFDolphinSceneData *dtmf_dolphin_data_get_current_scene_data() { return current_scene_data; } -bool dtmf_dolphin_data_get_tone_frequencies(float* freq1, float* freq2, uint8_t row, uint8_t col) { - for(size_t i = 0; i < current_scene_data->tone_count; i++) { +bool dtmf_dolphin_data_get_tone_frequencies(float *freq1, float *freq2, uint8_t row, uint8_t col) { + for (size_t i = 0; i < current_scene_data->tone_count; i++) { DTMFDolphinTones tones = current_scene_data->tones[i]; - if(tones.pos.row == row && tones.pos.col == col) { + if (tones.pos.row == row && tones.pos.col == col) { freq1[0] = tones.frequency_1; freq2[0] = tones.frequency_2; return true; @@ -142,9 +148,9 @@ bool dtmf_dolphin_data_get_tone_frequencies(float* freq1, float* freq2, uint8_t } const char* dtmf_dolphin_data_get_tone_name(uint8_t row, uint8_t col) { - for(size_t i = 0; i < current_scene_data->tone_count; i++) { + for (size_t i = 0; i < current_scene_data->tone_count; i++) { DTMFDolphinTones tones = current_scene_data->tones[i]; - if(tones.pos.row == row && tones.pos.col == col) { + if (tones.pos.row == row && tones.pos.col == col) { return tones.name; } } @@ -152,7 +158,7 @@ const char* dtmf_dolphin_data_get_tone_name(uint8_t row, uint8_t col) { } const char* dtmf_dolphin_data_get_current_section_name() { - if(current_scene_data) { + if (current_scene_data) { return current_scene_data->name; } return NULL; @@ -162,26 +168,27 @@ void dtmf_dolphin_tone_get_max_pos(uint8_t* max_rows, uint8_t* max_cols, uint8_t max_rows[0] = 0; max_cols[0] = 0; max_span[0] = 0; - uint8_t tmp_rowspan[5] = {0, 0, 0, 0, 0}; - for(size_t i = 0; i < current_scene_data->tone_count; i++) { + uint8_t tmp_rowspan[5] = { 0, 0, 0, 0, 0 }; + for (size_t i = 0; i < current_scene_data->tone_count; i++) { DTMFDolphinTones tones = current_scene_data->tones[i]; - if(tones.pos.row > max_rows[0]) { + if (tones.pos.row > max_rows[0]) { max_rows[0] = tones.pos.row; } - if(tones.pos.col > max_cols[0]) { + if (tones.pos.col > max_cols[0]) { max_cols[0] = tones.pos.col; } tmp_rowspan[tones.pos.row] += tones.pos.span; - if(tmp_rowspan[tones.pos.row] > max_span[0]) max_span[0] = tmp_rowspan[tones.pos.row]; + if (tmp_rowspan[tones.pos.row] > max_span[0]) + max_span[0] = tmp_rowspan[tones.pos.row]; } max_rows[0]++; max_cols[0]++; } uint8_t dtmf_dolphin_get_tone_span(uint8_t row, uint8_t col) { - for(size_t i = 0; i < current_scene_data->tone_count; i++) { + for (size_t i = 0; i < current_scene_data->tone_count; i++) { DTMFDolphinTones tones = current_scene_data->tones[i]; - if(tones.pos.row == row && tones.pos.col == col) { + if (tones.pos.row == row && tones.pos.col == col) { return tones.pos.span; } } diff --git a/applications/plugins/dtmf_dolphin/dtmf_dolphin_data.h b/applications/plugins/dtmf_dolphin/dtmf_dolphin_data.h index 056fb223e..65fb9c75e 100644 --- a/applications/plugins/dtmf_dolphin/dtmf_dolphin_data.h +++ b/applications/plugins/dtmf_dolphin/dtmf_dolphin_data.h @@ -17,7 +17,7 @@ void dtmf_dolphin_data_set_current_section(DTMFDolphinToneSection section); DTMFDolphinToneSection dtmf_dolphin_data_get_current_section(); -bool dtmf_dolphin_data_get_tone_frequencies(float* freq1, float* freq2, uint8_t row, uint8_t col); +bool dtmf_dolphin_data_get_tone_frequencies(float *freq1, float *freq2, uint8_t row, uint8_t col); const char* dtmf_dolphin_data_get_tone_name(uint8_t row, uint8_t col); diff --git a/applications/plugins/dtmf_dolphin/dtmf_dolphin_i.h b/applications/plugins/dtmf_dolphin/dtmf_dolphin_i.h index abdabd2b3..2a0de1b41 100644 --- a/applications/plugins/dtmf_dolphin/dtmf_dolphin_i.h +++ b/applications/plugins/dtmf_dolphin/dtmf_dolphin_i.h @@ -17,6 +17,7 @@ #define TAG "DTMFDolphin" + enum DTMFDolphinSceneState { DTMFDolphinSceneStateDialer, DTMFDolphinSceneStateBluebox, @@ -38,4 +39,7 @@ typedef struct { NotificationApp* notification; } DTMFDolphinApp; -typedef enum { DTMFDolphinViewMainMenu, DTMFDolphinViewDialer } DTMFDolphinView; +typedef enum { + DTMFDolphinViewMainMenu, + DTMFDolphinViewDialer +} DTMFDolphinView; diff --git a/applications/plugins/dtmf_dolphin/phone.png b/applications/plugins/dtmf_dolphin/phone.png new file mode 100644 index 0000000000000000000000000000000000000000..443f847c3cd72b263c4d8623101af5acd4d77439 GIT binary patch literal 306 zcmex=8Ac{%7FISvA$DN~4iQmBB~Ed}|F;-8fUaY(XGouZ zBf~@1e5J|3&)YmgL!L~TeDjMMUzhGd<;|fRWzCJ-RyAxjN^^T|$l$=2EUj{mQ=4m( zRoB#2OP30+`cfM*&o1&H-&RM~9SN344yc_Ibxtw=JgJNKKZ9T5H<5qtNlE+Gw9S3n jvwM5Bscene_manager, scene_id); - switch(state) { + switch (state) + { case DTMFDolphinSceneStateBluebox: dtmf_dolphin_data_set_current_section(DTMF_DOLPHIN_TONE_BLOCK_BLUEBOX); - break; + break; case DTMFDolphinSceneStateRedboxUS: dtmf_dolphin_data_set_current_section(DTMF_DOLPHIN_TONE_BLOCK_REDBOX_US); break; diff --git a/applications/plugins/dtmf_dolphin/scenes/dtmf_dolphin_scene_start.c b/applications/plugins/dtmf_dolphin/scenes/dtmf_dolphin_scene_start.c index 1afd117fd..8bd53440d 100644 --- a/applications/plugins/dtmf_dolphin/scenes/dtmf_dolphin_scene_start.c +++ b/applications/plugins/dtmf_dolphin/scenes/dtmf_dolphin_scene_start.c @@ -2,11 +2,26 @@ static void dtmf_dolphin_scene_start_main_menu_enter_callback(void* context, uint32_t index) { DTMFDolphinApp* app = context; - if(index == DTMFDolphinSceneStateDialer) { - view_dispatcher_send_custom_event(app->view_dispatcher, DTMFDolphinEventStartDialer); - } else if(index == DTMFDolphinSceneStateBluebox) { - view_dispatcher_send_custom_event(app->view_dispatcher, DTMFDolphinEventStartBluebox); + uint8_t cust_event = 255; + switch (index) + { + case 0: + cust_event = DTMFDolphinEventStartDialer; + break; + case 1: + cust_event = DTMFDolphinEventStartBluebox; + break; + case 2: + cust_event = DTMFDolphinEventStartMisc; + break; + default: + return; } + + view_dispatcher_send_custom_event( + app->view_dispatcher, + cust_event + ); } void dtmf_dolphin_scene_start_on_enter(void* context) { @@ -15,16 +30,21 @@ void dtmf_dolphin_scene_start_on_enter(void* context) { // VariableItem* item; variable_item_list_set_enter_callback( - var_item_list, dtmf_dolphin_scene_start_main_menu_enter_callback, app); + var_item_list, + dtmf_dolphin_scene_start_main_menu_enter_callback, + app); variable_item_list_add(var_item_list, "Dialer", 0, NULL, NULL); variable_item_list_add(var_item_list, "Bluebox", 0, NULL, NULL); variable_item_list_add(var_item_list, "Misc", 0, NULL, NULL); variable_item_list_set_selected_item( - var_item_list, scene_manager_get_scene_state(app->scene_manager, DTMFDolphinSceneStart)); + var_item_list, + scene_manager_get_scene_state(app->scene_manager, DTMFDolphinSceneStart)); - view_dispatcher_switch_to_view(app->view_dispatcher, DTMFDolphinViewMainMenu); + view_dispatcher_switch_to_view( + app->view_dispatcher, + DTMFDolphinViewMainMenu); } bool dtmf_dolphin_scene_start_on_event(void* context, SceneManagerEvent event) { @@ -33,17 +53,14 @@ bool dtmf_dolphin_scene_start_on_event(void* context, SceneManagerEvent event) { bool consumed = false; if(event.type == SceneManagerEventTypeCustom) { - if(event.event == DTMFDolphinEventStartDialer) { - scene_manager_set_scene_state( - app->scene_manager, DTMFDolphinSceneDialer, DTMFDolphinSceneStateDialer); + if (event.event == DTMFDolphinEventStartDialer) { + scene_manager_set_scene_state(app->scene_manager, DTMFDolphinSceneDialer, DTMFDolphinSceneStateDialer); scene_manager_next_scene(app->scene_manager, DTMFDolphinSceneDialer); - } else if(event.event == DTMFDolphinEventStartBluebox) { - scene_manager_set_scene_state( - app->scene_manager, DTMFDolphinSceneDialer, DTMFDolphinSceneStateBluebox); + } else if (event.event == DTMFDolphinEventStartBluebox) { + scene_manager_set_scene_state(app->scene_manager, DTMFDolphinSceneDialer, DTMFDolphinSceneStateBluebox); scene_manager_next_scene(app->scene_manager, DTMFDolphinSceneDialer); - } else if(event.event == DTMFDolphinEventStartMisc) { - scene_manager_set_scene_state( - app->scene_manager, DTMFDolphinSceneDialer, DTMFDolphinSceneStateMisc); + } else if (event.event == DTMFDolphinEventStartMisc) { + scene_manager_set_scene_state(app->scene_manager, DTMFDolphinSceneDialer, DTMFDolphinSceneStateMisc); scene_manager_next_scene(app->scene_manager, DTMFDolphinSceneDialer); } consumed = true; diff --git a/applications/plugins/dtmf_dolphin/views/dtmf_dolphin_common.h b/applications/plugins/dtmf_dolphin/views/dtmf_dolphin_common.h index f2f4838d6..855978d2c 100644 --- a/applications/plugins/dtmf_dolphin/views/dtmf_dolphin_common.h +++ b/applications/plugins/dtmf_dolphin/views/dtmf_dolphin_common.h @@ -7,4 +7,4 @@ #define DTMF_DOLPHIN_NUMPAD_Y 14 #define DTMF_DOLPHIN_BUTTON_WIDTH 13 #define DTMF_DOLPHIN_BUTTON_HEIGHT 13 -#define DTMF_DOLPHIN_BUTTON_PADDING 1 // all sides +#define DTMF_DOLPHIN_BUTTON_PADDING 1 // all sides diff --git a/applications/plugins/dtmf_dolphin/views/dtmf_dolphin_dialer.c b/applications/plugins/dtmf_dolphin/views/dtmf_dolphin_dialer.c index 15f0a8303..96d9e465a 100644 --- a/applications/plugins/dtmf_dolphin/views/dtmf_dolphin_dialer.c +++ b/applications/plugins/dtmf_dolphin/views/dtmf_dolphin_dialer.c @@ -21,55 +21,53 @@ static bool dtmf_dolphin_dialer_process_up(DTMFDolphinDialer* dtmf_dolphin_diale static bool dtmf_dolphin_dialer_process_down(DTMFDolphinDialer* dtmf_dolphin_dialer); static bool dtmf_dolphin_dialer_process_left(DTMFDolphinDialer* dtmf_dolphin_dialer); static bool dtmf_dolphin_dialer_process_right(DTMFDolphinDialer* dtmf_dolphin_dialer); -static bool - dtmf_dolphin_dialer_process_ok(DTMFDolphinDialer* dtmf_dolphin_dialer, InputEvent* event); +static bool dtmf_dolphin_dialer_process_ok(DTMFDolphinDialer* dtmf_dolphin_dialer, InputEvent* event); void draw_button(Canvas* canvas, uint8_t row, uint8_t col, bool invert) { - uint8_t left = DTMF_DOLPHIN_NUMPAD_X + // ((col + 1) * DTMF_DOLPHIN_BUTTON_PADDING) + - (col * DTMF_DOLPHIN_BUTTON_WIDTH); - // (col * DTMF_DOLPHIN_BUTTON_PADDING); - uint8_t top = DTMF_DOLPHIN_NUMPAD_Y + // ((row + 1) * DTMF_DOLPHIN_BUTTON_PADDING) + - (row * DTMF_DOLPHIN_BUTTON_HEIGHT); - // (row * DTMF_DOLPHIN_BUTTON_PADDING); + + uint8_t left = DTMF_DOLPHIN_NUMPAD_X + \ + // ((col + 1) * DTMF_DOLPHIN_BUTTON_PADDING) + + (col * DTMF_DOLPHIN_BUTTON_WIDTH); + // (col * DTMF_DOLPHIN_BUTTON_PADDING); + uint8_t top = DTMF_DOLPHIN_NUMPAD_Y + \ + // ((row + 1) * DTMF_DOLPHIN_BUTTON_PADDING) + + (row * DTMF_DOLPHIN_BUTTON_HEIGHT); + // (row * DTMF_DOLPHIN_BUTTON_PADDING); uint8_t span = dtmf_dolphin_get_tone_span(row, col); - if(span == 0) { + if (span == 0) { return; } canvas_set_color(canvas, ColorBlack); - - if(invert) - canvas_draw_rbox( - canvas, - left, - top, + + if (invert) + canvas_draw_rbox(canvas, left, top, (DTMF_DOLPHIN_BUTTON_WIDTH * span) - (DTMF_DOLPHIN_BUTTON_PADDING * 2), DTMF_DOLPHIN_BUTTON_HEIGHT - (DTMF_DOLPHIN_BUTTON_PADDING * 2), 2); else - canvas_draw_rframe( - canvas, - left, - top, + canvas_draw_rframe(canvas, left, top, (DTMF_DOLPHIN_BUTTON_WIDTH * span) - (DTMF_DOLPHIN_BUTTON_PADDING * 2), - DTMF_DOLPHIN_BUTTON_HEIGHT - (DTMF_DOLPHIN_BUTTON_PADDING * 2), + DTMF_DOLPHIN_BUTTON_HEIGHT- (DTMF_DOLPHIN_BUTTON_PADDING * 2), 2); - if(invert) canvas_invert_color(canvas); + if (invert) + canvas_invert_color(canvas); + canvas_set_font(canvas, FontSecondary); // canvas_set_color(canvas, invert ? ColorWhite : ColorBlack); - canvas_draw_str_aligned( - canvas, - left - 1 + (int)((DTMF_DOLPHIN_BUTTON_WIDTH * span) / 2), - top + (int)(DTMF_DOLPHIN_BUTTON_HEIGHT / 2), + canvas_draw_str_aligned(canvas, + left - 1 + (int) ((DTMF_DOLPHIN_BUTTON_WIDTH * span) / 2), + top + (int) (DTMF_DOLPHIN_BUTTON_HEIGHT / 2), AlignCenter, AlignCenter, dtmf_dolphin_data_get_tone_name(row, col)); - if(invert) canvas_invert_color(canvas); + if (invert) + canvas_invert_color(canvas); } void draw_dialer(Canvas* canvas, void* _model) { @@ -81,9 +79,9 @@ void draw_dialer(Canvas* canvas, void* _model) { canvas_set_font(canvas, FontSecondary); - for(int r = 0; r < max_rows; r++) { - for(int c = 0; c < max_cols; c++) { - if(model->row == r && model->col == c) + for (int r = 0; r < max_rows; r++) { + for (int c = 0; c < max_cols; c++) { + if (model->row == r && model->col == c) draw_button(canvas, r, c, true); else draw_button(canvas, r, c, false); @@ -91,20 +89,20 @@ void draw_dialer(Canvas* canvas, void* _model) { } } -void update_frequencies(DTMFDolphinDialerModel* model) { +void update_frequencies(DTMFDolphinDialerModel *model) { dtmf_dolphin_data_get_tone_frequencies(&model->freq1, &model->freq2, model->row, model->col); } static void dtmf_dolphin_dialer_draw_callback(Canvas* canvas, void* _model) { DTMFDolphinDialerModel* model = _model; - if(model->playing) { + if (model->playing) { // Leverage the prioritized draw callback to handle // the DMA so that it doesn't skip. dtmf_dolphin_audio_handle_tick(); // Don't do any drawing if audio is playing. canvas_set_font(canvas, FontPrimary); elements_multiline_text_aligned( - canvas, + canvas, canvas_width(canvas) / 2, canvas_height(canvas) / 2, AlignCenter, @@ -120,36 +118,33 @@ static void dtmf_dolphin_dialer_draw_callback(Canvas* canvas, void* _model) { canvas_set_font(canvas, FontPrimary); elements_multiline_text(canvas, 2, 10, dtmf_dolphin_data_get_current_section_name()); - canvas_draw_line( - canvas, - (max_span * DTMF_DOLPHIN_BUTTON_WIDTH) + 1, - 0, - (max_span * DTMF_DOLPHIN_BUTTON_WIDTH) + 1, - canvas_height(canvas)); + canvas_draw_line(canvas, + (max_span * DTMF_DOLPHIN_BUTTON_WIDTH) + 1, 0, + (max_span * DTMF_DOLPHIN_BUTTON_WIDTH) + 1, canvas_height(canvas)); elements_multiline_text(canvas, (max_span * DTMF_DOLPHIN_BUTTON_WIDTH) + 4, 10, "Detail"); - canvas_draw_line( - canvas, 0, DTMF_DOLPHIN_NUMPAD_Y - 3, canvas_width(canvas), DTMF_DOLPHIN_NUMPAD_Y - 3); + canvas_draw_line(canvas, 0, DTMF_DOLPHIN_NUMPAD_Y - 3, canvas_width(canvas), DTMF_DOLPHIN_NUMPAD_Y - 3); // elements_multiline_text_aligned(canvas, 64, 2, AlignCenter, AlignTop, "Dialer Mode"); draw_dialer(canvas, model); - FuriString* output; - output = furi_string_alloc(); + FuriString *output = furi_string_alloc(); - if(model->freq1 && model->freq2) { + if (model->freq1 && model->freq2) { furi_string_cat_printf( output, "Dual Tone\nF1: %u Hz\nF2: %u Hz\n", - (unsigned int)model->freq1, - (unsigned int)model->freq2); - } else if(model->freq1) { - furi_string_cat_printf(output, "Single Tone\nF: %u Hz\n", (unsigned int)model->freq1); + (unsigned int) model->freq1, + (unsigned int) model->freq2); + } else if (model->freq1) { + furi_string_cat_printf( + output, + "Single Tone\nF: %u Hz\n", + (unsigned int) model->freq1); } canvas_set_font(canvas, FontSecondary); canvas_set_color(canvas, ColorBlack); - elements_multiline_text( - canvas, (max_span * DTMF_DOLPHIN_BUTTON_WIDTH) + 4, 21, furi_string_get_cstr(output)); + elements_multiline_text(canvas, (max_span * DTMF_DOLPHIN_BUTTON_WIDTH) + 4, 21, furi_string_get_cstr(output)); furi_string_free(output); } @@ -184,11 +179,11 @@ static bool dtmf_dolphin_dialer_process_up(DTMFDolphinDialer* dtmf_dolphin_diale { uint8_t span = 0; uint8_t cursor = model->row; - while(span == 0 && cursor > 0) { + while (span == 0 && cursor > 0) { cursor--; span = dtmf_dolphin_get_tone_span(cursor, model->col); } - if(span != 0) { + if (span != 0) { model->row = cursor; } }, @@ -212,7 +207,7 @@ static bool dtmf_dolphin_dialer_process_down(DTMFDolphinDialer* dtmf_dolphin_dia cursor++; span = dtmf_dolphin_get_tone_span(cursor, model->col); } - if(span != 0) { + if (span != 0) { model->row = cursor; } }, @@ -227,11 +222,11 @@ static bool dtmf_dolphin_dialer_process_left(DTMFDolphinDialer* dtmf_dolphin_dia { uint8_t span = 0; uint8_t cursor = model->col; - while(span == 0 && cursor > 0) { + while (span == 0 && cursor > 0) { cursor--; span = dtmf_dolphin_get_tone_span(model->row, cursor); } - if(span != 0) { + if (span != 0) { model->col = cursor; } }, @@ -255,7 +250,7 @@ static bool dtmf_dolphin_dialer_process_right(DTMFDolphinDialer* dtmf_dolphin_di cursor++; span = dtmf_dolphin_get_tone_span(model->row, cursor); } - if(span != 0) { + if (span != 0) { model->col = cursor; } }, @@ -263,17 +258,16 @@ static bool dtmf_dolphin_dialer_process_right(DTMFDolphinDialer* dtmf_dolphin_di return true; } -static bool - dtmf_dolphin_dialer_process_ok(DTMFDolphinDialer* dtmf_dolphin_dialer, InputEvent* event) { +static bool dtmf_dolphin_dialer_process_ok(DTMFDolphinDialer* dtmf_dolphin_dialer, InputEvent* event) { bool consumed = false; with_view_model( dtmf_dolphin_dialer->view, DTMFDolphinDialerModel * model, { - if(event->type == InputTypePress) { + if (event->type == InputTypePress) { model->playing = dtmf_dolphin_audio_play_tones(model->freq1, model->freq2); - } else if(event->type == InputTypeRelease) { + } else if (event->type == InputTypeRelease) { model->playing = !dtmf_dolphin_audio_stop_tones(); } }, @@ -297,15 +291,15 @@ static void dtmf_dolphin_dialer_enter_callback(void* context) { model->freq2 = 0.0; model->playing = false; }, - true); + true + ); } DTMFDolphinDialer* dtmf_dolphin_dialer_alloc() { DTMFDolphinDialer* dtmf_dolphin_dialer = malloc(sizeof(DTMFDolphinDialer)); dtmf_dolphin_dialer->view = view_alloc(); - view_allocate_model( - dtmf_dolphin_dialer->view, ViewModelTypeLocking, sizeof(DTMFDolphinDialerModel)); + view_allocate_model(dtmf_dolphin_dialer->view, ViewModelTypeLocking, sizeof(DTMFDolphinDialerModel)); with_view_model( dtmf_dolphin_dialer->view, @@ -318,7 +312,8 @@ DTMFDolphinDialer* dtmf_dolphin_dialer_alloc() { model->freq2 = 0.0; model->playing = false; }, - true); + true + ); view_set_context(dtmf_dolphin_dialer->view, dtmf_dolphin_dialer); view_set_draw_callback(dtmf_dolphin_dialer->view, dtmf_dolphin_dialer_draw_callback); @@ -337,3 +332,4 @@ View* dtmf_dolphin_dialer_get_view(DTMFDolphinDialer* dtmf_dolphin_dialer) { furi_assert(dtmf_dolphin_dialer); return dtmf_dolphin_dialer->view; } + diff --git a/applications/plugins/dtmf_dolphin/views/dtmf_dolphin_dialer.h b/applications/plugins/dtmf_dolphin/views/dtmf_dolphin_dialer.h index 1929afbc5..c52343ff0 100644 --- a/applications/plugins/dtmf_dolphin/views/dtmf_dolphin_dialer.h +++ b/applications/plugins/dtmf_dolphin/views/dtmf_dolphin_dialer.h @@ -12,7 +12,4 @@ void dtmf_dolphin_dialer_free(DTMFDolphinDialer* dtmf_dolphin_dialer); View* dtmf_dolphin_dialer_get_view(DTMFDolphinDialer* dtmf_dolphin_dialer); -void dtmf_dolphin_dialer_set_ok_callback( - DTMFDolphinDialer* dtmf_dolphin_dialer, - DTMFDolphinDialerOkCallback callback, - void* context); +void dtmf_dolphin_dialer_set_ok_callback(DTMFDolphinDialer* dtmf_dolphin_dialer, DTMFDolphinDialerOkCallback callback, void* context);