diff --git a/ocs/note.md b/ocs/note.md index 3073ee6..ac632c2 100644 --- a/ocs/note.md +++ b/ocs/note.md @@ -78,3 +78,527 @@ scp -o "BatchMode=no" -o "StrictHostKeyChecking=no" -i pass.txt /usr/bin/ocs_lin + + + +//http.cpp +// smbus_http.cpp +#include "smbus_http.h" +#include +#include +#include + +#include "lt_config.h" +#define CONFIG_ENABLE_EXP_REMAP (config_.exp_remap) +#define CONFIG_ENABLE_TRACE (config_.trace_payload) + +static std::map static_exp_map_ = {{2, 1}, {4, 2}, {6, 3}, {8, 4}}; +static std::map headers_ = { + {"Content-Type", "application/json"}, + {"Accept", "application/json"} +}; +#define PRINT(...) do {\ + if (CONFIG_ENABLE_TRACE) printf(__VA_ARGS__); \ +} while (0) + +SmbusHttp::SmbusHttp(const struct http_t& config, const std::string& token) : config_(config), token_(token) +{ + http_helper_ = std::make_unique(config_.user, config_.pswd); + + if (CONFIG_ENABLE_EXP_REMAP) exp_map_ = static_exp_map_; +} + +std::vector SmbusHttp::string_to_bytes(const std::string& hexString) +{ + std::vector bytes; + if (hexString.length() % 2 != 0) return bytes; // 返回空vector,表示无效输入 + + bytes.reserve(hexString.length() / 2); + for (size_t i = 0; i < hexString.length(); i += 2) + { + std::string byteString = hexString.substr(i, 2); + uint8_t byte = static_cast(std::stoi(byteString, nullptr, 16)); + bytes.push_back(byte); + } + return bytes; +} + +std::string SmbusHttp::build_user_pwd() +{ + std::ostringstream json; + json << "{"; + json << "\"UserName\":\"" << config_.user << "\","; + json << "\"Password\":\"" << config_.pswd << "\""; + json << "}"; + return json.str(); +} + +std::string SmbusHttp::build_get_register_json(int exp_id, int cmd_id, int read_len) +{ + std::ostringstream json; + json << "{"; + json << "\"ExpanderId\":" << exp_id << ","; + json << "\"CmdId\":" << cmd_id << ","; + json << "\"ReadLen\":" << read_len; + json << "}"; + return json.str(); +} + +std::string SmbusHttp::build_set_register_json(int exp_id, int cmd_id, int write_len, const std::string& value) +{ + std::ostringstream json; + json << "{"; + json << "\"ExpanderId\":" << exp_id << ","; + json << "\"CmdId\":" << cmd_id << ","; + json << "\"WriteLen\":" << write_len << ","; + json << "\"Value\":\"" << value << "\""; + json << "}"; + return json.str(); +} + +std::string SmbusHttp::build_get_base_info_json(int exp_id, int addr, int read_len) +{ + std::ostringstream json; + json << "{"; + json << "\"ExpanderId\":" << exp_id << ","; + json << "\"Addr\":" << addr << ","; + json << "\"ReadLen\":" << read_len; + json << "}"; + return json.str(); +} + +int SmbusHttp::get_register(int exp_id, int cmd_id, int read_len, std::vector& bytes) +{ + exp_id = remap(exp_id); + + std::string url = config_.host + config_.get_register; + std::string json_payload = build_get_register_json(exp_id, cmd_id, read_len); + + PRINT("get_register:\nurl: %s\n", url.c_str()); + PRINT("Payload: %s\n", json_payload.c_str()); + + std::string response_str = http_helper_->post(url, json_payload, headers_, true); + + PRINT("Response: %s\n", response_str.c_str()); + + if (!response_str.empty()) + { + auto result = parse_response(response_str); + if (result.first == 0) + { + bytes = string_to_bytes(result.second); + return 0; + } + else + { + std::cerr << __PRETTY_FUNCTION__ << " failed, Code: " << result.first << ", Desc:" << result.second << std::endl; + exit(1); + } + } + + return -1; +} + +int SmbusHttp::set_register(int exp_id, int cmd_id, int write_len, const std::vector& value) +{ + exp_id = remap(exp_id); + std::string url = config_.host + config_.set_register; + + std::string hexString(value.size() * 2, '0'); + for (size_t i = 0; i < value.size(); ++i) + sprintf(&hexString[i * 2], "%02X", value[i]); + + std::string json_payload = build_set_register_json(exp_id, cmd_id, write_len, hexString); + + PRINT("set_register\nurl: %s\n", url.c_str()); + PRINT("Payload: %s\n", json_payload.c_str()); + + std::string response_str = http_helper_->post(url, json_payload, headers_, true); + + PRINT("Response: %s\n", response_str.c_str()); + + if (!response_str.empty()) + { + auto result = parse_response(response_str); + if (result.first == 0) + { + return 0; + } + else + { + std::cerr << __PRETTY_FUNCTION__ << " failed, Code: " << result.first << ", Desc:" << result.second << std::endl; + exit(1); + } + } + + return -1; +} + +int SmbusHttp::get_fru(int exp_id, uint8_t addr, int num, std::vector& bytes) +{ + exp_id = remap(exp_id); + + std::string url = config_.host + config_.get_fru; + std::string json_payload = build_get_base_info_json(exp_id, static_cast(addr), num); + + PRINT("get_fru\nurl: %s\n", url.c_str()); + PRINT("Payload: %s\n", json_payload.c_str()); + + std::string response_str = http_helper_->post(url, json_payload, headers_, true); + + PRINT("Response: %s\n", response_str.c_str()); + + if (!response_str.empty()) + { + auto result = parse_response(response_str); + if (result.first == 0) + { + return 0; + } + else + { + std::cerr << __PRETTY_FUNCTION__ << " failed, Code: " << result.first << ", Desc:" << result.second << std::endl; + exit(1); + } + } + if (!response_str.empty()) + { + auto result = parse_response(response_str); + if (result.first == 0) + { + bytes = string_to_bytes(result.second); + return 0; + } + else + { + std::cerr << __PRETTY_FUNCTION__ << " failed, Code: " << result.first << ", Desc:" << result.second << std::endl; + exit(1); + } + } + + return -1; +} + +SmbusHttpBiren::SmbusHttpBiren(const struct http_t& config, const std::string& token) : SmbusHttp(config, token) +{ + if (0 == token_.length()) + { + token_ = get_token(); + }\ + if (token_.length()) http_helper_->set_token(token_); +} + +int SmbusHttpBiren::lock(int exp_id, int seconds) +{ + exp_id = remap(exp_id); + std::string url = config_.host + config_.access_lock; + + std::string json_payload = build_lock(exp_id); + + PRINT("lock\nurl: %s\n", url.c_str()); + PRINT("Payload: %s\n", json_payload.c_str()); + + std::string response_str = http_helper_->post(url, json_payload, headers_, true); + + PRINT("Response: %s\n", response_str.c_str()); + + if (!response_str.empty()) + { + auto result = parse_response(response_str); + if (result.first == 0) + { + return 0; + } + else + { + std::cerr << __PRETTY_FUNCTION__ << " failed, Code: " << result.first << ", Desc:" << result.second << std::endl; + exit(1); + } + } + + return -1; +} + +int SmbusHttpBiren::unlock(int exp_id) +{ + exp_id = remap(exp_id); + std::string url = config_.host + config_.access_unlock; + + std::string json_payload = build_unlock(exp_id); + + PRINT("unlock\nurl: %s\n", url.c_str()); + PRINT("Payload: %s\n", json_payload.c_str()); + + std::string response_str = http_helper_->post(url, json_payload, headers_, true); + + PRINT("Response: %s\n", response_str.c_str()); + + if (!response_str.empty()) + { + auto result = parse_response(response_str); + if (result.first == 0) + { + return 0; + } + else + { + std::cerr << __PRETTY_FUNCTION__ << " failed, Code: " << result.first << ", Desc:" << result.second << std::endl; + exit(1); + } + } + + return -1; +} + +std::string SmbusHttpBiren::build_lock(int exp_id) +{ + std::ostringstream json; + json << "{"; + json << "\"ExpanderId\":" << exp_id; + json << "}"; + return json.str(); +} +std::string SmbusHttpBiren::build_unlock(int exp_id) +{ + std::ostringstream json; + json << "{"; + json << "\"ExpanderId\":" << exp_id; + json << "}"; + return json.str(); +} + +std::pair SmbusHttpBiren::parse_response(const std::string& response) +{ + int CompletionCode = -1; + json j = json::parse(response); + if (j.contains("Status")) + { + if ("OK" == j["Status"].get()) + { + if (j.contains("Data") && j["Data"].contains("Value")) + return std::make_pair(0, j["Data"]["Value"].get()); + return std::make_pair(0, ""); + } + } + return std::make_pair(CompletionCode, "Invalid Response"); +} + +std::pair SmbusHttpBiren::parse_token(const std::string& response) +{ + int CompletionCode = -1; + json j = json::parse(response); + if (j.contains("X-Auth-Token")) + { + CompletionCode = 0; + return std::make_pair(CompletionCode, j["X-Auth-Token"].get()); + } + return std::make_pair(CompletionCode, "Invalid Response"); +} + +int SmbusHttpBiren::remap(int exp_id) +{ + if (!token_.empty() && !exp_map_.empty()) + { + auto it = exp_map_.find(exp_id); + if (it != exp_map_.end()) return it->second; + } + return exp_id; +} + +std::string SmbusHttpBiren::get_token() +{ + std::string url = config_.host + config_.get_token; + std::string json_payload = build_user_pwd(); + + PRINT("get_token:\nurl: %s\n", url.c_str()); + PRINT("Payload: %s\n", json_payload.c_str()); + + std::string response_str = http_helper_->post(url, json_payload, headers_, true, true); + + PRINT("Response: %s\n", response_str.c_str()); + + if (!response_str.empty()) + { + auto result = parse_token(response_str); + if (result.first == 0) + { + return result.second; + } + else + { + std::cerr << __PRETTY_FUNCTION__ << " failed, Code: " << result.first << ", Desc:" << result.second << std::endl; + exit(1); + } + } + + return ""; +} + +int SmbusHttpH3C::lock(int exp_id, int seconds) +{ + exp_id = remap(exp_id); + + std::string url = config_.host + config_.access_lock; + std::string json_payload = build_lock(exp_id, seconds); + + PRINT("lock\nurl: %s\n", url.c_str()); + PRINT("Payload: %s\n", json_payload.c_str()); + + std::string response_str = http_helper_->post(url, json_payload, headers_, true); + + PRINT("Response: %s\n", response_str.c_str()); + + if (!response_str.empty()) + { + auto result = parse_response(response_str); + if (result.first == 0) + { + return 0; + } + else + { + std::cerr << __PRETTY_FUNCTION__ << " failed, Code: " << result.first << ", Desc:" << result.second << std::endl; + exit(1); + } + } + + return -1; +} + +int SmbusHttpH3C::unlock(int exp_id) +{ + exp_id = remap(exp_id); + + std::string url = config_.host + config_.access_unlock; + std::string json_payload = build_unlock(exp_id); + + PRINT("unlock\nurl: %s\n", url.c_str()); + PRINT("Payload: %s\n", json_payload.c_str()); + + std::string response_str = http_helper_->post(url, json_payload, headers_, true); + + PRINT("Response: %s\n", response_str.c_str()); + + if (!response_str.empty()) + { + auto result = parse_response(response_str); + if (result.first == 0) + { + return 0; + } + else + { + std::cerr << __PRETTY_FUNCTION__ << " failed, Code: " << result.first << ", Desc:" << result.second << std::endl; + exit(1); + } + } + + return -1; +} + +std::pair SmbusHttpH3C::parse_response(const std::string& response) +{ + int CompletionCode = -1; + json j = json::parse(response); + if (j.contains("Oem") && j["Oem"].contains("Public") && j["Oem"]["Public"].contains("CompletionCode") && j["Oem"]["Public"].contains("Description")) + { + CompletionCode = j["Oem"]["Public"]["CompletionCode"].get(); + if (CompletionCode == 0 && j.contains("Data") && j["Data"].contains("RegisterValue")) + return std::make_pair(CompletionCode, j["Data"]["RegisterValue"].get()); + return std::make_pair(CompletionCode, j["Oem"]["Public"]["Description"].get()); + } + return std::make_pair(CompletionCode, "Invalid Response"); +} +std::string SmbusHttpH3C::build_lock(int exp_id, int seconds) +{ + std::ostringstream json; + json << "{"; + json << "\"ExpanderId\":" << exp_id << ","; + json << "\"timeout\":" << seconds; + json << "}"; + return json.str(); +} + +std::string SmbusHttpH3C::build_unlock(int exp_id) +{ + std::ostringstream json; + json << "{"; + json << "\"ExpanderId\":" << exp_id << ","; + json << "}"; + return json.str(); +} + +//http.h + +// smbus_http_util.h +#ifndef SMBUS_HTTP_H +#define SMBUS_HTTP_H + +#include +#include +#include +#include +#include +#include "http_helper.h" +#include "lt_config.h" + +class SmbusHttp +{ + +public: + SmbusHttp(const struct http_t& config, const std::string& token); + + virtual int lock(int exp_id, int seconds) { return 0; } + virtual int unlock(int exp_id) { return 0; } + virtual std::string get_token() { return ""; } + virtual int get_register(int exp_id, int cmd_id, int read_len, std::vector& bytes); + virtual int set_register(int exp_id, int cmd_id, int write_len, const std::vector& value); + virtual int get_fru(int exp_id, uint8_t addr, int num, std::vector& bytes); + +protected: + struct http_t config_; + std::unique_ptr http_helper_; + + virtual int remap(int exp_id) { return exp_id; } + std::map exp_map_; + + // 手动构建JSON字符串 + std::vector string_to_bytes(const std::string& hexString); + std::string build_user_pwd(); + std::string build_get_register_json(int exp_id, int cmd_id, int read_len); + std::string build_set_register_json(int exp_id, int cmd_id, int write_len, const std::string& value); + std::string build_get_base_info_json(int exp_id, int addr, int read_len); + + // 解析响应中的Status和Data字段 + virtual std::pair parse_response(const std::string& response) = 0; + std::string token_; +}; + +class SmbusHttpBiren : public SmbusHttp +{ +public: + SmbusHttpBiren(const struct http_t& config, const std::string& token); + int lock(int exp_id, int seconds) override; + int unlock(int exp_id) override; + std::string get_token() override; +protected: + int remap(int exp_id) override; + std::pair parse_token(const std::string& response); + std::pair parse_response(const std::string& response); + std::string build_lock(int exp_id); + std::string build_unlock(int exp_id); +}; + +class SmbusHttpH3C : public SmbusHttp +{ +public: + SmbusHttpH3C(const struct http_t& config, const std::string& token) : SmbusHttp(config, token) {} + int lock(int exp_id, int seconds) override; + int unlock(int exp_id) override; +protected: + std::string build_lock(int exp_id, int seconds); + std::string build_unlock(int exp_id); + std::pair parse_response(const std::string& response); +}; + +#endif // SMBUS_HTTP_UTIL_H \ No newline at end of file