Newer
Older
rtmp / rtmp.c
@reddawg reddawg on 16 May 2007 6 KB Sync
/*
RTMP Server
*/

#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <fcntl.h>
#include <unistd.h>
#include <string.h>

#include "rtmp.h"

amfHeader_real *AMFS = 0x0;

int getAMF(int);
int doProcessPacket(int,int);
int doAmfFunction(int fd,int amfID,int packetSize);


int main(void) {
  int newFD  = 0x0; //New Socket;
  //socklen_t sin_size;
  //struct sockaddr_in remoteAddr; // connector's address information

  AMFS = (amfHeader_real *)malloc(sizeof(amfHeader_real) * 128);

  sStartListener();

  while(1) {  // main accept() loop
    while (1);
/*
    sin_size = sizeof(struct sockaddr_in);
    if ((newFD = accept(listenerFD, (struct sockaddr *)&remoteAddr, &sin_size)) == -1) {
      perror("accept");
      continue;
      }
    fcntl(newFD, F_SETFL, fcntl(newFD, F_GETFL, 0) | O_NONBLOCK);
    printf("server: got connection from %s\n",inet_ntoa(remoteAddr.sin_addr));
    if (doHandshake(newFD) != 0) {
      close(newFD);
      exit(0);
      }
*/
    while (1) {
      if (getAMF(newFD) != 0x0) {
        printf("Error");
        close(newFD);
        exit(0);
        } 
      }
    close(newFD);  // parent doesn't need this
    }
  return 0;
  }

int getAMF(int fd) {
  int AMF;
  int recLen     = 0x0;
  int amfID      = 0x0;
  int headerSize = 0x0;
  int packetSize = 0x0;
  char data[12];
  amfHeader *amfHdr = (amfHeader *)&data;
  fd_set readset;

  FD_ZERO(&readset);
  FD_SET(fd,&readset);


  while (select(fd + 1,&readset,0x0,0x0,0x0)) {
    if (FD_ISSET(fd,&readset))
      break;
    }

  recLen = recv(fd,&AMF,1,0);
  if (recLen != 1)
    return(-1);

  headerSize = (AMF & 0xC0) >> 6;
  amfID      = (AMF & 0x3F); 

  switch(headerSize) {
    case 0:
      while (select(fd + 1,&readset,0x0,0x0,0x0)) {
        if (FD_ISSET(fd,&readset))
          break;
        }

      recLen = recv(fd,&data,11,0);
      printf("12 Byte Header\n");
      packetSize = (amfHdr->amfSize[0] * 256 * 256) + (amfHdr->amfSize[1] * 256) + amfHdr->amfSize[2];
      printf("PacketSize: [%i]\n",packetSize);
      AMFS[amfID].bodySize  = packetSize;
      AMFS[amfID].bodyCount = 0;
      AMFS[amfID].body = (char *)malloc(packetSize);
      AMFS[amfID].amfType = amfHdr->amfType[0];
      if (packetSize > 128) {
        while (select(fd + 1,&readset,0x0,0x0,0x0)) {
          if (FD_ISSET(fd,&readset))
            break;
          }
        recv(fd,AMFS[amfID].body + AMFS[amfID].bodyCount,128,0);
        AMFS[amfID].bodyCount = 128;
        }
      break;
    case 3:
      printf("4 Byte Header\n");
      if ((AMFS[amfID].bodySize - AMFS[amfID].bodyCount) > 128) {
        while (select(fd + 1,&readset,0x0,0x0,0x0)) {
          if (FD_ISSET(fd,&readset))
            break;
          }
        recv(fd,AMFS[amfID].body + (AMFS[amfID].bodyCount - 1),128,0);
        AMFS[amfID].bodyCount += 128;
        }
      else {
        printf("Bal: (%i)\n",(AMFS[amfID].bodySize - AMFS[amfID].bodyCount));
        while (select(fd + 1,&readset,0x0,0x0,0x0)) {
          if (FD_ISSET(fd,&readset))
            break;
          }
        recLen = recv(fd,AMFS[amfID].body + (AMFS[amfID].bodyCount - 1),(AMFS[amfID].bodySize - AMFS[amfID].bodyCount)-1,0);
        printf("Received: [%i]\n",recLen);
        AMFS[amfID].bodyCount += (AMFS[amfID].bodySize - AMFS[amfID].bodyCount)-1;
        }
      break;
    case 2:
      printf("2 Byte Header\n");
      if ((AMFS[amfID].bodySize - AMFS[amfID].bodyCount) > 128) {
        while (select(fd + 1,&readset,0x0,0x0,0x0)) {
          if (FD_ISSET(fd,&readset))
            break;
          }
        recv(fd,AMFS[amfID].body + (AMFS[amfID].bodyCount - 1),128,0);
        AMFS[amfID].bodyCount += 128;
        }
      else {
        printf("Bal: (%i)\n",(AMFS[amfID].bodySize - AMFS[amfID].bodyCount));
        while (select(fd + 1,&readset,0x0,0x0,0x0)) {
          if (FD_ISSET(fd,&readset))
            break;
          }
        recLen = recv(fd,AMFS[amfID].body + (AMFS[amfID].bodyCount - 1),(AMFS[amfID].bodySize - AMFS[amfID].bodyCount)-1,0);
        printf("Received: [%i]\n",recLen);
        AMFS[amfID].bodyCount += (AMFS[amfID].bodySize - AMFS[amfID].bodyCount)-1;
        }
      break;

    default:
      printf("Unhandled Header Size: [%i]\n",headerSize);
      return(-1);
      break;
    }
  if (AMFS[amfID].bodySize == AMFS[amfID].bodyCount)
    doProcessPacket(fd,amfID);
  return(0x0); 
  }

int doProcessPacket(int fd,int amfID) {
  printf("WOOP");
  return(0x0);
  }

int getAMF_old(int fd,int amf) {
  int recLen        = 0x0;
  int amfID         = 0x0;
  int headerSize    = 0x0;
  int packetSize    = 0x0;
  char data[12];
  amfHeader *amfHdr = (amfHeader *)&data;
  fd_set readset;

  FD_ZERO(&readset);
  FD_SET(fd,&readset);



  headerSize = (amf & 0xC0) >> 6;
  amfID      = amf & 0x3F;

  printf("AMF ID: [0x%X]\n",amfID);

  switch(headerSize) {
    case 0:
      printf("12 Byte Header\n");
  while (select(fd + 1,&readset,0x0,0x0,0x0)) {
    if (FD_ISSET(fd,&readset))
      break;
    }

      recLen = recv(fd,&data,11,0);
      printf("Size: [0x%X:0x%X:0x%X]\n",amfHdr->amfSize[0] & 0xFF,amfHdr->amfSize[1] & 0xFF,amfHdr->amfSize[2] & 0xFF);
      packetSize = (amfHdr->amfSize[0] * 256 * 256) + (amfHdr->amfSize[1] * 256) + amfHdr->amfSize[2];
      printf("PacketSize: [%i]\n",packetSize);
/*
      recLen = recv(fd,&packet,packetSize,0);
        if (recLen != packetSize) {
          printf("Error Reading Packet\n");
          return(-1);
          }
*/
      break;
    default:
      printf("Unhandled Header Size: [%i]\n",headerSize);
      return(-1);
      break;
    }

  switch (amfHdr->amfType[0]) {
    case 0x14:
      doAmfFunction(fd,amfID,packetSize);
      break;
    default:
      printf("Unhandled amfType: [0x%X]\n",amfHdr->amfType[0]);
      return(-1);
      break;
    }
  return(0x0);
  }

int doAmfFunction(int fd,int amfID,int packetSize) {
  int   recLen = 0x0;
  int   i      = 0x0;
  int   ch     = 0x0;
  char *packet = 0x0;
  char  function[256];
  fd_set readset;

  FD_ZERO(&readset);
  FD_SET(fd,&readset);


  printf("Reading Packet");
  packet = (char *)malloc(packetSize);
  while (select(fd + 1,&readset,0x0,0x0,0x0)) {
    if (FD_ISSET(fd,&readset))
      break;
    }

  recLen = recv(fd,packet,packetSize,MSG_WAITALL);

  for (i = 0;i < packet[2];i++) {
    function[i] = packet[i + 3];
    }
  function[i] = '\0';
  printf("Function: [%s]\n",function);
  if (!strcmp(function,"connect"))
    amfDoAccept(fd);

  for (i=0;i<recLen;i++) {
    ch = packet[i];
    if (ch >= 10 && ch <= 128)
    printf("[%c]",ch);
    else
      printf("[0x%X]",ch);
    }
  printf("\n");
  return(0x0);
  }