#include #include #include #include using namespace std::chrono_literals; namespace rfspace { RFspaceClientClass::RFspaceClientClass(net::Conn conn, net::Conn udpConn, dsp::stream* out) { client = std::move(conn); udpClient = std::move(udpConn); output = out; rbuffer = new uint8_t[RFSPACE_MAX_SIZE]; sbuffer = new uint8_t[RFSPACE_MAX_SIZE]; ubuffer = new uint8_t[RFSPACE_MAX_SIZE]; output->clearWriteStop(); uint8_t test = 0x5A; udpClient->write(1, &test); // Start readers client->readAsync(sizeof(tcpHeader), (uint8_t*)&tcpHeader, tcpHandler, this); udpClient->readAsync(sizeof(udpHeader), (uint8_t*)&udpHeader, udpHandler, this); // Start SDR uint8_t args[4] = {0x70, 2, 0, 0}; setControlItem(0x18, args, 4); } RFspaceClientClass::~RFspaceClientClass() { close(); delete[] rbuffer; delete[] sbuffer; delete[] ubuffer; } int RFspaceClientClass::getControlItem(uint16_t item, void* param, int len) { // Build packet uint16_t* header = (uint16_t*)&sbuffer[0]; uint16_t* item_val = (uint16_t*)&sbuffer[2]; *header = 4 | (RFSPACE_MSG_TYPE_H2T_REQ_CTRL_ITEM << 13); *item_val = item; // Send packet SCIRRecv.release(); client->write(4, sbuffer); // Wait for a response if (!SCIRRecv.await(2000)) { SCIRRecv.release(); return -1; } // Forward data int toRead = ((SCIRSize - 4) < len) ? (SCIRSize - 4) : len; memcpy(param, &rbuffer[4], toRead); // Release receiving thread SCIRRecv.release(); return toRead; } void RFspaceClientClass::setControlItem(uint16_t item, void* param, int len) { // Build packet uint16_t* header = (uint16_t*)&sbuffer[0]; uint16_t* item_val = (uint16_t*)&sbuffer[2]; *header = (len + 4) | (RFSPACE_MSG_TYPE_H2T_SET_CTRL_ITEM << 13); *item_val = item; memcpy(&sbuffer[4], param, len); // Send packet client->write(len + 4, sbuffer); } void RFspaceClientClass::close() { output->stopWriter(); client->close(); udpClient->close(); } bool RFspaceClientClass::isOpen() { return client->isOpen(); } void RFspaceClientClass::tcpHandler(int count, uint8_t* buf, void* ctx) { RFspaceClientClass* _this = (RFspaceClientClass*)ctx; uint8_t type = _this->tcpHeader >> 13; uint16_t size = _this->tcpHeader & 0b1111111111111; // Read the rest of the data if (size > 2) { _this->client->read(size - 2, &_this->rbuffer[2]); } spdlog::warn("TCP received: {0} {1}", type, size); // Process data if (type == RFSPACE_MSG_TYPE_T2H_SET_CTRL_ITEM_RESP) { _this->SCIRSize = size; _this->SCIRRecv.trigger(); } // Restart an async read _this->client->readAsync(sizeof(_this->tcpHeader), (uint8_t*)&_this->tcpHeader, tcpHandler, _this); } void RFspaceClientClass::udpHandler(int count, uint8_t* buf, void* ctx) { RFspaceClientClass* _this = (RFspaceClientClass*)ctx; uint8_t type = _this->udpHeader >> 13; uint16_t size = _this->udpHeader & 0b1111111111111; spdlog::warn("UDP received: {0} {1}", type, size); // Read the rest of the data if (size > 2) { _this->client->read(size - 2, &_this->rbuffer[2]); } // Restart an async read _this->client->readAsync(sizeof(_this->udpHeader), (uint8_t*)&_this->udpHeader, udpHandler, _this); } RFspaceClient connect(std::string host, uint16_t port, dsp::stream* out) { net::Conn conn = net::connect(host, port); if (!conn) { return NULL; } net::Conn udpConn = net::openUDP("0.0.0.0", port, host, port, true); if (!udpConn) { return NULL; } return RFspaceClient(new RFspaceClientClass(std::move(conn), std::move(udpConn), out)); } }