about summary refs log tree commit diff stats
path: root/source/main.c
diff options
context:
space:
mode:
authorKelly Rauchenberger <fefferburbia@gmail.com>2017-09-16 16:11:15 -0400
committerKelly Rauchenberger <fefferburbia@gmail.com>2017-09-16 16:11:15 -0400
commit4fe95cc1e7412e309d026e53cd44239bd3ef031d (patch)
treec1b711ed5a81976d9054da6205f5f9b2c3133248 /source/main.c
parente2a76d1f0fd978f285edf1dbc0f6e87cf89c63ce (diff)
downloadgen3uploader-4fe95cc1e7412e309d026e53cd44239bd3ef031d.tar.gz
gen3uploader-4fe95cc1e7412e309d026e53cd44239bd3ef031d.tar.bz2
gen3uploader-4fe95cc1e7412e309d026e53cd44239bd3ef031d.zip
Wii can now send a POST request to a website
The extractor now uses libfat to read a config file off the root of the
SD card, a model for which is included in the repository. The extractor
is capable of negotiating an HTTPS connection, but it requires a
download of the target site's root CA certificate to be on the SD card
and pointed at by the config file. TLS/SSL functionality is provided by
wolfSSL. I had to make a couple of minor changes to wolfSSL for it to
work properly, and those changes are located in the devkitpro branch of
my fork, hatkirby/wolfssl.

The Wii program now arranges some of the information that the GBA sends
it into a JSON object, which is then sent off (along with some
authentication information from the config file) to the endpoint defined
in the config file. The code used to maintain the network connection is
from the WiiTweet project, which was licensed under the GPL. Some of the
code used to send the HTTP request also comes from said project.
Diffstat (limited to 'source/main.c')
-rw-r--r--source/main.c244
1 files changed, 229 insertions, 15 deletions
diff --git a/source/main.c b/source/main.c index 3806106..eb5072e 100644 --- a/source/main.c +++ b/source/main.c
@@ -11,10 +11,14 @@
11#include <stdlib.h> 11#include <stdlib.h>
12#include <unistd.h> 12#include <unistd.h>
13#include <string.h> 13#include <string.h>
14#include <fat.h>
15#include "cJSON.h"
14#include "link.h" 16#include "link.h"
15#include "encoding.h" 17#include "encoding.h"
16#include "multiboot.h" 18#include "multiboot.h"
17#include "pokemon.h" 19#include "pokemon.h"
20#include "http.h"
21#include "netinf.h"
18 22
19void printmain() 23void printmain()
20{ 24{
@@ -65,8 +69,75 @@ void fatalError(char *msg)
65 exit(0); 69 exit(0);
66} 70}
67 71
72cJSON* getConfig()
73{
74 FILE* fp = fopen("/gen3uploader.cfg", "r");
75 if (!fp)
76 {
77 fatalError("ERROR: Could not find config file!\n");
78 }
79
80 fseek(fp, 0L, SEEK_END);
81 long lSize = ftell(fp);
82 rewind(fp);
83
84 char* buffer = calloc(1, lSize+1);
85 if (!buffer)
86 {
87 fclose(fp);
88 fatalError("ERROR: Could not allocate memory.\n");
89 }
90
91 if (fread(buffer, lSize, 1, fp) != 1)
92 {
93 fclose(fp);
94 free(buffer);
95 fatalError("ERROR: Could not read config file.\n");
96 }
97
98 cJSON* config = cJSON_Parse(buffer);
99
100 fclose(fp);
101 free(buffer);
102
103 return config;
104}
105
68void* extractor(void* userdata) 106void* extractor(void* userdata)
69{ 107{
108 cJSON* config = (cJSON*)userdata;
109
110 WOLFSSL_CTX* sslContext = 0;
111 if (cJSON_HasObjectItem(config, "certificate"))
112 {
113 wolfSSL_Init();
114
115 sslContext = wolfSSL_CTX_new(wolfTLSv1_client_method());
116 if (sslContext == NULL)
117 {
118 fatalError("wolfSSL_CTX_new error.\n");
119 }
120
121 if (wolfSSL_CTX_load_verify_locations(
122 sslContext,
123 cJSON_GetObjectItem(config, "certificate")->valuestring,
124 0) != SSL_SUCCESS)
125 {
126 fatalError("Error loading certificate file.\n");
127 }
128 }
129
130 while (!initializeNetwork())
131 {
132 printf("Could not initialize network.\n");
133 printf("Press A to try again, press B to exit.\n");
134
135 if (waitForButtons(PAD_BUTTON_A | PAD_BUTTON_B) == PAD_BUTTON_B)
136 {
137 endproc();
138 }
139 }
140
70 for (;;) 141 for (;;)
71 { 142 {
72 printmain(); 143 printmain();
@@ -174,6 +245,17 @@ void* extractor(void* userdata)
174 245
175 sendMsg(1); 246 sendMsg(1);
176 247
248 cJSON* root = cJSON_CreateObject();
249
250 cJSON_AddItemToObject(
251 root,
252 "playerName",
253 cJSON_CreateString(d_trainerName));
254
255 cJSON_AddNumberToObject(root, "playerId", trainerId);
256 cJSON_AddNumberToObject(root, "gameId", gameId);
257 cJSON_AddNumberToObject(root, "language", gameLanguage);
258
177 // Get Pokédex data 259 // Get Pokédex data
178 u32 pokedexSeen[13]; 260 u32 pokedexSeen[13];
179 u32 pokedexCaught[13]; 261 u32 pokedexCaught[13];
@@ -208,6 +290,8 @@ void* extractor(void* userdata)
208 290
209 u32 partyCount = getMsg(); 291 u32 partyCount = getMsg();
210 292
293 cJSON* jParty = cJSON_CreateArray();
294
211 for (u32 i = 0; i < partyCount; i++) 295 for (u32 i = 0; i < partyCount; i++)
212 { 296 {
213 usleep(5000); 297 usleep(5000);
@@ -235,22 +319,144 @@ void* extractor(void* userdata)
235 pki->key[5], 319 pki->key[5],
236 pki->key[6]); 320 pki->key[6]);
237 321
238 printf("Species: %d\n", __builtin_bswap16(pki->species)); 322 cJSON* jPoke = cJSON_CreateObject();
239 printf("Nickname: %s\n", d_pokename); 323
240 printf("OT: %s\n", d_otName); 324 cJSON_AddNumberToObject(
241 printf("Level: %d\n", pki->level); 325 jPoke,
242 printf("HP: %ld\n", __builtin_bswap32(pki->hp)); 326 "species",
243 printf("Attack: %ld\n", __builtin_bswap32(pki->attack)); 327 __builtin_bswap16(pki->species));
244 printf("Defense: %ld\n", __builtin_bswap32(pki->defense)); 328
245 printf("Special Attack: %ld\n", __builtin_bswap32(pki->spAttack)); 329 cJSON_AddItemToObject(
246 printf("Special Defense: %ld\n", __builtin_bswap32(pki->spDefense)); 330 jPoke,
247 printf("Speed: %ld\n", __builtin_bswap32(pki->speed)); 331 "nickname",
248 printf("Key: %s\n", d_key); 332 cJSON_CreateString(d_pokename));
249 333
250 printf("\n"); 334 cJSON_AddItemToObject(
335 jPoke,
336 "otName",
337 cJSON_CreateString(d_otName));
338
339 cJSON_AddNumberToObject(
340 jPoke,
341 "otId",
342 __builtin_bswap16(pki->otId));
343
344 cJSON_AddNumberToObject(
345 jPoke,
346 "level",
347 pki->level);
348
349 cJSON_AddNumberToObject(
350 jPoke,
351 "hp",
352 __builtin_bswap32(pki->hp));
353
354 cJSON_AddNumberToObject(
355 jPoke,
356 "attack",
357 __builtin_bswap32(pki->attack));
358
359 cJSON_AddNumberToObject(
360 jPoke,
361 "defense",
362 __builtin_bswap32(pki->defense));
363
364 cJSON_AddNumberToObject(
365 jPoke,
366 "speed",
367 __builtin_bswap32(pki->speed));
368
369 cJSON_AddNumberToObject(
370 jPoke,
371 "spAttack",
372 __builtin_bswap32(pki->spAttack));
373
374 cJSON_AddNumberToObject(
375 jPoke,
376 "spDefense",
377 __builtin_bswap32(pki->spDefense));
378
379 cJSON_AddItemToObject(
380 jPoke,
381 "key",
382 cJSON_CreateString(d_key));
383
384 cJSON_AddNumberToObject(
385 jPoke,
386 "experience",
387 __builtin_bswap32(pki->experience));
388
389 cJSON_AddNumberToObject(
390 jPoke,
391 "heldItem",
392 __builtin_bswap16(pki->heldItem));
393
394 cJSON* jMoves = cJSON_CreateArray();
395
396 for (int j=0; j<4; j++)
397 {
398 if (pki->moves[j] != 0)
399 {
400 cJSON* jMove = cJSON_CreateObject();
401
402 cJSON_AddNumberToObject(
403 jMove,
404 "id",
405 __builtin_bswap16(pki->moves[j]));
406
407 cJSON_AddNumberToObject(
408 jMove,
409 "ppBonuses",
410 (pki->ppBonuses >> (2*j)) & 3);
411
412 cJSON_AddItemToArray(jMoves, jMove);
413 } else {
414 break;
415 }
416 }
417
418 cJSON_AddItemToObject(
419 jPoke,
420 "moves",
421 jMoves);
422
423 if (pki->otGender)
424 {
425 cJSON_AddStringToObject(jPoke, "otGender", "female");
426 } else {
427 cJSON_AddStringToObject(jPoke, "otGender", "male");
428 }
429
430 cJSON_AddNumberToObject(
431 jPoke,
432 "metLevel",
433 pki->metLevel);
434
435 cJSON_AddNumberToObject(
436 jPoke,
437 "metLocation",
438 pki->metLocation);
439
440 cJSON_AddItemToArray(jParty, jPoke);
251 } 441 }
252 442
253 waitForButtons(PAD_BUTTON_START); 443 cJSON_AddItemToObject(root, "party", jParty);
444
445 char *rendered = cJSON_Print(root);
446 printf("%s\n", rendered);
447
448 waitForButtons(PAD_BUTTON_A);
449
450 int result = submitToApi(
451 cJSON_GetObjectItem(config, "url")->valuestring,
452 sslContext,
453 root,
454 cJSON_GetObjectItem(config, "username")->valuestring,
455 cJSON_GetObjectItem(config, "password")->valuestring);
456
457 printf("Result: %d\n", result);
458
459 waitForButtons(PAD_BUTTON_A);
254 } 460 }
255 461
256 return NULL; 462 return NULL;
@@ -276,6 +482,14 @@ int main(int argc, char *argv[])
276 VIDEO_ClearFrameBuffer(rmode, xfb, COLOR_BLACK); 482 VIDEO_ClearFrameBuffer(rmode, xfb, COLOR_BLACK);
277 PAD_Init(); 483 PAD_Init();
278 484
485 if (!fatInitDefault())
486 {
487 printmain();
488 fatalError("ERROR: Cannot find config file!\n");
489 }
490
491 cJSON* config = getConfig();
492
279 initLink(); 493 initLink();
280 494
281 lwp_t extractorHandle = (lwp_t)NULL; 495 lwp_t extractorHandle = (lwp_t)NULL;
@@ -283,7 +497,7 @@ int main(int argc, char *argv[])
283 LWP_CreateThread( 497 LWP_CreateThread(
284 &extractorHandle, // thread handle 498 &extractorHandle, // thread handle
285 extractor, // code 499 extractor, // code
286 NULL, // userdata 500 config, // userdata
287 NULL, // stack base 501 NULL, // stack base
288 16*1024, // stack size 502 16*1024, // stack size
289 LWP_PRIO_HIGHEST); // thread priority 503 LWP_PRIO_HIGHEST); // thread priority