Contiki 2.6

raven-ipso.c

Go to the documentation of this file.
00001 /*   Copyright (c) 2008, Swedish Institute of Computer Science
00002  *  All rights reserved.
00003  *
00004  *   All rights reserved.
00005  *
00006  *   Redistribution and use in source and binary forms, with or without
00007  *   modification, are permitted provided that the following conditions are met:
00008  *
00009  *   * Redistributions of source code must retain the above copyright
00010  *     notice, this list of conditions and the following disclaimer.
00011  *   * Redistributions in binary form must reproduce the above copyright
00012  *     notice, this list of conditions and the following disclaimer in
00013  *     the documentation and/or other materials provided with the
00014  *     distribution.
00015  *   * Neither the name of the copyright holders nor the names of
00016  *     contributors may be used to endorse or promote products derived
00017  *     from this software without specific prior written permission.
00018  *
00019  *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
00020  *  AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
00021  *  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
00022  *  ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
00023  *  LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
00024  *  CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
00025  *  SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
00026  *  INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
00027  *  CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
00028  *  ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
00029  *  POSSIBILITY OF SUCH DAMAGE.
00030  *
00031  */
00032 
00033 /**
00034  *  \brief This module contains code to interface a Contiki-based
00035  *  project on the AVR Raven platform's ATMega1284P chip to the LCD
00036  *  driver chip (ATMega3290P) on the Raven.
00037  *  
00038  *  \author Durvy Mathilde <mdurvy@cisco.com>
00039  *
00040  */
00041 
00042 /**  \addtogroup raven
00043  * @{ 
00044  */
00045 
00046 /**
00047  *  \defgroup ravenserial Serial interface between Raven processors
00048  * @{
00049  */
00050 
00051 /**
00052  *  \file
00053  *  This file contains code to connect the two AVR Raven processors via
00054  *  a serial connection for the IPSO interop application
00055  *
00056  */
00057 
00058 #include "contiki.h"
00059 #include "contiki-lib.h"
00060 #include "contiki-net.h"
00061 
00062 #include "mac.h"
00063 
00064 #include "raven-lcd.h"
00065 
00066 #include <string.h>
00067 #include <stdio.h>
00068 
00069 #define cmd_len 8
00070 #define data_len 20
00071 
00072 static uint8_t seqno;
00073 uip_ipaddr_t ping_addr;
00074 uip_ipaddr_t udp_addr;
00075 static struct uip_udp_conn *udp_conn;
00076 char udp_data[data_len];
00077 
00078 static struct{
00079   uint8_t frame[cmd_len];
00080   uint8_t ndx;
00081   uint8_t len;
00082   uint8_t cmd;
00083   uint8_t done;
00084 } cmd;
00085 
00086 #define UIP_IP_BUF   ((struct uip_ip_hdr *)&uip_buf[UIP_LLH_LEN])
00087 #define UIP_ICMP_BUF ((struct uip_icmp_hdr *)&uip_buf[uip_l2_l3_hdr_len])
00088 
00089 void rs232_send(uint8_t port, unsigned char c);
00090 
00091 /*------------------------------------------------------------------*/
00092 /* Sends a ping packet out the radio */
00093 void
00094 raven_ping6(void)
00095 {
00096    
00097   /* ping ipv6.google.com*/
00098   uip_ip6addr(&ping_addr,0x2001,0x420,0x5FFF,0x7D,0x2D0,0xB7FF,0xFE23,0xE6DB);
00099   //uip_ip6addr(&ping_addr, 0x2001, 0x4860, 0, 0x2001, 0, 0, 0, 0x68);
00100   //uip_ip6addr(&ping_addr, 0xaaaa, 0, 0, 0, 0, 0, 0, 1);
00101   
00102   UIP_IP_BUF->vtc = 0x60;
00103   UIP_IP_BUF->tcflow = 1;
00104   UIP_IP_BUF->flow = 0;
00105   UIP_IP_BUF->proto = UIP_PROTO_ICMP6;
00106 //UIP_IP_BUF->ttl = uip_netif_physical_if.cur_hop_limit;
00107   UIP_IP_BUF->ttl = uip_ds6_if.cur_hop_limit;
00108   uip_ipaddr_copy(&UIP_IP_BUF->destipaddr, &ping_addr);
00109 //uip_netif_select_src(&UIP_IP_BUF->srcipaddr, &UIP_IP_BUF->destipaddr);
00110   uip_ds6_select_src(&UIP_IP_BUF->srcipaddr, &UIP_IP_BUF->destipaddr); 
00111   UIP_ICMP_BUF->type = ICMP6_ECHO_REQUEST;
00112   UIP_ICMP_BUF->icode = 0;
00113   /* set identifier and sequence number to 0 */
00114   memset((void *)UIP_ICMP_BUF + UIP_ICMPH_LEN, 0, 4);
00115     
00116   uip_len = UIP_ICMPH_LEN + UIP_ICMP6_ECHO_REQUEST_LEN + UIP_IPH_LEN;
00117   UIP_IP_BUF->len[0] = (uint8_t)((uip_len - 40) >> 8);
00118   UIP_IP_BUF->len[1] = (uint8_t)((uip_len - 40) & 0x00FF);
00119     
00120   UIP_ICMP_BUF->icmpchksum = 0;
00121   UIP_ICMP_BUF->icmpchksum = ~uip_icmp6chksum();
00122     
00123   tcpip_ipv6_output();
00124 }
00125 
00126 /*------------------------------------------------------------------*/
00127 /* Send a serial command frame to the ATMega3290 Processsor on Raven
00128    via serial port */
00129 static void
00130 send_frame(uint8_t cmd, uint8_t len, uint8_t *payload)
00131 {
00132   uint8_t i;
00133 
00134   rs232_send(0, SOF_CHAR);    /* Start of Frame */
00135   rs232_send(0, len);
00136   rs232_send(0, cmd);
00137   for (i=0;i<len;i++)
00138     rs232_send(0,*payload++);
00139   rs232_send(0, EOF_CHAR);
00140 }
00141 
00142 /*------------------------------------------------------------------*/
00143 static uint8_t
00144 raven_gui_loop(process_event_t ev, process_data_t data)
00145 {
00146   if(ev == tcpip_icmp6_event) {
00147     switch(*((uint8_t *)data)){
00148     case ICMP6_ECHO_REQUEST:
00149       /* We have received a ping request over the air. Tell 3290 */
00150       send_frame(REPORT_PING_BEEP, 0, 0);
00151       break;
00152     case ICMP6_ECHO_REPLY:
00153       /* We have received a ping reply over the air. Pass seqno to 3290 */
00154       send_frame(REPORT_PING, 1, &seqno);
00155       break;
00156     }
00157   } else {
00158     switch(ev){
00159     case SERIAL_CMD:        
00160       /* Check for command from serial port, execute it. */
00161       if (cmd.done){
00162         /* Execute the waiting command */
00163         switch (cmd.cmd){
00164           case SEND_PING:
00165             /* Send ping request over the air */
00166             seqno = cmd.frame[0];
00167             raven_ping6();
00168             break;
00169           case SEND_TEMP:
00170             /* Set temperature string in web server */
00171             sprintf(udp_data, "T%s\r\n", (char *)cmd.frame);
00172             uip_udp_packet_send(udp_conn, udp_data, data_len);
00173             break;
00174           default:
00175             break;
00176         }
00177         /* Reset command done flag. */
00178         cmd.done = 0;
00179       }
00180       break;
00181     default:
00182       break;
00183     }
00184   }
00185   return 0;
00186 }
00187 
00188 /*--------------------------------------------------------------------*/
00189 /* Process an input character from serial port.  
00190  * ** This is called from an ISR!!
00191  */
00192 int raven_lcd_serial_input(unsigned char ch)
00193 {
00194   /* Parse frame,  */
00195   switch (cmd.ndx){
00196     case 0:
00197       /* first byte, must be 0x01 */
00198       cmd.done = 0;
00199       if (ch != 0x01){
00200         return 0;
00201       }
00202       break;
00203     case 1: 
00204       /* Second byte, length of payload */
00205       cmd.len = ch;
00206       break;
00207     case 2:
00208       /* Third byte, command byte */
00209       cmd.cmd = ch;
00210       break;
00211     default:
00212       /* Payload and ETX */
00213       if (cmd.ndx >= cmd.len+3){
00214         /* all done, check ETX */
00215         if (ch == 0x04){
00216           cmd.done = 1;
00217           process_post(&raven_lcd_process, SERIAL_CMD, 0);
00218         } else {
00219           /* Failed ETX */
00220           cmd.ndx = 0;
00221         }
00222       } else {
00223         /* Just grab and store payload */
00224         cmd.frame[cmd.ndx - 3] = ch;
00225       }
00226       break;
00227   }
00228 
00229   cmd.ndx++;
00230 
00231   return 0;
00232 }
00233 
00234 /*---------------------------------------------------------------------------*/
00235 PROCESS(raven_lcd_process, "Raven LCD interface process");
00236 PROCESS_THREAD(raven_lcd_process, ev, data)
00237 {
00238   uint8_t error;
00239 
00240   PROCESS_BEGIN();
00241 
00242   /*Create a udp connection to the IPSOserver*/
00243 
00244   //swisscom uip_ip6addr(&udp_addr,0x2001,918,0xfff9,0,0,0,0,1); 
00245   //HE uip_ip6addr(&udp_addr,0x2001,0x470,0x1f12,0x5ec,0x12,0x13ff,0xfe14,0x1516);
00246   uip_ip6addr(&udp_addr,0x2001,0x420,0x5FFF,0x7D,0x2D0,0xB7FF,0xFE23,0xE6DB);
00247   
00248   /* set destination parameters*/
00249   udp_conn = udp_new(&udp_addr, UIP_HTONS(0xF0B0), NULL);
00250   /*set local port */
00251   udp_bind(udp_conn, UIP_HTONS(0xF0B0+1));
00252   
00253   if((error = icmp6_new(NULL)) == 0) {
00254     while(1) {
00255       PROCESS_YIELD();
00256       raven_gui_loop(ev, data);
00257     } 
00258   }
00259   PROCESS_END();
00260 }
00261 /** @} */
00262 /** @} */