| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419 |
- #include "metroflip_i.h"
- #include <stdlib.h>
- #include <string.h>
- #include "calypso_util.h"
- #include "../metroflip/metroflip_api.h"
- CalypsoElement make_calypso_final_element(
- const char* key,
- int size,
- const char* label,
- CalypsoFinalType final_type) {
- CalypsoElement final_element = {};
- final_element.type = CALYPSO_ELEMENT_TYPE_FINAL;
- final_element.final = malloc(sizeof(CalypsoFinalElement));
- final_element.final->size = size;
- final_element.final->final_type = final_type;
- strncpy(final_element.final->key, key, 36);
- strncpy(final_element.final->label, label, 64);
- return final_element;
- }
- CalypsoElement make_calypso_bitmap_element(const char* key, int size, CalypsoElement* elements) {
- CalypsoElement bitmap_element = {};
- bitmap_element.type = CALYPSO_ELEMENT_TYPE_BITMAP;
- bitmap_element.bitmap = malloc(sizeof(CalypsoBitmapElement));
- bitmap_element.bitmap->size = size;
- bitmap_element.bitmap->elements = malloc(size * sizeof(CalypsoElement));
- for(int i = 0; i < size; i++) {
- bitmap_element.bitmap->elements[i] = elements[i];
- }
- strncpy(bitmap_element.bitmap->key, key, 36);
- return bitmap_element;
- }
- CalypsoElement
- make_calypso_container_element(const char* key, int size, CalypsoElement* elements) {
- CalypsoElement container_element = {};
- container_element.type = CALYPSO_ELEMENT_TYPE_CONTAINER;
- container_element.container = malloc(sizeof(CalypsoContainerElement));
- container_element.container->size = size;
- container_element.container->elements = malloc(size * sizeof(CalypsoElement));
- for(int i = 0; i < size; i++) {
- container_element.container->elements[i] = elements[i];
- }
- strncpy(container_element.container->key, key, 36);
- return container_element;
- }
- CalypsoElement make_calypso_repeater_element(const char* key, int size, CalypsoElement element) {
- CalypsoElement repeater_element = {};
- repeater_element.type = CALYPSO_ELEMENT_TYPE_REPEATER;
- repeater_element.repeater = malloc(sizeof(CalypsoRepeaterElement));
- repeater_element.repeater->size = size;
- repeater_element.repeater->element = element;
- strncpy(repeater_element.repeater->key, key, 36);
- return repeater_element;
- }
- void free_calypso_element(CalypsoElement* element) {
- if(element->type == CALYPSO_ELEMENT_TYPE_FINAL) {
- free(element->final);
- } else if(element->type == CALYPSO_ELEMENT_TYPE_BITMAP) {
- for(int i = 0; i < element->bitmap->size; i++) {
- free_calypso_element(&element->bitmap->elements[i]);
- }
- free(element->bitmap->elements);
- free(element->bitmap);
- } else if(element->type == CALYPSO_ELEMENT_TYPE_CONTAINER) {
- for(int i = 0; i < element->container->size; i++) {
- free_calypso_element(&element->container->elements[i]);
- }
- free(element->container->elements);
- free(element->container);
- } else if(element->type == CALYPSO_ELEMENT_TYPE_REPEATER) {
- free_calypso_element(&element->repeater->element);
- free(element->repeater);
- }
- }
- void free_calypso_structure(CalypsoApp* structure) {
- for(int i = 0; i < structure->container->size; i++) {
- free_calypso_element(&structure->container->elements[i]);
- }
- free(structure->container->elements);
- free(structure->container);
- free(structure);
- }
- int* get_bitmap_positions(const char* binary_string, int* count) {
- int length = strlen(binary_string);
- int* positions = malloc(length * sizeof(int));
- int pos_index = 0;
- for(int i = 0; i < length; i++) {
- if(binary_string[length - 1 - i] == '1') {
- positions[pos_index++] = i;
- }
- }
- *count = pos_index;
- return positions;
- }
- int is_bit_present(int* positions, int count, int bit) {
- for(int i = 0; i < count; i++) {
- if(positions[i] == bit) {
- return 1;
- }
- }
- return 0;
- }
- bool is_calypso_subnode_present(
- const char* binary_string,
- const char* key,
- CalypsoBitmapElement* bitmap) {
- char bit_slice[bitmap->size + 1];
- strncpy(bit_slice, binary_string, bitmap->size);
- bit_slice[bitmap->size] = '\0';
- int count = 0;
- int* positions = get_bitmap_positions(bit_slice, &count);
- int offset = bitmap->size;
- for(int i = 0; i < count; i++) {
- CalypsoElement* element = &bitmap->elements[positions[i]];
- if(element->type == CALYPSO_ELEMENT_TYPE_FINAL) {
- if(strcmp(element->final->key, key) == 0) {
- free(positions);
- return true;
- }
- offset += element->final->size;
- } else {
- if(strcmp(element->bitmap->key, key) == 0) {
- free(positions);
- return true;
- }
- int sub_binary_string_size = element->bitmap->size;
- char bit_slice[sub_binary_string_size + 1];
- strncpy(bit_slice, binary_string, sub_binary_string_size);
- bit_slice[sub_binary_string_size] = '\0';
- if(is_calypso_subnode_present(binary_string + offset, key, element->bitmap)) {
- free(positions);
- return true;
- }
- offset += element->bitmap->size;
- }
- }
- free(positions);
- return false;
- }
- bool is_calypso_node_present(const char* binary_string, const char* key, CalypsoApp* structure) {
- int offset = 0;
- for(int i = 0; i < structure->container->size; i++) {
- if(structure->container->elements[i].type == CALYPSO_ELEMENT_TYPE_FINAL) {
- if(strcmp(structure->container->elements[i].final->key, key) == 0) {
- return true;
- }
- offset += structure->container->elements[i].final->size;
- } else {
- if(strcmp(structure->container->elements[i].bitmap->key, key) == 0) {
- return true;
- }
- int sub_binary_string_size = structure->container->elements[i].bitmap->size;
- char bit_slice[sub_binary_string_size + 1];
- strncpy(bit_slice, binary_string, sub_binary_string_size);
- bit_slice[sub_binary_string_size] = '\0';
- if(is_calypso_subnode_present(
- binary_string + offset, key, structure->container->elements[i].bitmap)) {
- return true;
- }
- offset += structure->container->elements[i].bitmap->size;
- }
- }
- return false;
- }
- int get_calypso_subnode_offset(
- const char* binary_string,
- const char* key,
- CalypsoElement* elem,
- bool* found) {
- // recursive function to get the offset of a subnode in a calypso binary string
- if(elem->type == CALYPSO_ELEMENT_TYPE_FINAL) {
- if(strcmp(elem->final->key, key) == 0) {
- *found = true;
- return 0;
- }
- return elem->final->size;
- } else if(elem->type == CALYPSO_ELEMENT_TYPE_BITMAP) {
- CalypsoBitmapElement* bitmap = elem->bitmap;
- char bit_slice[bitmap->size + 1];
- strncpy(bit_slice, binary_string, bitmap->size);
- bit_slice[bitmap->size] = '\0';
- int count = 0;
- int* positions = get_bitmap_positions(bit_slice, &count);
- bool f = false;
- int count_offset = bitmap->size;
- for(int i = 0; i < count; i++) {
- CalypsoElement element = bitmap->elements[positions[i]];
- count_offset +=
- get_calypso_subnode_offset(binary_string + count_offset, key, &element, &f);
- if(f) {
- *found = true;
- free(positions);
- return count_offset;
- }
- }
- free(positions);
- return count_offset;
- } else if(elem->type == CALYPSO_ELEMENT_TYPE_CONTAINER) {
- // same as bitmap but without bitmap at the beginning
- CalypsoContainerElement* container = elem->container;
- int count_offset = 0;
- bool f = false;
- for(int i = 0; i < container->size; i++) {
- CalypsoElement element = container->elements[i];
- count_offset +=
- get_calypso_subnode_offset(binary_string + count_offset, key, &element, &f);
- if(f) {
- *found = true;
- return count_offset;
- }
- }
- return count_offset;
- } else if(elem->type == CALYPSO_ELEMENT_TYPE_REPEATER) {
- // same as bitmap but instead of a bitmap, we have the count of how many times to repeat the inner element
- CalypsoRepeaterElement* repeater = elem->repeater;
- char bit_slice[repeater->size + 1];
- strncpy(bit_slice, binary_string, repeater->size);
- bit_slice[repeater->size] = '\0';
- int C = bit_slice_to_dec(bit_slice, 0, repeater->size - 1);
- int count_offset = repeater->size;
- bool f = false;
- for(int i = 0; i < C; i++) {
- count_offset += get_calypso_subnode_offset(
- binary_string + count_offset, key, &repeater->element, &f);
- if(f) {
- *found = true;
- return count_offset;
- }
- }
- }
- return 0;
- }
- int get_calypso_node_offset(const char* binary_string, const char* key, CalypsoApp* structure) {
- CalypsoElement* element = malloc(sizeof(CalypsoElement));
- element->type = CALYPSO_ELEMENT_TYPE_CONTAINER;
- element->container = structure->container;
- bool found;
- int offset = get_calypso_subnode_offset(binary_string, key, element, &found);
- if(!found) {
- FURI_LOG_E("Metroflip:Scene:Calypso", "Key %s not found in calypso structure", key);
- }
- free(element);
- return offset;
- }
- int get_calypso_subnode_size(const char* key, CalypsoElement* element) {
- if(element->type == CALYPSO_ELEMENT_TYPE_FINAL) {
- if(strcmp(element->final->key, key) == 0) {
- return element->final->size;
- }
- } else if(element->type == CALYPSO_ELEMENT_TYPE_BITMAP) {
- if(strcmp(element->bitmap->key, key) == 0) {
- return element->bitmap->size;
- }
- for(int i = 0; i < element->bitmap->size; i++) {
- int size = get_calypso_subnode_size(key, &element->bitmap->elements[i]);
- if(size != 0) {
- return size;
- }
- }
- } else if(element->type == CALYPSO_ELEMENT_TYPE_CONTAINER) {
- if(strcmp(element->container->key, key) == 0) {
- return element->container->size;
- }
- for(int i = 0; i < element->container->size; i++) {
- int size = get_calypso_subnode_size(key, &element->container->elements[i]);
- if(size != 0) {
- return size;
- }
- }
- } else if(element->type == CALYPSO_ELEMENT_TYPE_REPEATER) {
- if(strcmp(element->repeater->key, key) == 0) {
- return element->repeater->size;
- }
- int size = get_calypso_subnode_size(key, &element->repeater->element);
- if(size != 0) {
- return size;
- }
- }
- return 0;
- }
- int get_calypso_node_size(const char* key, CalypsoApp* structure) {
- CalypsoElement* element = malloc(sizeof(CalypsoElement));
- element->type = CALYPSO_ELEMENT_TYPE_CONTAINER;
- element->container = structure->container;
- int count = get_calypso_subnode_size(key, element);
- free(element);
- return count;
- }
- CALYPSO_CARD_TYPE guess_card_type(int country_num, int network_num) {
- switch(country_num) {
- case 56:
- switch(network_num) {
- case 1:
- return CALYPSO_CARD_MOBIB;
- default:
- return CALYPSO_CARD_UNKNOWN;
- }
- case 124:
- switch(network_num) {
- case 1:
- return CALYPSO_CARD_OPUS;
- default:
- return CALYPSO_CARD_UNKNOWN;
- }
- case 131:
- return CALYPSO_CARD_VIVA;
- case 250:
- switch(network_num) {
- case 0:
- return CALYPSO_CARD_PASSPASS;
- case 64:
- return CALYPSO_CARD_TAM; // Montpellier
- case 149:
- return CALYPSO_CARD_TRANSPOLE; // Lille
- case 502:
- return CALYPSO_CARD_OURA;
- case 901:
- return CALYPSO_CARD_NAVIGO;
- case 908:
- return CALYPSO_CARD_KORRIGO;
- case 916:
- return CALYPSO_CARD_TISSEO;
- case 920:
- return CALYPSO_CARD_ENVIBUS;
- case 921:
- return CALYPSO_CARD_GIRONDE;
- default:
- return CALYPSO_CARD_UNKNOWN;
- }
- case 376:
- return CALYPSO_CARD_RAVKAV;
- default:
- return CALYPSO_CARD_UNKNOWN;
- }
- }
- const char* get_country_string(int country_num) {
- switch(country_num) {
- case 56:
- return "Belgium";
- case 124:
- return "Canada";
- case 131:
- return "Portugal";
- case 250:
- return "France";
- case 376:
- return "Israel";
- default: {
- char* country = malloc(4 * sizeof(char));
- snprintf(country, 4, "%d", country_num);
- return country;
- }
- }
- }
- const char* get_network_string(CALYPSO_CARD_TYPE card_type) {
- switch(card_type) {
- case CALYPSO_CARD_MOBIB:
- return "Mobib";
- case CALYPSO_CARD_OPUS:
- return "Opus";
- case CALYPSO_CARD_VIVA:
- return "Viva";
- case CALYPSO_CARD_PASSPASS:
- return "PassPass";
- case CALYPSO_CARD_TAM:
- return "TAM";
- case CALYPSO_CARD_OURA:
- return "Oura";
- case CALYPSO_CARD_NAVIGO:
- return "IDFM";
- case CALYPSO_CARD_KORRIGO:
- return "KorriGo";
- case CALYPSO_CARD_TISSEO:
- return "Tisseo";
- case CALYPSO_CARD_ENVIBUS:
- return "Envibus";
- case CALYPSO_CARD_GIRONDE:
- return "Gironde";
- case CALYPSO_CARD_RAVKAV:
- return "Rav-Kav";
- default:
- return "Unknown";
- }
- }
|