void evilInit () { FILE *fp; char input[50]; if ((fp = fopen(CONFIG_FILE, "r")) == NULL) { fprintf(stderr, "Error: %d in evil send: fopen.\n", errno); exit(0); } fscanf(fp, "%s%d", input, &crptProb); fscanf(fp, "%s%d", input, &dropProb); fscanf(fp, "%s%d", input, &dupProb); fscanf(fp, "%s%d", input, &delayProb); fscanf(fp, "%s%d", input, &minDelay); fscanf(fp, "%s%d", input, &maxDelay); fclose(fp); assert((0 <= crptProb) && (crptProb <= 100)); assert((0 <= dropProb) && (dropProb <= 100)); assert((0 <= dupProb) && (dupProb <= 100)); assert((0 <= delayProb) && (delayProb <= 100)); assert((0 <= minDelay) && (minDelay <= maxDelay)); PRINTDEBUG(printf("Evil send initialized with parameters:\n\tCorrupt-Prob:\t\t%d%%\n\tDrop-Prob:\t\t%d%%\n\tDuplicate-Prob:\t\t%d%%\n\tDelay-Prob:\t\t%d%%\n\tMin-Delay:\t\t%dms\n\tMax-Delay:\t\t%dms\n", crptProb, dropProb, dupProb, delayProb, minDelay, maxDelay)); eventTimerInit(); }
static int Gather_ElementRestriction (DDD_OBJ obj, void *data) { ELEMENT *theElement = (ELEMENT *)obj; PRINTDEBUG(gm,4,(PFMT "Gather_ElementRestriction(): e=" EID_FMTX "\n", me,EID_PRTX(theElement))) ((int *)data)[0] = USED(theElement); return(GM_OK); }
void NS_DIM_PREFIX BVertexGatherBndP (BNDP *bndp, int cnt, char *data) { PRINTDEBUG(dom,1,("BVertexGatherBnd(): me %d pid %d " "n %d size %d cnt %d\n", me,BND_PATCH_ID(bndp), BND_N(bndp),BND_SIZE(bndp),cnt)); ASSERT(cnt == BND_SIZE(bndp)); memcpy(data,bndp,cnt); }
void NS_DIM_PREFIX BVertexXferBndP (BNDP *bndp, int proc, int prio) { INT size; size = BND_SIZE(bndp); PRINTDEBUG(dom,1,("BVertexXferBndP(): me %x %d pid %d n %d size %d\n", me,bndp,BND_PATCH_ID(bndp),BND_N(bndp),BND_SIZE(bndp))); DDD_XferAddData(size,DDD_DOMAIN_DATA); }
void NS_DIM_PREFIX BVertexScatterBndP (BNDP **bndp, int cnt, char *data) { if (*bndp == NULL) { *bndp = (BNDS *) memmgr_AllocOMEM((size_t)cnt,TypeBndP,0,0); memcpy(*bndp,data,cnt); PRINTDEBUG(dom,1,("BVertexScatterBndP(): me %d pid " "%d n %d size %d cnt %d\n", me,BND_PATCH_ID(*bndp), BND_N(*bndp),BND_SIZE(*bndp),cnt)); } }
static int Gather_RestrictedPartition (DDD_OBJ obj, void *data, DDD_PROC proc, DDD_PRIO prio) { ELEMENT *theElement = (ELEMENT *)obj; if (EMASTER(theElement)) { PRINTDEBUG(gm,4,(PFMT "Gather_RestrictedPartition(): e=" EID_FMTX "\n", me,EID_PRTX(theElement))) ((int *)data)[0] = PARTITION(theElement); } return(GM_OK); }
void delayedSend (void *args) { DelayedSendArgsType *temp; assert(args != NULL); temp = (DelayedSendArgsType *)args; PRINTDEBUG(printf("EVIL: sending delayed message on %d.\n", temp->sockfd)); if (sendto(temp->sockfd, temp->msg, temp->msgLen, temp->flags, temp->toAddr, temp->addrLen) < 0) { return; } free(temp->msg); free(temp->toAddr); }
static int Scatter_ElementRestriction (DDD_OBJ obj, void *data) { ELEMENT *theElement = (ELEMENT *)obj; int used; PRINTDEBUG(gm,4,(PFMT "Scatter_ElementRestriction(): e=" EID_FMTX "\n", me,EID_PRTX(theElement))) if (EMASTER(theElement)) { PRINTDEBUG(gm,4,(PFMT "Scatter_ElementRestriction(): restricting sons of e=" EID_FMTX "\n", me,EID_PRTX(theElement))) used = MAX(USED(theElement),((int *)data)[0]); SETUSED(theElement,used); } return(GM_OK); }
void NS_DIM_PREFIX BElementXferBndS (BNDS **bnds, int n, int proc, int prio) { INT size,i,size0; size = CEIL(sizeof(INT)); for (i=0; i<n; i++) if (bnds[i] != NULL) { size0 = BND_SIZE(bnds[i]); size += CEIL(size0) + CEIL(sizeof(INT)); PRINTDEBUG(dom,1,("BElementXferBndS(): Xfer me %x " "%d pid %d n %d size %d\n", me,bnds[i],BND_PATCH_ID(bnds[i]), BND_N(bnds[i]),BND_SIZE(bnds[i]))); } DDD_XferAddData(size,DDD_DOMAIN_DATA); }
static int Scatter_RestrictedPartition (DDD_OBJ obj, void *data, DDD_PROC proc, DDD_PRIO prio) { ELEMENT *theElement = (ELEMENT *)obj; ELEMENT *SonList[MAX_SONS]; int i,partition; if (USED(theElement) && EMASTERPRIO(prio)) { PRINTDEBUG(gm,4,(PFMT "Scatter_ElementRestriction(): restricting sons of e=" EID_FMTX "\n", me,EID_PRTX(theElement))) partition = ((int *)data)[0]; /* send master sons to master element partition */ if (GetSons(theElement,SonList)) RETURN(GM_ERROR); for (i=0; SonList[i]!=NULL; i++) PARTITION(SonList[i]) = partition; } return(GM_OK); }
void NS_DIM_PREFIX BElementGatherBndS (BNDS **bnds, int n, int cnt, char *data) { INT size,i; for (i=0; i<n; i++) if (bnds[i] != NULL) { PRINTDEBUG(dom,1,("BElementGatherBndS(): %d " "me %d %x pid %d n %d size %d\n",i, me,bnds[i],BND_PATCH_ID(bnds[i]), BND_N(bnds[i]),BND_SIZE(bnds[i]))); size = BND_SIZE(bnds[i]); memcpy(data,&i,sizeof(INT)); data += CEIL(sizeof(INT)); memcpy(data,bnds[i],size); data += CEIL(size); } i = -1; memcpy(data,&i,sizeof(INT)); }
void NS_DIM_PREFIX BElementScatterBndS (BNDS **bnds, int n, int cnt, char *data) { INT size,i; BNDS *bs; memcpy(&i,data,sizeof(INT)); while (i != -1) { data += CEIL(sizeof(INT)); bs = (BNDS *) data; size = BND_SIZE(bs); PRINTDEBUG(dom,1,("BElementScatterBndS(): %d me %d\n",i,size)); if (bnds[i] == NULL) { bs = (BNDS *) memmgr_AllocOMEM((size_t)size,TypeBndS,0,0); memcpy(bs,data,size); bnds[i] = bs; } data += CEIL(size); memcpy(&i,data,sizeof(INT)); } }
/*---------------------------------------------------------------------------*/ 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);*/ 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. */ if(mac_sequence_is_duplicate()) { /* Drop the packet. */ /* printf("Drop duplicate ContikiMAC layer packet\n");*/ return; } 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()); NETSTACK_MAC.input(); return; } else { PRINTDEBUG("contikimac: data not for us\n"); } } else { PRINTF("contikimac: failed to parse (%u)\n", packetbuf_totlen()); } }
/*---------------------------------------------------------------------------*/ static void powercycle_turn_radio_off(void) { #if CONTIKIMAC_CONF_COMPOWER uint8_t was_on = radio_is_on; #endif /* CONTIKIMAC_CONF_COMPOWER */ #if RDC_CONF_HARDWARE_SEND_ACK if(we_are_sending == 0 && we_are_receiving_burst == 0) { #else if(we_are_sending == 0 && we_are_receiving_burst == 0 && we_are_acking == 0) { #endif off(); #if CONTIKIMAC_CONF_COMPOWER if(was_on && !radio_is_on) { compower_accumulate(&compower_idle_activity); } #endif /* CONTIKIMAC_CONF_COMPOWER */ } } /*---------------------------------------------------------------------------*/ static void powercycle_turn_radio_on(void) { #if RDC_CONF_HARDWARE_SEND_ACK if(we_are_sending == 0 && we_are_receiving_burst == 0) { #else if(we_are_sending == 0 && we_are_receiving_burst == 0 && we_are_acking == 0) { #endif on(); } } /*---------------------------------------------------------------------------*/ static char powercycle(struct rtimer *t, void *ptr) { #if SYNC_CYCLE_STARTS static volatile rtimer_clock_t sync_cycle_start; static volatile uint8_t sync_cycle_phase; #endif PT_BEGIN(&pt); #if SYNC_CYCLE_STARTS sync_cycle_start = RTIMER_NOW(); #else cycle_start = RTIMER_NOW(); #endif while(1) { static uint8_t packet_seen; static rtimer_clock_t t0; static uint8_t count; #if SYNC_CYCLE_STARTS /* Compute cycle start when RTIMER_ARCH_SECOND is not a multiple of CHANNEL_CHECK_RATE */ if(sync_cycle_phase++ == NETSTACK_RDC_CHANNEL_CHECK_RATE) { sync_cycle_phase = 0; sync_cycle_start += RTIMER_ARCH_SECOND; cycle_start = sync_cycle_start; } else { #if (RTIMER_ARCH_SECOND * NETSTACK_RDC_CHANNEL_CHECK_RATE) > 65535 cycle_start = sync_cycle_start + ((unsigned long)(sync_cycle_phase*RTIMER_ARCH_SECOND))/NETSTACK_RDC_CHANNEL_CHECK_RATE; #else cycle_start = sync_cycle_start + (sync_cycle_phase*RTIMER_ARCH_SECOND)/NETSTACK_RDC_CHANNEL_CHECK_RATE; #endif } #else cycle_start += CYCLE_TIME; #endif packet_seen = 0; for(count = 0; count < CCA_COUNT_MAX; ++count) { t0 = RTIMER_NOW(); if(we_are_sending == 0 && we_are_receiving_burst == 0) { powercycle_turn_radio_on(); /* Check if a packet is seen in the air. If so, we keep the radio on for a while (LISTEN_TIME_AFTER_PACKET_DETECTED) to be able to receive the packet. We also continuously check the radio medium to make sure that we wasn't woken up by a false positive: a spurious radio interference that was not caused by an incoming packet. */ if(NETSTACK_RADIO.channel_clear() == 0) { packet_seen = 1; break; } powercycle_turn_radio_off(); } schedule_powercycle_fixed(t, RTIMER_NOW() + CCA_SLEEP_TIME); PT_YIELD(&pt); } if(packet_seen) { static rtimer_clock_t start; static uint8_t silence_periods, periods; start = RTIMER_NOW(); periods = silence_periods = 0; while(we_are_sending == 0 && radio_is_on && RTIMER_CLOCK_LT(RTIMER_NOW(), (start + LISTEN_TIME_AFTER_PACKET_DETECTED))) { /* Check for a number of consecutive periods of non-activity. If we see two such periods, we turn the radio off. Also, if a packet has been successfully received (as indicated by the NETSTACK_RADIO.pending_packet() function), we stop snooping. */ #if !RDC_CONF_HARDWARE_CSMA /* A cca cycle will disrupt rx on some radios, e.g. mc1322x, rf230 */ /*TODO: Modify those drivers to just return the internal RSSI when already in rx mode */ if(NETSTACK_RADIO.channel_clear()) { ++silence_periods; } else { silence_periods = 0; } #endif ++periods; if(NETSTACK_RADIO.receiving_packet()) { silence_periods = 0; } if(silence_periods > MAX_SILENCE_PERIODS) { powercycle_turn_radio_off(); break; } if(WITH_FAST_SLEEP && periods > MAX_NONACTIVITY_PERIODS && !(NETSTACK_RADIO.receiving_packet() || NETSTACK_RADIO.pending_packet())) { powercycle_turn_radio_off(); break; } if(NETSTACK_RADIO.pending_packet()) { break; } schedule_powercycle(t, CCA_CHECK_TIME + CCA_SLEEP_TIME); PT_YIELD(&pt); } if(radio_is_on) { if(!(NETSTACK_RADIO.receiving_packet() || NETSTACK_RADIO.pending_packet()) || !RTIMER_CLOCK_LT(RTIMER_NOW(), (start + LISTEN_TIME_AFTER_PACKET_DETECTED))) { powercycle_turn_radio_off(); } } } if(RTIMER_CLOCK_LT(RTIMER_NOW() - cycle_start, CYCLE_TIME - CHECK_TIME * 4)) { /* Schedule the next powercycle interrupt, or sleep the mcu until then. Sleeping will not exit from this interrupt, so ensure an occasional wake cycle or foreground processing will be blocked until a packet is detected */ #if RDC_CONF_MCU_SLEEP static uint8_t sleepcycle; if((sleepcycle++ < 16) && !we_are_sending && !radio_is_on) { rtimer_arch_sleep(CYCLE_TIME - (RTIMER_NOW() - cycle_start)); } else { sleepcycle = 0; schedule_powercycle_fixed(t, CYCLE_TIME + cycle_start); PT_YIELD(&pt); } #else schedule_powercycle_fixed(t, CYCLE_TIME + cycle_start); PT_YIELD(&pt); #endif } } PT_END(&pt); } /*---------------------------------------------------------------------------*/ static int broadcast_rate_drop(void) { #if CONTIKIMAC_CONF_BROADCAST_RATE_LIMIT if(!timer_expired(&broadcast_rate_timer)) { broadcast_rate_counter++; if(broadcast_rate_counter < CONTIKIMAC_CONF_BROADCAST_RATE_LIMIT) { return 0; } else { return 1; } } else { timer_set(&broadcast_rate_timer, CLOCK_SECOND); broadcast_rate_counter = 0; return 0; } #else /* CONTIKIMAC_CONF_BROADCAST_RATE_LIMIT */ return 0; #endif /* CONTIKIMAC_CONF_BROADCAST_RATE_LIMIT */ } /*---------------------------------------------------------------------------*/ 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; rtimer_clock_t encounter_time = 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 ret; uint8_t contikimac_was_on; uint8_t seqno; #if WITH_CONTIKIMAC_HEADER struct hdr *chdr; #endif /* WITH_CONTIKIMAC_HEADER */ /* 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, &rimeaddr_node_addr); #endif 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); 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(); #ifdef NETSTACK_ENCRYPT NETSTACK_ENCRYPT(); #endif /* NETSTACK_ENCRYPT */ transmit_len = packetbuf_totlen(); 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_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(); } #endif watchdog_periodic(); t0 = RTIMER_NOW(); seqno = packetbuf_attr(PACKETBUF_ATTR_MAC_SEQNO); 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; } len = 0; { rtimer_clock_t wt; rtimer_clock_t txtime; int ret; txtime = RTIMER_NOW(); ret = NETSTACK_RADIO.transmit(transmit_len); #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; encounter_time = txtime; 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); //PRINTF("%u %u vs %u", len, ackbuf[ACK_LEN - 1], seqno); if(len == ACK_LEN && seqno == ackbuf[ACK_LEN - 1]) { got_strobe_ack = 1; encounter_time = txtime; 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 qsend_packet(mac_callback_t sent, void *ptr) { int ret = send_packet(sent, ptr, NULL, 0); if(ret != MAC_TX_DEFERRED) { mac_call_sent_callback(sent, ptr, ret, 1); } }
/*---------------------------------------------------------------------------*/ 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 && (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 !RDC_CONF_HARDWARE_SEND_ACK if (rimeaddr_cmp(packetbuf_addr(PACKETBUF_ADDR_RECEIVER), &rimeaddr_node_addr)) { we_are_acking = 1; /* need to send an ack */ static uint8_t ackbuf[ACK_LEN] = { 0 }; ackbuf[ACK_LEN - 1] = packetbuf_attr(PACKETBUF_ATTR_PACKET_ID); NETSTACK_RADIO.send(ackbuf, ACK_LEN); we_are_acking = 0; } #endif /* 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()); } }
/*---------------------------------------------------------------------------*/ static void input_packet(void) { struct xmac_hdr *hdr; printf("input packet!\n"); if(NETSTACK_FRAMER.parse() >= 0) { 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() >= 0) { /* 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()); } }
/*---------------------------------------------------------------------------*/ 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 */ 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()); } }
//-----------------------------------------------------------------------------------------------------------------------// // main //-----------------------------------------------------------------------------------------------------------------------// int main(int argc, char * argv[]) { int rc=0; int rank=0; #ifdef MPI int comsize; // init MPI MPI_Init(&argc, &argv); MPI_Comm_size(MPI_COMM_WORLD, &comsize); MPI_Comm_rank(MPI_COMM_WORLD, &rank); fprintf(stderr,"rank=%d\n", rank); #ifdef BGQ install_signal_handler(); #endif #endif args = parseargs(argc, argv); // init, initcamera, initvolattrs if ((rc=init(args, rank) != 0)) { fprintf(stderr, "initialization failed: %d\n", rc); return 0; }; //---------------------------- Platform Specific Display and Interaction ----------------------------------------// #if LOCAL resettransforms(); mystate.alpha=0.25f; glutInit(&argc, argv); glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGBA | GLUT_DEPTH); glutInitWindowSize(WINDOWWIDTH, WINDOWHEIGHT); glutCreateWindow("iVR"); glutReshapeFunc(reshape); glutDisplayFunc(display); glutKeyboardFunc(keyboard); glutMouseFunc(mousebutton); glutMotionFunc(mousemotion); // glEnable(GL_DEPTH_TEST); glEnable(GL_CULL_FACE); glCullFace(GL_BACK); glDisable(GL_DEPTH_TEST); glutMainLoop(); #elif MPI // BEGIN MPI CODE #ifdef REMOTE // START OF REMOTE RENDERING HANDSHAKE // connect to relay server if (rank == 0) { sockfd = initconnection(HOSTNAME, PORT); if (sockfd == -1) { fprintf(stderr,"remote connection failed, sockfd=%d\n",sockfd); freeall(); exit(0); } fprintf(stderr,"relay connection succeeded\n"); } PRINTDEBUG("%3d: \n", rank); boolean_t connected = TRUE; int ctr = 0; while (connected) { // main loop when steering fprintf(stderr,"%3d: before steering control\n", rank); if (rank == 0) { rc = recvstate(sockfd, &mystate); fprintf(stderr,"bytes recvd=%d\n", rc); if (mystate.finish) connected = 0;; winwidth = mystate.winwidth; winheight=mystate.winheight; } // end if rank == 0 for remote visualization // wait until we've completed the handshake with steering client before proceeding; MPI_Barrier(MPI_COMM_WORLD); MPI_Bcast(&connected, 1, MPI_INT, 0, MPI_COMM_WORLD); if (!connected) break; MPI_Bcast((float *)&winwidth, 1, MPI_FLOAT, 0, MPI_COMM_WORLD); MPI_Bcast((float *)&winheight, 1, MPI_FLOAT, 0, MPI_COMM_WORLD); MPI_Bcast(&mystate.alpha, 1, MPI_FLOAT, 0, MPI_COMM_WORLD); MPI_Bcast(mystate.newconst, 6, MPI_FLOAT, 0, MPI_COMM_WORLD); MPI_Bcast(mystate.mvm, 16, MPI_FLOAT, 0, MPI_COMM_WORLD); MPI_Bcast(mystate.pm, 16, MPI_FLOAT, 0, MPI_COMM_WORLD); MPI_Bcast(mystate.vv, 4, MPI_FLOAT, 0, MPI_COMM_WORLD); #endif float planeconst[6] = {pzero[0], pzero[1], pzero[2], pzero[3], pzero[4], pzero[5]}; setviewport(&viewport, 0, 0, winwidth, winheight); setplaneconst(planeconst, mystate.newconst); setmvm(mvm, mystate.mvm); setpm(pm, mystate.pm); setfrustum(&viewvolume, mystate.vv); updatevolbbox(); initcolbufs(rank); // create and display the image unsigned long long lstart, lstop; for (int i=0; i<1; i++) { TIME(RENDER, lstart); createlocalimage(rank); // can't composite until all ranks have completed local image generation MPI_Barrier(MPI_COMM_WORLD); compositelocalimage(); TIME(RENDER, lstop); PERFORMANCE(lstart, lstop, framenum, elapsed, avg); } // wait until all ranks exit composite step before writing image MPI_Barrier(MPI_COMM_WORLD); writeimage(ctr++); #ifdef REMOTE } // end while remote loop if (rank == 0) disconnect(sockfd); #endif // END OF REMOTE CLIENT HANDSHAKE fprintf(stderr,"%3d: finished\n", rank); MPI_Barrier(MPI_COMM_WORLD); MPI_Finalize(); #endif // clean up freeall(); exit(0); }
/*---------------------------------------------------------------------------*/ static int send_packet(void) { rtimer_clock_t t0; rtimer_clock_t t; rtimer_clock_t encounter_time = 0; int strobes; int ret; #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() >= 0) { 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 ret = NETSTACK_RADIO.send(strobe, strobe_len); #else /* restore the packet to send */ queuebuf_to_packetbuf(packet); ret = NETSTACK_RADIO.send(packetbuf_hdrptr(), packetbuf_totlen()); #endif off(); } else { #if 0 rtimer_clock_t wt; #endif on(); ret = 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 RDC_CONF_HARDWARE_ACK if(ret == RADIO_TX_OK) { got_strobe_ack = 1; } else { off(); } #else if(detect_ack()) { got_strobe_ack = 1; } else { off(); } #endif /* RDC_CONF_HARDWARE_ACK */ } } } } #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) { ret = NETSTACK_RADIO.send(packetbuf_hdrptr(), packetbuf_totlen()); if(!is_broadcast) { #if RDC_CONF_HARDWARE_ACK if(ret == RADIO_TX_OK) { got_ack = 1; } #else if(detect_ack()) { got_ack = 1; } #endif /* RDC_CONF_HARDWARE_ACK */ } } 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; } }
ssize_t evilsendto (int sockfd, char *msg, size_t msgLen, int flags, struct sockaddr *toAddr, socklen_t addrLen) { sigset_t mask, oldmask; int bytesSent; DelayedSendArgsType *args; if (msgLen > MAX_MSG_LEN) { errno = EMSGSIZE; return -1; } sigemptyset(&mask); sigaddset(&mask, SIGALRM); sigaddset(&mask, SIGIO); if (pthread_sigmask(SIG_BLOCK, &mask, &oldmask) < 0) { fprintf(stderr, "Error: %d in evil send: sigmask.\n", errno); exit(0); }; if (toss(crptProb)) { int randomByte = (rand() % msgLen); printf("\nmsg before corrupion: %s",msg); printf("\ncorrupted:%c",msg[randomByte]); msg[randomByte] = ~msg[randomByte]; printf("\nmsg after corrupion: %s",msg); PRINTDEBUG(printf("EVIL: corrupting message on %d.\n", sockfd)); bytesSent = sendto(sockfd, msg, msgLen, flags, toAddr, addrLen); msg[randomByte] = ~msg[randomByte]; } else if (toss(dropProb)) { PRINTDEBUG(printf("EVIL: droping message on %d.\n", sockfd)); bytesSent = msgLen; } else if (toss(dupProb)) { struct timeval delay; int milliDelay; milliDelay = minDelay + rand()%(maxDelay-minDelay+1); delay.tv_sec = milliDelay/1000; delay.tv_usec = 1000 * (milliDelay%1000); PRINTDEBUG(printf("EVIL: duplicating message on %d.\n", sockfd)); if (milliDelay > 0) { args = makeDelayedSendArgs(sockfd, msg, msgLen, flags, toAddr, addrLen); if (setEvent(delay, delayedSend, args, sizeof(*args)) < 0) { fprintf(stderr, "Error: %d in evil send: setEvent.\n", errno); exit(0); } free(args); } else { bytesSent = sendto(sockfd, msg, msgLen, flags, toAddr, addrLen); } bytesSent = sendto(sockfd, msg, msgLen, flags, toAddr, addrLen); } else if (toss(delayProb)) { struct timeval delay; int milliDelay; milliDelay = minDelay + rand()%(maxDelay-minDelay+1); delay.tv_sec = milliDelay/1000; delay.tv_usec = 1000 * (milliDelay%1000); PRINTDEBUG(printf("EVIL: delaying message on %d.\n", sockfd)); if (milliDelay > 0) { args = makeDelayedSendArgs(sockfd, msg, msgLen, flags, toAddr, addrLen); if (setEvent(delay, delayedSend, args, sizeof(*args)) < 0) { fprintf(stderr, "Error: %d in evil send: setEvent.\n", errno); exit(0); } free(args); bytesSent = msgLen; } else { bytesSent = sendto(sockfd, msg, msgLen, flags, toAddr, addrLen); } } else { PRINTDEBUG(printf("EVIL: sending message on %d.\n", sockfd)); bytesSent = sendto(sockfd, msg, msgLen, flags, toAddr, addrLen); } if (pthread_sigmask(SIG_SETMASK, &oldmask, NULL) < 0) { fprintf(stderr, "Error: %d in evil send: sigmask.\n", errno); exit(0); }; return bytesSent; }
int compositelocalimage() { #ifdef MPI int rank, comsize; MPI_Comm_rank(MPI_COMM_WORLD, &rank); MPI_Comm_size(MPI_COMM_WORLD, &comsize); // create aabb array to store bboxes for all ranks AABB *abboxes=NULL, *bboxesorg=NULL; RECT *tiles=NULL; int hit=0; int numtiles = viewport.tilex * viewport.tiley; int x, y, w, h; bboxesorg = (AABB *) malloc(sizeof(AABB) * comsize); tiles = (RECT *) malloc(sizeof(RECT) * numtiles); abboxes = (AABB *) malloc(sizeof(AABB) * comsize); assert (bboxesorg != NULL && tiles != NULL && abboxes != NULL); // allgather parameters float *sbboxes=NULL; float *rbboxes=NULL; sbboxes = (float *) malloc(sizeof(float) * MAXPLANE); rbboxes = (float *) malloc(sizeof(float) * comsize * MAXPLANE); assert (sbboxes != NULL && rbboxes != NULL); sbboxes[0] = aabb.wincoord.x; sbboxes[1] = aabb.wincoord.y; sbboxes[2] = aabb.wincoord.z; sbboxes[3] = aabb.wincoord.w ; sbboxes[4] = aabb.wincoord.h ; sbboxes[5] = aabb.wincoord.d ; // Should we avoid doing this and just compute all teh bboxes for all ranks on each rank MPI_Allgather(sbboxes, MAXPLANE, MPI_FLOAT, rbboxes, MAXPLANE, MPI_FLOAT, MPI_COMM_WORLD); // could avoid this copy by splitting bboxes into two structures - rbboxes and bboxes for (int i=0, j=0; i<comsize; i++) { abboxes[i].wincoord.x = rbboxes[j++]; abboxes[i].wincoord.y = rbboxes[j++]; abboxes[i].wincoord.z = rbboxes[j++]; abboxes[i].wincoord.w = rbboxes[j++]; abboxes[i].wincoord.h = rbboxes[j++]; abboxes[i].wincoord.d = rbboxes[j++]; abboxes[i].wincoord.cx = abboxes[i].wincoord.x + abboxes[i].wincoord.w/2.0f; abboxes[i].wincoord.cy = abboxes[i].wincoord.y + abboxes[i].wincoord.h/2.0f; abboxes[i].rank = i; } memcpy(bboxesorg, abboxes, sizeof(aabb) * comsize); // sort by depth from near to far sortboxlist(0, comsize-1, abboxes); // compute overlap for each tile and subtile int (*rankspertile)[numtiles] = malloc(comsize * sizeof(*rankspertile)); assert(*rankspertile != NULL); //memset((void **) rankspertile, -1, sizeof(int) * comsize * numtiles); for (int m=0; m<comsize; m++) { for (int n=0; n<numtiles; n++) { rankspertile[m][n] = -1; } } // create tile parameters based on number of tiles and size of display createtiles(tiles, viewport); for (int j=0; j<numtiles; j++) { for (int i=0; i<comsize; i++) { // if the bbox overlaps the tile you compute the overlap region, // and place the rank # in the tiles[i] list array hit=intersectrect(abboxes[i].wincoord, tiles[j]); if (hit) { rankspertile[i][j] = abboxes[i].rank; PRINTDEBUG("%3d: TILE: %d -BOXRANK: %d - BBOXDEPTH: %f\n", rank, j, abboxes[i].rank, abboxes[i].wincoord.d); } } } #if 0 // there are h rows each representing a block // each row is the w of the tile times 4 floats (RGBA) // the next block is WINDOWWIDTH*4 (RGBA) floats from the current block position int w = (int) (tiles[rank].w/* + 0.5f*/); int h = (int) (tiles[rank].h/* + 0.5f*/); int x = (int) (tiles[rank].x/* + 0.5f*/); int y = (int) (tiles[rank].y/* + 0.5f*/); // init initbuffer initbuffer = (float *) malloc(sizeof(float) * w * h * ELEMENTSPERPIXEL); assert(initbuffer != NULL); for (int i=0,j=0; i<w*h; i++) { initbuffer[j] = 0.0f; initbuffer[j+1] = 0.0f; initbuffer[j+2] = 0.0f; initbuffer[j+3] = 1.0f; j += 4; } #endif int *r = (int *) malloc(sizeof(int) * comsize); int *s = (int *) malloc(sizeof(int) * comsize); assert (r != NULL && s != NULL); int rcv; int snd; MPI_Request rrequests[comsize]; MPI_Request srequests[comsize]; #ifdef IVR_DEBUG MPI_Status statuses[comsize]; #endif rcv = 0; snd = 0; for (int j=0; j<numtiles; j++) { w = (int) (tiles[j].w/* + 0.5f*/); h = (int) (tiles[j].h/* + 0.5f*/); x = (int) (tiles[j].x/* + 0.5f*/); y = (int) (tiles[j].y/* + 0.5f*/); fprintf(stderr,"tile=%d w,h=%d,%d\n", j,w,h); if (j == rank) owneroftile = j; for (int i=0; i<comsize; i++) { if (rankspertile[i][j] != -1) { if (owneroftile == j) { r[rcv] = rankspertile[i][j]; rcv++; } if (rankspertile[i][j] == rank) { s[snd] = j; snd++; } } } } int ns = 0; int nr = 0; float *rcolorbuf = NULL; if (rcv > 0) { rcolorbuf = (float *) malloc(sizeof(float) * w * h * rcv * ELEMENTSPERPIXEL); assert(rcolorbuf != NULL); #ifdef IVR_DEBUG for (int i=0; i<rcv; i++) { PRINTDEBUG("%3d: rcv=%d, i=%d, fromrnk %d\n", rank, rcv, i, r[i]); } #endif if (owneroftile == rank) { for (int i = 0; i < rcv; ++i) { float *rbuf = (rcolorbuf + w*h*ELEMENTSPERPIXEL*i); MPI_Irecv(rbuf, w*h*4, MPI_FLOAT, r[i], 0, MPI_COMM_WORLD, &rrequests[nr++]); } } } float *scolorbuf = NULL; if (snd > 0) { #ifdef IVR_DEBUG for (int i=0; i<snd; i++) { PRINTDEBUG("%3d: snd=%d, i=%d, torank %d\n", rank, snd, i, s[i]); } #endif scolorbuf = (float*) malloc(sizeof(float) * w *h * ELEMENTSPERPIXEL * snd); assert(scolorbuf != NULL); for (int i=0; i<snd; i++) { x = (int) (tiles[s[i]].x/* + 0.5f*/); y = (int) (tiles[s[i]].y/* + 0.5f*/); w = (int) (tiles[s[i]].w/* + 0.5f*/); h = (int) (tiles[s[i]].h/* + 0.5f*/); start = y*viewport.w + x; //PRINTDEBUG("%3d: START-XY =%d, %d, %f, %f\n", s[i], x, y); float *sbuf = (scolorbuf + w*h*ELEMENTSPERPIXEL*i); float *scolors = (float *) &(colorbuf[start]); stridememcpy(sbuf, scolors, h, w*ELEMENTSPERPIXEL, viewport.w*ELEMENTSPERPIXEL, sizeof(float)); MPI_Isend(sbuf, w*h*ELEMENTSPERPIXEL, MPI_FLOAT, s[i], 0, MPI_COMM_WORLD, &srequests[ns++]); } free(scolorbuf); } MPI_Waitall(nr, rrequests, MPI_STATUSES_IGNORE); MPI_Waitall(ns, srequests, MPI_STATUSES_IGNORE); // free(scolorbuf); //All data is in rcolorbuf on rank==r[0] if (owneroftile == rank) { //rank owns tile and there is something to composite int elements = w*h*ELEMENTSPERPIXEL; tilebuffer = (float *) malloc(elements*sizeof(float)); assert(tilebuffer != NULL); memcpy(tilebuffer, initbuffer, elements*sizeof(float)); if (rcv > 0) { PRINTDEBUGTILES(rcv, rank, elements, rcolorbuf); compositetiles(tilebuffer, rcolorbuf, rcv, w, h); free(rcolorbuf); } #ifdef IVR_DEBUG2 PRINTDEBUG("%3d: rcv=%d\n", rank, rcv); char fn[32]; sprintf(fn, "tile%d.raw", rank); FILE *fout = fopen(fn,"w+b"); fwrite(tilebuffer, elements,sizeof(float), fout); fclose(fout); #endif // free(rcolorbuf); } free(r); free(s); #if 0 free(initbuffer); #endif free((*rankspertile)); free(tiles); free(abboxes); free(sbboxes); free(rbboxes); free(bboxesorg); #endif return 0; }
void NS_DIM_PREFIX SetGhostObjectPriorities (GRID *theGrid) { ELEMENT *theElement,*theNeighbor,*SonList[MAX_SONS]; NODE *theNode; EDGE *theEdge; VECTOR *theVector; INT i,prio,*proclist,hghost,vghost; /* reset USED flag for objects of ghostelements */ for (theElement=PFIRSTELEMENT(theGrid); theElement!=NULL; theElement=SUCCE(theElement)) { SETUSED(theElement,0); SETTHEFLAG(theElement,0); for (i=0; i<EDGES_OF_ELEM(theElement); i++) { theEdge = GetEdge(CORNER(theElement,CORNER_OF_EDGE(theElement,i,0)), CORNER(theElement,CORNER_OF_EDGE(theElement,i,1))); ASSERT(theEdge != NULL); SETUSED(theEdge,0); SETTHEFLAG(theEdge,0); } if (VEC_DEF_IN_OBJ_OF_GRID(theGrid,SIDEVEC)) for (i=0; i<SIDES_OF_ELEM(theElement); i++) { theVector = SVECTOR(theElement,i); if (theVector != NULL) { SETUSED(theVector,0); SETTHEFLAG(theVector,0); } } } /* to reset also nodes which are at corners of the boundary */ /* reset of nodes need to be done through the node list */ for (theNode=PFIRSTNODE(theGrid); theNode!=NULL; theNode=SUCCN(theNode)) { SETUSED(theNode,0); SETTHEFLAG(theNode,0); SETMODIFIED(theNode,0); } /* set FLAG for objects of horizontal and vertical overlap */ for (theElement=PFIRSTELEMENT(theGrid); theElement!=NULL; theElement=SUCCE(theElement)) { if (PARTITION(theElement) == me) continue; /* check for horizontal ghost */ hghost = 0; for (i=0; i<SIDES_OF_ELEM(theElement); i++) { theNeighbor = NBELEM(theElement,i); if (theNeighbor == NULL) continue; if (PARTITION(theNeighbor) == me) { hghost = 1; break; } } /* check for vertical ghost */ vghost = 0; GetAllSons(theElement,SonList); for (i=0; SonList[i]!=NULL; i++) { if (PARTITION(SonList[i]) == me) { vghost = 1; break; } } /* one or both of vghost and hghost should be true here */ /* except for elements which will be disposed during Xfer */ if (vghost) SETTHEFLAG(theElement,1); if (hghost) SETUSED(theElement,1); for (i=0; i<CORNERS_OF_ELEM(theElement); i++) { theNode = CORNER(theElement,i); if (vghost) SETTHEFLAG(theNode,1); if (hghost) SETUSED(theNode,1); } for (i=0; i<EDGES_OF_ELEM(theElement); i++) { theEdge = GetEdge(CORNER_OF_EDGE_PTR(theElement,i,0), CORNER_OF_EDGE_PTR(theElement,i,1)); ASSERT(theEdge != NULL); if (vghost) SETTHEFLAG(theEdge,1); if (hghost) SETUSED(theEdge,1); } if (VEC_DEF_IN_OBJ_OF_GRID(theGrid,SIDEVEC)) for (i=0; i<SIDES_OF_ELEM(theElement); i++) { theVector = SVECTOR(theElement,i); if (theVector != NULL) { if (vghost) SETTHEFLAG(theVector,1); if (hghost) SETUSED(theVector,1); } } } DEBUG_TIME(0); /* set USED flag for objects of master elements */ /* reset FLAG for objects of master elements */ for (theElement=PFIRSTELEMENT(theGrid); theElement!=NULL; theElement=SUCCE(theElement)) { if (PARTITION(theElement) != me) continue; SETUSED(theElement,0); SETTHEFLAG(theElement,0); for (i=0; i<CORNERS_OF_ELEM(theElement); i++) { theNode = CORNER(theElement,i); SETUSED(theNode,0); SETTHEFLAG(theNode,0); SETMODIFIED(theNode,1); } for (i=0; i<EDGES_OF_ELEM(theElement); i++) { theEdge = GetEdge(CORNER_OF_EDGE_PTR(theElement,i,0), CORNER_OF_EDGE_PTR(theElement,i,1)); ASSERT(theEdge != NULL); SETUSED(theEdge,0); SETTHEFLAG(theEdge,0); } if (VEC_DEF_IN_OBJ_OF_GRID(theGrid,SIDEVEC)) for (i=0; i<SIDES_OF_ELEM(theElement); i++) { theVector = SVECTOR(theElement,i); if (theVector != NULL) { SETUSED(theVector,0); SETTHEFLAG(theVector,0); } } } DEBUG_TIME(0); /* set object priorities for ghostelements */ for (theElement=PFIRSTELEMENT(theGrid); theElement!=NULL; theElement=SUCCE(theElement)) { if (PARTITION(theElement) == me) continue; if (USED(theElement) || THEFLAG(theElement)) { prio = PRIO_CALC(theElement); PRINTDEBUG(gm,1,("SetGhostObjectPriorities(): e=" EID_FMTX " new prio=%d\n", EID_PRTX(theElement),prio)) SETEPRIOX(theElement,prio); if (VEC_DEF_IN_OBJ_OF_GRID(theGrid,ELEMVEC)) { theVector = EVECTOR(theElement); if (theVector != NULL) SETPRIOX(theVector,prio); } } /* set edge priorities */ for (i=0; i<EDGES_OF_ELEM(theElement); i++) { theEdge = GetEdge(CORNER(theElement,CORNER_OF_EDGE(theElement,i,0)), CORNER(theElement,CORNER_OF_EDGE(theElement,i,1))); ASSERT(theEdge != NULL); if (USED(theEdge) || THEFLAG(theEdge)) { PRINTDEBUG(dddif,3,(PFMT " dddif_SetGhostObjectPriorities():" " downgrade edge=" EDID_FMTX " from=%d to PrioHGhost\n", me,EDID_PRTX(theEdge),prio)); EDGE_PRIORITY_SET(theGrid,theEdge,PRIO_CALC(theEdge)); } else EDGE_PRIORITY_SET(theGrid,theEdge,PrioMaster); } #ifdef __THREEDIM__ /* if one(all) of the side nodes is (are) a hghost (vghost) node */ /* then its a hghost (vghost) side vector */ if (VEC_DEF_IN_OBJ_OF_GRID(theGrid,SIDEVEC)) for (i=0; i<SIDES_OF_ELEM(theElement); i++) { if (USED(theVector) || THEFLAG(theVector)) SETPRIOX(theVector,PRIO_CALC(theVector)); } #endif } /* to set also nodes which are at corners of the boundary */ /* set them through the node list */ for (theNode=PFIRSTNODE(theGrid); theNode!=NULL; theNode=SUCCN(theNode)) { /* check if its a master node */ if (USED(theNode) || THEFLAG(theNode)) { PRINTDEBUG(dddif,3,(PFMT " dddif_SetGhostObjectPriorities():" " downgrade node=" ID_FMTX " from=%d to PrioHGhost\n", me,ID_PRTX(theNode),prio)); /* set node priorities of node to ghost */ NODE_PRIORITY_SET(theGrid,theNode,PRIO_CALC(theNode)) } else if (MODIFIED(theNode) == 0)
INT InitGeometry (HEAP *Heap, GEOMETRY *G) { INT i; for (i=0; i<G->nP; i++) if (G->P[i].bnd == 1) { int k,n; if (G->P[i].segment <G->nS) n = 1; else n = G->L[G->P[i].segment-G->nS].n; ASSERT(n>0); G->P[i].bp = (BP *) GetFreelistMemory(Heap,sizeof(BP)+(n-1)*sizeof(int)); ASSERT(G->P[i].bp != NULL); G->P[i].bp->id = G->P[i].id; G->P[i].bp->n = n; if (n == 1) G->P[i].bp->segment[0] = G->P[i].segment; else for (k=0; k<n; k++) G->P[i].bp->segment[k] = G->L[G->P[i].segment-G->nS].S[k]; G->P[i].bp->property = 0; for (k=0; k<DIM; k++) G->P[i].bp->x[k] = G->P[i].x[k]; } for (i=0; i<G->nC; i++) if (G->C[i].bnd == 1) { int j; for (j=0; j<nfaces[G->C[i].n]; j++) { if (G->C[i].C[j] < 0) { int k; int in = G->S[G->C[i].S[j]].in; int out = G->S[G->C[i].S[j]].out; G->C[i].bs[j] = (BS *) GetFreelistMemory(Heap,sizeof(BS)); ASSERT(G->C[i].bs[j] != NULL); G->C[i].bs[j]->id = G->F[G->C[i].F[j]].id; G->C[i].bs[j]->in = G->C[i].subdomain; if (G->C[i].subdomain == in) G->C[i].bs[j]->out = out; else G->C[i].bs[j]->out = in; G->C[i].bs[j]->segment = G->C[i].S[j]; G->C[i].bs[j]->property = G->S[G->C[i].S[j]].property; G->C[i].bs[j]->n = ncfaces[G->C[i].n][j]; for (k=0; k<G->C[i].bs[j]->n; k++) { int l; for (l=0; l<DIM; l++) G->C[i].bs[j]->x[k][l] = G->P[G->C[i].P[faces[G->C[i].n][j][k]]].x[l]; } PRINTDEBUG(dom,3,("bs C %d F %d S %d prop %d\n", i,j, G->C[i].bs[j]->segment, G->S[G->C[i].S[j]].property)); } else G->C[i].bs[j] = NULL; } } Prop = G->Prop; Geom = G->Geom; return (0); }
/*---------------------------------------------------------------------------*/ static void input_packet(void) { struct cxmac_hdr *hdr; if(NETSTACK_FRAMER.parse() >= 0) { hdr = packetbuf_dataptr(); if(hdr->dispatch != DISPATCH) { someone_is_sending = 0; if(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. */ /* We have received the final packet, so we can go back to being asleep. */ off(); #if CXMAC_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 /* CXMAC_CONF_COMPOWER */ waiting_for_packet = 0; PRINTDEBUG("cxmac: data(%u)\n", packetbuf_datalen()); NETSTACK_MAC.input(); return; } else { PRINTDEBUG("cxmac: data not for us\n"); } } else if(hdr->type == TYPE_STROBE) { someone_is_sending = 2; if(linkaddr_cmp(packetbuf_addr(PACKETBUF_ADDR_RECEIVER), &linkaddr_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. */ hdr->type = TYPE_STROBE_ACK; packetbuf_set_addr(PACKETBUF_ADDR_RECEIVER, packetbuf_addr(PACKETBUF_ADDR_SENDER)); packetbuf_set_addr(PACKETBUF_ADDR_SENDER, &linkaddr_node_addr); packetbuf_compact(); if(NETSTACK_FRAMER.create() >= 0) { /* 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("cxmac: send strobe ack %u\n", packetbuf_totlen()); } else { PRINTF("cxmac: failed to send strobe ack\n"); } } else if(linkaddr_cmp(packetbuf_addr(PACKETBUF_ADDR_RECEIVER), &linkaddr_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("cxmac: strobe not for us\n"); } /* We are done processing the strobe and we therefore return to the caller. */ return; #if CXMAC_CONF_ANNOUNCEMENTS } else if(hdr->type == TYPE_ANNOUNCEMENT) { packetbuf_hdrreduce(sizeof(struct cxmac_hdr)); parse_announcements(packetbuf_addr(PACKETBUF_ADDR_SENDER)); #endif /* CXMAC_CONF_ANNOUNCEMENTS */ } else if(hdr->type == TYPE_STROBE_ACK) { PRINTDEBUG("cxmac: stray strobe ack\n"); } else { PRINTF("cxmac: unknown type %u (%u)\n", hdr->type, packetbuf_datalen()); } } else { PRINTF("cxmac: failed to parse (%u)\n", packetbuf_totlen()); } }
int writetomemory(int rank, int a) { #if defined(MPI) && defined(MEMIMAGE) int color = 0; int rc=0; MPI_Comm tilecomm; if (owneroftile == rank) color = 1; MPI_Comm_split(MPI_COMM_WORLD, color, rank, &tilecomm); if (color) { int cartsize, cartrank; MPI_Comm cartcomm; MPI_Status status; // init parameters for Cart_create int gsizes[2] = {viewport.h, viewport.w*4}; int psizes[2] = {viewport.tilex, viewport.tiley}; int lsizes[2] = {gsizes[0]/psizes[0], (gsizes[1])/psizes[1]}; int dims[2] = {psizes[0], psizes[1]}; int periods[2] = {1,1}; int coords[2]; int *indices = NULL; float *tmprecvbuffer = NULL; // Create cartesian coord MPI_Cart_create(tilecomm, 2, dims, periods, 0, &cartcomm); MPI_Comm_rank(cartcomm, &cartrank); MPI_Comm_size(cartcomm, &cartsize); MPI_Cart_coords(cartcomm, cartrank, 2, coords); /* global indices of first element of local array */ int startindex[2]; startindex[0] = coords[0] * lsizes[0]; startindex[1] = coords[1] * lsizes[1]; int localarraysize = lsizes[0] * lsizes[1]; int globalarraysize = gsizes[0] * gsizes[1]; PRINTDEBUG("%3d: start=%d,%d\n", cartrank, startindex[0], startindex[1]); if (cartrank == 0) { recvbuffer = (float *) malloc(sizeof(float) * globalarraysize); tmprecvbuffer = (float *) malloc(sizeof(float) * globalarraysize); indices = (int *) malloc(sizeof(int) * 2 * cartsize); assert (recvbuffer != NULL && tmprecvbuffer != NULL && indices != NULL); } MPI_Gather(tilebuffer, localarraysize, MPI_FLOAT, tmprecvbuffer, localarraysize, MPI_FLOAT, 0, cartcomm); MPI_Gather(startindex, 2, MPI_INT, indices, 2, MPI_INT, 0, cartcomm); if (cartrank == 0) { int e=0,s=0; int i=0; int rindx, cindx; // row and column indices into temprecvbuffer, recvbuffer int numtiles = viewport.tilex * viewport.tiley; for (int n=0,indx=0; n<numtiles; n++) { rindx = indices[indx]; cindx = indices[indx+1]; s = (rindx * gsizes[1]) + cindx;; e = s; for (int r=0; r<lsizes[0]; r++) { for (int c=0; c<lsizes[1]; c++) { recvbuffer[e] = tmprecvbuffer[i]; e++; i++; } s += gsizes[1]; e = s; } indx += 2; } #ifdef REMOTE for (int i=0; i<globalarraysize; i++) tiffimage[i] = (unsigned char) (recvbuffer[i] * 255.0 + 0.5f); rc = sendimage(sockfd, (unsigned char *)tiffimage, globalarraysize); #endif free(recvbuffer); free(tmprecvbuffer); free(indices); } free(tilebuffer); MPI_Comm_free(&cartcomm); } MPI_Comm_free(&tilecomm); #endif return 0; }
/*---------------------------------------------------------------------------*/ 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; rtimer_clock_t encounter_time = 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 ret; uint8_t contikimac_was_on; uint8_t seqno; #if WITH_CONTIKIMAC_HEADER struct hdr *chdr; #endif /* WITH_CONTIKIMAC_HEADER */ /* 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, &rimeaddr_node_addr); #endif 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); 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(); #ifdef NETSTACK_ENCRYPT NETSTACK_ENCRYPT(); #endif /* NETSTACK_ENCRYPT */ transmit_len = packetbuf_totlen(); 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_receiver_awake) { #if WITH_PHASE_OPTIMIZATION ret = phase_wait(&phase_list, 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(); } #endif watchdog_periodic(); t0 = RTIMER_NOW(); seqno = packetbuf_attr(PACKETBUF_ATTR_MAC_SEQNO); 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; } len = 0; { rtimer_clock_t wt; rtimer_clock_t txtime; int ret; txtime = RTIMER_NOW(); ret = NETSTACK_RADIO.transmit(transmit_len); #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; encounter_time = txtime; 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; encounter_time = txtime; 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(&phase_list, packetbuf_addr(PACKETBUF_ADDR_RECEIVER), encounter_time, ret); } } #endif /* WITH_PHASE_OPTIMIZATION */ return ret; }
/*---------------------------------------------------------------------------*/ static int send_packet(mac_callback_t mac_callback, void *mac_callback_ptr) { rtimer_clock_t t0; rtimer_clock_t t; rtimer_clock_t encounter_time = 0, last_transmission_time = 0; uint8_t first_transmission = 1; 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; #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; } else { is_streaming = 0; } } 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 /* WITH_CONTIKIMAC_HEADER */ /* 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 /* WITH_CONTIKIMAC_HEADER */ /* Make sure that the packet is longer or equal to the shortest packet length. */ transmit_len = packetbuf_totlen(); if(transmit_len < SHORTEST_PACKET_SIZE) { #if 0 /* Pad with zeroes */ uint8_t *ptr; ptr = packetbuf_dataptr(); memset(ptr + packetbuf_datalen(), 0, SHORTEST_PACKET_SIZE - packetbuf_totlen()); #endif 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 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) { 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; } } } else { 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; if(packetbuf_attr(PACKETBUF_ATTR_PACKET_TYPE) != PACKETBUF_ATTR_PACKET_TYPE_ACK && is_streaming == 0) { /* Check if there are any transmissions by others. */ for(i = 0; i < CCA_COUNT_MAX; ++i) { t0 = RTIMER_NOW(); on(); #if NURTIMER while(RTIMER_CLOCK_LT(t0, RTIMER_NOW(), t0 + CCA_CHECK_TIME)); #else while(RTIMER_CLOCK_LT(RTIMER_NOW(), t0 + CCA_CHECK_TIME)) { } #endif if(NETSTACK_RADIO.channel_clear() == 0) { collisions++; off(); break; } off(); t0 = RTIMER_NOW(); #if NURTIMER while(RTIMER_CLOCK_LT(t0, RTIMER_NOW(), t0 + CCA_SLEEP_TIME)); #else while(RTIMER_CLOCK_LT(RTIMER_NOW(), t0 + CCA_SLEEP_TIME)) { } #endif } } if(collisions > 0) { we_are_sending = 0; off(); PRINTF("contikimac: collisions before sending\n"); return MAC_TX_COLLISION; } if(!is_broadcast) { on(); } watchdog_periodic(); t0 = RTIMER_NOW(); t = RTIMER_NOW(); #if NURTIMER for(strobes = 0, collisions = 0; got_strobe_ack == 0 && collisions == 0 && RTIMER_CLOCK_LT(t0, RTIMER_NOW(), t0 + STROBE_TIME); strobes++) { #else for(strobes = 0, collisions = 0; got_strobe_ack == 0 && collisions == 0 && RTIMER_CLOCK_LT(RTIMER_NOW(), t0 + STROBE_TIME); strobes++) { #endif watchdog_periodic(); if(is_known_receiver && !RTIMER_CLOCK_LT(RTIMER_NOW(), t0 + MAX_PHASE_STROBE_TIME)) { break; } len = 0; t = RTIMER_NOW(); { rtimer_clock_t wt; rtimer_clock_t now = RTIMER_NOW(); int ret; ret = NETSTACK_RADIO.transmit(transmit_len); wt = RTIMER_NOW(); #if NURTIMER while(RTIMER_CLOCK_LT(wt, RTIMER_NOW(), wt + INTER_PACKET_INTERVAL)); #else while(RTIMER_CLOCK_LT(RTIMER_NOW(), wt + INTER_PACKET_INTERVAL)) { } #endif if(!is_broadcast && (NETSTACK_RADIO.receiving_packet() || NETSTACK_RADIO.pending_packet() || NETSTACK_RADIO.channel_clear() == 0)) { uint8_t ackbuf[ACK_LEN]; wt = RTIMER_NOW(); #if NURTIMER while(RTIMER_CLOCK_LT(wt, RTIMER_NOW(), wt + AFTER_ACK_DETECTECT_WAIT_TIME)); #else while(RTIMER_CLOCK_LT(RTIMER_NOW(), wt + AFTER_ACK_DETECTECT_WAIT_TIME)) { } #endif len = NETSTACK_RADIO.read(ackbuf, ACK_LEN); if(len == ACK_LEN) { got_strobe_ack = 1; // encounter_time = last_transmission_time; encounter_time = now; break; } else { PRINTF("contikimac: collisions while sending\n"); collisions++; } } last_transmission_time = now; first_transmission = 0; } } 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 && is_reliable) { on(); /* Wait for ACK packet */ } else { off(); } } else { 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 */ 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(!first_transmission)*/ { /* COOJA_DEBUG_PRINTF("first phase 0x%02x\n", encounter_time % CYCLE_TIME);*/ if(WITH_ACK_OPTIMIZATION) { if(collisions == 0 && packetbuf_attr(PACKETBUF_ATTR_PACKET_TYPE) != PACKETBUF_ATTR_PACKET_TYPE_ACK && is_streaming == 0) { phase_update(&phase_list, packetbuf_addr(PACKETBUF_ADDR_RECEIVER), encounter_time, ret); } } else { if(collisions == 0 && is_streaming == 0) { phase_update(&phase_list, packetbuf_addr(PACKETBUF_ADDR_RECEIVER), encounter_time, ret); } } } #endif /* WITH_PHASE_OPTIMIZATION */ return ret; } /*---------------------------------------------------------------------------*/ static void qsend_packet(mac_callback_t sent, void *ptr) { int ret = send_packet(sent, ptr); if(ret != MAC_TX_DEFERRED) { // printf("contikimac qsend_packet %p\n", ptr); mac_call_sent_callback(sent, ptr, ret, 1); } }
/*---------------------------------------------------------------------------*/ 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 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 && (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 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 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()); } }
void writetofile(int rank, int a) { #if defined(MPI) && defined(FILEIMAGE) // dump all the tiles to 1 file using MPI-IO int color = 0; MPI_Comm tilecomm; MPI_File fhtout; if (owneroftile == rank) color = 1; PRINTDEBUG("%3d: tileowner=%d, color=%d\n", rank, owneroftile, color); MPI_Comm_split(MPI_COMM_WORLD, color, rank, &tilecomm); if (color) { int cartrank; MPI_Comm cartcomm; const MPI_Status status; // init parameters for Cart_create int gsizes[2] = {viewport.h, viewport.w*ELEMENTSPERPIXEL}; int psizes[2] = {viewport.tiley, viewport.tilex}; int lsizes[2] = {gsizes[0]/psizes[0], (gsizes[1])/psizes[1]}; int dims[2] = {psizes[0], psizes[1]}; int periods[2] = {1,1}; int coords[2]; PRINTDEBUG("%3d: gsizes=%d,%d, psizes=%d,%d, lsizes=%d,%d\n", rank, gsizes[0], gsizes[1], psizes[0], psizes[1], lsizes[0], lsizes[1]); // Create cartesian coord MPI_Cart_create(tilecomm, 2, dims, periods, 0, &cartcomm); MPI_Comm_rank(cartcomm, &cartrank); MPI_Cart_coords(cartcomm, cartrank, 2, coords); // check coords PRINTDEBUG("%3d: coords=%d,%d\n", cartrank, coords[0], coords[1]); /* global indices of first element of local array */ int startindex[2]; startindex[0] = coords[0] * lsizes[0]; startindex[1] = coords[1] * lsizes[1]; PRINTDEBUG("%3d: start=%d,%d\n", cartrank, startindex[0], startindex[1]); int filetype; filetype=0; MPI_Type_create_subarray(2, gsizes, lsizes, startindex, MPI_ORDER_C, MPI_FLOAT, &filetype); MPI_Type_commit(&filetype); char imagefull[32]; sprintf(imagefull,"imagefull%d.raw", a); PRINTDEBUG("%s\n", imagefull); MPI_File_open(cartcomm, imagefull, MPI_MODE_CREATE | MPI_MODE_WRONLY, MPI_INFO_NULL, &fhtout); MPI_File_set_view(fhtout, 0, MPI_FLOAT, filetype, "native", MPI_INFO_NULL); int localarraysize = lsizes[0] * lsizes[1]; PRINTDEBUG("%3d: size=%d\n", cartrank, localarraysize); MPI_File_write(fhtout, tilebuffer, localarraysize, MPI_FLOAT, &status); int count; MPI_Get_count(&status, MPI_FLOAT, &count); PRINTDEBUG("%3d: cnt=%d\n", cartrank, count); MPI_File_close(&fhtout); MPI_Comm_free(&cartcomm); MPI_Type_free(&filetype); // free(tilebuffer); } MPI_Comm_free(&tilecomm); #endif }