char TWI_SendAddress ( char Address, char TWI_RW ) { char twst; int timer; TWCR = (1<<TWINT)|(1<<TWSTA)|(1<<TWEN); timer = CLOCK_RegisterCoundowntimer(); if( timer == CLOCK_FAILED ) return FALSE; CLOCK_SetCountdownTimer( timer , TWITIMEOUT, MSECOUND ); while (!(TWCR & (1<<TWINT))) { if ( CLOCK_GetCountdownTimer( timer ) == 0 ) { CLOCK_ReleaseCountdownTimer( timer ); return FALSE; } } CLOCK_ReleaseCountdownTimer( timer ); twst = TWSR & 0xF8; if ((twst != TWI_START) && (twst != TWI_REP_START)) return FALSE; TWDR = (Address<<1) + TWI_RW; TWCR = (1<<TWINT)|(1<<TWEN); timer = CLOCK_RegisterCoundowntimer(); if( timer == CLOCK_FAILED ) return FALSE; CLOCK_SetCountdownTimer( timer , TWITIMEOUT, MSECOUND ); while (!(TWCR & (1<<TWINT))) { if ( CLOCK_GetCountdownTimer( timer ) == 0 ) { CLOCK_ReleaseCountdownTimer( timer ); return FALSE; } } CLOCK_ReleaseCountdownTimer( timer ); twst = TWSR & 0xF8; if ((twst != TWI_MTX_ADR_ACK) && (twst != TWI_MRX_ADR_ACK)) return FALSE; return TRUE; }
void TWI_SendStart(void) { int timer; TWCR = (1<<TWINT)|(1<<TWSTA)|(1<<TWEN); //make start timer = CLOCK_RegisterCoundowntimer(); if( timer == CLOCK_FAILED ) return; CLOCK_SetCountdownTimer( timer , TWITIMEOUT, MSECOUND ); while (!(TWCR & (1<<TWINT))) { if ( CLOCK_GetCountdownTimer( timer ) == 0 ) { CLOCK_ReleaseCountdownTimer( timer ); return; } } CLOCK_ReleaseCountdownTimer( timer ); if (( TWSR != TWI_START) && ( TWSR != TWI_REP_START)) return; return; }
char TWI_Write ( char Data ) { int timer; char twst; TWDR = Data; TWCR = (1<<TWINT)|(1<<TWEN); timer = CLOCK_RegisterCoundowntimer(); if( timer == CLOCK_FAILED ) return FALSE; CLOCK_SetCountdownTimer( timer , TWITIMEOUT, MSECOUND ); while (!(TWCR & (1<<TWINT))) { if ( CLOCK_GetCountdownTimer( timer ) == 0 ) { CLOCK_ReleaseCountdownTimer( timer ); return FALSE; } } CLOCK_ReleaseCountdownTimer( timer ); twst = TWSR & 0xF8; if (twst != TWI_MTX_DATA_ACK) return 1; return 0; }
void TWI_SendStop ( void ) { int timer; TWCR = (1<<TWINT)|(1<<TWEN)|(1<<TWSTO); timer = CLOCK_RegisterCoundowntimer(); if( timer == CLOCK_FAILED ) return; CLOCK_SetCountdownTimer( timer , TWITIMEOUT, MSECOUND ); while (!(TWCR & (1<<TWINT))) { if ( CLOCK_GetCountdownTimer( timer ) == 0 ) { CLOCK_ReleaseCountdownTimer( timer ); return; } } CLOCK_ReleaseCountdownTimer( timer ); }
char TWI_ReadNack ( void ) { int timer; TWCR = (1<<TWINT)|(1<<TWEN); timer = CLOCK_RegisterCoundowntimer(); if( timer == CLOCK_FAILED ) return FALSE; CLOCK_SetCountdownTimer( timer , TWITIMEOUT, MSECOUND ); while (!(TWCR & (1<<TWINT))) { if ( CLOCK_GetCountdownTimer( timer ) == 0 ) { CLOCK_ReleaseCountdownTimer( timer ); return FALSE; } } CLOCK_ReleaseCountdownTimer( timer ); return TWDR; }
/*------------------------------------------------------------------------------------------------------------*/ unsigned int NTP_GetTime( unsigned long IP, char * dnsbuffer, char timedif ) { char buffer[ NTP_SIZE ]; int i=0, socket, timer, retval = NTP_ERROR; #if defined(NTP_DEBUG) char String[30]; #endif union DATE ZeitInSek; struct TIME time; #if defined(NTP_DEBUG) printf_P( PSTR("Oeffne neues Socket.\r\n") ); #endif if ( IP == 0 ) { #ifdef UDP #ifdef DNS if ( dnsbuffer != 0 ) { // Host nach IP auflösen IP = DNS_ResolveName( dnsbuffer ); // könnte er aufgelöst werden ? if ( IP == DNS_NO_ANSWER ) return( NTP_ERROR ); } else #endif #endif return( NTP_ERROR ); } // UDP-socket aufmachen für Bootp socket = UDP_RegisterSocket( IP , 37 , NTP_SIZE , buffer); // Wenn Fehler aufgetretten, return if ( socket == UDP_SOCKET_ERROR ) { return ( NTP_ERROR ); } #if defined(NTP_DEBUG) printf_P( PSTR("UDP-Socket aufgemacht zur %s.\r\n"), iptostr( IP, String ) ); #endif // leeres UDP-Packet an Time-server senden UDP_SendPacket( socket, 0 , buffer); #if defined(NTP_DEBUG) printf_P( PSTR("UDP-Packet gesendet.\r\n")); #endif // Timeout-counter reservieren und starten timer = CLOCK_RegisterCountdowntimer(); if ( timer == CLOCK_FAILED ) return ( NTP_ERROR ); CLOCK_SetCountdownTimer( timer , 500, MSECOUND ); #if defined(NTP_DEBUG) printf_P( PSTR("Warte auf Antwort.")); #endif // Auf Antwort des Timer-Servers warten while( 1 ) { // Wenn Time-Server geantwortet hat inerhalb des Timeouts, hier weiter if ( UDP_GetSocketState( socket ) == UDP_SOCKET_BUSY && ( CLOCK_GetCountdownTimer( timer ) != 0 ) ) { // Sind 4 Bytes empfangen worden, wenn ja okay, sonst fehler if ( UDP_GetByteInBuffer( socket ) >= 4 ) { // Daten kopieren und Zeit ausrechnen for ( i = 0 ; i < 4 ; i++ ) ZeitInSek.DateByte[ i ] = buffer[ 3 - i ]; CLOCK_GetTime( &time ); time.time = ZeitInSek.Date; time.timezone = timedif; CLOCK_decode_time( &time ); CLOCK_SetTime( &time ); retval = NTP_OK; #if defined(NTP_DEBUG) printf_P( PSTR("Antwort erhalten.\r\n")); #endif // fertisch break; } else { #if defined(NTP_DEBUG) printf_P( PSTR("Falsches Format der Antwort.\r\n")); #endif retval = NTP_ERROR; break; } } // Timeout erreicht ? Wenn ja Fehler. if ( CLOCK_GetCountdownTimer( timer ) == 0 ) { #if defined(NTP_DEBUG) printf_P( PSTR("Timeout beun warten auf Antwort.\r\n")); #endif retval = NTP_ERROR; break; } } // timer freigeben und UDP-Socket schliessen CLOCK_ReleaseCountdownTimer( timer ); UDP_CloseSocket( socket ); #if defined(NTP_DEBUG) printf_P( PSTR("UDP-Socket geschlossen.\r\n")); #endif return( retval ); }
/*------------------------------------------------------------------------------------------------------------*/ void mp3client_startstreaming( unsigned char * streamingPROTO, unsigned char * streamingURL, unsigned long streamingIP, unsigned int streamingPORT, unsigned char * streamingFILE, unsigned int socket ) { unsigned int TEMP_MP3_SOCKET = NO_SOCKET_USED; int REQUESTCODE; STDOUT_Set_TCP_Socket ( socket ); // mindestens IP und PORT gesetzt ? if ( streamingIP == 0 || streamingPORT == 0 ) return( 0 ); // schon ein stream offen ? Wenn ja killen if ( MP3_SOCKET != NO_SOCKET_USED ) { printf_P( PSTR("Highjack current stream and kill them on Socket %d\r\n"), MP3_SOCKET ); mp3client_stopstreaming ( ); } printf_P( PSTR("Connect to %s"), streamingURL ); // neue Verbindung auf machen TEMP_MP3_SOCKET = Connect2IP( streamingIP , streamingPORT ); // neue Verbindung geöffnet ? if ( TEMP_MP3_SOCKET != NO_SOCKET_USED ) { printf_P( PSTR(" connected ;-D\r\n"), streamingURL ); } else { printf_P( PSTR(" fail to connect ;-(\r\n"), streamingURL ); } STDOUT_Flush(); // Wenn Verbindung geöffnet, weiter weiter :-) if ( TEMP_MP3_SOCKET != NO_SOCKET_USED ) { STDOUT_Set_TCP_Socket ( TEMP_MP3_SOCKET ); // Request senden printf_P( PSTR("GET /%s HTTP/1.1\r\n" \ "Host: %s\r\n" \ "User-Agent: mp3-streamingclient v0.1a (ccc-berlin)\r\n" \ "Icy-MetaData: %d\r\n" \ "Keep-Alive: \r\n" \ "Connection: TE, Keep-Alive\r\n" \ "TE: trailers\r\n\r\n" ), streamingFILE , streamingFILE , metainfo ); STDOUT_Set_TCP_Socket ( socket ); printf_P( PSTR("Request on TCP-Socket %d\r\n"), TEMP_MP3_SOCKET ); // Stream setzen MP3_SOCKET = TEMP_MP3_SOCKET; // Lautstärke sichern timer0_stop(); vol = VS10xx_read( VS10xx_Register_VOL ); // VS10xx reseten VS10xx_reset( SOFT_RESET ); // gesicherte Lautstärke setzen VS10xx_write( VS10xx_Register_VOL, vol ); printf_P( PSTR("MP3 buffering ( FIFO = %d with %dBytes )\r\n"), MP3_FIFO, mp3_buffer_size ); // Timeout für pufferauffüllen setzen CLOCK_SetCountdownTimer ( mp3timer, 1000, MSECOUND ); // alten MP3-Puffer löschen Flush_FIFO ( MP3_FIFO ); STDOUT_Flush(); STDOUT_Set_RS232 (); REQUESTCODE = mp3client_pharseheader( MP3_SOCKET ); STDOUT_Set_TCP_Socket ( socket ); if ( REQUESTCODE != 200 ) { switch ( REQUESTCODE ) { case -1: printf_P( PSTR("Timeout:") ); break; case 400: printf_P( PSTR("Requestcode: %d Bad Request:"), REQUESTCODE ); break; case 401: printf_P( PSTR("Requestcode: %d Unauthorized:"), REQUESTCODE ); break; case 403: printf_P( PSTR("Requestcode: %d Forbidden:"), REQUESTCODE ); break; case 404: printf_P( PSTR("Requestcode: %d Not Found:"), REQUESTCODE ); break; case 405: printf_P( PSTR("Requestcode: %d Method Not Allowed:"), REQUESTCODE ); break; case 500: printf_P( PSTR("Requestcode: %d Internal Server Error:"), REQUESTCODE ); break; default: printf_P( PSTR("Requestcode: %d Unknow:"), REQUESTCODE ); break; } printf_P( PSTR("Stream failed\r\n") ); STDOUT_Flush(); MP3_SOCKET = NO_SOCKET_USED; return; } // wenn alles schick mit dem stream dann: printf_P( PSTR("Requestcode: %d - Stream okay, Tsunami can highjack them totaly\r\n"), REQUESTCODE ); metaintcounter = 0; slowstart = 1; // Counter setzen für die statsupdates CLOCK_SetCountdownTimer ( mp3timer, 50, MSECOUND ); } STDOUT_Flush(); }
/*------------------------------------------------------------------------------------------------------------*/ void mp3client_thread( void ) { #define bandwidthhis 16 unsigned char i; static unsigned long totalbytesold[bandwidthhis],bandwidth; static unsigned char y; static unsigned int temp; timer0_stop(); STDOUT_Set_RS232 (); if ( MP3_SOCKET == NO_SOCKET_USED ) { // keine Verbindung offen? Trafficcounter zurücksetzen y=0; metaintcounter=0; slowstart = 1; } else { // Verbindung wirklich noch offen if( CheckSocketState( MP3_SOCKET ) == SOCKET_NOT_USE ) { CloseTCPSocket( MP3_SOCKET ); MP3_SOCKET = NO_SOCKET_USED; } else { // Wenn Puffer auf unter 1/8 gelaufen ist slowstart setzen if ( Get_Bytes_in_FIFO ( MP3_FIFO ) < mp3_buffer_size / 8 ) slowstart = 1; /* // Datenpuffer auffrischen mit neuen daten von TCP-Verbindung while ( GetBytesInSocketData( MP3_SOCKET ) >= MP3TCPtranslen && Get_FIFOrestsize ( MP3_FIFO ) > MP3TCPtranslen && metainfolen == 0 ) { // Wenn die transferlänge zum nächsten Metaint kleiner als translen zwischen tcp und mp3 buffer ist, nur diese // kopieren damit danach der metaint eingelesen werden kann if ( metaint - ( metaintcounter%metaint ) < MP3TCPtranslen && metaint != 0) { LED_on(1); temp = GetSocketDataToFIFO ( MP3_SOCKET, MP3_FIFO, metaint - ( metaintcounter%metaint ) ); totalbytes = totalbytes + temp; metaintcounter = metaintcounter + temp; LED_off(1); } else { LED_on(1); temp = GetSocketDataToFIFO ( MP3_SOCKET, MP3_FIFO, MP3TCPtranslen ); totalbytes = totalbytes + temp; metaintcounter = metaintcounter + temp; LED_off(1); } if ( metaintcounter%metaint == 0 && metaint != 0 ) { // checkt und wartet ob mehr als 1 Byte im Puffer ist while ( GetBytesInSocketData( MP3_SOCKET ) <= 0 ); // lese Byte und errechne die metalänge metainfolen = GetByteFromSocketData ( MP3_SOCKET ) * 16 ; break; } } */ // Wenn der metaintcounter auf einen metaint steht, den metaint lesen und ausgeben if ( metainfolen != 0 ) { mp3client_readmetainfo( MP3_SOCKET, metainfolen ); metainfolen = 0; } // Counter schon bei 0, wenn ja stats updaten if ( CLOCK_GetCountdownTimer ( mp3timer ) == 0 ) { bandwidth = 0; // traffic aufaddieren for ( i = 0 ; i < bandwidthhis ; i++) bandwidth = bandwidth + totalbytesold[ i ]; // bandwidth berechnen alle 0,5 sekunden bandwidth = ( bandwidth / bandwidthhis ) * 2; // stats sichern mp3clientupdate( bandwidth, GetBytesInSocketData( MP3_SOCKET ) , Get_Bytes_in_FIFO ( MP3_FIFO ), VS10xx_get_decodetime( ), verboselevel ); // wenn verboselevel gesetzt ausgeben if ( verboselevel != 0) printf_P( PSTR("\r%5d(TCP %4d)Bytes on FIFO, bandwidth:%3ldkbit/s(%2dkb/s)"), Get_Bytes_in_FIFO ( MP3_FIFO ), GetBytesInSocketData( MP3_SOCKET ), ( bandwidth * 8 ) / 1024, ( bandwidth * 8 ) / 8192 ); // zähler für bandwidth zurücksetzten if ( y < bandwidthhis ) { totalbytesold[y] = totalbytes; } else { y = 0; totalbytesold[y] = totalbytes; } y++; totalbytes = 0; // Counter neu starten 0,5 Sekunden CLOCK_SetCountdownTimer ( mp3timer, 47, MSECOUND ); } } } timer0_free(); return; }
/* Download CEPT-Hypertext Page from Ulm */ int applicationBtxHttpGet(char *url, unsigned long ulmIp ,char *data, int *status) { volatile unsigned int httpServerSocket = NO_SOCKET_USED; char dataByte; char *dataPointer = data; unsigned char timeoutTimerHandle; int dataCount = 0; /* Counter to prevent buffer overflows */ /* Pass 1: Establish server connection */ httpServerSocket = Connect2IP(ulmIp,BTX_ULM_PORT); /* Connect http-server (Ulm) */ if(httpServerSocket == NO_SOCKET_USED) return -1; /* Connection failed */ /* Pass 2: Perform HTTP-Request */ STDOUT_Set_TCP_Socket(httpServerSocket); printf_P(PSTR("GET %s HTTP/1.0\r\nHost: " BTX_ULM_HOST "\r\n\r\n"),url); STDOUT_Flush(); if(httpServerSocket == NO_SOCKET_USED) return -1; /* Connection closed unexpectetly */ timeoutTimerHandle = CLOCK_RegisterCoundowntimer(); /* Register timer */ while(GetBytesInSocketData(httpServerSocket) == 0); /* Trigger on incoming data */ while(GetBytesInSocketData(httpServerSocket) > 0) { dataByte = GetByteFromSocketData(httpServerSocket); if(dataCount < BTX_CEPT_HYPERTEXT_BUFFERSIZE-1) { *dataPointer = dataByte; dataPointer++; dataCount++; } /* Handle connection timeout (3 retrys) */ if(GetBytesInSocketData(httpServerSocket) == 0) { CLOCK_SetCountdownTimer (timeoutTimerHandle, 8, MSECOUND ); while(CLOCK_GetCountdownTimer(timeoutTimerHandle) > 0); if(GetBytesInSocketData(httpServerSocket) == 0) { CLOCK_SetCountdownTimer (timeoutTimerHandle, 16, MSECOUND ); while(CLOCK_GetCountdownTimer(timeoutTimerHandle) > 0); if(GetBytesInSocketData(httpServerSocket) == 0) { CLOCK_SetCountdownTimer (timeoutTimerHandle, 32, MSECOUND ); while(CLOCK_GetCountdownTimer(timeoutTimerHandle) > 0); if(GetBytesInSocketData(httpServerSocket) == 0) break; } } } } CLOCK_ReleaseCountdownTimer(timeoutTimerHandle); /* Free timer */ *dataPointer = '\0'; /* Add a 0 to make the string functions happy */ *status = atoi(&data[8]); /* Calculate status code */ CloseTCPSocket (httpServerSocket); /* Close connection */ STDOUT_Set_RS232(); /* Set STDOUT to console */ return 0; }
/*! \brief Holt von einen Hostname die IP-Adressen * \warning Es ist drauf zu achten das genug Speicher vorgesehen ist fuer die Anworten und das auch Packete mit entsprechender groesse * vom Ethernetmodul empfagen werden koennen und nicht verworfen werden. Siehe MAX_FRAMELEN in enc28j60.h . * \param HOSTNAME Zeiger auf den Hostnamestring der mit 0 teminiert ist. * \retval IP Die IP des Hostname, wenn IP = DNS_NO_ANSWER ist war die Anfrage nicht erfolgreich. Es sollte der DNSserver Eintrag ueberprueft werden * oder die richtigkeit des Hostname. */ unsigned long DNS_ResolveName( char * HOSTNAME ) { int i,UDP_socket; int timer; // udp-puffer anlegen unsigned char * udpbuffer; udpbuffer = (unsigned char*) __builtin_alloca (( size_t ) DNS_BUFFER_LENGHT ); // DNS-struct in udp-puffer anlegen struct DNS_header * DNS_question; DNS_question = ( struct DNS_header *) udpbuffer; // DNS anfrage bauen DNS_question->TransactionID = 0x1acd; DNS_question->Flags = ChangeEndian16bit( 0x0100 ); DNS_question->Questions = ChangeEndian16bit( 1 ); DNS_question->Answer_RRs = 0; DNS_question->Authority_RRs = 0; DNS_question->Additional_RRs = 0; // Hostename für DNS umwandeln, in i steht die länge des neuen strings i = DNS_convertHostName( HOSTNAME, DNS_question->Queries ); DNS_question->Queries[i + 1] = '\0'; DNS_question->Queries[i + 2] = 1; DNS_question->Queries[i + 3] = '\0'; DNS_question->Queries[i + 4] = 1; i = i + 5; // Antwortstruct anlegen struct DNS_answer * DNS_ans; DNS_ans = ( void * ) &DNS_question->Queries[i]; // UDP-Paccket senden UDP_socket = UDP_RegisterSocket( DNSserver , DNS_SERVER_PORT, DNS_BUFFER_LENGHT , udpbuffer); if ( UDP_socket == UDP_SOCKET_ERROR ) return( DNS_NO_ANSWER ); UDP_SendPacket( UDP_socket, DNS_HEADER_LENGHT + i , udpbuffer); // empfang des der DNS-Atwort abwarten timer = CLOCK_RegisterCoundowntimer(); if ( timer == CLOCK_FAILED ) return ( DNS_NO_ANSWER ); CLOCK_SetCountdownTimer ( timer, DNS_REQUEST_TIMEOUT, MSECOUND ); while ( 1 ) { if ( UDP_GetSocketState( UDP_socket ) == UDP_SOCKET_BUSY ) { CLOCK_ReleaseCountdownTimer( timer ); UDP_CloseSocket( UDP_socket ); if ( ( ChangeEndian16bit( DNS_question->Flags ) & 0x000f ) != 0 ) return ( DNS_NO_ANSWER ); break; } if ( CLOCK_GetCountdownTimer( timer ) == 0 ) { CLOCK_ReleaseCountdownTimer( timer ); UDP_CloseSocket( UDP_socket ); return( DNS_NO_ANSWER ); } } // Antwortpacket auseinander nehmen while ( 1 ) { // Wenn noch nicht der Hosteintrag dann nächsten DNS-Answer Datensatz if ( ChangeEndian16bit( DNS_ans->Type ) != A_HOSTNAME ) { i = i + ChangeEndian16bit( DNS_ans->Datalenght ) + DNS_ANSWER_HEADER_LENGHT; DNS_ans = ( void * ) &DNS_question->Queries[i]; } else break; } return( DNS_ans->Adress ); }