/*
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);
}