Difference between revisions of "EI-Agent Sample Client"

From ESS-WIKI
Jump to: navigation, search
(Created page with "Advantech provides a WISE-PaaS 2.0 EI-Agent Sample to demonstrate how to implement a custom application to connect to WISE-PaaS 2.0 Server. == WISECore APIs == === List ===...")
 
Line 6: Line 6:
  
  
<pre>bool core_initialize(char* strTenantID, char* strClientID, char* strHostName, char* strMAC, void* userdata);</pre>
+
<syntaxhighlight lang="c">bool core_initialize(char* strTenantID, char* strClientID, char* strHostName, char* strMAC, void* userdata);</syntaxhighlight>''Description''
 
 
''Description''
 
 
 
 
*General initialization of the WISECore API. Prior to calling any WISECore API functions,&nbsp;the library needs to be initialized by calling this function.
 
*General initialization of the WISECore API. Prior to calling any WISECore API functions,&nbsp;the library needs to be initialized by calling this function.
 
*The result for all&nbsp;WISECore API function will be false unless this function is called.
 
*The result for all&nbsp;WISECore API function will be false unless this function is called.
Line 37: Line 34:
  
  
<pre>void core_uninitialize();</pre>
+
<syntaxhighlight lang="c">void core_uninitialize();</syntaxhighlight> ''Description''
 
 
''Description''
 
 
 
 
*General function to uninitialize the WISECore API library that should be called before program exit.
 
*General function to uninitialize the WISECore API library that should be called before program exit.
  
Line 58: Line 52:
  
  
<pre>bool core_product_info_set(char* strSerialNum, char* strParentID, char* strVersion, char* strType, char* strProduct, char* strManufacture);</pre>
+
<syntaxhighlight lang="c">bool core_product_info_set(char* strSerialNum, char* strParentID, char* strVersion, char* strType, char* strProduct, char* strManufacture);</syntaxhighlight> ''Description''
 
 
''Description''
 
 
 
 
*Assign the basic information to identify the device.
 
*Assign the basic information to identify the device.
  
Line 90: Line 81:
  
  
<pre>bool core_tag_set(char* strTag);</pre>
+
<syntaxhighlight lang="c">bool core_tag_set(char* strTag);</syntaxhighlight> ''Description''
 
 
''Description''
 
 
 
 
*Assign the tag to markup the support product, for example: "RMM" for RMM product.
 
*Assign the tag to markup the support product, for example: "RMM" for RMM product.
  
Line 112: Line 100:
  
  
<pre>bool core_account_bind(char* strLoginID, char* strLoginPW);
+
<syntaxhighlight lang="c">bool core_account_bind(char* strLoginID, char* strLoginPW);</syntaxhighlight> ''Description''
</pre>
 
 
 
''Description''
 
 
 
 
*Bind the device to a specific user account automatically.
 
*Bind the device to a specific user account automatically.
  
Line 131: Line 115:
  
 
''Example''
 
''Example''
<pre>#include "WISECore.h"
+
<syntaxhighlight lang="c">#include "WISECore.h"
  
 
int main (int argc, char *argv[])
 
int main (int argc, char *argv[])
Line 154: Line 138:
 
return iRet;
 
return iRet;
 
}
 
}
</pre>
+
</syntaxhighlight>
  
 
+
<syntaxhighlight lang="c">bool core_tls_set(const char *cafile, const char *capath, const char *certfile, const char *keyfile, const char *password);</syntaxhighlight lang="c">
<pre />
 
 
 
<pre>bool core_tls_set(const char *cafile, const char *capath, const char *certfile, const char *keyfile, const char *password);</pre>
 
  
 
''Description''
 
''Description''
Line 170: Line 151:
  
 
*cafile[POINTER]
 
*cafile[POINTER]
**path to a file containing the PEM encoded trusted CA certificate files.  
+
**path to a file containing the PEM encoded trusted CA certificate files.
 
**Either cafile or capath must not be NULL.
 
**Either cafile or capath must not be NULL.
 
*capath[NUMBER]
 
*capath[NUMBER]
Line 190: Line 171:
  
 
''Example''
 
''Example''
<pre>#include "WISECore.h"
+
<syntaxhighlight lang="c">#include "WISECore.h"
 
int main (int argc, char *argv[])  
 
int main (int argc, char *argv[])  
 
{
 
{
Line 211: Line 192:
 
&nbsp;  core_uninitialize(); return iRet;  
 
&nbsp;  core_uninitialize(); return iRet;  
 
}
 
}
</pre>
+
</syntaxhighlight>
 
 
 
----
 
----
  
  
<pre>int saclient_getsocketaddress(char* clientip, int size);</pre>
+
<syntaxhighlight lang="c">int saclient_getsocketaddress(char* clientip, int size);</syntaxhighlight>
 
 
 
''Description''
 
''Description''
  
Line 237: Line 216:
  
 
''Example''
 
''Example''
<pre>#include "SAClient.h"
+
<syntaxhighlight lang="c">#include "SAClient.h"
 
int main (int argc, char *argv[])
 
int main (int argc, char *argv[])
 
{
 
{
Line 253: Line 232:
 
iRet = saclient_initialize(&config, &profile, NULL);
 
iRet = saclient_initialize(&config, &profile, NULL);
 
   
 
   
if(iRet != saclient_success)
+
if(iRet&nbsp;!= saclient_success)
 
{
 
{
 
printf("Unable to initialize AgentCore.");
 
printf("Unable to initialize AgentCore.");
Line 262: Line 241:
 
iRet = saclient_connect();
 
iRet = saclient_connect();
 
   
 
   
if(iRet != saclient_success){
+
if(iRet&nbsp;!= saclient_success){
 
printf("sampleagent Unable to connect to broker.");
 
printf("sampleagent Unable to connect to broker.");
 
 
Line 268: Line 247:
 
char localip[256]={0};
 
char localip[256]={0};
 
saclient_getsocketaddress(localip, sizeof(localip));
 
saclient_getsocketaddress(localip, sizeof(localip));
printf("sampleagent Connected localip: %s", localip);
+
printf("sampleagent Connected localip:&nbsp;%s", localip);
 
}
 
}
 
   
 
   
Line 277: Line 256:
 
return iRet;
 
return iRet;
 
}
 
}
</pre>
+
</syntaxhighlight>
  
 
=== Callback Function ===
 
=== Callback Function ===

Revision as of 05:20, 18 May 2017

Advantech provides a WISE-PaaS 2.0 EI-Agent Sample to demonstrate how to implement a custom application to connect to WISE-PaaS 2.0 Server.

WISECore APIs

List

bool core_initialize(char* strTenantID, char* strClientID, char* strHostName, char* strMAC, void* userdata);
Description
  • General initialization of the WISECore API. Prior to calling any WISECore API functions, the library needs to be initialized by calling this function.
  • The result for all WISECore API function will be false unless this function is called.

Parameters

  • strTenantID[POINTER]
    • the tenant ID string in UUID format: xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx.
  • strClientID[POINTER]
    • the client ID string in UUID format: xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx.
  • strHostName[POINTER]
    • the host name string as device recognize name.
  • strMAC[POINTER]
    • first MAC address of the device.
  • userdata[POINTER]
    • the unstructured pointer to reference to user data.

Return Values

  • true/false

Example

Reference to core_account_bind().



void core_uninitialize();
Description
  • General function to uninitialize the WISECore API library that should be called before program exit.

Parameters

  • None

Return Values

  • None

Example

Reference to core_account_bind().



bool core_product_info_set(char* strSerialNum, char* strParentID, char* strVersion, char* strType, char* strProduct, char* strManufacture);
Description
  • Assign the basic information to identify the device.

Parameters

  • strSerialNum[POINTER]
    • the serial number string of target device.
  • strParentID[POINTER]
    • the parent device ID string in UUID format: xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx, used to point out the EIS or Gateway device ID if the taget device connect to server through an EIS or Gateway device.
  • strVersion[POINTER]
    • the applicatin version string.
  • strType[POINTER]
    • the applicatin type string, default is "IPC" for general usage.
  • strProduct[POINTER]
    • the target device product name.
  • strManufacture[POINTER]
    • the target device manufacture name.

Return Values

  • true/false

Example

Reference to core_account_bind().



bool core_tag_set(char* strTag);
Description
  • Assign the tag to markup the support product, for example: "RMM" for RMM product.

Parameters

  • strManufacture[POINTER]
    • the target device supported function set.

Return Values

  • true/false

Example

Reference to core_account_bind().



bool core_account_bind(char* strLoginID, char* strLoginPW);
Description
  • Bind the device to a specific user account automatically.

Parameters

  • strLoginID[POINTER]
    • Account ID.
  • strLoginPW[POINTER]
    • Account Password, need to encrypt with AgentEncrypt application.

Return Values

  • true/false.

Example

#include "WISECore.h"

int main (int argc, char *argv[])
{
	int iRet = 0;
	/*Initialize WISECore*/
	if(!core_initialize("general", "00000001-0000-0000-0000-305A3A77B1CC", "TestClient", "305A3A77B1CC", NULL))
&nbsp;&nbsp; &nbsp;{
&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;printf("Unable to initialize WISECore.\n");
&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;goto EXIT;
&nbsp;&nbsp; &nbsp;}
&nbsp;&nbsp; &nbsp;printf("Agent Initialized\n");
&nbsp;   /*Setup device identify information*/
&nbsp;&nbsp; &nbsp;core_product_info_set("305A3A77B1CC", NULL/*no parent ID*/, "2.0.1", "IPC", "test", "test"); 
&nbsp;   /*Setup support function tag*/
&nbsp;&nbsp; &nbsp;core_tag_set("RMM");
&nbsp;   /*binding to a specific account*/
&nbsp;&nbsp; &nbsp;core_account_bind("admin","GP25qY7TjJA=");
EXIT:
&nbsp;   /*Release WISECore*/
&nbsp;   core_uninitialize();
	return iRet;
}
bool core_tls_set(const char *cafile, const char *capath, const char *certfile, const char *keyfile, const char *password);</syntaxhighlight lang="c">

''Description''

*Configure the client for certificate based SSL/TLS support. Must be called&nbsp;before &lt;core_connect&gt;.
*Cannot be used in conjunction with &lt;core_tls_psk_set&gt;.
*Define the Certificate Authority certificates to be trusted (ie. the server&nbsp;certificate must be signed with one of these certificates) using cafile.&nbsp;If the server you are connecting to requires clients to provide a&nbsp;certificate, define certfile and keyfile with your client certificate and&nbsp;private key. If your private key is encrypted, provide a password callback&nbsp;function.

''Parameters''

*cafile[POINTER]
**path to a file containing the PEM encoded trusted CA certificate files.
**Either cafile or capath must not be NULL.
*capath[NUMBER]
**path to a directory containing the PEM encoded trusted CA certificate files. See mosquitto.conf for more details on configuring this directory.
**Either cafile or capath must not&nbsp;be NULL.
*certfile[POINTER]
**path to a file containing the PEM encoded certificate file&nbsp;for this client.
**If NULL, keyfile must also be NULL and no&nbsp;client certificate will be used.
*keyfile[POINTER]
**path to a file containing the PEM encoded private key for this client.
**If NULL, certfile must also be NULL and no client certificate will be used.
*password[POINTER]
**if keyfile is encrypted, set the password to allow your client&nbsp;to pass the correct password for decryption.
**need to encrypt with AgentEncrypt application.

''Return Values''

*true/false

''Example''
<syntaxhighlight lang="c">#include "WISECore.h"
int main (int argc, char *argv[]) 
{
&nbsp;   int iRet = 0; /*Initialize WISECore*/ if(!core_initialize("general", "00000001-0000-0000-0000-305A3A77B1CC", "TestClient", "305A3A77B1CC", NULL))
&nbsp;&nbsp; &nbsp;{
&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;printf("Unable to initialize WISECore.\n");
&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;goto EXIT;
&nbsp;&nbsp; &nbsp;}
&nbsp;&nbsp; &nbsp;printf("Agent Initialized\n");
&nbsp;   /*Setup TLS*/
&nbsp;&nbsp; &nbsp;core_tls_set( "server.crt", NULL, "ca.crt", "ca.key", "05155853");
&nbsp; &nbsp; /*Connect to Server*/
&nbsp;&nbsp; &nbsp;core_connect("127.0.0.1",1883,"admin","05155853");

&nbsp;   /*Disconnect*/
  &nbsp; core_disconnect(false);

EXIT:
  &nbsp; /*Release WISECore*/
&nbsp;   core_uninitialize(); return iRet; 
}


int saclient_getsocketaddress(char* clientip, int size);

Description

  • Get local IP address that connect to server.

Parameters

  • clientip [POINTER]
    • IP address string.
  • size[NUMBER]
    • the size of IP address.

Return Values

  • saclient_success: on success.
  • saclient_no_init: not initialized or init failed before.
  • saclient_no_connnect: not connect before or lost connection.
  • saclient_false: connect failed.

Example

#include "SAClient.h"
int main (int argc, char *argv[])
{
	int iRet = 0;
	
	/*agent configuration structure: define how does the agent connect to Server*/
	susiaccess_agent_conf_body_t config;
 	/*Pre-set Agent Config struct*/

	/*agent profile structure: define agent platform information*/
	susiaccess_agent_profile_body_t profile;
	/*Pre-set Agent Profile struct*/
  
	/*Initialize SAClient with Agent Configure and Profile structure, and the Log File Handle*/
	iRet = saclient_initialize(&config, &profile, NULL);
 
	if(iRet&nbsp;!= saclient_success)
	{
		printf("Unable to initialize AgentCore.");
		return iRet;
	}
 
	/*start connect to server, server is defined in agent config*/
	iRet = saclient_connect();
 
	if(iRet&nbsp;!= saclient_success){
		printf("sampleagent Unable to connect to broker.");
			
	} else {
		char localip[256]={0};
		saclient_getsocketaddress(localip, sizeof(localip));
		printf("sampleagent Connected localip:&nbsp;%s", localip);
	}
 
	/*disconnect from server*/
	saclient_disconnect();
	/*release SAClient resource*/
	saclient_uninitialize();
	return iRet;
}

Callback Function

typedef void (*SACLIENT_MESSAGE_RECV_CALLBACK)(char* topic, susiaccess_packet_body_t *pkt, void *pRev1, void* pRev2);

Description

  • define the message receive callback function.

Parameters

  • topic[POINTER]
    • MQTT topic string
  • pkt[POINTER]
    • the packet structure pointer.
  • pRev1[POINTER]
    • preserved pointer.
  • pRev2[POINTER]
    • preserved pointer.

Return Values

  • None.


typedef void (*SACLIENT_CONNECTED_CALLBACK)();

Description

  • define the on connected callback function.

Parameters

  • None

Return Values

  • None.


typedef void (*SACLIENT_LOSTCONNECT_CALLBACK)();

Description

  • define the on lost connect callback function.

Parameters

  • None

Return Values

  • None.


typedef void (*SACLIENT_DISCONNECT_CALLBACK)();

Description

  • define the on disconnect callback function.

Parameters

  • None

Return Values

  • None.

Configuration Structure

typedef struct {
	/*Connection Mode*/
	char runMode[DEF_RUN_MODE_LENGTH];
	char autoStart[DEF_ENABLE_LENGTH];

	/*Connection Info*/
	char serverIP[DEF_MAX_STRING_LENGTH];
	char serverPort[DEF_PORT_LENGTH];
	char serverAuth[DEF_USER_PASS_LENGTH];

	tls_type tlstype;
	/*TLS*/
	char cafile[DEF_MAX_PATH];
	char capath[DEF_MAX_PATH];
	char certfile[DEF_MAX_PATH];
	char keyfile[DEF_MAX_PATH];
	char cerpasswd[DEF_USER_PASS_LENGTH];
	/*pre-shared-key*/
	char psk[DEF_USER_PASS_LENGTH];
	char identity[DEF_USER_PASS_LENGTH];
	char ciphers[DEF_MAX_CIPHER];
}susiaccess_agent_conf_body_t;

Description

  • The structure for agent connect configuration, defined in susiaccess_def.h.

Parameters

  • runMode[POINTER]
    • default is remote.
    • no other mode in WISE Agent version 3.x
  • autoStart[POINTER]
    • The Agent will reconnect to server automatically, default is True.
  • serverIP[POINTER]
    • indicate the server URL or IP Address
  • serverPort[POINTER]
    • Server (MQTT Broker) listen port,
    • in WISE Agent version 3.1 or later the default port is 1883
    • in WISE Agent version 3.0 the default port is 10001.
  • serverAuth[POINTER]
    • Server (MQTT Broker) authentication string.
    • The string is encode from <ID>:<PASS>.
    • It worked on SSL Mode.
  • tlstype [NUMBER]
    • define the TLS (SSL) mode:
      • tls_type_none
      • tls_type_tls
      • tls_type_psk
  • cafile[POINTER]
    • the filepath of SSL Certificate Authority file in tls_type_tls mode.
  • capath[POINTER]
    • the path of SSL Certificate Authority files in tls_type_tls mode.
  • certfile[POINTER]
    • the filepath of SSL Certificate file in tls_type_tls mode.
  • keyfile[POINTER]
    • the filepath of SSL Key file in tls_type_tls mode.
  • cerpasswd[POINTER]
    • the string of SSL Certificate file password in tls_type_tls mode.
  • psk[POINTER]
    • the string of SSL pre-share key in tls_type_psk mode.
  • identity[POINTER]
    • the unique string of SSL identity in tls_type_psk mode.
  • ciphers[POINTER]
    • the supported cipher list in tls_type_psk mode.

Profile Structure

typedef struct {
	/*Agent Info*/
	char version[DEF_MAX_STRING_LENGTH];
	char hostname[DEF_HOSTNAME_LENGTH];
	char devId[DEF_DEVID_LENGTH];
	char sn[DEF_SN_LENGTH];
	char mac[DEF_MAC_LENGTH];
	char lal[DEF_LAL_LENGTH];
	char account[DEF_USER_PASS_LENGTH];
	char passwd[DEF_USER_PASS_LENGTH];
	char workdir[DEF_MAX_PATH];

	/*Custom Info*/
	char type[DEF_MAX_STRING_LENGTH];
	char product[DEF_MAX_STRING_LENGTH];
	char manufacture[DEF_MAX_STRING_LENGTH];

	/*OS Info*/
	char osversion[DEF_OSVERSION_LEN];
	char biosversion[DEF_VERSION_LENGTH];
	char platformname[DEF_FILENAME_LENGTH];
	char processorname[DEF_PROCESSOR_NAME_LEN];
	char osarchitect[DEF_FILENAME_LENGTH];
	long totalmemsize;
	char maclist[DEF_MAC_LENGTH*16];
	char localip[DEF_MAX_STRING_LENGTH];
}susiaccess_agent_profile_body_t;

Description

  • The structure for  platform description, defined in susiaccess_def.h.

Parameters

  • version[POINTER]
    • The version fo the application.
  • hostname [POINTER]
    • The name of target device ro agent.
  • devId[POINTER]
    • The Unique ID of the target device or agent.
  • sn[POINTER]
    • The target device serial number
  • mac[POINTER]
    • the MAC Address of first ethernet or wireless card.
  • type[POINTER]
    • the agent type, defualt is IPC.
    • User can define their own type for customization.
  • produce[POINTER]
    • the product name.
  • manufacture[POINTER]
    • the manufacture name.
  • osversion[POINTER]
    • the OS version of target device.
  • biosversion[POINTER]
    • the BIOS version of target device.
  • platformname[POINTER]
    • the platform (board) name of target device.
  • processorname[POINTER]
    • the processor name of target device.
  • osarchitect[POINTER]
    • the OS architecture name of target device.
  • totalmemsize [NUMBER]
    • the OS recognized total memory size of target device.
  • maclist[POINTER]
    • list all the ethernet and wireless card MAC Address.
  • localip[POINTER]
    • the local IP of target device.
  • account[POINTER]
    • bind the device or anget to the sepcific account, default is anonymous.
  • passwd[POINTER]
    • the encrypted password string of account.
  • workdir[POINTER]
    • current executable binary file location.

Packet Structure

 typedef struct{
	int cmd;
	int requestID;      /**< Callback request id */
	char devId[DEF_DEVID_LENGTH]; /**< Agent device id */
	char handlerName[MAX_TOPIC_LEN];
	char* content;     /**< Callback request content */
	packet_type type;
}susiaccess_packet_body_t;

Description

  • the structure for transmit packet, defined in susiaccess_def.h.

Parameters

  • cmd [NUMBER]
    • The command id defined in Plugins (Handlers).
  • requestID [NUMBER]
    • The unique ID for Plugins (Handlers),
    • No used for V3.1 or later version, preserved for V3.0.
  • devId[POINTER]
    • The target device or Agent ID.
  • handlerName[POINTER]
    • The string of Plugin (Handler) Name.
  • content[POINTER]
    • the string of packet content message.
  • type [NUMBER]
    • the packet type:
      • pkt_type_susiaccess: common RMM message packet wrapped with RMM pre-defined header.
      • pkt_type_custom: customized message packet without wrapped with RMM header.

Client Sample Code

#include "stdafx.h"
#include <SAClient.h>
#include <Windows.h>
#include <Log.h>
/*agent connected callback function*/
void on_connect_cb()
{
	SUSIAccessAgentLog(Normal, "CB_Connected ");
}

/*agent lost connect callback function*/
void on_lost_connect_cb()
{
	SUSIAccessAgentLog(Normal, "CB_Lostconnect ");
}

/*agent disconnect callback function*/
void on_disconnect_cb()
{
	SUSIAccessAgentLog(Normal, "CB_Disconnect ");
}

/*agent received message callback function*/
void on_msgrecv(char* topic, susiaccess_packet_body_t *pkt, void *pRev1, void* pRev2)
{
	/*user can process received command here*/
	SUSIAccessAgentLog(Normal, "Packet received, %s\r\n", pkt->content);
}

int main(int argc, char *argv[])
{
	int iRet = 0;
	char moudlePath[MAX_PATH] = {0};
	
	/*agent configuration structure: define how does the agent connect to Server*/
	susiaccess_agent_conf_body_t config;

	/*agent profile structure: define agent platform information*/
	susiaccess_agent_profile_body_t profile;

	memset(moudlePath, 0 , sizeof(moudlePath));
	util_module_path_get(moudlePath);
		
	// Initialize Log Library
	SUSIAccessAgentLogHandle = InitLog(moudlePath);
	SUSIAccessAgentLog(Normal, "Current path: %s", moudlePath);

	// Pre-set Agent Config struct
	memset(&config, 0 , sizeof(susiaccess_agent_conf_body_t));
	strcpy(config.runMode,"remote"); //runMode default is remote. There are no other mode in WISE Agent version 3.x
	strcpy(config.autoStart,"True"); //autoStart default is True. The Agent will reconnect to server automatically.
	strcpy(config.serverIP,"dev-wisepaas.eastasia.cloudapp.azure.com"); //serverIP indicate the server URL or IP Address
	strcpy(config.serverPort,"1883"); //serverPort indocate the server (MQTT Broker) listen port, default is 1883 in WISE Agent version 3.1 or later, WISE Agent version 3.0 is 10001.
	strcpy(config.serverAuth,"fENl4B7tnuwpIbs61I5xJQ=="); //serverAuth is the server (MQTT Broker) authentication string. the string is encode from <ID>:<PASS>. It only worked on SSL Mode.
	config.tlstype = tls_type_none; //tlstype define the TLS (SSL) mode
	switch(config.tlstype)
	{
	case tls_type_none: //disable TLS (SSL).
		break;
	case tls_type_tls: //setup TLS with certificate file.
		{
			strcpy(config.cafile, "ca.crt");
			strcpy(config.capath, "");
			strcpy(config.certfile, "server.crt");
			strcpy(config.keyfile, "server.key");
			strcpy(config.cerpasswd, "123456");
		}
		break;
	case tls_type_psk: //setup TLS with pre share key.
		{
			strcpy(config.psk, "");
			strcpy(config.identity, "SAClientSample");
			strcpy(config.ciphers, "");
		}
		break;
	}

	// Pre-set Agent Profile struct
	memset(&profile, 0 , sizeof(susiaccess_agent_profile_body_t));
	snprintf(profile.version, DEF_VERSION_LENGTH, "%d.%d.%d.%d", 3, 1, 0, 0);  //version indicate the version fo the application.
	strcpy(profile.hostname,"SAClientSample"); //hostname indicate the name of target device ro agent.
	strcpy(profile.devId,"000014DAE996BE04"); //devId is the Unique ID of the target device or agent.
	strcpy(profile.sn,"14DAE996BE04"); //sn indicate the device serial number.
	strcpy(profile.mac,"14DAE996BE04"); //mac indicate the MAC Address of first ethernet or wireless card.
	strcpy(profile.type,"IPC"); //type indicate the agent type, defualt is IPC. User can define their own type for customization.
	strcpy(profile.product,"Sample Agent"); //produce indicate the product name
	strcpy(profile.manufacture,"test"); //manufacture indicate the manufacture name
	strcpy(profile.osversion,"NA"); //osversion indicate the OS version of target device
	strcpy(profile.biosversion,"NA"); //biosversion indicate the BIOS version of target device
	strcpy(profile.platformname,"NA"); //platformname indicate the platform (board) name of target device
	strcpy(profile.processorname,"NA"); //processorname indicate the processor name of target device
	strcpy(profile.osarchitect,"NA"); //osarchitect indicate the OS architecture name of target device
	profile.totalmemsize = 40832; //totalmemsize indicate the OS recognized total memory size of target device
	strcpy(profile.maclist,"14DAE996BE04"); //maclist list all the ethernet and wireless card MAC Address.
	strcpy(profile.localip,"172.21.73.151"); //localip indicate the local IP of target device
	strcpy(profile.account,"anonymous"); //account bind the device or anget to the sepcific account, default is anonymous.
	strcpy(profile.passwd,""); //passwd indicate the encrypted password of account.
	strcpy(profile.workdir, moudlePath); //workdir indicate current executable binary file location.


	/*Initialize SAClient with Agent Configure and Profile structure, and the Log File Handle*/
	iRet = saclient_initialize(&config, &profile, SUSIAccessAgentLogHandle);

	if(iRet != saclient_success)
	{
		SUSIAccessAgentLog(Error, "Unable to initialize AgentCore.");
		goto EXIT;
	}

	SUSIAccessAgentLog(Normal, "Agent Initialized");

	/*register the conect, lost connect and disconnect callback function*/
	saclient_connection_callback_set(on_connect_cb, on_disconnect_cb, on_disconnect_cb);

	SUSIAccessAgentLog(Normal, "Agent Set Callback");
	
	/*start connect to server, server is defined in agent config*/
	iRet = saclient_connect();

	if(iRet != saclient_success){
		SUSIAccessAgentLog(Error, "sampleagent Unable to connect to broker.");
		goto EXIT;
	} else {
		SUSIAccessAgentLog(Normal, "sampleagent Connect to broker: %s", config.serverIP);
	}
	
	{
		
		char topicStr[128] = {0};
		susiaccess_packet_body_t pkt;

		/* Add  subscribe topic Callback*/
		sprintf(topicStr, "/cagent/admin/%s/testreq", profile.devId);
		saclient_subscribe(topicStr, 0, on_msgrecv);
		
		/*Send test packet to specific topic*/
		strcpy(pkt.devId, profile.devId);
		strcpy(pkt.handlerName, "Test");
		pkt.requestID = 0;
		pkt.cmd = 0;
		pkt.content = (char*)malloc(strlen("{\"Test\":100}")+1);
		memset(pkt.content, 0, strlen("{\"Test\":100}")+1);
		strcpy(pkt.content, "{\"Test\":100}");
		saclient_publish(topicStr, 0, false, &pkt);
		free(pkt.content);
	}

EXIT:
	printf("Click enter to exit");
	fgetc(stdin);

	/*disconnect from server*/
	saclient_disconnect();
	SUSIAccessAgentLog(Normal, "Send Client Info: disconnect");
	/*release SAClient resource*/
	saclient_uninitialize();
	SUSIAccessAgentLog(Normal, "Agent Uninitialize");
	/*release log resource*/
	UninitLog(SUSIAccessAgentLogHandle);

	return iRet;
}