/* SliMP3 emulator - an emulator for the SliMP3 network MP3 player. Copyright (C) 2001 Jacob Potter This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. Some of the networking code is based on Kien Pham's UDP example program. */ #include #include #include #include #include #include #include #include #include #include "parsemessage.h" #include "infared.h" #include "chunkreq.h" /* You will *need* to change these three #defines for your setup! */ #define MY_BROADCAST_ADDR "10.44.44.255" /* For use with SlimDP */ #define MY_SERVER_ADDR "10.44.44.10" /* For use without SlimDP */ #define USE_SLIMDP 1 #define PORT1 1069 #define EMU_VERSION 0x11 #define EMU_DEVTYPE 1 int server_sock, stream_status, sf; struct sockaddr_in server_address; int get_packet_flag, ip_lock; pthread_t stream_thread; int create_UDP_socket(int port) { /* this function is straight from the UDP example code. */ int file_descriptor; struct sockaddr_in host_address; file_descriptor=socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP); if (file_descriptor < 0) { perror("socket()"); return -1; } memset((void*)&host_address, 0, sizeof(host_address)); host_address.sin_family=AF_INET; host_address.sin_addr.s_addr=INADDR_ANY; host_address.sin_port=htons(port); if (bind(file_descriptor, (struct sockaddr*)&host_address, sizeof(host_address))<0) { perror("bind()"); return -1; } return file_descriptor; } void d_or_h(char c) { char dp[4]; dp[0] = c; dp[1] = EMU_DEVTYPE; dp[2] = EMU_VERSION; dp[3] = 0; if (sendto(server_sock, dp, sizeof(dp), 0, (struct sockaddr*)&server_address, sizeof(server_address))<0) { perror("sendto() in d_or_h():"); return; } } void s_broadcast(int v) { if (setsockopt(server_sock,SOL_SOCKET,SO_BROADCAST,&v,sizeof(v)) < 0) { if(v) perror("Couldn't setsockopt() SO_BROADCAST"); else perror("Couldn't un-setsockopt() SO_BROADCAST"); } } void get_codes() { char buffer[2048]; int server_address_size, l; unsigned char *address_holder; address_holder=(unsigned char*)&server_address.sin_addr.s_addr; server_address_size=sizeof(server_address); if (ip_lock) l=recvfrom(server_sock, buffer, 2047, 0, 0, 0); else l=recvfrom(server_sock, buffer, 2047, 0, (struct sockaddr*)&server_address, &server_address_size); if (l < 0) { perror("recvfrom()"); return; } switch(buffer[0]) { case 'D': printf("Discovered!\n"); if (!ip_lock) break; if ((buffer[2] + buffer[3] + buffer[4] + buffer[5]) != 0) { address_holder[0] = buffer[2]; address_holder[1] = buffer[3]; address_holder[2] = buffer[4]; address_holder[3] = buffer[5]; } s_broadcast(0); printf("Discovered!\n"); break; case 'd': /* Ignore - a side effect of sending the 'd' packet to the broadcast address. */ break; case 'h': if (!ip_lock) break; d_or_h('h'); break; case 'l': parseMessage(buffer+18, l-18); break; case 's': if (!ip_lock) break; if (buffer[1] & 1) { printf("Recieved 'start' control code.\n"); stream_status = start_stream(server_sock, &server_address); } if (buffer[1] & 2) { printf("Recieved 'pause' control code.\n"); stream_status = stop_stream(); } if (buffer[1] & 4) { printf("Recieved 'resume' control code.\n"); stream_status = stop_stream(); } break; case 'm': write(sf, buffer+18, l-18); if (!ip_lock) break; if (stream_status) get_next_chunk(); break; case '2': printf("Got %d bytes of I2C data.\n", l-18); break; default: printf("Got %d-byte packet of unknown type \'%c\'.\n", l, buffer[0]); } } void *display_loop(void *foo) { stream_status = 0; while(!0) { get_codes(); } } int main(int number_of_arguments, char *arguments[]) { long thecount; unsigned char *address_holder; pthread_t t1; printf("SliMP3 emulator v0.1 by Jacob Potter, emulating SliMP3 firmware v1.0.\n"); printf("Networking code based on the UDP example program by Kien Pham.\n\n"); server_sock=create_UDP_socket(1069); memset((void*)&server_address, 0, sizeof(server_address)); server_address.sin_family=AF_INET; server_address.sin_port=htons(PORT1); address_holder=(unsigned char*)&server_address.sin_addr.s_addr; if (USE_SLIMDP) { ip_lock = 0; inet_aton(MY_BROADCAST_ADDR, &server_address.sin_addr); s_broadcast(1); printf("Waiting for discovery responce...\n"); } else { inet_aton(MY_SERVER_ADDR, &server_address.sin_addr); } thecount = 0; initDisplay(); pthread_create(&t1, 0, display_loop, (void *)0); if (!ip_lock) d_or_h('d'); do_ir_loop(server_sock, &server_address); printf("Returned from IR code loop\n"); sleep(0); close(server_sock); exit(0); }