(Mostly) finish QR support

This commit is contained in:
2017-09-04 02:03:58 -04:00
parent 7aed454297
commit 3241544296
4 changed files with 124 additions and 1 deletions

View File

@@ -36,5 +36,6 @@ bool qr_mode;
void init_qr(void); void init_qr(void);
void exit_qr(void); void exit_qr(void);
void take_picture(void); void take_picture(void);
Result http_get(char *url, char *path);
#endif #endif

View File

@@ -27,8 +27,8 @@
#include "camera.h" #include "camera.h"
#include "quirc/quirc.h" #include "quirc/quirc.h"
#include "pp2d/pp2d/pp2d.h"
#include "draw.h" #include "draw.h"
#include "fs.h"
void init_qr(void) void init_qr(void)
{ {
@@ -70,4 +70,122 @@ void take_picture(void)
CAMU_StopCapture(PORT_CAM1); CAMU_StopCapture(PORT_CAM1);
svcCloseHandle(cam_handle); svcCloseHandle(cam_handle);
CAMU_Activate(PORT_NONE); CAMU_Activate(PORT_NONE);
}
/*
Putting this in camera because I'm too lazy to make a network.c
This'll probably get refactored later
*/
Result http_get(char *url, char *path)
{
Result ret;
httpcContext context;
char *new_url = NULL;
u32 status_code;
u32 content_size = 0;
u32 read_size = 0;
u32 size = 0;
u8 *buf;
u8 *last_buf;
do {
ret = httpcOpenContext(&context, HTTPC_METHOD_GET, url, 1);
ret = httpcSetSSLOpt(&context, SSLCOPT_DisableVerify); // should let us do https
ret = httpcSetKeepAlive(&context, HTTPC_KEEPALIVE_ENABLED);
ret = httpcAddRequestHeaderField(&context, "User-Agent", "Anemone3DS/1.1.0");
ret = httpcAddRequestHeaderField(&context, "Connection", "Keep-Alive");
ret = httpcBeginRequest(&context);
if (ret != 0)
{
httpcCloseContext(&context);
if (new_url != NULL) free(new_url);
return ret;
}
ret = httpcGetResponseStatusCode(&context, &status_code);
if(ret!=0){
httpcCloseContext(&context);
if(new_url!=NULL) free(new_url);
return ret;
}
if ((status_code >= 301 && status_code <= 303) || (status_code >= 307 && status_code <= 308))
{
if (new_url == NULL) new_url = malloc(0x1000);
ret = httpcGetResponseHeader(&context, "Location", new_url, 0x1000);
url = new_url;
httpcCloseContext(&context);
}
} while ((status_code >= 301 && status_code <= 303) || (status_code >= 307 && status_code <= 308));
if (status_code != 200)
{
httpcCloseContext(&context);
if (new_url != NULL) free(new_url);
return ret;
}
ret = httpcGetDownloadSizeState(&context, NULL, &content_size);
if (ret != 0)
{
httpcCloseContext(&context);
if (new_url != NULL) free(new_url);
return ret;
}
buf = malloc(0x1000);
if (buf == NULL)
{
httpcCloseContext(&context);
free(new_url);
return -2;
}
char *content_disposition = malloc(1024);
ret = httpcGetResponseHeader(&context, "Content-Disposition", content_disposition, 1024);
if (ret != 0)
{
free(content_disposition);
free(new_url);
free(buf);
}
char *filename;
filename = strtok(content_disposition, "\"");
filename = strtok(NULL, "\"");
do {
ret = httpcDownloadData(&context, buf + size, 0x1000, &read_size);
size += read_size;
if (ret == (s32)HTTPC_RESULTCODE_DOWNLOADPENDING)
{
last_buf = buf;
buf = realloc(buf, size + 0x1000);
if (buf == NULL)
{
httpcCloseContext(&context);
free(last_buf);
return ret;
}
}
} while (ret == (s32)HTTPC_RESULTCODE_DOWNLOADPENDING);
last_buf = buf;
buf = realloc(buf, size);
if (buf == NULL)
{
httpcCloseContext(&context);
free(last_buf);
return -1;
}
char path_to_file[0x106] = {0};
strcpy(path_to_file, path);
strcat(path_to_file, filename);
remake_file(path_to_file, ArchiveSD, size);
buf_to_file(size, path_to_file, ArchiveSD, (char*)buf);
return 0;
} }

View File

@@ -109,6 +109,8 @@ void draw_qr(void)
if (!quirc_decode(&code, &data)) if (!quirc_decode(&code, &data))
{ {
qr_mode = false; qr_mode = false;
http_get((char*)data.payload, "/Themes/");
} }
} }
} }

View File

@@ -38,6 +38,7 @@ int init_services(void)
{ {
cfguInit(); cfguInit();
ptmuInit(); ptmuInit();
httpcInit(0);
open_archives(); open_archives();
bool homebrew = true; bool homebrew = true;
if (!envIsHomebrew()) if (!envIsHomebrew())
@@ -59,6 +60,7 @@ int exit_services(void)
close_archives(); close_archives();
cfguExit(); cfguExit();
ptmuExit(); ptmuExit();
httpcExit();
return 0; return 0;
} }