?login_element?

Subversion Repositories NedoOS

Rev

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