Statistics
| Branch: | Tag: | Revision:

amiro-blt / Target / Source / net.c @ 93933a75

History | View | Annotate | Download (11.897 KB)

1 69661903 Thomas Schöpping
/************************************************************************************//**
2
* \file         Source\net.c
3
* \brief        Bootloader TCP/IP network communication interface source file.
4
* \ingroup      Core
5
* \internal
6
*----------------------------------------------------------------------------------------
7
*                          C O P Y R I G H T
8
*----------------------------------------------------------------------------------------
9
*   Copyright (c) 2014  by Feaser    http://www.feaser.com    All rights reserved
10
*
11
*----------------------------------------------------------------------------------------
12
*                            L I C E N S E
13
*----------------------------------------------------------------------------------------
14
* This file is part of OpenBLT. OpenBLT is free software: you can redistribute it and/or
15
* modify it under the terms of the GNU General Public License as published by the Free
16
* Software Foundation, either version 3 of the License, or (at your option) any later
17
* version.
18
*
19
* OpenBLT is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
20
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
21
* PURPOSE. See the GNU General Public License for more details.
22
*
23
* You should have received a copy of the GNU General Public License along with OpenBLT.
24
* If not, see <http://www.gnu.org/licenses/>.
25
*
26
* A special exception to the GPL is included to allow you to distribute a combined work 
27
* that includes OpenBLT without being obliged to provide the source code for any 
28
* proprietary components. The exception text is included at the bottom of the license
29
* file <license.html>.
30
* 
31
* \endinternal
32
****************************************************************************************/
33
34
/****************************************************************************************
35
* Include files
36
****************************************************************************************/
37
#include "boot.h"                                /* bootloader generic header          */
38
#if (BOOT_COM_NET_ENABLE > 0)
39
#include "netdev.h"
40
#include "uip.h"
41
#include "uip_arp.h"
42
#endif
43
44
45
#if (BOOT_COM_NET_ENABLE > 0)
46
/****************************************************************************************
47
* Macro definitions
48
****************************************************************************************/
49
/** \brief Delta time for the uIP periodic timer. */
50
#define NET_UIP_PERIODIC_TIMER_MS   (500)
51
/** \brief Delta time for the uIP ARP timer. */
52
#define NET_UIP_ARP_TIMER_MS        (10000)
53
/** \brief Macro for accessing the Ethernet header information in the buffer */
54
#define NET_UIP_HEADER_BUF          ((struct uip_eth_hdr *)&uip_buf[0])
55
56
57
/****************************************************************************************
58
* Hook functions
59
****************************************************************************************/
60
#if (BOOT_COM_NET_IPADDR_HOOK_ENABLE > 0)
61
extern void NetIpAddressHook(blt_int8u *ipAddrArray);
62
#endif
63
#if (BOOT_COM_NET_NETMASK_HOOK_ENABLE > 0)
64
extern void NetNetworkMaskHook(blt_int8u *netMaskArray);
65
#endif
66
#if (BOOT_COM_NET_GATEWAY_HOOK_ENABLE > 0)
67
extern void NetGatewayAddressHook(blt_int8u *gatewayAddrArray);
68
#endif
69
70
71
/****************************************************************************************
72
* Function prototypes
73
****************************************************************************************/
74
static void NetServerTask(void);
75
76
77
/****************************************************************************************
78
* Local data declarations
79
****************************************************************************************/
80
/** \brief Holds the time out value of the uIP periodic timer. */
81
static blt_int32u periodicTimerTimeOut;
82
/** \brief Holds the time out value of the uIP ARP timer. */
83
static blt_int32u ARPTimerTimeOut;
84
85
86
/************************************************************************************//**
87
** \brief     Initializes the TCP/IP network communication interface.
88
** \return    none.
89
**
90
****************************************************************************************/
91
void NetInit(void)
92
{
93
  uip_ipaddr_t ipaddr;
94
  #if (BOOT_COM_NET_IPADDR_HOOK_ENABLE > 0)
95
  blt_int8u ipAddrArray[4];
96
  #endif
97
  #if (BOOT_COM_NET_NETMASK_HOOK_ENABLE > 0)
98
  blt_int8u netMaskArray[4];
99
  #endif
100
  #if (BOOT_COM_NET_GATEWAY_HOOK_ENABLE > 0)
101
  blt_int8u gatewayAddrArray[4];
102
  #endif
103
104
  /* initialize the network device */
105
  netdev_init();
106
  /* initialize the timer variables */
107
  periodicTimerTimeOut = TimerGet() + NET_UIP_PERIODIC_TIMER_MS;
108
  ARPTimerTimeOut = TimerGet() + NET_UIP_ARP_TIMER_MS;
109
  /* initialize the uIP TCP/IP stack. */
110
  uip_init();
111
  /* set the IP address */
112
  #if (BOOT_COM_NET_IPADDR_HOOK_ENABLE > 0)
113
  NetIpAddressHook(ipAddrArray);
114
  uip_ipaddr(ipaddr, ipAddrArray[0], ipAddrArray[1], ipAddrArray[2], ipAddrArray[3]);
115
  #else
116
  uip_ipaddr(ipaddr, BOOT_COM_NET_IPADDR0, BOOT_COM_NET_IPADDR1, BOOT_COM_NET_IPADDR2,
117
             BOOT_COM_NET_IPADDR3);
118
  #endif
119
  uip_sethostaddr(ipaddr);
120
  /* set the network mask */
121
  #if (BOOT_COM_NET_NETMASK_HOOK_ENABLE > 0)
122
  NetNetworkMaskHook(netMaskArray);
123
  uip_ipaddr(ipaddr, netMaskArray[0], netMaskArray[1], netMaskArray[2], netMaskArray[3]);
124
  #else
125
  uip_ipaddr(ipaddr, BOOT_COM_NET_NETMASK0, BOOT_COM_NET_NETMASK1, BOOT_COM_NET_NETMASK2,
126
             BOOT_COM_NET_NETMASK3);
127
  #endif
128
  uip_setnetmask(ipaddr);
129
  /* set the gateway address */
130
  #if (BOOT_COM_NET_GATEWAY_HOOK_ENABLE > 0)
131
  NetGatewayAddressHook(gatewayAddrArray);
132
  uip_ipaddr(ipaddr, gatewayAddrArray[0], gatewayAddrArray[1], gatewayAddrArray[2], gatewayAddrArray[3]);
133
  #else
134
  uip_ipaddr(ipaddr, BOOT_COM_NET_GATEWAY0, BOOT_COM_NET_GATEWAY1, BOOT_COM_NET_GATEWAY2,
135
             BOOT_COM_NET_GATEWAY3);
136
  #endif
137
  uip_setdraddr(ipaddr);
138
  /* start listening on the configured port for XCP transfers on TCP/IP */
139
  uip_listen(HTONS(BOOT_COM_NET_PORT));
140
  /* initialize the MAC and set the MAC address */
141
  netdev_init_mac();  
142
} /*** end of NetInit ***/
143
144
145
/************************************************************************************//**
146
** \brief     Transmits a packet formatted for the communication interface.
147
** \param     data Pointer to byte array with data that it to be transmitted.
148
** \param     len  Number of bytes that are to be transmitted.
149
** \return    none.
150
**
151
****************************************************************************************/
152
void NetTransmitPacket(blt_int8u *data, blt_int8u len)
153
{
154
  uip_tcp_appstate_t *s;
155
  blt_int16u cnt;
156
  
157
  /* get pointer to application state */
158
  s = &(uip_conn->appstate);
159
160
  /* add the dto counter first */
161
  *(blt_int32u*)&(s->dto_data[0]) = s->dto_counter;
162
  /* copy the actual XCP response */
163
  for (cnt=0; cnt<len; cnt++)
164
  {
165
    s->dto_data[cnt+4] = data[cnt];
166
  }
167
  /* set the length of the TCP/IP packet */
168
  s->dto_len = len + 4;
169
  /* submit it for transmission */
170
  uip_send(s->dto_data, s->dto_len);
171
  /* update dto counter for the next transmission */
172
  s->dto_counter++;
173
} /*** end of NetTransmitPacket ***/
174
175
176
/************************************************************************************//**
177
** \brief     Receives a communication interface packet if one is present.
178
** \param     data Pointer to byte array where the data is to be stored.
179
** \return    BLT_TRUE if a packet was received, BLT_FALSE otherwise.
180
**
181
****************************************************************************************/
182
blt_bool NetReceivePacket(blt_int8u *data)
183
{
184
  /* run the TCP/IP server task function, which will handle the reception and 
185
   * transmission of XCP packets
186
   */
187
  NetServerTask();
188
  
189
  /* packet reception and transmission is completely handled by the NetServerTask so 
190
   * always return BLT_FALSE here.
191
   */
192
  return BLT_FALSE;
193
} /*** end of NetReceivePacket ***/
194
195
196
/************************************************************************************//**
197
** \brief     The uIP network application that implements XCP on TCP/IP. Note that this
198
**            application make use of the fact that XCP is request/response based. So
199
**            no new request will come in when a response is pending for transmission,
200
**            if so, the transmission of the pending response is aborted.
201
** \return    none.
202
**
203
****************************************************************************************/
204
void NetApp(void)
205
{
206
  uip_tcp_appstate_t *s;
207
  blt_int8u *newDataPtr;
208
209
  /* get pointer to application state */
210
  s = &(uip_conn->appstate);
211
  
212
  if (uip_connected()) 
213
  {
214
    /* init the dto counter and reset the pending dto data length */
215
    s->dto_counter = 1;
216
    s->dto_len = 0;
217
    return;
218
  }
219
220
  if (uip_acked()) 
221
  {
222
    /* dto sent so set the pending dto data length to zero */
223
    s->dto_len = 0;
224
  }
225
226
  if (uip_rexmit()) 
227
  {
228
    /* retransmit the currently pending dto response */
229
    if (s->dto_len > 0)
230
    {
231
      /* resend the last pending dto response */
232
      uip_send(s->dto_data, s->dto_len);
233
    }
234
  }  
235
236
  if (uip_newdata()) 
237
  {
238
    /* XCP is request/response. this means is a new request comes in when a response
239
     * transmission is still pending, the XCP master either re-initialized or sent
240
     * the request again because of a response time-out. Either way the pending response
241
     * should be cancelled before handling the new request.
242
     */
243
    s->dto_len = 0;
244
    /* the first 4 bytes contain a counter value in which we are not really interested */
245
    newDataPtr = uip_appdata;
246
    XcpPacketReceived(&newDataPtr[4]);
247
  }
248
} /*** end of NetApp ***/
249
250
251
/************************************************************************************//**
252
** \brief     Runs the TCP/IP server task.
253
** \return    none.
254
**
255
****************************************************************************************/
256
static void NetServerTask(void)
257
{
258
  blt_int32u connection;
259
  blt_int32u packetLen;
260
  
261
  /* check for an RX packet and read it. */
262
  packetLen = netdev_read();
263
  if(packetLen > 0)
264
  {
265
    /* set uip_len for uIP stack usage */
266
    uip_len = (blt_int16u)packetLen;
267
268
    /* process incoming IP packets here. */
269
    if(NET_UIP_HEADER_BUF->type == htons(UIP_ETHTYPE_IP))
270
    {
271
      uip_arp_ipin();
272
      uip_input();
273
      /* if the above function invocation resulted in data that
274
       * should be sent out on the network, the global variable
275
       * uip_len is set to a value > 0.
276
       */
277
      if(uip_len > 0)
278
      {
279
        uip_arp_out();
280
        netdev_send();
281
        uip_len = 0;
282
      }
283
    }
284
    /* process incoming ARP packets here. */
285
    else if(NET_UIP_HEADER_BUF->type == htons(UIP_ETHTYPE_ARP))
286
    {
287
      uip_arp_arpin();
288
289
      /* if the above function invocation resulted in data that
290
       * should be sent out on the network, the global variable
291
       * uip_len is set to a value > 0.
292
       */
293
      if(uip_len > 0)
294
      {
295
        netdev_send();
296
        uip_len = 0;
297
      }
298
    }
299
  }
300
  
301
  /* process TCP/IP Periodic Timer here. */
302
  if (TimerGet() >= periodicTimerTimeOut)
303
  {
304
    periodicTimerTimeOut += NET_UIP_PERIODIC_TIMER_MS;
305
    for (connection = 0; connection < UIP_CONNS; connection++)
306
    {
307
      uip_periodic(connection);
308
      /* If the above function invocation resulted in data that
309
       * should be sent out on the network, the global variable
310
       * uip_len is set to a value > 0.
311
       */
312
      if(uip_len > 0)
313
      {
314
        uip_arp_out();
315
        netdev_send();
316
        uip_len = 0;
317
      }
318
    }
319
  }
320
  
321
  /* process ARP Timer here. */
322
  if (TimerGet() >= ARPTimerTimeOut)
323
  {
324
      ARPTimerTimeOut += NET_UIP_ARP_TIMER_MS;
325
      uip_arp_timer();
326
  }
327
} /*** end of NetServerTask ***/
328
#endif /* BOOT_COM_NET_ENABLE > 0 */
329
330
331
/*********************************** end of net.c **************************************/