calypso_util.c 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372
  1. #include <stdlib.h>
  2. #include <string.h>
  3. #include "calypso_util.h"
  4. CalypsoElement make_calypso_final_element(
  5. const char* key,
  6. int size,
  7. const char* label,
  8. CalypsoFinalType final_type) {
  9. CalypsoElement final_element = {};
  10. final_element.type = CALYPSO_ELEMENT_TYPE_FINAL;
  11. final_element.final = malloc(sizeof(CalypsoFinalElement));
  12. final_element.final->size = size;
  13. final_element.final->final_type = final_type;
  14. strncpy(final_element.final->key, key, 36);
  15. strncpy(final_element.final->label, label, 64);
  16. return final_element;
  17. }
  18. CalypsoElement make_calypso_bitmap_element(const char* key, int size, CalypsoElement* elements) {
  19. CalypsoElement bitmap_element = {};
  20. bitmap_element.type = CALYPSO_ELEMENT_TYPE_BITMAP;
  21. bitmap_element.bitmap = malloc(sizeof(CalypsoBitmapElement));
  22. bitmap_element.bitmap->size = size;
  23. bitmap_element.bitmap->elements = malloc(size * sizeof(CalypsoElement));
  24. for(int i = 0; i < size; i++) {
  25. bitmap_element.bitmap->elements[i] = elements[i];
  26. }
  27. strncpy(bitmap_element.bitmap->key, key, 36);
  28. return bitmap_element;
  29. }
  30. CalypsoElement
  31. make_calypso_container_element(const char* key, int size, CalypsoElement* elements) {
  32. CalypsoElement container_element = {};
  33. container_element.type = CALYPSO_ELEMENT_TYPE_CONTAINER;
  34. container_element.container = malloc(sizeof(CalypsoContainerElement));
  35. container_element.container->size = size;
  36. container_element.container->elements = malloc(size * sizeof(CalypsoElement));
  37. for(int i = 0; i < size; i++) {
  38. container_element.container->elements[i] = elements[i];
  39. }
  40. strncpy(container_element.container->key, key, 36);
  41. return container_element;
  42. }
  43. void free_calypso_element(CalypsoElement* element) {
  44. if(element->type == CALYPSO_ELEMENT_TYPE_FINAL) {
  45. free(element->final);
  46. } else if(element->type == CALYPSO_ELEMENT_TYPE_BITMAP) {
  47. for(int i = 0; i < element->bitmap->size; i++) {
  48. free_calypso_element(&element->bitmap->elements[i]);
  49. }
  50. free(element->bitmap->elements);
  51. free(element->bitmap);
  52. } else if(element->type == CALYPSO_ELEMENT_TYPE_CONTAINER) {
  53. for(int i = 0; i < element->container->size; i++) {
  54. free_calypso_element(&element->container->elements[i]);
  55. }
  56. free(element->container->elements);
  57. free(element->container);
  58. }
  59. }
  60. void free_calypso_structure(CalypsoApp* structure) {
  61. for(int i = 0; i < structure->container->size; i++) {
  62. free_calypso_element(&structure->container->elements[i]);
  63. }
  64. free(structure->container->elements);
  65. free(structure->container);
  66. free(structure);
  67. }
  68. int* get_bitmap_positions(const char* binary_string, int* count) {
  69. int length = strlen(binary_string);
  70. int* positions = malloc(length * sizeof(int));
  71. int pos_index = 0;
  72. for(int i = 0; i < length; i++) {
  73. if(binary_string[length - 1 - i] == '1') {
  74. positions[pos_index++] = i;
  75. }
  76. }
  77. *count = pos_index;
  78. return positions;
  79. }
  80. int is_bit_present(int* positions, int count, int bit) {
  81. for(int i = 0; i < count; i++) {
  82. if(positions[i] == bit) {
  83. return 1;
  84. }
  85. }
  86. return 0;
  87. }
  88. bool is_calypso_subnode_present(
  89. const char* binary_string,
  90. const char* key,
  91. CalypsoBitmapElement* bitmap) {
  92. char bit_slice[bitmap->size + 1];
  93. strncpy(bit_slice, binary_string, bitmap->size);
  94. bit_slice[bitmap->size] = '\0';
  95. int count = 0;
  96. int* positions = get_bitmap_positions(bit_slice, &count);
  97. int offset = bitmap->size;
  98. for(int i = 0; i < count; i++) {
  99. CalypsoElement* element = &bitmap->elements[positions[i]];
  100. if(element->type == CALYPSO_ELEMENT_TYPE_FINAL) {
  101. if(strcmp(element->final->key, key) == 0) {
  102. free(positions);
  103. return true;
  104. }
  105. offset += element->final->size;
  106. } else {
  107. if(strcmp(element->bitmap->key, key) == 0) {
  108. free(positions);
  109. return true;
  110. }
  111. int sub_binary_string_size = element->bitmap->size;
  112. char bit_slice[sub_binary_string_size + 1];
  113. strncpy(bit_slice, binary_string, sub_binary_string_size);
  114. bit_slice[sub_binary_string_size] = '\0';
  115. if(is_calypso_subnode_present(binary_string + offset, key, element->bitmap)) {
  116. free(positions);
  117. return true;
  118. }
  119. offset += element->bitmap->size;
  120. }
  121. }
  122. free(positions);
  123. return false;
  124. }
  125. bool is_calypso_node_present(const char* binary_string, const char* key, CalypsoApp* structure) {
  126. int offset = 0;
  127. for(int i = 0; i < structure->container->size; i++) {
  128. if(structure->container->elements[i].type == CALYPSO_ELEMENT_TYPE_FINAL) {
  129. if(strcmp(structure->container->elements[i].final->key, key) == 0) {
  130. return true;
  131. }
  132. offset += structure->container->elements[i].final->size;
  133. } else {
  134. if(strcmp(structure->container->elements[i].bitmap->key, key) == 0) {
  135. return true;
  136. }
  137. int sub_binary_string_size = structure->container->elements[i].bitmap->size;
  138. char bit_slice[sub_binary_string_size + 1];
  139. strncpy(bit_slice, binary_string, sub_binary_string_size);
  140. bit_slice[sub_binary_string_size] = '\0';
  141. if(is_calypso_subnode_present(
  142. binary_string + offset, key, structure->container->elements[i].bitmap)) {
  143. return true;
  144. }
  145. offset += structure->container->elements[i].bitmap->size;
  146. }
  147. }
  148. return false;
  149. }
  150. int get_calypso_subnode_offset(
  151. const char* binary_string,
  152. const char* key,
  153. CalypsoElement* elem,
  154. bool* found) {
  155. // recursive function to get the offset of a subnode in a calypso binary string
  156. if(elem->type == CALYPSO_ELEMENT_TYPE_FINAL) {
  157. if(strcmp(elem->final->key, key) == 0) {
  158. *found = true;
  159. return 0;
  160. }
  161. return elem->final->size;
  162. } else if(elem->type == CALYPSO_ELEMENT_TYPE_BITMAP) {
  163. CalypsoBitmapElement* bitmap = elem->bitmap;
  164. char bit_slice[bitmap->size + 1];
  165. strncpy(bit_slice, binary_string, bitmap->size);
  166. bit_slice[bitmap->size] = '\0';
  167. int count = 0;
  168. int* positions = get_bitmap_positions(bit_slice, &count);
  169. bool f = false;
  170. int count_offset = bitmap->size;
  171. for(int i = 0; i < count; i++) {
  172. CalypsoElement element = bitmap->elements[positions[i]];
  173. count_offset +=
  174. get_calypso_subnode_offset(binary_string + count_offset, key, &element, &f);
  175. if(f) {
  176. *found = true;
  177. free(positions);
  178. return count_offset;
  179. }
  180. }
  181. free(positions);
  182. return count_offset;
  183. } else if(elem->type == CALYPSO_ELEMENT_TYPE_CONTAINER) {
  184. // same as bitmap but without bitmap at the beginning
  185. CalypsoContainerElement* container = elem->container;
  186. int count_offset = 0;
  187. bool f = false;
  188. for(int i = 0; i < container->size; i++) {
  189. CalypsoElement element = container->elements[i];
  190. count_offset +=
  191. get_calypso_subnode_offset(binary_string + count_offset, key, &element, &f);
  192. if(f) {
  193. *found = true;
  194. return count_offset;
  195. }
  196. }
  197. return count_offset;
  198. }
  199. return 0;
  200. }
  201. int get_calypso_node_offset(const char* binary_string, const char* key, CalypsoApp* structure) {
  202. CalypsoElement* element = malloc(sizeof(CalypsoElement));
  203. element->type = CALYPSO_ELEMENT_TYPE_CONTAINER;
  204. element->container = structure->container;
  205. bool found;
  206. int offset = get_calypso_subnode_offset(binary_string, key, element, &found);
  207. if(!found) {
  208. FURI_LOG_E("Metroflip:Scene:Calypso", "Key %s not found in calypso structure", key);
  209. }
  210. free(element);
  211. return offset;
  212. }
  213. int get_calypso_subnode_size(const char* key, CalypsoElement* element) {
  214. if(element->type == CALYPSO_ELEMENT_TYPE_FINAL) {
  215. if(strcmp(element->final->key, key) == 0) {
  216. return element->final->size;
  217. }
  218. } else if(element->type == CALYPSO_ELEMENT_TYPE_BITMAP) {
  219. if(strcmp(element->bitmap->key, key) == 0) {
  220. return element->bitmap->size;
  221. }
  222. for(int i = 0; i < element->bitmap->size; i++) {
  223. int size = get_calypso_subnode_size(key, &element->bitmap->elements[i]);
  224. if(size != 0) {
  225. return size;
  226. }
  227. }
  228. } else if(element->type == CALYPSO_ELEMENT_TYPE_CONTAINER) {
  229. if(strcmp(element->container->key, key) == 0) {
  230. return element->container->size;
  231. }
  232. for(int i = 0; i < element->container->size; i++) {
  233. int size = get_calypso_subnode_size(key, &element->container->elements[i]);
  234. if(size != 0) {
  235. return size;
  236. }
  237. }
  238. }
  239. return 0;
  240. }
  241. int get_calypso_node_size(const char* key, CalypsoApp* structure) {
  242. CalypsoElement* element = malloc(sizeof(CalypsoElement));
  243. element->type = CALYPSO_ELEMENT_TYPE_CONTAINER;
  244. element->container = structure->container;
  245. int count = get_calypso_subnode_size(key, element);
  246. free(element);
  247. return count;
  248. }
  249. CALYPSO_CARD_TYPE guess_card_type(int country_num, int network_num) {
  250. switch(country_num) {
  251. case 56:
  252. switch(network_num) {
  253. case 1:
  254. return CALYPSO_CARD_MOBIB;
  255. default:
  256. return CALYPSO_CARD_UNKNOWN;
  257. }
  258. case 124:
  259. switch(network_num) {
  260. case 1:
  261. return CALYPSO_CARD_OPUS;
  262. default:
  263. return CALYPSO_CARD_UNKNOWN;
  264. }
  265. case 131:
  266. return CALYPSO_CARD_VIVA;
  267. case 250:
  268. switch(network_num) {
  269. case 0:
  270. return CALYPSO_CARD_PASSPASS;
  271. case 64:
  272. return CALYPSO_CARD_TAM; // Montpellier
  273. case 502:
  274. return CALYPSO_CARD_OURA;
  275. case 901:
  276. return CALYPSO_CARD_NAVIGO;
  277. case 908:
  278. return CALYPSO_CARD_KORRIGO;
  279. case 916:
  280. return CALYPSO_CARD_TISSEO;
  281. case 920:
  282. return CALYPSO_CARD_ENVIBUS;
  283. case 921:
  284. return CALYPSO_CARD_GIRONDE;
  285. default:
  286. return CALYPSO_CARD_UNKNOWN;
  287. }
  288. case 376:
  289. return CALYPSO_CARD_RAVKAV;
  290. default:
  291. return CALYPSO_CARD_UNKNOWN;
  292. }
  293. }
  294. const char* get_country_string(int country_num) {
  295. switch(country_num) {
  296. case 56:
  297. return "Belgium";
  298. case 124:
  299. return "Canada";
  300. case 131:
  301. return "Portugal";
  302. case 250:
  303. return "France";
  304. case 376:
  305. return "Israel";
  306. default: {
  307. char* country = malloc(4 * sizeof(char));
  308. snprintf(country, 4, "%d", country_num);
  309. return country;
  310. }
  311. }
  312. }
  313. const char* get_network_string(CALYPSO_CARD_TYPE card_type) {
  314. switch(card_type) {
  315. case CALYPSO_CARD_MOBIB:
  316. return "Mobib";
  317. case CALYPSO_CARD_OPUS:
  318. return "Opus";
  319. case CALYPSO_CARD_VIVA:
  320. return "Viva";
  321. case CALYPSO_CARD_PASSPASS:
  322. return "PassPass";
  323. case CALYPSO_CARD_TAM:
  324. return "TAM";
  325. case CALYPSO_CARD_OURA:
  326. return "Oura";
  327. case CALYPSO_CARD_NAVIGO:
  328. return "IDFM";
  329. case CALYPSO_CARD_KORRIGO:
  330. return "KorriGo";
  331. case CALYPSO_CARD_TISSEO:
  332. return "Tisseo";
  333. case CALYPSO_CARD_ENVIBUS:
  334. return "Envibus";
  335. case CALYPSO_CARD_GIRONDE:
  336. return "Gironde";
  337. case CALYPSO_CARD_RAVKAV:
  338. return "Rav-Kav";
  339. default:
  340. return "Unknown";
  341. }
  342. }