Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <stdio.h>
- #include <stdlib.h>
- #include <stdint.h>
- #include <fcntl.h>
- #include <string.h>
- #include <errno.h>
- #include <unistd.h>
- #include <sys/types.h>
- #include <sys/stat.h>
- #define SECTOR_ALIGNMENT 512
- #define TRWIFI_FILE_PATH "/mnt/sd/ML/DATA/TRWIFI/"
- int http_get_url(char *url_in, char *data, uint32_t max_len, uint32_t *data_len);
- 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";
- /* return the number of bytes to read, aligned to sector sizes (needed for O_DIRECT) */
- uint32_t sector_align(uint32_t size)
- {
- return ((size + SECTOR_ALIGNMENT) & ~(SECTOR_ALIGNMENT-1));
- }
- /* split fields at colons */
- void split_command(char *line, char **cmd, uint32_t *size)
- {
- int pos = 0;
- int field = 0;
- /* init, just in case */
- *cmd = NULL;
- *size = 0;
- /* go over all fields and replace ':' with string terminators */
- for(pos = 0; pos < strlen(line); pos++)
- {
- if(line[pos] == ':')
- {
- field++;
- line[pos] = '\000';
- /* the second field contains payload size */
- if(field == 1)
- {
- *size = atoi(&line[pos + 1]);
- }
- }
- }
- *cmd = line;
- }
- void command_http_get(char *cmd_buf, uint32_t cmd_len, char *res_buf, uint32_t res_len, char *data_buf, uint32_t data_len)
- {
- uint32_t received = 0;
- int ret = http_get_url(cmd_buf, data_buf, data_len, &received);
- if(!ret)
- {
- sprintf(res_buf, "DATA:%d:", received);
- printf("command_http_get: res_buf: '%s'", res_buf);
- }
- else
- {
- sprintf(res_buf, "DATA:0:");
- printf("command_http_get: returned %d", ret);
- }
- }
- void command_exec(char *cmd_buf, uint32_t cmd_len, char *res_buf, uint32_t res_len, char *data_buf, uint32_t data_len)
- {
- FILE *fp = NULL;
- char *command = malloc(cmd_len + 1);
- strncpy(command, cmd_buf, cmd_len);
- command[cmd_len] = '\000';
- printf("[CMD] EXEC '%s'\n", command);
- /* Open the command for reading. */
- fp = popen(command, "r");
- if(fp == NULL)
- {
- printf("command_exec: Failed to run command '%s'\n", command);
- sprintf(data_buf, "Failed to run command '%s'\n", command);
- sprintf(res_buf, "DATA:%d:", strlen(data_buf));
- free(command);
- return;
- }
- /* Read the output a line at a time - output it. */
- uint32_t pos = 0;
- while(1)
- {
- uint32_t remain = data_len - pos;
- size_t ret = fread(&data_buf[pos], 1, remain, fp);
- if(ret > 0)
- {
- printf("command_exec: read: '%s'", &data_buf[pos]);
- pos += ret;
- }
- if(feof(fp) || ferror(fp))
- {
- printf("command_exec: read: failed");
- break;
- }
- /* if remain is zero and there is still data, we cannot do anything about that */
- if(!remain)
- {
- printf("command_exec: read: buffer too small");
- break;
- }
- }
- free(command);
- sprintf(res_buf, "DATA:%d:", pos);
- printf("command_exec: res_buf: '%s'", res_buf);
- pclose(fp);
- }
- void command_status(char *res_buf, uint32_t res_len, char *data_buf, uint32_t data_len)
- {
- printf("[CMD] STATUS\n");
- strcpy(data_buf, "I am fine, thanks.");
- strcpy(res_buf, "READY:0:");
- }
- int main(int argc, char *argv[])
- {
- uint32_t sleep_time = 100000;
- uint32_t timeouts = 0;
- uint32_t do_restart = 0;
- uint32_t done = 0;
- static char sd_res_buf[SECTOR_ALIGNMENT] __attribute__ ((__aligned__ (SECTOR_ALIGNMENT)));
- static char sd_data_buf[2 * 1024 * 1024] __attribute__ ((__aligned__ (SECTOR_ALIGNMENT)));
- static char ml_cmd_buf_in[SECTOR_ALIGNMENT] __attribute__ ((__aligned__ (SECTOR_ALIGNMENT)));
- static char ml_cmd_buf_out[SECTOR_ALIGNMENT] __attribute__ ((__aligned__ (SECTOR_ALIGNMENT)));
- static char ml_data_buf[2 * 1024 * 1024] __attribute__ ((__aligned__ (SECTOR_ALIGNMENT)));
- int sd_res_fd = -1;
- int sd_data_fd = -1;
- int ml_cmd_fd = -1;
- int ml_data_fd = -1;
- printf("Starting tr_wifi daemon\n");
- restart:
- sd_res_fd = open(sd_res_file, O_DIRECT | O_NOATIME | O_WRONLY | O_SYNC | O_DSYNC);
- sd_data_fd = open(sd_data_file, O_DIRECT | O_NOATIME | O_WRONLY | O_SYNC | O_DSYNC);
- ml_cmd_fd = open(ml_cmd_file, O_DIRECT | O_NOATIME | O_RDWR | O_SYNC | O_DSYNC);
- ml_data_fd = open(ml_data_file, O_DIRECT | O_NOATIME | O_RDONLY | O_SYNC | O_DSYNC);
- /* check if files could be opened */
- if(sd_res_fd == -1)
- {
- printf("Failed to open '%s'\n", sd_res_file);
- do_restart = 1;
- }
- if(sd_data_fd == -1)
- {
- printf("Failed to open '%s'\n", sd_data_file);
- do_restart = 1;
- }
- if(ml_cmd_fd == -1)
- {
- printf("Failed to open '%s'\n", ml_cmd_file);
- do_restart = 1;
- }
- if(ml_data_fd == -1)
- {
- printf("Failed to open '%s'\n", ml_data_file);
- do_restart = 1;
- }
- while(!done && !do_restart)
- {
- /* flush all buffers and read the command */
- sync();
- fsync(ml_cmd_fd);
- lseek(ml_cmd_fd, 0, SEEK_SET);
- ssize_t bytes_read = read(ml_cmd_fd, ml_cmd_buf_in, sizeof(ml_cmd_buf_in));
- /* if reading the command file failed, try to restart the daemon after a small relay */
- if(bytes_read <= 0)
- {
- printf("READ: %d, errno: %d\n", bytes_read, errno);
- do_restart = 1;
- break;
- }
- else if(strlen(ml_cmd_buf_in) == 0)
- {
- timeouts++;
- }
- else
- {
- /* reset command */
- strcpy(ml_cmd_buf_out, "");
- lseek(ml_cmd_fd, 0, SEEK_SET);
- write(ml_cmd_fd, ml_cmd_buf_out, sizeof(ml_cmd_buf_out));
- fsync(ml_cmd_fd);
- sync();
- printf("READ: '%s'\n", ml_cmd_buf_in);
- /* now try to parse the command */
- char *cmd = NULL;
- uint32_t size = 0;
- /* split in command and payload size */
- split_command(ml_cmd_buf_in, &cmd, &size);
- /* if there is payload, try to read */
- if(size)
- {
- uint32_t read_count = sector_align(size);
- /* as we use O_DIRECT, we can only read multiple of SECTOR_ALIGNMENT bytes (512 for kernel 2.6) */
- if(read_count < sizeof(ml_data_buf))
- {
- fsync(ml_data_fd);
- lseek(ml_data_fd, 0, SEEK_SET);
- ssize_t data_read = read(ml_data_fd, ml_data_buf, read_count);
- if(data_read < read_count)
- {
- printf("READ PARAM: %d/%d read (real: %d)\n", data_read, read_count, size);
- size = 0;
- }
- }
- else
- {
- printf("READ PARAM: %d > %d, so abort read (real: %d)\n", read_count, sizeof(ml_data_buf), size);
- size = 0;
- }
- }
- if(!strcmp(cmd, "EXEC"))
- {
- command_exec(ml_data_buf, size, sd_res_buf, sizeof(sd_res_buf), sd_data_buf, sizeof(sd_data_buf));
- }
- else if(!strcmp(cmd, "HTTP_GET"))
- {
- command_http_get(ml_data_buf, size, sd_res_buf, sizeof(sd_res_buf), sd_data_buf, sizeof(sd_data_buf));
- }
- else if(!strcmp(cmd, "STATUS"))
- {
- command_status(sd_res_buf, sizeof(sd_res_buf), sd_data_buf, sizeof(sd_data_buf));
- }
- else if(!strcmp(cmd, "EXIT"))
- {
- strcpy(sd_data_buf, "");
- strcpy(sd_res_buf, "TERMINATED:0:");
- done = 1;
- }
- else
- {
- strcpy(sd_data_buf, "");
- strcpy(sd_res_buf, "READY:0:");
- }
- /* ok the command (whatever it was) finished, now write back the response/data */
- lseek(sd_data_fd, 0, SEEK_SET);
- lseek(sd_res_fd, 0, SEEK_SET);
- write(sd_data_fd, sd_data_buf, sizeof(sd_data_buf));
- write(sd_res_fd, sd_res_buf, sizeof(sd_res_buf));
- fsync(sd_data_fd);
- fsync(sd_res_fd);
- sync();
- }
- /* if there was no command lately, sleep a bit longer */
- if(timeouts > 100)
- {
- sleep_time = 250000;
- }
- else
- {
- sleep_time = 50000;
- }
- usleep(sleep_time);
- }
- /* something failed, try to restart */
- if(do_restart)
- {
- sleep(1);
- close(sd_res_fd);
- close(sd_data_fd);
- close(ml_cmd_fd);
- close(ml_data_fd);
- printf("Restarting tr_wifi daemon\n");
- goto restart;
- }
- return 0;
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement