?login_element?

Subversion Repositories NedoOS

Rev

Rev 2076 | Rev 2112 | Go to most recent revision | Blame | Compare with Previous | Last modification | View Log | Download | RSS feed

  1. #include <math.h>
  2. #include <stdlib.h>
  3. #include <stdio.h>
  4. #include <string.h>
  5. #include <oscalls.h>
  6. #include <osfs.h>
  7. #include <intrz80.h>
  8. #include <ctype.h>
  9. #include <tcp.h>
  10. #include <graphic.h>
  11. #include <terminal.c>
  12. #define COMMANDLINE 0x0080
  13. unsigned int RBR_THR = 0xf8ef;
  14. unsigned int IER = 0xf9ef;
  15. unsigned int IIR_FCR = 0xfaef;
  16. unsigned int LCR = 0xfbef;
  17. unsigned int MCR = 0xfcef;
  18. unsigned int LSR = 0xfdef;
  19. unsigned int MSR = 0xfeef;
  20. unsigned int SR = 0xffef;
  21. unsigned int divider = 1;
  22. unsigned char comType = 0;
  23. unsigned int espType = 32;
  24.  
  25. const unsigned char sendOk[] = "SEND OK";
  26. const unsigned char gotWiFi[] = "WIFI GOT IP";
  27. unsigned char buffer[] = "0000000000";
  28. const unsigned char userAgent[] = " HTTP/1.1\r\nHost: zxart.ee\r\nUser-Agent: Mozilla/4.0 (compatible; MSIE5.01; NedoOS; Radio)\r\n\r\n\0";
  29. const unsigned char cmdlist1[] = "GET /file/id:";
  30. unsigned char userQuery[256] = "/api/export:zxMusic/limit:10/filter:zxMusicId=44816";
  31. unsigned char fileName[] = "radio/player.ovl";
  32. unsigned char appCmd[128] = "player.com ";
  33. unsigned char curPath[128];
  34.  
  35. unsigned char ver[] = "2.3";
  36.  
  37. unsigned char queryType[64];
  38. unsigned char netbuf[4096];
  39. unsigned char dataBuffer[4096];
  40. unsigned char crlf[2] = {13, 10};
  41. unsigned char formats[4][4] = {"pt3", "pt2", "tfc", "ts"};
  42. unsigned char interfaces[2][8] = {"nedoNET\0", "ESP-COM\0"};
  43. unsigned char cmd[256];
  44. unsigned char link[512];
  45. unsigned char toLog[256];
  46.  
  47. unsigned char status, key, curFormat;
  48. struct sockaddr_in targetadr;
  49. struct readstructure readStruct;
  50. unsigned long contLen;
  51. long count;
  52. unsigned char saveFlag, saveBak, logFlag, rptFlag, netDriver;
  53. union APP_PAGES main_pg;
  54. union APP_PAGES player_pg;
  55. unsigned int loaded;
  56. unsigned int headlng;
  57. unsigned char cutOff = 1;
  58. int remainTime;
  59.  
  60. struct fileStruct
  61. {
  62.   long picId;
  63.   unsigned long fileSize;
  64.   unsigned int picYear;
  65.   unsigned long totalAmount;
  66.   unsigned int curPos;
  67.   unsigned int startBar;
  68.   unsigned int trackInSeconds;
  69.   unsigned char time[16];
  70.   unsigned char picRating[8];
  71.   unsigned char trackName[256];
  72.   unsigned char fileName[256];
  73.   unsigned char authorIds[64];
  74.   unsigned char authorTitle[64];
  75.   unsigned char authorRealName[64];
  76.   unsigned char afn[64];
  77.   unsigned char tfn[64];
  78.   unsigned char fileName2[256];
  79. } curFileStruct;
  80.  
  81. void writeLog(char *logline)
  82. {
  83.   FILE *LogFile;
  84.   unsigned long fileSize;
  85.  
  86.   LogFile = OS_OPENHANDLE("m:/bin/radio/radio.log", 0x80);
  87.   if (((int)LogFile) & 0xff)
  88.   {
  89.     LogFile = OS_CREATEHANDLE("m:/bin/radio/radio.log", 0x80);
  90.     OS_CLOSEHANDLE(LogFile);
  91.     LogFile = OS_OPENHANDLE("m:/bin/radio/radio.log", 0x80);
  92.   }
  93.  
  94.   fileSize = OS_GETFILESIZE(LogFile);
  95.   OS_SEEKHANDLE(LogFile, fileSize);
  96.   OS_WRITEHANDLE(logline, LogFile, strlen(logline));
  97.   OS_CLOSEHANDLE(LogFile);
  98. }
  99.  
  100. void delay(unsigned long counter)
  101. {
  102.   unsigned long start, finish;
  103.   counter = counter / 20;
  104.   if (counter < 1)
  105.   {
  106.     counter = 1;
  107.   }
  108.   start = time();
  109.   finish = start + counter;
  110.  
  111.   while (start < finish)
  112.   {
  113.     start = time();
  114.   }
  115. }
  116.  
  117. void clearStatus(void)
  118. {
  119.   AT(1, 25);
  120.   printf("                                                                               \r");
  121. }
  122.  
  123. void printProgress(unsigned char type)
  124. {
  125.   unsigned char bar, minutes, seconds;
  126.   unsigned char *position;
  127.   long barLenght;
  128.   int timer;
  129.   switch (type)
  130.   {
  131.   case 0: // print empty bar
  132.     AT(6, 11);
  133.     ATRIB(93);
  134.     printf("%02u:%02u", 0, 0);
  135.     AT(15, 11);
  136.     ATRIB(97);
  137.     for (bar = 0; bar < 50; bar++)
  138.     {
  139.       putchar(176);
  140.     }
  141.     putchar(' ');
  142.     putchar(' ');
  143.     minutes = atoi(curFileStruct.time);
  144.     position = (strstr(curFileStruct.time, ":")) + 1;
  145.     seconds = atoi(position);
  146.     curFileStruct.trackInSeconds = minutes * 60 + seconds;
  147.     curFileStruct.curPos = 0;
  148.     curFileStruct.startBar = 0;
  149.     break;
  150.   case 1: // print progress bar
  151.  
  152.     AT(6, 11);
  153.     ATRIB(93);
  154.     timer = floor(curFileStruct.curPos / 60);
  155.     printf("%02u:%02u", timer, (curFileStruct.curPos - (timer * 60)));
  156.  
  157.     barLenght = (curFileStruct.curPos * 50 / curFileStruct.trackInSeconds);
  158.     if (barLenght > 49)
  159.     {
  160.       barLenght = 50;
  161.     }
  162.     AT(15 + curFileStruct.startBar, 11);
  163.     ATRIB(97);
  164.     for (bar = 0; bar < barLenght - curFileStruct.startBar; bar++)
  165.     {
  166.       putchar(178);
  167.     }
  168.     AT(1, 1);
  169.     curFileStruct.startBar = bar;
  170.     break;
  171.   case 2: // print full bar
  172.     AT(15, 11);
  173.     ATRIB(97);
  174.     for (bar = 0; bar < 50; bar++)
  175.     {
  176.       putchar(178);
  177.     }
  178.     break;
  179.   }
  180. }
  181. void errorPrint(unsigned int error)
  182. {
  183.   switch (error)
  184.   {
  185.   case 2:
  186.     printf("02 SHUT_RDWR");
  187.     break;
  188.   case 4:
  189.     printf("04 ERR_INTR");
  190.     break;
  191.   case 23:
  192.     printf("23 ERR_NFILE");
  193.     break;
  194.   case 35:
  195.     printf("35 ERR_EAGAIN");
  196.     break;
  197.   case 37:
  198.     printf("37 ERR_ALREADY");
  199.     break;
  200.   case 38:
  201.     printf("38 ERR_NOTSOCK");
  202.     break;
  203.   case 40:
  204.     printf("40 ERR_EMSGSIZE");
  205.     break;
  206.   case 41:
  207.     printf("41 ERR_PROTOTYPE");
  208.     break;
  209.   case 47:
  210.     printf("47 ERR_AFNOSUPPORT");
  211.     break;
  212.   case 53:
  213.     printf("53 ERR_ECONNABORTED");
  214.     break;
  215.   case 54:
  216.     printf("54 ERR_CONNRESET");
  217.     break;
  218.   case 57:
  219.     printf("57 ERR_NOTCONN");
  220.     break;
  221.   case 65:
  222.     printf("65 ERR_HOSTUNREACH");
  223.     break;
  224.   default:
  225.     printf("%u UNKNOWN ERROR", error);
  226.     break;
  227.   }
  228.   YIELD();
  229. }
  230.  
  231. void printHelp(void)
  232. {
  233.   AT(1, 15);
  234.   ATRIB(97);
  235.   printf(" [<-] [B] Previous track          [->] [ ] Next track      \r\n");
  236.   printf(" [S]  Stop player                 [R]  Repeat track mode   \r\n");
  237.   printf(" [K]  Toggle saving tracks        [D]  Download track      \r\n");
  238.   printf(" [Q]  Select Query type           [F]  Select tracks format\r\n");
  239.   printf(" [I]  Interface ZXNETUSB/ESP32    [J]  Jump to NNNN file   \r\n");
  240.   printf(" [L]  Toggle operation logging    [ESC] Exit to OS         \r\n");
  241.   printf("                                                           \r\n");
  242. }
  243.  
  244. unsigned char OpenSock(unsigned char family, unsigned char protocol)
  245. {
  246.   unsigned char socket;
  247.   unsigned int todo;
  248.   todo = OS_NETSOCKET((family << 8) + protocol);
  249.   if (todo > 32767)
  250.   {
  251.     clearStatus();
  252.     printf("OS_NETSOCKET: ");
  253.     errorPrint(todo & 255);
  254.     exit(0);
  255.   }
  256.   else
  257.   {
  258.     socket = ((todo & 65280) >> 8);
  259.     if (logFlag)
  260.     {
  261.       clearStatus();
  262.       printf("OS_NETSOCKET: Socket #%d created.", socket);
  263.     }
  264.   }
  265.   return socket;
  266. }
  267.  
  268. unsigned int netShutDown(unsigned char socket, unsigned char type)
  269. {
  270.   unsigned int todo;
  271.   todo = OS_NETSHUTDOWN(socket, type);
  272.   if (todo > 32767)
  273.   {
  274.     clearStatus();
  275.     printf("OS_NETSHUTDOWN: ");
  276.     errorPrint(todo & 255);
  277.     return 255;
  278.   }
  279.   else
  280.   {
  281.     if (logFlag)
  282.     {
  283.       clearStatus();
  284.       printf("OS_NETSHUTDOWN: Socket #%u closed.", socket);
  285.     }
  286.   }
  287.   return 0;
  288. }
  289.  
  290. unsigned char netConnect(unsigned char socket)
  291. {
  292.   unsigned int todo, retry = 10;
  293.  
  294.   targetadr.family = AF_INET;
  295.   targetadr.porth = 00;
  296.   targetadr.portl = 80;
  297.   targetadr.b1 = 217;
  298.   targetadr.b2 = 146;
  299.   targetadr.b3 = 69;
  300.   targetadr.b4 = 13;
  301.   while (retry > 0)
  302.   {
  303.     todo = OS_NETCONNECT(socket, &targetadr);
  304.  
  305.     if (todo > 32767)
  306.     {
  307.       retry--;
  308.       clearStatus();
  309.       printf("OS_NETCONNECT [ERROR:");
  310.       errorPrint(todo & 255);
  311.       printf("] [Retry:%u]", retry);
  312.       YIELD();
  313.       netShutDown(socket, 0);
  314.       socket = OpenSock(AF_INET, SOCK_STREAM);
  315.     }
  316.     else
  317.     {
  318.       if (logFlag)
  319.       {
  320.         clearStatus();
  321.         printf("OS_NETCONNECT: connected , %u", (todo & 255));
  322.       }
  323.       return 1;
  324.     }
  325.   }
  326.   getchar();
  327.   exit(0);
  328.   return 0;
  329. }
  330.  
  331. unsigned int tcpRead(unsigned char socket)
  332. {
  333.   unsigned char retry = 20;
  334.   unsigned int err, todo;
  335.   readStruct.socket = socket;
  336.   readStruct.BufAdr = (unsigned int)&netbuf;
  337.   readStruct.bufsize = sizeof(netbuf);
  338.   readStruct.protocol = SOCK_STREAM;
  339.  
  340. wizread:
  341.   todo = OS_WIZNETREAD(&readStruct);
  342.   if (todo > 32767)
  343.   {
  344.     if (retry == 0)
  345.     {
  346.       err = todo & 255;
  347.       clearStatus();
  348.       printf("OS_WIZNETREAD: ");
  349.       errorPrint(err);
  350.       if (err == ERR_EAGAIN)
  351.       {
  352.         return 0;
  353.       }
  354.       exit(0);
  355.     }
  356.     retry--;
  357.     if (logFlag)
  358.     {
  359.       AT(54, 25);
  360.       printf("OS_WIZNETREAD: retry %u   ", retry);
  361.     }
  362.     delay(200);
  363.     goto wizread;
  364.   }
  365.   if (logFlag)
  366.   {
  367.     clearStatus();
  368.     printf("OS_WIZNETREAD: %u bytes read.", todo);
  369.   }
  370.   return todo;
  371. }
  372.  
  373. int pos(unsigned char *s, unsigned char *c, unsigned int n, unsigned int startPos)
  374. {
  375.   unsigned int i, j;
  376.   unsigned int lenC, lenS;
  377.  
  378.   for (lenC = 0; c[lenC]; lenC++)
  379.     ;
  380.   for (lenS = 0; s[lenS]; lenS++)
  381.     ;
  382.  
  383.   for (i = startPos; i <= lenS - lenC; i++)
  384.   {
  385.     for (j = 0; s[i + j] == c[j]; j++)
  386.       ;
  387.  
  388.     if (j - lenC == 1 && i == lenS - lenC && !(n - 1))
  389.       return i;
  390.     if (j == lenC)
  391.       if (n - 1)
  392.         n--;
  393.       else
  394.         return i;
  395.   }
  396.   return -1;
  397. }
  398.  
  399. unsigned int cutHeader(unsigned int todo)
  400. {
  401.   unsigned int q, headlng;
  402.   unsigned char *count;
  403.   count = strstr(netbuf, "Content-Length:");
  404.   if (count == NULL)
  405.   {
  406.     clearStatus();
  407.     printf("Content-Length:  not found.");
  408.     contLen = 0;
  409.   }
  410.   else
  411.   {
  412.     contLen = atol(count + 15);
  413.     curFileStruct.fileSize = contLen;
  414.     //  printf("=> Dlinna  soderzhimogo = %lu \n\r", curFileStruct.fileSize);
  415.   }
  416.  
  417.   count = strstr(netbuf, "\r\n\r\n");
  418.   headlng = ((unsigned int)count - (unsigned int)netbuf + 4);
  419.   q = todo - headlng;
  420.   memcpy(&netbuf, count + 4, q);
  421.   return q;
  422. }
  423.  
  424. ////////////////////////ESP32 PROCEDURES//////////////////////
  425. void uart_write(unsigned char data)
  426. {
  427.   unsigned char status;
  428.   switch (comType)
  429.   {
  430.   case 0:
  431.   case 2:
  432.     while ((input(LSR) & 64) == 0)
  433.     {
  434.     }
  435.     output(RBR_THR, data);
  436.     break;
  437.   case 1:
  438.     disable_interrupt();
  439.     do
  440.     {
  441.       input(0x55fe);          // Переход в режим команд
  442.       status = input(0x42fe); // Команда прочесть статус
  443.     } while ((status & 64) == 0); // Проверяем 6 бит
  444.  
  445.     input(0x55fe);               // Переход в режим команд
  446.     input(0x03fe);               // Команда записать в порт
  447.     input((data << 8) | 0x00fe); // Записываем data в порт
  448.     enable_interrupt();
  449.     break;
  450.   }
  451. }
  452.  
  453. void uart_setrts(unsigned char mode)
  454. {
  455.   switch (comType)
  456.   {
  457.   case 0:
  458.     switch (mode)
  459.     {
  460.     case 1:
  461.       output(MCR, 2);
  462.       break;
  463.     case 0:
  464.       output(MCR, 0);
  465.       break;
  466.     default:
  467.       disable_interrupt();
  468.       output(MCR, 2);
  469.       output(MCR, 0);
  470.       enable_interrupt();
  471.       break;
  472.     }
  473.   case 1:
  474.     switch (mode)
  475.     {
  476.     case 1:
  477.       disable_interrupt();
  478.       input(0x55fe); // Переход в режим команд
  479.       input(0x43fe); // Команда установить статус
  480.       input(0x03fe); // Устанавливаем готовность DTR и RTS
  481.       enable_interrupt();
  482.       break;
  483.     case 0:
  484.       disable_interrupt();
  485.       input(0x55fe); // Переход в режим команд
  486.       input(0x43fe); // Команда установить статус
  487.       input(0x00fe); // Снимаем готовность DTR и RTS
  488.       enable_interrupt();
  489.       break;
  490.     default:
  491.       disable_interrupt();
  492.       input(0x55fe); // Переход в режим команд
  493.       input(0x43fe); // Команда установить статус
  494.       input(0x03fe); // Устанавливаем готовность DTR и RTS
  495.       input(0x55fe); // Переход в режим команд
  496.       input(0x43fe); // Команда установить статус
  497.       input(0x00fe); // Снимаем готовность DTR и RTS
  498.       enable_interrupt();
  499.       break;
  500.     }
  501.   case 2:
  502.     break;
  503.   }
  504. }
  505.  
  506. void uart_init(unsigned char divisor)
  507. {
  508.   switch (comType)
  509.   {
  510.   case 0:
  511.   case 2:
  512.     output(MCR, 0x00);        // Disable input
  513.     output(IIR_FCR, 0x87);    // Enable fifo 8 level, and clear it
  514.     output(LCR, 0x83);        // 8n1, DLAB=1
  515.     output(RBR_THR, divisor); // 115200 (divider 1-115200, 3 - 38400)
  516.     output(IER, 0x00);        // (divider 0). Divider is 16 bit, so we get (#0002 divider)
  517.     output(LCR, 0x03);        // 8n1, DLAB=0
  518.     output(IER, 0x00);        // Disable int
  519.     output(MCR, 0x2f);        // Enable AFE
  520.     break;
  521.   case 1:
  522.     disable_interrupt();
  523.     input(0x55fe);
  524.     input(0xc3fe);
  525.     input((divisor << 8) | 0x00fe);
  526.     enable_interrupt();
  527.     break;
  528.   }
  529. }
  530.  
  531. unsigned char uart_hasByte(void)
  532. {
  533.   unsigned char queue;
  534.   switch (comType)
  535.   {
  536.   case 0:
  537.   case 2:
  538.     return (1 & input(LSR));
  539.   case 1:
  540.     disable_interrupt();
  541.     input(0x55fe);         // Переход в режим команд
  542.     queue = input(0xc2fe); // Получаем количество байт в приемном буфере
  543.     enable_interrupt();
  544.     return queue;
  545.   }
  546.   return 255;
  547. }
  548.  
  549. unsigned char uart_read(void)
  550. {
  551.   unsigned char data;
  552.   switch (comType)
  553.   {
  554.   case 0:
  555.   case 2:
  556.     return input(RBR_THR);
  557.   case 1:
  558.     disable_interrupt();
  559.     input(0x55fe);        // Переход в режим команд
  560.     data = input(0x02fe); // Команда прочесть из порта
  561.     enable_interrupt();
  562.     return data;
  563.   }
  564.   return 255;
  565. }
  566.  
  567. unsigned char uart_readBlock(void)
  568. {
  569.   unsigned char data;
  570.   switch (comType)
  571.   {
  572.   case 0:
  573.     while (uart_hasByte() == 0)
  574.     {
  575.       uart_setrts(2);
  576.     }
  577.     return input(RBR_THR);
  578.   case 1:
  579.     while (uart_hasByte() == 0)
  580.     {
  581.       uart_setrts(2);
  582.     }
  583.     disable_interrupt();
  584.     input(0x55fe);        // Переход в режим команд
  585.     data = input(0x02fe); // Команда прочесть из порта
  586.     enable_interrupt();
  587.     return data;
  588.   case 2:
  589.     while (uart_hasByte() == 0)
  590.     {
  591.     }
  592.     return input(RBR_THR);
  593.   }
  594.   return 255;
  595. }
  596.  
  597. void uart_flush(void)
  598. {
  599.   unsigned int count;
  600.   for (count = 0; count < 6000; count++)
  601.   {
  602.     uart_setrts(1);
  603.     uart_read();
  604.   }
  605.   clearStatus();
  606.   printf("Buffer cleared.");
  607. }
  608. void getdataEsp(unsigned int counted)
  609. {
  610.   unsigned int counter;
  611.   for (counter = 0; counter < counted; counter++)
  612.   {
  613.     netbuf[counter] = uart_readBlock();
  614.   }
  615.   netbuf[counter] = 0;
  616. }
  617.  
  618. void sendcommand(char *commandline)
  619. {
  620.   unsigned int count, cmdLen;
  621.   cmdLen = strlen(commandline);
  622.   for (count = 0; count < cmdLen; count++)
  623.   {
  624.     uart_write(commandline[count]);
  625.   }
  626.   uart_write('\r');
  627.   uart_write('\n');
  628.   // printf("Sended:[%s] \r\n", commandline);
  629. }
  630. unsigned char getAnswer2(void)
  631. {
  632.   unsigned char readbyte;
  633.   unsigned int curPos = 0;
  634.   do
  635.   {
  636.     readbyte = uart_readBlock();
  637.   } while (((readbyte == 0x0a) || (readbyte == 0x0d)));
  638.   netbuf[curPos] = readbyte;
  639.   curPos = 1;
  640.   do
  641.   {
  642.     readbyte = uart_readBlock();
  643.     netbuf[curPos] = readbyte;
  644.     curPos++;
  645.   } while (readbyte != 0x0d);
  646.   netbuf[curPos - 1] = 0;
  647.   uart_readBlock(); // 0xa
  648.   // printf("Answer:[%s]\r\n", netbuf);
  649.   // getchar();
  650.   return curPos;
  651. }
  652.  
  653. void espReBoot(void)
  654. {
  655.   unsigned char byte, count;
  656.   uart_flush();
  657.   sendcommand("AT+RST");
  658.   clearStatus();
  659.   printf("Resetting ESP...");
  660.   count = 0;
  661.   do
  662.   {
  663.     byte = uart_readBlock();
  664.     if (byte == gotWiFi[count])
  665.     {
  666.       count++;
  667.     }
  668.     else
  669.     {
  670.       count = 0;
  671.     }
  672.   } while (count < strlen(gotWiFi));
  673.   uart_readBlock(); // CR
  674.   uart_readBlock(); // LF
  675.   clearStatus();
  676.   printf("Reset complete.");
  677.  
  678.   sendcommand("ATE0");
  679.   do
  680.   {
  681.     byte = uart_readBlock();
  682.   } while (byte != 'K'); // OK
  683.   // clearStatus();
  684.   // puts("ATE0 Answer:[OK]");
  685.   uart_readBlock(); // CR
  686.   uart_readBlock(); // LN
  687.  
  688.   sendcommand("AT+CIPCLOSE");
  689.   getAnswer2();
  690.   sendcommand("AT+CIPDINFO=0");
  691.   getAnswer2();
  692.   sendcommand("AT+CIPMUX=0");
  693.   getAnswer2();
  694.   sendcommand("AT+CIPSERVER=0");
  695.   getAnswer2();
  696.   sendcommand("AT+CIPRECVMODE=0");
  697.   getAnswer2();
  698. }
  699.  
  700. unsigned int recvHead(void)
  701. {
  702.   unsigned char byte, dataRead = 0;
  703.   do
  704.   {
  705.     byte = uart_readBlock();
  706.   } while (byte != ',');
  707.  
  708.   dataRead = 0;
  709.   do
  710.   {
  711.     byte = uart_readBlock();
  712.     netbuf[dataRead] = byte;
  713.     dataRead++;
  714.   } while (byte != ':');
  715.   netbuf[dataRead] = 0;
  716.   loaded = atoi(netbuf); // <actual_len>
  717.   // printf("\r\n loaded %u\r\n", loaded);
  718.   return loaded;
  719. }
  720.  
  721. // in netbuf data to send
  722. unsigned int fillDataBufferEsp(void)
  723. {
  724.   unsigned char sizeLink;
  725.   unsigned long toDownload, downloaded;
  726.   unsigned char byte, count = 0, try = 0;
  727.   unsigned int dataSize;
  728.   unsigned char skipHeader;
  729.   unsigned char *count1;
  730.  
  731.   strcpy(link, netbuf);
  732.   sizeLink = strlen(link);
  733.   try = 0;
  734.   do
  735.   {
  736.     try++;
  737.     if (try > 1)
  738.     {
  739.       clearStatus();
  740.       printf("----->Retry:%u", try);
  741.       delay(500);
  742.     }
  743.     sendcommand("AT+CIPSTART=\"TCP\",\"zxart.ee\",80");
  744.     getAnswer2(); // CONNECT or ERROR or link is not valid
  745.     count1 = strstr(netbuf, "CONNECT");
  746.   } while (count1 == NULL);
  747.  
  748.   getAnswer2(); // OK
  749.  
  750.   strcpy(cmd, "AT+CIPSEND=");
  751.   sprintf(netbuf, "%u", sizeLink + 2); // second CRLF in send command
  752.   strcat(cmd, netbuf);
  753.   sendcommand(cmd);
  754.   getAnswer2();
  755.  
  756.   do
  757.   {
  758.     byte = uart_readBlock();
  759.     // putchar(byte);
  760.   } while (byte != '>');
  761.   sendcommand(link);
  762.   count = 0;
  763.   do
  764.   {
  765.     byte = uart_readBlock();
  766.     if (byte == sendOk[count])
  767.     {
  768.       count++;
  769.     }
  770.     else
  771.     {
  772.       count = 0;
  773.     }
  774.   } while (count < strlen(sendOk));
  775.   uart_readBlock(); // CR
  776.   uart_readBlock(); // LF
  777.   skipHeader = 0;
  778.   downloaded = 0;
  779.   do
  780.   {
  781.     headlng = 0;
  782.     dataSize = recvHead();
  783.     getdataEsp(dataSize); // Requested size
  784.     if (skipHeader == 0)
  785.     {
  786.       dataSize = cutHeader(dataSize);
  787.       toDownload = contLen;
  788.       skipHeader = 1;
  789.     }
  790.     downloaded = downloaded + dataSize;
  791.     memcpy(dataBuffer + downloaded - dataSize, netbuf + headlng, dataSize);
  792.     toDownload = toDownload - dataSize;
  793.   } while (toDownload > 0);
  794.   sendcommand("AT+CIPCLOSE");
  795.  
  796.   getAnswer2(); // CLOSED
  797.   getAnswer2(); // OK
  798.   return 0;
  799. }
  800. void loadEspConfig(void)
  801. {
  802.   unsigned char curParam[256];
  803.   unsigned char res;
  804.   FILE *espcom;
  805.   OS_SETSYSDRV();
  806.   OS_CHDIR("browser");
  807.   espcom = OS_OPENHANDLE("espcom.ini", 0x80);
  808.   if (((int)espcom) & 0xff)
  809.   {
  810.     clearStatus();
  811.     printf("mrfesp.ini opening error");
  812.     return;
  813.   }
  814.  
  815.   OS_READHANDLE(curParam, espcom, 256);
  816.  
  817.   res = sscanf(curParam, "%x %x %x %x %x %x %x %x %u %u %u", &RBR_THR, &IER, &IIR_FCR, &LCR, &MCR, &LSR, &MSR, &SR, &divider, &comType, &espType);
  818.   BOX(1, 15, 80, 8, 40);
  819.   AT(1, 15);
  820.   puts("Config loaded:");
  821.   if (comType == 1)
  822.   {
  823.     puts("     Controller base port: 0x55fe");
  824.   }
  825.   else
  826.   {
  827.     printf("     RBR_THR:0x%4x     IER    :0x%4x\r\n     IIR_FCR:0x%4x     LCR    :0x%4x\r\n", RBR_THR, IER, IIR_FCR, LCR);
  828.     printf("     MCR    :0x%4x     LSR    :0x%4x\r\n     MSR    :0x%4x     SR     :0x%4x\r\n", MCR, LSR, MSR, SR);
  829.   }
  830.   printf("     DIV    :%4u       TYPE   :%4u  \r\n     ESP    : %u ", divider, comType, espType);
  831.   switch (comType)
  832.   {
  833.   case 0:
  834.     puts("(16550 like w/o AFC)");
  835.     break;
  836.   case 1:
  837.     puts("(ATM Turbo 2+)");
  838.     break;
  839.   case 2:
  840.     puts("(16550 with AFC)");
  841.   default:
  842.     puts("(Unknown type)");
  843.     break;
  844.   }
  845. }
  846.  
  847. ////////////////////////ESP32 PROCEDURES//////////////////////
  848.  
  849. char *str_replace(char *dst, int num, const char *str,
  850.                   const char *orig, const char *rep)
  851. {
  852.   const char *ptr;
  853.   size_t len1 = strlen(orig);
  854.   size_t len2 = strlen(rep);
  855.   char *tmp = dst;
  856.  
  857.   num -= 1;
  858.   while ((ptr = strstr(str, orig)) != NULL)
  859.   {
  860.     num -= (ptr - str) + len2;
  861.     if (num < 1)
  862.       break;
  863.  
  864.     strncpy(dst, str, (size_t)(ptr - str));
  865.     dst += ptr - str;
  866.     strncpy(dst, rep, len2);
  867.     dst += len2;
  868.     str = ptr + len1;
  869.   }
  870.  
  871.   for (; (*dst = *str) && (num > 0); --num)
  872.   {
  873.     ++dst;
  874.     ++str;
  875.   }
  876.   return tmp;
  877. }
  878.  
  879. const char *parseJson(unsigned char *property)
  880. {
  881.   unsigned int w, lng, lngp1, findEnd, listPos;
  882.   unsigned char terminator;
  883.   int n;
  884.   n = -1;
  885.   netbuf[0] = '\0';
  886.   n = pos(dataBuffer, property, 1, 0);
  887.   if (n == -1)
  888.   {
  889.     strcpy(netbuf, "0\0");
  890.     return netbuf;
  891.   }
  892.   lng = n - 1 + strlen(property);
  893.   if (dataBuffer[lng] == ':')
  894.   {
  895.     terminator = '\0';
  896.   }
  897.   if (dataBuffer[lng] == '\"')
  898.   {
  899.     terminator = '\"';
  900.   }
  901.   if (dataBuffer[lng] == '[')
  902.   {
  903.     terminator = ']';
  904.   }
  905.  
  906.   findEnd = 1;
  907.   lngp1 = lng + 1;
  908.  
  909.   while (42)
  910.   {
  911.  
  912.     if ((dataBuffer[lngp1 + findEnd] == ','))
  913.     {
  914.       if (terminator == '\0')
  915.       {
  916.         break;
  917.       }
  918.       if ((dataBuffer[lng + findEnd] == terminator))
  919.       {
  920.         findEnd--;
  921.         break;
  922.       }
  923.     }
  924.     findEnd++;
  925.   }
  926.   listPos = 0;
  927.   for (w = lngp1; w < findEnd + lngp1; w++)
  928.   {
  929.     netbuf[listPos] = dataBuffer[w];
  930.     listPos++;
  931.   }
  932.   netbuf[listPos] = '\0';
  933.   return netbuf;
  934. }
  935. void convert866(void)
  936. {
  937.   unsigned int lng, targetPos, w, q = 0;
  938.   unsigned char buffer[8], one, two;
  939.   unsigned int decVal;
  940.   lng = strlen(netbuf);
  941.   targetPos = lng + 1;
  942.  
  943.   while (q < lng)
  944.   {
  945.     one = netbuf[q];
  946.     two = netbuf[q + 1];
  947.     if (one == 92 && two == 117)
  948.     {
  949.       q = q + 2;
  950.       for (w = 0; w < 4; w++)
  951.       {
  952.         buffer[w] = netbuf[q + w];
  953.       }
  954.       q = q + 4;
  955.       buffer[4] = '\0';
  956.       decVal = (unsigned int)strtol(buffer, NULL, 16);
  957.  
  958.       if (decVal < 1088)
  959.       {
  960.         decVal = decVal - 912;
  961.       }
  962.       if (decVal > 1087)
  963.       {
  964.         decVal = decVal - 864;
  965.       }
  966.       if (decVal == 1025)
  967.       {
  968.         decVal = 240;
  969.       }
  970.       if (decVal == 1105)
  971.       {
  972.         decVal = 241;
  973.       }
  974.       netbuf[targetPos] = decVal;
  975.     }
  976.     else
  977.     {
  978.       netbuf[targetPos] = netbuf[q];
  979.       q++;
  980.     }
  981.     targetPos++;
  982.   }
  983.   netbuf[targetPos] = '\0';
  984.  
  985.   for (w = lng + 1; w < targetPos + 1; w++)
  986.   {
  987.     netbuf[w - lng - 1] = netbuf[w];
  988.   }
  989. }
  990.  
  991. void nameRepair(unsigned char *pfn, unsigned int tfnSize)
  992. {
  993.   str_replace(pfn, tfnSize, pfn, "\\", "_");
  994.   str_replace(pfn, tfnSize, pfn, "/", "_");
  995.   str_replace(pfn, tfnSize, pfn, ":", "_");
  996.   str_replace(pfn, tfnSize, pfn, "*", "_");
  997.   str_replace(pfn, tfnSize, pfn, "?", "_");
  998.   str_replace(pfn, tfnSize, pfn, "<", "_");
  999.   str_replace(pfn, tfnSize, pfn, ">", "_");
  1000.   str_replace(pfn, tfnSize, pfn, "|", "_");
  1001.   str_replace(pfn, tfnSize, pfn, " ", "_");
  1002.   str_replace(pfn, tfnSize, pfn, "&#039;", "'");
  1003.   str_replace(pfn, tfnSize, pfn, "&amp;", "&");
  1004.   str_replace(pfn, tfnSize, pfn, "&quot;", "'");
  1005.   str_replace(pfn, tfnSize, pfn, "&gt;", ")");
  1006.   str_replace(pfn, tfnSize, pfn, "&lt;", "(");
  1007.   str_replace(pfn, tfnSize, pfn, "\"", "'");
  1008. }
  1009.  
  1010. void stringRepair(unsigned char *pfn, unsigned int tSize)
  1011. {
  1012.   str_replace(pfn, tSize, pfn, "&#039;", "'");
  1013.   str_replace(pfn, tSize, pfn, "&amp;", "&");
  1014.   str_replace(pfn, tSize, pfn, "&gt;", ">");
  1015.   str_replace(pfn, tSize, pfn, "&lt;", "<");
  1016.   str_replace(pfn, tSize, pfn, "&quot;", "\"");
  1017.   str_replace(pfn, tSize, pfn, "\\/", "/");
  1018. }
  1019.  
  1020. void ncReplace(void)
  1021. {
  1022.   unsigned char len;
  1023.   for (len = 0; len < strlen(curFileStruct.afn); len++)
  1024.   {
  1025.     if (curFileStruct.afn[len] < ' ')
  1026.     {
  1027.       curFileStruct.afn[len] = '_';
  1028.     }
  1029.   }
  1030.  
  1031.   for (len = 0; len < strlen(curFileStruct.tfn); len++)
  1032.   {
  1033.     if (curFileStruct.tfn[len] < ' ')
  1034.     {
  1035.       curFileStruct.tfn[len] = '_';
  1036.     }
  1037.   }
  1038. }
  1039.  
  1040. unsigned char saveBuf(unsigned long fileId, unsigned char operation, unsigned int sizeOfBuf)
  1041. {
  1042.   FILE *fp2;
  1043.   unsigned long fileSize;
  1044.   unsigned char afnSize, tfnSize;
  1045.   unsigned char fileIdChar[10];
  1046.  
  1047.   if (operation == 00)
  1048.   {
  1049.  
  1050.     if (saveFlag == 0)
  1051.     {
  1052.       sprintf(curFileStruct.fileName, "temp.%s", formats[curFormat]);
  1053.     }
  1054.     else
  1055.     {
  1056.       afnSize = sizeof(curFileStruct.afn) - 1;
  1057.       tfnSize = sizeof(curFileStruct.tfn) - 1;
  1058.  
  1059.       strcpy(curFileStruct.afn, curFileStruct.authorTitle);
  1060.       nameRepair(curFileStruct.afn, afnSize);
  1061.       strcpy(curFileStruct.tfn, curFileStruct.trackName);
  1062.       nameRepair(curFileStruct.tfn, tfnSize);
  1063.       sprintf(curFileStruct.fileName, "%s-%s.%s", curFileStruct.afn, curFileStruct.tfn, formats[curFormat]);
  1064.       ncReplace();
  1065.  
  1066.       if (strlen(curFileStruct.fileName) > 63)
  1067.       {
  1068.         sprintf(fileIdChar, "-%ld", fileId);
  1069.         str_replace(curFileStruct.fileName, sizeof(curFileStruct.fileName) - 1, curFileStruct.fileName, fileIdChar, "");
  1070.         curFileStruct.fileName[50] = '\0';
  1071.         strcat(curFileStruct.fileName, fileIdChar);
  1072.         strcat(curFileStruct.fileName, formats[curFormat]);
  1073.       }
  1074.     }
  1075.     OS_SETSYSDRV();
  1076.     OS_MKDIR("../downloads/radio"); // Create if not exist
  1077.     OS_CHDIR("../downloads/radio");
  1078.     fp2 = OS_CREATEHANDLE(curFileStruct.fileName, 0x80);
  1079.     if (((int)fp2) & 0xff)
  1080.     {
  1081.       clearStatus();
  1082.       printf("%s creating error. Check for  downloads\\radio folder.", curFileStruct.fileName);
  1083.       getchar();
  1084.       exit(0);
  1085.     }
  1086.     OS_CLOSEHANDLE(fp2);
  1087.     return 0;
  1088.   }
  1089.  
  1090.   if (operation == 01)
  1091.   {
  1092.     fp2 = OS_OPENHANDLE(curFileStruct.fileName, 0x80);
  1093.     if (((int)fp2) & 0xff)
  1094.     {
  1095.  
  1096.       clearStatus();
  1097.       printf("%s opening error.", curFileStruct.fileName);
  1098.       exit(0);
  1099.     }
  1100.     fileSize = OS_GETFILESIZE(fp2);
  1101.     OS_SEEKHANDLE(fp2, fileSize);
  1102.     OS_WRITEHANDLE(netbuf, fp2, sizeOfBuf);
  1103.     OS_CLOSEHANDLE(fp2);
  1104.     return 0;
  1105.   }
  1106.  
  1107.   if (operation == 02)
  1108.   {
  1109.     OS_CLOSEHANDLE(fp2);
  1110.     return 0;
  1111.   }
  1112.  
  1113.   return 0;
  1114. }
  1115.  
  1116. void getData(unsigned char socket)
  1117. {
  1118.   unsigned int todo, w, bPos, skipHeader;
  1119.  
  1120.   skipHeader = 0;
  1121.   bPos = 0;
  1122.   while (1)
  1123.   {
  1124.     todo = tcpRead(socket);
  1125.     if (todo == 0)
  1126.     {
  1127.       break;
  1128.     }
  1129.     if (skipHeader == 0)
  1130.     {
  1131.       skipHeader = 1;
  1132.       todo = cutHeader(todo);
  1133.     }
  1134.  
  1135.     if (bPos + todo > sizeof(dataBuffer))
  1136.     {
  1137.       clearStatus();
  1138.       printf("dataBuffer overrun...");
  1139.       break;
  1140.     }
  1141.  
  1142.     for (w = 0; w < todo; w++)
  1143.     {
  1144.       dataBuffer[w + bPos] = netbuf[w];
  1145.     }
  1146.     bPos = bPos + todo;
  1147.     if (bPos == contLen)
  1148.     {
  1149.       // dataBuffer[todo + bPos + 1] = '\0';
  1150.       break;
  1151.     }
  1152.   }
  1153.   netShutDown(socket, 1);
  1154. }
  1155.  
  1156. unsigned int tcpSend(unsigned char socket, unsigned int messageadr, unsigned int size)
  1157. {
  1158.   unsigned char retry = 20;
  1159.   unsigned int todo;
  1160.   readStruct.socket = socket;
  1161.   readStruct.BufAdr = messageadr;
  1162.   readStruct.bufsize = size;
  1163.   readStruct.protocol = SOCK_STREAM;
  1164.  
  1165. wizwrite:
  1166.   todo = OS_WIZNETWRITE(&readStruct);
  1167.   if (todo > 32767)
  1168.   {
  1169.     clearStatus();
  1170.     printf("OS_WIZNETWRITE: ");
  1171.     errorPrint(todo & 255);
  1172.     if (retry == 0)
  1173.     {
  1174.       exit(0);
  1175.     }
  1176.     retry--;
  1177.     delay(150);
  1178.     goto wizwrite;
  1179.   }
  1180.   else
  1181.   {
  1182.     if (logFlag)
  1183.     {
  1184.       clearStatus();
  1185.       printf("OS_WIZNETWRITE: %u bytes written.", todo);
  1186.     }
  1187.   }
  1188.   return todo;
  1189. }
  1190.  
  1191. unsigned long processJson(unsigned long startPos, unsigned char limit, unsigned char queryNum)
  1192. {
  1193.   FILE *fp3;
  1194.   unsigned int retry, tSize;
  1195.   unsigned int todo;
  1196.   unsigned char *count, socket;
  1197.   clearStatus();
  1198.   printf("Getting data(%u)...", queryNum);
  1199.  
  1200.   switch (queryNum)
  1201.   {
  1202.   case 0: // GET /api/export:zxMusic/limit:1/start:1/filter:zxMusicFormat=pt3/order:date,desc HTTP/1.1\r\nHost: zxart.ee\r\nUser-Agent: User-Agent: Mozilla/4.0 (compatible; MSIE5.01; NedoOS)
  1203.     strcpy(netbuf, "GET /api/export:zxMusic/limit:");
  1204.     sprintf(buffer, "%u", limit);
  1205.     strcat(netbuf, buffer);
  1206.     strcat(netbuf, "/start:");
  1207.     sprintf(buffer, "%lu", startPos);
  1208.     strcat(netbuf, buffer);
  1209.     strcat(netbuf, "/filter:zxMusicFormat=");
  1210.     strcat(netbuf, formats[curFormat]);
  1211.     strcat(netbuf, "/order:date,desc");
  1212.     strcat(netbuf, userAgent);
  1213.     break;
  1214.   case 1: // GET /api/types:zxMusic/export:zxMusic/language:eng/limit:1/start:0/order:votes,rand/filter:zxMusicMinRating=4;
  1215.     startPos = 0;
  1216.     strcpy(netbuf, "GET /api/types:zxMusic/export:zxMusic/language:eng/limit:");
  1217.     sprintf(buffer, "%u", limit);
  1218.     strcat(netbuf, buffer);
  1219.     strcat(netbuf, "/start:");
  1220.     sprintf(buffer, "%lu", startPos);
  1221.     strcat(netbuf, buffer);
  1222.     strcat(netbuf, "/order:votes,rand/filter:zxMusicMinRating=4;zxMusicFormat=");
  1223.     strcat(netbuf, formats[curFormat]);
  1224.     strcat(netbuf, userAgent);
  1225.     break;
  1226.   case 2: // GET /api/types:zxMusic/export:zxMusic/language:eng/limit:1/start:0/order:rand/filter:zxMusicFormat=PT3 HTTP/1.1\r\nHost: zxart.ee\r\nUser-Agent: User-Agent: Mozilla/4.0 (compatible; MSIE5.01; NedoOS)
  1227.     startPos = 0;
  1228.     strcpy(netbuf, "GET /api/types:zxMusic/export:zxMusic/language:eng/limit:");
  1229.     sprintf(buffer, "%u", limit);
  1230.     strcat(netbuf, buffer);
  1231.     strcat(netbuf, "/start:");
  1232.     sprintf(buffer, "%lu", startPos);
  1233.     strcat(netbuf, buffer);
  1234.     strcat(netbuf, "/order:rand/filter:zxMusicFormat=");
  1235.     strcat(netbuf, formats[curFormat]);
  1236.     strcat(netbuf, userAgent);
  1237.     break;
  1238.  
  1239.   case 3: // GET /api/export:zxMusic/limit:1/start:1/filter:zxMusicFormat=pt3;authorId=7744/order:date,desc HTTP/1.1\r\nHost: zxart.ee\r\nUser-Agent: User-Agent: Mozilla/4.0 (compatible; MSIE5.01; NedoOS)
  1240.  
  1241.     fp3 = OS_OPENHANDLE("radio/user.que", 0x80);
  1242.     if (((int)fp3) & 0xff)
  1243.     {
  1244.       fp3 = OS_CREATEHANDLE("radio/user.que", 0x80);
  1245.       OS_WRITEHANDLE(userQuery, fp3, sizeof(userQuery));
  1246.       OS_CLOSEHANDLE(fp3);
  1247.       fp3 = OS_OPENHANDLE("radio/user.que", 0x80);
  1248.     }
  1249.     OS_READHANDLE(userQuery, fp3, sizeof(userQuery));
  1250.     OS_CLOSEHANDLE(fp3);
  1251.  
  1252.     strcpy(netbuf, "GET /api/limit:");
  1253.     sprintf(buffer, "%u", limit);
  1254.     strcat(netbuf, buffer);
  1255.     strcat(netbuf, "/start:");
  1256.     sprintf(buffer, "%lu", startPos);
  1257.     strcat(netbuf, buffer);
  1258.     strcat(netbuf, userQuery);
  1259.     strcat(netbuf, userAgent);
  1260.     break;
  1261.  
  1262.   case 99: // GET /jsonElementData/elementId:182798
  1263.     strcpy(netbuf, "GET /jsonElementData/elementId:");
  1264.     sprintf(buffer, "%lu", startPos);
  1265.     strcat(netbuf, buffer);
  1266.     strcat(netbuf, userAgent);
  1267.     break;
  1268.   }
  1269.  
  1270.   retry = 10;
  1271.  
  1272.   while (42)
  1273.   {
  1274.     if (netDriver == 0)
  1275.     {
  1276.       socket = OpenSock(AF_INET, SOCK_STREAM);
  1277.       netConnect(socket);
  1278.       todo = tcpSend(socket, (unsigned int)&netbuf, strlen(netbuf));
  1279.       getData(socket);
  1280.       clearStatus();
  1281.       printf("Processing data (%u)...", queryNum);
  1282.     }
  1283.     else
  1284.     {
  1285.       fillDataBufferEsp();
  1286.     }
  1287.  
  1288.     count = strstr(dataBuffer, "responseStatus\":\"success");
  1289.     if (count == NULL)
  1290.     {
  1291.       retry--;
  1292.       clearStatus();
  1293.       printf("PROCESS JSON: [ERROR: Bad responseStatus.] [Query:%u][Retry:%u] [Track:%lu]\r\n", queryNum, retry, startPos);
  1294.       YIELD();
  1295.       if (retry < 1)
  1296.       {
  1297.         return -1;
  1298.       }
  1299.     }
  1300.     else
  1301.     {
  1302.       break;
  1303.     }
  1304.   }
  1305.   count = strstr(dataBuffer, "\"id\":");
  1306.   if (count == NULL)
  1307.   {
  1308.     clearStatus();
  1309.     printf("BAD JSON: not ID query = %u startPos = %lu", queryNum, startPos);
  1310.     return -2;
  1311.   }
  1312.   if (queryNum < 4)
  1313.   {
  1314.     netbuf[0] = '\0';
  1315.     parseJson("\"id\":");
  1316.     curFileStruct.picId = atol(netbuf);
  1317.     parseJson(",\"title\":\"");
  1318.     convert866();
  1319.     strcpy(curFileStruct.trackName, netbuf);
  1320.  
  1321.     tSize = sizeof(curFileStruct.trackName);
  1322.     stringRepair(curFileStruct.trackName, tSize);
  1323.  
  1324.     parseJson("\"rating\":\"");
  1325.     strcpy(curFileStruct.picRating, netbuf);
  1326.     parseJson("\"year\":\"");
  1327.     curFileStruct.picYear = atoi(netbuf);
  1328.     parseJson("\"totalAmount\":");
  1329.     curFileStruct.totalAmount = atol(netbuf);
  1330.     parseJson("\"time\":\"");
  1331.     strcpy(curFileStruct.time, netbuf);
  1332.     parseJson("\"authorIds\":[");
  1333.     strcpy(curFileStruct.authorIds, netbuf);
  1334.     parseJson("\"authorIds\":[");
  1335.     strcpy(curFileStruct.fileName2, netbuf);
  1336.   }
  1337.   if (queryNum == 99)
  1338.   {
  1339.     parseJson(",\"title\":\"");
  1340.     convert866();
  1341.     strcpy(curFileStruct.authorTitle, netbuf);
  1342.     parseJson(",\"realName\":\"");
  1343.     convert866();
  1344.     strcpy(curFileStruct.authorRealName, netbuf);
  1345.   }
  1346.   return curFileStruct.picId;
  1347. }
  1348.  
  1349. unsigned char getTrack2(unsigned long fileId)
  1350. {
  1351.   unsigned int todo;
  1352.   unsigned char socket;
  1353.   unsigned int skipHeader = 0;
  1354.   unsigned long bytecount;
  1355.   unsigned int packSize = 2000;
  1356.   unsigned char sizeLink;
  1357.   unsigned long toDownload, downloaded;
  1358.   unsigned char try = 0, byte = 0;
  1359.   unsigned int dataSize, count;
  1360.   unsigned char *count1;
  1361.   clearStatus();
  1362.   printf("Getting track...");
  1363.  
  1364.   if (netDriver == 0)
  1365.   {
  1366.     strcpy(netbuf, cmdlist1);
  1367.     sprintf(buffer, "%lu", fileId);
  1368.     strcat(netbuf, buffer);
  1369.     strcat(netbuf, userAgent);
  1370.  
  1371.     socket = OpenSock(AF_INET, SOCK_STREAM);
  1372.     todo = netConnect(socket);
  1373.     todo = tcpSend(socket, (unsigned int)&netbuf, strlen(netbuf));
  1374.     saveBuf(curFileStruct.picId, 00, 0);
  1375.     do
  1376.     {
  1377.       todo = tcpRead(socket);
  1378.       if (todo == 0)
  1379.       {
  1380.         break;
  1381.       }
  1382.       if (skipHeader == 0)
  1383.       {
  1384.         skipHeader = 1;
  1385.         todo = cutHeader(todo);
  1386.         bytecount = contLen;
  1387.       }
  1388.       saveBuf(curFileStruct.picId, 01, todo);
  1389.       bytecount = bytecount - todo;
  1390.     } while (bytecount != 0);
  1391.     netShutDown(socket, 0);
  1392.   }
  1393.   else
  1394.   {
  1395.     sprintf(buffer, "%lu", fileId);
  1396.     strcpy(netbuf, cmdlist1);
  1397.     strcat(netbuf, buffer);
  1398.     strcat(netbuf, userAgent);
  1399.     saveBuf(curFileStruct.picId, 00, 0);
  1400.  
  1401.     strcpy(link, netbuf);
  1402.     sizeLink = strlen(link);
  1403.     try = 0;
  1404.     do
  1405.     {
  1406.       try++;
  1407.       if (try > 1)
  1408.       {
  1409.         clearStatus();
  1410.         printf("----->Retry:%u", try);
  1411.         delay(500);
  1412.       }
  1413.       sendcommand("AT+CIPSTART=\"TCP\",\"zxart.ee\",80");
  1414.       getAnswer2(); // CONNECT or ERROR or link is not valid
  1415.       count1 = strstr(netbuf, "CONNECT");
  1416.     } while (count1 == NULL);
  1417.  
  1418.     getAnswer2(); // OK
  1419.  
  1420.     strcpy(netbuf, cmdlist1);
  1421.     sprintf(buffer, "%lu", fileId);
  1422.     strcat(netbuf, buffer);
  1423.     strcat(netbuf, userAgent);
  1424.     strcpy(cmd, "AT+CIPSEND=");
  1425.     sprintf(netbuf, "%u", sizeLink + 2); // second CRLF in send command
  1426.     strcat(cmd, netbuf);
  1427.     sendcommand(cmd);
  1428.     getAnswer2();
  1429.  
  1430.     do
  1431.     {
  1432.       byte = uart_readBlock();
  1433.       // putchar(byte);
  1434.     } while (byte != '>');
  1435.     sendcommand(link);
  1436.     count = 0;
  1437.  
  1438.     do
  1439.     {
  1440.       byte = uart_readBlock();
  1441.       if (byte == sendOk[count])
  1442.       {
  1443.         count++;
  1444.       }
  1445.       else
  1446.       {
  1447.         count = 0;
  1448.       }
  1449.     } while (count < strlen(sendOk));
  1450.     uart_readBlock(); // CR
  1451.     uart_readBlock(); // LF
  1452.     skipHeader = 0;
  1453.     downloaded = 0;
  1454.  
  1455.     do
  1456.     {
  1457.       headlng = 0;
  1458.       dataSize = recvHead();
  1459.       getdataEsp(dataSize); // Requested size
  1460.       if (skipHeader == 0)
  1461.       {
  1462.         dataSize = cutHeader(dataSize);
  1463.         toDownload = contLen;
  1464.         skipHeader = 1;
  1465.       }
  1466.       downloaded = downloaded + dataSize;
  1467.       saveBuf(curFileStruct.picId, 01, dataSize);
  1468.       toDownload = toDownload - dataSize;
  1469.     } while (toDownload > 0);
  1470.     sendcommand("AT+CIPCLOSE");
  1471.     getAnswer2(); // CLOSED
  1472.     getAnswer2(); // OK
  1473.     saveBuf(curFileStruct.picId, 02, 0);
  1474.   }
  1475.   return 0;
  1476. }
  1477. unsigned char runPlayer(void)
  1478. {
  1479.   FILE *fp2;
  1480.   unsigned long playerSize, loaded, loop;
  1481.   unsigned char pgbak;
  1482.   // writeLog("runPlayer() entry.\r\n");
  1483.   clearStatus();
  1484.   printf("Running player...");
  1485.   strcpy(appCmd, "player.com ");
  1486.   strcat(appCmd, curFileStruct.fileName);
  1487.   player_pg.l = OS_GETMAINPAGES();
  1488.   pgbak = main_pg.pgs.window_3;
  1489.   loaded = 0;
  1490.   OS_GETPATH((unsigned int)&curPath);
  1491.   OS_SETSYSDRV();
  1492.   fp2 = OS_OPENHANDLE(fileName, 0x80);
  1493.   if (((int)fp2) & 0xff)
  1494.   {
  1495.     clearStatus();
  1496.     printf("%s", fileName);
  1497.     printf(" not found.");
  1498.     exit(0);
  1499.   }
  1500.   playerSize = OS_GETFILESIZE(fp2);
  1501.   OS_CHDIR(curPath);
  1502.   OS_NEWAPP((unsigned int)&player_pg);
  1503.   SETPG32KHIGH(player_pg.pgs.window_3);
  1504.   memcpy((char *)(0xC080), &appCmd, sizeof(appCmd));
  1505.   for (loop = 0; loop < playerSize; loop = loop + loaded)
  1506.   {
  1507.     loaded = OS_READHANDLE(dataBuffer, fp2, sizeof(dataBuffer));
  1508.     memcpy((char *)(0xC100 + loop), &dataBuffer, loaded);
  1509.   }
  1510.   OS_CLOSEHANDLE(fp2);
  1511.   SETPG32KHIGH(pgbak);
  1512.   OS_RUNAPP(player_pg.pgs.pId);
  1513.  
  1514.   sprintf(toLog, "runPlayer() return [PID:%u]\r\n", player_pg.pgs.pId);
  1515.   // writeLog(toLog);
  1516.  
  1517.   return player_pg.pgs.pId;
  1518. }
  1519.  
  1520. long trackSelector(unsigned char mode)
  1521. {
  1522.   switch (mode)
  1523.   {
  1524.   case 0: // Next track
  1525.     count++;
  1526.     if (count > curFileStruct.totalAmount - 1)
  1527.     {
  1528.       count = 0;
  1529.     }
  1530.     break;
  1531.   case 1: // Prev. track
  1532.     count--;
  1533.     if (count < 0)
  1534.     {
  1535.       count = curFileStruct.totalAmount - 1;
  1536.     }
  1537.     break;
  1538.   }
  1539.   return count;
  1540. }
  1541.  
  1542. void printStatus(void)
  1543. {
  1544.   AT(1, 9);
  1545.   ATRIB(93);
  1546.   printf(" [Q]Query : ");
  1547.   ATRIB(97);
  1548.   printf("%s", queryType);
  1549.   printf("  ");
  1550.   AT(1, 24);
  1551.   ATRIB(45);
  1552.   printf("                                                                                ");
  1553.   AT(2, 24);
  1554.   ATRIB(93);
  1555.   printf(" [F]Format: ");
  1556.   ATRIB(97);
  1557.   printf("%s", formats[curFormat]);
  1558.   ATRIB(93);
  1559.   printf(" [K]Keep files: ");
  1560.   ATRIB(97);
  1561.   printf("%u", saveFlag);
  1562.   ATRIB(93);
  1563.   printf(" [R]Repeat: ");
  1564.   ATRIB(97);
  1565.   printf("%u", rptFlag);
  1566.   ATRIB(93);
  1567.   printf(" [J]Jump to ");
  1568.   printf(" [E]Exit        [%s]", ver);
  1569.  
  1570.   ATRIB(97);
  1571.   ATRIB(40);
  1572. }
  1573.  
  1574. void printInfo(void)
  1575. {
  1576.   BOX(30, 2, 50, 6, 40);
  1577.   AT(1, 2);
  1578.   ATRIB(97);
  1579.   ATRIB(93);
  1580.   printf(" #: ");
  1581.   ATRIB(97);
  1582.   printf("%lu", count);
  1583.   ATRIB(93);
  1584.   printf(" ID: ");
  1585.   ATRIB(97);
  1586.   printf("%lu", curFileStruct.picId);
  1587.   ATRIB(93);
  1588.   printf(" Total Tracks: ");
  1589.   ATRIB(97);
  1590.   printf("%lu", curFileStruct.totalAmount);
  1591.   printf(" \r\n");
  1592.   ATRIB(93);
  1593.   printf(" RATING: ");
  1594.   ATRIB(97);
  1595.   printf("%s", curFileStruct.picRating);
  1596.   ATRIB(93);
  1597.   printf(" YEAR: ");
  1598.   ATRIB(97);
  1599.   printf("%u", curFileStruct.picYear);
  1600.   ATRIB(93);
  1601.   printf(" DURATION: ");
  1602.   ATRIB(97);
  1603.   printf("%s", curFileStruct.time);
  1604.   printf(" \r\n\r\n");
  1605.   ATRIB(93);
  1606.   printf(" AuthorsIDs ");
  1607.   ATRIB(97);
  1608.   printf("%s", curFileStruct.authorIds);
  1609.   ATRIB(93);
  1610.   printf(" Author: ");
  1611.   ATRIB(97);
  1612.   printf("%s", curFileStruct.authorTitle);
  1613.   ATRIB(93);
  1614.   printf(" Real name: ");
  1615.   ATRIB(97);
  1616.   printf("%s", curFileStruct.authorRealName);
  1617.   printf(" \r\n\r\n");
  1618.   ATRIB(96);
  1619.   printf("                                                                           \r");
  1620.   printf("   TITLE: %s\r\n", curFileStruct.trackName);
  1621. }
  1622.  
  1623. unsigned char testPlayer(void)
  1624. {
  1625.   union APP_PAGES player2_pg;
  1626.   player2_pg.l = OS_GETAPPMAINPAGES(player_pg.pgs.pId);
  1627.   if (errno == 0)
  1628.   {
  1629.     return 1;
  1630.   }
  1631.   else
  1632.   {
  1633.     return 0;
  1634.   }
  1635. }
  1636.  
  1637. C_task main(int argc, char *argv[])
  1638. {
  1639.   unsigned char errn, keypress, queryNum, pId, alive, changedFormat;
  1640.   long iddqd, idkfa, ipadress;
  1641.   unsigned long curTimer, startTimer, oldTimer;
  1642.   os_initstdio();
  1643.   srand(time());
  1644.  
  1645.   count = 0;
  1646.   saveFlag = 0;
  1647.   logFlag = 0;
  1648.   queryNum = 0;
  1649.   curFormat = 0;
  1650.   changedFormat = 0;
  1651.   rptFlag = 0;
  1652.   netDriver = 0;
  1653.  
  1654.   if (argc > 1)
  1655.   {
  1656.     if ((argv[1][0] == 'e') || (argv[1][0] == 'E'))
  1657.     {
  1658.       netDriver = 1;
  1659.       clearStatus();
  1660.       printf("    ESP-COM mode enabled...");
  1661.       loadEspConfig();
  1662.       uart_init(divider);
  1663.       espReBoot();
  1664.       printHelp();
  1665.     }
  1666.   }
  1667.  
  1668.   strcpy(queryType, "from newest to oldest");
  1669.   BOX(1, 1, 80, 25, 40);
  1670.   AT(1, 1);
  1671.   ATRIB(97);
  1672.   ATRIB(45);
  1673.   printf("                           ZXART.EE radio for %s                           ", interfaces[netDriver]);
  1674.   AT(1, 24);
  1675.   printf("  [L]Enable logging(press on startup)                                          ");
  1676.  
  1677.   ATRIB(33);
  1678.   ATRIB(40);
  1679.  
  1680.   keypress = _low_level_get();
  1681.   if (keypress == 'l' || keypress == 'L')
  1682.   {
  1683.     logFlag = 1;
  1684.     clearStatus();
  1685.     printf("Logging enabled");
  1686.     getchar();
  1687.   }
  1688.  
  1689. start:
  1690.   // writeLog("\r\n**********[Start new track]**********\r\n");
  1691.   OS_SETSYSDRV();
  1692.   printHelp();
  1693.   curFileStruct.fileSize = 0;
  1694.  
  1695.   iddqd = processJson(count, 1, queryNum); // Query for track info
  1696.   if (iddqd < 0)
  1697.   {
  1698.     {
  1699.       clearStatus();
  1700.       printf("Error getting track info, next please(%ld)...", iddqd);
  1701.       count = trackSelector(0);
  1702.       goto start;
  1703.     }
  1704.   }
  1705.  
  1706.   idkfa = processJson(atol(curFileStruct.authorIds), 0, 99); // Query for AuthorID
  1707.  
  1708.   if (idkfa < 0)
  1709.   {
  1710.     clearStatus();
  1711.     printf("Error getting author %lu", atol(curFileStruct.authorIds));
  1712.     strcpy(curFileStruct.authorTitle, "-");
  1713.     strcpy(curFileStruct.authorRealName, "-");
  1714.   }
  1715.  
  1716.   sprintf(toLog, "Playing[%u][", curFileStruct.picId);
  1717.   // writeLog(toLog);
  1718.   // writeLog(curFileStruct.trackName);
  1719.   // writeLog("]\r\n");
  1720.  
  1721. replay:
  1722.  
  1723.   errn = getTrack2(iddqd); // Downloading the track
  1724.  
  1725. resume:
  1726.   startTimer = time();
  1727.   printProgress(0);
  1728.   // writeLog("runPlayer() before.\r\n");
  1729.   pId = runPlayer(); // Start the Player!
  1730.   // writeLog("runPlayer() after.\r\n");
  1731.   printStatus();
  1732.   printInfo();
  1733. rekey:
  1734.   keypress = _low_level_get();
  1735.   if (keypress != 0)
  1736.   {
  1737.     if (keypress == 27 || keypress == 'e' || keypress == 'E')
  1738.     {
  1739.       OS_DROPAPP(pId);
  1740.       BOX(1, 1, 80, 25, 40);
  1741.       AT(1, 1);
  1742.       printf("Good bye...\r\n");
  1743.       ATRIB(37);
  1744.       ATRIB(40);
  1745.       exit(0);
  1746.     }
  1747.     if (keypress == 248 || keypress == 'b' || keypress == 'B')
  1748.     {
  1749.       changedFormat = 0;
  1750.       OS_DROPAPP(pId);
  1751.       clearStatus();
  1752.       printf("Player stopped...");
  1753.       count = trackSelector(1);
  1754.       goto start;
  1755.     }
  1756.  
  1757.     if (keypress == 251 || keypress == 32 || keypress == 'n' || keypress == 'N')
  1758.     {
  1759.       changedFormat = 0;
  1760.       OS_DROPAPP(pId);
  1761.       clearStatus();
  1762.       printf("Player stopped...");
  1763.       count = trackSelector(0);
  1764.       goto start;
  1765.     }
  1766.  
  1767.     if (keypress == 'k' || keypress == 'K')
  1768.     {
  1769.       OS_DROPAPP(pId);
  1770.       clearStatus();
  1771.       printf("Player stopped...");
  1772.       saveFlag = !saveFlag;
  1773.       printStatus();
  1774.       changedFormat = 0;
  1775.       goto replay;
  1776.     }
  1777.  
  1778.     if (keypress == 'q' || keypress == 'Q')
  1779.     {
  1780.       OS_DROPAPP(pId);
  1781.       clearStatus();
  1782.       printf("Player stopped...");
  1783.       queryNum++;
  1784.       if (queryNum > 3)
  1785.       {
  1786.         queryNum = 0;
  1787.       }
  1788.       switch (queryNum)
  1789.       {
  1790.       case 0:
  1791.         strcpy(queryType, "from newest to oldest                   ");
  1792.         break;
  1793.       case 1:
  1794.         strcpy(queryType, "Random best and most voted tracks       ");
  1795.         break;
  1796.       case 2:
  1797.         strcpy(queryType, "Random play                             ");
  1798.         break;
  1799.       case 3:
  1800.         strcpy(queryType, "User defined query from \"user.que\"     ");
  1801.         break;
  1802.       }
  1803.       count = 0;
  1804.       changedFormat = 0;
  1805.       printStatus();
  1806.       goto start;
  1807.     }
  1808.  
  1809.     if (keypress == 'j' || keypress == 'J')
  1810.     {
  1811.       AT(1, 7);
  1812.       printf("                                                                      \r");
  1813.       printf("Jump to track:");
  1814.       scanf("%lu", &count);
  1815.       OS_DROPAPP(pId);
  1816.       if (count > curFileStruct.totalAmount - 1)
  1817.       {
  1818.         count = curFileStruct.totalAmount - 1;
  1819.       }
  1820.       changedFormat = 0;
  1821.       goto start;
  1822.     }
  1823.  
  1824.     if (keypress == 'f' || keypress == 'F')
  1825.     {
  1826.       OS_DROPAPP(pId);
  1827.       clearStatus();
  1828.       printf("Player stopped...");
  1829.       curFormat++;
  1830.       count = -1;
  1831.       if (curFormat > 3)
  1832.       {
  1833.         curFormat = 0;
  1834.       }
  1835.       changedFormat = 1;
  1836.       curFileStruct.totalAmount = 1;
  1837.       if (strstr(formats[curFormat], "tfc") != NULL)
  1838.       {
  1839.         cutOff = 5;
  1840.       }
  1841.       else
  1842.       {
  1843.         cutOff = 0;
  1844.       }
  1845.  
  1846.       printStatus();
  1847.       printProgress(0);
  1848.       BOX(1, 2, 80, 6, 40);
  1849.       goto rekey;
  1850.     }
  1851.  
  1852.     if (keypress == 'l' || keypress == 'L')
  1853.     {
  1854.       logFlag = !logFlag;
  1855.       clearStatus();
  1856.       printf("Logging: %u", logFlag);
  1857.     }
  1858.  
  1859.     if (keypress == 's' || keypress == 'S')
  1860.     {
  1861.       OS_DROPAPP(pId);
  1862.       clearStatus();
  1863.       printf("Player stopped...");
  1864.       printProgress(0);
  1865.       changedFormat = 1;
  1866.       getchar();
  1867.       goto resume;
  1868.     }
  1869.     if (keypress == 'r' || keypress == 'R')
  1870.     {
  1871.       rptFlag = !rptFlag;
  1872.       clearStatus();
  1873.       printStatus();
  1874.       goto rekey;
  1875.     }
  1876.     if (keypress == 'd' || keypress == 'D')
  1877.     {
  1878.       saveBak = saveFlag;
  1879.       saveFlag = 1;
  1880.  
  1881.       errn = getTrack2(iddqd); // Downloading the track
  1882.  
  1883.       saveFlag = saveBak;
  1884.       clearStatus();
  1885.       printf("File saved: [%s]...", curFileStruct.fileName);
  1886.       goto rekey;
  1887.     }
  1888.  
  1889.     if (keypress == 'i' || keypress == 'I')
  1890.     {
  1891.       netDriver = !netDriver;
  1892.       if (netDriver == 1)
  1893.       {
  1894.         clearStatus();
  1895.         printf("    ESP-COM mode enabled...");
  1896.         loadEspConfig();
  1897.         uart_init(divider);
  1898.         espReBoot();
  1899.         printHelp();
  1900.       }
  1901.       else
  1902.       {
  1903.         clearStatus();
  1904.         printf("    ZXNETUSB mode enabled...");
  1905.       }
  1906.       AT(1, 1);
  1907.       ATRIB(97);
  1908.       ATRIB(45);
  1909.       printf("                           ZXART.EE radio for %s                    ", interfaces[netDriver]);
  1910.       ATRIB(33);
  1911.       ATRIB(40);
  1912.     }
  1913.   }
  1914.  
  1915.   curTimer = time();
  1916.   curFileStruct.curPos = (curTimer - startTimer) / 50;
  1917.   alive++; // debug
  1918.   /*
  1919.     if ((curTimer - oldTimer) > 49)
  1920.     {
  1921.       alive = testPlayer();
  1922.       sprintf(toLog, ",%u", alive);
  1923.       //writeLog(toLog);
  1924.     }
  1925.     if (alive == 0 && !changedFormat)
  1926.     {
  1927.       if (rptFlag == 1)
  1928.       {
  1929.         goto resume;
  1930.       }
  1931.       //writeLog("\r\nalive == 0. Next track please.\r\n");
  1932.       printProgress(2);
  1933.       count = trackSelector(0);
  1934.       goto start;
  1935.     }
  1936.  
  1937.     if (alive == 1 && ((curTimer - oldTimer) > 49))
  1938.     {
  1939.       sprintf(toLog, ".%u", curFileStruct.trackInSeconds - curFileStruct.curPos);
  1940.       //writeLog(toLog);
  1941.       printProgress(1);
  1942.       oldTimer = curTimer;
  1943.     }
  1944.   */
  1945.  
  1946.   remainTime = curFileStruct.trackInSeconds - curFileStruct.curPos;
  1947.  
  1948.   if ((remainTime < cutOff) && !changedFormat)
  1949.   {
  1950.  
  1951.     OS_DROPAPP(pId);
  1952.     clearStatus();
  1953.     printf("Player stopped...");
  1954.  
  1955.     if (rptFlag == 1)
  1956.     {
  1957.       goto resume;
  1958.     }
  1959.     // writeLog("\r\nalive == 0. Next track please.\r\n");
  1960.     printProgress(2);
  1961.     count = trackSelector(0);
  1962.     goto start;
  1963.   }
  1964.   if ((curTimer - oldTimer) > 49 && !changedFormat)
  1965.   {
  1966.     sprintf(toLog, ".%u", remainTime);
  1967.     // writeLog(toLog);
  1968.     printProgress(1);
  1969.     oldTimer = curTimer;
  1970.   }
  1971.  
  1972.   YIELD();
  1973.   goto rekey;
  1974. }
  1975.