MOOS 0.2375
/home/toby/moos-ivp/MOOS-2375-Oct0611/Essentials/pMOOSBridge/MOOSUDPLink.cpp
Go to the documentation of this file.
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 
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines