embkernel
 All Classes Functions Variables Typedefs Groups Pages
Net.cpp
1 //------------------------------------------------------------------------------
2 //This file is part of embKernel.
3 //See license.txt for the full license governing this code.
4 //------------------------------------------------------------------------------
5 
6 #include "Net.hpp"
7 #include "NetIp.hpp"
8 #include "NetArp.hpp"
9 #include "NetMacros.hpp"
10 #include "NetClientDhcp.hpp"
11 #include "NetTcp.hpp"
12 
13 RtosSemaphore Net::sSemaEvent(255, 0);
14 RtosSemaphore Net::sSemaMemory(1, 1);
15 RtosTask* Net::sTask;
16 NetMac* Net::sMac;
17 LibDmem* Net::sMem;
18 NetDefs::MAC_ADDR Net::sMacAddr;
19 NetDefs::NET_CONFIG Net::sConfig;
20 Rtos::TICK Net::sTickTimerArp;
21 Rtos::TICK Net::sTickTimerTcp;
22 Rtos::TICK Net::sTickTimerClientDhcp;
23 
24 void Net::init(Rtos::PRIORITY priority, size_t stackSize, NetMac* mac, LibDmem* mem) {
25  sTask = new RtosTask(priority, "NET", stackSize, run);
26  sMac = mac;
27  sMem = mem;
28 }
29 
30 void Net::run(RtosTask*) {
31  loadMac(sMacAddr);
32  loadConfig(sConfig);
33  sMac->start(sMacAddr);
34 
35  sTickTimerTcp = Rtos::getTick();
36  sTickTimerArp = sTickTimerTcp + Rtos::convertMsToTick(5);
37  sTickTimerClientDhcp = sTickTimerArp + Rtos::convertMsToTick(500);
38 
39  while (true) {
40  if (sSemaEvent.take(Rtos::convertMsToTick(5))) {
41  //Clean up sent buffers
42  sMac->freeSentFrames();
43  //Get rx buffer if any
44  NetDefs::FRAME* frame = sMac->getFrame();
45 
46  if (frame) {
47  switch (frame->types.mac.macHeader.type) {
48  case NetDefs::MAC_TYPE_ARP:
49  NetArp::processFrame(*frame, frame->types.arp.arpHeader);
50  break;
51  case NetDefs::MAC_TYPE_IP:
52  NetIp::processFrame(*frame, frame->types.ip.ipHeader);
53  break;
54  default:
55  freeFrame(*frame);
56  break;
57  }
58  }
59  }
60 
61  if (Rtos::isElapsed(sTickTimerTcp)) {
62  sTickTimerTcp += Rtos::convertMsToTick(10);
63  NetTcp::tick();
64  }
65  else if (Rtos::isElapsed(sTickTimerArp)) {
66  sTickTimerArp += Rtos::convertMsToTick(100);
67  NetArp::tick();
68  }
69 #if NET_CFG_USE_DHCP_CLIENT
70  else if (Rtos::isElapsed(sTickTimerClientDhcp)) {
71  sTickTimerClientDhcp += Rtos::convertMsToTick(1000);
72  NetClientDhcp::tick();
73  }
74 #endif
75 
76  }
77  }
78 
79 NetDefs::FRAME* Net::allocFrame(size_t size) {
80  sSemaMemory.take(Rtos::TICK_INFINITE);
81  NetDefs::FRAME* frame = (NetDefs::FRAME*) sMem->alloc(size);
82  sSemaMemory.give(Rtos::TICK_INFINITE);
83  return frame;
84 }
85 
86 void Net::freeFrame(NetDefs::FRAME& frame) {
87  sSemaMemory.take(Rtos::TICK_INFINITE);
88  sMem->free(&frame);
89  sSemaMemory.give(Rtos::TICK_INFINITE);
90 }
91 
92 void* Net::resizeFrame(NetDefs::FRAME& frame, size_t size) {
93  sSemaMemory.take(Rtos::TICK_INFINITE);
94  void* result = sMem->resize(&frame, size);
95  sSemaMemory.give(Rtos::TICK_INFINITE);
96  return result;
97 }
98 
99 void* Net::resizeFrameLeft(NetDefs::FRAME& frame, size_t left) {
100  sSemaMemory.take(Rtos::TICK_INFINITE);
101  void* result = sMem->resizeLeft(&frame, left);
102  sSemaMemory.give(Rtos::TICK_INFINITE);
103  return result;
104 }
105 
106 void Net::putHeader(NetDefs::FRAME& frame, const NetDefs::MAC_ADDR& dst, NetDefs::MAC_TYPE type) {
107  sMac->putHeader(frame, dst, type);
108 }
109 
110 void Net::flush(NetDefs::FRAME& frame, size_t len, bool discardable) {
111  sMac->flush(frame, len, discardable);
112 }
113 
114 NetDefs::NET_CONFIG& Net::getConfig() {
115  return sConfig;
116 }
117 
118 size_t Net::getTotalMemory() {
119  return sMem->getTotalMemory();
120 }
121 
122 size_t Net::getFreeMemory() {
123  return sMem->getFreeMemory();
124 }
125 
126 unsigned int Net::getBlockCount() {
127  return sMem->getBlockCount();
128 }
129 
130 bool Net::onMacEventInterrupt() {
131  return sSemaEvent.giveFromInt();
132 }
133