diff --git a/hueplusplus/Hue.cpp b/hueplusplus/Hue.cpp index 121ea48..9d260fb 100755 --- a/hueplusplus/Hue.cpp +++ b/hueplusplus/Hue.cpp @@ -19,9 +19,11 @@ #include "include/Hue.h" +#include +#include #include #include -#include +#include #include #include @@ -39,15 +41,8 @@ HueFinder::HueFinder(std::shared_ptr handler) std::vector HueFinder::FindBridges() const { UPnP uplug; std::vector> foundDevices = - uplug.getDevices(http_handler); + uplug.getDevices(http_handler); - // Does not work - std::regex manufRegex( - "Royal Philips Electronics"); - std::regex manURLRegex( - "http://www\\.philips\\.com"); - std::regex modelRegex("Philips hue bridge[^<]*"); - std::regex serialRegex("(\\w+)"); std::vector foundBridges; for (const std::pair &p : foundDevices) { size_t found = p.second.find("IpBridge"); @@ -57,18 +52,12 @@ std::vector HueFinder::FindBridges() const { size_t length = p.first.find(":", start) - start; bridge.ip = p.first.substr(start, length); std::string desc = http_handler->GETString( - "/description.xml", "application/xml", "", bridge.ip); - std::smatch matchResult; - if (std::regex_search(desc, manufRegex) && - std::regex_search(desc, manURLRegex) && - std::regex_search(desc, modelRegex) && - std::regex_search(desc, matchResult, serialRegex)) { - // The string matches - // Get 1st submatch (0 is whole match) - bridge.mac = matchResult[1].str(); + "/description.xml", "application/xml", "", bridge.ip); + std::string mac = ParseDescription(desc); + if (!mac.empty()) { + bridge.mac = NormalizeMac(mac); foundBridges.push_back(std::move(bridge)); } - // break; } } return foundBridges; @@ -113,6 +102,28 @@ std::string HueFinder::NormalizeMac(std::string input) { return input; } +std::string HueFinder::ParseDescription(const std::string & description) +{ + const char* manufacturer = "Royal Philips Electronics"; + const char* manURL = "http://www.philips.com"; + const char* model = "Philips hue bridge"; + const char* serialBegin = ""; + const char* serialEnd = ""; + if (description.find(manufacturer) != std::string::npos && description.find(manURL) != std::string::npos + && description.find(model) != std::string::npos) { + std::size_t begin = description.find(serialBegin); + std::size_t end = description.find(serialEnd, begin); + if (begin != std::string::npos && end != std::string::npos) { + begin += std::strlen(serialBegin); + if (begin < description.size()) { + std::string result = description.substr(begin, end); + return result; + } + } + } + return std::string(); +} + Hue::Hue(const std::string &ip, const std::string &username, std::shared_ptr handler) : ip(ip), username(username), http_handler(std::move(handler)), diff --git a/hueplusplus/include/Hue.h b/hueplusplus/include/Hue.h index 65fd176..8391e7d 100755 --- a/hueplusplus/include/Hue.h +++ b/hueplusplus/include/Hue.h @@ -86,9 +86,16 @@ private: //! \returns \p input without separators and whitespace, in upper case. static std::string NormalizeMac(std::string input); + //! \brief Parses mac address from description.xml + //! + //! \param description Content of description.xml file as returned by GET request. + //! \returns Content of xml element \c serialNumber if description matches a Hue bridge, + //! otherwise an empty string. + static std::string ParseDescription(const std::string& description); + std::map - usernames; //!< Maps all macs to usernames added by \ref - //!< HueFinder::AddUsername + usernames; //!< Maps all macs to usernames added by \ref + //!< HueFinder::AddUsername std::shared_ptr http_handler; };