|
|
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;