📄 webradio.c
字号:
/*!
* Copyright (C) 2006-2007 by egnite Software GmbH. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the copyright holders nor the names of
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY EGNITE SOFTWARE GMBH AND CONTRIBUTORS
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL EGNITE
* SOFTWARE GMBH OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
* OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
* AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
* THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* For additional information see http://www.ethernut.de/
*/
/*!
* \file webradio.c
* \brief Internet radio main file.
*
* \verbatim
*
* $Log$
*
* \endverbatim
*/
/*
* Limited AT91SAM9260-EK MP3 player sample.
*
* Will sequentially play all MP3 files from an MMC's root directory.
*
* MultiMedia Cards only, no SD Cards (see arch/arm/dev/at91_mmc.c).
* Root directory must contain MP3 files only.
* Hardcoded for 180MHz CPU clock and 44.1kHz sampling rate (also see ./at73dac.c).
*/
#include <cfg/os.h>
#include <cfg/clock.h>
#include <dev/board.h>
#include <dev/st7036.h>
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include <time.h>
#include <fcntl.h>
#include <io.h>
#include <sys/version.h>
#include <sys/confnet.h>
#include <sys/atom.h>
#include <sys/heap.h>
#include <sys/thread.h>
#include <sys/timer.h>
#include <sys/event.h>
#include <sys/socket.h>
#include <hxmp3/mp3dec.h>
#include <netinet/tcp.h>
#include <arpa/inet.h>
#include <net/route.h>
#include <pro/dhcp.h>
#include <pro/sntp.h>
#include <pro/discover.h>
#include "tlv320dac.h"
#include "config.h"
#include "shoutcast.h"
#include "player.h"
#include "httpserv.h"
#include "userif.h"
/*
* Unique MAC address of the Ethernut Board.
*
* Ignored if EEPROM contains a valid configuration.
*/
#define MY_MAC { 0x00, 0x06, 0x98, 0x30, 0x00, 0x35 }
/*
* Unique IP address of the Ethernut Board.
*
* Ignored if DHCP is used.
*/
#define MY_IPADDR "192.168.192.35"
/*
* IP network mask of the Ethernut Board.
*
* Ignored if DHCP is used.
*/
#define MY_IPMASK "255.255.255.0"
/*
* Gateway IP address for the Ethernut Board.
*
* Ignored if DHCP is used.
*/
#define MY_IPGATE "192.168.192.1"
/*
* Wether we should run a discovery responder.
*/
#if defined(AT91SAM9260_EK)
#define USE_DISCOVERY
#endif
/*
* IP address of the host running a time daemon.
*/
#if defined(AT91SAM9260_EK)
//#define MY_TIMED "130.149.17.21"
#endif
/*
* Local timezone, -1 for Central Europe.
*/
#ifndef MY_TZ
#define MY_TZ -1
#endif
RADIOCONTROL radio;
/*
* Query a time server and optionally update the hardware clock.
*/
static int QueryTimeServer(void)
{
int rc = -1;
#ifdef MY_TIMED
int retries = 5;
_timezone = MY_TZ * 60L * 60L;
while (retries--) {
time_t now;
u_long timeserver = inet_addr(MY_TIMED);
/* Query network time service and set the system time. */
printf("Query time from %s...", MY_TIMED);
if(NutSNTPGetTime(×erver, &now) == 0) {
puts("OK");
rc = 0;
stime(&now);
break;
}
else {
puts("failed");
}
}
#endif
return rc;
}
int InitEthernetDevice(void)
{
u_long ip_addr = inet_addr(MY_IPADDR);
u_long ip_mask = inet_addr(MY_IPMASK);
u_long ip_gate = inet_addr(MY_IPGATE);
u_char mac[6] = MY_MAC;
for (;;) {
printf("Register %s...", DEV_ETHER_NAME);
if (NutRegisterDevice(&DEV_ETHER, 0x8300, 5) == 0) {
puts("OK");
break;
}
puts("No Ethernet, retry");
}
printf("Configure %s...", DEV_ETHER_NAME);
if (NutDhcpIfConfig(DEV_ETHER_NAME, 0, 60000) == 0) {
puts("OK");
return 0;
}
printf("initial boot...");
if (NutDhcpIfConfig(DEV_ETHER_NAME, mac, 60000) == 0) {
puts("OK");
return 0;
}
printf("No DHCP...");
NutNetIfConfig(DEV_ETHER_NAME, mac, ip_addr, ip_mask);
/* Without DHCP we had to set the default gateway manually.*/
if(ip_gate) {
printf("hard coded gate...");
NutIpRouteAdd(0, 0, ip_gate, &DEV_ETHER);
}
puts("OK");
return 0;
}
/*!
* \brief Main application routine.
*/
int main(void)
{
u_long baud = 115200;
u_long ipgate;
u_int failcnt = 0;
/*
* Register and open the DBGU device, which we will use for debug
* output via stdout.
*/
NutRegisterDevice(&DEV_DEBUG, 0, 0);
freopen(DEV_DEBUG_NAME, "w", stdout);
_ioctl(_fileno(stdout), UART_SETSPEED, &baud);
/*
* Display some general information.
*/
printf("\n\nSAM Internet Radio %s - Nut/OS %s\n", VERSION, NutVersionString());
printf("%u bytes free\n", (u_int)NutHeapAvailable());
printf("CPU Clock : %lu\n", NutGetCpuClock());
printf("Master Clock: %lu\n", At91GetMasterClock());
/*
* Initialize the user interface, LCD and 3 buttons.
*/
if (NutRegisterDevice(&devSbiLcd, 0, 0)) {
puts("Failed to register LCD");
}
if (UserIfInit("sbilcd")) {
puts("LCD init failure\n");
}
/*
* Initialize the Ethernet device and print our IP setting.
*/
InitEthernetDevice();
printf("IP Addr: %s\n", inet_ntoa(confnet.cdn_ip_addr));
printf("IP Mask: %s\n", inet_ntoa(confnet.cdn_ip_mask));
NutIpRouteQuery(0, &ipgate);
printf("IP Gate: %s\n", inet_ntoa(ipgate));
/*
* Register a discovery responder. This optional feature
* allows to discover all Nut/OS devices in a local network.
*/
#ifdef USE_DISCOVERY
printf("Start Responder...");
if (NutRegisterDiscovery((u_long)-1, 0, DISF_INITAL_ANN)) {
puts("failed");
}
else {
puts("OK");
}
#endif
/*
* Try to get current date and time from an SNTP server.
*/
if (QueryTimeServer() == 0) {
time_t now = time(0);
struct _tm *lot = localtime(&now);
printf("Date: %02u.%02u.%u\n", lot->tm_mday, lot->tm_mon + 1, 1900 + lot->tm_year);
printf("Time: %02u:%02u:%02u\n", lot->tm_hour, lot->tm_min, lot->tm_sec);
#ifdef USE_HTTPSERVER
h_timevalid = 1;
#endif
}
#ifdef USE_HTTPSERVER
HttpServerStart();
#endif
ConfigResetFactory();
/*
* Create all required receiver and player instances.
*/
radio.rc_rip = ReceiverCreate(&rpiShoutcast);
radio.rc_pip = PlayerCreate(&ppiMp3);
/*
* Never ending application loop.
*/
for (;;) {
if (failcnt > 3) {
printf("Too many failures. Select next station.\n");
radio.rc_rstation = StationSelect(radio.rc_cstation, 1);
failcnt = 0;
}
radio.rc_cstation = radio.rc_rstation;
printf("Trying station entry %u\n", radio.rc_cstation);
/*
* Connect station.
*/
UserIfShowStatus(DIST_CONNECTING);
radio.rc_sip = StationConnect(&station[radio.rc_cstation]);
if (radio.rc_sip == NULL) {
/* Connection failed. */
UserIfShowStatus(DIST_DEAD);
NutSleep(1000);
radio.rc_rstation = StationSelect(radio.rc_cstation, 0);
failcnt++;
continue;
}
/*
* Station connected.
*/
printf("Connected: %u bytes free\n", (u_int)NutHeapAvailable());
if (ReceiverStart(radio.rc_rip, radio.rc_sip) == 0) {
UserIfShowStatus(DIST_CONNECTED);
if (radio.rc_sip->si_ptype == PLAYER_TYPE_MP3) {
if (PlayerStart(radio.rc_pip, radio.rc_rip) == 0) {
failcnt = 0;
NutSleep(1000);
while (radio.rc_cstation == radio.rc_rstation) {
if (PlayerStatus(radio.rc_pip) != PSTAT_RUNNING) {
radio.rc_rstation = StationSelect(radio.rc_cstation, 0);
failcnt++;
break;
}
NutSleep(1000);
}
printf("\nStop player ");
PlayerStop(radio.rc_pip);
}
else {
radio.rc_rstation = StationSelect(radio.rc_cstation, 0);
failcnt++;
}
}
else {
printf("Bad content type\n");
radio.rc_rstation = StationSelect(radio.rc_cstation, 0);
failcnt++;
}
printf("\nStop receiver ");
ReceiverStop(radio.rc_rip);
}
else {
radio.rc_rstation = StationSelect(radio.rc_cstation, 0);
failcnt++;
}
printf("\nDisconnect station ");
StationDisconnect(radio.rc_sip);
radio.rc_sip = NULL;
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -