nmxp_chan.c 14.7 KB
Newer Older
1
2
/*! \file
 *
Matteo Quintiliani's avatar
Matteo Quintiliani committed
3
 * \brief Channels for Nanometrics Protocol Library
4
5
6
7
8
9
 *
 * Author:
 * 	Matteo Quintiliani
 * 	Istituto Nazionale di Geofisica e Vulcanologia - Italy
 *	quintiliani@ingv.it
 *
10
 * $Id: nmxp_chan.c,v 1.31 2008-02-24 15:10:52 mtheo Exp $
Matteo Quintiliani's avatar
Matteo Quintiliani committed
11
 *
12
13
14
 */

#include "nmxp_chan.h"
Matteo Quintiliani's avatar
Matteo Quintiliani committed
15
#include "nmxp_base.h"
16
17

#include <string.h>
18
#include <stdlib.h>
19

20
int nmxp_chan_cpy_sta_chan(const char *net_dot_station_dot_channel, char *station_code, char *channel_code, char *network_code) {
21
    int ret = 0;
22
23
24
25
26
27
    int errors = 0;
    int i;
    char *period1 = NULL, *period2 = NULL;
    char *tmp_name = NULL;

    if(net_dot_station_dot_channel || station_code || channel_code || network_code) {
28
29
30

	station_code[0] = 0;
	channel_code[0] = 0;
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
	network_code[0] = 0;

	tmp_name = strdup(net_dot_station_dot_channel);
	/* count '.' */
	i=0;
	while(i < strlen(tmp_name)  && !errors) {
	    if(tmp_name[i] == '.') {
		if(!period1) {
		    period1 = tmp_name+i;
		} else if(!period2) {
		    period2 = tmp_name+i;
		} else {
		    errors++;
		}
	    }
	    i++;
	}
	if(!errors && period1) {
	    ret = 1;
	    if(period2) {
		/* NET.STA.CHAN */
		*period1++ = '\0';
		*period2++ = '\0';
		strcpy(network_code, tmp_name);
		strcpy(station_code, period1);
		strcpy(channel_code, period2);
57
	    } else {
58
59
60
61
		/* STA.CHAN */
		*period1++ = '\0';
		strcpy(station_code, tmp_name);
		strcpy(channel_code, period1);
62
	    }
63
	} else {
64
	    nmxp_log(NMXP_LOG_ERR, NMXP_LOG_D_CHANNEL, "Name %s is not in NET.STA.CHAN format! (NET. is optional)\n", net_dot_station_dot_channel);
65
66
67
68
	}

	if(tmp_name) {
	    free(tmp_name);
69
	}
70

71
    } else {
72
	nmxp_log(NMXP_LOG_ERR, NMXP_LOG_D_CHANNEL, "Some parameter is NULL in nmxp_chan_cpy_sta_chan().\n",  net_dot_station_dot_channel);
73
74
75
76
77
78
    }

    return ret;
}


79

80
81
82
83
84
85
/*
 * Match string against the extended regular expression in
 * pattern, treating errors as no match.
 *
 * return 1 for match, 0 for no match, -1 on error for invalid pattern, -2 on error for invalid station_dot_channel
 */
86
int nmxp_chan_match(const char *net_dot_station_dot_channel, char *pattern)
87
88
89
90
{
    int ret = 0;
    int i, l;
    char sta_pattern[20];
91
    char cha_pattern[20];
92
    char net_pattern[20];
93
94
95
96
    char sta_sdc[20];
    char *cha_sdc;

    /* validate pattern channel */
97
    if(!nmxp_chan_cpy_sta_chan(pattern, sta_pattern, cha_pattern, net_pattern)) {
98
	nmxp_log(NMXP_LOG_ERR, NMXP_LOG_D_CHANNEL, "Channel pattern %s is not in STA.CHAN format!\n", pattern);
99
100
101
	return -1;
    }

102
103
104
105
106
107
108
109
110
    l = strlen(net_pattern);
    i = 0;
    while(i < l  &&  ret != -1) {
	if(  !(
		(net_pattern[i] >= 'A'  &&  net_pattern[i] <= 'Z')
		|| (net_pattern[i] >= 'a'  &&  net_pattern[i] <= 'z')
		|| (net_pattern[i] >= '0'  &&  net_pattern[i] <= '9')
		)
	  ) {
111
	    nmxp_log(NMXP_LOG_ERR, NMXP_LOG_D_CHANNEL, "Channel pattern %s has not valid NET format!\n", pattern);
112
113
114
115
116
	    return -1;
	}
	i++;
    }
    
117
    l = strlen(sta_pattern);
118
119
120
    if(((l == 1) && sta_pattern[0] == '*')) {
	/* do nothing */
    } else {
121
122
123
124
125
126
127
128
129
    i = 0;
    while(i < l  &&  ret != -1) {
	if(  !(
		(sta_pattern[i] >= 'A'  &&  sta_pattern[i] <= 'Z')
		|| (sta_pattern[i] >= 'a'  &&  sta_pattern[i] <= 'z')
		|| (sta_pattern[i] >= '0'  &&  sta_pattern[i] <= '9')
		|| (sta_pattern[i] == '_' )
	     )
	  ) {
130
	    nmxp_log(NMXP_LOG_ERR, NMXP_LOG_D_CHANNEL, "Channel pattern %s has not valid STA format!\n", pattern);
131
132
133
134
	    return -1;
	}
	i++;
    }
135
    }
136
137
138
    
    l = strlen(cha_pattern);
    if(l != 3) {
139
	nmxp_log(NMXP_LOG_ERR, NMXP_LOG_D_CHANNEL, "Channel pattern %s has not valid CHAN format!\n", pattern);
140
141
142
143
144
145
146
147
148
149
150
	return -1;
    }
    i = 0;
    while(i < l  &&  ret != -1) {
	if(  !(
		    (cha_pattern[i] >= 'A'  &&  cha_pattern[i] <= 'Z')
		    || (cha_pattern[i] >= 'a'  &&  cha_pattern[i] <= 'z')
		    || (cha_pattern[i] == '_' )
		    || (cha_pattern[i] == '?' )
	      )
	  ) {
151
	    nmxp_log(NMXP_LOG_ERR, NMXP_LOG_D_CHANNEL, "Channel pattern %s has not valid CHAN format!\n", pattern);
152
153
154
155
156
	    return -1;
	}
	i++;
    }

157
    strcpy(sta_sdc, net_dot_station_dot_channel);
158
    if( (cha_sdc = strchr(sta_sdc, '.')) == NULL ) {
159
	nmxp_log(NMXP_LOG_ERR, NMXP_LOG_D_CHANNEL, "Channel %s is not in STA.CHAN format!\n", net_dot_station_dot_channel);
160
161
162
163
164
165
166
	return -2;
    }
    if(cha_sdc) {
	*cha_sdc++ = '\0';
    }
    l = strlen(cha_sdc);
    if(l != 3) {
167
	nmxp_log(NMXP_LOG_ERR, NMXP_LOG_D_CHANNEL, "Channel %s has not valid CHAN format!\n", pattern);
168
169
170
	return -1;
    }

171
172
173
    l = strlen(sta_pattern);
    if ( (strcasecmp(sta_sdc, sta_pattern) == 0) 
	    || ((l == 1) && sta_pattern[0] == '*')) {
174
175
176
177
178
179
180
181
182
183
184
185
186
187
	/* matching CHAN */
	ret = 1;
	i = 0;
	while(i < 3  &&  ret != 0) {
	    ret = ((cha_pattern[i] == '?')? 1 : (cha_pattern[i] == cha_sdc[i]));
	    i++;
	}
    }


    return ret;
}


Matteo Quintiliani's avatar
Matteo Quintiliani committed
188
int nmxp_chan_lookupKey(char* name, NMXP_CHAN_LIST *channelList)
189
{
190
191
    int chan_number = channelList->number;
    int i_chan = 0;
192

193
    for (i_chan = 0; i_chan < chan_number; i_chan++)
194
    {
195
196
	if (strcasecmp(name, channelList->channel[i_chan].name) == 0)
	    return channelList->channel[i_chan].key;
197
198
199
200
201
    }

    return -1;
}

202

203
int nmxp_chan_lookupKeyIndex(int32_t key, NMXP_CHAN_LIST_NET *channelList)
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
{
    int i_chan = 0;
    int ret = -1;

    i_chan = 0;
    while(i_chan < channelList->number  &&  ret == -1)
    {
	if ( key == channelList->channel[i_chan].key ) {
	    ret = i_chan;
	}
	i_chan++;
    }

    return ret;
}


221
char *nmxp_chan_lookupName(int32_t key, NMXP_CHAN_LIST_NET *channelList)
222
{
223
    int i_chan = 0;
224
    static char ret[12];
225

226
227
228
    ret[0] = 0;

    for (i_chan = 0; i_chan < channelList->number; i_chan++)
229
    {
230
	if ( key == channelList->channel[i_chan].key ) {
231
	    strcpy(ret, channelList->channel[i_chan].name);
232
	}
233
234
    }

235
    if(ret[0] == 0) {
236
	nmxp_log(NMXP_LOG_ERR, NMXP_LOG_D_CHANNEL, "Key %d not found!\n", key);
237
238
239
240
	return NULL;
    } else {
	return ret;
    }
241
242
}

243

Matteo Quintiliani's avatar
Matteo Quintiliani committed
244
NMXP_CHAN_LIST *nmxp_chan_getType(NMXP_CHAN_LIST *channelList, NMXP_DATATYPE dataType) {
245
246
247
248
249
250
251
252
253
254
    NMXP_CHAN_LIST *ret_channelList = NULL;

    int chan_number = channelList->number;
    int i_chan = 0;

    ret_channelList = (NMXP_CHAN_LIST *) malloc(sizeof(NMXP_CHAN_LIST));
    ret_channelList->number = 0;

    for (i_chan = 0; i_chan < chan_number; i_chan++)
    {
255
	if ( getDataTypeFromKey(channelList->channel[i_chan].key) == dataType) {
256
257
258
259
260
261
262
263
264
	    ret_channelList->channel[ret_channelList->number].key = channelList->channel[i_chan].key;
	    strcpy(ret_channelList->channel[ret_channelList->number].name, channelList->channel[i_chan].name);
	    ret_channelList->number++;
	}
    }

    return ret_channelList;
}

265

266
267
NMXP_CHAN_LIST_NET *nmxp_chan_subset(NMXP_CHAN_LIST *channelList, NMXP_DATATYPE dataType, char *sta_chan_list, const char *network_code_default) {
    NMXP_CHAN_LIST_NET *ret_channelList = NULL;
268
    int istalist, ista;
269
270
    char sta_chan_code_pattern[100];
    int i_chan, ret_match;
271
272
273
    char network_code[20];
    char station_code[20];
    char channel_code[20];
274

275
    ret_channelList = (NMXP_CHAN_LIST_NET *) malloc(sizeof(NMXP_CHAN_LIST_NET));
276
277
    ret_channelList->number = 0;

278
279
280
281
    istalist = 0;
    while(sta_chan_list[istalist] != sep_chan_list  &&  sta_chan_list[istalist] != 0) {
	ista = 0;
	while(sta_chan_list[istalist] != sep_chan_list  &&  sta_chan_list[istalist] != 0) {
282
	    sta_chan_code_pattern[ista++] = sta_chan_list[istalist++];
283
	}
284
	sta_chan_code_pattern[ista] = 0;
285
286
287
	if(sta_chan_list[istalist] == sep_chan_list) {
	    istalist++;
	}
288
289
290
291
	ret_match = 1;
	i_chan = 0;
	while(i_chan < channelList->number  &&  ret_match != -1) {
	    ret_match = nmxp_chan_match(channelList->channel[i_chan].name, sta_chan_code_pattern);
292
	    if(ret_match == 1) {
293
294
295
		    if(i_chan != -1  && getDataTypeFromKey(channelList->channel[i_chan].key) == dataType) {
			ret_channelList->channel[ret_channelList->number].key =        channelList->channel[i_chan].key;
			strcpy(ret_channelList->channel[ret_channelList->number].name, channelList->channel[i_chan].name);
296
297
298
			nmxp_chan_cpy_sta_chan(sta_chan_code_pattern, station_code, channel_code, network_code);
			sprintf(ret_channelList->channel[ret_channelList->number].name, "%s.%s",
				(network_code[0] != 0)? network_code : network_code_default, channelList->channel[i_chan].name);
299
300
301
302
			ret_channelList->number++;
		    }
	    }
	    i_chan++;
303
304
	}
    }
305
    
306
307
308
309
    return ret_channelList;
}


310
/* Comparison Key Function*/
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
int chan_key_compare(const void *a, const void *b)
{
    int ret = 0;
    NMXP_CHAN_KEY *pa = (NMXP_CHAN_KEY *) a; 
    NMXP_CHAN_KEY *pb = (NMXP_CHAN_KEY *) b;

    if(pa->key > pb->key) {
	ret = 1;
    } else if(pa->key < pb->key) {
	ret = -1;
    }
    return ret;
}

void nmxp_chan_sortByKey(NMXP_CHAN_LIST *channelList) {
    qsort (channelList->channel, channelList->number, sizeof (NMXP_CHAN_KEY), chan_key_compare);
}

329
/* Comparison Name Function*/
330
331
332
333
334
335
336
337
338
339
340
341
int chan_name_compare(const void *a, const void *b)
{
    NMXP_CHAN_KEY *pa = (NMXP_CHAN_KEY *) a; 
    NMXP_CHAN_KEY *pb = (NMXP_CHAN_KEY *) b;

    return strcmp(pa->name, pb->name);
}

void nmxp_chan_sortByName(NMXP_CHAN_LIST *channelList) {
    qsort (channelList->channel, channelList->number, sizeof (NMXP_CHAN_KEY), chan_name_compare);
}

342
343
344
345
346

void nmxp_chan_print_channelList(NMXP_CHAN_LIST *channelList) {
    int chan_number = channelList->number;
    int i_chan = 0;

347
    nmxp_log(NMXP_LOG_NORM_NO, NMXP_LOG_D_CHANNEL, "%04d channels:\n", chan_number);
348
349
350

    for (i_chan = 0; i_chan < chan_number; i_chan++)
    {
351
352
353
354
355
356
	nmxp_log(NMXP_LOG_NORM_NO, NMXP_LOG_D_ANY, "%04d %12d %6s%c%-11s\n",
		i_chan+1,
		channelList->channel[i_chan].key,
		"    ",
		' ',
		channelList->channel[i_chan].name);
357
358
359
360
361
    }

}

void nmxp_chan_print_netchannelList(NMXP_CHAN_LIST_NET *channelList) {
362
363
364
    int chan_number = channelList->number;
    int i_chan = 0;

365
    nmxp_log(NMXP_LOG_NORM, NMXP_LOG_D_CHANNEL, "%04d channels:\n", chan_number);
366
367
368

    for (i_chan = 0; i_chan < chan_number; i_chan++)
    {
369
	nmxp_log(NMXP_LOG_NORM, NMXP_LOG_D_CHANNEL, "%04d %12d %s\n", i_chan+1, channelList->channel[i_chan].key, channelList->channel[i_chan].name);
370
371
372
373
    }

}

Matteo Quintiliani's avatar
Matteo Quintiliani committed
374
375
376
377
378

void nmxp_meta_chan_free(NMXP_META_CHAN_LIST **chan_list) {
    NMXP_META_CHAN_LIST *iter = *chan_list;
    NMXP_META_CHAN_LIST *iter_next = NULL;

379
    nmxp_log(NMXP_LOG_NORM, NMXP_LOG_D_CHANNEL, "nmxp_meta_chan_free()\n");
Matteo Quintiliani's avatar
Matteo Quintiliani committed
380
381
382
383
384
385
386
387
388
389
390
391
392

    if(iter) {
	iter_next = iter->next;
	while(iter) {
	    free(iter);
	    iter = iter_next;
	    iter_next = iter->next;
	}
	*chan_list = NULL;
    }

}

393
int nmxp_meta_chan_compare(NMXP_META_CHAN_LIST *item1, NMXP_META_CHAN_LIST *item2, NMXP_META_CHAN_LIST_SORT_TYPE sorttype) {
394
    int ret = 0;
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
    switch(sorttype) {
	case NMXP_META_SORT_KEY:
	    if(item1->key > item2->key) {
		ret = 1;
	    } else if(item1->key < item2->key) {
		ret = -1;
	    }
	    break;
	case NMXP_META_SORT_NAME:
	    ret = strcmp(item1->name, item2->name);
	    break;
	case NMXP_META_SORT_START_TIME:
	    if(item1->start_time > item2->start_time) {
		ret = 1;
	    } else if(item1->start_time < item2->start_time) {
		ret = -1;
	    }
	    break;
	case NMXP_META_SORT_END_TIME:
	    if(item1->end_time > item2->end_time) {
		ret = 1;
	    } else if(item1->end_time < item2->end_time) {
		ret = -1;
	    }
	    break;
	default:
421
	    nmxp_log(NMXP_LOG_ERR, NMXP_LOG_D_CHANNEL, "Sort type %d not defined!\n", sorttype);
422
	    break;
423
424
425
426
    }
    return ret;
}

427
NMXP_META_CHAN_LIST *nmxp_meta_chan_add(NMXP_META_CHAN_LIST **chan_list, int32_t key, char *name, int32_t start_time, int32_t end_time, char *network, NMXP_META_CHAN_LIST_SORT_TYPE sorttype) {
Matteo Quintiliani's avatar
Matteo Quintiliani committed
428
429
430
    NMXP_META_CHAN_LIST *iter = NULL;
    NMXP_META_CHAN_LIST *new_item = NULL;

Matteo Quintiliani's avatar
Matteo Quintiliani committed
431
    /* nmxp_log(NMXP_LOG_NORM, NMXP_LOG_D_CHANNEL, "nmxp_meta_chan_add(%d, %d, %s, %d, %d, %s, %d)\n", *chan_list, key, name, start_time, end_time, network, sorttype); */
432
433

    if(sorttype != NMXP_META_SORT_KEY  &&  sorttype != NMXP_META_SORT_NAME) {
434
	nmxp_log(NMXP_LOG_ERR, NMXP_LOG_D_CHANNEL, "nmxp_meta_chan_add() can only accept NMXP_META_SORT_KEY or NMXP_META_SORT_NAME. Fixed NMXP_META_SORT_KEY!\n");
435
436
	sorttype = NMXP_META_SORT_KEY;
    }
Matteo Quintiliani's avatar
Matteo Quintiliani committed
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458

    new_item = (NMXP_META_CHAN_LIST *) malloc(sizeof(NMXP_META_CHAN_LIST));
    new_item->key = 0;
    new_item->name[0] = 0;
    new_item->start_time = 0;
    new_item->end_time = 0;
    new_item->network[0] = 0;
    new_item->next = NULL;
    new_item->key = key;
    if(name) {
	strncpy(new_item->name, name, 12);
    }
    new_item->start_time = start_time;
    new_item->end_time = end_time;
    if(network) {
	strncpy(new_item->network, network, 12);
    }


    if(*chan_list == NULL) {
	*chan_list = new_item;
    } else {
459
	if(nmxp_meta_chan_compare(new_item, *chan_list, sorttype) < 0) {
Matteo Quintiliani's avatar
Matteo Quintiliani committed
460
461
462
	    new_item->next = *chan_list;
	    *chan_list = new_item;
	} else {
463
	    for(iter = *chan_list; iter->next != NULL  && nmxp_meta_chan_compare(new_item, iter->next, sorttype) > 0; iter = iter->next) {
Matteo Quintiliani's avatar
Matteo Quintiliani committed
464
465
466
467
468
469
470
471
472
473
474
475
476
	    }
	    new_item->next = iter->next;
	    iter->next = new_item;
	}
    }

    return new_item;
}

NMXP_META_CHAN_LIST *nmxp_meta_chan_search_key(NMXP_META_CHAN_LIST *chan_list, int32_t key) {
    NMXP_META_CHAN_LIST *iter = chan_list;
    int found = 0;

Matteo Quintiliani's avatar
Matteo Quintiliani committed
477
    /* nmxp_log(NMXP_LOG_NORM, NMXP_LOG_D_CHANNEL, "nmxp_meta_chan_search_key()\n"); */
Matteo Quintiliani's avatar
Matteo Quintiliani committed
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492

    while(iter != NULL  &&  !found) {
	if(iter->key == key) {
	    found = 1;
	} else {
	    iter = iter->next;
	}
    }

    return iter;
}

NMXP_META_CHAN_LIST *nmxp_meta_chan_set_name(NMXP_META_CHAN_LIST *chan_list, int32_t key, char *name) {
    NMXP_META_CHAN_LIST *ret = NULL;

493
    nmxp_log(NMXP_LOG_NORM_NO, NMXP_LOG_D_CHANNEL, "nmxp_meta_chan_set_name()\n");
Matteo Quintiliani's avatar
Matteo Quintiliani committed
494
495
496
497
498
499
500
501
502
503
504

    if( (ret = nmxp_meta_chan_search_key(chan_list, key)) ) {
	strncpy(ret->name, name, 12);
    }

    return ret;
}

NMXP_META_CHAN_LIST *nmxp_meta_chan_set_times(NMXP_META_CHAN_LIST *chan_list, int32_t key, int32_t start_time, int32_t end_time) {
    NMXP_META_CHAN_LIST *ret = NULL;

Matteo Quintiliani's avatar
Matteo Quintiliani committed
505
    /* nmxp_log(NMXP_LOG_NORM, NMXP_LOG_D_CHANNEL, "nmxp_meta_chan_set_times()\n"); */
Matteo Quintiliani's avatar
Matteo Quintiliani committed
506
507
508
509
510
511
512
513
514
515
516
517

    if( (ret = nmxp_meta_chan_search_key(chan_list, key)) ) {
	ret->start_time = start_time;
	ret->end_time = end_time;
    }

    return ret;
}

NMXP_META_CHAN_LIST *nmxp_meta_chan_set_network(NMXP_META_CHAN_LIST *chan_list, int32_t key, char *network) {
    NMXP_META_CHAN_LIST *ret = NULL;

518
    nmxp_log(NMXP_LOG_NORM, NMXP_LOG_D_CHANNEL, "nmxp_meta_chan_set_network()\n");
Matteo Quintiliani's avatar
Matteo Quintiliani committed
519
520
521
522
523
524
525
526
527
528
529
530
531

    if( (ret = nmxp_meta_chan_search_key(chan_list, key)) ) {
	strncpy(ret->network, network, 12);
    }

    return ret;
}

void nmxp_meta_chan_print(NMXP_META_CHAN_LIST *chan_list) {
    NMXP_META_CHAN_LIST *iter = chan_list;
    char str_start_time[200], str_end_time[200];
    str_start_time[0] = 0;
    str_end_time[0] = 0;
532
    int i_chan = 0;
Matteo Quintiliani's avatar
Matteo Quintiliani committed
533

534
    nmxp_log(NMXP_LOG_NORM, NMXP_LOG_D_CHANNEL, "nmxp_meta_chan_print()\n");
Matteo Quintiliani's avatar
Matteo Quintiliani committed
535
536
537
538
539

    while(iter != NULL) {
	nmxp_data_to_str(str_start_time, iter->start_time);
	nmxp_data_to_str(str_end_time,   iter->end_time);

540
541
	nmxp_log(NMXP_LOG_NORM_NO, NMXP_LOG_D_ANY, "%04d %12d %6s%c%-11s (%s  -  %s)\n",
		i_chan+1,
Matteo Quintiliani's avatar
Matteo Quintiliani committed
542
543
		iter->key,
		iter->network,
544
545
		(strcmp(iter->network, "")==0)? ' ' : '.',
		iter->name,
Matteo Quintiliani's avatar
Matteo Quintiliani committed
546
547
548
549
		str_start_time,
		str_end_time
		);
	iter = iter->next;
550
	i_chan++;
Matteo Quintiliani's avatar
Matteo Quintiliani committed
551
552
553
554
555
    }
}