mbedからGluinサーバへ接続するライブラリです

Dependents:   Servo_DxDevice

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers DxClient.cpp Source File

DxClient.cpp

00001 #include "DxClient.h"
00002 #include "picojson.h"
00003 
00004 #if 1
00005 #define DXDBG(x, ...) printf("[DxClient : DBG]"x"\r\n", ##__VA_ARGS__); 
00006 #define DXWARN(x, ...) printf("[DxClient : WARN]"x"\r\n", ##__VA_ARGS__); 
00007 #define DXERR(x, ...) printf("[DxClient : ERR]"x"\r\n", ##__VA_ARGS__); 
00008 #else
00009 #define DXDBG(x, ...) 
00010 #define DXWARN(x, ...)
00011 #define DXERR(x, ...) 
00012 #endif
00013 
00014 #define DXINFO(x, ...) printf("[DxClient : INFO]"x"\r\n", ##__VA_ARGS__); 
00015 
00016 void generate_randomid( char* out, int len )
00017 {
00018     int i;
00019     static char* words = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890!#$%&()=<>?-_[]{}";
00020     for (i=0;i<len-1;i++) {
00021         out[i] = words[ rand()%strlen(words) ];
00022     }
00023     out[len-1] = 0;
00024 }
00025 
00026 DxClient::DxClient(char * url, char* deviceid, float seed) 
00027 {
00028     m_ws.set_server( url );   
00029     strcpy( m_deviceid, deviceid );
00030     
00031     memset( m_user, 0, sizeof(m_user));
00032     memset( m_pass, 0, sizeof(m_pass));
00033     memset( m_dev_name, 0, sizeof(m_dev_name));
00034     memset( m_dev_description, 0, sizeof(m_dev_description));
00035     
00036     m_func_get_request = NULL;
00037     m_func_set_request = NULL;
00038     
00039     DXDBG("random seed is %f", seed );
00040     srand(seed);
00041 }
00042 
00043 
00044 void DxClient::set_user(char* user, char *pass)
00045 {
00046     //  set auth user and password
00047     strncpy( m_user, user, sizeof(m_user) );
00048     strncpy( m_pass, pass, sizeof(m_pass) );
00049 }
00050 
00051 void DxClient::set_device_description(char* desc)
00052 {
00053     strncpy( m_dev_description, desc, sizeof(m_dev_description) );
00054 }
00055 void DxClient::set_device_name(char* name)
00056 {
00057     strncpy( m_dev_name, name, sizeof(m_dev_name) );
00058 }
00059 
00060 
00061 bool DxClient::connect()
00062 {
00063     bool res;
00064     res = m_ws.connect();
00065     if (res) {
00066         DXDBG("Connected to server by Websocket");
00067         // send user_auth_request
00068         res = dx_user_auth_request();
00069         if (res) {
00070             DXDBG("...Authorized");
00071         } else {
00072             DXDBG("...Login failed");
00073         }
00074     } else {
00075         DXDBG("Failed to server by Websocket");
00076     }
00077     return res;
00078 }
00079 
00080 bool DxClient::close()
00081 {
00082     return m_ws.close();
00083 }
00084 
00085 // ==============================================
00086 //  Send user_auth_request to server
00087 //  if user is authorized correctly, clinet gets 200 OK response
00088 //  this request must be sent before any other requset
00089 // ==============================================
00090 bool DxClient::dx_user_auth_request()
00091 {
00092     DXDBG("Call dx_user_auth_request");
00093     
00094     int  i, len;
00095     bool res;
00096     
00097     char message[MAX_MESSAGELEN];
00098     char mesid[MAX_MESSAGEIDLEN];
00099     generate_randomid( mesid, sizeof(mesid) );
00100     len = snprintf(message, sizeof(message), "{" \
00101                     "\"type\":\"user-auth-request\"," \
00102                     "\"message-id\":\"%s\"," \
00103                     "\"username\":\"%s\"," \
00104                     "\"password\":\"%s\"" \
00105                     "}",
00106                     mesid,
00107                     m_user,
00108                     m_pass
00109                     );
00110     if (len >= sizeof(message)-1) {
00111         DXDBG( "USER_AUTH: message is over MAX LEN");
00112         return false;
00113     }
00114     DXDBG("send: %s", message);
00115 
00116     m_ws.send(message);
00117 
00118     // clear the buffer and wait a sec...
00119     memset( message, 0, sizeof(message));
00120     for (i=0, res=false;i<10;i++) {
00121         wait(0.5f);
00122         if (m_ws.read(message)) {
00123             DXDBG("Get Message: %s\n", message);
00124             picojson::value v;
00125             std::string err;
00126             picojson::parse(v, (const char *)message, (const char *)(message + strlen(message)), &err);
00127 
00128 
00129             if (err.empty())
00130             {
00131                 picojson::object& root = v.get<picojson::object>();
00132                 
00133                 // check auth response
00134                 if (root["type"].is<std::string>()) {
00135                     if (strcmp(root["type"].get<std::string>().c_str(), "user-auth-response")) {
00136                         DXDBG("USER_AUTH: Not user_auth_response\n");
00137                         break;
00138                     }
00139                 } else {
00140                     DXDBG("USER_AUTH: there is no type\n");
00141                     break;
00142                 }
00143                 if (root["message-id"].is<std::string>()) {
00144                     if (strcmp(root["message-id"].get<std::string>().c_str(), mesid)) {
00145                         DXDBG("USER_AUTH: Not correct response message-id\n");
00146                         break;
00147                     }
00148                 } else {
00149                     DXDBG("USER_AUTH: there is no message-id\n");
00150                     break;
00151                 }
00152                 if (root["status"].is<std::string>()) {
00153                     if (strcmp(root["status"].get<std::string>().c_str(), "200 OK")) {
00154                         DXDBG("USER_AUTH: status error\n");
00155                         break;
00156                     }
00157                 } else {
00158                     DXDBG("USER_AUTH: there is no status\n");
00159                     break;
00160                 }
00161 
00162                 DXDBG("USER_AUTH: user auth is success\n");
00163                 res = true;
00164             } else {
00165                 DXDBG("USER_AUTH: JSON parse Error\n");
00166             }
00167             break;        
00168         }
00169     }
00170     return res;
00171 }
00172 
00173 char* dx_type_to_string( dx_prop_type type, char* buf)
00174 {
00175     char *res = buf;
00176     switch( type ) {
00177         case DX_STRING:
00178             sprintf( res, "string" );
00179             break;
00180         case DX_INTEGER:
00181             sprintf( res, "integer" );
00182             break;
00183         case DX_FLOAT:
00184             sprintf( res, "float" );
00185             break;
00186         case DX_BOOLEAN:
00187             sprintf( res, "boolean" );
00188             break;
00189         default:
00190             sprintf( res, "unknown" );
00191             break;
00192     }
00193     return res;
00194 }
00195 char* dx_direction_to_string( dx_prop_direction dic, char* buf)
00196 {
00197     char *res = buf;
00198     switch( dic ) {
00199         case DX_UPONLY:
00200             sprintf( res, "uponly" );
00201             break;
00202         case DX_DOWNONLY:
00203             sprintf( res, "downonly" );
00204             break;
00205         case DX_UPDOWN:
00206             sprintf( res, "updown" );
00207             break;
00208         default:
00209             sprintf( res, "unknown" );
00210             break;
00211     }
00212     return res;
00213 }
00214 char* dx_mode_to_string( dx_prop_mode mode, char* buf)
00215 {
00216     char *res = buf;
00217     switch( mode ) {
00218         case DX_READONLY:
00219             sprintf( res, "readonly" );
00220             break;
00221         case DX_WRITEONLY:
00222             sprintf( res, "writeonly" );
00223             break;
00224         case DX_READWRITE:
00225             sprintf( res, "readwrite" );
00226             break;
00227         default:
00228             sprintf( res, "unknown" );
00229             break;
00230     }
00231     return res;
00232 }
00233 
00234 // ==============================================
00235 //
00236 // ==============================================
00237 bool DxClient::register_device( dx_props *props )
00238 {
00239     DXDBG("Call register_device");
00240     
00241     bool res;
00242     int len;
00243 
00244     char message[MAX_MESSAGELEN];
00245     char mesid[MAX_MESSAGEIDLEN];
00246     generate_randomid( mesid, sizeof(mesid) );
00247     len = snprintf(message, sizeof(message), "{" \
00248                     "\"type\":\"device-register-request\"," \
00249                     "\"device-id\":\"%s\"," \
00250                     "\"message-id\":\"%s\"," \
00251                     "\"name\":\"%s\"," \
00252                     "\"description\":\"%s\"," \
00253                     "\"props\":{",
00254                     m_deviceid,
00255                     mesid,
00256                     m_dev_name,
00257                     m_dev_description
00258                     );
00259     if (len >= sizeof(message)-1) {
00260         DXDBG( "REGISTER_DEVICE: message is over  MAX LEN");
00261         return false;
00262     }
00263                     
00264     int i;
00265     for (i=0;i<props->numofprops;i++) {
00266         char s_prop[MAX_PROPLEN];
00267         char s_type[16];
00268         char s_direction[16];
00269         char s_mode[16];
00270         
00271         char s_val[MAX_PROPSVALLEN];
00272         switch( props->props[i].type ){
00273             case DX_STRING:
00274                 sprintf( s_val, "\"%s\"", props->props[i].s_val );
00275                 break;
00276             case DX_INTEGER:
00277                 sprintf( s_val, "%d", (int)(props->props[i].f_val) );
00278                 break;
00279             case DX_FLOAT:
00280                 sprintf( s_val, "%f", props->props[i].f_val );
00281                 break;
00282             case DX_BOOLEAN:
00283                 sprintf( s_val, "%s", props->props[i].b_val?"true":"false" );
00284                 break;
00285         }
00286         
00287         len = snprintf( s_prop, sizeof(s_prop), "\"%s\": {" \
00288                             "\"value\":%s," \
00289                             "\"type\":\"%s\"," \
00290                             "\"direction\":\"%s\"," \
00291                             "\"mode\":\"%s\"" \
00292                             "}",
00293                             props->props[i].name,
00294                             s_val,
00295                             dx_type_to_string( props->props[i].type, s_type ),
00296                             dx_direction_to_string( props->props[i].direction, s_direction ),
00297                             dx_mode_to_string( props->props[i].mode, s_mode )
00298                             );
00299         if (len >= sizeof(s_prop)-1) {
00300             DXDBG( "REGISTER_DEVICE: prop is over  MAX LEN");
00301             return false;
00302         }
00303         if (len + strlen(message) >= sizeof(message)-1) {
00304             DXDBG( "REGISTER_DEVICE: message is over  MAX LEN");
00305             return false;
00306         }
00307         strcat( message, s_prop );
00308         
00309         if (i+1 < props->numofprops) {
00310             if (1 + strlen(message) >= sizeof(message)-1) {
00311                 DXDBG( "REGISTER_DEVICE: message is over  MAX LEN");
00312                 return false;
00313             }
00314             strncat( message, ",", sizeof(message) );
00315         }
00316     }
00317 
00318     if (2 + strlen(message) >= sizeof(message)-1) {
00319         DXDBG( "REGISTER_DEVICE: message is over  MAX LEN");
00320         return false;
00321     }
00322     strcat( message, "}}" );
00323 
00324     DXDBG("send: %s", message);
00325     m_ws.send(message);
00326     
00327     // clear the buffer and wait a sec...
00328     memset( message, 0, sizeof(message));
00329     for (i=0, res=false;i<10;i++) {
00330         wait(0.5f);
00331         if (m_ws.read(message)) {
00332             DXDBG("Get Message(%d): %s", strlen(message), message);
00333             picojson::value v;
00334             std::string err;
00335             picojson::parse(v, (const char *)message, (const char *)(message + strlen(message)), &err);
00336 
00337             if (err.empty())
00338             {
00339                 picojson::object& root = v.get<picojson::object>();
00340                 // check auth response
00341                 if (root["type"].is<std::string>()) {
00342                     if (strcmp(root["type"].get<std::string>().c_str(), "device-register-response")) {
00343                         DXDBG("REGISTER_DEVICE: Not device_register_response");
00344                         break;
00345                     }
00346                 } else {
00347                     DXDBG("REGISTER_DEVICE: there is no type");
00348                     break;
00349                 }
00350                 if (root["message-id"].is<std::string>()) {
00351                     if (strcmp(root["message-id"].get<std::string>().c_str(), mesid)) {
00352                         DXDBG("REGISTER_DEVICE: Not correct response message-id");
00353                         break;
00354                     }
00355                 } else {
00356                     DXDBG("REGISTER_DEVICE: there is no message-id");
00357                     break;
00358                 }
00359                 if (root["status"].is<std::string>()) {
00360                     if (strcmp(root["status"].get<std::string>().c_str(), "200 OK")) {
00361                         DXDBG("REGISTER_DEVICE: status error");
00362                         break;
00363                     }
00364                 } else {
00365                     DXDBG("REGISTER_DEVICE: there is no status");
00366                     break;
00367                 }
00368                 DXDBG("REGISTER_DEVICE: device register is success");
00369                 res = true;
00370             } else {
00371                 DXDBG("REGISTER_DEVICE: Parse Error");
00372             }
00373             break;
00374         }
00375     }
00376 
00377     return res;
00378 }
00379 
00380 // ==============================================
00381 //
00382 // ==============================================
00383 bool DxClient::deregister_device()
00384 {
00385     int len;
00386     
00387     char message[MAX_MESSAGELEN];
00388     char mesid[MAX_MESSAGEIDLEN];
00389 
00390     generate_randomid( mesid, sizeof(mesid) );
00391     len = snprintf(message, sizeof(message), "{" \
00392                     "\"type\":\"device-deregister-request\"," \
00393                     "\"device-id\":\"%s\"," \
00394                     "\"message-id\":\"%s\"" \
00395                     "}",
00396                     m_deviceid,
00397                     mesid
00398                     );
00399     if (len >= sizeof(message)-1) {
00400         DXDBG( "DEREGISTER_DEVICE: message is over  MAX LEN");
00401         return false;
00402     }
00403 
00404     DXDBG("send: %s", message);
00405     m_ws.send(message);
00406 
00407     // clear the buffer and wait a sec...
00408     bool res;
00409     int i;
00410     memset( message, 0, sizeof(message));
00411     for (i=0, res=false;i<10;i++) {
00412         wait(0.5f);
00413         if (m_ws.read(message)) {
00414             DXDBG("Get Message(%d): %s", strlen(message), message);
00415             picojson::value v;
00416             std::string err;
00417             picojson::parse(v, (const char *)message, (const char *)(message + strlen(message)), &err);
00418 
00419             if (err.empty())
00420             {
00421                 picojson::object& root = v.get<picojson::object>();
00422                 // check auth response
00423                 if (root["type"].is<std::string>()) {
00424                     if (strcmp(root["type"].get<std::string>().c_str(), "device-deregister-response")) {
00425                         DXDBG("DEREGISTER_DEVICE: Not device_deregister_response");
00426                         break;
00427                     }
00428                 } else {
00429                     DXDBG("DEREGISTER_DEVICE: there is no type");
00430                     break;
00431                 }
00432                 if (root["message-id"].is<std::string>()) {
00433                     if (strcmp(root["message-id"].get<std::string>().c_str(), mesid)) {
00434                         DXDBG("DEREGISTER_DEVICE: Not correct response message-id");
00435                         break;
00436                     }
00437                 } else {
00438                     DXDBG("REGISTER_DEVICE: there is no message-id");
00439                     break;
00440                 }
00441                 if (root["status"].is<std::string>()) {
00442                     if (strcmp(root["status"].get<std::string>().c_str(), "200 OK")) {
00443                         DXDBG("DEREGISTER_DEVICE: status error");
00444                         break;
00445                     }
00446                 } else {
00447                     DXDBG("DEREGISTER_DEVICE: there is no status");
00448                     break;
00449                 }
00450                 DXDBG("DEREGISTER_DEVICE: device deregister is success");
00451                 res = true;
00452             } else {
00453                 DXDBG("DEREGISTER_DEVICE: Parse Error");
00454             }
00455             break;
00456         }
00457     }
00458                     
00459     return res;
00460 }
00461 
00462 // ==============================================
00463 //
00464 // ==============================================
00465 bool DxClient::update_device( dx_props *props )
00466 {
00467     int len;
00468     
00469     char message[MAX_MESSAGELEN];
00470     char mesid[MAX_MESSAGEIDLEN];
00471 
00472     generate_randomid( mesid, sizeof(mesid) );
00473     len = snprintf(message, sizeof(message), "{" \
00474                     "\"type\":\"device-update-request\"," \
00475                     "\"device-id\":\"%s\"," \
00476                     "\"message-id\":\"%s\"," \
00477                     "\"props\":{",
00478                     m_deviceid,
00479                     mesid
00480                     );
00481     if (len >= sizeof(message)-1) {
00482         DXDBG( "UPDATE_DEVICE: message is over  MAX LEN");
00483         return false;
00484     }
00485 
00486     int i;                    
00487     for (i=0;i<props->numofprops;i++) {
00488         char s_prop[MAX_PROPLEN];
00489         char s_val[MAX_PROPSVALLEN];
00490         switch( props->props[i].type ){
00491             case DX_STRING:
00492                 sprintf( s_val, "\"%s\"", props->props[i].s_val );
00493                 break;
00494             case DX_INTEGER:
00495                 sprintf( s_val, "%d", (int)(props->props[i].f_val) );
00496                 break;
00497             case DX_FLOAT:
00498                 sprintf( s_val, "%f", props->props[i].f_val );
00499                 break;
00500             case DX_BOOLEAN:
00501                 sprintf( s_val, "%s", props->props[i].b_val?"true":"false" );
00502                 break;
00503         }
00504         
00505         len = snprintf( s_prop, sizeof(s_prop), "\"%s\": {" \
00506                             "\"value\":%s" \
00507                             "}",
00508                             props->props[i].name,
00509                             s_val
00510                             );
00511         if (len >= sizeof(s_prop)-1) {
00512             DXDBG( "UPDATE_DEVICE: prop is over  MAX LEN");
00513             return false;
00514         }
00515         if (len + strlen(message) >= sizeof(message)-1) {
00516             DXDBG( "UPDATE_DEVICE: message is over  MAX LEN");
00517             return false;
00518         }
00519         strcat( message, s_prop );
00520         
00521         if (i+1 < props->numofprops) {
00522             if (1 + strlen(message) >= sizeof(message)-1) {
00523                 DXDBG( "UPDATE_DEVICE: message is over  MAX LEN");
00524                 return false;
00525             }
00526             strncat( message, ",", sizeof(message) );
00527         }
00528     }
00529 
00530     if (2 + strlen(message) >= sizeof(message)-1) {
00531         DXDBG( "UPDATE_DEVICE: message is over  MAX LEN");
00532         return false;
00533     }
00534     strcat( message, "}}" );
00535 
00536     DXDBG("send: %s", message);
00537     m_ws.send(message);
00538 
00539     bool res=true;
00540 /*    
00541     // clear the buffer and wait a sec...
00542     memset( message, 0, sizeof(message));
00543     for (i=0, res=false;i<10;i++) {
00544         wait(0.5f);
00545         if (m_ws.read(message)) {
00546             DXDBG("Get Message(%d): %s", strlen(message), message);
00547             picojson::value v;
00548             std::string err;
00549             picojson::parse(v, (const char *)message, (const char *)(message + strlen(message)), &err);
00550 
00551             if (err.empty())
00552             {
00553                 picojson::object& root = v.get<picojson::object>();
00554                 // check auth response
00555                 if (root["type"].is<std::string>()) {
00556                     if (strcmp(root["type"].get<std::string>().c_str(), "device-update-response")) {
00557                         DXDBG("UPDATE_DEVICE: Not device_update_response");
00558                         break;
00559                     }
00560                 } else {
00561                     DXDBG("UPDATE_DEVICE: there is no type");
00562                     break;
00563                 }
00564                 if (root["message-id"].is<std::string>()) {
00565                     if (strcmp(root["message-id"].get<std::string>().c_str(), mesid)) {
00566                         DXDBG("UPDATE_DEVICE: Not correct response message-id");
00567                         break;
00568                     }
00569                 } else {
00570                     DXDBG("UPDATE_DEVICE: there is no message-id");
00571                     break;
00572                 }
00573                 if (root["status"].is<std::string>()) {
00574                     if (strcmp(root["status"].get<std::string>().c_str(), "200 OK")) {
00575                         DXDBG("UPDATE_DEVICE: status error");
00576                         break;
00577                     }
00578                 } else {
00579                     DXDBG("UPDATE_DEVICE: there is no status");
00580                     break;
00581                 }
00582                 DXDBG("UPDATE_DEVICE: device update is success");
00583                 res = true;
00584             } else {
00585                 DXDBG("UPDATE_DEVICE: Parse Error");
00586             }
00587             break;
00588         }
00589     }
00590 
00591 */
00592     return res;
00593 }
00594 
00595 
00596 // ==============================================
00597 //
00598 // ==============================================
00599 bool DxClient::keepalive_device()
00600 {
00601     DXDBG("Call keepalive_device");
00602     
00603     int  len;
00604     
00605     char message[MAX_MESSAGELEN];
00606     char mesid[MAX_MESSAGEIDLEN];
00607     generate_randomid( mesid, sizeof(mesid) );
00608     len = snprintf(message, sizeof(message), "{" \
00609                     "\"type\":\"keep-alive-request\"," \
00610                     "\"device-id\":\"%s\"," \
00611                     "\"message-id\":\"%s\"" \
00612                     "}",
00613                     m_deviceid,
00614                     mesid
00615                     );
00616     if (len >= sizeof(message)-1) {
00617         DXDBG( "KEEPALIVE_DEVICE: message is over MAX LEN");
00618         return false;
00619     }
00620     DXDBG("send: %s", message);
00621 
00622     m_ws.send(message);
00623 
00624     bool res=true;
00625 /*
00626     int i;
00627     // clear the buffer and wait a sec...
00628     memset( message, 0, sizeof(message));
00629     for (i=0, res=true;i<10;i++) {
00630         wait(0.5f);
00631         if (m_ws.read(message)) {
00632             DXDBG("Get Message: %s\n", message);
00633             picojson::value v;
00634             std::string err;
00635             picojson::parse(v, (const char *)message, (const char *)(message + strlen(message)), &err);
00636 
00637 
00638             if (err.empty())
00639             {
00640                 picojson::object& root = v.get<picojson::object>();
00641                 
00642                 // check auth response
00643                 if (root["type"].is<std::string>()) {
00644                     if (strcmp(root["type"].get<std::string>().c_str(), "keep-alive-response")) {
00645                         DXDBG("KEEPALIVE_DEVICE: Not keep-alive-response\n");
00646                         break;
00647                     }
00648                 } else {
00649                     DXDBG("KEEPALIVE_DEVICE: there is no type\n");
00650                     break;
00651                 }
00652                 if (root["message-id"].is<std::string>()) {
00653                     if (strcmp(root["message-id"].get<std::string>().c_str(), mesid)) {
00654                         DXDBG("KEEPALIVE_DEVICE: Not correct response message-id\n");
00655                         break;
00656                     }
00657                 } else {
00658                     DXDBG("KEEPALIVE_DEVICE: there is no message-id\n");
00659                     break;
00660                 }
00661                 if (root["status"].is<std::string>()) {
00662                     if (strcmp(root["status"].get<std::string>().c_str(), "200 OK")) {
00663                         DXDBG("KEEPALIVE_DEVICE: status error\n");
00664                         break;
00665                     }
00666                 } else {
00667                     DXDBG("KEEPALIVE_DEVICE: there is no status\n");
00668                     break;
00669                 }
00670 
00671                 DXDBG("KEEPALIVE_DEVICE: keep alive is success\n");
00672                 res = true;
00673             } else {
00674                 DXDBG("KEEPALIVE_DEVICE: JSON parse Error\n");
00675             }
00676             break;        
00677         }
00678     }
00679 */
00680     return res;
00681 }
00682 
00683 
00684 // ==============================================
00685 //
00686 // ==============================================
00687 bool DxClient::handle_messages()
00688 {
00689     bool res = true;
00690     
00691     char message[MAX_MESSAGELEN];
00692 
00693     
00694     // clear the buffer and wait a sec...
00695     while(1) {
00696         memset( message, 0, sizeof(message));
00697         if (m_ws.read(message)) {
00698             DXDBG("Get Message(%d): %s", strlen(message), message);
00699             picojson::value v;
00700             std::string err;
00701             picojson::parse(v, (const char *)message, (const char *)(message + strlen(message)), &err);
00702 
00703             if (err.empty())
00704             {
00705                 picojson::object& root = v.get<picojson::object>();
00706                 // check auth response
00707                 if (root["message-id"].is<std::string>()) {
00708                     // no check message-d
00709                 } else {
00710                     DXDBG("HANDLE_MESSAGE: there is no message-id");
00711                     continue;
00712                 }
00713                 if (root["device-id"].is<std::string>()) {
00714                     if (strcmp(root["device-id"].get<std::string>().c_str(), m_deviceid)) {
00715                         DXDBG("HANDLE_MESSAGE: different device-id");
00716                         continue;
00717                     }
00718                 } else {
00719                     DXDBG("HANDLE_MESSAGE: there is no device-id");
00720                     continue;
00721                 }
00722                 
00723                 if (root["type"].is<std::string>()) {
00724                     if (!strcmp(root["type"].get<std::string>().c_str(), "device-get-request")
00725                         || !strcmp(root["type"].get<std::string>().c_str(), "device-set-request")) {
00726                         DXDBG("HANDLE_MESSAGE: recv %s", root["type"].get<std::string>().c_str());
00727 
00728 //                        if ( 1) {
00729                         if(root["props"].is<picojson::object>() ){
00730 //                            picojson::object& props_root = root;
00731                             picojson::object& props_root = root["props"].get<picojson::object>();
00732 
00733                             dx_props ps;
00734                             ps.numofprops = props_root.size();
00735                             DXDBG("HANDLE_MESSAGE: prop size: %d", ps.numofprops);
00736 
00737                             ps.props = (dx_prop*)malloc( sizeof(dx_prop) * ps.numofprops );
00738                             if (ps.props == NULL) {
00739                                 DXDBG("HANDLE_MESSAGE: No memory");
00740                                 continue;
00741                             }
00742                             memset( ps.props, 0, sizeof(dx_prop) * ps.numofprops );
00743 
00744                             dx_prop *pr = ps.props;
00745                             for (picojson::object::const_iterator it = props_root.begin(); it != props_root.end(); it++,pr++) {
00746                                 if (props_root[it->first].is<picojson::object>()) {
00747                                     picojson::object& prop = props_root[it->first].get<picojson::object>();
00748                                     
00749                                     if (prop["value"].is<std::string>()) { // test only
00750                                         snprintf( pr->s_val, sizeof(pr->s_val), "%s", prop["value"].get<std::string>().c_str() );
00751                                     }
00752                                     else if (prop["value"].is<double>()) { // integer or float
00753                                         pr->f_val = prop["value"].get<double>();
00754                                         if ( (int)(pr->f_val) ) {
00755                                             pr->b_val = true;
00756                                         } else {
00757                                             pr->b_val = false;
00758                                         }
00759                                     }
00760                                     else if (prop["value"].is<bool>()) { // integer or float
00761                                         pr->b_val = prop["value"].get<bool>();
00762                                         if(pr->b_val){
00763                                             pr->f_val = 1;
00764                                         } else {
00765                                             pr->f_val = 0;
00766                                         }
00767                                     }
00768                                 }
00769                                 snprintf( pr->name, sizeof(pr->name), "%s", it->first.c_str() );
00770                                 DXDBG("HANDLE_MESSAGE: prop name: %s", pr->name);
00771                             }
00772                             
00773                             if (m_func_get_request && !strcmp(root["type"].get<std::string>().c_str(), "device-get-request")) {
00774                                 if((*m_func_get_request)( &ps )) {
00775                                     dx_device_get_response(&ps, root["message-id"].get<std::string>().c_str());
00776                                 } else {
00777                                     dx_error_response(root["message-id"].get<std::string>().c_str());
00778                                 }
00779                             }
00780                             if (m_func_set_request && !strcmp(root["type"].get<std::string>().c_str(), "device-set-request")) {
00781                                 if((*m_func_set_request)( &ps )) {
00782                                     dx_device_set_response(&ps, root["message-id"].get<std::string>().c_str());
00783                                 } else {
00784                                     dx_error_response(root["message-id"].get<std::string>().c_str());
00785                                 }
00786                             }
00787                             free(ps.props);
00788                             continue;
00789                         } else {
00790                             DXDBG("HANDLE_MESSAGE: no props in request");
00791                         }
00792                         // send error message
00793                         dx_error_response(root["message-id"].get<std::string>().c_str());
00794                     }
00795                     else if (!strcmp(root["type"].get<std::string>().c_str(), "device-update-response")) {
00796                         DXDBG("HANDLE_MESSAGE: recv device-update-response");
00797                     }
00798                     else if (!strcmp(root["type"].get<std::string>().c_str(), "keep-alive-response")) {
00799                         DXDBG("HANDLE_MESSAGE: recv keep-alive-response");
00800 
00801                     }
00802                     else {
00803                         DXDBG("HANDLE_MESSAGE: Unknown message type");
00804                     }
00805                 } else {
00806                     DXDBG("HANDLE_MESSAGE: there is no type");
00807                 }
00808             } else {
00809                 DXDBG("HANDLE_MESSAGE: Parse Error");
00810             }
00811         } else {
00812             break; // no more message
00813         }
00814     }
00815 
00816     return res;
00817 }
00818 
00819 
00820 bool DxClient::dx_error_response( const char* mesid)
00821 {
00822     DXDBG("Call dx_error_response");
00823     
00824     int  len;
00825     char message[MAX_MESSAGELEN];
00826     len = snprintf(message, sizeof(message), "{" \
00827                     "\"device-id\":\"%s\"," \
00828                     "\"message-id\":\"%s\"," \
00829                     "\"status\":\"400 Bad Request\"" \
00830                     "}",
00831                     m_deviceid,
00832                     mesid
00833                     );
00834     if (len >= sizeof(message)-1) {
00835         DXDBG( "ERROR_RESPONSE: message is over MAX LEN");
00836         return false;
00837     }
00838     DXDBG("send: %s", message);
00839     m_ws.send(message);
00840     
00841     return true;
00842 }
00843 
00844 
00845 void DxClient::set_get_requset_handler(REQUEST_HANDLER handler)
00846 {
00847     m_func_get_request = handler;
00848 }
00849 void DxClient::set_set_requset_handler(REQUEST_HANDLER handler)
00850 {
00851     m_func_set_request = handler;
00852 }
00853 
00854 
00855 // ==============================================
00856 //
00857 // ==============================================
00858 bool DxClient::dx_device_get_response( dx_props *props, const char* mesid )
00859 {
00860     DXDBG("Call dx_device_get_response");
00861 
00862     int len;
00863     char message[MAX_MESSAGELEN];
00864 
00865     len = snprintf(message, sizeof(message), "{" \
00866                     "\"type\":\"device-get-response\"," \
00867                     "\"device-id\":\"%s\"," \
00868                     "\"message-id\":\"%s\"," \
00869                     "\"props\":{",
00870                     m_deviceid,
00871                     mesid
00872                     );
00873     if (len >= sizeof(message)-1) {
00874         DXDBG( "DEVICE_GET: message is over  MAX LEN");
00875         return false;
00876     }
00877 
00878     int i;                    
00879     for (i=0;i<props->numofprops;i++) {
00880         char s_prop[MAX_PROPLEN];
00881         char s_val[MAX_PROPSVALLEN];
00882         switch( props->props[i].type ){
00883             case DX_STRING:
00884                 sprintf( s_val, "\"%s\"", props->props[i].s_val );
00885                 break;
00886             case DX_INTEGER:
00887                 sprintf( s_val, "%d", (int)(props->props[i].f_val) );
00888                 break;
00889             case DX_FLOAT:
00890                 sprintf( s_val, "%f", props->props[i].f_val );
00891                 break;
00892             case DX_BOOLEAN:
00893                 sprintf( s_val, "%s", props->props[i].b_val?"true":"false" );
00894                 break;
00895         }
00896         
00897         len = snprintf( s_prop, sizeof(s_prop), "\"%s\": {" \
00898                             "\"value\":%s" \
00899                             "}",
00900                             props->props[i].name,
00901                             s_val
00902                             );
00903         if (len >= sizeof(s_prop)-1) {
00904             DXDBG( "DEVICE_GET: prop is over  MAX LEN");
00905             return false;
00906         }
00907         if (len + strlen(message) >= sizeof(message)-1) {
00908             DXDBG( "DEVICE_GET: message is over  MAX LEN");
00909             return false;
00910         }
00911         strcat( message, s_prop );
00912         
00913         if (i+1 < props->numofprops) {
00914             if (1 + strlen(message) >= sizeof(message)-1) {
00915                 DXDBG( "DEVICE_GET: message is over  MAX LEN");
00916                 return false;
00917             }
00918             strncat( message, ",", sizeof(message) );
00919         }
00920     }
00921 
00922     if (2 + strlen(message) >= sizeof(message)-1) {
00923         DXDBG( "DEVICE_GET: message is over  MAX LEN");
00924         return false;
00925     }
00926     strcat( message, "}}" );
00927 
00928     DXDBG("send: %s", message);
00929     m_ws.send(message);
00930     
00931     return true;
00932 }
00933 
00934 bool DxClient::dx_device_set_response( dx_props *props, const char* mesid )
00935 {
00936     DXDBG("Call dx_device_set_response");
00937     
00938     int  len;
00939     char message[MAX_MESSAGELEN];
00940     len = snprintf(message, sizeof(message), "{" \
00941                     "\"type\":\"device-set-response\"," \
00942                     "\"device-id\":\"%s\"," \
00943                     "\"message-id\":\"%s\"," \
00944                     "\"status\":\"200 OK\"" \
00945                     "}",
00946                     m_deviceid,
00947                     mesid
00948                     );
00949     if (len >= sizeof(message)-1) {
00950         DXDBG( "ERROR_RESPONSE: message is over MAX LEN");
00951         return false;
00952     }
00953     DXDBG("send: %s", message);
00954     m_ws.send(message);
00955     
00956     return true;
00957 }