0

我正在尝试在 contiki3.0 中构建一个应用程序,其中几个节点在将其写入日志时广播其传感器数据,然后每 3 分钟将日志发送到接收器并启动一个新日志。我还希望接收器确认接收到日志。

我一直在尝试这样做一个月,但我无法让代码正常工作,我将不胜感激。这是节点的代码:

#include "contiki-conf.h"
#include "dev/button-sensor.h"
#include "dev/light-sensor.h"
#include "dev/leds.h"
#include "net/linkaddr.h"
#include "contiki.h"
#include "lib/random.h"
#include "sys/ctimer.h"
#include "sys/etimer.h"
#include "net/ip/uip.h"
#include "net/ipv6/uip-ds6.h"
#include "event-post.h"
#include "simple-udp.h"
#include <limits.h>

#include <stdio.h>
#include <string.h>

#define UDP_PORT 1234

#define SEND_INTERVAL   (20 * CLOCK_SECOND)
#define SEND_TIME   (random_rand() % (SEND_INTERVAL))
/*---------------------------------------------------------------------------*/

static struct simple_udp_connection broadcast_connection;
static process_event_t event_data_ready;
/*---------------------------------------------------------------------------*/
PROCESS(sara, "broadcast");
PROCESS(broadcast_example_process, "BB");
AUTOSTART_PROCESSES(&sara, &broadcast_example_process);
/*---------------------------------------------------------------------------*/


PROCESS_THREAD(sara, ev, data)
{ 
  static struct etimer timer;
  static struct event_struct es;

  PROCESS_BEGIN();
   es.s_val = SHRT_MAX-2;
   es.i_val = INT_MAX-2;
   es.l_val = LONG_MAX-2;
    /* sizeof(long long) == sizeof(long) on sensinodes - see other examples*/
   es.ll_val = LONG_MAX-2;
    /* and some typedef-ed unsigned variables */
   es.u8_val = UCHAR_MAX-2;
   es.u16_val = USHRT_MAX-2;
   es.u32_val = ULONG_MAX-2;
   event_data_ready = process_alloc_event();
    printf("Contiki allocated event ID %d.\r\n", event_data_ready);
    etimer_set(&timer, CLOCK_CONF_SECOND * 2);
    while(1){
        printf("Sensor process: Wait for timer event...\r\n");
        /* Wait on our timer */
        PROCESS_WAIT_EVENT_UNTIL(ev == PROCESS_EVENT_TIMER);

        /* blip */
        /* leds_toggle(LEDS_BLUE); */

        /* Set the 'sensor' value before throwing the event */
        printf("Sensor Process: Incrementing values...%d,%d,%d,%d,%d,%d, %d\r\n", es.s_val++, es.i_val++, es.l_val++, es.ll_val++, es.u8_val++, es.u16_val++,es.u32_val++);

        /* Post our event.
         * N.B. es is declared static.
         * Try passing a volatile variable and observe the results... */
        printf("Sensor Process: Generating 'Data Ready' event.\r\n");
        process_post(&broadcast_example_process, event_data_ready, &es);

        /* reset the timer so we can wait on it again */
        etimer_reset(&timer);
    }
  SENSORS_ACTIVATE(button_sensor);
  SENSORS_ACTIVATE(light_sensor);
  static  int counter=0;

printf("Light: \%u\n", light_sensor);

counter++;
if (counter == 4){

printf("Hello, world you have read the light 4 times \n");


}

  PROCESS_END();
}

static void
receiver(struct simple_udp_connection *c,
         const uip_ipaddr_t *sender_addr,
         uint16_t sender_port,
         const uip_ipaddr_t *receiver_addr,
         uint16_t receiver_port,
         const uint8_t *data,
         uint16_t datalen)


{
  printf("Data received on port %d from port %d with length %d\n",
         receiver_port, sender_port, datalen);
}


/*---------------------------------------------------------------------------*/
PROCESS_THREAD(broadcast_example_process, ev, data)
{
  static struct etimer periodic_timer;
  static struct etimer send_timer;
  uip_ipaddr_t addr;

  PROCESS_BEGIN();

  simple_udp_register(&broadcast_connection, UDP_PORT,
                      NULL, UDP_PORT,
                      receiver);

  etimer_set(&periodic_timer, SEND_INTERVAL);
  while(1) {
    PROCESS_WAIT_EVENT_UNTIL(etimer_expired(&periodic_timer));
    etimer_reset(&periodic_timer);
    etimer_set(&send_timer, SEND_TIME);

    PROCESS_WAIT_EVENT_UNTIL(etimer_expired(&send_timer));
    printf("Sending broadcast\n");
    uip_create_linklocal_allnodes_mcast(&addr);
    simple_udp_sendto(&broadcast_connection, data, sizeof(data), &addr);
  }

  PROCESS_END();
}
/*---------------------------------------------------------------------------*/

这是接收器代码,它是来自 Contiki 示例的 udp-sink 代码:

#include "contiki.h"
#include "contiki-lib.h"
#include "contiki-net.h"
#include "net/ip/uip.h"
#include "net/rpl/rpl.h"
#include "net/linkaddr.h"

#include "net/netstack.h"
#include "dev/button-sensor.h"
#include "dev/serial-line.h"
#if CONTIKI_TARGET_Z1
#include "dev/uart0.h"
#else
#include "dev/uart1.h"
#endif
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include "collect-common.h"
#include "collect-view.h"

#define DEBUG DEBUG_PRINT
#include "net/ip/uip-debug.h"

#define UIP_IP_BUF   ((struct uip_ip_hdr *)&uip_buf[UIP_LLH_LEN])

#define UDP_CLIENT_PORT 8775
#define UDP_SERVER_PORT 5688

static struct uip_udp_conn *server_conn;

PROCESS(udp_server_process, "UDP server process");
AUTOSTART_PROCESSES(&udp_server_process,&collect_common_process);
/*---------------------------------------------------------------------------*/
void
collect_common_set_sink(void)
{
}
/*---------------------------------------------------------------------------*/
void
collect_common_net_print(void)
{
  printf("I am sink!\n");
}
/*---------------------------------------------------------------------------*/
void
collect_common_send(void)
{
  /* Server never sends */
}
/*---------------------------------------------------------------------------*/
void
collect_common_net_init(void)
{
#if CONTIKI_TARGET_Z1
  uart0_set_input(serial_line_input_byte);
#else
  uart1_set_input(serial_line_input_byte);
#endif
  serial_line_init();

  PRINTF("I am sink!\n");
}
/*---------------------------------------------------------------------------*/
static void
tcpip_handler(void)
{
  uint8_t *appdata;
  linkaddr_t sender;
  uint8_t seqno;
  uint8_t hops;

  if(uip_newdata()) {
    appdata = (uint8_t *)uip_appdata;
    sender.u8[0] = UIP_IP_BUF->srcipaddr.u8[15];
    sender.u8[1] = UIP_IP_BUF->srcipaddr.u8[14];
    seqno = *appdata;
    hops = uip_ds6_if.cur_hop_limit - UIP_IP_BUF->ttl + 1;
    collect_common_recv(&sender, seqno, hops,
                        appdata + 2, uip_datalen() - 2);
  }
}
/*---------------------------------------------------------------------------*/
static void
print_local_addresses(void)
{
  int i;
  uint8_t state;

  PRINTF("Server IPv6 addresses: ");
  for(i = 0; i < UIP_DS6_ADDR_NB; i++) {
    state = uip_ds6_if.addr_list[i].state;
    if(state == ADDR_TENTATIVE || state == ADDR_PREFERRED) {
      PRINT6ADDR(&uip_ds6_if.addr_list[i].ipaddr);
      PRINTF("\n");
      /* hack to make address "final" */
      if (state == ADDR_TENTATIVE) {
        uip_ds6_if.addr_list[i].state = ADDR_PREFERRED;
      }
    }
  }
}
/*---------------------------------------------------------------------------*/
PROCESS_THREAD(udp_server_process, ev, data)
{
  uip_ipaddr_t ipaddr;
  struct uip_ds6_addr *root_if;

  PROCESS_BEGIN();

  PROCESS_PAUSE();

  SENSORS_ACTIVATE(button_sensor);

  PRINTF("UDP server started\n");

#if UIP_CONF_ROUTER
  uip_ip6addr(&ipaddr, 0xaaaa, 0, 0, 0, 0, 0, 0, 1);
  /* uip_ds6_set_addr_iid(&ipaddr, &uip_lladdr); */
  uip_ds6_addr_add(&ipaddr, 0, ADDR_MANUAL);
  root_if = uip_ds6_addr_lookup(&ipaddr);
  if(root_if != NULL) {
    rpl_dag_t *dag;
    dag = rpl_set_root(RPL_DEFAULT_INSTANCE,(uip_ip6addr_t *)&ipaddr);
    uip_ip6addr(&ipaddr, 0xaaaa, 0, 0, 0, 0, 0, 0, 0);
    rpl_set_prefix(dag, &ipaddr, 64);
    PRINTF("created a new RPL dag\n");
  } else {
    PRINTF("failed to create a new RPL DAG\n");
  }
#endif /* UIP_CONF_ROUTER */

  print_local_addresses();

  /* The data sink runs with a 100% duty cycle in order to ensure high
     packet reception rates. */
  NETSTACK_RDC.off(1);

  server_conn = udp_new(NULL, UIP_HTONS(UDP_CLIENT_PORT), NULL);
  udp_bind(server_conn, UIP_HTONS(UDP_SERVER_PORT));

  PRINTF("Created a server connection with remote address ");
  PRINT6ADDR(&server_conn->ripaddr);
  PRINTF(" local/remote port %u/%u\n", UIP_HTONS(server_conn->lport),
         UIP_HTONS(server_conn->rport));

  while(1) {
    PROCESS_YIELD();
    if(ev == tcpip_event) {
      tcpip_handler();
    } else if (ev == sensors_event && data == &button_sensor) {
      PRINTF("Initiaing global repair\n");
      rpl_repair_root(RPL_DEFAULT_INSTANCE);
    }
  }

  PROCESS_END();
}
/*---------------------------------------------------------------------------*/
4

0 回答 0