//-*-c++-*-
/***************************************************************************
 *   Copyright (C) 2003 by Fred Schaettgen                                 *
 *   kdebluetooth@schaettgen.de                                            *
 *                                                                         *
 *   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 2 of the License, or     *
 *   (at your option) any later version.                                   *
 ***************************************************************************/

#include "rfcommserversocket.h"

#include <errno.h>
#include <unistd.h>
#include <sys/time.h>
#include <sys/ioctl.h>
#include <sys/socket.h>
#include <bluetooth/bluetooth.h>
#include <bluetooth/rfcomm.h>
#include <qsocketnotifier.h>
#include "deviceaddress.h"
#include <kdebug.h>
#include "deviceaddress.h"

namespace KBluetooth
{

RfcommServerSocket::RfcommServerSocket(int port, QObject *parent, char* name) :
        QObject(parent, name)
{
    sockaddr_rc local_addr;
    int s;

    if ((s = ::socket(PF_BLUETOOTH, SOCK_STREAM, BTPROTO_RFCOMM)) < 0)
    {
        kdWarning() << QString("Can't create socket. %1 (%2)")
            .arg(strerror(errno)).arg(errno) << endl;
    }

    memset(&local_addr, 0, sizeof(local_addr));
    local_addr.rc_family = AF_BLUETOOTH;
    bdaddr_t addrAny = DeviceAddress::any.getBdaddr();
    bacpy(&local_addr.rc_bdaddr, &addrAny);
    local_addr.rc_channel = port;

    if (bind(s, (struct sockaddr *)&local_addr, sizeof(local_addr)) < 0)
    {
        kdWarning() << QString("Cannot bind socket. %1 (%2)")
            .arg(strerror(errno)).arg(errno) << endl;
        close(s);
    }

    if (listen(s, 10) < 0 )
    {
        kdWarning() << QString("Can't listen. %1 (%2)")
            .arg(strerror(errno)).arg(errno) << endl;
    }


    //setSocket(s);
    notifier = new QSocketNotifier(s, QSocketNotifier::Read,this);
    connect(notifier, SIGNAL(activated(int)), this, SLOT(acceptConnection(int)));
}

RfcommServerSocket::~RfcommServerSocket()
{
}


void RfcommServerSocket::acceptConnection(int s)
{
    struct sockaddr_rc rem_addr;
    socklen_t opt = sizeof(rem_addr);
    int newSocket;
    if ((newSocket=accept(s, (struct sockaddr *)&rem_addr, &opt))>=0)
    {
        char buf[20];
        ba2str(&rem_addr.rc_bdaddr, buf);
        kdDebug() << QString("Accepted connection from %1")
            .arg(buf) << endl;
        emit onNewConnection(newSocket, QString(buf));
    }
    else
    {
        kdWarning() << "Could not accept connection" << endl;
    }
}

}
#include "rfcommserversocket.moc"
