Subversion Repositories NedoOS

Rev

Rev 2336 | Blame | Compare with Previous | Last modification | View Log | Download

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