Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <module.h>
- #include <dryos.h>
- #include <bmp.h>
- #include <menu.h>
- #include <../ime_base/ime_base.h>
- #define TRWIFI_LETTER "B:/"
- #define TRWIFI_FILE_PATH TRWIFI_LETTER "ML/DATA/TRWIFI/"
- /* those are the hardcoded communication file sizes. all must be a multiple of 512 byte (linux, sector size etc) */
- #define ML_CMD_SIZE 512
- #define SD_RES_SIZE 512
- #define ML_DATA_SIZE 1*1024*1024
- #define SD_DATA_SIZE 10*1024*1024
- /* for tracking the card's current state */
- #define STATUS_UNKNOWN 0
- #define STATUS_READY 1
- #define STATUS_DATA 2
- #define STATUS_BUSY 3
- #define STATUS_NOT_RUNNING 4
- /* all needed scripts are embedded */
- extern char _binary_DATA_busybox_size;
- extern char _binary_DATA_busybox_start;
- extern char _binary_DATA_s_trwifi_sh_size;
- extern char _binary_DATA_s_trwifi_sh_start;
- extern char _binary_DATA_s_inetd_sh_size;
- extern char _binary_DATA_s_inetd_sh_start;
- extern char _binary_tr_daemon_daemon_start;
- extern char _binary_tr_daemon_daemon_size;
- /* file path is hardcoded */
- static char *file_autorun = TRWIFI_LETTER "autorun.sh";
- static char *file_busybox = TRWIFI_LETTER "busybox.bin";
- /* these are the scripts we copy, they wont change */
- static char *file_trwifi = TRWIFI_FILE_PATH "EXEC/S_TRWIFI.SH";
- static char *file_inetd = TRWIFI_FILE_PATH "EXEC/S_INETD.SH";
- static char *file_daemon = TRWIFI_FILE_PATH "EXEC/DAEMON.BIN";
- static char *sd_res_file = TRWIFI_FILE_PATH "COMM/SD_RES.DAT";
- static char *sd_data_file = TRWIFI_FILE_PATH "COMM/SD_DATA.DAT";
- static char *ml_cmd_file = TRWIFI_FILE_PATH "COMM/ML_CMD.DAT";
- static char *ml_data_file = TRWIFI_FILE_PATH "COMM/ML_DATA.DAT";
- static uint32_t trwifi_status = STATUS_NOT_RUNNING;
- static uint32_t trwifi_enabled = 0;
- struct msg_queue *trwifi_cmd_queue = NULL;
- typedef struct
- {
- void (*cbr)(void *ctx, char *ret, uint32_t size);
- void *ctx;
- char cmd;
- } trwifi_cmd_t;
- static char trwifi_shell_cmd[64];
- /* ensure that given file exists and has specified size */
- static void trwifi_prepare_file(char* file, uint32_t size)
- {
- uint32_t file_size;
- if((FIO_GetFileSize( file, &file_size ) == 0) && (file_size == size))
- {
- return;
- }
- /* file does not exist or has wrong size */
- FIO_RemoveFile(file);
- FILE *f = FIO_CreateFileEx(file);
- if (f == INVALID_PTR)
- {
- return;
- }
- FIO_SeekFile(f, size - 1, SEEK_SET);
- if(FIO_WriteFile(f, "\000", 1) != 1)
- {
- FIO_CloseFile(f);
- beep();
- bmp_printf(FONT_MED, 0, 400, "Failed to write '%s'. Please run CHKDSK.", file);
- return;
- }
- FIO_CloseFile(f);
- }
- /* this routine is to write data without resizing file */
- static uint32_t trwifi_write(char *file, char *data, uint32_t length)
- {
- if(!length)
- {
- length = strlen(data) + 1;
- }
- FILE* f = FIO_Open(file, O_WRONLY | O_SYNC);
- if(f == INVALID_PTR)
- {
- beep();
- bmp_printf(FONT_MED, 0, 400, "Failed to open '%s'", file);
- return 1;
- }
- FIO_SeekFile(f, 0, SEEK_SET);
- if(FIO_WriteFile(f, data, length) != length)
- {
- FIO_CloseFile(f);
- beep();
- bmp_printf(FONT_MED, 0, 400, "Failed to write '%s'", file);
- return 2;
- }
- FIO_CloseFile(f);
- return 0;
- }
- static void trwifi_process_http_get_file(char *file, char *data_buf, uint32_t data_size)
- {
- uint32_t time = get_ms_clock_value();
- while(get_ms_clock_value() - time < 2000)
- {
- bmp_printf(FONT_MED, 20, 140, "FILE: '%s'", file);
- bmp_printf(FONT_MED, 20, 160, "DATA: %d bytes", data_size);
- }
- FILE * f = NULL;
- f = FIO_CreateFileEx(file);
- if (f != (void*) -1)
- {
- FIO_WriteFile(f, data_buf, data_size);
- FIO_CloseFile(f);
- }
- }
- static void trwifi_process_http_get_data(void *ctx, char *data_buf, uint32_t data_size)
- {
- void (*cbr)(void *ctx, char *data, uint32_t length) = ctx;
- cbr(NULL, data_buf, data_size);
- }
- static void trwifi_process_data(void *ctx, char *data_buf, uint32_t data_size)
- {
- uint32_t time = get_ms_clock_value();
- while(get_ms_clock_value() - time < 2000)
- {
- bmp_printf(FONT_MED, 20, 140, "DATA: '%s'", data_buf);
- }
- }
- static void trwifi_write_cmd(char *cmd, void (*cbr)(void *ctx, char *ret, uint32_t size), void *ctx)
- {
- trwifi_cmd_t *req = malloc(strlen(cmd) + sizeof(trwifi_cmd_t) - 1);
- req->cbr = cbr;
- req->ctx = ctx;
- strcpy(&req->cmd, cmd);
- msg_queue_post(trwifi_cmd_queue, req);
- }
- static void trwifi_thread(uint32_t unused)
- {
- trwifi_cmd_t *current_cmd = NULL;
- uint32_t timeout = 200;
- uint32_t last_comm_time = get_ms_clock_value();
- uint32_t card_alive = 0;
- trwifi_status = STATUS_UNKNOWN;
- /* this loop will exit as soon the current msleep returns */
- while(trwifi_enabled)
- {
- char status[SD_RES_SIZE+1];
- char *size = NULL;
- status[SD_RES_SIZE] = '\000';
- uint32_t last_comm = get_ms_clock_value() - last_comm_time;
- if(last_comm > 30000 && !card_alive)
- {
- beep();
- NotifyBox(5000, "Transcend WiFi-SD does not respond, exiting");
- break;
- }
- /* no communication the last 10 seconds -> read status every 5 seconds. might change when communication is bidirectional (wlan remote?) */
- if(last_comm > 10000)
- {
- timeout = 5000;
- }
- else
- {
- /* there has been communication lately, so poll a bit faster */
- timeout = 100;
- }
- /* if there is no current command, fetch and write the command to command file */
- if(!current_cmd)
- {
- if(!msg_queue_receive(trwifi_cmd_queue, (trwifi_cmd_t **)¤t_cmd, timeout))
- {
- trwifi_write(sd_res_file, "BUSY:0:", 0);
- trwifi_write(ml_cmd_file, ¤t_cmd->cmd, 0);
- last_comm_time = get_ms_clock_value();
- }
- }
- else
- {
- /* if there is a command pending, fetch every 100 msec */
- msleep(100);
- }
- /* now read the card's response */
- FILE* f = FIO_Open(sd_res_file, O_RDONLY | O_SYNC);
- if (f == INVALID_PTR)
- {
- beep();
- bmp_printf(FONT_MED, 0, 400, "Failed to open '%s'", sd_res_file);
- break;
- }
- if(FIO_ReadFile(f, status, SD_RES_SIZE) != SD_RES_SIZE)
- {
- FIO_CloseFile(f);
- beep();
- bmp_printf(FONT_MED, 0, 400, "Failed to read '%s'", sd_res_file);
- break;
- }
- FIO_CloseFile(f);
- /* split fields at colons and terminate every element */
- uint32_t field = 0;
- int32_t data_size = 0;
- for(int pos = 0; pos < sizeof(status); pos++)
- {
- if(status[pos] == ':')
- {
- field++;
- status[pos] = '\000';
- if(field == 1)
- {
- size = &status[pos + 1];
- data_size = atoi(size);
- }
- }
- }
- /* whats the current response? BUSY is set by us, so its the most likely response after a command was sent */
- if(!strcmp(status, "BUSY"))
- {
- trwifi_status = STATUS_BUSY;
- }
- else if(!strcmp(status, "DATA"))
- {
- trwifi_status = STATUS_DATA;
- last_comm_time = get_ms_clock_value();
- /* some sanity checks, don't to anything if there is invalid data size */
- if(data_size > 0 && data_size <= SD_DATA_SIZE)
- {
- char *data_buf = malloc(data_size + 1);
- FILE* data_fd = FIO_Open(sd_data_file, O_RDONLY | O_SYNC);
- if(data_fd == INVALID_PTR)
- {
- beep();
- free(data_buf);
- bmp_printf(FONT_MED, 0, 400, "Failed to open '%s'", sd_data_file);
- return;
- }
- if(FIO_ReadFile(data_fd, data_buf, data_size) != data_size)
- {
- FIO_CloseFile(data_fd);
- free(data_buf);
- beep();
- bmp_printf(FONT_MED, 0, 400, "Failed to read '%s'", sd_data_file);
- return;
- }
- FIO_CloseFile(data_fd);
- /* there is for sure someone who directly prints the string (and it isn't null terminated), so terminate it just to make sure ;) */
- data_buf[data_size] = '\000';
- /* when there was a command pending, inform it about the DATA state by calling with received data */
- if(current_cmd)
- {
- current_cmd->cbr(current_cmd->ctx, data_buf, data_size);
- free(current_cmd);
- current_cmd = NULL;
- }
- else
- {
- beep();
- bmp_printf(FONT_MED, 0, 400, "Card sent us data, but we didn't request anything?");
- }
- free(data_buf);
- }
- else
- {
- /* when there was a command pending, call with no data which signals that the command is finished */
- if(current_cmd)
- {
- current_cmd->cbr(current_cmd->ctx, NULL, 0);
- free(current_cmd);
- current_cmd = NULL;
- }
- }
- /* reset state and request state again */
- trwifi_write(sd_res_file, "BUSY:0:", 0);
- trwifi_write(ml_cmd_file, "STATUS:0:", 0);
- }
- else if(!strcmp(status, "READY"))
- {
- trwifi_status = STATUS_READY;
- /* the first time inform the user about the card being ready. have to do it the other way around */
- if(!card_alive)
- {
- card_alive = 1;
- beep();
- NotifyBox(500, "Transcend WiFi-SD is ready");
- }
- /* when there was a command pending, inform it about the READY state */
- if(current_cmd)
- {
- current_cmd->cbr(current_cmd->ctx, NULL, 0);
- free(current_cmd);
- current_cmd = NULL;
- }
- }
- else if(!strcmp(status, "UNKNOWN"))
- {
- trwifi_status = STATUS_UNKNOWN;
- }
- }
- trwifi_status = STATUS_NOT_RUNNING;
- trwifi_enabled = 0;
- }
- /* download url to the file specified */
- int32_t net_get_file(char *url, char *dst_file)
- {
- char command[32];
- snprintf(command, sizeof(command), "HTTP_GET:%d:", strlen(url));
- trwifi_write(ml_data_file, url, 0);
- trwifi_write_cmd(command, &trwifi_process_http_get_file, dst_file);
- return NULL;
- }
- /* download url and call back */
- int32_t net_get_data(char *url, void (*cbr)(void *ctx, char *data, uint32_t length))
- {
- char command[32];
- snprintf(command, sizeof(command), "HTTP_GET:%d:", strlen(url));
- trwifi_write(ml_data_file, url, 0);
- trwifi_write_cmd(command, &trwifi_process_http_get_data, cbr);
- return NULL;
- }
- /* execute a command on card and return buffer with returned string - to be freed using free() */
- char *trwifi_exec(char *cmd)
- {
- char command[32];
- snprintf(command, sizeof(command), "EXEC:%d:", strlen(cmd));
- trwifi_write(ml_data_file, cmd, 0);
- trwifi_write_cmd(command, &trwifi_process_data, NULL);
- return NULL;
- }
- static MENU_SELECT_FUNC(trwifi_start_select)
- {
- if(!trwifi_enabled)
- {
- trwifi_enabled = 1;
- task_create("TRWIFI", 0x1C, 0x1000, &trwifi_thread, NULL);
- }
- else
- {
- trwifi_enabled = 0;
- }
- }
- static MENU_SELECT_FUNC(trwifi_check_select)
- {
- trwifi_exec("mount");
- }
- static IME_DONE_FUNC(ime_base_test_done)
- {
- char command[32];
- snprintf(command, sizeof(command), "EXEC:%d:", strlen(trwifi_shell_cmd));
- trwifi_write(ml_data_file, trwifi_shell_cmd, 0);
- trwifi_write_cmd(command, &trwifi_process_data, NULL);
- return IME_OK;
- }
- static MENU_SELECT_FUNC(trwifi_exec_select)
- {
- strcpy(trwifi_shell_cmd, "");
- ime_base_start("Shell command", trwifi_shell_cmd, sizeof(trwifi_shell_cmd), IME_UTF8, IME_CHARSET_ANY, NULL, &ime_base_test_done, 0, 0, 0, 0);
- }
- /* Installation part */
- static uint32_t trwifi_file_exists(char *file)
- {
- uint32_t file_size;
- if(FIO_GetFileSize( file, &file_size ) == 0)
- {
- return 1;
- }
- return 0;
- }
- static void trwifi_install_file(char *file, char *data, uint32_t length)
- {
- FIO_RemoveFile(file);
- FILE *f = FIO_CreateFileEx(file);
- if (f == INVALID_PTR)
- {
- return;
- }
- if(FIO_WriteFile(f, data, length) != length)
- {
- FIO_CloseFile(f);
- beep();
- bmp_printf(FONT_MED, 0, 400, "Failed to write '%s'", file);
- return;
- }
- FIO_CloseFile(f);
- }
- static void trwifi_uninstall_file(char *file)
- {
- FIO_RemoveFile(file);
- }
- static void trwifi_install_files()
- {
- FIO_CreateDirectory(TRWIFI_FILE_PATH);
- //trwifi_install_file(file_autorun, &_binary_DATA_autorun_sh_start, &_binary_DATA_autorun_sh_size);
- //trwifi_install_file(file_busybox, &_binary_DATA_busybox_start, _binary_DATA_busybox_size);
- trwifi_install_file(file_daemon, &_binary_tr_daemon_daemon_start, (int)&_binary_tr_daemon_daemon_size);
- trwifi_install_file(file_trwifi, &_binary_DATA_s_trwifi_sh_start, (int)&_binary_DATA_s_trwifi_sh_size);
- trwifi_install_file(file_inetd, &_binary_DATA_s_inetd_sh_start, (int)&_binary_DATA_s_inetd_sh_size);
- }
- static void trwifi_uninstall_files()
- {
- //trwifi_uninstall_file(file_autorun);
- //trwifi_uninstall_file(file_busybox);
- trwifi_uninstall_file(file_daemon);
- trwifi_uninstall_file(file_trwifi);
- trwifi_uninstall_file(file_inetd);
- }
- static void trwifi_install_status(uint32_t *missing, uint32_t *existing)
- {
- //*missing |= !trwifi_file_exists(file_autorun);
- //*missing |= !trwifi_file_exists(file_busybox);
- *missing |= !trwifi_file_exists(file_daemon);
- *missing |= !trwifi_file_exists(file_trwifi);
- *missing |= !trwifi_file_exists(file_inetd);
- //*existing |= trwifi_file_exists(file_autorun);
- //*existing |= trwifi_file_exists(file_busybox);
- *existing |= trwifi_file_exists(file_daemon);
- *existing |= trwifi_file_exists(file_trwifi);
- *existing |= trwifi_file_exists(file_inetd);
- }
- static MENU_UPDATE_FUNC(trwifi_start_update)
- {
- uint32_t missing = 0;
- uint32_t existing = 0;
- trwifi_install_status(&missing, &existing);
- if(!missing)
- {
- if(trwifi_enabled)
- {
- MENU_SET_NAME("Stop daemon");
- MENU_SET_WARNING(MENU_WARN_INFO, "Already starting..." );
- }
- else
- {
- MENU_SET_WARNING(MENU_WARN_INFO, "Scripts seem to be installed, ready to start daemon." );
- }
- }
- else if(existing && missing)
- {
- MENU_SET_WARNING(MENU_WARN_NOT_WORKING, "Scripts are partially missing. Please reinstall." );
- }
- else
- {
- MENU_SET_WARNING(MENU_WARN_NOT_WORKING, "Scripts are missing. Please install." );
- }
- }
- static MENU_UPDATE_FUNC(trwifi_check_update)
- {
- if(trwifi_status == STATUS_READY)
- {
- MENU_SET_WARNING(MENU_WARN_INFO, "Card seems to be up and ready for commands." );
- }
- else
- {
- MENU_SET_WARNING(MENU_WARN_NOT_WORKING, "Either daemon was not started or card isn't perepared." );
- }
- }
- static MENU_UPDATE_FUNC(trwifi_exec_update)
- {
- if(trwifi_status == STATUS_READY)
- {
- MENU_SET_WARNING(MENU_WARN_INFO, "Card seems to be up and ready for commands." );
- }
- else
- {
- MENU_SET_WARNING(MENU_WARN_NOT_WORKING, "Either daemon was not started or card isn't perepared." );
- }
- }
- static MENU_UPDATE_FUNC(trwifi_install_update)
- {
- uint32_t missing = 0;
- uint32_t existing = 0;
- trwifi_install_status(&missing, &existing);
- if(existing && missing)
- {
- MENU_SET_NAME("Remove Scripts");
- MENU_SET_WARNING(MENU_WARN_ADVICE, "Scripts partially installed, click to remove them." );
- }
- else if(existing)
- {
- MENU_SET_NAME("Remove Scripts");
- MENU_SET_WARNING(MENU_WARN_ADVICE, "Scripts are installed, click to remove them." );
- }
- else
- {
- MENU_SET_NAME("Install Scripts");
- MENU_SET_WARNING(MENU_WARN_ADVICE, "Click to install Transcend Wifi scripts." );
- }
- }
- static MENU_SELECT_FUNC(trwifi_install_select)
- {
- uint32_t missing = 0;
- uint32_t existing = 0;
- trwifi_install_status(&missing, &existing);
- if(existing)
- {
- trwifi_uninstall_files();
- }
- else
- {
- trwifi_install_files();
- NotifyBox(100000, "Installed scripts, please repower camera.");
- }
- }
- static MENU_SELECT_FUNC(trwifi_http_test_select)
- {
- net_get_file("http://upload.g3gg0.de/pub_files/bc3ccd38fe8807eabc7e73cb036fb4ba/data.txt", "B:/TEST.GET");
- }
- static struct menu_entry trwifi_menu[] =
- {
- {
- .name = "Transcend WiFi-SD",
- .help = "",
- .submenu_width = 710,
- .children = (struct menu_entry[])
- {
- {
- .name = "Start daemon",
- .select = &trwifi_start_select,
- .update = &trwifi_start_update,
- },
- {
- .name = "Install scripts",
- .select = &trwifi_install_select,
- .update = &trwifi_install_update,
- },
- {
- .name = "Check status",
- .select = &trwifi_check_select,
- .update = &trwifi_check_update,
- },
- {
- .name = "HTTP test",
- .select = &trwifi_http_test_select,
- },
- {
- .name = "Enter shell command",
- .select = &trwifi_exec_select,
- .update = &trwifi_exec_update,
- },
- MENU_EOL,
- },
- },
- };
- static unsigned int trwifi_init()
- {
- trwifi_cmd_queue = (struct msg_queue *) msg_queue_create("trwifi_cmd_queue", 100);
- trwifi_install_files();
- /* create the communication files */
- trwifi_prepare_file(sd_res_file, SD_RES_SIZE);
- trwifi_prepare_file(ml_cmd_file, ML_CMD_SIZE);
- trwifi_prepare_file(ml_data_file, ML_DATA_SIZE);
- trwifi_prepare_file(sd_data_file, SD_DATA_SIZE);
- /* init to UNKNOWN state and request a status update from card */
- trwifi_write(sd_res_file, "UNKNOWN:0:", 0);
- trwifi_write(ml_cmd_file, "STATUS:0:", 0);
- trwifi_enabled = 1;
- task_create("TRWIFI", 0x1C, 0x1000, &trwifi_thread, NULL);
- /* still need to find a suitable menu */
- menu_add("Audio", trwifi_menu, COUNT(trwifi_menu));
- return 0;
- }
- static unsigned int trwifi_deinit()
- {
- return 0;
- }
- MODULE_INFO_START()
- MODULE_INIT(trwifi_init)
- MODULE_DEINIT(trwifi_deinit)
- MODULE_INFO_END()
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement