ChatManager.cpp Example File
bluetoothsppchat/src/ChatManager.cpp
#include "ChatManager.hpp"
#include <QtCore>
#include <btapi/btdevice.h>
#include <btapi/btspp.h>
#include <errno.h>
#include <iostream>
#define SPP_SERVICE_UUID "00001101-0000-1000-8000-00805F9B34FB"
void BTControllerSPPCallback(long param, int fd)
{
ChatManager *chatManager = reinterpret_cast<ChatManager*>(param);
if (chatManager) {
chatManager->setSPPServer(fd);
}
}
SPPThread::SPPThread(QObject *parent)
: QThread(parent)
{
resetFD();
}
void SPPThread::init(int fd, bool isServer)
{
m_sppFD = fd;
m_sppServer = isServer;
}
int SPPThread::getFD() const
{
return m_sppFD;
}
void SPPThread::resetFD()
{
m_sppFD = -1;
m_sppServer = false;
}
bool SPPThread::isServer() const
{
return m_sppServer;
}
bool SPPThread::active() const
{
return (m_sppFD >= 0);
}
void SPPThread::run()
{
int readlen;
char tempbuff[128];
while (m_sppFD >= 0) {
if ((readlen = read(m_sppFD, tempbuff, (128 - 1))) > 0) {
tempbuff[readlen] = '\0';
emit incomingMessage(QString::fromLatin1(tempbuff));
} else {
if (readlen <= 0) {
emit connectionClosed();
}
}
}
}
ChatManager::ChatManager(QObject *parent)
: QObject(parent)
{
bool ok = connect(&m_sppDataThread, SIGNAL(incomingMessage(QString)), SLOT(incomingMessage(QString)));
Q_ASSERT(ok);
ok = connect(&m_sppDataThread, SIGNAL(connectionClosed()), SLOT(closeSPPConnection()));
Q_ASSERT(ok);
ok = connect(&m_sppDataThread, SIGNAL(connectionClosed()), SIGNAL(chatEnded()));
Q_ASSERT(ok);
}
ChatManager::~ChatManager()
{
closeSPPConnection();
}
void ChatManager::setRemoteAddress(const QString &address)
{
m_remoteAddress = address;
}
void ChatManager::setSPPServer(int fd)
{
if (fd >= 0) {
m_sppDataThread.init(fd, true);
m_sppDataThread.start();
updateChatWindow("Client connected!\n\n");
}
}
void ChatManager::setSPPClient(int fd)
{
if (fd >= 0) {
m_sppDataThread.init(fd, false);
m_sppDataThread.start();
}
}
void ChatManager::connectToSPPService()
{
m_chatHistory.clear();
const int fd = bt_spp_open(m_remoteAddress.toAscii().data(), (char *) SPP_SERVICE_UUID, false);
if (fd >= 0) {
updateChatWindow("SPP Client\n\n");
setSPPClient(fd);
} else {
showDialog("spp_open fail", "errno = " + QString::number(errno) );
}
}
void ChatManager::startSPPServer()
{
m_chatHistory.clear();
if (bt_spp_open_server((char *) "", (char *) SPP_SERVICE_UUID, 0, BTControllerSPPCallback, reinterpret_cast<long>(this)) == 0) {
updateChatWindow("SPP Server started. Waiting for clients..\n\n");
m_sppDataThread.init(-1, true);
} else {
showDialog("spp_open_server fail", "errno = " + QString::number(errno) );
}
}
void ChatManager::sendSPPMessage(const QString &msg)
{
if (m_sppDataThread.active()) {
write(m_sppDataThread.getFD(), msg.toAscii().data(), msg.size());
updateChatWindow(" We: " + msg);
} else {
updateChatWindow("ERROR - send with no file descriptor.");
}
}
void ChatManager::closeSPPConnection()
{
if (m_sppDataThread.isServer()) {
m_sppDataThread.resetFD();
bt_spp_close_server((char *) SPP_SERVICE_UUID);
} else {
if (m_sppDataThread.active()) {
int closeFD = m_sppDataThread.getFD();
m_sppDataThread.resetFD();
bt_spp_close(closeFD);
}
}
std::cout << "SPP Closed" << std::endl;
}
void ChatManager::incomingMessage(const QString &message)
{
updateChatWindow("They: " + message);
}
void ChatManager::updateChatWindow(const QString &msg)
{
if (m_chatHistory.size() > 0)
m_chatHistory.append("\n");
m_chatHistory.append(msg);
emit chatHistoryChanged();
}
void ChatManager::showDialog(const QString &title, const QString &message)
{
m_waitDialog.setTitle(title);
m_waitDialog.setBody(message);
m_waitDialog.show();
}
QString ChatManager::chatHistory() const
{
return m_chatHistory;
}