client.c 1.9 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889
  1. #include <stdio.h>
  2. #include <signal.h>
  3. #include <string.h>
  4. #include <fcntl.h>
  5. #include <sys/time.h>
  6. #include <sys/socket.h>
  7. #include <netinet/in.h>
  8. #include <linux/kd.h>
  9. #define CLK_FREQ 1193180
  10. int term;
  11. enum cmd_t {CMD_KA, CMD_PING, CMD_QUIT, CMD_PLAY};
  12. struct cmd_buffer {
  13. int cmd;
  14. int data[8];
  15. };
  16. void sigalrm(int sig) {
  17. ioctl(term, KIOCSOUND, 0);
  18. }
  19. int main(int argc, char **argv) {
  20. struct sockaddr_in addr, remote;
  21. int sock, rlen = sizeof(remote), i;
  22. struct itimerval tmr;
  23. struct cmd_buffer cmd;
  24. struct sigaction sa;
  25. if((term = open("/dev/console", O_WRONLY)) < 0) {
  26. perror("open");
  27. return 1;
  28. }
  29. if((sock = socket(AF_INET, SOCK_DGRAM, 0)) < 0) {
  30. perror("socket");
  31. return 1;
  32. }
  33. memset(&addr, 0, sizeof(addr));
  34. addr.sin_family = AF_INET;
  35. addr.sin_addr.s_addr = htonl(INADDR_ANY);
  36. addr.sin_port = htons(13676);
  37. if((bind(sock, (struct sockaddr *) &addr, sizeof(addr))) < 0) {
  38. perror("bind");
  39. return 1;
  40. }
  41. sa.sa_handler = sigalrm;
  42. sa.sa_flags = SA_NODEFER | SA_RESTART;
  43. sigemptyset(&sa.sa_mask);
  44. sigaction(SIGALRM, &sa, NULL);
  45. printf("Ready to begin (listening on 13676)\n");
  46. memset(&tmr, 0, sizeof(tmr));
  47. while(1) {
  48. if(recvfrom(sock, &cmd, sizeof(cmd), 0, (struct sockaddr *) &remote, &rlen) < 0) {
  49. perror("recvfrom");
  50. return 1;
  51. }
  52. cmd.cmd = ntohl(cmd.cmd);
  53. for(i = 0; i < 8; i++) cmd.data[i] = ntohl(cmd.data[i]);
  54. /* printf("From %s:%d, cmd %d\n", inet_ntoa(remote.sin_addr.s_addr), remote.sin_port, cmd.cmd); */
  55. switch((enum cmd_t) cmd.cmd) {
  56. case CMD_QUIT:
  57. return 0;
  58. break;
  59. case CMD_PING:
  60. sendto(sock, &cmd, sizeof(cmd), 0, (struct sockaddr *) &remote, rlen);
  61. break;
  62. case CMD_PLAY:
  63. tmr.it_value.tv_sec = cmd.data[0];
  64. tmr.it_value.tv_usec = cmd.data[1];
  65. setitimer(ITIMER_REAL, &tmr, NULL);
  66. ioctl(term, KIOCSOUND, (int) (CLK_FREQ / cmd.data[2]));
  67. default:
  68. printf("WARNING: Unknown cmd %d\n", cmd.cmd);
  69. case CMD_KA:
  70. break;
  71. }
  72. }
  73. }