Skip to content

Commit c37af7b

Browse files
authored
Merge pull request #22 from DocSystem/dev
2 parents 7a654fe + 2dbede2 commit c37af7b

File tree

2 files changed

+135
-34
lines changed

2 files changed

+135
-34
lines changed

scenes/metroflip_scene_navigo.c

Lines changed: 127 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -78,15 +78,32 @@ const char* get_country(int country_num) {
7878
switch(country_num) {
7979
case 250:
8080
return "France";
81-
default:
82-
return "Unknown";
81+
case 124:
82+
return "Canada";
83+
default: {
84+
char* country = malloc(4 * sizeof(char));
85+
snprintf(country, 4, "%d", country_num);
86+
return country;
87+
}
8388
}
8489
}
8590

86-
const char* get_network(int network_num) {
87-
switch(network_num) {
88-
case 901:
89-
return "Ile-de-France Mobilites";
91+
const char* get_network(int country_num, int network_num) {
92+
switch(country_num) {
93+
case 250:
94+
switch(network_num) {
95+
case 901:
96+
return "IDFM";
97+
default:
98+
return "Unknown";
99+
}
100+
case 124:
101+
switch(network_num) {
102+
case 1:
103+
return "STM";
104+
default:
105+
return "Unknown";
106+
}
90107
default:
91108
return "Unknown";
92109
}
@@ -175,29 +192,64 @@ const char* get_navigo_type(int type) {
175192
case IMAGINE_R:
176193
return "Imagine R";
177194
default:
178-
return "Navigo Inconnu";
195+
return "Navigo";
179196
}
180197
}
181198

182199
const char* get_tariff(int tariff) {
183200
switch(tariff) {
201+
case 0x0000:
202+
return "Navigo Mois"; // Theoric
203+
case 0x0001:
204+
return "Navigo Semaine"; // Theoric
184205
case 0x0002:
185206
return "Navigo Annuel";
207+
case 0x0003:
208+
return "Navigo Jour"; // Theoric
186209
case 0x0004:
187210
return "Imagine R Junior";
188211
case 0x0005:
189212
return "Imagine R Etudiant";
190213
case 0x000D:
191214
return "Navigo Jeunes Week-end";
215+
case 0x0015:
216+
return "Paris-Visite"; // Theoric
192217
case 0x1000:
193218
return "Navigo Liberte+";
219+
case 0x4015:
220+
return "Paris-Visite (Enfant)"; // Theoric
194221
case 0x5000:
195-
return "Navigo Easy";
196-
default:
197-
return "Inconnu";
222+
return "Tickets T+";
223+
case 0x5004:
224+
return "Tickets OrlyBus"; // Theoric
225+
case 0x5005:
226+
return "Tickets RoissyBus"; // Theoric
227+
case 0x5006:
228+
return "Bus-Tram"; // Theoric
229+
case 0x5008:
230+
return "Metro-Train-RER"; // Theoric
231+
case 0x500b:
232+
return "Paris <> Aeroports"; // Theoric
233+
case 0x5010:
234+
return "Tickets T+ (Reduit)"; // Theoric
235+
case 0x5016:
236+
return "Bus-Tram (Reduit)"; // Theoric
237+
case 0x5018:
238+
return "Metro-Train-RER (Reduit)"; // Theoric
239+
case 0x501b:
240+
return "Paris <> Aeroports (Reduit)"; // Theoric
241+
default: {
242+
char* tariff_str = malloc(6 * sizeof(char));
243+
snprintf(tariff_str, 6, "%d", tariff);
244+
return tariff_str;
245+
}
198246
}
199247
}
200248

249+
bool is_ticket_count_available(int tariff) {
250+
return tariff >= 0x5000 && tariff <= 0x501b;
251+
}
252+
201253
const char* get_pay_method(int pay_method) {
202254
switch(pay_method) {
203255
case 0x30:
@@ -316,10 +368,29 @@ const char* get_train_station(int station_group_id, int station_id) {
316368
return station;
317369
}
318370

371+
const char* get_tram_line(int route_number) {
372+
switch(route_number) {
373+
case 16:
374+
return "T6";
375+
default: {
376+
char* line = malloc(3 * sizeof(char));
377+
if(!line) {
378+
return "Unknown";
379+
}
380+
snprintf(line, 3, "T%d", route_number);
381+
return line;
382+
}
383+
}
384+
}
385+
319386
void show_event_info(
320387
NavigoCardEvent* event,
321388
NavigoCardContract* contracts,
322389
FuriString* parsed_data) {
390+
if(event->used_contract == 0) {
391+
furi_string_cat_printf(parsed_data, "No event data\n");
392+
return;
393+
}
323394
if(event->transport_type == BUS_URBAIN || event->transport_type == BUS_INTERURBAIN ||
324395
event->transport_type == METRO || event->transport_type == TRAM) {
325396
if(event->route_number_available) {
@@ -329,6 +400,13 @@ void show_event_info(
329400
"%s 3 bis\n%s\n",
330401
get_transport_type(event->transport_type),
331402
get_transition_type(event->transition));
403+
} else if(event->transport_type == TRAM) {
404+
furi_string_cat_printf(
405+
parsed_data,
406+
"%s %s\n%s\n",
407+
get_transport_type(event->transport_type),
408+
get_tram_line(event->route_number),
409+
get_transition_type(event->transition));
332410
} else {
333411
furi_string_cat_printf(
334412
parsed_data,
@@ -378,7 +456,7 @@ void show_event_info(
378456
parsed_data,
379457
"Contract: %d - %s\n",
380458
event->used_contract,
381-
get_tariff(contracts[event->used_contract].tariff));
459+
get_tariff(contracts[event->used_contract - 1].tariff));
382460
}
383461
locale_format_datetime_cat(parsed_data, &event->date, true);
384462
furi_string_cat_printf(parsed_data, "\n");
@@ -423,7 +501,7 @@ void show_event_info(
423501
parsed_data,
424502
"Contract: %d - %s\n",
425503
event->used_contract,
426-
get_tariff(contracts[event->used_contract].tariff));
504+
get_tariff(contracts[event->used_contract - 1].tariff));
427505
}
428506
locale_format_datetime_cat(parsed_data, &event->date, true);
429507
furi_string_cat_printf(parsed_data, "\n");
@@ -454,15 +532,18 @@ void show_event_info(
454532
parsed_data,
455533
"Contract: %d - %s\n",
456534
event->used_contract,
457-
get_tariff(contracts[event->used_contract].tariff));
535+
get_tariff(contracts[event->used_contract - 1].tariff));
458536
}
459537
locale_format_datetime_cat(parsed_data, &event->date, true);
460538
furi_string_cat_printf(parsed_data, "\n");
461539
}
462540
}
463541

464-
void show_contract_info(NavigoCardContract* contract, int ticket_count, FuriString* parsed_data) {
542+
void show_contract_info(NavigoCardContract* contract, FuriString* parsed_data) {
465543
furi_string_cat_printf(parsed_data, "Type: %s\n", get_tariff(contract->tariff));
544+
if(is_ticket_count_available(contract->tariff)) {
545+
furi_string_cat_printf(parsed_data, "Remaining Tickets: %d\n", contract->counter.count);
546+
}
466547
if(contract->serial_number_available) {
467548
furi_string_cat_printf(parsed_data, "TCN Number: %d\n", contract->serial_number);
468549
}
@@ -473,9 +554,6 @@ void show_contract_info(NavigoCardContract* contract, int ticket_count, FuriStri
473554
if(contract->price_amount_available) {
474555
furi_string_cat_printf(parsed_data, "Amount: %.2f EUR\n", contract->price_amount);
475556
}
476-
if(contract->tariff == 0x5000) {
477-
furi_string_cat_printf(parsed_data, "Remaining Tickets: %d\n", ticket_count);
478-
}
479557
if(contract->end_date_available) {
480558
furi_string_cat_printf(parsed_data, "Valid\nfrom: ");
481559
locale_format_datetime_cat(parsed_data, &contract->start_date, false);
@@ -506,16 +584,11 @@ void show_environment_info(NavigoCardEnv* environment, FuriString* parsed_data)
506584
"App Version: %s - v%d\n",
507585
get_intercode_version(environment->app_version),
508586
get_intercode_subversion(environment->app_version));
509-
if(environment->country_num == 250) {
510-
furi_string_cat_printf(parsed_data, "Country: France\n");
511-
} else {
512-
furi_string_cat_printf(parsed_data, "Country: %d\n", environment->country_num);
513-
}
514-
if(environment->network_num == 901) {
515-
furi_string_cat_printf(parsed_data, "Network: Ile-de-France Mobilites\n");
516-
} else {
517-
furi_string_cat_printf(parsed_data, "Network: %d\n", environment->network_num);
518-
}
587+
furi_string_cat_printf(parsed_data, "Country: %s\n", get_country(environment->country_num));
588+
furi_string_cat_printf(
589+
parsed_data,
590+
"Network: %s\n",
591+
get_network(environment->country_num, environment->network_num));
519592
furi_string_cat_printf(parsed_data, "End of validity:\n");
520593
locale_format_datetime_cat(parsed_data, &environment->end_dt, false);
521594
furi_string_cat_printf(parsed_data, "\n");
@@ -531,15 +604,15 @@ void update_page_info(void* context, FuriString* parsed_data) {
531604
get_navigo_type(ctx->card->holder.card_status),
532605
ctx->card->card_number);
533606
furi_string_cat_printf(parsed_data, "\e#Contract 1:\n");
534-
show_contract_info(&ctx->card->contracts[0], ctx->card->ticket_counts[0], parsed_data);
607+
show_contract_info(&ctx->card->contracts[0], parsed_data);
535608
} else if(ctx->page_id == 1) {
536609
furi_string_cat_printf(
537610
parsed_data,
538611
"\e#%s %u:\n",
539612
get_navigo_type(ctx->card->holder.card_status),
540613
ctx->card->card_number);
541614
furi_string_cat_printf(parsed_data, "\e#Contract 2:\n");
542-
show_contract_info(&ctx->card->contracts[1], ctx->card->ticket_counts[1], parsed_data);
615+
show_contract_info(&ctx->card->contracts[1], parsed_data);
543616
} else if(ctx->page_id == 2) {
544617
furi_string_cat_printf(parsed_data, "\e#Environment:\n");
545618
show_environment_info(&ctx->card->environment, parsed_data);
@@ -585,7 +658,7 @@ void metroflip_back_button_widget_callback(GuiButtonType result, InputType type,
585658
FURI_LOG_I(TAG, "Page ID: %d -> %d", ctx->page_id, ctx->page_id - 1);
586659

587660
if(ctx->page_id > 0) {
588-
if(ctx->page_id == 2 && ctx->card->contracts[1].tariff == 0) {
661+
if(ctx->page_id == 2 && ctx->card->contracts[1].present == 0) {
589662
ctx->page_id -= 1;
590663
}
591664
ctx->page_id -= 1;
@@ -623,7 +696,7 @@ void metroflip_next_button_widget_callback(GuiButtonType result, InputType type,
623696
FURI_LOG_I(TAG, "Page ID: %d -> %d", ctx->page_id, ctx->page_id + 1);
624697

625698
if(ctx->page_id < 5) {
626-
if(ctx->page_id == 0 && ctx->card->contracts[1].tariff == 0) {
699+
if(ctx->page_id == 0 && ctx->card->contracts[1].present == 0) {
627700
ctx->page_id += 1;
628701
}
629702
ctx->page_id += 1;
@@ -797,6 +870,15 @@ static NfcCommand metroflip_scene_navigo_poller_callback(NfcGenericEvent event,
797870
TAG, "Position: %d, Key: %s, Offset: %d", positions[i], key, offset);
798871
} */
799872

873+
if(bit_slice_to_dec(
874+
bit_representation,
875+
0,
876+
NavigoContractStructure->elements[0].bitmap->size - 1) == 0) {
877+
break;
878+
}
879+
880+
card->contracts[i - 1].present = 1;
881+
800882
// 2. ContractTariff
801883
const char* contract_key = "ContractTariff";
802884
if(is_calypso_node_present(
@@ -1078,12 +1160,24 @@ static NfcCommand metroflip_scene_navigo_poller_callback(NfcGenericEvent event,
10781160
// Ticket count (contract 1)
10791161
start = 0;
10801162
end = 5;
1081-
card->ticket_counts[0] = bit_slice_to_dec(counter_bit_representation, start, end);
1163+
card->contracts[0].counter.count =
1164+
bit_slice_to_dec(counter_bit_representation, start, end);
1165+
1166+
start = 6;
1167+
end = 23;
1168+
card->contracts[0].counter.relative_first_stamp_15mn =
1169+
bit_slice_to_dec(counter_bit_representation, start, end);
10821170

10831171
// Ticket count (contract 2)
10841172
start = 24;
10851173
end = 29;
1086-
card->ticket_counts[1] = bit_slice_to_dec(counter_bit_representation, start, end);
1174+
card->contracts[1].counter.count =
1175+
bit_slice_to_dec(counter_bit_representation, start, end);
1176+
1177+
start = 30;
1178+
end = 47;
1179+
card->contracts[1].counter.relative_first_stamp_15mn =
1180+
bit_slice_to_dec(counter_bit_representation, start, end);
10871181

10881182
// FURI_LOG_I(TAG, "Ticket count 1: %d", card->ticket_counts[0]);
10891183
// FURI_LOG_I(TAG, "Ticket count 2: %d", card->ticket_counts[1]);

scenes/navigo_structs.h

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,12 @@ typedef struct {
3737
int commercial_id;
3838
} NavigoCardHolder;
3939

40+
typedef struct {
41+
int count;
42+
int relative_first_stamp_15mn;
43+
int struct_number;
44+
} NavigoCardContractCounter;
45+
4046
typedef struct {
4147
int tariff;
4248
int serial_number;
@@ -55,14 +61,15 @@ typedef struct {
5561
int sale_device;
5662
int status;
5763
int authenticator;
64+
NavigoCardContractCounter counter;
65+
bool present;
5866
} NavigoCardContract;
5967

6068
typedef struct {
6169
NavigoCardEnv environment;
6270
NavigoCardHolder holder;
6371
NavigoCardContract contracts[2];
6472
NavigoCardEvent events[3];
65-
int ticket_counts[2];
6673
unsigned int card_number;
6774
} NavigoCardData;
6875

0 commit comments

Comments
 (0)