JD2022-TU1/main/extern/Hue/libhuestream/huestream/connect/FullConfigRetriever.cpp

215 lines
5.8 KiB
C++

/*******************************************************************************
Copyright © 2017 Philips Lighting Holding B.V.
All Rights Reserved.
********************************************************************************/
#include <algorithm>
#include "FullConfigRetriever.h"
namespace huestream {
#define CLIP_ERROR_TYPE_UNAUTHORIZED_USER 1
FullConfigRetriever::FullConfigRetriever(const shared_ptr<IHttp> http) : _http(http), _currentlyStreamingUsername("") {
}
void FullConfigRetriever::Execute(BridgePtr bridge, RetrieveCallbackHandler cb) {
_bridge = bridge;
_cb = cb;
if (!GetFullConfig()) {
_cb(OPERATION_FAILED, _bridge);
return;
}
if (!ParseToJson()) {
_cb(OPERATION_FAILED, _bridge);
return;
}
if (!CheckForNoErrorsInResponse()) {
_cb(OPERATION_FAILED, _bridge);
return;
}
if (!ParseConfig()) {
_cb(OPERATION_FAILED, _bridge);
return;
}
ParseGroups();
_cb(OPERATION_SUCCESS, _bridge);
}
bool FullConfigRetriever::GetFullConfig() {
string _baseUrl = "http://" + _bridge->GetIpAddress() + "/api/" + _bridge->GetUser() + "/";
string fullConfigUrl = _baseUrl;
auto req = std::make_shared<HttpRequestInfo>(HTTP_REQUEST_GET, fullConfigUrl);
_http->Execute(req);
if (req->GetSuccess()) {
_response = req->GetResponse();
} else {
_bridge->SetIsValidIp(false);
}
return req->GetSuccess();
}
bool FullConfigRetriever::ParseToJson() {
JSONNode n = libjson::parse(_response);
if (n.type() == JSON_NULL) {
_bridge->SetIsValidIp(false);
return false;
}
_root = n;
return true;
}
bool FullConfigRetriever::CheckForNoErrorsInResponse() const {
bool hasError = false;
bool hasUnauthorizedError = false;
if (_root.type() == JSON_ARRAY) {
for (auto it = _root.begin(); it != _root.end(); ++it) {
auto entry = it->find("error");
if (entry != it->end()) {
hasError = true;
auto i = entry->find("type");
if (i != entry->end()) {
if (i->as_int() == CLIP_ERROR_TYPE_UNAUTHORIZED_USER) {
hasUnauthorizedError = true;
}
}
break;
}
}
}
if (hasError) {
if (hasUnauthorizedError) {
_bridge->SetIsAuthorized(false);
_bridge->SetIsValidIp(true);
} else {
_bridge->SetIsValidIp(false);
}
return false;
}
return true;
}
bool FullConfigRetriever::ParseConfig() const {
if (!SerializerHelper::IsAttributeSet(&_root, "config")) {
_bridge->SetIsValidIp(false);
return false;
}
JSONNode config = (_root)["config"];
string name = "";
Serializable::DeserializeValue(&config, "name", &name, "");
_bridge->SetName(name);
string modelid = "";
Serializable::DeserializeValue(&config, "modelid", &modelid, "");
_bridge->SetModelId(modelid);
string swversion = "";
Serializable::DeserializeValue(&config, "swversion", &swversion, "");
_bridge->SetSoftwareVersion(swversion);
string apiversion = "";
Serializable::DeserializeValue(&config, "apiversion", &apiversion, "");
_bridge->SetApiversion(apiversion);
string bridgeid = "";
Serializable::DeserializeValue(&config, "bridgeid", &bridgeid, "");
_bridge->SetId(bridgeid);
if (!SerializerHelper::IsAttributeSet(&_root, "groups")) {
_bridge->SetIsValidIp(false);
return false;
}
_bridge->SetIsValidIp(true);
return true;
}
void FullConfigRetriever::ParseGroups() {
JSONNode groups = (_root)["groups"];
auto parsedGroups = std::make_shared<GroupList>();
for (auto jsonGroup = groups.begin(); jsonGroup != groups.end(); ++jsonGroup) {
if (GroupIsEntertainment(*jsonGroup) && GroupIsClassTv(*jsonGroup)) {
auto group = ParseEntertainmentGroup(*jsonGroup);
parsedGroups->push_back(group);
}
}
_bridge->SetGroups(parsedGroups);
}
bool FullConfigRetriever::GroupIsEntertainment(const JSONNode& j) {
return (SerializerHelper::IsAttributeSet(&j, "type") && j["type"].as_string() == "Entertainment");
}
bool FullConfigRetriever::GroupIsClassTv(const JSONNode& j) {
return (SerializerHelper::IsAttributeSet(&j, "class") && j["class"].as_string() == "TV");
}
shared_ptr<Group> FullConfigRetriever::ParseEntertainmentGroup(const JSONNode& node) {
auto groupId = std::stoi(node.name());
auto group = std::make_shared<Group>();
group->SetId(groupId);
string name = "";
Serializable::DeserializeValue(&node, "name", &name, "");
group->SetName(name);
ParseLightsAndLocations(node, group);
ParseStreamActive(node, group);
return group;
}
void FullConfigRetriever::ParseLightsAndLocations(const JSONNode& node, GroupPtr group) const {
if (SerializerHelper::IsAttributeSet(&node, "locations")) {
auto locations = node["locations"];
for (auto i = locations.begin(); i != locations.end(); ++i) {
auto lightId = std::stoi(i->name());
auto coordinates = *i;
group->AddLight(lightId, coordinates[0].as_float(), coordinates[1].as_float());
}
}
}
void FullConfigRetriever::ParseStreamActive(const JSONNode& node, GroupPtr group) {
if (SerializerHelper::IsAttributeSet(&node, "stream")) {
auto stream = node["stream"];
if (SerializerHelper::IsAttributeSet(&stream, "active") && SerializerHelper::IsAttributeSet(&stream, "owner")) {
auto active = stream["active"].as_bool();
group->SetActive(active);
if (active) {
auto owner = stream["owner"].as_string();
group->SetOwner(owner);
group->SetFriendlyOwnerName(GetFriendlyName(owner));
}
}
}
}
std::string FullConfigRetriever::GetFriendlyName(std::string userName) {
std::string name = "";
JSONNode config = (_root)["config"];
if (SerializerHelper::IsAttributeSet(&config, "whitelist")) {
JSONNode whitelist = (config)["whitelist"];
if (SerializerHelper::IsAttributeSet(&whitelist, userName)) {
JSONNode user = (whitelist)[userName];
Serializable::DeserializeValue(&user, "name", &name, "");
}
}
return name;
}
}