Rev 2038 |
Blame |
Compare with Previous |
Last modification |
View Log
| Download
| RSS feed
#include <math.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <oscalls.h>
#include <osfs.h>
#include <intrz80.h>
#include <ctype.h>
#include <tcp.h>
#include <graphic.h>
#include <terminal.c>
#define COMMANDLINE 0x0080
unsigned int RBR_THR
= 0xF8EF;
unsigned int IER
= 0xF9EF;
unsigned int IIR_FCR
= 0xFAEF;
unsigned int LCR
= 0xFBEF;
unsigned int MCR
= 0xFCEF;
unsigned int LSR
= 0xFDEF;
unsigned int MSR
= 0xFEEF;
unsigned int SR
= 0xFFEF;
unsigned int divider
= 1;
unsigned char comType
= 0;
unsigned char ver
[] = "2.1";
unsigned char queryType
[64];
unsigned char netbuf
[3048];
unsigned char dataBuffer
[6132];
unsigned char crlf
[2] = {13, 10};
unsigned char formats
[4][4] = {"pt3", "pt2", "tfc", "ts"};
unsigned char status
, key
, curFormat
;
struct sockaddr_in targetadr
;
struct readstructure readStruct
;
unsigned long contLen
;
long count
;
unsigned char saveFlag
, saveBak
, logFlag
, rptFlag
, netDriver
;
union APP_PAGES main_pg
;
union APP_PAGES player_pg
;
unsigned int loaded
;
unsigned int headlng
;
unsigned char cmd
[256];
unsigned char link
[512];
struct fileStruct
{
long picId
;
unsigned long fileSize
;
unsigned int picYear
;
unsigned long totalAmount
;
unsigned int curPos
;
unsigned int startBar
;
unsigned int trackInSeconds
;
unsigned char time[16];
unsigned char picRating
[8];
unsigned char trackName
[256];
unsigned char fileName
[256];
unsigned char authorIds
[64];
unsigned char authorTitle
[64];
unsigned char authorRealName
[64];
unsigned char afn
[64];
unsigned char tfn
[64];
unsigned char fileName2
[256];
} curFileStruct
;
void delay
(unsigned long counter
)
{
unsigned long start
, finish
;
counter
= counter
/ 20;
if (counter
< 1)
{
counter
= 1;
}
start
= time();
finish
= start
+ counter
;
while (start
< finish
)
{
start
= time();
}
}
void clearStatus
(void)
{
AT
(1, 25);
printf(" \r");
}
void printProgress
(unsigned char type
)
{
unsigned char bar
, minutes
, seconds
;
unsigned char *position
;
long barLenght
;
int timer
;
switch (type
)
{
case 0: // print empty bar
AT
(6, 11);
ATRIB
(93);
printf("%02u:%02u", 0, 0);
AT
(15, 11);
ATRIB
(97);
for (bar
= 0; bar
< 50; bar
++)
{
putchar(176);
}
putchar(' ');
putchar(' ');
minutes
= atoi(curFileStruct.
time);
position
= (strstr(curFileStruct.
time, ":")) + 1;
seconds
= atoi(position
);
curFileStruct.
trackInSeconds = minutes
* 60 + seconds
;
curFileStruct.
curPos = 0;
curFileStruct.
startBar = 0;
break;
case 1: // print progress bar
AT
(6, 11);
ATRIB
(93);
timer
= floor(curFileStruct.
curPos / 60);
printf("%02u:%02u", timer
, (curFileStruct.
curPos - (timer
* 60)));
barLenght
= (curFileStruct.
curPos * 50 / curFileStruct.
trackInSeconds);
if (barLenght
> 49)
{
barLenght
= 50;
}
AT
(15 + curFileStruct.
startBar, 11);
ATRIB
(97);
for (bar
= 0; bar
< barLenght
- curFileStruct.
startBar; bar
++)
{
putchar(178);
}
AT
(1, 1);
curFileStruct.
startBar = bar
;
break;
case 2: // print full bar
AT
(15, 11);
ATRIB
(97);
for (bar
= 0; bar
< 50; bar
++)
{
putchar(178);
}
break;
}
}
void errorPrint
(unsigned int error
)
{
switch (error
)
{
case 2:
printf("02 SHUT_RDWR");
break;
case 4:
printf("04 ERR_INTR");
break;
case 23:
printf("23 ERR_NFILE");
break;
case 35:
printf("35 ERR_EAGAIN");
break;
case 37:
printf("37 ERR_ALREADY");
break;
case 38:
printf("38 ERR_NOTSOCK");
break;
case 40:
printf("40 ERR_EMSGSIZE");
break;
case 41:
printf("41 ERR_PROTOTYPE");
break;
case 47:
printf("47 ERR_AFNOSUPPORT");
break;
case 53:
printf("53 ERR_ECONNABORTED");
break;
case 54:
printf("54 ERR_CONNRESET");
break;
case 57:
printf("57 ERR_NOTCONN");
break;
case 65:
printf("65 ERR_HOSTUNREACH");
break;
default:
printf("%u UNKNOWN ERROR", error
);
break;
}
YIELD
();
}
void printHelp
(void)
{
AT
(1, 15);
ATRIB
(97);
printf(" [<-] Previous track [->] Next track\r\n");
printf(" [S] Stop player [R] Repeat track mode\r\n");
printf(" [K] Toggle saving tracks [D] Download track\r\n");
printf(" [Q] Select Query type [F] Select tracks format\r\n");
printf(" [I] Interface ZXNETUSB/ESP32 [J] Jump to NNNN file\r\n");
printf(" [L] Toggle operation logging [ESC] Exit to OS\r\n");
printf(" \r\n");
}
unsigned char OpenSock
(unsigned char family
, unsigned char protocol
)
{
unsigned char socket
;
unsigned int todo
;
todo
= OS_NETSOCKET
((family
<< 8) + protocol
);
if (todo
> 32767)
{
clearStatus
();
printf("OS_NETSOCKET: ");
errorPrint
(todo
& 255);
exit(0);
}
else
{
socket
= ((todo
& 65280) >> 8);
if (logFlag
)
{
clearStatus
();
printf("OS_NETSOCKET: Socket #%d created.", socket
);
}
}
return socket
;
}
unsigned int netShutDown
(unsigned char socket
, unsigned char type
)
{
unsigned int todo
;
todo
= OS_NETSHUTDOWN
(socket
, type
);
if (todo
> 32767)
{
clearStatus
();
printf("OS_NETSHUTDOWN: ");
errorPrint
(todo
& 255);
return 255;
}
else
{
if (logFlag
)
{
clearStatus
();
printf("OS_NETSHUTDOWN: Socket #%u closed.", socket
);
}
}
return 0;
}
unsigned char netConnect
(unsigned char socket
)
{
unsigned int todo
, retry
= 10;
targetadr.
family = AF_INET
;
targetadr.
porth = 00;
targetadr.
portl = 80;
targetadr.
b1 = 217;
targetadr.
b2 = 146;
targetadr.
b3 = 69;
targetadr.
b4 = 13;
while (retry
> 0)
{
todo
= OS_NETCONNECT
(socket
, &targetadr
);
if (todo
> 32767)
{
retry
--;
clearStatus
();
printf("OS_NETCONNECT [ERROR:");
errorPrint
(todo
& 255);
printf("] [Retry:%u]", retry
);
YIELD
();
netShutDown
(socket
, 0);
socket
= OpenSock
(AF_INET
, SOCK_STREAM
);
}
else
{
if (logFlag
)
{
clearStatus
();
printf("OS_NETCONNECT: connected , %u", (todo
& 255));
}
return 1;
}
}
getchar();
exit(0);
return 0;
}
unsigned int tcpRead
(unsigned char socket
)
{
unsigned char retry
= 20;
unsigned int err
, todo
;
readStruct.
socket = socket
;
readStruct.
BufAdr = (unsigned int)&netbuf
;
readStruct.
bufsize = sizeof(netbuf
);
readStruct.
protocol = SOCK_STREAM
;
wizread
:
todo
= OS_WIZNETREAD
(&readStruct
);
if (todo
> 32767)
{
if (retry
== 0)
{
err
= todo
& 255;
clearStatus
();
printf("OS_WIZNETREAD: ");
errorPrint
(err
);
if (err
== ERR_EAGAIN
)
{
return 0;
}
exit(0);
}
retry
--;
if (logFlag
)
{
AT
(54, 25);
printf("OS_WIZNETREAD: retry %u ", retry
);
}
delay
(200);
goto wizread
;
}
if (logFlag
)
{
clearStatus
();
printf("OS_WIZNETREAD: %u bytes read.", todo
);
}
return todo
;
}
int pos
(unsigned char *s
, unsigned char *c
, unsigned int n
, unsigned int startPos
)
{
unsigned int i
, j
;
unsigned int lenC
, lenS
;
for (lenC
= 0; c
[lenC
]; lenC
++)
;
for (lenS
= 0; s
[lenS
]; lenS
++)
;
for (i
= startPos
; i
<= lenS
- lenC
; i
++)
{
for (j
= 0; s
[i
+ j
] == c
[j
]; j
++)
;
if (j
- lenC
== 1 && i
== lenS
- lenC
&& !(n
- 1))
return i
;
if (j
== lenC
)
if (n
- 1)
n
--;
else
return i
;
}
return -1;
}
unsigned int cutHeader
(unsigned int todo
)
{
unsigned int q
, headlng
;
unsigned char *count
;
count
= strstr(netbuf
, "Content-Length:");
if (count
== NULL
)
{
clearStatus
();
printf("Content-Length: not found.");
contLen
= 0;
}
else
{
contLen
= atol(count
+ 15);
curFileStruct.
fileSize = contLen
;
// printf("=> Dlinna soderzhimogo = %lu \n\r", curFileStruct.fileSize);
}
count
= strstr(netbuf
, "\r\n\r\n");
headlng
= ((unsigned int)count
- (unsigned int)netbuf
+ 4);
q
= todo
- headlng
;
memcpy(&netbuf
, count
+ 4, q
);
return q
;
}
////////////////////////ESP32 PROCEDURES//////////////////////
void uart_write
(unsigned char data
)
{
while ((input
(LSR
) & 64) == 0)
{
}
output
(RBR_THR
, data
);
}
void uart_setrts
(unsigned char mode
)
{
switch (mode
)
{
case 1:
output
(MCR
, 2);
break;
case 0:
output
(MCR
, 0);
break;
default:
disable_interrupt
();
output
(MCR
, 2);
output
(MCR
, 0);
enable_interrupt
();
}
}
void uart_init
(unsigned char divisor
)
{
clearStatus
();
printf("Initing UART [divider:%u]", divisor
);
output
(MCR
, 0x00); // Disable input
output
(IIR_FCR
, 0x87); // Enable fifo 8 level, and clear it
output
(LCR
, 0x83); // 8n1, DLAB=1
output
(RBR_THR
, divisor
); // 115200 (divider 1-115200, 3 - 38400)
output
(IER
, 0x00); // (divider 0). Divider is 16 bit, so we get (#0002 divider)
output
(LCR
, 0x03); // 8n1, DLAB=0
output
(IER
, 0x00); // Disable int
output
(MCR
, 0x2f); // Enable AFE
uart_setrts
(0);
}
unsigned char uart_hasByte
(void)
{
return (1 & input
(LSR
));
}
unsigned char uart_read
(void)
{
uart_setrts
(2);
return input
(RBR_THR
);
}
unsigned char uart_readBlock
(void)
{
while (uart_hasByte
() == 0)
{
uart_setrts
(2);
}
return input
(RBR_THR
);
}
void uart_flush
(void)
{
unsigned int count
;
for (count
= 0; count
< 6000; count
++)
{
uart_setrts
(1);
uart_read
();
}
clearStatus
();
printf("Buffer cleared.");
}
void getdataEsp
(unsigned int counted
)
{
unsigned int counter
;
for (counter
= 0; counter
< counted
; counter
++)
{
netbuf
[counter
] = uart_readBlock
();
}
netbuf
[counter
] = 0;
}
void sendcommand
(char *commandline
)
{
unsigned int count
, cmdLen
;
cmdLen
= strlen(commandline
);
for (count
= 0; count
< cmdLen
; count
++)
{
uart_write
(commandline
[count
]);
}
uart_write
('\r');
uart_write
('\n');
// printf("Sended:[%s] \r\n", commandline);
}
unsigned char getAnswer
(unsigned char skip
)
{
unsigned char readbyte
;
unsigned int curPos
= 0;
while (skip
!= 0)
{
uart_readBlock
();
skip
--;
}
while (42)
{
readbyte
= uart_readBlock
();
if (readbyte
== 0x0a)
{
break;
}
netbuf
[curPos
] = readbyte
;
curPos
++;
}
netbuf
[curPos
- 1] = 0;
// printf("Answer:[%s]\r\n", netbuf);
return curPos
;
}
void espReBoot
(void)
{
unsigned char byte
;
uart_flush
();
sendcommand
("AT+RST");
clearStatus
();
printf("Resetting ESP...");
do
{
byte
= uart_read
();
} while (byte
!= 'P'); // WIFI GOT IP
uart_readBlock
(); // CR
uart_readBlock
(); // LN
clearStatus
();
printf("Reset complete.");
sendcommand
("ATE0");
do
{
byte
= uart_read
();
} while (byte
!= 'K'); // OK
// puts("Answer:[OK]");
uart_readBlock
(); // CR
uart_readBlock
(); // LN
sendcommand
("AT+CIPCLOSE");
getAnswer
(2);
sendcommand
("AT+CIPDINFO=0");
getAnswer
(2);
sendcommand
("AT+CIPMUX=0");
getAnswer
(2);
sendcommand
("AT+CIPSERVER=0");
getAnswer
(2);
sendcommand
("AT+CIPRECVMODE=1");
getAnswer
(2);
}
unsigned int recvHead
(void)
{
unsigned char byte
, dataRead
= 0;
do
{
byte
= uart_readBlock
();
netbuf
[dataRead
] = byte
;
dataRead
++;
} while (byte
!= ',');
netbuf
[dataRead
] = 0;
loaded
= atoi(netbuf
+ 13); // <actual_len>
return loaded
;
}
// in netbuf data to send
unsigned int fillDataBufferEsp
(void)
{
unsigned int packSize
= 2000;
unsigned char link
[512];
unsigned char sizeLink
;
unsigned long toDownload
, downloaded
;
unsigned char byte
;
unsigned int dataSize
;
unsigned char skipHeader
;
strcpy(link
, netbuf
);
strcat(link
, "\r\n");
sizeLink
= strlen(link
);
sendcommand
("AT+CIPSTART=\"TCP\",\"zxart.ee\",80");
getAnswer
(2); // CONNECT
getAnswer
(0); // OK
strcpy(cmd
, "AT+CIPSEND=");
sprintf(netbuf
, "%u", sizeLink
+ 2); // second CRLF in send command
strcat(cmd
, netbuf
);
sendcommand
(cmd
);
byte
= 0;
while (byte
!= '>')
{
byte
= uart_readBlock
();
// putchar(byte);
}
sendcommand
(link
);
getAnswer
(2); // Recv 132 bytes
getAnswer
(2); // SEND OK
getAnswer
(2); //+IPD,3872
skipHeader
= 0;
downloaded
= 0;
do
{
headlng
= 0;
strcpy(netbuf
, "AT+CIPRECVDATA=");
sprintf(link
, "%u", packSize
);
strcat(netbuf
, link
);
sendcommand
(netbuf
);
dataSize
= recvHead
();
getdataEsp
(dataSize
); // Requested size
if (skipHeader
== 0)
{
dataSize
= cutHeader
(dataSize
);
toDownload
= contLen
;
skipHeader
= 1;
}
downloaded
= downloaded
+ dataSize
;
memcpy(dataBuffer
+ downloaded
- dataSize
, netbuf
+ headlng
, dataSize
);
toDownload
= toDownload
- dataSize
;
getAnswer
(2); // OK
if (toDownload
> 0)
{
getAnswer
(2); // +IPD,1824
}
} while (toDownload
> 0);
sendcommand
("AT+CIPCLOSE");
getAnswer
(0); // CLOSED
return 0;
}
void loadEspConfig
(void)
{
unsigned char curParam
[256];
unsigned char res
;
FILE
*espcom
;
OS_SETSYSDRV
();
OS_CHDIR
("browser");
espcom
= OS_OPENHANDLE
("espcom.ini", 0x80);
if (((int)espcom
) & 0xff)
{
clearStatus
();
printf("mrfesp.ini opening error");
return;
}
OS_READHANDLE
(curParam
, espcom
, 256);
res
= sscanf(curParam
, "%x %x %x %x %x %x %x %x %u", &RBR_THR
, &IER
, &IIR_FCR
, &LCR
, &MCR
, &LSR
, &MSR
, &SR
, ÷r
, &comType
);
BOX
(1, 15, 80, 8, 40);
AT
(1, 15);
puts("Config loaded:");
printf(" RBR_THR:0x%4x IER :0x%4x\r\n IIR_FCR:0x%4x LCR :0x%4x\r\n", RBR_THR
, IER
, IIR_FCR
, LCR
);
printf(" MCR :0x%4x LSR :0x%4x\r\n MSR :0x%4x SR :0x%4x\r\n", MCR
, LSR
, MSR
, SR
);
printf(" DIV :%4u TYPE :%4u", divider
, comType
);
}
////////////////////////ESP32 PROCEDURES//////////////////////
char *str_replace
(char *dst
, int num
, const char *str
,
const char *orig
, const char *rep
)
{
const char *ptr
;
size_t len1
= strlen(orig
);
size_t len2
= strlen(rep
);
char *tmp
= dst
;
num
-= 1;
while ((ptr
= strstr(str
, orig
)) != NULL
)
{
num
-= (ptr
- str
) + len2
;
if (num
< 1)
break;
strncpy(dst
, str
, (size_t)(ptr
- str
));
dst
+= ptr
- str
;
strncpy(dst
, rep
, len2
);
dst
+= len2
;
str
= ptr
+ len1
;
}
for (; (*dst
= *str
) && (num
> 0); --num
)
{
++dst
;
++str
;
}
return tmp
;
}
const char *parseJson
(unsigned char *property
)
{
unsigned int w
, lng
, lngp1
, findEnd
, listPos
;
unsigned char terminator
;
int n
;
n
= -1;
netbuf
[0] = '\0';
n
= pos
(dataBuffer
, property
, 1, 0);
if (n
== -1)
{
strcpy(netbuf
, "0\0");
return netbuf
;
}
lng
= n
- 1 + strlen(property
);
if (dataBuffer
[lng
] == ':')
{
terminator
= '\0';
}
if (dataBuffer
[lng
] == '\"')
{
terminator
= '\"';
}
if (dataBuffer
[lng
] == '[')
{
terminator
= ']';
}
findEnd
= 1;
lngp1
= lng
+ 1;
while (42)
{
if ((dataBuffer
[lngp1
+ findEnd
] == ','))
{
if (terminator
== '\0')
{
break;
}
if ((dataBuffer
[lng
+ findEnd
] == terminator
))
{
findEnd
--;
break;
}
}
findEnd
++;
}
listPos
= 0;
for (w
= lngp1
; w
< findEnd
+ lngp1
; w
++)
{
netbuf
[listPos
] = dataBuffer
[w
];
listPos
++;
}
netbuf
[listPos
] = '\0';
return netbuf
;
}
void convert866
(void)
{
unsigned int lng
, targetPos
, w
, q
= 0;
unsigned char buffer
[8], one
, two
;
unsigned int decVal
;
lng
= strlen(netbuf
);
targetPos
= lng
+ 1;
while (q
< lng
)
{
one
= netbuf
[q
];
two
= netbuf
[q
+ 1];
if (one
== 92 && two
== 117)
{
q
= q
+ 2;
for (w
= 0; w
< 4; w
++)
{
buffer
[w
] = netbuf
[q
+ w
];
}
q
= q
+ 4;
buffer
[4] = '\0';
decVal
= (unsigned int)strtol(buffer
, NULL
, 16);
if (decVal
< 1088)
{
decVal
= decVal
- 912;
}
if (decVal
> 1087)
{
decVal
= decVal
- 864;
}
if (decVal
== 1025)
{
decVal
= 240;
}
if (decVal
== 1105)
{
decVal
= 241;
}
netbuf
[targetPos
] = decVal
;
}
else
{
netbuf
[targetPos
] = netbuf
[q
];
q
++;
}
targetPos
++;
}
netbuf
[targetPos
] = '\0';
for (w
= lng
+ 1; w
< targetPos
+ 1; w
++)
{
netbuf
[w
- lng
- 1] = netbuf
[w
];
}
}
void nameRepair
(unsigned char *pfn
, unsigned int tfnSize
)
{
str_replace
(pfn
, tfnSize
, pfn
, "\\", "_");
str_replace
(pfn
, tfnSize
, pfn
, "/", "_");
str_replace
(pfn
, tfnSize
, pfn
, ":", "_");
str_replace
(pfn
, tfnSize
, pfn
, "*", "_");
str_replace
(pfn
, tfnSize
, pfn
, "?", "_");
str_replace
(pfn
, tfnSize
, pfn
, "<", "_");
str_replace
(pfn
, tfnSize
, pfn
, ">", "_");
str_replace
(pfn
, tfnSize
, pfn
, "|", "_");
str_replace
(pfn
, tfnSize
, pfn
, " ", "_");
str_replace
(pfn
, tfnSize
, pfn
, "'", "'");
str_replace
(pfn
, tfnSize
, pfn
, "&", "&");
str_replace
(pfn
, tfnSize
, pfn
, """, "'");
str_replace
(pfn
, tfnSize
, pfn
, ">", ")");
str_replace
(pfn
, tfnSize
, pfn
, "<", "(");
str_replace
(pfn
, tfnSize
, pfn
, "\"", "'");
}
void stringRepair
(unsigned char *pfn
, unsigned int tSize
)
{
str_replace
(pfn
, tSize
, pfn
, "'", "'");
str_replace
(pfn
, tSize
, pfn
, "&", "&");
str_replace
(pfn
, tSize
, pfn
, ">", ">");
str_replace
(pfn
, tSize
, pfn
, "<", "<");
str_replace
(pfn
, tSize
, pfn
, """, "\"");
str_replace
(pfn
, tSize
, pfn
, "\\/", "/");
}
void ncReplace
(void)
{
unsigned char len
;
for (len
= 0; len
< strlen(curFileStruct.
afn); len
++)
{
if (curFileStruct.
afn[len
] < ' ')
{
curFileStruct.
afn[len
] = '_';
}
}
for (len
= 0; len
< strlen(curFileStruct.
tfn); len
++)
{
if (curFileStruct.
tfn[len
] < ' ')
{
curFileStruct.
tfn[len
] = '_';
}
}
}
unsigned char saveBuf
(unsigned long fileId
, unsigned char operation
, unsigned int sizeOfBuf
)
{
FILE
*fp2
;
unsigned long fileSize
;
unsigned char afnSize
, tfnSize
;
unsigned char fileIdChar
[10];
if (operation
== 00)
{
if (saveFlag
== 0)
{
sprintf(curFileStruct.
fileName, "temp.%s", formats
[curFormat
]);
}
else
{
afnSize
= sizeof(curFileStruct.
afn) - 1;
tfnSize
= sizeof(curFileStruct.
tfn) - 1;
strcpy(curFileStruct.
afn, curFileStruct.
authorTitle);
nameRepair
(curFileStruct.
afn, afnSize
);
strcpy(curFileStruct.
tfn, curFileStruct.
trackName);
nameRepair
(curFileStruct.
tfn, tfnSize
);
sprintf(curFileStruct.
fileName, "%s-%s.%s", curFileStruct.
afn, curFileStruct.
tfn, formats
[curFormat
]);
ncReplace
();
if (strlen(curFileStruct.
fileName) > 63)
{
sprintf(fileIdChar
, "-%ld", fileId
);
str_replace
(curFileStruct.
fileName, sizeof(curFileStruct.
fileName) - 1, curFileStruct.
fileName, fileIdChar
, "");
curFileStruct.
fileName[50] = '\0';
strcat(curFileStruct.
fileName, fileIdChar
);
strcat(curFileStruct.
fileName, formats
[curFormat
]);
}
}
OS_SETSYSDRV
();
OS_MKDIR
("../downloads/radio"); // Create if not exist
OS_CHDIR
("../downloads/radio");
fp2
= OS_CREATEHANDLE
(curFileStruct.
fileName, 0x80);
if (((int)fp2
) & 0xff)
{
clearStatus
();
printf("%s creating error. Check for downloads\\radio folder.", curFileStruct.
fileName);
getchar();
exit(0);
}
OS_CLOSEHANDLE
(fp2
);
return 0;
}
if (operation
== 01)
{
fp2
= OS_OPENHANDLE
(curFileStruct.
fileName, 0x80);
if (((int)fp2
) & 0xff)
{
clearStatus
();
printf("%s opening error.", curFileStruct.
fileName);
exit(0);
}
fileSize
= OS_GETFILESIZE
(fp2
);
OS_SEEKHANDLE
(fp2
, fileSize
);
OS_WRITEHANDLE
(netbuf
, fp2
, sizeOfBuf
);
OS_CLOSEHANDLE
(fp2
);
return 0;
}
if (operation
== 02)
{
OS_CLOSEHANDLE
(fp2
);
return 0;
}
return 0;
}
void getData
(unsigned char socket
)
{
unsigned int todo
, w
, bPos
, skipHeader
;
skipHeader
= 0;
bPos
= 0;
while (1)
{
todo
= tcpRead
(socket
);
if (todo
== 0)
{
break;
}
if (skipHeader
== 0)
{
skipHeader
= 1;
todo
= cutHeader
(todo
);
}
if (bPos
+ todo
> sizeof(dataBuffer
))
{
clearStatus
();
printf("dataBuffer overrun...");
break;
}
for (w
= 0; w
< todo
; w
++)
{
dataBuffer
[w
+ bPos
] = netbuf
[w
];
}
bPos
= bPos
+ todo
;
if (bPos
== contLen
)
{
// dataBuffer[todo + bPos + 1] = '\0';
break;
}
}
netShutDown
(socket
, 1);
}
unsigned int tcpSend
(unsigned char socket
, unsigned int messageadr
, unsigned int size
)
{
unsigned char retry
= 20;
unsigned int todo
;
readStruct.
socket = socket
;
readStruct.
BufAdr = messageadr
;
readStruct.
bufsize = size
;
readStruct.
protocol = SOCK_STREAM
;
wizwrite
:
todo
= OS_WIZNETWRITE
(&readStruct
);
if (todo
> 32767)
{
clearStatus
();
printf("OS_WIZNETWRITE: ");
errorPrint
(todo
& 255);
if (retry
== 0)
{
exit(0);
}
retry
--;
delay
(150);
goto wizwrite
;
}
else
{
if (logFlag
)
{
clearStatus
();
printf("OS_WIZNETWRITE: %u bytes written.", todo
);
}
}
return todo
;
}
unsigned long processJson
(unsigned long startPos
, unsigned char limit
, unsigned char queryNum
)
{
FILE
*fp3
;
unsigned int retry
, tSize
;
unsigned int todo
;
unsigned char buffer
[] = "000000000";
unsigned char *count
, socket
;
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";
unsigned char userQuery
[256] = "/api/export:zxMusic/limit:10/filter:zxMusicId=44816";
clearStatus
();
printf("Getting data(%u)...", queryNum
);
switch (queryNum
)
{
case 0: // GET /api/export:zxMusic/limit:1/start:1/filter:zxMusicFormat=pt3/order:date,desc HTTP/1.1\r\nHost: zxart.ee\r\nUser-Agent: User-Agent: Mozilla/4.0 (compatible; MSIE5.01; NedoOS)
strcpy(netbuf
, "GET /api/export:zxMusic/limit:");
sprintf(buffer
, "%u", limit
);
strcat(netbuf
, buffer
);
strcat(netbuf
, "/start:");
sprintf(buffer
, "%lu", startPos
);
strcat(netbuf
, buffer
);
strcat(netbuf
, "/filter:zxMusicFormat=");
strcat(netbuf
, formats
[curFormat
]);
strcat(netbuf
, "/order:date,desc");
strcat(netbuf
, userAgent
);
break;
case 1: // GET /api/types:zxMusic/export:zxMusic/language:eng/limit:1/start:0/order:votes,rand/filter:zxMusicMinRating=4;
startPos
= 0;
strcpy(netbuf
, "GET /api/types:zxMusic/export:zxMusic/language:eng/limit:");
sprintf(buffer
, "%u", limit
);
strcat(netbuf
, buffer
);
strcat(netbuf
, "/start:");
sprintf(buffer
, "%lu", startPos
);
strcat(netbuf
, buffer
);
strcat(netbuf
, "/order:votes,rand/filter:zxMusicMinRating=4;zxMusicFormat=");
strcat(netbuf
, formats
[curFormat
]);
strcat(netbuf
, userAgent
);
break;
case 2: // GET /api/types:zxMusic/export:zxMusic/language:eng/limit:1/start:0/order:rand/filter:zxMusicFormat=PT3 HTTP/1.1\r\nHost: zxart.ee\r\nUser-Agent: User-Agent: Mozilla/4.0 (compatible; MSIE5.01; NedoOS)
startPos
= 0;
strcpy(netbuf
, "GET /api/types:zxMusic/export:zxMusic/language:eng/limit:");
sprintf(buffer
, "%u", limit
);
strcat(netbuf
, buffer
);
strcat(netbuf
, "/start:");
sprintf(buffer
, "%lu", startPos
);
strcat(netbuf
, buffer
);
strcat(netbuf
, "/order:rand/filter:zxMusicFormat=");
strcat(netbuf
, formats
[curFormat
]);
strcat(netbuf
, userAgent
);
break;
case 3: // GET /api/export:zxMusic/limit:1/start:1/filter:zxMusicFormat=pt3;authorId=7744/order:date,desc HTTP/1.1\r\nHost: zxart.ee\r\nUser-Agent: User-Agent: Mozilla/4.0 (compatible; MSIE5.01; NedoOS)
fp3
= OS_OPENHANDLE
("radio/user.que", 0x80);
if (((int)fp3
) & 0xff)
{
fp3
= OS_CREATEHANDLE
("radio/user.que", 0x80);
OS_WRITEHANDLE
(userQuery
, fp3
, sizeof(userQuery
));
OS_CLOSEHANDLE
(fp3
);
fp3
= OS_OPENHANDLE
("radio/user.que", 0x80);
}
OS_READHANDLE
(userQuery
, fp3
, sizeof(userQuery
));
OS_CLOSEHANDLE
(fp3
);
strcpy(netbuf
, "GET /api/limit:");
sprintf(buffer
, "%u", limit
);
strcat(netbuf
, buffer
);
strcat(netbuf
, "/start:");
sprintf(buffer
, "%lu", startPos
);
strcat(netbuf
, buffer
);
strcat(netbuf
, userQuery
);
strcat(netbuf
, userAgent
);
break;
case 99: // GET /jsonElementData/elementId:182798
strcpy(netbuf
, "GET /jsonElementData/elementId:");
sprintf(buffer
, "%lu", startPos
);
strcat(netbuf
, buffer
);
strcat(netbuf
, userAgent
);
break;
}
retry
= 10;
while (42)
{
if (netDriver
== 0)
{
socket
= OpenSock
(AF_INET
, SOCK_STREAM
);
netConnect
(socket
);
todo
= tcpSend
(socket
, (unsigned int)&netbuf
, strlen(netbuf
));
getData
(socket
);
clearStatus
();
printf("Processing data (%u)...", queryNum
);
}
else
{
fillDataBufferEsp
();
}
count
= strstr(dataBuffer
, "responseStatus\":\"success");
if (count
== NULL
)
{
retry
--;
clearStatus
();
printf("PROCESS JSON: [ERROR: Bad responseStatus.] [Query:%u][Retry:%u] [Track:%lu]\r\n", queryNum
, retry
, startPos
);
YIELD
();
if (retry
< 1)
{
return -1;
}
}
else
{
break;
}
}
count
= strstr(dataBuffer
, "\"id\":");
if (count
== NULL
)
{
clearStatus
();
printf("BAD JSON: not ID query = %u startPos = %lu", queryNum
, startPos
);
return -2;
}
if (queryNum
< 4)
{
netbuf
[0] = '\0';
parseJson
("\"id\":");
curFileStruct.
picId = atol(netbuf
);
parseJson
(",\"title\":\"");
convert866
();
strcpy(curFileStruct.
trackName, netbuf
);
tSize
= sizeof(curFileStruct.
trackName);
stringRepair
(curFileStruct.
trackName, tSize
);
parseJson
("\"rating\":\"");
strcpy(curFileStruct.
picRating, netbuf
);
parseJson
("\"year\":\"");
curFileStruct.
picYear = atoi(netbuf
);
parseJson
("\"totalAmount\":");
curFileStruct.
totalAmount = atol(netbuf
);
parseJson
("\"time\":\"");
strcpy(curFileStruct.
time, netbuf
);
parseJson
("\"authorIds\":[");
strcpy(curFileStruct.
authorIds, netbuf
);
parseJson
("\"authorIds\":[");
strcpy(curFileStruct.
fileName2, netbuf
);
}
if (queryNum
== 99)
{
parseJson
(",\"title\":\"");
convert866
();
strcpy(curFileStruct.
authorTitle, netbuf
);
parseJson
(",\"realName\":\"");
convert866
();
strcpy(curFileStruct.
authorRealName, netbuf
);
}
return curFileStruct.
picId;
}
unsigned char getTrack2
(unsigned long fileId
)
{
unsigned int todo
;
unsigned char cmdlist1
[] = "GET /file/id:";
unsigned char cmdlist2
[] = " HTTP/1.1\r\nHost: zxart.ee\r\nUser-Agent: Mozilla/4.0 (compatible; MSIE5.01; NedoOS; Radio)\r\n\r\n\0";
unsigned char buffer
[] = "0000000000";
unsigned char socket
;
unsigned int skipHeader
= 0;
unsigned long bytecount
;
unsigned int packSize
= 2000;
unsigned char sizeLink
;
unsigned long toDownload
, downloaded
;
unsigned char byte
= 0;
unsigned int dataSize
;
if (netDriver
== 0)
{
clearStatus
();
printf("Getting track...");
strcpy(netbuf
, cmdlist1
);
sprintf(buffer
, "%lu", fileId
);
strcat(netbuf
, buffer
);
strcat(netbuf
, cmdlist2
);
socket
= OpenSock
(AF_INET
, SOCK_STREAM
);
todo
= netConnect
(socket
);
todo
= tcpSend
(socket
, (unsigned int)&netbuf
, strlen(netbuf
));
saveBuf
(curFileStruct.
picId, 00, 0);
do
{
todo
= tcpRead
(socket
);
if (todo
== 0)
{
break;
}
if (skipHeader
== 0)
{
skipHeader
= 1;
todo
= cutHeader
(todo
);
bytecount
= contLen
;
}
saveBuf
(curFileStruct.
picId, 01, todo
);
bytecount
= bytecount
- todo
;
} while (bytecount
!= 0);
netShutDown
(socket
, 0);
}
else
{
clearStatus
();
printf("Getting track...");
sprintf(buffer
, "%lu", fileId
);
strcpy(netbuf
, cmdlist1
);
strcat(netbuf
, buffer
);
strcat(netbuf
, cmdlist2
);
saveBuf
(curFileStruct.
picId, 00, 0);
strcpy(link
, netbuf
);
sizeLink
= strlen(link
);
sendcommand
("AT+CIPSTART=\"TCP\",\"zxart.ee\",80");
getAnswer
(2); // CONNECT
getAnswer
(0); // OK
strcpy(netbuf
, cmdlist1
);
sprintf(buffer
, "%lu", fileId
);
strcat(netbuf
, buffer
);
strcat(netbuf
, cmdlist2
);
strcpy(cmd
, "AT+CIPSEND=");
sprintf(netbuf
, "%u", sizeLink
+ 2); // second CRLF in send command
strcat(cmd
, netbuf
);
sendcommand
(cmd
);
do
{
byte
= uart_readBlock
();
// putchar(byte);
} while (byte
!= '>');
sendcommand
(link
);
getAnswer
(2); // Recv 132 bytes
getAnswer
(2); // SEND OK
getAnswer
(2); //+IPD,3872
downloaded
= 0;
do
{
headlng
= 0;
strcpy(netbuf
, "AT+CIPRECVDATA=");
sprintf(link
, "%u", packSize
);
strcat(netbuf
, link
);
sendcommand
(netbuf
);
dataSize
= recvHead
();
getdataEsp
(dataSize
); // Requested size
if (skipHeader
== 0)
{
dataSize
= cutHeader
(dataSize
);
toDownload
= contLen
;
skipHeader
= 1;
}
downloaded
= downloaded
+ dataSize
;
saveBuf
(curFileStruct.
picId, 01, dataSize
);
toDownload
= toDownload
- dataSize
;
getAnswer
(2); // OK
if (toDownload
> 0)
{
getAnswer
(2); // +IPD,1824
}
} while (toDownload
> 0);
sendcommand
("AT+CIPCLOSE");
getAnswer
(0); // CLOSED
}
return 0;
}
unsigned char runPlayer
(void)
{
FILE
*fp2
;
unsigned char fileName
[] = "radio/player.ovl";
unsigned char appCmd
[128] = "player.com ";
unsigned char curPath
[128];
unsigned long playerSize
, loaded
, loop
;
unsigned char pgbak
;
clearStatus
();
printf("Running player...");
strcat(appCmd
, curFileStruct.
fileName);
player_pg.
l = OS_GETMAINPAGES
();
pgbak
= main_pg.
pgs.
window_3;
loaded
= 0;
OS_GETPATH
((unsigned int)&curPath
);
OS_SETSYSDRV
();
fp2
= OS_OPENHANDLE
(fileName
, 0x80);
if (((int)fp2
) & 0xff)
{
clearStatus
();
printf("%s", fileName
);
printf(" not found.");
exit(0);
}
playerSize
= OS_GETFILESIZE
(fp2
);
OS_CHDIR
(curPath
);
OS_NEWAPP
((unsigned int)&player_pg
);
SETPG32KHIGH
(player_pg.
pgs.
window_3);
memcpy((char *)(0xC080), &appCmd
, sizeof(appCmd
));
for (loop
= 0; loop
< playerSize
; loop
= loop
+ loaded
)
{
loaded
= OS_READHANDLE
(dataBuffer
, fp2
, sizeof(dataBuffer
));
memcpy((char *)(0xC100 + loop
), &dataBuffer
, loaded
);
}
OS_CLOSEHANDLE
(fp2
);
SETPG32KHIGH
(pgbak
);
OS_RUNAPP
(player_pg.
pgs.
pId);
return player_pg.
pgs.
pId;
}
long trackSelector
(unsigned char mode
)
{
switch (mode
)
{
case 0: // Next track
count
++;
if (count
> curFileStruct.
totalAmount - 1)
{
count
= 0;
}
break;
case 1: // Prev. track
count
--;
if (count
< 0)
{
count
= curFileStruct.
totalAmount - 1;
}
break;
}
return count
;
}
void printStatus
(void)
{
AT
(1, 9);
ATRIB
(93);
printf(" [Q]Query : ");
ATRIB
(97);
printf("%s", queryType
);
printf(" ");
AT
(1, 24);
ATRIB
(45);
printf(" ");
AT
(2, 24);
ATRIB
(93);
printf(" [F]Format: ");
ATRIB
(97);
printf("%s", formats
[curFormat
]);
ATRIB
(93);
printf(" [K]Keep files: ");
ATRIB
(97);
printf("%u", saveFlag
);
ATRIB
(93);
printf(" [R]Repeat: ");
ATRIB
(97);
printf("%u", rptFlag
);
ATRIB
(93);
printf(" [J]Jump to ");
printf(" [E]Exit [%s]", ver
);
ATRIB
(97);
ATRIB
(40);
}
void printInfo
(void)
{
BOX
(30, 2, 50, 6, 40);
AT
(1, 2);
ATRIB
(97);
ATRIB
(93);
printf(" #: ");
ATRIB
(97);
printf("%lu", count
);
ATRIB
(93);
printf(" ID: ");
ATRIB
(97);
printf("%lu", curFileStruct.
picId);
ATRIB
(93);
printf(" Total Tracks: ");
ATRIB
(97);
printf("%lu", curFileStruct.
totalAmount);
printf(" \r\n");
ATRIB
(93);
printf(" RATING: ");
ATRIB
(97);
printf("%s", curFileStruct.
picRating);
ATRIB
(93);
printf(" YEAR: ");
ATRIB
(97);
printf("%u", curFileStruct.
picYear);
ATRIB
(93);
printf(" DURATION: ");
ATRIB
(97);
printf("%s", curFileStruct.
time);
printf(" \r\n\r\n");
ATRIB
(93);
printf(" AuthorsIDs ");
ATRIB
(97);
printf("%s", curFileStruct.
authorIds);
ATRIB
(93);
printf(" Author: ");
ATRIB
(97);
printf("%s", curFileStruct.
authorTitle);
ATRIB
(93);
printf(" Real name: ");
ATRIB
(97);
printf("%s", curFileStruct.
authorRealName);
printf(" \r\n\r\n");
ATRIB
(96);
printf(" \r");
printf(" TITLE: %s\r\n", curFileStruct.
trackName);
}
unsigned char testPlayer
(void)
{
union APP_PAGES player2_pg
;
player2_pg.
l = OS_GETAPPMAINPAGES
(player_pg.
pgs.
pId);
if (errno
== 0)
{
return 1;
}
else
{
return 0;
}
}
C_task main
(int argc
, char *argv
[])
{
unsigned char errn
, keypress
, queryNum
, pId
, alive
, changedFormat
;
long iddqd
, idkfa
, ipadress
;
unsigned long curTimer
, startTimer
, oldTimer
;
os_initstdio
();
srand(time());
count
= 0;
saveFlag
= 0;
logFlag
= 0;
queryNum
= 0;
curFormat
= 0;
changedFormat
= 0;
rptFlag
= 0;
netDriver
= 0;
if (argc
> 1)
{
if ((argv
[1][0] == 'e') || (argv
[1][0] == 'E'))
{
netDriver
= 1;
clearStatus
();
printf(" ESP32 mode enabled...");
loadEspConfig
();
uart_init
(divider
);
espReBoot
();
printHelp
();
}
}
strcpy(queryType
, "from newest to oldest");
BOX
(1, 1, 80, 25, 40);
AT
(1, 1);
ATRIB
(97);
ATRIB
(45);
printf(" ZXART.EE radio for nedoNET \n\r");
AT
(1, 24);
printf(" [L]Enable logging(press on startup) ");
ATRIB
(33);
ATRIB
(40);
keypress
= _low_level_get
();
if (keypress
== 'l' || keypress
== 'L')
{
logFlag
= 1;
clearStatus
();
printf("Logging enabled");
getchar();
}
start
:
OS_SETSYSDRV
();
printHelp
();
curFileStruct.
fileSize = 0;
iddqd
= processJson
(count
, 1, queryNum
); // Query for track info
if (iddqd
< 0)
{
{
clearStatus
();
printf("Error getting track info, next please(%ld)...", iddqd
);
count
= trackSelector
(0);
goto start
;
}
}
idkfa
= processJson
(atol(curFileStruct.
authorIds), 0, 99); // Query for AuthorID
if (idkfa
< 0)
{
clearStatus
();
printf("Error getting author %lu", atol(curFileStruct.
authorIds));
strcpy(curFileStruct.
authorTitle, "-");
strcpy(curFileStruct.
authorRealName, "-");
}
replay
:
errn
= getTrack2
(iddqd
); // Downloading the track
resume
:
startTimer
= time();
printProgress
(0);
pId
= runPlayer
(); // Start thr Player!
printStatus
();
printInfo
();
rekey
:
keypress
= _low_level_get
();
if (keypress
!= 0)
{
if (keypress
== 27 || keypress
== 'e' || keypress
== 'E')
{
OS_DROPAPP
(pId
);
BOX
(1, 1, 80, 25, 40);
AT
(1, 1);
printf("Good bye...\r\n");
ATRIB
(37);
ATRIB
(40);
exit(0);
}
if (keypress
== 248 || keypress
== 'b' || keypress
== 'B')
{
changedFormat
= 0;
OS_DROPAPP
(pId
);
clearStatus
();
printf("Player stopped...");
count
= trackSelector
(1);
goto start
;
}
if (keypress
== 251 || keypress
== 32 || keypress
== 'n' || keypress
== 'N')
{
changedFormat
= 0;
OS_DROPAPP
(pId
);
clearStatus
();
printf("Player stopped...");
count
= trackSelector
(0);
goto start
;
}
if (keypress
== 'k' || keypress
== 'K')
{
OS_DROPAPP
(pId
);
clearStatus
();
printf("Player stopped...");
saveFlag
= !saveFlag
;
printStatus
();
goto replay
;
}
if (keypress
== 'q' || keypress
== 'Q')
{
OS_DROPAPP
(pId
);
clearStatus
();
printf("Player stopped...");
queryNum
++;
if (queryNum
> 3)
{
queryNum
= 0;
}
switch (queryNum
)
{
case 0:
strcpy(queryType
, "from newest to oldest ");
break;
case 1:
strcpy(queryType
, "Random best and most voted tracks ");
break;
case 2:
strcpy(queryType
, "Random play ");
break;
case 3:
strcpy(queryType
, "User defined query from \"user.que\" ");
break;
}
count
= 0;
printStatus
();
goto start
;
}
if (keypress
== 'j' || keypress
== 'J')
{
AT
(1, 7);
printf(" \r");
printf("Jump to track:");
scanf("%lu", &count
);
OS_DROPAPP
(pId
);
if (count
> curFileStruct.
totalAmount - 1)
{
count
= curFileStruct.
totalAmount - 1;
}
goto start
;
}
if (keypress
== 'f' || keypress
== 'F')
{
OS_DROPAPP
(pId
);
clearStatus
();
printf("Player stopped...");
curFormat
++;
count
= -1;
if (curFormat
> 3)
{
curFormat
= 0;
}
changedFormat
= 1;
curFileStruct.
totalAmount = 1;
printStatus
();
printProgress
(0);
BOX
(1, 2, 80, 6, 40);
goto rekey
;
}
if (keypress
== 'l' || keypress
== 'L')
{
logFlag
= !logFlag
;
clearStatus
();
printf("Logging: %u", logFlag
);
}
if (keypress
== 's' || keypress
== 'S')
{
OS_DROPAPP
(pId
);
clearStatus
();
printf("Player stopped...");
printProgress
(0);
getchar();
goto resume
;
}
if (keypress
== 'r' || keypress
== 'R')
{
rptFlag
= !rptFlag
;
clearStatus
();
printStatus
();
goto rekey
;
}
if (keypress
== 'd' || keypress
== 'D')
{
saveBak
= saveFlag
;
saveFlag
= 1;
errn
= getTrack2
(iddqd
); // Downloading the track
saveFlag
= saveBak
;
clearStatus
();
printf("File saved: [%s]...", curFileStruct.
fileName);
goto rekey
;
}
if (keypress
== 'i' || keypress
== 'I')
{
netDriver
= !netDriver
;
if (netDriver
== 1)
{
clearStatus
();
printf(" ESP32 mode enabled...");
loadEspConfig
();
uart_init
(divider
);
espReBoot
();
printHelp
();
}
else
{
clearStatus
();
printf(" ZXNETUSB mode enabled...");
}
}
}
curTimer
= time();
curFileStruct.
curPos = (curTimer
- startTimer
) / 50;
alive
= testPlayer
();
if (alive
== 0 && !changedFormat
)
{
if (rptFlag
== 1)
{
goto resume
;
}
printProgress
(2);
count
= trackSelector
(0);
goto start
;
}
if (alive
== 1 && ((curTimer
- oldTimer
) > 49))
{
printProgress
(1);
oldTimer
= curTimer
;
}
YIELD
();
goto rekey
;
}