/* Copy in a set of routing entries.
 *
 * `routes` should be an array of `_if_routes` preceded with a single word
 * indicating the number of entries.
 */
void input_filtering_get_routes(if_collection_t *filters, uint32_t *routes)
{
  // Copy in the number of routing entries
  filters->n_routes = routes[0];
  routes++;  // Advance the pointer to the first entry
  debug("Loading %d filter routes\n", filters->n_routes);

  // Malloc sufficient room for the entries
  MALLOC_OR_DIE(filters->routes, filters->n_routes * sizeof(if_route_t));

  // Copy the entries across
  spin1_memcpy(filters->routes, routes,
               filters->n_routes * sizeof(if_route_t));

  // DEBUG: Print the route entries
#ifdef DEBUG
  for (uint32_t n = 0; n < filters->n_routes; n++)
  {
    io_printf(IO_BUF, "\tRoute[%d] = (0x%08x, 0x%08x) dmask=0x%08x => %d\n",
              n, filters->routes[n].key, filters->routes[n].mask,
              filters->routes[n].dimension_mask,
              filters->routes[n].input_index);
  }
#endif
}
void _lti_filter_init(void *p, if_filter_t *filter, uint32_t size)
{
  // Cast the parameters block
  struct _lti_filter_init_params *params = \
    (struct _lti_filter_init_params *) p;

  // Malloc space for the parameters
  MALLOC_OR_DIE(filter->state, sizeof(lti_state_t));

  lti_state_t *state = (lti_state_t *) filter->state;
  state->order = params->order;

  debug(">> LTI Filter of order %d", state->order);
  MALLOC_OR_DIE(state->abs, sizeof(ab_t) * state->order);

  // Malloc space for the state
  MALLOC_OR_DIE(state->xyz, sizeof(ab_t) * state->order * size);

  // Copy the parameters across
  value_t *data = &params->data;
  spin1_memcpy(state->abs, data, sizeof(ab_t) * state->order);

  // If debugging then print out all filter parameters
#ifdef DEBUG
  for (uint32_t k = 0; k < state->order; k++)
  {
    io_printf(IO_BUF, "a[%d] = %k, b[%d] = %k\n",
              state->abs[k].a, state->abs[k].b);
  }
#endif

  // Zero all the state holding variables
  state->n = 0;
  memset(state->xyz, 0, sizeof(ab_t) * size * state->order);

  // Store a reference to the correct step function for the filter.  Insert any
  // specially optimised filters here.
  filter->step = _lti_filter_step;
}
void _lowpass_filter_init(void *params, if_filter_t *filter,
                          uint32_t size)
{
  use(size);

  // Copy the filter parameters into memory
  MALLOC_OR_DIE(filter->state, sizeof(lowpass_state_t));
  spin1_memcpy(filter->state, params, sizeof(lowpass_state_t));

  debug(">> Lowpass filter (%k, %k)\n",
            ((lowpass_state_t *)filter->state)->a,
            ((lowpass_state_t *)filter->state)->b);

  // Store a reference to the step function
  filter->step = _lowpass_filter_step;
}
/* Initialise a filter collection with an output accumulator.
 *
 * Use zero to indicate that no output accumulator should be assigned.
 */
void input_filtering_initialise_output(if_collection_t *filters,
                                       uint32_t n_dimensions)
{
  // Store the output size
  filters->output_size = n_dimensions;

  // If the output size is zero then don't allocate an accumulator, otherwise
  // malloc sufficient space.
  if (n_dimensions == 0)
  {
    filters->output = NULL;
  }
  else
  {
    MALLOC_OR_DIE(filters->output, sizeof(value_t) * n_dimensions);
  }
}
/* Copy in a set of filters.
 *
 * The first word of `filters` should indicate how many entries there are.  The
 * first word of each entry should indicate the length of the entry.  Each
 * entry should be a `filter_parameters_t` with some following words which can
 * be interpreted by the appropriate initialisation function.
 * If signal_output_array is specified it should contain a pre-allocated
 * output array for each filter
 */
void input_filtering_get_filters(if_collection_t *filters, uint32_t *data,
  value_t **filter_output_array)
{
  // Get the number of filters and malloc sufficient space for the filter
  // parameters.
  filters->n_filters = data[0];
  MALLOC_OR_DIE(filters->filters, filters->n_filters * sizeof(if_filter_t));

  debug("Loading %d filters\n", filters->n_filters);

  // Move the "filters" pointer to the first element
  data++;

  // Allow casting filters pointer to a _filter_parameters pointer
  filter_parameters_t *params;

  // Initialise each filter in turn
  for (uint32_t f = 0; f < filters->n_filters; f++)
  {
    // Get the parameters
    params = (filter_parameters_t *) data;

    // Get the size of the filter, store it
    filters->filters[f].size = params->size;

    debug("> Filter [%d] size = %d\n", f, params->size);

    // Initialise the input accumulator
    MALLOC_OR_DIE(filters->filters[f].input, sizeof(if_accumulator_t));
    MALLOC_OR_DIE(filters->filters[f].input->value,
                  sizeof(value_t)*params->size);
    filters->filters[f].input->mask = (params->flags & (1 << LATCHING)) ?
                                      0x00000000 : 0xffffffff;

    // If no filter output array is specified, allocate new vector
    if(filter_output_array == NULL)
    {
      MALLOC_OR_DIE(filters->filters[f].output,
                    sizeof(value_t) * params->size);
    }
    // Otherwise, copy output pointer into filter
    else
    {
      filters->filters[f].output = filter_output_array[f];
    }

    // Zero the input and the output
    memset(filters->filters[f].input->value, 0,
           sizeof(value_t) * params->size);
    memset(filters->filters[f].output, 0, sizeof(value_t) * params->size);

    // Initialise the filter itself
    filter_types[params->init_method]((void *) &params->data,
                                      &filters->filters[f],
                                      params->size);

    // Progress to the next filter, 4 is the number of actual elements in a
    // `filter_parameters_t` (because `->data` is word 0 of the specific filter
    // parameters).
    data += params->n_words + 4;
  }
}
示例#6
0
void
netsnmp_parse_override(const char *token, char *line)
{
    char           *cp;
    char            buf[SNMP_MAXBUF], namebuf[SNMP_MAXBUF];
    int             readwrite = 0;
    oid             oidbuf[MAX_OID_LEN];
    size_t          oidbuf_len = MAX_OID_LEN;
    int             type;
    override_data  *thedata;
    netsnmp_handler_registration *the_reg;

    cp = copy_nword(line, namebuf, sizeof(namebuf) - 1);
    if (strcmp(namebuf, "-rw") == 0) {
        readwrite = 1;
        cp = copy_nword(cp, namebuf, sizeof(namebuf) - 1);
    }

    if (!cp) {
        config_perror("no oid specified");
        return;
    }

    if (!snmp_parse_oid(namebuf, oidbuf, &oidbuf_len)) {
        config_perror("illegal oid");
        return;
    }
    cp = copy_nword(cp, buf, sizeof(buf) - 1);

    if (!cp && strcmp(buf, "null") != 0) {
        config_perror("no variable value specified");
        return;
    }

    {
        struct { const char* key; int value; } const strings[] = {
            { "counter", ASN_COUNTER },
            { "counter64", ASN_COUNTER64 },
            { "integer", ASN_INTEGER },
            { "ipaddress", ASN_IPADDRESS },
            { "nsap", ASN_NSAP },
            { "null", ASN_NULL },
            { "object_id", ASN_OBJECT_ID },
            { "octet_str", ASN_OCTET_STR },
            { "opaque", ASN_OPAQUE },
#ifdef NETSNMP_WITH_OPAQUE_SPECIAL_TYPES
            { "opaque_counter64", ASN_OPAQUE_COUNTER64 },
            { "opaque_double", ASN_OPAQUE_DOUBLE },
            { "opaque_float", ASN_OPAQUE_FLOAT },
            { "opaque_i64", ASN_OPAQUE_I64 },
            { "opaque_u64", ASN_OPAQUE_U64 },
#endif
            { "timeticks", ASN_TIMETICKS },
            { "uinteger", ASN_GAUGE },
            { "unsigned", ASN_UNSIGNED },
            { NULL, 0 }
        }, * run;
        for(run = strings; run->key && strcasecmp(run->key, buf) < 0; ++run);
        if(run->key && strcasecmp(run->key, buf) == 0)
            type = run->value;
        else {
            config_perror("unknown type specified");
            return;
        }
    }

    if (cp)
        copy_nword(cp, buf, sizeof(buf) - 1);
    else
        buf[0] = 0;

    thedata = SNMP_MALLOC_TYPEDEF(override_data);
    if (!thedata) {
        config_perror("memory allocation failure");
        return;
    }
    thedata->type = type;

    switch (type) {
    case ASN_INTEGER:
        MALLOC_OR_DIE(sizeof(long));
        *((long *) thedata->value) = strtol(buf, NULL, 0);
        break;

    case ASN_COUNTER:
    case ASN_TIMETICKS:
    case ASN_UNSIGNED:
        MALLOC_OR_DIE(sizeof(u_long));
        *((u_long *) thedata->value) = strtoul(buf, NULL, 0);
        break;

    case ASN_OCTET_STR:
    case ASN_BIT_STR:
        if (buf[0] == '0' && buf[1] == 'x') {
            /*
             * hex 
             */
            thedata->value_len =
                hex_to_binary2((u_char *)(buf + 2), strlen(buf) - 2,
                               (char **) &thedata->value);
        } else {
            thedata->value = strdup(buf);
            thedata->value_len = strlen(buf);
        }
        break;

    case ASN_OBJECT_ID:
        read_config_read_objid(buf, (oid **) & thedata->value,
                               &thedata->value_len);
        break;

    case ASN_NULL:
        thedata->value_len = 0;
        break;

    default:
        SNMP_FREE(thedata);
        config_perror("illegal/unsupported type specified");
        return;
    }

    if (!thedata->value && thedata->type != ASN_NULL) {
        config_perror("memory allocation failure");
        free(thedata);
        return;
    }

    the_reg = SNMP_MALLOC_TYPEDEF(netsnmp_handler_registration);
    if (!the_reg) {
        config_perror("memory allocation failure");
        free(thedata);
        return;
    }

    the_reg->handlerName = strdup(namebuf);
    the_reg->priority = 255;
    the_reg->modes = (readwrite) ? HANDLER_CAN_RWRITE : HANDLER_CAN_RONLY;
    the_reg->handler =
        netsnmp_create_handler("override", override_handler);
    the_reg->rootoid = snmp_duplicate_objid(oidbuf, oidbuf_len);
    the_reg->rootoid_len = oidbuf_len;
    if (!the_reg->rootoid || !the_reg->handler || !the_reg->handlerName) {
        if (the_reg->handler)
            SNMP_FREE(the_reg->handler->handler_name);
        SNMP_FREE(the_reg->handler);
        SNMP_FREE(the_reg->handlerName);
        SNMP_FREE(the_reg);
        config_perror("memory allocation failure");
        free(thedata);
        return;
    }
    the_reg->handler->myvoid = thedata;

    if (netsnmp_register_instance(the_reg)) {
        config_perror("oid registration failed within the agent");
        SNMP_FREE(thedata->value);
        free(thedata);
        return;
    }
}