Subversion Repositories NedoOS

Rev

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