diff --git a/firmware/applications/mesh/mesh.c b/firmware/applications/mesh/mesh.c index dccfd6d..e142c50 100644 --- a/firmware/applications/mesh/mesh.c +++ b/firmware/applications/mesh/mesh.c @@ -10,39 +10,12 @@ #include "funk/nrf24l01p.h" +#include "funk/mesh.h" + #include -#define MESH_CHANNEL 85 -#define MESH_MAC "MESHB" - /**************************************************************************/ -uint32_t const meshkey[4] = { - 0x00000000, 0x00000000, 0x00000000, 0x00000000 -}; - -#define MESHBUFSIZE 10 -#define MESHPKTSIZE 32 -typedef struct { - uint8_t pkt[32]; - char flags; -} MPKT; - -MPKT meshbuffer[MESHBUFSIZE]; - -#define MF_FREE (0) -#define MF_USED (1<<0) - -time_t _timet=0; - -// Timezones suck. Currently we only do it all in localtime. -// I know it's broken. Sorry -time_t getSeconds(void){ - return _timet+(getTimer()*SYSTICKSPEED/1000); -}; - -// ********************************************************************** - void m_init(void){ nrf_init(); @@ -56,169 +29,16 @@ void m_init(void){ nrf_config_set(&config); - for(int i=0;itm_sec = dayclock % 60; - timep->tm_min = (dayclock % 3600) / 60; - timep->tm_hour = dayclock / 3600; - timep->tm_wday = (dayno + 4) % 7; /* day 0 was a thursday */ - while (dayno >= YEARSIZE(year)) { - dayno -= YEARSIZE(year); - year++; - } - timep->tm_year = year - YEAR0; - timep->tm_yday = dayno; - timep->tm_mon = 0; - while (dayno >= _ytab[LEAPYEAR(year)][timep->tm_mon]) { - dayno -= _ytab[LEAPYEAR(year)][timep->tm_mon]; - timep->tm_mon++; - } - timep->tm_mday = dayno + 1; - timep->tm_isdst = 0; - - return timep; -} - -#define M_SENDINT 500 -#define M_RECVINT 1000 -#define M_RECVTIM 100 - - -void m_recv(void){ - __attribute__ ((aligned (4))) uint8_t buf[32]; - int len; - int recvend=M_RECVTIM/SYSTICKSPEED+getTimer(); - - static int toggle=0; - gpioSetValue (RB_LED2, toggle); - toggle=1-toggle; - - m_cleanup(); - - nrf_rcv_pkt_start(); - do{ - len=nrf_rcv_pkt_poll_dec(sizeof(buf),buf,meshkey); - - // Receive - if(len<=0){ - delayms_power(10); - continue; - }; - - int i; - for(i=0;i_timet) // Do not live in the past. - _timet = toff; - }else if (buf[0]>='A' && buf[0] <'T'){ // Truncate ascii packets. - meshbuffer[i].pkt[MESHPKTSIZE-3]=0; - }; - }while(getTimer()tm_year+YEAR0); lcdNl(); + + lcdNl(); + lcdPrint("<"); + + for(int i=0;i"); + + lcdPrint("Gen:"); + lcdPrintInt(meshgen); + lcdNl(); lcdRefresh(); delayms_queue(50); }while ((getInputRaw())==BTN_NONE); }; + + +inline void blink(char a, char b){ + gpioSetValue (a,b, 1-gpioGetValue(a,b)); +}; + + + +/***********************************************************************/ + + +void m_cleanup(void){ + mesh_cleanup(); +}; + +void m_recv(void){ + mesh_recvloop(); +} + +void m_send(void){ + mesh_sendloop(); +}; + +void tick_mesh(void){ + mesh_systick(); +}; + diff --git a/firmware/funk/Makefile b/firmware/funk/Makefile index 77e9a83..b8bd41f 100644 --- a/firmware/funk/Makefile +++ b/firmware/funk/Makefile @@ -8,6 +8,7 @@ OBJS += nrf24l01p.o OBJS += rftransfer.o OBJS += filetransfer.o OBJS += openbeacon.o +OBJS += mesh.o LIBNAME=funk diff --git a/firmware/funk/mesh.c b/firmware/funk/mesh.c new file mode 100644 index 0000000..e0f869f --- /dev/null +++ b/firmware/funk/mesh.c @@ -0,0 +1,163 @@ +#include +#include +#include "basic/basic.h" +#include "funk/mesh.h" +#include "funk/nrf24l01p.h" +#include "basic/byteorder.h" +#include "basic/random.h" + +char meshgen=0; // Generation +MPKT meshbuffer[MESHBUFSIZE]; + +uint32_t const meshkey[4] = { + 0x00000000, 0x00000000, 0x00000000, 0x00000000 +}; + +struct NRF_CFG oldconfig; + +void initMesh(void){ + for(int i=0;iSECS_DAY) + meshbuffer[i].flags=MF_FREE; + }; + }; +}; + +void mesh_recvloop(void){ + __attribute__ ((aligned (4))) uint8_t buf[32]; + int len; + int recvend=M_RECVTIM/SYSTICKSPEED+getTimer(); + int pktctr=0; + + nrf_config_get(&oldconfig); + + nrf_set_channel(MESH_CHANNEL); + nrf_set_rx_mac(0,MESHPKTSIZE,strlen(MESH_MAC),(uint8_t*)MESH_MAC); + + mesh_cleanup(); + + nrf_rcv_pkt_start(); + do{ + len=nrf_rcv_pkt_poll_dec(sizeof(buf),buf,meshkey); + + // Receive + if(len<=0){ + delayms_power(10); + continue; + }; + pktctr++; + + if(MO_GEN(buf)>meshgen){ + meshgen++; + _timet=0; + continue; + }; + + if(MO_TYPE(buf)=='T'){ + time_t toff=MO_TIME(buf)-(getTimer()*SYSTICKSPEED/1000); + if (toff>_timet) // Do not live in the past. + _timet = toff; + continue; + }; + + // Safety: Truncate ascii packets by 0-ing the CRC + if (MO_TYPE(buf) >='A' && MO_TYPE(buf) <='Z'){ + buf[MESHPKTSIZE-2]=0; + }; + + // Store packet in a free slot + int free=-1; + for(int i=0;i + MO_TIME(meshbuffer[i].pkt)){ + free=i; + break; + }else{ + free=-2; + break; + }; + }; + }; + + if(free==-1){ // Buffer full. Ah well. Kill a random packet + free=1; // XXX: GetRandom()? + }; + + if(free<0) + continue; + + memcpy(meshbuffer[free].pkt,buf,MESHPKTSIZE); + meshbuffer[free].flags=MF_USED; + + }while(getTimer()MESHBUFSIZE); + + nrf_rcv_pkt_end(); + nrf_config_set(&oldconfig); +} + +void mesh_sendloop(void){ + int ctr=0; + __attribute__ ((aligned (4))) uint8_t buf[32]; + int status; + + nrf_config_get(&oldconfig); + nrf_set_channel(MESH_CHANNEL); + nrf_set_tx_mac(strlen(MESH_MAC),(uint8_t*)MESH_MAC); + + // Update [T]ime packet + MO_TIME_set(meshbuffer[0].pkt,getSeconds()); + MO_GEN_set(meshbuffer[0].pkt,meshgen); + + for (int i=0;i