DOC HOME SITE MAP MAN PAGES GNU INFO SEARCH PRINT BOOK
 
Developing SMUX peers for SNMP agents

Writing set functions

Now let's look at implementing ``set'' functions for single and multiple instances. This will require additional changes to foomib.c. When a SetRequest PDU is being processed, control is passed through this set function, and it is here that single instance objects are written.

For every single instance leaf object in your MIB module with read-write access, add a ``case'' to this ``switch'' statement. For your object, use one of the examples below which has the same syntax.

       switch (ifvar) {
       case BOARDSTATUS:
           if ((*os->os_decode) (&value, v->value) == NOTOK)
               return error__status_badValue;
   

i = *((int *) value); (*os->os_free) (value);

if ((i != 1) && (i != 2)) return error__status_badValue;

new_boardStatus = i; return error__status_noError;

case EXAMPLEIPADDR: if ((*os->os_decode) (&value, v->value) == NOTOK) return error__status_badValue;

new_exampleIpAddr = ((struct sockaddr_in *) value)->sin_addr; newflag_exampleIpAddr = 1;

(*os->os_free) (value); return error__status_noError;

case EXAMPLEOBJECTID: if ((*os->os_decode) (&value, v->value) == NOTOK) return error__status_badValue;

if ((OID) value == NULLOID) new_exampleObjectID = NULLOID; else new_exampleObjectID = oid_cpy((OID) value);

(*os->os_free) (value); return error__status_noError;

default: return error__status_noSuchName; }

This function is executed when processing SetRequest PDUs for a VarBind of an Object in the serialLineTable.

For each table in your MIB module that also contains objects with read-write access, make one of the following functions of name set_tableName(). If the table does not contain any read-write access objects, this function is unnecessary.

    static int
    set_serialLineTable(oi, v, offset)
  	 OI              oi;
  	 register struct type_SNMP_VarBind *v;
  	 int             offset;
    {
When a SetRequest PDU is being processed, control is passed to this function. The multiple instance objects are set at this point.

For every read-write access object in the table that this function services, add a ``case'' to this ``switch'' statement. Use the appropriate function ( o_string(), o_integer(), and so on) according to the object's syntax.

   switch (ifvar) {
   case SERIALLINEBAUDRATE:
       if ((*os->os_decode) (&value, v->value) == NOTOK)
           return error__status_badValue;
   

i = *((int *) value); (*os->os_free) (value);

if ((i != BAUD1200) && (i != BAUD2400) && (i != BAUD9600) && (i != BAUD19800)) return error__status_badValue;

serialLineTable[ifnum].new_serialLineBaudRate = i; return error__status_noError;

case SERIALLINETERMLOCATION: if ((*os->os_decode) (&value, v->value) == NOTOK) return error__status_badValue;

cp = ((OctetString *) value);

printf ("NEW LOCATION = %& \n", cp->octet_ptr);

serialLineTable[ifnum].newflag_serialLineTermLocation = 1; if (cp == NULL) { serialLineTable[ifnum].new_serialLineTermLocation[0] = '\0'; } else { if (cp->length < LOCATIONSIZE) { (void) strncpy(serialLineTable[ifnum].new_serialLineTermLocation, cp->octet_ptr, cp->length); serialLineTable[ifnum].new_serialLineTermLocation[cp->length]='\0';

} else { LIB_ERROR("\n WARNING: serialLineTermLocation string too long\n"); (void) strncpy(serialLineTable[ifnum].new_serialLineTermLocation, cp->octet_ptr, LOCATIONSIZE - 1);

/* Silently ignore DisplayStrings that are too long. */ serialLineTable[i].new_serialLineTermLocation[ LOCATIONSIZE - 1] = '\0'; } }

(*os->os_free) (value); return error__status_noError;

default: return error__status_noSuchName; }

You will recall that a ``set'' is a two-phase process: the agent receives the SetRequestPDU from the client running on the management station and sends the request on to the appropriate peers, then collates the peer responses; depending upon the responses from the peers, the agent then issues either a ``commit'' or a``rollback'' SOutPDU. When the peer processes a SMUX ``commit'' or ``rollback'' SOutPDU, it executes the sync_foo() function. sync_foo completes the set operation: if it receives a ``commit'' SOoutPDU from the agent, sync_foo writes the new values to the variables; if it receives a ``rollback'' SOoutPDU, sync_foo discards the new pending values without writing them.

For each MIB module that also contains objects with read-write access, make one of the following functions of name sync_MIBmodule().

    int
    sync_foo(cor)
        int             cor;
    {
In the ``switch'' statement where the commit instruction is processed, all variables must be updated with the values that were temporarily stored in the new variables. At this point the hardware and/or file configuration should be updated. Unlike a real SMUX peer, the example peer does not communicate with a device and it does not write to a configuration file.

For each single instance object in the MIB module that has a read-write access, add an ``if'' statement that checks if there is a new value to commit. This is shown in the following example:

    if (new_boardStatus)
        boardStatus = new_boardStatus;

if (newflag_exampleIpAddr) exampleIpAddr = new_exampleIpAddr;

if (new_exampleObjectID != NULLOID) exampleObjectID = oid_cpy(new_exampleObjectID);

For each table in the MIB module that contains a read-write access object, add a for() loop:
    for (i = 0; i < numberLines; i++) {
For every object in the table that has a read-write access, add an ``if'' statement inside the for() loop that checks if there is a new value to commit. This is shown in the following example:
    if (serialLineTable[i].new_serialLineBaudRate) {
        serialLineTable[i].serialLineBaudRate
            = serialLineTable[i].new_serialLineBaudRate;
        serialLineTable[i].new_serialLineBaudRate = 0;
    }
    if (serialLineTable[i].newflag_serialLineTermLocation) {
        (void) strcpy(serialLineTable[i].serialLineTermLocation,
                  serialLineTable[i].new_serialLineTermLocation);
        serialLineTable[i].newflag_serialLineTermLocation = 0;
    }
In the ``switch'' statement where the rollback instruction is processed, all temporary variables that were holding pending values must be zeroed.

For each single instance object in the MIB module that has an access of read-write, add an assignment statement that zeroes the new value as shown:

    new_boardStatus = 0;
    newflag_exampleIpAddr = 0;
    new_exampleObjectID = NULLOID;
For each table in the MIB module that contains a read-write access object, add a for() loop:
    for (i = 0; i < numberLines; i++) {
For every object in the table that has a read-write access, add an ``if'' statement inside the for() loop that zeroes the new value as in the following example:
        serialLineTable[i].new_serialLineBaudRate = 0;
        serialLineTable[i].newflag_serialLineTermLocation = 0;

Next topic: Generating traps
Previous topic: Writing get functions

© 2003 Caldera International, Inc. All rights reserved.
SCO OpenServer Release 5.0.7 -- 11 February 2003