/* udp_send.c
 * UDP Babyphone Sender (Mikrophon)
 * Andre Adrian
 */

#include "udp_common.h"

int main(int argc, char *argv[])
{
  struct sockaddr_in remote;  // UDP Empfaenger IPv4 Adress und Port Struktur
  int remotefd;               // UDP Empfaenger Filedeskriptor
  struct hostent *he;
  int rv;
  int yes = 1;
  
  int fd, i;
  int level;
  int len;
  char buffer[BUFSIZE];
 
  if (argc != 2) {
    fprintf(stderr, "usage: udp_send hostname\n");
    exit(1);
  }

  he = gethostbyname(argv[1]);  // hole UDP Empfaenger IPv4 Adresse
  exit_if(NULL == he);

  remotefd = socket(AF_INET, SOCK_DGRAM, 0); // Socket Filedeskriptor anlegen
  exit_if(remotefd < 0);
  
  // UDP Broadcast erlauben
  rv = setsockopt(remotefd, SOL_SOCKET, SO_BROADCAST, &yes, sizeof(yes));
  exit_if(rv < 0);
  
  memset(&remote, 0, sizeof(remote)); // remote mit 0 fuellen
  remote.sin_family = AF_INET;
  remote.sin_port = htons(BABYPHONE_PORT);
  remote.sin_addr = *((struct in_addr *) he->h_addr);
  
  
  fd = open("/dev/dsp", O_RDONLY);          // Soundcard oeffnen
  exit_if(fd < 0);
  
  // Anzahl und Groesse der Audio-Buffers im Soundcard Treiber setzen
  i = AUDIOBUFS << 16 | BUFSIZELD;
  rv = ioctl(fd, SNDCTL_DSP_SETFRAGMENT, &i);
  exit_if(rv < 0);
  
  i = AUDIOFORMAT;                          // Audio Codec (Format) setzen
  rv = ioctl(fd, SNDCTL_DSP_SETFMT, &i);
  exit_if(rv < 0);
  
  i = AUDIOCHANNELS;                        // Mono oder Stereo setzen
  rv = ioctl(fd, SNDCTL_DSP_CHANNELS, &i);
  exit_if(rv < 0);

  i = AUDIOSPEED;                           // Abtastfrequenz setzen     
  rv = ioctl(fd, SNDCTL_DSP_SPEED, &i);
  exit_if(rv < 0);

  // Aufnahme (Capture) einschalten
  rv = ioctl(fd, MIXER_READ(SOUND_MIXER_IGAIN), &i);
  exit_if(rv < 0);
  
  if (0 == i) {           // i == 0 bedeutet keine Aufnahme (Capture)    
    i = 1 + (1 << 8);
    rv = ioctl(fd, MIXER_WRITE(SOUND_MIXER_IGAIN), &i);
    exit_if(rv < 0);
  }
  
  for (;;) {                                // Endlosschleife
    len = read(fd, buffer, sizeof(buffer)); // Audio holen
    exit_if(len < 0);
    
    rv = sendto(remotefd, buffer, len, 0, 
                (struct sockaddr *) &remote, sizeof(remote));
    exit_if(rv != len);
  }

  // hierhin kommt das Programm garnicht..
  close(fd);      
  close(remotefd);

  return 0;
}
