Contiki 2.5
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 /**
34  * \brief This module contains code to interface a Contiki-based
35  * project on the AVR Raven platform's ATMega1284P chip to the LCD
36  * driver chip (ATMega3290P) on the Raven.
37  *
38  * \author Durvy Mathilde <mdurvy@cisco.com>
39  *
40  */
41 
42 /** \addtogroup raven
43  * @{
44  */
45 
46 /**
47  * \defgroup ravenserial Serial interface between Raven processors
48  * @{
49  */
50 
51 /**
52  * \file
53  * This file contains code to connect the two AVR Raven processors via
54  * a serial connection for the IPSO interop application
55  *
56  */
57 
58 #include "contiki.h"
59 #include "contiki-lib.h"
60 #include "contiki-net.h"
61 
62 #include "mac.h"
63 
64 #include "raven-lcd.h"
65 
66 #include <string.h>
67 #include <stdio.h>
68 
69 #define cmd_len 8
70 #define data_len 20
71 
72 static u8_t seqno;
73 uip_ipaddr_t ping_addr;
74 uip_ipaddr_t udp_addr;
75 static struct uip_udp_conn *udp_conn;
76 char udp_data[data_len];
77 
78 static struct{
79  u8_t frame[cmd_len];
80  u8_t ndx;
81  u8_t len;
82  u8_t cmd;
83  u8_t done;
84 } cmd;
85 
86 #define UIP_IP_BUF ((struct uip_ip_hdr *)&uip_buf[UIP_LLH_LEN])
87 #define UIP_ICMP_BUF ((struct uip_icmp_hdr *)&uip_buf[uip_l2_l3_hdr_len])
88 
89 void rs232_send(uint8_t port, unsigned char c);
90 
91 /*------------------------------------------------------------------*/
92 /* Sends a ping packet out the radio */
93 void
94 raven_ping6(void)
95 {
96 
97  /* ping ipv6.google.com*/
98  uip_ip6addr(&ping_addr,0x2001,0x420,0x5FFF,0x7D,0x2D0,0xB7FF,0xFE23,0xE6DB);
99  //uip_ip6addr(&ping_addr, 0x2001, 0x4860, 0, 0x2001, 0, 0, 0, 0x68);
100  //uip_ip6addr(&ping_addr, 0xaaaa, 0, 0, 0, 0, 0, 0, 1);
101 
102  UIP_IP_BUF->vtc = 0x60;
103  UIP_IP_BUF->tcflow = 1;
104  UIP_IP_BUF->flow = 0;
105  UIP_IP_BUF->proto = UIP_PROTO_ICMP6;
106 //UIP_IP_BUF->ttl = uip_netif_physical_if.cur_hop_limit;
107  UIP_IP_BUF->ttl = uip_ds6_if.cur_hop_limit;
108  uip_ipaddr_copy(&UIP_IP_BUF->destipaddr, &ping_addr);
109 //uip_netif_select_src(&UIP_IP_BUF->srcipaddr, &UIP_IP_BUF->destipaddr);
110  uip_ds6_select_src(&UIP_IP_BUF->srcipaddr, &UIP_IP_BUF->destipaddr);
112  UIP_ICMP_BUF->icode = 0;
113  /* set identifier and sequence number to 0 */
114  memset((void *)UIP_ICMP_BUF + UIP_ICMPH_LEN, 0, 4);
115 
116  uip_len = UIP_ICMPH_LEN + UIP_ICMP6_ECHO_REQUEST_LEN + UIP_IPH_LEN;
117  UIP_IP_BUF->len[0] = (u8_t)((uip_len - 40) >> 8);
118  UIP_IP_BUF->len[1] = (u8_t)((uip_len - 40) & 0x00FF);
119 
120  UIP_ICMP_BUF->icmpchksum = 0;
121  UIP_ICMP_BUF->icmpchksum = ~uip_icmp6chksum();
122 
123  tcpip_ipv6_output();
124 }
125 
126 /*------------------------------------------------------------------*/
127 /* Send a serial command frame to the ATMega3290 Processsor on Raven
128  via serial port */
129 static void
130 send_frame(uint8_t cmd, uint8_t len, uint8_t *payload)
131 {
132  uint8_t i;
133 
134  rs232_send(0, SOF_CHAR); /* Start of Frame */
135  rs232_send(0, len);
136  rs232_send(0, cmd);
137  for (i=0;i<len;i++)
138  rs232_send(0,*payload++);
139  rs232_send(0, EOF_CHAR);
140 }
141 
142 /*------------------------------------------------------------------*/
143 static u8_t
144 raven_gui_loop(process_event_t ev, process_data_t data)
145 {
146  if(ev == tcpip_icmp6_event) {
147  switch(*((uint8_t *)data)){
148  case ICMP6_ECHO_REQUEST:
149  /* We have received a ping request over the air. Tell 3290 */
150  send_frame(REPORT_PING_BEEP, 0, 0);
151  break;
152  case ICMP6_ECHO_REPLY:
153  /* We have received a ping reply over the air. Pass seqno to 3290 */
154  send_frame(REPORT_PING, 1, &seqno);
155  break;
156  }
157  } else {
158  switch(ev){
159  case SERIAL_CMD:
160  /* Check for command from serial port, execute it. */
161  if (cmd.done){
162  /* Execute the waiting command */
163  switch (cmd.cmd){
164  case SEND_PING:
165  /* Send ping request over the air */
166  seqno = cmd.frame[0];
167  raven_ping6();
168  break;
169  case SEND_TEMP:
170  /* Set temperature string in web server */
171  sprintf(udp_data, "T%s\r\n", (char *)cmd.frame);
172  uip_udp_packet_send(udp_conn, udp_data, data_len);
173  break;
174  default:
175  break;
176  }
177  /* Reset command done flag. */
178  cmd.done = 0;
179  }
180  break;
181  default:
182  break;
183  }
184  }
185  return 0;
186 }
187 
188 /*--------------------------------------------------------------------*/
189 /* Process an input character from serial port.
190  * ** This is called from an ISR!!
191  */
192 int raven_lcd_serial_input(unsigned char ch)
193 {
194  /* Parse frame, */
195  switch (cmd.ndx){
196  case 0:
197  /* first byte, must be 0x01 */
198  cmd.done = 0;
199  if (ch != 0x01){
200  return 0;
201  }
202  break;
203  case 1:
204  /* Second byte, length of payload */
205  cmd.len = ch;
206  break;
207  case 2:
208  /* Third byte, command byte */
209  cmd.cmd = ch;
210  break;
211  default:
212  /* Payload and ETX */
213  if (cmd.ndx >= cmd.len+3){
214  /* all done, check ETX */
215  if (ch == 0x04){
216  cmd.done = 1;
217  process_post(&raven_lcd_process, SERIAL_CMD, 0);
218  } else {
219  /* Failed ETX */
220  cmd.ndx = 0;
221  }
222  } else {
223  /* Just grab and store payload */
224  cmd.frame[cmd.ndx - 3] = ch;
225  }
226  break;
227  }
228 
229  cmd.ndx++;
230 
231  return 0;
232 }
233 
234 /*---------------------------------------------------------------------------*/
235 PROCESS(raven_lcd_process, "Raven LCD interface process");
236 PROCESS_THREAD(raven_lcd_process, ev, data)
237 {
238  u8_t error;
239 
240  PROCESS_BEGIN();
241 
242  /*Create a udp connection to the IPSOserver*/
243 
244  //swisscom uip_ip6addr(&udp_addr,0x2001,918,0xfff9,0,0,0,0,1);
245  //HE uip_ip6addr(&udp_addr,0x2001,0x470,0x1f12,0x5ec,0x12,0x13ff,0xfe14,0x1516);
246  uip_ip6addr(&udp_addr,0x2001,0x420,0x5FFF,0x7D,0x2D0,0xB7FF,0xFE23,0xE6DB);
247 
248  /* set destination parameters*/
249  udp_conn = udp_new(&udp_addr, UIP_HTONS(0xF0B0), NULL);
250  /*set local port */
251  udp_bind(udp_conn, UIP_HTONS(0xF0B0+1));
252 
253  if((error = icmp6_new(NULL)) == 0) {
254  while(1) {
255  PROCESS_YIELD();
256  raven_gui_loop(ev, data);
257  }
258  }
259  PROCESS_END();
260 }
261 /** @} */
262 /** @} */