You are on page 1of 18

Agent Toolkit

AdventNet

C Edition
Release 6

IPC Example Tutorials

AdventNet, Inc. 5645 Gibraltar Drive Pleasanton, CA 94588 USA Phone: +1-925-924-9500 Fax: +1-925-924-9600 E-mail:info@adventnet.com 1999 - 2003 AdventNet Inc. All Rights Reserved.

IPC Example

Table Of Contents

IPC REFERENCE IMPLEMENTATION ..................................................................... 2


Introduction .......................................................................................................................... 2 Requirements ...................................................................................................................... 3 Application Notes................................................................................................................. 4 IPC COM MIB ...................................................................................................................... 6 Generated Code .................................................................................................................. 7 External Application ............................................................................................................. 8 Instrumentation .................................................................................................................. 10 Request Processing........................................................................................................... 15 Running the Example ........................................................................................................ 17

AdventNet Inc.

IPC Example

IPC Reference Implementation Introduction


This document explains the implementation of the Multi-Protocol Agent with No Storage option. In this implementation, the real data is maintained by an external application, which may be any user application. Since, the data is not held by the Agent when a request is made, the Agent has to communicate with the external application to get the data and send back the response to the Manager. You would like to implement a no storage Agent of a similar type. But you may not know how to make this Agent communicate with the external application, send the request, and get back the response from the external application. This document guides you to implement this process with the help of an example.

Objectives of the Implementation


The main objective of this implementation is to provide you a clear understanding of the communication process between the no storage Agent and the external application. Hence, the focus with reference to this implementation will be on the following areas: Instrumentation of the No Storage Agent Request Processing Running the Example and Testing the Agent

Getting Started
To get started with this implementation, please go through the following sections in the order in which they are specified : The Requirements topic lists down the basic requirements for working with this implementation. The Application Notes explains the application that is taken up for this reference implementation. The Generated Code topic deals with the files that are generated by default for this implementation. The External Application topic explains the external application and the functions defined for implementing this example. Instrumentation explains the process of adding the actual functionality to the generated code, for implementing the ipc agent through sockets or through message queues. Request Processing explains how a get/get-next/set request is processed. Running the Example provides the basic steps involved in running this example.

AdventNet Inc.

IPC Example

Requirements
The following are the basic requirements for this implementation:

Hardware
Memory: Minimum 128 MB RAM CPU: Minimum 266 MHz Pentium Processor Disk Space: Minimum of 100 Mega Bytes hard disk space

Software
Operating System: Any OS which supports sockets or Message queues. AdventNet Agent Toolkit C Edition, Release 6: Please download the same from our Web site, www.adventnet.com and install it. Follow the instructions given for installation and setup of the toolkit, in the Release 6 Product Help documentation. C/C++ Compiler: Supports Microsoft Visual C++ 4.0 onward or Borland C++ 4.0 onward for Windows. GNU C or C++ compiler (any version) for UNIX platform.

Others Requirements
Refer to the section, "Generated Code Structure" under "Building Multi-Protocol Agent" in our Product Help Documentation to get an idea about the files generated, the methods present in these files, and their functionality. Knowledge in Socket programming.

AdventNet Inc.

IPC Example

Application Notes
In this application, the Agent is implemented as a "No Storage Agent" and the data are held by an external application. When any request is sent by the Manager, the Agent contacts the external application, retrieves the data, and sends back the response to the Manager. Hence, the implementation involves two modules: Agent application and External application. The communication between the Agent and the resources in the external application are through Inter Process Communication (IPC). This is done through message queues or udp sockets. The Agent sends the request message to the external application through a UDP Socket or message queue. The external application reads this message and sends the response to the agent application. Now the agent reads this response message and sends it back to the manager. The architecture given below explains the communication between the Manager, Agent, and the External Application.

What Is a Socket?
A socket is an end point for communication. The IPC operations are based on socket pairs, one belonging to a communication process. IPC is done by exchanging some data through transmitting that data in a message between a socket in one process and another socket in another process. When messages are sent, the messages are queued at the sending socket until the underlying network protocol has transmitted them. When they arrive, the messages are queued at the receiving socket until the receiving process makes the necessary calls to receive them. A call to the socket() system routine returns the socket descriptor, and you can communicate through it using the specialized send() and recv() socket calls.

What Is a Message Queue?


Message queues can be best described as an internal linked list within the kernel's addressing space. Messages can be sent to the queue in order and retrieved from the queue in several different ways. Each message queue (of course) is uniquely identified by an IPC identifier. Note: In this example, we are using IPC for communication between the agent and the user application. Other modes of communication, such as Serial port communication, device driver communication, or proprietary methods can also be used.

AdventNet Inc.

IPC Example

Agent Application
The following are the important features of the Agent application : It acts only as an interface and does not contain any data. It contains the source files for SNMP/HTTP/TL1 operations and functionality. It contains generated code for the IPCCOM.Mib MIB. It contains the modified code to support UDP communication.

External Application
The following are the important features of the External Application : The external application may be any existing software which is designed to perform some processing for the system (device/printer). The Real data to be managed is available in this application. Request processing takes place between the agent application and external application.

AdventNet Inc.

IPC Example

IPC COM MIB


In this example, the resources to be managed by the agent are defined in the IPCCOMMUNICATION-MIB. The Agent application implements this MIB which contains a table ipcTable with the following columns in it:

Table Column Names


ipcldx ipcCount ipcTime ipcStatus

Usage
The index column for the table of type integer and access as read-only. It is of type Integer and access as read-write. The time at which the request is made. It is of type timeticks and access as read only. It is of type rowStatus and access as read-write.

AdventNet Inc.

IPC Example

Generated Code
The following files get generated under ./projects/projectname/agent/stubs/ipc-communication-mib/src directory for IPC-COMMUNICATION-MIB : ipccommunicationmib.c: This file contains all the init methods of the generated MIB and FreeResources Method. ipctablehdlr.c: The basic functionality of this file is to register the module <modulename> with the Agent and to handle all requests, such as GET, GET-NEXT, SET from the Managers. It also handles row creation and deletion in case of tables. ipctableinstru.c : This file contains a get method for all table columns and a set method for each scalar and table column provided they have read-write or read-create access. The functions defined in this file will be called from the handler file whenever a GET,GET-NEXT, and SET request is received from the Manager.

In the Instrumentation topic, you will see how the methods present in the generated handler files are instrumented for communicating with the external application.

AdventNet Inc.

IPC Example

External Application
Functions Defined in the External Application (ipcext.c)
In this implementation, the external application is only a simulation. It is a separate entity and has to be compiled and started separately.

Data Maintained by the External Application


The external application maintains the ipctable as an array of structures. The structure template is similar to the table maintained by the Agent as shown below. The user table initially maintains five rows of data. struct ipcEntry { INT32 ipcIdx; INT32 ipcCount; LONG ipcTime; INT32 ipcStatus; };

In the external application, the macro for using Sockets/message queues is defined in the file ipcext.c.

Functions Defined for IPC Implementation Using Message Queues


1. ReadMessage() This function reads the message from the message queue. It takes the following inputs: qId : The message queue Id. of type integer. qBuf : The pointer to the message structure

This function is used for reading the message from the Agent by the external application and returning the received message. The function call msgrcv() is used for receiving the message. 2. ProcessAndSendQueueMessage() This function is used to process and send the message from the agent to the external application . It takes the following inputs: qId : The message queue Id. of type integer. qBuf : The pointer to the message structure. text : The actual message which is of type string This function sends the message as Type2 as shown below: qbuf->mType = 2; The other values of the message structure are filled up and sent using the function call: msgsnd().

AdventNet Inc.

IPC Example

Functions Defined for IPC Implementation Using Sockets


1. ReadAndProcessUDPMessage() This function reads the message from the client application and processes it according to the received information. It takes the following inputs: SOCKET sockFd struct sockaddr_in *sockAddr The function call recvfrom() is used for receiving messages. After receiving the message from the Agent, the application processes it based on the type of the request and the message. In this example, the external application has 5 rows by default. The constraint found in the external application in this example are: Number of rows that can be added cannot exceed 10 with index values 1 to 10.

AdventNet Inc.

IPC Example

Instrumentation
Overview Using Instrument Files Using Header Files Newly Added Files Instrumentation Using UDP Sockets o o o o o Defining a Message Structure Creating a Socket Binding the Socket Sending the Message to the External Application through the Socket Receiving the Message from the External Application through the Socket Defining a Message Structure Creating the Message Queue Sending the Message to the External Application through the Message Queue Receiving the Message from the External Application through the Message Queue

Instrumentation Using Message Queues o o o o

Overview
This topic discusses the generated files of the agent application and their instrumentation to get the data from the external application. Instrumentation can be done in two ways : Using Instrument files or Using Handler Files

Using Instrument Files


This file is generated for each table or scalar group of the MIB. It contains the set/get methods for each variable defined in the Mib. Here, you can add the necessary code to contact the external application and get the data. The disadvantage of instrumenting the instru.c files are a. In case of Multi-Varbind request, the Agent has to contact the external application for each varbind. b. Instrumentation has to be done for each get/set method.

Using Handler Files


This file is generated for each table or scalar group of the MIB. It handles all requests, such as GET, GET-NEXT, and SET from the Managers. Here, you can add the necessary code to contact the external application and get the data. The advantages of instrumenting the handler files are This file defines the <ModuleName>Process Requests method from which you can know the set of table column/scalars received for a listener. Using these inputs, you can call your application method and update the local data structure simultaneously. In this example, instrumentation is done in the generated handler files. In addition, new files are added for implementing this example.

AdventNet Inc.

10

IPC Example

Newly Added Files


In this implementation, we have defined a new header file ipcext.h which defines the macros needed for IPC Communication. The example by default implements SOCKETS. The macro SOCK_IMPL defined in this file specifies that the implementation is through SOCKETS. If this macro is not defined, then the implementation is through Message Queues. The external application socket is listening at port 9001 for requests from the agent application at 8005. The port numbers are defined under the macro's TARGET_PORT and CLIENT_PORT in ipcext.h. In this example, we have implemented the ipc agent using sockets and message queues. Hence, instrumentation is dealt with in separate headings as shown in the link below: Instrumentation Using Sockets Instrumentation Using Message Queues

Instrumentation Using UDP Sockets


In order to communicate with the external application, the files and methods generated in the agent application has to be instrumented to get the required functionality. The ipcext.h file is defined which declares the necessary macros, the message structure, and functions. The ipctablehdlr.c file is instrumented by adding new methods to create the message queue, to send messages to the external application, and receive messages from the external application. The following are the steps to instrument the IPC Agent using sockets: Defining a Message Structure Creating a Socket Binding the Socket Sending the Message to the External Application through the Socket Receiving the Message from the External Application through the Socket

a. Defining the Message Structure :


The communication between the agent and the external application is in the form of a message. Hence, the first step is to define the structure of the message to be communicated. The structure of the message, when it is transferred from the agent application to the external application, is defined in the ipcext.h file. RequestType<blankspace>TextMessage. INT32 reqType; /* 0 - GET / 1 - GET-NEXT / 2 - SET*/ CHAR text[400]; The structure of the message, when it is transferred from the external application and the agent applications, is ReturnType<blankspace>TextMessage. INT32 retType; /* 0 - FAILURE / 1 - SUCCESS */ CHAR text[400];

b. Creating a Socket
In this example, the message to be communicated is through sockets. Hence, the next step is to create a socket. The agent application creates a socket and binds it with a name in the InitIpcTable() function of ipctablehdlr.c. The global variable gv_ipcSockFd is defined in the header file ipcext.h. An UDP socket is created and the descriptor is stored in the variable gv_ipcSockFd.

AdventNet Inc.

11

IPC Example

/ * Cretes a UDP socket. */ gv_ipcSockFd = socket(AF_INET, SOCK_DGRAM, 0); if (gv_ipcSockFd < 0) { printf("Unable to open socket on port number %d ", CLIENT_PORT); exit(0); }

c. Binding the Socket


After creating a socket, the socket is given a name by using the bind () call. The gv_ipcSockAddr is declared in the header file ipcext.h. The macro's CLIENT_PORT and CLIENT_HOST are also defined in the header file ipcext.h. The values of CLIENT_PORT and the CLIENT_HOST are by default 8005 and 127.0.0.1 respectively. gv_ipcSockAddr.sin_family = AF_INET; gv_ipcSockAddr.sin_port = htons(CLIENT_PORT); gv_ipcSockAddr.sin_addr.s_addr = inet_addr(CLIENT_HOST); if (bind(gv_ipcSockFd, (struct sockaddr *)&gv_ipcSockAddr, sizeof(gv_ipcSock Addr)) != 0) { printf("Problem in bind\n"); perror("!!!!"); exit(0); } Now, we have defined a message structure, created a socket, and given a name for the socket using the bind function. The next step is to send the message using the socket.

d. Sending the Message through the Socket


The function SendUDPMessage() is added in the ipctablehdlr.c file to create and send a message from the agent application to the user application through sockets. The prototype of this function is void SendUDPMessage(CHAR *text, INT32 type). This function takes the following inputs : o text: The actual message which is of type string. o reqType: The request type which is of type integer. It creates the message by using this function and then it uses the sendto () call to send this message to the user / external application.

e. Reading the Message


Now, the agent application has to receive the message from the external application . The function ReadUDPMessage() is added in the ipctablehdlr.c file to read and process the received message from the external application. The prototype of this function is CHAR ReadUDPMessage(INT32 *indOut) This function uses the recvfrom () call to receive the message from the user / external application.

AdventNet Inc.

12

IPC Example

Instrumentation Using Message Queues


To communicate with the external application, the files and methods generated in the agent application have to be instrumented to get the required functionality. To implement the IPC agent using message queues, the ipcext.h file is defined which declares the necessary macros, the message structure, and functions. The ipctablehdlr.c file is instrumented by adding new methods to create the message queue, to send messages to the external application, and to receive messages from the external application. The following are the steps involved to instrument the IPC agent using message queues: Defining a Message Structure Creating the Message Queue Sending the Message to the External Application through the Message Queue Receiving the Message from the External Application through the Message Queue

Defining a Message Structure


The structure of the message is defined in ipcext.h as shown below : struct myMsgBuf { LONG mType; CHAR reqType; /* 0 - GET / 1 - GET_NEXT / 2 - SET */ CHAR mText[400]; CHAR retType; /* 0 - FAILURE / 1 - SUCCESS */ }; In the above message structure mType: Type of the message (1 or 2). reqType: 0 for type GET, 1 for type GET-NEXT, and 2 for type SET specified by the agent. mText: The message content. retType: 1 for Success or 0 for Failure specified by the external application.

Creating the Message Queue


The Agent application creates the message queue in the InitIpcTable() function. The function msgget() creates a message queue and opens it if it does not exist . If the queue already exists, it opens the queue. This function returns the queue ID. The following code can be specified in the init function call of the MIB. In this example, the code is specified in the InitIpcTable function of the Agent. The agent and the external application communicate through a common Key 006. /* Open the queue - create if necessary */ if((gv_msgQueueId = msgget(KEY, IPC_CREAT|0660)) == -1) { perror("msgget"); exit(1); }

AdventNet Inc.

13

IPC Example

Sending the Message through the Message Queue


The function SendQueueMessage() is added in the ipctablehdlr.c file to send the message from the agent to the external application using message queues. It takes the following inputs: SendQueueMessage(INT32 qid, struct myMsgBuf *qBuf, CHAR reqType , CHAR *text)

qId: The message queue ID of type integer. qBuf: The pointer to the message structure. reqType: The request type which is of type character. text: The actual message which is of type string.

This function sends the message as type1 as shown below: qBuf->mType = 1; The other values of the message structure are filled up and sent using the function call msgsnd().

Reading the Message from the Message Queue


The function ReadQueueMessage() is added in the ipctablehdlr.c file to read the message from the message queue. The prototype of the function is CHAR *ReadQueueMessage(INT32 qid, struct myMsgBuf *qBuf) This function takes the following inputs: qId: The message queue ID of type integer. qBuf: The pointer to the message structure.

This function is used to read the message from the external application by the agent and returns the received message. The function call msgrcv() is used to receive the message. The agent writes the message into the queue as Type1. The external application reads this message and writes the response into the queue as Type2. Now the agent reads this message with Type2 and sends back the response to the manager.

AdventNet Inc.

14

IPC Example

Request Processing
Processing a GET Request Processing a GET-NEXT Request Processing a SET Request

Processing a GET Request


When a get request is sent by the Manager to the Agent The Agent API calls the IpcTableProcessRequests() in the ipctablehdlr.c file. The above function processes the request and in turn calls the SendMessageToExternalApplication(). This in turn calls the following method which sends the message to the external application: o o SendUDPMessage() in case of sockets. SendQueueMessage() in case of message queues.

Next, the function ReadMessageFromExternalApplication() is called which in turn calls the following method which receives the message from the external / external application which contains the values of the row. o o ReadUDPMessage() in case of sockets. ReadQueueMessage() in case of message queues.

The function ReadUDPMessage() then stores the value in the table gv_ipcTableVector() through the function call CreateAndAddNewIpcTableEntry().

For example, for the column variable "ipcTime", the external application returns the time at which the request is made. It then stores them in the table gv_ipcTableVector(). When the request is made for a specified index, the index is sent to the external application . The external application searches the corresponding row for the specified index. If the index matches with the given index, it retrieves the corresponding column's row value and returns "1" to the variable type retType in the message structure. If the index does not match with the given index, it returns "0" to the variable retType in the message structure. In this implementation, the index column ipcIdx is of type string. The agent will retrieve the column values from the text variable in the message structure and will create a row in the table with corresponding column values.

Processing of a GET-NEXT Request


The process for a get-next request is same as get request. In this case, the index is incremented by 1 and sent to the user application. If there is no corresponding row in the external application for the specified index, the external application finds the next index available in the table and returns the corresponding row to the agent. For the column variable "ipcTime", the external application returns the time at which the request is made.

AdventNet Inc.

15

IPC Example

Processing a SET Request


When a set request is sent by the Manager to the Agent The agent API calls the IpcTableProcessRequests() in the ipctablehdlr.c file. The above function processes the request and in turn calls the SendMessageToExternalApplication(). This in turn calls the following method which sends the message to the external application: o o SendUDPMessage() in case of sockets. SendQueueMessage() in case of message queues.

Next, the following function is called which gets the corresponding values of the corresponding row: o o ReadUDPMessage() ReadQueueMessage()

The values are then stored in the table gv_ipcTableVector(), using the function CreateAndAddNewIpcTableEntry(). If the corresponding row does not exist in the external application, the table is not updated for the corresponding row. If a request is received for a row (muti-varibinds) then the agent will contact external application and retrieve value for the complete row. The Agent API updates the table with the new values set by the manager if a row already exists or it creates a new row in the table if the row does not exist. Before sending a response to the manager, the Agent API calls the function UpdateIpcTable(). This function is used to update the rows in the external application as maintained by the agent. In case of row deletion, the UpdateIpcTable() function will have the row status value as nonexistent (0). This will delete the row in the external application.

AdventNet Inc.

16

IPC Example

Running the Example


The IPC reference implementation files are available in the ./examples/mpa directory. Since, the implementation involves two modules, one for agent and the other for external application, the following files in the ./examples/mpa/ipc-mp-agent directory are used for the agent module: ipctablehdlr.c ipcext.h

The following files in the ./examples/mpa/ipc_mp_agent/ipcext directory are used for external application module: ipcext.c stdvars.h

To implement this example, please follow the steps given below: 1. To generate code for the agent application, load the IPC-COMMUNICATION-MIB in the Agent (MIB) Compiler. 2. Create a new project with the Agent type as Multi-Protocol Agent. 3. In Settings->General options, specify the storage type as No storage and generate source code. 4. Replace the generated ipctablehdlr file in the <AdventNet>/C Agent/projects/<ProjectName>/agent/stubs/ipc-communication-mib/src directory with the file in the examples/mpa/ipc-mp-agent directory. 5. Copy the ipcext.h file in the <AdventNet>/C-Agent/projects/<ProjectName>/agent/stubs/ipccommunication-mib/include directory . 6. Compile the generated code as given below : cd <AdventNet>/C-Agent/projects/<projectname>/agent make for Unix-based systems and nmake for Windows. 7. On successful compilation, run the agent as given below: cd <AdventNet>/C-Agent/projects/<projectname>/agent/bin ./cagent for Unix-based systems or cagent for Windows. 8. Compile the ipcext.c file in the <AdventNet>/C Agent/examples/mpa/ipc-mp-agent/ipcext directory as given below: cd <AdventNet>/C Agent/examples/mpa/ipc-mp-agent/ipcext - gcc ipcext.c -o ipcext for Unixbased systems (or) cl.exe ipcext.c for Windows. 9. To run the external application, cd <AdventNet>/C Agent/examples/mpa/ipc-mp-agent/ipcext - ./ipcext for Unix (or) ipcext for Windows 10. Load the MIB in the MIB Browser and query the agent which runs at port 8001 by default. You can find the Agent responding with the required values.

AdventNet Inc.

17

You might also like