Fork of NetServicesMin with some warnings removed
Fork of NetServicesMin by
lwipNetUdpSocket.cpp
00001 #pragma diag_remark 1464 00002 /* 00003 Copyright (c) 2010 Donatien Garnier (donatiengar [at] gmail [dot] com) 00004 00005 Permission is hereby granted, free of charge, to any person obtaining a copy 00006 of this software and associated documentation files (the "Software"), to deal 00007 in the Software without restriction, including without limitation the rights 00008 to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 00009 copies of the Software, and to permit persons to whom the Software is 00010 furnished to do so, subject to the following conditions: 00011 00012 The above copyright notice and this permission notice shall be included in 00013 all copies or substantial portions of the Software. 00014 00015 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 00016 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 00017 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 00018 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 00019 LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 00020 OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 00021 THE SOFTWARE. 00022 */ 00023 00024 #include "lwip/ip_addr.h" 00025 #include "lwipNetUdpSocket.h" 00026 #include "lwip/udp.h" 00027 #include "lwip/igmp.h" 00028 00029 00030 //#define __DEBUG 00031 #include "dbg/dbg.h" 00032 00033 #include "netCfg.h" 00034 #if NET_LWIP_STACK 00035 00036 LwipNetUdpSocket::LwipNetUdpSocket(udp_pcb* pPcb /*= NULL*/) : NetUdpSocket(), m_pPcb(pPcb), m_lInPkt(), m_multicastGroup() //Passes a pcb if already created (by an accept req for instance), in that case transfers ownership 00037 { 00038 DBG("New LwipNetUdpSocket %p (pPCb=%p)\n", (void*)this, (void*) pPcb); 00039 if(!m_pPcb) 00040 m_pPcb = udp_new(); 00041 if(m_pPcb) 00042 { 00043 //Setup callback 00044 udp_recv( (udp_pcb*) m_pPcb, LwipNetUdpSocket::sRecvCb, (void*) this ); 00045 } 00046 } 00047 00048 LwipNetUdpSocket::~LwipNetUdpSocket() 00049 { 00050 close(); 00051 } 00052 00053 NetUdpSocketErr LwipNetUdpSocket::bind(const Host& me) 00054 { 00055 err_t err; 00056 00057 if(!m_pPcb) 00058 return NETUDPSOCKET_MEM; //NetUdpSocket was not properly initialised, should destroy it & retry 00059 00060 #if LWIP_IGMP //Multicast support enabled 00061 if(me.getIp().isMulticast()) 00062 { 00063 DBG("This is a multicast addr, joining multicast group\n"); 00064 m_multicastGroup = me.getIp(); 00065 err = igmp_joingroup(IP_ADDR_ANY, &(m_multicastGroup.getStruct())); 00066 if(err) 00067 return NETUDPSOCKET_IF; //Could not find or create group 00068 } 00069 #endif 00070 00071 err = udp_bind( (udp_pcb*) m_pPcb, IP_ADDR_ANY, me.getPort()); //IP_ADDR_ANY : Bind the connection to all local addresses 00072 if(err) 00073 return NETUDPSOCKET_INUSE; 00074 00075 //Setup callback 00076 udp_recv( (udp_pcb*) m_pPcb, LwipNetUdpSocket::sRecvCb, (void*) this ); 00077 00078 return NETUDPSOCKET_OK; 00079 } 00080 00081 #define MAX(a,b) ((a>b)?a:b) 00082 #define MIN(a,b) ((a<b)?a:b) 00083 00084 int /*if < 0 : NetUdpSocketErr*/ LwipNetUdpSocket::sendto(const char* buf, int len, Host* pHost) 00085 { 00086 if( !m_pPcb ) //Pcb doesn't exist (anymore) 00087 return NETUDPSOCKET_MEM; 00088 pbuf* p = pbuf_alloc(PBUF_TRANSPORT, len, PBUF_POOL); 00089 if( !p ) 00090 return NETUDPSOCKET_MEM; 00091 char* pBuf = (char*) buf; 00092 pbuf* q = p; 00093 do 00094 { 00095 memcpy (q->payload, (void*)pBuf, q->len); 00096 pBuf += q->len; 00097 q = q->next; 00098 } while(q != NULL); 00099 00100 ip_addr_t hip(pHost->getIp().getStruct()); 00101 err_t err = udp_sendto( (udp_pcb*) m_pPcb, p, &hip, pHost->getPort() ); 00102 pbuf_free( p ); 00103 if(err) 00104 return NETUDPSOCKET_SETUP; //Connection problem 00105 DBG("%d bytes sent in UDP Socket.\n", len); 00106 return len; 00107 } 00108 00109 int /*if < 0 : NetUdpSocketErr*/ LwipNetUdpSocket::recvfrom(char* buf, int len, Host* pHost) 00110 { 00111 if( !m_pPcb ) //Pcb doesn't exist (anymore) 00112 return NETUDPSOCKET_MEM; 00113 int inLen = 0; 00114 int cpyLen = 0; 00115 00116 static int rmgLen = 0; 00117 //Contains the remaining len in this pbuf 00118 00119 if( m_lInPkt.empty() ) 00120 return 0; 00121 00122 pbuf* pBuf = (pbuf*) m_lInPkt.front().pBuf; 00123 00124 if(pHost) 00125 *pHost = Host( IpAddr(&m_lInPkt.front().addr), m_lInPkt.front().port ); 00126 00127 if( !pBuf ) 00128 { 00129 rmgLen = 0; 00130 return 0; 00131 } 00132 00133 if ( !rmgLen ) //We did not know m_pReadPbuf->len last time we called this fn 00134 { 00135 rmgLen = pBuf->len; 00136 } 00137 00138 while ( inLen < len ) 00139 { 00140 cpyLen = MIN( (len - inLen), rmgLen ); //Remaining len to copy, remaining len in THIS pbuf 00141 memcpy((void*)buf, (void*)((char*)(pBuf->payload) + (pBuf->len - rmgLen)), cpyLen); 00142 inLen += cpyLen; 00143 buf += cpyLen; 00144 00145 rmgLen = rmgLen - cpyLen; //Update rmgLen 00146 00147 if( rmgLen > 0 ) 00148 { 00149 //We did not read this pbuf completely, so let's save it's pos & return 00150 break; 00151 } 00152 00153 if(pBuf->next) 00154 { 00155 pbuf* pNextPBuf = pBuf->next; 00156 pBuf->next = NULL; //So that it is not freed as well 00157 //We get the reference to pNextPBuf from m_pReadPbuf 00158 pbuf_free((pbuf*)pBuf); 00159 pBuf = pNextPBuf; 00160 rmgLen = pBuf->len; 00161 } 00162 else 00163 { 00164 pbuf_free((pbuf*)pBuf); 00165 pBuf = NULL; 00166 rmgLen = 0; 00167 m_lInPkt.pop_front(); 00168 break; //No more data to read 00169 } 00170 } 00171 00172 return inLen; 00173 } 00174 00175 NetUdpSocketErr LwipNetUdpSocket::close() 00176 { 00177 DBG("LwipNetUdpSocket::close() : Closing...\n"); 00178 00179 if(m_closed) 00180 return NETUDPSOCKET_OK; //Already being closed 00181 m_closed = true; 00182 00183 if( !m_pPcb ) //Pcb doesn't exist (anymore) 00184 return NETUDPSOCKET_MEM; 00185 00186 DBG("LwipNetUdpSocket::close() : Cleanup...\n"); 00187 00188 //Cleanup incoming data 00189 cleanUp(); 00190 00191 00192 DBG("LwipNetUdpSocket::close() : removing m_pPcb...\n"); 00193 udp_remove( (udp_pcb*) m_pPcb); 00194 00195 m_pPcb = NULL; 00196 return NETUDPSOCKET_OK; 00197 } 00198 00199 NetUdpSocketErr LwipNetUdpSocket::poll() 00200 { 00201 NetUdpSocket::flushEvents(); 00202 return NETUDPSOCKET_OK; 00203 } 00204 00205 // Callbacks events 00206 00207 void LwipNetUdpSocket::recvCb(udp_pcb* pcb, struct pbuf* p, ip_addr_t* addr, u16_t port) 00208 { 00209 DBG(" Packet of length %d arrived in UDP Socket.\n", p->tot_len); 00210 list<InPacket>::iterator it; 00211 for ( it = m_lInPkt.begin(); it != m_lInPkt.end(); it++ ) 00212 { 00213 if( ip_addr_cmp((&((*it).addr)), addr) && ((*it).port == port) ) 00214 { 00215 //Let's tail this packet to the previous one 00216 pbuf_cat((pbuf*)((*it).pBuf), p); 00217 //No need to queue an event in that case since the read buf has not been processed yet 00218 return; 00219 } 00220 } 00221 00222 //New host, add a packet to the queue 00223 InPacket pkt; 00224 pkt.pBuf = p; 00225 pkt.addr = *addr; 00226 pkt.port = port; 00227 m_lInPkt.push_back(pkt); 00228 00229 queueEvent(NETUDPSOCKET_READABLE); 00230 } 00231 00232 void LwipNetUdpSocket::cleanUp() //Flush input buffer 00233 { 00234 //Ensure that further error won't be followed to this inst (which can be destroyed) 00235 if( m_pPcb ) 00236 { 00237 udp_recv( (udp_pcb*) m_pPcb, NULL, (void*) NULL ); 00238 } 00239 00240 //Leaving multicast group(Ok because LwIP has a refscount for multicast group) 00241 #if LWIP_IGMP //Multicast support enabled 00242 if(m_multicastGroup.isMulticast()) 00243 { 00244 igmp_leavegroup(IP_ADDR_ANY, &(m_multicastGroup.getStruct())); 00245 m_multicastGroup = IpAddr(); 00246 } 00247 #endif 00248 00249 list<InPacket>::iterator it; 00250 for ( it = m_lInPkt.begin(); it != m_lInPkt.end(); it++ ) 00251 { 00252 //Free buf 00253 pbuf_free((pbuf*)((*it).pBuf)); 00254 } 00255 m_lInPkt.clear(); 00256 } 00257 00258 // Static callback from LwIp 00259 00260 void LwipNetUdpSocket::sRecvCb(void *arg, struct udp_pcb *pcb, struct pbuf *p, ip_addr_t *addr, u16_t port) 00261 { 00262 LwipNetUdpSocket* pMe = (LwipNetUdpSocket*) arg; 00263 return pMe->recvCb( pcb, p, addr, port ); 00264 } 00265 00266 #endif
Generated on Wed Jul 13 2022 04:33:03 by 1.7.2