Contiki 3.x
raven-ipso.c
Go to the documentation of this file.
1 /* Copyright (c) 2008, Swedish Institute of Computer Science
2  * All rights reserved.
3  *
4  * All rights reserved.
5  *
6  * Redistribution and use in source and binary forms, with or without
7  * modification, are permitted provided that the following conditions are met:
8  *
9  * * Redistributions of source code must retain the above copyright
10  * notice, this list of conditions and the following disclaimer.
11  * * Redistributions in binary form must reproduce the above copyright
12  * notice, this list of conditions and the following disclaimer in
13  * the documentation and/or other materials provided with the
14  * distribution.
15  * * Neither the name of the copyright holders nor the names of
16  * contributors may be used to endorse or promote products derived
17  * from this software without specific prior written permission.
18  *
19  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
20  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22  * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
23  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
24  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
25  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
26  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
27  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
28  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29  * POSSIBILITY OF SUCH DAMAGE.
30  *
31  */
32 
33 /** \addtogroup avr-atmega128rfa1
34  * @{
35  */
36 
37 /**
38  * \defgroup ravenserial Serial interface between Raven processors
39  *
40  * \brief This module contains code to interface a Contiki-based
41  * project on the AVR Raven platform's ATMega1284P chip to the LCD
42  * driver chip (ATMega3290P) on the Raven.
43  *
44  * \author Durvy Mathilde <mdurvy@cisco.com>
45  *
46  * @{
47  */
48 
49 /**
50  * \file
51  * This file contains code to connect the two AVR Raven processors via
52  * a serial connection for the IPSO interop application
53  *
54  */
55 
56 #include "contiki.h"
57 #include "contiki-lib.h"
58 #include "contiki-net.h"
59 
60 #include "mac.h"
61 
62 #include "raven-lcd.h"
63 
64 #include <string.h>
65 #include <stdio.h>
66 
67 #define cmd_len 8
68 #define data_len 20
69 
70 static uint8_t seqno;
71 uip_ipaddr_t ping_addr;
72 uip_ipaddr_t udp_addr;
73 static struct uip_udp_conn *udp_conn;
74 char udp_data[data_len];
75 
76 static struct{
77  uint8_t frame[cmd_len];
78  uint8_t ndx;
79  uint8_t len;
80  uint8_t cmd;
81  uint8_t done;
82 } cmd;
83 
84 #define UIP_IP_BUF ((struct uip_ip_hdr *)&uip_buf[UIP_LLH_LEN])
85 #define UIP_ICMP_BUF ((struct uip_icmp_hdr *)&uip_buf[uip_l2_l3_hdr_len])
86 
87 void rs232_send(uint8_t port, unsigned char c);
88 
89 /*------------------------------------------------------------------*/
90 /* Sends a ping packet out the radio */
91 void
92 raven_ping6(void)
93 {
94 
95  /* ping ipv6.google.com*/
96  uip_ip6addr(&ping_addr,0x2001,0x420,0x5FFF,0x7D,0x2D0,0xB7FF,0xFE23,0xE6DB);
97  //uip_ip6addr(&ping_addr, 0x2001, 0x4860, 0, 0x2001, 0, 0, 0, 0x68);
98  //uip_ip6addr(&ping_addr, 0xaaaa, 0, 0, 0, 0, 0, 0, 1);
99 
100  UIP_IP_BUF->vtc = 0x60;
101  UIP_IP_BUF->tcflow = 1;
102  UIP_IP_BUF->flow = 0;
103  UIP_IP_BUF->proto = UIP_PROTO_ICMP6;
104 //UIP_IP_BUF->ttl = uip_netif_physical_if.cur_hop_limit;
105  UIP_IP_BUF->ttl = uip_ds6_if.cur_hop_limit;
106  uip_ipaddr_copy(&UIP_IP_BUF->destipaddr, &ping_addr);
107 //uip_netif_select_src(&UIP_IP_BUF->srcipaddr, &UIP_IP_BUF->destipaddr);
108  uip_ds6_select_src(&UIP_IP_BUF->srcipaddr, &UIP_IP_BUF->destipaddr);
110  UIP_ICMP_BUF->icode = 0;
111  /* set identifier and sequence number to 0 */
112  memset((void *)UIP_ICMP_BUF + UIP_ICMPH_LEN, 0, 4);
113 
114  uip_len = UIP_ICMPH_LEN + UIP_ICMP6_ECHO_REQUEST_LEN + UIP_IPH_LEN;
115  UIP_IP_BUF->len[0] = (uint8_t)((uip_len - 40) >> 8);
116  UIP_IP_BUF->len[1] = (uint8_t)((uip_len - 40) & 0x00FF);
117 
118  UIP_ICMP_BUF->icmpchksum = 0;
119  UIP_ICMP_BUF->icmpchksum = ~uip_icmp6chksum();
120 
122 }
123 
124 /*------------------------------------------------------------------*/
125 /* Send a serial command frame to the ATMega3290 Processsor on Raven
126  via serial port */
127 static void
128 send_frame(uint8_t cmd, uint8_t len, uint8_t *payload)
129 {
130  uint8_t i;
131 
132  rs232_send(0, SOF_CHAR); /* Start of Frame */
133  rs232_send(0, len);
134  rs232_send(0, cmd);
135  for (i=0;i<len;i++)
136  rs232_send(0,*payload++);
137  rs232_send(0, EOF_CHAR);
138 }
139 
140 /*------------------------------------------------------------------*/
141 static uint8_t
142 raven_gui_loop(process_event_t ev, process_data_t data)
143 {
144  if(ev == tcpip_icmp6_event) {
145  switch(*((uint8_t *)data)){
146  case ICMP6_ECHO_REQUEST:
147  /* We have received a ping request over the air. Tell 3290 */
148  send_frame(REPORT_PING_BEEP, 0, 0);
149  break;
150  case ICMP6_ECHO_REPLY:
151  /* We have received a ping reply over the air. Pass seqno to 3290 */
152  send_frame(REPORT_PING, 1, &seqno);
153  break;
154  }
155  } else {
156  switch(ev){
157  case SERIAL_CMD:
158  /* Check for command from serial port, execute it. */
159  if (cmd.done){
160  /* Execute the waiting command */
161  switch (cmd.cmd){
162  case SEND_PING:
163  /* Send ping request over the air */
164  seqno = cmd.frame[0];
165  raven_ping6();
166  break;
167  case SEND_TEMP:
168  /* Set temperature string in web server */
169  sprintf(udp_data, "T%s\r\n", (char *)cmd.frame);
170  uip_udp_packet_send(udp_conn, udp_data, data_len);
171  break;
172  default:
173  break;
174  }
175  /* Reset command done flag. */
176  cmd.done = 0;
177  }
178  break;
179  default:
180  break;
181  }
182  }
183  return 0;
184 }
185 
186 /*--------------------------------------------------------------------*/
187 /* Process an input character from serial port.
188  * ** This is called from an ISR!!
189  */
190 int raven_lcd_serial_input(unsigned char ch)
191 {
192  /* Parse frame, */
193  switch (cmd.ndx){
194  case 0:
195  /* first byte, must be 0x01 */
196  cmd.done = 0;
197  if (ch != 0x01){
198  return 0;
199  }
200  break;
201  case 1:
202  /* Second byte, length of payload */
203  cmd.len = ch;
204  break;
205  case 2:
206  /* Third byte, command byte */
207  cmd.cmd = ch;
208  break;
209  default:
210  /* Payload and ETX */
211  if (cmd.ndx >= cmd.len+3){
212  /* all done, check ETX */
213  if (ch == 0x04){
214  cmd.done = 1;
215  process_post(&raven_lcd_process, SERIAL_CMD, 0);
216  } else {
217  /* Failed ETX */
218  cmd.ndx = 0;
219  }
220  } else {
221  /* Just grab and store payload */
222  cmd.frame[cmd.ndx - 3] = ch;
223  }
224  break;
225  }
226 
227  cmd.ndx++;
228 
229  return 0;
230 }
231 
232 /*---------------------------------------------------------------------------*/
233 PROCESS(raven_lcd_process, "Raven LCD interface process");
234 PROCESS_THREAD(raven_lcd_process, ev, data)
235 {
236  uint8_t error;
237 
238  PROCESS_BEGIN();
239 
240  /*Create a udp connection to the IPSOserver*/
241 
242  //swisscom uip_ip6addr(&udp_addr,0x2001,918,0xfff9,0,0,0,0,1);
243  //HE uip_ip6addr(&udp_addr,0x2001,0x470,0x1f12,0x5ec,0x12,0x13ff,0xfe14,0x1516);
244  uip_ip6addr(&udp_addr,0x2001,0x420,0x5FFF,0x7D,0x2D0,0xB7FF,0xFE23,0xE6DB);
245 
246  /* set destination parameters*/
247  udp_conn = udp_new(&udp_addr, UIP_HTONS(0xF0B0), NULL);
248  /*set local port */
249  udp_bind(udp_conn, UIP_HTONS(0xF0B0+1));
250 
251  if((error = icmp6_new(NULL)) == 0) {
252  while(1) {
253  PROCESS_YIELD();
254  raven_gui_loop(ev, data);
255  }
256  }
257  PROCESS_END();
258 }
259 /** @} */
260 /** @} */
uip_len
The length of the packet in the uip_buf buffer.
Definition: tcp_loader.c:75
void tcpip_ipv6_output(void)
This function does address resolution and then calls tcpip_output.
Definition: tcpip.c:540
#define PROCESS_BEGIN()
Define the beginning of a process.
Definition: process.h:120
CCIF struct uip_udp_conn * udp_new(const uip_ipaddr_t *ripaddr, uint16_t port, void *appstate)
Create a new UDP connection.
#define ICMP6_ECHO_REPLY
Echo reply.
Definition: uip-icmp6.h:58
#define NULL
The null pointer.
#define SOF_CHAR
Start-of-frame character.
Definition: uart.h:49
#define UIP_HTONS(n)
Convert 16-bit quantity from host byte order to network byte order.
Definition: uip.h:1238
int process_post(struct process *p, process_event_t ev, process_data_t data)
Post an asynchronous event.
Definition: process.c:322
#define PROCESS_THREAD(name, ev, data)
Define the body of a process.
Definition: process.h:273
#define UIP_IP_BUF
Pointer to IP header.
Definition: uip-nd6.c:104
#define PROCESS_END()
Define the end of a process.
Definition: process.h:131
uint16_t uip_icmp6chksum(void)
Calculate the ICMP checksum of the packet in uip_buf.
Definition: uip6.c:387
#define uip_ipaddr_copy(dest, src)
Copy an IP address from one place to another.
Definition: uip.h:1026
#define ICMP6_ECHO_REQUEST
Echo request.
Definition: uip-icmp6.h:57
#define PROCESS(name, strname)
Declare a process.
Definition: process.h:307
void uip_ds6_select_src(uip_ipaddr_t *src, uip_ipaddr_t *dst)
Source address selection, see RFC 3484.
Definition: uip-ds6.c:497
#define UIP_ICMP_BUF
Pointer to ICMP header.
Definition: uip-nd6.c:105
#define PROCESS_YIELD()
Yield the currently running process.
Definition: process.h:164
#define EOF_CHAR
End-of-frame character.
Definition: uart.h:50
#define udp_bind(conn, port)
Bind a UDP connection to a local port.
Definition: tcpip.h:262
Representation of a uIP UDP connection.
Definition: uip.h:1394
#define uip_ip6addr(addr, addr0, addr1, addr2, addr3, addr4, addr5, addr6, addr7)
Construct an IPv6 address from eight 16-bit words.
Definition: uip.h:969
void rs232_send(uint8_t port, unsigned char c)
Print a character on RS232.
Definition: rs232.c:325
MAC driver header file
#define UIP_ICMP6_ECHO_REQUEST_LEN
Echo Request constant part length.
Definition: uip-icmp6.h:99