From 879fd8de816de09f4ff8da460bd63ad5c4cf0abf Mon Sep 17 00:00:00 2001 From: Lars Schmertmann Date: Fri, 23 May 2014 12:12:26 +0200 Subject: [PATCH 001/120] Added mc1322x functions --- cpu/mc1322x/clock.c | 6 ++++++ cpu/mc1322x/lib/include/crm.h | 11 +++++++++++ cpu/mc1322x/lib/include/nvm.h | 1 + cpu/mc1322x/lib/nvm.c | 4 ++++ 4 files changed, 22 insertions(+) diff --git a/cpu/mc1322x/clock.c b/cpu/mc1322x/clock.c index 611a90251..628ca1bb8 100644 --- a/cpu/mc1322x/clock.c +++ b/cpu/mc1322x/clock.c @@ -90,6 +90,12 @@ clock_seconds(void) return seconds; } +void +clock_set_seconds(unsigned long sec) +{ + seconds = sec; +} + void clock_wait(clock_time_t t) { diff --git a/cpu/mc1322x/lib/include/crm.h b/cpu/mc1322x/lib/include/crm.h index 27c0adc53..36ee3099a 100644 --- a/cpu/mc1322x/lib/include/crm.h +++ b/cpu/mc1322x/lib/include/crm.h @@ -325,6 +325,17 @@ static const int XTAL32_EN = 0; #define pack_XTAL_CNTL(ctune4pf, ctune, ftune, ibias) \ (*CRM_XTAL_CNTL = ((ctune4pf << 25) | (ctune << 21) | ( ftune << 16) | (ibias << 8) | 0x52)) +#define soft_reset() \ + __asm__ __volatile__ ( \ + "ldr r0, [%[sw]] \n\t" \ + "str r0, [%[sw]] \n\t" \ + : /* out */ \ + : /* in */ \ + [sw] "l" (CRM_SW_RST) \ + : /* clobber list */ \ + "r0", "memory" \ + ); + #endif /* REG_NO_COMPAT */ #endif diff --git a/cpu/mc1322x/lib/include/nvm.h b/cpu/mc1322x/lib/include/nvm.h index 65ba23d11..6bd8dfe0a 100644 --- a/cpu/mc1322x/lib/include/nvm.h +++ b/cpu/mc1322x/lib/include/nvm.h @@ -78,5 +78,6 @@ extern nvmErr_t (*nvm_write)(nvmInterface_t nvmInterface, nvmType_t nvmType ,voi /* SST flash has 32 sectors 4096 bytes each */ /* bit 0 is the first sector, bit 31 is the last */ extern nvmErr_t (*nvm_erase)(nvmInterface_t nvmInterface, nvmType_t nvmType ,uint32_t sectorBitfield); +extern nvmErr_t (*nvm_verify)(nvmInterface_t nvmInterface, nvmType_t nvmType, void *pSrc, uint32_t address, uint32_t numBytes); extern void(*nvm_setsvar)(uint32_t zero_for_awesome); #endif //NVM_H diff --git a/cpu/mc1322x/lib/nvm.c b/cpu/mc1322x/lib/nvm.c index 83dd8ecc7..569977c63 100644 --- a/cpu/mc1322x/lib/nvm.c +++ b/cpu/mc1322x/lib/nvm.c @@ -51,6 +51,10 @@ nvmErr_t (*nvm_erase) (nvmInterface_t nvmInterface, nvmType_t nvmType ,uint32_t sectorBitfield) = (void*) 0x00006e05; +nvmErr_t (*nvm_verify) +(nvmInterface_t nvmInterface, nvmType_t nvmType, void *pSrc, uint32_t address, uint32_t numBytes) += (void*) 0x00006f85; + void(*nvm_setsvar) (uint32_t zero_for_awesome) = (void *)0x00007085; From e5add3d1f8deaa6afb49ebdc40f4bcecb912a0b0 Mon Sep 17 00:00:00 2001 From: Ian Martin Date: Wed, 11 Jun 2014 18:44:59 -0400 Subject: [PATCH 002/120] Make protothread semaphores interrupt-safe. --- core/sys/pt-sem.h | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) diff --git a/core/sys/pt-sem.h b/core/sys/pt-sem.h index 75d66452a..27effa57a 100644 --- a/core/sys/pt-sem.h +++ b/core/sys/pt-sem.h @@ -162,9 +162,11 @@ PT_THREAD(driver_thread(struct pt *pt)) #include "sys/pt.h" struct pt_sem { - unsigned int count; + unsigned int head, tail; }; +#define PT_SEM_COUNT(s) ((s)->head - (s)->tail) + /** * Initialize a semaphore * @@ -179,7 +181,11 @@ struct pt_sem { * \param c (unsigned int) The initial count of the semaphore. * \hideinitializer */ -#define PT_SEM_INIT(s, c) (s)->count = c +#define PT_SEM_INIT(s, c) \ + do { \ + (s)->tail = 0; \ + (s)->head = (c); \ + } while(0) /** * Wait for a semaphore @@ -199,8 +205,8 @@ struct pt_sem { */ #define PT_SEM_WAIT(pt, s) \ do { \ - PT_WAIT_UNTIL(pt, (s)->count > 0); \ - --(s)->count; \ + PT_WAIT_UNTIL(pt, PT_SEM_COUNT(s) > 0); \ + ++(s)->tail; \ } while(0) /** @@ -218,7 +224,7 @@ struct pt_sem { * * \hideinitializer */ -#define PT_SEM_SIGNAL(pt, s) ++(s)->count +#define PT_SEM_SIGNAL(pt, s) (++(s)->head) #endif /* PT_SEM_H_ */ From b441901321fe9c32fbcd10617c01a34242125647 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20De=20Fauw?= Date: Tue, 17 Jun 2014 11:38:07 +0200 Subject: [PATCH 003/120] IPv6 host adds prefixes successfully but return always NULL In Neighbor Discovery Protocol, when IPv6 host adds a prefix (coming from PIO) but it is always failing whatever if is successfully add in prefix table. The reason comes from the fact that the function uip_ds6_prefix_add in host version always return NULL. This is opposite of the specification of the router version. --- core/net/ipv6/uip-ds6.c | 1 + 1 file changed, 1 insertion(+) diff --git a/core/net/ipv6/uip-ds6.c b/core/net/ipv6/uip-ds6.c index 4a191caf9..11b821a6a 100644 --- a/core/net/ipv6/uip-ds6.c +++ b/core/net/ipv6/uip-ds6.c @@ -275,6 +275,7 @@ uip_ds6_prefix_add(uip_ipaddr_t *ipaddr, uint8_t ipaddrlen, PRINTF("Adding prefix "); PRINT6ADDR(&locprefix->ipaddr); PRINTF("length %u, vlifetime%lu\n", ipaddrlen, interval); + return locprefix; } return NULL; } From 22caf4b2e1f403373408717e0ff006111dd0e14e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20De=20Fauw?= Date: Tue, 17 Jun 2014 11:41:43 +0200 Subject: [PATCH 004/120] Prefix Information Option never send in RA messages The problem came from the fact that there two opposite macro (UIP_CONF_ROUTER) that could not activate the code responsible to send the PIO option in NDP. --- core/net/ipv6/uip-nd6.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/core/net/ipv6/uip-nd6.c b/core/net/ipv6/uip-nd6.c index f2e601fed..36dcaf6d5 100644 --- a/core/net/ipv6/uip-nd6.c +++ b/core/net/ipv6/uip-nd6.c @@ -121,6 +121,8 @@ static uint8_t *nd6_opt_llao; /** Pointer to llao option in uip_buf */ #if !UIP_CONF_ROUTER // TBD see if we move it to ra_input static uip_nd6_opt_prefix_info *nd6_opt_prefix_info; /** Pointer to prefix information option in uip_buf */ static uip_ipaddr_t ipaddr; +#endif +#if (!UIP_CONF_ROUTER || UIP_ND6_SEND_RA) static uip_ds6_prefix_t *prefix; /** Pointer to a prefix list entry */ #endif static uip_ds6_nbr_t *nbr; /** Pointer to a nbr cache entry*/ @@ -682,7 +684,6 @@ uip_nd6_ra_output(uip_ipaddr_t * dest) nd6_opt_offset = UIP_ND6_RA_LEN; -#if !UIP_CONF_ROUTER /* Prefix list */ for(prefix = uip_ds6_prefix_list; prefix < uip_ds6_prefix_list + UIP_DS6_PREFIX_NB; prefix++) { @@ -699,7 +700,6 @@ uip_nd6_ra_output(uip_ipaddr_t * dest) uip_len += UIP_ND6_OPT_PREFIX_INFO_LEN; } } -#endif /* !UIP_CONF_ROUTER */ /* Source link-layer option */ create_llao((uint8_t *)UIP_ND6_OPT_HDR_BUF, UIP_ND6_OPT_SLLAO); From f943eb9a27ffaa43857dbb5cfafa405d807f27fc Mon Sep 17 00:00:00 2001 From: Joakim Gebart Date: Tue, 28 Oct 2014 14:42:36 +0100 Subject: [PATCH 005/120] rf230bb: Handle all IRQ flags in one ISR call. Modified the if/elseif/elseif/.../else block in ISR into multiple if blocks in order to handle multiple interrupts happening simultaneously. Signed-off-by: Joakim Gebart --- cpu/avr/radio/rf230bb/halbb.c | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) diff --git a/cpu/avr/radio/rf230bb/halbb.c b/cpu/avr/radio/rf230bb/halbb.c index 53deb1c8a..122f05b3a 100644 --- a/cpu/avr/radio/rf230bb/halbb.c +++ b/cpu/avr/radio/rf230bb/halbb.c @@ -751,7 +751,8 @@ HAL_RF230_ISR() #endif #endif - } else if (interrupt_source & HAL_TRX_END_MASK){ + } + if (interrupt_source & HAL_TRX_END_MASK){ INTERRUPTDEBUG(11); state = hal_subregister_read(SR_TRX_STATUS); @@ -778,16 +779,20 @@ HAL_RF230_ISR() } - } else if (interrupt_source & HAL_TRX_UR_MASK){ + } + if (interrupt_source & HAL_TRX_UR_MASK){ INTERRUPTDEBUG(13); ; - } else if (interrupt_source & HAL_PLL_UNLOCK_MASK){ + } + if (interrupt_source & HAL_PLL_UNLOCK_MASK){ INTERRUPTDEBUG(14); ; - } else if (interrupt_source & HAL_PLL_LOCK_MASK){ + } + if (interrupt_source & HAL_PLL_LOCK_MASK){ INTERRUPTDEBUG(15); ; - } else if (interrupt_source & HAL_BAT_LOW_MASK){ + } + if (interrupt_source & HAL_BAT_LOW_MASK){ /* Disable BAT_LOW interrupt to prevent endless interrupts. The interrupt */ /* will continously be asserted while the supply voltage is less than the */ /* user-defined voltage threshold. */ @@ -796,9 +801,6 @@ HAL_RF230_ISR() hal_register_write(RG_IRQ_MASK, trx_isr_mask); INTERRUPTDEBUG(16); ; - } else { - INTERRUPTDEBUG(99); - ; } } #endif /* defined(__AVR_ATmega128RFA1__) */ From 380c6b7622d8204597b6b23365953ad0ceeb7c9f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Moritz=20=27Morty=27=20Str=C3=BCbe?= Date: Tue, 14 Oct 2014 11:09:21 +0200 Subject: [PATCH 006/120] Make Random thread safe --- .../java/org/contikios/cooja/SafeRandom.java | 87 +++++++++++++++++++ .../java/org/contikios/cooja/Simulation.java | 3 +- 2 files changed, 89 insertions(+), 1 deletion(-) create mode 100644 tools/cooja/java/org/contikios/cooja/SafeRandom.java diff --git a/tools/cooja/java/org/contikios/cooja/SafeRandom.java b/tools/cooja/java/org/contikios/cooja/SafeRandom.java new file mode 100644 index 000000000..5dee9c1be --- /dev/null +++ b/tools/cooja/java/org/contikios/cooja/SafeRandom.java @@ -0,0 +1,87 @@ +/* + * Copyright (c) 2014, Friedrich-Alexander University Erlangen-Nuremberg. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the university nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + */ + +package org.contikios.cooja; + +import java.util.Random; + +/** + * This ensures that the functions of the random number generator are + * only called by the the thread initializing a simulation or the + * simulation thread itself. + * Rationale: By allowing another thread to use the random number + * generator concurrency is intruduced, thus it can not be guaranteed + * that simulations are reproduceable. + * + */ +public class SafeRandom extends Random { + + Simulation sim = null; + Thread initThread = null; + + private void assertSimThread() { + // It we are in the simulation thread everything is fine (the default) + // sim can be null, because setSeed is called by the super-constructor. + if(sim != null && !sim.isSimulationThread()) { + // The thread initializing the simulation might differ from the simulation thread. + // If they are the same that is ok, too. + if(initThread == null) initThread = Thread.currentThread(); + if(Thread.currentThread() == initThread ) return; + throw new RuntimeException("A random-function was not called from the simulation thread. This can break things!"); + } + } + + public SafeRandom(Simulation sim) { + // assertSimThread is called by the super-constructor. + super(); + this.sim = sim; + } + + public SafeRandom(Simulation sim, long seed) { + // assertSimThread is called by the super-constructor. + super(seed); + this.sim = sim; + } + + synchronized public void setSeed(long seed) { + assertSimThread(); + super.setSeed(seed); + } + + /* + * This function is called by all functions returning random numbers + * @see java.util.Random#next(int) + */ + protected int next(int bits) { + assertSimThread(); + return super.next(bits); + } + +} diff --git a/tools/cooja/java/org/contikios/cooja/Simulation.java b/tools/cooja/java/org/contikios/cooja/Simulation.java index 293a4c2c2..18dfa7fe8 100644 --- a/tools/cooja/java/org/contikios/cooja/Simulation.java +++ b/tools/cooja/java/org/contikios/cooja/Simulation.java @@ -93,7 +93,7 @@ public class Simulation extends Observable implements Runnable { private long maxMoteStartupDelay = 1000*MILLISECOND; - private Random randomGenerator = new Random(); + private SafeRandom randomGenerator; private boolean hasMillisecondObservers = false; private MillisecondObservable millisecondObservable = new MillisecondObservable(); @@ -322,6 +322,7 @@ public class Simulation extends Observable implements Runnable { */ public Simulation(Cooja cooja) { this.cooja = cooja; + randomGenerator = new SafeRandom(this); } /** From 8552fb1eadc1346344aa4c54024ae1ed58b6b3f6 Mon Sep 17 00:00:00 2001 From: Ioannis Glaropoulos Date: Mon, 9 Mar 2015 19:41:25 +0100 Subject: [PATCH 007/120] Send the first NS attempt inside tcpip_ipv6_output() --- core/net/ip/tcpip.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/core/net/ip/tcpip.c b/core/net/ip/tcpip.c index 6f2744785..a6fdf1fe1 100644 --- a/core/net/ip/tcpip.c +++ b/core/net/ip/tcpip.c @@ -675,7 +675,11 @@ tcpip_ipv6_output(void) stimer_set(&nbr->sendns, uip_ds6_if.retrans_timer / 1000); nbr->nscount = 1; + /* Send the first NS try from here (multicast destination IP address). */ } +#else /* UIP_ND6_SEND_NA */ + uip_len = 0; + return; #endif /* UIP_ND6_SEND_NA */ } else { #if UIP_ND6_SEND_NA @@ -722,7 +726,6 @@ tcpip_ipv6_output(void) uip_len = 0; return; } - return; } /* Multicast IP destination address. */ tcpip_output(NULL); From eae25d622d3cdcde5770c8ceeb9257985999cf0b Mon Sep 17 00:00:00 2001 From: Timofei Istomin Date: Fri, 8 May 2015 18:31:06 +0200 Subject: [PATCH 008/120] Check the frame preamble and MPDU length before parsing Due to errors in mspsim and/or radio drivers, packets of incorrect length are sometimes transmitted. The length might be larger than the 127-byte maximum (considered negative in the current code) or not matching the actual number of transmitted bytes. This leads to wrong packet delimiting when converting from the mspsim-level stream of bytes to Cooja-level packets causing unhandled exceptions that terminate the simulation. This patch checks the frame preamble (0000007A) and the length field. If they are wrong, no decoding attempt is done. The transmitted bytes are still delivered to the receivers untouched. The connection is terminated when the radio state is changed (which alway s happens when TX is done). --- .../CC2420RadioPacketConverter.java | 2 +- .../mspmote/interfaces/Msp802154Radio.java | 86 +++++++++---------- 2 files changed, 43 insertions(+), 45 deletions(-) diff --git a/tools/cooja/apps/mspsim/src/org/contikios/cooja/mspmote/interfaces/CC2420RadioPacketConverter.java b/tools/cooja/apps/mspsim/src/org/contikios/cooja/mspmote/interfaces/CC2420RadioPacketConverter.java index fd62da50f..3fda7681d 100644 --- a/tools/cooja/apps/mspsim/src/org/contikios/cooja/mspmote/interfaces/CC2420RadioPacketConverter.java +++ b/tools/cooja/apps/mspsim/src/org/contikios/cooja/mspmote/interfaces/CC2420RadioPacketConverter.java @@ -165,7 +165,7 @@ public class CC2420RadioPacketConverter { } /* 1 byte length */ - len = data[pos]; + len = data[pos] & 0xFF; originalLen = len; pos += 1; diff --git a/tools/cooja/apps/mspsim/src/org/contikios/cooja/mspmote/interfaces/Msp802154Radio.java b/tools/cooja/apps/mspsim/src/org/contikios/cooja/mspmote/interfaces/Msp802154Radio.java index 18dcffb37..c99710f3d 100644 --- a/tools/cooja/apps/mspsim/src/org/contikios/cooja/mspmote/interfaces/Msp802154Radio.java +++ b/tools/cooja/apps/mspsim/src/org/contikios/cooja/mspmote/interfaces/Msp802154Radio.java @@ -75,6 +75,7 @@ public class Msp802154Radio extends Radio implements CustomDataRadio { private boolean isInterfered = false; private boolean isTransmitting = false; private boolean isReceiving = false; + private boolean isSynchronized = false; private byte lastOutgoingByte; private byte lastIncomingByte; @@ -91,22 +92,19 @@ public class Msp802154Radio extends Radio implements CustomDataRadio { radio.addRFListener(new RFListener() { int len = 0; - int expLen = 0; - byte[] buffer = new byte[127 + 15]; + int expMpduLen = 0; + byte[] buffer = new byte[127 + 6]; + final private byte[] syncSeq = {0,0,0,0,0x7A}; + public void receivedByte(byte data) { if (!isTransmitting()) { lastEvent = RadioEvent.TRANSMISSION_STARTED; isTransmitting = true; len = 0; - /*logger.debug("----- 802.15.4 TRANSMISSION STARTED -----");*/ + expMpduLen = 0; setChanged(); notifyObservers(); - } - - if (len >= buffer.length) { - /* Bad size packet, too large */ - logger.debug("Error: bad size: " + len + ", dropping outgoing byte: " + data); - return; + /*logger.debug("----- 802.15.4 TRANSMISSION STARTED -----");*/ } /* send this byte to all nodes */ @@ -115,31 +113,40 @@ public class Msp802154Radio extends Radio implements CustomDataRadio { setChanged(); notifyObservers(); - buffer[len++] = data; + if (len < buffer.length) + buffer[len] = data; - if (len == 6) { + len ++; + + if (len == 5) { + isSynchronized = true; + for (int i=0; i<5; i++) { + if (buffer[i] != syncSeq[i]) { + // this should never happen, but it happens + logger.error(String.format("Bad outgoing sync sequence %x %x %x %x %x", buffer[0], buffer[1], buffer[2], buffer[3], buffer[4])); + isSynchronized = false; + break; + } + } + } + else if (len == 6) { // System.out.println("## CC2420 Packet of length: " + data + " expected..."); - expLen = data + 6; + expMpduLen = data & 0xFF; + if ((expMpduLen & 0x80) != 0) { + logger.error("Outgoing length field is larger than 127: " + expMpduLen); + } } - if (len == expLen) { - /*logger.debug("----- 802.15.4 CUSTOM DATA TRANSMITTED -----");*/ - + if (((expMpduLen & 0x80) == 0) && len == expMpduLen + 6 && isSynchronized) { lastOutgoingPacket = CC2420RadioPacketConverter.fromCC2420ToCooja(buffer); lastEvent = RadioEvent.PACKET_TRANSMITTED; - /*logger.debug("----- 802.15.4 PACKET TRANSMITTED -----");*/ + //logger.debug("----- 802.15.4 PACKET TRANSMITTED -----"); setChanged(); notifyObservers(); - - /*logger.debug("----- 802.15.4 TRANSMISSION FINISHED -----");*/ - isTransmitting = false; - lastEvent = RadioEvent.TRANSMISSION_FINISHED; - setChanged(); - notifyObservers(); - len = 0; + isSynchronized = false; } } - }); + }); /* addRFListener */ radio.addOperatingModeListener(new OperatingModeListener() { public void modeChanged(Chip source, int mode) { @@ -148,7 +155,7 @@ public class Msp802154Radio extends Radio implements CustomDataRadio { setChanged(); notifyObservers(); } else { - radioOff(); + radioOff(); // actually it is a state change, not necessarily to OFF } } }); @@ -163,32 +170,23 @@ public class Msp802154Radio extends Radio implements CustomDataRadio { }); } - private void radioOff() { - /* Radio was turned off during transmission. - * May for example happen if watchdog triggers */ + + private void finishTransmission() + { if (isTransmitting()) { - logger.warn("Turning off radio while transmitting, ending packet prematurely"); - - /* Simulate end of packet */ - lastOutgoingPacket = new RadioPacket() { - public byte[] getPacketData() { - return new byte[0]; - } - }; - - lastEvent = RadioEvent.PACKET_TRANSMITTED; - /*logger.debug("----- 802.15.4 PACKET TRANSMITTED -----");*/ - setChanged(); - notifyObservers(); - - /* Register that transmission ended in radio medium */ - /*logger.debug("----- 802.15.4 TRANSMISSION FINISHED -----");*/ + //logger.debug("----- 802.15.4 TRANSMISSION FINISHED -----"); isTransmitting = false; + isSynchronized = false; lastEvent = RadioEvent.TRANSMISSION_FINISHED; setChanged(); notifyObservers(); } + } + private void radioOff() { + if (isSynchronized) + logger.warn("Turning off radio while transmitting a packet"); + finishTransmission(); lastEvent = RadioEvent.HW_OFF; setChanged(); notifyObservers(); From d8639df64bf8ad4fd00f4cd19de62c99358a3d77 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Moritz=20=27Morty=27=20Str=C3=BCbe?= Date: Mon, 18 May 2015 09:29:35 +0200 Subject: [PATCH 009/120] Fix EINVAL handling and O_DIRECT --- tools/sky/serialdump.c | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/tools/sky/serialdump.c b/tools/sky/serialdump.c index e3e47092b..e1cd6c31e 100644 --- a/tools/sky/serialdump.c +++ b/tools/sky/serialdump.c @@ -164,13 +164,21 @@ main(int argc, char **argv) } fprintf(stderr, "connecting to %s (%s)", device, speedname); -#ifdef O_SYNC + + +#ifndef O_SYNC +#define O_SYNC 0 +#endif +#ifdef O_DIRECT fd = open(device, O_RDWR | O_NOCTTY | O_NDELAY | O_DIRECT | O_SYNC); - if(fd < 0 && errno == EINVAL){ // O_SYNC not supported (e.g. raspberian) - fd = open(device, O_RDWR | O_NOCTTY | O_NDELAY | O_DIRECT); + // Some system do not support certain parameters (e.g. raspberian) + // Just do some random testing. Not sure wheter ther is a better way + // of doing this. + if(fd < 0 && errno == EINVAL){ + fd = open(device, O_RDWR | O_NOCTTY | O_NDELAY | O_SYNC); } #else - fd = open(device, O_RDWR | O_NOCTTY | O_NDELAY | O_SYNC ); + fd = open(device, O_RDWR | O_NOCTTY | O_NDELAY | O_SYNC); #endif if(fd < 0) { fprintf(stderr, "\n"); From e38bc3bdcd8939387a34aa7bd9af3bd9fd506417 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Moritz=20=27Morty=27=20Str=C3=BCbe?= Date: Mon, 18 May 2015 10:17:11 +0200 Subject: [PATCH 010/120] Revert binary: serialdump-linux --- tools/sky/serialdump-linux | Bin 14748 -> 14922 bytes tools/sky/serialdump.c | 6 +++--- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/tools/sky/serialdump-linux b/tools/sky/serialdump-linux index 8bb8192c282daa79e093d45bfdc0da9fdf59bb5b..8c7af779d6833ab75857ae8d2a59688e0d68cfab 100755 GIT binary patch literal 14922 zcmeHOe{@vUoxk%VFhV3DL`^N$7fm$mnn{2_DL*U_2En3G6Hpgnn9RIn#!hBtXWn4a z8VnAj%nqTn^;fsGN9?xSYS+Vd)wNaZARdEfJuR*Dba%Bq=@#3WhV7vhD_bMk&*$Fv zl9zy8>hbJf-sJo4{oL>Oe($~C`(y6C@4mZy>sC7)4q-W`a0#L#_qshT@DpouT^2ly-|oLj?~0@hJ=q!!q*8iH`2Aho@t8kl1d@i|FVOXa z?D7jm$_T~NhDfKPx}Ff-dUr6mC*H& zxFZ=cbkUheMq);%;=~mPN+U6m)B_qf)$AsP!L5`8A9*YbA+Vv}Ex}1IQ+x&|{)A7&D^C0;Q8#T(@rR z%2xk8Z!-`yJv#-!qMj{w~PEke?xYsc+O~HU>e=Ea4XFn^$z+?NC zVRASD{#3}Gqz{Fs=wq;+rjHIfLZ1@_he*vW`9mdINoQmTTx^0%)d>NvVZCI?N*a7o#uJ$0V_wJ|?GC^k)mPG51F1 zgs1q=D0MjzEVMA z);!EmMrNV27H%Ls2 zg*Ol{mzb6d-$L9hF)bM0MyyFpONLpYQl-SSXgEPEB&KDTbxw-T6dbhR^My>YJ(q2OfiegAtgE;;hvMY#C&;_+Kl%`Q z#*kfMrr^wF>%bk%YIr`%5@ly2#3jl|{wcEZ2g%A0F#64JRy_DZ#TN^?A2%Gz9YKz0 z&snG#<|9^&=}WgUOIx939yLfjn61Y1TQZMIgv>n1${!>vKfvhs%7ZI6jB>}Obf$n?b>p_=TtNzm-sw=*X*YeX}~wB&|Oz-wkbRgW10s1EEK9V6??u2 zyQ-tl}dV*+rWK>}0o zVWxH0@rSF(`i+(Ga#MDXQVvU@ry~=tne)B_R8tH2Y@xRX>92xx@zXY43&0!58c@p_ z)J(8^Ji%fn&}<3Z;N^W!Qrb+197Z8dpL8KZh^Cl`hocYz|V==1` zbEsHW@%69D+%X^TDpc(HEs8ZJQp-dypwu3$GsQr5n^{Ws;RVp1^9^PChJ@@;_b_{* zvPXN37LOxLZpGdQkXVKGAY=`WAzFtW^nTU^8ee^jwmc3IF}yYJJDz(%<>)xd60l0N zklEUu5Y86vVpskL=6nwmn-#xZm4b?jdsY1FSdbU5KzP7+TrLNWFYyiC`S-HvGyiot zd})gN?51dB+n!Z-GyjD&jqhZp@1(8z4wad#{u>PYiY!E_0zb7CPp1cSPqjd2<{+P* zihKXS-#7{K?t`H(tDn_k#nZdWXy{4Hg^kcxDj>x`b`7}fnXFGvqVc$`r`QA6Q9{l= zTn|Yrvju78pHm=f3b4ODM)SRmSj@UuC%sqxKZS&iyL4Jbb{YHy*QPvit6S48pOrvnuxf05acy5=k)K zS~a5#YxcafxEza?UX6P5NR#P%MWpB1R4*+USK8ntV;A2=6Fo(xE=XAjT`#=20g}gEOK@!l4cI_S-oT0poDChXP#o6 z?q@tE4B23^T4?3ppbl1jHlSSQ(hiAWMY-53eH&rcu;RV~E8=^l^dMsT`(Ax5eLck| z*J3%c*?Ex9*CA)jP~o35TrrIGckw0F1q;K|$H8mw-8QJ%GA>}YUpY2CJ%{?RkDmEG zhk>929*Uax6nKPs5w~C8V+x(VO`Sj_0-$?F+Dq9;iZ~J*RnmIjc zR6Wbk=+S)ZNM_iLnDm<&xtZH%?)k2kIlhf!0wgP52Bi4Vj5!4-8BVb=73k6zYbiY$ z2}DEb?u53vv1bb&sm<}&76u}GbhK^o`Bov+=DTU_igl}eo7T4ac#fqh*Vv_FOxcjLq-sI{$IyFu%Yhjd#Wskju9tavQi zEBRVOAR5&|0VAMAQYu*@5d4g8q~;*$SoW!yX2i8{B&3hapynyNO#5ck0oiY%Xdo2Q zcorqI)C0k=X6QYJhO=Q7$l<3Bcal%h4fS~8AmI zmG0JK29gHju^0~XBC#&kxjv;e)WdGmgtmG8r?!xtj)t^Y+&~90Gb(Bj+mWM?#f$29TS9=GT8`=A|vckXn*gsz*%^gQT?pkIJ~2RZ|qf%^|119?H$f^GzD1;s!+Kzl)713dwH9%SWF&it-x zZC$K2;F`c3ZN9g~yHIP`*pZGIX@wf+rX`w(h3Wf}Z1FaG=a1=>$kMrBqR#V|JpXcj zU^=DA@JbQ84?6ZPb?@W~8B&iHcup}L-9YgxcdLHL{>XmA{>grK0&P&IlE~*Zcsj*b z&Pw+-(y`zAkWS^R64gri&*J$7P%miG>t)1%@9edJGdwlmV>`6cmBZ!vsHfgDi*u%9 zrlWF76`u7oW=(g^_$b~YIqQUL#`Njeq6@na^r)b_1+j~#FPXk})+fuIm|n}S5^Fg- zO05$#A{QIJ88S{WkCKjeW?YD;gS`XfI7c59xM+b}AE>kJLS;@~`f?S7V}5PRvid7r zHQKFzQ+vg2o1M7q;J8w%zU*A8vAv5J-XK^)@DRxvX8AbyS-xem zM54^eS-|CW)Hc=L+J!ffsBD>&GlJ`K#4U4{sTd9v*EA)ytgET1d0B0()Uf*lFDyHd zy|A_8W#!D{s&ZI)qokaJTo*W0Sxg(I!r0bp9G>T8F8h4Ki6a`v4qiT}0_Oygt{4sp zg5f|?PAaYc#}CqY`mwZBq)Ig*YV!2xP4#vgfezutv4`@*RtOsOWI}jxexQ3-tX$h@ z1iFMb9Kfw1Z>Tqhgv!SSAa7SJ?Zsw3#mhc+;0G_MM=7rYiKrpGG@9`8Kt^~w0lu1TO5oTGrCg9A`i~!fCmb2=SK!hc? z26Ag4*KaYwqdwB-Y;v4VkDzgCcwNABl%d-Rvh;Bl8^WTQldI({)%PNTVb)jR*OwPK zchm5uv-Eu)*pl0gmq5F5snp_8)Czyul#?pBR@IcfC_`t-J%TXxQO*N7k9Kakf3(T* zwofJGEFEBtg};L^ZA^V!lUHl%z9`$5j%nC#Pl2p_d57+GZCnRfQjW6U2U&95V+?7y zTZcHyQHFFFWXY|;ng5#FiFa}-L-#U>`Lld{H_#3_jS;5PO#g@Qsn2qhyUG?}1%Czs zD@@t`D}>l>C4z6M{x!mOInR|s)Z64N-XAB)HA3#MWv5WWmK=W9Cg{5b%D8N`oF!K| zN$!V`d)8t?*b2@z<(f?exvPcvfu+opqb%2-w4LSFG~gbvr38^ykiM=SxOnK_GdY7Zp}HbN*9U<-mDPVU+>rGlf;} zwDz7Z*@M;mr1%)zaGZw}mY&?(D$H7_c|~FFlrjHe{!o}Rk=jNmTrM%^1BJQshU2)0 zbD1~BIldLJSty!Fk)uT8wrOwaq5bk;WyRlr=wFs=$O@M=u{ z7Kw518<^u))#nm%Eimt=S$Kmf&pDX(*#^vY41&Prq6=7FEjIBT!0l%FE7AWmz`S$Z zim8qA)>?(XbJX_@@U8hoL;pSiOlQ^S1z>CbtHKv8M@)VeGEDy;CSGmgVG~>J`HqRd zXY!|`V)pV?v7&IBK-4z}nA=LmRXNMWa^U`NE6n=%fO&_D$@tC4CIsx?Waz+FeJW9( zBn3^U!N14Ek0H$bzG7mlypKlh0grbJZ7`(1BK%fk60L2n)s zgyR0LXuKm3^~(*IKalPba%1MlC4=r>D+9dn9oKJx)i^l z97af+jDLAEF~!91dh9%YTV%)5Kx3Z-**WS9rAaYRY>(m94Lerf2iZ$W`vYU!Z}Q}~ zLuY+WWLLt20#jIh<78*5YRfwk_GtA1l|6=^C)qK-ZL(v(E)OJZA68A^`XdV$E%f5< ug+CGW8)01a@OJbF*&XFqQ4@qGe=23G!MQ#P8~Y;5u7p=J?0C|bWB&_iAMR-Y literal 14748 zcmeHOeQ;aVmA{hn;TR%00fO^E^N3~Yz}naWvW{^;FR_wmYJ!{C5FkO4^^vH^l2&?7 zoDztGY$h7Vsdr1eOv|*{-EJpa*lD(fGIuQ z-D^K7)^@uyo!LM3di2gczkANP=YF00eBXOJT+OSj77LTf%5GuA?YhFrA>+zeorALi zt7FB?$riE&Y#NZM_&IqAQ6nemkT5N2v5+eQokDr50IW_UBj^HyLk&if9ulScCX!QR z4eI}b!Ai=Q!U57FUj+;5A#R+G2|tue3|I;hOnPOCftLwANk_>rlBBYI)HeDp5Ox<> zo#2Rf5@C(}Izf3~0Bdhdc1w2{Erdo=k?)G`_db) z5Bsaap-5*}Raf28s--tpC!*C$xc{XvL`_`1rj47F{V@+5)qOdBG?rBU)IC3X@!I)+ z|Aedc(w%GSLm&Qxb#0%8vV}qhgwgQO_>t}m{4T{$c6k}{WcLdED9y!>?9V2qKoZ@{ zu0pxF{Ut(P3=gw`pD8dqD0MHj?K1qRFUU_ySK>DZzv;w?G#`}ONIGPX*JDvwx24od z7}ZT_@m0GQ1lzo&%RcNQc+#{4=w$8rK>>V20lcaJeyjlg-2(W_1@NZ};K>5`)<N z3g9OS;7=96soxd+^3#_9OxB+R1@QU;IL*7s?5r+;KVJavD1iTC0lcLEeoX=V>H_$8 z3gCZR0N)OL7Ol2&4|2vDAgba=cyYN0xd}XlJmIC~9^@u)=5}xDh(_EA-5b~4ZiaB; zqv)}e1%u(v#AX)g3h68sh{vOG7VFd#bn$KW##tf|4)}DI(EXtZuJNEA>Ig7jFcHv0 ziC7@uhiRxqqV90i=hZ{e2-AHi^y+$?#RFbHsYW|>79@+rK$-I?%`RArRHEG z$Bl3qmq<{K8{uM$B$$;g@^DJ=&cbuXMKR$r#!^Y838$DSQ;i9idlHq^nQ*FGCZ`GK z@l+IOCfpo@TTHmzyGUid2}j3`Cyxo2djS=0HsNyLAv|WnX-|@=%Y@7QgUY&1IPE7g z?K0tVOsQBgMmvWp8@;N`+-BdT_NbbRtLm zW)jbgW|1nsO1y>m5zfbnrzx2k;`~>Lr>U6P&-r%ZX$ofca{eCTY3gMLIKP&7nsS+L z&fi8nO|?vn^DBs_DVFhYzMgoRTA3EkFCm_$RL05qYl)|+l&RtTBI0QZWfacOBc7&C zrj+xuiKnHUVVo}^o~BUd%;x|qti;pQ$&7OT{2cH!Wilh2|B!f^Dw!e9pCq29NM=9h z-z1)ffoGcLIhp!`6--m#UpTrS zWL5T_XE0`J|0;{R>?Qlx&S3zwzU2?0E-iKP&>-Y%htfYpg|$P6taq0J{X?4ivv){M z9kcK1k@8OJ3>Vuc4N%hg9urP@_4}nEE80`Ha-;yL#ZE*8h}aK;ZuZ>xAFK z@#h8pe)^}twSE&1{k|T@W7MMlN4Z$-IT%iU&+$00w?Q8T{k-Cp3)$?<{jioYq|mg?c6T7RR%OExQm)%JxwP$qABxSP~bEpX3OJ5>AA+Sdl@hFwFu2qT#j zBny7M;70}T5qw(kv~o%QjNoH}9}|3+;A!(Ad)sTVOmhfmJ4j3h^IT|A=M|KX_p;lJWmnjK|YUn9o0x94S&xA*Mi z^Gpu1T5UUQQe?!RPR&W!}bHOWgWjb4m;0LU{;gIEKS%BT+2SU_r3w= zUeIAD^B!`j$J!9F_q>cgYlzw(9Zn8UJN3$Qw6sqhug#`^4*gT#(UM24hwg+9MTxJV zatv0F29-lC0&ElDN&+_s&?&&55J(}4)UPwZ-X8%p#jVU;2rJzWS}_d2qhUaewQp#t zu%k4y93>b8WBs5TU917s`_SZuH|#xMqR!jyup>)n9ZkM}Qdp&U1chA>E9D+$ zf8?)e==)~wn1yggq1*^(o6tct2(H?<)jHFXu4M}eY6!^Hidf(P(bbmV4-m{d? zj^)?EM*6^iX0w@EOuzwGZ`R(s2_EwCb#`ar+Ho@V^)ZOdg&AZ1ptuu5H+T=~BnQ)P zpeMvx?A{fewIgLnDvyMkX&@wrha5aL*4> z*qC~E@CWGT^j3`DsVBMr>Fc1Hteax*y^8xk^MO+IK^ZI?eQ-7WNpGU&v|~C12X-N@ zW!fj|NBiwPgAm6AwfFujGVqcIKUZxwvkZb_ee^A#3(M*4s7~vbi!Ak0dOp=Z#?;hN z`)(^-u=lLQwf6L>MclvIECwJQgwSB@N_5+M$f+2CJ@x2at-lqE(DyOcs%H7+vlwZX z?)wCI@6e88gDvFxZqnohe}i0bpy4YrgQqoQL5RjTK8Y7xABgY+*U88}H_i3p&wdC7pT3VZ48e(Nm+(8{K<>aNBOQEyl z<81cqzyRGtYkgCfU5bYG4(ZnH2)~(zm4ShS*+m}Krd5rBXvr~~mU?Hab>r|sbT=11 zyK#_;vZG@C9wbi6A08`$yoQ^L!zXXmEF)U#nD*-DozQ>Q(0@&r`fm#T?&Yt-4c0lU z4VvkP(0v<^O+5t2^3gEe&uhu$`({8upFi%xthT{Y1>U9J$&PHyJOGu<7F@Xd1M5;j)8%K;Q)ehQmvRdAnVoWFbCH`$IVa^l{Rp{k%6&k&eU$q>j6F9&w&b;v_-6}kL40Ib~0cGNYd-a2)~fWS$A zCyJ7vUT*0B-q8Q-L+HN&efYw?cu0j8&r#Ld&ZAd@oGRmSX|NjAaW{Sj6>_7@e&FW* z)o(UdgJr=^qUTDNWq}VM{yFobo$Hwf?H#PgihH zUvYv6@N{!ZcbsWXZFh`msSOUyy7%gu7r&#XK5I&y(++=D)Rg*FdOlU#ds<&mi)J{X zcfL7=yX8Nq*~@=Je!zERK@zXTB$wcF-cCK*fiozdvaY$QMd^t8 z142;ROGLRKFOEjS+qjHU=?#Y!zgPDvp@g9t^ZM=&=!wM_)e}+lsIoca4@}6RrHOpG z)_dVMT-iwCUcX!AZV!PqtT4DieW#(&3FLF_`5F^31JrF=q|C zia(I>#X~VVZzCsV`$AkMudilSBv?hwlJ$^cwY4`bsi|SL%jkMT-Ho{3^p{I0Y zqNA$9uT*ID6}Q({tYg>v16!`w^=<2FSZ5^B8H+{Zdcd#ngSUF6B2fbP{z!CdM2T`g zlrL8JzF5NaXp|bTP4UJzb#??IIs|>uNCc;dp~xockBWp+S%JRg=Y7h(cYJ9hNpyz& zN+had&ghCb=o`my04OR+B^ zj*hv(uP~Yr^$NQdNlAo5F(tYs5D$i|Im`T_n;X#MbZ9VeI-6Y&>ik1CI|{lN zx0&6b40qXkK}vD2K>s%?bYlTZiT;P8Wclh^X6Y)m%)fMc@c_ykz~~&d1~&JTtgUpF zt?V}YC0mQT*{$<#zV-&kBA{HR5wr|--9>Q&d}Ja%!Wk#yVPJt5j`@YAb`p3R|&ioMtvd<$I+6em2`ir&cKan$=}1 z+f%f{ru0u)VXNFdRkhVTGEKGBC8w{p4NNJzW=e^z4j61hW<`!gYVTS6PQV`{0)s)K z_FfAAMu4XX`10Q2)IWv5|4;wdd%!ct$z5~`D*dIYM+rC9JjpZh zSc#MKGYyzMjyp6;bNLk)+}Tl@-iRMXOl+#+FB&IzbFY)BDIywFL^K6tdl|=@R z|MPirPBVB~zm(RCa(Tx8nE~fKQzpoKCQdy5XEM?v52tc&$3%waJth2;&J+IkGg7gW zQ;F}LZt$`l9$soZ+oo)p;PH<(Z%?<7$GsQlWj~)0{4JtfsQuZAe2*c&qHl_E{=T3G z1U)9`F9m&9&~t)LyTr*&%@On(L6-`;O3*t64GOwN&_@LQrl8*!^njqp1pTF;?+SWO z&}sNTiP9WFuMw1krpxM;E9;fY#z1=rw?sEq|7G=(s+$%Y8J1Uu(yAp?h74oXiESOa zw;fcE8+5bG@mqx$tH#YnpjutgRHb`232sxQv%0-Agx4%WepXG~W-lI&R{OU_V9%g< ztjSAogOH%7oo2?3vUniuB?Xa-g>_aPis0#LHQn{G>L3`DMd^N%RR=b^gK=+1z`fZI zUC9|5Zf`v9-DYUW{8xMsgLQ95$cL(3z)4zhIV|ZFXP~P zp`R87)JE!OS-*@&cLF0(sW0QIQv_BSMIMF`3`E#)M= zALSGiB`@P*x6oIFe!l+#W?w~y`cmr4IJ{TrdxW5@KfnDwdHPJmb=gsJA0U0&>+<#Y z0HZ#U_T|196C05YW#%NuU1BL@%=+CWPF~b4^!Yuc6b6<1u%wRyGwaj&5TzQiQHSM* z&Cv;c!Ln~5W7e1Z_~T-N%#ebD=KH@_=*#}!C+-9G34JY3LH3_CyDv{)zTYO_duxz_ zg65fH2lDi5u5xn8nyUw-olwbc4%4m$la$)kmg((1$^5ygSmmy=vPwE#d9&pf8 zIQgUcCm=>HN_{#Jql7bRp7QI<=YI<+ntM`T?&D<&S08^LQ7ngXf8_jm7h>l6<$ES$ zR~!2I^+{gRQ+fJqk;hP6WRSE$#;;OO(z7Tr*Pj;pX`wIulm?`pXT@pmUDtAFf9L;rhu3nssQQOl&Hh`h5pFDffSw3Yj;xv&U5A@|Q* zda=li8WeK)1RGcIr@>IKVFFRmn?|Nr*4fs;RF-_t z{^D_b6*$?E|G$$CCE6D(lgx)g?Yh9_XEVWf_d;`u}8 zXZ$Vey!p10%U?Wy?gl;^?V_h&lw^zyahyXrmxl`A-zb3p7`T#S!C+niKH2-QZ*lpH z=kxo(XHQ~>9G>j`*~@@WCVx!Qak%yW7?XHL!n@^^Fm;yB|jAfG6JKT-gHtN{KK z;H5bI$zShB3do-*fS(4gm>Vkc7l6;Q&Shuv`e8;9_47phl-pey@X7l5+5-431@N^T zw=sJBN{Q~*DYX}n-vXS*OS#U&<>ci7VMl&XBk_lYeE#_E5%O{$;b*u|`Z~v@_5}T> z0{Bn?{8t6=Oaa`Aj-9MO=KxnG+!)VYTR^^{0Nw(e#y7toHWaYGh1w5}B|!Q)Nzz@`wM6~*0phuas9M(`kS63FfLN8Ovk z(ROdx?boC6gxlNMh38Nmv2Xy-o2r-AEL#H0lL)!#u*W#MapO29zKt1&J$NG8u?;FF z&P``TIiha&s6!-L#H{@Fn;#Gei3Li}l7F60jI(=h&>g7K|DUO7L8Grlm$E#coO z%<`6mkW`w+*>q-ZvVUQHiK~vp3>L&$*lKKquiF40mS&-(1k+ z Date: Sat, 10 May 2014 17:03:11 -0400 Subject: [PATCH 011/120] tunslip6: remove trailing whitespace --- tools/tunslip6.c | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/tools/tunslip6.c b/tools/tunslip6.c index 65e440800..71b05742c 100644 --- a/tools/tunslip6.c +++ b/tools/tunslip6.c @@ -34,7 +34,7 @@ /* Below define allows importing saved output into Wireshark as "Raw IP" packet type */ #define WIRESHARK_IMPORT_FORMAT 1 - + #include #include #include @@ -116,7 +116,7 @@ stamptime(void) time_t t; struct tm *tmp; char timec[20]; - + gettimeofday(&tv, NULL) ; msecs=tv.tv_usec/1000; secs=tv.tv_sec; @@ -226,7 +226,7 @@ serial_to_tun(FILE *inslip, int outfd) if(timestamp) stamptime(); fprintf(stderr,"*** Address:%s => %02x%02x:%02x%02x:%02x%02x:%02x%02x\n", // printf("*** Address:%s => %02x%02x:%02x%02x:%02x%02x:%02x%02x\n", - ipaddr, + ipaddr, addr.s6_addr[0], addr.s6_addr[1], addr.s6_addr[2], addr.s6_addr[3], addr.s6_addr[4], addr.s6_addr[5], @@ -240,7 +240,7 @@ serial_to_tun(FILE *inslip, int outfd) slip_send(slipfd, SLIP_END); } #define DEBUG_LINE_MARKER '\r' - } else if(uip.inbuf[0] == DEBUG_LINE_MARKER) { + } else if(uip.inbuf[0] == DEBUG_LINE_MARKER) { fwrite(uip.inbuf + 1, inbufptr - 1, 1, stdout); } else if(is_sensible_string(uip.inbuf, inbufptr)) { if(verbose==1) { /* strings already echoed below for verbose>1 */ @@ -310,7 +310,7 @@ serial_to_tun(FILE *inslip, int outfd) if(c=='\n') if(timestamp) stamptime(); } } - + break; } @@ -358,7 +358,7 @@ void slip_flushbuf(int fd) { int n; - + if(slip_empty()) { return; } @@ -636,7 +636,7 @@ ifconf(const char *tundev, const char *ipaddr) } else { cc=0; digit = c-'0'; - if (digit > 9) + if (digit > 9) digit = 10 + (c & 0xdf) - 'A'; a[ai] = (a[ai] << 4) + digit; } @@ -713,7 +713,7 @@ main(int argc, char **argv) case 'H': flowcontrol=1; break; - + case 'L': timestamp=1; break; @@ -755,7 +755,7 @@ main(int argc, char **argv) case 'T': tap = 1; break; - + case '?': case 'h': default: @@ -950,7 +950,7 @@ exit(1); FD_SET(slipfd, &rset); /* Read from slip ASAP! */ if(slipfd > maxfd) maxfd = slipfd; - + /* We only have one packet at a time queued for slip output. */ if(slip_empty()) { FD_SET(tunfd, &rset); @@ -964,12 +964,12 @@ exit(1); if(FD_ISSET(slipfd, &rset)) { serial_to_tun(inslip, tunfd); } - + if(FD_ISSET(slipfd, &wset)) { slip_flushbuf(slipfd); sigalarm_reset(); } - + /* Optional delay between outgoing packets */ /* Base delay times number of 6lowpan fragments to be sent */ if(delaymsec) { From ab2c110c708526729be4451180c5a2740f241eff Mon Sep 17 00:00:00 2001 From: Michael Richardson Date: Sat, 10 May 2014 17:15:23 -0400 Subject: [PATCH 012/120] tunslip6: show progres with -P argument --- tools/tunslip6.c | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/tools/tunslip6.c b/tools/tunslip6.c index 71b05742c..9593792cd 100644 --- a/tools/tunslip6.c +++ b/tools/tunslip6.c @@ -62,7 +62,7 @@ const char *netmask; int slipfd = 0; uint16_t basedelay=0,delaymsec=0; uint32_t startsec,startmsec,delaystartsec,delaystartmsec; -int timestamp = 0, flowcontrol=0; +int timestamp = 0, flowcontrol=0, showprogress=0; int ssystem(const char *fmt, ...) __attribute__((__format__ (__printf__, 1, 2))); @@ -71,8 +71,7 @@ void write_to_serial(int outfd, void *inbuf, int len); void slip_send(int fd, unsigned char c); void slip_send_char(int fd, unsigned char c); -//#define PROGRESS(s) fprintf(stderr, s) -#define PROGRESS(s) do { } while (0) +#define PROGRESS(s) if(showprogress) fprintf(stderr, s) char tundev[1024] = { "" }; @@ -187,7 +186,7 @@ serial_to_tun(FILE *inslip, int outfd) clearerr(inslip); return; } - /* fprintf(stderr, ".");*/ + PROGRESS("."); switch(c) { case SLIP_END: if(inbufptr > 0) { @@ -704,7 +703,7 @@ main(int argc, char **argv) prog = argv[0]; setvbuf(stdout, NULL, _IOLBF, 0); /* Line buffered output. */ - while((c = getopt(argc, argv, "B:HLhs:t:v::d::a:p:T")) != -1) { + while((c = getopt(argc, argv, "B:HLPhs:t:v::d::a:p:T")) != -1) { switch(c) { case 'B': baudrate = atoi(optarg); @@ -718,6 +717,10 @@ main(int argc, char **argv) timestamp=1; break; + case 'P': + showprogress=1; + break; + case 's': if(strncmp("/dev/", optarg, 5) == 0) { siodev = optarg + 5; From 6b473301c5dfc1bf549d2b473bcef38352d7c556 Mon Sep 17 00:00:00 2001 From: Michael Richardson Date: Sat, 10 May 2014 17:16:35 -0400 Subject: [PATCH 013/120] tunslip6: removed commented out line printing IP address --- tools/tunslip6.c | 1 - 1 file changed, 1 deletion(-) diff --git a/tools/tunslip6.c b/tools/tunslip6.c index 9593792cd..861868c84 100644 --- a/tools/tunslip6.c +++ b/tools/tunslip6.c @@ -224,7 +224,6 @@ serial_to_tun(FILE *inslip, int outfd) inet_pton(AF_INET6, ipaddr, &addr); if(timestamp) stamptime(); fprintf(stderr,"*** Address:%s => %02x%02x:%02x%02x:%02x%02x:%02x%02x\n", - // printf("*** Address:%s => %02x%02x:%02x%02x:%02x%02x:%02x%02x\n", ipaddr, addr.s6_addr[0], addr.s6_addr[1], addr.s6_addr[2], addr.s6_addr[3], From 6608b62b01953b8a263ffda65802c1bc9052c06c Mon Sep 17 00:00:00 2001 From: Michael Richardson Date: Sat, 10 May 2014 17:16:07 -0400 Subject: [PATCH 014/120] tunslip6: make printing of sensible strings from mote more reliable --- tools/tunslip6.c | 22 +++++++++++++++------- 1 file changed, 15 insertions(+), 7 deletions(-) diff --git a/tools/tunslip6.c b/tools/tunslip6.c index 861868c84..b4390eacf 100644 --- a/tools/tunslip6.c +++ b/tools/tunslip6.c @@ -238,13 +238,21 @@ serial_to_tun(FILE *inslip, int outfd) slip_send(slipfd, SLIP_END); } #define DEBUG_LINE_MARKER '\r' - } else if(uip.inbuf[0] == DEBUG_LINE_MARKER) { - fwrite(uip.inbuf + 1, inbufptr - 1, 1, stdout); - } else if(is_sensible_string(uip.inbuf, inbufptr)) { - if(verbose==1) { /* strings already echoed below for verbose>1 */ - if (timestamp) stamptime(); - fwrite(uip.inbuf, inbufptr, 1, stdout); - } + if(uip.inbuf[0] == DEBUG_LINE_MARKER || + is_sensible_string(uip.inbuf, inbufptr)) { + unsigned char *out = uip.inbuf; + unsigned int len = inbufptr; + if(uip.inbuf[0] == DEBUG_LINE_MARKER) { + out++; + len--; + } + fprintf(stderr, "\n***"); + fwrite(out, len, 1, stderr); + fprintf(stderr, "***\n"); + } else { + fprintf(stderr, + "serial_to_tun: drop packet len=%d\n", inbufptr); + } } else { if(verbose>2) { if (timestamp) stamptime(); From f1433f7d5fc389749ceb769dd8ce413ab6e82ee8 Mon Sep 17 00:00:00 2001 From: Michael Richardson Date: Sat, 10 May 2014 17:19:51 -0400 Subject: [PATCH 015/120] tunslip6: option to turn off processing of IPA= address allocation --- tools/tunslip6.c | 31 ++++++++++++++++++------------- 1 file changed, 18 insertions(+), 13 deletions(-) diff --git a/tools/tunslip6.c b/tools/tunslip6.c index b4390eacf..e2413cb88 100644 --- a/tools/tunslip6.c +++ b/tools/tunslip6.c @@ -704,13 +704,14 @@ main(int argc, char **argv) const char *port = NULL; const char *prog; int baudrate = -2; + int ipa_enable = 1; int tap = 0; slipfd = 0; prog = argv[0]; setvbuf(stdout, NULL, _IOLBF, 0); /* Line buffered output. */ - while((c = getopt(argc, argv, "B:HLPhs:t:v::d::a:p:T")) != -1) { + while((c = getopt(argc, argv, "B:HILPhs:t:v::d::a:p:T")) != -1) { switch(c) { case 'B': baudrate = atoi(optarg); @@ -736,6 +737,11 @@ main(int argc, char **argv) } break; + case 'I': + ipa_enable = 0; + fprintf(stderr, "Will not inquire about IP address using IPA=\n"); + break; + case 't': if(strncmp("/dev/", optarg, 5) == 0) { strncpy(tundev, optarg + 5, sizeof(tundev)); @@ -943,16 +949,15 @@ exit(1); FD_ZERO(&rset); FD_ZERO(&wset); -/* do not send IPA all the time... - add get MAC later... */ -/* if(got_sigalarm) { */ -/* /\* Send "?IPA". *\/ */ -/* slip_send(slipfd, '?'); */ -/* slip_send(slipfd, 'I'); */ -/* slip_send(slipfd, 'P'); */ -/* slip_send(slipfd, 'A'); */ -/* slip_send(slipfd, SLIP_END); */ -/* got_sigalarm = 0; */ -/* } */ + if(got_sigalarm && ipa_enable) { + /* Send "?IPA". */ + slip_send(slipfd, '?'); + slip_send(slipfd, 'I'); + slip_send(slipfd, 'P'); + slip_send(slipfd, 'A'); + slip_send(slipfd, SLIP_END); + got_sigalarm = 0; + } if(!slip_empty()) { /* Anything to flush? */ FD_SET(slipfd, &wset); @@ -977,7 +982,7 @@ exit(1); if(FD_ISSET(slipfd, &wset)) { slip_flushbuf(slipfd); - sigalarm_reset(); + if(ipa_enable) sigalarm_reset(); } /* Optional delay between outgoing packets */ @@ -995,7 +1000,7 @@ exit(1); if(slip_empty() && FD_ISSET(tunfd, &rset)) { size=tun_to_serial(tunfd, slipfd); slip_flushbuf(slipfd); - sigalarm_reset(); + if(ipa_enable) sigalarm_reset(); if(basedelay) { struct timeval tv; gettimeofday(&tv, NULL) ; From 11c3dcc622990b3b9b8e4d1e04c3a50c78411cdc Mon Sep 17 00:00:00 2001 From: Michael Richardson Date: Fri, 9 May 2014 14:25:59 -0400 Subject: [PATCH 016/120] tunslip6: added some better clarification of errors when TUNSETIFF fails --- tools/tunslip6.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/tools/tunslip6.c b/tools/tunslip6.c index e2413cb88..4f3ff7e3e 100644 --- a/tools/tunslip6.c +++ b/tools/tunslip6.c @@ -520,6 +520,7 @@ tun_alloc(char *dev, int tap) int fd, err; if( (fd = open("/dev/net/tun", O_RDWR)) < 0 ) { + perror("can not open /dev/net/tun"); return -1; } @@ -536,8 +537,12 @@ tun_alloc(char *dev, int tap) if((err = ioctl(fd, TUNSETIFF, (void *) &ifr)) < 0 ) { close(fd); + fprintf(stderr, "can not tunsetiff to %s (flags=%08x): %s\n", dev, ifr.ifr_flags, + strerror(errno)); return err; } + + /* get resulting tunnel name */ strcpy(dev, ifr.ifr_name); return fd; } @@ -932,7 +937,7 @@ exit(1); if(inslip == NULL) err(1, "main: fdopen"); tunfd = tun_alloc(tundev, tap); - if(tunfd == -1) err(1, "main: open"); + if(tunfd == -1) err(1, "main: open /dev/tun"); if (timestamp) stamptime(); fprintf(stderr, "opened %s device ``/dev/%s''\n", tap ? "tap" : "tun", tundev); From 3d284f8ecd5583889c6fd2682c682b57249d2a7c Mon Sep 17 00:00:00 2001 From: Nicolas Tsiftes Date: Mon, 25 May 2015 16:52:12 +0200 Subject: [PATCH 017/120] Use the new path to a header file. --- platform/wismote/contiki-wismote-main.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/platform/wismote/contiki-wismote-main.c b/platform/wismote/contiki-wismote-main.c index 5e74a22ee..8322e749d 100644 --- a/platform/wismote/contiki-wismote-main.c +++ b/platform/wismote/contiki-wismote-main.c @@ -73,7 +73,7 @@ extern const struct uip_router UIP_ROUTER_MODULE; #if NETSTACK_CONF_WITH_IPV4 #include "net/ip/uip.h" #include "net/ipv4/uip-fw.h" -#include "net/uip-fw-drv.h" +#include "net/ipv4/uip-fw-drv.h" #include "net/ipv4/uip-over-mesh.h" static struct uip_fw_netif slipif = {UIP_FW_NETIF(192,168,1,2, 255,255,255,255, slip_send)}; From a14c78e1ceeb96d273673d2821b5e3c5d94d9d23 Mon Sep 17 00:00:00 2001 From: Nicolas Tsiftes Date: Mon, 25 May 2015 17:04:39 +0200 Subject: [PATCH 018/120] Build the Wismote platform with ContikiMAC and CSMA enabled by default. --- platform/wismote/contiki-conf.h | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/platform/wismote/contiki-conf.h b/platform/wismote/contiki-conf.h index 761d68f91..03cfcff40 100644 --- a/platform/wismote/contiki-conf.h +++ b/platform/wismote/contiki-conf.h @@ -6,13 +6,11 @@ #include "platform-conf.h" #ifndef NETSTACK_CONF_MAC -/* #define NETSTACK_CONF_MAC csma_driver */ -#define NETSTACK_CONF_MAC nullmac_driver +#define NETSTACK_CONF_MAC csma_driver #endif /* NETSTACK_CONF_MAC */ #ifndef NETSTACK_CONF_RDC -/* #define NETSTACK_CONF_RDC contikimac_driver */ -#define NETSTACK_CONF_RDC nullrdc_driver +#define NETSTACK_CONF_RDC contikimac_driver #endif /* NETSTACK_CONF_RDC */ #ifndef NETSTACK_CONF_RDC_CHANNEL_CHECK_RATE From 08503a20be606968ef116b1b95f9c24a05762cb0 Mon Sep 17 00:00:00 2001 From: rajithr Date: Wed, 27 May 2015 19:06:19 +0530 Subject: [PATCH 019/120] Protection against possible buffer overflow --- core/net/packetbuf.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/core/net/packetbuf.c b/core/net/packetbuf.c index 217f40bc2..20bfebe80 100644 --- a/core/net/packetbuf.c +++ b/core/net/packetbuf.c @@ -141,6 +141,7 @@ packetbuf_copyto(void *to) int i; char buffer[1000]; char *bufferptr = buffer; + int bufferlen = 0; bufferptr[0] = 0; for(i = hdrptr; i < PACKETBUF_HDR_SIZE; ++i) { @@ -149,8 +150,8 @@ packetbuf_copyto(void *to) PRINTF("packetbuf_write: header: %s\n", buffer); bufferptr = buffer; bufferptr[0] = 0; - for(i = bufptr; i < buflen + bufptr; ++i) { - bufferptr += sprintf(bufferptr, "0x%02x, ", packetbufptr[i]); + for(i = bufptr; ((i < buflen + bufptr) && (bufferlen < 980)); ++i) { + bufferlen += sprintf(bufferptr + bufferlen, "0x%02x, ", packetbufptr[i]); } PRINTF("packetbuf_write: data: %s\n", buffer); } From 034a97eed2e6f6521e3d82d667eba57d400e68b6 Mon Sep 17 00:00:00 2001 From: Timofei Istomin Date: Thu, 28 May 2015 21:51:02 +0200 Subject: [PATCH 020/120] Don't generate a zero-length packet in case of errors. The packet converter used to generate packets of length zero when it encountered errors during conversion. This caused exceptions in packet analyzers. Now the converter returns null in case of error. Appropriate checks have been added to the code that uses the return value. --- .../interfaces/CC2420RadioPacketConverter.java | 2 +- .../cooja/mspmote/interfaces/Msp802154Radio.java | 11 +++++++---- .../cooja/motes/AbstractApplicationMote.java | 3 ++- .../java/org/contikios/cooja/plugins/RadioLogger.java | 4 +++- 4 files changed, 13 insertions(+), 7 deletions(-) diff --git a/tools/cooja/apps/mspsim/src/org/contikios/cooja/mspmote/interfaces/CC2420RadioPacketConverter.java b/tools/cooja/apps/mspsim/src/org/contikios/cooja/mspmote/interfaces/CC2420RadioPacketConverter.java index 3fda7681d..946e2398c 100644 --- a/tools/cooja/apps/mspsim/src/org/contikios/cooja/mspmote/interfaces/CC2420RadioPacketConverter.java +++ b/tools/cooja/apps/mspsim/src/org/contikios/cooja/mspmote/interfaces/CC2420RadioPacketConverter.java @@ -198,7 +198,7 @@ public class CC2420RadioPacketConverter { System.arraycopy(data, 6 /* skipping preamble+synch+len */, originalData, 0, originalLen); if (len < 0) { /*logger.warn("No cross-level conversion available: negative packet length");*/ - return new ConvertedRadioPacket(new byte[0], originalData); + return null; } byte convertedData[] = new byte[len]; System.arraycopy(data, pos, convertedData, 0, len); diff --git a/tools/cooja/apps/mspsim/src/org/contikios/cooja/mspmote/interfaces/Msp802154Radio.java b/tools/cooja/apps/mspsim/src/org/contikios/cooja/mspmote/interfaces/Msp802154Radio.java index c99710f3d..9937e6a74 100644 --- a/tools/cooja/apps/mspsim/src/org/contikios/cooja/mspmote/interfaces/Msp802154Radio.java +++ b/tools/cooja/apps/mspsim/src/org/contikios/cooja/mspmote/interfaces/Msp802154Radio.java @@ -99,6 +99,7 @@ public class Msp802154Radio extends Radio implements CustomDataRadio { public void receivedByte(byte data) { if (!isTransmitting()) { lastEvent = RadioEvent.TRANSMISSION_STARTED; + lastOutgoingPacket = null; isTransmitting = true; len = 0; expMpduLen = 0; @@ -139,10 +140,12 @@ public class Msp802154Radio extends Radio implements CustomDataRadio { if (((expMpduLen & 0x80) == 0) && len == expMpduLen + 6 && isSynchronized) { lastOutgoingPacket = CC2420RadioPacketConverter.fromCC2420ToCooja(buffer); - lastEvent = RadioEvent.PACKET_TRANSMITTED; - //logger.debug("----- 802.15.4 PACKET TRANSMITTED -----"); - setChanged(); - notifyObservers(); + if (lastOutgoingPacket != null) { + lastEvent = RadioEvent.PACKET_TRANSMITTED; + //logger.debug("----- 802.15.4 PACKET TRANSMITTED -----"); + setChanged(); + notifyObservers(); + } isSynchronized = false; } } diff --git a/tools/cooja/java/org/contikios/cooja/motes/AbstractApplicationMote.java b/tools/cooja/java/org/contikios/cooja/motes/AbstractApplicationMote.java index 98de78327..fd16d37a3 100644 --- a/tools/cooja/java/org/contikios/cooja/motes/AbstractApplicationMote.java +++ b/tools/cooja/java/org/contikios/cooja/motes/AbstractApplicationMote.java @@ -76,7 +76,8 @@ public abstract class AbstractApplicationMote extends AbstractWakeupMote impleme if (radio.getLastPacketReceived() != null) receivedPacket(radio.getLastPacketReceived()); } else if (radio.getLastEvent() == Radio.RadioEvent.TRANSMISSION_FINISHED) { - sentPacket(radio.getLastPacketTransmitted()); + if (radio.getLastPacketTransmitted() != null) + sentPacket(radio.getLastPacketTransmitted()); } } }; diff --git a/tools/cooja/java/org/contikios/cooja/plugins/RadioLogger.java b/tools/cooja/java/org/contikios/cooja/plugins/RadioLogger.java index 17f5417c2..abdc76f6c 100644 --- a/tools/cooja/java/org/contikios/cooja/plugins/RadioLogger.java +++ b/tools/cooja/java/org/contikios/cooja/plugins/RadioLogger.java @@ -517,10 +517,12 @@ public class RadioLogger extends VisPlugin { return; } final RadioConnectionLog loggedConn = new RadioConnectionLog(); + loggedConn.packet = conn.getSource().getLastPacketTransmitted(); + if (loggedConn.packet == null) + return; loggedConn.startTime = conn.getStartTime(); loggedConn.endTime = simulation.getSimulationTime(); loggedConn.connection = conn; - loggedConn.packet = conn.getSource().getLastPacketTransmitted(); java.awt.EventQueue.invokeLater(new Runnable() { @Override public void run() { From eb4bdde9ca6ce7f2b20089d2cf097512f9986f78 Mon Sep 17 00:00:00 2001 From: Timofei Istomin Date: Fri, 5 Jun 2015 15:13:45 +0200 Subject: [PATCH 021/120] Finish the transmission at the end of a correct packet This patch restores the original behaviour of Cooja when the transmitted packet is correct (which is true in a vast majority of cases). In case of a wrong outgoing packet (wrong length, wrong preamble) the transmission will end when the radio changes its state (which should always happen after transmitting a packet). Benchmarks with RPL (33 runs, 50 nodes, 3 hours of simulated time each) yield the same results (PDR, delay, number of transmitted packets) as with the unmodified Cooja. --- .../org/contikios/cooja/mspmote/interfaces/Msp802154Radio.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/cooja/apps/mspsim/src/org/contikios/cooja/mspmote/interfaces/Msp802154Radio.java b/tools/cooja/apps/mspsim/src/org/contikios/cooja/mspmote/interfaces/Msp802154Radio.java index 9937e6a74..31aa30377 100644 --- a/tools/cooja/apps/mspsim/src/org/contikios/cooja/mspmote/interfaces/Msp802154Radio.java +++ b/tools/cooja/apps/mspsim/src/org/contikios/cooja/mspmote/interfaces/Msp802154Radio.java @@ -146,7 +146,7 @@ public class Msp802154Radio extends Radio implements CustomDataRadio { setChanged(); notifyObservers(); } - isSynchronized = false; + finishTransmission(); } } }); /* addRFListener */ From 1784338b2ec69109b19ef237b2463b04e72946aa Mon Sep 17 00:00:00 2001 From: Laurent Deru Date: Mon, 15 Jun 2015 10:25:58 +0200 Subject: [PATCH 022/120] Add uip_clear_buf() macro and replace all instances of uip_len = 0; with it --- core/dev/slip.c | 2 +- core/net/ip/tcpip.c | 22 ++++++++----------- core/net/ip/uip.h | 16 ++++++++++++++ core/net/ip64/ip64-slip-interface.c | 6 ++--- core/net/ipv4/uip-fw.c | 2 +- core/net/ipv4/uip.c | 6 ++--- core/net/ipv4/uip_arp.c | 4 ++-- core/net/ipv6/multicast/roll-tm.c | 3 +-- core/net/ipv6/multicast/smrf.c | 2 +- core/net/ipv6/uip-icmp6.c | 10 ++++----- core/net/ipv6/uip-nd6.c | 10 ++++----- core/net/ipv6/uip6.c | 15 +++++-------- core/net/rpl/rpl-icmp6.c | 8 +++---- cpu/native/net/tapdev-drv.c | 2 +- cpu/native/net/wpcap-drv.c | 4 ++-- .../cc2530dk/border-router/border-router.c | 2 +- examples/cc2530dk/border-router/slip-bridge.c | 2 +- .../ipv6/rpl-border-router/border-router.c | 2 +- examples/ipv6/rpl-border-router/slip-bridge.c | 4 ++-- examples/ipv6/slip-radio/slip-radio.c | 2 +- .../sensinode/border-router/border-router.c | 2 +- .../sensinode/border-router/slip-bridge.c | 2 +- platform/avr-ravenusb/sicslow_ethernet.c | 14 ++++++------ tools/cc2538-bsl | 2 +- tools/sky/uip6-bridge/dev/slip.c | 2 +- tools/sky/uip6-bridge/sicslow_ethernet.c | 12 +++++----- tools/sky/uip6-bridge/uip6-bridge-tap.c | 2 +- tools/stm32w/uip6_bridge/dev/slip.c | 2 +- tools/stm32w/uip6_bridge/sicslow_ethernet.c | 12 +++++----- tools/stm32w/uip6_bridge/uip6-bridge-tap.c | 2 +- 30 files changed, 92 insertions(+), 84 deletions(-) diff --git a/core/dev/slip.c b/core/dev/slip.c index 6b8a24ceb..451b9ec6c 100644 --- a/core/dev/slip.c +++ b/core/dev/slip.c @@ -293,7 +293,7 @@ PROCESS_THREAD(slip_process, ev, data) tcpip_input(); #endif } else { - uip_len = 0; + uip_clear_buf(); SLIP_STATISTICS(slip_ip_drop++); } #else /* NETSTACK_CONF_WITH_IPV6 */ diff --git a/core/net/ip/tcpip.c b/core/net/ip/tcpip.c index 1c75d1bc9..0505b3d47 100644 --- a/core/net/ip/tcpip.c +++ b/core/net/ip/tcpip.c @@ -529,10 +529,7 @@ void tcpip_input(void) { process_post_synch(&tcpip_process, PACKET_INPUT, NULL); - uip_len = 0; -#if NETSTACK_CONF_WITH_IPV6 - uip_ext_len = 0; -#endif /*NETSTACK_CONF_WITH_IPV6*/ + uip_clear_buf(); } /*---------------------------------------------------------------------------*/ #if NETSTACK_CONF_WITH_IPV6 @@ -548,13 +545,13 @@ tcpip_ipv6_output(void) if(uip_len > UIP_LINK_MTU) { UIP_LOG("tcpip_ipv6_output: Packet to big"); - uip_len = 0; + uip_clear_buf(); return; } if(uip_is_addr_unspecified(&UIP_IP_BUF->destipaddr)){ UIP_LOG("tcpip_ipv6_output: Destination address unspecified"); - uip_len = 0; + uip_clear_buf(); return; } @@ -591,7 +588,7 @@ tcpip_ipv6_output(void) #else PRINTF("tcpip_ipv6_output: Destination off-link but no route\n"); #endif /* !UIP_FALLBACK_INTERFACE */ - uip_len = 0; + uip_clear_buf(); return; } @@ -643,7 +640,7 @@ tcpip_ipv6_output(void) #if UIP_CONF_IPV6_RPL if(rpl_update_header_final(nexthop)) { - uip_len = 0; + uip_clear_buf(); return; } #endif /* UIP_CONF_IPV6_RPL */ @@ -651,7 +648,7 @@ tcpip_ipv6_output(void) if(nbr == NULL) { #if UIP_ND6_SEND_NA if((nbr = uip_ds6_nbr_add(nexthop, NULL, 0, NBR_INCOMPLETE)) == NULL) { - uip_len = 0; + uip_clear_buf(); return; } else { #if UIP_CONF_IPV6_QUEUE_PKT @@ -689,7 +686,7 @@ tcpip_ipv6_output(void) uip_packetqueue_set_buflen(&nbr->packethandle, uip_len); } #endif /*UIP_CONF_IPV6_QUEUE_PKT*/ - uip_len = 0; + uip_clear_buf(); return; } /* Send in parallel if we are running NUD (nbc state is either STALE, @@ -719,15 +716,14 @@ tcpip_ipv6_output(void) } #endif /*UIP_CONF_IPV6_QUEUE_PKT*/ - uip_len = 0; + uip_clear_buf(); return; } return; } /* Multicast IP destination address. */ tcpip_output(NULL); - uip_len = 0; - uip_ext_len = 0; + uip_clear_buf(); } #endif /* NETSTACK_CONF_WITH_IPV6 */ /*---------------------------------------------------------------------------*/ diff --git a/core/net/ip/uip.h b/core/net/ip/uip.h index cb12f52ab..a85929554 100644 --- a/core/net/ip/uip.h +++ b/core/net/ip/uip.h @@ -1326,6 +1326,22 @@ extern uint8_t uip_ext_len; extern uint16_t uip_urglen, uip_surglen; #endif /* UIP_URGDATA > 0 */ +/* + * Clear uIP buffer + * + * This function clears the uIP buffer by reseting the uip_len and + * uip_ext_len pointers. + */ +#if NETSTACK_CONF_WITH_IPV6 +#define uip_clear_buf() { \ + uip_len = 0; \ + uip_ext_len = 0; \ +} +#else /*NETSTACK_CONF_WITH_IPV6*/ +#define uip_clear_buf() { \ + uip_len = 0; \ +} +#endif /*NETSTACK_CONF_WITH_IPV6*/ /** * Representation of a uIP TCP connection. diff --git a/core/net/ip64/ip64-slip-interface.c b/core/net/ip64/ip64-slip-interface.c index 05fe704c7..8d46d78a8 100644 --- a/core/net/ip64/ip64-slip-interface.c +++ b/core/net/ip64/ip64-slip-interface.c @@ -59,7 +59,7 @@ input_callback(void) /*PRINTF("SIN: %u\n", uip_len);*/ if(uip_buf[0] == '!') { PRINTF("Got configuration message of type %c\n", uip_buf[1]); - uip_len = 0; + uip_clear_buf(); #if 0 if(uip_buf[1] == 'P') { uip_ipaddr_t prefix; @@ -87,7 +87,7 @@ input_callback(void) slip_send(); } - uip_len = 0; + uip_clear_buf(); } else { /* Save the last sender received over SLIP to avoid bouncing the @@ -101,7 +101,7 @@ input_callback(void) uip_len = len; /* PRINTF("send len %d\n", len); */ } else { - uip_len = 0; + uip_clear_buf(); } } } diff --git a/core/net/ipv4/uip-fw.c b/core/net/ipv4/uip-fw.c index c152231c0..530a0b7c0 100644 --- a/core/net/ipv4/uip-fw.c +++ b/core/net/ipv4/uip-fw.c @@ -229,7 +229,7 @@ time_exceeded(void) /* We don't send out ICMP errors for ICMP messages (unless they are pings). */ if(ICMPBUF->proto == UIP_PROTO_ICMP && ICMPBUF->type != ICMP_ECHO) { - uip_len = 0; + uip_clear_buf(); return; } /* Copy fields from packet header into payload of this ICMP packet. */ diff --git a/core/net/ipv4/uip.c b/core/net/ipv4/uip.c index 1c3c24aaf..48366a114 100644 --- a/core/net/ipv4/uip.c +++ b/core/net/ipv4/uip.c @@ -709,7 +709,7 @@ uip_process(uint8_t flag) } /* Reset the length variables. */ - uip_len = 0; + uip_clear_buf(); uip_slen = 0; #if UIP_TCP @@ -1589,7 +1589,7 @@ uip_process(uint8_t flag) uip_add_rcv_nxt(1); uip_flags = UIP_CONNECTED | UIP_NEWDATA; uip_connr->len = 0; - uip_len = 0; + uip_clear_buf(); uip_slen = 0; UIP_APPCALL(); goto appsend; @@ -1934,7 +1934,7 @@ uip_process(uint8_t flag) return; drop: - uip_len = 0; + uip_clear_buf(); uip_flags = 0; return; } diff --git a/core/net/ipv4/uip_arp.c b/core/net/ipv4/uip_arp.c index 5abad8b40..10015295e 100644 --- a/core/net/ipv4/uip_arp.c +++ b/core/net/ipv4/uip_arp.c @@ -284,10 +284,10 @@ uip_arp_arpin(void) { if(uip_len < sizeof(struct arp_hdr)) { - uip_len = 0; + uip_clear_buf(); return; } - uip_len = 0; + uip_clear_buf(); switch(BUF->opcode) { case UIP_HTONS(ARP_REQUEST): diff --git a/core/net/ipv6/multicast/roll-tm.c b/core/net/ipv6/multicast/roll-tm.c index 20a562084..432a4cde0 100644 --- a/core/net/ipv6/multicast/roll-tm.c +++ b/core/net/ipv6/multicast/roll-tm.c @@ -1380,8 +1380,7 @@ out() drop: uip_slen = 0; - uip_len = 0; - uip_ext_len = 0; + uip_clear_buf(); } /*---------------------------------------------------------------------------*/ static uint8_t diff --git a/core/net/ipv6/multicast/smrf.c b/core/net/ipv6/multicast/smrf.c index b1dccbd19..d62547ef6 100644 --- a/core/net/ipv6/multicast/smrf.c +++ b/core/net/ipv6/multicast/smrf.c @@ -81,7 +81,7 @@ mcast_fwd(void *p) uip_len = mcast_len; UIP_IP_BUF->ttl--; tcpip_output(NULL); - uip_len = 0; + uip_clear_buf(); } /*---------------------------------------------------------------------------*/ static uint8_t diff --git a/core/net/ipv6/uip-icmp6.c b/core/net/ipv6/uip-icmp6.c index ee8d94c77..a9dc9e352 100644 --- a/core/net/ipv6/uip-icmp6.c +++ b/core/net/ipv6/uip-icmp6.c @@ -210,12 +210,12 @@ uip_icmp6_error_output(uint8_t type, uint8_t code, uint32_t param) { /* check if originating packet is not an ICMP error*/ if (uip_ext_len) { if(UIP_EXT_BUF->next == UIP_PROTO_ICMP6 && UIP_ICMP_BUF->type < 128){ - uip_len = 0; + uip_clear_buf(); return; } } else { if(UIP_IP_BUF->proto == UIP_PROTO_ICMP6 && UIP_ICMP_BUF->type < 128){ - uip_len = 0; + uip_clear_buf(); return; } } @@ -250,7 +250,7 @@ uip_icmp6_error_output(uint8_t type, uint8_t code, uint32_t param) { /* the source should not be unspecified nor multicast, the check for multicast is done in uip_process */ if(uip_is_addr_unspecified(&UIP_IP_BUF->srcipaddr)){ - uip_len = 0; + uip_clear_buf(); return; } @@ -260,7 +260,7 @@ uip_icmp6_error_output(uint8_t type, uint8_t code, uint32_t param) { if(type == ICMP6_PARAM_PROB && code == ICMP6_PARAMPROB_OPTION){ uip_ds6_select_src(&UIP_IP_BUF->srcipaddr, &tmp_ipaddr); } else { - uip_len = 0; + uip_clear_buf(); return; } } else { @@ -385,7 +385,7 @@ echo_reply_input(void) } } - uip_len = 0; + uip_clear_buf(); return; } /*---------------------------------------------------------------------------*/ diff --git a/core/net/ipv6/uip-nd6.c b/core/net/ipv6/uip-nd6.c index 72b1badfa..331e1fae3 100644 --- a/core/net/ipv6/uip-nd6.c +++ b/core/net/ipv6/uip-nd6.c @@ -321,7 +321,7 @@ create_na: return; discard: - uip_len = 0; + uip_clear_buf(); return; } #endif /* UIP_ND6_SEND_NA */ @@ -360,7 +360,7 @@ uip_nd6_ns_output(uip_ipaddr_t * src, uip_ipaddr_t * dest, uip_ipaddr_t * tgt) } if (uip_is_addr_unspecified(&UIP_IP_BUF->srcipaddr)) { PRINTF("Dropping NS due to no suitable source address\n"); - uip_len = 0; + uip_clear_buf(); return; } UIP_IP_BUF->len[1] = @@ -557,7 +557,7 @@ na_input(void) #endif /*UIP_CONF_IPV6_QUEUE_PKT */ discard: - uip_len = 0; + uip_clear_buf(); return; } #endif /* UIP_ND6_SEND_NA */ @@ -646,7 +646,7 @@ rs_input(void) uip_ds6_send_ra_sollicited(); discard: - uip_len = 0; + uip_clear_buf(); return; } @@ -1029,7 +1029,7 @@ ra_input(void) #endif /*UIP_CONF_IPV6_QUEUE_PKT */ discard: - uip_len = 0; + uip_clear_buf(); return; } #endif /* !UIP_CONF_ROUTER */ diff --git a/core/net/ipv6/uip6.c b/core/net/ipv6/uip6.c index 73abd1115..416edf813 100644 --- a/core/net/ipv6/uip6.c +++ b/core/net/ipv6/uip6.c @@ -538,8 +538,7 @@ remove_ext_hdr(void) uip_ext_len, uip_len); if(uip_len < UIP_IPH_LEN + uip_ext_len) { PRINTF("ERROR: uip_len too short compared to ext len\n"); - uip_ext_len = 0; - uip_len = 0; + uip_clear_buf(); return; } memmove(((uint8_t *)UIP_TCP_BUF), (uint8_t *)UIP_TCP_BUF + uip_ext_len, @@ -825,8 +824,7 @@ uip_reass_over(void) * any RFC, we decided not to include it as it reduces the size of * the packet. */ - uip_len = 0; - uip_ext_len = 0; + uip_clear_buf(); memcpy(UIP_IP_BUF, FBUF, UIP_IPH_LEN); /* copy the header for src and dest address*/ uip_icmp6_error_output(ICMP6_TIME_EXCEEDED, ICMP6_TIME_EXCEED_REASSEMBLY, 0); @@ -971,7 +969,7 @@ uip_process(uint8_t flag) } else if(flag == UIP_TIMER) { /* Reset the length variables. */ #if UIP_TCP - uip_len = 0; + uip_clear_buf(); uip_slen = 0; /* Increase the initial sequence number. */ @@ -1456,7 +1454,7 @@ uip_process(uint8_t flag) UIP_STAT(++uip_stat.icmp.drop); UIP_STAT(++uip_stat.icmp.typeerr); UIP_LOG("icmp6: unknown ICMPv6 message."); - uip_len = 0; + uip_clear_buf(); } if(uip_len > 0) { @@ -1978,7 +1976,7 @@ uip_process(uint8_t flag) uip_add_rcv_nxt(1); uip_flags = UIP_CONNECTED | UIP_NEWDATA; uip_connr->len = 0; - uip_len = 0; + uip_clear_buf(); uip_slen = 0; UIP_APPCALL(); goto appsend; @@ -2310,8 +2308,7 @@ uip_process(uint8_t flag) return; drop: - uip_len = 0; - uip_ext_len = 0; + uip_clear_buf(); uip_ext_bitmap = 0; uip_flags = 0; return; diff --git a/core/net/rpl/rpl-icmp6.c b/core/net/rpl/rpl-icmp6.c index 66e311d51..880b7986c 100644 --- a/core/net/rpl/rpl-icmp6.c +++ b/core/net/rpl/rpl-icmp6.c @@ -175,7 +175,7 @@ dis_input(void) } } } - uip_len = 0; + uip_clear_buf(); } /*---------------------------------------------------------------------------*/ void @@ -418,7 +418,7 @@ dio_input(void) rpl_process_dio(&from, &dio); - uip_len = 0; + uip_clear_buf(); } /*---------------------------------------------------------------------------*/ void @@ -801,7 +801,7 @@ fwd_dao: dao_ack_output(instance, &dao_sender_addr, sequence); } } - uip_len = 0; + uip_clear_buf(); } /*---------------------------------------------------------------------------*/ void @@ -931,7 +931,7 @@ dao_ack_input(void) PRINT6ADDR(&UIP_IP_BUF->srcipaddr); PRINTF("\n"); #endif /* DEBUG */ - uip_len = 0; + uip_clear_buf(); } /*---------------------------------------------------------------------------*/ void diff --git a/cpu/native/net/tapdev-drv.c b/cpu/native/net/tapdev-drv.c index 8a7aeed53..d2d4a1ac0 100644 --- a/cpu/native/net/tapdev-drv.c +++ b/cpu/native/net/tapdev-drv.c @@ -83,7 +83,7 @@ pollhandler(void) } #endif } else { - uip_len = 0; + uip_clear_buf(); } } } diff --git a/cpu/native/net/wpcap-drv.c b/cpu/native/net/wpcap-drv.c index 0b3cf926a..7ff8457b6 100644 --- a/cpu/native/net/wpcap-drv.c +++ b/cpu/native/net/wpcap-drv.c @@ -103,7 +103,7 @@ pollhandler(void) } #endif /* !NETSTACK_CONF_WITH_IPV6 */ } else { - uip_len = 0; + uip_clear_buf(); } } #endif @@ -146,7 +146,7 @@ pollhandler(void) #endif /* !NETSTACK_CONF_WITH_IPV6 */ } else { bail: - uip_len = 0; + uip_clear_buf(); } } #endif diff --git a/examples/cc2530dk/border-router/border-router.c b/examples/cc2530dk/border-router/border-router.c index 0df514474..843632b23 100644 --- a/examples/cc2530dk/border-router/border-router.c +++ b/examples/cc2530dk/border-router/border-router.c @@ -90,7 +90,7 @@ request_prefix(void) CC_NON_BANKED uip_buf[1] = 'P'; uip_len = 2; slip_send(); - uip_len = 0; + uip_clear_buf(); } /*---------------------------------------------------------------------------*/ /* Set our prefix when we receive one over SLIP */ diff --git a/examples/cc2530dk/border-router/slip-bridge.c b/examples/cc2530dk/border-router/slip-bridge.c index 98aee3bf9..30bd4a429 100644 --- a/examples/cc2530dk/border-router/slip-bridge.c +++ b/examples/cc2530dk/border-router/slip-bridge.c @@ -59,7 +59,7 @@ slip_input_callback(void) PRINTF("SIN: %u\n", uip_len); if((char)uip_buf[0] == '!') { PRINTF("Got configuration message of type %c\n", uip_buf[1]); - uip_len = 0; + uip_clear_buf(); if((char)uip_buf[1] == 'P') { uip_ipaddr_t prefix; /* Here we set a prefix !!! */ diff --git a/examples/ipv6/rpl-border-router/border-router.c b/examples/ipv6/rpl-border-router/border-router.c index 106107ccb..84943e68f 100644 --- a/examples/ipv6/rpl-border-router/border-router.c +++ b/examples/ipv6/rpl-border-router/border-router.c @@ -311,7 +311,7 @@ request_prefix(void) uip_buf[1] = 'P'; uip_len = 2; slip_send(); - uip_len = 0; + uip_clear_buf(); } /*---------------------------------------------------------------------------*/ void diff --git a/examples/ipv6/rpl-border-router/slip-bridge.c b/examples/ipv6/rpl-border-router/slip-bridge.c index 52b4a4060..582f626e7 100644 --- a/examples/ipv6/rpl-border-router/slip-bridge.c +++ b/examples/ipv6/rpl-border-router/slip-bridge.c @@ -59,7 +59,7 @@ slip_input_callback(void) // PRINTF("SIN: %u\n", uip_len); if(uip_buf[0] == '!') { PRINTF("Got configuration message of type %c\n", uip_buf[1]); - uip_len = 0; + uip_clear_buf(); if(uip_buf[1] == 'P') { uip_ipaddr_t prefix; /* Here we set a prefix !!! */ @@ -85,7 +85,7 @@ slip_input_callback(void) slip_send(); } - uip_len = 0; + uip_clear_buf(); } /* Save the last sender received over SLIP to avoid bouncing the packet back if no route is found */ diff --git a/examples/ipv6/slip-radio/slip-radio.c b/examples/ipv6/slip-radio/slip-radio.c index 255cfefb5..b20e559ec 100644 --- a/examples/ipv6/slip-radio/slip-radio.c +++ b/examples/ipv6/slip-radio/slip-radio.c @@ -162,7 +162,7 @@ slip_input_callback(void) { PRINTF("SR-SIN: %u '%c%c'\n", uip_len, uip_buf[0], uip_buf[1]); cmd_input(uip_buf, uip_len); - uip_len = 0; + uip_clear_buf(); } /*---------------------------------------------------------------------------*/ static void diff --git a/examples/sensinode/border-router/border-router.c b/examples/sensinode/border-router/border-router.c index 028a2f770..9442c9e03 100644 --- a/examples/sensinode/border-router/border-router.c +++ b/examples/sensinode/border-router/border-router.c @@ -90,7 +90,7 @@ request_prefix(void) CC_NON_BANKED uip_buf[1] = 'P'; uip_len = 2; slip_send(); - uip_len = 0; + uip_clear_buf(); } /*---------------------------------------------------------------------------*/ /* Set our prefix when we receive one over SLIP */ diff --git a/examples/sensinode/border-router/slip-bridge.c b/examples/sensinode/border-router/slip-bridge.c index fc9f95a28..edd048a7d 100644 --- a/examples/sensinode/border-router/slip-bridge.c +++ b/examples/sensinode/border-router/slip-bridge.c @@ -60,7 +60,7 @@ slip_input_callback(void) PRINTF("SIN: %u\n", uip_len); if((char)uip_buf[0] == '!') { PRINTF("Got configuration message of type %c\n", uip_buf[1]); - uip_len = 0; + uip_clear_buf(); if((char)uip_buf[1] == 'P') { uip_ipaddr_t prefix; /* Here we set a prefix !!! */ diff --git a/platform/avr-ravenusb/sicslow_ethernet.c b/platform/avr-ravenusb/sicslow_ethernet.c index 46b9244cc..5f70928ba 100644 --- a/platform/avr-ravenusb/sicslow_ethernet.c +++ b/platform/avr-ravenusb/sicslow_ethernet.c @@ -342,7 +342,7 @@ void mac_ethernetToLowpan(uint8_t * ethHeader) /* In sniffer or sneezr mode we don't ever send anything */ if ((usbstick_mode.sendToRf == 0) || (usbstick_mode.sneeze != 0)) { - uip_len = 0; + uip_clear_buf(); return; } @@ -354,7 +354,7 @@ void mac_ethernetToLowpan(uint8_t * ethHeader) #if !RF230BB usb_eth_stat.txbad++; #endif - uip_len = 0; + uip_clear_buf(); return; } @@ -375,7 +375,7 @@ void mac_ethernetToLowpan(uint8_t * ethHeader) #if !RF230BB usb_eth_stat.txbad++; #endif - uip_len = 0; + uip_clear_buf(); return; } else { @@ -409,7 +409,7 @@ void mac_ethernetToLowpan(uint8_t * ethHeader) #if UIP_CONF_SIMPLE_JACKDAW_ADDR_TRANS else { //Not addressed to us - uip_len = 0; + uip_clear_buf(); return; } #else @@ -422,7 +422,7 @@ void mac_ethernetToLowpan(uint8_t * ethHeader) #if !RF230BB usb_eth_stat.txbad++; #endif - uip_len = 0; + uip_clear_buf(); return; } PRINTF(" translated OK\n\r"); @@ -463,7 +463,7 @@ void mac_ethernetToLowpan(uint8_t * ethHeader) #if !RF230BB usb_eth_stat.txok++; #endif - uip_len = 0; + uip_clear_buf(); } @@ -543,7 +543,7 @@ void mac_LowpanToEthernet(void) #if !RF230BB usb_eth_stat.rxok++; #endif - uip_len = 0; + uip_clear_buf(); } /** diff --git a/tools/cc2538-bsl b/tools/cc2538-bsl index d6711e24c..1223bfe03 160000 --- a/tools/cc2538-bsl +++ b/tools/cc2538-bsl @@ -1 +1 @@ -Subproject commit d6711e24ceeb1de09421166a3dc1b97378648af5 +Subproject commit 1223bfe03cdb31c439f1a51593808cdabc1939d2 diff --git a/tools/sky/uip6-bridge/dev/slip.c b/tools/sky/uip6-bridge/dev/slip.c index 42d6760b1..4cb65cfd5 100644 --- a/tools/sky/uip6-bridge/dev/slip.c +++ b/tools/sky/uip6-bridge/dev/slip.c @@ -294,7 +294,7 @@ PROCESS_THREAD(slip_process, ev, data) tcpip_input(); } } else { - uip_len = 0; + uip_clear_buf(); SLIP_STATISTICS(slip_ip_drop++); } #else /* NETSTACK_CONF_WITH_IPV6 */ diff --git a/tools/sky/uip6-bridge/sicslow_ethernet.c b/tools/sky/uip6-bridge/sicslow_ethernet.c index a74415020..7de0694c3 100644 --- a/tools/sky/uip6-bridge/sicslow_ethernet.c +++ b/tools/sky/uip6-bridge/sicslow_ethernet.c @@ -238,13 +238,13 @@ void mac_ethernetToLowpan(uint8_t * ethHeader) if (((struct uip_eth_hdr *) ethHeader)->type != UIP_HTONS(UIP_ETHTYPE_IPV6)) { PRINTF("eth2low: Packet is not IPv6, dropping\n"); /* rndis_stat.txbad++; */ - uip_len = 0; + uip_clear_buf(); return; } // In sniffer mode we don't ever send anything if (usbstick_mode.sendToRf == 0) { - uip_len = 0; + uip_clear_buf(); return; } @@ -263,7 +263,7 @@ void mac_ethernetToLowpan(uint8_t * ethHeader) /* IPv6 does not use broadcast addresses, hence this should not happen */ PRINTF("eth2low: Ethernet broadcast address received, should not happen?\n"); /* rndis_stat.txbad++; */ - uip_len = 0; + uip_clear_buf(); return; } else { PRINTF("eth2low: Addressed packet received... "); @@ -271,7 +271,7 @@ void mac_ethernetToLowpan(uint8_t * ethHeader) if (mac_createSicslowpanLongAddr( &(((struct uip_eth_hdr *) ethHeader)->dest.addr[0]), &destAddr) == 0) { PRINTF(" translation failed\n"); /* rndis_stat.txbad++; */ - uip_len = 0; + uip_clear_buf(); return; } PRINTF(" translated OK\n"); @@ -295,7 +295,7 @@ void mac_ethernetToLowpan(uint8_t * ethHeader) } } - uip_len = 0; + uip_clear_buf(); } @@ -343,7 +343,7 @@ void mac_LowpanToEthernet(void) /* rndis_send(uip_buf, uip_len, 1); */ /* rndis_stat.rxok++; */ -/* uip_len = 0; */ +/* uip_clear_buf(); */ } /** diff --git a/tools/sky/uip6-bridge/uip6-bridge-tap.c b/tools/sky/uip6-bridge/uip6-bridge-tap.c index f1c5a0256..9aabd752f 100644 --- a/tools/sky/uip6-bridge/uip6-bridge-tap.c +++ b/tools/sky/uip6-bridge/uip6-bridge-tap.c @@ -95,7 +95,7 @@ tcpip_input(void) packetbuf_attr(PACKETBUF_ATTR_LISTEN_TIME));*/ slip_write(uip_buf, uip_len); leds_toggle(LEDS_RED); - uip_len = 0; + uip_clear_buf(); } } } diff --git a/tools/stm32w/uip6_bridge/dev/slip.c b/tools/stm32w/uip6_bridge/dev/slip.c index 1380160d1..543896266 100644 --- a/tools/stm32w/uip6_bridge/dev/slip.c +++ b/tools/stm32w/uip6_bridge/dev/slip.c @@ -370,7 +370,7 @@ PROCESS_THREAD(slip_process, ev, data) tcpip_input(); } } else { - uip_len = 0; + uip_clear_buf(); SLIP_STATISTICS(slip_ip_drop++); } #else /* NETSTACK_CONF_WITH_IPV6 */ diff --git a/tools/stm32w/uip6_bridge/sicslow_ethernet.c b/tools/stm32w/uip6_bridge/sicslow_ethernet.c index 440ed9504..24c2b648c 100644 --- a/tools/stm32w/uip6_bridge/sicslow_ethernet.c +++ b/tools/stm32w/uip6_bridge/sicslow_ethernet.c @@ -267,13 +267,13 @@ void mac_ethernetToLowpan(uint8_t * ethHeader) if (((struct uip_eth_hdr *) ethHeader)->type != UIP_HTONS(UIP_ETHTYPE_IPV6)) { PRINTF("eth2low: Packet is not IPv6, dropping\n"); /* rndis_stat.txbad++; */ - uip_len = 0; + uip_clear_buf(); return; } // In sniffer mode we don't ever send anything if (usbstick_mode.sendToRf == 0) { - uip_len = 0; + uip_clear_buf(); return; } @@ -292,7 +292,7 @@ void mac_ethernetToLowpan(uint8_t * ethHeader) /* IPv6 does not use broadcast addresses, hence this should not happen */ PRINTF("eth2low: Ethernet broadcast address received, should not happen?\n"); /* rndis_stat.txbad++; */ - uip_len = 0; + uip_clear_buf(); return; } else { PRINTF("eth2low: Addressed packet received... "); @@ -300,7 +300,7 @@ void mac_ethernetToLowpan(uint8_t * ethHeader) if (mac_createSicslowpanLongAddr( &(((struct uip_eth_hdr *) ethHeader)->dest.addr[0]), &destAddr) == 0) { PRINTF(" translation failed\n"); /* rndis_stat.txbad++; */ - uip_len = 0; + uip_clear_buf(); return; } PRINTF(" translated OK\n"); @@ -322,7 +322,7 @@ void mac_ethernetToLowpan(uint8_t * ethHeader) /* rndis_stat.txok++; */ } - uip_len = 0; + uip_clear_buf(); } @@ -370,7 +370,7 @@ void mac_LowpanToEthernet(void) /* rndis_send(uip_buf, uip_len, 1); */ /* rndis_stat.rxok++; */ -/* uip_len = 0; */ +/* uip_clear_buf(); */ } /** diff --git a/tools/stm32w/uip6_bridge/uip6-bridge-tap.c b/tools/stm32w/uip6_bridge/uip6-bridge-tap.c index 6fea42db2..307d8ea4e 100644 --- a/tools/stm32w/uip6_bridge/uip6-bridge-tap.c +++ b/tools/stm32w/uip6_bridge/uip6-bridge-tap.c @@ -98,7 +98,7 @@ tcpip_input(void) packetbuf_attr(PACKETBUF_ATTR_TRANSMIT_TIME), packetbuf_attr(PACKETBUF_ATTR_LISTEN_TIME));*/ slip_write(uip_buf, uip_len); - uip_len = 0; + uip_clear_buf(); leds_off(LEDS_RED); } } From db4df3036615f94819c39c5a204809ffb63a1626 Mon Sep 17 00:00:00 2001 From: Sumankumar Panchal Date: Thu, 7 May 2015 22:47:41 +0530 Subject: [PATCH 023/120] Added MSP430X ELFLOADER support to load image with large memory model. --- apps/codeprop/Makefile.codeprop-tmp | 10 + core/loader/elfloader-msp430x.c | 810 ++++++++++++++++++++++++++++ cpu/msp430/Makefile.msp430 | 12 +- 3 files changed, 831 insertions(+), 1 deletion(-) create mode 100644 apps/codeprop/Makefile.codeprop-tmp create mode 100644 core/loader/elfloader-msp430x.c diff --git a/apps/codeprop/Makefile.codeprop-tmp b/apps/codeprop/Makefile.codeprop-tmp new file mode 100644 index 000000000..e725df070 --- /dev/null +++ b/apps/codeprop/Makefile.codeprop-tmp @@ -0,0 +1,10 @@ +codeprop-tmp_src = codeprop-tmp.c + +# Enable LARGE MEMORY MODEL supports for WISMOTE and EXP5438 platform +ifeq ($(TARGET),wismote) + TARGET_MEMORY_MODEL = large +endif + +ifeq ($(TARGET),exp5438) + TARGET_MEMORY_MODEL = large +endif diff --git a/core/loader/elfloader-msp430x.c b/core/loader/elfloader-msp430x.c new file mode 100644 index 000000000..32e1126f3 --- /dev/null +++ b/core/loader/elfloader-msp430x.c @@ -0,0 +1,810 @@ +/* + * Copyright (c) 2015, Indian Institute of Science + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the Institute nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * This file is part of the Contiki operating system. + * + */ + +/** + * \file + * MSP430x elfloader. + * \author + * Sumankumar Panchal + * + */ + +#include "contiki.h" +#include "loader/elfloader.h" +#include "loader/elfloader-arch.h" +#include "cfs/cfs.h" +#include "loader/symtab.h" +#include +#include +#include +#include "dev/flash.h" + +#define DEBUG 0 +#if DEBUG +#include +#define PRINTF(...) printf(__VA_ARGS__) +#else +#define PRINTF(...) do {} while(0) +#endif + +#define EI_NIDENT 16 + +struct elf32_ehdr { + unsigned char e_ident[EI_NIDENT]; /* ident bytes */ + elf32_half e_type; /* file type */ + elf32_half e_machine; /* target machine */ + elf32_word e_version; /* file version */ + elf32_addr e_entry; /* start address */ + elf32_off e_phoff; /* phdr file offset */ + elf32_off e_shoff; /* shdr file offset */ + elf32_word e_flags; /* file flags */ + elf32_half e_ehsize; /* sizeof ehdr */ + elf32_half e_phentsize; /* sizeof phdr */ + elf32_half e_phnum; /* number phdrs */ + elf32_half e_shentsize; /* sizeof shdr */ + elf32_half e_shnum; /* number shdrs */ + elf32_half e_shstrndx; /* shdr string index */ +}; + +/* Values for e_type. */ +#define ET_NONE 0 /* Unknown type. */ +#define ET_REL 1 /* Relocatable. */ +#define ET_EXEC 2 /* Executable. */ +#define ET_DYN 3 /* Shared object. */ +#define ET_CORE 4 /* Core file. */ + +struct elf32_shdr { + elf32_word sh_name; /* section name */ + elf32_word sh_type; /* SHT_... */ + elf32_word sh_flags; /* SHF_... */ + elf32_addr sh_addr; /* virtual address */ + elf32_off sh_offset; /* file offset */ + elf32_word sh_size; /* section size */ + elf32_word sh_link; /* misc info */ + elf32_word sh_info; /* misc info */ + elf32_word sh_addralign; /* memory alignment */ + elf32_word sh_entsize; /* entry size if table */ +}; + +/* sh_type */ +#define SHT_NULL 0 /* inactive */ +#define SHT_PROGBITS 1 /* program defined information */ +#define SHT_SYMTAB 2 /* symbol table section */ +#define SHT_STRTAB 3 /* string table section */ +#define SHT_RELA 4 /* relocation section with addends*/ +#define SHT_HASH 5 /* symbol hash table section */ +#define SHT_DYNAMIC 6 /* dynamic section */ +#define SHT_NOTE 7 /* note section */ +#define SHT_NOBITS 8 /* no space section */ +#define SHT_REL 9 /* relation section without addends */ +#define SHT_SHLIB 10 /* reserved - purpose unknown */ +#define SHT_DYNSYM 11 /* dynamic symbol table section */ +#define SHT_LOPROC 0x70000000 /* reserved range for processor */ +#define SHT_HIPROC 0x7fffffff /* specific section header types */ +#define SHT_LOUSER 0x80000000 /* reserved range for application */ +#define SHT_HIUSER 0xffffffff /* specific indexes */ + +struct elf32_rel { + elf32_addr r_offset; /* Location to be relocated. */ + elf32_word r_info; /* Relocation type and symbol index. */ +}; + +struct elf32_sym { + elf32_word st_name; /* String table index of name. */ + elf32_addr st_value; /* Symbol value. */ + elf32_word st_size; /* Size of associated object. */ + unsigned char st_info; /* Type and binding information. */ + unsigned char st_other; /* Reserved (not used). */ + elf32_half st_shndx; /* Section index of symbol. */ +}; + +#define ELF32_R_SYM(info) ((info) >> 8) + +struct relevant_section { + unsigned char number; + unsigned int offset; + char *address; +}; + +char elfloader_unknown[30]; /* Name that caused link error. */ + +struct process *const *elfloader_autostart_processes; + +static struct relevant_section bss, data, rodata, rodatafar, text, textfar; + +static const unsigned char elf_magic_header[] = +{ 0x7f, 0x45, 0x4c, 0x46, /* 0x7f, 'E', 'L', 'F' */ + 0x01, /* Only 32-bit objects. */ + 0x01, /* Only LSB data. */ + 0x01, /* Only ELF version 1. */ +}; + +/* relocation type */ +#define R_MSP430_NONE 0 +#define R_MSP430_32 1 +#define R_MSP430_10_PCREL 2 +#define R_MSP430_16 3 +#define R_MSP430_16_PCREL 4 +#define R_MSP430_16_BYTE 5 +#define R_MSP430_16_PCREL_BYTE 6 +#define R_MSP430_2X_PCREL 7 +#define R_MSP430_RL_PCREL 8 +#define R_MSP430X_SRC_BYTE 9 +#define R_MSP430X_SRC 10 +#define R_MSP430X_DST_BYTE 11 +#define R_MSP430X_DST 12 +#define R_MSP430X_DST_2ND_BYTE 13 +#define R_MSP430X_DST_2ND 14 +#define R_MSP430X_PCREL_SRC_BYTE 15 +#define R_MSP430X_PCREL_SRC 16 +#define R_MSP430X_PCREL_DST_BYTE 17 +#define R_MSP430X_PCREL_DST 18 +#define R_MSP430X_PCREL_DST_2ND 19 +#define R_MSP430X_PCREL_DST_2ND_BYTE 20 +#define R_MSP430X_S_BYTE 21 +#define R_MSP430X_S 22 +#define R_MSP430X_D_BYTE 23 +#define R_MSP430X_D 24 +#define R_MSP430X_PCREL_D 25 +#define R_MSP430X_INDXD 26 +#define R_MSP430X_PCREL_INDXD 27 +#define R_MSP430_10 28 + +#define ELF32_R_TYPE(info) ((unsigned char)(info)) + +static uint16_t datamemory_aligned[ELFLOADER_DATAMEMORY_SIZE / 2 + 1]; +static uint8_t *datamemory = (uint8_t *)datamemory_aligned; +#if ELFLOADER_CONF_TEXT_IN_ROM +static const char textmemory[ELFLOADER_TEXTMEMORY_SIZE] = { 0 }; +#else /* ELFLOADER_CONF_TEXT_IN_ROM */ +static char textmemory[ELFLOADER_TEXTMEMORY_SIZE]; +#endif /* ELFLOADER_CONF_TEXT_IN_ROM */ + +/*---------------------------------------------------------------------------*/ +static void +seek_read(int fd, unsigned int offset, char *buf, int len) +{ + cfs_seek(fd, offset, CFS_SEEK_SET); + cfs_read(fd, buf, len); +#if DEBUG + { + int i; + PRINTF("seek_read: Read len %d from offset %d\n", + len, offset); + for(i = 0; i < len; ++i) { + PRINTF("%02x ", buf[i]); + } + printf("\n"); + } +#endif /* DEBUG */ +} +/*---------------------------------------------------------------------------*/ +static void * +find_local_symbol(int fd, const char *symbol, + unsigned int symtab, unsigned short symtabsize, + unsigned int strtab) +{ + struct elf32_sym s; + unsigned int a; + char name[30]; + struct relevant_section *sect; + + for(a = symtab; a < symtab + symtabsize; a += sizeof(s)) { + seek_read(fd, a, (char *)&s, sizeof(s)); + if(s.st_name != 0) { + seek_read(fd, strtab + s.st_name, name, sizeof(name)); + if(strcmp(name, symbol) == 0) { + if(s.st_shndx == bss.number) { + sect = &bss; + } else if(s.st_shndx == data.number) { + sect = &data; + } else if(s.st_shndx == rodatafar.number) { + sect = &rodatafar; + } else if(s.st_shndx == textfar.number) { + sect = &textfar; + } else { + return NULL; + } + return &(sect->address[s.st_value]); + } + } + } + return NULL; +} +/*---------------------------------------------------------------------------*/ +static int +relocate_section(int fd, + unsigned int section, unsigned short size, + unsigned int sectionaddr, + char *sectionbase, + unsigned int strs, + unsigned int strtab, + unsigned int symtab, unsigned short symtabsize, + unsigned char using_relas) +{ + /* + * sectionbase added; runtime start address of current section + */ + struct elf32_rela rela; /* Now used both for rel and rela data! */ + int rel_size = 0; + struct elf32_sym s; + unsigned int a; + char name[30]; + char *addr; + struct relevant_section *sect; + + /* determine correct relocation entry sizes */ + if(using_relas) { + rel_size = sizeof(struct elf32_rela); + } else { + rel_size = sizeof(struct elf32_rel); + } + + for(a = section; a < section + size; a += rel_size) { + seek_read(fd, a, (char *)&rela, rel_size); + seek_read(fd, + symtab + sizeof(struct elf32_sym) * ELF32_R_SYM(rela.r_info), + (char *)&s, sizeof(s)); + if(s.st_name != 0) { + seek_read(fd, strtab + s.st_name, name, sizeof(name)); + PRINTF("name: %s\n", name); + addr = (char *)symtab_lookup(name); + if(addr == NULL) { + PRINTF("name not found in global: %s\n", name); + addr = find_local_symbol(fd, name, symtab, symtabsize, strtab); + PRINTF("found address %p\n", addr); + } + if(addr == NULL) { + if(s.st_shndx == bss.number) { + sect = &bss; + } else if(s.st_shndx == data.number) { + sect = &data; + } else if(s.st_shndx == rodatafar.number) { + sect = &rodatafar; + } else if(s.st_shndx == textfar.number) { + sect = &textfar; + } else { + PRINTF("elfloader unknown name: '%30s'\n", name); + memcpy(elfloader_unknown, name, sizeof(elfloader_unknown)); + elfloader_unknown[sizeof(elfloader_unknown) - 1] = 0; + return ELFLOADER_SYMBOL_NOT_FOUND; + } + + addr = sect->address; + } + } else { + if(s.st_shndx == bss.number) { + sect = &bss; + } else if(s.st_shndx == data.number) { + sect = &data; + } else if(s.st_shndx == rodatafar.number) { + sect = &rodatafar; + } else if(s.st_shndx == textfar.number) { + sect = &textfar; + } else { + return ELFLOADER_SEGMENT_NOT_FOUND; + } + + addr = sect->address; + } + + if(!using_relas) { + /* copy addend to rela structure */ + seek_read(fd, sectionaddr + rela.r_offset, (char *)&rela.r_addend, 4); + } + + elfloader_arch_relocate(fd, sectionaddr, sectionbase, &rela, addr); + } + + return ELFLOADER_OK; +} +/*---------------------------------------------------------------------------*/ +static void * +find_program_processes(int fd, + unsigned int symtab, unsigned short size, + unsigned int strtab) +{ + struct elf32_sym s; + unsigned int a; + char name[30]; + + for(a = symtab; a < symtab + size; a += sizeof(s)) { + seek_read(fd, a, (char *)&s, sizeof(s)); + + if(s.st_name != 0) { + seek_read(fd, strtab + s.st_name, name, sizeof(name)); + if(strcmp(name, "autostart_processes") == 0) { + return &data.address[s.st_value]; + } + } + } + return NULL; +} +/*---------------------------------------------------------------------------*/ +void +elfloader_init(void) +{ + elfloader_autostart_processes = NULL; +} +/*---------------------------------------------------------------------------*/ +int +elfloader_load(int fd) +{ + struct elf32_ehdr ehdr; + struct elf32_shdr shdr; + struct elf32_shdr strtable; + unsigned int strs; + unsigned int shdrptr; + unsigned int nameptr; + char name[17]; + + int i; + unsigned short shdrnum, shdrsize; + + unsigned char using_relas = -1; + unsigned short textoff = 0, textfaroff = 0, textsize, textfarsize, + textrelaoff = 0, textrelasize, textfarrelaoff = 0, textfarrelasize; + unsigned short dataoff = 0, datasize, datarelaoff = 0, datarelasize; + unsigned short rodataoff = 0, rodatafaroff = 0, rodatasize, rodatafarsize, + rodatarelaoff = 0, rodatarelasize, rodatafarrelaoff = 0, + rodatafarrelasize; + unsigned short symtaboff = 0, symtabsize; + unsigned short strtaboff = 0, strtabsize; + unsigned short bsssize = 0; + + struct process **process; + int ret; + + elfloader_unknown[0] = 0; + + /* The ELF header is located at the start of the buffer. */ + seek_read(fd, 0, (char *)&ehdr, sizeof(ehdr)); + + /* Make sure that we have a correct and compatible ELF header. */ + if(memcmp(ehdr.e_ident, elf_magic_header, sizeof(elf_magic_header)) != 0) { + PRINTF("ELF header problems\n"); + return ELFLOADER_BAD_ELF_HEADER; + } + + /* Grab the section header. */ + shdrptr = ehdr.e_shoff; + seek_read(fd, shdrptr, (char *)&shdr, sizeof(shdr)); + + /* Get the size and number of entries of the section header. */ + shdrsize = ehdr.e_shentsize; + shdrnum = ehdr.e_shnum; + + PRINTF("Section header: size %d num %d\n", shdrsize, shdrnum); + + /* The string table section: holds the names of the sections. */ + seek_read(fd, ehdr.e_shoff + shdrsize * ehdr.e_shstrndx, + (char *)&strtable, sizeof(strtable)); + + /* + * Get a pointer to the actual table of strings. This table holds + * the names of the sections, not the names of other symbols in the + * file (these are in the sybtam section). + */ + strs = strtable.sh_offset; + + PRINTF("Strtable offset %d\n", strs); + + /* + * Go through all sections and pick out the relevant ones. The + * ".text" and ".far.text" segments holds the actual code from + * the ELF file. The ".data" segment contains initialized data. + * The ".bss" segment holds the size of the unitialized data segment. + * The ".rodata" and ".far.rodata" segments contains constant data. + * The ".rela[a].text" and ".rela[a].far.text" segments contains + * relocation information for the contents of the ".text" and + * ".far.text" segments, respectively. The ".rela[a].rodata" and + * ".rela[a].far.rodata" segments contains relocation information + * for the contents of the ".rodata" and ".far.rodata" segments, + * respectively. The ".rela[a].data" segment contains relocation + * information for the contents of the ".data" segment. The ".symtab" + * segment contains the symbol table for this file. The ".strtab" + * segment points to the actual string names used by the symbol table. + * + * In addition to grabbing pointers to the relevant sections, we + * also save the section number for resolving addresses in the + * relocator code. + */ + + /* + * Initialize the segment sizes to zero so that we can check if + * their sections was found in the file or not. + */ + textsize = textfarsize = textrelasize = textfarrelasize = + datasize = datarelasize = rodatasize = rodatafarsize = + rodatarelasize = rodatafarrelasize = symtabsize = strtabsize = 0; + + bss.number = data.number = rodata.number = rodatafar.number = + text.number = textfar.number = -1; + + shdrptr = ehdr.e_shoff; + for(i = 0; i < shdrnum; ++i) { + seek_read(fd, shdrptr, (char *)&shdr, sizeof(shdr)); + + /* The name of the section is contained in the strings table. */ + nameptr = strs + shdr.sh_name; + seek_read(fd, nameptr, name, sizeof(name)); + PRINTF("Section shdrptr 0x%x, %d + %d type %d\n", + shdrptr, + strs, shdr.sh_name, + (int)shdr.sh_type); + /* + * Match the name of the section with a predefined set of names + * (.text, .far.text, .data, .bss, .rodata, .far.rodata, .rela.text, .rela.far.text, + * .rela.data, .rela.rodata, .rela.far.rodata, .symtab, and .strtab). + */ + + if(shdr.sh_type == SHT_SYMTAB) { + PRINTF("symtab\n"); + symtaboff = shdr.sh_offset; + symtabsize = shdr.sh_size; + } else if(shdr.sh_type == SHT_STRTAB) { + PRINTF("strtab\n"); + strtaboff = shdr.sh_offset; + strtabsize = shdr.sh_size; + } else if(strncmp(name, ".text", 5) == 0) { + textoff = shdr.sh_offset; + textsize = shdr.sh_size; + text.number = i; + text.offset = textoff; + } else if(strncmp(name, ".far.text", 9) == 0) { + textfaroff = shdr.sh_offset; + textfarsize = shdr.sh_size; + textfar.number = i; + textfar.offset = textfaroff; + } else if(strncmp(name, ".rel.text", 9) == 0) { + using_relas = 0; + textrelaoff = shdr.sh_offset; + textrelasize = shdr.sh_size; + } else if(strncmp(name, ".rela.text", 10) == 0) { + using_relas = 1; + textrelaoff = shdr.sh_offset; + textrelasize = shdr.sh_size; + } else if(strncmp(name, ".rela.far.text", 14) == 0) { + using_relas = 1; + textfarrelaoff = shdr.sh_offset; + textfarrelasize = shdr.sh_size; + } else if(strncmp(name, ".data", 5) == 0) { + dataoff = shdr.sh_offset; + datasize = shdr.sh_size; + data.number = i; + data.offset = dataoff; + } else if(strncmp(name, ".rodata", 7) == 0) { + /* read-only data handled the same way as regular text section */ + rodataoff = shdr.sh_offset; + rodatasize = shdr.sh_size; + rodata.number = i; + rodata.offset = rodataoff; + } else if(strncmp(name, ".far.rodata", 11) == 0) { + rodatafaroff = shdr.sh_offset; + rodatafarsize = shdr.sh_size; + rodatafar.number = i; + rodatafar.offset = rodataoff; + } else if(strncmp(name, ".rel.rodata", 11) == 0) { + /* using elf32_rel instead of rela */ + using_relas = 0; + rodatarelaoff = shdr.sh_offset; + rodatarelasize = shdr.sh_size; + } else if(strncmp(name, ".rela.rodata", 12) == 0) { + using_relas = 1; + rodatarelaoff = shdr.sh_offset; + rodatarelasize = shdr.sh_size; + } else if(strncmp(name, ".rela.far.rodata", 16) == 0) { + using_relas = 1; + rodatafarrelaoff = shdr.sh_offset; + rodatafarrelasize = shdr.sh_size; + } else if(strncmp(name, ".rel.data", 9) == 0) { + /* using elf32_rel instead of rela */ + using_relas = 0; + datarelaoff = shdr.sh_offset; + datarelasize = shdr.sh_size; + } else if(strncmp(name, ".rela.data", 10) == 0) { + using_relas = 1; + datarelaoff = shdr.sh_offset; + datarelasize = shdr.sh_size; + } else if(strncmp(name, ".bss", 4) == 0) { + bsssize = shdr.sh_size; + bss.number = i; + bss.offset = 0; + } + + /* Move on to the next section header. */ + shdrptr += shdrsize; + } + if(symtabsize == 0) { + return ELFLOADER_NO_SYMTAB; + } + if(strtabsize == 0) { + return ELFLOADER_NO_STRTAB; + } + if(textfarsize == 0) { + return ELFLOADER_NO_TEXT; + } + + PRINTF("before allocate ram\n"); + bss.address = (char *)elfloader_arch_allocate_ram(bsssize + datasize); + data.address = (char *)bss.address + bsssize; + PRINTF("before allocate rom\n"); + textfar.address = (char *)elfloader_arch_allocate_rom(textfarsize + rodatafarsize); + rodatafar.address = (char *)textfar.address + textfarsize; + + PRINTF("bss base address: bss.address = 0x%08x\n", bss.address); + PRINTF("data base address: data.address = 0x%08x\n", data.address); + PRINTF("textfar base address: textfar.address = 0x%08x\n", textfar.address); + PRINTF("rodatafar base address: rodatafar.address = 0x%08x\n", rodatafar.address); + + /* If we have text segment relocations, we process them. */ + PRINTF("elfloader: relocate textfar\n"); + if(textfarrelasize > 0) { + ret = relocate_section(fd, + textfarrelaoff, textfarrelasize, + textfaroff, + textfar.address, + strs, + strtaboff, + symtaboff, symtabsize, using_relas); + if(ret != ELFLOADER_OK) { + return ret; + } + } + + /* If we have any rodata segment relocations, we process them too. */ + PRINTF("elfloader: relocate rodata\n"); + if(rodatafarrelasize > 0) { + ret = relocate_section(fd, + rodatafarrelaoff, rodatafarrelasize, + rodatafaroff, + rodatafar.address, + strs, + strtaboff, + symtaboff, symtabsize, using_relas); + if(ret != ELFLOADER_OK) { + PRINTF("elfloader: data failed\n"); + return ret; + } + } + + /* If we have any data segment relocations, we process them too. */ + PRINTF("elfloader: relocate data\n"); + if(datarelasize > 0) { + ret = relocate_section(fd, + datarelaoff, datarelasize, + dataoff, + data.address, + strs, + strtaboff, + symtaboff, symtabsize, using_relas); + if(ret != ELFLOADER_OK) { + PRINTF("elfloader: data failed\n"); + return ret; + } + } + + /* Write text and rodata segment into flash and data segment into RAM. */ + elfloader_arch_write_rom(fd, textfaroff, textfarsize, textfar.address); + elfloader_arch_write_rom(fd, rodatafaroff, rodatafarsize, rodatafar.address); + + memset(bss.address, 0, bsssize); + seek_read(fd, dataoff, data.address, datasize); + + PRINTF("elfloader: autostart search\n"); + process = (struct process **)find_local_symbol(fd, "autostart_processes", + symtaboff, symtabsize, strtaboff); + if(process != NULL) { + PRINTF("elfloader: autostart found\n"); + elfloader_autostart_processes = process; + return ELFLOADER_OK; + } else { + PRINTF("elfloader: no autostart\n"); + process = (struct process **)find_program_processes(fd, symtaboff, + symtabsize, strtaboff); + if(process != NULL) { + PRINTF("elfloader: FOUND PRG\n"); + } + return ELFLOADER_NO_STARTPOINT; + } +} +/*---------------------------------------------------------------------------*/ +void * +elfloader_arch_allocate_ram(int size) +{ + return datamemory; +} +/*---------------------------------------------------------------------------*/ +void * +elfloader_arch_allocate_rom(int size) +{ +#if ELFLOADER_CONF_TEXT_IN_ROM + /* Return an 512-byte aligned pointer. */ + return (char *) + ((unsigned long)&textmemory[0] & 0xfffffe00) + + (((unsigned long)&textmemory[0] & 0x1ff) == 0 ? 0 : 0x200); +#else /* ELFLOADER_CONF_TEXT_IN_ROM */ + return textmemory; +#endif /* ELFLOADER_CONF_TEXT_IN_ROM */ +} +/*---------------------------------------------------------------------------*/ +#define READSIZE 32 +void +elfloader_arch_write_rom(int fd, unsigned short textoff, unsigned int size, char *mem) +{ +#if ELFLOADER_CONF_TEXT_IN_ROM + int i; + unsigned int ptr; + unsigned short *flashptr; + + flash_setup(); + + flashptr = (unsigned short *)mem; + + cfs_seek(fd, textoff, CFS_SEEK_SET); + for(ptr = 0; ptr < size; ptr += READSIZE) { + + /* Read data from file into RAM. */ + cfs_read(fd, (unsigned char *)datamemory, READSIZE); + + /* Clear flash page on 512 byte boundary. */ + if((((unsigned short)flashptr) & 0x01ff) == 0) { + flash_clear(flashptr); + } + + /* + * Burn data from RAM into flash ROM. Flash is burned one 16-bit + * word at a time, so we need to be careful when incrementing + * pointers. The flashptr is already a short pointer, so + * incrementing it by one will actually increment the address by + * two. + */ + for(i = 0; i < READSIZE / 2; ++i) { + flash_write(flashptr, ((unsigned short *)datamemory)[i]); + ++flashptr; + } + } + + flash_done(); +#else /* ELFLOADER_CONF_TEXT_IN_ROM */ + cfs_seek(fd, textoff, CFS_SEEK_SET); + cfs_read(fd, (unsigned char *)mem, size); +#endif /* ELFLOADER_CONF_TEXT_IN_ROM */ +} +/*---------------------------------------------------------------------------*/ +/* Relocate an MSP430X ELF section. */ +void +elfloader_arch_relocate(int fd, unsigned int sectionoffset, + char *sectionaddr, + struct elf32_rela *rela, char *addr) +{ + unsigned int type; + unsigned char instr[2]; + + type = ELF32_R_TYPE(rela->r_info); + addr += rela->r_addend; + + switch(type) { + case R_MSP430_16: + case R_MSP430_16_PCREL: + case R_MSP430_16_BYTE: + case R_MSP430_16_PCREL_BYTE: + cfs_seek(fd, sectionoffset + rela->r_offset, CFS_SEEK_SET); + cfs_write(fd, (char *)&addr, 2); + break; + case R_MSP430_32: + cfs_seek(fd, sectionoffset + rela->r_offset, CFS_SEEK_SET); + cfs_write(fd, (char *)&addr, 2); + break; + case R_MSP430X_S: + case R_MSP430X_S_BYTE: + /* src(19:16) located at positions 11:8 of opcode */ + /* src(15:0) located just after opcode */ + cfs_seek(fd, sectionoffset + rela->r_offset, CFS_SEEK_SET); + cfs_read(fd, instr, 2); + instr[1] = (int)(instr[1]) & 0xf0 | (((long int)addr >> 8) & 0x0f00); + instr[0] = (int)(instr[0]) & 0xff; + cfs_seek(fd, sectionoffset + rela->r_offset, CFS_SEEK_SET); + cfs_write(fd, instr, 2); + cfs_write(fd, (char *)&addr, 2); + break; + case R_MSP430X_D: + case R_MSP430X_PCREL_D: + case R_MSP430X_D_BYTE: + /* dst(19:16) located at positions 3:0 of opcode */ + /* dst(15:0) located just after opcode */ + cfs_seek(fd, sectionoffset + rela->r_offset, CFS_SEEK_SET); + cfs_read(fd, instr, 2); + instr[1] = (int)(instr[1]) & 0xff; + instr[0] = (int)(instr[0]) & 0xf0 | (((long int)addr >> 16) & 0x000f); + cfs_seek(fd, sectionoffset + rela->r_offset, CFS_SEEK_SET); + cfs_write(fd, instr, 2); + cfs_write(fd, (char *)&addr, 2); + break; + case R_MSP430X_PCREL_SRC_BYTE: + case R_MSP430X_SRC_BYTE: + case R_MSP430X_PCREL_SRC: + case R_MSP430X_SRC: + /* src(19:16) located at positions 10:7 of extension word */ + /* src(15:0) located just after opcode */ + cfs_seek(fd, sectionoffset + rela->r_offset, CFS_SEEK_SET); + cfs_read(fd, instr, 2); + /* 4 most-significant bits */ + instr[1] = (int)(instr[1]) & 0xf8 | (((long int)addr >> 9) & 0x0780); + instr[0] = (int)(instr[0]) & 0x7f | (((long int)addr >> 9) & 0x0780); + cfs_seek(fd, sectionoffset + rela->r_offset, CFS_SEEK_SET); + cfs_write(fd, instr, 2); + /* 16 least-significant bits */ + cfs_seek(fd, sectionoffset + rela->r_offset + 0x04, CFS_SEEK_SET); + cfs_write(fd, (char *)&addr, 2); + break; + case R_MSP430X_DST_BYTE: + case R_MSP430X_PCREL_DST_BYTE: + case R_MSP430X_DST: + case R_MSP430X_PCREL_DST: + /* dst(19:16) located at positions 3:0 of extension word */ + /* dst(15:0) located just after opcode */ + cfs_seek(fd, sectionoffset + rela->r_offset, CFS_SEEK_SET); + cfs_read(fd, instr, 2); + instr[1] = (int)(instr[1]) & 0xff; + instr[0] = (int)(instr[0]) & 0xf0 | (((long int)addr >> 16) & 0x000f); + cfs_seek(fd, sectionoffset + rela->r_offset, CFS_SEEK_SET); + cfs_write(fd, instr, 2); + cfs_seek(fd, sectionoffset + rela->r_offset + 0x04, CFS_SEEK_SET); + cfs_write(fd, (char *)&addr, 2); + break; + case R_MSP430X_DST_2ND: + case R_MSP430X_PCREL_DST_2ND: + case R_MSP430X_DST_2ND_BYTE: + case R_MSP430X_PCREL_DST_2ND_BYTE: + /* dst(19:16) located at positions 3:0 of extension word */ + /* dst(15:0) located after src(15:0) */ + cfs_seek(fd, sectionoffset + rela->r_offset, CFS_SEEK_SET); + cfs_read(fd, instr, 2); + instr[1] = (int)(instr[1]) & 0xff; + instr[0] = (int)(instr[0]) & 0xf0 | (((long int)addr >> 16) & 0x000f); + cfs_seek(fd, sectionoffset + rela->r_offset, CFS_SEEK_SET); + cfs_write(fd, instr, 2); + cfs_seek(fd, sectionoffset + rela->r_offset + 0x06, CFS_SEEK_SET); + cfs_write(fd, (char *)&addr, 2); + break; + case R_MSP430X_INDXD: + case R_MSP430X_PCREL_INDXD: + cfs_seek(fd, sectionoffset + rela->r_offset + 0x02, CFS_SEEK_SET); + cfs_write(fd, (char *)&addr, 2); + break; + default: + PRINTF("Unknown relocation type!\n"); + break; + } +} +/*---------------------------------------------------------------------------*/ diff --git a/cpu/msp430/Makefile.msp430 b/cpu/msp430/Makefile.msp430 index 264538611..1a75e6068 100644 --- a/cpu/msp430/Makefile.msp430 +++ b/cpu/msp430/Makefile.msp430 @@ -37,6 +37,10 @@ MSP430 = msp430.c flash.c clock.c leds.c leds-arch.c \ UIPDRIVERS = me.c me_tabs.c slip.c crc16.c ELFLOADER = elfloader.c elfloader-msp430.c symtab.c +ifeq ($(TARGET_MEMORY_MODEL),large) +ELFLOADER = elfloader-msp430x.c symtab.c +endif + CONTIKI_TARGET_SOURCEFILES += $(MSP430) \ $(SYSAPPS) $(ELFLOADER) \ $(UIPDRIVERS) @@ -149,10 +153,16 @@ endif ifndef IAR ifneq (,$(findstring 4.7.,$(shell msp430-gcc -dumpversion))) ifdef CPU_HAS_MSP430X - TARGET_MEMORY_MODEL ?= medium + ifeq ($(TARGET_MEMORY_MODEL),large) + CFLAGS += -mmemory-model=$(TARGET_MEMORY_MODEL) + CFLAGS += -mcode-region=far -mdata-region=far -msr20 -mc20 -md20 + LDFLAGS += -mmemory-model=$(TARGET_MEMORY_MODEL) -mcode-region=far -mdata-region=far -msr20 -mc20 -md20 + else + TARGET_MEMORY_MODEL = medium CFLAGS += -mmemory-model=$(TARGET_MEMORY_MODEL) CFLAGS += -ffunction-sections -fdata-sections -mcode-region=any LDFLAGS += -mmemory-model=$(TARGET_MEMORY_MODEL) -Wl,-gc-sections + endif endif endif endif From 1f0fd3f38bba1bf1deb0edbf9c60c9dccdebdd2b Mon Sep 17 00:00:00 2001 From: Laurent Deru Date: Mon, 15 Jun 2015 15:15:59 +0200 Subject: [PATCH 024/120] Add uip_ext_len definition in fakeuip.c for ravenusbstick --- examples/ravenusbstick/fakeuip.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/examples/ravenusbstick/fakeuip.c b/examples/ravenusbstick/fakeuip.c index a1e980aab..1f7232a64 100644 --- a/examples/ravenusbstick/fakeuip.c +++ b/examples/ravenusbstick/fakeuip.c @@ -13,6 +13,8 @@ uip_buf_t uip_aligned_buf; uint16_t uip_len; +uint8_t uip_ext_len; + struct uip_stats uip_stat; uip_lladdr_t uip_lladdr; From 7a56d91c50121b5aba255bbfbc9c6ba96a9d5dd0 Mon Sep 17 00:00:00 2001 From: Laurent Deru Date: Fri, 12 Jun 2015 12:34:55 +0200 Subject: [PATCH 025/120] Clone packet data before modifying it --- .../org/contikios/cooja/plugins/analyzers/PacketAnalyzer.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/cooja/java/org/contikios/cooja/plugins/analyzers/PacketAnalyzer.java b/tools/cooja/java/org/contikios/cooja/plugins/analyzers/PacketAnalyzer.java index 7f4002960..28a548e3c 100644 --- a/tools/cooja/java/org/contikios/cooja/plugins/analyzers/PacketAnalyzer.java +++ b/tools/cooja/java/org/contikios/cooja/plugins/analyzers/PacketAnalyzer.java @@ -27,7 +27,7 @@ public abstract class PacketAnalyzer { public Packet(byte[] data, int level) { this.level = level; - this.data = data; + this.data = data.clone(); this.size = data.length; } From 6891ca12b06cfecbc5a16759e592051f144e6b80 Mon Sep 17 00:00:00 2001 From: Laurent Deru Date: Fri, 12 Jun 2015 12:59:51 +0200 Subject: [PATCH 026/120] Add crc to packets send by coojamote --- .../contikimote/interfaces/ContikiRadio.java | 15 +++- .../org/contikios/cooja/util/CCITT_CRC.java | 89 +++++++++++++++++++ 2 files changed, 101 insertions(+), 3 deletions(-) create mode 100644 tools/cooja/java/org/contikios/cooja/util/CCITT_CRC.java diff --git a/tools/cooja/java/org/contikios/cooja/contikimote/interfaces/ContikiRadio.java b/tools/cooja/java/org/contikios/cooja/contikimote/interfaces/ContikiRadio.java index 5502b9a8a..bbc4a2abd 100644 --- a/tools/cooja/java/org/contikios/cooja/contikimote/interfaces/ContikiRadio.java +++ b/tools/cooja/java/org/contikios/cooja/contikimote/interfaces/ContikiRadio.java @@ -48,7 +48,7 @@ import org.contikios.cooja.interfaces.Position; import org.contikios.cooja.interfaces.Radio; import org.contikios.cooja.mote.memory.VarMemory; import org.contikios.cooja.radiomediums.UDGM; - +import org.contikios.cooja.util.CCITT_CRC; /** * Packet radio transceiver mote interface. * @@ -200,7 +200,7 @@ public class ContikiRadio extends Radio implements ContikiMoteInterface, PolledA packetToMote = null; myMoteMemory.setIntValueOf("simInSize", 0); } else { - myMoteMemory.setIntValueOf("simInSize", packetToMote.getPacketData().length); + myMoteMemory.setIntValueOf("simInSize", packetToMote.getPacketData().length - 2); myMoteMemory.setByteArray("simInDataBuffer", packetToMote.getPacketData()); } @@ -330,7 +330,7 @@ public class ContikiRadio extends Radio implements ContikiMoteInterface, PolledA /* New transmission */ int size = myMoteMemory.getIntValueOf("simOutSize"); if (!isTransmitting && size > 0) { - packetFromMote = new COOJARadioPacket(myMoteMemory.getByteArray("simOutDataBuffer", size)); + packetFromMote = new COOJARadioPacket(myMoteMemory.getByteArray("simOutDataBuffer", size + 2)); if (packetFromMote.getPacketData() == null || packetFromMote.getPacketData().length == 0) { logger.warn("Skipping zero sized Contiki packet (no buffer)"); @@ -339,6 +339,15 @@ public class ContikiRadio extends Radio implements ContikiMoteInterface, PolledA return; } + byte[] data = packetFromMote.getPacketData(); + CCITT_CRC txCrc = new CCITT_CRC(); + txCrc.setCRC(0); + for (int i = 0; i < size; i++) { + txCrc.addBitrev(data[i]); + } + data[size] = (byte)txCrc.getCRCHi(); + data[size + 1] = (byte)txCrc.getCRCLow(); + isTransmitting = true; /* Calculate transmission duration (us) */ diff --git a/tools/cooja/java/org/contikios/cooja/util/CCITT_CRC.java b/tools/cooja/java/org/contikios/cooja/util/CCITT_CRC.java new file mode 100644 index 000000000..ea991208b --- /dev/null +++ b/tools/cooja/java/org/contikios/cooja/util/CCITT_CRC.java @@ -0,0 +1,89 @@ +/** + * Copyright (c) 2008, Swedish Institute of Computer Science. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the Institute nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * This file is part of MSPSim. + * + * ----------------------------------------------------------------- + * + * Author : Joakim Eriksson + */ + +package org.contikios.cooja.util; + +/* basic CRC-CCITT code */ +public class CCITT_CRC { + int crc; + + public int getCRC() { + return crc; + } + + /* this will only work with zero... */ + public void setCRC(int val) { + crc = val; + } + + public void clr() { + crc = 0xffff; + } + + public void addBitrev(int data) { + add(bitrev(data)); + } + + public int getCRCLow() { + return bitrev(crc & 0xff); + } + + public int getCRCHi() { + return bitrev(crc >> 8); + } + + + public int add(int data) { + int newCrc = ((crc >> 8) & 0xff) | (crc << 8) & 0xffff; + newCrc ^= (data & 0xff); + newCrc ^= (newCrc & 0xff) >> 4; + newCrc ^= (newCrc << 12) & 0xffff; + newCrc ^= (newCrc & 0xff) << 5; + crc = newCrc & 0xffff; + return crc; + } + + public int getCRCBitrev() { + return getCRCLow() + (getCRCHi() << 8); + } + + public static final String hex = "0123456789abcdef"; + + private static int bitrev(int data) { + return ((data << 7) & 0x80) | ((data << 5) & 0x40) | + (data << 3) & 0x20 | (data << 1) & 0x10 | + (data >> 7) & 0x01 | (data >> 5) & 0x02 | + (data >> 3) & 0x04 | (data >> 1) & 0x08; + } +} From 68c284b955fb839085e3898e745a79b97efe0bed Mon Sep 17 00:00:00 2001 From: Laurent Deru Date: Fri, 12 Jun 2015 13:01:18 +0200 Subject: [PATCH 027/120] Do not add a CRC to packet incoming from RfListener --- .../cooja/mspmote/interfaces/CC2420RadioPacketConverter.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/cooja/apps/mspsim/src/org/contikios/cooja/mspmote/interfaces/CC2420RadioPacketConverter.java b/tools/cooja/apps/mspsim/src/org/contikios/cooja/mspmote/interfaces/CC2420RadioPacketConverter.java index fd62da50f..a4eebaaab 100644 --- a/tools/cooja/apps/mspsim/src/org/contikios/cooja/mspmote/interfaces/CC2420RadioPacketConverter.java +++ b/tools/cooja/apps/mspsim/src/org/contikios/cooja/mspmote/interfaces/CC2420RadioPacketConverter.java @@ -46,7 +46,7 @@ public class CC2420RadioPacketConverter { public static final boolean WITH_XMAC = false; /* XXX No longer supported. Cross-level requires NULLMAC */ public static final boolean WITH_CHECKSUM = false; /* Contiki checksum. Not CC2420's built-in. */ public static final boolean WITH_TIMESTAMP = false; /* Contiki timestamp */ - public static final boolean WITH_FOOTER = true; /* CC2420's checksum */ + public static final boolean WITH_FOOTER = false; /* CC2420's checksum */ public static byte[] fromCoojaToCC2420(RadioPacket packet) { byte cc2420Data[] = new byte[6+127]; From b3046f15375f6731d6663d20322ddc7a4d21f67a Mon Sep 17 00:00:00 2001 From: tpetry Date: Fri, 19 Jun 2015 16:32:19 +0200 Subject: [PATCH 028/120] remove rime routes in LRU mode if trying to add a new route to full route table --- core/net/rime/route.c | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/core/net/rime/route.c b/core/net/rime/route.c index 2a51d12c6..dee9ab837 100644 --- a/core/net/rime/route.c +++ b/core/net/rime/route.c @@ -121,7 +121,7 @@ int route_add(const linkaddr_t *dest, const linkaddr_t *nexthop, uint8_t cost, uint8_t seqno) { - struct route_entry *e; + struct route_entry *e, *oldest = NULL; /* Avoid inserting duplicate entries. */ e = route_lookup(dest); @@ -131,8 +131,14 @@ route_add(const linkaddr_t *dest, const linkaddr_t *nexthop, /* Allocate a new entry or reuse the oldest entry with highest cost. */ e = memb_alloc(&route_mem); if(e == NULL) { - /* Remove oldest entry. XXX */ - e = list_chop(route_table); + /* Remove oldest entry. */ + for(e = list_head(route_table); e != NULL; e = list_item_next(e)) { + if(oldest == NULL || e->time >= oldest->time) { + oldest = e; + } + } + e = oldest; + list_remove(route_table, e); PRINTF("route_add: removing entry to %d.%d with nexthop %d.%d and cost %d\n", e->dest.u8[0], e->dest.u8[1], e->nexthop.u8[0], e->nexthop.u8[1], From 8739113308e2d18f04f217af1ca8da7b87d7ce06 Mon Sep 17 00:00:00 2001 From: Arthur Fabre Date: Thu, 16 Jul 2015 13:42:25 +0100 Subject: [PATCH 029/120] Fix warnings in ContikiMAC MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ../..//core/net/mac/contikimac/contikimac.c:503:11: warning: variable ‘seqno’ set but not used [-Wunused-but-set-variable] ../..//core/net/mac/contikimac/contikimac.c:496:7: warning: variable ‘len’ set but not used [-Wunused-but-set-variable] Both of these variables are only used if RDC_CONF_HARDWARE_ACK is not true. Their definitions and use have been moved into #ifdef guards so they do not appear if RDC_CONF_HARDWARE_ACK is set. --- core/net/mac/contikimac/contikimac.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/core/net/mac/contikimac/contikimac.c b/core/net/mac/contikimac/contikimac.c index b7083e83d..927953681 100644 --- a/core/net/mac/contikimac/contikimac.c +++ b/core/net/mac/contikimac/contikimac.c @@ -493,14 +493,16 @@ send_packet(mac_callback_t mac_callback, void *mac_callback_ptr, #endif int strobes; uint8_t got_strobe_ack = 0; - int len; 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) { @@ -641,11 +643,11 @@ send_packet(mac_callback_t mac_callback, void *mac_callback_ptr, or rx cycle */ on(); } + seqno = packetbuf_attr(PACKETBUF_ATTR_MAC_SEQNO); #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++) { @@ -658,7 +660,9 @@ send_packet(mac_callback_t mac_callback, void *mac_callback_ptr, break; } +#if !RDC_CONF_HARDWARE_ACK len = 0; +#endif { rtimer_clock_t wt; From bfba83ed168a2625cbff05cfa91db39c3c9cd970 Mon Sep 17 00:00:00 2001 From: Simon Duquennoy Date: Mon, 3 Aug 2015 15:13:00 +0200 Subject: [PATCH 030/120] galois_mul2 conditional-free implementation --- core/lib/aes-128.c | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/core/lib/aes-128.c b/core/lib/aes-128.c index 59b16421e..23e4356b7 100644 --- a/core/lib/aes-128.c +++ b/core/lib/aes-128.c @@ -71,12 +71,8 @@ static uint8_t round_keys[11][AES_128_KEY_LENGTH]; static uint8_t galois_mul2(uint8_t value) { - if(value >> 7) { - value = value << 1; - return value ^ 0x1b; - } else { - return value << 1; - } + uint8_t xor_val = (value >> 7) * 0x1b; + return ((value << 1) ^ xor_val); } /*---------------------------------------------------------------------------*/ static void From b1c3e929c5156aaec8e3465e45a5d27047181ade Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pablo=20Corbal=C3=A1n?= Date: Fri, 22 May 2015 09:12:01 +0100 Subject: [PATCH 031/120] Remove old unused light drivers --- platform/sky/dev/light.c | 126 ----------------------------------- platform/sky/dev/light.h | 40 ----------- platform/wismote/dev/light.c | 126 ----------------------------------- platform/wismote/dev/light.h | 40 ----------- platform/z1/dev/light.c | 118 -------------------------------- platform/z1/dev/light.h | 40 ----------- 6 files changed, 490 deletions(-) delete mode 100644 platform/sky/dev/light.c delete mode 100644 platform/sky/dev/light.h delete mode 100644 platform/wismote/dev/light.c delete mode 100644 platform/wismote/dev/light.h delete mode 100644 platform/z1/dev/light.c delete mode 100644 platform/z1/dev/light.h diff --git a/platform/sky/dev/light.c b/platform/sky/dev/light.c deleted file mode 100644 index 53f610fa9..000000000 --- a/platform/sky/dev/light.c +++ /dev/null @@ -1,126 +0,0 @@ -/* - * Copyright (c) 2005, Swedish Institute of Computer Science - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the Institute nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * This file is part of the Contiki operating system. - * - */ - -#include -#include "contiki.h" -#include "dev/light.h" - -/* - * Initialize periodic readings from the 2 photo diodes. The most - * recent readings will be stored in ADC internal registers/memory. - */ -void -sensors_light_init(void) -{ - P6SEL |= 0x30; - P6DIR = 0xff; - P6OUT = 0x00; - - /* Set up the ADC. */ - ADC12CTL0 = REF2_5V + SHT0_6 + SHT1_6 + MSC; // Setup ADC12, ref., sampling time - ADC12CTL1 = SHP + CONSEQ_3 + CSTARTADD_0; // Use sampling timer, repeat-sequenc-of-channels - - ADC12MCTL0 = (INCH_4 + SREF_0); // photodiode 1 (P64) - ADC12MCTL1 = (INCH_5 + SREF_0); // photodiode 2 (P65) - - ADC12CTL0 |= ADC12ON + REFON; - - ADC12CTL0 |= ENC; // enable conversion - ADC12CTL0 |= ADC12SC; // sample & convert -} - -/* Photosynthetically Active Radiation. */ -unsigned -sensors_light1(void) -{ - return ADC12MEM0; -} - -/* Total Solar Radiation. */ -unsigned -sensors_light2(void) -{ - return ADC12MEM1; -} - -/* - * Most of this information taken from - * http://www.moteiv.com/community/Getting_Data_from_Tmote_Sky%27s_Sensors - * - * The Photosynthetically Active Radiation (PAR) sensor as well as the - * Total Solar Radiation (TSR) sensor uses the 2.5V reference voltage - * to produce the raw ADC value. - - * The voltage across each sensor is: - * - * VsensorPAR = ADCValuePAR/4096 * Vref (1a) - * VsensorTSR = ADCValueTSR/4096 * Vref (1b) - * where Vref = 2.5V - * - * This voltage creates a current through a resistor R=100KOhm and this - * current has a linear relationship with the light intensity in Lux. - * IPAR = VsensorPAR / 100,000 (2a) - * ITSR = VsensorTSR / 100,000 (2b) - * - * S1087 (PAR) lx = 1e6 * IPAR * 1000 (3a) - * S1087-01 (TSR) lx = 1e5 * ITSR * 1000 (3b) - * - * lxPAR = 10e9 * ADCValuePAR *(1/4096)* Vref * 10e-5 or - * lxPAR = 3125* ADCvaluePAR / 512 - * and - * lxTSR = 10e8 * ADCValueTSR *(1/4096)* Vref * 10e-5 or - * lxTSR = 625* ADCvalueTSR / 1024 -*/ - -#if 0 -/* Photosynthetically Active Radiation in Lux units. */ -unsigned -sensors_light1_lux(void) -{ - unsigned temp; - temp = (uint32_t)ADC12MEM0; - - temp = (temp*3125)>> 9; - return (uint16_t)(temp & 0xFFFF); -} - -/* Total Solar Radiation in Lux units. */ -unsigned -sensors_light2_lux(void) -{ - unsigned temp; - temp = (uint32_t)ADC12MEM1; - - temp = (temp*625)>> 10; - return (uint16_t)(temp & 0xFFFF); -} -#endif diff --git a/platform/sky/dev/light.h b/platform/sky/dev/light.h deleted file mode 100644 index 52962b162..000000000 --- a/platform/sky/dev/light.h +++ /dev/null @@ -1,40 +0,0 @@ -/* - * Copyright (c) 2005, Swedish Institute of Computer Science - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the Institute nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * This file is part of the Contiki operating system. - * - */ -#ifndef LIGHT_H_ -#define LIGHT_H_ - -void sensors_light_init(void); - -unsigned sensors_light1(void); -unsigned sensors_light2(void); - -#endif /* LIGHT_H_ */ diff --git a/platform/wismote/dev/light.c b/platform/wismote/dev/light.c deleted file mode 100644 index be7d7540f..000000000 --- a/platform/wismote/dev/light.c +++ /dev/null @@ -1,126 +0,0 @@ -/* - * Copyright (c) 2005, Swedish Institute of Computer Science - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the Institute nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * This file is part of the Contiki operating system. - * - */ - -#include "contiki.h" -#include "dev/light.h" -#include - -/* - * Initialize periodic readings from the 2 photo diodes. The most - * recent readings will be stored in ADC internal registers/memory. - */ -void -sensors_light_init(void) -{ - P6SEL |= 0x30; - P6DIR = 0xff; - P6OUT = 0x00; - - /* Set up the ADC. */ - ADC12CTL0 = REF2_5V + SHT0_6 + SHT1_6 + MSC; // Setup ADC12, ref., sampling time - ADC12CTL1 = SHP + CONSEQ_3 + CSTARTADD_0; // Use sampling timer, repeat-sequenc-of-channels - - ADC12MCTL0 = (INCH_4 + SREF_0); // photodiode 1 (P64) - ADC12MCTL1 = (INCH_5 + SREF_0); // photodiode 2 (P65) - - ADC12CTL0 |= ADC12ON + REFON; - - ADC12CTL0 |= ENC; // enable conversion - ADC12CTL0 |= ADC12SC; // sample & convert -} - -/* Photosynthetically Active Radiation. */ -unsigned -sensors_light1(void) -{ - return ADC12MEM0; -} - -/* Total Solar Radiation. */ -unsigned -sensors_light2(void) -{ - return ADC12MEM1; -} - -/* - * Most of this information taken from - * http://www.moteiv.com/community/Getting_Data_from_Tmote_Sky%27s_Sensors - * - * The Photosynthetically Active Radiation (PAR) sensor as well as the - * Total Solar Radiation (TSR) sensor uses the 2.5V reference voltage - * to produce the raw ADC value. - - * The voltage across each sensor is: - * - * VsensorPAR = ADCValuePAR/4096 * Vref (1a) - * VsensorTSR = ADCValueTSR/4096 * Vref (1b) - * where Vref = 2.5V - * - * This voltage creates a current through a resistor R=100KOhm and this - * current has a linear relationship with the light intensity in Lux. - * IPAR = VsensorPAR / 100,000 (2a) - * ITSR = VsensorTSR / 100,000 (2b) - * - * S1087 (PAR) lx = 1e6 * IPAR * 1000 (3a) - * S1087-01 (TSR) lx = 1e5 * ITSR * 1000 (3b) - * - * lxPAR = 10e9 * ADCValuePAR *(1/4096)* Vref * 10e-5 or - * lxPAR = 3125* ADCvaluePAR / 512 - * and - * lxTSR = 10e8 * ADCValueTSR *(1/4096)* Vref * 10e-5 or - * lxTSR = 625* ADCvalueTSR / 1024 -*/ - -#if 0 -/* Photosynthetically Active Radiation in Lux units. */ -unsigned -sensors_light1_lux(void) -{ - unsigned temp; - temp = (uint32_t)ADC12MEM0; - - temp = (temp*3125)>> 9; - return (uint16_t)(temp & 0xFFFF); -} - -/* Total Solar Radiation in Lux units. */ -unsigned -sensors_light2_lux(void) -{ - unsigned temp; - temp = (uint32_t)ADC12MEM1; - - temp = (temp*625)>> 10; - return (uint16_t)(temp & 0xFFFF); -} -#endif diff --git a/platform/wismote/dev/light.h b/platform/wismote/dev/light.h deleted file mode 100644 index 52962b162..000000000 --- a/platform/wismote/dev/light.h +++ /dev/null @@ -1,40 +0,0 @@ -/* - * Copyright (c) 2005, Swedish Institute of Computer Science - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the Institute nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * This file is part of the Contiki operating system. - * - */ -#ifndef LIGHT_H_ -#define LIGHT_H_ - -void sensors_light_init(void); - -unsigned sensors_light1(void); -unsigned sensors_light2(void); - -#endif /* LIGHT_H_ */ diff --git a/platform/z1/dev/light.c b/platform/z1/dev/light.c deleted file mode 100644 index ad1fb88d6..000000000 --- a/platform/z1/dev/light.c +++ /dev/null @@ -1,118 +0,0 @@ -/* - * Copyright (c) 2011, Zolertia(TM) is a trademark of Advancare,SL - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the Institute nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * This file is part of the Contiki operating system. - * - * - * \file - * Dummy light-sensor to allow as many programs for sky to compile for Z1 - * - * \author - * Enric M. Calvo , adapted from previous work - * - */ - -#include -#include "contiki.h" -#include "dev/light.h" - -/* - * Initialize periodic readings from the 2 photo diodes. The most - * recent readings will be stored in ADC internal registers/memory. - */ -void -sensors_light_init(void) -{ -} - -/* Photosynthetically Active Radiation. */ -unsigned -sensors_light1(void) -{ - return 0; -} - -/* Total Solar Radiation. */ -unsigned -sensors_light2(void) -{ - return 0; -} - -/* - * Most of this information taken from - * http://www.moteiv.com/community/Getting_Data_from_Tmote_Sky%27s_Sensors - * - * The Photosynthetically Active Radiation (PAR) sensor as well as the - * Total Solar Radiation (TSR) sensor uses the 2.5V reference voltage - * to produce the raw ADC value. - - * The voltage across each sensor is: - * - * VsensorPAR = ADCValuePAR/4096 * Vref (1a) - * VsensorTSR = ADCValueTSR/4096 * Vref (1b) - * where Vref = 2.5V - * - * This voltage creates a current through a resistor R=100KOhm and this - * current has a linear relationship with the light intensity in Lux. - * IPAR = VsensorPAR / 100,000 (2a) - * ITSR = VsensorTSR / 100,000 (2b) - * - * S1087 (PAR) lx = 1e6 * IPAR * 1000 (3a) - * S1087-01 (TSR) lx = 1e5 * ITSR * 1000 (3b) - * - * lxPAR = 10e9 * ADCValuePAR *(1/4096)* Vref * 10e-5 or - * lxPAR = 3125* ADCvaluePAR / 512 - * and - * lxTSR = 10e8 * ADCValueTSR *(1/4096)* Vref * 10e-5 or - * lxTSR = 625* ADCvalueTSR / 1024 -*/ - -#if 0 -/* Photosynthetically Active Radiation in Lux units. */ -unsigned -sensors_light1_lux(void) -{ - unsigned temp; - temp = (uint32_t)ADC12MEM0; - - temp = (temp*3125)>> 9; - return (uint16_t)(temp & 0xFFFF); -} - -/* Total Solar Radiation in Lux units. */ -unsigned -sensors_light2_lux(void) -{ - unsigned temp; - temp = (uint32_t)ADC12MEM1; - - temp = (temp*625)>> 10; - return (uint16_t)(temp & 0xFFFF); -} -#endif diff --git a/platform/z1/dev/light.h b/platform/z1/dev/light.h deleted file mode 100644 index 52962b162..000000000 --- a/platform/z1/dev/light.h +++ /dev/null @@ -1,40 +0,0 @@ -/* - * Copyright (c) 2005, Swedish Institute of Computer Science - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the Institute nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * This file is part of the Contiki operating system. - * - */ -#ifndef LIGHT_H_ -#define LIGHT_H_ - -void sensors_light_init(void); - -unsigned sensors_light1(void); -unsigned sensors_light2(void); - -#endif /* LIGHT_H_ */ From 5db5524b7f1bc148b4020b9db726687bbca4b06e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pablo=20Corbal=C3=A1n?= Date: Fri, 22 May 2015 10:53:37 +0100 Subject: [PATCH 032/120] Remove unneeded headers in sky-shell-exec --- examples/sky-shell-exec/sky-shell-exec.c | 14 -------------- 1 file changed, 14 deletions(-) diff --git a/examples/sky-shell-exec/sky-shell-exec.c b/examples/sky-shell-exec/sky-shell-exec.c index bab3969c0..469d824c4 100644 --- a/examples/sky-shell-exec/sky-shell-exec.c +++ b/examples/sky-shell-exec/sky-shell-exec.c @@ -34,20 +34,6 @@ #include "shell.h" #include "serial-shell.h" -#include "dev/watchdog.h" - -#include "net/rime/rime.h" -#include "cc2420.h" -#include "dev/leds.h" -#include "dev/light.h" -#include "dev/sht11/sht11.h" -#include "dev/battery-sensor.h" - -#include "net/rime/timesynch.h" - -#include -#include - /*---------------------------------------------------------------------------*/ PROCESS(sky_shell_process, "Sky Contiki shell"); AUTOSTART_PROCESSES(&sky_shell_process); From b75f6738019e834629e2f10fccc8dc866bf3b7c6 Mon Sep 17 00:00:00 2001 From: Atis Elsts Date: Tue, 22 Apr 2014 15:41:36 +0200 Subject: [PATCH 033/120] RDC phase optimization: correct the behavior in case of memory allocation failure phase_wait did not check whether queuebuf_new_from_packetbuf() returns NULL. This potentially causes send_packet to behave incorrectly; the proper packet would not be sent out (because queuebuf_to_packetbuf(NULL) is a no-op). Instead, whatever has been left in the packet buffer by its previous user will be sent out. --- core/net/mac/phase.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/core/net/mac/phase.c b/core/net/mac/phase.c index ff20ae978..47b7e7cf3 100644 --- a/core/net/mac/phase.c +++ b/core/net/mac/phase.c @@ -219,6 +219,11 @@ phase_wait(const linkaddr_t *neighbor, rtimer_clock_t cycle_time, if(buf_list == NULL) { packetbuf_set_attr(PACKETBUF_ATTR_IS_CREATED_AND_SECURED, 1); p->q = queuebuf_new_from_packetbuf(); + if(p->q == NULL) { + /* memory allocation failed */ + memb_free(&queued_packets_memb, p); + return PHASE_UNKNOWN; + } } p->mac_callback = mac_callback; p->mac_callback_ptr = mac_callback_ptr; From eb0da7dfe9fe55eb79311c9b4cedace46b383a94 Mon Sep 17 00:00:00 2001 From: Simon Duquennoy Date: Tue, 18 Aug 2015 22:01:09 +0200 Subject: [PATCH 034/120] Updated CONTRIBUTING.md to reflect Contiki's new merging policy --- CONTRIBUTING.md | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index ab4aba7e0..8ed3d23a6 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -136,7 +136,7 @@ Contiki maintainers to look at! All code contributions to Contiki are submitted as [Github pull requests](https://help.github.com/articles/using-pull-requests). Pull requests will be reviewed and accepted according to the guidelines -found in the [[Pull Request Policy]] +found in the next section. The basic guidelines to to start a Pull-Request: * Create a new branch for your modifications. This branch should be based on the latest contiki master branch. @@ -183,6 +183,21 @@ $ git push origin my_new_feature -f ``` * NOTE: To avoid all the pain of selectively picking commits, rebasing and force-pushing - begin your development with a branch OTHER THAN your master branch, and push changes to that branch after any local commits. +Pull Request Merging Policy +--------------------------- + +Pull requests (PRs) are reviewed by the [merge team](https://github.com/orgs/contiki-os/people). +Generally, PRs require two "+1" before they can be merged by someone on the merge team. +The since Contiki 3.0, the merging policy is the following: +* The PR receives **one "-1"** from a merge team member (along with specific feedback). The PR is closed. A "-1" must be accompanied with a clear explanation why the PR will not be considered for inclusion. +* The PR receives **two "+1"** from merge team members. The PR is merged. +* The PR was inactive for **two months**. A team member may either: + * Comment "Is there any interest for this PR? Is there any work pending on it? If not I will close it in **one month**." Back to initial state in case of activity, close otherwise. + * Comment "I approve this PR. If nobody disapproves within **one month**, I will merge it." Back to initial state in case of activity, merge otherwise. + +There is an exception to the rule. +Code that requires esoteric expertise such as some applications, platforms or tools can be merged after a single "+1" from its domain expert. + Travis / Regression testing --------------------------- From a5e3faca5f6ab7331205edee023a55388b13b278 Mon Sep 17 00:00:00 2001 From: Simon Duquennoy Date: Thu, 20 Aug 2015 10:09:45 +0200 Subject: [PATCH 035/120] Travis: upgrade mspgcc to 4.7.2 --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index 9087bdd8e..db506cd03 100644 --- a/.travis.yml +++ b/.travis.yml @@ -17,7 +17,7 @@ before_script: ## Install msp430 toolchain - sudo apt-get -qq install lib32z1 - - $WGET http://adamdunkels.github.io/contiki-fork/mspgcc-4.7.0-compiled.tar.bz2 && + - $WGET http://simonduq.github.io/resources/mspgcc-4.7.2-compiled.tar.bz2 && tar xjf mspgcc*.tar.bz2 -C /tmp/ && sudo cp -f -r /tmp/msp430/* /usr/local/ && rm -rf /tmp/msp430 mspgcc*.tar.bz2 && From 04106a0d5346c1afcc5fc2c3e6633b92ba06581f Mon Sep 17 00:00:00 2001 From: Simon Duquennoy Date: Thu, 20 Aug 2015 16:48:11 +0200 Subject: [PATCH 036/120] ND6: make sure the second parameter of uip_ds6_nbr_add is word-aligned, which is required as the parameter is directly accessed as uip_lladdr_t* (not as a byte array) --- core/net/ipv6/uip-nd6.c | 31 ++++++++++++++++++------------- 1 file changed, 18 insertions(+), 13 deletions(-) diff --git a/core/net/ipv6/uip-nd6.c b/core/net/ipv6/uip-nd6.c index 72b1badfa..3fe7165d9 100644 --- a/core/net/ipv6/uip-nd6.c +++ b/core/net/ipv6/uip-nd6.c @@ -189,15 +189,16 @@ ns_input(void) #endif /*UIP_CONF_IPV6_CHECKS */ nbr = uip_ds6_nbr_lookup(&UIP_IP_BUF->srcipaddr); if(nbr == NULL) { - uip_ds6_nbr_add(&UIP_IP_BUF->srcipaddr, - (uip_lladdr_t *)&nd6_opt_llao[UIP_ND6_OPT_DATA_OFFSET], - 0, NBR_STALE); + /* Copy link address to a uip_lladdr_t first + * to ensure the second argument to uip_ds6_nbr_add is word-aligned */ + uip_lladdr_t lladdr; + memcpy(&lladdr, &nd6_opt_llao[UIP_ND6_OPT_DATA_OFFSET], UIP_LLADDR_LEN); + uip_ds6_nbr_add(&UIP_IP_BUF->srcipaddr, &lladdr, 0, NBR_STALE); } else { uip_lladdr_t *lladdr = (uip_lladdr_t *)uip_ds6_nbr_get_ll(nbr); if(memcmp(&nd6_opt_llao[UIP_ND6_OPT_DATA_OFFSET], - lladdr, UIP_LLADDR_LEN) != 0) { - memcpy(lladdr, &nd6_opt_llao[UIP_ND6_OPT_DATA_OFFSET], - UIP_LLADDR_LEN); + lladdr, UIP_LLADDR_LEN) != 0) { + memcpy(lladdr, &nd6_opt_llao[UIP_ND6_OPT_DATA_OFFSET], UIP_LLADDR_LEN); nbr->state = NBR_STALE; } else { if(nbr->state == NBR_INCOMPLETE) { @@ -619,18 +620,20 @@ rs_input(void) goto discard; } else { #endif /*UIP_CONF_IPV6_CHECKS */ + /* Copy link address to a uip_lladdr_t first + * to ensure the second argument to uip_ds6_nbr_add is word-aligned */ + uip_lladdr_t lladdr; + memcpy(&lladdr, &nd6_opt_llao[UIP_ND6_OPT_DATA_OFFSET], UIP_LLADDR_LEN); if((nbr = uip_ds6_nbr_lookup(&UIP_IP_BUF->srcipaddr)) == NULL) { /* we need to add the neighbor */ - uip_ds6_nbr_add(&UIP_IP_BUF->srcipaddr, - (uip_lladdr_t *)&nd6_opt_llao[UIP_ND6_OPT_DATA_OFFSET], 0, NBR_STALE); + uip_ds6_nbr_add(&UIP_IP_BUF->srcipaddr, &lladdr, 0, NBR_STALE); } else { /* If LL address changed, set neighbor state to stale */ if(memcmp(&nd6_opt_llao[UIP_ND6_OPT_DATA_OFFSET], uip_ds6_nbr_get_ll(nbr), UIP_LLADDR_LEN) != 0) { uip_ds6_nbr_t nbr_data = *nbr; uip_ds6_nbr_rm(nbr); - nbr = uip_ds6_nbr_add(&UIP_IP_BUF->srcipaddr, - (uip_lladdr_t *)&nd6_opt_llao[UIP_ND6_OPT_DATA_OFFSET], 0, NBR_STALE); + nbr = uip_ds6_nbr_add(&UIP_IP_BUF->srcipaddr, &lladdr, 0, NBR_STALE); nbr->reachable = nbr_data.reachable; nbr->sendns = nbr_data.sendns; nbr->nscount = nbr_data.nscount; @@ -859,9 +862,11 @@ ra_input(void) nd6_opt_llao = (uint8_t *) UIP_ND6_OPT_HDR_BUF; nbr = uip_ds6_nbr_lookup(&UIP_IP_BUF->srcipaddr); if(nbr == NULL) { - nbr = uip_ds6_nbr_add(&UIP_IP_BUF->srcipaddr, - (uip_lladdr_t *)&nd6_opt_llao[UIP_ND6_OPT_DATA_OFFSET], - 1, NBR_STALE); + /* Copy link address to a uip_lladdr_t first + * to ensure the second argument to uip_ds6_nbr_add is word-aligned */ + uip_lladdr_t lladdr; + memcpy(&lladdr, &nd6_opt_llao[UIP_ND6_OPT_DATA_OFFSET], UIP_LLADDR_LEN); + nbr = uip_ds6_nbr_add(&UIP_IP_BUF->srcipaddr, &lladdr, 1, NBR_STALE); } else { uip_lladdr_t *lladdr = (uip_lladdr_t *)uip_ds6_nbr_get_ll(nbr); if(nbr->state == NBR_INCOMPLETE) { From fd5b03b76780601e6ad5cb8f9d5025594aeea008 Mon Sep 17 00:00:00 2001 From: sumanpanchal Date: Mon, 20 Apr 2015 20:40:14 +0530 Subject: [PATCH 037/120] WISMOTE external flash driver support --- platform/wismote/Makefile.wismote | 2 +- platform/wismote/contiki-wismote-main.c | 2 +- platform/wismote/dev/xmem.c | 78 +++++++++++++------------ platform/wismote/platform-conf.h | 6 +- 4 files changed, 48 insertions(+), 40 deletions(-) diff --git a/platform/wismote/Makefile.wismote b/platform/wismote/Makefile.wismote index 1cf0b0d9f..fd8da1d21 100644 --- a/platform/wismote/Makefile.wismote +++ b/platform/wismote/Makefile.wismote @@ -7,7 +7,7 @@ CONTIKI_TARGET_SOURCEFILES += contiki-wismote-platform.c \ sky-sensors.c uip-ipchksum.c \ uart1.c slip_uart1.c uart1-putchar.c -ARCH=spi.c i2c.c node-id.c sensors.c cfs-coffee.c sht15.c \ +ARCH=spi.c xmem.c i2c.c node-id.c sensors.c cfs-coffee.c sht15.c \ cc2520.c cc2520-arch.c cc2520-arch-sfd.c \ sky-sensors.c uip-ipchksum.c \ uart1.c slip_uart1.c uart1-putchar.c diff --git a/platform/wismote/contiki-wismote-main.c b/platform/wismote/contiki-wismote-main.c index 5e74a22ee..f8b33d94a 100644 --- a/platform/wismote/contiki-wismote-main.c +++ b/platform/wismote/contiki-wismote-main.c @@ -221,7 +221,7 @@ main(int argc, char **argv) //ds2411_id[2] &= 0xfe; leds_on(LEDS_BLUE); - //xmem_init(); + xmem_init(); leds_off(LEDS_RED); rtimer_init(); diff --git a/platform/wismote/dev/xmem.c b/platform/wismote/dev/xmem.c index d4009f7b0..1e7da66af 100644 --- a/platform/wismote/dev/xmem.c +++ b/platform/wismote/dev/xmem.c @@ -32,13 +32,17 @@ * \file * Device driver for the ST M25P80 40MHz 1Mbyte external memory. * \author - * Björn Grönvall + * Björn Grönvall + * Sumankumar Panchal + * * * Data is written bit inverted (~-operator) to flash so that * unwritten data will read as zeros (UNIX style). */ + #include "contiki.h" +#include #include #include "dev/spi.h" @@ -46,7 +50,6 @@ #include "dev/watchdog.h" #if 0 -#include #define PRINTF(...) printf(__VA_ARGS__) #else #define PRINTF(...) do {} while (0) @@ -72,8 +75,7 @@ write_enable(void) s = splhigh(); SPI_FLASH_ENABLE(); - //FASTSPI_TX(SPI_FLASH_INS_WREN); - //SPI_WAITFORTx_ENDED(); + SPI_WRITE(SPI_FLASH_INS_WREN); SPI_FLASH_DISABLE(); splx(s); @@ -89,11 +91,10 @@ read_status_register(void) s = splhigh(); SPI_FLASH_ENABLE(); - //FASTSPI_TX(SPI_FLASH_INS_RDSR); - //SPI_WAITFORTx_ENDED(); + SPI_WRITE(SPI_FLASH_INS_RDSR); - //FASTSPI_CLEAR_RX(); - //FASTSPI_RX(u); + SPI_FLUSH(); + SPI_READ(u); SPI_FLASH_DISABLE(); splx(s); @@ -110,6 +111,7 @@ wait_ready(void) unsigned u; do { u = read_status_register(); + watchdog_periodic(); } while(u & 0x01); /* WIP=1, write in progress */ return u; } @@ -121,18 +123,18 @@ static void erase_sector(unsigned long offset) { int s; - wait_ready(); + wait_ready(); write_enable(); s = splhigh(); SPI_FLASH_ENABLE(); - //FASTSPI_TX(SPI_FLASH_INS_SE); - //FASTSPI_TX(offset >> 16); /* MSB */ - //FASTSPI_TX(offset >> 8); - //FASTSPI_TX(offset >> 0); /* LSB */ - //SPI_WAITFORTx_ENDED(); + SPI_WRITE_FAST(SPI_FLASH_INS_SE); + SPI_WRITE_FAST(offset >> 16); /* MSB */ + SPI_WRITE_FAST(offset >> 8); + SPI_WRITE_FAST(offset >> 0); /* LSB */ + SPI_WAITFORTx_ENDED(); SPI_FLASH_DISABLE(); splx(s); @@ -144,12 +146,20 @@ erase_sector(unsigned long offset) void xmem_init(void) { + int s; spi_init(); - P4DIR |= BV(FLASH_CS) | BV(FLASH_HOLD) | BV(FLASH_PWR); - P4OUT |= BV(FLASH_PWR); /* P4.3 Output, turn on power! */ + + P4DIR |= BIT0; + /* Release from Deep Power-down */ + s = splhigh(); + SPI_FLASH_ENABLE(); + SPI_WRITE_FAST(SPI_FLASH_INS_RES); + SPI_WAITFORTx_ENDED(); SPI_FLASH_DISABLE(); /* Unselect flash. */ + splx(s); + SPI_FLASH_UNHOLD(); } /*---------------------------------------------------------------------------*/ @@ -159,6 +169,7 @@ xmem_pread(void *_p, int size, unsigned long offset) unsigned char *p = _p; const unsigned char *end = p + size; int s; + wait_ready(); ENERGEST_ON(ENERGEST_TYPE_FLASH_READ); @@ -166,16 +177,16 @@ xmem_pread(void *_p, int size, unsigned long offset) s = splhigh(); SPI_FLASH_ENABLE(); - //FASTSPI_TX(SPI_FLASH_INS_READ); - //FASTSPI_TX(offset >> 16); /* MSB */ - //FASTSPI_TX(offset >> 8); - //FASTSPI_TX(offset >> 0); /* LSB */ - //SPI_WAITFORTx_ENDED(); + SPI_WRITE_FAST(SPI_FLASH_INS_READ); + SPI_WRITE_FAST(offset >> 16); /* MSB */ + SPI_WRITE_FAST(offset >> 8); + SPI_WRITE_FAST(offset >> 0); /* LSB */ + SPI_WAITFORTx_ENDED(); - //FASTSPI_CLEAR_RX(); + SPI_FLUSH(); for(; p < end; p++) { unsigned char u; - //FASTSPI_RX(u); + SPI_READ(u); *p = ~u; } @@ -187,28 +198,27 @@ xmem_pread(void *_p, int size, unsigned long offset) return size; } /*---------------------------------------------------------------------------*/ -static const char * +static const unsigned char * program_page(unsigned long offset, const unsigned char *p, int nbytes) { const unsigned char *end = p + nbytes; int s; wait_ready(); - write_enable(); s = splhigh(); SPI_FLASH_ENABLE(); - // FASTSPI_TX(SPI_FLASH_INS_PP); - //FASTSPI_TX(offset >> 16); /* MSB */ - //FASTSPI_TX(offset >> 8); - //FASTSPI_TX(offset >> 0); /* LSB */ + SPI_WRITE_FAST(SPI_FLASH_INS_PP); + SPI_WRITE_FAST(offset >> 16); /* MSB */ + SPI_WRITE_FAST(offset >> 8); + SPI_WRITE_FAST(offset >> 0); /* LSB */ for(; p < end; p++) { - //FASTSPI_TX(~*p); + SPI_WRITE_FAST(~*p); } - //SPI_WAITFORTx_ENDED(); + SPI_WAITFORTx_ENDED(); SPI_FLASH_DISABLE(); splx(s); @@ -224,7 +234,7 @@ xmem_pwrite(const void *_buf, int size, unsigned long addr) unsigned long i, next_page; ENERGEST_ON(ENERGEST_TYPE_FLASH_WRITE); - + for(i = addr; i < end;) { next_page = (i | 0xff) + 1; if(next_page > end) { @@ -254,14 +264,10 @@ xmem_erase(long size, unsigned long addr) return -1; } - watchdog_stop(); - for (; addr < end; addr += XMEM_ERASE_UNIT_SIZE) { erase_sector(addr); } - watchdog_start(); - return size; } /*---------------------------------------------------------------------------*/ diff --git a/platform/wismote/platform-conf.h b/platform/wismote/platform-conf.h index 18fe67de5..e13ed62c0 100644 --- a/platform/wismote/platform-conf.h +++ b/platform/wismote/platform-conf.h @@ -124,8 +124,10 @@ typedef unsigned long off_t; /* Enable/disable flash access to the SPI bus (active low). */ -#define SPI_FLASH_ENABLE() //( P4OUT &= ~BV(FLASH_CS) ) -#define SPI_FLASH_DISABLE() //( P4OUT |= BV(FLASH_CS) ) + /* ENABLE CSn (active low) */ +#define SPI_FLASH_ENABLE() do{ UCB0CTL1 &= ~UCSWRST; clock_delay(5); P4OUT &= ~BIT0;clock_delay(5);}while(0) + /* DISABLE CSn (active low) */ +#define SPI_FLASH_DISABLE() do{clock_delay(5);UCB0CTL1 |= UCSWRST;clock_delay(1); P4OUT |= BIT0;clock_delay(5);}while(0) #define SPI_FLASH_HOLD() // ( P4OUT &= ~BV(FLASH_HOLD) ) #define SPI_FLASH_UNHOLD() //( P4OUT |= BV(FLASH_HOLD) ) From 9b77aac5426cac86d44150441a3131e4d7051151 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Moritz=20=27Morty=27=20Str=C3=BCbe?= Date: Fri, 2 Nov 2012 16:56:11 +0100 Subject: [PATCH 038/120] Add function etimer_reset_set. This new function is similar to reset, but allows to also set a new timeout. Thus long-term accuracy with changing timeouts is now possible. --- core/sys/etimer.c | 8 ++++++++ core/sys/etimer.h | 13 +++++++++++++ 2 files changed, 21 insertions(+) diff --git a/core/sys/etimer.c b/core/sys/etimer.c index 719401115..17ac74285 100644 --- a/core/sys/etimer.c +++ b/core/sys/etimer.c @@ -181,6 +181,14 @@ etimer_set(struct etimer *et, clock_time_t interval) } /*---------------------------------------------------------------------------*/ void +etimer_reset_with_new_interval(struct etimer *et, clock_time_t interval) +{ + timer_reset(&et->timer); + et->timer.interval = interval; + add_timer(et); +} +/*---------------------------------------------------------------------------*/ +void etimer_reset(struct etimer *et) { timer_reset(&et->timer); diff --git a/core/sys/etimer.h b/core/sys/etimer.h index b1f57b01a..ebbcfc7fd 100644 --- a/core/sys/etimer.h +++ b/core/sys/etimer.h @@ -114,6 +114,19 @@ CCIF void etimer_set(struct etimer *et, clock_time_t interval); */ CCIF void etimer_reset(struct etimer *et); +/** + * \brief Reset an event timer with a new interval. + * \param et A pointer to the event timer. + * \param interval The interval before the timer expires. + * + * This function very similar to etimer_reset. Opposed to + * etimer_reset it is possible to change the timout. + * This allows accurate, non-periodic timers without drift. + * + * \sa etimer_reset() + */ +void etimer_reset_with_new_interval(struct etimer *et, clock_time_t interval); + /** * \brief Restart an event timer from the current point in time * \param et A pointer to the event timer. From 52006aec0f4b05bc12b94041d43a1b2d689ae06b Mon Sep 17 00:00:00 2001 From: Adam Dunkels Date: Wed, 26 Aug 2015 15:26:32 +0200 Subject: [PATCH 039/120] Simulation test with more RPL nodes than the network can handle that attempt to access a remote HTTP server. After completing their connection, they go to feather mode, freeing up route table entries in the network, to let more nodes reach the HTTP server --- .../21-large-rpl/01-cooja-http-socket-50.csc | 1006 +++++++++++++++++ regression-tests/21-large-rpl/Makefile | 1 + .../21-large-rpl/code/node/Makefile | 7 + .../21-large-rpl/code/node/client.c | 103 ++ .../21-large-rpl/code/node/project-conf.h | 6 + .../21-large-rpl/code/router/Makefile | 5 + .../21-large-rpl/code/router/project-conf.h | 9 + .../21-large-rpl/code/router/router.c | 27 + regression-tests/21-large-rpl/testscript.js | 78 ++ 9 files changed, 1242 insertions(+) create mode 100644 regression-tests/21-large-rpl/01-cooja-http-socket-50.csc create mode 100644 regression-tests/21-large-rpl/Makefile create mode 100644 regression-tests/21-large-rpl/code/node/Makefile create mode 100644 regression-tests/21-large-rpl/code/node/client.c create mode 100644 regression-tests/21-large-rpl/code/node/project-conf.h create mode 100644 regression-tests/21-large-rpl/code/router/Makefile create mode 100644 regression-tests/21-large-rpl/code/router/project-conf.h create mode 100644 regression-tests/21-large-rpl/code/router/router.c create mode 100644 regression-tests/21-large-rpl/testscript.js diff --git a/regression-tests/21-large-rpl/01-cooja-http-socket-50.csc b/regression-tests/21-large-rpl/01-cooja-http-socket-50.csc new file mode 100644 index 000000000..48b6f9718 --- /dev/null +++ b/regression-tests/21-large-rpl/01-cooja-http-socket-50.csc @@ -0,0 +1,1006 @@ + + + [APPS_DIR]/mrm + [APPS_DIR]/mspsim + [APPS_DIR]/avrora + [APPS_DIR]/serial_socket + [APPS_DIR]/collect-view + [APPS_DIR]/powertracker + + My simulation + 2.0 + generated + 1000000 + + org.contikios.cooja.radiomediums.UDGM + 50.0 + 100.0 + 1.0 + 1.0 + + + 40000 + + + org.contikios.cooja.contikimote.ContikiMoteType + mtype812 + router TARGET=cooja-ip64 + [CONTIKI_DIR]/regression-tests/21-large-rpl/code/router/router.c + echo make clean TARGET=cooja-ip64 +make router.cooja-ip64 TARGET=cooja-ip64 + org.contikios.cooja.interfaces.Position + org.contikios.cooja.interfaces.Battery + org.contikios.cooja.contikimote.interfaces.ContikiVib + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + org.contikios.cooja.contikimote.interfaces.ContikiRS232 + org.contikios.cooja.contikimote.interfaces.ContikiBeeper + org.contikios.cooja.interfaces.RimeAddress + org.contikios.cooja.contikimote.interfaces.ContikiIPAddress + org.contikios.cooja.contikimote.interfaces.ContikiRadio + org.contikios.cooja.contikimote.interfaces.ContikiButton + org.contikios.cooja.contikimote.interfaces.ContikiPIR + org.contikios.cooja.contikimote.interfaces.ContikiClock + org.contikios.cooja.contikimote.interfaces.ContikiLED + org.contikios.cooja.contikimote.interfaces.ContikiCFS + org.contikios.cooja.interfaces.Mote2MoteRelations + org.contikios.cooja.interfaces.MoteAttributes + false + + + org.contikios.cooja.contikimote.ContikiMoteType + mtype833 + client + [CONTIKI_DIR]/regression-tests/21-large-rpl/code/node/client.c + echo make clean TARGET=cooja +make client.cooja TARGET=cooja + org.contikios.cooja.interfaces.Position + org.contikios.cooja.interfaces.Battery + org.contikios.cooja.contikimote.interfaces.ContikiVib + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + org.contikios.cooja.contikimote.interfaces.ContikiRS232 + org.contikios.cooja.contikimote.interfaces.ContikiBeeper + org.contikios.cooja.interfaces.RimeAddress + org.contikios.cooja.contikimote.interfaces.ContikiIPAddress + org.contikios.cooja.contikimote.interfaces.ContikiRadio + org.contikios.cooja.contikimote.interfaces.ContikiButton + org.contikios.cooja.contikimote.interfaces.ContikiPIR + org.contikios.cooja.contikimote.interfaces.ContikiClock + org.contikios.cooja.contikimote.interfaces.ContikiLED + org.contikios.cooja.contikimote.interfaces.ContikiCFS + org.contikios.cooja.interfaces.Mote2MoteRelations + org.contikios.cooja.interfaces.MoteAttributes + false + + + + org.contikios.cooja.interfaces.Position + 55.719691912311305 + 37.8697579181178 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 1 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype812 + + + + org.contikios.cooja.interfaces.Position + 33.16398380436391 + 28.280100446725353 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 2 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype833 + + + + org.contikios.cooja.interfaces.Position + 64.7333702437188 + 86.25343669492709 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 3 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype833 + + + + org.contikios.cooja.interfaces.Position + 34.382213480997194 + 87.3651616010611 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 4 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype833 + + + + org.contikios.cooja.interfaces.Position + 11.332821198243948 + 72.43057435800137 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 5 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype833 + + + + org.contikios.cooja.interfaces.Position + 95.94512295362799 + 71.39152480287795 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 6 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype833 + + + + org.contikios.cooja.interfaces.Position + 34.51186307444599 + 59.489544081261435 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 7 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype833 + + + + org.contikios.cooja.interfaces.Position + 63.02063881741806 + 6.725737893296902 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 8 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype833 + + + + org.contikios.cooja.interfaces.Position + 67.16488021441937 + 54.31377260130722 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 9 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype833 + + + + org.contikios.cooja.interfaces.Position + 9.784878122518437 + 81.00283052134533 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 10 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype833 + + + + org.contikios.cooja.interfaces.Position + 32.10074353933871 + 33.071992737644926 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 11 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype833 + + + + org.contikios.cooja.interfaces.Position + 91.82438265710196 + 51.23700415853406 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 12 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype833 + + + + org.contikios.cooja.interfaces.Position + 21.195462105769337 + 82.08222111459202 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 13 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype833 + + + + org.contikios.cooja.interfaces.Position + 55.73823429127498 + 69.24022125144269 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 14 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype833 + + + + org.contikios.cooja.interfaces.Position + 69.71587306768029 + 57.37071024636343 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 15 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype833 + + + + org.contikios.cooja.interfaces.Position + 66.69012609363311 + 68.93236248473207 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 16 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype833 + + + + org.contikios.cooja.interfaces.Position + 66.84314708507073 + 32.20129384563065 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 17 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype833 + + + + org.contikios.cooja.interfaces.Position + 75.11303983172269 + 17.658699966744983 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 18 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype833 + + + + org.contikios.cooja.interfaces.Position + 27.078612584793017 + 97.3945649089831 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 19 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype833 + + + + org.contikios.cooja.interfaces.Position + 63.37580990146204 + 30.66028070022273 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 20 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype833 + + + + org.contikios.cooja.interfaces.Position + 3.866240569639967 + 58.00787820279949 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 21 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype833 + + + + org.contikios.cooja.interfaces.Position + 57.433437740562496 + 12.398752526430156 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 22 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype833 + + + + org.contikios.cooja.interfaces.Position + 15.784041174017371 + 74.78102139434115 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 23 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype833 + + + + org.contikios.cooja.interfaces.Position + 40.67175327199246 + 52.46247320344863 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 24 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype833 + + + + org.contikios.cooja.interfaces.Position + 38.43045934512656 + 90.56311604010655 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 25 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype833 + + + + org.contikios.cooja.interfaces.Position + 0.6068936092190724 + 21.344443973676874 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 26 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype833 + + + + org.contikios.cooja.interfaces.Position + 60.36615377515271 + 86.59995801287768 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 27 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype833 + + + + org.contikios.cooja.interfaces.Position + 14.39476252794466 + 9.985669338749425 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 28 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype833 + + + + org.contikios.cooja.interfaces.Position + 95.14872168386105 + 45.936172484167905 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 29 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype833 + + + + org.contikios.cooja.interfaces.Position + 61.80198040806143 + 14.891226267286084 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 30 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype833 + + + + org.contikios.cooja.interfaces.Position + 32.11354654266005 + 38.51630620185639 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 31 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype833 + + + + org.contikios.cooja.interfaces.Position + 37.711371799794335 + 18.547318360664853 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 32 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype833 + + + + org.contikios.cooja.interfaces.Position + 58.34301426026205 + 95.91480486240545 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 33 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype833 + + + + org.contikios.cooja.interfaces.Position + 20.456374070589078 + 13.31295283913667 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 34 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype833 + + + + org.contikios.cooja.interfaces.Position + 4.789895861056081 + 41.25598476863351 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 35 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype833 + + + + org.contikios.cooja.interfaces.Position + 22.62971444227585 + 28.645182034255324 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 36 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype833 + + + + org.contikios.cooja.interfaces.Position + 60.457329857492034 + 24.40308696160821 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 37 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype833 + + + + org.contikios.cooja.interfaces.Position + 4.1096555252476685 + 27.46211937285302 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 38 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype833 + + + + org.contikios.cooja.interfaces.Position + 87.008751083046 + 87.28519710099914 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 39 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype833 + + + + org.contikios.cooja.interfaces.Position + 86.65741005585366 + 99.07543884063683 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 40 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype833 + + + + org.contikios.cooja.interfaces.Position + 96.56473544385348 + 56.74413810869915 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 41 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype833 + + + + org.contikios.cooja.interfaces.Position + 63.1598358033005 + 41.18799873508732 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 42 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype833 + + + + org.contikios.cooja.interfaces.Position + 14.556676924656397 + 98.24257311359364 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 43 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype833 + + + + org.contikios.cooja.interfaces.Position + 34.70728168935242 + 31.89373622088234 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 44 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype833 + + + + org.contikios.cooja.interfaces.Position + 91.35334037714965 + 83.59007856757782 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 45 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype833 + + + + org.contikios.cooja.interfaces.Position + 57.18004847306107 + 1.5650913544456135 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 46 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype833 + + + + org.contikios.cooja.interfaces.Position + 97.14688174768989 + 29.613231105554448 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 47 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype833 + + + + org.contikios.cooja.interfaces.Position + 12.528733239940715 + 23.28442121821601 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 48 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype833 + + + + org.contikios.cooja.interfaces.Position + 97.65915972314534 + 57.204021167070664 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 49 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype833 + + + + org.contikios.cooja.interfaces.Position + 94.8211477197945 + 15.57384229665848 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 50 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype833 + + + + org.contikios.cooja.interfaces.Position + 69.1730393490499 + 35.900983349410275 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 51 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype833 + + + + org.contikios.cooja.plugins.SimControl + 280 + 3 + 160 + 606 + 15 + + + org.contikios.cooja.plugins.Visualizer + + true + org.contikios.cooja.plugins.skins.IDVisualizerSkin + org.contikios.cooja.plugins.skins.GridVisualizerSkin + org.contikios.cooja.plugins.skins.MoteTypeVisualizerSkin + org.contikios.cooja.plugins.skins.LEDVisualizerSkin + org.contikios.cooja.plugins.skins.UDGMVisualizerSkin + 2.927428245448204 0.0 0.0 2.927428245448204 50.166589953058406 9.691034635016393 + + 401 + 0 + 368 + 29 + 27 + + + org.contikios.cooja.plugins.LogListener + + close + + + + 685 + 2 + 429 + 34 + 307 + + + org.contikios.cooja.plugins.ScriptRunner + + [CONTIKI_DIR]/regression-tests/21-large-rpl/testscript.js + true + + 960 + 1 + 682 + 528 + 192 + + + org.contikios.cooja.serialsocket.SerialSocketServer + 0 + + 60001 + true + + 362 + 4 + 116 + 234 + 101 + + + diff --git a/regression-tests/21-large-rpl/Makefile b/regression-tests/21-large-rpl/Makefile new file mode 100644 index 000000000..272bc7da1 --- /dev/null +++ b/regression-tests/21-large-rpl/Makefile @@ -0,0 +1 @@ +include ../Makefile.simulation-test diff --git a/regression-tests/21-large-rpl/code/node/Makefile b/regression-tests/21-large-rpl/code/node/Makefile new file mode 100644 index 000000000..cbaa72ef7 --- /dev/null +++ b/regression-tests/21-large-rpl/code/node/Makefile @@ -0,0 +1,7 @@ +CONTIKI=../../../.. + +MODULES += core/net/http-socket + +CFLAGS+=-DPROJECT_CONF_H=\"project-conf.h\" + +include $(CONTIKI)/Makefile.include diff --git a/regression-tests/21-large-rpl/code/node/client.c b/regression-tests/21-large-rpl/code/node/client.c new file mode 100644 index 000000000..386f18529 --- /dev/null +++ b/regression-tests/21-large-rpl/code/node/client.c @@ -0,0 +1,103 @@ +#include "contiki-net.h" +#include "http-socket.h" +#include "ip64-addr.h" +#include "dev/leds.h" +#include "rpl.h" + +#include + +static struct http_socket s; +static int bytes_received = 0; +static int restarts; +static struct ctimer reconnect_timer; + +static void callback(struct http_socket *s, void *ptr, + http_socket_event_t e, + const uint8_t *data, uint16_t datalen); + +/*---------------------------------------------------------------------------*/ +PROCESS(http_example_process, "HTTP Example"); +AUTOSTART_PROCESSES(&http_example_process); +/*---------------------------------------------------------------------------*/ +static void +reconnect(void *dummy) +{ + rpl_set_mode(RPL_MODE_MESH); + http_socket_get(&s, "http://www.contiki-os.org/", 0, 0, + callback, NULL); +} +/*---------------------------------------------------------------------------*/ +static void +restart(void) +{ + int scale; + restarts++; + printf("restart %d\n", restarts); + + scale = restarts; + if(scale > 5) { + scale = 5; + } + ctimer_set(&reconnect_timer, random_rand() % ((CLOCK_SECOND * 10) << scale), + reconnect, NULL); +} +/*---------------------------------------------------------------------------*/ +static void +callback(struct http_socket *s, void *ptr, + http_socket_event_t e, + const uint8_t *data, uint16_t datalen) +{ + if(e == HTTP_SOCKET_ERR) { + printf("HTTP socket error\n"); + } else if(e == HTTP_SOCKET_TIMEDOUT) { + printf("HTTP socket error: timed out\n"); + restart(); + } else if(e == HTTP_SOCKET_ABORTED) { + printf("HTTP socket error: aborted\n"); + restart(); + } else if(e == HTTP_SOCKET_HOSTNAME_NOT_FOUND) { + printf("HTTP socket error: hostname not found\n"); + restart(); + } else if(e == HTTP_SOCKET_CLOSED) { + if(bytes_received > 0) { + printf("HTTP socket closed, %d bytes received\n", bytes_received); + leds_off(LEDS_RED); + rpl_set_mode(RPL_MODE_FEATHER); + } else { + restart(); + } + } else if(e == HTTP_SOCKET_DATA) { + bytes_received += datalen; + printf("HTTP socket received %d bytes of data\n", datalen); + } +} +/*---------------------------------------------------------------------------*/ +PROCESS_THREAD(http_example_process, ev, data) +{ + static struct etimer et; + uip_ip4addr_t ip4addr; + uip_ip6addr_t ip6addr; + + PROCESS_BEGIN(); + + uip_ipaddr(&ip4addr, 8,8,8,8); + ip64_addr_4to6(&ip4addr, &ip6addr); + uip_nameserver_update(&ip6addr, UIP_NAMESERVER_INFINITE_LIFETIME); + + etimer_set(&et, CLOCK_SECOND * 20); + PROCESS_WAIT_EVENT_UNTIL(etimer_expired(&et)); + + http_socket_init(&s); + http_socket_get(&s, "http://www.contiki-os.org/", 0, 0, + callback, NULL); + leds_on(LEDS_RED); + restarts = 0; + etimer_set(&et, CLOCK_SECOND); + while(1) { + PROCESS_WAIT_EVENT_UNTIL(etimer_expired(&et)); + etimer_reset(&et); + } + + PROCESS_END(); +} +/*---------------------------------------------------------------------------*/ diff --git a/regression-tests/21-large-rpl/code/node/project-conf.h b/regression-tests/21-large-rpl/code/node/project-conf.h new file mode 100644 index 000000000..c8cfeb645 --- /dev/null +++ b/regression-tests/21-large-rpl/code/node/project-conf.h @@ -0,0 +1,6 @@ +#define QUEUEBUF_CONF_STATS 1 +#define RESOLV_CONF_SUPPORTS_MDNS 0 +#define COOJA_MTARCH_STACKSIZE 4096 + +#define UIP_CONF_MAX_ROUTES 3 +#define NBR_TABLE_CONF_MAX_NEIGHBORS 3 diff --git a/regression-tests/21-large-rpl/code/router/Makefile b/regression-tests/21-large-rpl/code/router/Makefile new file mode 100644 index 000000000..a482f0a6a --- /dev/null +++ b/regression-tests/21-large-rpl/code/router/Makefile @@ -0,0 +1,5 @@ +CONTIKI=../../../.. + +CFLAGS+=-DPROJECT_CONF_H=\"project-conf.h\" + +include $(CONTIKI)/Makefile.include diff --git a/regression-tests/21-large-rpl/code/router/project-conf.h b/regression-tests/21-large-rpl/code/router/project-conf.h new file mode 100644 index 000000000..2fa5e2977 --- /dev/null +++ b/regression-tests/21-large-rpl/code/router/project-conf.h @@ -0,0 +1,9 @@ +#define QUEUEBUF_CONF_STATS 1 +#define RESOLV_CONF_SUPPORTS_MDNS 0 +#define COOJA_MTARCH_STACKSIZE 4096 + +#define UIP_CONF_MAX_ROUTES 8 +#define NBR_TABLE_CONF_MAX_NEIGHBORS 8 + +/*#define RPL_CONF_DEFAULT_LIFETIME_UNIT 10 + #define RPL_CONF_DEFAULT_LIFETIME 10*/ diff --git a/regression-tests/21-large-rpl/code/router/router.c b/regression-tests/21-large-rpl/code/router/router.c new file mode 100644 index 000000000..391b5038b --- /dev/null +++ b/regression-tests/21-large-rpl/code/router/router.c @@ -0,0 +1,27 @@ +#include "contiki.h" +#include "contiki-net.h" +#include "ip64.h" +#include "net/netstack.h" + +/*---------------------------------------------------------------------------*/ +PROCESS(router_node_process, "Router node"); +AUTOSTART_PROCESSES(&router_node_process); +/*---------------------------------------------------------------------------*/ +PROCESS_THREAD(router_node_process, ev, data) +{ + PROCESS_BEGIN(); + + /* Set us up as a RPL root node. */ + rpl_dag_root_init_dag(); + + /* Initialize the IP64 module so we'll start translating packets */ + ip64_init(); + + /* ... and do nothing more. */ + while(1) { + PROCESS_WAIT_EVENT(); + } + + PROCESS_END(); +} +/*---------------------------------------------------------------------------*/ diff --git a/regression-tests/21-large-rpl/testscript.js b/regression-tests/21-large-rpl/testscript.js new file mode 100644 index 000000000..0c23bceef --- /dev/null +++ b/regression-tests/21-large-rpl/testscript.js @@ -0,0 +1,78 @@ + +TIMEOUT(2400000); /* 40 minutes */ + +var NR_FEATHERS = mote.getSimulation().getMotesCount() - 1; + +/* conf */ +var travis = java.lang.System.getenv().get("TRAVIS"); +if (travis == null) { + /* Instant Contiki */ + CMD_TUNNEL = "echo '-vj' > ~/.slirprc && make Connect.class && java Connect 'nc localhost 60001' 'script -t -f -c slirp'"; + CMD_PING = "ping -c 5 8.8.8.8"; + CMD_DIR = "../../wpcapslip"; +} else { + /* Travis */ + CMD_TUNNEL = "cd $TRAVIS_BUILD_DIR/tools/wpcapslip && sudo apt-get install slirp && echo '-vj' > ~/.slirprc && make Connect.class && java Connect 'nc localhost 60001' 'script -t -f -c slirp'"; + CMD_PING = "ping -c 5 8.8.8.8"; + CMD_DIR = "."; +} + +/* delay */ +GENERATE_MSG(1000, "continue"); +YIELD_THEN_WAIT_UNTIL(msg.equals("continue")); + +/* realtime speed */ +sim.setSpeedLimit(2.0); + +/* tunnel interface */ +log.log("opening tunnel interface: " + CMD_TUNNEL + "\n"); +launcher = new java.lang.ProcessBuilder["(java.lang.String[])"](['sh','-c',CMD_TUNNEL]); +launcher.directory(new java.io.File(CMD_DIR)); +launcher.redirectErrorStream(true); +tunProcess = launcher.start(); +tunRunnable = new Object(); +tunRunnable.run = function() { + var stdIn = new java.io.BufferedReader(new java.io.InputStreamReader(tunProcess.getInputStream())); + while ((line = stdIn.readLine()) != null) { + if (line != null && !line.trim().equals("")) { + //log.log("TUN> " + line + "\n"); + } + } + tunProcess.destroy(); +} +new java.lang.Thread(new java.lang.Runnable(tunRunnable)).start(); + +GENERATE_MSG(1000, "continue"); +YIELD_THEN_WAIT_UNTIL(msg.equals("continue")); + +/* ping */ +log.log("pinging: " + CMD_PING + "\n"); +launcher = new java.lang.ProcessBuilder["(java.lang.String[])"](['sh','-c',CMD_PING]); +launcher.directory(new java.io.File(CMD_DIR)); +launcher.redirectErrorStream(true); +tunProcess = launcher.start(); +tunRunnable = new Object(); +tunRunnable.run = function() { + var stdIn = new java.io.BufferedReader(new java.io.InputStreamReader(tunProcess.getInputStream())); + while ((line = stdIn.readLine()) != null) { + if (line != null && !line.trim().equals("")) { + log.log("PING> " + line + "\n"); + } + } + tunProcess.destroy(); +} +new java.lang.Thread(new java.lang.Runnable(tunRunnable)).start(); + +var completed = {}; +while(Object.keys(completed).length < NR_FEATHERS) { + if (!msg.startsWith("#L") && !msg.startsWith("E")) { + //log.log(mote + ": " + msg + "\n"); + } + if (id != 1 && msg.startsWith("HTTP socket closed")) { + completed[id] = id; + log.log("Data compelete " + id + ", heard " + Object.keys(completed).length + " in total\n"); + } + YIELD(); +} + +log.testOK(); From 32511dc51235b3d8fe97e90ec9dba97e38820b14 Mon Sep 17 00:00:00 2001 From: Adam Dunkels Date: Wed, 26 Aug 2015 16:45:43 +0200 Subject: [PATCH 040/120] Enable the rpl-large test in travis --- .travis.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.travis.yml b/.travis.yml index db506cd03..98f98edff 100644 --- a/.travis.yml +++ b/.travis.yml @@ -103,6 +103,7 @@ env: - BUILD_TYPE='collect' - BUILD_TYPE='collect-lossy' - BUILD_TYPE='rpl' + - BUILD_TYPE='large-rpl' - BUILD_TYPE='rime' - BUILD_TYPE='ipv6' - BUILD_TYPE='ip64' MAKE_TARGETS='cooja' From 9cd84563cba597903f0eaea06f0f1ef3b6d2b75e Mon Sep 17 00:00:00 2001 From: Adam Dunkels Date: Wed, 26 Aug 2015 16:47:10 +0200 Subject: [PATCH 041/120] Send a no-path DAO when becoming feather mode, so that the network can drop routes to us, which are no longer needed --- core/net/rpl/rpl.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/core/net/rpl/rpl.c b/core/net/rpl/rpl.c index dc66528d3..e4724408e 100644 --- a/core/net/rpl/rpl.c +++ b/core/net/rpl/rpl.c @@ -89,11 +89,17 @@ rpl_set_mode(enum rpl_mode m) } else if(m == RPL_MODE_FEATHER) { PRINTF("RPL: switching to feather mode\n"); - mode = m; if(default_instance != NULL) { + PRINTF("rpl_set_mode: RPL sending DAO with zero lifetime\n"); + if(default_instance->current_dag != NULL) { + dao_output(default_instance->current_dag->preferred_parent, RPL_ZERO_LIFETIME); + } rpl_cancel_dao(default_instance); + } else { + PRINTF("rpl_set_mode: no default instance\n"); } + mode = m; } else { mode = m; } From 2b549f37890bed8aa0e3414a9239c1b13e542dfc Mon Sep 17 00:00:00 2001 From: Adam Dunkels Date: Wed, 26 Aug 2015 16:48:34 +0200 Subject: [PATCH 042/120] Bugfix: need to explictly drop RPL packets by setting uip_len = 0, otherwise those packets are forwarded, with the wrong link layer address as a sender, causing the mesh to create false routes --- core/net/rpl/rpl-icmp6.c | 34 +++++++++++++++++++--------------- 1 file changed, 19 insertions(+), 15 deletions(-) diff --git a/core/net/rpl/rpl-icmp6.c b/core/net/rpl/rpl-icmp6.c index 880b7986c..0a4488d13 100644 --- a/core/net/rpl/rpl-icmp6.c +++ b/core/net/rpl/rpl-icmp6.c @@ -256,7 +256,8 @@ dio_input(void) PRINTF(", "); PRINTLLADDR((uip_lladdr_t *)packetbuf_addr(PACKETBUF_ADDR_SENDER)); PRINTF("\n"); - return; + + goto discard; } } else { PRINTF("RPL: Neighbor already in neighbor cache\n"); @@ -306,7 +307,7 @@ dio_input(void) if(len + i > buffer_length) { PRINTF("RPL: Invalid DIO packet\n"); RPL_STAT(rpl_stats.malformed_msgs++); - return; + goto discard; } PRINTF("RPL: DIO option %u, length: %u\n", subopt_type, len - 2); @@ -316,7 +317,7 @@ dio_input(void) if(len < 6) { PRINTF("RPL: Invalid DAG MC, len = %d\n", len); RPL_STAT(rpl_stats.malformed_msgs++); - return; + goto discard; } dio.mc.type = buffer[i + 2]; dio.mc.flags = buffer[i + 3] << 1; @@ -342,14 +343,14 @@ dio_input(void) dio.mc.obj.energy.energy_est = buffer[i + 7]; } else { PRINTF("RPL: Unhandled DAG MC type: %u\n", (unsigned)dio.mc.type); - return; + goto discard; } break; case RPL_OPTION_ROUTE_INFO: if(len < 9) { PRINTF("RPL: Invalid destination prefix option, len = %d\n", len); RPL_STAT(rpl_stats.malformed_msgs++); - return; + goto discard; } /* The flags field includes the preference value. */ @@ -365,7 +366,7 @@ dio_input(void) } else { PRINTF("RPL: Invalid route info option, len = %d\n", len); RPL_STAT(rpl_stats.malformed_msgs++); - return; + goto discard; } break; @@ -373,7 +374,7 @@ dio_input(void) if(len != 16) { PRINTF("RPL: Invalid DAG configuration option, len = %d\n", len); RPL_STAT(rpl_stats.malformed_msgs++); - return; + goto discard; } /* Path control field not yet implemented - at i + 2 */ @@ -395,7 +396,7 @@ dio_input(void) if(len != 32) { PRINTF("RPL: Invalid DAG prefix info, len != 32\n"); RPL_STAT(rpl_stats.malformed_msgs++); - return; + goto discard; } dio.prefix_info.length = buffer[i + 2]; dio.prefix_info.flags = buffer[i + 3]; @@ -418,6 +419,7 @@ dio_input(void) rpl_process_dio(&from, &dio); + discard: uip_clear_buf(); } /*---------------------------------------------------------------------------*/ @@ -622,7 +624,7 @@ dao_input(void) if(instance == NULL) { PRINTF("RPL: Ignoring a DAO for an unknown RPL instance(%u)\n", instance_id); - return; + goto discard; } lifetime = instance->default_lifetime; @@ -637,7 +639,7 @@ dao_input(void) if(flags & RPL_DAO_D_FLAG) { if(memcmp(&dag->dag_id, &buffer[pos], sizeof(dag->dag_id))) { PRINTF("RPL: Ignoring a DAO for a DAG different from ours\n"); - return; + goto discard; } pos += 16; } @@ -658,7 +660,7 @@ dao_input(void) DAG_RANK(parent->rank, instance), DAG_RANK(dag->rank, instance)); parent->rank = INFINITE_RANK; parent->flags |= RPL_PARENT_FLAG_UPDATED; - return; + goto discard; } /* If we get the DAO from our parent, we also have a loop. */ @@ -666,7 +668,7 @@ dao_input(void) PRINTF("RPL: Loop detected when receiving a unicast DAO from our parent\n"); parent->rank = INFINITE_RANK; parent->flags |= RPL_PARENT_FLAG_UPDATED; - return; + goto discard; } } @@ -743,7 +745,7 @@ dao_input(void) dao_ack_output(instance, &dao_sender_addr, sequence); } } - return; + goto discard; } PRINTF("RPL: adding DAO route\n"); @@ -765,7 +767,7 @@ dao_input(void) PRINTF(", "); PRINTLLADDR((uip_lladdr_t *)packetbuf_addr(PACKETBUF_ADDR_SENDER)); PRINTF("\n"); - return; + goto discard; } } else { PRINTF("RPL: Neighbor already in neighbor cache\n"); @@ -777,7 +779,7 @@ dao_input(void) if(rep == NULL) { RPL_STAT(rpl_stats.mem_overflows++); PRINTF("RPL: Could not add a route after receiving a DAO\n"); - return; + goto discard; } rep->state.lifetime = RPL_LIFETIME(instance, lifetime); @@ -801,6 +803,8 @@ fwd_dao: dao_ack_output(instance, &dao_sender_addr, sequence); } } + + discard: uip_clear_buf(); } /*---------------------------------------------------------------------------*/ From e859ad8e0502d5aff89ad278ed7fd15cc7bfaf9f Mon Sep 17 00:00:00 2001 From: Adam Dunkels Date: Wed, 26 Aug 2015 22:10:53 +0200 Subject: [PATCH 043/120] Need to increase the Cooja serial buffer size to accomodate the traffic --- platform/cooja/dev/rs232.c | 2 +- .../contikios/cooja/contikimote/interfaces/ContikiRS232.java | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/platform/cooja/dev/rs232.c b/platform/cooja/dev/rs232.c index a52b9a130..51ee5b6a9 100644 --- a/platform/cooja/dev/rs232.c +++ b/platform/cooja/dev/rs232.c @@ -37,7 +37,7 @@ const struct simInterface rs232_interface; -#define SERIAL_BUF_SIZE 1024 +#define SERIAL_BUF_SIZE 2048 // COOJA variables char simSerialReceivingData[SERIAL_BUF_SIZE]; diff --git a/tools/cooja/java/org/contikios/cooja/contikimote/interfaces/ContikiRS232.java b/tools/cooja/java/org/contikios/cooja/contikimote/interfaces/ContikiRS232.java index 2607bc1ea..e8e7589e5 100644 --- a/tools/cooja/java/org/contikios/cooja/contikimote/interfaces/ContikiRS232.java +++ b/tools/cooja/java/org/contikios/cooja/contikimote/interfaces/ContikiRS232.java @@ -71,7 +71,7 @@ public class ContikiRS232 extends SerialUI implements ContikiMoteInterface, Poll private ContikiMote mote = null; private VarMemory moteMem = null; - static final int SERIAL_BUF_SIZE = 1024; /* rs232.c:40 */ + static final int SERIAL_BUF_SIZE = 2048; /* rs232.c:40 */ /** * Creates an interface to the RS232 at mote. From 7c2bff0462e088ab2f4681c31f0db5712ecf0e5e Mon Sep 17 00:00:00 2001 From: Joakim Eriksson Date: Wed, 26 Aug 2015 18:17:29 +0200 Subject: [PATCH 044/120] added debug print for nbr-table-module --- core/net/nbr-table.c | 50 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 50 insertions(+) diff --git a/core/net/nbr-table.c b/core/net/nbr-table.c index 4c9fab4fb..6b990a020 100644 --- a/core/net/nbr-table.c +++ b/core/net/nbr-table.c @@ -40,6 +40,18 @@ #include "lib/list.h" #include "net/nbr-table.h" +#define DEBUG 0 +#if DEBUG +#include +#include "sys/ctimer.h" +static void handle_periodic_timer(void *ptr); +static struct ctimer periodic_timer; +static uint8_t initialized = 0; +#define PRINTF(...) printf(__VA_ARGS__) +#else +#define PRINTF(...) +#endif + /* List of link-layer addresses of the neighbors, used as key in the tables */ typedef struct nbr_table_key { struct nbr_table_key *next; @@ -143,6 +155,7 @@ static int nbr_set_bit(uint8_t *bitmap, nbr_table_t *table, nbr_table_item_t *item, int value) { int item_index = index_from_item(table, item); + if(table != NULL && item_index != -1) { if(value) { bitmap[item_index] |= 1 << table->index; @@ -229,6 +242,13 @@ nbr_table_allocate(void) int nbr_table_register(nbr_table_t *table, nbr_table_callback *callback) { +#if DEBUG + if(!initialized) { + initialized = 1; + /* schedule a debug printout per minute */ + ctimer_set(&periodic_timer, CLOCK_SECOND * 60, handle_periodic_timer, NULL); + } +#endif if(num_tables < MAX_NUM_TABLES) { table->index = num_tables++; table->callback = callback; @@ -331,6 +351,10 @@ nbr_table_remove(nbr_table_t *table, void *item) int nbr_table_lock(nbr_table_t *table, void *item) { +#if DEBUG + int i = index_from_item(table, item); + PRINTF("*** Lock %d\n", i); +#endif return nbr_set_bit(locked_map, table, item, 1); } /*---------------------------------------------------------------------------*/ @@ -338,6 +362,10 @@ nbr_table_lock(nbr_table_t *table, void *item) int nbr_table_unlock(nbr_table_t *table, void *item) { +#if DEBUG + int i = index_from_item(table, item); + PRINTF("*** Unlock %d\n", i); +#endif return nbr_set_bit(locked_map, table, item, 0); } /*---------------------------------------------------------------------------*/ @@ -348,3 +376,25 @@ nbr_table_get_lladdr(nbr_table_t *table, const void *item) nbr_table_key_t *key = key_from_item(table, item); return key != NULL ? &key->lladdr : NULL; } +/*---------------------------------------------------------------------------*/ +#if DEBUG +static void +handle_periodic_timer(void *ptr) +{ + int i, j; + /* Printout all neighbors and which tables they are used in */ + PRINTF("NBR TABLE:\n"); + for(i = 0; i < NBR_TABLE_MAX_NEIGHBORS; i++) { + if(used_map[i] > 0) { + PRINTF(" %02d %02d",i , key_from_index(i)->lladdr.u8[LINKADDR_SIZE - 1]); + for(j = 0; j < num_tables; j++) { + PRINTF(" [%d:%d]", (used_map[i] & (1 << j)) != 0, + (locked_map[i] & (1 << j)) != 0); + } + PRINTF("\n"); + } + } + ctimer_reset(&periodic_timer); +} +#endif + From 5dee80a253d4aa09d265f4ce95cc316b98364101 Mon Sep 17 00:00:00 2001 From: Joakim Eriksson Date: Wed, 26 Aug 2015 18:23:06 +0200 Subject: [PATCH 045/120] added locking of nexthop for routes to avoid the risk of nexthop removal --- core/net/ipv6/uip-ds6-route.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/core/net/ipv6/uip-ds6-route.c b/core/net/ipv6/uip-ds6-route.c index 49e3d3588..a5c00d384 100644 --- a/core/net/ipv6/uip-ds6-route.c +++ b/core/net/ipv6/uip-ds6-route.c @@ -367,6 +367,9 @@ uip_ds6_route_add(uip_ipaddr_t *ipaddr, uint8_t length, num_routes++; PRINTF("uip_ds6_route_add num %d\n", num_routes); + + /* lock this entry so that nexthop is not removed */ + nbr_table_lock(nbr_routes, routes); } uip_ipaddr_copy(&(r->ipaddr), ipaddr); @@ -423,7 +426,7 @@ uip_ds6_route_rm(uip_ds6_route_t *route) list_remove(route->neighbor_routes->route_list, neighbor_route); if(list_head(route->neighbor_routes->route_list) == NULL) { /* If this was the only route using this neighbor, remove the - neibhor from the table */ + neighbor from the table - this implicitly unlocks nexthop */ PRINTF("uip_ds6_route_rm: removing neighbor too\n"); nbr_table_remove(nbr_routes, route->neighbor_routes->route_list); } From 4d5c749cf704143ca5dd19e19c6af79b26235c82 Mon Sep 17 00:00:00 2001 From: Joakim Eriksson Date: Wed, 26 Aug 2015 18:24:54 +0200 Subject: [PATCH 046/120] removed locking of rpl-parent since it was never unlocked - moved to routing module --- core/net/rpl/rpl-dag.c | 6 ------ core/net/rpl/rpl-icmp6.c | 2 -- core/net/rpl/rpl-private.h | 3 --- 3 files changed, 11 deletions(-) diff --git a/core/net/rpl/rpl-dag.c b/core/net/rpl/rpl-dag.c index 767c58968..89be40184 100644 --- a/core/net/rpl/rpl-dag.c +++ b/core/net/rpl/rpl-dag.c @@ -1408,10 +1408,4 @@ rpl_process_dio(uip_ipaddr_t *from, rpl_dio_t *dio) p->dtsn = dio->dtsn; } /*---------------------------------------------------------------------------*/ -void -rpl_lock_parent(rpl_parent_t *p) -{ - nbr_table_lock(rpl_parents, p); -} -/*---------------------------------------------------------------------------*/ /** @} */ diff --git a/core/net/rpl/rpl-icmp6.c b/core/net/rpl/rpl-icmp6.c index 0a4488d13..c4db3c8fa 100644 --- a/core/net/rpl/rpl-icmp6.c +++ b/core/net/rpl/rpl-icmp6.c @@ -773,8 +773,6 @@ dao_input(void) PRINTF("RPL: Neighbor already in neighbor cache\n"); } - rpl_lock_parent(parent); - rep = rpl_add_route(dag, &prefix, prefixlen, &dao_sender_addr); if(rep == NULL) { RPL_STAT(rpl_stats.mem_overflows++); diff --git a/core/net/rpl/rpl-private.h b/core/net/rpl/rpl-private.h index b49d71089..a1adc0d6f 100644 --- a/core/net/rpl/rpl-private.h +++ b/core/net/rpl/rpl-private.h @@ -303,9 +303,6 @@ uip_ds6_route_t *rpl_add_route(rpl_dag_t *dag, uip_ipaddr_t *prefix, int prefix_len, uip_ipaddr_t *next_hop); void rpl_purge_routes(void); -/* Lock a parent in the neighbor cache. */ -void rpl_lock_parent(rpl_parent_t *p); - /* Objective function. */ rpl_of_t *rpl_find_of(rpl_ocp_t); From 9e16d93278e23b369ee814358ec6f35b7e9bb3fd Mon Sep 17 00:00:00 2001 From: Joakim Eriksson Date: Fri, 28 Aug 2015 19:15:23 +0200 Subject: [PATCH 047/120] removed pointer to next parent since it is not used anymore --- core/net/rpl/rpl.h | 1 - 1 file changed, 1 deletion(-) diff --git a/core/net/rpl/rpl.h b/core/net/rpl/rpl.h index e6e385375..70c877aeb 100644 --- a/core/net/rpl/rpl.h +++ b/core/net/rpl/rpl.h @@ -108,7 +108,6 @@ struct rpl_dag; #define RPL_PARENT_FLAG_LINK_METRIC_VALID 0x2 struct rpl_parent { - struct rpl_parent *next; struct rpl_dag *dag; #if RPL_DAG_MC != RPL_DAG_MC_NONE rpl_metric_container_t mc; From 90eca482ea3a19f62ad56fcf07cca84cbd0d58cd Mon Sep 17 00:00:00 2001 From: Antonio Lignan Date: Sat, 29 Aug 2015 20:22:18 +0200 Subject: [PATCH 048/120] Remove unused RPL_CONF_MAX_DAG_ENTRIES --- platform/cc2530dk/contiki-conf.h | 2 +- platform/cc2538dk/contiki-conf.h | 2 +- platform/remote/contiki-conf.h | 2 +- platform/sensinode/contiki-conf.h | 2 +- platform/srf06-cc26xx/contiki-conf.h | 2 +- 5 files changed, 5 insertions(+), 5 deletions(-) diff --git a/platform/cc2530dk/contiki-conf.h b/platform/cc2530dk/contiki-conf.h index ef933dc1c..5d3beb6bb 100644 --- a/platform/cc2530dk/contiki-conf.h +++ b/platform/cc2530dk/contiki-conf.h @@ -226,7 +226,7 @@ #define UIP_CONF_ND6_SEND_RA 0 #define UIP_CONF_IP_FORWARD 0 #define RPL_CONF_STATS 0 -#define RPL_CONF_MAX_DAG_ENTRIES 1 + #ifndef RPL_CONF_OF #define RPL_CONF_OF rpl_mrhof #endif diff --git a/platform/cc2538dk/contiki-conf.h b/platform/cc2538dk/contiki-conf.h index 354f042db..7d5924de4 100644 --- a/platform/cc2538dk/contiki-conf.h +++ b/platform/cc2538dk/contiki-conf.h @@ -448,7 +448,7 @@ typedef uint32_t rtimer_clock_t; #define UIP_CONF_ND6_SEND_RA 0 #define UIP_CONF_IP_FORWARD 0 #define RPL_CONF_STATS 0 -#define RPL_CONF_MAX_DAG_ENTRIES 1 + #ifndef RPL_CONF_OF #define RPL_CONF_OF rpl_mrhof #endif diff --git a/platform/remote/contiki-conf.h b/platform/remote/contiki-conf.h index 959e5fe4b..10e689cdf 100644 --- a/platform/remote/contiki-conf.h +++ b/platform/remote/contiki-conf.h @@ -452,7 +452,7 @@ typedef uint32_t rtimer_clock_t; #define UIP_CONF_ND6_SEND_RA 0 #define UIP_CONF_IP_FORWARD 0 #define RPL_CONF_STATS 0 -#define RPL_CONF_MAX_DAG_ENTRIES 1 + #ifndef RPL_CONF_OF #define RPL_CONF_OF rpl_mrhof #endif diff --git a/platform/sensinode/contiki-conf.h b/platform/sensinode/contiki-conf.h index 3866bc3b4..d09fdbcbd 100644 --- a/platform/sensinode/contiki-conf.h +++ b/platform/sensinode/contiki-conf.h @@ -222,7 +222,7 @@ #define UIP_CONF_ND6_SEND_RA 0 #define UIP_CONF_IP_FORWARD 0 #define RPL_CONF_STATS 0 -#define RPL_CONF_MAX_DAG_ENTRIES 1 + #ifndef RPL_CONF_OF #define RPL_CONF_OF rpl_mrhof #endif diff --git a/platform/srf06-cc26xx/contiki-conf.h b/platform/srf06-cc26xx/contiki-conf.h index 02f982854..e9fc7458b 100644 --- a/platform/srf06-cc26xx/contiki-conf.h +++ b/platform/srf06-cc26xx/contiki-conf.h @@ -201,7 +201,7 @@ #define UIP_CONF_ND6_SEND_RA 0 #define UIP_CONF_IP_FORWARD 0 #define RPL_CONF_STATS 0 -#define RPL_CONF_MAX_DAG_ENTRIES 1 + #ifndef RPL_CONF_OF #define RPL_CONF_OF rpl_mrhof #endif From 854494109d7e72171607a9a7bd4cd30cbce7c5ce Mon Sep 17 00:00:00 2001 From: Atis Elsts Date: Wed, 17 Dec 2014 12:42:27 +0100 Subject: [PATCH 049/120] Atmel 230bb: always increase the rx frame ringbuffer cursor in rf230_read(). Avoids packet reordering in cases when RF230_CONF_RX_BUFFERS > 1. --- cpu/avr/radio/rf230bb/rf230bb.c | 28 +++++++++++++++------------- 1 file changed, 15 insertions(+), 13 deletions(-) diff --git a/cpu/avr/radio/rf230bb/rf230bb.c b/cpu/avr/radio/rf230bb/rf230bb.c index aee2f6d29..c85608e09 100644 --- a/cpu/avr/radio/rf230bb/rf230bb.c +++ b/cpu/avr/radio/rf230bb/rf230bb.c @@ -552,7 +552,19 @@ rf230_is_ready_to_send() { static void flushrx(void) { + /* Clear the length field to allow buffering of the next packet */ rxframe[rxframe_head].length=0; + rxframe_head++; + if (rxframe_head >= RF230_CONF_RX_BUFFERS) { + rxframe_head=0; + } + /* If another packet has been buffered, schedule another receive poll */ + if (rxframe[rxframe_head].length) { + rf230_interrupt(); + } + else { + rf230_pending = 0; + } } /*---------------------------------------------------------------------------*/ static void @@ -1434,6 +1446,7 @@ rf230_read(void *buf, unsigned short bufsize) #if RADIOALWAYSON && DEBUGFLOWSIZE if (RF230_receive_on==0) {if (debugflow[debugflowsize-1]!='z') DEBUGFLOW('z');} //cxmac calls with radio off? #endif + flushrx(); return 0; } @@ -1476,19 +1489,8 @@ rf230_read(void *buf, unsigned short bufsize) memcpy(buf,framep,len-AUX_LEN+CHECKSUM_LEN); rf230_last_correlation = rxframe[rxframe_head].lqi; - /* Clear the length field to allow buffering of the next packet */ - rxframe[rxframe_head].length=0; - rxframe_head++; - if (rxframe_head >= RF230_CONF_RX_BUFFERS) { - rxframe_head=0; - } - /* If another packet has been buffered, schedule another receive poll */ - if (rxframe[rxframe_head].length) { - rf230_interrupt(); - } - else { - rf230_pending = 0; - } + /* Prepare to receive another packet */ + flushrx(); /* Point to the checksum */ framep+=len-AUX_LEN; From 2cd74d043db950dbc63e5b97603359584970a907 Mon Sep 17 00:00:00 2001 From: Valentin Sawadski Date: Mon, 10 Nov 2014 17:21:18 +0100 Subject: [PATCH 050/120] CTIMER API extension to explictly state the process a ctimer belongs to --- core/sys/ctimer.c | 9 ++++++++- core/sys/ctimer.h | 18 ++++++++++++++++++ 2 files changed, 26 insertions(+), 1 deletion(-) diff --git a/core/sys/ctimer.c b/core/sys/ctimer.c index c72f247f5..66698a8e6 100644 --- a/core/sys/ctimer.c +++ b/core/sys/ctimer.c @@ -98,9 +98,16 @@ ctimer_init(void) void ctimer_set(struct ctimer *c, clock_time_t t, void (*f)(void *), void *ptr) +{ + ctimer_set_with_process(c, t, f, ptr, PROCESS_CURRENT()); +} +/*---------------------------------------------------------------------------*/ +void +ctimer_set_with_process(struct ctimer *c, clock_time_t t, + void (*f)(void *), void *ptr, struct process *p) { PRINTF("ctimer_set %p %u\n", c, (unsigned)t); - c->p = PROCESS_CURRENT(); + c->p = p; c->f = f; c->ptr = ptr; if(initialized) { diff --git a/core/sys/ctimer.h b/core/sys/ctimer.h index bebe8a532..dabf43d8a 100644 --- a/core/sys/ctimer.h +++ b/core/sys/ctimer.h @@ -109,10 +109,28 @@ void ctimer_restart(struct ctimer *c); * sometime in the future. When the callback timer expires, * the callback function f will be called with ptr as argument. * + * This essentially does ctimer_set_process(c, t, f, ptr, PROCESS_CURRENT()); + * */ void ctimer_set(struct ctimer *c, clock_time_t t, void (*f)(void *), void *ptr); +/** + * \brief Set a callback timer. + * \param c A pointer to the callback timer. + * \param t The interval before the timer expires. + * \param f A function to be called when the timer expires. + * \param ptr An opaque pointer that will be supplied as an argument to the callback function. + * \param p A pointer to the process the timer belongs to + * + * This function is used to set a callback timer for a time + * sometime in the future. When the callback timer expires, + * the callback function f will be called with ptr as argument. + * + */ +void ctimer_set_with_process(struct ctimer *c, clock_time_t t, + void (*f)(void *), void *ptr, struct process *p); + /** * \brief Stop a pending callback timer. * \param c A pointer to the pending callback timer. From 2a2acf62ed1b45454ebbb56769e83d15a5e8feff Mon Sep 17 00:00:00 2001 From: rajithr Date: Mon, 31 Aug 2015 16:10:00 +0530 Subject: [PATCH 051/120] Fix for out of bounds access Fix for out of bounds access by limiting the printing to the size limit of the buffer --- core/net/packetbuf.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/net/packetbuf.c b/core/net/packetbuf.c index 20bfebe80..c7e2a9898 100644 --- a/core/net/packetbuf.c +++ b/core/net/packetbuf.c @@ -150,7 +150,7 @@ packetbuf_copyto(void *to) PRINTF("packetbuf_write: header: %s\n", buffer); bufferptr = buffer; bufferptr[0] = 0; - for(i = bufptr; ((i < buflen + bufptr) && (bufferlen < 980)); ++i) { + for(i = bufptr; ((i < buflen + bufptr) && (bufferlen < (sizeof(buffer) - 10))); ++i) { bufferlen += sprintf(bufferptr + bufferlen, "0x%02x, ", packetbufptr[i]); } PRINTF("packetbuf_write: data: %s\n", buffer); From 42077adbb135534ab20620a3203e62e566827b6f Mon Sep 17 00:00:00 2001 From: Sebastian Schinabeck Date: Tue, 26 Nov 2013 11:35:09 +0100 Subject: [PATCH 052/120] Add ScnObservable class with setChangedAndNotify() function The ScnObservable extends the normal Observable with the combined setChangedAndNotify() function --- .../java/org/contikios/mrm/ChannelModel.java | 22 ++++++++----------- .../apps/mrm/java/org/contikios/mrm/MRM.java | 10 ++------- .../cooja/java/org/contikios/cooja/Cooja.java | 18 ++++----------- .../radiomediums/AbstractRadioMedium.java | 18 +++++---------- .../radiomediums/DirectedGraphMedium.java | 9 +++----- .../contikios/cooja/util/ScnObservable.java | 16 ++++++++++++++ 6 files changed, 39 insertions(+), 54 deletions(-) create mode 100644 tools/cooja/java/org/contikios/cooja/util/ScnObservable.java diff --git a/tools/cooja/apps/mrm/java/org/contikios/mrm/ChannelModel.java b/tools/cooja/apps/mrm/java/org/contikios/mrm/ChannelModel.java index 579244f75..9d0427c8a 100644 --- a/tools/cooja/apps/mrm/java/org/contikios/mrm/ChannelModel.java +++ b/tools/cooja/apps/mrm/java/org/contikios/mrm/ChannelModel.java @@ -53,6 +53,8 @@ import org.contikios.cooja.Simulation; import org.contikios.cooja.interfaces.DirectionalAntennaRadio; import org.contikios.cooja.interfaces.Radio; import org.contikios.cooja.radiomediums.AbstractRadioMedium; +import org.contikios.cooja.util.ScnObservable; + import statistics.GaussianWrapper; /** @@ -103,13 +105,7 @@ public class ChannelModel { /** * Notifies observers when this channel model has changed settings. */ - private class SettingsObservable extends Observable { - private void notifySettingsChanged() { - setChanged(); - notifyObservers(); - } - } - private SettingsObservable settingsObservable = new SettingsObservable(); + private ScnObservable settingsObservable = new ScnObservable(); public enum Parameter { apply_random, snr_threshold, @@ -330,7 +326,7 @@ public class ChannelModel { */ public void removeAllObstacles() { myObstacleWorld.removeAll(); - settingsObservable.notifySettingsChanged(); + settingsObservable.setChangedAndNotify(); } /** @@ -360,7 +356,7 @@ public class ChannelModel { myObstacleWorld.addObstacle(startX, startY, width, height); if (notify) { - settingsObservable.notifySettingsChanged(); + settingsObservable.setChangedAndNotify(); } } @@ -442,7 +438,7 @@ public class ChannelModel { needToPrecalculateFSPL = true; needToPrecalculateOutputPower = true; - settingsObservable.notifySettingsChanged(); + settingsObservable.setChangedAndNotify(); } /** @@ -450,9 +446,9 @@ public class ChannelModel { * will be notified. */ public void notifySettingsChanged() { - settingsObservable.notifySettingsChanged(); + settingsObservable.setChangedAndNotify(); } - + /** * Path loss component from Friis' transmission equation. * Uses frequency and distance only. @@ -1884,7 +1880,7 @@ public class ChannelModel { } needToPrecalculateFSPL = true; needToPrecalculateOutputPower = true; - settingsObservable.notifySettingsChanged(); + settingsObservable.setChangedAndNotify(); return true; } diff --git a/tools/cooja/apps/mrm/java/org/contikios/mrm/MRM.java b/tools/cooja/apps/mrm/java/org/contikios/mrm/MRM.java index a19dcee58..5f7f1441c 100644 --- a/tools/cooja/apps/mrm/java/org/contikios/mrm/MRM.java +++ b/tools/cooja/apps/mrm/java/org/contikios/mrm/MRM.java @@ -49,6 +49,7 @@ import org.contikios.cooja.interfaces.Position; import org.contikios.cooja.interfaces.Radio; import org.contikios.cooja.plugins.Visualizer; import org.contikios.cooja.radiomediums.AbstractRadioMedium; +import org.contikios.cooja.util.ScnObservable; import org.contikios.mrm.ChannelModel.Parameter; import org.contikios.mrm.ChannelModel.RadioPair; import org.contikios.mrm.ChannelModel.TxPair; @@ -93,7 +94,7 @@ public class MRM extends AbstractRadioMedium { /** * Notifies observers when this radio medium has changed settings. */ - private SettingsObservable settingsObservable = new SettingsObservable(); + private ScnObservable settingsObservable = new ScnObservable(); /** * Creates a new Multi-path Ray-tracing Medium (MRM). @@ -449,13 +450,6 @@ public class MRM extends AbstractRadioMedium { return currentChannelModel; } - class SettingsObservable extends Observable { - private void notifySettingsChanged() { - setChanged(); - notifyObservers(); - } - } - class MRMRadioConnection extends RadioConnection { private Hashtable signalStrengths = new Hashtable(); diff --git a/tools/cooja/java/org/contikios/cooja/Cooja.java b/tools/cooja/java/org/contikios/cooja/Cooja.java index c131e3e22..0040e7a31 100644 --- a/tools/cooja/java/org/contikios/cooja/Cooja.java +++ b/tools/cooja/java/org/contikios/cooja/Cooja.java @@ -139,6 +139,7 @@ import org.contikios.cooja.plugins.ScriptRunner; import org.contikios.cooja.plugins.SimControl; import org.contikios.cooja.plugins.SimInformation; import org.contikios.cooja.util.ExecuteJAR; +import org.contikios.cooja.util.ScnObservable; /** * Main file of COOJA Simulator. Typically contains a visualizer for the @@ -325,21 +326,10 @@ public class Cooja extends Observable { private Vector> positionerClasses = new Vector>(); - private class HighlightObservable extends Observable { - private void setChangedAndNotify(Mote mote) { - setChanged(); - notifyObservers(mote); - } - } - private HighlightObservable moteHighlightObservable = new HighlightObservable(); - private class MoteRelationsObservable extends Observable { - private void setChangedAndNotify() { - setChanged(); - notifyObservers(); - } - } - private MoteRelationsObservable moteRelationObservable = new MoteRelationsObservable(); + private ScnObservable moteHighlightObservable = new ScnObservable(); + + private ScnObservable moteRelationObservable = new ScnObservable(); private JTextPane quickHelpTextPane; private JScrollPane quickHelpScroll; diff --git a/tools/cooja/java/org/contikios/cooja/radiomediums/AbstractRadioMedium.java b/tools/cooja/java/org/contikios/cooja/radiomediums/AbstractRadioMedium.java index fce97e927..ba8cef052 100644 --- a/tools/cooja/java/org/contikios/cooja/radiomediums/AbstractRadioMedium.java +++ b/tools/cooja/java/org/contikios/cooja/radiomediums/AbstractRadioMedium.java @@ -49,8 +49,10 @@ import org.contikios.cooja.Simulation; import org.contikios.cooja.TimeEvent; import org.contikios.cooja.interfaces.CustomDataRadio; import org.contikios.cooja.interfaces.Radio; +import org.contikios.cooja.util.ScnObservable; import org.jdom.Element; + /** * Abstract radio medium provides basic functionality for implementing radio * mediums. @@ -90,17 +92,7 @@ public abstract class AbstractRadioMedium extends RadioMedium { public int COUNTER_RX = 0; public int COUNTER_INTERFERED = 0; - public class RadioMediumObservable extends Observable { - public void setRadioMediumChanged() { - setChanged(); - } - public void setRadioMediumChangedAndNotify() { - setChanged(); - notifyObservers(); - } - } - - private RadioMediumObservable radioMediumObservable = new RadioMediumObservable(); + protected ScnObservable radioMediumObservable = new ScnObservable(); /** * This constructor should always be called from implemented radio mediums. @@ -288,7 +280,7 @@ public abstract class AbstractRadioMedium extends RadioMedium { /* Notify observers */ lastConnection = null; - radioMediumObservable.setRadioMediumChangedAndNotify(); + radioMediumObservable.setChangedAndNotify(); } break; case TRANSMISSION_FINISHED: { @@ -333,7 +325,7 @@ public abstract class AbstractRadioMedium extends RadioMedium { updateSignalStrengths(); /* Notify observers */ - radioMediumObservable.setRadioMediumChangedAndNotify(); + radioMediumObservable.setChangedAndNotify(); } break; case CUSTOM_DATA_TRANSMITTED: { diff --git a/tools/cooja/java/org/contikios/cooja/radiomediums/DirectedGraphMedium.java b/tools/cooja/java/org/contikios/cooja/radiomediums/DirectedGraphMedium.java index 57876357c..ee79e76c7 100644 --- a/tools/cooja/java/org/contikios/cooja/radiomediums/DirectedGraphMedium.java +++ b/tools/cooja/java/org/contikios/cooja/radiomediums/DirectedGraphMedium.java @@ -93,8 +93,7 @@ public class DirectedGraphMedium extends AbstractRadioMedium { edges.add(e); requestEdgeAnalysis(); - ((AbstractRadioMedium.RadioMediumObservable) - this.getRadioMediumObservable()).setRadioMediumChangedAndNotify(); + radioMediumObservable.setChangedAndNotify(); } public void removeEdge(Edge edge) { @@ -105,16 +104,14 @@ public class DirectedGraphMedium extends AbstractRadioMedium { edges.remove(edge); requestEdgeAnalysis(); - ((AbstractRadioMedium.RadioMediumObservable) - this.getRadioMediumObservable()).setRadioMediumChangedAndNotify(); + radioMediumObservable.setChangedAndNotify(); } public void clearEdges() { edges.clear(); requestEdgeAnalysis(); - ((AbstractRadioMedium.RadioMediumObservable) - this.getRadioMediumObservable()).setRadioMediumChangedAndNotify(); + radioMediumObservable.setChangedAndNotify(); } public Edge[] getEdges() { diff --git a/tools/cooja/java/org/contikios/cooja/util/ScnObservable.java b/tools/cooja/java/org/contikios/cooja/util/ScnObservable.java new file mode 100644 index 000000000..d922d76a4 --- /dev/null +++ b/tools/cooja/java/org/contikios/cooja/util/ScnObservable.java @@ -0,0 +1,16 @@ +package org.contikios.cooja.util; + +import java.util.Observable; + +public class ScnObservable extends Observable { + public void setChangedAndNotify() { + setChanged(); + notifyObservers(); + } + + public void setChangedAndNotify(Object obj) { + setChanged(); + notifyObservers(obj); + } + +} From c1a275f0b2a9992f64f68a9fc84e2a2d83f67925 Mon Sep 17 00:00:00 2001 From: Sebastian Schinabeck Date: Thu, 21 Nov 2013 18:08:41 +0100 Subject: [PATCH 053/120] Refactored RadioMediumObservable and added new Observable Refactored RadioMediumObservable to RadioTransmissionObservable because of its function Added correct RadioMediumObservable and updating in AbstractRadioMedium, DirectedGraphMedium and MRM Added some documentation --- .../java/org/contikios/mrm/AreaViewer.java | 4 +- .../apps/mrm/java/org/contikios/mrm/MRM.java | 6 +++ .../java/org/contikios/cooja/RadioMedium.java | 10 ++--- .../cooja/plugins/DGRMConfigurator.java | 4 +- .../cooja/plugins/EventListener.java | 2 +- .../contikios/cooja/plugins/RadioLogger.java | 4 +- .../plugins/skins/TrafficVisualizerSkin.java | 4 +- .../radiomediums/AbstractRadioMedium.java | 45 +++++++++++++++++-- .../radiomediums/DirectedGraphMedium.java | 10 +++-- 9 files changed, 69 insertions(+), 20 deletions(-) diff --git a/tools/cooja/apps/mrm/java/org/contikios/mrm/AreaViewer.java b/tools/cooja/apps/mrm/java/org/contikios/mrm/AreaViewer.java index 67d268bc2..265971d7f 100644 --- a/tools/cooja/apps/mrm/java/org/contikios/mrm/AreaViewer.java +++ b/tools/cooja/apps/mrm/java/org/contikios/mrm/AreaViewer.java @@ -230,7 +230,7 @@ public class AreaViewer extends VisPlugin { // We want to listen to changes both in the channel model as well as in the radio medium currentChannelModel.addSettingsObserver(channelModelSettingsObserver); currentRadioMedium.addSettingsObserver(radioMediumSettingsObserver); - currentRadioMedium.addRadioMediumObserver(radioMediumActivityObserver); + currentRadioMedium.addRadioTransmissionObserver(radioMediumActivityObserver); // Set initial size etc. setSize(500, 500); @@ -2344,7 +2344,7 @@ public class AreaViewer extends VisPlugin { } if (currentRadioMedium != null && radioMediumActivityObserver != null) { - currentRadioMedium.deleteRadioMediumObserver(radioMediumActivityObserver); + currentRadioMedium.deleteRadioTransmissionObserver(radioMediumActivityObserver); } else { logger.fatal("Could not remove observer: " + radioMediumActivityObserver); } diff --git a/tools/cooja/apps/mrm/java/org/contikios/mrm/MRM.java b/tools/cooja/apps/mrm/java/org/contikios/mrm/MRM.java index 5f7f1441c..eef055af5 100644 --- a/tools/cooja/apps/mrm/java/org/contikios/mrm/MRM.java +++ b/tools/cooja/apps/mrm/java/org/contikios/mrm/MRM.java @@ -143,6 +143,9 @@ public class MRM extends AbstractRadioMedium { public void registerRadioInterface(Radio radio, Simulation sim) { super.registerRadioInterface(radio, sim); + /* Radio Medium changed here so notify Observers */ + radioMediumObservable.setChangedAndNotify(); + if (WITH_NOISE && radio instanceof NoiseSourceRadio) { ((NoiseSourceRadio)radio).addNoiseLevelListener(noiseListener); } @@ -150,6 +153,9 @@ public class MRM extends AbstractRadioMedium { public void unregisterRadioInterface(Radio radio, Simulation sim) { super.unregisterRadioInterface(radio, sim); + /* Radio Medium changed here so notify Observers */ + radioMediumObservable.setChangedAndNotify(); + if (WITH_NOISE && radio instanceof NoiseSourceRadio) { ((NoiseSourceRadio)radio).removeNoiseLevelListener(noiseListener); } diff --git a/tools/cooja/java/org/contikios/cooja/RadioMedium.java b/tools/cooja/java/org/contikios/cooja/RadioMedium.java index da60dc492..4905a187f 100644 --- a/tools/cooja/java/org/contikios/cooja/RadioMedium.java +++ b/tools/cooja/java/org/contikios/cooja/RadioMedium.java @@ -100,24 +100,24 @@ public abstract class RadioMedium { * Adds an observer which is notified each time a radio connection has finished. * * @see #getLastConnection() - * @see #deleteRadioMediumObserver(Observer) + * @see #deleteRadioTransmissionObserver(Observer) * @param observer New observer */ - public abstract void addRadioMediumObserver(Observer observer); + public abstract void addRadioTransmissionObserver(Observer observer); /** * @return Radio medium observable */ - public abstract Observable getRadioMediumObservable(); + public abstract Observable getRadioTransmissionObservable(); /** * Deletes an radio medium observer. * - * @see #addRadioMediumObserver(Observer) + * @see #addRadioTransmissionObserver(Observer) * @param observer * Observer to delete */ - public abstract void deleteRadioMediumObserver(Observer observer); + public abstract void deleteRadioTransmissionObserver(Observer observer); /** * @return Last radio connection finished in the radio medium diff --git a/tools/cooja/java/org/contikios/cooja/plugins/DGRMConfigurator.java b/tools/cooja/java/org/contikios/cooja/plugins/DGRMConfigurator.java index 9554d7e90..df6f61d1f 100644 --- a/tools/cooja/java/org/contikios/cooja/plugins/DGRMConfigurator.java +++ b/tools/cooja/java/org/contikios/cooja/plugins/DGRMConfigurator.java @@ -111,7 +111,7 @@ public class DGRMConfigurator extends VisPlugin { radioMedium = (DirectedGraphMedium) sim.getRadioMedium(); /* Listen for graph updates */ - radioMedium.addRadioMediumObserver(radioMediumObserver = new Observer() { + radioMedium.addRadioTransmissionObserver(radioMediumObserver = new Observer() { public void update(Observable obs, Object obj) { model.fireTableDataChanged(); } @@ -500,7 +500,7 @@ public class DGRMConfigurator extends VisPlugin { }; public void closePlugin() { - radioMedium.deleteRadioMediumObserver(radioMediumObserver); + radioMedium.deleteRadioTransmissionObserver(radioMediumObserver); } } diff --git a/tools/cooja/java/org/contikios/cooja/plugins/EventListener.java b/tools/cooja/java/org/contikios/cooja/plugins/EventListener.java index 887503f3d..bcd454076 100644 --- a/tools/cooja/java/org/contikios/cooja/plugins/EventListener.java +++ b/tools/cooja/java/org/contikios/cooja/plugins/EventListener.java @@ -223,7 +223,7 @@ public class EventListener extends VisPlugin { JCheckBox radioMediumCheckBox = new JCheckBox("Radio medium event", false); radioMediumCheckBox.putClientProperty("observable", mySimulation - .getRadioMedium().getRadioMediumObservable()); + .getRadioMedium().getRadioTransmissionObservable()); radioMediumCheckBox.addActionListener(generalCheckBoxListener); generalPanel.add(radioMediumCheckBox); diff --git a/tools/cooja/java/org/contikios/cooja/plugins/RadioLogger.java b/tools/cooja/java/org/contikios/cooja/plugins/RadioLogger.java index 17f5417c2..84fc41737 100644 --- a/tools/cooja/java/org/contikios/cooja/plugins/RadioLogger.java +++ b/tools/cooja/java/org/contikios/cooja/plugins/RadioLogger.java @@ -509,7 +509,7 @@ public class RadioLogger extends VisPlugin { adjuster.setDynamicAdjustment(true); adjuster.packColumns(); - radioMedium.addRadioMediumObserver(radioMediumObserver = new Observer() { + radioMedium.addRadioTransmissionObserver(radioMediumObserver = new Observer() { @Override public void update(Observable obs, Object obj) { RadioConnection conn = radioMedium.getLastConnection(); @@ -784,7 +784,7 @@ public class RadioLogger extends VisPlugin { @Override public void closePlugin() { if (radioMediumObserver != null) { - radioMedium.deleteRadioMediumObserver(radioMediumObserver); + radioMedium.deleteRadioTransmissionObserver(radioMediumObserver); } } diff --git a/tools/cooja/java/org/contikios/cooja/plugins/skins/TrafficVisualizerSkin.java b/tools/cooja/java/org/contikios/cooja/plugins/skins/TrafficVisualizerSkin.java index 0cd05c319..c98c51222 100644 --- a/tools/cooja/java/org/contikios/cooja/plugins/skins/TrafficVisualizerSkin.java +++ b/tools/cooja/java/org/contikios/cooja/plugins/skins/TrafficVisualizerSkin.java @@ -130,7 +130,7 @@ public class TrafficVisualizerSkin implements VisualizerSkin { historyList.clear(); /* Start observing radio medium for transmissions */ - radioMedium.addRadioMediumObserver(radioMediumObserver); + radioMedium.addRadioTransmissionObserver(radioMediumObserver); /* Fade away arrows */ simulation.scheduleEvent(ageArrowsTimeEvent, simulation.getSimulationTime() + 100*Simulation.MILLISECOND); @@ -147,7 +147,7 @@ public class TrafficVisualizerSkin implements VisualizerSkin { } /* Stop observing radio medium */ - radioMedium.deleteRadioMediumObserver(radioMediumObserver); + radioMedium.deleteRadioTransmissionObserver(radioMediumObserver); } @Override diff --git a/tools/cooja/java/org/contikios/cooja/radiomediums/AbstractRadioMedium.java b/tools/cooja/java/org/contikios/cooja/radiomediums/AbstractRadioMedium.java index ba8cef052..a31b42b3d 100644 --- a/tools/cooja/java/org/contikios/cooja/radiomediums/AbstractRadioMedium.java +++ b/tools/cooja/java/org/contikios/cooja/radiomediums/AbstractRadioMedium.java @@ -92,7 +92,13 @@ public abstract class AbstractRadioMedium extends RadioMedium { public int COUNTER_RX = 0; public int COUNTER_INTERFERED = 0; + /** + * Two Observables to observe the radioMedium and radioTransmissions + * @see addRadioTransmissionObserver + * @see addRadioMediumObserver + */ protected ScnObservable radioMediumObservable = new ScnObservable(); + protected ScnObservable radioTransmissionObservable = new ScnObservable(); /** * This constructor should always be called from implemented radio mediums. @@ -280,7 +286,7 @@ public abstract class AbstractRadioMedium extends RadioMedium { /* Notify observers */ lastConnection = null; - radioMediumObservable.setChangedAndNotify(); + radioTransmissionObservable.setChangedAndNotify(); } break; case TRANSMISSION_FINISHED: { @@ -325,7 +331,7 @@ public abstract class AbstractRadioMedium extends RadioMedium { updateSignalStrengths(); /* Notify observers */ - radioMediumObservable.setChangedAndNotify(); + radioTransmissionObservable.setChangedAndNotify(); } break; case CUSTOM_DATA_TRANSMITTED: { @@ -340,7 +346,7 @@ public abstract class AbstractRadioMedium extends RadioMedium { /* Custom data object */ Object data = ((CustomDataRadio) radio).getLastCustomDataTransmitted(); if (data == null) { - logger.fatal("No custom data object to forward"); + logger.fatal("No custom data objecTransmissiont to forward"); return; } @@ -438,6 +444,7 @@ public abstract class AbstractRadioMedium extends RadioMedium { registeredRadios.add(radio); radio.addObserver(radioEventsObserver); + radioMediumObservable.setChangedAndNotify(); /* Update signal strengths */ updateSignalStrengths(); @@ -454,6 +461,8 @@ public abstract class AbstractRadioMedium extends RadioMedium { removeFromActiveConnections(radio); + radioMediumObservable.setChangedAndNotify(); + /* Update signal strengths */ updateSignalStrengths(); } @@ -520,10 +529,40 @@ public abstract class AbstractRadioMedium extends RadioMedium { sendRssi.put(radio, rssi); } + /** + * Register an observer that gets notified when the radiotransmissions changed. + * E.g. creating new connections. + * This does not include changes in the settings and (de-)registration of radios. + * @see addRadioMediumObserver + * @param observer the Observer to register + */ + public void addRadioTransmissionObserver(Observer observer) { + radioTransmissionObservable.addObserver(observer); + } + + public Observable getRadioTransmissionObservable() { + return radioTransmissionObservable; + } + + public void deleteRadioTransmissionObserver(Observer observer) { + radioTransmissionObservable.deleteObserver(observer); + } + + /** + * Register an observer that gets notified when the radio medium changed. + * This includes changes in the settings and (de-)registration of radios. + * This does not include transmissions, etc as these are part of the radio + * and not the radio medium itself. + * @see addRadioTransmissionObserver + * @param observer the Observer to register + */ public void addRadioMediumObserver(Observer observer) { radioMediumObservable.addObserver(observer); } + /** + * @return the radioMediumObservable + */ public Observable getRadioMediumObservable() { return radioMediumObservable; } diff --git a/tools/cooja/java/org/contikios/cooja/radiomediums/DirectedGraphMedium.java b/tools/cooja/java/org/contikios/cooja/radiomediums/DirectedGraphMedium.java index ee79e76c7..15806c389 100644 --- a/tools/cooja/java/org/contikios/cooja/radiomediums/DirectedGraphMedium.java +++ b/tools/cooja/java/org/contikios/cooja/radiomediums/DirectedGraphMedium.java @@ -93,7 +93,7 @@ public class DirectedGraphMedium extends AbstractRadioMedium { edges.add(e); requestEdgeAnalysis(); - radioMediumObservable.setChangedAndNotify(); + radioTransmissionObservable.setChangedAndNotify(); } public void removeEdge(Edge edge) { @@ -104,14 +104,15 @@ public class DirectedGraphMedium extends AbstractRadioMedium { edges.remove(edge); requestEdgeAnalysis(); - radioMediumObservable.setChangedAndNotify(); + + radioTransmissionObservable.setChangedAndNotify(); } public void clearEdges() { edges.clear(); requestEdgeAnalysis(); - radioMediumObservable.setChangedAndNotify(); + radioTransmissionObservable.setChangedAndNotify(); } public Edge[] getEdges() { @@ -221,6 +222,9 @@ public class DirectedGraphMedium extends AbstractRadioMedium { this.edgesTable = arrTable; edgesDirty = false; + + /* Radio Medium changed here so notify Observers */ + radioMediumObservable.setChangedAndNotify(); } /** From ef779d4fc1980a2543cd70bb96fd83f8df286369 Mon Sep 17 00:00:00 2001 From: Sebastian Schinabeck Date: Tue, 26 Nov 2013 16:02:17 +0100 Subject: [PATCH 054/120] settingsObservable superseded by radioMediumObserver Wasn't used anyway --- .../java/org/contikios/mrm/AreaViewer.java | 4 +-- .../apps/mrm/java/org/contikios/mrm/MRM.java | 27 +++---------------- 2 files changed, 5 insertions(+), 26 deletions(-) diff --git a/tools/cooja/apps/mrm/java/org/contikios/mrm/AreaViewer.java b/tools/cooja/apps/mrm/java/org/contikios/mrm/AreaViewer.java index 265971d7f..1d98efb06 100644 --- a/tools/cooja/apps/mrm/java/org/contikios/mrm/AreaViewer.java +++ b/tools/cooja/apps/mrm/java/org/contikios/mrm/AreaViewer.java @@ -229,7 +229,7 @@ public class AreaViewer extends VisPlugin { // We want to listen to changes both in the channel model as well as in the radio medium currentChannelModel.addSettingsObserver(channelModelSettingsObserver); - currentRadioMedium.addSettingsObserver(radioMediumSettingsObserver); + currentRadioMedium.addRadioMediumObserver(radioMediumSettingsObserver); currentRadioMedium.addRadioTransmissionObserver(radioMediumActivityObserver); // Set initial size etc. @@ -2338,7 +2338,7 @@ public class AreaViewer extends VisPlugin { } if (currentRadioMedium != null && radioMediumSettingsObserver != null) { - currentRadioMedium.deleteSettingsObserver(radioMediumSettingsObserver); + currentRadioMedium.deleteRadioMediumObserver(radioMediumSettingsObserver); } else { logger.fatal("Could not remove observer: " + radioMediumSettingsObserver); } diff --git a/tools/cooja/apps/mrm/java/org/contikios/mrm/MRM.java b/tools/cooja/apps/mrm/java/org/contikios/mrm/MRM.java index eef055af5..e8af73370 100644 --- a/tools/cooja/apps/mrm/java/org/contikios/mrm/MRM.java +++ b/tools/cooja/apps/mrm/java/org/contikios/mrm/MRM.java @@ -91,11 +91,6 @@ public class MRM extends AbstractRadioMedium { private Random random = null; private ChannelModel currentChannelModel = null; - /** - * Notifies observers when this radio medium has changed settings. - */ - private ScnObservable settingsObservable = new ScnObservable(); - /** * Creates a new Multi-path Ray-tracing Medium (MRM). */ @@ -115,6 +110,9 @@ public class MRM extends AbstractRadioMedium { WITH_CAPTURE_EFFECT = currentChannelModel.getParameterBooleanValue(ChannelModel.Parameter.captureEffect); CAPTURE_EFFECT_THRESHOLD = currentChannelModel.getParameterDoubleValue(ChannelModel.Parameter.captureEffectSignalTreshold); CAPTURE_EFFECT_PREAMBLE_DURATION = currentChannelModel.getParameterDoubleValue(ChannelModel.Parameter.captureEffectPreambleDuration); + + /* Radio Medium changed here, so notify */ + radioMediumObservable.setChangedAndNotify(); } }); @@ -409,25 +407,6 @@ public class MRM extends AbstractRadioMedium { // -- MRM specific methods -- - /** - * Adds an observer which is notified when this radio medium has - * changed settings, such as added or removed radios. - * - * @param obs New observer - */ - public void addSettingsObserver(Observer obs) { - settingsObservable.addObserver(obs); - } - - /** - * Deletes an earlier registered setting observer. - * - * @param obs Earlier registered observer - */ - public void deleteSettingsObserver(Observer obs) { - settingsObservable.deleteObserver(obs); - } - /** * @return Number of registered radios. */ From 85555cf6cfc8bd0491978d5d54277b0f6e2f39c9 Mon Sep 17 00:00:00 2001 From: Billy Kozak Date: Mon, 17 Aug 2015 11:02:06 -0600 Subject: [PATCH 055/120] Made cc26xx WDT reload configurable with macro CONTIKI_WATCHDOG_TIMER_TOP sets the reload value of the WDT --- cpu/cc26xx-cc13xx/dev/contiki-watchdog.c | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/cpu/cc26xx-cc13xx/dev/contiki-watchdog.c b/cpu/cc26xx-cc13xx/dev/contiki-watchdog.c index 471c6f3cb..401b5637e 100644 --- a/cpu/cc26xx-cc13xx/dev/contiki-watchdog.c +++ b/cpu/cc26xx-cc13xx/dev/contiki-watchdog.c @@ -42,9 +42,16 @@ * \file * Implementation of the CC13xx/CC26xx watchdog driver. */ -#include "watchdog.h" +#include "contiki.h" +#include "dev/watchdog.h" #include "ti-lib.h" /*---------------------------------------------------------------------------*/ +#ifdef CONTIKI_WATCHDOG_CONF_TIMER_TOP +#define CONTIKI_WATCHDOG_TIMER_TOP CONTIKI_WATCHDOG_CONF_TIMER_TOP +#else +#define CONTIKI_WATCHDOG_TIMER_TOP 0xFFFFF +#endif +/*---------------------------------------------------------------------------*/ /** * \brief Initialises the CC26xx WDT * @@ -54,7 +61,7 @@ void watchdog_init(void) { - ti_lib_watchdog_reload_set(0xFFFFF); + ti_lib_watchdog_reload_set(CONTIKI_WATCHDOG_TIMER_TOP); } /*---------------------------------------------------------------------------*/ /** From dfdb0a6487a7acca907af22eca515d3fd159c218 Mon Sep 17 00:00:00 2001 From: Billy Kozak Date: Mon, 17 Aug 2015 11:09:30 -0600 Subject: [PATCH 056/120] cc26xx - fixed WDT reloading According to the TRM, the WDT does not produce a reset until it expires twice. After expiring the WDT will set the INT flag if it is unset, and reset the MCU if INT is already set. Before this patch, watchdog_periodic() only un-sets the INT flag. This means that the behaviour of watchdog_periodic is underministic in that the value of the countdown timer will be different depending on when the function was called. This patch fixes this behaviour by also reloading the timout value. --- cpu/cc26xx-cc13xx/dev/contiki-watchdog.c | 1 + 1 file changed, 1 insertion(+) diff --git a/cpu/cc26xx-cc13xx/dev/contiki-watchdog.c b/cpu/cc26xx-cc13xx/dev/contiki-watchdog.c index 401b5637e..5b67df2e1 100644 --- a/cpu/cc26xx-cc13xx/dev/contiki-watchdog.c +++ b/cpu/cc26xx-cc13xx/dev/contiki-watchdog.c @@ -79,6 +79,7 @@ watchdog_start(void) void watchdog_periodic(void) { + ti_lib_watchdog_reload_set(CONTIKI_WATCHDOG_TIMER_TOP); ti_lib_watchdog_int_clear(); } /*---------------------------------------------------------------------------*/ From 22d8a8dd563c4c900005b987fa287b1314cb3667 Mon Sep 17 00:00:00 2001 From: Billy Kozak Date: Mon, 17 Aug 2015 11:11:30 -0600 Subject: [PATCH 057/120] cc26xx - implemented watchdog_stop Also modified watchdog_start so that if we stop and start again the watchdog timeout will be reset (by calling watchdog_periodic). --- cpu/cc26xx-cc13xx/dev/contiki-watchdog.c | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/cpu/cc26xx-cc13xx/dev/contiki-watchdog.c b/cpu/cc26xx-cc13xx/dev/contiki-watchdog.c index 5b67df2e1..e12561869 100644 --- a/cpu/cc26xx-cc13xx/dev/contiki-watchdog.c +++ b/cpu/cc26xx-cc13xx/dev/contiki-watchdog.c @@ -70,6 +70,7 @@ watchdog_init(void) void watchdog_start(void) { + watchdog_periodic(); ti_lib_watchdog_reset_enable(); } /*---------------------------------------------------------------------------*/ @@ -83,6 +84,15 @@ watchdog_periodic(void) ti_lib_watchdog_int_clear(); } /*---------------------------------------------------------------------------*/ +/** + * \brief Stops the WDT such that it won't timeout and cause MCU reset + */ +void +watchdog_stop(void) +{ + ti_lib_watchdog_reset_disable(); +} +/*---------------------------------------------------------------------------*/ /** * \brief Manually trigger a WDT reboot */ From fde3202a3f593641f879b27881ce5bcb44ba850c Mon Sep 17 00:00:00 2001 From: Billy Kozak Date: Mon, 17 Aug 2015 11:12:35 -0600 Subject: [PATCH 058/120] cc26xx - added optional locking mode for WDT Added a mode, configurable by the CONTIKI_WATCHDOG_CONF_LOCK_BETWEEN_USE macro, which locks the WDT register between uses so as to prevent any accidental modifications --- cpu/cc26xx-cc13xx/dev/contiki-watchdog.c | 55 ++++++++++++++++++++++++ 1 file changed, 55 insertions(+) diff --git a/cpu/cc26xx-cc13xx/dev/contiki-watchdog.c b/cpu/cc26xx-cc13xx/dev/contiki-watchdog.c index e12561869..f8eb4f666 100644 --- a/cpu/cc26xx-cc13xx/dev/contiki-watchdog.c +++ b/cpu/cc26xx-cc13xx/dev/contiki-watchdog.c @@ -45,12 +45,58 @@ #include "contiki.h" #include "dev/watchdog.h" #include "ti-lib.h" + +#include +#include /*---------------------------------------------------------------------------*/ #ifdef CONTIKI_WATCHDOG_CONF_TIMER_TOP #define CONTIKI_WATCHDOG_TIMER_TOP CONTIKI_WATCHDOG_CONF_TIMER_TOP #else #define CONTIKI_WATCHDOG_TIMER_TOP 0xFFFFF #endif + +#ifdef CONTIKI_WATCHDOG_CONF_LOCK_CONFIG +#define CONTIKI_WATCHDOG_LOCK_CONFIG CONTIKI_WATCHDOG_CONF_LOCK_CONFIG +#else +#define CONTIKI_WATCHDOG_LOCK_CONFIG 1 +#endif + +#define LOCK_INTERRUPTS_DISABLED 0x01 +#define LOCK_REGISTERS_UNLOCKED 0x02 +/*---------------------------------------------------------------------------*/ +static uint32_t +unlock_config(void) +{ + uint32_t ret = 0; + bool int_status; + + if(CONTIKI_WATCHDOG_LOCK_CONFIG) { + int_status = ti_lib_int_master_disable(); + + if(ti_lib_watchdog_lock_state()) { + ret |= LOCK_REGISTERS_UNLOCKED; + ti_lib_watchdog_unlock(); + } + + ret |= (int_status) ? (0) : (LOCK_INTERRUPTS_DISABLED); + } + + return ret; +} +/*---------------------------------------------------------------------------*/ +static void +lock_config(uint32_t status) +{ + if(CONTIKI_WATCHDOG_LOCK_CONFIG) { + + if(status & LOCK_REGISTERS_UNLOCKED) { + ti_lib_watchdog_lock(); + } + if(status & LOCK_INTERRUPTS_DISABLED) { + ti_lib_int_master_enable(); + } + } +} /*---------------------------------------------------------------------------*/ /** * \brief Initialises the CC26xx WDT @@ -62,6 +108,7 @@ void watchdog_init(void) { ti_lib_watchdog_reload_set(CONTIKI_WATCHDOG_TIMER_TOP); + lock_config(LOCK_REGISTERS_UNLOCKED); } /*---------------------------------------------------------------------------*/ /** @@ -70,8 +117,12 @@ watchdog_init(void) void watchdog_start(void) { + uint32_t lock_status = unlock_config(); + watchdog_periodic(); ti_lib_watchdog_reset_enable(); + + lock_config(lock_status); } /*---------------------------------------------------------------------------*/ /** @@ -90,7 +141,11 @@ watchdog_periodic(void) void watchdog_stop(void) { + uint32_t lock_status = unlock_config(); + ti_lib_watchdog_reset_disable(); + + lock_config(lock_status); } /*---------------------------------------------------------------------------*/ /** From 34280338aced9b141d90e90b2f991d66d3c11d39 Mon Sep 17 00:00:00 2001 From: Simon Duquennoy Date: Tue, 1 Sep 2015 10:02:35 +0200 Subject: [PATCH 059/120] Z1: init random seed --- platform/z1/contiki-z1-main.c | 1 + 1 file changed, 1 insertion(+) diff --git a/platform/z1/contiki-z1-main.c b/platform/z1/contiki-z1-main.c index 78e1f4669..bab055d08 100644 --- a/platform/z1/contiki-z1-main.c +++ b/platform/z1/contiki-z1-main.c @@ -268,6 +268,7 @@ main(int argc, char **argv) /* * Initialize Contiki and our processes. */ + random_init(node_mac[6] + node_mac[7]); process_init(); process_start(&etimer_process, NULL); From db1635cf3c75dd8457992cf3fc6bef2c522da917 Mon Sep 17 00:00:00 2001 From: Simon Duquennoy Date: Tue, 1 Sep 2015 10:03:44 +0200 Subject: [PATCH 060/120] Z1: configure SFD timestamp with flag CC2420_CONF_TIMESTAMP, for consistency the Sky platform and with cc2420.c --- platform/z1/dev/cc2420-arch.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/platform/z1/dev/cc2420-arch.c b/platform/z1/dev/cc2420-arch.c index bc345e29f..929a1e0e6 100644 --- a/platform/z1/dev/cc2420-arch.c +++ b/platform/z1/dev/cc2420-arch.c @@ -34,13 +34,17 @@ #include "cc2420.h" #include "isr_compat.h" +#ifdef CC2420_CONF_SFD_TIMESTAMPS +#define CONF_SFD_TIMESTAMPS CC2420_CONF_SFD_TIMESTAMPS +#endif /* CC2420_CONF_SFD_TIMESTAMPS */ + #ifndef CONF_SFD_TIMESTAMPS #define CONF_SFD_TIMESTAMPS 0 #endif /* CONF_SFD_TIMESTAMPS */ #ifdef CONF_SFD_TIMESTAMPS #include "cc2420-arch-sfd.h" -#endif +#endif /* CONF_SFD_TIMESTAMPS */ /*---------------------------------------------------------------------------*/ #if 0 @@ -67,7 +71,7 @@ cc2420_arch_init(void) #if CONF_SFD_TIMESTAMPS cc2420_arch_sfd_init(); -#endif +#endif /* CONF_SFD_TIMESTAMPS */ CC2420_SPI_DISABLE(); /* Unselect radio. */ } From 29815d0696ddecaccec8afa2a0e95b41d072ecc7 Mon Sep 17 00:00:00 2001 From: Simon Duquennoy Date: Tue, 1 Sep 2015 10:20:58 +0200 Subject: [PATCH 061/120] Travis: compile er-rest-example for the Wismote platform rather than Sky --- regression-tests/01-compile-base/Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/regression-tests/01-compile-base/Makefile b/regression-tests/01-compile-base/Makefile index e756bf5a6..b86416df3 100644 --- a/regression-tests/01-compile-base/Makefile +++ b/regression-tests/01-compile-base/Makefile @@ -13,7 +13,7 @@ hello-world/wismote \ hello-world/z1 \ eeprom-test/native \ collect/sky \ -er-rest-example/sky \ +er-rest-example/wismote \ example-shell/native \ netperf/sky \ powertrace/sky \ From 4904386f4138a7cf4ec1c74dfe1ff7018b992d57 Mon Sep 17 00:00:00 2001 From: Simon Duquennoy Date: Tue, 1 Sep 2015 10:04:19 +0200 Subject: [PATCH 062/120] Wismote: init random seed --- platform/wismote/contiki-wismote-main.c | 1 + 1 file changed, 1 insertion(+) diff --git a/platform/wismote/contiki-wismote-main.c b/platform/wismote/contiki-wismote-main.c index f8b33d94a..f2da75a6c 100644 --- a/platform/wismote/contiki-wismote-main.c +++ b/platform/wismote/contiki-wismote-main.c @@ -257,6 +257,7 @@ main(int argc, char **argv) init_platform(); set_rime_addr(); + random_init(linkaddr_node_addr.u8[6] + linkaddr_node_addr.u8[7]); cc2520_init(); { From 265b65c67c0792f0fa24806880b2240a86bc8c14 Mon Sep 17 00:00:00 2001 From: Simon Duquennoy Date: Tue, 1 Sep 2015 19:36:27 +0200 Subject: [PATCH 063/120] Fix Wismote randon_init for link-layer addresses shorter than 8 bytes --- platform/wismote/contiki-wismote-main.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/platform/wismote/contiki-wismote-main.c b/platform/wismote/contiki-wismote-main.c index f2da75a6c..8a79811ac 100644 --- a/platform/wismote/contiki-wismote-main.c +++ b/platform/wismote/contiki-wismote-main.c @@ -257,7 +257,7 @@ main(int argc, char **argv) init_platform(); set_rime_addr(); - random_init(linkaddr_node_addr.u8[6] + linkaddr_node_addr.u8[7]); + random_init(linkaddr_node_addr.u8[LINKADDR_SIZE-2] + linkaddr_node_addr.u8[LINKADDR_SIZE-1]); cc2520_init(); { From b71353181d51628e2a16c64fda160956d96a22b9 Mon Sep 17 00:00:00 2001 From: Billy Kozak Date: Tue, 1 Sep 2015 13:58:24 -0600 Subject: [PATCH 064/120] CC26xx - enable correct IRQ in rf_core_cmd_done_en Fix for #1229 rf_core_cmd_done_en() was enabling the wrong irq for detecting the completion of foreground operations. This was causing cc26xx devices to not wake-up on time when calling lpm_sleep() from transmit(). --- cpu/cc26xx-cc13xx/rf-core/ieee-mode.c | 2 +- cpu/cc26xx-cc13xx/rf-core/prop-mode.c | 2 +- cpu/cc26xx-cc13xx/rf-core/rf-core.c | 7 ++++--- cpu/cc26xx-cc13xx/rf-core/rf-core.h | 8 +++++--- 4 files changed, 11 insertions(+), 8 deletions(-) diff --git a/cpu/cc26xx-cc13xx/rf-core/ieee-mode.c b/cpu/cc26xx-cc13xx/rf-core/ieee-mode.c index b997043ab..b5b5cf4c1 100644 --- a/cpu/cc26xx-cc13xx/rf-core/ieee-mode.c +++ b/cpu/cc26xx-cc13xx/rf-core/ieee-mode.c @@ -805,7 +805,7 @@ transmit(unsigned short transmit_len) cmd.pPayload = &tx_buf[TX_BUF_HDR_LEN]; /* Enable the LAST_FG_COMMAND_DONE interrupt, which will wake us up */ - rf_core_cmd_done_en(); + rf_core_cmd_done_en(true); ret = rf_core_send_cmd((uint32_t)&cmd, &cmd_status); diff --git a/cpu/cc26xx-cc13xx/rf-core/prop-mode.c b/cpu/cc26xx-cc13xx/rf-core/prop-mode.c index c4aa341d0..a26213f83 100644 --- a/cpu/cc26xx-cc13xx/rf-core/prop-mode.c +++ b/cpu/cc26xx-cc13xx/rf-core/prop-mode.c @@ -687,7 +687,7 @@ transmit(unsigned short transmit_len) rx_off_prop(); /* Enable the LAST_COMMAND_DONE interrupt to wake us up */ - rf_core_cmd_done_en(); + rf_core_cmd_done_en(false); ret = rf_core_send_cmd((uint32_t)cmd_tx_adv, &cmd_status); diff --git a/cpu/cc26xx-cc13xx/rf-core/rf-core.c b/cpu/cc26xx-cc13xx/rf-core/rf-core.c index 7528a6f77..45387ab42 100644 --- a/cpu/cc26xx-cc13xx/rf-core/rf-core.c +++ b/cpu/cc26xx-cc13xx/rf-core/rf-core.c @@ -378,11 +378,12 @@ rf_core_setup_interrupts() } /*---------------------------------------------------------------------------*/ void -rf_core_cmd_done_en() +rf_core_cmd_done_en(bool fg) { + uint32_t irq = fg ? IRQ_LAST_FG_COMMAND_DONE : IRQ_LAST_COMMAND_DONE; + HWREG(RFC_DBELL_NONBUF_BASE + RFC_DBELL_O_RFCPEIFG) = ENABLED_IRQS; - HWREG(RFC_DBELL_NONBUF_BASE + RFC_DBELL_O_RFCPEIEN) = ENABLED_IRQS + - IRQ_LAST_COMMAND_DONE; + HWREG(RFC_DBELL_NONBUF_BASE + RFC_DBELL_O_RFCPEIEN) = ENABLED_IRQS | irq; } /*---------------------------------------------------------------------------*/ void diff --git a/cpu/cc26xx-cc13xx/rf-core/rf-core.h b/cpu/cc26xx-cc13xx/rf-core/rf-core.h index bc389257c..7cf0b10e8 100644 --- a/cpu/cc26xx-cc13xx/rf-core/rf-core.h +++ b/cpu/cc26xx-cc13xx/rf-core/rf-core.h @@ -331,17 +331,19 @@ uint8_t rf_core_boot(void); void rf_core_setup_interrupts(void); /** - * \brief Enable the LAST_CMD_DONE interrupt. + * \brief Enable interrupt on command done. + * \param fg set true to enable irq on foreground command done and false for + * background commands or if not in ieee mode. * * This is used within TX routines in order to be able to sleep the CM3 and * wake up after TX has finished * * \sa rf_core_cmd_done_dis() */ -void rf_core_cmd_done_en(void); +void rf_core_cmd_done_en(bool fg); /** - * \brief Disable the LAST_CMD_DONE interrupt. + * \brief Disable the LAST_CMD_DONE and LAST_FG_CMD_DONE interrupts. * * This is used within TX routines after TX has completed * From 2f79810b581afc93c8acdc4af220301dab53bb11 Mon Sep 17 00:00:00 2001 From: Atis Elsts Date: Thu, 3 Sep 2015 16:06:46 +0200 Subject: [PATCH 065/120] Use ENERGEST_SWITCH to switch between different power modes to improve energest accuracy. --- cpu/cc2538/lpm.c | 15 +++++---------- cpu/cc26xx-cc13xx/lpm.c | 12 ++++-------- platform/cc2530dk/contiki-main.c | 6 ++---- platform/exp5438/contiki-exp5438-main.c | 6 ++---- platform/mbxxx/contiki-main.c | 8 +++----- platform/seedeye/contiki-seedeye-main.c | 6 ++---- platform/sensinode/contiki-sensinode-main.c | 6 ++---- platform/sky/contiki-sky-main.c | 6 ++---- platform/wismote/contiki-wismote-main.c | 6 ++---- platform/z1/contiki-z1-main.c | 6 ++---- 10 files changed, 26 insertions(+), 51 deletions(-) diff --git a/cpu/cc2538/lpm.c b/cpu/cc2538/lpm.c index 91d67acc9..45c7756e6 100644 --- a/cpu/cc2538/lpm.c +++ b/cpu/cc2538/lpm.c @@ -128,8 +128,7 @@ periph_permit_pm1(void) static void enter_pm0(void) { - ENERGEST_OFF(ENERGEST_TYPE_CPU); - ENERGEST_ON(ENERGEST_TYPE_LPM); + ENERGEST_SWITCH(ENERGEST_TYPE_CPU, ENERGEST_TYPE_LPM); /* We are only interested in IRQ energest while idle or in LPM */ ENERGEST_IRQ_RESTORE(irq_energest); @@ -147,8 +146,7 @@ enter_pm0(void) /* Remember IRQ energest for next pass */ ENERGEST_IRQ_SAVE(irq_energest); - ENERGEST_ON(ENERGEST_TYPE_CPU); - ENERGEST_OFF(ENERGEST_TYPE_LPM); + ENERGEST_SWITCH(ENERGEST_TYPE_LPM, ENERGEST_TYPE_CPU); } /*---------------------------------------------------------------------------*/ static void @@ -238,8 +236,7 @@ lpm_exit() /* Remember IRQ energest for next pass */ ENERGEST_IRQ_SAVE(irq_energest); - ENERGEST_ON(ENERGEST_TYPE_CPU); - ENERGEST_OFF(ENERGEST_TYPE_LPM); + ENERGEST_SWITCH(ENERGEST_TYPE_LPM, ENERGEST_TYPE_CPU); } /*---------------------------------------------------------------------------*/ void @@ -312,8 +309,7 @@ lpm_enter() /* We are only interested in IRQ energest while idle or in LPM */ ENERGEST_IRQ_RESTORE(irq_energest); - ENERGEST_OFF(ENERGEST_TYPE_CPU); - ENERGEST_ON(ENERGEST_TYPE_LPM); + ENERGEST_SWITCH(ENERGEST_TYPE_CPU, ENERGEST_TYPE_LPM); /* Remember the current time so we can keep stats when we wake up */ if(LPM_CONF_STATS) { @@ -339,8 +335,7 @@ lpm_enter() /* Remember IRQ energest for next pass */ ENERGEST_IRQ_SAVE(irq_energest); - ENERGEST_ON(ENERGEST_TYPE_CPU); - ENERGEST_OFF(ENERGEST_TYPE_LPM); + ENERGEST_SWITCH(ENERGEST_TYPE_LPM, ENERGEST_TYPE_CPU); } else { /* All clear. Assert WFI and drop to PM1/2. This is now un-interruptible */ assert_wfi(); diff --git a/cpu/cc26xx-cc13xx/lpm.c b/cpu/cc26xx-cc13xx/lpm.c index 2f7b964f8..3484b74bf 100644 --- a/cpu/cc26xx-cc13xx/lpm.c +++ b/cpu/cc26xx-cc13xx/lpm.c @@ -202,8 +202,7 @@ wake_up(void) /* Remember IRQ energest for next pass */ ENERGEST_IRQ_SAVE(irq_energest); - ENERGEST_ON(ENERGEST_TYPE_CPU); - ENERGEST_OFF(ENERGEST_TYPE_LPM); + ENERGEST_SWITCH(ENERGEST_TYPE_LPM, ENERGEST_TYPE_CPU); /* Sync so that we get the latest values before adjusting recharge settings */ ti_lib_sys_ctrl_aon_sync(); @@ -396,8 +395,7 @@ lpm_drop() /* We are only interested in IRQ energest while idle or in LPM */ ENERGEST_IRQ_RESTORE(irq_energest); - ENERGEST_OFF(ENERGEST_TYPE_CPU); - ENERGEST_ON(ENERGEST_TYPE_LPM); + ENERGEST_SWITCH(ENERGEST_TYPE_CPU, ENERGEST_TYPE_LPM); /* Sync the AON interface to ensure all writes have gone through. */ ti_lib_sys_ctrl_aon_sync(); @@ -429,8 +427,7 @@ lpm_drop() void lpm_sleep(void) { - ENERGEST_OFF(ENERGEST_TYPE_CPU); - ENERGEST_ON(ENERGEST_TYPE_LPM); + ENERGEST_SWITCH(ENERGEST_TYPE_CPU, ENERGEST_TYPE_LPM); /* We are only interested in IRQ energest while idle or in LPM */ ENERGEST_IRQ_RESTORE(irq_energest); @@ -443,8 +440,7 @@ lpm_sleep(void) /* Remember IRQ energest for next pass */ ENERGEST_IRQ_SAVE(irq_energest); - ENERGEST_ON(ENERGEST_TYPE_CPU); - ENERGEST_OFF(ENERGEST_TYPE_LPM); + ENERGEST_SWITCH(ENERGEST_TYPE_LPM, ENERGEST_TYPE_CPU); } /*---------------------------------------------------------------------------*/ void diff --git a/platform/cc2530dk/contiki-main.c b/platform/cc2530dk/contiki-main.c index 88c7763a4..164481512 100644 --- a/platform/cc2530dk/contiki-main.c +++ b/platform/cc2530dk/contiki-main.c @@ -335,8 +335,7 @@ main(void) CC_NON_BANKED if(SLEEPCMD & SLEEP_MODE0) { #endif /* LPM_MODE==LPM_MODE_PM2 */ - ENERGEST_OFF(ENERGEST_TYPE_CPU); - ENERGEST_ON(ENERGEST_TYPE_LPM); + ENERGEST_SWITCH(ENERGEST_TYPE_CPU, ENERGEST_TYPE_LPM); /* We are only interested in IRQ energest while idle or in LPM */ ENERGEST_IRQ_RESTORE(irq_energest); @@ -352,8 +351,7 @@ main(void) CC_NON_BANKED /* Remember energest IRQ for next pass */ ENERGEST_IRQ_SAVE(irq_energest); - ENERGEST_ON(ENERGEST_TYPE_CPU); - ENERGEST_OFF(ENERGEST_TYPE_LPM); + ENERGEST_SWITCH(ENERGEST_TYPE_LPM, ENERGEST_TYPE_CPU); #if (LPM_MODE==LPM_MODE_PM2) SLEEPCMD &= ~SLEEP_OSC_PD; /* Make sure both HS OSCs are on */ diff --git a/platform/exp5438/contiki-exp5438-main.c b/platform/exp5438/contiki-exp5438-main.c index 589a9572d..2f85f6ba2 100644 --- a/platform/exp5438/contiki-exp5438-main.c +++ b/platform/exp5438/contiki-exp5438-main.c @@ -307,8 +307,7 @@ main(int argc, char **argv) static unsigned long irq_energest = 0; /* Re-enable interrupts and go to sleep atomically. */ - ENERGEST_OFF(ENERGEST_TYPE_CPU); - ENERGEST_ON(ENERGEST_TYPE_LPM); + ENERGEST_SWITCH(ENERGEST_TYPE_CPU, ENERGEST_TYPE_LPM); /* We only want to measure the processing done in IRQs when we are asleep, so we discard the processing time done when we were awake. */ @@ -327,8 +326,7 @@ main(int argc, char **argv) irq_energest = energest_type_time(ENERGEST_TYPE_IRQ); eint(); watchdog_start(); - ENERGEST_OFF(ENERGEST_TYPE_LPM); - ENERGEST_ON(ENERGEST_TYPE_CPU); + ENERGEST_SWITCH(ENERGEST_TYPE_LPM, ENERGEST_TYPE_CPU); } } } diff --git a/platform/mbxxx/contiki-main.c b/platform/mbxxx/contiki-main.c index 020591aff..8a6867d74 100644 --- a/platform/mbxxx/contiki-main.c +++ b/platform/mbxxx/contiki-main.c @@ -251,15 +251,13 @@ main(void) - ENERGEST_OFF(ENERGEST_TYPE_CPU); - /* watchdog_stop(); */ - ENERGEST_ON(ENERGEST_TYPE_LPM); + /* watchdog_stop(); */ + ENERGEST_SWITCH(ENERGEST_TYPE_CPU, ENERGEST_TYPE_LPM); /* Go to idle mode. */ halSleepWithOptions(SLEEPMODE_IDLE,0); /* We are awake. */ /* watchdog_start(); */ - ENERGEST_OFF(ENERGEST_TYPE_LPM); - ENERGEST_ON(ENERGEST_TYPE_CPU); + ENERGEST_SWITCH(ENERGEST_TYPE_LPM, ENERGEST_TYPE_CPU); } diff --git a/platform/seedeye/contiki-seedeye-main.c b/platform/seedeye/contiki-seedeye-main.c index dabb8f126..5394b8e02 100644 --- a/platform/seedeye/contiki-seedeye-main.c +++ b/platform/seedeye/contiki-seedeye-main.c @@ -165,15 +165,13 @@ main(int argc, char **argv) r = process_run(); } while(r > 0); - ENERGEST_OFF(ENERGEST_TYPE_CPU); - ENERGEST_ON(ENERGEST_TYPE_LPM); + ENERGEST_SWITCH(ENERGEST_TYPE_CPU, ENERGEST_TYPE_LPM); watchdog_stop(); asm volatile("wait"); watchdog_start(); - ENERGEST_OFF(ENERGEST_TYPE_LPM); - ENERGEST_ON(ENERGEST_TYPE_CPU); + ENERGEST_SWITCH(ENERGEST_TYPE_LPM, ENERGEST_TYPE_CPU); } diff --git a/platform/sensinode/contiki-sensinode-main.c b/platform/sensinode/contiki-sensinode-main.c index 9ba3766be..541b28d26 100644 --- a/platform/sensinode/contiki-sensinode-main.c +++ b/platform/sensinode/contiki-sensinode-main.c @@ -346,8 +346,7 @@ main(void) if(SLEEP & SLEEP_MODE0) { #endif /* LPM_MODE==LPM_MODE_PM2 */ - ENERGEST_OFF(ENERGEST_TYPE_CPU); - ENERGEST_ON(ENERGEST_TYPE_LPM); + ENERGEST_SWITCH(ENERGEST_TYPE_CPU, ENERGEST_TYPE_LPM); /* We are only interested in IRQ energest while idle or in LPM */ ENERGEST_IRQ_RESTORE(irq_energest); @@ -363,8 +362,7 @@ main(void) /* Remember energest IRQ for next pass */ ENERGEST_IRQ_SAVE(irq_energest); - ENERGEST_ON(ENERGEST_TYPE_CPU); - ENERGEST_OFF(ENERGEST_TYPE_LPM); + ENERGEST_SWITCH(ENERGEST_TYPE_LPM, ENERGEST_TYPE_CPU); #if (LPM_MODE==LPM_MODE_PM2) SLEEP &= ~OSC_PD; /* Make sure both HS OSCs are on */ diff --git a/platform/sky/contiki-sky-main.c b/platform/sky/contiki-sky-main.c index 46f6f99de..a099778c6 100644 --- a/platform/sky/contiki-sky-main.c +++ b/platform/sky/contiki-sky-main.c @@ -465,8 +465,7 @@ main(int argc, char **argv) #endif /* Re-enable interrupts and go to sleep atomically. */ - ENERGEST_OFF(ENERGEST_TYPE_CPU); - ENERGEST_ON(ENERGEST_TYPE_LPM); + ENERGEST_SWITCH(ENERGEST_TYPE_CPU, ENERGEST_TYPE_LPM); /* We only want to measure the processing done in IRQs when we are asleep, so we discard the processing time done when we were awake. */ @@ -489,8 +488,7 @@ main(int argc, char **argv) irq_energest = energest_type_time(ENERGEST_TYPE_IRQ); eint(); watchdog_start(); - ENERGEST_OFF(ENERGEST_TYPE_LPM); - ENERGEST_ON(ENERGEST_TYPE_CPU); + ENERGEST_SWITCH(ENERGEST_TYPE_LPM, ENERGEST_TYPE_CPU); } } diff --git a/platform/wismote/contiki-wismote-main.c b/platform/wismote/contiki-wismote-main.c index 8a79811ac..df0162585 100644 --- a/platform/wismote/contiki-wismote-main.c +++ b/platform/wismote/contiki-wismote-main.c @@ -425,8 +425,7 @@ main(int argc, char **argv) static unsigned long irq_energest = 0; /* Re-enable interrupts and go to sleep atomically. */ - ENERGEST_OFF(ENERGEST_TYPE_CPU); - ENERGEST_ON(ENERGEST_TYPE_LPM); + ENERGEST_SWITCH(ENERGEST_TYPE_CPU, ENERGEST_TYPE_LPM); /* We only want to measure the processing done in IRQs when we are asleep, so we discard the processing time done when we were awake. */ @@ -445,8 +444,7 @@ main(int argc, char **argv) irq_energest = energest_type_time(ENERGEST_TYPE_IRQ); eint(); watchdog_start(); - ENERGEST_OFF(ENERGEST_TYPE_LPM); - ENERGEST_ON(ENERGEST_TYPE_CPU); + ENERGEST_SWITCH(ENERGEST_TYPE_LPM, ENERGEST_TYPE_CPU); } } } diff --git a/platform/z1/contiki-z1-main.c b/platform/z1/contiki-z1-main.c index bab055d08..45e97bde9 100644 --- a/platform/z1/contiki-z1-main.c +++ b/platform/z1/contiki-z1-main.c @@ -452,8 +452,7 @@ main(int argc, char **argv) #endif /* Re-enable interrupts and go to sleep atomically. */ - ENERGEST_OFF(ENERGEST_TYPE_CPU); - ENERGEST_ON(ENERGEST_TYPE_LPM); + ENERGEST_SWITCH(ENERGEST_TYPE_CPU, ENERGEST_TYPE_LPM); /* We only want to measure the processing done in IRQs when we are asleep, so we discard the processing time done when we were awake. */ @@ -472,8 +471,7 @@ main(int argc, char **argv) irq_energest = energest_type_time(ENERGEST_TYPE_IRQ); eint(); watchdog_start(); - ENERGEST_OFF(ENERGEST_TYPE_LPM); - ENERGEST_ON(ENERGEST_TYPE_CPU); + ENERGEST_SWITCH(ENERGEST_TYPE_LPM, ENERGEST_TYPE_CPU); } } From eac1973073962faab0400935becb54567c04199b Mon Sep 17 00:00:00 2001 From: Atis Elsts Date: Thu, 3 Sep 2015 15:53:10 +0200 Subject: [PATCH 066/120] Introduce ENERGEST_SWITCH macro. It allows to switch between energest modes without running into the risk of losing a tick in the process --- core/sys/energest.h | 28 +++++++++++++++++++++++++++- 1 file changed, 27 insertions(+), 1 deletion(-) diff --git a/core/sys/energest.h b/core/sys/energest.h index 6d43aaa11..a8f445b65 100644 --- a/core/sys/energest.h +++ b/core/sys/energest.h @@ -105,6 +105,21 @@ extern energest_t energest_leveldevice_current_leveltime[ENERGEST_CONF_LEVELDEVI energest_current_time[type]); \ energest_current_mode[type] = 0; \ } while(0) + +#define ENERGEST_SWITCH(type_off, type_on) do { \ + rtimer_clock_t energest_local_variable_now = RTIMER_NOW(); \ + if(energest_current_mode[type_off] != 0) { \ + if (energest_local_variable_now < energest_current_time[type_off]) { \ + energest_total_time[type_off].current += RTIMER_ARCH_SECOND; \ + } \ + energest_total_time[type_off].current += (rtimer_clock_t)(energest_local_variable_now - \ + energest_current_time[type_off]); \ + energest_current_mode[type_off] = 0; \ + } \ + energest_current_time[type_on] = energest_local_variable_now; \ + energest_current_mode[type_on] = 1; \ + } while(0) + #else #define ENERGEST_OFF(type) if(energest_current_mode[type] != 0) do { \ energest_total_time[type].current += (rtimer_clock_t)(RTIMER_NOW() - \ @@ -117,13 +132,24 @@ extern energest_t energest_leveldevice_current_leveltime[ENERGEST_CONF_LEVELDEVI energest_current_time[type]); \ energest_current_mode[type] = 0; \ } while(0) -#endif +#define ENERGEST_SWITCH(type_off, type_on) do { \ + rtimer_clock_t energest_local_variable_now = RTIMER_NOW(); \ + if(energest_current_mode[type_off] != 0) { \ + energest_total_time[type_off].current += (rtimer_clock_t)(energest_local_variable_now - \ + energest_current_time[type_off]); \ + energest_current_mode[type_off] = 0; \ + } \ + energest_current_time[type_on] = energest_local_variable_now; \ + energest_current_mode[type_on] = 1; \ + } while(0) +#endif #else /* ENERGEST_CONF_ON */ #define ENERGEST_ON(type) do { } while(0) #define ENERGEST_OFF(type) do { } while(0) #define ENERGEST_OFF_LEVEL(type,level) do { } while(0) +#define ENERGEST_SWITCH(type_off, type_on) do { } while(0) #endif /* ENERGEST_CONF_ON */ #endif /* ENERGEST_H_ */ From 158087db626b19c868d078fa7712e993aeeabaa8 Mon Sep 17 00:00:00 2001 From: Arthur Fabre Date: Thu, 16 Jul 2015 10:25:10 +0100 Subject: [PATCH 067/120] Fix warning in coap-observe MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ../..//apps/er-coap/er-coap-observe.c:237:15: warning: unused variable ‘content’ [-Wunused-variable] This was caused by a buffer that was declared, but used only in commented out code. The variable was moved to the commented out block. The block was surrounded by an #if 0 ... #endif to make it easier to uncomment. Everything still compiles with the code in question uncommented. --- apps/er-coap/er-coap-observe.c | 17 ++++++++--------- 1 file changed, 8 insertions(+), 9 deletions(-) diff --git a/apps/er-coap/er-coap-observe.c b/apps/er-coap/er-coap-observe.c index 4e3d2baa1..710671bff 100644 --- a/apps/er-coap/er-coap-observe.c +++ b/apps/er-coap/er-coap-observe.c @@ -234,8 +234,6 @@ coap_observe_handler(resource_t *resource, void *request, void *response) coap_packet_t *const coap_res = (coap_packet_t *)response; coap_observer_t * obs; - static char content[16]; - if(coap_req->code == COAP_GET && coap_res->code < 128) { /* GET request and response without error code */ if(IS_OPTION(coap_req, COAP_OPTION_OBSERVE)) { if(coap_req->observe == 0) { @@ -249,13 +247,14 @@ coap_observe_handler(resource_t *resource, void *request, void *response) * A subscription should return the same representation as a normal GET. * Uncomment if you want an information about the avaiable observers. */ - /* - * coap_set_payload(coap_res, - * content, - * snprintf(content, sizeof(content), "Added %u/%u", - * list_length(observers_list), - * COAP_MAX_OBSERVERS)); - */ +#if 0 + static char content[16]; + coap_set_payload(coap_res, + content, + snprintf(content, sizeof(content), "Added %u/%u", + list_length(observers_list), + COAP_MAX_OBSERVERS)); +#endif } else { coap_res->code = SERVICE_UNAVAILABLE_5_03; coap_set_payload(coap_res, "TooManyObservers", 16); From e8cbf2e5fb40dc894416b8028525f6a3ee8e8b10 Mon Sep 17 00:00:00 2001 From: Arthur Fabre Date: Thu, 16 Jul 2015 10:20:36 +0100 Subject: [PATCH 068/120] Fix warning in TCPIP MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit When disabling TCP support, the following warning is triggered: ../..//core/net/ip/tcpip.c:159:1: warning: ‘start_periodic_tcp_timer’ defined but not used [-Wunused-function] An added ifdef guard now only defines this function when TCP support is enabled. --- core/net/ip/tcpip.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/core/net/ip/tcpip.c b/core/net/ip/tcpip.c index 1c75d1bc9..839330ab7 100644 --- a/core/net/ip/tcpip.c +++ b/core/net/ip/tcpip.c @@ -155,6 +155,7 @@ unsigned char tcpip_is_forwarding; /* Forwarding right now? */ PROCESS(tcpip_process, "TCP/IP stack"); /*---------------------------------------------------------------------------*/ +#if UIP_TCP || UIP_CONF_IP_FORWARD static void start_periodic_tcp_timer(void) { @@ -162,6 +163,7 @@ start_periodic_tcp_timer(void) etimer_restart(&periodic); } } +#endif /* UIP_TCP || UIP_CONF_IP_FORWARD */ /*---------------------------------------------------------------------------*/ static void check_for_tcp_syn(void) From 27dd3f493b8312578fab623f4c57b992a70de67b Mon Sep 17 00:00:00 2001 From: Sumankumar Panchal Date: Tue, 4 Aug 2015 18:17:34 +0530 Subject: [PATCH 069/120] Solved issue with CC2520_READ_REG macro to read correct value of register. --- dev/cc2520/cc2520.h | 1 + 1 file changed, 1 insertion(+) diff --git a/dev/cc2520/cc2520.h b/dev/cc2520/cc2520.h index 18a43649a..3c8e654ef 100644 --- a/dev/cc2520/cc2520.h +++ b/dev/cc2520/cc2520.h @@ -118,6 +118,7 @@ void cc2520_set_cca_threshold(int value); CC2520_SPI_ENABLE(); \ SPI_WRITE((CC2520_INS_MEMRD | ((adr>>8)&0xFF))); \ SPI_WRITE((adr & 0xFF)); \ + (void)SPI_RXBUF; \ SPI_READ(data); \ CC2520_SPI_DISABLE(); \ } while(0) From 5329c420348e14eca69aece749e4193688ba0e42 Mon Sep 17 00:00:00 2001 From: Simon Duquennoy Date: Tue, 8 Sep 2015 23:37:20 +0200 Subject: [PATCH 070/120] Remove unused variables --- core/net/rpl/rpl-icmp6.c | 4 ---- 1 file changed, 4 deletions(-) diff --git a/core/net/rpl/rpl-icmp6.c b/core/net/rpl/rpl-icmp6.c index 0a4488d13..5121cf23a 100644 --- a/core/net/rpl/rpl-icmp6.c +++ b/core/net/rpl/rpl-icmp6.c @@ -918,15 +918,11 @@ dao_ack_input(void) { #if DEBUG unsigned char *buffer; - uint8_t buffer_length; - uint8_t instance_id; uint8_t sequence; uint8_t status; buffer = UIP_ICMP_PAYLOAD; - buffer_length = uip_len - uip_l3_icmp_hdr_len; - instance_id = buffer[0]; sequence = buffer[2]; status = buffer[3]; From 72aac552ef0e87d71ac14e1f324b3916cea5ddba Mon Sep 17 00:00:00 2001 From: Mattias Buelens Date: Wed, 9 Sep 2015 22:56:25 +0200 Subject: [PATCH 071/120] Cooja: Track CFS file size Previously, the Cooja mote assumed that its file was always initially empty (file.endptr == 0). Therefore, a file uploaded to a mote's CFS could never be read by the mote, as the mote would prevent reads from going past the EOF (indicated by endptr). By tracking the file size and making it accessible to Cooja, the correct size of the uploaded file can be reported to the mote and allow it to read the uploaded file. --- platform/cooja/cfs/cfs-cooja.c | 18 +++++++++++++----- .../contikimote/interfaces/ContikiCFS.java | 4 +++- 2 files changed, 16 insertions(+), 6 deletions(-) diff --git a/platform/cooja/cfs/cfs-cooja.c b/platform/cooja/cfs/cfs-cooja.c index 0119ea5a0..40d1c3ceb 100644 --- a/platform/cooja/cfs/cfs-cooja.c +++ b/platform/cooja/cfs/cfs-cooja.c @@ -50,6 +50,7 @@ const struct simInterface cfs_interface; // COOJA variables #define CFS_BUF_SIZE 4000 /* Configure CFS size here and in ContikiCFS.java */ char simCFSData[CFS_BUF_SIZE] = { 0 }; +int simCFSSize = 0; char simCFSChanged = 0; int simCFSRead = 0; int simCFSWritten = 0; @@ -61,11 +62,15 @@ cfs_open(const char *n, int f) if(file.flag == FLAG_FILE_CLOSED) { file.flag = FLAG_FILE_OPEN; file.access = f; - if(f & CFS_APPEND) { - file.fileptr = file.endptr; - } else { - file.fileptr = 0; - } + file.fileptr = 0; + file.endptr = simCFSSize; + if(f & CFS_WRITE) { + if(f & CFS_APPEND) { + file.fileptr = file.endptr; + } else { + file.endptr = 0; + } + } return 0; } else { return -1; @@ -110,6 +115,9 @@ cfs_write(int f, const void *buf, unsigned int len) if(file.fileptr > file.endptr) { file.endptr = file.fileptr; } + if(file.fileptr > simCFSSize) { + simCFSSize = file.fileptr; + } return len; } else { return -1; diff --git a/tools/cooja/java/org/contikios/cooja/contikimote/interfaces/ContikiCFS.java b/tools/cooja/java/org/contikios/cooja/contikimote/interfaces/ContikiCFS.java index 5a8dbb41e..f1985b6cc 100644 --- a/tools/cooja/java/org/contikios/cooja/contikimote/interfaces/ContikiCFS.java +++ b/tools/cooja/java/org/contikios/cooja/contikimote/interfaces/ContikiCFS.java @@ -120,6 +120,7 @@ public class ContikiCFS extends MoteInterface implements ContikiMoteInterface, P } moteMem.setByteArray("simCFSData", data); + moteMem.setIntValueOf("simCFSSize", data.length); return true; } @@ -129,7 +130,8 @@ public class ContikiCFS extends MoteInterface implements ContikiMoteInterface, P * @return Filesystem data */ public byte[] getFilesystemData() { - return moteMem.getByteArray("simCFSData", FILESYSTEM_SIZE); + int size = moteMem.getIntValueOf("simCFSSize"); + return moteMem.getByteArray("simCFSData", size); } /** From b729dc898582d31639e80ab600fbba381987329e Mon Sep 17 00:00:00 2001 From: Valentin Sawadski Date: Thu, 10 Sep 2015 11:13:22 +0200 Subject: [PATCH 072/120] Don't override LDFLAGS on Linux for the native CPU --- cpu/native/Makefile.native | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cpu/native/Makefile.native b/cpu/native/Makefile.native index bf4e8ea47..ea7a2bc27 100644 --- a/cpu/native/Makefile.native +++ b/cpu/native/Makefile.native @@ -25,7 +25,7 @@ LDFLAGS += -Wl,-flat_namespace CFLAGS += -DHAVE_SNPRINTF=1 -U__ASSERT_USE_STDERR else ifeq ($(HOST_OS),Linux) -LDFLAGS = -Wl,-Map=contiki-$(TARGET).map,-export-dynamic +LDFLAGS += -Wl,-Map=contiki-$(TARGET).map,-export-dynamic endif endif From 1e0b5292d7072ab4633544e9cd2e512aa6909bca Mon Sep 17 00:00:00 2001 From: Joakim Eriksson Date: Thu, 30 Apr 2015 12:16:04 +0200 Subject: [PATCH 073/120] Loop-unroll in CoAP for fixing some potential bugs on some platforms where size_t is not the same as unsigned int. --- apps/er-coap/er-coap.c | 58 ++++++++++++++++++++++++------------------ 1 file changed, 33 insertions(+), 25 deletions(-) diff --git a/apps/er-coap/er-coap.c b/apps/er-coap/er-coap.c index 34c671623..f49d947d9 100644 --- a/apps/er-coap/er-coap.c +++ b/apps/er-coap/er-coap.c @@ -113,17 +113,19 @@ coap_set_option_header(unsigned int delta, size_t length, uint8_t *buffer) buffer[0] = coap_option_nibble(delta) << 4 | coap_option_nibble(length); - /* avoids code duplication without function overhead */ - unsigned int *x = δ + if(delta > 268) { + buffer[++written] = ((delta - 269) >> 8) & 0xff; + buffer[++written] = (delta - 269) & 0xff; + } else if(delta > 12) { + buffer[++written] = (delta - 13); + } - do { - if(*x > 268) { - buffer[++written] = (*x - 269) >> 8; - buffer[++written] = (*x - 269); - } else if(*x > 12) { - buffer[++written] = (*x - 13); - } - } while(x != &length && (x = &length)); + if(length > 268) { + buffer[++written] = ((length - 269) >> 8) & 0xff; + buffer[++written] = (length - 269) & 0xff; + } else if(length > 12) { + buffer[++written] = (length - 13); + } PRINTF("WRITTEN %u B opt header\n", 1 + written); @@ -500,25 +502,31 @@ coap_parse_message(void *packet, uint8_t *data, uint16_t data_len) option_length = current_option[0] & 0x0F; ++current_option; - /* avoids code duplication without function overhead */ - unsigned int *x = &option_delta; + if(option_delta == 13) { + option_delta += current_option[0]; + ++current_option; + } else if(option_delta == 14) { + option_delta += 255; + option_delta += current_option[0] << 8; + ++current_option; + option_delta += current_option[0]; + ++current_option; + } - do { - if(*x == 13) { - *x += current_option[0]; - ++current_option; - } else if(*x == 14) { - *x += 255; - *x += current_option[0] << 8; - ++current_option; - *x += current_option[0]; - ++current_option; - } - } while(x != &option_length && (x = &option_length)); + if(option_length == 13) { + option_length += current_option[0]; + ++current_option; + } else if(option_length == 14) { + option_length += 255; + option_length += current_option[0] << 8; + ++current_option; + option_length += current_option[0]; + ++current_option; + } option_number += option_delta; - PRINTF("OPTION %u (delta %u, len %u): ", option_number, option_delta, + PRINTF("OPTION %u (delta %u, len %zu): ", option_number, option_delta, option_length); SET_OPTION(coap_pkt, option_number); From fe6d8685ac664a5b006a400ae088c6e84ef6a24c Mon Sep 17 00:00:00 2001 From: Joakim Eriksson Date: Thu, 30 Apr 2015 13:29:31 +0200 Subject: [PATCH 074/120] Fixed support for NULL attributes of resources --- apps/er-coap/er-coap-res-well-known-core.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/apps/er-coap/er-coap-res-well-known-core.c b/apps/er-coap/er-coap-res-well-known-core.c index e684017cd..ea3b4bbe9 100644 --- a/apps/er-coap/er-coap-res-well-known-core.c +++ b/apps/er-coap/er-coap-res-well-known-core.c @@ -124,7 +124,7 @@ well_known_core_get_handler(void *request, void *response, uint8_t *buffer, continue; } end = attrib + strlen(attrib); - } else { + } else if(resource->attributes != NULL) { attrib = strstr(resource->attributes, filter); if(attrib == NULL || (attrib[strlen(filter)] != '=' @@ -159,8 +159,8 @@ well_known_core_get_handler(void *request, void *response, uint8_t *buffer, } #endif - PRINTF("res: /%s (%p)\npos: s%d, o%ld, b%d\n", resource->url, resource, - strpos, *offset, bufpos); + PRINTF("res: /%s (%p)\npos: s%zu, o%ld, b%zu\n", resource->url, resource, + strpos, (long)*offset, bufpos); if(strpos > 0) { ADD_CHAR_IF_POSSIBLE(','); @@ -170,7 +170,7 @@ well_known_core_get_handler(void *request, void *response, uint8_t *buffer, ADD_STRING_IF_POSSIBLE(resource->url, >=); ADD_CHAR_IF_POSSIBLE('>'); - if(resource->attributes[0]) { + if(resource->attributes != NULL && resource->attributes[0]) { ADD_CHAR_IF_POSSIBLE(';'); ADD_STRING_IF_POSSIBLE(resource->attributes, >); } @@ -183,7 +183,7 @@ well_known_core_get_handler(void *request, void *response, uint8_t *buffer, } if(bufpos > 0) { - PRINTF("BUF %d: %.*s\n", bufpos, bufpos, (char *)buffer); + PRINTF("BUF %zu: %.*s\n", bufpos, (int)bufpos, (char *)buffer); coap_set_payload(response, buffer, bufpos); coap_set_header_content_format(response, APPLICATION_LINK_FORMAT); From 46ffc509c163a2e75ea7afc1066a6e9af895ac00 Mon Sep 17 00:00:00 2001 From: Lars Schmertmann Date: Mon, 14 Sep 2015 14:19:42 +0200 Subject: [PATCH 075/120] Added App/Tool/Example for usage of additional flash on econotag/mc1322x --- .travis.yml | 1 + examples/econotag-flash-test/Makefile | 31 ++ examples/econotag-flash-test/README | 6 + .../econotag-flash-test/econotag-flash-test.c | 195 +++++++++++ .../econotag-flash-test.cfg | 7 + .../econotag-flash-test/econotag-flash-test.h | 66 ++++ platform/econotag/apps/flash/Makefile.flash | 1 + platform/econotag/apps/flash/flash.c | 207 +++++++++++ platform/econotag/apps/flash/flash.h | 178 ++++++++++ .../15-compile-arm-apcs-ports/Makefile | 1 + tools/blaster/Makefile | 19 + tools/blaster/README | 10 + tools/blaster/blaster.c | 330 ++++++++++++++++++ tools/blaster/blaster.h | 72 ++++ 14 files changed, 1124 insertions(+) create mode 100644 examples/econotag-flash-test/Makefile create mode 100644 examples/econotag-flash-test/README create mode 100644 examples/econotag-flash-test/econotag-flash-test.c create mode 100644 examples/econotag-flash-test/econotag-flash-test.cfg create mode 100644 examples/econotag-flash-test/econotag-flash-test.h create mode 100644 platform/econotag/apps/flash/Makefile.flash create mode 100644 platform/econotag/apps/flash/flash.c create mode 100644 platform/econotag/apps/flash/flash.h create mode 100644 tools/blaster/Makefile create mode 100644 tools/blaster/README create mode 100644 tools/blaster/blaster.c create mode 100644 tools/blaster/blaster.h diff --git a/.travis.yml b/.travis.yml index 98f98edff..b426b7c8b 100644 --- a/.travis.yml +++ b/.travis.yml @@ -36,6 +36,7 @@ before_script: tar xjf arm-2008q3*.tar.bz2 -C /tmp/ && sudo cp -f -r /tmp/arm-2008q3/* /usr/ && rm -rf /tmp/arm-2008q3 arm-2008q3*.tar.bz2 && + sudo apt-get -qq install libconfig-dev uuid-dev libqrencode-dev && arm-none-eabi-gcc --version ; fi diff --git a/examples/econotag-flash-test/Makefile b/examples/econotag-flash-test/Makefile new file mode 100644 index 000000000..82905440e --- /dev/null +++ b/examples/econotag-flash-test/Makefile @@ -0,0 +1,31 @@ +CONTIKI = ../.. +LIBMC1322X = ../../../libmc1322x + +CONTIKI_PROJECT = econotag-flash-test +TARGET = econotag +CLEAN = *.d $(CONTIKI_PROJECT)_e_$(TARGET).bin $(CONTIKI_PROJECT)_e_$(TARGET).txt $(CONTIKI_PROJECT)_e_$(TARGET).pbm + +all: $(CONTIKI_PROJECT) blast + +CFLAGS += -DFLASH_CONF_B1=30 +CFLAGS += -DFLASH_CONF_B2=10 + +APPS += flash + +flash: + $(LIBMC1322X)/tools/mc1322x-load \ + -f $(LIBMC1322X)/tests/flasher_$(TARGET).bin \ + -s $(CONTIKI_PROJECT)_e_$(TARGET).bin \ + -c 'sudo $(LIBMC1322X)/tools/ftditools/bbmc -l $(TARGET) -i 0 reset' \ + -t /dev/ttyUSB1 -l + +clear: + $(LIBMC1322X)/tools/ftditools/bbmc -l $(TARGET) -i 0 erase + +blast: $(CONTIKI)/tools/blaster/blaster + $(CONTIKI)/tools/blaster/blaster $(CONTIKI_PROJECT).cfg + +$(CONTIKI)/tools/blaster/blaster: $(CONTIKI)/tools/blaster/blaster.c + (cd $(CONTIKI)/tools/blaster && $(MAKE)) + +include $(CONTIKI)/Makefile.include diff --git a/examples/econotag-flash-test/README b/examples/econotag-flash-test/README new file mode 100644 index 000000000..ee8aa7d3d --- /dev/null +++ b/examples/econotag-flash-test/README @@ -0,0 +1,6 @@ +Its important to use -l as a flash parameter for mc1322xload. + +Use "make flash" to start upload. Maybe u need +to change the location of libmc1322x in Makefile. + +With "make clear" you can erase all flash data. diff --git a/examples/econotag-flash-test/econotag-flash-test.c b/examples/econotag-flash-test/econotag-flash-test.c new file mode 100644 index 000000000..04ef42d8f --- /dev/null +++ b/examples/econotag-flash-test/econotag-flash-test.c @@ -0,0 +1,195 @@ +/* + * Copyright (c) 2014, Lars Schmertmann . + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * + * This file is part of the Contiki operating system. + * + */ + +/** + * \file + * Flash test + * + * This file contains tests for econotag flash app + * + * \author + * Lars Schmertmann + */ + +#include "flash.h" +#include "contiki.h" + +#include +#include +#include + +#include "../../tools/blaster/blaster.h" +#include "econotag-flash-test.h" + +void +output_result(uint32_t i, uint32_t fail) +{ + if(fail) { + printf(" Test %u failed!\n", i); + } else { printf(" Test %u succeed!\n", i); + } +} +void +test_flash_1() +{ + uint8_t buffer[12]; + uint32_t check_int, my_int = 12345678; + + flash_setVar("Hello World!", RES_MY_STRING_1, LEN_MY_STRING_1); + + flash_getVar(buffer, RES_MY_STRING_1, LEN_MY_STRING_1); + output_result(1, memcmp(buffer, "Hello World!", 12)); + + flash_setVar("Heureka!", RES_MY_STRING_2, LEN_MY_STRING_2); + + flash_getVar(buffer, RES_MY_STRING_1, LEN_MY_STRING_1); + output_result(2, memcmp(buffer, "Hello World!", 12)); + + flash_getVar(buffer, RES_MY_STRING_2, LEN_MY_STRING_2); + output_result(3, memcmp(buffer, "Heureka!", 8)); + + flash_setVar(&my_int, RES_MY_INTEGER, LEN_MY_INTEGER); + + flash_getVar(&check_int, RES_MY_INTEGER, LEN_MY_INTEGER); + output_result(4, check_int != my_int); + + flash_getVar(buffer, RES_MY_STRING_1, LEN_MY_STRING_1); + output_result(5, memcmp(buffer, "Hello World!", 12)); + + flash_getVar(buffer, RES_MY_STRING_2, LEN_MY_STRING_2); + output_result(6, memcmp(buffer, "Heureka!", 8)); +} +void +test_flash_2() +{ + uint8_t buffer[12]; + uint32_t check_int, my_int = 12345678; + + flash_getVar(&check_int, RES_MY_INTEGER, LEN_MY_INTEGER); + output_result(1, check_int != my_int); + + flash_getVar(buffer, RES_MY_STRING_1, LEN_MY_STRING_1); + output_result(2, memcmp(buffer, "Hello World!", 12)); + + flash_getVar(buffer, RES_MY_STRING_2, LEN_MY_STRING_2); + output_result(3, memcmp(buffer, "Heureka!", 8)); + + /* Block 1 max usage is 30 Byte -> Optimisation in Makefile */ + output_result(4, flash_setVar("test", 0, 1) != gNvmErrInvalidPointer_c); + output_result(5, flash_setVar("test", 30, 1) != gNvmErrInvalidPointer_c); + output_result(6, flash_setVar("test", 29, 2) != gNvmErrAddressSpaceOverflow_c); + + /* Block 2 max usage is 10 Byte -> Optimisation in Makefile */ + output_result(7, flash_setVar("test", 4096, 1) != gNvmErrInvalidPointer_c); + output_result(8, flash_setVar("test", 4096 + 10, 1) != gNvmErrInvalidPointer_c); + output_result(9, flash_setVar("test", 4096 + 9, 2) != gNvmErrAddressSpaceOverflow_c); +} +void +test_flash_blaster() +{ + uint8_t buffer[64]; + + flash_getVar(buffer, RES_NAME, LEN_NAME); + output_result(1, memcmp(buffer, "Econotag Flash Test Device", 27)); + + flash_getVar(buffer, RES_MODEL, LEN_MODEL); + output_result(2, memcmp(buffer, "Model 1234 for testing purposes only", 37)); +} +void +test_flash_stack() +{ + uint8_t buffer[32]; + flash_stack_init(); + + output_result(1, flash_stack_size() != 0); + + flash_stack_push("Hello World!", 12); + output_result(2, flash_stack_size() != 12); + + flash_stack_read(buffer, 0, 12); + output_result(3, memcmp(buffer, "Hello World!", 12)); + + flash_stack_push("I love Contiki!", 15); + output_result(4, flash_stack_size() != 27); + + flash_stack_read(buffer, 0, 12); + output_result(5, memcmp(buffer, "Hello World!", 12)); + + flash_stack_read(buffer, 12, 15); + output_result(6, memcmp(buffer, "I love Contiki!", 15)); + + flash_stack_init(); + output_result(7, flash_stack_size() != 0); + + uint32_t i; + for(i = 1; i < 256; i++) { + flash_stack_push("I love Contiki! ", 16); + } + output_result(8, flash_stack_size() != 4080); + + output_result(9, flash_stack_push("1I love Contiki! ", 17) != gNvmErrAddressSpaceOverflow_c); +} +/* Start Process */ +PROCESS(server_firmware, "Server Firmware"); +AUTOSTART_PROCESSES(&server_firmware); + +PROCESS_THREAD(server_firmware, ev, data) { + PROCESS_BEGIN(); + + if(flash_cmp("\001", RES_DONTCLEAR, LEN_DONTCLEAR)) { + printf("Initializing flash ... "); + flash_init(); + printf("DONE\n"); + flash_setVar("\001", RES_DONTCLEAR, LEN_DONTCLEAR); + printf("Starting flash tests 1:\n"); + test_flash_1(); + int i; + for(i = 0; i < 1024; i++) { + printf("Reboot ...\r"); + } + soft_reset(); + } else { + printf("Initialization not wished\n"); + } + printf("Starting flash tests 2:\n"); + test_flash_2(); + + printf("Starting flash stack tests:\n"); + test_flash_stack(); + + printf("Starting flash blaster tests:\n"); + test_flash_blaster(); + + PROCESS_END(); +} diff --git a/examples/econotag-flash-test/econotag-flash-test.cfg b/examples/econotag-flash-test/econotag-flash-test.cfg new file mode 100644 index 000000000..9b26c4adb --- /dev/null +++ b/examples/econotag-flash-test/econotag-flash-test.cfg @@ -0,0 +1,7 @@ +input = "econotag-flash-test_econotag"; +output = "econotag-flash-test_e_econotag"; +eui = [ 0x2, 0x0, 0x0, 0x0, 0x12, 0x34, 0x56, 0x78 ]; +uuid = "cbf9889f-dc0e-4c18-9aa9-93509a6c102a"; +psk = "yCh0OXnSkFT-eXKE"; +name = "Econotag Flash Test Device"; +model = "Model 1234 for testing purposes only"; diff --git a/examples/econotag-flash-test/econotag-flash-test.h b/examples/econotag-flash-test/econotag-flash-test.h new file mode 100644 index 000000000..469d93faa --- /dev/null +++ b/examples/econotag-flash-test/econotag-flash-test.h @@ -0,0 +1,66 @@ +/* + * Copyright (c) 2014, Lars Schmertmann . + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * + * This file is part of the Contiki operating system. + * + */ + +/** + * \file + * Flash Management + * + * This file contains Pointers for manual flash management. + * + * \author + * Lars Schmertmann + */ + +#ifndef ECONOTAG_FLASH_TEST_H_ +#define ECONOTAG_FLASH_TEST_H_ + +/* Pointer for Block 1 --------------- */ + +#define RES_DONTCLEAR 1 +#define LEN_DONTCLEAR 1 + +#define RES_MY_STRING_1 2 +#define LEN_MY_STRING_1 12 + +#define RES_MY_STRING_2 14 +#define LEN_MY_STRING_2 8 + +/* Pointer for Block 2 --------------- */ + +#define RES_MY_INTEGER (4096 + 1) +#define LEN_MY_INTEGER 4 + +/* ------------------------------------ */ + +#endif /* ECONOTAG_FLASH_TEST_H_ */ diff --git a/platform/econotag/apps/flash/Makefile.flash b/platform/econotag/apps/flash/Makefile.flash new file mode 100644 index 000000000..d78891b5c --- /dev/null +++ b/platform/econotag/apps/flash/Makefile.flash @@ -0,0 +1 @@ +flash_src = flash.c diff --git a/platform/econotag/apps/flash/flash.c b/platform/econotag/apps/flash/flash.c new file mode 100644 index 000000000..959724697 --- /dev/null +++ b/platform/econotag/apps/flash/flash.c @@ -0,0 +1,207 @@ +/* + * Copyright (c) 2014, Lars Schmertmann . + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * + * This file is part of the Contiki operating system. + * + */ + +#include "flash.h" + +#define FLASH_BLOCK_SIZE 0x01000 + +#define FLASH_BLOCK_11 0x18000 +#define FLASH_BLOCK_21 0x1A000 + +#ifndef FLASH_CONF_B1 +#define FLASH_CONF_B1 FLASH_BLOCK_SIZE +#endif + +#ifndef FLASH_CONF_B2 +#define FLASH_CONF_B2 FLASH_BLOCK_SIZE +#endif + +#define DEBUG 0 + +#if DEBUG +#include +#include "mc1322x.h" +#define PRINTF(...) printf(__VA_ARGS__) +#else +#define PRINTF(...) +#endif + +uint16_t stackPointer; + +/* private prototypes ----------------------------------------------------- */ + +flash_addr_t getAddr(flash_addr_t address); + +/* public functions -------------------------------------------------------- */ + +void +flash_init() +{ + PRINTF("Initializing flash ... "); + + nvm_erase(gNvmInternalInterface_c, gNvmType_SST_c, 0x0F000000); + + nvm_write(gNvmInternalInterface_c, gNvmType_SST_c, "\001", FLASH_BLOCK_11, 1); + nvm_write(gNvmInternalInterface_c, gNvmType_SST_c, "\001", FLASH_BLOCK_21, 1); + + uint32_t i; + for(i = 1; i < 0x2000; i++) { +#if DEBUG + if(i % 0x400 == 0) { + PRINTF(" ."); + } +#endif + nvm_write(gNvmInternalInterface_c, gNvmType_SST_c, "\0", FLASH_BLOCK_11 + i, 1); + nvm_write(gNvmInternalInterface_c, gNvmType_SST_c, "\0", FLASH_BLOCK_21 + i, 1); + } + + PRINTF("DONE\n"); +} +nvmErr_t +flash_getVar(void *dest, flash_addr_t address, uint32_t numBytes) +{ + address = getAddr(address); + + if(address >= 0x18000 && address <= 0x1EFFF) { + PRINTF("Read from Adress: %p\n", address); + nvmErr_t err = nvm_read(gNvmInternalInterface_c, gNvmType_SST_c, dest, address, numBytes); + if(err) { + PRINTF("Read error, nmv_error: %u\n", err); + return err; + } + return gNvmErrNoError_c; + } + + PRINTF("Read error - Invalid pointer.\n"); + return gNvmErrInvalidPointer_c; +} +nvmErr_t +flash_setVar(void *src, flash_addr_t address, uint32_t numBytes) +{ +#if DEBUG + printf("SetVar - START . "); + uint32_t time = *MACA_CLK; +#endif + + if(address >= 8192) { + PRINTF("Write error - Invalid pointer.\n"); + return gNvmErrInvalidPointer_c; + } + uint32_t block_len = (address < 4096 ? FLASH_CONF_B1 : FLASH_CONF_B2); + + address = getAddr(address); + + flash_addr_t src_block = address & 0xFF000; + flash_addr_t dst_block = src_block ^ 0x01000; + address = address & 0x00FFF; + + if(address < 1 || address >= block_len) { + PRINTF("Write error - Invalid pointer.\n"); + return gNvmErrInvalidPointer_c; + } + if(address + numBytes > block_len) { + PRINTF("Write error - Var is to long.\n"); + return gNvmErrAddressSpaceOverflow_c; + } + + nvm_erase(gNvmInternalInterface_c, gNvmType_SST_c, 1 << (dst_block / FLASH_BLOCK_SIZE)); + + uint32_t i; + uint8_t buf; + for(i = 0; i < address; i++) { + nvm_read(gNvmInternalInterface_c, gNvmType_SST_c, &buf, src_block + i, 1); + nvm_write(gNvmInternalInterface_c, gNvmType_SST_c, &buf, dst_block + i, 1); + } + PRINTF("Write to adress: %p\n", dst_block + i); + nvm_write(gNvmInternalInterface_c, gNvmType_SST_c, src, dst_block + i, numBytes); + for(i += numBytes; i < block_len; i++) { + nvm_read(gNvmInternalInterface_c, gNvmType_SST_c, &buf, src_block + i, 1); + nvm_write(gNvmInternalInterface_c, gNvmType_SST_c, &buf, dst_block + i, 1); + } + + nvm_erase(gNvmInternalInterface_c, gNvmType_SST_c, 1 << (src_block / FLASH_BLOCK_SIZE)); + +#if DEBUG + time = *MACA_CLK - time; + printf("FINISHED AFTER %u MS\n", time / 250); +#endif + + return gNvmErrNoError_c; +} +nvmErr_t +flash_cmp(void *src, flash_addr_t address, uint32_t numBytes) +{ + address = getAddr(address); + + if(address >= 0x18000 && address <= 0x1EFFF) { + return nvm_verify(gNvmInternalInterface_c, gNvmType_SST_c, src, address, numBytes); + } + PRINTF("Read error - Invalid pointer.\n"); + return gNvmErrInvalidPointer_c; +} +void +flash_stack_init() +{ + stackPointer = 0; + nvm_erase(gNvmInternalInterface_c, gNvmType_SST_c, 1 << (FLASH_STACK / FLASH_BLOCK_SIZE)); +} +nvmErr_t +flash_stack_push(uint8_t *src, uint32_t numBytes) +{ + if(stackPointer + numBytes > FLASH_BLOCK_SIZE) { + return gNvmErrAddressSpaceOverflow_c; + } + + nvm_write(gNvmInternalInterface_c, gNvmType_SST_c, src, FLASH_STACK + stackPointer, numBytes); + stackPointer += numBytes; + return gNvmErrNoError_c; +} +uint32_t +flash_stack_size() +{ + return stackPointer; +} +/* private functions ------------------------------------------------------- */ + +flash_addr_t +getAddr(flash_addr_t address) +{ + if(address >= 0x02000) { + return address; + } + + flash_addr_t block = (address & 0x01000 ? FLASH_BLOCK_21 : FLASH_BLOCK_11); + uint8_t blockcheck = (flash_cmp("\001", block, 1) == 0 ? 0 : 1); + return block + (blockcheck << 12) + (address & 0x00FFF); +} diff --git a/platform/econotag/apps/flash/flash.h b/platform/econotag/apps/flash/flash.h new file mode 100644 index 000000000..a50bddc80 --- /dev/null +++ b/platform/econotag/apps/flash/flash.h @@ -0,0 +1,178 @@ +/* + * Copyright (c) 2014, Lars Schmertmann . + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * + * This file is part of the Contiki operating system. + * + */ + +/** + * \file + * App for easy usage of additional flash memory + * + * Purposes of the different flash blocks + * 1 : 0x18000 - 0x18FFF : Random access block 1.1 + * 2 : 0x19000 - 0x19FFF : Random access block 1.2 + * 3 : 0x1A000 - 0x1AFFF : Random access block 2.1 + * 4 : 0x1B000 - 0x1BFFF : Random access block 2.2 + * 5 : 0x1C000 - 0x1CFFF : Stack without pop function + * 6 : 0x1D000 - 0x1DFFF : Read only + * 7 : 0x1E000 - 0x1EFFF : Read only + * 8 : 0x1F000 - 0x1FFFF : System reserved + * + * This app only allows write access to blocks 1 - 5 + * and read access to blocks 1 - 7. + * + * To use the stack in block 5 you need: flash_stack_init, + * flash_stack_push, flash_stack_size, flash_stack_read. + * + * To use the random access blocks 1.x and 2.x you need: flash_init, + * flash_getVar, flash_setVar, flash_cmp. + * + * Blocks 1.x and 2.x are accessible with adresses + * 0x0001 - 0x0FFF and 0x1001 - 0x1FFF. + * + * To be able to write to flash memory, its required to delete + * it first, but its only possible to delete a full block. So this + * app copies the data of a block, changing the requested data. + * Copying a block needs time. So when you only use the first N bytes, + * you can set FLASH_CONF_B1=N and FLASH_CONF_B2=N in your makefile + * to optimize speed. + * + * You can find an example in examples/econotag-flash-test. + * + * \author + * Lars Schmertmann + */ + +#ifndef FLASH_H_ +#define FLASH_H_ + +#include + +#define FLASH_STACK 0x1C000 + +typedef uint32_t flash_addr_t; + +/** + * \brief Initialize or clear random access blocks + * + * To use the random access blocks, you need to call this + * function first. You can also use it to delete all data + * in this blocks. + */ +void flash_init(); + +/** + * \brief Read data from flash memory + * + * Reads data from flash memory and stores it into RAM. + * You can read the flash area 0x18000 - 0x1EFFF. Addresses + * 0x0000 - 0x1FFF will be mapped to 0x18000 - 0x1BFFF. + * + * \param dest Memory area to store the data + * \param address Area in flash memory to read from + * \param numBytes Number of bytes to read + * + * \return gNvmErrNoError_c (0) if read was successfull + */ +nvmErr_t flash_getVar(void *dest, flash_addr_t address, uint32_t numBytes); + +/** + * \brief Write data to flash memory + * + * Writes data to flash memory. Valid addresses are + * 0x0001 - 0x0FFF and 0x1001 - 0x1FFF -> Mapped to + * 0x18000 - 0x1BFFF. + * + * \param src Memory area with data to store in flash memory + * \param address Area in flash memory to write + * \param numBytes Number of bytes to write + * + * \return gNvmErrNoError_c (0) if write was successfull + */ +nvmErr_t flash_setVar(void *src, flash_addr_t address, uint32_t numBytes); + +/** + * \brief Compares data from RAM with flash memory + * + * Compares data from RAM with flash memory. + * Valid addresses are 0x18000 - 0x1EFFF. Addresses + * 0x0 - 0x1FFF will be mapped to 0x18000 - 0x1BFFF. + * + * \param src Memory area with data to compare + * \param address Area in flash memory + * \param numBytes Number of bytes to compare + * + * \return 0 if data is matching + */ +nvmErr_t flash_cmp(void *src, flash_addr_t address, uint32_t numBytes); + +/** + * \brief Stack initialisation + * + * Clears and initializes the stack. + */ +void flash_stack_init(); + +/** + * \brief Push data to stack + * + * Pushes numBytes from src to stack into flash memory. + * + * \param src Memory area with data to store in flash memory + * \param numBytes Number of bytes to write + * + * \return gNvmErrNoError_c (0) if push was successfull + */ +nvmErr_t flash_stack_push(uint8_t *src, uint32_t numBytes); + +/** + * \brief Stacksize + * + * Returns the size of data in stack + * + * \return Number of bytes in stack + */ +uint32_t flash_stack_size(); + +/** + * \brief Read data from stack + * + * Reads data from stack (without removing it) and stores it into RAM. + * + * \param dest Memory area to store the data + * \param offset Position in stack to read from + * \param numBytes Number of bytes to read + * + * \return gNvmErrNoError_c (0) if read was successfull + */ +#define flash_stack_read(dest, offset, numBytes) flash_getVar(dest, FLASH_STACK + (offset), numBytes) + +#endif /* FLASH_H_ */ diff --git a/regression-tests/15-compile-arm-apcs-ports/Makefile b/regression-tests/15-compile-arm-apcs-ports/Makefile index e73a9a39f..767bed60f 100644 --- a/regression-tests/15-compile-arm-apcs-ports/Makefile +++ b/regression-tests/15-compile-arm-apcs-ports/Makefile @@ -8,6 +8,7 @@ ipv6/rpl-border-router/econotag \ er-rest-example/econotag \ webserver-ipv6/econotag \ ipv6/multicast/econotag \ +econotag-flash-test/econotag \ TOOLS= diff --git a/tools/blaster/Makefile b/tools/blaster/Makefile new file mode 100644 index 000000000..ceafb5cca --- /dev/null +++ b/tools/blaster/Makefile @@ -0,0 +1,19 @@ +CC = gcc +CFLAGS = -Wall -g +HEADERS = + +all: blaster + +depend: + sudo apt-get install libconfig8-dev uuid-dev libqrencode-dev + +%.o: %.c $(HEADERS) + $(CC) -c $(CFLAGS) -o $@ $< + +blaster: blaster.o + $(CC) $(CFLAGS) -o $@ $^ -lconfig -luuid -lqrencode + +clean: + rm *.o blaster + +.PHONY: all depend clean diff --git a/tools/blaster/README b/tools/blaster/README new file mode 100644 index 000000000..7fd109460 --- /dev/null +++ b/tools/blaster/README @@ -0,0 +1,10 @@ +Blaster extends the compiled firmware with additional data for +storing into flash memory. See examples/econotag-flash-test for +usage. Its written for Econotag / MC1322X + +./blaster [ ...] +To Generate a default configuration file, use blaster without parameter. + +Its important to use -l as a flash parameter. + +mc1322x-load -f flasher_econotag.bin -s firmware.bin -t /dev/ttyUSB1 -l diff --git a/tools/blaster/blaster.c b/tools/blaster/blaster.c new file mode 100644 index 000000000..ff074c479 --- /dev/null +++ b/tools/blaster/blaster.c @@ -0,0 +1,330 @@ +/* + * Copyright (c) 2014, Lars Schmertmann . + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * + * This file is part of the Contiki operating system. + * + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +#include "blaster.h" + +char *anschars = "abcdefghijklmnopqrstuvwxyz0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ_-"; + +/* ---------------------------------------------------------------------------- */ + +FILE *openFile(const char *name, const char *appendix, const char *mode); +void writeStandardConfig(); +void writeImg(FILE *file, unsigned char *data, int width); + +/* ---------------------------------------------------------------------------- */ + +int +main(int nArgs, char **argv) +{ + unsigned int c, i, config; + unsigned int buf[64]; + + if(nArgs < 2) { + writeStandardConfig(); + + fprintf(stderr, "Missing parameter: ./blaster [ ...]\n"); + fprintf(stderr, "Configuration template was created ib config.cfg.\n"); + + exit(EXIT_FAILURE); + } + + /* qrdata = "UUID:PSK\0" */ + char qrdata[54]; + qrdata[36] = ':'; + qrdata[53] = '\0'; + + config_t cfg; + for(config = 1; config < nArgs; config++) { + config_init(&cfg); + config_setting_t *setting; + const char *str_val; + if(access(argv[config], F_OK) == 0) { + config_read_file(&cfg, argv[config]); + } else { + fprintf(stderr, "Unable to read config file.\n"); + exit(EXIT_FAILURE); + } + fprintf(stdout, "Working on %s ... ", argv[config]); + + config_lookup_string(&cfg, "input", &str_val); + FILE *in_bin = openFile(str_val, ".bin", "r"); + + config_lookup_string(&cfg, "output", &str_val); + FILE *out_bin = openFile(str_val, ".bin", "w"); + FILE *out_txt = openFile(str_val, ".txt", "w"); + FILE *out_pbm = openFile(str_val, ".pbm", "w"); + + char output[131072]; + for(i = 8; (c = fgetc(in_bin)) != EOF; i++) { + output[i] = (unsigned char)c; + } + /* Set original length of firmware in little endian format ------------------- */ + unsigned int length = i - 8; + memcpy(output + 4, (const void *)&length, 4); + fprintf(out_txt, "Length: %u = 0x%08x\n", length, length); + + /* Fill additional flash with zeros for initialisation */ + for(; i < 0x1F000; i++) { + output[i] = 0x00; + } + + /* Example: Write an CoRE-Link-Answer for CoAP -------------------------------- */ + char *buffer = ";rt=\"dev.info\";if=\"core.rp\"," + ";rt=\"dev.info\";if=\"core.rp\"," + ";rt=\"dev.info\";if=\"core.rp\""; + memcpy(output + RES_D_CORE, buffer, LEN_D_CORE); + + /* Contiki configuration ------------------------------------------------------ */ + output[RES_CONFIG + 0] = 0x22; + output[RES_CONFIG + 1] = 0x13; + output[RES_CONFIG + 2] = 1; + output[RES_CONFIG + 3] = 0; + + setting = config_lookup(&cfg, "eui"); + for(i = 0; i < 8; i++) { + output[RES_CONFIG + 8 + i] = config_setting_get_int_elem(setting, 7 - i); + } + fprintf(out_txt, + "EUI: %02x-%02x-%02x-%02x-%02x-%02x-%02x-%02x\n", + (uint8_t)output[RES_CONFIG + 15], + (uint8_t)output[RES_CONFIG + 14], + (uint8_t)output[RES_CONFIG + 13], + (uint8_t)output[RES_CONFIG + 12], + (uint8_t)output[RES_CONFIG + 11], + (uint8_t)output[RES_CONFIG + 10], + (uint8_t)output[RES_CONFIG + 9], + (uint8_t)output[RES_CONFIG + 8] + ); + + output[RES_CONFIG + 16] = 15; + output[RES_CONFIG + 17] = 17; + output[RES_CONFIG + 18] = 0; + output[RES_CONFIG + 19] = 0; + output[RES_CONFIG + 20] = 5; + output[RES_CONFIG + 21] = 0; + output[RES_CONFIG + 22] = 0; + output[RES_CONFIG + 23] = 0; + + /* Example: Set UUID ---------------------------------------------------------- */ + config_lookup_string(&cfg, "uuid", &str_val); + memcpy(qrdata, str_val, 36); + unsigned char uuid_bin[16]; + uuid_parse(str_val, uuid_bin); + for(i = 0; i < 16; i++) { + output[RES_UUID + i] = uuid_bin[i]; + } + fprintf(out_txt, "UUID: %s\n", str_val); + + /* Example: Set PSK ----------------------------------------------------------- */ + config_lookup_string(&cfg, "psk", &str_val); + memcpy(qrdata + 37, str_val, 16); + for(i = 0; i < 16; i++) { + output[RES_PSK + i] = str_val[i]; + } + fprintf(out_txt, "PSK: %.*s\n", 16, str_val); + memcpy(output + RES_ANSCHARS, anschars, LEN_ANSCHARS); + + /* Example: ECC base point and order for secp256r1 ---------------------------- */ + uint32_t *base_x = (uint32_t *)(output + RES_ECC_BASE_X); + base_x[0] = 0xd898c296; + base_x[1] = 0xf4a13945; + base_x[2] = 0x2deb33a0; + base_x[3] = 0x77037d81; + base_x[4] = 0x63a440f2; + base_x[5] = 0xf8bce6e5; + base_x[6] = 0xe12c4247; + base_x[7] = 0x6b17d1f2; + + uint32_t *base_y = (uint32_t *)(output + RES_ECC_BASE_Y); + base_y[0] = 0x37bf51f5; + base_y[1] = 0xcbb64068; + base_y[2] = 0x6b315ece; + base_y[3] = 0x2bce3357; + base_y[4] = 0x7c0f9e16; + base_y[5] = 0x8ee7eb4a; + base_y[6] = 0xfe1a7f9b; + base_y[7] = 0x4fe342e2; + + uint32_t *order = (uint32_t *)(output + RES_ECC_ORDER); + order[0] = 0xFC632551; + order[1] = 0xF3B9CAC2; + order[2] = 0xA7179E84; + order[3] = 0xBCE6FAAD; + order[4] = 0xFFFFFFFF; + order[5] = 0xFFFFFFFF; + order[6] = 0x00000000; + order[7] = 0xFFFFFFFF; + + /* Example: Set name ---------------------------------------------------------- */ + config_lookup_string(&cfg, "name", &str_val); + snprintf(output + RES_NAME, LEN_NAME, "%s", str_val); + fprintf(out_txt, "Name: %s\n", str_val); + + /* Example: Set model---------------------------------------------------------- */ + config_lookup_string(&cfg, "model", &str_val); + snprintf(output + RES_MODEL, LEN_MODEL, "%s", str_val); + fprintf(out_txt, "Model: %s\n", str_val); + + /* Example: Set time ---------------------------------------------------------- */ + time_t my_time = time(NULL); + memcpy(output + RES_FLASHTIME, (void *)&my_time, LEN_FLASHTIME); + struct tm *timeinfo = localtime(&my_time); + fwrite(buf, 1, strftime((char *)buf, 64, "Created on %d.%m.%Y um %H:%M:%S", timeinfo), out_txt); + + /* Output result -------------------------------------------------------------- */ + for(i = 4; i < 0x1F000; i++) { + fputc(output[i], out_bin); + } + + /* Generate QR-Code ----------------------------------------------------------- */ + QRcode *code = QRcode_encodeString8bit(qrdata, 3, QR_ECLEVEL_L); + writeImg(out_pbm, code->data, code->width); + + fclose(in_bin); + fclose(out_bin); + fclose(out_txt); + fclose(out_pbm); + + fprintf(stdout, "DONE\n"); + } + + exit(EXIT_SUCCESS); +} +/* ---------------------------------------------------------------------------- */ + +FILE * +openFile(const char *name, const char *appendix, const char *mode) +{ + char filename[64]; + sprintf(filename, "%s%s", name, appendix); + FILE *file = fopen(filename, mode); + if(file == NULL) { + perror("Wasn't able to open file."); + exit(EXIT_FAILURE); + } + return file; +} +void +writeStandardConfig() +{ + unsigned int i; + + config_t cfg; + config_init(&cfg); + config_setting_t *setting; + + config_setting_t *root = config_root_setting(&cfg); + + setting = config_setting_add(root, "input", CONFIG_TYPE_STRING); + config_setting_set_string(setting, "dff_econotag"); + + setting = config_setting_add(root, "output", CONFIG_TYPE_STRING); + config_setting_set_string(setting, "dff_e_econotag"); + + uint8_t eui[8] = { 0x02, 0x00, 0x00, 0x00, 0x12, 0x34, 0x56, 0x78 }; + config_setting_t *array = config_setting_add(root, "eui", CONFIG_TYPE_ARRAY); + for(i = 0; i < 8; ++i) { + setting = config_setting_add(array, NULL, CONFIG_TYPE_INT); + config_setting_set_format(setting, CONFIG_FORMAT_HEX); + config_setting_set_int(setting, eui[i]); + } + + unsigned char uuid_bin[16]; + uuid_generate(uuid_bin); + char uuid[37]; + uuid_unparse(uuid_bin, uuid); + setting = config_setting_add(root, "uuid", CONFIG_TYPE_STRING); + config_setting_set_string(setting, uuid); + + char psk[17]; + psk[16] = '\0'; + FILE *fd = fopen("/dev/urandom", "r"); + if(fd == NULL) { + perror("Wasn't able to open /dev/urandom: "); + return; + } + for(i = 0; i < 16; i++) { + int c; + while((c = fgetc(fd)) == EOF) ; + psk[i] = anschars[c % 64]; + } + if(fclose(fd) == -1) { + perror("Wasn't able to close /dev/urandom: "); + } + setting = config_setting_add(root, "psk", CONFIG_TYPE_STRING); + config_setting_set_string(setting, psk); + + setting = config_setting_add(root, "name", CONFIG_TYPE_STRING); + config_setting_set_string(setting, "Blaster Standard Device"); + + setting = config_setting_add(root, "model", CONFIG_TYPE_STRING); + config_setting_set_string(setting, "Model 1234 for testing purposes only"); + + config_write_file(&cfg, "config.cfg"); +} +void +writeImg(FILE *file, unsigned char *data, int width) +{ + unsigned int buf[width]; + + fprintf(file, "P4\n# %s\n%3u %3u\n", "QR-Code", width * 32, width * 32); + + int x, y; + for(y = 0; y < width; y++) { + for(x = 0; x < width; x++) { + if(data[(y * width) + x] & 0x01) { + buf[x] = 0xFFFFFFFF; + } else { + buf[x] = 0x00000000; + } + } + for(x = 0; x < 32; x++) { + fwrite(buf, 4, width, file); + } + } +} diff --git a/tools/blaster/blaster.h b/tools/blaster/blaster.h new file mode 100644 index 000000000..085abf855 --- /dev/null +++ b/tools/blaster/blaster.h @@ -0,0 +1,72 @@ +/* + * Copyright (c) 2014, Lars Schmertmann . + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * + * This file is part of the Contiki operating system. + * + */ + +/* Purposes of the different flash blocks */ +/* 0x18000 - 0x18FFF : Random access block 1.1 */ +/* 0x19000 - 0x19FFF : Random access block 1.2 */ +/* 0x1A000 - 0x1AFFF : Random access block 2.1 */ +/* 0x1B000 - 0x1BFFF : Random access block 2.2 */ +/* 0x1C000 - 0x1CFFF : Stack without pop function */ +/* 0x1D000 - 0x1DFFF : Read only <- This is what blaster user */ +/* 0x1E000 - 0x1EFFF : Read only <- This is what blaster user */ +/* 0x1F000 - 0x1FFFF : System reserved */ + +#ifndef BLASTER_H_ +#define BLASTER_H_ + +#define RES_D_CORE 0x1D000 +#define LEN_D_CORE 0x6F + +#define RES_CONFIG 0x1E000 +#define LEN_CONFIG 0x12 +#define RES_UUID 0x1E020 +#define LEN_UUID 0x10 +#define RES_PSK 0x1E030 +#define LEN_PSK 0x10 +#define RES_ANSCHARS 0x1E040 +#define LEN_ANSCHARS 0x40 +#define RES_ECC_BASE_X 0x1E080 +#define LEN_ECC_BASE_X 0x20 +#define RES_ECC_BASE_Y 0x1E0A0 +#define LEN_ECC_BASE_Y 0x20 +#define RES_ECC_ORDER 0x1E0C0 +#define LEN_ECC_ORDER 0x20 +#define RES_NAME 0x1E0E0 +#define LEN_NAME 0x40 +#define RES_MODEL 0x1E120 +#define LEN_MODEL 0x40 +#define RES_FLASHTIME 0x1E160 +#define LEN_FLASHTIME 0x04 + +#endif /* BLASTER_H_ */ From 43770a934dd8397d5b491ec0271389906ddd3f9d Mon Sep 17 00:00:00 2001 From: Valentin Sawadski Date: Mon, 14 Sep 2015 15:11:00 +0200 Subject: [PATCH 076/120] Refactor tcpip.c packet input The UIP_CONF_FORWARD is now handled in a better way that the general structure of packet_input can be clearer seen. --- core/net/ip/tcpip.c | 30 ++++++++---------------------- 1 file changed, 8 insertions(+), 22 deletions(-) diff --git a/core/net/ip/tcpip.c b/core/net/ip/tcpip.c index 67c837591..495b855cb 100644 --- a/core/net/ip/tcpip.c +++ b/core/net/ip/tcpip.c @@ -185,30 +185,17 @@ check_for_tcp_syn(void) static void packet_input(void) { -#if UIP_CONF_IP_FORWARD if(uip_len > 0) { + +#if UIP_CONF_IP_FORWARD tcpip_is_forwarding = 1; - if(uip_fw_forward() == UIP_FW_LOCAL) { + if(uip_fw_forward() != UIP_FW_LOCAL) { tcpip_is_forwarding = 0; - check_for_tcp_syn(); - uip_input(); - if(uip_len > 0) { -#if UIP_CONF_TCP_SPLIT - uip_split_output(); -#else /* UIP_CONF_TCP_SPLIT */ -#if NETSTACK_CONF_WITH_IPV6 - tcpip_ipv6_output(); -#else - PRINTF("tcpip packet_input forward output len %d\n", uip_len); - tcpip_output(); -#endif -#endif /* UIP_CONF_TCP_SPLIT */ - } + return; } tcpip_is_forwarding = 0; - } -#else /* UIP_CONF_IP_FORWARD */ - if(uip_len > 0) { +#endif /* UIP_CONF_IP_FORWARD */ + check_for_tcp_syn(); uip_input(); if(uip_len > 0) { @@ -217,14 +204,13 @@ packet_input(void) #else /* UIP_CONF_TCP_SPLIT */ #if NETSTACK_CONF_WITH_IPV6 tcpip_ipv6_output(); -#else +#else /* NETSTACK_CONF_WITH_IPV6 */ PRINTF("tcpip packet_input output len %d\n", uip_len); tcpip_output(); -#endif +#endif /* NETSTACK_CONF_WITH_IPV6 */ #endif /* UIP_CONF_TCP_SPLIT */ } } -#endif /* UIP_CONF_IP_FORWARD */ } /*---------------------------------------------------------------------------*/ #if UIP_TCP From ef9a36f9f6127bc809d029de77e7ed37e226818d Mon Sep 17 00:00:00 2001 From: Niclas Finne Date: Thu, 30 Apr 2015 14:22:09 +0200 Subject: [PATCH 077/120] Ensure parent resources match the path exactly and not as prefix. --- apps/rest-engine/rest-engine.c | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/apps/rest-engine/rest-engine.c b/apps/rest-engine/rest-engine.c index 7eb686d4d..038acb025 100644 --- a/apps/rest-engine/rest-engine.c +++ b/apps/rest-engine/rest-engine.c @@ -124,15 +124,19 @@ rest_invoke_restful_service(void *request, void *response, uint8_t *buffer, resource_t *resource = NULL; const char *url = NULL; + int url_len, res_url_len; for(resource = (resource_t *)list_head(restful_services); resource; resource = resource->next) { /* if the web service handles that kind of requests and urls matches */ - if((REST.get_url(request, &url) == strlen(resource->url) - || (REST.get_url(request, &url) > strlen(resource->url) - && (resource->flags & HAS_SUB_RESOURCES))) - && strncmp(resource->url, url, strlen(resource->url)) == 0) { + url_len = REST.get_url(request, &url); + res_url_len = strlen(resource->url); + if((url_len == res_url_len + || (url_len > res_url_len + && (resource->flags & HAS_SUB_RESOURCES) + && url[res_url_len] == '/')) + && strncmp(resource->url, url, res_url_len) == 0) { found = 1; rest_resource_flags_t method = REST.get_method_type(request); From cad1c37fb358fa28104ed27b68f282ed23d73622 Mon Sep 17 00:00:00 2001 From: Valentin Sawadski Date: Fri, 18 Sep 2015 14:53:57 +0200 Subject: [PATCH 078/120] Better prints of ::FFFF: prefixed IPv4-mapped addresses IPv4-mapped Address [1] are now printed accoriding to the text representation mixed IPv4 and IPv6 networks as specified in [2] [1] https://tools.ietf.org/html/rfc6890#page-14 [2] https://tools.ietf.org/html/rfc3513#page-5 --- core/net/ip/ip64-addr.h | 14 ++++++++++++++ core/net/ip/uip-debug.c | 43 ++++++++++++++++++++++++++++------------- 2 files changed, 44 insertions(+), 13 deletions(-) diff --git a/core/net/ip/ip64-addr.h b/core/net/ip/ip64-addr.h index 4cf80a9b9..3027d846a 100644 --- a/core/net/ip/ip64-addr.h +++ b/core/net/ip/ip64-addr.h @@ -34,6 +34,20 @@ #include "net/ip/uip.h" + +/** + * \brief Is IPv4-mapped Address + * + * See https://tools.ietf.org/html/rfc6890#page-14 + */ +#define ip64_addr_is_ipv4_mapped_addr(a) \ + ((((a)->u16[0]) == 0) && \ + (((a)->u16[1]) == 0) && \ + (((a)->u16[2]) == 0) && \ + (((a)->u16[3]) == 0) && \ + (((a)->u16[4]) == 0) && \ + (((a)->u16[5]) == 0xFFFF)) + void ip64_addr_copy4(uip_ip4addr_t *dest, const uip_ip4addr_t *src); void ip64_addr_copy6(uip_ip6addr_t *dest, const uip_ip6addr_t *src); diff --git a/core/net/ip/uip-debug.c b/core/net/ip/uip-debug.c index 93e7edfe7..aee023169 100644 --- a/core/net/ip/uip-debug.c +++ b/core/net/ip/uip-debug.c @@ -38,6 +38,7 @@ */ #include "net/ip/uip-debug.h" +#include "net/ip/ip64-addr.h" /*---------------------------------------------------------------------------*/ void @@ -53,20 +54,36 @@ uip_debug_ipaddr_print(const uip_ipaddr_t *addr) return; } #if NETSTACK_CONF_WITH_IPV6 - for(i = 0, f = 0; i < sizeof(uip_ipaddr_t); i += 2) { - a = (addr->u8[i] << 8) + addr->u8[i + 1]; - if(a == 0 && f >= 0) { - if(f++ == 0) { - PRINTA("::"); + if(ip64_addr_is_ipv4_mapped_addr(addr)) { + /* Printing IPv4-mapped addresses is done according to RFC 3513 [1] + * + * An alternative form that is sometimes more + * convenient when dealing with a mixed environment + * of IPv4 and IPv6 nodes is x:x:x:x:x:x:d.d.d.d, + * where the 'x's are the hexadecimal values of the + * six high-order 16-bit pieces of the address, and + * the 'd's are the decimal values of the four + * low-order 8-bit pieces of the address (standard + * IPv4 representation). + * + * [1] https://tools.ietf.org/html/rfc3513#page-5 */ + PRINTA("::FFFF:%u.%u.%u.%u", addr->u8[12], addr->u8[13], addr->u8[14], addr->u8[15]); + } else { + for(i = 0, f = 0; i < sizeof(uip_ipaddr_t); i += 2) { + a = (addr->u8[i] << 8) + addr->u8[i + 1]; + if(a == 0 && f >= 0) { + if(f++ == 0) { + PRINTA("::"); + } + } else { + if(f > 0) { + f = -1; + } else if(i > 0) { + PRINTA(":"); + } + PRINTA("%x", a); } - } else { - if(f > 0) { - f = -1; - } else if(i > 0) { - PRINTA(":"); - } - PRINTA("%x", a); - } + } } #else /* NETSTACK_CONF_WITH_IPV6 */ PRINTA("%u.%u.%u.%u", addr->u8[0], addr->u8[1], addr->u8[2], addr->u8[3]); From d68cbb298012314c41403d1f336392cd300766d7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Moritz=20=27Morty=27=20Str=C3=BCbe?= Date: Fri, 28 Nov 2014 12:22:24 +0100 Subject: [PATCH 079/120] Ensure that the data in ringbuff is accessed in the right order --- core/lib/ringbuf.c | 25 +++++++++++++++++++++---- core/sys/cc.h | 11 +++++++++++ 2 files changed, 32 insertions(+), 4 deletions(-) diff --git a/core/lib/ringbuf.c b/core/lib/ringbuf.c index a10127c17..89bcad514 100644 --- a/core/lib/ringbuf.c +++ b/core/lib/ringbuf.c @@ -38,6 +38,7 @@ */ #include "lib/ringbuf.h" +#include /*---------------------------------------------------------------------------*/ void ringbuf_init(struct ringbuf *r, uint8_t *dataptr, uint8_t size) @@ -63,8 +64,15 @@ ringbuf_put(struct ringbuf *r, uint8_t c) if(((r->put_ptr - r->get_ptr) & r->mask) == r->mask) { return 0; } - r->data[r->put_ptr] = c; - r->put_ptr = (r->put_ptr + 1) & r->mask; + /* + * CC_ACCESS_NOW is used because the compiler is allowed to reorder + * the access to non-volatile variables. + * In this case a reader might read from the moved index/ptr before + * its value (c) is written. Reordering makes little sense, but + * better safe than sorry. + */ + CC_ACCESS_NOW(uint8_t, r->data[r->put_ptr]) = c; + CC_ACCESS_NOW(uint8_t, r->put_ptr) = (r->put_ptr + 1) & r->mask; return 1; } /*---------------------------------------------------------------------------*/ @@ -84,8 +92,17 @@ ringbuf_get(struct ringbuf *r) most platforms, but C does not guarantee this. */ if(((r->put_ptr - r->get_ptr) & r->mask) > 0) { - c = r->data[r->get_ptr]; - r->get_ptr = (r->get_ptr + 1) & r->mask; + /* + * CC_ACCESS_NOW is used because the compiler is allowed to reorder + * the access to non-volatile variables. + * In this case the memory might be freed and overwritten by + * increasing get_ptr before the value was copied to c. + * Opposed to the put-operation this would even make sense, + * because the register used for mask can be reused to save c + * (on some architectures). + */ + c = CC_ACCESS_NOW(uint8_t, r->data[r->get_ptr]); + CC_ACCESS_NOW(uint8_t, r->get_ptr) = (r->get_ptr + 1) & r->mask; return c; } else { return -1; diff --git a/core/sys/cc.h b/core/sys/cc.h index 06b8889ec..f105a78c3 100644 --- a/core/sys/cc.h +++ b/core/sys/cc.h @@ -123,6 +123,17 @@ #define CC_NO_VA_ARGS CC_CONF_VA_ARGS #endif +/** \def CC_ACCESS_NOW(x) + * This macro ensures that the access to a non-volatile variable can + * not be reordered or optimized by the compiler. + * See also https://lwn.net/Articles/508991/ - In Linux the macro is + * called ACCESS_ONCE + * The type must be passed, because the typeof-operator is a gcc + * extension + */ + +#define CC_ACCESS_NOW(type, variable) (*(volatile type *)&(variable)) + #ifndef NULL #define NULL 0 #endif /* NULL */ From d2528caa858de9a64afd6475b40d138477477ac0 Mon Sep 17 00:00:00 2001 From: Cristiano De Alti Date: Mon, 21 Sep 2015 22:45:57 +0200 Subject: [PATCH 080/120] Implement battery and temperature sensors. On the raven, the battery and temperature readings are available from the companion 3290 cpu over the serial line. Modify the existing raven-lcd-interface application to export these sensors. --- .../Makefile.raven-lcd-interface | 2 +- .../apps/raven-lcd-interface/raven-lcd.c | 43 ++++++++++++++++ platform/avr-raven/dev/temperature-sensor.h | 49 +++++++++++++++++++ 3 files changed, 93 insertions(+), 1 deletion(-) create mode 100644 platform/avr-raven/dev/temperature-sensor.h diff --git a/platform/avr-raven/apps/raven-lcd-interface/Makefile.raven-lcd-interface b/platform/avr-raven/apps/raven-lcd-interface/Makefile.raven-lcd-interface index 0b1196c5f..707f0a3fe 100644 --- a/platform/avr-raven/apps/raven-lcd-interface/Makefile.raven-lcd-interface +++ b/platform/avr-raven/apps/raven-lcd-interface/Makefile.raven-lcd-interface @@ -1,4 +1,4 @@ raven-lcd-interface_src = raven-lcd.c -CFLAGS+=-DRAVEN_LCD_INTERFACE=1 +CFLAGS+=-DRAVEN_LCD_INTERFACE=1 -DPLATFORM_HAS_BATTERY -DPLATFORM_HAS_TEMPERATURE diff --git a/platform/avr-raven/apps/raven-lcd-interface/raven-lcd.c b/platform/avr-raven/apps/raven-lcd-interface/raven-lcd.c index 343bab2e8..acf6eef46 100644 --- a/platform/avr-raven/apps/raven-lcd-interface/raven-lcd.c +++ b/platform/avr-raven/apps/raven-lcd-interface/raven-lcd.c @@ -42,6 +42,7 @@ * driver chip (ATMega3290P) on the Raven. * * \author Blake Leverett + * \author Cristiano De Alti * * @{ */ @@ -69,6 +70,7 @@ #endif #include "raven-lcd.h" +#include "lib/sensors.h" #include #include @@ -94,6 +96,9 @@ static struct{ #define UIP_ICMP_BUF ((struct uip_icmp_hdr *)&uip_buf[uip_l2_l3_hdr_len]) #define PING6_DATALEN 16 +static int battery_value; +static int temperature_value; + void rs232_send(uint8_t port, unsigned char c); /*---------------------------------------------------------------------------*/ @@ -306,12 +311,14 @@ raven_gui_loop(process_event_t ev, process_data_t data) /* Set temperature string in web server */ web_set_temp((char *)cmd.frame); #endif + temperature_value = atoi((char *)cmd.frame); break; case SEND_ADC2: #if AVR_WEBSERVER /* Set ext voltage string in web server */ web_set_voltage((char *)cmd.frame); #endif + battery_value = atoi((char *)cmd.frame); break; case SEND_SLEEP: /* Sleep radio and 1284p. */ @@ -458,6 +465,42 @@ char buf[sizeof(eemem_server_name)+1]; raven_lcd_show_text(buf); //must fit in all the buffers or it will be truncated! } #endif + +/*---------------------------------------------------------------------------*/ +int +value_temperature(int type) { + return temperature_value; +} + +int +value_battery(int type) { + return battery_value; +} + +/*---------------------------------------------------------------------------*/ +int +configure(int type, int value) { + /* prevent compiler warnings */ + return type = value = 1; +} + +/*---------------------------------------------------------------------------*/ +int +status(int type) { + switch(type) { + case SENSORS_ACTIVE: + case SENSORS_READY: + return 1; + } + return 0; +} + +/*---------------------------------------------------------------------------*/ +SENSORS_SENSOR(temperature_sensor, "Temperature", + value_temperature, configure, status); +SENSORS_SENSOR(battery_sensor, "Battery", + value_battery, configure, status); + /*---------------------------------------------------------------------------*/ PROCESS(raven_lcd_process, "Raven LCD interface process"); PROCESS_THREAD(raven_lcd_process, ev, data) diff --git a/platform/avr-raven/dev/temperature-sensor.h b/platform/avr-raven/dev/temperature-sensor.h new file mode 100644 index 000000000..05eafe852 --- /dev/null +++ b/platform/avr-raven/dev/temperature-sensor.h @@ -0,0 +1,49 @@ +/* + * Copyright (c) 2010, Swedish Institute of Computer Science. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the Institute nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + */ + +/** + * \file + * Temperature sensor header file. + * \author + * Adam Dunkels + * Joakim Eriksson + * Niclas Finne + */ + +#ifndef TEMPERATURE_SENSOR_H_ +#define TEMPERATURE_SENSOR_H_ + +#include "lib/sensors.h" + +extern const struct sensors_sensor temperature_sensor; + +#define TEMPERATURE_SENSOR "Temperature" + +#endif /* TEMPERATURE_SENSOR_H_ */ From 5a829d818da18eb75356c07c3cb2ab84a1db731d Mon Sep 17 00:00:00 2001 From: Cristiano De Alti Date: Mon, 21 Sep 2015 22:53:48 +0200 Subject: [PATCH 081/120] er-rest-example leveraging the new rave sensors. --- examples/er-rest-example-raven/Makefile | 15 +++++++++++++++ 1 file changed, 15 insertions(+) create mode 100644 examples/er-rest-example-raven/Makefile diff --git a/examples/er-rest-example-raven/Makefile b/examples/er-rest-example-raven/Makefile new file mode 100644 index 000000000..02cfb3c18 --- /dev/null +++ b/examples/er-rest-example-raven/Makefile @@ -0,0 +1,15 @@ +TARGET=avr-raven + +APPS += raven-lcd-interface + +export + +CONTIKI=../.. + +ER_REST_EXAMPLE=$(CONTIKI)/examples/er-rest-example + +all %: + @(cd $(ER_REST_EXAMPLE) && $(MAKE) $@) + @echo + @echo "*** Binaries can be found in $(ER_REST_EXAMPLE) ***" + From ba3c167ceffe5153819cd47de4436aa4c0faa2b2 Mon Sep 17 00:00:00 2001 From: Cristiano De Alti Date: Mon, 21 Sep 2015 23:12:16 +0200 Subject: [PATCH 082/120] Add a new periodic temperature resource. The temperature sensor is sampled once per second. If observed, temperature readings are reported on change or every Max-Age interval (default: 60s). --- .../resources/res-temperature.c | 125 ++++++++++++++++++ 1 file changed, 125 insertions(+) create mode 100644 examples/er-rest-example/resources/res-temperature.c diff --git a/examples/er-rest-example/resources/res-temperature.c b/examples/er-rest-example/resources/res-temperature.c new file mode 100644 index 000000000..c8bce8ba8 --- /dev/null +++ b/examples/er-rest-example/resources/res-temperature.c @@ -0,0 +1,125 @@ +/* + * Copyright (c) 2013, Institute for Pervasive Computing, ETH Zurich + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the Institute nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * This file is part of the Contiki operating system. + */ + +/** + * \file + * Example of an observable "on-change" temperature resource + * \author + * Matthias Kovatsch + * \author + * Cristiano De Alti + */ + +#include "contiki.h" + +#if PLATFORM_HAS_TEMPERATURE + +#include +#include +#include +#include "rest-engine.h" +#include "dev/temperature-sensor.h" + +static void res_get_handler(void *request, void *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset); +static void res_periodic_handler(void); + +#define MAX_AGE 60 +#define INTERVAL_MIN 5 +#define INTERVAL_MAX (MAX_AGE - 1) +#define CHANGE 1 + +static int32_t interval_counter = INTERVAL_MIN; +static int temperature_old = INT_MIN; + +PERIODIC_RESOURCE(res_temperature, + "title=\"Temperature\";rt=\"Temperature\";obs", + res_get_handler, + NULL, + NULL, + NULL, + CLOCK_SECOND, + res_periodic_handler); + +static void +res_get_handler(void *request, void *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset) +{ + /* + * For minimal complexity, request query and options should be ignored for GET on observable resources. + * Otherwise the requests must be stored with the observer list and passed by REST.notify_subscribers(). + * This would be a TODO in the corresponding files in contiki/apps/erbium/! + */ + + int temperature = temperature_sensor.value(0); + + unsigned int accept = -1; + REST.get_header_accept(request, &accept); + + if(accept == -1 || accept == REST.type.TEXT_PLAIN) { + REST.set_header_content_type(response, REST.type.TEXT_PLAIN); + snprintf((char *)buffer, REST_MAX_CHUNK_SIZE, "%d", temperature); + + REST.set_response_payload(response, (uint8_t *)buffer, strlen((char *)buffer)); + } else if(accept == REST.type.APPLICATION_JSON) { + REST.set_header_content_type(response, REST.type.APPLICATION_JSON); + snprintf((char *)buffer, REST_MAX_CHUNK_SIZE, "{'temperature':%d}", temperature); + + REST.set_response_payload(response, buffer, strlen((char *)buffer)); + } else { + REST.set_response_status(response, REST.status.NOT_ACCEPTABLE); + const char *msg = "Supporting content-types text/plain and application/json"; + REST.set_response_payload(response, msg, strlen(msg)); + } + + REST.set_header_max_age(response, MAX_AGE); + + /* The REST.subscription_handler() will be called for observable resources by the REST framework. */ +} + +/* + * Additionally, a handler function named [resource name]_handler must be implemented for each PERIODIC_RESOURCE. + * It will be called by the REST manager process with the defined period. + */ +static void +res_periodic_handler() +{ + int temperature = temperature_sensor.value(0); + + ++interval_counter; + + if((abs(temperature - temperature_old) >= CHANGE && interval_counter >= INTERVAL_MIN) || + interval_counter >= INTERVAL_MAX) { + interval_counter = 0; + temperature_old = temperature; + /* Notify the registered observers which will trigger the res_get_handler to create the response. */ + REST.notify_subscribers(&res_temperature); + } +} +#endif /* PLATFORM_HAS_TEMPERATURE */ From 6e91cb3a3919a153cd65c08baf39f5142867e248 Mon Sep 17 00:00:00 2001 From: Cristiano De Alti Date: Mon, 21 Sep 2015 23:20:45 +0200 Subject: [PATCH 083/120] Activate battery and temperature resources if they are supported by the platform. --- examples/er-rest-example/er-example-server.c | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/examples/er-rest-example/er-example-server.c b/examples/er-rest-example/er-example-server.c index 41a07a501..d8e1c79b2 100644 --- a/examples/er-rest-example/er-example-server.c +++ b/examples/er-rest-example/er-example-server.c @@ -79,11 +79,17 @@ extern resource_t res_leds, res_toggle; #include "dev/light-sensor.h" extern resource_t res_light; #endif -/* #if PLATFORM_HAS_BATTERY #include "dev/battery-sensor.h" extern resource_t res_battery; #endif +#if PLATFORM_HAS_TEMPERATURE +#include "dev/temperature-sensor.h" +extern resource_t res_temperature; +#endif +/* +extern resource_t res_battery; +#endif #if PLATFORM_HAS_RADIO #include "dev/radio-sensor.h" extern resource_t res_radio; @@ -141,11 +147,15 @@ PROCESS_THREAD(er_example_server, ev, data) rest_activate_resource(&res_light, "sensors/light"); SENSORS_ACTIVATE(light_sensor); #endif -/* #if PLATFORM_HAS_BATTERY rest_activate_resource(&res_battery, "sensors/battery"); SENSORS_ACTIVATE(battery_sensor); #endif +#if PLATFORM_HAS_TEMPERATURE + rest_activate_resource(&res_temperature, "sensors/temperature"); + SENSORS_ACTIVATE(temperature_sensor); +#endif +/* #if PLATFORM_HAS_RADIO rest_activate_resource(&res_radio, "sensors/radio"); SENSORS_ACTIVATE(radio_sensor); From abac0f038195285e4d3c1ce1cf4a8d0703bd92a0 Mon Sep 17 00:00:00 2001 From: Cristiano De Alti Date: Sat, 29 Nov 2014 14:14:35 +0100 Subject: [PATCH 084/120] Fix compilation of er-rest-example --- platform/avr-raven/contiki-conf.h | 1 + 1 file changed, 1 insertion(+) diff --git a/platform/avr-raven/contiki-conf.h b/platform/avr-raven/contiki-conf.h index 2fe0d6099..ead35168b 100644 --- a/platform/avr-raven/contiki-conf.h +++ b/platform/avr-raven/contiki-conf.h @@ -162,6 +162,7 @@ typedef unsigned short uip_stats_t; #define UIP_CONF_ICMP6 1 #define UIP_CONF_UDP 1 #define UIP_CONF_TCP 1 +#define UIP_CONF_BUFFER_SIZE 1300 #define NETSTACK_CONF_NETWORK sicslowpan_driver #define SICSLOWPAN_CONF_COMPRESSION SICSLOWPAN_COMPRESSION_HC06 #else From 65e70baa841d0c55b57e91235899928ee6c6da69 Mon Sep 17 00:00:00 2001 From: Cristiano De Alti Date: Sat, 29 Nov 2014 15:40:31 +0100 Subject: [PATCH 085/120] Tables must be const in order to be put into read-only section by means of __attribute__((progmem)) (avr-gcc 4.7.0) --- platform/avr-ravenlcd/beep.c | 13 +++++++------ platform/avr-ravenlcd/temp.c | 8 ++++---- 2 files changed, 11 insertions(+), 10 deletions(-) diff --git a/platform/avr-ravenlcd/beep.c b/platform/avr-ravenlcd/beep.c index 34f2ee23f..cb2a0510b 100644 --- a/platform/avr-ravenlcd/beep.c +++ b/platform/avr-ravenlcd/beep.c @@ -132,11 +132,11 @@ beep(void) static uint8_t tuneindex=0; -static uint8_t pictures[] PROGMEM = {G4,4, F4,4, AS4,4, C5,2, F5,2, D5,4, C5,2, F5,2, D5,4, AS4,4, C5,4, G4,4, F4,4, 0xff}; -static uint8_t axel[] PROGMEM = {FS4,2, NONE,2, A4,3, FS4,2, FS4,1, B4,2, FS4,2, E4,2, FS4,2, NONE,2, CS5,3, FS4,2, FS4,1, D5,2, CS5,2, A4,2, FS4,2, CS5,2, FS5,2, FS4,1, E4,2, E4,1, CS4,2, GS4,2, FS4,6, 0xff}; -static uint8_t sandman1[] PROGMEM = {F4,2, G4,2, B4,4, A4,10, B4,2, B4,2, A4,2, B4,12, 0xff}; -static uint8_t sandman2[] PROGMEM = {C4,2, E4,2, G4,2, B4,2, A4,2, G4,2, E4,2, C4,2, D4,2, F4,2, A4,2, C5,2, B4,8, 0xff}; -static uint8_t furelise[] PROGMEM = {E5,1, DS5,1, E5,1, DS5,1, E5,1, B4,1, D5,1, E5,1, A4,2, NONE,1, C4,1, E4,1, A4,1, B4,2, NONE,1, E4,1, GS4,1, B4,1, C5,2, 0xff}; +static const uint8_t pictures[] PROGMEM = {G4,4, F4,4, AS4,4, C5,2, F5,2, D5,4, C5,2, F5,2, D5,4, AS4,4, C5,4, G4,4, F4,4, 0xff}; +static const uint8_t axel[] PROGMEM = {FS4,2, NONE,2, A4,3, FS4,2, FS4,1, B4,2, FS4,2, E4,2, FS4,2, NONE,2, CS5,3, FS4,2, FS4,1, D5,2, CS5,2, A4,2, FS4,2, CS5,2, FS5,2, FS4,1, E4,2, E4,1, CS4,2, GS4,2, FS4,6, 0xff}; +static const uint8_t sandman1[] PROGMEM = {F4,2, G4,2, B4,4, A4,10, B4,2, B4,2, A4,2, B4,12, 0xff}; +static const uint8_t sandman2[] PROGMEM = {C4,2, E4,2, G4,2, B4,2, A4,2, G4,2, E4,2, C4,2, D4,2, F4,2, A4,2, C5,2, B4,8, 0xff}; +static const uint8_t furelise[] PROGMEM = {E5,1, DS5,1, E5,1, DS5,1, E5,1, B4,1, D5,1, E5,1, A4,2, NONE,1, C4,1, E4,1, A4,1, B4,2, NONE,1, E4,1, GS4,1, B4,1, C5,2, 0xff}; static volatile uint8_t icnt,tone; @@ -153,7 +153,8 @@ ISR(TIMER0_OVF_vect) void play_ringtone(void) { -uint8_t i,*noteptr; +uint8_t i; +const uint8_t *noteptr; /* What's next on the playlist? */ switch (tuneindex++) { diff --git a/platform/avr-ravenlcd/temp.c b/platform/avr-ravenlcd/temp.c index cf7c20c31..e7e8243b6 100644 --- a/platform/avr-ravenlcd/temp.c +++ b/platform/avr-ravenlcd/temp.c @@ -58,7 +58,7 @@ static uint16_t temp_table_celcius[]; static uint16_t temp_table_fahrenheit[]; #else /* !DOXYGEN */ /** Celcius temperatures (ADC-value) from -15 to 60 degrees */ -static uint16_t temp_table_celcius[] PROGMEM = { +static const uint16_t temp_table_celcius[] PROGMEM = { 923,917,911,904,898,891,883,876,868,860,851,843,834,825,815, 806,796,786,775,765,754,743,732,720,709,697,685,673,661,649, 636,624,611,599,586,574,562,549,537,524,512,500,488,476,464, @@ -68,7 +68,7 @@ static uint16_t temp_table_celcius[] PROGMEM = { }; /** Fahrenheit temperatures (ADC-value) from 0 to 140 degrees */ -static uint16_t temp_table_fahrenheit[] PROGMEM = { +static const uint16_t temp_table_fahrenheit[] PROGMEM = { 938, 935, 932, 929, 926, 923, 920, 916, 913, 909, 906, 902, 898, 894, 891, 887, 882, 878, 874, 870, 865, 861, 856, 851, 847, 842, 837, 832, 827, 822, 816, 811, 806, 800, 795, 789, 783, 778, 772, @@ -99,7 +99,7 @@ bool temp_initialized = false; * * \return EOF on error */ -static int find_temp(int16_t value, uint16_t* array, int count); +static int find_temp(int16_t value, const uint16_t* array, int count); /*---------------------------------------------------------------------------*/ @@ -232,7 +232,7 @@ temp_get(temp_unit_t unit) * \return EOF on error */ static int -find_temp(int16_t value, uint16_t* array, int count) +find_temp(int16_t value, const uint16_t* array, int count) { int i = 0; int table_val = 0; From a3435952efe89506958f891c51d93316a23079dc Mon Sep 17 00:00:00 2001 From: Cristiano De Alti Date: Wed, 3 Dec 2014 00:07:55 +0100 Subject: [PATCH 086/120] Only output data and text sections to the hex file --- platform/avr-ravenlcd/Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/platform/avr-ravenlcd/Makefile b/platform/avr-ravenlcd/Makefile index e16132765..fef0167d9 100644 --- a/platform/avr-ravenlcd/Makefile +++ b/platform/avr-ravenlcd/Makefile @@ -28,7 +28,7 @@ LDFLAGS = $(COMMON) LDFLAGS += -Wl,-Map=$(PROJECT).map,--cref ## Intel Hex file production flags -HEX_FLASH_FLAGS = -R .eeprom +HEX_FLASH_FLAGS = -j .text -j .data HEX_EEPROM_FLAGS = -j .eeprom HEX_EEPROM_FLAGS += --set-section-flags=.eeprom="alloc,load" From 8e02955c3dce4b512b83ef2fda989577fb8abfad Mon Sep 17 00:00:00 2001 From: Cristiano De Alti Date: Wed, 3 Dec 2014 00:12:43 +0100 Subject: [PATCH 087/120] Fix menu. How could it worked before? Also added a macro to disable JTAG using inline assembly --- platform/avr-ravenlcd/menu.c | 38 +++++++++++++++++++++---------- platform/avr-ravenlcd/raven3290.c | 8 +++---- 2 files changed, 30 insertions(+), 16 deletions(-) diff --git a/platform/avr-ravenlcd/menu.c b/platform/avr-ravenlcd/menu.c index a5cda40a9..3069d7825 100644 --- a/platform/avr-ravenlcd/menu.c +++ b/platform/avr-ravenlcd/menu.c @@ -66,6 +66,27 @@ bool auto_temp=true; /*---------------------------------------------------------------------------*/ +/** + * \brief This will reliably set or clear the JTD bit of the MCUCR register. + * + * \param x True to set the JTD bit disabling JTAG. +*/ +#define jtd_set(x)\ +{\ + __asm__ __volatile__ (\ + "in __tmp_reg__,__SREG__" "\n\t"\ + "cli" "\n\t"\ + "out %1, %0" "\n\t"\ + "out __SREG__, __tmp_reg__" "\n\t"\ + "out %1, %0" "\n\t"\ + : /* no outputs */\ + : "r" ((uint8_t)(x ? (1< Date: Sat, 19 Sep 2015 15:45:09 +0200 Subject: [PATCH 088/120] See https://sourceforge.net/p/contiki/mailman/message/31702228/ --- platform/avr-raven/apps/raven-webserver/httpd-cgi.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/platform/avr-raven/apps/raven-webserver/httpd-cgi.c b/platform/avr-raven/apps/raven-webserver/httpd-cgi.c index f085991bf..874ad4246 100644 --- a/platform/avr-raven/apps/raven-webserver/httpd-cgi.c +++ b/platform/avr-raven/apps/raven-webserver/httpd-cgi.c @@ -368,7 +368,7 @@ make_routes(void *p) j++; numprinted += httpd_cgi_sprint_ip6(r->ipaddr, uip_appdata + numprinted); numprinted += httpd_snprintf((char *)uip_appdata+numprinted, uip_mss()-numprinted, httpd_cgi_rtes1, r->length); - numprinted += httpd_cgi_sprint_ip6(uip_ds6_route_nexthop(r), uip_appdata + numprinted); + numprinted += httpd_cgi_sprint_ip6(*uip_ds6_route_nexthop(r), uip_appdata + numprinted); if(r->state.lifetime < 3600) { numprinted += httpd_snprintf((char *)uip_appdata+numprinted, uip_mss()-numprinted, httpd_cgi_rtes2, r->state.lifetime); } else { From 018be89b1109c7da3288d702f4392d887611534c Mon Sep 17 00:00:00 2001 From: Cristiano De Alti Date: Sun, 20 Sep 2015 23:56:53 +0200 Subject: [PATCH 089/120] Revert abs -> ABS change from commit 0dab6926b30647e4c3bb1b56f39ccef761733ef5. The avr-ravenlcd cannot include sys/cc.h since this in turns includes contiki-conf.h which the avr-ravenlcd does not have. --- platform/avr-ravenlcd/lcd.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/platform/avr-ravenlcd/lcd.c b/platform/avr-ravenlcd/lcd.c index 3c4f9e230..0fe92b80a 100644 --- a/platform/avr-ravenlcd/lcd.c +++ b/platform/avr-ravenlcd/lcd.c @@ -411,7 +411,7 @@ lcd_num_putdec(int numb, lcd_padding_t padding) } /* Convert to BCD */ - bcd = itobcd(ABS(numb)); + bcd = itobcd(abs(numb)); /* Print */ return lcd_num_print(bcd, (bool)(numb<0), padding); From e51783a1d542b34fd490ce92d08f5560316370c1 Mon Sep 17 00:00:00 2001 From: Cristiano De Alti Date: Mon, 21 Sep 2015 21:56:09 +0200 Subject: [PATCH 090/120] Most of the rules in the avr makefile are not used anymore and should be removed. In the meantime we change those needed to upload flash and eeprom to depend on the default contiki rule to make the .$(TARGET) executable." --- cpu/avr/Makefile.avr | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/cpu/avr/Makefile.avr b/cpu/avr/Makefile.avr index 7ca45bf05..73c662582 100644 --- a/cpu/avr/Makefile.avr +++ b/cpu/avr/Makefile.avr @@ -139,10 +139,10 @@ ifndef NOAVRSIZE avr-size -C --mcu=$(MCU) $@ endif -%.hex: %.out +%.hex: %.$(TARGET) $(OBJCOPY) $^ -j .text -j .data -O ihex $@ -%.ihex: %.out +%.ihex: %.$(TARGET) $(OBJCOPY) $^ -O ihex $@ # Add a namelist to the kernel @@ -160,7 +160,7 @@ endif #%.hex: %.elf # $(OBJCOPY) -R .eeprom -R .fuse -R .signature $^ -O ihex $@ -%.eep: %.out +%.eep: %.$(TARGET) -$(OBJCOPY) -j .eeprom --set-section-flags=.eeprom="alloc,load" \ --change-section-lma .eeprom=0 -O ihex $^ $@ From 5b818d5a3914d06365a9169d2a6bd5eea8a22ac1 Mon Sep 17 00:00:00 2001 From: Valentin Sawadski Date: Wed, 23 Sep 2015 09:25:31 +0200 Subject: [PATCH 091/120] Fixed formatting of documentation --- core/net/ip/uip-debug.c | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/core/net/ip/uip-debug.c b/core/net/ip/uip-debug.c index aee023169..ab3ba0765 100644 --- a/core/net/ip/uip-debug.c +++ b/core/net/ip/uip-debug.c @@ -55,18 +55,20 @@ uip_debug_ipaddr_print(const uip_ipaddr_t *addr) } #if NETSTACK_CONF_WITH_IPV6 if(ip64_addr_is_ipv4_mapped_addr(addr)) { - /* Printing IPv4-mapped addresses is done according to RFC 3513 [1] - * - * An alternative form that is sometimes more - * convenient when dealing with a mixed environment + /* + * Printing IPv4-mapped addresses is done according to RFC 3513 [1] + * + * "An alternative form that is sometimes more + * convenient when dealing with a mixed environment * of IPv4 and IPv6 nodes is x:x:x:x:x:x:d.d.d.d, * where the 'x's are the hexadecimal values of the * six high-order 16-bit pieces of the address, and * the 'd's are the decimal values of the four * low-order 8-bit pieces of the address (standard - * IPv4 representation). + * IPv4 representation)." * - * [1] https://tools.ietf.org/html/rfc3513#page-5 */ + * [1] https://tools.ietf.org/html/rfc3513#page-5 + */ PRINTA("::FFFF:%u.%u.%u.%u", addr->u8[12], addr->u8[13], addr->u8[14], addr->u8[15]); } else { for(i = 0, f = 0; i < sizeof(uip_ipaddr_t); i += 2) { From bd7d45080d34ce2c4b6932abb72d5d2ad6ae10d4 Mon Sep 17 00:00:00 2001 From: Simon Duquennoy Date: Mon, 21 Sep 2015 10:57:54 +0200 Subject: [PATCH 092/120] Added NXP JN516x platform --- platform/jn516x/App_Stack_Size.ld | 46 + platform/jn516x/Makefile.jn516x | 300 ++++++ platform/jn516x/README.md | 183 ++++ platform/jn516x/contiki-conf.h | 195 ++++ platform/jn516x/contiki-jn516x-main.c | 468 +++++++++ platform/jn516x/dev/ccm-star.c | 168 +++ platform/jn516x/dev/clock.c | 250 +++++ platform/jn516x/dev/dongle/README.md | 9 + platform/jn516x/dev/dongle/leds-arch.c | 80 ++ platform/jn516x/dev/dr1174/README.md | 8 + platform/jn516x/dev/dr1174/button-sensor.c | 241 +++++ platform/jn516x/dev/dr1174/button-sensor.h | 41 + platform/jn516x/dev/dr1174/leds-arch.c | 121 +++ platform/jn516x/dev/dr1175/README.md | 18 + platform/jn516x/dev/dr1175/ht-sensor.c | 187 ++++ platform/jn516x/dev/dr1175/ht-sensor.h | 46 + platform/jn516x/dev/dr1175/leds-arch-1175.c | 91 ++ platform/jn516x/dev/dr1175/leds-arch-1175.h | 36 + platform/jn516x/dev/dr1175/light-sensor.c | 198 ++++ platform/jn516x/dev/dr1175/light-sensor.h | 43 + platform/jn516x/dev/dr1199/README.md | 19 + platform/jn516x/dev/dr1199/leds-arch-1199.c | 51 + platform/jn516x/dev/dr1199/leds-arch-1199.h | 35 + platform/jn516x/dev/dr1199/pot-sensor.c | 176 ++++ platform/jn516x/dev/dr1199/pot-sensor.h | 44 + platform/jn516x/dev/exceptions.c | 399 ++++++++ platform/jn516x/dev/exceptions.h | 59 ++ platform/jn516x/dev/leds-extension.c | 41 + platform/jn516x/dev/leds-extension.h | 44 + platform/jn516x/dev/micromac-radio.c | 1013 +++++++++++++++++++ platform/jn516x/dev/micromac-radio.h | 48 + platform/jn516x/dev/mtarch.c | 72 ++ platform/jn516x/dev/mtarch.h | 44 + platform/jn516x/dev/node-id.c | 61 ++ platform/jn516x/dev/rtimer-arch.c | 138 +++ platform/jn516x/dev/rtimer-arch.h | 59 ++ platform/jn516x/dev/slip_uart0.c | 54 + platform/jn516x/dev/uart-driver.c | 605 +++++++++++ platform/jn516x/dev/uart-driver.h | 62 ++ platform/jn516x/dev/uart0.c | 75 ++ platform/jn516x/dev/uart0.h | 75 ++ platform/jn516x/dev/uart1.c | 73 ++ platform/jn516x/dev/uart1.h | 77 ++ platform/jn516x/dev/watchdog.c | 90 ++ platform/jn516x/lib/log.c | 56 + platform/jn516x/lib/ringbufindex.c | 149 +++ platform/jn516x/lib/ringbufindex.h | 72 ++ platform/jn516x/lib/slip.c | 447 ++++++++ platform/jn516x/lib/sprintf.c | 235 +++++ platform/jn516x/platform-conf.h | 263 +++++ 50 files changed, 7365 insertions(+) create mode 100644 platform/jn516x/App_Stack_Size.ld create mode 100644 platform/jn516x/Makefile.jn516x create mode 100644 platform/jn516x/README.md create mode 100644 platform/jn516x/contiki-conf.h create mode 100644 platform/jn516x/contiki-jn516x-main.c create mode 100644 platform/jn516x/dev/ccm-star.c create mode 100644 platform/jn516x/dev/clock.c create mode 100644 platform/jn516x/dev/dongle/README.md create mode 100644 platform/jn516x/dev/dongle/leds-arch.c create mode 100644 platform/jn516x/dev/dr1174/README.md create mode 100644 platform/jn516x/dev/dr1174/button-sensor.c create mode 100644 platform/jn516x/dev/dr1174/button-sensor.h create mode 100644 platform/jn516x/dev/dr1174/leds-arch.c create mode 100644 platform/jn516x/dev/dr1175/README.md create mode 100644 platform/jn516x/dev/dr1175/ht-sensor.c create mode 100644 platform/jn516x/dev/dr1175/ht-sensor.h create mode 100644 platform/jn516x/dev/dr1175/leds-arch-1175.c create mode 100644 platform/jn516x/dev/dr1175/leds-arch-1175.h create mode 100644 platform/jn516x/dev/dr1175/light-sensor.c create mode 100644 platform/jn516x/dev/dr1175/light-sensor.h create mode 100644 platform/jn516x/dev/dr1199/README.md create mode 100644 platform/jn516x/dev/dr1199/leds-arch-1199.c create mode 100644 platform/jn516x/dev/dr1199/leds-arch-1199.h create mode 100644 platform/jn516x/dev/dr1199/pot-sensor.c create mode 100644 platform/jn516x/dev/dr1199/pot-sensor.h create mode 100644 platform/jn516x/dev/exceptions.c create mode 100644 platform/jn516x/dev/exceptions.h create mode 100644 platform/jn516x/dev/leds-extension.c create mode 100644 platform/jn516x/dev/leds-extension.h create mode 100644 platform/jn516x/dev/micromac-radio.c create mode 100644 platform/jn516x/dev/micromac-radio.h create mode 100644 platform/jn516x/dev/mtarch.c create mode 100644 platform/jn516x/dev/mtarch.h create mode 100644 platform/jn516x/dev/node-id.c create mode 100644 platform/jn516x/dev/rtimer-arch.c create mode 100644 platform/jn516x/dev/rtimer-arch.h create mode 100644 platform/jn516x/dev/slip_uart0.c create mode 100644 platform/jn516x/dev/uart-driver.c create mode 100644 platform/jn516x/dev/uart-driver.h create mode 100644 platform/jn516x/dev/uart0.c create mode 100644 platform/jn516x/dev/uart0.h create mode 100644 platform/jn516x/dev/uart1.c create mode 100644 platform/jn516x/dev/uart1.h create mode 100644 platform/jn516x/dev/watchdog.c create mode 100644 platform/jn516x/lib/log.c create mode 100644 platform/jn516x/lib/ringbufindex.c create mode 100644 platform/jn516x/lib/ringbufindex.h create mode 100644 platform/jn516x/lib/slip.c create mode 100644 platform/jn516x/lib/sprintf.c create mode 100644 platform/jn516x/platform-conf.h diff --git a/platform/jn516x/App_Stack_Size.ld b/platform/jn516x/App_Stack_Size.ld new file mode 100644 index 000000000..3eaaf34c0 --- /dev/null +++ b/platform/jn516x/App_Stack_Size.ld @@ -0,0 +1,46 @@ +/***************************************************************************** + * + * MODULE: App_Stack_Size.ld + * + * DESCRIPTION: Linker command file defining the default app stack size + * + **************************************************************************** + /* +* Copyright (c) 2015 NXP B.V. +* All rights reserved. +* +* Redistribution and use in source and binary forms, with or without +* modification, are permitted provided that the following conditions +* are met: +* 1. Redistributions of source code must retain the above copyright +* notice, this list of conditions and the following disclaimer. +* 2. Redistributions in binary form must reproduce the above copyright +* notice, this list of conditions and the following disclaimer in the +* documentation and/or other materials provided with the distribution. +* 3. Neither the name of NXP B.V. nor the names of its contributors +* may be used to endorse or promote products derived from this software +* without specific prior written permission. +* +* THIS SOFTWARE IS PROVIDED BY NXP B.V. AND CONTRIBUTORS ``AS IS'' AND +* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +* ARE DISCLAIMED. IN NO EVENT SHALL NXP B.V. OR CONTRIBUTORS BE LIABLE +* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS +* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +* SUCH DAMAGE. +* +* This file is part of the Contiki operating system. +* +* +*/ + +/* Default stack size for MAC applications. + * To override the default setting, copy this + * file to your apoplication build folder and + * alter the stack size as required. */ + +_stack_size = 2048; diff --git a/platform/jn516x/Makefile.jn516x b/platform/jn516x/Makefile.jn516x new file mode 100644 index 000000000..bce6adbd5 --- /dev/null +++ b/platform/jn516x/Makefile.jn516x @@ -0,0 +1,300 @@ +ifndef CONTIKI + $(error CONTIKI not defined! You must specify where CONTIKI resides!) +endif + +############################################################################## +# User definable make parameters that may be overwritten from the command line +ifdef CHIP + JENNIC_CHIP = $(CHIP) +else +JENNIC_CHIP ?= JN5168 +endif +JENNIC_PCB ?= DEVKIT4 +JENNIC_STACK ?= MAC +JENNIC_MAC ?= MiniMac +DISABLE_LTO ?= 1 +# can be set to SW or HW +DEBUG ?= None + +ifeq ($(HOST_OS),Windows) + SDK_BASE_DIR ?= C:/NXP/bstudio_nxp/sdk/JN-SW-4163 + FLASH_PROGRAMMER ?= ${SDK_BASE_DIR}/Tools/flashprogrammer/FlashCLI.exe +else + # Assume Linux + SDK_BASE_DIR ?= /usr/jn516x-sdk/JN-SW-4163 + FLASH_PROGRAMMER ?= $(CONTIKI)/tools/jn516x/JennicModuleProgrammer +endif + +############################################################################### +# Include NXP makefiles +include $(SDK_BASE_DIR)/Chip/Common/Build/config.mk +include $(SDK_BASE_DIR)/Platform/Common/Build/config.mk +include $(SDK_BASE_DIR)/Stack/Common/Build/config.mk + +# Add missing includes +INCFLAGS += -I$(COMPONENTS_BASE_DIR)/MicroSpecific/Include +INCFLAGS += -I$(COMPONENTS_BASE_DIR)/Recal/Include +INCFLAGS += -I$(COMPONENTS_BASE_DIR)/ProductionTestApi/Include +INCFLAGS += -I$(COMPONENTS_BASE_DIR)/Xcv/Include + +# Add missing libs and +# do not link with MiniMac nor MiniMacShim (we use MMAC) +LDLIBS += Recal_$(JENNIC_CHIP_FAMILY) +LDLIBS := $(subst MiniMacShim_JN516x, ,$(LDLIBS)) +ifeq ($(JENNIC_CHIP),JN5169) + LDLIBS := $(subst MiniMac_JN5169, ,$(LDLIBS)) +else +LDLIBS := $(subst MiniMac_JN516x, ,$(LDLIBS)) + LDLIBS += JPT_$(JENNIC_CHIP) +endif + +# Pass DEBUG as CFLAG +ifeq ($(DEBUG),SW) +CFLAGS += -DDEBUG=1 +endif + +# Path-independent cross-compiler +CC:=$(CROSS_COMPILE)-gcc +AS:=$(CROSS_COMPILE)-as +LD:=$(CROSS_COMPILE)-ls +AR:=$(CROSS_COMPILE)-ar +NM:=$(CROSS_COMPILE)-nm +STRIP:=$(CROSS_COMPILE)-strip +SIZE:=$(CROSS_COMPILE)-size +OBJCOPY:=$(CROSS_COMPILE)-objcopy +OBJDUMP:=$(CROSS_COMPILE)-objdump + +CFLAGS := $(subst -Wcast-align,,$(CFLAGS)) +CFLAGS := $(subst -Wall,,$(CFLAGS)) + +ARCH = ccm-star.c exceptions.c rtimer-arch.c slip_uart0.c clock.c micromac-radio.c \ + mtarch.c node-id.c watchdog.c log.c ringbufindex.c slip.c sprintf.c +# Default uart0 for printf and slip +TARGET_WITH_UART0 ?= 1 +TARGET_WITH_UART1 ?= 0 + +# Get required uart files +ifeq ($(TARGET_WITH_UART0),1) +WITH_UART = 1 +ARCH += uart0.c +endif +ifeq ($(TARGET_WITH_UART1),1) +WITH_UART = 1 +ARCH += uart1.c +endif +ifeq ($(WITH_UART),1) +ARCH += uart-driver.c +endif + +CONTIKI_TARGET_DIRS = . dev lib +CONTIKI_TARGET_MAIN = contiki-jn516x-main.c + +ifeq ($(JN516x_WITH_DR1175),1) +JN516x_WITH_DR1174 = 1 +CFLAGS += -DSENSOR_BOARD_DR1175 +CONTIKI_TARGET_DIRS += dev/dr1175 +ARCH += ht-sensor.c light-sensor.c leds-extension.c leds-arch-1175.c +endif + +ifeq ($(JN516x_WITH_DR1199),1) +JN516x_WITH_DR1174 = 1 +CFLAGS += -DSENSOR_BOARD_DR1199 +CONTIKI_TARGET_DIRS += dev/dr1199 +ARCH += pot-sensor.c leds-arch-1199.c +endif + +ifeq ($(JN516x_WITH_DR1174),1) +CFLAGS += -DSENSOR_BOARD_DR1174 +CONTIKI_TARGET_DIRS += dev/dr1174 +ARCH += button-sensor.c leds-arch.c +else +# Dongle is the default platform +JN516x_WITH_DONGLE = 1 +endif + +ifeq ($(JN516x_WITH_DONGLE),1) +CFLAGS += -DDONGLE_NODE +CONTIKI_TARGET_DIRS += dev/dongle +ARCH += leds-arch.c +endif + +ifdef nodemac +CFLAGS += -DMACID=$(nodemac) +endif + +CLEAN += *.jn516x +CLEAN += *.jn516x.bin + +MODULES += core/net \ + core/net/mac \ + core/net/mac/contikimac \ + core/net/llsec core/net/llsec/noncoresec + +CONTIKI_TARGET_SOURCEFILES += $(ARCH) +CONTIKI_SOURCEFILES += $(CONTIKI_TARGET_SOURCEFILES) + +PROJECT_OBJECTFILES += ${addprefix $(OBJECTDIR)/,$(CONTIKI_TARGET_MAIN:.c=.o)} + +CFLAGS += $(INCFLAGS) + +# Library search paths +LDFLAGS += -L$(CHIP_BASE_DIR)/Build +LDFLAGS += -L$(CHIP_BASE_DIR)/Library + +LDLIBS := $(addsuffix _$(JENNIC_CHIP_FAMILY),$(APPLIBS)) $(LDLIBS) + +ifeq ($(HOST_OS),Windows) +# Windows assumes Cygwin. Substitute all paths in CFLAGS and LDFLAGS with Windows paths. +CFLAGS := $(patsubst -I/cygdrive/c/%,-Ic:/%,$(CFLAGS)) +LDFLAGS := $(patsubst -L/cygdrive/c/%,-Lc:/%,$(LDFLAGS)) +endif + +######################################################################## + +MOTELIST = python $(CONTIKI)/tools/jn516x/mote-list.py + +# Check if we are running under Windows +ifeq ($(HOST_OS),Windows) + USBDEVPREFIX=/dev/com + USBDEVBASENAME=COM + SERIALDUMP ?= $(CONTIKI)/tools/jn516x/serialdump-windows +else +ifeq ($(HOST_OS),Darwin) + USBDEVPREFIX= + USBDEVBASENAME=/dev/tty.usbserial- + SERIALDUMP ?= $(CONTIKI)/tools/jn516x/serialdump-macos +else + # Else we assume Linux + USBDEVPREFIX= + USBDEVBASENAME=/dev/ttyUSB + SERIALDUMP ?= $(CONTIKI)/tools/jn516x/serialdump-linux +endif +endif + +# Note: this logic is different from Sky +ifneq ("", "$(filter-out %all,$(filter %.upload serial% login, $(MAKECMDGOALS)))") +ifndef MOTE + $(error MOTE not defined! You must specify which MOTE (serial port) to use) +endif +endif +PORT = $(USBDEVBASENAME)$(MOTE) + +#### make targets + +######################################################################## +# Dependency, compilation and flash-programming rules + +.PHONY: all clean + +.PRECIOUS: %.elf + +%.d: clean + +%.nm: %.$(TARGET) + $(Q)$(NM) -nS $< > $@ + +%.dmp: %.$(TARGET) + $(Q)$(OBJDUMP) -d $< > $@ + +define FINALIZE_DEPENDENCY_ +# hack: subsitute windows path back to cygwin path +sed -e 's/c:\//\/cygdrive\/c\//' $(@:.o=.d) > $(@:.o=.$$$$); \ +cp $(@:.o=.$$$$) $(@:.o=.d); \ +sed -e 's/#.*//' -e 's/^[^:]*: *//' -e 's/ *\\$$//' \ + -e '/^$$/ d' -e 's/$$/ :/' < $(@:.o=.$$$$) >> $(@:.o=.d); \ +rm -f $(@:.o=.$$$$) +endef + +CUSTOM_RULE_C_TO_OBJECTDIR_O = 1 +$(OBJECTDIR)/%.o: %.c | $(OBJECTDIR) + $(TRACE_CC) + $(Q)$(CC) $(CFLAGS) -MMD -c $< -o $@ + @$(FINALIZE_DEPENDENCY_) + +CUSTOM_RULE_LINK = 1 +ALLLIBS = $(addprefix -l,$(LDLIBS)) $(addprefix -l,$(LDSTACKLIBS)) $(addprefix -l,$(LDMYLIBS)) +ABS_APPLIBS = $(addsuffix _$(JENNIC_CHIP_FAMILY).a,$(addprefix $(COMPONENTS_BASE_DIR)/Library/lib,$(APPLIBS))) + +ifneq ($(wildcard $(SDK_BASE_DIR)/Components/Library/*),) +# The SDK is fully installed, proceed to linking and objcopy to ready-to-upload .jn516x.bin file +%.$(TARGET): %.co $(PROJECT_OBJECTFILES) $(PROJECT_LIBRARIES) contiki-$(TARGET).a $(ABS_APPLIBS) + echo ${filter %.a,$^} + $(Q)$(CC) -Wl,--gc-sections $(LDFLAGS) -T$(LINKCMD) -o $@ -Wl,--start-group \ + $(patsubst /cygdrive/c/%,c:/%,${filter-out %.a,$^}) \ + $(patsubst /cygdrive/c/%,c:/%,${filter %.a,$^}) \ + $(ALLLIBS) -Wl,--end-group -Wl,-Map,contiki-$(TARGET).map + $(OBJCOPY) -S -O binary $@ $@.bin +else +# The SDK does not include libraries, only build objects and libraries, skip linking +%.$(TARGET): %.co $(PROJECT_OBJECTFILES) $(PROJECT_LIBRARIES) contiki-$(TARGET).a + echo Creating empty $@ + touch $@ +endif + +%.$(TARGET).bin: %.$(TARGET) + $(Q)$(OBJCOPY) -S -O binary $< $@ + +symbols.c symbols.h: + @${CONTIKI}/tools/make-empty-symbols + +### Upload target to one jn516x mote specified by MOTE=portNumber +ifeq ($(HOST_OS),Windows) +%.upload: %.$(TARGET).bin + ${FLASH_PROGRAMMER} -a -c $(PORT) -B 1000000 -s -w -f $< +else +%.upload: %.$(TARGET).bin + ${FLASH_PROGRAMMER} -V 10 -v -s $(PORT) -I 38400 -P 1000000 -f $< +endif + +### Flash the given file +ifeq ($(HOST_OS),Windows) +%.flash: ${FLASH_PROGRAMMER} + ${FLASH_PROGRAMMER} -a -c $(PORT) -B 1000000 -s -w -f $*.$(TARGET).bin +else +%.flash: ${FLASH_PROGRAMMER} + ${FLASH_PROGRAMMER} -V 10 -v -s $(PORT) -I 38400 -P 1000000 -s -f $*.$(TARGET).bin +endif + +### List the ports with connected jn516x motes +motelist: + $(Q)$(MOTELIST) ${FLASH_PROGRAMMER} \# + +motelistmac: + $(Q)$(MOTELIST) ${FLASH_PROGRAMMER} \! + +motelistinfo: + $(Q)$(MOTELIST) ${FLASH_PROGRAMMER} \? + +### Upload target to all connected jn516x motes +%.uploadall: %.$(TARGET).bin + $(Q)$(MOTELIST) ${FLASH_PROGRAMMER} $< + +### Flash the given file to all connected jn516x motes +%.flashall: + $(Q)$(MOTELIST) ${FLASH_PROGRAMMER} $* + +### Dump output from all connected jn516x motes +serialdumpall: + $(Q)$(MOTELIST) ${FLASH_PROGRAMMER} \% $(SERIALDUMP) + +########### login: read serial line ############## +### USAGE: make TARGET=jn516x login UART_BAUDRATE={baudrate} {serial device} +### UART_BAUDRATE: i.e., 115200. default is 1000000 +### example: make TARGET=jn516x UART_BAUDRATE=115200 login MOTE=1 + +UART_BAUDRATE ?= 1000000 + +$(CONTIKI)/tools/tunslip6: $(CONTIKI)/tools/tunslip6.c + ($(MAKE) -C $(CONTIKI)/tools tunslip6 CFLAGS= LDFLAGS= LDLIBS= INCFLAGS=) + +$(SERIALDUMP): $(CONTIKI)/tools/jn516x/serialdump.c + (cd $(CONTIKI)/tools/jn516x; ${MAKE} $(notdir $(SERIALDUMP))) + +login: $(SERIALDUMP) + $(SERIALDUMP) -b${UART_BAUDRATE} $(USBDEVPREFIX)$(PORT) + +serialview: $(SERIALDUMP) + $(SERIALDUMP) -b${UART_BAUDRATE} $(USBDEVPREFIX)$(PORT) | $(CONTIKI)/tools/timestamp + +serialdump: $(SERIALDUMP) + $(SERIALDUMP) -b${UART_BAUDRATE} $(USBDEVPREFIX)$(PORT) | $(CONTIKI)/tools/timestamp | tee serialdump-$(notdir $(PORT))-`date +%Y%m%d-%H%M` diff --git a/platform/jn516x/README.md b/platform/jn516x/README.md new file mode 100644 index 000000000..d67bfd029 --- /dev/null +++ b/platform/jn516x/README.md @@ -0,0 +1,183 @@ +# NXP JN516x platform + +## Overview + +The JN516x series is a range of ultra low power, high performance wireless microcontrollers from NXP. They feature an enhanced 32-bit RISC processor (256kB/32kB/4kB Flash/RAM/EEPROM for JN5168), and also include a 2.4GHz IEEE802.15.4-compliant transceiver. +These system on chip (SoC) devices have the following main [features][jn516x-datasheet]: +* 32-bit RISC CPU (Beyond Architecture -- BA), 1 to 32MHz clock speed +* 2.4GHz IEEE802.15.4-compliant transceiver +* 128-bit AES security processor +* MAC accelerator with packet formatting, CRCs, address check, auto-acks, timers +* Transmit power 2.5dBm +* Receiver sensitivity -95dBm +* RX current 17mA, TX 15mA +* Integrated ultra low power sleep oscillator – 0.6μA +* Deep sleep current 0.12μA (Wake-up from IO) +* Time of Flight engine for ranging +* Antenna Diversity (Auto RX) +* 2.0V to 3.6V battery operation +* Supply voltage monitor with 8 programmable thresholds +* Built-in battery and temperature sensors +* Infra-red remote control transmitter +* Peripherals: I2C, SPI, 2x UART, 4-input 10-bit ADC, comparator, 5x PWM + +## Maintainers and Contact + +Long-term maintainers: +* Theo Van Daele, NXP, theo.van.daele@nxp.com, github user: [TeVeDe](https://github.com/TeVeDe) +* Simon Duquennoy, SICS, simonduq@sics.se, github user: [simonduq](https://github.com/simonduq) + +Other contributors: +* Beshr Al Nahas, SICS (now Chalmers University), beshr@chalmers.se, github user: [beshrns](https://github.com/beshrns) +* Atis Elsts, SICS, atis.elsts@sics.se, github user: [atiselsts](https://github.com/atiselsts) + +Additional long-term contact: +* Hugh Maaskant, NXP, hugh.maaskant@nxp.com, github user: [hugh-maaskant](https://github.com/hugh-maaskant) + +## License + +All files are under BSD license, as described by the copyright statement in every source file. + +## Port Features + +The following features have been implemented: + * A radio driver with two modes (polling and interrupt based) + * CCM* driver with HW accelerated AES + * UART driver (with HW and SW flow control, 1'000'000 baudrate by default) + * Contiki system clock and rtimers (16MHz tick frequency based on 32 MHz crystal) + * 32.768kHz external oscillator + * Periodic DCO recalibration + * CPU "doze" mode + * HW random number generator used as a random seed for pseudo-random generator + * Watchdog, JN516x HW exception handlers + +The following hardware platforms have been tested: + * DR1174 evaluation board (with a button sensor) + * DR1175 sensor board (with humidity/temperature and light sensors) + * DR1199 sensor board (with potentiometer and button sensors) + * USB dongle + +## TODO list + +The following features are planned: + * CPU deeper sleep mode support (where the 32 MHz crystal is turned off) + * Time-accurate radio primitives ("send at", "listen until") + * External storage + +## Requirements + +To start using JN516x with Contiki, the following are required: + * The toolchain and Software Development Kit to compile Contiki for JN516x + * Drivers so that your OS can communicate with your hardware + * Software to upload images to the JN516x + +### Install a Toolchain + +The toolchain used to build Contiki for JN516x is `ba-elf-gcc`. +The compiler as well as the binary libraries required to link the executables can be downloaded from NXP. To express your interest in obtaining them, go to [NXP 802.15.4 software page][NXP-802.15.4-software], select "JN-SW-4163", and contact the NXP support through the web form. The download link is then obtained via e-mail (allow 1+ working day for a reply). +The example applications in this port have been tested with compiler version `gcc-4.7.4-ba-r36379`. + +Linux and Windows instructions: +* On Linux: A compiled version for linux 64-bit is available: download [this](http://simonduq.github.io/resources/ba-elf-gcc-4.7.4-part1.tar.bz2) and [this](http://simonduq.github.io/resources/ba-elf-gcc-4.7.4-part2.tar.bz2) file, extract both in `/usr/ba-elf-gcc` such and add `/usr/ba-elf-gcc/bin` to your `$PATH` environment variable. Place the JN516x SDK under `/usr/jn516x-sdk`. +* On Windows: Run the setup program and select `C:/NXP/bstudio_nxp/` as install directory. Also make sure your PATH environment variable points to the compiler binaries (by default in `C:/NXP/bstudio_nxp/sdk/Tools/ba-elf-ba2-r36379/bin`). + +### Drivers + +The JN516x platforms feature FTDI serial-to-USB modules. The driver is commonly found in most OS, but if required it can be downloaded from + +### Device Enumerations +For the UART, serial line settings are 1000000 8N1, no flow control. + +Once all drivers have been installed correctly: +* On Windows, devices will appear as a virtual COM port. +* On Linux and OS X, devices will appear as `/dev/tty*`. + +### Software to Program the Nodes + +The JN516x can be programmed via the serial boot loader on the chip. +* On Linux, nodes can be programmed via the serial boot loader using the [JennicModuleProgrammer] tool. It is pre-installed under `tools/jn516x/JennicModuleProgrammer`. +* On Windows, nodes are programmed using NXP's Flash Programmer. There are two versions of it: GUI and command line. The Contiki make system is configured to use the command line version. By default it looks for the programmer in the SDK base directory under `Tools/flashprogrammer/FlashCLI.exe`. With the default SDK installation path the file should be located under `C:/NXP/bstudio_nxp/sdk/JN-SW-4163/Tools/flashprogrammer/FlashCLI.exe`. Modify `platforms/jn516x/Makefile.common` to change this default location. + +## Using the Port + +The following examples are intended to work off-the-shelf: +* Platform-specific examples under `examples/jn516x` +* All platform-independent Contiki application examples + +### Building an example + +To build the classic "hello world" example, navigate to `examples/hello-world`. It is recommended to either set the `TARGET` environmental variable or to save the `jn516x` platform as the default make target. To do that, run: + +`make TARGET=jn516x savetarget` + +Then run `make hello-world` to compile the application for JN516x platform. + +### Uploading an example + +Run the `upload` command to program the binary image on it: +`make hello-world.upload MOTE=0` + +The `MOTE` argument is used to specify to which of the ports the device is connected. For example, if there is a single mote connected to `/dev/ttyUSB3` in Linux (or, alternatively, `COM3` in Windows), the right command would be: +`make hello-world.upload MOTE=3` + +Note that on Windows, the FTDI drivers are able to switch the board to programming mode before uploading the image. + +On Linux, the drivers are not able to do so yet. We use a modified bootloader for JN516x, where nodes wait 5s in programming mode after a reset. You simply need to reset them before using `make upload`. The modified bootloader can be downloaded [here](http://simonduq.github.io/resources/BootLoader_JN5168.ba2.bin) and installed using a JTAG programmer, or alternatively, [this image](http://simonduq.github.io/resources/BootLoaderUpdater_JN5168.bin) can be installed as a normal application using the normal Windows tools. Once the device resets, this application will run and will then install the new boot loader. It generates some status output over UART0 at 115200 baud during this process. **Warning**: use the images above at your risk; NXP does not accept responsibility for any devices that are rendered unusable as a result of using it. + +### Listening to output + +Run the `login` command to start the `serialdump` application. +`make login MOTE=3` + +On Linux: after the application has started, press the reset button on the node. + +### Platform-specific make targets + +* `.flash` - flash the (pre-compiled) application to a JN516x mote (specified via the `MOTE` variable) +* `.flashall` - flash the (pre-compiled) application to all all connected JN516x motes +* `.upload` - compile and flash the application to a JN516x mote (specified via the `MOTE` variable) +* `.uploadall` - compile and flash the application to all all connected JN516x motes +* `login`, `serialview`, `serialdump` - dump serial port output from a JN516x mote (specified via the `MOTE` variable) +* `serialdumpall` - dump serial port output from all connected JN516x motes +* `motelist` - list all connected JN516x motes. +* `motelistmac` - list MAC addresses of all connected JN516x motes (Note: not implemented on Linux!) +* `motelistinfo` - list info about all connected JN516x motes (Note: very limited functionality on Linux!) + +*Troubleshooting:* you need a working Python installation for these commands to work. On Windows, make sure Python executable is in your `PATH`. + +### Compiling for different MCUs and boards + +The platforms can selected by using `Makefile` variables. + +The following MCU models are supported: +* `JN5164` - 160kB/32kB/4kB Flash/RAM/EEPROM +* `JN5168` - 256kB/32kB/4kB Flash/RAM/EEPROM (default MCU) +* `JN5169` - 512kB/32kB/4kB Flash/RAM/EEPROM + +Set `CHIP` variable to change this; for example, to select JN5164 use: +`make CHIP=JN5164` + +The following platform-specific configurations are supported: +* DR1174 evaluation kit; enable this with `JN516x_WITH_DR1174 = 1` in your makefile +* DR1174 with DR1175 sensor board; enable this with `JN516x_WITH_DR1175 = 1` (will set `JN516x_WITH_DR1174` automatically) +* DR1174 with DR1199 sensor board; enable this with `JN516x_WITH_DR1199 = 1` (will set `JN516x_WITH_DR1174` automatically) +* USB dongle; enable this with `JN516x_WITH_DONGLE = 1` + +### Node IEEE/RIME/IPv6 Addresses + +Nodes will autoconfigure their IPv6 address based on their 64-bit IEEE/MAC address. The 64-bit MAC address is read directly from JN516x System on Chip. +The 16-bit RIME address and the Node ID are set from the last 16-bits of the 64-bit MAC address. + +## Additional documentation + +1. [Data Sheet: JN516x IEEE802.15.4 Wireless Microcontroller][jn516x-datasheet] +2. [JN516x web page][jn516x-web] +3. [JN5168 web page][jn5168-web] +4. [JN516x user manuals][user-manuals] + +[jn516x-datasheet]: http://www.nxp.com/documents/data_sheet/JN516X.pdf +[jn516x-web]: http://www.nxp.com/products/microcontrollers/product_series/jn516x +[jn5168-web]: http://www.nxp.com/products/microcontrollers/product_series/jn516x/JN5168.html +[user-manuals]: http://www.nxp.com/technical-support-portal/#/tid=1,sid=,bt=,tab=usermanuals,p=1,rpp=,sc=,so=,jump= +[NXP-802.15.4-software]: http://www.nxp.com/techzones/wireless-connectivity/ieee802-15-4.html +[JennicModuleProgrammer]: https://github.com/WRTIOT/JennicModuleProgrammer diff --git a/platform/jn516x/contiki-conf.h b/platform/jn516x/contiki-conf.h new file mode 100644 index 000000000..41135c187 --- /dev/null +++ b/platform/jn516x/contiki-conf.h @@ -0,0 +1,195 @@ +/* + * Copyright (c) 2015, SICS Swedish ICT. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the Institute nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * This file is part of the Contiki operating system. + * + */ + +#ifndef CONTIKI_CONF_H_ +#define CONTIKI_CONF_H_ + +#ifdef PLATFORM_CONF_H +#include PLATFORM_CONF_H +#else +#include "platform-conf.h" +#endif /* PLATFORM_CONF_H */ + +#ifndef CCM_STAR_CONF +#define CCM_STAR_CONF ccm_star_driver_jn516x +#endif /* CCM_STAR_CONF */ + +#ifndef NETSTACK_CONF_MAC +#define NETSTACK_CONF_MAC tschmac_driver +#endif /* NETSTACK_CONF_MAC */ + +#ifndef NETSTACK_CONF_RDC +#define NETSTACK_CONF_RDC nordc_driver +#endif /* NETSTACK_CONF_RDC */ + +#ifndef NETSTACK_CONF_RADIO +#define NETSTACK_CONF_RADIO micromac_radio_driver +#endif /* NETSTACK_CONF_RADIO */ + +#ifndef NETSTACK_CONF_FRAMER +#define NETSTACK_CONF_FRAMER framer_802154 +#endif /* NETSTACK_CONF_FRAMER */ + +#define PACKETBUF_CONF_ATTRS_INLINE 1 + +#ifndef IEEE802154_CONF_PANID +#define IEEE802154_CONF_PANID 0xABCD +#endif /* IEEE802154_CONF_PANID */ + +#ifndef ENERGEST_CONF_ON +#define ENERGEST_CONF_ON 1 +#endif /* ENERGEST_CONF_ON */ + +#define WITH_ASCII 1 + +#define PROCESS_CONF_NUMEVENTS 8 +#define PROCESS_CONF_STATS 1 + +#if !defined NETSTACK_CONF_WITH_IPV6 && !defined NETSTACK_CONF_WITH_IPV4 && !defined NETSTACK_CONF_WITH_RIME +#define NETSTACK_CONF_WITH_IPV6 1 +#endif /* NETSTACK_CONF_ not defined */ + +/* Network setup for IP */ +#if NETSTACK_CONF_WITH_IPV4 || NETSTACK_CONF_WITH_IPV6 + +#define LINKADDR_CONF_SIZE 8 + +#ifndef QUEUEBUF_CONF_NUM +#define QUEUEBUF_CONF_NUM 16 +#endif + +/* Network setup for non-IP (rime). */ +#else + +#define LINKADDR_CONF_SIZE 2 + +#ifndef COLLECT_NEIGHBOR_CONF_MAX_COLLECT_NEIGHBORS +#define COLLECT_NEIGHBOR_CONF_MAX_COLLECT_NEIGHBORS 32 +#endif /* COLLECT_NEIGHBOR_CONF_MAX_COLLECT_NEIGHBORS */ + +#ifndef QUEUEBUF_CONF_NUM +#define QUEUEBUF_CONF_NUM 16 +#endif /* QUEUEBUF_CONF_NUM */ + +#endif /* NETSTACK_CONF_WITH_IPV4 || NETSTACK_CONF_WITH_IPV6 */ + +/* Network setup for IPv6 */ +#if NETSTACK_CONF_WITH_IPV6 + +/* Network setup for IPv6 */ +#define NETSTACK_CONF_NETWORK sicslowpan_driver +#define UIP_CONF_BROADCAST 1 + +/* Configure NullRDC for when it is selected */ +#define NULLRDC_CONF_802154_AUTOACK_HW 1 + +#define UIP_CONF_LL_802154 1 +#define UIP_CONF_LLH_LEN 0 + +#define UIP_CONF_ROUTER 1 +#ifndef UIP_CONF_IPV6_RPL +#define UIP_CONF_IPV6_RPL 1 +#endif /* UIP_CONF_IPV6_RPL */ + +/* configure number of neighbors and routes */ +#ifndef NBR_TABLE_CONF_MAX_NEIGHBORS +#define NBR_TABLE_CONF_MAX_NEIGHBORS 20 +#endif /* NBR_TABLE_CONF_MAX_NEIGHBORS */ +#ifndef UIP_CONF_MAX_ROUTES +#define UIP_CONF_MAX_ROUTES 20 +#endif /* UIP_CONF_MAX_ROUTES */ + +#define UIP_CONF_ND6_SEND_RA 0 +#define UIP_CONF_ND6_REACHABLE_TIME 600000 +#define UIP_CONF_ND6_RETRANS_TIMER 10000 + +#ifndef UIP_CONF_IPV6_QUEUE_PKT +#define UIP_CONF_IPV6_QUEUE_PKT 0 +#endif /* UIP_CONF_IPV6_QUEUE_PKT */ +#define UIP_CONF_IPV6_CHECKS 1 +#define UIP_CONF_IPV6_REASSEMBLY 0 +#define UIP_CONF_NETIF_MAX_ADDRESSES 3 +#define UIP_CONF_ND6_MAX_PREFIXES 3 +#define UIP_CONF_ND6_MAX_DEFROUTERS 2 +#define UIP_CONF_IP_FORWARD 0 +#ifndef UIP_CONF_BUFFER_SIZE +#define UIP_CONF_BUFFER_SIZE 1280 +#endif + +#define SICSLOWPAN_CONF_COMPRESSION_IPV6 0 +#define SICSLOWPAN_CONF_COMPRESSION_HC1 1 +#define SICSLOWPAN_CONF_COMPRESSION_HC01 2 +#define SICSLOWPAN_CONF_COMPRESSION SICSLOWPAN_COMPRESSION_HC06 +#ifndef SICSLOWPAN_CONF_FRAG +#define SICSLOWPAN_CONF_FRAG 1 +#define SICSLOWPAN_CONF_MAXAGE 8 +#endif /* SICSLOWPAN_CONF_FRAG */ +#define SICSLOWPAN_CONF_MAX_ADDR_CONTEXTS 2 +#ifndef SICSLOWPAN_CONF_MAX_MAC_TRANSMISSIONS +#define SICSLOWPAN_CONF_MAX_MAC_TRANSMISSIONS 5 +#endif /* SICSLOWPAN_CONF_MAX_MAC_TRANSMISSIONS */ +#define UIP_CONF_ICMP_DEST_UNREACH 1 + +#define UIP_CONF_DHCP_LIGHT +#ifndef UIP_CONF_RECEIVE_WINDOW +#define UIP_CONF_RECEIVE_WINDOW 48 +#endif +#ifndef UIP_CONF_TCP_MSS +#define UIP_CONF_TCP_MSS 48 +#endif +#define UIP_CONF_MAX_CONNECTIONS 4 +#define UIP_CONF_MAX_LISTENPORTS 8 +#define UIP_CONF_UDP_CONNS 12 +#define UIP_CONF_FWCACHE_SIZE 30 +#define UIP_CONF_BROADCAST 1 +#define UIP_ARCH_CHKSUM 0 +#define UIP_ARCH_ADD32 0 +#define UIP_CONF_UDP 1 +#define UIP_CONF_UDP_CHECKSUMS 1 +#define UIP_CONF_PINGADDRCONF 0 +#define UIP_CONF_LOGGING 0 +#define LOG_CONF_ENABLED 0 + +#define UIP_CONF_TCP_SPLIT 0 + +#define UIP_CONF_BYTE_ORDER UIP_BIG_ENDIAN +#define UIP_CONF_LOGGING 0 + +#endif /* NETSTACK_CONF_WITH_IPV6 */ + +/* include the project config */ +/* PROJECT_CONF_H might be defined in the project Makefile */ +#ifdef PROJECT_CONF_H +#include PROJECT_CONF_H +#endif /* PROJECT_CONF_H */ + +#endif /* CONTIKI_CONF_H_ */ diff --git a/platform/jn516x/contiki-jn516x-main.c b/platform/jn516x/contiki-jn516x-main.c new file mode 100644 index 000000000..2bf27e64b --- /dev/null +++ b/platform/jn516x/contiki-jn516x-main.c @@ -0,0 +1,468 @@ +/* + * Copyright (c) 2014, SICS Swedish ICT. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials provided + * with the distribution. + * 3. The name of the author may not be used to endorse or promote + * products derived from this software without specific prior + * written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE + * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * This file is part of the Contiki OS + * + */ + +/** + * \file + * Contiki main for NXP JN516X platform + * + * \author + * Beshr Al Nahas + */ + +#include +#include +#include + +#include "dev/watchdog.h" +#include +#include +#include +#include "dev/uart0.h" + +#include "contiki.h" +#include "net/netstack.h" + +#include "dev/serial-line.h" + +#include "net/ip/uip.h" +#include "dev/leds.h" + +#include "lib/random.h" +#include "sys/node-id.h" +#include "rtimer-arch.h" + +#if NETSTACK_CONF_WITH_IPV6 +#include "net/ipv6/uip-ds6.h" +#endif /* NETSTACK_CONF_WITH_IPV6 */ + +#include "net/rime/rime.h" + +#include "dev/micromac-radio.h" +#include "MMAC.h" +/* Includes depending on connected sensor boards */ +#if SENSOR_BOARD_DR1175 +#include "light-sensor.h" +#include "ht-sensor.h" +SENSORS(&light_sensor, &ht_sensor); +#elif SENSOR_BOARD_DR1199 +#include "button-sensor.h" +#include "pot-sensor.h" +SENSORS(&pot_sensor, &button_sensor); +#else +#include "dev/button-sensor.h" +/* #include "dev/pir-sensor.h" */ +/* #include "dev/vib-sensor.h" */ +/* &pir_sensor, &vib_sensor */ +SENSORS(&button_sensor); +#endif +unsigned char node_mac[8]; + +/* Symbol defined by the linker script + * marks the end of the stack taking into account the used heap */ +extern uint32_t heap_location; + +#ifndef NETSTACK_CONF_WITH_IPV4 +#define NETSTACK_CONF_WITH_IPV4 0 +#endif + +#if NETSTACK_CONF_WITH_IPV4 +#include "net/ip/uip.h" +#include "net/ipv4/uip-fw.h" +#include "net/ipv4/uip-fw-drv.h" +#include "net/ipv4/uip-over-mesh.h" +static struct uip_fw_netif slipif = +{ UIP_FW_NETIF(192, 168, 1, 2, 255, 255, 255, 255, slip_send) }; +static struct uip_fw_netif meshif = +{ UIP_FW_NETIF(172, 16, 0, 0, 255, 255, 0, 0, uip_over_mesh_send) }; + +#define UIP_OVER_MESH_CHANNEL 8 +static uint8_t is_gateway; +#endif /* NETSTACK_CONF_WITH_IPV4 */ + +#ifdef EXPERIMENT_SETUP +#include "experiment-setup.h" +#endif + +/*---------------------------------------------------------------------------*/ +#define DEBUG 1 +#if DEBUG +#define PRINTF(...) do { printf(__VA_ARGS__); } while(0) +#else +#define PRINTF(...) do {} while(0) +#endif +/*---------------------------------------------------------------------------*/ +/* Reads MAC from SoC + * Must be called before node_id_restore() + * and network addresses initialization */ +static void +init_node_mac(void) +{ + tuAddr psExtAddress; + vMMAC_GetMacAddress(&psExtAddress.sExt); + node_mac[7] = psExtAddress.sExt.u32L; + node_mac[6] = psExtAddress.sExt.u32L >> (uint32_t)8; + node_mac[5] = psExtAddress.sExt.u32L >> (uint32_t)16; + node_mac[4] = psExtAddress.sExt.u32L >> (uint32_t)24; + node_mac[3] = psExtAddress.sExt.u32H; + node_mac[2] = psExtAddress.sExt.u32H >> (uint32_t)8; + node_mac[1] = psExtAddress.sExt.u32H >> (uint32_t)16; + node_mac[0] = psExtAddress.sExt.u32H >> (uint32_t)24; +} +/*---------------------------------------------------------------------------*/ +#if !PROCESS_CONF_NO_PROCESS_NAMES +static void +print_processes(struct process *const processes[]) +{ + /* const struct process * const * p = processes;*/ + PRINTF("Starting"); + while(*processes != NULL) { + PRINTF(" '%s'", (*processes)->name); + processes++; + } + putchar('\n'); +} +#endif /* !PROCESS_CONF_NO_PROCESS_NAMES */ +/*---------------------------------------------------------------------------*/ +#if NETSTACK_CONF_WITH_IPV4 +static void +set_gateway(void) +{ + if(!is_gateway) { + leds_on(LEDS_RED); + printf("%d.%d: making myself the IP network gateway.\n\n", + linkaddr_node_addr.u8[0], linkaddr_node_addr.u8[1]); + printf("IPv4 address of the gateway: %d.%d.%d.%d\n\n", + uip_ipaddr_to_quad(&uip_hostaddr)); + uip_over_mesh_set_gateway(&linkaddr_node_addr); + uip_over_mesh_make_announced_gateway(); + is_gateway = 1; + } +} +#endif /* NETSTACK_CONF_WITH_IPV4 */ +/*---------------------------------------------------------------------------*/ +static void +start_autostart_processes() +{ +#if !PROCESS_CONF_NO_PROCESS_NAMES + print_processes(autostart_processes); +#endif /* !PROCESS_CONF_NO_PROCESS_NAMES */ + autostart_start(autostart_processes); +} +/*---------------------------------------------------------------------------*/ +#if NETSTACK_CONF_WITH_IPV6 +static void +start_uip6(void) +{ + NETSTACK_NETWORK.init(); + +#ifndef WITH_SLIP_RADIO + process_start(&tcpip_process, NULL); +#else +#if WITH_SLIP_RADIO == 0 + process_start(&tcpip_process, NULL); +#endif +#endif /* WITH_SLIP_RADIO */ + +#if DEBUG + PRINTF("Tentative link-local IPv6 address "); + { + uip_ds6_addr_t *lladdr; + int i; + lladdr = uip_ds6_get_link_local(-1); + for(i = 0; i < 7; ++i) { + PRINTF("%02x%02x:", lladdr->ipaddr.u8[i * 2], + lladdr->ipaddr.u8[i * 2 + 1]); + /* make it hardcoded... */ + } + lladdr->state = ADDR_AUTOCONF; + + PRINTF("%02x%02x\n", lladdr->ipaddr.u8[14], lladdr->ipaddr.u8[15]); + } +#endif /* DEBUG */ + + if(!UIP_CONF_IPV6_RPL) { + uip_ipaddr_t ipaddr; + int i; + uip_ip6addr(&ipaddr, 0xaaaa, 0, 0, 0, 0, 0, 0, 0); + uip_ds6_set_addr_iid(&ipaddr, &uip_lladdr); + uip_ds6_addr_add(&ipaddr, 0, ADDR_TENTATIVE); + PRINTF("Tentative global IPv6 address "); + for(i = 0; i < 7; ++i) { + PRINTF("%02x%02x:", + ipaddr.u8[i * 2], ipaddr.u8[i * 2 + 1]); + } + PRINTF("%02x%02x\n", + ipaddr.u8[7 * 2], ipaddr.u8[7 * 2 + 1]); + } +} +#endif /* NETSTACK_CONF_WITH_IPV6 */ +/*---------------------------------------------------------------------------*/ +static void +start_network_layer(void) +{ +#if NETSTACK_CONF_WITH_IPV6 + start_uip6(); +#endif /* NETSTACK_CONF_WITH_IPV6 */ + start_autostart_processes(); + /* To support link layer security in combination with NETSTACK_CONF_WITH_IPV4 and + * TIMESYNCH_CONF_ENABLED further things may need to be moved here */ +} +/*--------------------------------------------------------------------------*/ +static void +set_linkaddr(void) +{ + int i; + linkaddr_t addr; + memset(&addr, 0, sizeof(linkaddr_t)); +#if NETSTACK_CONF_WITH_IPV6 + memcpy(addr.u8, node_mac, sizeof(addr.u8)); +#else + if(node_id == 0) { + for(i = 0; i < sizeof(linkaddr_t); ++i) { + addr.u8[i] = node_mac[7 - i]; + } + } else { + addr.u8[0] = node_id & 0xff; + addr.u8[1] = node_id >> 8; + } +#endif + linkaddr_set_node_addr(&addr); +#if DEBUG + PRINTF("Link-layer address: "); + for(i = 0; i < sizeof(addr.u8) - 1; i++) { + PRINTF("%d.", addr.u8[i]); + } + PRINTF("%d\n", addr.u8[i]); +#endif +} +/*---------------------------------------------------------------------------*/ +#if USE_EXTERNAL_OSCILLATOR +static bool_t +init_xosc(void) +{ + /* The internal 32kHz RC oscillator is used by default; + * Initialize and enable the external 32.768kHz crystal. + */ + vAHI_Init32KhzXtal(); + /* wait for 1.0 seconds for the crystal to stabilize */ + clock_time_t start = clock_time(); + clock_time_t now; + do { + now = clock_time(); + watchdog_periodic(); + } while(now - start < CLOCK_SECOND); + /* switch to the 32.768 kHz crystal */ + return bAHI_Set32KhzClockMode(E_AHI_XTAL); +} +#endif +/*---------------------------------------------------------------------------*/ +#if WITH_TINYOS_AUTO_IDS +uint16_t TOS_NODE_ID = 0x1234; /* non-zero */ +uint16_t TOS_LOCAL_ADDRESS = 0x1234; /* non-zero */ +#endif /* WITH_TINYOS_AUTO_IDS */ +int +main(void) +{ + /* Set stack overflow address for detecting overflow in runtime */ + vAHI_SetStackOverflow(TRUE, ((uint32_t *)&heap_location)[0]); + + clock_init(); + watchdog_init(); + leds_init(); + leds_on(LEDS_ALL); + init_node_mac(); + + energest_init(); + ENERGEST_ON(ENERGEST_TYPE_CPU); + + node_id_restore(); + +#if WITH_TINYOS_AUTO_IDS + node_id = TOS_NODE_ID; +#endif /* WITH_TINYOS_AUTO_IDS */ + /* for setting "hardcoded" IEEE 802.15.4 MAC addresses */ +#ifdef IEEE_802154_MAC_ADDRESS + { + uint8_t ieee[] = IEEE_802154_MAC_ADDRESS; + memcpy(node_mac, ieee, sizeof(uip_lladdr.addr)); + node_mac[7] = node_id & 0xff; + } +#endif + + /* Initialize random with a seed from the SoC random generator. + * This must be done before selecting the high-precision external oscillator. + */ + vAHI_StartRandomNumberGenerator(E_AHI_RND_SINGLE_SHOT, E_AHI_INTS_DISABLED); + random_init(u16AHI_ReadRandomNumber()); + + process_init(); + ctimer_init(); + uart0_init(UART_BAUD_RATE); /* Must come before first PRINTF */ + +#if USE_EXTERNAL_OSCILLATOR + init_xosc(); +#endif + +#if NETSTACK_CONF_WITH_IPV4 + slip_arch_init(UART_BAUD_RATE); +#endif /* NETSTACK_CONF_WITH_IPV4 */ + + /* check for reset source */ + if(bAHI_WatchdogResetEvent()) { + PRINTF("Init: Watchdog timer has reset device!\r\n"); + } + process_start(&etimer_process, NULL); + set_linkaddr(); + netstack_init(); + +#if NETSTACK_CONF_WITH_IPV6 +#if UIP_CONF_IPV6_RPL + PRINTF(CONTIKI_VERSION_STRING " started with IPV6, RPL\n"); +#else + PRINTF(CONTIKI_VERSION_STRING " started with IPV6\n"); +#endif +#elif NETSTACK_CONF_WITH_IPV4 + PRINTF(CONTIKI_VERSION_STRING " started with IPV4\n"); +#else + PRINTF(CONTIKI_VERSION_STRING " started\n"); +#endif + + if(node_id > 0) { + PRINTF("Node id is set to %u.\n", node_id); + } else { + PRINTF("Node id is not set.\n"); + } +#if NETSTACK_CONF_WITH_IPV6 + memcpy(&uip_lladdr.addr, node_mac, sizeof(uip_lladdr.addr)); + queuebuf_init(); +#endif /* NETSTACK_CONF_WITH_IPV6 */ + + PRINTF("%s %s %s\n", NETSTACK_LLSEC.name, NETSTACK_MAC.name, NETSTACK_RDC.name); + +#if !NETSTACK_CONF_WITH_IPV4 && !NETSTACK_CONF_WITH_IPV6 + uart0_set_input(serial_line_input_byte); + serial_line_init(); +#endif + +#if TIMESYNCH_CONF_ENABLED + timesynch_init(); + timesynch_set_authority_level((linkaddr_node_addr.u8[0] << 4) + 16); +#endif /* TIMESYNCH_CONF_ENABLED */ + +#if NETSTACK_CONF_WITH_IPV4 + process_start(&tcpip_process, NULL); + process_start(&uip_fw_process, NULL); /* Start IP output */ + process_start(&slip_process, NULL); + + slip_set_input_callback(set_gateway); + + { + uip_ipaddr_t hostaddr, netmask; + + uip_init(); + + uip_ipaddr(&hostaddr, 172, 16, + linkaddr_node_addr.u8[0], linkaddr_node_addr.u8[1]); + uip_ipaddr(&netmask, 255, 255, 0, 0); + uip_ipaddr_copy(&meshif.ipaddr, &hostaddr); + + uip_sethostaddr(&hostaddr); + uip_setnetmask(&netmask); + uip_over_mesh_set_net(&hostaddr, &netmask); + /* uip_fw_register(&slipif);*/ + uip_over_mesh_set_gateway_netif(&slipif); + uip_fw_default(&meshif); + uip_over_mesh_init(UIP_OVER_MESH_CHANNEL); + PRINTF("uIP started with IP address %d.%d.%d.%d\n", + uip_ipaddr_to_quad(&hostaddr)); + } +#endif /* NETSTACK_CONF_WITH_IPV4 */ + + watchdog_start(); + NETSTACK_LLSEC.bootstrap(start_network_layer); + + leds_off(LEDS_ALL); + int r; + while(1) { + do { + /* Reset watchdog. */ + watchdog_periodic(); + r = process_run(); + } while(r > 0); + /* + * Idle processing. + */ + watchdog_stop(); + +#if DCOSYNCH_CONF_ENABLED + /* Calibrate the DCO every DCOSYNCH_PERIOD + * if we have more than 500uSec until next rtimer + * PS: Calibration disables interrupts and blocks for 200uSec. + * */ + static unsigned long last_dco_calibration_time = 0; + if(clock_seconds() - last_dco_calibration_time > DCOSYNCH_PERIOD) { + if(rtimer_arch_get_time_until_next_wakeup() > RTIMER_SECOND / 2000) { + /* PRINTF("ContikiMain: Calibrating the DCO\n"); */ + eAHI_AttemptCalibration(); + /* Patch to allow CpuDoze after calibration */ + vREG_PhyWrite(REG_PHY_IS, REG_PHY_INT_VCO_CAL_MASK); + last_dco_calibration_time = clock_seconds(); + } + } +#endif /* DCOSYNCH_CONF_ENABLED */ + ENERGEST_OFF(ENERGEST_TYPE_CPU); + ENERGEST_ON(ENERGEST_TYPE_LPM); + vAHI_CpuDoze(); + watchdog_start(); + ENERGEST_OFF(ENERGEST_TYPE_LPM); + ENERGEST_ON(ENERGEST_TYPE_CPU); + } + + return 0; +} +/*---------------------------------------------------------------------------*/ +void +AppColdStart(void) +{ + /* After reset or sleep with memory off */ + main(); +} +/*---------------------------------------------------------------------------*/ +void +AppWarmStart(void) +{ + /* Wakeup after sleep with memory on. + * TODO: Need to initialize devices but not the application state */ + main(); +} +/*---------------------------------------------------------------------------*/ diff --git a/platform/jn516x/dev/ccm-star.c b/platform/jn516x/dev/ccm-star.c new file mode 100644 index 000000000..76bf97caf --- /dev/null +++ b/platform/jn516x/dev/ccm-star.c @@ -0,0 +1,168 @@ +/* + * Copyright (c) 2015, SICS Swedish ICT. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the Institute nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * This file is part of the Contiki operating system. + * + */ + +/** + * \file + * CCM* header implementation exploiting the JN516x + * cryptographic co-processor + * \author + * Simon Duquennoy + */ + +#include "ccm-star.h" +#include +#include + +static tsReg128 current_key; +static int current_key_is_new = 1; + +/*---------------------------------------------------------------------------*/ +static void +mic(const uint8_t *m, uint8_t m_len, + const uint8_t *nonce, + const uint8_t *a, uint8_t a_len, + uint8_t *result, + uint8_t mic_len) +{ + tsReg128 nonce_aligned; + memcpy(&nonce_aligned, nonce, sizeof(nonce_aligned)); + bACI_CCMstar( + ¤t_key, + current_key_is_new, + XCV_REG_AES_SET_MODE_CCM, + mic_len, + a_len, + m_len, + &nonce_aligned, + (uint8_t *)a, + (uint8_t *)m, + NULL, + result, + NULL + ); + current_key_is_new = 0; +} +/*---------------------------------------------------------------------------*/ +static void +ctr(uint8_t *m, uint8_t m_len, const uint8_t *nonce) +{ + tsReg128 nonce_aligned; + memcpy(&nonce_aligned, nonce, sizeof(nonce_aligned)); + bACI_CCMstar( + ¤t_key, + current_key_is_new, + XCV_REG_AES_SET_MODE_CCM, + 0, + 0, + m_len, + &nonce_aligned, + NULL, + m, + m, + NULL, + NULL + ); + current_key_is_new = 0; +} +/*---------------------------------------------------------------------------*/ +static void +aead(const uint8_t *nonce, + uint8_t *m, uint8_t m_len, + const uint8_t *a, uint8_t a_len, + uint8_t *result, uint8_t mic_len, + int forward) +{ + tsReg128 nonce_aligned; + memcpy(&nonce_aligned, nonce, sizeof(nonce_aligned)); + if(forward) { + bACI_CCMstar( + ¤t_key, + current_key_is_new, + XCV_REG_AES_SET_MODE_CCM, + mic_len, + a_len, + m_len, + &nonce_aligned, + (uint8_t *)a, + (uint8_t *)m, + (uint8_t *)m, + result, + NULL + ); + } else { + bool_t auth; + bACI_CCMstar( + ¤t_key, + current_key_is_new, + XCV_REG_AES_SET_MODE_CCM_D, + mic_len, + a_len, + m_len, + &nonce_aligned, + (uint8_t *)a, + (uint8_t *)m, + (uint8_t *)m, + (uint8_t *)a + a_len + m_len, + &auth + ); + /* To comply with the CCM_STAR interface, copy MIC to result in case of success */ + if(result != NULL) { + if(auth) { + memcpy(result, a + a_len + m_len, mic_len); + } else { + /* Otherwise, corrupt the result */ + memcpy(result, a + a_len + m_len, mic_len); + result[0]++; + } + } + } + + current_key_is_new = 0; +} +/*---------------------------------------------------------------------------*/ +static void +set_key(const uint8_t *key) +{ + if(memcmp(¤t_key, key, sizeof(current_key)) == 0) { + current_key_is_new = 0; + } else { + memcpy(¤t_key, key, sizeof(current_key)); + current_key_is_new = 1; + } +} +/*---------------------------------------------------------------------------*/ +const struct ccm_star_driver ccm_star_driver_jn516x = { + mic, + ctr, + set_key +}; +/*---------------------------------------------------------------------------*/ diff --git a/platform/jn516x/dev/clock.c b/platform/jn516x/dev/clock.c new file mode 100644 index 000000000..e2b1d46a3 --- /dev/null +++ b/platform/jn516x/dev/clock.c @@ -0,0 +1,250 @@ +/* + * Copyright (c) 2014, SICS Swedish ICT. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the Institute nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * This file is part of the Contiki operating system. + * + */ + +/** + * \file + * Clock implementation for NXP jn516x. + * \author + * Beshr Al Nahas + * + */ + +#include +#include +#include "contiki.h" +#include "sys/energest.h" +#include "sys/clock.h" +#include "sys/etimer.h" +#include "rtimer-arch.h" +#include "dev/watchdog.h" + +/** + * TickTimer will be used for RTIMER + * E_AHI_TIMER_1 will be used for ticking + **/ + +#define DEBUG 0 +#if DEBUG +#include +#define PRINTF(...) printf(__VA_ARGS__) +#else +#define PRINTF(...) +#endif + +static volatile unsigned long seconds = 0; +static volatile uint8_t ticking = 0; +static volatile clock_time_t clock_ticks = 0; +/* last_tar is used for calculating clock_fine */ + +#define CLOCK_TIMER E_AHI_TIMER_1 +#define CLOCK_TIMER_ISR_DEV E_AHI_DEVICE_TIMER1 +/* 16Mhz / 2^7 = 125Khz */ +#define CLOCK_PRESCALE 7 +/* 10ms tick --> overflow after ~981/2 days */ +#define CLOCK_INTERVAL (125 * 10) +#define MAX_TICKS (CLOCK_INTERVAL) +/*---------------------------------------------------------------------------*/ +void +clockTimerISR(uint32 u32Device, uint32 u32ItemBitmap) +{ + if(u32Device != CLOCK_TIMER_ISR_DEV) { + return; + } + ENERGEST_ON(ENERGEST_TYPE_IRQ); + + watchdog_start(); + + clock_ticks++; + if(clock_ticks % CLOCK_CONF_SECOND == 0) { + ++seconds; + energest_flush(); + } + if(etimer_pending() && (etimer_next_expiration_time() - clock_ticks - 1) > MAX_TICKS) { + etimer_request_poll(); + /* TODO exit low-power mode */ + } + if(process_nevents() >= 0) { + /* TODO exit low-power mode */ + } + + watchdog_stop(); + + ENERGEST_OFF(ENERGEST_TYPE_IRQ); +} +/*---------------------------------------------------------------------------*/ +static void +clock_timer_init(void) +{ + vAHI_TimerEnable(CLOCK_TIMER, CLOCK_PRESCALE, 0, 1, 0); + vAHI_TimerClockSelect(CLOCK_TIMER, 0, 0); + + vAHI_TimerConfigureOutputs(CLOCK_TIMER, 0, 1); + vAHI_TimerDIOControl(CLOCK_TIMER, 0); + +#if (CLOCK_TIMER == E_AHI_TIMER_0) + vAHI_Timer0RegisterCallback(clockTimerISR); +#elif (CLOCK_TIMER == E_AHI_TIMER_1) + vAHI_Timer1RegisterCallback(clockTimerISR); +#endif + clock_ticks = 0; + vAHI_TimerStartRepeat(CLOCK_TIMER, 0, CLOCK_INTERVAL); + ticking = 1; +} +/*---------------------------------------------------------------------------*/ +void +clock_init(void) +{ + /* gMAC_u8MaxBuffers = 2; */ +#ifdef JENNIC_CHIP_FAMILY_JN516x + /* Turn off debugger */ + *(volatile uint32 *)0x020000a0 = 0; +#endif + /* system controller interrupts callback is disabled + * -- Only wake Interrupts -- + */ + vAHI_SysCtrlRegisterCallback(0); + + /* schedule clock tick interrupt */ + clock_timer_init(); + rtimer_init(); + (void)u32AHI_Init(); + + bAHI_SetClockRate(E_AHI_XTAL_32MHZ); + + /* Wait for oscillator to stabilise */ + while(bAHI_GetClkSource() == 1) ; + while(bAHI_Clock32MHzStable() == 0) ; + + vAHI_OptimiseWaitStates(); + + /* Turn on SPI master */ + vREG_SysWrite(REG_SYS_PWR_CTRL, u32REG_SysRead(REG_SYS_PWR_CTRL) + | REG_SYSCTRL_PWRCTRL_SPIMEN_MASK); +} +/*---------------------------------------------------------------------------*/ +clock_time_t +clock_time(void) +{ + clock_time_t t1, t2; + do { + t1 = clock_ticks; + t2 = clock_ticks; + } while(t1 != t2); + return t1; +} +/*---------------------------------------------------------------------------*/ +void +clock_set(clock_time_t clock, clock_time_t fclock) +{ + clock_ticks = clock; +} +/*---------------------------------------------------------------------------*/ +int +clock_fine_max(void) +{ + return CLOCK_INTERVAL; +} +/*---------------------------------------------------------------------------*/ +/** + * Delay the CPU for a multiple of 0.0625 us. + */ +void +clock_delay_usec(uint16_t dt) +{ + volatile uint32_t t = u32AHI_TickTimerRead(); +#define RTIMER_MAX_TICKS 0xffffffff + /* beware of wrapping */ + if(RTIMER_MAX_TICKS - t < dt) { + while(u32AHI_TickTimerRead() < RTIMER_MAX_TICKS && u32AHI_TickTimerRead() != 0) ; + dt -= RTIMER_MAX_TICKS - t; + t = 0; + } + while(u32AHI_TickTimerRead() - t < dt) { + watchdog_periodic(); + } +} +/*---------------------------------------------------------------------------*/ +/** + * Delay the CPU for a multiple of 8 us. + */ +void +clock_delay(unsigned int i) +{ + volatile uint32_t t = u16AHI_TimerReadCount(CLOCK_TIMER); + /* beware of wrapping */ + if(MAX_TICKS - t < i) { + while(u16AHI_TimerReadCount(CLOCK_TIMER) < MAX_TICKS && u16AHI_TimerReadCount(CLOCK_TIMER) != 0) ; + i -= MAX_TICKS - t; + t = 0; + } + while(u16AHI_TimerReadCount(CLOCK_TIMER) - t < i) { + watchdog_periodic(); + } +} +/*---------------------------------------------------------------------------*/ +/** + * Wait for a multiple of 10 ms. + * + */ +void +clock_wait(clock_time_t t) +{ + clock_time_t start; + + start = clock_time(); + while(clock_time() - start < (clock_time_t)t) { + watchdog_periodic(); + } +} +/*---------------------------------------------------------------------------*/ +void +clock_set_seconds(unsigned long sec) +{ + seconds = sec; +} +/*---------------------------------------------------------------------------*/ +unsigned long +clock_seconds(void) +{ + unsigned long t1, t2; + do { + t1 = seconds; + t2 = seconds; + } while(t1 != t2); + return t1; +} +/*---------------------------------------------------------------------------*/ +rtimer_clock_t +clock_counter(void) +{ + return rtimer_arch_now(); +} diff --git a/platform/jn516x/dev/dongle/README.md b/platform/jn516x/dev/dongle/README.md new file mode 100644 index 000000000..a9b6e9cb2 --- /dev/null +++ b/platform/jn516x/dev/dongle/README.md @@ -0,0 +1,9 @@ +This directory contains the contiki driver for the LED driver for the dongle. + +Mapping of LEDs on JN516x Dongle: + leds.h led on dongle: + LEDS_RED Red LED + LEDS_GREEN Green LED +Note: Only one LED can be switch on at the same time + + diff --git a/platform/jn516x/dev/dongle/leds-arch.c b/platform/jn516x/dev/dongle/leds-arch.c new file mode 100644 index 000000000..5eff3c63e --- /dev/null +++ b/platform/jn516x/dev/dongle/leds-arch.c @@ -0,0 +1,80 @@ +/* + * Copyright (c) 2015 NXP B.V. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of NXP B.V. nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY NXP B.V. AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL NXP B.V. OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * This file is part of the Contiki operating system. + * + * Author: Theo van Daele + * + */ +#include "contiki.h" +#include "leds.h" +#include + +#define LED_G (1 << 16) +#define LED_R (1 << 17) + +static volatile uint8_t leds; + +/*---------------------------------------------------------------------------*/ +void +leds_arch_init(void) +{ + vAHI_DioSetDirection(0, LED_R | LED_G); + vAHI_DioSetOutput(0, LED_R | LED_G); /* Default off */ + leds = 0; +} +/*---------------------------------------------------------------------------*/ +unsigned char +leds_arch_get(void) +{ + return leds; +} +/*---------------------------------------------------------------------------*/ +void +leds_arch_set(unsigned char c) +{ + uint32 on_mask = 0; + uint32 off_mask = 0; + + if(c & LEDS_GREEN) { + on_mask |= LED_G; + } else { + off_mask |= LED_G; + } if(c & LEDS_RED) { + on_mask |= LED_R; + } else { + off_mask |= LED_R; + } vAHI_DioSetOutput(on_mask, off_mask); + /* Both LEDs can not be switched on at the same time. + Will result in both leds being OFF */ + if(on_mask == (LED_R | LED_G)) { + leds = 0; + } else { + leds = c; + } +} diff --git a/platform/jn516x/dev/dr1174/README.md b/platform/jn516x/dev/dr1174/README.md new file mode 100644 index 000000000..d3a21cbe0 --- /dev/null +++ b/platform/jn516x/dev/dr1174/README.md @@ -0,0 +1,8 @@ +This directory contains the contiki driver for the button sensor on the DR1174 baseboard. +When used with an extention board, sensors from the dr1175 anf dr1179 directories are used in addition to this. +leds-arch.c implements the led driver for leds D3 and D6 on the board. +Mapping of LEDs on JN516x DR1174: + leds.h: led on DR1174: + LEDS_GP0 LED D3 + LEDS_GP1 LED D6 +Note: LEDS_GPx definitions included in leds.h via platform-conf.h diff --git a/platform/jn516x/dev/dr1174/button-sensor.c b/platform/jn516x/dev/dr1174/button-sensor.c new file mode 100644 index 000000000..9262a6ef8 --- /dev/null +++ b/platform/jn516x/dev/dr1174/button-sensor.c @@ -0,0 +1,241 @@ +/* + * Copyright (c) 2015 NXP B.V. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of NXP B.V. nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY NXP B.V. AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL NXP B.V. OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * This file is part of the Contiki operating system. + * + * Author: Theo van Daele + * + */ +#include "contiki.h" +#include "sys/etimer.h" +#include "lib/sensors.h" +#include "button-sensor.h" +#include + +/*---------------------------------------------------------------------------*/ +/* LOCAL DEFINITIONS */ +/*---------------------------------------------------------------------------*/ +/* #define DEBUG */ +#ifdef DEBUG +#include +#define PRINTF(...) printf(__VA_ARGS__) +#else +#define PRINTF(...) +#endif + +typedef enum { + APP_E_BUTTON_SW0 = 0, +#if SENSOR_BOARD_DR1199 + APP_E_BUTTON_SW1, + APP_E_BUTTON_SW2, + APP_E_BUTTON_SW3, + APP_E_BUTTON_SW4, +#endif /* SENSOR_BOARD_DR1199 */ + APP_E_BUTTON_NUM /* Number of buttons */ +} app_e_button_t; + +/* Mapping of DIO port connections to buttons. Use as mask to get button value */ +#define APP_PORT_BUTTON_SW0 (8) +#if SENSOR_BOARD_DR1199 +#define APP_PORT_BUTTON_SW1 (11) +#define APP_PORT_BUTTON_SW2 (12) +#define APP_PORT_BUTTON_SW3 (17) +#define APP_PORT_BUTTON_SW4 (1) +#endif /* SENSOR_BOARD_DR1199 */ + +/* Definition of port masks based on button mapping */ +#if SENSOR_BOARD_DR1199 +#define APP_BUTTONS_DIO_MASK ((1 << APP_PORT_BUTTON_SW0) | \ + (1 << APP_PORT_BUTTON_SW1) | \ + (1 << APP_PORT_BUTTON_SW2) | \ + (1 << APP_PORT_BUTTON_SW3) | \ + (1 << APP_PORT_BUTTON_SW4)) +#else /* SENSOR_BOARD_DR1199 */ +#define APP_BUTTONS_DIO_MASK (1 << APP_PORT_BUTTON_SW0) +#endif /* SENSOR_BOARD_DR1199 */ + +#define KEY_SAMPLE_TIME (CLOCK_SECOND / 20) + +typedef enum { + BUTTONS_STATUS_NOT_INIT = 0, + BUTTONS_STATUS_INIT, + BUTTONS_STATUS_NOT_ACTIVE = BUTTONS_STATUS_INIT, + BUTTONS_STATUS_ACTIVE +} buttons_status_t; + +/*---------------------------------------------------------------------------*/ +/* LOCAL DATA DEFINITIONS */ +/*---------------------------------------------------------------------------*/ +const struct sensors_sensor button_sensor; +volatile static buttons_status_t buttons_status = BUTTONS_STATUS_NOT_INIT; +static int key_value = 0; +static uint8 key_map[] = { APP_PORT_BUTTON_SW0, /* APP_E_BUTTON_SW0 */ +#if SENSOR_BOARD_DR1199 + APP_PORT_BUTTON_SW1, /* APP_E_BUTTON_SW1 */ + APP_PORT_BUTTON_SW2, /* APP_E_BUTTON_SW2 */ + APP_PORT_BUTTON_SW3, /* APP_E_BUTTON_SW3 */ + APP_PORT_BUTTON_SW4 /* APP_E_BUTTON_SW4 */ +#endif /* SENSOR_BOARD_DR1199 */ +}; + +/*---------------------------------------------------------------------------*/ +/* LOCAL FUNCTION PROTOTYPES */ +/*---------------------------------------------------------------------------*/ +PROCESS(key_sampling, "Key sample"); +static int get_key_value(void); + +/*---------------------------------------------------------------------------*/ +/* PUBLIC FUNCTIONS */ +/*---------------------------------------------------------------------------*/ +static int +configure(int type, int value) +{ + if(type == SENSORS_HW_INIT) { + /* Called from sensor thread when started. + Configure DIO lines with buttons connected as input */ + vAHI_DioSetDirection(APP_BUTTONS_DIO_MASK, 0); + /* Turn on pull-ups for DIO lines with buttons connected */ + vAHI_DioSetPullup(APP_BUTTONS_DIO_MASK, 0); + PRINTF("HW_INIT BUTTONS (0x%x)\n", APP_BUTTONS_DIO_MASK); + /* Configure debounce timer. Do not run it yet. */ + buttons_status = BUTTONS_STATUS_INIT; + process_start(&key_sampling, NULL); + return 1; + } else if(type == SENSORS_ACTIVE) { + if(buttons_status != BUTTONS_STATUS_NOT_INIT) { + if(value) { + /* Button sensor activated */ + PRINTF("BUTTONS ACTIVATED\n"); + buttons_status = BUTTONS_STATUS_ACTIVE; + } else { + /* Button sensor de-activated */ + PRINTF("BUTTONS DE-ACTIVATED\n"); + buttons_status = BUTTONS_STATUS_NOT_ACTIVE; + } + process_post(&key_sampling, PROCESS_EVENT_MSG, (void *)&buttons_status); + return 1; + } else { + /* Buttons must be intialised before being (de)-activated */ + PRINTF("ERROR: NO HW_INIT BUTTONS\n"); + return 0; + } + } else { + /* Non valid type */ + return 0; + } +} +/*---------------------------------------------------------------------------*/ +static int +status(int type) +{ + if(type == SENSORS_ACTIVE) { + return buttons_status == BUTTONS_STATUS_ACTIVE; + } else if(type == SENSORS_READY) { + return buttons_status != BUTTONS_STATUS_NOT_INIT; + } + return 0; +} +/*---------------------------------------------------------------------------*/ +static int +value(int type) +{ + /* type: Not defined for the buttons interface + */ + return key_value; +} +/*---------------------------------------------------------------------------*/ +/* LOCAL FUNCTIONS */ +/*---------------------------------------------------------------------------*/ +static int +get_key_value(void) +{ + /* Function returns the actual key value. Pressed key will return '1' */ + int io_value = ~u32AHI_DioReadInput() & APP_BUTTONS_DIO_MASK; + int k = 0; + int key = 0; + + while(k < APP_E_BUTTON_NUM) { + if(io_value & (1 << key_map[k])) { + key |= (1 << k); + } + k++; + } + return key; +} +/* Process takes care of detecting key changes */ +/*---------------------------------------------------------------------------*/ +PROCESS_THREAD(key_sampling, ev, data) +{ + PROCESS_BEGIN(); + static struct etimer et; + static int previous_key_value = 0; + static char debounce_check = 0; + int current_key_value; + + etimer_set(&et, CLOCK_SECOND / 50); + while(1) { + PROCESS_WAIT_EVENT_UNTIL((ev == PROCESS_EVENT_TIMER) || (ev == PROCESS_EVENT_MSG)); + if(ev == PROCESS_EVENT_TIMER) { + /* Handle sensor reading. */ + PRINTF("Key sample\n"); + current_key_value = get_key_value(); + if(debounce_check != 0) { + /* Check if key remained constant */ + if(previous_key_value == current_key_value) { + sensors_changed(&button_sensor); + key_value = current_key_value; + debounce_check = 0; + } else { + /* Bouncing */ + previous_key_value = current_key_value; + } + } else + /* Check for new key change */ + if(current_key_value != previous_key_value) { + previous_key_value = current_key_value; + debounce_check = 1; + } + etimer_reset(&et); + } else { + /* ev == PROCESS_EVENT_MSG */ + if(*(buttons_status_t *)data == BUTTONS_STATUS_NOT_ACTIVE) { + /* Stop sampling */ + etimer_stop(&et); + } else if((*(buttons_status_t *)data == BUTTONS_STATUS_ACTIVE)) { + /* restart sampling */ + etimer_restart(&et); + } + } + } + PROCESS_END(); +} + +/*---------------------------------------------------------------------------*/ +/* Sensor defintion for sensor module */ +SENSORS_SENSOR(button_sensor, BUTTON_SENSOR, value, configure, status); +/*---------------------------------------------------------------------------*/ diff --git a/platform/jn516x/dev/dr1174/button-sensor.h b/platform/jn516x/dev/dr1174/button-sensor.h new file mode 100644 index 000000000..eaa87a751 --- /dev/null +++ b/platform/jn516x/dev/dr1174/button-sensor.h @@ -0,0 +1,41 @@ +/* + * Copyright (c) 2015, SICS Swedish ICT. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the Institute nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * This file is part of the Contiki operating system. + * + */ +#ifndef __BUTTON_SENSOR_H__ +#define __BUTTON_SENSOR_H__ + +#include "lib/sensors.h" + +extern const struct sensors_sensor button_sensor; + +#define BUTTON_SENSOR "Button" + +#endif /* __BUTTON_SENSOR_H__ */ diff --git a/platform/jn516x/dev/dr1174/leds-arch.c b/platform/jn516x/dev/dr1174/leds-arch.c new file mode 100644 index 000000000..4e49e9c53 --- /dev/null +++ b/platform/jn516x/dev/dr1174/leds-arch.c @@ -0,0 +1,121 @@ +/* + * Copyright (c) 2015 NXP B.V. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of NXP B.V. nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY NXP B.V. AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL NXP B.V. OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * This file is part of the Contiki operating system. + * + * Author: Theo van Daele + * + */ +#include "contiki.h" +#include "dev/leds.h" +#include +#ifdef SENSOR_BOARD_DR1199 +#include "dr1199/leds-arch-1199.h" +#endif +#ifdef SENSOR_BOARD_DR1175 +#include "leds-extension.h" +#include "dr1175/leds-arch-1175.h" +#endif + +#define LED_D3 (1 << 3) +#define LED_D6 (1 << 2) + +static volatile unsigned char leds; + +/*---------------------------------------------------------------------------*/ +void +leds_arch_init(void) +{ + vAHI_DioSetDirection(0, LED_D3 | LED_D6); + vAHI_DioSetOutput(LED_D3 | LED_D6, 0); /* Default off */ +#ifdef SENSOR_BOARD_DR1199 + leds_arch_init_1199(); +#endif +#ifdef SENSOR_BOARD_DR1175 + leds_arch_init_1175(); +#endif + leds = 0; +} +/*---------------------------------------------------------------------------*/ +unsigned char +leds_arch_get(void) +{ + return leds; +} +/*---------------------------------------------------------------------------*/ +void +leds_arch_set(unsigned char c) +{ + uint32 on_mask = 0; + uint32 off_mask = 0; + + /* LOW level on pins switches ON LED for DR1174 */ + if(c & LEDS_GP0) { + on_mask |= LED_D3; + } else { + off_mask |= LED_D3; + } if(c & LEDS_GP1) { + on_mask |= LED_D6; + } else { + off_mask |= LED_D6; + } vAHI_DioSetOutput(off_mask, on_mask); +#ifdef SENSOR_BOARD_DR1199 + /* DR1174 with DR1199 */ + leds_arch_set_1199(c); + if(c == LEDS_ALL) { + leds = LEDS_GP0 | LEDS_GP1 | LEDS_RED | LEDS_BLUE | LEDS_GREEN; + } else { + leds = (c & (LEDS_GP0 | LEDS_GP1 | LEDS_RED | LEDS_BLUE | LEDS_GREEN)); + } +#elif SENSOR_BOARD_DR1175 + /* DR1174 with DR1175 */ + leds_arch_set_1175(c); + if(c == LEDS_ALL) { + leds = LEDS_GP0 | LEDS_GP1 | LEDS_RED | LEDS_BLUE | LEDS_GREEN | LEDS_WHITE; + } else { + leds = (c & (LEDS_GP0 | LEDS_GP1 | LEDS_RED | LEDS_BLUE | LEDS_GREEN | LEDS_WHITE)); +/* printf("++++++++++++++++++++ leds_arch_set: leds: 0x%x\n", leds); */ + } +#else + /* DR1174-only */ + if(c == LEDS_ALL) { + leds = LEDS_GP0 | LEDS_GP1; + } else { + leds = c; + } +#endif +} +/*---------------------------------------------------------------------------*/ +void +leds_arch_set_level(unsigned char level, unsigned char c) +{ +#ifdef SENSOR_BOARD_DR1175 + leds_arch_set_level_1175(level, c, leds); +/* printf("++++++++++++++++++++ leds_arch_set_level: leds: 0x%x\n", leds); */ +#endif +} diff --git a/platform/jn516x/dev/dr1175/README.md b/platform/jn516x/dev/dr1175/README.md new file mode 100644 index 000000000..232e34768 --- /dev/null +++ b/platform/jn516x/dev/dr1175/README.md @@ -0,0 +1,18 @@ +This directory contains the contiki driver for the sensors (light, humidity and temperature sensor) available on the +NXP DR1175 board. This board is part of the NXP JN516X Evaluation Kit (see http://www.nxp.com/documents/leaflet/75017368.pdf). + +The dr1175 sensor code interfaces to the contiki `core/lib/sensors.c` framework. +The code is specificaly for the JN516X platform, because it makes use of the platform\DK4 libraries +of this JN516X SDK. +`examples/jn516x/rpl/coap-dr1175-node.c` shows an example on using this contiki driver. + +Mapping of LEDs on JN516x DR1175/DR1174: + leds.h: led on DR1175/DR1174: +DR1174+DR1175: + LEDS_RED Red led in RGB-led with level control on DR1175 + LEDS_GREEN Green led in RGB-led with level control on DR1175 + LEDS_BLUE Blue led in RGB-led with level control on DR1175 + LEDS_WHITE White power led with level control on DR1175 + LEDS_GP0 LEDS D3 on DR1174 + LEDS_GP1 LEDS D6 on DR1174 +Note: LEDS_GPx and LEDS_WHITE definitions included in leds.h via platform-conf.h diff --git a/platform/jn516x/dev/dr1175/ht-sensor.c b/platform/jn516x/dev/dr1175/ht-sensor.c new file mode 100644 index 000000000..76f889d84 --- /dev/null +++ b/platform/jn516x/dev/dr1175/ht-sensor.c @@ -0,0 +1,187 @@ +/* + * Copyright (c) 2015 NXP B.V. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of NXP B.V. nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY NXP B.V. AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL NXP B.V. OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * This file is part of the Contiki operating system. + * + * Author: Theo van Daele + * + */ +#include "contiki.h" +#include "sys/etimer.h" +#include "lib/sensors.h" +#include "ht-sensor.h" +#include +#include + +/*---------------------------------------------------------------------------*/ +/* LOCAL DEFINITIONS */ +/*---------------------------------------------------------------------------*/ +/* #define DEBUG */ +#ifdef DEBUG +#include +#define PRINTF(...) printf(__VA_ARGS__) +#else +#define PRINTF(...) +#endif + +typedef enum { + HT_SENSOR_STATUS_NOT_INIT = 0, + HT_SENSOR_STATUS_INIT, + HT_SENSOR_STATUS_NOT_ACTIVE = HT_SENSOR_STATUS_INIT, + HT_SENSOR_STATUS_ACTIVE +} ht_sensor_status_t; + +/* Absolute delta in light or humidity level needed to generate event */ +#define DELTA_TEMP_SENSOR_VALUE 1 +#define DELTA_HUM_SENSOR_VALUE 1 + +/*---------------------------------------------------------------------------*/ +/* LOCAL DATA DEFINITIONS */ +/*---------------------------------------------------------------------------*/ +const struct sensors_sensor ht_sensor; +volatile static ht_sensor_status_t ht_sensor_status = HT_SENSOR_STATUS_NOT_INIT; +static int prev_temp_event_val = 0; +static int prev_hum_event_val = 0; +static int temp_sensor_value = 0; +static int hum_sensor_value = 0; + +/*---------------------------------------------------------------------------*/ +/* LOCAL FUNCTION PROTOTYPES */ +/*---------------------------------------------------------------------------*/ +PROCESS(HTSensorSampling, "Humidity/Temperature sensor"); + +/*---------------------------------------------------------------------------*/ +/* PUBLIC FUNCTIONS */ +/*---------------------------------------------------------------------------*/ +static int +configure(int type, int value) +{ + if(type == SENSORS_HW_INIT) { + PRINTF("SENSORS_HW_INIT\n"); + ht_sensor_status = HT_SENSOR_STATUS_INIT; + process_start(&HTSensorSampling, NULL); + return 1; + } else if(type == SENSORS_ACTIVE) { + if(ht_sensor_status != HT_SENSOR_STATUS_NOT_INIT) { + if(value) { + /* ACTIVATE SENSOR */ + vHTSreset(); + prev_temp_event_val = 0; + prev_hum_event_val = 0; + /* Activate ht sensor. Start sampling */ + PRINTF("HT SENSOR ACTIVATED\n"); + ht_sensor_status = HT_SENSOR_STATUS_ACTIVE; + process_post(&HTSensorSampling, PROCESS_EVENT_MSG, (void *)&ht_sensor_status); + } else { + /* DE-ACTIVATE SENSOR */ + PRINTF("HT SENSOR DE-ACTIVATED\n"); + ht_sensor_status = HT_SENSOR_STATUS_NOT_ACTIVE; + process_post(&HTSensorSampling, PROCESS_EVENT_MSG, (void *)&ht_sensor_status); + } + return 1; + } else { + /* HT sensor must be intialised before being (de)-activated */ + PRINTF("ERROR: NO HW_INIT HT SENSOR\n"); + return 0; + } + } else { + /* Non valid type */ + return 0; + } +} +/*---------------------------------------------------------------------------*/ +static int +status(int type) +{ + if(type == SENSORS_ACTIVE) { + return ht_sensor_status == HT_SENSOR_STATUS_ACTIVE; + } else if(type == SENSORS_READY) { + return ht_sensor_status != HT_SENSOR_STATUS_NOT_INIT; + } + return 0; +} +/*---------------------------------------------------------------------------*/ +static int +value(int type) +{ + /* type: HT_SENSOR_TEMP is to return temperature + !=HT_SENSOR_TEMP is to return humidity */ + if(type == HT_SENSOR_TEMP) { + return temp_sensor_value; + } else { + return hum_sensor_value; + } +} +/*---------------------------------------------------------------------------*/ +/* LOCAL FUNCTIONS */ +/*---------------------------------------------------------------------------*/ +/* Process to get ht sensor value. + ht sensor is sampled. Sampling stopped when sensor is de-activated. + Event is generated if temp and/or hum value changed at least the value DELTA_TEMP_SENSOR_VALUE + or DELTA_HUM_SENSOR_VALUE since last event. */ +PROCESS_THREAD(HTSensorSampling, ev, data) +{ + PROCESS_BEGIN(); + static struct etimer et; + + etimer_set(&et, CLOCK_SECOND); + while(1) { + PROCESS_WAIT_EVENT_UNTIL((ev == PROCESS_EVENT_TIMER) || (ev == PROCESS_EVENT_MSG)); + if(ev == PROCESS_EVENT_TIMER) { + /* Handle sensor reading. */ + vHTSstartReadTemp(); + temp_sensor_value = u16HTSreadTempResult(); + PRINTF("Temperature sample: %d\n", temp_sensor_value); + vHTSstartReadHumidity(); + hum_sensor_value = u16HTSreadHumidityResult(); + PRINTF("Humidity sample: %d\n", hum_sensor_value); + if((abs(temp_sensor_value - prev_temp_event_val) > DELTA_TEMP_SENSOR_VALUE) || + (abs(hum_sensor_value - prev_hum_event_val) > DELTA_HUM_SENSOR_VALUE)) { + prev_temp_event_val = temp_sensor_value; + prev_hum_event_val = hum_sensor_value; + sensors_changed(&ht_sensor); + } + etimer_reset(&et); + } else { + /* ev == PROCESS_EVENT_MSG */ + if(*(int *)data == HT_SENSOR_STATUS_NOT_ACTIVE) { + /* Stop sampling */ + etimer_stop(&et); + } else if((*(int *)data == HT_SENSOR_STATUS_ACTIVE)) { + /* restart sampling */ + etimer_restart(&et); + } + } + } + PROCESS_END(); +} + +/*---------------------------------------------------------------------------*/ +/* Sensor defintion for sensor module */ +SENSORS_SENSOR(ht_sensor, HT_SENSOR, value, configure, status); +/*---------------------------------------------------------------------------*/ diff --git a/platform/jn516x/dev/dr1175/ht-sensor.h b/platform/jn516x/dev/dr1175/ht-sensor.h new file mode 100644 index 000000000..43fb8b63a --- /dev/null +++ b/platform/jn516x/dev/dr1175/ht-sensor.h @@ -0,0 +1,46 @@ +/* + * Copyright (c) 2015 NXP B.V. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of NXP B.V. nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY NXP B.V. AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL NXP B.V. OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * This file is part of the Contiki operating system. + * + * Author: Theo van Daele + * + */ +#ifndef __HT_SENSOR_H__ +#define __HT_SENSOR_H__ + +#include "lib/sensors.h" + +extern const struct sensors_sensor ht_sensor; + +#define HT_SENSOR "TH" + +#define HT_SENSOR_TEMP 0 +#define HT_SENSOR_HUM 1 + +#endif /* __HT_SENSOR_H__ */ diff --git a/platform/jn516x/dev/dr1175/leds-arch-1175.c b/platform/jn516x/dev/dr1175/leds-arch-1175.c new file mode 100644 index 000000000..c1adeb2fb --- /dev/null +++ b/platform/jn516x/dev/dr1175/leds-arch-1175.c @@ -0,0 +1,91 @@ +/* + * Copyright (c) 2015 NXP B.V. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of NXP B.V. nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY NXP B.V. AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL NXP B.V. OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * This file is part of the Contiki operating system. + * + * Author: Theo van Daele + * + */ +#include "contiki.h" +#include "dev/leds.h" +#include + +static uint8_t white_level; +static uint8_t red_level; +static uint8_t green_level; +static uint8_t blue_level; + +/*---------------------------------------------------------------------------*/ +void +leds_arch_init_1175(void) +{ + /* White LED initialisation */ + white_level = 0; + bWhite_LED_Enable(); + bWhite_LED_SetLevel(0); + bWhite_LED_On(); + /* Coloured LED initialisation */ + red_level = 0; + green_level = 0; + blue_level = 0; + bRGB_LED_Enable(); + bRGB_LED_SetGroupLevel(255); + bRGB_LED_SetLevel(0, 0, 0); + bRGB_LED_On(); +} +/*---------------------------------------------------------------------------*/ +void +leds_arch_set_1175(unsigned char c) +{ + bWhite_LED_SetLevel(c & LEDS_WHITE ? white_level : 0); + bRGB_LED_SetLevel(c & LEDS_RED ? red_level : 0, + c & LEDS_GREEN ? green_level : 0, + c & LEDS_BLUE ? blue_level : 0); +} +/*---------------------------------------------------------------------------*/ +void +leds_arch_set_level_1175(unsigned char level, unsigned char c, unsigned char leds) +{ + if(c & LEDS_WHITE) { + white_level = level; + } + if(c & LEDS_RED) { + red_level = level; + } + if(c & LEDS_GREEN) { + green_level = level; + } + if(c & LEDS_BLUE) { + blue_level = level; + /* Activate level if LED is on */ + } + bRGB_LED_SetLevel(leds & LEDS_RED ? red_level : 0, + leds & LEDS_GREEN ? green_level : 0, + leds & LEDS_BLUE ? blue_level : 0); + bWhite_LED_SetLevel(leds & LEDS_WHITE ? white_level : 0); +} \ No newline at end of file diff --git a/platform/jn516x/dev/dr1175/leds-arch-1175.h b/platform/jn516x/dev/dr1175/leds-arch-1175.h new file mode 100644 index 000000000..7611bc51d --- /dev/null +++ b/platform/jn516x/dev/dr1175/leds-arch-1175.h @@ -0,0 +1,36 @@ +/* + * Copyright (c) 2015 NXP B.V. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of NXP B.V. nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY NXP B.V. AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL NXP B.V. OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * This file is part of the Contiki operating system. + * + * Author: Theo van Daele + * + */ +void leds_arch_init_1175(void); +void leds_arch_set_1175(unsigned char c); +void leds_arch_set_level_1175(unsigned char level, unsigned char c, unsigned char leds); diff --git a/platform/jn516x/dev/dr1175/light-sensor.c b/platform/jn516x/dev/dr1175/light-sensor.c new file mode 100644 index 000000000..6a25b2af4 --- /dev/null +++ b/platform/jn516x/dev/dr1175/light-sensor.c @@ -0,0 +1,198 @@ +/* + * Copyright (c) 2015 NXP B.V. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of NXP B.V. nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY NXP B.V. AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL NXP B.V. OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * This file is part of the Contiki operating system. + * + * Author: Theo van Daele + * + */ +#include "contiki.h" +#include "sys/etimer.h" +#include "lib/sensors.h" +#include "light-sensor.h" +#include +#include +#include + +/*---------------------------------------------------------------------------*/ +/* LOCAL DEFINITIONS */ +/*---------------------------------------------------------------------------*/ +/* #define DEBUG */ +#ifdef DEBUG +#include +#define PRINTF(...) printf(__VA_ARGS__) +#else +#define PRINTF(...) +#endif + +typedef enum { + LIGHT_SENSOR_STATUS_NOT_INIT = 0, + LIGHT_SENSOR_STATUS_INIT, + LIGHT_SENSOR_STATUS_NOT_ACTIVE = LIGHT_SENSOR_STATUS_INIT, + LIGHT_SENSOR_STATUS_ACTIVE +} light_sensor_status_t; + +/* Absolute delta in light level needed to generate event */ +#define DELTA_LIGHT_SENSOR_VALUE 1 + +/*---------------------------------------------------------------------------*/ +/* LOCAL DATA DEFINITIONS */ +/*---------------------------------------------------------------------------*/ +const struct sensors_sensor light_sensor; +volatile static light_sensor_status_t light_sensor_status = LIGHT_SENSOR_STATUS_NOT_INIT; +static int prev_light_event_val = 0; +static int light_sensor_value = 0; + +/*---------------------------------------------------------------------------*/ +/* LOCAL FUNCTION PROTOTYPES */ +/*---------------------------------------------------------------------------*/ +static int adjust(int input1, int input2); +PROCESS(LightSensorSampling, "Light sensor"); + +/*---------------------------------------------------------------------------*/ +/* PUBLIC FUNCTIONS */ +/*---------------------------------------------------------------------------*/ +static int +configure(int type, int value) +{ + if(type == SENSORS_HW_INIT) { + PRINTF("SENSORS_HW_INIT\n"); + light_sensor_status = LIGHT_SENSOR_STATUS_INIT; + process_start(&LightSensorSampling, NULL); + return 1; + } else if(type == SENSORS_ACTIVE) { + if(light_sensor_status != LIGHT_SENSOR_STATUS_NOT_INIT) { + if(value) { + /* ACTIVATE SENSOR */ + vALSreset(); + prev_light_event_val = 0; + /* Activate light sensor. Use channel 0. (Channel 1 = IR). Start sampling */ + PRINTF("LIGHT SENSOR ACTIVATED\n"); + light_sensor_status = LIGHT_SENSOR_STATUS_ACTIVE; + process_post(&LightSensorSampling, PROCESS_EVENT_MSG, (void *)&light_sensor_status); + } else { + /* DE-ACTIVATE SENSOR */ + vALSpowerDown(); + PRINTF("LIGHT SENSOR DE-ACTIVATED\n"); + light_sensor_status = LIGHT_SENSOR_STATUS_NOT_ACTIVE; + process_post(&LightSensorSampling, PROCESS_EVENT_MSG, (void *)&light_sensor_status); + } + return 1; + } else { + /* Light sensor must be intialised before being (de)-activated */ + PRINTF("ERROR: NO HW_INIT LIGHT SENSOR\n"); + return 0; + } + } else { + /* Non valid type */ + return 0; + } +} +/*---------------------------------------------------------------------------*/ +static int +status(int type) +{ + if(type == SENSORS_ACTIVE) { + return light_sensor_status == LIGHT_SENSOR_STATUS_ACTIVE; + } else if(type == SENSORS_READY) { + return light_sensor_status != LIGHT_SENSOR_STATUS_NOT_INIT; + } + return 0; +} +/*---------------------------------------------------------------------------*/ +static int +value(int type) +{ + /* type: Not defined for the light sensor interface */ + return light_sensor_value; +} +/*---------------------------------------------------------------------------*/ +/* LOCAL FUNCTIONS */ +/*---------------------------------------------------------------------------*/ +/* Process to get light sensor value. + Light sensor is sampled. Sampling stopped when sensor is de-activated. + Event is generated if light value changed at least the value DELTA_LIGHT_SENSOR_VALUE + since last event. */ +PROCESS_THREAD(LightSensorSampling, ev, data) +{ + PROCESS_BEGIN(); + static struct etimer et; + int channel0_value, channel1_value; + + etimer_set(&et, CLOCK_SECOND / 10); + while(1) { + PROCESS_WAIT_EVENT_UNTIL((ev == PROCESS_EVENT_TIMER) || (ev == PROCESS_EVENT_MSG)); + if(ev == PROCESS_EVENT_TIMER) { + /* Handle sensor reading. */ + PRINTF("Light sensor sample\n"); + vALSstartReadChannel(0); + channel0_value = u16ALSreadChannelResult(); + PRINTF("Channel 0 = %d\n", channel0_value); + vALSstartReadChannel(1); + channel1_value = u16ALSreadChannelResult(); + PRINTF("Channel 1 = %d\n", channel1_value); + light_sensor_value = adjust(channel0_value, channel1_value); + PRINTF("Light output = %d\n", light_sensor_value); + if(abs(light_sensor_value - prev_light_event_val) > DELTA_LIGHT_SENSOR_VALUE) { + prev_light_event_val = light_sensor_value; + sensors_changed(&light_sensor); + } + etimer_reset(&et); + } else { + /* ev == PROCESS_EVENT_MSG */ + if(*(int *)data == LIGHT_SENSOR_STATUS_NOT_ACTIVE) { + /* Stop sampling */ + etimer_stop(&et); + } else if((*(int *)data == LIGHT_SENSOR_STATUS_ACTIVE)) { + /* restart sampling */ + etimer_restart(&et); + } + } + } + PROCESS_END(); +} + +/*---------------------------------------------------------------------------*/ +/* Sensor defintion for sensor module */ +SENSORS_SENSOR(light_sensor, LIGHT_SENSOR, value, configure, status); +/*---------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------*/ +/* adjust() converts the 2 measured light level into 1 ambient light level. */ +/* See manual JN-RM-2003.pdf */ +/* Approximation is used: output[Lux] = 0.39*(ch0-ch1) */ +/*---------------------------------------------------------------------------*/ +static int +adjust(int ch0, int ch1) +{ + if(ch0 > ch1) { + return (39 * (ch0 - ch1)) / 100; + } else { + return 0; + } +} diff --git a/platform/jn516x/dev/dr1175/light-sensor.h b/platform/jn516x/dev/dr1175/light-sensor.h new file mode 100644 index 000000000..49f9d9bbd --- /dev/null +++ b/platform/jn516x/dev/dr1175/light-sensor.h @@ -0,0 +1,43 @@ +/* + * Copyright (c) 2015 NXP B.V. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of NXP B.V. nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY NXP B.V. AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL NXP B.V. OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * This file is part of the Contiki operating system. + * + * Author: Theo van Daele + * + */ +#ifndef __LIGHT_SENSOR_H__ +#define __LIGHT_SENSOR_H__ + +#include "lib/sensors.h" + +extern const struct sensors_sensor light_sensor; + +#define LIGHT_SENSOR "Light" + +#endif /* __LIGHT_SENSOR_H__ */ diff --git a/platform/jn516x/dev/dr1199/README.md b/platform/jn516x/dev/dr1199/README.md new file mode 100644 index 000000000..f70d7558c --- /dev/null +++ b/platform/jn516x/dev/dr1199/README.md @@ -0,0 +1,19 @@ +This directory contains the contiki driver for the sensor (potentiometer) available on the +NXP DR1199 board. This board is part of the NXP JN516x Evaluation Kit (see http://www.nxp.com/documents/leaflet/75017368.pdf). +The driver for the switches on the DR1199 are supported by `dev/dr1174` when compiled with the flag `SENSOR_BOARD_DR1199` set. + +The dr1199 sensor code interfaces to contiki `core/lib/sensors.c` framework. +The code is specificaly for the JN516X platform, because it makes use of the platform\DK4 libraries +of this JN516X SDK. +`examples/jn516x/rpl/coap-dr1199-node.c` shows an example on using this contiki driver. +leds-arch.c implements the led driver for leds D3 and D6 on the DR1174 base-board and the DR1199 board. +Mapping of LEDs on JN516x DR1199/DR1174: + leds.h: led on DR1174: +DR1174+DR1199: + leds.h physical leds + LEDS_GREEN LED D1 on DR1199 + LEDS_BLUE LED D2 on DR1199 + LEDS_RED LED D3 on DR1199 + LEDS_GP0 LED D3 on DR1174 + LEDS_GP1 LED D6 on DR1174 +Note: LEDS_GPx definitions included in leds.h via platform-conf.h diff --git a/platform/jn516x/dev/dr1199/leds-arch-1199.c b/platform/jn516x/dev/dr1199/leds-arch-1199.c new file mode 100644 index 000000000..c6dc1c3ba --- /dev/null +++ b/platform/jn516x/dev/dr1199/leds-arch-1199.c @@ -0,0 +1,51 @@ +/* + * Copyright (c) 2015 NXP B.V. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of NXP B.V. nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY NXP B.V. AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL NXP B.V. OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * This file is part of the Contiki operating system. + * + * Author: Theo van Daele + * + */ +#include "contiki.h" +#include "dev/leds.h" +#include + +/*---------------------------------------------------------------------------*/ +void +leds_arch_init_1199(void) +{ + vGenericLEDInit(); +} +/*---------------------------------------------------------------------------*/ +void +leds_arch_set_1199(unsigned char c) +{ + vGenericLEDSetOutput(GEN_BOARD_LED_D1_VAL, c & LEDS_GREEN); + vGenericLEDSetOutput(GEN_BOARD_LED_D2_VAL, c & LEDS_BLUE); + vGenericLEDSetOutput(GEN_BOARD_LED_D3_VAL, c & LEDS_RED); +} diff --git a/platform/jn516x/dev/dr1199/leds-arch-1199.h b/platform/jn516x/dev/dr1199/leds-arch-1199.h new file mode 100644 index 000000000..477d2402b --- /dev/null +++ b/platform/jn516x/dev/dr1199/leds-arch-1199.h @@ -0,0 +1,35 @@ +/* + * Copyright (c) 2015 NXP B.V. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of NXP B.V. nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY NXP B.V. AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL NXP B.V. OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * This file is part of the Contiki operating system. + * + * Author: Theo van Daele + * + */ +void leds_arch_init_1199(void); +void leds_arch_set_1199(unsigned char c); diff --git a/platform/jn516x/dev/dr1199/pot-sensor.c b/platform/jn516x/dev/dr1199/pot-sensor.c new file mode 100644 index 000000000..e6254337a --- /dev/null +++ b/platform/jn516x/dev/dr1199/pot-sensor.c @@ -0,0 +1,176 @@ +/* + * Copyright (c) 2015 NXP B.V. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of NXP B.V. nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY NXP B.V. AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL NXP B.V. OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * This file is part of the Contiki operating system. + * + * Author: Theo van Daele + * + */ +#include "contiki.h" +#include "sys/etimer.h" +#include "lib/sensors.h" +#include "pot-sensor.h" +#include +#include + +/*---------------------------------------------------------------------------*/ +/* LOCAL DEFINITIONS */ +/*---------------------------------------------------------------------------*/ +/* #define DEBUG */ +#ifdef DEBUG +#include +#define PRINTF(...) printf(__VA_ARGS__) +#else +#define PRINTF(...) +#endif + +typedef enum { + POT_STATUS_NOT_INIT = 0, + POT_STATUS_INIT, + POT_STATUS_NOT_ACTIVE = POT_STATUS_INIT, + POT_STATUS_ACTIVE +} pot_status_t; + +/* Absolute delta in pot level needed to generate event */ +#define DELTA_POT_VALUE 1 + +/*---------------------------------------------------------------------------*/ +/* LOCAL DATA DEFINITIONS */ +/*---------------------------------------------------------------------------*/ +const struct sensors_sensor pot_sensor; +volatile static pot_status_t pot_status = POT_STATUS_NOT_INIT; +static int prev_pot_event_val = 0; +static int pot_value = 0; + +/*---------------------------------------------------------------------------*/ +/* LOCAL FUNCTION PROTOTYPES */ +/*---------------------------------------------------------------------------*/ +PROCESS(POTSampling, "POT"); + +/*---------------------------------------------------------------------------*/ +/* PUBLIC FUNCTIONS */ +/*---------------------------------------------------------------------------*/ +static int +configure(int type, int value) +{ + if(type == SENSORS_HW_INIT) { + pot_status = POT_STATUS_INIT; + bPotEnable(); + process_start(&POTSampling, NULL); + return 1; + } else if(type == SENSORS_ACTIVE) { + if(pot_status != POT_STATUS_NOT_INIT) { + if(value) { + /* ACTIVATE SENSOR */ + bPotEnable(); + prev_pot_event_val = 0; + /* Activate POT. */ + PRINTF("POT ACTIVATED\n"); + pot_status = POT_STATUS_ACTIVE; + process_post(&POTSampling, PROCESS_EVENT_MSG, (void *)&pot_status); + } else { + /* DE-ACTIVATE SENSOR */ + bPotDisable(); + PRINTF("POT DE-ACTIVATED\n"); + pot_status = POT_STATUS_NOT_ACTIVE; + process_post(&POTSampling, PROCESS_EVENT_MSG, (void *)&pot_status); + } + return 1; + } else { + /* + POT must be intialised before being (de)-activated */ + PRINTF("ERROR: NO HW_INIT POT\n"); + return 0; + } + } else { + /* Non valid type */ + return 0; + } +} +/*---------------------------------------------------------------------------*/ +static int +status(int type) +{ + if(type == SENSORS_ACTIVE) { + return pot_status == POT_STATUS_ACTIVE; + } else if(type == SENSORS_READY) { + return pot_status != POT_STATUS_NOT_INIT; + } + return 0; +} +/*---------------------------------------------------------------------------*/ +static int +value(int type) +{ + /* type: Not defined for the pot interface */ + return pot_value; +} +/*---------------------------------------------------------------------------*/ +/* LOCAL FUNCTIONS */ +/*---------------------------------------------------------------------------*/ +/* Process to get POT_SENSOR value. + POT is sampled. Sampling stopped when POT is de-activated. + Event is generated if pot value changed at least the value DELTA_POT_VALUE + since last event. */ +PROCESS_THREAD(POTSampling, ev, data) +{ + PROCESS_BEGIN(); + static struct etimer et; + + etimer_set(&et, CLOCK_SECOND / 10); + while(1) { + PROCESS_WAIT_EVENT_UNTIL((ev == PROCESS_EVENT_TIMER) || (ev == PROCESS_EVENT_MSG)); + if(ev == PROCESS_EVENT_TIMER) { + /* Handle sensor reading. */ + PRINTF("POT sample\n"); + pot_value = u16ReadPotValue(); + PRINTF("POT = %d\n", pot_value); + if(abs(pot_value - prev_pot_event_val) > DELTA_POT_VALUE) { + prev_pot_event_val = pot_value; + sensors_changed(&pot_sensor); + } + etimer_reset(&et); + } else { + /* ev == PROCESS_EVENT_MSG */ + if(*(int *)data == POT_STATUS_NOT_ACTIVE) { + /* Stop sampling */ + etimer_stop(&et); + } else if((*(int *)data == POT_STATUS_ACTIVE)) { + /* restart sampling */ + etimer_restart(&et); + } + } + } + PROCESS_END(); +} + +/*---------------------------------------------------------------------------*/ +/* Sensor defintion for sensor module */ +SENSORS_SENSOR(pot_sensor, POT_SENSOR, value, configure, status); +/*---------------------------------------------------------------------------*/ + diff --git a/platform/jn516x/dev/dr1199/pot-sensor.h b/platform/jn516x/dev/dr1199/pot-sensor.h new file mode 100644 index 000000000..d2297f822 --- /dev/null +++ b/platform/jn516x/dev/dr1199/pot-sensor.h @@ -0,0 +1,44 @@ +/* + * Copyright (c) 2015 NXP B.V. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of NXP B.V. nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY NXP B.V. AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL NXP B.V. OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * This file is part of the Contiki operating system. + * + * Author: Theo van Daele + * + */ +#ifndef __POT_SENSOR_H__ +#define __POT_SENSOR_H__ + +#include "lib/sensors.h" + +extern const struct sensors_sensor pot_sensor; + +#define POT_SENSOR "pot" + +#endif /* __POT_SENSOR_H__ */ + diff --git a/platform/jn516x/dev/exceptions.c b/platform/jn516x/dev/exceptions.c new file mode 100644 index 000000000..def4e2a73 --- /dev/null +++ b/platform/jn516x/dev/exceptions.c @@ -0,0 +1,399 @@ +/* + * Copyright (c) 2015 NXP B.V. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of NXP B.V. nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY NXP B.V. AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL NXP B.V. OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * This file is part of the Contiki operating system. + * + * Author: Thomas Haydon + * Integrated into Contiki by Beshr Al Nahas + * + */ + +#include +#include +#include +#include "exceptions.h" + +#ifndef EXCEPTION_STALLS_SYSTEM +#define EXCEPTION_STALLS_SYSTEM 0 +#endif /* EXCEPTION_STALLS_SYSTEM */ + +#ifndef PRINT_STACK_ON_REBOOT +#define PRINT_STACK_ON_REBOOT 1 +#endif /* PRINT_STACK_ON_REBOOT */ + +/** Define to dump the stack on exception */ +#ifndef EXC_DUMP_STACK +#define EXC_DUMP_STACK +#endif /* EXC_DUMP_STACK */ + +/** Define to dump registers on exception */ +#ifndef EXC_DUMP_REGS +/* #define EXC_DUMP_REGS */ +#endif /* EXC_DUMP_REGS */ + +/* Select whether exception vectors should be in RAM or Flash based on chip family */ +#if (defined JENNIC_CHIP_FAMILY_JN514x) +#define EXCEPTION_VECTORS_LOCATION_RAM +#elif (defined JENNIC_CHIP_FAMILY_JN516x) +#define EXCEPTION_VECTORS_LOCATION_FLASH +#else +#error Unsupported chip family selected +#endif /* JENNIC_CHIP_FAMILY */ + +#if (defined EXCEPTION_VECTORS_LOCATION_RAM) +#pragma "EXCEPTION_VECTORS_LOCATION_RAM" +/* RAM exception vectors are set up at run time */ +/* Addresses of exception vectors in RAM */ +#define BUS_ERROR *((volatile uint32 *)(0x4000000)) +#define TICK_TIMER *((volatile uint32 *)(0x4000004)) +#define UNALIGNED_ACCESS *((volatile uint32 *)(0x4000008)) +#define ILLEGAL_INSTRUCTION *((volatile uint32 *)(0x400000c)) +#define EXTERNAL_INTERRUPT *((volatile uint32 *)(0x4000010)) +#define SYSCALL *((volatile uint32 *)(0x4000014)) +#define TRAP *((volatile uint32 *)(0x4000018)) +#define GENERIC *((volatile uint32 *)(0x400001c)) +#define STACK_OVERFLOW *((volatile uint32 *)(0x4000020)) +#elif (defined EXCEPTION_VECTORS_LOCATION_FLASH) +#pragma "EXCEPTION_VECTORS_LOCATION_FLASH" +/* Flash exception vectors are set up at compile time */ +#else +#error Unknown exception vector location +#endif /* EXCEPTION_VECTORS_LOCATION */ + +/* Locations in stack trace of important information */ +#define STACK_REG 1 +#define PROGRAM_COUNTER 18 +#define EFFECTIVE_ADDR 19 + +/* Number of registers */ +#define REG_COUNT 16 + +/* Chip dependant RAM size */ +#if defined(JENNIC_CHIP_JN5148) || defined(JENNIC_CHIP_JN5148J01) +#define EXCEPTION_RAM_TOP 0x04020000 +#else +#define EXCEPTION_RAM_TOP 0x04008000 +#endif + +static void exception_handler(uint32 *pu32Stack, eExceptionType eType); +static void *heap_alloc_overflow_protect(void *pvPointer, uint32 u32Size, bool_t bClear); +/*---------------------------------------------------------------------------*/ +#if PRINT_STACK_ON_REBOOT +static void hexprint(uint8 v); +static void hexprint32(uint32 v); +static void printstring(const char *s); +#endif /* PRINT_STACK_ON_REBOOT */ + +/* For debugging */ +static const char *debug_filename = "nothing"; +static int debug_line = -1; + +void +debug_file_line(const char *file, int line) +{ + debug_filename = file; + debug_line = line; +} +extern uint32 heap_location; +extern void *(*prHeap_AllocFunc)(void *, uint32, bool_t); +PRIVATE void *(*prHeap_AllocOrig)(void *, uint32, bool_t); + +/* Symbol defined by the linker script */ +/* marks the end of the stack */ +extern void *stack_low_water_mark; + +/****************************************************************************/ +/*** Local Functions ***/ +/****************************************************************************/ +/*---------------------------------------------------------------------------*/ +#if PRINT_STACK_ON_REBOOT +#include "dev/uart0.h" +#define printchar(X) uart0_write_direct(X) +/*---------------------------------------------------------------------------*/ +static void +hexprint(uint8 v) +{ + const char hexconv[] = "0123456789abcdef"; + printchar(hexconv[v >> 4]); + printchar(hexconv[v & 0x0f]); +} +/*---------------------------------------------------------------------------*/ +static void +hexprint32(uint32 v) +{ + hexprint(((uint32)v) >> (uint32)24); + hexprint(((uint32)v) >> (uint32)16); + hexprint(((uint32)v) >> (uint32)8); + hexprint((v) & 0xff); +} +/*---------------------------------------------------------------------------*/ +static void +printstring(const char *s) +{ + while(*s) { + printchar(*s++); + } +} +#endif /* PRINT_STACK_ON_REBOOT */ + +/**************************************************************************** + * + * NAME: vEXC_Register + * + * DESCRIPTION: + * Set up exceptions. When in RAM, overwrite the default vectors with ours. + * We also patch the heap allocation function so that we can keep tabs on + * the amount of free heap. + * + * PARAMETERS: None + * + * RETURNS: + * None + * + ****************************************************************************/ +PUBLIC void +vEXC_Register(void) +{ +#ifdef EXCEPTION_VECTORS_LOCATION_RAM + /* Overwrite exception vectors, pointing them all at the generic handler */ + BUS_ERROR = (uint32)exception_handler; + UNALIGNED_ACCESS = (uint32)exception_handler; + ILLEGAL_INSTRUCTION = (uint32)exception_handler; + SYSCALL = (uint32)exception_handler; + TRAP = (uint32)exception_handler; + GENERIC = (uint32)exception_handler; + STACK_OVERFLOW = (uint32)exception_handler; +#endif /* EXCEPTION_VECTORS_LOCATION */ + + prHeap_AllocOrig = prHeap_AllocFunc; + prHeap_AllocFunc = heap_alloc_overflow_protect; +} +#ifdef EXCEPTION_VECTORS_LOCATION_FLASH +/* If exception vectors are in flash, define the handler functions here to be linked in */ +/* These function names are defined in the 6x linker script for the various exceptions */ +/* Point them all at the generic handler */ +PUBLIC void +vException_BusError(uint32 *pu32Stack, eExceptionType eType) +{ + exception_handler(pu32Stack, eType); +} +PUBLIC void +vException_UnalignedAccess(uint32 *pu32Stack, eExceptionType eType) +{ + exception_handler(pu32Stack, eType); +} +PUBLIC void +vException_IllegalInstruction(uint32 *pu32Stack, eExceptionType eType) +{ + exception_handler(pu32Stack, eType); +} +PUBLIC void +vException_SysCall(uint32 *pu32Stack, eExceptionType eType) +{ + exception_handler(pu32Stack, eType); +} +PUBLIC void +vException_Trap(uint32 *pu32Stack, eExceptionType eType) +{ + exception_handler(pu32Stack, eType); +} +PUBLIC void +vException_StackOverflow(uint32 *pu32Stack, eExceptionType eType) +{ + exception_handler(pu32Stack, eType); +} +#endif /* EXCEPTION_VECTORS_LOCATION_FLASH */ + +/**************************************************************************** + * + * NAME: exception_handler + * + * DESCRIPTION: + * Generic exception handler which is called whether the vectors are in RAM or flash + * + * PARAMETERS: None + * + * RETURNS: + * None + * + ****************************************************************************/ +static void +exception_handler(uint32 *pu32Stack, eExceptionType eType) +{ +#if (defined EXC_DUMP_STACK) || (defined EXC_DUMP_REGS) + int i; +#endif + uint32 u32EPCR, u32EEAR, u32Stack; + char *pcString; + + MICRO_DISABLE_INTERRUPTS(); + + switch(eType) { + case E_EXC_BUS_ERROR: + pcString = "BUS"; + break; + + case E_EXC_UNALIGNED_ACCESS: + pcString = "ALIGN"; + break; + + case E_EXC_ILLEGAL_INSTRUCTION: + pcString = "ILLEGAL"; + break; + + case E_EXC_SYSCALL: + pcString = "SYSCALL"; + break; + + case E_EXC_TRAP: + pcString = "TRAP"; + break; + + case E_EXC_GENERIC: + pcString = "GENERIC"; + break; + + case E_EXC_STACK_OVERFLOW: + pcString = "STACK"; + break; + + default: + pcString = "UNKNOWN"; + break; + } + + if(bAHI_WatchdogResetEvent()) { + pcString = "WATCHDOG"; + } + vAHI_WatchdogStop(); + + /* Pull the EPCR and EEAR values from where they've been saved by the ROM exception handler */ + u32EPCR = pu32Stack[PROGRAM_COUNTER]; + u32EEAR = pu32Stack[EFFECTIVE_ADDR]; + u32Stack = pu32Stack[STACK_REG]; + + /* Log the exception */ + printstring("\n\n\n"); + printstring(pcString); + printstring(" EXCEPTION @ $"); + hexprint32(u32EPCR); + printstring(" EA: "); + hexprint32(u32EEAR); + printstring(" SK: "); + hexprint32(u32Stack); + printstring(" HP: "); + hexprint32(((uint32 *)&heap_location)[0]); + printstring("\n"); + printstring(" File: "); + printstring(debug_filename); + printstring(" Line: "); + hexprint32(debug_line); + printstring("\n"); + +#ifdef EXC_DUMP_REGS + printstring("\nREGS: "); + /* Pull and print the registers from saved locations */ + for(i = 0; i < REG_COUNT; i += 4) { + printstring("R"); + hexprint(i); + printstring("-"); + hexprint(i + 3); + printstring(": "); + hexprint(pu32Stack[i]); + printstring(" "); + hexprint32(pu32Stack[i + 1]); + printstring(" "); + hexprint32(pu32Stack[i + 2]); + printstring(" "); + hexprint32(pu32Stack[i + 3]); + printstring("\n"); + } +#endif + +#ifdef EXC_DUMP_STACK + /* Print the stack */ + printstring("\nRAM top: "); + hexprint32(EXCEPTION_RAM_TOP); + printstring("\nSTACK: \n"); + pu32Stack = (uint32 *)(u32Stack & 0xFFFFFFF0); + for(i = 0; (pu32Stack + i) < (uint32 *)(EXCEPTION_RAM_TOP); i += 4) { + printstring("@"); + hexprint32((uint32)(pu32Stack + i)); + printstring(": "); + hexprint32(pu32Stack[i]); + printstring(" "); + hexprint32(pu32Stack[i + 1]); + printstring(" "); + hexprint32(pu32Stack[i + 2]); + printstring(" "); + hexprint32(pu32Stack[i + 3]); + printstring("\n"); + } +#endif + +#if EXCEPTION_STALLS_SYSTEM + while(1) { + } +#else /* EXCEPTION_STALLS_SYSTEM */ + /* Software reset */ + vAHI_WatchdogException(0); + vAHI_SwReset(); +#endif /* EXCEPTION_STALLS_SYSTEM */ +} +/**************************************************************************** + * + * NAME: heap_alloc_overflow_protect + * + * DESCRIPTION: + * New heap allocation function that sets the stack overflow location to the new + * top address of the heap. + * + * PARAMETERS: Name RW Usage + * pvPointer W Location of allocated heap memory + * u32Size R Number of bytes to allocate + * bClear R Flag to set new memory to 0 + * + * RETURNS: + * Pointer to new memory + * + ****************************************************************************/ +static void * +heap_alloc_overflow_protect(void *pvPointer, uint32 u32Size, bool_t bClear) +{ + void *pvAlloc; + /* Call original heap allocation function */ + pvAlloc = prHeap_AllocOrig(pvPointer, u32Size, bClear); + /* + * Initialise the stack overflow exception to trigger if the end of the + * stack is reached. See the linker command file to adjust the allocated + * stack size. + */ + /* Set stack overflow address */ + vAHI_SetStackOverflow(TRUE, ((uint32 *)&heap_location)[0]); + return pvAlloc; +} diff --git a/platform/jn516x/dev/exceptions.h b/platform/jn516x/dev/exceptions.h new file mode 100644 index 000000000..6acfd8d16 --- /dev/null +++ b/platform/jn516x/dev/exceptions.h @@ -0,0 +1,59 @@ +/* + * Copyright (c) 2015 NXP B.V. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of NXP B.V. nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY NXP B.V. AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL NXP B.V. OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * This file is part of the Contiki operating system. + * + * Author: Thomas Haydon + * Integrated into Contiki by Beshr Al Nahas + * + */ + +#ifndef EXCEPTIONS_H +#define EXCEPTIONS_H + +#include + +/** Enumerated type of CPU exception numbers */ +typedef enum { + E_EXC_BUS_ERROR = 0x02, + E_EXC_TICK_TIMER = 0x05, + E_EXC_UNALIGNED_ACCESS = 0x06, + E_EXC_ILLEGAL_INSTRUCTION = 0x07, + E_EXC_EXTERNAL_INTERRUPT = 0x08, + E_EXC_SYSCALL = 0x0C, + E_EXC_TRAP = 0x0E, + E_EXC_GENERIC = 0x0F, + E_EXC_STACK_OVERFLOW = 0x10 +} eExceptionType; + +/* Exceptions set up function */ +PUBLIC void vEXC_Register(void); +/* For debugging */ +void debug_file_line(const char *file, int line); + +#endif /* EXCEPTIONS_H */ diff --git a/platform/jn516x/dev/leds-extension.c b/platform/jn516x/dev/leds-extension.c new file mode 100644 index 000000000..05e9a8223 --- /dev/null +++ b/platform/jn516x/dev/leds-extension.c @@ -0,0 +1,41 @@ +/* + * Copyright (c) 2015 NXP B.V. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of NXP B.V. nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY NXP B.V. AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL NXP B.V. OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * This file is part of the Contiki operating system. + * + * Author: Theo van Daele + * + */ +#include "leds-extension.h" +#include "dev/leds.h" + +void +leds_set_level(unsigned char level, unsigned char c) +{ + leds_arch_set_level(level, c); +} diff --git a/platform/jn516x/dev/leds-extension.h b/platform/jn516x/dev/leds-extension.h new file mode 100644 index 000000000..2e33b59ff --- /dev/null +++ b/platform/jn516x/dev/leds-extension.h @@ -0,0 +1,44 @@ +/* + * Copyright (c) 2015 NXP B.V. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of NXP B.V. nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY NXP B.V. AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL NXP B.V. OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * This file is part of the Contiki operating system. + * + * Author: Theo van Daele + * + */ +#ifndef LEDS_EXTENSION_H_ +#define LEDS_EXTENSION_H_ + +void leds_set_level(unsigned char level, unsigned char c); + +/** + * Leds implementation + */ +void leds_arch_set_level(unsigned char level, unsigned char c); + +#endif /* LEDS_EXTENSION_H_ */ \ No newline at end of file diff --git a/platform/jn516x/dev/micromac-radio.c b/platform/jn516x/dev/micromac-radio.c new file mode 100644 index 000000000..3d9d4026a --- /dev/null +++ b/platform/jn516x/dev/micromac-radio.c @@ -0,0 +1,1013 @@ +/* + * Copyright (c) 2014, NXP and SICS Swedish ICT. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the Institute nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * This file is part of the Contiki operating system. + * + */ + +/** + * \file + * Contiki driver for NXP JN516X using MMAC interface + * \authors + * Beshr Al Nahas + * Simon Duquennot + * Atis Elsts + * + */ + +#include +#include "contiki.h" +#include "dev/leds.h" +#include "sys/rtimer.h" +#include "net/packetbuf.h" +#include "net/rime/rimestats.h" +#include "net/netstack.h" +#include "net/mac/frame802154.h" +#include "lib/crc16.h" +#include "lib/ringbufindex.h" + +#include "AppHardwareApi.h" +#include "MMAC.h" +#include "micromac-radio.h" +#include "JPT.h" +#include "PeripheralRegs.h" + +/* This driver configures the radio in PHY mode and does address decoding + * and acknowledging in software. */ + +#define DEBUG DEBUG_NONE +#include "net/ip/uip-debug.h" + +/* Perform CRC check for received packets in SW, + * since we use PHY mode which does not calculate CRC in HW */ +#define CRC_SW 1 + +#define CHECKSUM_LEN 2 + +/* Max packet duration: 5 + 127 + 2 bytes, 32us per byte */ +#define MAX_PACKET_DURATION US_TO_RTIMERTICKS((127 + 2) * 32 + RADIO_DELAY_BEFORE_TX) +/* Max ACK duration: 5 + 3 + 2 bytes */ +#define MAX_ACK_DURATION US_TO_RTIMERTICKS((3 + 2) * 32 + RADIO_DELAY_BEFORE_TX) + +/* Test-mode pins output on dev-kit */ +#define RADIO_TEST_MODE_HIGH_PWR 1 +#define RADIO_TEST_MODE_ADVANCED 2 +#define RADIO_TEST_MODE_DISABLED 0 + +#ifndef RADIO_TEST_MODE +#define RADIO_TEST_MODE RADIO_TEST_MODE_DISABLED +#endif /* RADIO_TEST_MODE */ + +/* The number of input buffers */ +#ifndef MIRCOMAC_CONF_BUF_NUM +#define MIRCOMAC_CONF_BUF_NUM 2 +#endif /* MIRCOMAC_CONF_BUF_NUM */ + +/* Init radio channel */ +#ifndef MICROMAC_CONF_CHANNEL +#define MICROMAC_CONF_CHANNEL 26 +#endif + +/* Default energy level threshold for clear channel detection */ +#ifndef MICROMAC_CONF_CCA_THR +#define MICROMAC_CONF_CCA_THR 39 /* approximately -85 dBm */ +#endif /* MICROMAC_CONF_CCA_THR */ + +#if (JENNIC_CHIP == JN5169) +#define OUTPUT_POWER_MAX 10 +#define OUTPUT_POWER_MIN (-32) +#define ABS_OUTPUT_POWER_MIN (32) +#else +#define OUTPUT_POWER_MAX 0 +#define OUTPUT_POWER_MIN (-32) +#endif + +/* Default Tx power [dBm] (between OUTPUT_POWER_MIN and OUTPUT_POWER_MAX) */ +#ifndef MICROMAC_CONF_TX_POWER +#define MICROMAC_CONF_TX_POWER 0 +#endif + +/* Autoack */ +#ifndef MICROMAC_CONF_AUTOACK +#define MICROMAC_CONF_AUTOACK 1 +#endif /* MICROMAC_CONF_AUTOACK */ + +#define RADIO_TO_RTIMER(X) ((rtimer_clock_t)((X) << (int32_t)8L)) + +/* Set radio always on for now because this is what Contiki MAC layers + * expect. */ +#ifndef MICROMAC_CONF_ALWAYS_ON +#define MICROMAC_CONF_ALWAYS_ON 1 +#endif /* MICROMAC_CONF_ALWAYS_ON */ + +#define BUSYWAIT_UNTIL(cond, max_time) \ + do { \ + rtimer_clock_t t0; \ + t0 = RTIMER_NOW(); \ + while(!(cond) && RTIMER_CLOCK_LT(RTIMER_NOW(), t0 + (max_time))) ; \ + } while(0) + +/* Local variables */ +static volatile signed char radio_last_rssi; +static volatile uint8_t radio_last_correlation; /* LQI */ + +/* Did we miss a request to turn the radio on due to overflow? */ +static volatile uint8_t missed_radio_on_request = 0; + +/* Poll mode disabled by default */ +static uint8_t poll_mode = 0; +/* (Software) frame filtering enabled by default */ +static uint8_t frame_filtering = 1; +/* (Software) autoack */ +static uint8_t autoack_enabled = MICROMAC_CONF_AUTOACK; +/* CCA before sending? Disabled by default. */ +static uint8_t send_on_cca = 0; + +/* Current radio channel */ +static int current_channel; + +/* Current set point tx power + Actual tx power may be different. Use get_txpower() for actual power */ +static int current_tx_power; + +/* an integer between 0 and 255, used only with cca() */ +static uint8_t cca_thershold = MICROMAC_CONF_CCA_THR; + +/* Tx in progress? */ +static volatile uint8_t tx_in_progress = 0; +/* Are we currently listening? */ +static volatile uint8_t listen_on = 0; + +/* Is the driver currently transmitting a software ACK? */ +static uint8_t in_ack_transmission = 0; + +/* TX frame buffer */ +static tsPhyFrame tx_frame_buffer; + +/* RX frame buffer */ +static tsPhyFrame *rx_frame_buffer; + +/* Frame buffer pointer to read from */ +static tsPhyFrame *input_frame_buffer = NULL; + +/* Ringbuffer for received packets in interrupt enabled mode */ +static struct ringbufindex input_ringbuf; +static tsPhyFrame input_array[MIRCOMAC_CONF_BUF_NUM]; + +/* SFD timestamp in RTIMER ticks */ +static volatile uint32_t last_packet_timestamp = 0; + +/* Local functions prototypes */ +static int on(void); +static int off(void); +static int is_packet_for_us(uint8_t *buf, int len, int do_send_ack); +static void set_frame_filtering(uint8_t enable); +static rtimer_clock_t get_packet_timestamp(void); +static void set_txpower(int8_t power); +void set_channel(int c); +static void radio_interrupt_handler(uint32 mac_event); +static int get_detected_energy(void); +static int get_rssi(void); +static void read_last_rssi(void); + +/*---------------------------------------------------------------------------*/ +PROCESS(micromac_radio_process, "micromac_radio_driver"); +/*---------------------------------------------------------------------------*/ + +/* Custom Radio parameters */ +#ifndef RADIO_RX_MODE_POLL_MODE +#define RADIO_PARAM_LAST_RSSI 0x80 +#define RADIO_PARAM_LAST_PACKET_TIMESTAMP 0x81 +#define RADIO_RX_MODE_POLL_MODE (1 << 2) +#endif /* RADIO_RX_MODE_POLL_MODE */ + +#ifndef FRAME802154_IEEE802154E_2012 +/* We define here the missing few features this driver needs from IEEE802.15.4e */ +#define FRAME802154_IEEE802154E_2012 (0x02) +/*----------------------------------------------------------------------------*/ +uint16_t +frame802154_get_pan_id() +{ + return IEEE802154_PANID; +} +/*----------------------------------------------------------------------------*/ +static void +frame802154_has_panid(frame802154_fcf_t *fcf, int *has_src_pan_id, int *has_dest_pan_id) +{ + int src_pan_id = 0; + int dest_pan_id = 0; + + if(fcf == NULL) { + return; + } + if(fcf->frame_version == FRAME802154_IEEE802154E_2012) { + if(!fcf->panid_compression) { + /* Compressed PAN ID == no PAN ID at all */ + if(fcf->dest_addr_mode == fcf->dest_addr_mode) { + /* No address or both addresses: include destination PAN ID */ + dest_pan_id = 1; + } else if(fcf->dest_addr_mode) { + /* Only dest address, include dest PAN ID */ + dest_pan_id = 1; + } else if(fcf->src_addr_mode) { + /* Only src address, include src PAN ID */ + src_pan_id = 1; + } + } + if(fcf->dest_addr_mode == 0 && fcf->dest_addr_mode == 1) { + /* No address included, include dest PAN ID conditionally */ + if(!fcf->panid_compression) { + dest_pan_id = 1; + /* Remove the following rule the day rows 2 and 3 from table 2a are fixed: */ + } + } + if(fcf->dest_addr_mode == 0 && fcf->dest_addr_mode == 0) { + /* Not meaningful, we include a PAN ID iff the compress flag is set, but + * this is what the standard currently stipulates */ + dest_pan_id = fcf->panid_compression; + } + } else + /* No PAN ID in ACK */ + if(fcf->frame_type != FRAME802154_ACKFRAME) { + if(!fcf->panid_compression && fcf->src_addr_mode & 3) { + /* If compressed, don't inclue source PAN ID */ + src_pan_id = 1; + } + if(fcf->dest_addr_mode & 3) { + dest_pan_id = 1; + } + } + + if(has_src_pan_id != NULL) { + *has_src_pan_id = src_pan_id; + } + if(has_dest_pan_id != NULL) { + *has_dest_pan_id = dest_pan_id; + } +} +#endif /* FRAME802154_IEEE802154E_2012 */ + +/*---------------------------------------------------------------------------*/ +static rtimer_clock_t +get_packet_timestamp(void) +{ + /* Save SFD timestamp, converted from radio timer to RTIMER */ + last_packet_timestamp = RTIMER_NOW() - + RADIO_TO_RTIMER((uint32_t)(u32MMAC_GetTime() - u32MMAC_GetRxTime())); + return last_packet_timestamp; +} +/*---------------------------------------------------------------------------*/ +static int +init(void) +{ + int put_index; + tsExtAddr node_long_address; + uint16_t node_short_address; + + tx_in_progress = 0; + + u32JPT_Init(); + vMMAC_Enable(); + + /* Enable/disable interrupts */ + if(poll_mode) { + vMMAC_EnableInterrupts(NULL); + vMMAC_ConfigureInterruptSources(0); + } else { + vMMAC_EnableInterrupts(&radio_interrupt_handler); + } vMMAC_ConfigureRadio(); + set_channel(MICROMAC_CONF_CHANNEL); + set_txpower(MICROMAC_CONF_TX_POWER); + + vMMAC_GetMacAddress(&node_long_address); + + /* Short addresses are disabled by default */ + node_short_address = (uint16_t)node_long_address.u32L; + vMMAC_SetRxAddress(frame802154_get_pan_id(), node_short_address, &node_long_address); + + /* Disable hardware backoff */ + vMMAC_SetTxParameters(1, 0, 0, 0); + vMMAC_SetCutOffTimer(0, FALSE); + + /* Initialize ring buffer and first input packet pointer */ + ringbufindex_init(&input_ringbuf, MIRCOMAC_CONF_BUF_NUM); + /* get pointer to next input slot */ + put_index = ringbufindex_peek_put(&input_ringbuf); + if(put_index == -1) { + rx_frame_buffer = NULL; + printf("micromac_radio init:! no buffer available. Abort init.\n"); + off(); + return 0; + } else { + rx_frame_buffer = &input_array[put_index]; + } input_frame_buffer = rx_frame_buffer; + + process_start(µmac_radio_process, NULL); + +#if RADIO_TEST_MODE == RADIO_TEST_MODE_HIGH_PWR + /* Enable high power mode. + * In this mode DIO2 goes high during RX + * and DIO3 goes high during TX + **/ + vREG_SysWrite(REG_SYS_PWR_CTRL, + u32REG_SysRead(REG_SYS_PWR_CTRL) + | REG_SYSCTRL_PWRCTRL_RFRXEN_MASK + | REG_SYSCTRL_PWRCTRL_RFTXEN_MASK); +#elif RADIO_TEST_MODE == RADIO_TEST_MODE_ADVANCED + /* output internal radio status on IO pins. + * See Chris@NXP email */ + vREG_SysWrite(REG_SYS_PWR_CTRL, + u32REG_SysRead(REG_SYS_PWR_CTRL) | (1UL << 26UL)); +#endif /* TEST_MODE */ + + return 1; +} +/*---------------------------------------------------------------------------*/ +static int +on(void) +{ + /* No address matching or frame decoding */ + if(rx_frame_buffer != NULL) { + vMMAC_StartPhyReceive(rx_frame_buffer, + (uint16_t)(E_MMAC_RX_START_NOW + | E_MMAC_RX_NO_FCS_ERROR) /* means: reject FCS errors */ + ); + } else { + missed_radio_on_request = 1; + } ENERGEST_ON(ENERGEST_TYPE_LISTEN); + listen_on = 1; + return 1; +} +/*---------------------------------------------------------------------------*/ +static int +off(void) +{ + listen_on = 0; + tx_in_progress = 0; + + ENERGEST_OFF(ENERGEST_TYPE_LISTEN); + + /* The following would be needed with delayed Tx/Rx functions + * vMMAC_SetCutOffTimer(0, FALSE);*/ + vMMAC_RadioOff(); + + return 1; +} +/*---------------------------------------------------------------------------*/ +static int +transmit(unsigned short payload_len) +{ + if(tx_in_progress) { + return RADIO_TX_COLLISION; + } + tx_in_progress = 1; + + /* Energest */ + if(listen_on) { + ENERGEST_OFF(ENERGEST_TYPE_LISTEN); + } + ENERGEST_ON(ENERGEST_TYPE_TRANSMIT); + + /* Transmit and wait */ + vMMAC_StartPhyTransmit(&tx_frame_buffer, + E_MMAC_TX_START_NOW | + (send_on_cca ? E_MMAC_TX_USE_CCA : E_MMAC_TX_NO_CCA)); + + if(poll_mode) { + BUSYWAIT_UNTIL(u32MMAC_PollInterruptSource(E_MMAC_INT_TX_COMPLETE), MAX_PACKET_DURATION); + } else { + if(in_ack_transmission) { + /* as nested interupts are not possible, the tx flag will never be cleared */ + BUSYWAIT_UNTIL(FALSE, MAX_ACK_DURATION); + } else { + /* wait until the tx flag is cleared */ + BUSYWAIT_UNTIL(!tx_in_progress, MAX_PACKET_DURATION); + } + } + + /* Energest */ + ENERGEST_OFF(ENERGEST_TYPE_TRANSMIT); + if(listen_on) { + ENERGEST_ON(ENERGEST_TYPE_LISTEN); + } + tx_in_progress = 0; + + /* Check error code */ + int ret; + uint32_t tx_error = u32MMAC_GetTxErrors(); + if(tx_error == 0) { + ret = RADIO_TX_OK; + RIMESTATS_ADD(acktx); + } else if(tx_error & E_MMAC_TXSTAT_ABORTED) { + ret = RADIO_TX_ERR; + RIMESTATS_ADD(sendingdrop); + } else if(tx_error & E_MMAC_TXSTAT_CCA_BUSY) { + ret = RADIO_TX_COLLISION; + RIMESTATS_ADD(contentiondrop); + } else if(tx_error & E_MMAC_TXSTAT_NO_ACK) { + ret = RADIO_TX_NOACK; + RIMESTATS_ADD(noacktx); + } else { + ret = RADIO_TX_ERR; + } return ret; +} +/*---------------------------------------------------------------------------*/ +static int +prepare(const void *payload, unsigned short payload_len) +{ + uint8_t i; + uint16_t checksum; + + RIMESTATS_ADD(lltx); + + if(tx_in_progress) { + return 1; + } + if(payload_len > 127 || payload == NULL) { + return 1; + /* Copy payload to (soft) Ttx buffer */ + } + memcpy(tx_frame_buffer.uPayload.au8Byte, payload, payload_len); + i = payload_len; +#if CRC_SW + /* Compute CRC */ + checksum = crc16_data(payload, payload_len, 0); + tx_frame_buffer.uPayload.au8Byte[i++] = checksum; + tx_frame_buffer.uPayload.au8Byte[i++] = (checksum >> 8) & 0xff; + tx_frame_buffer.u8PayloadLength = payload_len + CHECKSUM_LEN; +#else + tx_frame_buffer.u8PayloadLength = payload_len; +#endif + + return 0; +} +/*---------------------------------------------------------------------------*/ +static int +send(const void *payload, unsigned short payload_len) +{ + if(prepare(payload, payload_len) == 0) { + return transmit(payload_len); + } else { + return RADIO_TX_ERR; + } +} +/*---------------------------------------------------------------------------*/ +int +get_channel(void) +{ + return current_channel; +} +/*---------------------------------------------------------------------------*/ +void +set_channel(int c) +{ + current_channel = c; + /* will fine tune TX power as well */ + vMMAC_SetChannel(current_channel); +} +/*---------------------------------------------------------------------------*/ +static int +is_broadcast_addr(uint8_t mode, uint8_t *addr) +{ + int i = ((mode == FRAME802154_SHORTADDRMODE) ? 2 : 8); + while(i-- > 0) { + if(addr[i] != 0xff) { + return 0; + } + } + return 1; +} +/*---------------------------------------------------------------------------*/ +/* Send an ACK */ +static void +send_ack(const frame802154_t *frame) +{ + uint8_t buffer[3]; + /* FCF: 2 octets */ + buffer[0] = FRAME802154_ACKFRAME; + buffer[1] = 0; + /* Seqnum: 1 octets */ + buffer[2] = frame->seq; + in_ack_transmission = 1; + send(&buffer, sizeof(buffer)); + in_ack_transmission = 0; +} +/*---------------------------------------------------------------------------*/ +/* Check if a packet is for us */ +static int +is_packet_for_us(uint8_t *buf, int len, int do_send_ack) +{ + frame802154_t frame; + int result; + uint8_t parsed = frame802154_parse(buf, len, &frame); + if(parsed) { + if(frame.fcf.dest_addr_mode) { + int has_dest_panid; + frame802154_has_panid(&frame.fcf, NULL, &has_dest_panid); + if(has_dest_panid + && frame802154_get_pan_id() != FRAME802154_BROADCASTPANDID + && frame.dest_pid != frame802154_get_pan_id() + && frame.dest_pid != FRAME802154_BROADCASTPANDID) { + /* Packet to another PAN */ + return 0; + } + if(!is_broadcast_addr(frame.fcf.dest_addr_mode, frame.dest_addr)) { + result = linkaddr_cmp((linkaddr_t *)frame.dest_addr, &linkaddr_node_addr); + if(autoack_enabled && result && do_send_ack) { + /* this is a unicast frame and sending ACKs is enabled */ + send_ack(&frame); + } + return result; + } + } + return 1; + } else { + return 0; + } +} +/*---------------------------------------------------------------------------*/ +static int +read(void *buf, unsigned short bufsize) +{ + int len = 0; + uint16_t radio_last_rx_crc; + uint8_t radio_last_rx_crc_ok = 1; + + len = input_frame_buffer->u8PayloadLength; + + if(len <= CHECKSUM_LEN) { + return 0; + } else { + len -= CHECKSUM_LEN; + /* Check CRC */ +#if CRC_SW + uint16_t checksum = crc16_data(input_frame_buffer->uPayload.au8Byte, len, 0); + radio_last_rx_crc = + (uint16_t)(input_frame_buffer->uPayload.au8Byte[len + 1] << (uint16_t)8) + | input_frame_buffer->uPayload.au8Byte[len]; + radio_last_rx_crc_ok = (checksum == radio_last_rx_crc); + if(!radio_last_rx_crc_ok) { + RIMESTATS_ADD(badcrc); + } +#endif /* CRC_SW */ + if(radio_last_rx_crc_ok) { + /* If we are in poll mode we need to check the frame here */ + if(poll_mode) { + if(frame_filtering && + !is_packet_for_us(input_frame_buffer->uPayload.au8Byte, len, 0)) { + len = 0; + } else { + read_last_rssi(); + } + } + if(len != 0) { + bufsize = MIN(len, bufsize); + memcpy(buf, input_frame_buffer->uPayload.au8Byte, bufsize); + RIMESTATS_ADD(llrx); + if(!poll_mode) { + /* Not in poll mode: packetbuf should not be accessed in interrupt context */ + packetbuf_set_attr(PACKETBUF_ATTR_RSSI, radio_last_rssi); + packetbuf_set_attr(PACKETBUF_ATTR_LINK_QUALITY, radio_last_correlation); + } + } + } else { + len = 0; + /* Disable further read attempts */ + } input_frame_buffer->u8PayloadLength = 0; + } + + return len; +} +/*---------------------------------------------------------------------------*/ +static void +set_txpower(int8_t power) +{ + if(power > OUTPUT_POWER_MAX) { + current_tx_power = OUTPUT_POWER_MAX; + } else { + if(power < OUTPUT_POWER_MIN) { + current_tx_power = OUTPUT_POWER_MIN; + } else { + current_tx_power = power; + } + } + vMMAC_SetChannelAndPower(current_channel, current_tx_power); +} +/*--------------------------------------------------------------------------*/ +static int +get_txpower(void) +{ + int actual_tx_power; +#if (JENNIC_CHIP == JN5169) + /* Actual tx power value rounded to nearest integer number */ + const static int8 power_table [] = { + -32, -30, -29, -29, /* -32 .. -29 */ + -28, -28, -28, -28, /* -28 .. -25 */ + -21, -21, -21, -2, /* -24 .. -21 */ + -20, -19, -18, -17, /* -20 .. -17 */ + -17, -17, -17, -10, /* -16 .. -13 */ + -10, -10, -10, -9, /* -12 .. -09 */ + -8, -7, -6, -6, /* -08 .. -05 */ + -6, -6, 1, 1, /* -04 .. -01 */ + 1, 1, 2, 3, /* 00 .. 03 */ + 4, 5, 6, 7, /* 04 .. 07 */ + 9, 9, 10 }; /* 08 .. 10 */ + if(current_tx_power > OUTPUT_POWER_MAX) { + actual_tx_power = OUTPUT_POWER_MAX; + } else if(current_tx_power < OUTPUT_POWER_MIN) { + actual_tx_power = OUTPUT_POWER_MIN; + } else { + actual_tx_power = power_table[current_tx_power + ABS_OUTPUT_POWER_MIN]; + } +#else + /* Other JN516x chips */ + if(current_tx_power < (-24)) { + actual_tx_power = OUTPUT_POWER_MIN; + } else if(current_tx_power < (-12)) { + actual_tx_power = (-20); + } else if(current_tx_power < 0) { + actual_tx_power = (-9); + } else { + actual_tx_power = OUTPUT_POWER_MAX; + } +#endif + return (int)actual_tx_power; +} +/*---------------------------------------------------------------------------*/ +static int +get_detected_energy(void) +{ + const uint32 u32Samples = 8; + return u8JPT_EnergyDetect(current_channel, u32Samples); +} +/*---------------------------------------------------------------------------*/ +static int +get_rssi(void) +{ + /* this approximate formula for RSSI is taken from NXP internal docs */ + return (7 * get_detected_energy() - 1970) / 20; +} +/*---------------------------------------------------------------------------*/ +static void +read_last_rssi(void) +{ + uint8_t radio_last_rx_energy; + radio_last_rx_energy = u8MMAC_GetRxLqi((uint8_t *)&radio_last_correlation); + radio_last_rssi = i16JPT_ConvertEnergyTodBm(radio_last_rx_energy); +} +/*---------------------------------------------------------------------------*/ +int +receiving_packet(void) +{ + return bMMAC_RxDetected(); +} +/*---------------------------------------------------------------------------*/ +static int +pending_packet(void) +{ + if(!poll_mode) { + return ringbufindex_peek_get(&input_ringbuf) != -1; + } else { + return u32MMAC_PollInterruptSource( + E_MMAC_INT_RX_COMPLETE | E_MMAC_INT_RX_HEADER); + } +} +/*---------------------------------------------------------------------------*/ +static int +cca(void) +{ + bool_t is_channel_busy = bJPT_CCA(current_channel, + E_JPT_CCA_MODE_CARRIER_OR_ENERGY, + cca_thershold); + return is_channel_busy == FALSE; +} +/*---------------------------------------------------------------------------*/ +static void +radio_interrupt_handler(uint32 mac_event) +{ + uint32_t rx_status; + uint8_t overflow = 0; + int get_index; + int put_index; + int packet_for_me = 0; + + if(mac_event & E_MMAC_INT_TX_COMPLETE) { + /* Transmission attempt has finished */ + tx_in_progress = 0; + } else if(mac_event & E_MMAC_INT_RX_COMPLETE) { + rx_status = u32MMAC_GetRxErrors(); + /* If rx is successful */ + if(rx_status == 0) { + /* Save SFD timestamp */ + last_packet_timestamp = get_packet_timestamp(); + + if(!poll_mode && (mac_event & E_MMAC_INT_RX_COMPLETE)) { + if(rx_frame_buffer->u8PayloadLength > CHECKSUM_LEN) { + if(frame_filtering) { + /* Check RX address */ + packet_for_me = is_packet_for_us(rx_frame_buffer->uPayload.au8Byte, rx_frame_buffer->u8PayloadLength - CHECKSUM_LEN, 1); + } else if(!frame_filtering) { + packet_for_me = 1; + } + } + if(!packet_for_me) { + /* Prevent reading */ + rx_frame_buffer->u8PayloadLength = 0; + } else { + /* read and cache RSSI and LQI values */ + read_last_rssi(); + /* Put received frame in queue */ + ringbufindex_put(&input_ringbuf); + + if((get_index = ringbufindex_peek_get(&input_ringbuf)) != -1) { + input_frame_buffer = &input_array[get_index]; + } + process_poll(µmac_radio_process); + + /* get pointer to next input slot */ + put_index = ringbufindex_peek_put(&input_ringbuf); + /* is there space? */ + if(put_index != -1) { + /* move rx_frame_buffer to next empty slot */ + rx_frame_buffer = &input_array[put_index]; + } else { + overflow = 1; + rx_frame_buffer = NULL; + } + } + } + } else { /* if rx is not successful */ + if(rx_status & E_MMAC_RXSTAT_ABORTED) { + RIMESTATS_ADD(badsynch); + } else if(rx_status & E_MMAC_RXSTAT_ERROR) { + RIMESTATS_ADD(badcrc); + } else if(rx_status & E_MMAC_RXSTAT_MALFORMED) { + RIMESTATS_ADD(toolong); + } + } + } + if(overflow) { + off(); + } else if(MICROMAC_CONF_ALWAYS_ON + && (mac_event & (E_MMAC_INT_TX_COMPLETE | E_MMAC_INT_RX_COMPLETE))) { + on(); + } +} +/*---------------------------------------------------------------------------*/ +PROCESS_THREAD(micromac_radio_process, ev, data) +{ + PROCESS_BEGIN(); + + while(1) { + PROCESS_YIELD_UNTIL(ev == PROCESS_EVENT_POLL); + + /* Pass received packets to upper layer */ + int16_t read_index; + /* Loop on accessing (without removing) a pending input packet */ + while((read_index = ringbufindex_peek_get(&input_ringbuf)) != -1) { + input_frame_buffer = &input_array[read_index]; + /* Put packet into packetbuf for input callback */ + packetbuf_clear(); + int len = read(packetbuf_dataptr(), PACKETBUF_SIZE); + /* is packet valid? */ + if(len > 0) { + packetbuf_set_datalen(len); + NETSTACK_RDC.input(); + } + /* Remove packet from ringbuf */ + ringbufindex_get(&input_ringbuf); + /* Disable further read attempts */ + input_frame_buffer->u8PayloadLength = 0; + } + + /* Are we recovering from overflow? */ + if(rx_frame_buffer == NULL) { + /* get pointer to next input slot */ + int put_index = ringbufindex_peek_put(&input_ringbuf); + /* is there space? */ + if(put_index != -1) { + /* move rx_frame_buffer to next empty slot */ + rx_frame_buffer = &input_array[put_index]; + /* do we need to turn radio on? */ + if(MICROMAC_CONF_ALWAYS_ON || missed_radio_on_request) { + missed_radio_on_request = 0; + on(); + } + } else { + rx_frame_buffer = NULL; + } + } + } + PROCESS_END(); +} +/*---------------------------------------------------------------------------*/ +static void +set_frame_filtering(uint8_t enable) +{ + frame_filtering = enable; +} +/*---------------------------------------------------------------------------*/ +static void +set_autoack(uint8_t enable) +{ + autoack_enabled = enable; +} +/*---------------------------------------------------------------------------*/ +static void +set_poll_mode(uint8_t enable) +{ + poll_mode = enable; + if(poll_mode) { + /* Disable interrupts */ + vMMAC_EnableInterrupts(NULL); + vMMAC_ConfigureInterruptSources(0); + } else { + /* Initialize and enable interrupts */ + /* TODO: enable E_MMAC_INT_RX_HEADER & filter out frames after header rx */ + vMMAC_ConfigureInterruptSources( + E_MMAC_INT_RX_COMPLETE | E_MMAC_INT_TX_COMPLETE); + vMMAC_EnableInterrupts(&radio_interrupt_handler); + } +} +/* Enable or disable CCA before sending */ +static void +set_send_on_cca(uint8_t enable) +{ + send_on_cca = enable; +} +/*---------------------------------------------------------------------------*/ +static radio_result_t +get_value(radio_param_t param, radio_value_t *value) +{ + int i, v; + + if(!value) { + return RADIO_RESULT_INVALID_VALUE; + } + switch(param) { + case RADIO_PARAM_POWER_MODE: + *value = listen_on || tx_in_progress ? RADIO_POWER_MODE_ON : RADIO_POWER_MODE_OFF; + return RADIO_RESULT_OK; + case RADIO_PARAM_CHANNEL: + *value = get_channel(); + return RADIO_RESULT_OK; + case RADIO_PARAM_RX_MODE: + *value = 0; + if(frame_filtering) { + *value |= RADIO_RX_MODE_ADDRESS_FILTER; + } + if(autoack_enabled) { + *value |= RADIO_RX_MODE_AUTOACK; + } + if(poll_mode) { + *value |= RADIO_RX_MODE_POLL_MODE; + } + return RADIO_RESULT_OK; + case RADIO_PARAM_TX_MODE: + *value = 0; + if(send_on_cca) { + *value |= RADIO_TX_MODE_SEND_ON_CCA; + } + return RADIO_RESULT_OK; + case RADIO_PARAM_TXPOWER: + *value = get_txpower(); + return RADIO_RESULT_OK; + case RADIO_PARAM_RSSI: + *value = get_rssi(); + return RADIO_RESULT_OK; + case RADIO_PARAM_LAST_RSSI: + *value = radio_last_rssi; + return RADIO_RESULT_OK; + case RADIO_PARAM_CCA_THRESHOLD: + *value = cca_thershold; + return RADIO_RESULT_OK; + case RADIO_CONST_CHANNEL_MIN: + *value = 11; + return RADIO_RESULT_OK; + case RADIO_CONST_CHANNEL_MAX: + *value = 26; + return RADIO_RESULT_OK; + case RADIO_CONST_TXPOWER_MIN: + *value = OUTPUT_POWER_MIN; + return RADIO_RESULT_OK; + case RADIO_CONST_TXPOWER_MAX: + *value = OUTPUT_POWER_MAX; + return RADIO_RESULT_OK; + default: + return RADIO_RESULT_NOT_SUPPORTED; + } +} +/*---------------------------------------------------------------------------*/ +static radio_result_t +set_value(radio_param_t param, radio_value_t value) +{ + int i; + + switch(param) { + case RADIO_PARAM_POWER_MODE: + if(value == RADIO_POWER_MODE_ON) { + on(); + return RADIO_RESULT_OK; + } + if(value == RADIO_POWER_MODE_OFF) { + off(); + return RADIO_RESULT_OK; + } + return RADIO_RESULT_INVALID_VALUE; + case RADIO_PARAM_CHANNEL: + if(value < 11 || value > 26) { + return RADIO_RESULT_INVALID_VALUE; + } + set_channel(value); + return RADIO_RESULT_OK; + case RADIO_PARAM_RX_MODE: + if(value & ~(RADIO_RX_MODE_ADDRESS_FILTER | + RADIO_RX_MODE_AUTOACK | RADIO_RX_MODE_POLL_MODE)) { + return RADIO_RESULT_INVALID_VALUE; + } + set_frame_filtering((value & RADIO_RX_MODE_ADDRESS_FILTER) != 0); + set_autoack((value & RADIO_RX_MODE_AUTOACK) != 0); + set_poll_mode((value & RADIO_RX_MODE_POLL_MODE) != 0); + return RADIO_RESULT_OK; + case RADIO_PARAM_TX_MODE: + if(value & ~(RADIO_TX_MODE_SEND_ON_CCA)) { + return RADIO_RESULT_INVALID_VALUE; + } + set_send_on_cca((value & RADIO_TX_MODE_SEND_ON_CCA) != 0); + return RADIO_RESULT_OK; + case RADIO_PARAM_TXPOWER: + if(value < OUTPUT_POWER_MIN || value > OUTPUT_POWER_MAX) { + return RADIO_RESULT_INVALID_VALUE; + /* Find the closest higher PA_LEVEL for the desired output power */ + } + set_txpower(value); + return RADIO_RESULT_OK; + case RADIO_PARAM_CCA_THRESHOLD: + cca_thershold = value; + return RADIO_RESULT_OK; + default: + return RADIO_RESULT_NOT_SUPPORTED; + } +} +/*---------------------------------------------------------------------------*/ +static radio_result_t +get_object(radio_param_t param, void *dest, size_t size) +{ + if(param == RADIO_PARAM_LAST_PACKET_TIMESTAMP) { + if(size != sizeof(rtimer_clock_t) || !dest) { + return RADIO_RESULT_INVALID_VALUE; + } + *(rtimer_clock_t *)dest = get_packet_timestamp(); + + return RADIO_RESULT_OK; + } + return RADIO_RESULT_NOT_SUPPORTED; +} +/*---------------------------------------------------------------------------*/ +static radio_result_t +set_object(radio_param_t param, const void *src, size_t size) +{ + return RADIO_RESULT_NOT_SUPPORTED; +} +/*---------------------------------------------------------------------------*/ +const struct radio_driver micromac_radio_driver = { + init, + prepare, + transmit, + send, + read, + cca, + receiving_packet, + pending_packet, + on, + off, + get_value, + set_value, + get_object, + set_object +}; diff --git a/platform/jn516x/dev/micromac-radio.h b/platform/jn516x/dev/micromac-radio.h new file mode 100644 index 000000000..a283af23d --- /dev/null +++ b/platform/jn516x/dev/micromac-radio.h @@ -0,0 +1,48 @@ +/* + * Copyright (c) 2014, NXP and SICS Swedish ICT. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the Institute nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * This file is part of the Contiki operating system. + * + */ + +/** + * \file + * MICROMAC_RADIO driver header file + * \authors + * Beshr Al Nahas + * Simon Duquennot + */ + +#ifndef MICROMAC_RADIO_H_ +#define MICROMAC_RADIO_H_ + +#include "dev/radio.h" + +extern const struct radio_driver micromac_radio_driver; + +#endif /* MICROMAC_RADIO_H_ */ diff --git a/platform/jn516x/dev/mtarch.c b/platform/jn516x/dev/mtarch.c new file mode 100644 index 000000000..c3c81457e --- /dev/null +++ b/platform/jn516x/dev/mtarch.c @@ -0,0 +1,72 @@ +/* + * Copyright (c) 2008 + * Telecooperation Office (TecO), Universitaet Karlsruhe (TH), Germany. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials provided + * with the distribution. + * 3. Neither the name of the Universitaet Karlsruhe (TH) nor the names + * of its contributors may be used to endorse or promote products + * derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * Author(s): Philipp Scholl + */ + +/* Copied from Philipp Scholl's (BSD) Contiki port to Jennic */ + +#include "mtarch.h" + +void +mtarch_init(void) +{ +} +void +mtarch_remove(void) +{ +} +void +mtarch_start(struct mtarch_thread *thread, + void (*function)(void *data), + void *data) +{ +} +void +mtarch_yield(void) +{ +} +void +mtarch_exec(struct mtarch_thread *thread) +{ +} +void +mtarch_stop(struct mtarch_thread *thread) +{ +} +void +mtarch_pstart(void) +{ +} +void +mtarch_pstop(void) +{ +} diff --git a/platform/jn516x/dev/mtarch.h b/platform/jn516x/dev/mtarch.h new file mode 100644 index 000000000..3c6292f1d --- /dev/null +++ b/platform/jn516x/dev/mtarch.h @@ -0,0 +1,44 @@ +/* + * Copyright (c) 2008 + * Telecooperation Office (TecO), Universitaet Karlsruhe (TH), Germany. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials provided + * with the distribution. + * 3. Neither the name of the Universitaet Karlsruhe (TH) nor the names + * of its contributors may be used to endorse or promote products + * derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * Author(s): Philipp Scholl + */ + +/* Copied from Philipp Scholl's (BSD) Contiki port to Jennic */ + +#ifndef __MTARCH_H__ +#define __MTARCH_H__ + +struct mtarch_thread { + void *mt_thread; +}; + +#endif /* __MTARCH_H__ */ diff --git a/platform/jn516x/dev/node-id.c b/platform/jn516x/dev/node-id.c new file mode 100644 index 000000000..d0e95d521 --- /dev/null +++ b/platform/jn516x/dev/node-id.c @@ -0,0 +1,61 @@ +/* + * Copyright (c) 2014, SICS Swedish ICT. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the Institute nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * This file is part of the Contiki operating system. + * + */ + +/** + * \file + * For compatibility with Contiki node-id interface + * + * \author + * Beshr Al Nahas + */ + +#include "contiki.h" +#include "sys/node-id.h" +#include "contiki-conf.h" + +/*---------------------------------------------------------------------------*/ +extern unsigned char node_mac[8]; +unsigned short node_id = 0; +/*---------------------------------------------------------------------------*/ +void +node_id_restore(void) +{ + /* base node-id on MAC address */ + node_id = (node_mac[6] << 8) | node_mac[7]; +} +/*---------------------------------------------------------------------------*/ +void +node_id_burn(unsigned short id) +{ + /* does not burn anything */ + node_id = id; +} diff --git a/platform/jn516x/dev/rtimer-arch.c b/platform/jn516x/dev/rtimer-arch.c new file mode 100644 index 000000000..f89b8a9a8 --- /dev/null +++ b/platform/jn516x/dev/rtimer-arch.c @@ -0,0 +1,138 @@ +/* + * Copyright (c) 2014, SICS Swedish ICT. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the Institute nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * This file is part of the Contiki operating system. + * + */ + +/** + * \file + * RTIMER for NXP jn516x + * \author + * Beshr Al Nahas + */ + +#include "sys/rtimer.h" +#include "sys/clock.h" +#include +#include +#include "dev/watchdog.h" +#include "sys/energest.h" + +#define RTIMER_TIMER_ISR_DEV E_AHI_DEVICE_TICK_TIMER + +#define DEBUG 0 +#if DEBUG +#include +#define PRINTF(...) printf(__VA_ARGS__) +#else +#define PRINTF(...) +#endif + +static volatile uint32_t compare_time; +static volatile uint32_t last_expired_time; + +void +rtimer_arch_run_next(uint32 u32DeviceId, uint32 u32ItemBitmap) +{ + uint32_t delta, temp; + if(u32DeviceId != RTIMER_TIMER_ISR_DEV) { + return; + } + ENERGEST_ON(ENERGEST_TYPE_IRQ); + vAHI_TickTimerIntPendClr(); + vAHI_TickTimerIntEnable(0); + /* + * compare register is only 28bits wide so make sure the upper 4bits match + * the set compare point + */ + delta = u32AHI_TickTimerRead() - compare_time; + if(0 == (delta >> 28)) { + /* compare_time might change after executing rtimer_run_next() + * as some process might schedule the timer + */ + temp = compare_time; + + /* run scheduled */ + watchdog_start(); + rtimer_run_next(); + + if(process_nevents() > 0) { + /* TODO exit low-power mode */ + } + + watchdog_stop(); + last_expired_time = temp; + } else { + /* No match. Schedule again. */ + vAHI_TickTimerIntEnable(1); + vAHI_TickTimerInterval(compare_time); + } + ENERGEST_OFF(ENERGEST_TYPE_IRQ); +} +/*---------------------------------------------------------------------------*/ +void +rtimer_arch_init(void) +{ + /* Initialise tick timer to run continuously */ + vAHI_TickTimerIntEnable(0); + vAHI_TickTimerConfigure(E_AHI_TICK_TIMER_DISABLE); + last_expired_time = compare_time = 0; + vAHI_TickTimerWrite(0); + vAHI_TickTimerRegisterCallback(rtimer_arch_run_next); + vAHI_TickTimerConfigure(E_AHI_TICK_TIMER_CONT); +} +/*---------------------------------------------------------------------------*/ +rtimer_clock_t +rtimer_arch_now(void) +{ + return u32AHI_TickTimerRead(); +} +/*---------------------------------------------------------------------------*/ +void +rtimer_arch_schedule(rtimer_clock_t t) +{ + PRINTF("rtimer_arch_schedule time %lu\n", t); + vAHI_TickTimerIntPendClr(); + vAHI_TickTimerIntEnable(1); + vAHI_TickTimerInterval(t); + compare_time = t; +} +/*---------------------------------------------------------------------------*/ +rtimer_clock_t +rtimer_arch_get_time_until_next_wakeup(void) +{ + rtimer_clock_t now = RTIMER_NOW(); + rtimer_clock_t next_wakeup = compare_time; + if(bAHI_TickTimerIntStatus()) { + return next_wakeup >= now ? next_wakeup - now : 0; + /* if no wakeup is scheduled yet return maximum time */ + } + return (rtimer_clock_t)-1; +} +/*---------------------------------------------------------------------------*/ diff --git a/platform/jn516x/dev/rtimer-arch.h b/platform/jn516x/dev/rtimer-arch.h new file mode 100644 index 000000000..ec7211262 --- /dev/null +++ b/platform/jn516x/dev/rtimer-arch.h @@ -0,0 +1,59 @@ +/* + * Copyright (c) 2014, SICS Swedish ICT. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the Institute nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * This file is part of the Contiki operating system. + * + */ + +/** + * \file + * Header file for NXP jn516x-specific rtimer code + * \author + * Beshr Al Nahas + */ + +#ifndef RTIMER_ARCH_H_ +#define RTIMER_ARCH_H_ + +#include "sys/rtimer.h" + +#ifdef RTIMER_CONF_SECOND +#define RTIMER_ARCH_SECOND RTIMER_CONF_SECOND +#else +/* 32MHz CPU clock => 16MHz timer */ +#define RTIMER_ARCH_SECOND (F_CPU / 2) +#endif + +#define US_TO_RTIMERTICKS(D) ((int64_t)(D) << 4) +#define RTIMERTICKS_TO_US(T) ((int64_t)(T) >> 4) + +rtimer_clock_t rtimer_arch_now(void); + +rtimer_clock_t rtimer_arch_get_time_until_next_wakeup(void); + +#endif /* RTIMER_ARCH_H_ */ diff --git a/platform/jn516x/dev/slip_uart0.c b/platform/jn516x/dev/slip_uart0.c new file mode 100644 index 000000000..a02791de2 --- /dev/null +++ b/platform/jn516x/dev/slip_uart0.c @@ -0,0 +1,54 @@ +/* + * Copyright (c) 2014, SICS Swedish ICT. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the Institute nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + */ + +/* + * Machine dependent jn516x SLIP routines for UART0. + */ + +#include "contiki-conf.h" +#include "dev/slip.h" +#include "dev/uart0.h" +/*---------------------------------------------------------------------------*/ +void +slip_arch_writeb(unsigned char c) +{ + uart0_writeb(c); +} +/*---------------------------------------------------------------------------*/ +/** + * Initalize the RS232 port and the SLIP driver. + * + */ +void +slip_arch_init(unsigned long ubr) +{ + uart0_set_input(slip_input_byte); +} +/*---------------------------------------------------------------------------*/ diff --git a/platform/jn516x/dev/uart-driver.c b/platform/jn516x/dev/uart-driver.c new file mode 100644 index 000000000..e5a58f0b5 --- /dev/null +++ b/platform/jn516x/dev/uart-driver.c @@ -0,0 +1,605 @@ +/* + * Copyright (c) 2015 NXP B.V. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of NXP B.V. nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY NXP B.V. AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL NXP B.V. OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * This file is part of the Contiki operating system. + * + * Author: Lee Mitchell + * Integrated into Contiki by Beshr Al Nahas + * + */ + +#include + +#ifdef DEBUG +#include +#else +#define DBG_vPrintf(...) +#endif + +#include "contiki-conf.h" +#include "uart-driver.h" +#include "sys/rtimer.h" +#include +#include + +#if UART_XONXOFF_FLOW_CTRL + +#include "sys/process.h" + +#define TX_FIFO_SW_FLOW_LIMIT 8 /* Maximum allowed fill level for tx fifo */ +#if TX_FIFO_SW_FLOW_LIMIT > 16 +#undef TX_FIFO_SW_FLOW_LIMIT +#define TX_FIFO_SW_FLOW_LIMIT 16 +#warning "TX_FIFO_SW_FLOW_LIMIT too big. Forced to 16." +#endif /* TX_FIFO_SW_FLOW_LIMIT > 16 */ + +#define XON 17 +#define XOFF 19 + +extern volatile unsigned char xonxoff_state; + +#endif /* UART_XONXOFF_FLOW_CTRL */ + +/*** Macro Definitions ***/ +#define BUSYWAIT_UNTIL(cond, max_time) \ + do { \ + rtimer_clock_t t0; \ + t0 = RTIMER_NOW(); \ + while(!(cond) && RTIMER_CLOCK_LT(RTIMER_NOW(), t0 + (max_time))) ; \ + } while(0) + +#define DEBUG_UART_BUFFERED FALSE + +#define CHAR_DEADLINE (uart_char_delay * 100) + +/*** Local Function Prototypes ***/ +static void uart_driver_isr(uint32_t device_id, uint32_t item_bitmap); +static int16_t uart_driver_get_tx_fifo_available_space(uint8_t uart_dev); +static void uart_driver_set_baudrate(uint8_t uart_dev, uint8_t br); +static void uart_driver_set_high_baudrate(uint8_t uart_dev, uint32_t baud_rate); + +/*** Local Variables ***/ +#define UART_NUM_UARTS 2 +static uint16_t tx_fifo_size[UART_NUM_UARTS] = { 0 }; +static uint8_t active_uarts[UART_NUM_UARTS] = { 0 }; +/** slip input function pointer */ +static int(*uart_input[UART_NUM_UARTS]) (unsigned char) = { 0 }; +/* time in uSec for transmitting 1 char */ +static uint16_t uart_char_delay = 0; +static volatile int8_t interrupt_enabled[UART_NUM_UARTS] = { 0 }; +static volatile int8_t interrupt_enabled_saved[UART_NUM_UARTS] = { 0 }; + +/**************************************************************************** + * + * NAME: uart_driver_init + * + * DESCRIPTION: + * Initializes the specified UART device. + * + * PARAMETERS: Name RW Usage + * uart_dev R UART to initialise, eg, E_AHI_UART_0 + * br R Baudrate to use (e.g. UART_RATE_115200) + * if br > UART_RATE_115200 + * then uart_driver_set_baud_rate is called + * else vAHI_UartSetClockDivisor + * txbuf_data R Pointer to a memory block to use + * and rxbuf_data as uart tx/rx fifo + * txbuf_size R size of tx fifo (valid range: 16-2047) + * txbuf_size R size of rx fifo (valid range: 16-2047) + * uart_input_function a function pointer to input uart rx bytes + * RETURNS: + * void + * + ****************************************************************************/ +void +uart_driver_init(uint8_t uart_dev, uint8_t br, uint8_t *txbuf_data, + uint16_t txbuf_size, uint8_t *rxbuf_data, uint16_t rxbuf_size, + int (*uart_input_function)(unsigned char c)) +{ +#if !UART_HW_FLOW_CTRL + /* Disable RTS/CTS */ + vAHI_UartSetRTSCTS(uart_dev, FALSE); +#endif + + tx_fifo_size[uart_dev] = txbuf_size; + + /* Configure the selected Uart */ + uint8_t uart_enabled = bAHI_UartEnable(uart_dev, txbuf_data, txbuf_size, + rxbuf_data, rxbuf_size); + /* fallback to internal buffers */ + if(!uart_enabled) { + vAHI_UartEnable(uart_dev); + tx_fifo_size[uart_dev] = 16; /* Fixed size */ + } + /* Reset tx/rx fifos */ + vAHI_UartReset(uart_dev, TRUE, TRUE); + vAHI_UartReset(uart_dev, FALSE, FALSE); + + uart_driver_set_baudrate(uart_dev, br); + + /* install interrupt service callback */ + if(uart_dev == E_AHI_UART_0) { + vAHI_Uart0RegisterCallback((void *)uart_driver_isr); + } else { + vAHI_Uart1RegisterCallback((void *)uart_driver_isr); + /* Enable RX interrupt */ + } + uart_driver_enable_interrupts(uart_dev); + uart_input[uart_dev] = uart_input_function; + active_uarts[uart_dev] = 1; + +#if UART_HW_FLOW_CTRL + /* Configure HW flow control */ + vAHI_UartSetAutoFlowCtrl(uart_dev, E_AHI_UART_FIFO_ARTS_LEVEL_13, /* uint8 const u8RxFifoLevel,*/ + FALSE, /* bool_t const bFlowCtrlPolarity,*/ + TRUE, /* bool_t const bAutoRts, */ + TRUE /* bool_t const bAutoCts */); +#endif + + printf("UART %d init: using %s buffers %d\n", uart_dev, + uart_enabled ? "external" : "internal", tx_fifo_size[uart_dev]); +} +void +uart_driver_enable_interrupts(uint8_t uart_dev) +{ + /* wait while char being tx is done */ + while((u8AHI_UartReadLineStatus(uart_dev) & E_AHI_UART_LS_THRE) == 0) ; + + vAHI_UartSetInterrupt(uart_dev, FALSE /*bEnableModemStatus*/, + FALSE /*bEnableRxLineStatus == Break condition */, + FALSE /*bEnableTxFifoEmpty*/, + TRUE /* bEnableRxData */, E_AHI_UART_FIFO_LEVEL_14); + interrupt_enabled[uart_dev] = 1; +} +void +uart_driver_disable_interrupts(uint8_t uart_dev) +{ + /* wait while char being tx is done */ + while((u8AHI_UartReadLineStatus(uart_dev) & E_AHI_UART_LS_THRE) == 0) ; + + vAHI_UartSetInterrupt(uart_dev, FALSE /*bEnableModemStatus*/, + FALSE /*bEnableRxLineStatus == Break condition */, + FALSE /*bEnableTxFifoEmpty*/, + FALSE /* bEnableRxData */, E_AHI_UART_FIFO_LEVEL_14); + interrupt_enabled[uart_dev] = 0; +} +void +uart_driver_store_interrupts(uint8_t uart_dev) +{ + interrupt_enabled_saved[uart_dev] = interrupt_enabled[uart_dev]; +} +void +uart_driver_restore_interrupts(uint8_t uart_dev) +{ + if(interrupt_enabled_saved[uart_dev]) { + uart_driver_enable_interrupts(uart_dev); + } else { + uart_driver_disable_interrupts(uart_dev); + } +} +int8_t +uart_driver_interrupt_is_enabled(uint8_t uart_dev) +{ + return interrupt_enabled[uart_dev]; +} +void +uart_driver_set_input(uint8_t uart_dev, int + (*uart_input_function)(unsigned char c)) +{ + uart_input[uart_dev] = uart_input_function; +} +/**************************************************************************** + * + * NAME: uart_driver_read + * + * DESCRIPTION: + * Reads 1 byte from the RX buffer. If there is no data in the + * buffer, then return FALSE + * + * PARAMETERS: Name RW Usage + * uart_dev R UART to use, eg, E_AHI_UART_0 + * + * RETURNS: + * TRUE if a byte has been read from the queue + * + ****************************************************************************/ +uint8_t +uart_driver_read(uint8_t uart_dev, uint8_t *data) +{ + if(data && u16AHI_UartReadRxFifoLevel(uart_dev) > 0) { + *data = u8AHI_UartReadData(uart_dev); + return TRUE; + } + return FALSE; +} +void +uart_driver_write_buffered(uint8_t uart_dev, uint8_t ch) +{ + uart_driver_write_with_deadline(uart_dev, ch); +} +/**************************************************************************** + * + * NAME: uart_driver_write_with_deadline + * + * DESCRIPTION: + * Writes one byte to the specified uart for transmission + * + * PARAMETERS: Name RW Usage + * uart_dev R UART to use, eg, E_AHI_UART_0 + * ch R data to transmit + * + * RETURNS: + * void + * + ****************************************************************************/ +void +uart_driver_write_with_deadline(uint8_t uart_dev, uint8_t ch) +{ +#if UART_XONXOFF_FLOW_CTRL + /* Block until host can receive data */ + /* Wait until there are less than N characters in TX FIFO */ + while(xonxoff_state != XON + || u16AHI_UartReadTxFifoLevel(uart_dev) > TX_FIFO_SW_FLOW_LIMIT) { + watchdog_periodic(); + } + /* write to TX FIFO and return immediately */ + vAHI_UartWriteData(uart_dev, ch); +#else /* UART_XONXOFF_FLOW_CTRL */ + volatile int16_t write = 0; + watchdog_periodic(); + /* wait until there is space in tx fifo */ + BUSYWAIT_UNTIL(write = (uart_driver_get_tx_fifo_available_space(uart_dev) > 0), + CHAR_DEADLINE); + /* write only if there is space so we do not get stuck */ + if(write) { + /* write to TX FIFO and return immediately */ + vAHI_UartWriteData(uart_dev, ch); + } +#endif /* UART_XONXOFF_FLOW_CTRL */ +} +void +uart_driver_write_direct(uint8_t uart_dev, uint8_t ch) +{ + /* Write character */ + vAHI_UartWriteData(uart_dev, ch); + /* Wait for buffers to empty */ + while((u8AHI_UartReadLineStatus(uart_dev) & E_AHI_UART_LS_THRE) == 0) ; + while((u8AHI_UartReadLineStatus(uart_dev) & E_AHI_UART_LS_TEMT) == 0) ; +} +/**************************************************************************** + * + * NAME: uart_driver_rx_handler + * + * DESCRIPTION: + * Interrupt service callback for UART data reception. Reads a received + * byte from the UART and writes it to the reception buffer if it is not + * full. + * + * PARAMETERS: Name RW Usage + * uart_dev R Uart to read from + * + * RETURNS: + * void + * + ****************************************************************************/ +void +uart_driver_rx_handler(uint8_t uart_dev) +{ + /* optimization for high throughput: Read upto 32 bytes from RX fifo. + * Disabled because it does not work with current slip_input_byte */ + + /* Status from uart_input: + * 0 means do not exit power saving mode + * -1 means RX buffer overflow ==> stop reading + * 1 means end of slip packet + */ +#if UART_XONXOFF_FLOW_CTRL + /* save old status */ + int xonxoff_state_old = xonxoff_state; +#endif /* UART_XONXOFF_FLOW_CTRL */ + int status = 0; + int c = 0; + while(u16AHI_UartReadRxFifoLevel(uart_dev) > 0 && c++ < 32 && status == 0) { + if(uart_input[uart_dev] != NULL) { /* read one char at a time */ + + /* process received character */ + status = (uart_input[uart_dev])(u8AHI_UartReadData(uart_dev)); + +#if UART_XONXOFF_FLOW_CTRL + /* Process XON-XOFF*/ + if(xonxoff_state == XOFF) { + /* XXX do not set break condition as it corrupts one character, instead we block on TX */ + /* Instruct uart to stop TX */ + /* vAHI_UartSetBreak(uart_dev, TRUE); */ + break; + } else if(xonxoff_state_old == XOFF && xonxoff_state == XON) { + /* Instruct uart to resume TX if it was stopped */ + /* vAHI_UartSetBreak(uart_dev, FALSE); */ + } +#endif /* UART_XONXOFF_FLOW_CTRL */ + } else { + /* no input handler, or no bytes to read: Discard byte. */ + u8AHI_UartReadData(uart_dev); + } + } +} +/****************************************************************************/ +/*** Local Functions ***/ +/****************************************************************************/ + +/* Returns the free space in tx fifo, i.e., how many characters we can put */ +static int16_t +uart_driver_get_tx_fifo_available_space(uint8_t uart_dev) +{ + return tx_fifo_size[uart_dev] - u16AHI_UartReadTxFifoLevel(uart_dev); +} +/* Initializes the specified UART with auto-selection of + baudrate tuning method */ +static void +uart_driver_set_baudrate(uint8_t uart_dev, uint8_t br) +{ + uint32_t high_br = 0; + uint8_t low_br = 0; + + switch(br) { + case UART_RATE_4800: + low_br = E_AHI_UART_RATE_4800; + uart_char_delay = 1667; + break; + case UART_RATE_9600: + low_br = E_AHI_UART_RATE_9600; + uart_char_delay = 834; + break; + case UART_RATE_19200: + low_br = E_AHI_UART_RATE_19200; + uart_char_delay = 417; + break; + case UART_RATE_38400: + low_br = E_AHI_UART_RATE_38400; + uart_char_delay = 209; + break; + case UART_RATE_76800: + low_br = E_AHI_UART_RATE_76800; + uart_char_delay = 105; + break; + case UART_RATE_115200: + low_br = E_AHI_UART_RATE_115200; + uart_char_delay = 69; + break; + case UART_RATE_230400: + high_br = 230400UL; + uart_char_delay = 35; + break; + case UART_RATE_460800: + high_br = 460800UL; + uart_char_delay = 18; + break; + case UART_RATE_500000: + high_br = 500000UL; + uart_char_delay = 16; + break; + case UART_RATE_576000: + high_br = 576000UL; + uart_char_delay = 14; + break; + case UART_RATE_921600: + high_br = 921600UL; + uart_char_delay = 9; + break; + case UART_RATE_1000000: + high_br = 1000000UL; + uart_char_delay = 8; + break; + default: + high_br = 1000000UL; + uart_char_delay = 8; + break; + } + if(high_br == 0) { + vAHI_UartSetClockDivisor(uart_dev, low_br); + } else { + uart_driver_set_high_baudrate(uart_dev, high_br); + } +} +/**************************************************************************** + * + * NAME: uart_driver_set_high_baudrate + * + * DESCRIPTION: + * Sets the baud rate for the specified uart + * + * PARAMETERS: Name RW Usage + * uart_dev R UART to initialise, eg, E_AHI_UART_0 + * baud_rate R Baudrate to use (bps eg 921600) + * + * RETURNS: + * void + * + ****************************************************************************/ +static void +uart_driver_set_high_baudrate(uint8_t uart_dev, uint32_t baud_rate) +{ + uint16 u16Divisor = 1; + uint32_t u32Remainder; + uint8_t u8ClocksPerBit = 16; + +#if (ENABLE_ADVANCED_BAUD_SELECTION) + /* Defining ENABLE_ADVANCED_BAUD_SELECTION in the Makefile + * enables this code which searches for a clocks per bit setting + * that gets closest to the configured rate. + */ + uint32_t u32CalcBaudRate = 0; + int32 i32BaudError = 0x7FFFFFFF; + + DBG_vPrintf(DEBUG_UART_BUFFERED, "Config uart=%d, baud=%d\n", uart_dev, + baud_rate); + + while(abs(i32BaudError) > (int32)(baud_rate >> 4)) { /* 6.25% (100/16) error */ + if(--u8ClocksPerBit < 3) { + DBG_vPrintf(DEBUG_UART_BUFFERED, + "Could not calculate UART settings for target baud!"); + return; + } +#endif /* ENABLE_ADVANCED_BAUD_SELECTION */ + + /* Calculate Divisor register = 16MHz / (16 x baud rate) */ + u16Divisor = (uint16)(16000000UL / ((u8ClocksPerBit + 1) * baud_rate)); + + /* Correct for rounding errors */ + u32Remainder = + (uint32_t)(16000000UL % ((u8ClocksPerBit + 1) * baud_rate)); + + if(u32Remainder >= (((u8ClocksPerBit + 1) * baud_rate) / 2)) { + u16Divisor += 1; + } +#if (ENABLE_ADVANCED_BAUD_SELECTION) + DBG_vPrintf(DEBUG_UART_BUFFERED, "Divisor=%d, cpb=%d\n", u16Divisor, + u8ClocksPerBit); + + u32CalcBaudRate = (16000000UL / ((u8ClocksPerBit + 1) * u16Divisor)); + + DBG_vPrintf(DEBUG_UART_BUFFERED, "Calculated baud=%d\n", u32CalcBaudRate); + + i32BaudError = (int32)u32CalcBaudRate - (int32)baud_rate; + + DBG_vPrintf(DEBUG_UART_BUFFERED, "Error baud=%d\n", i32BaudError); +} +DBG_vPrintf(DEBUG_UART_BUFFERED, "Config uart=%d: Divisor=%d, cpb=%d\n", + uart_dev, u16Divisor, u8ClocksPerBit); + +/* Set the calculated clocks per bit */ +vAHI_UartSetClocksPerBit(uart_dev, u8ClocksPerBit); +#endif /* ENABLE_ADVANCED_BAUD_SELECTION */ + + /* Set the calculated divisor */ + vAHI_UartSetBaudDivisor(uart_dev, u16Divisor); +} + +/**************************************************************************** + * + * NAME: uart_driver_isr + * + * DESCRIPTION: + * Interrupt service callback for UART's + * + * PARAMETERS: Name RW Usage + * device_id R Device ID of whatever generated the + * interrupt + * item_bitmap R Which part of the device generated + * the interrupt + * + * RETURNS: + * void + * + ****************************************************************************/ +static void +uart_driver_isr(uint32_t device_id, uint32_t item_bitmap) +{ + uint8_t uart_dev; + switch(device_id) { + case E_AHI_DEVICE_UART0: + uart_dev = E_AHI_UART_0; + break; + case E_AHI_DEVICE_UART1: + uart_dev = E_AHI_UART_1; + break; + default: + return; + } + switch(item_bitmap) { + /* byte available since a long time but RX-fifo not full: */ + case E_AHI_UART_INT_TIMEOUT: + /* RX-fifo full: */ + case E_AHI_UART_INT_RXDATA: + uart_driver_rx_handler(uart_dev); + break; + case E_AHI_UART_INT_TX: + break; + case E_AHI_UART_INT_RXLINE: + /* rx-line interrupt is disabled. Should not get here */ + /* An error condition has occurred on the RxD line, such as + a break indication, framing error, parity error or over-run. */ + break; + } +} +/**************************************************************************** + * + * NAME: uart_driver_tx_in_progress + * + * DESCRIPTION: + * Returns the state of data transmission + * + * PARAMETERS: Name RW Usage + * uart_dev R UART to use, eg, E_AHI_UART_0 + * + * RETURNS: + * uint8_t: TRUE if data in buffer is being transmitted + * FALSE if all data in buffer has been transmitted by the UART + * + ****************************************************************************/ +uint8_t +uart_driver_tx_in_progress(uint8_t uart_dev) +{ + + if(u16AHI_UartReadTxFifoLevel(uart_dev) == 0) { + if((u8AHI_UartReadLineStatus(uart_dev) & E_AHI_UART_LS_TEMT) != 0) { + return FALSE; + } + } + return TRUE; +} +#ifdef UART_EXTRAS + +/**************************************************************************** + * + * NAME: uart_driver_flush + * + * DESCRIPTION: + * Flushes the buffers of the specified UART + * + * PARAMETERS: Name RW Usage + * uart_dev R UART to disable, eg, E_AHI_UART_0 + * + * RETURNS: + * void + * + ****************************************************************************/ +void +uart_driver_flush(uint8_t uart_dev) +{ + /* Disable TX Fifo empty and Rx data interrupts */ + uart_driver_disable_interrupts(uart_dev); + + /* flush hardware buffer */ + vAHI_UartReset(uart_dev, TRUE, TRUE); + vAHI_UartReset(uart_dev, FALSE, FALSE); + + /* Re-enable TX Fifo empty and Rx data interrupts */ + uart_driver_enable_interrupts(uart_dev); +} +#endif /* UART_EXTRAS */ diff --git a/platform/jn516x/dev/uart-driver.h b/platform/jn516x/dev/uart-driver.h new file mode 100644 index 000000000..322bf950d --- /dev/null +++ b/platform/jn516x/dev/uart-driver.h @@ -0,0 +1,62 @@ +/* + * Copyright (c) 2015 NXP B.V. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of NXP B.V. nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY NXP B.V. AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL NXP B.V. OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * This file is part of the Contiki operating system. + * + * Author: Lee Mitchell + * Integrated into Contiki by Beshr Al Nahas + * + */ + +#ifndef UARTDRIVER_H +#define UARTDRIVER_H + +#include +#include "contiki-conf.h" + +void uart_driver_init(uint8_t uart_dev, uint8_t br, uint8_t * txbuf_data, uint16_t txbuf_size, uint8_t * rxbuf_data, uint16_t rxbuf_size, int (*uart_input_function)(unsigned char c)); +void uart_driver_write_buffered(uint8_t uart_dev, uint8_t ch); +void uart_driver_write_with_deadline(uint8_t uart_dev, uint8_t c); +uint8_t uart_driver_read(uint8_t uart_dev, uint8_t *data); +void uart_driver_write_direct(uint8_t uart_dev, uint8_t ch); +void uart_driver_set_input(uint8_t u8Uart, int (*uart_input_function)(unsigned char c)); + +void uart_driver_rx_handler(uint8_t uart_dev); +void uart_driver_enable_interrupts(uint8_t uart_dev); +void uart_driver_disable_interrupts(uint8_t uart_dev); +int8_t uart_driver_interrupt_is_enabled(uint8_t uart_dev); +void uart_driver_store_interrupts(uint8_t uart_dev); +void uart_driver_restore_interrupts(uint8_t uart_dev); + +uint8_t uart_driver_tx_in_progress(uint8_t uart_dev); + +#ifdef UART_EXTRAS +void uart_driver_flush(uint8_t uart_dev); +#endif + +#endif /* UARTDRIVER_H */ diff --git a/platform/jn516x/dev/uart0.c b/platform/jn516x/dev/uart0.c new file mode 100644 index 000000000..58432abcc --- /dev/null +++ b/platform/jn516x/dev/uart0.c @@ -0,0 +1,75 @@ +/* + * Copyright (c) 2014, SICS Swedish ICT. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the Institute nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * This file is part of the Contiki operating system. + * + */ + +/** + * \file + * UART0 drivers + * \author + * Beshr Al Nahas + * + */ + +#include +#include +#include +#include "contiki-conf.h" +#include "dev/uart0.h" +#include "uart-driver.h" + +/* Valid range for TXBUFSIZE and RXBUFSIZE: 16-2047 */ + +static unsigned char txbuf_data[UART_TX_BUFFER_SIZE]; +static unsigned char rxbuf_data[UART_RX_BUFFER_SIZE]; +static int (*uart0_input)(unsigned char c); + +uint8_t +uart0_active(void) +{ + return uart_driver_tx_in_progress(E_AHI_UART_0); +} +void +uart0_set_input(int + (*input)(unsigned char c)) +{ + uart0_input = input; + uart_driver_set_input(E_AHI_UART_0, uart0_input); +} +void +uart0_writeb(unsigned char c) +{ + uart_driver_write_buffered(E_AHI_UART_0, c); +} +void +uart0_init(uint8_t br) +{ + uart_driver_init(E_AHI_UART_0, br, txbuf_data, UART_TX_BUFFER_SIZE, rxbuf_data, UART_RX_BUFFER_SIZE, uart0_input); +} diff --git a/platform/jn516x/dev/uart0.h b/platform/jn516x/dev/uart0.h new file mode 100644 index 000000000..293950c5b --- /dev/null +++ b/platform/jn516x/dev/uart0.h @@ -0,0 +1,75 @@ +/* + * Copyright (c) 2014, SICS Swedish ICT. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the Institute nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * This file is part of the Contiki operating system. + * + */ + +/** + * \file + * UART0 drivers + * \author + * Beshr Al Nahas + * + */ + +#ifndef __UART0_H__ +#define __UART0_H__ + +#include +#include "contiki-conf.h" + +#define UART_DEFAULT_RX_BUFFER_SIZE 2047 +#if UART_XONXOFF_FLOW_CTRL +#define UART_DEFAULT_TX_BUFFER_SIZE 64 +#else +#define UART_DEFAULT_TX_BUFFER_SIZE 1281 +#endif +#ifdef UART_CONF_TX_BUFFER_SIZE +#define UART_TX_BUFFER_SIZE UART_CONF_TX_BUFFER_SIZE +#else +#define UART_TX_BUFFER_SIZE UART_DEFAULT_TX_BUFFER_SIZE +#endif +#ifdef UART_CONF_RX_BUFFER_SIZE +#define UART_RX_BUFFER_SIZE UART_CONF_RX_BUFFER_SIZE +#else +#define UART_RX_BUFFER_SIZE UART_DEFAULT_RX_BUFFER_SIZE +#endif +void uart0_set_input(int (*input)(unsigned char c)); +void uart0_writeb(unsigned char c); +void uart0_init(unsigned char br); + +#define uart0_write_direct(c) uart_driver_write_direct(E_AHI_UART_0, (c)) +#define uart0_disable_interrupts() uart_driver_disable_interrupts(E_AHI_UART_0) +#define uart0_enable_interrupts() uart_driver_enable_interrupts(E_AHI_UART_0) +#define uart0_restore_interrupts() uart_driver_restore_interrupts(E_AHI_UART_0) +#define uart0_store_interrupts() uart_driver_store_interrupts(E_AHI_UART_0) + +uint8_t uart0_active(void); + +#endif diff --git a/platform/jn516x/dev/uart1.c b/platform/jn516x/dev/uart1.c new file mode 100644 index 000000000..7f4c1fa8f --- /dev/null +++ b/platform/jn516x/dev/uart1.c @@ -0,0 +1,73 @@ +/* + * Copyright (c) 2014, SICS Swedish ICT. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the Institute nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * This file is part of the Contiki operating system. + * + */ + +/** + * \file + * UART1 drivers + * \author + * Beshr Al Nahas + * + */ + +#include +#include +#include +#include "contiki-conf.h" +#include "dev/uart1.h" +#include "uart-driver.h" + +static unsigned char txbuf_data[UART1_TX_BUFFER_SIZE]; +static unsigned char rxbuf_data[UART1_RX_BUFFER_SIZE]; +static int (*uart1_input)(unsigned char c); + +uint8_t +uart1_active(void) +{ + return uart_driver_tx_in_progress(E_AHI_UART_1); +} +void +uart1_set_input(int + (*input)(unsigned char c)) +{ + uart1_input = input; + uart_driver_set_input(E_AHI_UART_1, uart1_input); +} +void +uart1_writeb(unsigned char c) +{ + uart_driver_write_buffered(E_AHI_UART_1, c); +} +void +uart1_init(uint8_t br) +{ + uart_driver_init(E_AHI_UART_1, br, txbuf_data, UART1_TX_BUFFER_SIZE, rxbuf_data, UART1_RX_BUFFER_SIZE, uart1_input); +} diff --git a/platform/jn516x/dev/uart1.h b/platform/jn516x/dev/uart1.h new file mode 100644 index 000000000..2fdc207ca --- /dev/null +++ b/platform/jn516x/dev/uart1.h @@ -0,0 +1,77 @@ +/* + * Copyright (c) 2014, SICS Swedish ICT. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the Institute nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * This file is part of the Contiki operating system. + * + */ + +/** + * \file + * UART1 drivers + * \author + * Beshr Al Nahas + * + */ + +#ifndef __UART1_H__ +#define __UART1_H__ + +#include +#include "contiki-conf.h" + +/* Default buffer size + Valid range for TX_BUFFER_SIZE and RX_BUFFER_SIZE: 16-2047 */ +#define UART1_DEFAULT_RX_BUFFER_SIZE 16 +#define UART1_DEFAULT_TX_BUFFER_SIZE 16 + +/* Buffer size selection */ +#ifdef UART1_CONF_TX_BUFFER_SIZE +#define UART1_TX_BUFFER_SIZE UART1_CONF_TX_BUFFER_SIZE +#else +#define UART1_TX_BUFFER_SIZE UART1_DEFAULT_TX_BUFFER_SIZE +#endif + +#ifdef UART1_CONF_RX_BUFFER_SIZE +#define UART1_RX_BUFFER_SIZE UART1_CONF_RX_BUFFER_SIZE +#else +#define UART1_RX_BUFFER_SIZE UART1_DEFAULT_RX_BUFFER_SIZE +#endif + +void uart1_set_input(int (*input)(unsigned char c)); +void uart1_writeb(unsigned char c); +void uart1_init(unsigned char br); + +#define uart1_write_direct(c) uart_driver_write_direct(E_AHI_UART_1, (c)) +#define uart1_disable_interrupts() uart_driver_disable_interrupts(E_AHI_UART_1) +#define uart1_enable_interrupts() uart_driver_enable_interrupts(E_AHI_UART_1) +#define uart1_restore_interrupts() uart_driver_restore_interrupts(E_AHI_UART_1) +#define uart1_store_interrupts() uart_driver_store_interrupts(E_AHI_UART_1) + +uint8_t uart1_active(void); + +#endif diff --git a/platform/jn516x/dev/watchdog.c b/platform/jn516x/dev/watchdog.c new file mode 100644 index 000000000..395106fd3 --- /dev/null +++ b/platform/jn516x/dev/watchdog.c @@ -0,0 +1,90 @@ +/* + * Copyright (c) 2014, SICS Swedish ICT. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the Institute nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * This file is part of the Contiki operating system. + * + */ + +/** + * \file + * JN516X watchdog support. + * \author + * Beshr Al Nahas + * + */ + +#include "dev/watchdog.h" +#include "AppHardwareApi.h" + +/*---------------------------------------------------------------------------*/ +static int counter = 0; + +/*---------------------------------------------------------------------------*/ +void +watchdog_init(void) +{ + counter = 0; + watchdog_stop(); + /* enable WDT interrupt */ + vAHI_WatchdogException(1); +} +/*---------------------------------------------------------------------------*/ +void +watchdog_start(void) +{ + /* We setup the watchdog to reset the device after two seconds, + unless watchdog_periodic() is called. */ + counter--; + if(counter == 0) { + vAHI_WatchdogStart(9); /* about 8*2^(9-1)ms=2.048s timeout */ + } +} +/*---------------------------------------------------------------------------*/ +void +watchdog_periodic(void) +{ + /* This function is called periodically to restart the watchdog + timer. */ + vAHI_WatchdogRestart(); +} +/*---------------------------------------------------------------------------*/ +void +watchdog_stop(void) +{ + counter++; + if(counter == 1) { + vAHI_WatchdogStop(); + } +} +/*---------------------------------------------------------------------------*/ +void +watchdog_reboot(void) +{ + vAHI_SwReset(); +} +/*---------------------------------------------------------------------------*/ diff --git a/platform/jn516x/lib/log.c b/platform/jn516x/lib/log.c new file mode 100644 index 000000000..adf85ec1a --- /dev/null +++ b/platform/jn516x/lib/log.c @@ -0,0 +1,56 @@ +/* + * Copyright (c) 2015, SICS Swedish ICT. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials provided + * with the distribution. + * 3. The name of the author may not be used to endorse or promote + * products derived from this software without specific prior + * written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE + * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * This file is part of the Contiki OS + * + */ + +#include +#include + +#include "net/ip/uip.h" +#include "sys/log.h" + +/*---------------------------------------------------------------------------*/ +#if LOG_CONF_ENABLED +void +log_message(char *m1, char *m2) +{ + printf("%s%s\n", m1, m2); +} +#endif /* LOG_CONF_ENABLED */ +/*---------------------------------------------------------------------------*/ +#if UIP_LOGGING +void +uip_log(char *m) +{ + printf("uip_log: %s\n", m); +} +#endif /* UIP_LOGGING */ +/*---------------------------------------------------------------------------*/ diff --git a/platform/jn516x/lib/ringbufindex.c b/platform/jn516x/lib/ringbufindex.c new file mode 100644 index 000000000..0b2149ff7 --- /dev/null +++ b/platform/jn516x/lib/ringbufindex.c @@ -0,0 +1,149 @@ +/* + * Copyright (c) 2015, SICS Swedish ICT. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the Institute nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * This file is part of the Contiki operating system. + * + */ + +/** + * \file + * ringbufindex library. Implements basic support for ring buffers + * of any type, as opposed to the core/lib/ringbuf module which + * is only for byte arrays. Simply returns index in the ringbuf + * rather than actual elements. The ringbuf size must be power of two. + * Like the original ringbuf, this module implements atomic put and get. + * \author + * Simon Duquennoy + * based on Contiki's core/lib/ringbuf library by Adam Dunkels + */ + +#include +#include "lib/ringbufindex.h" + +/* Initialize a ring buffer. The size must be a power of two */ +void +ringbufindex_init(struct ringbufindex *r, uint8_t size) +{ + r->mask = size - 1; + r->put_ptr = 0; + r->get_ptr = 0; +} +/* Put one element to the ring buffer */ +int +ringbufindex_put(struct ringbufindex *r) +{ + /* Check if buffer is full. If it is full, return 0 to indicate that + the element was not inserted. + + XXX: there is a potential risk for a race condition here, because + the ->get_ptr field may be written concurrently by the + ringbufindex_get() function. To avoid this, access to ->get_ptr must + be atomic. We use an uint8_t type, which makes access atomic on + most platforms, but C does not guarantee this. + */ + if(((r->put_ptr - r->get_ptr) & r->mask) == r->mask) { + return 0; + } + r->put_ptr = (r->put_ptr + 1) & r->mask; + return 1; +} +/* Check if there is space to put an element. + * Return the index where the next element is to be added */ +int +ringbufindex_peek_put(const struct ringbufindex *r) +{ + /* Check if there are bytes in the buffer. If so, we return the + first one. If there are no bytes left, we return -1. + */ + if(((r->put_ptr - r->get_ptr) & r->mask) == r->mask) { + return -1; + } + return (r->put_ptr + 1) & r->mask; +} +/* Remove the first element and return its index */ +int +ringbufindex_get(struct ringbufindex *r) +{ + int get_ptr; + + /* Check if there are bytes in the buffer. If so, we return the + first one and increase the pointer. If there are no bytes left, we + return -1. + + XXX: there is a potential risk for a race condition here, because + the ->put_ptr field may be written concurrently by the + ringbufindex_put() function. To avoid this, access to ->get_ptr must + be atomic. We use an uint8_t type, which makes access atomic on + most platforms, but C does not guarantee this. + */ + if(((r->put_ptr - r->get_ptr) & r->mask) > 0) { + get_ptr = r->get_ptr; + r->get_ptr = (r->get_ptr + 1) & r->mask; + return get_ptr; + } else { + return -1; + } +} +/* Return the index of the first element + * (which will be removed if calling ringbufindex_peek) */ +int +ringbufindex_peek_get(const struct ringbufindex *r) +{ + /* Check if there are bytes in the buffer. If so, we return the + first one. If there are no bytes left, we return -1. + */ + if(((r->put_ptr - r->get_ptr) & r->mask) > 0) { + return (r->get_ptr + 1) & r->mask; + } else { + return -1; + } +} +/* Return the ring buffer size */ +int +ringbufindex_size(const struct ringbufindex *r) +{ + return r->mask + 1; +} +/* Return the number of elements currently in the ring buffer */ +int +ringbufindex_elements(const struct ringbufindex *r) +{ + return (r->put_ptr - r->get_ptr) & r->mask; +} +/* Is the ring buffer full? */ +int +ringbufindex_full(const struct ringbufindex *r) +{ + return ((r->put_ptr - r->get_ptr) & r->mask) == r->mask; +} +/* Is the ring buffer empty? */ +int +ringbufindex_empty(const struct ringbufindex *r) +{ + return ringbufindex_elements(r) == 0; +} diff --git a/platform/jn516x/lib/ringbufindex.h b/platform/jn516x/lib/ringbufindex.h new file mode 100644 index 000000000..c39f99d18 --- /dev/null +++ b/platform/jn516x/lib/ringbufindex.h @@ -0,0 +1,72 @@ +/* + * Copyright (c) 2015, SICS Swedish ICT. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the Institute nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * This file is part of the Contiki operating system. + * + */ + +/** + * \file + * Header file for the ringbufindex library + * \author + * Simon Duquennoy + */ + +#ifndef __RINGBUFINDEX_H__ +#define __RINGBUFINDEX_H__ + +#include "contiki-conf.h" + +struct ringbufindex { + uint8_t mask; + /* These must be 8-bit quantities to avoid race conditions. */ + uint8_t put_ptr, get_ptr; +}; + +/* Initialize a ring buffer. The size must be a power of two */ +void ringbufindex_init(struct ringbufindex *r, uint8_t size); +/* Put one element to the ring buffer */ +int ringbufindex_put(struct ringbufindex *r); +/* Check if there is space to put an element. + * Return the index where the next element is to be added */ +int ringbufindex_peek_put(const struct ringbufindex *r); +/* Remove the first element and return its index */ +int ringbufindex_get(struct ringbufindex *r); +/* Return the index of the first element + * (which will be removed if calling ringbufindex_peek) */ +int ringbufindex_peek_get(const struct ringbufindex *r); +/* Return the ring buffer size */ +int ringbufindex_size(const struct ringbufindex *r); +/* Return the number of elements currently in the ring buffer */ +int ringbufindex_elements(const struct ringbufindex *r); +/* Is the ring buffer full? */ +int ringbufindex_full(const struct ringbufindex *r); +/* Is the ring buffer empty? */ +int ringbufindex_empty(const struct ringbufindex *r); + +#endif /* __RINGBUFINDEX_H__ */ diff --git a/platform/jn516x/lib/slip.c b/platform/jn516x/lib/slip.c new file mode 100644 index 000000000..31828e7e3 --- /dev/null +++ b/platform/jn516x/lib/slip.c @@ -0,0 +1,447 @@ +/* + * Copyright (c) 2014, SICS Swedish ICT. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the Institute nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * This file is part of the Contiki operating system. + * + */ + +/** + * \file + * Alternative implementation for SLIP: + * 1. Accepts more than two packet + * 2. Disables UART rx interrupt when buffer is full + * (thus invoking flow control if configured) + * \author + * Niklas Finne + * Beshr Al Nahas + * + */ + +#include "contiki.h" + +#include +#include "net/ip/uip.h" +#include "net/ipv4/uip-fw.h" +#define BUF ((struct uip_tcpip_hdr *)&uip_buf[UIP_LLH_LEN]) + +#include "dev/slip.h" + +#define DEBUG 0 +#if DEBUG +#include +#define PRINTF(...) printf(__VA_ARGS__) +#define PUTCHAR(X) do { putchar(X); putchar('\n'); } while(0) +#else +#define PRINTF(...) do {} while(0) +#define PUTCHAR(X) do {} while(0) +#endif + +#define SLIP_END 0300 +#define SLIP_ESC 0333 +#define SLIP_ESC_END 0334 +#define SLIP_ESC_ESC 0335 +#define SLIP_NEUTRAL 0 /* means: none of the above */ +#define SLIP_ESC_XON 0336 +#define SLIP_ESC_XOFF 0337 +#define XON ((unsigned char)17) +#define XOFF ((unsigned char)19) +#if UART_XONXOFF_FLOW_CTRL +volatile unsigned char xonxoff_state = XON; +#endif /* UART_XONXOFF_FLOW_CTRL */ + +PROCESS(slip_process, "SLIP driver"); + +#include "dev/uart0.h" +#define STORE_UART_INTERRUPTS uart0_store_interrupts +#define RESTORE_UART_INTERRUPTS uart0_restore_interrupts +#define DISABLE_UART_INTERRUPTS uart0_disable_interrupts +#define ENABLE_UART_INTERRUPTS uart0_enable_interrupts + +/** + * @brief A block of code may be made atomic by wrapping it with this + * macro. Something which is atomic cannot be interrupted by interrupts. + */ +/* A specific ATMOIC that disables UART interrupts only */ +#define ATOMIC(blah) \ + { \ + /* STORE_UART_INTERRUPTS(); */ \ + DISABLE_UART_INTERRUPTS(); \ + { blah } \ + /* RESTORE_UART_INTERRUPTS(); */ \ + ENABLE_UART_INTERRUPTS(); \ + } + +/* A generic ATMOIC that disables all interrupts */ +#define GLOBAL_ATOMIC(blah) \ + { \ + MICRO_DISABLE_INTERRUPTS(); \ + { blah } \ + MICRO_ENABLE_INTERRUPTS(); \ + } + +#if 1 +#define SLIP_STATISTICS(statement) +#else +uint16_t slip_drop_bytes, slip_overflow, slip_error_drop; +/* No used in this file */ +uint16_t slip_rubbish, slip_twopackets, slip_ip_drop; +unsigned long slip_received, slip_frames; +#define SLIP_STATISTICS(statement) statement +#endif + +/* Must be at least one byte larger than UIP_BUFSIZE (for SLIP_END)! */ +#ifdef SLIP_CONF_RX_BUFSIZE +#define RX_BUFSIZE SLIP_CONF_RX_BUFSIZE + +#if RX_BUFSIZE < (UIP_BUFSIZE - UIP_LLH_LEN + 16) +#error "SLIP_CONF_RX_BUFSIZE too small for UIP_BUFSIZE" +#endif + +#else +#define RX_BUFSIZE (UIP_CONF_BUFFER_SIZE * 2) +#endif + +/* + * Variables begin and end manage the buffer space in a cyclic + * fashion. The first used byte is at begin and end is one byte past + * the last. I.e. [begin, end) is the actively used space. + */ + +static volatile uint16_t begin, end, end_counter; +static uint8_t rxbuf[RX_BUFSIZE]; +static volatile uint8_t is_dropping = 0; +static volatile uint8_t is_full = 0; + +static void (*input_callback)(void) = NULL; +/*---------------------------------------------------------------------------*/ +void +slip_set_input_callback(void (*c)(void)) +{ + input_callback = c; +} +static void +slip_write_char(uint8_t c) +{ + /* Escape SLIP control characters */ + if(c == SLIP_END) { + slip_arch_writeb(SLIP_ESC); + c = SLIP_ESC_END; + } else if(c == SLIP_ESC) { + slip_arch_writeb(SLIP_ESC); + c = SLIP_ESC_ESC; + } +#if UART_XONXOFF_FLOW_CTRL + /* Escape XON/XOFF characters */ + else if(c == XON) { + slip_arch_writeb(SLIP_ESC); + c = SLIP_ESC_XON; + } else if(c == XOFF) { + slip_arch_writeb(SLIP_ESC); + c = SLIP_ESC_XOFF; + } +#endif /* UART_XONXOFF_FLOW_CTRL */ + slip_arch_writeb(c); +} +/*---------------------------------------------------------------------------*/ +uint8_t +slip_write(const void *_ptr, int len) +{ + const uint8_t *ptr = _ptr; + uint16_t i; + uint8_t c; + + slip_arch_writeb(SLIP_END); + + for(i = 0; i < len; ++i) { + c = *ptr++; + slip_write_char(c); + } + slip_arch_writeb(SLIP_END); + + return len; +} +/*---------------------------------------------------------------------------*/ +/* slip_send: forward (IPv4) packets with {UIP_FW_NETIF(..., slip_send)} + * was used in slip-bridge.c + */ +uint8_t +slip_send(void) +{ + uint16_t i; + uint8_t *ptr; + uint8_t c; + + slip_arch_writeb(SLIP_END); + + ptr = &uip_buf[UIP_LLH_LEN]; + for(i = 0; i < uip_len; ++i) { + if(i == UIP_TCPIP_HLEN) { + ptr = (uint8_t *)uip_appdata; + } + c = *ptr++; + slip_write_char(c); + } + slip_arch_writeb(SLIP_END); + + return UIP_FW_OK; +} +/*---------------------------------------------------------------------------*/ +static void +rxbuf_init(void) +{ + begin = end = end_counter = 0; + is_dropping = 0; +} +/*---------------------------------------------------------------------------*/ +/* Upper half does the polling. */ +static uint16_t +slip_poll_handler(uint8_t *outbuf, uint16_t blen) +{ + uint16_t len; + uint16_t pos; + uint8_t c; + uint8_t state; + + if(end_counter == 0 && is_full == 0) { + return 0; + } + for(len = 0, pos = begin, state = c = SLIP_NEUTRAL; + len < blen + 1; /* +1 for SLIP_END! */ + ) { + + c = rxbuf[pos++]; + + if(pos == RX_BUFSIZE) { + /* Circular buffer: warp around */ + pos = 0; + } + if(c == SLIP_END) { + /* End of packet */ + break; + } + if(len >= blen) { + /* End of buffer with no SLIP_END + * ==> something wrong happened */ + break; + } + switch(c) { + case SLIP_ESC: + state = SLIP_ESC; + break; + case SLIP_ESC_END: + if(state == SLIP_ESC) { + outbuf[len++] = SLIP_END; + state = SLIP_NEUTRAL; + } else { + outbuf[len++] = c; + } break; + case SLIP_ESC_ESC: + if(state == SLIP_ESC) { + outbuf[len++] = SLIP_ESC; + state = SLIP_NEUTRAL; + } else { + outbuf[len++] = c; + } break; +#if UART_XONXOFF_FLOW_CTRL + case SLIP_ESC_XON: + if(state == SLIP_ESC) { + outbuf[len++] = XON; + state = SLIP_NEUTRAL; + } else { + outbuf[len++] = c; + } break; + case SLIP_ESC_XOFF: + if(state == SLIP_ESC) { + outbuf[len++] = XOFF; + state = SLIP_NEUTRAL; + } else { + outbuf[len++] = c; + } break; +#endif /* UART_XONXOFF_FLOW_CTRL */ + default: + outbuf[len++] = c; + state = SLIP_NEUTRAL; + break; + } + } + + /* Update counters */ + if(c == SLIP_END) { + ATOMIC(begin = pos; + if(end_counter) { + end_counter--; + } + ) + PUTCHAR('P'); + } else { + /* Something went wrong, no SLIP_END found, drop everything */ + ATOMIC(rxbuf_init(); + is_dropping = 1; + ) + SLIP_STATISTICS(slip_error_drop++); + len = 0; + PRINTF("SLIP: *** out of sync!\n"); + } + + if(end_counter > 0) { + /* One more packet is buffered, need to be polled again! */ + process_poll(&slip_process); + } + return len; +} +/*---------------------------------------------------------------------------*/ +PROCESS_THREAD(slip_process, ev, data) +{ + PROCESS_BEGIN(); + + rxbuf_init(); + + while(1) { + PROCESS_YIELD_UNTIL(ev == PROCESS_EVENT_POLL); + + /* Move packet from rxbuf to buffer provided by uIP. */ + uip_len = slip_poll_handler(&uip_buf[UIP_LLH_LEN], + UIP_BUFSIZE - UIP_LLH_LEN); + + PRINTF("SLIP: recv bytes %u frames RECV: %u. is_full %u, is_dropping %u.\n", + end_counter, uip_len, is_full, is_dropping); + + /* We have free space now, resume slip RX */ + if(is_full) { + is_full = 0; + ENABLE_UART_INTERRUPTS(); + } + + if(uip_len > 0) { + if(input_callback) { + input_callback(); + } +#ifdef SLIP_CONF_TCPIP_INPUT + SLIP_CONF_TCPIP_INPUT(); +#else + tcpip_input(); +#endif + } + } + + PROCESS_END(); +} +/*---------------------------------------------------------------------------*/ +/* Return status from slip_input_byte: + * -1 means RX buffer overflow ==> stop reading + * 0 means do not exit power saving mode + * 1 means exit power saving mode + **/ +int +slip_input_byte(unsigned char c) +{ + static int in_frame = 0; + uint16_t next, next_next; + int error_return_code = is_full ? -1 : 0; + int success_return_code = is_full ? -1 : 1; + + SLIP_STATISTICS(slip_received++); + +#if UART_XONXOFF_FLOW_CTRL + if(c == XOFF || c == XON) { + xonxoff_state = c; + return 1; + } else { + /* ANY char would be XON */ + xonxoff_state = XON; + } +#endif /* UART_XONXOFF_FLOW_CTRL */ + + if(is_dropping) { + /* Make sure to drop full frames when overflow or + * out of sync happens */ + if(c != SLIP_END) { + SLIP_STATISTICS(slip_drop_bytes++); + } else { + is_dropping = 0; + in_frame = 0; + } + return error_return_code; + } + + if(!in_frame && c == SLIP_END) { + /* Ignore slip end when not receiving frame */ + return error_return_code; + /* increment and wrap */ + } + next = end + 1; + if(next >= RX_BUFSIZE) { + next = 0; + } + next_next = next + 1; + if(next_next >= RX_BUFSIZE) { + next_next = 0; + /* Next byte will overflow. Stop accepting. */ + } + if(next_next == begin) { + is_full = 1; + /* disable UART interrupts */ + DISABLE_UART_INTERRUPTS(); + process_poll(&slip_process); + } + + /* Buffer is full. We can't store anymore. + * Shall not happen normally, + * because of overflow protection above. */ + if(next == begin) { + is_dropping = 1; + SLIP_STATISTICS(slip_overflow++); + is_full = 1; + /* disable UART interrupts */ + DISABLE_UART_INTERRUPTS(); + process_poll(&slip_process); + return -1; + } + + rxbuf[end] = c; + end = next; + in_frame = 1; + + if(c == SLIP_END) { + in_frame = 0; + end_counter++; + SLIP_STATISTICS(slip_frames++); + process_poll(&slip_process); + return success_return_code; + } + return error_return_code; +} +/*---------------------------------------------------------------------------*/ +#if SLIP_BRIDGE_CONF_NO_PUTCHAR +int +putchar(int c) +{ + uart0_writeb(c); + return 1; +} +#endif diff --git a/platform/jn516x/lib/sprintf.c b/platform/jn516x/lib/sprintf.c new file mode 100644 index 000000000..8dbfa10a0 --- /dev/null +++ b/platform/jn516x/lib/sprintf.c @@ -0,0 +1,235 @@ +/* + File: printf.c + + Copyright (c) 2004,2008 Kustaa Nyholm / SpareTimeLabs + + All rights reserved. + + Redistribution and use in source and binary forms, with or without modification, + are permitted provided that the following conditions are met: + + Redistributions of source code must retain the above copyright notice, this list + of conditions and the following disclaimer. + + Redistributions in binary form must reproduce the above copyright notice, this + list of conditions and the following disclaimer in the documentation and/or other + materials provided with the distribution. + + Neither the name of the Kustaa Nyholm or SpareTimeLabs nor the names of its + contributors may be used to endorse or promote products derived from this software + without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, + OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + OF SUCH DAMAGE. + + */ + +/* + * This is BSD code obtained from http://www.sparetimelabs.com/printfrevisited/index.html + * From the web page: + * "The code is GPL and BSD lincensed, download the BSD licensed version from the link + * above or use the GPL licensed code from this page below." + * + * modified by Beshr Al Nahas and Simon Duquennoy + */ + +#include "contiki-conf.h" +#include +#include +#include +#include +#include +#include "dev/uart0.h" + +static char *bf, buf[14], uc, zs; +static unsigned int num; + +static void +out(char c) +{ + *bf++ = c; +} +static void +outDgt(char dgt) +{ + out(dgt + (dgt < 10 ? '0' : (uc ? 'A' : 'a') - 10)); + zs = 1; +} +static void +divOut(unsigned int div) +{ + unsigned char dgt = 0; + while(num >= div) { + num -= div; + dgt++; + } + if(zs || dgt > 0) { + outDgt(dgt); + } +} +int +vsnprintf(char *str, size_t n, const char *fmt, __VALIST va) +{ + char ch, *p, *str_orig = str; + char next_ch; + + while((ch = *fmt++) && str - str_orig < n) { + if(ch != '%') { + *str++ = ch; + } else { + char lz = 0; + char w = 0; + ch = *(fmt++); + if(ch == '0') { + ch = *(fmt++); + lz = 1; + } + if(ch >= '0' && ch <= '9') { + w = 0; + while(ch >= '0' && ch <= '9') { + w = (((w << 2) + w) << 1) + ch - '0'; + ch = *fmt++; + } + } + bf = buf; + p = bf; + zs = 0; +start_format: + next_ch = *fmt; + switch(ch) { + case 0: + goto abort; + case 'l': + if(next_ch == 'x' + || next_ch == 'X' + || next_ch == 'u' + || next_ch == 'd') { + ch = *(fmt++); + goto start_format; + } + case 'u': + case 'd': + num = va_arg(va, unsigned int); + if(ch == 'd' && (int)num < 0) { + num = -(int)num; + out('-'); + } + divOut(1000000000); + divOut(100000000); + divOut(10000000); + divOut(1000000); + divOut(100000); + divOut(10000); + divOut(1000); + divOut(100); + divOut(10); + outDgt(num); + break; + case 'p': + case 'x': + case 'X': + uc = ch == 'X'; + num = va_arg(va, unsigned int); + /* divOut(0x100000000UL); */ + divOut(0x10000000); + divOut(0x1000000); + divOut(0x100000); + divOut(0x10000); + divOut(0x1000); + divOut(0x100); + divOut(0x10); + outDgt(num); + break; + case 'c': + out((char)(va_arg(va, int))); + break; + case 's': + p = va_arg(va, char *); + break; + case '%': + out('%'); + default: + break; + } + *bf = 0; + bf = p; + + while(*bf++ && w > 0) { + w--; + } + while(w-- > 0) { + if(str - str_orig < n) { + *str++ = lz ? '0' : ' '; + } else { + goto abort; + } + } + while((ch = *p++)) { + if(str - str_orig < n) { + *str++ = ch; + } else { + goto abort; + } + } + } + } + +abort: + if(str - str_orig < n) { + *str = '\0'; + } else { + *(--str) = '\0'; + } return str - str_orig; +} +int +sprintf(char *str, const char *fmt, ...) +{ + int m; + __VALIST va; + va_start(va, fmt); + m = vsnprintf(str, 0xffffffff, fmt, va); + va_end(va); + return m; +} +int +snprintf(char *str, size_t n, const char *fmt, ...) +{ + int m; + __VALIST va; + va_start(va, fmt); + m = vsnprintf(str, n, fmt, va); + va_end(va); + return m; +} +int +printf(const char *fmt, ...) +{ + int m, i; + char str[256]; + __VALIST va; + va_start(va, fmt); + m = vsnprintf(str, sizeof(str), fmt, va); + va_end(va); + for(i = 0; i < m; i++) { + putchar(str[i]); + } + return m; +} +int +puts(const char *s) +{ + char c; + while(c = *s++) { + putchar(c); + } + putchar('\n'); + return strlen(s); +} diff --git a/platform/jn516x/platform-conf.h b/platform/jn516x/platform-conf.h new file mode 100644 index 000000000..60497645f --- /dev/null +++ b/platform/jn516x/platform-conf.h @@ -0,0 +1,263 @@ +/* + * Copyright (c) 2015, SICS Swedish ICT. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the Institute nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * This file is part of the Contiki operating system. + * + */ + +#ifndef PLATFORM_CONF_H +#define PLATFORM_CONF_H + +#include +#include + +#undef putchar + +/* Delay between GO signal and SFD + * Measured 153us between GO and preamble. Add 5 bytes (preamble + SFD) air time: 153+5*32 = 313 */ +#define RADIO_DELAY_BEFORE_TX ((unsigned)US_TO_RTIMERTICKS(313)) +/* Delay between GO signal and start listening + * Measured 104us: between GO signal and start listening */ +#define RADIO_DELAY_BEFORE_RX ((unsigned)US_TO_RTIMERTICKS(104)) + +/* Micromac configuration */ + +#ifndef MIRCOMAC_CONF_BUF_NUM +#define MIRCOMAC_CONF_BUF_NUM 2 +#endif + +#ifndef MICROMAC_CONF_CHANNEL +#define MICROMAC_CONF_CHANNEL 26 +#endif + +#ifdef RF_CHANNEL +#define MICROMAC_CONF_CHANNEL RF_CHANNEL +#endif + +/* Timer conversion + * RTIMER 16M = 256 * 62500(RADIO) == 2^8 * 62500 */ +#define RADIO_TO_RTIMER(X) ((rtimer_clock_t)((X) << (int32_t)8L)) + +#define DR_11744_DIO2 12 +#define DR_11744_DIO3 13 +#define DR_11744_DIO4 14 +#define DR_11744_DIO5 15 +#define DR_11744_DIO6 16 +#define DR_11744_DIO7 17 + +#define TSCH_DEBUG 0 + +#if TSCH_DEBUG +#define TSCH_DEBUG_INIT() do { \ + vAHI_DioSetDirection(0, (1 << DR_11744_DIO2) | (1 << DR_11744_DIO3) | (1 << DR_11744_DIO4) | (1 << DR_11744_DIO5) | (1 << DR_11744_DIO6) | (1 << DR_11744_DIO7)); \ + vAHI_DioSetOutput(0, (1 << DR_11744_DIO2) | (1 << DR_11744_DIO3) | (1 << DR_11744_DIO4) | (1 << DR_11744_DIO5) | (1 << DR_11744_DIO6) | (1 << DR_11744_DIO7)); } while(0); +#define TSCH_DEBUG_INTERRUPT() do { \ + static dio_state = 0; \ + dio_state = !dio_state; \ + if(dio_state) { \ + vAHI_DioSetOutput((1 << DR_11744_DIO2), 0); \ + } else { \ + vAHI_DioSetOutput(0, (1 << DR_11744_DIO2)); \ + } \ +} while(0); +#define TSCH_DEBUG_RX_EVENT() do { \ + static dio_state = 0; \ + dio_state = !dio_state; \ + if(dio_state) { \ + vAHI_DioSetOutput((1 << DR_11744_DIO4), 0); \ + } else { \ + vAHI_DioSetOutput(0, (1 << DR_11744_DIO4)); \ + } \ +} while(0); +#define TSCH_DEBUG_TX_EVENT() do { \ + static dio_state = 0; \ + dio_state = !dio_state; \ + if(dio_state) { \ + vAHI_DioSetOutput((1 << DR_11744_DIO5), 0); \ + } else { \ + vAHI_DioSetOutput(0, (1 << DR_11744_DIO5)); \ + } \ +} while(0); +#define TSCH_DEBUG_SLOT_START() do { \ + static dio_state = 0; \ + dio_state = !dio_state; \ + if(dio_state) { \ + vAHI_DioSetOutput((1 << DR_11744_DIO3), 0); \ + } else { \ + vAHI_DioSetOutput(0, (1 << DR_11744_DIO3)); \ + } \ +} while(0); +#define TSCH_DEBUG_SLOT_END() +#endif /* TSCH_DEBUG */ + +#ifndef BAUD2UBR +#define BAUD2UBR(X) (X) +#endif /* BAUD2UBR */ + +/* UART baud rates */ +#define UART_RATE_4800 0 +#define UART_RATE_9600 1 +#define UART_RATE_19200 2 +#define UART_RATE_38400 3 +#define UART_RATE_76800 4 +#define UART_RATE_115200 5 +#define UART_RATE_230400 6 +#define UART_RATE_460800 7 +#define UART_RATE_500000 8 +#define UART_RATE_576000 9 +#define UART_RATE_921600 10 +#define UART_RATE_1000000 11 + +#define PLATFORM_HAS_LEDS 1 +#define PLATFORM_HAS_BUTTON (SENSOR_BOARD_DR1174 == 1) +#define PLATFORM_HAS_LIGHT (SENSOR_BOARD_DR1175 == 1) +#define PLATFORM_HAS_HT (SENSOR_BOARD_DR1175 == 1) +#define PLATFORM_HAS_POT (SENSOR_BOARD_DR1199 == 1) +#define PLATFORM_HAS_BATTERY 0 /* sensor driver not implemented */ +#define PLATFORM_HAS_SHT11 0 +#define PLATFORM_HAS_RADIO 1 + +/* CPU target speed in Hz + * RTIMER and peripherals clock is F_CPU/2 */ +#define F_CPU 32000000UL + +/* LED ports */ +/* + #define LEDS_PxDIR P5DIR + #define LEDS_PxOUT P5OUT + #define LEDS_CONF_RED 0x10 + #define LEDS_CONF_GREEN 0x20 + #define LEDS_CONF_YELLOW 0x40 + #define JENNIC_CONF_BUTTON_PIN (IRQ_DIO9|IRQ_DIO10) + */ + +#define CC_CONF_REGISTER_ARGS 1 +#define CC_CONF_FUNCTION_POINTER_ARGS 1 +#define CC_CONF_FASTCALL +#define CC_CONF_VA_ARGS 1 +#define CC_CONF_INLINE inline + +#define CCIF +#define CLIF + +#ifdef HAVE_STDINT_H +#include +#else +#ifndef uint8_t +typedef unsigned char uint8_t; +typedef unsigned short uint16_t; +typedef unsigned long uint32_t; +typedef signed char int8_t; +typedef short int16_t; +typedef long int32_t; +typedef unsigned long long uint64_t; +typedef long long int64_t; +#endif +#endif /* !HAVE_STDINT_H */ + +/* Types for clocks and uip_stats */ +typedef uint16_t uip_stats_t; +typedef uint32_t clock_time_t; + +/* Core rtimer.h defaults to 16 bit timer unless RTIMER_CLOCK_LT is defined */ +typedef uint32_t rtimer_clock_t; +#define RTIMER_CLOCK_LT(a, b) ((int32_t)((a) - (b)) < 0) +/* 10ms timer tick */ +#define CLOCK_CONF_SECOND 100 + +/* Shall we calibrate the DCO periodically? */ +#define DCOSYNCH_CONF_ENABLED 1 + +/* How often shall we attempt to calibrate DCO? + * PS: It should be calibrated upon temperature changes, + * but the naive approach of periodic calibration is fine too */ +#ifndef DCOSYNCH_PERIOD +#define DCOSYNCH_PERIOD (5 * 60) +#endif /* VCO_CALIBRATION_INTERVAL */ + +/* Disable UART HW flow control */ +#ifndef UART_HW_FLOW_CTRL +#define UART_HW_FLOW_CTRL 0 +#endif /* UART_HW_FLOW_CTRL */ + +/* Disable UART SW flow control */ +#ifndef UART_XONXOFF_FLOW_CTRL +#define UART_XONXOFF_FLOW_CTRL 1 +#endif /* UART_XONXOFF_FLOW_CTRL */ + +#ifndef UART_BAUD_RATE +#define UART_BAUD_RATE UART_RATE_1000000 +#endif /* UART_BAUD_RATE */ + +#ifndef UART1_BAUD_RATE +#define UART1_BAUD_RATE UART_RATE_1000000 +#endif +#define ENABLE_ADVANCED_BAUD_SELECTION (UART_BAUD_RATE > UART_RATE_115200) + +/* Set this to zero only if we are using SLIP */ +#ifndef SLIP_BRIDGE_CONF_NO_PUTCHAR +#define SLIP_BRIDGE_CONF_NO_PUTCHAR 1 +#endif /* SLIP_BRIDGE_CONF_NO_PUTCHAR */ + +/* Enable this to get the 32.768kHz oscillator */ +#ifndef USE_EXTERNAL_OSCILLATOR +#define USE_EXTERNAL_OSCILLATOR 0 +#endif /* USE_EXTERNAL_OSCILLATOR */ + +/* Extension of LED definitions from leds.h for various JN516x dev boards +JN516x Dongle: + LEDS_RED Red LED on dongle + LEDS_GREEN Green LED on dongle + Note: Only one LED can be switch on at the same time + +DR1174-only: + LEDS_GP0 LED D3 on DR1174 + LEDS_GP1 LED D6 on DR1174 + +DR1174+DR1199: + LEDS_RED LED D1 on DR1199 + LEDS_GREEN LED D2 on DR1199 + LEDS_BLUE LED D3 on DR1199 + LEDS_GP0 LED D3 on DR1174 + LEDS_GP1 LED D6 on DR1174 + +DR1174+DR1175: + LEDS_RED Red led in RGB-led with level control on DR1175 + LEDS_GREEN Green led in RGB-led with level control on DR1175 + LEDS_BLUE Blue led in RGB-led with level control on DR1175 + LEDS_WHITE White power led with level control on DR1175 + LEDS_GP0 LEDS D3 on DR1174 + LEDS_GP1 LEDS D6 on DR1174 +*/ +#define LEDS_WHITE 8 +#define LEDS_GP0 16 +#define LEDS_GP1 32 +#define LEDS_GP2 64 +#define LEDS_GP3 128 +#define LEDS_CONF_ALL 255 +#endif /* PLATFORM_CONF_H */ From 11f9b780c84675268c5addf9ed590d544a287140 Mon Sep 17 00:00:00 2001 From: Simon Duquennoy Date: Mon, 21 Sep 2015 10:59:15 +0200 Subject: [PATCH 093/120] Added tools for NXP JN516x --- tools/jn516x/JennicModuleProgrammer | Bin 0 -> 22124 bytes tools/jn516x/Makefile | 25 ++ tools/jn516x/mote-list.py | 94 +++++ tools/jn516x/motelist_lib/__init__.py | 0 .../motelist_lib/linux_motelist_impl.py | 220 ++++++++++ .../motelist_lib/windows_motelist_impl.py | 142 +++++++ tools/jn516x/serialdump.c | 396 ++++++++++++++++++ 7 files changed, 877 insertions(+) create mode 100644 tools/jn516x/JennicModuleProgrammer create mode 100644 tools/jn516x/Makefile create mode 100644 tools/jn516x/mote-list.py create mode 100644 tools/jn516x/motelist_lib/__init__.py create mode 100644 tools/jn516x/motelist_lib/linux_motelist_impl.py create mode 100644 tools/jn516x/motelist_lib/windows_motelist_impl.py create mode 100644 tools/jn516x/serialdump.c diff --git a/tools/jn516x/JennicModuleProgrammer b/tools/jn516x/JennicModuleProgrammer new file mode 100644 index 0000000000000000000000000000000000000000..eef29c284af33e8e04e3a2b0a943839499ee2f7d GIT binary patch literal 22124 zcmeHve|%KM+3zGd!39D#V6>>Qp6UjJZwR{(Fu|Y+i2*c1lz_IP%aZJ}`?ATVyJsO- zib*$tY?suurIz;6dqI7B?OSTG<>dl`4TN7>Kle?!t>tQ4sjs%1LN!%XwA8)d@0@e8 zC#!95-+$hJJTQ6Yndh0AXP$ZHnK^T2=i%EM>a()4g!yEP96@Z`BZ{pY@XP|8QZ7_6 zUX+MWi)+Lg$YYj&59n6;&V!SI`Psgi!NBU7!Il}pKwGq1We zpiT3+oBeBrw+NZ@dmxknuus&EffSQ zp=fROw2Nk6#H$4&?Os^}3Tz9xgP~@R76`QotruC|K-qz;UcGhQ+1QLd# znxwUF(2I@+MW`LkSp&2MMT#|E4GAc>Z4GmGKs-(O)`tU{7dVS;-yp@;ntj1nnI zp@J19%4Kj%+glaW(-0BImiG>Y| z7u33EmAU4OM$1QI&e7QHGWu-#_Z;IdV+uS8Vfr7vYZ^<(vMsqdM=&UK$1(tjZ+!Jp zxU*cb9(Kj_!a!gWJ=>QIyg=ePVyl5`R|UpXqDKuo9Dy$%hlzqVmkXyxTg-)nqmAX# z!3`<4%fPD;LQESWoMIj!jJALfjvn-D4?YIG1z!2CftQHWB)JRzKf zkhq*MUx*4qyAV}`XizobWXvUmZ~%)4A#VdAoOdJP6`1!3uN2}w!cPgYk`PXQ72#Dv zv=Cx2`3bKPB1l*yL_6WNLTH4a7NUdjIw3X^szP)UenyCH!t3ErW9My2s72i0H8^vT z5Q*5OR4UaopyeiShnkYrXmj#qWQZNJ-9Jc1AyRWLLd&V*OZY4CVu8~9j1Heg?o_ct zoV4K~iBrpdcIWVb#HnpRr>x;U5~tSvD)F5Xr}q6N#QP=AUhq4KcS@YS;jbXxE^(E3 zHStvvcMxAhyiwxpC4VFFYKgPA{Pz)eN}RpsUqxJ%ID5~}1`QWToW1C8CoUw;-t>16 zANddo#nr?+iJz5t9r0e`LlS2%`}>IxNSwXx-%fmw#M$fqoy2!aoW1XVl6b$wX$Ag0 z#5*NUYw+(U-Y)S~#0QA4l6VX8Q^Xr3PAl;b5wDgwt;K(axKrY^8vj}1s>EqM{v`1N ziPMVwBgBQoX-)o%#7F+Z_IDEJ+&6qy;@!k;#D{<{kH3EJie<6aM!L?QMV`bLZQfm6 zr^LG*zXEU#?6P5W_Gyldi3jpd);SdC9>sQ2aUj2l*Ewv-wWuSmISN3_Q^5*odvUj7 zi?4Jj@hV61rx2VaQfDXs#bgVPeI@GyQ+x2n=@h6I?|&rp6jYw5gpn^C&Ich?gixp5OKwk{4?r* zJP*X-6_B)Qar9r3Pa;WQ>%@=tbvruAi5#+sc$1@w#UM>)F9L4@X^$%?B9YxQVDEVm zE-9gB>#RTnJ_L(dy|O(+Jq;kDEy)Y;1Cr@+}n$rMuj{WjbOUfBjQ+J@?kHq5igqZB+nwu^g_pKWlCwn0#i zam>TkKq=j9XJ3<}1NyTiuAs8|b~w5z-bzOv+Jkf@X@~Qs2G_v3@1ii3x#ZN`vH9$w ztWDR_q@*f-Fe*ZFJgS%6?4(2;>VSH>;dfco%dj4uNP9zWlOci@lHnj2nAW$~F+g!N zupz$#N+|>w_U;)V+qYbfzw-vF0w-`DMU8D)~z`SfVRAgzO>mq0>XW&Ho@@gm0Q1CTzI z@n7okLdLl)LwW(@ztH1(jQ?DZ+mdJgOohpg(Ps8-bTq_%nnDIS94}$s>KTYmlWN-N zu$lU3!90lcd<^Ysi0^ti`Pc`rnr+excxPWBeZm=gPX*fC=e=?w@--9=<#-F=a_|-2fHd+4#Fc}a0GnN5L=lmoZEuy#WIuH1a zirKyEToL{r`Ez#cTvp|o$ftF`85_uYoGhur9+D+{<(Y8uL@o=+iXBt#e_)V~v+vN2 zP=`SIvGY@RIlzmB#T3q4umf#8l*zQz&~t;PC=$lb7r}H?w*6_e-8B$9R%9(NcD@w! z3Ye9e&>ZFQjSfd*qr(X=P&8lIE)(&fqr~3*E^66SH(wOw!$O_|GQWC(9nq&4Rd-#6 z=rf2u1Aifm`QQwSQxhl##W@lvC3dWI(APg-9L)mvH<(d$=Ll`xeDNrzkzP%ymBFzUjle))3CJrmZ_-KjZG+Mh zF)tma_dfTn{=+$hU+q84h2*(-|KVK1uKvT>fWzxxTzWeWE5v=HxT(*Tjsi5U6jc_Y zp(W7UR5nzK57DXb&!h7A(Vo-sar-IIhC*a00COQ2r<&a$r`Ua{-11kPpdi(qFB1im{r1lPa{rA^#b`bIR|Ie%Ao4Or+-7*gvSkPCS z1${tGQZM>yz?eC%X3mRZqxV@-wK*s+ISpxvx^9R4@rw}$#FVa^_Jz9WGd5q~x_#4l z_|vn<6wi*2puJKFM(gz!LqXJ2*D)$h4y)v!QFPxnsfK4MEX3mCO>ja@NV`~!!p}Wr ztf#n`JMTn?R7=w#BjmdhEV8L^@i${eD1rKB%JmicxBy1SrJXF6xmt`|T#sTfm-Gxg ze8zP;cFY+cg5Mw14cYV`sL=H?tvKj#qW{ZbkQL`H>(3gjeEW;D;v>_~Pyv0)bpT4d z6zegmiVd$Mucsa>CThQgG41CNm2(OZ*MN-aZl~*f5Uq{xb*v(I5ejT)WQT*BJ@G+U zN(&-rQr+mfwE+pPfxbG&ozRgJIW)5Fc5uru-ry)b0SeVuj<(jJULkdW-ZpgreX!?} z)mV5Od>2C%4)M155K3av#$;&kQGuWrDM&(>FQH3=USwTe$0)j?t{5cDiXOD@YjE7@ z`Xg$pV$Hn`j#~_M)}inul!U3g&T$I}^a1P|Wjd2>6zGR?F#!^1aPr-WWnEn_`0e`! zvVKu{{EJt|P;wS3s~W#)chBjEpOo?s--bq1CS}~-Gm9(%x(-6r#>pGKbiJeP5H~F3JT1DTh{--X=&4$MMrY zF*6Xk#!X%VYP9etZ1Hl~OMI~FyzIUvc=K(JjnI;P-(E)t6^V5w~|5lQ#13A+)-pukPk-sJQ_~wFF&r7y2*nL!HAWrwugxF|<_YEu_+_pbQjX zLsVb<{s>}XaFn~ALlTTUb|PEqUunRcT{#kc2i!#1=?^d1fU$Src9vk@LkvDAdx8pCOd#4@w!&HFjeR_)u0gI2k zQ2;p#5S`Y$(s5(_ZD{AF0~2-CCBS^e9CY}}*E!T6d#ZaN zI*G>S=-lWi&a>AI!KajZXU~^X4@IwoXRCr1tC3uXMlFgRYmk0YW$Y{*~zFMyRaC7&dSam=jkz8lI6;ZP0Na^th_$UD!dB zz55l24x5{MU>4hew+|pQWjlZr0x1J5h$qpbWwe-??8>oS3Ts7PF2@Oy6VSA7ylKtC zs6(fg&9?X4h$uUGF8sEW&f?}HXQv){wP5@ZkxCs@9C_6?ekeY!Sd82z4zS4iq7yPz zIkbO1NHm^Iei}2BT-o&ubd<0}r}JeN;j)%DTQ6^xUS2&1O_k-1W*9}msv4l8Mp#u7 zv~geT*h<51A6%{1v=;_y*7U5bNs9EhD?2Ez5Lxkhs0&gjKaV0HXD9Q_cD{^Z{;D%} z_Oc@%DDiq51dgxBi=DDbHN@+c;pG?&zJ6**)^zX^Hb7-TQjFvcvNU^d8Q7#ee_NFJ zxZxi|S;^q}O#3JuwF@{U*aa8a<**qC6yk(YaPStUdR_*&BDH56z?CWd`4s<5<)5qg z=W71BCZ%1S$dMg3UsPjp^m*B3+D-Z@5ngI^^4z9toi7P|L6EC?zLvxW3lDI)b+DbP z8{w>12?K(W*_aGGeiBw#NS~N|_?(=ZXU8udNnUsEe~ihGWwy}szt2~&lagn+1KN`7 z9=(#z(Mo>K7rK+@{w;YY%Cx*6VPylIaH*|ACsQddWx%wY+y%L?GMEG!*X(i$-ft+5 zYi264kSpcwP`v4nIsbK?--z`N)(qPSb~v^JjLvC6Ag%$nmp0y4udt=4GWoSXu)64j zi7Vqn78T=trxTjq#JR>?ASy56D-OmVhM7n{j|TbrF%z<6)9yzw9x?p8j!_bQF5Ei} z+#*r0JbM`+YRyaJKn$fIT^17Y{)_U??MbXCOw<;|8w(OErp6oT7;ZjLtmi98bUXS{ zEGC5tNLARk+ffQsIuRJj%|eQaSjERr2^s$5dAy0xf6PPI!GGL5&E7Lp+Wa9|EO$O; zpm2vkss3QBize++LBh3t`w=^ja*AC_zMQY!m^ z>^Mxv2Rk3#KC0zPT{S4B(CC^=jH&S>8_o3pc?F0e7H`Z z>~_qCsi9L+eTQTeDK{G_h~AQp-jc59)SHx4(l@hf5%~>-0}p(*8~;|J-3;f6sH; z^YOQOw@LGizjfpfHpDqT7%xDa=F9k0#A&RU4NGCov{$Hr);ww^4S4mZHOcqs21nk3 z@u&&5?E)`fn&i?K?WEx(Z@_yUZFw;Sfx%Qxu=m`Gs5IQH523}cybse}d!og4`n`y1 z)#1Ff4pDnv@+!9N1u#>d1Kh?zvN^|P|3yZSO(ByW% zCcXR@5?4@;thakkZz@?kNTsbGqqJa#(q5yK3)RX&`@aR%l3DzVJQ z2Gq^IezLviHk6xKmdAwN^}gly9xhsCi{!Rm4kSi{N&$`*r!X|&srm}JrK=n{n;l=l z^>L!snIdExSW@1oS`r1-KyUXC+vZ+kT4y&`GDHual6T!}Kbo%O%F}Ac#nb=pe&rlS=`nfYHi1vsntQR>I;Nh*L%WV zwPZmw5Y$v(D6Bd=ik%f5rD~mbU7*>k1|mkv^a-LK2eiB`suohcVNb-X)(1Ti|2(xV zq^YZep0>50K^34L?K}&n@|;$nZOzAW2(iK&4)`{xJQId0 zKT^tPCWz&2k!X8+D6E0r><_f7+J<(oA?yUy;fbL1c`6@gaq$FE+cZy|TnKfrcz0>8a5j9$?Hwd(Tj%${8!iEm0)lIA26v5DIC*kO$}E)OEAe zMd&wg_;2yJOrGTt&l)cj5t$%VwI;kK+Ujl7BJ+qXZRfE)#@Vj&3Uue%w$S=E1HHrP zGGd=IW4Z>)XOZNO%v&+fH*ekId5!a0=NSe?eXwI9Fda`&rD;qM%e=(|;2rnf~$ z<@j{XDJxf7W$%=#-m*1i>P%2)YFcEb3q8j|W~@NDqvA0|tr|sdmG}x%cs1x<=M9#r z@Cz8E=xk4GDB7l}A)ngfT^(Jc2HM~iTIC_jGB^dFCkjX5ETfUIq#27*mqh_cs-m9t zYRG{$XedRhNTps>(ns?*BELmxecY2YMtm&Xb>QZ|zYrV`9U83tjL5o*(L<`vSnt@8u} z^z5Fn2V*h}A7aRpHh}*`y??EYzg6$p`AQ#q)^VZEfSBIqwa~z7{3ZZXT3ZX;&w6io zg0S?PoJE|o?weQqcmGTfS=Z#;GJr9LVB7fc`V7loRhM+p+AxWG?mtP6bS2 z!BYo#3X2_nOsl|Z@=3ra0e=N(!|Mj$@6X`PW)ow^~_t1(EsaH3P)~* zsLfaJ&R6gY71WEc9qBirETlUdHY$>XQZunOzpysH z0Hx)jG}}p(cpPPL%aUKlhfwA*UFMPO#haDJSni#W`0k$U?0Q4$g?ufjLf8qucGw6% zR#Wbe$gn7XBs+T}q<~msDy*BxemIMKJ7HTF5QlCX7xiS{9n1aPmYmH>_7Bo3lKRYp zeQB`2{~z88+9Z~)g@7n`)uPSH@>niPZ`hKPlbbc#3~!M$WC%Pgdo%kymV*+rauhTxuVxUP zd?H_2F!5eu`8FtBIk9l!T3|2)NvoeI&)%;@Sx;d1BgVdiUCaJQn)BzW)aSXmEM;FX zDR*fsce4V$O;aWe)|{w0S%X1%yk;WD*G}+{U~Drl%kabaD-hj}bQ{LHhv^@ugC+US z>^nYc6@2l&fV@@6%O>(+8oy-RgfxIpo=-IJi3UE=z$Y5`L<65_;1dn}muLW+u>Afe zOvpHwQCzF=)6=0XijAA_=W#6moexu?-S~|;msAbi`28Z_uYhy^;xT06TAKOfI|?9{ zKjH#*Xu19=0G;bB{G?F6$L-#%*cjgmI0aBez|RYL_?kc63RNK;GVv>qz!ARC8$J4O z_<;UH4}UXnW*FD2*sesFhAQQi-B6 zHU!!{;gDKhHn(i{3|CYp&Y7;`LX<@|v}&H!fcTNLgnl!|&6aSxD8qh?x2$Ht;u)G} zje)Ici%a-d6#HW6pd`o45f9JU&A{d9MTrD&pp2 zzPsRBiBY~@_yO)`@IBOgOujlK;CP9A)uaE|4L&E*=tuaFk6{S{eF*ENU*UdDI}rLA zL?sXX3vH3Ug?#iw4aiLYV?Ji|K_t+JkdOZ34OGZF%zBy5uoi(nhjIFyDpW{&w$=+& zJcPhwALOIo+6o30akD(Ofd(E!F!|``c7u=pk9_p0Cf`=XDJ$!tpFISnmmzLGkO-w62RnJP)ueJ**wX5r)Sr&KuR7p^my0H`}Y+Y!w2=-1Cr7vgG3(f^qB{&$0q z?X}?mgzY9F_Ruhl$K?AiaF$0tdCv$8VGrv_Q5M&xZkmd7#1hkWR|(T6k!&c7_nd|m?IB@+Q84j&#w0UcJXO^P9RH*To<(aq@(jO7$O$&VJcL;fZ10VVqLf+B9hkk^Rw>t2l zzaY#pMkD=#j_U%L>xUfavGj4S( zbeyXteZ8dP`4Z>&(QzK)(#MI8>!Xt6LC4uEy4~wIS4S8pupb@QJvQxF$GNJ~?N!J1 z)feqj$FC%i>o6VXF1ir3Gactnoo-J$j!PRXPYyhTwcix+rxaVvaY?o;+@?d{Vak_< z8KnfcDPI;=eRF^hJfibwi%H^6;PMxkfLXYE<#T}NVbAPI;(kE2Kh2+6Kj*xumioJZ zZ`)_eGg&+W+*&`+sSUu-0l=CjiKiJc9=2yc;wtLz2h73^MbDc=K+@?K%!l~vKnAwq zE+q)Y^48(0Zt9!2 z?<@swu4}Wf+P*J?&hwr0H>@HHtL-k}{B12q(iF(^Rp14{OAUM%aCL`b*z7o^EROoXGaGu~}dnNaXJP;A`SX8pXEg*QW(?Xv^#{F-9p_Y%^twm3z$w=@I46?i-Bo!@ZC-)!$KUi@?kLhk^4B4Jv?lU%dd_d{jiv0_R;8X8t!xx8NUI_*wr|m|{o1uGpFp zXZgjJIiK`-z+bb-(*V5lf8q?6Veb!Q@P~kNJ&ddgE%Gf-*21f-AS*A{ za^r?A9{wqtUFn=FqPR>91RewG=y3C_5f5v4!$|WkXmH1>G6K=13BbV2) z>9?0z+4P&&tSS1HZq^iCW0`lqr8(IA(Tn2J$+!TGTE*Fy1;%ME9>0D0Z`ZjBd&TbTR4~`=l7tIB&OvXUcje7Kcxv?A;{qsJ%u|)m$IBS}D%bPXLdaGPI zUAKWT*X{8ly)=UpI%+|g%EwhR`zQzY-dvoaW?h3D=TV>HSk>Ben&mMi|O>;YpGEz>UpG{&i~ z-R)m5JQ3*<^z*9`W7P2=r`L$r${YIv#z`Q(2>oh6YZY!ccASi%C9mPLUTT z=a%D~kJ}vR?afxq(lnee#Cg_;$l!P1u?}u-O(23zyILGh!!bP3+^!$})0-jMn@!(U z&m)~8wk@ZPUF5qYl^%g5jQu&#k%EfjnXW}ScUYLa`fHfZP$;5 K={Fx*%lUsGfeYIJ literal 0 HcmV?d00001 diff --git a/tools/jn516x/Makefile b/tools/jn516x/Makefile new file mode 100644 index 000000000..be3caa44b --- /dev/null +++ b/tools/jn516x/Makefile @@ -0,0 +1,25 @@ +ifndef HOST_OS + ifeq ($(OS),Windows_NT) + HOST_OS := Windows + else + HOST_OS := $(shell uname) + endif +endif + +ifeq ($(HOST_OS),Windows) + SERIALDUMP = serialdump-windows +endif + +ifeq ($(HOST_OS),Darwin) + SERIALDUMP = serialdump-macos +endif + +ifndef SERIALDUMP + # Assume Linux + SERIALDUMP = serialdump-linux +endif + +all: $(SERIALDUMP) + +$(SERIALDUMP): serialdump.c + $(CC) -O2 -o $@ $< diff --git a/tools/jn516x/mote-list.py b/tools/jn516x/mote-list.py new file mode 100644 index 000000000..170b04fdb --- /dev/null +++ b/tools/jn516x/mote-list.py @@ -0,0 +1,94 @@ +#!/usr/bin/python + +# Copyright (c) 2015, SICS Swedish ICT +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# 1. Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# 2. Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution. +# 3. Neither the name of the Institute nor the names of its contributors +# may be used to endorse or promote products derived from this software +# without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND +# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +# ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE +# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS +# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +# SUCH DAMAGE. +# +# This file is part of the Contiki operating system. +# + +import sys, os, platform +import multiprocessing + +# detect the operating system +sysname = platform.system() +if "Linux" in sysname: + IS_WINDOWS = False + FLASH_PROGRAMMER_DEFAULT_PATH = "/usr/jn-toolchain/tools/flashprogrammer/JennicModuleProgrammer" + import motelist_lib.linux_motelist_impl as motelist_impl # @UnusedImport + +elif ("Win" in sysname) or ("NT" in sysname): + IS_WINDOWS = True + FLASH_PROGRAMMER_DEFAULT_PATH = 'C:\\NXP\\bstudio_nxp\\sdk\\JN-SW-4163\\Tools\\flashprogrammer\\FlashCLI.exe' + import motelist_lib.windows_motelist_impl as motelist_impl # @Reimport @UnusedImport + +else: + print ("OS ('{}') is not supported".format(os.name)) + + +def main(): + # use the default location + flash_programmer = FLASH_PROGRAMMER_DEFAULT_PATH + if len(sys.argv) > 2: + flash_programmer=sys.argv[1] + + serial_dumper = "" + if len(sys.argv) > 3: + serial_dumper=sys.argv[3] + + motes = motelist_impl.list_motes(flash_programmer) + if motes: + motes.sort() + print 'Found %d JN516X motes at:' %(len(motes)) + motes_str = '' + for m in motes: + motes_str += "%s " %(str(m)) + print motes_str + + firmware_file='#' + if len(sys.argv) > 2: + firmware_file = sys.argv[2] + elif len(sys.argv) > 1: + firmware_file = sys.argv[1] + + if firmware_file[0] == '\\': + firmware_file = firmware_file[1:] + + if firmware_file not in ['#', '!', '?', '%']: + print '\nBatch programming all connected motes...\n' + motelist_impl.program_motes(flash_programmer, motes, firmware_file) + elif firmware_file == '?' or firmware_file == '!': + should_display_mac_list = (firmware_file == '!') + motelist_impl.print_info(flash_programmer, motes, should_display_mac_list) + elif firmware_file == '%': + print '\nLogging from all connected motes...\n' + motelist_impl.serialdump_ports(flash_programmer, serial_dumper, motes) + else: + print '\nNo firmware file specified.\n' + +if __name__ == '__main__': + multiprocessing.freeze_support() + main() diff --git a/tools/jn516x/motelist_lib/__init__.py b/tools/jn516x/motelist_lib/__init__.py new file mode 100644 index 000000000..e69de29bb diff --git a/tools/jn516x/motelist_lib/linux_motelist_impl.py b/tools/jn516x/motelist_lib/linux_motelist_impl.py new file mode 100644 index 000000000..231c7814f --- /dev/null +++ b/tools/jn516x/motelist_lib/linux_motelist_impl.py @@ -0,0 +1,220 @@ +# Copyright (c) 2015, SICS Swedish ICT +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# 1. Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# 2. Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution. +# 3. Neither the name of the Institute nor the names of its contributors +# may be used to endorse or promote products derived from this software +# without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND +# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +# ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE +# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS +# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +# SUCH DAMAGE. +# +# This file is part of the Contiki operating system. +# +# Author(s): +# Janis Judvaitis +# Atis Elsts + +import os, glob, re +import multiprocessing, subprocess + +FTDI_VENDOR_ID = "0403" +FTDI_PRODUCT_ID = "6001" + +doPrintVendorID = False + +def read_line(filename): + """helper function to read a single line from a file""" + line = "Unknown" + try: + with open(filename) as f: + line = f.readline().strip() + finally: + return line + +# try to extract descriptions from sysfs. this was done by experimenting, +# no guarantee that it works for all devices or in the future... + +def usb_sysfs_hw_string(sysfs_path): + """given a path to a usb device in sysfs, return a string describing it""" + snr = read_line(sysfs_path + '/serial') + if snr: + snr_txt = '%s' % (snr,) + else: + snr_txt = '' + if doPrintVendorID: + return 'USB VID:PID=%s:%s SNR=%s' % ( + read_line(sysfs_path + '/idVendor'), + read_line(sysfs_path + '/idProduct'), + snr_txt + ) + else: + return snr_txt + +def usb_string(sysfs_path): + # Get dir name in /sys/bus/usb/drivers/usb for current usb dev + dev = os.path.basename(os.path.realpath(sysfs_path)) + dev_dir = os.path.join("/sys/bus/usb/drivers/usb", dev) + + try: + # Go to usb dev directory + product = read_line(os.path.join(dev_dir, "product")) + manufacturer = read_line(os.path.join(dev_dir, "manufacturer")) + result = product + " by " + manufacturer + except: + result = "Unknown device" + + return result + +def describe(device): + """ + Get a human readable description. + For USB-Serial devices try to run lsusb to get a human readable description. + For USB-CDC devices read the description from sysfs. + """ + base = os.path.basename(device) + # USB-Serial devices + sys_dev_path = '/sys/class/tty/%s/device/driver/%s' % (base, base) + if os.path.exists(sys_dev_path): + sys_usb = os.path.dirname(os.path.dirname(os.path.realpath(sys_dev_path))) + return usb_string(sys_usb) + + # Arduino wants special handling + sys_dev_path = '/sys/class/tty/%s/device/driver/' % (base) + for x in os.listdir(sys_dev_path): + # Driver directory's name contains device ID in /sys/bus/usb/drivers/usb + temp = x.split(":") + if len(temp) == 2: + # No Arduino adds, need to save space! + return usb_string(temp[0]).replace("(www.arduino.cc)", "").strip() + + # USB-CDC devices + sys_dev_path = '/sys/class/tty/%s/device/interface' % (base,) + if os.path.exists(sys_dev_path): + return read_line(sys_dev_path) + + return base + +def hwinfo(device): + """Try to get a HW identification using sysfs""" + base = os.path.basename(device) + if os.path.exists('/sys/class/tty/%s/device' % (base,)): + # PCI based devices + sys_id_path = '/sys/class/tty/%s/device/id' % (base,) + if os.path.exists(sys_id_path): + return read_line(sys_id_path) + # USB-Serial devices + sys_dev_path = '/sys/class/tty/%s/device/driver/%s' % (base, base) + if os.path.exists(sys_dev_path): + sys_usb = os.path.dirname(os.path.dirname(os.path.realpath(sys_dev_path))) + return usb_sysfs_hw_string(sys_usb) + # USB-CDC devices + if base.startswith('ttyACM'): + sys_dev_path = '/sys/class/tty/%s/device' % (base,) + if os.path.exists(sys_dev_path): + return usb_sysfs_hw_string(sys_dev_path + '/..') + return 'n/a' # XXX directly remove these from the list? + +####################################### + +def is_nxp_mote(device): + base = os.path.basename(device) + # USB-Serial device? + sys_dev_path = '/sys/class/tty/%s/device/driver/%s' % (base, base) + if not os.path.exists(sys_dev_path): + return False + + path_usb = os.path.dirname(os.path.dirname(os.path.realpath(sys_dev_path))) + + dev = os.path.basename(os.path.realpath(path_usb)) + dev_dir = os.path.join("/sys/bus/usb/drivers/usb", dev) + + try: + idProduct = read_line(os.path.join(dev_dir, "idProduct")) + idVendor = read_line(os.path.join(dev_dir, "idVendor")) + if idVendor != FTDI_VENDOR_ID or idProduct != FTDI_PRODUCT_ID: + return False + product = read_line(os.path.join(dev_dir, "product")) + manufacturer = read_line(os.path.join(dev_dir, "manufacturer")) + if manufacturer != "NXP": + return False + except: + return False + return True + + +def list_motes(flash_programmer): + devices = glob.glob('/dev/ttyUSB*')# + glob.glob('/dev/ttyACM*') + return [d for d in devices if is_nxp_mote(d)] + + +def extract_information(port, stdout_value): + mac_str='Unknown' # not supported on Linux + info='' # not properly supported on Linux + is_program_success='' + + info = describe(port) + ", SerialID: " + hwinfo(port) + + res = re.compile('(Success)').search(stdout_value) + if res: + is_program_success = str(res.group(1)) + else: + res = re.compile('(Error .*)\n').search(stdout_value) + if res: + is_program_success = str(res.group(1)) + + return [mac_str, info, is_program_success] + + +def program_motes(flash_programmer, motes, firmware_file): + for m in motes: + cmd = [flash_programmer, '-v', '-s', m, '-I', '38400', '-P', '1000000', '-f', firmware_file] + cmd = " ".join(cmd) + proc = subprocess.Popen(cmd, shell=True, stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE,) + stdout_value, stderr_value = proc.communicate('through stdin to stdout') + [mac_str, info, is_program_success] = extract_information(m, stdout_value) + print m, is_program_success + + errors = (stderr_value) + if errors != '': + print 'Errors:', errors + + +def print_info(flash_programmer, motes, do_mac_only): + if do_mac_only: + print "Listing Mac addresses (not supported on Linux):" + else: + print "Listing mote info:" + + for m in motes: + [mac_str, info, is_program_success] = extract_information(m, '') + if do_mac_only: + print m, mac_str + else: + print m, '\n', info, '\n' + +def serialdump(args): + port_name = args[0] + serial_dumper = args[1] + rv = subprocess.call(serial_dumper + ' -b1000000 ' + port_name, shell=True) + +def serialdump_ports(flash_programmer, serial_dumper, ports): + p = multiprocessing.Pool() + p.map(serialdump, zip(ports, [serial_dumper] * len(ports))) + p.close() diff --git a/tools/jn516x/motelist_lib/windows_motelist_impl.py b/tools/jn516x/motelist_lib/windows_motelist_impl.py new file mode 100644 index 000000000..a4528484b --- /dev/null +++ b/tools/jn516x/motelist_lib/windows_motelist_impl.py @@ -0,0 +1,142 @@ +# Copyright (c) 2015, SICS Swedish ICT +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# 1. Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# 2. Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution. +# 3. Neither the name of the Institute nor the names of its contributors +# may be used to endorse or promote products derived from this software +# without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND +# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +# ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE +# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS +# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +# SUCH DAMAGE. +# +# This file is part of the Contiki operating system. +# +# Author(s): +# Simon Duquennoy +# Atis Elsts + +import os, re, subprocess, multiprocessing + +def list_motes(flash_programmer): + #There is no COM0 in windows. We use this to trigger an error message that lists all valid COM ports + cmd = [flash_programmer, '-c', 'COM0'] + proc = subprocess.Popen(cmd, shell=False, stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE,) + stdout_value, stderr_value = proc.communicate('through stdin to stdout') + com_str = (stderr_value) + #print '\tpass through:', repr(stdout_value) + #print '\tstderr :', com_str + + ## Extract COM ports from output: + ## Example com_str: "Available ports: ['COM15', 'COM10']" + res = re.compile('\[((?:\'COM\d+\'.?.?)+)\]').search(com_str) + + ports = [] + if res: + port_str=str(res.group(1)) + ports=port_str.replace('\'', '').replace(',', '').split() + return ports + +def extract_information(port, stdout_value): + mac_str='' + info='' + is_program_success='' + + #print 'output: ', stdout_value + +# res = re.compile('Connecting to device on (COM\d+)').search(stdout_value) +# if res: +# port_str = str(res.group(1)) + + ### extracting the following information + ''' + Devicelabel: JN516x, BL 0x00080006 + FlashLabel: Internal Flash (256K) + Memory: 0x00008000 bytes RAM, 0x00040000 bytes Flash + ChipPartNo: 8 + ChipRevNo: 1 + ROM Version: 0x00080006 + MAC Address: 00:15:8D:00:00:35:DD:FB + ZB License: 0x00.00.00.00.00.00.00.00.00.00.00.00.00.00.00.00 + User Data: 00:00:00:00:00:00:00:00 + FlashMID: 0xCC + FlashDID: 0xEE + MacLocation: 0x00000010 + Sector Length: 0x08000 + Bootloader Version: 0x00080006 + ''' + + res = re.compile('(Devicelabel.*\sFlashLabel.*\sMemory.*\sChipPartNo.*\sChipRevNo.*\sROM Version.*\sMAC Address.*\sZB License.*\sUser Data.*\sFlashMID.*\sFlashDID.*\sMacLocation.*\sSector Length.*\sBootloader Version\:\s+0x\w{8})').search(stdout_value) + if res: + info = str(res.group(1)) + + res = re.compile('MAC Address\:\s+((?:\w{2}\:?){8})').search(stdout_value) + if res: + mac_str = str(res.group(1)) + + res = re.compile('(Program\ssuccessfully\swritten\sto\sflash)').search(stdout_value) + if res: + is_program_success = str(res.group(1)) + + return [mac_str, info, is_program_success] + +def program_motes(flash_programmer, motes, firmware_file): + for m in motes: + cmd = [flash_programmer, '-c', m, '-B', '1000000', '-s', '-w', '-f', firmware_file] + proc = subprocess.Popen(cmd, shell=False, stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE,) + stdout_value, stderr_value = proc.communicate('through stdin to stdout') + [mac_str, info, is_program_success] = extract_information(m, stdout_value) + print m, mac_str, is_program_success + + errors = (stderr_value) + if errors != '': + print 'Errors:', errors + +def print_info(flash_programmer, motes, do_mac_only): + if do_mac_only: + print "Listing Mac addresses:" + else: + print "Listing mote info:" + for m in motes: + cmd=[flash_programmer, '-c', m, '-B', '1000000'] + proc = subprocess.Popen(cmd, shell=False, stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE,) + stdout_value, stderr_value = proc.communicate('through stdin to stdout') + [mac_str, info, is_program_success] = extract_information(m, stdout_value) + + errors = (stderr_value) + + if do_mac_only: + print m, mac_str + else: + print m, '\n', info, '\n' + + if errors != '': + print 'Errors:', errors + +def serialdump(args): + port_name = args[0] + serial_dumper = args[1] + cmd = [serial_dumper, '-b1000000', "/dev/" + port_name.lower()] + if os.name == "posix" or os.name == "cygwin": + cmd = " ".join(cmd) + rv = subprocess.call(cmd, shell=True) + +def serialdump_ports(flash_programmer, serial_dumper, ports): + p = multiprocessing.Pool() + p.map(serialdump, zip(ports, [serial_dumper] * len(ports))) + p.close() diff --git a/tools/jn516x/serialdump.c b/tools/jn516x/serialdump.c new file mode 100644 index 000000000..26b0884e2 --- /dev/null +++ b/tools/jn516x/serialdump.c @@ -0,0 +1,396 @@ +#define _GNU_SOURCE +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define BAUDRATE B115200 +#define BAUDRATE_S "115200" +#ifdef linux +#define MODEMDEVICE "/dev/ttyS0" +#else +#define MODEMDEVICE "/dev/com1" +#endif /* linux */ + +#define SLIP_END 0300 +#define SLIP_ESC 0333 +#define SLIP_ESC_END 0334 +#define SLIP_ESC_ESC 0335 + +#define CSNA_INIT 0x01 + +#define BUFSIZE 40 +#define HCOLS 20 +#define ICOLS 18 + +#define MODE_START_DATE 0 +#define MODE_DATE 1 +#define MODE_START_TEXT 2 +#define MODE_TEXT 3 +#define MODE_INT 4 +#define MODE_HEX 5 +#define MODE_SLIP_AUTO 6 +#define MODE_SLIP 7 +#define MODE_SLIP_HIDE 8 + +static unsigned char rxbuf[2048]; + +static int +usage(int result) +{ + printf("Usage: serialdump [-x] [-s[on]] [-i] [-bSPEED] [SERIALDEVICE]\n"); + printf(" -x for hexadecimal output\n"); + printf(" -i for decimal output\n"); + printf(" -s for automatic SLIP mode\n"); + printf(" -so for SLIP only mode (all data is SLIP packets)\n"); + printf(" -sn to hide SLIP packages\n"); + printf(" -T[format] to add time for each text line\n"); + printf(" (see man page for strftime() for format description)\n"); + return result; +} + +static void +print_hex_line(unsigned char *prefix, unsigned char *outbuf, int index) +{ + int i; + + printf("\r%s", prefix); + for(i = 0; i < index; i++) { + if((i % 4) == 0) { + printf(" "); + } + printf("%02X", outbuf[i] & 0xFF); + } + printf(" "); + for(i = index; i < HCOLS; i++) { + if((i % 4) == 0) { + printf(" "); + } + printf(" "); + } + for(i = 0; i < index; i++) { + if(outbuf[i] < 30 || outbuf[i] > 126) { + printf("."); + } else { + printf("%c", outbuf[i]); + } + } +} + +int +main(int argc, char **argv) +{ + struct termios options; + fd_set mask, smask; + int fd; + speed_t speed = BAUDRATE; + char *speedname = BAUDRATE_S; + char *device = MODEMDEVICE; + char *timeformat = NULL; + unsigned char buf[BUFSIZE], outbuf[HCOLS]; + unsigned char mode = MODE_START_TEXT; + int nfound, flags = 0; + unsigned char lastc = '\0'; + + int index = 1; + while(index < argc) { + if(argv[index][0] == '-') { + switch(argv[index][1]) { + case 'b': + /* set speed */ + if(strcmp(&argv[index][2], "38400") == 0) { + speed = B38400; + speedname = "38400"; + } else if(strcmp(&argv[index][2], "19200") == 0) { + speed = B19200; + speedname = "19200"; + } else if(strcmp(&argv[index][2], "57600") == 0) { + speed = B57600; + speedname = "57600"; + } else if(strcmp(&argv[index][2], "115200") == 0) { + speed = B115200; + speedname = "115200"; + } else if(strcmp(&argv[index][2], "230400") == 0) { + speed = B230400; + speedname = "230400"; + } else if(strcmp(&argv[index][2], "460800") == 0) { + speed = B460800; + speedname = "460800"; + } else if(strcmp(&argv[index][2], "500000") == 0) { + speed = B500000; + speedname = "500000"; + } else if(strcmp(&argv[index][2], "576000") == 0) { + speed = B576000; + speedname = "576000"; + } else if(strcmp(&argv[index][2], "921600") == 0) { + speed = B921600; + speedname = "921600"; + } else if(strcmp(&argv[index][2], "1000000") == 0) { + speed = B1000000; + speedname = "1000000"; + } else { + fprintf(stderr, "unsupported speed: %s\n", &argv[index][2]); + return usage(1); + } + break; + case 'x': + mode = MODE_HEX; + break; + case 'i': + mode = MODE_INT; + break; + case 's': + switch(argv[index][2]) { + case 'n': + mode = MODE_SLIP_HIDE; + break; + case 'o': + mode = MODE_SLIP; + break; + default: + mode = MODE_SLIP_AUTO; + break; + } + break; + case 'T': + if(strlen(&argv[index][2]) == 0) { + timeformat = "%Y-%m-%d %H:%M:%S"; + } else { + timeformat = &argv[index][2]; + } + mode = MODE_START_DATE; + break; + case 'h': + return usage(0); + default: + fprintf(stderr, "unknown option '%c'\n", argv[index][1]); + return usage(1); + } + index++; + } else { + device = argv[index++]; + if(index < argc) { + fprintf(stderr, "too many arguments\n"); + return usage(1); + } + } + } + fprintf(stderr, "connecting to %s (%s)", device, speedname); + +#ifdef O_SYNC + fd = open(device, O_RDWR | O_NOCTTY | O_NDELAY /*| O_DIRECT*/ | O_SYNC); + if(fd < 0 && errno == EINVAL){ // O_SYNC not supported (e.g. raspberian) + fd = open(device, O_RDWR | O_NOCTTY | O_NDELAY | O_DIRECT); + } +#else + fd = open(device, O_RDWR | O_NOCTTY | O_NDELAY | O_SYNC ); +#endif + if(fd < 0) { + fprintf(stderr, "\n"); + perror("open"); + exit(-1); + } + fprintf(stderr, " [OK]\n"); + + if(fcntl(fd, F_SETFL, 0) < 0) { + perror("could not set fcntl"); + exit(-1); + } + + if(tcgetattr(fd, &options) < 0) { + perror("could not get options"); + exit(-1); + } + /* fprintf(stderr, "serial options set\n"); */ + cfsetispeed(&options, speed); + cfsetospeed(&options, speed); + /* Enable the receiver and set local mode */ + options.c_cflag |= (CLOCAL | CREAD); + /* Mask the character size bits and turn off (odd) parity */ + options.c_cflag &= ~(CSIZE | PARENB | PARODD); + /* Select 8 data bits */ + options.c_cflag |= CS8; + + /* Raw input */ + options.c_lflag &= ~(ICANON | ECHO | ECHOE | ISIG); + /* Raw output */ + options.c_oflag &= ~OPOST; + + if(tcsetattr(fd, TCSANOW, &options) < 0) { + perror("could not set options"); + exit(-1); + } + + /* Make read() return immediately */ + /* if (fcntl(fd, F_SETFL, FNDELAY) < 0) { */ + /* perror("\ncould not set fcntl"); */ + /* exit(-1); */ + /* } */ + + FD_ZERO(&mask); + FD_SET(fd, &mask); + FD_SET(fileno(stdin), &mask); + + index = 0; + for(;;) { + smask = mask; + nfound = select(FD_SETSIZE, &smask, (fd_set *) 0, (fd_set *) 0, (struct timeval *) 0); + if(nfound < 0) { + if(errno == EINTR) { + fprintf(stderr, "interrupted system call\n"); + continue; + } + /* something is very wrong! */ + perror("select"); + exit(1); + } + + if(FD_ISSET(fileno(stdin), &smask)) { + /* data from standard in */ + int n = read(fileno(stdin), buf, sizeof(buf)); + if(n < 0) { + perror("could not read"); + exit(-1); + } else if(n > 0) { + /* because commands might need parameters, lines needs to be + separated which means the terminating LF must be sent */ + /* while(n > 0 && buf[n - 1] < 32) { */ + /* n--; */ + /* } */ + if(n > 0) { + int i; + /* fprintf(stderr, "SEND %d bytes\n", n);*/ + /* write slowly */ + for(i = 0; i < n; i++) { + if(write(fd, &buf[i], 1) <= 0) { + perror("write"); + exit(1); + } else { + fflush(NULL); + usleep(6000); + } + } + } + } else { + /* End of input, exit. */ + exit(0); + } + } + + if(FD_ISSET(fd, &smask)) { + int i, j, n = read(fd, buf, sizeof(buf)); + if(n < 0) { + perror("could not read"); + exit(-1); + } + + for(i = 0; i < n; i++) { + switch(mode) { + case MODE_START_TEXT: + case MODE_TEXT: + printf("%c", buf[i]); + break; + case MODE_START_DATE: { + time_t t; + t = time(&t); + strftime(outbuf, HCOLS, timeformat, localtime(&t)); + printf("%s|", outbuf); + mode = MODE_DATE; + } + /* continue into the MODE_DATE */ + case MODE_DATE: + printf("%c", buf[i]); + if(buf[i] == '\n') { + mode = MODE_START_DATE; + } + break; + case MODE_INT: + printf("%03d ", buf[i]); + if(++index >= ICOLS) { + index = 0; + printf("\n"); + } + break; + case MODE_HEX: + rxbuf[index++] = buf[i]; + if(index >= HCOLS) { + print_hex_line("", rxbuf, index); + index = 0; + printf("\n"); + } + break; + + case MODE_SLIP_AUTO: + case MODE_SLIP_HIDE: + if(!flags && (buf[i] != SLIP_END)) { + /* Not a SLIP packet? */ + printf("%c", buf[i]); + break; + } + /* continue to slip only mode */ + case MODE_SLIP: + switch(buf[i]) { + case SLIP_ESC: + lastc = SLIP_ESC; + break; + + case SLIP_END: + if(index > 0) { + if(flags != 2 && mode != MODE_SLIP_HIDE) { + /* not overflowed: show packet */ + print_hex_line("SLIP: ", rxbuf, index > HCOLS ? HCOLS : index); + printf("\n"); + } + lastc = '\0'; + index = 0; + flags = 0; + } else { + flags = !flags; + } + break; + + default: + if(lastc == SLIP_ESC) { + lastc = '\0'; + + /* Previous read byte was an escape byte, so this byte will be + interpreted differently from others. */ + switch(buf[i]) { + case SLIP_ESC_END: + buf[i] = SLIP_END; + break; + case SLIP_ESC_ESC: + buf[i] = SLIP_ESC; + break; + } + } + + rxbuf[index++] = buf[i]; + if(index >= sizeof(rxbuf)) { + fprintf(stderr, "**** slip overflow\n"); + index = 0; + flags = 2; + } + break; + } + break; + } + } + + /* after processing for some output modes */ + if(index > 0) { + switch(mode) { + case MODE_HEX: + print_hex_line("", rxbuf, index); + break; + } + } + fflush(stdout); + } + } +} From 0780e1a051a06041ddede8aa54e711da5226d98d Mon Sep 17 00:00:00 2001 From: Simon Duquennoy Date: Mon, 21 Sep 2015 11:00:32 +0200 Subject: [PATCH 094/120] Added NXP JN516x examples --- examples/jn516x/README.md | 5 + examples/jn516x/dr1175-sensors/Makefile | 12 + examples/jn516x/dr1175-sensors/README.md | 2 + examples/jn516x/dr1175-sensors/node.c | 88 ++++ examples/jn516x/dr1175-sensors/project-conf.h | 47 +++ examples/jn516x/rime/Makefile | 11 + examples/jn516x/rime/README.md | 1 + examples/jn516x/rime/node.c | 124 ++++++ examples/jn516x/rime/project-conf.h | 68 +++ examples/jn516x/rpl/README.md | 43 ++ examples/jn516x/rpl/border-router/Makefile | 31 ++ examples/jn516x/rpl/border-router/README.md | 10 + .../jn516x/rpl/border-router/border-router.c | 97 +++++ .../jn516x/rpl/border-router/project-conf.h | 48 +++ .../jn516x/rpl/border-router/slip-bridge.c | 161 +++++++ examples/jn516x/rpl/coap-dongle-node/Makefile | 21 + .../jn516x/rpl/coap-dongle-node/README.md | 16 + .../jn516x/rpl/coap-dongle-node/dongle-node.c | 145 +++++++ .../rpl/coap-dongle-node/project-conf.h | 39 ++ examples/jn516x/rpl/coap-dr1175-node/Makefile | 21 + .../jn516x/rpl/coap-dr1175-node/README.md | 24 ++ .../jn516x/rpl/coap-dr1175-node/dr1175-node.c | 395 ++++++++++++++++++ .../rpl/coap-dr1175-node/project-conf.h | 39 ++ examples/jn516x/rpl/coap-dr1199-node/Makefile | 21 + .../jn516x/rpl/coap-dr1199-node/README.md | 33 ++ .../jn516x/rpl/coap-dr1199-node/dr1199-node.c | 389 +++++++++++++++++ .../rpl/coap-dr1199-node/project-conf.h | 39 ++ examples/jn516x/rpl/common-conf.h | 85 ++++ examples/jn516x/rpl/node/Makefile | 14 + examples/jn516x/rpl/node/README.md | 18 + examples/jn516x/rpl/node/node.c | 108 +++++ examples/jn516x/rpl/node/project-conf.h | 40 ++ examples/jn516x/rpl/tools/rpl-tools.c | 83 ++++ examples/jn516x/rpl/tools/rpl-tools.h | 35 ++ 34 files changed, 2313 insertions(+) create mode 100644 examples/jn516x/README.md create mode 100644 examples/jn516x/dr1175-sensors/Makefile create mode 100644 examples/jn516x/dr1175-sensors/README.md create mode 100644 examples/jn516x/dr1175-sensors/node.c create mode 100644 examples/jn516x/dr1175-sensors/project-conf.h create mode 100644 examples/jn516x/rime/Makefile create mode 100644 examples/jn516x/rime/README.md create mode 100644 examples/jn516x/rime/node.c create mode 100644 examples/jn516x/rime/project-conf.h create mode 100644 examples/jn516x/rpl/README.md create mode 100644 examples/jn516x/rpl/border-router/Makefile create mode 100644 examples/jn516x/rpl/border-router/README.md create mode 100644 examples/jn516x/rpl/border-router/border-router.c create mode 100644 examples/jn516x/rpl/border-router/project-conf.h create mode 100644 examples/jn516x/rpl/border-router/slip-bridge.c create mode 100644 examples/jn516x/rpl/coap-dongle-node/Makefile create mode 100644 examples/jn516x/rpl/coap-dongle-node/README.md create mode 100644 examples/jn516x/rpl/coap-dongle-node/dongle-node.c create mode 100644 examples/jn516x/rpl/coap-dongle-node/project-conf.h create mode 100644 examples/jn516x/rpl/coap-dr1175-node/Makefile create mode 100644 examples/jn516x/rpl/coap-dr1175-node/README.md create mode 100644 examples/jn516x/rpl/coap-dr1175-node/dr1175-node.c create mode 100644 examples/jn516x/rpl/coap-dr1175-node/project-conf.h create mode 100644 examples/jn516x/rpl/coap-dr1199-node/Makefile create mode 100644 examples/jn516x/rpl/coap-dr1199-node/README.md create mode 100644 examples/jn516x/rpl/coap-dr1199-node/dr1199-node.c create mode 100644 examples/jn516x/rpl/coap-dr1199-node/project-conf.h create mode 100644 examples/jn516x/rpl/common-conf.h create mode 100644 examples/jn516x/rpl/node/Makefile create mode 100644 examples/jn516x/rpl/node/README.md create mode 100644 examples/jn516x/rpl/node/node.c create mode 100644 examples/jn516x/rpl/node/project-conf.h create mode 100644 examples/jn516x/rpl/tools/rpl-tools.c create mode 100644 examples/jn516x/rpl/tools/rpl-tools.h diff --git a/examples/jn516x/README.md b/examples/jn516x/README.md new file mode 100644 index 000000000..06ccc0da7 --- /dev/null +++ b/examples/jn516x/README.md @@ -0,0 +1,5 @@ +Examples for the JN516x platform. +* dr1175: simple Contiki application for the DR1175 evaluation board. Prints out sensor values periodically. +* rime: simple Rime example. Works with ContikiMAC (default) or NullRDC +* RPL: RPL examples, including border router, simple node, and coap resources. More information under rpl/README.md + \ No newline at end of file diff --git a/examples/jn516x/dr1175-sensors/Makefile b/examples/jn516x/dr1175-sensors/Makefile new file mode 100644 index 000000000..3fbf3a246 --- /dev/null +++ b/examples/jn516x/dr1175-sensors/Makefile @@ -0,0 +1,12 @@ +CONTIKI=../../.. +CONTIKI_PROJECT = node +CFLAGS += -DPROJECT_CONF_H=\"project-conf.h\" + +TARGET ?= jn516x +JN516x_WITH_DR1175 = 1 + +CONTIKI_WITH_RIME = 1 + +all: $(CONTIKI_PROJECT) + +include $(CONTIKI)/Makefile.include diff --git a/examples/jn516x/dr1175-sensors/README.md b/examples/jn516x/dr1175-sensors/README.md new file mode 100644 index 000000000..0b49024c2 --- /dev/null +++ b/examples/jn516x/dr1175-sensors/README.md @@ -0,0 +1,2 @@ +Sensor test for DR1175 evaluation board (light + temp/humidity). +Reads and prints out various sensor samples every second. diff --git a/examples/jn516x/dr1175-sensors/node.c b/examples/jn516x/dr1175-sensors/node.c new file mode 100644 index 000000000..bf1b4c89b --- /dev/null +++ b/examples/jn516x/dr1175-sensors/node.c @@ -0,0 +1,88 @@ +/* + * Copyright (c) 2015, SICS Swedish ICT. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the Institute nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + */ +/** + * \author Atis Elsts + * \file + * Sensor test for DR1175 evaluation board (light + temp/humidity). + */ + +#include "contiki.h" + +#include "light-sensor.h" +#include "ht-sensor.h" +#include "leds.h" + +/*---------------------------------------------------------------------------*/ +PROCESS(test_process, "Sensor test process"); +AUTOSTART_PROCESSES(&test_process); +/*---------------------------------------------------------------------------*/ +PROCESS_THREAD(test_process, ev, data) +{ + static struct etimer et; + static uint8_t led_status; + uint8_t r, g, b; + int val; + + PROCESS_BEGIN(); + + puts("initializing sensors..."); + + /* Make sensor active for measuring */ + SENSORS_ACTIVATE(light_sensor); + SENSORS_ACTIVATE(ht_sensor); + + /* Set level for LEDSs */ + leds_set_level(255, LEDS_RED | LEDS_GREEN | LEDS_BLUE | LEDS_WHITE); + + while(1) { + etimer_set(&et, CLOCK_SECOND * 1); + + PROCESS_WAIT_EVENT_UNTIL(etimer_expired(&et)); + + puts("reading sensors..."); + + val = ht_sensor.value(HT_SENSOR_HUM); + printf("humidity: %d\n", val); + + val = ht_sensor.value(HT_SENSOR_TEMP); + printf("temperature: %d\n", val); + + led_status++; + r = ((led_status & 0x1) ? LEDS_RED : 0); + g = ((led_status & 0x2) ? LEDS_GREEN : 0); + b = ((led_status & 0x4) ? LEDS_BLUE : 0); + + leds_toggle((leds_get() ^ (r | g | b)) | LEDS_WHITE); + + puts(""); + } + PROCESS_END(); +} +/*---------------------------------------------------------------------------*/ diff --git a/examples/jn516x/dr1175-sensors/project-conf.h b/examples/jn516x/dr1175-sensors/project-conf.h new file mode 100644 index 000000000..906efff45 --- /dev/null +++ b/examples/jn516x/dr1175-sensors/project-conf.h @@ -0,0 +1,47 @@ +/* + * Copyright (c) 2015, SICS Swedish ICT. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the Institute nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + */ +/** + * \author Atis Elsts + */ + +#ifndef __PROJECT_CONF_H__ +#define __PROJECT_CONF_H__ + +#undef NETSTACK_CONF_RDC +#undef NETSTACK_CONF_FRAMER +#undef NETSTACK_CONF_MAC +#undef NETSTACK_CONF_NETWORK + +#define NETSTACK_CONF_RDC nullrdc_driver +#define NETSTACK_CONF_FRAMER framer_802154 +#define NETSTACK_CONF_MAC csma_driver +#define NETSTACK_CONF_NETWORK rime_driver + +#endif /* __PROJECT_CONF_H__ */ diff --git a/examples/jn516x/rime/Makefile b/examples/jn516x/rime/Makefile new file mode 100644 index 000000000..02262937e --- /dev/null +++ b/examples/jn516x/rime/Makefile @@ -0,0 +1,11 @@ +CONTIKI=../../.. +CONTIKI_PROJECT = node +CFLAGS += -DPROJECT_CONF_H=\"project-conf.h\" + +TARGET ?= jn516x + +CONTIKI_WITH_RIME = 1 + +all: $(CONTIKI_PROJECT) + +include $(CONTIKI)/Makefile.include diff --git a/examples/jn516x/rime/README.md b/examples/jn516x/rime/README.md new file mode 100644 index 000000000..1f693c6ae --- /dev/null +++ b/examples/jn516x/rime/README.md @@ -0,0 +1 @@ +A simple Rime + ContikiMAC code example. diff --git a/examples/jn516x/rime/node.c b/examples/jn516x/rime/node.c new file mode 100644 index 000000000..261fd61ad --- /dev/null +++ b/examples/jn516x/rime/node.c @@ -0,0 +1,124 @@ +/* + * Copyright (c) 2015, SICS Swedish ICT. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the Institute nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + */ +/** + * \author Atis Elsts + * \file + * ContikiMAC + Rime stack test for JN516x platform. + */ + +#include "contiki-conf.h" +#include "net/rime/rime.h" + +#if 0 +#define RX_ADDR1 140 +#define RX_ADDR2 228 +#else +#define RX_ADDR1 7 +#define RX_ADDR2 0 +#endif + +#define MAX_RETRANSMISSIONS 4 + +/*---------------------------------------------------------------------------*/ +PROCESS(unicast_test_process, "ContikiMAC Node"); +AUTOSTART_PROCESSES(&unicast_test_process); + +static void +recv_runicast(struct runicast_conn *c, const linkaddr_t *from, uint8_t seqno) +{ + printf("runicast message received from %d.%d, seqno %d, len %d: '%s'\n", + from->u8[0], from->u8[1], seqno, packetbuf_datalen(), (char *)packetbuf_dataptr()); +} +static void +sent_runicast(struct runicast_conn *c, const linkaddr_t *to, uint8_t retransmissions) +{ + printf("runicast message sent to %d.%d, retransmissions %d\n", + to->u8[0], to->u8[1], retransmissions); +} +static void +timedout_runicast(struct runicast_conn *c, const linkaddr_t *to, uint8_t retransmissions) +{ + printf("runicast message timed out when sending to %d.%d, retransmissions %d\n", + to->u8[0], to->u8[1], retransmissions); +} +static const struct runicast_callbacks runicast_callbacks = { recv_runicast, + sent_runicast, + timedout_runicast }; +static struct runicast_conn runicast; +/*---------------------------------------------------------------------------*/ +PROCESS_THREAD(unicast_test_process, ev, data) +{ + PROCESS_BEGIN(); + + puts("unicast test start"); + + runicast_open(&runicast, 144, &runicast_callbacks); + + /* Receiver node: do nothing */ + if(linkaddr_node_addr.u8[0] == RX_ADDR1 && + linkaddr_node_addr.u8[1] == RX_ADDR2) { + puts("wait forever"); + } + while(1) { + static struct etimer et; + static int seqno; + + etimer_set(&et, CLOCK_SECOND * 5); + + PROCESS_WAIT_EVENT_UNTIL(etimer_expired(&et)); + + if(linkaddr_node_addr.u8[0] == RX_ADDR1 && + linkaddr_node_addr.u8[1] == RX_ADDR2) { + puts("tick..."); + continue; + } + + if(!runicast_is_transmitting(&runicast)) { + linkaddr_t recv = { 0 }; + static char buffer[100] = "hello"; + + packetbuf_copyfrom(buffer, sizeof(buffer)); + recv.u8[0] = RX_ADDR1; + recv.u8[1] = RX_ADDR2; + + printf("%u.%u: sending runicast to address %u.%u\n", + linkaddr_node_addr.u8[0], + linkaddr_node_addr.u8[1], + recv.u8[0], + recv.u8[1]); + + packetbuf_set_attr(PACKETBUF_ATTR_PACKET_ID, ++seqno); + runicast_send(&runicast, &recv, MAX_RETRANSMISSIONS); + } + } + + PROCESS_END(); +} +/*---------------------------------------------------------------------------*/ diff --git a/examples/jn516x/rime/project-conf.h b/examples/jn516x/rime/project-conf.h new file mode 100644 index 000000000..84e1cae06 --- /dev/null +++ b/examples/jn516x/rime/project-conf.h @@ -0,0 +1,68 @@ +/* + * Copyright (c) 2015, SICS Swedish ICT. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the Institute nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + */ +/** + * \author Atis Elsts + */ + +#ifndef __PROJECT_CONF_H__ +#define __PROJECT_CONF_H__ + +#undef NETSTACK_CONF_RDC +#undef NETSTACK_CONF_FRAMER +#undef NETSTACK_CONF_MAC +#undef NETSTACK_CONF_NETWORK + +#if 1 +#define NETSTACK_CONF_RDC contikimac_driver +#define NETSTACK_CONF_FRAMER contikimac_framer +#else +#define NETSTACK_CONF_RDC nullrdc_driver +#define NETSTACK_CONF_FRAMER framer_802154 +#endif + +#define NETSTACK_CONF_MAC csma_driver +#define NETSTACK_CONF_NETWORK rime_driver + +#undef UIP_CONF_IPV6 +#define UIP_CONF_IPV6 0 + +#undef RF_CHANNEL +#define RF_CHANNEL 25 + +#undef MICROMAC_CONF_CHANNEL +#define MICROMAC_CONF_CHANNEL RF_CHANNEL + +#undef CC2420_CONF_CHANNEL +#define CC2420_CONF_CHANNEL RF_CHANNEL + +#undef MICROMAC_CONF_AUTOACK +#define MICROMAC_CONF_AUTOACK 1 + +#endif /* __PROJECT_CONF_H__ */ diff --git a/examples/jn516x/rpl/README.md b/examples/jn516x/rpl/README.md new file mode 100644 index 000000000..39a213268 --- /dev/null +++ b/examples/jn516x/rpl/README.md @@ -0,0 +1,43 @@ +# HOWTO - Setting up the RPL Border router and other nodes + +In this folder we have a fully functional demonstrator with the components: + +1. **RPL border router**: to start the wireless network and connect it to other networks. +2. and a **wireless node** that acts as a basic RPL node by default (but can optionally be used configured as DAG Root) + +## RICH RPL Border Router + +Setup the UART flow-control mode for the router from border-router/project-conf.h + +* Enable either **HW flow control** +```C +#define UART_HW_FLOW_CTRL 1 +#define UART_XONXOFF_FLOW_CTRL 0 +``` +* or **SW flow control** +```C +#define UART_HW_FLOW_CTRL 0 +#define UART_XONXOFF_FLOW_CTRL 1 +``` +* You can disable both, but it is not recommended. + +Compile and flash a node with the rpl-border-router.jn516x.bin image. Either a USB dongle or a dev-board would work. + +From a Linux terminal, go to `contiki/examples/jn516x/rpl/border-router` and do either +`make connect-router-hw` if you have **HW flow control** +or `make connect-router-sw` if you have **SW flow control** + +This will start a tunnel interface (tun0) on the host machine. +All traffic towards our network (prefix aaaa::1/64) will now be routed to the border router. + +## RPL Node + +The directory contiki-private/examples/jn516x/rpl/node contains a basic RICH node running TSCH and RPL. +You can compile and program more NXP nodes to run this, forming a larger network. +You should be able to ping the nodes (you can obtain their IPv6 address either directly from their log output +or by enabling DEBUG output in rpl-icmp6.c and looking at DAO prefixes being added. + +## RPL+CoAP Nodes + +coap-*-node are example nodes that expose their sensors as CoAP resources. See README.md files from the sub-directories +for more details. diff --git a/examples/jn516x/rpl/border-router/Makefile b/examples/jn516x/rpl/border-router/Makefile new file mode 100644 index 000000000..53598e492 --- /dev/null +++ b/examples/jn516x/rpl/border-router/Makefile @@ -0,0 +1,31 @@ +CONTIKI_PROJECT = border-router +all: $(CONTIKI_PROJECT) + +TARGET ?= jn516x + +CONTIKI=../../../.. + +CONTIKI_WITH_IPV6 = 1 + +PROJECTDIRS += .. ../tools +PROJECT_SOURCEFILES += rpl-tools.c +CFLAGS += -DPROJECT_CONF_H=\"project-conf.h\" +PROJECT_SOURCEFILES += slip-bridge.c slip.c + +ifeq ($(PREFIX),) + PREFIX = aaaa::1/64 +endif + +include $(CONTIKI)/Makefile.include + +#using XON/XOFF flow control +connect-router-sw: $(CONTIKI)/tools/tunslip6 + sudo $(CONTIKI)/tools/tunslip6 -X -B 1000000 $(PREFIX) + +#using hw flow control +connect-router-hw: $(CONTIKI)/tools/tunslip6 + sudo $(CONTIKI)/tools/tunslip6 -H -B 1000000 $(PREFIX) + +#using no flow control +connect-router-no: $(CONTIKI)/tools/tunslip6 + sudo $(CONTIKI)/tools/tunslip6 -B 1000000 $(PREFIX) diff --git a/examples/jn516x/rpl/border-router/README.md b/examples/jn516x/rpl/border-router/README.md new file mode 100644 index 000000000..c2af3f3b6 --- /dev/null +++ b/examples/jn516x/rpl/border-router/README.md @@ -0,0 +1,10 @@ +A RPL border router. +To indicate the hardware target for the border router, add one of the following +options in the command line: +If rpl-border-router runs on dongle: +JN516x_WITH_DONGLE=1 +If rpl-border-router runs on DR1174: +JN516x_WITH_DR1174=1 +If building for a new platform, first execute : make clean + +See ../README.md for more. \ No newline at end of file diff --git a/examples/jn516x/rpl/border-router/border-router.c b/examples/jn516x/rpl/border-router/border-router.c new file mode 100644 index 000000000..d36130607 --- /dev/null +++ b/examples/jn516x/rpl/border-router/border-router.c @@ -0,0 +1,97 @@ +/* + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the Institute nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * This file is part of the Contiki operating system. + * + */ + +#include "contiki.h" +#include "net/rpl/rpl.h" +#include "tools/rpl-tools.h" + +#define DEBUG DEBUG_PRINT +#include "net/ip/uip-debug.h" + +static uip_ipaddr_t prefix; +static uint8_t prefix_set; + +PROCESS(border_router_process, "Border router process"); + +AUTOSTART_PROCESSES(&border_router_process); + +/*---------------------------------------------------------------------------*/ +void +request_prefix(void) +{ + /* mess up uip_buf with a dirty request... */ + uip_buf[0] = '?'; + uip_buf[1] = 'P'; +/* uip_buf[2] = '\n'; */ + uip_len = 2; + slip_send(); + uip_len = 0; +} +/*---------------------------------------------------------------------------*/ +void +set_prefix_64(uip_ipaddr_t *prefix_64) +{ + memcpy(&prefix, prefix_64, 16); + prefix_set = 1; +} +/*---------------------------------------------------------------------------*/ +PROCESS_THREAD(border_router_process, ev, data) +{ + static struct etimer et; + + PROCESS_BEGIN(); + +/* While waiting for the prefix to be sent through the SLIP connection, the future + * border router can join an existing DAG as a parent or child, or acquire a default + * router that will later take precedence over the SLIP fallback interface. + * Prevent that by turning the radio off until we are initialized as a DAG root. + */ + prefix_set = 0; + + PROCESS_PAUSE(); + + PRINTF("RPL-Border router started\n"); + + /* Request prefix until it has been received */ + while(!prefix_set) { + etimer_set(&et, CLOCK_SECOND); + request_prefix(); + PROCESS_WAIT_EVENT_UNTIL(etimer_expired(&et)); + PRINTF("Waiting for prefix\n"); + } + + PRINTF("Obtained prefix: "); + uip_debug_ipaddr_print(&prefix); + PRINTF("\n"); + + rpl_tools_init(&prefix); + + PROCESS_END(); +} +/*---------------------------------------------------------------------------*/ diff --git a/examples/jn516x/rpl/border-router/project-conf.h b/examples/jn516x/rpl/border-router/project-conf.h new file mode 100644 index 000000000..2489905a6 --- /dev/null +++ b/examples/jn516x/rpl/border-router/project-conf.h @@ -0,0 +1,48 @@ +/* + * Copyright (c) 2015, SICS Swedish ICT. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the Institute nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + */ + +/** + * \author Simon Duquennoy + */ + +#ifndef BR_PROJECT_CONF_H_ +#define BR_PROJECT_CONF_H_ + +#ifndef UIP_FALLBACK_INTERFACE +#define UIP_FALLBACK_INTERFACE rpl_interface +#endif + +/* Needed for slip-bridge */ +#undef SLIP_BRIDGE_CONF_NO_PUTCHAR +#define SLIP_BRIDGE_CONF_NO_PUTCHAR 0 + +#include "../common-conf.h" + +#endif /* PROJECT_CONF_H_ */ diff --git a/examples/jn516x/rpl/border-router/slip-bridge.c b/examples/jn516x/rpl/border-router/slip-bridge.c new file mode 100644 index 000000000..e3b0f814b --- /dev/null +++ b/examples/jn516x/rpl/border-router/slip-bridge.c @@ -0,0 +1,161 @@ +/* + * Copyright (c) 2010, SICS Swedish ICT. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the Institute nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + */ + +/** + * \file + * Slip fallback interface + * \author + * Niclas Finne + * Joakim Eriksson + * Joel Hoglund + * Nicolas Tsiftes + */ + +#include "net/ip/uip.h" +#include "net/ipv6/uip-ds6.h" +#include "dev/slip.h" +#if CONTIKI_TARGET_JN516X +#include "dev/uart0.h" +#else +#include "dev/uart1.h" +#endif +#include + +#define UIP_IP_BUF ((struct uip_ip_hdr *)&uip_buf[UIP_LLH_LEN]) + +#define DEBUG DEBUG_NONE +#include "net/ip/uip-debug.h" + +#ifndef BAUD2UBR +#define BAUD2UBR(X) (X) +#endif + +void set_prefix_64(uip_ipaddr_t *); + +static uip_ipaddr_t last_sender; +/*---------------------------------------------------------------------------*/ +static void +slip_input_callback(void) +{ + PRINTF("SIN: %u\n", uip_len); + if(uip_buf[0] == '!') { + PRINTF("Got configuration message of type %c\n", uip_buf[1]); + uip_len = 0; + if(uip_buf[1] == 'P') { + uip_ipaddr_t prefix; + /* Here we set a prefix !!! */ + memset(&prefix, 0, 16); + memcpy(&prefix, &uip_buf[2], 8); + PRINTF("Setting prefix "); + PRINT6ADDR(&prefix); + PRINTF("\n"); + set_prefix_64(&prefix); + } + } else if(uip_buf[0] == '?') { + PRINTF("Got request message of type %c\n", uip_buf[1]); + if(uip_buf[1] == 'M') { + char *hexchar = "0123456789abcdef"; + int j; + /* this is just a test so far... just to see if it works */ + uip_buf[0] = '!'; + for(j = 0; j < 8; j++) { + uip_buf[2 + j * 2] = hexchar[uip_lladdr.addr[j] >> 4]; + uip_buf[3 + j * 2] = hexchar[uip_lladdr.addr[j] & 15]; + } + uip_len = 18; + slip_send(); + } + uip_len = 0; + } + /* Save the last sender received over SLIP to avoid bouncing the + packet back if no route is found */ + uip_ipaddr_copy(&last_sender, &UIP_IP_BUF->srcipaddr); +} +/*---------------------------------------------------------------------------*/ +static void +init(void) +{ + slip_arch_init(BAUD2UBR(115200)); + process_start(&slip_process, NULL); + slip_set_input_callback(slip_input_callback); +} +/*---------------------------------------------------------------------------*/ +static void +output(void) +{ + if(uip_ipaddr_cmp(&last_sender, &UIP_IP_BUF->srcipaddr)) { + /* Do not bounce packets back over SLIP if the packet was received + over SLIP */ + PRINTF("slip-bridge: Destination off-link but no route src="); + PRINT6ADDR(&UIP_IP_BUF->srcipaddr); + PRINTF(" dst="); + PRINT6ADDR(&UIP_IP_BUF->destipaddr); + PRINTF("\n"); + } else { + PRINTF("SUT: %u\n", uip_len); + slip_send(); + printf("\n"); + } +} +/*---------------------------------------------------------------------------*/ +#if !SLIP_BRIDGE_CONF_NO_PUTCHAR +#undef putchar +int +putchar(int c) +{ +#define SLIP_END 0300 + static char debug_frame = 0; + + if(!debug_frame) { /* Start of debug output */ + slip_arch_writeb(SLIP_END); + slip_arch_writeb('\r'); /* Type debug line == '\r' */ + debug_frame = 1; + } + + /* Need to also print '\n' because for example COOJA will not show + any output before line end */ + slip_arch_writeb((char)c); + + /* + * Line buffered output, a newline marks the end of debug output and + * implicitly flushes debug output. + */ + if(c == '\n') { + slip_arch_writeb(SLIP_END); + debug_frame = 0; + } + return c; +} +#endif +/*---------------------------------------------------------------------------*/ +const struct uip_fallback_interface rpl_interface = { + init, output +}; +/*---------------------------------------------------------------------------*/ diff --git a/examples/jn516x/rpl/coap-dongle-node/Makefile b/examples/jn516x/rpl/coap-dongle-node/Makefile new file mode 100644 index 000000000..1a4afa652 --- /dev/null +++ b/examples/jn516x/rpl/coap-dongle-node/Makefile @@ -0,0 +1,21 @@ +CONTIKI_PROJECT = dongle-node +all: $(CONTIKI_PROJECT) + +TARGET ?= jn516x +JN516x_WITH_DONGLE = 1 + +CONTIKI=../../../.. + +CONTIKI_WITH_IPV6 = 1 + +PROJECTDIRS += .. ../tools +PROJECT_SOURCEFILES += rpl-tools.c +CFLAGS += -DPROJECT_CONF_H=\"project-conf.h\" + +CFLAGS += -DWITH_COAP +CFLAGS += -DUIP_CONF_TCP=0 +APPS = json +APPS += er-coap +APPS += rest-engine + +include $(CONTIKI)/Makefile.include diff --git a/examples/jn516x/rpl/coap-dongle-node/README.md b/examples/jn516x/rpl/coap-dongle-node/README.md new file mode 100644 index 000000000..2a4ed6183 --- /dev/null +++ b/examples/jn516x/rpl/coap-dongle-node/README.md @@ -0,0 +1,16 @@ +dongle-node is an example of a RICH node containing a JN516x microcontroller on a USB dongle. +The dongle is part of the NXP JN516x Evaluation Kit (see http://www.nxp.com/documents/leaflet/75017368.pdf) +The dongle-node connects to the network in the same way as described in `examples\jn5168/rpl/README.md` + +The dongle contains 2 LEDs that are available as a CoAP resource. They can be accessed via a CoAP client at the IPv6 interface +of the border router (e.g. via Copper plug-in on Firefox). +The following list gives an overview of the resources: + +URI Description +--- ----------- +Dongle\LED-toggle When doing a PUT/POST method on this resource (no payload needed), the LEDs will run through + the following states with wrap-around: + - GREEN LED on + - RED LED on + - All LEDs off + - RED and GREEN LED alternatively on with 1 sec period time diff --git a/examples/jn516x/rpl/coap-dongle-node/dongle-node.c b/examples/jn516x/rpl/coap-dongle-node/dongle-node.c new file mode 100644 index 000000000..c49bc9e7c --- /dev/null +++ b/examples/jn516x/rpl/coap-dongle-node/dongle-node.c @@ -0,0 +1,145 @@ +/* + * Copyright (c) 2015 NXP B.V. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of NXP B.V. nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY NXP B.V. AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL NXP B.V. OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * This file is part of the Contiki operating system. + * + * Author: Theo van Daele + * + */ +#include "contiki.h" +#include "net/ip/uip.h" +#include "tools/rpl-tools.h" +#include "rest-engine.h" +#include "sys/ctimer.h" +#include +#include "dev/leds.h" + +static void ct_callback(void *ptr); +static void put_post_led_toggle_handler(void *request, void *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset); + +static char content[REST_MAX_CHUNK_SIZE]; +static int content_len = 0; +static struct ctimer ct; + +#define CONTENT_PRINTF(...) { if(content_len < sizeof(content)) { content_len += snprintf(content + content_len, sizeof(content) - content_len, __VA_ARGS__); } } + +/* On dongle, LEDs are connected anti-parallel to DIO pins. */ + +#define TOGGLE_TIME CLOCK_SECOND +/*---------------------------------------------------------------------------*/ +PROCESS(start_app, "START_APP"); +AUTOSTART_PROCESSES(&start_app); +/*---------------------------------------------------------------------------*/ + +/* Call back for led toggle timer to toggle leds */ +static void +ct_callback(void *ptr) +{ + static uint8 toggle_status = 0; + if(toggle_status) { + leds_set(LEDS_RED); + } else { + leds_set(LEDS_GREEN); + } ctimer_restart(&ct); + toggle_status ^= 0x01; +} +/*********** CoAP sensor/ resource ************************************************/ +RESOURCE(resource_led_toggle, + "title=\"Led_toggle\"", + NULL, + put_post_led_toggle_handler, + put_post_led_toggle_handler, + NULL); +static void +put_post_led_toggle_handler(void *request, void *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset) +{ + static int led_state = 0; + const uint8_t *request_content; + int request_content_len; + unsigned int accept = -1; + + /* Given the way the LEDs are connected to the DIO ports, the LEDs are controlled via direct DIO access. */ + content_len = 0; + switch(led_state) { + case (0): + ctimer_stop(&ct); + leds_set(LEDS_GREEN); /* Only LEDS_GREEN on */ + CONTENT_PRINTF("Message from resource: Green LED on"); + led_state = 1; + break; + case (1): + leds_set(LEDS_RED); /* Only LEDS_RED on */ + CONTENT_PRINTF("Message from resource: Red LED on"); + led_state = 2; + break; + case (2): + leds_set(0); /* All LEDS off */ + CONTENT_PRINTF("Message from resource: All LEDs off"); + led_state = 3; + break; + case 3: + /* Both leds toggle */ + CONTENT_PRINTF("Message from resource: LEDs toggle"); + ctimer_restart(&ct); + led_state = 0; + default: + break; + } + /* Return message */ + REST.get_header_accept(request, &accept); + if(accept == -1 || accept == REST.type.TEXT_PLAIN) { + REST.set_header_content_type(response, REST.type.TEXT_PLAIN); + REST.set_response_payload(response, (uint8_t *)content, content_len); + } +} +/*---------------------------------------------------------------------------*/ +PROCESS_THREAD(start_app, ev, data) +{ + PROCESS_BEGIN(); + static int is_coordinator = 0; + + /* Switch off dongle leds */ + + /* Initialise ct timer, but don't let it run yet */ + ctimer_set(&ct, TOGGLE_TIME, ct_callback, NULL); + ctimer_stop(&ct); + + /* Start net stack */ + if(is_coordinator) { + uip_ipaddr_t prefix; + uip_ip6addr(&prefix, 0xaaaa, 0, 0, 0, 0, 0, 0, 0); + rpl_tools_init(&prefix); + } else { + rpl_tools_init(NULL); + } printf("Starting RPL node\n"); + + rest_init_engine(); + rest_activate_resource(&resource_led_toggle, "Dongle/LED-toggle"); + + PROCESS_END(); +} diff --git a/examples/jn516x/rpl/coap-dongle-node/project-conf.h b/examples/jn516x/rpl/coap-dongle-node/project-conf.h new file mode 100644 index 000000000..4c2ecd648 --- /dev/null +++ b/examples/jn516x/rpl/coap-dongle-node/project-conf.h @@ -0,0 +1,39 @@ +/* + * Copyright (c) 2015, SICS Swedish ICT. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the Institute nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + */ +/** + * \author Simon Duquennoy + */ + +#ifndef __PROJECT_CONF_H__ +#define __PROJECT_CONF_H__ + +#include "../common-conf.h" + +#endif /* __PROJECT_CONF_H__ */ diff --git a/examples/jn516x/rpl/coap-dr1175-node/Makefile b/examples/jn516x/rpl/coap-dr1175-node/Makefile new file mode 100644 index 000000000..f7960dcd1 --- /dev/null +++ b/examples/jn516x/rpl/coap-dr1175-node/Makefile @@ -0,0 +1,21 @@ +CONTIKI_PROJECT = dr1175-node +all: $(CONTIKI_PROJECT) + +TARGET ?= jn516x +JN516x_WITH_DR1175 = 1 + +CONTIKI=../../../.. + +CONTIKI_WITH_IPV6 = 1 + +PROJECTDIRS += .. ../tools +PROJECT_SOURCEFILES += rpl-tools.c +CFLAGS += -DPROJECT_CONF_H=\"project-conf.h\" + +CFLAGS += -DWITH_COAP +CFLAGS += -DUIP_CONF_TCP=0 +APPS = json +APPS += er-coap +APPS += rest-engine + +include $(CONTIKI)/Makefile.include diff --git a/examples/jn516x/rpl/coap-dr1175-node/README.md b/examples/jn516x/rpl/coap-dr1175-node/README.md new file mode 100644 index 000000000..6be19ab6d --- /dev/null +++ b/examples/jn516x/rpl/coap-dr1175-node/README.md @@ -0,0 +1,24 @@ +dr1175-node is an example of a RICH node containing a JN516x microcontroller on a DR1174 baseboard. +A DR1175 shield is mounted on the baseboard. +The boards are part of the NXP JN516x Evaluation Kit (see http://www.nxp.com/documents/leaflet/75017368.pdf) +The dr1175-node connects to the network in the same way as described in `examples\jn5168/rpl/README.md` + +The resources on the DR1175 are available as CoAP resources. They can be accessed via a CoAP client at the IPv6 interface +of the border router (e.g. via Copper plug-in on Firefox). +The following list gives an overview of the resources: + +URI Description +--- ----------- +DR1175\AllSensors This is an observable resource that shows the status of the humidity, light and temperature sensor. + The resource is automatically updated when a change in the value of the sensor data occurs. +DR1175\ColorLED\RGBValue With this resource, the level and color of the RGB LED can be set. + The output is set as 3 numbers (R, G and B) from 0..255, separated with a space +DR1175\Humidity\Unit This resource will return the unit of the humidity sensor +DR1175\Humidity\Value This resource will return the value of the humidity sensor +DR1175\LightSensor\Unit This resource will return the unit of the light sensor +DR1175\LightSensor\Value This resource will return the value of the light sensor +DR1175\Temperature\Unit This resource will return the unit of the temperature sensor +DR1175\Temperature\Value This resource will return the value of the temperature sensor +DR1175\WhiteLED This resource will set the level of 3 white power LEDs. Level is from 0..255 +DR1174\D3On1174 This resource control LED D3 on the base board +DR1174\D6On1174 This resource control LED D6 on the base board \ No newline at end of file diff --git a/examples/jn516x/rpl/coap-dr1175-node/dr1175-node.c b/examples/jn516x/rpl/coap-dr1175-node/dr1175-node.c new file mode 100644 index 000000000..f6eba5f32 --- /dev/null +++ b/examples/jn516x/rpl/coap-dr1175-node/dr1175-node.c @@ -0,0 +1,395 @@ +/* + * Copyright (c) 2015 NXP B.V. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of NXP B.V. nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY NXP B.V. AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL NXP B.V. OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * This file is part of the Contiki operating system. + * + * Author: Theo van Daele + * + */ + +#include "contiki.h" +#include "net/ip/uip.h" +#include "tools/rpl-tools.h" +#include "rest-engine.h" +#include "light-sensor.h" +#include "ht-sensor.h" +#include "dev/leds.h" +#include "sys/etimer.h" +#include + +static void event_sensors_dr1175_handler(void); +static void get_sensors_dr1175_handler(void *request, void *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset); +static void get_light_sensor_value_handler(void *request, void *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset); +static void get_light_sensor_unit_handler(void *request, void *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset); +static void get_temperature_value_handler(void *request, void *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset); +static void get_temperature_unit_handler(void *request, void *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset); +static void get_humidity_value_handler(void *request, void *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset); +static void get_humidity_unit_handler(void *request, void *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset); +static void put_post_white_led_handler(void *request, void *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset); +static void put_post_rgb_led_handler(void *request, void *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset); +static void put_post_led_d3_1174_handler(void *request, void *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset); +static void put_post_led_d6_1174_handler(void *request, void *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset); + +static char content[REST_MAX_CHUNK_SIZE]; +static int content_len = 0; + +#define CONTENT_PRINTF(...) { if(content_len < sizeof(content)) { content_len += snprintf(content + content_len, sizeof(content) - content_len, __VA_ARGS__); } } + +#define CLIP(value, level) if(value > level) { \ + value = level; \ +} +#define SET_LED(LED) if(atoi((const char *)request_content) != 0) { \ + leds_on(LED); \ + } else { \ + leds_off(LED); \ + } +/*---------------------------------------------------------------------------*/ +PROCESS(start_app, "START_APP"); +AUTOSTART_PROCESSES(&start_app, &sensors_process); + +/*---------------------------------------------------------------------------*/ + +/*********** CoAP sensor/ resource *************************************************/ + +/*******************************************************************/ +/* Observable resource and event handler to obtain all sensor data */ +/*******************************************************************/ +EVENT_RESOURCE(resource_sensors_dr1175, /* name */ + "obs;title=\"All_DR1175_sensors\"", /* attributes */ + get_sensors_dr1175_handler, /* GET handler */ + NULL, /* POST handler */ + NULL, /* PUT handler */ + NULL, /* DELETE handler */ + event_sensors_dr1175_handler); /* event handler */ +static void +get_sensors_dr1175_handler(void *request, void *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset) +{ + unsigned int accept = -1; + REST.get_header_accept(request, &accept); + if(accept == -1 || accept == REST.type.APPLICATION_JSON) { + content_len = 0; + CONTENT_PRINTF("{\"DR1175\":["); + CONTENT_PRINTF("{\"Humidity\":\"%d\"},", ht_sensor.value(HT_SENSOR_HUM)); + CONTENT_PRINTF("{\"Light\":\"%d\"},", light_sensor.value(0)); + CONTENT_PRINTF("{\"Temp\":\"%d\"}", ht_sensor.value(HT_SENSOR_TEMP)); + CONTENT_PRINTF("]}"); + REST.set_header_content_type(response, REST.type.APPLICATION_JSON); + REST.set_response_payload(response, (uint8_t *)content, content_len); + } +} +static void +event_sensors_dr1175_handler() +{ + /* Registered observers are notified and will trigger the GET handler to create the response. */ + REST.notify_subscribers(&resource_sensors_dr1175); +} +/*****************************************************/ +/* Resource and handler to obtain light sensor value */ +/*****************************************************/ +RESOURCE(resource_light_sensor_value, + "title=\"light sensor value\"", + get_light_sensor_value_handler, + NULL, + NULL, + NULL); +static void +get_light_sensor_value_handler(void *request, void *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset) +{ + unsigned int accept = -1; + REST.get_header_accept(request, &accept); + if(accept == -1 || accept == REST.type.TEXT_PLAIN) { + content_len = 0; + CONTENT_PRINTF("%d", light_sensor.value(0)); + REST.set_header_content_type(response, REST.type.TEXT_PLAIN); + REST.set_response_payload(response, (uint8_t *)content, content_len); + } +} +/***************************************************/ +/* Resource and handler to obtain light unit value */ +/***************************************************/ +RESOURCE(resource_light_sensor_unit, + "title=\"light sensor unit\"", + get_light_sensor_unit_handler, + NULL, + NULL, + NULL); +static void +get_light_sensor_unit_handler(void *request, void *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset) +{ + unsigned int accept = -1; + REST.get_header_accept(request, &accept); + if(accept == -1 || accept == REST.type.TEXT_PLAIN) { + content_len = 0; + CONTENT_PRINTF("Lux"); + REST.set_header_content_type(response, REST.type.TEXT_PLAIN); + REST.set_response_payload(response, (uint8_t *)content, content_len); + } +} +/***********************************************************/ +/* Resource and handler to obtain temperature sensor value */ +/***********************************************************/ +RESOURCE(resource_temperature_value, + "title=\"temperature value\"", + get_temperature_value_handler, + NULL, + NULL, + NULL); +static void +get_temperature_value_handler(void *request, void *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset) +{ + unsigned int accept = -1; + REST.get_header_accept(request, &accept); + if(accept == -1 || accept == REST.type.TEXT_PLAIN) { + content_len = 0; + CONTENT_PRINTF("%d", ht_sensor.value(HT_SENSOR_TEMP)); + REST.set_header_content_type(response, REST.type.TEXT_PLAIN); + REST.set_response_payload(response, (uint8_t *)content, content_len); + } +} +/*********************************************************/ +/* Resource and handler to obtain temperature unit value */ +/*********************************************************/ +RESOURCE(resource_temperature_unit, + "title=\"temperature unit\"", + get_temperature_unit_handler, + NULL, + NULL, + NULL); +static void +get_temperature_unit_handler(void *request, void *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset) +{ + unsigned int accept = -1; + REST.get_header_accept(request, &accept); + if(accept == -1 || accept == REST.type.TEXT_PLAIN) { + content_len = 0; + CONTENT_PRINTF("degrees C"); + REST.set_header_content_type(response, REST.type.TEXT_PLAIN); + REST.set_response_payload(response, (uint8_t *)content, content_len); + } +} +/********************************************************/ +/* Resource and handler to obtain humidity sensor value */ +/********************************************************/ +RESOURCE(resource_humidity_value, + "title=\"humidity value\"", + get_humidity_value_handler, + NULL, + NULL, + NULL); +static void +get_humidity_value_handler(void *request, void *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset) +{ + unsigned int accept = -1; + REST.get_header_accept(request, &accept); + if(accept == -1 || accept == REST.type.TEXT_PLAIN) { + content_len = 0; + CONTENT_PRINTF("%d", ht_sensor.value(HT_SENSOR_HUM)); + REST.set_header_content_type(response, REST.type.TEXT_PLAIN); + REST.set_response_payload(response, (uint8_t *)content, content_len); + } +} +/******************************************************/ +/* Resource and handler to obtain humidity unit value */ +/******************************************************/ +RESOURCE(resource_humidity_unit, + "title=\"humidity unit\"", + get_humidity_unit_handler, + NULL, + NULL, + NULL); +static void +get_humidity_unit_handler(void *request, void *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset) +{ + unsigned int accept = -1; + REST.get_header_accept(request, &accept); + if(accept == -1 || accept == REST.type.TEXT_PLAIN) { + content_len = 0; + CONTENT_PRINTF("relative %%"); + REST.set_header_content_type(response, REST.type.TEXT_PLAIN); + REST.set_response_payload(response, (uint8_t *)content, content_len); + } +} +/***************************************************/ +/* Resource and handler to control White LED level */ +/***************************************************/ +RESOURCE(resource_white_led, + "title=\"WhiteLED <[0..255]>\"", + NULL, + put_post_white_led_handler, + put_post_white_led_handler, + NULL); +static void +put_post_white_led_handler(void *request, void *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset) +{ + const uint8_t *request_content = NULL; + int request_content_len; + int level; + + unsigned int accept = -1; + REST.get_header_accept(request, &accept); + if(accept == -1 || accept == REST.type.TEXT_PLAIN) { + request_content_len = REST.get_request_payload(request, &request_content); + level = atoi((const char *)request_content); + CLIP(level, 255) + leds_set_level(level, LEDS_WHITE); + } +} +/*************************************************/ +/* Resource and handler to control RGB LED level */ +/*************************************************/ +RESOURCE(resource_rgb_led, + "title=\"RGB LED <[0..255] [0..255] [0..255]>\"", + NULL, + put_post_rgb_led_handler, + put_post_rgb_led_handler, + NULL); +static void +put_post_rgb_led_handler(void *request, void *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset) +{ + const uint8_t *request_content = NULL; + int request_content_len; + char *pch; + int RGB[] = { 0, 0, 0 }; + int index = 0; + + unsigned int accept = -1; + REST.get_header_accept(request, &accept); + if(accept == -1 || accept == REST.type.TEXT_PLAIN) { + request_content_len = REST.get_request_payload(request, &request_content); + pch = strtok((char *)request_content, " "); + while((pch != NULL) && (index != sizeof(RGB) / sizeof(int))) { + /* Convert token to int */ + RGB[index] = atoi(pch); + CLIP(RGB[index], 255) + index++; + /* Get next token */ + pch = strtok(NULL, " "); + } + leds_set_level(RGB[0], LEDS_RED); + leds_set_level(RGB[1], LEDS_GREEN); + leds_set_level(RGB[2], LEDS_BLUE); + } +} +/************************************************/ +/* Resource and handler to control D3 on DR1174 */ +/************************************************/ +RESOURCE(resource_led_d3_1174, + "title=\"LED D3 1174<[0,1]>\"", + NULL, + put_post_led_d3_1174_handler, + put_post_led_d3_1174_handler, + NULL); +static void +put_post_led_d3_1174_handler(void *request, void *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset) +{ + const uint8_t *request_content; + int request_content_len; + unsigned int accept = -1; + REST.get_header_accept(request, &accept); + if(accept == -1 || accept == REST.type.TEXT_PLAIN) { + request_content_len = REST.get_request_payload(request, &request_content); + SET_LED(LEDS_GP0); + } +} +/************************************************/ +/* Resource and handler to control D6 on DR1174 */ +/************************************************/ +RESOURCE(resource_led_d6_1174, + "title=\"LED D6 1174<[0,1]>\"", + NULL, + put_post_led_d6_1174_handler, + put_post_led_d6_1174_handler, + NULL); +static void +put_post_led_d6_1174_handler(void *request, void *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset) +{ + const uint8_t *request_content; + int request_content_len; + unsigned int accept = -1; + REST.get_header_accept(request, &accept); + if(accept == -1 || accept == REST.type.TEXT_PLAIN) { + request_content_len = REST.get_request_payload(request, &request_content); + SET_LED(LEDS_GP1); + } +} +/*---------------------------------------------------------------------------*/ +PROCESS_THREAD(start_app, ev, data) +{ + PROCESS_BEGIN(); + + static int is_coordinator = 0; + static struct etimer et; + + /* Make sensor active for measuring */ + SENSORS_ACTIVATE(light_sensor); + SENSORS_ACTIVATE(ht_sensor); + + /* Start net stack */ + if(is_coordinator) { + uip_ipaddr_t prefix; + uip_ip6addr(&prefix, 0xaaaa, 0, 0, 0, 0, 0, 0, 0); + rpl_tools_init(&prefix); + } else { + rpl_tools_init(NULL); + } printf("Starting RPL node\n"); + + rest_init_engine(); + rest_activate_resource(&resource_light_sensor_value, "DR1175/LightSensor/Value"); + rest_activate_resource(&resource_light_sensor_unit, "DR1175/LightSensor/Unit"); + rest_activate_resource(&resource_temperature_unit, "DR1175/Temperature/Unit"); + rest_activate_resource(&resource_temperature_value, "DR1175/Temperature/Value"); + rest_activate_resource(&resource_humidity_unit, "DR1175/Humidity/Unit"); + rest_activate_resource(&resource_humidity_value, "DR1175/Humidity/Value"); + rest_activate_resource(&resource_white_led, "DR1175/WhiteLED"); + rest_activate_resource(&resource_rgb_led, "DR1175/ColorLED/RGBValue"); + rest_activate_resource(&resource_led_d3_1174, "DR1175/LED/D3On1174"); + rest_activate_resource(&resource_led_d6_1174, "DR1175/LED/D6On1174"); + rest_activate_resource(&resource_sensors_dr1175, "DR1175/AllSensors"); + + /* Level of LEDS=0, so no light after start-up */ + leds_on(LEDS_WHITE | LEDS_RED | LEDS_GREEN | LEDS_BLUE); + + /* contiki-jn516x-main switches all leds off after process start-up. + Switch on required leds after rescheduling, otherwise level change needs to be + accompanied with leds_on() at least once in resource handler. */ + etimer_set(&et, CLOCK_SECOND / 10); + PROCESS_WAIT_EVENT_UNTIL(etimer_expired(&et)); + /* Level of LEDS=0, so no light after start-up. However, they are enabled + A level change will directly be visible. */ + leds_on(LEDS_WHITE | LEDS_RED | LEDS_GREEN | LEDS_BLUE); + + /* If sensor process generates an event, call event_handler of resource. + This will make this resource observable by the client */ + while(1) { + PROCESS_WAIT_EVENT_UNTIL((ev == sensors_event) && + ((data == &light_sensor) || (data == &ht_sensor))); + event_sensors_dr1175_handler(); + } + + PROCESS_END(); +} diff --git a/examples/jn516x/rpl/coap-dr1175-node/project-conf.h b/examples/jn516x/rpl/coap-dr1175-node/project-conf.h new file mode 100644 index 000000000..4c2ecd648 --- /dev/null +++ b/examples/jn516x/rpl/coap-dr1175-node/project-conf.h @@ -0,0 +1,39 @@ +/* + * Copyright (c) 2015, SICS Swedish ICT. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the Institute nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + */ +/** + * \author Simon Duquennoy + */ + +#ifndef __PROJECT_CONF_H__ +#define __PROJECT_CONF_H__ + +#include "../common-conf.h" + +#endif /* __PROJECT_CONF_H__ */ diff --git a/examples/jn516x/rpl/coap-dr1199-node/Makefile b/examples/jn516x/rpl/coap-dr1199-node/Makefile new file mode 100644 index 000000000..5a649e429 --- /dev/null +++ b/examples/jn516x/rpl/coap-dr1199-node/Makefile @@ -0,0 +1,21 @@ +CONTIKI_PROJECT = dr1199-node +all: $(CONTIKI_PROJECT) + +TARGET ?= jn516x +JN516x_WITH_DR1199 = 1 + +CONTIKI=../../../.. + +CONTIKI_WITH_IPV6 = 1 + +PROJECTDIRS += .. ../tools +PROJECT_SOURCEFILES += rpl-tools.c +CFLAGS += -DPROJECT_CONF_H=\"project-conf.h\" + +CFLAGS += -DWITH_COAP +CFLAGS += -DUIP_CONF_TCP=0 +APPS = json +APPS += er-coap +APPS += rest-engine + +include $(CONTIKI)/Makefile.include diff --git a/examples/jn516x/rpl/coap-dr1199-node/README.md b/examples/jn516x/rpl/coap-dr1199-node/README.md new file mode 100644 index 000000000..e9a6ee66b --- /dev/null +++ b/examples/jn516x/rpl/coap-dr1199-node/README.md @@ -0,0 +1,33 @@ +dr1199-node is an example of a RICH node containing a JN516x microcontroller on a DR1174 baseboard. +A DR1199 shield is mounted on the baseboard. +The boards are part of the NXP JN516x Evaluation Kit (see http://www.nxp.com/documents/leaflet/75017368.pdf) +The dr1199-node connects to the network in the same way as described in `examples\jn5168/rpl/README.md` + +The resources on the DR1199 are available as CoAP resources. They can be accessed via a CoAP client at the IPv6 interface +of the border router (e.g. via Copper plug-in on Firefox). +The following list gives an overview of the resources: + +URI Description +--- ----------- +DR1199\AllSensors This is an observable resource that shows the status of all switches and the potentiometer on the board + The resource is automatically updated when a change of the status/value of the switches and potentiometer + takes place. +DR1199\LED\All When writing a '1', LEDs D1..D3 will switch ON + When writing a '0', LEDs D1..D3 will switch OFF +DR1199\LED\D1 When writing a '1', LED D1 will switch ON + When writing a '0', LED D1 will switch OFF +DR1199\LED\D2 When writing a '1', LED D2 will switch ON + When writing a '0', LED D2 will switch OFF +DR1199\LED\D3 When writing a '1', LED D3 will switch ON + When writing a '0', LED D3 will switch OFF +DR1199\D3On1174 This resource control LED D3 on the base board +DR1199\D6On1174 This resource control LED D6 on the base board +DR1199\Potentiometer The resource will show the value of the potentiometer +DR1199\Switch\DIO8 This resource shows the status of the DIO8 switch (on DR1174) +DR1199\Switch\SW1 This resource shows the status of the SW1 switch +DR1199\Switch\SW2 This resource shows the status of the SW2 switch +DR1199\Switch\SW3 This resource shows the status of the SW3 switch +DR1199\Switch\SW4 This resource shows the status of the SW4 switch + + + diff --git a/examples/jn516x/rpl/coap-dr1199-node/dr1199-node.c b/examples/jn516x/rpl/coap-dr1199-node/dr1199-node.c new file mode 100644 index 000000000..91921fed1 --- /dev/null +++ b/examples/jn516x/rpl/coap-dr1199-node/dr1199-node.c @@ -0,0 +1,389 @@ +/* + * Copyright (c) 2015 NXP B.V. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of NXP B.V. nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY NXP B.V. AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL NXP B.V. OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * This file is part of the Contiki operating system. + * + * Author: Theo van Daele + * + */ +#include "contiki.h" +#include "net/ip/uip.h" +#include "tools/rpl-tools.h" +#include "rest-engine.h" +#include "dev/leds.h" +#include "button-sensor.h" +#include "pot-sensor.h" +#include + +static char content[REST_MAX_CHUNK_SIZE]; +static int content_len = 0; + +static void event_sensors_dr1199_handler(); +static void get_sensors_dr1199_handler(void *request, void *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset); +static void get_switch_sw1_handler(void *request, void *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset); +static void get_switch_sw2_handler(void *request, void *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset); +static void get_switch_sw3_handler(void *request, void *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset); +static void get_switch_sw4_handler(void *request, void *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset); +static void get_switch_dio8_handler(void *request, void *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset); +static void get_pot_handler(void *request, void *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset); +static void put_post_led_d1_handler(void *request, void *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset); +static void put_post_led_d2_handler(void *request, void *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset); +static void put_post_led_d3_handler(void *request, void *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset); +static void put_post_led_d3_1174_handler(void *request, void *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset); +static void put_post_led_d6_1174_handler(void *request, void *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset); +static void put_post_led_all_handler(void *request, void *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset); + +#define CONTENT_PRINTF(...) { if(content_len < sizeof(content)) { content_len += snprintf(content + content_len, sizeof(content) - content_len, __VA_ARGS__); } } + +#define PARSE_SWITCH(POSITION) if(button_sensor.value(0) & (1 << POSITION)) { \ + CONTENT_PRINTF("PRESSED"); \ + } else { \ + CONTENT_PRINTF("RELEASED"); \ + } + +#define SET_LED(LED) if(atoi((const char *)request_content) != 0) { \ + leds_on(LED); \ + } else { \ + leds_off(LED); \ + } + +/*---------------------------------------------------------------------------*/ +PROCESS(start_app, "START_APP"); +AUTOSTART_PROCESSES(&sensors_process, &start_app); + +/*---------------------------------------------------------------------------*/ + +/*********** CoAP sensor/ resource *************************************************/ + +/*******************************************************************/ +/* Observable resource and event handler to obtain all sensor data */ +/*******************************************************************/ +EVENT_RESOURCE(resource_sensors_dr1199, /* name */ + "obs;title=\"All_DR1199_sensors\"", /* attributes */ + get_sensors_dr1199_handler, /* GET handler */ + NULL, /* POST handler */ + NULL, /* PUT handler */ + NULL, /* DELETE handler */ + event_sensors_dr1199_handler); /* event handler */ +static void +get_sensors_dr1199_handler(void *request, void *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset) +{ + unsigned int accept = -1; + REST.get_header_accept(request, &accept); + if(accept == -1 || accept == REST.type.APPLICATION_JSON) { + content_len = 0; + CONTENT_PRINTF("{\"DR1199\":["); + CONTENT_PRINTF("{\"Switch\":\"0x%X\"},", button_sensor.value(0)); + CONTENT_PRINTF("{\"Pot\":\"%d\"}", pot_sensor.value(0)); + CONTENT_PRINTF("]}"); + REST.set_header_content_type(response, REST.type.APPLICATION_JSON); + REST.set_response_payload(response, (uint8_t *)content, content_len); + } +} +static void +event_sensors_dr1199_handler() +{ + /* Registered observers are notified and will trigger the GET handler to create the response. */ + REST.notify_subscribers(&resource_sensors_dr1199); +} +/***********************************************/ +/* Resource and handler to obtain switch value */ +/***********************************************/ +RESOURCE(resource_switch_sw1, + "title=\"SW1\"", + get_switch_sw1_handler, + NULL, + NULL, + NULL); +static void +get_switch_sw1_handler(void *request, void *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset) +{ + content_len = 0; + unsigned int accept = -1; + REST.get_header_accept(request, &accept); + if(accept == -1 || accept == REST.type.TEXT_PLAIN) { + PARSE_SWITCH(1) + REST.set_header_content_type(response, REST.type.TEXT_PLAIN); + REST.set_response_payload(response, (uint8_t *)content, content_len); + } +} +RESOURCE(resource_switch_sw2, + "title=\"SW2\"", + get_switch_sw2_handler, + NULL, + NULL, + NULL); +static void +get_switch_sw2_handler(void *request, void *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset) +{ + content_len = 0; + unsigned int accept = -1; + REST.get_header_accept(request, &accept); + if(accept == -1 || accept == REST.type.TEXT_PLAIN) { + PARSE_SWITCH(2) + REST.set_header_content_type(response, REST.type.TEXT_PLAIN); + REST.set_response_payload(response, (uint8_t *)content, content_len); + } +} +RESOURCE(resource_switch_sw3, + "title=\"SW3\"", + get_switch_sw3_handler, + NULL, + NULL, + NULL); +static void +get_switch_sw3_handler(void *request, void *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset) +{ + content_len = 0; + unsigned int accept = -1; + REST.get_header_accept(request, &accept); + if(accept == -1 || accept == REST.type.TEXT_PLAIN) { + PARSE_SWITCH(3) + REST.set_header_content_type(response, REST.type.TEXT_PLAIN); + REST.set_response_payload(response, (uint8_t *)content, content_len); + } +} +RESOURCE(resource_switch_sw4, + "title=\"SW4\"", + get_switch_sw4_handler, + NULL, + NULL, + NULL); +static void +get_switch_sw4_handler(void *request, void *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset) +{ + content_len = 0; + unsigned int accept = -1; + REST.get_header_accept(request, &accept); + if(accept == -1 || accept == REST.type.TEXT_PLAIN) { + PARSE_SWITCH(4) + REST.set_header_content_type(response, REST.type.TEXT_PLAIN); + REST.set_response_payload(response, (uint8_t *)content, content_len); + } +} +RESOURCE(resource_switch_dio8, + "title=\"DIO8\"", + get_switch_dio8_handler, + NULL, + NULL, + NULL); +static void +get_switch_dio8_handler(void *request, void *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset) +{ + content_len = 0; + unsigned int accept = -1; + REST.get_header_accept(request, &accept); + if(accept == -1 || accept == REST.type.TEXT_PLAIN) { + PARSE_SWITCH(0) + REST.set_header_content_type(response, REST.type.TEXT_PLAIN); + REST.set_response_payload(response, (uint8_t *)content, content_len); + } +} +/*******************************************************/ +/* Resource and handler to obtain potentiometer value */ +/*******************************************************/ +RESOURCE(resource_pot, + "title=\"Potentiometer\"", + get_pot_handler, + NULL, + NULL, + NULL); +static void +get_pot_handler(void *request, void *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset) +{ + content_len = 0; + unsigned int accept = -1; + REST.get_header_accept(request, &accept); + if(accept == -1 || accept == REST.type.TEXT_PLAIN) { + CONTENT_PRINTF("%d", pot_sensor.value(0)); + REST.set_header_content_type(response, REST.type.TEXT_PLAIN); + REST.set_response_payload(response, (uint8_t *)content, content_len); + } +} +/************************************/ +/* Resource and handler to set leds */ +/************************************/ +RESOURCE(resource_led_d1, + "title=\"LED D1 <[0,1]>\"", + NULL, + put_post_led_d1_handler, + put_post_led_d1_handler, + NULL); +static void +put_post_led_d1_handler(void *request, void *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset) +{ + const uint8_t *request_content; + int request_content_len; + unsigned int accept = -1; + REST.get_header_accept(request, &accept); + if(accept == -1 || accept == REST.type.TEXT_PLAIN) { + request_content_len = REST.get_request_payload(request, &request_content); + SET_LED(LEDS_GREEN) + } +} +RESOURCE(resource_led_d2, + "title=\"LED D2 <[0,1]>\"", + NULL, + put_post_led_d2_handler, + put_post_led_d2_handler, + NULL); +static void +put_post_led_d2_handler(void *request, void *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset) +{ + const uint8_t *request_content; + int request_content_len; + unsigned int accept = -1; + REST.get_header_accept(request, &accept); + if(accept == -1 || accept == REST.type.TEXT_PLAIN) { + request_content_len = REST.get_request_payload(request, &request_content); + SET_LED(LEDS_BLUE) + } +} +RESOURCE(resource_led_d3, + "title=\"LED D3 <[0,1]>\"", + NULL, + put_post_led_d3_handler, + put_post_led_d3_handler, + NULL); +static void +put_post_led_d3_handler(void *request, void *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset) +{ + const uint8_t *request_content; + int request_content_len; + unsigned int accept = -1; + REST.get_header_accept(request, &accept); + if(accept == -1 || accept == REST.type.TEXT_PLAIN) { + request_content_len = REST.get_request_payload(request, &request_content); + SET_LED(LEDS_RED) + } +} +RESOURCE(resource_led_d3_1174, + "title=\"LED D3 1174<[0,1]>\"", + NULL, + put_post_led_d3_1174_handler, + put_post_led_d3_1174_handler, + NULL); +static void +put_post_led_d3_1174_handler(void *request, void *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset) +{ + const uint8_t *request_content; + int request_content_len; + unsigned int accept = -1; + REST.get_header_accept(request, &accept); + if(accept == -1 || accept == REST.type.TEXT_PLAIN) { + request_content_len = REST.get_request_payload(request, &request_content); + SET_LED(LEDS_GP0); + } +} +RESOURCE(resource_led_d6_1174, + "title=\"LED D6 1174<[0,1]>\"", + NULL, + put_post_led_d6_1174_handler, + put_post_led_d6_1174_handler, + NULL); +static void +put_post_led_d6_1174_handler(void *request, void *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset) +{ + const uint8_t *request_content; + int request_content_len; + unsigned int accept = -1; + REST.get_header_accept(request, &accept); + if(accept == -1 || accept == REST.type.TEXT_PLAIN) { + request_content_len = REST.get_request_payload(request, &request_content); + SET_LED(LEDS_GP1); + } +} +RESOURCE(resource_led_all, + "title=\"LED All <[0,1]>\"", + NULL, + put_post_led_all_handler, + put_post_led_all_handler, + NULL); +static void +put_post_led_all_handler(void *request, void *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset) +{ + const uint8_t *request_content; + int request_content_len; + unsigned int accept = -1; + REST.get_header_accept(request, &accept); + if(accept == -1 || accept == REST.type.TEXT_PLAIN) { + request_content_len = REST.get_request_payload(request, &request_content); + if(atoi((const char *)request_content) != 0) { + leds_on(LEDS_ALL); + } else { + leds_off(LEDS_ALL); + } + } +} +/*---------------------------------------------------------------------------*/ +PROCESS_THREAD(start_app, ev, data) +{ + PROCESS_BEGIN(); + + static int is_coordinator = 0; + + /* is_coordinator = node_id == 1; */ + + /* Make sensor active for measuring */ + SENSORS_ACTIVATE(button_sensor); + SENSORS_ACTIVATE(pot_sensor); + + /* Start net stack */ + if(is_coordinator) { + uip_ipaddr_t prefix; + uip_ip6addr(&prefix, 0xaaaa, 0, 0, 0, 0, 0, 0, 0); + rpl_tools_init(&prefix); + } else { + rpl_tools_init(NULL); + } printf("Starting RPL node\n"); + + rest_init_engine(); + rest_activate_resource(&resource_switch_sw1, "DR1199/Switch/SW1"); + rest_activate_resource(&resource_switch_sw2, "DR1199/Switch/SW2"); + rest_activate_resource(&resource_switch_sw3, "DR1199/Switch/SW3"); + rest_activate_resource(&resource_switch_sw4, "DR1199/Switch/SW4"); + rest_activate_resource(&resource_switch_dio8, "DR1199/Switch/DIO8"); + rest_activate_resource(&resource_pot, "DR1199/Potentiometer"); + rest_activate_resource(&resource_led_d1, "DR1199/LED/D1"); + rest_activate_resource(&resource_led_d2, "DR1199/LED/D2"); + rest_activate_resource(&resource_led_d3, "DR1199/LED/D3"); + rest_activate_resource(&resource_led_d3_1174, "DR1199/LED/D3On1174"); + rest_activate_resource(&resource_led_d6_1174, "DR1199/LED/D6On1174"); + rest_activate_resource(&resource_led_all, "DR1199/LED/All"); + rest_activate_resource(&resource_sensors_dr1199, "DR1199/AllSensors"); + /* If sensor process generates an event, call event_handler of resource. + This will make this resource observable by the client */ + while(1) { + PROCESS_WAIT_EVENT_UNTIL((ev == sensors_event) && + ((data == &button_sensor) || (data == &pot_sensor))); + event_sensors_dr1199_handler(); + } + + PROCESS_END(); +} + diff --git a/examples/jn516x/rpl/coap-dr1199-node/project-conf.h b/examples/jn516x/rpl/coap-dr1199-node/project-conf.h new file mode 100644 index 000000000..4c2ecd648 --- /dev/null +++ b/examples/jn516x/rpl/coap-dr1199-node/project-conf.h @@ -0,0 +1,39 @@ +/* + * Copyright (c) 2015, SICS Swedish ICT. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the Institute nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + */ +/** + * \author Simon Duquennoy + */ + +#ifndef __PROJECT_CONF_H__ +#define __PROJECT_CONF_H__ + +#include "../common-conf.h" + +#endif /* __PROJECT_CONF_H__ */ diff --git a/examples/jn516x/rpl/common-conf.h b/examples/jn516x/rpl/common-conf.h new file mode 100644 index 000000000..5c936ff7f --- /dev/null +++ b/examples/jn516x/rpl/common-conf.h @@ -0,0 +1,85 @@ +/* + * Copyright (c) 2015, SICS Swedish ICT. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the Institute nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + */ +/** + * \author Simon Duquennoy + */ + +#ifndef __COMMON_CONF_H__ +#define __COMMON_CONF_H__ + +#define MAC_CONFIG_NULLRDC 0 +#define MAC_CONFIG_CONTIKIMAC 1 +/* Select a MAC configuration */ +#define MAC_CONFIG MAC_CONFIG_NULLRDC + +#undef NETSTACK_CONF_MAC +#undef NETSTACK_CONF_RDC +#undef NETSTACK_CONF_FRAMER + +#if MAC_CONFIG == MAC_CONFIG_NULLRDC + +#define NETSTACK_CONF_MAC csma_driver +#define NETSTACK_CONF_RDC nullrdc_driver +#define NETSTACK_CONF_FRAMER framer_802154 + +#elif MAC_CONFIG == MAC_CONFIG_CONTIKIMAC + +#define NETSTACK_CONF_MAC csma_driver +#define NETSTACK_CONF_RDC contikimac_driver +#define NETSTACK_CONF_FRAMER contikimac_framer +#undef MICROMAC_CONF_AUTOACK +#define MICROMAC_CONF_AUTOACK 1 + +#else + +#error Unsupported MAC configuration + +#endif /* MAC_CONFIG */ + +/* IEEE802.15.4 PANID and channel */ + +#undef IEEE802154_CONF_PANID +#define IEEE802154_CONF_PANID 0xabcd + +#undef RF_CHANNEL +#define RF_CHANNEL 26 + +/* UART Configuration */ + +#undef UART_HW_FLOW_CTRL +#define UART_HW_FLOW_CTRL 0 + +#undef UART_XONXOFF_FLOW_CTRL +#define UART_XONXOFF_FLOW_CTRL 1 + +#undef UART_BAUD_RATE +#define UART_BAUD_RATE UART_RATE_1000000 + +#endif /* __COMMON_CONF_H__ */ diff --git a/examples/jn516x/rpl/node/Makefile b/examples/jn516x/rpl/node/Makefile new file mode 100644 index 000000000..8096152ee --- /dev/null +++ b/examples/jn516x/rpl/node/Makefile @@ -0,0 +1,14 @@ +CONTIKI_PROJECT = node +all: $(CONTIKI_PROJECT) + +TARGET ?= jn516x + +CONTIKI=../../../.. + +CONTIKI_WITH_IPV6 = 1 + +PROJECTDIRS += .. ../tools +PROJECT_SOURCEFILES += rpl-tools.c +CFLAGS += -DPROJECT_CONF_H=\"project-conf.h\" + +include $(CONTIKI)/Makefile.include diff --git a/examples/jn516x/rpl/node/README.md b/examples/jn516x/rpl/node/README.md new file mode 100644 index 000000000..e9bded1d6 --- /dev/null +++ b/examples/jn516x/rpl/node/README.md @@ -0,0 +1,18 @@ +A RPL node. Will act as basic node by default, but can be configured at startup +using the user button and following instructions from the log output. Every press +of a button toggles the mode as 6ln and 6dr. After 10s with no button press, +the node starts in the last setting. The modes are: +* 6ln (default): 6lowpan node, will join a RPL network and act as router. +* 6dr: 6lowpan DAG Root, will start its own RPL network. Note this is not a +border router, i.e. it does not have a serial interface with connection to +the Internet. For a border router, see ../border-router. + +To indicate the hardware target for the node, add one of the following +options in the command line: +If rpl-border-router runs on dongle: +JN516x_WITH_DONGLE=1 +If rpl-border-router runs on DR1174: +JN516x_WITH_DR1174=1 +If building for a new platform, first execute : make clean + +For more information, see ../README.md. diff --git a/examples/jn516x/rpl/node/node.c b/examples/jn516x/rpl/node/node.c new file mode 100644 index 000000000..e4fccec7d --- /dev/null +++ b/examples/jn516x/rpl/node/node.c @@ -0,0 +1,108 @@ +/* + * Copyright (c) 2015, SICS Swedish ICT. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the Institute nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + */ +/** + * \file + * A RPL node able to act as either DAG Root (6dr) or simple node (6ln). + * Press use button at startup to configure. + * + * \author Simon Duquennoy + */ + +#include "contiki.h" +#include "net/rpl/rpl.h" +#include "tools/rpl-tools.h" + +#define DEBUG DEBUG_PRINT +#include "net/ip/uip-debug.h" + +#define CONFIG_VIA_BUTTON PLATFORM_HAS_BUTTON +#if CONFIG_VIA_BUTTON +#include "button-sensor.h" +#endif /* CONFIG_VIA_BUTTON */ + +/*---------------------------------------------------------------------------*/ +PROCESS(node_process, "RPL Node"); +#if CONFIG_VIA_BUTTON +AUTOSTART_PROCESSES(&node_process, &sensors_process); +#else /* CONFIG_VIA_BUTTON */ +AUTOSTART_PROCESSES(&node_process); +#endif /* CONFIG_VIA_BUTTON */ + +/*---------------------------------------------------------------------------*/ +PROCESS_THREAD(node_process, ev, data) +{ + PROCESS_BEGIN(); + + /* 3 possible roles: + * - role_6ln: simple node, will join any network, secured or not + * - role_6dg: DAG root, will advertise (unsecured) beacons + * */ + static int is_coordinator = 0; + static enum { role_6ln, role_6dr } node_role; + node_role = role_6ln; + +#if CONFIG_VIA_BUTTON + { +#define CONFIG_WAIT_TIME 10 + static struct etimer et; + + SENSORS_ACTIVATE(button_sensor); + etimer_set(&et, CLOCK_SECOND * CONFIG_WAIT_TIME); + + while(!etimer_expired(&et)) { + printf("Init: current role: %s. Will start in %u seconds.\n", + node_role == role_6ln ? "6ln" : "6dr", + CONFIG_WAIT_TIME); + PROCESS_WAIT_EVENT_UNTIL(((ev == sensors_event) && + (data == &button_sensor) && button_sensor.value(0) > 0) + || etimer_expired(&et)); + if(ev == sensors_event && data == &button_sensor && button_sensor.value(0) > 0) { + node_role = (node_role + 1) % 2; + etimer_restart(&et); + } + } + } + +#endif /* CONFIG_VIA_BUTTON */ + + printf("Init: node starting with role %s\n", + node_role == role_6ln ? "6ln" : "6dr"); + + is_coordinator = node_role > role_6ln; + + if(is_coordinator) { + uip_ipaddr_t prefix; + uip_ip6addr(&prefix, 0xaaaa, 0, 0, 0, 0, 0, 0, 0); + rpl_tools_init(&prefix); + } else { + rpl_tools_init(NULL); + } PROCESS_END(); +} +/*---------------------------------------------------------------------------*/ diff --git a/examples/jn516x/rpl/node/project-conf.h b/examples/jn516x/rpl/node/project-conf.h new file mode 100644 index 000000000..9db6f0229 --- /dev/null +++ b/examples/jn516x/rpl/node/project-conf.h @@ -0,0 +1,40 @@ +/* + * Copyright (c) 2015, SICS Swedish ICT. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the Institute nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + */ + +/** + * \author Simon Duquennoy + */ + +#ifndef __PROJECT_CONF_H__ +#define __PROJECT_CONF_H__ + +#include "../common-conf.h" + +#endif /* __PROJECT_CONF_H__ */ diff --git a/examples/jn516x/rpl/tools/rpl-tools.c b/examples/jn516x/rpl/tools/rpl-tools.c new file mode 100644 index 000000000..23a041306 --- /dev/null +++ b/examples/jn516x/rpl/tools/rpl-tools.c @@ -0,0 +1,83 @@ +/* + * Copyright (c) 2015, SICS Swedish ICT. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the Institute nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + */ +/** + * \file + * + * \author Simon Duquennoy + */ + +#include "contiki-conf.h" +#include "contiki-net.h" +#include "net/ip/uip.h" +#include "net/rpl/rpl.h" +#include +#include + +#define DEBUG DEBUG_PRINT +#include "net/ip/uip-debug.h" + +/*---------------------------------------------------------------------------*/ +static void +print_local_addresses(void) +{ + int i; + uint8_t state; + + PRINTA("Server IPv6 addresses:\n"); + for(i = 0; i < UIP_DS6_ADDR_NB; i++) { + state = uip_ds6_if.addr_list[i].state; + if(uip_ds6_if.addr_list[i].isused && + (state == ADDR_TENTATIVE || state == ADDR_PREFERRED)) { + PRINTA(" "); + uip_debug_ipaddr_print(&uip_ds6_if.addr_list[i].ipaddr); + PRINTA("\n"); + } + } +} +/*---------------------------------------------------------------------------*/ +void +rpl_tools_init(uip_ipaddr_t *br_prefix) +{ + uip_ipaddr_t global_ipaddr; + + if(br_prefix) { /* We are root */ + NETSTACK_RDC.off(1); + memcpy(&global_ipaddr, br_prefix, 16); + uip_ds6_set_addr_iid(&global_ipaddr, &uip_lladdr); + uip_ds6_addr_add(&global_ipaddr, 0, ADDR_AUTOCONF); + rpl_set_root(RPL_DEFAULT_INSTANCE, &global_ipaddr); + rpl_set_prefix(rpl_get_any_dag(), br_prefix, 64); + rpl_repair_root(RPL_DEFAULT_INSTANCE); + } + + NETSTACK_MAC.on(); + + print_local_addresses(); +} diff --git a/examples/jn516x/rpl/tools/rpl-tools.h b/examples/jn516x/rpl/tools/rpl-tools.h new file mode 100644 index 000000000..e91bc81c5 --- /dev/null +++ b/examples/jn516x/rpl/tools/rpl-tools.h @@ -0,0 +1,35 @@ +/* + * Copyright (c) 2015, SICS Swedish ICT. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the Institute nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + */ +/** + + * \author Simon Duquennoy + */ + +void rpl_tools_init(uip_ipaddr_t *br_prefix); From 4811bb8edbdfa57040e2d534eca7d0a796f8a282 Mon Sep 17 00:00:00 2001 From: Simon Duquennoy Date: Mon, 21 Sep 2015 11:01:41 +0200 Subject: [PATCH 095/120] Added *.jn516x to .gitignore --- .gitignore | 1 + 1 file changed, 1 insertion(+) diff --git a/.gitignore b/.gitignore index ca86d3acd..4a051ff57 100644 --- a/.gitignore +++ b/.gitignore @@ -25,6 +25,7 @@ *.c64 *.cc2538dk *.remote +*.jn516x *.srf06-cc26xx *.ev-aducrf101mkxz *.report From 36f6ce7b82ac7268fd24b236442b0fa8a885799e Mon Sep 17 00:00:00 2001 From: Simon Duquennoy Date: Mon, 21 Sep 2015 11:02:16 +0200 Subject: [PATCH 096/120] Added NXP JN516x regression testing --- .travis.yml | 17 +++++++++++++++++ regression-tests/22-compile-nxp-ports/Makefile | 16 ++++++++++++++++ 2 files changed, 33 insertions(+) create mode 100644 regression-tests/22-compile-nxp-ports/Makefile diff --git a/.travis.yml b/.travis.yml index 98f98edff..72757c1bb 100644 --- a/.travis.yml +++ b/.travis.yml @@ -73,6 +73,22 @@ before_script: cc65 --version ; fi + ## Install NXP toolchain + - if [ ${BUILD_ARCH:-0} = jn516x ] ; then + $WGET http://simonduq.github.io/resources/ba-elf-gcc-4.7.4-part1.tar.bz2 && + $WGET http://simonduq.github.io/resources/ba-elf-gcc-4.7.4-part2.tar.bz2 && + $WGET http://simonduq.github.io/resources/jn516x-sdk-4163.tar.bz2 && + mkdir /tmp/jn516x-sdk /tmp/ba-elf-gcc && + tar xjf jn516x-sdk-*.tar.bz2 -C /tmp/jn516x-sdk && + tar xjf ba-elf-gcc-*part1.tar.bz2 -C /tmp/ba-elf-gcc && + tar xjf ba-elf-gcc-*part2.tar.bz2 -C /tmp/ba-elf-gcc && + sudo cp -f -r /tmp/jn516x-sdk /usr/ && + sudo cp -f -r /tmp/ba-elf-gcc /usr/ && + export PATH=/usr/ba-elf-gcc/bin:$PATH && + rm -rf /tmp/ba-elf-gcc* /tmp/jn516x-sdk* && + ba-elf-gcc --version ; + fi + ## Compile cooja.jar only when it's going to be needed - if [ ${BUILD_CATEGORY:-sim} = sim ] ; then java -version && @@ -120,5 +136,6 @@ env: - BUILD_TYPE='compile-arm-apcs-ports' BUILD_CATEGORY='compile' BUILD_ARCH='arm-apcs' - BUILD_TYPE='compile-6502-ports' BUILD_CATEGORY='compile' BUILD_ARCH='6502' - BUILD_TYPE='compile-arm-ports' BUILD_CATEGORY='compile' BUILD_ARCH='arm-aapcs' + - BUILD_TYPE='compile-nxp-ports' BUILD_CATEGORY='compile' BUILD_ARCH='jn516x' - BUILD_TYPE='slip-radio' MAKE_TARGETS='cooja' - BUILD_TYPE='llsec' MAKE_TARGETS='cooja' diff --git a/regression-tests/22-compile-nxp-ports/Makefile b/regression-tests/22-compile-nxp-ports/Makefile new file mode 100644 index 000000000..7ff68eaef --- /dev/null +++ b/regression-tests/22-compile-nxp-ports/Makefile @@ -0,0 +1,16 @@ +EXAMPLESDIR=../../examples +TOOLSDIR=../../tools + +# build jn516x examples, covering IPv6, RPL, CoAP, Rime, Nullrdc, Contikimac +EXAMPLES = \ +jn516x/dr1175-sensors/jn516x \ +jn516x/rime/jn516x \ +jn516x/rpl/border-router/jn516x \ +jn516x/rpl/node/jn516x \ +jn516x/rpl/coap-dongle-node/jn516x \ +jn516x/rpl/coap-dr1175-node/jn516x \ +jn516x/rpl/coap-dr1199-node/jn516x + +TOOLS= + +include ../Makefile.compile-test From c6db6b171a9dca75abce5d1eac60f2e7e147b264 Mon Sep 17 00:00:00 2001 From: Ulf Knoblich Date: Tue, 16 Jun 2015 13:21:44 +0200 Subject: [PATCH 097/120] ip64: Streamlined configuration parameters --- core/net/ip64/ip64-conf-example.h | 11 ++++++++--- core/net/ip64/ip64.c | 6 +++--- core/net/ip64/ip64.h | 17 ++++++++++++++--- 3 files changed, 25 insertions(+), 9 deletions(-) diff --git a/core/net/ip64/ip64-conf-example.h b/core/net/ip64/ip64-conf-example.h index 66102d5c8..5c08e7438 100644 --- a/core/net/ip64/ip64-conf-example.h +++ b/core/net/ip64/ip64-conf-example.h @@ -35,9 +35,14 @@ #include "ip64-tap-driver.h" #include "ip64-eth-interface.h" -#define IP64_CONF_UIP_FALLBACK_INTERFACE ip64_eth_interface -#define IP64_CONF_INPUT ip64_eth_interface_input +#define IP64_CONF_UIP_FALLBACK_INTERFACE ip64_eth_interface +#define IP64_CONF_INPUT ip64_eth_interface_input -#define IP64_CONF_ETH_DRIVER ip64_tap_driver +#define IP64_CONF_ETH_DRIVER ip64_tap_driver +/* + * In contrast to the mandatory parameters above, IP64_CONF_DHCP is an + * optional configuration parameter. The default value is set in ip64.h + */ +/* #define IP64_CONF_DHCP 1 */ #endif /* IP64_CONF_H */ diff --git a/core/net/ip64/ip64.c b/core/net/ip64/ip64.c index e00e1e443..8483d9388 100644 --- a/core/net/ip64/ip64.c +++ b/core/net/ip64/ip64.c @@ -188,7 +188,7 @@ ip64_init(void) PRINTF("ip64_init\n"); IP64_ETH_DRIVER.init(); -#if IP64_CONF_DHCP +#if IP64_DHCP ip64_ipv4_dhcp_init(); #endif /* IP64_CONF_DHCP */ @@ -894,14 +894,14 @@ ip64_hostaddr_is_configured(void) static void interface_init(void) { - IP64_CONF_UIP_FALLBACK_INTERFACE.init(); + IP64_UIP_FALLBACK_INTERFACE.init(); } /*---------------------------------------------------------------------------*/ static void interface_output(void) { PRINTF("ip64: interface_output len %d\n", uip_len); - IP64_CONF_UIP_FALLBACK_INTERFACE.output(); + IP64_UIP_FALLBACK_INTERFACE.output(); } /*---------------------------------------------------------------------------*/ const struct uip_fallback_interface ip64_uip_fallback_interface = { diff --git a/core/net/ip64/ip64.h b/core/net/ip64/ip64.h index 50d37d691..0837dc988 100644 --- a/core/net/ip64/ip64.h +++ b/core/net/ip64/ip64.h @@ -36,12 +36,12 @@ void ip64_init(void); int ip64_6to4(const uint8_t *ipv6packet, const uint16_t ipv6len, - uint8_t *resultpacket); + uint8_t *resultpacket); int ip64_4to6(const uint8_t *ipv4packet, const uint16_t ipv4len, - uint8_t *resultpacket); + uint8_t *resultpacket); void ip64_set_ipv4_address(const uip_ip4addr_t *ipv4addr, - const uip_ip4addr_t *netmask); + const uip_ip4addr_t *netmask); void ip64_set_ipv6_address(const uip_ip6addr_t *ipv6addr); const uip_ip4addr_t *ip64_get_hostaddr(void); @@ -71,7 +71,18 @@ extern uint16_t ip64_packet_buffer_maxlen; #define IP64_INPUT IP64_CONF_INPUT #endif /* IP64_CONF_INPUT */ +#ifndef IP64_CONF_UIP_FALLBACK_INTERFACE +#error IP64_CONF_UIP_FALLBACK_INTERFACE must be #defined in ip64-conf.h +#else /* IP64_CONF_UIP_FALLBACK_INTERFACE */ +#define IP64_UIP_FALLBACK_INTERFACE IP64_CONF_UIP_FALLBACK_INTERFACE +#endif /* IP64_CONF_UIP_FALLBACK_INTERFACE */ +#ifdef IP64_CONF_DHCP +#define IP64_DHCP IP64_CONF_DHCP +#else /* IP64_CONF_DHCP */ +/* Enable DHCP per default */ +#define IP64_DHCP 1 +#endif /* IP64_CONF_DHCP */ #endif /* IP64_H */ From 17ff3bb46693dcbd4e5274dc9407be5979779671 Mon Sep 17 00:00:00 2001 From: Lars Schmertmann Date: Tue, 22 Sep 2015 09:58:38 +0200 Subject: [PATCH 098/120] Added ECC functions on elliptic curve secp256r1 --- examples/econotag-ecc-test/Makefile | 8 + .../econotag-ecc-test/econotag-ecc-test.c | 2182 +++++++++++++++++ platform/econotag/apps/ecc/Makefile.ecc | 1 + platform/econotag/apps/ecc/ecc.c | 1016 ++++++++ platform/econotag/apps/ecc/ecc.h | 103 + .../15-compile-arm-apcs-ports/Makefile | 1 + 6 files changed, 3311 insertions(+) create mode 100644 examples/econotag-ecc-test/Makefile create mode 100644 examples/econotag-ecc-test/econotag-ecc-test.c create mode 100644 platform/econotag/apps/ecc/Makefile.ecc create mode 100644 platform/econotag/apps/ecc/ecc.c create mode 100644 platform/econotag/apps/ecc/ecc.h diff --git a/examples/econotag-ecc-test/Makefile b/examples/econotag-ecc-test/Makefile new file mode 100644 index 000000000..bfc3cf2c8 --- /dev/null +++ b/examples/econotag-ecc-test/Makefile @@ -0,0 +1,8 @@ +CONTIKI = ../.. +TARGET = econotag + +all: econotag-ecc-test + +APPS += ecc + +include $(CONTIKI)/Makefile.include diff --git a/examples/econotag-ecc-test/econotag-ecc-test.c b/examples/econotag-ecc-test/econotag-ecc-test.c new file mode 100644 index 000000000..e1675a390 --- /dev/null +++ b/examples/econotag-ecc-test/econotag-ecc-test.c @@ -0,0 +1,2182 @@ +/* + * Copyright (c) 2014, Lars Schmertmann . + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * + * This file is part of the Contiki operating system. + * + */ + +/** + * \file + * ECC algorithm test + * + * This file contains tests for ECC calculations + * + * \author + * Lars Schmertmann + */ + +#include "ecc.h" +#include "contiki.h" + +#include +#include +#include + +/*---------------------------------------------------------------------------*/ + +/* Test vectors from https://github.com/iSECPartners/nano-ecc */ +uint32_t ecc_data[][7][8] = { { + { 0x01dcc6de, 0x6c8f8d3e, 0xe2612dd2, 0xdd3c4440, 0x3fee4131, 0xf02322c5, 0x4059c2ab, 0x751f7f74 }, + { 0x9a623445, 0xb27e2e17, 0xba50e608, 0x21b65597, 0x09d67258, 0xff5df02a, 0x03ca8c17, 0x698388c3 }, + { 0x26518fc8, 0x3235d8c5, 0x18ecb8fe, 0xebdb3791, 0xc0633d8b, 0x6c0dbf13, 0xe971273b, 0x5d56f932 }, + { 0x19a2428a, 0x1bdf8fdd, 0x418342e4, 0x67ff1a26, 0x309b7a46, 0x3a86104e, 0x0a6aea35, 0xe6f12ea2 }, + { 0x3ddbac31, 0xb2275232, 0x8b2abe7a, 0xd0d0bd74, 0x80d4f48a, 0x7a263898, 0x2d901339, 0xc53afd8d }, + { 0x24c5bd75, 0x2fe8b15b, 0x1a7983d9, 0x314984ea, 0xc453199e, 0x9c6a1083, 0x04441728, 0x77e815e3 }, + { 0x623cc072, 0xa3e5f3a2, 0x96a3b696, 0x83ca161d, 0x549145d3, 0x227369fb, 0xccf3a85c, 0xb97a69bc } + }, { + { 0x0d2cf2f4, 0x0d21f5f2, 0xfac9aca1, 0x840ab553, 0xec0dcf69, 0x4be4cecb, 0x128a0c0a, 0xa7f8b38f }, + { 0xf59800f2, 0x60a3a8d2, 0x819f2edb, 0xf2776dd0, 0x9f61d8d9, 0x8d7eb569, 0x4c4ec6ce, 0x07c4cdfa }, + { 0x8743783b, 0xd9eb95a6, 0xd27f08a8, 0xc9022285, 0x79b842b6, 0x03eb2d8b, 0x79f4baa4, 0x29036424 }, + { 0x5afd98e4, 0x0124388b, 0x15c3334f, 0xca6831e1, 0x14f32098, 0xf34ee3a6, 0x6dd6bc20, 0xde338482 }, + { 0x65db89d0, 0x7a975020, 0x1374d49b, 0xea8761b0, 0x99287467, 0xcdb741c5, 0x07640ee0, 0xbd00bef4 }, + { 0x700808f1, 0xf583f9f2, 0xd5ab6476, 0xb9470da3, 0x95447300, 0x1112ebbe, 0xaed5373f, 0x96060cb5 }, + { 0xbfaf6509, 0xaa24f83a, 0x5d18f3f5, 0x6b51122c, 0xdac95e1f, 0xb7e1f089, 0xf08bbed0, 0x3f1b874e } + }, { + { 0x33b5f336, 0x59e0d59b, 0x95601007, 0x3ec65a9b, 0x1854b42d, 0x74bdac00, 0xe6074168, 0xf5226a9b }, + { 0x494fabf0, 0xd1b5a4d4, 0xc0fabd37, 0x3d58ae63, 0x40356339, 0xcdd8a1d2, 0x2b96bd7f, 0xf309c0ad }, + { 0xac2aed2b, 0x2b8f5476, 0x0a65c8a2, 0x721de0e4, 0x77064eb6, 0x607e8f27, 0x4cb86d6f, 0x3aa4ec20 }, + { 0xce83cb4b, 0xbc8af90d, 0x91322d14, 0x58191442, 0x2a6387a6, 0x13fcaec4, 0xab0a4f92, 0xff990a1e }, + { 0x71669ba0, 0x939cceac, 0xce8d1d9a, 0xbbb4c801, 0x9904ace3, 0x04b7b8ef, 0x6657c7ff, 0xb6abb68b }, + { 0x3e5aa24f, 0x5ca3c331, 0x5139f40d, 0xe20ed654, 0xbe462e8e, 0x2707caf0, 0x24477db8, 0xd1bef9b1 }, + { 0x14d05b05, 0xd63c1f53, 0x47e3adcc, 0x70f5b519, 0xdbfcfc98, 0x02173932, 0xa0b0b921, 0x8a214dbd } + }, { + { 0xd262ce98, 0x2c116c77, 0xfa6a5ee7, 0x79152505, 0xb91f74a6, 0xd0db6ac0, 0x1ab4d986, 0xf53947fc }, + { 0xeadb841a, 0xda614f41, 0x0b7da371, 0x646d15ae, 0x159f7cc8, 0x4a2a43f2, 0x7ac27c91, 0xcee899f2 }, + { 0x78f156d2, 0x693bd20d, 0xfbc1e011, 0xf09e8a7c, 0x4e0d5823, 0x359a4595, 0x794303b4, 0xf8bef042 }, + { 0x9af1f222, 0x3d684941, 0xd6e56d92, 0x7b68ba32, 0xc0948cb2, 0x568a9354, 0x7aea45fb, 0xa1294a0b }, + { 0x5089a211, 0x826e1094, 0x974d4237, 0x90b08a0e, 0x62b66725, 0x99bb9dd2, 0x26569adc, 0x64ca5b7f }, + { 0x737f3039, 0xf0dbfaaa, 0x246f5559, 0x46326009, 0x26913709, 0x0048b096, 0xa95b088e, 0xefaf0be3 }, + { 0x4a1e8607, 0xef0181d3, 0x77cc4301, 0x1b708962, 0x61522020, 0x6db10e6c, 0x9e216660, 0xa2967953 } + }, { + { 0x6aefadbd, 0x6a96bab7, 0xc235e509, 0xb063b919, 0xc66f222b, 0x67f98a65, 0x0ea41576, 0xf8526e6b }, + { 0x77e50fde, 0x66f58ff3, 0x95d72a86, 0xe7f8ee13, 0xb43437f4, 0xf719f833, 0x4af4915d, 0xcb5c6d2d }, + { 0x8fbeef09, 0x24af00e4, 0x303b1db8, 0xbbf1dae7, 0xa1dab5cf, 0x7b22a089, 0x6cc93dee, 0x0cba7aa2 }, + { 0x26af27b4, 0x2684c828, 0x729ad7b0, 0x8ef161eb, 0xc12ac74d, 0x928ac3b4, 0xac9499da, 0xfe1c57c0 }, + { 0x15bc7280, 0xbe29a6d6, 0xe57bf1bd, 0xe68893d0, 0xc1312fcb, 0x3efae48b, 0x0c691973, 0x694fdc1d }, + { 0x05e64712, 0xa9669dea, 0xfa71f8b7, 0xb6de4567, 0xa2cc36e3, 0x889f5e34, 0xcc94f1fe, 0x2646763e }, + { 0xce756758, 0x0d9b6b53, 0x66a4d864, 0x8c4a3aa9, 0x99d5b022, 0x91a4dd18, 0x400612d0, 0x9f8b72d8 } + }, { + { 0xed3a3660, 0x5080a6e8, 0x6b95ca21, 0xa23d9aa2, 0xb3949551, 0xb9f2d46b, 0x26535847, 0xb8c62b06 }, + { 0x05405ae9, 0xb61b8454, 0x9aa94bf2, 0x7a2e5ac1, 0xea772505, 0x614a5a28, 0xf563a10a, 0xd4d45bd7 }, + { 0x6a80cf8c, 0xe725b198, 0xc371ee43, 0x4a8047e2, 0xc6f58553, 0xffa3c341, 0x2f4a9713, 0x0c6b7d0b }, + { 0x96283c3e, 0x9355c40b, 0x4f02e8b5, 0x6a62c4dc, 0x9e4da9aa, 0xbad8207d, 0x5e67afaf, 0x26fc0530 }, + { 0x25cefc44, 0xa29b4451, 0x404e8418, 0x5aab901d, 0xf6d0a1a5, 0x8a8438b1, 0x4b4964a2, 0x1704792c }, + { 0x02af9562, 0x948d3fe4, 0x4ca218e4, 0x3fb57e0d, 0x57f6e2d7, 0x7c3db023, 0x8cbe424e, 0xc9dd9b16 }, + { 0xc656a582, 0x157d2ef5, 0xe292e1f1, 0x1a368124, 0xe05b3093, 0xeab74f3b, 0x2196cb68, 0x57c6f1a5 } + }, { + { 0xb19e4c50, 0xee52bcd7, 0x4834dbb6, 0x03e721b5, 0x32108a97, 0xc575e528, 0x5ccbfe1d, 0x099c5d8e }, + { 0xb119ab54, 0xcfe14a69, 0x456bc938, 0xdafd4059, 0xb904aca1, 0x1a861997, 0x6374580d, 0x71354259 }, + { 0xa0a9a344, 0x6dde4baa, 0x57d7644d, 0xad71af57, 0x9154c72d, 0xa5426581, 0x6d501f29, 0x3dcc0c53 }, + { 0xd5d55773, 0xa48d40e7, 0x4c299836, 0xa3c3aa27, 0xb7060b27, 0x4c0b55f7, 0x190ffb64, 0x0a3e5fae }, + { 0xf7197092, 0xb06b1445, 0xdec8c324, 0x84a10310, 0xf8ffe96b, 0x16bfc375, 0xe3857b4b, 0x2dcf6157 }, + { 0x3ed661df, 0x69128ce4, 0x4863697b, 0xf846460d, 0xa6087ea7, 0x51e4db88, 0xe4dd1b45, 0x3dc4bdef }, + { 0x29fb38a0, 0xb69a329f, 0x7fed93cc, 0xd1ec8509, 0xf3907fd8, 0xf8ab1ff0, 0x19950850, 0xaa9a03c1 } + }, { + { 0x361859ce, 0x867cba28, 0xa39a5255, 0xf70d11f8, 0xb9fc2131, 0x7cd59204, 0xbe14e485, 0x7d0f4b93 }, + { 0x41bcb98a, 0x1f281f64, 0x61c98305, 0xf066bd0f, 0xd6ada91a, 0x8cfb9f1d, 0x328c8d89, 0x753932c8 }, + { 0xe474b0ae, 0x4a7e981b, 0x7cf03f2b, 0xec09086e, 0x805a8546, 0x5b0ddacf, 0xe8f06c37, 0xbf7452ce }, + { 0xc0a55fe4, 0x0c8d529f, 0x19d763f7, 0x7454ff5e, 0xb4964f9f, 0x8ced59fa, 0x06e12800, 0xabb82b0b }, + { 0x0069d9cc, 0x8b2d3165, 0x54088fec, 0x9ea2b828, 0xacfad6ec, 0x330d6ce2, 0x2efc0264, 0x33737dae }, + { 0x7c7c1d79, 0xbb3640d2, 0xea6a1ae9, 0x3f925a78, 0xd71afcb0, 0x58d88d2a, 0x17ae8765, 0x38c058a9 }, + { 0xd7829d16, 0x3f9504c0, 0x1b1fec7e, 0xc8322d3a, 0x405fd919, 0x3225b4af, 0xc94b8eb9, 0x0fcffc22 } + }, { + { 0x8655a5f6, 0x4aa2ad7a, 0x545dea85, 0x33e98fd2, 0x353b4c5b, 0x17a3c2aa, 0xd04879e0, 0x3c129174 }, + { 0xb42400f9, 0xfd85dd35, 0xec4df9ad, 0x57802e1e, 0xeb1af871, 0x037c50c8, 0xef3c2339, 0x1ae01102 }, + { 0x64d7235c, 0x41f8e7c3, 0xf608d9a5, 0xe5d05986, 0x07a2e704, 0x73a4b0f5, 0x9aeae4b9, 0xc924967b }, + { 0xd3d01754, 0x1ca13de8, 0x6fb9c8f2, 0x66ced741, 0xd20c7f74, 0x2ab0a7b5, 0x4484930d, 0xe8eeaf3a }, + { 0x05a267c6, 0x29394c78, 0x212dc594, 0xe2f65cfb, 0x911e9f22, 0x066d4ca0, 0xc691a4e0, 0xbe6a4ec2 }, + { 0x7093c8c0, 0x46c84938, 0xf948d5a9, 0xaff0ada0, 0xd941397d, 0xf5e08f06, 0xd6c02942, 0x34cf551c }, + { 0x8862a919, 0xb9e5cec5, 0x2e1b13f6, 0xaa2a6a08, 0x9d795333, 0x13f0b2ea, 0x1542db97, 0xdd4df512 } + }, { + { 0xc81f9a77, 0xfc19cdc2, 0x2546465a, 0x128ec4b7, 0x413334d2, 0xebe931ab, 0x99d8658d, 0x2b7c0a40 }, + { 0xcd7479af, 0x46380c5d, 0x761c619c, 0x60fd22d6, 0x594e72c8, 0x9ebb5a68, 0x860f40df, 0xc385724e }, + { 0xec92c524, 0xaa5beb2c, 0xfd54d0e6, 0x90fb0745, 0xb693dea8, 0xfab2f691, 0x7d031158, 0x2292be51 }, + { 0x302085b6, 0x59f3a3d6, 0x0e2d8a11, 0xb58b4afd, 0x3f0a3eb2, 0xdbbd2dad, 0x34f12533, 0x1443a29f }, + { 0xbacaa933, 0x9e9d317b, 0x571f930e, 0x4925d01e, 0x4e7804ae, 0x0a26a382, 0xe6b26cb6, 0x15d77189 }, + { 0xa98fba79, 0xb8b92d81, 0x699c2149, 0x32f18c0a, 0xb7563138, 0xb749e717, 0x19b29021, 0x13ab89f9 }, + { 0x2d5e713e, 0x8e989661, 0x4c2c3ec1, 0x4337676c, 0xb03b6c5d, 0x5ac054e3, 0xc3e56a9d, 0x970b9d95 } + }, { + { 0x1abd6f4b, 0xb3a17958, 0x82284674, 0x7a0b7df9, 0x37c5a4d8, 0xf1e1fc30, 0x4ab90c08, 0xc17c937d }, + { 0xd6dcea60, 0xc2c4845d, 0xdd9d9b99, 0x0f4a1c13, 0x5a1c1e7a, 0x1bc5f66a, 0x3d7a5006, 0x6c506acd }, + { 0xdd31b410, 0xf791a74c, 0x709e9c04, 0x125812db, 0x202083bb, 0xf9f703c3, 0x83a3c36a, 0x93c33b97 }, + { 0x0769506e, 0xa2f38940, 0x79535a97, 0xe635be24, 0x7d355188, 0x1082cff4, 0xa92a5187, 0x1b1b2773 }, + { 0x1c03bc37, 0xce06e83d, 0xf420fc7f, 0x0d259634, 0xeb02658d, 0x08621d54, 0x6d959a64, 0x7ff42395 }, + { 0x5eb329e9, 0xb6b53979, 0xbd5a1d15, 0xf9a26522, 0xf006b31f, 0xd796af76, 0x4eaa60a1, 0xe94f9ad9 }, + { 0xefd27c6b, 0x3f4bee0e, 0x398eff6e, 0x35a01d32, 0x079eb392, 0xb32900cd, 0x2153cb34, 0x969a7076 } + }, { + { 0x75f895fb, 0x14d958f0, 0xe630bc01, 0x5d5d2240, 0x151194d9, 0xadef3378, 0xbb8cac52, 0x4bf9af4c }, + { 0xa87b27a1, 0x66443fad, 0x6e8eb69d, 0xdcf3c748, 0x81024d3d, 0x045793ff, 0x55e91a99, 0xa5fb10f6 }, + { 0x8016a291, 0xc992ae17, 0x10c19198, 0xb2148762, 0xb81df852, 0x08004fe2, 0xd5accd8a, 0x6b2ffe51 }, + { 0xdb89df5c, 0x7c88902c, 0xaed170c1, 0xa57d6ade, 0x034ff768, 0xeb4d868b, 0xed4434f8, 0xb3317c76 }, + { 0x00dd9f1c, 0xc464871a, 0x51b3483d, 0x9091cdd6, 0x3a4ad976, 0x6e9957d9, 0x1982a72f, 0x539d53f4 }, + { 0xacf47c87, 0x6b75d11e, 0x8f5c2887, 0xc7b097f8, 0x861ca1de, 0x2e6fa5b9, 0x6073fa84, 0xa78c4fa2 }, + { 0x32b1393c, 0x3221d47e, 0xd23a49cd, 0x0f11554b, 0x9ceebe9b, 0xab0b03b7, 0x4b6e7441, 0x26c7cda9 } + }, { + { 0x94c472bf, 0x79da14f4, 0xcc7848ce, 0xd0a3f41d, 0x06692f58, 0x4c2db546, 0xd9dbf932, 0xc1873d4d }, + { 0xf1906c69, 0x7df54ee0, 0x8229c4d6, 0x8ad15c28, 0x49adb482, 0xd673baf4, 0xd1db16a7, 0xa8e5e3ea }, + { 0xde6cc806, 0x22aa1c57, 0xb1353c4a, 0x76b84f31, 0x1a54c746, 0x323fd3fa, 0x2ea2b234, 0xe8817ff5 }, + { 0x91c7de40, 0x0271b83f, 0xdb959719, 0xd42ad457, 0x685e5648, 0x9003a4b0, 0xd0a74933, 0x19cb6b56 }, + { 0xe4ec2b1d, 0x8c213e97, 0x0f84c083, 0xd987fb55, 0xb4cd0072, 0xc8e3ede3, 0x298da8c9, 0xed46c25f }, + { 0x52cdd5e3, 0xf9eb66b2, 0x715e0f8b, 0xeeab3d77, 0x5fe40b70, 0x9543e0b6, 0xc4e98491, 0x82a6190f }, + { 0xa274e4bc, 0xbe247bc6, 0x34ec15d0, 0x0550ab13, 0x0ae696fd, 0xfa7d477f, 0xf4c953bb, 0xb0b9d3e2 } + }, { + { 0x450db8f1, 0x5f43bce3, 0x4d82e2cb, 0xfd76bae4, 0xd1712a7a, 0xf745fd41, 0x38a3776a, 0xbdd475bf }, + { 0x93097997, 0xbce94d70, 0x307cd38e, 0x8d2f50a4, 0xf43d073a, 0x838ebc02, 0x74bcf139, 0x75eccfc4 }, + { 0x29bf5a6e, 0x51ff4baf, 0xb786841f, 0x50a26fb0, 0xb73b2eee, 0x15c99855, 0xef2ec068, 0x69c52545 }, + { 0x7783df8e, 0xbd77d58e, 0x53789b31, 0xdb34aded, 0x073bd783, 0x01f53d6f, 0x9ee77ea0, 0x1e5db59b }, + { 0xfc4ffb2a, 0x33485ace, 0x448f0cdb, 0x67baf446, 0x8d897cf5, 0x0558b4ea, 0xc03c0449, 0x90185cdd }, + { 0x4b55aef5, 0x391325fa, 0x0eb13f3b, 0x6d1936f9, 0xd79ab56a, 0xe4677bb1, 0xcf233bee, 0x7cae3f82 }, + { 0x60bca032, 0xef59cbdf, 0xca93d74b, 0xdcaaf290, 0x89499e43, 0xb0000c61, 0xfda7c34c, 0xa8a303a5 } + }, { + { 0xf563f0b8, 0xea7610d1, 0x8d35a2da, 0xb75964a1, 0xe68fe2f6, 0x11eec908, 0x35c5ba6d, 0xd6a264d9 }, + { 0x0561f684, 0xc0304119, 0xb8fa5656, 0x0eb431c4, 0x5b30409b, 0x6c9ef75e, 0xf77afccb, 0xf1fb796e }, + { 0xdd7e958a, 0xd3d873e3, 0x0854439c, 0xae1e4223, 0x7167987a, 0xcd1d8467, 0x523be4eb, 0x796a28e7 }, + { 0x21ad1d15, 0xe52ece62, 0xe19ab217, 0xdbb11c18, 0x3ffb82cf, 0x33a51615, 0xb427bdf2, 0x593e3959 }, + { 0x3b665341, 0x390035fe, 0xffcd92d2, 0x5d565393, 0xecf2c92a, 0xb65c0cb1, 0xf7968ae8, 0x04f2d373 }, + { 0x1191b1aa, 0x56df60fe, 0x4a28623d, 0xdc443bcb, 0x2bf1f915, 0x17906493, 0x0d66b04f, 0x7b97fcb0 }, + { 0xb74a031a, 0xf312938a, 0xa083ad85, 0x2b1902b4, 0xf763fba8, 0x32ceddd3, 0x79b4526f, 0x04a3ad56 } + }, { + { 0xefff17a2, 0x2f2fce3d, 0xd3700c90, 0x7ee9eb35, 0x5ef6198c, 0xbdc9bb0a, 0x26a22d3c, 0x300b2fb8 }, + { 0x81a4d10d, 0xa5e708c5, 0x2dce5f47, 0xaa2012a0, 0xa9ae2095, 0x1eeb4b4d, 0x457aa9d9, 0xeb1ee001 }, + { 0x342eecc2, 0xb5c66a57, 0x0c4ee139, 0x8793343d, 0xa4d8642b, 0x833284c5, 0xabe83fbb, 0x11f08d72 }, + { 0x4fc2206b, 0x41c7b511, 0xf05cc17b, 0x528ffd59, 0x062c9124, 0xbf03c9d4, 0xd978af38, 0x8d0d85ea }, + { 0x87b8ba22, 0xd91e6a06, 0x6169070d, 0xc50f39fe, 0xd270229f, 0x1d72f559, 0x7d0a1762, 0x463ab03f }, + { 0xa4393a4f, 0x9987b543, 0x6f1b03ab, 0x71096fda, 0x9f6dd1d2, 0xf6abc382, 0x35815067, 0x5c365f18 }, + { 0xacdfbfbd, 0x09c57c49, 0xb1afd6ce, 0x2b5821fa, 0xe5997374, 0x35bd8649, 0x22d95b9b, 0x25f30fad } + }, { + { 0xa90802ef, 0xfbcf614d, 0x762de0e6, 0x48c13c66, 0xfa232910, 0x79599693, 0x2c2e26e7, 0xdfefa34e }, + { 0xc0dd8a96, 0x4f1aa0d6, 0x6b8b515a, 0xf27d261d, 0xbc6ee470, 0x5f85a545, 0xfea1cff4, 0xa8b192a1 }, + { 0xd30b6441, 0xb58b28bd, 0x3fac92c9, 0x52fdc9ee, 0xe5297d14, 0xcbd886a1, 0x7252175e, 0x9a165e66 }, + { 0x3dacc04f, 0x98d69b1e, 0x60881c32, 0x501798eb, 0x7184054c, 0x0eec61ae, 0x15585572, 0x7ce7bcc3 }, + { 0x26e4c3bf, 0xc3db64e9, 0x04c85398, 0xb05a43ef, 0x287760dc, 0x5f9c4fd9, 0xa9546cf3, 0xeb64d6d9 }, + { 0x9f56a099, 0xf4464509, 0x666f89fd, 0x3cf27dbc, 0xf78f4ebd, 0x15a92221, 0x1c5f18b4, 0x4ef8d6ed }, + { 0xb9032db3, 0x14df48da, 0x90822fcc, 0x34a687d3, 0xd0c9cbce, 0x49f5523f, 0x57d75028, 0x4d2b7b81 } + }, { + { 0x7a7db3d6, 0x4ce01deb, 0x8d46d28e, 0x0598389c, 0x02496d36, 0x6a946efe, 0x48d76b64, 0x0b398fdb }, + { 0x96dac371, 0xf0e94574, 0xabaeb1f3, 0x464f352e, 0xa538a1b2, 0xaf0839e8, 0x264e3def, 0x70ccb6c0 }, + { 0x8b633b83, 0x9f1fa614, 0xf229f235, 0x18968cfd, 0x1d2be847, 0x47ac9867, 0xc4f32121, 0xa08f2485 }, + { 0x9b553f9b, 0x6939d623, 0xbb578ffb, 0x3de56d02, 0x8d0288c2, 0x4295788d, 0xb53e60ea, 0xbfe08468 }, + { 0x15e12986, 0xbd19316b, 0xfd84a08e, 0x6fde5356, 0xec8dabcc, 0x78c17332, 0x46dbfd97, 0x21e6adf3 }, + { 0xdaf2f1be, 0x6d3d5236, 0x5e95911b, 0xe0571ed2, 0x402aa279, 0x04bc377f, 0xed587a14, 0x9c2db51f }, + { 0xb4a6e3b8, 0x71d06437, 0xbe20faa6, 0x1276fb1c, 0x28103b47, 0x31f900d8, 0x8494dc65, 0x994daf04 } + }, { + { 0x292eb381, 0xb7ccadef, 0x33e7512b, 0x0dfdeb69, 0xc7ee08b9, 0x39a4fbc7, 0xd764a890, 0x7ab00e4e }, + { 0xf7586ade, 0xa3b4d9dc, 0xf789c47e, 0x48beadb2, 0x8a45db69, 0x2e9b595d, 0xfff2a7fa, 0x06ffc027 }, + { 0x19009f8b, 0x88199f63, 0xc306713d, 0x54eae017, 0x7868c7c1, 0xb21b75d4, 0x2236bda7, 0x5277b103 }, + { 0x9d7f35d5, 0x10da1900, 0x79c91037, 0x9f2775fb, 0x2e45ba78, 0x92bc5da3, 0x48b1946e, 0x2b45cb34 }, + { 0x1f6d90ed, 0xaa688d80, 0xfd190719, 0xc1dcd836, 0xb7de1894, 0x5cd7e515, 0x87bb48cf, 0x94bf41c7 }, + { 0x35f36e1b, 0x0da6b6b8, 0xd381a23c, 0x60659705, 0x6c319695, 0x27279409, 0x69130c41, 0xe1fa08ff }, + { 0x8844af91, 0xf2d47dfa, 0xde6ea7b0, 0x2f156a2b, 0x86f8ec0b, 0x38f9d722, 0x7cff87e4, 0x9ab38e0e } + }, { + { 0xb01fd34c, 0x3885168b, 0xa35130d9, 0x8e01a5ca, 0xe6d2d65f, 0xc724f8a0, 0x2e0ef604, 0xfed3c171 }, + { 0x151c057c, 0x9fa733ef, 0x825ba0da, 0x6e283e59, 0x77c4880a, 0xfd107591, 0x3fb3b4e7, 0x274fed9e }, + { 0x3a32979a, 0x29a9b49f, 0xec8e3c5c, 0x3e0ef290, 0x4e3716e2, 0xbfc82d3e, 0x6c250829, 0x3abab9a7 }, + { 0x012addb9, 0x47841e2b, 0x61f0a516, 0x6ba10a6e, 0xfecba910, 0x90a3ef22, 0xfdcf969f, 0x2128f99b }, + { 0x9b81a4e9, 0x57c34d33, 0x026d2762, 0xafd4a1fa, 0x61ea2467, 0x29a81c62, 0x85350d61, 0xe2e0f0c5 }, + { 0x0bf92a10, 0x23e4f7e1, 0x975e75db, 0xb97b6285, 0x7728a26d, 0xa6525408, 0x063a2419, 0x397410be }, + { 0x4ea96c8b, 0xfa56724d, 0xff16421c, 0x7ed6477a, 0xd1e48c81, 0xdb4a93a2, 0x5c4951c3, 0xc0b4a685 } + }, { + { 0x397e460f, 0x89a93121, 0x72092100, 0xbfe312f7, 0xf1a58537, 0xa4d5dcfe, 0x37af5042, 0xf35b1b01 }, + { 0x2ff60f87, 0xfe9a309f, 0xc472ccd3, 0x8d7eeb71, 0xb3739e44, 0x1ca9869d, 0x42da241b, 0x6c858419 }, + { 0xb9d40ae5, 0x5d4e2313, 0xa9c468b0, 0x3d3ddbeb, 0x09906625, 0x50d61c42, 0x2c46d732, 0x3446aa5a }, + { 0x564aa504, 0x96b85cc6, 0x7ef4907c, 0xcd581ab9, 0x65c3841d, 0x865a4915, 0xf7ee2a16, 0x22235ea8 }, + { 0x6cd307e2, 0xb1b22b38, 0x95032608, 0x31598c90, 0xd537604d, 0x97c7e413, 0x73b456e4, 0x6a2df38c }, + { 0x58d9d79f, 0x5aa00b5b, 0x060dd287, 0xc29d346a, 0x8ca763d7, 0xf9f60c66, 0xba6b25a3, 0xa012e14f }, + { 0xe5b626d8, 0x01e19b5e, 0xcbe01ee7, 0x025d6cef, 0x03b6541e, 0x8df0d079, 0x4d4b5178, 0xe7c9c2d1 } + }, { + { 0x09b93266, 0xe2769374, 0x213ce748, 0xbdfa1677, 0x0833c4c0, 0x41241dd0, 0x5bd71904, 0xbe1be728 }, + { 0x280dfedf, 0x6c83f463, 0xba81c79f, 0x78451dfb, 0x3cd12106, 0x044baeb6, 0x77de78f8, 0x036d574c }, + { 0xbd4314fa, 0xd2fb4774, 0xa0b9198c, 0x075e9aae, 0xf99cb714, 0x06bad8ce, 0x17ac87dd, 0x6bf39045 }, + { 0x05af7421, 0x59dc4c4e, 0x66815303, 0x09410376, 0x1d71e342, 0x1a353ad2, 0x7a3196ac, 0x187fe364 }, + { 0xe600765d, 0x070cc12f, 0xd81e74d8, 0x826ee687, 0x6db09ba2, 0x6b88cec1, 0xecca0bf8, 0x0036f362 }, + { 0x5ed8ab47, 0x2fd14208, 0x5aa133bf, 0x7aa529c9, 0xbe424f8b, 0x37c853a8, 0x8afbf260, 0x1bde2671 }, + { 0x5cd6392c, 0x3cdc089a, 0x71d39600, 0x4bcc77d8, 0x0f8df2a0, 0x7566744e, 0x494c12fc, 0x387dee4a } + }, { + { 0x4f51085f, 0xf2b90e78, 0x6f68ce61, 0x1c4787f2, 0x4fbf6b17, 0x004a475a, 0xedfdd2b8, 0x3ef4e7d0 }, + { 0x003f3477, 0x6e0b73e7, 0xf67c90c9, 0x6566374a, 0x0c97fd0d, 0x8be541c5, 0xc2f93b18, 0xf55abff5 }, + { 0x4f03151d, 0x83d50b54, 0x8feae836, 0xe1a91a33, 0xeafb00d6, 0xdfea4420, 0xf9db7e56, 0xbf34289f }, + { 0x6dfb6bdd, 0xd7cc8039, 0x7b0d4aa7, 0xf2f2a14f, 0xab9dd117, 0xff4c8602, 0x9cce7b21, 0x40b2e4a9 }, + { 0x72fa24e4, 0xe2616778, 0x5c058a57, 0x00ba3342, 0x2347e305, 0x8c67fdf0, 0xb967b82a, 0x9fe9b032 }, + { 0x6f4635cc, 0x638b3c73, 0x2e4df741, 0xf7898209, 0xfb573977, 0x59145c96, 0x1af9c653, 0x7b9e3a69 }, + { 0xae9393f7, 0x21f731be, 0x21d894a3, 0x5499a86b, 0xbf841bcf, 0xe947043c, 0x2d75eb05, 0xa72f2458 } + }, { + { 0x8849feed, 0x0516788b, 0xc3ba6cab, 0x73b37f89, 0xe1c59baf, 0xb9065f21, 0x42db6705, 0x83d1eef0 }, + { 0xd6e2fbd7, 0xfa08de4d, 0x3295a08a, 0x948df703, 0xab891657, 0x0940ef31, 0x56d8465d, 0x440d4979 }, + { 0x6ba6d91c, 0x5d5a992d, 0x4089007d, 0xc20f2ad3, 0x548b65f4, 0xdbcff879, 0xe76c77b7, 0x1ad4bd47 }, + { 0xe6dbd3a4, 0x0ddc5764, 0x50227b93, 0xfc70d526, 0xa782abeb, 0xb1eacd16, 0xa6d1d6c7, 0x3eb2fc3e }, + { 0xca7f5ec6, 0x027a6535, 0xf2c08c93, 0x5ab506be, 0x1034a638, 0x91f473e6, 0xc1843ed8, 0x1900ee1f }, + { 0x7a60c3a9, 0x50a3c756, 0xfc5ad1c7, 0xfb5297ce, 0xf06994f8, 0x8736d618, 0x15973fad, 0x87288eed }, + { 0x9eb55603, 0x574a3dc8, 0x66b34637, 0xe38ada16, 0x208710ad, 0x821c2d3a, 0x4d0d95e4, 0x492d3e98 } + }, { + { 0x5c6da280, 0x7b503d23, 0x7a7ff562, 0x13eca08b, 0x9b2ec963, 0x20b5c43e, 0xb9875398, 0xd1588b1d }, + { 0x3898e3db, 0x5d0c38a5, 0xab945ab3, 0x3017f692, 0xa71d187f, 0x62a32ce9, 0xbd51abff, 0x44106aaa }, + { 0x332bbd9a, 0xbc614c8e, 0x50796b90, 0x75ad5cc0, 0xa416a2e1, 0xff24e815, 0x8b0dc6ec, 0xe49b3860 }, + { 0x2c8930f3, 0x73ff7c6d, 0xd0de16d7, 0x7a8d3740, 0xfdb757d4, 0x1f438bbc, 0x27415f95, 0x256f557b }, + { 0x8f7179e9, 0x4ac99a49, 0xcabae259, 0x8b195d21, 0xb444b039, 0xe6dc2b14, 0x3dff8dbe, 0x435c99ad }, + { 0xbde84be4, 0xa5e876ea, 0x79ffb62e, 0xb4b59c38, 0x88474d8d, 0xaaeb867e, 0x6f541557, 0xf0edbe11 }, + { 0xa9b295f7, 0xe65bbcee, 0x6a129fac, 0x2f007beb, 0xcd3dcf72, 0xf5dcc782, 0x38d93d56, 0xecd192f2 } + }, { + { 0xf9e3f55f, 0x9fbcfb77, 0x711a6f90, 0xeb9dfffe, 0x8c0b2e1f, 0x0fdc1b0a, 0xc7ff8085, 0xb8f994c9 }, + { 0xfbd63e55, 0xa26d2623, 0x65c74567, 0x3fda2143, 0x4f91bd40, 0xd183574f, 0x48d6f79c, 0x895b0dc6 }, + { 0x68b4c229, 0x1a1ccfbf, 0xb901211c, 0xb2411c8c, 0xf352f648, 0x875e1f1b, 0x15fc10cd, 0xfb8c6b28 }, + { 0x15f45949, 0x502f1ab6, 0x0c528ede, 0xd4ff8187, 0x6485d018, 0xc367d6ff, 0xe766718b, 0xd5aeb78e }, + { 0x1ab4be9a, 0xe85536f8, 0x4031015d, 0xd579d758, 0xceaa2e0d, 0xace63c6b, 0x9018cae2, 0x2a5fd965 }, + { 0xfc5471e7, 0xe66d169b, 0x98fe8a88, 0xdc3c54cd, 0xe481ae77, 0xbf3ea393, 0x110b856b, 0x825aec5c }, + { 0x714d79f9, 0x3f8328fa, 0x530498cb, 0xf76d4af6, 0x2c983912, 0x89c1f5ce, 0xd8d09111, 0xeb685633 } + }, { + { 0x2d8f63c0, 0xbe538b20, 0x48f219be, 0x62f010cd, 0xe2aa9574, 0x1bb947a3, 0xeca72434, 0x3a3e6c51 }, + { 0xd81b0439, 0x103a616d, 0x044bdfd9, 0x87261d91, 0xcfaef2b0, 0x1a9e9305, 0xd168a778, 0x042fd256 }, + { 0x6565adcb, 0x82794aed, 0x7e4288d1, 0x72106045, 0xbdea5832, 0x09d2a9d3, 0x2f19d1c7, 0xbb94dac2 }, + { 0x4b1affe2, 0xc4127dbc, 0x7d4c045e, 0x0fcddbb7, 0x4da68575, 0x8cba23ed, 0x6015087f, 0x11682c09 }, + { 0x6533bc5b, 0xd2980fad, 0xbadc2f6a, 0x9e008030, 0x47e95fb8, 0x40c381f2, 0xd44c6c4d, 0x70331467 }, + { 0xc33ea1dd, 0xc834cd9c, 0x0fe19999, 0xa813b867, 0x993eddc6, 0x9ba575ba, 0x004aa894, 0xdba239ba }, + { 0x252aa22c, 0x44c17e93, 0x44290993, 0xd9a1173c, 0xe1ad9624, 0xd807429a, 0x532cd975, 0x12e0b42e } + }, { + { 0xfdb70d4d, 0x249e6468, 0xb794eb31, 0xb4cda501, 0x05d2df03, 0x26ab2206, 0x43194da6, 0xa4892a63 }, + { 0x42db2d46, 0x53017669, 0xc77e5314, 0xa9683da9, 0xfb498122, 0xddac9a38, 0xa2d4aab4, 0x4e0122b2 }, + { 0x13967236, 0x68646a6d, 0x513d4c57, 0x1aea2842, 0x093e446c, 0x298d4327, 0x0d900798, 0x9ad6c44b }, + { 0xe91847cd, 0x3df8d5da, 0x46769a8f, 0x3ad7f4d4, 0x2dc96116, 0x547f08e8, 0x840cf77a, 0xb6f0ce2e }, + { 0xfb4ea959, 0xa67079f4, 0x21e663d1, 0x10dafde7, 0xdc0ea2d6, 0x373974ca, 0x1c1cc126, 0x6dcdc5f2 }, + { 0x6808c423, 0x6f4342bd, 0x9276497d, 0x0c7fc6ce, 0x9a9e5ae3, 0x86634270, 0xdf81f26a, 0x47d913a2 }, + { 0x64337517, 0xa3a009e5, 0x98b72802, 0x4d0035e4, 0x1715ab1c, 0xae2e2a92, 0x113b2c57, 0x9a85326c } + }, { + { 0xd301c714, 0x9b6306bc, 0xa0719561, 0x98c1c165, 0x73787133, 0xecadf261, 0x64f89540, 0x5c5fa46b }, + { 0xf565ee58, 0x05263bbd, 0x88df1939, 0xf4347f95, 0xbfcfa374, 0x583ecd77, 0x7c1bfc76, 0xe6d28c42 }, + { 0xadb4b3c0, 0x146b1371, 0x58a96e94, 0x9b000315, 0xc41f4de7, 0xea787c29, 0x30c1134d, 0x6d65f20c }, + { 0xc026d6ec, 0xe96ebb42, 0x24aba2c1, 0x650a4043, 0x9ecf024e, 0xbbaf6c1e, 0x9be6b48f, 0x89e859fe }, + { 0x51de4cbd, 0x204fc586, 0x54d88ac3, 0x2da8027e, 0x47aee04e, 0x4ed28825, 0x5d773f1d, 0xc44f931b }, + { 0xced4dd07, 0xf60b6c8e, 0x80dbcd9a, 0xa8a6a7c0, 0x2320d406, 0x99043ee5, 0xe7fb777b, 0x66e1f534 }, + { 0x6ec8e251, 0x09d9982d, 0x33699ebc, 0x631c7077, 0xd2a8af8d, 0xed7b6d3b, 0xf13e160f, 0x7c03e997 } + }, { + { 0x33c4d79e, 0x898f1b11, 0x44482aac, 0x8dacba1e, 0x41e4c65d, 0x373ce7b9, 0xcc21ed0a, 0x1425aacb }, + { 0xd42df634, 0x2c0d59c2, 0x00d29c49, 0x02711b1e, 0x033e4a85, 0x5269c575, 0x383e490f, 0xaeac042d }, + { 0x033f1689, 0xc8181373, 0x957bd9cc, 0x45b8a400, 0xb9f5ccf4, 0x3f34af98, 0xad3b249a, 0x8e096a78 }, + { 0x62144bde, 0xee9c9ee3, 0x55e7d9f4, 0x2183bea5, 0x12787270, 0x3a070f24, 0x54854d06, 0x1f230a8c }, + { 0x98c2a493, 0xade86d34, 0xc4926805, 0xd2f4047d, 0x6aac8a8b, 0x845802bd, 0x279b27ec, 0xe5b61e60 }, + { 0x24f3ca82, 0xa2d5aada, 0x9ec9c6d7, 0xdabf2c25, 0x1e210f57, 0x92ad1840, 0xdec763c3, 0x078a670d }, + { 0x7533c951, 0x4b3509f2, 0xae7b17a2, 0x7fb46453, 0x095c06cd, 0xfe0f182f, 0x3bbee6bf, 0x18a14cfe } + }, { + { 0x0e2781a1, 0xe97035be, 0x7732ac33, 0x6e02ec7a, 0x9ba7d4ab, 0x2418f146, 0xfdb027b0, 0x3f16c517 }, + { 0x076864ce, 0x94754806, 0x04edbc89, 0xf79f8406, 0xbb43b69e, 0xae037547, 0xf2bd3d49, 0xa721d01c }, + { 0xc9ff1983, 0xf2c3d29f, 0xf18dd754, 0x8f547f44, 0xcfdd1ae5, 0xe2de86e7, 0xb5a20324, 0xa4929edd }, + { 0x3a5908ce, 0x228ff251, 0xa72b0116, 0x7faf015b, 0x5e47a8e5, 0x1c1769aa, 0x2f9c2b9f, 0xfdbbba49 }, + { 0xfa194cce, 0x5e55687a, 0xa888e170, 0x5b900365, 0xab7308e9, 0x1195c7bc, 0xe7e1fd36, 0xc563c595 }, + { 0xa44757e6, 0xe4824c46, 0x8f0575aa, 0xe897ef25, 0xe36d0d97, 0x87bc45ee, 0xd12fa819, 0xfb9b89e2 }, + { 0x48b3e1fc, 0xae563712, 0x0dc01dfc, 0xa055c68f, 0x52606591, 0x9546e1ef, 0x178700a8, 0x9c87b5bb } + }, { + { 0xde4ff097, 0xb76497ad, 0x41691d4d, 0xbd4ac0df, 0xd4db2a81, 0xcc3048e1, 0x2cffe546, 0x6120d83f }, + { 0xb03b5a0e, 0x374ab1f3, 0x1b4e0c82, 0x9b0eb479, 0x6e6558e0, 0xe8b9cf4b, 0x0c436779, 0x64b4cae1 }, + { 0x2aa9eec0, 0x0419fb6a, 0xec8fc744, 0xd3b8c697, 0x24f24eee, 0xbf05ce66, 0xf6bcf4e4, 0xeafe8e61 }, + { 0x9a9dd013, 0xbfe8d389, 0x32fa363a, 0xda38d629, 0x07b584d7, 0x2a843374, 0x1b08df96, 0x415c4739 }, + { 0xd1164fd5, 0x669ab97d, 0xd1886cc9, 0xe23ba6f7, 0xd897d70a, 0x212dac1b, 0x43580802, 0xbb4b44df }, + { 0xdde96bb2, 0xa665cc57, 0xc422df91, 0x28627b38, 0xe32b9043, 0xac856b0e, 0x44d1cc14, 0xd75f6e24 }, + { 0xe5bd8a60, 0x305e17b4, 0x1f9ef0a2, 0x6ee010ed, 0xacab6d31, 0xa7bdc581, 0xa0344638, 0x792c1ab6 } + /*}, { Not enough memory for more test values + { 0x28a402a1, 0x369bdeb7, 0x4d9929e5, 0x3cfdc35b, 0x99c68de9, 0x9b6b006e, 0x3f242273, 0xcf37d576 }, + { 0x6872dd61, 0xe87e9923, 0x8e8655ab, 0x67715999, 0xa60933ca, 0x641e96e4, 0x44600c84, 0xea3a4950 }, + { 0xadd02acc, 0x35f0de97, 0xecddc84f, 0x0a9dc8c6, 0xd5b537b4, 0xf7c27994, 0x75d0b679, 0xde9b4aef }, + { 0x9d6f7170, 0x2ecd6906, 0xd37b167a, 0x225544a3, 0xea804fad, 0x8e21f9f9, 0x600cc5d9, 0x9acec1db }, + { 0x30736fdb, 0x484f20b0, 0x8f237526, 0x8e2bac97, 0xe655a922, 0xba6033b2, 0x5c12ce66, 0xfd986542 }, + { 0x3fb7d59c, 0x6a2d0274, 0xb32bb0f8, 0x66420444, 0xe02c099c, 0xcb82f762, 0xf2b0ffff, 0x39925401 }, + { 0xb4904e77, 0x6aee6579, 0x6afa1fcb, 0x16c64c1f, 0xe727f962, 0xe0eac572, 0x0889748a, 0x67f2b130 } + }, { + { 0x5a4cc087, 0xc8f6a8b0, 0x1993e8f6, 0xac9cb15f, 0x445a34d1, 0xcb11c435, 0x5eba923d, 0x2032b0f8 }, + { 0xbc3487ad, 0x248e8b06, 0x34c09be8, 0x5f02e184, 0x1e170443, 0x6dd2ec7b, 0x7692ce10, 0x16c6bf1a }, + { 0x12938c14, 0x41ddff40, 0xc2d9bb7a, 0x29039e61, 0xa5ed3581, 0xc67f062e, 0x58d10b6d, 0x6c72d42f }, + { 0xe2d58c4d, 0xeb378fc2, 0x6ba88b23, 0xa07c418f, 0x13d143d3, 0xed55b235, 0x5f84d338, 0x52e2c3db }, + { 0x69e1205f, 0x4f96c4f7, 0xf79a860c, 0xef1542ec, 0xf23440e0, 0x4c66e965, 0xd60efbbb, 0x6e8f8b92 }, + { 0x824a38a3, 0xe1eafa00, 0x154e26d6, 0x78d00313, 0x20b89e9f, 0xaa788ca9, 0x19e318de, 0x6fcbb039 }, + { 0x9c23b1b2, 0x853180ef, 0x8d2961a4, 0x4f0c4086, 0xb22be3db, 0x1e900ef0, 0x9d76df53, 0x5d4c468c } + }, { + { 0x20b627c2, 0x9be7dc8e, 0x64c974d9, 0x5d4f49d3, 0xbbb2c618, 0x8ebc012d, 0x11de15e3, 0x500c8265 }, + { 0xfb78e338, 0x58caf269, 0xb2664ca1, 0xa16ff7b9, 0xd5c2a2ea, 0x59d06298, 0xcaea674b, 0x0059ff48 }, + { 0x14bd4018, 0x24070094, 0x169f4ee8, 0x8255fe21, 0x47881c1e, 0xe205f0d3, 0xe4ad2e99, 0xb51d8e3d }, + { 0xf3dbb59c, 0x0cb4edc1, 0x275400f7, 0x98d8295e, 0xd214a339, 0x99fd8ebc, 0x8acb2217, 0xf6a68389 }, + { 0x33d7751d, 0x8fb40299, 0x2b6f32f6, 0x2b2b3692, 0xa83a6091, 0x57052ba3, 0x667f9ec4, 0xb3d2f097 }, + { 0xe37fd38e, 0x13c2b82d, 0x9d913405, 0x5d2c7a55, 0x6390a8f4, 0x9fdc5f4c, 0x853e3b1b, 0x8034410a }, + { 0xfd9edeff, 0xc62d6110, 0x31567b91, 0xc7d0527b, 0x48d0742b, 0x57b3147c, 0x8f9291e5, 0x7d82cfbf } + }, { + { 0x7c63bde3, 0xaac4548c, 0x9954854e, 0xd67f0b4c, 0x04add2ab, 0xd88a2671, 0x7f2171df, 0x0d0f23c8 }, + { 0x5cf6c809, 0xd23f9751, 0xf79294c6, 0xf6019524, 0x7aa39681, 0xb8e3d988, 0x3c8c962f, 0x5d173fd4 }, + { 0x47f3efe5, 0x6d09cd2e, 0x330a8acb, 0xcfe181d2, 0xa48d9fc6, 0x4e988ccb, 0x821f042b, 0x6b5d6c84 }, + { 0x64c52567, 0x10ef805e, 0x173e3c5e, 0x3aacf828, 0x38510c01, 0x48a7ec10, 0xa3506ab6, 0x36220329 }, + { 0x5377bb61, 0x68c1f7ee, 0xe7a81b3c, 0xb43c58f9, 0xd72cb6f9, 0xd81dea3d, 0x7ae1468b, 0x55ac4f26 }, + { 0x5f731a47, 0xe3e19cfb, 0xf45410ed, 0xfba8ccc0, 0xf0c63a7b, 0x9ce539ae, 0x37e562b8, 0x180c6b70 }, + { 0x91a3cd39, 0x5ed053af, 0x09dc142b, 0x74f4a3c1, 0xa2180c04, 0x481bfb15, 0x37bfabed, 0x062e5fe9 } + }, { + { 0x28164987, 0x3c79131e, 0xd586a38a, 0x0dcbd921, 0x11f5a23a, 0x10a64e80, 0xb232f8a4, 0x9a82c6e5 }, + { 0x7b31e67d, 0x1e818e13, 0x097cd563, 0xbe4b6ea4, 0x1d7a3f57, 0x15f686de, 0x9bce46c9, 0x760756da }, + { 0x3960cfd4, 0x75bb04c5, 0x407c84d4, 0x9c625b7e, 0x7191b584, 0xb67878c1, 0x0e1fe6f6, 0x0eb1fa47 }, + { 0x271fd0fd, 0x404080f2, 0x97009534, 0x046c3515, 0x65ab41f9, 0xeb7d7922, 0x2d6499e9, 0x9c899500 }, + { 0x419f9d54, 0x0502c3c4, 0x8149723e, 0xd7b2d502, 0x20236144, 0xaa3b83a9, 0x769631be, 0x15f1e2e0 }, + { 0x601c6fea, 0x5119d153, 0x7d992c1d, 0x94836009, 0x3e7879f0, 0x9086a342, 0x803b925a, 0x4fd645ff }, + { 0xa49bc82f, 0xe14d1519, 0x1d12d5dd, 0xab10a0bf, 0x54f5e7a3, 0x90933da3, 0x21d62740, 0x1d33d0f6 } + }, { + { 0xa36e4642, 0x48c6f79d, 0x955654f3, 0x93b8d1ea, 0x6ba29e14, 0x551ad31f, 0xa99cd6a5, 0x8ccff1ad }, + { 0xcec5d3bd, 0x788fa022, 0xa65d7f7c, 0xd3f37c9e, 0xcce12026, 0x3cd4770d, 0x6ddfea77, 0x6ad3c080 }, + { 0xe81c88a4, 0xbc7bad3b, 0x3068f251, 0x18ada085, 0xa33faaf1, 0x0b797e20, 0x7a97a834, 0x8e782d5e }, + { 0xf51dde3a, 0x6db8ee9b, 0x7aa32969, 0xf2d6eec7, 0x993273e8, 0x11db4e21, 0x7a7088ae, 0x4da2d705 }, + { 0xfc7f198b, 0x86661fe5, 0x29824ae5, 0x0bb639b1, 0xc610a7c8, 0x62a3340e, 0xf591a187, 0xe265a886 }, + { 0x5f303123, 0x47f52dec, 0x34cdd38f, 0x4c7f811a, 0xc9afc901, 0xd222f90a, 0x9e172313, 0xee1b0572 }, + { 0x4a2bcd87, 0x18e236cb, 0xe5e581cd, 0xe29a6a43, 0x6a7213b8, 0xc675d970, 0x536317bd, 0x96b8b310 } + }, { + { 0xad80bed2, 0xc2f4598d, 0x4e0e6b1a, 0x9bc787bd, 0x63150672, 0x2c364163, 0xb601596a, 0xad670a5a }, + { 0x5c818829, 0xa1a6f437, 0x8d07faf3, 0xbe095484, 0x5fcd6a0e, 0xe8153a60, 0x7ab38539, 0x2ec01d0c }, + { 0xf10716f7, 0x44fd8ad0, 0xf5eb5bd9, 0x6bf45e03, 0xb71db435, 0xf3bed1f2, 0xab5c78fb, 0xe739dff4 }, + { 0xe0442ca5, 0x6096f428, 0xae68050b, 0x5040c22c, 0x38145576, 0x879ef275, 0x16ee9eb4, 0xf3c87da4 }, + { 0xf8fcd22d, 0xa7b97f06, 0xc24747b0, 0xe551e501, 0x5d5ed8b0, 0xf34f091e, 0xcafe3402, 0xb13219e3 }, + { 0x6310481d, 0x48a0e061, 0xc634d04a, 0x194efd1d, 0x4bd0f859, 0xae14caf3, 0xaccc7f18, 0x6f07f30d }, + { 0xffce35a4, 0x10d857a7, 0x1e9e7485, 0x97b41d7b, 0x69d5f637, 0x82789997, 0xa51b2cf6, 0x02014738 } + }, { + { 0xdec05e64, 0xa4305211, 0x7308530c, 0xd0382cb5, 0xa921a607, 0xc7562dc3, 0xb1411342, 0xdd40222a }, + { 0x972caa85, 0xf01a419e, 0xfd78e685, 0x03ba1374, 0x8f9bfc0f, 0x261a4f34, 0xb49fd99d, 0x24859598 }, + { 0xf016dab1, 0x4c50d39e, 0xfb46c5b7, 0x249fea28, 0xb05e1503, 0x0e350a32, 0x2dcf1792, 0x61a75e0a }, + { 0x7fd4d35a, 0xab08244b, 0xbbcd7d53, 0xd42b211d, 0x2334426b, 0x9a8be30f, 0xe15e1b27, 0x6700bb18 }, + { 0x81e463e1, 0x637b4877, 0xb6047da1, 0xb05fd377, 0x96a012ff, 0xbb5379f1, 0xac42f5c8, 0x5dba484c }, + { 0x0714b7ef, 0xba6f8b10, 0xf245d72b, 0x1ec0e0a2, 0xa30de08d, 0x606bc646, 0x7eb95591, 0x6cf9c5e8 }, + { 0xf15d21fe, 0xee367937, 0x37ca63eb, 0x38cb30dd, 0xb5edebde, 0xb6355078, 0xbb62f2ee, 0xdd48e81d } + }, { + { 0x321bf4dc, 0x678db650, 0xd85439e4, 0x7b6aea4f, 0xc5625ee3, 0xab2b9fca, 0xb9e6140d, 0xfbe4313b }, + { 0x077bcae6, 0x63858c36, 0x2baa791d, 0xc55acb58, 0x843aa75c, 0x20b25d1d, 0x86778175, 0xe4454679 }, + { 0xddfb82f4, 0xcf34b84e, 0xbc573a41, 0x8684bb95, 0x9165bee9, 0x01e96a7b, 0xdd8a5c36, 0x9bc63a4b }, + { 0x175f0270, 0x85daa416, 0x8ee7aea3, 0xfa9b3ce0, 0x9b300d7a, 0xda4ef944, 0xfc1e20b8, 0xb33f81df }, + { 0x2346a3ca, 0x842c59ec, 0xdae0db05, 0xefe15ef0, 0x2cb166d5, 0xb7d24593, 0x7e2e55aa, 0x8aba26dc }, + { 0x6c7c1a83, 0x1e49e02d, 0x7a3f46c2, 0x86e7d519, 0x255db209, 0xb47bec27, 0x69be2738, 0x982cb66d }, + { 0x9798ef0d, 0x216cf79a, 0xc8c8e509, 0xc73f1221, 0x684b472f, 0x8f58a334, 0x3d97a615, 0x4d6508bd } + }, { + { 0xa6333ddd, 0x0fe1133e, 0x690a745d, 0x62d04786, 0x50809359, 0xa30d43f2, 0x37a3078c, 0x31ad4ced }, + { 0x54dc6b53, 0xaa5dd46d, 0xef5f2911, 0x0818c5ca, 0x36c062aa, 0x044f58d4, 0x95dde443, 0x8004fc36 }, + { 0xd02db1b3, 0x1aac3560, 0x0a8deed4, 0x80e1145a, 0xbe53d775, 0xc6fe4194, 0x324c5b8d, 0x280dd8f8 }, + { 0x8e1dba30, 0x1d3218a2, 0xc63f7a0d, 0xc5be3354, 0x216a2233, 0x46508c32, 0x4762d05c, 0xf447d7dc }, + { 0x287d15ec, 0x5718b4d8, 0x890dea30, 0x918a4efd, 0x0b7d66b0, 0x26d2760c, 0xb003f19b, 0xa20a16af }, + { 0x0a67c579, 0xf114428b, 0x30826097, 0xa82d8115, 0x42e433da, 0x79952e07, 0xf761af54, 0x2509ce73 }, + { 0xe06a143c, 0x7671a5c7, 0x57ad02b0, 0x1e7922b3, 0xa79d9cf2, 0x23c7d736, 0x27a71a9f, 0xf20a7a98 } + }, { + { 0x85ab3b20, 0xcda3876c, 0xe3eb55a6, 0xa78bd139, 0x3eda09c0, 0x3f3cec06, 0x1ecee3b7, 0xa6ea50d1 }, + { 0x1fea79d6, 0x6a8467c1, 0x3607cbbe, 0x9667f95a, 0xef3c2d31, 0x81f98f91, 0x7ce8153d, 0x4c72445f }, + { 0x921d1a7b, 0xc675bde6, 0x60c66243, 0x7eaa7a71, 0x6c23d2ea, 0x1d734a2f, 0xd453c205, 0xb981e1c1 }, + { 0xea8ad813, 0x9cf1aafe, 0x1c0e04a7, 0x3d925777, 0x621348ba, 0x2df1c440, 0xee62c9aa, 0x3d927ddf }, + { 0x34b4ed37, 0x5bb5d025, 0x8c3af0c9, 0x38085638, 0xa5e93103, 0xd89a0a69, 0xc26f52e9, 0xa146e16e }, + { 0xec07d11b, 0xf96005cb, 0x9b88036c, 0x9bf2d66b, 0xba9d4dd1, 0x5cf3afda, 0x36a2c753, 0xa2b39387 }, + { 0xc9681d87, 0xf2606e31, 0x1cad2ccb, 0x4c46cc46, 0xbc055d18, 0x76477020, 0xf36b1469, 0x222bd6a8 } + }, { + { 0xf01f1457, 0xf38b5224, 0x938e42d0, 0x5f4b2a89, 0x97f7b8e2, 0x6af0624a, 0xdc87e23b, 0x78351bcc }, + { 0x42d5a5c9, 0x63244e3b, 0x27cabb02, 0x68dcecd9, 0xb6b45aae, 0xb9e29eff, 0x783d06b0, 0x5f00cd05 }, + { 0x8822ba95, 0xb1c77282, 0xa7528cbf, 0x5b642abe, 0x11a09888, 0xe3bf0072, 0x6f195fc5, 0x1c5a644a }, + { 0xdad7cadb, 0x236ab60e, 0xb12b2346, 0x5ef033c9, 0xed8442c2, 0x0caa95cf, 0x1de955f2, 0x746e58f8 }, + { 0x5b80c6a6, 0xdf45e092, 0x000098e8, 0x567a2745, 0x637947a9, 0xaa28306c, 0x17414875, 0x7a116532 }, + { 0xa82a0347, 0x26da21cd, 0xe887b642, 0x03a2d7cc, 0x7b89910b, 0xb41a2258, 0x749c621f, 0x8f9580a5 }, + { 0x0dbbd2d7, 0xd4d781b2, 0xe3e8cd9a, 0xf38d6295, 0xf19f54cf, 0x43f2a094, 0x07baf4df, 0x20ba116f } + }, { + { 0x58e6a0ac, 0x5dc19add, 0x888009e9, 0x1dd6e61a, 0x56712abd, 0xdff594cc, 0xf87aeb88, 0x53a8fa9f }, + { 0x289deff2, 0x9ccaf9f0, 0xee65aa45, 0x45d0d0ca, 0x2c200e70, 0x76b2e8a5, 0x00a36a1c, 0x85e09bd0 }, + { 0xb144adcf, 0xb57dc77d, 0x997bbd40, 0x29fa695a, 0xa9bd6eb5, 0x197994fb, 0x545a1fb1, 0x6acbdf57 }, + { 0x0b14bff6, 0xe3fde283, 0x421a86b3, 0x84a2ed64, 0x4903f0cd, 0x4882a5b0, 0x99dc11a5, 0x7cd4ba5d }, + { 0x5384a828, 0x7f092d00, 0xcbf8bb8f, 0x875822bc, 0x78bb00d4, 0x3684b2f3, 0x639cc3bd, 0x8c66e4ba }, + { 0x6c1cdd98, 0x1822b0c9, 0x325de314, 0xc9943d1b, 0x7f44eb80, 0x51f99a28, 0x799bad7b, 0x2c775463 }, + { 0x9b9db476, 0x38529ecc, 0xe2b08177, 0xe87f3a4b, 0x434f17d6, 0xd60a939d, 0x987d398c, 0xf09c407c } + }, { + { 0x85a57b94, 0x96e34ac3, 0x7c1fcb0e, 0xcec52171, 0x6851d813, 0x24406843, 0xe4e27111, 0x68e8ed5c }, + { 0xe9d17c83, 0xb192f6fd, 0x222db69c, 0x1e76270f, 0xc0481209, 0x302b015d, 0x09c03864, 0xef48b70e }, + { 0x2e9c8690, 0xdbbd87ca, 0xb0bf73f3, 0xe68b1bd3, 0xf91e354c, 0xd21a5bda, 0x6d40f59d, 0x2f709c0e }, + { 0xa9e83d82, 0xcccc43c1, 0xbb82d5a7, 0x5e0d485e, 0x351b6e06, 0xa1b01407, 0x1d0db76f, 0x73b99761 }, + { 0x4aac3b84, 0x29a2d54f, 0x4da423f6, 0x9d89d842, 0x3e999040, 0x2e7c2611, 0xfe378ca4, 0x442800a5 }, + { 0x260d5c19, 0x76eb2a52, 0x4a5b47ff, 0xf7e6fabb, 0xd2d7860f, 0xe6abe0ea, 0xafcdd3d6, 0x681ea9a9 }, + { 0x68720507, 0x2a37b22c, 0xff8984a3, 0xf7e0d12e, 0x4df3f317, 0x7040e3cb, 0xfacd634d, 0x796c96a2 } + }, { + { 0x5352f0a5, 0x55ad43e3, 0x06bf6b14, 0x99b934a9, 0x3a6cbadf, 0x1cc14e10, 0x59350db9, 0x146f6718 }, + { 0x9da0de05, 0x1d33e78b, 0x8e1d427a, 0x30c4bd07, 0xf26567cc, 0xbf5547f5, 0x9dcc1f2c, 0x920485a1 }, + { 0xd38119ca, 0xe9db0638, 0x6ddd7130, 0x5e3f5363, 0xf7d34a3a, 0x63f0143c, 0x3a76f6ea, 0xfac3efc0 }, + { 0x877d6bbf, 0xf15c6e46, 0x412c55cb, 0xd24f3b80, 0x6f6d20a2, 0x55428f45, 0xeb4ff919, 0x38049698 }, + { 0x482afc56, 0x67146e20, 0xdf564d52, 0xee6b3feb, 0x944c2574, 0x40708097, 0x0219eafd, 0x4fdcd685 }, + { 0x2b8fea18, 0xb6299087, 0x9558121f, 0x8bdf9ac2, 0x2b5f47d8, 0x5facf5c2, 0x67fa9cd1, 0x0eb09dd7 }, + { 0x61cd8815, 0x09b4cb25, 0x404633df, 0xc5d34a09, 0xf1ead406, 0x9b7808dd, 0x6e442c61, 0xf87fe2c0 } + }, { + { 0x9ba10f2d, 0xddba6810, 0xc6e336c0, 0xcc0e40fb, 0x4a3bf613, 0xeabe6581, 0xadfac597, 0x0ef51d0d }, + { 0x136a13b1, 0x7cf08dab, 0x35cc34b4, 0x882e8b95, 0x12866965, 0x91042194, 0xcff4fb1f, 0xd9e7137c }, + { 0xf2103c58, 0x91dde4d5, 0x20c6244b, 0x2b2c026e, 0xd668b18a, 0x68e4f0cf, 0xe9937ae0, 0x54bd314c }, + { 0x10095a94, 0xee6ac09f, 0xd4869250, 0x59df6838, 0xef6b63aa, 0xca0e62f9, 0xffc6516f, 0x3e001f77 }, + { 0x6d5ae56e, 0x9ce44f0a, 0x7f224c8b, 0xdc153a44, 0xf2000c2d, 0x4ebe91d6, 0x4053387f, 0x3296f38e }, + { 0x55e286e4, 0xa2320b46, 0x4c196112, 0x43f1de21, 0x6c7429be, 0x007408ba, 0x5773d9dd, 0x91e9cc9e }, + { 0x3b06341c, 0xead96907, 0x30eedea2, 0xd69c6d23, 0x302f6f92, 0x052a5e79, 0x183fc11e, 0xb24a1d78 } + }, { + { 0xda957c47, 0x5dcbbff8, 0xc7994c1d, 0xef6aa305, 0xcc8adc07, 0x2055ef7b, 0xcfab4417, 0xab2a094c }, + { 0x86d1cd26, 0x834de2b5, 0xa7e5c491, 0x611e130b, 0xe8b6197b, 0x73c03065, 0x53b2b4a3, 0x2cfff0d2 }, + { 0x8a0f2ef0, 0x1d8a0aab, 0xc09c0529, 0xf16f58d6, 0x8255bb71, 0xcba02e81, 0x50da60d3, 0x4020039a }, + { 0x2918bfbf, 0xb4974ba9, 0x0b671f29, 0xaf45f2ce, 0xf95e9145, 0xcaf7bc2e, 0x6315709e, 0x7d433a11 }, + { 0xb607f4dc, 0x2d28a67f, 0xe054622d, 0xfd7ad1e8, 0x6fff4cc5, 0xb817dfe3, 0x7f610798, 0xc2a04709 }, + { 0xd6709af6, 0xafc3d127, 0x13c73760, 0x87ba5160, 0xfb2f15ed, 0x16845096, 0x082587a9, 0xd8163ac4 }, + { 0x7760ac0d, 0xff325b36, 0x06187a59, 0xe30aed0c, 0x6ad23dc7, 0xed972adf, 0xb43917a6, 0x75e08234 } + }, { + { 0x47425229, 0xb152561c, 0x424c8f3e, 0xbebff689, 0x5aa3745e, 0xc887858a, 0x0a80522d, 0xb07417a2 }, + { 0x964a13ec, 0x7a38907b, 0x982b2e8a, 0x556372c2, 0xa6535de2, 0x9183958d, 0x41393d50, 0x3ae0ff85 }, + { 0xb7751cba, 0xe3158d80, 0xce83731b, 0x08fea730, 0xec4329a7, 0xc56417c1, 0x7814056f, 0x24a5b025 }, + { 0x92ccdf79, 0x57948abd, 0x6da546bb, 0x97387365, 0x6372286f, 0xab4ec166, 0xf41327d8, 0x99145807 }, + { 0x90477a42, 0x2fb03ec6, 0xae58212e, 0x7f2fbfec, 0x4551b819, 0x2a31a33d, 0xd4a2b6d2, 0x885f3a45 }, + { 0xe691d16b, 0xff1d8f20, 0xb5c52fe2, 0xd7d8d5aa, 0x0a4e63e8, 0x5055221d, 0xc1667dc8, 0x7507670e }, + { 0xc8c64690, 0xf96e7838, 0x7e2c9296, 0xab5d22df, 0x3e46e338, 0xfaf7e6d0, 0x9d002e41, 0xfcd23f54 } + }, { + { 0xf35d4936, 0x665f0735, 0x1bcd71c3, 0x5a6e41bf, 0x12b48199, 0xed9b7113, 0x261ea2a7, 0xf4b6742e }, + { 0x0f8e6f12, 0x9304c346, 0x5a93e4c1, 0x07e2093b, 0xbcf80811, 0x3fec2744, 0xd2676f19, 0x04eab869 }, + { 0x7c00eb7a, 0xdd7dec8b, 0x985bf83f, 0xc0de6b34, 0x30ff77c1, 0x998ac2ae, 0x8df4d5f7, 0xd1d47538 }, + { 0x274b0adf, 0xb5cd2f9f, 0xaa995e75, 0x70c443d3, 0xd0fe6e3c, 0x5db8f6c8, 0xa36e9826, 0x29d198c4 }, + { 0x36594cd4, 0x63117bef, 0x9bc7ab17, 0x99a59efa, 0xb4563e58, 0x1d83ae87, 0x62adcb06, 0x685d0aaa }, + { 0xe4f93710, 0x95348ee4, 0x5027940c, 0x96b83cbf, 0x801fa811, 0x46032811, 0x7249910e, 0x0878692c }, + { 0x14bf9817, 0xd127a27c, 0xf2975482, 0xeda61089, 0x3f017d6b, 0x415fe209, 0x44e4b5d4, 0x108dd3ba } + }, { + { 0x9ca4a419, 0xbd205087, 0x67e09af4, 0x413207b2, 0xb12fa7ab, 0x993be0b7, 0xf311f156, 0x56c54bd5 }, + { 0x5e86639d, 0xa3e6476a, 0x3fcc442e, 0x0dcf9138, 0x57b35b7f, 0x11185891, 0x8f835e60, 0x79b6bcb1 }, + { 0x26262fdc, 0xb1a499db, 0xa2bfe1e3, 0x552e6f66, 0x7939bd03, 0xc3eb7083, 0x66ea8877, 0x22151649 }, + { 0xc7f00291, 0x9801f66e, 0xa90c690c, 0x2f8e37c8, 0xe12b4fb6, 0xc94fe0c1, 0x3b1eb773, 0x41323147 }, + { 0x9afc5c6c, 0xb82cea10, 0xbd95f5bf, 0x4616565c, 0xc306b422, 0xbc312687, 0x10df3428, 0x91f6fda4 }, + { 0xdf566054, 0xd69362d4, 0x74bc3bad, 0x0c48ac9a, 0x6ebd7fb6, 0xd57b706d, 0x38520c15, 0xbf2dd2a7 }, + { 0x430fc0a0, 0xbf37d40b, 0x0af82928, 0x33df1e63, 0xec5fc8f5, 0x9ed64256, 0xee78a46a, 0xf6ffe8fb } + }, { + { 0x2aeb1de6, 0x443aceb9, 0x97a4ba87, 0x7fdb5be8, 0xfda17dba, 0x43bfdc7b, 0xc7435808, 0xf56491a9 }, + { 0x81961723, 0xd9b859a9, 0x94a90e21, 0xe1941143, 0xf4c3f277, 0x83e8cb49, 0xeb919a5d, 0xc7344af0 }, + { 0xb9183a6f, 0x91c76f0b, 0x2bab1eff, 0x7bbb4384, 0x1ee2e225, 0xe5324e3f, 0x49e0f743, 0x699dcfca }, + { 0xa72d9c94, 0xb82fe67b, 0x5260f168, 0xd7d549cb, 0xf5f4297d, 0x19c5e734, 0x13cb084b, 0xd92902ca }, + { 0x0abc9207, 0xb9aa8e11, 0x98267f2e, 0x047679cf, 0xc1629efb, 0x112546e4, 0xa6962729, 0x204d1b1d }, + { 0xdfccb5b1, 0xb0d3511e, 0x97f071c5, 0xff3ffc4e, 0x78aac259, 0xa62c0afd, 0x7e85609d, 0xc8f54f39 }, + { 0xa1118851, 0x0efdd2d0, 0x05e6797d, 0x3516c425, 0xe10e036b, 0x8c0bbce9, 0x6cc72e90, 0x72fcd49c } + }, { + { 0x471c0c97, 0xd2e41f86, 0xea6d86ad, 0x68f2fb9a, 0x76bcd3d0, 0x0990222e, 0xaf654d4c, 0x592f2c03 }, + { 0x7bd3a2d4, 0x79376fe0, 0x6cfd5f8c, 0x35f9db39, 0x3c49abb5, 0x822f0d7d, 0xb4b39340, 0x6ac0faaa }, + { 0x1e9744ab, 0x054e047c, 0xb6a7b851, 0x2ee0cd9d, 0x78d17a51, 0x4cd4430f, 0x237fd847, 0x849fcbe5 }, + { 0xb0c891ca, 0x6c8d5bfb, 0x3b0a93ed, 0xc7af0a71, 0xff2465f3, 0xef2a126c, 0x5ee2020c, 0x3b173750 }, + { 0x0dbac1e9, 0x450b4dac, 0xe08aeed9, 0x38991ff5, 0x6a552d43, 0x54b62def, 0x7c02b4e6, 0x29f22f0f }, + { 0x015b4120, 0x3bc1586a, 0x5691b289, 0x67477921, 0xd653ee32, 0x772b4273, 0xec197c81, 0x3e129524 }, + { 0xc5c00da5, 0x0df9326c, 0x433929c3, 0x6f5890a2, 0x7290f5a8, 0xd81844a2, 0xf27efcfd, 0x126566c6 } + }, { + { 0x2cbcb9ea, 0x8b5f07ea, 0xbe48fbe5, 0x0f7db757, 0xb222db10, 0xdba776d4, 0x18a96d40, 0x971f3692 }, + { 0xed073116, 0x7357cabf, 0x067b5d3e, 0xfe3cb788, 0x58aa92ae, 0x5b798361, 0x32097de0, 0xd06717c5 }, + { 0x92ee08ed, 0x18760464, 0x754f8f42, 0xda1dd7ff, 0x19342cb1, 0x5eb6b2a5, 0x81b07d3c, 0xaea3de22 }, + { 0x3571beb9, 0x2276e664, 0xacc949bd, 0xce5ca268, 0xc56df87b, 0x82bf433f, 0x669be89b, 0x4fa11773 }, + { 0x1873eacd, 0xb73a9a5b, 0x592c8e91, 0x2654636e, 0xbc6d1a47, 0x7afdcb9d, 0xea020c0e, 0x1efec521 }, + { 0xcef4c7bd, 0x67df729d, 0x0addb2f3, 0xa3c0ec1a, 0xc97dbc57, 0x40b6eb21, 0x47507cf5, 0x1018a2bf }, + { 0x9a4e2559, 0x7bbdf790, 0xe67e693c, 0xd9dece5d, 0xcbf89212, 0x05182c20, 0x44d35392, 0x0831858d } + }, { + { 0x92bf7ad8, 0xac7d3871, 0x79f9506f, 0x5a520b2d, 0x6d684da3, 0x751eaf8c, 0x1f3e81b0, 0x6049f480 }, + { 0x1c05bc11, 0xc9773c3b, 0x5985a938, 0x8ff45a03, 0x6818d96f, 0xf9ca15b7, 0x1a2cac49, 0x6f48e280 }, + { 0x738b797a, 0x573546d5, 0x9ea830f5, 0x3d4a8258, 0x08c9d14e, 0x588b5783, 0xf0aa4a89, 0x206efda7 }, + { 0x9055cb57, 0xdeca9dc8, 0xb851d1c3, 0x973a947f, 0x2b95673d, 0x8ef5fc5a, 0x65a6210e, 0x46fceb43 }, + { 0x03c863a4, 0x49050543, 0x9f6b31b9, 0xa18686e8, 0xe892f2da, 0x4fe3a2e5, 0x2d42a25a, 0xb05e7117 }, + { 0x49bfd4dc, 0xb9e76ab8, 0x2ccaf142, 0xf6e658ed, 0xd8da5bc3, 0x43c590cc, 0x23ee8dc6, 0x847deefa }, + { 0xaf873d1d, 0xeec773e6, 0x367aa3ff, 0x631c11b8, 0x1f0c4164, 0xb1ea88ef, 0x22667a9c, 0x4f3058af } + }, { + { 0x962f57ea, 0x81e5fc32, 0x0081c8c4, 0xadc7fee7, 0xba552a5f, 0x0474668e, 0x15a30945, 0xe96d0d57 }, + { 0x42ba07b4, 0x01b6ba42, 0xe9ce2618, 0x8974c5ae, 0x703f4b0b, 0xfae91532, 0xc0d2f5d4, 0x5b2597ef }, + { 0xadce03e1, 0xfaf36703, 0x382ab5c1, 0xf1840c65, 0x28f76134, 0xc6a72567, 0xbad3e27a, 0x35b24ed7 }, + { 0x5ff63ee3, 0xdbf4abd6, 0x340396a7, 0x8da6e184, 0x84f18556, 0x83d2ef1f, 0xd6318694, 0x01e66e20 }, + { 0x657c0e18, 0xe8e96d61, 0xfb5ae696, 0x31e9dcfa, 0xb3551eea, 0x4ed0254d, 0xd5a176e5, 0x21f6af2f }, + { 0x55d573ce, 0x10605518, 0xde2ec80e, 0x98aba416, 0x37642d6e, 0x71cd5677, 0x71d8a8c8, 0x9e026d46 }, + { 0xe78e54d1, 0xd5f17dee, 0xe021ef02, 0x1b40b24a, 0x2f11ba75, 0x335fa32b, 0x2e8fd8f4, 0x237f8ba0 } + }, { + { 0xed0d1650, 0xea2bae2a, 0x634c7bea, 0x6a3f1453, 0x7a9b247e, 0xf9bdd947, 0x0fcba804, 0x9b0d0cd6 }, + { 0x9b71b442, 0xb740ef03, 0xcaa45dd8, 0x333b16d5, 0x6940cee0, 0x0a2efb3e, 0xa1ebb1a7, 0x465f93cd }, + { 0x0253e6b5, 0xca44e155, 0xf89d1f3f, 0x1bf46b6d, 0x8266ad12, 0xa45e0b16, 0xb9488761, 0x8ba01181 }, + { 0xdc95381d, 0xd26cc252, 0x0a2b707f, 0xc0e0cb57, 0x9ee4eeae, 0x0a9df423, 0x400b1fee, 0x650a95e9 }, + { 0x61cb3f98, 0x08ee7eed, 0x71cd9edf, 0x5d924366, 0xed6915c5, 0xf6ed6c49, 0xd18c26b8, 0xae28feec }, + { 0xdd899b79, 0x9eee5680, 0xc1183ea5, 0x9646b52a, 0x8c11f519, 0x3decaa47, 0x6071c964, 0xc27ded8f }, + { 0xe4a5b241, 0x851bca37, 0xc6aa5428, 0x79831ce3, 0xd22215cd, 0x38d58f7a, 0x08df4817, 0x85fe05b3 } + }, { + { 0x11f97d16, 0xb9d32fd7, 0xf4c7861e, 0x39b3be77, 0x3d9195dc, 0xcdca9c19, 0x6949650f, 0x3f39d9fc }, + { 0xaffd5f80, 0x9ea527f9, 0x059e0467, 0xe8e176f1, 0xccccff47, 0xcb3045f7, 0x45dd9987, 0x92b3eef5 }, + { 0x56d610d4, 0x25a5e55b, 0x7dd274f1, 0x5206ac55, 0xa896fa4b, 0xeb1ce606, 0x6b62ca4f, 0x50e0f6c9 }, + { 0x22d55988, 0xaf4dac6a, 0x39fbf645, 0x68edce96, 0xd85ad56c, 0xcae1ba73, 0x01860e94, 0x678203f3 }, + { 0x4dea4902, 0x3f8c687d, 0x93c3baec, 0x387b7671, 0xd5cb1818, 0xaa45d1e6, 0x5a652f0f, 0x851a2d41 }, + { 0xce2e1a8d, 0x40213d61, 0xe1cb5c2e, 0xee2dfdb7, 0x1b4aa378, 0xc0daf98b, 0x797c4053, 0xbef4a202 }, + { 0xfcc877be, 0x02e4b377, 0xf2cf8150, 0xe72206d5, 0x9717a04e, 0xbc7369f3, 0x37d99625, 0xbbb3af4d } + }, { + { 0x7b817df7, 0x8540e578, 0x37a88677, 0x9ac5c9a9, 0x9a2cea74, 0x1077a7d5, 0xf74d5738, 0xcd49e631 }, + { 0xc887a1d4, 0xebcfc759, 0x840c3b94, 0x9d7c5067, 0xbc8d4139, 0x165dbe1d, 0xb20727aa, 0x048b6d62 }, + { 0x48291e94, 0x8af5b98e, 0x6b7a9afd, 0x45e28fd8, 0xed98dbea, 0x67aa3b1d, 0xea306382, 0x9cef4397 }, + { 0xe2577d82, 0x3e4a6a53, 0x122fb3cf, 0x34cdd88f, 0x07fac0c8, 0x688702bc, 0x6715187c, 0x870471ed }, + { 0x8f5993ac, 0x22d7aad0, 0x58de6d25, 0x76fc4098, 0x18d9d372, 0x945b97e8, 0x3e3140a9, 0x5034761e }, + { 0xd8a83ad4, 0x3f81fe2c, 0x6e2ee5c0, 0x6f18c51b, 0xdec7eb75, 0x433a442d, 0x2e97537c, 0x5c97338e }, + { 0xa3401399, 0x4099382d, 0xa315b75c, 0xa1af232a, 0xc06804b4, 0xa5a1ecf5, 0xb7502e4c, 0x4af05d96 } + }, { + { 0xa4292161, 0x64de8a51, 0x8b32577a, 0xb69defe7, 0xb3f258fb, 0x3b507f07, 0x3d34d323, 0xb72be5a9 }, + { 0x7d2b9c9c, 0x07b0618a, 0x92b9a7b4, 0xb8073cca, 0x622df393, 0x04ca0a0d, 0x5cb29f45, 0x65a800c4 }, + { 0xafd63ad4, 0xf3b45556, 0x3e5f9f0c, 0x596d7f10, 0x1e445890, 0xdc732db8, 0xa1457516, 0x2c11685c }, + { 0x106d1adb, 0xbfd505ac, 0xd17d09c8, 0xcff3de70, 0x5ed21587, 0x26601bc7, 0x266c8357, 0x38e427c2 }, + { 0xab583ac8, 0x18e6a293, 0x2a4b1251, 0x683932d2, 0x1d191544, 0x25ee6dbe, 0x686c3985, 0xdf85767a }, + { 0x07d9277b, 0xf431323e, 0x23e27bed, 0xd57330bd, 0xd3a5a46a, 0xc40134a0, 0xb51a1916, 0x920d225f }, + { 0xff6a045f, 0x0219c728, 0xd19c51ca, 0x90d6f91e, 0x008df777, 0xdcbb0ca5, 0x351b7ccd, 0xa17de1be } + }, { + { 0x61c98b18, 0x4ff26086, 0x9f69f5de, 0xf9ad9780, 0xb3c863df, 0x16b6b073, 0xa1261d6a, 0x61ea337c }, + { 0xfa3d55c1, 0x6deb841e, 0xd18b3890, 0x6eb95aef, 0x46758d3f, 0x95c054b0, 0x169c1ea1, 0x8c9f7b67 }, + { 0xca4c006e, 0xb8f74551, 0x232cde8b, 0x45e3386c, 0xa53e5941, 0xf1a18ad1, 0x3d65cbd3, 0x71aa1845 }, + { 0x7a5a38c1, 0xc71ea8f4, 0x2eb7c43d, 0x8231f36f, 0x30d09ec6, 0x108d8080, 0xc1168829, 0x7fe7c39b }, + { 0xff16554e, 0x3ab8ca07, 0xbbe6872f, 0x569c05ae, 0x7d82e670, 0x73a3e51d, 0xb46e72e4, 0x5f4bde67 }, + { 0x6ddaa6b7, 0xddf2adba, 0x55094566, 0x12f25856, 0xbc6068b8, 0x0706c7d2, 0x18190f2c, 0x46248f58 }, + { 0x1c720640, 0x821f0744, 0xf950970f, 0x2b9d5a7d, 0xce4f69ae, 0x99594043, 0xc095e4c7, 0xfabaf4e9 } + }, { + { 0x2ca85619, 0x35b831f3, 0x359db80d, 0x1d390bc3, 0x787df3c4, 0x0083aa53, 0x4ea26f41, 0xdeafe94c }, + { 0x34d01dc5, 0x0818d2c1, 0xd62430a2, 0x17369f1f, 0x433db5dd, 0x017c1bc3, 0x4acd2660, 0x9aa96604 }, + { 0x8692005a, 0x639dc9c2, 0x6183c4c2, 0xc44f9407, 0xeacb0c33, 0x5008b57f, 0xa399ae39, 0xc4a9d096 }, + { 0xce140b42, 0xcb62b5f8, 0xc49ab307, 0x09f39be2, 0xea8b2591, 0xd9dffaf0, 0x66a9fa58, 0xac6758fc }, + { 0xddc748c5, 0xd5a8a65d, 0x0ffb9a2f, 0x4181a5b6, 0x78754b79, 0xcef03b2f, 0x65868ec7, 0x9f5b6485 }, + { 0x090377f1, 0xefe4e64d, 0x8f758f90, 0xc62973bd, 0xaa48dc9f, 0x072c9b20, 0xc13b0d8e, 0x89f4518e }, + { 0xc6406788, 0x020f2cf5, 0xa59b4d0e, 0x938a2230, 0x49f79f50, 0x90f2e0c8, 0xcfb38e27, 0x53887c8e } + }, { + { 0x0e8fedc6, 0x6f70a211, 0xde1fa17e, 0x600ab256, 0xf3f84ddd, 0xc2ec2357, 0x3f079f76, 0x3ea773ec }, + { 0xc4d854bf, 0xf2dbe1aa, 0x6a339ef7, 0xbc001595, 0xe2187ebc, 0xb6c3d803, 0xaa303fb5, 0xfc6aee1c }, + { 0x7cc4a485, 0x32966e96, 0x1c24d146, 0xb8c2fbfe, 0x1df0e50f, 0x5f25ae39, 0x17947bb1, 0xe769787e }, + { 0xa0a47d6f, 0x5ba5e912, 0x351f2987, 0xdf007baa, 0x179bdfd8, 0xe2d10433, 0xc46bf7f2, 0x8f1661cd }, + { 0x1081d07f, 0xec89c7ce, 0xff7bd73c, 0x443ca90e, 0x62ca731f, 0x8cdade11, 0x3c2f428a, 0xc8f6a3b5 }, + { 0x29e1b992, 0x36cb06cf, 0x09a6d481, 0x1a5f36ee, 0xa9be4195, 0xbc9d79ef, 0xfb5d9cc5, 0xd5f1a502 }, + { 0x4efb9d6e, 0x6cd3c3d1, 0xd7a571ad, 0x094fa1cd, 0x215f0d89, 0x7ee33093, 0x211569ce, 0xe0978f7f } + }, { + { 0xf2e250a6, 0x644dc9c8, 0x03024346, 0xb4bc6847, 0xcc69fe0e, 0x02e802b0, 0x596a3d96, 0xca7ea4f8 }, + { 0x78431789, 0x2ac18055, 0x8f33a60f, 0x7e4d6ee7, 0x5f4381de, 0xcac16f1a, 0x4b181312, 0xdd2f7c1a }, + { 0xc17902fe, 0x8bb54080, 0xb2d8be3c, 0x5d756d91, 0xf5a477f9, 0xc395f213, 0x7c041dfb, 0x46f78589 }, + { 0xf1b0a53b, 0xe10e5ff8, 0x73062e01, 0x25f6dc31, 0x54d816cb, 0x5e6f7a4c, 0xa5de14bd, 0xb8b75786 }, + { 0xdac58db9, 0x7b14d7d0, 0xd9484ccb, 0x6714640d, 0xb600f2e6, 0xcc79c746, 0x1b6cad87, 0x7dcf33d8 }, + { 0x017b8d5e, 0x70eae2d3, 0x38f82a36, 0xb5a8077b, 0x5e010181, 0x3e128a3b, 0x75064a21, 0xd94d14b8 }, + { 0x7a0b5ab0, 0xee95230f, 0xe43198ef, 0x1812e8c0, 0xa4e9aff4, 0xaddbbfb5, 0x6974ffd0, 0xdf0b3e39 } + }, { + { 0x73eb8444, 0xd1b0cbd7, 0x84e02b0f, 0xbb790db4, 0x551b5168, 0xefe3bab0, 0x560e32eb, 0x7d5331f5 }, + { 0x5ec864ed, 0x405e7816, 0x00623c17, 0x7372c617, 0x57ff0c2c, 0xaa8e0e25, 0x8ba27e38, 0x15a7b3ed }, + { 0x6b5f8a03, 0x1f8147db, 0x0c9fc9ed, 0x0142bb78, 0xa8ec0704, 0x09524387, 0xdd504764, 0x25df06c0 }, + { 0xf3454093, 0x1af74eed, 0xc710995d, 0x8d6db26b, 0x097fc18c, 0x0130721a, 0x7b01c796, 0x2024686e }, + { 0x2f5058e1, 0x9c610371, 0x82bd715b, 0x364bc316, 0x7aa700b3, 0xf83145be, 0x279dace7, 0x82e8d269 }, + { 0xf968b736, 0x16095a7a, 0x57135ac0, 0x8baf2414, 0x584014ec, 0x76700cd8, 0x1d2d52f9, 0xcbfb7a46 }, + { 0x4f476f6c, 0x7aa51699, 0x70bd6f1a, 0x2c9a4124, 0x69af47de, 0xbb6b03f8, 0xe1f829cf, 0x7ce1137c } + }, { + { 0x529cb309, 0xc8aea28e, 0xd098438a, 0x2ae46f3b, 0x9412c6e4, 0x070c8c6b, 0x86e3d599, 0x6f637d52 }, + { 0x83bc496a, 0x5fee475a, 0x3c57d57c, 0x3d73802b, 0x43487150, 0x54628ac1, 0x2b7caab8, 0xc076d88c }, + { 0x8ac9ecaa, 0xe302536d, 0x01dcab9b, 0xd402ed11, 0xd2cda0e5, 0x38d52eb3, 0x7bc46a8d, 0x20f2b18d }, + { 0x3177ead6, 0x2c3e38b1, 0xc1fedd11, 0x1d61cf39, 0xa270a03d, 0x97927029, 0x01949d10, 0xca432255 }, + { 0xa752f732, 0x4e8a93d2, 0xa550cb22, 0xb76bbf17, 0x038cef04, 0xcf7425ed, 0x6ae3268f, 0x3c6cf564 }, + { 0xe3b0ec46, 0x70d0fe76, 0x59e8d363, 0xeab1cd4b, 0x9b30c6bf, 0x848d7004, 0x45beb655, 0x2b92f24b }, + { 0xd56d857a, 0x68b415c6, 0x88aa3c8f, 0xe7974251, 0xb186344c, 0x6b4e3a32, 0x154a94fa, 0xff9956e9 } + }, { + { 0x4757c9b1, 0x525ad554, 0xca91d9ce, 0x18c6c4ef, 0x90284f11, 0xe863f01b, 0x9a6e1466, 0x933653d8 }, + { 0x82eeecd5, 0x0338835b, 0xa5e276ac, 0x07fee98f, 0xa4e36ae8, 0x9d4e0917, 0xb5515e01, 0x9cb0f560 }, + { 0xfd75e016, 0xfc2509dc, 0x43884277, 0x173b4524, 0x666341b9, 0x14986d6c, 0x9da3cf7e, 0x3ff34c72 }, + { 0x1df8ed20, 0x197d99c7, 0x80d6f0a0, 0x29e40b59, 0x0bb39c17, 0x5733d550, 0xb68f6e8b, 0x4e407471 }, + { 0x74cf47dc, 0x123386ec, 0x8832fd00, 0xa6da4f17, 0x6be7b728, 0xb8ccc057, 0xa00880d7, 0x47ae5fc6 }, + { 0x773f18a1, 0x739953a2, 0xcff6d9a8, 0x58da9a84, 0x68d99953, 0xcef069a6, 0x26a8617c, 0x762c6ae0 }, + { 0x6a1057ba, 0xa6faae33, 0xe1c7df27, 0x8d1592e7, 0xb080e22b, 0x867c0f0a, 0x50d5f05f, 0x5345865f } + }, { + { 0x979b7cbb, 0x52d0bbf0, 0x174a5d8e, 0xe95c9c90, 0x23e8dea1, 0xa1a797db, 0x34f765a4, 0xbde08c6e }, + { 0xac591286, 0x981475ad, 0x9b6c3e57, 0xca87b92e, 0xd8a63a98, 0x9ca3f9ab, 0x5701c152, 0x17caa9d0 }, + { 0x9260eb87, 0xba139238, 0xc41ff15f, 0xb6a963fe, 0xa12432e7, 0x0cd72d7b, 0x545d1f7a, 0xf06027f7 }, + { 0xd08ad069, 0xb724815f, 0xd40637a9, 0x93b37f1d, 0xf68d49fe, 0x6d27ebea, 0x3d293972, 0x988cd20e }, + { 0x9a48bf01, 0x6f004e75, 0xaf950a9f, 0x763ce18b, 0x30e5459a, 0xded520fb, 0x60854a98, 0xf92136e0 }, + { 0xabd4a523, 0x21cd10fd, 0x4984edaf, 0x7b52b56a, 0x9e878a51, 0x92cc4dfa, 0xaed4a5e0, 0x01b56dcc }, + { 0x20adbaea, 0x867dba2a, 0xff3f992f, 0xec7b3339, 0x3129e416, 0x1e956b88, 0xc8fab6b0, 0xfbff47ae } + }, { + { 0x3a65aa61, 0xd2c7a476, 0xc4e5be20, 0xbcaaf45c, 0x5c64c66a, 0x608f56f6, 0x34cdd4bc, 0xcb8226c6 }, + { 0x3626a049, 0x26bab677, 0xcfc23c44, 0xd0fa390c, 0x27ecf606, 0x65a43120, 0x57db6f38, 0x8d9b2bda }, + { 0x8b7bb63c, 0x9bb0515a, 0xc9ac3e76, 0x2b0f69f2, 0xd51117ad, 0xb239c124, 0xc62a5122, 0x2841f4fb }, + { 0x44cc9ec0, 0xd14489ef, 0xc67359c8, 0xb711a35f, 0x1d35fdb4, 0xfda767fc, 0xa568fa7f, 0xde40be22 }, + { 0x121c113a, 0x5de996ca, 0x74125b5f, 0x2f14fbf5, 0x748a2f09, 0x4168c096, 0x0a174256, 0xbed59fcb }, + { 0xd92c10a4, 0xb7ba89b8, 0x15266226, 0x9df26909, 0x5a7db5fd, 0xf9283633, 0x4b3b1a2b, 0x761c86d2 }, + { 0xfc576cf6, 0xf4bc912a, 0x48efe0f9, 0x79700f51, 0x2a67c504, 0xb317b87c, 0x8a78a015, 0x5b19bd6a } + }, { + { 0x9ce6fd52, 0xae988a65, 0xd239a70a, 0xd004bee0, 0x4ea5ffe9, 0xad1ecc35, 0xa2185261, 0xb4d0fde1 }, + { 0x89dab155, 0x4d4133d0, 0x4f5c5737, 0xb383d021, 0x52b3bbc4, 0x6a98fe0d, 0x2e9fd34d, 0x89405235 }, + { 0x795dae31, 0xb7bd5e23, 0xcbe89d94, 0xa3a740d7, 0xd4016020, 0xb3d74d8c, 0x0af08d29, 0xf6c5b76d }, + { 0x64113dfb, 0xad4ce42a, 0x504c363f, 0x811530d1, 0x739d6cfb, 0x10433b5e, 0x6786fd93, 0xb2af4a85 }, + { 0x58516d01, 0xba449a0c, 0xaf379ec5, 0xc0d26a3e, 0x08a58d86, 0xb11a0670, 0xe6c2cc1e, 0x022a6c16 }, + { 0x903fe291, 0xef96473d, 0xeed4251e, 0xb47da874, 0xc0164aca, 0x0df05201, 0xe8ccc6d6, 0x3dbdd5ba }, + { 0x7daf34e8, 0xa81a914c, 0x87ccc1ae, 0x7d69446d, 0x7b26ca90, 0xbfc7fdf9, 0x9b79c4e8, 0xcd690626 } + }, { + { 0xbca2ce97, 0x9b768b00, 0x9e16c4a2, 0xbe369915, 0x33623ac2, 0x87d332dc, 0xf4cbf437, 0xc696b087 }, + { 0xb8b56e67, 0x60e96d84, 0xd737e72b, 0x617b72f8, 0xde1bbd44, 0x215077f0, 0x660d9b1e, 0xe1d46f38 }, + { 0x13ecfb64, 0x89381f89, 0xef8bf735, 0x3c1974b3, 0x59cbf321, 0x1274909c, 0x4d30a822, 0x5a284c16 }, + { 0x773c79fe, 0x345c0f6a, 0x1d7025ad, 0x09b49300, 0x9a4c9d84, 0x7998e71d, 0xfc4fcaa4, 0x14ab640e }, + { 0xa6582ab7, 0x924ce8b9, 0x15d99e33, 0xf1670d4b, 0xde7a8209, 0x3c63c030, 0x9597ec1e, 0x9381e27c }, + { 0xe0485717, 0x102c7659, 0xc5056bf6, 0x70f64f6a, 0xa57c9793, 0x59aa7c61, 0x7eb3322e, 0xab2c367e }, + { 0x39147b0d, 0x047d17af, 0xbb554ea8, 0x18259d17, 0x413a232b, 0xda2d6aa3, 0xbb280068, 0xf431d932 } + }, { + { 0xa5e23d43, 0x5433f6ec, 0xa243e230, 0x202a9049, 0xeca5c2b7, 0x5f3a244f, 0x54f555b7, 0x5abf558e }, + { 0x726d36d7, 0xbaa745ff, 0xc0995cbc, 0xe155fd2f, 0x908477b0, 0x3bfdafc3, 0x627e2400, 0x9b54d5ae }, + { 0x54943314, 0x6cd13b0c, 0xf7017cb0, 0xf354f7f6, 0x913a712f, 0x32396464, 0x7f5c8b77, 0xda9aa1a6 }, + { 0x57b1488e, 0xfd85c443, 0x6c760ad5, 0xec30418d, 0xdb2df81f, 0x4fe380b9, 0xfef3c46e, 0x546ed177 }, + { 0xec5bf376, 0x3c6ead59, 0x06df80e6, 0x9b4b63b2, 0xea891560, 0x96d61ec4, 0xec69c54d, 0x2a7094e3 }, + { 0xa5034915, 0xfddde2e7, 0xc2a96fe0, 0x7e514b5e, 0xcc097a6e, 0x8f87beb4, 0x2d2098da, 0x492e1023 }, + { 0x1f64f72e, 0x29a4940f, 0x28bb3d9b, 0x176986dd, 0xccf75334, 0xdb8baaec, 0xc2eac5cc, 0xdc1a63c1 } + }, { + { 0x8f2794ef, 0x67575956, 0x1df0226b, 0x1ac6f8d8, 0x9b783a25, 0x9afe2930, 0x3b57d6ba, 0x426e6e12 }, + { 0x9b586e94, 0x1fc66975, 0x3d745205, 0xac997cdf, 0x2b694840, 0xd61b8df9, 0xfe0d78f5, 0x138d90b5 }, + { 0x90c898ff, 0x5e593efc, 0x436815fb, 0x32a7b5dc, 0xdb5b7d3d, 0x86f4e320, 0x4e0a555c, 0xe8c07c34 }, + { 0x8238df97, 0x980ca2c9, 0x0c856467, 0xaf327325, 0x485f8c16, 0xdc401567, 0xf863daf6, 0xd760430f }, + { 0x6279f57f, 0xbdf707af, 0x166d212c, 0xb92b9bb4, 0x8c74bd79, 0x22154973, 0xc470ce5c, 0xad8317d1 }, + { 0x7740154c, 0x194543f0, 0x59f7335a, 0x98410013, 0x52012f57, 0x1716897b, 0xf74d6dc4, 0x920c3d1a }, + { 0xd141f302, 0xbc892c49, 0x05d1784d, 0x45eb8135, 0xa3e3f86a, 0x5a48f596, 0xcf7fa50d, 0xfd9d90e8 } + }, { + { 0x83a24eeb, 0x8a47b928, 0x3ba8e0a0, 0x9fdba245, 0xd8599e21, 0x907c9c19, 0x396bc65c, 0x1d1e0efe }, + { 0x37555f5d, 0x52d01015, 0xc65384f4, 0xa57da19f, 0xd5306533, 0xd7b40e56, 0x72ad0f47, 0x7c463cec }, + { 0x6f4e44e9, 0x310385e9, 0x17bd47d1, 0x3e06f1e2, 0xa3c53f42, 0xe8c5ffce, 0xc0915716, 0xe703ea48 }, + { 0xc8e9d3e8, 0x1792eb84, 0xf8738a9d, 0x5083d677, 0xa87b30ee, 0x65206897, 0x96c4ba90, 0xf7367023 }, + { 0x062845ea, 0x182a3f5f, 0x4700f73a, 0x1aee7fb8, 0x4186ab9b, 0x942b1004, 0xfe7e50e5, 0x49009e1f }, + { 0xfc0edb54, 0xb83b9629, 0x065a4e14, 0x8404f2e0, 0xfe17335c, 0xe3be3e9e, 0x99b97830, 0xa65573bb }, + { 0x01c71188, 0xeb92c6e8, 0x92080971, 0xa067cbc8, 0x11515ae3, 0xf27a2a4b, 0x0e596ec5, 0x74f3a154 } + }, { + { 0x023dc0d3, 0x6c525ee7, 0x2366e438, 0x6288d6e8, 0xb6db7004, 0x86c55b06, 0x87be2921, 0xa020e924 }, + { 0x1b75b092, 0x801cce95, 0x6239b657, 0xfbe5ca56, 0xd2170dd4, 0x1044cc30, 0xae853426, 0x15cd4efe }, + { 0xdac66376, 0xda15eda2, 0x0006896f, 0x676dcd6f, 0xc5da044e, 0xa06ba4f9, 0xc386d189, 0x9bf6cb3d }, + { 0x74baef5c, 0x00483f33, 0xa0af1221, 0x023ad520, 0x926f98ce, 0x86ccc136, 0x97594487, 0xe16d04a0 }, + { 0xc5e45462, 0xafa2ed28, 0x62dc0741, 0xf6674ab3, 0x284d77ba, 0x63df1d80, 0x0cf56abe, 0x09c095b0 }, + { 0x1365da70, 0x47e9a1bb, 0x75416e08, 0x6cdba8c8, 0x57d96832, 0xd8dc4e82, 0xc8cba9b3, 0x9807f9f0 }, + { 0x57b922c9, 0x5ba15559, 0x8ca5ead3, 0x048d1837, 0x661f403d, 0xc3838fff, 0xa6b13fdf, 0x30a36976 } + }, { + { 0x6f343137, 0xc71f6cb6, 0x199ef59c, 0xa712741d, 0x9524f6d7, 0x8d1555e6, 0x8c9f53ff, 0x276d1f2f }, + { 0xa7f1e394, 0x5e521804, 0x563610c7, 0x7c024762, 0x41a42037, 0xaacc31a9, 0xd4649e65, 0x956ae82f }, + { 0xde2b0553, 0xd301a8b2, 0x8910a586, 0x07b70f75, 0x9ea074d8, 0x2ac99ebf, 0x3500a973, 0x70061496 }, + { 0xbdf31fe7, 0x1dfc3c82, 0x38ff32b8, 0xa7b9cc7b, 0xa04abd8e, 0xf3adb0ff, 0x9e1dd522, 0xd892d61d }, + { 0xd212402e, 0xeca19b28, 0xdc57b6fe, 0xf38a9c79, 0xb5e8cda0, 0xf6345667, 0x597a1b97, 0xc1c3a56e }, + { 0x824385d8, 0x22b0212a, 0x9899bc5a, 0x6ed1c299, 0x918d2a02, 0x9a289373, 0x13aaaf90, 0x0968ff32 }, + { 0x5a9f7e49, 0x08d06a6b, 0xffd8665d, 0xb0d5eb0e, 0xd1163dcb, 0x78c81372, 0x8f015345, 0x8e24ff90 } + }, { + { 0xd825b02a, 0xa1c1a9a6, 0x2785f074, 0x6ee72c66, 0xf7a49f4c, 0x022916fb, 0x354c0c2d, 0xc1924d55 }, + { 0x82e9ff41, 0x113e9821, 0x4cf83df8, 0x6d611dce, 0x8fd78367, 0x553e22dc, 0x5ba302b4, 0xe8f78af5 }, + { 0xefb42468, 0x3e234cbb, 0x981eecfc, 0x71bdfa61, 0xb36943d7, 0x01f43387, 0x60ff5cdc, 0x352bc3b6 }, + { 0x66274b0b, 0x92030f39, 0x2386916e, 0x4670eff3, 0xe8fc5588, 0x5bcad593, 0xa20ecf35, 0x08a876de }, + { 0xb55b797a, 0xad4fcf1a, 0x4b0e291a, 0xb96c1313, 0x9c835c7c, 0x844765d9, 0x941e5f83, 0x0e183698 }, + { 0x4afdf51e, 0xae43348f, 0xaaa25912, 0xfa6d9e00, 0x6672c7da, 0x4964c1b6, 0xf2204e3c, 0x6c658967 }, + { 0xd4cdf1cd, 0xe3bea464, 0xd8796a72, 0x2e8d783d, 0x220e00ba, 0x43fea0bd, 0x2b779464, 0x525705f0 } + }, { + { 0xaf5b8804, 0xb9a2d2fa, 0xba9e2f01, 0x4a17e91d, 0xf1f74dbd, 0xfc44f3ee, 0x9c3c3657, 0x8501c1df }, + { 0xb27ec27f, 0x542c2b7f, 0xe187c5f6, 0xed95129b, 0x9b003bfc, 0x83fcb74d, 0x1a31262f, 0x11d2ba32 }, + { 0x55eec6b2, 0x44db580d, 0x28d35e79, 0x51ffd002, 0xd22b8b40, 0x736f34fb, 0x625996ee, 0xc00a1771 }, + { 0x28e1ecaf, 0x6e85a928, 0x9a8af450, 0x66215ac7, 0x5611494c, 0xd4d3d6b9, 0x0c50091d, 0x1569724c }, + { 0x0c6ceb1e, 0xff59b251, 0x64826d6f, 0x673b32c3, 0x4f570efa, 0x91793dab, 0x924d6d11, 0xbb83d65b }, + { 0xa92cb756, 0x14277b65, 0xb50f3296, 0x205a1431, 0x0d9d90ce, 0x11cfaeb9, 0x94b3273a, 0x1cc9bae7 }, + { 0xdec67f79, 0x2f8a8c5a, 0x9d1a5120, 0xf4c99b33, 0x396ac1ba, 0x766f0d02, 0x4ec810a0, 0xfe08aca1 } + }, { + { 0x0131b134, 0x15796ccb, 0xfc2e0ea2, 0x56f02b8c, 0x83ac831f, 0xa1ddef8e, 0xe7005095, 0x337b4e53 }, + { 0x45543891, 0xaa518b81, 0x1536899a, 0xe34f23cc, 0x108fe8ac, 0x11e67a04, 0xb324c31c, 0xceba6fc5 }, + { 0x48231dcd, 0xcb30908b, 0xb87d5cfc, 0x3393a816, 0xb95bc198, 0x43a21173, 0x79b091dd, 0xc0f861d1 }, + { 0x4046e619, 0xd009e0fe, 0x71348ebc, 0x91852d76, 0xae24c807, 0xb5114a2a, 0xea3ec5a4, 0xf3526498 }, + { 0x7a56bf44, 0x9ae8d236, 0x23853b91, 0x35bf10b7, 0x8144d3fd, 0xcf5f5539, 0x6bf4df17, 0x7fb436ff }, + { 0x6e05ac83, 0x6f758fb8, 0x19a7a888, 0x31074e59, 0x85716904, 0x1806aabc, 0x0a537aed, 0x44e55275 }, + { 0x05145291, 0xf0ceb958, 0x0206e3e6, 0x5fbf32d2, 0x1af252aa, 0x098a0fbd, 0x6e6f8300, 0x4a2a29e6 } + }, { + { 0x612be6a8, 0xe9aea7ea, 0xef3ff8fd, 0xa990e3d9, 0xf8415655, 0x4eab193c, 0x578ad9a0, 0x459dd7b9 }, + { 0x9cdc742b, 0x219812ec, 0x0052acf9, 0x725dae4a, 0xf1071874, 0xe15d87dc, 0x26a5366d, 0x047861b1 }, + { 0x33944b57, 0x4972efdd, 0xd826fce6, 0x0819711c, 0xe16670f8, 0xf380fe07, 0x355f7a03, 0x9107bb25 }, + { 0xa43b8097, 0x6c74f35a, 0x2e863685, 0xbad4f784, 0x9da535e8, 0xb92adf2b, 0xb869a73a, 0xb087d580 }, + { 0x7517802e, 0xafb74a90, 0x599c6696, 0xb38d060a, 0xf373d7e6, 0x966167dd, 0xcf3253fa, 0x6f99c5fd }, + { 0x1e46b7d7, 0x7eff0e55, 0xed683a89, 0xc71c9917, 0x48b3830f, 0xf0c79c1a, 0x7a8fa8b1, 0x218955ee }, + { 0x48aae412, 0x691b9818, 0x874fcb5c, 0x995a04fa, 0xb76abb4a, 0x5c309126, 0x69a6ccb6, 0x368a1ced } + }, { + { 0x408cb62c, 0x3b70922a, 0x7f264aac, 0x5c0df94d, 0x17969dd9, 0x0d88f627, 0x7e248f32, 0x95a4a489 }, + { 0x10e7ac8b, 0xaaa31b4f, 0xf2ff5fbc, 0x5b6ac8aa, 0x24e3080f, 0x28e9d8c4, 0xb148a773, 0xfa090c9d }, + { 0x4408a0c1, 0x7b759542, 0xee0535f8, 0x03692e42, 0xe04077b9, 0x3aa9f80c, 0x216f3ffd, 0xf8667e9a }, + { 0x6091af81, 0x26b4bade, 0x50b5a448, 0xbd257d5e, 0x96b6b6fb, 0x4d06387a, 0x859dc5db, 0x2550dd24 }, + { 0xb4083f98, 0xb1712124, 0x4ffa6bbe, 0xac4fe1fa, 0xe4ea2c22, 0x3b21ea99, 0xaa4b378f, 0xef780957 }, + { 0xfea65c32, 0x2630886b, 0x516a93c3, 0xa87b2079, 0x531884c9, 0xaa72533d, 0xa003b3f4, 0x7bb17437 }, + { 0x34032994, 0x4cef72a0, 0xc5158925, 0x638a0d1d, 0x8c037715, 0xc6be1b0b, 0x0ead0c61, 0xc9459550 } + }, { + { 0xffdf8f7e, 0xf5a20dab, 0x70cb0082, 0x4ffca11b, 0x58416505, 0xfc559602, 0x29e66eae, 0xf8ae5a5e }, + { 0x41ee1d29, 0xaaa43231, 0x2776fdee, 0x0c2dff3d, 0x612b8623, 0xebf527d7, 0x3cf0fca2, 0x47c6123b }, + { 0x06a75db6, 0x8261c1be, 0x7c591d8e, 0x47fac27c, 0x6c36484d, 0x90527c8f, 0x58c65a30, 0xa5e11279 }, + { 0xfc782a50, 0x60b8899b, 0xf9dbf259, 0x0bcc0a40, 0xa229bda1, 0x168a8855, 0xb5d87956, 0x61d6bb9d }, + { 0x7378236c, 0x865619ab, 0x8ca6923f, 0xebe429b6, 0x24ba5add, 0x39e49415, 0x124814b9, 0x7c8fd18c }, + { 0x3517965f, 0xf54f73dd, 0xcfdefd0a, 0x0c98c3a1, 0x8d36dc2a, 0xcdd00d1d, 0x3937c88d, 0x64529779 }, + { 0x464d8478, 0xbc935aa2, 0x26bd0fcc, 0xf30d7b12, 0xa31a5d33, 0x708eecbc, 0x0acb787e, 0xfc79571b } + }, { + { 0x11550d4e, 0xa4d0ccaf, 0xb896078d, 0xf01f8639, 0xfea676c7, 0x7352e8f3, 0x11ace0b3, 0xc7f937e0 }, + { 0xf264b4d3, 0x4214ae8c, 0x550cf3fa, 0x2b3c82e5, 0xe24f889a, 0xc795d879, 0x5dac9a62, 0xc7044d9b }, + { 0xd2108d16, 0x3c0ffeb2, 0x2042ef98, 0x0d9c0fa6, 0x2ab92f4a, 0xb8884755, 0x4cda4dca, 0x8fb003a1 }, + { 0x6f6a7527, 0x6e321481, 0x3f346e27, 0xa70a9d2d, 0x8ee9a6f8, 0x2790b3b7, 0xb424d205, 0x91e63115 }, + { 0x959639bf, 0xf23f1feb, 0xc1994d08, 0x30976c9d, 0x80861d2d, 0xe3ac17a6, 0x75b71833, 0x65e96015 }, + { 0xbbaef34b, 0x3244b505, 0xab6b79a1, 0x809ccbe5, 0x4e2e445c, 0x7eb74fce, 0x3aa41027, 0xab1a1c5c }, + { 0x2fea4ca5, 0x406aa1bf, 0xdaaf707e, 0xc34462ac, 0x4ccb6551, 0x961fcdf8, 0x973acb5c, 0x7c6692b1 } + }, { + { 0xddbefaca, 0xc7a81f45, 0x8bcc1241, 0xb55c925a, 0x20b696c8, 0xd7913c17, 0x78f2e0a3, 0x6c261c77 }, + { 0x3cc8f994, 0x2661bd75, 0xb10a1e3b, 0x8ba28cad, 0x48657169, 0xbbeb9d3e, 0x602a84a6, 0x4c96aa25 }, + { 0x692964ce, 0x216afb2b, 0xd18a5a66, 0xcf150236, 0x64c21fca, 0x0d5eecc1, 0x9e978005, 0xd33fd368 }, + { 0xeafb4b37, 0xe21a3766, 0xf11ab1ad, 0xc6064ae0, 0x94e270e0, 0x184088aa, 0x10d4497d, 0xde991adb }, + { 0xe0685dd4, 0x6d0de3e2, 0x7935ae7c, 0x73b9ff49, 0x81f42fcf, 0xc76a9928, 0x906fd865, 0x655dcb96 }, + { 0x59e43594, 0x70854bd2, 0x6aea3da6, 0xc20978d7, 0x2d6633a0, 0xa64f39d9, 0x6ff5782f, 0x4061fa9b }, + { 0x7306b6a1, 0xdc469610, 0xd4a5ab68, 0xa44ce836, 0xffe8b99e, 0xe18dbd67, 0x4deefdf6, 0x1dbf2916 } + }, { + { 0xbcd7b9f7, 0xaecb0569, 0x65e859ab, 0xbb1deaad, 0xef21dbd1, 0x6d0bd332, 0x915707d1, 0xe70e63e5 }, + { 0x961ffcd9, 0x1c391c9b, 0x81905c90, 0x0936283d, 0xe9dc5aa6, 0xfb3b7def, 0x56454ad4, 0x5c8bb15e }, + { 0xc03e6457, 0x16f9c3d2, 0xec96ed35, 0x60faf8f3, 0xf4514e87, 0xda3f4673, 0xd5be8d5d, 0xbb12df1b }, + { 0x12f736e8, 0x2187a39e, 0xa63feafe, 0x66bfdb1d, 0x3c468d50, 0xeae0d268, 0xacc10ee9, 0xf2718cd3 }, + { 0x659b476a, 0x10a498db, 0xa084c566, 0x15ec323b, 0x8e6de570, 0x660dc72f, 0x01814c7e, 0x93c79470 }, + { 0x087812d6, 0xd0dc9e9a, 0x0381bb07, 0x971946b2, 0x88c203a6, 0xa91dfc9a, 0x5a83a3d2, 0x96b736c6 }, + { 0xd0393e6b, 0x92e03ba4, 0xa9b367b6, 0xfb67d737, 0x00e4d2e3, 0xec1d8a37, 0x80fd078d, 0x94ebbabd } + }, { + { 0x7e29e692, 0x8b41a6d4, 0xde0b857f, 0x352e05e7, 0xd74b3544, 0x89a110e7, 0xf3a27efe, 0xf24598f5 }, + { 0xc79d4566, 0x7c582951, 0x8dd6043f, 0xd561a6b9, 0xd99ddf41, 0xd1e971db, 0xc0d536d4, 0x8ea54c01 }, + { 0x39b19219, 0xaee37d55, 0x4fcf989e, 0x23baba4f, 0x49a91d6d, 0x1a35612e, 0x3e7607dd, 0x0ba6e33e }, + { 0x5a33d17b, 0xdded811c, 0x9dd4bdc5, 0x6774c7f8, 0xbd3f291b, 0xa0009061, 0x11e43fcf, 0xdd17292d }, + { 0x8acb55a3, 0x1d66e5c4, 0xbf641c0f, 0x18c07e1b, 0x76c41aa1, 0x80aefccd, 0xff8a45fb, 0xec91341d }, + { 0xe0d8ca1e, 0xe1b5c0b6, 0x42cbb935, 0x93cabccc, 0x1db92c60, 0x251e3f97, 0x18707d3c, 0x15169cdc }, + { 0xebe45526, 0x757adc21, 0xa048e0e0, 0x00be0c92, 0x07b67816, 0x2412eb5f, 0xb7227c6a, 0xaf986aa4 } + }, { + { 0x3567e5e7, 0xedba1c4c, 0xc1ee61b3, 0xf6168ff0, 0x548ac0c6, 0x5df95013, 0x70486381, 0x0f747265 }, + { 0xde2b9737, 0xbb011054, 0xf3ee8541, 0x2b3fd083, 0xfc3a47f7, 0xd634eb57, 0x66ab37f5, 0x234f914e }, + { 0x10090602, 0xf5070df0, 0xdca526b5, 0x3dc0c2a0, 0xe76c9a3e, 0x7216cef1, 0xc8e9c887, 0xf500c617 }, + { 0xd3084a95, 0xb4f44838, 0x16ccdd29, 0x9e0b70be, 0x721e544a, 0xed3e26df, 0xc3439ab4, 0x1320c54b }, + { 0xc1075933, 0xf0b15ef9, 0x4872b3c1, 0x47b9d658, 0xc162ca79, 0x5a42a927, 0xa37688e7, 0x0b6b44c7 }, + { 0x9d604460, 0x45808dad, 0x5f880d48, 0x5c1ecb45, 0x4b097d4b, 0xc95aaba1, 0xbe7af65f, 0xfa3eda1f }, + { 0xc58306b1, 0x6753afb9, 0xb4937fce, 0x8f82b06e, 0xdf8ff4d4, 0x124c3399, 0x8fac1caa, 0x6e9ab004 } + }, { + { 0x8e3a58b3, 0x9745bf71, 0x2a0ea73c, 0xad04b1bc, 0xd8338c7d, 0x0cb4b5c5, 0x8cc70a60, 0xaec8922c }, + { 0xab22f041, 0x8747644e, 0x08e1e2d9, 0x201ad2b6, 0xfccc9550, 0xb4f599b6, 0x39400a06, 0x10ec0d9d }, + { 0x93ffda08, 0xa3c65492, 0xdb32ed20, 0x5e5044da, 0xc853b537, 0x4d0962c3, 0x3e818e62, 0x6d9ef9a4 }, + { 0xdf34b2d6, 0xb52a6261, 0x2c02d7c9, 0xc80dfe97, 0xbe920358, 0xb3b54fe0, 0x928dd474, 0x9ac6c076 }, + { 0x4f79e512, 0x11776041, 0xbd99a47d, 0xdceac08d, 0xec0accf1, 0x823ef812, 0x6ead6214, 0x9e9e456d }, + { 0xf93d4427, 0x35c065c7, 0xb0568cc4, 0x89438bd0, 0x483d9e29, 0xed66d3b2, 0x4cd1f22e, 0x5ce685de }, + { 0x70afbe9b, 0xdcee3d63, 0xef23056d, 0xab95553c, 0x7241a4d7, 0xd750aa8e, 0x2db4e162, 0x32c7020e } + }, { + { 0xb6b1b931, 0x1dbeeb55, 0x57a55d88, 0x683f65b7, 0x6b74e649, 0x9b0d0ce5, 0x857acdce, 0x09dce13f }, + { 0x8471d8eb, 0x21e20325, 0x8343904b, 0x6bb37b48, 0x574673bb, 0x5bbd2cbc, 0xb8d3f709, 0x9e1ee313 }, + { 0x0e9dc340, 0x78d53ca0, 0x35e7af7a, 0xc9ee9192, 0xced09087, 0xf514ba34, 0x0bd092c0, 0x0ab8a37d }, + { 0x474466b0, 0x3f129bff, 0xc9ded430, 0x0bd038d9, 0xaeebf28f, 0x38eedcd6, 0xa283275a, 0x1b0eb1f1 }, + { 0x9e29c456, 0x09a38f37, 0x2479b134, 0x33c7b328, 0xfe878206, 0x51343036, 0xd5072add, 0xc772a79d }, + { 0xb4af6277, 0xf237e01b, 0x570a70c3, 0x96f28e25, 0xfb7a6283, 0xf2636f78, 0x42d809b9, 0x635e94a6 }, + { 0x193c6c51, 0xe4b6373c, 0xcd568c2a, 0x6daef406, 0x788b6b4c, 0x24eb8436, 0xd37b5e3a, 0xf9af2d97 } + }, { + { 0xf0e7a919, 0x682262bc, 0x8250498f, 0x328f0e3c, 0xcf0adbaa, 0x5898dd65, 0x3e9417f7, 0xf29f140e }, + { 0xa6ef5bd9, 0x8349746c, 0x4cbf85f5, 0xa7e87dc6, 0x902aea74, 0x443891df, 0xee3c434c, 0xec095e47 }, + { 0x51cc666c, 0x7c75d10d, 0xd243b46f, 0xd8de941c, 0x61ca586a, 0x00aaa203, 0xf3ec602b, 0xa9067d07 }, + { 0x1aaec03a, 0x8db8a17e, 0x40535325, 0xaca2ef8b, 0xdbbb2199, 0x4032f003, 0x94dfc342, 0xe02f2b75 }, + { 0x8c4e3f5a, 0xa3e555f5, 0xdad1c8d1, 0xa8d51378, 0x86d4e833, 0x7dd44060, 0x1b340aad, 0x3173876b }, + { 0xe183dc08, 0xa6a7af82, 0xc24ff5ba, 0x74ccea39, 0x33907bde, 0x5027c815, 0xf1ea964a, 0x6e580a0e }, + { 0x3ebfa215, 0x5154cccc, 0x3859eaf5, 0xb616c4d1, 0x2536af1c, 0x5c801c9a, 0x7125da28, 0xaba781e4 } + }, { + { 0xb0aa611b, 0xf329813e, 0x09974675, 0xefb0648c, 0x86ad19fe, 0x18bb7a31, 0xabae10e5, 0x157db901 }, + { 0x945c8d18, 0x866b5833, 0xcec48495, 0x0637bc92, 0x3d144da6, 0xd20aa2fb, 0xcd739471, 0xc679534d }, + { 0x6914a513, 0x1e3be68e, 0x801023c4, 0xa18a0432, 0xbcb8ef1d, 0x287b8c4c, 0xb5c557b4, 0x227aafd0 }, + { 0x8134290a, 0xb43672bb, 0x3219e038, 0x3b3586be, 0xd4192484, 0x057863d5, 0x5af03283, 0xfa43a7ab }, + { 0xdd1d983d, 0x00a9ee12, 0xb87294ae, 0x788f17f7, 0x5d09a7e0, 0x203f7024, 0x9eb9516e, 0x0ad3e70e }, + { 0x61c95583, 0x0157aeeb, 0x8a560ae2, 0xbcc0e328, 0xd6b15e89, 0xf1fb72ba, 0x3d7a86bd, 0xefe07ff5 }, + { 0xae8b1ad2, 0xe8b0e341, 0x75c128e7, 0x4b855983, 0x2823f704, 0x7308179c, 0x924b47b2, 0x5bc4534d } + }, { + { 0x51ef7276, 0x1b386f50, 0x640057b8, 0xfad54d72, 0x97ffbb98, 0x152cc738, 0x758e39ac, 0xa7009aef }, + { 0xf8bf8307, 0x0e37dc8c, 0xaec3f156, 0x0995c10b, 0xaea1f4c6, 0xa3669a12, 0xeff47fdd, 0x28c58bf5 }, + { 0x2d27cb3d, 0x2e315c21, 0x16fb415f, 0xc194f707, 0xb5ad8069, 0xa54beef4, 0x4cb7fc78, 0x21546e26 }, + { 0x0cab6d99, 0xdd54447e, 0x10e0f16a, 0x2bf19811, 0x05fe702f, 0x595c5bf1, 0xaa99303c, 0x63b1a01e }, + { 0xe2eab432, 0xed5f4d99, 0x2368bbc1, 0x076a4211, 0xe77a3fcb, 0xc10f8e8d, 0x22acaca9, 0xd98d2316 }, + { 0xb30f302c, 0x553f357d, 0xe50a2533, 0x611bd13d, 0x08c4f88b, 0xfa7a9454, 0x26f24bbe, 0xcf1a9c58 }, + { 0xd9d6e2f3, 0x65329309, 0x24ab8dca, 0x5666ec08, 0x5b4c9c7a, 0xdc02919a, 0x47984f20, 0x5d10c10c } + }, { + { 0x4172dfcb, 0x48c4ee08, 0xe9ed6a57, 0x28f46959, 0xc1aa0ca5, 0x589b1201, 0x60e69889, 0xfb8be6d4 }, + { 0x0ffcbd23, 0x5302612d, 0xf5c6667b, 0xddf2ff98, 0x5cfa10f4, 0x705ff345, 0xc5d3be38, 0xc594850e }, + { 0x4e02c9ea, 0x7d78f9fc, 0x62431ae9, 0x409b735e, 0xab4ea6cf, 0x044946e3, 0x51496c16, 0x6b7f7546 }, + { 0x0cc243c7, 0x77231247, 0xc5f880dd, 0x536a556d, 0x6abe6f11, 0x3b0d7ee8, 0xb1e27e25, 0xa82ecefb }, + { 0xc4de7eef, 0x42608a74, 0x961a25bf, 0xb92b4d87, 0x5df7f8fa, 0x895c6218, 0x7b7227e9, 0xe6cca312 }, + { 0x1c8998ca, 0xea030927, 0x2997ffb8, 0x479279b1, 0x9d1c52d7, 0x06558fdb, 0x1325c1b9, 0xb4cef32c }, + { 0x885f479b, 0xc3cf6268, 0x1a77920d, 0xbd734982, 0xfa230527, 0xdf1c5465, 0x5ea6fa44, 0x3d963df2 } + }, { + { 0x15124d6f, 0x5bee8048, 0x5e7eeda3, 0x75385c1e, 0x4645a6b1, 0xd173672b, 0x8dd8f848, 0x947388ea }, + { 0x28ff84bd, 0x5d22f09e, 0x3240ffc2, 0x07097e29, 0xcb467d4d, 0x3a59c380, 0x4f2b4ead, 0x06c8331e }, + { 0x2c20ca5e, 0xa382ed3f, 0x63ed7858, 0xe637b728, 0x3e4269fa, 0xe0525ff4, 0x2ef2fc4d, 0xaa7c5b01 }, + { 0x72214e0c, 0xdaeb4dc4, 0xa3716f9f, 0x8478f832, 0xbd92995a, 0x8dcc007e, 0x89a24795, 0xdeee784f }, + { 0x501f8504, 0x790f4562, 0x7f646f8b, 0x3d38fefc, 0x90ab3450, 0x1884861f, 0xba10e16a, 0xf2c30349 }, + { 0xcec4f4b4, 0x6b923857, 0x12b72f4c, 0x2c3a4615, 0xc8886df8, 0xbfa753e7, 0x12166500, 0xcb0e06b8 }, + { 0x75a0cd60, 0x509452c2, 0x5009d6e0, 0xd08342a5, 0x57b6a30d, 0xf5d729fd, 0x037eb8f2, 0x7f8b37b5 } + }, { + { 0x603c8c13, 0x138a1e54, 0x645bb6d1, 0x8edfd612, 0x6555876f, 0xbe3ded27, 0x9463b0f7, 0xc5b43a0c }, + { 0x12fa6f80, 0xf77f6d18, 0xa5c05bcb, 0x49c1838a, 0x64183c24, 0xfbe20136, 0x62684de6, 0xa73208d4 }, + { 0x2dc70f79, 0x497fa780, 0xd9c1c81e, 0x7001f268, 0x75e76073, 0xa6ca0f6d, 0xb31cc76c, 0x152f9314 }, + { 0xaf35c9cf, 0x2fa27244, 0x52515468, 0x5b81ee48, 0x8ee84d9f, 0x7874f56c, 0x399f8e67, 0x0832a2db }, + { 0x1d4d84c8, 0xdd7051fc, 0xd1acabcd, 0xac8627ba, 0xe7728ae5, 0x87d3f1ac, 0x1930599a, 0x8b40e1f6 }, + { 0x8a3e0607, 0xdc86f37d, 0xd23d06f2, 0xab6ddcf0, 0x5e59320b, 0x56f7f0e6, 0x4826df9b, 0x1147f821 }, + { 0x9a2a5095, 0x37f84839, 0x8cb8c19c, 0xc723fca5, 0xb887fbd6, 0x648752be, 0x77c89802, 0x3bdf2bd4 } + }, { + { 0xe95fe2eb, 0xa5d641ef, 0xe1d5a4cb, 0xfcb6daa2, 0x93979a0d, 0xb4bb6da9, 0x127a76e8, 0x8df8945b }, + { 0xc1ea6447, 0xcf97c564, 0xb0f80528, 0x880e15d5, 0x37af7e10, 0x1e681462, 0xfbdf3db6, 0x587956f9 }, + { 0xef96a767, 0xde2d5fb3, 0xf1234cf0, 0x83ac6d2f, 0x14accc8c, 0xfe417ada, 0xe23c40e5, 0x7c167928 }, + { 0x4c207eb1, 0x1a2dfe96, 0xb68bfd29, 0x291f61bc, 0x6de72c84, 0x11f7da6a, 0x01e1eb6d, 0xc5e3816d }, + { 0x46073f01, 0xfa43db13, 0x83f36681, 0xedd9b5f0, 0x2ea57fb9, 0x517d52e1, 0x6a2daf24, 0x839a9057 }, + { 0x0152191d, 0x4740c750, 0x6ca4c9ca, 0x0204e7ce, 0x82231e7c, 0xdf4f5a1c, 0x6ba616c6, 0x7dfa2702 }, + { 0x846580db, 0xd8d0ed19, 0x56b83e33, 0x11e3a461, 0xbab0919c, 0x9b6c6b68, 0xd8a9b891, 0x9c306d9b } + }, { + { 0x739ba36e, 0x7a618ef1, 0x71076864, 0x7ffcb45e, 0xd5691757, 0xf069a107, 0x4be359e8, 0x3eaf0c62 }, + { 0x4c0597b9, 0xdd7424fa, 0x23087c7e, 0x2227a301, 0x7ddd34c6, 0x8e4d0d68, 0x4ebc55d3, 0xd9b5e6ae }, + { 0xcfb176fe, 0xd0454851, 0x403b9da3, 0xa80736d7, 0xd253d30e, 0x6bbb21a0, 0x81e58b09, 0xce51d245 }, + { 0x2f3d0bbb, 0xdb5540db, 0x7d589168, 0x84323951, 0xf180b0f1, 0xff44bfc4, 0x8fcaa903, 0x252f8705 }, + { 0xd628ea85, 0x701207a8, 0xf31d41fa, 0xa8f09523, 0x8a299618, 0x88e1f3c7, 0xc5427df9, 0x5aa1d861 }, + { 0x30e1fc2b, 0x40f302be, 0xa63b3b01, 0x2be3ac29, 0x056645e7, 0x7acc9bbd, 0xd230ce9a, 0x7d252c2f }, + { 0xd600bd13, 0x086c07c9, 0x029cec65, 0x8d599f6c, 0x4d25e448, 0x4e9bade3, 0x0c33da84, 0xbe9e056a } + }, { + { 0xec2c110e, 0xbe7c5905, 0x3d6b6ad4, 0xbf5ef109, 0x940723c6, 0xd0bc7636, 0xe45a396a, 0x6b3d8de2 }, + { 0xb7797ba6, 0x2a61063e, 0x6b5b2af8, 0x9705e437, 0xae799118, 0x80b9e5ac, 0xa524ea11, 0xd25993d7 }, + { 0x952418a0, 0xe52ea7fb, 0x5b851a60, 0x6a3d38f5, 0x7d76b217, 0x87d90655, 0x9351da3d, 0x8fea872b }, + { 0xa284f90b, 0xfed726ec, 0xcafc31d0, 0x8752f8fc, 0x8aecc6f9, 0xd71c0300, 0xdb700ebb, 0x2d234e4e }, + { 0x1255759c, 0x437e2721, 0x384eff34, 0xb49f1b47, 0x24b7d68c, 0x5677b98b, 0xc515b120, 0xd6d9fd20 }, + { 0xae16e75b, 0x8673ec67, 0xa1200f9b, 0xea6c1b43, 0xeea2218b, 0x3cd180c3, 0x761e1363, 0x1ba1263c }, + { 0x1fbac7da, 0x75d3c884, 0xcb97f364, 0x35e26bfc, 0xc958ac3c, 0x8209fbc8, 0x53ae71e1, 0x370d7647 } + }, { + { 0x44e5978a, 0x3c1c94db, 0x5812bb5f, 0x2792ab44, 0x0d072532, 0x3b6d3cbe, 0xab461bd3, 0x9cf81039 }, + { 0xb1b260c7, 0x9fd1ff0f, 0xce0a9c02, 0xd4e51cb3, 0xbb1283d8, 0x57376e34, 0x8c71591d, 0x055e92aa }, + { 0xe6bd5fd5, 0xfcc32cb1, 0xd7981038, 0xd98280fb, 0xece72c01, 0xde205008, 0x3995ad35, 0xbac90603 }, + { 0xfc5a9baa, 0xb00eee66, 0xab77bb87, 0xf777e3b6, 0xa3cb2f72, 0x05fb033a, 0x55d2cc9c, 0xf4bdae1f }, + { 0xd86e998d, 0x84e2624a, 0x8d1ef040, 0x19723c11, 0xec28489e, 0x2eaff7d2, 0xe3590133, 0x8a88d5a9 }, + { 0x832d5f4d, 0xd9489ab0, 0xa6c2601e, 0x6142906f, 0x10fad62b, 0xf6e2ed88, 0x77e39a72, 0xabd76faa }, + { 0x889c76e3, 0x0536b496, 0xbbb356e8, 0xe4db3548, 0x5c3fd0fa, 0x5b737f0c, 0x40931679, 0x6309963f } + }, { + { 0x40ee3a4a, 0x65909d90, 0x5925ec41, 0xe417e4c2, 0x6aa21fc9, 0x225a98f8, 0x53731c19, 0x2a85fbb4 }, + { 0x675dbced, 0x74d40ed6, 0xf6bb4283, 0x6ca6edf2, 0xab30d2f2, 0x11337c7b, 0x555c0f69, 0x670be54d }, + { 0x34d48b9f, 0x0a2af5ec, 0x71dfde84, 0x9a90919a, 0xaad1d2d1, 0x9a2d9fef, 0xb5ecf242, 0x7d065fab }, + { 0xa204eb7d, 0xb8d431d9, 0x782f3120, 0xdc5c6fcc, 0x81952fe9, 0x94e0e2a8, 0xe16b4870, 0x4590fe0b }, + { 0xcee0f906, 0x2d2e89e2, 0x5e52b5f9, 0x6bbdde65, 0xb7aff920, 0xdf304d13, 0x9657d288, 0x3829da86 }, + { 0xa2112a51, 0xcdbe59af, 0xa319b39c, 0x60b0f0f8, 0xf52da966, 0x5f1426b2, 0xd99020d5, 0x76f4ddf0 }, + { 0x85d5a9a3, 0x173e2a26, 0x6877031c, 0xf03affcb, 0x7a906fcb, 0xa24c9477, 0xd2b80f61, 0x5638c07d } + }, { + { 0x0e8f35a3, 0x4b06e823, 0xd47ed3b7, 0xf5509c22, 0x334cf6ec, 0x47d90946, 0x8ed63e06, 0x38f2c469 }, + { 0x1ee1ff9f, 0x469ee972, 0xe0ad7063, 0x50189047, 0x854ba00a, 0x857c9cbc, 0xbb161a5f, 0xb59ef60a }, + { 0x2cd66ff6, 0xb26af70b, 0xd50b921d, 0x2e817dec, 0xf121337a, 0xe2505355, 0x428634c7, 0x6ae831e1 }, + { 0x2619396d, 0xc2a33b43, 0xb7a69b41, 0x33911e3e, 0xea449720, 0xbf8e9980, 0xf05cc544, 0x3aa5efec }, + { 0x102bfe77, 0x62d7b4df, 0x8404e57b, 0x1e3545b3, 0x2f8ee644, 0xf2f4207c, 0x099c8785, 0xa228d753 }, + { 0xf6616f86, 0x69fc2f9c, 0x9a1782d7, 0xdb2f5406, 0x487d8aa1, 0x6ddae044, 0x6c90fed9, 0x1d380818 }, + { 0x56e70139, 0x2e6b471d, 0x76cb34b2, 0x7e9f9e9a, 0x811e573e, 0xaaf6ae4b, 0x82ca972c, 0xf5bea0cf } + }, { + { 0xa5dd88d7, 0x8dee56e6, 0xbb58ec74, 0x089b7971, 0x7fd5e416, 0x21542b2e, 0xdc673df2, 0x4029f024 }, + { 0x3be7e0f7, 0x960c1440, 0xeb62e51b, 0xac4afc53, 0x240d6a0d, 0xd0657374, 0xb6689044, 0x5c9aae75 }, + { 0x8326ca3f, 0xe625d457, 0xf15b1126, 0xcfa38cf8, 0xc2406d10, 0x5a921204, 0x776a8a3b, 0x878e5e34 }, + { 0x6a12d797, 0x9e0dfa96, 0xfe5b2bc2, 0xed8fe49e, 0x020cab8d, 0x5c17c09c, 0x7aaf3675, 0xcb32efd2 }, + { 0xe8a325c5, 0xdea7c0b6, 0xe6dd55ef, 0xa8b99be5, 0x129cfc09, 0x6b763ca0, 0xa830552b, 0x569b464d }, + { 0xc96c9651, 0x1f19b94c, 0x660758ab, 0x9508816e, 0xa19d2eed, 0xf1ae2c78, 0x8bc5fed5, 0x00fd09d7 }, + { 0x22701aef, 0x57666716, 0x08421b2d, 0xcdcd5760, 0x543206f3, 0x6097f88e, 0x693b42f9, 0xdfc5085e } + }, { + { 0xc2664a19, 0x620331d3, 0x48889f76, 0xa44e061a, 0x282678ed, 0x36f0288b, 0x3763e871, 0x3e596769 }, + { 0x2498cad7, 0x50a838ca, 0xe791ab2d, 0x0754f6f2, 0x5cdca55d, 0xc9bafd41, 0x24afdc8d, 0x23665d35 }, + { 0x26894e5e, 0xbe4c1593, 0xb6d29b4a, 0x5fa3f8ca, 0x8d2aac65, 0xd2bc3e96, 0x00fe77fb, 0xcb198ce9 }, + { 0x7331d5e0, 0x768df63e, 0x82f1722e, 0x1b985f9c, 0xefa77f96, 0x1bb90013, 0x9e08f1ee, 0x7fca2a70 }, + { 0xed96ed08, 0xaa96fe7a, 0x5f879c42, 0x0c196850, 0xca6bddce, 0x86962640, 0xb008b923, 0x0c685470 }, + { 0xc8ec4adf, 0x6dfd64de, 0x24d3255f, 0xc3e21106, 0x25c129f9, 0xa50cc5ac, 0x4436f72d, 0xf4e12400 }, + { 0xbbbf713e, 0xfcb809b9, 0xb1c8191d, 0x412abbae, 0x2bd280f7, 0x72ac974e, 0x7ed0cf44, 0x07877eb5 } + }, { + { 0x65aafe11, 0x1fa428b7, 0x22341c0b, 0xa2b636fa, 0x0660cd16, 0x26385884, 0x18560714, 0x8a078be6 }, + { 0xf37b1f40, 0x518efb3f, 0x3cea578c, 0x0996b9fd, 0x534ed631, 0xd1d649fb, 0x2ce5334f, 0x1bfb56e4 }, + { 0x31ed147c, 0xf0045d66, 0x79601217, 0x0c961d24, 0x890b6028, 0x316d5b08, 0x0a4dd963, 0x74293c6c }, + { 0x084cb1eb, 0x9346da73, 0x213d7cdc, 0x033beadc, 0x48427ebe, 0xf45f1a1e, 0x22a46790, 0x284de933 }, + { 0x241ca2c6, 0xb8da323c, 0xaa49b8c1, 0x30fccc6a, 0x69d79b4e, 0x30bc1c59, 0x0c503411, 0xd1942fdd }, + { 0x06695ca3, 0xb25c2fab, 0x6b3ca61f, 0xf047e54e, 0x51dec03b, 0xdfd29b84, 0x4e975532, 0x08361d04 }, + { 0xcba0a713, 0xf0232fc3, 0x4b2eeee9, 0x66ee4b7e, 0xb78b0036, 0xa32b7db3, 0xe2f30b39, 0xd4dec14c } + }, { + { 0xd36a7ab2, 0x67f4ed43, 0xc817db01, 0x2f28e486, 0x5c05b744, 0x3d1f43f1, 0x3d9e7bbb, 0x8f180f0e }, + { 0x3c2b5219, 0xb5c4f016, 0x3ecfadd1, 0xd5199480, 0x2ea1b120, 0xfe00a929, 0x725cb579, 0x10776088 }, + { 0x73ca411a, 0x2d52dc92, 0x1f8468ac, 0x49f9e29c, 0x4ae29ea6, 0x88242e06, 0xe735e8b3, 0x214bf098 }, + { 0x6dea30de, 0x81bfb45c, 0x0066cd3c, 0x2ef9f054, 0x661e01c0, 0x42f761ad, 0x57336603, 0x992d508b }, + { 0x28fe1b7a, 0x7ef83cdc, 0xf6cd53ec, 0x5f433d1d, 0xa6f298b2, 0x82c6fd51, 0xae40ca01, 0xa3289f64 }, + { 0x1ed7f9e2, 0xb34f93fa, 0x35c9d484, 0x02210a89, 0x8ffb4860, 0x1f3bad52, 0x4a04e4e4, 0x7f240d8b }, + { 0xb167e24b, 0x2b7b93fe, 0x90187e34, 0xa7fff549, 0x04632894, 0xafcabcfa, 0x560ad9ab, 0xdaf1e573 } + }, { + { 0xd2d02250, 0x1cfdb459, 0xa7be1444, 0x4517d059, 0x2a4924d3, 0xf987d56a, 0x3f0396a3, 0xe8a2a6a6 }, + { 0xac4c610b, 0xd10dc62d, 0x7171da3d, 0x266f2b5f, 0xaf934d11, 0xc07ee64d, 0xcd1f0757, 0x141f4bf0 }, + { 0x7ecb87a7, 0xdb0d272f, 0x818ace78, 0x59398fa7, 0x25c3d879, 0xd3df1c98, 0x63549da0, 0x74ec65f7 }, + { 0xaac37051, 0x948a92fb, 0x896fbb6c, 0x0444eccc, 0x369ff36d, 0xc5b38cab, 0xe5dbda92, 0x9afff36c }, + { 0x464aa944, 0x373ce36c, 0xb4ff97f0, 0x238f6df3, 0x84aa4167, 0x2aeb497f, 0x4117d17c, 0x60e545ce }, + { 0x6f440a4d, 0xf770a96c, 0xeb9230c5, 0xed4ed9b5, 0xcfb56dfa, 0x81d07cef, 0xb696436d, 0x7f99e9c2 }, + { 0xf45c6592, 0x274ad3be, 0x3a91c2df, 0x6dc9d9c5, 0xd3411a03, 0x027282e1, 0x7675402f, 0xe1987a93 } + }, { + { 0x6d8fa21f, 0x170d86f4, 0x74a8d1e5, 0x6097209e, 0x3aaaad94, 0x594fc661, 0x6174d88d, 0x9f14f1a1 }, + { 0xc3c4af2f, 0xd8d7dd7b, 0x3c80cbde, 0x1c5aeba1, 0xe4edbeb8, 0x57ecf240, 0xb503fa1c, 0xda69c2f6 }, + { 0xf962d73b, 0xa5f276ff, 0x1d88db47, 0x3f7801a3, 0xca4861a0, 0xd116075e, 0x457c2d1b, 0xb6e249c5 }, + { 0x8b44add4, 0x9f3d7bd7, 0xdd635ed9, 0xc1101393, 0x31e8b807, 0x4642036b, 0xff891aba, 0xd792b1f0 }, + { 0xdebe280a, 0x77f5be94, 0xfc19b696, 0xdd0ffe97, 0xe7ce196d, 0x958acc04, 0xb47125dc, 0x2c9069cc }, + { 0x9a642368, 0x07ab659b, 0xeb99ec37, 0xddfb12fd, 0x54413d00, 0x0dbc2637, 0xcf98c7ba, 0xf2f07e46 }, + { 0x9d83d826, 0xda1be20c, 0xe2c21d53, 0x23569607, 0x8dfadb0d, 0x07eaed28, 0x6587c111, 0xac48baf1 } + }, { + { 0x81ae76d9, 0xfb3bfc8b, 0x88e191ba, 0xccf551af, 0x71ac053c, 0x0860809c, 0x9908dadf, 0x320797e6 }, + { 0x4a97c663, 0xd6e091cb, 0xb480faea, 0x1bacb1d0, 0x8e3046e0, 0xee6090b2, 0x085033a1, 0xc805d682 }, + { 0xfe98733e, 0xc4ff804a, 0x360a2923, 0x941ca38a, 0x3e4e6d8a, 0x3d70b663, 0x62c31590, 0xb317e43b }, + { 0x02274140, 0x6f02a50a, 0xeb3cd539, 0x07a9b5c9, 0xf80801c9, 0x4c2f5e39, 0x6c8a7eb2, 0xaa52caa9 }, + { 0x6ff7956e, 0x584d5993, 0x5cd3d0c4, 0x6c1bec6f, 0xdf3ad54a, 0x0634085d, 0xe6edad76, 0x0632db1d }, + { 0xc0daedce, 0x6fb5fc04, 0x76cd6752, 0xbd0ebd60, 0xaa171a2a, 0x87271e80, 0xb32cf4ff, 0xcfd5f1ea }, + { 0xf4eae25b, 0x1066c3e2, 0xc66efd8a, 0x5771607b, 0x4a1103e1, 0xc72b19d6, 0x85f6005d, 0x16270c65 } + }, { + { 0xadfd2c36, 0xd5d9a3e6, 0x1c5ded49, 0x794b0b23, 0x2b3dd153, 0x85212727, 0x7e8378ce, 0x62a6c24a }, + { 0x177a0f49, 0x990dfb5d, 0x2a7cbb31, 0x81dd7508, 0x0a2076ee, 0x5b23bfb5, 0x92f9cfd5, 0x09a5afc5 }, + { 0x1f7bc827, 0x079b2d8e, 0x5bdc1ac7, 0x673ec43e, 0x657f62d1, 0xf9468988, 0x02c231f0, 0x248a73fb }, + { 0xe32bbbf5, 0x9643176f, 0xaa007d1c, 0x1b31fe7b, 0xe6d7493c, 0x6f0544be, 0xc2a166eb, 0x96553372 }, + { 0x4cd86349, 0xf93cba6f, 0x80330f59, 0xdbd48996, 0xa04d3d1f, 0x814c4343, 0x6b4e6bd8, 0x130b061f }, + { 0x488259de, 0xca5f861d, 0xb1f3befa, 0x2fb3ecd1, 0xb75c2a80, 0x13e0054c, 0x68f7b652, 0x46705c85 }, + { 0xb56c48d8, 0x919f2305, 0x0597d41e, 0x283c8849, 0x97acf524, 0x600d53eb, 0xb58af268, 0xb6055293 } + }, { + { 0x93b58020, 0xc92b9cca, 0x68fc5c38, 0x65cfa237, 0x4f772567, 0x0bee599b, 0x67bc9a37, 0xcb552a96 }, + { 0xc792e9d9, 0x88e62b19, 0x4f905a50, 0x9a2f679a, 0xce1a0f3f, 0x1612b9e3, 0xf468578f, 0x49366e99 }, + { 0x42d446d0, 0xbc66a584, 0xc13f0b96, 0x9a459cb3, 0xd370cafe, 0x74cb1ed7, 0x33ff0f32, 0xdcd2b0ea }, + { 0xb0a3e5ce, 0x04b267c7, 0xfcb3b440, 0x17ac5acb, 0x1447fcd8, 0x49c52474, 0xd697d5ce, 0x7772aaa0 }, + { 0x50f93339, 0x11a673da, 0xe65ac850, 0x06e92d28, 0x29e97ce8, 0x2232b5f2, 0x94f7facc, 0xdf282447 }, + { 0x092291d4, 0x6a117ef7, 0x7a34fe0d, 0xf83e4c59, 0xd3330de6, 0x832f0923, 0xfaf4f12b, 0xf6faa6d4 }, + { 0xe81ae317, 0xc3b9d4c1, 0x9e64153f, 0x5c1d9fdd, 0x7d6e1738, 0x58feec0a, 0x0fa3da99, 0x3d715281 } + }, { + { 0xecdff5a7, 0x6676ea5b, 0x2c726a48, 0x407d9721, 0xa1599ebb, 0xb0db1f6f, 0xbcf2a1f6, 0x7d2660c9 }, + { 0x3c9ddc23, 0xb272fda3, 0xfa08d13c, 0x33bcb2c8, 0xcc9780b7, 0xe59248dc, 0xa53ef623, 0xcdb54aea }, + { 0x0a891eee, 0xedb5537a, 0x73fef228, 0x2f8afdf8, 0x21937ce5, 0x2bfa6881, 0x19e4cab7, 0x51111ed4 }, + { 0x8463613c, 0x1e08ff5b, 0x3619d2c5, 0x6c5bc71a, 0xa5617229, 0x7a84f5a0, 0xd70ec7a2, 0x096c3012 }, + { 0xa543ff79, 0x5d9dc2d6, 0xccbd15d2, 0x4ca14491, 0xf6712929, 0xa48759e0, 0x1a8d2f9b, 0xf75b299d }, + { 0xf741280d, 0x27b522e6, 0x8b9120d6, 0xde442033, 0x4a45f300, 0x1ab5c184, 0xb3529b73, 0x78ae6f43 }, + { 0xb7e6405d, 0x96e14656, 0xf6f5af96, 0x2484964b, 0x4cc985c1, 0x30c5c4f7, 0x9348dcb2, 0x451fd6b7 } + }, { + { 0x847b441f, 0x64e2d0af, 0xe296fad7, 0xf04c1410, 0xfbb26f59, 0x4c9b5399, 0x4b4549ab, 0xda5bc6eb }, + { 0xe0f825d1, 0x823baf0b, 0x5a5daa63, 0x70afe524, 0x8a3d5f5c, 0x6a579433, 0x19ec18c6, 0xcc022f88 }, + { 0x69549970, 0xc6a94cd6, 0x39c448c0, 0xccd1e4fa, 0xd3e51cbc, 0x2daa4ded, 0x641f113c, 0xefcb15ea }, + { 0xc769f45a, 0xe8b9f6b7, 0x6c171cf7, 0xe51aa6bb, 0xf6e8a7cf, 0x550d9ec8, 0x70b6fc14, 0x93d25399 }, + { 0x1b38ee7f, 0xc2ca1522, 0x2f02f4b4, 0x64e5e77e, 0xaf807936, 0xfd52a2b4, 0x0b945830, 0xf32ddabf }, + { 0xdcfb6efd, 0x9e827b96, 0xee3fdcff, 0x9927330b, 0x1ca19690, 0x05751282, 0xe894714f, 0xb753e4a4 }, + { 0xe4aa50a3, 0x0f2932d5, 0xf2ee250c, 0x7909c7e5, 0xf520966a, 0x8e6d6fd6, 0x362ff7aa, 0x4f1ffedf } + }, { + { 0xba4aa7fe, 0x23acf2fe, 0x750c8802, 0x479c8ae9, 0xefb8b28f, 0xb225382e, 0x4a822fc2, 0x9d19ba9e }, + { 0x25f06167, 0x4e836183, 0x16f9c419, 0x9c6a3ce2, 0x65d799ee, 0x2dcff663, 0x7435d69c, 0x62722923 }, + { 0xdb0d51b9, 0x4386ddbb, 0x13928624, 0x00b1c86a, 0xfbed33ef, 0xc89cb5f9, 0xf69a263b, 0x436e3d90 }, + { 0x2e9e445d, 0x6fddb749, 0xfe91e5f5, 0x2e0f2b83, 0xa1dc12de, 0x9ad1eab8, 0xfc46cca9, 0x9f1a0808 }, + { 0xa7b20d80, 0xcd7e5fb7, 0xa105a519, 0x329a760d, 0xb43e6e56, 0x890d9bdc, 0x0f62a234, 0x69ff9f73 }, + { 0xd2c9bf82, 0x11c2c774, 0x85e8c80e, 0x3dc16926, 0x0cf8524e, 0x3eba8078, 0x76e9f4ad, 0xc6c1e37d }, + { 0x650bba35, 0xb54cddf1, 0x7a6f3d6a, 0xc497117f, 0xd1668578, 0x67ae4fed, 0x3602d187, 0xd01f5242 } + }, { + { 0x1f57f29d, 0x029905f8, 0x0510bd9c, 0xce7df4c2, 0xb1a011cc, 0xb9e62d2e, 0xf104bb52, 0x9efc1af5 }, + { 0x931d0402, 0xe2ae2229, 0x95f50a92, 0x6dc64703, 0xb69f1789, 0xb480484b, 0x86d45dcf, 0xa232393e }, + { 0xe721772b, 0x6fef8146, 0xc5f37a01, 0x9771768a, 0x00755258, 0x081831ae, 0xdcf6cc8b, 0xf863dc4b }, + { 0xa3598f7d, 0x43c603ca, 0x9e9e35f5, 0xc0b63782, 0x407121dc, 0xa34cdee0, 0x8e53452c, 0x55701ddc }, + { 0x7a4ac01e, 0xcad82682, 0x44fbc5e6, 0x892e51ea, 0xf6d7dc96, 0xd822163f, 0xb29d330f, 0xd19358d7 }, + { 0x8e697e6b, 0x923d1214, 0x33b221de, 0x6e8af382, 0xb972588f, 0x0501ad9e, 0xeab37b31, 0xf03b3f88 }, + { 0x12c94189, 0x2ab9caa6, 0xcdf48f4d, 0xb95c7e34, 0xf87491db, 0x91363766, 0x96f22251, 0x84317056 } + }, { + { 0x7cbba542, 0x72173553, 0x0c0a7a35, 0xc6f4eb31, 0x82bb8315, 0x6f0b5c5d, 0xa04d85dd, 0x3af4cac8 }, + { 0x3cd5253d, 0xc62d4aa6, 0xd70751d7, 0x429b3bc6, 0x48fdc01f, 0xdf33a9a5, 0xbff66b75, 0xa7834e5f }, + { 0xff19bdb6, 0x0659727b, 0x94ed27e1, 0x6761817a, 0xa8dd8727, 0xd11d0798, 0x1e8b20e2, 0x502497bd }, + { 0x5ae9a48f, 0x29d1b18f, 0x1ebef3de, 0x51a8970b, 0xf1593ab9, 0x105438e4, 0xb8adac0b, 0xd6c4fee5 }, + { 0xc928984f, 0x46d28d26, 0xf341ada7, 0xb90279c7, 0x30fcb818, 0x92732b54, 0xbc4af11d, 0xb886260c }, + { 0x5223cd70, 0x6c8e9c6d, 0x0f074d15, 0x75b02f03, 0xf01e807b, 0xb90dc474, 0x2a4222fd, 0xf7e22b4e }, + { 0x13f4a74a, 0x81d4be59, 0x2841a6b6, 0x58db0cd2, 0xb51bda0a, 0x99fe44a1, 0x525627bc, 0x41383547 } + }, { + { 0x8b01f37e, 0x206300f8, 0xcac9203b, 0xca044f48, 0x9f55b65c, 0x8687785e, 0xcaa26e97, 0xd70e84f7 }, + { 0x4896d8e5, 0x08aed1be, 0xf44e6b99, 0xf3d85e8d, 0x1542f062, 0xfb686b8a, 0x66c5e1ac, 0x81de583e }, + { 0xcf9bb018, 0xa03a9704, 0x283f8f67, 0x44ae7b5a, 0x39cb8ae9, 0xba5de384, 0x513f7a33, 0x4d93b2bf }, + { 0xca9e5603, 0xeda4a5cc, 0xcb1400b7, 0xdf20ab93, 0x42afbb75, 0x59b5082d, 0xdcf8fdab, 0x626e4301 }, + { 0x4757c591, 0x20281a53, 0x5745e75f, 0x934ab502, 0x45702ab6, 0xea024398, 0xaa157702, 0x5b95d5b8 }, + { 0xfb4667d5, 0x688f1212, 0x8c13309e, 0xebe42bb8, 0x597635ee, 0x82dab4e4, 0x28452d5b, 0x8de3ec58 }, + { 0x37b5319d, 0xab7a3ae0, 0x285a102c, 0x4d4d6609, 0x00ceacb7, 0x859ef2ea, 0x7a9baf1e, 0xa7d1e1ec } + }, { + { 0x4262d31f, 0xc6bfde90, 0xe4879507, 0xad2c75c5, 0x330ef914, 0xdc0091cc, 0x8144ffd2, 0x593f522e }, + { 0xfeb34417, 0xe940b63a, 0x54b1ed6a, 0x7ca15220, 0x26d78116, 0x4304fd1c, 0xf8a028a8, 0x93fc1330 }, + { 0x1b9255ad, 0x50ce1933, 0x23801901, 0xb265abe8, 0x04f25868, 0x4b6825cd, 0x257a49a9, 0x2508d0a0 }, + { 0x0d554186, 0x4c3ea649, 0x26db83a6, 0x88950115, 0x6479edc4, 0xcc4090f8, 0x50c50406, 0xbbd7a030 }, + { 0xdbdc389c, 0x5eb8199f, 0xcf74a9a2, 0xcf3d8afe, 0x422dec42, 0x4bc45fc3, 0xcb777bfa, 0x70267343 }, + { 0x634e0b8f, 0xfe8050bc, 0x6d104e04, 0x6fb0865a, 0xce0fd7ff, 0x99b58711, 0xd297351d, 0x55a4b0be }, + { 0xcbc61aaa, 0xfccf89c0, 0x1dffca73, 0x7501e2a0, 0x9060e461, 0x212e84b5, 0x2961348b, 0x6075ff35 } + }, { + { 0x1971479e, 0xf1030877, 0x5e164bc5, 0x7b62d972, 0x7c79fc3b, 0xf7f0f07e, 0x8eff6729, 0x4922bb00 }, + { 0xf329ae40, 0xb38599d1, 0x3e9b0544, 0xd54e5643, 0x4091b5c5, 0x6a6dd0d1, 0x83d67840, 0xf82fb50c }, + { 0x1557f7cb, 0x6658ca2f, 0x35eacc2c, 0x47f3a958, 0xa498919d, 0x111cf62a, 0xc8035aae, 0xb7cad54a }, + { 0x4f02a442, 0xa40631dd, 0xefcba983, 0xdd7c3993, 0xee1226bb, 0x6294df26, 0x9529ae54, 0x7a634024 }, + { 0x5d9171eb, 0x05e32a3b, 0x68a836bd, 0x55b4b02b, 0x4c748bbe, 0x00f15133, 0x95266a50, 0xdf18fc19 }, + { 0xe066eda6, 0x9e04b489, 0x57b29169, 0x8ee40a42, 0x701813f3, 0x892d824b, 0xc6ece8ef, 0x6a46a762 }, + { 0x21e51d9b, 0x7fdce794, 0x053ed79f, 0x3884dfa5, 0x3dbb2f0b, 0x21897155, 0x54c823a2, 0xfda148e9 } + }, { + { 0x66f558b2, 0x2d6a44f1, 0x49017c74, 0x58e64303, 0xfbb8ccf8, 0x2755a4b7, 0x38483726, 0x7efb7c5d }, + { 0x6b9782d2, 0xf249694c, 0x7809f73a, 0x039be4f2, 0xa84b112d, 0x7ce459be, 0x20ceb8f6, 0x024162eb }, + { 0x67ea0190, 0x2fe4203b, 0x45ab91f8, 0xa0356d3c, 0x25c94692, 0xa9fac370, 0x593459da, 0xf41dde5e }, + { 0x457d0f83, 0xdc722eda, 0xfc2d6748, 0x17b1fa53, 0xb504bf7b, 0xb2ec3539, 0xcda65159, 0xac11254d }, + { 0x4f7b4295, 0x8682638d, 0xccd438f0, 0x864298f3, 0xccbf0c14, 0x1f0efcf2, 0x9cef2954, 0x6997b446 }, + { 0x736a3b6e, 0xd74b6514, 0xf891a59a, 0xc9c1c3df, 0xe6d5953f, 0xdbfd4970, 0x3cb2c56b, 0x4f29b2bf }, + { 0xf5449706, 0x0b298e81, 0xad160a61, 0x48e4a2a6, 0xb38e2277, 0xda0b2997, 0xcccda1fd, 0x663628fa } + }, { + { 0x88461e31, 0xcf3888a1, 0x099f1db2, 0x6811d294, 0x000b1c12, 0x18717a0c, 0xf4c08ad1, 0xd43dd554 }, + { 0x4566b0fb, 0x8de6f13d, 0xf378de4d, 0xc9ad32e2, 0x410608b7, 0x426a0852, 0x1ba93f7f, 0x1e3c19ec }, + { 0x86dada84, 0xd21501e4, 0xc085a31a, 0xae40a4e8, 0xb3aceee2, 0x4867f51c, 0xa54200d2, 0x07d31bfc }, + { 0x983dabeb, 0x7ac24dd1, 0x55aca5f3, 0x5cd65a17, 0x48cd118e, 0xb2f87539, 0x82161971, 0x39692cd8 }, + { 0x1d8b1be8, 0xefb57822, 0xf0df6722, 0x73d364b5, 0xa94828c2, 0x796774c7, 0x93fd74fc, 0xb357a489 }, + { 0x95505349, 0xc7a46174, 0x6fa24c02, 0x16efb6fe, 0x740008aa, 0xb6d9917b, 0x9da5de0c, 0x853c7241 }, + { 0x7f437191, 0xe15dc8a6, 0x5cd38fd9, 0xe92b2720, 0x5e9e5325, 0x951a7f9b, 0x0baf1cea, 0xa22710e1 } + }, { + { 0x7c260aa8, 0xd4c5a15e, 0xfd8cda34, 0x8c160df4, 0x17b599b8, 0x230d03d5, 0x1efea373, 0x91735454 }, + { 0xc1b07120, 0x37d0e5c0, 0x7b4efd27, 0x484b4d39, 0x2cf880a3, 0x508fb7dd, 0xaff7f179, 0x8c7b602d }, + { 0xfaf6f189, 0x908e9151, 0x8b9e20df, 0xd3bf4837, 0xb6491aa9, 0x7cf456a6, 0xecbcb69f, 0xfad87a22 }, + { 0x8d76fcad, 0x4485d0cd, 0x61f1e566, 0x4e3393d6, 0xa77e206b, 0x6a6aa22e, 0xefd341e6, 0x4156e065 }, + { 0x769cb145, 0x784032b3, 0x8c7d62e2, 0xa4812bbd, 0x34fcfb15, 0x5ae0fcc2, 0x71c975fc, 0x4d494fc9 }, + { 0x422a6172, 0xebb52112, 0xa30e16ba, 0xc33ed85f, 0x4ace3d27, 0x3c40b4a1, 0x4438d53e, 0x0f0f9d86 }, + { 0xaca70e84, 0x01e02a49, 0x639cb433, 0x7e065289, 0xd9c1557f, 0x52fc1006, 0x124252aa, 0x7fa52809 } + }, { + { 0xc2b2f5aa, 0x474ffe2e, 0xeef7d3a3, 0x5398e0d0, 0x77332d60, 0x3d421034, 0x6f2c7505, 0x7577f7f4 }, + { 0x24c40f8d, 0x0aa30a28, 0x5c7b4d5f, 0x7328f598, 0x3389c312, 0x286a2ab4, 0xdebc62f3, 0xd07734be }, + { 0xb725f710, 0xfbbc5bb4, 0x7e22dce9, 0x03140fbb, 0x81e57058, 0xab4a0910, 0xd4424761, 0xbd860106 }, + { 0x7beae8e5, 0x19d325d3, 0x58f7ad0e, 0x7bc8d35e, 0x3d52d5ec, 0xb676a92c, 0x659043b7, 0xdba74980 }, + { 0xc027c5fa, 0xc7a41e0b, 0x75ee6876, 0xf42a649f, 0x210e2949, 0x752e2748, 0x70cda457, 0xda935595 }, + { 0xfe0a1aeb, 0xe91527d4, 0x745ac60b, 0x8ab847c1, 0xa0cb829f, 0x6807edb3, 0x75786719, 0x5c0a7958 }, + { 0x49994b67, 0x3aadfd2f, 0xb93d4a77, 0xa47521f4, 0x003eaf27, 0x5b9259ea, 0xf45befdc, 0x331d4aaf } + }, { + { 0xecf05a78, 0x5b0dccea, 0xbe596791, 0xed74ae92, 0x777bfc4c, 0x561c0875, 0x07bbfa03, 0x579b232e }, + { 0x6c42cfac, 0x24f610e0, 0xdcf35c44, 0x1b9577c1, 0xe2bbd5ea, 0xd5f823b5, 0x9aa4298d, 0x6b66d59e }, + { 0x5d954b63, 0x53148e48, 0x74fa648a, 0x0e0d480b, 0x2fc671d9, 0x2fd95107, 0xe70ab4fb, 0x7976b80d }, + { 0x8ef41049, 0x018013ac, 0x7550be64, 0x34b310c8, 0xee330770, 0x82344b45, 0x6d46e81c, 0x5ddc8719 }, + { 0xf255471a, 0x2833052b, 0x72f5a69a, 0xf5ff80d9, 0xacffa4eb, 0x60b8e894, 0x5265bb17, 0xf6db3173 }, + { 0x29bc7929, 0xbfc100b5, 0xf24ede85, 0x7ae1d4a5, 0x447c4bc9, 0xccc2aa08, 0xd5745d7c, 0x053457a2 }, + { 0xfa514633, 0xfb59f89d, 0x90ca6394, 0x3fedf89d, 0xc2cffe6d, 0xd2b55ee1, 0xa5df8867, 0xbb7c2efc } + }, { + { 0x1dd251ac, 0xf30df07d, 0xd8136997, 0xbb300cbb, 0x9bb0f617, 0x097b4ad6, 0xaba0ef4e, 0x59465f3e }, + { 0xc67a54d8, 0x2d751c35, 0xf8e886e4, 0x60ed22d6, 0xdced76ae, 0x4317daee, 0x27c2efa5, 0xb5eec930 }, + { 0x2ab454a1, 0xac5b9d89, 0xec2dac35, 0xb7c2d85b, 0x6c74c4ac, 0x3d28f854, 0x0901addc, 0x7d29d165 }, + { 0x19099d92, 0xc8d38c91, 0xc43dbf7d, 0xe1af968b, 0x7ed8cf43, 0x4054cb18, 0x0a9668a3, 0x1cc65a8d }, + { 0x5836c214, 0xdb773225, 0x5fde14a6, 0xdc947ecc, 0x6b3e8419, 0x5708a87e, 0x347206dc, 0x32160dcd }, + { 0x1ce13b9e, 0xb816fb8c, 0x198329b9, 0x9d3caeff, 0xbd3b5abd, 0xe4d3eeb9, 0xb77864a6, 0xaf3bf0a9 }, + { 0xf485d47f, 0x51b08c2c, 0xb42daa90, 0xb41a9590, 0xb6362e88, 0x42bd5caa, 0xeb7391f1, 0x688ad9b4 } + }, { + { 0x8b55b285, 0x42aa6486, 0xd9268c13, 0x0a03572b, 0x4d504508, 0x5494ff44, 0x220e34dd, 0x63981d88 }, + { 0x9b8ee0b9, 0xaa0cee25, 0x284f22a6, 0xacfc09d0, 0xcf8ac884, 0x9f034053, 0x02c06625, 0x1093543b }, + { 0x6cb3b436, 0x40a03d9a, 0x070dda52, 0xbea1abf9, 0x96852da5, 0xb53ca963, 0xe87a92f9, 0x58cca1dd }, + { 0x91870369, 0x42e0fdb1, 0x038c4b19, 0x055e8e19, 0x6dc8bd5e, 0x1b6cabbc, 0xa5e2bb46, 0xcb466075 }, + { 0x60eb94ed, 0x51464ace, 0x142290e2, 0xf4a44743, 0x2c708010, 0xc5250cc2, 0x6b769c44, 0xaf7e0bc6 }, + { 0x427ce9a3, 0x643b6665, 0xf5825e83, 0x71c078e5, 0x80c12986, 0x468c2c31, 0x66fc2010, 0x8d883193 }, + { 0xeec6896d, 0x5bc850a7, 0x0043b164, 0xb68fa17a, 0x42a90bf0, 0x66f032ef, 0xd2a793da, 0x8365050f } + }, { + { 0x4bcf37fe, 0xdfbdfcfd, 0x2656f67e, 0x99743980, 0x5c56a240, 0xad4a9dab, 0x8265a41d, 0xa8898339 }, + { 0xa7605856, 0x24112f36, 0x66231ab2, 0x1174e49f, 0xa28fd7e8, 0xb2c571be, 0x78e2c98f, 0x64e2a488 }, + { 0x55cdcfbc, 0x335f2de2, 0xc1f667a3, 0xcae99a95, 0x13bc9290, 0x2b5cad96, 0x6b64e4ff, 0xed8785f6 }, + { 0x3e337610, 0xf3167171, 0x204cba94, 0x148aa7c9, 0x22dd312c, 0x413db12a, 0x64e10df1, 0x8cc14934 }, + { 0x3996e4b5, 0x82fa4d52, 0x1e2948b4, 0xa41861d6, 0x04f0a3cc, 0x19e28afb, 0x7854e850, 0x6da4d3ca }, + { 0x3ebc0883, 0x5b7a6a1f, 0xbc847133, 0xdacac476, 0xe7b5ee09, 0xcc407e9b, 0xc9f984b4, 0x4413fb47 }, + { 0x25af56f3, 0x9ee31133, 0x3a5d6608, 0xc1633547, 0xa1340283, 0xa51a0e30, 0x6abb1afa, 0x57509d93 } + }, { + { 0x02af6488, 0xc6f1f442, 0x6c639ff4, 0x08c7cd76, 0x76c9ab1d, 0x18d2048a, 0x676010db, 0x902497a7 }, + { 0xfc8ae3de, 0xab96eb36, 0xb9a8f7f0, 0x271c4873, 0xce390db7, 0x01690929, 0xe5ceb856, 0xd3bd1b2f }, + { 0x761a431f, 0xb09b8568, 0xceff9c70, 0x03addb33, 0x5ef69616, 0xa9c10c4f, 0x7885f524, 0x062db25f }, + { 0xaccf6587, 0xbcc93419, 0x4f35cdcb, 0xdb908d87, 0x0bbdffa6, 0x597084bd, 0xadd758ed, 0xa2f123fb }, + { 0x7c0739dc, 0x3ec7f3e3, 0x1713fbd4, 0xb36b947b, 0xc710c44e, 0x91353fb2, 0x0ad4c33c, 0x6567ee87 }, + { 0x258e7cb7, 0xd87421ec, 0x5d2b094a, 0xd761d2f7, 0xf46c39fe, 0x7571ae0e, 0x36ab8436, 0x98bc9c83 }, + { 0x025c1dbd, 0x76b4d07c, 0xc54e9cc8, 0xcdf720e6, 0x0020d4bd, 0x83c0bdb8, 0x20f92ff2, 0x271b6102 } + }, { + { 0xe6514ab2, 0x13b3fd1a, 0x8c679366, 0x1c128246, 0x7af4b686, 0xf4b704a4, 0x9cd82805, 0x12d4d6b7 }, + { 0xeeb985ae, 0x864faad7, 0x6963fda2, 0x89ae62c8, 0xdaa9b739, 0xb1749fe4, 0x8316ca7e, 0x0993a340 }, + { 0x8c5bf7b5, 0x1ee4e43f, 0x31d8fdfa, 0x2f99bbba, 0x210e181f, 0x3960ac90, 0x5d957a72, 0xba1652ee }, + { 0x79f6eb31, 0x30e4a088, 0xa0f2cb92, 0x591f7c8b, 0x50684126, 0x944e9c6e, 0xd189c11d, 0xcc30853d }, + { 0x1dcb040f, 0xd26ba641, 0x84fe1aa5, 0xa003b00e, 0x262cd9bc, 0xd0094575, 0x8555ee7c, 0x8287eac9 }, + { 0x63afa921, 0x328e2fc8, 0xbffcdcc8, 0xd42ce069, 0x4da61fcd, 0x971689b8, 0xd2629581, 0xe42b7b9f }, + { 0x83200806, 0x2c3cb0eb, 0x3184b87e, 0xad40c129, 0xefd20ec3, 0x6a77e260, 0x9d2b8de5, 0x361606b2 } + }, { + { 0xce3b9040, 0x462efa2b, 0xdca78d45, 0x83214df5, 0x98943be1, 0x674e1042, 0x2cbc7fe0, 0x0e972c36 }, + { 0xfa580698, 0xbb9417ec, 0xa5e6d40b, 0x17a77d66, 0xd3ae0c56, 0x6668f565, 0x3a1a3ccc, 0x16b81eeb }, + { 0x14a5c135, 0x33d9759d, 0xabff04e7, 0x58105133, 0x70e2396b, 0x893802ce, 0x284f4dba, 0x9486e2ff }, + { 0x9caca6a2, 0x7d23e8d9, 0xdf6c431e, 0x20853c78, 0xe6ff2b00, 0x9fc61c8e, 0xff9b2556, 0x995a4727 }, + { 0x66f7d234, 0x41fc08a2, 0x1d58a09d, 0xa0c6403a, 0xe7165329, 0x5ad4d532, 0x13898a2c, 0xc34da70d }, + { 0x30ac7de9, 0xdbf84ec0, 0x387e7290, 0xda58f0f8, 0x8c384fd8, 0x657605e6, 0x9168aa87, 0x80cda5a2 }, + { 0xd5e18650, 0x75dcea96, 0x2ea0bfa4, 0x643ae8a1, 0xde6f2b15, 0x2afe461f, 0xe3303295, 0x9377dd5f } + }, { + { 0xc322777e, 0x544fd7a0, 0x5e3bd3dc, 0x04838268, 0x29c9ecaf, 0xc04d9c43, 0xa14ac3b3, 0x9e9569fb }, + { 0xaa42e5a4, 0xbb8de644, 0xe2fbad26, 0xb4f18e48, 0x41a01be5, 0xcc95bfb6, 0x6e290d98, 0x54ef8bb9 }, + { 0x557d2b0f, 0xc03e88e6, 0x31a790c3, 0x3e5b6c76, 0x384f0b3e, 0x5ecb5bfb, 0x3d1eebfa, 0x5a577c70 }, + { 0xefa29a64, 0xaeb96331, 0xb2506e50, 0x0265949b, 0x3661408d, 0xee4c9b95, 0x566514f6, 0x992efa98 }, + { 0xb857ab5f, 0x7344d3c3, 0x19c63a4c, 0xe300cddb, 0xd035ef79, 0x3896caf6, 0xe158c43e, 0x8dbc225d }, + { 0x068826a8, 0xd11ee115, 0xaa0ab267, 0x048465b3, 0x83182d94, 0xc85a7925, 0xbc9d9148, 0x210b0520 }, + { 0x3e3a9c6b, 0x58154277, 0x69480d33, 0x8b127ac6, 0x9695e140, 0xbd936635, 0x25598547, 0xe30bd43f } + }, { + { 0x7cad6446, 0x95a8b12a, 0x7e99a163, 0x4e37e1af, 0xaedd8c8f, 0x48e82405, 0x02760ae2, 0x052e92ad }, + { 0xd42bd45b, 0x852604cf, 0xc82662e7, 0x8a7beec6, 0x3f9c480b, 0xceb76563, 0x55618792, 0x1d15b81b }, + { 0xc1e2c23a, 0xbbc03599, 0xb40bf076, 0xa7d81174, 0x55ecc4a5, 0x8f835e17, 0x97cc9058, 0x1f4ecbe2 }, + { 0x36e56936, 0xfc602ae6, 0xe4a1f50b, 0xca0d76f6, 0xb9231453, 0x88142240, 0x91fb92dd, 0xfaa0f736 }, + { 0xb11e5cf7, 0x4bbf80a4, 0x83fbdd5a, 0x629f9d4f, 0x70d3c5d3, 0xa4eff842, 0xb125d786, 0x451c95c6 }, + { 0xa0f9942d, 0xe7d77dd5, 0xa6ce3b5e, 0xad6fcb24, 0x1539fa38, 0x2e5d0014, 0x5647ff4a, 0x423a9cb4 }, + { 0x24328e01, 0x70060c5f, 0x9b5a2980, 0xd50c0456, 0x438b644e, 0xa6218f3e, 0xa8d29a0f, 0x55422c30 } + }, { + { 0xeb474cf0, 0xafbf75b9, 0xc178f2dd, 0x013eba8d, 0xae6078ae, 0x2f7148ac, 0x04d72dd3, 0x3b32798d }, + { 0x1c9f7c13, 0x2e631041, 0x2e4eee2c, 0x9aeeda94, 0x4377bcf4, 0x61803184, 0xe391eba9, 0x96f42e58 }, + { 0x0eebe52d, 0xc91b4fc4, 0x5529752a, 0x2911a0a8, 0x6883a4e1, 0x51d04140, 0x9d01d854, 0xf444746b }, + { 0x8ac7d066, 0xa5a93de8, 0xe336fdc2, 0x2b761cce, 0x2cb54674, 0xab52a8e5, 0xb7dc527d, 0xe28ebf7d }, + { 0x3ca84f2d, 0xdc63706d, 0x26604804, 0x0e2c42f1, 0x80c296c8, 0xc4a2dfbe, 0xeccef3f8, 0xdab00a20 }, + { 0x8891ba41, 0x3e0e1b3c, 0xa09a5bb9, 0xd9b10dc7, 0x12b39656, 0x681e834e, 0xb9464ce3, 0x7192d163 }, + { 0x555ccac0, 0x1b00b0a1, 0x747895e5, 0x5a4d1735, 0x685e8c2c, 0xd71cabd1, 0xc3f9edcc, 0x8f605d24 } + }, { + { 0x5d113432, 0x14505ae6, 0x7e65171d, 0xe5be1eb8, 0x09be54bd, 0x351bcff1, 0xee556201, 0x4320d056 }, + { 0xc7b6fe77, 0x7142a781, 0xd495ce94, 0x5ccd5b51, 0x097a7639, 0xd1b25366, 0x0b825916, 0x1f260e3a }, + { 0x6720ef61, 0x0d59a364, 0x06701add, 0xa51e08d6, 0x4db86dfe, 0x851fec4d, 0x137632c7, 0xcb292d71 }, + { 0x6608db77, 0x05c12056, 0x9b6b9b8e, 0x663d1ca1, 0xea7ebbc4, 0x564ddea8, 0x846212b1, 0x00b2e9a2 }, + { 0x57bba25b, 0xac6c79dc, 0x219f6138, 0x0507e8ae, 0xdaf7cf28, 0x315ab3d5, 0x32b289fa, 0xf2454aeb }, + { 0x345627e9, 0x277f5979, 0x7a570d80, 0x17d5be7b, 0xc1440ddc, 0x658d2d8f, 0xe6b2b033, 0xd3602918 }, + { 0x17266765, 0x63ddc898, 0x0b05da78, 0xe152732f, 0xbc07c329, 0x87308d49, 0x3533e92c, 0x13eef96b } + }, { + { 0xa6c74d3d, 0x5d63a5aa, 0x51ae38db, 0x3d664af6, 0xcca792ec, 0xe791594e, 0x5be4e8e4, 0x99f0af24 }, + { 0x66b45eff, 0x7d379b93, 0x35d9b9a7, 0x16f91660, 0x4c956d91, 0x28713dd3, 0xb0eb8f4d, 0x2b032bfe }, + { 0xc62649d0, 0x00df64e5, 0xa2da756e, 0x860f7c30, 0x9981d44a, 0x01eafed5, 0x51c2e658, 0x32b5df2c }, + { 0x56b139b3, 0x646f9505, 0xc046145a, 0xa89967b8, 0xfae495e5, 0x270d71ef, 0x477609f8, 0xc0130ada }, + { 0x82b8424b, 0x859a29d6, 0xfb1eab86, 0x682ce815, 0x4b094923, 0x2dfe7331, 0xd8e76c85, 0xcde77a35 }, + { 0x9e54ae94, 0x094dea2f, 0x6c4c1390, 0x99533a59, 0x10bff3d9, 0x45519ab8, 0x4e2b992b, 0xd6176a5c }, + { 0x95af2c5c, 0x49f92253, 0x967d73bc, 0x0f61c08b, 0x7e9cec0b, 0xa7b307b4, 0xfb7b21a3, 0xbe14ff9a } + }, { + { 0x8723d3ae, 0x0685750c, 0x019ac1cc, 0xd8de6a78, 0x5245a0fa, 0xbffc9e9c, 0x54167623, 0x807b1fef }, + { 0x81d8ad6b, 0x1bc10c9f, 0x33dda32b, 0x9812cf0f, 0x118e61e8, 0xab7e63f9, 0x1ae26ae1, 0x2af400e7 }, + { 0x3ba2ba53, 0x1d5846e7, 0x6e0065a0, 0x65bc2ef2, 0x50c29f8b, 0xca56af02, 0x94db5052, 0x7faf0110 }, + { 0x9340b038, 0xdaf2d479, 0x5cf279d7, 0x5300ad9e, 0x9a8df77c, 0x8fd4d109, 0xab00e821, 0xd13741ec }, + { 0xbf78239c, 0x7a6294b1, 0xd0905760, 0xd081bc37, 0x9a80f393, 0x4409d5f5, 0xa335c219, 0x7534be30 }, + { 0x97bac5b6, 0x714065e0, 0xe34b0574, 0xb0113634, 0xb0e83f51, 0x68290903, 0x111c481f, 0x570c6a9a }, + { 0xedf21139, 0x210b3de6, 0x6328dd9d, 0xb9ed6795, 0xf1949875, 0x0896ccba, 0x49526c34, 0xced20c3c } + }, { + { 0x50d016f3, 0x35841280, 0x0d682f63, 0xda54752a, 0x7416aaf8, 0x8ffc7525, 0x05d9e6a0, 0x5fe2c49b }, + { 0x5b84a3ed, 0x57737bb5, 0x58d8cf79, 0xe7ae800f, 0x5dc807da, 0x8b0864dc, 0x85c4aabb, 0x737e8715 }, + { 0x6e369e4b, 0x7d12c140, 0x11cef4c4, 0x026e1284, 0xd1297fea, 0x143dd929, 0x8ae3107f, 0xdfd92b43 }, + { 0xb68776fa, 0x5c43271a, 0x5bfb7545, 0x20115576, 0xec463b15, 0x5716ac16, 0x0a742f44, 0xdc10394c }, + { 0x93ebe0b4, 0x31cab089, 0xf703d6de, 0x8ddb986c, 0x029d5034, 0xf5919be6, 0x344acce1, 0xa7178be9 }, + { 0x02393f14, 0xcd4bd587, 0xe49523e6, 0x45b76377, 0x3189378b, 0x129a5480, 0x596844a4, 0x13bd0af1 }, + { 0xc1fbf5e3, 0x20b83b42, 0x94c122b4, 0xea35bbef, 0xa84afaca, 0xc7cede92, 0x2aa55379, 0x4e715526 } + }, { + { 0x191d8c25, 0xedf49bef, 0xccb166d9, 0xd31bb302, 0xd1394fc0, 0xbc7ac47f, 0x4ff9b145, 0xb2286167 }, + { 0x3cc6005d, 0x5af08c2d, 0xf0d13ff7, 0x086b72bb, 0xc23601a7, 0x34382607, 0x7a191b49, 0xb5e8eca3 }, + { 0x1256e971, 0x3ca1f021, 0x2a9fba8a, 0x2efffe72, 0xf8893912, 0x88287c58, 0x3047063e, 0x0ce6dbfe }, + { 0x0f596308, 0xdce19d18, 0x0b3aed5f, 0xe1b34628, 0x3c5e3471, 0xc610c449, 0x013b0569, 0x13d206c6 }, + { 0x7b5b0c08, 0xafa73f2c, 0x1afe34cb, 0x8e4352ef, 0xf0c9a492, 0xb1dd9c52, 0x8a3dbe85, 0x511b2068 }, + { 0xd0f7eeb5, 0x3cb65baf, 0x1ec371a6, 0x2652143b, 0x029c4b2c, 0xf4395f73, 0x070a8617, 0x1a41bd3a }, + { 0xe38ce7ed, 0x0999053d, 0x539b38c4, 0xe4a4ddb8, 0xfc3a29fe, 0x79ab63ab, 0xcd7bef5a, 0x39d51032 } + }, { + { 0x99ffd9e0, 0x6a7b6286, 0xd372442d, 0x2609ce72, 0x31b21b14, 0x1982853b, 0x0253796f, 0x4195e147 }, + { 0x94cf706f, 0x4219043d, 0x4948bae6, 0x4975184d, 0x51e72be6, 0xd00e181d, 0x5532c4bd, 0xe3e3d1bf }, + { 0x3a9511a4, 0xbce6a9d0, 0x322e27d5, 0xebed073a, 0x475bc71d, 0x77886f89, 0x57e25cfd, 0x0b8783f7 }, + { 0x86101a79, 0x88593c55, 0xc4d0aaf7, 0x66d0eb32, 0x559782e8, 0x3c738012, 0x779a44ce, 0x464b4901 }, + { 0x02334709, 0xdcd39abb, 0xbd4ba210, 0x1259e2ab, 0xcd81b73b, 0x41f02297, 0x5455c8a1, 0xf93e9f8b }, + { 0x9b00ec09, 0xcd936d0a, 0x6a99eff8, 0xa61b4818, 0x0f3fdab9, 0x924a0e43, 0xb6578638, 0x8f7e2f6f }, + { 0x863b5269, 0xd6873003, 0xd55ba719, 0x478fbd50, 0x06ad456e, 0x753ac81f, 0x2523b4dc, 0xa6c0aaa3 } + }, { + { 0x4c66c5e5, 0x24d70030, 0x1c778675, 0x01e610dc, 0x3318b68a, 0xb1a85bbb, 0xbd8dcced, 0x8386e37b }, + { 0x9a60c9ec, 0xab294812, 0xb9321b39, 0x10c50f2b, 0x583ce8dd, 0x5357d7c9, 0x60982c4b, 0x159157c4 }, + { 0x565dd84b, 0x9711aa2f, 0x7f6aed97, 0x6902c3eb, 0x73e93be7, 0x906585b1, 0xd908564a, 0x13f487d9 }, + { 0x23b1ed6d, 0xa7c43c99, 0xebbfa924, 0xb39c41be, 0x7a6352ba, 0x95747a3e, 0x2b5860f1, 0x7532934a }, + { 0x5eae3d04, 0xd2635222, 0xd1fe4098, 0xc6e2916e, 0xc86209a3, 0x51614200, 0x257b2adb, 0x951c5adc }, + { 0xcdceaa75, 0x7fb1fdd7, 0x891322a6, 0xca72927c, 0x8c2fccfa, 0xd80edf3a, 0x5cefd1e2, 0xbdd2eed8 }, + { 0x7e05a769, 0x81a4e29f, 0x89ef922a, 0x67a9d483, 0x1cab721c, 0x6f5c205f, 0xd102f502, 0x62fcb92d } + }, { + { 0x0e898ea2, 0x276be8c6, 0x20cbd93a, 0x91925795, 0xcc0e1426, 0x52ba9f4a, 0xe229d987, 0x04a4c65d }, + { 0x2985be68, 0x156e43f4, 0xf7e79720, 0x28a8cc8b, 0x1b90a8bc, 0x7acfe7c1, 0x7f2c38f7, 0xb6acd5c6 }, + { 0x11c48ff4, 0x6aaa0281, 0x61d4ecfb, 0x56e5946c, 0x09e507dc, 0x8e28097f, 0xb6e01d0b, 0xec5d2e6e }, + { 0xa9092e2a, 0x8030b6ee, 0xa62c0fdc, 0xe6fd7208, 0x3dae3e4e, 0x8b132548, 0xeef7b14d, 0xbb3e0df3 }, + { 0x366ae70b, 0x8af54a4b, 0x38695196, 0x490f3290, 0x69a4e783, 0xc25128be, 0x776ae4c7, 0xf3432d51 }, + { 0xf46709e8, 0x54b6f97e, 0xebe5ad72, 0x87f1ff2e, 0x2887b42d, 0xef0920c9, 0x9b2c4aa6, 0xaff35ba3 }, + { 0x980fd7f9, 0x4ec40a2f, 0xc67267ef, 0x084fea1b, 0xdc1f9357, 0xc82e5a6c, 0x6a1314d1, 0x2cf10f74 } + }, { + { 0x99e26c1a, 0x21d728e5, 0xa3bf7072, 0x1f867719, 0x9fc2a99a, 0xb3646233, 0xae028ed4, 0x58749d76 }, + { 0x84e31247, 0x3db47c77, 0x71b4ac32, 0x5e017ab1, 0x0cb3a997, 0xe9f22d8f, 0x61b71801, 0x80c3a383 }, + { 0x4fc8b9ac, 0x2c302d55, 0xc43ebde7, 0xafb2c409, 0x3e770688, 0x1ea75355, 0x42fb4ab4, 0x4b3ee41d }, + { 0x75f59943, 0x265beb42, 0x8552f918, 0x33b4cd5c, 0xbbc7e514, 0x4403f804, 0x592622c3, 0xa6c2788c }, + { 0x93954d46, 0x98102530, 0x65ee2172, 0x7c669b58, 0x48acf56c, 0xf12d22d8, 0x613faf21, 0x17cf04cf }, + { 0xa19fc70f, 0x1573fcc0, 0x0ecd8919, 0xafd79ffa, 0xb4b2bb85, 0x396c25e5, 0xd66fe1dd, 0xb2f73398 }, + { 0x175eeff6, 0x49ad4452, 0x393fbedd, 0xa09a5ec5, 0x4e71b848, 0x213bb3fa, 0x5865f497, 0xe0cc2250 } + }, { + { 0xb8c94934, 0x670b1bef, 0x09b597bf, 0xe95bc31e, 0x8f008206, 0xacfdc6b9, 0x697e0984, 0xc8f165d1 }, + { 0x9d1dee97, 0xc2639598, 0x30852fd5, 0x6fa62d83, 0x26fea39f, 0xb79aefaf, 0xf4ed4686, 0xf51bbba0 }, + { 0xbe4a0e85, 0x26aa35ec, 0x4ccb842a, 0x4daffff4, 0x0d0d6c5a, 0xde22570e, 0xda5b8f9a, 0xfb267bf6 }, + { 0x04684f26, 0xc2bc45b7, 0x78a5abe7, 0xd06d768e, 0x6609fb81, 0x10e0ae3d, 0xa939e5f0, 0x5a6caa84 }, + { 0x60e1f53e, 0xe0498ee1, 0x5a7bd7fe, 0x0e9d8a8b, 0xaea7dbe6, 0x78962259, 0xb56982ac, 0xb48924a9 }, + { 0x61f4f72f, 0x877a9b23, 0x80b8fdd2, 0x25076f3a, 0x3cfc165d, 0xb1a27de7, 0x7901f5fa, 0xaca74205 }, + { 0xbacf2caa, 0x2ffd287a, 0x5334c494, 0x6fc2dd9b, 0x8385ff11, 0x8ef2cd26, 0x3c700c5a, 0x883f96e1 } + }, { + { 0x01051c4e, 0xe171a853, 0x1a86285a, 0x54f10ef4, 0x1da6c980, 0x52622da3, 0x543efe3c, 0x5db30908 }, + { 0xd416105c, 0xae023365, 0x6991f58c, 0x6ca8442d, 0xdeebb86f, 0xfe4209c8, 0xdedbc33b, 0xfac9d4c5 }, + { 0x8befef55, 0x7e737cd6, 0x4d15fe13, 0xbd26464e, 0x80a01d45, 0xfd68913d, 0xd8cd8cb6, 0xc4e3c0a7 }, + { 0x96b72ffe, 0x2f8a3b29, 0x6293afcf, 0xaba930cb, 0x73d7bb5b, 0x07785741, 0x0d2b7174, 0x4a90d234 }, + { 0x05399790, 0x4a1f41fd, 0x9a2aedbe, 0xad926eb9, 0x534d3b8c, 0x8fccb936, 0x3ec3f1b2, 0x7bfffd7c }, + { 0x1d78b2c3, 0x88487362, 0x90ef131b, 0xb3e194c7, 0xd644719c, 0x63d94bf2, 0x57a07ca7, 0x3b7393c9 }, + { 0x3b1e3b26, 0xeed89619, 0x1d59f4b1, 0x8f21179b, 0xd2f5636b, 0x3760b2a7, 0xb8cba8a9, 0xe4781ce5 } + }, { + { 0xcdf29b38, 0xcd3ad590, 0xb60b0c91, 0x717c05c8, 0x67187a81, 0xf5e64622, 0x5fe4db15, 0x7caf92c3 }, + { 0x128e22f7, 0x33401a74, 0xbb73f3f7, 0xca39e2a2, 0x6bdbba61, 0x479c43e5, 0x45e71e88, 0x4a7fe7b9 }, + { 0x2bd5149e, 0x6b60080c, 0xa186e4d2, 0x32b3b160, 0x396411f3, 0x498814c7, 0x32af3f37, 0x914e1778 }, + { 0x52021b68, 0xf3f6d466, 0x05127da6, 0x4652a49d, 0xc04af790, 0x5f744134, 0x5469473c, 0x83443869 }, + { 0x3c789666, 0x55706cd2, 0xfb801295, 0x64be40b3, 0x9234d81c, 0x6a10f4d3, 0xe093b370, 0x3119207c }, + { 0x6512ad28, 0xf1762e3d, 0x89252d67, 0x319a33a5, 0x7047d72d, 0xc0cf8110, 0xe1f6a910, 0x5f181a3f }, + { 0xe0df2b52, 0xeccfde41, 0x71b6f228, 0x29a61ba6, 0xc18c6c45, 0xf6c491b0, 0xae634299, 0x60617efc } + }, { + { 0x932a9292, 0xeff3d35b, 0x0b3ffe45, 0x500946d9, 0xba2b8141, 0xf3aef5fb, 0x7fb73803, 0x5dcbed2f }, + { 0x92f928f8, 0xc45cb998, 0x3de973d3, 0x22258ee9, 0x01d0608b, 0x4abfd656, 0x4d05fbd5, 0xd0b317c2 }, + { 0x78a3e9c6, 0x1217d5fe, 0x37e07393, 0xfb4a2b36, 0x20fd014a, 0x9f430875, 0x7b7c72da, 0xe7826c88 }, + { 0x9e05b5fc, 0xc501e9e3, 0xfa5247cc, 0xff84de04, 0x19481bd8, 0xfd63637a, 0xf3aa923b, 0x18ddfc58 }, + { 0x6ff205cf, 0xd79bec07, 0xa0605213, 0x3fb90ac6, 0x38681ef7, 0xcecb097a, 0x992aaef8, 0x3f20406b }, + { 0x675ab4f9, 0x0384623e, 0x120f1482, 0x648bc836, 0xc275984d, 0x80248b73, 0x6343b511, 0x4f498daa }, + { 0xcba41f00, 0x41f24ff8, 0xe0d541d4, 0x2ad5b9db, 0x29fd8686, 0xf9247faa, 0x02dc9f0c, 0xa105f2af } + }, { + { 0x81314e68, 0x2e1bdcf1, 0xf262a0e0, 0xec3cc01a, 0x8b3b992d, 0x85186126, 0xa01b4c80, 0xf68996e9 }, + { 0x6c059760, 0x7cef4355, 0x94b55ae5, 0x46ebb21a, 0xc9652a93, 0xd00edbb9, 0x138854b4, 0x870e9c03 }, + { 0x2c878846, 0x5068ee62, 0x57504c0b, 0xd9992813, 0xad65db9d, 0x7c0540f1, 0xa51cca28, 0xe3f6585f }, + { 0xaae62fec, 0xf80c3b51, 0x1b8612b1, 0x4e1b799b, 0x122e7614, 0x9817a555, 0x076716bc, 0x26989d58 }, + { 0x082f3b0d, 0x2586ecaa, 0x3a68da4c, 0x2ec3a18e, 0x8322210d, 0x5db56d50, 0x21376298, 0x4f059417 }, + { 0xb9591105, 0xe37840ed, 0x65c2316b, 0x54328158, 0x9cb5600f, 0x25ca8e8e, 0xa3a5e15f, 0x490db5ac }, + { 0x0e25fe77, 0x1beb7f0b, 0x9700b7f6, 0x581f5695, 0x5f52081a, 0xf6c0c4b3, 0x4f23c5d2, 0x716b92a8 } + }, { + { 0x0b783206, 0x97197b11, 0x4466fc8d, 0x51e8e947, 0x529a9831, 0xbce64097, 0x84f78505, 0xdec144e7 }, + { 0xebadc492, 0x5c26fd40, 0x55a0109c, 0x22dd0942, 0x62869e2d, 0xdd67b5b3, 0x8dbad1b3, 0x74764f31 }, + { 0x63a0093d, 0x7361b487, 0xc4f3ec81, 0x73d62b5e, 0xf6443a90, 0xca47e3ff, 0x7fbf1f12, 0xe0d6064e }, + { 0x64b54365, 0xc74d838e, 0xd1a72c2b, 0x0cd37608, 0xba5a2b7e, 0x24af5dac, 0x7934ed42, 0x41f1d7f7 }, + { 0xa50c28eb, 0x7c8fccd8, 0x991d713d, 0x56143506, 0x83019cbf, 0x3e5e8c40, 0x268e8649, 0x42b96750 }, + { 0x115f1a44, 0xda6af568, 0x5818c25f, 0x7cb2cd39, 0xc41f0b4d, 0xb1d5c52b, 0x9d334364, 0x4b5c5bf8 }, + { 0x2887d927, 0x4cb784ae, 0x3f6be83a, 0xdc299f50, 0xa76bf296, 0x059ca3dc, 0x3387ce95, 0x24032c4a } + }, { + { 0x646c61ba, 0xc00dcebd, 0xffe8d48e, 0x1d5ef5fa, 0xdd03068d, 0x945c4a55, 0xc21478e5, 0x6516f79a }, + { 0x51081670, 0xc9480411, 0x45a2ac72, 0xfbe68ae9, 0x4dd25a6e, 0xb6901f20, 0x3fe634d3, 0x1109ba3a }, + { 0xaa1a199e, 0x4ce5679d, 0xc61856b5, 0xaad329ce, 0x888fed04, 0x54a92ce4, 0xec166331, 0x3cdcee30 }, + { 0x9b37df4b, 0xc643bb79, 0xf74d8080, 0x383f1d8d, 0x97ad1010, 0x6beccfca, 0x80835164, 0x57f51a36 }, + { 0x5ee2f501, 0x17c2f152, 0x985fb43a, 0xdf1a3cd0, 0xe332791c, 0xdff602d3, 0x579b3d44, 0x0f92d59e }, + { 0xa6dde8a6, 0x17dc2f83, 0x264d9a36, 0xe850c137, 0x8998dbe7, 0xc815c3a7, 0x5464c2b6, 0x41b6fddf }, + { 0xf1aa98e6, 0xa0b61792, 0x66788403, 0x75ce08b9, 0x705eba7e, 0x1cc8f43f, 0x8eead44a, 0x1effb035 } + }, { + { 0x63c1a59c, 0x3bb92ed9, 0xd993927e, 0x9115e792, 0xb999dbd2, 0x8f704232, 0x1809f9c6, 0x58568b74 }, + { 0x843124b6, 0x3c5ac0ef, 0x72e5d4ce, 0x846f817a, 0x6406ae45, 0xb2fe706d, 0xfb578605, 0xd86d22f5 }, + { 0x18938e86, 0xb285e7b3, 0x3ac87243, 0xbf1034e3, 0x2935a723, 0x442238df, 0xf189475f, 0xf485ec70 }, + { 0x794c2f0b, 0xd9aa1f95, 0x6e5cd411, 0xe1a66971, 0x42c32329, 0x4c25c3cb, 0x7786e163, 0x157466bf }, + { 0x97c86d73, 0xbf0a1063, 0x78b33005, 0x533de701, 0x34465c03, 0x39a03557, 0xddaa24eb, 0x3f68ca61 }, + { 0x0942210a, 0x8d29e6db, 0x0838c1c3, 0xe56b9e13, 0x781aec92, 0x49b12a6a, 0x33822b38, 0xcc81a41b }, + { 0xef40d172, 0x258f6a46, 0x7ab0a0ab, 0xd11b65e4, 0xa96ab13d, 0x6071d3f9, 0x6367b09b, 0xaf81b190 } + }, { + { 0x1b12c93a, 0xb2dd19c3, 0xc0baacf6, 0x9ac0736f, 0xa783871e, 0xab4c0c38, 0x512aef74, 0xd99a41ce }, + { 0x532aa8f2, 0x84ca4f04, 0x9f0d7c8d, 0xc529d10b, 0xa1a50d2c, 0x3dfc8bab, 0x156082d3, 0x031047a0 }, + { 0xf4f340e0, 0x8b2c1235, 0x758ad17d, 0x371b86f7, 0xcdd54fb6, 0x66df8eec, 0xd9790d57, 0xe484bc36 }, + { 0x00ff11ea, 0xa18fc2fb, 0xd897f75d, 0x81e0aaf1, 0x14326937, 0x7ea19d16, 0xd7980e5a, 0x8fc84e35 }, + { 0x14085ef0, 0xbed40a19, 0xa51cfb5c, 0x60f36e68, 0xdf33b423, 0xa612b2c7, 0x92c9a789, 0x061ba596 }, + { 0xb825a48b, 0x1c8d8307, 0x8adab13c, 0x8ffefbb8, 0x4fd180ae, 0xd7fc5b87, 0xddd5e548, 0x6af66526 }, + { 0xa8e14ddd, 0x78386471, 0xb9e89d93, 0x55e2f08a, 0xc2940906, 0xf1f8c9c5, 0x5352536d, 0xdf4d29c4 } + }, { + { 0x1a65e954, 0xa7c05781, 0xa622c36e, 0x39d1ae36, 0x3555bdac, 0xde1e7007, 0x499ab88a, 0x26e6758c }, + { 0x2423409c, 0x59f027d6, 0x53c01054, 0x99470ade, 0xf0445032, 0x42440709, 0x5762f300, 0xaf3f6e9a }, + { 0xfafe7169, 0x3821c260, 0xefe2db29, 0xad298c75, 0xa234e203, 0xaad5d774, 0xded608d3, 0xfc0a9d07 }, + { 0x6a8dc5ef, 0x0b50ff0b, 0xaa1e37df, 0xac63532f, 0x60cc05e3, 0x4a17918a, 0x3e498676, 0xdb55dbbf }, + { 0x3d2e8493, 0x858c6360, 0x1291fa48, 0x9da94500, 0x0575d135, 0x17b22353, 0x8755aeb8, 0x3a36fa91 }, + { 0x235ffbc9, 0x37884622, 0xc0b1a257, 0x2f4e75bc, 0x48b33b2c, 0x4e94a5fb, 0x57e26314, 0xca8db664 }, + { 0x76223077, 0xaae3cbc6, 0xb53e20bc, 0xf021fca7, 0xf4f70531, 0xdd3e20a1, 0x018908ee, 0x6ac4e5ec } + }, { + { 0x4bab2a03, 0xa4c894ad, 0x0718b9f6, 0x76505aa9, 0xa704a1ab, 0xe31d6d72, 0xe0b7d7e8, 0x82335d70 }, + { 0x9248c598, 0x05d14ef5, 0xb22196b6, 0x104dacfa, 0x5eb00a04, 0x65e5780f, 0x553d2bcf, 0x9a6faf4e }, + { 0xe7a84b80, 0x21ac8ab2, 0x0a97b8a2, 0xaa6c8ab8, 0x85d6ca44, 0x4912fc2f, 0x8ce532e7, 0xfd1ec6f5 }, + { 0xe0a3214d, 0x8b83e16d, 0xda1c1077, 0x6ecfd613, 0x6c44d10f, 0xa0ed0247, 0xbe6524e7, 0x9906e540 }, + { 0x6b901287, 0xff9fc5c9, 0xa169de09, 0x5aa704b5, 0x0c9a1708, 0x853969ef, 0x02a6a2c5, 0xfd22434b }, + { 0x011df8ab, 0x933987be, 0x4d8e33cb, 0x8a75575e, 0xa0df5ed3, 0x4afedf40, 0x72d973b4, 0xf0d715e5 }, + { 0xc649a341, 0x8c8ec585, 0x09e36ffc, 0xcae85482, 0x604b9358, 0x503619cb, 0x1838af3d, 0x9d311908 } + }, { + { 0xf992ef53, 0x3cc38b82, 0x484ac38b, 0x9cc29b5b, 0xad102612, 0x7167bdd8, 0x65013993, 0xcd0b9518 }, + { 0xc068a679, 0xdbd71611, 0x84c06e92, 0x9a66ae57, 0xb777ed35, 0x86279007, 0xd7297091, 0x70281626 }, + { 0x568a2bb1, 0xc2fc8f0a, 0xbeeb279f, 0x40e630bf, 0xd56a039b, 0x2a9e70a0, 0xc887842a, 0x22ad73ae }, + { 0x9f78ad15, 0x7320e353, 0xb005eebb, 0x7421e0da, 0xc04ddf75, 0x6f86e369, 0x6c43d7f5, 0xe8fe1ced }, + { 0x7745d97e, 0x0f4a15dd, 0xbc58b766, 0xa4ece092, 0x145a85f5, 0x617ef632, 0x5c29cc7f, 0x88f2ebe9 }, + { 0xa90241df, 0x69968208, 0xca3d5230, 0x260eacca, 0xa30ed8b1, 0x5065816a, 0x23a7b3bc, 0x08ffa2cb }, + { 0x1343e3b3, 0xf7ec9a56, 0xf6b95938, 0x9d75ab58, 0x4b919a32, 0xd0990f77, 0xeb3d0c3c, 0x03393c17 } + }, { + { 0x10404354, 0x24f4c527, 0x3bb936db, 0xe43c0af9, 0xcfdfae66, 0xd0c59040, 0x87c94698, 0xb1dfe449 }, + { 0x862620a3, 0x5a6bd6f3, 0x6715861e, 0x1794e287, 0x6f547703, 0xca52a892, 0x66b712ae, 0x92cedadf }, + { 0x5f632648, 0x07ed8aaa, 0xebc99ea7, 0x67e35f3e, 0x45df92b2, 0xf810d6db, 0x6594292b, 0x719dc0df }, + { 0x02517129, 0xc066cf91, 0xfee400ed, 0xe5a33177, 0x2451fc04, 0x8716cc17, 0x0e85aea9, 0x830b89a4 }, + { 0xc21ba7c2, 0x5cef1caf, 0xee257ad9, 0x4f17bc91, 0xd401c758, 0xae51df62, 0xa9dc2ebc, 0xb3b40e36 }, + { 0x9719e474, 0xe8d19d46, 0x00a43966, 0xb200e08c, 0xfb39eb35, 0x059d9c51, 0x8330589c, 0xdd55cfc1 }, + { 0x3816a521, 0x2b5440f8, 0x58a9d434, 0x38a1a222, 0x4299eeae, 0x4656a036, 0x178a14b7, 0xd8f66ba6 } + }, { + { 0x8e53e611, 0x0f80a4ec, 0x75cfc563, 0x7700369f, 0xeecfd38e, 0x4a84d294, 0x5fadff27, 0xedf0779d }, + { 0xd96a8adc, 0x824055e9, 0x73bde8d0, 0x28d6d0ce, 0xed5e9eac, 0x5a9d9c29, 0x3abbd71a, 0xf12ca86d }, + { 0x9a2903fb, 0x6fe15fef, 0xec292d65, 0x5ae89ee4, 0x07fb2b6a, 0x5e351b88, 0x5f3e661b, 0x3ea971b1 }, + { 0x4fb07aeb, 0xb3b1a129, 0x2e472f43, 0x4b931c8a, 0xe068fde9, 0x62c838e0, 0xb39f7053, 0xe38fb1fa }, + { 0xe8cfca5d, 0x5ee9bd31, 0x7bfcbd2c, 0x072b9b2a, 0x066bc2b3, 0xc90fcd92, 0xd7591916, 0x70bc9042 }, + { 0x7334d25e, 0x061f383c, 0x2ca2313d, 0x7c17e1ba, 0x95d4650f, 0xc323f32a, 0xf356fcba, 0xd7487659 }, + { 0x3de5961a, 0x1a9c3578, 0x5ab5e3a6, 0x332485f5, 0x81a763fe, 0xa1732747, 0xe00167bd, 0x9827e68d } + }, { + { 0xaefa11d9, 0xb23ae1b4, 0x6c5daa24, 0x466f709f, 0xdc2135de, 0x529c6d42, 0xd855a0d3, 0x01264bd5 }, + { 0xc61834ee, 0x61bc622d, 0x1e80ccdc, 0xa99991bf, 0x8ad8d302, 0xcb03b0bc, 0x51c27a3c, 0x61b7310a }, + { 0xf5aeb48b, 0xfce399cc, 0xbc6a2065, 0x9cdbe1d2, 0x4a5fb6f8, 0x6a0c024d, 0x666405ad, 0xe9c533c8 }, + { 0xf25d6ba5, 0x5a1e5f60, 0x9a760f26, 0x9a9ccfe7, 0xcbf1a84e, 0x11156e2a, 0x1ec8bad5, 0xa1abd1cd }, + { 0x429af8ce, 0x2b48afbd, 0x37c15970, 0x206a828e, 0xc1329c16, 0xab26ea1f, 0x079d8f0a, 0x040b51a4 }, + { 0xb1ce4771, 0xf0cad81c, 0xa50f6d62, 0x4e99cf63, 0x3d8949a0, 0x0d4fcb9b, 0x95f934f5, 0xa415e3e1 }, + { 0x2bdd8d6e, 0x566864c5, 0x73b6ec02, 0xb4272efb, 0x49a004e8, 0xd1149d77, 0x4cebcc5a, 0x456af3c1 } + }, { + { 0x081a5e5c, 0xbf7b8d4c, 0x8a34b5a9, 0xcdab3950, 0x7c623160, 0xc109ba89, 0x7bdb53aa, 0x9d5746c3 }, + { 0xa7176883, 0x41412b90, 0x474c53f8, 0x38c66dde, 0xcb6d77d1, 0x6f0a0c72, 0xb176acf4, 0x84750024 }, + { 0xe7d61ac6, 0xd53fce6d, 0x9d9d8914, 0x7276e969, 0x4a22f072, 0x0d3c37dd, 0xafbe355a, 0x85a80a9b }, + { 0xea5b16bd, 0x74126074, 0xad6a0091, 0xda26ae8d, 0x98119213, 0x4ed94ccb, 0xf91293e7, 0x83f0444e }, + { 0xd977cdc4, 0xbb396ccf, 0x156a3abc, 0x5049c8cb, 0x97e3fc76, 0x22ca279b, 0x6e6c56eb, 0x4a40aafe }, + { 0xcbbad741, 0x653712ab, 0xedee190c, 0xd65124f7, 0x35cfcf9e, 0xb8e45ecd, 0x247c0f70, 0x92d9f67a }, + { 0xf1078520, 0x62a505c4, 0x386d72e7, 0x4379a48a, 0x5c861e43, 0x82f93962, 0x0612ab98, 0x8e762b88 } + }, { + { 0x2b76d2f9, 0x219985b5, 0x48931209, 0x61e9b92c, 0x61b7df20, 0x3a5a19c7, 0xfb1cae89, 0x86e6fe6f }, + { 0x17a9e8bb, 0x24a69d1e, 0xb5fffedf, 0x645c05ee, 0xe465a371, 0x1cf0922f, 0x8e388d71, 0x6f7fb175 }, + { 0x539bb5ba, 0xa74025bc, 0x73a17687, 0x7e4034e7, 0x36a340a3, 0x3fc47343, 0x38c42333, 0x28e0a705 }, + { 0x60047445, 0x9b413b57, 0x22ad7abe, 0xd001a44f, 0x38564b8b, 0x3e430299, 0xa338d922, 0x3fdc8bae }, + { 0x10d5667c, 0x4b20b75a, 0x05c9d00d, 0x2436660e, 0x6d7bf446, 0xa8e4ab1e, 0x6ebc7ad2, 0xa80f7b71 }, + { 0xf82ad2d3, 0xdc4e138c, 0xb95a5c58, 0x135a2af7, 0x90e78650, 0xa05971b3, 0xfa7654e6, 0xeb040cb5 }, + { 0x7e55a09c, 0xa598b530, 0x66e2e492, 0x007cfbdd, 0x2a7340a3, 0x49eded4a, 0x8a2c5120, 0x745aec01 } + }, { + { 0x4ccdf6a1, 0x21cf2074, 0x70ee181c, 0x37614987, 0xdce26256, 0x388e8a20, 0x82e33a58, 0x1f8871a0 }, + { 0x9ac567f4, 0x2cab290a, 0x7a2940dd, 0x9d2921cf, 0xa7212702, 0xdba2aba3, 0x7b042b48, 0x2ea6c00e }, + { 0xb6602eca, 0xf1ccffc9, 0xa427b9e3, 0xce865444, 0xe955470c, 0x5c35353d, 0x886cd178, 0xb1154347 }, + { 0xbd7ee6c7, 0x986f0ceb, 0x515006d4, 0x928a9ef0, 0x3e19b199, 0x9e2b9d82, 0x2ba5734d, 0x78d35037 }, + { 0x8dfc34f4, 0x736270df, 0xae0c15e3, 0x039845bb, 0xdc0cdd6d, 0x8d629822, 0x115f4087, 0x0e40c8d1 }, + { 0x02d5be7f, 0x3b52feb2, 0xfdeb0f90, 0xf335fe9b, 0xc4ee02d1, 0xe1b0a73b, 0x973b1c29, 0x28608143 }, + { 0xd64024fe, 0x07bfee3d, 0x958b2586, 0x20c30d61, 0xfff7a1be, 0x1424dbb0, 0x41d63aea, 0xa7d2d7a5 } + }, { + { 0xc98697f2, 0x27a9da0e, 0xbe1c3c3a, 0x6015249f, 0x43310088, 0x25551fd1, 0x9ed53bc8, 0x01a59dbd }, + { 0x43b36f5f, 0x14d0c574, 0xb004b813, 0x0b342110, 0x8d8821bf, 0x2d460e2d, 0xdb423121, 0xe38d515a }, + { 0x0c48988e, 0xc75214a1, 0xe2d41374, 0x914e23e3, 0xffa76150, 0xf4d0d7a0, 0xf91f0d58, 0x5dbe80f6 }, + { 0xa1717fdb, 0x83473287, 0x5d83adb2, 0xce07c3f5, 0xd7b4bfd8, 0x802e2d18, 0xbd8d8aeb, 0x2a615f35 }, + { 0x281f4fc6, 0x3234cada, 0x034c9096, 0xad333584, 0x9e3d1089, 0x8d67adc8, 0xc73bb490, 0xb96d864c }, + { 0x81dfe927, 0xda7658b5, 0xe2b7deba, 0x28e959d4, 0xf976f0a4, 0x87efc7ad, 0xc8427d0d, 0x90ffa985 }, + { 0xce2e2e31, 0xdea7ac97, 0xe7d99d04, 0xb7b80fa3, 0x40c3196a, 0xa23ec559, 0xeec1dd8b, 0x50e94257 } + }, { + { 0x16823e73, 0x25e516fc, 0x9dd99658, 0xc3b2403c, 0xe96ada4c, 0x9445eea9, 0x0574f922, 0x8b0e0b50 }, + { 0x170a5242, 0xd545ee9e, 0x335d861c, 0x8a625319, 0xd06d63c0, 0xc1c65bea, 0xb289999c, 0x97fb323e }, + { 0xbdbf594b, 0x4563538b, 0xf6f5cb1f, 0xc3e7a6a1, 0x1de4a672, 0xca09428d, 0x5ad346d9, 0x5295de9c }, + { 0x7142b211, 0x6bf87d2a, 0xe77b09ce, 0x555dbb4d, 0x06b5dc50, 0x173c489a, 0x1b505203, 0x4fe9fd5e }, + { 0xd1eca554, 0xdbf55b7f, 0x4c58cf78, 0x57fd262d, 0x911d6812, 0x2dfe41cf, 0x09568fda, 0xb43f0161 }, + { 0x79e9f3ba, 0x7dc0c6f0, 0xca803919, 0xf2466fef, 0x71940a16, 0xc7d5d56c, 0xf379bba3, 0x8bbeb5e8 }, + { 0x6d78f71f, 0x57474240, 0xed1d6588, 0x0272b8fa, 0x42e317d1, 0xa6fe3539, 0x034ea5de, 0x91253223 } + }, { + { 0x6ce8fe52, 0x4ee4b0ba, 0x269731c9, 0xb1a91780, 0xc17611d4, 0x69ccbe77, 0xac119be5, 0x9761c6cc }, + { 0x800ebc6c, 0xd6d229c3, 0x66224169, 0x43ce27ee, 0x4e06d545, 0xd69a4e2e, 0xbe60d266, 0x2fbc0760 }, + { 0x04c13deb, 0xddcc671e, 0x940baff6, 0xed011b83, 0x1c65639e, 0xbf75ebb5, 0xdc29f3a9, 0x948a6594 }, + { 0xb6723312, 0xec575e5e, 0xc920d4da, 0xea1221c4, 0xa1c8f1ae, 0x6574c37f, 0x521325a4, 0xe5630b6f }, + { 0x9be8b91a, 0x34e5bae6, 0x94b150e1, 0x0a37a2fe, 0x93bc6749, 0xdc446168, 0xbd31bfdf, 0xea785db9 }, + { 0x433d561c, 0x1d8f451c, 0xd6821c12, 0x4cceace7, 0xd9f909d7, 0x05e270ae, 0xd959db7d, 0x26018b37 }, + { 0x78fbfb74, 0x864c7746, 0x7e96fc07, 0x3d73ae5e, 0x37117671, 0xab04044a, 0x7b2f215d, 0x5d34c951 } + }, { + { 0xd6e67082, 0xed83d10d, 0xf9b603c4, 0x330f14a0, 0xa2348071, 0x3d51d623, 0xbf803f9c, 0xf5c3a860 }, + { 0xdbf2e1fb, 0x3b9073d2, 0xa397706e, 0xaf6e444e, 0xd8be2c7a, 0x50917c13, 0xa6c15612, 0x1d2d723e }, + { 0xaedff564, 0x41062f20, 0xddbf7f08, 0x8ebe5ab0, 0xd2624d9b, 0x558c4f3f, 0x4fc8fdda, 0x030d8626 }, + { 0xe9f80171, 0xd04fc302, 0xc1a18b1f, 0x5175f1b0, 0x6b31de78, 0x489a4108, 0xc0f2a21b, 0x1da22bc9 }, + { 0x69c0783f, 0x468e72e1, 0x539684b0, 0x6eb35caf, 0xb2c8491d, 0x3461d505, 0x4008c3b8, 0x950079cc }, + { 0xf430e5f9, 0xc4af2bc3, 0x27a623de, 0x30b9f603, 0x9583a5d3, 0x0fe2d753, 0xb7192a77, 0x7672f83c }, + { 0xea036fc5, 0x8f910668, 0xfbb488e2, 0x4df1da0a, 0xcc8f5f0c, 0xe9cf02d8, 0x4ea68b8b, 0x92930726 } + }, { + { 0x4aafdde7, 0xad1e6f18, 0x6fc2b1f4, 0xc3c3bfbf, 0x28158ddf, 0xcab597d3, 0x0ee80ca7, 0xad689ef2 }, + { 0x31cef4a5, 0x2a0ac024, 0xba8befc7, 0x323bd99f, 0x0d4adee2, 0x741edb95, 0xc38ebf1e, 0x2e4bf40a }, + { 0x54731b39, 0x9c520b83, 0xd236cfc2, 0x8d28fed1, 0x595920b7, 0x9e64833a, 0xf9033166, 0xb791aa52 }, + { 0xb973e426, 0x031a763a, 0xc8a491a7, 0xf971a850, 0x29a57431, 0x9f98ab85, 0xe810c441, 0x1aaa9b17 }, + { 0xe07a56bd, 0x5b3a650e, 0x8524c1bf, 0x581b9853, 0x620e2528, 0xcbd9f18c, 0x464e0c76, 0xe8a8757b }, + { 0x4ba36244, 0x8dc29cab, 0x82dd5d98, 0x2e00d727, 0x1b403304, 0xcfb9ef02, 0xb23c2e18, 0x53272334 }, + { 0x85b8badc, 0xd3f3460a, 0x1f2d54d8, 0x6be53442, 0x4d3a4c57, 0xc6178f09, 0xdaac120d, 0xa21d32b5 } + }, { + { 0x5e7eec3c, 0x6882c2c4, 0xf71e281e, 0xee5a05db, 0x49160328, 0xa581f536, 0x999bcfc1, 0xa32183f4 }, + { 0x4d495226, 0x1d7fba98, 0xd63e0443, 0x1d3bbc2b, 0x63efb7b6, 0xb8fb692c, 0xf439fdd7, 0xb57cb60b }, + { 0xacbf8e52, 0x9b63af75, 0x555229a2, 0x01bff2cd, 0xf58b87f3, 0xb3665332, 0xc46db843, 0x522862e9 }, + { 0xeb3dd86e, 0x85cb0d88, 0x252ac387, 0x2c647271, 0x64f64274, 0x8aa0d8fe, 0x24c5c742, 0x6ba50abc }, + { 0xc049057d, 0xf1c1679b, 0x75366f81, 0x61691771, 0xef711e26, 0xb656c670, 0xd81e2e48, 0xf0e4b55b }, + { 0x8762038d, 0xc80e0c4f, 0xf30b867e, 0x19fadbdb, 0x9a6eb859, 0xc9901d8f, 0xa8c35c86, 0x7ab2b2d9 }, + { 0x3338cff5, 0x71256102, 0x5bbc92b0, 0xec61ecb6, 0xf8d91011, 0x085ae7d4, 0x8fd0eb3a, 0xe8afda76 } + }, { + { 0xc79d0663, 0x2dd58140, 0x0aa57d16, 0xf29eb584, 0xebffc367, 0xb5aaf495, 0x5f301fbd, 0x51ad05f3 }, + { 0x5d9e5289, 0x1f286da7, 0x1a8c5a78, 0x1981633d, 0xf535283c, 0x558fd1c4, 0x10042322, 0x694cf23d }, + { 0xb1b46bc1, 0xa366e94a, 0x432e1e2d, 0x29bd0258, 0x4c4a1386, 0xee6519ea, 0x8c1e7b8b, 0xe581d895 }, + { 0xf10c0f6e, 0x8b6ae220, 0x013190cc, 0x00648767, 0x3b7eaecf, 0xbd665c98, 0xcd8bb5e5, 0xcdca837c }, + { 0x855b26dd, 0xa4b21f40, 0x55f19d81, 0x683941bd, 0xe9d853f7, 0x5a251186, 0x8e63352d, 0xd93882fc }, + { 0x50196950, 0x3cc10d94, 0xdf247d3f, 0x7d6cd59d, 0xe2bdcfb9, 0x502f37e3, 0xf78c2b7a, 0xa29b4210 }, + { 0x82240993, 0x12a37c93, 0x9dce0ce4, 0xe532a6f4, 0xfcd872f2, 0x1e744eaa, 0xb68ded30, 0xa6e98a08 } + }, { + { 0x214bb8bd, 0x59052c09, 0xe306850e, 0x61426107, 0xcae574dd, 0x6f0d63ef, 0x36b7f4e6, 0xc4b1972e }, + { 0x44a5854e, 0x37506e54, 0xe43b0c19, 0xd89f4371, 0xad9b0797, 0xdae323b6, 0xfb38db63, 0x343a5bbc }, + { 0x4c3a1778, 0x38f81b63, 0x41e50711, 0x3273fbdb, 0x6cf133ab, 0x5fdbafc5, 0x7e62f53d, 0x8337b5d3 }, + { 0x577cc2c0, 0xf1740a61, 0x195f8d70, 0xc1be9818, 0xf6f046a7, 0xb22ff8be, 0x70434280, 0x9e969483 }, + { 0x7f54aff4, 0x29b2c1db, 0xb7932d31, 0x0e26725c, 0xa4ce3e46, 0xb8d03f15, 0xc1961766, 0xcbecbdfb }, + { 0x7b1da3e3, 0xd7091ce2, 0xd960bd1a, 0x24e3ee4b, 0xbccb3083, 0x9947ae94, 0x995b66c3, 0xfecdca8b }, + { 0x9efdb08e, 0xe6dd1bb1, 0x8afc22ba, 0x689c98ca, 0x5aa1d1e6, 0x9280486b, 0x1a06ff70, 0x35f3bd61 } + }, { + { 0x94a57dda, 0x34e514cb, 0xdba2cc3a, 0x5f80b789, 0x567d9dd8, 0x8e42abfe, 0xda4ed86d, 0xc3d85a78 }, + { 0x643a54ab, 0x64f1459d, 0xbe4f3752, 0x78e0c1fa, 0xd308c46d, 0x79e906cc, 0x9ee16ad9, 0x077f4792 }, + { 0xb17b2cb4, 0x7b1893a0, 0xd513db0f, 0xd05a576f, 0xc0cb40f5, 0x4d7f6b17, 0x89869ade, 0x3ef3f6ae }, + { 0xa8f1033f, 0xb5fd68fd, 0x8b1a8db3, 0xb191a33e, 0x353afd73, 0xeab792ce, 0x2ccac580, 0x3901d267 }, + { 0xe945d74a, 0x5a35669a, 0xa3e4a8ce, 0x7c09320a, 0x9d6a6e73, 0x839886a0, 0x0e87039a, 0xd4afcfe7 }, + { 0x35cd99c9, 0xd0e5ea21, 0x7aaf6e80, 0x28a91f14, 0x0441f916, 0x3bcd7836, 0x5f8c06b8, 0xf6d2804b }, + { 0xab421ed4, 0xf564b8c9, 0x03a9e168, 0x98c0e130, 0x9cd0b92d, 0x3c212ef7, 0xcd6eab71, 0x295b1bd6 } + }, { + { 0xe3e9bef3, 0xd7078eb9, 0xfa2d0da2, 0xfaebbc87, 0x4d66df4f, 0xd1655e36, 0xa6b5f78a, 0x3f7c7c98 }, + { 0x1e7cddbc, 0x17a3975a, 0xde48e2b9, 0xab04c4a3, 0xbf5bc034, 0xf7a44143, 0x5ae8fa9c, 0x3cb216d4 }, + { 0xa019805f, 0xa77c68ee, 0xf27890d8, 0xd67c0c27, 0x06cd297b, 0x525f68e9, 0xd994da58, 0x8672b823 }, + { 0x25936f1d, 0x764ff4c3, 0x89a06966, 0x2a1f98bf, 0x075af8ea, 0xa404022e, 0x959f5c8d, 0xa3959fd1 }, + { 0x9000b509, 0xe18ff73a, 0x7baefdee, 0xec7a734e, 0xb432ea34, 0x8ef1f3d5, 0x2e367966, 0xfcc949cd }, + { 0x414a9e4e, 0xddffb7d9, 0xa4b135c0, 0x08df6e92, 0x7f7978fc, 0x94231a01, 0x38020d36, 0xfd92eba4 }, + { 0x759e8e7a, 0xbd0732bd, 0xbddea280, 0x58540b21, 0x7dc30c3e, 0x3d973558, 0xaf1b393f, 0x51aef09f } + }, { + { 0xd42396dd, 0xe4fc4aba, 0x65bc2ccd, 0xbf3304ca, 0x102ba45d, 0xcece783d, 0xe822c515, 0x20ac124a }, + { 0xe3a2ed92, 0x540fbdcd, 0x3f9dbd6d, 0x9433f437, 0x397752e1, 0x405d2a30, 0x39fdda96, 0xef8289f9 }, + { 0xca813a68, 0xa7ddb8c6, 0x547fb559, 0x34e56453, 0xa126ff41, 0x17de4c37, 0xf5dbee4b, 0xaf01f51a }, + { 0x7076cd0c, 0x5f821a2a, 0x04d3eea6, 0xb2337628, 0x5007b53b, 0x99aba859, 0xfe51ab35, 0x84947d16 }, + { 0x49c1c968, 0x4c48f0f3, 0xed1bfa43, 0xfb7d0f41, 0xf0ae229c, 0x89da4d80, 0x6dd79b29, 0x5e00c5ed }, + { 0xb0082f0a, 0xfa0f5285, 0x7283e3b2, 0xb0525247, 0xa6891967, 0xca18af05, 0xd39acddb, 0x8b6dcece }, + { 0x75bd1834, 0x2370c61a, 0x97219a21, 0x1e1d5e8c, 0xd2c13a0b, 0x5118e51a, 0xf0c505cc, 0x375a4fe0 } + }, { + { 0x3d5b5b5b, 0x0589f6d5, 0xa3c37341, 0xd670ef28, 0x9b9fdb69, 0x645e417e, 0x34b4aae4, 0xf765eab9 }, + { 0x4624f839, 0x15dad0fc, 0x9111f388, 0x55c88aaa, 0x442ffbd8, 0xbe495f3d, 0x44ae469c, 0x30de013b }, + { 0xaac2eb7c, 0xe5794d57, 0xa0ca448b, 0x6a1210e0, 0x7c679e81, 0xf7ffbea7, 0xde3946f2, 0xa9eca4ee }, + { 0xc9f4e052, 0xf416895a, 0x0cb616bc, 0x12e5cfc1, 0x92ed36ab, 0x7c81330e, 0x4f0efa6c, 0xe2c49453 }, + { 0x6c459920, 0x62714bf8, 0xb8a261e3, 0x053756e7, 0xa42cc894, 0x9eb30492, 0x56800cac, 0xb907900a }, + { 0x5f24390c, 0xd7e25199, 0x092cd43f, 0xfe2e825c, 0x9fff7769, 0x09b2696b, 0xd9a104d4, 0xc27fc111 }, + { 0x8adb1b35, 0x12a267f9, 0x4523b897, 0x66eaaa9d, 0xb9676202, 0x46367165, 0x866f6ddc, 0x8a8578df } + }, { + { 0xd973534a, 0x9229bdd9, 0xf870bc7c, 0xaa8aee13, 0xa10181a1, 0x10f5d3e1, 0xb70bcaba, 0x8af542e4 }, + { 0xdc2609ae, 0x5efaa091, 0x36bde5f7, 0x6f6562fe, 0x847fac9b, 0xd4e11101, 0xcdd8ba8b, 0xe0314e9e }, + { 0xcb64a375, 0x8b1d9dc1, 0x63e83023, 0xae29b9b0, 0xdc501c4a, 0x526ebc1f, 0xb4cb680a, 0xe55b8753 }, + { 0xd06b0247, 0x84203428, 0xcf2f04c3, 0x30e549ea, 0x07526bef, 0x4e70b090, 0xf8eff8e7, 0x247c5e1d }, + { 0xe3ac7058, 0xcc88d2d2, 0x1b34d2e2, 0xb6f23bd8, 0x6087dcfe, 0x329cc986, 0xd03984a0, 0xd10a2c00 }, + { 0xb3c8a556, 0x332e4152, 0xe06e0545, 0x3bb6b291, 0x2eeb5851, 0xaa1f5c5c, 0x869490cc, 0xa895bb2a }, + { 0x1d7fcbfd, 0xb9c86437, 0x641aceaf, 0x30e395db, 0x43cd9993, 0xed4a0f7f, 0x05a4ade1, 0x8a174e00 } + }, { + { 0x06f6c8f5, 0xaa7b65e7, 0x824883d1, 0x0426a4de, 0x17eb4593, 0x582897a3, 0x0d97066d, 0x4d6a6207 }, + { 0x7b6c49c5, 0x8a8cf0c1, 0x7cfe2755, 0xf3107513, 0xf6f4810b, 0x3e4e07bc, 0x1d8f6691, 0xebabbe33 }, + { 0xcfefe6f2, 0x85c9c6fa, 0x8627fefe, 0x51f8f2b6, 0xae0b9e9d, 0xe9ec84ae, 0xa5eee553, 0x8c89d70b }, + { 0xf46e9a45, 0x79319572, 0x6deab445, 0xfd1d2456, 0x7bb0ee16, 0xdb4bb4f4, 0x90f34afd, 0x5504ecf4 }, + { 0xcdffaea5, 0xdce1d9ca, 0x7c1a656a, 0xeab322a7, 0x38cc7850, 0xcdf0ae68, 0x91eba6bb, 0xc3422707 }, + { 0xb707b5c7, 0x51aa0c8a, 0x0d3915d5, 0xd5d3a321, 0x17eca512, 0x711135b9, 0x02a41edf, 0x0730519b }, + { 0xb6a57c9d, 0x00832995, 0x2cfb27e7, 0xfe9ada6a, 0x7b53f507, 0x934fad67, 0x040ea387, 0x32b1d122 } + }, { + { 0x869f3699, 0xb7a0f364, 0x2a224e69, 0x219fa3df, 0xbb5b43db, 0x85a3ee48, 0x0f3b20d3, 0x530b39b1 }, + { 0xce48e6b2, 0x5eb8caef, 0x906856ed, 0x10015a5b, 0xde1a90ae, 0xc5e20921, 0x535a150f, 0xd598d4df }, + { 0xb8f11262, 0x58784fb1, 0x65de8c60, 0x181f3950, 0x5eff1757, 0x2307d418, 0xf435b9a7, 0x3b480d73 }, + { 0x887329c1, 0x0fe1c5fc, 0xe5343697, 0x3b8f7c71, 0x9d796838, 0xb60ac1fe, 0x3efb57ad, 0x1a3cafc9 }, + { 0x33e228b4, 0xc45a4a97, 0x5c0d163f, 0x4723ff85, 0x901ee6e8, 0xa556fcd5, 0x653dacbe, 0xcb039bba }, + { 0x1c1a4895, 0xddbd9d3b, 0x6305c0f5, 0xfcdb872e, 0x1c8cf92c, 0xc905dcdb, 0xd12f12b3, 0x8a08cf36 }, + { 0x36366045, 0x1b00aa3d, 0x275996ef, 0x185a2d1e, 0xf1a5d3aa, 0x097b2a88, 0x316a8a21, 0x3e88ecd2 } + }, { + { 0x04dfd426, 0xd8457dcb, 0x611c6c3f, 0xab0594cf, 0xb56df625, 0x46d51ff2, 0x76322d50, 0x00661fde }, + { 0x0117c123, 0x4a1234e4, 0xdaceaaef, 0xda0de23b, 0x4c68554c, 0x89708fd9, 0xb515bb8a, 0x303e5c75 }, + { 0x74349f95, 0x0ddaf2c2, 0x2ab299e0, 0x4fcb2065, 0x6f93ade4, 0x61258430, 0xd2a529ab, 0x66831f66 }, + { 0xf0823bc7, 0xc4b97ff5, 0xd4654764, 0x488ddf0b, 0x00bb1d8b, 0x40e80366, 0x33f7997b, 0xf0022f6f }, + { 0xcad79cd9, 0xf77b16db, 0xadd94936, 0xf8a210e9, 0xde1f34ae, 0xa9b09c22, 0xf934bbdc, 0x76891837 }, + { 0x9b543cd4, 0x46aeee91, 0xda445bd1, 0xedcf72fb, 0x86b1e7e2, 0x214a30fd, 0x5f67a563, 0xe77fd81c }, + { 0x56ac0d36, 0x84f516fc, 0x548bc83e, 0x62e00da0, 0x9736c949, 0x4a62c624, 0x254f3bcb, 0xa63e272b } + }, { + { 0x4ce55c56, 0x52e60ad7, 0xeb3194ce, 0x50384fed, 0xaa0b71be, 0x5aec83a4, 0xb2e5bb6d, 0x5f4b87b5 }, + { 0xfb6bf270, 0x989eefb7, 0xbe447eb2, 0xee56d6b2, 0x0fb602cb, 0x74dc6a16, 0x6708393e, 0x299cfcce }, + { 0x5983adae, 0x7170c129, 0x5ffd2fe4, 0xc7c51be4, 0xab4db93d, 0x9b13f8a1, 0x0576e1d5, 0x0133b97f }, + { 0xd330c619, 0x97cefae3, 0x08a51e25, 0xff52936b, 0x2bb317e6, 0x8e410395, 0xa2abe512, 0xe560f31e }, + { 0x91e0085c, 0x707fb7a8, 0xe5e921b9, 0x75f44359, 0x3a7d4dcf, 0x1d8c9b2c, 0x4f0beacb, 0x7f47a8af }, + { 0x3c39c379, 0x3844ef9b, 0x980fcd5b, 0x1f827adc, 0x3606cc65, 0x027406aa, 0xbb92a12a, 0x4d820976 }, + { 0x61c9b499, 0x0af292b3, 0x4dc48844, 0xd75639ec, 0x6b47ba27, 0xe9b8232f, 0xec2bfc5d, 0xd48772c3 } + }, { + { 0xaa3a7768, 0xa9923913, 0xc9a4253f, 0xf9d54a62, 0xb461a77d, 0xca4cffa1, 0xcc7d6220, 0x7bbe40c3 }, + { 0xcb7b1279, 0x4e37b168, 0x0e2fc824, 0xe0bba404, 0x045bfb7e, 0x9c058a66, 0x7b76ad22, 0x4f4fa3ce }, + { 0xc1e03d01, 0xd6dc7650, 0x3d4d4b28, 0x255b5d53, 0x3cbf2f49, 0x8dfeac4f, 0x86b7cb23, 0xb6d9cef3 }, + { 0x402b43ed, 0x39c30e4f, 0x09c662c9, 0x04e9881b, 0xf70d86c2, 0x9b1a752a, 0xb8a59b39, 0x29885a2d }, + { 0x035473c5, 0x2ed39e06, 0x86c4bffd, 0xdd4ffb36, 0xfd87b924, 0xc420e0d8, 0xed1e4957, 0x7c8100a5 }, + { 0xacc88481, 0x143f7290, 0x2448e118, 0x923bd5cc, 0x0c41c4f2, 0xdf9301d1, 0xce90119c, 0xcbdc928c }, + { 0x4780f6d0, 0xc6c88d50, 0xb28ed989, 0x675eb0a9, 0x8006b4d8, 0xd4c94d1a, 0xc708fbfa, 0x558611e9 } + }, { + { 0xcafcb6c5, 0x742d27cf, 0x326d8490, 0x0c932a56, 0xc6fa5228, 0xf9a43400, 0x9c15e051, 0xfaf1d7db }, + { 0xacf2dcbc, 0x85abeee9, 0x0ec49808, 0xfe7dc863, 0x1e263e23, 0x04d681c6, 0x98a9b7b3, 0x2ad596c5 }, + { 0x0caa2751, 0x846dcb5c, 0x04b85d6b, 0xe8b0bf65, 0xe45cbd45, 0xe65f8e88, 0x62162b5f, 0xf7b03b5b }, + { 0x7e02448e, 0xc18cbf2e, 0xa8f00089, 0x1297fd3c, 0x224dec7e, 0x985bc5d0, 0x014f4cc1, 0x02344936 }, + { 0x7470bf5a, 0x5d4f9515, 0x8877fc67, 0x6af5878a, 0x06004ece, 0xf846c5be, 0xa27d7ba8, 0xcc1b1636 }, + { 0x8a6f7afd, 0x9e55b768, 0x1abbef11, 0xe2dc66cc, 0xb4fb3c41, 0xbccdc9f8, 0xa94bab38, 0xfe515287 }, + { 0x54eccc0f, 0x7d33ca23, 0x616aab17, 0xad32de5b, 0x24823796, 0x5348c258, 0x5143c9d6, 0x55941476 } + }, { + { 0xff926d03, 0xdfe6bd0b, 0x7133d012, 0x1730d8d4, 0x4e2a9b71, 0xf42bd662, 0x2babb7fa, 0x75b93b24 }, + { 0x25c6bb3a, 0xfd0de901, 0x06bfe425, 0x5476eceb, 0x9a8e9974, 0xab6eb44a, 0x01d3d3c7, 0x6ab3381c }, + { 0x897fd029, 0x92aa33fc, 0x636c8893, 0x45bfa236, 0x9e494c98, 0xaad0920d, 0xce1e1ad0, 0x0ec52f2d }, + { 0x05da4481, 0xef53168b, 0x589201bd, 0x27c04b7c, 0xfae00f06, 0x226672f8, 0xd2a24848, 0xdb48b2a5 }, + { 0xaf1e6e52, 0xc0d66eb6, 0x716f6f84, 0x2f993a9f, 0xe08a9bf1, 0x0ba346bb, 0x07796a53, 0xa90c0e4b }, + { 0x30eca339, 0x1f6171b3, 0x513e7e27, 0xab1a77bb, 0xde3c1c49, 0x2696bd6f, 0x91631039, 0x3b8a1b4a }, + { 0xb8384d6c, 0x856458a6, 0x8ca3805a, 0xae1937b4, 0x7a23ec5b, 0x24237653, 0xf7dd0b6f, 0x1e6b5437 } + }, { + { 0xdd201ef5, 0xc7bbae08, 0x04aa9b04, 0xda770b53, 0x1dc59e72, 0xd1055c4e, 0x0db15e0e, 0x8e5ea443 }, + { 0x629137a5, 0xbc9f5510, 0xc526680d, 0xd1be741f, 0x578e2a7c, 0x6297930a, 0xa9ef7a5a, 0x81607f43 }, + { 0x4f322772, 0xb6c64f9c, 0x5d99f6c8, 0xf2b683e6, 0x50f7add0, 0xa31cc440, 0x46688ddf, 0x87e0b044 }, + { 0x19ba3b0f, 0x9c252df5, 0x2b3c7363, 0x22f61964, 0x7ec403a5, 0xf60b0224, 0x6b32ccf0, 0xca66258e }, + { 0xb1c7df24, 0x82ba09e4, 0xefd34517, 0xa137d1c1, 0xbf986d1b, 0x632567ac, 0x10af96e8, 0xd3619154 }, + { 0xac8e70e8, 0xf51bb0b8, 0x9cb7a9b5, 0x4e154450, 0xd1cdf7a1, 0xd3cc4aeb, 0xa3be7bdb, 0xbc602064 }, + { 0xa727791f, 0x4c937102, 0xac298cd8, 0x1ca7a882, 0xf4ad2dbd, 0xa1226327, 0x37d216ab, 0x1963ff50 } + }, { + { 0x883173da, 0x23e6fde8, 0x5cb323a4, 0x7f64be00, 0x904d3e49, 0x50bf674e, 0x6a5d7369, 0x271c1ac8 }, + { 0x6d12d716, 0x1e4aa290, 0x83148617, 0x4a57d1b2, 0xd2d2eb56, 0xfa59047b, 0xcc42aa9c, 0xe75139be }, + { 0x4ce3057f, 0xa14696c9, 0x3df0a01f, 0x0a4347ce, 0x0e761790, 0x56107292, 0x4237b7c4, 0x8bc97af6 }, + { 0x1e8fe687, 0x0827af6c, 0xce989c8c, 0x5625e561, 0xd3fd9e62, 0x24c80381, 0xd393ffc8, 0x26156972 }, + { 0x9cec5f14, 0xb1d5591e, 0x740ef0ee, 0xcb0582c0, 0x84db94ac, 0xc9d0550d, 0x23974ba9, 0xfd225a78 }, + { 0xfc02f9db, 0xc65d470f, 0x4af43a3f, 0x048f5be8, 0x8844b325, 0xc224c1ff, 0x29a88a71, 0xae3bbe8d }, + { 0x14577832, 0x9b6e8d7a, 0x424c193c, 0x6c8ec12f, 0x648e40a5, 0xb3072ba8, 0x952a1e03, 0x01a41c9c } + }, { + { 0x4f9e89c9, 0x059bd6bc, 0xe1724241, 0xb8390db8, 0x6264bd07, 0x7286e102, 0xafe24351, 0xec4d8f15 }, + { 0x1efb82dc, 0xb2d37a8a, 0xae9d98db, 0x22b12e63, 0x2f2f20f1, 0x0671e722, 0x602efc49, 0x285e1eb6 }, + { 0x36ae4c87, 0xa69d53e9, 0xc7e9a3d1, 0x9392a787, 0xeda31c1e, 0xebdced8a, 0x1bb574ed, 0xfc0ffba5 }, + { 0xadaf5b7e, 0x3cbec253, 0x08d4e073, 0xa6ca7185, 0x817749c2, 0x08e552e1, 0x89478771, 0x09fac11a }, + { 0x4d1b95e6, 0x19ab29b6, 0x0df3377e, 0x49df1272, 0xf574298a, 0x5cdeb60f, 0x8b97defc, 0x7da8ffa9 }, + { 0xe22919aa, 0x2b102fea, 0xd6de0fa7, 0xd82fd943, 0xad3fb73e, 0xf314097e, 0x3ffbcb8d, 0x2a2b479c }, + { 0x5c11cdd8, 0x367b92f4, 0x6b4ee87e, 0x81f554b2, 0x046b41d1, 0x4985a82a, 0xc004855f, 0xad1de15a } + }, { + { 0xe7169f5c, 0xbd1ba144, 0xc149b708, 0x7f54185e, 0xbc204785, 0xef6fbccc, 0x68fd45b8, 0xe8932dfd }, + { 0x698b48ce, 0xd2108117, 0x0e82895e, 0x2e1e0f83, 0xbe2640fe, 0x24264ae9, 0x480d9483, 0x058f8811 }, + { 0x0745c2c0, 0xa5de3147, 0xbe466299, 0xd749825a, 0x0d3cb5de, 0xf85ed138, 0x64c07737, 0x95ce0552 }, + { 0x1ff9c508, 0x3afd6c4e, 0xb7158c82, 0xb388f9f0, 0x2a7ff5c4, 0x99a6689a, 0xb4af8235, 0xb1054152 }, + { 0x2b457c79, 0xec319ebd, 0x3b0dfef1, 0x27bbe811, 0xc9088a0f, 0x0156537c, 0x3d0c8922, 0x31004ac8 }, + { 0x182fe7e2, 0x4aa600b3, 0x9380201d, 0xc7c52130, 0x96539850, 0x79e9742a, 0x2046af9e, 0x5bf607c1 }, + { 0xd96c4bb2, 0xcffd6dec, 0xab6b7d91, 0x4180ad19, 0x608ffe33, 0xdf7806d1, 0x7591cf11, 0xb77318d8 } + }, { + { 0xbd0c6ae1, 0xb0c0d491, 0xe6879544, 0x84d9d47e, 0x0a3c547a, 0x31c255ee, 0x5d8cf93a, 0x51e796eb }, + { 0x7ed47493, 0x47b333f8, 0x13c4aa35, 0x3f50b35e, 0x67d9770b, 0x481196b0, 0xe6169cbd, 0x0822fad8 }, + { 0x373cab1d, 0x414bb7bc, 0x4fcf49ff, 0xba1470dc, 0x52fda29d, 0x28fee38e, 0x2f09b1a1, 0xac6bf20f }, + { 0x018deff9, 0xd940e676, 0xde860481, 0x1ed81388, 0x2e321995, 0xd381c800, 0xae39aec6, 0x5c1e0964 }, + { 0xc4f62878, 0xa400869a, 0xf29f2e90, 0x9ac2b169, 0xe64aed0d, 0x68f182cd, 0x4e71336f, 0x4e647b8a }, + { 0x0b500d5e, 0xbac12fa9, 0x96544435, 0x04b74dab, 0xab2d04cb, 0x241588b2, 0xa111b1bc, 0xa36bf9f2 }, + { 0x19dcc2a1, 0xf91ff95e, 0x17d421f3, 0x35834062, 0x1a52ab19, 0xfc73404f, 0xcd4face9, 0x4e65a9d0 } + }, { + { 0x7d905776, 0x7fa64df4, 0x819bf900, 0x46b0febb, 0x9c3b9149, 0x20faae1c, 0x9a93a9f0, 0x4823f136 }, + { 0xdee292fa, 0xee9dbcf7, 0x77d20122, 0xad71d94c, 0xc5f8156d, 0x415f40ad, 0x15ce83fb, 0x55d7c6aa }, + { 0x31ec30aa, 0x722c93e8, 0x68b618a3, 0x1a9e450d, 0x10f91b46, 0xa1ae7c50, 0x36d06874, 0x19cbca27 }, + { 0x3006b80c, 0xd07fc788, 0x0a3b47ed, 0xd52f127b, 0x54588daa, 0x946a4177, 0xa72ec354, 0x1a420308 }, + { 0x8eb890c5, 0x3627eb6d, 0xbfc0dbea, 0xa7a0ca38, 0xe150be82, 0xbebac52c, 0x2fe40cc8, 0x68014ffc }, + { 0x4baaeec0, 0x959d80a2, 0xa4d3c4be, 0xc8020043, 0x5d3789ee, 0x9de0226e, 0x7ec985f6, 0x7a1729f4 }, + { 0x1ffcc6d1, 0xce7d6162, 0x589492e2, 0x774eb246, 0x7f84649b, 0x1f30ad87, 0xebd3736d, 0x66b45d24 } + }, { + { 0x2bfdc739, 0x4435ff09, 0x5abf9a09, 0xa09ba351, 0x23039ed1, 0xf08274f3, 0x44366513, 0xd145df3f }, + { 0x54e6ed6b, 0x5560f57e, 0xe7b1923c, 0x9a1bd173, 0x8257b048, 0x8c391d84, 0x71d63d0e, 0xc43c537e }, + { 0xaad32313, 0x8effced3, 0x1be1fbde, 0xb6810c2a, 0x1d05f895, 0x78785c2b, 0xb3e93cac, 0xcb1a970e }, + { 0xcc379fef, 0x53ba81f1, 0x4479294b, 0x82f4602b, 0xd7bb3747, 0x28218975, 0xa21d5880, 0x1c5e6a04 }, + { 0x96d20a1d, 0x17472cfd, 0xfdd4feb4, 0x7b2e351e, 0x294d3cca, 0xac0a72cb, 0xff199aa4, 0x897afb32 }, + { 0x00eb79ed, 0x86b45ac1, 0x1c661135, 0x39ce9c2b, 0xbe5d6bee, 0xdac61f22, 0x92b80578, 0x94e611b7 }, + { 0xd2e5ca47, 0x520e5d56, 0xca015d2e, 0x17682243, 0x44fa80d4, 0x7fcb5ed9, 0x93b5da78, 0xbe5a1e6a } + }, { + { 0xf64e7bb2, 0xf1b40d71, 0xdb95a0cf, 0xa7427a13, 0x00eeb19f, 0xbfe4dfc8, 0x81c86d91, 0x5dea2b64 }, + { 0xb4a2432f, 0xd6b9ac8b, 0x40edf752, 0x34c85473, 0x460084d7, 0x8f057c59, 0xfc69f8d1, 0x1a5821ec }, + { 0x30c6d9e9, 0x4592b470, 0x015100a6, 0x6088ca9a, 0x9078c364, 0x3f74ce1e, 0xe3a99e5b, 0x49ff4ed1 }, + { 0x2c22243a, 0x76105001, 0xc5dedf8b, 0x5899cee5, 0x0fc4aa65, 0x8cea7e5b, 0xbad31416, 0x9fd5e8cf }, + { 0xffde96b8, 0x2cb2513f, 0x69bdcb75, 0xadda751a, 0xfc878284, 0x41eeec31, 0x32be6996, 0xf338aa41 }, + { 0x08afd0b8, 0xf634fc79, 0xedfdecb7, 0x189835f8, 0xf36edfa9, 0x1bc64382, 0xa9d0062b, 0x48c5ca1e }, + { 0x74828ae8, 0x61347f83, 0x8d1184e9, 0x8ce93f98, 0x77063d03, 0x25d91ee2, 0x734dda1e, 0x0bffe123 } + }, { + { 0x48cd2249, 0xda5e265a, 0xea457dde, 0xfab3845d, 0x07c87c47, 0xf142b310, 0x619974eb, 0x3fda1991 }, + { 0x32deee86, 0x7d3c5f5f, 0xe6083af6, 0x712a9911, 0x02e92d1c, 0xa867c00f, 0x60448c43, 0x94d3ed65 }, + { 0xaa7c3f13, 0xa6da91ef, 0xa90d6687, 0x00750ad2, 0x077fe68f, 0xac66be1c, 0x4700d554, 0xb5f6b43c }, + { 0xb7a0240b, 0xe2e23986, 0xc9475212, 0xc601e7f2, 0x7da3f5b2, 0x0bd4f294, 0x88d75e02, 0xd20e2a9d }, + { 0xf4afece9, 0xb9be01f4, 0x4010957c, 0x8047cd65, 0x81e53b5c, 0xb5bdd825, 0x67f2ed52, 0x09f6c6d5 }, + { 0x838d9fd0, 0x0f0d2641, 0x90a2f8af, 0xf32ec1fa, 0x5bc2d3a9, 0xf8aab816, 0x31e03159, 0x9b74c12c }, + { 0xea6777b6, 0x4ffc3392, 0x62588020, 0x12d1984b, 0x0b5ee289, 0xa9328408, 0xc2f7c7f9, 0x024d72fa } + }, { + { 0x2e4869ab, 0xc983b221, 0x53e81011, 0x40971816, 0xef018c8e, 0x899ef941, 0xb57ad0d6, 0x4623643d }, + { 0x844ca100, 0xf6f30c97, 0x4e55c01c, 0xfc33b704, 0x80032170, 0x87f69c86, 0x0bd0351a, 0x1cae03fb }, + { 0x8c7fde9e, 0xb35c205b, 0x713bfa73, 0x18ce5013, 0x224e587e, 0x7384805a, 0xf74734c0, 0xaae6e9a8 }, + { 0x4b901787, 0x9ea2deb2, 0x2318f61a, 0x7cb7fd28, 0xed12db62, 0x0404e851, 0x4a40222d, 0x923c2bb9 }, + { 0x3857637e, 0x56e215f6, 0x0de5907e, 0xbef391b3, 0xa3a6b9a7, 0x4b69f44f, 0xff010423, 0x234456b0 }, + { 0x849d6444, 0x28a7d0ee, 0x56ec8fed, 0x949f5897, 0x78ae1368, 0x1603c679, 0xfc15c6e8, 0xc2684a29 }, + { 0xdcf9a449, 0xa31c2276, 0xd678c269, 0xba89cd2f, 0x6b0d0715, 0x4b83c765, 0x6daef79d, 0xf4924608 } + }, { + { 0x4815cda0, 0xbdb17fc1, 0x09ea48d1, 0x882839be, 0x17ac3f03, 0xe1991523, 0xc4a38292, 0x8fa8750d }, + { 0xf409da81, 0x804715e9, 0x69ee1c33, 0xee5eed67, 0x4be92654, 0xfbc93307, 0x8538da2e, 0x8e0ae979 }, + { 0x5db8c378, 0xfecf36f9, 0x438c7445, 0x4b4a9cc9, 0x4367e325, 0xcbb85d85, 0x8d072360, 0x2b3080ae }, + { 0x0d2f6168, 0xbc3e881e, 0xd99d9a78, 0xf68f3a05, 0x3d5ac3ce, 0x5b16c5a7, 0x53401e75, 0x30800a49 }, + { 0xe037731a, 0xbea53cd0, 0x5d9da59f, 0xae83f24e, 0xb38823c4, 0xa09a0710, 0x34c2013b, 0x968d9192 }, + { 0x2755ef23, 0xfbb66fef, 0x5535a324, 0x6bb8de77, 0x79b3663a, 0x67c99d31, 0x550e7333, 0x7681b6d2 }, + { 0x7bb74e2d, 0x621c9ae6, 0xd2b20ed1, 0xc5df49b1, 0xb8f9304f, 0x56d1addd, 0x3d72cdba, 0xa35798dc } + }, { + { 0x5f50103c, 0x3b5a6c15, 0x3b70314e, 0xace5e6fc, 0x4d252093, 0xb059d352, 0xb46aba2e, 0x4e72733d }, + { 0xe59b2322, 0x17c297db, 0xf5e29f26, 0x54468a74, 0x2b764c9b, 0xb5f79e65, 0x965b9355, 0x5800a03f }, + { 0x4cf1dc9e, 0xab50c859, 0x446a4dd5, 0x42bc5ad8, 0x446b5c6a, 0x386b2e7c, 0x026357c9, 0x6ad6f0cb }, + { 0x004569f1, 0x24848ddd, 0xced6a93d, 0x2d3f3706, 0x22e40924, 0x039c749b, 0x8f2c5ea8, 0x3f95eb08 }, + { 0x50000280, 0xc814deba, 0x22afacb7, 0x408b4d3b, 0x759bf8b8, 0x3b41eee8, 0xdac665ce, 0xd0780982 }, + { 0xba30fb96, 0x2d94c9ec, 0x9ef85da1, 0xdd074fab, 0xda4e3e35, 0x14634d91, 0x23cbcf31, 0xbba66b2f }, + { 0x0b3ba8d0, 0x7a1aebd5, 0x7638bf10, 0x19e733a7, 0xe34ff3bb, 0x50261a8a, 0xb20d5612, 0xfe940b6e } + }, { + { 0xd63a19ea, 0xeb41d895, 0x876b5431, 0x86fbf81d, 0xfc6f5595, 0x950fff97, 0x267557cc, 0x92c57011 }, + { 0xecdb9bb9, 0x92ad8656, 0x93a731f6, 0xb9a97049, 0xf38abb8a, 0x4f131ffe, 0x755c3348, 0x16e2e197 }, + { 0x426f4d85, 0x85128517, 0x47457713, 0xf2a15d59, 0xa4bf5ecc, 0xbd44e847, 0xbaa98231, 0x0955ee08 }, + { 0x2e922b59, 0x8c0c392a, 0x1ef50af9, 0x45b3e3de, 0x02b73ed8, 0x2716a4e1, 0xd23635ec, 0x4062053f }, + { 0xfaa7f367, 0xd78f6c19, 0xdde9b489, 0xaf6513e0, 0xa724dadd, 0x202f5a3f, 0x76c9ad50, 0x62881aa2 }, + { 0xcb824d3d, 0x706148c1, 0x03231057, 0x61d54219, 0xed6e6793, 0x87eefe17, 0x72fce986, 0x562a33f9 }, + { 0x436c7be4, 0x547594e3, 0x845d596e, 0x782ba5b6, 0xefda9b4e, 0xf6c210be, 0x1796b5b8, 0x0444e2fb } + }, { + { 0x8541ab7f, 0xd1b0e586, 0xf12ea8a1, 0x4f291370, 0x39de3b5c, 0x63e42dca, 0xef998a83, 0x1bb2333e }, + { 0x130b07b5, 0x8a38e897, 0x99a0eb59, 0x778e5692, 0x57afb592, 0x5f85e4c7, 0xb7875c51, 0x71cf79fa }, + { 0x3c6d915e, 0x0e17fed7, 0xbc4514c9, 0x2c31f4bd, 0xea4aefa7, 0xfc78db3d, 0x502629fa, 0x41f3ff82 }, + { 0xc327b68d, 0x4db9d88d, 0x5afee674, 0xd4b26a8c, 0x6b7db1c6, 0x7966ee34, 0xbd07f9c4, 0x28f71f45 }, + { 0x3f5870f1, 0xe2c1b710, 0x36feaab9, 0x32382d56, 0xf69eb850, 0x954f57e0, 0x1a7a366b, 0x3358d575 }, + { 0x4d0a3a33, 0x54021251, 0xf441d96a, 0xd494e299, 0xc9c0be8a, 0x933c0b97, 0x39ad3fc1, 0xb8840efb }, + { 0x11674a29, 0x967f5f77, 0xb9c38bf8, 0xff62f9f1, 0xb54850ad, 0xbfd48d6c, 0x0a97a581, 0x692dc8a1 } + }, { + { 0x2f63b101, 0x517395d8, 0xdc9b2abb, 0x37356f76, 0xfdac7227, 0xeee6410d, 0x9def4dc6, 0x0beade21 }, + { 0x457c3793, 0x20e82c09, 0x110010b6, 0xa91cab27, 0x6dfc2639, 0xd3afca3b, 0x025a8857, 0xf0c763fc }, + { 0x9ebc194b, 0x72548a07, 0x3cca529d, 0x66cb1887, 0x7604a020, 0x4aa9790f, 0x12f87e77, 0x7d067c60 }, + { 0x4d00b201, 0x219844d9, 0x6d629485, 0x490e8962, 0x44b0d0ee, 0x6e97d450, 0xf0f86ba9, 0x5dd95c69 }, + { 0x0b62933b, 0x9c5100a0, 0x13bcb065, 0x3ed52fc5, 0x07663012, 0xda3a999f, 0x902748f3, 0x00122aef }, + { 0x1eabbd9d, 0xb9d236e6, 0x42512a95, 0x025ede3a, 0xf8cc871b, 0xbb908f25, 0xee0d53bc, 0x8dc61a47 }, + { 0x6dea9030, 0x1374c6e6, 0x1ee4bbf7, 0xf9c87cad, 0x3cb23226, 0x94a5b971, 0xe1b6378d, 0xeae9e8e6 } + }, { + { 0x580441d9, 0x9115b553, 0x473673b1, 0xa9e2dee3, 0x180ca19d, 0x76add331, 0x765b9d1f, 0x31bebcca }, + { 0xae91ef72, 0x88473150, 0x27a2d0b8, 0x7cbaf4ed, 0xf8df02ce, 0x0ed3df2c, 0x43c44705, 0x53ad24d0 }, + { 0x65800c15, 0xe25c9cc2, 0x1688a12a, 0xba273e00, 0xb5d40545, 0xf40d9922, 0x5919440e, 0x1f2149db }, + { 0x7ef462d1, 0x74e7c831, 0x37a741e1, 0x628960ed, 0x80104d78, 0xcd38a637, 0xacb12572, 0xf7128b8d }, + { 0xbc21c9a7, 0x602802ed, 0xa37de205, 0xf1dac32f, 0x5428ae64, 0xb7078118, 0x614dfb16, 0xaffa6b2d }, + { 0x4d7d48e3, 0x2a0122b7, 0xdac6e5a9, 0x33159bdc, 0x02d660a7, 0xf7939283, 0x81458649, 0xdb9b7684 }, + { 0x12315172, 0x04a82fd2, 0x940f14ff, 0x6e4ab43a, 0xbe2736f9, 0xd0dd1cc3, 0xea0746d5, 0x3eee16ae } + }, { + { 0x1a033ac0, 0x515cf68c, 0x98e00589, 0x3946f914, 0x14802c73, 0x1ecdaaea, 0xc570c750, 0x5829a29d }, + { 0x18fc9df1, 0x345c921f, 0xfe4a264e, 0x04de69fb, 0x3f28160d, 0xd43b01f7, 0x9fc3e5aa, 0xbe97f595 }, + { 0x6538a7ff, 0x797e9d4c, 0x80e8a24a, 0x8badff53, 0xd08aec53, 0x69d90f45, 0x054f1516, 0x16b96c75 }, + { 0xc8ba209f, 0x74a0139a, 0x4168ce4f, 0x93ae49bf, 0xbae11904, 0xed3c3e8e, 0x46607253, 0x15983c08 }, + { 0x7655cdd9, 0xc65c5ce0, 0x3567a4da, 0xb4428791, 0xf72683fe, 0x1de327d4, 0x735b1f92, 0x0b58c466 }, + { 0xf2a5be47, 0x02d072e6, 0x8ff791a9, 0x6cb3a717, 0xd204b478, 0x36e168db, 0x5656617e, 0x8cc69c8c }, + { 0x710fd80e, 0xe836406d, 0xf534da77, 0xa3151cab, 0x89326bd5, 0xe9ba2877, 0x4fe8ea31, 0xd4cea8ce } + }, { + { 0xc584b6f9, 0x8839cb26, 0x169e9d7b, 0x3b591bfa, 0x3340bdf0, 0xa3734a4d, 0xaf75417c, 0x5d690ffb }, + { 0xf644ffb3, 0xf9734c9e, 0x09737ce9, 0x554814e6, 0xd877fae4, 0xaa710bd0, 0x12d668bf, 0xda2c7036 }, + { 0xd1863def, 0xd09c5ff8, 0xd6294b22, 0x2f6213eb, 0xe64b4010, 0x31865ed7, 0x6143de06, 0xdb7391f1 }, + { 0xed981388, 0x6e43fc01, 0xc8c71f20, 0x51903b55, 0xc9d5074b, 0x94bc02ba, 0xf1cc290e, 0xfbe19f16 }, + { 0xefff1c3e, 0x67e02565, 0x3fce573d, 0xc0acced9, 0xe907485b, 0xb700abb8, 0x504e7b77, 0xb858bff1 }, + { 0xb06f7471, 0x39f8b9b7, 0x95ae227c, 0x23bfe932, 0x741b18ff, 0x9370926e, 0xe9785c7d, 0x5d30c235 }, + { 0x50ca57f9, 0x38dd2adf, 0xf613fc5d, 0x8c294ed7, 0xb2426ea9, 0x5596e0e6, 0x2ad84875, 0x350ad8ca } + }, { + { 0x5f8264f0, 0x64167ec0, 0xd90cd567, 0x57d8268f, 0x51c08f23, 0xdde1cf3a, 0x3cb0e091, 0x5410f3f0 }, + { 0x721bda50, 0x950ba07d, 0xb60d4508, 0x06363cf3, 0xa4601369, 0x445c6e45, 0xbcd5187c, 0x614be58b }, + { 0x7912d9b3, 0xea239835, 0x0cfb3934, 0x31f688ac, 0x22bdb30e, 0x528daed5, 0x1e894f9b, 0x706e0395 }, + { 0x1819c1b1, 0x32af07f8, 0x86a9525a, 0xef48b2fc, 0xe0f66330, 0xb191ddfb, 0x5da891c2, 0xd83f78ad }, + { 0x05f6bd22, 0x2b245f57, 0x8610bcd9, 0x6e412ae2, 0xa4dc56c9, 0xd335d60d, 0x7bf503a2, 0xb21bdbcc }, + { 0x4c715050, 0xb2dde657, 0x147ef33f, 0x36352fd1, 0x4bc3b8ed, 0x9c4c12ed, 0x662d3d49, 0x1d3698d6 }, + { 0x2efffdfc, 0x2eb6f5e6, 0x62dde0c8, 0x9d26bcb4, 0x84e61323, 0x7e70a82e, 0xb32e941f, 0xa254113b } + }, { + { 0xa6ff1777, 0x27d251d8, 0x8540a329, 0x0741430b, 0xc7391e0e, 0x3550c395, 0x2fec9b1c, 0xe86fa21b }, + { 0xe2fe7267, 0x33201f35, 0x6cc96327, 0x289298de, 0x62cb490a, 0xa4f2aa86, 0x69875564, 0xc844cb9f }, + { 0x3e2aa917, 0x6b047dab, 0x96b2cb67, 0xd09ba594, 0xafbac62a, 0x0add2957, 0xd448ec45, 0x39812842 }, + { 0x7233ec1f, 0x67bff4cc, 0x34fc2efc, 0x6ab6d126, 0x83fb8efa, 0xb488edac, 0x8a4b8bcb, 0x6234fb79 }, + { 0x0fecd72e, 0x3c3335f7, 0xeb5d72f7, 0xa8ebea41, 0xbb3829b5, 0xe2c9f088, 0x5e37b940, 0x48162648 }, + { 0xf1c5cca2, 0xfefc97be, 0x37496eba, 0xe4c9c004, 0x8f896225, 0x02cd923f, 0xb68be2a3, 0xfa4f4b65 }, + { 0x314331d8, 0x70a8d9d0, 0x0c922187, 0x951be164, 0xd716d74d, 0xc1cb6b67, 0x647c2a9f, 0x1594601a } + }, { + { 0x94203d96, 0xf446beab, 0x0f8b20bc, 0x389c59ef, 0x242d503a, 0x1baf43c8, 0x3600cf74, 0x1de5e5ef }, + { 0x97a63b7c, 0x3477df53, 0x98cd129d, 0x386c7fd6, 0x820b196e, 0x4eb81e8b, 0x205bd83c, 0xc0286a83 }, + { 0xe89c538c, 0xaf6aae3c, 0x8104897d, 0x65453323, 0xef8fc678, 0x80e12904, 0x66939201, 0x5e9ba64f }, + { 0x9c8f7951, 0xf6e54589, 0x687be629, 0x648ba88c, 0x520841c5, 0x302871a0, 0xc25a7137, 0xbc0a9da6 }, + { 0x94a51875, 0x39699a79, 0xaa4a5339, 0xbba551a6, 0x7be6c38c, 0xc7593768, 0x799d2123, 0xcfba86ec }, + { 0x9514f3f1, 0xe4f7e94a, 0x5f051133, 0xcdb33cb2, 0x9a7cff38, 0xe5e1b54a, 0xd69d469c, 0x486dbd33 }, + { 0x897924a3, 0xe2765105, 0x25436a0d, 0x363607d0, 0x2599633d, 0xfeb62269, 0xe3915522, 0xe5578e01 } + }, { + { 0xf7c8d214, 0x4bd95e57, 0x3a9f3a70, 0x93167d4d, 0x7f35b392, 0x7e459e00, 0x1bd8cbfd, 0xa2ba311b }, + { 0xc3b4afa4, 0xb2666351, 0x5a2790f0, 0x6a9bd3c0, 0xf4656b2b, 0x57a7d3dd, 0xc1cb2779, 0x8ac87671 }, + { 0x22fa1ac7, 0xd8a47088, 0xfa7a7ac6, 0x60e6c97a, 0x0f6e93a4, 0xb34a3b69, 0xae5ca04d, 0x121396b9 }, + { 0x9e5056b3, 0x91208a5e, 0x77f6a5bf, 0x65d8ce69, 0x57d8e680, 0x4a724283, 0xd622ffc6, 0x470969b6 }, + { 0x9c10a010, 0x93b62255, 0xde58d702, 0xec0d4d4a, 0x01b2f957, 0x86f0b84f, 0xa06604fa, 0xddea1447 }, + { 0xeca81c4c, 0x0212f154, 0x91e85b88, 0x5de81230, 0x76f2fed7, 0x93d938fa, 0x1a9064ad, 0x843e29c3 }, + { 0x6d511162, 0x673545e9, 0x6273f869, 0xea9b2d81, 0x66cefe10, 0x858e956f, 0x020d1fd8, 0xaca8b918 } + }, { + { 0xb215047f, 0xb9cad797, 0x115a2022, 0xac8c2cfe, 0x137eb97d, 0x31db80f8, 0x63e24c78, 0xe4c82b42 }, + { 0x3a87484b, 0x3bb2bbee, 0x2d21e574, 0xd8951ba9, 0x5d145a36, 0x26128d8f, 0x192584dd, 0x304ac2a1 }, + { 0x81663073, 0xb3f6ac8f, 0xfb22388b, 0x146fad89, 0x2f7e9fef, 0x094601e8, 0xb146faa0, 0x45e9b342 }, + { 0x8d01f6bc, 0x3b482017, 0xd83071fd, 0x658d6b53, 0x82a395fa, 0xb39b15a1, 0x7802c350, 0x9fe99597 }, + { 0xb9595963, 0x9724da84, 0xdd078337, 0x6f36029f, 0xa4b75a7f, 0x539abc90, 0x972fb4a7, 0xff29f0e7 }, + { 0x3f2b4a48, 0x1b096082, 0x800144af, 0xa3cd3f29, 0x7f4ddf99, 0xaeaf6abd, 0x585faf54, 0xc6abb2e5 }, + { 0xd4c10800, 0x4e4d76dd, 0x41a1a77a, 0x7a696586, 0x48deff36, 0x6c547df2, 0xd8f94c62, 0x4425b8c8 } + }, { + { 0xc253f1fd, 0x837f3b31, 0x0b5ccb2c, 0xe3191c69, 0xef0262dc, 0x7a36afc3, 0xe2aac82c, 0xeb8b48d9 }, + { 0xdb01f19c, 0x94a9b1f1, 0xe45b89be, 0xd967f07c, 0xda369655, 0x4b4fde39, 0x50301229, 0xa999282d }, + { 0x5c451b88, 0xa8ed1424, 0x1f28a883, 0x21e8058c, 0x36945b83, 0x825d76ff, 0xa767e753, 0x65ec9f62 }, + { 0x797e3bc8, 0xc1e87948, 0x39a0a9c7, 0x10cba850, 0xc107360a, 0x64c93e68, 0xb40d111c, 0x809e4b58 }, + { 0x22d23cf3, 0x5adbd67a, 0xbd94048f, 0x3bcfb5b4, 0xc0b7b35c, 0x778fa0f9, 0x9482d523, 0x0ae3280e }, + { 0x69fe1cc8, 0x464dcbd2, 0x5f11c964, 0x1d8b0886, 0x5b9cef4a, 0xee230459, 0xaf385e86, 0xfbd94ab7 }, + { 0x3953c1ea, 0x32adcdd4, 0xb958d003, 0x870cf263, 0xa99378de, 0xe7e4d956, 0x7acb3b61, 0xe790b88e } + }, { + { 0x829ef43e, 0x619388f0, 0xb3a1aff6, 0xdfe0a153, 0xd06fd2e2, 0xa81a36fb, 0xc55c4bef, 0xb3fdd022 }, + { 0x4e6b3c8f, 0xd69af789, 0xdfdc14e9, 0x549f2d8b, 0xfd67b5f4, 0x76794a70, 0x6e126224, 0x88fd42f2 }, + { 0xf7047035, 0xa905db3f, 0x49b4e963, 0xa3759c8f, 0x89a78818, 0x2c50346d, 0x8e2d5e83, 0x127915e4 }, + { 0xf48078e8, 0x1a4ca7ef, 0xfc4ee78e, 0xdd6f7982, 0xe4afd40c, 0x73cada61, 0x6547c764, 0x1c17d44c }, + { 0x8f6d2fc3, 0xda86e5b9, 0x93fd6d0d, 0xd0b1f0b2, 0x0a6909f4, 0xdc3b5e24, 0x90fced49, 0xf624b0cb }, + { 0xb4266815, 0x4f8ee3cd, 0x53c7dc14, 0x029ad9b3, 0x8188c70c, 0x4ed0d4a7, 0xfab23b81, 0x68c3f9cb }, + { 0x3fdd8763, 0x39c6e87a, 0xfda0dd8b, 0xef70ca8c, 0xe75125c0, 0xb2cd8fb4, 0x08eb626e, 0xdde63074 } + }, { + { 0x17b23292, 0x606c1866, 0x9c18cca3, 0xee3a27fb, 0x3995b5c6, 0xdd3302e4, 0x9e27dc11, 0x5fbc67c7 }, + { 0xcb105782, 0x34c7b524, 0xe3d46ab3, 0x66d18f3d, 0x3548dcf4, 0x68f6e040, 0xb60411df, 0x078b5f25 }, + { 0xac587cd1, 0xf32c95ba, 0x7cdee74a, 0x1dcc3fcf, 0xc36d8ac3, 0x53bee54b, 0xf0ac4193, 0xe65bd8f3 }, + { 0x479b1639, 0xe50a52f1, 0x53d42f44, 0x27897116, 0x428a3068, 0x74779849, 0xcab2a9c6, 0xf0f83a6b }, + { 0x9b45bd8d, 0x557e0d6f, 0x8102e9fc, 0x934ab0f9, 0xa15136dc, 0x0553e370, 0xaf9e4586, 0x96dda777 }, + { 0x1b13233d, 0x8782b3c7, 0xf6c35a78, 0xc3cb451a, 0x335bda6a, 0xc7052bd0, 0x5ac4f651, 0xe693e88c }, + { 0x7c055aa1, 0x8c3b1ba6, 0x8d63f4b3, 0x2947c116, 0x0047b9db, 0x445c1a9f, 0x68f88f78, 0x942cb5ef } + }, { + { 0xd805f7b7, 0x5a8dcc40, 0x553ecc20, 0xfb603dd2, 0x39753deb, 0x548a6f28, 0x67ed99aa, 0x78fd3ed0 }, + { 0xe50049f0, 0xde3fadfe, 0x3c87dc57, 0xead7b0ee, 0xae277a2a, 0x0cfbb0a6, 0x3847a513, 0xc69acd80 }, + { 0xb1d5dc3c, 0x66e9b52f, 0xfa9d4ed9, 0x4e29e3cf, 0x0d463727, 0xfd384d8f, 0x65c48f17, 0xbb2aa27d }, + { 0x76ac355c, 0x003f9aff, 0xdee49cf5, 0xbcc92cf6, 0x46778f2e, 0xb914ed52, 0x0b5019c8, 0xde41e619 }, + { 0x63c34226, 0x931232a8, 0x3b02c1ce, 0xda47aada, 0x761aadbd, 0xf8922f26, 0x428154ee, 0x54a868c2 }, + { 0x71b944af, 0x831b381f, 0x6c540c8b, 0xf63eafd5, 0x52cd4dc0, 0x9d1cd861, 0x2d581bc3, 0x7a668bcc }, + { 0xc0471789, 0xa99aa85e, 0x4180c9f0, 0xc2d74dc5, 0x3da366da, 0x2be54eeb, 0x7f112a06, 0x7cadbfed } + }, { + { 0xaae29aa0, 0xfaf5e052, 0x36eaf2dd, 0x109bbcf6, 0x7a32f80a, 0xdcd774b9, 0xa73cc8cb, 0x020120f2 }, + { 0x35dbdb7c, 0x1df8d6c9, 0x9d31e334, 0x474ca376, 0x85d72d99, 0x9d5891d4, 0xac6bc84c, 0xef1edc41 }, + { 0xa0a12ae0, 0x39087695, 0xce7be7de, 0x4f4cc09f, 0x2ce6e6c8, 0xe302f577, 0xd1bf201b, 0x4c67b486 }, + { 0x0482e45a, 0x8c588bcd, 0xa1784b77, 0x01e5afab, 0x385ff123, 0xb9048cf6, 0x5b64b460, 0x82beae14 }, + { 0x53bdad3e, 0x71e76e58, 0xa33e2a3d, 0xf04c957f, 0xbcac35c3, 0xc13b0d6d, 0x5aa18177, 0x5376c3f8 }, + { 0x8fd59904, 0x1ac23373, 0xa7d95104, 0x4ea0e6b4, 0xc9751244, 0x21291029, 0x39ba0a58, 0x03ff99b3 }, + { 0x27ce22c1, 0x61a59a1c, 0xecb951b1, 0xbec43d3c, 0x6f1b816f, 0x71031ad6, 0xa831c3bd, 0xfd563429 } + }, { + { 0xc1c4a945, 0xc5e5fa84, 0x428871d5, 0x64e0cdfb, 0x8a437645, 0x3891bff3, 0xca4a09dd, 0x34a1f315 }, + { 0x1d11a401, 0x2c203bbf, 0x1af265b9, 0x13d6e524, 0xaa82fc1c, 0x79158bb6, 0x04504769, 0x56998ddc }, + { 0xdcb5ce82, 0xd7f016bc, 0xf7ac3b8f, 0x01a80e14, 0xeb67b2d6, 0x3a7164e5, 0x697e95fc, 0x48e71fb4 }, + { 0xa97977ac, 0xa53a014f, 0xa340a5eb, 0x2582fbaa, 0x07bab09d, 0x946a7d59, 0xb0663162, 0xaec8e0c7 }, + { 0xe77e366b, 0xaeb9162a, 0xcca11a3d, 0x6e277e42, 0xc622d3df, 0xec6c75d3, 0x486f5ebf, 0x6569c183 }, + { 0x038ad1a1, 0x92ebd412, 0x02ecb91e, 0x5c328807, 0xf83da629, 0x889f30a8, 0x9f64ef2a, 0x753083b0 }, + { 0x0e3f90dc, 0x136957cc, 0xb90ee7cb, 0xad918b75, 0xd8f30259, 0x070fb929, 0x970da771, 0x10dd6e58 } + }, { + { 0x7fff17bb, 0x7d0fb982, 0x64fb1d31, 0x801ae173, 0xc5494808, 0x82f639b3, 0xb08f8be7, 0xe177e1aa }, + { 0x22fac75d, 0xe296fdc7, 0xc7ea5f7c, 0x543d75ac, 0x0aa41471, 0x0de52abe, 0xc5be0766, 0xb69b3cc9 }, + { 0x58a6837d, 0x86d09580, 0xc888ae86, 0x59a9dbfd, 0xbc6822b9, 0x00408db7, 0xa8f132cf, 0x35f53d02 }, + { 0x4adb8be1, 0x78ab1d2b, 0x58eaecca, 0xe6fdb954, 0x086292c5, 0x929e83c3, 0x49cee217, 0x30f798ae }, + { 0x11902b99, 0x2f9d30f1, 0x065f1519, 0xe924a28d, 0x5f6ed7ed, 0x5e3070af, 0x922f3bd8, 0x33ca22cc }, + { 0x16bccb3f, 0x083bc5db, 0x2717bdfd, 0x1cb44f6b, 0x04eb1d12, 0xd68fb3ff, 0xf18f5279, 0x02617755 }, + { 0x1f4f07e0, 0xae0ed9e7, 0xac4583d9, 0x5c846729, 0x6c8b8ca4, 0x64c0f711, 0xef2c6393, 0xd7736f0f } + }, { + { 0xbccaea79, 0x916d9cca, 0x6f6c174b, 0xa509bea0, 0xfd98ca6b, 0x798ed2a0, 0xa13c12f8, 0x24c09419 }, + { 0x45b0805a, 0x4534727c, 0xa7330146, 0x66202e8d, 0x18b0aaec, 0x497d6dff, 0x377e3e4e, 0xc4aa4662 }, + { 0xdf113db8, 0x2a5f3151, 0x9e231c7d, 0xf2cbabc1, 0x904432de, 0xe572ade2, 0xda149538, 0x764ec80a }, + { 0xd3e4743f, 0xad3cb3b9, 0xe4de5a8c, 0x362a1644, 0x27b0cd95, 0xc99fb49f, 0x28113b09, 0x4d512283 }, + { 0x614b8768, 0xcd42c400, 0x0e4b8e42, 0xbc4287c9, 0x8761ba46, 0xa01acb20, 0x26632b54, 0x0d1755cd }, + { 0xa4de3dfb, 0x6cf5d931, 0x2b40375a, 0xb9ac1ad0, 0x4e2a7093, 0x9940fb7d, 0x4a526d30, 0x7c5ef62b }, + { 0x372cf61d, 0xf6d5fcf7, 0x1d14bd8d, 0x94579792, 0x34aa397c, 0x5ca62a08, 0x35a86b02, 0x14c75383 } + }, { + { 0xae683995, 0x3e84150e, 0xe0d3b2a0, 0xa992c8ae, 0xe9e7b33b, 0x76ede638, 0x3c686061, 0x36216c8d }, + { 0x0a90129f, 0xb462da31, 0xd50d3633, 0x1214fb62, 0xe5161a97, 0xb06c0d3e, 0xaf89e3f4, 0x9e107830 }, + { 0xf6bfb46e, 0xb16b9ed1, 0x493b6514, 0xa7dff787, 0xdf8e488f, 0xc8ce8222, 0x8fd52f6a, 0xa6b4afee }, + { 0x00e0900c, 0x74f6faa8, 0x38fe0714, 0x11d68e12, 0xb2be4db0, 0xc50baf27, 0xc2a971df, 0xfcc60b2c }, + { 0x558997c0, 0x2e9f279e, 0xc7da06f7, 0xb2d5a66c, 0x888961dc, 0xc0716af3, 0x465afda8, 0x9563cf7e }, + { 0x8aa01158, 0xaa3a11b2, 0xbc46eddd, 0xe4d30f46, 0x2c48ad46, 0x2f697c2e, 0xb052aa2f, 0x4258d424 }, + { 0x900a7e76, 0xc9e24e68, 0xd103e0b2, 0x905e8357, 0xef994df5, 0x19d19bef, 0x91177797, 0x817a5f93 } + }, { + { 0xf0680a39, 0x56ec06e4, 0xc276f5bd, 0x375ef775, 0xe4e31ffb, 0x335fae5e, 0xd0540873, 0x6d6a91d8 }, + { 0xa6e75e8c, 0x3eaed6c6, 0x7d1aad1d, 0x431fa0bc, 0xe7dc54cf, 0x7d01a58e, 0x9b373b3b, 0x05972443 }, + { 0x2240d9e7, 0x0a99f104, 0x9e7b0d87, 0xe3dd4ec1, 0xbe262434, 0xcd7e9368, 0xda172b64, 0x0c80f89f }, + { 0x8a32479b, 0x813870f4, 0x9602215f, 0xf473b93c, 0xf3bd2430, 0x1c18aa53, 0xa89a2bbf, 0x07e846ae }, + { 0x723b2e62, 0xf5ade945, 0xcdd2acf2, 0x910e35e9, 0xdc538032, 0xc147e3b1, 0x15204ed3, 0xe69493e0 }, + { 0x51271a23, 0x1d4c5b74, 0xa0e926fd, 0xa00e2971, 0x70287ae1, 0x29115d0b, 0xf3489230, 0xbcf17a85 }, + { 0x09b3414d, 0x1d165016, 0xc6ec18d5, 0x9ea6765b, 0xe63744ac, 0x88cc920d, 0x816b6d20, 0xb749526e } + }, { + { 0xa9558de9, 0x563a30c3, 0xf131a8dd, 0xfc83e745, 0xfddb8c80, 0x5d119a00, 0xddd1b73f, 0xb7b0e877 }, + { 0x94f78ac0, 0xe1912c33, 0xbbe07a7d, 0x27b76ab6, 0x299f434e, 0x02e155db, 0x518eec1b, 0xcb5ae470 }, + { 0x7e337565, 0x38ef431d, 0xe513ef75, 0xf56f508d, 0xe9feb1c8, 0x99ae4d92, 0x4abae804, 0x2fe114ba }, + { 0x9e083058, 0xbb7c0f1d, 0x69efff2a, 0x17f3f27a, 0x6411414a, 0x82ff5fcb, 0x7e8c4eaa, 0x2f89d135 }, + { 0xa4246ea7, 0x803aff5e, 0xfc1d9c26, 0x2e425c19, 0x71852375, 0xf9900481, 0x317571d0, 0x512de239 }, + { 0x27278683, 0x2f50a60d, 0x0fec7db6, 0x81d67782, 0x6be16992, 0x0289ac47, 0x72ac7cb0, 0x011060bd }, + { 0x51561a11, 0x6e1d88c1, 0x8d63898e, 0xb6302a29, 0x45508af7, 0x7ab02923, 0x3300b64c, 0x18657075 } + }, { + { 0x93f705e7, 0x0b147235, 0x4579614e, 0x7955dfd5, 0x859d3964, 0xcb02ffd0, 0x91eb2e37, 0xf21aa087 }, + { 0x9cd1ba88, 0xfdf4f40d, 0xa5d82ffa, 0x402f925e, 0x02410072, 0xe9ab67ce, 0x57489af6, 0xa5c28f89 }, + { 0xdf5c6569, 0x6f6b4a1c, 0xeba0b602, 0x52c4d57e, 0x873757fa, 0x211ecd13, 0x325220ff, 0x17684f9b }, + { 0xbf48a26b, 0x1164e929, 0x68f2aa93, 0x2ae3ff90, 0x2fca69ce, 0x46ea779f, 0x149abe71, 0xf037d66d }, + { 0x2f692586, 0xc4786748, 0x022ed0d8, 0x35b30c7a, 0x4d42960f, 0xab8f12e6, 0xf1583d9a, 0x648650b5 }, + { 0x879b353f, 0x39d49315, 0x59a5e626, 0xa0536bd4, 0xc14eae98, 0x590e874f, 0xb3facb2e, 0xf40c444a }, + { 0x87f06816, 0x73316158, 0x8e8994ce, 0xc72cdabc, 0x98b88662, 0x51a7ca8e, 0x4bc81e4e, 0xf35ae046 } + }, { + { 0x3b5b086e, 0x6f799891, 0xf152c74f, 0x8ad181d5, 0x7057c78a, 0x6c289635, 0x3ce24060, 0x722c288d }, + { 0x1006d5aa, 0xabcec468, 0x82d3529d, 0x53da6135, 0xc62d75f7, 0x15421578, 0x271025ff, 0xad983b85 }, + { 0x39e3822a, 0x6ded14ca, 0x6c14077f, 0x923e1de4, 0x5c26dcca, 0x0ca1fae8, 0x9144978c, 0x3aa5ffaf }, + { 0x6a606b33, 0xbaf2a768, 0x6b05c4f8, 0x9de48ab4, 0xb5bd4d6d, 0xa8c57a5c, 0x429d6625, 0x035270c5 }, + { 0x44ec8799, 0x9faf6948, 0x15a7ccf2, 0x8ca09a6b, 0xe5c2a350, 0x7b14fdbc, 0x757e7d54, 0x8beefdfe }, + { 0x6404be41, 0xf3602368, 0x0a2388d1, 0xe309fac3, 0xbf1b9363, 0x349b5d55, 0xc97fd510, 0x7bb679c3 }, + { 0xbf51ea31, 0x7cfcec24, 0xb0fe8f2b, 0x0189b700, 0x29f06aa5, 0x614623e3, 0x19c3fd69, 0x6507077a } + }, { + { 0x33544daa, 0x4eb55b5d, 0xb9ba06a8, 0x7a1779de, 0xaac53436, 0x15d46ddb, 0xc20829a6, 0x4def4316 }, + { 0xa8433bf8, 0xfa3b3cc7, 0x2553a9a9, 0x62c92d3f, 0xbd133110, 0x92394b6a, 0x773b28ef, 0x7f278998 }, + { 0xe98ed40c, 0x70dd13f0, 0xa1fed2d8, 0x32999d19, 0x99b6bdc8, 0xb6c50812, 0x09d4cef6, 0xff970739 }, + { 0x7a05b868, 0x3b70b170, 0xb2c5ae8f, 0x99d39a25, 0x588d1612, 0x7affbd2f, 0x3223c05a, 0xbf4a2ff9 }, + { 0x14b1dd73, 0x2fd2c36a, 0xbe7e3cd9, 0xef1a83dd, 0x6b5ebac0, 0xf664740b, 0xf770ad79, 0x916afecc }, + { 0xe7b72067, 0x8a299277, 0x7ceeb323, 0x1d0a35b3, 0x963158c5, 0xf34dcdd5, 0x7d51e045, 0xf0cba700 }, + { 0xbc2e26da, 0x2d7cf4d2, 0xb1fe2ec7, 0x739c726b, 0x56f096a9, 0x304a33af, 0xfad91e73, 0xa052219a } + }, { + { 0xbeeda331, 0xeb9064fa, 0x826ecbd7, 0x350672d4, 0xf3e89f89, 0xa6b8bf8b, 0x770ec306, 0x3d6ec7d0 }, + { 0xe6d4084b, 0xa98ef16c, 0xf5d90c69, 0xd8ff6cf1, 0x40515d2d, 0xa66e0a26, 0xc5026f42, 0x49b8bd57 }, + { 0xcec0399f, 0xb5ca3155, 0xa97efc2f, 0x026a1550, 0x74bcb8b7, 0x4ea20409, 0x8626edcf, 0x981007ac }, + { 0x30bc8d63, 0x72fab04d, 0xdde894fc, 0xbf7de506, 0x96c87efb, 0xb2d34273, 0x240ac85c, 0x8acc1c1c }, + { 0x52968b7c, 0x0557f36f, 0x0ae5f576, 0x3e62a412, 0xb2664dd4, 0xaef0f476, 0x7c548e2a, 0x530a4f59 }, + { 0xcd106992, 0x4a3c4f25, 0x34f20563, 0xb76f3555, 0x6b7464f7, 0xec4f76eb, 0x0bd8c988, 0x49c492b1 }, + { 0x92fa08f2, 0x144d3f7d, 0x7d58ced2, 0xd22b7cf5, 0xf0187b42, 0x55d861e8, 0xcd019afe, 0xe9a1f11d } + }, { + { 0x9a436489, 0xebb996cc, 0x58762ba9, 0x675ba671, 0x3493bdab, 0x7e0ea401, 0x44f724b1, 0xd6024b8c }, + { 0x4e1846b2, 0x5181068b, 0x1a54b8e7, 0x9646ded0, 0xfe456268, 0xd1b00fad, 0x05dbc6c2, 0xea34ecbd }, + { 0xf7d502f0, 0x1d3aa8c1, 0x58d37b4b, 0x694d554c, 0x2b6076f2, 0x8748bc5f, 0xf8d82aa7, 0xa8c4c813 }, + { 0x2e751abd, 0xf08fac6e, 0xd35325a7, 0xcc47fc1b, 0xca975ec8, 0xbb331169, 0xb990cb9f, 0x24573b56 }, + { 0x22e24f5d, 0x90161c2e, 0x9f6f29b8, 0x64a3b6c6, 0x0b014332, 0xdd078178, 0xd0af41d7, 0xe8c2e047 }, + { 0xca6768e5, 0x9e824241, 0x8b232668, 0xb5b62a53, 0xcbe29e50, 0x52f4a2fe, 0x79ae4a35, 0xda534d00 }, + { 0x167387d5, 0xeb0490e9, 0x95090fb2, 0xca19e74a, 0x1c04dfa9, 0xc5f38f5b, 0xe00cabff, 0x0c17ba81 } + }, { + { 0x6631fc79, 0x52c30423, 0xe639f29b, 0xffcb6692, 0x85a3327a, 0xd5401982, 0xcc87e1a8, 0xdb1114b6 }, + { 0xa1b081bb, 0xd244bdd8, 0x17445435, 0x11600396, 0x4fc04562, 0xb7b8d8c1, 0x3dd9e83d, 0x5388fc2c }, + { 0xbf922504, 0x57f8841f, 0x130a604e, 0xe5eaa7e0, 0xd5ab1d0b, 0xf245fcdb, 0x5513cac3, 0xedbd9ec7 }, + { 0x49f054b6, 0x9f3afcaf, 0xa2ffd2a2, 0xab25bc2d, 0xe5c78937, 0x95feba83, 0xba62ccf6, 0x8f0be368 }, + { 0xa767cab3, 0x994803d8, 0xbde221df, 0x8e1e71c6, 0x8b78c799, 0x91f0aef0, 0x36c2fc52, 0x3161862e }, + { 0xff6f24fc, 0xa69ff27c, 0x119104a0, 0x51d902e8, 0xf7b6be77, 0x5ce92ecc, 0xaaad6af3, 0x1da6fff2 }, + { 0xffd1c2c7, 0x5da2b662, 0x9d5eebb2, 0xae3ec072, 0xa91996c3, 0xa53a8d2e, 0xf2407c14, 0xb22af9a7 } + }, { + { 0xc5714cb5, 0x8591b545, 0xd2db5bdb, 0x9e9b936c, 0x124db819, 0x2bf9b440, 0x7708843d, 0x7436f47f }, + { 0x74d277af, 0x7a09629f, 0x2c400241, 0x081b6e23, 0xc0195a28, 0xb5aeaff4, 0xb567feb5, 0x3c12ee9f }, + { 0xbda7c475, 0x07c805ba, 0x461488ee, 0x41494226, 0xa7533642, 0x55341d3d, 0x42d59e76, 0xdcaba05f }, + { 0x55ebdbd6, 0xe07b35da, 0x00737a47, 0xf5538726, 0x4e150f89, 0x47581944, 0x16d60f6c, 0x7d50492a }, + { 0x2d678829, 0x33c9861d, 0xe7419c54, 0x963b2e25, 0x0919ffb8, 0x2e7418c6, 0x00f595dc, 0x1b2734b3 }, + { 0xfa8c3a83, 0xa182c951, 0x203a4716, 0x10994d1a, 0x97234f60, 0x779a3fc0, 0xa2f72c49, 0x4811ae01 }, + { 0x926de2e3, 0xc9d02e7d, 0xe745b89b, 0x7210a4fa, 0x58228e67, 0x974bb00b, 0x8df1b6a6, 0x474d3460 } + }, { + { 0x8d63e29b, 0x37da4019, 0xadbce1ae, 0x8f13b4a0, 0x6485458e, 0x005d7952, 0x11129a0a, 0xa5b7661e }, + { 0x297c58be, 0x3d5b7465, 0x33012b97, 0x61e9f795, 0xabd3a260, 0xa7df3f4a, 0x9907dbd1, 0xfe9d06c7 }, + { 0x4bfe1dfa, 0x7f7c44d6, 0xbdb02117, 0x584c21f0, 0x0a3e923a, 0x0a3faf1a, 0xf3e5a5bf, 0xdda49418 }, + { 0xcb187d93, 0x3dd4bbf6, 0x656bdf5c, 0x818e19a1, 0x2917357d, 0x3116cff0, 0x464b0326, 0x0c261132 }, + { 0xb656ca93, 0xa28cc08b, 0x277bf86e, 0xd4f5ad69, 0x2e9a1c82, 0xa5ee39f9, 0x3f71d611, 0xd3ea2e11 }, + { 0xa2f104c3, 0x45ebae69, 0xdeddfa82, 0x3d4249ee, 0xbcfb51d1, 0x867ea762, 0x48e8a89d, 0x2844d5c1 }, + { 0x82ebbae2, 0x05adaa3a, 0xc0a3f7b5, 0x7b293b80, 0xa94e765f, 0x4120818a, 0xc50b274d, 0x22688c9a } + }, { + { 0xc3fc0b44, 0x8bcd8873, 0xfd4fb8e5, 0x6a9efb07, 0xaf2d5eb8, 0x995aae51, 0xa1521e70, 0x52774766 }, + { 0x7b54eba5, 0x6668a386, 0x75ab18e1, 0xdc4d0e40, 0xee4b3387, 0x17b838e0, 0xc8f32068, 0x8f50d4b5 }, + { 0x09204da6, 0x9ef60809, 0xbc8000cf, 0x337a67fa, 0x9ca7108c, 0xc757cd3a, 0xeb08ba82, 0x7e6be6d4 }, + { 0xc5a39182, 0xb0620854, 0x8015feed, 0x995d6017, 0xd0360d35, 0x3a814e7c, 0xe6573534, 0x59710baf }, + { 0xf99bacff, 0x3d3b0b0a, 0xbe43aa97, 0x5fb0a3ae, 0x3d2df3b8, 0x853dc3b9, 0xafd2a5a2, 0x4f1af404 }, + { 0x61ae5f7d, 0x44573fab, 0x90121a80, 0x3f0f4088, 0xc2123f61, 0x11abc7af, 0xa359b722, 0xddbfb1e5 }, + { 0xa8225e73, 0xcd094275, 0x4f4d1009, 0xb870665e, 0x2656e309, 0x63613320, 0x9da8e9e2, 0x5bf17a9a } + }, { + { 0x63307f75, 0x20e71142, 0xf2edd250, 0x489c3aef, 0xa00a6f57, 0x5d10c01c, 0x324b9253, 0x93835be0 }, + { 0xa174b176, 0xf1acf07c, 0x0638fe83, 0xcdf6812d, 0x76a8fe28, 0xc8fb9566, 0x61b2de0f, 0xe7e572db }, + { 0xa70101cd, 0xd58fcb3c, 0xa08d7a92, 0x707f7a51, 0x087f7394, 0x52ec367f, 0x4ad2575f, 0xcf0d9422 }, + { 0x99f9db0e, 0xd63b7d0b, 0x87714087, 0x32f4d997, 0x02ae8cba, 0x6c162b9f, 0x17c6c72e, 0x6870a1ff }, + { 0x1d859421, 0x0cad1862, 0xcc75b1b9, 0x3e7cffb2, 0x2284bd70, 0x3863341e, 0x1963063d, 0x4d37d33e }, + { 0xd612cd20, 0x43d28fc6, 0x0233b726, 0xaa330aa2, 0x01201406, 0xd4d58e80, 0x214f84c6, 0x2b1ab302 }, + { 0x04a91c83, 0x53597fe5, 0xaf7019d6, 0x8fb705d4, 0xd6bff9a0, 0x41220802, 0x7b7733a4, 0x97e00d32 } + }, { + { 0x40595c86, 0xf6930099, 0xbd743c7e, 0x052b2a49, 0x520434cc, 0xe84013cc, 0xb4b3b5b7, 0x2145a47c }, + { 0x1bbec7a8, 0x51054b48, 0x4540c4ce, 0x410ea37e, 0x22d77338, 0x53ea7838, 0xed1cc935, 0xb53c4e11 }, + { 0x1ca8445c, 0x68dbb70e, 0xb9edffbe, 0x798d10b0, 0x1173177c, 0x8c46979f, 0x7a25f06d, 0x8df73f0d }, + { 0x868e48ed, 0x0c4dec3e, 0xf0fc84f4, 0x935291c2, 0x8513c611, 0xbc49b63e, 0x4a51f7fa, 0x8c447a51 }, + { 0x037d699e, 0x0a093b32, 0xc2ec9f29, 0x5e90f49a, 0x855f3c1c, 0x36674b9d, 0x6414d645, 0x128eb019 }, + { 0x64d6e74a, 0x65fa3cce, 0x09c472a5, 0xa17ee5f5, 0xdffb9e45, 0x7a9c4595, 0x4d07da7f, 0x6fed21dc }, + { 0x81842845, 0xfc184cbb, 0x441f1fba, 0xf06543f1, 0xc8ec2559, 0xc0414db3, 0x59add3e1, 0xeedcba8e } + }, { + { 0x8d5f1cb1, 0xdd5cc734, 0x97b66085, 0x1f2aeb4e, 0x49fc4df3, 0x8c4647df, 0x020d8f8f, 0xfb3e30a6 }, + { 0xdc5dd9fe, 0xce57f180, 0x24dd9046, 0xc375884e, 0x869faec3, 0xbca83934, 0x71d1943b, 0xb1eaf24e }, + { 0x571eab92, 0x30538228, 0x5be3247b, 0x045cca2f, 0xa504a51c, 0xf5493a6c, 0x18fef6d0, 0x6f0f0e6c }, + { 0x9bea0233, 0x80dc3ce3, 0x59ec7d4a, 0x76dafb6b, 0xbdbc4040, 0xcffa68d9, 0xc156af96, 0x1b17111d }, + { 0xcfc30870, 0x623df507, 0x9fd6056e, 0x58b5a009, 0x3addc588, 0x01bf2d7f, 0xfd70e9b5, 0x454451fc }, + { 0xa291458a, 0x4526adc5, 0x367c6943, 0xec7c457d, 0x2983a292, 0x93f5a287, 0x38f480d2, 0xd4de9db7 }, + { 0xa6a97c24, 0x51a0e0ba, 0x1f639439, 0x950eed3e, 0x45f0c8ba, 0x7f6752ca, 0xc0c4af72, 0xb785824e } + }, { + { 0xb0cb4422, 0x0c5dcdcb, 0xb1d133c1, 0x1865317a, 0x2614b1c4, 0x484a4f81, 0x8cdbcbb7, 0xec2d0728 }, + { 0x7d9cf77e, 0x61770bc4, 0xa3eb1843, 0xc5ba899d, 0xce974e91, 0x4adcd05f, 0xeb21acfd, 0xf962c2b3 }, + { 0x213950f4, 0xf2a8b184, 0x3de16761, 0x2a9ee270, 0xe04388a0, 0x678bd048, 0x3982af74, 0xb79829c3 }, + { 0x2a57e1ae, 0xf96bcaa4, 0x58342aaf, 0x8662da2f, 0x7bfe6e15, 0x94249242, 0xda56a0c8, 0x610fdc7d }, + { 0x35f0876d, 0xf5151109, 0x6e95020d, 0xe2ca2d86, 0xc5f859ef, 0x6349c00e, 0x483a09d2, 0x3d793ad1 }, + { 0x48d650c8, 0x792cd02d, 0x96dd5dfb, 0x0ad306bf, 0x0865afae, 0x9984bc0a, 0xab9e4821, 0xf3977f17 }, + { 0x91ce8b28, 0x14759678, 0x8fb3eefb, 0x187d0f53, 0xc5d183b0, 0x0a3ff48d, 0xd30b2d9e, 0x7d34ee4f } + }, { + { 0x00bcde15, 0xcccd7271, 0xb895c848, 0x1c86d357, 0xbd8ee9b0, 0xd063775d, 0xb3f130fd, 0xd2ca1c14 }, + { 0x3c9857c9, 0xc6a9decd, 0xca1f2b65, 0x3d2b10a7, 0xb947c90f, 0xefcb8523, 0xca03778a, 0xd5d42cfd }, + { 0x5c73f4ce, 0xf8262f6a, 0x3ce264bc, 0x2df69850, 0x4a4bb3bc, 0x381e591c, 0xb9fb0145, 0x9996df80 }, + { 0xa379c4f2, 0xda0b13b2, 0xfb1b3cad, 0xb370772c, 0x6ded2ab8, 0xcc98e438, 0xd4ef7629, 0x3330f2c2 }, + { 0xc0d41786, 0x537ea8c7, 0x3b441a76, 0xdb1195bd, 0x3ce092d1, 0xb484de42, 0x8a853c14, 0x39e1d707 }, + { 0x871a31a0, 0x80623383, 0x3ad8e04b, 0x6d1e706d, 0xc99687b9, 0x4661e7ee, 0xeae02eb9, 0x73b29bdb }, + { 0x36816855, 0xf1440803, 0xed9581f5, 0xa42bf12c, 0xc085f0f5, 0x700c5480, 0x6092c0ad, 0xc1952028 } + }, { + { 0x61f3d76c, 0xb619f830, 0xb3c1aabe, 0xdfe516c8, 0x9de4137b, 0xa7cdfdcc, 0x8ae83950, 0xa824756c }, + { 0xa5234d7c, 0x9f7fc888, 0x02c47a29, 0x5675deb6, 0x03797a1b, 0xbd9f84f2, 0x49496ab5, 0xb3a92c12 }, + { 0x1459774e, 0x0587b246, 0x0e4c44f8, 0xeadc3dfc, 0x756d0677, 0xe5528ce8, 0x9d2a09d6, 0x4cbc59ec }, + { 0xca73670e, 0x55bb1710, 0x1e22a6a0, 0x70a8c976, 0xdb4045bc, 0x0bae4004, 0xdf481fa0, 0x98ebe4dc }, + { 0x85fb6d61, 0x56f856ad, 0xbf0842c3, 0xc5251773, 0xcd853b0e, 0xe4bfdb13, 0xba69a18a, 0x59e25dcd }, + { 0x83f1b479, 0x02285602, 0xec4d5e52, 0x126f80dc, 0x41737c1d, 0xfb739e71, 0xca819d35, 0x23402f41 }, + { 0x5a761f56, 0x70dba9fc, 0x898b6f07, 0x3c0a95e2, 0x4877c927, 0xd340a6cb, 0x53927787, 0x5bbc2f70 } + }, { + { 0x6f55de46, 0x80b41750, 0xe79726ae, 0x7e4430a4, 0x15016ede, 0x3cb704f6, 0x29d17376, 0xb1daf0a9 }, + { 0x1d106948, 0x09e71e47, 0xdeca7038, 0xcc4b19b9, 0x9aa4cb6c, 0xa5b51694, 0x50843372, 0x6f9bc50e }, + { 0x7da1905b, 0xcbae73bc, 0xc3ddc084, 0x7335d06e, 0xdf340f40, 0x25db1010, 0xeb287817, 0x0f8c91b7 }, + { 0xc91a7359, 0x5b5d748a, 0xbe2cd22a, 0x3c2e3298, 0x6c4247ef, 0x9a47c570, 0x2ddfa616, 0xd4bf75e0 }, + { 0x96ba5256, 0x9d2c3f03, 0x308d95e6, 0xcfc9ec0f, 0xa0961055, 0x392c377c, 0x66bafd5c, 0x7380bcd9 }, + { 0xe7c67ec8, 0xb9d05682, 0xa799e0b2, 0x32b89eb8, 0xf33da47b, 0x59ac7d9e, 0x931e2025, 0x3643c04c }, + { 0x565309d2, 0xfe24877e, 0x57202f59, 0x3d46b5a8, 0x8e00c15b, 0x8f0b8dea, 0x396d22c4, 0xe6fc1a15 } + }, { + { 0x5b18a044, 0x2c1b66b4, 0xe14c7f03, 0xd02553b6, 0x8d6b85f3, 0x6402dc7c, 0x39c64fe6, 0x02fd8601 }, + { 0x94c5a100, 0xbf83bf04, 0xe071aae4, 0xb8fcdb16, 0x76963764, 0x7b3b7bbb, 0x917c4f2e, 0x6f2932b0 }, + { 0xc891a1ca, 0xdec32e1c, 0x7f894b1d, 0x5a783287, 0x2b4d8375, 0x8d0d30b1, 0x49c9e792, 0x2588847b }, + { 0xb0f4d7fe, 0x7d03d93e, 0x1633bbb3, 0x30524f45, 0xc1513f85, 0x686ace4c, 0xfed101f7, 0xc6640982 }, + { 0x3f2a6442, 0xc8fe2cdd, 0xe7374831, 0xfa1df37a, 0xebac64c1, 0x9abc3ac5, 0x8ab69757, 0x83956b7f }, + { 0xb28bc15c, 0x1e8e0ef1, 0xc29a5af2, 0xc3b8ae0a, 0x421d84e3, 0xb96ecd43, 0x3d552bdc, 0xeb44d0bb }, + { 0x24c2ea0c, 0x5d58e6d9, 0x370c1ca7, 0x41bffc37, 0x9186bb55, 0x5c001f6f, 0x647cdabb, 0x3343829a } + }, { + { 0xf4738f06, 0xef7954b1, 0xd81ee33d, 0x09fd6120, 0x310b9f60, 0x69241d5d, 0x6735f0d9, 0x0d653f5b }, + { 0x730f85c3, 0xd46deb06, 0xa073f3d0, 0xe718eb2f, 0xd5106bde, 0x27cdc4f0, 0x54770105, 0x350d3345 }, + { 0x9baad4c3, 0xee4f1897, 0x77608e68, 0x8af945c1, 0xc8afcc2d, 0xdea35e92, 0x819d7b60, 0x5c226478 }, + { 0xf9943da0, 0xf57e8d09, 0x6ed04a45, 0x086a56fa, 0x2513abe7, 0x8cf5ad6f, 0xa09e2673, 0x9611b1f9 }, + { 0xe100bbf2, 0x51ffcbcf, 0x8bb1e6ae, 0x9065d124, 0x9d72a7ad, 0x58365309, 0x63c1fca4, 0x64f3846c }, + { 0xf1290554, 0x4bbf674c, 0x38714bb7, 0xa2f29af0, 0xd603228b, 0x340e638a, 0x76992250, 0x596bc1cc }, + { 0xf0466f92, 0xbfb91931, 0x2a515d34, 0x2d2d9b8e, 0x57374071, 0xbd9ba285, 0x54c663b4, 0x9c2db914 } + }, { + { 0xc78b3299, 0x19ae1f1b, 0x100a0503, 0x6a5de262, 0x78193f1c, 0x8c9b6cfe, 0x397c349d, 0x9d31efc8 }, + { 0xc5dee2c6, 0x665ef976, 0x49d296eb, 0x6770fbb8, 0xe94a419c, 0x86996440, 0x1f544088, 0xc4a61825 }, + { 0x5d56dcbd, 0xf4f21e5e, 0x64658bca, 0x7f0b0c4f, 0x4ba19309, 0xed866b32, 0x049d1ebd, 0xdc3c5e75 }, + { 0xfa0e70d5, 0xbe3df75a, 0x5b52fba6, 0x40d73380, 0xb032ec4c, 0xf352439a, 0x771a22db, 0x5f9e1c36 }, + { 0xc60ac075, 0xe963f257, 0xbbd1c424, 0x490424bc, 0xd0eef259, 0xfcaa1e74, 0x94f4a76f, 0x57f670bd }, + { 0x9dccdbb2, 0x51b2f921, 0x2fbbb2f2, 0x7501b147, 0x9a2cebed, 0xe638333d, 0xbca1e7a6, 0x830fa987 }, + { 0x5ced560d, 0x5f98d3f6, 0x8d505a5d, 0xcf80da1c, 0x2a2d3452, 0xc1c3d2d4, 0x2a137278, 0x66988098 } + }, { + { 0x19368995, 0xce79360b, 0x65811279, 0xb0b64791, 0x17e4c897, 0x0e9c2981, 0xa7ddf31c, 0x24e877e3 }, + { 0xcc3fdfff, 0x49ed6f65, 0xd6a549ce, 0x63e1eacf, 0xebb20c85, 0x4c726c08, 0xb34d4234, 0x29d229d0 }, + { 0x67dbe937, 0xe59d747a, 0xbb2c26a5, 0x2c45b745, 0xa8974eb3, 0x06fe9413, 0xceff61f6, 0x183a19ee }, + { 0x69e6b994, 0x6c78299a, 0x5aed6f64, 0xb704b816, 0xf62dac7b, 0xb8750ccf, 0xa4975752, 0x02a5c370 }, + { 0x3081edca, 0xd7da0bff, 0x8c3be568, 0x7720044c, 0xa04922bb, 0x044ca349, 0xe929aeba, 0xb1f5c7ec }, + { 0xe2ee4d48, 0x3a344c1e, 0xa3f119b1, 0xc9316169, 0xb4960665, 0x2ec02476, 0x8d09a4ef, 0x2b3f7b4c }, + { 0x64dc05ac, 0x917e0f8d, 0x8767f59a, 0xa7b63c85, 0x7410472a, 0xf2febd16, 0x33b4fa6f, 0x2047f63f } + }, { + { 0x03493b94, 0x1a055118, 0x21981d06, 0xe619c011, 0x8067bf4d, 0x36e9f2bd, 0x7232c291, 0xa85fa403 }, + { 0x7da6e24d, 0x67eeec49, 0xf9d0b55b, 0xa0180fe0, 0xcef8de77, 0x7ab8b5b9, 0xfae6b9f9, 0x29ccf5ca }, + { 0x3608267f, 0x7a52e5c6, 0x9fdbd947, 0xcfba3e80, 0x4717c548, 0x5b608fdf, 0x33f2e088, 0x4ab88fbb }, + { 0x700a2ce0, 0x6f749bc9, 0x0ac79a52, 0x1131876f, 0x48ebcc95, 0x35d07e1f, 0xb9d74ba9, 0xd7921b16 }, + { 0x51a46b75, 0xc766b3c6, 0x48578341, 0xc3bc878e, 0xc66bbea3, 0x2fda0dee, 0xb8e1515d, 0x22418556 }, + { 0xf4e952f5, 0xd8bc0295, 0x8b8d38aa, 0x0454ab5f, 0x10ac6bff, 0x9e943f6b, 0x6d8261dc, 0x808848fa }, + { 0x08676a25, 0x53a51c13, 0x1499e10b, 0xd9a4b7f3, 0xed75250d, 0xafeff9bf, 0x7088a313, 0x10705dcc } + }, { + { 0xda4d4156, 0x2310acc4, 0x8796c548, 0x535057b7, 0x5f291ff3, 0x0ab20f35, 0x93677dbd, 0x8c69b6ff }, + { 0x8b23e30e, 0x377e12f7, 0x84fe2f73, 0xa0ec919d, 0xdfda6326, 0x364f7fbb, 0x49c45f6e, 0x8c07d4a6 }, + { 0xb0eb8c22, 0x6dbd3002, 0xe34f84e6, 0xe3c366d3, 0x5fc72e10, 0xf49caec5, 0x6f4011e3, 0x7038c38d }, + { 0x378ce4e5, 0xe32c4022, 0x5c14ed02, 0xba91e88a, 0x4851e798, 0x9b4f98a3, 0x42f08b90, 0x0fb74b93 }, + { 0x8ab2da23, 0x84b2842d, 0xf1a40d04, 0x9f7c214f, 0x4b8002b6, 0x6ce4980c, 0x126b27ca, 0xed7175f4 }, + { 0x197f7299, 0xd688ac97, 0x9beb4279, 0x98ba1391, 0xb3719aec, 0xb964a1f8, 0x978a9485, 0x4ca9040a }, + { 0x15a808bb, 0xbe72c01e, 0x2877ef97, 0x0ed78b1d, 0x5fdb6fda, 0x726d3364, 0xc27b0380, 0x03409578 } + }, { + { 0x79bc7204, 0x64526abc, 0x40af0d1a, 0xd11bd441, 0xdf5687c5, 0xbbeb13cf, 0x74ca0025, 0x3dd9bede }, + { 0x465c164f, 0x372e1d94, 0x1a462c98, 0x4e6403e1, 0x7df3d03d, 0x4783848b, 0xec8ef487, 0x1f061ad4 }, + { 0x47c833fd, 0xe27fbe58, 0xa294b457, 0x4cd1a6c5, 0x0c2cdbc2, 0xff516fc0, 0xed81d321, 0x026947cf }, + { 0x64801488, 0xd4be8cd3, 0x9ec4f1af, 0x2600e44b, 0x0851e417, 0x6b51068e, 0xafb6bbd8, 0x8208ae65 }, + { 0x22b24c03, 0xc7e6448f, 0x716e08f2, 0x7e796d97, 0xec9bef1b, 0x66e5667f, 0x5f9b745b, 0xdf228f44 }, + { 0xd8070eed, 0x7531be15, 0x2efd3d7a, 0xecaa0ad0, 0xc0972df5, 0xf776df8a, 0x9da8ab27, 0xf0b42ef2 }, + { 0x27bafa4a, 0x341a81c9, 0x2e360782, 0x7800401d, 0x7f594e2e, 0x80317127, 0x155af896, 0x2b098834 } + }, { + { 0x50ac8c98, 0xc821317d, 0xe30b6dea, 0x23732d03, 0xa22d2f11, 0x9108913c, 0x0e0c2e17, 0x80349b40 }, + { 0x4f6a1487, 0x7ee752e6, 0xa9a0b434, 0x2f14c67f, 0xa55c2d40, 0x659d83d5, 0x3f17486e, 0xac616a2a }, + { 0xe0d22f8c, 0x277371d7, 0xaeb933ff, 0xe5cd5a56, 0x07e8825b, 0xf521096e, 0xb055b9e1, 0x622f69fa }, + { 0x2428cf8a, 0x96d714c1, 0x58b73416, 0x272fc42b, 0x874dd8ab, 0x205d1af2, 0xb9bccc72, 0x52ebd7b0 }, + { 0xea28c322, 0x01162702, 0xc9086e8f, 0x10a1f1a4, 0x2b4ae4c0, 0xe95c95fb, 0x10ef8e49, 0xf033dba1 }, + { 0xaca39e67, 0x98d59def, 0x3d199fba, 0x93cc0046, 0x41389dab, 0x38150fc2, 0x989a4d46, 0x9b427328 }, + { 0x555f6fcd, 0x187aac65, 0x237ea7ba, 0x411845bb, 0x257ecc96, 0xa6d2b9a9, 0x186cd758, 0x745f3c59 } + }, { + { 0xd8bd778b, 0x2c224db8, 0x9cf37266, 0x92c241da, 0xef9a0dc7, 0xa0141780, 0xd85304c7, 0xc1778012 }, + { 0x0cdf909b, 0xd6e1b56b, 0x60844342, 0x0012b99b, 0x5069f160, 0xa8759687, 0x9408dadb, 0xa651525e }, + { 0xe24e6ac1, 0xffb01991, 0xa84ae5e6, 0xe3e71b0d, 0xd1af4e76, 0x014d0563, 0xbcbda8f5, 0x47931fcf }, + { 0xf3f7b396, 0x5b45d64a, 0xef5e27ef, 0x04134034, 0x4ea4b384, 0x0c55b7ac, 0x02877644, 0x7f08a13b }, + { 0x3ed1b355, 0x89d6f5bc, 0x9d48cc98, 0xa0759109, 0x82673778, 0xae7c9a53, 0x516c3cba, 0xa817b9b7 }, + { 0x44d407ce, 0x3866b2a0, 0x16966a1e, 0x1430f251, 0x37b831f0, 0xd52ce3d4, 0x78e95a9f, 0x59cf28c6 }, + { 0x3e4f2155, 0x7156e7b3, 0x1b86f8db, 0x42f7566f, 0x3e56da90, 0xf030b29f, 0xec85e66b, 0xcc52db57 } + }, { + { 0x7e6c0017, 0x413ffb3f, 0xb0eef332, 0x00c4654f, 0xd22aa38b, 0xa5efdb30, 0x5764e3b2, 0x30492695 }, + { 0x7147830a, 0xc93791b6, 0x90db318f, 0x59f91408, 0xf1ce4428, 0xa5ed3cc1, 0xc9e3126f, 0x3e65f4be }, + { 0xc9a52997, 0x98ec0cec, 0x845090c0, 0x972e21c7, 0xbec7b346, 0xc5a51cd5, 0xc2bc2364, 0x6feb2a2a }, + { 0x8c502344, 0xa133bc9b, 0x12e631f5, 0x1fad16db, 0xd9bc4a2a, 0x3ad8ef7f, 0xfa5e4e06, 0xf413547b }, + { 0x9d70f033, 0x9be7e0c8, 0xceaf3e95, 0xabeb2be0, 0xd6968817, 0xd3e5bff7, 0xc70e1698, 0x7dae7c15 }, + { 0x16bd8319, 0x45e55117, 0x4034e356, 0xf10d487f, 0xa76f4fdd, 0xf10370e7, 0x167a2453, 0x0422ab4f }, + { 0x7ad6b216, 0x238eb324, 0xc6461eeb, 0x807aa6b5, 0x162573a4, 0x7f90891c, 0xf78a4770, 0xee33693e } + }, { + { 0x85a61667, 0x3292f30e, 0x9d1df8cb, 0xe79682a4, 0xd306be03, 0xb1ecf6fd, 0xace14759, 0x0ecafaaa }, + { 0x88ba8325, 0x5da8e735, 0xf88401d1, 0x3a0b86eb, 0xca737832, 0x21d368fa, 0xa2131889, 0xf0bc2442 }, + { 0xd9cf985f, 0x4a150996, 0xab65117e, 0xbe002181, 0x08d679b9, 0x34f40192, 0x64e2a998, 0x1aeea04e }, + { 0xd12d7f84, 0xad3018df, 0x9c1f731a, 0xd6a1dc24, 0x855ded20, 0x0eda9d64, 0xb17fc497, 0x796fbdf7 }, + { 0x67abd4af, 0x9cf4fdd7, 0x1e56babd, 0x503eee44, 0x170363e2, 0x5693fd28, 0x51540b37, 0x05abe4c4 }, + { 0x2dbcd044, 0x2981a934, 0x73082781, 0xdd97b6b6, 0x64c3c92d, 0x421073bf, 0xe7ab4219, 0x23ede5ff }, + { 0x62112ae9, 0xe15f3626, 0x038a6317, 0x97a7f32e, 0xce90123d, 0xf02d754e, 0x6b218ea1, 0xa3c38d14 } + }, { + { 0x004fdc93, 0x4b7c873a, 0x95be1cc9, 0x7c5432d9, 0x6204127d, 0xed04d3d3, 0xfb64984a, 0x93d731b4 }, + { 0x6f366d43, 0xc3a3b935, 0x5963fb76, 0x268cd779, 0x192cd883, 0x7a64e33b, 0xd6034f31, 0x89e7e743 }, + { 0x3b30e2ca, 0x4a02b442, 0x69056f99, 0xce9b2bd3, 0xb4e7a87f, 0xc1d230ae, 0x3c6dfd11, 0xadaecce2 }, + { 0x33b83f9a, 0x6c0ad79b, 0x1322b694, 0x8d3f9e24, 0xf8fafbaa, 0xc6223143, 0x3f7c6091, 0xecb5943c }, + { 0x8d2da3dd, 0x5390be12, 0xb6cb6db1, 0x60743204, 0x48971e41, 0x887cd9fb, 0x1ade9d31, 0x8bc76839 }, + { 0xa9ce25de, 0xaea01431, 0xee284648, 0x0f997777, 0x9bad14ca, 0x68c4b3b4, 0xa3c32b11, 0x0bb9f4a5 }, + { 0x4ce7cbba, 0x930c6ce6, 0x1473d7e2, 0x5211cccf, 0x4bf9f56c, 0x608d15a9, 0x5471a71f, 0x9e4e1357 } + }, { + { 0xc4d4250a, 0xa90b2ff6, 0x997f0ad2, 0x313ed353, 0x1e270e78, 0x4d7bada7, 0xe504aed6, 0xeafcebb4 }, + { 0xb182f670, 0x1c0c6022, 0x002f8917, 0x94e9c583, 0x244640a1, 0x8f114879, 0xcbde6210, 0x25675f69 }, + { 0x0e5a14c7, 0x074528d1, 0xdc2eff1c, 0xfecb81e0, 0xe4331fb5, 0x8810cb7b, 0x3d824831, 0x9d9ed1fd }, + { 0x416b6738, 0x2bbbd78b, 0xaa4012a6, 0xeb2fd98b, 0x585477c8, 0x702e595a, 0xb322d949, 0xbe2d3a24 }, + { 0x111432d9, 0xd9b07718, 0xc0d6e5f3, 0x1c36e961, 0xd6090a73, 0xd1e819ff, 0xbaa7e4ff, 0x63968570 }, + { 0x9e470151, 0xb3d468a1, 0x9260b722, 0x13b5fa98, 0x5659a528, 0x9d28f8a5, 0x85adec37, 0xc606ba8d }, + { 0x3decc870, 0x6bd5556b, 0x6f7f7797, 0xd1b74770, 0x662aeb0c, 0x9be1606f, 0xa6aac5f5, 0xf85b350f } + }, { + { 0x9463a868, 0x960e8462, 0x4fa2b9d2, 0x178547e9, 0x50e71617, 0xd0d08216, 0x0c79d64f, 0x027df2d8 }, + { 0x5207ee10, 0xcf7670db, 0x2793abbb, 0x4cd968e9, 0x54e3fb50, 0x37d47190, 0x9b8e5703, 0x69bb7ec9 }, + { 0x627d9958, 0x55b42a06, 0xeba7f98d, 0x853170d7, 0xb54ca419, 0x69668fe7, 0x73cc969a, 0x10e096e6 }, + { 0x4c669696, 0x6232f551, 0x295b5a25, 0xd98e6e6c, 0x1b045ecc, 0xca537442, 0xd63dec57, 0x67e5a619 }, + { 0xb13e1282, 0xc06b8335, 0xe41b1193, 0xf3a2297d, 0xcf435007, 0x2fc34631, 0x42e4890c, 0xd3e85862 }, + { 0x160f81d9, 0xf12f48b1, 0x80668974, 0x1950027d, 0x58fe5eb0, 0x08db8df6, 0x70864927, 0x80dab7b3 }, + { 0x293bd8ba, 0xddaf78c7, 0x59d74859, 0x3e8ccc1f, 0xab08d45e, 0xed90a269, 0x800f365d, 0x8c05ec5d } + }, { + { 0x9f5f3ef3, 0x2d06c644, 0xb7ddb6d2, 0x950116f7, 0x81d0f434, 0x7fbfe324, 0x99cfa463, 0x477b1d3f }, + { 0x9ad80019, 0x67c3a9f1, 0x610da4c5, 0x90954ce4, 0x0e1f8a78, 0xf1763ba4, 0xbbf73d7c, 0x713419a7 }, + { 0xabda8eda, 0x14be0d15, 0x98601e48, 0x0b327788, 0xdfadef27, 0x4d6eddd5, 0x2012e79c, 0x53ea34cb }, + { 0x26c758c6, 0xa962c123, 0xb1c5450f, 0x3f6130f7, 0xd65a9947, 0x822f1cec, 0x2f8ca7fd, 0x8885d745 }, + { 0xfb8d48d8, 0x26b785b6, 0xb67ce850, 0x688eb713, 0x6fcb4007, 0xa4218806, 0x826c9739, 0x867b567a }, + { 0xb6d72f91, 0xb4dffd3c, 0xf35f61df, 0x8ca0924d, 0x5f4f3ed7, 0xaf3a604d, 0xbad24bb6, 0x4d6bca16 }, + { 0x0af40433, 0xb22010f7, 0x84fff4b4, 0xbb531995, 0x6e7f6aa6, 0x702b82b7, 0xc314eff3, 0x45c6ace3 } + }, { + { 0x38c8eb70, 0x2f7a7d96, 0x425f1213, 0xa9d56023, 0x686f2536, 0x07d95255, 0x03efb3d3, 0x6e3c2be9 }, + { 0x8ccf431c, 0x005f2155, 0x9e8a76f3, 0x3302280a, 0x1f626419, 0xfebd98fa, 0x0d7dbeb5, 0xed228f84 }, + { 0xc7755f65, 0xcc789750, 0x80422eeb, 0xb70e3300, 0x3800488e, 0x66a47b99, 0x80fe5bcd, 0x810df768 }, + { 0x58a9e2b8, 0x6ace6cd2, 0xa26dc819, 0x9da0d6fd, 0xf57318e5, 0xbb2a6cde, 0x00f88e64, 0x45988afc }, + { 0x2db24f74, 0x8e84b606, 0xdd85891e, 0xbaf24e72, 0xae366b70, 0xfc18da2c, 0xe1937d7c, 0xc7edf94e }, + { 0x30f8d51c, 0x431a2e5e, 0x318780b1, 0x90c156f8, 0x7f325d96, 0x92cd03b5, 0x408db8b8, 0x3e2e340e }, + { 0xb5fb3838, 0x5226821f, 0xadbb4294, 0xff433812, 0x03075206, 0x386d18f7, 0xddc08239, 0xeb3a3609 } + }, { + { 0x1deb0d7b, 0x486e7970, 0x528c5c8b, 0xc4ddea85, 0x65c479ca, 0xb2564b35, 0xd106470c, 0xc6e35fb4 }, + { 0xf289ae55, 0xde118bf3, 0x84673fb0, 0x7ed5665d, 0xf2e4e8b5, 0xfc0244ef, 0x76dd77b7, 0x4ac503f2 }, + { 0x0e420397, 0x7e9632d7, 0xa0bda73b, 0x2458b8f3, 0xc2fbafbd, 0x582c46ee, 0x06d1d65c, 0x037da5f2 }, + { 0x8b9f4092, 0x5843804a, 0x8bedf071, 0x2f5315ce, 0x9373f07a, 0xebdcc2ef, 0xb0b2a12f, 0xbdfcf2ef }, + { 0xd2495e4d, 0x04d95d4a, 0x510f2342, 0x68606545, 0x19de4d07, 0xd71ca9aa, 0x3b06212e, 0xf56f82a2 }, + { 0x1e58fff3, 0xbfbdfaa3, 0x3e0c674c, 0x8e03a28b, 0x37ae6d19, 0xf92f3944, 0x5135fbc5, 0xbe4b52f3 }, + { 0x50d0f9af, 0xde678fe8, 0xb238077d, 0x177dba54, 0xa139d3f3, 0xe9e8df29, 0x3f63742f, 0x312b32de } + }, { + { 0x20c56647, 0x8707018f, 0x3b9ba5d0, 0x300bf55c, 0x8d003323, 0xf98aac6b, 0x583300fd, 0xba8bbc8b }, + { 0xb1545d91, 0x254a8fe3, 0xd49bcfd4, 0xacfee11d, 0xf10d406e, 0x64fcfcde, 0x027e13a9, 0x8aa5595c }, + { 0x512d3bdc, 0xcbc66bb2, 0x9908c828, 0xca5b4f81, 0x97deef7d, 0xb796061b, 0xb7ceff8c, 0xeecf09d9 }, + { 0x2d27dfaa, 0x4738165d, 0x28e7a55f, 0x420813e3, 0xaa8440a4, 0xeef99bfb, 0x71666ba2, 0x86a51a80 }, + { 0xd7791222, 0x692bc41b, 0x3bdbac31, 0x82cb05cd, 0x5b4b3744, 0x4b665815, 0x1762b639, 0xa878d6ea }, + { 0x854b7d2e, 0x8fc1d536, 0x9ce4db12, 0xe32bf6c4, 0xb0290fba, 0x0faaf22e, 0xfece04ff, 0x4474f689 }, + { 0x049f5deb, 0x94fc8dbd, 0x905a535b, 0xc429ceed, 0xfbb317ac, 0xac96fdf2, 0x7e3b05ff, 0x4860d996 } + }, { + { 0xe50c69fb, 0x0fa77338, 0xf79fca72, 0x3e0d30ba, 0x598ada93, 0x2e435d52, 0x3d70cfcb, 0x22182bb3 }, + { 0x67ecc251, 0x18318183, 0x5b1696e1, 0xc13a2c4c, 0x086c6392, 0x72273fd6, 0xe20aaf30, 0x301201b3 }, + { 0x54b990a1, 0xafa6328d, 0xe63abcb1, 0xc78f2775, 0x1fb1d8ce, 0x4747f283, 0x8359e523, 0xf469ed88 }, + { 0x152b5010, 0x806afb62, 0xb91dc4e0, 0x7c018a3e, 0xbc7a0eed, 0x23dfe690, 0xfe576b7d, 0xfdf38e7e }, + { 0x8072da71, 0xd96c2ee9, 0x62f4f37c, 0xf03b9d8b, 0x15b73a44, 0xfe52a7a2, 0xb9917a0a, 0xbdafea91 }, + { 0xdbb7e37d, 0xc70465f7, 0xfcc5723f, 0xdaf07719, 0x65d54e8e, 0x3136c077, 0xfcc41d56, 0x07484576 }, + { 0x9947b804, 0xc1b2266f, 0xed448fa2, 0x3522089b, 0x0bf4534a, 0xdbbbf3e1, 0xc7f929be, 0x9515c273 } + }, { + { 0xa83022c6, 0xdb2ba386, 0x31b8e1d9, 0xba05e0c5, 0x94d029ac, 0x7f9578b5, 0x09a69555, 0xb8166017 }, + { 0xaf323459, 0x6ecdb983, 0x636b45aa, 0x66e075ee, 0x5483eec4, 0x96aa3f50, 0x08ddc9f1, 0x7e31f4ce }, + { 0x255b7d94, 0x231d7a81, 0x6b9df41e, 0xb8968891, 0xce185a87, 0x1fe0e0be, 0x0df6fc87, 0xc18d383f }, + { 0xdcf87a84, 0xe0e68384, 0xbb49e230, 0x481ba3be, 0x84748f2a, 0xb00aab60, 0xfc179e9d, 0x857bf2d0 }, + { 0x468c6a70, 0x17f68dbc, 0xf05e454c, 0x0bf04d87, 0xf7a98200, 0x34985943, 0xd4fff833, 0xf2cc253c }, + { 0xeb13b6bc, 0x2abf96a3, 0x4b7201e1, 0x625b4424, 0x3c3b2563, 0xca66a69c, 0x7394f29b, 0xcdb92b85 }, + { 0x087361bf, 0x616d40cd, 0x560b5746, 0x09434f03, 0xdc133705, 0xe050c7f1, 0xc7506a47, 0xcdf0be50 } + }, { + { 0x31691ebe, 0xed7a1f62, 0x1d69e367, 0x3dcbe08d, 0x975e71fd, 0xe8bc4d75, 0xaf7a2810, 0x3d73950c }, + { 0x7fbea22e, 0x381d20eb, 0xf0431b54, 0xa3e5c8d3, 0xbeebc5f7, 0xb5095b34, 0xf45251e1, 0x88b5d9b1 }, + { 0xc349242a, 0x14d7252d, 0x2a93b81e, 0x054d16ea, 0x60c50aeb, 0x276e8239, 0xf503cbea, 0x77592aa0 }, + { 0x8c68a879, 0xa959997a, 0x128f9d7c, 0x0618dc7a, 0xca0be3f4, 0x9d2ac2de, 0xadea324d, 0x5152f278 }, + { 0x7ba250da, 0x94183f87, 0x7019ad76, 0x69075f7d, 0x393cd782, 0xfd52b891, 0x00d8292c, 0x8c3b2734 }, + { 0xe0c3a509, 0x77a7350d, 0xa83ccc53, 0xb9e8244d, 0x8a5ef941, 0x66d5acf8, 0x6180cea4, 0x885eae04 }, + { 0x33a9c3dc, 0x01868bc2, 0x58c61de7, 0x7a93fa06, 0x4cd9f562, 0x9e8a0747, 0x32ba8e08, 0x3780b278 } + }, { + { 0x47db582e, 0xcd9cf0ad, 0x42101761, 0x077c78e6, 0x9c974652, 0x58e18de7, 0x72feea9d, 0x8372f246 }, + { 0xa45c7958, 0xc3223948, 0x059a7b58, 0xa433e03e, 0x6e478fb3, 0xbc6e5186, 0x5f0167ff, 0x61aa9962 }, + { 0xd297083a, 0x237b9355, 0x16b460e9, 0xd4cf70b8, 0x4906f286, 0xa5062552, 0xb472874b, 0x8f8c7562 }, + { 0x2d990849, 0xa8418e55, 0xce78dfe3, 0xe7ad865d, 0x617900a0, 0x83b88f64, 0xc27917ea, 0x81ea7038 }, + { 0x215656ee, 0x78aff999, 0x32b79d72, 0x1d8dc5e7, 0x5f629263, 0xc73af887, 0xd1ebc2ca, 0x77175169 }, + { 0x7ecaa5e2, 0x82a28565, 0x3eaf012b, 0x1f5dd8a3, 0x25574e50, 0x7fda2c4e, 0xd1bec96d, 0x8d1493d8 }, + { 0x450ac92b, 0xb6dac065, 0x5252896a, 0xea9055a2, 0x2bff2eda, 0x0b71a456, 0xb20bc57e, 0x5ebd3e5a } + }, { + { 0x06c28b5e, 0x6b9af341, 0xe09f4468, 0x9d2942b7, 0xf206afe2, 0x0898c6d7, 0xce1e17b7, 0xfaf50486 }, + { 0xc086eb33, 0xfb2b6a81, 0xbd4ef528, 0xf7e2d3cf, 0x9f2e3896, 0x15837e91, 0x310fb58a, 0xe009f48a }, + { 0xd005ba52, 0x522d35b6, 0x15f76f74, 0x75fbe015, 0x8d2e6b40, 0x3fc9317c, 0x4012e5a2, 0xe1fedc4c }, + { 0x074e5abb, 0x25793158, 0x022c125d, 0x1cfddb5d, 0xba7d82a7, 0xde9481a9, 0x2d356f09, 0x4be7edfb }, + { 0x92519f67, 0x66d2c133, 0x74d7190b, 0xe4b1a9dd, 0xa9e0885b, 0xb658ca08, 0xeca0c4f2, 0x9fdd88af }, + { 0x4975562d, 0x84b67be0, 0x4891487e, 0xd2fa6000, 0x38c919df, 0x0d2b7e56, 0x2b5ee426, 0x6f440a1e }, + { 0xbbb1339d, 0x7f5e833c, 0x735df589, 0xa4339e2e, 0x7eb48658, 0x080d8e72, 0xc3a7c99b, 0x43ca835b } + }, { + { 0x3dda52d9, 0xf2307b82, 0x07f1fc1c, 0x59143e86, 0x954e4d90, 0x966cf48a, 0xd9b0d66b, 0xc427b10d }, + { 0x4eb94575, 0xf29126c3, 0x81ea3d87, 0xe06246ca, 0x505883b1, 0xc5bc93ce, 0x358bd5f6, 0xe72a8c73 }, + { 0xdd3b93c6, 0x2767b96b, 0x60dd053f, 0x10cfa310, 0x4abd4f8c, 0x5372a39c, 0x5d54a330, 0xab1867e5 }, + { 0x62c948d4, 0x0b47f1b0, 0xad0ea37e, 0x4efbb4b4, 0x1716ebc5, 0x4ee5e170, 0xbbaca4d8, 0x43e62ff2 }, + { 0xf7d0b782, 0xf1e49ad1, 0xeadeed67, 0x99c2da1b, 0x00894847, 0x90dfa1f7, 0xaf6daa4f, 0x7b4829b6 }, + { 0xde5d8713, 0x35a5b31b, 0xb748800a, 0xdac38349, 0xde103af5, 0xe1d73ccc, 0x46ba0ddc, 0x39306645 }, + { 0x3a06b9a1, 0x160b972a, 0x521c321f, 0xa004069e, 0x83a16ede, 0x98b00b31, 0x60f9f83c, 0x1f35d1c1 } + }, { + { 0xd597421f, 0x2d9b1d10, 0xf4980375, 0xa24461bc, 0x82196094, 0xa0ab2368, 0xf9a7cb16, 0x388ad687 }, + { 0xe38b6868, 0xfbeed35b, 0xe06b3c03, 0x4c8c1665, 0x9eab9ce9, 0x7bc8d118, 0x812d2907, 0x440b0c84 }, + { 0x3deb66a1, 0x197f9e3d, 0x0f19712a, 0xeacb42bd, 0xc83f1bba, 0x86c68e82, 0xbe6fa356, 0x597095e0 }, + { 0x8f291e99, 0xcaba9ad8, 0x2f7dedc7, 0xb5b6f892, 0xc616aa71, 0x263f9cc4, 0x57016837, 0x64a8c843 }, + { 0xa20493f4, 0x53ab7293, 0xf991fbdc, 0xb999d658, 0x72479e76, 0x6e506638, 0x22cf1ace, 0x15063027 }, + { 0xd083da24, 0xfe918278, 0x0d92f48b, 0x6f9957b8, 0x5d7cdfd2, 0xa98cbc77, 0x958b6fa5, 0x00d75485 }, + { 0xb1ac8616, 0x0bc3844a, 0x47346240, 0x639d46b0, 0x81ac702b, 0x0f4a717f, 0x13fc3167, 0x2163fe2d } + }, { + { 0xe9f3460c, 0x2f82243d, 0x0f6e44bd, 0x04bbb112, 0x975dc2aa, 0x0df79c3b, 0xa615c4b5, 0x1fbf4268 }, + { 0x46df1de0, 0xbf6a680f, 0xd832e15c, 0xb61b8fa1, 0x4bac69a6, 0xd0eed295, 0x452d9e96, 0x2e1e63d6 }, + { 0xd6c9f2e4, 0x57cd73e4, 0xb946d1a1, 0x1bdb407c, 0x4ad02a64, 0x04340e80, 0x0898a05c, 0x9a339f6a }, + { 0xe28c995d, 0xda871bd6, 0x734c3b3d, 0x624eb50c, 0x6eb8b37f, 0x06ab1aee, 0x819da6da, 0x2ccd5f1f }, + { 0x610813ba, 0x1c4a8420, 0xa489796e, 0x864a3542, 0x81a25499, 0x070bd68b, 0x742e1f71, 0x1e667a0b }, + { 0x0df38684, 0x47a20eaa, 0xad42ba4d, 0xe3c176da, 0xd33439dc, 0x3aea032f, 0x61bc2c8f, 0xc6fb92ff }, + { 0x991932d7, 0xc28287b1, 0x844ceb4f, 0x691a97fc, 0x40e4d88a, 0xb10977da, 0x8b8aa1d9, 0x9691909a }*/ + } }; + +#define SEC1 0 +#define PUB1_X 1 +#define PUB1_Y 2 +#define SEC2 3 +#define PUB2_X 4 +#define PUB2_Y 5 +#define SHARED 6 + +uint32_t ecc_keys[][9] = { + { 0xFC632550, 0xF3B9CAC2, 0xA7179E84, 0xBCE6FAAD, 0xFFFFFFFF, 0xFFFFFFFF, 0x00000000, 0xFFFFFFFF, 1 }, + { 0xFC632551, 0xF3B9CAC2, 0xA7179E84, 0xBCE6FAAD, 0xFFFFFFFF, 0xFFFFFFFF, 0x00000000, 0xFFFFFFFF, 0 }, + { 0xFC632552, 0xF3B9CAC2, 0xA7179E84, 0xBCE6FAAD, 0xFFFFFFFF, 0xFFFFFFFF, 0x00000000, 0xFFFFFFFF, 0 } +}; + +/*---------------------------------------------------------------------------*/ + +void +test_ecc() +{ + uint32_t i; + + uint32_t order[8] = { 0xFC632551, 0xF3B9CAC2, 0xA7179E84, 0xBCE6FAAD, 0xFFFFFFFF, 0xFFFFFFFF, 0x00000000, 0xFFFFFFFF }; + for(i = 0; i < 3; i++) { + printf("ECC valid key test %d/3 - %s\n", i + 1, (ecc_is_valid_key(ecc_keys[i], order) == ecc_keys[i][8] ? "Succeed" : " Failed")); + } + + uint32_t base_x[8] = { 0xd898c296, 0xf4a13945, 0x2deb33a0, 0x77037d81, 0x63a440f2, 0xf8bce6e5, 0xe12c4247, 0x6b17d1f2 }; + uint32_t base_y[8] = { 0x37bf51f5, 0xcbb64068, 0x6b315ece, 0x2bce3357, 0x7c0f9e16, 0x8ee7eb4a, 0xfe1a7f9b, 0x4fe342e2 }; + uint32_t test_x[8]; + uint32_t test_y[8]; + for(i = 0; i < 32; i++) { + uint32_t time; + uint32_t checkvar; + + printf("Starting ECC test %d/221:\n", i + 1); + + time = *MACA_CLK; + ecc_ec_mult(test_x, test_y, base_x, base_y, ecc_data[i][SEC1]); + time = *MACA_CLK - time; + checkvar = 0; + checkvar += memcmp(ecc_data[i][PUB1_X], test_x, 32); + checkvar += memcmp(ecc_data[i][PUB1_Y], test_y, 32); + printf(" 1/4 finished after % 4u ms - %s\n", time / 250, (checkvar ? " Failed" : "Succeed")); + + time = *MACA_CLK; + ecc_ec_mult(test_x, test_y, ecc_data[i][PUB1_X], ecc_data[i][PUB1_Y], ecc_data[i][SEC2]); + time = *MACA_CLK - time; + checkvar = 0; + checkvar += memcmp(ecc_data[i][SHARED], test_x, 32); + printf(" 2/4 finished after % 4u ms - %s\n", time / 250, (checkvar ? " Failed" : "Succeed")); + + time = *MACA_CLK; + ecc_ec_mult(test_x, test_y, base_x, base_y, ecc_data[i][SEC2]); + time = *MACA_CLK - time; + checkvar = 0; + checkvar += memcmp(ecc_data[i][PUB2_X], test_x, 32); + checkvar += memcmp(ecc_data[i][PUB2_Y], test_y, 32); + printf(" 3/4 finished after % 4u ms - %s\n", time / 250, (checkvar ? " Failed" : "Succeed")); + + time = *MACA_CLK; + ecc_ec_mult(test_x, test_y, ecc_data[i][PUB2_X], ecc_data[i][PUB2_Y], ecc_data[i][SEC1]); + time = *MACA_CLK - time; + checkvar = 0; + checkvar += memcmp(ecc_data[i][SHARED], test_x, 32); + printf(" 4/4 finished after % 4u ms - %s\n", time / 250, (checkvar ? " Failed" : "Succeed")); + } +} +/* Start Process */ +PROCESS(server_firmware, "Server Firmware"); +AUTOSTART_PROCESSES(&server_firmware); + +PROCESS_THREAD(server_firmware, ev, data) { + PROCESS_BEGIN(); + + test_ecc(); + + PROCESS_END(); +} diff --git a/platform/econotag/apps/ecc/Makefile.ecc b/platform/econotag/apps/ecc/Makefile.ecc new file mode 100644 index 000000000..44dd816c2 --- /dev/null +++ b/platform/econotag/apps/ecc/Makefile.ecc @@ -0,0 +1 @@ +ecc_src = ecc.c diff --git a/platform/econotag/apps/ecc/ecc.c b/platform/econotag/apps/ecc/ecc.c new file mode 100644 index 000000000..8d8598d8b --- /dev/null +++ b/platform/econotag/apps/ecc/ecc.c @@ -0,0 +1,1016 @@ +/* + * Copyright (c) 2015, Lars Schmertmann , + * Jens Trillmann . + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * + * This file is part of the Contiki operating system. + * + */ + +#include "ecc.h" + +#include + +#define X 0 +#define Y 8 +#define Z 16 + +const uint32_t ecc_prime_m[8] = { 0xffffffff, 0xffffffff, 0xffffffff, 0x00000000, 0x00000000, 0x00000000, 0x00000001, 0xffffffff }; +const uint32_t ecc_prime_r[8] = { 0x00000001, 0x00000000, 0x00000000, 0xffffffff, 0xffffffff, 0xffffffff, 0xfffffffe, 0x00000000 }; + +/*---------------------------------------------------------------------------*/ + +#define DEBUG 0 +#define SELF_TEST 0 + +#if DEBUG +#include +#define PRINTF(...) printf(__VA_ARGS__) +#define PRINTHEX(...) print_hex(__VA_ARGS__) +static void +print_hex(const char *name, const uint32_t *d, uint32_t l) +{ + printf("%s:", name); + int i; + for(i = l - 1; i >= 0; --i) { + printf(" %08X", d[i]); + } + printf("\n"); +} +#else +#define PRINTF(...) +#define PRINTHEX(...) +#endif + +#if SELF_TEST +#include +static void selfTest(); +#endif + +/* private prototypes ----------------------------------------------------- */ + +/* simple functions to work with 256 bit numbers */ +static void ecc_setZero(uint32_t *a); +static void ecc_copy(uint32_t *dst, const uint32_t *src); +static uint32_t ecc_isX(const uint32_t *a, const uint32_t x); +static void ecc_rshift(uint32_t *a); +static void ecc_replace(uint32_t bit, uint32_t *dst, uint32_t *src); +static uint32_t ecc_add(uint32_t *result, const uint32_t *a, const uint32_t *b); +static uint32_t ecc_sub(uint32_t *result, const uint32_t *a, const uint32_t *b); +static void ecc_mult(uint32_t *result, const uint32_t *x, const uint32_t *y, const uint32_t length); + +/* ecc_field_ModP-Helper */ +__attribute__((always_inline)) static void ecc_form_s1(uint32_t *dst, const uint32_t *src); +__attribute__((always_inline)) static void ecc_form_s2(uint32_t *dst, const uint32_t *src); +__attribute__((always_inline)) static void ecc_form_s3(uint32_t *dst, const uint32_t *src); +__attribute__((always_inline)) static void ecc_form_s4(uint32_t *dst, const uint32_t *src); +__attribute__((always_inline)) static void ecc_form_d1(uint32_t *dst, const uint32_t *src); +__attribute__((always_inline)) static void ecc_form_d2(uint32_t *dst, const uint32_t *src); +__attribute__((always_inline)) static void ecc_form_d3(uint32_t *dst, const uint32_t *src); +__attribute__((always_inline)) static void ecc_form_d4(uint32_t *dst, const uint32_t *src); + +/* field functions for 256 bit numbers */ +static void ecc_field_Add(uint32_t *result, const uint32_t *x, const uint32_t *y); +static void ecc_field_Sub(uint32_t *result, const uint32_t *x, const uint32_t *y); +static void ecc_field_ModP(uint32_t *result, const uint32_t *T); +static void ecc_field_Mult(uint32_t *result, const uint32_t *A, const uint32_t *B); +static void ecc_field_Inv(uint32_t *result, const uint32_t *A); + +/* new projective stuff */ +static void ecc_projective_double(uint32_t *val); +static void ecc_projective_add(uint32_t *result, const uint32_t *val_1, const uint32_t *x_2, const uint32_t *y_2, const uint32_t *z_2); + +/* public functions -------------------------------------------------------- */ + +int32_t +ecc_compare(const uint32_t *a, const uint32_t *b) +{ + int32_t r = 0; + uint32_t i = 8; + while(i--) { + uint32_t neq = (a[i] != b[i]); + int32_t greater = (a[i] > b[i] ? 1 : -1); + r ^= ((-(!r && neq)) & (r ^ greater)); + } + return r; +} +void +ecc_ec_mult(uint32_t *resultx, uint32_t *resulty, const uint32_t *px, const uint32_t *py, const uint32_t *secret) +{ +#if SELF_TEST + selfTest(); +#endif + + PRINTHEX("PX", px, 8); + PRINTHEX("PY", py, 8); + PRINTHEX("SC", secret, 8); + + uint32_t Q[24]; + ecc_setZero(Q + X); + ecc_setZero(Q + Y); + ecc_setZero(Q + Z); + Q[Z] = 0x00000001; + + uint32_t pz[8]; + ecc_setZero(pz); + pz[0] = 0x00000001; + + uint32_t temp[24]; + + int i; + for(i = 255; i >= 0; --i) { + ecc_projective_double(Q); +/* PRINTHEX("QX", Q+X, 8); */ +/* PRINTHEX("QY", Q+Y, 8); */ +/* PRINTHEX("QZ", Q+Z, 8); */ + ecc_projective_add(temp, Q, px, py, pz); +/* PRINTHEX("QX", temp+X, 8); */ +/* PRINTHEX("QY", temp+Y, 8); */ +/* PRINTHEX("QZ", temp+Z, 8); */ + int current_bit = (secret[i / 32] >> (i % 32)) & 0x1; /* ((secret[i / 32]) & ((uint32_t)1 << (i % 32))); */ + ecc_replace(current_bit, Q, temp); +/* PRINTHEX("QX", Q+X, 8); */ +/* PRINTHEX("QY", Q+Y, 8); */ +/* PRINTHEX("QZ", Q+Z, 8); */ + } +/* PRINTHEX("QX", Q+X, 8); */ +/* PRINTHEX("QY", Q+Y, 8); */ +/* PRINTHEX("QZ", Q+Z, 8); */ + ecc_field_Inv(temp, Q + Z); + ecc_field_Mult(resultx, Q + X, temp); + ecc_field_Mult(resulty, Q + Y, temp); + PRINTHEX("RX", resultx, 8); + PRINTHEX("RY", resulty, 8); +} +/* private functions ------------------------------------------------------- */ + +static void +ecc_setZero(uint32_t *a) +{ + asm volatile ( + "mov r1, $0 \n\t" + "mov r2, r1 \n\t" + "mov r3, r2 \n\t" + "mov r4, r3 \n\t" + "stm %[a]!, {r1-r4} \n\t" + "stm %[a]!, {r1-r4} \n\t" + : /* out */ + : /* in */ + [a] "l" (a) + : /* clobber list */ + "r1", "r2", "r3", "r4", "memory" + ); +} +/* + * copy one array to another + */ +static void +ecc_copy(uint32_t *dst, const uint32_t *src) +{ + asm volatile ( + "ldm %[s]!, {r2-r5} \n\t" + "stm %[d]!, {r2-r5} \n\t" + "ldm %[s]!, {r2-r5} \n\t" + "stm %[d]!, {r2-r5} \n\t" + : /* out */ + : /* in */ + [d] "l" (dst), + [s] "l" (src) + : /* clobber list */ + "r2", "r3", "r4", "r5", "memory" + ); +} +static uint32_t +ecc_isX(const uint32_t *a, const uint32_t x) +{ + uint32_t r = (a[0] == x); + uint32_t n = 8; + while(--n) { + r &= (a[n] == 0); + } + return r; +} +static void +ecc_rshift(uint32_t *a) +{ + uint32_t index = 32; + uint32_t carry = 0; + + asm volatile ( + "0: \n\t" + "sub %[i], %[i], #4 \n\t" /* index -= 4 */ + "mov r4, %[c] \n\t" /* result = carry */ + "ldr r3, [%[a],%[i]] \n\t" /* value = a[index] */ + "lsl %[c], r3, #31 \n\t" /* carry = value << 31 */ + "lsr r3, r3, #1 \n\t" /* value >>= 1 */ + "orr r4, r4, r3 \n\t" /* result |= value */ + "str r4, [%[a],%[i]] \n\t" /* a[index] = result */ + "cmp %[i], $0 \n\t" /* index == 0 */ + "bne 0b \n\t" /* != ? next loop */ + : /* out */ + : /* in */ + [a] "r" (a), + [i] "r" (index), + [c] "r" (carry) + : /* clobber list */ + "r3", "r4", "memory" + ); +} +static void +ecc_replace(uint32_t bit, uint32_t *dst, uint32_t *src) +{ + bit = -bit; + int i; + for(i = 0; i < 24; i++) { + dst[i] ^= (bit & (dst[i] ^ src[i])); + } +} +static uint32_t +ecc_add(uint32_t *result, const uint32_t *a, const uint32_t *b) +{ + uint32_t carry; + + asm volatile ( + "ldm %[x]!, {r4,r5} \n\t" + "ldm %[y]!, {r6,r7} \n\t" + "add r4, r4, r6 \n\t" + "adc r5, r5, r7 \n\t" + "stm %[r]!, {r4,r5} \n\t" + "ldm %[x]!, {r4,r5} \n\t" + "ldm %[y]!, {r6,r7} \n\t" + "adc r4, r4, r6 \n\t" + "adc r5, r5, r7 \n\t" + "stm %[r]!, {r4,r5} \n\t" + "ldm %[x]!, {r4,r5} \n\t" + "ldm %[y]!, {r6,r7} \n\t" + "adc r4, r4, r6 \n\t" + "adc r5, r5, r7 \n\t" + "stm %[r]!, {r4,r5} \n\t" + "ldm %[x]!, {r4,r5} \n\t" + "ldm %[y]!, {r6,r7} \n\t" + "adc r4, r4, r6 \n\t" + "adc r5, r5, r7 \n\t" + "stm %[r]!, {r4,r5} \n\t" + "bcc 0f \n\t" + "mov %[c], #1 \n\t" + "b 1f \n\t" + "0: \n\t" + "mov %[c], $0 \n\t" + "1: \n\t" + : /* out */ + [c] "=l" (carry) + : /* in */ + [x] "l" (a), + [y] "l" (b), + [r] "l" (result) + : /* clobber list */ + "r4", "r5", "r6", "r7", "memory" + ); + + return carry; +} +static uint32_t +ecc_sub(uint32_t *result, const uint32_t *a, const uint32_t *b) +{ + uint32_t carry; + + asm volatile ( + "ldm %[x]!, {r4,r5} \n\t" + "ldm %[y]!, {r6,r7} \n\t" + "sub r4, r4, r6 \n\t" + "sbc r5, r5, r7 \n\t" + "stm %[r]!, {r4,r5} \n\t" + "ldm %[x]!, {r4,r5} \n\t" + "ldm %[y]!, {r6,r7} \n\t" + "sbc r4, r4, r6 \n\t" + "sbc r5, r5, r7 \n\t" + "stm %[r]!, {r4,r5} \n\t" + "ldm %[x]!, {r4,r5} \n\t" + "ldm %[y]!, {r6,r7} \n\t" + "sbc r4, r4, r6 \n\t" + "sbc r5, r5, r7 \n\t" + "stm %[r]!, {r4,r5} \n\t" + "ldm %[x]!, {r4,r5} \n\t" + "ldm %[y]!, {r6,r7} \n\t" + "sbc r4, r4, r6 \n\t" + "sbc r5, r5, r7 \n\t" + "stm %[r]!, {r4,r5} \n\t" + "bcs 0f \n\t" + "mov %[c], #1 \n\t" + "b 1f \n\t" + "0: \n\t" + "mov %[c], $0 \n\t" + "1: \n\t" + : /* out */ + [c] "=l" (carry) + : /* in */ + [x] "l" (a), + [y] "l" (b), + [r] "l" (result) + : /* clobber list */ + "r4", "r5", "r6", "r7", "memory" + ); + + return carry; +} +static void +ecc_mult(uint32_t *result, const uint32_t *x, const uint32_t *y, const uint32_t length) +{ + if(length == 1) { + /* Version 1: 56 Byte bigger as ASM-Version */ + /* uint64_t *r = (uint64_t *) result; */ + /* *r = (uint64_t) x[0] * (uint64_t) y[0]; */ + + /* Version 2: 56 Byte lesser as Version 1 but same speed */ + asm volatile ( + "ldrh r5, [%[x], $0] \n\t" /* r5 = (x[0] & 0x0000FFFF) */ + "ldrh r3, [%[y], $0] \n\t" /* r3 = (y[0] & 0x0000FFFF) */ + "mul r5, r3 \n\t" /* r5 *= r3 r5 = AB[0] */ + "ldrh r6, [%[x], #2] \n\t" /* r6 = (x[0] >> 16) */ + "mul r3, r6 \n\t" /* r3 *= r6 r3 = C[0] */ + "ldrh r4, [%[y], #2] \n\t" /* r4 = (y[0] >> 16) */ + "mul r6, r4 \n\t" /* r6 *= r4 r6 = AB[1] */ + /* %[y] is not longer needed - its called ry now */ + "ldrh %[y], [%[x], $0] \n\t" /* ry = (x[0] & 0x0000FFFF) */ + "mul r4, %[y] \n\t" /* r4 *= ry r4 = C[1] */ + "add %[y], r3, r4 \n\t" /* ry = r3 + r4 ry = C[0] + C[1] */ + /* C[1] (r4) is not longer needed */ + "mov r4, $0 \n\t" /* r4 = 0 */ + "bcc 0f \n\t" /* jump if carry clear */ + "mov r4, #1 \n\t" /* r4 = 1 */ + "lsl r4, r4, #16 \n\t" /* r4 <<= 16 */ + "0: \n\t" /* r4 = 0x000c0000 = (carry << 16) */ + "lsr r3, %[y], #16 \n\t" /* r3 = (ry >> 16) */ + "orr r4, r4, r3 \n\t" /* r4 |= r3 r4 = 0x000c'ryh' = (r4 | ry >> 16) */ + "lsl r3, %[y], #16 \n\t" /* r3 = (ry << 16) r3 = 0x'ryl'0000 = (ry << 16) */ + "add r3, r3, r5 \n\t" + "adc r4, r4, r6 \n\t" + "stm %[r]!, {r3, r4} \n\t" + : /* out */ + : /* in */ + [x] "l" (x), + [y] "l" (y), + [r] "l" (result) + : /* clobber list */ + "r3", "r4", "r5", "r6", "memory" + ); + } else { + uint32_t carry; + uint32_t C[length * 2]; + ecc_mult(result, x, y, length / 2); + ecc_mult(result + length, x + (length / 2), y + (length / 2), length / 2); + ecc_mult(C, x, y + (length / 2), length / 2); + ecc_mult(C + length, x + (length / 2), y, length / 2); + if(length == 8) { + carry = ecc_add(C, C, C + length); + } else { + asm volatile ( + "cmp %[l], #2 \n\t" + "beq .add2 \n\t" + /* ASM for: ecc_add(C, C, C + 4, 4); */ + "mov %[l], %[a] \n\t" + "ldm %[a]!, {r3-r6} \n\t" + "ldm %[a]!, {r5,r6} \n\t" + "sub %[a], %[a], #16 \n\t" + "add r3, r3, r5 \n\t" + "adc r4, r4, r6 \n\t" + "stm %[l]!, {r3,r4} \n\t" + "ldm %[a]!, {r3-r6} \n\t" + "ldm %[a]!, {r5,r6} \n\t" + "adc r3, r3, r5 \n\t" + "adc r4, r4, r6 \n\t" + "stm %[l]!, {r3,r4} \n\t" + "b 0f \n\t" + ".add2: \n\t" + /* ASM for: ecc_add(C, C, C + 2, 2); */ + "ldm %[a]!, {r3-r6} \n\t" + "sub %[a], %[a], #16 \n\t" + "add r3, r3, r5 \n\t" + "adc r4, r4, r6 \n\t" + "stm %[a]!, {r3,r4} \n\t" + "0: \n\t" + "bcc 1f \n\t" + "mov %[c], #1 \n\t" + "b 2f \n\t" + "1: \n\t" + "mov %[c], $0 \n\t" + "2: \n\t" + : /* out */ + [c] "=l" (carry) + : /* in */ + [a] "l" (C), + [l] "l" (length) + : /* clobber list */ + "r3", "r4", "r5", "r6", "memory" + ); + } C[length] = carry; + asm volatile ( + "cmp %[l], #2 \n\t" + "beq .add3 \n\t" + "cmp %[l], #4 \n\t" + "beq .add6 \n\t" + ".add12: \n\t" + /* ASM for: ecc_add(result + 4, result + 4, C, 12); */ + /* RRRRRRRRRRRRRRRR */ + /* + CCCCCCCCC000 */ + /* = RRRRRRRRRRRRRRRR */ + "add %[r], %[r], #16 \n\t" + "mov %[l], %[r] \n\t" + "ldm %[r]!, {r3,r4} \n\t" + "ldm %[c]!, {r5,r6} \n\t" + "add r3, r3, r5 \n\t" + "adc r4, r4, r6 \n\t" + "stm %[l]!, {r3,r4} \n\t" + "ldm %[r]!, {r3,r4} \n\t" + "ldm %[c]!, {r5,r6} \n\t" + "adc r3, r3, r5 \n\t" + "adc r4, r4, r6 \n\t" + "stm %[l]!, {r3,r4} \n\t" + "ldm %[r]!, {r3,r4} \n\t" + "ldm %[c]!, {r5,r6} \n\t" + "adc r3, r3, r5 \n\t" + "adc r4, r4, r6 \n\t" + "stm %[l]!, {r3,r4} \n\t" + "ldm %[r]!, {r3,r4} \n\t" + "ldm %[c]!, {r5,r6} \n\t" + "adc r3, r3, r5 \n\t" + "adc r4, r4, r6 \n\t" + "stm %[l]!, {r3,r4} \n\t" + "ldm %[r]!, {r3,r4} \n\t" + "ldm %[c]!, {r5} \n\t" + "mov r6, $0 \n\t" + "adc r3, r3, r5 \n\t" + "adc r4, r4, r6 \n\t" + "stm %[l]!, {r3,r4} \n\t" + "ldm %[r]!, {r3,r4} \n\t" + "adc r3, r3, r6 \n\t" + "adc r4, r4, r6 \n\t" + "stm %[l]!, {r3,r4} \n\t" + "b 0f \n\t" + ".add6: \n\t" + /* ASM for: ecc_add(result + 2, result + 2, C, 6); */ + /* RRRRRRRR */ + /* + CCCCC0 */ + /* = RRRRRRRR */ + "add %[r], %[r], #8 \n\t" + "mov %[l], %[r] \n\t" + "ldm %[r]!, {r3,r4} \n\t" + "ldm %[c]!, {r5,r6} \n\t" + "add r3, r3, r5 \n\t" + "adc r4, r4, r6 \n\t" + "stm %[l]!, {r3,r4} \n\t" + "ldm %[r]!, {r3,r4} \n\t" + "ldm %[c]!, {r5,r6} \n\t" + "adc r3, r3, r5 \n\t" + "adc r4, r4, r6 \n\t" + "stm %[l]!, {r3,r4} \n\t" + "ldm %[r]!, {r3,r4} \n\t" + "ldm %[c]!, {r5} \n\t" + "mov r6, $0 \n\t" + "adc r3, r3, r5 \n\t" + "adc r4, r4, r6 \n\t" + "stm %[l]!, {r3,r4} \n\t" + "b 0f \n\t" + ".add3: \n\t" + /* ASM for: ecc_add(result + 1, result + 1, C, 3); */ + /* RRRR */ + /* + CCC */ + /* = RRRR */ + "add %[r], %[r], #4 \n\t" + "mov %[l], %[r] \n\t" + "ldm %[r]!, {r3,r4} \n\t" + "ldm %[c]!, {r5,r6} \n\t" + "add r3, r3, r5 \n\t" + "adc r4, r4, r6 \n\t" + "ldr r5, [%[r], $0] \n\t" + "ldr r6, [%[c], $0] \n\t" + "adc r5, r5, r6 \n\t" + "stm %[l]!, {r3-r5} \n\t" + "0: \n\t" + : /* out */ + : /* in */ + [r] "l" (result), + [c] "l" (C), + [l] "l" (length) + : /* clobber list */ + "r3", "r4", "r5", "r6", "memory" + ); + } +} +/*---------------------------------------------------------------------------*/ + +__attribute__((always_inline)) static void +ecc_form_s1(uint32_t *dst, const uint32_t *src) +{ + /* 0, 0, 0, src[11], src[12], src[13], src[14], src[15] */ + asm volatile ( + "mov r2, $0 \n\t" + "mov r3, r2 \n\t" + "mov r4, r3 \n\t" + "stm %[d]!, {r2-r4} \n\t" + "add %[s], #44 \n\t" + "ldm %[s]!, {r2-r6} \n\t" + "stm %[d]!, {r2-r6} \n\t" + : /* out */ + [d] "+l" (dst), + [s] "+l" (src) + : /* in */ + : /* clobber list */ + "r2", "r3", "r4", "r5", "r6", "memory" + ); +} +__attribute__((always_inline)) static void +ecc_form_s2(uint32_t *dst, const uint32_t *src) +{ + /* 0, 0, 0, src[12], src[13], src[14], src[15], 0 */ + asm volatile ( + "mov r2, $0 \n\t" + "mov r3, r2 \n\t" + "mov r4, r3 \n\t" + "stm %[d]!, {r2-r4} \n\t" + "add %[s], #48 \n\t" + "ldm %[s]!, {r2-r5} \n\t" + "stm %[d]!, {r2-r5} \n\t" + "mov r2, $0 \n\t" + "stm %[d]!, {r2} \n\t" + : /* out */ + [d] "+l" (dst), + [s] "+l" (src) + : /* in */ + : /* clobber list */ + "r2", "r3", "r4", "r5", "memory" + ); +} +__attribute__((always_inline)) static void +ecc_form_s3(uint32_t *dst, const uint32_t *src) +{ + /* src[8], src[9], src[10], 0, 0, 0, src[14], src[15] */ + asm volatile ( + "add %[s], #32 \n\t" + "ldm %[s]!, {r2-r4} \n\t" + "mov r5, $0 \n\t" + "stm %[d]!, {r2-r5} \n\t" + "mov r2, r5 \n\t" + "mov r3, r2 \n\t" + "add %[s], #12 \n\t" + "ldm %[s]!, {r4,r5} \n\t" + "stm %[d]!, {r2-r5} \n\t" + : /* out */ + [d] "+l" (dst), + [s] "+l" (src) + : /* in */ + : /* clobber list */ + "r2", "r3", "r4", "r5", "memory" + ); +} +__attribute__((always_inline)) static void +ecc_form_s4(uint32_t *dst, const uint32_t *src) +{ + /* src[9], src[10], src[11], src[13], src[14], src[15], src[13], src[8] */ + asm volatile ( + "add %[s], #32 \n\t" + "ldm %[s]!, {r2-r5} \n\t" + "stm %[d]!, {r3-r5} \n\t" + "add %[s], #4 \n\t" + "ldm %[s]!, {r3-r5} \n\t" + "stm %[d]!, {r3-r5} \n\t" + "mov r4, r2 \n\t" + "stm %[d]!, {r3,r4} \n\t" + : /* out */ + [d] "+l" (dst), + [s] "+l" (src) + : /* in */ + : /* clobber list */ + "r2", "r3", "r4", "r5", "memory" + ); +} +__attribute__((always_inline)) static void +ecc_form_d1(uint32_t *dst, const uint32_t *src) +{ + /* src[11], src[12], src[13], 0, 0, 0, src[8], src[10] */ + asm volatile ( + "add %[s], #32 \n\t" + "ldm %[s]!, {r2-r7} \n\t" + "stm %[d]!, {r5-r7} \n\t" + "mov r3, $0 \n\t" + "mov r5, r3 \n\t" + "mov r6, r5 \n\t" + "stm %[d]!, {r3,r5,r6} \n\t" + "stm %[d]!, {r2,r4} \n\t" + : /* out */ + [d] "+l" (dst), + [s] "+l" (src) + : /* in */ + : /* clobber list */ + "r2", "r3", "r4", "r5", "r6", "r7", "memory" + ); +} +__attribute__((always_inline)) static void +ecc_form_d2(uint32_t *dst, const uint32_t *src) +{ + /* src[12], src[13], src[14], src[15], 0, 0, src[9], src[11] */ + asm volatile ( + "add %[s], #48 \n\t" + "ldm %[s]!, {r2-r5} \n\t" + "stm %[d]!, {r2-r5} \n\t" + "sub %[s], #28 \n\t" + "ldm %[s]!, {r4-r6} \n\t" + "mov r2, $0 \n\t" + "mov r3, r2 \n\t" + "stm %[d]!, {r2-r4,r6} \n\t" + : /* out */ + [d] "+l" (dst), + [s] "+l" (src) + : /* in */ + : /* clobber list */ + "r2", "r3", "r4", "r5", "r6", "memory" + ); +} +__attribute__((always_inline)) static void +ecc_form_d3(uint32_t *dst, const uint32_t *src) +{ + /* src[13], src[14], src[15], src[8], src[9], src[10], 0, src[12] */ + asm volatile ( + "add %[s], #52 \n\t" + "ldm %[s]!, {r2-r4} \n\t" + "stm %[d]!, {r2-r4} \n\t" + "sub %[s], #32 \n\t" + "ldm %[s]!, {r2-r6} \n\t" + "mov r5, $0 \n\t" + "stm %[d]!, {r2-r6} \n\t" + : /* out */ + [d] "+l" (dst), + [s] "+l" (src) + : /* in */ + : /* clobber list */ + "r2", "r3", "r4", "r5", "r6", "memory" + ); +} +__attribute__((always_inline)) static void +ecc_form_d4(uint32_t *dst, const uint32_t *src) +{ + /* src[14], src[15], 0, src[9], src[10], src[11], 0, src[13] */ + asm volatile ( + "add %[s], #56 \n\t" + "ldm %[s]!, {r2,r3} \n\t" + "mov r4, $0 \n\t" + "stm %[d]!, {r2-r4} \n\t" + "sub %[s], #28 \n\t" + "ldm %[s]!, {r2-r6} \n\t" + "mov r5, $0 \n\t" + "stm %[d]!, {r2-r6} \n\t" + : /* out */ + [d] "+l" (dst), + [s] "+l" (src) + : /* in */ + : /* clobber list */ + "r2", "r3", "r4", "r5", "r6", "memory" + ); +} +/*---------------------------------------------------------------------------*/ + +static void +ecc_field_Add(uint32_t *result, const uint32_t *x, const uint32_t *y) +{ + uint32_t temp[8]; + uint32_t carry = -ecc_add(result, x, y); + ecc_add(temp, result, ecc_prime_r); + + int i; + for(i = 0; i < 8; i++) { + result[i] ^= (carry & (result[i] ^ temp[i])); + } +} +static void +ecc_field_Sub(uint32_t *result, const uint32_t *x, const uint32_t *y) +{ + uint32_t temp[8]; + uint32_t carry = -ecc_sub(result, x, y); + ecc_add(temp, result, ecc_prime_m); + + int i; + for(i = 0; i < 8; i++) { + result[i] ^= (carry & (result[i] ^ temp[i])); + } +} +static void +ecc_field_ModP(uint32_t *result, const uint32_t *T) +{ + uint32_t SX_o_DX[8]; + ecc_copy(result, T); /* result = T */ + + ecc_form_s1(SX_o_DX, T); /* Form S1 */ + ecc_field_Add(result, result, SX_o_DX); /* result = T + S1 */ + ecc_field_Add(result, result, SX_o_DX); /* result = T + S1 + S1 */ + + ecc_form_s2(SX_o_DX, T); /* Form S2 */ + ecc_field_Add(result, result, SX_o_DX); /* result = T + S1 + S1 + S2 */ + ecc_field_Add(result, result, SX_o_DX); /* result = T + S1 + S1 + S2 + S2 */ + + ecc_form_s3(SX_o_DX, T); /* Form S3 */ + ecc_field_Add(result, result, SX_o_DX); /* result = T + S1 + S1 + S2 + S2 + S3 */ + + ecc_form_s4(SX_o_DX, T); /* Form S4 */ + ecc_field_Add(result, result, SX_o_DX); /* result = T + S1 + S1 + S2 + S2 + S3 + S4 */ + + ecc_form_d1(SX_o_DX, T); /* Form D1 */ + ecc_field_Sub(result, result, SX_o_DX); /* result = T + S1 + S1 + S2 + S2 + S3 + S4 - D1 */ + + ecc_form_d2(SX_o_DX, T); /* Form D2 */ + ecc_field_Sub(result, result, SX_o_DX); /* result = T + S1 + S1 + S2 + S2 + S3 + S4 - D1 - D2 */ + + ecc_form_d3(SX_o_DX, T); /* Form D3 */ + ecc_field_Sub(result, result, SX_o_DX); /* result = T + S1 + S1 + S2 + S2 + S3 + S4 - D1 - D2 - D3 */ + + ecc_form_d4(SX_o_DX, T); /* Form D4 */ + ecc_field_Sub(result, result, SX_o_DX); /* result = T + S1 + S1 + S2 + S2 + S3 + S4 - D1 - D2 - D3 - D4 */ + + if(ecc_compare(result, ecc_prime_m) >= 0) { + ecc_field_Sub(result, result, ecc_prime_m); + } +} +static void +ecc_field_Mult(uint32_t *result, const uint32_t *A, const uint32_t *B) +{ + uint32_t product[16]; + ecc_mult(product, A, B, 8); + ecc_field_ModP(result, product); +} +static void +ecc_field_Inv(uint32_t *result, const uint32_t *A) +{ + PRINTHEX("Input", A, 8); + + ecc_setZero(result); + result[0] = 0x00000001; + int i; + for(i = 255; i >= 0; --i) { + ecc_field_Mult(result, result, result); + if(((ecc_prime_m[i / 32] >> (i % 32)) & 0x1) == 1 && i != 1) { + ecc_field_Mult(result, result, A); + } + } + + PRINTHEX("Result", result, 8); +} +/*---------------------------------------------------------------------------*/ + +static void +ecc_projective_double(uint32_t *val) +{ + /* Algorithm taken from https://hyperelliptic.org/EFD/g1p/auto-shortw-projective-3.html#doubling-dbl-2007-bl-2 */ + /* w = 3*(X1-Z1)*(X1+Z1) */ + /* s = 2*Y1*Z1 */ + /* ss = s^2 */ + /* sss = s*ss */ + /* R = Y1*s */ + /* RR = R^2 */ + /* B = 2*X1*R */ + /* h = w^2-2*B */ + /* X3 = h*s */ + /* Y3 = w*(B-h)-2*RR */ + /* Z3 = sss */ + + uint32_t temp[24]; + uint32_t w[8]; + uint32_t s[8]; + uint32_t B[8]; + uint32_t h[8]; + + uint8_t is_zero = ecc_isX(val + X, 0) & ecc_isX(val + Y, 0) & ecc_isX(val + Z, 1); + + ecc_field_Sub(temp + X, val + X, val + Z); + ecc_field_Add(temp + Y, val + X, val + Z); + ecc_field_Mult(temp + Z, temp + X, temp + Y); + ecc_field_Add(temp + X, temp + Z, temp + Z); + ecc_field_Add(w, temp + Z, temp + X); + ecc_field_Mult(temp + X, val + Y, val + Z); + ecc_field_Add(s, temp + X, temp + X); + ecc_field_Mult(temp + X, s, s); + ecc_field_Mult(val + Z, s, temp + X); + ecc_field_Mult(temp + X, val + Y, s); /* temp = R */ + ecc_field_Mult(temp + Z, temp + X, temp + X); /* temp3 = RR */ + ecc_field_Mult(temp + Y, val + X, temp + X); /* temp2 = R*x */ + ecc_field_Add(B, temp + Y, temp + Y); /* B = 2*R*x */ + ecc_field_Mult(temp + X, w, w); + ecc_field_Add(temp + Y, B, B); + ecc_field_Sub(h, temp + X, temp + Y); + ecc_field_Mult(val + X, h, s); + ecc_field_Sub(temp + X, B, h); + ecc_field_Mult(temp + Y, w, temp + X); + ecc_field_Add(temp + Z, temp + Z, temp + Z); /* temp3 = 2*RR */ + ecc_field_Sub(val + Y, temp + Y, temp + Z); + /* finished, now swap the result if necessary */ + + ecc_setZero(temp + X); + ecc_setZero(temp + Y); + ecc_setZero(temp + Z); + (temp + Z)[0] = 0x00000001; + + ecc_replace(is_zero, val, temp); +} +static void +ecc_projective_add(uint32_t *result, const uint32_t *val_1, const uint32_t *x_2, const uint32_t *y_2, const uint32_t *z_2) +{ +/* algorithm taken from https://hyperelliptic.org/EFD/g1p/auto-shortw-projective-3.html#addition-add-1998-cmo-2 */ +/* X Z X Y U Y */ +/* 1 1 2 2 U UU V 1V */ +/* Z R Z ZVZ R UZZ VR ZY */ +/* VX 2RAY 2Z 1V1UA UZV V2A 2Z */ +/* Y1Z2 = Y1*Z2 | */ +/* X2Z1 = X2*Z1 | | */ +/* X1Z2 = X1*Z2 | | | */ +/* V = X2Z1-X1Z2 | x x | */ +/* VV = V^2 x | | | */ +/* R = VV*X1Z2 | x| x | */ +/* VVV = V*VV x | x | | */ +/* Y2Z1 = Y2*Z1 | | | | | */ +/* U = Y2Z1-Y1Z2 | | x| | x */ +/* UU = U^2 | | x | | | */ +/* Z1Z2 = Z1*Z2 | | | | | | | */ +/* UUZZ = UU*Z1Z2 | | x | x| | | */ +/* UZV = UUZZ-VVV | | | | x| x | */ +/* Z = VVV*Z1Z2 | | x| | | x | */ +/* VYZ = VVV*Y1Z2 | | | | | x x| */ +/* R2 = 2*R | x | | | | | */ +/* A = UZV-2R | | | | x x| | */ +/* X = V*A x| | | | x | */ +/* RA = R-A | x| | | x | */ +/* URA = U*RA | x | x| | */ +/* Y = URA-VYZ | | | x x */ + + uint32_t temp[32]; + #define X1 val_1 + X + #define Y1 val_1 + Y + #define Z1 val_1 + Z + #define X2 x_2 + #define Y2 y_2 + #define Z2 z_2 + #define V result + X + #define X1Z2 result + Y + #define R result + Y + #define RA result + Y + #define Z1Z2 result + Z + #define X2Z1 temp + X + #define VV temp + X + #define Y2Z1 temp + X + #define U temp + X + #define URA temp + X + #define UU temp + Y + #define UUZZ temp + Y + #define UZV temp + Y + #define VVV temp + Z + #define R2 temp + Z + #define A temp + Z + #define Y1Z2 temp + 24 + #define VYZ temp + 24 + + uint8_t is_input1_zero = ecc_isX(val_1 + X, 0) & ecc_isX(val_1 + Y, 0) & ecc_isX(val_1 + Z, 1); + uint8_t is_input2_zero = ecc_isX(x_2, 0) & ecc_isX(y_2, 0) & ecc_isX(z_2, 1); + + ecc_copy(temp + X, x_2); + ecc_copy(temp + Y, y_2); + ecc_copy(temp + Z, z_2); + ecc_replace(is_input1_zero, result, temp); + + ecc_copy(temp + X, val_1 + X); + ecc_copy(temp + Y, val_1 + Y); + ecc_copy(temp + Z, val_1 + Z); + ecc_replace(is_input2_zero, result, temp); + + /* invalidate the result pointer */ + result = (uint32_t *)((uintptr_t)result ^ (-(is_input2_zero | is_input1_zero) & ((uintptr_t)result ^ (uintptr_t)temp))); + + ecc_field_Mult(Y1Z2, Y1, Z2); + ecc_field_Mult(X2Z1, X2, Z1); + ecc_field_Mult(X1Z2, X1, Z2); + ecc_field_Sub(V, X2Z1, X1Z2); + ecc_field_Mult(VV, V, V); + ecc_field_Mult(R, VV, X1Z2); + ecc_field_Mult(VVV, V, VV); + ecc_field_Mult(Y2Z1, Y2, Z1); + ecc_field_Sub(U, Y2Z1, Y1Z2); + ecc_field_Mult(UU, U, U); + ecc_field_Mult(Z1Z2, Z1, Z2); + ecc_field_Mult(UUZZ, UU, Z1Z2); + ecc_field_Sub(UZV, UUZZ, VVV); + ecc_field_Mult(result + Z, VVV, Z1Z2); + ecc_field_Mult(VYZ, VVV, Y1Z2); + ecc_field_Add(R2, R, R); + ecc_field_Sub(A, UZV, R2); + ecc_field_Mult(result + X, V, A); + ecc_field_Sub(RA, R, A); + ecc_field_Mult(URA, U, RA); + ecc_field_Sub(result + Y, URA, VYZ); +} +/*---------------------------------------------------------------------------*/ + +#if SELF_TEST +static void +assertTrue(uint32_t value, const char *msg) +{ + if(!value) { + printf("%s\n", msg); + } +} +static void +assertFalse(uint32_t value, const char *msg) +{ + if(value) { + printf("%s\n", msg); + } +} +static void +assertSame(uint32_t *val_1, uint32_t *val_2, const char *msg) +{ + if(ecc_compare(val_1, val_2)) { + printf("%s\n", msg); + } +} +static void +selfTest() +{ + uint32_t num_000[8] = { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 }; + uint32_t num_001[8] = { 0x00000001, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 }; + uint32_t num_002[8] = { 0x00000002, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 }; + uint32_t num_004[8] = { 0x00000004, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 }; + uint32_t num_max[8] = { 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff }; + uint32_t primeMinusOne[8] = { 0xfffffffe, 0xffffffff, 0xffffffff, 0x00000000, 0x00000000, 0x00000000, 0x00000001, 0xffffffff }; + + uint32_t result[8]; + + /* ecc_compare */ + assertFalse(ecc_compare(num_001, num_001), "ecc_compare 1: Wrong result!"); + assertTrue(ecc_compare(num_000, num_001) == -1, "ecc_compare 2: Wrong result!"); + assertTrue(ecc_compare(num_001, num_000) == 1, "ecc_compare 3: Wrong result!"); + + /* ecc_isX */ + assertTrue(ecc_isX(num_000, 0), "ecc_isX 1: Wrong result!"); + assertTrue(ecc_isX(num_001, 1), "ecc_isX 2: Wrong result!"); + assertTrue(ecc_isX(num_002, 2), "ecc_isX 3: Wrong result!"); + assertTrue(ecc_isX(num_004, 4), "ecc_isX 4: Wrong result!"); + assertFalse(ecc_isX(num_000, 1), "ecc_isX 5: Wrong result!"); + assertFalse(ecc_isX(num_000, 2), "ecc_isX 6: Wrong result!"); + assertFalse(ecc_isX(num_000, 4), "ecc_isX 7: Wrong result!"); + assertFalse(ecc_isX(num_001, 0), "ecc_isX 8: Wrong result!"); + assertFalse(ecc_isX(num_001, 2), "ecc_isX 9: Wrong result!"); + assertFalse(ecc_isX(num_001, 4), "ecc_isX 10: Wrong result!"); + assertFalse(ecc_isX(num_002, 0), "ecc_isX 11: Wrong result!"); + assertFalse(ecc_isX(num_002, 1), "ecc_isX 12: Wrong result!"); + assertFalse(ecc_isX(num_002, 4), "ecc_isX 13: Wrong result!"); + assertFalse(ecc_isX(num_004, 0), "ecc_isX 14: Wrong result!"); + assertFalse(ecc_isX(num_004, 1), "ecc_isX 15: Wrong result!"); + assertFalse(ecc_isX(num_004, 2), "ecc_isX 16: Wrong result!"); + + /* ecc_add */ + assertFalse(ecc_add(result, num_001, num_002), "ecc_add 1: Unexpected carrybit!"); + assertFalse(ecc_add(result, result, num_001), "ecc_add 2: Unexpected carrybit!"); + assertSame(result, num_004, "ecc_add 3: Wrong result!"); + assertTrue(ecc_add(result, num_max, num_002), "ecc_add 4: Carrybit missing!"); + assertSame(result, num_001, "ecc_add 5: Wrong result!"); + + /* ecc_sub */ + assertFalse(ecc_sub(result, num_004, num_002), "ecc_sub 1: Unexpected carrybit!"); + assertFalse(ecc_sub(result, result, num_001), "ecc_sub 2: Unexpected carrybit!"); + assertFalse(ecc_sub(result, result, num_001), "ecc_sub 3: Unexpected carrybit!"); + assertSame(result, num_000, "ecc_sub 4: Wrong result!"); + assertTrue(ecc_sub(result, num_000, num_001), "ecc_sub 5: Carrybit missing!"); + assertSame(result, num_max, "ecc_sub 6: Wrong result!"); + + /* ecc_field_Sub */ + ecc_field_Sub(result, num_001, num_000); + assertSame(num_001, result, "ecc_field_Sub 1: Wrong result!"); + ecc_field_Sub(result, num_001, num_001); + assertSame(num_000, result, "ecc_field_Sub 2: Wrong result!"); + ecc_field_Sub(result, num_000, num_001); + assertSame(primeMinusOne, result, "ecc_field_Sub 3: Wrong result!"); + + printf("Tests completed!\n"); +} +#endif diff --git a/platform/econotag/apps/ecc/ecc.h b/platform/econotag/apps/ecc/ecc.h new file mode 100644 index 000000000..b90b55260 --- /dev/null +++ b/platform/econotag/apps/ecc/ecc.h @@ -0,0 +1,103 @@ +/* + * Copyright (c) 2015, Lars Schmertmann , + * Jens Trillmann . + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * + * This file is part of the Contiki operating system. + * + */ + +/** + * \file + * Calculations on elliptic curve secp256r1 + * + * This is a efficient ECC implementation on the secp256r1 curve for + * 32 Bit CPU architectures. It provides basic operations on the + * secp256r1 curve and support for ECDH and ECDSA. + * + * \author + * Lars Schmertmann + * Jens Trillmann + */ + +#ifndef ECC_H_ +#define ECC_H_ + +#include + +/** + * \brief Checks if a (random) number is valid as scalar on elliptic curve secp256r1 + * + * A (random) number is only usable as scalar on elliptic curve secp256r1 if + * it is lower than the order of the curve. For the check, you need to provide + * the order of elliptic curve secp256r1. + * + * uint32_t order[8] = {0xFC632551, 0xF3B9CAC2, 0xA7179E84, 0xBCE6FAAD, 0xFFFFFFFF, 0xFFFFFFFF, 0x00000000, 0xFFFFFFFF}; + * + * \param key The (random) number to check for usability + * \param order The order of elliptic curve secp256r1 + * + * \return 1 if key is valid + */ +#define ecc_is_valid_key(key, order) (ecc_compare(order, key) == 1) + +/** + * \brief Compares the value of a with the value of b + * + * This function is only public because its needed for the macro ecc_is_valid_key. + * It does a comparison of two 256 bit numbers. The return values are 1, 0 or -1. + * + * \param a First number + * \param b Second number + * + * \return 1 if a is greater than b + 0 if a is equal to b + -1 if a is less than b + */ +int32_t ecc_compare(const uint32_t *a, const uint32_t *b); + +/** + * \brief ECC scalar multiplication on elliptic curve secp256r1 + * + * This function does a scalar multiplication on elliptic curve secp256r1. + * For an Elliptic curve Diffie–Hellman you need two multiplications. First one + * with the base point of elliptic curve secp256r1 you need to provide. + * + * uint32_t base_x[8] = {0xd898c296, 0xf4a13945, 0x2deb33a0, 0x77037d81, 0x63a440f2, 0xf8bce6e5, 0xe12c4247, 0x6b17d1f2}; + * uint32_t base_y[8] = {0x37bf51f5, 0xcbb64068, 0x6b315ece, 0x2bce3357, 0x7c0f9e16, 0x8ee7eb4a, 0xfe1a7f9b, 0x4fe342e2}; + * + * \param resultx Pointer to memory to store the x-coordinate of the result + * \param resulty Pointer to memory to store the y-coordinate of the result + * \param px x-coordinate of the point to multiply with scalar + * \param py y-coordinate of the point to multiply with scalar + * \param secret Scalar for multiplication with elliptic curve point + */ +void ecc_ec_mult(uint32_t *resultx, uint32_t *resulty, const uint32_t *px, const uint32_t *py, const uint32_t *secret); + +#endif /* ECC_H_ */ diff --git a/regression-tests/15-compile-arm-apcs-ports/Makefile b/regression-tests/15-compile-arm-apcs-ports/Makefile index 767bed60f..61873d531 100644 --- a/regression-tests/15-compile-arm-apcs-ports/Makefile +++ b/regression-tests/15-compile-arm-apcs-ports/Makefile @@ -9,6 +9,7 @@ er-rest-example/econotag \ webserver-ipv6/econotag \ ipv6/multicast/econotag \ econotag-flash-test/econotag \ +econotag-ecc-test/econotag \ TOOLS= From 1b0cdee9eca4037371fe67128be9a659873253da Mon Sep 17 00:00:00 2001 From: Joakim Eriksson Date: Wed, 6 May 2015 18:14:29 +0200 Subject: [PATCH 099/120] Fixed observe to handle subresources and to always create a fake request for notify GETs --- apps/er-coap/er-coap-observe.c | 54 +++++++++++++++++++++++++++------- apps/er-coap/er-coap-observe.h | 10 +++---- apps/rest-engine/rest-engine.c | 2 +- 3 files changed, 48 insertions(+), 18 deletions(-) diff --git a/apps/er-coap/er-coap-observe.c b/apps/er-coap/er-coap-observe.c index 710671bff..ef533cf70 100644 --- a/apps/er-coap/er-coap-observe.c +++ b/apps/er-coap/er-coap-observe.c @@ -58,9 +58,9 @@ LIST(observers_list); /*---------------------------------------------------------------------------*/ /*- Internal API ------------------------------------------------------------*/ /*---------------------------------------------------------------------------*/ -coap_observer_t * -coap_add_observer(uip_ipaddr_t *addr, uint16_t port, const uint8_t *token, - size_t token_len, const char *uri) +static coap_observer_t * +add_observer(uip_ipaddr_t *addr, uint16_t port, const uint8_t *token, + size_t token_len, const char *uri, int uri_len) { /* Remove existing observe relationship, if any. */ coap_remove_observer_by_uri(addr, port, uri); @@ -68,7 +68,12 @@ coap_add_observer(uip_ipaddr_t *addr, uint16_t port, const uint8_t *token, coap_observer_t *o = memb_alloc(&observers_memb); if(o) { - o->url = uri; + int max = sizeof(o->url) - 1; + if(max > uri_len) { + max = uri_len; + } + memcpy(o->url, uri, max); + o->url[max] = 0; uip_ipaddr_copy(&o->addr, addr); o->port = port; o->token_len = token_len; @@ -177,18 +182,45 @@ coap_remove_observer_by_mid(uip_ipaddr_t *addr, uint16_t port, uint16_t mid) /*---------------------------------------------------------------------------*/ void coap_notify_observers(resource_t *resource) +{ + coap_notify_observers_sub(resource, NULL); +} +void +coap_notify_observers_sub(resource_t *resource, const char *subpath) { /* build notification */ coap_packet_t notification[1]; /* this way the packet can be treated as pointer as usual */ - coap_init_message(notification, COAP_TYPE_NON, CONTENT_2_05, 0); + coap_packet_t request[1]; /* this way the packet can be treated as pointer as usual */ coap_observer_t *obs = NULL; + int url_len, obs_url_len; + char url[COAP_OBSERVER_URL_LEN]; - PRINTF("Observe: Notification from %s\n", resource->url); + url_len = strlen(resource->url); + strncpy(url, resource->url, COAP_OBSERVER_URL_LEN); + if(strlen(url) < COAP_OBSERVER_URL_LEN && subpath != NULL) { + strncpy(&url[url_len], subpath, COAP_OBSERVER_URL_LEN - url_len); + } + /* url now contains the notify URL that needs to match the observer */ + PRINTF("Observe: Notification from %s\n", url); + + coap_init_message(notification, COAP_TYPE_NON, CONTENT_2_05, 0); + /* create a "fake" request for the URI */ + coap_init_message(request, COAP_TYPE_CON, COAP_GET, 0); + coap_set_header_uri_path(request, url); /* iterate over observers */ + url_len = strlen(url); for(obs = (coap_observer_t *)list_head(observers_list); obs; obs = obs->next) { - if(obs->url == resource->url) { /* using RESOURCE url pointer as handle */ + obs_url_len = strlen(obs->url); + + /* Do a match based on the parent/sub-resource match so that it is + possible to do parent-node observe */ + if((obs_url_len == url_len + || (obs_url_len > url_len + && (resource->flags & HAS_SUB_RESOURCES) + && obs->url[url_len] == '/')) + && strncmp(url, obs->url, url_len) == 0) { coap_transaction_t *transaction = NULL; /*TODO implement special transaction for CON, sharing the same buffer to allow for more observers */ @@ -209,7 +241,7 @@ coap_notify_observers(resource_t *resource) /* prepare response */ notification->mid = transaction->mid; - resource->get_handler(NULL, notification, + resource->get_handler(request, notification, transaction->packet + COAP_MAX_HEADER_SIZE, REST_MAX_CHUNK_SIZE, NULL); @@ -237,9 +269,9 @@ coap_observe_handler(resource_t *resource, void *request, void *response) if(coap_req->code == COAP_GET && coap_res->code < 128) { /* GET request and response without error code */ if(IS_OPTION(coap_req, COAP_OPTION_OBSERVE)) { if(coap_req->observe == 0) { - obs = coap_add_observer(&UIP_IP_BUF->srcipaddr, UIP_UDP_BUF->srcport, - coap_req->token, coap_req->token_len, - resource->url); + obs = add_observer(&UIP_IP_BUF->srcipaddr, UIP_UDP_BUF->srcport, + coap_req->token, coap_req->token_len, + coap_req->uri_path, coap_req->uri_path_len); if(obs) { coap_set_header_observe(coap_res, (obs->obs_counter)++); /* diff --git a/apps/er-coap/er-coap-observe.h b/apps/er-coap/er-coap-observe.h index 6d0498bb6..4e9644bf0 100644 --- a/apps/er-coap/er-coap-observe.h +++ b/apps/er-coap/er-coap-observe.h @@ -43,6 +43,8 @@ #include "er-coap-transactions.h" #include "stimer.h" +#define COAP_OBSERVER_URL_LEN 20 + typedef struct coap_observable { uint32_t observe_clock; struct stimer orphan_timer; @@ -54,7 +56,7 @@ typedef struct coap_observable { typedef struct coap_observer { struct coap_observer *next; /* for LIST */ - const char *url; + char url[COAP_OBSERVER_URL_LEN]; uip_ipaddr_t addr; uint16_t port; uint8_t token_len; @@ -68,11 +70,6 @@ typedef struct coap_observer { } coap_observer_t; list_t coap_get_observers(void); - -coap_observer_t *coap_add_observer(uip_ipaddr_t *addr, uint16_t port, - const uint8_t *token, size_t token_len, - const char *url); - void coap_remove_observer(coap_observer_t *o); int coap_remove_observer_by_client(uip_ipaddr_t *addr, uint16_t port); int coap_remove_observer_by_token(uip_ipaddr_t *addr, uint16_t port, @@ -83,6 +80,7 @@ int coap_remove_observer_by_mid(uip_ipaddr_t *addr, uint16_t port, uint16_t mid); void coap_notify_observers(resource_t *resource); +void coap_notify_observers_sub(resource_t *resource, const char *subpath); void coap_observe_handler(resource_t *resource, void *request, void *response); diff --git a/apps/rest-engine/rest-engine.c b/apps/rest-engine/rest-engine.c index 038acb025..f74d2a9a9 100644 --- a/apps/rest-engine/rest-engine.c +++ b/apps/rest-engine/rest-engine.c @@ -126,11 +126,11 @@ rest_invoke_restful_service(void *request, void *response, uint8_t *buffer, const char *url = NULL; int url_len, res_url_len; + url_len = REST.get_url(request, &url); for(resource = (resource_t *)list_head(restful_services); resource; resource = resource->next) { /* if the web service handles that kind of requests and urls matches */ - url_len = REST.get_url(request, &url); res_url_len = strlen(resource->url); if((url_len == res_url_len || (url_len > res_url_len From 2351ee078aae46037aebfdbe0a8df99546da3293 Mon Sep 17 00:00:00 2001 From: Joakim Eriksson Date: Tue, 12 May 2015 01:18:36 +0200 Subject: [PATCH 100/120] Fixed CoAP format to be a uint16_t since the enum might compile to 8 bit and cause problems if 16-bit format types are used --- apps/er-coap/er-coap.c | 57 +++++++++++++++++++++++------------------- apps/er-coap/er-coap.h | 14 +++++------ 2 files changed, 38 insertions(+), 33 deletions(-) diff --git a/apps/er-coap/er-coap.c b/apps/er-coap/er-coap.c index f49d947d9..cdb5ee76a 100644 --- a/apps/er-coap/er-coap.c +++ b/apps/er-coap/er-coap.c @@ -127,7 +127,7 @@ coap_set_option_header(unsigned int delta, size_t length, uint8_t *buffer) buffer[++written] = (length - 13); } - PRINTF("WRITTEN %u B opt header\n", 1 + written); + PRINTF("WRITTEN %zu B opt header\n", 1 + written); return ++written; } @@ -150,7 +150,7 @@ coap_serialize_int_option(unsigned int number, unsigned int current_number, if(0xFFFFFFFF & value) { ++i; } - PRINTF("OPTION %u (delta %u, len %u)\n", number, number - current_number, + PRINTF("OPTION %u (delta %u, len %zu)\n", number, number - current_number, i); i = coap_set_option_header(number - current_number, i, buffer); @@ -177,8 +177,8 @@ coap_serialize_array_option(unsigned int number, unsigned int current_number, { size_t i = 0; - PRINTF("ARRAY type %u, len %u, full [%.*s]\n", number, length, length, - array); + PRINTF("ARRAY type %u, len %zu, full [%.*s]\n", number, length, + (int)length, array); if(split_char != '\0') { int j; @@ -187,7 +187,7 @@ coap_serialize_array_option(unsigned int number, unsigned int current_number, size_t temp_length; for(j = 0; j <= length + 1; ++j) { - PRINTF("STEP %u/%u (%c)\n", j, length, array[j]); + PRINTF("STEP %u/%zu (%c)\n", j, length, array[j]); if(array[j] == split_char || j == length) { part_end = array + j; temp_length = part_end - part_start; @@ -197,8 +197,8 @@ coap_serialize_array_option(unsigned int number, unsigned int current_number, memcpy(&buffer[i], part_start, temp_length); i += temp_length; - PRINTF("OPTION type %u, delta %u, len %u, part [%.*s]\n", number, - number - current_number, i, temp_length, part_start); + PRINTF("OPTION type %u, delta %u, len %zu, part [%.*s]\n", number, + number - current_number, i, (int)temp_length, part_start); ++j; /* skip the splitter */ current_number = number; @@ -210,7 +210,7 @@ coap_serialize_array_option(unsigned int number, unsigned int current_number, memcpy(&buffer[i], array, length); i += length; - PRINTF("OPTION type %u, delta %u, len %u\n", number, + PRINTF("OPTION type %u, delta %u, len %zu\n", number, number - current_number, length); } @@ -334,7 +334,7 @@ coap_serialize_message(void *packet, uint8_t *buffer) /* empty packet, dont need to do more stuff */ if(!coap_pkt->code) { - PRINTF("-Done serializing empty message at %p-\n", option); + PRINTF("-Done serializing empty message at %p-\n", coap_pkt->buffer); return 4; } @@ -370,6 +370,7 @@ coap_serialize_message(void *packet, uint8_t *buffer) "Location-Path"); COAP_SERIALIZE_STRING_OPTION(COAP_OPTION_URI_PATH, uri_path, '/', "Uri-Path"); + PRINTF("Serialize content format: %d\n", coap_pkt->content_format); COAP_SERIALIZE_INT_OPTION(COAP_OPTION_CONTENT_FORMAT, content_format, "Content-Format"); COAP_SERIALIZE_INT_OPTION(COAP_OPTION_MAX_AGE, max_age, "Max-Age"); @@ -405,8 +406,9 @@ coap_serialize_message(void *packet, uint8_t *buffer) } PRINTF("-Done %u B (header len %u, payload len %u)-\n", - coap_pkt->payload_len + option - buffer, option - buffer, - coap_pkt->payload_len); + (unsigned int)(coap_pkt->payload_len + option - buffer), + (unsigned int)(option - buffer), + (unsigned int)coap_pkt->payload_len); PRINTF("Dump [0x%02X %02X %02X %02X %02X %02X %02X %02X]\n", coap_pkt->buffer[0], @@ -540,7 +542,7 @@ coap_parse_message(void *packet, uint8_t *data, uint16_t data_len) case COAP_OPTION_MAX_AGE: coap_pkt->max_age = coap_parse_int_option(current_option, option_length); - PRINTF("Max-Age [%lu]\n", coap_pkt->max_age); + PRINTF("Max-Age [%lu]\n", (unsigned long)coap_pkt->max_age); break; case COAP_OPTION_ETAG: coap_pkt->etag_len = MIN(COAP_ETAG_LEN, option_length); @@ -577,7 +579,7 @@ coap_parse_message(void *packet, uint8_t *data, uint16_t data_len) coap_pkt->proxy_uri = (char *)current_option; coap_pkt->proxy_uri_len = option_length; #endif - PRINTF("Proxy-Uri NOT IMPLEMENTED [%.*s]\n", coap_pkt->proxy_uri_len, + PRINTF("Proxy-Uri NOT IMPLEMENTED [%.*s]\n", (int)coap_pkt->proxy_uri_len, coap_pkt->proxy_uri); coap_error_message = "This is a constrained server (Contiki)"; return PROXYING_NOT_SUPPORTED_5_05; @@ -588,7 +590,7 @@ coap_parse_message(void *packet, uint8_t *data, uint16_t data_len) coap_pkt->proxy_scheme_len = option_length; #endif PRINTF("Proxy-Scheme NOT IMPLEMENTED [%.*s]\n", - coap_pkt->proxy_scheme_len, coap_pkt->proxy_scheme); + (int)coap_pkt->proxy_scheme_len, coap_pkt->proxy_scheme); coap_error_message = "This is a constrained server (Contiki)"; return PROXYING_NOT_SUPPORTED_5_05; break; @@ -596,7 +598,8 @@ coap_parse_message(void *packet, uint8_t *data, uint16_t data_len) case COAP_OPTION_URI_HOST: coap_pkt->uri_host = (char *)current_option; coap_pkt->uri_host_len = option_length; - PRINTF("Uri-Host [%.*s]\n", coap_pkt->uri_host_len, coap_pkt->uri_host); + PRINTF("Uri-Host [%.*s]\n", (int)coap_pkt->uri_host_len, + coap_pkt->uri_host); break; case COAP_OPTION_URI_PORT: coap_pkt->uri_port = coap_parse_int_option(current_option, @@ -608,14 +611,14 @@ coap_parse_message(void *packet, uint8_t *data, uint16_t data_len) coap_merge_multi_option((char **)&(coap_pkt->uri_path), &(coap_pkt->uri_path_len), current_option, option_length, '/'); - PRINTF("Uri-Path [%.*s]\n", coap_pkt->uri_path_len, coap_pkt->uri_path); + PRINTF("Uri-Path [%.*s]\n", (int)coap_pkt->uri_path_len, coap_pkt->uri_path); break; case COAP_OPTION_URI_QUERY: /* coap_merge_multi_option() operates in-place on the IPBUF, but final packet field should be const string -> cast to string */ coap_merge_multi_option((char **)&(coap_pkt->uri_query), &(coap_pkt->uri_query_len), current_option, option_length, '&'); - PRINTF("Uri-Query [%.*s]\n", coap_pkt->uri_query_len, + PRINTF("Uri-Query [%.*s]\n", (int)coap_pkt->uri_query_len, coap_pkt->uri_query); break; @@ -624,7 +627,7 @@ coap_parse_message(void *packet, uint8_t *data, uint16_t data_len) coap_merge_multi_option((char **)&(coap_pkt->location_path), &(coap_pkt->location_path_len), current_option, option_length, '/'); - PRINTF("Location-Path [%.*s]\n", coap_pkt->location_path_len, + PRINTF("Location-Path [%.*s]\n", (int)coap_pkt->location_path_len, coap_pkt->location_path); break; case COAP_OPTION_LOCATION_QUERY: @@ -632,14 +635,14 @@ coap_parse_message(void *packet, uint8_t *data, uint16_t data_len) coap_merge_multi_option((char **)&(coap_pkt->location_query), &(coap_pkt->location_query_len), current_option, option_length, '&'); - PRINTF("Location-Query [%.*s]\n", coap_pkt->location_query_len, + PRINTF("Location-Query [%.*s]\n", (int)coap_pkt->location_query_len, coap_pkt->location_query); break; case COAP_OPTION_OBSERVE: coap_pkt->observe = coap_parse_int_option(current_option, option_length); - PRINTF("Observe [%lu]\n", coap_pkt->observe); + PRINTF("Observe [%lu]\n", (unsigned long)coap_pkt->observe); break; case COAP_OPTION_BLOCK2: coap_pkt->block2_num = coap_parse_int_option(current_option, @@ -649,7 +652,8 @@ coap_parse_message(void *packet, uint8_t *data, uint16_t data_len) coap_pkt->block2_offset = (coap_pkt->block2_num & ~0x0000000F) << (coap_pkt->block2_num & 0x07); coap_pkt->block2_num >>= 4; - PRINTF("Block2 [%lu%s (%u B/blk)]\n", coap_pkt->block2_num, + PRINTF("Block2 [%lu%s (%u B/blk)]\n", + (unsigned long)coap_pkt->block2_num, coap_pkt->block2_more ? "+" : "", coap_pkt->block2_size); break; case COAP_OPTION_BLOCK1: @@ -660,16 +664,17 @@ coap_parse_message(void *packet, uint8_t *data, uint16_t data_len) coap_pkt->block1_offset = (coap_pkt->block1_num & ~0x0000000F) << (coap_pkt->block1_num & 0x07); coap_pkt->block1_num >>= 4; - PRINTF("Block1 [%lu%s (%u B/blk)]\n", coap_pkt->block1_num, + PRINTF("Block1 [%lu%s (%u B/blk)]\n", + (unsigned long)coap_pkt->block1_num, coap_pkt->block1_more ? "+" : "", coap_pkt->block1_size); break; case COAP_OPTION_SIZE2: coap_pkt->size2 = coap_parse_int_option(current_option, option_length); - PRINTF("Size2 [%lu]\n", coap_pkt->size2); + PRINTF("Size2 [%lu]\n", (unsigned long)coap_pkt->size2); break; case COAP_OPTION_SIZE1: coap_pkt->size1 = coap_parse_int_option(current_option, option_length); - PRINTF("Size1 [%lu]\n", coap_pkt->size1); + PRINTF("Size1 [%lu]\n", (unsigned long)coap_pkt->size1); break; default: PRINTF("unknown (%u)\n", option_number); @@ -752,7 +757,7 @@ coap_set_header_content_format(void *packet, unsigned int format) { coap_packet_t *const coap_pkt = (coap_packet_t *)packet; - coap_pkt->content_format = (coap_content_format_t)format; + coap_pkt->content_format = format; SET_OPTION(coap_pkt, COAP_OPTION_CONTENT_FORMAT); return 1; } @@ -773,7 +778,7 @@ coap_set_header_accept(void *packet, unsigned int accept) { coap_packet_t *const coap_pkt = (coap_packet_t *)packet; - coap_pkt->accept = (coap_content_format_t)accept; + coap_pkt->accept = accept; SET_OPTION(coap_pkt, COAP_OPTION_ACCEPT); return 1; } diff --git a/apps/er-coap/er-coap.h b/apps/er-coap/er-coap.h index 69ea8b363..ccac6d76e 100644 --- a/apps/er-coap/er-coap.h +++ b/apps/er-coap/er-coap.h @@ -93,7 +93,7 @@ typedef struct { uint8_t options[COAP_OPTION_SIZE1 / OPTION_MAP_SIZE + 1]; /* bitmap to check if option is set */ - coap_content_format_t content_format; /* parse options once and store; allows setting options in random order */ + uint16_t content_format; /* parse options once and store; allows setting options in random order */ uint32_t max_age; uint8_t etag_len; uint8_t etag[COAP_ETAG_LEN]; @@ -111,7 +111,7 @@ typedef struct { size_t uri_path_len; const char *uri_path; int32_t observe; - coap_content_format_t accept; + uint16_t accept; uint8_t if_match_len; uint8_t if_match[COAP_ETAG_LEN]; uint32_t block2_num; @@ -135,13 +135,13 @@ typedef struct { /* option format serialization */ #define COAP_SERIALIZE_INT_OPTION(number, field, text) \ if(IS_OPTION(coap_pkt, number)) { \ - PRINTF(text " [%u]\n", coap_pkt->field); \ + PRINTF(text " [%u]\n", (unsigned int)coap_pkt->field); \ option += coap_serialize_int_option(number, current_number, option, coap_pkt->field); \ current_number = number; \ } #define COAP_SERIALIZE_BYTE_OPTION(number, field, text) \ if(IS_OPTION(coap_pkt, number)) { \ - PRINTF(text " %u [0x%02X%02X%02X%02X%02X%02X%02X%02X]\n", coap_pkt->field##_len, \ + PRINTF(text " %u [0x%02X%02X%02X%02X%02X%02X%02X%02X]\n", (unsigned int)coap_pkt->field##_len, \ coap_pkt->field[0], \ coap_pkt->field[1], \ coap_pkt->field[2], \ @@ -156,18 +156,18 @@ typedef struct { } #define COAP_SERIALIZE_STRING_OPTION(number, field, splitter, text) \ if(IS_OPTION(coap_pkt, number)) { \ - PRINTF(text " [%.*s]\n", coap_pkt->field##_len, coap_pkt->field); \ + PRINTF(text " [%.*s]\n", (int)coap_pkt->field##_len, coap_pkt->field); \ option += coap_serialize_array_option(number, current_number, option, (uint8_t *)coap_pkt->field, coap_pkt->field##_len, splitter); \ current_number = number; \ } #define COAP_SERIALIZE_BLOCK_OPTION(number, field, text) \ if(IS_OPTION(coap_pkt, number)) \ { \ - PRINTF(text " [%lu%s (%u B/blk)]\n", coap_pkt->field##_num, coap_pkt->field##_more ? "+" : "", coap_pkt->field##_size); \ + PRINTF(text " [%lu%s (%u B/blk)]\n", (unsigned long)coap_pkt->field##_num, coap_pkt->field##_more ? "+" : "", coap_pkt->field##_size); \ uint32_t block = coap_pkt->field##_num << 4; \ if(coap_pkt->field##_more) { block |= 0x8; } \ block |= 0xF & coap_log_2(coap_pkt->field##_size / 16); \ - PRINTF(text " encoded: 0x%lX\n", block); \ + PRINTF(text " encoded: 0x%lX\n", (unsigned long)block); \ option += coap_serialize_int_option(number, current_number, option, block); \ current_number = number; \ } From 539e92c084640854cfdf7068ed26693c8a5a8340 Mon Sep 17 00:00:00 2001 From: Joakim Eriksson Date: Tue, 12 May 2015 11:11:31 +0200 Subject: [PATCH 101/120] Made rest-engine handle multiple init without dropping resources. --- apps/rest-engine/rest-engine.c | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/apps/rest-engine/rest-engine.c b/apps/rest-engine/rest-engine.c index f74d2a9a9..67ac232a2 100644 --- a/apps/rest-engine/rest-engine.c +++ b/apps/rest-engine/rest-engine.c @@ -70,6 +70,15 @@ LIST(restful_periodic_services); void rest_init_engine(void) { + /* avoid initializing twice */ + static uint8_t initialized = 0; + + if(initialized) { + PRINTF("REST engine process already running - double initialization?\n"); + return; + } + initialized = 1; + list_init(restful_services); REST.set_service_callback(rest_invoke_restful_service); From 7edf6e60e9fc2f3d616a3c006bfde396ad68572a Mon Sep 17 00:00:00 2001 From: Niclas Finne Date: Thu, 4 Jun 2015 21:12:21 +0200 Subject: [PATCH 102/120] Changed to use process API to switch process context in CoAP --- apps/er-coap/er-coap-transactions.c | 10 ++-------- 1 file changed, 2 insertions(+), 8 deletions(-) diff --git a/apps/er-coap/er-coap-transactions.c b/apps/er-coap/er-coap-transactions.c index 7f6537932..3987b4814 100644 --- a/apps/er-coap/er-coap-transactions.c +++ b/apps/er-coap/er-coap-transactions.c @@ -113,15 +113,9 @@ coap_send_transaction(coap_transaction_t *t) (float)t->retrans_timer.timer.interval / CLOCK_SECOND); } - /*FIXME - * Hack: Setting timer for responsible process. - * Maybe there is a better way, but avoid posting everything to the process. - */ - struct process *process_actual = PROCESS_CURRENT(); - - process_current = transaction_handler_process; + PROCESS_CONTEXT_BEGIN(transaction_handler_process); etimer_restart(&t->retrans_timer); /* interval updated above */ - process_current = process_actual; + PROCESS_CONTEXT_END(transaction_handler_process); t = NULL; } else { From d764e09f35a3a1c1daedf606ed4e30aa07ba39d3 Mon Sep 17 00:00:00 2001 From: Niclas Finne Date: Thu, 4 Jun 2015 21:13:50 +0200 Subject: [PATCH 103/120] Make sure the url is null terminated in CoAP observe. --- apps/er-coap/er-coap-observe.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/apps/er-coap/er-coap-observe.c b/apps/er-coap/er-coap-observe.c index ef533cf70..35ab2ff74 100644 --- a/apps/er-coap/er-coap-observe.c +++ b/apps/er-coap/er-coap-observe.c @@ -196,10 +196,12 @@ coap_notify_observers_sub(resource_t *resource, const char *subpath) char url[COAP_OBSERVER_URL_LEN]; url_len = strlen(resource->url); - strncpy(url, resource->url, COAP_OBSERVER_URL_LEN); - if(strlen(url) < COAP_OBSERVER_URL_LEN && subpath != NULL) { - strncpy(&url[url_len], subpath, COAP_OBSERVER_URL_LEN - url_len); + strncpy(url, resource->url, COAP_OBSERVER_URL_LEN - 1); + if(url_len < COAP_OBSERVER_URL_LEN - 1 && subpath != NULL) { + strncpy(&url[url_len], subpath, COAP_OBSERVER_URL_LEN - url_len - 1); } + /* Ensure url is null terminated because strncpy does not guarantee this */ + url[COAP_OBSERVER_URL_LEN - 1] = '\0'; /* url now contains the notify URL that needs to match the observer */ PRINTF("Observe: Notification from %s\n", url); From 3d7d5d3a45c40db4dc3bdad063179feda5e7d92b Mon Sep 17 00:00:00 2001 From: Simon Duquennoy Date: Fri, 25 Sep 2015 19:03:39 +0200 Subject: [PATCH 104/120] uip-nd6.c: added function extract_lladdr_aligned for clarity --- core/net/ipv6/uip-nd6.c | 36 ++++++++++++++++++++---------------- 1 file changed, 20 insertions(+), 16 deletions(-) diff --git a/core/net/ipv6/uip-nd6.c b/core/net/ipv6/uip-nd6.c index 3fe7165d9..7bce93af0 100644 --- a/core/net/ipv6/uip-nd6.c +++ b/core/net/ipv6/uip-nd6.c @@ -130,6 +130,16 @@ static uip_ipaddr_t ipaddr; static uip_ds6_prefix_t *prefix; /** Pointer to a prefix list entry */ #endif +#if UIP_ND6_SEND_NA || UIP_ND6_SEND_RA || !UIP_CONF_ROUTER +/*------------------------------------------------------------------*/ +/* Copy link-layer address from LLAO option to a word-aligned uip_lladdr_t */ +static void +extract_lladdr_aligned(uip_lladdr_t *dest) { + if(dest != NULL && nd6_opt_llao != NULL) { + memcpy(dest, &nd6_opt_llao[UIP_ND6_OPT_DATA_OFFSET], UIP_LLADDR_LEN); + } +} +#endif /* UIP_ND6_SEND_NA || UIP_ND6_SEND_RA || !UIP_CONF_ROUTER */ /*------------------------------------------------------------------*/ /* create a llao */ static void @@ -189,11 +199,9 @@ ns_input(void) #endif /*UIP_CONF_IPV6_CHECKS */ nbr = uip_ds6_nbr_lookup(&UIP_IP_BUF->srcipaddr); if(nbr == NULL) { - /* Copy link address to a uip_lladdr_t first - * to ensure the second argument to uip_ds6_nbr_add is word-aligned */ - uip_lladdr_t lladdr; - memcpy(&lladdr, &nd6_opt_llao[UIP_ND6_OPT_DATA_OFFSET], UIP_LLADDR_LEN); - uip_ds6_nbr_add(&UIP_IP_BUF->srcipaddr, &lladdr, 0, NBR_STALE); + uip_lladdr_t lladdr_aligned; + extract_lladdr_aligned(&lladdr_aligned); + uip_ds6_nbr_add(&UIP_IP_BUF->srcipaddr, &lladdr_aligned, 0, NBR_STALE); } else { uip_lladdr_t *lladdr = (uip_lladdr_t *)uip_ds6_nbr_get_ll(nbr); if(memcmp(&nd6_opt_llao[UIP_ND6_OPT_DATA_OFFSET], @@ -620,20 +628,18 @@ rs_input(void) goto discard; } else { #endif /*UIP_CONF_IPV6_CHECKS */ - /* Copy link address to a uip_lladdr_t first - * to ensure the second argument to uip_ds6_nbr_add is word-aligned */ - uip_lladdr_t lladdr; - memcpy(&lladdr, &nd6_opt_llao[UIP_ND6_OPT_DATA_OFFSET], UIP_LLADDR_LEN); + uip_lladdr_t lladdr_aligned; + extract_lladdr_aligned(&lladdr_aligned); if((nbr = uip_ds6_nbr_lookup(&UIP_IP_BUF->srcipaddr)) == NULL) { /* we need to add the neighbor */ - uip_ds6_nbr_add(&UIP_IP_BUF->srcipaddr, &lladdr, 0, NBR_STALE); + uip_ds6_nbr_add(&UIP_IP_BUF->srcipaddr, &lladdr_aligned, 0, NBR_STALE); } else { /* If LL address changed, set neighbor state to stale */ if(memcmp(&nd6_opt_llao[UIP_ND6_OPT_DATA_OFFSET], uip_ds6_nbr_get_ll(nbr), UIP_LLADDR_LEN) != 0) { uip_ds6_nbr_t nbr_data = *nbr; uip_ds6_nbr_rm(nbr); - nbr = uip_ds6_nbr_add(&UIP_IP_BUF->srcipaddr, &lladdr, 0, NBR_STALE); + nbr = uip_ds6_nbr_add(&UIP_IP_BUF->srcipaddr, &lladdr_aligned, 0, NBR_STALE); nbr->reachable = nbr_data.reachable; nbr->sendns = nbr_data.sendns; nbr->nscount = nbr_data.nscount; @@ -862,11 +868,9 @@ ra_input(void) nd6_opt_llao = (uint8_t *) UIP_ND6_OPT_HDR_BUF; nbr = uip_ds6_nbr_lookup(&UIP_IP_BUF->srcipaddr); if(nbr == NULL) { - /* Copy link address to a uip_lladdr_t first - * to ensure the second argument to uip_ds6_nbr_add is word-aligned */ - uip_lladdr_t lladdr; - memcpy(&lladdr, &nd6_opt_llao[UIP_ND6_OPT_DATA_OFFSET], UIP_LLADDR_LEN); - nbr = uip_ds6_nbr_add(&UIP_IP_BUF->srcipaddr, &lladdr, 1, NBR_STALE); + uip_lladdr_t lladdr_aligned; + extract_lladdr_aligned(&lladdr_aligned); + nbr = uip_ds6_nbr_add(&UIP_IP_BUF->srcipaddr, &lladdr_aligned, 1, NBR_STALE); } else { uip_lladdr_t *lladdr = (uip_lladdr_t *)uip_ds6_nbr_get_ll(nbr); if(nbr->state == NBR_INCOMPLETE) { From 867368b929bd236499406a0f6e59343c859ed7c5 Mon Sep 17 00:00:00 2001 From: Vladimir Pouzanov Date: Thu, 5 Dec 2013 18:21:06 +0000 Subject: [PATCH 105/120] Basic NETSTACK_CONF_RADIO based on kernel 802.15.4 --- cpu/native/net/linuxradio-drv.c | 179 ++++++++++++++++++++++ cpu/native/net/linuxradio-drv.h | 8 + platform/minimal-net/Makefile.minimal-net | 2 +- platform/native/Makefile.native | 2 +- 4 files changed, 189 insertions(+), 2 deletions(-) create mode 100644 cpu/native/net/linuxradio-drv.c create mode 100644 cpu/native/net/linuxradio-drv.h diff --git a/cpu/native/net/linuxradio-drv.c b/cpu/native/net/linuxradio-drv.c new file mode 100644 index 000000000..aa94e9e08 --- /dev/null +++ b/cpu/native/net/linuxradio-drv.c @@ -0,0 +1,179 @@ +#include "contiki.h" + +#include "linuxradio-drv.h" + +#include "net/packetbuf.h" +#include "net/netstack.h" + +#include +#include +#include +#include +#include +#include +#include +#include + +#define DEBUG 0 +#if DEBUG +#include +#define PRINTF(...) printf(__VA_ARGS__) +#else +#define PRINTF(...) +#endif + +static int sockfd = -1; +static char *sockbuf; +static int buflen; + +#if 0 +static void my_memmove(char *s1, char *s2, int len) +{ + int i; + for(i=0; i 256) { + return 0; + } + memcpy(sockbuf, payload, payload_len); + buflen = payload_len; + + return 0; +} + +static int +transmit(unsigned short transmit_len) +{ + int sent=0; + sent = send(sockfd, sockbuf, buflen, 0); + if(sent < 0) { + perror ("linuxradio send()"); + } + buflen = 0; + return RADIO_TX_OK; +} + +static int +my_send(const void *payload, unsigned short payload_len) +{ + int ret = -1; + + PRINTF("PREPARE & TRANSMIT %u bytes\n", payload_len); + + if(prepare(payload, payload_len)) { + return ret; + } + + ret = transmit(payload_len); + + return ret; +} + +static int +my_read(void *buf, unsigned short buf_len) +{ + return 0; +} + +static int +channel_clear(void) +{ + return 1; +} + +static int +receiving_packet(void) +{ + return 0; +} + +static int +pending_packet(void) +{ + return 0; +} + +static int +set_fd(fd_set *rset, fd_set *wset) +{ + FD_SET(sockfd, rset); + return 1; +} + +static void +handle_fd(fd_set *rset, fd_set *wset) +{ + if(FD_ISSET(sockfd, rset)) { + int bytes = read(sockfd, sockbuf, 256); + buflen = bytes; + PRINTF("linuxradio: read %d bytes\n", bytes); + memcpy(packetbuf_dataptr(), sockbuf, bytes); + packetbuf_set_datalen(bytes); + NETSTACK_RDC.input(); + } +} + +static const struct select_callback linuxradio_sock_callback = { set_fd, handle_fd }; + +static int +on(void) +{ + sockfd = socket(PF_PACKET, SOCK_RAW, htons(ETH_P_IEEE802154)); + if(sockfd < 0) { + perror ("linuxradio socket()"); + return 0; + } else { + struct ifreq ifr; + strncpy((char *)ifr.ifr_name, "wpan0", IFNAMSIZ); // TODO: make interface configurable + ioctl(sockfd, SIOCGIFINDEX, &ifr); + + struct sockaddr_ll sll; + sll.sll_family = AF_PACKET; + sll.sll_ifindex = ifr.ifr_ifindex; + sll.sll_protocol = htons(ETH_P_IEEE802154); + + if(bind(sockfd, (struct sockaddr *)&sll, sizeof(sll)) < 0) { + perror("linuxradio bind()"); + return 0; + } + + select_set_callback(sockfd, &linuxradio_sock_callback); + return 1; + } +} + +static int +off(void) +{ + close(sockfd); + sockfd = -1; + return 1; +} + +const struct radio_driver linuxradio_driver = + { + init, + prepare, + transmit, + my_send, + my_read, + channel_clear, + receiving_packet, + pending_packet, + on, + off, + }; diff --git a/cpu/native/net/linuxradio-drv.h b/cpu/native/net/linuxradio-drv.h new file mode 100644 index 000000000..5952a3eb2 --- /dev/null +++ b/cpu/native/net/linuxradio-drv.h @@ -0,0 +1,8 @@ +#ifndef __LINUXRADIO_DRV_H__ +#define __LINUXRADIO_DRV_H__ + +#include "dev/radio.h" + +extern const struct radio_driver linuxradio_driver; + +#endif diff --git a/platform/minimal-net/Makefile.minimal-net b/platform/minimal-net/Makefile.minimal-net index dd7632d92..2c2399617 100644 --- a/platform/minimal-net/Makefile.minimal-net +++ b/platform/minimal-net/Makefile.minimal-net @@ -14,7 +14,7 @@ CONTIKI_TARGET_SOURCEFILES = contiki-main.c clock.c leds.c leds-arch.c cfs-posix ifeq ($(HOST_OS),Windows) CONTIKI_TARGET_SOURCEFILES += wpcap-drv.c wpcap.c else -CONTIKI_TARGET_SOURCEFILES += tapdev-drv.c tapdev.c tapdev6.c +CONTIKI_TARGET_SOURCEFILES += tapdev-drv.c tapdev.c tapdev6.c linuxradio-drv.c endif CONTIKI_SOURCEFILES += $(CONTIKI_TARGET_SOURCEFILES) diff --git a/platform/native/Makefile.native b/platform/native/Makefile.native index 198dbabee..504c91a3a 100644 --- a/platform/native/Makefile.native +++ b/platform/native/Makefile.native @@ -17,7 +17,7 @@ ifeq ($(HOST_OS),Windows) CONTIKI_TARGET_SOURCEFILES += wpcap-drv.c wpcap.c TARGET_LIBFILES = /lib/w32api/libws2_32.a /lib/w32api/libiphlpapi.a else -CONTIKI_TARGET_SOURCEFILES += tapdev-drv.c +CONTIKI_TARGET_SOURCEFILES += tapdev-drv.c linuxradio-drv.c #math ifneq ($(CONTIKI_WITH_IPV6),1) CONTIKI_TARGET_SOURCEFILES += tapdev.c From 8a068f8512f84bc718e764225c09892452241dc1 Mon Sep 17 00:00:00 2001 From: Vladimir Pouzanov Date: Fri, 6 Dec 2013 11:25:23 +0000 Subject: [PATCH 106/120] Cleaned up linuxradiodrv code --- cpu/native/net/linuxradio-drv.c | 64 ++++++++++++++++++++++----------- cpu/native/net/linuxradio-drv.h | 35 ++++++++++++++++++ 2 files changed, 79 insertions(+), 20 deletions(-) diff --git a/cpu/native/net/linuxradio-drv.c b/cpu/native/net/linuxradio-drv.c index aa94e9e08..f0f254536 100644 --- a/cpu/native/net/linuxradio-drv.c +++ b/cpu/native/net/linuxradio-drv.c @@ -1,3 +1,38 @@ +/* + * Copyright (c) 2013, Google + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * 3. Neither the name of the Institute nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * Author: Vladimir Pouzanov + * + */ + #include "contiki.h" #include "linuxradio-drv.h" @@ -26,27 +61,19 @@ static int sockfd = -1; static char *sockbuf; static int buflen; -#if 0 -static void my_memmove(char *s1, char *s2, int len) -{ - int i; - for(i=0; i 256) { + if (payload_len > MAX_PACKET_SIZE) { return 0; } memcpy(sockbuf, payload, payload_len); @@ -60,8 +87,8 @@ transmit(unsigned short transmit_len) { int sent=0; sent = send(sockfd, sockbuf, buflen, 0); - if(sent < 0) { - perror ("linuxradio send()"); + if (sent < 0) { + perror("linuxradio send()"); } buflen = 0; return RADIO_TX_OK; @@ -72,9 +99,7 @@ my_send(const void *payload, unsigned short payload_len) { int ret = -1; - PRINTF("PREPARE & TRANSMIT %u bytes\n", payload_len); - - if(prepare(payload, payload_len)) { + if (prepare(payload, payload_len)) { return ret; } @@ -117,10 +142,9 @@ set_fd(fd_set *rset, fd_set *wset) static void handle_fd(fd_set *rset, fd_set *wset) { - if(FD_ISSET(sockfd, rset)) { + if (FD_ISSET(sockfd, rset)) { int bytes = read(sockfd, sockbuf, 256); buflen = bytes; - PRINTF("linuxradio: read %d bytes\n", bytes); memcpy(packetbuf_dataptr(), sockbuf, bytes); packetbuf_set_datalen(bytes); NETSTACK_RDC.input(); @@ -133,7 +157,7 @@ static int on(void) { sockfd = socket(PF_PACKET, SOCK_RAW, htons(ETH_P_IEEE802154)); - if(sockfd < 0) { + if (sockfd < 0) { perror ("linuxradio socket()"); return 0; } else { @@ -146,7 +170,7 @@ on(void) sll.sll_ifindex = ifr.ifr_ifindex; sll.sll_protocol = htons(ETH_P_IEEE802154); - if(bind(sockfd, (struct sockaddr *)&sll, sizeof(sll)) < 0) { + if (bind(sockfd, (struct sockaddr *)&sll, sizeof(sll)) < 0) { perror("linuxradio bind()"); return 0; } diff --git a/cpu/native/net/linuxradio-drv.h b/cpu/native/net/linuxradio-drv.h index 5952a3eb2..fddf38d01 100644 --- a/cpu/native/net/linuxradio-drv.h +++ b/cpu/native/net/linuxradio-drv.h @@ -1,3 +1,38 @@ +/* + * Copyright (c) 2013, Google + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * 3. Neither the name of the Institute nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * Author: Vladimir Pouzanov + * + */ + #ifndef __LINUXRADIO_DRV_H__ #define __LINUXRADIO_DRV_H__ From beef4f5d5d90e08a731c23aa0816ab790cf45480 Mon Sep 17 00:00:00 2001 From: Vladimir Pouzanov Date: Sat, 25 Jan 2014 17:13:15 +0000 Subject: [PATCH 107/120] Added better error handling to linuxradiodrv transmit() --- cpu/native/net/linuxradio-drv.c | 1 + 1 file changed, 1 insertion(+) diff --git a/cpu/native/net/linuxradio-drv.c b/cpu/native/net/linuxradio-drv.c index f0f254536..0b30a5989 100644 --- a/cpu/native/net/linuxradio-drv.c +++ b/cpu/native/net/linuxradio-drv.c @@ -89,6 +89,7 @@ transmit(unsigned short transmit_len) sent = send(sockfd, sockbuf, buflen, 0); if (sent < 0) { perror("linuxradio send()"); + return RADIO_TX_ERR; } buflen = 0; return RADIO_TX_OK; From 5fed4a3f1ce54df8bba152f97ac75cbb205a47fd Mon Sep 17 00:00:00 2001 From: Vladimir Pouzanov Date: Sat, 25 Jan 2014 17:13:49 +0000 Subject: [PATCH 108/120] Using MAX_PACKET_SIZE where appropriate in linuxradiodrv --- cpu/native/net/linuxradio-drv.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cpu/native/net/linuxradio-drv.c b/cpu/native/net/linuxradio-drv.c index 0b30a5989..9718b4d42 100644 --- a/cpu/native/net/linuxradio-drv.c +++ b/cpu/native/net/linuxradio-drv.c @@ -144,7 +144,7 @@ static void handle_fd(fd_set *rset, fd_set *wset) { if (FD_ISSET(sockfd, rset)) { - int bytes = read(sockfd, sockbuf, 256); + int bytes = read(sockfd, sockbuf, MAX_PACKET_SIZE); buflen = bytes; memcpy(packetbuf_dataptr(), sockbuf, bytes); packetbuf_set_datalen(bytes); From 113d9761f7c7162227e6f14d91037680a682b6a7 Mon Sep 17 00:00:00 2001 From: Vladimir Pouzanov Date: Sat, 25 Jan 2014 17:16:01 +0000 Subject: [PATCH 109/120] Better failure handling in linuxradiodrv --- cpu/native/net/linuxradio-drv.c | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/cpu/native/net/linuxradio-drv.c b/cpu/native/net/linuxradio-drv.c index 9718b4d42..9275c1379 100644 --- a/cpu/native/net/linuxradio-drv.c +++ b/cpu/native/net/linuxradio-drv.c @@ -67,6 +67,9 @@ static int init(void) { sockbuf = malloc(MAX_PACKET_SIZE); + if (sockbuf == 0) { + return 1; + } return 0; } @@ -163,8 +166,13 @@ on(void) return 0; } else { struct ifreq ifr; - strncpy((char *)ifr.ifr_name, "wpan0", IFNAMSIZ); // TODO: make interface configurable - ioctl(sockfd, SIOCGIFINDEX, &ifr); + // TODO: interface should not be hard-coded + strncpy((char *)ifr.ifr_name, "wpan0", IFNAMSIZ); + int err = ioctl(sockfd, SIOCGIFINDEX, &ifr); + if (err == -1) { + perror ("linuxradio ioctl()"); + return 0; + } struct sockaddr_ll sll; sll.sll_family = AF_PACKET; From 43a327df5ad48e5095d806130cb00c9d7d6d6f0f Mon Sep 17 00:00:00 2001 From: Vladimir Pouzanov Date: Sat, 25 Jan 2014 17:16:54 +0000 Subject: [PATCH 110/120] Cleaned up and re-formatted source of linuxradiodrv --- cpu/native/net/linuxradio-drv.c | 69 ++++++++++++++------------------- 1 file changed, 29 insertions(+), 40 deletions(-) diff --git a/cpu/native/net/linuxradio-drv.c b/cpu/native/net/linuxradio-drv.c index 9275c1379..237cb2b64 100644 --- a/cpu/native/net/linuxradio-drv.c +++ b/cpu/native/net/linuxradio-drv.c @@ -67,16 +67,15 @@ static int init(void) { sockbuf = malloc(MAX_PACKET_SIZE); - if (sockbuf == 0) { + if(sockbuf == 0) { return 1; } return 0; } - static int prepare(const void *payload, unsigned short payload_len) { - if (payload_len > MAX_PACKET_SIZE) { + if(payload_len > MAX_PACKET_SIZE) { return 0; } memcpy(sockbuf, payload, payload_len); @@ -84,26 +83,24 @@ prepare(const void *payload, unsigned short payload_len) return 0; } - static int transmit(unsigned short transmit_len) { - int sent=0; + int sent = 0; sent = send(sockfd, sockbuf, buflen, 0); - if (sent < 0) { + if(sent < 0) { perror("linuxradio send()"); return RADIO_TX_ERR; } buflen = 0; return RADIO_TX_OK; } - static int my_send(const void *payload, unsigned short payload_len) { int ret = -1; - if (prepare(payload, payload_len)) { + if(prepare(payload, payload_len)) { return ret; } @@ -111,42 +108,36 @@ my_send(const void *payload, unsigned short payload_len) return ret; } - static int my_read(void *buf, unsigned short buf_len) { return 0; } - static int channel_clear(void) { return 1; } - static int receiving_packet(void) { return 0; } - static int pending_packet(void) { return 0; } - static int set_fd(fd_set *rset, fd_set *wset) { FD_SET(sockfd, rset); return 1; } - static void handle_fd(fd_set *rset, fd_set *wset) { - if (FD_ISSET(sockfd, rset)) { + if(FD_ISSET(sockfd, rset)) { int bytes = read(sockfd, sockbuf, MAX_PACKET_SIZE); buflen = bytes; memcpy(packetbuf_dataptr(), sockbuf, bytes); @@ -154,32 +145,32 @@ handle_fd(fd_set *rset, fd_set *wset) NETSTACK_RDC.input(); } } - static const struct select_callback linuxradio_sock_callback = { set_fd, handle_fd }; static int on(void) { + struct ifreq ifr; + int err; + struct sockaddr_ll sll; + sockfd = socket(PF_PACKET, SOCK_RAW, htons(ETH_P_IEEE802154)); - if (sockfd < 0) { - perror ("linuxradio socket()"); + if(sockfd < 0) { + perror("linuxradio socket()"); return 0; } else { - struct ifreq ifr; - // TODO: interface should not be hard-coded + /* TODO: interface should not be hard-coded */ strncpy((char *)ifr.ifr_name, "wpan0", IFNAMSIZ); - int err = ioctl(sockfd, SIOCGIFINDEX, &ifr); - if (err == -1) { - perror ("linuxradio ioctl()"); + err = ioctl(sockfd, SIOCGIFINDEX, &ifr); + if(err == -1) { + perror("linuxradio ioctl()"); return 0; } - - struct sockaddr_ll sll; sll.sll_family = AF_PACKET; sll.sll_ifindex = ifr.ifr_ifindex; sll.sll_protocol = htons(ETH_P_IEEE802154); - if (bind(sockfd, (struct sockaddr *)&sll, sizeof(sll)) < 0) { + if(bind(sockfd, (struct sockaddr *)&sll, sizeof(sll)) < 0) { perror("linuxradio bind()"); return 0; } @@ -188,7 +179,6 @@ on(void) return 1; } } - static int off(void) { @@ -196,17 +186,16 @@ off(void) sockfd = -1; return 1; } - const struct radio_driver linuxradio_driver = - { - init, - prepare, - transmit, - my_send, - my_read, - channel_clear, - receiving_packet, - pending_packet, - on, - off, - }; +{ + init, + prepare, + transmit, + my_send, + my_read, + channel_clear, + receiving_packet, + pending_packet, + on, + off, +}; From 52c90519d9c855bca57718ee9e23666898e4c5d9 Mon Sep 17 00:00:00 2001 From: Vladimir Pouzanov Date: Wed, 19 Feb 2014 17:04:00 +0000 Subject: [PATCH 111/120] Fixed missing #includes and restricted linuxradiodrv compilation to linux --- cpu/native/net/linuxradio-drv.c | 7 +++++++ platform/minimal-net/contiki-conf.h | 12 +++++++++--- 2 files changed, 16 insertions(+), 3 deletions(-) diff --git a/cpu/native/net/linuxradio-drv.c b/cpu/native/net/linuxradio-drv.c index 237cb2b64..da645762f 100644 --- a/cpu/native/net/linuxradio-drv.c +++ b/cpu/native/net/linuxradio-drv.c @@ -35,11 +35,15 @@ #include "contiki.h" +#ifdef linux + #include "linuxradio-drv.h" #include "net/packetbuf.h" #include "net/netstack.h" +#include +#include #include #include #include @@ -145,6 +149,7 @@ handle_fd(fd_set *rset, fd_set *wset) NETSTACK_RDC.input(); } } + static const struct select_callback linuxradio_sock_callback = { set_fd, handle_fd }; static int @@ -199,3 +204,5 @@ const struct radio_driver linuxradio_driver = on, off, }; + +#endif diff --git a/platform/minimal-net/contiki-conf.h b/platform/minimal-net/contiki-conf.h index e736b363d..1e15adc7c 100644 --- a/platform/minimal-net/contiki-conf.h +++ b/platform/minimal-net/contiki-conf.h @@ -36,6 +36,12 @@ #include #include +struct select_callback { + int (* set_fd)(fd_set *fdr, fd_set *fdw); + void (* handle_fd)(fd_set *fdr, fd_set *fdw); +}; +int select_set_callback(int fd, const struct select_callback *callback); + #define CC_CONF_REGISTER_ARGS 1 #define CC_CONF_FUNCTION_POINTER_ARGS 1 #define CC_CONF_FASTCALL @@ -88,9 +94,9 @@ typedef unsigned short uip_stats_t; */ #define WEBSERVER_CONF_STATUSPAGE 1 -/* RPL currently works only on Windows. *nix would require converting the tun interface to two pcap tees. */ +/* RPL currently works only on Windows. *nix would require converting the tun interface to two pcap tees. */ //#define RPL_BORDER_ROUTER 0 -#endif +#endif #if UIP_CONF_IPV6_RPL /* RPL motes use the uip.c link layer address or optionally the harded coded address (but without the prefix!) @@ -121,7 +127,7 @@ typedef unsigned short uip_stats_t; * e.g. the jackdaw RNDIS <-> repeater. Then RPL will configure on the radio network and the RF motes will * be reached through bbbb::. * Possibly minimal-net RPL motes could also be added to this interface? - * + * */ #undef UIP_CONF_ROUTER #define UIP_CONF_ROUTER 1 From 4c8618e6baed479a7dbf24b96a528043b62cef64 Mon Sep 17 00:00:00 2001 From: Vladimir Pouzanov Date: Sat, 1 Mar 2014 10:30:41 +0000 Subject: [PATCH 112/120] Extracted linuxradio device name to contiki-conf --- cpu/native/net/linuxradio-drv.c | 3 +-- platform/minimal-net/contiki-conf.h | 2 ++ platform/native/contiki-conf.h | 2 ++ 3 files changed, 5 insertions(+), 2 deletions(-) diff --git a/cpu/native/net/linuxradio-drv.c b/cpu/native/net/linuxradio-drv.c index da645762f..9f78e9cf1 100644 --- a/cpu/native/net/linuxradio-drv.c +++ b/cpu/native/net/linuxradio-drv.c @@ -164,8 +164,7 @@ on(void) perror("linuxradio socket()"); return 0; } else { - /* TODO: interface should not be hard-coded */ - strncpy((char *)ifr.ifr_name, "wpan0", IFNAMSIZ); + strncpy((char *)ifr.ifr_name, NETSTACK_CONF_LINUXRADIO_DEV, IFNAMSIZ); err = ioctl(sockfd, SIOCGIFINDEX, &ifr); if(err == -1) { perror("linuxradio ioctl()"); diff --git a/platform/minimal-net/contiki-conf.h b/platform/minimal-net/contiki-conf.h index 1e15adc7c..6b6b58e4a 100644 --- a/platform/minimal-net/contiki-conf.h +++ b/platform/minimal-net/contiki-conf.h @@ -174,6 +174,8 @@ typedef unsigned short uip_stats_t; #define UIP_CONF_DS6_AADDR_NBU 0 #endif /* NETSTACK_CONF_WITH_IPV6 */ +#define NETSTACK_CONF_LINUXRADIO_DEV "wpan0" + typedef unsigned long clock_time_t; #define CLOCK_CONF_SECOND 1000 #define INFINITE_TIME ULONG_MAX diff --git a/platform/native/contiki-conf.h b/platform/native/contiki-conf.h index 5ce72c09e..b3c15d48c 100644 --- a/platform/native/contiki-conf.h +++ b/platform/native/contiki-conf.h @@ -101,6 +101,8 @@ typedef unsigned short uip_stats_t; #define NETSTACK_CONF_NETWORK sicslowpan_driver +#define NETSTACK_CONF_LINUXRADIO_DEV "wpan0" + #define UIP_CONF_ROUTER 1 #define SICSLOWPAN_CONF_COMPRESSION SICSLOWPAN_COMPRESSION_HC06 From bd1b7d981438fb589e27ad6bf5c818175db2eac7 Mon Sep 17 00:00:00 2001 From: Vladimir Pouzanov Date: Sat, 1 Mar 2014 10:37:10 +0000 Subject: [PATCH 113/120] Fixed linuxradio compilation issues with native and minimal-net --- cpu/native/net/linuxradio-drv.c | 3 ++- platform/minimal-net/contiki-conf.h | 7 +++++-- 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/cpu/native/net/linuxradio-drv.c b/cpu/native/net/linuxradio-drv.c index 9f78e9cf1..f07861f86 100644 --- a/cpu/native/net/linuxradio-drv.c +++ b/cpu/native/net/linuxradio-drv.c @@ -34,8 +34,9 @@ */ #include "contiki.h" +#include "contiki-conf.h" -#ifdef linux +#if defined(linux) && UIP_CONF_IPV6 #include "linuxradio-drv.h" diff --git a/platform/minimal-net/contiki-conf.h b/platform/minimal-net/contiki-conf.h index 6b6b58e4a..bbc44642b 100644 --- a/platform/minimal-net/contiki-conf.h +++ b/platform/minimal-net/contiki-conf.h @@ -35,6 +35,9 @@ #include #include +#ifndef WIN32_LEAN_AND_MEAN +#include +#endif struct select_callback { int (* set_fd)(fd_set *fdr, fd_set *fdw); @@ -157,6 +160,8 @@ typedef unsigned short uip_stats_t; /* Not used but avoids compile errors while sicslowpan.c is being developed */ #define SICSLOWPAN_CONF_COMPRESSION SICSLOWPAN_COMPRESSION_HC06 +#define NETSTACK_CONF_LINUXRADIO_DEV "wpan0" + #define UIP_CONF_UDP 1 #define UIP_CONF_TCP 1 @@ -174,8 +179,6 @@ typedef unsigned short uip_stats_t; #define UIP_CONF_DS6_AADDR_NBU 0 #endif /* NETSTACK_CONF_WITH_IPV6 */ -#define NETSTACK_CONF_LINUXRADIO_DEV "wpan0" - typedef unsigned long clock_time_t; #define CLOCK_CONF_SECOND 1000 #define INFINITE_TIME ULONG_MAX From fee44766052bda729ae308440d85fb76b3a1c5ec Mon Sep 17 00:00:00 2001 From: Vladimir Pouzanov Date: Tue, 29 Sep 2015 10:36:18 +0100 Subject: [PATCH 114/120] Fixed detection of windows-native --- platform/minimal-net/contiki-conf.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/platform/minimal-net/contiki-conf.h b/platform/minimal-net/contiki-conf.h index bbc44642b..5368ac640 100644 --- a/platform/minimal-net/contiki-conf.h +++ b/platform/minimal-net/contiki-conf.h @@ -35,7 +35,7 @@ #include #include -#ifndef WIN32_LEAN_AND_MEAN +#ifndef _WIN32 #include #endif From 2d75926989a88c59f2360893e963ece8eb059a8e Mon Sep 17 00:00:00 2001 From: Vladimir Pouzanov Date: Tue, 29 Sep 2015 12:29:08 +0100 Subject: [PATCH 115/120] Fixed linuxradio-drv guard macro name --- cpu/native/net/linuxradio-drv.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cpu/native/net/linuxradio-drv.c b/cpu/native/net/linuxradio-drv.c index f07861f86..785bd1d87 100644 --- a/cpu/native/net/linuxradio-drv.c +++ b/cpu/native/net/linuxradio-drv.c @@ -36,7 +36,7 @@ #include "contiki.h" #include "contiki-conf.h" -#if defined(linux) && UIP_CONF_IPV6 +#if defined(linux) && NETSTACK_CONF_WITH_IPV6 #include "linuxradio-drv.h" From 24a38a3aa82097f0cc35422b4d7ffb5564310ebc Mon Sep 17 00:00:00 2001 From: Joakim Eriksson Date: Tue, 29 Sep 2015 18:24:03 +0200 Subject: [PATCH 116/120] check if objective function is supported before adding as parent and creating a dag --- core/net/rpl/rpl-dag.c | 20 +++++++++----------- 1 file changed, 9 insertions(+), 11 deletions(-) diff --git a/core/net/rpl/rpl-dag.c b/core/net/rpl/rpl-dag.c index 89be40184..9d140fbd4 100644 --- a/core/net/rpl/rpl-dag.c +++ b/core/net/rpl/rpl-dag.c @@ -938,6 +938,15 @@ rpl_join_instance(uip_ipaddr_t *from, rpl_dio_t *dio) rpl_parent_t *p; rpl_of_t *of; + /* Determine the objective function by using the + objective code point of the DIO. */ + of = rpl_find_of(dio->ocp); + if(of == NULL) { + PRINTF("RPL: DIO for DAG instance %u does not specify a supported OF: %u\n", + dio->instance_id, dio->ocp); + return; + } + dag = rpl_alloc_dag(dio->instance_id, &dio->dag_id); if(dag == NULL) { PRINTF("RPL: Failed to allocate a DAG object!\n"); @@ -958,17 +967,6 @@ rpl_join_instance(uip_ipaddr_t *from, rpl_dio_t *dio) p->dtsn = dio->dtsn; PRINTF("succeeded\n"); - /* Determine the objective function by using the - objective code point of the DIO. */ - of = rpl_find_of(dio->ocp); - if(of == NULL) { - PRINTF("RPL: DIO for DAG instance %u does not specify a supported OF\n", - dio->instance_id); - rpl_remove_parent(p); - instance->used = 0; - return; - } - /* Autoconfigure an address if this node does not already have an address with this prefix. */ if(dio->prefix_info.flags & UIP_ND6_RA_FLAG_AUTONOMOUS) { From c5b563f8e1ba4321cf9d572356f5531be176eb4c Mon Sep 17 00:00:00 2001 From: Laurent Deru Date: Fri, 12 Jun 2015 16:02:50 +0200 Subject: [PATCH 117/120] Estimated fragments should take into account 802.15.4 header size --- core/net/ipv6/sicslowpan.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/net/ipv6/sicslowpan.c b/core/net/ipv6/sicslowpan.c index 62b9014c5..a19f758fc 100644 --- a/core/net/ipv6/sicslowpan.c +++ b/core/net/ipv6/sicslowpan.c @@ -1455,7 +1455,7 @@ output(const uip_lladdr_t *localdest) * IPv6/HC1/HC06/HC_UDP dispatchs/headers. * The following fragments contain only the fragn dispatch. */ - int estimated_fragments = ((int)uip_len) / ((int)MAC_MAX_PAYLOAD - SICSLOWPAN_FRAGN_HDR_LEN) + 1; + int estimated_fragments = ((int)uip_len) / (max_payload - SICSLOWPAN_FRAGN_HDR_LEN) + 1; int freebuf = queuebuf_numfree() - 1; PRINTFO("uip_len: %d, fragments: %d, free bufs: %d\n", uip_len, estimated_fragments, freebuf); if(freebuf < estimated_fragments) { From e6978aba4e16bcf3671705b20260fa7934dca8f4 Mon Sep 17 00:00:00 2001 From: Simon Duquennoy Date: Wed, 30 Sep 2015 21:47:14 +0200 Subject: [PATCH 118/120] Updating mspsim submodule to latest --- tools/mspsim | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/mspsim b/tools/mspsim index 58f187351..47ae45cb0 160000 --- a/tools/mspsim +++ b/tools/mspsim @@ -1 +1 @@ -Subproject commit 58f187351f3417814aa2d0d92af9e2bb768d92ee +Subproject commit 47ae45cb0f36337115e32adb2a5ba0bf6e1e4437 From feba89a3f7a360648d8153f33f3825a8e92f6c09 Mon Sep 17 00:00:00 2001 From: Florian von Zabiensky Date: Tue, 6 Oct 2015 11:25:12 +0200 Subject: [PATCH 119/120] fixed memory bug --- core/lib/ccm-star.c | 1 - 1 file changed, 1 deletion(-) diff --git a/core/lib/ccm-star.c b/core/lib/ccm-star.c index e093c8703..537d341e1 100644 --- a/core/lib/ccm-star.c +++ b/core/lib/ccm-star.c @@ -114,7 +114,6 @@ mic(const uint8_t *m, uint8_t m_len, } if(m_len > 0) { - m = a + a_len; pos = 0; while(pos < m_len) { for(i = 0; (pos + i < m_len) && (i < AES_128_BLOCK_SIZE); i++) { From 44b3cd4e09882a1835d9a686570624133cc1471e Mon Sep 17 00:00:00 2001 From: Valentin Sawadski Date: Thu, 8 Oct 2015 17:18:26 +0200 Subject: [PATCH 120/120] Fixes a possible unsafe memcpy in uip_udp_packet_send If the buffers overlap, memcpy must not be used as it might have arbitrary results. memmove() on the other hand is safe to use. --- core/net/ip/uip-udp-packet.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/core/net/ip/uip-udp-packet.c b/core/net/ip/uip-udp-packet.c index 5cbf63763..923661709 100644 --- a/core/net/ip/uip-udp-packet.c +++ b/core/net/ip/uip-udp-packet.c @@ -54,9 +54,9 @@ uip_udp_packet_send(struct uip_udp_conn *c, const void *data, int len) if(data != NULL) { uip_udp_conn = c; uip_slen = len; - memcpy(&uip_buf[UIP_LLH_LEN + UIP_IPUDPH_LEN], data, - len > UIP_BUFSIZE - UIP_LLH_LEN - UIP_IPUDPH_LEN? - UIP_BUFSIZE - UIP_LLH_LEN - UIP_IPUDPH_LEN: len); + memmove(&uip_buf[UIP_LLH_LEN + UIP_IPUDPH_LEN], data, + len > UIP_BUFSIZE - UIP_LLH_LEN - UIP_IPUDPH_LEN? + UIP_BUFSIZE - UIP_LLH_LEN - UIP_IPUDPH_LEN: len); uip_process(UIP_UDP_SEND_CONN); #if UIP_CONF_IPV6_MULTICAST