Added project files
This commit is contained in:
@@ -142,12 +142,12 @@
|
|||||||
</Link>
|
</Link>
|
||||||
</ItemDefinitionGroup>
|
</ItemDefinitionGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ClCompile Include="..\..\..\..\..\Desktop\ipac\source\heap.c" />
|
<ClCompile Include="heap.c" />
|
||||||
<ClCompile Include="llist.c" />
|
<ClCompile Include="llist.c" />
|
||||||
<ClCompile Include="main.c" />
|
<ClCompile Include="main.c" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ClInclude Include="..\..\..\..\..\Desktop\ipac\include\heap.h" />
|
<ClInclude Include="heap.h" />
|
||||||
<ClInclude Include="llist.h" />
|
<ClInclude Include="llist.h" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
||||||
|
|||||||
@@ -3,10 +3,10 @@
|
|||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ClCompile Include="llist.c" />
|
<ClCompile Include="llist.c" />
|
||||||
<ClCompile Include="main.c" />
|
<ClCompile Include="main.c" />
|
||||||
<ClCompile Include="..\..\..\..\..\Desktop\ipac\source\heap.c" />
|
<ClCompile Include="heap.c" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ClInclude Include="llist.h" />
|
<ClInclude Include="llist.h" />
|
||||||
<ClInclude Include="..\..\..\..\..\Desktop\ipac\include\heap.h" />
|
<ClInclude Include="heap.h" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
</Project>
|
</Project>
|
||||||
@@ -0,0 +1,162 @@
|
|||||||
|
|
||||||
|
char customCharArray[64] = {
|
||||||
|
0b00000,0b01000,0b11111,0b01000,0b00010,0b11111,0b00010,0b00000, //Web sync true
|
||||||
|
0b00000,0b00100,0b01110,0b00000,0b00000,0b01110,0b00100,0b00000, //Up Down
|
||||||
|
0b00100,0b01110,0b01110,0b01110,0b11111,0b00000,0b00100,0b00000, //Alarm Clock
|
||||||
|
0b00000,0b00100,0b01101,0b11101,0b01101,0b00100,0b00000,0b00000, //Volume ON
|
||||||
|
0b00000,0b00100,0b01100,0b11100,0b01100,0b00100,0b00000,0b00000, //Volume OFF
|
||||||
|
0b00000,0b00001,0b00011,0b00111,0b01111,0b11111,0b00000,0b00000, //Network TRUE
|
||||||
|
0b00000,0b01000,0b01100,0b01110,0b01100,0b01000,0b00000,0b00000, //PLAY
|
||||||
|
0b00000,0b01110,0b10101,0b10111,0b10001,0b01110,0b00000,0b00000 //Time Sync TRUE
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
void LcdClear()
|
||||||
|
{
|
||||||
|
LcdWriteByte(WRITE_COMMAND, 0x01); // display clear
|
||||||
|
NutDelay(5);
|
||||||
|
LcdWriteByte(WRITE_COMMAND, 0x80); // DD-RAM address counter (cursor pos) to '0'
|
||||||
|
}
|
||||||
|
|
||||||
|
void LcdLine(u_char line, char text[])
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
|
||||||
|
if(line == 0) //Top line
|
||||||
|
{
|
||||||
|
LcdWriteByte(WRITE_COMMAND, 0x80); // command to write to line 1
|
||||||
|
for(i = 0; i< 16; i++)
|
||||||
|
{
|
||||||
|
LcdChar(32); //Clear the line
|
||||||
|
}
|
||||||
|
LcdWriteByte(WRITE_COMMAND, 0x80); // command to write to line 1
|
||||||
|
}
|
||||||
|
else if(line == 1) //Bottom line
|
||||||
|
{
|
||||||
|
LcdWriteByte(WRITE_COMMAND, 0xC0); // command to write to line 2
|
||||||
|
for(i = 0; i< 16; i++)
|
||||||
|
{
|
||||||
|
LcdChar(32); //Clear the line
|
||||||
|
}
|
||||||
|
LcdWriteByte(WRITE_COMMAND, 0xC0); // command to write to line 1
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
int count = 0;
|
||||||
|
|
||||||
|
while(text[count] != '\0')
|
||||||
|
{
|
||||||
|
//Replace ~n with the decimal n
|
||||||
|
//This displays the custom character
|
||||||
|
if(text[count] == '~')
|
||||||
|
{
|
||||||
|
count++;
|
||||||
|
char num = text[count];
|
||||||
|
|
||||||
|
int number = num - '0';
|
||||||
|
|
||||||
|
LcdWriteByte(WRITE_DATA, number);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
//Write char to display
|
||||||
|
LcdChar(text[count]);
|
||||||
|
}
|
||||||
|
|
||||||
|
count++;
|
||||||
|
|
||||||
|
if(count > 24)
|
||||||
|
break;
|
||||||
|
|
||||||
|
NutSleep(1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void LcdScrollLine(u_char line, int pos, char text[])
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
|
||||||
|
if(line == 0)
|
||||||
|
{
|
||||||
|
LcdWriteByte(WRITE_COMMAND, 0x80); // command to write to line 1
|
||||||
|
for(i = 0; i< 16; i++)
|
||||||
|
{
|
||||||
|
LcdChar(32);
|
||||||
|
}
|
||||||
|
LcdWriteByte(WRITE_COMMAND, 0x80); // command to write to line 1
|
||||||
|
}
|
||||||
|
else if(line == 1)
|
||||||
|
{
|
||||||
|
LcdWriteByte(WRITE_COMMAND, 0xC0); // command to write to line 2
|
||||||
|
for(i = 0; i< 16; i++)
|
||||||
|
{
|
||||||
|
LcdChar(32);
|
||||||
|
}
|
||||||
|
LcdWriteByte(WRITE_COMMAND, 0xC0); // command to write to line 1
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
//Start at scroll location
|
||||||
|
int count = pos;
|
||||||
|
|
||||||
|
while(text[count] != '\0')
|
||||||
|
{
|
||||||
|
if(text[count] == '~')
|
||||||
|
{
|
||||||
|
count++;
|
||||||
|
char num = text[count];
|
||||||
|
|
||||||
|
int number = num - '0';
|
||||||
|
|
||||||
|
LcdWriteByte(WRITE_DATA, number);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
LcdChar(text[count]);
|
||||||
|
}
|
||||||
|
|
||||||
|
count++;
|
||||||
|
|
||||||
|
if(count > 24 + pos)
|
||||||
|
break;
|
||||||
|
|
||||||
|
NutSleep(1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//Write data to the Custom Character RAM
|
||||||
|
void LcdCGRAM(char *icon, int length)
|
||||||
|
{
|
||||||
|
//SELECT CGRAM
|
||||||
|
LcdWriteByte(WRITE_COMMAND, 0x40);
|
||||||
|
|
||||||
|
int count;
|
||||||
|
|
||||||
|
//Write the array with custom icons
|
||||||
|
for(count = 0; count < length; count++)
|
||||||
|
{
|
||||||
|
LcdChar(icon[count]);
|
||||||
|
NutSleep(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
//Select the display RAM
|
||||||
|
LcdWriteByte(WRITE_COMMAND, 0x80);
|
||||||
|
}
|
||||||
|
|
||||||
|
void LcdSetPosition(int line)
|
||||||
|
{
|
||||||
|
if(line)
|
||||||
|
{
|
||||||
|
LcdWriteByte(WRITE_COMMAND, 0xC0);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
LcdWriteByte(WRITE_COMMAND, 0x80);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,10 @@
|
|||||||
|
|
||||||
|
#ifndef _Display_H
|
||||||
|
#define _Display_H
|
||||||
|
|
||||||
|
extern void LcdSetPosition(int);
|
||||||
|
extern void LcdLine(u_char line, char text[]);
|
||||||
|
extern void LcdScrollLine(u_char line, int pos, char text[]);
|
||||||
|
extern void LcdClear(void);
|
||||||
|
|
||||||
|
#endif
|
||||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,48 @@
|
|||||||
|
#ifndef MENU_INCLUDE
|
||||||
|
#define MENU_INCLUDE
|
||||||
|
|
||||||
|
/* Defines */
|
||||||
|
#define BL_SWITCH_OFF_DELAY 100 // lcd back-light switches of 10 sec after idle
|
||||||
|
#define MAX_MENU_KEY 4
|
||||||
|
#define LCD_MAX_LINES 2
|
||||||
|
/* Exported functions */
|
||||||
|
void handleMenu(void);
|
||||||
|
void InitMenu(void);
|
||||||
|
void navigateToMenu(unsigned int);
|
||||||
|
|
||||||
|
void AlarmStartedRinging(void);
|
||||||
|
void AlarmStoppedRinging(void);
|
||||||
|
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
unsigned int menuID; /* (Uniek) MenuID */
|
||||||
|
|
||||||
|
//Navigating
|
||||||
|
void (*fp_onEntry)(void); /* On entry function call */
|
||||||
|
void (*fp_onActive)(void); //On active function call
|
||||||
|
void (*fp_onExit)(void); /* On exit function call */
|
||||||
|
|
||||||
|
//Key events
|
||||||
|
void (*fp_onKeyESC)(void); /* function call for key's */
|
||||||
|
void (*fp_onKeyUP)(void);
|
||||||
|
void (*fp_onKeyDOWN)(void);
|
||||||
|
void (*fp_onKeyLEFT)(void);
|
||||||
|
void (*fp_onKeyRIGHT)(void);
|
||||||
|
void (*fp_onKeyOK)(void);
|
||||||
|
void (*fp_onKeyONE)(void);
|
||||||
|
void (*fp_onKeyTWO)(void);
|
||||||
|
void (*fp_onKeyTHREE)(void);
|
||||||
|
void (*fp_onKeyFOUR)(void);
|
||||||
|
void (*fp_onKeyFIVE)(void);
|
||||||
|
void (*fp_onKeyALT)(void);
|
||||||
|
|
||||||
|
//Quick navigating
|
||||||
|
unsigned int newMenuIdKey[MAX_MENU_KEY]; /* New menuId when key pressed */
|
||||||
|
|
||||||
|
//Text and other data
|
||||||
|
char *txt[LCD_MAX_LINES]; /* LCD_MAX_LINES lines of LCD text (or NULL) */
|
||||||
|
|
||||||
|
} MENU_ITEM_STRUCT;
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
@@ -0,0 +1,344 @@
|
|||||||
|
|
||||||
|
#define LOG_MODULE LOG_PLAYER_MODULE
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
#include <sys/thread.h>
|
||||||
|
#include <sys/timer.h>
|
||||||
|
#include <sys/version.h>
|
||||||
|
#include <dev/irqreg.h>
|
||||||
|
#include <arpa/inet.h>
|
||||||
|
#include <net/route.h>
|
||||||
|
#include <pro/dhcp.h>
|
||||||
|
#include <pro/sntp.h>
|
||||||
|
|
||||||
|
#include <sys/confnet.h>
|
||||||
|
|
||||||
|
#include <dev/board.h>
|
||||||
|
#include <pro/httpd.h>
|
||||||
|
#include <pro/asp.h>
|
||||||
|
#include <pro/discover.h>
|
||||||
|
#include <dev/nicrtl.h>
|
||||||
|
#include <sys/socket.h>
|
||||||
|
#include <netinet/tcp.h>
|
||||||
|
|
||||||
|
#include "player.h"
|
||||||
|
#include "vs10xx.h"
|
||||||
|
#include "streamer.h"
|
||||||
|
#include "settings.h"
|
||||||
|
#include <sys/bankmem.h>
|
||||||
|
|
||||||
|
#define OK 1
|
||||||
|
#define NOK 0
|
||||||
|
|
||||||
|
int stopped = 1;
|
||||||
|
int stopstream = 0;
|
||||||
|
|
||||||
|
char* MetaData;
|
||||||
|
|
||||||
|
int initPlayer(void)
|
||||||
|
{
|
||||||
|
MetaData = (char *) calloc(128, sizeof(char));
|
||||||
|
|
||||||
|
SetBass(GetBass());
|
||||||
|
SetTreble(GetTreble());
|
||||||
|
SetVolume(GetVolume());
|
||||||
|
return OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
char* GetMetaData(void)
|
||||||
|
{
|
||||||
|
return MetaData;
|
||||||
|
}
|
||||||
|
|
||||||
|
int isStreaming()
|
||||||
|
{
|
||||||
|
return !stopped;
|
||||||
|
}
|
||||||
|
|
||||||
|
int ProcessMetaData(FILE *stream)
|
||||||
|
{
|
||||||
|
u_char blks = 0;
|
||||||
|
u_short cnt;
|
||||||
|
int got;
|
||||||
|
int rc = 0;
|
||||||
|
u_char *mbuf;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Wait for the lenght byte.
|
||||||
|
*/
|
||||||
|
got = fread(&blks, 1, 1, stream);
|
||||||
|
if(got != 1) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
if (blks) {
|
||||||
|
if (blks > 32) {
|
||||||
|
printf("[PLAYER] Error: Metadata too large, %u blocks\n", blks);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
cnt = blks * 16;
|
||||||
|
if ((mbuf = malloc(cnt + 1)) == 0) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Receive the metadata block.
|
||||||
|
*/
|
||||||
|
for (;;) {
|
||||||
|
if ((got = fread(mbuf + rc, 1, cnt, stream)) <= 0) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
if ((cnt -= got) == 0) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
rc += got;
|
||||||
|
mbuf[rc] = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
memset(&MetaData[0], 0, sizeof(MetaData));
|
||||||
|
|
||||||
|
int count = 0;
|
||||||
|
int copy = 0;
|
||||||
|
|
||||||
|
int startval = 0;
|
||||||
|
int stopval = 0;
|
||||||
|
|
||||||
|
for(;;)
|
||||||
|
{
|
||||||
|
|
||||||
|
if(mbuf[count] == '\'' && copy == 1)
|
||||||
|
{
|
||||||
|
copy = 0;
|
||||||
|
stopval = count-1;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(mbuf[count] == '\'' && copy == 0)
|
||||||
|
{
|
||||||
|
startval = count+1;
|
||||||
|
copy = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
count++;
|
||||||
|
}
|
||||||
|
|
||||||
|
int len = stopval - startval;
|
||||||
|
len = len > 127 ? 127 : len;
|
||||||
|
|
||||||
|
strncpy(MetaData, (char*) &mbuf[startval], len);
|
||||||
|
|
||||||
|
free(mbuf);
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int stop(void)
|
||||||
|
{
|
||||||
|
if(stopped == 1)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
printf("[PLAYER] Stopping other stream\n");
|
||||||
|
|
||||||
|
stopstream = 1;
|
||||||
|
|
||||||
|
while(!stopped) { NutSleep(5); };
|
||||||
|
printf("[PLAYER] Stream stopped\n");
|
||||||
|
|
||||||
|
//Give thread time to clean up
|
||||||
|
NutSleep(100);
|
||||||
|
|
||||||
|
strcpy(MetaData, "");
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
int play(u_long ip, u_short port, u_char *path)
|
||||||
|
{
|
||||||
|
stop(); //Stop any old threads
|
||||||
|
|
||||||
|
FILE *stream;
|
||||||
|
TCPSOCKET *sock = 0;
|
||||||
|
u_long metaint;
|
||||||
|
|
||||||
|
stream = ConnectStation(sock, ip, port, path, &metaint); //Connect to a stream
|
||||||
|
|
||||||
|
if(!stream)
|
||||||
|
{
|
||||||
|
printf("[PLAYER] Not stream\n");
|
||||||
|
return NOK;
|
||||||
|
}
|
||||||
|
|
||||||
|
//Package 3 variables in a struct to pass them to the thread.
|
||||||
|
StreamData *arguments = malloc(sizeof(StreamData));
|
||||||
|
arguments->stream = stream;
|
||||||
|
arguments->sock = sock;
|
||||||
|
arguments->metaint = metaint;
|
||||||
|
|
||||||
|
//Start thread with packaged arguments
|
||||||
|
NutThreadCreate("Streamer", StreamPlayer, arguments, 512);
|
||||||
|
|
||||||
|
//Await thread start
|
||||||
|
NutSleep(20);
|
||||||
|
|
||||||
|
//Clear the packege
|
||||||
|
free(arguments);
|
||||||
|
|
||||||
|
return OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
THREAD(StreamPlayer, arg)
|
||||||
|
{
|
||||||
|
|
||||||
|
NutThreadSetPriority(1); // high prio
|
||||||
|
|
||||||
|
printf("[PLAYER] Play thread created. Device is playing stream now !\n");
|
||||||
|
|
||||||
|
StreamData* f = (StreamData *) arg;
|
||||||
|
|
||||||
|
FILE* stream = f->stream;
|
||||||
|
TCPSOCKET* sock = f->sock;
|
||||||
|
u_long metaint = f->metaint;
|
||||||
|
|
||||||
|
size_t rbytes;
|
||||||
|
u_char *mp3buf;
|
||||||
|
u_char ief;
|
||||||
|
int got = 0;
|
||||||
|
u_long last;
|
||||||
|
u_long mp3left = metaint;
|
||||||
|
int endstream = 0;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Initialize the MP3 buffer. The NutSegBuf routines provide a global
|
||||||
|
* system buffer, which works with banked and non-banked systems.
|
||||||
|
*/
|
||||||
|
if (NutSegBufInit(8192) == 0) {
|
||||||
|
printf("[PLAYER] Error: MP3 buffer init failed\n");
|
||||||
|
NutThreadExit();
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Initialize the MP3 decoder hardware.
|
||||||
|
*/
|
||||||
|
if (VsPlayerReset(0)) {
|
||||||
|
printf("[PLAYER] Error: MP3 hardware init failed\n");
|
||||||
|
NutThreadExit();
|
||||||
|
}
|
||||||
|
|
||||||
|
stopped = 0;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Reset the MP3 buffer.
|
||||||
|
*/
|
||||||
|
ief = VsPlayerInterrupts(0);
|
||||||
|
NutSegBufReset();
|
||||||
|
VsPlayerInterrupts(ief);
|
||||||
|
last = NutGetSeconds();
|
||||||
|
|
||||||
|
for (;;) {
|
||||||
|
|
||||||
|
if(stopstream)
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Query number of byte available in MP3 buffer.
|
||||||
|
*/
|
||||||
|
ief = VsPlayerInterrupts(0);
|
||||||
|
mp3buf = (u_char*) NutSegBufWriteRequest(&rbytes);
|
||||||
|
VsPlayerInterrupts(ief);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* If the player is not running, kick it.
|
||||||
|
*/
|
||||||
|
if (VsGetStatus() != VS_STATUS_RUNNING) {
|
||||||
|
printf("[PLAYER] Not running\n");
|
||||||
|
if(rbytes < 1024 || NutGetSeconds() - last > 4UL) {
|
||||||
|
last = NutGetSeconds();
|
||||||
|
printf("[PLAYER] Kick player\n");
|
||||||
|
VsPlayerKick();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/*
|
||||||
|
* Do not read pass metadata.
|
||||||
|
*/
|
||||||
|
if (metaint && rbytes > mp3left) {
|
||||||
|
rbytes = mp3left;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Read data directly into the MP3 buffer.
|
||||||
|
*/
|
||||||
|
while (rbytes) {
|
||||||
|
|
||||||
|
if ((got = fread(mp3buf, 1, rbytes, stream)) > 0) {
|
||||||
|
ief = VsPlayerInterrupts(0);
|
||||||
|
mp3buf = (u_char *) NutSegBufWriteCommit(got);
|
||||||
|
VsPlayerInterrupts(ief);
|
||||||
|
|
||||||
|
if (metaint) {
|
||||||
|
mp3left -= got;
|
||||||
|
if (mp3left == 0) {
|
||||||
|
ProcessMetaData(stream);
|
||||||
|
mp3left = metaint;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if(got < rbytes && got < 512) {
|
||||||
|
//printf("%lu buffered\n", NutSegBufUsed());
|
||||||
|
NutSleep(250);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
NutThreadYield();
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
printf("[PLAYER] Failed to read from stream, closing\n");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
rbytes -= got;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(got <= 0) {
|
||||||
|
endstream++;
|
||||||
|
|
||||||
|
printf("[PLAYER] Stream ending, %d tries left\n", 3 - endstream);
|
||||||
|
|
||||||
|
if(endstream >= 3)
|
||||||
|
{
|
||||||
|
printf("[PLAYER] End of stream, closing\n");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
endstream = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
VsPlayerStop(); //Stop the audio
|
||||||
|
|
||||||
|
while (VsGetStatus() == VS_STATUS_RUNNING) {
|
||||||
|
NutSleep(50); //Wait until player has really stopped
|
||||||
|
}
|
||||||
|
|
||||||
|
fclose(stream); //Close stream
|
||||||
|
NutTcpCloseSocket(sock); //Close socket
|
||||||
|
|
||||||
|
strcpy(MetaData, ""); //Clear meta data
|
||||||
|
|
||||||
|
stopstream = 0; //Clear stop flag
|
||||||
|
stopped = 1; //Mark thread as stopped
|
||||||
|
|
||||||
|
printf("[PLAYER] End of play thread\n");
|
||||||
|
|
||||||
|
NutThreadExit(); //Clean up thread and exit
|
||||||
|
|
||||||
|
for(;;)
|
||||||
|
{
|
||||||
|
printf("[PLAYER] PLAY THREAD NOT STOPPED\n");
|
||||||
|
NutThreadYield();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@@ -0,0 +1,28 @@
|
|||||||
|
#ifndef PLAYER_INC
|
||||||
|
#define PLAYER_INC
|
||||||
|
|
||||||
|
#include <sys/nutconfig.h>
|
||||||
|
#include <sys/types.h>
|
||||||
|
|
||||||
|
//#include <stdlib.h>
|
||||||
|
//#include <string.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <io.h>
|
||||||
|
|
||||||
|
//Struct to package arguments to array
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
FILE* stream;
|
||||||
|
TCPSOCKET* sock;
|
||||||
|
u_long metaint;
|
||||||
|
} StreamData;
|
||||||
|
|
||||||
|
THREAD(StreamPlayer, arg);
|
||||||
|
|
||||||
|
extern int initPlayer(void);
|
||||||
|
extern char * GetMetaData(void);
|
||||||
|
extern int play(u_long ip, u_short port, u_char *path);
|
||||||
|
extern int stop(void);
|
||||||
|
extern int isStreaming(void);
|
||||||
|
|
||||||
|
#endif
|
||||||
@@ -0,0 +1,155 @@
|
|||||||
|
/* ========================================================================
|
||||||
|
* [PROJECT] SIR
|
||||||
|
* [MODULE] Real Time Clock
|
||||||
|
* [TITLE] High- and low level Routines for INtersil X1205 RTC chip
|
||||||
|
* [FILE] rtc.c
|
||||||
|
* [VSN] 1.0
|
||||||
|
* [CREATED] 13042007
|
||||||
|
* [LASTCHNGD] 131042007
|
||||||
|
* [COPYRIGHT] Copyright (C) STREAMIT BV 2010
|
||||||
|
* [PURPOSE] contains all interface- and low-level routines to
|
||||||
|
* read/write date/time/status strings from the X1205
|
||||||
|
* ======================================================================== */
|
||||||
|
|
||||||
|
#define LOG_MODULE LOG_RTC_MODULE
|
||||||
|
|
||||||
|
#include <cfg/os.h>
|
||||||
|
#include <dev/twif.h>
|
||||||
|
#include <sys/event.h>
|
||||||
|
#include <sys/timer.h>
|
||||||
|
#include <sys/thread.h>
|
||||||
|
|
||||||
|
#include <arpa/inet.h>
|
||||||
|
#include <net/route.h>
|
||||||
|
#include <pro/dhcp.h>
|
||||||
|
#include <pro/sntp.h>
|
||||||
|
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <io.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <time.h>
|
||||||
|
|
||||||
|
#include "rtc.h"
|
||||||
|
#include "portio.h"
|
||||||
|
|
||||||
|
//Timezones with offset value and name
|
||||||
|
const int tz[25] = { -11, -10, -9, -8, -7, -6, -5, -4, -3, -2, -1, 0, +1, +2, +3, +4, +5, +6, +7, +8, +9, +10, +11, +12, +13};
|
||||||
|
const char tzName[25][30] = { "Midway", "Honolulu", "Anchorage", "Los Angeles", "Phoenix", "Chicago", "New York", "Santiago", "Buenos Aires", "South-Georgia", "Azores", "London", "Amsterdam", "Athens", "Moscow", "Dubai", "Pakistan", "Bangladesh", "Bangkok", "Bejing", "Tokyo", "Sydney", "Solomon", "Auckland", "Samoa" };
|
||||||
|
|
||||||
|
|
||||||
|
//Sync the RTC with NTP server and apply timezone offset
|
||||||
|
int X12RTCSyncClock(void)
|
||||||
|
{
|
||||||
|
time_t cur_time = 0;
|
||||||
|
tm *cur_dt = malloc(sizeof(tm));
|
||||||
|
|
||||||
|
uint32_t timeserver = 0;
|
||||||
|
|
||||||
|
timeserver = inet_addr("85.254.217.3");
|
||||||
|
|
||||||
|
int i;
|
||||||
|
//3 attempts are allowed before giving up
|
||||||
|
for (i = 0; i < 3; i++) {
|
||||||
|
|
||||||
|
//Try to get the NTP time
|
||||||
|
if (NutSNTPGetTime(×erver, &cur_time) == 0) {
|
||||||
|
synced = 1; //Mark time as synced
|
||||||
|
|
||||||
|
printf("[RTC] Sync Succesfull\n");
|
||||||
|
|
||||||
|
//TimeZone
|
||||||
|
_timezone = 0;
|
||||||
|
stime(&cur_time);
|
||||||
|
|
||||||
|
_timezone = -GetTimeZone() * 60 * 60; //Apply timezone offset
|
||||||
|
_daylight = 1;
|
||||||
|
time(&cur_time);
|
||||||
|
cur_dt = localtime(&cur_time); //Calculate timezone offset
|
||||||
|
|
||||||
|
X12RtcSetClock(cur_dt); //Set the new time in the RTC
|
||||||
|
break;
|
||||||
|
} else {
|
||||||
|
synced = 0; //Mark time as out of sync
|
||||||
|
NutSleep(500);
|
||||||
|
printf("[RTC] Sync Failed, retrying\n");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
free(cur_dt);
|
||||||
|
|
||||||
|
SetConnected(synced); //Mark network connections the same as synced value
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
//Format the RTC value to a Time string
|
||||||
|
void GetTimeString(char * str)
|
||||||
|
{
|
||||||
|
if (X12RtcGetClock(&gmt) == 0)
|
||||||
|
{
|
||||||
|
gmt.tm_year = gmt.tm_year + 1900;
|
||||||
|
sprintf(str, "%02d:%02d:%02d", gmt.tm_hour, gmt.tm_min, gmt.tm_sec);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//Format the RTC value to a Date string
|
||||||
|
void GetDateString(char * str)
|
||||||
|
{
|
||||||
|
if (X12RtcGetClock(&gmt) == 0)
|
||||||
|
{
|
||||||
|
gmt.tm_year = gmt.tm_year + 1900;
|
||||||
|
sprintf(str, "%02d-%02d-%04d", gmt.tm_mday, gmt.tm_mon+1, gmt.tm_year );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//Format the RTC value to a DateTime string
|
||||||
|
void GetDateTimeString(char * str)
|
||||||
|
{
|
||||||
|
if (X12RtcGetClock(&gmt) == 0)
|
||||||
|
{
|
||||||
|
gmt.tm_year = gmt.tm_year + 1900;
|
||||||
|
sprintf(str, "%02d:%02d %02d-%02d-%04d", gmt.tm_hour, gmt.tm_min, gmt.tm_mday, gmt.tm_mon+1, gmt.tm_year );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//Get the time struct which is synced using the RTC and NTP
|
||||||
|
tm* GetTimeStruct(void)
|
||||||
|
{
|
||||||
|
if (X12RtcGetClock(&gmt) == 0)
|
||||||
|
{
|
||||||
|
gmt.tm_year = gmt.tm_year + 1900;
|
||||||
|
}
|
||||||
|
|
||||||
|
return &gmt;
|
||||||
|
}
|
||||||
|
|
||||||
|
//Sync time with the NTP server
|
||||||
|
int SyncTime( void )
|
||||||
|
{
|
||||||
|
X12RTCSyncClock();
|
||||||
|
|
||||||
|
if (X12RtcGetClock(&gmt) == 0)
|
||||||
|
{
|
||||||
|
//X12RtcGetClockTimezone(&gmt, GetTimeZone());
|
||||||
|
gmt.tm_year = gmt.tm_year + 1900;
|
||||||
|
printf("[RTC] Time [%02d:%02d:%02d / %02d-%02d-%04d]\n", gmt.tm_hour, gmt.tm_min, gmt.tm_sec, gmt.tm_mday, gmt.tm_mon+1, gmt.tm_year );
|
||||||
|
}
|
||||||
|
|
||||||
|
return synced;
|
||||||
|
}
|
||||||
|
|
||||||
|
int GetTimeSynced(void)
|
||||||
|
{
|
||||||
|
return synced;
|
||||||
|
}
|
||||||
|
|
||||||
|
int GetTimeZoneValue(int i)
|
||||||
|
{
|
||||||
|
return tz[i];
|
||||||
|
}
|
||||||
|
|
||||||
|
void GetTimeZoneName(int i, char * string)
|
||||||
|
{
|
||||||
|
strcpy(string, tzName[i]);
|
||||||
|
}
|
||||||
@@ -0,0 +1,28 @@
|
|||||||
|
#ifndef _RTC_H_
|
||||||
|
#define _RTC_H_
|
||||||
|
|
||||||
|
#include <time.h> // for tm-struct
|
||||||
|
|
||||||
|
tm gmt;
|
||||||
|
int synced;
|
||||||
|
|
||||||
|
extern void GetDateString(char*);
|
||||||
|
extern void GetDateTimeString(char*);
|
||||||
|
extern void GetTimeString(char*);
|
||||||
|
extern tm* GetTimeStruct(void);
|
||||||
|
extern int SyncTime( void );
|
||||||
|
extern int GetTimeSynced( void );
|
||||||
|
|
||||||
|
extern int GetTimeZoneValue(int);
|
||||||
|
extern void GetTimeZoneName(int, char *);
|
||||||
|
|
||||||
|
/* Prototypes */
|
||||||
|
extern int X12Init(void);
|
||||||
|
|
||||||
|
extern int X12RtcGetClock(tm *tm);
|
||||||
|
extern int X12RtcSetClock(CONST tm *tm);
|
||||||
|
extern int X12RtcSyncClock(void);
|
||||||
|
extern int X12RtcWrite(int nv, CONST u_char *buff, size_t len);
|
||||||
|
|
||||||
|
/* End of prototypes */
|
||||||
|
#endif
|
||||||
@@ -0,0 +1,98 @@
|
|||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <io.h>
|
||||||
|
|
||||||
|
#include <dev/debug.h>
|
||||||
|
#include <dev/nicrtl.h>
|
||||||
|
#include <dev/vs1001k.h>
|
||||||
|
|
||||||
|
#include <sys/version.h>
|
||||||
|
#include <sys/confnet.h>
|
||||||
|
#include <sys/heap.h>
|
||||||
|
#include <sys/bankmem.h>
|
||||||
|
#include <sys/thread.h>
|
||||||
|
#include <sys/timer.h>
|
||||||
|
|
||||||
|
#include <dev/board.h>
|
||||||
|
#include <pro/httpd.h>
|
||||||
|
#include <pro/dhcp.h>
|
||||||
|
#include <pro/asp.h>
|
||||||
|
#include <pro/discover.h>
|
||||||
|
#include <dev/nicrtl.h>
|
||||||
|
#include <arpa/inet.h>
|
||||||
|
#include <sys/socket.h>
|
||||||
|
#include <netinet/tcp.h>
|
||||||
|
|
||||||
|
#include <pro/dhcp.h>
|
||||||
|
|
||||||
|
#include "streamer.h"
|
||||||
|
#include "player.h"
|
||||||
|
#include "web.h"
|
||||||
|
|
||||||
|
#define OK 1
|
||||||
|
#define NOK 0
|
||||||
|
/*!
|
||||||
|
* \brief Connect to a radio station.
|
||||||
|
*
|
||||||
|
* \param sock TCP socket for this connection.
|
||||||
|
* \param ip IP address of the server to connect.
|
||||||
|
* \param port Port number of the server to connect.
|
||||||
|
*
|
||||||
|
* \return Stream pointer of the established connection on success.
|
||||||
|
* Otherwise 0 is returned.
|
||||||
|
*/
|
||||||
|
FILE *ConnectStation(TCPSOCKET *sock, u_long ip, u_short port, u_char *path, u_long *metaint){
|
||||||
|
FILE *stream;
|
||||||
|
u_char *line;
|
||||||
|
u_char *cp;
|
||||||
|
|
||||||
|
stream = getStream(sock, ip,port);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Send the HTTP request.
|
||||||
|
*/
|
||||||
|
printf("[STREAMER] GET %s HTTP/1.0\n\n", path);
|
||||||
|
fprintf(stream, "GET %s HTTP/1.0\r\n", path);
|
||||||
|
fprintf(stream, "Host: %s\r\n", inet_ntoa(ip));
|
||||||
|
fprintf(stream, "User-Agent: Ethernut\r\n");
|
||||||
|
fprintf(stream, "Accept: */*\r\n");
|
||||||
|
fprintf(stream, "Icy-MetaData: 1\r\n");
|
||||||
|
fprintf(stream, "Connection: close\r\n");
|
||||||
|
fputs("\r\n", stream);
|
||||||
|
fflush(stream);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Receive the HTTP header.
|
||||||
|
*/
|
||||||
|
line = malloc(MAX_HEADERLINE);
|
||||||
|
while(fgets((char*) line, MAX_HEADERLINE, stream)) {
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Chop off the carriage return at the end of the line. If none
|
||||||
|
* was found, then this line was probably too large for our buffer.
|
||||||
|
*/
|
||||||
|
cp = (u_char *) strchr((char*) line, '\r');
|
||||||
|
if(cp == 0) {
|
||||||
|
printf("[STREAMER] Warning: Input buffer overflow\n");
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
*cp = 0;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* The header is terminated by an empty line.
|
||||||
|
*/
|
||||||
|
if(*line == 0) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if(strncmp((char*) line, "icy-metaint:", 12) == 0) {
|
||||||
|
*metaint = atol( (char*) (line + 12));
|
||||||
|
}
|
||||||
|
printf("[STREAMER] line of metaint: %s\n", line);
|
||||||
|
}
|
||||||
|
putchar('\n');
|
||||||
|
|
||||||
|
free(line);
|
||||||
|
|
||||||
|
return stream;
|
||||||
|
}
|
||||||
@@ -0,0 +1,9 @@
|
|||||||
|
#ifndef STREAMER_INC
|
||||||
|
#define STREAMER_INC
|
||||||
|
|
||||||
|
#define MAX_HEADERLINE 512
|
||||||
|
|
||||||
|
extern FILE *ConnectStation(TCPSOCKET *sock, u_long ip, u_short port, u_char *path, u_long *metaint);
|
||||||
|
|
||||||
|
|
||||||
|
#endif
|
||||||
Reference in New Issue
Block a user