BaseLib::PVariable PhpVariableConverter::getVariable(zval* value) { try { BaseLib::PVariable variable; if(!value) return variable; if(Z_TYPE_P(value) == IS_LONG) { variable.reset(new BaseLib::Variable((int32_t)Z_LVAL_P(value))); } else if(Z_TYPE_P(value) == IS_DOUBLE) { variable.reset(new BaseLib::Variable((double)Z_DVAL_P(value))); } else if(Z_TYPE_P(value) == IS_TRUE) { variable.reset(new BaseLib::Variable(true)); } else if(Z_TYPE_P(value) == IS_FALSE) { variable.reset(new BaseLib::Variable(false)); } else if(Z_TYPE_P(value) == IS_STRING) { if(Z_STRLEN_P(value) > 0) variable.reset(new BaseLib::Variable(std::string(Z_STRVAL_P(value), Z_STRLEN_P(value)))); else variable.reset(new BaseLib::Variable(std::string(""))); } else if(Z_TYPE_P(value) == IS_ARRAY) { zval* element = nullptr; HashTable* ht = Z_ARRVAL_P(value); zend_string* key = nullptr; ulong keyIndex = 0; ZEND_HASH_FOREACH_KEY_VAL(ht, keyIndex, key, element) { if(!element) continue; if(!variable) { if(key) variable.reset(new BaseLib::Variable(BaseLib::VariableType::tStruct)); else variable.reset(new BaseLib::Variable(BaseLib::VariableType::tArray)); } BaseLib::PVariable arrayElement = getVariable(element); if(!arrayElement) continue; if(key) { std::string keyName; keyName = std::string(key->val, key->len); variable->structValue->insert(BaseLib::StructElement(keyName, arrayElement)); } else variable->arrayValue->push_back(arrayElement); } ZEND_HASH_FOREACH_END(); } else { variable.reset(new BaseLib::Variable(std::string(""))); } return variable; }
void MQTT::messageReceived(std::vector<char>& message) { try { BaseLib::PVariable result = _jsonDecoder->decode(message); std::string methodName; std::string clientId; int32_t messageId = 0; BaseLib::PVariable parameters; if(result->type == BaseLib::VariableType::tStruct) { if(result->structValue->find("method") == result->structValue->end()) { _out.printWarning("Warning: Could not decode JSON RPC packet from MQTT payload."); return; } methodName = result->structValue->at("method")->stringValue; if(result->structValue->find("id") != result->structValue->end()) messageId = result->structValue->at("id")->integerValue; if(result->structValue->find("clientid") != result->structValue->end()) clientId = result->structValue->at("clientid")->stringValue; if(result->structValue->find("params") != result->structValue->end()) parameters = result->structValue->at("params"); else parameters.reset(new BaseLib::Variable()); } else { _out.printWarning("Warning: Could not decode MQTT RPC packet."); return; } GD::out.printInfo("Info: MQTT RPC call received. Method: " + methodName); BaseLib::PVariable response = GD::rpcServers.begin()->second.callMethod(methodName, parameters); std::shared_ptr<std::pair<std::string, std::vector<char>>> responseData(new std::pair<std::string, std::vector<char>>()); _jsonEncoder->encodeMQTTResponse(methodName, response, messageId, responseData->second); responseData->first = (!clientId.empty()) ? clientId + "/rpcResult" : "rpcResult"; queueMessage(responseData); } catch(const std::exception& ex) { _out.printEx(__FILE__, __LINE__, __PRETTY_FUNCTION__, ex.what()); } catch(BaseLib::Exception& ex) { _out.printEx(__FILE__, __LINE__, __PRETTY_FUNCTION__, ex.what()); } catch(...) { _out.printEx(__FILE__, __LINE__, __PRETTY_FUNCTION__); } }