X-Git-Url: http://git.eversberg.eu/gitweb.cgi?p=lcr.git;a=blobdiff_plain;f=interface.c;h=fa7270d9ec1229914ddb3d3be4f4c86d2bf8e061;hp=520ecbd0819cf3f36dcd50542ca96df864790335;hb=701b046a45c2c79cc6d07ac3a4f84f499f7ed376;hpb=559ff64e3062b70f27ddceba825f40642a6c5725 diff --git a/interface.c b/interface.c index 520ecbd..fa7270d 100644 --- a/interface.c +++ b/interface.c @@ -18,62 +18,44 @@ struct interface *interface_first = NULL; /* first interface is current list */ struct interface *interface_newlist = NULL; /* first interface in new list */ -/* set default selchannel */ -void default_selchannel(struct interface_port *ifport) +/* set default out_channel */ +void default_out_channel(struct interface_port *ifport) { struct select_channel *selchannel, **selchannelp; - /* channel selection for TE-ports */ - if (!ifport->mISDNport->ntmode) + selchannel = (struct select_channel *)MALLOC(sizeof(struct select_channel)); + memuse++; + + if (ifport->mISDNport->ntmode) + selchannel->channel = CHANNEL_FREE; + else + selchannel->channel = CHANNEL_ANY; + + ifport->out_channel = selchannel; + + /* additional channel selection for multipoint NT ports */ + if (!ifport->mISDNport->ptp && ifport->mISDNport->ntmode) { - selchannel = (struct select_channel *)malloc(sizeof(struct select_channel)); - if (!selchannel) - { - PERROR("No memory!"); - return; - } + selchannelp = &(selchannel->next); + selchannel = (struct select_channel *)MALLOC(sizeof(struct select_channel)); memuse++; - memset(*selchannelp, 0, sizeof(struct select_channel)); - *selchannelp->channel = SEL_CHANNEL_ANY; - selchannelp = &ifport->selchannel; - while(*selchannelp) - selchannelp = &((*selchannelp)->next); + selchannel->channel = CHANNEL_NO; // call waiting *selchannelp = selchannel; - return(0); } +} - /* channel selection for NT-ports */ - selchannel = (struct select_channel *)malloc(sizeof(struct select_channel)); - if (!selchannel) - { - PERROR("No memory!"); - return; - } + +/* set default in_channel */ +void default_in_channel(struct interface_port *ifport) +{ + struct select_channel *selchannel; + + selchannel = (struct select_channel *)MALLOC(sizeof(struct select_channel)); memuse++; - memset(*selchannelp, 0, sizeof(struct select_channel)); - *selchannelp->channel = SEL_CHANNEL_FREE; - selchannelp = &ifport->selchannel; - while(*selchannelp) - selchannelp = &((*selchannelp)->next); - *selchannelp = selchannel; - - /* additional channel selection for multipoint ports */ - if (!ifport->mISDNport->ptp) - { - selchannel = (struct select_channel *)malloc(sizeof(struct select_channel)); - if (!selchannel) - { - PERROR("No memory!"); - return; - } - memuse++; - memset(*selchannelp, 0, sizeof(struct select_channel)); - *selchannelp->channel = SEL_CHANNEL_NO; // call waiting - selchannelp = &ifport->selchannel; - while(*selchannelp) - selchannelp = &((*selchannelp)->next); - *selchannelp = selchannel; - } + + selchannel->channel = CHANNEL_FREE; + + ifport->in_channel = selchannel; } @@ -256,7 +238,6 @@ static int inter_port(struct interface *interface, char *filename, int line, cha { struct interface_port *ifport, **ifportp; struct interface *searchif; - struct interface_port *searchport; int val; val = get_number(value); @@ -269,7 +250,7 @@ static int inter_port(struct interface *interface, char *filename, int line, cha searchif = interface_newlist; while(searchif) { - searchport = searchif->ifport; + ifport = searchif->ifport; while(ifport) { if (ifport->portnum == val) @@ -282,14 +263,8 @@ static int inter_port(struct interface *interface, char *filename, int line, cha searchif = searchif->next; } /* alloc port substructure */ - ifport = (struct interface_port *)malloc(sizeof(struct interface_port)); - if (!ifport) - { - SPRINT(interface_error, "No memory!"); - return(-1); - } + ifport = (struct interface_port *)MALLOC(sizeof(struct interface_port)); memuse++; - memset(ifport, 0, sizeof(struct interface_port)); ifport->interface = interface; /* set value */ ifport->portnum = val; @@ -325,7 +300,7 @@ static int inter_channel_out(struct interface *interface, char *filename, int li if (!strcasecmp(el, "force")) { ifport->channel_force = 1; - if (ifport->selchannel) + if (ifport->out_channel) { SPRINT(interface_error, "Error in %s (line %d): value 'force' may only appear as first element in list.\n", filename, line); return(-1); @@ -333,17 +308,17 @@ static int inter_channel_out(struct interface *interface, char *filename, int li } else if (!strcasecmp(el, "any")) { - val = SEL_CHANNEL_ANY; + val = CHANNEL_ANY; goto selchannel; } else if (!strcasecmp(el, "free")) { - val = SEL_CHANNEL_FREE; + val = CHANNEL_FREE; goto selchannel; } else if (!strcasecmp(el, "no")) { - val = SEL_CHANNEL_NO; + val = CHANNEL_NO; goto selchannel; } else { @@ -361,18 +336,12 @@ static int inter_channel_out(struct interface *interface, char *filename, int li } selchannel: /* add to select-channel list */ - selchannel = (struct select_channel *)malloc(sizeof(struct select_channel)); - if (!selchannel) - { - SPRINT(interface_error, "No memory!"); - return(-1); - } + selchannel = (struct select_channel *)MALLOC(sizeof(struct select_channel)); memuse++; - memset(selchannel, 0, sizeof(struct select_channel)); /* set value */ selchannel->channel = val; /* tail port */ - selchannelp = &ifport->selchannel; + selchannelp = &ifport->out_channel; while(*selchannelp) selchannelp = &((*selchannelp)->next); *selchannelp = selchannel; @@ -402,14 +371,14 @@ static int inter_channel_in(struct interface *interface, char *filename, int lin { el = p; p = get_seperated(p); - if (ifport->in_select) if (ifport->in_select->channel == SEL_CHANNEL_FREE) + if (ifport->in_channel) if (ifport->in_channel->channel == CHANNEL_FREE) { SPRINT(interface_error, "Error in %s (line %d): parameter '%s' has values behind 'free' keyword. They has no effect.\n", filename, line, parameter); return(-1); } if (!strcasecmp(el, "free")) { - val = SEL_CHANNEL_FREE; + val = CHANNEL_FREE; goto selchannel; } else { @@ -427,18 +396,12 @@ static int inter_channel_in(struct interface *interface, char *filename, int lin } selchannel: /* add to select-channel list */ - selchannel = (struct select_channel *)malloc(sizeof(struct select_channel)); - if (!selchannel) - { - SPRINT(interface_error, "No memory!"); - return(-1); - } + selchannel = (struct select_channel *)MALLOC(sizeof(struct select_channel)); memuse++; - memset(selchannel, 0, sizeof(struct select_channel)); /* set value */ selchannel->channel = val; /* tail port */ - selchannelp = &ifport->in_select; + selchannelp = &ifport->in_channel; while(*selchannelp) selchannelp = &((*selchannelp)->next); *selchannelp = selchannel; @@ -469,14 +432,8 @@ static int inter_msn(struct interface *interface, char *filename, int line, char el = p; p = get_seperated(p); /* add MSN to list */ - ifmsn = (struct interface_msn *)malloc(sizeof(struct interface_msn)); - if (!ifmsn) - { - SPRINT(interface_error, "No memory!"); - return(-1); - } + ifmsn = (struct interface_msn *)MALLOC(sizeof(struct interface_msn)); memuse++; - memset(ifmsn, 0, sizeof(struct interface_msn)); /* set value */ SCPY(ifmsn->msn, el); /* tail port */ @@ -501,15 +458,10 @@ static int inter_screen(struct interface_screen **ifscreenp, struct interface *i el = p; p = get_seperated(p); /* add screen entry to list*/ - ifscreen = (struct interface_screen *)malloc(sizeof(struct interface_screen)); - if (!ifscreen) - { - SPRINT(interface_error, "No memory!"); - return(-1); - } + ifscreen = (struct interface_screen *)MALLOC(sizeof(struct interface_screen)); memuse++; - memset(ifscreen, 0, sizeof(struct interface_screen)); -#warning handle unchanged as unchanged!! + ifscreen->match_type = -1; /* unchecked */ + ifscreen->match_present = -1; /* unchecked */ ifscreen->result_type = -1; /* unchanged */ ifscreen->result_present = -1; /* unchanged */ /* tail port */ @@ -554,7 +506,7 @@ static int inter_screen(struct interface_screen **ifscreenp, struct interface *i if (ifscreen->match_present != -1) { presenterror: - SPRINT(interface_error, "Error in %s (line %d): presentation type already set earlier.\n", filename, line, parameter); + SPRINT(interface_error, "Error in %s (line %d): presentation type already set earlier.\n", filename, line); return(-1); } ifscreen->match_present = INFO_PRESENT_ALLOWED; @@ -566,6 +518,15 @@ static int inter_screen(struct interface_screen **ifscreenp, struct interface *i ifscreen->match_present = INFO_PRESENT_RESTRICTED; } else { SCPY(ifscreen->match, el); + /* check for % at the end */ + if (strchr(el, '%')) + { + if (strchr(el, '%') != el+strlen(el)-1) + { + SPRINT(interface_error, "Error in %s (line %d): %% joker found, but must at the end.\n", filename, line, parameter); + return(-1); + } + } break; } } @@ -616,6 +577,15 @@ static int inter_screen(struct interface_screen **ifscreenp, struct interface *i ifscreen->result_present = INFO_PRESENT_RESTRICTED; } else { SCPY(ifscreen->result, el); + /* check for % at the end */ + if (strchr(el, '%')) + { + if (strchr(el, '%') != el+strlen(el)-1) + { + SPRINT(interface_error, "Error in %s (line %d): %% joker found, but must at the end.\n", filename, line, parameter); + return(-1); + } + } break; } } @@ -640,11 +610,30 @@ static int inter_screen_out(struct interface *interface, char *filename, int lin { return(inter_screen(&interface->ifscreen_out, interface, filename, line, parameter, value)); } -static int inter_filter(struct interface *interface, char *filename, int line, char *parameter, char *value) +static int inter_nodtmf(struct interface *interface, char *filename, int line, char *parameter, char *value) { + struct interface_port *ifport; + + /* port in chain ? */ + if (!interface->ifport) + { + SPRINT(interface_error, "Error in %s (line %d): parameter '%s' expects previous 'port' definition.\n", filename, line, parameter); + return(-1); + } + /* goto end of chain */ + ifport = interface->ifport; + while(ifport->next) + ifport = ifport->next; + ifport->nodtmf = 1; + return(0); +} #warning filter to be done +#if 0 +static int inter_filter(struct interface *interface, char *filename, int line, char *parameter, char *value) +{ return(0); } +#endif /* @@ -679,7 +668,7 @@ struct interface_param interface_param[] = { "This is required on PRI NT-mode ports that are point-to-point by default.\n" "This parameter must follow a 'port' parameter."}, - {"channel_out", &inter_channel_out, "[force,][][,...][,free][,any][,no]", + {"channel-out", &inter_channel_out, "[force,][][,...][,free][,any][,no]", "Channel selection list for all outgoing calls to the interface.\n" "A free channels is searched in order of appearance.\n" "This parameter must follow a 'port' parameter.\n" @@ -689,13 +678,13 @@ struct interface_param interface_param[] = { " any - On outgoing calls, signal 'any channel acceptable'. (see DSS1)\n" " no - Signal 'no channel available' aka 'call waiting'. (see DSS1)"}, - {"channel_in", &inter_channel_in, "[force,][][,...][,free][,any][,no]", + {"channel-in", &inter_channel_in, "[force,][][,...][,free][,any][,no]", "Channel selection list for all incomming calls from the interface.\n" "A free channels is accepted if in the list.\n" - "If no channel was requested, the first free channel found is selected.\n" + "If any channel was requested, the first free channel found is selected.\n" "This parameter must follow a 'port' parameter.\n" " [,...] - List of channels to accept.\n" - " free - Accept any free channel\n" + " free - Accept any free channel"}, {"msn", &inter_msn, ",[[,...]]", "Incomming caller ID is checked against given MSN numbers.\n" @@ -716,10 +705,17 @@ struct interface_param interface_param[] = { "Adds an entry for outgoing calls to the caller ID screen list.\n" "See 'screen-in' for help."}, + {"nodtmf", &inter_nodtmf, "", + "Disables DTMF detection for this interface.\n" + "This parameter must follow a 'port' parameter."}, + +#if 0 +#warning todo: filter, also in the PmISDN object {"filter", &inter_filter, " [parameters]", "Adds/appends a filter. Filters are ordered in transmit direction.\n" "gain - Changes volume (-8 .. 8)\n" "blowfish - Adds encryption. Key must be 4-56 bytes (8-112 hex characters."}, +#endif {NULL, NULL, NULL, NULL} }; @@ -744,10 +740,7 @@ struct interface *read_interfaces(void) struct interface_param *ifparam; if (interface_newlist != NULL) - { - PERROR("software error, list is not empty.\n"); - exit(-1); - } + FATAL("list is not empty.\n"); interface_error[0] = '\0'; SPRINT(filename, "%s/interface.conf", INSTALL_DATA); @@ -838,7 +831,7 @@ struct interface *read_interfaces(void) parameter[strlen(parameter)-1] = '\0'; /* check if interface name already exists */ - interface = interface_first; + interface = interface_newlist; while(interface) { if (!strcasecmp(interface->name, parameter+1)) @@ -850,14 +843,8 @@ struct interface *read_interfaces(void) } /* append interface to new list */ - interface = (struct interface *)malloc(sizeof(struct interface)); - if (!interface) - { - SPRINT(interface_error, "No memory!"); - goto error; - } + interface = (struct interface *)MALLOC(sizeof(struct interface)); memuse++; - memset(interface, 0, sizeof(struct interface)); /* name interface */ SCPY(interface->name, parameter+1); @@ -876,10 +863,12 @@ struct interface *read_interfaces(void) { if (ifparam->func(interface, filename, line, parameter, value)) goto error; - continue; + break; } ifparam++; } + if (ifparam->name) + continue; SPRINT(interface_error, "Error in %s (line %d): unknown parameter: '%s'.\n", filename, line, parameter); goto error; @@ -918,8 +907,7 @@ void free_interfaces(struct interface *interface) { temp = selchannel; selchannel = selchannel->next; - memset(temp, 0, sizeof(struct select_channel)); - free(temp); + FREE(temp, sizeof(struct select_channel)); memuse--; } selchannel = ifport->out_channel; @@ -927,14 +915,12 @@ void free_interfaces(struct interface *interface) { temp = selchannel; selchannel = selchannel->next; - memset(temp, 0, sizeof(struct select_channel)); - free(temp); + FREE(temp, sizeof(struct select_channel)); memuse--; } temp = ifport; ifport = ifport->next; - memset(temp, 0, sizeof(struct interface_port)); - free(temp); + FREE(temp, sizeof(struct interface_port)); memuse--; } ifmsn = interface->ifmsn; @@ -942,8 +928,7 @@ void free_interfaces(struct interface *interface) { temp = ifmsn; ifmsn = ifmsn->next; - memset(temp, 0, sizeof(struct interface_msn)); - free(temp); + FREE(temp, sizeof(struct interface_msn)); memuse--; } ifscreen = interface->ifscreen_in; @@ -951,8 +936,7 @@ void free_interfaces(struct interface *interface) { temp = ifscreen; ifscreen = ifscreen->next; - memset(temp, 0, sizeof(struct interface_screen)); - free(temp); + FREE(temp, sizeof(struct interface_screen)); memuse--; } ifscreen = interface->ifscreen_out; @@ -960,8 +944,7 @@ void free_interfaces(struct interface *interface) { temp = ifscreen; ifscreen = ifscreen->next; - memset(temp, 0, sizeof(struct interface_screen)); - free(temp); + FREE(temp, sizeof(struct interface_screen)); memuse--; } iffilter = interface->iffilter; @@ -969,18 +952,43 @@ void free_interfaces(struct interface *interface) { temp = iffilter; iffilter = iffilter->next; - memset(temp, 0, sizeof(struct interface_filter)); - free(temp); + FREE(temp, sizeof(struct interface_filter)); memuse--; } temp = interface; interface = interface->next; - memset(temp, 0, sizeof(struct interface)); - free(temp); + FREE(temp, sizeof(struct interface)); memuse--; } } +/* + * defaults of ports if not specified by config + */ +static void set_defaults(struct interface_port *ifport) +{ + /* default channel selection list */ + if (!ifport->out_channel) + default_out_channel(ifport); + if (!ifport->in_channel) + default_in_channel(ifport); + /* default is_tones */ + if (ifport->interface->is_tones) + ifport->mISDNport->tones = (ifport->interface->is_tones==IS_YES); + else + ifport->mISDNport->tones = (ifport->mISDNport->ntmode)?1:0; + /* default is_earlyb */ + if (ifport->interface->is_earlyb) + ifport->mISDNport->earlyb = (ifport->interface->is_earlyb==IS_YES); + else + ifport->mISDNport->earlyb = (ifport->mISDNport->ntmode)?0:1; + /* set locally flag */ + if (ifport->interface->extension) + ifport->mISDNport->locally = 1; + else + ifport->mISDNport->locally = 0; +} + /* * all links between mISDNport and interface are made @@ -1015,6 +1023,7 @@ void relink_interfaces(void) { ifport->mISDNport = mISDNport; mISDNport->ifport = ifport; + set_defaults(ifport); } mISDNport = mISDNport->next; } @@ -1047,36 +1056,37 @@ void relink_interfaces(void) { if (!ifport->mISDNport) { - /* open new port */ - mISDNport = mISDNport_open(ifport->portnum, ifport->ptp, ifport->ptmp); - if (mISDNport) - { - ifport->mISDNport = mISDNport; - mISDNport->ifport = ifport; - } - } - if (ifport->mISDNport) - { - /* default channel selection list */ - if (!ifport->selchannel) - default_selchannel(ifport); - /* default is_tones */ - if (ifport->interface->is_tones) - ifport->mISDNport->is_tones = (ifport->interface->is_tones==IS_YES); - else - ifport->mISDNport->is_tones = (ifport->mISDNport->ntmode)?1:0; - /* default is_earlyb */ - if (ifport->interface->is_earlyb) - ifport->mISDNport->is_earlyb = (ifport->interface->is_earlyb==IS_YES); - else - ifport->mISDNport->is_earlyb = (ifport->mISDNport->ntmode)?0:1; + load_port(ifport); } + ifport = ifport->next; } interface = interface->next; } } + +/* + * load port + */ +void load_port(struct interface_port *ifport) +{ + struct mISDNport *mISDNport; + + /* open new port */ + mISDNport = mISDNport_open(ifport->portnum, ifport->ptp, ifport->ptmp, ifport->interface); + if (mISDNport) + { + /* link port */ + ifport->mISDNport = mISDNport; + mISDNport->ifport = ifport; + set_defaults(ifport); + } else + { + ifport->block = 2; /* not available */ + } +} + /* * give summary of interface syntax */ @@ -1104,4 +1114,3 @@ void doc_interface(void) } } -