コード例 #1
0
/*---------------------------------------------------------------------------*/
static void
process_run_thread_loop(void *data)
{
    /* Yield once during bootup */
    simProcessRunValue = 1;
    cooja_mt_yield();

    contiki_init();

    while(1)
    {
        simProcessRunValue = process_run();
        while(simProcessRunValue-- > 0) {
          process_run();
        }
        simProcessRunValue = process_nevents();

        /* Check if we must stay awake */
        if(simDontFallAsleep) {
            simDontFallAsleep=0;
            simProcessRunValue = 1;
        }

        /* Return to COOJA */
        cooja_mt_yield();
    }
}
コード例 #2
0
ファイル: contiki_template.c プロジェクト: EDAyele/ptunes
/*---------------------------------------------------------------------------*/
static void
start_process_run_loop(void *data)
{
    /* Yield once during bootup */
    simProcessRunValue = 1;
    cooja_mt_yield();

    /* Initialize random generator */
    random_init(0);

    /* Start process handler */
    process_init();

    /* Start Contiki processes */
    procinit_init();

    /* Print startup information */
    printf(CONTIKI_VERSION_STRING " started. ");
    if(node_id > 0) {
      printf("Node id is set to %u.\n", node_id);
    } else {
      printf("Node id is not set.\n");
    }

    /* Initialize communication stack */
    init_net();

    /* Start serial process */
    serial_line_init();

    /* Start autostart processes (defined in Contiki application) */
    print_processes(autostart_processes);
    autostart_start(autostart_processes);

    while(1)
	{
		/* Always pretend we have processes left while inside process_run() */
		simProcessRunValue = 1;

		if (simDoReceiverCallback) {
		  simDoReceiverCallback = 0;
		  radio_call_receiver();
		}

		simProcessRunValue = process_run();
		while (simProcessRunValue-- > 0) {
		  process_run();
		}
		simProcessRunValue = process_nevents();

		// Check if we must stay awake
		if (simDontFallAsleep) {
			simDontFallAsleep=0;
			simProcessRunValue = 1;
		}

		/* Yield thread when one process_run has completed */
		cooja_mt_yield();
	}
}
コード例 #3
0
/* Lock TSCH (no slot operation) */
int
tsch_get_lock(void)
{
  if(!tsch_locked) {
    rtimer_clock_t busy_wait_time;
    int busy_wait = 0; /* Flag used for logging purposes */
    /* Make sure no new slot operation will start */
    tsch_lock_requested = 1;
    /* Wait for the end of current slot operation. */
    if(tsch_in_slot_operation) {
      busy_wait = 1;
      busy_wait_time = RTIMER_NOW();
      while(tsch_in_slot_operation) {
#if CONTIKI_TARGET_COOJA || CONTIKI_TARGET_COOJA_IP64
        simProcessRunValue = 1;
        cooja_mt_yield();
#endif /* CONTIKI_TARGET_COOJA || CONTIKI_TARGET_COOJA_IP64 */
      }
      busy_wait_time = RTIMER_NOW() - busy_wait_time;
    }
    if(!tsch_locked) {
      /* Take the lock if it is free */
      tsch_locked = 1;
      tsch_lock_requested = 0;
      if(busy_wait) {
        /* Issue a log whenever we had to busy wait until getting the lock */
        TSCH_LOG_ADD(tsch_log_message,
            snprintf(log->message, sizeof(log->message),
                "!get lock delay %u", (unsigned)busy_wait_time);
        );
      }
コード例 #4
0
ファイル: cooja-radio.c プロジェクト: kincki/contiki
/*---------------------------------------------------------------------------*/
static int
radio_send(const void *payload, unsigned short payload_len)
{
  int radiostate = simRadioHWOn;

  if(!simRadioHWOn) {
    /* Turn on radio temporarily */
    simRadioHWOn = 1;
  }
  if(payload_len > COOJA_RADIO_BUFSIZE) {
    return RADIO_TX_ERR;
  }
  if(payload_len == 0) {
    return RADIO_TX_ERR;
  }
  if(simOutSize > 0) {
    return RADIO_TX_ERR;
  }

  /* Copy packet data to temporary storage */
  memcpy(simOutDataBuffer, payload, payload_len);
  simOutSize = payload_len;

  /* Transmit */
  if (simOutSize > 0) {
    PRINTF("COOJA: sending %d bytes @ %lu\n", simOutSize, clock_time());
  }
  while(simOutSize > 0) {
    cooja_mt_yield();
  }

  simRadioHWOn = radiostate;
  /* FIXME: this doesn't work */
  cooja_mt_yield();
  /* duplicate packets here */
  if (clock_seconds() >= failure_delay[simMoteID]) {
    if (!--packet_duplicate[simMoteID]) {
      PRINTF("COOJA: sending %d bytes @ %lu (twice)\n", payload_len, clock_time());
      radio_send(payload, payload_len);
    }
  }

  return RADIO_TX_OK;
}
コード例 #5
0
/*---------------------------------------------------------------------------*/
static void
rtimer_thread_loop(void *data)
{
  while(1)
  {
    rtimer_arch_check();

    /* Return to COOJA */
    cooja_mt_yield();
  }
}
コード例 #6
0
ファイル: nullrdc.c プロジェクト: EricZaluzec/zephyr
/*---------------------------------------------------------------------------*/
static int
send_one_packet(struct net_buf *buf, mac_callback_t sent, void *ptr)
{
  int ret;
  int last_sent_ok = 0;
#if NULLRDC_ENABLE_RETRANSMISSIONS
  rtimer_clock_t target_time;
  uint8_t tx_attempts = 0;
  uint8_t max_tx_attempts;

  if(packetbuf_attr(PACKETBUF_ATTR_MAX_MAC_TRANSMISSIONS) > 0) {
    max_tx_attempts = packetbuf_attr(PACKETBUF_ATTR_MAX_MAC_TRANSMISSIONS);
  } else {
    max_tx_attempts = NULLRDC_MAX_RETRANSMISSIONS + 1;
  }
#endif /* NULLRDC_ENABLE_RETRANSMISSIONS */

  packetbuf_set_addr(buf, PACKETBUF_ADDR_SENDER, &linkaddr_node_addr);
#if NULLRDC_802154_AUTOACK || NULLRDC_802154_AUTOACK_HW
  packetbuf_set_attr(buf, PACKETBUF_ATTR_MAC_ACK, 1);
#endif /* NULLRDC_802154_AUTOACK || NULLRDC_802154_AUTOACK_HW */

  if(NETSTACK_FRAMER.create_and_secure(buf) < 0) {
    /* Failed to allocate space for headers */
    PRINTF("nullrdc: send failed, too large header\n");
    ret = MAC_TX_ERR_FATAL;
  } else {
#if NULLRDC_802154_AUTOACK
    int is_broadcast;
    uint8_t dsn;
    dsn = ((uint8_t *)packetbuf_hdrptr())[2] & 0xff;

    NETSTACK_RADIO.prepare(packetbuf_hdrptr(), packetbuf_totlen());

    is_broadcast = packetbuf_holds_broadcast();

    if(NETSTACK_RADIO.receiving_packet() ||
       (!is_broadcast && NETSTACK_RADIO.pending_packet())) {

      /* Currently receiving a packet over air or the radio has
         already received a packet that needs to be read before
         sending with auto ack. */
      ret = MAC_TX_COLLISION;
    } else {
      if(!is_broadcast) {
        RIMESTATS_ADD(reliabletx);
      }
#if NULLRDC_ENABLE_RETRANSMISSIONS
  while(1) {
    /* Transmit packet and check status */
    tx_attempts++;
#endif /* NULLRDC_ENABLE_RETRANSMISSIONS */

      switch(NETSTACK_RADIO.transmit(packetbuf_totlen(buf))) {
      case RADIO_TX_OK:
        if(is_broadcast) {
          ret = MAC_TX_OK;
        } else {
          rtimer_clock_t wt;

          /* Check for ack */
          wt = RTIMER_NOW();
          watchdog_periodic();
          while(RTIMER_CLOCK_LT(RTIMER_NOW(), wt + ACK_WAIT_TIME)) {
#if CONTIKI_TARGET_COOJA
            simProcessRunValue = 1;
            cooja_mt_yield();
#endif /* CONTIKI_TARGET_COOJA */
          }

          ret = MAC_TX_NOACK;
          if(NETSTACK_RADIO.receiving_packet() ||
             NETSTACK_RADIO.pending_packet() ||
             NETSTACK_RADIO.channel_clear() == 0) {
            int len;
            uint8_t ackbuf[ACK_LEN];

            if(AFTER_ACK_DETECTED_WAIT_TIME > 0) {
              wt = RTIMER_NOW();
              watchdog_periodic();
              while(RTIMER_CLOCK_LT(RTIMER_NOW(),
                                    wt + AFTER_ACK_DETECTED_WAIT_TIME)) {
      #if CONTIKI_TARGET_COOJA
                  simProcessRunValue = 1;
                  cooja_mt_yield();
      #endif /* CONTIKI_TARGET_COOJA */
              }
            }

            if(NETSTACK_RADIO.pending_packet()) {
              len = NETSTACK_RADIO.read(ackbuf, ACK_LEN);
              if(len == ACK_LEN && ackbuf[2] == dsn) {
                /* Ack received */
                RIMESTATS_ADD(ackrx);
                ret = MAC_TX_OK;
              } else {
                /* Not an ack or ack not for us: collision */
                ret = MAC_TX_COLLISION;
              }
            }
          } else {
	    PRINTF("nullrdc tx noack\n");
	  }
        }
        break;
      case RADIO_TX_COLLISION:
        ret = MAC_TX_COLLISION;
        break;
      default:
        ret = MAC_TX_ERR;
        break;
      }
#if NULLRDC_ENABLE_RETRANSMISSIONS
    if(is_broadcast) {
#if !NULLRDC_ENABLE_RETRANSMISSIONS_BCAST
      break;
#else  /* NULLRDC_ENABLE_RETRANSMISSIONS_BCAST */
      if(ret != MAC_TX_COLLISION) {
        /* Retry broadcast frame only upon collision */
        break;
      }
#endif /* NULLRDC_ENABLE_RETRANSMISSIONS_BCAST */
    } else {
      /* Frame is unicast. Do not retry unless NO_ACK or COLLISION */
      if((ret != MAC_TX_NOACK) && (ret != MAC_TX_COLLISION)) {
        break;
      }
    }
    /* Do not retry if max attempts reached. */
    if(tx_attempts >= max_tx_attempts) {
      PRINTF("nullrdc: max tx attempts reached\n");
      break;
    }
    /* Block-wait before retrying the frame. */
    target_time = RTIMER_NOW() +
      (RTIMER_SECOND * NULLRDC_TX_RETRY_DELAY_MS / 1000);
    watchdog_periodic();
    while(RTIMER_CLOCK_LT(RTIMER_NOW(), target_time)) {
      /* Wait */
    }
    /* Attempt a new frame (re)transmission */
  }
#endif /* NULLRDC_ENABLE_RETRANSMISSIONS */
    }

#else /* ! NULLRDC_802154_AUTOACK */

    switch(NETSTACK_RADIO.send(buf, packetbuf_hdrptr(buf), packetbuf_totlen(buf))) {
    case RADIO_TX_OK:
      ret = MAC_TX_OK;
      break;
    case RADIO_TX_COLLISION:
      ret = MAC_TX_COLLISION;
      break;
    case RADIO_TX_NOACK:
      ret = MAC_TX_NOACK;
      break;
    default:
      ret = MAC_TX_ERR;
      break;
    }

#endif /* ! NULLRDC_802154_AUTOACK */
  }
  if(ret == MAC_TX_OK) {
    last_sent_ok = 1;
  }
#if ! NULLRDC_ENABLE_RETRANSMISSIONS
  mac_call_sent_callback(buf, sent, ptr, ret, 1);
#else
  mac_call_sent_callback(buf, sent, ptr, ret, tx_attempts);
#endif /* !NULLRDC_ENABLE_RETRANSMISSIONS */
  return last_sent_ok;
}
コード例 #7
0
/*---------------------------------------------------------------------------*/
static int
send_one_packet(mac_callback_t sent, void *ptr)
{
	int ret;
	int last_sent_ok = 0;

	packetbuf_set_addr(PACKETBUF_ADDR_SENDER, &linkaddr_node_addr);
#if DISCOVERY_AWARE_RDC_802154_AUTOACK || DISCOVERY_AWARE_RDC_802154_AUTOACK_HW
	packetbuf_set_attr(PACKETBUF_ATTR_MAC_ACK, 1);
#endif /* DISCOVERY_AWARE_RDC_802154_AUTOACK || DISCOVERY_AWARE_RDC_802154_AUTOACK_HW */

	if (!radio_status) {
		on();
	}


	if(NETSTACK_FRAMER.create() < 0) {
		/* Failed to allocate space for headers */
	    PRINTF("RDC: send failed, too large header\n");
		ret = MAC_TX_ERR_FATAL;
	} else {

#ifdef NETSTACK_ENCRYPT
		NETSTACK_ENCRYPT();
#endif /* NETSTACK_ENCRYPT */

#if DISCOVERY_AWARE_RDC_802154_AUTOACK
		int is_broadcast;
		uint8_t dsn;
		dsn = ((uint8_t *)packetbuf_hdrptr())[2] & 0xff;

		NETSTACK_RADIO.prepare(packetbuf_hdrptr(), packetbuf_totlen());

		is_broadcast = linkaddr_cmp(packetbuf_addr(PACKETBUF_ADDR_RECEIVER),
				&linkaddr_null);

		if(NETSTACK_RADIO.receiving_packet() ||
				(!is_broadcast && NETSTACK_RADIO.pending_packet())) {

			/* Currently receiving a packet over air or the radio has
         already received a packet that needs to be read before
         sending with auto ack. */
			ret = MAC_TX_COLLISION;

		} else {
  		  if(!is_broadcast) {
			RIMESTATS_ADD(reliabletx);
		  }

			switch(NETSTACK_RADIO.transmit(packetbuf_totlen())) {
			case RADIO_TX_OK:
				if(is_broadcast) {
					ret = MAC_TX_OK;
				} else {
					rtimer_clock_t wt;

					/* Check for ack */
					wt = RTIMER_NOW();
					watchdog_periodic();
					while(RTIMER_CLOCK_LT(RTIMER_NOW(), wt + ACK_WAIT_TIME)) {
#if CONTIKI_TARGET_COOJA
						simProcessRunValue = 1;
						cooja_mt_yield();
#endif /* CONTIKI_TARGET_COOJA */
					}

					ret = MAC_TX_NOACK;
					if(NETSTACK_RADIO.receiving_packet() ||
							NETSTACK_RADIO.pending_packet() ||
							NETSTACK_RADIO.channel_clear() == 0) {
						int len;
						uint8_t ackbuf[ACK_LEN];

						if(AFTER_ACK_DETECTED_WAIT_TIME > 0) {
							wt = RTIMER_NOW();
							watchdog_periodic();
							while(RTIMER_CLOCK_LT(RTIMER_NOW(), wt + AFTER_ACK_DETECTED_WAIT_TIME)) {
#if CONTIKI_TARGET_COOJA
								simProcessRunValue = 1;
								cooja_mt_yield();
#endif /* CONTIKI_TARGET_COOJA */
							}
						}

						if(NETSTACK_RADIO.pending_packet()) {
							len = NETSTACK_RADIO.read(ackbuf, ACK_LEN);
							if(len == ACK_LEN && ackbuf[2] == dsn) {
								/* Ack received */
								RIMESTATS_ADD(ackrx);
								ret = MAC_TX_OK;
							} else {
								/* Not an ack or ack not for us: collision */
								ret = MAC_TX_COLLISION;
							}
						}
					} else {
						PRINTF("RDC tx noack\n");
					}
				}
				break;
			case RADIO_TX_COLLISION:
				ret = MAC_TX_COLLISION;
				break;
			default:
				ret = MAC_TX_ERR;
				break;
			}
		}

#else /* ! DISCOVERY_AWARE_RDC_802154_AUTOACK */

		switch(NETSTACK_RADIO.send(packetbuf_hdrptr(), packetbuf_totlen())) {
		case RADIO_TX_OK:
			ret = MAC_TX_OK;
			break;
		case RADIO_TX_COLLISION:
			ret = MAC_TX_COLLISION;
			break;
		case RADIO_TX_NOACK:
			ret = MAC_TX_NOACK;
			break;
		default:
			ret = MAC_TX_ERR;
			break;
		}

#endif /* ! DISCOVERY_AWARE_RDC_802154_AUTOACK */
	}



	if (!linkaddr_cmp(packetbuf_addr(PACKETBUF_ADDR_RECEIVER), &linkaddr_null)
			&&  ret == MAC_TX_OK) {
		send_flag = 1;
		to_modifier+=10;
	}

	if(ret == MAC_TX_OK) {
		last_sent_ok = 1;
	}

	mac_call_sent_callback(sent, ptr, ret, 1);

	return last_sent_ok;
}