/*---------------------------------------------------------------------------*/ static void input_packet(void) { /* We have received the packet, so we can go back to being asleep. */ off(); /* printf("cycle_start 0x%02x 0x%02x\n", cycle_start, cycle_start % CYCLE_TIME);*/ if(packetbuf_totlen() > 0 && NETSTACK_FRAMER.parse()) { #if WITH_CONTIKIMAC_HEADER struct hdr *chdr; chdr = packetbuf_dataptr(); if(chdr->id != CONTIKIMAC_ID) { PRINTF("contikimac: failed to parse hdr (%u)\n", packetbuf_totlen()); return; } packetbuf_hdrreduce(sizeof(struct hdr)); packetbuf_set_datalen(chdr->len); #endif /* WITH_CONTIKIMAC_HEADER */ if(packetbuf_datalen() > 0 && packetbuf_totlen() > 0 && (rimeaddr_cmp(packetbuf_addr(PACKETBUF_ADDR_RECEIVER), &rimeaddr_node_addr) || rimeaddr_cmp(packetbuf_addr(PACKETBUF_ADDR_RECEIVER), &rimeaddr_null))) { /* This is a regular packet that is destined to us or to the broadcast address. */ #if WITH_PHASE_OPTIMIZATION /* If the sender has set its pending flag, it has its radio turned on and we should drop the phase estimation that we have from before. */ if(packetbuf_attr(PACKETBUF_ATTR_PENDING)) { phase_remove(&phase_list, packetbuf_addr(PACKETBUF_ADDR_SENDER)); } #endif /* WITH_PHASE_OPTIMIZATION */ /* Check for duplicate packet by comparing the sequence number of the incoming packet with the last few ones we saw. */ { int i; for(i = 0; i < MAX_SEQNOS; ++i) { if(packetbuf_attr(PACKETBUF_ATTR_PACKET_ID) == received_seqnos[i].seqno && rimeaddr_cmp(packetbuf_addr(PACKETBUF_ADDR_SENDER), &received_seqnos[i].sender)) { /* Drop the packet. */ /* printf("Drop duplicate ContikiMAC layer packet\n");*/ return; } } for(i = MAX_SEQNOS - 1; i > 0; --i) { memcpy(&received_seqnos[i], &received_seqnos[i - 1], sizeof(struct seqno)); } received_seqnos[0].seqno = packetbuf_attr(PACKETBUF_ATTR_PACKET_ID); rimeaddr_copy(&received_seqnos[0].sender, packetbuf_addr(PACKETBUF_ADDR_SENDER)); } #if CONTIKIMAC_CONF_COMPOWER /* Accumulate the power consumption for the packet reception. */ compower_accumulate(¤t_packet); /* Convert the accumulated power consumption for the received packet to packet attributes so that the higher levels can keep track of the amount of energy spent on receiving the packet. */ compower_attrconv(¤t_packet); /* Clear the accumulated power consumption so that it is ready for the next packet. */ compower_clear(¤t_packet); #endif /* CONTIKIMAC_CONF_COMPOWER */ PRINTDEBUG("contikimac: data (%u)\n", packetbuf_datalen()); NETSTACK_MAC.input(); return; } else { PRINTDEBUG("contikimac: data not for us\n"); } } else { PRINTF("contikimac: failed to parse (%u)\n", packetbuf_totlen()); } }
/*---------------------------------------------------------------------------*/ static int send_packet(mac_callback_t mac_callback, void *mac_callback_ptr, struct rdc_buf_list *buf_list, int is_receiver_awake) { rtimer_clock_t t0; #if WITH_PHASE_OPTIMIZATION rtimer_clock_t encounter_time = 0; #endif int strobes; uint8_t got_strobe_ack = 0; uint8_t is_broadcast = 0; uint8_t is_known_receiver = 0; uint8_t collisions; int transmit_len; int ret; uint8_t contikimac_was_on; #if !RDC_CONF_HARDWARE_ACK int len; uint8_t seqno; #endif /* Exit if RDC and radio were explicitly turned off */ if(!contikimac_is_on && !contikimac_keep_radio_on) { PRINTF("contikimac: radio is turned off\n"); return MAC_TX_ERR_FATAL; } if(packetbuf_totlen() == 0) { PRINTF("contikimac: send_packet data len 0\n"); return MAC_TX_ERR_FATAL; } #if !NETSTACK_CONF_BRIDGE_MODE /* If NETSTACK_CONF_BRIDGE_MODE is set, assume PACKETBUF_ADDR_SENDER is already set. */ packetbuf_set_addr(PACKETBUF_ADDR_SENDER, &linkaddr_node_addr); #endif if(packetbuf_holds_broadcast()) { is_broadcast = 1; PRINTDEBUG("contikimac: send broadcast\n"); if(broadcast_rate_drop()) { return MAC_TX_COLLISION; } } else { #if NETSTACK_CONF_WITH_IPV6 PRINTDEBUG("contikimac: send unicast to %02x%02x:%02x%02x:%02x%02x:%02x%02x\n", packetbuf_addr(PACKETBUF_ADDR_RECEIVER)->u8[0], packetbuf_addr(PACKETBUF_ADDR_RECEIVER)->u8[1], packetbuf_addr(PACKETBUF_ADDR_RECEIVER)->u8[2], packetbuf_addr(PACKETBUF_ADDR_RECEIVER)->u8[3], packetbuf_addr(PACKETBUF_ADDR_RECEIVER)->u8[4], packetbuf_addr(PACKETBUF_ADDR_RECEIVER)->u8[5], packetbuf_addr(PACKETBUF_ADDR_RECEIVER)->u8[6], packetbuf_addr(PACKETBUF_ADDR_RECEIVER)->u8[7]); #else /* NETSTACK_CONF_WITH_IPV6 */ PRINTDEBUG("contikimac: send unicast to %u.%u\n", packetbuf_addr(PACKETBUF_ADDR_RECEIVER)->u8[0], packetbuf_addr(PACKETBUF_ADDR_RECEIVER)->u8[1]); #endif /* NETSTACK_CONF_WITH_IPV6 */ } if(!packetbuf_attr(PACKETBUF_ATTR_IS_CREATED_AND_SECURED)) { packetbuf_set_attr(PACKETBUF_ATTR_MAC_ACK, 1); if(NETSTACK_FRAMER.create_and_secure() < 0) { PRINTF("contikimac: framer failed\n"); return MAC_TX_ERR_FATAL; } } transmit_len = packetbuf_totlen(); NETSTACK_RADIO.prepare(packetbuf_hdrptr(), transmit_len); if(!is_broadcast && !is_receiver_awake) { #if WITH_PHASE_OPTIMIZATION ret = phase_wait(packetbuf_addr(PACKETBUF_ADDR_RECEIVER), CYCLE_TIME, GUARD_TIME, mac_callback, mac_callback_ptr, buf_list); if(ret == PHASE_DEFERRED) { return MAC_TX_DEFERRED; } if(ret != PHASE_UNKNOWN) { is_known_receiver = 1; } #endif /* WITH_PHASE_OPTIMIZATION */ } /* By setting we_are_sending to one, we ensure that the rtimer powercycle interrupt do not interfere with us sending the packet. */ we_are_sending = 1; /* If we have a pending packet in the radio, we should not send now, because we will trash the received packet. Instead, we signal that we have a collision, which lets the packet be received. This packet will be retransmitted later by the MAC protocol instread. */ if(NETSTACK_RADIO.receiving_packet() || NETSTACK_RADIO.pending_packet()) { we_are_sending = 0; PRINTF("contikimac: collision receiving %d, pending %d\n", NETSTACK_RADIO.receiving_packet(), NETSTACK_RADIO.pending_packet()); return MAC_TX_COLLISION; } /* Switch off the radio to ensure that we didn't start sending while the radio was doing a channel check. */ off(); strobes = 0; /* Send a train of strobes until the receiver answers with an ACK. */ collisions = 0; got_strobe_ack = 0; /* Set contikimac_is_on to one to allow the on() and off() functions to control the radio. We restore the old value of contikimac_is_on when we are done. */ contikimac_was_on = contikimac_is_on; contikimac_is_on = 1; #if !RDC_CONF_HARDWARE_CSMA /* Check if there are any transmissions by others. */ /* TODO: why does this give collisions before sending with the mc1322x? */ if(is_receiver_awake == 0) { int i; for(i = 0; i < CCA_COUNT_MAX_TX; ++i) { t0 = RTIMER_NOW(); on(); #if CCA_CHECK_TIME > 0 while(RTIMER_CLOCK_LT(RTIMER_NOW(), t0 + CCA_CHECK_TIME)) { } #endif if(NETSTACK_RADIO.channel_clear() == 0) { collisions++; off(); break; } off(); t0 = RTIMER_NOW(); while(RTIMER_CLOCK_LT(RTIMER_NOW(), t0 + CCA_SLEEP_TIME)) { } } } if(collisions > 0) { we_are_sending = 0; off(); PRINTF("contikimac: collisions before sending\n"); contikimac_is_on = contikimac_was_on; return MAC_TX_COLLISION; } #endif /* RDC_CONF_HARDWARE_CSMA */ #if !RDC_CONF_HARDWARE_ACK if(!is_broadcast) { /* Turn radio on to receive expected unicast ack. Not necessary with hardware ack detection, and may trigger an unnecessary cca or rx cycle */ on(); } seqno = packetbuf_attr(PACKETBUF_ATTR_MAC_SEQNO); #endif watchdog_periodic(); t0 = RTIMER_NOW(); for(strobes = 0, collisions = 0; got_strobe_ack == 0 && collisions == 0 && RTIMER_CLOCK_LT(RTIMER_NOW(), t0 + STROBE_TIME); strobes++) { watchdog_periodic(); if(!is_broadcast && (is_receiver_awake || is_known_receiver) && !RTIMER_CLOCK_LT(RTIMER_NOW(), t0 + MAX_PHASE_STROBE_TIME)) { PRINTF("miss to %d\n", packetbuf_addr(PACKETBUF_ADDR_RECEIVER)->u8[0]); break; } #if !RDC_CONF_HARDWARE_ACK len = 0; #endif { rtimer_clock_t wt; #if WITH_PHASE_OPTIMIZATION rtimer_clock_t txtime = RTIMER_NOW(); #endif #if RDC_CONF_HARDWARE_ACK int ret = NETSTACK_RADIO.transmit(transmit_len); #else NETSTACK_RADIO.transmit(transmit_len); #endif #if RDC_CONF_HARDWARE_ACK /* For radios that block in the transmit routine and detect the ACK in hardware */ if(ret == RADIO_TX_OK) { if(!is_broadcast) { got_strobe_ack = 1; #if WITH_PHASE_OPTIMIZATION encounter_time = txtime; #endif break; } } else if (ret == RADIO_TX_NOACK) { } else if (ret == RADIO_TX_COLLISION) { PRINTF("contikimac: collisions while sending\n"); collisions++; } wt = RTIMER_NOW(); while(RTIMER_CLOCK_LT(RTIMER_NOW(), wt + INTER_PACKET_INTERVAL)) { } #else /* RDC_CONF_HARDWARE_ACK */ /* Wait for the ACK packet */ wt = RTIMER_NOW(); while(RTIMER_CLOCK_LT(RTIMER_NOW(), wt + INTER_PACKET_INTERVAL)) { } if(!is_broadcast && (NETSTACK_RADIO.receiving_packet() || NETSTACK_RADIO.pending_packet() || NETSTACK_RADIO.channel_clear() == 0)) { uint8_t ackbuf[ACK_LEN]; wt = RTIMER_NOW(); while(RTIMER_CLOCK_LT(RTIMER_NOW(), wt + AFTER_ACK_DETECTECT_WAIT_TIME)) { } len = NETSTACK_RADIO.read(ackbuf, ACK_LEN); if(len == ACK_LEN && seqno == ackbuf[ACK_LEN - 1]) { got_strobe_ack = 1; #if WITH_PHASE_OPTIMIZATION encounter_time = txtime; #endif break; } else { PRINTF("contikimac: collisions while sending\n"); collisions++; } } #endif /* RDC_CONF_HARDWARE_ACK */ } } off(); PRINTF("contikimac: send (strobes=%u, len=%u, %s, %s), done\n", strobes, packetbuf_totlen(), got_strobe_ack ? "ack" : "no ack", collisions ? "collision" : "no collision"); #if CONTIKIMAC_CONF_COMPOWER /* Accumulate the power consumption for the packet transmission. */ compower_accumulate(¤t_packet); /* Convert the accumulated power consumption for the transmitted packet to packet attributes so that the higher levels can keep track of the amount of energy spent on transmitting the packet. */ compower_attrconv(¤t_packet); /* Clear the accumulated power consumption so that it is ready for the next packet. */ compower_clear(¤t_packet); #endif /* CONTIKIMAC_CONF_COMPOWER */ contikimac_is_on = contikimac_was_on; we_are_sending = 0; /* Determine the return value that we will return from the function. We must pass this value to the phase module before we return from the function. */ if(collisions > 0) { ret = MAC_TX_COLLISION; } else if(!is_broadcast && !got_strobe_ack) { ret = MAC_TX_NOACK; } else { ret = MAC_TX_OK; } #if WITH_PHASE_OPTIMIZATION if(is_known_receiver && got_strobe_ack) { PRINTF("no miss %d wake-ups %d\n", packetbuf_addr(PACKETBUF_ADDR_RECEIVER)->u8[0], strobes); } if(!is_broadcast) { if(collisions == 0 && is_receiver_awake == 0) { phase_update(packetbuf_addr(PACKETBUF_ADDR_RECEIVER), encounter_time, ret); } } #endif /* WITH_PHASE_OPTIMIZATION */ return ret; }
/*---------------------------------------------------------------------------*/ static void input_packet(void) { static struct ctimer ct; int duplicate = 0; #if CONTIKIMAC_SEND_SW_ACK int original_datalen; uint8_t *original_dataptr; original_datalen = packetbuf_datalen(); original_dataptr = packetbuf_dataptr(); #endif if(!we_are_receiving_burst) { off(); } if(packetbuf_datalen() == ACK_LEN) { /* Ignore ack packets */ PRINTF("ContikiMAC: ignored ack\n"); return; } /* printf("cycle_start 0x%02x 0x%02x\n", cycle_start, cycle_start % CYCLE_TIME);*/ if(packetbuf_totlen() > 0 && NETSTACK_FRAMER.parse() >= 0) { if(packetbuf_datalen() > 0 && packetbuf_totlen() > 0 && (linkaddr_cmp(packetbuf_addr(PACKETBUF_ADDR_RECEIVER), &linkaddr_node_addr) || packetbuf_holds_broadcast())) { /* This is a regular packet that is destined to us or to the broadcast address. */ /* If FRAME_PENDING is set, we are receiving a packets in a burst */ /* TODO To prevent denial-of-sleep attacks, the transceiver should be disabled upon receipt of an unauthentic frame. */ we_are_receiving_burst = packetbuf_attr(PACKETBUF_ATTR_PENDING); if(we_are_receiving_burst) { on(); /* Set a timer to turn the radio off in case we do not receive a next packet */ ctimer_set(&ct, INTER_PACKET_DEADLINE, recv_burst_off, NULL); } else { off(); ctimer_stop(&ct); } #if RDC_WITH_DUPLICATE_DETECTION /* Check for duplicate packet. */ duplicate = mac_sequence_is_duplicate(); if(duplicate) { /* Drop the packet. */ PRINTF("contikimac: Drop duplicate\n"); } else { mac_sequence_register_seqno(); } #endif /* RDC_WITH_DUPLICATE_DETECTION */ #if CONTIKIMAC_CONF_COMPOWER /* Accumulate the power consumption for the packet reception. */ compower_accumulate(¤t_packet); /* Convert the accumulated power consumption for the received packet to packet attributes so that the higher levels can keep track of the amount of energy spent on receiving the packet. */ compower_attrconv(¤t_packet); /* Clear the accumulated power consumption so that it is ready for the next packet. */ compower_clear(¤t_packet); #endif /* CONTIKIMAC_CONF_COMPOWER */ PRINTDEBUG("contikimac: data (%u)\n", packetbuf_datalen()); #if CONTIKIMAC_SEND_SW_ACK { frame802154_t info154; frame802154_parse(original_dataptr, original_datalen, &info154); if(info154.fcf.frame_type == FRAME802154_DATAFRAME && info154.fcf.ack_required != 0 && linkaddr_cmp((linkaddr_t *)&info154.dest_addr, &linkaddr_node_addr)) { uint8_t ackdata[ACK_LEN] = {0, 0, 0}; we_are_sending = 1; ackdata[0] = FRAME802154_ACKFRAME; ackdata[1] = 0; ackdata[2] = info154.seq; NETSTACK_RADIO.send(ackdata, ACK_LEN); we_are_sending = 0; } } #endif /* CONTIKIMAC_SEND_SW_ACK */ if(!duplicate) { NETSTACK_MAC.input(); } return; } else { PRINTDEBUG("contikimac: data not for us\n"); } } else { PRINTF("contikimac: failed to parse (%u)\n", packetbuf_totlen()); } }
/*---------------------------------------------------------------------------*/ static void input_packet(void) { struct xmac_hdr *hdr; if(NETSTACK_FRAMER.parse()) { hdr = packetbuf_dataptr(); if(hdr->dispatch != DISPATCH) { someone_is_sending = 0; if(rimeaddr_cmp(packetbuf_addr(PACKETBUF_ADDR_RECEIVER), &rimeaddr_node_addr) || rimeaddr_cmp(packetbuf_addr(PACKETBUF_ADDR_RECEIVER), &rimeaddr_null)) { /* This is a regular packet that is destined to us or to the broadcast address. */ /* We have received the final packet, so we can go back to being asleep. */ off(); /* Check for duplicate packet by comparing the sequence number of the incoming packet with the last few ones we saw. */ { int i; for(i = 0; i < MAX_SEQNOS; ++i) { if(packetbuf_attr(PACKETBUF_ATTR_PACKET_ID) == received_seqnos[i].seqno && rimeaddr_cmp(packetbuf_addr(PACKETBUF_ADDR_SENDER), &received_seqnos[i].sender)) { /* Drop the packet. */ return; } } for(i = MAX_SEQNOS - 1; i > 0; --i) { memcpy(&received_seqnos[i], &received_seqnos[i - 1], sizeof(struct seqno)); } received_seqnos[0].seqno = packetbuf_attr(PACKETBUF_ATTR_PACKET_ID); rimeaddr_copy(&received_seqnos[0].sender, packetbuf_addr(PACKETBUF_ADDR_SENDER)); } #if XMAC_CONF_COMPOWER /* Accumulate the power consumption for the packet reception. */ compower_accumulate(¤t_packet); /* Convert the accumulated power consumption for the received packet to packet attributes so that the higher levels can keep track of the amount of energy spent on receiving the packet. */ compower_attrconv(¤t_packet); /* Clear the accumulated power consumption so that it is ready for the next packet. */ compower_clear(¤t_packet); #endif /* XMAC_CONF_COMPOWER */ waiting_for_packet = 0; PRINTDEBUG("xmac: data(%u)\n", packetbuf_datalen()); NETSTACK_MAC.input(); return; } else { PRINTDEBUG("xmac: data not for us\n"); } } else if(hdr->type == TYPE_STROBE) { someone_is_sending = 2; if(rimeaddr_cmp(packetbuf_addr(PACKETBUF_ADDR_RECEIVER), &rimeaddr_node_addr)) { /* This is a strobe packet for us. */ /* If the sender address is someone else, we should acknowledge the strobe and wait for the packet. By using the same address as both sender and receiver, we flag the message is a strobe ack. */ waiting_for_packet = 1; #if 0 hdr->type = TYPE_STROBE_ACK; packetbuf_set_addr(PACKETBUF_ADDR_RECEIVER, packetbuf_addr(PACKETBUF_ADDR_SENDER)); packetbuf_set_addr(PACKETBUF_ADDR_SENDER, &rimeaddr_node_addr); packetbuf_compact(); if(NETSTACK_FRAMER.create()) { /* We turn on the radio in anticipation of the incoming packet. */ someone_is_sending = 1; waiting_for_packet = 1; on(); NETSTACK_RADIO.send(packetbuf_hdrptr(), packetbuf_totlen()); PRINTDEBUG("xmac: send strobe ack %u\n", packetbuf_totlen()); } else { PRINTF("xmac: failed to send strobe ack\n"); } #endif /* 0 */ } else if(rimeaddr_cmp(packetbuf_addr(PACKETBUF_ADDR_RECEIVER), &rimeaddr_null)) { /* If the receiver address is null, the strobe is sent to prepare for an incoming broadcast packet. If this is the case, we turn on the radio and wait for the incoming broadcast packet. */ waiting_for_packet = 1; on(); } else { PRINTDEBUG("xmac: strobe not for us\n"); } /* We are done processing the strobe and we therefore return to the caller. */ return; #if XMAC_CONF_ANNOUNCEMENTS } else if(hdr->type == TYPE_ANNOUNCEMENT) { packetbuf_hdrreduce(sizeof(struct xmac_hdr)); parse_announcements(packetbuf_addr(PACKETBUF_ADDR_SENDER)); #endif /* XMAC_CONF_ANNOUNCEMENTS */ } else if(hdr->type == TYPE_STROBE_ACK) { PRINTDEBUG("xmac: stray strobe ack\n"); } else { PRINTF("xmac: unknown type %u (%u/%u)\n", hdr->type, packetbuf_datalen(), len); } } else { PRINTF("xmac: failed to parse (%u)\n", packetbuf_totlen()); } }
void LED::toggle(void){ status ? off() : on(); }
void apollo_kbd_device::beeper::beeper_callback() { off(); }
// this code is from Linux-PAM pam_unix support.c static int _yubi_run_helper_binary(const char *otp, const char *user) { int retval; int child; int fds[2]; void (*sighandler)(int) = NULL; D(("called.")); /* create a pipe for the password */ if (pipe(fds) != 0) { D(("could not make pipe")); return PAM_AUTH_ERR; } #if 0 // this code is from Linux-PAM pam_unix support.c if (off(UNIX_NOREAP, ctrl)) { /* * This code arranges that the demise of the child does not cause * the application to receive a signal it is not expecting - which * may kill the application or worse. * * The "noreap" module argument is provided so that the admin can * override this behavior. */ sighandler = signal(SIGCHLD, SIG_DFL); } #else sighandler = signal(SIGCHLD, SIG_DFL); #endif /* fork */ child = fork(); if (child == 0) { int i = 0; struct rlimit rlim; static char *envp[] = { NULL }; char *args[] = { NULL, NULL, NULL, NULL }; /* XXX - should really tidy up PAM here too */ close(0); close(1); /* reopen stdin as pipe */ close(fds[1]); dup2(fds[0], STDIN_FILENO); if ( getrlimit(RLIMIT_NOFILE, &rlim)==0 ) { for (i=2; i<(int)rlim.rlim_max; i++) { if (fds[0] != i) close(i); } } if (SELINUX_ENABLED && geteuid() == 0) { /* must set the real uid to 0 so the helper will not error */ /* out if pam is called from setuid binary (su, sudo...) */ setuid(0); } /* exec binary helper */ args[0] = strdup(CHKPWD_HELPER); args[1] = strdup(user); execve(CHKPWD_HELPER, args, envp); /* should not get here: exit with error */ D(("helper binary is not available")); exit(PAM_AUTHINFO_UNAVAIL); } else if (child > 0) { /* wait for child */ /* if the stored password is NULL */ int rc = 0; if (otp != NULL) /* send the password to the child */ { write(fds[1], otp, strlen(otp)+1); otp = NULL; } else { write(fds[1], "", 1); /* blank password */ } close(fds[0]); /* close here to avoid possible SIGPIPE above */ close(fds[1]); rc = waitpid(child, &retval, 0); /* wait for helper to complete */ if (rc < 0) { D(("yk_chkpwd waitpid returned %d: %m", rc)); retval = PAM_AUTH_ERR; } else { retval = WEXITSTATUS(retval); } } else { D(("fork failed")); close(fds[0]); close(fds[1]); retval = PAM_AUTH_ERR; } if (sighandler != SIG_ERR) { (void) signal(SIGCHLD, sighandler); /* restore old signal handler */ } D(("returning %d", retval)); return retval; }
/*---------------------------------------------------------------------------*/ static void input_packet(void) { static struct ctimer ct; if(!we_are_receiving_burst) { off(); } /* printf("cycle_start 0x%02x 0x%02x\n", cycle_start, cycle_start % CYCLE_TIME);*/ #ifdef NETSTACK_DECRYPT NETSTACK_DECRYPT(); #endif /* NETSTACK_DECRYPT */ if(packetbuf_totlen() > 0 && NETSTACK_FRAMER.parse() >= 0) { #if WITH_CONTIKIMAC_HEADER struct hdr *chdr; chdr = packetbuf_dataptr(); if(chdr->id != CONTIKIMAC_ID) { PRINTF("contikimac: failed to parse hdr (%u)\n", packetbuf_totlen()); return; } packetbuf_hdrreduce(sizeof(struct hdr)); packetbuf_set_datalen(chdr->len); #endif /* WITH_CONTIKIMAC_HEADER */ if(packetbuf_datalen() > 0 && packetbuf_totlen() > 0 && (linkaddr_cmp(packetbuf_addr(PACKETBUF_ADDR_RECEIVER), &linkaddr_node_addr) || linkaddr_cmp(packetbuf_addr(PACKETBUF_ADDR_RECEIVER), &linkaddr_null))) { /* This is a regular packet that is destined to us or to the broadcast address. */ /* If FRAME_PENDING is set, we are receiving a packets in a burst */ we_are_receiving_burst = packetbuf_attr(PACKETBUF_ATTR_PENDING); if(we_are_receiving_burst) { on(); /* Set a timer to turn the radio off in case we do not receive a next packet */ ctimer_set(&ct, INTER_PACKET_DEADLINE, recv_burst_off, NULL); } else { off(); ctimer_stop(&ct); } /* Check for duplicate packet. */ if(mac_sequence_is_duplicate()) { /* Drop the packet. */ /* printf("Drop duplicate ContikiMAC layer packet\n");*/ return; } mac_sequence_register_seqno(); #if CONTIKIMAC_CONF_COMPOWER /* Accumulate the power consumption for the packet reception. */ compower_accumulate(¤t_packet); /* Convert the accumulated power consumption for the received packet to packet attributes so that the higher levels can keep track of the amount of energy spent on receiving the packet. */ compower_attrconv(¤t_packet); /* Clear the accumulated power consumption so that it is ready for the next packet. */ compower_clear(¤t_packet); #endif /* CONTIKIMAC_CONF_COMPOWER */ PRINTDEBUG("contikimac: data (%u)\n", packetbuf_datalen()); NETSTACK_MAC.input(); return; } else { PRINTDEBUG("contikimac: data not for us\n"); } } else { PRINTF("contikimac: failed to parse (%u)\n", packetbuf_totlen()); } }
bool GSRenderer::Merge(int field) { bool en[2]; GSVector4i fr[2]; GSVector4i dr[2]; GSVector2i display_baseline = { INT_MAX, INT_MAX }; GSVector2i frame_baseline = { INT_MAX, INT_MAX }; for(int i = 0; i < 2; i++) { en[i] = IsEnabled(i); if(en[i]) { fr[i] = GetFrameRect(i); dr[i] = GetDisplayRect(i); display_baseline.x = min(dr[i].left, display_baseline.x); display_baseline.y = min(dr[i].top, display_baseline.y); frame_baseline.x = min(fr[i].left, frame_baseline.x); frame_baseline.y = min(fr[i].top, frame_baseline.y); //printf("[%d]: %d %d %d %d, %d %d %d %d\n", i, fr[i].x,fr[i].y,fr[i].z,fr[i].w , dr[i].x,dr[i].y,dr[i].z,dr[i].w); } } if(!en[0] && !en[1]) { return false; } GL_PUSH("Renderer Merge %d", s_n); // try to avoid fullscreen blur, could be nice on tv but on a monitor it's like double vision, hurts my eyes (persona 4, guitar hero) // // NOTE: probably the technique explained in graphtip.pdf (Antialiasing by Supersampling / 4. Reading Odd/Even Scan Lines Separately with the PCRTC then Blending) bool samesrc = en[0] && en[1] && m_regs->DISP[0].DISPFB.FBP == m_regs->DISP[1].DISPFB.FBP && m_regs->DISP[0].DISPFB.FBW == m_regs->DISP[1].DISPFB.FBW && m_regs->DISP[0].DISPFB.PSM == m_regs->DISP[1].DISPFB.PSM; // bool blurdetected = false; if(samesrc /*&& m_regs->PMODE.SLBG == 0 && m_regs->PMODE.MMOD == 1 && m_regs->PMODE.ALP == 0x80*/) { if(fr[0].eq(fr[1] + GSVector4i(0, -1, 0, 0)) && dr[0].eq(dr[1] + GSVector4i(0, 0, 0, 1)) || fr[1].eq(fr[0] + GSVector4i(0, -1, 0, 0)) && dr[1].eq(dr[0] + GSVector4i(0, 0, 0, 1))) { // persona 4: // // fr[0] = 0 0 640 448 // fr[1] = 0 1 640 448 // dr[0] = 159 50 779 498 // dr[1] = 159 50 779 497 // // second image shifted up by 1 pixel and blended over itself // // god of war: // // fr[0] = 0 1 512 448 // fr[1] = 0 0 512 448 // dr[0] = 127 50 639 497 // dr[1] = 127 50 639 498 // // same just the first image shifted int top = min(fr[0].top, fr[1].top); int bottom = max(dr[0].bottom, dr[1].bottom); fr[0].top = top; fr[1].top = top; dr[0].bottom = bottom; dr[1].bottom = bottom; // blurdetected = true; } else if(dr[0].eq(dr[1]) && (fr[0].eq(fr[1] + GSVector4i(0, 1, 0, 1)) || fr[1].eq(fr[0] + GSVector4i(0, 1, 0, 1)))) { // dq5: // // fr[0] = 0 1 512 445 // fr[1] = 0 0 512 444 // dr[0] = 127 50 639 494 // dr[1] = 127 50 639 494 int top = min(fr[0].top, fr[1].top); int bottom = min(fr[0].bottom, fr[1].bottom); fr[0].top = fr[1].top = top; fr[0].bottom = fr[1].bottom = bottom; // blurdetected = true; } //printf("samesrc = %d blurdetected = %d\n",samesrc,blurdetected); } GSVector2i fs(0, 0); GSVector2i ds(0, 0); GSTexture* tex[2] = {NULL, NULL}; int y_offset[2] = {0, 0}; s_n++; if(samesrc && fr[0].bottom == fr[1].bottom) { tex[0] = GetOutput(0, y_offset[0]); tex[1] = tex[0]; // saves one texture fetch y_offset[1] = y_offset[0]; } else { if(en[0]) tex[0] = GetOutput(0, y_offset[0]); if(en[1]) tex[1] = GetOutput(1, y_offset[1]); } GSVector4 src[2]; GSVector4 src_hw[2]; GSVector4 dst[2]; for(int i = 0; i < 2; i++) { if(!en[i] || !tex[i]) continue; GSVector4i r = fr[i]; GSVector4 scale = GSVector4(tex[i]->GetScale()).xyxy(); src[i] = GSVector4(r) * scale / GSVector4(tex[i]->GetSize()).xyxy(); src_hw[i] = (GSVector4(r) + GSVector4 (0, y_offset[i], 0, y_offset[i])) * scale / GSVector4(tex[i]->GetSize()).xyxy(); GSVector2 off(0, 0); GSVector2i display_diff(dr[i].left - display_baseline.x, dr[i].top - display_baseline.y); GSVector2i frame_diff(fr[i].left - frame_baseline.x, fr[i].top - frame_baseline.y); // Time Crisis 2/3 uses two side by side images when in split screen mode. // Though ignore cases where baseline and display rectangle offsets only differ by 1 pixel, causes blurring and wrong resolution output on FFXII if(display_diff.x > 2) { off.x = tex[i]->GetScale().x * display_diff.x; } // If the DX offset is too small then consider the status of frame memory offsets, prevents blurring on Tenchu: Fatal Shadows, Worms 3D else if(display_diff.x || frame_diff.x) { off.x = tex[i]->GetScale().x * frame_diff.x; } if(display_diff.y >= 4) // Shouldn't this be 2? { off.y = tex[i]->GetScale().y * display_diff.y; if(m_regs->SMODE2.INT && m_regs->SMODE2.FFMD) { off.y /= 2; } } else if(display_diff.y || frame_diff.y) { off.y = tex[i]->GetScale().y * frame_diff.y; } dst[i] = GSVector4(off).xyxy() + scale * GSVector4(r.rsize()); fs.x = max(fs.x, (int)(dst[i].z + 0.5f)); fs.y = max(fs.y, (int)(dst[i].w + 0.5f)); } ds = fs; if(m_regs->SMODE2.INT && m_regs->SMODE2.FFMD) { ds.y *= 2; } m_real_size = ds; bool slbg = m_regs->PMODE.SLBG; bool mmod = m_regs->PMODE.MMOD; if(tex[0] || tex[1]) { if(tex[0] == tex[1] && !slbg && (src[0] == src[1] & dst[0] == dst[1]).alltrue()) { // the two outputs are identical, skip drawing one of them (the one that is alpha blended) tex[0] = NULL; } GSVector4 c = GSVector4((int)m_regs->BGCOLOR.R, (int)m_regs->BGCOLOR.G, (int)m_regs->BGCOLOR.B, (int)m_regs->PMODE.ALP) / 255; m_dev->Merge(tex, src_hw, dst, fs, slbg, mmod, c); if(m_regs->SMODE2.INT && m_interlace > 0) { if(m_interlace == 7 && m_regs->SMODE2.FFMD) // Auto interlace enabled / Odd frame interlace setting { int field2 = 0; int mode = 2; m_dev->Interlace(ds, field ^ field2, mode, tex[1] ? tex[1]->GetScale().y : tex[0]->GetScale().y); } else { int field2 = 1 - ((m_interlace - 1) & 1); int mode = (m_interlace - 1) >> 1; m_dev->Interlace(ds, field ^ field2, mode, tex[1] ? tex[1]->GetScale().y : tex[0]->GetScale().y); } } if(m_shadeboost) { m_dev->ShadeBoost(); } if(m_shaderfx) { m_dev->ExternalFX(); } if(m_fxaa) { m_dev->FXAA(); } } return true; }
void TerminalToggle::buffer_off() { off(ICANON); }
void TerminalToggle::echo_off() { off(ECHO); }
static int hardware_init_port(void) { u8 scratch, scratch2, scratch3; /* * This is a simple port existence test, borrowed from the autoconfig * function in drivers/tty/serial/8250/8250_port.c */ scratch = sinp(UART_IER); soutp(UART_IER, 0); #ifdef __i386__ outb(0xff, 0x080); #endif scratch2 = sinp(UART_IER) & 0x0f; soutp(UART_IER, 0x0f); #ifdef __i386__ outb(0x00, 0x080); #endif scratch3 = sinp(UART_IER) & 0x0f; soutp(UART_IER, scratch); if (scratch2 != 0 || scratch3 != 0x0f) { /* we fail, there's nothing here */ pr_err("port existence test failed, cannot continue\n"); return -ENODEV; } /* Set DLAB 0. */ soutp(UART_LCR, sinp(UART_LCR) & (~UART_LCR_DLAB)); /* First of all, disable all interrupts */ soutp(UART_IER, sinp(UART_IER) & (~(UART_IER_MSI | UART_IER_RLSI | UART_IER_THRI | UART_IER_RDI))); /* Clear registers. */ sinp(UART_LSR); sinp(UART_RX); sinp(UART_IIR); sinp(UART_MSR); /* Set line for power source */ off(); /* Clear registers again to be sure. */ sinp(UART_LSR); sinp(UART_RX); sinp(UART_IIR); sinp(UART_MSR); switch (type) { case IR_IRDEO: case IR_IRDEO_REMOTE: /* setup port to 7N1 @ 115200 Baud */ /* 7N1+start = 9 bits at 115200 ~ 3 bits at 38kHz */ /* Set DLAB 1. */ soutp(UART_LCR, sinp(UART_LCR) | UART_LCR_DLAB); /* Set divisor to 1 => 115200 Baud */ soutp(UART_DLM, 0); soutp(UART_DLL, 1); /* Set DLAB 0 + 7N1 */ soutp(UART_LCR, UART_LCR_WLEN7); /* THR interrupt already disabled at this point */ break; default: break; } return 0; }
static void send_space_homebrew(void) { off(); }
void LED13::blink(int time) { on(); delay(time/2); off(); delay(time/2); }
void Relay::stop( void) { Timer1.stop(); is_inaction = false; off(); }
void QgsEllipseSymbolLayerV2::renderPoint( const QPointF& point, QgsSymbolV2RenderContext& context ) { QgsExpression* outlineWidthExpression = expression( "outline_width" ); QgsExpression* fillColorExpression = expression( "fill_color" ); QgsExpression* outlineColorExpression = expression( "outline_color" ); QgsExpression* widthExpression = expression( "width" ); QgsExpression* heightExpression = expression( "height" ); QgsExpression* symbolNameExpression = expression( "symbol_name" ); QgsExpression* rotationExpression = expression( "rotation" ); if ( outlineWidthExpression ) { double width = outlineWidthExpression->evaluate( const_cast<QgsFeature*>( context.feature() ) ).toDouble(); width *= QgsSymbolLayerV2Utils::lineWidthScaleFactor( context.renderContext(), mOutlineWidthUnit ); mPen.setWidthF( width ); } if ( fillColorExpression ) { QString colorString = fillColorExpression->evaluate( const_cast<QgsFeature*>( context.feature() ) ).toString(); mBrush.setColor( QColor( QgsSymbolLayerV2Utils::decodeColor( colorString ) ) ); } if ( outlineColorExpression ) { QString colorString = outlineColorExpression->evaluate( const_cast<QgsFeature*>( context.feature() ) ).toString(); mPen.setColor( QColor( QgsSymbolLayerV2Utils::decodeColor( colorString ) ) ); } if ( widthExpression || heightExpression || symbolNameExpression ) { QString symbolName = mSymbolName; if ( symbolNameExpression ) { symbolName = symbolNameExpression->evaluate( const_cast<QgsFeature*>( context.feature() ) ).toString(); } preparePath( symbolName, context, context.feature() ); } //offset double offsetX = 0; double offsetY = 0; markerOffset( context, mSymbolWidth, mSymbolHeight, mSymbolWidthUnit, mSymbolHeightUnit, offsetX, offsetY ); QPointF off( offsetX, offsetY ); QPainter* p = context.renderContext().painter(); if ( !p ) { return; } //priority for rotation: 1. data defined symbol level, 2. symbol layer rotation (mAngle) double rotation = 0.0; if ( rotationExpression ) { rotation = rotationExpression->evaluate( const_cast<QgsFeature*>( context.feature() ) ).toDouble(); } else if ( !qgsDoubleNear( mAngle, 0.0 ) ) { rotation = mAngle; } if ( rotation ) off = _rotatedOffset( off, rotation ); QMatrix transform; transform.translate( point.x() + off.x(), point.y() + off.y() ); if ( !qgsDoubleNear( rotation, 0.0 ) ) { transform.rotate( rotation ); } p->setPen( mPen ); p->setBrush( mBrush ); p->drawPath( transform.map( mPainterPath ) ); }
Point2f offF(int i) const { return off(i).cast<float>(); }
/*! Destructor to close the device. Turn the ring light off. \exception vpParallelPortException::closing If the device used to access to the parallel port can't be closed. */ vpRingLight::~vpRingLight() { off(); }
//================================================================================================= void FlowContainer::Update(float dt) { bool ok = false; group = -1; id = -1; if(mouse_focus) { if(IsInside(GUI.cursor_pos)) { ok = true; if(Key.Focus()) scroll.ApplyMouseWheel(); Int2 off(0, (int)scroll.offset); for(FlowItem* fi : items) { Int2 p = fi->pos - off + global_pos; if(fi->type == FlowItem::Item) { if(fi->group != -1 && PointInRect(GUI.cursor_pos, p, fi->size)) { group = fi->group; id = fi->id; if(allow_select && fi->state != Button::DISABLED) { GUI.cursor_mode = CURSOR_HAND; if(on_select && Key.Pressed(VK_LBUTTON)) { selected = fi; on_select(); return; } } } } else if(fi->type == FlowItem::Button && fi->state != Button::DISABLED) { if(PointInRect(GUI.cursor_pos, p, fi->size)) { GUI.cursor_mode = CURSOR_HAND; if(fi->state == Button::DOWN) { if(Key.Up(VK_LBUTTON)) { fi->state = Button::HOVER; on_button(fi->group, fi->id); return; } } else if(Key.Pressed(VK_LBUTTON)) fi->state = Button::DOWN; else fi->state = Button::HOVER; } else fi->state = Button::NONE; } } } scroll.mouse_focus = mouse_focus; scroll.Update(dt); } if(!ok) { for(FlowItem* fi : items) { if(fi->type == FlowItem::Button && fi->state != Button::DISABLED) fi->state = Button::NONE; } } }
PAMH_ARG_DECL(char * create_password_hash, const char *password, unsigned int ctrl, int rounds) { const char *algoid; char salt[64]; /* contains rounds number + max 16 bytes of salt + algo id */ char *sp; if (on(UNIX_MD5_PASS, ctrl)) { /* algoid = "$1" */ return crypt_md5_wrapper(password); } else if (on(UNIX_BLOWFISH_PASS, ctrl)) { algoid = "$2a$"; } else if (on(UNIX_SHA256_PASS, ctrl)) { algoid = "$5$"; } else if (on(UNIX_SHA512_PASS, ctrl)) { algoid = "$6$"; } else { /* must be crypt/bigcrypt */ char tmppass[9]; char *crypted; crypt_make_salt(salt, 2); if (off(UNIX_BIGCRYPT, ctrl) && strlen(password) > 8) { strncpy(tmppass, password, sizeof(tmppass)-1); tmppass[sizeof(tmppass)-1] = '\0'; password = tmppass; } crypted = bigcrypt(password, salt); memset(tmppass, '\0', sizeof(tmppass)); password = NULL; return crypted; } #ifdef HAVE_CRYPT_GENSALT_R if (on(UNIX_BLOWFISH_PASS, ctrl)) { char entropy[17]; crypt_make_salt(entropy, sizeof(entropy) - 1); sp = crypt_gensalt_r (algoid, rounds, entropy, sizeof(entropy), salt, sizeof(salt)); } else { #endif sp = stpcpy(salt, algoid); if (on(UNIX_ALGO_ROUNDS, ctrl)) { sp += snprintf(sp, sizeof(salt) - 3, "rounds=%u$", rounds); } crypt_make_salt(sp, 8); /* For now be conservative so the resulting hashes * are not too long. 8 bytes of salt prevents dictionary * attacks well enough. */ #ifdef HAVE_CRYPT_GENSALT_R } #endif sp = crypt(password, salt); if (!sp || strncmp(algoid, sp, strlen(algoid)) != 0) { /* libxcrypt/libc doesn't know the algorithm, use MD5 */ pam_syslog(pamh, LOG_ERR, "Algo %s not supported by the crypto backend, " "falling back to MD5\n", on(UNIX_BLOWFISH_PASS, ctrl) ? "blowfish" : on(UNIX_SHA256_PASS, ctrl) ? "sha256" : on(UNIX_SHA512_PASS, ctrl) ? "sha512" : algoid); if(sp) { memset(sp, '\0', strlen(sp)); } return crypt_md5_wrapper(password); } return x_strdup(sp); }
/*---------------------------------------------------------------------------*/ static int send_packet(void) { rtimer_clock_t t0; rtimer_clock_t t; rtimer_clock_t encounter_time = 0; int strobes; #if 0 struct xmac_hdr *hdr; #endif uint8_t got_strobe_ack = 0; uint8_t got_ack = 0; uint8_t strobe[MAX_STROBE_SIZE]; int strobe_len, len; int is_broadcast = 0; int is_reliable; struct encounter *e; struct queuebuf *packet; int is_already_streaming = 0; uint8_t collisions; /* Create the X-MAC header for the data packet. */ packetbuf_set_addr(PACKETBUF_ADDR_SENDER, &rimeaddr_node_addr); if(rimeaddr_cmp(packetbuf_addr(PACKETBUF_ADDR_RECEIVER), &rimeaddr_null)) { is_broadcast = 1; PRINTDEBUG("xmac: send broadcast\n"); } else { #if UIP_CONF_IPV6 PRINTDEBUG("xmac: send unicast to %02x%02x:%02x%02x:%02x%02x:%02x%02x\n", packetbuf_addr(PACKETBUF_ADDR_RECEIVER)->u8[0], packetbuf_addr(PACKETBUF_ADDR_RECEIVER)->u8[1], packetbuf_addr(PACKETBUF_ADDR_RECEIVER)->u8[2], packetbuf_addr(PACKETBUF_ADDR_RECEIVER)->u8[3], packetbuf_addr(PACKETBUF_ADDR_RECEIVER)->u8[4], packetbuf_addr(PACKETBUF_ADDR_RECEIVER)->u8[5], packetbuf_addr(PACKETBUF_ADDR_RECEIVER)->u8[6], packetbuf_addr(PACKETBUF_ADDR_RECEIVER)->u8[7]); #else PRINTDEBUG("xmac: send unicast to %u.%u\n", packetbuf_addr(PACKETBUF_ADDR_RECEIVER)->u8[0], packetbuf_addr(PACKETBUF_ADDR_RECEIVER)->u8[1]); #endif /* UIP_CONF_IPV6 */ } is_reliable = packetbuf_attr(PACKETBUF_ATTR_RELIABLE) || packetbuf_attr(PACKETBUF_ATTR_ERELIABLE); packetbuf_set_attr(PACKETBUF_ATTR_MAC_ACK, 1); len = NETSTACK_FRAMER.create(); strobe_len = len + sizeof(struct xmac_hdr); if(len == 0 || strobe_len > (int)sizeof(strobe)) { /* Failed to send */ PRINTF("xmac: send failed, too large header\n"); return MAC_TX_ERR_FATAL; } memcpy(strobe, packetbuf_hdrptr(), len); strobe[len] = DISPATCH; /* dispatch */ strobe[len + 1] = TYPE_STROBE; /* type */ packetbuf_compact(); packet = queuebuf_new_from_packetbuf(); if(packet == NULL) { /* No buffer available */ PRINTF("xmac: send failed, no queue buffer available (of %u)\n", QUEUEBUF_CONF_NUM); return MAC_TX_ERR; } #if WITH_STREAMING if(is_streaming == 1 && (rimeaddr_cmp(packetbuf_addr(PACKETBUF_ADDR_RECEIVER), &is_streaming_to) || rimeaddr_cmp(packetbuf_addr(PACKETBUF_ADDR_RECEIVER), &is_streaming_to_too))) { is_already_streaming = 1; } if(packetbuf_attr(PACKETBUF_ATTR_PACKET_TYPE) == PACKETBUF_ATTR_PACKET_TYPE_STREAM) { is_streaming = 1; if(rimeaddr_cmp(&is_streaming_to, &rimeaddr_null)) { rimeaddr_copy(&is_streaming_to, packetbuf_addr(PACKETBUF_ADDR_RECEIVER)); } else if(!rimeaddr_cmp(&is_streaming_to, packetbuf_addr(PACKETBUF_ADDR_RECEIVER))) { rimeaddr_copy(&is_streaming_to_too, packetbuf_addr(PACKETBUF_ADDR_RECEIVER)); } stream_until = RTIMER_NOW() + DEFAULT_STREAM_TIME; } #endif /* WITH_STREAMING */ off(); #if WITH_ENCOUNTER_OPTIMIZATION /* We go through the list of encounters to find if we have recorded an encounter with this particular neighbor. If so, we can compute the time for the next expected encounter and setup a ctimer to switch on the radio just before the encounter. */ for(e = list_head(encounter_list); e != NULL; e = list_item_next(e)) { const rimeaddr_t *neighbor = packetbuf_addr(PACKETBUF_ADDR_RECEIVER); if(rimeaddr_cmp(neighbor, &e->neighbor)) { rtimer_clock_t wait, now, expected; /* We expect encounters to happen every DEFAULT_PERIOD time units. The next expected encounter is at time e->time + DEFAULT_PERIOD. To compute a relative offset, we subtract with clock_time(). Because we are only interested in turning on the radio within the DEFAULT_PERIOD period, we compute the waiting time with modulo DEFAULT_PERIOD. */ now = RTIMER_NOW(); wait = ((rtimer_clock_t)(e->time - now)) % (DEFAULT_PERIOD); if(wait < 2 * DEFAULT_ON_TIME) { wait = DEFAULT_PERIOD; } expected = now + wait - 2 * DEFAULT_ON_TIME; #if WITH_ACK_OPTIMIZATION /* Wait until the receiver is expected to be awake */ if(packetbuf_attr(PACKETBUF_ATTR_PACKET_TYPE) != PACKETBUF_ATTR_PACKET_TYPE_ACK && is_streaming == 0) { /* Do not wait if we are sending an ACK, because then the receiver will already be awake. */ while(RTIMER_CLOCK_LT(RTIMER_NOW(), expected)); } #else /* WITH_ACK_OPTIMIZATION */ /* Wait until the receiver is expected to be awake */ while(RTIMER_CLOCK_LT(RTIMER_NOW(), expected)); #endif /* WITH_ACK_OPTIMIZATION */ } } #endif /* WITH_ENCOUNTER_OPTIMIZATION */ /* By setting we_are_sending to one, we ensure that the rtimer powercycle interrupt do not interfere with us sending the packet. */ we_are_sending = 1; t0 = RTIMER_NOW(); strobes = 0; LEDS_ON(LEDS_BLUE); /* Send a train of strobes until the receiver answers with an ACK. */ /* Turn on the radio to listen for the strobe ACK. */ // on(); collisions = 0; if(!is_already_streaming) { watchdog_stop(); got_strobe_ack = 0; t = RTIMER_NOW(); for(strobes = 0, collisions = 0; got_strobe_ack == 0 && collisions == 0 && RTIMER_CLOCK_LT(RTIMER_NOW(), t0 + xmac_config.strobe_time); strobes++) { while(got_strobe_ack == 0 && RTIMER_CLOCK_LT(RTIMER_NOW(), t + xmac_config.strobe_wait_time)) { #if 0 rtimer_clock_t now = RTIMER_NOW(); /* See if we got an ACK */ packetbuf_clear(); len = NETSTACK_RADIO.read(packetbuf_dataptr(), PACKETBUF_SIZE); if(len > 0) { packetbuf_set_datalen(len); if(NETSTACK_FRAMER.parse()) { hdr = packetbuf_dataptr(); if(hdr->dispatch == DISPATCH && hdr->type == TYPE_STROBE_ACK) { if(rimeaddr_cmp(packetbuf_addr(PACKETBUF_ADDR_RECEIVER), &rimeaddr_node_addr)) { /* We got an ACK from the receiver, so we can immediately send the packet. */ got_strobe_ack = 1; encounter_time = now; } else { PRINTDEBUG("xmac: strobe ack for someone else\n"); } } else { /*if(hdr->dispatch == DISPATCH && hdr->type == TYPE_STROBE)*/ PRINTDEBUG("xmac: strobe from someone else\n"); collisions++; } } else { PRINTF("xmac: send failed to parse %u\n", len); } } #endif /* 0 */ } t = RTIMER_NOW(); /* Send the strobe packet. */ if(got_strobe_ack == 0 && collisions == 0) { if(is_broadcast) { #if WITH_STROBE_BROADCAST NETSTACK_RADIO.send(strobe, strobe_len); #else /* restore the packet to send */ queuebuf_to_packetbuf(packet); NETSTACK_RADIO.send(packetbuf_hdrptr(), packetbuf_totlen()); #endif off(); } else { #if 0 rtimer_clock_t wt; #endif on(); NETSTACK_RADIO.send(strobe, strobe_len); #if 0 /* Turn off the radio for a while to let the other side respond. We don't need to keep our radio on when we know that the other side needs some time to produce a reply. */ off(); wt = RTIMER_NOW(); while(RTIMER_CLOCK_LT(RTIMER_NOW(), wt + WAIT_TIME_BEFORE_STROBE_ACK)); #endif /* 0 */ if(detect_ack()) { got_strobe_ack = 1; } else { off(); } } } } } #if WITH_ACK_OPTIMIZATION /* If we have received the strobe ACK, and we are sending a packet that will need an upper layer ACK (as signified by the PACKETBUF_ATTR_RELIABLE packet attribute), we keep the radio on. */ if(got_strobe_ack && (packetbuf_attr(PACKETBUF_ATTR_RELIABLE) || packetbuf_attr(PACKETBUF_ATTR_ERELIABLE) || packetbuf_attr(PACKETBUF_ATTR_PACKET_TYPE) == PACKETBUF_ATTR_PACKET_TYPE_STREAM)) { on(); /* Wait for ACK packet */ waiting_for_packet = 1; } else { off(); } #endif /* WITH_ACK_OPTIMIZATION */ /* restore the packet to send */ queuebuf_to_packetbuf(packet); queuebuf_free(packet); /* Send the data packet. */ if((is_broadcast || got_strobe_ack || is_streaming) && collisions == 0) { NETSTACK_RADIO.send(packetbuf_hdrptr(), packetbuf_totlen()); if(!is_broadcast) { if(detect_ack()) { got_ack = 1; } } } off(); #if WITH_ENCOUNTER_OPTIMIZATION if(got_strobe_ack && !is_streaming) { register_encounter(packetbuf_addr(PACKETBUF_ADDR_RECEIVER), encounter_time); } #endif /* WITH_ENCOUNTER_OPTIMIZATION */ watchdog_start(); PRINTF("xmac: send (strobes=%u,len=%u,%s), done\n", strobes, packetbuf_totlen(), got_strobe_ack ? "ack" : "no ack"); #if XMAC_CONF_COMPOWER /* Accumulate the power consumption for the packet transmission. */ compower_accumulate(¤t_packet); /* Convert the accumulated power consumption for the transmitted packet to packet attributes so that the higher levels can keep track of the amount of energy spent on transmitting the packet. */ compower_attrconv(¤t_packet); /* Clear the accumulated power consumption so that it is ready for the next packet. */ compower_clear(¤t_packet); #endif /* XMAC_CONF_COMPOWER */ we_are_sending = 0; LEDS_OFF(LEDS_BLUE); if(collisions == 0) { if(is_broadcast == 0 && got_ack == 0) { return MAC_TX_NOACK; } else { return MAC_TX_OK; } } else { someone_is_sending++; return MAC_TX_COLLISION; } }
Leds::Leds(PinName leftPin, PinName rightPin) : leftLed(leftPin), rightLed(rightPin){ off(ALL); }
void game::paint() const { //Positioning help point off(GAME_OFFSET, GAME_OFFSET); point top_left = point(GAME_SCALE*1/5); point bot_right = point(GAME_SCALE*4/5); //Colors SDL_Color c_border{ 0, 0, 0, 255 }; SDL_Color c_ghost{ 0, 0, 0, 128 }; SDL_Color c_player{ 200, 50, 50, 255 }; SDL_Color c_opponent{ 50, 50, 200, 255 }; //Draw last player color if (_lastmove_owner == player) PAINTER->push(c_player); if (_lastmove_owner == opponent) PAINTER->push(c_opponent); PAINTER->fill_circle(TURN_OFFSET, TURN_SIZE); PAINTER->pop(); //Paint with border color PAINTER->push(c_border); //Iterate cells for (size_t x = 0; x < _board.width(); ++x) { for (size_t y = 0; y < _board.height(); ++y) { point index = point(x, y); point current = off + index*GAME_SCALE; const cell & cell = _board.at(x, y); //Draw cell top-left circle PAINTER->fill_circle(current, GAME_SCALE / 10); //Draw top line if (cell.top) PAINTER->draw_line(current, current + point(1, 0)*GAME_SCALE, GAME_SCALE / 30); //Draw ghost top line else if (index == _ghost.index && _ghost.border == top && _ghost.possible) { PAINTER->push(c_ghost); PAINTER->draw_line(current, current + point(1, 0)*GAME_SCALE, GAME_SCALE / 30); PAINTER->pop(); } //Draw left line if (cell.left) PAINTER->draw_line(current, current + point(0, 1)*GAME_SCALE, GAME_SCALE / 30); //Draw ghost left line else if (index == _ghost.index && _ghost.border == left && _ghost.possible) { PAINTER->push(c_ghost); PAINTER->draw_line(current, current + point(0, 1)*GAME_SCALE, GAME_SCALE / 30); PAINTER->pop(); } //Draw owner (if any) if ((cell.owner & player_owned) != empty) { if (cell.owner == player) PAINTER->push(c_player); if (cell.owner == opponent) PAINTER->push(c_opponent); PAINTER->fill_rect(current + top_left, current + bot_right); PAINTER->pop(); } } } //Last move indicator if (_lastmove_radius > 0) PAINTER->draw_circle(_lastmove_position, _lastmove_radius); //Clear drawing color PAINTER->pop(); }
void QgsEllipseSymbolLayerV2::renderPoint( const QPointF& point, QgsSymbolV2RenderContext& context ) { bool ok; if ( hasDataDefinedProperty( QgsSymbolLayerV2::EXPR_OUTLINE_WIDTH ) ) { context.setOriginalValueVariable( mOutlineWidth ); double width = evaluateDataDefinedProperty( QgsSymbolLayerV2::EXPR_OUTLINE_WIDTH, context, mOutlineWidth ).toDouble(); width = QgsSymbolLayerV2Utils::convertToPainterUnits( context.renderContext(), width, mOutlineWidthUnit, mOutlineWidthMapUnitScale ); mPen.setWidthF( width ); } if ( hasDataDefinedProperty( QgsSymbolLayerV2::EXPR_OUTLINE_STYLE ) ) { context.setOriginalValueVariable( QgsSymbolLayerV2Utils::encodePenStyle( mPen.style() ) ); QString styleString = evaluateDataDefinedProperty( QgsSymbolLayerV2::EXPR_OUTLINE_STYLE, context, QVariant(), &ok ).toString(); if ( ok ) { Qt::PenStyle style = QgsSymbolLayerV2Utils::decodePenStyle( styleString ); mPen.setStyle( style ); } } if ( hasDataDefinedProperty( QgsSymbolLayerV2::EXPR_FILL_COLOR ) ) { context.setOriginalValueVariable( QgsSymbolLayerV2Utils::encodeColor( mBrush.color() ) ); QString colorString = evaluateDataDefinedProperty( QgsSymbolLayerV2::EXPR_FILL_COLOR, context, QVariant(), &ok ).toString(); if ( ok ) mBrush.setColor( QgsSymbolLayerV2Utils::decodeColor( colorString ) ); } if ( hasDataDefinedProperty( QgsSymbolLayerV2::EXPR_OUTLINE_COLOR ) ) { context.setOriginalValueVariable( QgsSymbolLayerV2Utils::encodeColor( mPen.color() ) ); QString colorString = evaluateDataDefinedProperty( QgsSymbolLayerV2::EXPR_OUTLINE_COLOR, context, QVariant(), &ok ).toString(); if ( ok ) mPen.setColor( QgsSymbolLayerV2Utils::decodeColor( colorString ) ); } double scaledWidth = mSymbolWidth; double scaledHeight = mSymbolHeight; if ( hasDataDefinedProperty( QgsSymbolLayerV2::EXPR_WIDTH ) || hasDataDefinedProperty( QgsSymbolLayerV2::EXPR_HEIGHT ) || hasDataDefinedProperty( QgsSymbolLayerV2::EXPR_SYMBOL_NAME ) ) { QString symbolName = mSymbolName; if ( hasDataDefinedProperty( QgsSymbolLayerV2::EXPR_SYMBOL_NAME ) ) { context.setOriginalValueVariable( mSymbolName ); symbolName = evaluateDataDefinedProperty( QgsSymbolLayerV2::EXPR_SYMBOL_NAME, context, mSymbolName ).toString(); } preparePath( symbolName, context, &scaledWidth, &scaledHeight, context.feature() ); } //offset double offsetX = 0; double offsetY = 0; markerOffset( context, scaledWidth, scaledHeight, mSymbolWidthUnit, mSymbolHeightUnit, offsetX, offsetY, mSymbolWidthMapUnitScale, mSymbolHeightMapUnitScale ); QPointF off( offsetX, offsetY ); QPainter* p = context.renderContext().painter(); if ( !p ) { return; } //priority for rotation: 1. data defined symbol level, 2. symbol layer rotation (mAngle) double rotation = 0.0; if ( hasDataDefinedProperty( QgsSymbolLayerV2::EXPR_ROTATION ) ) { context.setOriginalValueVariable( mAngle ); rotation = evaluateDataDefinedProperty( QgsSymbolLayerV2::EXPR_ROTATION, context, mAngle ).toDouble() + mLineAngle; } else if ( !qgsDoubleNear( mAngle + mLineAngle, 0.0 ) ) { rotation = mAngle + mLineAngle; } if ( rotation ) off = _rotatedOffset( off, rotation ); QMatrix transform; transform.translate( point.x() + off.x(), point.y() + off.y() ); if ( !qgsDoubleNear( rotation, 0.0 ) ) { transform.rotate( rotation ); } p->setPen( mPen ); p->setBrush( mBrush ); p->drawPath( transform.map( mPainterPath ) ); }
/*---------------------------------------------------------------------------*/ static int transmit(unsigned short transmit_len) { uint8_t counter; int ret = RADIO_TX_ERR; rtimer_clock_t t0; transmit_len; /* hush the warning */ if(!(rf_flags & RX_ACTIVE)) { t0 = RTIMER_NOW(); on(); rf_flags |= WAS_OFF; while(RTIMER_CLOCK_LT(RTIMER_NOW(), t0 + ONOFF_TIME)); } if(channel_clear() == CC2530_RF_CCA_BUSY) { RIMESTATS_ADD(contentiondrop); return RADIO_TX_COLLISION; } /* * prepare() double checked that TX_ACTIVE is low. If SFD is high we are * receiving. Abort transmission and bail out with RADIO_TX_COLLISION */ if(FSMSTAT1 & FSMSTAT1_SFD) { RIMESTATS_ADD(contentiondrop); return RADIO_TX_COLLISION; } /* Start the transmission */ RF_TX_LED_ON(); ENERGEST_OFF(ENERGEST_TYPE_LISTEN); ENERGEST_ON(ENERGEST_TYPE_TRANSMIT); CC2530_CSP_ISTXON(); counter = 0; while(!(FSMSTAT1 & FSMSTAT1_TX_ACTIVE) && (counter++ < 3)) { clock_delay_usec(6); } if(!(FSMSTAT1 & FSMSTAT1_TX_ACTIVE)) { PUTSTRING("RF: TX never active.\n"); CC2530_CSP_ISFLUSHTX(); ret = RADIO_TX_ERR; } else { /* Wait for the transmission to finish */ while(FSMSTAT1 & FSMSTAT1_TX_ACTIVE); ret = RADIO_TX_OK; } ENERGEST_OFF(ENERGEST_TYPE_TRANSMIT); ENERGEST_ON(ENERGEST_TYPE_LISTEN); if(rf_flags & WAS_OFF) { off(); } RIMESTATS_ADD(lltx); RF_TX_LED_OFF(); /* OK, sent. We are now ready to send more */ return ret; }
bool QgsEllipseSymbolLayerV2::writeDxf( QgsDxfExport& e, double mmMapUnitScaleFactor, const QString& layerName, QgsSymbolV2RenderContext *context, const QgsFeature*, const QPointF& shift ) const { //width double symbolWidth = mSymbolWidth; if ( hasDataDefinedProperty( QgsSymbolLayerV2::EXPR_WIDTH ) ) //1. priority: data defined setting on symbol layer le { context->setOriginalValueVariable( mSymbolWidth ); symbolWidth = evaluateDataDefinedProperty( QgsSymbolLayerV2::EXPR_WIDTH, *context, mSymbolWidth ).toDouble(); } else if ( context->renderHints() & QgsSymbolV2::DataDefinedSizeScale ) //2. priority: is data defined size on symbol level { symbolWidth = mSize; } if ( mSymbolWidthUnit == QgsSymbolV2::MM ) { symbolWidth *= mmMapUnitScaleFactor; } //height double symbolHeight = mSymbolHeight; if ( hasDataDefinedProperty( QgsSymbolLayerV2::EXPR_HEIGHT ) ) //1. priority: data defined setting on symbol layer level { context->setOriginalValueVariable( mSymbolHeight ); symbolHeight = evaluateDataDefinedProperty( QgsSymbolLayerV2::EXPR_HEIGHT, *context, mSymbolHeight ).toDouble(); } else if ( context->renderHints() & QgsSymbolV2::DataDefinedSizeScale ) //2. priority: is data defined size on symbol level { symbolHeight = mSize; } if ( mSymbolHeightUnit == QgsSymbolV2::MM ) { symbolHeight *= mmMapUnitScaleFactor; } //outline width double outlineWidth = mOutlineWidth; if ( hasDataDefinedProperty( QgsSymbolLayerV2::EXPR_OUTLINE_WIDTH ) ) { context->setOriginalValueVariable( mOutlineWidth ); outlineWidth = evaluateDataDefinedProperty( QgsSymbolLayerV2::EXPR_OUTLINE_WIDTH, *context, mOutlineWidth ).toDouble(); } if ( mOutlineWidthUnit == QgsSymbolV2::MM ) { outlineWidth *= outlineWidth; } //fill color bool ok; QColor fc = mFillColor; if ( hasDataDefinedProperty( QgsSymbolLayerV2::EXPR_FILL_COLOR ) ) { context->setOriginalValueVariable( QgsSymbolLayerV2Utils::encodeColor( mFillColor ) ); QString colorString = evaluateDataDefinedProperty( QgsSymbolLayerV2::EXPR_FILL_COLOR, *context, QVariant(), &ok ).toString(); if ( ok ) fc = QgsSymbolLayerV2Utils::decodeColor( colorString ); } //outline color QColor oc = mOutlineColor; if ( hasDataDefinedProperty( QgsSymbolLayerV2::EXPR_OUTLINE_COLOR ) ) { context->setOriginalValueVariable( QgsSymbolLayerV2Utils::encodeColor( mOutlineColor ) ); QString colorString = evaluateDataDefinedProperty( QgsSymbolLayerV2::EXPR_OUTLINE_COLOR, *context, QVariant(), &ok ).toString(); if ( ok ) oc = QgsSymbolLayerV2Utils::decodeColor( colorString ); } //symbol name QString symbolName = mSymbolName; if ( hasDataDefinedProperty( QgsSymbolLayerV2::EXPR_SYMBOL_NAME ) ) { context->setOriginalValueVariable( mSymbolName ); symbolName = evaluateDataDefinedProperty( QgsSymbolLayerV2::EXPR_SYMBOL_NAME, *context, mSymbolName ).toString(); } //offset double offsetX = 0; double offsetY = 0; markerOffset( *context, offsetX, offsetY ); QPointF off( offsetX, offsetY ); //priority for rotation: 1. data defined symbol level, 2. symbol layer rotation (mAngle) double rotation = 0.0; if ( hasDataDefinedProperty( QgsSymbolLayerV2::EXPR_ROTATION ) ) { context->setOriginalValueVariable( mAngle ); rotation = evaluateDataDefinedProperty( QgsSymbolLayerV2::EXPR_ROTATION, *context, mAngle ).toDouble() + mLineAngle; } else if ( !qgsDoubleNear( mAngle + mLineAngle, 0.0 ) ) { rotation = mAngle + mLineAngle; } rotation = -rotation; //rotation in Qt is counterclockwise if ( rotation ) off = _rotatedOffset( off, rotation ); QTransform t; t.translate( shift.x() + offsetX, shift.y() + offsetY ); if ( rotation != 0 ) t.rotate( rotation ); double halfWidth = symbolWidth / 2.0; double halfHeight = symbolHeight / 2.0; if ( symbolName == "circle" ) { if ( qgsDoubleNear( halfWidth, halfHeight ) ) { QPointF pt( t.map( QPointF( 0, 0 ) ) ); e.writeFilledCircle( layerName, oc, pt, halfWidth ); } else { QgsPolyline line; double stepsize = 2 * M_PI / 40; for ( int i = 0; i < 39; ++i ) { double angle = stepsize * i; double x = halfWidth * cos( angle ); double y = halfHeight * sin( angle ); QPointF pt( t.map( QPointF( x, y ) ) ); line.push_back( pt ); } //close ellipse with first point line.push_back( line.at( 0 ) ); if ( mBrush.style() != Qt::NoBrush ) e.writePolygon( QgsPolygon() << line, layerName, "SOLID", fc ); if ( mPen.style() != Qt::NoPen ) e.writePolyline( line, layerName, "CONTINUOUS", oc, outlineWidth ); } } else if ( symbolName == "rectangle" ) { QgsPolygon p( 1 ); p[0].resize( 5 ); p[0][0] = t.map( QPointF( -halfWidth, -halfHeight ) ); p[0][1] = t.map( QPointF( halfWidth, -halfHeight ) ); p[0][2] = t.map( QPointF( halfWidth, halfHeight ) ); p[0][3] = t.map( QPointF( -halfWidth, halfHeight ) ); p[0][4] = p[0][0]; if ( mBrush.style() != Qt::NoBrush ) e.writePolygon( p, layerName, "SOLID", fc ); if ( mPen.style() != Qt::NoPen ) e.writePolyline( p[0], layerName, "CONTINUOUS", oc, outlineWidth ); return true; } else if ( symbolName == "cross" && mPen.style() != Qt::NoPen ) { QgsPolyline line( 2 ); line[0] = t.map( QPointF( -halfWidth, 0 ) ); line[1] = t.map( QPointF( halfWidth, 0 ) ); e.writePolyline( line, layerName, "CONTINUOUS", oc, outlineWidth ); line[0] = t.map( QPointF( 0, halfHeight ) ); line[1] = t.map( QPointF( 0, -halfHeight ) ); e.writePolyline( line, layerName, "CONTINUOUS", oc, outlineWidth ); return true; } else if ( symbolName == "triangle" ) { QgsPolygon p( 1 ); p[0].resize( 4 ); p[0][0] = QPointF( t.map( QPointF( -halfWidth, -halfHeight ) ) ); p[0][1] = QPointF( t.map( QPointF( halfWidth, -halfHeight ) ) ); p[0][2] = QPointF( t.map( QPointF( 0, halfHeight ) ) ); p[0][3] = p[0][0]; if ( mBrush.style() != Qt::NoBrush ) e.writePolygon( p, layerName, "SOLID", fc ); if ( mPen.style() != Qt::NoPen ) e.writePolyline( p[0], layerName, "CONTINUOUS", oc, outlineWidth ); return true; } return false; //soon... }
/* Timer callback triggered when receiving a burst, after having waited for a next packet for a too long time. Turns the radio off and leaves burst reception mode */ static void recv_burst_off(void *ptr) { off(); we_are_receiving_burst = 0; }
*/ static void key_params_free(key_params_t *params) { assert(params); free(params->id); dnssec_binary_free(¶ms->public_key); clear_struct(params); } #define _cleanup_key_params_ _cleanup_(key_params_free) static const encode_attr_t KEY_ATTRIBUTES[] = { #define off(member) offsetof(key_params_t, member) { "id", off(id), encode_keyid, decode_keyid }, { "keytag", off(keytag), encode_uint16, decode_ignore }, { "algorithm", off(algorithm), encode_uint8, decode_uint8 }, { "public_key", off(public_key), encode_binary, decode_binary }, { "ksk", off(is_ksk), encode_bool, decode_bool }, { "created", off(timing.created), encode_time, decode_time }, { "publish", off(timing.publish), encode_time, decode_time }, { "active", off(timing.active), encode_time, decode_time }, { "retire", off(timing.retire), encode_time, decode_time }, { "remove", off(timing.remove), encode_time, decode_time }, { 0 } #undef off }; /* -- configuration loading ------------------------------------------------ */
Watchdog::Watchdog(uint8_t resetTime) { prescaler = resetTime; // set the prescaler value off(); // turn of the watchdog to avoid unexpected and weird problem due to multiple reset at initialization }
/*---------------------------------------------------------------------------*/ static int send_packet(mac_callback_t mac_callback, void *mac_callback_ptr) { rtimer_clock_t t0; rtimer_clock_t encounter_time = 0, previous_txtime = 0; int strobes; uint8_t got_strobe_ack = 0; int hdrlen, len; uint8_t is_broadcast = 0; uint8_t is_reliable = 0; uint8_t is_known_receiver = 0; uint8_t collisions; int transmit_len; int i; int ret; uint8_t contikimac_was_on; #if WITH_CONTIKIMAC_HEADER struct hdr *chdr; #endif /* WITH_CONTIKIMAC_HEADER */ if(packetbuf_totlen() == 0) { PRINTF("contikimac: send_packet data len 0\n"); return MAC_TX_ERR_FATAL; } packetbuf_set_addr(PACKETBUF_ADDR_SENDER, &rimeaddr_node_addr); if(rimeaddr_cmp(packetbuf_addr(PACKETBUF_ADDR_RECEIVER), &rimeaddr_null)) { is_broadcast = 1; PRINTDEBUG("contikimac: send broadcast\n"); if(broadcast_rate_drop()) { return MAC_TX_COLLISION; } } else { #if UIP_CONF_IPV6 PRINTDEBUG("contikimac: send unicast to %02x%02x:%02x%02x:%02x%02x:%02x%02x\n", packetbuf_addr(PACKETBUF_ADDR_RECEIVER)->u8[0], packetbuf_addr(PACKETBUF_ADDR_RECEIVER)->u8[1], packetbuf_addr(PACKETBUF_ADDR_RECEIVER)->u8[2], packetbuf_addr(PACKETBUF_ADDR_RECEIVER)->u8[3], packetbuf_addr(PACKETBUF_ADDR_RECEIVER)->u8[4], packetbuf_addr(PACKETBUF_ADDR_RECEIVER)->u8[5], packetbuf_addr(PACKETBUF_ADDR_RECEIVER)->u8[6], packetbuf_addr(PACKETBUF_ADDR_RECEIVER)->u8[7]); #else /* UIP_CONF_IPV6 */ PRINTDEBUG("contikimac: send unicast to %u.%u\n", packetbuf_addr(PACKETBUF_ADDR_RECEIVER)->u8[0], packetbuf_addr(PACKETBUF_ADDR_RECEIVER)->u8[1]); #endif /* UIP_CONF_IPV6 */ } is_reliable = packetbuf_attr(PACKETBUF_ATTR_RELIABLE) || packetbuf_attr(PACKETBUF_ATTR_ERELIABLE); if(WITH_STREAMING) { if(packetbuf_attr(PACKETBUF_ATTR_PACKET_TYPE) == PACKETBUF_ATTR_PACKET_TYPE_STREAM) { if(rimeaddr_cmp(&is_streaming_to, &rimeaddr_null)) { rimeaddr_copy(&is_streaming_to, packetbuf_addr(PACKETBUF_ADDR_RECEIVER)); } else if(!rimeaddr_cmp (&is_streaming_to, packetbuf_addr(PACKETBUF_ADDR_RECEIVER))) { rimeaddr_copy(&is_streaming_to_too, packetbuf_addr(PACKETBUF_ADDR_RECEIVER)); } stream_until = RTIMER_NOW() + DEFAULT_STREAM_TIME; is_streaming = 1; } } if(is_streaming) { packetbuf_set_attr(PACKETBUF_ATTR_PENDING, 1); } packetbuf_set_attr(PACKETBUF_ATTR_MAC_ACK, 1); #if WITH_CONTIKIMAC_HEADER hdrlen = packetbuf_totlen(); if(packetbuf_hdralloc(sizeof(struct hdr)) == 0) { /* Failed to allocate space for contikimac header */ PRINTF("contikimac: send failed, too large header\n"); return MAC_TX_ERR_FATAL; } chdr = packetbuf_hdrptr(); chdr->id = CONTIKIMAC_ID; chdr->len = hdrlen; /* Create the MAC header for the data packet. */ hdrlen = NETSTACK_FRAMER.create(); if(hdrlen == 0) { /* Failed to send */ PRINTF("contikimac: send failed, too large header\n"); packetbuf_hdr_remove(sizeof(struct hdr)); return MAC_TX_ERR_FATAL; } hdrlen += sizeof(struct hdr); #else /* Create the MAC header for the data packet. */ hdrlen = NETSTACK_FRAMER.create(); if(hdrlen == 0) { /* Failed to send */ PRINTF("contikimac: send failed, too large header\n"); return MAC_TX_ERR_FATAL; } #endif /* Make sure that the packet is longer or equal to the shortest packet length. */ transmit_len = packetbuf_totlen(); if(transmit_len < SHORTEST_PACKET_SIZE) { /* Pad with zeroes */ uint8_t *ptr; ptr = packetbuf_dataptr(); memset(ptr + packetbuf_datalen(), 0, SHORTEST_PACKET_SIZE - packetbuf_totlen()); PRINTF("contikimac: shorter than shortest (%d)\n", packetbuf_totlen()); transmit_len = SHORTEST_PACKET_SIZE; } packetbuf_compact(); NETSTACK_RADIO.prepare(packetbuf_hdrptr(), transmit_len); /* Remove the MAC-layer header since it will be recreated next time around. */ packetbuf_hdr_remove(hdrlen); if(!is_broadcast && !is_streaming) { #if WITH_PHASE_OPTIMIZATION ret = phase_wait(&phase_list, packetbuf_addr(PACKETBUF_ADDR_RECEIVER), CYCLE_TIME, GUARD_TIME, mac_callback, mac_callback_ptr); if(ret == PHASE_DEFERRED) { return MAC_TX_DEFERRED; } if(ret != PHASE_UNKNOWN) { is_known_receiver = 1; } #endif /* WITH_PHASE_OPTIMIZATION */ } /* By setting we_are_sending to one, we ensure that the rtimer powercycle interrupt do not interfere with us sending the packet. */ we_are_sending = 1; /* If we have a pending packet in the radio, we should not send now, because we will trash the received packet. Instead, we signal that we have a collision, which lets the packet be received. This packet will be retransmitted later by the MAC protocol instread. */ if(NETSTACK_RADIO.receiving_packet() || NETSTACK_RADIO.pending_packet()) { we_are_sending = 0; PRINTF("contikimac: collision receiving %d, pending %d\n", NETSTACK_RADIO.receiving_packet(), NETSTACK_RADIO.pending_packet()); return MAC_TX_COLLISION; } /* Switch off the radio to ensure that we didn't start sending while the radio was doing a channel check. */ off(); strobes = 0; /* Send a train of strobes until the receiver answers with an ACK. */ collisions = 0; got_strobe_ack = 0; /* Set contikimac_is_on to one to allow the on() and off() functions to control the radio. We restore the old value of contikimac_is_on when we are done. */ contikimac_was_on = contikimac_is_on; contikimac_is_on = 1; if(is_streaming == 0) { /* Check if there are any transmissions by others. */ for(i = 0; i < CCA_COUNT_MAX; ++i) { t0 = RTIMER_NOW(); on(); while(RTIMER_CLOCK_LT(RTIMER_NOW(), t0 + CCA_CHECK_TIME)) { } if(NETSTACK_RADIO.channel_clear() == 0) { collisions++; off(); break; } off(); t0 = RTIMER_NOW(); while(RTIMER_CLOCK_LT(RTIMER_NOW(), t0 + CCA_SLEEP_TIME)) { } } } if(collisions > 0) { we_are_sending = 0; off(); PRINTF("contikimac: collisions before sending\n"); contikimac_is_on = contikimac_was_on; return MAC_TX_COLLISION; } if(!is_broadcast) { on(); } watchdog_periodic(); t0 = RTIMER_NOW(); for(strobes = 0, collisions = 0; got_strobe_ack == 0 && collisions == 0 && RTIMER_CLOCK_LT(RTIMER_NOW(), t0 + STROBE_TIME); strobes++) { watchdog_periodic(); if(is_known_receiver && !RTIMER_CLOCK_LT(RTIMER_NOW(), t0 + MAX_PHASE_STROBE_TIME)) { PRINTF("miss to %d\n", packetbuf_addr(PACKETBUF_ADDR_RECEIVER)->u8[0]); break; } len = 0; previous_txtime = RTIMER_NOW(); { rtimer_clock_t wt; rtimer_clock_t txtime; int ret; txtime = RTIMER_NOW(); ret = NETSTACK_RADIO.transmit(transmit_len); wt = RTIMER_NOW(); while(RTIMER_CLOCK_LT(RTIMER_NOW(), wt + INTER_PACKET_INTERVAL)) { } if(!is_broadcast && (NETSTACK_RADIO.receiving_packet() || NETSTACK_RADIO.pending_packet() || NETSTACK_RADIO.channel_clear() == 0)) { uint8_t ackbuf[ACK_LEN]; wt = RTIMER_NOW(); while(RTIMER_CLOCK_LT(RTIMER_NOW(), wt + AFTER_ACK_DETECTECT_WAIT_TIME)) { } len = NETSTACK_RADIO.read(ackbuf, ACK_LEN); if(len == ACK_LEN) { got_strobe_ack = 1; encounter_time = previous_txtime; break; } else { PRINTF("contikimac: collisions while sending\n"); collisions++; } } previous_txtime = txtime; } } off(); PRINTF("contikimac: send (strobes=%u, len=%u, %s, %s), done\n", strobes, packetbuf_totlen(), got_strobe_ack ? "ack" : "no ack", collisions ? "collision" : "no collision"); #if CONTIKIMAC_CONF_COMPOWER /* Accumulate the power consumption for the packet transmission. */ compower_accumulate(¤t_packet); /* Convert the accumulated power consumption for the transmitted packet to packet attributes so that the higher levels can keep track of the amount of energy spent on transmitting the packet. */ compower_attrconv(¤t_packet); /* Clear the accumulated power consumption so that it is ready for the next packet. */ compower_clear(¤t_packet); #endif /* CONTIKIMAC_CONF_COMPOWER */ contikimac_is_on = contikimac_was_on; we_are_sending = 0; /* Determine the return value that we will return from the function. We must pass this value to the phase module before we return from the function. */ if(collisions > 0) { ret = MAC_TX_COLLISION; } else if(!is_broadcast && !got_strobe_ack) { ret = MAC_TX_NOACK; } else { ret = MAC_TX_OK; } #if WITH_PHASE_OPTIMIZATION if(is_known_receiver && got_strobe_ack) { PRINTF("no miss %d wake-ups %d\n", packetbuf_addr(PACKETBUF_ADDR_RECEIVER)->u8[0], strobes); } if(!is_broadcast) { if(collisions == 0 && is_streaming == 0) { phase_update(&phase_list, packetbuf_addr(PACKETBUF_ADDR_RECEIVER), encounter_time, ret); } } #endif /* WITH_PHASE_OPTIMIZATION */ if(WITH_STREAMING) { if(packetbuf_attr(PACKETBUF_ATTR_PACKET_TYPE) == PACKETBUF_ATTR_PACKET_TYPE_STREAM_END) { is_streaming = 0; } } return ret; }