Licensing Integration
and
Analytics Integration
Introduction:
In this article we are going to add a sample code project to your own application using C/C++. NSA can easily be added to new or existing software as it is a shared library and can be accessed as such. The library is intended to be used with the dlopen family of functions (dlopen, dlclose, dlsym, etc). While it may be possible to link to the NSA library it is not a currently supported option.
Of course you can use any IDE or language you prefer.
Having created your Custom Analytics DLL you will now need to code your project with the quick changes listed below.
Installation:
The NSA library can be installed anywhere that is convenient.
Prevention of Data Loss: To prevent data loss, the NSA library caches any information that hasn't been sent in the case of network interrupt, shutdown, or similar circumstances. The cache file is circular with a maximum size equal to the value you stamped into the library. Once the maximum size has been reached, the cache file wraps around and begins overwriting the oldest data. When a successful connection to Nalpeiron is detected, the entire cache will be automatically sent.
Privacy: Nalpeiron has taken several steps to help our customers cope with the many privacy laws around the world. First, there is a privacy setting that can be stamped into the shared library then accessed and changed via NSA functions. Second, Nalpeiron provides geographical location information to the NSA library and incoming data is tagged by country. If incoming data originates in a region where it is illegal to collect such data, the incoming data is dropped and never stored.
The privacy setting (accessed with NSAGetPrivacy and NSASetPrivacy) is used to enable or disable all NSA functions that collect information. If this value is set (= 1), all such functions are disabled. If this value is not set (= 0), the functions are enabled though data may still not be collected due to local privacy laws. If the value has never been set (= 2), the privacy setting stamped into the library is used. The privacy setting is stored along with the cache file and, if that file is deleted, the privacy setting will be to. In this case, the setting defaults to the value stamped into the library until NSASetPrivacy is used.
NSA functions:
NSA functions are called using a capital letter.
The C SDK contains an example usage of the NSALibrary. The example can be built from the command line with the included Makefile. The result is a command line program that accesses each of the NSA functions. It can be incorporated into your project (especially the header files) or used to test/debug. Usage information may be obtained with the -? parameter:| Letter | Function |
|---|---|
| A | NSAApStart |
| B | NSAApStop |
| C | NSAClose |
| D number_of_loops | Test run |
| E | NSAException |
| F |
NSAFeatureStart |
| G | NSAFeatureEnd |
| H | TestConnection |
| I | NSASysInfo |
| L | NSALogin |
| O | NSAOpen |
| P | NSASetPrivacy |
| T | NSASendCache |
| Q | NSAGetPrivacy |
| S | NSAGetStats |
| V | Version |
| X | NSALogout |
| Parameter | Description |
|---|---|
| -a value | Application Language |
| -b value | Log File directory path |
| -c value | Customer ID |
| -d value |
log level [0 - 5] |
| -e value | Exception Code |
| -f value | Feature Code |
| -g value | Error description |
| -h value | Max Log Queue Length |
| -i value | Max Cache Queue Length |
| -j value | Min number of network threads |
| -k value | Max number of network threads |
| -n value | BuildNumber |
| -p value | Product ID |
| -s value | License status |
| -t value | Edition |
| -u value | Username |
| -v value | BuildVersion |
| -w value | Proxy IP |
| -x value | Proxy Port Number |
| -y value | Proxy Username |
| -z value | Proxy Password |
| -l path_to_library | Path to the NSAfilechck.dll |
| -o | Enable Offline Mode |
NSA Examples Usage
| Example function | Call |
|---|---|
| Check state of end user privacy | ./nsaExample -l /tmp/test.dylib -c 3183 -p 100 -u nalpUser -Q |
| Set privacy to none | ./nsaExample -l /tmp/test.dylib -c 3183 -p 100 -u nalpUser -P -r 0 |
| Application Start | ./nsaExample -l /tmp/test.dylib -c 3183 -p 100 -u nalpUser -A |
| login | ./nsaExample -l /tmp/test.dylib -c 3183 -p 100 -u nalpUser -L |
| Feature start | ./nsaExample -l /tmp/test.dylib -c 3183 -p 100 -u nalpUser -f print -F |
| Exception | ./nsaExample -l /tmp/test.dylib -c 3183 -p 100 -u nalpUser -e NAN -d "division by zero" -E |
| Sys info | ./nsaExample -l /tmp/test.dylib -c 3183 -p 100 -u nalpUser -v 1 -n 2 -t 3 -a en -s OK -I |
| Feature end | ./nsaExample -l /tmp/test.dylib -c 3183 -p 100 -u nalpUser -f print -G |
| Logout | ./nsaExample -l /tmp/test.dylib -c 3183 -p 100 -u nalpUser -X |
| Application End | ./nsaExample -l /tmp/test.dylib -c 3183 -p 100 -u nalpUser -B |
| Get NSA Statistics | ./nsaExample -l /tmp/test.dylib -c 3183 -p 100 -u nalpUser -S |
NSALogin:
CodeKitExample -l c:\tmp\NSAfilechck.dll -u nalpeiron -L
NSALogout:
CodeKitExample -l c:\tmp\NSAfilechck.dll -u nalpeiron -X
NSAFeatureStart:
CodeKitExample -l c:\tmp\NSAfilechck.dll -u nalpeiron -f featureCode -F
NSAFeatureEnd:
CodeKitExample -l c:\tmp\NSAfilechck.dll -u nalpeiron -f featureCode -G
Library Version:
CodeKitExample -l c:\tmp\NSAfilechck.dll -V
NSASysInfo:
CodeKitExample -l c:\tmp\NSAfilechck.dll -a en -n 1.0 -s "license current" -t "Pro Edition" -u nalpeiron -v 1.0.0 -I
Library Usage:
All functions return positive numbers (or 0) on success and negative number on error. Strings passed into NSA are expected to be either ANSI C strings or UTF8 encoded unicode. The following functions are provided by the NSA library. Of course, as you will be accessing them from the shared libraries rather than directly you need to use the typedeffed functions pointers (see NSAFunctions.h in the c/c++ SDK) rather than these prototypes.
For example usage see nsaExample.c in the SDK.
| int NalpLibOpen(char *xmlParams) | Initializes the library. THIS FUNCTION MUST BE CALLED AFTER THE LIBRARY IS OPENED (with dlopen, for instance) BUT BEFORE THE LIBRARY IS ACCESSED. Returns 0 for success and a negative number for an error. The NSAOpen has been modified to take a xml string as its parameter. This will ensure any future changes to NSAOpen will remain backward compatible. The current form of the xml string is: <?xml version=\"1.0\" encoding=\"UTF-8\"?>
<SHAFERXMLParams> <NSAEnabled>1</NSAEnabled> <NSLEnabled>1</NSLEnabled> <LogLevel>value</LogLevel> <WorkDir>dir_path</WorkDir> <LogQLen>int</LogQLen> <CacheQLen>int</CacheQLen> <SoapThreadsMin>int</SoapThreadsMax> <OfflineMode>0 or 1</OfflineMode> <ProxyIP>IP addr</ProxyIP> <ProxyPort>port number</ProxPort> <ProxyUsername>string</ProxUsername> <ProxyPassword>string</ProxyPassword> </SHAFERXMLParams> where: NSAEnabled 0 disables the NSA library and 1 enables the NSA library. NSLEnabled 0 disables the NSL library and 1 enables the NSL library. WorkDir is the location where NSA will store all its information and files. If this value is not specified the files will be stored in the default Nalpeiron directory (the current working directory on Linux and Mac, in a publically accessible directory selected by the OS on Windows). loglevel s an integer 0 to 6. If loglevel is not specified it will default to level 0 (off). You should not use log level higher than 4. The higher levels do not provide any useful end user debugging.
LogQLen is the maximum length of the log queue. Once the log queue reaches this length, additional log entries will be discarded. As messages in the queue are written to the log file, the queue will shrink and logging will automatically begin again. The default is 300. CacheQLen is the maximum length of the cache queue. Once the cache queue reaches this length, additional cache entries will be discarded. As messages in the queue are written to the cache file, the queue will shrink and caching will automatically begin again. The default is 25. SoapThreadsMin/SoapThreadsMax - Network connections between the NSA library and the Nalpeiron server are handled by a lthread pool. The values specify the minimum number of threads available to the pool and the maximum number of threads available to the pool. The number of threads in the pool will grow and shrink between these two extremes as needed. The default for each is 10. ProxyIP/ProxyPort - If the NSA library is connecting to the internet via a proxy use these values to specify the IP address and port number of the proxy server. If no proxy is used, they can be left empty or completely unspecified. The default is no proxy. ProxyUsername/ProxyPassword - If you are using a network proxy to which requires a username and password, specify them here. OfflineMode - If OfflineMode is on (1), the no data is sent to the Nalpeiron server. All transactions are written immediately to cache. The library makes no attempts to collection location information or send the cache to Nalpeiron. The default is 0 (ie on-line). |
||||||||||||||||||||||||||||||||||||||
| int NalpLibClose() | Shuts down the library. THIS FUNCTION MUST BE CALLED IMMEDIATELY BEFORE CLOSING THE LIBRARY (ie with dlclose). If this function is not called before the library is closed, information may be lost and memory corruption could occur. Returns 0 for success and a negative number for an error. |
||||||||||||||||||||||||||||||||||||||
| int NalpGetErrorMsg(int nalpErrorNo, char **errMsg) | Returns a descriptive string explaining negative error number nalpErrorNo. errMsg should be freed via NSAFree by the caller. | ||||||||||||||||||||||||||||||||||||||
| int NSAGetPrivacy() | Checks current privacy settings. Returns 0 for "no privacy", 1 for "privacy enabled", 2 for "unset" and a negative number for an error. If privacy is unset, the privacy setting used will be the one stamped into the library. | ||||||||||||||||||||||||||||||||||||||
| int NSASetPrivacy(int setting) | Sets a privacy value for the library. Possible values for setting are 0 "no privacy", 1 "privacy enabled" or a negative number for an error. | ||||||||||||||||||||||||||||||||||||||
| int NSAAppStart() | Records startup of your application. Returns 0 on success and a negative number for an error. | ||||||||||||||||||||||||||||||||||||||
| int NSAAppStop() | Records shutdown of your application. Returns 0 on success and a negative number for an error. | ||||||||||||||||||||||||||||||||||||||
| int NSALogin(char *username) | Records login of username. Returns 0 on success and a negative number for an error. Username should be a ANSI C string or a utf8 encoded unicode string. | ||||||||||||||||||||||||||||||||||||||
| int NSALogout(char *username) | Records logout of username. Returns 0 on success and a negative number for an error. Username should be a ANSI C string or a utf8 encoded unicode string. | ||||||||||||||||||||||||||||||||||||||
| int NSAFeatureStart( char *username, char *featureCode) | Records start of use of featureCode by username. Returns 0 on success and a negative number for an error. Username and featureCode should be a ANSI C strings or a utf8 encoded unicode strings. | ||||||||||||||||||||||||||||||||||||||
| int NSAFeatureStop( char *username, char *featureCode) | Records end of use of featureCode by username. Returns 0 on success and a negative number for an error. Username and featureCode should be a ANSI C strings or a utf8 encoded unicode strings. | ||||||||||||||||||||||||||||||||||||||
| int NSAException( char *username, char *exceptionCode, char *description) | Records an error of type exceptionCode by username with details in description. Returns 0 on success and a negative number for an error. Username, featureCode, and description should be a ANSI C strings or a utf8 encoded unicode strings. | ||||||||||||||||||||||||||||||||||||||
| int NSASysInfo( char *username, char *applang, char *version, char *edition, char *build, char *licenseStatus) |
Send information about the system to Nalpeiron. Returns 0 on success and a negative number for an error. Username, applang, version, edition, build, and licenseStatus should be a ANSI C strings or a utf8 encoded unicode strings. NSASysInfo sends the following information
|
||||||||||||||||||||||||||||||||||||||
| int NSASendCache( char *username) | Check NSA's job cache. If not empty, send it. Returns 0 on success and a negative number for an error. Username should be a ANSI C string or a utf8 encoded unicode string. This function is provided for special circumstances but should be largely unnecessary as sending of the cache is automatic. Upon a successful completion of any of the functions about, the communication thread checks to see if the cache contains information. If it does it is sent to Nalpeiron. |
||||||||||||||||||||||||||||||||||||||
| int NSAValidateDLL(int customerID, int productID) | Verifies that the shared library you are accessing is the library you stamped. It does this by checking the customerID and productID sent in against the stamped values. If they match, 1 is returned. If they do no match a 0 is returned. |
||||||||||||||||||||||||||||||||||||||
| int NSAGetVersion() | Returns the version of the NSA library being accessed. | ||||||||||||||||||||||||||||||||||||||
| int NSAGetStats( char **nsaStats ) | Returns information about the NSA library's status. The following information is return in the form of a string
<?xml version="1.0" encoding="UTF-8"?>
<NSA Current Statistics> <OfflineMode>0</OfflineMode> <LocationInfo>1</LocationInfo> <Cache Thread> <Max Cache Que Len>25</Max Cache Que Len> <Current Cache Que Len>0</Current Cache Que Len> <Cache writes>1</Cache writes> <Cache fails>0</Cache fails> </Cache Thread> <Soap Pool> <Min Soap Threads>10</Min Soap Threads> <Max Soap Threads>10</Max Soap Threads> <Queued Jobs>0</Queued Jobs> <Running Jobs>0</Running Jobs> <Finished Jobs>145</Finished Jobs> </Soap Pool> </NSA Current Statistics> |
||||||||||||||||||||||||||||||||||||||
| Test Option -D number_of_loops | is not a NSA library function. When called it executes the informational routines in the library (return version, validate dll, etc) then loops through each of the other calls (NSAApStart, NSAFeatureStart, etc etc) number_of_loops times. At the end of each loop, NSAStats is called and its information printed to the screen. This functions is intended for demostration and debugging. | ||||||||||||||||||||||||||||||||||||||
|
int NSAFree(void *) |
The NSAFree functions is available to free any memory allocated by the NSA library. This function is mandatory on windows as depending on how your binary is built, your final binary may have a different heap than the NSA library. This function is provided to ensure that memory allocated from the NSA heap is freed there. NSAFree should be used on the memory returned from NSAGetStats, ReturnVersion, GetComputerID, GetHostName, etc.. |
Obvious mistakes to avoid
If call NSAOpen (In example the encapsulating function is the init function, which contains the call) isn't called, the required threads won't be created. At best, the library will not function if a call to call NSAOpen is not made. Most likely, it will seg fault. If call NSAClose (In example the encapsulating function is the ApplicationEnd Function, which contains the call) isn't called when you're finished, the main program won't wait for the thread to finish before shutting down. This will result in a loss of any information still being processed by the threads. It may also cause memory corruption.
Firewall and Proxy issues
NSA/NSL sends data to Nalpeiron via a network connection to either port 80 or port 443. If you have a firewall blocking these outgoing ports your data will not reach Nalpeiron. The NSA/NSL library will recognize this fact and cache the data to disk. However, as no data has reached Nalpeiron your reports will be empty. Likewise, the same issue can be caused by a proxy server in place between your client location and Nalpeiron. NSA/NSL will utilize a proxy server but call NSAOpen (In example the encapsulating function is the init function, which contains the call) must be supplied with the proxy information (see the call NSAOpen function parameters in the Function Reference Guide).
The easiest way to make sure you have connectivity to Nalpeiron is with the call NSLTestConnection (in the example the encapsulating function is TestInternetConnection, which contains this call) function. That function will attempt to contact the Nalpeiron server. If this function fails, you have connectivity issue and, most likely, the other NSA/NSL functions will fail as well. If this is the case, you will need to Manually activate your client and your NSA data will be sent to the cache file rather than to the Nalpeiron.
NOTE : For Permanently Offline NSA/NSL applications the NSA data will never get to the server for reporting, only online NSA/NSL applications can send analytics information to the activation server for reporting. For temporarily offline NSA/NSL Application, when the application can see the activation server the cached NSA data will be sent to the activation server for reporting
End User System Info
It is important that you make a call to call NSASysInfo (in the example the encapsulating function is ApplicationStart, which contains this call) at least once per application run. NSASysInfo collects various system information that is necessary for generating reports on the Nalpeiron Analytics website. Repeated calls into call NSASysInfo will not initiate repeated connections to Nalpeiron. NSASysInfo caches the system information and sends it to Nalpeiron only when something has changed.
Usage options
You are free to use the files from the SDK in your own projects. The typical method of doing this would be to include nsaFunctions.h, nsaWin.h and nsaWin.c in your project. Modify the setLib function in nsaWin.c to point to the location of nsaFilechck.dll on your end user's system. Once these files are included in your project, you'll be able to call into the NSA library in exactly the same method demonstrated in CCodeKit Example.
Download the Example Applications attached
Release Notes (Please always check the release notes for the latest updates)
