Subversion Repositories svn.mios32

Rev

Rev 1118 | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
371 tk 1
// $Id: uip_task.c 2425 2016-11-03 00:44:22Z tk $
2
/*
3
 * uIP handler as FreeRTOS task
4
 *
5
 * Framework taken from $MIOS32_PATH/modules/uip/doc/example-mainloop-with-arp.c
6
 *
7
 * ==========================================================================
8
 *
9
 *  Copyright (C) 2009 Thorsten Klose (tk@midibox.org)
10
 *  Licensed for personal non-commercial use only.
11
 *  All other rights reserved.
12
 *
13
 * ==========================================================================
14
 */
15
 
16
/////////////////////////////////////////////////////////////////////////////
17
// Include files
18
/////////////////////////////////////////////////////////////////////////////
19
#include <mios32.h>
20
 
21
#include <FreeRTOS.h>
22
#include <task.h>
23
#include <queue.h>
24
 
25
#include "uip.h"
26
#include "uip_arp.h"
27
#include "network-device.h"
28
#include "timer.h"
29
 
382 tk 30
#include "uip_task.h"
371 tk 31
 
382 tk 32
#include "osc_server.h"
33
#include "osc_client.h"
817 tk 34
#include "dhcpc.h"
382 tk 35
 
36
 
371 tk 37
/////////////////////////////////////////////////////////////////////////////
38
// Task Priorities
39
/////////////////////////////////////////////////////////////////////////////
40
 
41
// lower priority than MIOS32 hooks
42
#define PRIORITY_TASK_UIP       ( tskIDLE_PRIORITY + 2 )
43
 
44
 
382 tk 45
// for mutual exclusive access to uIP functions
46
// The mutex is handled with MUTEX_UIP_TAKE and MUTEX_UIP_GIVE macros
47
xSemaphoreHandle xUIPSemaphore;
48
 
49
 
371 tk 50
/////////////////////////////////////////////////////////////////////////////
51
// Local defines
52
/////////////////////////////////////////////////////////////////////////////
53
 
54
#define BUF ((struct uip_eth_hdr *)&uip_buf[0])
55
 
56
 
57
/////////////////////////////////////////////////////////////////////////////
58
// Local prototypes
59
/////////////////////////////////////////////////////////////////////////////
60
static void UIP_TASK_Handler(void *pvParameters);
817 tk 61
static s32 UIP_TASK_StartServices(void);
62
static s32 UIP_TASK_SendDebugMessage_IP(void);
371 tk 63
 
64
 
65
/////////////////////////////////////////////////////////////////////////////
817 tk 66
// Local variables
67
/////////////////////////////////////////////////////////////////////////////
68
static u8 services_running;
69
 
70
 
71
/////////////////////////////////////////////////////////////////////////////
371 tk 72
// Initialize the uIP task
73
/////////////////////////////////////////////////////////////////////////////
74
s32 UIP_TASK_Init(u32 mode)
75
{
76
  if( mode > 0 )
77
    return -1; // only mode 0 supported yet
78
 
817 tk 79
  xUIPSemaphore = xSemaphoreCreateRecursiveMutex();
382 tk 80
 
2425 tk 81
  xTaskCreate(UIP_TASK_Handler, "uIP", configMINIMAL_STACK_SIZE, NULL, PRIORITY_TASK_UIP, NULL);
371 tk 82
 
817 tk 83
  services_running = 0;
84
 
371 tk 85
  return 0; // no error
86
}
87
 
88
 
89
/////////////////////////////////////////////////////////////////////////////
90
// The uIP Task is executed each mS
91
/////////////////////////////////////////////////////////////////////////////
92
static void UIP_TASK_Handler(void *pvParameters)
93
{
94
  int i;
95
  struct timer periodic_timer, arp_timer;
96
 
97
  // Initialise the xLastExecutionTime variable on task entry
98
  portTickType xLastExecutionTime = xTaskGetTickCount();
99
 
382 tk 100
  // take over exclusive access to UIP functions
101
  MUTEX_UIP_TAKE;
102
 
371 tk 103
  // init uIP timers
104
  timer_set(&periodic_timer, CLOCK_SECOND / 2);
105
  timer_set(&arp_timer, CLOCK_SECOND * 10);
106
 
107
  // init the network driver
108
  network_device_init();
109
 
110
  // init uIP
111
  uip_init();
817 tk 112
  uip_arp_init();
371 tk 113
 
114
  // set my ethernet address
387 tk 115
  unsigned char *mac_addr = network_device_mac_addr();
116
  {
117
    int i;
118
    for(i=0; i<6; ++i)
119
      uip_ethaddr.addr[i] = mac_addr[i];
120
  }
371 tk 121
 
817 tk 122
#ifndef DONT_USE_DHCP
123
  dhcpc_init(uip_ethaddr.addr, sizeof(uip_ethaddr.addr));
124
  MIOS32_MIDI_SendDebugMessage("[UIP_TASK] DHCP Client requests the IP settings...\n");
125
#else
1118 tk 126
  uip_ipaddr_t ipaddr;
371 tk 127
  // set my IP address
387 tk 128
  uip_ipaddr(ipaddr,
129
         ((MY_IP_ADDRESS)>>24) & 0xff,
130
         ((MY_IP_ADDRESS)>>16) & 0xff,
131
         ((MY_IP_ADDRESS)>> 8) & 0xff,
132
         ((MY_IP_ADDRESS)>> 0) & 0xff);
371 tk 133
  uip_sethostaddr(ipaddr);
387 tk 134
 
135
  // set my netmask
136
  uip_ipaddr(ipaddr,
137
         ((MY_NETMASK)>>24) & 0xff,
138
         ((MY_NETMASK)>>16) & 0xff,
139
         ((MY_NETMASK)>> 8) & 0xff,
140
         ((MY_NETMASK)>> 0) & 0xff);
371 tk 141
  uip_setnetmask(ipaddr);
142
 
143
  // default router
387 tk 144
  uip_ipaddr(ipaddr,
145
         ((MY_GATEWAY)>>24) & 0xff,
146
         ((MY_GATEWAY)>>16) & 0xff,
147
         ((MY_GATEWAY)>> 8) & 0xff,
148
         ((MY_GATEWAY)>> 0) & 0xff);
371 tk 149
  uip_setdraddr(ipaddr);
150
 
817 tk 151
  MIOS32_MIDI_SendDebugMessage("[UIP_TASK] IP Address statically set:\n");
371 tk 152
 
817 tk 153
  // start services immediately
154
  UIP_TASK_StartServices();
155
#endif
371 tk 156
 
817 tk 157
 
382 tk 158
  // release exclusive access to UIP functions
159
  MUTEX_UIP_GIVE;
160
 
371 tk 161
  // endless loop
162
  while( 1 ) {
163
    vTaskDelayUntil(&xLastExecutionTime, 1 / portTICK_RATE_MS);
164
 
382 tk 165
    // take over exclusive access to UIP functions
166
    MUTEX_UIP_TAKE;
167
 
371 tk 168
    if( !(clock_time_tick() % 100) ) {
169
      // each 100 mS: check availablility of network device
170
      network_device_check();
171
    }
172
 
173
    if( network_device_available() ) {
174
      uip_len = network_device_read();
175
 
176
      if( uip_len > 0 ) {
177
    if(BUF->type == htons(UIP_ETHTYPE_IP) ) {
178
      uip_arp_ipin();
179
      uip_input();
180
 
181
      /* If the above function invocation resulted in data that
182
         should be sent out on the network, the global variable
183
         uip_len is set to a value > 0. */
184
      if( uip_len > 0 ) {
185
        uip_arp_out();
186
        network_device_send();
187
      }
188
    } else if(BUF->type == htons(UIP_ETHTYPE_ARP)) {
189
      uip_arp_arpin();
190
      /* If the above function invocation resulted in data that
191
         should be sent out on the network, the global variable
192
         uip_len is set to a value > 0. */
193
      if(uip_len > 0) {
194
        network_device_send();
195
      }
196
    }
197
 
198
      } else if(timer_expired(&periodic_timer)) {
199
    timer_reset(&periodic_timer);
200
    for(i = 0; i < UIP_CONNS; i++) {
201
      uip_periodic(i);
202
      /* If the above function invocation resulted in data that
203
         should be sent out on the network, the global variable
204
         uip_len is set to a value > 0. */
205
      if(uip_len > 0) {
206
        uip_arp_out();
207
        network_device_send();
208
      }
209
    }
210
 
211
#if UIP_UDP
212
    for(i = 0; i < UIP_UDP_CONNS; i++) {
213
      uip_udp_periodic(i);
214
      /* If the above function invocation resulted in data that
215
         should be sent out on the network, the global variable
216
         uip_len is set to a value > 0. */
217
      if(uip_len > 0) {
218
        uip_arp_out();
219
        network_device_send();
220
      }
221
    }
222
#endif /* UIP_UDP */
223
 
224
    /* Call the ARP timer function every 10 seconds. */
225
    if(timer_expired(&arp_timer)) {
226
      timer_reset(&arp_timer);
227
      uip_arp_timer();
228
    }
229
      }
230
    }
382 tk 231
 
232
    // release exclusive access to UIP functions
233
    MUTEX_UIP_GIVE;
371 tk 234
  }
235
}
236
 
237
 
817 tk 238
/////////////////////////////////////////////////////////////////////////////
239
// used by uIP to print a debug message
240
/////////////////////////////////////////////////////////////////////////////
371 tk 241
void uip_log(char *msg)
242
{
243
  MIOS32_MIDI_SendDebugMessage(msg);
244
}
245
 
246
 
817 tk 247
/////////////////////////////////////////////////////////////////////////////
248
// Prints current IP settings
249
/////////////////////////////////////////////////////////////////////////////
250
static s32 UIP_TASK_SendDebugMessage_IP(void)
251
{
252
  uip_ipaddr_t ipaddr;
253
  uip_gethostaddr(&ipaddr);
254
 
255
  MIOS32_MIDI_SendDebugMessage("[UIP_TASK] IP address: %d.%d.%d.%d\n",
256
                   uip_ipaddr1(ipaddr), uip_ipaddr2(ipaddr),
257
                   uip_ipaddr3(ipaddr), uip_ipaddr4(ipaddr));
258
 
259
  uip_ipaddr_t netmask;
260
  uip_getnetmask(&netmask);
261
  MIOS32_MIDI_SendDebugMessage("[UIP_TASK] Netmask: %d.%d.%d.%d\n",
262
                   uip_ipaddr1(netmask), uip_ipaddr2(netmask),
263
                   uip_ipaddr3(netmask), uip_ipaddr4(netmask));
264
 
265
  uip_ipaddr_t draddr;
266
  uip_getdraddr(&draddr);
267
  MIOS32_MIDI_SendDebugMessage("[UIP_TASK] Default Router (Gateway): %d.%d.%d.%d\n",
268
                   uip_ipaddr1(draddr), uip_ipaddr2(draddr),
269
                   uip_ipaddr3(draddr), uip_ipaddr4(draddr));
270
 
271
  return 0; // no error
272
}
273
 
274
 
275
/////////////////////////////////////////////////////////////////////////////
276
// start services
277
/////////////////////////////////////////////////////////////////////////////
278
static s32 UIP_TASK_StartServices(void)
279
{
280
  // print IP settings
281
  UIP_TASK_SendDebugMessage_IP();
282
 
283
  // start telnet daemon
284
  telnetd_init();
285
 
286
  // start OSC daemon and client
287
  OSC_CLIENT_Init(0);
288
  OSC_SERVER_Init(0);
289
 
290
  // services available now
291
  services_running = 1;
292
 
293
  return 0; // no error
294
}
295
 
296
 
297
/////////////////////////////////////////////////////////////////////////////
298
// Status flag for external functions
299
/////////////////////////////////////////////////////////////////////////////
300
s32 UIP_TASK_ServicesRunning(void)
301
{
302
  return services_running;
303
}
304
 
305
 
306
/////////////////////////////////////////////////////////////////////////////
307
// Called by UDP handler of uIP
308
/////////////////////////////////////////////////////////////////////////////
309
s32 UIP_TASK_UDP_AppCall(void)
310
{
311
  // DHCP client
312
  if( uip_udp_conn->rport == HTONS(DHCPC_SERVER_PORT) || uip_udp_conn->rport == HTONS(DHCPC_CLIENT_PORT) ) {
313
    dhcpc_appcall();
314
 
315
  // OSC Server
316
  } else if( uip_udp_conn->rport == HTONS(OSC_SERVER_PORT) ) {
317
    OSC_SERVER_AppCall();
318
  }
319
 
320
  return 0; // no error
321
}
322
 
323
 
324
/////////////////////////////////////////////////////////////////////////////
325
// Called by DHCP client once it got IP addresses
326
/////////////////////////////////////////////////////////////////////////////
327
void dhcpc_configured(const struct dhcpc_state *s)
328
{
329
  // set IP settings
330
  uip_sethostaddr(s->ipaddr);
331
  uip_setnetmask(s->netmask);
332
  uip_setdraddr(s->default_router);
333
 
334
  // start services
335
  UIP_TASK_StartServices();
336
 
337
  // print unused settings
338
  MIOS32_MIDI_SendDebugMessage("[UIP_TASK] Got DNS server %d.%d.%d.%d\n",
339
                   uip_ipaddr1(s->dnsaddr), uip_ipaddr2(s->dnsaddr),
340
                   uip_ipaddr3(s->dnsaddr), uip_ipaddr4(s->dnsaddr));
341
  MIOS32_MIDI_SendDebugMessage("[UIP_TASK] Lease expires in %d hours\n",
342
                   (ntohs(s->lease_time[0])*65536ul + ntohs(s->lease_time[1]))/3600);
343
}