RESOLVED BY implementing make_data_context 

    iinfo->make_data_context = context_convert_function;
. . .

    void * context_convert_function( void *loop_context, netsnmp_iterator_info 
*iinfo )    {        Context_Data *datactx = SNMP_MALLOC_TYPEDEF(Context_Data); 
       if (!datactx)            return NULL;        strncpy( datactx->L1line, 
L1.front().c_str(), 1000 );        datactx->len = L1.front().length();
        return datactx;    }


    On Thursday, January 5, 2023 at 02:28:49 p.m. EST, Ian C via Net-snmp-users 
<net-snmp-users@lists.sourceforge.net> wrote:  
 
 


I have a sub-agent which I'm hoping will handle snmpwalk requests.  Presently 
what is happening is that my get_first_data_point() reads a file (a QNX PPS 
object to be specific), each line in the file represents on table row. Each 
line is json-formatted and gets parsed to the field level.  Reading of the 
entire file happens once in get_first_data_point(), each line in that file then 
becomes a element within a std::list<std::string>


    typedef struct context_data_s {
        char L1line[1000];
        int len;
    } context_data;

    std::list<std::string> L1;

    void readL1PpsData()
    {
      ... For each line read do a 
      ... L1.push_back( line )
      ... all fine here
    }

    netsnmp_variable_list *
    inputSourcesInfoTable_get_first_data_point(void **my_loop_context,
                              void **my_data_context,
                              netsnmp_variable_list *put_index_data,
                              netsnmp_iterator_info *mydata)
    {
        DEBUGMSGTL(("SourcesInfoTable", "1st get_first_data_point() before 
populate L1 size %d \n", (int)L1.size()));
        context_data * L1ctx = SNMP_MALLOC_TYPEDEF(context_data);
        readL1PpsData( L1 );
        DEBUGMSGTL(("SourcesInfoTable", "1st get_first_data_point() after 
populate L1 size %d \n", (int)L1.size()));
        DEBUGMSGTL(("SourcesInfoTable", "1st get_first_data_point() front() 
|%s| \n", L1.front().c_str()));
        strncpy( L1ctx->L1line, L1.front().c_str(), 1000 );
        L1ctx->len = L1.front().length();
        L1_set_index_value( put_index_data );
        *my_loop_context = L1ctx;
        *my_data_context = L1ctx->L1line;
        return put_index_data;
    }

    netsnmp_variable_list *
    inputSourcesInfoTable_get_next_data_point(void **my_loop_context,
                              void **my_data_context,
                              netsnmp_variable_list *put_index_data,
                              netsnmp_iterator_info *mydata)
    {
        DEBUGMSGTL(("SourcesInfoTable", "N_th get_next_data_point() L1 size %d 
\n", (int)L1.size()));
        if( L1.size() == 0 ) {
            /* End of routes.  stop here by returning NULL */
            //SNMP_FREE(position);
            *my_loop_context = NULL;
            *my_data_context = NULL;
            return NULL;
        }
        context_data * L1ctx = (context_data*)*my_loop_context;
        L1.pop_front();
        strncpy( L1ctx->L1line, L1.front().c_str(), 1000 );
        L1ctx->len = L1.front().length();
        L1_set_index_value( put_index_data );
        *my_loop_context = L1ctx;
        *my_data_context = L1ctx->L1line;
        return put_index_data;
    }


The issue that I'm having is that once my handler gets called it only has empty 
strings as data_context.

    int
    inputSourcesInfoTable_handler(
        netsnmp_mib_handler               *handler,
        netsnmp_handler_registration      *reginfo,
        netsnmp_agent_request_info        *reqinfo,
        netsnmp_request_info              *requests) {

        netsnmp_request_info       *request;
        netsnmp_table_request_info *table_info;

        std::string s = L1.front();
        DEBUGMSGTL(("SourcesInfoTable", "entering handler() request (%d)\n", 
reqinfo->mode ));
        switch (reqinfo->mode) {
            /*
             * Read-support (also covers GetNext requests)
             */
            case MODE_GET:
                for ( request = requests; request; request = request->next ) {
                    char *data_context = 
(char*)netsnmp_extract_iterator_context( request );
                    std::string sDbg;
                    if( data_context == NULL ) {
                        DEBUGMSGTL(("SourcesInfoTable", " handler() 
data_context NULL"));
                        continue;
                    }
                    else {
                        char dbg[40];
                        memset( dbg, 0, 40 );
                        strncpy( dbg, data_context, 39 );
                        DEBUGMSGTL(("SourcesInfoTable", " handler() dbg is 
|%s|\n", dbg)); // <-------- HERE always || 
                    }

                    table_info  = netsnmp_extract_table_info( request );
                    switch (table_info->colnum) {
                    . . . SNIP! . . .

Q: How am I screwing up the data_context?
Q: Is it normal for the handler to only get called once get_next_data_point 
returns NULL?


Thanks for the help

Ian

Ps. Note that I've used mib2c.iterate.conf to generate priliminary code and 
then modified as per HostsTable & RouteTable examples.
_______________________________________________
Net-snmp-users mailing list
Net-snmp-users@lists.sourceforge.net
Please see the following page to unsubscribe or change other options:
https://lists.sourceforge.net/lists/listinfo/net-snmp-users
  
_______________________________________________
Net-snmp-users mailing list
Net-snmp-users@lists.sourceforge.net
Please see the following page to unsubscribe or change other options:
https://lists.sourceforge.net/lists/listinfo/net-snmp-users

Reply via email to