///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
| 860 | |
| 861 | //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// |
| 862 | json FSecure::C3::Core::Profiler::Gateway::GetCapability() |
| 863 | { |
| 864 | // Request access to Gateway object. |
| 865 | auto gateway = m_Gateway.lock(); |
| 866 | if (!gateway) |
| 867 | return {}; |
| 868 | |
| 869 | // TODO This function require refactoring. |
| 870 | |
| 871 | // Construct the InitialPacket. |
| 872 | json initialPacket = json::parse(gateway->m_InterfaceFactory.GetCapability()); |
| 873 | |
| 874 | for (auto& interface : initialPacket["channels"]) |
| 875 | EnsureCreateExists(interface); |
| 876 | |
| 877 | // Create method in interface is constructor. It must be a relay/gateway command. |
| 878 | // initialPacket is copied to original to prevent iterator invalidation. |
| 879 | // last 256 commands will be reserved for common commands. |
| 880 | auto modifyEntry = [&, id = static_cast<uint16_t>(-257), oryginal = initialPacket](std::vector<std::string> const& relayTypes, auto interfaceType, std::vector<std::string> prefix, bool isDevice) mutable |
| 881 | { |
| 882 | auto idToErase = 0; |
| 883 | std::vector<std::unordered_map<std::string, std::vector<json>>> buffer; |
| 884 | buffer.resize(prefix.size()); |
| 885 | for (auto&& element : oryginal[interfaceType]) |
| 886 | { |
| 887 | try |
| 888 | { |
| 889 | for (auto i = 0u; i < prefix.size(); ++i) |
| 890 | { |
| 891 | auto arguments = element.at("create").at("arguments"); |
| 892 | if (i) // NegotiationChannel command |
| 893 | { |
| 894 | if (arguments.empty() || arguments[0].size() != 2) |
| 895 | continue; |
| 896 | |
| 897 | arguments[0] = { {"type", "string"}, {"name", "Negotiation Identifier"}, {"randomize", true}, {"description", "One identifier used to negotiate identifiers for each joining relay"} }; |
| 898 | } |
| 899 | |
| 900 | for (auto&& relayType : relayTypes) |
| 901 | buffer[i][relayType].push_back(json{ {"name", prefix[i] + element["name"].template get<std::string>()}, {"arguments", arguments}, {"id", id} }); |
| 902 | |
| 903 | m_CreateCommands.push_back({ id, initialPacket[interfaceType][idToErase]["type"].template get<uint32_t>(), isDevice, !!i }); // store command id and hash. |
| 904 | --id; |
| 905 | } |
| 906 | |
| 907 | // modify initial Packet with extra entries. |
| 908 | initialPacket[interfaceType][idToErase].erase("create"); |
| 909 | AddBuildInCommands(initialPacket[interfaceType][idToErase], isDevice); |
| 910 | } |
| 911 | catch (std::exception& e) |
| 912 | { |
| 913 | m_Gateway.lock()->Log({ std::string("Exception caught when parsing interface capability. ") + e.what(), LogMessage::Severity::Error }); |
| 914 | } |
| 915 | |
| 916 | ++idToErase; |
| 917 | } |
| 918 | |
| 919 | // move commands from buffer to modified json in correct order. |