/* * Copyright (C) 2016 EPFL * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see http://www.gnu.org/licenses/. */ /** * @file TcpSocket.cpp * @brief QML wrapper source for QTcpSocket * @author Ayberk Özgür * @date 2016-11-10 */ #include "TcpSocket.h" #include namespace QMLTcpSockets{ TcpSocket::TcpSocket(QQuickItem* parent): QQuickItem(parent), socket(this) { connect(&socket, SIGNAL(connected()), this, SIGNAL(connected())); connect(&socket, SIGNAL(disconnected()), this, SIGNAL(disconnected())); connect(&socket, SIGNAL(error(QAbstractSocket::SocketError)), this, SLOT(emitErrorAsInt(QAbstractSocket::SocketError))); connect(&socket, SIGNAL(readyRead()), this, SLOT(publish())); peer = ""; port = 0; } TcpSocket::TcpSocket(QIntPtr* socketDescriptor, QQuickItem* parent): TcpSocket(parent) { socket.setSocketDescriptor(socketDescriptor->ptr); socketDescriptor->deleteLater(); peer = socket.peerAddress().toString(); port = socket.peerPort(); } TcpSocket::~TcpSocket(){ socket.flush(); } void TcpSocket::setSocketDescriptor(QIntPtr* socketDescriptor){ socket.flush(); socket.disconnectFromHost(); socket.setSocketDescriptor(socketDescriptor->ptr); socketDescriptor->deleteLater(); QString peer = socket.peerAddress().toString(); if(this->peer != peer){ this->peer = peer; emit peerChanged(); } quint16 port = socket.peerPort(); if(this->port != port){ this->port = port; emit portChanged(); } emit connected(); } void TcpSocket::setSocketOption(int option, QVariant value){ socket.setSocketOption((QAbstractSocket::SocketOption)option, value); } void TcpSocket::setPeer(QString peer){ if(peer != this->peer){ if(socket.state() != TcpSocketEnums::UnconnectedState) qWarning() << "TcpSocket::setPeer(): Can only set peer while disconnected."; else{ this->peer = peer; emit peerChanged(); } } } void TcpSocket::setPort(int port){ if(port < 0){ qWarning() << "TcpSocket::setPort(): port given was negative, setting to 0."; port = 0; } else if(port > 0xFFFF){ qWarning() << "TcpSocket::setPort(): port given was larger than 65535, setting to 65535."; port = 0xFFFF; } if(port != this->port){ if(socket.state() != TcpSocketEnums::UnconnectedState) qWarning() << "TcpSocket::setPort(): Can only set port while disconnected."; else{ this->port = port; emit portChanged(); } } } void TcpSocket::connectToHost(){ socket.connectToHost(peer, port); } void TcpSocket::disconnectFromHost(){ socket.disconnectFromHost(); } void TcpSocket::emitErrorAsInt(QAbstractSocket::SocketError socketError){ emit error(socketError); } void TcpSocket::publish(){ QList list; QByteArray receivedBytes = socket.readAll(); for(char c : receivedBytes) list << (int)(*((unsigned char*)(&c))); emit bytesReceived(list); } bool TcpSocket::writeBytes(QList bytes){ QByteArray container; for(int b : bytes){ if(b < 0 || b > 0xFF){ qWarning() << "TcpSocket::writeBytes(): bytes contain integer not in [0x00,0xFF], not writing"; return false; } else container.append((char)b); } int numBytesToWrite = container.size(); const char* bytesRaw = container.constData(); while(numBytesToWrite > 0){ int bytesWritten = socket.write(bytesRaw, numBytesToWrite); if(bytesWritten < 0){ qWarning() << "TcpSocket::writeBytes(): Bytes were not written: " << socket.errorString(); return false; } numBytesToWrite -= bytesWritten; bytesRaw += bytesWritten; } socket.flush(); return true; } }