added filter options (gain, pipeline, blowfish) to interface configuration.
[lcr.git] / interface.c
index 1c0956b..b2995ff 100644 (file)
@@ -479,9 +479,6 @@ static int inter_screen(struct interface_screen **ifscreenp, struct interface *i
                SPRINT(interface_error, "Error in %s (line %d): parameter '%s' expects old caller ID and new caller ID.\n", filename, line, parameter);
                return(-1);
        }
-       p = value;
-       el = p;
-       p = get_seperated(p);
        /* add screen entry to list*/
        ifscreen = (struct interface_screen *)MALLOC(sizeof(struct interface_screen));
        memuse++;
@@ -493,7 +490,9 @@ static int inter_screen(struct interface_screen **ifscreenp, struct interface *i
        while(*ifscreenp)
                ifscreenp = &((*ifscreenp)->next);
        *ifscreenp = ifscreen;
+//     printf("interface=%s\n", interface->name);
        /* get match */
+       p = value;
        while(*p)
        {
                el = p;
@@ -536,7 +535,7 @@ static int inter_screen(struct interface_screen **ifscreenp, struct interface *i
                        }
                        ifscreen->match_present = INFO_PRESENT_ALLOWED;
                } else
-               if (!strcasecmp(el, "restricted"))
+               if (!strcasecmp(el, "restrict") || !strcasecmp(el, "restricted"))
                {
                        if (ifscreen->match_present != -1)
                                goto presenterror;
@@ -595,7 +594,7 @@ static int inter_screen(struct interface_screen **ifscreenp, struct interface *i
                                goto presenterror;
                        ifscreen->result_present = INFO_PRESENT_ALLOWED;
                } else
-               if (!strcasecmp(el, "restricted"))
+               if (!strcasecmp(el, "restrict") || !strcasecmp(el, "restricted"))
                {
                        if (ifscreen->result_present != -1)
                                goto presenterror;
@@ -652,13 +651,116 @@ static int inter_nodtmf(struct interface *interface, char *filename, int line, c
        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)
 {
+       char *p, *q;
+
+       /* seperate parameter from filter */
+       p = value;
+       while(*p > 32)
+               p++;
+       if (*p)
+       {
+               *p++ = 0;
+               while(*p > 0 && *p <= 32)
+                       p++;
+       }
+
+       if (!strcasecmp(value, "gain"))
+       {
+               q = p;
+               while(*q > 32)
+                       q++;
+               if (*q)
+               {
+                       *q++ = 0;
+                       while(*q > 0 && *q <= 32)
+                               q++;
+               }
+               if (*p == 0 || *q == 0)
+               {
+                       SPRINT(interface_error, "Error in %s (line %d): parameter '%s %s' expects two gain values.\n", filename, line, parameter, value);
+                       return(-1);
+               }
+               if (atoi(p)<-8 || atoi(p)>8 || atoi(q)<-8 || atoi(q)>8)
+               {
+                       SPRINT(interface_error, "Error in %s (line %d): parameter '%s %s' gain values not in range. (-8...8)\n", filename, line, parameter, value);
+                       return(-1);
+               }
+               interface->gain_tx = atoi(p);
+               interface->gain_rx = atoi(q);
+       } else
+       if (!strcasecmp(value, "pipeline"))
+       {
+               if (*p == 0)
+               {
+                       SPRINT(interface_error, "Error in %s (line %d): parameter '%s %s' expects pipeline string.\n", filename, line, parameter, value);
+                       return(-1);
+               }
+               SCPY(interface->pipeline, p);
+       } else
+       if (!strcasecmp(value, "blowfish"))
+       {
+               unsigned char key[56];
+               int l;
+               
+               if (!!strncmp(p, "0x", 2))
+               {
+                       SPRINT(interface_error, "Error in %s (line %d): parameter '%s %s' expects blowfish key starting with '0x'.\n", filename, line, parameter, value);
+                       return(-1);
+               }
+               p += 2;
+               l = 0; 
+               while(*p)
+               {
+                       if (l == 56)
+                       {
+                               SPRINT(interface_error, "Error in %s (line %d): parameter '%s %s' key too long.\n", filename, line, parameter, value);
+                               return(-1);
+                       }
+                       if (*p >= '0' && *p <= '9')
+                               key[l] = (*p-'0')<<4;
+                       else if (*p >= 'a' && *p <= 'f')
+                               key[l] = (*p-'a'+10)<<4;
+                       else if (*p >= 'A' && *p <= 'F')
+                               key[l] = (*p-'A'+10)<<4;
+                       else
+                       {
+                               digout:
+                               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);
+                               return(-1);
+                       }
+                       p++;
+                       if (*p == 0)
+                       {
+                               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);
+                               return(-1);
+                       }
+                       if (*p >= '0' && *p <= '9')
+                               key[l] = (*p-'0')<<4;
+                       else if (*p >= 'a' && *p <= 'f')
+                               key[l] = (*p-'a'+10)<<4;
+                       else if (*p >= 'A' && *p <= 'F')
+                               key[l] = (*p-'A'+10)<<4;
+                       else
+                               goto digout;
+                       p++;
+                       l++;
+               }
+               if (l < 4)
+               {
+                       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);
+                       return(-1);
+               }
+               memcpy(interface->bf_key, key, l);
+               interface->bf_len = l;
+       } else
+       {
+               SPRINT(interface_error, "Error in %s (line %d): parameter '%s' has unknown filter '%s'.\n", filename, line, parameter, value);
+               return(-1);
+       }
        return(0);
 }
-#endif
 
 
 /*
@@ -743,12 +845,17 @@ struct interface_param interface_param[] = {
        "This parameter must follow a 'port' parameter."},
 
 #if 0
-#warning todo: filter, also in the PmISDN object
-       {"filter", &inter_filter, "<filter> [parameters]",
+       {"layer2keep", &inter_layer2keep, "yes | no",
+       "By default, layer 2 is establised and kept up on PTP interfaces.\n"
+       ".\n"
+       "This parameter must follow a 'port' parameter."},
+#endif
+
+       {"filter", &inter_filter, "<filter> <parameters>",
        "Adds/appends a filter. Filters are ordered in transmit direction.\n"
        "gain <tx-volume> <rx-volume> - Changes volume (-8 .. 8)\n"
+       "pipeline <string> - Sets echo cancelation pipeline.\n"
        "blowfish <key> - Adds encryption. Key must be 4-56 bytes (8-112 hex characters."},
-#endif
 
        {NULL, NULL, NULL, NULL}
 };
@@ -928,7 +1035,6 @@ void free_interfaces(struct interface *interface)
        struct select_channel *selchannel;
        struct interface_msn *ifmsn;
        struct interface_screen *ifscreen;
-       struct interface_filter *iffilter;
 
        while(interface)
        {
@@ -980,14 +1086,6 @@ void free_interfaces(struct interface *interface)
                        FREE(temp, sizeof(struct interface_screen));
                        memuse--;
                }
-               iffilter = interface->iffilter;
-               while(iffilter)
-               {
-                       temp = iffilter;
-                       iffilter = iffilter->next;
-                       FREE(temp, sizeof(struct interface_filter));
-                       memuse--;
-               }
                temp = interface;
                interface = interface->next;
                FREE(temp, sizeof(struct interface));
@@ -1147,3 +1245,156 @@ void doc_interface(void)
        }
 }
 
+
+/* screen caller id
+ * out==0: incomming caller id, out==1: outgoing caller id
+ */
+void do_screen(int out, char *id, int idsize, int *type, int *present, struct interface *interface)
+{
+       char                    *msn1;
+       struct interface_msn    *ifmsn;
+       struct interface_screen *ifscreen;
+       char suffix[64];
+
+       /* screen incoming caller id */
+       if (!out)
+       {
+               /* check for MSN numbers, use first MSN if no match */
+               msn1 = NULL;
+               ifmsn = interface->ifmsn;
+               while(ifmsn)
+               {
+                       if (!msn1)
+                               msn1 = ifmsn->msn;
+                       if (!strcmp(ifmsn->msn, id))
+                       {
+                               break;
+                       }
+                       ifmsn = ifmsn->next;
+               }
+               if (ifmsn)
+               {
+                       start_trace(0, interface, numberrize_callerinfo(id, *type), NULL, DIRECTION_IN, 0, 0, "SCREEN (fount in MSN list)");
+                       add_trace("msn", NULL, "%s", id);
+                       end_trace();
+               }
+               if (!ifmsn && msn1) // not in list, first msn given
+               {
+                       start_trace(0, interface, numberrize_callerinfo(id, *type), NULL, DIRECTION_IN, 0, 0, "SCREEN (not fount in MSN list)");
+                       add_trace("msn", "given", "%s", id);
+                       add_trace("msn", "used", "%s", msn1);
+                       end_trace();
+                       UNCPY(id, msn1, idsize);
+                       id[idsize-1] = '\0';
+               }
+       }
+
+       /* check screen list */
+       if (out)
+               ifscreen = interface->ifscreen_out;
+       else
+               ifscreen = interface->ifscreen_in;
+       while (ifscreen)
+       {
+               if (ifscreen->match_type==-1 || ifscreen->match_type==*type)
+               if (ifscreen->match_present==-1 || ifscreen->match_present==*present)
+               {
+                       if (strchr(ifscreen->match,'%'))
+                       {
+                               if (!strncmp(ifscreen->match, id, strchr(ifscreen->match,'%')-ifscreen->match))
+                                       break;
+                       } else
+                       {
+                               if (!strcmp(ifscreen->match, id))
+                                       break;
+                       }
+               }
+               ifscreen = ifscreen->next;
+       }
+       if (ifscreen) // match
+       {
+               start_trace(0, interface, numberrize_callerinfo(id, *type), NULL, out?DIRECTION_OUT:DIRECTION_IN, 0, 0, "SCREEN (fount in screen list)");
+               switch(*type)
+               {
+                       case INFO_NTYPE_UNKNOWN:
+                       add_trace("given", "type", "unknown");
+                       break;
+                       case INFO_NTYPE_SUBSCRIBER:
+                       add_trace("given", "type", "subscriber");
+                       break;
+                       case INFO_NTYPE_NATIONAL:
+                       add_trace("given", "type", "national");
+                       break;
+                       case INFO_NTYPE_INTERNATIONAL:
+                       add_trace("given", "type", "international");
+                       break;
+               }
+               switch(*present)
+               {
+                       case INFO_PRESENT_ALLOWED:
+                       add_trace("given", "present", "allowed");
+                       break;
+                       case INFO_PRESENT_RESTRICTED:
+                       add_trace("given", "present", "restricted");
+                       break;
+                       case INFO_PRESENT_NOTAVAIL:
+                       add_trace("given", "present", "not available");
+                       break;
+               }
+               add_trace("given", "id", "%s", id[0]?id:"<empty>");
+               if (ifscreen->result_type != -1)
+               {
+                       *type = ifscreen->result_type;
+                       switch(*type)
+                       {
+                               case INFO_NTYPE_UNKNOWN:
+                               add_trace("used", "type", "unknown");
+                               break;
+                               case INFO_NTYPE_SUBSCRIBER:
+                               add_trace("used", "type", "subscriber");
+                               break;
+                               case INFO_NTYPE_NATIONAL:
+                               add_trace("used", "type", "national");
+                               break;
+                               case INFO_NTYPE_INTERNATIONAL:
+                               add_trace("used", "type", "international");
+                               break;
+                       }
+               }
+               if (ifscreen->result_present != -1)
+               {
+                       *present = ifscreen->result_present;
+                       switch(*present)
+                       {
+                               case INFO_PRESENT_ALLOWED:
+                               add_trace("used", "present", "allowed");
+                               break;
+                               case INFO_PRESENT_RESTRICTED:
+                               add_trace("used", "present", "restricted");
+                               break;
+                               case INFO_PRESENT_NOTAVAIL:
+                               add_trace("used", "present", "not available");
+                               break;
+                       }
+               }
+               if (strchr(ifscreen->match,'%'))
+               {
+                       SCPY(suffix, strchr(ifscreen->match,'%') - ifscreen->match + id);
+                       UNCPY(id, ifscreen->result, idsize);
+                       id[idsize-1] = '\0';
+                       if (strchr(id,'%'))
+                       {
+                               *strchr(id,'%') = '\0';
+                               UNCAT(id, suffix, idsize);
+                               id[idsize-1] = '\0';
+                       }
+               } else
+               {
+                       UNCPY(id, ifscreen->result, idsize);
+                       id[idsize-1] = '\0';
+               }
+               add_trace("used", "id", "%s", id[0]?id:"<empty>");
+               end_trace();
+       }
+}
+