?login_element?

Subversion Repositories NedoOS

Rev

Rev 2067 | Rev 2108 | Go to most recent revision | Blame | Compare with Previous | Last modification | View Log | Download | RSS feed

  1. #include <math.h>
  2. #include <stdlib.h>
  3. #include <stdio.h>
  4. #include <string.h>
  5. #include <oscalls.h>
  6. #include <osfs.h>
  7. #include <intrz80.h>
  8. #include <ctype.h>
  9. #include <tcp.h>
  10. #include <graphic.h>
  11. #include <terminal.c>
  12.  
  13. unsigned int RBR_THR = 0xf8ef;
  14. unsigned int IER = 0xf9ef;
  15. unsigned int IIR_FCR = 0xfaef;
  16. unsigned int LCR = 0xfbef;
  17. unsigned int MCR = 0xfcef;
  18. unsigned int LSR = 0xfdef;
  19. unsigned int MSR = 0xfeef;
  20. unsigned int SR = 0xffef;
  21. unsigned int divider = 1;
  22. unsigned char comType = 0;
  23. unsigned int espType = 32;
  24.  
  25. unsigned char picture[16384];
  26. unsigned char netbuf[8000];
  27.  
  28. struct fileStruct
  29. {
  30.   long picId;
  31.   unsigned int picYear;
  32.   unsigned long totalAmount;
  33.   unsigned char picRating[8];
  34.   unsigned char picName[256];
  35.   unsigned char picType[64];
  36.   unsigned char authorIds[64];
  37.   unsigned char authorTitle[64];
  38.   unsigned char authorRealName[64];
  39.   unsigned char afn[128];
  40.   unsigned char pfn[128];
  41.   unsigned char fileName[128];
  42. } curFileStruct;
  43.  
  44. unsigned char ver[] = "2.8";
  45. const unsigned char sendOk[] = "SEND OK";
  46. const unsigned char gotWiFi[] = "WIFI GOT IP";
  47. unsigned char buffer[] = "0000000000";
  48. unsigned char userAgent[] = " HTTP/1.1\r\nHost: zxart.ee\r\nUser-Agent: Mozilla/4.0 (compatible; MSIE5.01; NedoOS; GetPic)\r\n\r\n\0";
  49. unsigned char keypress, verbose, randomPic, slideShow, netDriver;
  50.  
  51. unsigned long contLen;
  52. unsigned long count = 0;
  53. unsigned int headlng;
  54. unsigned int slideShowTime = 0;
  55. unsigned int loaded;
  56.  
  57. unsigned char crlf[2] = {13, 10};
  58. unsigned char cmd[512];
  59. unsigned char link[512];
  60. unsigned char fileIdChar[10];
  61.  
  62. struct sockaddr_in targetadr;
  63. struct readstructure readStruct;
  64. struct packetStruct
  65. {
  66.   unsigned long contLen;
  67.   unsigned int headlng;
  68. } pack;
  69.  
  70. void emptyKeys(void)
  71. {
  72.   unsigned char loop, key;
  73.   do
  74.   {
  75.     key = _low_level_get();
  76.     if (loop > 64)
  77.     {
  78.       break;
  79.     }
  80.     loop++;
  81.   } while (key != 0);
  82. }
  83.  
  84. void printHelp(void)
  85. {
  86.   ATRIB(95);
  87.   printf("   GETPIC [%s] zxart.ee picture viewer for nedoNET\n\r", ver);
  88.   ATRIB(33);
  89.   ATRIB(40);
  90.   printf("-------------------------------------------------------\n\r");
  91.   printf(" Управление:\n\r");
  92.   printf(" 'ESC' - выход из программы;\n\r");
  93.   printf(" '<-' или 'B' к последним картинкам;\n\r");
  94.   printf(" '->' или 'Пробел' к более старым картинкам\n\r");
  95.   printf(" 'J' Прыжок на  указанную по счету картинку\n\r");
  96.   printf(" 'I' Просмотр экрана информации о картинках\n\r");
  97.   printf(" 'S' Сохранить картинку на диск в текущую папку\n\r");
  98.   printf(" 'V' не выводить информацию об авторах\n\r");
  99.   printf(" 'R' переход в режим  случайная картинка с рейтингом 4+\n\r");
  100.   printf(" 'A' переход в режим  слайд-шоу\n\r");
  101.   printf(" 'D' Переключение режима ZXNETUSB/ESP-AT\n\r");
  102.   printf(" 'H' Данная справочная информация\n\r");
  103.   printf("-----------------Нажмите любую кнопку------------------\n\r");
  104.   ATRIB(93);
  105.   keypress = getchar();
  106. }
  107. void delay(unsigned long counter)
  108. {
  109.   unsigned long start, finish;
  110.   counter = counter / 20;
  111.   if (counter < 1)
  112.   {
  113.     counter = 1;
  114.   }
  115.   start = time();
  116.   finish = start + counter;
  117.  
  118.   while (start < finish)
  119.   {
  120.     start = time();
  121.   }
  122. }
  123.  
  124. unsigned int httpError(void)
  125. {
  126.   unsigned char *httpRes;
  127.   unsigned int httpErr;
  128.   httpRes = strstr(netbuf, "HTTP/1.1 ");
  129.  
  130.   if (httpRes != NULL)
  131.   {
  132.     httpErr = atol(httpRes + 9);
  133.   }
  134.   else
  135.   {
  136.     httpErr = 0;
  137.   }
  138.   return httpErr;
  139. }
  140.  
  141. void errorPrint(unsigned int error)
  142. {
  143.   switch (error)
  144.   {
  145.   case 2:
  146.     printf("02 SHUT_RDWR");
  147.     break;
  148.   case 4:
  149.     printf("04 ERR_INTR");
  150.     break;
  151.   case 23:
  152.     printf("23 ERR_NFILE");
  153.     break;
  154.   case 35:
  155.     printf("35 ERR_EAGAIN");
  156.     break;
  157.   case 37:
  158.     printf("37 ERR_ALREADY");
  159.     break;
  160.   case 38:
  161.     printf("38 ERR_NOTSOCK");
  162.     break;
  163.   case 40:
  164.     printf("40 ERR_EMSGSIZE");
  165.     break;
  166.   case 41:
  167.     printf("41 ERR_PROTOTYPE");
  168.     break;
  169.   case 47:
  170.     printf("47 ERR_AFNOSUPPORT");
  171.     break;
  172.   case 53:
  173.     printf("53 ERR_ECONNABORTED");
  174.     break;
  175.   case 54:
  176.     printf("54 ERR_CONNRESET");
  177.     break;
  178.   case 57:
  179.     printf("57 ERR_NOTCONN");
  180.     break;
  181.   case 65:
  182.     printf("65 ERR_HOSTUNREACH");
  183.     break;
  184.   default:
  185.     printf("%u UNKNOWN ERROR", error);
  186.     break;
  187.   }
  188. }
  189.  
  190. signed char OpenSock(unsigned char family, unsigned char protocol)
  191. {
  192.   signed char socket;
  193.   unsigned int todo;
  194.   todo = OS_NETSOCKET((family << 8) + protocol);
  195.   if (todo > 32767)
  196.   {
  197.     printf("OS_NETSOCKET: [ERROR:");
  198.     errorPrint(todo & 255);
  199.     printf("] Press any key.");
  200.     getchar();
  201.     exit(0);
  202.   }
  203.   else
  204.   {
  205.     socket = ((todo & 65280) >> 8);
  206.     // printf("OS_NETSOCKET: Socket #%d created\n\r", socket);
  207.   }
  208.   return socket;
  209. }
  210.  
  211. signed char netShutDown(signed char socket, unsigned char type)
  212. {
  213.   unsigned int todo;
  214.   todo = OS_NETSHUTDOWN(socket, type);
  215.   if (todo > 32767)
  216.   {
  217.     printf("OS_NETSHUTDOWN: [ERROR:");
  218.     errorPrint(todo & 255);
  219.     return -1;
  220.   }
  221.   else
  222.   {
  223.     // printf("Socket #%d closed.\n\r", socket);
  224.   }
  225.   return 1;
  226. }
  227.  
  228. unsigned char netConnect(signed char socket)
  229. {
  230.   unsigned int todo, retry = 10;
  231.  
  232.   targetadr.family = AF_INET;
  233.   targetadr.porth = 00;
  234.   targetadr.portl = 80;
  235.   targetadr.b1 = 217;
  236.   targetadr.b2 = 146;
  237.   targetadr.b3 = 69;
  238.   targetadr.b4 = 13;
  239.   while (retry != 0)
  240.   {
  241.     todo = OS_NETCONNECT(socket, &targetadr);
  242.  
  243.     if (todo > 32767)
  244.     {
  245.       retry--;
  246.       printf("OS_NETCONNECT [ERROR:");
  247.       errorPrint(todo & 255);
  248.       printf("] [Retry:%u] [Pic:%lu]\r\n", retry, count);
  249.       YIELD();
  250.       netShutDown(socket, 0);
  251.       puts("before socket");
  252.       socket = OpenSock(AF_INET, SOCK_STREAM);
  253.       puts("after socket");
  254.     }
  255.     else
  256.     {
  257.       // printf("OS_NETCONNECT: connection successful, %u\n\r", (todo & 255));
  258.       return 1;
  259.     }
  260.   }
  261.   puts("try to exit");
  262.   getchar();
  263.   exit(0);
  264.   return 0;
  265. }
  266.  
  267. unsigned int tcpSend(signed char socket, unsigned int messageadr, unsigned int size)
  268. {
  269.   unsigned char retry = 10;
  270.   unsigned int todo;
  271.   readStruct.socket = socket;
  272.   readStruct.BufAdr = messageadr;
  273.   readStruct.bufsize = size;
  274.   readStruct.protocol = SOCK_STREAM;
  275.   while (retry > 0)
  276.   {
  277.     todo = OS_WIZNETWRITE(&readStruct);
  278.     if (todo > 32767)
  279.     {
  280.       printf("OS_WIZNETWRITE: [ERROR:");
  281.       errorPrint(todo & 255);
  282.       printf("] [Retry:%u] [Pic:%lu]\r\n", retry, count);
  283.       YIELD();
  284.       retry--;
  285.     }
  286.     else
  287.     {
  288.       // printf("OS_WIZNETWRITE: %u bytes written. \n\r", todo);
  289.       return todo;
  290.     }
  291.   }
  292.  
  293.   getchar();
  294.   exit(0);
  295.   return todo;
  296. }
  297.  
  298. unsigned int tcpRead(signed char socket)
  299. {
  300.   unsigned char retry = 10;
  301.   unsigned int todo;
  302.  
  303.   readStruct.socket = socket;
  304.   readStruct.BufAdr = (unsigned int)&netbuf;
  305.   readStruct.bufsize = sizeof(netbuf);
  306.   readStruct.protocol = SOCK_STREAM;
  307.  
  308.   while (retry > 0)
  309.   {
  310.     todo = OS_WIZNETREAD(&readStruct);
  311.  
  312.     if (todo > 32767)
  313.     {
  314.       if ((todo & 255) != ERR_EAGAIN)
  315.       {
  316.         printf("OS_WIZNETREAD: [ERROR:");
  317.         errorPrint(todo & 255);
  318.         printf("] [Retry:%u] [Pic:%lu]\r\n", retry, count);
  319.         YIELD();
  320.         retry--;
  321.       }
  322.     }
  323.     else
  324.     {
  325.       // printf("OS_WIZNETREAD: %u bytes read. \n\r", todo);
  326.       return todo;
  327.     }
  328.   }
  329.   getchar();
  330.   exit(0);
  331.   return todo;
  332. }
  333. unsigned int cutHeader(unsigned int todo)
  334. {
  335.   unsigned int err;
  336.   unsigned char *count1;
  337.  
  338.   err = httpError();
  339.   if (err != 200)
  340.   {
  341.     printf("\r\nHTTP response:[%u]\r\n", err);
  342.     printf("^^^^^^^^^^^^^^^^^^^^^\r\n");
  343.     puts(netbuf);
  344.     getchar();
  345.   }
  346.   count1 = strstr(netbuf, "Content-Length:");
  347.   if (count1 == NULL)
  348.   {
  349.     printf("contLen  not found \r\n");
  350.     contLen = 0;
  351.   }
  352.   else
  353.   {
  354.     contLen = atol(count1 + 15);
  355.     // printf("Content-Length: %lu \n\r", contLen);
  356.   }
  357.  
  358.   count1 = strstr(netbuf, "\r\n\r\n");
  359.   if (count1 == NULL)
  360.   {
  361.     printf("header not found\r\n");
  362.   }
  363.   else
  364.   {
  365.     headlng = ((unsigned int)count1 - (unsigned int)netbuf + 4);
  366.     // printf("header %u bytes\r\n", headlng);
  367.   }
  368.   return todo - headlng;
  369. }
  370.  
  371. ////////////////////////ESP32 PROCEDURES//////////////////////
  372. void uart_write(unsigned char data)
  373. {
  374.   unsigned char status;
  375.   switch (comType)
  376.   {
  377.   case 0:
  378.   case 2:
  379.     while ((input(LSR) & 64) == 0)
  380.     {
  381.     }
  382.     output(RBR_THR, data);
  383.     break;
  384.   case 1:
  385.     disable_interrupt();
  386.     do
  387.     {
  388.       input(0x55fe);          // Переход в режим команд
  389.       status = input(0x42fe); // Команда прочесть статус
  390.     } while ((status & 64) == 0); // Проверяем 6 бит
  391.  
  392.     input(0x55fe);               // Переход в режим команд
  393.     input(0x03fe);               // Команда записать в порт
  394.     input((data << 8) | 0x00fe); // Записываем data в порт
  395.     enable_interrupt();
  396.     break;
  397.   }
  398. }
  399.  
  400. void uart_setrts(unsigned char mode)
  401. {
  402.   switch (comType)
  403.   {
  404.   case 0:
  405.     switch (mode)
  406.     {
  407.     case 1:
  408.       output(MCR, 2);
  409.       break;
  410.     case 0:
  411.       output(MCR, 0);
  412.       break;
  413.     default:
  414.       disable_interrupt();
  415.       output(MCR, 2);
  416.       output(MCR, 0);
  417.       enable_interrupt();
  418.       break;
  419.     }
  420.   case 1:
  421.     switch (mode)
  422.     {
  423.     case 1:
  424.       disable_interrupt();
  425.       input(0x55fe); // Переход в режим команд
  426.       input(0x43fe); // Команда установить статус
  427.       input(0x03fe); // Устанавливаем готовность DTR и RTS
  428.       enable_interrupt();
  429.       break;
  430.     case 0:
  431.       disable_interrupt();
  432.       input(0x55fe); // Переход в режим команд
  433.       input(0x43fe); // Команда установить статус
  434.       input(0x00fe); // Снимаем готовность DTR и RTS
  435.       enable_interrupt();
  436.       break;
  437.     default:
  438.       disable_interrupt();
  439.       input(0x55fe); // Переход в режим команд
  440.       input(0x43fe); // Команда установить статус
  441.       input(0x03fe); // Устанавливаем готовность DTR и RTS
  442.  
  443.       input(0x55fe); // Переход в режим команд
  444.       input(0x43fe); // Команда установить статус
  445.       input(0x00fe); // Снимаем готовность DTR и RTS
  446.       enable_interrupt();
  447.       break;
  448.     }
  449.   case 2:
  450.     break;
  451.   }
  452. }
  453.  
  454. void uart_init(unsigned char divisor)
  455. {
  456.   switch (comType)
  457.   {
  458.   case 0:
  459.   case 2:
  460.     output(MCR, 0x00);        // Disable input
  461.     output(IIR_FCR, 0x87);    // Enable fifo 8 level, and clear it
  462.     output(LCR, 0x83);        // 8n1, DLAB=1
  463.     output(RBR_THR, divisor); // 115200 (divider 1-115200, 3 - 38400)
  464.     output(IER, 0x00);        // (divider 0). Divider is 16 bit, so we get (#0002 divider)
  465.     output(LCR, 0x03);        // 8n1, DLAB=0
  466.     output(IER, 0x00);        // Disable int
  467.     output(MCR, 0x2f);        // Enable AFE
  468.     break;
  469.   case 1:
  470.     disable_interrupt();
  471.     input(0x55fe);
  472.     input(0xc3fe);
  473.     input((divisor << 8) | 0x00fe);
  474.     enable_interrupt();
  475.     break;
  476.   }
  477. }
  478.  
  479. unsigned char uart_hasByte(void)
  480. {
  481.   unsigned char queue;
  482.   switch (comType)
  483.   {
  484.   case 0:
  485.   case 2:
  486.     return (1 & input(LSR));
  487.   case 1:
  488.     disable_interrupt();
  489.     input(0x55fe);         // Переход в режим команд
  490.     queue = input(0xc2fe); // Получаем количество байт в приемном буфере
  491.     enable_interrupt();
  492.     return queue;
  493.   }
  494.   return 255;
  495. }
  496.  
  497. unsigned char uart_read(void)
  498. {
  499.   unsigned char data;
  500.   switch (comType)
  501.   {
  502.   case 0:
  503.   case 2:
  504.     return input(RBR_THR);
  505.   case 1:
  506.     disable_interrupt();
  507.     input(0x55fe);        // Переход в режим команд
  508.     data = input(0x02fe); // Команда прочесть из порта
  509.     enable_interrupt();
  510.     return data;
  511.   }
  512.   return 255;
  513. }
  514.  
  515. unsigned char uart_readBlock(void)
  516. {
  517.   unsigned char data;
  518.   switch (comType)
  519.   {
  520.   case 0:
  521.     while (uart_hasByte() == 0)
  522.     {
  523.       uart_setrts(2);
  524.     }
  525.     return input(RBR_THR);
  526.   case 1:
  527.     while (uart_hasByte() == 0)
  528.     {
  529.       uart_setrts(2);
  530.     }
  531.     disable_interrupt();
  532.     input(0x55fe);        // Переход в режим команд
  533.     data = input(0x02fe); // Команда прочесть из порта
  534.     enable_interrupt();
  535.     return data;
  536.   case 2:
  537.     while (uart_hasByte() == 0)
  538.     {
  539.     }
  540.     return input(RBR_THR);
  541.   }
  542.   return 255;
  543. }
  544.  
  545. void uart_flush(void)
  546. {
  547.   unsigned int count;
  548.   for (count = 0; count < 6000; count++)
  549.   {
  550.     disable_interrupt();
  551.     uart_setrts(1);
  552.     enable_interrupt();
  553.     uart_read();
  554.   }
  555.   printf("\r\nBuffer cleared.\r\n");
  556. }
  557. void getdataEsp(unsigned int counted)
  558. {
  559.   unsigned int counter;
  560.   for (counter = 0; counter < counted; counter++)
  561.   {
  562.     netbuf[counter] = uart_readBlock();
  563.   }
  564.   netbuf[counter] = 0;
  565. }
  566.  
  567. void sendcommand(char *commandline)
  568. {
  569.   unsigned int count, cmdLen;
  570.   cmdLen = strlen(commandline);
  571.   for (count = 0; count < cmdLen; count++)
  572.   {
  573.     uart_write(commandline[count]);
  574.   }
  575.   uart_write('\r');
  576.   uart_write('\n');
  577.   // printf("Sended:[%s] \r\n", commandline);
  578. }
  579.  
  580. unsigned char getAnswer2(void)
  581. {
  582.   unsigned char readbyte;
  583.   unsigned int curPos = 0;
  584.   do
  585.   {
  586.     readbyte = uart_readBlock();
  587.     // putdec(readbyte);
  588.   } while (((readbyte == 0x0a) || (readbyte == 0x0d)));
  589.  
  590.   netbuf[curPos] = readbyte;
  591.   curPos++;
  592.   do
  593.   {
  594.     readbyte = uart_readBlock();
  595.     netbuf[curPos] = readbyte;
  596.     curPos++;
  597.   } while (readbyte != 0x0d);
  598.   netbuf[curPos - 1] = 0;
  599.   uart_readBlock(); // 0xa
  600.   // printf("Answer:[%s]\r\n", netbuf);
  601.   //   getchar();
  602.   return curPos;
  603. }
  604.  
  605. void espReBoot(void)
  606. {
  607.   unsigned char byte, count;
  608.   uart_flush();
  609.   sendcommand("AT+RST");
  610.   printf("Resetting ESP...");
  611.   count = 0;
  612.   do
  613.   {
  614.     byte = uart_readBlock();
  615.     if (byte == gotWiFi[count])
  616.     {
  617.       count++;
  618.     }
  619.     else
  620.     {
  621.       count = 0;
  622.     }
  623.   } while (count < strlen(gotWiFi));
  624.   uart_readBlock(); // CR
  625.   uart_readBlock(); // LF
  626.   puts("Reset complete.");
  627.  
  628.   sendcommand("ATE0");
  629.   do
  630.   {
  631.     byte = uart_readBlock();
  632.   } while (byte != 'K'); // OK
  633.   // puts("Answer:[OK]");
  634.   uart_readBlock(); // CR
  635.   uart_readBlock(); // LN
  636.  
  637.   sendcommand("AT+CIPCLOSE");
  638.   getAnswer2();
  639.   sendcommand("AT+CIPDINFO=0");
  640.   getAnswer2();
  641.   sendcommand("AT+CIPMUX=0");
  642.   getAnswer2();
  643.   sendcommand("AT+CIPSERVER=0");
  644.   getAnswer2();
  645.   sendcommand("AT+CIPRECVMODE=0");
  646.   getAnswer2();
  647. }
  648. unsigned int recvHead(void)
  649. {
  650.   unsigned char byte, dataRead = 0;
  651.   do
  652.   {
  653.     byte = uart_readBlock();
  654.   } while (byte != ',');
  655.  
  656.   dataRead = 0;
  657.   do
  658.   {
  659.     byte = uart_readBlock();
  660.     netbuf[dataRead] = byte;
  661.     dataRead++;
  662.   } while (byte != ':');
  663.   netbuf[dataRead] = 0;
  664.   loaded = atoi(netbuf); // <actual_len>
  665.   // printf("\r\n loaded %u\r\n", loaded);
  666.   return loaded;
  667. }
  668.  
  669. // in netbuf data to send
  670. unsigned int fillPictureEsp(void)
  671. {
  672.   unsigned char sizeLink = 0;
  673.   unsigned long downloaded = 0;
  674.   unsigned char byte, count = 0, try = 0;
  675.   unsigned int dataSize = 0;
  676.   unsigned char skipHeader = 0;
  677.   unsigned char *count1;
  678.  
  679.   strcpy(link, netbuf);
  680.   sizeLink = strlen(link);
  681.   try = 0;
  682.   do
  683.   {
  684.     try++;
  685.     if (try > 1)
  686.     {
  687.       printf("----->Retry:%u\r\n", try);
  688.       delay(1000);
  689.     }
  690.     sendcommand("AT+CIPSTART=\"TCP\",\"zxart.ee\",80");
  691.     getAnswer2(); // CONNECT or ERROR or link is not valid
  692.     count1 = strstr(netbuf, "CONNECT");
  693.   } while (count1 == NULL);
  694.  
  695.   getAnswer2(); // OK
  696.  
  697.   strcpy(cmd, "AT+CIPSEND=");
  698.   sprintf(netbuf, "%u", sizeLink + 2); // second CRLF in send command
  699.  
  700.   strcat(cmd, netbuf);
  701.   sendcommand(cmd);
  702.   getAnswer2();
  703.   do
  704.   {
  705.     byte = uart_readBlock();
  706.     //putchar(byte);
  707.   } while (byte != '>');
  708.   sendcommand(link);
  709.  
  710.   count = 0;
  711.  
  712.   do
  713.   {
  714.     byte = uart_readBlock();
  715.     if (byte == sendOk[count])
  716.     {
  717.       count++;
  718.     }
  719.     else
  720.     {
  721.       count = 0;
  722.     }
  723.   } while (count < strlen(sendOk));
  724.   uart_readBlock(); // CR
  725.   uart_readBlock(); // LF
  726.   skipHeader = 0;
  727.   downloaded = 0;
  728.   do
  729.   {
  730.     headlng = 0;
  731.     dataSize = recvHead();
  732.     getdataEsp(dataSize); // Requested size
  733.     if (skipHeader == 0)
  734.     {
  735.       dataSize = cutHeader(dataSize);
  736.       skipHeader = 1;
  737.     }
  738.     downloaded = downloaded + dataSize;
  739.     memcpy(picture + downloaded - dataSize, netbuf + headlng, dataSize);
  740.   } while (downloaded < contLen);
  741.   sendcommand("AT+CIPCLOSE");
  742.   getAnswer2(); // CLOSED
  743.   getAnswer2(); // OK
  744.   return 0;
  745. }
  746. unsigned char getPicEsp(unsigned long fileId)
  747. {
  748.   netbuf[0] = 0;
  749.   sprintf(buffer, "%lu", fileId);
  750.   strcat(netbuf, "GET /file/id:");
  751.   strcat(netbuf, buffer);
  752.   strcat(netbuf, " HTTP/1.1\r\nHost: zxart.ee\r\nUser-Agent: User-Agent: Mozilla/4.0 (compatible; MSIE5.01; NedoOS)\r\n\r\n\0");
  753.   fillPictureEsp();
  754.   return 0;
  755. }
  756.  
  757. void loadEspConfig(void)
  758. {
  759.   unsigned char curParam[256];
  760.   unsigned char res;
  761.   FILE *espcom;
  762.   OS_SETSYSDRV();
  763.   OS_CHDIR("browser");
  764.   espcom = OS_OPENHANDLE("espcom.ini", 0x80);
  765.   if (((int)espcom) & 0xff)
  766.   {
  767.     printf("mrfesp.ini opening error\r\n");
  768.     return;
  769.   }
  770.  
  771.   OS_READHANDLE(curParam, espcom, 256);
  772.  
  773.   res = sscanf(curParam, "%x %x %x %x %x %x %x %x %u %u %u", &RBR_THR, &IER, &IIR_FCR, &LCR, &MCR, &LSR, &MSR, &SR, &divider, &comType, &espType);
  774.   puts("Config loaded:");
  775.   if (comType == 1)
  776.   {
  777.     puts("     Controller base port: 0x55fe");
  778.   }
  779.   else
  780.   {
  781.     printf("     RBR_THR:0x%4x\r\n     IER    :0x%4x\r\n     IIR_FCR:0x%4x\r\n     LCR    :0x%4x\r\n", RBR_THR, IER, IIR_FCR, LCR);
  782.     printf("     MCR    :0x%4x\r\n     LSR    :0x%4x\r\n     MSR    :0x%4x\r\n     SR     :0x%4x\r\n", MCR, LSR, MSR, SR);
  783.   }
  784.   printf("     DIVIDER:  %4u\r\n     TYPE   :  %4u\r\n     ESP    : %u\r\n", divider, comType, espType);
  785.  
  786.   switch (comType)
  787.   {
  788.   case 0:
  789.     puts("     (16550 like w/o AFC)");
  790.     break;
  791.   case 1:
  792.     puts("     (ATM Turbo 2+)");
  793.     break;
  794.   case 2:
  795.     puts("     (16550 with AFC)");
  796.   default:
  797.     puts("     (Unknown type)");
  798.     break;
  799.   }
  800. }
  801.  
  802. ////////////////////////ESP32 PROCEDURES//////////////////////
  803.  
  804. char *str_replace(char *dst, int num, const char *str,
  805.                   const char *orig, const char *rep)
  806. {
  807.   const char *ptr;
  808.   size_t len1 = strlen(orig);
  809.   size_t len2 = strlen(rep);
  810.   char *tmp = dst;
  811.  
  812.   num -= 1;
  813.   while ((ptr = strstr(str, orig)) != NULL)
  814.   {
  815.     num -= (ptr - str) + len2;
  816.     if (num < 1)
  817.       break;
  818.  
  819.     strncpy(dst, str, (size_t)(ptr - str));
  820.     dst += ptr - str;
  821.     strncpy(dst, rep, len2);
  822.     dst += len2;
  823.     str = ptr + len1;
  824.   }
  825.  
  826.   for (; (*dst = *str) && (num > 0); --num)
  827.   {
  828.     ++dst;
  829.     ++str;
  830.   }
  831.   return tmp;
  832. }
  833.  
  834. void fillPicture(signed char socket)
  835. {
  836.   unsigned int todo, w, pPos, headskip;
  837.   headskip = 0;
  838.   pPos = 0;
  839.   while (42)
  840.   {
  841.     headlng = 0;
  842.     todo = tcpRead(socket);
  843.     if (todo == 0)
  844.     {
  845.       break;
  846.     }
  847.     if (headskip == 0)
  848.     {
  849.       headskip = 1;
  850.       todo = cutHeader(todo);
  851.     }
  852.  
  853.     if (pPos + todo > sizeof(picture))
  854.     {
  855.       printf("dataBuffer overrun... %u reached \n\r", pPos + todo);
  856.       break;
  857.     }
  858.     for (w = 0; w < todo; w++)
  859.     {
  860.       picture[w + pPos] = netbuf[w + headlng];
  861.     }
  862.  
  863.     pPos = pPos + todo;
  864.     if (pPos == contLen)
  865.     {
  866.       break;
  867.     }
  868.   }
  869.   netShutDown(socket, 0);
  870. }
  871. void nameRepair(unsigned char *pfn, unsigned int tfnSize)
  872. {
  873.  
  874.   str_replace(pfn, tfnSize, pfn, "\\", "_");
  875.   str_replace(pfn, tfnSize, pfn, "/", "_");
  876.   str_replace(pfn, tfnSize, pfn, ":", "_");
  877.   str_replace(pfn, tfnSize, pfn, "*", "_");
  878.   str_replace(pfn, tfnSize, pfn, "?", "_");
  879.   str_replace(pfn, tfnSize, pfn, "<", "_");
  880.   str_replace(pfn, tfnSize, pfn, ">", "_");
  881.   str_replace(pfn, tfnSize, pfn, "|", "_");
  882.   str_replace(pfn, tfnSize, pfn, " ", "_");
  883.   str_replace(pfn, tfnSize, pfn, "&#039;", "'");
  884.   str_replace(pfn, tfnSize, pfn, "&amp;", "&");
  885.   str_replace(pfn, tfnSize, pfn, "&quot;", "'");
  886.   str_replace(pfn, tfnSize, pfn, "&gt;", ")");
  887.   str_replace(pfn, tfnSize, pfn, "&lt;", "(");
  888.   str_replace(pfn, tfnSize, pfn, "\"", "'");
  889. }
  890.  
  891. void stringRepair(unsigned char *pfn, unsigned int tSize)
  892. {
  893.   str_replace(pfn, tSize, pfn, "&#039;", "'");
  894.   str_replace(pfn, tSize, pfn, "&amp;", "&");
  895.   str_replace(pfn, tSize, pfn, "&gt;", ">");
  896.   str_replace(pfn, tSize, pfn, "&lt;", "<");
  897.   str_replace(pfn, tSize, pfn, "&quot;", "\"");
  898.   str_replace(pfn, tSize, pfn, "\\/", "/");
  899. }
  900.  
  901. unsigned char getPic(unsigned long fileId)
  902. {
  903.   unsigned int todo;
  904.   signed char socket;
  905.   socket = OpenSock(AF_INET, SOCK_STREAM);
  906.   todo = netConnect(socket);
  907.   sprintf(buffer, "%lu", fileId);
  908.   strcpy(netbuf, "GET /file/id:");
  909.   strcat(netbuf, buffer);
  910.   strcat(netbuf, " HTTP/1.1\r\nHost: zxart.ee\r\nUser-Agent: User-Agent: Mozilla/4.0 (compatible; MSIE5.01; NedoOS)\r\n\r\n\0");
  911.   todo = tcpSend(socket, (unsigned int)&netbuf, strlen(netbuf));
  912.   fillPicture(socket);
  913.   return 0;
  914. }
  915.  
  916. void ncReplace(void)
  917. {
  918.   unsigned char len;
  919.   for (len = 0; len < strlen(curFileStruct.afn); len++)
  920.   {
  921.     if ((curFileStruct.afn[len] < ' ') || (curFileStruct.afn[len] > 0xef) || (curFileStruct.afn[len] > 0x7e && curFileStruct.afn[len] < 0xb0))
  922.     {
  923.       curFileStruct.afn[len] = '_';
  924.     }
  925.   }
  926.  
  927.   for (len = 0; len < strlen(curFileStruct.pfn); len++)
  928.   {
  929.     if ((curFileStruct.pfn[len] < ' ') || (curFileStruct.pfn[len] > 0xef) || (curFileStruct.pfn[len] > 0x7e && curFileStruct.pfn[len] < 0xb0))
  930.     {
  931.       curFileStruct.pfn[len] = '_';
  932.     }
  933.   }
  934. }
  935.  
  936. unsigned char savePic(unsigned long fileId)
  937. {
  938.   FILE *fp2;
  939.   unsigned char afnSize, tfnSize;
  940.  
  941.   afnSize = sizeof(curFileStruct.afn) - 1;
  942.   tfnSize = sizeof(curFileStruct.pfn) - 1;
  943.  
  944.   strcpy(curFileStruct.afn, curFileStruct.authorTitle);
  945.   nameRepair(curFileStruct.afn, afnSize);
  946.  
  947.   strcpy(curFileStruct.pfn, curFileStruct.picName);
  948.   nameRepair(curFileStruct.pfn, tfnSize);
  949.   ncReplace();
  950.  
  951.   sprintf(curFileStruct.fileName, "%s-%s-%ld.scr", curFileStruct.afn, curFileStruct.pfn, fileId);
  952.   if (strlen(curFileStruct.fileName) > 62)
  953.   {
  954.     sprintf(fileIdChar, "-%ld", fileId);
  955.     str_replace(curFileStruct.fileName, sizeof(curFileStruct.fileName) - 1, curFileStruct.fileName, fileIdChar, "");
  956.     curFileStruct.fileName[50] = '\0';
  957.     strcat(curFileStruct.fileName, fileIdChar);
  958.     strcat(curFileStruct.fileName, ".scr");
  959.   }
  960.   OS_SETSYSDRV();
  961.   OS_MKDIR("../downloads");        // Create if not exist
  962.   OS_MKDIR("../downloads/getpic"); // Create if not exist
  963.   OS_CHDIR("../downloads/getpic");
  964.   fp2 = OS_CREATEHANDLE(curFileStruct.fileName, 0x80);
  965.   if (((int)fp2) & 0xff)
  966.   {
  967.     printf("%s creating error\r\n", curFileStruct.fileName);
  968.     getchar();
  969.     exit(0);
  970.   }
  971.   OS_WRITEHANDLE(picture, fp2, 6912);
  972.   OS_CLOSEHANDLE(fp2);
  973.   return 0;
  974. }
  975.  
  976. int pos(unsigned char *s, unsigned char *c, unsigned int n, unsigned int startPos)
  977. {
  978.   unsigned int i, j;
  979.   unsigned int lenC, lenS;
  980.  
  981.   for (lenC = 0; c[lenC]; lenC++)
  982.     ;
  983.   for (lenS = 0; s[lenS]; lenS++)
  984.     ;
  985.  
  986.   for (i = startPos; i <= lenS - lenC; i++)
  987.   {
  988.     for (j = 0; s[i + j] == c[j]; j++)
  989.       ;
  990.  
  991.     if (j - lenC == 1 && i == lenS - lenC && !(n - 1))
  992.       return i;
  993.     if (j == lenC)
  994.       if (n - 1)
  995.         n--;
  996.       else
  997.         return i;
  998.   }
  999.   return -1;
  1000. }
  1001.  
  1002. const char *parseJson(unsigned char *property)
  1003. {
  1004.   unsigned int w, lng, lngp1, findEnd, listPos;
  1005.   unsigned char terminator;
  1006.   int n;
  1007.   n = -1;
  1008.   // netbuf[0] = '\0';
  1009.   n = pos(picture, property, 1, 0);
  1010.   if (n == -1)
  1011.   {
  1012.     strcpy(netbuf, "-");
  1013.     // printf("Property %s not found", property);
  1014.     return netbuf;
  1015.   }
  1016.   lng = n - 1 + strlen(property);
  1017.   if (picture[lng] == ':')
  1018.   {
  1019.     terminator = '\0';
  1020.   }
  1021.   if (picture[lng] == '\"')
  1022.   {
  1023.     terminator = '\"';
  1024.   }
  1025.   if (picture[lng] == '[')
  1026.   {
  1027.     terminator = ']';
  1028.   }
  1029.  
  1030.   findEnd = 1;
  1031.   lngp1 = lng + 1;
  1032.  
  1033.   while (42)
  1034.   {
  1035.  
  1036.     if ((picture[lngp1 + findEnd] == ','))
  1037.     {
  1038.       if (terminator == '\0')
  1039.       {
  1040.         break;
  1041.       }
  1042.       if ((picture[lng + findEnd] == terminator))
  1043.       {
  1044.         findEnd--;
  1045.         break;
  1046.       }
  1047.     }
  1048.     findEnd++;
  1049.   }
  1050.   listPos = 0;
  1051.   for (w = lngp1; w < findEnd + lngp1; w++)
  1052.   {
  1053.     netbuf[listPos] = picture[w];
  1054.     listPos++;
  1055.   }
  1056.   netbuf[listPos] = '\0';
  1057.   return netbuf;
  1058. }
  1059. void convert866(void)
  1060. {
  1061.   unsigned int lng, targetPos, w, q = 0;
  1062.   unsigned char buffer[8], one, two;
  1063.   unsigned int decVal;
  1064.   lng = strlen(netbuf);
  1065.   targetPos = lng + 1;
  1066.  
  1067.   while (q < lng)
  1068.   {
  1069.     one = netbuf[q];
  1070.     two = netbuf[q + 1];
  1071.     if (one == 92 && two == 117)
  1072.     {
  1073.       q = q + 2;
  1074.       for (w = 0; w < 4; w++)
  1075.       {
  1076.         buffer[w] = netbuf[q + w];
  1077.       }
  1078.       q = q + 4;
  1079.       buffer[4] = '\0';
  1080.       decVal = (unsigned int)strtol(buffer, NULL, 16);
  1081.  
  1082.       if (decVal < 1088)
  1083.       {
  1084.         decVal = decVal - 912;
  1085.       }
  1086.       if (decVal > 1087)
  1087.       {
  1088.         decVal = decVal - 864;
  1089.       }
  1090.       if (decVal == 1025)
  1091.       {
  1092.         decVal = 240;
  1093.       }
  1094.       if (decVal == 1105)
  1095.       {
  1096.         decVal = 241;
  1097.       }
  1098.  
  1099.       netbuf[targetPos] = decVal;
  1100.     }
  1101.     else
  1102.     {
  1103.       netbuf[targetPos] = netbuf[q];
  1104.       q++;
  1105.     }
  1106.     targetPos++;
  1107.   }
  1108.   netbuf[targetPos] = 0;
  1109.  
  1110.   for (w = lng + 1; w < targetPos + 1; w++)
  1111.   {
  1112.     netbuf[w - lng - 1] = netbuf[w];
  1113.   }
  1114. }
  1115.  
  1116. long processJson(unsigned long startPos, unsigned char limit, unsigned char queryNum)
  1117. {
  1118.   unsigned int retry, tSize;
  1119.   unsigned int todo;
  1120.   unsigned char *count1, socket;
  1121.   switch (queryNum)
  1122.   {
  1123.   case 0:
  1124.     strcpy(netbuf, "GET /api/export:zxPicture/filter:zxPictureType=standard/limit:");
  1125.     sprintf(buffer, "%u", limit);
  1126.     strcat(netbuf, buffer);
  1127.     strcat(netbuf, "/start:");
  1128.     sprintf(buffer, "%lu", startPos);
  1129.     strcat(netbuf, buffer);
  1130.     strcat(netbuf, "/order:date,desc");
  1131.     strcat(netbuf, userAgent);
  1132.     break;
  1133.   case 1:
  1134.     strcpy(netbuf, "GET /api/types:zxPicture/export:zxPicture/language:eng/start:0/limit:1/order:rand/filter:zxPictureMinRating=4;zxPictureType=standard");
  1135.     strcat(netbuf, userAgent);
  1136.     break;
  1137.  
  1138.   case 3: // /api/export:author/filter:authorId=2202
  1139.     strcpy(netbuf, "GET /api/export:author/filter:authorId=");
  1140.     sprintf(buffer, "%lu", startPos);
  1141.     strcat(netbuf, buffer);
  1142.     strcat(netbuf, userAgent);
  1143.     break;
  1144.  
  1145.   case 99: // GET /jsonElementData/elementId:182798
  1146.     strcpy(netbuf, "GET /jsonElementData/elementId:");
  1147.     sprintf(buffer, "%lu", startPos);
  1148.     strcat(netbuf, buffer);
  1149.     strcat(netbuf, userAgent);
  1150.     break;
  1151.   }
  1152.   retry = 10;
  1153.   while (42)
  1154.   {
  1155.     if (netDriver == 0)
  1156.     {
  1157.       socket = OpenSock(AF_INET, SOCK_STREAM);
  1158.       netConnect(socket);
  1159.       todo = tcpSend(socket, (unsigned int)&netbuf, strlen(netbuf));
  1160.       fillPicture(socket);
  1161.     }
  1162.     else
  1163.     {
  1164.       fillPictureEsp();
  1165.     }
  1166.     count1 = strstr(picture, "responseStatus\":\"success");
  1167.     if (count1 == NULL)
  1168.     {
  1169.       retry--;
  1170.       ATRIB(91);
  1171.       printf("PROCESS JSON: [ERROR: Bad responseStatus.] [Query:%u][Retry:%u] [Pic:%lu]\r\n", queryNum, retry, startPos);
  1172.       YIELD();
  1173.       puts(netbuf);
  1174.       getchar();
  1175.       if (retry < 1)
  1176.       {
  1177.         return -1;
  1178.       }
  1179.     }
  1180.     else
  1181.     {
  1182.       break;
  1183.     }
  1184.   }
  1185.  
  1186.   count1 = strstr(picture, "\"id\":");
  1187.   if (count1 == NULL)
  1188.   {
  1189.     ATRIB(91);
  1190.     printf("PROCESS JSON: [ERROR: ID not found.] [Query:%u][Pic:%lu]\r\n", queryNum, startPos);
  1191.     YIELD();
  1192.     return -2;
  1193.   }
  1194.  
  1195.   netbuf[0] = 0;
  1196.   if (queryNum < 3)
  1197.   {
  1198.     parseJson("\"id\":");
  1199.     curFileStruct.picId = atol(netbuf);
  1200.     parseJson(",\"title\":\"");
  1201.     convert866();
  1202.     strcpy(curFileStruct.picName, netbuf);
  1203.  
  1204.     tSize = sizeof(curFileStruct.picName);
  1205.     stringRepair(curFileStruct.picName, tSize);
  1206.  
  1207.     parseJson(",\"type\":\"");
  1208.     strcpy(curFileStruct.picType, netbuf);
  1209.     parseJson("\"rating\":\"");
  1210.     strcpy(curFileStruct.picRating, netbuf);
  1211.     parseJson("\"year\":\"");
  1212.     curFileStruct.picYear = atoi(netbuf);
  1213.     parseJson("\"totalAmount\":");
  1214.     curFileStruct.totalAmount = atol(netbuf);
  1215.     parseJson("\"authorIds\":[");
  1216.     strcpy(curFileStruct.authorIds, netbuf);
  1217.   }
  1218.   if (queryNum == 99)
  1219.   {
  1220.     parseJson(",\"title\":\"");
  1221.     convert866();
  1222.     strcpy(curFileStruct.authorTitle, netbuf);
  1223.     parseJson(",\"realName\":\"");
  1224.     convert866();
  1225.     strcpy(curFileStruct.authorRealName, netbuf);
  1226.   }
  1227.   return curFileStruct.picId;
  1228. }
  1229.  
  1230. void printData(void)
  1231. {
  1232.   ATRIB(93);
  1233.   printf(" #: ");
  1234.   ATRIB(97);
  1235.   printf("%lu", count);
  1236.   ATRIB(93);
  1237.   printf(" ID: ");
  1238.   ATRIB(97);
  1239.   printf("%lu ", curFileStruct.picId);
  1240.   ATRIB(93);
  1241.   printf(" Total Pics: ");
  1242.   ATRIB(97);
  1243.   printf("%lu\r\n", curFileStruct.totalAmount);
  1244.   ATRIB(93);
  1245.   printf(" Author: ");
  1246.   ATRIB(96);
  1247.   printf("%s\r\n", curFileStruct.authorTitle);
  1248.   ATRIB(93);
  1249.   printf(" TITLE: ");
  1250.   ATRIB(95);
  1251.   printf("%s\r\n", curFileStruct.picName);
  1252.   ATRIB(93);
  1253.   printf(" RATING: ");
  1254.   ATRIB(97);
  1255.   printf("%s", curFileStruct.picRating);
  1256.   ATRIB(93);
  1257.   printf(" YEAR: ");
  1258.   ATRIB(97);
  1259.   printf("%u\r\n", curFileStruct.picYear);
  1260.   ATRIB(93);
  1261.   printf(" AuthorsIDs ");
  1262.   ATRIB(97);
  1263.   printf("%s", curFileStruct.authorIds);
  1264.   ATRIB(93);
  1265.   printf(" Real name: ");
  1266.   ATRIB(97);
  1267.   printf("%s\r\n", curFileStruct.authorRealName);
  1268.   ATRIB(96);
  1269.   printf("\r\n");
  1270.   // YIELD();
  1271. }
  1272. void safeKeys(unsigned char keypress)
  1273. {
  1274.   if (keypress == 27)
  1275.   {
  1276.     printf("Good bye...\r\n");
  1277.     ATRIB(37);
  1278.     ATRIB(40);
  1279.     exit(0);
  1280.   }
  1281.  
  1282.   if (keypress == 'j' || keypress == 'J')
  1283.   {
  1284.     printf("Jump to picture:");
  1285.     scanf("%lu", &count);
  1286.     if (count > curFileStruct.totalAmount - 1)
  1287.     {
  1288.       count = curFileStruct.totalAmount - 1;
  1289.     }
  1290.   }
  1291.  
  1292.   if (keypress == 'v' || keypress == 'V')
  1293.   {
  1294.     verbose = !verbose;
  1295.  
  1296.     if (verbose == 0)
  1297.     {
  1298.       BOX(1, 1, 80, 25, 40);
  1299.       AT(1, 1);
  1300.     }
  1301.   }
  1302.  
  1303.   if (keypress == 'h' || keypress == 'H')
  1304.   {
  1305.     printHelp();
  1306.   }
  1307.  
  1308.   if (keypress == 'r' || keypress == 'R')
  1309.   {
  1310.     randomPic = !randomPic;
  1311.  
  1312.     if (verbose == 1)
  1313.     {
  1314.       if (randomPic == 1)
  1315.       {
  1316.         printf("    Random mode enabled...\r\n");
  1317.       }
  1318.       else
  1319.       {
  1320.         printf("    Sequental mode enabled...\r\n");
  1321.       }
  1322.     }
  1323.   }
  1324.   if (keypress == 'a' || keypress == 'A')
  1325.   {
  1326.     slideShow = !slideShow;
  1327.     if (slideShow == 1)
  1328.     {
  1329.       if (verbose == 1)
  1330.         printf("    SlideShow mode enabled...\r\n\r\n");
  1331.       slideShowTime = 250;
  1332.     }
  1333.     else
  1334.     {
  1335.       if (verbose == 1)
  1336.         printf("    Manual mode enabled...\r\n\r\n");
  1337.       slideShowTime = 0;
  1338.     }
  1339.   }
  1340.  
  1341.   if (keypress == 'd' || keypress == 'D')
  1342.   {
  1343.     netDriver = !netDriver;
  1344.     if (netDriver == 1)
  1345.     {
  1346.       printf("    ESP-AT mode enabled...\r\n");
  1347.       loadEspConfig();
  1348.       uart_init(divider);
  1349.       espReBoot();
  1350.       printf("    ESP-AT inited...\r\n");
  1351.     }
  1352.  
  1353.     else
  1354.     {
  1355.       if (verbose == 1)
  1356.         printf("    ZXNETUSB mode enabled...\r\n\r\n");
  1357.     }
  1358.   }
  1359. }
  1360.  
  1361. C_task main(void)
  1362. {
  1363.   unsigned char errno;
  1364.   unsigned long ipadress;
  1365.   long iddqd, idkfa;
  1366.  
  1367.   os_initstdio();
  1368.  
  1369.   count = 0;
  1370.   verbose = 1;
  1371.   randomPic = 0;
  1372.   slideShow = 0;
  1373.   netDriver = 0;
  1374.  
  1375.   BOX(1, 1, 80, 25, 40);
  1376.   AT(1, 1);
  1377.   printHelp();
  1378.   safeKeys(keypress);
  1379.  
  1380. start:
  1381.   keypress = 0;
  1382.   switch (randomPic)
  1383.   {
  1384.   case 0:
  1385.  
  1386.     iddqd = processJson(count, 1, 0);
  1387.     break;
  1388.   case 1:
  1389.     iddqd = processJson(0, 1, 1);
  1390.     break;
  1391.   }
  1392.  
  1393.   if (iddqd < 0)
  1394.   {
  1395.     count++;
  1396.     goto start;
  1397.   }
  1398.  
  1399.   if (verbose == 1)
  1400.   {
  1401.     idkfa = processJson(atol(curFileStruct.authorIds), 0, 99);
  1402.     if (idkfa < 0)
  1403.     {
  1404.       printf(" Cant parse curFileStruct.authorIds = %s \r\n\r\n", curFileStruct.authorIds);
  1405.       count++;
  1406.       goto start;
  1407.     }
  1408.  
  1409.     printData();
  1410.   }
  1411.   else
  1412.   {
  1413.     // ATRIB(97);
  1414.     // printf(" Getting picture...\r\n");
  1415.   }
  1416.  
  1417.   if (strcmp(curFileStruct.picType, "standard") != 0)
  1418.   {
  1419.     printf("  >>Format '%s' not supported, skipped \n\r", curFileStruct.picType);
  1420.     count++;
  1421.     goto start;
  1422.   }
  1423.  
  1424.   if (netDriver == 0)
  1425.   {
  1426.     errno = getPic(iddqd);
  1427.   }
  1428.   else
  1429.   {
  1430.     errno = getPicEsp(iddqd);
  1431.   }
  1432.  
  1433. review:
  1434.   keypress = viewScreen6912((unsigned int)&picture, slideShowTime);
  1435.   emptyKeys();
  1436.  
  1437.   ///// Keys only for pictures
  1438.   if (keypress == 's' || keypress == 'S')
  1439.   {
  1440.     savePic(iddqd);
  1441.     if (verbose == 1)
  1442.       printf("        ID:%lu    TITLE:%s  SAVED\r\n\r\n", curFileStruct.picId, curFileStruct.picName);
  1443.     count++;
  1444.   }
  1445.  
  1446.   if (keypress == 248 || keypress == 'b' || keypress == 'B')
  1447.   {
  1448.     if (count > 0)
  1449.     {
  1450.       count--;
  1451.     }
  1452.   }
  1453.   if (keypress == 251 || keypress == 32)
  1454.   {
  1455.     count++;
  1456.     goto start;
  1457.   }
  1458.   if (keypress == 'i' || keypress == 'I')
  1459.   {
  1460.     delay(100);
  1461.     getchar();
  1462.     goto review;
  1463.   }
  1464.   safeKeys(keypress);
  1465.   goto start;
  1466. }
  1467.