Difference between revisions of "EI-Agent Sample Client"

From ESS-WIKI
Jump to: navigation, search
(Add core_tls_psk_set Sample Code)
 
(30 intermediate revisions by the same user not shown)
Line 35: Line 35:
  
 
<syntaxhighlight lang="c">void core_uninitialize();</syntaxhighlight> ''Description''
 
<syntaxhighlight lang="c">void core_uninitialize();</syntaxhighlight> ''Description''
*General function to uninitialize the WISECore API library that should be called before program exit.
+
*General function to release the WISECore API library that should be called before program exit.
  
 
''Parameters''
 
''Parameters''
Line 60: Line 60:
 
**the serial number string of target device.
 
**the serial number string of target device.
 
*strParentID[POINTER]
 
*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&nbsp;if the taget device connect to server through an EIS or Gateway device.
+
**the parent device ID string in UUID format: xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx, used to point out the EIS or Gateway device ID&nbsp;if the target device connect to server through an EIS or Gateway device.
 
*strVersion[POINTER]
 
*strVersion[POINTER]
**the applicatin version string.
+
**the application version string.
 
*strType[POINTER]
 
*strType[POINTER]
**the applicatin type string, default is "IPC" for general usage.
+
**the application type string, default is "IPC" for general usage.
 
*strProduct[POINTER]
 
*strProduct[POINTER]
 
**the target device product name.
 
**the target device product name.
Line 119: Line 119:
 
int main (int argc, char *argv[])
 
int main (int argc, char *argv[])
 
{
 
{
int iRet = 0;
+
    int iRet = 0;
/*Initialize WISECore*/
+
    /*Initialize WISECore*/
if(!core_initialize("general", "00000001-0000-0000-0000-305A3A77B1CC", "TestClient", "305A3A77B1CC", NULL))
+
    if(!core_initialize("general", "00000001-0000-0000-0000-305A3A77B1CC", "TestClient", "305A3A77B1CC", NULL))
 
     {
 
     {
 
         printf("Unable to initialize WISECore.\n");
 
         printf("Unable to initialize WISECore.\n");
Line 136: Line 136:
 
     /*Release WISECore*/
 
     /*Release WISECore*/
 
     core_uninitialize();
 
     core_uninitialize();
return iRet;
+
    return iRet;
 
}
 
}
 
</syntaxhighlight>
 
</syntaxhighlight>
Line 173: Line 173:
 
int main (int argc, char *argv[])  
 
int main (int argc, char *argv[])  
 
{
 
{
     int iRet = 0; /*Initialize WISECore*/ if(!core_initialize("general", "00000001-0000-0000-0000-305A3A77B1CC", "TestClient", "305A3A77B1CC", NULL))
+
     int iRet = 0; /*Initialize WISECore*/   if(!core_initialize("general", "00000001-0000-0000-0000-305A3A77B1CC", "TestClient", "305A3A77B1CC", NULL))
 
     {
 
     {
 
         printf("Unable to initialize WISECore.\n");
 
         printf("Unable to initialize WISECore.\n");
Line 218: Line 218:
 
int main (int argc, char *argv[])  
 
int main (int argc, char *argv[])  
 
{
 
{
     int iRet = 0; /*Initialize WISECore*/ if(!core_initialize("general", "00000001-0000-0000-0000-305A3A77B1CC", "TestClient", "305A3A77B1CC", NULL))
+
     int iRet = 0; /*Initialize WISECore*/    if(!core_initialize("general", "00000001-0000-0000-0000-305A3A77B1CC", "TestClient", "305A3A77B1CC", NULL))
 
     {
 
     {
 
         printf("Unable to initialize WISECore.\n");
 
         printf("Unable to initialize WISECore.\n");
Line 238: Line 238:
 
}
 
}
 
</syntaxhighlight>
 
</syntaxhighlight>
 +
----
 +
 +
 +
<syntaxhighlight lang="c">bool core_connect(char* strServerIP, int iServerPort, char* strConnID, char* strConnPW);</syntaxhighlight> ''Description''
 +
*Connect to server that defined in Configuration data of lite_initialize parameters.
 +
 +
''Parameters''
 +
 +
*strServerIP[POINTER]
 +
**remote server URL or IP address.
 +
*iServerPort[NUMBER]
 +
**connection protocol listen port.
 +
*strConnID[POINTER]
 +
**connection protocol access id
 +
*strConnPW[POINTER]
 +
**connection protocol access password
 +
 +
''Return Values''
 +
 +
*true/false
 +
 +
''Example''
 +
 +
Reference to core_tls_set().
 +
 +
----
 +
 +
 +
<syntaxhighlight lang="c">void core_disconnect(bool bForce);</syntaxhighlight> ''Description''
 +
*Disconnect from server.
 +
 +
''Parameters''
 +
 +
*bForce[BOOLEAN]
 +
**Is force to disconnect.
 +
 +
''Return Values''
 +
 +
*None
 +
 +
''Example''
 +
 +
Reference to core_tls_set().
 +
 +
----
 +
 +
 +
<syntaxhighlight lang="c">bool core_connection_callback_set(CORE_CONNECTED_CALLBACK on_connect, CORE_LOSTCONNECTED_CALLBACK on_lostconnect, CORE_DISCONNECT_CALLBACK on_disconnect, CORE_MESSAGE_RECV_CALLBACK on_msg_recv);</syntaxhighlight> ''Description''
 +
*Register the callback function to handle the connection event.
 +
 +
''Parameters''
 +
 +
*on_connect[POINTER]
 +
**Function Pointer to handle connect success event.
 +
*on_lost_connect[POINTER]
 +
**Function Pointer to handle lost connect event.
 +
**The SAClient will reconnect automatically, if left as NULL.
 +
*on_disconnect[POINTER]
 +
**Function Pointer to handle disconnect event.
 +
*on_msg_recv[POINTER]
 +
**Function Pointer to handle message receive event.
 +
 +
''Return Values''
 +
 +
*true/false
 +
 +
''Example''
 +
<syntaxhighlight lang="c">#include "WISECore.h"
 +
void on_connect_cb(void* userdata)
 +
{
 +
    printf("CB_Connected \n");
 +
    /*Send device register message.*/
 +
    core_device_register();
 +
}
 +
 +
void on_lostconnect_cb(void* userdata)
 +
{
 +
    printf("CB_Lostconnect %s\n", core_error_string_get());
 +
}
 +
 +
void on_disconnect_cb(void* userdata)
 +
{
 +
    printf("CB_Disconnect \n");
 +
}
 +
 +
void on_msgrecv(const char* topic, const void *pkt, const long pktlength, void* userdata)
 +
{
 +
    printf("Packet received:\n [%s],\n %s\n", topic, pkt);
 +
}
 +
 +
int main (int argc, char *argv[])
 +
{
 +
    int iRet = 0; /*Initialize WISECore*/    if(!core_initialize("general", "00000001-0000-0000-0000-305A3A77B1CC", "TestClient", "305A3A77B1CC", NULL))
 +
    {
 +
        printf("Unable to initialize WISECore.\n");
 +
        goto EXIT;
 +
    }
 +
    printf("Agent Initialized\n");
 +
    /*Setup connection callback function*/
 +
    core_connection_callback_set(on_connect_cb, on_lostconnect_cb, on_disconnect_cb, on_msgrecv);
 +
 +
    /*Connect to Server*/
 +
    core_connect("127.0.0.1",1883,"admin","123456");
 +
 +
    /*Disconnect*/
 +
    core_disconnect(false);
 +
 +
EXIT:
 +
    /*Release WISECore*/
 +
    core_uninitialize();
 +
    return iRet;
 +
}
 +
</syntaxhighlight>
 +
----
 +
 +
 +
<syntaxhighlight lang="c">bool core_action_callback_set(CORE_RENAME_CALLBACK on_rename, CORE_UPDATE_CALLBACK on_update);</syntaxhighlight> ''Description''
 +
*Register the callback function to handle the action event.
 +
 +
''Parameters''
 +
 +
*on_rename[POINTER]
 +
**Function Pointer to handle rename event.
 +
*on_update[POINTER]
 +
**Function Pointer to handle update event.
 +
 +
''Return Values''
 +
 +
*true/false
 +
 +
''Example''
 +
<syntaxhighlight lang="c">#include "WISECore.h"
 +
void on_rename(const char* name, const int cmdid, const char* sessionid, const char* tenantid, const char* devid, void* userdata)
 +
{
 +
    printf("rename to: %s\n", name);
 +
    /*Send action response*/
 +
    core_action_response(cmdid, sessionid, true, tenantid, devid);
 +
    return;
 +
}
 +
 +
void on_update(const char* loginID, const char* loginPW, const int port, const char* path, const char* md5, const int cmdid, const char* sessionid, const char* tenantid, const char* devid, void* userdata)
 +
{
 +
    printf("Update: %s, %s, %d, %s, %s\n", loginID, loginPW, port, path, md5);
 +
    /*Send action response*/
 +
    core_action_response(cmdid, sessionid, true, tenantid, devid);
 +
    return;
 +
}
 +
 +
int main (int argc, char *argv[])
 +
{
 +
    int iRet = 0; /*Initialize WISECore*/    if(!core_initialize("general", "00000001-0000-0000-0000-305A3A77B1CC", "TestClient", "305A3A77B1CC", NULL))
 +
    {
 +
        printf("Unable to initialize WISECore.\n");
 +
        goto EXIT;
 +
    }
 +
    printf("Agent Initialized\n");
 +
    /*Setup action request callback function*/
 +
    core_action_callback_set(on_rename, on_update);
 +
 +
    /*Connect to Server*/
 +
    core_connect("127.0.0.1",1883,"admin","123456");
 +
 +
    /*Disconnect*/
 +
    core_disconnect(false);
 +
 +
EXIT:
 +
    /*Release WISECore*/
 +
    core_uninitialize();
 +
    return iRet;
 +
}
 +
</syntaxhighlight>
 +
----
 +
 +
 +
<syntaxhighlight lang="c">bool core_action_response(const int cmdid, const char * sessoinid, bool success, const char* tenantid, const char* devid);</syntaxhighlight> ''Description''
 +
*Send rename, update or heartbeat rate update action response back to server.
 +
 +
''Parameters''
 +
 +
*cmdid[NUMBER]
 +
**command ID of request action.
 +
*sessionid[POINTER]
 +
**session ID of request action.
 +
*success[BOOLEAN]
 +
**result of request action.
 +
*tenantid[POINTER]
 +
**tenant ID of request device.
 +
*devid[POINTER]
 +
**device ID of request device.
 +
 +
''Return Values''
 +
 +
*true/false
 +
 +
''Example''
 +
 +
Reference to core_action_callback_set().
 +
 +
----
 +
 +
 +
<syntaxhighlight lang="c">bool core_server_reconnect_callback_set(CORE_SERVER_RECONNECT_CALLBACK on_server_reconnect);</syntaxhighlight> ''Description''
 +
*Register the callback function to handle the server reconnect event.
 +
 +
''Parameters''
 +
 +
*on_server_reconnect[POINTER]
 +
**Function Pointer to handle server reconnect event.
 +
 +
''Return Values''
 +
 +
*true/false
 +
 +
''Example''
 +
<syntaxhighlight lang="c">#include "WISECore.h"
 +
void on_server_reconnect(const char* tenantid, const char* devid, void* userdata)
 +
{
 +
    /*Send device register message again.*/
 +
    core_device_register();
 +
}
 +
 +
int main (int argc, char *argv[])
 +
{
 +
    int iRet = 0; /*Initialize WISECore*/    if(!core_initialize("general", "00000001-0000-0000-0000-305A3A77B1CC", "TestClient", "305A3A77B1CC", NULL))
 +
    {
 +
        printf("Unable to initialize WISECore.\n");
 +
        goto EXIT;
 +
    }
 +
    printf("Agent Initialized\n");
 +
    /*Setup reconnect request callback function*/
 +
    core_server_reconnect_callback_set(on_server_reconnect);
 +
 +
    /*Connect to Server*/
 +
    core_connect("127.0.0.1",1883,"admin","123456");
 +
 +
    /*Disconnect*/
 +
    core_disconnect(false);
 +
 +
EXIT:
 +
    /*Release WISECore*/
 +
    core_uninitialize();
 +
    return iRet;
 +
}
 +
</syntaxhighlight>
 +
----
 +
 +
 +
<syntaxhighlight lang="c">bool core_iot_callback_set(CORE_GET_CAPABILITY_CALLBACK on_get_capability, CORE_START_REPORT_CALLBACK on_start_report, CORE_STOP_REPORT_CALLBACK on_stop_report);</syntaxhighlight> ''Description''
 +
*Register the callback function to handle the get IoT capability or start/stop report sensor data.
 +
 +
''Parameters''
 +
 +
*on_get_capability[POINTER]
 +
**Function Pointer to handle get capability event.
 +
*on_start_report[POINTER]
 +
**Function Pointer to handle start report event.
 +
*on_stop_report[POINTER]
 +
**Function Pointer to handle stop report event.
 +
 +
''Return Values''
 +
 +
*true/false
 +
 +
''Example''
 +
<syntaxhighlight lang="c">#include "WISECore.h"
 +
void on_get_capability(const void *pkt, const long pktlength, const char* tenantid, const char* devid, void* userdata)
 +
{
 +
    printf("on_get_capabiltenanted\n");
 +
    /*TODO: send whole capability*/
 +
}
 +
 +
void on_start_report(const void *pkt, const long pktlength, const char* tenantid, const char* devid, void* userdata)
 +
{
 +
    /*TODO: start report sensor data*/
 +
    printf("on_start_report\n");
 +
}
 +
 +
void on_stop_report(const void *pkt, const long pktlength, const char* tenantid, const char* devid, void* userdata)
 +
{
 +
    /*TODO: stop report sensor data*/
 +
    printf("on_stop_report\n");
 +
}
 +
 +
int main (int argc, char *argv[])
 +
{
 +
    int iRet = 0; /*Initialize WISECore*/    if(!core_initialize("general", "00000001-0000-0000-0000-305A3A77B1CC", "TestClient", "305A3A77B1CC", NULL))
 +
    {
 +
        printf("Unable to initialize WISECore.\n");
 +
        goto EXIT;
 +
    }
 +
    printf("Agent Initialized\n");
 +
    /*Setup iot command callback function*/
 +
    core_iot_callback_set(on_get_capability, on_start_report, on_stop_report);
 +
 +
    /*Connect to Server*/
 +
    core_connect("127.0.0.1",1883,"admin","123456");
 +
 +
    /*Disconnect*/
 +
    core_disconnect(false);
 +
 +
EXIT:
 +
    /*Release WISECore*/
 +
    core_uninitialize();
 +
    return iRet;
 +
}
 +
</syntaxhighlight>
 +
----
 +
 +
 +
<syntaxhighlight lang="c">bool core_time_tick_callback_set(CORE_GET_TIME_TICK_CALLBACK get_time_tick);</syntaxhighlight> ''Description''
 +
*Register the callback function to assign time tick.
 +
 +
''Parameters''
 +
 +
*get_time_tick[POINTER]
 +
**Function Pointer to assign current timestamp in millisecond.
 +
 +
''Return Values''
 +
 +
*true/false
 +
 +
''Example''
 +
<syntaxhighlight lang="c">#include "WISECore.h"
 +
#ifdef WIN32
 +
#include "sys/time.h"
 +
int gettimeofday(struct timeval *tv, struct timezone *tz)
 +
{
 +
    time_t clock;
 +
    struct tm tm;
 +
    SYSTEMTIME wtm;
 +
 +
    GetLocalTime(&wtm);
 +
    tm.tm_year    = wtm.wYear - 1900;
 +
    tm.tm_mon    = wtm.wMonth - 1;
 +
    tm.tm_mday    = wtm.wDay;
 +
    tm.tm_hour    = wtm.wHour;
 +
    tm.tm_min    = wtm.wMinute;
 +
    tm.tm_sec    = wtm.wSecond;
 +
    tm. tm_isdst    = -1;
 +
    clock = mktime(&tm);
 +
    tv->tv_sec = (long)clock;
 +
    tv->tv_usec = wtm.wMilliseconds * 1000;
 +
 +
    return (0);
 +
}
 +
#endif
 +
 +
long long get_timetick(void* userdata)
 +
{
 +
long long tick = 0;
 +
struct timeval tv;
 +
gettimeofday(&tv, NULL);
 +
tick = (long long)tv.tv_sec*1000 + (long long)tv.tv_usec/1000;
 +
return tick;
 +
}
 +
 +
int main (int argc, char *argv[])
 +
{
 +
    int iRet = 0; /*Initialize WISECore*/    if(!core_initialize("general", "00000001-0000-0000-0000-305A3A77B1CC", "TestClient", "305A3A77B1CC", NULL))
 +
    {
 +
        printf("Unable to initialize WISECore.\n");
 +
        goto EXIT;
 +
    }
 +
    printf("Agent Initialized\n");
 +
    /*Setup time tick callback function*/
 +
    core_time_tick_callback_set(get_timetick);
 +
 +
    /*Connect to Server*/
 +
    core_connect("127.0.0.1",1883,"admin","123456");
 +
 +
    /*Disconnect*/
 +
    core_disconnect(false);
 +
 +
EXIT:
 +
    /*Release WISECore*/
 +
    core_uninitialize();
 +
    return iRet;
 +
 +
</syntaxhighlight>
 +
----
 +
 +
 +
<syntaxhighlight lang="c">bool core_heartbeat_callback_set(CORE_QUERY_HEARTBEATRATE_CALLBACK on_query_heartbeatrate, CORE_UPDATE_HEARTBEATRATE_CALLBACK on_update_heartbeatrate);</syntaxhighlight> ''Description''
 +
*Register the callback function to handle the heartbeat rate query and update command.
 +
 +
''Parameters''
 +
 +
*on_query_heartbeatrate[POINTER]
 +
**Function Pointer to handle heartbeat rate query event.
 +
*on_update_heartbeatrate[POINTER]
 +
**Function Pointer to handle heartbeat rate update event.
 +
 +
''Return Values''
 +
 +
*true/false
 +
 +
''Example''
 +
<syntaxhighlight lang="c">#include "WISECore.h"
 +
int g_iHeartbeatRate = 60;
 +
void on_heartbeatrate_query(const char* sessionid, const char* tenantid, const char* devid, void* userdata)
 +
{
 +
    /*Send current heartbeat rate:60 back to server*/
 +
    core_heartbeatratequery_response(g_iHeartbeatRate, sessionid, tenantid, devid);
 +
    printf("Heartbeat Rate Query: %s, %s\n", sessionid, devid);
 +
}
 +
 +
void on_heartbeatrate_update(const int heartbeatrate, const char* sessionid, const char* tenantid, const char* devid, void* userdata)
 +
{
 +
    printf("Heartbeat Rate Update: %d, %s, %s\n", heartbeatrate, sessionid, devid);
 +
    g_iHeartbeatRate = heartbeatrate;
 +
    core_action_response(130/*wise_heartbeatrate_update_rep*/, sessionid, true, tenantid, devid);
 +
}
 +
 +
int main (int argc, char *argv[])
 +
{
 +
    int iRet = 0; /*Initialize WISECore*/    if(!core_initialize("general", "00000001-0000-0000-0000-305A3A77B1CC", "TestClient", "305A3A77B1CC", NULL))
 +
    {
 +
        printf("Unable to initialize WISECore.\n");
 +
        goto EXIT;
 +
    }
 +
    printf("Agent Initialized\n");
 +
    /*Setup heartbeat command callback function*/
 +
    core_heartbeat_callback_set(on_heartbeatrate_query, on_heartbeatrate_update);
 +
 +
    /*Connect to Server*/
 +
    core_connect("127.0.0.1",1883,"admin","123456");
 +
 +
    /*Disconnect*/
 +
    core_disconnect(false);
 +
 +
EXIT:
 +
    /*Release WISECore*/
 +
    core_uninitialize();
 +
    return iRet;
 +
 +
</syntaxhighlight>
 +
----
 +
 +
 +
<syntaxhighlight lang="c">bool core_heartbeatratequery_response(const int heartbeatrate, const char * sessoinid, const char* tenantid, const char* devid);</syntaxhighlight> ''Description''
 +
*Send heartbeat rate update response back to server.
 +
 +
''Parameters''
 +
 +
*heartbeatrate[NUMBER]
 +
**current heartbeat rate.
 +
*sessionid[POINTER]
 +
**session ID of request action.
 +
*tenantid[POINTER]
 +
**tenant ID of request device.
 +
*devid[POINTER]
 +
**device ID of request device.
 +
 +
''Return Values''
 +
 +
*true/false
 +
 +
''Example''
 +
 +
Reference to core_heartbeat_callback_set().
 +
 +
----
 +
 +
 +
<syntaxhighlight lang="c">bool core_device_register();</syntaxhighlight> ''Description''
 +
*Send device information, wrapped in JSON format, to register device.
 +
 +
''Parameters''
 +
 +
*None
 +
 +
''Return Values''
 +
 +
*true/false
 +
 +
''Example''
 +
 +
Reference to core_connection_callback_set().
 +
 +
----
 +
 +
 +
<syntaxhighlight lang="c">bool core_heartbeat_send();</syntaxhighlight> ''Description''
 +
*Send heartbeat message, wrapped in JSON format, to server.
 +
 +
''Parameters''
 +
 +
*None
 +
 +
''Return Values''
 +
 +
*true/false
 +
 +
''Example''
 +
<syntaxhighlight lang="c">#include "WISECore.h"
 +
#include "pthread.h"
 +
int g_iHeartbeatRate = 60;
 +
void* threadconnect(void* args)
 +
{
 +
    core_device_register();
 +
    while(true)
 +
    {
 +
        core_heartbeat_send();
 +
        usleep(g_iHeartbeatRate*1000000);
 +
    }
 +
    pthread_exit(0);
 +
    return NULL;
 +
}
 +
 +
void on_connect_cb(void* userdata)
 +
{
 +
pthread_t conn = 0;
 +
if(pthread_create(&conn, NULL, threadconnect, NULL)==0)
 +
pthread_detach(conn);
 +
}
 +
 +
int main (int argc, char *argv[])
 +
{
 +
    int iRet = 0; /*Initialize WISECore*/    if(!core_initialize("general", "00000001-0000-0000-0000-305A3A77B1CC", "TestClient", "305A3A77B1CC", NULL))
 +
    {
 +
        printf("Unable to initialize WISECore.\n");
 +
        goto EXIT;
 +
    }
 +
    printf("Agent Initialized\n");
 +
    /*Setup connection callback function*/
 +
    core_connection_callback_set(on_connect_cb, on_lostconnect_cb, on_disconnect_cb, on_msgrecv);
 +
 +
    /*Connect to Server*/
 +
    core_connect("127.0.0.1",1883,"admin","123456");
 +
 +
    /*Disconnect*/
 +
    core_disconnect(false);
 +
 +
EXIT:
 +
    /*Release WISECore*/
 +
    core_uninitialize();
 +
    return iRet;
 +
 +
</syntaxhighlight>
 +
----
 +
 +
 +
<syntaxhighlight lang="c">bool core_publish(char const * topic, void * pkt, long pktlength, int retain, int qos);</syntaxhighlight> ''Description''
 +
*Send message, wrapped in JSON format, to server on specific topic.
 +
 +
''Parameters''
 +
 +
*topic[POINTER]
 +
**the MQTT topic to publish.
 +
*pkt[POINTER]
 +
**the message to publish, in JSON string struct.
 +
*pktlength[NUMBER]
 +
**the message length.
 +
*retain[NUMBER]
 +
**enable flag to retain this message in broker.
 +
*qos[NUMBER]
 +
**QoS level 1, 2, 3
 +
 +
''Return Values''
 +
 +
*true/false
 +
 +
''Example''
 +
<syntaxhighlight lang="c">#include "WISECore.h"
 +
#include "pthread.h"
 +
int g_iHeartbeatRate = 60;
 +
void* threadconnect(void* args)
 +
{
 +
    core_device_register();
 +
    while(true)
 +
    {
 +
        core_publish(" /wisepaas/general/device/00000001-0000-0000-0000-305A3A77B1CC/devinfoack", "{\"agentID\":\"00000001-0000-0000-0000-305A3A77B1CC\",\"handlerName\":\"general\",\"commCmd\":2055,\"content\":{\"sample\":{\"data1\":5}}}", 123, 0, 0);
 +
        usleep(g_iHeartbeatRate*1000000);
 +
    }
 +
    pthread_exit(0);
 +
    return NULL;
 +
}
 +
 +
void on_connect_cb(void* userdata)
 +
{
 +
pthread_t conn = 0;
 +
if(pthread_create(&conn, NULL, threadconnect, NULL)==0)
 +
pthread_detach(conn);
 +
}
 +
 +
int main (int argc, char *argv[])
 +
{
 +
    int iRet = 0; /*Initialize WISECore*/    if(!core_initialize("general", "00000001-0000-0000-0000-305A3A77B1CC", "TestClient", "305A3A77B1CC", NULL))
 +
    {
 +
        printf("Unable to initialize WISECore.\n");
 +
        goto EXIT;
 +
    }
 +
    printf("Agent Initialized\n");
 +
    /*Setup connection callback function*/
 +
    core_connection_callback_set(on_connect_cb, on_lostconnect_cb, on_disconnect_cb, on_msgrecv);
 +
 +
    /*Connect to Server*/
 +
    core_connect("127.0.0.1",1883,"admin","123456");
 +
 +
    /*Disconnect*/
 +
    core_disconnect(false);
 +
 +
EXIT:
 +
    /*Release WISECore*/
 +
    core_uninitialize();
 +
    return iRet;
 +
 +
</syntaxhighlight>
 +
----
 +
 +
 +
<syntaxhighlight lang="c">bool core_subscribe(char const * topic, int qos);</syntaxhighlight> ''Description''
 +
*subscribe and receive the message from server on specific topic.
 +
 +
''Parameters''
 +
 +
*topic[POINTER]
 +
**the topic to subscribe.
 +
*qos[NUMBER]
 +
**QoS level 1, 2, 3
 +
 +
''Return Values''
 +
 +
*true/false
 +
 +
''Example''
 +
<syntaxhighlight lang="c">#include "WISECore.h"
 +
void on_connect_cb(void* userdata)
 +
{
 +
    printf("CB_Connected \n");
 +
    /*Send device register message.*/
 +
    core_device_register();
 +
 +
    core_subscribe("/wisepaas/general/device/00000001-0000-0000-0000-305A3A77B1CC/agentactionreq", 0);
 +
}
 +
 +
void on_lostconnect_cb(void* userdata)
 +
{
 +
    printf("CB_Lostconnect %s\n", core_error_string_get());
 +
}
 +
 +
void on_disconnect_cb(void* userdata)
 +
{
 +
    printf("CB_Disconnect \n");
 +
}
 +
 +
void on_msgrecv(const char* topic, const void *pkt, const long pktlength, void* userdata)
 +
{
 +
    printf("Packet received:\n [%s],\n %s\n", topic, pkt);
 +
}
 +
 +
int main (int argc, char *argv[])
 +
{
 +
    int iRet = 0; /*Initialize WISECore*/    if(!core_initialize("general", "00000001-0000-0000-0000-305A3A77B1CC", "TestClient", "305A3A77B1CC", NULL))
 +
    {
 +
        printf("Unable to initialize WISECore.\n");
 +
        goto EXIT;
 +
    }
 +
    printf("Agent Initialized\n");
 +
    /*Setup connection callback function*/
 +
    core_connection_callback_set(on_connect_cb, on_lostconnect_cb, on_disconnect_cb, on_msgrecv);
 +
 +
    /*Connect to Server*/
 +
    core_connect("127.0.0.1",1883,"admin","123456");
 +
 +
    /*Unsubscribe topic*/
 +
    core_unsubscribe("/wisepaas/general/device/00000001-0000-0000-0000-305A3A77B1CC/agentactionreq");
 +
 +
    /*Disconnect*/
 +
    core_disconnect(false);
 +
 +
EXIT:
 +
    /*Release WISECore*/
 +
    core_uninitialize();
 +
    return iRet;
 +
}
 +
</syntaxhighlight>
 +
----
 +
 +
 +
<syntaxhighlight lang="c">bool core_unsubscribe(char const * topic)</syntaxhighlight> ''Description''
 +
*stop to receive message from server on specific topic.
 +
 +
''Parameters''
 +
 +
*topic[POINTER]
 +
**the topic to unsubscribe.
 +
 +
''Return Values''
 +
 +
*true/false
 +
 +
''Example''
 +
 +
Reference to core_subscribe().
 +
 +
----
 +
 +
 +
<syntaxhighlight lang="c">const char* core_error_string_get();</syntaxhighlight> ''Description''
 +
*Call to obtain a const string description the error number.
 +
 +
''Parameters''
 +
 +
*None
 +
 +
''Return Values''
 +
 +
*true/false
 +
 +
''Example''
 +
 +
Reference to core_connection_callback_set().
  
 
=== Callback Function ===
 
=== Callback Function ===
<pre>typedef&nbsp;void (*SACLIENT_MESSAGE_RECV_CALLBACK)(char* topic, susiaccess_packet_body_t *pkt, void *pRev1, void* pRev2);</pre>
 
  
''Description''
 
  
 +
<syntaxhighlight lang="c">typedef void (*CORE_MESSAGE_RECV_CALLBACK)(const char* topic, const void *pkt, const long pktlength, void* userdata);</syntaxhighlight>''Description''
 
*define the message receive callback function.
 
*define the message receive callback function.
  
Line 251: Line 963:
 
**MQTT topic string
 
**MQTT topic string
 
*pkt[POINTER]
 
*pkt[POINTER]
**the packet&nbsp;structure pointer.
+
**the packet structure pointer.
*pRev1[POINTER]
+
*pktlength[NUMBER]
**preserved pointer.
+
**received packet length.
*pRev2[POINTER]
+
*userdata[POINTER]
**preserved pointer.
+
**unformated pointer to carry the user defined structure.
  
 
''Return Values''
 
''Return Values''
Line 264: Line 976:
  
  
<pre>typedef&nbsp;void (*SACLIENT_CONNECTED_CALLBACK)();</pre>
+
<syntaxhighlight lang="c">typedef void (*CORE_CONNECTED_CALLBACK)(void* userdata);</syntaxhighlight> ''Description''
 +
*define the on connected callback function.
 +
 
 +
''Parameters''
 +
 
 +
*userdata[POINTER]
 +
**unformated pointer to carry the user defined structure.
 +
 
 +
''Return Values''
 +
 
 +
*None.
 +
 
 +
----
 +
 
 +
 
 +
<syntaxhighlight lang="c">typedef void (*CORE_LOSTCONNECTED_CALLBACK)(void* userdata);</syntaxhighlight> ''Description''
 +
*define the on lost connect&nbsp;callback function.
 +
 
 +
''Parameters''
 +
 
 +
*userdata[POINTER]
 +
**unformated pointer to carry the user defined structure.
 +
 
 +
''Return Values''
 +
 
 +
*None.
 +
 
 +
----
 +
 
 +
 
 +
<syntaxhighlight lang="c">typedef void (*CORE_DISCONNECT_CALLBACK)(void* userdata);</syntaxhighlight> ''Description''
 +
*define the on disconnect callback function.
 +
 
 +
''Parameters''
 +
 
 +
*userdata[POINTER]
 +
**unformated pointer to carry the user defined structure.
 +
 
 +
''Return Values''
 +
 
 +
*None.
 +
 
 +
----
  
''Description''
 
  
*define the on connected callback function.
+
<syntaxhighlight lang="c">typedef void (*CORE_RENAME_CALLBACK)(const char* name, const int cmdid, const char* sessionid, const char* tenantid, const char* clientid, void* userdata);</syntaxhighlight> ''Description''
 +
*define the rename callback function to handle the rename command received from server.
  
 
''Parameters''
 
''Parameters''
  
*None
+
*name[POINTER]
 +
**new name.
 +
*cmdid[NUMBER]
 +
**received command ID.
 +
*sessionid[POINTER]
 +
**received request session ID.
 +
*tenantid[POINTER]
 +
**the tenant ID string in UUID format: xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx.
 +
*clientid[POINTER]
 +
**the client ID string in UUID format: xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx.
 +
*userdata[POINTER]
 +
**unformated pointer to carry the user defined structure.
  
 
''Return Values''
 
''Return Values''
Line 281: Line 1,046:
  
  
<pre>typedef&nbsp;void (*SACLIENT_LOSTCONNECT_CALLBACK)();</pre>
+
<syntaxhighlight lang="c">typedef void (*CORE_UPDATE_CALLBACK)(const char* loginID, const char* loginPW, const int port, const char* path, const char* md5, const int cmdid, const char* sessionid, const char* tenantid, const char* clientid, void* userdata);</syntaxhighlight> ''Description''
 +
*define the update callback function to handle the update command received from server.
 +
 
 +
''Parameters''
  
''Description''
+
*loginID[POINTER]
 +
**ftp server login account.
 +
*loginPW[POINTER]
 +
**ftp server login password.
 +
*port[NUMBER]
 +
**ftp server listen port.
 +
*path[POINTER]
 +
**ftp download file path.
 +
*md5[POINTER]
 +
**md5 to verify download file.
 +
*cmdid[NUMBER]
 +
**received command ID.
 +
*sessionid[POINTER]
 +
**received request session ID.
 +
*tenantid[POINTER]
 +
**the tenant ID string in UUID format: xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx.
 +
*clientid[POINTER]
 +
**the client ID string in UUID format: xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx.
 +
*userdata[POINTER]
 +
**unformated pointer to carry the user defined structure.
  
*define the on lost connect&nbsp;callback function.
+
''Return Values''
 +
 
 +
*None.
 +
 
 +
----
 +
 
 +
 
 +
<syntaxhighlight lang="c">typedef void (*CORE_SERVER_RECONNECT_CALLBACK)(const char* tenantid, const char* clientid, void* userdata);</syntaxhighlight> ''Description''
 +
*define the server reconnect callback function to handle the received command from server.
  
 
''Parameters''
 
''Parameters''
  
*None
+
*tenantid[POINTER]
 +
**the tenant ID string in UUID format: xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx.
 +
*clientid[POINTER]
 +
**the client ID string in UUID format: xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx.
 +
*userdata[POINTER]
 +
**unformated pointer to carry the user defined structure.
  
 
''Return Values''
 
''Return Values''
Line 298: Line 1,098:
  
  
<pre>typedef&nbsp;void (*SACLIENT_DISCONNECT_CALLBACK)();</pre>
+
<syntaxhighlight lang="c">typedef void (*CORE_GET_CAPABILITY_CALLBACK)(const void *pkt, const long pktlength, const char* tenantid, const char* clientid, void* userdata);</syntaxhighlight> ''Description''
 +
*define the get capability callback function to handle the received command from server.
  
''Description''
+
''Parameters''
  
*define the on disconnect&nbsp;callback function.
+
*pkt[POINTER]
 +
**the received payload in JSON string.
 +
*pktlength[NUMBER]
 +
**the length of received payload.
 +
*tenantid[POINTER]
 +
**the tenant ID string in UUID format: xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx.
 +
*clientid[POINTER]
 +
**the client ID string in UUID format: xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx.
 +
*userdata[POINTER]
 +
**unformated pointer to carry the user defined structure.
 +
 
 +
''Return Values''
 +
 
 +
*None.
 +
 
 +
----
 +
 
 +
 
 +
<syntaxhighlight lang="c">typedef void (*CORE_START_REPORT_CALLBACK)(const void *pkt, const long pktlength, const char* tenantid, const char* clientid, void* userdata);</syntaxhighlight> ''Description''
 +
*define the start report callback function to handle the received command from server.
  
 
''Parameters''
 
''Parameters''
  
*None
+
*pkt[POINTER]
 +
**the received payload in JSON string.
 +
*pktlength[NUMBER]
 +
**the length of received payload.
 +
*tenantid[POINTER]
 +
**the tenant ID string in UUID format: xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx.
 +
*clientid[POINTER]
 +
**the client ID string in UUID format: xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx.
 +
*userdata[POINTER]
 +
**unformated pointer to carry the user defined structure.
  
 
''Return Values''
 
''Return Values''
Line 312: Line 1,141:
 
*None.
 
*None.
  
=== Configuration Structure ===
+
----
<pre>typedef struct {
+
 
/*Connection Mode*/
+
 
char runMode[DEF_RUN_MODE_LENGTH];
+
<syntaxhighlight lang="c">typedef void (*CORE_STOP_REPORT_CALLBACK)(const void *pkt, const long pktlength, const char* tenantid, const char* clientid, void* userdata);</syntaxhighlight> ''Description''
char autoStart[DEF_ENABLE_LENGTH];
+
*define the stop report callback function to handle the received command from server.
 +
 
 +
''Parameters''
  
/*Connection Info*/
+
*pkt[POINTER]
char serverIP[DEF_MAX_STRING_LENGTH];
+
**the received payload in JSON string.
char serverPort[DEF_PORT_LENGTH];
+
*pktlength[NUMBER]
char serverAuth[DEF_USER_PASS_LENGTH];
+
**the length of received payload.
 +
*tenantid[POINTER]
 +
**the tenant ID string in UUID format: xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx.
 +
*clientid[POINTER]
 +
**the client ID string in UUID format: xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx.
 +
*userdata[POINTER]
 +
**unformated pointer to carry the user defined structure.
  
tls_type tlstype;
+
''Return Values''
/*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;</pre>
 
  
''Description''
+
*None.
  
*The structure for agent connect&nbsp;configuration, defined in&nbsp;susiaccess_def.h.
+
----
 +
 
 +
 
 +
<syntaxhighlight lang="c">typedef void (*CORE_QUERY_HEARTBEATRATE_CALLBACK)(const char* sessionid,const char* tenantid,const char* clientid, void* userdata);</syntaxhighlight> ''Description''
 +
*define the query heart beat rate callback function to handle the received command from server.
  
 
''Parameters''
 
''Parameters''
  
*runMode[POINTER]
+
*sessionid[POINTER]
**default is remote.
+
**received request session ID.
**no other mode in WISE Agent version 3.x
+
*tenantid[POINTER]
*autoStart[POINTER]
+
**the tenant ID string in UUID format: xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx.
**The Agent will reconnect to server automatically,&nbsp;default is True.
+
*clientid[POINTER]
*serverIP[POINTER]
+
**the client ID string in UUID format: xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx.
**indicate the server URL or IP Address
+
*userdata[POINTER]
*serverPort[POINTER]
+
**unformated pointer to carry the user defined structure.
**Server (MQTT Broker) listen port,
 
**in WISE Agent version 3.1 or later the&nbsp;default port is 1883
 
**in WISE Agent version 3.0 the&nbsp;default port&nbsp;is 10001.
 
*serverAuth[POINTER]
 
**Server (MQTT Broker) authentication string.
 
**The string is encode from &lt;ID&gt;:&lt;PASS&gt;.
 
**It worked on SSL Mode.
 
*tlstype&nbsp;[NUMBER]
 
**define the TLS (SSL) mode:
 
***tls_type_none
 
***tls_type_tls
 
***tls_type_psk
 
*cafile[POINTER]
 
**the filepath of SSL Certificate Authority&nbsp;file in&nbsp;tls_type_tls mode.
 
*capath[POINTER]
 
**the path of SSL Certificate Authority&nbsp;files in&nbsp;tls_type_tls mode.
 
*certfile[POINTER]
 
**the filepath of SSL Certificate file in&nbsp;tls_type_tls mode.
 
*keyfile[POINTER]
 
**the&nbsp;filepath of SSL Key file in&nbsp;tls_type_tls mode.
 
*cerpasswd[POINTER]
 
**the string of SSL Certificate file password in&nbsp;tls_type_tls mode.
 
*psk[POINTER]
 
**the string of SSL pre-share key in&nbsp;tls_type_psk mode.
 
*identity[POINTER]
 
**the unique string of SSL identity&nbsp;in&nbsp;tls_type_psk mode.
 
*ciphers[POINTER]
 
**the supported cipher list in&nbsp;tls_type_psk mode.
 
  
=== Profile Structure ===
+
''Return Values''
<pre>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*/
+
*None.
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;</pre>
 
  
''Description''
 
  
*The structure for &nbsp;platform description, defined in&nbsp;susiaccess_def.h.
+
<syntaxhighlight lang="c">typedef void (*CORE_UPDATE_HEARTBEATRATE_CALLBACK)(const int heartbeatrate, const char* sessionid, const char* tenantid, const char* clientid, void* userdata);</syntaxhighlight> ''Description''
 +
*define the update heart beat rate callback function to handle the received command from server.
  
 
''Parameters''
 
''Parameters''
  
*version[POINTER]
+
*heartbeatrate[NUMBER]
**The version fo the application.
+
**new heart beat rate in second.
*hostname&nbsp;[POINTER]
+
*sessionid[POINTER]
**The name of target device ro agent.
+
**received request session ID.
*devId[POINTER]
+
*tenantid[POINTER]
**The Unique ID of the target device or agent.
+
**the tenant ID string in UUID format: xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx.
*sn[POINTER]
+
*clientid[POINTER]
**The target&nbsp;device serial number
+
**the client ID string in UUID format: xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx.
*mac[POINTER]
+
*userdata[POINTER]
**the MAC Address of first ethernet or wireless card.
+
**unformated pointer to carry the user defined structure.
*type[POINTER]
+
 
**the agent type, defualt is IPC.
+
''Return Values''
**User can define their own type for customization.
+
 
*produce[POINTER]
+
*None.
**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&nbsp;[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 ===
+
----
<pre>&nbsp;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;</pre>
 
  
''Description''
 
  
*the structure for transmit packet, defined in susiaccess_def.h.
+
<syntaxhighlight lang="c">typedef long long (*CORE_GET_TIME_TICK_CALLBACK)(void* userdata);</syntaxhighlight> ''Description''
 +
*define theget time tick callback function to handle pass the time tick into EI-Agent. EI-Agent cannot get or generate time tick itself.
  
 
''Parameters''
 
''Parameters''
  
*cmd&nbsp;[NUMBER]
+
*userdata[POINTER]
**The command id defined in Plugins (Handlers).
+
**unformated pointer to carry the user defined structure.
*requestID&nbsp;[NUMBER]
+
 
**The unique ID for Plugins (Handlers),
+
''Return Values''
**No used for V3.1 or later version, preserved for V3.0.
+
 
*devId[POINTER]
+
*None.
**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&nbsp;RMM pre-defined header.
 
***pkt_type_custom: customized message packet without wrapped with RMM header.
 
  
 
== Client Sample Code ==
 
== Client Sample Code ==
<pre>#include "stdafx.h"
+
 
#include <SAClient.h>
+
 
#include <Windows.h>
+
<syntaxhighlight lang="c">#include "network.h"
#include <Log.h>
+
#include <stdio.h>
/*agent connected callback function*/
+
#include <string.h>
void on_connect_cb()
+
#include <stdlib.h>
 +
#include <unistd.h>
 +
#include <pthread.h>
 +
#include <time.h>
 +
#include "WISECore.h"
 +
#include "HandlerKernel.h"
 +
#include "util_path.h"
 +
#include "IPSOParser.h"
 +
#include "IoTMessageGenerate.h"
 +
#include "WISEPlatform.h"
 +
 
 +
#define DEF_OSINFO_JSON "{\"content\":{\"cagentVersion\":\"%s\",\"cagentType\":\"%s\",\"osVersion\":\"%s\",\"biosVersion\":\"%s\",\"platformName\":\"%s\",\"processorName\":\"%s\",\"osArch\":\"%s\",\"totalPhysMemKB\":%d,\"macs\":\"%s\",\"IP\":\"%s\"},\"commCmd\":116,\"agentID\":\"%s\",\"handlerName\":\"general\",\"sendTS\":{\"$date\":%lld}}"
 +
 
 +
char g_strClientID[37] = "00000001-0000-0000-0000-305A3A77B1CC";
 +
char g_strTenantID[37] = "general";
 +
char g_strHostName[11] = "TestClient";
 +
char g_strProductTag[37] = "RMM";
 +
 
 +
MSG_CLASSIFY_T* g_pCapability = NULL;
 +
void* g_pHandler = NULL;
 +
//-------------------------Memory leak check define--------------------------------
 +
#ifdef MEM_LEAK_CHECK
 +
#include <crtdbg.h>
 +
_CrtMemState memStateStart, memStateEnd, memStateDiff;
 +
#endif
 +
//---------------------------------------------------------------------------------
 +
void SubscribeRMMTopic();
 +
 
 +
void* threadconnect(void* args)
 
{
 
{
SUSIAccessAgentLog(Normal, "CB_Connected ");
+
char strRecvTopic[256] = {0};
 +
 
 +
core_device_register();
 +
 
 +
printf("CB_Connected \n");
 +
 
 +
SubscribeRMMTopic();
 +
while(true)
 +
{
 +
core_heartbeat_send();
 +
usleep(60000*1000);
 +
}
 +
 
 +
pthread_exit(0);
 +
return NULL;
 
}
 
}
  
/*agent lost connect callback function*/
+
void on_connect_cb(void* userdata)
void on_lost_connect_cb()
 
 
{
 
{
SUSIAccessAgentLog(Normal, "CB_Lostconnect ");
+
pthread_t conn = 0;
 +
if(pthread_create(&conn, NULL, threadconnect, NULL)==0)
 +
pthread_detach(conn);
 
}
 
}
  
/*agent disconnect callback function*/
+
void on_lostconnect_cb(void* userdata)
void on_disconnect_cb()
 
 
{
 
{
SUSIAccessAgentLog(Normal, "CB_Disconnect ");
+
//printf("CB_Lostconnect %s\n", core_error_string_get());
 
}
 
}
  
/*agent received message callback function*/
+
void on_disconnect_cb(void* userdata)
void on_msgrecv(char* topic, susiaccess_packet_body_t *pkt, void *pRev1, void* pRev2)
 
 
{
 
{
/*user can process received command here*/
+
printf("CB_Disconnect \n");
SUSIAccessAgentLog(Normal, "Packet received,&nbsp;%s\r\n", pkt->content);
 
 
}
 
}
  
int main(int argc, char *argv[])
+
/*callback function to handle threshold rule check event*/
 +
void on_threshold_triggered(threshold_event_type type, char* sensorname, double value, MSG_ATTRIBUTE_T* attr, void *pRev)
 +
{
 +
printf(" SampleHandler> threshold triggered:[%d, %s, %f]", type, sensorname, value);
 +
}
 +
 
 +
/*callback function to handle get sensor data event*/
 +
bool on_get_sensor(get_data_t* objlist, void *pRev)
 
{
 
{
int iRet = 0;
+
get_data_t *current = objlist;
char moudlePath[MAX_PATH] = {0};
+
if(objlist == NULL) return false;
+
 
/*agent configuration structure: define how does the agent connect to Server*/
+
while(current)
susiaccess_agent_conf_body_t config;
+
{
 +
current->errcode = STATUSCODE_SUCCESS;
 +
strcpy(current->errstring, STATUS_SUCCESS);
  
/*agent profile structure: define agent platform information*/
+
switch(current->attr->type)
susiaccess_agent_profile_body_t profile;
+
{
 +
case attr_type_numeric:
 +
printf(" SampleHandler> get: %s value:%d", current->sensorname, current->attr->v);
 +
break;
 +
case attr_type_boolean:
 +
printf(" SampleHandler> get: %s value:%s", current->sensorname, current->attr->bv?"true":"false");
 +
break;
 +
case attr_type_string:
 +
printf(" SampleHandler> get: %s value:%s", current->sensorname, current->attr->sv);
 +
break;
 +
case attr_type_date:
 +
printf(" SampleHandler> get: %s value:Date:%s", current->sensorname, current->attr->sv);
 +
break;
 +
case attr_type_timestamp:
 +
printf(" SampleHandler> get: %s value:Timestamp:%d",current->sensorname, current->attr->v);
 +
break;
 +
}
  
memset(moudlePath, 0 , sizeof(moudlePath));
+
current = current->next;
util_module_path_get(moudlePath);
+
}
+
return true;
// Initialize Log Library
+
}
SUSIAccessAgentLogHandle = InitLog(moudlePath);
 
SUSIAccessAgentLog(Normal, "Current path:&nbsp;%s", moudlePath);
 
  
// Pre-set Agent Config struct
+
/*callback function to handle set sensor data event*/
memset(&config, 0 , sizeof(susiaccess_agent_conf_body_t));
+
bool on_set_sensor(set_data_t* objlist, void *pRev)
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.
+
set_data_t *current = objlist;
strcpy(config.serverIP,"dev-wisepaas.eastasia.cloudapp.azure.com"); //serverIP indicate the server URL or IP Address
+
if(objlist == NULL) return false;
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.
+
while(current)
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).
+
current->errcode = STATUSCODE_SUCCESS;
break;
+
strcpy(current->errstring, STATUS_SUCCESS);
case tls_type_tls: //setup TLS with certificate file.
+
 
 +
switch(current->newtype)
 
{
 
{
strcpy(config.cafile, "ca.crt");
+
case attr_type_numeric:
strcpy(config.capath, "");
+
printf(" SampleHandler> set: %s value:%d", current->sensorname, current->v);
strcpy(config.certfile, "server.crt");
+
break;
strcpy(config.keyfile, "server.key");
+
case attr_type_boolean:
strcpy(config.cerpasswd, "123456");
+
printf(" SampleHandler> set: %s value:%s", current->sensorname, current->bv?"true":"false");
 +
break;
 +
case attr_type_string:
 +
printf(" SampleHandler> set: %s value:%s", current->sensorname, current->sv);
 +
break;
 
}
 
}
break;
+
 
case tls_type_psk: //setup TLS with pre share key.
+
current = current->next;
 +
}
 +
 
 +
return true;
 +
}
 +
 
 +
void on_msgrecv(const char* topic, const void *pkt, const long pktlength, void* userdata)
 +
{
 +
int cmdID = 0;
 +
char sessionID[32] = {0};
 +
 
 +
printf("Packet received:\n [%s],\n %s\n", topic, pkt);
 +
/* All messages received from subscribed topics will trigger this callback function.
 +
* topic: received topic.
 +
* pkt: received message in json string.
 +
* pktlength: received message length.
 +
*/
 +
 
 +
if(g_pHandler)
 +
{
 +
/*Parse Received Command*/
 +
if(HandlerKernelEx_ParseRecvCMDWithSessionID((char*)pkt, &cmdID, sessionID) != handler_success)
 +
return;
 +
switch(cmdID)
 
{
 
{
strcpy(config.psk, "");
+
case hk_get_capability_req:
strcpy(config.identity, "SAClientSample");
+
if(g_pCapability)
strcpy(config.ciphers, "");
+
{
 +
HandlerKernelEx_LockCapability(g_pHandler);
 +
HandlerKernelEx_SetCapability(g_pHandler, g_pCapability, true);
 +
HandlerKernelEx_UnlockCapability(g_pHandler);
 +
}
 +
break;
 +
case hk_auto_upload_req:
 +
/*start live report*/
 +
HandlerKernelEx_LiveReportStart(g_pHandler, hk_auto_upload_rep, (char*)pkt);
 +
break;
 +
case hk_set_thr_req:
 +
/*Stop threshold check thread*/
 +
HandlerKernelEx_StopThresholdCheck(g_pHandler);
 +
/*setup threshold rule*/
 +
HandlerKernelEx_SetThreshold(g_pHandler, hk_set_thr_rep,(char*) pkt);
 +
/*register the threshold check callback function to handle trigger event*/
 +
HandlerKernelEx_SetThresholdTrigger(g_pHandler, on_threshold_triggered);
 +
/*Restart threshold check thread*/
 +
HandlerKernelEx_StartThresholdCheck(g_pHandler);
 +
break;
 +
case hk_del_thr_req:
 +
/*Stop threshold check thread*/
 +
HandlerKernelEx_StopThresholdCheck(g_pHandler);
 +
/*clear threshold check callback function*/
 +
HandlerKernelEx_SetThresholdTrigger(g_pHandler, NULL);
 +
/*Delete all threshold rules*/
 +
HandlerKernelEx_DeleteAllThreshold(g_pHandler, hk_del_thr_rep);
 +
break;
 +
case hk_get_sensors_data_req:
 +
/*Get Sensor Data with callback function*/
 +
HandlerKernelEx_GetSensorData(g_pHandler, hk_get_sensors_data_rep, sessionID, (char*)pkt, on_get_sensor);
 +
break;
 +
case hk_set_sensors_data_req:
 +
/*Set Sensor Data with callback function*/
 +
HandlerKernelEx_SetSensorData(g_pHandler, hk_set_sensors_data_rep, sessionID, (char*)pkt, on_set_sensor);
 +
break;
 +
default:
 +
{
 +
/* Send command not support reply message*/
 +
char topic[128] = {0};
 +
char repMsg[32] = {0};
 +
int len = 0;
 +
sprintf( repMsg, "{\"errorRep\":\"Unknown cmd!\"}" );
 +
len= strlen( "{\"errorRep\":\"Unknown cmd!\"}" ) ;
 +
sprintf(topic, DEF_AGENTACT_TOPIC, g_strTenantID, g_strProductTag, g_strClientID);
 +
core_publish(topic, repMsg, len, 0, 0);
 +
}
 +
break;
 
}
 
}
break;
 
 
}
 
}
 +
}
 +
 +
void on_rename(const char* name, const int cmdid, const char* sessionid, const char* tenantid, const char* devid, void* userdata)
 +
{
 +
printf("rename to: %s\n", name);
 +
 +
core_action_response(cmdid, sessionid, true, tenantid, devid);
 +
return;
 +
}
 +
 +
void on_update(const char* loginID, const char* loginPW, const int port, const char* path, const char* md5, const int cmdid, const char* sessionid, const char* tenantid, const char* devid, void* userdata)
 +
{
 +
printf("Update: %s, %s, %d, %s, %s\n", loginID, loginPW, port, path, md5);
  
// Pre-set Agent Profile struct
+
core_action_response(cmdid, sessionid, true, tenantid, devid);
memset(&profile, 0 , sizeof(susiaccess_agent_profile_body_t));
+
return;
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.
 
  
 +
void on_server_reconnect(const char* tenantid, const char* devid, void* userdata)
 +
{
 +
if(!strcmp(g_strClientID, devid))
 +
core_device_register();
 +
/*TODO: resend whole capability*/
 +
}
  
/*Initialize SAClient with Agent Configure and Profile structure, and the Log File Handle*/
+
bool SendOSInfo();
iRet = saclient_initialize(&config, &profile, SUSIAccessAgentLogHandle);
 
  
if(iRet&nbsp;!= saclient_success)
+
void* threadgetcapab(void* args)
 +
{
 +
SendOSInfo();
 +
 
 +
if(g_pHandler)
 
{
 
{
SUSIAccessAgentLog(Error, "Unable to initialize AgentCore.");
+
HandlerKernelEx_LockCapability(g_pHandler);
goto EXIT;
+
HandlerKernelEx_SetCapability(g_pHandler, g_pCapability, true);
 +
HandlerKernelEx_UnlockCapability(g_pHandler);
 +
}
 +
 
 +
printf("on_get_capability \n");
 +
pthread_exit(0);
 +
return NULL;
 +
}
 +
 
 +
void on_get_capability(const void *pkt, const long pktlength, const char* tenantid, const char* devid, void* userdata)
 +
{
 +
pthread_t getcapab = 0;
 +
if(pthread_create(&getcapab, NULL, threadgetcapab, NULL)==0)
 +
pthread_detach(getcapab);
 +
/*TODO: send whole capability*/
 +
}
 +
 
 +
void on_start_report(const void *pkt, const long pktlength, const char* tenantid, const char* devid, void* userdata)
 +
{
 +
/*TODO: start report sensor data*/
 +
if(g_pHandler)
 +
{
 +
HandlerKernelEx_AutoReportStart(g_pHandler, pkt);
 +
}
 +
}
 +
 
 +
void on_stop_report(const void *pkt, const long pktlength, const char* tenantid, const char* devid, void* userdata)
 +
{
 +
/*TODO: stop report sensor data*/
 +
if(g_pHandler)
 +
{
 +
HandlerKernelEx_AutoReportStop(g_pHandler, pkt);
 
}
 
}
 +
}
 +
 +
void on_heartbeatrate_query(const char* sessionid,const char* tenantid,const char* devid, void* userdata)
 +
{
 +
core_heartbeatratequery_response(60,sessionid, tenantid, devid);
 +
}
 +
 +
#ifdef WIN32
 +
#include "sys/time.h"
 +
int gettimeofday(struct timeval *tv, struct timezone *tz)
 +
{
 +
    time_t clock;
 +
    struct tm tm;
 +
    SYSTEMTIME wtm;
 +
 +
    GetLocalTime(&wtm);
 +
    tm.tm_year    = wtm.wYear - 1900;
 +
    tm.tm_mon    = wtm.wMonth - 1;
 +
    tm.tm_mday    = wtm.wDay;
 +
    tm.tm_hour    = wtm.wHour;
 +
    tm.tm_min    = wtm.wMinute;
 +
    tm.tm_sec    = wtm.wSecond;
 +
    tm. tm_isdst    = -1;
 +
    clock = mktime(&tm);
 +
    tv->tv_sec = (long)clock;
 +
    tv->tv_usec = wtm.wMilliseconds * 1000;
 +
 +
    return (0);
 +
}
 +
#endif
  
SUSIAccessAgentLog(Normal, "Agent Initialized");
+
long long get_timetick(void* userdata)
 +
{
 +
long long tick = 0;
 +
struct timeval tv;
 +
gettimeofday(&tv, NULL);
 +
tick = (long long)tv.tv_sec*1000 + (long long)tv.tv_usec/1000;
 +
return tick;
 +
}
  
/*register the conect, lost connect and disconnect callback function*/
+
void on_heartbeatrate_update(const int heartbeatrate, const char* sessionid, const char* tenantid, const char* devid, void* userdata)
saclient_connection_callback_set(on_connect_cb, on_disconnect_cb, on_disconnect_cb);
+
{
 +
printf("Heartbeat Rate Update: %d, %s, %s\n", heartbeatrate, sessionid, devid);
  
SUSIAccessAgentLog(Normal, "Agent Set Callback");
+
core_action_response(130/*wise_heartbeatrate_update_rep*/, sessionid, true, tenantid, devid);
 +
return;
 +
}
 +
 
 +
AGENT_SEND_STATUS send_cbf(HANDLE const handler, int enum_act, void const * const requestData, unsigned int const requestLen, void *pRev1, void* pRev2 )
 +
{
 +
char* buff = NULL;
 +
char topic[128] = {0};
 +
HANDLER_INFO_EX* pHandler = NULL;
 +
bool bResult = false;
 +
int length = 0;
 +
if(handler == NULL || requestData == NULL)
 +
return cagent_send_data_error;
 +
pHandler = (HANDLER_INFO_EX*)handler;
 
 
/*start connect to server, server is defined in agent config*/
+
length =  strlen(DEF_ACTION_RESPONSE_JSON) + requestLen + 12 + strlen(pHandler->Name);
iRet = saclient_connect();
+
buff = calloc(1,length);
 +
snprintf(buff, length, DEF_ACTION_RESPONSE_JSON, enum_act, pHandler->Name, (char*)requestData, get_timetick(NULL));
 +
 
 +
sprintf(topic, DEF_AGENTACT_TOPIC, pHandler->agentInfo->tenantId, g_strProductTag, pHandler->agentInfo->devId);
 +
 
 +
bResult = core_publish(topic, buff, strlen(buff), 0, 0);
 +
 
 +
free(buff);
 +
if(bResult)
 +
return cagent_success;
 +
else
 +
return cagent_send_data_error;
 +
}
 +
 
 +
 
 +
AGENT_SEND_STATUS send_capability_cbf( HANDLE const handler, void const * const requestData, unsigned int const requestLen, void *pRev1, void* pRev2 )
 +
{
 +
 
 +
MSG_CLASSIFY_T* root = NULL;
 +
HANDLER_INFO_EX* pHandler = NULL;
 +
if(handler == NULL || requestData == NULL)
 +
return cagent_send_data_error;
 +
pHandler = (HANDLER_INFO_EX*)handler;
 +
root = IoT_CreateRoot(pHandler->Name);
 +
if(transfer_parse_ipso((char*)requestData,  root))
 +
{
 +
char topic[128] = {0};
 +
char* buff = IoT_PrintFullCapability(root, pHandler->agentInfo->devId);
 +
sprintf(topic, DEF_AGENTACT_TOPIC, pHandler->agentInfo->tenantId, g_strProductTag, pHandler->agentInfo->devId);
 +
if(core_publish(topic, buff, strlen(buff), 0, 0))
 +
return cagent_success;
 +
else
 +
{
 +
 
 +
return cagent_send_data_error;
 +
}
 +
}
 +
return cagent_send_data_error;
 +
}
 +
 
 +
AGENT_SEND_STATUS send_autoreport_cbf( HANDLE const handler, void const * const requestData, unsigned int const requestLen, void *pRev1, void* pRev2 )
 +
{
 +
char* buff = NULL;
 +
char topic[128] = {0};
 +
HANDLER_INFO_EX* pHandler = NULL;
 +
bool bResult = false;
 +
int length = 0;
 +
if(handler == NULL || requestData == NULL)
 +
return cagent_send_data_error;
 +
pHandler = (HANDLER_INFO_EX*)handler;
 +
length =  strlen(DEF_ACTION_RESPONSE_JSON) + requestLen + 12 + strlen(pHandler->Name);
 +
buff = calloc(1,length);
 +
snprintf(buff, length, DEF_ACTION_RESPONSE_JSON, 2055, "general", (char*)requestData, get_timetick(NULL));
 +
sprintf(topic, DEF_AGENTREPORT_TOPIC, pHandler->agentInfo->tenantId, pHandler->agentInfo->devId);
 +
 
 +
bResult = core_publish(topic, buff, strlen(buff), 0, 0);
 +
 
 +
free(buff);
 +
if(bResult)
 +
return cagent_success;
 +
else
 +
return cagent_send_data_error;
 +
}
 +
 
 +
AGENT_SEND_STATUS  send_event_cbf( HANDLE const handler, HANDLER_NOTIFY_SEVERITY severity, void const * const requestData, unsigned int const requestLen, void *pRev1, void* pRev2 )
 +
{
 +
char* buff = NULL;
 +
char topic[128] = {0};
 +
HANDLER_INFO_EX* pHandler = NULL;
 +
bool bResult = false;
 +
int length = 0;
 +
if(handler == NULL || requestData == NULL)
 +
return cagent_send_data_error;
 +
pHandler = (HANDLER_INFO_EX*)handler;
 +
length =  strlen(DEF_ACTION_RESPONSE_JSON) + requestLen + 12 + strlen(pHandler->Name);
 +
buff = calloc(1,length);
 +
snprintf(buff, length, DEF_ACTION_RESPONSE_JSON, 2059, pHandler->Name, (char*)requestData, get_timetick(NULL));
 +
sprintf(topic, DEF_EVENTNOTIFY_TOPIC, pHandler->agentInfo->tenantId, g_strProductTag, pHandler->agentInfo->devId);
 +
 
 +
bResult = core_publish(topic, buff, strlen(buff), 0, 0);
 +
 
 +
free(buff);
 +
if(bResult)
 +
return cagent_success;
 +
else
 +
return cagent_send_data_error;
 +
}
 +
 
 +
MSG_CLASSIFY_T* LoadCapability(char* path)
 +
{
 +
int size = 0;
 +
char* buff = NULL;
 +
char handler[256] = {0};
 +
MSG_CLASSIFY_T* root = NULL;
 +
size = util_file_size_get(path);
 +
buff = calloc(1, size+1);
 +
if(buff == NULL)
 +
return root;
 +
if(util_file_read(path, buff, size)==0)
 +
return root;
 +
if(!transfer_get_ipso_handlername(buff, handler))
 +
return root;
 +
root = IoT_CreateRoot(handler);
 +
transfer_parse_ipso(buff, root);
 +
free(buff);
 +
return root;
 +
}
 +
 
 +
void* CreateSampleHandler(cagent_agent_info_body_t* agentinfo)
 +
{
 +
void* pHandler = NULL;
 +
HANDLER_INFO_EX myhandler;
 +
memset(&myhandler, 0, sizeof(HANDLER_INFO_EX));
 +
strcpy(myhandler.Name, "SUSIControl");
 +
myhandler.sendcbf = send_cbf;
 +
myhandler.sendcapabilitycbf = send_capability_cbf;
 +
myhandler.sendreportcbf = send_autoreport_cbf;
 +
myhandler.sendeventcbf = send_event_cbf;
 +
myhandler.agentInfo = calloc(1, sizeof(cagent_agent_info_body_t));
 +
memcpy(myhandler.agentInfo, agentinfo, sizeof(cagent_agent_info_body_t));
 +
 
 +
pHandler = HandlerKernelEx_Initialize((HANDLER_INFO*)&myhandler);
 +
g_pCapability = LoadCapability("capability.txt");
 +
if(g_pCapability != NULL)
 +
HandlerKernelEx_SetCapability(pHandler, g_pCapability,false);
 +
printf("Create Sample Handler\n");
 +
return pHandler;
 +
}
 +
 
 +
void ReleaseSampleHandler(void* phandler)
 +
{
 +
HandlerKernelEx_Uninitialize(phandler);
 +
}
 +
 
 +
void SubscribeRMMTopic()
 +
{
 +
char topic[256] = {0};
 +
sprintf(topic, DEF_CALLBACKREQ_TOPIC, g_strTenantID, g_strProductTag, g_strClientID);
 +
 
 +
core_subscribe(topic, 0);
 +
}
 +
 
 +
void CreateAgentInfo(cagent_agent_info_body_t* agentinfo)
 +
{
 +
if(agentinfo!= NULL)
 +
{
 +
strcpy(agentinfo->hostname, g_strHostName);
 +
strcpy(agentinfo->devId, g_strClientID);
 +
strcpy(agentinfo->tenantId, g_strTenantID);
 +
strcpy(agentinfo->sn, "305A3A77B1CC");
 +
strcpy(agentinfo->mac, "305A3A77B1CC");
 +
strcpy(agentinfo->version, "4.0.0");
 +
strcpy(agentinfo->type, "IPC");
 +
strcpy(agentinfo->product, "test");
 +
strcpy(agentinfo->manufacture, "test");
 +
agentinfo->status = 0;
 +
}
 +
}
 +
 
 +
void UpdateData(char* path, MSG_CLASSIFY_T* root)
 +
{
 +
int size = 0;
 +
char* buff = NULL;
 +
char handler[256] = {0};
 +
if(root == NULL)
 +
return;
 +
 
 +
size = util_file_size_get(path);
 +
buff = calloc(1, size+1);
 +
if(buff == NULL)
 +
return;
 +
if(util_file_read(path, buff, size)==0)
 +
return;
 +
if(!transfer_get_ipso_handlername(buff, handler))
 +
return;
 +
transfer_parse_ipso(buff, root);
 +
free(buff);
 +
}
 +
 
 +
void* threadaccessdata(void* args)
 +
{
 +
while(true)
 +
{
 +
HandlerKernelEx_LockCapability(g_pHandler);
 +
UpdateData("capability.txt", g_pCapability);
 +
HandlerKernelEx_UnlockCapability(g_pHandler);
 +
usleep(1000*1000);
 +
}
 +
pthread_exit(0);
 +
return NULL;
 +
}
 +
 
 +
pthread_t StartAccessData()
 +
{
 +
pthread_t thread = 0;
 +
if(pthread_create(&thread, NULL, threadaccessdata, NULL)!=0)
 +
thread = 0;
 +
return thread;
 +
}
  
if(iRet&nbsp;!= saclient_success){
+
void StopAccessData(pthread_t thread)
SUSIAccessAgentLog(Error, "sampleagent Unable to connect to broker.");
+
{
goto EXIT;
+
if(thread != 0)
} else {
+
{
SUSIAccessAgentLog(Normal, "sampleagent Connect to broker:&nbsp;%s", config.serverIP);
+
pthread_cancel(thread);
 +
pthread_join(thread, NULL);
 
}
 
}
 +
}
 +
 +
bool SendOSInfo()
 +
{
 +
long long tick = 0;
 +
char strPayloadBuff[2048] = {0};
 +
char localip[16] = {0};
 +
char strTopicBuff[256] = {0};
 +
tick = get_timetick(NULL);
 +
 
 
 +
core_address_get(localip);
 +
 +
snprintf(strPayloadBuff, sizeof(strPayloadBuff), DEF_OSINFO_JSON, "4.0.0",
 +
"IPC",
 +
"Windows 8",
 +
"V1.2",
 +
"SOM-111",
 +
"Intel(R) Atom(TM) CPU D525  @ 1.8077GHz",
 +
"X86",
 +
2048,
 +
"305A3A77B1DA",
 +
localip,
 +
g_strClientID,
 +
tick);
 +
 +
#ifdef _WISEPAAS_02_DEF_H_
 +
sprintf(strTopicBuff, DEF_AGENTACT_TOPIC, g_strTenantID, g_strProductTag, g_strClientID);
 +
#else
 +
sprintf(strTopicBuff, DEF_AGENTACT_TOPIC, pHandle->strClientID);
 +
#endif
 +
 +
return core_publish(strTopicBuff, strPayloadBuff, strlen(strPayloadBuff), 0, 0);
 +
}
 +
 +
int main(int argc, char *argv[])
 +
{
 +
//char strServerIP[64] = "dev-wisepaas.eastasia.cloudapp.azure.com";
 +
char strServerIP[64] = "172.22.12.29";
 +
int iPort = 1883;
 +
pthread_t threaddataaccess = 0;
 +
int SSLMode = 0;  //0:disable, 1:CA Mode, 2: PSK Mode.
 +
cagent_agent_info_body_t agentinfo;
 +
#ifdef MEM_LEAK_CHECK
 +
_CrtSetDbgFlag ( _CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF );
 +
_CrtMemCheckpoint( &memStateStart);
 +
#endif
 +
CreateAgentInfo(&agentinfo);
 +
 +
g_pHandler = CreateSampleHandler(&agentinfo);
 +
 +
 +
threaddataaccess = StartAccessData();
 +
 +
if(!core_initialize(g_strTenantID, g_strClientID, g_strHostName, agentinfo.mac, &agentinfo))
 
{
 
{
+
printf("Unable to initialize AgentCore.\n");
char topicStr[128] = {0};
+
goto EXIT;
susiaccess_packet_body_t pkt;
+
}
 +
printf("Agent Initialized\n");
 +
 
 +
core_connection_callback_set(on_connect_cb, on_lostconnect_cb, on_disconnect_cb, on_msgrecv);
 +
 
 +
core_action_callback_set(on_rename, on_update);
 +
 
 +
core_server_reconnect_callback_set(on_server_reconnect);
 +
 
 +
core_iot_callback_set(on_get_capability, on_start_report, on_stop_report);
 +
 
 +
core_time_tick_callback_set(get_timetick);
 +
 
 +
core_heartbeat_callback_set(on_heartbeatrate_query, on_heartbeatrate_update);
 +
 
 +
core_tag_set(g_strProductTag);
 +
 
 +
core_product_info_set(agentinfo.sn, NULL, agentinfo.version, agentinfo.type, agentinfo.product, agentinfo.manufacture);
 +
 
 +
if(SSLMode == 1)
 +
core_tls_set( "server.crt", NULL, "ca.crt", "ca.key", "05155853");
 +
else if(SSLMode == 2)
 +
core_tls_psk_set("05155853", g_strClientID, NULL);
  
/* Add  subscribe topic Callback*/
+
if(!core_connect(strServerIP, iPort, "admin", "05155853")){
sprintf(topicStr, "/cagent/admin/%s/testreq", profile.devId);
+
printf("Unable to connect to broker. %s\n", core_error_string_get());
saclient_subscribe(topicStr, 0, on_msgrecv);
+
goto EXIT;
+
} else {
/*Send test packet to specific topic*/
+
printf("Connect to broker: %s\n", strServerIP);
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:
 
EXIT:
printf("Click enter to exit");
+
printf("Click enter to exit\n");
 
fgetc(stdin);
 
fgetc(stdin);
  
/*disconnect from server*/
+
StopAccessData(threaddataaccess);
saclient_disconnect();
 
SUSIAccessAgentLog(Normal, "Send Client Info: disconnect");
 
/*release SAClient resource*/
 
saclient_uninitialize();
 
SUSIAccessAgentLog(Normal, "Agent Uninitialize");
 
/*release log resource*/
 
UninitLog(SUSIAccessAgentLogHandle);
 
  
return iRet;
+
ReleaseSampleHandler(g_pHandler);
}</pre>
+
 
 +
core_disconnect(true);
 +
printf("Send Client Info: disconnect\n");
 +
core_uninitialize();
 +
#ifdef MEM_LEAK_CHECK
 +
_CrtMemCheckpoint( &memStateEnd );
 +
if ( _CrtMemDifference( &memStateDiff, &memStateStart, &memStateEnd) )
 +
_CrtMemDumpStatistics( &memStateDiff );
 +
#endif
 +
 
 +
return 0;
 +
}
 +
</syntaxhighlight>

Latest revision as of 04:43, 1 June 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 release 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 target device connect to server through an EIS or Gateway device.
  • strVersion[POINTER]
    • the application version string.
  • strType[POINTER]
    • the application 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))
    {
        printf("Unable to initialize WISECore.\n");
        goto EXIT;
    }
    printf("Agent Initialized\n");
    /*Setup device identify information*/
    core_product_info_set("305A3A77B1CC", NULL/*no parent ID*/, "2.0.1", "IPC", "test", "test"); 
    /*Setup support function tag*/
    core_tag_set("RMM");
    /*binding to a specific account*/
    core_account_bind("admin","GP25qY7TjJA=");
EXIT:
    /*Release WISECore*/
    core_uninitialize();
    return iRet;
}


bool core_tls_set(const char *cafile, const char *capath, const char *certfile, const char *keyfile, const char *password);
Description
  • Configure the client for certificate based SSL/TLS support. Must be called before <core_connect>.
  • Cannot be used in conjunction with <core_tls_psk_set>.
  • Define the Certificate Authority certificates to be trusted (ie. the server certificate must be signed with one of these certificates) using cafile. If the server you are connecting to requires clients to provide a certificate, define certfile and keyfile with your client certificate and private key. If your private key is encrypted, provide a password callback 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 be NULL.
  • certfile[POINTER]
    • path to a file containing the PEM encoded certificate file for this client.
    • If NULL, keyfile must also be NULL and no 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 to pass the correct password for decryption.
    • 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))
    {
        printf("Unable to initialize WISECore.\n");
        goto EXIT;
    }
    printf("Agent Initialized\n");
    /*Setup TLS*/
    core_tls_set( "server.crt", NULL, "ca.crt", "ca.key", "123456");
    /*Connect to Server*/
    core_connect("127.0.0.1",1883,"admin","123456");

    /*Disconnect*/
    core_disconnect(false);

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


bool core_tls_psk_set(const char *psk, const char *identity, const char *ciphers); 
Description
  • Configure the client for pre-shared-key based TLS support. Must be called before <wc_connect>.
  • Cannot be used in conjunction with <core_tls_set>.

Parameters

  • psk [POINTER]
    • the pre-shared-key in hex format with no leading "0x".
  • identity[POINTER]
    • the identity of this client. May be used as the username depending on the server settings.
  • ciphers[POINTER]
    • a string describing the PSK ciphers available for use. See the "openssl ciphers" tool for more information.
    • If NULL, the default ciphers will be used.

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))
    {
        printf("Unable to initialize WISECore.\n");
        goto EXIT;
    }
    printf("Agent Initialized\n");
    /*Setup PSK*/
    core_tls_psk_set("05155853", "00000001-0000-0000-0000-305A3A77B1CC", NULL);
    /*Connect to Server*/
    core_connect("127.0.0.1",1883,"admin","123456");

    /*Disconnect*/
    core_disconnect(false);

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


bool core_connect(char* strServerIP, int iServerPort, char* strConnID, char* strConnPW);
Description
  • Connect to server that defined in Configuration data of lite_initialize parameters.

Parameters

  • strServerIP[POINTER]
    • remote server URL or IP address.
  • iServerPort[NUMBER]
    • connection protocol listen port.
  • strConnID[POINTER]
    • connection protocol access id
  • strConnPW[POINTER]
    • connection protocol access password

Return Values

  • true/false

Example

Reference to core_tls_set().



void core_disconnect(bool bForce);
Description
  • Disconnect from server.

Parameters

  • bForce[BOOLEAN]
    • Is force to disconnect.

Return Values

  • None

Example

Reference to core_tls_set().



bool core_connection_callback_set(CORE_CONNECTED_CALLBACK on_connect, CORE_LOSTCONNECTED_CALLBACK on_lostconnect, CORE_DISCONNECT_CALLBACK on_disconnect, CORE_MESSAGE_RECV_CALLBACK on_msg_recv);
Description
  • Register the callback function to handle the connection event.

Parameters

  • on_connect[POINTER]
    • Function Pointer to handle connect success event.
  • on_lost_connect[POINTER]
    • Function Pointer to handle lost connect event.
    • The SAClient will reconnect automatically, if left as NULL.
  • on_disconnect[POINTER]
    • Function Pointer to handle disconnect event.
  • on_msg_recv[POINTER]
    • Function Pointer to handle message receive event.

Return Values

  • true/false

Example

#include "WISECore.h"
void on_connect_cb(void* userdata)
{
    printf("CB_Connected \n");
    /*Send device register message.*/
    core_device_register(); 
}

void on_lostconnect_cb(void* userdata)
{
    printf("CB_Lostconnect %s\n", core_error_string_get());
}

void on_disconnect_cb(void* userdata)
{
    printf("CB_Disconnect \n");
}

void on_msgrecv(const char* topic, const void *pkt, const long pktlength, void* userdata)
{
    printf("Packet received:\n [%s],\n %s\n", topic, pkt);
}

int main (int argc, char *argv[]) 
{
    int iRet = 0; /*Initialize WISECore*/     if(!core_initialize("general", "00000001-0000-0000-0000-305A3A77B1CC", "TestClient", "305A3A77B1CC", NULL))
    {
        printf("Unable to initialize WISECore.\n");
        goto EXIT;
    }
    printf("Agent Initialized\n");
    /*Setup connection callback function*/
    core_connection_callback_set(on_connect_cb, on_lostconnect_cb, on_disconnect_cb, on_msgrecv);

    /*Connect to Server*/
    core_connect("127.0.0.1",1883,"admin","123456");

    /*Disconnect*/
    core_disconnect(false);

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


bool core_action_callback_set(CORE_RENAME_CALLBACK on_rename, CORE_UPDATE_CALLBACK on_update);
Description
  • Register the callback function to handle the action event.

Parameters

  • on_rename[POINTER]
    • Function Pointer to handle rename event.
  • on_update[POINTER]
    • Function Pointer to handle update event.

Return Values

  • true/false

Example

#include "WISECore.h"
void on_rename(const char* name, const int cmdid, const char* sessionid, const char* tenantid, const char* devid, void* userdata)
{
    printf("rename to: %s\n", name);
    /*Send action response*/
    core_action_response(cmdid, sessionid, true, tenantid, devid);
    return;
}

void on_update(const char* loginID, const char* loginPW, const int port, const char* path, const char* md5, const int cmdid, const char* sessionid, const char* tenantid, const char* devid, void* userdata)
{
    printf("Update: %s, %s, %d, %s, %s\n", loginID, loginPW, port, path, md5);
    /*Send action response*/
    core_action_response(cmdid, sessionid, true, tenantid, devid);
    return;
}

int main (int argc, char *argv[]) 
{
    int iRet = 0; /*Initialize WISECore*/     if(!core_initialize("general", "00000001-0000-0000-0000-305A3A77B1CC", "TestClient", "305A3A77B1CC", NULL))
    {
        printf("Unable to initialize WISECore.\n");
        goto EXIT;
    }
    printf("Agent Initialized\n");
    /*Setup action request callback function*/
    core_action_callback_set(on_rename, on_update);

    /*Connect to Server*/
    core_connect("127.0.0.1",1883,"admin","123456");

    /*Disconnect*/
    core_disconnect(false);

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


bool core_action_response(const int cmdid, const char * sessoinid, bool success, const char* tenantid, const char* devid);
Description
  • Send rename, update or heartbeat rate update action response back to server.

Parameters

  • cmdid[NUMBER]
    • command ID of request action.
  • sessionid[POINTER]
    • session ID of request action.
  • success[BOOLEAN]
    • result of request action.
  • tenantid[POINTER]
    • tenant ID of request device.
  • devid[POINTER]
    • device ID of request device.

Return Values

  • true/false

Example

Reference to core_action_callback_set().



bool core_server_reconnect_callback_set(CORE_SERVER_RECONNECT_CALLBACK on_server_reconnect);
Description
  • Register the callback function to handle the server reconnect event.

Parameters

  • on_server_reconnect[POINTER]
    • Function Pointer to handle server reconnect event.

Return Values

  • true/false

Example

#include "WISECore.h"
void on_server_reconnect(const char* tenantid, const char* devid, void* userdata)
{
    /*Send device register message again.*/
    core_device_register(); 
}

int main (int argc, char *argv[]) 
{
    int iRet = 0; /*Initialize WISECore*/     if(!core_initialize("general", "00000001-0000-0000-0000-305A3A77B1CC", "TestClient", "305A3A77B1CC", NULL))
    {
        printf("Unable to initialize WISECore.\n");
        goto EXIT;
    }
    printf("Agent Initialized\n");
    /*Setup reconnect request callback function*/
    core_server_reconnect_callback_set(on_server_reconnect);

    /*Connect to Server*/
    core_connect("127.0.0.1",1883,"admin","123456");

    /*Disconnect*/
    core_disconnect(false);

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


bool core_iot_callback_set(CORE_GET_CAPABILITY_CALLBACK on_get_capability, CORE_START_REPORT_CALLBACK on_start_report, CORE_STOP_REPORT_CALLBACK on_stop_report);
Description
  • Register the callback function to handle the get IoT capability or start/stop report sensor data.

Parameters

  • on_get_capability[POINTER]
    • Function Pointer to handle get capability event.
  • on_start_report[POINTER]
    • Function Pointer to handle start report event.
  • on_stop_report[POINTER]
    • Function Pointer to handle stop report event.

Return Values

  • true/false

Example

#include "WISECore.h"
void on_get_capability(const void *pkt, const long pktlength, const char* tenantid, const char* devid, void* userdata)
{
    printf("on_get_capabiltenanted\n");
    /*TODO: send whole capability*/
}

void on_start_report(const void *pkt, const long pktlength, const char* tenantid, const char* devid, void* userdata)
{
    /*TODO: start report sensor data*/
    printf("on_start_report\n");
}

void on_stop_report(const void *pkt, const long pktlength, const char* tenantid, const char* devid, void* userdata)
{
    /*TODO: stop report sensor data*/
    printf("on_stop_report\n");
}

int main (int argc, char *argv[]) 
{
    int iRet = 0; /*Initialize WISECore*/     if(!core_initialize("general", "00000001-0000-0000-0000-305A3A77B1CC", "TestClient", "305A3A77B1CC", NULL))
    {
        printf("Unable to initialize WISECore.\n");
        goto EXIT;
    }
    printf("Agent Initialized\n");
    /*Setup iot command callback function*/
    core_iot_callback_set(on_get_capability, on_start_report, on_stop_report);

    /*Connect to Server*/
    core_connect("127.0.0.1",1883,"admin","123456");

    /*Disconnect*/
    core_disconnect(false);

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


bool core_time_tick_callback_set(CORE_GET_TIME_TICK_CALLBACK get_time_tick);
Description
  • Register the callback function to assign time tick.

Parameters

  • get_time_tick[POINTER]
    • Function Pointer to assign current timestamp in millisecond.

Return Values

  • true/false

Example

#include "WISECore.h"
#ifdef WIN32
#include "sys/time.h"
int gettimeofday(struct timeval *tv, struct timezone *tz)
{
    time_t clock;
    struct tm tm;
    SYSTEMTIME wtm;
 
    GetLocalTime(&wtm);
    tm.tm_year     = wtm.wYear - 1900;
    tm.tm_mon     = wtm.wMonth - 1;
    tm.tm_mday     = wtm.wDay;
    tm.tm_hour     = wtm.wHour;
    tm.tm_min     = wtm.wMinute;
    tm.tm_sec     = wtm.wSecond;
    tm. tm_isdst    = -1;
    clock = mktime(&tm);
    tv->tv_sec = (long)clock;
    tv->tv_usec = wtm.wMilliseconds * 1000;
 
    return (0);
}
#endif

long long get_timetick(void* userdata)
{
	long long tick = 0;
	struct timeval tv;
	gettimeofday(&tv, NULL);
	tick = (long long)tv.tv_sec*1000 + (long long)tv.tv_usec/1000;
	return tick;
}

int main (int argc, char *argv[]) 
{
    int iRet = 0; /*Initialize WISECore*/     if(!core_initialize("general", "00000001-0000-0000-0000-305A3A77B1CC", "TestClient", "305A3A77B1CC", NULL))
    {
        printf("Unable to initialize WISECore.\n");
        goto EXIT;
    }
    printf("Agent Initialized\n");
    /*Setup time tick callback function*/
    core_time_tick_callback_set(get_timetick);

    /*Connect to Server*/
    core_connect("127.0.0.1",1883,"admin","123456");

    /*Disconnect*/
    core_disconnect(false);

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


bool core_heartbeat_callback_set(CORE_QUERY_HEARTBEATRATE_CALLBACK on_query_heartbeatrate, CORE_UPDATE_HEARTBEATRATE_CALLBACK on_update_heartbeatrate);
Description
  • Register the callback function to handle the heartbeat rate query and update command.

Parameters

  • on_query_heartbeatrate[POINTER]
    • Function Pointer to handle heartbeat rate query event.
  • on_update_heartbeatrate[POINTER]
    • Function Pointer to handle heartbeat rate update event.

Return Values

  • true/false

Example

#include "WISECore.h"
int g_iHeartbeatRate = 60;
void on_heartbeatrate_query(const char* sessionid, const char* tenantid, const char* devid, void* userdata)
{
    /*Send current heartbeat rate:60 back to server*/
    core_heartbeatratequery_response(g_iHeartbeatRate, sessionid, tenantid, devid);
    printf("Heartbeat Rate Query: %s, %s\n", sessionid, devid);
}

void on_heartbeatrate_update(const int heartbeatrate, const char* sessionid, const char* tenantid, const char* devid, void* userdata)
{
    printf("Heartbeat Rate Update: %d, %s, %s\n", heartbeatrate, sessionid, devid);
    g_iHeartbeatRate = heartbeatrate;
    core_action_response(130/*wise_heartbeatrate_update_rep*/, sessionid, true, tenantid, devid);
}

int main (int argc, char *argv[]) 
{
    int iRet = 0; /*Initialize WISECore*/     if(!core_initialize("general", "00000001-0000-0000-0000-305A3A77B1CC", "TestClient", "305A3A77B1CC", NULL))
    {
        printf("Unable to initialize WISECore.\n");
        goto EXIT;
    }
    printf("Agent Initialized\n");
    /*Setup heartbeat command callback function*/
    core_heartbeat_callback_set(on_heartbeatrate_query, on_heartbeatrate_update);

    /*Connect to Server*/
    core_connect("127.0.0.1",1883,"admin","123456");

    /*Disconnect*/
    core_disconnect(false);

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


bool core_heartbeatratequery_response(const int heartbeatrate, const char * sessoinid, const char* tenantid, const char* devid);
Description
  • Send heartbeat rate update response back to server.

Parameters

  • heartbeatrate[NUMBER]
    • current heartbeat rate.
  • sessionid[POINTER]
    • session ID of request action.
  • tenantid[POINTER]
    • tenant ID of request device.
  • devid[POINTER]
    • device ID of request device.

Return Values

  • true/false

Example

Reference to core_heartbeat_callback_set().



bool core_device_register();
Description
  • Send device information, wrapped in JSON format, to register device.

Parameters

  • None

Return Values

  • true/false

Example

Reference to core_connection_callback_set().



bool core_heartbeat_send();
Description
  • Send heartbeat message, wrapped in JSON format, to server.

Parameters

  • None

Return Values

  • true/false

Example

#include "WISECore.h"
#include "pthread.h"
int g_iHeartbeatRate = 60;
void* threadconnect(void* args)
{
    core_device_register();
    while(true)
    {
        core_heartbeat_send();
        usleep(g_iHeartbeatRate*1000000);
    }
    pthread_exit(0);
    return NULL;
}

void on_connect_cb(void* userdata)
{
	pthread_t conn = 0;
	if(pthread_create(&conn, NULL, threadconnect, NULL)==0)
		pthread_detach(conn);
}

int main (int argc, char *argv[]) 
{
    int iRet = 0; /*Initialize WISECore*/     if(!core_initialize("general", "00000001-0000-0000-0000-305A3A77B1CC", "TestClient", "305A3A77B1CC", NULL))
    {
        printf("Unable to initialize WISECore.\n");
        goto EXIT;
    }
    printf("Agent Initialized\n");
    /*Setup connection callback function*/
    core_connection_callback_set(on_connect_cb, on_lostconnect_cb, on_disconnect_cb, on_msgrecv);

    /*Connect to Server*/
    core_connect("127.0.0.1",1883,"admin","123456");

    /*Disconnect*/
    core_disconnect(false);

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


bool core_publish(char const * topic, void * pkt, long pktlength, int retain, int qos);
Description
  • Send message, wrapped in JSON format, to server on specific topic.

Parameters

  • topic[POINTER]
    • the MQTT topic to publish.
  • pkt[POINTER]
    • the message to publish, in JSON string struct.
  • pktlength[NUMBER]
    • the message length.
  • retain[NUMBER]
    • enable flag to retain this message in broker.
  • qos[NUMBER]
    • QoS level 1, 2, 3

Return Values

  • true/false

Example

#include "WISECore.h"
#include "pthread.h"
int g_iHeartbeatRate = 60;
void* threadconnect(void* args)
{
    core_device_register();
    while(true)
    {
        core_publish(" /wisepaas/general/device/00000001-0000-0000-0000-305A3A77B1CC/devinfoack", "{\"agentID\":\"00000001-0000-0000-0000-305A3A77B1CC\",\"handlerName\":\"general\",\"commCmd\":2055,\"content\":{\"sample\":{\"data1\":5}}}", 123, 0, 0);
        usleep(g_iHeartbeatRate*1000000);
    }
    pthread_exit(0);
    return NULL;
}

void on_connect_cb(void* userdata)
{
	pthread_t conn = 0;
	if(pthread_create(&conn, NULL, threadconnect, NULL)==0)
		pthread_detach(conn);
}

int main (int argc, char *argv[]) 
{
    int iRet = 0; /*Initialize WISECore*/     if(!core_initialize("general", "00000001-0000-0000-0000-305A3A77B1CC", "TestClient", "305A3A77B1CC", NULL))
    {
        printf("Unable to initialize WISECore.\n");
        goto EXIT;
    }
    printf("Agent Initialized\n");
    /*Setup connection callback function*/
    core_connection_callback_set(on_connect_cb, on_lostconnect_cb, on_disconnect_cb, on_msgrecv);

    /*Connect to Server*/
    core_connect("127.0.0.1",1883,"admin","123456");

    /*Disconnect*/
    core_disconnect(false);

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


bool core_subscribe(char const * topic, int qos);
Description
  • subscribe and receive the message from server on specific topic.

Parameters

  • topic[POINTER]
    • the topic to subscribe.
  • qos[NUMBER]
    • QoS level 1, 2, 3

Return Values

  • true/false

Example

#include "WISECore.h"
void on_connect_cb(void* userdata)
{
    printf("CB_Connected \n");
    /*Send device register message.*/
    core_device_register(); 

    core_subscribe("/wisepaas/general/device/00000001-0000-0000-0000-305A3A77B1CC/agentactionreq", 0);
}

void on_lostconnect_cb(void* userdata)
{
    printf("CB_Lostconnect %s\n", core_error_string_get());
}

void on_disconnect_cb(void* userdata)
{
    printf("CB_Disconnect \n");
}

void on_msgrecv(const char* topic, const void *pkt, const long pktlength, void* userdata)
{
    printf("Packet received:\n [%s],\n %s\n", topic, pkt);
}

int main (int argc, char *argv[]) 
{
    int iRet = 0; /*Initialize WISECore*/     if(!core_initialize("general", "00000001-0000-0000-0000-305A3A77B1CC", "TestClient", "305A3A77B1CC", NULL))
    {
        printf("Unable to initialize WISECore.\n");
        goto EXIT;
    }
    printf("Agent Initialized\n");
    /*Setup connection callback function*/
    core_connection_callback_set(on_connect_cb, on_lostconnect_cb, on_disconnect_cb, on_msgrecv);

    /*Connect to Server*/
    core_connect("127.0.0.1",1883,"admin","123456");

    /*Unsubscribe topic*/
    core_unsubscribe("/wisepaas/general/device/00000001-0000-0000-0000-305A3A77B1CC/agentactionreq");

    /*Disconnect*/
    core_disconnect(false);

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


bool core_unsubscribe(char const * topic)
Description
  • stop to receive message from server on specific topic.

Parameters

  • topic[POINTER]
    • the topic to unsubscribe.

Return Values

  • true/false

Example

Reference to core_subscribe().



const char* core_error_string_get();
Description
  • Call to obtain a const string description the error number.

Parameters

  • None

Return Values

  • true/false

Example

Reference to core_connection_callback_set().

Callback Function

typedef void (*CORE_MESSAGE_RECV_CALLBACK)(const char* topic, const void *pkt, const long pktlength, void* userdata);
Description
  • define the message receive callback function.

Parameters

  • topic[POINTER]
    • MQTT topic string
  • pkt[POINTER]
    • the packet structure pointer.
  • pktlength[NUMBER]
    • received packet length.
  • userdata[POINTER]
    • unformated pointer to carry the user defined structure.

Return Values

  • None.


typedef void (*CORE_CONNECTED_CALLBACK)(void* userdata);
Description
  • define the on connected callback function.

Parameters

  • userdata[POINTER]
    • unformated pointer to carry the user defined structure.

Return Values

  • None.


typedef void (*CORE_LOSTCONNECTED_CALLBACK)(void* userdata);
Description
  • define the on lost connect callback function.

Parameters

  • userdata[POINTER]
    • unformated pointer to carry the user defined structure.

Return Values

  • None.


typedef void (*CORE_DISCONNECT_CALLBACK)(void* userdata);
Description
  • define the on disconnect callback function.

Parameters

  • userdata[POINTER]
    • unformated pointer to carry the user defined structure.

Return Values

  • None.


typedef void (*CORE_RENAME_CALLBACK)(const char* name, const int cmdid, const char* sessionid, const char* tenantid, const char* clientid, void* userdata);
Description
  • define the rename callback function to handle the rename command received from server.

Parameters

  • name[POINTER]
    • new name.
  • cmdid[NUMBER]
    • received command ID.
  • sessionid[POINTER]
    • received request session ID.
  • tenantid[POINTER]
    • the tenant ID string in UUID format: xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx.
  • clientid[POINTER]
    • the client ID string in UUID format: xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx.
  • userdata[POINTER]
    • unformated pointer to carry the user defined structure.

Return Values

  • None.


typedef void (*CORE_UPDATE_CALLBACK)(const char* loginID, const char* loginPW, const int port, const char* path, const char* md5, const int cmdid, const char* sessionid, const char* tenantid, const char* clientid, void* userdata);
Description
  • define the update callback function to handle the update command received from server.

Parameters

  • loginID[POINTER]
    • ftp server login account.
  • loginPW[POINTER]
    • ftp server login password.
  • port[NUMBER]
    • ftp server listen port.
  • path[POINTER]
    • ftp download file path.
  • md5[POINTER]
    • md5 to verify download file.
  • cmdid[NUMBER]
    • received command ID.
  • sessionid[POINTER]
    • received request session ID.
  • tenantid[POINTER]
    • the tenant ID string in UUID format: xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx.
  • clientid[POINTER]
    • the client ID string in UUID format: xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx.
  • userdata[POINTER]
    • unformated pointer to carry the user defined structure.

Return Values

  • None.


typedef void (*CORE_SERVER_RECONNECT_CALLBACK)(const char* tenantid, const char* clientid, void* userdata);
Description
  • define the server reconnect callback function to handle the received command from server.

Parameters

  • tenantid[POINTER]
    • the tenant ID string in UUID format: xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx.
  • clientid[POINTER]
    • the client ID string in UUID format: xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx.
  • userdata[POINTER]
    • unformated pointer to carry the user defined structure.

Return Values

  • None.


typedef void (*CORE_GET_CAPABILITY_CALLBACK)(const void *pkt, const long pktlength, const char* tenantid, const char* clientid, void* userdata);
Description
  • define the get capability callback function to handle the received command from server.

Parameters

  • pkt[POINTER]
    • the received payload in JSON string.
  • pktlength[NUMBER]
    • the length of received payload.
  • tenantid[POINTER]
    • the tenant ID string in UUID format: xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx.
  • clientid[POINTER]
    • the client ID string in UUID format: xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx.
  • userdata[POINTER]
    • unformated pointer to carry the user defined structure.

Return Values

  • None.


typedef void (*CORE_START_REPORT_CALLBACK)(const void *pkt, const long pktlength, const char* tenantid, const char* clientid, void* userdata);
Description
  • define the start report callback function to handle the received command from server.

Parameters

  • pkt[POINTER]
    • the received payload in JSON string.
  • pktlength[NUMBER]
    • the length of received payload.
  • tenantid[POINTER]
    • the tenant ID string in UUID format: xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx.
  • clientid[POINTER]
    • the client ID string in UUID format: xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx.
  • userdata[POINTER]
    • unformated pointer to carry the user defined structure.

Return Values

  • None.


typedef void (*CORE_STOP_REPORT_CALLBACK)(const void *pkt, const long pktlength, const char* tenantid, const char* clientid, void* userdata);
Description
  • define the stop report callback function to handle the received command from server.

Parameters

  • pkt[POINTER]
    • the received payload in JSON string.
  • pktlength[NUMBER]
    • the length of received payload.
  • tenantid[POINTER]
    • the tenant ID string in UUID format: xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx.
  • clientid[POINTER]
    • the client ID string in UUID format: xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx.
  • userdata[POINTER]
    • unformated pointer to carry the user defined structure.

Return Values

  • None.


typedef void (*CORE_QUERY_HEARTBEATRATE_CALLBACK)(const char* sessionid,const char* tenantid,const char* clientid, void* userdata);
Description
  • define the query heart beat rate callback function to handle the received command from server.

Parameters

  • sessionid[POINTER]
    • received request session ID.
  • tenantid[POINTER]
    • the tenant ID string in UUID format: xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx.
  • clientid[POINTER]
    • the client ID string in UUID format: xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx.
  • userdata[POINTER]
    • unformated pointer to carry the user defined structure.

Return Values

  • None.


typedef void (*CORE_UPDATE_HEARTBEATRATE_CALLBACK)(const int heartbeatrate, const char* sessionid, const char* tenantid, const char* clientid, void* userdata);
Description
  • define the update heart beat rate callback function to handle the received command from server.

Parameters

  • heartbeatrate[NUMBER]
    • new heart beat rate in second.
  • sessionid[POINTER]
    • received request session ID.
  • tenantid[POINTER]
    • the tenant ID string in UUID format: xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx.
  • clientid[POINTER]
    • the client ID string in UUID format: xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx.
  • userdata[POINTER]
    • unformated pointer to carry the user defined structure.

Return Values

  • None.


typedef long long (*CORE_GET_TIME_TICK_CALLBACK)(void* userdata);
Description
  • define theget time tick callback function to handle pass the time tick into EI-Agent. EI-Agent cannot get or generate time tick itself.

Parameters

  • userdata[POINTER]
    • unformated pointer to carry the user defined structure.

Return Values

  • None.

Client Sample Code

#include "network.h"
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
#include <pthread.h>
#include <time.h>
#include "WISECore.h"
#include "HandlerKernel.h"
#include "util_path.h"
#include "IPSOParser.h"
#include "IoTMessageGenerate.h"
#include "WISEPlatform.h"

#define DEF_OSINFO_JSON "{\"content\":{\"cagentVersion\":\"%s\",\"cagentType\":\"%s\",\"osVersion\":\"%s\",\"biosVersion\":\"%s\",\"platformName\":\"%s\",\"processorName\":\"%s\",\"osArch\":\"%s\",\"totalPhysMemKB\":%d,\"macs\":\"%s\",\"IP\":\"%s\"},\"commCmd\":116,\"agentID\":\"%s\",\"handlerName\":\"general\",\"sendTS\":{\"$date\":%lld}}"

char g_strClientID[37] = "00000001-0000-0000-0000-305A3A77B1CC";
char g_strTenantID[37] = "general";
char g_strHostName[11] = "TestClient";
char g_strProductTag[37] = "RMM";

MSG_CLASSIFY_T* g_pCapability = NULL;
void* g_pHandler = NULL;
//-------------------------Memory leak check define--------------------------------
#ifdef MEM_LEAK_CHECK
#include <crtdbg.h>
_CrtMemState memStateStart, memStateEnd, memStateDiff;
#endif
//---------------------------------------------------------------------------------
void SubscribeRMMTopic();

void* threadconnect(void* args)
{
	char strRecvTopic[256] = {0};

	core_device_register();

	printf("CB_Connected \n");

	SubscribeRMMTopic();
	while(true)
	{
		core_heartbeat_send();
		usleep(60000*1000);
	}

	pthread_exit(0);
	return NULL;
}

void on_connect_cb(void* userdata)
{
	pthread_t conn = 0;
	if(pthread_create(&conn, NULL, threadconnect, NULL)==0)
		pthread_detach(conn);
}

void on_lostconnect_cb(void* userdata)
{
	//printf("CB_Lostconnect %s\n", core_error_string_get());
}

void on_disconnect_cb(void* userdata)
{
	printf("CB_Disconnect \n");
}

/*callback function to handle threshold rule check event*/
void on_threshold_triggered(threshold_event_type type, char* sensorname, double value, MSG_ATTRIBUTE_T* attr, void *pRev)
{
	printf(" SampleHandler> threshold triggered:[%d, %s, %f]", type, sensorname, value);
}

/*callback function to handle get sensor data event*/
bool on_get_sensor(get_data_t* objlist, void *pRev)
{
	get_data_t *current = objlist;
	if(objlist == NULL) return false;

	while(current)
	{
		current->errcode = STATUSCODE_SUCCESS;
		strcpy(current->errstring, STATUS_SUCCESS);

		switch(current->attr->type)
		{
		case attr_type_numeric:
			printf(" SampleHandler> get: %s value:%d", current->sensorname, current->attr->v);
		 break;
		case attr_type_boolean:
			printf(" SampleHandler> get: %s value:%s", current->sensorname, current->attr->bv?"true":"false");
		 break;
		case attr_type_string:
			printf(" SampleHandler> get: %s value:%s", current->sensorname, current->attr->sv);
		 break;
		case attr_type_date:
			printf(" SampleHandler> get: %s value:Date:%s", current->sensorname, current->attr->sv);
		 break;
		case attr_type_timestamp:
		 printf(" SampleHandler> get: %s value:Timestamp:%d",current->sensorname, current->attr->v);
		 break;
		}

		current = current->next;
	}
	return true;
}

/*callback function to handle set sensor data event*/
bool on_set_sensor(set_data_t* objlist, void *pRev)
{
	set_data_t *current = objlist;
	if(objlist == NULL) return false;
	while(current)
	{
		current->errcode = STATUSCODE_SUCCESS;
		strcpy(current->errstring, STATUS_SUCCESS);

		switch(current->newtype)
		{
		case attr_type_numeric:
			printf(" SampleHandler> set: %s value:%d", current->sensorname, current->v);
		 break;
		case attr_type_boolean:
			printf(" SampleHandler> set: %s value:%s", current->sensorname, current->bv?"true":"false");
		 break;
		case attr_type_string:
			printf(" SampleHandler> set: %s value:%s", current->sensorname, current->sv);
		 break;
		}

		current = current->next;
	}

	return true;
}

void on_msgrecv(const char* topic, const void *pkt, const long pktlength, void* userdata)
{
	int cmdID = 0;
	char sessionID[32] = {0};

	printf("Packet received:\n [%s],\n %s\n", topic, pkt);
	/* All messages received from subscribed topics will trigger this callback function.
	 * topic: received topic.
	 * pkt: received message in json string.
	 * pktlength: received message length.
	 */

	if(g_pHandler)
	{		
		/*Parse Received Command*/
		if(HandlerKernelEx_ParseRecvCMDWithSessionID((char*)pkt, &cmdID, sessionID) != handler_success)
			return;
		switch(cmdID)
		{
		case hk_get_capability_req:
			if(g_pCapability)
			{
				HandlerKernelEx_LockCapability(g_pHandler);
				HandlerKernelEx_SetCapability(g_pHandler, g_pCapability, true);
				HandlerKernelEx_UnlockCapability(g_pHandler);
			}
			break;
		case hk_auto_upload_req:
			/*start live report*/
			HandlerKernelEx_LiveReportStart(g_pHandler, hk_auto_upload_rep, (char*)pkt);
			break;
		case hk_set_thr_req:
			/*Stop threshold check thread*/
			HandlerKernelEx_StopThresholdCheck(g_pHandler);
			/*setup threshold rule*/
			HandlerKernelEx_SetThreshold(g_pHandler, hk_set_thr_rep,(char*) pkt);
			/*register the threshold check callback function to handle trigger event*/
			HandlerKernelEx_SetThresholdTrigger(g_pHandler, on_threshold_triggered);
			/*Restart threshold check thread*/
			HandlerKernelEx_StartThresholdCheck(g_pHandler);
			break;
		case hk_del_thr_req:
			/*Stop threshold check thread*/
			HandlerKernelEx_StopThresholdCheck(g_pHandler);
			/*clear threshold check callback function*/
			HandlerKernelEx_SetThresholdTrigger(g_pHandler, NULL);
			/*Delete all threshold rules*/
			HandlerKernelEx_DeleteAllThreshold(g_pHandler, hk_del_thr_rep);
			break;
		case hk_get_sensors_data_req:
			/*Get Sensor Data with callback function*/
			HandlerKernelEx_GetSensorData(g_pHandler, hk_get_sensors_data_rep, sessionID, (char*)pkt, on_get_sensor);
			break;
		case hk_set_sensors_data_req:
			/*Set Sensor Data with callback function*/
			HandlerKernelEx_SetSensorData(g_pHandler, hk_set_sensors_data_rep, sessionID, (char*)pkt, on_set_sensor);
			break;
		default:
			{
				/* Send command not support reply message*/
				char topic[128] = {0};
				char repMsg[32] = {0};
				int len = 0;
				sprintf( repMsg, "{\"errorRep\":\"Unknown cmd!\"}" );
				len= strlen( "{\"errorRep\":\"Unknown cmd!\"}" ) ;
				sprintf(topic, DEF_AGENTACT_TOPIC, g_strTenantID, g_strProductTag, g_strClientID);
				core_publish(topic, repMsg, len, 0, 0);
			}
			break;
		}
	}
}

void on_rename(const char* name, const int cmdid, const char* sessionid, const char* tenantid, const char* devid, void* userdata)
{
	printf("rename to: %s\n", name);

	core_action_response(cmdid, sessionid, true, tenantid, devid);
	return;
}

void on_update(const char* loginID, const char* loginPW, const int port, const char* path, const char* md5, const int cmdid, const char* sessionid, const char* tenantid, const char* devid, void* userdata)
{
	printf("Update: %s, %s, %d, %s, %s\n", loginID, loginPW, port, path, md5);

	core_action_response(cmdid, sessionid, true, tenantid, devid);
	return;
}

void on_server_reconnect(const char* tenantid, const char* devid, void* userdata)
{
	if(!strcmp(g_strClientID, devid))
		core_device_register();
	/*TODO: resend whole capability*/
}

bool SendOSInfo();

void* threadgetcapab(void* args)
{
	SendOSInfo();

	if(g_pHandler)
	{
		HandlerKernelEx_LockCapability(g_pHandler);
		HandlerKernelEx_SetCapability(g_pHandler, g_pCapability, true);
		HandlerKernelEx_UnlockCapability(g_pHandler);
	}

	printf("on_get_capability \n");
	pthread_exit(0);
	return NULL;
}

void on_get_capability(const void *pkt, const long pktlength, const char* tenantid, const char* devid, void* userdata)
{
	pthread_t getcapab = 0;
	if(pthread_create(&getcapab, NULL, threadgetcapab, NULL)==0)
		pthread_detach(getcapab);
	/*TODO: send whole capability*/
}

void on_start_report(const void *pkt, const long pktlength, const char* tenantid, const char* devid, void* userdata)
{
	/*TODO: start report sensor data*/
	if(g_pHandler)
	{
		HandlerKernelEx_AutoReportStart(g_pHandler, pkt);
	}
}

void on_stop_report(const void *pkt, const long pktlength, const char* tenantid, const char* devid, void* userdata)
{
	/*TODO: stop report sensor data*/
	if(g_pHandler)
	{
		HandlerKernelEx_AutoReportStop(g_pHandler, pkt);
	}
}

void on_heartbeatrate_query(const char* sessionid,const char* tenantid,const char* devid, void* userdata)
{
	core_heartbeatratequery_response(60,sessionid, tenantid, devid);
}

#ifdef WIN32
#include "sys/time.h"
int gettimeofday(struct timeval *tv, struct timezone *tz)
{
    time_t clock;
    struct tm tm;
    SYSTEMTIME wtm;
 
    GetLocalTime(&wtm);
    tm.tm_year     = wtm.wYear - 1900;
    tm.tm_mon     = wtm.wMonth - 1;
    tm.tm_mday     = wtm.wDay;
    tm.tm_hour     = wtm.wHour;
    tm.tm_min     = wtm.wMinute;
    tm.tm_sec     = wtm.wSecond;
    tm. tm_isdst    = -1;
    clock = mktime(&tm);
    tv->tv_sec = (long)clock;
    tv->tv_usec = wtm.wMilliseconds * 1000;
 
    return (0);
}
#endif

long long get_timetick(void* userdata)
{
	long long tick = 0;
	struct timeval tv;
	gettimeofday(&tv, NULL);
	tick = (long long)tv.tv_sec*1000 + (long long)tv.tv_usec/1000;
	return tick;
}

void on_heartbeatrate_update(const int heartbeatrate, const char* sessionid, const char* tenantid, const char* devid, void* userdata)
{
	printf("Heartbeat Rate Update: %d, %s, %s\n", heartbeatrate, sessionid, devid);

	core_action_response(130/*wise_heartbeatrate_update_rep*/, sessionid, true, tenantid, devid);
	return;
}

AGENT_SEND_STATUS send_cbf(HANDLE const handler, int enum_act, void const * const requestData, unsigned int const requestLen, void *pRev1, void* pRev2 )
{
	char* buff = NULL;
	char topic[128] = {0};
	HANDLER_INFO_EX* pHandler = NULL;
	bool bResult = false;
	int length = 0;
	if(handler == NULL || requestData == NULL)
		return cagent_send_data_error;
	pHandler = (HANDLER_INFO_EX*)handler;
	
	length =  strlen(DEF_ACTION_RESPONSE_JSON) + requestLen + 12 + strlen(pHandler->Name);
	buff = calloc(1,length);
	snprintf(buff, length, DEF_ACTION_RESPONSE_JSON, enum_act, pHandler->Name, (char*)requestData, get_timetick(NULL));

	sprintf(topic, DEF_AGENTACT_TOPIC, pHandler->agentInfo->tenantId, g_strProductTag, pHandler->agentInfo->devId);

	bResult = core_publish(topic, buff, strlen(buff), 0, 0);

	free(buff);
	if(bResult)
		return cagent_success;
	else
		return cagent_send_data_error;
}


AGENT_SEND_STATUS send_capability_cbf( HANDLE const handler, void const * const requestData, unsigned int const requestLen, void *pRev1, void* pRev2 )
{

	MSG_CLASSIFY_T* root = NULL;
	HANDLER_INFO_EX* pHandler = NULL;
	if(handler == NULL || requestData == NULL)
		return cagent_send_data_error;
	pHandler = (HANDLER_INFO_EX*)handler;
	root = IoT_CreateRoot(pHandler->Name);
	if(transfer_parse_ipso((char*)requestData,  root))
	{
		char topic[128] = {0};
		char* buff = IoT_PrintFullCapability(root, pHandler->agentInfo->devId);
		sprintf(topic, DEF_AGENTACT_TOPIC, pHandler->agentInfo->tenantId, g_strProductTag, pHandler->agentInfo->devId);
		if(core_publish(topic, buff, strlen(buff), 0, 0))
			return cagent_success;
		else
		{

			return cagent_send_data_error;
		}
	}
	return cagent_send_data_error;
}

AGENT_SEND_STATUS send_autoreport_cbf( HANDLE const handler, void const * const requestData, unsigned int const requestLen, void *pRev1, void* pRev2 )
{
	char* buff = NULL;
	char topic[128] = {0};
	HANDLER_INFO_EX* pHandler = NULL;
	bool bResult = false;
	int length = 0;
	if(handler == NULL || requestData == NULL)
		return cagent_send_data_error;
	pHandler = (HANDLER_INFO_EX*)handler;
	length =  strlen(DEF_ACTION_RESPONSE_JSON) + requestLen + 12 + strlen(pHandler->Name);
	buff = calloc(1,length);
	snprintf(buff, length, DEF_ACTION_RESPONSE_JSON, 2055, "general", (char*)requestData, get_timetick(NULL));
	sprintf(topic, DEF_AGENTREPORT_TOPIC, pHandler->agentInfo->tenantId, pHandler->agentInfo->devId);

	bResult = core_publish(topic, buff, strlen(buff), 0, 0);

	free(buff);
	if(bResult)
		return cagent_success;
	else
		return cagent_send_data_error;
}

AGENT_SEND_STATUS  send_event_cbf( HANDLE const handler, HANDLER_NOTIFY_SEVERITY severity, void const * const requestData, unsigned int const requestLen, void *pRev1, void* pRev2 )
{
	char* buff = NULL;
	char topic[128] = {0};
	HANDLER_INFO_EX* pHandler = NULL;
	bool bResult = false;
	int length = 0;
	if(handler == NULL || requestData == NULL)
		return cagent_send_data_error;
	pHandler = (HANDLER_INFO_EX*)handler;
	length =  strlen(DEF_ACTION_RESPONSE_JSON) + requestLen + 12 + strlen(pHandler->Name);
	buff = calloc(1,length);
	snprintf(buff, length, DEF_ACTION_RESPONSE_JSON, 2059, pHandler->Name, (char*)requestData, get_timetick(NULL));
	sprintf(topic, DEF_EVENTNOTIFY_TOPIC, pHandler->agentInfo->tenantId, g_strProductTag, pHandler->agentInfo->devId);

	bResult = core_publish(topic, buff, strlen(buff), 0, 0);

	free(buff);
	if(bResult)
		return cagent_success;
	else
		return cagent_send_data_error;
}

MSG_CLASSIFY_T* LoadCapability(char* path)
{
	int size = 0;
	char* buff = NULL; 
	char handler[256] = {0};
	MSG_CLASSIFY_T* root = NULL;
	size = util_file_size_get(path);
	buff = calloc(1, size+1);
	if(buff == NULL)
		return root;
	if(util_file_read(path, buff, size)==0)
		return root;
	if(!transfer_get_ipso_handlername(buff, handler))
		return root;
	root = IoT_CreateRoot(handler);
	transfer_parse_ipso(buff, root);
	free(buff);
	return root;
}

void* CreateSampleHandler(cagent_agent_info_body_t* agentinfo)
{
	void* pHandler = NULL;
	HANDLER_INFO_EX myhandler;
	memset(&myhandler, 0, sizeof(HANDLER_INFO_EX));
	strcpy(myhandler.Name, "SUSIControl");
	myhandler.sendcbf = send_cbf;
	myhandler.sendcapabilitycbf = send_capability_cbf;
	myhandler.sendreportcbf = send_autoreport_cbf;
	myhandler.sendeventcbf = send_event_cbf;
	myhandler.agentInfo = calloc(1, sizeof(cagent_agent_info_body_t));
	memcpy(myhandler.agentInfo, agentinfo, sizeof(cagent_agent_info_body_t));

	pHandler = HandlerKernelEx_Initialize((HANDLER_INFO*)&myhandler);
	g_pCapability = LoadCapability("capability.txt");
	if(g_pCapability != NULL)
		HandlerKernelEx_SetCapability(pHandler, g_pCapability,false);
	printf("Create Sample Handler\n");
	return pHandler;
}

void ReleaseSampleHandler(void* phandler)
{
	HandlerKernelEx_Uninitialize(phandler);
}

void SubscribeRMMTopic()
{
	char topic[256] = {0};
	sprintf(topic, DEF_CALLBACKREQ_TOPIC, g_strTenantID, g_strProductTag, g_strClientID);

	core_subscribe(topic, 0);
}

void CreateAgentInfo(cagent_agent_info_body_t* agentinfo)
{
	if(agentinfo!= NULL)
	{
		strcpy(agentinfo->hostname, g_strHostName);
		strcpy(agentinfo->devId, g_strClientID);
		strcpy(agentinfo->tenantId, g_strTenantID);
		strcpy(agentinfo->sn, "305A3A77B1CC");
		strcpy(agentinfo->mac, "305A3A77B1CC");
		strcpy(agentinfo->version, "4.0.0");
		strcpy(agentinfo->type, "IPC");
		strcpy(agentinfo->product, "test");
		strcpy(agentinfo->manufacture, "test");
		agentinfo->status = 0;
	}
}

void UpdateData(char* path, MSG_CLASSIFY_T* root)
{
	int size = 0;
	char* buff = NULL; 
	char handler[256] = {0};
	if(root == NULL)
		return;

	size = util_file_size_get(path);
	buff = calloc(1, size+1);
	if(buff == NULL)
		return;
	if(util_file_read(path, buff, size)==0)
		return;
	if(!transfer_get_ipso_handlername(buff, handler))
		return;
	transfer_parse_ipso(buff, root);
	free(buff);
}

void* threadaccessdata(void* args)
{
	while(true)
	{
		HandlerKernelEx_LockCapability(g_pHandler);
		UpdateData("capability.txt", g_pCapability);
		HandlerKernelEx_UnlockCapability(g_pHandler);
		usleep(1000*1000);
	}
	pthread_exit(0);
	return NULL;
}

pthread_t StartAccessData()
{
	pthread_t thread = 0;
	if(pthread_create(&thread, NULL, threadaccessdata, NULL)!=0)
		thread = 0;
	return thread;
}

void StopAccessData(pthread_t thread)
{
	if(thread != 0)
	{
		pthread_cancel(thread);
		pthread_join(thread, NULL);
	}
}

bool SendOSInfo()
{
	long long tick = 0;
	char strPayloadBuff[2048] = {0};
	char localip[16] = {0};
	char strTopicBuff[256] = {0};
	tick = get_timetick(NULL);

	
	core_address_get(localip);

	snprintf(strPayloadBuff, sizeof(strPayloadBuff), DEF_OSINFO_JSON, "4.0.0",
												 "IPC",
												 "Windows 8",
												 "V1.2",
												 "SOM-111",
												 "Intel(R) Atom(TM) CPU D525   @ 1.8077GHz",
												 "X86",
												 2048,
												 "305A3A77B1DA",
												 localip,
												 g_strClientID,
												 tick);

#ifdef _WISEPAAS_02_DEF_H_
	sprintf(strTopicBuff, DEF_AGENTACT_TOPIC, g_strTenantID, g_strProductTag, g_strClientID);
#else
	sprintf(strTopicBuff, DEF_AGENTACT_TOPIC, pHandle->strClientID);
#endif
	
	return core_publish(strTopicBuff, strPayloadBuff, strlen(strPayloadBuff), 0, 0);
}

int main(int argc, char *argv[])
{
	//char strServerIP[64] = "dev-wisepaas.eastasia.cloudapp.azure.com";
	char strServerIP[64] = "172.22.12.29";
	int iPort = 1883;
	pthread_t threaddataaccess = 0;
	int SSLMode = 0;  //0:disable, 1:CA Mode, 2: PSK Mode.
	cagent_agent_info_body_t agentinfo;
#ifdef MEM_LEAK_CHECK
	_CrtSetDbgFlag ( _CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF ); 
	_CrtMemCheckpoint( &memStateStart);
#endif
	CreateAgentInfo(&agentinfo);

	g_pHandler = CreateSampleHandler(&agentinfo);

	
	threaddataaccess = StartAccessData();

	if(!core_initialize(g_strTenantID, g_strClientID, g_strHostName, agentinfo.mac, &agentinfo))
	{
		printf("Unable to initialize AgentCore.\n");
		goto EXIT;
	}
	printf("Agent Initialized\n");

	core_connection_callback_set(on_connect_cb, on_lostconnect_cb, on_disconnect_cb, on_msgrecv);

	core_action_callback_set(on_rename, on_update);

	core_server_reconnect_callback_set(on_server_reconnect);

	core_iot_callback_set(on_get_capability, on_start_report, on_stop_report);

	core_time_tick_callback_set(get_timetick);

	core_heartbeat_callback_set(on_heartbeatrate_query, on_heartbeatrate_update);

	core_tag_set(g_strProductTag);

	core_product_info_set(agentinfo.sn, NULL, agentinfo.version, agentinfo.type, agentinfo.product, agentinfo.manufacture);

	if(SSLMode == 1)
		core_tls_set( "server.crt", NULL, "ca.crt", "ca.key", "05155853");
	else if(SSLMode == 2)
		core_tls_psk_set("05155853", g_strClientID, NULL);

	if(!core_connect(strServerIP, iPort, "admin", "05155853")){
		printf("Unable to connect to broker. %s\n", core_error_string_get());
		goto EXIT;
	} else {
		printf("Connect to broker: %s\n", strServerIP);
	}
	
EXIT:
	printf("Click enter to exit\n");
	fgetc(stdin);

	StopAccessData(threaddataaccess);

	ReleaseSampleHandler(g_pHandler);

	core_disconnect(true);
	printf("Send Client Info: disconnect\n");
	core_uninitialize();
#ifdef MEM_LEAK_CHECK
	_CrtMemCheckpoint( &memStateEnd );
	if ( _CrtMemDifference( &memStateDiff, &memStateStart, &memStateEnd) )
		_CrtMemDumpStatistics( &memStateDiff );
#endif

	return 0;
}