qmisdnwatch - mISDN v2 GUI swissknife
http://www.misdn.org/index.php/Qmisdnwatch needs Qt4, compiles via 'qmake && make'
This commit is contained in:
parent
a66a3c83b0
commit
9f442954dc
|
@ -0,0 +1,40 @@
|
|||
qmisdnwatch
|
||||
|
||||
|
||||
AUTHOR
|
||||
-------
|
||||
Martin Bachem
|
||||
m.bachem@gmx.de
|
||||
|
||||
|
||||
LICENSE
|
||||
--------
|
||||
qmisdnwatch 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 version 2
|
||||
qmisdnwatch 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 qmisdnwatch. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
|
||||
REQUIREMENTS
|
||||
-------------
|
||||
mISDN v2
|
||||
Qt4
|
||||
|
||||
|
||||
COMPILE / RUN
|
||||
---------------
|
||||
qmake
|
||||
make
|
||||
./qmisdnwatch
|
||||
|
||||
DOCs
|
||||
-----
|
||||
http://www.misdn.org/index.php/Qmisdnwatch
|
||||
|
||||
|
||||
<end of file>
|
|
@ -0,0 +1,10 @@
|
|||
TEMPLATE = app
|
||||
TARGET =
|
||||
DEPENDPATH += . src
|
||||
INCLUDEPATH += . src
|
||||
|
||||
# not yet ;) LIBS += -lmisdn
|
||||
|
||||
# Input
|
||||
HEADERS += src/mainWindow.h src/misdn.h src/extraWidgets.h src/Ql1logThread.h
|
||||
SOURCES += src/main.cpp src/mainWindow.cpp src/misdn.cpp src/extraWidgets.cpp src/Ql1logThread.cpp
|
|
@ -0,0 +1,92 @@
|
|||
/* $Id: Ql1logThread.cpp 4 2008-10-28 00:04:24Z daxtar $
|
||||
* (c) 2008 Martin Bachem, m.bachem@gmx.de
|
||||
*
|
||||
* This file is part of qmisdnwatch
|
||||
*
|
||||
* Project's Home
|
||||
* http://www.misdn.org/index.php/Qmisdnwatch
|
||||
*
|
||||
* qmisdnwatch 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 version 2
|
||||
*
|
||||
* qmisdnwatch 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 qmisdnwatch. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#include <QByteArray>
|
||||
#include <sys/ioctl.h>
|
||||
#include "misdn.h"
|
||||
#include "Ql1logThread.h"
|
||||
|
||||
void Ql1logThread::run(void)
|
||||
{
|
||||
struct sockaddr_mISDN addr;
|
||||
int log_socket;
|
||||
dch_echo = misdn.openl1Log(devId, protocol, &log_socket, &addr);
|
||||
|
||||
qDebug("Ql1logThread::run log_socket(%i) devId(%d) proto(%d)",
|
||||
log_socket, devId, protocol);
|
||||
|
||||
if (log_socket >= 0)
|
||||
{
|
||||
struct msghdr mh;
|
||||
struct iovec iov[1];
|
||||
struct ctstamp cts;
|
||||
int ret;
|
||||
int buflen = 512;
|
||||
unsigned char buffer[buflen];
|
||||
|
||||
while (1) {
|
||||
mh.msg_name = NULL;
|
||||
mh.msg_namelen = 0;
|
||||
mh.msg_iov = iov;
|
||||
mh.msg_iovlen = 1;
|
||||
mh.msg_control = &cts;
|
||||
mh.msg_controllen = sizeof(cts);
|
||||
mh.msg_flags = 0;
|
||||
iov[0].iov_base = buffer;
|
||||
iov[0].iov_len = buflen;
|
||||
ret = recvmsg(log_socket, &mh, 0);
|
||||
|
||||
if (ret >= 0) {
|
||||
if (cts.cmsg_type != MISDN_TIME_STAMP) {
|
||||
cts.tv.tv_sec = 0;
|
||||
cts.tv.tv_usec = 0;
|
||||
}
|
||||
QByteArray * data = new QByteArray((const char *)buffer, ret);
|
||||
emit rcvData(devId, *data, cts.tv);
|
||||
}
|
||||
}
|
||||
} else
|
||||
qDebug("ERROR connecting log_socket");
|
||||
}
|
||||
|
||||
void Ql1logThread::setProtocol(int p) {
|
||||
protocol = p;
|
||||
qDebug("Ql1logThread protocol %d (%d)", protocol, p);
|
||||
}
|
||||
|
||||
int Ql1logThread::getProtocol(void) {
|
||||
return protocol;
|
||||
}
|
||||
|
||||
int Ql1logThread::hasEcho(void) {
|
||||
return (dch_echo);
|
||||
}
|
||||
|
||||
Ql1logThread::Ql1logThread(int id, mISDN & m) : devId(id), misdn(m) {
|
||||
dch_echo = -1;
|
||||
connect(this, SIGNAL(finished()), this, SLOT(finish()));
|
||||
}
|
||||
|
||||
void Ql1logThread::finish() {
|
||||
close(log_socket);
|
||||
emit finished(devId);
|
||||
}
|
|
@ -0,0 +1,60 @@
|
|||
/* $Id: Ql1logThread.h 4 2008-10-28 00:04:24Z daxtar $
|
||||
* (c) 2008 Martin Bachem, m.bachem@gmx.de
|
||||
*
|
||||
* This file is part of qmisdnwatch
|
||||
*
|
||||
* Project's Home
|
||||
* http://www.misdn.org/index.php/Qmisdnwatch
|
||||
*
|
||||
* qmisdnwatch 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 version 2
|
||||
*
|
||||
* qmisdnwatch 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 qmisdnwatch. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef _QL1LOGTHREAD_H_
|
||||
#define _QL1LOGTHREAD_H_
|
||||
|
||||
#include <QObject>
|
||||
#include <QThread>
|
||||
#include <QByteArray>
|
||||
#include "misdn.h"
|
||||
|
||||
class Ql1logThread : public QThread
|
||||
{
|
||||
Q_OBJECT
|
||||
private:
|
||||
int devId;
|
||||
mISDN & misdn;
|
||||
int protocol;
|
||||
int log_socket;
|
||||
int dch_echo;
|
||||
struct sockaddr_mISDN log_addr;
|
||||
|
||||
public:
|
||||
Ql1logThread(int id, mISDN & m);
|
||||
void setProtocol(int p);
|
||||
int getProtocol(void);
|
||||
int hasEcho(void);
|
||||
|
||||
protected:
|
||||
void run();
|
||||
|
||||
public slots:
|
||||
void finish();
|
||||
|
||||
signals:
|
||||
void finished(unsigned int id);
|
||||
void rcvData(unsigned int id, QByteArray data, struct timeval);
|
||||
};
|
||||
|
||||
|
||||
#endif // _QL1LOGTHREAD_H_
|
|
@ -0,0 +1,35 @@
|
|||
/* $Id: extraWidgets.cpp 4 2008-10-28 00:04:24Z daxtar $
|
||||
* (c) 2008 Martin Bachem, m.bachem@gmx.de
|
||||
*
|
||||
* This file is part of qmisdnwatch
|
||||
*
|
||||
* Project's Home
|
||||
* http://www.misdn.org/index.php/Qmisdnwatch
|
||||
*
|
||||
* qmisdnwatch 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 version 2
|
||||
*
|
||||
* qmisdnwatch 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 qmisdnwatch. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#include <QObject>
|
||||
#include <QWidget>
|
||||
#include <QPushButton>
|
||||
#include "extraWidgets.h"
|
||||
|
||||
idButton::idButton( const QString& text, unsigned int id, QWidget* parent )
|
||||
: QPushButton(text, parent), devId(id) {
|
||||
connect(this, SIGNAL(clicked()), this, SLOT(click()));
|
||||
}
|
||||
|
||||
void idButton::click() {
|
||||
emit clicked(devId);
|
||||
}
|
|
@ -0,0 +1,41 @@
|
|||
/* $Id: extraWidgets.h 4 2008-10-28 00:04:24Z daxtar $
|
||||
* (c) 2008 Martin Bachem, m.bachem@gmx.de
|
||||
*
|
||||
* This file is part of qmisdnwatch
|
||||
*
|
||||
* Project's Home
|
||||
* http://www.misdn.org/index.php/Qmisdnwatch
|
||||
*
|
||||
* qmisdnwatch 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 version 2
|
||||
*
|
||||
* qmisdnwatch 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 qmisdnwatch. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef _EXTRA_WIDGETS_H_
|
||||
#define _EXTRA_WIDGETS_H_
|
||||
|
||||
#include <QPushButton>
|
||||
|
||||
/* QBushbutton sending mISDN device ID at clicked() signal */
|
||||
class idButton : public QPushButton {
|
||||
Q_OBJECT
|
||||
public:
|
||||
idButton( const QString& text, unsigned int id, QWidget* parent = NULL );
|
||||
private:
|
||||
unsigned int devId;
|
||||
public slots:
|
||||
void click();
|
||||
signals:
|
||||
void clicked(unsigned int id);
|
||||
};
|
||||
|
||||
#endif // _EXTRA_WIDGETS_H_
|
|
@ -0,0 +1,39 @@
|
|||
/* $Id: main.cpp 4 2008-10-28 00:04:24Z daxtar $
|
||||
* (c) 2008 Martin Bachem, m.bachem@gmx.de
|
||||
*
|
||||
* This file is part of qmisdnwatch
|
||||
*
|
||||
* Project's Home
|
||||
* http://www.misdn.org/index.php/Qmisdnwatch
|
||||
*
|
||||
* qmisdnwatch 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 version 2
|
||||
*
|
||||
* qmisdnwatch 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 qmisdnwatch. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#include <QApplication>
|
||||
#include "mainWindow.h"
|
||||
#include "misdn.h"
|
||||
|
||||
Q_DECLARE_METATYPE(timeval);
|
||||
QDataStream &operator<<( QDataStream &out, const timeval& ) { return out; }
|
||||
QDataStream &operator>>( QDataStream &in, timeval& ) { return in; }
|
||||
|
||||
int main(int argc, char *argv[]) {
|
||||
qRegisterMetaType<timeval>("timeval");
|
||||
qRegisterMetaTypeStreamOperators<timeval>("timeval");
|
||||
|
||||
QApplication app(argc, argv);
|
||||
mainWindow* window = new mainWindow;
|
||||
window->show();
|
||||
return app.exec();
|
||||
}
|
|
@ -0,0 +1,662 @@
|
|||
/* $Id: mainWindow.cpp 7 2008-10-28 22:06:36Z daxtar $
|
||||
* (c) 2008 Martin Bachem, m.bachem@gmx.de
|
||||
*
|
||||
* This file is part of qmisdnwatch
|
||||
*
|
||||
* Project's Home
|
||||
* http://www.misdn.org/index.php/Qmisdnwatch
|
||||
*
|
||||
* qmisdnwatch 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 version 2
|
||||
*
|
||||
* qmisdnwatch 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 qmisdnwatch. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#include <QApplication>
|
||||
#include <QVBoxLayout>
|
||||
#include <QTreeWidget>
|
||||
#include <QTreeWidgetItem>
|
||||
#include <QTimer>
|
||||
#include <QLabel>
|
||||
#include <QInputDialog>
|
||||
#include <QByteArray>
|
||||
#include <QFile>
|
||||
#include <QFileDialog>
|
||||
#include <QDataStream>
|
||||
#include <QMessageBox>
|
||||
#include <QMenuBar>
|
||||
#include <QMenu>
|
||||
#include <mISDNuser/mISDNif.h>
|
||||
#include "mainWindow.h"
|
||||
|
||||
|
||||
struct isdnDeviceStuff * mainWindow::getStuffbyId(unsigned int id) {
|
||||
int i;
|
||||
for (i=0; i<devStack.count(); i++)
|
||||
if (devStack[i].id == id)
|
||||
return &devStack[i];
|
||||
return NULL;
|
||||
}
|
||||
|
||||
struct mISDN_devinfo * mainWindow::getDevInfoById(unsigned int id) {
|
||||
int i;
|
||||
for (i=0; i<deviceList.count(); i++)
|
||||
if (deviceList[i].id == id)
|
||||
return &deviceList[i];
|
||||
return NULL;
|
||||
}
|
||||
|
||||
int mainWindow::renameDevice(unsigned int id) {
|
||||
struct isdnDeviceStuff * thisDevStuff = getStuffbyId(id);
|
||||
if (!thisDevStuff)
|
||||
return -1;
|
||||
struct mISDN_devinfo * devInfo = getDevInfoById(id);
|
||||
if (!devInfo)
|
||||
return -1;
|
||||
|
||||
bool inputOk;
|
||||
QString newName = QInputDialog::getText(this, tr("device Name"), "new device name:",
|
||||
QLineEdit::Normal, QString(devInfo->name), &inputOk);
|
||||
if (inputOk && !newName.isEmpty()) {
|
||||
if (strcmp(newName.toAscii().data(), devInfo->name) != 0) {
|
||||
deviceListTimer->stop();
|
||||
if (!misdn.renameLayer1(id, newName.toAscii().data())) {
|
||||
strncpy(devInfo->name, newName.toAscii().data(), MISDN_MAX_IDLEN);
|
||||
tabsheet->setTabText(thisDevStuff->tabId, newName);
|
||||
thisDevStuff->treeHead->setText(0, newName);
|
||||
debugOut(thisDevStuff->log, tr("renamed device to '%1'\n")
|
||||
.arg(newName));
|
||||
} else {
|
||||
debugOut(thisDevStuff->log, tr("ERROR: renaming to '%1' failed\n")
|
||||
.arg(newName));
|
||||
}
|
||||
deviceListTimer->start(1000);
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int mainWindow::cleanL2(unsigned int id) {
|
||||
struct isdnDeviceStuff * thisDevStuff = getStuffbyId(id);
|
||||
if (!thisDevStuff)
|
||||
return -1;
|
||||
|
||||
int ret = misdn.cleanl2(id);
|
||||
if (ret >= 0)
|
||||
debugOut(thisDevStuff->log, tr("cleansed Layer2\n"));
|
||||
else {
|
||||
debugOut(thisDevStuff->log, tr("ERROR: cleaning L2 failed: "));
|
||||
if (ret == -4)
|
||||
debugOut(thisDevStuff->log, tr("no L2 protocol set\n"));
|
||||
else if (ret == -1)
|
||||
debugOut(thisDevStuff->log, tr("ioctrl invalid argument\n"));
|
||||
else
|
||||
debugOut(thisDevStuff->log, QString("%1\n").arg(ret));
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int mainWindow::logFinished(unsigned int id) {
|
||||
struct isdnDeviceStuff * thisDevStuff = getStuffbyId(id);
|
||||
if (!thisDevStuff)
|
||||
return -1;
|
||||
debugOut(thisDevStuff->log, tr("logging stopped\n"));
|
||||
if (thisDevStuff->l1log->hasEcho())
|
||||
thisDevStuff->buttonLogL1->setText(tr("start D-/E-Channel logging"));
|
||||
else
|
||||
thisDevStuff->buttonLogL1->setText(tr("start D-Channel logging"));
|
||||
return 0;
|
||||
}
|
||||
|
||||
void mainWindow::eyeSDNappend(QByteArray & target, QByteArray & data, int offset) {
|
||||
for (int i=offset; i<data.count(); i++) {
|
||||
unsigned char byte = data[i];
|
||||
if ((byte == 0xFF) || (byte == 0xFE)) {
|
||||
target.append(0xFE);
|
||||
byte -= 2;
|
||||
}
|
||||
target.append(byte);
|
||||
}
|
||||
}
|
||||
|
||||
void mainWindow::logRcvData(unsigned int id, QByteArray data, struct timeval tv) {
|
||||
struct isdnDeviceStuff * thisDevStuff = getStuffbyId(id);
|
||||
struct mISDN_devinfo * devInfo = getDevInfoById(id);
|
||||
struct tm *mt;
|
||||
unsigned char origin;
|
||||
int len;
|
||||
|
||||
if ((!thisDevStuff) || (!devInfo))
|
||||
return;
|
||||
|
||||
unsigned char buffer[data.count()];
|
||||
for (int i=0; i<data.count(); i++)
|
||||
buffer[i] = data[i];
|
||||
struct mISDNhead * hh = (struct mISDNhead *)buffer;
|
||||
|
||||
QString timeStr("");
|
||||
mt = localtime((time_t *)&tv.tv_sec);
|
||||
timeStr.sprintf("%02d.%02d.%04d %02d:%02d:%02d.%06ld:\t", mt->tm_mday, mt->tm_mon + 1, mt->tm_year + 1900,
|
||||
mt->tm_hour, mt->tm_min, mt->tm_sec, tv.tv_usec);
|
||||
debugOut(thisDevStuff->log, timeStr);
|
||||
|
||||
debugOut(thisDevStuff->log, QString("prim(0x%1)\tid(%2)")
|
||||
.arg(QString::number(hh->prim, 16))
|
||||
.arg(QString::number(hh->id, 16)));
|
||||
|
||||
binaryOut(thisDevStuff->log, data, sizeof(struct mISDNhead));
|
||||
|
||||
// collect data as eyeSDN stream to SaveAs wireshark readable
|
||||
if (thisDevStuff->l1log->hasEcho() && (hh->prim == PH_DATA_REQ))
|
||||
return;
|
||||
if ((hh->prim != PH_DATA_REQ) && (hh->prim != PH_DATA_IND) &&
|
||||
(hh->prim != PH_DATA_E_IND))
|
||||
return;
|
||||
|
||||
if (devInfo->protocol == ISDN_P_NT_S0 || devInfo->protocol == ISDN_P_NT_E1)
|
||||
origin = hh->prim == PH_DATA_REQ ? 0 : 1;
|
||||
else
|
||||
origin = ((hh->prim == PH_DATA_REQ) ||
|
||||
(hh->prim == PH_DATA_E_IND)) ? 1 : 0;
|
||||
|
||||
len = data.count() - MISDN_HEADER_LEN;
|
||||
QByteArray eyeHeader;
|
||||
eyeHeader.append((unsigned char)(0xff & (tv.tv_usec >> 16)));
|
||||
eyeHeader.append((unsigned char)(0xff & (tv.tv_usec >> 8)));
|
||||
eyeHeader.append((unsigned char)(0xff & tv.tv_usec));
|
||||
eyeHeader.append((char)0);
|
||||
eyeHeader.append((unsigned char)(0xff & (tv.tv_sec >> 24)));
|
||||
eyeHeader.append((unsigned char)(0xff & (tv.tv_sec >> 16)));
|
||||
eyeHeader.append((unsigned char)(0xff & (tv.tv_sec >> 8)));
|
||||
eyeHeader.append((unsigned char)(0xff & tv.tv_sec));
|
||||
eyeHeader.append((char)0);
|
||||
eyeHeader.append((unsigned char) origin);
|
||||
eyeHeader.append((unsigned char)(0xff & (len >> 8)));
|
||||
eyeHeader.append((unsigned char)(0xff & len));
|
||||
|
||||
/* add Frame escaped */
|
||||
thisDevStuff->eyeSDN.append(0xFF);
|
||||
eyeSDNappend(thisDevStuff->eyeSDN, eyeHeader, 0);
|
||||
eyeSDNappend(thisDevStuff->eyeSDN, data, sizeof(struct mISDNhead));
|
||||
}
|
||||
|
||||
int mainWindow::switchL1Logging(unsigned int id) {
|
||||
struct isdnDeviceStuff * thisDevStuff = getStuffbyId(id);
|
||||
struct mISDN_devinfo * devInfo = getDevInfoById(id);
|
||||
if ((!thisDevStuff) || (!devInfo))
|
||||
return -1;
|
||||
|
||||
if (thisDevStuff->l1log->isRunning()) {
|
||||
thisDevStuff->l1log->terminate();
|
||||
thisDevStuff->l1log->wait(1000);
|
||||
if (thisDevStuff->l1log->isRunning()) {
|
||||
debugOut(thisDevStuff->log, tr("ERROR: stop logging failed\n"));
|
||||
} else {
|
||||
thisDevStuff->buttonLogL1->setText(tr("start D-/E-Channel logging"));
|
||||
}
|
||||
} else {
|
||||
bool protoDefined=false;
|
||||
if (!devInfo->protocol) {
|
||||
QStringList items;
|
||||
if (devInfo->Dprotocols & (1 << ISDN_P_TE_S0))
|
||||
items << "TE mode S0 layer1";
|
||||
if (devInfo->Dprotocols & (1 << ISDN_P_NT_S0))
|
||||
items << "NT mode S0 layer1";
|
||||
if (devInfo->Dprotocols & (1 << ISDN_P_TE_E1))
|
||||
items << "TE mode E1 layer1";
|
||||
if (devInfo->Dprotocols & (1 << ISDN_P_NT_E1))
|
||||
items << "NT mode E1 layer1";
|
||||
if (devInfo->Dprotocols & (1 << ISDN_P_TE_UP0))
|
||||
items << "TE mode UP0 layer1";
|
||||
if (devInfo->Dprotocols & (1 << ISDN_P_NT_UP0))
|
||||
items << "NT mode UP0 layer1";
|
||||
QString value = QInputDialog::getItem(this,
|
||||
tr("select portmode"),
|
||||
tr("port still unused, please select layer1 mode:"),
|
||||
items, 0, false, &protoDefined);
|
||||
|
||||
if (protoDefined && !value.isEmpty()) {
|
||||
if (value == "TE mode S0 layer1")
|
||||
thisDevStuff->l1log->setProtocol(ISDN_P_TE_S0);
|
||||
if (value == "NT mode S0 layer1")
|
||||
thisDevStuff->l1log->setProtocol(ISDN_P_NT_S0);
|
||||
if (value == "TE mode E1 layer1")
|
||||
thisDevStuff->l1log->setProtocol(ISDN_P_TE_E1);
|
||||
if (value == "NT mode E1 layer1")
|
||||
thisDevStuff->l1log->setProtocol(ISDN_P_NT_E1);
|
||||
if (value == "TE mode UP0 layer1")
|
||||
thisDevStuff->l1log->setProtocol(ISDN_P_TE_UP0);
|
||||
if (value == "NT mode UP0 layer1")
|
||||
thisDevStuff->l1log->setProtocol(ISDN_P_NT_UP0);
|
||||
}
|
||||
} else {
|
||||
thisDevStuff->l1log->setProtocol(devInfo->protocol);
|
||||
protoDefined = true;
|
||||
}
|
||||
|
||||
if (protoDefined) {
|
||||
thisDevStuff->eyeSDN.clear();
|
||||
thisDevStuff->l1log->start();
|
||||
if (thisDevStuff->l1log->isRunning()) {
|
||||
QByteArray eyeHeader("EyeSDN");
|
||||
thisDevStuff->eyeSDN.append(eyeHeader);
|
||||
if (thisDevStuff->l1log->hasEcho()) {
|
||||
debugOut(thisDevStuff->log,
|
||||
tr("D/E channel logging started\n"));
|
||||
thisDevStuff->buttonLogL1->setText(
|
||||
tr("stop D-/E-Channel logging"));
|
||||
}
|
||||
else {
|
||||
debugOut(thisDevStuff->log,
|
||||
tr("D channel logging started\n"));
|
||||
thisDevStuff->buttonLogL1->setText(
|
||||
tr("stop D-Channel logging"));
|
||||
|
||||
}
|
||||
} else {
|
||||
debugOut(thisDevStuff->log,
|
||||
tr("ERROR: start logging failed\n"));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int mainWindow::saveL1Log(unsigned int id) {
|
||||
struct isdnDeviceStuff * thisDevStuff = getStuffbyId(id);
|
||||
struct mISDN_devinfo * devInfo = getDevInfoById(id);
|
||||
if ((!thisDevStuff) || (!devInfo))
|
||||
return -1;
|
||||
|
||||
QString filename;
|
||||
filename = QFileDialog::getSaveFileName(
|
||||
this, tr("Save Log As WireShark readable"));
|
||||
|
||||
// QString("%1").arg(QDir::currentPath()));
|
||||
|
||||
if (filename.isEmpty())
|
||||
return -1;
|
||||
|
||||
/* save complete file */
|
||||
QFile file(filename);
|
||||
file.open(QIODevice::WriteOnly);
|
||||
QDataStream out(&file);
|
||||
for (int i = 0; i < thisDevStuff->eyeSDN.count(); ++i) {
|
||||
unsigned char byte = thisDevStuff->eyeSDN[i];
|
||||
out.writeRawData((const char*)&byte, 1);
|
||||
}
|
||||
file.close();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void mainWindow::createNewDeviceTab(struct mISDN_devinfo *devinfo) {
|
||||
struct isdnDeviceStuff newDevStuff;
|
||||
qDebug("device %d arised (%s)", devinfo->id, devinfo->name);
|
||||
|
||||
newDevStuff.id = devinfo->id;
|
||||
newDevStuff.tab = new QWidget;
|
||||
newDevStuff.tabId = tabsheet->addTab(newDevStuff.tab,
|
||||
QString(devinfo->name));
|
||||
|
||||
/* Button 'rename' */
|
||||
newDevStuff.buttonRename = new idButton(tr("rename"),
|
||||
newDevStuff.id, newDevStuff.tab);
|
||||
connect(newDevStuff.buttonRename, SIGNAL(clicked(unsigned int)),
|
||||
this, SLOT(renameDevice(unsigned int)));
|
||||
|
||||
/* Button 'clean Layer2' */
|
||||
newDevStuff.buttonCleanL2 = new idButton(tr("clean Layer2"),
|
||||
newDevStuff.id, newDevStuff.tab);
|
||||
connect(newDevStuff.buttonCleanL2, SIGNAL(clicked(unsigned int)),
|
||||
this, SLOT(cleanL2(unsigned int)));
|
||||
|
||||
/* Button 'L1 logging' */
|
||||
newDevStuff.buttonLogL1 = new idButton(tr("start D-/E-Channel logging"),
|
||||
newDevStuff.id, newDevStuff.tab);
|
||||
connect(newDevStuff.buttonLogL1, SIGNAL(clicked(unsigned int)),
|
||||
this, SLOT(switchL1Logging(unsigned int)));
|
||||
|
||||
/* Button 'saveLog' */
|
||||
newDevStuff.buttonSaveLog = new idButton(tr("Save Log As"),
|
||||
newDevStuff.id, newDevStuff.tab);
|
||||
connect(newDevStuff.buttonSaveLog, SIGNAL(clicked(unsigned int)),
|
||||
this, SLOT(saveL1Log(unsigned int)));
|
||||
|
||||
/* mainLabel */
|
||||
newDevStuff.mainLabel = new QLabel(QString(tr("Device Controls")));
|
||||
|
||||
/* Text Widget */
|
||||
newDevStuff.log = new QTextEdit();
|
||||
|
||||
/* l1log Thread */
|
||||
newDevStuff.l1log = new Ql1logThread(devinfo->id, misdn);
|
||||
connect(newDevStuff.l1log, SIGNAL(finished(unsigned int)),
|
||||
this, SLOT(logFinished(unsigned int)));
|
||||
connect(newDevStuff.l1log, SIGNAL(rcvData(unsigned int, QByteArray, struct timeval)),
|
||||
this, SLOT(logRcvData(unsigned int, QByteArray, struct timeval)));
|
||||
|
||||
/* Layout */
|
||||
QVBoxLayout *vbox = new QVBoxLayout(newDevStuff.tab);
|
||||
vbox->addWidget(newDevStuff.mainLabel);
|
||||
QHBoxLayout *hbox = new QHBoxLayout();
|
||||
hbox->addWidget(newDevStuff.buttonRename);
|
||||
hbox->addSpacing(5);
|
||||
hbox->addWidget(newDevStuff.buttonCleanL2);
|
||||
hbox->addSpacing(5);
|
||||
hbox->addWidget(newDevStuff.buttonLogL1);
|
||||
hbox->addWidget(newDevStuff.buttonSaveLog);
|
||||
hbox->insertStretch(5, 0);
|
||||
vbox->addItem(hbox);
|
||||
vbox->addWidget(newDevStuff.log);
|
||||
|
||||
devStack << newDevStuff;
|
||||
}
|
||||
|
||||
void mainWindow::removeVanishedDevices(void) {
|
||||
int i, j;
|
||||
int vanishedDev=1;
|
||||
while (vanishedDev && devStack.count()) {
|
||||
for (i=(devStack.count()-1); i>=0; i--) {
|
||||
vanishedDev = 1;
|
||||
for (j=0; j<deviceList.count(); j++)
|
||||
if (devStack[i].id == deviceList[j].id)
|
||||
vanishedDev = 0;
|
||||
if (vanishedDev) {
|
||||
qDebug("device %d vansihed", devStack[i].id);
|
||||
tabsheet->removeTab(devStack[i].tabId);
|
||||
for(j=i+1; j<devStack.count(); j++)
|
||||
devStack[j].tabId--;
|
||||
devStack.removeAt(i);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void mainWindow::renewDeviceWidgets(void) {
|
||||
int i, j, n = deviceList.count();
|
||||
struct mISDN_devinfo devinfo;
|
||||
int newdev;
|
||||
|
||||
/* clear old widgets */
|
||||
devtree->clear();
|
||||
removeVanishedDevices();
|
||||
|
||||
QTreeWidgetItem* devitem;
|
||||
for (i=0; i<n; i++) {
|
||||
devinfo = deviceList[i];
|
||||
|
||||
newdev = 1;
|
||||
for (j=0; j<devStack.count(); j++)
|
||||
if (devinfo.id == devStack[j].id)
|
||||
newdev = 0;
|
||||
|
||||
/* create new Device Tab and stuff */
|
||||
if (newdev)
|
||||
createNewDeviceTab(&devinfo);
|
||||
|
||||
struct isdnDeviceStuff * thisDevStuff = getStuffbyId(devinfo.id);
|
||||
if (!thisDevStuff)
|
||||
return;
|
||||
|
||||
/* Update main Device Tree */
|
||||
devitem = new QTreeWidgetItem(devtree);
|
||||
devitem->setText(0, QString(devinfo.name));
|
||||
thisDevStuff->treeHead = devitem;
|
||||
|
||||
QTreeWidgetItem* optitem;
|
||||
|
||||
optitem = new QTreeWidgetItem(devitem);
|
||||
optitem->setText(0, tr("Id: %1")
|
||||
.arg(devinfo.id));
|
||||
|
||||
optitem = new QTreeWidgetItem(devitem);
|
||||
optitem->setText(0, tr("D protocols: %1")
|
||||
.arg(devinfo.Dprotocols));
|
||||
if (devinfo.Dprotocols) {
|
||||
QTreeWidgetItem* l1item = new QTreeWidgetItem(optitem);
|
||||
l1item->setText(0, tr("Layer 1"));
|
||||
|
||||
QTreeWidgetItem* doptitem;
|
||||
if (devinfo.Dprotocols & (1 << ISDN_P_TE_S0)) {
|
||||
doptitem = new QTreeWidgetItem(l1item);
|
||||
doptitem->setText(0, tr("S0 TE"));
|
||||
}
|
||||
if (devinfo.Dprotocols & (1 << ISDN_P_NT_S0)) {
|
||||
doptitem = new QTreeWidgetItem(l1item);
|
||||
doptitem->setText(0, tr("S0 NT"));
|
||||
}
|
||||
if (devinfo.Dprotocols & (1 << ISDN_P_TE_E1)) {
|
||||
doptitem = new QTreeWidgetItem(l1item);
|
||||
doptitem->setText(0, tr("E1 TE"));
|
||||
}
|
||||
if (devinfo.Dprotocols & (1 << ISDN_P_NT_E1)) {
|
||||
doptitem = new QTreeWidgetItem(l1item);
|
||||
doptitem->setText(0, tr("E1 NT"));
|
||||
}
|
||||
if (devinfo.Dprotocols & (1 << ISDN_P_TE_UP0)) {
|
||||
doptitem = new QTreeWidgetItem(l1item);
|
||||
doptitem->setText(0, tr("UP0 TE"));
|
||||
}
|
||||
if (devinfo.Dprotocols & (1 << ISDN_P_NT_UP0)) {
|
||||
doptitem = new QTreeWidgetItem(l1item);
|
||||
doptitem->setText(0, tr("UP0 NT"));
|
||||
}
|
||||
}
|
||||
|
||||
optitem = new QTreeWidgetItem(devitem);
|
||||
optitem->setText(0, tr("B protocols: %1")
|
||||
.arg(devinfo.Bprotocols));
|
||||
if (devinfo.Bprotocols) {
|
||||
QTreeWidgetItem* l1item = new QTreeWidgetItem(optitem);
|
||||
l1item->setText(0, QString("Layer 1"));
|
||||
QTreeWidgetItem* boptitem;
|
||||
if (devinfo.Bprotocols & (1 <<
|
||||
(ISDN_P_B_RAW
|
||||
- ISDN_P_B_START))) {
|
||||
boptitem = new QTreeWidgetItem(l1item);
|
||||
boptitem->setText(0,
|
||||
tr("RAW (transparent)"));
|
||||
}
|
||||
if (devinfo.Bprotocols & (1 <<
|
||||
(ISDN_P_B_HDLC
|
||||
- ISDN_P_B_START))) {
|
||||
boptitem = new QTreeWidgetItem(l1item);
|
||||
boptitem->setText(0, tr("HDLC"));
|
||||
}
|
||||
if (devinfo.Bprotocols & (1 <<
|
||||
(ISDN_P_B_X75SLP
|
||||
- ISDN_P_B_START))) {
|
||||
boptitem = new QTreeWidgetItem(l1item);
|
||||
boptitem->setText(0, tr("X.75"));
|
||||
}
|
||||
QTreeWidgetItem* l2item = new QTreeWidgetItem(optitem);
|
||||
l2item->setText(0, tr("Layer 2"));
|
||||
if (devinfo.Bprotocols & (1 <<
|
||||
(ISDN_P_B_L2DTMF
|
||||
- ISDN_P_B_START))) {
|
||||
boptitem = new QTreeWidgetItem(l2item);
|
||||
boptitem->setText(0, tr("DTMF"));
|
||||
}
|
||||
}
|
||||
optitem = new QTreeWidgetItem(devitem);
|
||||
optitem->setText(0, QString(tr("protocol: %1"))
|
||||
.arg(devinfo.protocol));
|
||||
QTreeWidgetItem* l1item = new QTreeWidgetItem(optitem);
|
||||
switch (devinfo.protocol) {
|
||||
case 0:
|
||||
l1item->setText(0, tr("unused"));
|
||||
break;
|
||||
case ISDN_P_TE_S0:
|
||||
l1item->setText(0, tr("S0 TE"));
|
||||
break;
|
||||
case ISDN_P_NT_S0:
|
||||
l1item->setText(0, tr("S0 NT"));
|
||||
break;
|
||||
case ISDN_P_TE_E1:
|
||||
l1item->setText(0, tr("E1 TE"));
|
||||
break;
|
||||
case ISDN_P_NT_E1:
|
||||
l1item->setText(0, tr("E1 NT"));
|
||||
break;
|
||||
case ISDN_P_TE_UP0:
|
||||
l1item->setText(0, tr("UP0 TE"));
|
||||
break;
|
||||
case ISDN_P_NT_UP0:
|
||||
l1item->setText(0, tr("UP0 NT"));
|
||||
break;
|
||||
default:
|
||||
l1item->setText(0, tr("unkown protocol"));
|
||||
break;
|
||||
}
|
||||
|
||||
optitem = new QTreeWidgetItem(devitem);
|
||||
optitem->setText(0, tr("B-Channels: %1")
|
||||
.arg(devinfo.nrbchan));
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
void mainWindow::updateDeviceList(void) {
|
||||
int i, j;
|
||||
QList <struct mISDN_devinfo> tmpDevList;
|
||||
int newdev = 0, oldnumdevs = misdn.getLastNumDevs();
|
||||
|
||||
i = misdn.getNumDevices();
|
||||
if (i < 0) {
|
||||
debugOut(logText, tr("unable to connect mISDN socket\n"));
|
||||
devtree->clear();
|
||||
return;
|
||||
}
|
||||
|
||||
if (i != oldnumdevs)
|
||||
debugOut(logText, tr("found %1 device%2\n")
|
||||
.arg(i)
|
||||
.arg((i==1)?"":"s"));
|
||||
|
||||
if (i >= 0) {
|
||||
struct mISDN_devinfo devinfo;
|
||||
|
||||
for (j=0; ((j<MAX_DEVICE_ID) && (tmpDevList.count() < i)); j++)
|
||||
if (misdn.getDeviceInfo(&devinfo, j) >= 0)
|
||||
tmpDevList << devinfo;
|
||||
|
||||
if (tmpDevList.count() == deviceList.count()) {
|
||||
for (j=0; j<deviceList.count(); j++)
|
||||
newdev |= memcmp(&tmpDevList[j],
|
||||
&deviceList[j],
|
||||
sizeof(struct mISDN_devinfo)-8);
|
||||
} else
|
||||
newdev = 1;
|
||||
|
||||
/* numDevices of devinfos had changed */
|
||||
if (newdev) {
|
||||
deviceList.clear();
|
||||
for (j=0; j<i; j++) {
|
||||
debugOut(logText, tr("id %1: '%2'\n")
|
||||
.arg(tmpDevList[j].id)
|
||||
.arg(QString(
|
||||
tmpDevList[j].name)));
|
||||
deviceList << tmpDevList[j];
|
||||
}
|
||||
renewDeviceWidgets();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void mainWindow::debugOut(QTextEdit * textEdit, QString text) {
|
||||
textEdit->moveCursor(QTextCursor::End);
|
||||
textEdit->insertPlainText(text);
|
||||
textEdit->ensureCursorVisible();
|
||||
}
|
||||
|
||||
void mainWindow::binaryOut(QTextEdit * textEdit, QByteArray & data, int offset) {
|
||||
int i, j=0;
|
||||
QString lz;
|
||||
if (offset < data.size())
|
||||
debugOut(textEdit, ": ");
|
||||
for (i=offset; i<data.size(); i++) {
|
||||
lz = (((unsigned char)data[i]) < 0x10)?"0":"";
|
||||
if (!(j++ % 8))
|
||||
debugOut(textEdit, "\n\t");
|
||||
debugOut(textEdit, QString("0x%1%2 ")
|
||||
.arg(lz)
|
||||
.arg(QString::number((unsigned char)data[i], 16))
|
||||
);
|
||||
}
|
||||
debugOut(textEdit, "\n\n");
|
||||
}
|
||||
|
||||
void mainWindow::about() {
|
||||
QMessageBox::information(this,
|
||||
tr("About qmisdnwatch"),
|
||||
tr("<b>qmisdnwatch</b> <b>v0.0.1</b><br>m.bachem@gmx.de<br>http://www.misdn.org/index.php/Qmisdnwatch"),
|
||||
QMessageBox::Ok);
|
||||
}
|
||||
|
||||
void mainWindow::aboutQt() {
|
||||
QMessageBox::aboutQt(this);
|
||||
}
|
||||
|
||||
// Neue Widget-Klasse vom eigentlichen Widget ableiten
|
||||
mainWindow::mainWindow( QMainWindow *parent,
|
||||
Qt::WindowFlags flags ) :
|
||||
QMainWindow(parent, flags)
|
||||
{
|
||||
resize(480, 400);
|
||||
|
||||
QWidget * centralwidget = new QWidget(this);
|
||||
tabsheet = new QTabWidget(centralwidget);
|
||||
maintab = new QWidget;
|
||||
|
||||
tabsheet->addTab(maintab, "mISDN");
|
||||
|
||||
QVBoxLayout *vbox01 = new QVBoxLayout(centralwidget);
|
||||
QVBoxLayout *vbox02 = new QVBoxLayout(maintab);
|
||||
|
||||
logText = new QTextEdit(maintab);
|
||||
logText->setMaximumHeight(120);
|
||||
|
||||
devtree = new QTreeWidget(maintab);
|
||||
devtree->setHeaderLabel(tr("mISDN v2 devices"));
|
||||
|
||||
deviceListTimer = new(QTimer);
|
||||
connect(deviceListTimer, SIGNAL(timeout()),
|
||||
this, SLOT(updateDeviceList()));
|
||||
|
||||
vbox01->addWidget(tabsheet);
|
||||
vbox02->addWidget(devtree);
|
||||
vbox02->addWidget(logText);
|
||||
|
||||
QMenu * optionsMenu = new QMenu(tr("Options"), this);
|
||||
// QMenu * actionsMenu = new QMenu(tr("Actions"), this);
|
||||
QMenu * helpMenu = new QMenu(tr("?"), this);
|
||||
helpMenu->addAction(tr("about qmisdnwatch"), this, SLOT(about()));
|
||||
helpMenu->addAction(tr("about Qt"), this, SLOT(aboutQt()));
|
||||
menuBar()->addMenu(optionsMenu);
|
||||
// menuBar()->addMenu(actionsMenu);
|
||||
menuBar()->addMenu(helpMenu);
|
||||
|
||||
setCentralWidget(centralwidget);
|
||||
setWindowTitle(QString ("qmisdnwatch"));
|
||||
|
||||
struct mISDNversion v;
|
||||
v = misdn.getVersion();
|
||||
debugOut(logText, tr("mISDN kernel driver v%1.%2.%4\n")
|
||||
.arg(v.major)
|
||||
.arg(v.minor)
|
||||
.arg(v.release));
|
||||
|
||||
updateDeviceList();
|
||||
deviceListTimer->start(1000);
|
||||
}
|
|
@ -0,0 +1,94 @@
|
|||
/* $Id: mainWindow.h 7 2008-10-28 22:06:36Z daxtar $
|
||||
* (c) 2008 Martin Bachem, m.bachem@gmx.de
|
||||
*
|
||||
* This file is part of qmisdnwatch
|
||||
*
|
||||
* Project's Home
|
||||
* http://www.misdn.org/index.php/Qmisdnwatch
|
||||
*
|
||||
* qmisdnwatch 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 version 2
|
||||
*
|
||||
* qmisdnwatch 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 qmisdnwatch. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef mainWindow_H
|
||||
#define mainWindow_H
|
||||
|
||||
#include <QWidget>
|
||||
#include <QMainWindow>
|
||||
#include <QTextEdit>
|
||||
#include <QTabWidget>
|
||||
#include <QTreeWidget>
|
||||
#include <QTimer>
|
||||
#include <QLabel>
|
||||
#include <QPushButton>
|
||||
#include <QThread>
|
||||
#include <mISDNuser/mISDNif.h>
|
||||
#include "Ql1logThread.h"
|
||||
#include "extraWidgets.h"
|
||||
#include "misdn.h"
|
||||
|
||||
|
||||
struct isdnDeviceStuff {
|
||||
unsigned int id;
|
||||
QWidget * tab; /* tab in TabWidget */
|
||||
int tabId; /* tabID in TabWidget */
|
||||
QLabel * mainLabel;
|
||||
QTreeWidgetItem * treeHead;
|
||||
QTextEdit * log;
|
||||
idButton * buttonRename;
|
||||
idButton * buttonCleanL2;
|
||||
idButton * buttonLogL1;
|
||||
idButton * buttonSaveLog;
|
||||
Ql1logThread * l1log;
|
||||
QByteArray eyeSDN;
|
||||
};
|
||||
|
||||
class mainWindow : public QMainWindow {
|
||||
Q_OBJECT
|
||||
public:
|
||||
mainWindow( QMainWindow *parent = 0,
|
||||
Qt::WindowFlags flags = 0 );
|
||||
|
||||
private:
|
||||
QList <struct mISDN_devinfo> deviceList;
|
||||
QList <struct isdnDeviceStuff> devStack;
|
||||
|
||||
QTabWidget * tabsheet;
|
||||
QWidget * maintab;
|
||||
QTreeWidget * devtree;
|
||||
QTimer * deviceListTimer;
|
||||
QTextEdit * logText;
|
||||
mISDN misdn;
|
||||
|
||||
void renewDeviceWidgets(void);
|
||||
void removeVanishedDevices(void);
|
||||
void createNewDeviceTab(struct mISDN_devinfo *devinfo);
|
||||
void debugOut(QTextEdit * textEdit, QString text);
|
||||
void binaryOut(QTextEdit * textEdit, QByteArray & data, int offset);
|
||||
struct isdnDeviceStuff * getStuffbyId(unsigned int id);
|
||||
struct mISDN_devinfo * getDevInfoById(unsigned int id);
|
||||
void eyeSDNappend(QByteArray & target, QByteArray & data, int offset);
|
||||
|
||||
private slots:
|
||||
void updateDeviceList(void);
|
||||
int renameDevice(unsigned int id);
|
||||
int cleanL2(unsigned int id);
|
||||
int switchL1Logging(unsigned int id);
|
||||
int saveL1Log(unsigned int id);
|
||||
void logRcvData(unsigned int id, QByteArray data, struct timeval tv);
|
||||
int logFinished(unsigned int id);
|
||||
void about();
|
||||
void aboutQt();
|
||||
};
|
||||
|
||||
#endif
|
|
@ -0,0 +1,173 @@
|
|||
/* $Id: misdn.cpp 4 2008-10-28 00:04:24Z daxtar $
|
||||
* (c) 2008 Martin Bachem, m.bachem@gmx.de
|
||||
*
|
||||
* This file is part of qmisdnwatch
|
||||
*
|
||||
* Project's Home
|
||||
* http://www.misdn.org/index.php/Qmisdnwatch
|
||||
*
|
||||
* qmisdnwatch 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 version 2
|
||||
*
|
||||
* qmisdnwatch 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 qmisdnwatch. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "misdn.h"
|
||||
|
||||
#define AF_COMPATIBILITY_FUNC
|
||||
#define MISDN_OLD_AF_COMPATIBILITY
|
||||
#include <mISDNuser/compat_af_isdn.h>
|
||||
|
||||
|
||||
mISDN::mISDN(void) {
|
||||
numdevices = -1;
|
||||
init_af_isdn();
|
||||
sock = socket(PF_ISDN, SOCK_RAW, ISDN_P_BASE);
|
||||
if (sock >= 0)
|
||||
queryVersion();
|
||||
}
|
||||
|
||||
mISDN::~mISDN(void) {
|
||||
if (sock >= 0) {
|
||||
close(sock);
|
||||
}
|
||||
}
|
||||
|
||||
struct mISDNversion mISDN::getVersion(void) {
|
||||
return(kver);
|
||||
}
|
||||
|
||||
void mISDN::queryVersion(void) {
|
||||
struct mISDNversion v;
|
||||
int ret;
|
||||
if (sock >= 0) {
|
||||
ret = ioctl(sock, IMGETVERSION, &v);
|
||||
if (ret >= 0)
|
||||
memcpy(&kver, &v, sizeof(struct mISDNversion));
|
||||
}
|
||||
}
|
||||
|
||||
int mISDN::getNumDevices(void) {
|
||||
int cnt, ret = 0;
|
||||
if (sock >= 0) {
|
||||
ret = ioctl(sock, IMGETCOUNT, &cnt);
|
||||
if (!ret) {
|
||||
numdevices = cnt;
|
||||
return(cnt);
|
||||
}
|
||||
}
|
||||
return(-1);
|
||||
}
|
||||
|
||||
int mISDN::getDeviceInfo(struct mISDN_devinfo *devinfo, int id) {
|
||||
int ret;
|
||||
if (sock >= 0) {
|
||||
devinfo->id = id;
|
||||
try {
|
||||
ret = ioctl(sock, IMGETDEVINFO, devinfo);
|
||||
if (!ret)
|
||||
return 0;
|
||||
}
|
||||
catch (...) {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
return -2;
|
||||
}
|
||||
|
||||
/*
|
||||
* returns
|
||||
* <0 on error
|
||||
* =0 socket open with no E-Channel logfing available
|
||||
* =1 socket open with E-Channel logging enabled
|
||||
*/
|
||||
int mISDN::openl1Log(int id, int protocol, int * log_socket,
|
||||
struct sockaddr_mISDN * log_addr)
|
||||
{
|
||||
int ret, channel;
|
||||
if ((*log_socket = socket(PF_ISDN, SOCK_DGRAM, protocol)) >= 0)
|
||||
{
|
||||
log_addr->family = AF_ISDN;
|
||||
log_addr->dev = id;
|
||||
ret = -1;
|
||||
channel = 1;
|
||||
while ((ret < 0) && (channel >= 0)) {
|
||||
log_addr->channel = (unsigned char)channel;
|
||||
ret = bind(*log_socket, (struct sockaddr *)log_addr,
|
||||
sizeof(struct sockaddr_mISDN));
|
||||
if (ret < 0)
|
||||
channel--;
|
||||
}
|
||||
int opt=1;
|
||||
setsockopt(*log_socket, SOL_MISDN, MISDN_TIME_STAMP,
|
||||
&opt, sizeof(opt));
|
||||
return (log_addr->channel == 1);
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
int mISDN::getLastNumDevs(void) {
|
||||
return(numdevices);
|
||||
}
|
||||
|
||||
int mISDN::renameLayer1(unsigned int id, char * name) {
|
||||
struct mISDN_devrename devrename;
|
||||
int ret;
|
||||
if (sock >= 0) {
|
||||
devrename.id = id;
|
||||
strncpy(devrename.name, name, MISDN_MAX_IDLEN);
|
||||
ret = ioctl(sock, IMSETDEVNAME, &devrename);
|
||||
return ret;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
int mISDN::cleanl2(unsigned int id) {
|
||||
int ret;
|
||||
if (sock >= 0) {
|
||||
struct mISDN_devinfo devinfo;
|
||||
if (getDeviceInfo(&devinfo, id) >= 0) {
|
||||
if (!devinfo.protocol)
|
||||
return -4;
|
||||
|
||||
int l2sock;
|
||||
if (IS_ISDN_P_TE(devinfo.protocol))
|
||||
l2sock = socket(PF_ISDN, SOCK_DGRAM,
|
||||
ISDN_P_LAPD_TE);
|
||||
else
|
||||
l2sock = socket(PF_ISDN, SOCK_DGRAM,
|
||||
ISDN_P_LAPD_NT);
|
||||
if (l2sock >= 0) {
|
||||
struct sockaddr_mISDN addr;
|
||||
addr.family = AF_ISDN;
|
||||
addr.dev = id;
|
||||
addr.channel = 0;
|
||||
addr.sapi = 0;
|
||||
addr.tei = 127;
|
||||
ret = bind(l2sock, (struct sockaddr *) &addr,
|
||||
sizeof(addr));
|
||||
if (ret >= 0) {
|
||||
int clean = 1;
|
||||
ret = ioctl(l2sock, IMCLEAR_L2, &clean);
|
||||
if (ret < 0)
|
||||
return -1;
|
||||
return 0;
|
||||
} else
|
||||
return -2;
|
||||
} else
|
||||
return -3;
|
||||
} else
|
||||
return -6;
|
||||
}
|
||||
return -7;
|
||||
}
|
|
@ -0,0 +1,102 @@
|
|||
/* $Id: misdn.h 6 2008-10-28 19:50:12Z daxtar $
|
||||
* (c) 2008 Martin Bachem, m.bachem@gmx.de
|
||||
*
|
||||
* This file is part of qmisdnwatch
|
||||
*
|
||||
* Project's Home
|
||||
* http://www.misdn.org/index.php/Qmisdnwatch
|
||||
*
|
||||
* qmisdnwatch 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 version 2
|
||||
*
|
||||
* qmisdnwatch 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 qmisdnwatch. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef _MISDN_H_
|
||||
#define _MISDN_H_
|
||||
|
||||
#include <sys/time.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <netinet/udp.h>
|
||||
#include <netinet/in.h>
|
||||
#include <netdb.h>
|
||||
#include <linux/socket.h>
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
#include <fcntl.h>
|
||||
#include <errno.h>
|
||||
#include <string.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <mISDNuser/mISDNif.h>
|
||||
#include <mISDNuser/q931.h>
|
||||
|
||||
|
||||
#ifndef ISDN_P_TE_UP0
|
||||
#define ISDN_P_TE_UP0 0x05
|
||||
#endif
|
||||
|
||||
#ifndef ISDN_P_NT_UP0
|
||||
#define ISDN_P_NT_UP0 0x06
|
||||
#endif
|
||||
|
||||
#ifndef IS_ISDN_P_TE
|
||||
#define IS_ISDN_P_TE(p) ((p == ISDN_P_TE_S0) || (p == ISDN_P_TE_E1) || \
|
||||
(p == ISDN_P_TE_UP0) || (p == ISDN_P_LAPD_TE))
|
||||
#endif
|
||||
#ifndef IS_ISDN_P_NT
|
||||
#define IS_ISDN_P_NT(p) ((p == ISDN_P_NT_S0) || (p == ISDN_P_NT_E1) || \
|
||||
(p == ISDN_P_NT_UP0) || (p == ISDN_P_LAPD_NT))
|
||||
#endif
|
||||
#ifndef IS_ISDN_P_S0
|
||||
#define IS_ISDN_P_S0(p) ((p == ISDN_P_TE_S0) || (p == ISDN_P_NT_S0))
|
||||
#endif
|
||||
#ifndef IS_ISDN_P_E1
|
||||
#define IS_ISDN_P_E1(p) ((p == ISDN_P_TE_E1) || (p == ISDN_P_NT_E1))
|
||||
#endif
|
||||
#ifndef IS_ISDN_P_UP0
|
||||
#define IS_ISDN_P_UP0(p) ((p == ISDN_P_TE_UP0) || (p == ISDN_P_NT_UP0))
|
||||
#endif
|
||||
|
||||
|
||||
class mISDN {
|
||||
public:
|
||||
mISDN(void);
|
||||
~mISDN(void);
|
||||
int getNumDevices(void);
|
||||
int getDeviceInfo(struct mISDN_devinfo *devinfo, int id);
|
||||
int getLastNumDevs(void);
|
||||
struct mISDNversion getVersion(void);
|
||||
|
||||
/* socket helper */
|
||||
int openl1Log(int id, int protocol, int * log_socket,
|
||||
struct sockaddr_mISDN * log_addr);
|
||||
|
||||
/* tools / examples */
|
||||
int renameLayer1(unsigned int id, char * name);
|
||||
int cleanl2(unsigned int id);
|
||||
|
||||
private:
|
||||
void queryVersion(void);
|
||||
int numdevices; // devicesNumber
|
||||
int sock; // base socket handles
|
||||
struct mISDNversion kver; // mISDN kernel version
|
||||
};
|
||||
|
||||
struct ctstamp {
|
||||
size_t cmsg_len;
|
||||
int cmsg_level;
|
||||
int cmsg_type;
|
||||
struct timeval tv;
|
||||
};
|
||||
|
||||
|
||||
#endif // _MISDN_H_
|
Loading…
Reference in New Issue