?login_element?

Subversion Repositories NedoOS

Rev

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

  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.   do
  661.   {
  662.     byte = uart_readBlock();
  663.     if (byte == gotWiFi[count])
  664.     {
  665.       count++;
  666.     }
  667.     else
  668.     {
  669.       count = 0;
  670.     }
  671.   } while (count < strlen(gotWiFi));
  672.   uart_readBlock(); // CR
  673.   uart_readBlock(); // LF
  674.   clearStatus();
  675.   printf("Reset complete.");
  676.  
  677.   sendcommand("ATE0");
  678.   do
  679.   {
  680.     byte = uart_readBlock();
  681.   } while (byte != 'K'); // OK
  682.   // clearStatus();
  683.   // puts("ATE0 Answer:[OK]");
  684.   uart_readBlock(); // CR
  685.   uart_readBlock(); // LN
  686.  
  687.   sendcommand("AT+CIPCLOSE");
  688.   getAnswer2();
  689.   sendcommand("AT+CIPDINFO=0");
  690.   getAnswer2();
  691.   sendcommand("AT+CIPMUX=0");
  692.   getAnswer2();
  693.   sendcommand("AT+CIPSERVER=0");
  694.   getAnswer2();
  695.   sendcommand("AT+CIPRECVMODE=0");
  696.   getAnswer2();
  697. }
  698.  
  699. unsigned int recvHead(void)
  700. {
  701.   unsigned char byte, dataRead = 0;
  702.   do
  703.   {
  704.     byte = uart_readBlock();
  705.   } while (byte != ',');
  706.  
  707.   dataRead = 0;
  708.   do
  709.   {
  710.     byte = uart_readBlock();
  711.     netbuf[dataRead] = byte;
  712.     dataRead++;
  713.   } while (byte != ':');
  714.   netbuf[dataRead] = 0;
  715.   loaded = atoi(netbuf); // <actual_len>
  716.   // printf("\r\n loaded %u\r\n", loaded);
  717.   return loaded;
  718. }
  719.  
  720. // in netbuf data to send
  721. unsigned int fillDataBufferEsp(void)
  722. {
  723.   unsigned char sizeLink;
  724.   unsigned long toDownload, downloaded;
  725.   unsigned char byte, count = 0, try = 0;
  726.   unsigned int dataSize;
  727.   unsigned char skipHeader;
  728.   unsigned char *count1;
  729.  
  730.   strcpy(link, netbuf);
  731.   sizeLink = strlen(link);
  732.   try = 0;
  733.   do
  734.   {
  735.     try++;
  736.     if (try > 1)
  737.     {
  738.       clearStatus();
  739.       printf("----->Retry:%u", try);
  740.       delay(500);
  741.     }
  742.     sendcommand("AT+CIPSTART=\"TCP\",\"zxart.ee\",80");
  743.     getAnswer2(); // CONNECT or ERROR or link is not valid
  744.     count1 = strstr(netbuf, "CONNECT");
  745.   } while (count1 == NULL);
  746.  
  747.   getAnswer2(); // OK
  748.  
  749.   strcpy(cmd, "AT+CIPSEND=");
  750.   sprintf(netbuf, "%u", sizeLink + 2); // second CRLF in send command
  751.   strcat(cmd, netbuf);
  752.   sendcommand(cmd);
  753.   getAnswer2();
  754.  
  755.   do
  756.   {
  757.     byte = uart_readBlock();
  758.     // putchar(byte);
  759.   } while (byte != '>');
  760.   sendcommand(link);
  761.   count = 0;
  762.   do
  763.   {
  764.     byte = uart_readBlock();
  765.     if (byte == sendOk[count])
  766.     {
  767.       count++;
  768.     }
  769.     else
  770.     {
  771.       count = 0;
  772.     }
  773.   } while (count < strlen(sendOk));
  774.   uart_readBlock(); // CR
  775.   uart_readBlock(); // LF
  776.   skipHeader = 0;
  777.   downloaded = 0;
  778.   do
  779.   {
  780.     headlng = 0;
  781.     dataSize = recvHead();
  782.     getdataEsp(dataSize); // Requested size
  783.     if (skipHeader == 0)
  784.     {
  785.       dataSize = cutHeader(dataSize);
  786.       toDownload = contLen;
  787.       skipHeader = 1;
  788.     }
  789.     downloaded = downloaded + dataSize;
  790.     memcpy(dataBuffer + downloaded - dataSize, netbuf + headlng, dataSize);
  791.     toDownload = toDownload - dataSize;
  792.   } while (toDownload > 0);
  793.   sendcommand("AT+CIPCLOSE");
  794.  
  795.   getAnswer2(); // CLOSED
  796.   getAnswer2(); // OK
  797.   return 0;
  798. }
  799. void loadEspConfig(void)
  800. {
  801.   unsigned char curParam[256];
  802.   unsigned char res;
  803.   FILE *espcom;
  804.   OS_SETSYSDRV();
  805.   OS_CHDIR("browser");
  806.   espcom = OS_OPENHANDLE("espcom.ini", 0x80);
  807.   if (((int)espcom) & 0xff)
  808.   {
  809.     clearStatus();
  810.     printf("mrfesp.ini opening error");
  811.     return;
  812.   }
  813.  
  814.   OS_READHANDLE(curParam, espcom, 256);
  815.  
  816.   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);
  817.   BOX(1, 15, 80, 8, 40);
  818.   AT(1, 15);
  819.   puts("Config loaded:");
  820.   if (comType == 1)
  821.   {
  822.     puts("     Controller base port: 0x55fe");
  823.   }
  824.   else
  825.   {
  826.     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);
  827.     printf("     MCR    :0x%4x     LSR    :0x%4x\r\n     MSR    :0x%4x     SR     :0x%4x\r\n", MCR, LSR, MSR, SR);
  828.   }
  829.   printf("     DIV    :%4u       TYPE   :%4u  \r\n     ESP    : %u ", divider, comType, espType);
  830.   switch (comType)
  831.   {
  832.   case 0:
  833.     puts("(16550 like w/o AFC)");
  834.     break;
  835.   case 1:
  836.     puts("(ATM Turbo 2+)");
  837.     break;
  838.   case 2:
  839.     puts("(16550 with AFC)");
  840.   default:
  841.     puts("(Unknown type)");
  842.     break;
  843.   }
  844. }
  845.  
  846. ////////////////////////ESP32 PROCEDURES//////////////////////
  847.  
  848. char *str_replace(char *dst, int num, const char *str,
  849.                   const char *orig, const char *rep)
  850. {
  851.   const char *ptr;
  852.   size_t len1 = strlen(orig);
  853.   size_t len2 = strlen(rep);
  854.   char *tmp = dst;
  855.  
  856.   num -= 1;
  857.   while ((ptr = strstr(str, orig)) != NULL)
  858.   {
  859.     num -= (ptr - str) + len2;
  860.     if (num < 1)
  861.       break;
  862.  
  863.     strncpy(dst, str, (size_t)(ptr - str));
  864.     dst += ptr - str;
  865.     strncpy(dst, rep, len2);
  866.     dst += len2;
  867.     str = ptr + len1;
  868.   }
  869.  
  870.   for (; (*dst = *str) && (num > 0); --num)
  871.   {
  872.     ++dst;
  873.     ++str;
  874.   }
  875.   return tmp;
  876. }
  877.  
  878. const char *parseJson(unsigned char *property)
  879. {
  880.   unsigned int w, lng, lngp1, findEnd, listPos;
  881.   unsigned char terminator;
  882.   int n;
  883.   n = -1;
  884.   netbuf[0] = '\0';
  885.   n = pos(dataBuffer, property, 1, 0);
  886.   if (n == -1)
  887.   {
  888.     strcpy(netbuf, "0\0");
  889.     return netbuf;
  890.   }
  891.   lng = n - 1 + strlen(property);
  892.   if (dataBuffer[lng] == ':')
  893.   {
  894.     terminator = '\0';
  895.   }
  896.   if (dataBuffer[lng] == '\"')
  897.   {
  898.     terminator = '\"';
  899.   }
  900.   if (dataBuffer[lng] == '[')
  901.   {
  902.     terminator = ']';
  903.   }
  904.  
  905.   findEnd = 1;
  906.   lngp1 = lng + 1;
  907.  
  908.   while (42)
  909.   {
  910.  
  911.     if ((dataBuffer[lngp1 + findEnd] == ','))
  912.     {
  913.       if (terminator == '\0')
  914.       {
  915.         break;
  916.       }
  917.       if ((dataBuffer[lng + findEnd] == terminator))
  918.       {
  919.         findEnd--;
  920.         break;
  921.       }
  922.     }
  923.     findEnd++;
  924.   }
  925.   listPos = 0;
  926.   for (w = lngp1; w < findEnd + lngp1; w++)
  927.   {
  928.     netbuf[listPos] = dataBuffer[w];
  929.     listPos++;
  930.   }
  931.   netbuf[listPos] = '\0';
  932.   return netbuf;
  933. }
  934. void convert866(void)
  935. {
  936.   unsigned int lng, targetPos, w, q = 0;
  937.   unsigned char buffer[8], one, two;
  938.   unsigned int decVal;
  939.   lng = strlen(netbuf);
  940.   targetPos = lng + 1;
  941.  
  942.   while (q < lng)
  943.   {
  944.     one = netbuf[q];
  945.     two = netbuf[q + 1];
  946.     if (one == 92 && two == 117)
  947.     {
  948.       q = q + 2;
  949.       for (w = 0; w < 4; w++)
  950.       {
  951.         buffer[w] = netbuf[q + w];
  952.       }
  953.       q = q + 4;
  954.       buffer[4] = '\0';
  955.       decVal = (unsigned int)strtol(buffer, NULL, 16);
  956.  
  957.       if (decVal < 1088)
  958.       {
  959.         decVal = decVal - 912;
  960.       }
  961.       if (decVal > 1087)
  962.       {
  963.         decVal = decVal - 864;
  964.       }
  965.       if (decVal == 1025)
  966.       {
  967.         decVal = 240;
  968.       }
  969.       if (decVal == 1105)
  970.       {
  971.         decVal = 241;
  972.       }
  973.       netbuf[targetPos] = decVal;
  974.     }
  975.     else
  976.     {
  977.       netbuf[targetPos] = netbuf[q];
  978.       q++;
  979.     }
  980.     targetPos++;
  981.   }
  982.   netbuf[targetPos] = '\0';
  983.  
  984.   for (w = lng + 1; w < targetPos + 1; w++)
  985.   {
  986.     netbuf[w - lng - 1] = netbuf[w];
  987.   }
  988. }
  989.  
  990. void nameRepair(unsigned char *pfn, unsigned int tfnSize)
  991. {
  992.   str_replace(pfn, tfnSize, pfn, "\\", "_");
  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, "&#039;", "'");
  1002.   str_replace(pfn, tfnSize, pfn, "&amp;", "&");
  1003.   str_replace(pfn, tfnSize, pfn, "&quot;", "'");
  1004.   str_replace(pfn, tfnSize, pfn, "&gt;", ")");
  1005.   str_replace(pfn, tfnSize, pfn, "&lt;", "(");
  1006.   str_replace(pfn, tfnSize, pfn, "\"", "'");
  1007. }
  1008.  
  1009. void stringRepair(unsigned char *pfn, unsigned int tSize)
  1010. {
  1011.   str_replace(pfn, tSize, pfn, "&#039;", "'");
  1012.   str_replace(pfn, tSize, pfn, "&amp;", "&");
  1013.   str_replace(pfn, tSize, pfn, "&gt;", ">");
  1014.   str_replace(pfn, tSize, pfn, "&lt;", "<");
  1015.   str_replace(pfn, tSize, pfn, "&quot;", "\"");
  1016.   str_replace(pfn, tSize, pfn, "\\/", "/");
  1017. }
  1018.  
  1019. void ncReplace(void)
  1020. {
  1021.   unsigned char len;
  1022.   for (len = 0; len < strlen(curFileStruct.afn); len++)
  1023.   {
  1024.     if (curFileStruct.afn[len] < ' ')
  1025.     {
  1026.       curFileStruct.afn[len] = '_';
  1027.     }
  1028.   }
  1029.  
  1030.   for (len = 0; len < strlen(curFileStruct.tfn); len++)
  1031.   {
  1032.     if (curFileStruct.tfn[len] < ' ')
  1033.     {
  1034.       curFileStruct.tfn[len] = '_';
  1035.     }
  1036.   }
  1037. }
  1038.  
  1039. unsigned char saveBuf(unsigned long fileId, unsigned char operation, unsigned int sizeOfBuf)
  1040. {
  1041.   FILE *fp2;
  1042.   unsigned long fileSize;
  1043.   unsigned char afnSize, tfnSize;
  1044.   unsigned char fileIdChar[10];
  1045.  
  1046.   if (operation == 00)
  1047.   {
  1048.  
  1049.     if (saveFlag == 0)
  1050.     {
  1051.       sprintf(curFileStruct.fileName, "temp.%s", formats[curFormat]);
  1052.     }
  1053.     else
  1054.     {
  1055.       afnSize = sizeof(curFileStruct.afn) - 1;
  1056.       tfnSize = sizeof(curFileStruct.tfn) - 1;
  1057.  
  1058.       strcpy(curFileStruct.afn, curFileStruct.authorTitle);
  1059.       nameRepair(curFileStruct.afn, afnSize);
  1060.       strcpy(curFileStruct.tfn, curFileStruct.trackName);
  1061.       nameRepair(curFileStruct.tfn, tfnSize);
  1062.       sprintf(curFileStruct.fileName, "%s-%s.%s", curFileStruct.afn, curFileStruct.tfn, formats[curFormat]);
  1063.       ncReplace();
  1064.  
  1065.       if (strlen(curFileStruct.fileName) > 63)
  1066.       {
  1067.         sprintf(fileIdChar, "-%ld", fileId);
  1068.         str_replace(curFileStruct.fileName, sizeof(curFileStruct.fileName) - 1, curFileStruct.fileName, fileIdChar, "");
  1069.         curFileStruct.fileName[50] = '\0';
  1070.         strcat(curFileStruct.fileName, fileIdChar);
  1071.         strcat(curFileStruct.fileName, formats[curFormat]);
  1072.       }
  1073.     }
  1074.     OS_SETSYSDRV();
  1075.     OS_MKDIR("../downloads/radio"); // Create if not exist
  1076.     OS_CHDIR("../downloads/radio");
  1077.     fp2 = OS_CREATEHANDLE(curFileStruct.fileName, 0x80);
  1078.     if (((int)fp2) & 0xff)
  1079.     {
  1080.       clearStatus();
  1081.       printf("%s creating error. Check for  downloads\\radio folder.", curFileStruct.fileName);
  1082.       getchar();
  1083.       exit(0);
  1084.     }
  1085.     OS_CLOSEHANDLE(fp2);
  1086.     return 0;
  1087.   }
  1088.  
  1089.   if (operation == 01)
  1090.   {
  1091.     fp2 = OS_OPENHANDLE(curFileStruct.fileName, 0x80);
  1092.     if (((int)fp2) & 0xff)
  1093.     {
  1094.  
  1095.       clearStatus();
  1096.       printf("%s opening error.", curFileStruct.fileName);
  1097.       exit(0);
  1098.     }
  1099.     fileSize = OS_GETFILESIZE(fp2);
  1100.     OS_SEEKHANDLE(fp2, fileSize);
  1101.     OS_WRITEHANDLE(netbuf, fp2, sizeOfBuf);
  1102.     OS_CLOSEHANDLE(fp2);
  1103.     return 0;
  1104.   }
  1105.  
  1106.   if (operation == 02)
  1107.   {
  1108.     OS_CLOSEHANDLE(fp2);
  1109.     return 0;
  1110.   }
  1111.  
  1112.   return 0;
  1113. }
  1114.  
  1115. void getData(unsigned char socket)
  1116. {
  1117.   unsigned int todo, w, bPos, skipHeader;
  1118.  
  1119.   skipHeader = 0;
  1120.   bPos = 0;
  1121.   while (1)
  1122.   {
  1123.     todo = tcpRead(socket);
  1124.     if (todo == 0)
  1125.     {
  1126.       break;
  1127.     }
  1128.     if (skipHeader == 0)
  1129.     {
  1130.       skipHeader = 1;
  1131.       todo = cutHeader(todo);
  1132.     }
  1133.  
  1134.     if (bPos + todo > sizeof(dataBuffer))
  1135.     {
  1136.       clearStatus();
  1137.       printf("dataBuffer overrun...");
  1138.       break;
  1139.     }
  1140.  
  1141.     for (w = 0; w < todo; w++)
  1142.     {
  1143.       dataBuffer[w + bPos] = netbuf[w];
  1144.     }
  1145.     bPos = bPos + todo;
  1146.     if (bPos == contLen)
  1147.     {
  1148.       // dataBuffer[todo + bPos + 1] = '\0';
  1149.       break;
  1150.     }
  1151.   }
  1152.   netShutDown(socket, 1);
  1153. }
  1154.  
  1155. unsigned int tcpSend(unsigned char socket, unsigned int messageadr, unsigned int size)
  1156. {
  1157.   unsigned char retry = 20;
  1158.   unsigned int todo;
  1159.   readStruct.socket = socket;
  1160.   readStruct.BufAdr = messageadr;
  1161.   readStruct.bufsize = size;
  1162.   readStruct.protocol = SOCK_STREAM;
  1163.  
  1164. wizwrite:
  1165.   todo = OS_WIZNETWRITE(&readStruct);
  1166.   if (todo > 32767)
  1167.   {
  1168.     clearStatus();
  1169.     printf("OS_WIZNETWRITE: ");
  1170.     errorPrint(todo & 255);
  1171.     if (retry == 0)
  1172.     {
  1173.       exit(0);
  1174.     }
  1175.     retry--;
  1176.     delay(150);
  1177.     goto wizwrite;
  1178.   }
  1179.   else
  1180.   {
  1181.     if (logFlag)
  1182.     {
  1183.       clearStatus();
  1184.       printf("OS_WIZNETWRITE: %u bytes written.", todo);
  1185.     }
  1186.   }
  1187.   return todo;
  1188. }
  1189.  
  1190. unsigned long processJson(unsigned long startPos, unsigned char limit, unsigned char queryNum)
  1191. {
  1192.   FILE *fp3;
  1193.   unsigned int retry, tSize;
  1194.   unsigned int todo;
  1195.   unsigned char *count, socket;
  1196.   clearStatus();
  1197.   printf("Getting data(%u)...", queryNum);
  1198.  
  1199.   switch (queryNum)
  1200.   {
  1201.   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)
  1202.     strcpy(netbuf, "GET /api/export:zxMusic/limit:");
  1203.     sprintf(buffer, "%u", limit);
  1204.     strcat(netbuf, buffer);
  1205.     strcat(netbuf, "/start:");
  1206.     sprintf(buffer, "%lu", startPos);
  1207.     strcat(netbuf, buffer);
  1208.     strcat(netbuf, "/filter:zxMusicFormat=");
  1209.     strcat(netbuf, formats[curFormat]);
  1210.     strcat(netbuf, "/order:date,desc");
  1211.     strcat(netbuf, userAgent);
  1212.     break;
  1213.   case 1: // GET /api/types:zxMusic/export:zxMusic/language:eng/limit:1/start:0/order:votes,rand/filter:zxMusicMinRating=4;
  1214.     startPos = 0;
  1215.     strcpy(netbuf, "GET /api/types:zxMusic/export:zxMusic/language:eng/limit:");
  1216.     sprintf(buffer, "%u", limit);
  1217.     strcat(netbuf, buffer);
  1218.     strcat(netbuf, "/start:");
  1219.     sprintf(buffer, "%lu", startPos);
  1220.     strcat(netbuf, buffer);
  1221.     strcat(netbuf, "/order:votes,rand/filter:zxMusicMinRating=4;zxMusicFormat=");
  1222.     strcat(netbuf, formats[curFormat]);
  1223.     strcat(netbuf, userAgent);
  1224.     break;
  1225.   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)
  1226.     startPos = 0;
  1227.     strcpy(netbuf, "GET /api/types:zxMusic/export:zxMusic/language:eng/limit:");
  1228.     sprintf(buffer, "%u", limit);
  1229.     strcat(netbuf, buffer);
  1230.     strcat(netbuf, "/start:");
  1231.     sprintf(buffer, "%lu", startPos);
  1232.     strcat(netbuf, buffer);
  1233.     strcat(netbuf, "/order:rand/filter:zxMusicFormat=");
  1234.     strcat(netbuf, formats[curFormat]);
  1235.     strcat(netbuf, userAgent);
  1236.     break;
  1237.  
  1238.   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)
  1239.  
  1240.     fp3 = OS_OPENHANDLE("radio/user.que", 0x80);
  1241.     if (((int)fp3) & 0xff)
  1242.     {
  1243.       fp3 = OS_CREATEHANDLE("radio/user.que", 0x80);
  1244.       OS_WRITEHANDLE(userQuery, fp3, sizeof(userQuery));
  1245.       OS_CLOSEHANDLE(fp3);
  1246.       fp3 = OS_OPENHANDLE("radio/user.que", 0x80);
  1247.     }
  1248.     OS_READHANDLE(userQuery, fp3, sizeof(userQuery));
  1249.     OS_CLOSEHANDLE(fp3);
  1250.  
  1251.     strcpy(netbuf, "GET /api/limit:");
  1252.     sprintf(buffer, "%u", limit);
  1253.     strcat(netbuf, buffer);
  1254.     strcat(netbuf, "/start:");
  1255.     sprintf(buffer, "%lu", startPos);
  1256.     strcat(netbuf, buffer);
  1257.     strcat(netbuf, userQuery);
  1258.     strcat(netbuf, userAgent);
  1259.     break;
  1260.  
  1261.   case 99: // GET /jsonElementData/elementId:182798
  1262.     strcpy(netbuf, "GET /jsonElementData/elementId:");
  1263.     sprintf(buffer, "%lu", startPos);
  1264.     strcat(netbuf, buffer);
  1265.     strcat(netbuf, userAgent);
  1266.     break;
  1267.   }
  1268.  
  1269.   retry = 10;
  1270.  
  1271.   while (42)
  1272.   {
  1273.     if (netDriver == 0)
  1274.     {
  1275.       socket = OpenSock(AF_INET, SOCK_STREAM);
  1276.       netConnect(socket);
  1277.       todo = tcpSend(socket, (unsigned int)&netbuf, strlen(netbuf));
  1278.       getData(socket);
  1279.       clearStatus();
  1280.       printf("Processing data (%u)...", queryNum);
  1281.     }
  1282.     else
  1283.     {
  1284.       fillDataBufferEsp();
  1285.     }
  1286.  
  1287.     count = strstr(dataBuffer, "responseStatus\":\"success");
  1288.     if (count == NULL)
  1289.     {
  1290.       retry--;
  1291.       clearStatus();
  1292.       printf("PROCESS JSON: [ERROR: Bad responseStatus.] [Query:%u][Retry:%u] [Track:%lu]\r\n", queryNum, retry, startPos);
  1293.       YIELD();
  1294.       if (retry < 1)
  1295.       {
  1296.         return -1;
  1297.       }
  1298.     }
  1299.     else
  1300.     {
  1301.       break;
  1302.     }
  1303.   }
  1304.   count = strstr(dataBuffer, "\"id\":");
  1305.   if (count == NULL)
  1306.   {
  1307.     clearStatus();
  1308.     printf("BAD JSON: not ID query = %u startPos = %lu", queryNum, startPos);
  1309.     return -2;
  1310.   }
  1311.   if (queryNum < 4)
  1312.   {
  1313.     netbuf[0] = '\0';
  1314.     parseJson("\"id\":");
  1315.     curFileStruct.picId = atol(netbuf);
  1316.     parseJson(",\"title\":\"");
  1317.     convert866();
  1318.     strcpy(curFileStruct.trackName, netbuf);
  1319.  
  1320.     tSize = sizeof(curFileStruct.trackName);
  1321.     stringRepair(curFileStruct.trackName, tSize);
  1322.  
  1323.     parseJson("\"rating\":\"");
  1324.     strcpy(curFileStruct.picRating, netbuf);
  1325.     parseJson("\"year\":\"");
  1326.     curFileStruct.picYear = atoi(netbuf);
  1327.     parseJson("\"totalAmount\":");
  1328.     curFileStruct.totalAmount = atol(netbuf);
  1329.     parseJson("\"time\":\"");
  1330.     strcpy(curFileStruct.time, netbuf);
  1331.     parseJson("\"authorIds\":[");
  1332.     strcpy(curFileStruct.authorIds, netbuf);
  1333.     parseJson("\"authorIds\":[");
  1334.     strcpy(curFileStruct.fileName2, netbuf);
  1335.   }
  1336.   if (queryNum == 99)
  1337.   {
  1338.     parseJson(",\"title\":\"");
  1339.     convert866();
  1340.     strcpy(curFileStruct.authorTitle, netbuf);
  1341.     parseJson(",\"realName\":\"");
  1342.     convert866();
  1343.     strcpy(curFileStruct.authorRealName, netbuf);
  1344.   }
  1345.   return curFileStruct.picId;
  1346. }
  1347.  
  1348. unsigned char getTrack2(unsigned long fileId)
  1349. {
  1350.   unsigned int todo;
  1351.   unsigned char socket;
  1352.   unsigned int skipHeader = 0;
  1353.   unsigned long bytecount;
  1354.   unsigned int packSize = 2000;
  1355.   unsigned char sizeLink;
  1356.   unsigned long toDownload, downloaded;
  1357.   unsigned char try = 0, byte = 0;
  1358.   unsigned int dataSize, count;
  1359.   unsigned char *count1;
  1360.   clearStatus();
  1361.   printf("Getting track...");
  1362.  
  1363.   if (netDriver == 0)
  1364.   {
  1365.     strcpy(netbuf, cmdlist1);
  1366.     sprintf(buffer, "%lu", fileId);
  1367.     strcat(netbuf, buffer);
  1368.     strcat(netbuf, userAgent);
  1369.  
  1370.     socket = OpenSock(AF_INET, SOCK_STREAM);
  1371.     todo = netConnect(socket);
  1372.     todo = tcpSend(socket, (unsigned int)&netbuf, strlen(netbuf));
  1373.     saveBuf(curFileStruct.picId, 00, 0);
  1374.     do
  1375.     {
  1376.       todo = tcpRead(socket);
  1377.       if (todo == 0)
  1378.       {
  1379.         break;
  1380.       }
  1381.       if (skipHeader == 0)
  1382.       {
  1383.         skipHeader = 1;
  1384.         todo = cutHeader(todo);
  1385.         bytecount = contLen;
  1386.       }
  1387.       saveBuf(curFileStruct.picId, 01, todo);
  1388.       bytecount = bytecount - todo;
  1389.     } while (bytecount != 0);
  1390.     netShutDown(socket, 0);
  1391.   }
  1392.   else
  1393.   {
  1394.     sprintf(buffer, "%lu", fileId);
  1395.     strcpy(netbuf, cmdlist1);
  1396.     strcat(netbuf, buffer);
  1397.     strcat(netbuf, userAgent);
  1398.     saveBuf(curFileStruct.picId, 00, 0);
  1399.  
  1400.     strcpy(link, netbuf);
  1401.     sizeLink = strlen(link);
  1402.     try = 0;
  1403.     do
  1404.     {
  1405.       try++;
  1406.       if (try > 1)
  1407.       {
  1408.         clearStatus();
  1409.         printf("----->Retry:%u", try);
  1410.         delay(500);
  1411.       }
  1412.       sendcommand("AT+CIPSTART=\"TCP\",\"zxart.ee\",80");
  1413.       getAnswer2(); // CONNECT or ERROR or link is not valid
  1414.       count1 = strstr(netbuf, "CONNECT");
  1415.     } while (count1 == NULL);
  1416.  
  1417.     getAnswer2(); // OK
  1418.  
  1419.     strcpy(netbuf, cmdlist1);
  1420.     sprintf(buffer, "%lu", fileId);
  1421.     strcat(netbuf, buffer);
  1422.     strcat(netbuf, userAgent);
  1423.     strcpy(cmd, "AT+CIPSEND=");
  1424.     sprintf(netbuf, "%u", sizeLink + 2); // second CRLF in send command
  1425.     strcat(cmd, netbuf);
  1426.     sendcommand(cmd);
  1427.     getAnswer2();
  1428.  
  1429.     do
  1430.     {
  1431.       byte = uart_readBlock();
  1432.       // putchar(byte);
  1433.     } while (byte != '>');
  1434.     sendcommand(link);
  1435.     count = 0;
  1436.  
  1437.     do
  1438.     {
  1439.       byte = uart_readBlock();
  1440.       if (byte == sendOk[count])
  1441.       {
  1442.         count++;
  1443.       }
  1444.       else
  1445.       {
  1446.         count = 0;
  1447.       }
  1448.     } while (count < strlen(sendOk));
  1449.     uart_readBlock(); // CR
  1450.     uart_readBlock(); // LF
  1451.     skipHeader = 0;
  1452.     downloaded = 0;
  1453.  
  1454.     do
  1455.     {
  1456.       headlng = 0;
  1457.       dataSize = recvHead();
  1458.       getdataEsp(dataSize); // Requested size
  1459.       if (skipHeader == 0)
  1460.       {
  1461.         dataSize = cutHeader(dataSize);
  1462.         toDownload = contLen;
  1463.         skipHeader = 1;
  1464.       }
  1465.       downloaded = downloaded + dataSize;
  1466.       saveBuf(curFileStruct.picId, 01, dataSize);
  1467.       toDownload = toDownload - dataSize;
  1468.     } while (toDownload > 0);
  1469.     sendcommand("AT+CIPCLOSE");
  1470.     getAnswer2(); // CLOSED
  1471.     getAnswer2(); // OK
  1472.   }
  1473.   return 0;
  1474. }
  1475. unsigned char runPlayer(void)
  1476. {
  1477.   FILE *fp2;
  1478.   unsigned long playerSize, loaded, loop;
  1479.   unsigned char pgbak;
  1480.   // writeLog("runPlayer() entry.\r\n");
  1481.   clearStatus();
  1482.   printf("Running player...");
  1483.   strcpy(appCmd, "player.com ");
  1484.   strcat(appCmd, curFileStruct.fileName);
  1485.   player_pg.l = OS_GETMAINPAGES();
  1486.   pgbak = main_pg.pgs.window_3;
  1487.   loaded = 0;
  1488.   OS_GETPATH((unsigned int)&curPath);
  1489.   OS_SETSYSDRV();
  1490.   fp2 = OS_OPENHANDLE(fileName, 0x80);
  1491.   if (((int)fp2) & 0xff)
  1492.   {
  1493.     clearStatus();
  1494.     printf("%s", fileName);
  1495.     printf(" not found.");
  1496.     exit(0);
  1497.   }
  1498.   playerSize = OS_GETFILESIZE(fp2);
  1499.   OS_CHDIR(curPath);
  1500.   OS_NEWAPP((unsigned int)&player_pg);
  1501.   SETPG32KHIGH(player_pg.pgs.window_3);
  1502.   memcpy((char *)(0xC080), &appCmd, sizeof(appCmd));
  1503.   for (loop = 0; loop < playerSize; loop = loop + loaded)
  1504.   {
  1505.     loaded = OS_READHANDLE(dataBuffer, fp2, sizeof(dataBuffer));
  1506.     memcpy((char *)(0xC100 + loop), &dataBuffer, loaded);
  1507.   }
  1508.   OS_CLOSEHANDLE(fp2);
  1509.   SETPG32KHIGH(pgbak);
  1510.   OS_RUNAPP(player_pg.pgs.pId);
  1511.  
  1512.   sprintf(toLog, "runPlayer() return [PID:%u]\r\n", player_pg.pgs.pId);
  1513.   // writeLog(toLog);
  1514.  
  1515.   return player_pg.pgs.pId;
  1516. }
  1517.  
  1518. long trackSelector(unsigned char mode)
  1519. {
  1520.   switch (mode)
  1521.   {
  1522.   case 0: // Next track
  1523.     count++;
  1524.     if (count > curFileStruct.totalAmount - 1)
  1525.     {
  1526.       count = 0;
  1527.     }
  1528.     break;
  1529.   case 1: // Prev. track
  1530.     count--;
  1531.     if (count < 0)
  1532.     {
  1533.       count = curFileStruct.totalAmount - 1;
  1534.     }
  1535.     break;
  1536.   }
  1537.   return count;
  1538. }
  1539.  
  1540. void printStatus(void)
  1541. {
  1542.   AT(1, 9);
  1543.   ATRIB(93);
  1544.   printf(" [Q]Query : ");
  1545.   ATRIB(97);
  1546.   printf("%s", queryType);
  1547.   printf("  ");
  1548.   AT(1, 24);
  1549.   ATRIB(45);
  1550.   printf("                                                                                ");
  1551.   AT(2, 24);
  1552.   ATRIB(93);
  1553.   printf(" [F]Format: ");
  1554.   ATRIB(97);
  1555.   printf("%s", formats[curFormat]);
  1556.   ATRIB(93);
  1557.   printf(" [K]Keep files: ");
  1558.   ATRIB(97);
  1559.   printf("%u", saveFlag);
  1560.   ATRIB(93);
  1561.   printf(" [R]Repeat: ");
  1562.   ATRIB(97);
  1563.   printf("%u", rptFlag);
  1564.   ATRIB(93);
  1565.   printf(" [J]Jump to ");
  1566.   printf(" [E]Exit        [%s]", ver);
  1567.  
  1568.   ATRIB(97);
  1569.   ATRIB(40);
  1570. }
  1571.  
  1572. void printInfo(void)
  1573. {
  1574.   BOX(30, 2, 50, 6, 40);
  1575.   AT(1, 2);
  1576.   ATRIB(97);
  1577.   ATRIB(93);
  1578.   printf(" #: ");
  1579.   ATRIB(97);
  1580.   printf("%lu", count);
  1581.   ATRIB(93);
  1582.   printf(" ID: ");
  1583.   ATRIB(97);
  1584.   printf("%lu", curFileStruct.picId);
  1585.   ATRIB(93);
  1586.   printf(" Total Tracks: ");
  1587.   ATRIB(97);
  1588.   printf("%lu", curFileStruct.totalAmount);
  1589.   printf(" \r\n");
  1590.   ATRIB(93);
  1591.   printf(" RATING: ");
  1592.   ATRIB(97);
  1593.   printf("%s", curFileStruct.picRating);
  1594.   ATRIB(93);
  1595.   printf(" YEAR: ");
  1596.   ATRIB(97);
  1597.   printf("%u", curFileStruct.picYear);
  1598.   ATRIB(93);
  1599.   printf(" DURATION: ");
  1600.   ATRIB(97);
  1601.   printf("%s", curFileStruct.time);
  1602.   printf(" \r\n\r\n");
  1603.   ATRIB(93);
  1604.   printf(" AuthorsIDs ");
  1605.   ATRIB(97);
  1606.   printf("%s", curFileStruct.authorIds);
  1607.   ATRIB(93);
  1608.   printf(" Author: ");
  1609.   ATRIB(97);
  1610.   printf("%s", curFileStruct.authorTitle);
  1611.   ATRIB(93);
  1612.   printf(" Real name: ");
  1613.   ATRIB(97);
  1614.   printf("%s", curFileStruct.authorRealName);
  1615.   printf(" \r\n\r\n");
  1616.   ATRIB(96);
  1617.   printf("                                                                           \r");
  1618.   printf("   TITLE: %s\r\n", curFileStruct.trackName);
  1619. }
  1620.  
  1621. unsigned char testPlayer(void)
  1622. {
  1623.   union APP_PAGES player2_pg;
  1624.   player2_pg.l = OS_GETAPPMAINPAGES(player_pg.pgs.pId);
  1625.   if (errno == 0)
  1626.   {
  1627.     return 1;
  1628.   }
  1629.   else
  1630.   {
  1631.     return 0;
  1632.   }
  1633. }
  1634.  
  1635. C_task main(int argc, char *argv[])
  1636. {
  1637.   unsigned char errn, keypress, queryNum, pId, alive, changedFormat;
  1638.   long iddqd, idkfa, ipadress;
  1639.   unsigned long curTimer, startTimer, oldTimer;
  1640.   os_initstdio();
  1641.   srand(time());
  1642.  
  1643.   count = 0;
  1644.   saveFlag = 0;
  1645.   logFlag = 0;
  1646.   queryNum = 0;
  1647.   curFormat = 0;
  1648.   changedFormat = 0;
  1649.   rptFlag = 0;
  1650.   netDriver = 0;
  1651.  
  1652.   if (argc > 1)
  1653.   {
  1654.     if ((argv[1][0] == 'e') || (argv[1][0] == 'E'))
  1655.     {
  1656.       netDriver = 1;
  1657.       clearStatus();
  1658.       printf("    ESP32 mode enabled...");
  1659.       loadEspConfig();
  1660.       uart_init(divider);
  1661.       espReBoot();
  1662.       printHelp();
  1663.     }
  1664.   }
  1665.  
  1666.   strcpy(queryType, "from newest to oldest");
  1667.   BOX(1, 1, 80, 25, 40);
  1668.   AT(1, 1);
  1669.   ATRIB(97);
  1670.   ATRIB(45);
  1671.   printf("                           ZXART.EE radio for %s                           ", interfaces[netDriver]);
  1672.   AT(1, 24);
  1673.   printf("  [L]Enable logging(press on startup)                                          ");
  1674.  
  1675.   ATRIB(33);
  1676.   ATRIB(40);
  1677.  
  1678.   keypress = _low_level_get();
  1679.   if (keypress == 'l' || keypress == 'L')
  1680.   {
  1681.     logFlag = 1;
  1682.     clearStatus();
  1683.     printf("Logging enabled");
  1684.     getchar();
  1685.   }
  1686.  
  1687. start:
  1688.   // writeLog("\r\n**********[Start new track]**********\r\n");
  1689.   OS_SETSYSDRV();
  1690.   printHelp();
  1691.   curFileStruct.fileSize = 0;
  1692.  
  1693.   iddqd = processJson(count, 1, queryNum); // Query for track info
  1694.   if (iddqd < 0)
  1695.   {
  1696.     {
  1697.       clearStatus();
  1698.       printf("Error getting track info, next please(%ld)...", iddqd);
  1699.       count = trackSelector(0);
  1700.       goto start;
  1701.     }
  1702.   }
  1703.  
  1704.   idkfa = processJson(atol(curFileStruct.authorIds), 0, 99); // Query for AuthorID
  1705.  
  1706.   if (idkfa < 0)
  1707.   {
  1708.     clearStatus();
  1709.     printf("Error getting author %lu", atol(curFileStruct.authorIds));
  1710.     strcpy(curFileStruct.authorTitle, "-");
  1711.     strcpy(curFileStruct.authorRealName, "-");
  1712.   }
  1713.  
  1714.   sprintf(toLog, "Playing[%u][", curFileStruct.picId);
  1715.   // writeLog(toLog);
  1716.   // writeLog(curFileStruct.trackName);
  1717.   // writeLog("]\r\n");
  1718.  
  1719. replay:
  1720.  
  1721.   errn = getTrack2(iddqd); // Downloading the track
  1722.  
  1723. resume:
  1724.   startTimer = time();
  1725.   printProgress(0);
  1726.   // writeLog("runPlayer() before.\r\n");
  1727.   pId = runPlayer(); // Start the Player!
  1728.   // writeLog("runPlayer() after.\r\n");
  1729.   printStatus();
  1730.   printInfo();
  1731. rekey:
  1732.   keypress = _low_level_get();
  1733.   if (keypress != 0)
  1734.   {
  1735.     if (keypress == 27 || keypress == 'e' || keypress == 'E')
  1736.     {
  1737.       OS_DROPAPP(pId);
  1738.       BOX(1, 1, 80, 25, 40);
  1739.       AT(1, 1);
  1740.       printf("Good bye...\r\n");
  1741.       ATRIB(37);
  1742.       ATRIB(40);
  1743.       exit(0);
  1744.     }
  1745.     if (keypress == 248 || keypress == 'b' || keypress == 'B')
  1746.     {
  1747.       changedFormat = 0;
  1748.       OS_DROPAPP(pId);
  1749.       clearStatus();
  1750.       printf("Player stopped...");
  1751.       count = trackSelector(1);
  1752.       goto start;
  1753.     }
  1754.  
  1755.     if (keypress == 251 || keypress == 32 || keypress == 'n' || keypress == 'N')
  1756.     {
  1757.       changedFormat = 0;
  1758.       OS_DROPAPP(pId);
  1759.       clearStatus();
  1760.       printf("Player stopped...");
  1761.       count = trackSelector(0);
  1762.       goto start;
  1763.     }
  1764.  
  1765.     if (keypress == 'k' || keypress == 'K')
  1766.     {
  1767.       OS_DROPAPP(pId);
  1768.       clearStatus();
  1769.       printf("Player stopped...");
  1770.       saveFlag = !saveFlag;
  1771.       printStatus();
  1772.       changedFormat = 0;
  1773.       goto replay;
  1774.     }
  1775.  
  1776.     if (keypress == 'q' || keypress == 'Q')
  1777.     {
  1778.       OS_DROPAPP(pId);
  1779.       clearStatus();
  1780.       printf("Player stopped...");
  1781.       queryNum++;
  1782.       if (queryNum > 3)
  1783.       {
  1784.         queryNum = 0;
  1785.       }
  1786.       switch (queryNum)
  1787.       {
  1788.       case 0:
  1789.         strcpy(queryType, "from newest to oldest                   ");
  1790.         break;
  1791.       case 1:
  1792.         strcpy(queryType, "Random best and most voted tracks       ");
  1793.         break;
  1794.       case 2:
  1795.         strcpy(queryType, "Random play                             ");
  1796.         break;
  1797.       case 3:
  1798.         strcpy(queryType, "User defined query from \"user.que\"     ");
  1799.         break;
  1800.       }
  1801.       count = 0;
  1802.       changedFormat = 0;
  1803.       printStatus();
  1804.       goto start;
  1805.     }
  1806.  
  1807.     if (keypress == 'j' || keypress == 'J')
  1808.     {
  1809.       AT(1, 7);
  1810.       printf("                                                                      \r");
  1811.       printf("Jump to track:");
  1812.       scanf("%lu", &count);
  1813.       OS_DROPAPP(pId);
  1814.       if (count > curFileStruct.totalAmount - 1)
  1815.       {
  1816.         count = curFileStruct.totalAmount - 1;
  1817.       }
  1818.       changedFormat = 0;
  1819.       goto start;
  1820.     }
  1821.  
  1822.     if (keypress == 'f' || keypress == 'F')
  1823.     {
  1824.       OS_DROPAPP(pId);
  1825.       clearStatus();
  1826.       printf("Player stopped...");
  1827.       curFormat++;
  1828.       count = -1;
  1829.       if (curFormat > 3)
  1830.       {
  1831.         curFormat = 0;
  1832.       }
  1833.       changedFormat = 1;
  1834.       curFileStruct.totalAmount = 1;
  1835.       if (strstr(formats[curFormat], "tfc") != NULL)
  1836.       {
  1837.         cutOff = 5;
  1838.       }
  1839.       else
  1840.       {
  1841.         cutOff = 0;
  1842.       }
  1843.  
  1844.       printStatus();
  1845.       printProgress(0);
  1846.       BOX(1, 2, 80, 6, 40);
  1847.       goto rekey;
  1848.     }
  1849.  
  1850.     if (keypress == 'l' || keypress == 'L')
  1851.     {
  1852.       logFlag = !logFlag;
  1853.       clearStatus();
  1854.       printf("Logging: %u", logFlag);
  1855.     }
  1856.  
  1857.     if (keypress == 's' || keypress == 'S')
  1858.     {
  1859.       OS_DROPAPP(pId);
  1860.       clearStatus();
  1861.       printf("Player stopped...");
  1862.       printProgress(0);
  1863.       changedFormat = 1;
  1864.       getchar();
  1865.       goto resume;
  1866.     }
  1867.     if (keypress == 'r' || keypress == 'R')
  1868.     {
  1869.       rptFlag = !rptFlag;
  1870.       clearStatus();
  1871.       printStatus();
  1872.       goto rekey;
  1873.     }
  1874.     if (keypress == 'd' || keypress == 'D')
  1875.     {
  1876.       saveBak = saveFlag;
  1877.       saveFlag = 1;
  1878.  
  1879.       errn = getTrack2(iddqd); // Downloading the track
  1880.  
  1881.       saveFlag = saveBak;
  1882.       clearStatus();
  1883.       printf("File saved: [%s]...", curFileStruct.fileName);
  1884.       goto rekey;
  1885.     }
  1886.  
  1887.     if (keypress == 'i' || keypress == 'I')
  1888.     {
  1889.       netDriver = !netDriver;
  1890.       if (netDriver == 1)
  1891.       {
  1892.         clearStatus();
  1893.         printf("    ESP32 mode enabled...");
  1894.         loadEspConfig();
  1895.         uart_init(divider);
  1896.         espReBoot();
  1897.         printHelp();
  1898.       }
  1899.       else
  1900.       {
  1901.         clearStatus();
  1902.         printf("    ZXNETUSB mode enabled...");
  1903.       }
  1904.       AT(1, 1);
  1905.       ATRIB(97);
  1906.       ATRIB(45);
  1907.       printf("                           ZXART.EE radio for %s                    ", interfaces[netDriver]);
  1908.       ATRIB(33);
  1909.       ATRIB(40);
  1910.     }
  1911.   }
  1912.  
  1913.   curTimer = time();
  1914.   curFileStruct.curPos = (curTimer - startTimer) / 50;
  1915.   alive++; // debug
  1916.   /*
  1917.     if ((curTimer - oldTimer) > 49)
  1918.     {
  1919.       alive = testPlayer();
  1920.       sprintf(toLog, ",%u", alive);
  1921.       //writeLog(toLog);
  1922.     }
  1923.     if (alive == 0 && !changedFormat)
  1924.     {
  1925.       if (rptFlag == 1)
  1926.       {
  1927.         goto resume;
  1928.       }
  1929.       //writeLog("\r\nalive == 0. Next track please.\r\n");
  1930.       printProgress(2);
  1931.       count = trackSelector(0);
  1932.       goto start;
  1933.     }
  1934.  
  1935.     if (alive == 1 && ((curTimer - oldTimer) > 49))
  1936.     {
  1937.       sprintf(toLog, ".%u", curFileStruct.trackInSeconds - curFileStruct.curPos);
  1938.       //writeLog(toLog);
  1939.       printProgress(1);
  1940.       oldTimer = curTimer;
  1941.     }
  1942.   */
  1943.  
  1944.   remainTime = curFileStruct.trackInSeconds - curFileStruct.curPos;
  1945.  
  1946.   if ((remainTime < cutOff) && !changedFormat)
  1947.   {
  1948.  
  1949.     OS_DROPAPP(pId);
  1950.     clearStatus();
  1951.     printf("Player stopped...");
  1952.  
  1953.     if (rptFlag == 1)
  1954.     {
  1955.       goto resume;
  1956.     }
  1957.     // writeLog("\r\nalive == 0. Next track please.\r\n");
  1958.     printProgress(2);
  1959.     count = trackSelector(0);
  1960.     goto start;
  1961.   }
  1962.   if ((curTimer - oldTimer) > 49 && !changedFormat)
  1963.   {
  1964.     sprintf(toLog, ".%u", remainTime);
  1965.     // writeLog(toLog);
  1966.     printProgress(1);
  1967.     oldTimer = curTimer;
  1968.   }
  1969.  
  1970.   YIELD();
  1971.   goto rekey;
  1972. }
  1973.