Table of Contents Index NMS Glossary Previous Page Next Page Version


Chapter 2

NMS OAM Programming Model


2.1 Introduction
2.2 Types of Functions
2.3 OAM Service Tasks and Related Functions
Configuring Objects
Managing Hardware
Starting, Stopping, and Testing Boards
Retrieving Board ID Information
Receiving NMS OAM Events
Advanced Functions
2.4 OAM Service Events
2.4.1 Freeing the Event Buffer
2.4.2 Code Sample

2.1 IntroductionTop of Page

This chapter:

2.2 Types of FunctionsTop of Page

There are two types of functions in Natural Access: synchronous and asynchronous.

The following table summarizes the differences between asynchronous and synchronous functions. Section 2.3 lists all OAM service functions and indicates if they are synchronous or asynchronous.
Characteristic

Asynchronous

Synchronous

Operation complete when function returns.

No

Yes

Returns an appropriate event when function is complete.

Yes

No

Function can fail after function returns.

Yes

No

2.3 OAM Service Tasks and Related FunctionsTop of Page

The following sections summarize OAM service tasks and related functions. With each function is listed:

Each listed function is described in detail in Chapter 9.

Configuring ObjectsTop of Page

The following functions are provided to access managed objects and edit configuration data:
Function

S/A1

Description

oamOpenObject

S

Starts an editing session on the specified managed object. Returns a handle to be used with subsequent NMS OAM API object-specific function invocations.

oamCloseObject

S

Ends the editing session for a managed object, validating and saving changes.

oamGetKeyword

S

Gets a keyword value for a managed object.

oamGetQualifier

S

Gets a keyword qualifier for a managed object.

oamSetKeyword

S

Sets a keyword for a managed object.

oamConfigExport

S

Exports the current configuration to an output file.

oamConfigImport

S

Imports the current configuration from an input file.

1 Synchronous or Asynchronous

Managing HardwareTop of Page

A client application can create a managed object for a board. Once the board exists as a managed object, NMS OAM can configure and manage the board.

A client application can also cause the OAM service to detect hardware in a system and create a managed object for each board. Note that some board plug-ins do not support this feature.

The following functions are provided to detect hardware and create or delete managed objects:
Function

S/A1

Description

oamCreateBoard

S

Creates a managed object for a board.

oamDeleteBoard

S

Deletes a board managed object (or all board managed objects).

oamDetectBoards

S

Detects physically installed boards in a system.

oamAddDetectedBoard

S

Creates a managed object for a physically detected board. (Not supported by all board plug-ins.)

1 Synchronous or Asynchronous

Starting, Stopping, and Testing BoardsTop of Page

The OAM service can start, test, or stop any boards that exist as managed objects. The following functions perform these operations:
Function

S/A1

Description

oamStartBoard

A

Starts one or more boards.

oamStopBoard

A

Stops one or more boards.

oamTestBoard

A

Tests one or more boards (if supported).

1 Synchronous or Asynchronous

Retrieving Board ID InformationTop of Page

The OAM service allows a client application to retrieve basic identification information about a board: its bus and slot, its driver ID information, its board number, or its serial number.

Each board is referred to using a unique name. The following functions allow a client application to look up the name of a board by providing various types of information about the board:
Function

S/A1

Description

oamBoardEnum

S

Lists the names of all boards that exist as managed objects.

oamBoardLookupByBusSlot

S

Looks up a board by its bus and slot, and returns its name.

oamBoardLookupByDriverIDs

S

Looks up a board by its driver ID information, and returns its name.

oamBoardLookupByNumber

S

Looks up a board by its board number, and returns its name.

oamBoardLookupByProduct

S

Given a product type, returns the board name of the first board of that product type listed in the NMS OAM database.

oamBoardLookupBySerialNumber

S

Looks up a board by its serial number, and returns its name.

1 Synchronous or Asynchronous

Once the name of the board is determined, the client application can retrieve other types of information about the board, using the following functions:
Function

S/A1

Description

oamBoardGetBusSlot

S

Given a board name, returns the bus and slot of the board.

oamBoardGetDriverIDs

S

Given a board name, returns the driver ID information of the board.

oamBoardGetNumber

S

Given a board name, returns the board number of the board.

oamBoardGetProduct

S

Given a board name, returns the product type of the board.

oamBoardGetSerialNumber

S

Given a board name, returns the serial number of the board.

1 Synchronous or Asynchronous

Receiving NMS OAM EventsTop of Page

Client applications must register with the OAM service to receive NMS OAM, Hot Swap and clock management events. The following functions allow applications to register or unregister:
Function

S/A1

Description

oamAlertRegister

S

Registers a client to receive events from NMS OAM and from EMCs.

oamAlertUnregister

S

Unregisters a client so it no longer receives events from NMS OAM and from EMCs.

1 Synchronous or Asynchronous

Advanced FunctionsTop of Page

The OAM service provides the following advanced system management functions (not intended for normal use):
Function

S/A1

Description

oamShutdown

S

Shuts down the Supervisor component of ctdaemon.

oamRestart

S

Restarts the Supervisor component of ctdaemon.

oamSendBuffer

S

Debug function. Sends a raw data buffer to a board.

oamAlertNotify

S

Broadcasts a specified alert message to all clients registered for alert notification.

1 Synchronous or Asynchronous

2.4 OAM Service EventsTop of Page

Events are generated by:

To receive events from the OAM service and from installed EMCs (such as Hot Swap and clock management), a client application must register with the OAM service. To learn how to register an application, see Section 3.6.6.

NMS OAM events arrive encapsulated in the standard CTA event data structure (defined in ctadef.h):

typedef struct CTA_EVENT
{
DWORD id; /* Event code (and source service id) */
CTAHD ctahd; /* Context handle */
DWORD timestamp; /* Timestamp */
DWORD userid; /* User id (defined by ctaCreateContext) */
DWORD size; /* Size of buffer if buffer != NULL */
void *buffer; /* Buffer pointer */
DWORD value; /* Event status or event-specific data */
DWORD objHd; /* Service client side object handle */
} CTA_EVENT;
This structure, returned by ctaWaitEvent, informs the application which event occurred on which CTA context, and includes additional information specific to the event.

The CTA_EVENT structure contains the following fields:
Field

Description

id

Contains an event code defined in the library header file. For example: OAMEVN_SOMETHING_ HAPPENED.

For a list of NMS OAM event codes, see Appendix A.

ctahd

Contains the CTA context handle returned from ctaCreateContext.

timestamp

Contains the time when the event was created in milliseconds since midnight, January 1, 1970, modulo 49 days.

An application can decode the timestamp using ctaGetTimeStamp.

userid

Contains the user-supplied id. This field is unaltered by Natural Access and facilitates asynchronous programming. Its purpose is to correlate a CTA context with an application object/context when events occur.

size

The size (bytes) of the area pointed to by the buffer field. This field also indicates whether a data buffer associated with the event must be freed using ctaFreeBuffer. If the buffer is NULL, this field may be used to hold an event-specific value.

For NMS OAM events, size indicates the size of the OAM_MSG structure.

buffer

This field points to data returned with the event. The field contains an application process address and the event's size field contains the actual size of the buffer.

For NMS OAM events, buffer points to an OAM_MSG structure.

Note: After processing an NMS OAM event, the application must free the event buffer for Natural Access. For more information, see Section 2.4.1.

value

This is an event-specific value. If the event is a DONE event (an event indicating that a function was successfully invoked, such as OAMEVN_STARTBOARD_DONE), this field holds a reason code indicating the actual results of the function.

For more information about reason codes, see Appendix A.

objHd

Contains the service client-side object handle.

Each event's prefix relates the event to a specific Natural Microsystems library of functions, as shown in the following table:
Event Prefix

Source

Defined In

OAMEVN_

OAM service

oamdef.h

HSWEVN_

Hot Swap EMC

hswdef.h

CLKEVN_

Clock Management EMC

clkdef.h

CTAEVN_

Natural Access

ctadef.h

(Other)

(Other service)

(Other .h file)

The application can use the OAM_IS_OAM_EVENT macro (defined in oamdef.h) to determine if an incoming event is an NMS OAM event.

The buffer field in the CTA_EVENT structure points to an OAM_MSG structure (defined in oamdef.h), containing more information about the event:

typedef struct oam_msg_tag
{
    DWORD dwMsgLen;       // Message length, including appended      //
                          // name & message strings                  //
    DWORD dwCode;         // Message code                            //
    DWORD dwSeverity;     // Message severity                        //
    DWORD dwOfsSzName;    // Offset to name string of source         //
                          // managed object                          //
    DWORD dwOfsSzMessage; // Offset to text message string           //
        // (String data is appended here) //
} OAM_MSG;

As shown in Figure 9, the OAM_MSG structure contains five DWORD fields and two strings that contain:

The OAM_MSG structure fields are used as described in the following table:
Field

Description

dwMsgLen

Indicates the length of the message appended to the end of the structure, including the name string and the text string.

dwCode

The event code (always equivalent to id in the CTA_EVENT structure).

dwSeverity

Indicates the severity of the message. Possible values are:

· CTA_TRACE_SEVERITY_INFO -- Message is informational.

· CTA_TRACE_SEVERITY_WARNING -- Message is a warning.

· CTA_TRACE_SEVERITY_ERROR -- Message is an error.

dwOfsSzName

Offset to the first byte of the name string (see below), from beginning of OAM_MSG structure.

dwOfsSzMessage

Offset to the first byte of the text message string (see below), from beginning of OAM_MSG structure.

(name string)

The name of the managed object associated with the message.

(text message string)

Free-form text giving additional information associated with the message.

Figure 10 illustrates the relationship between CTA_EVENT and OAM_MSG, and the fields they contain:


chap21.gif

Figure 10. CTA_EVENT Structure and OAM_MSG Structure

2.4.1 Freeing the Event BufferTop of Page

After processing an NMS OAM event, a client application must free the event buffer for Natural Access. This is very important to avoid memory leaks. If the buffer must be freed for Natural Access, then the flag CTA_INTERNAL_BUFFER is set in the size field. Use ctaFreeBuffer to free the event buffer.

If the CTA_INTERNAL_BUFFER is not set, the application does not need to free the event buffer, even if the buffer contains data.

For more information about event buffers, refer to the Natural Access Developer's Reference Manual.

2.4.2 Code SampleTop of Page

The following sample code demonstrates how to detect and process an NMS OAM event.

//////////////////////////////////////////////////////////////////////////////
// monitor
//
// Loops monitoring the OA&M system.

static const char *getText( DWORD dwCode );

static void monitor()
{
DWORD dwErr;
for (;;)
{
// Retrieve an event from the event queue.
CTA_EVENT cta_event;
dwErr = ctaWaitEvent( s_ctaqueuehd, &cta_event, 1000 );
if (dwErr != SUCCESS)
{
printf( "Error waiting for event, %s.\n", getText(dwErr) );
return;
}

// Check if buffer is owned by CTA and must be freed by us below.
bool const bCtaOwnsBuf = cta_event.buffer && (cta_event.size &
CTA_INTERNAL_BUFFER);
if (bCtaOwnsBuf)
cta_event.size &= ~CTA_INTERNAL_BUFFER; // clear flag from size

// Process the event.
if (cta_event.id == CTAEVN_WAIT_TIMEOUT)
{
. . .
}
else if (OAM_IS_OAM_EVENT(cta_event.id)) // if it's an NMS OAM event
{
if (!cta_event.buffer)
{
printf( "Error, NMS OAM event has NULL buffer.\n" );
continue;
}
const OAM_MSG * const pOamMsg = (OAM_MSG *)cta_event.buffer;
const char * const pszName = (char*)pOamMsg + pOamMsg->dwOfsSzName;
const char * const pszText = (char*)pOamMsg + pOamMsg->dwOfsSzMessage;

const char *pszSeverity;
switch (pOamMsg->dwSeverity)
{
case CTA_TRACE_SEVERITY_INFO: pszSeverity = "INFO"; break;
case CTA_TRACE_SEVERITY_WARNING: pszSeverity = "WARNING"; break;
default: /* CTA_TRACE_SEVERITY_ERROR */ pszSeverity = "ERROR"; break;
}
time_t t;
unsigned int nMsecs = 0;
dwErr = ctaGetTimeStamp( cta_event.timestamp, (unsigned long*)&t,
&nMsecs );
if (dwErr != SUCCESS)
printf( "Error converting timestamp: %s\n", getText(dwErr) );

// Get the local date and time
char szDateTime[80];
strcpy(szDateTime, ctime(&t));
// Truncate the year and trailing carriage return.
szDateTime[strlen(szDateTime) - 6] = '\0';
printf( "%s - %s", szDateTime, getText(pOamMsg->dwCode) );
if (CTA_IS_DONE_EVENT(pOamMsg->dwCode)) //If DONEevent,show reason code
printf( " %s", getText(cta_event.value) );
printf( " %s", pszSeverity );
printf( " \"%s\"\n%s\n", pszName, pszText );
}
else // else it's a non-NMS OAM event
printf( "%s\n", getText(cta_event.id) );

if (bCtaOwnsBuf)
ctaFreeBuffer( cta_event.buffer ); // our reponsibility to free
} // end for(;;)
}

//////////////////////////////////////////////////////////////////////////////
// getText
//
// Helper function that uses ctaGetText() to format the text for a numeric code
// (error, event, reason, or command code) and returns a pointer to that text.
// If ctaGetText() fails, formats the numeric code value in hex.
// This is actually a pointer to a local static buffer. It is not thread-safe
// and will be overwritten by subsequent calls.
//
// dwCode [in] is the numeric code.
//
// Returns a pointer to the text.

static const char *getText( DWORD dwCode )
{
DWORD const dwBufSize = 80;
static char szBuf[ dwBufSize ];

if (SUCCESS != ctaGetText( s_ctahd, dwCode, szBuf, dwBufSize ))
sprintf( szBuf, "0x%08lx", dwCode );

return szBuf;
}


Table of Contents Index NMS Glossary Previous Page Next Page Version


Want to send us feedback on our documentation? Email: Tech_Pubs@nmss.com
Copyright © 2001, Natural MicroSystems, Inc. All rights reserved.