This document explains the SCMS SM C/C++ API and how to install, compile, and run the API.
The SCMS SM C/C++ API is used for updating, querying, and configuring the Subscriber Manager (SM). It consists of two parts, which may be used separately or together without restriction.
SM Non-blocking C/C++ API—A high-performance API with low visibility to errors and other operation results. Supports automatic integrations with OSS/AAA systems.
SM Blocking C/C++ API—A more user-friendly API. Supports user interface applications for accessing and managing the SM.
A set of APIs with exactly the same functionality is also available for the Java environment.
Cisco Service Center Release |
Part Number |
Publication Date |
---|---|---|
Release 3.0.5 |
OL-7203-04 |
November, 2006 |
Description of Changes
Addition of the reconnect timeout parameter to the C++ init method. See C++ init Method and C++ init Method.
Addition of the setReconnectTimeout method. See setReconnectTimeout and setReconnectTimeout.
Cisco Service Center Release |
Part Number |
Publication Date |
---|---|---|
Release 3.0.3 |
OL-7203-03 |
May, 2006 |
Description of Changes
Updated documentation for Release 3.0.3. No major changes or new features were added to this release.
Release 3.0 |
OL-7203-02 |
December, 2005 |
This guide is for the networking or computer technician responsible for configuring the Subscriber Manager. It is also intended for the operator who manages the SCE platforms.
This Programmer Guide contains the following topics:
Chapter |
Title |
Description |
---|---|---|
Chapter 1 |
Describes the platforms on which the C/C++ API can be used, how to install, compile, and start running the C/C++ API component. | |
Chapter 2 |
Provides a description of the various concepts that are used when working with the SM C/C++ API. | |
Chapter 3 |
Describes the features and operations of the Blocking API and provides code examples. | |
Chapter 4 |
Describes the features and operations of the Non-blocking API and provides code examples. | |
Appendix A |
Provides a list of error codes that are used in the C/C++ API. |
This API Programmer Guide should be used in conjunction with all of the SCMS Subscriber Manager User, API, and Reference Guides.
This document uses the following conventions:
Convention |
Description |
---|---|
boldface font |
Commands and keywords are in boldface. |
italic font |
Arguments for which you supply values are in italics. |
[ ] |
Elements in square brackets are optional. |
{x | y | z} |
Alternative keywords are grouped in braces and separated by vertical bars. |
[x | y | z] |
Optional alternative keywords are grouped in brackets and separated by vertical bars. |
string |
A nonquoted set of characters. Do not use quotation marks around the string, or the string will include the quotation marks. |
|
Terminal sessions and information that the system displays are in |
|
Information you must enter is in |
|
Arguments for which you supply values are in |
® |
This pointer highlights an important line of text in an example. |
< > |
Nonprinting characters, such as passwords, are in angle brackets. |
[ ] |
Default responses to system prompts are in square brackets. |
!, # |
An exclamation point (!) or a pound sign (#) at the beginning of a line of code indicates a comment line. |
Means reader take note. Notes contain helpful suggestions or references to materials not covered in this manual.
Means reader be careful. In this situation, you might do something that could result in loss of data.
The following sections provide sources for obtaining documentation from Cisco Systems.
You can access the most current Cisco documentation on the World Wide Web at the following sites:
Cisco documentation and additional literature are available in a CD-ROM package that ships with your product. The Documentation CD-ROM is updated monthly and may be more current than printed documentation. The CD-ROM package is available as a single unit or as an annual subscription.
Cisco documentation is available in the following ways:
Registered Cisco Direct Customers can order Cisco Product documentation from the networking Products MarketPlace:
Registered Cisco.com users can order the Documentation CD-ROM through the online Subscription Store:
Nonregistered Cisco.com users can order documentation through a local account representative by calling Cisco corporate headquarters (California, USA) at 408 526-7208 or, in North America, by calling 800 553-NETS(6387).
If you are reading Cisco product documentation on the World Wide Web, you can submit technical comments electronically. Click Feedback in the toolbar and select Documentation. After you complete the form, click Submit to send it to Cisco.
You can e-mail your comments to bug-doc@cisco.com.
To submit your comments by mail, use the response card behind the front cover of your document, or write to the following address:
Attn Document Resource Connection Cisco Systems, Inc. 170 West Tasman Drive San Jose, CA 95134-9883
We appreciate your comments.
Cisco provides Cisco.com as a starting point for all technical assistance. Customers and partners can obtain documentation, troubleshooting tips, and sample configurations from online tools. For Cisco.com registered users, additional troubleshooting tools are available from the TAC website.
Cisco.com is the foundation of a suite of interactive, networked services that provides immediate, open access to Cisco information and resources at any time, from anywhere in the world. This highly integrated Internet application is a powerful, easy-to-use tool for doing business with Cisco.
Cisco.com provides a broad range of features and services to help customers and partners streamline business processes and improve productivity. Through Cisco.com, you can find information about Cisco and our networking solutions, services, and programs. In addition, you can resolve technical issues with online technical support, download and test software packages, and order Cisco learning materials and merchandise. Valuable online skill assessment, training, and certification programs are also available.
Customers and partners can self-register on Cisco.com to obtain additional personalized information and services. Registered users can order products, check on the status of an order, access technical support, and view benefits specific to their relationships with Cisco.
To access Cisco.com, go to http://www.cisco.com.
The Cisco Technical Assistance Center (TAC) website is available to all customers who need technical assistance with a Cisco product or technology that is under warranty or covered by a maintenance contract.
If you have a priority level 3 (P3) or priority level 4 (P4) problem, contact TAC by going to the TAC website http://www.cisco.com/tac.
P3 and P4 level problems are defined as follows:
P3—Your network is degraded. Network functionality is noticeably impaired, but most business operations continue.
P4—You need information or assistance on Cisco product capabilities, product installation, or basic product configuration.
In each of the above cases, use the Cisco TAC website to quickly find answers to your questions.
To register for Cisco.com, go to http://tools.cisco.com/RPF/register/register.do.
If you cannot resolve your technical issue by using the TAC online resources, Cisco.com registered users can open a case online by using the TAC Case Open tool at http://www.cisco.com/tac/caseopen.
If you have a priority level 1 (P1) or priority level 2 (P2) problem, contact TAC by telephone and immediately open a case. To obtain a directory of toll-free numbers for your country, go to http://www.cisco.com/warp/public/687/Directory/DirTAC.shtml.
P1 and P2 level problems are defined as follows:
P1—Your production network is down, causing a critical impact to business operations if service is not restored quickly. No workaround is available.
P2—Your production network is severely degraded, affecting significant aspects of your business operations. No workaround is available.
This section describes the platforms on which the SM C/C++ API can be used and how to install, compile, and start running the SM C/C++ API.
The SCMS SM C/C++ API was developed and tested on Windows, Solaris, and Linux platforms. It was compiled on Windows using Microsoft Visual C++ 6 compiler, on Solaris using the GCC 2.95.3 compiler, and on Linux using GCC 3.2.3 compiler.
The SCMS SM C/C++ API distribution is part of the SCMS SM-LEG distribution file and is located in the sm_api directory. The SCMS SM C/C++ API is packaged in a UNIX tar file. You can extract the SCMS SM C/C++ API using the UNIX tar utility or most Windows compression utilities.
To install the distribution on a UNIX platform:
Extract the SCMS SM-LEG distribution file and locate the C/C++ SM API distribution tar sm-c-api-dist.tar
file
Extract the C/C++ SM API package tar:
#
> tar -xvf sm-c-api-dist.tar
For brevity, the installation directory sm-c-api-vvv.bb
is referred to as
<installdir>
.
The abbreviations vvv and bb stand for the SCMS SM C/C++ API version and build number
The <installdir>/winnt
folder contains the smapi.dll
file, which is the Windows API Executable. It also contains additional DLL and LIB files necessary for the Windows API operation.
The <installdir>/solaris
folder contains the libsmapi.so
file, which is the Solaris API Executable.
The <installdir>/linux
folder contains the libsmapi.so
file, which is the Linux API Executable.
The <installdir>/include
folder contains the API C/C++ header files.
The <installdir>/include/system
folder contains the C++ API internal header files.
Table 1.1. Layout of Installation Directory
Folder |
Subfolder (as applicable) |
File Name |
---|---|---|
<installdir> |
|
README.csmapi |
|
Include |
BasicTypes.h |
|
|
Common.h |
|
|
GeneralDefs.h |
|
|
Logger.h |
|
|
PrintLogger.h |
|
|
SmApiBlocking.h |
|
|
SmApiBlocking_c.h |
|
|
SmApiNonBlocking.h |
|
|
SmApiNonBlocking_c.h |
|
Include/System |
OperationHandleInterface.h |
|
|
OperationResultInterface.h |
|
Linux |
libsmapi.so |
|
Solaris |
libsmapi.so |
|
Winnt |
asn1ber.dll |
|
|
asn1ber.lib |
|
|
asn1rt.dll |
|
|
asn1rt.lib |
|
|
SmApi.dll |
|
|
SmApi.lib |
To compile and run a program that uses the SCMS SM C/C++ API:
Ensure that smapi.dll
and the other DLL files are in your path or in the directory of your executable.
Ensure that the include
folder is in your include path of the compilation.
Example using Microsoft Visual C++ 6:
Enter the project settings, click the C++ tab, and then choose the Preprocessor category. Add the include directory path in the Additional Include directories line.
Ensure that the smapi.lib
file is in your linkage path.
Example using Microsoft Visual C++ 6:
Enter the project settings and click the Link tab. Add smapi.lib to the Object\Library modules line.
Include the relevant API header file in your source code, and compile your code.
To compile and run a program that uses the SM C/C++ API:
Ensure that libsmapi.so
is in your LD_LIBRARY_PATH.
For example, when using the Bash shell type, use the following command line:
bash-2.03$ export set LD_LIBRARY_PATH=$LD
LIBRARY_PATH:the-libsmapi.so-folder
Ensure that the include
folder is in your include path of the compilation.
For example, when using the GCC, add the include folder after the -I
option flag, as follows:
> gcc -c -o TestSmApi.o -Ism-api-header-file-folder
-Ism-api-header-file-folder/system/ TestSmApi.cpp
Ensure that the libsmapi.so
file is in your linkage line or load it dynamically.
Link your object file to the pthread and socket library, as follows:
> gcc -o testSmApi TestSmApi.o -lsmapi -lpthread -lsocket
To compile and run a program that uses the SM C/C++ API:
Ensure that libsmapi.so
is in your LD_LIBRARY_PATH.
For example, when using the Bash shell type, use the following command line:
bash-2.03$ export set LD_LIBRARY_PATH=$LD
LIBRARY_PATH:the-libsmapi.so-folder
Ensure that the include
folder is in your include path of the compilation.
For example, when using the GCC, add the include folder after the -I
option flag, as follows:
> gcc -c -o TestSmApi.o -Ism-api-header-file-folder
-Ism-api-header-file-folder/system/ TestSmApi.cpp
Ensure that the libsmapi.so
file is in your linkage line or load it dynamically. Specify the location of libsmapi.so
using the -L
option flag. Link your object file to the pthread and stdc++ libraries, as follows:
> gcc -o testSmApi TestSmApi.o -lsmapi -lpthread -lstdc++ -L<lib path>
The API connects to the PRPC server on the SM. For the API to work, the following conditions must be met:
The SM must be up and running, and reachable from the machine that hosts the API.
The PRPC server on the SM must be started.
The PRPC server is a proprietary RPC protocol designed by Cisco. For additional information, see the Cisco SCMS Subscriber Manager User Guide.
This chapter describes various concepts that are used when working with the SCMS SM C/C++ API.
This section describes the differences between the Blocking API and Non-blocking API operations.
In a Blocking API operation, which is the common type, every method returns after its operation has been performed.
The SM Blocking C/C++ API provides a wide range of operations and is a superset of the Non-blocking API functionality.
In a Non-blocking API operation, every method returns immediately, even before the completion of its operation. The operation results are returned either to a set of user defined callbacks or not returned at all.
The Non-blocking method is advantageous when the operation is lengthy and involves I/O. Performing the operation in a separate thread allows the calling program to continue doing other tasks and it improves overall system performance.
The SM Non-blocking C/C++ API contains a small number of Non-blocking operations. The API supports retrieval of operation results using result callbacks.
The SCMS SM C/C++ API is reliable in the sense that the operations performed on the API are kept until the SM returns their associated results. If the connection to the SM is lost, operations that were not sent to the SM and operations whose results did not yet return from the SM are sent to the SM immediately on reconnection. The order of operation invocation is maintained at all times.
The C and C++ APIs are essentially the same. The C API is actually a thin wrapper over the C++ API, with method prototype and signature changes imposed by the constraint of C not being an object-oriented programming language.
The following sections describe the C/C++ API differences and provide some examples.
The method names of the C API are the same as in the C++ API, except that the C API method names have an identifying prefix:
The Blocking C API method names are prefixed with SMB_
.
The Non-blocking C API methods are prefixed with SMNB_
.
The documentation of methods in this guide uses the name and signature of the C++ API methods.
The Blocking and Non-blocking APIs are C++ Objects. Several API instances can co-exist in a single process, each having its own socket and state. To provide the same functionality in the C API, the handle concept is introduced. Each C API method accepts a handle as its first argument. The handle is used to identify the C API instance on which the caller wants to operate. Calling the SMB_init
or SMNB_init
method creates a new C API instance; the return value of these methods provides the handle to the instance. For more information, see API Initialization.
The following C++ Blocking API logoutByName
method signature:
ReturnCode* logoutByName(char* argName,
char** argMappings,
MappingType* argMappingTypes,
int argMappingsSize)
is translated into C Blocking API as:
ReturnCode* SMB_logoutByName(SMB_HANDLE argApiHandle, char* argName, char** argMappings, MappingType* argMappingTypes, int argMappingsSize);
The following C++ Non-blocking API logoutByName
method signature:
int logoutByName(char* argName,
char** argMappings,
MappingType* argMappingTypes,
int argMappingsSize);
is translated into C Non-blocking API as:
int SMNB_logoutByName(SMNB_HANDLE argApiHandle,
char* argName,
char** argMappings,
MappingType* argMappingTypes,
int argMappingsSize);
To initialize the API:
Construct the API using one of its two constructors.
Perform API-specific setup operations.
Connect the API to the SM.
The following sections describe these three steps.
Initialization examples can be found in the code examples sections under each API.
Both C and C++ Blocking and Non-blocking APIs must construct and initialize the API. Be sure to check that the initialization has succeeded before proceeding.
To construct and initialize the API:
For the C++ API, construct an API object and call the init
function. For example:
SmApiNonBlocking nbapi;
If (!nbapi.init(0,2000000,10,30)) {
exit(1);
}
For the C API, call the init
function, which allocates and initializes the API. For example:
SMNB_HANDLE nbapi = SMNB_init(0,2000000,10,30);
if (nbapi == NULL) {
exit(1);
}
Set the Login Event Generator (LEG) name if you intend to turn on the SM-LEG failure handling options in the SM. For more information about LEGs and SM-LEG failure handling, see the SCMS Subscriber Manager User Guide.
To set the LEG name, call the relevant setName
function in the API. The SM will use the LEG name when recovering from a connection failure. A constant string that identifies the API will be appended to the LEG name as follows:
For Blocking API: .B.SM-API.C
For Non-blocking API: .NB.SM-API.C
If the provided LEG name is my-leg.10.1.12.45-version-1.0
, the actual LEG name will be my-leg.10.1.12.45-version-1.0.B.SM-API.C
If no name is set, the LEG uses the hostname of the machine as the prefix of the name.
For additional information about SM-LEG failure handling, see Appendix A of the Cisco SCMS Subscriber Manager User Guide.
The setup operations for the two APIs differ. Both APIs support setting a disconnect listener, which is described in the Disconnect Callback Listener section.
The following sections describe the setup operations for the Blocking API and the Non-blocking API.
To set up the Blocking API, you must set an operation timeout value. For more information, see Blocking API.
To set up the Non-blocking API you are required to set a disconnect callback, see Non-blocking API.
To connect to the SM, use one of the following connect methods:
Do one of the following:
The following example shows how to connect when using the C++ APIs:
connect(char* host, Uint16 argPort = 14374)
The following example shows how to connect when using the C Blocking API:
SMB_connect(SMB_HANDLE argApiHandle, char* host, Uint16 argPort)
The following example shows how to connect when using the C Non-blocking API:
SMNB_connect(SMNB_HANDLE argApiHandle, char* host, Uint16 argPort)
The argHostName
parameter can be either an IP address or a reachable hostname. At any time during the API operation, you can check if the API is connected by using one of the variants of the function isConnected
.
Both C and C++ Blocking and Non-blocking APIs must disconnect from the SM and free the memory of the API:
For the C++ APIs, call the disconnect
method and free the API object.
For the C APIs, call the appropriate disconnect
function and then free the API using the appropriate release
function.
The results of the API operations are returned using a generic structure called ReturnCode
. The ReturnCode
structure contains several parameters:
u
—A union of all of variables and pointers to variables that are the actual returned value.
type
—A return code type parameter (ReturnCodeType
enumeration) that defines the type of the value (u
) that the ReturnCode
structure holds.
size
—The number of elements in the value. If size
equals 1 then there is one element in the value, such as a scalar, character string, void, or error. If size
is greater than 1 then there are several elements in the array, and the type should be one of the array types.
The API allocates the return code structure and the API user must free the structure. You can use the freeReturnCode
utility function to safely free the structure.
Additional return code structure utility functions are:
printReturnCode
—Prints the ReturnCode
structure value to the stdout
isReturnCodeError
—Checks whether the ReturnCode
structure is an error
From GeneralDefs.h header file:
OSAL_DllExport typedef struct ReturnCode_t { ReturnCodeType type; int size; /* number of elements in the union element (for example: stringVal will have size=1) */ union { /* use union value according to the type value */ bool boolVal; short shortVal; int intVal; long longVal; char* stringVal; bool* boolArrayVal; short* shortArrayVal; int* intArrayVal; long* longArrayVal; char** stringArrayVal; ErrorCode* errorCode; struct ReturnCode_t** objectArray; } u; }ReturnCode;
In the following example, the subscriber data of subscriber1 is retrieved and displayed. The returned structure contains an array of ReturnCode structures held by the objectArray
union value. Each structure contains a different value type. For additional information, see the explanation of the getSubscriber method. This example code uses the isReturnCodeError
and freeReturnCode methods
.
ReturnCode* subFields = bapi.getSubscriber(“subscriber1”);
if (isReturnCodeError(subFields) == false)
{
printf("\tname:\t\t%s\n", subFields->u.objectArray[0]->u.stringVal);
printf("\tmapping:\t%s\n",
subFields->u.objectArray[1]->u.stringArrayVal[0]);
printf("\tdomain:\t\t%s\n", subFields->u.objectArray[3]->u.stringVal);
printf("\tautologout:\t%d\n", subFields->u.objectArray[8]->u.intVal);
}
else
{
printf("error in subscriber retrieval\n");
}
freeReturnCode(subFields);
The ErrorCode
structure can be one of the values of the return code structure. This structure describes the error that occurred. The structure consists of the following parameters:
type
—An ErrorCodeType enumeration that describes the error. See the GeneralDefs.h
file for additional information
message
—A specific error code
name
—Currently not used
Most methods of both APIs require the subscriber name as an input parameter. This section lists the formatting rules of a subscriber name.
The subscriber name is case-sensitive. It can contain up to 40 characters. You can use any of the following characters:
alphanumerics |
$ (dollar sign) |
. (period or dot) |
_ (underscore) |
- (minus sign or hyphen) |
% (percent sign) |
/ (slash) |
~ (tilde) |
! (exclamation mark) |
& (ampersand) |
: (colon) |
' (apostrophe) |
# (number sign) |
() (parentheses) |
@ (at sign) |
|
A network ID mapping is a network identifier that the SCE device can relate to a specific subscriber record. A typical example of a network ID mapping (or simply mapping) is an IP address. For additional information, see the Cisco SCMS Subscriber Manager User Guide. Currently, the Cisco Service Control Solution supports IP address, IP range, and VLAN mappings.
Both Blocking and Non-blocking APIs contain operations that accept mappings as a parameter. Examples are:
The addSubscriber
operation (Blocking APIs)
The login
method (Blocking or Non-blocking APIs)
When passing mappings to an API method, the caller is requested to provide two parameters:
A character string (char*
) mapping identifiers or array of character strings (char**
) mappings.
A MappingType
enumeration or array of MappingType
variables.
When passing arrays, the MappingType
variables array must contain the same number of elements as the mappings array.
The API supports the following subscriber mapping types (defined by the MappingType
enumeration):
IP addresses or IP ranges
VLAN tags
The string format of an IP address is the commonly used decimal notation:
IP-Address=[0-255].[0-255].[0-255].[0-255]
216.109.118.66
The GeneralDefs.h
header file provides the mapping type of an IP address:
IP_RANGE
specifies IP mapping (IP-Address or IP-Range that matches the mapping identifier with the same index in the mapping identifier array).
The string format of an IP range is an IP address in decimal notation and a decimal specifying the number of 1s in a bit mask:
IP-Range=[0-255].[0-255].[0-255].[0-255]/[0-32]
10.1.1.10/32
is an IP range with a full mask, that is, a regular IP address.
10.1.1.0/24
is an IP range with a 24-bit mask, that is, all the addresses ranging between 10.1.1.0
and 10.1.1.255
.
The mapping type of an IP Range is identical to the mapping type of the IP address.
The string format for VLAN tag mapping is: VLAN-tag = 0-4095
.
The string is a decimal in the specified range.
The GeneralDefs.h
header file also provides the mapping type:
VLAN
specifies a VLAN mapping that matches the mapping identifier with the same index in the mapping identifier array.
The Cisco SCMS Subscriber Manager User Guide explains the domain concept in detail. Briefly, a domain is an identifier that tells the SM which SCE devices to update with the subscriber record.
A domain name is of type (char*
). During system installation, the network administrator determines the system domain names, which therefore vary between installations. The APIs include methods that specify to which domain a subscriber belongs and allow queries about the system's domain names. If an API operation specifies a domain name that does not exist in the SM domain repository, it is considered an error and an ERROR_CODE_DOMAIN_NOT_FOUND
error ReturnCode
will be returned.
Several operations manipulate subscriber properties. A subscriber property is a key-value pair that affects the way the SCE analyzes and reacts to network traffic generated by the subscriber.
More information about properties can be found in the Cisco SCMS Subscriber Manager User Guide and in the Cisco Service Control Application for Broadband (SCA BB) User Guide. The application user guide provides application-specific information. It lists the subscriber properties that exist in the application running on your system, the allowed value set, and the significance of each property value.
To format subscriber properties for C/C++ API operations, use the String arrays (char**
) propertyKeys
and propertyValues
.
The arrays must be of the same length, and NULL entries are forbidden. Each key in the keys array has a matching entry in the values array. The value for propertyKeys[j]
resides in propertyValues[j]
.
If the property keys array is {
“name”,“color”,“shape”}
and the property values array is {
“john”,“red”,“circle”}
, the properties will be name=john, color=red, shape=circle
.
Some operations manipulate custom properties. Custom properties are similar to subscriber properties, but do not affect how the SCE analyzes and manipulates the subscriber's traffic. The application management modules use custom properties to store additional information for each subscriber.
To format custom properties, use the string (char**
) arrays customPropertyKeys
and customPropertyValues
, the same as used in formatting Subscriber Properties.
The API package contains a Logger
abstract class that can be inherited and used to integrate the SM API with the host application log. The Logger
class exposes four basic levels of logging: error messages, warning messages, informative messages, and several levels of trace messages. Both the Blocking and Non-blocking API have this capability. The Logger.h
header file provides the Logger
class.
The API user should implement a logger by inheriting from the Logger
class. To have the API use this logger, the code should call the API's setLogger
method of the C++ implementation of the API.
For testing and for simple LEG implementations, the API package provides the PrintLogger class, which is a simple implementation of the Logger
class that prints the log messages to the standard error (STDERR). An API user can initiate the PrintLogger
object, set its logging level using the setLoggingLevels
method of the PrintLogger
class, and pass the logger object to the API using the API setLogger
method. The PrintLogger.h
header file provides the PrintLogger
class.
Both Blocking and Non-blocking APIs allow setting a disconnect callback listener to be notified when the API is disconnected from the SM. The disconnect callback is defined as follows:
typedef void (*ConnectionIsDownCallBackFunc)();
To set the disconnect listener, use the setDisconnectListener
method.
The SCMS SM C/C++ API as a networking module might handle sockets that are closed by the SM, for example, if the SM is restarted, which may cause “Broken Pipe” signals. It is especially advisable for the UNIX environment to handle this signal.
To ignore the signal, add the following call:
sigignore(SIGPIPE);
When implementing the code that integrates the API with your application, you should consider the following practical tips:
Connect to the SM once and maintain an open API connection to the SM at all times, using the API many times. Establishing a connection is a timely procedure, which allocates resources on the SM side and the API client side.
Share the API connection between your threads. It is better to have one connection per LEG. Multiple connections require more resources on the SM and client side.
Do not implement synchronization of the calls to the API. The client automatically synchronizes calls to the API.
It is recommended to place the API clients (LEGs) in the same order of the SM machine processor number.
If the LEG application has bursts of logon operations, enlarge the internal buffer size accordingly to hold these bursts (Non-Blocking flavor).
During the integration, set the SM logon_logging_enabled
configuration parameter to view the API operations in the SM log to troubleshoot the integration, if any problems arise.
Use the debug mode for the LEG application that logs/prints the return values of the non-blocking operations.
Use the automatic reconnect feature to improve the resiliency of the connection to the SM.
In cluster setups, connect the API using the virtual IP address of the cluster and not the management IP address of one of the machines.
This chapter introduces the Reply Timeout, a feature unique to the Blocking API. It also lists all operations of the Blocking API, and provides code examples.
If you only need to develop an automatic integration, skip this chapter and go directly to the Non-blocking API chapter.
The Blocking API supports a configurable number of threads calling its methods simultaneously. For more information about configuring the number of threads, see the init method.
In a multi-threaded scenario for the Blocking API, the order of invocation is not guaranteed.
Thread0 calls operation0 at time0, and thread1 calls operation1 at time1, where time1 is later than time0. In this example, it is possible that operation1 may be performed before operation0, as shown in the following diagram (the vertical scale is time):
The SM allocates five threads to handle each API instance. It is recommended to develop a multi-threaded application that uses the API with a number of threads in the order of the five threads. Implementing with more threads might result in longer delays for the calling threads.
A Blocking operation returns only when the operation result has been retrieved from the SM. If a networking malfunction or other error prevents the operation result from being retrieved, the caller will wait indefinitely. The SM API provides means of working around this situation.
The reply timeout feature, the setReplyTimeout
method, lets the caller set a timeout. It will return a ReturnCode with the ERROR_CODE_CLIENT_OPERATION_TIMEOUT
error when a reply does not return within the timeout period.
Calling the setReplyTimeout
function with an int
value sets a reply timeout. The reply timeout is interpreted in milliseconds. A zero value indicates that the operation should wait (freeze, hang) until a result arrives - or indefinitely, if no result arrives.
This section lists the methods of the Blocking API. A description of each method's input parameters and return values follows the syntax of each method.
The Blocking API is a superset of the Non-blocking API. Except for differences in return values and result handling, identical operations in both APIs have the same functions and syntax structure.
The C/C++ API share the same function signature, except for the SMB_
prefix for all function names of the Blocking C APIs and the API handle of type SMB_HANDLE
as the first parameter in all functions. The function description explains any other differences between the APIs.
The Blocking API subscriber management methods can be classified into the following categories:
Dynamic IP and property allocation—For using the SM API for integration with an AAA system, the following methods are relevant:
These methods are not designed to add or remove subscribers from the database, but to modify dynamic parameters (such as IP addresses) of existing subscribers.
Static/Manual Subscriber configuration—For example for GUI usage, the following methods are relevant:
For simple read-only operations performed independently in subscriber awareness mode, the following methods are relevant:
It is possible to combine methods from different categories in a single application. The classification is presented for clarification purposes only.
Methods used for API maintenance - initialization, connection, disconnect:
The examples that appear at the end of the described methods are in C++. Every example described at the end of the methods should be preceded by the sample code below:
SmApiBlocking bapi;
// Init with default parameters
bapi.init();
// Connect to the SM
bapi.connect((char*)"1.1.1.1");
ReturnCode* login( char* argName,
char** argMappings,
MappingType* argMappingTypes,
int argMappingsSize,
char** argPropertyKeys,
char** argPropertyValues,
int argPropertySize,
char* argDomain,
bool argIsAdditive,
int argAutoLogoutTime)
The login
method adds or modifies a domain, mappings, and properties of a subscriber that already exists in the SM database. It can be called with partial data; for example, with only mappings or only properties provided and NULL put in the unchanged fields.
If another subscriber with the same (or colliding) mappings already exists in the same domain, the colliding mappings will be removed from the other subscriber and assigned to the new subscriber.
If the subscriber does not exist in the SM database, it will be created with the data provided.
argName
—See explanation of subscriber name format.
argMappings
—See explanation of mappings and mapping types.
If no mappings are specified, and the argIsAdditive
flag is TRUE, the previous mappings will be retained. If no such mappings exist, the operation will fail.
argMappingTypes
—See explanation of mappings and mapping types.
argMappingsSize
—The size of the argMappings
and argMappingTypes
arrays.
argPropertyKeys
—See explanation of property keys and values in the General API Concepts chapter.
argPropertyValues
—See explanation of property keys and values in the General API Concepts chapter.
argPropertySize
—The size of the argPropertyKeys
and argPropertyValues
arrays.
argDomain
—See explanation of domains.
If domain is NULL, but the subscriber already has a domain, the existing domain will be retained.
ArgIsAdditive
—Refers to the mappings parameters.
TRUE—Adds the mappings provided by this call to the subscriber record.
FALSE—Overrides the mappings that already exist in the subscriber record with the mappings provided by this call.
argAutoLogoutTime
—Applies only to mappings provided as arguments to this method.
Positive value (N)—Automatically logs out the mappings (similar to a logout method being called) after N seconds.
0 value—Maintains current expiration time for the given mappings.
Negative value—Disables any expiration time that might have been set for the mappings given.
The following is the list of error codes that this method might return:
ERROR_CODE_ILLEGAL_SUBSCRIBER_NAME
ERROR_CODE_BAD_SUBSCRIBER_MAPPING
ERROR_CODE_SUBSCRIBER_DOMAIN_ASSOCIATION
ERROR_CODE_DATABASE_EXCEPTION
ERROR_CODE_UNKNOWN
The following can cause this error:
NULL value for the domain
parameter for the subscriber that does not exist/does not have a domain
Invalid values for the propertyValues
parameter
For a description of error codes, see List of Error Codes.
To add the IP address 192.168.12.5 to an existing subscriber named john without affecting existing mappings:
MappingType map_type = IP_RANGE;
char* ip_address = "192.168.12.5";
bapi.login(
“john”, // subscriber name
&ip_address,
&map_type,
1, // one mapping
NULL, NULL, 0, // no properties
“subscribers”, // domain
true, // isMappingAdditive is true
-1); // autoLogoutTime set to infinite
To add the IP address 192.168.12.5 overriding previous mappings:
MappingType map_type = IP_RANGE;
char* ip_address = "192.168.12.5";
bapi.login(
“john”, // subscriber name
&ip_address,
&map_type,
1,
NULL, NULL,0,
“subscribers”, // domain
false, // isMappingAdditive is false
-1); // autoLogoutTime set to infinite
To extend the auto logout time of 192.168.12.5 that was previously assigned to john:
MappingType map_type = IP_RANGE;
char* ip_address = "192.168.12.5";
bapi.login(
“john”, // subscriber name
&ip_address,
&map_type,
1,
NULL, NULL, 0,
“subscribers”, // domain
false, // isMappingAdditive is false
300); // autoLogoutTime set to 300 seconds
To modify a dynamic property of john (e.g. package ID):
char* prop_name = "packageID";
char* prop_value = "10";
bapi.login(
“john”,
NULL, NULL, 0,
&prop_name, // property key
&prop_value, // property value
1, // one property
“subscribers”, // domain
false,
-1);
To add the IP address 192.168.12.5 to an existing subscriber named john without affecting existing mappings and modify a dynamic property of john (e.g. package ID):
MappingType map_type = IP_RANGE;
char* ip_address = "192.168.12.5";
char* prop_name = "packageID";
char* prop_value = "10";
bapi.login(
“john”,
&ip_address,
&map_type,
1,
&prop_name, // property key
&prop_value, // property value
1,
“subscribers”, // domain
true, // isMappingAdditive is set to true
-1);
ReturnCode* logoutByName( char* argName,
char** argMappings,
MappingType* argMappingTypes,
int argMappingsSize)
argName
—See explanation of subscriber name format.
argMappings
—See explanation of mappings and mapping types.
If no mappings are specified, all the subscriber mappings will be removed.
argMappingTypes
—See explanation of mappings and mapping types.
argMappingsSize
—The size of the argMappings
and argMappingTypes
arrays.
A pointer to a ReturnCode
structure with a Boolean type:
TRUE—If the subscriber was found and the subscriber mappings were removed from the subscriber database.
FALSE—If the subscriber was not found in the subscriber database.
The following is the list of error codes that this method might return:
ERROR_CODE_SUBSCRIBER_DOES_NOT_EXIST
ERROR_CODE _BAD_SUBSCRIBER_MAPPING
ERROR_CODE_SUBSCRIBER_DOMAIN_ASSOCIATION
ERROR_CODE_DOMAIN_NOT_FOUND
ERROR_CODE_NOT_A_SUBSCRIBER_DOMAIN
ERROR_CODE_DATABASE_EXCEPTION
For a description of error codes, see List of Error Codes.
ReturnCode* logoutByNameFromDomain (char* argName,
char** argMappings,
MappingType* argMappingTypes,
int argMappingsSize,
char* argDomain)
Locates the subscriber in the database according to the specified domain and removes mappings from the subscriber.
argName
—See explanation of subscriber name format.
argMappings
—See explanation of mappings and mapping types.
If no mappings are specified, all the subscriber mappings will be removed.
argMappingTypes
—See explanation of mappings and mapping types.
argMappingsSize
—The size of the argMappings
and argMappingTypes
arrays.
argDomain
—See explanation of domains.
The operation will fail if either of the following conditions exists:
The domain is null, but the subscriber exists in the database and belongs to a domain.
The domain specified is incorrect.
A pointer to a ReturnCode
structure with a Boolean type:
TRUE—If the subscriber was found and the subscriber mappings were removed from the subscriber database.
FALSE—If the subscriber was not found in the subscriber database.
The following is the list of error codes that this method might return:
ERROR_CODE_SUBSCRIBER_DOES_NOT_EXIST
ERROR_CODE _BAD_SUBSCRIBER_MAPPING
ERROR_CODE_SUBSCRIBER_DOMAIN_ASSOCIATION
ERROR_CODE_DOMAIN_NOT_FOUND
ERROR_CODE_NOT_A_SUBSCRIBER_DOMAIN
ERROR_CODE_DATABASE_EXCEPTION
For a description of error codes, see List of Error Codes.
To remove IP address 192.168.12.5 of subscriber john from domain subscribers:
MappingType map_type = IP_RANGE;
char* ip_address = "192.168.12.5";
bapi.logoutByNameFromDomain(
“john”,
&ip_address,
&map_type,
1,
“subscribers”);
To remove all IP addresses of subscriber john from domain subscribers:
bapi.logoutByNameFromDomain(
“john”,
NULL,
NULL,
0,
“subscribers”);
Locates a subscriber based on domain and mapping, and removes the subscriber mappings. The subscriber remains in the database.
argMapping
—See explanation of mappings and mapping types.
argMappingType
—See explanation of mappings and mapping types.
argDomain
—See description in logoutByNameFromDomain
operation.
A pointer to a ReturnCode
structure with a Boolean type:
TRUE—If the subscriber was found and removed from the subscriber database.
FALSE—If the subscriber was not found in the subscriber database.
The following is the list of error codes that this method might return:
ERROR_CODE_SUBSCRIBER_DOES_NOT_EXIST
ERROR_CODE _BAD_SUBSCRIBER_MAPPING
ERROR_CODE_SUBSCRIBER_DOMAIN_ASSOCIATION
ERROR_CODE_DOMAIN_NOT_FOUND
ERROR_CODE_NOT_A_SUBSCRIBER_DOMAIN
ERROR_CODE_DATABASE_EXCEPTION
For a description of error codes, see List of Error Codes.
ReturnCode* loginCable( char* argCpe,
char* argCm,
char* argIp,
int argLease,
char* argDomain,
char** argPropertyKeys,
char** argPropertyValues,
int argPropertySize)
A login method adapted for the cable environment, which calls the cable support module in the SM. This method logs in CPEs to the SM. To log in a CM, specify the CM MAC address in both CPE and CM arguments. For additional information, see the Cable Environment Appendix of the Cisco SCMS Subscriber Manager User Guide.
The name of the CPE in the SM database is the concatenation of the CPE and CM values with two underscore [“_”] characters between them. The caller must make sure that the lengths of CPE and CM add up to no more than 38 characters.
argCpe
—A unique identifier of the CPE (usually a MAC address).
argCm
—A unique identifier of the cable modem (usually a MAC address).
argIp
—The CPE IP address.
argLease
—The CPE lease time.
argDomain
—See explanation of domains.
The domain will usually be CMTS IP.
Domain aliases must be set on the SM in order to correctly interpret the CMTS IP as a domain name. For information regarding aliases configuration, see the Configuring Domains section of Cisco SCMS Subscriber Manager User Guide.
argPropertyKeys
—See explanation of the keys and values of the Subscriber Properties.
If the CPE is provided with partial or no application properties, the values for the missing application properties will be copied from the application properties of the CM to which this CPE belongs. Each CM application property thus serves as a default for the CPE under it.
argPropertyValues
—See explanation of the keys and values of the Subscriber Properties.
argPropertySize
—The size of the argPropertyKeys
and argPropertyValues
arrays.
To add the IP address 192.168.12.5 to a CM called CM1 with 2 hours lease time:
bapi.loginCable(
“CM1”,
“CM1”,
“192.168.12.5”,
7200, // lease time in seconds
“subscribers”,
NULL, NULL, 0); // no properties
To add the IP address 192.168.12.50 to a CPE called CPE1 behind CM1 with a lease time of 1 hour:
bapi.loginCable(
“CPE1”,
“CM1”,
“192.168.12.50”,
3600, // lease time in seconds
“subscribers”,
NULL, NULL, 0);
argCpe
—See description in the loginCable method.
argCm
—See description in the loginCable method.
argIp
—See description in the loginCable method.
argDomain
—See description in the loginCable method.
A pointer to a ReturnCode
structure with a Boolean type:
TRUE—If the CPE was found and removed from the subscriber database.
FALSE—If the CPE was not found in the subscriber database.
ReturnCode* addSubscriber( char* argName,
char** argMappings,
MappingType* argMappingTypes,
int argMappingsSize,
char** argPropertyKeys,
char** argPropertyValues,
int argPropertySize,
char** argCustomPropertyKeys,
char** argCustomPropertyValues,
int argCustomPropertySize,
char* argDomain)
Creates a new subscriber record according to the given data and adds it to the SM database. If a subscriber by this name already exists, it will be removed before the new one is added. In contrast to login
, which modifies fields passed to it and leaves unspecified fields unchanged, addSubscriber
sets the subscriber exactly as specified by the parameters passed to it.
It is recommended to call the login
method for existing subscribers, instead of addSubscriber
. Dynamic mappings and properties should be set by using login
. Static mappings and properties should be set the first time the subscriber is created by using addSubscriber
.
With addSubscriber
, the auto-logout feature is always disabled. To enable auto-logout, use login
.
Subscriber AB, already set up in the subscriber database, has a single IP mapping of IP1.
If an addSubscriber
operation for AB is called with no mappings specified (NULL in both the mappings and mappingTypes fields), AB will be left with no mappings.
However, calling a login
operation with these NULL-value parameters will not change AB's mappings; AB will still have its previous IP mapping of IP1.
argName
—See explanation of subscriber name format.
argMappings
—See explanation of mappings and mapping types.
argMappingTypes
—See explanation of mappings and mapping types in the General API Concepts chapter.
argMappingsSize
—The size of the argMappings
and argMappingTypes
arrays.
argPropertyKeys
—See explanation of property keys and values in the General API Concepts chapter.
argPropertyValues
—See explanation of property keys and values in the General API Concepts chapter.
argPropertySize
—The size of the argPropertyKeys
and argPropertyValues
arrays.
argCustomPropertyKeys
—See explanation of custom property keys and values in the General API Concepts chapter.
argCustomPropertyValues
—See explanation of custom property keys and values in the General API Concepts chapter.
argPropertySize
—The size of the argCustomPropertyKeys
and argCustomPropertyValues
arrays.
argDomain
—See explanation of domains.
A NULL value indicates that the subscriber is domain-less.
The following is the list of error codes that this method might return:
ERROR_CODE_ILLEGAL_SUBSCRIBER_NAME
ERROR_CODE _BAD_SUBSCRIBER_MAPPING
ERROR_CODE_DOMAIN_NOT_FOUND
ERROR_CODE_SUBSCRIBER_ALREADY_EXISTS
ERROR_CODE_SUBSCRIBER_DOMAIN_ASSOCIATION
ERROR_CODE_DATABASE_EXCEPTION
ERROR_CODE_UNKNOWN
This error code indicates that invalid values were supplied for the propertyValues
parameter.
For a description of error codes, see List of Error Codes.
To add a new subscriber, john, with custom properties:
char* propKeys[] = { “work_phone”, “home_phone” };
char *propValues[] = { “123456”, “898765” };
bapi.addSubscriber(
“john”,
NULL, NULL, 0, // dynamic mappings will be set by login
NULL, NULL, 0, // dynamic properties will be set by login
propKeys, propValues, 2, // 2 custom properties
“subscribers”); // default domain
argName
—See explanation of Subscriber Name Format.
A pointer to a ReturnCode
structure with a Boolean type:
TRUE—If the subscriber was found in the database and successfully removed.
FALSE—If the conditions for TRUE were not met; i.e., the subscriber was not found in the database, or the subscriber was found but was not successfully removed.
The following is the list of error codes that this method might return:
ERROR_CODE_ILLEGAL_SUBSCRIBER_NAME
ERROR_CODE _SUBSCRIBER_DOES_NOT_EXIST
ERROR_CODE_DATABASE_EXCEPTION
For a description of error codes, see List of Error Codes.
Removes all subscribers from the SM, leaving the database with no subscribers.
This method might take time to execute. To avoid operation timeout exceptions, set a high operation timeout (up to 5 minutes) before calling this method.
A pointer to a ReturnCode
structure holding an integer describing the number of subscribers in the SM.
A pointer to a ReturnCode
structure holding an integer describing the number of subscribers in the domain provided.
The following is the list of error codes that this method might return:
ERROR_CODE_NOT_A_SUBSCRIBER_DOMAIN
ERROR_CODE _DOMAIN_NOT_FOUND
For a description of error codes, see List of Error Codes.
Retrieves a subscriber record. Each field is formatted as an integer, string, or string array, as described in the Return Value section for this method. If the subscriber does not exist in the SM database, an exception will be thrown.
argName
—See explanation of subscriber name format.
A pointer to a ReturnCode
structure holding an array of ReturnCode
structures with nine elements. No array element is NULL.
The following list is the element values and their meanings:
Index 0 |
subscriber name ( |
Index 1 |
array of mappings ( |
Index 2 |
array of mapping types ( |
Index 3 |
Domain name ( |
Index 4 |
array of property names ( |
Index 5 |
array of property values ( |
Index 6 |
array of custom property names ( |
Index 7 |
array of custom property values ( |
Index 8 |
array of auto-logout time, as seconds from now, or value of -1 if not set (long 1*) one per mapping (index1) |
The following is the list of error codes that this method might return:
ERROR_CODE_SUBSCRIBER_DOES_NOT_EXIST
ERROR_CODE_DATABASE_EXCEPTION
For a description of error codes, see List of Error Codes.
To retrieve the subscriber record of john:
ReturnCode* sub = bapi.getSubscriber(“john”);
// sub name
char* name = sub->u.objectArray[0]->u.stringVal;
// sub mapping
char** mappings = sub->u.objectArray[1]->u.stringArrayVal;
// mappings types
short* types = sub->u.objectArray[2]->u.shortArrayVal;
char* domainName = (char*)sub->u.objectArray[3]->u.stringVal;
char** propertyNames = (char**)sub->u.objectArray[4]->u.stringArrayVal;
char** propertyValues = (char**)sub->u.objectArray[5]->u.stringArrayVal;
char** customPropertyName = (char**)sub->u.objectArray[6]->u.stringArrayVal;
char** customPropertyValues = (char**)sub->u.objectArray[7]->u.stringArrayVal;
long* autoLogoutTime = sub->u.objectArray[8]->u.longArrayVal;
argName
—See explanation of subscriber name format.
A pointer to a ReturnCode
structure with a Boolean type:
TRUE—If the subscriber was found in the SM database.
FALSE—If the subscriber could not be found.
Checks whether a subscriber that already exists in the SM database is logged in; i.e., if the subscriber also exists in an SCE database.
When the SM is configured to work in Pull mode, a TRUE value returned by this method does not guarantee that the subscriber actually exists in an SCE database, but rather that the subscriber is available to be pulled by an SCE if needed.
If the subscriber does not exist in the SM database, an exception will be thrown.
argName
—See explanation of subscriber name format.
A pointer to a ReturnCode
structure with a Boolean type:
TRUE—If the subscriber is logged in.
FALSE—If the subscriber is not logged in.
The following is the list of error codes that this method might return:
ERROR_CODE_ILLEGAL_SUBSCRIBER_NAME
ERROR_CODE_DATABASE_EXCEPTION
For a description of error codes, see List of Error Codes.
ReturnCode* getSubscriberNameByMapping( char* argMapping, MappingType argMappingType, char* argDomain)
argMapping
—See explanation of mappings and mapping types.
argMappingType
—See explanation of mappings and mapping types.
argDomain
—The name of the domain to which the subscriber belongs. The operation will fail if either of the following conditions exists:
The domain is null, but the subscriber exists in the database and belongs to a domain.
The specified domain is incorrect.
A pointer to a ReturnCode
structure with a String (char*
) type:
Subscriber name—If a subscriber record was found.
NULL—If no subscriber record with the supplied mapping could be found in the SM database.
The following is the list of error codes that this method might return:
ERROR_CODE_DOMAIN_NOT_FOUND
ERROR_CODE _BAD_SUBSCRIBER_MAPPING
ERROR_CODE_NOT_A_SUBSCRIBER_DOMAIN
ERROR_CODE_DATABASE_EXCEPTION
For a description of error codes, see List of Error Codes.
Gets a bulk of subscriber names from the SM database, starting with argFirstName
followed by the next argAmount
subscribers (in alphabetical order).
If argFirstName
is NULL, the (alphabetically) first subscriber name that exists in the SM database will be used.
There is no guarantee that the total number of subscribers (in all bulks) will equal the value returned from getNumOfSubscribers
at any time. They may differ, for example, if some subscribers are added or removed while bulks are being retrieved.
argFirstName
—Last subscriber name from last bulk (first name to look for). Use NULL to start with the first (alphabetic) subscriber.
argAmount
—Limit on number of subscribers that will be returned. If this value is higher than the SM limit (1000), the SM limit will be used.
Values higher than 500 to this parameter is not recommended.
A pointer to a ReturnCode
structure with a String Array (char**
) holding a list of subscriber names ordered alphabetically.
The method will return as many subscribers as are found in the SM database, starting at the requested subscriber. The lower value of argAmount
and the SM limit (1000) limits the array size.
The following is the list of error codes that this method might return:
ERROR_CODE_ILLEGAL_SUBSCRIBER_NAME
ERROR_CODE_DATABASE_EXCEPTION
For a description of error codes, see List of Error Codes.
To receive an alphabetical list of subscriber names:
bool hasMoreSubscribers;
char* lastBulkEnd = NULL;
char tmpName[50];
int bulkSize = 100;
do
{
ReturnCode* subscribers =
smApi.getSubscriberNames(lastBulkEnd,bulkSize);
hasMoreSubscribers = false;
if ((isReturnCodeError(subscribers) == false) &&
(subscribers->type == STRING_ARRAY_T) &&
(subscribers->u.stringArrayVal != NULL))
{
for (int i = 0; i < subscribers->size; i++)
{
// do something with subscribers->u.stringArrayVal[i]
}
if (subscribers->size == bulkSize)
{
hasMoreSubscribers = true;
strcpy (tmpName, subscribers->u.stringArrayVal[bulkSize - 1]);
lastBulkEnd = tmpName;
}
}
freeReturnCode(subscribers);
} while (hasMoreSubscribers);
Retrieves subscribers from the SM database that are associated with the specified domain.
The function of this operation is the same as the getSusbcriberNames operation.
argFirstName
—See description in getSusbcriberNames operation.
argAmount
—See description in getSusbcriberNames operation.
argDomain
—The name of a subscriber domain that exists in the SM domain repository.
An alphabetically ordered array of subscriber names that belong to the specified domain.
See the Return Value section of the getSusbcriberNames operation for more information.
The following is the list of error codes that this method might return:
ERROR_CODE_ILLEGAL_SUBSCRIBER_NAME
ERROR_CODE _DOMAIN_NOT_FOUND
ERROR_CODE_DATABASE_EXCEPTION
For a description of error codes, see List of Error Codes.
Retrieves subscribers from the SM database whose names begin with a specified prefix.
The function of this operation is the same as the getSusbcriberNames
operation.
argFirstName
—See description in getSusbcriberNames operation.
argAmount
—See description in getSusbcriberNames operation.
argPrefix
—A case-sensitive string that marks the prefix of the required subscriber names.
An alphabetically ordered array of subscriber names that start with the prefix required.
See the Return Value section of the getSusbcriberNames operation.
The following is the list of error codes that this method might return:
ERROR_CODE_ILLEGAL_SUBSCRIBER_NAME
ERROR_CODE_DATABASE_EXCEPTION
For a description of error codes, see List of Error Codes.
Retrieves subscribers from the SM database whose names end with the specified suffix.
The functions of this operation are the same as the getSusbcriberNames
operation.
argFirstName
—See description in getSusbcriberNames operation.
argAmount
—See description in getSusbcriberNames operation.
argSuffix
—A case-sensitive string that marks the suffix of the required subscriber names.
An alphabetically ordered array of subscriber names that end with the suffix required.
See the Return Value section of the getSubscriberNames operation.
The following is the list of error codes that this method might return:
ERROR_CODE_ILLEGAL_SUBSCRIBER_NAME
ERROR_CODE_DATABASE_EXCEPTION
For a description of error codes, see List of Error Codes.
A pointer to a ReturnCode
structure with a String Array (char**
) holding a complete list of subscriber domain names in the SM.
ReturnCode* setPropertiesToDefault( char* argName, char** argPropertyKeys, int argPropertySize)
Resets the specified application properties of a subscriber. If an application is installed, the relevant application properties will be set to the default value of the properties according to the currently loaded application information. If an application is not installed, an ERROR_CODE_ILLEGAL_STATE
error code is returned.
argName
—See explanation of subscriber name format.
argPropertyKeys
—See explanation of property keys and values in the General API Concepts chapter.
argPropertySize
—The size of the argPropertyKeys
array.
The following is the list of error codes that this method might return:
ERROR_CODE_ILLEGAL_SUBSCRIBER_NAME
ERROR_CODE _BAD_SUBSCRIBER_MAPPING
ERROR_CODE_DOMAIN_NOT_FOUND
ERROR_CODE_SUBSCRIBER_DOES_NOT_EXIST
ERROR_CODE_NOT_A_SUBSCRIBER_DOMAIN
ERROR_CODE_DATABASE_EXCEPTION
For a description of error codes, see List of Error Codes.
ReturnCode* removeCustomProperties( char* argName,
char** argCustomPropertyKeys,
int argCustomPropertySize)
argName
—See explanation of subscriber name format.
argCustomPropertyKeys
—See explanation of custom property keys and values in the General API Concepts chapter.
argCustomPropertySize
—The size of the argCustomPropertyKeys
array.
The following is the list of error codes that this method might return:
ERROR_CODE_ILLEGAL_SUBSCRIBER_NAME
ERROR_CODE _SUBSCRIBER_DOES_NOT_EXIST
ERROR_CODE_DATABASE_EXCEPTION
For a description of error codes, see List of Error Codes.
Sets an implementation of the abstract Logger class. Use this method to integrate the SM API log messages with the host application log.
Bool init( int argSupportedThreads, int argThreadPriority, Uint32 argBufferSize, Uint32 argKeepAliveDuration, Uint32 argConnectionTimeout, Uint32 argReconnectTimeout)
Configures and initializes the API.
This method must be called before performing any operation of the C++ API.
argSupportedThreads
—The number of threads the API should support.
argThreadPriority
—The priority for the PRPC protocol network thread.
argBufferSize
—The internal buffer size (for default use 2000000 (2,000,000) bytes).
argKeepAliveDuration
—A hint regarding the wanted delay between PRPC protocol keep-alive messages (default use 10 seconds).
argConnectionTimeout
—A hint regarding the wanted timeout on a non-responding PRPC protocol connection (for default use 20 seconds).
argReconnectTimeout
—When the connection to the SM is down, the API will attempt to re-establish the connection after this timeout.
SMB_HANDLE SMB_init ( int argSupportedThreads,
int argThreadPriority,
Uint32 argBufferSize,
Uint32 argKeepAliveDuration,
Uint32 argConnectionTimeout)
Allocates, configures, and initializes the API.
This method must be called before performing any operation of the C API.
argSupportedThreads
—The number of threads the API should support.
argThreadPriority
—The priority for the PRPC protocol network thread.
argBufferSize
—The internal buffer size (default use 2000000 (2,000,000) bytes).
argKeepAliveDuration
—A hint regarding the wanted delay between PRPC protocol keep-alive messages (default use 10 seconds).
argConnectionTimeout
—A hint regarding the wanted timeout on a non-responding PRPC protocol connection (for default use 20 seconds).
SMB_HANDLE
handle to the API. If the handle equals NULL, the initialization failed. Otherwise, a non-NULL value is returned.
Releases the resources used by the API. This function must be called at the end of the use of the API.
Sets the reconnection timeout.
When the connection to the SM is down, the API will attempt to re-establish the connection after 'reconnection timeout' seconds.
Sets the name of the API, which serves as a unique identifier for the API-SM connection. The setName
function should be called before calling the connect
method.
argHostName
—The SM IP-Address or hostname.
argPort
—TCP port to connect the SM on (default is 14374)
.
This section provides two code examples:
Getting number of subscribers
Adding subscriber, printing subscriber information, removing subscriber
The following example prints to stdout
the total number of subscribers in the SM database and the number of subscribers in each subscriber domain.
#include “SmApiBlocking.h” #include <stdio.h> int main(int argc, char* argv[]) { SmApiBlocking bapi; //initiation bapi.init(); bapi.setReplyTimeout(300000); //set timeout for 5 minutes bapi.connect(argv[1]); // connect to the SM //operations ReturnCode* domains = bapi.getDomains(); ReturnCode* totalSubscribers=bapi.getNumberOfSubscribers(); if ((isReturnCodeError(domains) == false) && (isReturnCodeError(totalSubscribers) == false)) { printf( "number of susbcribers in the database:\t\t %d\n", totalSubscribers->u.intVal); for (int i=0; i<domains->size; i++) { ReturnCode* numberOfSusbcribersInDomain= bapi.getNumberOfSubscribersInDomain( domains->u.stringArrayVal[i]); if (isReturnCodeError(numberOfSusbcribersInDomain) == false) { printf( "number of susbcribers domain %s:\t\t%d\n", domains->u.stringArrayVal[i], numberOfSusbcribersInDomain->u.intVal); } freeReturnCode (numberOfSusbcribersInDomain); } } freeReturnCode (domains); freeReturnCode (totalSubscribers); //finalization bapi.disconnect(); return 0; }
The following program adds a subscriber to the subscriber database, retrieves the subscriber information, prints it to stdout
, and removes the subscriber from the subscriber database.
#include “SmApiBlocking.h”
#include <stdio.h>
int main(int argc, char* argv[])
{
checkArguments(argc,argv);
SmApiBlocking bapi;
//initiation
bapi.init();
bapi.setReplyTimeout(10000); //set timeout for 10 seconds
bapi.connect(argv[1]); // connect to the SM
//add subscriber
printf("adding subscriber to SM\n");
MappingType type = IP_RANGE;
char* customKey = "custom-key";
char* customVal = "custom-value";
ReturnCode* ret = bapi.addSubscriber(
argv[2], // name
&(argv[3]), // mapping
&type, // mapping type
1, // one mapping
&(argv[4]), // property key
&(argv[5]), // property value
1, // number of properties
&customKey, //custom property key
&customVal, //custom property value
1, // number of custom properties
argv[6]); //domain
freeReturnCode (ret);
//Print subscriber
printf("Printing subscriber:\n");
ReturnCode* subfields = bapi.getSubscriber(argv[1]);
if (isReturnCodeError(subfields) == false)
{
printf("\tname:\t\t%s\n",
subfields->u.objectArray[0]->u.stringVal);
printf("\tmapping:\t%s\n",
subfields->u.objectArray[1]->u.stringArrayVal[0]);
printf("\tdomain:\t\t%s\n",
subfields->u.objectArray[3]->u.stringVal);
printf("\tautologout:\t%d\n",
subfields->u.objectArray[8]->u.intVal);
// Remove subscriber
printf("removing subscriber from SM\n");
bapi.removeSubscriber(argv[1]);
}
else
{
printf("error in subscriber retrieval\n");
}
freeReturnCode(subfields);
//finalization
bapi.disconnect();
return 0;
}
void checkArguments(int argc, char* argv[])
{
if (argc != 7)
{
printf("usage: AddPrintRemove <SM-address> <subscriber-name> “
“<IP mapping> <property-key> <property-value> <domain>");
exit(1);
}
}
This section provides two code examples:
Getting number of subscribers
Adding subscriber, printing subscriber information, removing subscriber
The following example prints to stdout
the total number of subscribers in the SM database and the number of subscribers in each subscriber domain.
#include “SmApiBlocking_c.h”
#include <stdio.h>
int main(int argc, char* argv[])
{
//initiation
SMB_HANDLE bapi = SMB_init(10,0,2000000,10,20);
if (bapi == NULL)
{
// init failure
return -1;
}
SMB_setReplyTimeout(bapi,300000); //set timeout for 5 minutes
SMB_connect(bapi,argv[1],14374); // connect to the SM
//operations
ReturnCode* domains = SMB_getDomains(bapi);
ReturnCode* totalSubscribers= SMB_getNumberOfSubscribers(bapi);
if ((isReturnCodeError(domains) == false) &&
(isReturnCodeError(totalSubscribers) == false))
{
printf("number of susbcribers in the database:\t\t %d\n",
totalSubscribers->u.intVal);
for (int i=0; i<domains->size; i++)
{
ReturnCode* numberOfSusbcribersInDomain=
SMB_getNumberOfSubscribersInDomain(bapi,
domains->u.stringArrayVal[i]);
if(isReturnCodeError(numberOfSusbcribersInDomain) == false
{
printf(
"number of susbcribers domain %s:\t\t%d\n",
domains->u.stringArrayVal[i],
numberOfSusbcribersInDomain->u.intVal);
}
freeReturnCode (numberOfSusbcribersInDomain);
}
}
freeReturnCode (domains);
freeReturnCode (totalSubscribers);
//finalization
SMB_disconnect(bapi);
SMB_release(bapi);
return 0;
}
The following program adds a subscriber to the subscriber database, retrieves the subscriber information, prints it to stdout
, and removes the subscriber from the subscriber database.
#include “SmApiBlocking_c.h”
#include <stdio.h>
int main(int argc, char* argv[])
{
checkArguments(argc,argv);
//initiation
SMB_HANDLE bapi = SMB_init(10,0,2000000,10,20);
if (bapi == NULL)
{
// init failure
return -1;
}
SMB_setReplyTimeout(bapi,10000); //set timeout for 10 seconds
SMB_connect(bapi,argv[1], 14374); // connect to the SM
//add subscriber
printf("adding subscriber to SM\n");
MappingType type = IP_RANGE;
char* customKey = "custom-key";
char* customVal = "custom-value";
ReturnCode* ret = SMB_addSubscriber(
bapi, // handle
argv[2], // name
&(argv[3]), // mapping`
&type, // mapping type
1, // one mapping
&(argv[4]), // property key
&(argv[5]), // property value
1, // number of properties
&customKey, //custom property key
&customVal, //custom property value
1, // number of custom properties
argv[6]); //domain
freeReturnCode (ret);
//Print subscriber
printf("Printing subscriber:\n");
ReturnCode* subfields = SMB_getSubscriber(bapi,argv[2]);
if (isReturnCodeError(subfields) == false)
{
printf("\tname:\t\t%s\n",
subfields->u.objectArray[0]->u.stringVal);
printf("\tmapping:\t%s\n",
subfields->u.objectArray[1]->u.stringArrayVal[0]);
printf("\tdomain:\t\t%s\n",
subfields->u.objectArray[3]->u.stringVal);
printf("\tautologout:\t%d\n",
subfields->u.objectArray[8]->u.intVal);
// Remove subscriber
printf("removing subscriber from SM\n");
SMB_removeSubscriber(bapi,argv[2]);
}
else
{
printf("error in subscriber retrieval\n");
}
freeReturnCode(subfields);
//finalization
SMB_disconnect(bapi);
SMB_release(bapi);
return 0;
}
void checkArguments(int argc, char* argv[])
{
if (argc != 7)
{
printf(
"usage: AddPrintRemove <SM-address> <subscriber-name> “
“<IP mapping> <property-key> <property-value> <domain>");
exit(1);
}
}
This chapter introduces the Result Handler Callbacks, a feature unique to the Non-blocking API. It also lists all methods of the Non-blocking API and provides code examples.
The Non-blocking API supports an unlimited number of threads calling its methods simultaneously.
In a multi-threaded scenario for the Non-blocking API, the order of invocation is guaranteed: the API performs operations in the same chronological order that they were called.
The Non-blocking API enables the setting of result handler callbacks. The result handler callbacks are two functions for handleSuccess
and handleError
, as outlined in the following code.
/* operation failure callback specification */
typedef void (*OperationFailCallBackFunc)(Uint32 argHandle,
ReturnCode *argReturnCode);
/* operation success callback specification */
typedef void (*OperationSuccessCallBackFunc)(Uint32 argHandle,
ReturnCode *argReturnCode);
You should implement these callbacks if you want to be informed about the success or error results of operations performed through the API.
This is the only interface for retrieving results; they cannot be returned immediately after the API method has returned to the caller.
Both handleSuccess
and handleError
callbacks accept two parameters:
Handle
—Each API operation's return-value is a handle of type Uint32
. This handle enables correlation between operation calls and their results. When a handle...
operation is called with a handle of value X, the result will match the operation that returned the same handle value (X) to the caller.
Result
—The actual result of the operation returned as a pointer of type ResultCode
.
The following example is a simple implementation of a result handler that counts the number of success/failure operations. This main method initiates the API and assigns a result handler.
For correct operation of the result handler, follow the code sequence given in the example.
This example does not demonstrate the use of callback handles.
#include "GeneralDefs.h"
#include "SmApiNonBlocking.h"
#include <stdio.h>
int successCnt = 0;
int failCnt = 0;
void onOperationFail(Uint32 argHandle, ReturnCode* argReturnCode)
{
failCnt++;
if (argReturnCode != NULL)
{
freeReturnCode(argReturnCode);
}
}
void onOperationSuccess(Uint32 argHandle, ReturnCode* argReturnCode)
{
successCnt++;
if (argReturnCode != NULL)
{
freeReturnCode(argReturnCode);
}
}
int main(int argc, char* argv[])
{
if (argc != 2)
{
printf("usage: ResultHandlerExample <sm-ip>");
exit(1);
}
//note the order of operations!
SmApiNonBlocking nbapi;
nbapi.init();
nbapi.connect(argv[1]);
nbapi.setReplyFailCallBack(onOperationFail);
nbapi.setReplySuccessCallBack(onOperationSuccess);
nbapi.login(...);
...
nbapi.disconnect();
return 0;
}
This section lists the methods of the Non-blocking API.
Some of the methods return a non-negative int
handle that may be used to correlate operation calls and their results (see the Result Handler Callbacks section). If an internal error occurred, a negative value is returned and the operation is not performed.
The operation results passed to the result handler callbacks are the same as the return values described in the same method in the Blocking API, except that: return values of Void
are translated to NULL
.
The error/fail callback will be handed with an error only if the matching operation in the Blocking API would return an error code with the same arguments according to the SM database state at the time of the call.
The C and C++ API share the same function signature, except for an SMNB_
prefix for all Non-blocking C APIs function names, and an API handle of type SMNB_HANDLE
as the first parameter in all functions. The function description explains any other differences between the APIs.
The following methods are described:
int login( char* argName,
char** argMappings,
MappingType* argMappingTypes,
int argMappingsSize,
char** argPropertyKeys,
char** argPropertyValues,
int argPropertySize,
char* argDomain,
bool argIsAdditive,
int argAutoLogoutTime)
The operation functionality is the same as the matching Blocking API operation. See the login operation in the Blocking API chapter for more information.
int logoutByName(char* argName,
char** argMappings,
MappingType* argMappingTypes,
int argMappingsSize)
The operation functionality is the same as the matching Blocking API operation. See the logoutByName operation in the Blocking API chapter for more information.
int logoutByNameFromDomain (char* argName,
char** argMappings,
MappingType* argMappingTypes,
int argMappingsSize,
char* argDomain)
The operation functionality is the same as the matching Blocking API operation. See the logoutByNameFromDomain operation in the Blocking API chapter for more information.
int logoutByMapping( char* argMapping,
MappingType argMappingType,
char* argDomain)
The operation functionality is the same as the matching Blocking API operation. See the logoutByMapping operation in the Blocking API chapter for more information.
i
nt loginCable( char* argCpe,
char* argCm,
char* argIp,
int argLease,
char* argDomain,
char** argPropertyKeys,
char** argPropertyValues,
int argPropertySize)
The operation functionality is the same as the matching Blocking API operation. See the loginCable operation in the Blocking API chapter for more information.
int logoutCable( char* argCpe,
char* argCm,
char* argIp,
char* argDomain)
The operation functionality is the same as the matching Blocking API operation. See the logoutCable operation in the Blocking API chapter for more information.
void setLogger(Logger *argLogger)The operation functionality is the same as the matching Blocking API operation. See the C++ setLogger Method operation in the Blocking API chapter for more information.
Bool init( int argThreadPriority = 0, Uint32 argBufferSize = DEFAULT_BUFFER_SIZE, Uint32 argKeepAliveDuration = DEFAULT_KEEP_ALIVE_DURATION, Uint32 argConnectionTimeout= DEFAULT_CONNECTION_TIMEOUT, Uint32 argReconnectTimeout = NO_RECONNECT)The operation functionality is the same as the matching Blocking API operation. See the C++ init Method operation in the Blocking API chapter for more information.
SMNB_HANDLE SMNB_init( int argThreadPriority,
Uint32 argBufferSize,
Uint32 argKeepAliveDuration,
Uint32 argConnectionTimeout)
The operation functionality is the same as the matching Blocking API operation. See the C SMB_init Function operation in the Blocking API chapter for more information.
void SMNB_release(SMNB_HANDLE argApiHandle)The operation functionality is the same as the matching Blocking API operation. See the C SMB_release Function operation in the Blocking API chapter for more information.
void setReconnectTimeout(Uint32 reconnectTimeout)
The operation functionality is the same as the matching Blocking API operation. See the setReconnectTimeout operation in the Blocking API chapter for more information.
void setName(char *argName)
The operation functionality is the same as the matching Blocking API operation. See the setName operation in the Blocking API chapter for more information.
bool connect(char* argHostName, Uint16 argPort = 14374)
The operation functionality is the same as the matching Blocking API operation. See the connect operation in the Blocking API chapter for more information.
bool disconnect()
The operation functionality is the same as the matching Blocking API operation. See the disconnect operation in the Blocking API chapter for more information.
bool isConnected();
The operation functionality is the same as the matching Blocking API operation. See the isConnected operation in the Blocking API chapter for more information.
This section provides a code example for logging in and logging out subscribers.
The following example logs in a predefined number of subscribers to the SM, and then logs them out. Note the implementation of a disconnect listener and a result handler.
#include “SmApiNonBlocking.h” #include <stdio.h> void connectionIsDown() { printf("disconnect listener callback:: connection is down\n"); } int count = 0; //prints every error that occurs void handleError(Uint32 argHandle, ReturnCode* argReturnCode) { ++count; printf("\terror %d:\n",count); printReturnCode(argReturnCode); freeReturnCode(argReturnCode); } //prints a success result every 100 results void handleSuccess(Uint32 argHandle, ReturnCode* argReturnCode) { if (++count%100 == 0) { printf("\tresult %d:\n",count); printReturnCode(argReturnCode); } freeReturnCode(argReturnCode); } //waits for result number 'last result' to arrive void waitForLastResult(int lastResult) { while (count<lastResult) { ::Sleep(100); } } void checkTheArguments(int argc, char* argv[]) { if (argc != 4) { printf ("usage: LoginLogout <SM-address> <domain> <num-susbcribers>"); exit(1); } } void main (int argc, char* argv[]) { //check arguments checkTheArguments(argc, argv); int numSubscribersToLogin = atoi(argv[3]); //instantiation SmApiNonBlocking nbapi; //initiation nbapi.init(); nbapi.setDisconnectListener(connectionIsDown); nbapi.connect(argv[1]); nbapi.setReplyFailCallBack(handleError); nbapi.setReplySuccessCallBack(handleSuccess); //login char name[10]; char ipString[15]; char* ip = &(ipString[0]); MappingType type = IP_RANGE; Uint32 ipVal = 0x0a000000; printf("login of %d subscribers\n",numSubscribersToLogin); for (int i=0; i<numSubscribersToLogin; i++) { sprintf((char*)name,"s%d",i); sprintf((char*)ip,"%d.%d.%d.%d", (int)((ipVal & 0xFF000000) >> 24), (int)((ipVal & 0x00FF0000) >> 16), (int)((ipVal & 0x0000FF00) >> 8), (int)(ipVal & 0x000000FF)); ipVal++; nbapi.login(name, //subscriber name &ip, //a single ip mapping &type, 1, NULL, //no properties NULL, 0, argv[2], //domain false, //mappings are not additive -1); //disable auto-logout } waitForLastResult(numSubscribersToLogin); //logout printf("logout of %d subscribers",numSubscribersToLogin); ipVal = 0x0a000000; for (i=0; i<numSubscribersToLogin; i++) { sprintf((char*)ip,"%d.%d.%d.%d", (int)((ipVal & 0xFF000000) >> 24), (int)((ipVal & 0x00FF0000) >> 16), (int)((ipVal & 0x0000FF00) >> 8), (int)(ipVal & 0x000000FF)); ipVal++; nbapi.logoutByMapping(ip, type, argv[2]); } waitForLastResult(numSubscribersToLogin*2); nbapi.disconnect(); }
This section provides a code example for logging in and logging out subscribers.
The following example logs in a predefined number of subscribers to the SM, and then logs them out. Note the implementation of a disconnect listener and a result handler.
#include “SmApiNonBlocking_c.h”
#include <stdio.h>
void connectionIsDown()
{
printf("disconnect listener callback:: connection is down\n");
}
int count = 0;
//prints every error that occurs
void handleError(Uint32 argHandle, ReturnCode* argReturnCode)
{
++count;
printf("\terror %d:\n",count);
printReturnCode(argReturnCode);
freeReturnCode(argReturnCode);
}
//prints a success result every 100 results
void handleSuccess(Uint32 argHandle, ReturnCode* argReturnCode)
{
if (++count%100 == 0)
{
printf("\tresult %d:\n",count);
printReturnCode(argReturnCode);
}
freeReturnCode(argReturnCode);
}
//waits for result number 'last result' to arrive
void waitForLastResult(int lastResult)
{
while (count<lastResult)
{
::Sleep(100);
}
}
void checkTheArguments(int argc, char* argv[])
{
if (argc != 3)
{
printf
("usage: LoginLogout <SM-address> <domain> <num-susbcribers>");
exit(1);
}
}
void main (int argc, char* argv[])
{
//check arguments
checkTheArguments(argc, argv);
int numSubscribersToLogin = atoi(argv[3]);
//instantiation
SMNB_HANDLE nbapi = SMNB_init(0,2000000,10,30);
if (nbapi == NULL)
{
exit(1);
}
SMNB_setDisconnectListener(nbapi,connectionIsDown);
SMNB_connect(nbapi,argv[1],14374);
SMNB_setReplyFailCallBack(nbapi,handleError);
SMNB_setReplySuccessCallBack(nbapi,handleSuccess);
//login
char name[10];
char ipString[15];
char* ip = &(ipString[0]);
MappingType type = IP_RANGE;
Uint32 ipVal = 0x0a000000;
printf("login of %d subscribers\n",numSubscribersToLogin);
for (int i=0; i<numSubscribersToLogin; i++)
{
sprintf((char*)name,"s%d",i);
sprintf((char*)ip,"%d.%d.%d.%d",
(int)((ipVal & 0xFF000000) >> 24),
(int)((ipVal & 0x00FF0000) >> 16),
(int)((ipVal & 0x0000FF00) >> 8),
(int)(ipVal & 0x000000FF));
ipVal++;
SMNB_login( nbapi,
name, //subscriber name
&ip, //a single ip mapping
&type,
1,
NULL, //no properties
NULL,
0,
argv[2], //domain
false, //mappings are not additive
-1); //disable auto-logout
}
waitForLastResult(numSubscribersToLogin);
//logout
printf("logout of %d subscribers",numSubscribersToLogin);
ipVal = 0x0a000000;
for (i=0; i<numSubscribersToLogin; i++)
{
sprintf((char*)ip,"%d.%d.%d.%d",
(int)((ipVal & 0xFF000000) >> 24),
(int)((ipVal & 0x00FF0000) >> 16),
(int)((ipVal & 0x0000FF00) >> 8),
(int)(ipVal & 0x000000FF));
ipVal++;
SMNB_logoutByMapping(nbapi,
ip,
type,
argv[1]);
}
waitForLastResult(numSubscribersToLogin*2);
SMNB_disconnect(nbapi);
SMNB_release(nbapi);
}
Error codes are used for interpreting the actual error for which a ReturnCode
(holding an ErrorCode
) was returned.
The error code enumeration is given in the GeneralDefs.h
header file. The following table gives a list of the error codes and their descriptions.
Table A.1. List of Error Codes
Error Code |
Description |
---|---|
|
A mapping was formatted badly or assigned to the subscriber illegally. |
|
The domain provided to the operation does not exist in the SM domain repository. |
|
One of the arguments provided to the method is illegal. |
|
The subscriber name provided has more than 40 characters or has illegal characters. |
|
The domain provided to the operation exists in the SM domain repository but is not a subscriber domain. |
|
A VLAN mapping string provided to the API does not represent a decimal number. |
|
The subscriber on which the operation is performed does not exist in the SM database. |
|
The subscriber exists in the SM database but is associated with a domain other than the one specified by the operation. |
|
The mappings provided for the subscriber by the operation already belong to another subscriber. |
|
The subscriber on which the operation was performed already exists in the SM database. |
|
Internal SM error – database error occurred during the operation. |
|
Internal SM error. |
|
Internal SM error. |
|
Internal SM error. |
|
Internal SM error. |
|
Internal error. |
|
Internal error. |
|
Internal SM error. |
|
Internal SM error. |
|
Internal SM error. |
|
Internal SM error. |
|
Internal SM error. |
|
Internal SM error. |
|
Internal SM error. The SM could not perform the operation on the SCE device. |
|
Internal SM or API error. |
|
Blocking API operation result did not return till the reply timeout expired. |