embkernel
 All Classes Functions Variables Typedefs Groups Pages
NetUdp.cpp
1 //------------------------------------------------------------------------------
2 //This file is part of embKernel.
3 //See license.txt for the full license governing this code.
4 //------------------------------------------------------------------------------
5 
6 #include "NetUdp.hpp"
7 #include "NetIp.hpp"
8 #include "Net.hpp"
9 #include "NetCfg.hpp"
10 #include "LibEndian.hpp"
11 #include "NetClientDhcp.hpp"
12 #include "NetNbns.hpp"
13 #include "NetRemoteConfiguration.hpp"
14 #include "NetUdpSocket.hpp"
15 
16 LibLinkedList<NetUdpSocket> NetUdp::sSocketList;
17 RtosSemaphore NetUdp::sSema(1, 1);
18 
19 void NetUdp::processFrame(NetDefs::FRAME& frame, NetDefs::UDP_HEADER& header, int len) {
20  swapHeader(header);
21 
22 #if NET_CFG_USE_DHCP_CLIENT//
23  if (header.dstPort == NetDefs::UDP_PORT_DHCP_CLIENT) {
24  NetClientDhcp::processFrame(frame, *((NetDefs::DHCP_HEADER*) (((uint8_t*) &header) + sizeof(header))), len - sizeof(header));
25  return;
26  }
27 #endif//NET_CFG_USE_DHCP_CLIENT
28 #if NET_CFG_USE_NBNS//
29  if (header.dstPort == NetDefs::UDP_PORT_NBNS) {
30  NetNbns::processFrame(frame, *((NetDefs::NBNS_HEADER*) (((uint8_t*) &header) + sizeof(header))), len - sizeof(header));
31  return;
32  }
33 #endif//NET_CFG_USE_NBNS
34 #if NET_CFG_USE_REMOTE_CONFIGURATION//
35  if (header.dstPort == NET_CFG_REMOTE_CONFIGURATION_PORT) {
36  NetRemoteConfiguration::processFrame(frame, len - sizeof(header));
37  return;
38  }
39 #endif//NET_CFG_USE_REMOTE_CONFIGURATION
40  NetUdpSocket* socket;
41  if (header.dstPort == 0) {
42  Net::freeFrame(frame);
43  }
44  else if ((socket = findMatchingSocket(header.dstPort)) == 0) {
45  Net::freeFrame(frame);
46  }
47  else {
48  NetDefs::IP_ADDR srcIp = frame.types.ip.ipHeader.srcAddr;
49  NetDefs::UDP_PORT srcPort = header.srcPort;
50 
51  NetUdpSocket::RX_PACKET* rxPkt = (NetUdpSocket::RX_PACKET*) Net::resizeFrameLeft(frame,
52  (((uint8_t*) &header + sizeof(NetDefs::UDP_HEADER) - (uint8_t*) &frame)) - sizeof(NetUdpSocket::PACKET_HEADER));
53  if (!rxPkt) {
54  Net::freeFrame(frame);
55  return;
56  }
57  rxPkt->hdr.ip = srcIp;
58  rxPkt->hdr.port = srcPort;
59  rxPkt->hdr.dataLen = len - sizeof(NetDefs::UDP_HEADER);
60  if (!socket->mRxMsgBox.give(rxPkt, 0)) {
61  Net::freeFrame((NetDefs::FRAME&) rxPkt);
62  return;
63  }
64  }
65 }
66 
67 void NetUdp::putHeader(NetDefs::FRAME& frame, const NetDefs::MAC_ADDR& macDst, const NetDefs::IP_ADDR& dstAddr, uint16_t srcPort, uint16_t dstPort,
68  int dataLen) {
69 
70  frame.types.udp.udpHeader.dstPort = dstPort;
71  frame.types.udp.udpHeader.srcPort = srcPort;
72  frame.types.udp.udpHeader.len = sizeof(NetDefs::UDP_HEADER) + dataLen;
73  frame.types.udp.udpHeader.checkSum = 0;
74 
75  swapHeader(frame.types.udp.udpHeader);
76 
77  NetIp::putHeader(frame, macDst, dstAddr, sizeof(NetDefs::UDP_HEADER) + dataLen, NetDefs::IP_PROTOCOL_UDP);
78 }
79 
80 void NetUdp::flush(NetDefs::FRAME& frame, int dataLen, bool discardable) {
81  NetIp::flush(frame, sizeof(NetDefs::UDP_HEADER) + dataLen, discardable);
82 }
83 
84 void NetUdp::swapHeader(NetDefs::UDP_HEADER& header) {
85  header.srcPort = LibEndian::hwToBe(header.srcPort);
86  header.dstPort = LibEndian::hwToBe(header.dstPort);
87  header.len = LibEndian::hwToBe(header.len);
88 }
89 
90 NetUdpSocket* NetUdp::findMatchingSocket(NetDefs::UDP_PORT port) {
91  sSema.take(Rtos::TICK_INFINITE);
92  for (NetUdpSocket* s = sSocketList.getFirst(); s != 0; s = s->getNext()) {
93  if (s->mLocalPort == port) {
94  sSema.give(Rtos::TICK_INFINITE);
95  return s;
96  }
97  }
98  sSema.give(Rtos::TICK_INFINITE);
99  return 0;
100 }
101 
102 void NetUdp::addSocket(NetUdpSocket& socket) {
103  sSema.take(Rtos::TICK_INFINITE);
104  sSocketList.insert(socket);
105  sSema.give(Rtos::TICK_INFINITE);
106 }
107 
108 void NetUdp::removeSocket(NetUdpSocket& socket) {
109  sSema.take(Rtos::TICK_INFINITE);
110  sSocketList.remove(socket);
111  sSema.give(Rtos::TICK_INFINITE);
112 }
113