114fe6698SNan Zhou // Copyright 2021 Google LLC 214fe6698SNan Zhou // 314fe6698SNan Zhou // Licensed under the Apache License, Version 2.0 (the "License"); 414fe6698SNan Zhou // you may not use this file except in compliance with the License. 514fe6698SNan Zhou // You may obtain a copy of the License at 614fe6698SNan Zhou // 714fe6698SNan Zhou // http://www.apache.org/licenses/LICENSE-2.0 814fe6698SNan Zhou // 914fe6698SNan Zhou // Unless required by applicable law or agreed to in writing, software 1014fe6698SNan Zhou // distributed under the License is distributed on an "AS IS" BASIS, 1114fe6698SNan Zhou // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 1214fe6698SNan Zhou // See the License for the specific language governing permissions and 1314fe6698SNan Zhou // limitations under the License. 1414fe6698SNan Zhou 1514fe6698SNan Zhou #include "src/default_addresses.h" 1614fe6698SNan Zhou 1714fe6698SNan Zhou #include "src/host_manager.hpp" 1814fe6698SNan Zhou #include "src/nemora.hpp" 1914fe6698SNan Zhou 2014fe6698SNan Zhou #include <arpa/inet.h> 2114fe6698SNan Zhou 2214fe6698SNan Zhou #include <CLI/CLI.hpp> 2314fe6698SNan Zhou #include <phosphor-logging/log.hpp> 2414fe6698SNan Zhou 2514fe6698SNan Zhou #include <csignal> 2614fe6698SNan Zhou #include <cstdint> 27*adb8ffe4SWilly Tu #include <iostream> 2814fe6698SNan Zhou #include <regex> 2914fe6698SNan Zhou #include <string> 3014fe6698SNan Zhou #include <thread> 3114fe6698SNan Zhou #include <unordered_map> 3214fe6698SNan Zhou #include <vector> 3314fe6698SNan Zhou 3414fe6698SNan Zhou using phosphor::logging::level; 3514fe6698SNan Zhou using phosphor::logging::log; 3614fe6698SNan Zhou 3714fe6698SNan Zhou namespace 3814fe6698SNan Zhou { 3914fe6698SNan Zhou volatile std::sig_atomic_t gSignalStatus; 4014fe6698SNan Zhou } 4114fe6698SNan Zhou 4214fe6698SNan Zhou void signal_handler(int signal) 4314fe6698SNan Zhou { 4414fe6698SNan Zhou gSignalStatus = signal; 4514fe6698SNan Zhou } 4614fe6698SNan Zhou 4714fe6698SNan Zhou void NemoraUdpPoll(Nemora* nemora) 4814fe6698SNan Zhou { 4914fe6698SNan Zhou while (!gSignalStatus) 5014fe6698SNan Zhou { 5114fe6698SNan Zhou nemora->UdpPoll(); 5214fe6698SNan Zhou } 5314fe6698SNan Zhou } 5414fe6698SNan Zhou 5514fe6698SNan Zhou int main(int argc, char* argv[]) 5614fe6698SNan Zhou { 5714fe6698SNan Zhou // Init arg parser 5814fe6698SNan Zhou CLI::App app("gBMC-side Nemora implementation (POST-code only)"); 5914fe6698SNan Zhou 6014fe6698SNan Zhou std::string udp_address_v4_str; 619632cb8aSHarvey.Wu auto* ipv4_option = app.add_option("--udp4", udp_address_v4_str, 629632cb8aSHarvey.Wu "Target IPv4 address for UDP " 639632cb8aSHarvey.Wu "communication, i.e., POST streaming.") 649632cb8aSHarvey.Wu ->capture_default_str(); 6514fe6698SNan Zhou 6614fe6698SNan Zhou std::string udp_address_v6_str; 679632cb8aSHarvey.Wu auto* ipv6_option = app.add_option("--udp6", udp_address_v6_str, 689632cb8aSHarvey.Wu "Target IPv6 address for UDP " 699632cb8aSHarvey.Wu "communication, i.e., POST streaming.") 709632cb8aSHarvey.Wu ->capture_default_str(); 7114fe6698SNan Zhou 7214fe6698SNan Zhou // interface is last, and required. 7314fe6698SNan Zhou std::string iface_name; 7414fe6698SNan Zhou app.add_option("interface", iface_name, 7514fe6698SNan Zhou "Network interface for TCP communication. Ex: eth0") 7614fe6698SNan Zhou ->required(); 7714fe6698SNan Zhou 7814fe6698SNan Zhou CLI11_PARSE(app, argc, argv); 7914fe6698SNan Zhou 8014fe6698SNan Zhou in_addr udp_address_v4; 8114fe6698SNan Zhou udp_address_v4.s_addr = htonl(DEFAULT_ADDRESSES_TARGET_IP); 8214fe6698SNan Zhou if (*ipv4_option && 8314fe6698SNan Zhou !inet_pton(AF_INET, udp_address_v4_str.c_str(), &udp_address_v4)) 8414fe6698SNan Zhou { 8514fe6698SNan Zhou std::cerr << "Invalid IPv4 address supplied: " << udp_address_v4_str 8614fe6698SNan Zhou << std::endl; 8714fe6698SNan Zhou } 8814fe6698SNan Zhou 8914fe6698SNan Zhou // The value from default_addresses.h is designed for LWIP which EC uses, 9014fe6698SNan Zhou // and needs to be translated to network byte order. 9114fe6698SNan Zhou in6_addr udp_address_v6; 9214fe6698SNan Zhou uint32_t default_addr_6[4] = DEFAULT_ADDRESSES_TARGET_IP6; 9314fe6698SNan Zhou 9414fe6698SNan Zhou auto htonl_inplace = [](uint32_t& i) { i = htonl(i); }; 9514fe6698SNan Zhou std::for_each(std::begin(default_addr_6), std::end(default_addr_6), 9614fe6698SNan Zhou htonl_inplace); 9714fe6698SNan Zhou std::memcpy(udp_address_v6.s6_addr, default_addr_6, sizeof(default_addr_6)); 9814fe6698SNan Zhou 9914fe6698SNan Zhou if (*ipv6_option && 10014fe6698SNan Zhou !inet_pton(AF_INET6, udp_address_v6_str.c_str(), &udp_address_v6)) 10114fe6698SNan Zhou { 10214fe6698SNan Zhou std::cerr << "Invalid IPv6 address supplied: " << udp_address_v6_str 10314fe6698SNan Zhou << std::endl; 10414fe6698SNan Zhou } 10514fe6698SNan Zhou 10614fe6698SNan Zhou log<level::INFO>("Start Nemora..."); 10714fe6698SNan Zhou Nemora nemora(iface_name, udp_address_v4, udp_address_v6); 10814fe6698SNan Zhou 10914fe6698SNan Zhou // Install a signal handler 11014fe6698SNan Zhou std::signal(SIGINT, signal_handler); 11114fe6698SNan Zhou 11214fe6698SNan Zhou std::thread udp(NemoraUdpPoll, &nemora); 11314fe6698SNan Zhou 11414fe6698SNan Zhou udp.join(); 11514fe6698SNan Zhou 11614fe6698SNan Zhou return EXIT_SUCCESS; 11714fe6698SNan Zhou } 118