<commit_before>#include "receiver.h"

/* Plugin includes */
#include "pud.h"
#include "state.h"
#include "posAvg.h"
#include "configuration.h"
#include "gpsConversion.h"
#include "networkInterfaces.h"
#include "timers.h"
#include "uplinkGateway.h"
#include "dump.h"

/* OLSRD includes */
#include "olsr_types.h"
#include "net_olsr.h"

/* System includes */
#include <pthread.h>
#include <nmea/parser.h>
#include <nmea/gmath.h>
#include <nmea/sentence.h>
#include <OlsrdPudWireFormat/wireFormat.h>

/* Debug includes */
#if defined(PUD_DUMP_GPS_PACKETS_TX_OLSR) || \
	defined(PUD_DUMP_GPS_PACKETS_TX_UPLINK) || \
	defined(PUD_DUMP_AVERAGING)
#include "olsr.h"
#endif

/*
 * NMEA parser
 */

/** The NMEA string parser */
static nmeaPARSER nmeaParser;

/*
 * State
 */

/** Type describing movement calculations */
typedef struct _MovementType {
	TristateBoolean moving; /**< SET: we are moving */

	TristateBoolean overThresholds; /**< SET: at least 1 threshold state is set */
	TristateBoolean speedOverThreshold; /**< SET: speed is over threshold */
	TristateBoolean hDistanceOverThreshold; /**< SET: horizontal distance is outside threshold */
	TristateBoolean vDistanceOverThreshold; /**< SET: vertical distance is outside threshold */

	TristateBoolean outside; /**< SET: at least 1 outside state is SET */
	TristateBoolean outsideHdop; /**< SET: avg is outside lastTx HDOP */
	TristateBoolean outsideVdop; /**< SET: avg is outside lastTx VDOP */

	TristateBoolean inside; /**< SET: all inside states are SET */
	TristateBoolean insideHdop; /**< SET: avg is inside lastTx HDOP */
	TristateBoolean insideVdop; /**< SET: avg is inside lastTx VDOP */
} MovementType;

/*
 * Averaging
 */

/** The average position with its administration */
static PositionAverageList positionAverageList;

/*
 * TX to OLSR
 */

typedef enum _TimedTxInterface {
	TX_INTERFACE_OLSR = 1,
	TX_INTERFACE_UPLINK = 2
} TimedTxInterface;

/** Structure of the latest GPS information that is transmitted */
typedef struct _TransmitGpsInformation {
	pthread_mutex_t mutex; /**< access mutex */
	bool positionUpdated; /**< true when the position information was updated */
	PositionUpdateEntry txPosition; /**< The last transmitted position */
	union olsr_ip_addr txGateway; /**< the best gateway */
} TransmitGpsInformation;

/** The latest position information that is transmitted */
static TransmitGpsInformation transmitGpsInformation;

/** The size of the buffer in which the OLSR and uplink messages are assembled */
#define TX_BUFFER_SIZE_FOR_OLSR 1024

/*
 * Functions
 */

/**
 Clear the MovementType
 * @param result a pointer to the MovementType
 */
static void clearMovementType(MovementType * result) {
	/* clear outputs */
	result->moving = TRISTATE_BOOLEAN_UNKNOWN;
	result->overThresholds = TRISTATE_BOOLEAN_UNKNOWN;
	result->speedOverThreshold = TRISTATE_BOOLEAN_UNKNOWN;
	result->hDistanceOverThreshold = TRISTATE_BOOLEAN_UNKNOWN;
	result->vDistanceOverThreshold = TRISTATE_BOOLEAN_UNKNOWN;
	result->outside = TRISTATE_BOOLEAN_UNKNOWN;
	result->outsideHdop = TRISTATE_BOOLEAN_UNKNOWN;
	result->outsideVdop = TRISTATE_BOOLEAN_UNKNOWN;
	result->inside = TRISTATE_BOOLEAN_UNKNOWN;
	result->insideHdop = TRISTATE_BOOLEAN_UNKNOWN;
	result->insideVdop = TRISTATE_BOOLEAN_UNKNOWN;
}

/**
 Determine whether s position is valid.

 @param position
 a pointer to a position

 @return
 - true when valid
 - false otherwise
 */
static bool positionValid(PositionUpdateEntry * position) {
	return (nmea_INFO_has_field(position->nmeaInfo.smask, FIX)
			&& (position->nmeaInfo.fix != NMEA_FIX_BAD));
}

/**
 Send the transmit buffer out over all designated interfaces, called as a
 timer callback and also immediately on an external state change.

 @param interfaces
 a bitmap defining which interfaces to send over
 */
static void txToAllOlsrInterfaces(TimedTxInterface interfaces) {
	/** txBuffer is used to concatenate the position update and cluster leader messages in */
	unsigned char txBuffer[TX_BUFFER_SIZE_FOR_OLSR];
	unsigned int txBufferBytesUsed = 0;
	#define txBufferBytesFree	(sizeof(txBuffer) - txBufferBytesUsed)

	/*
	 * The first message in txBuffer is an OLSR position update.
	 *
	 * The position update is not present when the position is not valid.
	 * Otherwise it is always present: when we transmit onto the OLSR network
	 * and/or when we transmit onto the uplink.
	 *
	 * The second message is the cluster leader message, but only when uplink
	 * was requested and correctly configured.
	 */

	UplinkMessage * pu_uplink = (UplinkMessage *) &txBuffer[0];
	union olsr_message * pu = &pu_uplink->msg.olsrMessage;
	unsigned int pu_size = 0;
	union olsr_ip_addr gateway;
	unsigned long long updateInterval;

	updateInterval =
			(getExternalState() == MOVEMENT_STATE_MOVING) ? getUpdateIntervalMoving() : getUpdateIntervalStationary();

	(void) pthread_mutex_lock(&transmitGpsInformation.mutex);

	/* only fixup timestamp when the position is valid _and_ when the position was not updated */
	if (positionValid(&transmitGpsInformation.txPosition) && !transmitGpsInformation.positionUpdated) {
		nmea_time_now(&transmitGpsInformation.txPosition.nmeaInfo.utc);
	}

	/* convert nmeaINFO to wireformat olsr message */
	txBufferBytesUsed += sizeof(UplinkHeader); /* keep before txBufferSpaceFree usage */
	pu_size = gpsToOlsr(&transmitGpsInformation.txPosition.nmeaInfo, pu, txBufferBytesFree, updateInterval);
	txBufferBytesUsed += pu_size;
	gateway = transmitGpsInformation.txGateway;

	transmitGpsInformation.positionUpdated = false;
	(void) pthread_mutex_unlock(&transmitGpsInformation.mutex);

	/*
	 * push out to all OLSR interfaces
	 */
	if (((interfaces & TX_INTERFACE_OLSR) != 0) && (pu_size > 0)) {
		int r;
		struct interface *ifn;
		for (ifn = ifnet; ifn; ifn = ifn->int_next) {
			r = net_outbuffer_push(ifn, pu, pu_size);
			if (r != (int) pu_size) {
				pudError(<commit_msg>PUD: consistent use of external state and resulting update interval<commit_after>#include "receiver.h"

/* Plugin includes */
#include "pud.h"
#include "state.h"
#include "posAvg.h"
#include "configuration.h"
#include "gpsConversion.h"
#include "networkInterfaces.h"
#include "timers.h"
#include "uplinkGateway.h"
#include "dump.h"

/* OLSRD includes */
#include "olsr_types.h"
#include "net_olsr.h"

/* System includes */
#include <pthread.h>
#include <nmea/parser.h>
#include <nmea/gmath.h>
#include <nmea/sentence.h>
#include <OlsrdPudWireFormat/wireFormat.h>

/* Debug includes */
#if defined(PUD_DUMP_GPS_PACKETS_TX_OLSR) || \
	defined(PUD_DUMP_GPS_PACKETS_TX_UPLINK) || \
	defined(PUD_DUMP_AVERAGING)
#include "olsr.h"
#endif

/*
 * NMEA parser
 */

/** The NMEA string parser */
static nmeaPARSER nmeaParser;

/*
 * State
 */

/** Type describing movement calculations */
typedef struct _MovementType {
	TristateBoolean moving; /**< SET: we are moving */

	TristateBoolean overThresholds; /**< SET: at least 1 threshold state is set */
	TristateBoolean speedOverThreshold; /**< SET: speed is over threshold */
	TristateBoolean hDistanceOverThreshold; /**< SET: horizontal distance is outside threshold */
	TristateBoolean vDistanceOverThreshold; /**< SET: vertical distance is outside threshold */

	TristateBoolean outside; /**< SET: at least 1 outside state is SET */
	TristateBoolean outsideHdop; /**< SET: avg is outside lastTx HDOP */
	TristateBoolean outsideVdop; /**< SET: avg is outside lastTx VDOP */

	TristateBoolean inside; /**< SET: all inside states are SET */
	TristateBoolean insideHdop; /**< SET: avg is inside lastTx HDOP */
	TristateBoolean insideVdop; /**< SET: avg is inside lastTx VDOP */
} MovementType;

/*
 * Averaging
 */

/** The average position with its administration */
static PositionAverageList positionAverageList;

/*
 * TX to OLSR
 */

typedef enum _TimedTxInterface {
	TX_INTERFACE_OLSR = 1,
	TX_INTERFACE_UPLINK = 2
} TimedTxInterface;

/** Structure of the latest GPS information that is transmitted */
typedef struct _TransmitGpsInformation {
	pthread_mutex_t mutex; /**< access mutex */
	bool positionUpdated; /**< true when the position information was updated */
	PositionUpdateEntry txPosition; /**< The last transmitted position */
	union olsr_ip_addr txGateway; /**< the best gateway */
} TransmitGpsInformation;

/** The latest position information that is transmitted */
static TransmitGpsInformation transmitGpsInformation;

/** The size of the buffer in which the OLSR and uplink messages are assembled */
#define TX_BUFFER_SIZE_FOR_OLSR 1024

/*
 * Functions
 */

/**
 Clear the MovementType
 * @param result a pointer to the MovementType
 */
static void clearMovementType(MovementType * result) {
	/* clear outputs */
	result->moving = TRISTATE_BOOLEAN_UNKNOWN;
	result->overThresholds = TRISTATE_BOOLEAN_UNKNOWN;
	result->speedOverThreshold = TRISTATE_BOOLEAN_UNKNOWN;
	result->hDistanceOverThreshold = TRISTATE_BOOLEAN_UNKNOWN;
	result->vDistanceOverThreshold = TRISTATE_BOOLEAN_UNKNOWN;
	result->outside = TRISTATE_BOOLEAN_UNKNOWN;
	result->outsideHdop = TRISTATE_BOOLEAN_UNKNOWN;
	result->outsideVdop = TRISTATE_BOOLEAN_UNKNOWN;
	result->inside = TRISTATE_BOOLEAN_UNKNOWN;
	result->insideHdop = TRISTATE_BOOLEAN_UNKNOWN;
	result->insideVdop = TRISTATE_BOOLEAN_UNKNOWN;
}

/**
 Determine whether s position is valid.

 @param position
 a pointer to a position

 @return
 - true when valid
 - false otherwise
 */
static bool positionValid(PositionUpdateEntry * position) {
	return (nmea_INFO_has_field(position->nmeaInfo.smask, FIX)
			&& (position->nmeaInfo.fix != NMEA_FIX_BAD));
}

/**
 Send the transmit buffer out over all designated interfaces, called as a
 timer callback and also immediately on an external state change.

 @param interfaces
 a bitmap defining which interfaces to send over
 */
static void txToAllOlsrInterfaces(TimedTxInterface interfaces) {
	/** txBuffer is used to concatenate the position update and cluster leader messages in */
	unsigned char txBuffer[TX_BUFFER_SIZE_FOR_OLSR];
	unsigned int txBufferBytesUsed = 0;
	#define txBufferBytesFree	(sizeof(txBuffer) - txBufferBytesUsed)

	/*
	 * The first message in txBuffer is an OLSR position update.
	 *
	 * The position update is not present when the position is not valid.
	 * Otherwise it is always present: when we transmit onto the OLSR network
	 * and/or when we transmit onto the uplink.
	 *
	 * The second message is the cluster leader message, but only when uplink
	 * was requested and correctly configured.
	 */

	UplinkMessage * pu_uplink = (UplinkMessage *) &txBuffer[0];
	union olsr_message * pu = &pu_uplink->msg.olsrMessage;
	unsigned int pu_size = 0;
	union olsr_ip_addr gateway;
	unsigned long long updateInterval;

	updateInterval =
			(getExternalState() == MOVEMENT_STATE_STATIONARY) ? getUpdateIntervalStationary() : getUpdateIntervalMoving();

	(void) pthread_mutex_lock(&transmitGpsInformation.mutex);

	/* only fixup timestamp when the position is valid _and_ when the position was not updated */
	if (positionValid(&transmitGpsInformation.txPosition) && !transmitGpsInformation.positionUpdated) {
		nmea_time_now(&transmitGpsInformation.txPosition.nmeaInfo.utc);
	}

	/* convert nmeaINFO to wireformat olsr message */
	txBufferBytesUsed += sizeof(UplinkHeader); /* keep before txBufferSpaceFree usage */
	pu_size = gpsToOlsr(&transmitGpsInformation.txPosition.nmeaInfo, pu, txBufferBytesFree, updateInterval);
	txBufferBytesUsed += pu_size;
	gateway = transmitGpsInformation.txGateway;

	transmitGpsInformation.positionUpdated = false;
	(void) pthread_mutex_unlock(&transmitGpsInformation.mutex);

	/*
	 * push out to all OLSR interfaces
	 */
	if (((interfaces & TX_INTERFACE_OLSR) != 0) && (pu_size > 0)) {
		int r;
		struct interface *ifn;
		for (ifn = ifnet; ifn; ifn = ifn->int_next) {
			r = net_outbuffer_push(ifn, pu, pu_size);
			if (r != (int) pu_size) {
				pudError(
{'fraction_non_alphanumeric': 0.09884999154405547, 'fraction_numerical': 0.002198545577541011, 'mean_word_length': 4.937248995983936, 'pattern_counts': {'":': 0, '<': 43, '<?xml version=': 0, '>': 45, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '5487211', 'n_tokens_mistral': 3914, 'n_tokens_neox': 3721, 'n_words': 1066}