@@ -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
182199const 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+
201253const 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+
319386void 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]);
0 commit comments