#include #include #include #include "basic/basic.h" #include "funk/mesh.h" #include "funk/nrf24l01p.h" #include "basic/byteorder.h" #include "basic/random.h" #include "basic/config.h" char meshgen=0; // Generation char meshincctr=0; char meshmsg=0; MPKT meshbuffer[MESHBUFSIZE]; uint32_t const meshkey[4] = { 0x00000042, 0x000005ec, 0x00000023, 0x00000005 }; struct NRF_CFG oldconfig; void initMesh(void){ for(int i=0;i='a' && MO_TYPE(meshbuffer[i].pkt)<='z'){ ; }else{ if (MO_TIME(meshbuffer[i].pkt)SECS_DAY) meshbuffer[i].flags=MF_FREE; }; }; }; }; 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); if(GLOBAL(privacy)==0) uint32touint8p(GetUUID32(),MO_BODY(meshbuffer[0].pkt)); else uint32touint8p(0,MO_BODY(meshbuffer[0].pkt)); for (int i=0;imeshgen){ if(meshgen) meshgen++; else meshgen=MO_GEN(buf); _timet=0; meshincctr=0; }; if(MO_TYPE(buf)=='T'){ time_t toff=MO_TIME(buf)-((getTimer()+(600/SYSTICKSPEED))/(1000/SYSTICKSPEED)); if (toff>_timet){ // Do not live in the past. _timet = toff; meshincctr++; }; return 1; }; // Safety: Truncate ascii packets by 0-ing the CRC buf[MESHPKTSIZE-2]=0; // Store packet in a same/free slot MPKT* mpkt=meshGetMessage(MO_TYPE(buf)); // Skip locked packet if(mpkt->flags&MF_LOCK) return 2; // only accept newer/better packets if(mpkt->flags==MF_USED) if(MO_TIME(buf)<=MO_TIME(mpkt->pkt)) return 2; if((MO_TYPE(buf)>='A' && MO_TYPE(buf)<='C') || (MO_TYPE(buf)>='A' && MO_TYPE(buf)<='C')) meshmsg=1; memcpy(mpkt->pkt,buf,MESHPKTSIZE); mpkt->flags=MF_USED; return 1; }; void mesh_recvqloop_end(void){ nrf_rcv_pkt_end(); nrf_config_set(&oldconfig); } void mesh_recvloop(void){ int recvend=M_RECVTIM/SYSTICKSPEED+getTimer(); int pktctr=0; mesh_recvqloop_setup(); do{ if( mesh_recvqloop_work() ){ pktctr++; }else{ delayms_power(10); }; }while(getTimer()MESHBUFSIZE); mesh_recvqloop_end(); }; uint8_t mesh_recvloop_plus(uint8_t state){ static int recvend=0; static int pktctr=0; if (state==0){ recvend=M_RECVTIM/SYSTICKSPEED+getTimer(); pktctr=0; mesh_recvqloop_setup(); state=1; }; if(state==1){ if( mesh_recvqloop_work() ){ pktctr++; }else{ delayms_power(10); }; if(getTimer()>recvend || pktctr>MESHBUFSIZE) state=0xff; }; if(state==0xff){ return 0xff; }; return state; }; void mesh_systick(void){ static int rcvctr=0; static int sendctr=0; if(rcvctr--<0){ push_queue_plus(&mesh_recvloop_plus); rcvctr=M_RECVINT/SYSTICKSPEED/2; rcvctr+=getRandom()%(rcvctr*2); }; if(sendctr--<0){ push_queue(&mesh_sendloop); sendctr=M_SENDINT/SYSTICKSPEED/2; sendctr+=getRandom()%(sendctr*2); }; };