The documentation set for this product strives to use bias-free language. For the purposes of this documentation set, bias-free is defined as language that does not imply discrimination based on age, disability, gender, racial identity, ethnic identity, sexual orientation, socioeconomic status, and intersectionality. Exceptions may be present in the documentation due to language that is hardcoded in the user interfaces of the product software, language used based on RFP documentation, or language that is used by a referenced third-party product. Learn more about how Cisco is using Inclusive Language.
This module describes the features and operations of the Nonblocking API and provides code examples.
This module introduces the Result Handler Callbacks, a feature unique to the Nonblocking API.
•Information About Result Handler Callbacks
•Information About Nonblocking API Methods
•Nonblocking API C++ Code Examples
•Nonblocking API C Code Examples
The Nonblocking API supports an unlimited number of threads calling its methods simultaneously.
Note In a multithreaded scenario for the Nonblocking API, the order of invocation is guaranteed: the API performs operations in the same chronological order that they were called.
The Nonblocking 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.
Note 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.
Note 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 Nonblocking API.
Some of the methods return a non-negative int handle that may be used to correlate operation calls and their results (see Information About Result Handler Callbacks). 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 section, except that: return values of Void are translated to NULL.
Note 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 Nonblocking 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 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 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 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 for more information.
int 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 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 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 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 for more information.
SMNB_HANDLE handle to the API. If the handle equals NULL, the initialization failed. Otherwise, a non-NULL value is returned.
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 for more information.
void setReconnectTimeout(Uint32 reconnectTimeout)
The operation functionality is the same as the matching Blocking API operation. See the setReconnectTimeout operation for more information.
void setName(char *argName)
The operation functionality is the same as the matching Blocking API operation. See the setName operation 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 for more information.
bool disconnect()
The operation functionality is the same as the matching Blocking API operation. See the disconnect operation for more information.
bool isConnected()
The operation functionality is the same as the matching Blocking API operation. See the isConnected operation 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);
}