#include #include #include #include #include #include #include #include #include #include #include "h261ctrl.h" h261ctrl_t::h261ctrl_t() { magic = H261MAGIC; seq = 2000; type = 0; rep_type = 0; h261_imgtype = 0; } H261CtrlConn::H261CtrlConn() { is_connected = 0; ctrlfd = encsockfd = encfilefd = decfd = 0; encpid = decpid = 0; } void H261CtrlConn::RcvPkt(void) { struct h261ctrl_t pkt; struct sockaddr_in peer; u_int tmp_len=sizeof(peer); recvfrom(ctrlfd, (void*)&pkt, sizeof(pkt), 0, (sockaddr*)&peer, &tmp_len); switch(pkt.type) { case CONN_REQ: AcceptConnect(&pkt, &peer); break; case DISCONNECT: AcceptDisconnect(&pkt, &peer); break; default: break; } } int H261CtrlConn::sendh261ctrlpkt(h261ctrl_t *pkt, struct sockaddr_in *peer, h261ctrl_t *rep) { static u_int seq = 200; struct sockaddr_in tmp; struct timeval tv; fd_set rdfs; int rc = 0; u_int tmp_len = sizeof(tmp); pkt->seq = seq++; rc = sendto(ctrlfd, (void*)pkt, sizeof(*pkt), 0, (sockaddr*)peer, sizeof(*peer)); if(rc < 0) { fprintf(stderr, "error in sendto\n"); perror("sendto "); } if(rep) { FD_ZERO(&rdfs); FD_SET(ctrlfd, &rdfs); tv.tv_sec = 4; tv.tv_usec = 0; rc = select(ctrlfd+1, &rdfs, 0, 0, &tv); fprintf(stderr, "rc after select = %d\n", rc); if(!rc) return -1; recvfrom(ctrlfd, (void*)rep, sizeof(*rep),0, (sockaddr*)&tmp, &tmp_len); } return 0; } int H261CtrlConn::MakeConnect( char *hostname) { struct hostent * remote; struct sockaddr_in remote_addr; struct h261ctrl_t pkt, rep; if(is_connected) return -1; memset(&remote_addr, 0, sizeof(remote_addr)); remote_addr.sin_family = AF_INET; remote_addr.sin_port = htons(H261CTRLPORT); remote = gethostbyname(hostname); if(!remote) return -1; remote_addr.sin_addr = *(struct in_addr *)remote->h_addr; pkt.type = CONN_REQ; pkt.h261_imgtype = QCIF_TYPE; neighbor = remote_addr; if( sendh261ctrlpkt(&pkt, &remote_addr, &rep) < 0) return -1; fprintf(stderr, "reptype is %d\n", rep.type); if(rep.type != ACK) return -1; #ifdef OLD connect(encsockfd, (sockaddr*)&remote_addr, sizeof(remote_addr)); #endif if( (decpid = fork()) == 0) /* Decoder */ execlp("./video_rx", "video_rx", 0); if( (encpid = fork()) == 0) /* Encoder */ execlp("./video_tx", "video_tx", "-f", encfilename, "-a", inet_ntoa(remote_addr.sin_addr), 0); fprintf(stderr, "encoder pid is %d decoder is %d\n", encpid, decpid); is_connected = 1; setconnstatus(1); return 0; } int H261CtrlConn::AcceptConnect(h261ctrl_t *h, struct sockaddr_in *peer) { int rc = 0; if(is_connected) return rc = -1; if(h->type == CONN_REQ) h->type = ACK; else h->type = NACK; peer->sin_port = htons(H261RXPORT); if( (decpid = fork()) == 0) /* Decoder */ execlp("./video_rx", "video_rx", 0); if( (encpid = fork()) == 0) /* Encoder */ execlp("./video_tx", "video_tx", "-f", encfilename, "-a", inet_ntoa(peer->sin_addr), 0); fprintf(stderr, "encoder pid is %d decoder is %d\n", encpid, decpid); is_connected = 1; setconnstatus(1); fprintf(stderr, "going to send reply to %s\n", inet_ntoa(peer->sin_addr)); peer->sin_port = htons(H261CTRLPORT); neighbor = *peer; sendh261ctrlpkt(h, peer); return 0; } void H261CtrlConn::Disconnect(void) { struct sockaddr_in remote_addr; struct h261ctrl_t pkt, rep; if(!is_connected) return; remote_addr = neighbor; pkt.type = DISCONNECT; pkt.h261_imgtype = QCIF_TYPE; kill(encpid, SIGKILL); kill(decpid, SIGKILL); encpid = decpid = 0; is_connected = 0; setconnstatus(0); sendh261ctrlpkt(&pkt, &remote_addr, &rep); } void H261CtrlConn::AcceptDisconnect(h261ctrl_t *h, struct sockaddr_in *peer) { int rc = 0; if(!is_connected) return; if(h->type == DISCONNECT) h->type = ACK; else h->type = NACK; *peer = neighbor; kill(encpid, SIGKILL); kill(decpid, SIGKILL); encpid = decpid = 0; is_connected = 0; setconnstatus(0); peer->sin_port = htons(H261CTRLPORT); sendh261ctrlpkt(h, peer); return 0; }