Advertisement
Guest User

Untitled

a guest
Oct 28th, 2014
48
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 9.38 KB | None | 0 0
  1.  
  2. #include <stdio.h>
  3. #include <stdlib.h>
  4. #include <stdint.h>
  5. #include <fcntl.h>
  6. #include <string.h>
  7. #include <errno.h>
  8. #include <unistd.h>
  9. #include <sys/types.h>
  10. #include <sys/stat.h>
  11.  
  12. #define SECTOR_ALIGNMENT 512
  13. #define TRWIFI_FILE_PATH "/mnt/sd/ML/DATA/TRWIFI/"
  14.  
  15. int http_get_url(char *url_in, char *data, uint32_t max_len, uint32_t *data_len);
  16.  
  17.  
  18. static char *sd_res_file = TRWIFI_FILE_PATH "COMM/SD_RES.DAT";
  19. static char *sd_data_file = TRWIFI_FILE_PATH "COMM/SD_DATA.DAT";
  20. static char *ml_cmd_file = TRWIFI_FILE_PATH "COMM/ML_CMD.DAT";
  21. static char *ml_data_file = TRWIFI_FILE_PATH "COMM/ML_DATA.DAT";
  22.  
  23. /* return the number of bytes to read, aligned to sector sizes (needed for O_DIRECT) */
  24. uint32_t sector_align(uint32_t size)
  25. {
  26.     return ((size + SECTOR_ALIGNMENT) & ~(SECTOR_ALIGNMENT-1));
  27. }
  28.  
  29. /* split fields at colons */
  30. void split_command(char *line, char **cmd, uint32_t *size)
  31. {
  32.     int pos = 0;
  33.     int field = 0;
  34.    
  35.     /* init, just in case */
  36.     *cmd = NULL;
  37.     *size = 0;
  38.    
  39.     /* go over all fields and replace ':' with string terminators */
  40.     for(pos = 0; pos < strlen(line); pos++)
  41.     {
  42.         if(line[pos] == ':')
  43.         {
  44.             field++;
  45.             line[pos] = '\000';
  46.            
  47.             /* the second field contains payload size */
  48.             if(field == 1)
  49.             {
  50.                 *size = atoi(&line[pos + 1]);
  51.             }
  52.         }
  53.     }
  54.    
  55.     *cmd = line;
  56. }
  57.  
  58. 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)
  59. {
  60.     uint32_t received = 0;
  61.     int ret = http_get_url(cmd_buf, data_buf, data_len, &received);
  62.    
  63.     if(!ret)
  64.     {
  65.         sprintf(res_buf, "DATA:%d:", received);
  66.         printf("command_http_get: res_buf: '%s'", res_buf);
  67.     }
  68.     else
  69.     {
  70.         sprintf(res_buf, "DATA:0:");
  71.         printf("command_http_get: returned %d", ret);
  72.     }
  73. }
  74.  
  75. void command_exec(char *cmd_buf, uint32_t cmd_len, char *res_buf, uint32_t res_len, char *data_buf, uint32_t data_len)
  76. {
  77.     FILE *fp = NULL;
  78.     char *command = malloc(cmd_len + 1);
  79.     strncpy(command, cmd_buf, cmd_len);
  80.     command[cmd_len] = '\000';
  81.    
  82.     printf("[CMD] EXEC '%s'\n", command);
  83.    
  84.     /* Open the command for reading. */
  85.     fp = popen(command, "r");
  86.     if(fp == NULL)
  87.     {
  88.         printf("command_exec: Failed to run command '%s'\n", command);
  89.         sprintf(data_buf, "Failed to run command '%s'\n", command);
  90.         sprintf(res_buf, "DATA:%d:", strlen(data_buf));
  91.         free(command);
  92.         return;
  93.     }
  94.  
  95.     /* Read the output a line at a time - output it. */
  96.     uint32_t pos = 0;
  97.     while(1)
  98.     {
  99.         uint32_t remain = data_len - pos;
  100.         size_t ret = fread(&data_buf[pos], 1, remain, fp);
  101.        
  102.         if(ret > 0)
  103.         {
  104.             printf("command_exec: read: '%s'", &data_buf[pos]);
  105.             pos += ret;
  106.         }
  107.        
  108.         if(feof(fp) || ferror(fp))
  109.         {
  110.             printf("command_exec: read: failed");
  111.             break;
  112.         }
  113.        
  114.         /* if remain is zero and there is still data, we cannot do anything about that */
  115.         if(!remain)
  116.         {
  117.             printf("command_exec: read: buffer too small");
  118.             break;
  119.         }
  120.     }
  121.  
  122.     free(command);
  123.    
  124.     sprintf(res_buf, "DATA:%d:", pos);
  125.     printf("command_exec: res_buf: '%s'", res_buf);
  126.    
  127.     pclose(fp);
  128. }
  129.  
  130.  
  131. void command_status(char *res_buf, uint32_t res_len, char *data_buf, uint32_t data_len)
  132. {
  133.     printf("[CMD] STATUS\n");
  134.    
  135.     strcpy(data_buf, "I am fine, thanks.");
  136.     strcpy(res_buf, "READY:0:");
  137. }
  138.  
  139. int main(int argc, char *argv[])
  140. {
  141.     uint32_t sleep_time = 100000;
  142.     uint32_t timeouts = 0;
  143.     uint32_t do_restart = 0;
  144.     uint32_t done = 0;
  145.    
  146.     static char sd_res_buf[SECTOR_ALIGNMENT] __attribute__ ((__aligned__ (SECTOR_ALIGNMENT)));
  147.     static char sd_data_buf[2 * 1024 * 1024] __attribute__ ((__aligned__ (SECTOR_ALIGNMENT)));
  148.     static char ml_cmd_buf_in[SECTOR_ALIGNMENT] __attribute__ ((__aligned__ (SECTOR_ALIGNMENT)));
  149.     static char ml_cmd_buf_out[SECTOR_ALIGNMENT] __attribute__ ((__aligned__ (SECTOR_ALIGNMENT)));
  150.     static char ml_data_buf[2 * 1024 * 1024] __attribute__ ((__aligned__ (SECTOR_ALIGNMENT)));
  151.    
  152.     int sd_res_fd = -1;
  153.     int sd_data_fd = -1;
  154.     int ml_cmd_fd = -1;
  155.     int ml_data_fd = -1;
  156.    
  157.     printf("Starting tr_wifi daemon\n");
  158. restart:
  159.    
  160.     sd_res_fd = open(sd_res_file, O_DIRECT | O_NOATIME | O_WRONLY | O_SYNC | O_DSYNC);
  161.     sd_data_fd = open(sd_data_file, O_DIRECT | O_NOATIME | O_WRONLY | O_SYNC | O_DSYNC);
  162.     ml_cmd_fd = open(ml_cmd_file, O_DIRECT | O_NOATIME | O_RDWR | O_SYNC | O_DSYNC);
  163.     ml_data_fd = open(ml_data_file, O_DIRECT | O_NOATIME | O_RDONLY | O_SYNC | O_DSYNC);
  164.    
  165.     /* check if files could be opened */
  166.     if(sd_res_fd == -1)
  167.     {
  168.         printf("Failed to open '%s'\n", sd_res_file);
  169.         do_restart = 1;
  170.     }
  171.      
  172.     if(sd_data_fd == -1)
  173.     {
  174.         printf("Failed to open '%s'\n", sd_data_file);
  175.         do_restart = 1;
  176.     }
  177.      
  178.     if(ml_cmd_fd == -1)
  179.     {
  180.         printf("Failed to open '%s'\n", ml_cmd_file);
  181.         do_restart = 1;
  182.     }
  183.      
  184.     if(ml_data_fd == -1)
  185.     {
  186.         printf("Failed to open '%s'\n", ml_data_file);
  187.         do_restart = 1;
  188.     }
  189.    
  190.     while(!done && !do_restart)
  191.     {
  192.         /* flush all buffers and read the command */
  193.         sync();
  194.         fsync(ml_cmd_fd);
  195.         lseek(ml_cmd_fd, 0, SEEK_SET);
  196.        
  197.         ssize_t bytes_read = read(ml_cmd_fd, ml_cmd_buf_in, sizeof(ml_cmd_buf_in));
  198.        
  199.         /* if reading the command file failed, try to restart the daemon after a small relay */
  200.         if(bytes_read <= 0)
  201.         {
  202.             printf("READ: %d, errno: %d\n", bytes_read, errno);
  203.             do_restart = 1;
  204.             break;
  205.         }
  206.         else if(strlen(ml_cmd_buf_in) == 0)
  207.         {
  208.             timeouts++;
  209.         }
  210.         else
  211.         {
  212.             /* reset command */
  213.             strcpy(ml_cmd_buf_out, "");
  214.             lseek(ml_cmd_fd, 0, SEEK_SET);
  215.             write(ml_cmd_fd, ml_cmd_buf_out, sizeof(ml_cmd_buf_out));
  216.             fsync(ml_cmd_fd);
  217.             sync();
  218.            
  219.             printf("READ: '%s'\n", ml_cmd_buf_in);
  220.            
  221.             /* now try to parse the command */
  222.             char *cmd = NULL;
  223.             uint32_t size = 0;
  224.            
  225.             /* split in command and payload size */
  226.             split_command(ml_cmd_buf_in, &cmd, &size);
  227.            
  228.             /* if there is payload, try to read */
  229.             if(size)
  230.             {
  231.                 uint32_t read_count = sector_align(size);
  232.                
  233.                 /* as we use O_DIRECT, we can only read multiple of SECTOR_ALIGNMENT bytes (512 for kernel 2.6) */
  234.                 if(read_count < sizeof(ml_data_buf))
  235.                 {
  236.                     fsync(ml_data_fd);
  237.                     lseek(ml_data_fd, 0, SEEK_SET);
  238.                     ssize_t data_read = read(ml_data_fd, ml_data_buf, read_count);
  239.                    
  240.                     if(data_read < read_count)
  241.                     {
  242.                         printf("READ PARAM: %d/%d read (real: %d)\n", data_read, read_count, size);
  243.                         size = 0;
  244.                     }
  245.                 }
  246.                 else
  247.                 {
  248.                     printf("READ PARAM: %d > %d, so abort read (real: %d)\n", read_count, sizeof(ml_data_buf), size);
  249.                     size = 0;
  250.                 }
  251.             }
  252.            
  253.             if(!strcmp(cmd, "EXEC"))
  254.             {
  255.                 command_exec(ml_data_buf, size, sd_res_buf, sizeof(sd_res_buf), sd_data_buf, sizeof(sd_data_buf));
  256.             }
  257.             else if(!strcmp(cmd, "HTTP_GET"))
  258.             {
  259.                 command_http_get(ml_data_buf, size, sd_res_buf, sizeof(sd_res_buf), sd_data_buf, sizeof(sd_data_buf));
  260.             }
  261.             else if(!strcmp(cmd, "STATUS"))
  262.             {
  263.                 command_status(sd_res_buf, sizeof(sd_res_buf), sd_data_buf, sizeof(sd_data_buf));
  264.             }
  265.             else if(!strcmp(cmd, "EXIT"))
  266.             {
  267.                 strcpy(sd_data_buf, "");
  268.                 strcpy(sd_res_buf, "TERMINATED:0:");
  269.                 done = 1;
  270.             }
  271.             else
  272.             {
  273.                 strcpy(sd_data_buf, "");
  274.                 strcpy(sd_res_buf, "READY:0:");
  275.             }
  276.            
  277.             /* ok the command (whatever it was) finished, now write back the response/data */
  278.             lseek(sd_data_fd, 0, SEEK_SET);
  279.             lseek(sd_res_fd, 0, SEEK_SET);
  280.             write(sd_data_fd, sd_data_buf, sizeof(sd_data_buf));
  281.             write(sd_res_fd, sd_res_buf, sizeof(sd_res_buf));
  282.             fsync(sd_data_fd);
  283.             fsync(sd_res_fd);
  284.             sync();
  285.         }
  286.        
  287.         /* if there was no command lately, sleep a bit longer */
  288.         if(timeouts > 100)
  289.         {
  290.             sleep_time = 250000;
  291.         }
  292.         else
  293.         {
  294.             sleep_time = 50000;
  295.         }
  296.         usleep(sleep_time);
  297.     }
  298.    
  299.     /* something failed, try to restart */
  300.     if(do_restart)
  301.     {
  302.         sleep(1);
  303.         close(sd_res_fd);
  304.         close(sd_data_fd);
  305.         close(ml_cmd_fd);
  306.         close(ml_data_fd);
  307.         printf("Restarting tr_wifi daemon\n");
  308.         goto restart;        
  309.     }
  310.     return 0;
  311. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement