?login_element?

Subversion Repositories NedoOS

Rev

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