RocketLogger  1.1
rl_server.c
Go to the documentation of this file.
1 
31 #include <libgen.h>
32 #include <stdint.h>
33 #include <stdio.h>
34 #include <sys/statvfs.h>
35 
36 #include "rl_lib.h"
37 #include "rl_util.h"
38 #include "sem.h"
39 #include "web.h"
40 
42 #define ARG_COUNT 4
43 #define MAX_STRING_LENGTH 150
45 #define MAX_STRING_VALUE 20
47 #define TIME_MARGIN 10
49 
50 // Global variables
52 int sem_id;
54 struct web_shm* web_data;
55 
57 uint32_t id;
59 uint8_t get_data;
61 uint32_t t_scale;
63 int64_t last_time;
65 int64_t curr_time;
67 int8_t num_channels;
68 
71 
75 
76 // functions
82 int64_t get_free_space(char* path) {
83 
84  struct statvfs stat;
85  statvfs(path, &stat);
86 
87  return (uint64_t)stat.f_bavail * (uint64_t)stat.f_bsize;
88 }
89 
95 void print_json_32(int32_t data[], int length) {
96  char str[MAX_STRING_LENGTH];
97  char val[MAX_STRING_VALUE];
98  int i;
99  sprintf(str, "[\"%d\"", data[0]);
100  for (i = 1; i < length; i++) {
101  sprintf(val, ",\"%d\"", data[i]);
102  strcat(str, val);
103  }
104  strcat(str, "]\n");
105  printf("%s", str);
106 }
107 
113 void print_json_64(int64_t data[], int length) {
114  char str[MAX_STRING_LENGTH];
115  char val[MAX_STRING_VALUE];
116  int i;
117  sprintf(str, "[\"%lld\"", data[0]);
118  for (i = 1; i < length; i++) {
119  sprintf(val, ",\"%lld\"", data[i]);
120  strcat(str, val);
121  }
122  strcat(str, "]\n");
123  printf("%s", str);
124 }
125 
129 void print_status(void) {
130  // STATUS
131  printf("%d\n", status.state);
132  if (status.state != RL_RUNNING) {
134 
135  // read calibration time
136  struct rl_calibration tmp_calibration;
137  rl_read_calibration(&tmp_calibration, &status.conf);
138  status.calibration_time = tmp_calibration.time;
139  }
140  // copy of filename (for dirname)
141  char file_name_copy[MAX_PATH_LENGTH];
142  strcpy(file_name_copy, status.conf.file_name);
143  printf("%llu\n", get_free_space(dirname(file_name_copy)));
144  printf("%llu\n", status.calibration_time);
145 
146  // CONFIG
147  printf("%d\n", status.conf.sample_rate);
148  printf("%d\n", status.conf.update_rate);
149  printf("%d\n", status.conf.digital_inputs);
150  printf("%d\n", status.conf.calibration);
151  printf("%d\n", status.conf.file_format);
152  printf("%s\n", status.conf.file_name);
153  printf("%llu\n", status.conf.max_file_size);
156  printf("%llu\n", status.samples_taken);
157  printf("%d\n", status.conf.enable_web_server);
158 }
159 
163 void print_data(void) {
164 
165  // print data length
166  int buffer_count = (curr_time - last_time + TIME_MARGIN) / 1000;
167 
168  // get available buffers
170  return;
171  }
172  int buffer_available = web_data->buffer[t_scale].filled;
173  set_sem(sem_id, DATA_SEM, 1);
174 
175  if (buffer_count > buffer_available) {
176  buffer_count = buffer_available;
177  }
178 
179  int buffer_size = buffer_sizes[t_scale];
180 
181  // print request id and status
182  printf("%d\n", id);
183  print_status();
184 
185  // data available
186  printf("1\n");
187 
188  // print time scale
189  printf("%d\n", t_scale);
190 
191  // print time
192  printf("%lld\n", curr_time);
193 
194  // print buffer information
195  printf("%d\n", buffer_count);
196  printf("%d\n", buffer_size);
197 
198  // read data
199  int64_t data[buffer_count][buffer_size][num_channels];
200  int i;
201 
203  return;
204  }
205  for (i = 0; i < buffer_count; i++) {
206 
207  // read data buffer
208  int64_t* shm_data = web_buffer_get(&web_data->buffer[t_scale], i);
209  if (web_data->buffer[t_scale].element_size > sizeof(data)) {
210  rl_log(ERROR,
211  "In print_data: memcpy is trying to copy to much data.");
212  break;
213  } else {
214  memcpy(&data[i][0][0], shm_data,
215  web_data->buffer[t_scale].element_size);
216  }
217  }
218  set_sem(sem_id, DATA_SEM, 1);
219 
220  // print data
221  for (i = buffer_count - 1; i >= 0; i--) {
222  int j;
223  for (j = 0; j < buffer_size; j++) {
224  print_json_64(data[i][j], num_channels);
225  }
226  }
227 }
228 
241 int main(int argc, char* argv[]) {
242 
243  // parse arguments
244  if (argc != ARG_COUNT + 1) {
245  rl_log(ERROR, "in rl_server: not enough arguments");
246  exit(FAILURE);
247  }
248  id = atoi(argv[1]);
249  get_data = atoi(argv[2]);
250  t_scale = atoi(argv[3]);
251  last_time = atoll(argv[4]);
252 
253  // check time scale
254  if (t_scale != S1 && t_scale != S10 && t_scale != S100) {
255  rl_log(WARNING, "unknown time scale");
256  t_scale = S1;
257  }
258 
259  // get status
261 
262  // quit, if data not requested or not running or web disabled
264  status.conf.enable_web_server == 0 || get_data == 0) {
265  // print request id and status
266  printf("%d\n", id);
267  print_status();
268  printf("0\n"); // no data available
269  exit(EXIT_SUCCESS);
270  }
271 
272  // open semaphore
274  if (sem_id < 0) {
275  // error already logged
276  exit(EXIT_FAILURE);
277  }
278 
279  // open shared memory
280  web_data = web_open_shm();
281 
282  // fetch data
283  uint8_t data_read = 0;
284  while (data_read == 0) {
285 
286  // get current time
288  exit(EXIT_FAILURE);
289  }
290  curr_time = web_data->time;
291  num_channels = web_data->num_channels;
292  set_sem(sem_id, DATA_SEM, 1);
293 
294  if (curr_time > last_time) {
295 
296  // re-read status
298 
299  // read and print data
300  print_data();
301 
302  data_read = 1;
303  } else {
304 
305  if (last_time > curr_time) {
306  // assume outdated time stamp
307  last_time = 0;
308  }
309 
310  // wait on new data
311  if (data_read == 0) {
313  // time-out or error -> stop
314  break;
315  }
316  }
317  }
318  }
319 
320  // unmap shared memory
321  shmdt(web_data);
322 
323  exit(EXIT_SUCCESS);
324 }
void print_data(void)
Definition: rl_server.c:163
int force_high_channels[NUM_I_CHANNELS]
Current channels to force to high range.
Definition: types.h:262
int open_sem(key_t key, int num_sems)
Definition: sem.c:71
struct ringbuffer buffer[WEB_RING_BUFFER_COUNT]
Array of ring buffers for different time scales.
Definition: web.h:100
#define FAILURE
Definition: types.h:77
#define SUCCESS
Definition: types.h:74
1 samples/s
Definition: web.h:55
struct rl_status status
Current status of RocketLogger.
Definition: rl_server.c:70
struct web_shm * web_open_shm(void)
Definition: web.c:72
int main(int argc, char *argv[])
Definition: rl_server.c:241
#define BUFFER1_SIZE
Size of 1s/div buffer.
Definition: web.h:59
#define NUM_SEMS
Number of semaphores in set.
Definition: types.h:313
#define WAIT_SEM
Definition: types.h:325
uint8_t get_data
1: data requested, 0: no data requested
Definition: rl_server.c:59
void rl_log(rl_log_type type, const char *format,...)
Definition: log.c:38
#define SEM_KEY
Semaphore key (used for set creation)
Definition: types.h:311
#define BUFFER10_SIZE
Size of 10s/div buffer.
Definition: web.h:61
int set_sem(int sem_id, int sem_num, int val)
Definition: sem.c:123
uint32_t num_channels
Number of channels sampled.
Definition: web.h:98
int wait_sem(int sem_id, int sem_num, int time_out)
Definition: sem.c:87
int digital_inputs
En-/disable digital inputs.
Definition: types.h:264
#define MAX_PATH_LENGTH
Maximum path length in characters.
Definition: types.h:101
100 sample/s
Definition: web.h:53
int enable_web_server
En-/disable plots on web interface.
Definition: types.h:266
rl_use_cal calibration
Use/ignore existing calibration.
Definition: types.h:268
int sem_id
ID of semaphore set.
Definition: rl_server.c:52
#define MAX_STRING_VALUE
Maximum string value length.
Definition: rl_server.c:46
#define DATA_SEM
Number of data semaphore in set (manages access to shared memory data)
Definition: types.h:322
#define TIME_MARGIN
Time margin for buffer number (in ms)
Definition: rl_server.c:48
rl_state state
State.
Definition: types.h:284
uint64_t samples_taken
Number of samples taken.
Definition: types.h:288
int read_default_config(struct rl_conf *conf)
Definition: rl_util.c:686
struct web_shm * web_data
Pointer to shared memory data.
Definition: rl_server.c:54
#define NUM_I_CHANNELS
Maximum number of RocketLogger current channels.
Definition: types.h:105
uint32_t t_scale
Requested time scale.
Definition: rl_server.c:61
uint32_t filled
Number of elements in buffer.
Definition: web.h:84
#define NUM_CHANNELS
Maximum number of RocketLogger channels.
Definition: types.h:103
int64_t curr_time
Time stamp of last buffer stored to shared memory.
Definition: rl_server.c:65
Warning.
Definition: types.h:200
#define BUFFER100_SIZE
Size of 100s/div buffer.
Definition: web.h:63
char file_name[MAX_PATH_LENGTH]
Data file name.
Definition: types.h:274
10 samples/s
Definition: web.h:54
Running.
Definition: types.h:141
int channels[NUM_CHANNELS]
Channels to sample.
Definition: types.h:260
uint64_t time
Time stamp of calibration run.
Definition: types.h:302
int64_t time
Time stamp of most recent datum (in UNIX time, UTC)
Definition: web.h:96
uint64_t calibration_time
Time stamp of last calibration run.
Definition: types.h:294
int64_t last_time
Last client time stamp.
Definition: rl_server.c:63
int64_t get_free_space(char *path)
Definition: rl_server.c:82
#define SEM_TIME_OUT
Time out time in seconds, waiting on semaphore read.
Definition: types.h:315
void rl_read_calibration(struct rl_calibration *calibration_ptr, struct rl_conf *conf)
Definition: rl_lib.c:78
rl_file_format file_format
File format.
Definition: types.h:270
#define WEB_RING_BUFFER_COUNT
Number of ring buffers in shared memory.
Definition: web.h:41
int update_rate
Data update rate.
Definition: types.h:256
Definition: web.h:94
Error.
Definition: types.h:199
struct rl_conf conf
Current configuration.
Definition: types.h:292
uint32_t element_size
Size of buffer element.
Definition: web.h:80
int sample_rate
Sampling rate.
Definition: types.h:252
#define ARG_COUNT
Number of input arguments required.
Definition: rl_server.c:42
uint32_t id
Client request id.
Definition: rl_server.c:57
int buffer_sizes[WEB_RING_BUFFER_COUNT]
Buffer sizes for different time scales.
Definition: rl_server.c:73
Not sampling.
Definition: types.h:149
uint64_t max_file_size
Maximum data file size.
Definition: types.h:272
rl_sampling sampling
Sampling state.
Definition: types.h:286
int64_t * web_buffer_get(struct ringbuffer *buffer, int num)
Definition: web.c:128
int8_t num_channels
Number of channels sampled.
Definition: rl_server.c:67
void print_json_32(int32_t data[], int length)
Definition: rl_server.c:95
void print_json_64(int64_t data[], int length)
Definition: rl_server.c:113
int rl_read_status(struct rl_status *status)
Definition: rl_lib.c:59
#define MAX_STRING_LENGTH
Maximum string line length.
Definition: rl_server.c:44
void print_status(void)
Definition: rl_server.c:129