//-*-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 "scoserversocket.h"

#include <stdio.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/sco.h>
#include <qsocketnotifier.h>
#include <kdebug.h>
#include "deviceaddress.h"

namespace KBluetooth
{

ScoServerSocket::ScoServerSocket(QObject *parent, char* name) :
        QObject(parent, name)
{
    sockaddr_sco local_addr;
    int s;

    if ((s = ::socket(PF_BLUETOOTH, SOCK_SEQPACKET, BTPROTO_SCO)) < 0)
    {
        kdDebug() << "Can't create sco socket. "
            << strerror(errno) << errno << endl;
    }

    memset(&local_addr, 0, sizeof(local_addr));
    local_addr.sco_family = AF_BLUETOOTH;
    bdaddr_t addrAny = DeviceAddress::any.getBdaddr();
    bacpy(&local_addr.sco_bdaddr, &addrAny);

    if (bind(s, (struct sockaddr *)&local_addr, sizeof(local_addr)) < 0)
    {
        kdDebug() << "Cannot bind sco socket."
            << strerror(errno) << errno << endl;
        close(s);
    }

    if( listen(s, 10) < 0 )
    {
        kdDebug() << "Can't listen (sco). "
            << strerror(errno) << errno << endl;
    }


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

    kdDebug() << "Listening on SCO socket " << endl;
}

ScoServerSocket::~ScoServerSocket()
{

}


void ScoServerSocket::acceptConnection(int s)
{
    kdDebug() << "Accept SCO connection.." << endl;
    struct sockaddr_sco 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.sco_bdaddr, buf);
        kdDebug() << "Accepted connection from "
            << buf << endl;
        emit onNewConnection(newSocket, DeviceAddress(rem_addr.sco_bdaddr));
    }
    else
    {
        kdDebug() << "Could not accept connection" << endl;
    }
}


}

#include "scoserversocket.moc"
