void fireExternalInterruptISRIfNoDebounce(void (*isrFunction)(void), unsigned long *lastDebounceTime) { if(isrFunction != NULL) { if(hasTimeElapsed(lastDebounceTime, DebounceDelay)) { isrFunction(); } } }
void firePinChangeISRIfNoDebounce(volatile uint8_t* pinRegister, PinChangeInterruptConfig config) { if (hasTimeElapsed(&config.lastDebounceTime, DebounceDelay)) { uint8_t currentPinValue = *pinRegister & (1 << config.pin); if (doesPinChangeEqualInterruptMode(config.mode, currentPinValue, config.lastPinValue)) { if(config.isrFunction != NULL) { config.isrFunction(); } } config.lastPinValue = currentPinValue; } }
int checkForFilteredFlows(struct in_addr* source, struct in_addr* dest){ pthread_mutex_lock(&(rrFilteringLock)); RRFilterEntry* tmp = rrFilterEntryHead; while(tmp != NULL){ if((tmp->source == NULL || compareIPAddresses(source, tmp->source) == TRUE) && (tmp->dest == NULL || compareIPAddresses(dest, tmp->dest) == TRUE) ) { if(hasTimeElapsed(tmp->timeStart, tmp->delayedCountTime) == TRUE){ tmp->count = tmp->count + 1; } return TRUE; } } pthread_mutex_unlock(&(rrFilteringLock)); return FALSE; }
size_t TcpClient::writeStream(const byte *rgbWrite, size_t cbWrite, unsigned long msBlockMax, DNETcK::STATUS * pStatus) { unsigned long tStart = 0; size_t cbWritten = 0; size_t cbReady = 0; tStart = millis(); do { // make sure we are Connected // this will also run the stack if(!isConnected(DNETcK::msImmediate, pStatus)) { return(cbWritten); } if((cbReady = TCPIsPutReady(_hTCP)) > 0) { cbReady = cbReady < cbWrite ? cbReady : cbWrite; cbReady = TCPPutArray(_hTCP, &rgbWrite[cbWritten], cbReady); cbWritten += cbReady; cbWrite -= cbReady; // flush out what we are trying to write TCPFlush(_hTCP); } } while(cbWrite > 0 && !hasTimeElapsed(tStart, msBlockMax, millis())); // put in the status if(cbWritten < cbWrite && pStatus != NULL) { *pStatus = DNETcK::WriteTimeout; } // make sure the last flush runs EthernetPeriodicTasks(); return(cbWritten); }
bool TcpClient::isConnected(unsigned long msBlockMax, DNETcK::STATUS * pStatus) { unsigned long tStart = 0; bool fConnected = false; DNETcK::STATUS statusT = DNETcK::WaitingReConnect; // we want this to be PeriodicTasks and not StackTasks because we // want to run all of the applications when IsConnected is called // because this is a common call and we want to keep all things running EthernetPeriodicTasks(); // see if we ever supplied info for a connection if(_hTCP >= INVALID_SOCKET) { if(pStatus != NULL) *pStatus = DNETcK::SocketError; return(false); } switch(_classState) { case DNETcK::Connected: case DNETcK::WaitingReConnect: case DNETcK::LostConnect: if(!DNETcK_IsMacConnected(&statusT)) { _classState = statusT; if(pStatus != NULL) *pStatus = statusT; return(false); } else if(TCPIsConnected(_hTCP)) { _classState = DNETcK::Connected; if(pStatus != NULL) *pStatus = DNETcK::Connected; return(true); } else { _classState = DNETcK::LostConnect; if(pStatus != NULL) *pStatus = DNETcK::LostConnect; return(false); } break; case DNETcK::NotConnected: _classState = DNETcK::WaitingConnect; // fall thru to get connected case DNETcK::WaitingConnect: // loop until connected, or the timeout tStart = millis(); do { // in order to know what connection state we have // we must run the stack tasks EthernetPeriodicTasks(); if(TCPIsConnected(_hTCP)) { // now that we are connected, we can setup the endpoints if(!_fEndPointsSetUp) { // we just Connected, there should be nothing in the flush buffers // and we should have our remote endpoints all set up. GetTcpSocketEndPoints(_hTCP, &_remoteEP.ip, &_remoteMAC, &_remoteEP.port, &_localEP.port); DNETcK::getMyIP(&_localEP.ip); _fEndPointsSetUp = true; } // we are connected _classState = DNETcK::Connected; if(pStatus != NULL) *pStatus = DNETcK::Connected; return(true); } } while(!hasTimeElapsed(tStart, msBlockMax, millis())); // clearly not connected, return our state if(pStatus != NULL) *pStatus = _classState; return(false); break; default: if(pStatus != NULL) *pStatus = _classState; return(false); break; } }
bool UdpClient::isEndPointResolved(unsigned long msBlockMax, DNETcK::STATUS * pStatus) { unsigned long tStart = 0; DNETcK::STATUS statusT = DNETcK::None; // we want this to be PeriodicTasks and not StackTask because we // want to run all of the applications when IsDNETcK::EndPointResolved is called // because this is a common call and we want to keep all things running EthernetPeriodicTasks(); // nothing to do if we have already resolved it. if(_fEndPointsSetUp) { if(pStatus != NULL) *pStatus = DNETcK::EndPointResolved; return(true); } // make sure the network is initialized if(!DNETcK::isInitialzied(msBlockMax, pStatus)) { return(false); } // make sure the UDP cache is big enough if(_cbCache < UdpClient::cbDatagramCacheMin) { if(pStatus != NULL) *pStatus = DNETcK::UDPCacheToSmall; return(false); } // initialize our status to our current state if(pStatus != NULL) *pStatus = _classState; // return our current state, except if we are in the process of resolving if(DNETcK::isStatusAnError(_classState)) { return(false); } // continue with the resolve process tStart = millis(); do { // run the stack EthernetPeriodicTasks(); switch(_classState) { case DNETcK::DNSResolving: if(DNETcK::isDNSResolved(_szHostName, &_remoteEP.ip, DNETcK::msImmediate, &statusT)) { DNETcK::requestARPIpMacResolution(_remoteEP.ip); _classState = DNETcK::ARPResolving; _msARPtStart = millis(); } // stay at the resolving state until an error occurs // if an error, then we fail. else if(DNETcK::isStatusAnError(statusT)) { _classState = DNETcK::DNSResolutionFailed; } break; case DNETcK::ARPResolving: // see if we resolved the MAC address if(DNETcK::isARPIpMacResolved(_remoteEP.ip, &_remoteMAC, DNETcK::msImmediate)) { _classState = DNETcK::AcquiringSocket; _msARPtStart = 0; } // if the ARP timeout has occured; rmember, ARP really doesn't give us failues else if(hasTimeElapsed(_msARPtStart, _msARPWait, millis())) { // resend the ARP Request if(_cARPRetries > 0) { DNETcK::requestARPIpMacResolution(_remoteEP.ip); _msARPtStart = millis(); _cARPRetries--; } // otherwise we are done else { _classState = DNETcK::ARPResolutionFailed; _msARPtStart = 0; } } break; case DNETcK::AcquiringSocket: // set up the socket _hUDP = UdpClientSetEndPoint(_remoteEP.ip.rgbIP, _remoteMAC.rgbMAC, _remoteEP.port, _localPort); if(_hUDP >= INVALID_UDP_SOCKET) { _classState = DNETcK::SocketError; if(pStatus != NULL) *pStatus = _classState; break; } // fall right into finalize; we have finalize for the UdpServer to use case DNETcK::Finalizing: // assume the best that we will finish, unless something bad happens. _classState = DNETcK::EndPointResolved; // we just set up the socket, so all of the IP and port info should be correct // let's just update our code so we know we have what the MAL thinks. GetUdpSocketEndPoints(_hUDP, &_remoteEP.ip, &_remoteMAC, &_remoteEP.port, &_localPort); // see if a cache buffer came in. if(_rgbCache == NULL) { close(); _classState = DNETcK::UDPCacheToSmall; } // add it to the underlying caching engine else { ExchangeCacheBuffer(_hUDP, _rgbCache, _cbCache); } break; // if we got an error in the process, we are done. // this is how we get out of the do-while on an error default: if(pStatus != NULL) *pStatus = _classState; return(false); } } while(_classState != DNETcK::EndPointResolved && !hasTimeElapsed(tStart, msBlockMax, millis())); // not sure how we got out of the loop // but assign our state and only return true if we succeeded. if(pStatus != NULL) *pStatus = _classState; if(_classState == DNETcK::EndPointResolved) { _fEndPointsSetUp = true; return(true); } return(false); }