mirror of
https://github.com/sle118/squeezelite-esp32.git
synced 2025-12-09 13:07:03 +03:00
update cspot
This commit is contained in:
@@ -7,10 +7,16 @@
|
||||
#include <cstring>
|
||||
#include <stdlib.h>
|
||||
#include <sys/types.h>
|
||||
#ifdef _WIN32
|
||||
#include <winsock2.h>
|
||||
#include <ws2tcpip.h>
|
||||
#include "win32shim.h"
|
||||
#else
|
||||
#include <sys/socket.h>
|
||||
#include <netdb.h>
|
||||
#include <netinet/in.h>
|
||||
#include <unistd.h>
|
||||
#endif
|
||||
#include <sstream>
|
||||
#include <fstream>
|
||||
#include "Logger.h"
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
#include "Logger.h"
|
||||
|
||||
AudioChunkManager::AudioChunkManager()
|
||||
: bell::Task("AudioChunkManager", 4 * 1024, -1, 1) {
|
||||
: bell::Task("AudioChunkManager", 4 * 1024, 0, 1) {
|
||||
this->chunks = std::vector<std::shared_ptr<AudioChunk>>();
|
||||
startTask();
|
||||
}
|
||||
|
||||
@@ -9,7 +9,7 @@ std::map<MercuryType, std::string> MercuryTypeMap({
|
||||
{MercuryType::UNSUB, "UNSUB"},
|
||||
});
|
||||
|
||||
MercuryManager::MercuryManager(std::unique_ptr<Session> session): bell::Task("mercuryManager", 6 * 1024, 0, 1)
|
||||
MercuryManager::MercuryManager(std::unique_ptr<Session> session): bell::Task("mercuryManager", 6 * 1024, 1, 1)
|
||||
{
|
||||
tempMercuryHeader = {};
|
||||
this->timeProvider = std::make_shared<TimeProvider>();
|
||||
@@ -115,6 +115,7 @@ std::shared_ptr<AudioChunk> MercuryManager::fetchAudioChunk(std::vector<uint8_t>
|
||||
this->session->shanConn->sendPacket(static_cast<uint8_t>(MercuryType::AUDIO_CHUNK_REQUEST_COMMAND), buffer);
|
||||
|
||||
// Used for broken connection detection
|
||||
//CSPOT_LOG(info, "requesting Chunk %hu", this->audioChunkSequence - 1);
|
||||
this->lastRequestTimestamp = this->timeProvider->getSyncedTimestamp();
|
||||
return this->audioChunkManager->registerNewChunk(this->audioChunkSequence - 1, audioKey, startPos, endPos);
|
||||
}
|
||||
|
||||
@@ -1,10 +1,26 @@
|
||||
|
||||
#include "PlainConnection.h"
|
||||
#include <cstring>
|
||||
#ifdef _WIN32
|
||||
#include <ws2tcpip.h>
|
||||
#else
|
||||
#include <netinet/tcp.h>
|
||||
#endif
|
||||
#include <errno.h>
|
||||
#include "Logger.h"
|
||||
|
||||
static int getErrno()
|
||||
{
|
||||
#ifdef _WIN32
|
||||
int code = WSAGetLastError();
|
||||
if (code == WSAETIMEDOUT) return ETIMEDOUT;
|
||||
if (code == WSAEINTR) return EINTR;
|
||||
return code;
|
||||
#else
|
||||
return errno;
|
||||
#endif
|
||||
}
|
||||
|
||||
PlainConnection::PlainConnection()
|
||||
{
|
||||
this->apSock = -1;
|
||||
@@ -46,11 +62,15 @@ void PlainConnection::connectToAp(std::string apAddress)
|
||||
(struct sockaddr *)ai->ai_addr,
|
||||
ai->ai_addrlen) != -1)
|
||||
{
|
||||
#ifdef _WIN32
|
||||
uint32_t tv = 3000;
|
||||
#else
|
||||
struct timeval tv;
|
||||
tv.tv_sec = 3;
|
||||
tv.tv_usec = 0;
|
||||
setsockopt(this->apSock, SOL_SOCKET, SO_RCVTIMEO, (const char *)&tv, sizeof tv);
|
||||
setsockopt(this->apSock, SOL_SOCKET, SO_SNDTIMEO, (const char *)&tv, sizeof tv);
|
||||
#endif
|
||||
setsockopt(this->apSock, SOL_SOCKET, SO_RCVTIMEO, (const char*)&tv, sizeof tv);
|
||||
setsockopt(this->apSock, SOL_SOCKET, SO_SNDTIMEO, (const char*)&tv, sizeof tv);
|
||||
|
||||
int flag = 1;
|
||||
setsockopt(this->apSock, /* socket affected */
|
||||
@@ -75,7 +95,6 @@ std::vector<uint8_t> PlainConnection::recvPacket()
|
||||
// Read packet size
|
||||
auto sizeData = readBlock(4);
|
||||
uint32_t packetSize = ntohl(extract<uint32_t>(sizeData, 0));
|
||||
|
||||
// Read actual data
|
||||
auto data = readBlock(packetSize - 4);
|
||||
sizeData.insert(sizeData.end(), data.begin(), data.end());
|
||||
@@ -110,9 +129,9 @@ std::vector<uint8_t> PlainConnection::readBlock(size_t size)
|
||||
while (idx < size)
|
||||
{
|
||||
READ:
|
||||
if ((n = recv(this->apSock, &buf[idx], size - idx, 0)) <= 0)
|
||||
if ((n = recv(this->apSock, (char*) &buf[idx], size - idx, 0)) <= 0)
|
||||
{
|
||||
switch (errno)
|
||||
switch (getErrno())
|
||||
{
|
||||
case EAGAIN:
|
||||
case ETIMEDOUT:
|
||||
@@ -145,9 +164,9 @@ size_t PlainConnection::writeBlock(const std::vector<uint8_t> &data)
|
||||
while (idx < data.size())
|
||||
{
|
||||
WRITE:
|
||||
if ((n = send(this->apSock, &data[idx], data.size() - idx < 64 ? data.size() - idx : 64, 0)) <= 0)
|
||||
if ((n = send(this->apSock, (char*) &data[idx], data.size() - idx < 64 ? data.size() - idx : 64, 0)) <= 0)
|
||||
{
|
||||
switch (errno)
|
||||
switch (getErrno())
|
||||
{
|
||||
case EAGAIN:
|
||||
case ETIMEDOUT:
|
||||
|
||||
@@ -9,20 +9,16 @@ using std::size_t;
|
||||
|
||||
static inline uint32_t rotl(uint32_t n, unsigned int c)
|
||||
{
|
||||
const unsigned int mask = (CHAR_BIT * sizeof(n) - 1); // assumes width is a power of 2.
|
||||
|
||||
// assert ( (c<=mask) &&"rotate by type width or more");
|
||||
c &= mask;
|
||||
return (n << c) | (n >> ((-c) & mask));
|
||||
c &= sizeof(n) * CHAR_BIT - 1;
|
||||
return (n << c) | (n >> (sizeof(n)*CHAR_BIT-c));
|
||||
}
|
||||
|
||||
static inline uint32_t rotr(uint32_t n, unsigned int c)
|
||||
{
|
||||
const unsigned int mask = (CHAR_BIT * sizeof(n) - 1);
|
||||
|
||||
// assert ( (c<=mask) &&"rotate by type width or more");
|
||||
c &= mask;
|
||||
return (n >> c) | (n << ((-c) & mask));
|
||||
c &= sizeof(n) * CHAR_BIT - 1;
|
||||
return (n >> c) | (n << (sizeof(n)*CHAR_BIT-c));
|
||||
}
|
||||
|
||||
uint32_t Shannon::sbox1(uint32_t w)
|
||||
|
||||
@@ -108,7 +108,7 @@ void SpircController::prevSong() {
|
||||
void SpircController::handleFrame(std::vector<uint8_t> &data) {
|
||||
pb_release(Frame_fields, &state->remoteFrame);
|
||||
pbDecode(state->remoteFrame, Frame_fields, data);
|
||||
|
||||
//CSPOT_LOG(info, "FRAME RECEIVED %d", (int) state->remoteFrame.typ);
|
||||
switch (state->remoteFrame.typ) {
|
||||
case MessageType_kMessageTypeNotify: {
|
||||
CSPOT_LOG(debug, "Notify frame");
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
#include "SpotifyTrack.h"
|
||||
#ifndef _WIN32
|
||||
#include "unistd.h"
|
||||
#endif
|
||||
#include "MercuryManager.h"
|
||||
#include <cassert>
|
||||
#include "CspotAssert.h"
|
||||
|
||||
@@ -1,14 +1,24 @@
|
||||
#include "ZeroconfAuthenticator.h"
|
||||
#include "JSONObject.h"
|
||||
#include <sstream>
|
||||
#ifndef _WIN32
|
||||
#include <sys/select.h>
|
||||
#else
|
||||
#include <iphlpapi.h>
|
||||
#pragma comment(lib, "IPHLPAPI.lib")
|
||||
#endif
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include "Logger.h"
|
||||
#include "CspotAssert.h"
|
||||
#include "ConfigJSON.h"
|
||||
|
||||
// provide weak deviceId (see ConstantParameters.h)
|
||||
#if _MSC_VER
|
||||
char deviceId[] = "142137fd329622137a14901634264e6f332e2411";
|
||||
#else
|
||||
char deviceId[] __attribute__((weak)) = "142137fd329622137a14901634264e6f332e2411";
|
||||
#endif
|
||||
|
||||
ZeroconfAuthenticator::ZeroconfAuthenticator(authCallback callback, std::shared_ptr<bell::BaseHTTPServer> httpServer) {
|
||||
this->gotBlobCallback = callback;
|
||||
@@ -17,15 +27,43 @@ ZeroconfAuthenticator::ZeroconfAuthenticator(authCallback callback, std::shared_
|
||||
this->crypto = std::make_unique<Crypto>();
|
||||
this->crypto->dhInit();
|
||||
this->server = httpServer;
|
||||
|
||||
#ifdef _WIN32
|
||||
char hostname[128];
|
||||
gethostname(hostname, sizeof(hostname));
|
||||
|
||||
struct sockaddr_in* host = NULL;
|
||||
ULONG size = sizeof(IP_ADAPTER_ADDRESSES) * 32;
|
||||
IP_ADAPTER_ADDRESSES* adapters = (IP_ADAPTER_ADDRESSES*) malloc(size);
|
||||
int ret = GetAdaptersAddresses(AF_UNSPEC, GAA_FLAG_INCLUDE_GATEWAYS | GAA_FLAG_SKIP_MULTICAST | GAA_FLAG_SKIP_ANYCAST, 0, adapters, &size);
|
||||
|
||||
for (PIP_ADAPTER_ADDRESSES adapter = adapters; adapter && !host; adapter = adapter->Next) {
|
||||
if (adapter->TunnelType == TUNNEL_TYPE_TEREDO) continue;
|
||||
if (adapter->OperStatus != IfOperStatusUp) continue;
|
||||
|
||||
for (IP_ADAPTER_UNICAST_ADDRESS* unicast = adapter->FirstUnicastAddress; unicast;
|
||||
unicast = unicast->Next) {
|
||||
if (adapter->FirstGatewayAddress && unicast->Address.lpSockaddr->sa_family == AF_INET) {
|
||||
host = (struct sockaddr_in*)unicast->Address.lpSockaddr;
|
||||
BELL_LOG(info, "mdns", "mDNS on interface %s", inet_ntoa(host->sin_addr));
|
||||
this->service = mdnsd_start(host->sin_addr, false);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
CSPOT_ASSERT(this->service, "can't start mDNS service");
|
||||
mdnsd_set_hostname(this->service, hostname, host->sin_addr);
|
||||
#endif
|
||||
}
|
||||
|
||||
void ZeroconfAuthenticator::registerHandlers() {
|
||||
// Make it discoverable for spoti clients
|
||||
registerZeroconf();
|
||||
auto getInfoHandler = [this](bell::HTTPRequest& request) {
|
||||
auto getInfoHandler = [this](std::unique_ptr<bell::HTTPRequest> request) {
|
||||
CSPOT_LOG(info, "Got request for info");
|
||||
bell::HTTPResponse response = {
|
||||
.connectionFd = request.connection,
|
||||
.connectionFd = request->connection,
|
||||
.status = 200,
|
||||
.body = this->buildJsonInfo(),
|
||||
.contentType = "application/json",
|
||||
@@ -33,7 +71,7 @@ void ZeroconfAuthenticator::registerHandlers() {
|
||||
server->respond(response);
|
||||
};
|
||||
|
||||
auto addUserHandler = [this](bell::HTTPRequest& request) {
|
||||
auto addUserHandler = [this](std::unique_ptr<bell::HTTPRequest> request) {
|
||||
BELL_LOG(info, "http", "Got request for adding user");
|
||||
bell::JSONObject obj;
|
||||
obj["status"] = 101;
|
||||
@@ -41,15 +79,15 @@ void ZeroconfAuthenticator::registerHandlers() {
|
||||
obj["statusString"] = "ERROR-OK";
|
||||
|
||||
bell::HTTPResponse response = {
|
||||
.connectionFd = request.connection,
|
||||
.connectionFd = request->connection,
|
||||
.status = 200,
|
||||
.body = obj.toString(),
|
||||
.contentType = "application/json",
|
||||
};
|
||||
server->respond(response);
|
||||
|
||||
auto correctBlob = this->getParameterFromUrlEncoded(request.body, "blob");
|
||||
this->handleAddUser(request.queryParams);
|
||||
auto correctBlob = this->getParameterFromUrlEncoded(request->body, "blob");
|
||||
this->handleAddUser(request->queryParams);
|
||||
};
|
||||
|
||||
BELL_LOG(info, "cspot", "Zeroconf registering handlers");
|
||||
@@ -62,12 +100,18 @@ void ZeroconfAuthenticator::registerZeroconf()
|
||||
const char* service = "_spotify-connect._tcp";
|
||||
|
||||
#ifdef ESP_PLATFORM
|
||||
mdns_txt_item_t serviceTxtData[3] = {
|
||||
{"VERSION", "1.0"},
|
||||
{"CPath", "/spotify_info"},
|
||||
{"Stack", "SP"} };
|
||||
mdns_service_add("cspot", "_spotify-connect", "_tcp", this->server->serverPort, serviceTxtData, 3);
|
||||
|
||||
mdns_txt_item_t serviceTxtData[3] = {
|
||||
{"VERSION", "1.0"},
|
||||
{"CPath", "/spotify_info"},
|
||||
{"Stack", "SP"} };
|
||||
mdns_service_add("cspot", "_spotify-connect", "_tcp", this->server->serverPort, serviceTxtData, 3);
|
||||
#elif _WIN32
|
||||
const char *serviceTxtData[] = {
|
||||
"VERSION=1.0",
|
||||
"CPath=/spotify_info",
|
||||
"Stack=SP",
|
||||
NULL };
|
||||
mdnsd_register_svc(this->service, "cspot", "_spotify-connect._tcp.local", this->server->serverPort, NULL, serviceTxtData);
|
||||
#else
|
||||
DNSServiceRef ref = NULL;
|
||||
TXTRecordRef txtRecord;
|
||||
|
||||
Reference in New Issue
Block a user