#include "crypto/crypto.h" #include "net/voice_frame.h" #include "protocol/envelope.h" #include #include #include #include static std::string hex(const std::vector& bytes) { std::ostringstream result; result << std::hex << std::setfill('0'); for (auto byte : bytes) result << std::setw(2) << unsigned(byte); return result.str(); } int main(int argc, char** argv) { if (argc != 2 || sodium_init() < 0) return 1; std::ofstream output(argv[1], std::ios::binary); if (!output) return 1; voicecat::v1::Envelope envelope; envelope.set_request_id(42); auto* hello = envelope.mutable_client_hello(); hello->set_proto_version(1); hello->set_client_name("test-client"); hello->set_client_version("0.0.1"); hello->add_features("text"); std::vector framed; if (!voicecat::protocol::encode_envelope(envelope, framed)) return 1; output << "{\n \"envelope\": \"" << hex(framed) << "\",\n \"media\": [\n"; std::array key{}; for (size_t i = 0; i < key.size(); ++i) key[i] = uint8_t(i); voicecat::crypto::SodiumMediaCrypto sender(key.data()); for (uint64_t sequence = 0; sequence <= 65536; ++sequence) { voicecat::net::VoiceFrame header; header.flags = voicecat::net::kFlagMarker; header.ssrc = 0xcafebabe; header.seq = sender.peek_send_counter(); header.timestamp = 960; const size_t length = sequence == 0 ? 0 : sequence == 1 ? 100 : 8; std::vector plaintext(length); for (size_t i = 0; i < length; ++i) plaintext[i] = uint8_t(i); std::vector packet(voicecat::net::kVoiceHeaderSize + length + 16); voicecat::net::serialize_header(header, packet.data()); if (sender.seal(plaintext.data(), length, packet.data(), 20, packet.data() + 20, length + 16) < 0) return 1; if (sequence == 0 || sequence == 1 || sequence == 65535 || sequence == 65536) { if (sequence != 0) output << ",\n"; output << " {\"sequence\": " << sequence << ", \"key\": \"" << hex(std::vector(key.begin(), key.end())) << "\", \"plaintext\": \"" << hex(plaintext) << "\", \"packet\": \"" << hex(packet) << "\"}"; } } output << "\n ]\n}\n"; return output ? 0 : 1; }