update cspot

This commit is contained in:
philippe44
2022-11-17 14:06:00 -08:00
parent a81d0e0513
commit 7e5f27af12
137 changed files with 6046 additions and 836 deletions

View File

@@ -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"

View File

@@ -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();
}

View File

@@ -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);
}

View File

@@ -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:

View File

@@ -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)

View File

@@ -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");

View File

@@ -1,5 +1,7 @@
#include "SpotifyTrack.h"
#ifndef _WIN32
#include "unistd.h"
#endif
#include "MercuryManager.h"
#include <cassert>
#include "CspotAssert.h"

View File

@@ -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;