/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ /*************************************************************************** * network.cc * * Wed Nov 3 21:23:14 CET 2004 * Copyright 2004 Bent Bisballe Nyeng * deva@aasimon.org ****************************************************************************/ /* * This file is part of MIaV. * * MIaV is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * MIaV is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with MIaV; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. */ #include "network.h" //#ifdef USE_DEBUG //#include "efencepp.h" //#endif /*USE_DEBUG*/ #include "info.h" #include #include #include #include #include Network::Network(Socket *gs) { s = gs; } Network::~Network() { } int Network::write(void *buf, int size) { if(!s->connected) { // MIaV::info->error("Write attempted to a socket not connected!"); return -1; } int n = send(s->sock, buf, size, MSG_WAITALL); if(n == -1) { MIaV::info->error("An error occurred!"); } return n; } int Network::read(void *buf, int size) { if(!s->connected) { // MIaV::info->error("Read attempted from a socket not connected!"); return -1; } int n = recv(s->sock, buf, size, MSG_WAITALL); if(n == -1) { MIaV::info->error("An error occurred!"); } return n; } /* struct msghdr { void *msg_name // Optional address. socklen_t msg_namelen // Size of address. struct iovec *msg_iov // Scatter/gather array. int msg_iovlen // Members in msg_iov. void *msg_control // Ancillary data; see below. socklen_t msg_controllen // Ancillary data buffer len. int msg_flags // Flags on received message. }; */ int Network::sendPackage(n_header *h, void* buf, int bufsz) { struct msghdr msg; struct iovec iovecs[2]; if(!s->connected) { // MIaV::info->error("Write attempted to a socket not connected!"); return -1; } memset(&msg, 0, sizeof(msg)); msg.msg_iov = iovecs; msg.msg_iovlen = 2; msg.msg_iov[0].iov_base = h; msg.msg_iov[0].iov_len = sizeof(*h); msg.msg_iov[1].iov_base = buf; msg.msg_iov[1].iov_len = bufsz; int n = sendmsg(s->sock, &msg, 0); if(n < 0) { MIaV::info->error("A network error ocurred during sendPackage!"); return -1; } return n; } int Network::recvPackage(n_header *h, void* buf, int bufsz) { struct msghdr msg; struct iovec iovecs[2]; if(!s->connected) { // MIaV::info->error("Read attempted to a socket not connected!"); return -1; } memset(&msg, 0, sizeof(msg)); iovecs[0].iov_base = h; iovecs[0].iov_len = sizeof(*h); iovecs[1].iov_base = buf; iovecs[1].iov_len = bufsz; msg.msg_iov = iovecs; msg.msg_iovlen = 2; int n = recvmsg(s->sock, &msg, MSG_WAITALL); if(n < 0) { MIaV::info->error("A network error ocurred during recvPackage!"); return -1; } if(msg.msg_iovlen != 2) { MIaV::info->error("Wrong package format!"); return -1; } return n; } int Network::sendFrame(Frame *frame) { frameheader_t header; struct msghdr msg; struct iovec iovecs[2]; if(!s->connected) { // MIaV::info->error("Write attempted to a socket not connected!"); return -1; } header.timecode.hour = htonl(frame->timecode.hour); header.timecode.min = htonl(frame->timecode.min); header.timecode.sec = htonl(frame->timecode.sec); header.timecode.frame = htonl(frame->timecode.frame); header.snapshot = htonl(frame->snapshot); header.freeze = htonl(frame->freeze); header.vformat = (video_format_t)htons((short unsigned int)frame->vformat); header.aformat = (audio_format_t)htons((short unsigned int)frame->aformat); header.vframesize = htonl(frame->vframesize); header.aframesize = htonl(frame->aframesize); write(&header, sizeof(header)); char *vframe = frame->vframe; char *aframe = frame->aframe; int vframesize = frame->vframesize; int aframesize = frame->aframesize; memset(&msg, 0, sizeof(msg)); msg.msg_iov = iovecs; msg.msg_iovlen = 2; msg.msg_iov[0].iov_base = vframe; msg.msg_iov[0].iov_len = vframesize; msg.msg_iov[1].iov_base = aframe; msg.msg_iov[1].iov_len = aframesize; int n = sendmsg(s->sock, &msg, 0); if(n < 0) { MIaV::info->error("A network error ocurred during sendPackage!"); return -1; } return n; } Frame *Network::recvFrame() { Frame *frame = NULL; frameheader_t header; struct msghdr msg; struct iovec iovecs[2]; if(!s->connected) { // MIaV::info->error("Read attempted to a socket not connected!"); return NULL; } read(&header, sizeof(header)); int vframesize = ntohl(header.vframesize); int aframesize = ntohl(header.aframesize); char *vframe = new char[vframesize]; char *aframe = new char[aframesize]; memset(&msg, 0, sizeof(msg)); iovecs[0].iov_base = vframe; iovecs[0].iov_len = vframesize; iovecs[1].iov_base = aframe; iovecs[1].iov_len = aframesize; msg.msg_iov = iovecs; msg.msg_iovlen = 2; int n = recvmsg(s->sock, &msg, MSG_WAITALL); if(n < 0) { MIaV::info->error("A network error ocurred during recvPackage!"); return NULL; } if(n == 0) { // No more frames to receive. return NULL; } if(msg.msg_iovlen != 2) { MIaV::info->error("Wrong package format!"); return NULL; } frame = new Frame(vframe, vframesize, (video_format_t)ntohs((short unsigned int)header.vformat), aframe, aframesize, (audio_format_t)ntohs((short unsigned int)header.aformat)); frame->timecode.hour = ntohl(header.timecode.hour); frame->timecode.min = ntohl(header.timecode.min); frame->timecode.sec = ntohl(header.timecode.sec); frame->timecode.frame = ntohl(header.timecode.frame); frame->snapshot = ntohl(header.snapshot); frame->freeze = ntohl(header.freeze); return frame; }