1 /*****************************************************************************\
5 **---------------------------------------------------------------------------**
6 ** Copyright: Andreas Eversberg **
8 ** reading interface.conf file and filling structure **
10 \*****************************************************************************/
14 struct interface *interface_first = NULL; /* first interface is current list */
15 struct interface *interface_newlist = NULL; /* first interface in new list */
19 /* set default out_channel */
20 void default_out_channel(struct interface_port *ifport)
22 struct select_channel *selchannel, **selchannelp;
24 selchannel = (struct select_channel *)MALLOC(sizeof(struct select_channel));
27 if (ifport->mISDNport->ntmode)
28 selchannel->channel = CHANNEL_FREE;
30 selchannel->channel = CHANNEL_ANY;
32 ifport->out_channel = selchannel;
34 /* additional channel selection for multipoint NT ports */
35 if (!ifport->mISDNport->ptp && ifport->mISDNport->ntmode) {
36 selchannelp = &(selchannel->next);
37 selchannel = (struct select_channel *)MALLOC(sizeof(struct select_channel));
39 selchannel->channel = CHANNEL_NO; // call waiting
40 *selchannelp = selchannel;
45 /* set default in_channel */
46 void default_in_channel(struct interface_port *ifport)
48 struct select_channel *selchannel;
50 selchannel = (struct select_channel *)MALLOC(sizeof(struct select_channel));
53 selchannel->channel = CHANNEL_FREE;
55 ifport->in_channel = selchannel;
60 /* parse string for a positive number */
61 static int get_number(char *value)
68 SPRINT(text, "%d", val);
70 if (!strcmp(value, text))
77 /* remove element from buffer
78 * and return pointer to next element in buffer */
79 static char *get_seperated(char *buffer)
82 if (*buffer==',' || *buffer<=32) { /* seperate */
84 while((*buffer>'\0' && *buffer<=32) || *buffer==',')
94 * parameter processing
96 static int inter_block(struct interface *interface, char *filename, int line, char *parameter, char *value)
98 struct interface_port *ifport;
100 /* port in chain ? */
101 if (!interface->ifport) {
102 SPRINT(interface_error, "Error in %s (line %d): parameter '%s' expects previous 'port' definition.\n", filename, line, parameter);
105 /* goto end of chain */
106 ifport = interface->ifport;
108 ifport = ifport->next;
111 SPRINT(interface_error, "Error in %s (line %d): parameter '%s' expects no value.\n", filename, line, parameter);
117 static int inter_extension(struct interface *interface, char *filename, int line, char *parameter, char *value)
119 if (interface->external) {
120 SPRINT(interface_error, "Error in %s (line %d): parameter '%s' not allowed, because interface is external interface.\n", filename, line, parameter);
124 SPRINT(interface_error, "Error in %s (line %d): parameter '%s' expects no value.\n", filename, line, parameter);
127 interface->extension = 1;
130 static int inter_extern(struct interface *interface, char *filename, int line, char *parameter, char *value)
132 if (interface->extension) {
133 SPRINT(interface_error, "Error in %s (line %d): parameter '%s' not allowed, because interface is an extension.\n", filename, line, parameter);
137 SPRINT(interface_error, "Error in %s (line %d): parameter '%s' expects no value.\n", filename, line, parameter);
140 interface->external = 1;
143 static int inter_ptp(struct interface *interface, char *filename, int line, char *parameter, char *value)
145 struct interface_port *ifport;
147 /* port in chain ? */
148 if (!interface->ifport) {
149 SPRINT(interface_error, "Error in %s (line %d): parameter '%s' expects previous 'port' definition.\n", filename, line, parameter);
152 if (interface->ifport->ptmp) {
153 SPRINT(interface_error, "Error in %s (line %d): parameter '%s' previously ptmp was given.\n", filename, line, parameter);
156 /* goto end of chain */
157 ifport = interface->ifport;
159 ifport = ifport->next;
162 SPRINT(interface_error, "Error in %s (line %d): parameter '%s' expects no value.\n", filename, line, parameter);
169 static int inter_ptmp(struct interface *interface, char *filename, int line, char *parameter, char *value)
171 struct interface_port *ifport;
173 /* port in chain ? */
174 if (!interface->ifport) {
175 SPRINT(interface_error, "Error in %s (line %d): parameter '%s' expects previous 'port' definition.\n", filename, line, parameter);
178 if (interface->ifport->ptp) {
179 SPRINT(interface_error, "Error in %s (line %d): parameter '%s' previously ptp was given.\n", filename, line, parameter);
182 /* goto end of chain */
183 ifport = interface->ifport;
185 ifport = ifport->next;
188 SPRINT(interface_error, "Error in %s (line %d): parameter '%s' expects no value.\n", filename, line, parameter);
195 static int inter_nt(struct interface *interface, char *filename, int line, char *parameter, char *value)
197 struct interface_port *ifport;
199 /* port in chain ? */
200 if (!interface->ifport) {
201 SPRINT(interface_error, "Error in %s (line %d): parameter '%s' expects previous 'port' definition.\n", filename, line, parameter);
204 /* goto end of chain */
205 ifport = interface->ifport;
207 ifport = ifport->next;
210 SPRINT(interface_error, "Error in %s (line %d): parameter '%s' expects no value.\n", filename, line, parameter);
216 static int inter_tespecial(struct interface *interface, char *filename, int line, char *parameter, char *value)
218 struct interface_port *ifport;
220 /* port in chain ? */
221 if (!interface->ifport) {
222 SPRINT(interface_error, "Error in %s (line %d): parameter '%s' expects previous 'port' definition.\n", filename, line, parameter);
225 /* goto end of chain */
226 ifport = interface->ifport;
228 ifport = ifport->next;
231 SPRINT(interface_error, "Error in %s (line %d): parameter '%s' expects no value.\n", filename, line, parameter);
234 ifport->tespecial = 1;
237 static int inter_tones(struct interface *interface, char *filename, int line, char *parameter, char *value)
239 if (!strcasecmp(value, "yes")) {
240 interface->is_tones = IS_YES;
242 if (!strcasecmp(value, "no")) {
243 interface->is_tones = IS_NO;
245 SPRINT(interface_error, "Error in %s (line %d): parameter '%s' expects value 'yes' or 'no'.\n", filename, line, parameter);
250 static int inter_earlyb(struct interface *interface, char *filename, int line, char *parameter, char *value)
252 if (!strcasecmp(value, "yes")) {
253 interface->is_earlyb = IS_YES;
255 if (!strcasecmp(value, "no")) {
256 interface->is_earlyb = IS_NO;
258 SPRINT(interface_error, "Error in %s (line %d): parameter '%s' expects value 'yes' or 'no'.\n", filename, line, parameter);
263 static int inter_hunt(struct interface *interface, char *filename, int line, char *parameter, char *value)
265 if (!strcasecmp(value, "linear")) {
266 interface->hunt = HUNT_LINEAR;
268 if (!strcasecmp(value, "roundrobin")) {
269 interface->hunt = HUNT_ROUNDROBIN;
271 SPRINT(interface_error, "Error in %s (line %d): parameter '%s' expects value 'linear' or 'roundrobin'.\n", filename, line, parameter);
276 static int inter_port(struct interface *interface, char *filename, int line, char *parameter, char *value)
278 SPRINT(interface_error, "Error in %s (line %d): parameter '%s' is outdated.\nPlease use 'portnum' and decrease port number by 1! Ports are counted from 0 now.\n", filename, line, parameter);
281 static int inter_portnum(struct interface *interface, char *filename, int line, char *parameter, char *value)
284 SPRINT(interface_error, "Error in %s (line %d): mISDN support is not compiled in.\n", filename, line);
287 struct interface_port *ifport, **ifportp;
288 struct interface *searchif;
291 val = get_number(value);
293 SPRINT(interface_error, "Error in %s (line %d): parameter '%s' expects one numeric value.\n", filename, line, parameter);
296 /* check for port already assigned */
297 searchif = interface_newlist;
299 ifport = searchif->ifport;
301 if (ifport->portnum == val) {
302 SPRINT(interface_error, "Error in %s (line %d): port '%d' already used above.\n", filename, line, val);
305 ifport = ifport->next;
307 searchif = searchif->next;
309 /* alloc port substructure */
310 ifport = (struct interface_port *)MALLOC(sizeof(struct interface_port));
312 ifport->interface = interface;
314 ifport->portnum = val;
316 ifportp = &interface->ifport;
318 ifportp = &((*ifportp)->next);
323 static int inter_portname(struct interface *interface, char *filename, int line, char *parameter, char *value)
326 SPRINT(interface_error, "Error in %s (line %d): mISDN support is not compiled in.\n", filename, line);
329 struct interface_port *ifport, **ifportp;
331 /* goto end of chain */
332 ifport = interface->ifport;
335 ifport = ifport->next;
338 /* alloc port substructure */
339 ifport = (struct interface_port *)MALLOC(sizeof(struct interface_port));
341 ifport->interface = interface;
343 ifport->portnum = -1; // disable until resolved
344 SCPY(ifport->portname, value);
346 ifportp = &interface->ifport;
348 ifportp = &((*ifportp)->next);
353 static int inter_l1hold(struct interface *interface, char *filename, int line, char *parameter, char *value)
355 struct interface_port *ifport;
357 /* port in chain ? */
358 if (!interface->ifport) {
359 SPRINT(interface_error, "Error in %s (line %d): parameter '%s' expects previous 'port' definition.\n", filename, line, parameter);
362 /* goto end of chain */
363 ifport = interface->ifport;
365 ifport = ifport->next;
366 if (!strcmp(value, "yes")) {
369 if (!strcmp(value, "no")) {
372 SPRINT(interface_error, "Error in %s (line %d): parameter '%s' expecting parameter 'yes' or 'no'.\n", filename, line, parameter);
377 static int inter_l2hold(struct interface *interface, char *filename, int line, char *parameter, char *value)
379 struct interface_port *ifport;
381 /* port in chain ? */
382 if (!interface->ifport) {
383 SPRINT(interface_error, "Error in %s (line %d): parameter '%s' expects previous 'port' definition.\n", filename, line, parameter);
386 /* goto end of chain */
387 ifport = interface->ifport;
389 ifport = ifport->next;
390 if (!strcmp(value, "yes")) {
393 if (!strcmp(value, "no")) {
396 SPRINT(interface_error, "Error in %s (line %d): parameter '%s' expecting parameter 'yes' or 'no'.\n", filename, line, parameter);
401 static int inter_channel_out(struct interface *interface, char *filename, int line, char *parameter, char *value)
403 struct interface_port *ifport;
404 struct select_channel *selchannel, **selchannelp;
408 /* port in chain ? */
409 if (!interface->ifport) {
410 SPRINT(interface_error, "Error in %s (line %d): parameter '%s' expects previous 'port' definition.\n", filename, line, parameter);
413 /* goto end of chain */
414 ifport = interface->ifport;
416 ifport = ifport->next;
420 p = get_seperated(p);
421 if (!strcasecmp(el, "force")) {
422 ifport->channel_force = 1;
423 if (ifport->out_channel) {
424 SPRINT(interface_error, "Error in %s (line %d): value 'force' may only appear as first element in list.\n", filename, line);
428 if (!strcasecmp(el, "any")) {
432 if (!strcasecmp(el, "free")) {
436 if (!strcasecmp(el, "no")) {
440 val = get_number(el);
442 SPRINT(interface_error, "Error in %s (line %d): parameter '%s' expects a comma seperated list of 'force', 'any', 'free', 'no' and any channel number.\n", filename, line, parameter);
446 if (val<1 || val==16 || val>126) {
447 SPRINT(interface_error, "Error in %s (line %d): channel '%d' out of range.\n", filename, line, val);
451 /* add to select-channel list */
452 selchannel = (struct select_channel *)MALLOC(sizeof(struct select_channel));
455 selchannel->channel = val;
457 selchannelp = &ifport->out_channel;
459 selchannelp = &((*selchannelp)->next);
460 *selchannelp = selchannel;
465 static int inter_channel_in(struct interface *interface, char *filename, int line, char *parameter, char *value)
467 struct interface_port *ifport;
468 struct select_channel *selchannel, **selchannelp;
472 /* port in chain ? */
473 if (!interface->ifport) {
474 SPRINT(interface_error, "Error in %s (line %d): parameter '%s' expects previous 'port' definition.\n", filename, line, parameter);
477 /* goto end of chain */
478 ifport = interface->ifport;
480 ifport = ifport->next;
484 p = get_seperated(p);
485 if (ifport->in_channel) if (ifport->in_channel->channel == CHANNEL_FREE) {
486 SPRINT(interface_error, "Error in %s (line %d): parameter '%s' has values behind 'free' keyword. They has no effect.\n", filename, line, parameter);
489 if (!strcasecmp(el, "free")) {
493 val = get_number(el);
495 SPRINT(interface_error, "Error in %s (line %d): parameter '%s' expects a comma seperated list of channel numbers and 'free'.\n", filename, line, parameter);
499 if (val<1 || val==16 || val>126) {
500 SPRINT(interface_error, "Error in %s (line %d): channel '%d' out of range.\n", filename, line, val);
504 /* add to select-channel list */
505 selchannel = (struct select_channel *)MALLOC(sizeof(struct select_channel));
508 selchannel->channel = val;
510 selchannelp = &ifport->in_channel;
512 selchannelp = &((*selchannelp)->next);
513 *selchannelp = selchannel;
518 static int inter_timeouts(struct interface *interface, char *filename, int line, char *parameter, char *value)
520 struct interface_port *ifport;
521 // struct select_channel *selchannel, **selchannelp;
525 /* port in chain ? */
526 if (!interface->ifport) {
527 SPRINT(interface_error, "Error in %s (line %d): parameter '%s' expects previous 'port' definition.\n", filename, line, parameter);
530 /* goto end of chain */
531 ifport = interface->ifport;
533 ifport = ifport->next;
537 SPRINT(interface_error, "Error in %s (line %d): parameter '%s' expects five timeout values.\n", filename, line, parameter);
541 p = get_seperated(p);
542 ifport->tout_setup = atoi(el);
546 p = get_seperated(p);
547 ifport->tout_dialing = atoi(el);
551 p = get_seperated(p);
552 ifport->tout_proceeding = atoi(el);
556 p = get_seperated(p);
557 ifport->tout_alerting = atoi(el);
561 p = get_seperated(p);
562 ifport->tout_disconnect = atoi(el);
565 static int inter_msn(struct interface *interface, char *filename, int line, char *parameter, char *value)
567 struct interface_msn *ifmsn, **ifmsnp;
571 SPRINT(interface_error, "Error in %s (line %d): parameter '%s' expects one MSN number or a list.\n", filename, line, parameter);
574 if (interface->ifscreen_in) {
575 SPRINT(interface_error, "Error in %s (line %d): parameter '%s' not allowed with 'screen_in' parameter.\n", filename, line, parameter);
583 p = get_seperated(p);
584 /* add MSN to list */
585 ifmsn = (struct interface_msn *)MALLOC(sizeof(struct interface_msn));
588 SCPY(ifmsn->msn, el);
590 ifmsnp = &interface->ifmsn;
592 ifmsnp = &((*ifmsnp)->next);
597 static int inter_screen(struct interface_screen **ifscreenp, struct interface *interface, char *filename, int line, char *parameter, char *value)
599 struct interface_screen *ifscreen;
603 SPRINT(interface_error, "Error in %s (line %d): parameter '%s' expects old caller ID and new caller ID.\n", filename, line, parameter);
606 /* add screen entry to list*/
607 ifscreen = (struct interface_screen *)MALLOC(sizeof(struct interface_screen));
609 ifscreen->match_type = -1; /* unchecked */
610 ifscreen->match_present = -1; /* unchecked */
611 ifscreen->result_type = -1; /* unchanged */
612 ifscreen->result_present = -1; /* unchanged */
615 ifscreenp = &((*ifscreenp)->next);
616 *ifscreenp = ifscreen;
617 // printf("interface=%s\n", interface->name);
622 p = get_seperated(p);
623 if (!strcasecmp(el, "unknown")) {
624 if (ifscreen->match_type != -1) {
626 SPRINT(interface_error, "Error in %s (line %d): number type already set earlier.\n", filename, line, parameter);
629 ifscreen->match_type = INFO_NTYPE_UNKNOWN;
631 if (!strcasecmp(el, "subscriber")) {
632 if (ifscreen->match_type != -1)
634 ifscreen->match_type = INFO_NTYPE_SUBSCRIBER;
636 if (!strcasecmp(el, "national")) {
637 if (ifscreen->match_type != -1)
639 ifscreen->match_type = INFO_NTYPE_NATIONAL;
641 if (!strcasecmp(el, "international")) {
642 if (ifscreen->match_type != -1)
644 ifscreen->match_type = INFO_NTYPE_INTERNATIONAL;
646 if (!strcasecmp(el, "allowed")) {
647 if (ifscreen->match_present != -1) {
649 SPRINT(interface_error, "Error in %s (line %d): presentation type already set earlier.\n", filename, line);
652 ifscreen->match_present = INFO_PRESENT_ALLOWED;
654 if (!strcasecmp(el, "restrict") || !strcasecmp(el, "restricted")) {
655 if (ifscreen->match_present != -1)
657 ifscreen->match_present = INFO_PRESENT_RESTRICTED;
659 SCPY(ifscreen->match, el);
660 /* check for % at the end */
661 if (strchr(el, '%')) {
662 if (strchr(el, '%') != el+strlen(el)-1) {
663 SPRINT(interface_error, "Error in %s (line %d): %% joker found, but must at the end.\n", filename, line, parameter);
670 if (ifscreen->match[0] == '\0') {
671 SPRINT(interface_error, "Error in %s (line %d): parameter '%s' expects old caller ID.\n", filename, line, parameter);
677 p = get_seperated(p);
678 if (!strcasecmp(el, "unknown")) {
679 if (ifscreen->result_type != -1)
681 ifscreen->result_type = INFO_NTYPE_UNKNOWN;
683 if (!strcasecmp(el, "subscriber")) {
684 if (ifscreen->result_type != -1)
686 ifscreen->result_type = INFO_NTYPE_SUBSCRIBER;
688 if (!strcasecmp(el, "national")) {
689 if (ifscreen->result_type != -1)
691 ifscreen->result_type = INFO_NTYPE_NATIONAL;
693 if (!strcasecmp(el, "international")) {
694 if (ifscreen->result_type != -1)
696 ifscreen->result_type = INFO_NTYPE_INTERNATIONAL;
698 if (!strcasecmp(el, "present") || !strcasecmp(el, "presented") || !strcasecmp(el, "allowed") || !strcasecmp(el, "allow")) {
699 if (ifscreen->result_present != -1)
701 ifscreen->result_present = INFO_PRESENT_ALLOWED;
703 if (!strcasecmp(el, "restrict") || !strcasecmp(el, "restricted") || !strcasecmp(el, "deny") || !strcasecmp(el, "denied")) {
704 if (ifscreen->result_present != -1)
706 ifscreen->result_present = INFO_PRESENT_RESTRICTED;
708 SCPY(ifscreen->result, el);
709 /* check for % at the end */
710 if (strchr(el, '%')) {
711 if (strchr(el, '%') != el+strlen(el)-1) {
712 SPRINT(interface_error, "Error in %s (line %d): %% joker found, but must at the end.\n", filename, line, parameter);
719 if (ifscreen->result[0] == '\0') {
720 SPRINT(interface_error, "Error in %s (line %d): parameter '%s' expects new caller ID.\n", filename, line, parameter);
725 static int inter_screen_in(struct interface *interface, char *filename, int line, char *parameter, char *value)
727 if (interface->ifmsn) {
728 SPRINT(interface_error, "Error in %s (line %d): parameter '%s' not allowed with 'msn' parameter.\n", filename, line, parameter);
732 return(inter_screen(&interface->ifscreen_in, interface, filename, line, parameter, value));
734 static int inter_screen_out(struct interface *interface, char *filename, int line, char *parameter, char *value)
736 return(inter_screen(&interface->ifscreen_out, interface, filename, line, parameter, value));
738 static int inter_nodtmf(struct interface *interface, char *filename, int line, char *parameter, char *value)
740 struct interface_port *ifport;
742 /* port in chain ? */
743 if (!interface->ifport) {
744 SPRINT(interface_error, "Error in %s (line %d): parameter '%s' expects previous 'port' definition.\n", filename, line, parameter);
747 /* goto end of chain */
748 ifport = interface->ifport;
750 ifport = ifport->next;
754 static int inter_filter(struct interface *interface, char *filename, int line, char *parameter, char *value)
758 /* seperate parameter from filter */
764 while(*p > 0 && *p <= 32)
768 if (!strcasecmp(value, "gain")) {
774 while(*q > 0 && *q <= 32)
777 if (*p == 0 || *q == 0) {
778 SPRINT(interface_error, "Error in %s (line %d): parameter '%s %s' expects two gain values.\n", filename, line, parameter, value);
781 if (atoi(p)<-8 || atoi(p)>8 || atoi(q)<-8 || atoi(q)>8) {
782 SPRINT(interface_error, "Error in %s (line %d): parameter '%s %s' gain values not in range. (-8...8)\n", filename, line, parameter, value);
785 interface->tx_gain = atoi(p);
786 interface->rx_gain = atoi(q);
788 if (!strcasecmp(value, "pipeline")) {
790 SPRINT(interface_error, "Error in %s (line %d): parameter '%s %s' expects pipeline string.\n", filename, line, parameter, value);
793 SCPY(interface->pipeline, p);
795 if (!strcasecmp(value, "blowfish")) {
796 unsigned char key[56];
799 if (!!strncmp(p, "0x", 2)) {
800 SPRINT(interface_error, "Error in %s (line %d): parameter '%s %s' expects blowfish key starting with '0x'.\n", filename, line, parameter, value);
807 SPRINT(interface_error, "Error in %s (line %d): parameter '%s %s' key too long.\n", filename, line, parameter, value);
810 if (*p >= '0' && *p <= '9')
811 key[l] = (*p-'0')<<4;
812 else if (*p >= 'a' && *p <= 'f')
813 key[l] = (*p-'a'+10)<<4;
814 else if (*p >= 'A' && *p <= 'F')
815 key[l] = (*p-'A'+10)<<4;
818 SPRINT(interface_error, "Error in %s (line %d): parameter '%s %s' key has digits out of range. (0...9, a...f)\n", filename, line, parameter, value);
823 SPRINT(interface_error, "Error in %s (line %d): parameter '%s %s' key must end on an 8 bit boundary (two character boundary).\n", filename, line, parameter, value);
826 if (*p >= '0' && *p <= '9')
827 key[l] = (*p-'0')<<4;
828 else if (*p >= 'a' && *p <= 'f')
829 key[l] = (*p-'a'+10)<<4;
830 else if (*p >= 'A' && *p <= 'F')
831 key[l] = (*p-'A'+10)<<4;
838 SPRINT(interface_error, "Error in %s (line %d): parameter '%s %s' key must be at least 4 bytes (8 characters).\n", filename, line, parameter, value);
841 memcpy(interface->bf_key, key, l);
842 interface->bf_len = l;
844 SPRINT(interface_error, "Error in %s (line %d): parameter '%s' has unknown filter '%s'.\n", filename, line, parameter, value);
849 static int inter_dialmax(struct interface *interface, char *filename, int line, char *parameter, char *value)
851 struct interface_port *ifport;
853 /* port in chain ? */
854 if (!interface->ifport) {
855 SPRINT(interface_error, "Error in %s (line %d): parameter '%s' expects previous 'port' definition.\n", filename, line, parameter);
858 /* goto end of chain */
859 ifport = interface->ifport;
861 ifport = ifport->next;
862 ifport->dialmax = atoi(value);
865 static int inter_tones_dir(struct interface *interface, char *filename, int line, char *parameter, char *value)
867 struct interface_port *ifport;
869 /* port in chain ? */
870 if (!interface->ifport) {
871 SPRINT(interface_error, "Error in %s (line %d): parameter '%s' expects previous 'port' definition.\n", filename, line, parameter);
874 /* goto end of chain */
875 ifport = interface->ifport;
877 ifport = ifport->next;
878 SCPY(ifport->tones_dir, value);
881 static int inter_gsm(struct interface *interface, char *filename, int line, char *parameter, char *value)
883 SPRINT(interface_error, "Error in %s (line %d): parameter '%s' is outdated.\nPlease use 'gsm-bs' for base station or 'gsm-ms' for mobile station interface!\n", filename, line, parameter);
886 static int inter_gsm_bs(struct interface *interface, char *filename, int line, char *parameter, char *value)
889 SPRINT(interface_error, "Error in %s (line %d): GSM BS side not compiled in.\n", filename, line);
892 struct interface *searchif;
894 searchif = interface_newlist;
896 if (searchif->gsm_bs) {
897 SPRINT(interface_error, "Error in %s (line %d): interface '%s' already uses gsm BS side.\n", filename, line, searchif->name);
900 searchif = searchif->next;
903 /* goto end of chain again to set gsmflag */
904 interface->gsm_bs = 1;
909 static int inter_gsm_ms(struct interface *interface, char *filename, int line, char *parameter, char *value)
912 SPRINT(interface_error, "Error in %s (line %d): GSM MS side not compiled in.\n", filename, line);
915 struct interface *searchif;
917 interface->gsm_ms = 1;
920 if (!value || !value[0]) {
921 SPRINT(interface_error, "Error in %s (line %d): Missing MS name and socket name.\n", filename, line);
924 SCPY(interface->gsm_ms_name, value);
926 /* check if name is used multiple times */
927 searchif = interface_newlist;
929 if (searchif != interface && !strcmp(searchif->gsm_ms_name, interface->gsm_ms_name)) {
930 SPRINT(interface_error, "Error in %s (line %d): mobile '%s' already uses the given MS name '%s', choose a different one.\n", filename, line, interface->gsm_ms_name, searchif->gsm_ms_name);
933 searchif = searchif->next;
939 static int inter_sip(struct interface *interface, char *filename, int line, char *parameter, char *value)
942 SPRINT(interface_error, "Error in %s (line %d): SIP not compiled in.\n", filename, line);
950 if (!value || !value[0]) {
951 SPRINT(interface_error, "Error in %s (line %d): Missing SIP local IP.\n", filename, line);
954 p = get_seperated(value);
956 SPRINT(interface_error, "Error in %s (line %d): Missing SIP remote IP.\n", filename, line);
959 SCPY(interface->sip_local_peer, value);
960 SCPY(interface->sip_remote_peer, p);
965 static int inter_rtp_bridge(struct interface *interface, char *filename, int line, char *parameter, char *value)
970 if (interface->gsm_bs)
978 SPRINT(interface_error, "Error in %s (line %d): Interface does not support RTP\n", filename, line);
981 interface->rtp_bridge = 1;
986 static int inter_rtp_payload(struct interface *interface, char *filename, int line, char *parameter, char *value)
989 SPRINT(interface_error, "Error in %s (line %d): GSM BS side not compiled in.\n", filename, line);
992 if (!interface->gsm_bs) {
993 SPRINT(interface_error, "Error in %s (line %d): This parameter only works for GSM BS side interface\n", filename, line);
996 if (!interface->rtp_bridge) {
997 SPRINT(interface_error, "Error in %s (line %d): This parameter only works here, if RTP bridging is enabled\n", filename, line);
1001 SPRINT(interface_error, "Error in %s (line %d): parameter '%s' expects one payload type\n", filename, line, parameter);
1004 if (interface->gsm_bs_payloads == sizeof(interface->gsm_bs_payload_types)) {
1005 SPRINT(interface_error, "Error in %s (line %d): Too many payload types defined\n", filename, line);
1008 interface->gsm_bs_payload_types[interface->gsm_bs_payloads++] = atoi(value);
1014 static int inter_nonotify(struct interface *interface, char *filename, int line, char *parameter, char *value)
1016 struct interface_port *ifport;
1018 /* port in chain ? */
1019 if (!interface->ifport) {
1020 SPRINT(interface_error, "Error in %s (line %d): parameter '%s' expects previous 'port' definition.\n", filename, line, parameter);
1023 /* goto end of chain */
1024 ifport = interface->ifport;
1026 ifport = ifport->next;
1027 ifport->nonotify = 1;
1031 static int inter_ss5(struct interface *interface, char *filename, int line, char *parameter, char *value)
1033 struct interface_port *ifport;
1036 /* port in chain ? */
1037 if (!interface->ifport) {
1038 SPRINT(interface_error, "Error in %s (line %d): parameter '%s' expects previous 'port' definition.\n", filename, line, parameter);
1041 /* goto end of chain */
1042 ifport = interface->ifport;
1044 ifport = ifport->next;
1045 ifport->ss5 |= SS5_ENABLE;
1046 while((element = strsep(&value, " "))) {
1047 if (element[0] == '\0')
1049 if (!strcasecmp(element, "connect"))
1050 ifport->ss5 |= SS5_FEATURE_CONNECT;
1052 if (!strcasecmp(element, "nodisconnect"))
1053 ifport->ss5 |= SS5_FEATURE_NODISCONNECT;
1055 if (!strcasecmp(element, "releaseguardtimer"))
1056 ifport->ss5 |= SS5_FEATURE_RELEASEGUARDTIMER;
1058 if (!strcasecmp(element, "bell"))
1059 ifport->ss5 |= SS5_FEATURE_BELL;
1061 if (!strcasecmp(element, "pulsedialing"))
1062 ifport->ss5 |= SS5_FEATURE_PULSEDIALING;
1064 if (!strcasecmp(element, "delay"))
1065 ifport->ss5 |= SS5_FEATURE_DELAY;
1067 if (!strcasecmp(element, "starrelease"))
1068 ifport->ss5 |= SS5_FEATURE_STAR_RELEASE;
1070 if (!strcasecmp(element, "suppress"))
1071 ifport->ss5 |= SS5_FEATURE_SUPPRESS;
1073 SPRINT(interface_error, "Error in %s (line %d): parameter '%s' does not allow value element '%s'.\n", filename, line, parameter, element);
1080 static int inter_remote(struct interface *interface, char *filename, int line, char *parameter, char *value)
1082 struct interface *searchif;
1085 SPRINT(interface_error, "Error in %s (line %d): parameter '%s' expects application name as value.\n", filename, line, parameter);
1088 searchif = interface_newlist;
1090 if (interface->remote && !strcmp(interface->remote_app, value)) {
1091 SPRINT(interface_error, "Error in %s (line %d): interface '%s' already uses remote application '%s'.\n", filename, line, interface->name, value);
1094 searchif = searchif->next;
1097 /* goto end of chain again to set application name */
1098 interface->remote = 1;
1099 SCPY(interface->remote_app, value);
1103 static int inter_context(struct interface *interface, char *filename, int line, char *parameter, char *value)
1106 SPRINT(interface_error, "Error in %s (line %d): parameter '%s' expects application context as value.\n", filename, line, parameter);
1109 SCPY(interface->remote_context, value);
1113 static int inter_shutdown(struct interface *interface, char *filename, int line, char *parameter, char *value)
1115 interface->shutdown = 1;
1119 static int inter_bridge(struct interface *interface, char *filename, int line, char *parameter, char *value)
1121 if (!value || !value[0]) {
1122 SPRINT(interface_error, "Error in %s (line %d): Missing destination interface name.\n", filename, line);
1125 interface->app = EAPP_TYPE_BRIDGE;
1126 SCPY(interface->bridge_if, value);
1133 * structure of parameters
1135 struct interface_param interface_param[] = {
1136 { "extension", &inter_extension, "",
1137 "If keyword is given, calls to interface are handled as internal extensions."},
1139 { "extern", &inter_extern, "",
1140 "If keyword is given, this interface will be used for external calls.\n"
1141 "Calls require an external interface, if the routing action 'extern' is used\nwithout specific interface given.\n"
1142 "Calls forwarded by extension's 'settings' also require an external interface."},
1144 {"tones", &inter_tones, "yes | no",
1145 "Interface generates tones during call setup and release, or not.\nBy default only NT-mode ports generate tones."},
1147 {"earlyb", &inter_earlyb, "yes | no",
1148 "Interface receives and bridges tones during call setup and release, or not.\nBy default only TE-mode ports receive tones."},
1150 {"hunt", &inter_hunt, "linear | roundrobin",
1151 "Select the algorithm for selecting port with free channel."},
1153 {"port", &inter_port, "<number>",
1155 {"portnum", &inter_portnum, "<number>",
1156 "Give exactly one port for this interface.\nTo give multiple ports, add more lines with port parameters."},
1157 {"portname", &inter_portname, "<name>",
1158 "Same as 'portnum', but the name is given instead.\nUse 'isdninfo' to list all available ports and names."},
1160 {"block", &inter_block, "",
1161 "If keyword is given, calls on this interface are blocked.\n"
1162 "This parameter must follow a 'port' parameter."},
1164 {"ptp", &inter_ptp, "",
1165 "The given port above is opened as point-to-point.\n"
1166 "This is required on NT-mode ports that are multipoint by default.\n"
1167 "This parameter must follow a 'port' parameter."},
1170 {"ptmp", &inter_ptmp, "",
1171 "The given port above is opened as point-to-multipoint.\n"
1172 "This is required on PRI NT-mode ports that are point-to-point by default.\n"
1173 "This parameter must follow a 'port' parameter."},
1176 {"nt", &inter_nt, "",
1177 "The given port above is opened in NT-mode.\n"
1178 "This is required on interfaces that support both NT-mode and TE-mode.\n"
1179 "This parameter must follow a 'port' parameter."},
1181 {"te-special", &inter_tespecial, "",
1182 "The given port uses a modified TE-mode.\n"
1183 "All information elements that are allowed Network->User will then be\n"
1184 "transmitted User->Network also. This is usefull to pass all informations\n"
1185 "between two interconnected LCRs, like 'redirected number' or 'display'.\n"
1186 "Note that this is not compliant with ISDN protocol.\n"
1187 "This parameter must follow a 'port' parameter."},
1189 {"layer1hold", &inter_l1hold, "yes | no",
1190 "The given port will not release layer 1 after layer 2 is down.\n"
1191 "It is required to keep layer 1 of telephones up, to solve activation problems.\n"
1192 "This parameter must follow a 'port' parameter."},
1194 {"layer2hold", &inter_l2hold, "yes | no",
1195 "The given port will continuously try to establish layer 2 link and hold it.\n"
1196 "It is required for PTP links in most cases, therefore it is default.\n"
1197 "This parameter must follow a 'port' parameter."},
1199 {"channel-out", &inter_channel_out, "[force,][<number>][,...][,free][,any][,no]",
1200 "Channel selection list for all outgoing calls to the interface.\n"
1201 "A free channels is searched in order of appearance.\n"
1202 "This parameter must follow a 'port' parameter.\n"
1203 " force - Forces the selected port with no acceptable alternative (see Q.931).\n"
1204 " -> this will be automatically set for multipoint (ptmp) NT-mode ports\n"
1205 " <number>[,...] - List of channels to search.\n"
1206 " free - Select any free channel\n"
1207 " any - On outgoing calls, signal 'any channel acceptable'. (see DSS1)\n"
1208 " no - Signal 'no channel available' aka 'call waiting'. (see DSS1)"},
1210 {"channel-in", &inter_channel_in, "[<number>][,...][,free]",
1211 "Channel selection list for all incoming calls from the interface.\n"
1212 "A free channels is accepted if in the list.\n"
1213 "If any channel was requested, the first free channel found is selected.\n"
1214 "This parameter must follow a 'port' parameter.\n"
1215 " <number>[,...] - List of channels to accept.\n"
1216 " free - Accept any free channel"},
1218 {"timeouts", &inter_timeouts, "<setup> <dialing> <proceeding> <alerting> <disconnect>",
1219 "Timeout values for call states. They are both for incoming and outgoing states.\n"
1220 "The default is 120 seconds for all states. Use 0 to disable.\n"
1221 "This parameter must follow a 'port' parameter.\n"},
1223 {"msn", &inter_msn, "<default MSN>,[<additional MSN>[,...]]",
1224 "Incoming caller ID is checked against given MSN numbers.\n"
1225 "If the caller ID is not found in this list, it is overwritten by the first MSN"},
1227 {"screen-in", &inter_screen_in, "[options] <old caller ID>[%] [options] <new caller ID>[%]",
1228 "Adds an entry for incoming calls to the caller ID screen list.\n"
1229 "If the given 'old caller ID' matches, it is replaced by the 'new caller ID'\n"
1230 "If '%' is given after old caller ID, it matches even if caller ID has\n"
1231 "additional digits.\n"
1232 "If '%' is given after mew caller ID, additinal digits of the 'old caller ID'\n"
1235 " unknown | subsciber | national | international - Change caller ID type.\n"
1236 " present | restrict - Change presentation of caller ID."},
1238 {"screen-out", &inter_screen_out, "[options] <old caller ID>[%] [options] <new caller ID>[%]",
1239 "Adds an entry for outgoing calls to the caller ID screen list.\n"
1240 "See 'screen-in' for help."},
1242 {"nodtmf", &inter_nodtmf, "",
1243 "Disables DTMF detection for this interface.\n"
1244 "This parameter must follow a 'port' parameter."},
1246 {"filter", &inter_filter, "<filter> <parameters>",
1247 "Adds/appends a filter. Filters are ordered in transmit direction.\n"
1248 "gain <tx-volume> <rx-volume> - Changes volume (-8 .. 8)\n"
1249 "pipeline <string> - Sets echo cancelation pipeline.\n"
1250 "blowfish <key> - Adds encryption. Key must be 4-56 bytes (8-112 hex characters."},
1252 {"dialmax", &inter_dialmax, "<digits>",
1253 "Limits the number of digits in setup/information message."},
1255 {"tones_dir", &inter_tones_dir, "<path>",
1256 "Overrides the given tone_dir in options.conf.\n"
1257 "To used kernel tones in mISDN_dsp.ko, say 'american', 'german', or 'oldgerman'."},
1259 {"gsm", &inter_gsm, "",
1261 {"gsm-bs", &inter_gsm_bs, "",
1262 "Sets up GSM base station interface for using OpenBSC."},
1263 {"gsm-ms", &inter_gsm_ms, "<socket>",
1264 "Sets up GSM mobile station interface for using Osmocom-BB.\n"
1265 "The name of the MS folows the interface name.\n"
1266 "The socket is /tmp/osmocom_l2 by default and need to be changed when multiple\n"
1267 "MS interfaces are used."},
1268 {"sip", &inter_sip, "<local IP> <remote IP>",
1269 "Sets up SIP interface that represents one SIP endpoint.\n"
1270 "Give SIP configuration file."},
1271 {"rtp-bridge", &inter_rtp_bridge, "",
1272 "Enables RTP bridging directly from this interface.\n"
1273 "This only works, if both ends support RTP. (like gsm-bs and sip)"},
1275 not needed, since ms defines what is supports and remote (sip) tells what is selected
1276 {"rtp-payload", &inter_rtp_payload, "<codec>",
1277 "Define RTP payload to use. Only valid in conjuntion with gsm-bs!\n"
1278 "If multiple payloads are defined, the first has highest priority.\n"
1279 "If none are defined, GSM fullrate V1 (type 3) is assumed.\n"},
1281 {"nonotify", &inter_nonotify, "",
1282 "Prevents sending notify messages to this interface. A call placed on hold will\n"
1283 "Not affect the remote end (phone or telcom switch).\n"
1284 "This parameter must follow a 'port' parameter."},
1285 {"bridge", &inter_bridge, "<destination interface>",
1286 "Define bridge application for this interface. All calls received on this\n"
1287 "interface will be directly bridged to the given destination interface.\n"
1288 "There will be no PBX application, nor routing."},
1291 {"ccitt5", &inter_ss5, "[<feature> [feature ...]]",
1292 "Interface uses CCITT No. 5 inband signalling rather than D-channel.\n"
1293 "This feature causes CPU load to rise and has no practical intend.\n"
1294 "If you don't know what it is, you don't need it.\n"
1295 "Features apply to protocol behaviour and blueboxing specials, they are:\n"
1296 " connect - Connect incomming call to throughconnect audio, if required.\n"
1297 " nodisconnect - Don't disconnect if incomming exchange disconnects.\n"
1298 " releaseguardtimer - Tries to prevent Blueboxing by a longer release-guard.\n"
1299 " bell - Allow releasing and pulse-dialing via 2600 Hz like old Bell systems.\n"
1300 " pulsedialing - Use pulse dialing on outgoing exchange. (takes long!)\n"
1301 " delay - Use on incomming exchange, to make you feel a delay when blueboxing.\n"
1302 " starrelease - Pulse dialing a star (11 pulses per digit) clears current call.\n"
1303 " suppress - Suppress received tones, as they will be recognized."},
1306 {"remote", &inter_remote, "<application>",
1307 "Sets up an interface that communicates with the remote application.\n"
1308 "Use \"asterisk\" to use chan_lcr as remote application."},
1309 {"context", &inter_context, "<context>",
1310 "Give context for calls to application."},
1312 {"shutdown", &inter_shutdown, "",
1313 "Interface will not be loaded when processing interface.conf"},
1315 {NULL, NULL, NULL, NULL}
1320 * read settings from interface.conf
1322 char interface_error[256];
1323 struct interface *read_interfaces(void)
1328 unsigned int line, i;
1330 struct interface *interface = NULL, /* in case no interface */
1331 **interfacep = &interface_newlist;
1332 char parameter[128];
1334 int expecting = 1; /* expecting new interface */
1335 struct interface_param *ifparam;
1337 if (interface_newlist != NULL)
1338 FATAL("list is not empty.\n");
1339 interface_error[0] = '\0';
1340 SPRINT(filename, "%s/interface.conf", CONFIG_DATA);
1342 if (!(fp = fopen(filename,"r"))) {
1343 SPRINT(interface_error, "Cannot open '%s'\n", filename);
1348 while((GETLINE(buffer, fp))) {
1352 while(*p <= 32) { /* skip spaces */
1357 if (*p==0 || *p=='#') /* ignore comments and empty line */
1362 i=0; /* read parameter */
1364 if (i+1 >= sizeof(parameter)) {
1365 SPRINT(interface_error, "Error in %s (line %d): parameter name too long.\n",filename,line);
1368 parameter[i+1] = '\0';
1369 parameter[i++] = *p++;
1372 while(*p <= 32) { /* skip spaces */
1378 if (*p!=0 && *p!='#') { /* missing name */
1379 i=0; /* read until end */
1380 while(*p!=0 && *p!='#') {
1381 if (i+1 >= sizeof(value)) {
1382 SPRINT(interface_error, "Error in %s (line %d): value too long.\n", filename, line);
1389 /* remove trailing spaces from value */
1391 if (value[i-1]==0 || value[i-1]>32)
1398 /* check for interface name as first statement */
1399 if (expecting && parameter[0]!='[') {
1400 SPRINT(interface_error, "Error in %s (line %d): expecting interface name inside [ and ], but got: '%s'.\n", filename, line, parameter);
1405 /* check for new interface */
1406 if (parameter[0] == '[') {
1407 if (parameter[strlen(parameter)-1] != ']') {
1408 SPRINT(interface_error, "Error in %s (line %d): expecting interface name inside [ and ], but got: '%s'.\n", filename, line, parameter);
1411 parameter[strlen(parameter)-1] = '\0';
1413 /* check if interface name already exists */
1414 interface = interface_newlist;
1416 if (!strcasecmp(interface->name, parameter+1)) {
1417 SPRINT(interface_error, "Error in %s (line %d): interface name '%s' already defined above.\n", filename, line, parameter+1);
1420 interface = interface->next;
1423 /* append interface to new list */
1424 interface = (struct interface *)MALLOC(sizeof(struct interface));
1427 /* name interface */
1428 SCPY(interface->name, parameter+1);
1431 *interfacep = interface;
1432 interfacep = &interface->next;
1437 ifparam = interface_param;
1438 while(ifparam->name) {
1439 if (!strcasecmp(parameter, ifparam->name)) {
1440 if (ifparam->func(interface, filename, line, parameter, value))
1449 SPRINT(interface_error, "Error in %s (line %d): unknown parameter: '%s'.\n", filename, line, parameter);
1454 return(interface_newlist);
1456 PERROR_RUNTIME("%s", interface_error);
1458 free_interfaces(interface_newlist);
1459 interface_newlist = NULL;
1465 * freeing chain of interfaces
1467 void free_interfaces(struct interface *interface)
1470 struct interface_port *ifport;
1471 struct select_channel *selchannel;
1472 struct interface_msn *ifmsn;
1473 struct interface_screen *ifscreen;
1476 ifport = interface->ifport;
1478 selchannel = ifport->in_channel;
1481 selchannel = selchannel->next;
1482 FREE(temp, sizeof(struct select_channel));
1485 selchannel = ifport->out_channel;
1488 selchannel = selchannel->next;
1489 FREE(temp, sizeof(struct select_channel));
1493 ifport = ifport->next;
1494 FREE(temp, sizeof(struct interface_port));
1497 ifmsn = interface->ifmsn;
1500 ifmsn = ifmsn->next;
1501 FREE(temp, sizeof(struct interface_msn));
1504 ifscreen = interface->ifscreen_in;
1507 ifscreen = ifscreen->next;
1508 FREE(temp, sizeof(struct interface_screen));
1511 ifscreen = interface->ifscreen_out;
1514 ifscreen = ifscreen->next;
1515 FREE(temp, sizeof(struct interface_screen));
1519 interface = interface->next;
1520 FREE(temp, sizeof(struct interface));
1527 * defaults of ports if not specified by config
1529 static void set_mISDN_defaults(struct interface_port *ifport)
1531 /* default channel selection list */
1532 if (!ifport->out_channel)
1533 default_out_channel(ifport);
1534 if (!ifport->in_channel)
1535 default_in_channel(ifport);
1536 /* must force the channel on PTMP/NT ports */
1537 if (!ifport->mISDNport->ptp && ifport->mISDNport->ntmode)
1538 ifport->channel_force = 1;
1539 /* default is_tones */
1540 if (ifport->interface->is_tones)
1541 ifport->mISDNport->tones = (ifport->interface->is_tones==IS_YES);
1543 ifport->mISDNport->tones = (ifport->mISDNport->ntmode || ifport->mISDNport->ss5)?1:0;
1544 /* default is_earlyb */
1545 if (ifport->interface->is_earlyb)
1546 ifport->mISDNport->earlyb = (ifport->interface->is_earlyb==IS_YES);
1548 ifport->mISDNport->earlyb = (ifport->mISDNport->ntmode && !ifport->mISDNport->ss5)?0:1;
1549 /* set locally flag */
1550 if (ifport->interface->extension)
1551 ifport->mISDNport->locally = 1;
1553 ifport->mISDNport->locally = 0;
1559 * all links between mISDNport and interface are made
1560 * unused mISDNports are closed, new mISDNports are opened
1561 * also set default select_channel lists
1563 void relink_interfaces(void)
1566 struct mISDNport *mISDNport;
1567 struct interface_port *ifport;
1569 struct interface *interface, *temp, *found;
1571 interface = interface_first;
1574 temp = interface_newlist;
1576 if (!strcmp(temp->name, interface->name))
1582 if (interface->gsm_ms)
1583 gsm_ms_delete(interface->gsm_ms_name);
1586 if (interface->gsm_bs)
1591 sip_exit_inst(interface);
1595 if (interface->sip) {
1596 /* move sip instance, if we keep interface */
1597 found->sip_inst = interface->sip_inst;
1598 interface->sip_inst = NULL;
1603 interface = interface->next;
1606 interface = interface_newlist;
1609 temp = interface_first;
1611 if (!strcmp(temp->name, interface->name))
1617 if (interface->gsm_ms)
1618 gsm_ms_new(interface);
1621 if (interface->gsm_bs)
1622 gsm_bs_init(interface);
1626 sip_init_inst(interface);
1629 interface = interface->next;
1633 /* unlink all mISDNports */
1634 mISDNport = mISDNport_first;
1636 mISDNport->ifport = NULL;
1637 mISDNport = mISDNport->next;
1640 /* relink existing mISDNports */
1641 interface = interface_newlist;
1643 ifport = interface->ifport;
1645 mISDNport = mISDNport_first;
1647 if (!strcmp(mISDNport->name, ifport->portname))
1648 ifport->portnum = mISDNport->portnum; /* same name, so we use same number */
1649 if (mISDNport->portnum == ifport->portnum) {
1650 PDEBUG(DEBUG_ISDN, "Port %d:%s relinking!\n", ifport->portnum, ifport->portname);
1651 ifport->mISDNport = mISDNport;
1652 mISDNport->ifport = ifport;
1653 set_mISDN_defaults(ifport);
1655 mISDNport = mISDNport->next;
1657 ifport = ifport->next;
1659 interface = interface->next;
1662 /* close unused mISDNports */
1664 mISDNport = mISDNport_first;
1666 if (mISDNport->ifport == NULL) {
1667 PDEBUG(DEBUG_ISDN, "Port %d is not used anymore and will be closed\n", mISDNport->portnum);
1669 mISDNport_close(mISDNport);
1672 mISDNport = mISDNport->next;
1675 /* open and link new mISDNports */
1676 interface = interface_newlist;
1678 ifport = interface->ifport;
1680 if (!ifport->mISDNport) {
1681 if (!interface->shutdown) {
1682 load_mISDN_port(ifport);
1687 ifport = ifport->next;
1689 interface = interface->next;
1699 void load_mISDN_port(struct interface_port *ifport)
1701 struct mISDNport *mISDNport;
1704 mISDNport = mISDNport_open(ifport);
1707 ifport->mISDNport = mISDNport;
1708 mISDNport->ifport = ifport;
1709 /* set number and name */
1710 ifport->portnum = mISDNport->portnum;
1711 SCPY(ifport->portname, mISDNport->name);
1713 set_mISDN_defaults(ifport);
1714 /* load static port instances */
1715 mISDNport_static(mISDNport);
1717 ifport->block = 2; /* not available */
1723 * give summary of interface syntax
1725 void doc_interface(void)
1727 struct interface_param *ifparam;
1729 printf("Syntax overview\n");
1730 printf("---------------\n\n");
1732 printf("[<name>]\n");
1733 ifparam = interface_param;
1734 while(ifparam->name) {
1735 if (ifparam->name[0])
1736 printf("%s %s\n", ifparam->name, ifparam->usage);
1740 ifparam = interface_param;
1741 while(ifparam->name) {
1742 if (ifparam->name[0]) {
1743 printf("\nParameter: %s %s\n", ifparam->name, ifparam->usage);
1744 printf("%s\n", ifparam->help);
1752 * out==0: incoming caller id, out==1: outgoing caller id
1754 void do_screen(int out, char *id, int idsize, int *type, int *present, const char *interface_name)
1757 struct interface_msn *ifmsn;
1758 struct interface_screen *ifscreen;
1760 struct interface *interface = interface_first;
1762 interface = getinterfacebyname(interface_name);
1766 /* screen incoming caller id */
1768 /* check for MSN numbers, use first MSN if no match */
1770 ifmsn = interface->ifmsn;
1774 if (!strcmp(ifmsn->msn, id)) {
1777 ifmsn = ifmsn->next;
1780 start_trace(-1, interface, numberrize_callerinfo(id, *type, options.national, options.international), NULL, DIRECTION_IN, 0, 0, "SCREEN (found in MSN list)");
1781 add_trace("msn", NULL, "%s", id);
1784 if (!ifmsn && msn1) { // not in list, first msn given
1785 start_trace(-1, interface, numberrize_callerinfo(id, *type, options.national, options.international), NULL, DIRECTION_IN, 0, 0, "SCREEN (not found in MSN list)");
1786 add_trace("msn", "given", "%s", id);
1787 add_trace("msn", "used", "%s", msn1);
1789 UNCPY(id, msn1, idsize);
1790 id[idsize-1] = '\0';
1794 /* check screen list */
1796 ifscreen = interface->ifscreen_out;
1798 ifscreen = interface->ifscreen_in;
1800 if (ifscreen->match_type==-1 || ifscreen->match_type==*type)
1801 if (ifscreen->match_present==-1 || ifscreen->match_present==*present) {
1802 if (strchr(ifscreen->match,'%')) {
1803 if (!strncmp(ifscreen->match, id, strchr(ifscreen->match,'%')-ifscreen->match))
1806 if (!strcmp(ifscreen->match, id))
1810 ifscreen = ifscreen->next;
1812 if (ifscreen) { // match
1813 start_trace(-1, interface, numberrize_callerinfo(id, *type, options.national, options.international), NULL, out?DIRECTION_OUT:DIRECTION_IN, 0, 0, "SCREEN (found in screen list)");
1815 case INFO_NTYPE_UNKNOWN:
1816 add_trace("given", "type", "unknown");
1818 case INFO_NTYPE_SUBSCRIBER:
1819 add_trace("given", "type", "subscriber");
1821 case INFO_NTYPE_NATIONAL:
1822 add_trace("given", "type", "national");
1824 case INFO_NTYPE_INTERNATIONAL:
1825 add_trace("given", "type", "international");
1829 case INFO_PRESENT_ALLOWED:
1830 add_trace("given", "present", "allowed");
1832 case INFO_PRESENT_RESTRICTED:
1833 add_trace("given", "present", "restricted");
1835 case INFO_PRESENT_NOTAVAIL:
1836 add_trace("given", "present", "not available");
1839 add_trace("given", "id", "%s", id[0]?id:"<empty>");
1840 if (ifscreen->result_type != -1) {
1841 *type = ifscreen->result_type;
1843 case INFO_NTYPE_UNKNOWN:
1844 add_trace("used", "type", "unknown");
1846 case INFO_NTYPE_SUBSCRIBER:
1847 add_trace("used", "type", "subscriber");
1849 case INFO_NTYPE_NATIONAL:
1850 add_trace("used", "type", "national");
1852 case INFO_NTYPE_INTERNATIONAL:
1853 add_trace("used", "type", "international");
1857 if (ifscreen->result_present != -1) {
1858 *present = ifscreen->result_present;
1860 case INFO_PRESENT_ALLOWED:
1861 add_trace("used", "present", "allowed");
1863 case INFO_PRESENT_RESTRICTED:
1864 add_trace("used", "present", "restricted");
1866 case INFO_PRESENT_NOTAVAIL:
1867 add_trace("used", "present", "not available");
1871 if (strchr(ifscreen->match,'%')) {
1872 SCPY(suffix, strchr(ifscreen->match,'%') - ifscreen->match + id);
1873 UNCPY(id, ifscreen->result, idsize);
1874 id[idsize-1] = '\0';
1875 if (strchr(id,'%')) {
1876 *strchr(id,'%') = '\0';
1877 UNCAT(id, suffix, idsize);
1878 id[idsize-1] = '\0';
1881 UNCPY(id, ifscreen->result, idsize);
1882 id[idsize-1] = '\0';
1884 add_trace("used", "id", "%s", id[0]?id:"<empty>");
1889 struct interface *getinterfacebyname(const char *name)
1891 struct interface *interface = interface_first;
1894 if (!strcmp(interface->name, name))
1896 interface = interface->next;