I am relatively new to C++ programming but conversant with C# programming. I am currently working on connecting to Avaya Aura Contact Centre RTD tables. The issue I am having is that the compiled software download from Avaya website connects to the server and download data to the console screen, but I intend to write the data to excel or text file.
The SDK gotten from Avaya is in C++ and after compiling the program it did not fetch me the tables to the console screen neither do I have it in my text or excel sheet. The SDK looks ambigous and will appreciate if anyone can see why it behave so. Here below is the rtdapp.cpp file of the SDK.
/*
*********************************************************************
This console program will request skillset statistic. Then it will
print out the skillset name and the number of agents availabe for this
skillset on the console screen. This program will run until the sleep_time
(input argument) expires
A global statistic cache link list is created to store the statistics. The
output will be from this cache.
Other than the main and the data stream callback function, four utility
functions are implemented. They are:
- newRows : add new rows into the statistic cache
- deleteRows : delete rows from the statistic cache
- updateRows : update statistic cache content
- displayCache : display statistic cache content
*********************************************************************
*/
#include <stdio.h>
#include <stdlib.h>
#include <nirtdtyp.h>
#include <nirtdapi.h>
#include <tchar.h>
#include <windows.h>
#include <stdio.h>
#if _MSC_VER >= 1310
#include <iostream>
#include <fstream>
using namespace std;
#else
#include <iostream.h>
#include <fstream.h>
#include <strstrea.h>
#endif
#include <stdlib.h>
#include <conio.h>
#include <time.h>
#include <math.h>
#include <fstream>
// structure definition
// skillset statistic link list item
typedef struct stStatItem {
NIrtd_stValue skillsetId;
NIrtd_stValue numAgtAv;
stStatItem* next;
} S_stStatItem;
// global statistic link list structure
typedef struct stStatList {
ULONG numItem;
stStatItem* startList;
} S_stStatList;
// global variable declaration
// global statistic cache
S_stStatList stat_list;
// authorization structure used by login and name cache
NIrtd_tAPIauth authInfo = NIrtd_NullAuth;
// This function will insert new rows into the global cache list
void newRows(NIrtd_stTable* newTable)
{
// structure used to stored temporary row
NIrtd_tRow tempRow = NIrtd_NullRow;
// return code
ULONG rc = NIrtd_eOK;
for (ULONG i=0; i < newTable->numberofrows ; i++)
{
// copy the new row content to temp row
rc = NIrtd_allocateRow(&tempRow, newTable, i);
if (rc != NIrtd_eOK)
{
printf("\nCannot copy new row, rc = %d", rc);
return;
}
S_stStatItem * tempStatItem =(S_stStatItem *) malloc( sizeof(stStatItem) );
tempStatItem->next = NULL;
// allocate the value structures in the tempStatItem
rc = NIrtd_allocateValue(&tempStatItem->skillsetId);
if ( rc != NIrtd_eOK)
{
printf("\nCannot allocate value structure, rc = %d", rc);
free(tempStatItem);
return;
}
rc = NIrtd_allocateValue(&tempStatItem->numAgtAv);
if ( rc != NIrtd_eOK)
{
printf("\nCannot allocate value structure, rc = %d", rc);
NIrtd_freeValue(&tempStatItem->skillsetId);
free(tempStatItem);
return;
}
// copy the skillset id
rc = NIrtd_getCol(&tempStatItem->skillsetId, &tempRow, 0);
if ( rc != NIrtd_eOK)
{
printf("\nCannot copy skillsetId out, rc = %d", rc);
NIrtd_freeValue(&tempStatItem->skillsetId);
NIrtd_freeValue(&tempStatItem->numAgtAv);
free(tempStatItem);
return;
}
// copy the number of agt avai. value
rc = NIrtd_getCol(&tempStatItem->numAgtAv, &tempRow, 1);
if ( rc != NIrtd_eOK)
{
printf("\nCannot copy agt avai., rc = %d", rc);
NIrtd_freeValue(&tempStatItem->skillsetId);
NIrtd_freeValue(&tempStatItem->numAgtAv);
free(tempStatItem);
return;
}
// if there is nothing in the cache list
if (stat_list.numItem == 0)
{
stat_list.startList = tempStatItem;
}
else
{
// find the end of the list an added in
S_stStatItem* loopStatItem = stat_list.startList;
while( loopStatItem->next != NULL)
{
loopStatItem = loopStatItem->next;
}
loopStatItem->next = tempStatItem;
}
stat_list.numItem++;
// free up tempRow for next round
rc = NIrtd_freeRow(&tempRow);
}
}
// This function will remove rows from the global statistic cache list
void deleteRows(NIrtd_stTable* deleteTable)
{
// structure used to stored temporary row
NIrtd_tRow tempRow = NIrtd_NullRow;
// return code
ULONG rc = NIrtd_eOK;
for (ULONG i=0; i < deleteTable->numberofrows; i++)
{
if (stat_list.numItem == 0)
{
printf("\nNo Item to be removed");
return;
}
// copy the delete row content to temp row
rc = NIrtd_allocateRow(&tempRow, deleteTable, i);
if (rc != NIrtd_eOK)
{
printf("\nCannot copy new row, rc = %d", rc);
return;
}
// value structure used to store the deleted skillset info
NIrtd_stValue deletedSkillset;
rc = NIrtd_allocateValue(&deletedSkillset);
if (rc != NIrtd_eOK)
{
printf("\nCannot allocate value structure to store deleted skillset, rc = %d", rc);
NIrtd_freeRow(&tempRow);
return;
}
// copy the deleted skillset id value into the deletedSkillset struct.
NIrtd_getCol(&deletedSkillset, &tempRow, 0);
if (rc != NIrtd_eOK)
{
printf("\nCannot copy the deleted skillset id, rc = %d", rc);
NIrtd_freeRow(&tempRow);
NIrtd_freeValue(&deletedSkillset);
return;
}
// flag to indicate whether the deleted item is in the list or not
int found = FALSE;
// address of the previous statItem's next pointer
S_stStatItem** pPrevItemLink = &stat_list.startList;
for (ULONG j = 0; (j < stat_list.numItem ) && (found != TRUE) ; j++)
{
if ( ( (*pPrevItemLink)->skillsetId).number == deletedSkillset.number)
{
// temporary storage for the deleted item's next pointer
S_stStatItem* pDeleteItemNext = (*pPrevItemLink)->next;
NIrtd_freeValue(& (*pPrevItemLink)->skillsetId );
NIrtd_freeValue(& (*pPrevItemLink)->numAgtAv );
free(*pPrevItemLink);
*pPrevItemLink = pDeleteItemNext;
stat_list.numItem--;
found = TRUE;
}
else
{
pPrevItemLink = & (*pPrevItemLink)->next;
}
}
// free up the deletedSkillset structure
NIrtd_freeValue(&deletedSkillset);
// free up tempRow for next round
NIrtd_freeRow(&tempRow);
}
}
// This function will update the global statistic cache list
void updateRows(NIrtd_stTable* updateTable)
{
// structure used to stored temporary row
NIrtd_tRow tempRow = NIrtd_NullRow;
// return code
ULONG rc = NIrtd_eOK;
for (ULONG i=0; i < updateTable->numberofrows; i++)
{
if (stat_list.numItem == 0)
{
printf("\nNo Item to update");
return;
}
// copy the update row content to temp row
rc = NIrtd_allocateRow(&tempRow, updateTable, i);
if (rc != NIrtd_eOK)
{
printf("\nCannot copy update row, rc = %d", rc);
return;
}
// value structure used to store the deleted skillset info
NIrtd_stValue updateSkillset;
rc = NIrtd_allocateValue(&updateSkillset);
if (rc != NIrtd_eOK)
{
printf("\nCannot allocate value structure to store update skillset, rc = %d", rc);
NIrtd_freeRow(&tempRow);
return;
}
// value structure used to store the agt available value
NIrtd_stValue agtAvValue;
rc = NIrtd_allocateValue(&agtAvValue);
if (rc != NIrtd_eOK)
{
printf("\nCannot allocate value structure to store the agt available value, rc = %d", rc);
NIrtd_freeRow(&tempRow);
return;
}
// copy the udpate skillset id value into the deletedSkillset struct.
rc = NIrtd_getCol(&updateSkillset, &tempRow, 0);
if (rc != NIrtd_eOK)
{
printf("\nCannot copy the update skillset id, rc = %d", rc);
NIrtd_freeValue(&updateSkillset);
NIrtd_freeValue(&agtAvValue);
NIrtd_freeRow(&tempRow);
return;
}
// flag to indicate whether the udpate item is in the list or not
int found = FALSE;
// address of the previous statItem's next pointer
S_stStatItem* tempStatItem = stat_list.startList;
for (ULONG j = 0; (j < stat_list.numItem ) && (found != TRUE) ; j++)
{
if ( (tempStatItem->skillsetId).number == updateSkillset.number && updateSkillset.number != 0)
{
// copy the update agt available value
rc = NIrtd_getCol(&agtAvValue, &tempRow, 1);
if (rc != NIrtd_eOK)
{
printf("\nCannot get the agt available value, rc = %d", rc);
NIrtd_freeValue(&updateSkillset);
NIrtd_freeValue(&agtAvValue);
NIrtd_freeRow(&tempRow);
return;
}
rc = NIrtd_cpValue(&(tempStatItem->numAgtAv), &agtAvValue);
if (rc != NIrtd_eOK)
{
printf("\nCannot copy the agt available value, rc = %d", rc);
NIrtd_freeValue(&updateSkillset);
NIrtd_freeValue(&agtAvValue);
NIrtd_freeRow(&tempRow);
return;
}
found = TRUE;
}
else
{
tempStatItem = tempStatItem->next;
}
}
// free up the updateSkillset structure
NIrtd_freeValue(&updateSkillset);
// free up the agt. available structure
NIrtd_freeValue(&agtAvValue);
// free up tempRow for next round
NIrtd_freeRow(&tempRow);
}
}
// this function will display the statistic content on screen
void displayCache()
{
ULONG rc;
// address of the previous statItem's next pointer
S_stStatItem* tempStatItem = stat_list.startList;
// temporary structure used to hold skillset name
NIrtd_stName tempSkillsetName;
for (ULONG j = 0; j < stat_list.numItem ; j++)
{
// allocate the name structure
rc = NIrtd_allocateName(&tempSkillsetName);
if ( rc != NIrtd_eOK)
{
printf("\nCannot allocate name structure for skillset name");
return;
}
rc = NIrtd_getName(&authInfo, NIrtd_SKLST_SKILLSET_ID, &(tempStatItem->skillsetId), &tempSkillsetName);
if ( rc == NIrtd_eOK )
{
printf("\nRow %d : %s %d", j, tempSkillsetName.last_name, (tempStatItem->numAgtAv).number);
ofstream ofs("C:\\segema.xls", ofstream::out);
if (ofs.good()) { // if opening is successful
// iterate through lines of sample text
//for (int i = 0; i < 5; i++)
// and print every line to the file
ofs << ("\nRow %d : %s %d", j, tempSkillsetName.last_name, (tempStatItem->numAgtAv).number) << endl;
// close the file
ofs.close();
} else
// otherwise print a message
cout << "ERROR: can't open file for writing." << endl;
tempStatItem = tempStatItem->next;
}
// cannot find the name in name cache
else if (rc == NIrtd_eNOT_FOUND)
{
// go to the server directly to retrieve the name
rc = NIrtd_getFailedName(&authInfo, NIrtd_SKLST_SKILLSET_ID, &(tempStatItem->skillsetId), &tempSkillsetName);
if (rc != NIrtd_eOK)
{
printf("\nCannot find the skillset name in server");
return;
}
printf("\nRow %d : %s %d", j, tempSkillsetName.last_name, (tempStatItem->numAgtAv).number);
tempStatItem = tempStatItem->next;
}
else
{
printf("\nOther error in getting name cache : %d", rc);
return;
}
NIrtd_freeName(&tempSkillsetName);
}
printf("\n\n");
}
// call back function
ULONG callback_function(ULONG return_code, NIrtd_tRequestId requestId, NIrtd_stTableGroup *tableGroup, void *yourPointer)
{
printf("\nCallback function:");
bool recovery = false;
if (return_code == NIrtd_eOK)
{
if (tableGroup->deletedValues.numberofrows > 0)
{
printf("\nDelete rows arrived %d", tableGroup->deletedValues.numberofrows);
deleteRows(&(tableGroup->deletedValues));
}
if (tableGroup->newValues.numberofrows > 0)
{
printf("\nNew rows arrived %d", tableGroup->newValues.numberofrows);
newRows(&(tableGroup->newValues));
}
if (tableGroup->deltaValues.numberofrows > 0)
{
updateRows(&(tableGroup->deltaValues));
}
displayCache();
//free the internally allocated space for data.
NIrtd_freeTableGroup(tableGroup);
}
else if (NIrtd_eSTART_RECOVERY == return_code) {
printf("\nRecovery Started");
recovery = true;
}
else if (NIrtd_eOK_RECOVERY == return_code) {
printf("\nRecovery Successful");
recovery = true;
}
else if (NIrtd_eBAD_RECOVERY == return_code) {
printf("\nRecovery Delayed");
recovery = true;
}
if (recovery) {
stat_list.numItem = 0;
stat_list.startList = NULL;
if (tableGroup != NULL)
NIrtd_freeTableGroup(tableGroup);
}
return NIrtd_eOK;
}
#ifdef UNICODE
void wmain(short argc, TCHAR *argv[])
#else
void main(short argc, char *argv[])
#endif
{
TCHAR ipAddress[100]; // server IP address
TCHAR username[100]; // user login name
TCHAR password[100]; // user login password
int refresh_rate = 0; // refresh rate
// if sleep time is specified , use the user input sleep time
if (argc < 5)
{
printf("rtdapp [server_ip] [user_login_name] [user_password] [refresh_rate]");
return;
}
_tcscpy(ipAddress, argv[1]);
_tcscpy(username, argv[2]);
_tcscpy(password, argv[3]);
refresh_rate = _ttoi(argv[4]);
_tprintf(_T("\n\tUsername : '%s'\n"), username);
_tprintf(_T("\tPassword : '%s'\n"), password);
_tprintf(_T("\tIP Address : '%s'\n"), ipAddress);
_tprintf(_T("\tRefresh : '%d'\n"), refresh_rate);
// initialize global variable
stat_list.numItem = 0;
stat_list.startList = NULL;
// setup the required variables
// return code from API
ULONG rc = NIrtd_eOK;
rc = NIrtd_setRecovery(90000,10000);
if (rc == NIrtd_eLIMIT_REACHED)
{
printf("failed to set up the Recovery: return code = %d", rc);
return;
}
rc = NIrtd_eOK;
// Query structure
NIrtd_tQuery query = NIrtd_NullQuery;
// Query request id return from the start data stream function
NIrtd_tRequestId requestId = NIrtd_NullRequestId;
// Perform login to the server
printf("Trying to log in...");
rc = NIrtd_login(&authInfo, ipAddress, username, password);
if (rc != NIrtd_eOK)
{
printf("failed to login: return code = %d", rc);
return;
}
else
{
printf("success : return code = %d", rc);
}
// setup name cache for SkillsetID to SkillsetName translation
rc = NIrtd_getNameCacheforDataColumn(&authInfo, NIrtd_SKLST_SKILLSET_ID);
if (rc != NIrtd_eOK)
{
printf("\nNIrtd_getNameCacheforDataColumn failed : rc = %d", rc);
rc = NIrtd_logout(&authInfo);
return;
}
else
{
printf("\nNIrtd_getNameCacheforDataColumn succeeded.");
}
// setup query
// allocate and initialize the query structure
rc = NIrtd_allocateQuery(&query, NIrtd_INTRVL_SKLST);
if (rc != NIrtd_eOK)
{
printf("\nNIrtd_allocateQuery failed : rc = %d", rc);
rc = NIrtd_logout(&authInfo);
return;
}
else
{
printf("\nNIrtd_allocateQuery succeeded.");
}
// select skillset ID as the first column
rc = NIrtd_selectColumn(&query, NIrtd_SKLST_SKILLSET_ID);
if (rc != NIrtd_eOK)
{
printf("\nNIrtd_selectColumn failed : rc = %d", rc);
rc = NIrtd_freeQuery(&query);
rc = NIrtd_logout(&authInfo);
return;
}
else
{
printf("\nNIrtd_SKLST_SKILLSET_ID Column selected.");
}
// select number of agent available as the second column
rc = NIrtd_selectColumn(&query, NIrtd_SKLST_AGENT_AVAIL);
if (rc != NIrtd_eOK)
{
printf("\nNIrtd_selectColumn failed : rc = %d", rc);
rc = NIrtd_freeQuery(&query);
rc = NIrtd_logout(&authInfo);
return;
}
else
{
printf("\nNIrtd_SKLST_AGENT_AVAIL Column selected.");
}
// start data stream
rc = NIrtd_startDataStream(&authInfo, &query, refresh_rate * 1000, callback_function, (void *)NULL, &requestId);
ofstream ofs("C:\\segema.xls", ofstream::out);
if (ofs.good()) { // if opening is successful
// iterate through lines of sample text
//for (int i = 0; i < 5; i++)
// and print every line to the file
ofs << rc << endl;
// close the file
ofs.close();
} else
// otherwise print a message
cout << "ERROR: can't open file for writing." << endl;
if (rc != NIrtd_eOK)
{
printf("\nNIrtd_startDataStream failed : rc = %d", rc);
rc = NIrtd_freeQuery(&query);
rc = NIrtd_logout(&authInfo);
return;
}
else
{
printf("\nNIrtd_startDataStream succeeded.");
}
// sleep until timer expired
while (true) {
// sleep until timer expired
Sleep(300);
if('q' == _getch()) {
_tprintf(_T("\n\nRequest to stop - accepted !!\n"));
break;
}
}
// free name cache
rc = NIrtd_removeNameCacheforDataColumn(&authInfo, NIrtd_SKLST_SKILLSET_ID);
// stop data stream before exit
rc = NIrtd_stopDataStream(&authInfo, requestId);
// deallocate all structures allocated
rc = NIrtd_freeQuery(&query);
// perform logout
rc = NIrtd_logout(&authInfo);
}
/*
*********************************************************************
This console program will request skillset statistic. Then it will
print out the skillset name and the number of agents availabe for this
skillset on the console screen. This program will run until the sleep_time
(input argument) expires
A global statistic cache link list is created to store the statistics. The
output will be from this cache.
Other than the main and the data stream callback function, four utility
functions are implemented. They are:
- newRows : add new rows into the statistic cache
- deleteRows : delete rows from the statistic cache
- updateRows : update statistic cache content
- displayCache : display statistic cache content
*********************************************************************
*/
#include <stdio.h>
#include <stdlib.h>
#include <nirtdtyp.h>
#include <nirtdapi.h>
#include <tchar.h>
#include <windows.h>
#include <stdio.h>
#if _MSC_VER >= 1310
#include <iostream>
#include <fstream>
using namespace std;
#else
#include <iostream.h>
#include <fstream.h>
#include <strstrea.h>
#endif
#include <stdlib.h>
#include <conio.h>
#include <time.h>
#include <math.h>
#include <fstream>
// structure definition
// skillset statistic link list item
typedef struct stStatItem {
NIrtd_stValue skillsetId;
NIrtd_stValue numAgtAv;
stStatItem* next;
} S_stStatItem;
// global statistic link list structure
typedef struct stStatList {
ULONG numItem;
stStatItem* startList;
} S_stStatList;
// global variable declaration
// global statistic cache
S_stStatList stat_list;
// authorization structure used by login and name cache
NIrtd_tAPIauth authInfo = NIrtd_NullAuth;
// This function will insert new rows into the global cache list
void newRows(NIrtd_stTable* newTable)
{
// structure used to stored temporary row
NIrtd_tRow tempRow = NIrtd_NullRow;
// return code
ULONG rc = NIrtd_eOK;
for (ULONG i=0; i < newTable->numberofrows ; i++)
{
// copy the new row content to temp row
rc = NIrtd_allocateRow(&tempRow, newTable, i);
if (rc != NIrtd_eOK)
{
printf("\nCannot copy new row, rc = %d", rc);
return;
}
S_stStatItem * tempStatItem =(S_stStatItem *) malloc( sizeof(stStatItem) );
tempStatItem->next = NULL;
// allocate the value structures in the tempStatItem
rc = NIrtd_allocateValue(&tempStatItem->skillsetId);
if ( rc != NIrtd_eOK)
{
printf("\nCannot allocate value structure, rc = %d", rc);
free(tempStatItem);
return;
}
rc = NIrtd_allocateValue(&tempStatItem->numAgtAv);
if ( rc != NIrtd_eOK)
{
printf("\nCannot allocate value structure, rc = %d", rc);
NIrtd_freeValue(&tempStatItem->skillsetId);
free(tempStatItem);
return;
}
// copy the skillset id
rc = NIrtd_getCol(&tempStatItem->skillsetId, &tempRow, 0);
if ( rc != NIrtd_eOK)
{
printf("\nCannot copy skillsetId out, rc = %d", rc);
NIrtd_freeValue(&tempStatItem->skillsetId);
NIrtd_freeValue(&tempStatItem->numAgtAv);
free(tempStatItem);
return;
}
// copy the number of agt avai. value
rc = NIrtd_getCol(&tempStatItem->numAgtAv, &tempRow, 1);
if ( rc != NIrtd_eOK)
{
printf("\nCannot copy agt avai., rc = %d", rc);
NIrtd_freeValue(&tempStatItem->skillsetId);
NIrtd_freeValue(&tempStatItem->numAgtAv);
free(tempStatItem);
return;
}
// if there is nothing in the cache list
if (stat_list.numItem == 0)
{
stat_list.startList = tempStatItem;
}
else
{
// find the end of the list an added in
S_stStatItem* loopStatItem = stat_list.startList;
while( loopStatItem->next != NULL)
{
loopStatItem = loopStatItem->next;
}
loopStatItem->next = tempStatItem;
}
stat_list.numItem++;
// free up tempRow for next round
rc = NIrtd_freeRow(&tempRow);
}
}
// This function will remove rows from the global statistic cache list
void deleteRows(NIrtd_stTable* deleteTable)
{
// structure used to stored temporary row
NIrtd_tRow tempRow = NIrtd_NullRow;
// return code
ULONG rc = NIrtd_eOK;
for (ULONG i=0; i < deleteTable->numberofrows; i++)
{
if (stat_list.numItem == 0)
{
printf("\nNo Item to be removed");
return;
}
// copy the delete row content to temp row
rc = NIrtd_allocateRow(&tempRow, deleteTable, i);
if (rc != NIrtd_eOK)
{
printf("\nCannot copy new row, rc = %d", rc);
return;
}
// value structure used to store the deleted skillset info
NIrtd_stValue deletedSkillset;
rc = NIrtd_allocateValue(&deletedSkillset);
if (rc != NIrtd_eOK)
{
printf("\nCannot allocate value structure to store deleted skillset, rc = %d", rc);
NIrtd_freeRow(&tempRow);
return;
}
// copy the deleted skillset id value into the deletedSkillset struct.
NIrtd_getCol(&deletedSkillset, &tempRow, 0);
if (rc != NIrtd_eOK)
{
printf("\nCannot copy the deleted skillset id, rc = %d", rc);
NIrtd_freeRow(&tempRow);
NIrtd_freeValue(&deletedSkillset);
return;
}
// flag to indicate whether the deleted item is in the list or not
int found = FALSE;
// address of the previous statItem's next pointer
S_stStatItem** pPrevItemLink = &stat_list.startList;
for (ULONG j = 0; (j < stat_list.numItem ) && (found != TRUE) ; j++)
{
if ( ( (*pPrevItemLink)->skillsetId).number == deletedSkillset.number)
{
// temporary storage for the deleted item's next pointer
S_stStatItem* pDeleteItemNext = (*pPrevItemLink)->next;
NIrtd_freeValue(& (*pPrevItemLink)->skillsetId );
NIrtd_freeValue(& (*pPrevItemLink)->numAgtAv );
free(*pPrevItemLink);
*pPrevItemLink = pDeleteItemNext;
stat_list.numItem--;
found = TRUE;
}
else
{
pPrevItemLink = & (*pPrevItemLink)->next;
}
}
// free up the deletedSkillset structure
NIrtd_freeValue(&deletedSkillset);
// free up tempRow for next round
NIrtd_freeRow(&tempRow);
}
}
// This function will update the global statistic cache list
void updateRows(NIrtd_stTable* updateTable)
{
// structure used to stored temporary row
NIrtd_tRow tempRow = NIrtd_NullRow;
// return code
ULONG rc = NIrtd_eOK;
for (ULONG i=0; i < updateTable->numberofrows; i++)
{
if (stat_list.numItem == 0)
{
printf("\nNo Item to update");
return;
}
// copy the update row content to temp row
rc = NIrtd_allocateRow(&tempRow, updateTable, i);
if (rc != NIrtd_eOK)
{
printf("\nCannot copy update row, rc = %d", rc);
return;
}
// value structure used to store the deleted skillset info
NIrtd_stValue updateSkillset;
rc = NIrtd_allocateValue(&updateSkillset);
if (rc != NIrtd_eOK)
{
printf("\nCannot allocate value structure to store update skillset, rc = %d", rc);
NIrtd_freeRow(&tempRow);
return;
}
// value structure used to store the agt available value
NIrtd_stValue agtAvValue;
rc = NIrtd_allocateValue(&agtAvValue);
if (rc != NIrtd_eOK)
{
printf("\nCannot allocate value structure to store the agt available value, rc = %d", rc);
NIrtd_freeRow(&tempRow);
return;
}
// copy the udpate skillset id value into the deletedSkillset struct.
rc = NIrtd_getCol(&updateSkillset, &tempRow, 0);
if (rc != NIrtd_eOK)
{
printf("\nCannot copy the update skillset id, rc = %d", rc);
NIrtd_freeValue(&updateSkillset);
NIrtd_freeValue(&agtAvValue);
NIrtd_freeRow(&tempRow);
return;
}
// flag to indicate whether the udpate item is in the list or not
int found = FALSE;
// address of the previous statItem's next pointer
S_stStatItem* tempStatItem = stat_list.startList;
for (ULONG j = 0; (j < stat_list.numItem ) && (found != TRUE) ; j++)
{
if ( (tempStatItem->skillsetId).number == updateSkillset.number && updateSkillset.number != 0)
{
// copy the update agt available value
rc = NIrtd_getCol(&agtAvValue, &tempRow, 1);
if (rc != NIrtd_eOK)
{
printf("\nCannot get the agt available value, rc = %d", rc);
NIrtd_freeValue(&updateSkillset);
NIrtd_freeValue(&agtAvValue);
NIrtd_freeRow(&tempRow);
return;
}
rc = NIrtd_cpValue(&(tempStatItem->numAgtAv), &agtAvValue);
if (rc != NIrtd_eOK)
{
printf("\nCannot copy the agt available value, rc = %d", rc);
NIrtd_freeValue(&updateSkillset);
NIrtd_freeValue(&agtAvValue);
NIrtd_freeRow(&tempRow);
return;
}
found = TRUE;
}
else
{
tempStatItem = tempStatItem->next;
}
}
// free up the updateSkillset structure
NIrtd_freeValue(&updateSkillset);
// free up the agt. available structure
NIrtd_freeValue(&agtAvValue);
// free up tempRow for next round
NIrtd_freeRow(&tempRow);
}
}
// this function will display the statistic content on screen
void displayCache()
{
ULONG rc;
// address of the previous statItem's next pointer
S_stStatItem* tempStatItem = stat_list.startList;
// temporary structure used to hold skillset name
NIrtd_stName tempSkillsetName;
for (ULONG j = 0; j < stat_list.numItem ; j++)
{
// allocate the name structure
rc = NIrtd_allocateName(&tempSkillsetName);
if ( rc != NIrtd_eOK)
{
printf("\nCannot allocate name structure for skillset name");
return;
}
rc = NIrtd_getName(&authInfo, NIrtd_SKLST_SKILLSET_ID, &(tempStatItem->skillsetId), &tempSkillsetName);
if ( rc == NIrtd_eOK )
{
printf("\nRow %d : %s %d", j, tempSkillsetName.last_name, (tempStatItem->numAgtAv).number);
ofstream ofs("C:\\segema.xls", ofstream::out);
if (ofs.good()) { // if opening is successful
// iterate through lines of sample text
//for (int i = 0; i < 5; i++)
// and print every line to the file
ofs << ("\nRow %d : %s %d", j, tempSkillsetName.last_name, (tempStatItem->numAgtAv).number) << endl;
// close the file
ofs.close();
} else
// otherwise print a message
cout << "ERROR: can't open file for writing." << endl;
tempStatItem = tempStatItem->next;
}
// cannot find the name in name cache
else if (rc == NIrtd_eNOT_FOUND)
{
// go to the server directly to retrieve the name
rc = NIrtd_getFailedName(&authInfo, NIrtd_SKLST_SKILLSET_ID, &(tempStatItem->skillsetId), &tempSkillsetName);
if (rc != NIrtd_eOK)
{
printf("\nCannot find the skillset name in server");
return;
}
printf("\nRow %d : %s %d", j, tempSkillsetName.last_name, (tempStatItem->numAgtAv).number);
tempStatItem = tempStatItem->next;
}
else
{
printf("\nOther error in getting name cache : %d", rc);
return;
}
NIrtd_freeName(&tempSkillsetName);
}
printf("\n\n");
}
// call back function
ULONG callback_function(ULONG return_code, NIrtd_tRequestId requestId, NIrtd_stTableGroup *tableGroup, void *yourPointer)
{
printf("\nCallback function:");
bool recovery = false;
if (return_code == NIrtd_eOK)
{
if (tableGroup->deletedValues.numberofrows > 0)
{
printf("\nDelete rows arrived %d", tableGroup->deletedValues.numberofrows);
deleteRows(&(tableGroup->deletedValues));
}
if (tableGroup->newValues.numberofrows > 0)
{
printf("\nNew rows arrived %d", tableGroup->newValues.numberofrows);
newRows(&(tableGroup->newValues));
}
if (tableGroup->deltaValues.numberofrows > 0)
{
updateRows(&(tableGroup->deltaValues));
}
displayCache();
//free the internally allocated space for data.
NIrtd_freeTableGroup(tableGroup);
}
else if (NIrtd_eSTART_RECOVERY == return_code) {
printf("\nRecovery Started");
recovery = true;
}
else if (NIrtd_eOK_RECOVERY == return_code) {
printf("\nRecovery Successful");
recovery = true;
}
else if (NIrtd_eBAD_RECOVERY == return_code) {
printf("\nRecovery Delayed");
recovery = true;
}
if (recovery) {
stat_list.numItem = 0;
stat_list.startList = NULL;
if (tableGroup != NULL)
NIrtd_freeTableGroup(tableGroup);
}
return NIrtd_eOK;
}
#ifdef UNICODE
void wmain(short argc, TCHAR *argv[])
#else
void main(short argc, char *argv[])
#endif
{
TCHAR ipAddress[100]; // server IP address
TCHAR username[100]; // user login name
TCHAR password[100]; // user login password
int refresh_rate = 0; // refresh rate
// if sleep time is specified , use the user input sleep time
if (argc < 5)
{
printf("rtdapp [server_ip] [user_login_name] [user_password] [refresh_rate]");
return;
}
_tcscpy(ipAddress, argv[1]);
_tcscpy(username, argv[2]);
_tcscpy(password, argv[3]);
refresh_rate = _ttoi(argv[4]);
_tprintf(_T("\n\tUsername : '%s'\n"), username);
_tprintf(_T("\tPassword : '%s'\n"), password);
_tprintf(_T("\tIP Address : '%s'\n"), ipAddress);
_tprintf(_T("\tRefresh : '%d'\n"), refresh_rate);
// initialize global variable
stat_list.numItem = 0;
stat_list.startList = NULL;
// setup the required variables
// return code from API
ULONG rc = NIrtd_eOK;
rc = NIrtd_setRecovery(90000,10000);
if (rc == NIrtd_eLIMIT_REACHED)
{
printf("failed to set up the Recovery: return code = %d", rc);
return;
}
rc = NIrtd_eOK;
// Query structure
NIrtd_tQuery query = NIrtd_NullQuery;
// Query request id return from the start data stream function
NIrtd_tRequestId requestId = NIrtd_NullRequestId;
// Perform login to the server
printf("Trying to log in...");
rc = NIrtd_login(&authInfo, ipAddress, username, password);
if (rc != NIrtd_eOK)
{
printf("failed to login: return code = %d", rc);
return;
}
else
{
printf("success : return code = %d", rc);
}
// setup name cache for SkillsetID to SkillsetName translation
rc = NIrtd_getNameCacheforDataColumn(&authInfo, NIrtd_SKLST_SKILLSET_ID);
if (rc != NIrtd_eOK)
{
printf("\nNIrtd_getNameCacheforDataColumn failed : rc = %d", rc);
rc = NIrtd_logout(&authInfo);
return;
}
else
{
printf("\nNIrtd_getNameCacheforDataColumn succeeded.");
}
// setup query
// allocate and initialize the query structure
rc = NIrtd_allocateQuery(&query, NIrtd_INTRVL_SKLST);
if (rc != NIrtd_eOK)
{
printf("\nNIrtd_allocateQuery failed : rc = %d", rc);
rc = NIrtd_logout(&authInfo);
return;
}
else
{
printf("\nNIrtd_allocateQuery succeeded.");
}
// select skillset ID as the first column
rc = NIrtd_selectColumn(&query, NIrtd_SKLST_SKILLSET_ID);
if (rc != NIrtd_eOK)
{
printf("\nNIrtd_selectColumn failed : rc = %d", rc);
rc = NIrtd_freeQuery(&query);
rc = NIrtd_logout(&authInfo);
return;
}
else
{
printf("\nNIrtd_SKLST_SKILLSET_ID Column selected.");
}
// select number of agent available as the second column
rc = NIrtd_selectColumn(&query, NIrtd_SKLST_AGENT_AVAIL);
if (rc != NIrtd_eOK)
{
printf("\nNIrtd_selectColumn failed : rc = %d", rc);
rc = NIrtd_freeQuery(&query);
rc = NIrtd_logout(&authInfo);
return;
}
else
{
printf("\nNIrtd_SKLST_AGENT_AVAIL Column selected.");
}
// start data stream
rc = NIrtd_startDataStream(&authInfo, &query, refresh_rate * 1000, callback_function, (void *)NULL, &requestId);
ofstream ofs("C:\\segema.xls", ofstream::out);
if (ofs.good()) { // if opening is successful
// iterate through lines of sample text
//for (int i = 0; i < 5; i++)
// and print every line to the file
ofs << rc << endl;
// close the file
ofs.close();
} else
// otherwise print a message
cout << "ERROR: can't open file for writing." << endl;
if (rc != NIrtd_eOK)
{
printf("\nNIrtd_startDataStream failed : rc = %d", rc);
rc = NIrtd_freeQuery(&query);
rc = NIrtd_logout(&authInfo);
return;
}
else
{
printf("\nNIrtd_startDataStream succeeded.");
}
// sleep until timer expired
while (true) {
// sleep until timer expired
Sleep(300);
if('q' == _getch()) {
_tprintf(_T("\n\nRequest to stop - accepted !!\n"));
break;
}
}
// free name cache
rc = NIrtd_removeNameCacheforDataColumn(&authInfo, NIrtd_SKLST_SKILLSET_ID);
// stop data stream before exit
rc = NIrtd_stopDataStream(&authInfo, requestId);
// deallocate all structures allocated
rc = NIrtd_freeQuery(&query);
// perform logout
rc = NIrtd_logout(&authInfo);
}
My observation is that the in the main column "(argc < 5)" is the cause of the problem, and removing it causes the program to halt execution and does not run
Thanks in advance for your quick response