MOOS 0.2375
|
00001 /* 00002 * MOOSUDPLink.cpp 00003 * MOOS 00004 * 00005 * Created by pnewman on 16/05/2009. 00006 * Copyright 2009 Oxford University. All rights reserved. 00007 * 00008 */ 00009 00010 #include "MOOSUDPLink.h" 00011 #include <MOOSLIB/XPCUdpSocket.h> 00012 #include <MOOSLIB/MOOSException.h> 00013 00014 00015 #define MAX_UDP_PKT_SIZE 65536 00016 00017 00018 bool _ListenCB(void * pParam) 00019 { 00020 CMOOSUDPLink* pMe = (CMOOSUDPLink* )pParam; 00021 return pMe->ListenLoop(); 00022 00023 } 00024 00025 00026 CMOOSUDPLink::CMOOSUDPLink() 00027 { 00028 m_pUDPSocket = NULL; 00029 m_nLocalPort = -1; 00030 } 00031 00032 bool CMOOSUDPLink::Run(int nLocalPort) 00033 { 00034 00035 m_nLocalPort = nLocalPort; 00036 00037 //input socket 00038 m_pUDPSocket = new XPCUdpSocket(m_nLocalPort); 00039 00040 //its likely we want tp broadcast 00041 00042 m_pUDPSocket->vSetBroadcast(true); 00043 00044 if(nLocalPort!=-1) 00045 { 00046 00047 try 00048 { 00049 m_pUDPSocket->vBindSocket(); 00050 } 00051 catch (XPCException e) 00052 { 00053 MOOSTrace(e.sGetException()); 00054 return false; 00055 } 00056 00057 m_ListenThread.Initialise(_ListenCB,this); 00058 m_ListenThread.Start(); 00059 } 00060 00061 return true; 00062 00063 } 00064 00065 bool CMOOSUDPLink::Post(CMOOSMsg & M,const std::string & sHost, long int nPort) 00066 { 00067 00068 if(m_pUDPSocket==NULL) 00069 return MOOSFail("CMOOSUDPLink::Post No functioning UDP socket - has run been called\n"); 00070 00071 00072 MOOSMSG_LIST OutBox; 00073 OutBox.push_back(M); 00074 00075 CMOOSCommPkt P; 00076 00077 P.Serialize(OutBox, true, false); 00078 00079 try 00080 { 00081 if(P.GetStreamLength()>MAX_UDP_PKT_SIZE) 00082 { 00083 //too big 00084 throw XPCException("serialised packet is too big to send ....ask for an upgrade"); 00085 } 00086 00087 int nSent = m_pUDPSocket->iSendMessageTo(P.m_pStream,P.GetStreamLength(),nPort,sHost); 00088 00089 00090 if(nSent!=P.GetStreamLength()) 00091 { 00092 //something abd happened.. 00093 throw XPCException("failed to send mailbox as datagram"); 00094 } 00095 else 00096 { 00097 //MOOSTrace("sent %d bytes\n", nSent); 00098 } 00099 } 00100 catch(XPCException e) 00101 { 00102 MOOSTrace("CMOOSUdpLink::PostLoop Exception caught %s\n",e.sGetException()); 00103 } 00104 00105 00106 return true; 00107 00108 } 00109 00110 bool CMOOSUDPLink::Fetch(MOOSMSG_LIST & M) 00111 { 00112 m_InLock.Lock(); 00113 M.splice(M.begin(),m_InBox); 00114 m_InLock.UnLock(); 00115 return true; 00116 } 00117 00118 00119 00120 00121 bool CMOOSUDPLink::ListenLoop() 00122 { 00123 //MOOSTrace("listening for incoming data packets on port %d\n",m_nLocalPort); 00124 unsigned char Buff[MAX_UDP_PKT_SIZE]; 00125 00126 while(!m_ListenThread.IsQuitRequested()) 00127 { 00128 int nRead = m_pUDPSocket->iRecieveMessage((unsigned char*)Buff,sizeof(Buff)); 00129 CMOOSCommPkt P; 00130 00131 try 00132 { 00133 ReadPktFromArray(Buff, nRead, P); 00134 00135 m_InLock.Lock(); 00136 { 00137 if(P.Serialize(m_InBox,false)) 00138 { 00139 MOOSTrace("%d MOOSMsg's held\n",m_InBox.size()); 00140 } 00141 else 00142 { 00143 MOOSTrace("failed to serialise CommPacket to Mailbox"); 00144 } 00145 00146 } 00147 m_InLock.UnLock(); 00148 00149 } 00150 catch (CMOOSException e) 00151 { 00152 MOOSTrace("failed to serialise udp datagram to a CommPacket"); 00153 } 00154 00155 00156 00157 } 00158 00159 return true; 00160 } 00161 00162 00163 00164 bool CMOOSUDPLink::ReadPktFromArray(unsigned char *pBuffer,int nBytes, CMOOSCommPkt& PktRx) 00165 { 00166 00167 int nRqd=0; 00168 int q = 0; 00169 while((nRqd=PktRx.GetBytesRequired())!=0) 00170 { 00171 if(q+nRqd<=nBytes) 00172 { 00173 PktRx.Fill(pBuffer+q,nRqd); 00174 q+=nRqd; 00175 } 00176 else 00177 { 00178 throw CMOOSException("UDP Packet was too small! Gross Error"); 00179 } 00180 } 00181 00182 return true; 00183 } 00184 00185