mbedからGluinサーバへ接続するライブラリです
Diff: DxClient.cpp
- Revision:
- 0:735163979ecf
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/DxClient.cpp Sat Feb 14 00:28:40 2015 +0000 @@ -0,0 +1,957 @@ +#include "DxClient.h" +#include "picojson.h" + +#if 1 +#define DXDBG(x, ...) printf("[DxClient : DBG]"x"\r\n", ##__VA_ARGS__); +#define DXWARN(x, ...) printf("[DxClient : WARN]"x"\r\n", ##__VA_ARGS__); +#define DXERR(x, ...) printf("[DxClient : ERR]"x"\r\n", ##__VA_ARGS__); +#else +#define DXDBG(x, ...) +#define DXWARN(x, ...) +#define DXERR(x, ...) +#endif + +#define DXINFO(x, ...) printf("[DxClient : INFO]"x"\r\n", ##__VA_ARGS__); + +void generate_randomid( char* out, int len ) +{ + int i; + static char* words = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890!#$%&()=<>?-_[]{}"; + for (i=0;i<len-1;i++) { + out[i] = words[ rand()%strlen(words) ]; + } + out[len-1] = 0; +} + +DxClient::DxClient(char * url, char* deviceid, float seed) +{ + m_ws.set_server( url ); + strcpy( m_deviceid, deviceid ); + + memset( m_user, 0, sizeof(m_user)); + memset( m_pass, 0, sizeof(m_pass)); + memset( m_dev_name, 0, sizeof(m_dev_name)); + memset( m_dev_description, 0, sizeof(m_dev_description)); + + m_func_get_request = NULL; + m_func_set_request = NULL; + + DXDBG("random seed is %f", seed ); + srand(seed); +} + + +void DxClient::set_user(char* user, char *pass) +{ + // set auth user and password + strncpy( m_user, user, sizeof(m_user) ); + strncpy( m_pass, pass, sizeof(m_pass) ); +} + +void DxClient::set_device_description(char* desc) +{ + strncpy( m_dev_description, desc, sizeof(m_dev_description) ); +} +void DxClient::set_device_name(char* name) +{ + strncpy( m_dev_name, name, sizeof(m_dev_name) ); +} + + +bool DxClient::connect() +{ + bool res; + res = m_ws.connect(); + if (res) { + DXDBG("Connected to server by Websocket"); + // send user_auth_request + res = dx_user_auth_request(); + if (res) { + DXDBG("...Authorized"); + } else { + DXDBG("...Login failed"); + } + } else { + DXDBG("Failed to server by Websocket"); + } + return res; +} + +bool DxClient::close() +{ + return m_ws.close(); +} + +// ============================================== +// Send user_auth_request to server +// if user is authorized correctly, clinet gets 200 OK response +// this request must be sent before any other requset +// ============================================== +bool DxClient::dx_user_auth_request() +{ + DXDBG("Call dx_user_auth_request"); + + int i, len; + bool res; + + char message[MAX_MESSAGELEN]; + char mesid[MAX_MESSAGEIDLEN]; + generate_randomid( mesid, sizeof(mesid) ); + len = snprintf(message, sizeof(message), "{" \ + "\"type\":\"user-auth-request\"," \ + "\"message-id\":\"%s\"," \ + "\"username\":\"%s\"," \ + "\"password\":\"%s\"" \ + "}", + mesid, + m_user, + m_pass + ); + if (len >= sizeof(message)-1) { + DXDBG( "USER_AUTH: message is over MAX LEN"); + return false; + } + DXDBG("send: %s", message); + + m_ws.send(message); + + // clear the buffer and wait a sec... + memset( message, 0, sizeof(message)); + for (i=0, res=false;i<10;i++) { + wait(0.5f); + if (m_ws.read(message)) { + DXDBG("Get Message: %s\n", message); + picojson::value v; + std::string err; + picojson::parse(v, (const char *)message, (const char *)(message + strlen(message)), &err); + + + if (err.empty()) + { + picojson::object& root = v.get<picojson::object>(); + + // check auth response + if (root["type"].is<std::string>()) { + if (strcmp(root["type"].get<std::string>().c_str(), "user-auth-response")) { + DXDBG("USER_AUTH: Not user_auth_response\n"); + break; + } + } else { + DXDBG("USER_AUTH: there is no type\n"); + break; + } + if (root["message-id"].is<std::string>()) { + if (strcmp(root["message-id"].get<std::string>().c_str(), mesid)) { + DXDBG("USER_AUTH: Not correct response message-id\n"); + break; + } + } else { + DXDBG("USER_AUTH: there is no message-id\n"); + break; + } + if (root["status"].is<std::string>()) { + if (strcmp(root["status"].get<std::string>().c_str(), "200 OK")) { + DXDBG("USER_AUTH: status error\n"); + break; + } + } else { + DXDBG("USER_AUTH: there is no status\n"); + break; + } + + DXDBG("USER_AUTH: user auth is success\n"); + res = true; + } else { + DXDBG("USER_AUTH: JSON parse Error\n"); + } + break; + } + } + return res; +} + +char* dx_type_to_string( dx_prop_type type, char* buf) +{ + char *res = buf; + switch( type ) { + case DX_STRING: + sprintf( res, "string" ); + break; + case DX_INTEGER: + sprintf( res, "integer" ); + break; + case DX_FLOAT: + sprintf( res, "float" ); + break; + case DX_BOOLEAN: + sprintf( res, "boolean" ); + break; + default: + sprintf( res, "unknown" ); + break; + } + return res; +} +char* dx_direction_to_string( dx_prop_direction dic, char* buf) +{ + char *res = buf; + switch( dic ) { + case DX_UPONLY: + sprintf( res, "uponly" ); + break; + case DX_DOWNONLY: + sprintf( res, "downonly" ); + break; + case DX_UPDOWN: + sprintf( res, "updown" ); + break; + default: + sprintf( res, "unknown" ); + break; + } + return res; +} +char* dx_mode_to_string( dx_prop_mode mode, char* buf) +{ + char *res = buf; + switch( mode ) { + case DX_READONLY: + sprintf( res, "readonly" ); + break; + case DX_WRITEONLY: + sprintf( res, "writeonly" ); + break; + case DX_READWRITE: + sprintf( res, "readwrite" ); + break; + default: + sprintf( res, "unknown" ); + break; + } + return res; +} + +// ============================================== +// +// ============================================== +bool DxClient::register_device( dx_props *props ) +{ + DXDBG("Call register_device"); + + bool res; + int len; + + char message[MAX_MESSAGELEN]; + char mesid[MAX_MESSAGEIDLEN]; + generate_randomid( mesid, sizeof(mesid) ); + len = snprintf(message, sizeof(message), "{" \ + "\"type\":\"device-register-request\"," \ + "\"device-id\":\"%s\"," \ + "\"message-id\":\"%s\"," \ + "\"name\":\"%s\"," \ + "\"description\":\"%s\"," \ + "\"props\":{", + m_deviceid, + mesid, + m_dev_name, + m_dev_description + ); + if (len >= sizeof(message)-1) { + DXDBG( "REGISTER_DEVICE: message is over MAX LEN"); + return false; + } + + int i; + for (i=0;i<props->numofprops;i++) { + char s_prop[MAX_PROPLEN]; + char s_type[16]; + char s_direction[16]; + char s_mode[16]; + + char s_val[MAX_PROPSVALLEN]; + switch( props->props[i].type ){ + case DX_STRING: + sprintf( s_val, "\"%s\"", props->props[i].s_val ); + break; + case DX_INTEGER: + sprintf( s_val, "%d", (int)(props->props[i].f_val) ); + break; + case DX_FLOAT: + sprintf( s_val, "%f", props->props[i].f_val ); + break; + case DX_BOOLEAN: + sprintf( s_val, "%s", props->props[i].b_val?"true":"false" ); + break; + } + + len = snprintf( s_prop, sizeof(s_prop), "\"%s\": {" \ + "\"value\":%s," \ + "\"type\":\"%s\"," \ + "\"direction\":\"%s\"," \ + "\"mode\":\"%s\"" \ + "}", + props->props[i].name, + s_val, + dx_type_to_string( props->props[i].type, s_type ), + dx_direction_to_string( props->props[i].direction, s_direction ), + dx_mode_to_string( props->props[i].mode, s_mode ) + ); + if (len >= sizeof(s_prop)-1) { + DXDBG( "REGISTER_DEVICE: prop is over MAX LEN"); + return false; + } + if (len + strlen(message) >= sizeof(message)-1) { + DXDBG( "REGISTER_DEVICE: message is over MAX LEN"); + return false; + } + strcat( message, s_prop ); + + if (i+1 < props->numofprops) { + if (1 + strlen(message) >= sizeof(message)-1) { + DXDBG( "REGISTER_DEVICE: message is over MAX LEN"); + return false; + } + strncat( message, ",", sizeof(message) ); + } + } + + if (2 + strlen(message) >= sizeof(message)-1) { + DXDBG( "REGISTER_DEVICE: message is over MAX LEN"); + return false; + } + strcat( message, "}}" ); + + DXDBG("send: %s", message); + m_ws.send(message); + + // clear the buffer and wait a sec... + memset( message, 0, sizeof(message)); + for (i=0, res=false;i<10;i++) { + wait(0.5f); + if (m_ws.read(message)) { + DXDBG("Get Message(%d): %s", strlen(message), message); + picojson::value v; + std::string err; + picojson::parse(v, (const char *)message, (const char *)(message + strlen(message)), &err); + + if (err.empty()) + { + picojson::object& root = v.get<picojson::object>(); + // check auth response + if (root["type"].is<std::string>()) { + if (strcmp(root["type"].get<std::string>().c_str(), "device-register-response")) { + DXDBG("REGISTER_DEVICE: Not device_register_response"); + break; + } + } else { + DXDBG("REGISTER_DEVICE: there is no type"); + break; + } + if (root["message-id"].is<std::string>()) { + if (strcmp(root["message-id"].get<std::string>().c_str(), mesid)) { + DXDBG("REGISTER_DEVICE: Not correct response message-id"); + break; + } + } else { + DXDBG("REGISTER_DEVICE: there is no message-id"); + break; + } + if (root["status"].is<std::string>()) { + if (strcmp(root["status"].get<std::string>().c_str(), "200 OK")) { + DXDBG("REGISTER_DEVICE: status error"); + break; + } + } else { + DXDBG("REGISTER_DEVICE: there is no status"); + break; + } + DXDBG("REGISTER_DEVICE: device register is success"); + res = true; + } else { + DXDBG("REGISTER_DEVICE: Parse Error"); + } + break; + } + } + + return res; +} + +// ============================================== +// +// ============================================== +bool DxClient::deregister_device() +{ + int len; + + char message[MAX_MESSAGELEN]; + char mesid[MAX_MESSAGEIDLEN]; + + generate_randomid( mesid, sizeof(mesid) ); + len = snprintf(message, sizeof(message), "{" \ + "\"type\":\"device-deregister-request\"," \ + "\"device-id\":\"%s\"," \ + "\"message-id\":\"%s\"" \ + "}", + m_deviceid, + mesid + ); + if (len >= sizeof(message)-1) { + DXDBG( "DEREGISTER_DEVICE: message is over MAX LEN"); + return false; + } + + DXDBG("send: %s", message); + m_ws.send(message); + + // clear the buffer and wait a sec... + bool res; + int i; + memset( message, 0, sizeof(message)); + for (i=0, res=false;i<10;i++) { + wait(0.5f); + if (m_ws.read(message)) { + DXDBG("Get Message(%d): %s", strlen(message), message); + picojson::value v; + std::string err; + picojson::parse(v, (const char *)message, (const char *)(message + strlen(message)), &err); + + if (err.empty()) + { + picojson::object& root = v.get<picojson::object>(); + // check auth response + if (root["type"].is<std::string>()) { + if (strcmp(root["type"].get<std::string>().c_str(), "device-deregister-response")) { + DXDBG("DEREGISTER_DEVICE: Not device_deregister_response"); + break; + } + } else { + DXDBG("DEREGISTER_DEVICE: there is no type"); + break; + } + if (root["message-id"].is<std::string>()) { + if (strcmp(root["message-id"].get<std::string>().c_str(), mesid)) { + DXDBG("DEREGISTER_DEVICE: Not correct response message-id"); + break; + } + } else { + DXDBG("REGISTER_DEVICE: there is no message-id"); + break; + } + if (root["status"].is<std::string>()) { + if (strcmp(root["status"].get<std::string>().c_str(), "200 OK")) { + DXDBG("DEREGISTER_DEVICE: status error"); + break; + } + } else { + DXDBG("DEREGISTER_DEVICE: there is no status"); + break; + } + DXDBG("DEREGISTER_DEVICE: device deregister is success"); + res = true; + } else { + DXDBG("DEREGISTER_DEVICE: Parse Error"); + } + break; + } + } + + return res; +} + +// ============================================== +// +// ============================================== +bool DxClient::update_device( dx_props *props ) +{ + int len; + + char message[MAX_MESSAGELEN]; + char mesid[MAX_MESSAGEIDLEN]; + + generate_randomid( mesid, sizeof(mesid) ); + len = snprintf(message, sizeof(message), "{" \ + "\"type\":\"device-update-request\"," \ + "\"device-id\":\"%s\"," \ + "\"message-id\":\"%s\"," \ + "\"props\":{", + m_deviceid, + mesid + ); + if (len >= sizeof(message)-1) { + DXDBG( "UPDATE_DEVICE: message is over MAX LEN"); + return false; + } + + int i; + for (i=0;i<props->numofprops;i++) { + char s_prop[MAX_PROPLEN]; + char s_val[MAX_PROPSVALLEN]; + switch( props->props[i].type ){ + case DX_STRING: + sprintf( s_val, "\"%s\"", props->props[i].s_val ); + break; + case DX_INTEGER: + sprintf( s_val, "%d", (int)(props->props[i].f_val) ); + break; + case DX_FLOAT: + sprintf( s_val, "%f", props->props[i].f_val ); + break; + case DX_BOOLEAN: + sprintf( s_val, "%s", props->props[i].b_val?"true":"false" ); + break; + } + + len = snprintf( s_prop, sizeof(s_prop), "\"%s\": {" \ + "\"value\":%s" \ + "}", + props->props[i].name, + s_val + ); + if (len >= sizeof(s_prop)-1) { + DXDBG( "UPDATE_DEVICE: prop is over MAX LEN"); + return false; + } + if (len + strlen(message) >= sizeof(message)-1) { + DXDBG( "UPDATE_DEVICE: message is over MAX LEN"); + return false; + } + strcat( message, s_prop ); + + if (i+1 < props->numofprops) { + if (1 + strlen(message) >= sizeof(message)-1) { + DXDBG( "UPDATE_DEVICE: message is over MAX LEN"); + return false; + } + strncat( message, ",", sizeof(message) ); + } + } + + if (2 + strlen(message) >= sizeof(message)-1) { + DXDBG( "UPDATE_DEVICE: message is over MAX LEN"); + return false; + } + strcat( message, "}}" ); + + DXDBG("send: %s", message); + m_ws.send(message); + + bool res=true; +/* + // clear the buffer and wait a sec... + memset( message, 0, sizeof(message)); + for (i=0, res=false;i<10;i++) { + wait(0.5f); + if (m_ws.read(message)) { + DXDBG("Get Message(%d): %s", strlen(message), message); + picojson::value v; + std::string err; + picojson::parse(v, (const char *)message, (const char *)(message + strlen(message)), &err); + + if (err.empty()) + { + picojson::object& root = v.get<picojson::object>(); + // check auth response + if (root["type"].is<std::string>()) { + if (strcmp(root["type"].get<std::string>().c_str(), "device-update-response")) { + DXDBG("UPDATE_DEVICE: Not device_update_response"); + break; + } + } else { + DXDBG("UPDATE_DEVICE: there is no type"); + break; + } + if (root["message-id"].is<std::string>()) { + if (strcmp(root["message-id"].get<std::string>().c_str(), mesid)) { + DXDBG("UPDATE_DEVICE: Not correct response message-id"); + break; + } + } else { + DXDBG("UPDATE_DEVICE: there is no message-id"); + break; + } + if (root["status"].is<std::string>()) { + if (strcmp(root["status"].get<std::string>().c_str(), "200 OK")) { + DXDBG("UPDATE_DEVICE: status error"); + break; + } + } else { + DXDBG("UPDATE_DEVICE: there is no status"); + break; + } + DXDBG("UPDATE_DEVICE: device update is success"); + res = true; + } else { + DXDBG("UPDATE_DEVICE: Parse Error"); + } + break; + } + } + +*/ + return res; +} + + +// ============================================== +// +// ============================================== +bool DxClient::keepalive_device() +{ + DXDBG("Call keepalive_device"); + + int len; + + char message[MAX_MESSAGELEN]; + char mesid[MAX_MESSAGEIDLEN]; + generate_randomid( mesid, sizeof(mesid) ); + len = snprintf(message, sizeof(message), "{" \ + "\"type\":\"keep-alive-request\"," \ + "\"device-id\":\"%s\"," \ + "\"message-id\":\"%s\"" \ + "}", + m_deviceid, + mesid + ); + if (len >= sizeof(message)-1) { + DXDBG( "KEEPALIVE_DEVICE: message is over MAX LEN"); + return false; + } + DXDBG("send: %s", message); + + m_ws.send(message); + + bool res=true; +/* + int i; + // clear the buffer and wait a sec... + memset( message, 0, sizeof(message)); + for (i=0, res=true;i<10;i++) { + wait(0.5f); + if (m_ws.read(message)) { + DXDBG("Get Message: %s\n", message); + picojson::value v; + std::string err; + picojson::parse(v, (const char *)message, (const char *)(message + strlen(message)), &err); + + + if (err.empty()) + { + picojson::object& root = v.get<picojson::object>(); + + // check auth response + if (root["type"].is<std::string>()) { + if (strcmp(root["type"].get<std::string>().c_str(), "keep-alive-response")) { + DXDBG("KEEPALIVE_DEVICE: Not keep-alive-response\n"); + break; + } + } else { + DXDBG("KEEPALIVE_DEVICE: there is no type\n"); + break; + } + if (root["message-id"].is<std::string>()) { + if (strcmp(root["message-id"].get<std::string>().c_str(), mesid)) { + DXDBG("KEEPALIVE_DEVICE: Not correct response message-id\n"); + break; + } + } else { + DXDBG("KEEPALIVE_DEVICE: there is no message-id\n"); + break; + } + if (root["status"].is<std::string>()) { + if (strcmp(root["status"].get<std::string>().c_str(), "200 OK")) { + DXDBG("KEEPALIVE_DEVICE: status error\n"); + break; + } + } else { + DXDBG("KEEPALIVE_DEVICE: there is no status\n"); + break; + } + + DXDBG("KEEPALIVE_DEVICE: keep alive is success\n"); + res = true; + } else { + DXDBG("KEEPALIVE_DEVICE: JSON parse Error\n"); + } + break; + } + } +*/ + return res; +} + + +// ============================================== +// +// ============================================== +bool DxClient::handle_messages() +{ + bool res = true; + + char message[MAX_MESSAGELEN]; + + + // clear the buffer and wait a sec... + while(1) { + memset( message, 0, sizeof(message)); + if (m_ws.read(message)) { + DXDBG("Get Message(%d): %s", strlen(message), message); + picojson::value v; + std::string err; + picojson::parse(v, (const char *)message, (const char *)(message + strlen(message)), &err); + + if (err.empty()) + { + picojson::object& root = v.get<picojson::object>(); + // check auth response + if (root["message-id"].is<std::string>()) { + // no check message-d + } else { + DXDBG("HANDLE_MESSAGE: there is no message-id"); + continue; + } + if (root["device-id"].is<std::string>()) { + if (strcmp(root["device-id"].get<std::string>().c_str(), m_deviceid)) { + DXDBG("HANDLE_MESSAGE: different device-id"); + continue; + } + } else { + DXDBG("HANDLE_MESSAGE: there is no device-id"); + continue; + } + + if (root["type"].is<std::string>()) { + if (!strcmp(root["type"].get<std::string>().c_str(), "device-get-request") + || !strcmp(root["type"].get<std::string>().c_str(), "device-set-request")) { + DXDBG("HANDLE_MESSAGE: recv %s", root["type"].get<std::string>().c_str()); + +// if ( 1) { + if(root["props"].is<picojson::object>() ){ +// picojson::object& props_root = root; + picojson::object& props_root = root["props"].get<picojson::object>(); + + dx_props ps; + ps.numofprops = props_root.size(); + DXDBG("HANDLE_MESSAGE: prop size: %d", ps.numofprops); + + ps.props = (dx_prop*)malloc( sizeof(dx_prop) * ps.numofprops ); + if (ps.props == NULL) { + DXDBG("HANDLE_MESSAGE: No memory"); + continue; + } + memset( ps.props, 0, sizeof(dx_prop) * ps.numofprops ); + + dx_prop *pr = ps.props; + for (picojson::object::const_iterator it = props_root.begin(); it != props_root.end(); it++,pr++) { + if (props_root[it->first].is<picojson::object>()) { + picojson::object& prop = props_root[it->first].get<picojson::object>(); + + if (prop["value"].is<std::string>()) { // test only + snprintf( pr->s_val, sizeof(pr->s_val), "%s", prop["value"].get<std::string>().c_str() ); + } + else if (prop["value"].is<double>()) { // integer or float + pr->f_val = prop["value"].get<double>(); + if ( (int)(pr->f_val) ) { + pr->b_val = true; + } else { + pr->b_val = false; + } + } + else if (prop["value"].is<bool>()) { // integer or float + pr->b_val = prop["value"].get<bool>(); + if(pr->b_val){ + pr->f_val = 1; + } else { + pr->f_val = 0; + } + } + } + snprintf( pr->name, sizeof(pr->name), "%s", it->first.c_str() ); + DXDBG("HANDLE_MESSAGE: prop name: %s", pr->name); + } + + if (m_func_get_request && !strcmp(root["type"].get<std::string>().c_str(), "device-get-request")) { + if((*m_func_get_request)( &ps )) { + dx_device_get_response(&ps, root["message-id"].get<std::string>().c_str()); + } else { + dx_error_response(root["message-id"].get<std::string>().c_str()); + } + } + if (m_func_set_request && !strcmp(root["type"].get<std::string>().c_str(), "device-set-request")) { + if((*m_func_set_request)( &ps )) { + dx_device_set_response(&ps, root["message-id"].get<std::string>().c_str()); + } else { + dx_error_response(root["message-id"].get<std::string>().c_str()); + } + } + free(ps.props); + continue; + } else { + DXDBG("HANDLE_MESSAGE: no props in request"); + } + // send error message + dx_error_response(root["message-id"].get<std::string>().c_str()); + } + else if (!strcmp(root["type"].get<std::string>().c_str(), "device-update-response")) { + DXDBG("HANDLE_MESSAGE: recv device-update-response"); + } + else if (!strcmp(root["type"].get<std::string>().c_str(), "keep-alive-response")) { + DXDBG("HANDLE_MESSAGE: recv keep-alive-response"); + + } + else { + DXDBG("HANDLE_MESSAGE: Unknown message type"); + } + } else { + DXDBG("HANDLE_MESSAGE: there is no type"); + } + } else { + DXDBG("HANDLE_MESSAGE: Parse Error"); + } + } else { + break; // no more message + } + } + + return res; +} + + +bool DxClient::dx_error_response( const char* mesid) +{ + DXDBG("Call dx_error_response"); + + int len; + char message[MAX_MESSAGELEN]; + len = snprintf(message, sizeof(message), "{" \ + "\"device-id\":\"%s\"," \ + "\"message-id\":\"%s\"," \ + "\"status\":\"400 Bad Request\"" \ + "}", + m_deviceid, + mesid + ); + if (len >= sizeof(message)-1) { + DXDBG( "ERROR_RESPONSE: message is over MAX LEN"); + return false; + } + DXDBG("send: %s", message); + m_ws.send(message); + + return true; +} + + +void DxClient::set_get_requset_handler(REQUEST_HANDLER handler) +{ + m_func_get_request = handler; +} +void DxClient::set_set_requset_handler(REQUEST_HANDLER handler) +{ + m_func_set_request = handler; +} + + +// ============================================== +// +// ============================================== +bool DxClient::dx_device_get_response( dx_props *props, const char* mesid ) +{ + DXDBG("Call dx_device_get_response"); + + int len; + char message[MAX_MESSAGELEN]; + + len = snprintf(message, sizeof(message), "{" \ + "\"type\":\"device-get-response\"," \ + "\"device-id\":\"%s\"," \ + "\"message-id\":\"%s\"," \ + "\"props\":{", + m_deviceid, + mesid + ); + if (len >= sizeof(message)-1) { + DXDBG( "DEVICE_GET: message is over MAX LEN"); + return false; + } + + int i; + for (i=0;i<props->numofprops;i++) { + char s_prop[MAX_PROPLEN]; + char s_val[MAX_PROPSVALLEN]; + switch( props->props[i].type ){ + case DX_STRING: + sprintf( s_val, "\"%s\"", props->props[i].s_val ); + break; + case DX_INTEGER: + sprintf( s_val, "%d", (int)(props->props[i].f_val) ); + break; + case DX_FLOAT: + sprintf( s_val, "%f", props->props[i].f_val ); + break; + case DX_BOOLEAN: + sprintf( s_val, "%s", props->props[i].b_val?"true":"false" ); + break; + } + + len = snprintf( s_prop, sizeof(s_prop), "\"%s\": {" \ + "\"value\":%s" \ + "}", + props->props[i].name, + s_val + ); + if (len >= sizeof(s_prop)-1) { + DXDBG( "DEVICE_GET: prop is over MAX LEN"); + return false; + } + if (len + strlen(message) >= sizeof(message)-1) { + DXDBG( "DEVICE_GET: message is over MAX LEN"); + return false; + } + strcat( message, s_prop ); + + if (i+1 < props->numofprops) { + if (1 + strlen(message) >= sizeof(message)-1) { + DXDBG( "DEVICE_GET: message is over MAX LEN"); + return false; + } + strncat( message, ",", sizeof(message) ); + } + } + + if (2 + strlen(message) >= sizeof(message)-1) { + DXDBG( "DEVICE_GET: message is over MAX LEN"); + return false; + } + strcat( message, "}}" ); + + DXDBG("send: %s", message); + m_ws.send(message); + + return true; +} + +bool DxClient::dx_device_set_response( dx_props *props, const char* mesid ) +{ + DXDBG("Call dx_device_set_response"); + + int len; + char message[MAX_MESSAGELEN]; + len = snprintf(message, sizeof(message), "{" \ + "\"type\":\"device-set-response\"," \ + "\"device-id\":\"%s\"," \ + "\"message-id\":\"%s\"," \ + "\"status\":\"200 OK\"" \ + "}", + m_deviceid, + mesid + ); + if (len >= sizeof(message)-1) { + DXDBG( "ERROR_RESPONSE: message is over MAX LEN"); + return false; + } + DXDBG("send: %s", message); + m_ws.send(message); + + return true; +}