mirror of
https://github.com/sle118/squeezelite-esp32.git
synced 2025-12-06 11:36:59 +03:00
108 lines
3.5 KiB
C++
108 lines
3.5 KiB
C++
#include "Session.h"
|
|
|
|
#include <limits.h> // for CHAR_BIT
|
|
#include <cstdint> // for uint8_t
|
|
#include <functional> // for __base
|
|
#include <memory> // for shared_ptr, unique_ptr, make_unique
|
|
#include <random> // for default_random_engine, independent_bi...
|
|
#include <type_traits> // for remove_extent_t
|
|
#include <utility> // for move
|
|
|
|
#include "ApResolve.h" // for ApResolve, cspot
|
|
#include "AuthChallenges.h" // for AuthChallenges
|
|
#include "BellLogger.h" // for AbstractLogger
|
|
#include "Logger.h" // for CSPOT_LOG
|
|
#include "LoginBlob.h" // for LoginBlob
|
|
#include "Packet.h" // for Packet
|
|
#include "PlainConnection.h" // for PlainConnection, timeoutCallback
|
|
#include "ShannonConnection.h" // for ShannonConnection
|
|
|
|
#include "NanoPBHelper.h" // for pbPutString, pbEncode, pbDecode
|
|
#include "pb_decode.h"
|
|
#include "protobuf/authentication.pb.h"
|
|
|
|
using random_bytes_engine =
|
|
std::independent_bits_engine<std::default_random_engine, CHAR_BIT, uint8_t>;
|
|
|
|
using namespace cspot;
|
|
|
|
Session::Session() {
|
|
this->challenges = std::make_unique<cspot::AuthChallenges>();
|
|
}
|
|
|
|
Session::~Session() {}
|
|
|
|
void Session::connect(std::unique_ptr<cspot::PlainConnection> connection) {
|
|
this->conn = std::move(connection);
|
|
conn->timeoutHandler = [this]() {
|
|
return this->triggerTimeout();
|
|
};
|
|
auto helloPacket = this->conn->sendPrefixPacket(
|
|
{0x00, 0x04}, this->challenges->prepareClientHello());
|
|
auto apResponse = this->conn->recvPacket();
|
|
CSPOT_LOG(info, "Received APHello response");
|
|
|
|
auto solvedHello = this->challenges->solveApHello(helloPacket, apResponse);
|
|
|
|
conn->sendPrefixPacket({}, solvedHello);
|
|
CSPOT_LOG(debug, "Received shannon keys");
|
|
|
|
// Generates the public and priv key
|
|
this->shanConn = std::make_shared<ShannonConnection>();
|
|
|
|
// Init shanno-encrypted connection
|
|
this->shanConn->wrapConnection(this->conn, challenges->shanSendKey,
|
|
challenges->shanRecvKey);
|
|
}
|
|
|
|
void Session::connectWithRandomAp() {
|
|
auto apResolver = std::make_unique<ApResolve>("");
|
|
auto conn = std::make_unique<cspot::PlainConnection>();
|
|
conn->timeoutHandler = [this]() {
|
|
return this->triggerTimeout();
|
|
};
|
|
|
|
auto apAddr = apResolver->fetchFirstApAddress();
|
|
|
|
CSPOT_LOG(debug, "Connecting with AP <%s>", apAddr.c_str());
|
|
conn->connect(apAddr);
|
|
|
|
this->connect(std::move(conn));
|
|
}
|
|
|
|
std::vector<uint8_t> Session::authenticate(std::shared_ptr<LoginBlob> blob) {
|
|
// save auth blob for reconnection purposes
|
|
authBlob = blob;
|
|
// prepare authentication request proto
|
|
auto data = challenges->prepareAuthPacket(blob->authData, blob->authType,
|
|
deviceId, blob->username);
|
|
|
|
// Send login request
|
|
this->shanConn->sendPacket(LOGIN_REQUEST_COMMAND, data);
|
|
|
|
auto packet = this->shanConn->recvPacket();
|
|
switch (packet.command) {
|
|
case AUTH_SUCCESSFUL_COMMAND: {
|
|
APWelcome welcome;
|
|
CSPOT_LOG(debug, "Authorization successful");
|
|
pbDecode(welcome, APWelcome_fields, packet.data);
|
|
return std::vector<uint8_t>(welcome.reusable_auth_credentials.bytes,
|
|
welcome.reusable_auth_credentials.bytes +
|
|
welcome.reusable_auth_credentials.size);
|
|
break;
|
|
}
|
|
case AUTH_DECLINED_COMMAND: {
|
|
CSPOT_LOG(error, "Authorization declined");
|
|
break;
|
|
}
|
|
default:
|
|
CSPOT_LOG(error, "Unknown auth fail code %d", packet.command);
|
|
}
|
|
|
|
return std::vector<uint8_t>(0);
|
|
}
|
|
|
|
void Session::close() {
|
|
this->conn->close();
|
|
}
|