29 #include <netinet/in.h>
30 #include <netinet/tcp.h>
31 #include <sys/socket.h>
72 const size_t bufSize = 1024;
73 uint8_t *buf = calloc(bufSize,
sizeof(uint8_t));
75 time_t lastRead = time(NULL);
76 time_t lastGoodSignal = time(NULL);
78 uint16_t cycdata[20] = {0};
82 uint16_t sysdata[16] = {0};
84 time_t now = time(NULL);
85 if ((lastRead + dwInfo->
timeout) < now) {
95 args->
tag, strerror(errno));
103 if (dw_hw < (ssize_t)(bufSize - 1)) {
105 ti = read(dwInfo->
handle, &(buf[dw_hw]), bufSize - dw_hw);
114 if (errno != EAGAIN) {
116 log_error(args->
pstate,
"[DW:%s] Unexpected error while reading from network (%s)",
117 args->
tag, strerror(errno));
139 lastGoodSignal = now;
146 cycdata[cCount++] = cd;
150 if ((now - lastGoodSignal) > 300) {
154 lastGoodSignal = now;
158 bool syncFound =
false;
159 for (
int i = 0; i < cCount; ++i) {
160 if (cycdata[i] == 0x7FFF) {
163 for (
int j = 0; j < cCount && (j + i) < 20; ++j) {
164 cycdata[j] = cycdata[j + i];
173 memset(cycdata, 0, 20 *
sizeof(cycdata[0]));
179 log_info(args->
pstate, 1,
"[DW:%s] Invalid spectrum data (cCount: %d)\n",
186 for (
int n = 0; n < 4; ++n) {
201 for (
int i = 0; i < 16; ++i) {
229 memset(&sysdata, 0, 16 *
sizeof(uint16_t));
230 memset(&sdset, 0, 16 *
sizeof(
bool));
233 cycdata[0] = cycdata[18];
234 cycdata[1] = cycdata[19];
235 memset(&(cycdata[2]), 0, 18 *
sizeof(uint16_t));
248 memset(buf, 0, bufSize);
289 if (dwInfo->
handle >= 0) {
315 if (dwInfo->
addr == NULL) {
321 if (dwInfo->
handle >= 0) {
328 struct sockaddr_in targetSA;
332 dwInfo->
handle = socket(PF_INET, SOCK_STREAM, 0);
334 struct hostent *hostinfo;
335 targetSA.sin_family = AF_INET;
336 targetSA.sin_port = htons(1180);
337 hostinfo = gethostbyname(dwInfo->
addr);
339 if (hostinfo == NULL) {
340 perror(
"dw_net_connect(hostinfo)");
343 targetSA.sin_addr = *(
struct in_addr *)hostinfo->h_addr;
346 int rs = connect(dwInfo->
handle, (
struct sockaddr *)&targetSA,
sizeof(targetSA));
347 if ((rs < 0) && (errno != EINPROGRESS)) {
348 perror(
"dw_net_connect(connect)");
353 if (fcntl(dwInfo->
handle, F_SETFL, fcntl(dwInfo->
handle, F_GETFL, NULL) | O_NONBLOCK) < 0) {
354 perror(
"dw_net_connect(fcntl)");
358 if (setsockopt(dwInfo->
handle, IPPROTO_TCP, TCP_NODELAY, (
void *)&enable,
sizeof(enable))) {
359 perror(
"dw_net_connect(NODELAY)");
386 .parseSpectrum =
false};
478 log_error(lta->
pstate,
"[DW:%s] Unable to allocate memory for device parameters",
498 int sn = strtol(t->
value, NULL, 0);
518 "[DW:%s] Unexpected Source ID number (0x%02x)- this may cause analysis problems",
536 "[DW:%s] Invalid timeout value (%d is not greater than zero)",
561 log_error(lta->
pstate,
"[DW:%s] Invalid value provided for 'spectrum': %s",
int config_parse_bool(const char *b)
Parse string to boolean.
char * config_qstrdup(const char *c)
Duplicate string, stripping optional leading/trailing quote marks.
config_kv * config_get_key(const config_section *cs, const char *kn)
Find configugration key within specific section, by name.
void signalHandlersBlock(void)
Block signals that we have handlers for.
bool shutdown
Set true to start clean shutdown.
msg_t * msg_new_string(const uint8_t source, const uint8_t type, const size_t len, const char *str)
Create a new message with a single string embedded.
void msg_destroy(msg_t *msg)
Destroy a message.
msg_t * msg_new_string_array(const uint8_t source, const uint8_t type, const strarray *array)
Create a new message containing an array of strings.
msg_t * msg_new_bytes(const uint8_t source, const uint8_t type, const size_t len, const uint8_t *bytes)
Create a new message containing raw binary data.
msg_t * msg_new_float(const uint8_t source, const uint8_t type, const float val)
Create new message with a single numeric value.
int16_t dw_hxv_vertical(const dw_hxv *in)
Extract vertical displacement component from HXV input line.
int16_t dw_hxv_west(const dw_hxv *in)
Extract west displacement component from HXV input line.
bool dw_spectrum_from_array(const uint16_t *arr, dw_spectrum *out)
Populate dw_spectrum from array of cyclic data words.
int16_t dw_hxv_north(const dw_hxv *in)
Extract north displacement component from HXV input line.
uint16_t dw_hxv_cycdat(const dw_hxv *in)
Extract cyclic data word from HXV input line.
bool dw_string_hxv(const char *in, size_t *end, dw_hxv *out)
Read a line of HXV data from string and convert.
bool dw_system_from_array(const uint16_t *arr, dw_system *out)
Extract system data from array of cyclic data words.
#define SLCHAN_TSTAMP
Source timestamp (milliseconds, arbitrary epoch)
#define SLCHAN_RAW
Raw device data (Not mandatory)
#define SLCHAN_MAP
Channel name map (excludes log channels)
#define SLCHAN_NAME
Name of source device.
#define DWCHAN_DV
Displacement (Vertical)
#define DWCHAN_TWTR
Water Temperature.
#define DWCHAN_SPM
Spectral data: M2 coefficient.
#define DWCHAN_DN
Displacement (North)
#define DWCHAN_SPS
Spectral data: Spread.
#define DWCHAN_LON
Longitude (Decimal degrees)
#define DWCHAN_SPD
Spectral data: Direction.
#define DWCHAN_SIG
Reported signal strength.
#define DWCHAN_LAT
Latitude (Decimal degrees)
#define DWCHAN_GPSFIX
GPS quality.
#define DWCHAN_DW
Displacement (West)
#define DWCHAN_INCLIN
Device inclination.
#define DWCHAN_SPF
Spectral data: Frequency.
#define DWCHAN_SPK
Spectral data: K factor.
#define DWCHAN_SPN
Spectral data: N2 coefficient.
#define DWCHAN_ORIENT
Device orientation.
#define DWCHAN_SPR
Spectral data: Relative PSD.
#define DWCHAN_HRMS
RMS Wave Height.
#define DWCHAN_TREF
Reference Temperature.
#define DWCHAN_WEEKS
Estimated weeks of battery remaining.
bool dw_net_connect(void *ptargs)
DW Network connection helper.
void * dw_channels(void *ptargs)
Channel map.
bool dw_parseConfig(log_thread_args_t *lta, config_section *s)
Take a configuration section and parse parameters.
void dw_push_message(log_thread_args_t *args, uint8_t sNum, uint8_t cNum, float data)
Create and push messages to queue.
void * dw_setup(void *ptargs)
Datawell thread setup.
dw_params dw_getParams()
Fill out default MP source parameters.
void * dw_logging(void *ptargs)
Datawell source main logging loop.
void * dw_shutdown(void *ptargs)
Datawell source shutdown.
device_callbacks dw_getCallbacks()
Fill out device callback functions for logging.
bool net_connect(void *ptargs)
Network connection helper function.
#define SLSOURCE_EXT
External data sources recorded but not interpreted by the logger.
atomic_bool shutdownFlag
Trigger clean software shutdown.
void log_info(const program_state *s, const int level, const char *format,...)
Output formatted information message at a given level.
void log_warning(const program_state *s, const char *format,...)
Output formatted warning message.
void log_error(const program_state *s, const char *format,...)
Output formatted error message.
bool queue_push(msgqueue *queue, msg_t *msg)
Add a message to the tail of the queue.
void sa_destroy(strarray *sa)
Destroy array and contents.
strarray * sa_new(int entries)
Allocate storage for a new array.
bool sa_create_entry(strarray *array, const int index, const size_t len, const char *src)
Create an string in a given position from a character array and length.
Represent a key=value pair.
char * value
Configuration item value.
Configuration file section.
Device specific function information.
device_fn startup
Called serially at startup, opens devices etc.
Internal representation of a Datawell HXV message.
uint8_t status
Error count. 0 or 1 OK, 2+ error.
Configuration is as per simple network sources.
char * sourceName
User defined name for this source.
bool parseSpectrum
Enable parsing of spectral data.
int timeout
Reconnect if no data received after this interval [s].
uint8_t sourceNum
Source ID for messages.
int handle
Handle for currently opened device.
bool recordRaw
Enable retention of raw data.
Internal representation of HXV spectral messages.
uint8_t frequencyBin[4]
Index for each line of spectral data.
float m2[4]
M2 Fourier coefficient for each line.
uint16_t sysword
12 bits of system data
float rpsd[4]
Relative power spectral density for each line.
float K[4]
Check factor for each line.
uint8_t sysseq
System data sequence number.
float spread[4]
Wave spread for each line.
float direction[4]
Direction for each line.
float n2[4]
N2 Fourier coefficient for each line.
Internal representation of HXV system messages.
float Hrms
RMS Wave height.
bool GPSfix
Valid GPS fix available.
float waterTemp
Water Temperature.
float orient
Buoy orientation.
float refTemp
Reference Temperature.
float incl
Buoy inclination.
int opTime
Weeks of battery life remaining.
Logging thread information.
msgqueue * logQ
Main message queue. Pushed to by threads, consumed by main()
char * tag
Tag/source name for messages etc.
void * dParams
Device/Thread specific data.
program_state * pstate
Current program state, used for logging.
int returnCode
Thread return code (output)