Compare commits
78 Commits
Author | SHA1 | Date |
---|---|---|
Harald Welte | ca72be85e9 | |
Harald Welte | 3bce40c22a | |
Harald Welte | b718bf65e4 | |
Harald Welte | 09b37dd814 | |
Harald Welte | 465dec0d27 | |
Harald Welte | 4d45ae8289 | |
Karsten Keil | d6818dd9a4 | |
Christoph Schulz | b45d87e52b | |
Karsten Keil | 710b87dcb9 | |
Karsten Keil | e5088699fb | |
Christian Herdtweck | a28cb6bc53 | |
Christian Herdtweck | 4f7cea4028 | |
Karsten Keil | 0f8548b3d2 | |
Karsten Keil | 488c9ea1c8 | |
Karsten Keil | c9e711960b | |
Karsten Keil | 25c7d7bbf5 | |
Thomas Jarosch | bdb5d3903c | |
Karsten Keil | 5875f14832 | |
Karsten Keil | 9097f56457 | |
Karsten Keil | 7d12683f36 | |
Karsten Keil | 3c6665d794 | |
Karsten Keil | d263d37f77 | |
Karsten Keil | 46b4dd6a25 | |
Karsten Keil | 56c333ab10 | |
Karsten Keil | cc80463f23 | |
Karsten Keil | 234e9bc9ce | |
Karsten Keil | 4be89daf43 | |
Karsten Keil | 79f85a5f96 | |
Karsten Keil | ae15977c06 | |
Karsten Keil | 9f5d377216 | |
Karsten Keil | 002a6e4bcb | |
Karsten Keil | ce11bd31a3 | |
Karsten Keil | 6cdc34ef49 | |
Karsten Keil | acd627c996 | |
Karsten Keil | bf6813426b | |
Karsten Keil | f732c35c3d | |
Christoph Schulz | 0d7fc6fd37 | |
Christoph Schulz | be0f62c087 | |
Christoph Schulz | cf98743fb3 | |
Christoph Schulz | 86da1e4546 | |
Christoph Schulz | c3c05bfb63 | |
Karsten Keil | 1acabc5db3 | |
Martin Bachem | a29326031e | |
Martin Bachem | 1bade6d562 | |
Martin Bachem | b76e29c8c3 | |
Maciej S. Szmigiero | 21b8c52a64 | |
Maciej S. Szmigiero | e3e71a7f94 | |
Maciej S. Szmigiero | 6e79260425 | |
Maciej S. Szmigiero | a50c5b93da | |
Maciej S. Szmigiero | 0cac6f5176 | |
Maciej S. Szmigiero | 99bccfa7b9 | |
Karsten Keil | 7e1924062d | |
Karsten Keil | c686153484 | |
Maciej S. Szmigiero | b4b3e62516 | |
Maciej S. Szmigiero | 06ed113c3d | |
Maciej S. Szmigiero | 4caaa5ac72 | |
Karsten Keil | 40aa4b22c1 | |
Thomas Jarosch | 6c25cdacd3 | |
Martin Bachem | bc5d24d5b2 | |
Karsten Keil | 3638cf36df | |
Karsten Keil | bd6ea3f85f | |
Karsten Keil | fc757c58dc | |
Karsten Keil | d9a97bb810 | |
Karsten Keil | 69cd05567c | |
Karsten Keil | 70c61ca931 | |
Karsten Keil | ed6c40581e | |
Karsten Keil | 50b4970832 | |
Karsten Keil | 43cd10a657 | |
Karsten Keil | 8a0d743a08 | |
Karsten Keil | d927b710c6 | |
Karsten Keil | dee4e5684a | |
Karsten Keil | ec4ac2763f | |
Andreas Eversberg | 1dc4c24d27 | |
Joerg Dorchain | 3293be0592 | |
Norbert Weyrich | df131f57d4 | |
Karsten Keil | 640ba25164 | |
Karsten Keil | 7e5e9df238 | |
Karsten Keil | d980284891 |
|
@ -45,3 +45,6 @@ config.sub
|
|||
DEADJOE
|
||||
.dirstamp
|
||||
libtool
|
||||
ar-lib
|
||||
capi20/m_capi_sock.h
|
||||
ylwrap
|
||||
|
|
|
@ -0,0 +1 @@
|
|||
theme: jekyll-theme-merlot
|
|
@ -150,7 +150,7 @@ static void ph_control(int sock, int c1, int c2)
|
|||
unsigned char data[MISDN_HEADER_LEN+sizeof(int)+sizeof(int)];
|
||||
struct mISDNhead *hh = (struct mISDNhead *)data;
|
||||
int len;
|
||||
unsigned long *d = (unsigned long *)(data + MISDN_HEADER_LEN);
|
||||
int *d = (int *)(data + MISDN_HEADER_LEN);
|
||||
|
||||
hh->prim = PH_CONTROL_REQ;
|
||||
hh->id = 0;
|
||||
|
@ -167,7 +167,7 @@ void ph_control_block(int sock, int c1, void *c2, int c2_len)
|
|||
unsigned char data[MISDN_HEADER_LEN+sizeof(int)+c2_len];
|
||||
struct mISDNhead *hh = (struct mISDNhead *)data;
|
||||
int len;
|
||||
unsigned long *d = (unsigned long *)(data + MISDN_HEADER_LEN);
|
||||
int *d = (int *)(data + MISDN_HEADER_LEN);
|
||||
|
||||
hh->prim = PH_CONTROL_REQ;
|
||||
hh->id = 0;
|
||||
|
@ -324,7 +324,7 @@ int mISDN_handler(void)
|
|||
mISDNport->prev->que_len = len;
|
||||
hh->prim = PH_ACTIVATE_REQ;
|
||||
hh->id = 0;
|
||||
len = sendto(mISDNport->d_sock, data, MISDN_HEADER_LEN, 0, NULL, 0);
|
||||
len = sendto(mISDNport->prev->d_sock, data, MISDN_HEADER_LEN, 0, NULL, 0);
|
||||
if (len <= 0)
|
||||
fprintf(stderr, "Failed to send to socket %d of port %d\n", mISDNport->d_sock, mISDNport->portnum);
|
||||
}
|
||||
|
@ -349,7 +349,7 @@ int mISDN_handler(void)
|
|||
mISDNport->next->que_len = len;
|
||||
hh->prim = PH_ACTIVATE_REQ;
|
||||
hh->id = 0;
|
||||
len = sendto(mISDNport->d_sock, data, MISDN_HEADER_LEN, 0, NULL, 0);
|
||||
len = sendto(mISDNport->next->d_sock, data, MISDN_HEADER_LEN, 0, NULL, 0);
|
||||
if (len <= 0)
|
||||
fprintf(stderr, "Failed to send to socket %d of port %d\n", mISDNport->d_sock, mISDNport->portnum);
|
||||
}
|
||||
|
|
|
@ -20,14 +20,10 @@ EXTRA_DIST = capi20.conf.sample
|
|||
|
||||
CLEANFILES = *~
|
||||
|
||||
MISDN_SOCKET_DIR = $(localstatedir)/run/mISDNcapid
|
||||
|
||||
install-exec-hook:
|
||||
install -d $(DESTDIR)$(MISDN_SOCKET_DIR)
|
||||
|
||||
install-data-local:
|
||||
install -d $(DESTDIR)$(sysconfdir)
|
||||
install -m 644 capi20.conf.sample $(DESTDIR)$(sysconfdir)/capi20.conf
|
||||
|
||||
distuninstallcheck_listfiles = \
|
||||
find . -type f -print | grep -v 'capi20.conf'
|
||||
|
||||
|
|
|
@ -1,5 +1,9 @@
|
|||
#include "alaw.h"
|
||||
|
||||
signed char lin2alaw[65536]; // 16bit unsigned index
|
||||
signed char *slin2alaw; // 16bit signed index
|
||||
uint16_t alaw2lin[256]; // alaw -> 16bit PCM, Mono, 8000 hz
|
||||
|
||||
// alaw -> signed 16-bit
|
||||
static short alaw_to_lin[] = {
|
||||
0x13fc, 0xec04, 0x0144, 0xfebc, 0x517c, 0xae84, 0x051c, 0xfae4,
|
||||
|
|
|
@ -2,9 +2,9 @@
|
|||
#define _ALAW_H
|
||||
#include <stdint.h>
|
||||
|
||||
signed char lin2alaw[65536]; // 16bit unsigned index
|
||||
signed char *slin2alaw; // 16bit signed index
|
||||
uint16_t alaw2lin[256]; // alaw -> 16bit PCM, Mono, 8000 hz
|
||||
extern signed char lin2alaw[65536]; // 16bit unsigned index
|
||||
extern signed char *slin2alaw; // 16bit signed index
|
||||
extern uint16_t alaw2lin[256]; // alaw -> 16bit PCM, Mono, 8000 hz
|
||||
|
||||
void create_lin2alaw_table(void);
|
||||
#endif
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/*
|
||||
/*
|
||||
* application.c
|
||||
*
|
||||
* Written by Karsten Keil <kkeil@linux-pingi.de>
|
||||
|
@ -103,8 +103,12 @@ int register_lController(struct mApplication *appl, struct lController *lc)
|
|||
eprint("%s: controller idx %d ID:%d\already registered\n", CAPIobjIDstr(&appl->cobj), i, lc->cobj.id);
|
||||
return -EBUSY;
|
||||
}
|
||||
appl->lcl[i] = lc;
|
||||
get_cobj(&lc->cobj);
|
||||
if (get_cobj(&lc->cobj)) {
|
||||
appl->lcl[i] = lc;
|
||||
} else {
|
||||
eprint("%s: controller idx %d cannot get controller object %s\n", CAPIobjIDstr(&appl->cobj), i, CAPIobjIDstr(&lc->cobj));
|
||||
return -EINVAL;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -135,9 +139,16 @@ void ReleaseApplication(struct mApplication *appl, int unregister)
|
|||
|
||||
appl->unregistered = unregister;
|
||||
|
||||
ret = pipe2(appl->cpipe, O_NONBLOCK);
|
||||
if (ret)
|
||||
eprint("%s: Cannot open control pipe - %s\n", CAPIobjIDstr(&appl->cobj), strerror(errno));
|
||||
if (appl->cpipe[0] > -1 && appl->cpipe[1] > -1) {
|
||||
wprint("%s appl->cpipe(%d, %d) still open - reuse fds\n", CAPIobjIDstr(&appl->cobj), appl->cpipe[0], appl->cpipe[1]);
|
||||
} else {
|
||||
ret = pipe2(appl->cpipe, O_NONBLOCK);
|
||||
if (ret)
|
||||
eprint("%s: Cannot open control pipe - %s\n", CAPIobjIDstr(&appl->cobj), strerror(errno));
|
||||
else
|
||||
dprint(MIDEBUG_CONTROLLER, "create appl->cpipe(%d, %d)\n", appl->cpipe[0], appl->cpipe[1]);
|
||||
}
|
||||
dprint(MIDEBUG_CONTROLLER, "close appl->fd %d\n", appl->fd);
|
||||
close(appl->fd);
|
||||
appl->fd = -1;
|
||||
|
||||
|
@ -193,9 +204,11 @@ void Free_Application(struct mCAPIobj *co)
|
|||
}
|
||||
if (!appl->unregistered) /* filedescriptor was closed */
|
||||
capi_freeapplid(appl->cobj.id2);
|
||||
dprint(MIDEBUG_CONTROLLER, "close appl->fd %d\n", appl->fd);
|
||||
if (appl->fd > 0)
|
||||
close(appl->fd);
|
||||
appl->fd = -1;
|
||||
dprint(MIDEBUG_CONTROLLER, "close appl->cpipe(%d, %d)\n", appl->cpipe[0], appl->cpipe[1]);
|
||||
if (appl->cpipe[1] > 0)
|
||||
close(appl->cpipe[1]);
|
||||
appl->cpipe[1] = -1;
|
||||
|
@ -228,7 +241,7 @@ void dump_applications(void)
|
|||
ap = container_of(co, struct mApplication, cobj);
|
||||
iprint("%s: MaxB3Con:%d MaxB3Blk:%d MaxB3Size:%d\n", CAPIobjIDstr(&ap->cobj),
|
||||
ap->MaxB3Con, ap->MaxB3Blk, ap->MaxB3Size);
|
||||
iprint("%s: Refs:%d cleaned:%s unregistered:%s cpipe(%d,%d)\n", CAPIobjIDstr(&ap->cobj),
|
||||
iprint("%s: Refs:%d cleaned:%s unregistered:%s cpipe(%d, %d)\n", CAPIobjIDstr(&ap->cobj),
|
||||
ap->cobj.refcnt, ap->cobj.cleaned ? "yes" : "no", ap->unregistered ? "yes" : "no",
|
||||
ap->cpipe[0], ap->cpipe[1]);
|
||||
for (i = 0; i < mI_ControllerCount; i++) {
|
||||
|
@ -281,8 +294,12 @@ struct lController *get_lController(struct mApplication *appl, unsigned int cont
|
|||
wprint("%s: wrong controller id %d (max %d)\n", CAPIobjIDstr(&appl->cobj), cont, mI_ControllerCount);
|
||||
lc = NULL;
|
||||
}
|
||||
if (lc)
|
||||
get_cobj(&lc->cobj);
|
||||
if (lc) {
|
||||
if (!get_cobj(&lc->cobj)) {
|
||||
wprint("%s: cannot get controller object %s\n", CAPIobjIDstr(&appl->cobj), CAPIobjIDstr(&lc->cobj));
|
||||
lc = NULL;
|
||||
}
|
||||
}
|
||||
return lc;
|
||||
}
|
||||
|
||||
|
@ -361,7 +378,8 @@ void SendCmsg2Application(struct mApplication *appl, struct mc_buf *mc)
|
|||
mCapi_message2str(mc);
|
||||
ret = send(appl->fd, mc->rb, mc->len, 0);
|
||||
if (ret != mc->len)
|
||||
eprint("Message send error len=%d ret=%d - %s\n", mc->len, ret, strerror(errno));
|
||||
eprint("%s: Message send error fd=%d len=%d ret=%d - %s\n",
|
||||
CAPIobjIDstr(&appl->cobj), appl->fd, mc->len, ret, strerror(errno));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -26,6 +26,8 @@ static struct mCAPIobj *danglinglist;
|
|||
static pthread_mutex_t uniqLock = PTHREAD_MUTEX_INITIALIZER;
|
||||
static unsigned int uniqID = 1;
|
||||
|
||||
static pthread_mutex_t rootLock = PTHREAD_MUTEX_INITIALIZER;
|
||||
|
||||
#ifdef MISDN_CAPI_REFCOUNT_DEBUG
|
||||
#define cobj_dbg(fmt, ...) do {\
|
||||
if (file && (MIDEBUG_CAPIOBJ & mI_debug_mask))\
|
||||
|
@ -130,6 +132,7 @@ void CAPIobj_exit(void)
|
|||
while (co) {
|
||||
cn = co->nextD;
|
||||
eprint("%s: uid=%i refcnt %d in dangling list - freeing now\n", CAPIobjIDstr(co), co->uid, co->refcnt);
|
||||
co->cleaned = 1;
|
||||
cobj_free(co);
|
||||
co = cn;
|
||||
}
|
||||
|
@ -355,19 +358,32 @@ struct mCAPIobj *__get_cobj(struct mCAPIobj *co, const char *file, int lineno)
|
|||
struct mCAPIobj *get_cobj(struct mCAPIobj *co)
|
||||
#endif
|
||||
{
|
||||
struct mCAPIobj *p;
|
||||
|
||||
if (co) {
|
||||
if (co->parent) {
|
||||
pthread_rwlock_wrlock(&co->parent->lock);
|
||||
p = co->parent;
|
||||
if (p) {
|
||||
pthread_rwlock_wrlock(&p->lock);
|
||||
} else {
|
||||
if (co->type != Cot_Root) { /* has no parent */
|
||||
cobj_warn("%s: parent not assigned\n", CAPIobjIDstr(co));
|
||||
cobj_err("%s: parent not assigned\n", CAPIobjIDstr(co));
|
||||
return NULL;
|
||||
}
|
||||
pthread_mutex_lock(&rootLock);
|
||||
}
|
||||
co->refcnt++;
|
||||
coref_dbg("%s\n", CAPIobjIDstr(co));
|
||||
if (co->parent)
|
||||
pthread_rwlock_unlock(&co->parent->lock);
|
||||
if (co->cleaned) {
|
||||
cobj_warn("%s: pending free detected - do not get object\n", CAPIobjIDstr(co));
|
||||
co = NULL;
|
||||
} else {
|
||||
if (co->freeing)
|
||||
cobj_err("Currently freeing %s refcnt: %d\n", CAPIobjIDstr(co), co->refcnt);
|
||||
co->refcnt++;
|
||||
coref_dbg("%s\n", CAPIobjIDstr(co));
|
||||
}
|
||||
if (p)
|
||||
pthread_rwlock_unlock(&p->lock);
|
||||
else
|
||||
pthread_mutex_unlock(&rootLock);
|
||||
} else
|
||||
coref_dbg("No CAPIobj\n");
|
||||
return co;
|
||||
|
@ -383,6 +399,8 @@ int put_cobj(struct mCAPIobj *co)
|
|||
int ret = -ENODEV;
|
||||
|
||||
if (co) {
|
||||
if (co->freeing)
|
||||
cobj_err("Currently freeing %s refcnt: %d\n", CAPIobjIDstr(co), co->refcnt);
|
||||
p = co->parent;
|
||||
if (p) {
|
||||
pthread_rwlock_wrlock(&p->lock);
|
||||
|
@ -394,6 +412,10 @@ int put_cobj(struct mCAPIobj *co)
|
|||
ret = co->refcnt;
|
||||
if (co->cleaned && co->refcnt <= 0) { /* last ref */
|
||||
pthread_rwlock_unlock(&p->lock);
|
||||
/* OK not perfect but scheduling here should prevent us from access of freed memory, if a other thread
|
||||
still pending on the lock - a cleaned object is not longer listed and do not return success in get_obj()
|
||||
so getting a new reference should not happen after this point */
|
||||
sched_yield();
|
||||
cobj_free(co);
|
||||
} else {
|
||||
pthread_rwlock_unlock(&p->lock);
|
||||
|
@ -409,9 +431,11 @@ int put_cobj(struct mCAPIobj *co)
|
|||
}
|
||||
} else {
|
||||
if (co->type == Cot_Root) { /* has no parent */
|
||||
pthread_mutex_lock(&rootLock);
|
||||
coref_dbg("%s\n", CAPIobjIDstr(co));
|
||||
co->refcnt--;
|
||||
ret = co->refcnt;
|
||||
pthread_mutex_unlock(&rootLock);
|
||||
} else
|
||||
cobj_warn("%s: parent not assigned\n", CAPIobjIDstr(co));
|
||||
}
|
||||
|
@ -436,10 +460,17 @@ struct mCAPIobj *get_next_cobj(struct mCAPIobj *parent, struct mCAPIobj *cur)
|
|||
else
|
||||
next = parent->listhead;
|
||||
if (next) {
|
||||
next->refcnt++;
|
||||
coref_dbg("%s: next %s\n", CAPIobjIDstr(cur), CAPIobjIDstr(next));
|
||||
if (next->cleaned) {
|
||||
cobj_warn("%s: pending free detected - do not get next\n", CAPIobjIDstr(next));
|
||||
next = NULL;
|
||||
} else {
|
||||
next->refcnt++;
|
||||
coref_dbg("%s: next %s\n", CAPIobjIDstr(cur), CAPIobjIDstr(next));
|
||||
}
|
||||
}
|
||||
pthread_rwlock_unlock(&parent->lock);
|
||||
if (parent->freeing)
|
||||
cobj_err("Currently freeing %s refcnt: %d Next: %s\n", CAPIobjIDstr(parent), parent->refcnt, CAPIobjIDstr(next));
|
||||
} else
|
||||
next = NULL;
|
||||
if (cur) {
|
||||
|
@ -530,6 +561,9 @@ int init_cobj_registered(struct mCAPIobj *co, struct mCAPIobj *parent, enum eCAP
|
|||
parent->listhead = co;
|
||||
parent->itemcnt++;
|
||||
co->refcnt = 2;
|
||||
} else {
|
||||
eprint("%s: error %s on init lock\n", CAPIobjt2str(co), strerror(errno));
|
||||
return ret;
|
||||
}
|
||||
pthread_rwlock_unlock(&parent->lock);
|
||||
if (ret == 0)
|
||||
|
|
206
capi20/daemon.c
206
capi20/daemon.c
|
@ -81,8 +81,8 @@ static int mainpoll_size = 0;
|
|||
static char def_config[] = DEF_CONFIG_FILE;
|
||||
static char *config_file = NULL;
|
||||
static int do_daemon = 1;
|
||||
static int mIsock = 0;
|
||||
static int mCsock = 0;
|
||||
static int mIsock = -1;
|
||||
static int mCsock = -1;
|
||||
static int mIControl[2] = {-1, -1};
|
||||
static struct pController *mI_Controller = NULL;
|
||||
int mI_ControllerCount = 0;
|
||||
|
@ -134,6 +134,7 @@ static void usage(void)
|
|||
fprintf(stderr, " Options are\n");
|
||||
fprintf(stderr, " -?, --help this help\n");
|
||||
fprintf(stderr, " -c, --config <file> use this config file - default %s\n", def_config);
|
||||
fprintf(stderr, " -d, --debug <debugmask> enable additional debug (see m_capi.h for the bits)\n");
|
||||
fprintf(stderr, " -D, --debug-file <debug file> use debug file (default stdout/stderr)\n");
|
||||
fprintf(stderr, " -f, --foreground run in forground, not as daemon\n");
|
||||
fprintf(stderr, " -k, --keeptemp do not delete temporary files (e.g. TIFF for fax)\n");
|
||||
|
@ -339,13 +340,24 @@ Signal handler for clean shutdown
|
|||
static void
|
||||
termHandler(int sig)
|
||||
{
|
||||
iprint("Terminating on signal %d -- request shutdown mISDNcapid\n", sig);
|
||||
send_master_control(MICD_CTRL_SHUTDOWN, 0, NULL);
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**********************************************************************
|
||||
Signal handler for re-opening log file
|
||||
***********************************************************************/
|
||||
static void
|
||||
hupHandler(int sig)
|
||||
{
|
||||
send_master_control(MICD_CTRL_REOPEN_LOG, 0, NULL);
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**********************************************************************
|
||||
Signal handler for dumping state info
|
||||
***********************************************************************/
|
||||
|
@ -407,6 +419,15 @@ const char *BItype2str(enum BType bt)
|
|||
|
||||
static void
|
||||
dumpHandler(int sig)
|
||||
{
|
||||
if (sig == SIGUSR1)
|
||||
send_master_control(MICD_CTRL_DUMP_1, 0, NULL); // master control will call do_dump
|
||||
else
|
||||
send_master_control(MICD_CTRL_DUMP_2, 0, NULL); // master control will call do_dump
|
||||
return;
|
||||
}
|
||||
|
||||
static void do_dump(const int sig)
|
||||
{
|
||||
if (sig == SIGUSR1) {
|
||||
iprint("Received signal %d -- start dumping\n", sig);
|
||||
|
@ -576,12 +597,40 @@ static int main_control(int idx)
|
|||
else
|
||||
event = -errno;
|
||||
eprint("Event for MasterControl read error read on parameter return %d (%d) - %s\n", ret, len, strerror(-event));
|
||||
free(para);
|
||||
return event;
|
||||
}
|
||||
}
|
||||
switch (event & MICD_EV_MASK) {
|
||||
case MICD_CTRL_SHUTDOWN:
|
||||
iprint("Terminating on signal -- request shutdown mISDNcapid\n");
|
||||
break;
|
||||
case MICD_CTRL_REOPEN_LOG:
|
||||
iprint("Re-opening log on signal\n");
|
||||
if (DebugFileName)
|
||||
{
|
||||
iprint("Received SIGHUP, closing this file for immediate re-open\n");
|
||||
fflush(DebugFile);
|
||||
fclose(DebugFile);
|
||||
DebugFile = fopen(DebugFileName, "a");
|
||||
if (!DebugFile)
|
||||
{
|
||||
fprintf(stderr, "Cannot re-open %s - %s\n", DebugFileName, strerror(errno));
|
||||
break;
|
||||
}
|
||||
iprint("Re-opened debug log file after SIGHUP\n");
|
||||
fflush(DebugFile);
|
||||
}
|
||||
else
|
||||
iprint("Nothing to do for SIGHUP since no debug file configured\n");
|
||||
break;
|
||||
case MICD_CTRL_DUMP_1:
|
||||
do_dump(SIGUSR1);
|
||||
break;
|
||||
case MICD_CTRL_DUMP_2:
|
||||
do_dump(SIGUSR2);
|
||||
break;
|
||||
|
||||
case MICD_CTRL_DISABLE_POLL:
|
||||
case MICD_CTRL_ENABLE_POLL:
|
||||
len /= sizeof(int);
|
||||
|
@ -618,6 +667,7 @@ void clean_all(void)
|
|||
for (i = 0; i < mainpoll_max; i++) {
|
||||
switch (pollinfo[i].type) {
|
||||
case PIT_Control:
|
||||
dprint(MIDEBUG_CONTROLLER, "close mIControl(%d, %d)\n", mIControl[0], mIControl[1]);
|
||||
if (mIControl[0] >= 0) {
|
||||
close(mIControl[0]);
|
||||
mIControl[0] = -1;
|
||||
|
@ -641,6 +691,7 @@ void clean_all(void)
|
|||
ReleaseBchannel(pollinfo[i].data);
|
||||
break;
|
||||
case PIT_NewConn:
|
||||
dprint(MIDEBUG_CONTROLLER, "close mainpoll[%d].fd %d\n", i, mainpoll[i].fd);
|
||||
close(mainpoll[i].fd);
|
||||
break;
|
||||
case PIT_ReleasedApp:
|
||||
|
@ -792,12 +843,13 @@ struct BInstance *ControllerSelChannel(struct pController *pc, int nr, int proto
|
|||
/* for now only one user allowed - this is not sufficient for X25 */
|
||||
wprint("Request for channel number %d on controller %d but channel already in use\n",
|
||||
nr, pc->profile.ncontroller);
|
||||
pthread_mutex_unlock(&bi->lock);
|
||||
bi = NULL;
|
||||
} else {
|
||||
bi->usecnt++;
|
||||
bi->proto = proto;
|
||||
pthread_mutex_unlock(&bi->lock);
|
||||
}
|
||||
pthread_mutex_unlock(&bi->lock);
|
||||
} else {
|
||||
eprint("Controller%d lock for BI[%d] could not aquired - %s\n",
|
||||
pc->profile.ncontroller, bi->nr, strerror(err));
|
||||
|
@ -806,6 +858,28 @@ struct BInstance *ControllerSelChannel(struct pController *pc, int nr, int proto
|
|||
return bi;
|
||||
}
|
||||
|
||||
int ControllerDeSelChannel(struct BInstance *bi)
|
||||
{
|
||||
int err;
|
||||
|
||||
err = pthread_mutex_lock(&bi->lock);
|
||||
if (err == 0) {
|
||||
if (bi->usecnt) {
|
||||
bi->usecnt--;
|
||||
bi->proto = ISDN_P_NONE;
|
||||
} else {
|
||||
wprint("BI[%d] usage count is already zero\n",
|
||||
bi->nr);
|
||||
err = -EINVAL;
|
||||
}
|
||||
pthread_mutex_unlock(&bi->lock);
|
||||
} else {
|
||||
eprint("Lock for BI[%d] could not be acquired - %s\n",
|
||||
bi->nr, strerror(err));
|
||||
}
|
||||
return err;
|
||||
}
|
||||
|
||||
int check_free_bchannels(struct pController *pc)
|
||||
{
|
||||
int i, cnt = 0;
|
||||
|
@ -831,15 +905,18 @@ static int Create_tty(struct BInstance *bi)
|
|||
eprint("Cannot open terminal - %s\n", strerror(errno));
|
||||
} else {
|
||||
bi->tty = ret;
|
||||
dprint(MIDEBUG_CONTROLLER, "create bi[%d]->tty %d\n", bi->nr, bi->tty);
|
||||
ret = grantpt(bi->tty);
|
||||
if (ret < 0) {
|
||||
eprint("Error on grantpt - %s\n", strerror(errno));
|
||||
dprint(MIDEBUG_CONTROLLER, "close bi[%d]->tty %d\n", bi->nr, bi->tty);
|
||||
close(bi->tty);
|
||||
bi->tty = -1;
|
||||
} else {
|
||||
ret = unlockpt(bi->tty);
|
||||
if (ret < 0) {
|
||||
eprint("Error on unlockpt - %s\n", strerror(errno));
|
||||
dprint(MIDEBUG_CONTROLLER, "close bi[%d]->tty %d\n", bi->nr, bi->tty);
|
||||
close(bi->tty);
|
||||
bi->tty = -1;
|
||||
} else {
|
||||
|
@ -848,8 +925,11 @@ static int Create_tty(struct BInstance *bi)
|
|||
ret = ioctl(bi->tty, TIOCPKT, &pmod);
|
||||
if (ret < 0) {
|
||||
eprint("Cannot set packet mode - %s\n", strerror(errno));
|
||||
dprint(MIDEBUG_CONTROLLER, "close bi[%d]->tty %d\n", bi->nr, bi->tty);
|
||||
close(bi->tty);
|
||||
bi->tty = -1;
|
||||
} else {
|
||||
bi->tty_received = 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -887,6 +967,7 @@ static int recv_tty(struct BInstance *bi)
|
|||
ret = -EMSGSIZE;
|
||||
}
|
||||
if (ret > 0) {
|
||||
bi->tty_received = 1;
|
||||
mc->len = ret;
|
||||
/* Fake length of DATA_B3 REQ to pass offset check */
|
||||
capimsg_setu16(mc->rb, 0, 22);
|
||||
|
@ -935,9 +1016,9 @@ static void *BCthread(void *arg)
|
|||
continue;
|
||||
}
|
||||
if (ret == 0) { /* timeout */
|
||||
wprint("Bchannel%d %stimeout (release %spending) thread=%05d\n", bi->nr,
|
||||
bi->got_timeout ? "2. " : "", bi->release_pending ? "" : "not ", bi->tid);
|
||||
if (bi->release_pending) {
|
||||
wprint("Bchannel%d %stimeout (release pending) thread=%05d\n", bi->nr,
|
||||
bi->got_timeout ? "2. " : "", bi->tid);
|
||||
if (bi->got_timeout) { /* 2 times */
|
||||
bi->detached = 1;
|
||||
ret = pthread_detach(bi->thread);
|
||||
|
@ -988,11 +1069,14 @@ static int CreateBchannelThread(struct BInstance *bi, int pcnt)
|
|||
{
|
||||
int ret, i;
|
||||
|
||||
if (bi->cpipe[0] > -1 || bi->cpipe[1] > -1)
|
||||
wprint("bi[%d]->cpipe(%d, %d) still open - may leaking fds\n", bi->nr, bi->cpipe[0], bi->cpipe[1]);
|
||||
ret = pipe(bi->cpipe);
|
||||
if (ret) {
|
||||
eprint("error - %s\n", strerror(errno));
|
||||
return ret;
|
||||
}
|
||||
} else
|
||||
dprint(MIDEBUG_CONTROLLER, "create bi[%d]->cpipe(%d, %d)\n", bi->nr, bi->cpipe[0], bi->cpipe[1]);
|
||||
ret = fcntl(bi->cpipe[0], F_SETFL, O_NONBLOCK);
|
||||
if (ret) {
|
||||
eprint("error - %s\n", strerror(errno));
|
||||
|
@ -1013,6 +1097,7 @@ static int CreateBchannelThread(struct BInstance *bi, int pcnt)
|
|||
if (ret) {
|
||||
eprint("Cannot create thread error - %s\n", strerror(errno));
|
||||
bi->detached = 1;
|
||||
dprint(MIDEBUG_CONTROLLER, "close bi[%d]->cpipe(%d, %d)\n", bi->nr, bi->cpipe[0], bi->cpipe[1]);
|
||||
close(bi->cpipe[0]);
|
||||
close(bi->cpipe[1]);
|
||||
bi->cpipe[0] = -1;
|
||||
|
@ -1059,6 +1144,7 @@ static int StopBchannelThread(struct BInstance *bi)
|
|||
} else {
|
||||
wprint("Running but already joined in thread=%05d ???\n", bi->tid);
|
||||
}
|
||||
dprint(MIDEBUG_CONTROLLER, "close bi[%d]->cpipe(%d, %d)\n", bi->nr, bi->cpipe[0], bi->cpipe[1]);
|
||||
close(bi->cpipe[0]);
|
||||
close(bi->cpipe[1]);
|
||||
bi->pfd[0].fd = -1;
|
||||
|
@ -1117,12 +1203,24 @@ int OpenBInstance(struct BInstance *bi, struct lPLCI *lp)
|
|||
wprint("Cannot open socket for BInstance %d on controller %d protocol 0x%02x - %s\n",
|
||||
bi->nr, bi->pc->profile.ncontroller, bi->proto, strerror(errno));
|
||||
return -errno;
|
||||
}
|
||||
} else
|
||||
dprint(MIDEBUG_CONTROLLER, "create socket bi[%d]->fd %d\n", bi->nr, sk);
|
||||
|
||||
ret = fcntl(sk, F_SETFL, O_NONBLOCK);
|
||||
if (ret < 0) {
|
||||
ret = -errno;
|
||||
wprint("fcntl error %s\n", strerror(errno));
|
||||
dprint(MIDEBUG_CONTROLLER, "close socket bi[%d]->fd %d\n", bi->nr, sk);
|
||||
close(sk);
|
||||
return ret;
|
||||
}
|
||||
|
||||
if (get_cobj(&lp->cobj)) {
|
||||
bi->lp = lp;
|
||||
} else {
|
||||
bi->lp = NULL;
|
||||
ret = -EINVAL;
|
||||
wprint("Cannot get logical controller object\n");
|
||||
close(sk);
|
||||
return ret;
|
||||
}
|
||||
|
@ -1144,7 +1242,10 @@ int OpenBInstance(struct BInstance *bi, struct lPLCI *lp)
|
|||
break;
|
||||
default:
|
||||
eprint("Error unnkown BType %d\n", lp->btype);
|
||||
dprint(MIDEBUG_CONTROLLER, "close socket bi[%d]->fd %d\n", bi->nr, sk);
|
||||
close(sk);
|
||||
bi->lp = NULL;
|
||||
put_cobj(&lp->cobj);
|
||||
return -EINVAL;
|
||||
}
|
||||
bi->type = lp->btype;
|
||||
|
@ -1161,15 +1262,16 @@ int OpenBInstance(struct BInstance *bi, struct lPLCI *lp)
|
|||
ret = -errno;
|
||||
wprint("Cannot bind socket for BInstance %d on controller %d (mISDN nr %d) protocol 0x%02x - %s\n",
|
||||
bi->nr, bi->pc->profile.ncontroller, bi->pc->mNr, bi->proto, strerror(errno));
|
||||
dprint(MIDEBUG_CONTROLLER, "close socket bi[%d]->fd %d\n", bi->nr, sk);
|
||||
close(sk);
|
||||
bi->from_down = dummy_btrans;
|
||||
bi->from_up = dummy_btrans;
|
||||
bi->type = BType_None;
|
||||
bi->lp = NULL;
|
||||
put_cobj(&lp->cobj);
|
||||
} else {
|
||||
bi->closed = 0;
|
||||
bi->fd = sk;
|
||||
bi->lp = lp;
|
||||
get_cobj(&lp->cobj);
|
||||
bi->org_rx_min = MISDN_CTRL_RX_SIZE_IGNORE;
|
||||
bi->rx_min = MISDN_CTRL_RX_SIZE_IGNORE;
|
||||
bi->org_rx_max = MISDN_CTRL_RX_SIZE_IGNORE;
|
||||
|
@ -1224,10 +1326,11 @@ int OpenBInstance(struct BInstance *bi, struct lPLCI *lp)
|
|||
ret = add_mainpoll(sk, PIT_Bchannel);
|
||||
if (ret < 0) {
|
||||
eprint("Error while adding mIsock to mainpoll (mainpoll_max %d)\n", mainpoll_max);
|
||||
dprint(MIDEBUG_CONTROLLER, "close socket bi[%d]->fd %d\n", bi->nr, sk);
|
||||
close(sk);
|
||||
bi->fd = -1;
|
||||
put_cobj(&lp->cobj);
|
||||
bi->lp = NULL;
|
||||
put_cobj(&lp->cobj);
|
||||
} else {
|
||||
dprint(MIDEBUG_CONTROLLER, "Controller%d: Bchannel %d socket %d added to poll idx %d\n",
|
||||
bi->pc->profile.ncontroller, bi->nr, sk, ret);
|
||||
|
@ -1240,10 +1343,11 @@ int OpenBInstance(struct BInstance *bi, struct lPLCI *lp)
|
|||
ret = CreateBchannelThread(bi, 2);
|
||||
if (ret < 0) {
|
||||
eprint("Error while creating B%d-channel thread\n", bi->nr);
|
||||
dprint(MIDEBUG_CONTROLLER, "close socket bi[%d]->fd %d\n", bi->nr, sk);
|
||||
close(sk);
|
||||
bi->fd = -1;
|
||||
put_cobj(&lp->cobj);
|
||||
bi->lp = NULL;
|
||||
put_cobj(&lp->cobj);
|
||||
} else {
|
||||
ret = 0;
|
||||
bi->UpId = 0;
|
||||
|
@ -1253,10 +1357,11 @@ int OpenBInstance(struct BInstance *bi, struct lPLCI *lp)
|
|||
ret = Create_tty(bi);
|
||||
if (ret < 0) {
|
||||
eprint("Error while creating B%d-channel tty\n", bi->nr);
|
||||
dprint(MIDEBUG_CONTROLLER, "close socket bi[%d]->fd %d\n", bi->nr, sk);
|
||||
close(sk);
|
||||
bi->fd = -1;
|
||||
put_cobj(&lp->cobj);
|
||||
bi->lp = NULL;
|
||||
put_cobj(&lp->cobj);
|
||||
return ret;
|
||||
} else {
|
||||
bi->pfd[2].fd = bi->tty;
|
||||
|
@ -1265,10 +1370,11 @@ int OpenBInstance(struct BInstance *bi, struct lPLCI *lp)
|
|||
}
|
||||
if (ret < 0) {
|
||||
eprint("Error while creating B%d-channel thread\n", bi->nr);
|
||||
dprint(MIDEBUG_CONTROLLER, "close socket bi[%d]->fd %d\n", bi->nr, sk);
|
||||
close(sk);
|
||||
bi->fd = -1;
|
||||
put_cobj(&lp->cobj);
|
||||
bi->lp = NULL;
|
||||
put_cobj(&lp->cobj);
|
||||
} else {
|
||||
ret = 0;
|
||||
bi->UpId = 0;
|
||||
|
@ -1309,12 +1415,14 @@ int CloseBInstance(struct BInstance *bi)
|
|||
#endif
|
||||
case BType_tty:
|
||||
StopBchannelThread(bi);
|
||||
dprint(MIDEBUG_CONTROLLER, "close bi[%d]->tty %d\n", bi->nr, bi->tty);
|
||||
if (bi->tty > -1)
|
||||
close(bi->tty);
|
||||
bi->tty = -1;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
dprint(MIDEBUG_CONTROLLER, "Closing fd=%d usecnt %d\n", bi->fd, bi->usecnt);
|
||||
if (bi->fd >= 0)
|
||||
close(bi->fd);
|
||||
bi->fd = -1;
|
||||
|
@ -1374,12 +1482,10 @@ int activate_bchannel(struct BInstance *bi)
|
|||
struct mISDNhead mh;
|
||||
|
||||
mh.id = 1;
|
||||
if (bi->proto == ISDN_P_B_RAW)
|
||||
mh.prim = PH_ACTIVATE_REQ;
|
||||
else if (bi->proto == ISDN_P_NONE)
|
||||
if (bi->proto == ISDN_P_NONE)
|
||||
return -EINVAL;
|
||||
else
|
||||
mh.prim = DL_ESTABLISH_REQ;
|
||||
mh.prim = PH_ACTIVATE_REQ;
|
||||
|
||||
ret = send(bi->fd, &mh, sizeof(mh), 0);
|
||||
if (ret != sizeof(mh)) {
|
||||
|
@ -1440,10 +1546,12 @@ int ReleaseBchannel(struct BInstance *bi)
|
|||
return -1;
|
||||
if (bi->fd >= 0) {
|
||||
del_mainpoll(bi->fd);
|
||||
dprint(MIDEBUG_CONTROLLER, "close bi[%d]->fd %d\n", bi->nr, bi->fd);
|
||||
close(bi->fd);
|
||||
bi->fd = -1;
|
||||
}
|
||||
if (bi->tty >= 0) {
|
||||
dprint(MIDEBUG_CONTROLLER, "close bi[%d]->tty %d\n", bi->nr, bi->tty);
|
||||
close(bi->tty);
|
||||
bi->tty = -1;
|
||||
}
|
||||
|
@ -1592,11 +1700,14 @@ static void ShutdownAppl(int idx, int unregister)
|
|||
eprint("Application not assigned\n");
|
||||
return;
|
||||
}
|
||||
if (appl->cpipe[0] > -1 || appl->cpipe[1] > -1)
|
||||
wprint("%s appl->cpipe(%d, %d) still open - leaking fds\n", CAPIobjIDstr(&appl->cobj), appl->cpipe[0], appl->cpipe[1]);
|
||||
ret = pipe2(appl->cpipe, O_NONBLOCK);
|
||||
if (ret) {
|
||||
eprint("Cannot open application %d control pipe - %s\n", appl->cobj.id2, strerror(errno));
|
||||
mainpoll[idx].fd = -1;
|
||||
} else {
|
||||
dprint(MIDEBUG_CONTROLLER, "create appl->cpipe(%d, %d)\n", appl->cpipe[0], appl->cpipe[1]);
|
||||
}
|
||||
ReleaseApplication(appl, unregister);
|
||||
pollinfo[idx].type = PIT_ReleasedApp;
|
||||
|
@ -1698,8 +1809,10 @@ static void mIcapi_release(int fd, int idx, struct mc_buf *mc)
|
|||
ret = send(fd, mc->rb, 10, 0);
|
||||
if (ret != 10)
|
||||
eprint("error send %d/%d - %s\n", ret, 10, strerror(errno));
|
||||
if (info == CapiNoError)
|
||||
if (info == CapiNoError) {
|
||||
close(fd);
|
||||
dprint(MIDEBUG_CONTROLLER, "close mIcapi_release fd %d\n", fd);
|
||||
}
|
||||
}
|
||||
|
||||
static void get_serial_number(int fd, struct mc_buf *mc)
|
||||
|
@ -1921,7 +2034,8 @@ int main_loop(void)
|
|||
if (ret) {
|
||||
eprint("error setup MasterControl pipe - %s\n", strerror(errno));
|
||||
return errno;
|
||||
}
|
||||
} else
|
||||
dprint(MIDEBUG_CONTROLLER, "create mIControl(%d, %d)\n", mIControl[0], mIControl[1]);
|
||||
ret = add_mainpoll(mIControl[0], PIT_Control);
|
||||
if (ret < 0) {
|
||||
eprint("Error while adding mIControl to mainpoll (mainpoll_max %d)\n", mainpoll_max);
|
||||
|
@ -2030,9 +2144,10 @@ int main_loop(void)
|
|||
break;
|
||||
}
|
||||
fd = mainpoll[i].fd;
|
||||
dprint(MIDEBUG_POLL, "read 0 socket %d type %d closed\n", fd, pollinfo[i].type);
|
||||
close(mainpoll[i].fd);
|
||||
res = del_mainpoll(mainpoll[i].fd);
|
||||
dprint(MIDEBUG_POLL, "socket connection %s - fd %d idx %d type %d closed\n",
|
||||
res == -ECONNABORTED ? "abort" : "reset", fd, i, pollinfo[i].type);
|
||||
close(fd);
|
||||
res = del_mainpoll(fd);
|
||||
if (res < 0) {
|
||||
eprint("Cannot delete fd=%d from mainpoll result %d\n", fd, res);
|
||||
} else
|
||||
|
@ -2071,11 +2186,11 @@ int main_loop(void)
|
|||
}
|
||||
break;
|
||||
case PIT_mISDNtimer:
|
||||
ret = read(mainpoll[i].fd, &timerId, sizeof(timerId));
|
||||
if (ret < 0) {
|
||||
res = read(mainpoll[i].fd, &timerId, sizeof(timerId));
|
||||
if (res < 0) {
|
||||
eprint("mISDN read timer error %s\n", strerror(errno));
|
||||
} else {
|
||||
if (ret == sizeof(timerId) && timerId) {
|
||||
if (res == sizeof(timerId) && timerId) {
|
||||
expire_timer(pollinfo[i].data, timerId);
|
||||
}
|
||||
}
|
||||
|
@ -2133,7 +2248,7 @@ static struct mi_ext_fn_s l3dbg = {
|
|||
.prt_debug = my_lib_debug,
|
||||
};
|
||||
|
||||
static struct sigaction mysig_term, mysig_dump;
|
||||
static struct sigaction mysig_term, mysig_dump, mysig_hup;
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
|
@ -2151,6 +2266,8 @@ int main(int argc, char *argv[])
|
|||
if (ret)
|
||||
exit(1);
|
||||
|
||||
memset(&mcaddr, 0, sizeof(mcaddr));
|
||||
|
||||
if (DebugFileName) {
|
||||
DebugFile = fopen(DebugFileName, "w");
|
||||
if (!DebugFile) {
|
||||
|
@ -2268,6 +2385,8 @@ int main(int argc, char *argv[])
|
|||
pc->BInstances[j].pc = pc;
|
||||
pc->BInstances[j].fd = -1;
|
||||
pc->BInstances[j].tty = -1;
|
||||
pc->BInstances[j].cpipe[0] = -1;
|
||||
pc->BInstances[j].cpipe[1] = -1;
|
||||
pthread_mutex_init(&pc->BInstances[j].lock, NULL);
|
||||
sem_init(&pc->BInstances[j].wait, 0, 0);
|
||||
}
|
||||
|
@ -2317,8 +2436,17 @@ retry_Csock:
|
|||
fprintf(stderr, "cannot create socket - %s\n", strerror(errno));
|
||||
goto errout;
|
||||
}
|
||||
|
||||
mcaddr.sun_family = AF_UNIX;
|
||||
sprintf(mcaddr.sun_path, MISDN_CAPI_SOCKET_PATH);
|
||||
ret = mkdir(MISDN_CAPI_SOCKET_DIR, S_IRWXU | S_IRWXG);
|
||||
if (ret < 0) {
|
||||
if (errno != EEXIST) {
|
||||
fprintf(stderr, "cannot create socket directory %s - %s\n", MISDN_CAPI_SOCKET_DIR, strerror(errno));
|
||||
goto errout;
|
||||
} else
|
||||
iprint("directory %s already exist - reusing it\n", MISDN_CAPI_SOCKET_DIR);
|
||||
}
|
||||
sprintf(mcaddr.sun_path, "%s/%s", MISDN_CAPI_SOCKET_DIR, MISDN_CAPI_SOCKET_NAME);
|
||||
ret = bind(mCsock, (struct sockaddr *)&mcaddr, sizeof(mcaddr));
|
||||
if (ret < 0) {
|
||||
fprintf(stderr, "cannot bind socket to %s - %s\n", mcaddr.sun_path, strerror(errno));
|
||||
|
@ -2326,10 +2454,10 @@ retry_Csock:
|
|||
ret = connect(mCsock, (struct sockaddr *)&mcaddr, sizeof(mcaddr));
|
||||
if (ret < 0) {
|
||||
/* seems the socket file is not in use */
|
||||
ret = unlink(MISDN_CAPI_SOCKET_PATH);
|
||||
ret = unlink(mcaddr.sun_path);
|
||||
if (ret < 0) {
|
||||
fprintf(stderr, "cannot remove old socket file %s - %s\n",
|
||||
MISDN_CAPI_SOCKET_PATH, strerror(errno));
|
||||
mcaddr.sun_path, strerror(errno));
|
||||
goto errout;
|
||||
}
|
||||
close(mCsock);
|
||||
|
@ -2341,9 +2469,9 @@ retry_Csock:
|
|||
|
||||
}
|
||||
}
|
||||
ret = chmod(MISDN_CAPI_SOCKET_PATH, S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP);
|
||||
ret = chmod(mcaddr.sun_path, S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP);
|
||||
if (ret < 0) {
|
||||
fprintf(stderr, "cannot change permissions on unix socket:%s - %s\n", MISDN_CAPI_SOCKET_PATH, strerror(errno));
|
||||
fprintf(stderr, "cannot change permissions on unix socket:%s - %s\n", mcaddr.sun_path, strerror(errno));
|
||||
goto errout;
|
||||
}
|
||||
|
||||
|
@ -2373,10 +2501,6 @@ retry_Csock:
|
|||
if (ret) {
|
||||
wprint("Error to setup signal handler for SIGTERM - %s\n", strerror(errno));
|
||||
}
|
||||
ret = sigaction(SIGHUP, &mysig_term, NULL);
|
||||
if (ret) {
|
||||
wprint("Error to setup signal handler for SIGHUP - %s\n", strerror(errno));
|
||||
}
|
||||
ret = sigaction(SIGINT, &mysig_term, NULL);
|
||||
if (ret) {
|
||||
wprint("Error to setup signal handler for SIGINT - %s\n", strerror(errno));
|
||||
|
@ -2392,6 +2516,13 @@ retry_Csock:
|
|||
if (ret) {
|
||||
wprint("Error to setup signal handler for SIGUSR2 - %s\n", strerror(errno));
|
||||
}
|
||||
|
||||
memset(&mysig_hup, 0, sizeof(mysig_hup));
|
||||
mysig_hup.sa_handler = hupHandler;
|
||||
ret = sigaction(SIGHUP, &mysig_hup, NULL);
|
||||
if (ret) {
|
||||
wprint("Error to setup signal handler for SIGHUP - %s\n", strerror(errno));
|
||||
}
|
||||
exitcode = main_loop();
|
||||
free_ncci_fsm();
|
||||
free_lPLCI_fsm();
|
||||
|
@ -2411,7 +2542,8 @@ errout:
|
|||
if (mICAPItimer_base->tdev > 0)
|
||||
close(mICAPItimer_base->tdev);
|
||||
mICAPItimer_base->tdev = -1;
|
||||
unlink(MISDN_CAPI_SOCKET_PATH);
|
||||
if (mcaddr.sun_path[0])
|
||||
unlink(mcaddr.sun_path);
|
||||
if (TempDirectory && !KeepTemporaryFiles) {
|
||||
ret = rmdir(TempDirectory);
|
||||
if (ret)
|
||||
|
|
|
@ -23,13 +23,13 @@
|
|||
#include <sys/mman.h>
|
||||
#include <fcntl.h>
|
||||
#include <mISDN/q931.h>
|
||||
#include <spandsp.h>
|
||||
#include "ncci.h"
|
||||
#include "alaw.h"
|
||||
#include "sff.h"
|
||||
#include "g3_mh.h"
|
||||
|
||||
#ifdef USE_SOFTFAX
|
||||
#include <spandsp.h>
|
||||
|
||||
struct mFAX {
|
||||
struct mCAPIobj cobj;
|
||||
|
@ -1300,7 +1300,8 @@ static int FaxWriteTiff(struct mFAX *fax, struct mc_buf *mc)
|
|||
res = -errno;
|
||||
wprint("%s: Cannot open TIFF %s for writing - %s\n", CAPIobjIDstr(&fax->cobj),
|
||||
fax->file_name, strerror(errno));
|
||||
}
|
||||
} else
|
||||
dprint(MIDEBUG_NCCI, "%s: open fax->file_d %d\n", CAPIobjIDstr(&fax->cobj), fax->file_d);
|
||||
}
|
||||
if (fax->file_d < 0) {
|
||||
if (!res)
|
||||
|
@ -1431,6 +1432,7 @@ static int FaxDisconnectB3Req(struct mFAX *fax, struct mNCCI *ncci, struct mc_bu
|
|||
break;
|
||||
case FAX_B3_FORMAT_TIFF:
|
||||
if (fax->file_d >= 0) {
|
||||
dprint(MIDEBUG_NCCI, "%s: close fax->file_d %d\n", CAPIobjIDstr(&fax->cobj), fax->file_d);
|
||||
close(fax->file_d);
|
||||
fax->file_d = -1;
|
||||
} else
|
||||
|
|
|
@ -15,7 +15,7 @@ enum {
|
|||
ST_LISTEN_L_1_1,
|
||||
} const ST_LISTEN_COUNT = ST_LISTEN_L_1_1 + 1;
|
||||
|
||||
static char *str_st_listen[] = {
|
||||
static const char *str_st_listen[] = {
|
||||
"ST_LISTEN_L_0",
|
||||
"ST_LISTEN_L_0_1",
|
||||
"ST_LISTEN_L_1",
|
||||
|
@ -27,14 +27,14 @@ enum {
|
|||
EV_LISTEN_CONF,
|
||||
} const EV_LISTEN_COUNT = EV_LISTEN_CONF + 1;
|
||||
|
||||
static char *str_ev_listen[] = {
|
||||
static const char *str_ev_listen[] = {
|
||||
"EV_LISTEN_REQ",
|
||||
"EV_LISTEN_CONF",
|
||||
};
|
||||
|
||||
static struct Fsm listen_fsm = { 0, 0, 0, 0, 0 };
|
||||
|
||||
static void listen_debug(struct FsmInst *fi, char *fmt, ...)
|
||||
static void listen_debug(struct FsmInst *fi, const char *fmt, ...)
|
||||
{
|
||||
char tmp[128];
|
||||
va_list args;
|
||||
|
@ -128,14 +128,19 @@ struct lController *addlController(struct mApplication *app, struct pController
|
|||
lc = calloc(1, sizeof(*lc));
|
||||
if (lc) {
|
||||
lc->cobj.id2 = app->cobj.id2;
|
||||
if (!get_cobj(&app->cobj)) {
|
||||
eprint("Cannot get application object\n");
|
||||
free(lc);
|
||||
return NULL;
|
||||
}
|
||||
ret = init_cobj_registered(&lc->cobj, &pc->cobjLC, Cot_lController, 0x0000ff);
|
||||
if (ret) {
|
||||
eprint("Controller%d: Application %d - cannot init\n", pc->profile.ncontroller, app->cobj.id2);
|
||||
put_cobj(&app->cobj);
|
||||
free(lc);
|
||||
lc = NULL;
|
||||
} else {
|
||||
lc->Appl = app;
|
||||
get_cobj(&app->cobj);
|
||||
lc->listen_m.fsm = &listen_fsm;
|
||||
lc->listen_m.state = ST_LISTEN_L_0;
|
||||
lc->listen_m.debug = MIDEBUG_CONTROLLER & mI_debug_mask;
|
||||
|
@ -146,10 +151,13 @@ struct lController *addlController(struct mApplication *app, struct pController
|
|||
lc->CIPmask2 = 0;
|
||||
ret = register_lController(app, lc);
|
||||
if (ret) {
|
||||
lc->Appl = NULL;
|
||||
put_cobj(&app->cobj);
|
||||
eprint("Controller%d: - cannot register LC on Application %d - %s\n", pc->profile.ncontroller,
|
||||
app->cobj.id2, strerror(-ret));
|
||||
free(lc);
|
||||
lc->cobj.cleaned = 1;
|
||||
delist_cobj(&lc->cobj);
|
||||
put_cobj(&lc->cobj);
|
||||
lc = NULL;
|
||||
}
|
||||
}
|
||||
|
|
155
capi20/lplci.c
155
capi20/lplci.c
|
@ -25,6 +25,9 @@
|
|||
static int lPLCILinkUp(struct lPLCI *);
|
||||
static int lPLCILinkDown(struct lPLCI *);
|
||||
|
||||
/* Enable experimental partial early B3 support */
|
||||
/* #define HANDLE_EARLYB3 1 */
|
||||
|
||||
/* T301 is usually 180 - give it a chance, if not clear down 2 sec later */
|
||||
#define ALERT_TIMEOUT 182000
|
||||
|
||||
|
@ -53,7 +56,7 @@ enum {
|
|||
ST_PLCI_P_RES,
|
||||
} const ST_PLCI_COUNT = ST_PLCI_P_RES + 1;
|
||||
|
||||
static char *str_st_plci[] = {
|
||||
static const char *str_st_plci[] = {
|
||||
"ST_PLCI_P_0",
|
||||
"ST_PLCI_P_0_1",
|
||||
"ST_PLCI_P_1",
|
||||
|
@ -114,7 +117,7 @@ enum {
|
|||
EV_AP_RELEASE,
|
||||
} const EV_PLCI_COUNT = EV_AP_RELEASE + 1;
|
||||
|
||||
static char *str_ev_plci[] = {
|
||||
static const char *str_ev_plci[] = {
|
||||
"EV_AP_CONNECT_REQ",
|
||||
"EV_PI_CONNECT_CONF",
|
||||
"EV_PI_CONNECT_IND",
|
||||
|
@ -163,7 +166,7 @@ static char *str_ev_plci[] = {
|
|||
|
||||
static struct Fsm plci_fsm = { 0, 0, 0, 0, 0 };
|
||||
|
||||
static void lPLCI_debug(struct FsmInst *fi, char *fmt, ...)
|
||||
static void lPLCI_debug(struct FsmInst *fi, const char *fmt, ...)
|
||||
{
|
||||
char tmp[160];
|
||||
va_list args;
|
||||
|
@ -232,7 +235,7 @@ static void lPLCIClearOtherApps(struct lPLCI *lp)
|
|||
static int lPLCIDisconnectInd(struct lPLCI *lp, struct mc_buf *mc)
|
||||
{
|
||||
struct BInstance *bi = lp->BIlink;
|
||||
int ret = -ENODEV;
|
||||
int ret = 0;
|
||||
|
||||
if (mc && bi) {
|
||||
lPLCICmsgHeader(lp, &mc->cmsg, CAPI_DISCONNECT, CAPI_IND);
|
||||
|
@ -273,12 +276,34 @@ static void lPLCIInfoIndMsg(struct lPLCI *lp, uint32_t mask, unsigned char mt, s
|
|||
mc_clear_cmsg(mc);
|
||||
}
|
||||
|
||||
static void lPLCIInfoIndIEProcess(struct lPLCI *lp, unsigned char ie, unsigned char *iep, struct mc_buf *mc)
|
||||
{
|
||||
#ifdef HANDLE_EARLYB3
|
||||
if (ie == IE_PROGRESS && lp->lc->InfoMask & CAPI_INFOMASK_EARLYB3) {
|
||||
if (iep[0] == 0x02 && (iep[1] & 0x60) == 0x00 && (iep[2] == 0x81 || iep[2] == 0x88)) {
|
||||
/* in-band information is (maybe) available */
|
||||
int ret;
|
||||
ret = lPLCILinkUp(lp);
|
||||
if (ret != 0) {
|
||||
wprint("%s: early B3 link establish failed, ret=%d\n", CAPIobjIDstr(&lp->cobj), ret);
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
mc_clear_cmsg(mc);
|
||||
lPLCICmsgHeader(lp, &mc->cmsg, CAPI_INFO, CAPI_IND);
|
||||
mc->cmsg.InfoNumber = ie;
|
||||
mc->cmsg.InfoElement = iep;
|
||||
Send2Application(lp, mc);
|
||||
}
|
||||
|
||||
static void lPLCIInfoIndIE(struct lPLCI *lp, unsigned char ie, uint32_t mask, struct mc_buf *mc)
|
||||
{
|
||||
unsigned char **v_ie, *iep;
|
||||
int pos;
|
||||
|
||||
if (!mc || mc->l3m)
|
||||
if (!mc || !mc->l3m)
|
||||
return;
|
||||
|
||||
if (!lp->lc || !(lp->lc->InfoMask & mask)) /* not requested by application */
|
||||
|
@ -298,25 +323,27 @@ static void lPLCIInfoIndIE(struct lPLCI *lp, unsigned char ie, uint32_t mask, st
|
|||
if ((iep == NULL) || (*iep == 0)) /* not available in message */
|
||||
return;
|
||||
|
||||
mc_clear_cmsg(mc);
|
||||
lPLCICmsgHeader(lp, &mc->cmsg, CAPI_INFO, CAPI_IND);
|
||||
mc->cmsg.InfoNumber = ie;
|
||||
mc->cmsg.InfoElement = iep;
|
||||
#ifdef HANDLE_EARLYB3
|
||||
if (ie == IE_PROGRESS && lp->lc->InfoMask & CAPI_INFOMASK_EARLYB3) {
|
||||
if (iep[0] == 0x02 && iep[2] == 0x88) { // in-band information available
|
||||
ret = lPLCILinkUp(lp);
|
||||
if (ret != 0) {
|
||||
....
|
||||
}
|
||||
if (!test_bit(PLCI_STATE_STACKREADY, &lp->plci->state)) {
|
||||
Send2ApplicationDelayed(lp, cmsg);
|
||||
return;
|
||||
}
|
||||
}
|
||||
lPLCIInfoIndIEProcess(lp, ie, iep, mc);
|
||||
|
||||
if (ie & 0x80) /* Single octet IEs aren't stored in an extra array */
|
||||
return;
|
||||
|
||||
for (pos = 0; pos < 8; pos++) {
|
||||
if (mc->l3m->extra[pos].codeset)
|
||||
continue;
|
||||
|
||||
/* assume that extra is filled in order without holes */
|
||||
if (!mc->l3m->extra[pos].val)
|
||||
break;
|
||||
|
||||
if (mc->l3m->extra[pos].ie != ie)
|
||||
continue;
|
||||
|
||||
if (!(*mc->l3m->extra[pos].val))
|
||||
continue;
|
||||
|
||||
lPLCIInfoIndIEProcess(lp, ie, mc->l3m->extra[pos].val, mc);
|
||||
}
|
||||
#endif
|
||||
Send2Application(lp, mc);
|
||||
}
|
||||
|
||||
uint16_t CIPMask2CIPValue(uint32_t mask)
|
||||
|
@ -354,7 +381,7 @@ uint32_t q931CIPMask(struct mc_buf * mc)
|
|||
*/
|
||||
|
||||
ret = mi_decode_bearer_capability(mc->l3m, NULL, &capability, &mode, &rate,
|
||||
NULL, NULL, &oct5, NULL, NULL, NULL, NULL, NULL, NULL, NULL);
|
||||
NULL, NULL, &oct5, NULL, NULL, NULL, NULL, NULL, NULL);
|
||||
|
||||
l = *mc->l3m->bearer_capability;
|
||||
if (l > 13)
|
||||
|
@ -1747,10 +1774,24 @@ int lPLCICreate(struct lPLCI **lpp, struct lController *lc, struct mPLCI *plci,
|
|||
return ret;
|
||||
}
|
||||
lp->cipmask = cipmask;
|
||||
lp->lc = lc;
|
||||
get_cobj(&lc->cobj);
|
||||
lp->Appl = lc->Appl;
|
||||
get_cobj(&lc->Appl->cobj);
|
||||
if (get_cobj(&lc->cobj)) {
|
||||
lp->lc = lc;
|
||||
} else {
|
||||
wprint("%s: Cannot get lController object\n", CAPIobjIDstr(&lc->cobj));
|
||||
lp->cobj.cleaned = 1;
|
||||
delist_cobj(&lp->cobj);
|
||||
put_cobj(&lp->cobj); /* will cleanup and free too */
|
||||
return -EINVAL;
|
||||
}
|
||||
if (get_cobj(&lc->Appl->cobj)) {
|
||||
lp->Appl = lc->Appl;
|
||||
} else {
|
||||
wprint("%s: Cannot get application object\n", CAPIobjIDstr(&lc->Appl->cobj));
|
||||
lp->cobj.cleaned = 1;
|
||||
delist_cobj(&lp->cobj);
|
||||
put_cobj(&lp->cobj); /* will cleanup and free too */
|
||||
return -EINVAL;
|
||||
}
|
||||
if (plci->pc->profile.goptions & 0x0008) {
|
||||
/* DTMF */
|
||||
lp->l1dtmf = 1;
|
||||
|
@ -1762,8 +1803,15 @@ int lPLCICreate(struct lPLCI **lpp, struct lController *lc, struct mPLCI *plci,
|
|||
lp->plci_m.printdebug = lPLCI_debug;
|
||||
lp->chid.nr = MI_CHAN_NONE;
|
||||
lp->autohangup = 1;
|
||||
init_timer(&lp->atimer, mICAPItimer_base, lp, atimer_timeout);
|
||||
get_cobj(&lp->cobj); /* timer ref */
|
||||
if (get_cobj(&lp->cobj)) { /* timer ref */
|
||||
init_timer(&lp->atimer, mICAPItimer_base, lp, atimer_timeout);
|
||||
} else {
|
||||
wprint("%s: Cannot get lplci object for timer ref\n", CAPIobjIDstr(&lp->cobj));
|
||||
lp->cobj.cleaned = 1;
|
||||
delist_cobj(&lp->cobj);
|
||||
put_cobj(&lp->cobj); /* will cleanup and free too */
|
||||
return -EINVAL;
|
||||
}
|
||||
*lpp = lp;
|
||||
return 0;
|
||||
}
|
||||
|
@ -1962,6 +2010,12 @@ static int lPLCILinkUp(struct lPLCI *lp)
|
|||
int ret = 0;
|
||||
struct mPLCI *plci = p4lPLCI(lp);
|
||||
|
||||
if (lp->BIlink) {
|
||||
dprint(MIDEBUG_PLCI, "%s: lPLCILinkUp lp->link(%p) already up, nothing to do\n", CAPIobjIDstr(&lp->cobj),
|
||||
lp->BIlink);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (lp->chid.nr == MI_CHAN_NONE || lp->chid.nr == MI_CHAN_ANY) {
|
||||
/* no valid channel set */
|
||||
wprint("%s: no channel selected (0x%x)\n", CAPIobjIDstr(&lp->cobj), lp->chid.nr);
|
||||
|
@ -1986,11 +2040,16 @@ static int lPLCILinkUp(struct lPLCI *lp)
|
|||
if (!OpenBInstance(lp->BIlink, lp)) {
|
||||
if (!plci->outgoing) { /* incoming call */
|
||||
ret = activate_bchannel(lp->BIlink);
|
||||
if (ret)
|
||||
if (ret) {
|
||||
CloseBInstance(lp->BIlink);
|
||||
lp->BIlink = NULL;
|
||||
ret = CapiMsgOSResourceErr;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
wprint("%s: OpenBInstance failed\n", CAPIobjIDstr(&lp->cobj));
|
||||
ControllerDeSelChannel(lp->BIlink);
|
||||
lp->BIlink = NULL;
|
||||
ret = CapiMsgOSResourceErr;
|
||||
}
|
||||
return ret;
|
||||
|
@ -2030,6 +2089,7 @@ void B3ReleaseLink(struct lPLCI *lp, struct BInstance *bi)
|
|||
{
|
||||
switch(bi->type) {
|
||||
case BType_Direct:
|
||||
case BType_tty:
|
||||
ncciReleaseLink(bi->b3data);
|
||||
break;
|
||||
#ifdef USE_SOFTFAX
|
||||
|
@ -2066,17 +2126,17 @@ void lPLCI_l3l4(struct lPLCI *lp, int pr, struct mc_buf *mc)
|
|||
break;
|
||||
case MT_CONNECT:
|
||||
if (mc->l3m) {
|
||||
ret = plci_parse_channel_id(lp, mc);
|
||||
if (ret < 0) {
|
||||
dprint(MIDEBUG_PLCI, "%s: Got no valid channel on %s (%d)\n", CAPIobjIDstr(&lp->cobj),
|
||||
_mi_msg_type2str(pr), ret);
|
||||
}
|
||||
lPLCIInfoIndIE(lp, IE_DATE, CAPI_INFOMASK_DISPLAY, mc);
|
||||
lPLCIInfoIndIE(lp, IE_DISPLAY, CAPI_INFOMASK_DISPLAY, mc);
|
||||
lPLCIInfoIndIE(lp, IE_USER_USER, CAPI_INFOMASK_USERUSER, mc);
|
||||
lPLCIInfoIndIE(lp, IE_PROGRESS, CAPI_INFOMASK_PROGRESS, mc);
|
||||
lPLCIInfoIndIE(lp, IE_FACILITY, CAPI_INFOMASK_FACILITY, mc);
|
||||
lPLCIInfoIndIE(lp, IE_CHANNEL_ID, CAPI_INFOMASK_CHANNELID, mc);
|
||||
ret = plci_parse_channel_id(lp, mc);
|
||||
if (ret < 0) {
|
||||
dprint(MIDEBUG_PLCI, "%s: Got no valid channel on %s (%d)\n", CAPIobjIDstr(&lp->cobj),
|
||||
_mi_msg_type2str(pr), ret);
|
||||
}
|
||||
}
|
||||
del_timer(&lp->atimer);
|
||||
FsmEvent(&lp->plci_m, EV_L3_SETUP_CONF, mc);
|
||||
|
@ -2130,19 +2190,24 @@ void lPLCI_l3l4(struct lPLCI *lp, int pr, struct mc_buf *mc)
|
|||
break;
|
||||
case MT_SETUP_ACKNOWLEDGE:
|
||||
if (mc->l3m) {
|
||||
lPLCIInfoIndMsg(lp, CAPI_INFOMASK_PROGRESS, MT_SETUP_ACKNOWLEDGE, mc);
|
||||
lPLCIInfoIndIE(lp, IE_DISPLAY, CAPI_INFOMASK_DISPLAY, mc);
|
||||
lPLCIInfoIndIE(lp, IE_PROGRESS, CAPI_INFOMASK_PROGRESS | CAPI_INFOMASK_EARLYB3, mc);
|
||||
lPLCIInfoIndIE(lp, IE_CHANNEL_ID, CAPI_INFOMASK_CHANNELID, mc);
|
||||
ret = plci_parse_channel_id(lp, mc);
|
||||
if (ret < -1) {
|
||||
wprint("%s: Got channel coding error in %s (%d)\n", CAPIobjIDstr(&lp->cobj),
|
||||
_mi_msg_type2str(pr), ret);
|
||||
}
|
||||
lPLCIInfoIndMsg(lp, CAPI_INFOMASK_PROGRESS, MT_SETUP_ACKNOWLEDGE, mc);
|
||||
lPLCIInfoIndIE(lp, IE_DISPLAY, CAPI_INFOMASK_DISPLAY, mc);
|
||||
lPLCIInfoIndIE(lp, IE_PROGRESS, CAPI_INFOMASK_PROGRESS | CAPI_INFOMASK_EARLYB3, mc);
|
||||
lPLCIInfoIndIE(lp, IE_CHANNEL_ID, CAPI_INFOMASK_CHANNELID, mc);
|
||||
}
|
||||
break;
|
||||
case MT_CALL_PROCEEDING:
|
||||
if (mc->l3m) {
|
||||
ret = plci_parse_channel_id(lp, mc);
|
||||
if (ret < -1) {
|
||||
wprint("%s: Got channel coding error in %s (%d)\n", CAPIobjIDstr(&lp->cobj),
|
||||
_mi_msg_type2str(pr), ret);
|
||||
}
|
||||
lPLCIInfoIndMsg(lp, CAPI_INFOMASK_PROGRESS, MT_CALL_PROCEEDING, mc);
|
||||
lPLCIInfoIndIE(lp, IE_DISPLAY, CAPI_INFOMASK_DISPLAY, mc);
|
||||
lPLCIInfoIndIE(lp, IE_PROGRESS, CAPI_INFOMASK_PROGRESS | CAPI_INFOMASK_EARLYB3, mc);
|
||||
|
@ -2151,17 +2216,17 @@ void lPLCI_l3l4(struct lPLCI *lp, int pr, struct mc_buf *mc)
|
|||
break;
|
||||
case MT_ALERTING:
|
||||
if (mc->l3m) {
|
||||
ret = plci_parse_channel_id(lp, mc);
|
||||
if (ret < -1) {
|
||||
wprint("%s: Got channel coding error in %s (%d)\n", CAPIobjIDstr(&lp->cobj),
|
||||
_mi_msg_type2str(pr), ret);
|
||||
}
|
||||
lPLCIInfoIndMsg(lp, CAPI_INFOMASK_PROGRESS, MT_ALERTING, mc);
|
||||
lPLCIInfoIndIE(lp, IE_DISPLAY, CAPI_INFOMASK_DISPLAY, mc);
|
||||
lPLCIInfoIndIE(lp, IE_USER_USER, CAPI_INFOMASK_USERUSER, mc);
|
||||
lPLCIInfoIndIE(lp, IE_PROGRESS, CAPI_INFOMASK_PROGRESS | CAPI_INFOMASK_EARLYB3, mc);
|
||||
lPLCIInfoIndIE(lp, IE_FACILITY, CAPI_INFOMASK_FACILITY, mc);
|
||||
lPLCIInfoIndIE(lp, IE_CHANNEL_ID, CAPI_INFOMASK_CHANNELID, mc);
|
||||
ret = plci_parse_channel_id(lp, mc);
|
||||
if (ret < -1) {
|
||||
wprint("%s: Got channel coding error in %s (%d)\n", CAPIobjIDstr(&lp->cobj),
|
||||
_mi_msg_type2str(pr), ret);
|
||||
}
|
||||
add_timer(&lp->atimer, ALERT_TIMEOUT);
|
||||
}
|
||||
break;
|
||||
|
|
|
@ -57,6 +57,9 @@ extern pid_t gettid(void);
|
|||
#define MICD_CTRL_SHUTDOWN 0x42010000
|
||||
#define MICD_CTRL_DISABLE_POLL 0x42020000
|
||||
#define MICD_CTRL_ENABLE_POLL 0x42030000
|
||||
#define MICD_CTRL_REOPEN_LOG 0x42040000
|
||||
#define MICD_CTRL_DUMP_1 0x42050000
|
||||
#define MICD_CTRL_DUMP_2 0x42060000
|
||||
|
||||
int send_master_control(int, int, void *);
|
||||
|
||||
|
@ -133,19 +136,26 @@ struct mCAPIobj {
|
|||
#endif
|
||||
};
|
||||
|
||||
#if __GNUC_PREREQ (3,4)
|
||||
# define __WUR __attribute__ ((__warn_unused_result__))
|
||||
#else
|
||||
# define __WUR
|
||||
#endif
|
||||
|
||||
|
||||
#ifdef MISDN_CAPI_REFCOUNT_DEBUG
|
||||
struct mCAPIobj *__get_cobj(struct mCAPIobj *, const char *, int);
|
||||
struct mCAPIobj *__get_cobj(struct mCAPIobj *, const char *, int) __WUR;
|
||||
int __put_cobj(struct mCAPIobj *, const char *, int);
|
||||
struct mCAPIobj *__get_next_cobj(struct mCAPIobj *, struct mCAPIobj *, const char *, int);
|
||||
struct mCAPIobj *__get_next_cobj(struct mCAPIobj *, struct mCAPIobj *, const char *, int) __WUR;
|
||||
int __delist_cobj(struct mCAPIobj *, const char *, int);
|
||||
#define get_cobj(co) __get_cobj(co, __FILE__, __LINE__)
|
||||
#define put_cobj(co) __put_cobj(co, __FILE__, __LINE__)
|
||||
#define get_next_cobj(pa, co) __get_next_cobj(pa, co, __FILE__, __LINE__)
|
||||
#define delist_cobj(co) __delist_cobj(co, __FILE__, __LINE__)
|
||||
#else
|
||||
struct mCAPIobj *get_cobj(struct mCAPIobj *);
|
||||
struct mCAPIobj *get_cobj(struct mCAPIobj *) __WUR;
|
||||
int put_cobj(struct mCAPIobj *);
|
||||
struct mCAPIobj *get_next_cobj(struct mCAPIobj *, struct mCAPIobj *);
|
||||
struct mCAPIobj *get_next_cobj(struct mCAPIobj *, struct mCAPIobj *) __WUR;
|
||||
int delist_cobj(struct mCAPIobj *);
|
||||
#endif
|
||||
|
||||
|
@ -169,6 +179,7 @@ struct BInstance {
|
|||
int proto;
|
||||
int fd;
|
||||
int tty;
|
||||
int tty_received;
|
||||
int rx_min;
|
||||
int rx_max;
|
||||
int org_rx_min;
|
||||
|
@ -243,6 +254,7 @@ struct pController {
|
|||
struct pController *get_mController(int);
|
||||
struct pController *get_cController(int);
|
||||
struct BInstance *ControllerSelChannel(struct pController *, int, int);
|
||||
int ControllerDeSelChannel(struct BInstance *);
|
||||
uint32_t NextFreePLCI(struct mCAPIobj *);
|
||||
int OpenLayer3(struct pController *);
|
||||
int check_free_bchannels(struct pController *);
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
*
|
||||
* Author Karsten Keil <kkeil@linux-pingi.de>
|
||||
*
|
||||
* Copyright 2011 by Karsten Keil <kkeil@linux-pingi.de>
|
||||
* Copyright 2011,2016 by Karsten Keil <kkeil@linux-pingi.de>
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU LESSER GENERAL PUBLIC LICENSE
|
||||
|
@ -25,7 +25,8 @@
|
|||
extern "C" {
|
||||
#endif
|
||||
|
||||
#define MISDN_CAPI_SOCKET_PATH "/var/run/mISDNcapid/sock"
|
||||
#define MISDN_CAPI_SOCKET_NAME "@MISDN_CAPI_SOCKET_NAME@"
|
||||
#define MISDN_CAPI_SOCKET_DIR "@MISDN_CAPI_SOCKET_DIR@"
|
||||
|
||||
#define MIC_INFO_CODING_ERROR 1
|
||||
|
|
@ -65,7 +65,7 @@ static int misdnOpenSocket(void)
|
|||
return -1;
|
||||
}
|
||||
mcaddr.sun_family = AF_UNIX;
|
||||
sprintf(mcaddr.sun_path, MISDN_CAPI_SOCKET_PATH);
|
||||
sprintf(mcaddr.sun_path, "%s/%s", MISDN_CAPI_SOCKET_DIR, MISDN_CAPI_SOCKET_NAME);
|
||||
|
||||
/* Connect socket to address */
|
||||
if (!connect(nHandle, (struct sockaddr *)&mcaddr, sizeof(mcaddr))) {
|
||||
|
|
|
@ -36,7 +36,7 @@
|
|||
const int ST_NCCI_COUNT = ST_NCCI_N_5 + 1;
|
||||
const int EV_NCCI_COUNT = EV_AP_RELEASE + 1;
|
||||
|
||||
static char *str_st_ncci[] = {
|
||||
static const char *str_st_ncci[] = {
|
||||
"ST_NCCI_N_0",
|
||||
"ST_NCCI_N_0_1",
|
||||
"ST_NCCI_N_1",
|
||||
|
@ -47,7 +47,7 @@ static char *str_st_ncci[] = {
|
|||
"ST_NCCI_N_5",
|
||||
};
|
||||
|
||||
static char *str_ev_ncci[] = {
|
||||
static const char *str_ev_ncci[] = {
|
||||
"EV_AP_CONNECT_B3_REQ",
|
||||
"EV_NC_CONNECT_B3_CONF",
|
||||
"EV_NC_CONNECT_B3_IND",
|
||||
|
@ -93,7 +93,7 @@ const char *_mi_ncci_ev2str(enum ev_ncci_e ev)
|
|||
}
|
||||
|
||||
|
||||
static void ncci_debug(struct FsmInst *fi, char *fmt, ...)
|
||||
static void ncci_debug(struct FsmInst *fi, const char *fmt, ...)
|
||||
{
|
||||
char tmp[128];
|
||||
va_list args;
|
||||
|
@ -151,7 +151,7 @@ static void ncci_connect_b3_resp(struct FsmInst *fi, int event, void *arg)
|
|||
struct mNCCI *ncci = fi->userdata;
|
||||
struct mc_buf *mc = arg;
|
||||
|
||||
if (mc->cmsg.Info == 0) {
|
||||
if (mc->cmsg.Reject == 0) {
|
||||
FsmChangeState(fi, ST_NCCI_N_2);
|
||||
ncciCmsgHeader(ncci, mc, CAPI_CONNECT_B3_ACTIVE, CAPI_IND);
|
||||
if (ncci->ncpi)
|
||||
|
@ -557,6 +557,7 @@ static struct FsmNode fn_ncci_list[] = {
|
|||
#endif
|
||||
{ST_NCCI_N_4, EV_NC_DISCONNECT_B3_CONF, ncci_disconnect_b3_conf},
|
||||
{ST_NCCI_N_4, EV_NC_DISCONNECT_B3_IND, ncci_disconnect_b3_ind},
|
||||
{ST_NCCI_N_4, EV_DL_RELEASE_IND, ncci_dl_release_ind_conf},
|
||||
{ST_NCCI_N_4, EV_DL_RELEASE_CONF, ncci_dl_release_ind_conf},
|
||||
{ST_NCCI_N_4, EV_DL_DOWN_IND, ncci_dl_down_ind},
|
||||
{ST_NCCI_N_4, EV_AP_MANUFACTURER_REQ, ncci_manufacturer_req},
|
||||
|
@ -640,6 +641,7 @@ struct mNCCI *ncciCreate(struct lPLCI *lp)
|
|||
{
|
||||
struct mNCCI *nc;
|
||||
int err;
|
||||
struct mApplication *appl = NULL;
|
||||
|
||||
nc = calloc(1, sizeof(*nc));
|
||||
if (!nc) {
|
||||
|
@ -647,6 +649,15 @@ struct mNCCI *ncciCreate(struct lPLCI *lp)
|
|||
return NULL;
|
||||
}
|
||||
nc->cobj.id2 = lp->cobj.id2;
|
||||
if (lp->Appl) {
|
||||
if (get_cobj(&lp->Appl->cobj)) {
|
||||
appl = lp->Appl;
|
||||
} else {
|
||||
wprint("Cannot get application object\n");
|
||||
free(nc);
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
err = init_cobj_registered(&nc->cobj, &lp->cobj, Cot_NCCI, 0x01ffff);
|
||||
if (!err) {
|
||||
dprint(MIDEBUG_NCCI, "NCCI%06x: will be created now\n", nc->cobj.id);
|
||||
|
@ -654,9 +665,7 @@ struct mNCCI *ncciCreate(struct lPLCI *lp)
|
|||
nc->ncci_m.debug = MIDEBUG_NCCI & mI_debug_mask;
|
||||
nc->ncci_m.userdata = nc;
|
||||
nc->ncci_m.printdebug = ncci_debug;
|
||||
nc->appl = lp->Appl;
|
||||
if (nc->appl)
|
||||
get_cobj(&nc->appl->cobj);
|
||||
nc->appl = appl;
|
||||
nc->BIlink = lp->BIlink;
|
||||
nc->window = lp->Appl->MaxB3Blk;
|
||||
pthread_mutex_init(&nc->lock, NULL);
|
||||
|
@ -710,6 +719,8 @@ struct mNCCI *ncciCreate(struct lPLCI *lp)
|
|||
nc->osize = 256;
|
||||
dprint(MIDEBUG_NCCI, "%s: created\n", CAPIobjIDstr(&nc->cobj));
|
||||
} else {
|
||||
if (appl)
|
||||
put_cobj(&appl->cobj);
|
||||
free(nc);
|
||||
nc = NULL;
|
||||
}
|
||||
|
@ -1062,6 +1073,12 @@ static int ncciDataInd(struct mNCCI *ncci, int pr, struct mc_buf *mc)
|
|||
pthread_mutex_unlock(&ncci->lock);
|
||||
hh++;
|
||||
mc->rp = (unsigned char *)hh;
|
||||
if (!ncci->BIlink->tty_received) {
|
||||
wprint("%s: frame with %d bytes discarded to avoid loopback\n",
|
||||
CAPIobjIDstr(&ncci->cobj), dlen);
|
||||
dhexprint(MIDEBUG_NCCI_DATA, "Data: ", mc->rp, dlen);
|
||||
return -EBUSY;
|
||||
}
|
||||
ret = write(ncci->BIlink->tty, mc->rp, dlen);
|
||||
if (ret != dlen)
|
||||
wprint("%s: frame with %d bytes only %d bytes were written to tty - %s\n",
|
||||
|
@ -1164,6 +1181,8 @@ static void ncciDataConf(struct mNCCI *ncci, struct mc_buf *mc)
|
|||
pthread_mutex_unlock(&ncci->lock);
|
||||
if (do_answer)
|
||||
AnswerDataB3Req(ncci, mc, CapiNoError);
|
||||
else
|
||||
free_mc_buf(mc);
|
||||
SendDataB3Down(ncci, 0);
|
||||
return;
|
||||
}
|
||||
|
|
12
capi20/sff.c
12
capi20/sff.c
|
@ -506,10 +506,10 @@ int SFF_WriteTiff(struct sff_state *sff, char *name)
|
|||
TIFF *tf;
|
||||
int compression_out = COMPRESSION_CCITTFAX3;
|
||||
int fillorder_out = FILLORDER_MSB2LSB;
|
||||
uint32 group3options_out = GROUP3OPT_FILLBITS|GROUP3OPT_2DENCODING;
|
||||
uint32 group4options_out = 0; /* compressed */
|
||||
uint32 defrowsperstrip = (uint32) 0;
|
||||
uint32 rowsperstrip;
|
||||
uint32_t group3options_out = GROUP3OPT_FILLBITS|GROUP3OPT_2DENCODING;
|
||||
uint32_t group4options_out = 0; /* compressed */
|
||||
uint32_t defrowsperstrip = (uint32_t) 0;
|
||||
uint32_t rowsperstrip;
|
||||
int photometric_out = PHOTOMETRIC_MINISWHITE;
|
||||
float resY;
|
||||
|
||||
|
@ -549,14 +549,14 @@ int SFF_WriteTiff(struct sff_state *sff, char *name)
|
|||
case COMPRESSION_CCITTFAX3:
|
||||
TIFFSetField(tf, TIFFTAG_GROUP3OPTIONS, group3options_out);
|
||||
TIFFSetField(tf, TIFFTAG_FAXMODE, FAXMODE_CLASSIC);
|
||||
rowsperstrip = (defrowsperstrip) ? defrowsperstrip : (uint32)-1;
|
||||
rowsperstrip = (defrowsperstrip) ? defrowsperstrip : (uint32_t)-1;
|
||||
break;
|
||||
|
||||
/* g4 */
|
||||
case COMPRESSION_CCITTFAX4:
|
||||
TIFFSetField(tf, TIFFTAG_GROUP4OPTIONS, group4options_out);
|
||||
TIFFSetField(tf, TIFFTAG_FAXMODE, FAXMODE_CLASSIC);
|
||||
rowsperstrip = (defrowsperstrip) ? defrowsperstrip : (uint32)-1;
|
||||
rowsperstrip = (defrowsperstrip) ? defrowsperstrip : (uint32_t)-1;
|
||||
break;
|
||||
|
||||
default:
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
# Process this file with autoconf to produce a configure script.
|
||||
|
||||
AC_PREREQ([2.63])
|
||||
AC_INIT([mISDNuser],[2.0.17],[i4ldeveloper@isdn4linux.de],[mISDNuser])
|
||||
AC_INIT([mISDNuser],[2.0.22],[i4ldeveloper@isdn4linux.de],[mISDNuser])
|
||||
AC_CONFIG_SRCDIR([tools/])
|
||||
AC_CONFIG_HEADERS([include/config.h])
|
||||
AC_CONFIG_MACRO_DIR([m4])
|
||||
|
@ -13,7 +13,9 @@ AM_INIT_AUTOMAKE([-Wall foreign subdir-objects])
|
|||
AC_PROG_CC
|
||||
AC_PROG_CXX
|
||||
AC_PROG_INSTALL
|
||||
AM_PROG_AR
|
||||
AC_PROG_LIBTOOL
|
||||
AM_PROG_LEX
|
||||
|
||||
AC_CHECK_LIB([pthread], [pthread_create])
|
||||
|
||||
|
@ -143,6 +145,8 @@ then
|
|||
AC_MSG_ERROR([spandsp header file not found - install spandsp development files])
|
||||
)
|
||||
fi
|
||||
AC_SUBST( [MISDN_CAPI_SOCKET_NAME], "sock" )
|
||||
AC_SUBST( [MISDN_CAPI_SOCKET_DIR], "$(localstatedir)/run/mISDNcapid" )
|
||||
fi
|
||||
|
||||
# Checks for library functions.
|
||||
|
@ -181,6 +185,7 @@ AC_CONFIG_FILES([Makefile
|
|||
guitools/Makefile
|
||||
guitools/qmisdnwatch/Makefile
|
||||
capi20/Makefile
|
||||
capi20/m_capi_sock.h
|
||||
capi20/module/Makefile
|
||||
])
|
||||
|
||||
|
|
|
@ -39,7 +39,7 @@
|
|||
#include <mISDN/q931.h>
|
||||
#include <mISDN/af_isdn.h>
|
||||
|
||||
int main()
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
int cnt, ret = 0, i = 0;
|
||||
int sk;
|
||||
|
|
|
@ -51,8 +51,7 @@
|
|||
#define MISDN_CTRL_L1_GET_SYNC_INFO 0x00010004
|
||||
#endif
|
||||
|
||||
void usage(pname)
|
||||
char *pname;
|
||||
void usage(char *pname)
|
||||
{
|
||||
fprintf(stderr,"Call with %s [options] [filename]\n",pname);
|
||||
fprintf(stderr,"\n");
|
||||
|
@ -81,6 +80,7 @@ char *pname;
|
|||
fprintf(stderr," 13 L1 Test AIS set)\n");
|
||||
fprintf(stderr," 14 L1 Test AIS cleared)\n");
|
||||
fprintf(stderr," 15 L1 Test set state machine to given -n value (allowed values 0-7, 7 - auto state enabled)\n");
|
||||
fprintf(stderr," 16 Reject calls with cause values (given via -n)\n");
|
||||
fprintf(stderr," -n <phone nr> Phonenumber to dial or on -F12 T3 value\n");
|
||||
fprintf(stderr," -vn Printing debug info level n\n");
|
||||
fprintf(stderr,"\n");
|
||||
|
@ -90,6 +90,7 @@ typedef struct _devinfo {
|
|||
int cardnr;
|
||||
int func;
|
||||
char phonenr[32];
|
||||
unsigned char cause;
|
||||
int layer2;
|
||||
struct sockaddr_mISDN l2addr;
|
||||
int bchan;
|
||||
|
@ -142,7 +143,7 @@ static char tt_char[] = "0123456789ABCD*#";
|
|||
*ptr++ = mty; \
|
||||
} while(0)
|
||||
|
||||
int play_msg(devinfo_t *di) {
|
||||
static int play_msg(devinfo_t *di) {
|
||||
unsigned char buf[PLAY_SIZE + MISDN_HEADER_LEN];
|
||||
struct mISDNhead *hh = (struct mISDNhead *)buf;
|
||||
int len, ret;
|
||||
|
@ -168,7 +169,7 @@ int play_msg(devinfo_t *di) {
|
|||
return ret;
|
||||
}
|
||||
|
||||
int send_data(devinfo_t *di) {
|
||||
static int send_data(devinfo_t *di) {
|
||||
char buf[MAX_DATA_BUF + MISDN_HEADER_LEN];
|
||||
struct mISDNhead *hh = (struct mISDNhead *)buf;
|
||||
char *data;
|
||||
|
@ -201,7 +202,7 @@ int send_data(devinfo_t *di) {
|
|||
return ret;
|
||||
}
|
||||
|
||||
int setup_bchannel(devinfo_t *di) {
|
||||
static int setup_bchannel(devinfo_t *di) {
|
||||
int ret;
|
||||
struct sockaddr_mISDN addr;
|
||||
|
||||
|
@ -241,7 +242,7 @@ int setup_bchannel(devinfo_t *di) {
|
|||
return ret;
|
||||
}
|
||||
|
||||
int send_SETUP(devinfo_t *di, int SI, char *PNr) {
|
||||
static int send_SETUP(devinfo_t *di, int SI, char *PNr) {
|
||||
char *msg, buf[64];
|
||||
char *np,*p;
|
||||
struct mISDNhead *hh = (struct mISDNhead *)buf;
|
||||
|
@ -278,7 +279,82 @@ int send_SETUP(devinfo_t *di, int SI, char *PNr) {
|
|||
return ret;
|
||||
}
|
||||
|
||||
int activate_bchan(devinfo_t *di) {
|
||||
static int send_msg_with_cause(devinfo_t *di, unsigned char mt) {
|
||||
char *msg, buf[64];
|
||||
char *p;
|
||||
struct mISDNhead *hh = (struct mISDNhead *)buf;
|
||||
int ret, len;
|
||||
|
||||
p = msg = buf + MISDN_HEADER_LEN;
|
||||
MsgHead(p, di->cr, mt);
|
||||
*p++ = IE_CAUSE;
|
||||
*p++ = 0x2; /* Length */
|
||||
*p++ = 0x82; /* Coding Std. CCITT, public network*/
|
||||
*p++ = 0x80 | (di->cause & 0x7f);
|
||||
|
||||
len = p - msg;
|
||||
hh->prim = DL_DATA_REQ;
|
||||
hh->id = MISDN_ID_ANY;
|
||||
ret = sendto(di->layer2, buf, len + MISDN_HEADER_LEN, 0, (struct sockaddr *)&di->l2addr, sizeof(di->l2addr));
|
||||
if (ret < 0)
|
||||
fprintf(stdout, "sendto error %s\n", strerror(errno));
|
||||
else if (VerifyOn > 2)
|
||||
fprintf(stdout,"send %s with %d bytes cause #%d\n", mi_msg_type2str(mt), ret, di->cause);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int send_answer(devinfo_t *di, unsigned char mt, unsigned char channel_id) {
|
||||
char *msg, buf[64];
|
||||
char *p;
|
||||
struct mISDNhead *hh = (struct mISDNhead *)buf;
|
||||
int ret, len;
|
||||
|
||||
p = msg = buf + MISDN_HEADER_LEN;
|
||||
MsgHead(p, di->cr, mt);
|
||||
*p++ = IE_CHANNEL_ID;
|
||||
*p++ = 0x1; /* Length */
|
||||
*p++ = channel_id;
|
||||
|
||||
len = p - msg;
|
||||
hh->prim = DL_DATA_REQ;
|
||||
hh->id = MISDN_ID_ANY;
|
||||
ret = sendto(di->layer2, buf, len + MISDN_HEADER_LEN, 0, (struct sockaddr *)&di->l2addr, sizeof(di->l2addr));
|
||||
if (ret < 0)
|
||||
fprintf(stdout, "sendto error %s\n", strerror(errno));
|
||||
else if (VerifyOn > 2)
|
||||
fprintf(stdout,"send %s with %d bytes cause #%d\n", mi_msg_type2str(mt), ret, di->cause);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int send_status(devinfo_t *di, unsigned char state) {
|
||||
char *msg, buf[64];
|
||||
char *p;
|
||||
struct mISDNhead *hh = (struct mISDNhead *)buf;
|
||||
int ret, len;
|
||||
|
||||
p = msg = buf + MISDN_HEADER_LEN;
|
||||
MsgHead(p, di->cr, MT_STATUS);
|
||||
*p++ = IE_CAUSE;
|
||||
*p++ = 0x2; /* Length */
|
||||
*p++ = 0x82; /* Coding Std. CCITT, public network*/
|
||||
*p++ = 0x80 | (di->cause & 0x7f);
|
||||
|
||||
*p++ = IE_CALL_STATE;
|
||||
*p++ = 1;
|
||||
*p++ = state;
|
||||
|
||||
len = p - msg;
|
||||
hh->prim = DL_DATA_REQ;
|
||||
hh->id = MISDN_ID_ANY;
|
||||
ret = sendto(di->layer2, buf, len + MISDN_HEADER_LEN, 0, (struct sockaddr *)&di->l2addr, sizeof(di->l2addr));
|
||||
if (ret < 0)
|
||||
fprintf(stdout, "sendto error %s\n", strerror(errno));
|
||||
else if (VerifyOn > 2)
|
||||
fprintf(stdout,"send %s with %d bytes cause #%d state %d\n", mi_msg_type2str(MT_STATUS), ret, di->cause, state);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int activate_bchan(devinfo_t *di) {
|
||||
unsigned char buf[2048];
|
||||
struct mISDNhead *hh = (struct mISDNhead *)buf;
|
||||
struct timeval tout;
|
||||
|
@ -340,7 +416,7 @@ int activate_bchan(devinfo_t *di) {
|
|||
return ret;
|
||||
}
|
||||
|
||||
int deactivate_bchan(devinfo_t *di) {
|
||||
static int deactivate_bchan(devinfo_t *di) {
|
||||
unsigned char buf[2048];
|
||||
struct mISDNhead *hh = (struct mISDNhead *)buf;
|
||||
struct timeval tout;
|
||||
|
@ -407,7 +483,7 @@ int deactivate_bchan(devinfo_t *di) {
|
|||
}
|
||||
|
||||
#ifdef NOTYET
|
||||
int send_touchtone(devinfo_t *di, int tone) {
|
||||
static int send_touchtone(devinfo_t *di, int tone) {
|
||||
struct mISDNhead frm;
|
||||
int tval, ret;
|
||||
|
||||
|
@ -423,7 +499,7 @@ int send_touchtone(devinfo_t *di, int tone) {
|
|||
}
|
||||
#endif
|
||||
|
||||
void
|
||||
static void
|
||||
do_hw_loop(devinfo_t *di)
|
||||
{
|
||||
struct mISDN_ctrl_req creq;
|
||||
|
@ -439,7 +515,7 @@ do_hw_loop(devinfo_t *di)
|
|||
di->flag |= FLG_BCHANNEL_LOOPSET;
|
||||
}
|
||||
|
||||
void
|
||||
static void
|
||||
del_hw_loop(devinfo_t *di)
|
||||
{
|
||||
struct mISDN_ctrl_req creq;
|
||||
|
@ -456,9 +532,10 @@ del_hw_loop(devinfo_t *di)
|
|||
di->flag &= ~FLG_BCHANNEL_LOOPSET;
|
||||
}
|
||||
|
||||
int do_bchannel(devinfo_t *di, int len, unsigned char *buf)
|
||||
static int do_bchannel(devinfo_t *di, int len, unsigned char *buf)
|
||||
{
|
||||
struct mISDNhead *hh = (struct mISDNhead *)buf;
|
||||
int ret;
|
||||
|
||||
if (len < MISDN_HEADER_LEN) {
|
||||
if (VerifyOn)
|
||||
|
@ -471,7 +548,10 @@ int do_bchannel(devinfo_t *di, int len, unsigned char *buf)
|
|||
hh->prim, hh->id, len);
|
||||
if (hh->prim == PH_DATA_IND) {
|
||||
/* received data, save it */
|
||||
write(di->save, buf + MISDN_HEADER_LEN, len - MISDN_HEADER_LEN);
|
||||
ret = write(di->save, buf + MISDN_HEADER_LEN, len - MISDN_HEADER_LEN);
|
||||
if (ret < 0)
|
||||
fprintf(stderr,"got error on write %s\n", strerror(errno));
|
||||
|
||||
} else if (hh->prim == PH_DATA_CNF) {
|
||||
/* get ACK of send data, so we can
|
||||
* send more
|
||||
|
@ -487,7 +567,9 @@ int do_bchannel(devinfo_t *di, int len, unsigned char *buf)
|
|||
}
|
||||
} else if (hh->prim == DL_DATA_IND) {
|
||||
/* received data, save it */
|
||||
write(di->save, buf + MISDN_HEADER_LEN, len - MISDN_HEADER_LEN);
|
||||
ret = write(di->save, buf + MISDN_HEADER_LEN, len - MISDN_HEADER_LEN);
|
||||
if (ret < 0)
|
||||
fprintf(stderr,"got error on write %s\n", strerror(errno));
|
||||
} else if (hh->prim == (PH_CONTROL_IND)) {
|
||||
if ((len == MISDN_HEADER_LEN) && ((hh->id & ~DTMF_TONE_MASK) == DTMF_TONE_VAL)) {
|
||||
fprintf(stdout,"GOT TT %c\n", DTMF_TONE_MASK & hh->id);
|
||||
|
@ -504,11 +586,11 @@ int do_bchannel(devinfo_t *di, int len, unsigned char *buf)
|
|||
#define L3_MT_OFF (MISDN_HEADER_LEN + 3)
|
||||
#define L3_CR_VAL (MISDN_HEADER_LEN + 2)
|
||||
|
||||
int do_dchannel(devinfo_t *di, int len, unsigned char *buf)
|
||||
static int do_dchannel(devinfo_t *di, int len, unsigned char *buf)
|
||||
{
|
||||
struct mISDNhead *hh = (struct mISDNhead *)buf;
|
||||
unsigned char *p, *msg;
|
||||
int ret, l;
|
||||
int ret, l, result = 0;
|
||||
|
||||
if (len < MISDN_HEADER_LEN) {
|
||||
if (VerifyOn)
|
||||
|
@ -543,9 +625,15 @@ int do_dchannel(devinfo_t *di, int len, unsigned char *buf)
|
|||
}
|
||||
idx++;
|
||||
}
|
||||
if (di->used_bchannel < 1 || di->used_bchannel > 2) {
|
||||
fprintf(stdout,"got no valid bchannel nr %d\n", di->used_bchannel);
|
||||
return 1;
|
||||
switch (di->func) {
|
||||
case 16:
|
||||
case 17:
|
||||
break;
|
||||
default:
|
||||
if (di->used_bchannel < 1 || di->used_bchannel > 2) {
|
||||
fprintf(stdout,"got no valid bchannel nr %d\n", di->used_bchannel);
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
switch (di->func) {
|
||||
case 5:
|
||||
|
@ -574,6 +662,11 @@ int do_dchannel(devinfo_t *di, int len, unsigned char *buf)
|
|||
case 7:
|
||||
di->flag |= FLG_BCHANNEL_SETUP;
|
||||
break;
|
||||
case 16:
|
||||
case 17:
|
||||
send_answer(di, MT_SETUP_ACKNOWLEDGE, 0x81); /* B1 channel */
|
||||
send_msg_with_cause(di, MT_DISCONNECT);
|
||||
return 0;
|
||||
}
|
||||
if (!(di->flag & FLG_CALL_ORGINATE)) {
|
||||
p = msg = buf + MISDN_HEADER_LEN;
|
||||
|
@ -584,7 +677,7 @@ int do_dchannel(devinfo_t *di, int len, unsigned char *buf)
|
|||
ret = sendto(di->layer2, buf, l + MISDN_HEADER_LEN, 0, (struct sockaddr *)&di->l2addr, sizeof(di->l2addr));
|
||||
if (ret < 0) {
|
||||
fprintf(stdout, "sendto error %s\n", strerror(errno));
|
||||
return 4;
|
||||
result = 4;
|
||||
}
|
||||
}
|
||||
} else if ((len > L3_MT_OFF) && (buf[L3_MT_OFF] == MT_CONNECT) && (di->flag & FLG_CALL_ORGINATE)) {
|
||||
|
@ -689,10 +782,40 @@ int do_dchannel(devinfo_t *di, int len, unsigned char *buf)
|
|||
if (ret < 0) {
|
||||
fprintf(stdout, "sendto error %s\n", strerror(errno));
|
||||
}
|
||||
return 7;
|
||||
switch (di->func) {
|
||||
case 16:
|
||||
case 17:
|
||||
result = 0;
|
||||
break;
|
||||
default:
|
||||
result = 7;
|
||||
break;
|
||||
}
|
||||
} else if ((len > L3_MT_OFF) && (buf[L3_MT_OFF] == MT_RELEASE_COMPLETE)) {
|
||||
/* on a disconnecting msg leave loop */
|
||||
return 8;
|
||||
result = 8;
|
||||
} else if ((len > L3_MT_OFF) && (buf[L3_MT_OFF] == MT_RESTART)) {
|
||||
l = di->cr;
|
||||
di->cr = buf[L3_CR_VAL];
|
||||
switch (di->func) {
|
||||
case 17:
|
||||
di->cause = CAUSE_NOTCOMPAT_STATE_OR_MT_NOTIMPLEMENTED;
|
||||
send_status(di, 0);
|
||||
break;
|
||||
default:
|
||||
di->cr = buf[L3_CR_VAL];
|
||||
|
||||
p = msg = buf + MISDN_HEADER_LEN;
|
||||
MsgHead(p, di->cr, MT_RESTART_ACKNOWLEDGE);
|
||||
/* we use the same content as recaived for the answer */
|
||||
hh->prim = DL_DATA_REQ;
|
||||
hh->id = MISDN_ID_ANY;
|
||||
ret = sendto(di->layer2, buf, len, 0, (struct sockaddr *)&di->l2addr, sizeof(di->l2addr));
|
||||
if (ret < 0)
|
||||
fprintf(stdout, "sendto error %s\n", strerror(errno));
|
||||
break;
|
||||
}
|
||||
di->cr = l;
|
||||
result = 9;
|
||||
} else {
|
||||
if (VerifyOn) {
|
||||
fprintf(stdout,"got unexpected D frame prim %s (%x) id(%x) len(%d)\n",
|
||||
|
@ -705,23 +828,24 @@ int do_dchannel(devinfo_t *di, int len, unsigned char *buf)
|
|||
}
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
return result;
|
||||
}
|
||||
|
||||
int do_connection(devinfo_t *di) {
|
||||
unsigned char *p, *msg, buf[MAX_REC_BUF];
|
||||
static int do_connection(devinfo_t *di) {
|
||||
unsigned char buf[MAX_REC_BUF];
|
||||
struct mISDNhead *hh;
|
||||
struct timeval tout;
|
||||
struct sockaddr_mISDN l2addr;
|
||||
socklen_t alen;
|
||||
fd_set rds;
|
||||
int ret = 0, l;
|
||||
int ret = 0;
|
||||
|
||||
if (di->setloopback)
|
||||
return 0;
|
||||
if (di->func > 12)
|
||||
return 0;
|
||||
return 0;
|
||||
if (di->func > 12 && di->func < 16)
|
||||
return 0;
|
||||
hh = (struct mISDNhead *)buf;
|
||||
|
||||
if (strlen(di->phonenr)) {
|
||||
di->flag |= FLG_CALL_ORGINATE;
|
||||
di->cr = 0x81;
|
||||
|
@ -752,15 +876,8 @@ int do_connection(devinfo_t *di) {
|
|||
send_touchtone(di, tt_char[di->val]);
|
||||
} else {
|
||||
/* After last tone disconnect */
|
||||
p = msg = buf + mISDN_HEADER_LEN;
|
||||
MsgHead(p, di->cr, MT_DISCONNECT);
|
||||
l = p - msg;
|
||||
hh->prim = DL_DATA_REQ;
|
||||
hh->id = MISDN_ID_ANY;
|
||||
ret = sendto(di->layer2, buf, l + MISDN_HEADER_LEN, 0, (struct sockaddr *)&di->l2addr, sizeof(di->l2addr));
|
||||
if (ret < 0) {
|
||||
fprintf(stdout, "sendto error %s\n", strerror(errno));
|
||||
}
|
||||
di->cause = CAUSE_NORMAL_CLEARING;
|
||||
send_msg_with_cause(di, MT_DISCONNECT);
|
||||
di->flag &= ~FLG_SEND_TONE;
|
||||
}
|
||||
continue;
|
||||
|
@ -785,30 +902,27 @@ int do_connection(devinfo_t *di) {
|
|||
continue;
|
||||
}
|
||||
if (di->flag & FLG_BCHANNEL_LOOPSET) {
|
||||
if (di->func == 7) { /* we never end on timeout */
|
||||
if (VerifyOn>3)
|
||||
fprintf(stdout,"timed out but continue\n");
|
||||
continue;
|
||||
}
|
||||
if (di->func == 7) { /* we never end on timeout */
|
||||
if (VerifyOn>3)
|
||||
fprintf(stdout,"timed out but continue\n");
|
||||
continue;
|
||||
}
|
||||
}
|
||||
/* hangup */
|
||||
fprintf(stdout,"timed out sending hangup\n");
|
||||
p = msg = buf + MISDN_HEADER_LEN;
|
||||
if (di->flag & FLG_CALL_ACTIVE)
|
||||
MsgHead(p, di->cr, MT_DISCONNECT);
|
||||
else
|
||||
MsgHead(p, di->cr, MT_RELEASE_COMPLETE);
|
||||
l = p - msg;
|
||||
hh->prim = DL_DATA_REQ;
|
||||
hh->id = MISDN_ID_ANY;
|
||||
ret = sendto(di->layer2, buf, l + MISDN_HEADER_LEN, 0, (struct sockaddr *)&di->l2addr, sizeof(di->l2addr));
|
||||
if (ret < 0) {
|
||||
fprintf(stdout, "sendto error %s\n", strerror(errno));
|
||||
if (di->func == 16 || di->func == 17) {
|
||||
break; /* we are cleared */
|
||||
} else {
|
||||
/* hangup */
|
||||
fprintf(stdout,"timed out sending hangup\n");
|
||||
di->cause = CAUSE_NORMAL_CLEARING;
|
||||
if (di->flag & FLG_CALL_ACTIVE)
|
||||
send_msg_with_cause(di, MT_DISCONNECT);
|
||||
else
|
||||
send_msg_with_cause(di, MT_RELEASE_COMPLETE);
|
||||
if (di->flag & FLG_CALL_ACTIVE)
|
||||
di->flag &= ~FLG_CALL_ACTIVE;
|
||||
else
|
||||
break;
|
||||
}
|
||||
if (di->flag & FLG_CALL_ACTIVE)
|
||||
di->flag &= ~FLG_CALL_ACTIVE;
|
||||
else
|
||||
break;
|
||||
}
|
||||
if (FD_ISSET(di->bchan, &rds)) {
|
||||
/* B-Channel related messages */
|
||||
|
@ -881,7 +995,7 @@ int do_connection(devinfo_t *di) {
|
|||
return 0;
|
||||
}
|
||||
|
||||
int do_setup(devinfo_t *di) {
|
||||
static int do_setup(devinfo_t *di) {
|
||||
int cnt, ret = 0;
|
||||
int sk;
|
||||
struct mISDN_devinfo devinfo;
|
||||
|
@ -894,6 +1008,12 @@ int do_setup(devinfo_t *di) {
|
|||
struct mISDN_ctrl_req creq;
|
||||
|
||||
di->dproto = ISDN_P_LAPD_TE;
|
||||
di->l2addr.family = AF_ISDN;
|
||||
di->l2addr.dev = di->cardnr;
|
||||
di->l2addr.channel = 0;
|
||||
di->l2addr.sapi = 0;
|
||||
di->l2addr.tei = 127;
|
||||
|
||||
switch (di->func) {
|
||||
case 0:
|
||||
case 5:
|
||||
|
@ -926,18 +1046,25 @@ int do_setup(devinfo_t *di) {
|
|||
di->si = 1;
|
||||
di->flag |= FLG_BCHANNEL_LOOP;
|
||||
break;
|
||||
case 8:
|
||||
case 9:
|
||||
case 10:
|
||||
case 11:
|
||||
di->setloopback = di->func - 7;
|
||||
break;
|
||||
case 12:
|
||||
case 13:
|
||||
case 14:
|
||||
case 15:
|
||||
di->dproto = ISDN_P_LAPD_NT;
|
||||
break;
|
||||
case 8:
|
||||
case 9:
|
||||
case 10:
|
||||
case 11:
|
||||
di->setloopback = di->func - 7;
|
||||
break;
|
||||
case 12:
|
||||
case 13:
|
||||
case 14:
|
||||
case 15:
|
||||
di->dproto = ISDN_P_LAPD_NT;
|
||||
break;
|
||||
case 17:
|
||||
case 16:
|
||||
di->dproto = ISDN_P_LAPD_NT;
|
||||
di->cause = atol(di->phonenr);
|
||||
di->l2addr.tei = 0; /* P2P */
|
||||
di->phonenr[0] = 0;
|
||||
break;
|
||||
default:
|
||||
fprintf(stdout,"unknown program function %d\n",
|
||||
di->func);
|
||||
|
@ -987,12 +1114,6 @@ int do_setup(devinfo_t *di) {
|
|||
return 6;
|
||||
}
|
||||
|
||||
di->l2addr.family = AF_ISDN;
|
||||
di->l2addr.dev = di->cardnr;
|
||||
di->l2addr.channel = 0;
|
||||
di->l2addr.sapi = 0;
|
||||
di->l2addr.tei = 127;
|
||||
|
||||
ret = bind(di->layer2, (struct sockaddr *) &di->l2addr, sizeof(di->l2addr));
|
||||
|
||||
if (ret < 0) {
|
||||
|
@ -1030,8 +1151,8 @@ int do_setup(devinfo_t *di) {
|
|||
return 8;
|
||||
}
|
||||
if (!di->phonenr[0]) {
|
||||
fprintf(stdout,"Setting Timer 3 value - need to give value with -n\n");
|
||||
return 8;
|
||||
fprintf(stdout,"Setting Timer 3 value - need to give value with -n\n");
|
||||
return 8;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1042,9 +1163,9 @@ int do_setup(devinfo_t *di) {
|
|||
if (ret < 0)
|
||||
fprintf(stdout,"hw_loop ioctl error %s\n", strerror(errno));
|
||||
else
|
||||
fprintf(stdout,"dhw_loop ioctl (%d) successful\n", di->setloopback);
|
||||
close(di->layer2);
|
||||
return ret;
|
||||
fprintf(stdout,"dhw_loop ioctl (%d) successful\n", di->setloopback);
|
||||
close(di->layer2);
|
||||
return ret;
|
||||
}
|
||||
if (di->func == 12) {
|
||||
creq.op = MISDN_CTRL_L1_TIMER3;
|
||||
|
@ -1054,9 +1175,9 @@ int do_setup(devinfo_t *di) {
|
|||
if (ret < 0)
|
||||
fprintf(stdout,"Timer3 ioctl error %s\n", strerror(errno));
|
||||
else
|
||||
fprintf(stdout,"Timer3 ioctl (%d) successful\n", di->setloopback);
|
||||
close(di->layer2);
|
||||
return ret;
|
||||
fprintf(stdout,"Timer3 ioctl (%d) successful\n", di->setloopback);
|
||||
close(di->layer2);
|
||||
return ret;
|
||||
}
|
||||
if (di->func == 13) {
|
||||
|
||||
|
@ -1067,9 +1188,9 @@ int do_setup(devinfo_t *di) {
|
|||
if (ret < 0)
|
||||
fprintf(stdout,"AIS ioctl error %s\n", strerror(errno));
|
||||
else
|
||||
fprintf(stdout,"AIS ioctl enable successful\n");
|
||||
close(di->layer2);
|
||||
return ret;
|
||||
fprintf(stdout,"AIS ioctl enable successful\n");
|
||||
close(di->layer2);
|
||||
return ret;
|
||||
}
|
||||
if (di->func == 14) {
|
||||
creq.op = MISDN_CTRL_L1_AIS_TEST;
|
||||
|
@ -1079,9 +1200,9 @@ int do_setup(devinfo_t *di) {
|
|||
if (ret < 0)
|
||||
fprintf(stdout,"AIS ioctl error %s\n", strerror(errno));
|
||||
else
|
||||
fprintf(stdout,"AIS ioctl disable successful\n");
|
||||
close(di->layer2);
|
||||
return ret;
|
||||
fprintf(stdout,"AIS ioctl disable successful\n");
|
||||
close(di->layer2);
|
||||
return ret;
|
||||
}
|
||||
if (di->func == 15) {
|
||||
creq.op = MISDN_CTRL_L1_STATE_TEST;
|
||||
|
@ -1091,9 +1212,9 @@ int do_setup(devinfo_t *di) {
|
|||
if (ret < 0)
|
||||
fprintf(stdout,"L1 state set ioctl error %s\n", strerror(errno));
|
||||
else
|
||||
fprintf(stdout,"L1 set state(%ld) ioctl successful\n", atol(di->phonenr));
|
||||
close(di->layer2);
|
||||
return ret;
|
||||
fprintf(stdout,"L1 set state(%ld) ioctl successful\n", atol(di->phonenr));
|
||||
close(di->layer2);
|
||||
return ret;
|
||||
}
|
||||
|
||||
hh = (struct mISDNhead *)buffer;
|
||||
|
@ -1148,6 +1269,30 @@ int do_setup(devinfo_t *di) {
|
|||
if (VerifyOn>3)
|
||||
fprintf(stdout,"dl_etablish send ret=%d\n", ret);
|
||||
|
||||
} else if (hh->prim == MPH_ACTIVATE_IND) {
|
||||
fprintf(stdout, "got MPH_ACTIVATE_IND\n");
|
||||
if (alen == sizeof(l2addr)) {
|
||||
if (VerifyOn)
|
||||
fprintf(stdout, "use channel(%d) sapi(%d) tei(%d) for now\n", l2addr.channel, l2addr.sapi, l2addr.tei);
|
||||
di->l2addr = l2addr;
|
||||
}
|
||||
if (di->func == 16 || di->func == 17) {
|
||||
fprintf(stdout, "NT Mode SAPI:%d TEI:%d activated\n", l2addr.sapi, l2addr.tei);
|
||||
} else {
|
||||
if (l2addr.tei != 127)
|
||||
continue;
|
||||
}
|
||||
hh->prim = DL_ESTABLISH_REQ;
|
||||
hh->id = MISDN_ID_ANY;
|
||||
ret = sendto(di->layer2, buffer, MISDN_HEADER_LEN, 0, (struct sockaddr *)&di->l2addr, sizeof(di->l2addr));
|
||||
|
||||
if (ret < 0) {
|
||||
fprintf(stdout, "could not send DL_ESTABLISH_REQ %s\n", strerror(errno));
|
||||
return 12;
|
||||
}
|
||||
|
||||
if (VerifyOn>3)
|
||||
fprintf(stdout,"dl_etablish send ret=%d\n", ret);
|
||||
} else if (hh->prim == DL_ESTABLISH_CNF) {
|
||||
fprintf(stdout, "got DL_ESTABLISH_CNF\n");
|
||||
break;
|
||||
|
@ -1162,12 +1307,9 @@ int do_setup(devinfo_t *di) {
|
|||
return 0;
|
||||
}
|
||||
|
||||
int main(argc,argv)
|
||||
int argc;
|
||||
char *argv[];
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
char FileName[200],FileNameOut[200], FileNameIn[200];
|
||||
char FileName[200],FileNameOut[208], FileNameIn[208];
|
||||
int aidx=1,para=1, idx;
|
||||
char sw;
|
||||
devinfo_t mISDN;
|
||||
|
@ -1206,8 +1348,8 @@ char *argv[];
|
|||
}
|
||||
break;
|
||||
case 'n':
|
||||
if (!argv[aidx][2]) {
|
||||
idx = 0;
|
||||
if (!argv[aidx][2]) {
|
||||
idx = 0;
|
||||
aidx++;
|
||||
} else {
|
||||
idx=2;
|
||||
|
@ -1231,7 +1373,7 @@ char *argv[];
|
|||
} else {
|
||||
if (para==1) {
|
||||
if (argc > 1)
|
||||
strncpy(FileName, argv[aidx], 199);
|
||||
strncpy(FileName, argv[aidx], sizeof(FileName) - 1);
|
||||
para++;
|
||||
} else {
|
||||
fprintf(stderr,"Undefined argument %s\n",argv[aidx]);
|
||||
|
@ -1239,7 +1381,7 @@ char *argv[];
|
|||
exit(1);
|
||||
}
|
||||
}
|
||||
aidx++;
|
||||
aidx++;
|
||||
} while (aidx<argc);
|
||||
}
|
||||
err = socket(PF_ISDN, SOCK_RAW, ISDN_P_BASE);
|
||||
|
@ -1249,8 +1391,8 @@ char *argv[];
|
|||
return 1;
|
||||
}
|
||||
close(err);
|
||||
sprintf(FileNameOut,"%s.out", FileName);
|
||||
sprintf(FileNameIn,"%s.in", FileName);
|
||||
snprintf(FileNameOut, sizeof(FileNameOut) - 1, "%s.out", FileName);
|
||||
snprintf(FileNameIn, sizeof(FileNameIn) - 1, "%s.in", FileName);
|
||||
if (0>(mISDN.save = open(FileNameIn, O_WRONLY|O_CREAT|O_TRUNC,S_IRWXU))) {
|
||||
printf("TestmISDN cannot open %s due to %s\n",FileNameIn,
|
||||
strerror(errno));
|
||||
|
|
|
@ -87,7 +87,7 @@ void usage(void) {
|
|||
printf("\nvalid options are:\n");
|
||||
printf("\n");
|
||||
printf(" --card=<n> use card number n (default 0)\n");
|
||||
printf(" --d enable D channel stream with <n> packet sz\n");
|
||||
printf(" --d, --d=<n> enable D channel stream with <n> packet sz\n");
|
||||
printf(" --b1, --b1=<n> enable B channel stream with <n> packet sz\n");
|
||||
printf(" --b2, --b2=<n> enable B channel stream with <n> packet sz\n");
|
||||
printf(" --te use TA in TE mode (default is NT)\n");
|
||||
|
@ -115,10 +115,13 @@ void usage(void) {
|
|||
#define CHAN_D 2
|
||||
#define MAX_CHAN 3
|
||||
|
||||
#define CHAN_ACTIVATE 1
|
||||
#define CHAN_DEACTIVATE 0
|
||||
|
||||
#define TX_BURST_HEADER_SZ 5
|
||||
|
||||
|
||||
static char * CHAN_NAMES[MAX_CHAN] = {
|
||||
static const char * CHAN_NAMES[MAX_CHAN] = {
|
||||
"B1", "B2", "D "
|
||||
};
|
||||
|
||||
|
@ -153,20 +156,22 @@ typedef struct {
|
|||
int tx_ack;
|
||||
int transp_rx;
|
||||
int activated;
|
||||
unsigned long long t_start; // time of day first TX
|
||||
unsigned long long t_start; // timestamp of first channel activate CNF
|
||||
data_stats_t rx, tx; // contains data statistics
|
||||
unsigned long seq_num;
|
||||
unsigned char idle_cnt; // cnt seconds if channel is acivated by idle
|
||||
unsigned char res_cnt; // cnt channel ressurections
|
||||
unsigned char hdlc;
|
||||
unsigned char toggle; // ACTIVATE/DEACTIVATE channel during testloop
|
||||
unsigned int toggle_cnt; // toggle count
|
||||
} channel_data_t;
|
||||
|
||||
typedef struct _devinfo {
|
||||
int device;
|
||||
int cardnr;
|
||||
int layerid[4]; // layer1 ID
|
||||
|
||||
int layerid[4]; // layer1 ID (sockets)
|
||||
struct sockaddr_mISDN laddr[4];
|
||||
int nds;
|
||||
|
||||
channel_data_t ch[4]; // data channel info for D,B2,B2,(E)
|
||||
unsigned char channel_mask; // enable channel streams
|
||||
|
@ -179,6 +184,7 @@ static int debug = 0;
|
|||
static int usleep_val = 200;
|
||||
static int te_mode = 0;
|
||||
static int stop = 0; // stop after x seconds
|
||||
static int exit_app = 0; // stop after x seconds
|
||||
static unsigned char payload = 1;
|
||||
static int btrans = 0;
|
||||
static int testloop = 0;
|
||||
|
@ -188,22 +194,22 @@ static devinfo_t mISDN;
|
|||
static unsigned char trans_tx_val[MAX_CHAN] = {0, 0, 0};
|
||||
static unsigned char trans_rx_val[MAX_CHAN] = {0, 0, 0};
|
||||
|
||||
void sig_handler(int sig) {
|
||||
int i;
|
||||
|
||||
fprintf(stdout, "exiting...\n");
|
||||
fflush(stdout);
|
||||
fflush(stderr);
|
||||
for (i = 0; i < MAX_CHAN; i++) {
|
||||
if (mISDN.layerid[i] > 0) {
|
||||
fprintf(stdout, "closing socket '%s'\n", CHAN_NAMES[i]);
|
||||
close(mISDN.layerid[i]);
|
||||
}
|
||||
// function header
|
||||
int control_channel(devinfo_t *di, unsigned char chan_id, unsigned char activate);
|
||||
|
||||
|
||||
void sig_handler(int sig) {
|
||||
switch (sig) {
|
||||
case 2:
|
||||
exit_app = 1; // request graceful stop of mainloop
|
||||
return;
|
||||
default:
|
||||
exit(0);
|
||||
}
|
||||
exit(0);
|
||||
}
|
||||
|
||||
void set_signals() {
|
||||
void set_signals(void) {
|
||||
/* Set up the signal handler */
|
||||
signal(SIGHUP, sig_handler);
|
||||
signal(SIGINT, sig_handler);
|
||||
|
@ -244,10 +250,6 @@ int setup_bchannel(devinfo_t *di, unsigned char bch) {
|
|||
return 2;
|
||||
}
|
||||
|
||||
if (di->layerid[bch] > di->nds - 1) {
|
||||
di->nds = di->layerid[bch] + 1;
|
||||
}
|
||||
|
||||
ret = fcntl(di->layerid[bch], F_SETFL, O_NONBLOCK);
|
||||
if (ret < 0) {
|
||||
fprintf(stdout, "fcntl error %s\n", strerror(errno));
|
||||
|
@ -268,62 +270,101 @@ int setup_bchannel(devinfo_t *di, unsigned char bch) {
|
|||
return ret;
|
||||
}
|
||||
|
||||
int activate_bchan(devinfo_t *di, unsigned char bch) {
|
||||
unsigned char buf[2048];
|
||||
struct mISDNhead *hh = (struct mISDNhead *) buf;
|
||||
/*
|
||||
* activate / deactivate B-Channel
|
||||
*/
|
||||
int control_channel(devinfo_t *di, unsigned char chan_id, unsigned char activate)
|
||||
{
|
||||
unsigned char buffer[2048];
|
||||
struct mISDNhead *hh = (struct mISDNhead *) buffer;
|
||||
struct timeval tout;
|
||||
fd_set rds;
|
||||
int ret;
|
||||
socklen_t alen;
|
||||
unsigned char done = 0;
|
||||
|
||||
hh->prim = PH_ACTIVATE_REQ;
|
||||
hh->prim = activate ? PH_ACTIVATE_REQ : PH_DEACTIVATE_REQ;
|
||||
hh->id = MISDN_ID_ANY;
|
||||
ret = sendto(di->layerid[bch], buf, MISDN_HEADER_LEN, 0, NULL, 0);
|
||||
ret = sendto(di->layerid[chan_id], buffer, MISDN_HEADER_LEN, 0, NULL, 0);
|
||||
|
||||
if (ret < 0) {
|
||||
fprintf(stdout, "could not send ACTIVATE_REQ %s\n", strerror(errno));
|
||||
fprintf(stdout, "could not send %s %s\n",
|
||||
(activate ? "PH_ACTIVATE_REQ" : "PH_DEACTIVATE_REQ"),
|
||||
strerror(errno));
|
||||
return 0;
|
||||
}
|
||||
|
||||
fprintf(stdout, "--> B%i - PH_ACTIVATE_REQ\n", bch + 1);
|
||||
|
||||
tout.tv_usec = 0;
|
||||
tout.tv_sec = 10;
|
||||
FD_ZERO(&rds);
|
||||
FD_SET(di->layerid[bch], &rds);
|
||||
|
||||
ret = select(di->nds, &rds, NULL, NULL, &tout);
|
||||
if (debug > 3) {
|
||||
fprintf(stdout, "select ret=%d\n", ret);
|
||||
}
|
||||
if (ret < 0) {
|
||||
fprintf(stdout, "select error %s\n", strerror(errno));
|
||||
return 0;
|
||||
}
|
||||
if (ret == 0) {
|
||||
fprintf(stdout, "select timeeout\n");
|
||||
return 0;
|
||||
if (!di->ch[chan_id].toggle_cnt || exit_app) {
|
||||
fprintf(stdout, "--> %s - %s\n", CHAN_NAMES[chan_id], (activate ? "PH_ACTIVATE_REQ" : "PH_DEACTIVATE_REQ"));
|
||||
}
|
||||
|
||||
if (FD_ISSET(di->layerid[bch], &rds)) {
|
||||
ret = recv(di->layerid[bch], buf, 2048, 0);
|
||||
int max_retry = 128;
|
||||
|
||||
do {
|
||||
tout.tv_usec = 1000 * 100;
|
||||
tout.tv_sec = 0;
|
||||
FD_ZERO(&rds);
|
||||
FD_SET(di->layerid[chan_id], &rds);
|
||||
|
||||
ret = select(di->layerid[chan_id]+1, &rds, NULL, NULL, &tout);
|
||||
if (debug > 3) {
|
||||
fprintf(stdout, "select ret=%d\n", ret);
|
||||
}
|
||||
if (ret < 0) {
|
||||
fprintf(stdout, "recv error %s\n", strerror(errno));
|
||||
fprintf(stdout, "select error %s\n", strerror(errno));
|
||||
return 0;
|
||||
}
|
||||
if (hh->prim == PH_ACTIVATE_IND) {
|
||||
fprintf(stdout, "<-- B%i - PH_ACTIVATE_IND\n", bch + 1);
|
||||
di->ch[bch].activated = 1;
|
||||
if (ret == 0) {
|
||||
fprintf(stdout, "select timeeout\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (FD_ISSET(di->layerid[chan_id], &rds)) {
|
||||
alen = sizeof (di->laddr[chan_id]);
|
||||
ret = recvfrom(di->layerid[chan_id], buffer, 2048, 0,
|
||||
(struct sockaddr *) &di->laddr[chan_id], &alen);
|
||||
if (ret < 0) {
|
||||
fprintf(stdout, "recvfrom error %s\n",
|
||||
strerror(errno));
|
||||
return 0;
|
||||
}
|
||||
if (debug > 3) {
|
||||
fprintf(stdout, "alen =%d, dev(%d) channel(%d)\n",
|
||||
alen, di->laddr[chan_id].dev, di->laddr[chan_id].channel);
|
||||
}
|
||||
if (activate && ((hh->prim == PH_ACTIVATE_IND) || (hh->prim == PH_ACTIVATE_CNF))) {
|
||||
if (!di->ch[chan_id].toggle_cnt || exit_app) {
|
||||
fprintf(stdout,
|
||||
"<-- %s - PH_ACTIVATE_%s\n",
|
||||
CHAN_NAMES[chan_id],
|
||||
(hh->prim == PH_ACTIVATE_IND) ? "IND" : "CNF");
|
||||
}
|
||||
di->ch[chan_id].toggle_cnt++;
|
||||
di->ch[chan_id].activated = 1;
|
||||
done = 1;
|
||||
} else
|
||||
if (!activate && ((hh->prim == PH_DEACTIVATE_IND) || (hh->prim == PH_DEACTIVATE_CNF))) {
|
||||
if (!di->ch[chan_id].toggle_cnt || exit_app) {
|
||||
fprintf(stdout,
|
||||
"<-- %s - PH_DEACTIVATE_%s\n",
|
||||
CHAN_NAMES[chan_id],
|
||||
(hh->prim == PH_DEACTIVATE_IND) ? "IND" : "CNF");
|
||||
}
|
||||
di->ch[chan_id].toggle_cnt++;
|
||||
di->ch[chan_id].activated = 0;
|
||||
done = 1;
|
||||
} else {
|
||||
if (debug)
|
||||
fprintf(stdout, "<-- %s - unhandled prim 0x%x\n",
|
||||
CHAN_NAMES[chan_id], hh->prim);
|
||||
}
|
||||
} else {
|
||||
if (debug)
|
||||
fprintf(stdout, "<-- B%i - unhandled prim 0x%x\n",
|
||||
bch + 1, hh->prim);
|
||||
fprintf(stdout, "chan fd not in set\n");
|
||||
return 0;
|
||||
}
|
||||
} else {
|
||||
fprintf(stdout, "bchan fd not in set\n");
|
||||
return 0;
|
||||
}
|
||||
return ret;
|
||||
} while (!done && (max_retry-- > 0));
|
||||
|
||||
return (done==1);
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -331,77 +372,27 @@ int activate_bchan(devinfo_t *di, unsigned char bch) {
|
|||
* returns 0 if PH_ACTIVATE_IND received within timeout interval
|
||||
*/
|
||||
int do_setup(devinfo_t *di) {
|
||||
int ret = 0;
|
||||
struct timeval tout;
|
||||
struct mISDNhead *hh;
|
||||
unsigned char buffer[2048];
|
||||
fd_set rds;
|
||||
socklen_t alen;
|
||||
|
||||
hh = (struct mISDNhead *) buffer;
|
||||
hh->prim = PH_ACTIVATE_REQ;
|
||||
hh->id = MISDN_ID_ANY;
|
||||
fprintf(stdout, "--> D - PH_ACTIVATE_REQ\n");
|
||||
ret = sendto(di->layerid[CHAN_D], buffer, MISDN_HEADER_LEN, 0, NULL, 0);
|
||||
|
||||
while (1) {
|
||||
tout.tv_usec = 0;
|
||||
tout.tv_sec = 1;
|
||||
FD_ZERO(&rds);
|
||||
FD_SET(di->layerid[CHAN_D], &rds);
|
||||
|
||||
ret = select(di->nds, &rds, NULL, NULL, &tout);
|
||||
if (debug > 3) {
|
||||
fprintf(stdout, "select ret=%d\n", ret);
|
||||
}
|
||||
if (ret < 0) {
|
||||
fprintf(stdout, "select error %s\n", strerror(errno));
|
||||
return 9;
|
||||
}
|
||||
if (ret == 0) {
|
||||
fprintf(stdout, "select timeeout\n");
|
||||
return 10;
|
||||
}
|
||||
|
||||
if (FD_ISSET(di->layerid[CHAN_D], &rds)) {
|
||||
alen = sizeof (di->laddr[CHAN_D]);
|
||||
ret = recvfrom(di->layerid[CHAN_D], buffer, 300, 0,
|
||||
(struct sockaddr *) &di->laddr[CHAN_D], &alen);
|
||||
if (ret < 0) {
|
||||
fprintf(stdout, "recvfrom error %s\n",
|
||||
strerror(errno));
|
||||
return 11;
|
||||
}
|
||||
if (debug > 3) {
|
||||
fprintf(stdout, "alen =%d, dev(%d) channel(%d)\n",
|
||||
alen, di->laddr[CHAN_D].dev, di->laddr[CHAN_D].channel);
|
||||
}
|
||||
if ((hh->prim == PH_ACTIVATE_IND) || (hh->prim == PH_ACTIVATE_CNF)) {
|
||||
if (hh->prim == PH_ACTIVATE_IND) {
|
||||
fprintf(stdout, "<-- D - PH_ACTIVATE_IND\n");
|
||||
} else {
|
||||
fprintf(stdout, "<-- D - PH_ACTIVATE_CNF\n");
|
||||
}
|
||||
di->ch[CHAN_D].activated = 1;
|
||||
|
||||
if ((di->ch[CHAN_B1].tx_ack) && (!setup_bchannel(di, CHAN_B1))) {
|
||||
activate_bchan(di, CHAN_B1);
|
||||
}
|
||||
|
||||
if ((di->ch[CHAN_B2].tx_ack) && (!setup_bchannel(di, CHAN_B2))) {
|
||||
activate_bchan(di, CHAN_B2);
|
||||
}
|
||||
if (!control_channel(di, CHAN_D, CHAN_ACTIVATE)) {
|
||||
fprintf(stdout, "error activateing D Channel\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (di->ch[CHAN_D].activated) {
|
||||
if ((di->ch[CHAN_B1].tx_ack) && (!setup_bchannel(di, CHAN_B1))) {
|
||||
if (!control_channel(di, CHAN_B1, CHAN_ACTIVATE)) {
|
||||
fprintf(stdout, "error activateing B1 Channel\n");
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
if ((di->ch[CHAN_B2].tx_ack) && (!setup_bchannel(di, CHAN_B2))) {
|
||||
if (!control_channel(di, CHAN_B2, CHAN_ACTIVATE)) {
|
||||
fprintf(stdout, "error activateing B2 Channel\n");
|
||||
return 0;
|
||||
} else {
|
||||
if (debug) {
|
||||
fprintf(stdout, "<-- D - unhandled prim 0x%x\n", hh->prim);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return 666;
|
||||
return (di->ch[CHAN_D].activated ? 0 : 1);
|
||||
}
|
||||
|
||||
int check_rx_data_hdlc(devinfo_t *di, int ch_idx, int ret, unsigned char *rx_buf) {
|
||||
|
@ -560,25 +551,26 @@ int main_data_loop(devinfo_t *di) {
|
|||
unsigned long rx_delta;
|
||||
unsigned int running_since = 0;
|
||||
|
||||
printf("\nwaiting for data (use CTRL-C to cancel) stop(%i) sleep(%i)...\n", stop, usleep_val);
|
||||
|
||||
t1 = get_tick_count();
|
||||
|
||||
tout.tv_usec = 0;
|
||||
tout.tv_sec = 1;
|
||||
tout.tv_usec = 4000;
|
||||
tout.tv_sec = 0;
|
||||
|
||||
printf("\nwaiting for data (use CTRL-C to cancel) stop(%i) sleep(%i)...\n", stop, usleep_val);
|
||||
while (1) {
|
||||
for (ch_idx = 0; ch_idx < MAX_CHAN; ch_idx++) {
|
||||
if (!di->ch[ch_idx].activated)
|
||||
if (!di->ch[ch_idx].activated) {
|
||||
if (di->ch[ch_idx].toggle) {
|
||||
if (control_channel(di, ch_idx, CHAN_ACTIVATE)) {
|
||||
di->ch[ch_idx].tx_ack = 1;
|
||||
}
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
/* write data */
|
||||
if (di->ch[ch_idx].tx_ack) {
|
||||
// start timer tick at first TX packet
|
||||
if (!di->ch[ch_idx].t_start) {
|
||||
di->ch[ch_idx].t_start = get_tick_count();
|
||||
di->ch[ch_idx].seq_num = di->ch[ch_idx].tx.pkt_cnt;
|
||||
}
|
||||
|
||||
l = build_tx_data(di, ch_idx, tx_buf + MISDN_HEADER_LEN);
|
||||
if (debug > 4) {
|
||||
printf("%s-TX size(%d) : ", CHAN_NAMES[ch_idx], l);
|
||||
|
@ -592,13 +584,16 @@ int main_data_loop(devinfo_t *di) {
|
|||
sizeof (di->laddr[ch_idx]));
|
||||
|
||||
di->ch[ch_idx].tx_ack--;
|
||||
if (!di->ch[ch_idx].t_start) {
|
||||
di->ch[ch_idx].t_start = get_tick_count();
|
||||
}
|
||||
}
|
||||
|
||||
/* read data */
|
||||
FD_ZERO(&rds);
|
||||
FD_SET(di->layerid[ch_idx], &rds);
|
||||
|
||||
ret = select(di->nds, &rds, NULL, NULL, &tout);
|
||||
ret = select(di->layerid[ch_idx] + 1, &rds, NULL, NULL, &tout);
|
||||
if (ret < 0) {
|
||||
fprintf(stdout, "select error %s\n", strerror(errno));
|
||||
}
|
||||
|
@ -646,8 +641,19 @@ int main_data_loop(devinfo_t *di) {
|
|||
if (rx_error) {
|
||||
di->ch[ch_idx].rx.err_pkt++;
|
||||
}
|
||||
|
||||
if (di->ch[ch_idx].toggle) {
|
||||
control_channel(di, ch_idx, CHAN_DEACTIVATE);
|
||||
}
|
||||
} else if (hhrx->prim == PH_DATA_CNF) {
|
||||
di->ch[ch_idx].tx_ack++;
|
||||
if (debug > 2) {
|
||||
fprintf(stdout, "<-- %s - PH_DATA_CNF (toggle:%i)\n",
|
||||
CHAN_NAMES[ch_idx], di->ch[ch_idx].toggle);
|
||||
}
|
||||
if (!di->ch[ch_idx].toggle) {
|
||||
// ready to send next TX package in next mainloop
|
||||
di->ch[ch_idx].tx_ack++;
|
||||
}
|
||||
} else {
|
||||
if (debug > 2) {
|
||||
fprintf(stdout, "<-- %s - unhandled prim 0x%x\n",
|
||||
|
@ -657,12 +663,9 @@ int main_data_loop(devinfo_t *di) {
|
|||
}
|
||||
}
|
||||
|
||||
/* relax cpu usage */
|
||||
usleep(usleep_val);
|
||||
|
||||
// print out data rate stats:
|
||||
t2 = get_tick_count();
|
||||
if ((t2 - t1) > (TICKS_PER_SEC / 1)) {
|
||||
if ((t2 - t1) > (TICKS_PER_SEC / 1) || exit_app) {
|
||||
t1 = t2;
|
||||
running_since++;
|
||||
|
||||
|
@ -670,16 +673,17 @@ int main_data_loop(devinfo_t *di) {
|
|||
rx_delta = (di->ch[ch_idx].rx.total - di->ch[ch_idx].rx.delta);
|
||||
printf("%s rate/s: %lu, rate-avg: %4.3f,"
|
||||
" rx total: %lu kb since %llu secs,"
|
||||
" pkt(rx/tx): %lu/%lu, rx-err:%lu,%i\n",
|
||||
" pkt(tx/rx): %lu/%lu, rx-err:%lu,%i DEACT/ACT(%d)\n",
|
||||
CHAN_NAMES[ch_idx], rx_delta,
|
||||
(double) ((double) ((unsigned long long) di->ch[ch_idx].rx.total * TICKS_PER_SEC)
|
||||
/ (double) (t2 - di->ch[ch_idx].t_start)),
|
||||
(di->ch[ch_idx].rx.total),
|
||||
di->ch[ch_idx].t_start ? ((t2 - di->ch[ch_idx].t_start) / TICKS_PER_SEC) : 0,
|
||||
di->ch[ch_idx].rx.pkt_cnt,
|
||||
di->ch[ch_idx].tx.pkt_cnt,
|
||||
di->ch[ch_idx].rx.pkt_cnt,
|
||||
di->ch[ch_idx].rx.err_pkt,
|
||||
di->ch[ch_idx].res_cnt);
|
||||
di->ch[ch_idx].res_cnt,
|
||||
di->ch[ch_idx].toggle_cnt);
|
||||
|
||||
/*
|
||||
* care for idle but 'active' channels, what happens
|
||||
|
@ -687,7 +691,7 @@ int main_data_loop(devinfo_t *di) {
|
|||
*/
|
||||
if ((di->ch[ch_idx].activated) && (!rx_delta)) {
|
||||
di->ch[ch_idx].idle_cnt++;
|
||||
if (di->ch[ch_idx].idle_cnt > 2) {
|
||||
if ((di->ch[ch_idx].idle_cnt > 2) && !di->ch[ch_idx].toggle) {
|
||||
// resurrect data pipe
|
||||
di->ch[ch_idx].seq_num++;
|
||||
di->ch[ch_idx].res_cnt++;
|
||||
|
@ -702,10 +706,24 @@ int main_data_loop(devinfo_t *di) {
|
|||
}
|
||||
printf("\n");
|
||||
|
||||
if ((stop) && (running_since >= stop)) {
|
||||
// closing all channels before exit
|
||||
if (exit_app || (stop && (running_since >= stop))) {
|
||||
for (ch_idx = 0; ch_idx < MAX_CHAN; ch_idx++) {
|
||||
if (di->ch[ch_idx].activated) {
|
||||
di->ch[ch_idx].activated = 0;
|
||||
control_channel(di, ch_idx, CHAN_DEACTIVATE);
|
||||
}
|
||||
|
||||
if (mISDN.layerid[ch_idx] > 0) {
|
||||
fprintf(stdout, "closing socket '%s'\n", CHAN_NAMES[ch_idx]);
|
||||
close(mISDN.layerid[ch_idx]);
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
usleep(usleep_val);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -764,7 +782,6 @@ connect_layer1_d(devinfo_t *di) {
|
|||
return 5;
|
||||
}
|
||||
|
||||
di->nds = di->layerid[CHAN_D] + 1;
|
||||
ret = fcntl(di->layerid[CHAN_D], F_SETFL, O_NONBLOCK);
|
||||
if (ret < 0) {
|
||||
fprintf(stdout, "fcntl error %s\n", strerror(errno));
|
||||
|
@ -774,7 +791,9 @@ connect_layer1_d(devinfo_t *di) {
|
|||
di->laddr[CHAN_D].family = AF_ISDN;
|
||||
di->laddr[CHAN_D].dev = di->cardnr;
|
||||
di->laddr[CHAN_D].channel = 0;
|
||||
|
||||
ret = bind(di->layerid[CHAN_D], (struct sockaddr *) &di->laddr[CHAN_D], sizeof (di->laddr[CHAN_D]));
|
||||
sleep(1);
|
||||
|
||||
if (ret < 0) {
|
||||
fprintf(stdout, "could not bind l1 socket %s\n", strerror(errno));
|
||||
|
@ -892,6 +911,11 @@ int main(int argc, char *argv[]) {
|
|||
// init Data burst values
|
||||
for (ch_idx = 0; ch_idx < MAX_CHAN; ch_idx++) {
|
||||
if (mISDN.channel_mask & (1 << ch_idx)) {
|
||||
if (mISDN.ch[ch_idx].tx_size < 0) {
|
||||
mISDN.ch[ch_idx].toggle = 1;
|
||||
mISDN.ch[ch_idx].tx_size *= -1;
|
||||
}
|
||||
|
||||
if (!mISDN.ch[ch_idx].tx_size) {
|
||||
mISDN.ch[ch_idx].tx_size = CHAN_DFLT_PKT_SZ[ch_idx];
|
||||
}
|
||||
|
@ -902,20 +926,13 @@ int main(int argc, char *argv[]) {
|
|||
|
||||
mISDN.ch[ch_idx].hdlc = (!(((ch_idx == CHAN_B1) || (ch_idx == CHAN_B2)) && btrans));
|
||||
mISDN.ch[ch_idx].tx_ack = 1;
|
||||
mISDN.ch[ch_idx].seq_num = 0;
|
||||
|
||||
fprintf(stdout, "chan %s stream enabled with packet sz %d bytes\n",
|
||||
CHAN_NAMES[ch_idx], di->ch[ch_idx].tx_size);
|
||||
}
|
||||
}
|
||||
|
||||
err = socket(PF_ISDN, SOCK_RAW, ISDN_P_BASE);
|
||||
if (err < 0) {
|
||||
fprintf(stderr, "cannot open mISDN due to %s\n",
|
||||
strerror(errno));
|
||||
return 1;
|
||||
}
|
||||
close(err);
|
||||
|
||||
err = connect_layer1_d(&mISDN);
|
||||
if (err) {
|
||||
fprintf(stdout, "error(%d) connecting layer1\n", err);
|
||||
|
@ -929,8 +946,8 @@ int main(int argc, char *argv[]) {
|
|||
set_signals();
|
||||
err = do_setup(&mISDN);
|
||||
if (err) {
|
||||
fprintf(stdout, "do_setup error %d\n", err);
|
||||
return (0);
|
||||
fprintf(stdout, "do_setup error %d\n", err); return
|
||||
(0);
|
||||
}
|
||||
if (mISDN.channel_mask) {
|
||||
main_data_loop(&mISDN);
|
||||
|
|
|
@ -43,8 +43,7 @@
|
|||
#include <mISDN/mISDNif.h>
|
||||
#include <mISDN/mlayer3.h>
|
||||
|
||||
void usage(pname)
|
||||
char *pname;
|
||||
void usage(char *pname)
|
||||
{
|
||||
fprintf(stderr,"Call with %s [options] [filename]\n", pname);
|
||||
fprintf(stderr,"\n");
|
||||
|
@ -1203,6 +1202,7 @@ static int do_control_worker(devinfo_t *di)
|
|||
break;
|
||||
#endif
|
||||
}
|
||||
break;
|
||||
case MT_CONNECT_ACKNOWLEDGE:
|
||||
mylog(3, "got %s\n", mi_msg_type2str(cmd));
|
||||
/* We got connect ack, so bring B-channel up */
|
||||
|
@ -1292,7 +1292,11 @@ static int bch_worker(devinfo_t *di)
|
|||
case PH_DATA_IND:
|
||||
case DL_DATA_IND:
|
||||
/* received data, save it */
|
||||
write(di->save, buf + MISDN_HEADER_LEN, len - MISDN_HEADER_LEN);
|
||||
ret = write(di->save, buf + MISDN_HEADER_LEN, len - MISDN_HEADER_LEN);
|
||||
if (ret < 0)
|
||||
fprintf(stderr,"got error on write %s\n", strerror(errno));
|
||||
else
|
||||
ret = 0;
|
||||
break;
|
||||
case PH_DATA_CNF:
|
||||
/* get ACK of send data, so we can
|
||||
|
@ -1556,9 +1560,7 @@ static struct mi_ext_fn_s myfn = {
|
|||
.prt_debug = my_lib_debug,
|
||||
};
|
||||
|
||||
int main(argc,argv)
|
||||
int argc;
|
||||
char *argv[];
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
char FileNameIn[200],FileNameOut[200];
|
||||
devinfo_t DevInfo;
|
||||
|
|
|
@ -152,6 +152,10 @@
|
|||
/* Version number of package */
|
||||
#undef VERSION
|
||||
|
||||
/* Define to 1 if `lex' declares `yytext' as a `char *' by default, not a
|
||||
`char[]'. */
|
||||
#undef YYTEXT_POINTER
|
||||
|
||||
/* Define to `__inline__' or `__inline' if that's what the C compiler
|
||||
calls it, or to nothing if 'inline' is not supported under any name. */
|
||||
#ifndef __cplusplus
|
||||
|
|
|
@ -137,38 +137,41 @@
|
|||
/*
|
||||
* Cause values
|
||||
*/
|
||||
#define CAUSE_UNASSIGNED_NUMBER 1
|
||||
#define CAUSE_NO_TRANSIT_ROUTE 2
|
||||
#define CAUSE_NO_ROUTE 3
|
||||
#define CAUSE_CHANNEL_UNACCEPT 6
|
||||
#define CAUSE_NORMAL_CLEARING 16
|
||||
#define CAUSE_USER_BUSY 17
|
||||
#define CAUSE_NOUSER_RESPONDING 18
|
||||
#define CAUSE_ALERTED_NO_ANSWER 19
|
||||
#define CAUSE_CALL_REJECTED 21
|
||||
#define CAUSE_NONSELECTED_USER 26
|
||||
#define CAUSE_DEST_OUT_OF_ORDER 27
|
||||
#define CAUSE_INVALID_NUMBER 28
|
||||
#define CAUSE_FACILITY_REJECTED 29
|
||||
#define CAUSE_STATUS_RESPONSE 30
|
||||
#define CAUSE_NORMALUNSPECIFIED 31
|
||||
#define CAUSE_NO_CHANNEL 34
|
||||
#define CAUSE_NET_OUT_OF_ORDER 28
|
||||
#define CAUSE_TEMPORARY_FAILURE 41
|
||||
#define CAUSE_SEQ_CONGESTION 42
|
||||
#define CAUSE_REQUESTED_CHANNEL 44
|
||||
#define CAUSE_RESOURCES_UNAVAIL 47
|
||||
#define CAUSE_INVALID_CALLREF 81
|
||||
#define CAUSE_INCOMPATIBLE_DEST 88
|
||||
#define CAUSE_MANDATORY_IE_MISS 96
|
||||
#define CAUSE_MT_NOTIMPLEMENTED 97
|
||||
#define CAUSE_IE_NOTIMPLEMENTED 99
|
||||
#define CAUSE_INVALID_CONTENTS 100
|
||||
#define CAUSE_NOTCOMPAT_STATE 101
|
||||
#define CAUSE_TIMER_EXPIRED 102
|
||||
#define CAUSE_PROTOCOL_ERROR 111
|
||||
#define CAUSE_UNASSIGNED_NUMBER 1
|
||||
#define CAUSE_NO_TRANSIT_ROUTE 2
|
||||
#define CAUSE_NO_ROUTE 3
|
||||
#define CAUSE_CHANNEL_UNACCEPT 6
|
||||
#define CAUSE_NORMAL_CLEARING 16
|
||||
#define CAUSE_USER_BUSY 17
|
||||
#define CAUSE_NOUSER_RESPONDING 18
|
||||
#define CAUSE_ALERTED_NO_ANSWER 19
|
||||
#define CAUSE_CALL_REJECTED 21
|
||||
#define CAUSE_NONSELECTED_USER 26
|
||||
#define CAUSE_DEST_OUT_OF_ORDER 27
|
||||
#define CAUSE_INVALID_NUMBER 28
|
||||
#define CAUSE_FACILITY_REJECTED 29
|
||||
#define CAUSE_STATUS_RESPONSE 30
|
||||
#define CAUSE_NORMALUNSPECIFIED 31
|
||||
#define CAUSE_NO_CHANNEL 34
|
||||
#define CAUSE_NET_OUT_OF_ORDER 28
|
||||
#define CAUSE_TEMPORARY_FAILURE 41
|
||||
#define CAUSE_SEQ_CONGESTION 42
|
||||
#define CAUSE_REQUESTED_CHANNEL 44
|
||||
#define CAUSE_RESOURCES_UNAVAIL 47
|
||||
#define CAUSE_FACILITY_NOTSUBSCRIBED 50
|
||||
#define CAUSE_FACILITY_NOTIMPLEMENTED 69
|
||||
#define CAUSE_INVALID_CALLREF 81
|
||||
#define CAUSE_INCOMPATIBLE_DEST 88
|
||||
#define CAUSE_MANDATORY_IE_MISS 96
|
||||
#define CAUSE_MT_NOTIMPLEMENTED 97
|
||||
#define CAUSE_NOTCOMPAT_STATE_OR_MT_NOTIMPLEMENTED 98
|
||||
#define CAUSE_IE_NOTIMPLEMENTED 99
|
||||
#define CAUSE_INVALID_CONTENTS 100
|
||||
#define CAUSE_NOTCOMPAT_STATE 101
|
||||
#define CAUSE_TIMER_EXPIRED 102
|
||||
#define CAUSE_PROTOCOL_ERROR 111
|
||||
|
||||
#define NO_CAUSE 254
|
||||
#define NO_CAUSE 254
|
||||
|
||||
/*
|
||||
* Restart indication class values
|
||||
|
@ -327,11 +330,17 @@ extern int mi_encode_progress(struct l3_msg *, struct misdn_progress_info *);
|
|||
extern int mi_encode_date(struct l3_msg *, struct tm *);
|
||||
extern int mi_encode_restart_ind(struct l3_msg *, unsigned char);
|
||||
extern int mi_encode_facility(struct l3_msg *, struct asn1_parm *);
|
||||
extern int mi_encode_notification_ind(struct l3_msg *, int);
|
||||
|
||||
/* Common IE decode helpers */
|
||||
struct mbuffer;
|
||||
extern int parseQ931(struct mbuffer *);
|
||||
extern int l3_ie2pos(u_char);
|
||||
extern unsigned char l3_pos2ie(int);
|
||||
|
||||
extern int mi_decode_progress(struct l3_msg *, struct misdn_progress_info *);
|
||||
extern int mi_decode_bearer_capability(struct l3_msg *, int *, int *, int *, int *, int *,
|
||||
int *, int *, int *, int *, int *, int *, int *, int *, int *);
|
||||
int *, int *, int *, int *, int *, int *, int *, int *);
|
||||
extern int mi_decode_hlc(struct l3_msg *l3m, int *, int *);
|
||||
extern int mi_decode_cause(struct l3_msg *, int *, int *, int *, int *, int *, unsigned char *);
|
||||
extern int mi_decode_channel_id(struct l3_msg *, struct misdn_channel_info *);
|
||||
|
@ -345,6 +354,7 @@ extern int mi_decode_useruser(struct l3_msg *, int *, int *, char *, int);
|
|||
extern int mi_decode_date(struct l3_msg *, struct tm *);
|
||||
extern int mi_decode_restart_ind(struct l3_msg *, unsigned char *);
|
||||
extern int mi_decode_facility(struct l3_msg *, struct asn1_parm *);
|
||||
extern int mi_decode_notification_ind(struct l3_msg *, int*);
|
||||
|
||||
/* some print helpers */
|
||||
extern const char *mi_bearer2str(int);
|
||||
|
|
|
@ -21,6 +21,6 @@ lib_LTLIBRARIES = libmisdn.la
|
|||
libmisdn_la_SOURCES = $(MISC_SRC) $(LAYER3_SRC) $(INCLUDE_SRC) $(ASN1_SRC) $(SUPPSERV_SRC)
|
||||
libmisdn_la_LDFLAGS = -version-info 1:0:0
|
||||
|
||||
AM_CPPFLAGS = -I$(top_srcdir)/include -Wall -Werror -I$(srcdir)/include $(_MEMLEAKDEBUG)
|
||||
AM_CPPFLAGS = -I$(top_srcdir)/include -Wall -Werror -Wno-error=array-bounds -I$(srcdir)/include $(_MEMLEAKDEBUG)
|
||||
|
||||
CLEANFILES = *~ */*~
|
||||
|
|
|
@ -57,7 +57,7 @@ extern int mi_printf(const char *file, int line, const char *func, int lev, cons
|
|||
|
||||
#define dhexprint(m, h, d, l) do { if (m & mI_debug_mask) mi_dhexprint(__FILE__, __LINE__, __PRETTY_FUNCTION__, h, d, l);} while(0)
|
||||
|
||||
extern void mi_dhexprint(const char *file, int line, const char *func, char *head, unsigned char *buf, int len);
|
||||
extern void mi_dhexprint(const char *file, int line, const char *func, const char *head, unsigned char *buf, int len);
|
||||
extern void mi_shexprint(char *dest, unsigned char *buf, int len);
|
||||
|
||||
#ifdef MEMLEAK_DEBUG
|
||||
|
|
|
@ -28,7 +28,7 @@ typedef void (* FSMFNPTR)(struct FsmInst *, int, void *);
|
|||
struct Fsm {
|
||||
FSMFNPTR *jumpmatrix;
|
||||
int state_count, event_count;
|
||||
char **strEvent, **strState;
|
||||
const char **strEvent, **strState;
|
||||
};
|
||||
|
||||
struct FsmInst {
|
||||
|
@ -38,7 +38,7 @@ struct FsmInst {
|
|||
int debug;
|
||||
void *userdata;
|
||||
int userint;
|
||||
void (*printdebug)(struct FsmInst *, char *, ...);
|
||||
void (*printdebug)(struct FsmInst *, const char *, ...);
|
||||
};
|
||||
|
||||
struct FsmNode {
|
||||
|
|
|
@ -30,7 +30,7 @@ typedef struct _l3_process l3_process_t;
|
|||
struct _layer3;
|
||||
|
||||
struct l3protocol {
|
||||
char *name;
|
||||
const char *name;
|
||||
unsigned int protocol;
|
||||
void (*init)(struct _layer3 *);
|
||||
};
|
||||
|
@ -117,8 +117,8 @@ extern l3_process_t *create_new_process(layer3_t *, unsigned int, unsigned int,
|
|||
extern void release_l3_process(struct _l3_process *);
|
||||
extern void SendMsg(struct _l3_process *, struct l3_msg *, int);
|
||||
extern void mISDN_l3up(l3_process_t *, unsigned int, struct l3_msg *);
|
||||
extern void mIl3_debug(layer3_t *, char *, ...);
|
||||
extern void mIpc_debug(u_int, struct _l3_process *, char *, ...);
|
||||
extern void mIl3_debug(layer3_t *, const char *, ...);
|
||||
extern void mIpc_debug(u_int, struct _l3_process *, const char *, ...);
|
||||
|
||||
static inline void
|
||||
newl3state(l3_process_t *pc, int state)
|
||||
|
@ -149,10 +149,7 @@ extern void L3AddTimer(struct L3Timer *, int, unsigned int);
|
|||
extern void L3DelTimer(struct L3Timer *);
|
||||
extern void l3_manager(struct l2l3if *, unsigned int);
|
||||
|
||||
extern int parseQ931(struct mbuffer *);
|
||||
extern int assembleQ931(struct _l3_process *, struct l3_msg *);
|
||||
extern int l3_ie2pos(u_char);
|
||||
extern unsigned char l3_pos2ie(int);
|
||||
|
||||
#define SBIT(state) (1 << state)
|
||||
#define ALL_STATES 0xffffffff
|
||||
|
|
|
@ -1042,7 +1042,7 @@ l3dss1_release_cmpl_req(l3_process_t *pc, unsigned int pr, struct l3_msg *l3m)
|
|||
}
|
||||
|
||||
static void
|
||||
send_timeout(l3_process_t *pc, char *nr)
|
||||
send_timeout(l3_process_t *pc, const char *nr)
|
||||
{
|
||||
struct l3_msg *l3m;
|
||||
unsigned char c[5];
|
||||
|
|
|
@ -1691,7 +1691,7 @@ l3dss1_tretrieve(l3_process_t *pc, unsigned int pr, struct l3_msg *l3m)
|
|||
}
|
||||
|
||||
static void
|
||||
send_timeout(l3_process_t *pc, char *nr)
|
||||
send_timeout(l3_process_t *pc, const char *nr)
|
||||
{
|
||||
struct l3_msg *l3m;
|
||||
unsigned char c[5];
|
||||
|
|
|
@ -30,7 +30,7 @@
|
|||
#include "debug.h"
|
||||
|
||||
void
|
||||
mIl3_debug(layer3_t *l3, char *fmt, ...)
|
||||
mIl3_debug(layer3_t *l3, const char *fmt, ...)
|
||||
{
|
||||
va_list args;
|
||||
char buf[256], *p;
|
||||
|
@ -44,7 +44,7 @@ mIl3_debug(layer3_t *l3, char *fmt, ...)
|
|||
}
|
||||
|
||||
void
|
||||
mIpc_debug(u_int dmask, l3_process_t *pc, char *fmt, ...)
|
||||
mIpc_debug(u_int dmask, l3_process_t *pc, const char *fmt, ...)
|
||||
{
|
||||
struct _layer3 *l3;
|
||||
va_list args;
|
||||
|
@ -66,7 +66,7 @@ mIpc_debug(u_int dmask, l3_process_t *pc, char *fmt, ...)
|
|||
}
|
||||
|
||||
static void
|
||||
l3fi_debug(struct FsmInst *fi, char *fmt, ...)
|
||||
l3fi_debug(struct FsmInst *fi, const char *fmt, ...)
|
||||
{
|
||||
struct l2l3if *l2i = fi->userdata;
|
||||
layer3_t *l3 = l2i->l3;
|
||||
|
@ -95,7 +95,7 @@ enum {
|
|||
|
||||
#define L3_STATE_COUNT (ST_L3_LC_ESTAB + 1)
|
||||
|
||||
static char *strL3State[] =
|
||||
static const char *strL3State[] =
|
||||
{
|
||||
"ST_L3_LC_REL",
|
||||
"ST_L3_LC_ESTAB_WAIT",
|
||||
|
@ -116,7 +116,7 @@ enum {
|
|||
|
||||
#define L3_EVENT_COUNT (EV_TIMEOUT+1)
|
||||
|
||||
static char *strL3Event[] =
|
||||
static const char *strL3Event[] =
|
||||
{
|
||||
"EV_ESTABLISH_REQ",
|
||||
"EV_ESTABLISH_IND",
|
||||
|
|
|
@ -57,7 +57,7 @@ cleanup_layer3(void)
|
|||
__init_done = 0;
|
||||
}
|
||||
|
||||
/* for now, maybe get this via some register prortocol in future */
|
||||
/* for now, maybe get this via some register protocol in future */
|
||||
extern struct l3protocol dss1user;
|
||||
extern struct l3protocol dss1net;
|
||||
/*
|
||||
|
@ -107,11 +107,14 @@ open_layer3(unsigned int dev, unsigned int proto, unsigned int prop, mlayer3_cb_
|
|||
/* handle version backward compatibility specific stuff here */
|
||||
|
||||
l3 = calloc(1, sizeof(struct _layer3));
|
||||
if (!l3)
|
||||
if (!l3) {
|
||||
close(fd);
|
||||
return NULL;
|
||||
}
|
||||
l3->ml3.devinfo = calloc(1, sizeof(*l3->ml3.devinfo));
|
||||
if (!l3->ml3.devinfo) {
|
||||
free(l3);
|
||||
close(fd);
|
||||
return NULL;
|
||||
}
|
||||
l3->ml3.options = prop;
|
||||
|
@ -134,7 +137,7 @@ open_layer3(unsigned int dev, unsigned int proto, unsigned int prop, mlayer3_cb_
|
|||
case L3_PROTOCOL_DSS1_USER:
|
||||
if (!(l3->ml3.devinfo->Dprotocols & (1 << ISDN_P_TE_S0))
|
||||
&& !(l3->ml3.devinfo->Dprotocols & (1 << ISDN_P_TE_E1))) {
|
||||
eprint("protocol L3_PROTOCOL_DSS1_USER device do not support ISDN_P_TE_S0 / ISDN_P_TE_E1\n");
|
||||
eprint("protocol L3_PROTOCOL_DSS1_USER device doesn't support ISDN_P_TE_S0 / ISDN_P_TE_E1\n");
|
||||
goto fail;
|
||||
}
|
||||
fd = socket(PF_ISDN, SOCK_DGRAM, ISDN_P_LAPD_TE);
|
||||
|
@ -147,7 +150,7 @@ open_layer3(unsigned int dev, unsigned int proto, unsigned int prop, mlayer3_cb_
|
|||
case L3_PROTOCOL_DSS1_NET:
|
||||
if (!(l3->ml3.devinfo->Dprotocols & (1 << ISDN_P_NT_S0))
|
||||
&& !(l3->ml3.devinfo->Dprotocols & (1 << ISDN_P_NT_E1))) {
|
||||
eprint("protocol L3_PROTOCOL_DSS1_NET device do not support ISDN_P_NT_S0 / ISDN_P_NT_E1\n");
|
||||
eprint("protocol L3_PROTOCOL_DSS1_NET device doesn't support ISDN_P_NT_S0 / ISDN_P_NT_E1\n");
|
||||
goto fail;
|
||||
}
|
||||
fd = socket(PF_ISDN, SOCK_DGRAM, ISDN_P_LAPD_NT);
|
||||
|
|
|
@ -357,7 +357,7 @@ mi_encode_hlc(struct l3_msg *l3m, int hlc, int ehlc)
|
|||
ie[1] = hlc & 0x7f;
|
||||
|
||||
if (ehlc < 0)
|
||||
ie[1] | 0x80;
|
||||
ie[1] |= 0x80;
|
||||
else {
|
||||
l = 3;
|
||||
ie[2] = 0x80 | (ehlc & 0x7f);
|
||||
|
@ -506,7 +506,7 @@ mi_encode_called_nr(struct l3_msg *l3m, char *nr, unsigned int type, unsigned in
|
|||
int
|
||||
mi_encode_redirecting_nr(struct l3_msg *l3m, char *nr, int pres, unsigned int type, unsigned int plan, int reason)
|
||||
{
|
||||
unsigned char ie[24];
|
||||
unsigned char ie[32];
|
||||
int l;
|
||||
|
||||
if (nr == NULL || *nr == 0) /* not provided */
|
||||
|
@ -537,7 +537,7 @@ mi_encode_redirecting_nr(struct l3_msg *l3m, char *nr, int pres, unsigned int ty
|
|||
int
|
||||
mi_encode_redirection_nr(struct l3_msg *l3m, char *nr, int pres, unsigned int type, unsigned int plan)
|
||||
{
|
||||
unsigned char ie[24];
|
||||
unsigned char ie[32];
|
||||
int l;
|
||||
|
||||
if (nr == NULL || *nr == 0) /* not provided */
|
||||
|
@ -678,6 +678,15 @@ mi_encode_facility(struct l3_msg *l3m, struct asn1_parm *fac)
|
|||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
mi_encode_notification_ind(struct l3_msg *l3m, int notInd)
|
||||
{
|
||||
notInd |= 0x80;
|
||||
|
||||
return add_layer3_ie(l3m, IE_NOTIFY, 1, (unsigned char*) ¬Ind);
|
||||
|
||||
}
|
||||
|
||||
/* helper functions to decode common IE */
|
||||
|
||||
#define _ASSIGN_PVAL(p, v) if (p) *p = (v)
|
||||
|
@ -702,22 +711,21 @@ mi_decode_progress(struct l3_msg *l3m, struct misdn_progress_info *progress)
|
|||
|
||||
int
|
||||
mi_decode_bearer_capability(struct l3_msg *l3m, int *coding, int *capability, int *mode, int *rate,
|
||||
int *oct_4a, int *oct_4b, int *oct_5, int *oct_5a, int *oct_5b1,
|
||||
int *oct_5b2, int *oct_5c, int *oct_5d, int *oct_6, int *oct_7)
|
||||
int *oct_4a, int *oct_4b, int *oct_5, int *oct_5a, int *oct_5b,
|
||||
int *oct_5c, int *oct_5d, int *oct_6, int *oct_7)
|
||||
{
|
||||
int opt[10];
|
||||
int opt[9];
|
||||
int i,j;
|
||||
enum {
|
||||
octet_4a = 0,
|
||||
octet_4b = 1,
|
||||
octet_5 = 2,
|
||||
octet_5a = 3,
|
||||
octet_5b1 = 4,
|
||||
octet_5b2 = 5,
|
||||
octet_5c = 6,
|
||||
octet_5d = 7,
|
||||
octet_6 = 8,
|
||||
octet_7 = 9
|
||||
octet_5b = 4,
|
||||
octet_5c = 5,
|
||||
octet_5d = 6,
|
||||
octet_6 = 7,
|
||||
octet_7 = 8
|
||||
};
|
||||
|
||||
if (!l3m->bearer_capability || *l3m->bearer_capability < 2)
|
||||
|
@ -728,7 +736,7 @@ mi_decode_bearer_capability(struct l3_msg *l3m, int *coding, int *capability, in
|
|||
_ASSIGN_PVAL(rate, l3m->bearer_capability[2] & 0x1f);
|
||||
|
||||
/* Now the optional octets */
|
||||
for (j = 0; j < 10; j++)
|
||||
for (j = 0; j < 9; j++)
|
||||
opt[j] = -1;
|
||||
i = 2;
|
||||
if (*l3m->bearer_capability <= i)
|
||||
|
@ -772,8 +780,7 @@ done:
|
|||
_ASSIGN_PVAL(oct_4b, opt[octet_4b]);
|
||||
_ASSIGN_PVAL(oct_5, opt[octet_5]);
|
||||
_ASSIGN_PVAL(oct_5a, opt[octet_5a]);
|
||||
_ASSIGN_PVAL(oct_5b1, opt[octet_5b1]);
|
||||
_ASSIGN_PVAL(oct_5b2, opt[octet_5b2]);
|
||||
_ASSIGN_PVAL(oct_5b, opt[octet_5b]);
|
||||
_ASSIGN_PVAL(oct_5c, opt[octet_5c]);
|
||||
_ASSIGN_PVAL(oct_5d, opt[octet_5d]);
|
||||
_ASSIGN_PVAL(oct_6, opt[octet_6]);
|
||||
|
@ -1123,10 +1130,21 @@ mi_decode_facility(struct l3_msg *l3m, struct asn1_parm *fac)
|
|||
return decodeFac(l3m->facility, fac);
|
||||
}
|
||||
|
||||
int
|
||||
mi_decode_notification_ind(struct l3_msg *l3m, int *notInd)
|
||||
{
|
||||
if (l3m == NULL || !l3m->notify)
|
||||
return 0;
|
||||
if (!notInd)
|
||||
return 0;
|
||||
_ASSIGN_PVAL(notInd, l3m->notify[1] & 0x7f);
|
||||
return 0;
|
||||
}
|
||||
|
||||
const char *
|
||||
mi_bearer2str(int cap)
|
||||
{
|
||||
static char *bearers[] = {
|
||||
static const char *bearers[] = {
|
||||
"Speech",
|
||||
"Audio 3.1 kHz",
|
||||
"Audio 7 kHz",
|
||||
|
|
|
@ -117,7 +117,7 @@ _mi_thread_create(pthread_t *thread, pthread_attr_t *attr, void *(*start_routine
|
|||
}
|
||||
|
||||
void
|
||||
mi_dhexprint(const char *file, int line, const char *func, char *head, unsigned char *buf, int len)
|
||||
mi_dhexprint(const char *file, int line, const char *func, const char *head, unsigned char *buf, int len)
|
||||
{
|
||||
int i;
|
||||
char *p,*obuf;
|
||||
|
|
|
@ -421,7 +421,7 @@ int ParseReturnErrorComponent(struct asn1_parm *pc, u_char * p, u_char * end, in
|
|||
{
|
||||
int invokeId;
|
||||
unsigned int errorValue;
|
||||
char *error;
|
||||
const char *error;
|
||||
char msg[20];
|
||||
INIT;
|
||||
|
||||
|
|
|
@ -784,7 +784,7 @@ int ParseDeactivationStatusNotificationDiv(struct asn1_parm *pc, u_char * p, u_c
|
|||
* \retval length on success.
|
||||
* \retval -1 on error.
|
||||
*/
|
||||
int encodeFacInterrogationDiversion(__u8 * Dest, const const struct asn1_parm *pc, const struct FacInterrogationDiversion *InterrogationDiversion)
|
||||
int encodeFacInterrogationDiversion(__u8 * Dest, const struct asn1_parm *pc, const struct FacInterrogationDiversion *InterrogationDiversion)
|
||||
{
|
||||
int Length;
|
||||
__u8 *p;
|
||||
|
@ -893,7 +893,7 @@ int ParseInterrogationDiversion_RES(struct asn1_parm *pc, u_char * p, u_char * e
|
|||
* \retval length on success.
|
||||
* \retval -1 on error.
|
||||
*/
|
||||
int encodeFacDiversionInformation(__u8 * Dest, const const struct asn1_parm *pc, const struct FacDiversionInformation *DiversionInformation)
|
||||
int encodeFacDiversionInformation(__u8 * Dest, const struct asn1_parm *pc, const struct FacDiversionInformation *DiversionInformation)
|
||||
{
|
||||
int Length;
|
||||
__u8 *p;
|
||||
|
@ -1052,7 +1052,7 @@ int ParseDiversionInformation(struct asn1_parm *pc, u_char * p, u_char * end,
|
|||
* \retval length on success.
|
||||
* \retval -1 on error.
|
||||
*/
|
||||
int encodeFacCallDeflection(__u8 * Dest, const const struct asn1_parm *pc, const struct FacCallDeflection *CallDeflection)
|
||||
int encodeFacCallDeflection(__u8 * Dest, const struct asn1_parm *pc, const struct FacCallDeflection *CallDeflection)
|
||||
{
|
||||
int Length;
|
||||
__u8 *p;
|
||||
|
@ -1142,7 +1142,7 @@ int ParseCallDeflection(struct asn1_parm *pc, u_char * p, u_char * end, struct F
|
|||
* \retval length on success.
|
||||
* \retval -1 on error.
|
||||
*/
|
||||
int encodeFacCallRerouteing(__u8 * Dest, const const struct asn1_parm *pc, const struct FacCallRerouteing *CallRerouteing)
|
||||
int encodeFacCallRerouteing(__u8 * Dest, const struct asn1_parm *pc, const struct FacCallRerouteing *CallRerouteing)
|
||||
{
|
||||
int Length;
|
||||
__u8 *p;
|
||||
|
@ -1284,7 +1284,7 @@ int ParseCallRerouteing(struct asn1_parm *pc, u_char * p, u_char * end, struct F
|
|||
* \retval length on success.
|
||||
* \retval -1 on error.
|
||||
*/
|
||||
int encodeFacInterrogateServedUserNumbers(__u8 * Dest, const const struct asn1_parm *pc, const struct FacServedUserNumberList *InterrogateServedUserNumbers)
|
||||
int encodeFacInterrogateServedUserNumbers(__u8 * Dest, const struct asn1_parm *pc, const struct FacServedUserNumberList *InterrogateServedUserNumbers)
|
||||
{
|
||||
int Length;
|
||||
__u8 *p;
|
||||
|
@ -1353,7 +1353,7 @@ int ParseInterrogateServedUserNumbers_RES(struct asn1_parm *pc, u_char * p, u_ch
|
|||
* \retval length on success.
|
||||
* \retval -1 on error.
|
||||
*/
|
||||
int encodeFacDivertingLegInformation1(__u8 * Dest, const const struct asn1_parm *pc, const struct FacDivertingLegInformation1 *DivertingLegInformation1)
|
||||
int encodeFacDivertingLegInformation1(__u8 * Dest, const struct asn1_parm *pc, const struct FacDivertingLegInformation1 *DivertingLegInformation1)
|
||||
{
|
||||
int Length;
|
||||
__u8 *p;
|
||||
|
@ -1422,7 +1422,7 @@ int ParseDivertingLegInformation1(struct asn1_parm *pc, u_char * p, u_char * end
|
|||
* \retval length on success.
|
||||
* \retval -1 on error.
|
||||
*/
|
||||
int encodeFacDivertingLegInformation2(__u8 * Dest, const const struct asn1_parm *pc, const struct FacDivertingLegInformation2 *DivertingLegInformation2)
|
||||
int encodeFacDivertingLegInformation2(__u8 * Dest, const struct asn1_parm *pc, const struct FacDivertingLegInformation2 *DivertingLegInformation2)
|
||||
{
|
||||
int Length;
|
||||
__u8 *p;
|
||||
|
@ -1524,7 +1524,7 @@ int ParseDivertingLegInformation2(struct asn1_parm *pc, u_char * p, u_char * end
|
|||
* \retval length on success.
|
||||
* \retval -1 on error.
|
||||
*/
|
||||
int encodeFacDivertingLegInformation3(__u8 * Dest, const const struct asn1_parm *pc, const struct FacDivertingLegInformation3 *DivertingLegInformation3)
|
||||
int encodeFacDivertingLegInformation3(__u8 * Dest, const struct asn1_parm *pc, const struct FacDivertingLegInformation3 *DivertingLegInformation3)
|
||||
{
|
||||
int Length;
|
||||
__u8 *p;
|
||||
|
|
|
@ -2,4 +2,7 @@
|
|||
/misdn_info
|
||||
/misdn_log
|
||||
/misdn_rename
|
||||
/misdn_E1test
|
||||
/misdn_E1test
|
||||
/isdn_text2wireshark
|
||||
/logger_config_parser.c
|
||||
/misdnlogger
|
||||
|
|
334
tools/E1test.c
334
tools/E1test.c
|
@ -1,5 +1,6 @@
|
|||
/*
|
||||
*
|
||||
* Copyright 2015 Karsten Keil <keil@b1-systems.de>
|
||||
* Copyright 2011 Karsten Keil <kkeil@linux-pingi.de>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
|
@ -42,7 +43,6 @@
|
|||
#include <mISDN/mISDNif.h>
|
||||
#include <mISDN/af_isdn.h>
|
||||
|
||||
|
||||
/* We do not have the all the ioctl controls mainstream yet so define it here.
|
||||
* It should still work then with the old standalone driver
|
||||
*/
|
||||
|
@ -55,7 +55,6 @@
|
|||
#define MISDN_CTRL_L1_GET_SYNC_INFO 0x00010004
|
||||
#endif
|
||||
|
||||
|
||||
#define FRAME_SIZE 32
|
||||
#define SMFR_SIZE (8 * FRAME_SIZE)
|
||||
#define MFR_SIZE (2 * SMFR_SIZE)
|
||||
|
@ -63,7 +62,6 @@
|
|||
#define DATA_SIZE_1MS (8 * 32)
|
||||
#define DATA_SIZE_1S (8000 * 32)
|
||||
|
||||
|
||||
#define MFR_SYNC_VALUE 0x2c
|
||||
#define MFR_SYNC_MASK 0xfc
|
||||
#define MFR_SYNC_BIT 0x01
|
||||
|
@ -103,18 +101,18 @@ enum FrameTypes {
|
|||
|
||||
struct fr_cdesc {
|
||||
enum FrameTypes type;
|
||||
uint8_t prop;
|
||||
uint8_t subcnt;
|
||||
uint16_t count;
|
||||
uint8_t prop;
|
||||
uint8_t subcnt;
|
||||
uint16_t count;
|
||||
};
|
||||
|
||||
struct fr_flatdesc {
|
||||
enum FrameTypes type; /* only basic frame types */
|
||||
uint8_t prop;
|
||||
uint8_t prop;
|
||||
enum FrameTypes otype; /* original type from generation */
|
||||
uint8_t mf_pos; /* 0 - 15 */
|
||||
uint32_t pos;
|
||||
uint8_t *data;
|
||||
uint8_t mf_pos; /* 0 - 15 */
|
||||
uint32_t pos;
|
||||
uint8_t *data;
|
||||
};
|
||||
|
||||
#define ftPROP_NONE 0x00
|
||||
|
@ -126,10 +124,10 @@ struct fr_flatdesc {
|
|||
#define ftPROP_AIS 0x80 /* AIS */
|
||||
|
||||
struct fr_data {
|
||||
int count;
|
||||
struct fr_flatdesc *desc;
|
||||
size_t data_size;
|
||||
uint8_t *data;
|
||||
int count;
|
||||
struct fr_flatdesc *desc;
|
||||
size_t data_size;
|
||||
uint8_t *data;
|
||||
};
|
||||
|
||||
static struct fr_data *TestData;
|
||||
|
@ -234,7 +232,7 @@ struct fr_cdesc test2[] = {
|
|||
{ftBIT2, ftPROP_FAIL, 1, 1},
|
||||
{ftFAS, ftPROP_NONE, 1, 1},
|
||||
{ftCtrl_End, ftPROP_NONE, 0, 0},
|
||||
|
||||
|
||||
{ftCtrl_Repeat, ftPROP_NONE, 0, 20},
|
||||
{ftBIT2, ftPROP_NONE, 1, 1},
|
||||
{ftFAS, ftPROP_NONE, 1, 1},
|
||||
|
@ -271,8 +269,8 @@ struct fr_cdesc test2[] = {
|
|||
{ftBIT2, ftPROP_NONE, 1, 1},
|
||||
{ftFAS, ftPROP_NONE, 1, 1},
|
||||
{ftCtrl_End, ftPROP_NONE, 0, 0},
|
||||
|
||||
{ftBIT2,ftPROP_NONE, 1, 1},
|
||||
|
||||
{ftBIT2, ftPROP_NONE, 1, 1},
|
||||
{ftFRAME_B, ftPROP_TS31, 2, 16000},
|
||||
{ftFRAME_C, ftPROP_TS31, 2, 6},
|
||||
{ftFRAME_B, ftPROP_TS31, 2, 16000},
|
||||
|
@ -313,7 +311,7 @@ struct fr_cdesc test3[] = {
|
|||
{ftFAS, ftPROP_FAIL, 1, 1},
|
||||
{ftBIT2, ftPROP_NONE, 1, 1},
|
||||
{ftMFB, ftPROP_NONE, 16, 250},
|
||||
|
||||
|
||||
{ftMFB, ftPROP_NONE, 16, 1},
|
||||
{ftMFA, ftPROP_NONE, 16, 1},
|
||||
{ftMFB, ftPROP_NONE, 16, 4},
|
||||
|
@ -323,11 +321,11 @@ struct fr_cdesc test3[] = {
|
|||
{ftMFA, ftPROP_NONE, 16, 1},
|
||||
{ftMFB, ftPROP_NONE, 16, 2},
|
||||
{ftMFA, ftPROP_NONE, 16, 1},
|
||||
|
||||
|
||||
{ftMFA, ftPROP_NONE, 16, 1},
|
||||
{ftMFB, ftPROP_NONE, 16, 2},
|
||||
{ftMFA, ftPROP_NONE, 16, 2},
|
||||
|
||||
|
||||
{ftCtrl_Repeat, ftPROP_NONE, 0, 500},
|
||||
{ftMFB, ftPROP_NONE, 16, 1},
|
||||
{ftMFA, ftPROP_NONE, 16, 1},
|
||||
|
@ -336,7 +334,6 @@ struct fr_cdesc test3[] = {
|
|||
{ftCtrl_Stop, ftPROP_NONE, 0, 0}
|
||||
};
|
||||
|
||||
|
||||
struct fr_cdesc test4[] = {
|
||||
{ftFRAME_B, ftPROP_TS31, 2, 16000},
|
||||
|
||||
|
@ -366,7 +363,7 @@ struct fr_cdesc test4[] = {
|
|||
{ftFAS, ftPROP_FAIL, 1, 1},
|
||||
{ftBIT2, ftPROP_NONE, 1, 1},
|
||||
{ftMFB, ftPROP_NONE, 16, 250},
|
||||
|
||||
|
||||
{ftMFB, ftPROP_NONE, 16, 1},
|
||||
{ftMFA, ftPROP_NONE, 16, 1},
|
||||
{ftMFB, ftPROP_NONE, 16, 4},
|
||||
|
@ -376,11 +373,11 @@ struct fr_cdesc test4[] = {
|
|||
{ftMFA, ftPROP_NONE, 16, 1},
|
||||
{ftMFB, ftPROP_NONE, 16, 2},
|
||||
{ftMFA, ftPROP_NONE, 16, 1},
|
||||
|
||||
|
||||
{ftMFA, ftPROP_NONE, 16, 1},
|
||||
{ftMFB, ftPROP_NONE, 16, 2},
|
||||
{ftMFA, ftPROP_NONE, 16, 2},
|
||||
|
||||
|
||||
{ftCtrl_Repeat, ftPROP_NONE, 0, 500},
|
||||
{ftMFB, ftPROP_NONE, 16, 1},
|
||||
{ftMFA, ftPROP_NONE, 16, 1},
|
||||
|
@ -389,15 +386,13 @@ struct fr_cdesc test4[] = {
|
|||
{ftCtrl_Stop, ftPROP_NONE, 0, 0}
|
||||
};
|
||||
|
||||
|
||||
static uint8_t mfr_sync;
|
||||
static uint8_t startcnt = MFR_SYNC_BITS;
|
||||
|
||||
static uint8_t *inbuf, *ib_p, *ib_end;
|
||||
static int ib_size, ib_pos;
|
||||
static uint8_t *outbuf, *ob_p, *ob_end;
|
||||
static int ob_size, ob_pos;
|
||||
|
||||
static uint8_t *inbuf, *ib_p, *ib_end;
|
||||
static int ib_size, ib_pos;
|
||||
static uint8_t *outbuf, *ob_p, *ob_end;
|
||||
static int ob_size, ob_pos;
|
||||
|
||||
enum FSyncState {
|
||||
FSync_None,
|
||||
|
@ -411,42 +406,40 @@ enum MFRSyncState {
|
|||
MFR_State_Sync
|
||||
};
|
||||
|
||||
|
||||
static enum FSyncState fsync_state = FSync_None;
|
||||
static enum MFRSyncState mfr_state = MFR_State_NotSync;
|
||||
|
||||
static uint8_t *last_mfrs;
|
||||
static uint8_t *last_mfrs;
|
||||
|
||||
static int good_mfr, bad_mfr;
|
||||
|
||||
|
||||
static int debuglevel = 0;
|
||||
static int RawReadMode = 0;
|
||||
static int cardnr = 0;
|
||||
static char * WriteFileName = NULL;
|
||||
static char *WriteFileName = NULL;
|
||||
static int ListMode = 0;
|
||||
struct fr_cdesc *Test = test0;
|
||||
static void usage(char *pname)
|
||||
{
|
||||
fprintf(stderr,"Call with %s [options]\n", pname);
|
||||
fprintf(stderr,"\n");
|
||||
fprintf(stderr,"\n Valid options are:\n");
|
||||
fprintf(stderr,"\n");
|
||||
fprintf(stderr," --help -? Usage ; printout this information\n");
|
||||
fprintf(stderr," --card -c <number> use card number # (default 0)\n");
|
||||
fprintf(stderr," --flat -f list flat test frame description\n");
|
||||
fprintf(stderr," --list -l list test frame description\n");
|
||||
fprintf(stderr," --raw -r rawread only mode\n");
|
||||
fprintf(stderr," --debug -d <level> debuglevel\n");
|
||||
fprintf(stderr," --test -t <test #> generate data for test # (default 0)\n");
|
||||
fprintf(stderr," --write -w <file> write <file>\n");
|
||||
fprintf(stderr,"\n");
|
||||
fprintf(stderr,"Tests:\n");
|
||||
fprintf(stderr," 0 - 10 seconds normal CRC4 framing\n");
|
||||
fprintf(stderr," 1 - TBR4 B.4.2 (table B.1)\n");
|
||||
fprintf(stderr," 2 - TBR4 B.5.2 (table B.2)\n");
|
||||
fprintf(stderr," 3 - TBR4 B.5.3 (table B.3)\n");
|
||||
fprintf(stderr,"\n");
|
||||
fprintf(stderr, "Call with %s [options]\n", pname);
|
||||
fprintf(stderr, "\n");
|
||||
fprintf(stderr, "\n Valid options are:\n");
|
||||
fprintf(stderr, "\n");
|
||||
fprintf(stderr, " --help -? Usage ; printout this information\n");
|
||||
fprintf(stderr, " --card -c <number> use card number # (default 0)\n");
|
||||
fprintf(stderr, " --flat -f list flat test frame description\n");
|
||||
fprintf(stderr, " --list -l list test frame description\n");
|
||||
fprintf(stderr, " --raw -r rawread only mode\n");
|
||||
fprintf(stderr, " --debug -d <level> debuglevel\n");
|
||||
fprintf(stderr, " --test -t <test #> generate data for test # (default 0)\n");
|
||||
fprintf(stderr, " --write -w <file> write <file>\n");
|
||||
fprintf(stderr, "\n");
|
||||
fprintf(stderr, "Tests:\n");
|
||||
fprintf(stderr, " 0 - 10 seconds normal CRC4 framing\n");
|
||||
fprintf(stderr, " 1 - TBR4 B.4.2 (table B.1)\n");
|
||||
fprintf(stderr, " 2 - TBR4 B.5.2 (table B.2)\n");
|
||||
fprintf(stderr, " 3 - TBR4 B.5.3 (table B.3)\n");
|
||||
fprintf(stderr, "\n");
|
||||
}
|
||||
|
||||
static int opt_parse(int ac, char *av[])
|
||||
|
@ -512,7 +505,7 @@ static int opt_parse(int ac, char *av[])
|
|||
break;
|
||||
case 't':
|
||||
if (optarg) {
|
||||
switch(*optarg) {
|
||||
switch (*optarg) {
|
||||
case '0':
|
||||
Test = test0;
|
||||
break;
|
||||
|
@ -547,10 +540,7 @@ static int opt_parse(int ac, char *av[])
|
|||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
static void printbinary(char *name, uint32_t val, uint8_t bits)
|
||||
static void printbinary(const char *name, uint32_t val, uint8_t bits)
|
||||
{
|
||||
uint32_t m;
|
||||
|
||||
|
@ -559,7 +549,7 @@ static void printbinary(char *name, uint32_t val, uint8_t bits)
|
|||
|
||||
printf("%s: ", name);
|
||||
|
||||
m = 1 << (bits -1);
|
||||
m = 1 << (bits - 1);
|
||||
while (m) {
|
||||
printf("%c", val & m ? '1' : '0');
|
||||
m >>= 1;
|
||||
|
@ -572,9 +562,9 @@ static void printhex(unsigned char *p, uint16_t idx, int len, int head)
|
|||
|
||||
for (i = 1; i <= len; i++) {
|
||||
printf(" %02x", p[idx++]);
|
||||
if ((i!=len) && !(i % 4) && (i % 16))
|
||||
if ((i != len) && !(i % 4) && (i % 16))
|
||||
printf(" ");
|
||||
if ((i!=len) && !(i % 16)) {
|
||||
if ((i != len) && !(i % 16)) {
|
||||
printf("\n");
|
||||
for (j = 0; j < head; j++)
|
||||
printf(" ");
|
||||
|
@ -594,16 +584,16 @@ void calc_bitswap_table(void)
|
|||
uint8_t v = 0;
|
||||
|
||||
do {
|
||||
bitswap_tbl[v] = (((v & 0x01) << 7) | ((v & 0x02) << 5) | ((v & 0x04) << 3) | ((v & 0x08) << 1) |
|
||||
((v & 0x10) >> 1) | ((v & 0x20) >> 3) | ((v & 0x40) >> 5) | ((v & 0x80) >> 7));
|
||||
bitswap_tbl[v] = (((v & 0x01) << 7) | ((v & 0x02) << 5) | ((v & 0x04) << 3) | ((v & 0x08) << 1) |
|
||||
((v & 0x10) >> 1) | ((v & 0x20) >> 3) | ((v & 0x40) >> 5) | ((v & 0x80) >> 7));
|
||||
v++;
|
||||
} while (v != 0);
|
||||
}
|
||||
|
||||
static uint8_t calc_crc4(uint8_t *data, uint16_t start, int len)
|
||||
static uint8_t calc_crc4(uint8_t * data, uint16_t start, int len)
|
||||
{
|
||||
uint16_t i, idx = start;
|
||||
uint8_t b, crc4 = 0;
|
||||
uint8_t b, crc4 = 0;
|
||||
|
||||
for (i = 0; i < len; i++) {
|
||||
b = bitswap_tbl[data[idx]];
|
||||
|
@ -616,17 +606,17 @@ static uint8_t calc_crc4(uint8_t *data, uint16_t start, int len)
|
|||
return crc4;
|
||||
};
|
||||
|
||||
static uint8_t calc_and_set_crc4_smf(uint8_t *smf, uint8_t crc)
|
||||
static uint8_t calc_and_set_crc4_smf(uint8_t * smf, uint8_t crc)
|
||||
{
|
||||
uint16_t i;
|
||||
uint8_t d, b, crc4 = 0;
|
||||
uint8_t d, b, crc4 = 0;
|
||||
|
||||
for (i = 0; i < SMFR_SIZE; i++) {
|
||||
d = smf[i];
|
||||
if (!(i % 64)) { /* Cx bit */
|
||||
if (!(i % 64)) { /* Cx bit */
|
||||
d &= 0xfe;
|
||||
b = bitswap_tbl[d];
|
||||
if (crc != 0xff) { /* no set if ff */
|
||||
if (crc != 0xff) { /* no set if ff */
|
||||
if (crc & 8)
|
||||
d |= 1;
|
||||
crc <<= 1;
|
||||
|
@ -643,7 +633,7 @@ static uint8_t calc_and_set_crc4_smf(uint8_t *smf, uint8_t crc)
|
|||
}
|
||||
|
||||
#ifdef NOT_USED_YET
|
||||
static uint8_t get_crc4_smf(uint8_t *smf)
|
||||
static uint8_t get_crc4_smf(uint8_t * smf)
|
||||
{
|
||||
uint16_t i;
|
||||
uint8_t crc4 = 0;
|
||||
|
@ -656,8 +646,8 @@ static uint8_t get_crc4_smf(uint8_t *smf)
|
|||
}
|
||||
#endif
|
||||
|
||||
static int cur_Err = 0;// cur_RAI = 0;
|
||||
static int analyse_mfr(uint8_t *p)
|
||||
static int cur_Err = 0; // cur_RAI = 0;
|
||||
static int analyse_mfr(uint8_t * p)
|
||||
{
|
||||
uint16_t i, t0idx;
|
||||
uint8_t d, crcfr[16];
|
||||
|
@ -682,7 +672,7 @@ static int analyse_mfr(uint8_t *p)
|
|||
case ftAIS:
|
||||
stim = "AIS";
|
||||
break;
|
||||
/* Basic Frames */
|
||||
/* Basic Frames */
|
||||
case ftFAS:
|
||||
if (dsc->prop & ftPROP_FAIL)
|
||||
stim = "/FAS";
|
||||
|
@ -695,21 +685,21 @@ static int analyse_mfr(uint8_t *p)
|
|||
else
|
||||
stim = "BIT 2";
|
||||
break;
|
||||
/* Sub multi frames */
|
||||
/* Sub multi frames */
|
||||
case ftSMFA:
|
||||
stim = "SMF A";
|
||||
break;
|
||||
case ftSMFB:
|
||||
stim = "SMF B";
|
||||
break;
|
||||
/* Multi frames */
|
||||
/* Multi frames */
|
||||
case ftMFA:
|
||||
stim = "MF A";
|
||||
break;
|
||||
case ftMFB:
|
||||
stim = "MF B";
|
||||
break;
|
||||
/* Frames */
|
||||
/* Frames */
|
||||
case ftFRAME_A:
|
||||
stim = "FRAME A";
|
||||
break;
|
||||
|
@ -724,8 +714,8 @@ static int analyse_mfr(uint8_t *p)
|
|||
break;
|
||||
}
|
||||
}
|
||||
|
||||
printf("Time:%6d ms {TX: %-7s} MFR %5d Error %3d ", ob_pos/DATA_SIZE_1MS, stim, good_mfr, bad_mfr);
|
||||
|
||||
printf("Time:%6d ms {TX: %-7s} MFR %5d Error %3d ", ob_pos / DATA_SIZE_1MS, stim, good_mfr, bad_mfr);
|
||||
last_mfrs = p;
|
||||
p -= MFR_SYNC_OFFSET * FRAME_SIZE;
|
||||
for (i = 0; i < 16; i++) {
|
||||
|
@ -743,7 +733,7 @@ static int analyse_mfr(uint8_t *p)
|
|||
}
|
||||
} else {
|
||||
C <<= 1;
|
||||
C |= ( 0x1 & d);
|
||||
C |= (0x1 & d);
|
||||
}
|
||||
}
|
||||
cr0 = calc_and_set_crc4_smf(p, 0xff);
|
||||
|
@ -776,12 +766,12 @@ static int analyse_mfr(uint8_t *p)
|
|||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Write one multiframe 16 * 2048 bit ; 512 bytes
|
||||
* returns the CRC4 for the next sub multiframe
|
||||
*/
|
||||
uint8_t fill_outframe(uint8_t *of, uint8_t A, uint8_t E, uint8_t S, uint8_t F, uint8_t cr0, uint8_t MFRSW, uint8_t *dch, uint8_t def)
|
||||
uint8_t fill_outframe(uint8_t * of, uint8_t A, uint8_t E, uint8_t S, uint8_t F, uint8_t cr0, uint8_t MFRSW, uint8_t * dch,
|
||||
uint8_t def)
|
||||
{
|
||||
uint16_t i, tidx;
|
||||
static unsigned char p;
|
||||
|
@ -789,7 +779,7 @@ uint8_t fill_outframe(uint8_t *of, uint8_t A, uint8_t E, uint8_t S, uint8_t F, u
|
|||
|
||||
tidx = 0;
|
||||
for (i = 0; i < 16; i++) {
|
||||
if (i & 1) { /* NFAS */
|
||||
if (i & 1) { /* NFAS */
|
||||
p = 0xf8 & S;
|
||||
if (A & 0x80)
|
||||
p |= 4;
|
||||
|
@ -810,7 +800,7 @@ uint8_t fill_outframe(uint8_t *of, uint8_t A, uint8_t E, uint8_t S, uint8_t F, u
|
|||
of[tidx] = p;
|
||||
tidx++;
|
||||
for (j = 1; j < 32; j++) {
|
||||
if (j == 16) { /* D channel */
|
||||
if (j == 16) { /* D channel */
|
||||
of[tidx] = *dch;
|
||||
dch++;
|
||||
} else
|
||||
|
@ -987,7 +977,7 @@ static int process_data(int cnt)
|
|||
break;
|
||||
}
|
||||
break;
|
||||
default: /* not possible here */
|
||||
default: /* not possible here */
|
||||
fprintf(stderr, "Line %d: Wrong state %d\n", __LINE__, frT[0]);
|
||||
exit(1);
|
||||
break;
|
||||
|
@ -1008,7 +998,7 @@ static int process_data(int cnt)
|
|||
mfr_state = MFR_State_Sync;
|
||||
good_mfr = 1;
|
||||
analyse_mfr(ib_cp);
|
||||
} else if (dist == 16 * 32) {
|
||||
} else if (dist == 16 * 32) {
|
||||
good_mfr++;
|
||||
analyse_mfr(ib_cp);
|
||||
}
|
||||
|
@ -1050,7 +1040,7 @@ static int fill_buffer(unsigned char *p, int len)
|
|||
}
|
||||
|
||||
/* returns next start frame */
|
||||
static uint8_t *fill_timeslot(uint8_t *p0, int ts, uint8_t *data, int datalen, int repeat)
|
||||
static uint8_t *fill_timeslot(uint8_t * p0, int ts, uint8_t * data, int datalen, int repeat)
|
||||
{
|
||||
uint8_t *p = p0;
|
||||
int i, cnt = repeat;
|
||||
|
@ -1065,8 +1055,8 @@ static uint8_t *fill_timeslot(uint8_t *p0, int ts, uint8_t *data, int datalen, i
|
|||
return p;
|
||||
}
|
||||
|
||||
uint8_t *fill_timeslot_ts0_smf(uint8_t *p0, int ts, int smf, uint8_t fas_err, uint8_t nfas_err, uint8_t mfsw,
|
||||
uint8_t S, uint8_t A, uint8_t C, uint8_t E, int repeat)
|
||||
uint8_t *fill_timeslot_ts0_smf(uint8_t * p0, int ts, int smf, uint8_t fas_err, uint8_t nfas_err, uint8_t mfsw,
|
||||
uint8_t S, uint8_t A, uint8_t C, uint8_t E, int repeat)
|
||||
{
|
||||
uint8_t *p = p0;
|
||||
uint8_t i, d[8], a, c, e, n, f, m;
|
||||
|
@ -1087,8 +1077,8 @@ uint8_t *fill_timeslot_ts0_smf(uint8_t *p0, int ts, int smf, uint8_t fas_err, ui
|
|||
m = mfsw >> 4;
|
||||
}
|
||||
for (i = 0; i < 8; i++) {
|
||||
if (i & 1) { /* NFAS */
|
||||
if (n & 8) /* nfas error */
|
||||
if (i & 1) { /* NFAS */
|
||||
if (n & 8) /* nfas error */
|
||||
d[i] = 0;
|
||||
else
|
||||
d[i] = 2;
|
||||
|
@ -1106,8 +1096,8 @@ uint8_t *fill_timeslot_ts0_smf(uint8_t *p0, int ts, int smf, uint8_t fas_err, ui
|
|||
if (a & 8)
|
||||
d[i] |= 4;
|
||||
a <<= 1;
|
||||
} else { /* FAS */
|
||||
if (f & 8) /* FAS error */
|
||||
} else { /* FAS */
|
||||
if (f & 8) /* FAS error */
|
||||
d[i] = 0xc8;
|
||||
else
|
||||
d[i] = FR_FAS_VAL;
|
||||
|
@ -1124,7 +1114,7 @@ uint8_t *fill_timeslot_ts0_smf(uint8_t *p0, int ts, int smf, uint8_t fas_err, ui
|
|||
return p;
|
||||
}
|
||||
|
||||
static uint8_t *calc_and_set_crc4_ts(uint8_t *start, uint8_t ts, uint8_t *first_last_crc, int smf_count)
|
||||
static uint8_t *calc_and_set_crc4_ts(uint8_t * start, uint8_t ts, uint8_t * first_last_crc, int smf_count)
|
||||
{
|
||||
uint8_t crc = *first_last_crc & 0xf;
|
||||
uint8_t wrong_crc = *first_last_crc & 0xf0;
|
||||
|
@ -1141,12 +1131,12 @@ static uint8_t *calc_and_set_crc4_ts(uint8_t *start, uint8_t ts, uint8_t *first_
|
|||
return p;
|
||||
}
|
||||
|
||||
static int transmit(int sock, uint8_t *ob, uint16_t len)
|
||||
static int transmit(int sock, uint8_t * ob, uint16_t len)
|
||||
{
|
||||
struct msghdr mh;
|
||||
struct iovec iov[2];
|
||||
struct msghdr mh;
|
||||
struct iovec iov[2];
|
||||
int ret;
|
||||
struct mISDNhead hh = {PH_DATA_REQ, 1};
|
||||
struct mISDNhead hh = { PH_DATA_REQ, 1 };
|
||||
|
||||
mh.msg_name = NULL;
|
||||
mh.msg_namelen = 0;
|
||||
|
@ -1161,8 +1151,7 @@ static int transmit(int sock, uint8_t *ob, uint16_t len)
|
|||
iov[1].iov_len = len;
|
||||
ret = sendmsg(sock, &mh, 0);
|
||||
if (ret != (len + MISDN_HEADER_LEN)) {
|
||||
fprintf(stderr, "Send error %d (%d + %d) - %s\n", ret,
|
||||
(int)MISDN_HEADER_LEN, len, strerror(errno));
|
||||
fprintf(stderr, "Send error %d (%d + %d) - %s\n", ret, (int)MISDN_HEADER_LEN, len, strerror(errno));
|
||||
ret = 0;
|
||||
} else
|
||||
ret = len;
|
||||
|
@ -1176,7 +1165,7 @@ static int last_dlen = 64;
|
|||
static int receive_ts0dch(int socket)
|
||||
{
|
||||
int ret, cnt, head;
|
||||
uint8_t buffer[MAX_RECV_BUFFER_SIZE];
|
||||
uint8_t buffer[MAX_RECV_BUFFER_SIZE];
|
||||
struct mISDNhead *hh = (struct mISDNhead *)buffer;
|
||||
|
||||
ret = recv(socket, buffer, MAX_RECV_BUFFER_SIZE, 0);
|
||||
|
@ -1186,9 +1175,9 @@ static int receive_ts0dch(int socket)
|
|||
}
|
||||
#if 0
|
||||
if (cts.cmsg_type == MISDN_TIME_STAMP) {
|
||||
mt = localtime((time_t *)&cts.tv.tv_sec);
|
||||
mt = localtime((time_t *) & cts.tv.tv_sec);
|
||||
head = printf("%02d.%02d.%04d %02d:%02d:%02d.%06ld", mt->tm_mday, mt->tm_mon + 1, mt->tm_year + 1900,
|
||||
mt->tm_hour, mt->tm_min, mt->tm_sec, cts.tv.tv_usec);
|
||||
mt->tm_hour, mt->tm_min, mt->tm_sec, cts.tv.tv_usec);
|
||||
} else {
|
||||
cts.tv.tv_sec = 0;
|
||||
cts.tv.tv_usec = 0;
|
||||
|
@ -1218,7 +1207,7 @@ static int receive_ts0dch(int socket)
|
|||
if (!RawReadMode) {
|
||||
ob_pos = ob_p - outbuf;
|
||||
if ((ob_pos + last_dlen) >= ob_size) {
|
||||
ret = -1; /* stop */
|
||||
ret = -1; /* stop */
|
||||
last_dlen = ob_size - ob_pos;
|
||||
}
|
||||
if (debuglevel == 5) {
|
||||
|
@ -1271,7 +1260,7 @@ static void print_testdescription(struct fr_cdesc *arg)
|
|||
case ftAIS:
|
||||
fprintf(stdout, "%-8s", "AIS");
|
||||
break;
|
||||
/* Basic Frames */
|
||||
/* Basic Frames */
|
||||
case ftFAS:
|
||||
if (dsc->prop & ftPROP_FAIL)
|
||||
fprintf(stdout, "%-8s", "/FAS");
|
||||
|
@ -1284,21 +1273,21 @@ static void print_testdescription(struct fr_cdesc *arg)
|
|||
else
|
||||
fprintf(stdout, "%-8s", "BIT 2");
|
||||
break;
|
||||
/* Sub multi frames */
|
||||
/* Sub multi frames */
|
||||
case ftSMFA:
|
||||
fprintf(stdout, "%-8s", "SMF A");
|
||||
break;
|
||||
case ftSMFB:
|
||||
fprintf(stdout, "%-8s", "SMF B");
|
||||
break;
|
||||
/* Multi frames */
|
||||
/* Multi frames */
|
||||
case ftMFA:
|
||||
fprintf(stdout, "%-8s", "MF A");
|
||||
break;
|
||||
case ftMFB:
|
||||
fprintf(stdout, "%-8s", "MF B");
|
||||
break;
|
||||
/* Frames */
|
||||
/* Frames */
|
||||
case ftFRAME_A:
|
||||
fprintf(stdout, "%-8s", "FRAME A");
|
||||
break;
|
||||
|
@ -1336,8 +1325,8 @@ static void print_flatdescription(struct fr_flatdesc *dsc)
|
|||
} else if (dsc->type == ftCtrl_Stop) {
|
||||
fprintf(stdout, "End of test\n");
|
||||
break;
|
||||
} else if (dsc->type == ftAIS) {
|
||||
fprintf(stdout, "%7d %2d %-6s", dsc->pos, dsc->mf_pos, "AIS");
|
||||
} else if (dsc->type == ftAIS) {
|
||||
fprintf(stdout, "%7d %2d %-6s", dsc->pos, dsc->mf_pos, "AIS");
|
||||
} else if (dsc->type == ftFAS) {
|
||||
if (dsc->prop & ftPROP_FAIL)
|
||||
fprintf(stdout, "%7d %2d %-6s", dsc->pos, dsc->mf_pos, "/FAS");
|
||||
|
@ -1353,7 +1342,7 @@ static void print_flatdescription(struct fr_flatdesc *dsc)
|
|||
case ftAIS:
|
||||
fprintf(stdout, "[%-7s]", "AIS");
|
||||
break;
|
||||
/* Basic Frames */
|
||||
/* Basic Frames */
|
||||
case ftFAS:
|
||||
if (dsc->prop & ftPROP_FAIL)
|
||||
fprintf(stdout, "[%-7s]", "/FAS");
|
||||
|
@ -1366,21 +1355,21 @@ static void print_flatdescription(struct fr_flatdesc *dsc)
|
|||
else
|
||||
fprintf(stdout, "[%-7s]", "BIT 2");
|
||||
break;
|
||||
/* Sub multi frames */
|
||||
/* Sub multi frames */
|
||||
case ftSMFA:
|
||||
fprintf(stdout, "[%-7s]", "SMF A");
|
||||
break;
|
||||
case ftSMFB:
|
||||
fprintf(stdout, "[%-7s]", "SMF B");
|
||||
break;
|
||||
/* Multi frames */
|
||||
/* Multi frames */
|
||||
case ftMFA:
|
||||
fprintf(stdout, "[%-7s]", "MF A");
|
||||
break;
|
||||
case ftMFB:
|
||||
fprintf(stdout, "[%-7s]", "MF B");
|
||||
break;
|
||||
/* Frames */
|
||||
/* Frames */
|
||||
case ftFRAME_A:
|
||||
fprintf(stdout, "[%-7s]", "FRAME A");
|
||||
break;
|
||||
|
@ -1399,7 +1388,7 @@ static void print_flatdescription(struct fr_flatdesc *dsc)
|
|||
if (dsc->prop & ftPROP_MFAS)
|
||||
fprintf(stdout, " (MFAS Error)");
|
||||
if (dsc->prop & ftPROP_TS31)
|
||||
fprintf(stdout, " (TS 31)");
|
||||
fprintf(stdout, " (TS 31)");
|
||||
if (dsc->prop & ftPROP_START)
|
||||
fprintf(stdout, " (Start Test)");
|
||||
fprintf(stdout, "\n");
|
||||
|
@ -1499,7 +1488,7 @@ static struct fr_flatdesc *make_flat_description(struct fr_cdesc *test, struct f
|
|||
break;
|
||||
}
|
||||
end = flat;
|
||||
repeat[csp]--; /* one already done */
|
||||
repeat[csp]--; /* one already done */
|
||||
while (repeat[csp]) {
|
||||
seq = start[csp];
|
||||
while (seq != end) {
|
||||
|
@ -1509,7 +1498,7 @@ static struct fr_flatdesc *make_flat_description(struct fr_cdesc *test, struct f
|
|||
seq++;
|
||||
flat++;
|
||||
pos++;
|
||||
}
|
||||
}
|
||||
--repeat[csp];
|
||||
}
|
||||
csp--;
|
||||
|
@ -1517,7 +1506,7 @@ static struct fr_flatdesc *make_flat_description(struct fr_cdesc *test, struct f
|
|||
for (cnt = 0; cnt < dsc->count; cnt++) {
|
||||
switch (dsc->type) {
|
||||
case ftAIS:
|
||||
/* Basic Frames */
|
||||
/* Basic Frames */
|
||||
case ftFAS:
|
||||
case ftBIT2:
|
||||
flat->pos = pos;
|
||||
|
@ -1527,7 +1516,7 @@ static struct fr_flatdesc *make_flat_description(struct fr_cdesc *test, struct f
|
|||
flat++;
|
||||
pos++;
|
||||
break;
|
||||
/* Sub multi frames */
|
||||
/* Sub multi frames */
|
||||
case ftSMFA:
|
||||
for (i = 0; i < 8; i++) {
|
||||
flat->pos = pos;
|
||||
|
@ -1555,7 +1544,7 @@ static struct fr_flatdesc *make_flat_description(struct fr_cdesc *test, struct f
|
|||
pos++;
|
||||
}
|
||||
break;
|
||||
/* Multi frames */
|
||||
/* Multi frames */
|
||||
case ftMFA:
|
||||
for (i = 0; i < 16; i++) {
|
||||
flat->pos = pos;
|
||||
|
@ -1583,7 +1572,7 @@ static struct fr_flatdesc *make_flat_description(struct fr_cdesc *test, struct f
|
|||
pos++;
|
||||
}
|
||||
break;
|
||||
/* Frames */
|
||||
/* Frames */
|
||||
case ftFRAME_A:
|
||||
flat->pos = pos;
|
||||
flat->otype = dsc->type;
|
||||
|
@ -1649,11 +1638,11 @@ static struct fr_flatdesc *make_flat_description(struct fr_cdesc *test, struct f
|
|||
flat->mf_pos = 0xff;
|
||||
flat->mf_pos = 14;
|
||||
} else if (flat->type == ftFAS) {
|
||||
if (mfpos & 1) /* reset */
|
||||
if (mfpos & 1) /* reset */
|
||||
mfpos = 0;
|
||||
} else if (flat->type == ftBIT2) {
|
||||
if (!(mfpos & 1))
|
||||
mfpos = 1;
|
||||
if (!(mfpos & 1))
|
||||
mfpos = 1;
|
||||
}
|
||||
flat->mf_pos = mfpos;
|
||||
mfpos++;
|
||||
|
@ -1666,15 +1655,15 @@ static struct fr_flatdesc *make_flat_description(struct fr_cdesc *test, struct f
|
|||
|
||||
static struct fr_data *gen_flat_frame_desc(struct fr_cdesc *dsc)
|
||||
{
|
||||
struct fr_data loc_frd, *frd;
|
||||
struct fr_flatdesc *flat_dsc;
|
||||
int cnt, sum, pre;
|
||||
struct fr_data loc_frd, *frd;
|
||||
struct fr_flatdesc *flat_dsc;
|
||||
int cnt, sum, pre;
|
||||
|
||||
pre = calc_flatcount(preamble);
|
||||
cnt = calc_flatcount(dsc);
|
||||
sum = pre + cnt;
|
||||
loc_frd.count = sum;
|
||||
flat_dsc = calloc(sum + 2, sizeof(*flat_dsc)); /* reserve for stop */
|
||||
flat_dsc = calloc(sum + 2, sizeof(*flat_dsc)); /* reserve for stop */
|
||||
if (!flat_dsc) {
|
||||
fprintf(stderr, "No memory to allocate %d * %zd bytes for flat description\n", loc_frd.count, sizeof(*flat_dsc));
|
||||
return NULL;
|
||||
|
@ -1702,7 +1691,8 @@ static struct fr_data *gen_flat_frame_desc(struct fr_cdesc *dsc)
|
|||
return frd;
|
||||
}
|
||||
|
||||
static int gen_flat_frame_data(struct fr_data *frd) {
|
||||
static int gen_flat_frame_data(struct fr_data *frd)
|
||||
{
|
||||
struct fr_flatdesc *flat;
|
||||
size_t size;
|
||||
int ret = 0;
|
||||
|
@ -1712,7 +1702,7 @@ static int gen_flat_frame_data(struct fr_data *frd) {
|
|||
size = frd->count;
|
||||
size *= FRAME_SIZE;
|
||||
frd->data_size = size;
|
||||
frd->data = malloc(size + 100 * FRAME_SIZE); /* Reserve to avoid crash when manipulate frames on the end */
|
||||
frd->data = malloc(size + 100 * FRAME_SIZE); /* Reserve to avoid crash when manipulate frames on the end */
|
||||
if (!frd->data) {
|
||||
fprintf(stderr, "No memory to allocate %zd + %d bytes\n", size, 100 * FRAME_SIZE);
|
||||
flat = NULL;
|
||||
|
@ -1759,7 +1749,7 @@ static int gen_flat_frame_data(struct fr_data *frd) {
|
|||
flat++;
|
||||
}
|
||||
p = frd->data;
|
||||
crc = 0; /* start value */
|
||||
crc = 0; /* start value */
|
||||
flat = frd->desc;
|
||||
while (flat) {
|
||||
if (flat->type == ftNone) {
|
||||
|
@ -1785,28 +1775,25 @@ static int gen_flat_frame_data(struct fr_data *frd) {
|
|||
}
|
||||
}
|
||||
flat++;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
int
|
||||
main(argc, argv)
|
||||
int argc;
|
||||
char *argv[];
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
int i, channel;
|
||||
int log_socket;
|
||||
struct sockaddr_mISDN log_addr;
|
||||
int buflen = 4104;
|
||||
u_char buffer[buflen];
|
||||
int result;
|
||||
int cnt, dlen;
|
||||
struct mISDN_devinfo di;
|
||||
struct mISDNhead *hh;
|
||||
struct mISDNversion ver;
|
||||
int i, channel;
|
||||
int log_socket;
|
||||
struct sockaddr_mISDN log_addr;
|
||||
int buflen = 4104;
|
||||
u_char buffer[buflen];
|
||||
int result;
|
||||
int cnt, dlen;
|
||||
struct mISDN_devinfo di;
|
||||
struct mISDNhead *hh;
|
||||
struct mISDNversion ver;
|
||||
struct pollfd pfd[8];
|
||||
int pfd_nr;
|
||||
struct mISDN_ctrl_req creq;
|
||||
struct mISDN_ctrl_req creq;
|
||||
|
||||
result = opt_parse(argc, argv);
|
||||
if (result) {
|
||||
|
@ -1832,12 +1819,12 @@ char *argv[];
|
|||
}
|
||||
result = gen_flat_frame_data(TestData);
|
||||
if (result) {
|
||||
fprintf(stderr,"Error generating test data\n");
|
||||
fprintf(stderr, "Error generating test data\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
if (cardnr < 0) {
|
||||
fprintf(stderr,"card nr may not be negative\n");
|
||||
fprintf(stderr, "card nr may not be negative\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
|
@ -1852,7 +1839,8 @@ char *argv[];
|
|||
exit(1);
|
||||
}
|
||||
if (ver.release & MISDN_GIT_RELEASE)
|
||||
printf("mISDN kernel version %d.%02d.%d (git.misdn.eu) found\n", ver.major, ver.minor, ver.release & ~MISDN_GIT_RELEASE);
|
||||
printf("mISDN kernel version %d.%02d.%d (git.misdn.eu) found\n", ver.major, ver.minor,
|
||||
ver.release & ~MISDN_GIT_RELEASE);
|
||||
else
|
||||
printf("mISDN kernel version %d.%02d.%d found\n", ver.major, ver.minor, ver.release);
|
||||
|
||||
|
@ -1868,7 +1856,7 @@ char *argv[];
|
|||
printf("ioctl error %s\n", strerror(errno));
|
||||
exit(1);
|
||||
} else
|
||||
printf("%d controller%s found\n", cnt, (cnt==1)?"":"s");
|
||||
printf("%d controller%s found\n", cnt, (cnt == 1) ? "" : "s");
|
||||
|
||||
di.id = cardnr;
|
||||
result = ioctl(log_socket, IMGETDEVINFO, &di);
|
||||
|
@ -1903,10 +1891,10 @@ char *argv[];
|
|||
ib_p = inbuf;
|
||||
ib_cp = inbuf;
|
||||
ib_end = outbuf + ib_size;
|
||||
|
||||
|
||||
/* Ready for transmit */
|
||||
ob_p = outbuf;
|
||||
|
||||
|
||||
if ((log_socket = socket(PF_ISDN, SOCK_DGRAM, ISDN_P_B_RAW)) < 0) {
|
||||
printf("could not open log socket %s\n", strerror(errno));
|
||||
exit(1);
|
||||
|
@ -1919,7 +1907,7 @@ char *argv[];
|
|||
channel = 0;
|
||||
|
||||
log_addr.channel = (unsigned char)channel;
|
||||
result = bind(log_socket, (struct sockaddr *) &log_addr, sizeof(log_addr));
|
||||
result = bind(log_socket, (struct sockaddr *)&log_addr, sizeof(log_addr));
|
||||
printf("log bind ch(%i) return %d\n", log_addr.channel, result);
|
||||
if (result < 0) {
|
||||
printf("log bind error %s\n", strerror(errno));
|
||||
|
@ -1958,10 +1946,8 @@ char *argv[];
|
|||
exit(1);
|
||||
}
|
||||
|
||||
|
||||
if (debuglevel)
|
||||
fprintf(stdout,"MISDN_CTRL_GETOP ioctl supported operations %x\n", creq.op);
|
||||
|
||||
fprintf(stdout, "MISDN_CTRL_GETOP ioctl supported operations %x\n", creq.op);
|
||||
|
||||
/* This set the register values in the card so, that the TS0 is not in full transparent mode,
|
||||
* so the receiver can syncronize - this allows to get the TS0 data on byte boundaries, so bit shifting all
|
||||
|
@ -1970,14 +1956,14 @@ char *argv[];
|
|||
|
||||
creq.op = MISDN_CTRL_L1_TS0_MODE;
|
||||
creq.channel = 0;
|
||||
creq.p1 = 0x06; /* R_RX_SL0_CFG0 = (V_AUTOSYNC | V_AUTO_RECO) */
|
||||
creq.p2 = 0x31; /* R_TX_SL0_CFG1 = (V_TX_MF | V_TX_E | V_INV_E) */
|
||||
creq.p1 = 0x06; /* R_RX_SL0_CFG0 = (V_AUTOSYNC | V_AUTO_RECO) */
|
||||
creq.p2 = 0x31; /* R_TX_SL0_CFG1 = (V_TX_MF | V_TX_E | V_INV_E) */
|
||||
creq.unused = 0;
|
||||
if (debuglevel)
|
||||
fprintf(stdout,"L1 TS0 ioctl R_RX_SL0_CFG0=%02x R_TX_SL0_CFG1=%02x\n", creq.p1, creq.p2);
|
||||
fprintf(stdout, "L1 TS0 ioctl R_RX_SL0_CFG0=%02x R_TX_SL0_CFG1=%02x\n", creq.p1, creq.p2);
|
||||
result = ioctl(log_socket, IMCTRLREQ, &creq);
|
||||
if (debuglevel)
|
||||
fprintf(stdout,"L1 TS0 ioctl old register values R_RX_SL0_CFG0=%02x R_TX_SL0_CFG1=%02x\n", creq.p1, creq.p2);
|
||||
fprintf(stdout, "L1 TS0 ioctl old register values R_RX_SL0_CFG0=%02x R_TX_SL0_CFG1=%02x\n", creq.p1, creq.p2);
|
||||
if (result < 0) {
|
||||
fprintf(stdout, "Error on MISDN_CTRL_L1_TS0_MODE ioctl - %s\n", strerror(errno));
|
||||
close(log_socket);
|
||||
|
@ -1985,7 +1971,7 @@ char *argv[];
|
|||
}
|
||||
|
||||
hh->prim = PH_ACTIVATE_REQ;
|
||||
hh->id = MISDN_ID_ANY;
|
||||
hh->id = MISDN_ID_ANY;
|
||||
result = sendto(log_socket, buffer, MISDN_HEADER_LEN, 0, NULL, 0);
|
||||
|
||||
if (result < 0) {
|
||||
|
@ -2007,13 +1993,12 @@ char *argv[];
|
|||
exit(1);
|
||||
}
|
||||
if (debuglevel)
|
||||
fprintf(stdout,"RX_OFF result %d ioctl p1=%02x p2=%02x p3=%02x\n",
|
||||
result, creq.p1, creq.p2, creq.unused);
|
||||
fprintf(stdout, "RX_OFF result %d ioctl p1=%02x p2=%02x p3=%02x\n", result, creq.p1, creq.p2, creq.unused);
|
||||
|
||||
creq.op = MISDN_CTRL_L1_GET_SYNC_INFO;
|
||||
creq.channel = 0;
|
||||
cnt = 0;
|
||||
/* Wait for sync - this will make sure that we do not need bit shifting incomming data */
|
||||
/* Wait for sync - this will make sure that we do not need bit shifting incomming data */
|
||||
for (i = 0; i < 5000; i++) {
|
||||
result = ioctl(log_socket, IMCTRLREQ, &creq);
|
||||
if (result < 0) {
|
||||
|
@ -2022,8 +2007,7 @@ char *argv[];
|
|||
exit(1);
|
||||
}
|
||||
if (debuglevel)
|
||||
fprintf(stdout,"L1 GET_SYNC_INFO ioctl p1=%02x p2=%02x p3=%02x\n",
|
||||
creq.p1, creq.p2, creq.unused);
|
||||
fprintf(stdout, "L1 GET_SYNC_INFO ioctl p1=%02x p2=%02x p3=%02x\n", creq.p1, creq.p2, creq.unused);
|
||||
if ((creq.p1 & 0xff07) == 0x2701) {
|
||||
cnt++;
|
||||
if (cnt == 3)
|
||||
|
@ -2035,11 +2019,11 @@ char *argv[];
|
|||
};
|
||||
|
||||
if (cnt != 3) {
|
||||
fprintf(stdout,"L1 ts0 sync state not reached\n");
|
||||
fprintf(stdout, "L1 ts0 sync state not reached\n");
|
||||
close(log_socket);
|
||||
exit(1);
|
||||
} else
|
||||
fprintf(stdout,"L1 ts0 sync state reached (need %d iterations)\n", i);
|
||||
fprintf(stdout, "L1 ts0 sync state reached (need %d iterations)\n", i);
|
||||
|
||||
/* reenable receive */
|
||||
creq.op = MISDN_CTRL_RX_OFF;
|
||||
|
@ -2054,18 +2038,18 @@ char *argv[];
|
|||
exit(1);
|
||||
}
|
||||
if (debuglevel)
|
||||
fprintf(stdout,"RX_OFF ioctl p1=%02x p2=%02x p3=%02x\n", creq.p1, creq.p2, creq.unused);
|
||||
fprintf(stdout, "RX_OFF ioctl p1=%02x p2=%02x p3=%02x\n", creq.p1, creq.p2, creq.unused);
|
||||
|
||||
creq.op = MISDN_CTRL_L1_TS0_MODE;
|
||||
creq.channel = 0;
|
||||
creq.p1 = 0x01; /* R_RX_SL0_CFG0 = (V_NO_INSYNC) */
|
||||
creq.p2 = 0x03; /* R_TX_SL0_CFG1 = (V_TX_MF | V_TRP_SL0) */
|
||||
creq.p1 = 0x01; /* R_RX_SL0_CFG0 = (V_NO_INSYNC) */
|
||||
creq.p2 = 0x03; /* R_TX_SL0_CFG1 = (V_TX_MF | V_TRP_SL0) */
|
||||
creq.unused = 0;
|
||||
if (debuglevel)
|
||||
fprintf(stdout,"L1 TS0 ioctl R_RX_SL0_CFG0=%02x R_TX_SL0_CFG1=%02x\n", creq.p1, creq.p2);
|
||||
fprintf(stdout, "L1 TS0 ioctl R_RX_SL0_CFG0=%02x R_TX_SL0_CFG1=%02x\n", creq.p1, creq.p2);
|
||||
result = ioctl(log_socket, IMCTRLREQ, &creq);
|
||||
if (debuglevel)
|
||||
fprintf(stdout,"L1 TS0 ioctl old register values R_RX_SL0_CFG0=%02x R_TX_SL0_CFG1=%02x\n", creq.p1, creq.p2);
|
||||
fprintf(stdout, "L1 TS0 ioctl old register values R_RX_SL0_CFG0=%02x R_TX_SL0_CFG1=%02x\n", creq.p1, creq.p2);
|
||||
if (result < 0) {
|
||||
fprintf(stdout, "Error on MISDN_CTRL_L1_TS0_MODE ioctl - %s\n", strerror(errno));
|
||||
close(log_socket);
|
||||
|
@ -2084,7 +2068,7 @@ char *argv[];
|
|||
}
|
||||
if (pfd[0].revents) {
|
||||
dlen = receive_ts0dch(log_socket);
|
||||
if (dlen < 1) /* end of data */
|
||||
if (dlen < 1) /* end of data */
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,13 +1,24 @@
|
|||
bin_PROGRAMS = misdn_info misdn_log misdn_E1test isdn_text2wireshark
|
||||
sbin_PROGRAMS = misdn_rename misdn_cleanl2
|
||||
sbin_PROGRAMS = misdn_rename misdn_cleanl2 misdnlogger
|
||||
|
||||
misdn_info_SOURCES = info.c
|
||||
misdn_log_SOURCES = loghex.c
|
||||
misdn_rename_SOURCES = rename.c
|
||||
misdn_cleanl2_SOURCES = cleanl2.c
|
||||
misdn_E1test_SOURCES = E1test.c
|
||||
misdnlogger_SOURCES = logger.h logger.c logger_config_parser.l
|
||||
misdnlogger_LDADD = ../lib/libmisdn.la
|
||||
isdn_text2wireshark_SOURCES = text_wireshark.c
|
||||
|
||||
AM_CPPFLAGS = -Wall -Werror -I$(top_srcdir)/include $(_MEMLEAKDEBUG)
|
||||
|
||||
CLEANFILES = *~
|
||||
|
||||
EXTRA_DIST = misdnlogger.conf.sample
|
||||
|
||||
install-data-local:
|
||||
install -d $(DESTDIR)$(sysconfdir)
|
||||
install -m 644 misdnlogger.conf.sample $(DESTDIR)$(sysconfdir)/misdnlogger.conf
|
||||
|
||||
distuninstallcheck_listfiles = \
|
||||
find . -type f -print | grep -v 'misdnlogger.conf'
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
/*
|
||||
*
|
||||
* Copyright 2015 Karsten Keil <keil@b1-systems.de>
|
||||
* Copyright 2008 Karsten Keil <kkeil@suse.de>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
|
@ -38,63 +39,58 @@
|
|||
#include <mISDN/mISDNif.h>
|
||||
#include <mISDN/af_isdn.h>
|
||||
|
||||
void usage(pname)
|
||||
char *pname;
|
||||
void usage(char *pname)
|
||||
{
|
||||
fprintf(stderr,"Call with %s [options]\n",pname);
|
||||
fprintf(stderr,"\n");
|
||||
fprintf(stderr,"\n Valid options are:\n");
|
||||
fprintf(stderr,"\n");
|
||||
fprintf(stderr," -? Usage ; printout this information\n");
|
||||
fprintf(stderr," -c<n> use card number n (default 1)\n");
|
||||
fprintf(stderr,"\n");
|
||||
fprintf(stderr, "Call with %s [options]\n", pname);
|
||||
fprintf(stderr, "\n");
|
||||
fprintf(stderr, "\n Valid options are:\n");
|
||||
fprintf(stderr, "\n");
|
||||
fprintf(stderr, " -? Usage ; printout this information\n");
|
||||
fprintf(stderr, " -c<n> use card number n (default 1)\n");
|
||||
fprintf(stderr, "\n");
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
main(argc, argv)
|
||||
int argc;
|
||||
char *argv[];
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
int aidx=1;
|
||||
int aidx = 1;
|
||||
int cardnr = 0;
|
||||
int sock;
|
||||
struct sockaddr_mISDN addr;
|
||||
struct sockaddr_mISDN addr;
|
||||
int result;
|
||||
int clean;
|
||||
char sw;
|
||||
u_int cnt, protocol;
|
||||
struct mISDN_devinfo di;
|
||||
|
||||
struct mISDN_devinfo di;
|
||||
|
||||
while (aidx < argc) {
|
||||
if (argv[aidx] && argv[aidx][0]=='-') {
|
||||
sw=argv[aidx][1];
|
||||
if (argv[aidx] && argv[aidx][0] == '-') {
|
||||
sw = argv[aidx][1];
|
||||
switch (sw) {
|
||||
case 'c':
|
||||
if (argv[aidx][2]) {
|
||||
cardnr=atol(&argv[aidx][2]);
|
||||
}
|
||||
break;
|
||||
case '?' :
|
||||
usage(argv[0]);
|
||||
exit(1);
|
||||
break;
|
||||
default : fprintf(stderr,"Unknown Switch %c\n",sw);
|
||||
usage(argv[0]);
|
||||
exit(1);
|
||||
break;
|
||||
case 'c':
|
||||
if (argv[aidx][2]) {
|
||||
cardnr = atol(&argv[aidx][2]);
|
||||
}
|
||||
break;
|
||||
case '?':
|
||||
usage(argv[0]);
|
||||
exit(1);
|
||||
break;
|
||||
default:
|
||||
fprintf(stderr, "Unknown Switch %c\n", sw);
|
||||
usage(argv[0]);
|
||||
exit(1);
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
fprintf(stderr,"Undefined argument %s\n",argv[aidx]);
|
||||
} else {
|
||||
fprintf(stderr, "Undefined argument %s\n", argv[aidx]);
|
||||
usage(argv[0]);
|
||||
exit(1);
|
||||
}
|
||||
aidx++;
|
||||
}
|
||||
}
|
||||
|
||||
if (cardnr < 0) {
|
||||
fprintf(stderr,"card nr cannot be negative\n");
|
||||
fprintf(stderr, "card nr cannot be negative\n");
|
||||
exit(1);
|
||||
}
|
||||
if ((sock = socket(PF_ISDN, SOCK_RAW, 0)) < 0) {
|
||||
|
@ -106,7 +102,7 @@ char *argv[];
|
|||
printf("ioctl error %s\n", strerror(errno));
|
||||
exit(1);
|
||||
} else
|
||||
printf("%d controller%s found\n", cnt, (cnt==1)?"":"s");
|
||||
printf("%d controller%s found\n", cnt, (cnt == 1) ? "" : "s");
|
||||
|
||||
di.id = cardnr;
|
||||
result = ioctl(sock, IMGETDEVINFO, &di);
|
||||
|
@ -144,8 +140,7 @@ char *argv[];
|
|||
addr.channel = 0;
|
||||
addr.sapi = 0;
|
||||
addr.tei = 127;
|
||||
result = bind(sock, (struct sockaddr *) &addr,
|
||||
sizeof(addr));
|
||||
result = bind(sock, (struct sockaddr *)&addr, sizeof(addr));
|
||||
printf("bind return %d\n", result);
|
||||
|
||||
if (result < 0) {
|
||||
|
|
113
tools/info.c
113
tools/info.c
|
@ -7,8 +7,7 @@
|
|||
** **
|
||||
** user space utility to list mISDN devices **
|
||||
** **
|
||||
\*****************************************************************************/
|
||||
|
||||
\*****************************************************************************/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
@ -20,7 +19,7 @@
|
|||
#include <mISDN/af_isdn.h>
|
||||
#include <errno.h>
|
||||
|
||||
char *spaces = " ";
|
||||
const char *spaces = " ";
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
|
@ -32,8 +31,7 @@ int main(int argc, char *argv[])
|
|||
|
||||
/* open mISDN */
|
||||
sock = socket(PF_ISDN, SOCK_RAW, ISDN_P_BASE);
|
||||
if (sock < 0)
|
||||
{
|
||||
if (sock < 0) {
|
||||
fprintf(stderr, "Cannot open mISDN due to %s. (Does your Kernel support socket based mISDN?)\n", strerror(errno));
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
@ -41,82 +39,70 @@ int main(int argc, char *argv[])
|
|||
/* get number of stacks */
|
||||
i = 0;
|
||||
ret = ioctl(sock, IMGETCOUNT, &ii);
|
||||
if (ret < 0)
|
||||
{
|
||||
if (ret < 0) {
|
||||
fprintf(stderr, "Cannot get number of mISDN devices. (ioctl IMGETCOUNT failed ret=%d)\n", ret);
|
||||
goto done;
|
||||
}
|
||||
printf("\n");
|
||||
if (ii <= 0)
|
||||
{
|
||||
if (ii <= 0) {
|
||||
printf("Found no card. Please be sure to load card drivers.\n");
|
||||
goto done;
|
||||
} else
|
||||
printf("Found %i port%s\n", ii, (ii>1)?"s":"");
|
||||
} else
|
||||
printf("Found %i port%s\n", ii, (ii > 1) ? "s" : "");
|
||||
|
||||
/* loop the number of cards and get their info */
|
||||
while(ii && i <= MAX_DEVICE_ID)
|
||||
{
|
||||
while (ii && i <= MAX_DEVICE_ID) {
|
||||
nt = te = bri = pri = pots = s0 = 0;
|
||||
useable = 0;
|
||||
|
||||
devinfo.id = i;
|
||||
ret = ioctl(sock, IMGETDEVINFO, &devinfo);
|
||||
if (ret < 0)
|
||||
{
|
||||
fprintf(stderr, "error getting info for device %d: %s\n", i,strerror(errno));
|
||||
if (ret < 0) {
|
||||
fprintf(stderr, "error getting info for device %d: %s\n", i, strerror(errno));
|
||||
goto next_dev;
|
||||
}
|
||||
|
||||
/* output the port info */
|
||||
printf(" Port %2d '%s':", i, devinfo.name);
|
||||
if (strlen(devinfo.name) <= strlen(spaces))
|
||||
printf(spaces+strlen(devinfo.name));
|
||||
printf("%s", spaces + strlen(devinfo.name));
|
||||
else
|
||||
printf("\n ");
|
||||
|
||||
if (devinfo.Dprotocols & (1 << ISDN_P_TE_S0))
|
||||
{
|
||||
if (devinfo.Dprotocols & (1 << ISDN_P_TE_S0)) {
|
||||
bri = 1;
|
||||
te = 1;
|
||||
s0 = 1;
|
||||
}
|
||||
if (devinfo.Dprotocols & (1 << ISDN_P_NT_S0))
|
||||
{
|
||||
if (devinfo.Dprotocols & (1 << ISDN_P_NT_S0)) {
|
||||
bri = 1;
|
||||
nt = 1;
|
||||
s0 = 1;
|
||||
}
|
||||
if (devinfo.Dprotocols & (1 << ISDN_P_TE_E1))
|
||||
{
|
||||
if (devinfo.Dprotocols & (1 << ISDN_P_TE_E1)) {
|
||||
pri = 1;
|
||||
te = 1;
|
||||
}
|
||||
if (devinfo.Dprotocols & (1 << ISDN_P_NT_E1))
|
||||
{
|
||||
if (devinfo.Dprotocols & (1 << ISDN_P_NT_E1)) {
|
||||
pri = 1;
|
||||
nt = 1;
|
||||
}
|
||||
if (devinfo.Dprotocols & (1 << ISDN_P_TE_UP0))
|
||||
{
|
||||
if (devinfo.Dprotocols & (1 << ISDN_P_TE_UP0)) {
|
||||
bri = 1;
|
||||
te = 1;
|
||||
}
|
||||
if (devinfo.Dprotocols & (1 << ISDN_P_NT_UP0))
|
||||
{
|
||||
if (devinfo.Dprotocols & (1 << ISDN_P_NT_UP0)) {
|
||||
bri = 1;
|
||||
nt = 1;
|
||||
}
|
||||
#ifdef ISDN_P_FXS
|
||||
if (devinfo.Dprotocols & (1 << ISDN_P_FXS))
|
||||
{
|
||||
if (devinfo.Dprotocols & (1 << ISDN_P_FXS)) {
|
||||
pots = 1;
|
||||
te = 1;
|
||||
}
|
||||
#endif
|
||||
#ifdef ISDN_P_FXO
|
||||
if (devinfo.Dprotocols & (1 << ISDN_P_FXO))
|
||||
{
|
||||
if (devinfo.Dprotocols & (1 << ISDN_P_FXO)) {
|
||||
pots = 1;
|
||||
nt = 1;
|
||||
}
|
||||
|
@ -125,14 +111,11 @@ int main(int argc, char *argv[])
|
|||
useable = 1;
|
||||
|
||||
if (te && nt && bri)
|
||||
printf("TE/NT-mode BRI %s (for phone lines & phones)",
|
||||
(s0) ? "S/T" : "UP0");
|
||||
printf("TE/NT-mode BRI %s (for phone lines & phones)", (s0) ? "S/T" : "UP0");
|
||||
if (te && !nt && bri)
|
||||
printf("TE-mode BRI %s (for phone lines)",
|
||||
(s0) ? "S/T" : "UP0");
|
||||
printf("TE-mode BRI %s (for phone lines)", (s0) ? "S/T" : "UP0");
|
||||
if (nt && !te && bri)
|
||||
printf("NT-mode BRI %s (for phones)",
|
||||
(s0) ? "S/T" : "UP0");
|
||||
printf("NT-mode BRI %s (for phones)", (s0) ? "S/T" : "UP0");
|
||||
if (te && nt && pri)
|
||||
printf("TE/NT-mode PRI E1 (for phone lines & E1 devices)");
|
||||
if (te && !nt && pri)
|
||||
|
@ -145,32 +128,25 @@ int main(int argc, char *argv[])
|
|||
printf("FXS POTS (for analog lines)");
|
||||
if (nt && !te && pots)
|
||||
printf("FXO POTS (for analog phones)");
|
||||
if (pots)
|
||||
{
|
||||
if (pots) {
|
||||
useable = 0;
|
||||
printf("\n -> Analog interfaces are not supported.");
|
||||
} else
|
||||
if (!useable)
|
||||
{
|
||||
} else if (!useable) {
|
||||
printf("unsupported interface protocol bits 0x%016x", devinfo.Dprotocols);
|
||||
}
|
||||
printf("\n %2d B-channels:", devinfo.nrbchan);
|
||||
c = 0;
|
||||
start_c = -1;
|
||||
while(c <= MISDN_MAX_CHANNEL + 1)
|
||||
{
|
||||
if (c <= MISDN_MAX_CHANNEL && test_channelmap(c, devinfo.channelmap))
|
||||
{
|
||||
while (c <= MISDN_MAX_CHANNEL + 1) {
|
||||
if (c <= MISDN_MAX_CHANNEL && test_channelmap(c, devinfo.channelmap)) {
|
||||
if (start_c < 0)
|
||||
start_c = c;
|
||||
} else
|
||||
{
|
||||
if (start_c >= 0)
|
||||
{
|
||||
if (c-1 == start_c)
|
||||
} else {
|
||||
if (start_c >= 0) {
|
||||
if (c - 1 == start_c)
|
||||
printf(" %d", start_c);
|
||||
else
|
||||
printf(" %d-%d", start_c, c-1);
|
||||
printf(" %d-%d", start_c, c - 1);
|
||||
start_c = -1;
|
||||
}
|
||||
}
|
||||
|
@ -178,36 +154,28 @@ int main(int argc, char *argv[])
|
|||
}
|
||||
printf("\n");
|
||||
printf(" B-protocols:");
|
||||
if (devinfo.Bprotocols & (1 << (ISDN_P_B_RAW & ISDN_P_B_MASK)))
|
||||
{
|
||||
if (devinfo.Bprotocols & (1 << (ISDN_P_B_RAW & ISDN_P_B_MASK))) {
|
||||
printf(" RAW");
|
||||
}
|
||||
if (devinfo.Bprotocols & (1 << (ISDN_P_B_HDLC & ISDN_P_B_MASK)))
|
||||
{
|
||||
if (devinfo.Bprotocols & (1 << (ISDN_P_B_HDLC & ISDN_P_B_MASK))) {
|
||||
printf(" HDLC");
|
||||
}
|
||||
if (devinfo.Bprotocols & (1 << (ISDN_P_B_X75SLP & ISDN_P_B_MASK)))
|
||||
{
|
||||
if (devinfo.Bprotocols & (1 << (ISDN_P_B_X75SLP & ISDN_P_B_MASK))) {
|
||||
printf(" X75slp");
|
||||
}
|
||||
if (devinfo.Bprotocols & (1 << (ISDN_P_B_L2DTMF & ISDN_P_B_MASK)))
|
||||
{
|
||||
if (devinfo.Bprotocols & (1 << (ISDN_P_B_L2DTMF & ISDN_P_B_MASK))) {
|
||||
printf(" L2:DTMF");
|
||||
}
|
||||
if (devinfo.Bprotocols & (1 << (ISDN_P_B_L2DSP & ISDN_P_B_MASK)))
|
||||
{
|
||||
if (devinfo.Bprotocols & (1 << (ISDN_P_B_L2DSP & ISDN_P_B_MASK))) {
|
||||
printf(" L2:DSP");
|
||||
}
|
||||
if (devinfo.Bprotocols & (1 << (ISDN_P_B_L2DSPHDLC & ISDN_P_B_MASK)))
|
||||
{
|
||||
if (devinfo.Bprotocols & (1 << (ISDN_P_B_L2DSPHDLC & ISDN_P_B_MASK))) {
|
||||
printf(" L2:DSPHDLC");
|
||||
}
|
||||
if (devinfo.Bprotocols & (1 << (ISDN_P_B_T30_FAX & ISDN_P_B_MASK)))
|
||||
{
|
||||
if (devinfo.Bprotocols & (1 << (ISDN_P_B_T30_FAX & ISDN_P_B_MASK))) {
|
||||
printf(" T30-Fax");
|
||||
}
|
||||
if (devinfo.Bprotocols & (1 << (ISDN_P_B_MODEM_ASYNC & ISDN_P_B_MASK)))
|
||||
{
|
||||
if (devinfo.Bprotocols & (1 << (ISDN_P_B_MODEM_ASYNC & ISDN_P_B_MASK))) {
|
||||
printf(" asnc.Modem");
|
||||
}
|
||||
printf("\n");
|
||||
|
@ -218,13 +186,12 @@ int main(int argc, char *argv[])
|
|||
printf(" --------\n");
|
||||
ii--;
|
||||
|
||||
next_dev:
|
||||
next_dev:
|
||||
i++;
|
||||
}
|
||||
printf("\n");
|
||||
|
||||
done:
|
||||
close(sock);
|
||||
return(0);
|
||||
return (0);
|
||||
}
|
||||
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,124 @@
|
|||
/*
|
||||
*
|
||||
* Copyright 2014 Karsten Keil <kkeil@linux-pingi.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
|
||||
* Foundation; either version 2 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, write to the Free Software Foundation, Inc., 59
|
||||
* Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*
|
||||
* The full GNU General Public License is included in this distribution in the
|
||||
* file called LICENSE.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef _LOGGER_H
|
||||
#define _LOGGER_H
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/socket.h>
|
||||
#include <netinet/udp.h>
|
||||
#include <netinet/in.h>
|
||||
#include <sys/syslog.h>
|
||||
#include <mISDN/mISDNif.h>
|
||||
#include <mISDN/mbuffer.h>
|
||||
|
||||
#define L3MT_SIZE 40
|
||||
#define LOGTXT_SIZE 1024
|
||||
#define MAX_FILE_NAME 256
|
||||
|
||||
struct mController {
|
||||
int mNr;
|
||||
int enable;
|
||||
int syslog;
|
||||
char logfile[MAX_FILE_NAME];
|
||||
char dumpfile[MAX_FILE_NAME];
|
||||
FILE *log;
|
||||
FILE *dump;
|
||||
int layer1;
|
||||
int layer2;
|
||||
unsigned char layer3[L3MT_SIZE];
|
||||
int protocol;
|
||||
int echo;
|
||||
int socket;
|
||||
struct sockaddr_mISDN addr;
|
||||
struct mISDN_devinfo devinfo;
|
||||
struct timeval *tv;
|
||||
char *lp;
|
||||
char logtxt[LOGTXT_SIZE];
|
||||
};
|
||||
|
||||
extern struct mController *defController;
|
||||
extern int mI_ControllerCount;
|
||||
|
||||
enum l3Values {
|
||||
l3vDISABLE = 0,
|
||||
l3vENABLE = 1,
|
||||
l3vVERBOSE = 2,
|
||||
l3vHEX = 4
|
||||
};
|
||||
|
||||
enum l2Values {
|
||||
l2vDISABLE = 0,
|
||||
l2vENABLE = 0x0001,
|
||||
l2vTEI = 0x0002,
|
||||
l2vSAPI = 0x0004,
|
||||
l2vCONTROL = 0x0008,
|
||||
l2vKEEPALIVE = 0x0010
|
||||
};
|
||||
|
||||
enum mTypes {
|
||||
mTunknown = 0,
|
||||
mTalerting,
|
||||
mTcall_proceeding,
|
||||
mTconnect,
|
||||
mTconnect_acknowledge,
|
||||
mTprogress,
|
||||
mTsetup,
|
||||
mTsetup_acknowledge,
|
||||
mTresume,
|
||||
mTresume_acknowledge,
|
||||
mTresume_reject,
|
||||
mTsuspend,
|
||||
mTsuspend_acknowledge,
|
||||
mTsuspend_reject,
|
||||
mTuser_information,
|
||||
mTdisconnect,
|
||||
mTrelease,
|
||||
mTrelease_complete,
|
||||
mTrestart,
|
||||
mTrestart_acknowledge,
|
||||
mTsegment,
|
||||
mTcongestion_control,
|
||||
mTinformation,
|
||||
mTfacility,
|
||||
mTnotify,
|
||||
mTstatus,
|
||||
mTstatus_enquiry,
|
||||
mThold,
|
||||
mThold_acknowledge,
|
||||
mThold_reject,
|
||||
mTretrieve,
|
||||
mTretrieve_acknowledge,
|
||||
mTretrieve_reject,
|
||||
mTregister,
|
||||
mTall
|
||||
};
|
||||
|
||||
extern const char *mTypesStr[];
|
||||
|
||||
|
||||
#define mlDEBUG_BASIC 0x01000000
|
||||
#define mlDEBUG_MESSAGE 0x02000000
|
||||
#define mlDEBUG_POLL 0x04000000
|
||||
|
||||
#endif /* _CALL_LOG_H */
|
|
@ -0,0 +1,554 @@
|
|||
WSP [ \t]
|
||||
NWSP [^ \t\n]
|
||||
VCHR [A-Za-z_]
|
||||
VCHRZ [A-Za-z_0-9]
|
||||
PATHCHR [A-Za-z_\/\.0-9]
|
||||
IDENT {VCHR}{VCHRZ}*
|
||||
LEXT \\\n
|
||||
LAYER [lL][aA][yY][eE][rR]
|
||||
ALL [aA][lL][lL]
|
||||
UNKNOWN [uU][nN][kK][nN][oO][wW][nN]
|
||||
ALERTING [aA][lL][eE][rR][tT][iI][nN][gG]
|
||||
CALL_PROCEEDING [cC][aA][lL][lL]_*[pP][rR][oO][cC][eE][eE][dD][iI][nN][gG]
|
||||
CONNECT [cC][oO][nN][nN][eE][cC][tT]
|
||||
CONNECT_ACKNOWLEDGE [cC][oO][nN][nN][eE][cC][tT]_*[aA][cC][kK][nN][oO][wW][lL][eE][dD][gG][eE]
|
||||
PROGRESS [pP][rR][oO][gG][rR][eE][sS][sS]
|
||||
SETUP [sS][eE][tT][uU][pP]
|
||||
SETUP_ACKNOWLEDGE [sS][eE][tT][uU][pP]_*[aA][cC][kK][nN][oO][wW][lL][eE][dD][gG][eE]
|
||||
RESUME [rR][eE][sS][uU][mM][eE]
|
||||
RESUME_ACKNOWLEDGE [rR][eE][sS][uU][mM][eE]_*[aA][cC][kK][nN][oO][wW][lL][eE][dD][gG][eE]
|
||||
RESUME_REJECT [rR][eE][sS][uU][mM][eE]_*[rR][eE][jJ][eE][cC][tT]
|
||||
SUSPEND [sS][uU][sS][pP][eE][nN][dD]
|
||||
SUSPEND_ACKNOWLEDGE [sS][uU][sS][pP][eE][nN][dD]_*[aA][cC][kK][nN][oO][wW][lL][eE][dD][gG][eE]
|
||||
SUSPEND_REJECT [sS][uU][sS][pP][eE][nN][dD]_*[rR][eE][jJ][eE][cC][tT]
|
||||
USER_INFORMATION [uU][sS][eE][rR]_*[iI][nN][fF][oO][rR][mM][aA][tT][iI][oO][nN]
|
||||
DISCONNECT [dD][iI][sS][cC][oO][nN][nN][eE][cC][tT]
|
||||
RELEASE [rR][eE][lL][eE][aA][sS][eE]
|
||||
RELEASE_COMPLETE [rR][eE][lL][eE][aA][sS][eE]_*[cC][oO][mM][pP][lL][eE][tT][eE]
|
||||
RESTART [rR][eE][sS][tT][aA][rR][tT]
|
||||
RESTART_ACKNOWLEDGE [rR][eE][sS][tT][aA][rR][tT]_*[aA][cC][kK][nN][oO][wW][lL][eE][dD][gG][eE]
|
||||
SEGMENT [sS][eE][gG][mM][eE][nN][tT]
|
||||
CONGESTION_CONTROL [cC][oO][nN][gG][eE][sS][tT][iI][oO][nN]_*[cC][oO][nN][tT][rR][oO][lL]
|
||||
INFORMATION [iI][nN][fF][oO][rR][mM][aA][tT][iI][oO][nN]
|
||||
FACILITY [fF][aA][cC][iI][lL][iI][tT][yY]
|
||||
NOTIFY [nN][oO][tT][iI][fF][yY]
|
||||
STATUS [sS][tT][aA][tT][uU][sS]
|
||||
STATUS_ENQUIRY [sS][tT][aA][tT][uU][sS]_*[eE][nN][qQ][uU][iI][rR][yY]
|
||||
HOLD [hH][oO][lL][dD]
|
||||
HOLD_ACKNOWLEDGE [hH][oO][lL][dD]_*[aA][cC][kK][nN][oO][wW][lL][eE][dD][gG][eE]
|
||||
HOLD_REJECT [hH][oO][lL][dD]_*[rR][eE][jJ][eE][cC][tT]
|
||||
RETRIEVE [rR][eE][tT][rR][iI][eE][vV][eE]
|
||||
RETRIEVE_ACKNOWLEDGE [rR][eE][tT][rR][iI][eE][vV][eE]_*[aA][cC][kK][nN][oO][wW][lL][eE][dD][gG][eE]
|
||||
RETRIEVE_REJECT [rR][eE][tT][rR][iI][eE][vV][eE]_*[rR][eE][jJ][eE][cC][tT]
|
||||
REGISTER [rR][eE][gG][iI][sS][tT][eE][rR]
|
||||
ECHO [eE][cC][hH][oO]
|
||||
TRUE [tT][rR][uU][eE]
|
||||
FALSE [fF][aA][lL][sS][eE]
|
||||
VERBOSE [vV][eE][rR][bB][oO][sS][eE]
|
||||
HEX [hH][eE][xX]
|
||||
HEXDUMP [hH][eE][xX][dD][uU][mM][pP]
|
||||
ENABLE [eE][nN][aA][bB][lL][eE]
|
||||
DISABLE [dD][iI][sS][aA][bB][lL][eE]
|
||||
CONTROLLER [cC][oO][nN][tT][rR][oO][lL][lL][eE][rR]
|
||||
KEEPALIVE [kK][eE][eE][pP][aA][lL][iI][vV][eE]
|
||||
TEI [tT][eE][iI]
|
||||
FULL [fF][uU][lL][lL]
|
||||
SAPI [sS][aA][pP][iI]
|
||||
ACTIVATE [aA][cC][tT][iI][vV][aA][tT][eE]
|
||||
DEACTIVATE [dD][eE][aA][cC][tT][iI][vV][aA][tT][eE]
|
||||
CONTROL [cC][oO][nN][tT][rR][oO][lL]
|
||||
SYSLOG [sS][yY][sS][lL][oO][gG]
|
||||
LOGFILE [lL][oO][gG][fF][iI][lL][eE]
|
||||
DUMPFILE [dD][uU][mM][pP][fF][iI][lL][eE]
|
||||
FRAMES [fF][rR][aA][mM][eE][sS]
|
||||
NOTICE [nN][oO][tT][iI][cC][eE]
|
||||
INFO [iI][nN][fF][oO]
|
||||
|
||||
|
||||
%option nounput
|
||||
%option noinput
|
||||
%option yylineno
|
||||
|
||||
%START Start Section EchoVal L1Value L2Value L3Type Level3 SysLog ErrorOut GetPath
|
||||
|
||||
%{
|
||||
#include "logger.h"
|
||||
|
||||
static int controller = -2;
|
||||
static int l3typ = -2;
|
||||
static int l3level = -2;
|
||||
static int filetyp = 0;
|
||||
static int l1_val = 0;
|
||||
static int l2_val = 0;
|
||||
static struct mController *currentController = NULL;
|
||||
|
||||
static int new_controller(void);
|
||||
static int setLayer3(int, int);
|
||||
|
||||
#define setValue(name, val) {\
|
||||
if (currentController) \
|
||||
currentController->name = val; \
|
||||
}
|
||||
%}
|
||||
|
||||
%%
|
||||
int ret;
|
||||
|
||||
|
||||
<Start>{
|
||||
#.* ;
|
||||
\[global\].* {
|
||||
if (controller != -2) {
|
||||
fprintf(stderr, "Line %d [global] section need to be the first section\n", yylineno);
|
||||
return -1;
|
||||
}
|
||||
controller = -1;
|
||||
new_controller();
|
||||
BEGIN Section;
|
||||
}
|
||||
\[{CONTROLLER}{WSP}*[0-9]+\].* {
|
||||
controller = atoi(yytext+11);
|
||||
ret = new_controller();
|
||||
if (ret < 0) {
|
||||
fprintf(stderr, "Line %d: '%s' Controller number %d is not valid\n", yylineno, yytext, controller);
|
||||
return -1;
|
||||
} else if (!ret) {
|
||||
fprintf(stderr, "Line %d: Controller %d was detected - ignored\n", yylineno, controller);
|
||||
}
|
||||
BEGIN Section;
|
||||
}
|
||||
\[[0-9]+\].* {
|
||||
controller = atoi(yytext+1);
|
||||
ret = new_controller();
|
||||
if (ret < 0) {
|
||||
fprintf(stderr, "Line %d: '%s' Controller number %d is not valid\n", yylineno, yytext, controller);
|
||||
return -1;
|
||||
} else if (!ret) {
|
||||
fprintf(stderr, "Line %d: Controller %d was detected - ignored\n", yylineno, controller);
|
||||
}
|
||||
BEGIN Section;
|
||||
}
|
||||
{LEXT} ;
|
||||
\n { }
|
||||
. {
|
||||
yyless(0);
|
||||
BEGIN ErrorOut;
|
||||
}
|
||||
}
|
||||
|
||||
<Section>{
|
||||
#.* ;
|
||||
{WSP}+ ;
|
||||
\[ {
|
||||
yyless(yyleng-1);
|
||||
BEGIN Start;
|
||||
}
|
||||
{ENABLE} setValue(enable, 1);
|
||||
{DISABLE} setValue(enable, 0);
|
||||
{ECHO} {
|
||||
BEGIN EchoVal;
|
||||
}
|
||||
{DUMPFILE}/{WSP} {filetyp = 1; BEGIN GetPath;}
|
||||
{LOGFILE}/{WSP} {filetyp = 2; BEGIN GetPath;}
|
||||
{SYSLOG}/{WSP} {
|
||||
BEGIN SysLog;
|
||||
}
|
||||
{LAYER}1/{WSP}* {
|
||||
BEGIN L1Value;
|
||||
}
|
||||
{LAYER}2/{WSP} {
|
||||
BEGIN L2Value;
|
||||
}
|
||||
{LAYER}3/{WSP} {
|
||||
l3typ =-1 ;
|
||||
BEGIN L3Type;
|
||||
}
|
||||
{LEXT} ;
|
||||
\n { }
|
||||
. {
|
||||
yyless(0);
|
||||
BEGIN ErrorOut;
|
||||
}
|
||||
}
|
||||
|
||||
<EchoVal>{
|
||||
{WSP}+ ;
|
||||
#.* ;
|
||||
{TRUE} |
|
||||
{ENABLE} setValue(echo, 1);
|
||||
{FALSE} |
|
||||
{DISABLE} setValue(echo, 0);
|
||||
{LEXT} ;
|
||||
\n {
|
||||
setValue(layer2, l2_val)
|
||||
BEGIN Section;
|
||||
}
|
||||
. {
|
||||
yyless(0);
|
||||
BEGIN ErrorOut;
|
||||
}
|
||||
}
|
||||
|
||||
<L1Value>{
|
||||
#.* ;
|
||||
{WSP}+ ;
|
||||
{TRUE} |
|
||||
{ENABLE} l1_val |= 1;
|
||||
{FALSE} |
|
||||
{DISABLE} l1_val = 0;
|
||||
\n {
|
||||
setValue(layer1, l1_val)
|
||||
BEGIN Section;
|
||||
}
|
||||
. {
|
||||
yyless(0);
|
||||
BEGIN ErrorOut;
|
||||
}
|
||||
}
|
||||
|
||||
<L2Value>{
|
||||
{WSP}+ ;
|
||||
#.* ;
|
||||
{TRUE} |
|
||||
{ENABLE} l2_val |= l2vENABLE;
|
||||
{TEI} l2_val |= l2vTEI;
|
||||
{SAPI} l2_val |= l2vSAPI;
|
||||
{CONTROL} l2_val |= l2vCONTROL;
|
||||
{KEEPALIVE} l2_val |= l2vKEEPALIVE;
|
||||
{FALSE} |
|
||||
{DISABLE} l2_val = l2vDISABLE;
|
||||
{LEXT} ;
|
||||
\n {
|
||||
setValue(layer2, l2_val)
|
||||
BEGIN Section;
|
||||
}
|
||||
. {
|
||||
yyless(0);
|
||||
BEGIN ErrorOut;
|
||||
}
|
||||
}
|
||||
|
||||
<L3Type>{
|
||||
{WSP}+ ;
|
||||
{ALL} {
|
||||
l3typ = mTall;
|
||||
l3level = l3vDISABLE;
|
||||
BEGIN Level3;
|
||||
}
|
||||
{UNKNOWN} {
|
||||
l3typ = mTunknown;
|
||||
l3level = currentController ? currentController->layer3[l3typ] : 0;
|
||||
BEGIN Level3;
|
||||
}
|
||||
{ALERTING} {
|
||||
l3typ = mTalerting;
|
||||
l3level = currentController ? currentController->layer3[l3typ] : 0;
|
||||
BEGIN Level3;
|
||||
}
|
||||
{CALL_PROCEEDING} {
|
||||
l3typ = mTcall_proceeding;
|
||||
l3level = currentController ? currentController->layer3[l3typ] : 0;
|
||||
BEGIN Level3;
|
||||
}
|
||||
{CONNECT} {
|
||||
l3typ = mTconnect;
|
||||
l3level = currentController ? currentController->layer3[l3typ] : 0;
|
||||
BEGIN Level3;
|
||||
}
|
||||
{CONNECT_ACKNOWLEDGE} {
|
||||
l3typ = mTconnect_acknowledge;
|
||||
l3level = currentController ? currentController->layer3[l3typ] : 0;
|
||||
BEGIN Level3;
|
||||
}
|
||||
{PROGRESS} {
|
||||
l3typ = mTprogress;
|
||||
l3level = currentController ? currentController->layer3[l3typ] : 0;
|
||||
BEGIN Level3;
|
||||
}
|
||||
{SETUP} {
|
||||
l3typ = mTsetup;
|
||||
l3level = currentController ? currentController->layer3[l3typ] : 0;
|
||||
BEGIN Level3;
|
||||
}
|
||||
{SETUP_ACKNOWLEDGE} {
|
||||
l3typ = mTsetup_acknowledge;
|
||||
l3level = currentController ? currentController->layer3[l3typ] : 0;
|
||||
BEGIN Level3;
|
||||
}
|
||||
{RESUME} {
|
||||
l3typ = mTresume;
|
||||
l3level = currentController ? currentController->layer3[l3typ] : 0;
|
||||
BEGIN Level3;
|
||||
}
|
||||
{RESUME_ACKNOWLEDGE} {
|
||||
l3typ = mTresume_acknowledge;
|
||||
l3level = currentController ? currentController->layer3[l3typ] : 0;
|
||||
BEGIN Level3;
|
||||
}
|
||||
{RESUME_REJECT} {
|
||||
l3typ = mTresume_reject;
|
||||
l3level = currentController ? currentController->layer3[l3typ] : 0;
|
||||
BEGIN Level3;
|
||||
}
|
||||
{SUSPEND} {
|
||||
l3typ = mTsuspend;
|
||||
l3level = currentController ? currentController->layer3[l3typ] : 0;
|
||||
BEGIN Level3;
|
||||
}
|
||||
{SUSPEND_ACKNOWLEDGE} {
|
||||
l3typ = mTsuspend_acknowledge;
|
||||
l3level = currentController ? currentController->layer3[l3typ] : 0;
|
||||
BEGIN Level3;
|
||||
}
|
||||
{SUSPEND_REJECT} {
|
||||
l3typ = mTsuspend_reject;
|
||||
l3level = currentController ? currentController->layer3[l3typ] : 0;
|
||||
BEGIN Level3;
|
||||
}
|
||||
{USER_INFORMATION} {
|
||||
l3typ = mTuser_information;
|
||||
l3level = currentController ? currentController->layer3[l3typ] : 0;
|
||||
BEGIN Level3;
|
||||
}
|
||||
{DISCONNECT} {
|
||||
l3typ = mTdisconnect;
|
||||
l3level = currentController ? currentController->layer3[l3typ] : 0;
|
||||
BEGIN Level3;
|
||||
}
|
||||
{RELEASE} {
|
||||
l3typ = mTrelease;
|
||||
l3level = currentController ? currentController->layer3[l3typ] : 0;
|
||||
BEGIN Level3;
|
||||
}
|
||||
{RELEASE_COMPLETE} {
|
||||
l3typ = mTrelease_complete;
|
||||
l3level = currentController ? currentController->layer3[l3typ] : 0;
|
||||
BEGIN Level3;
|
||||
}
|
||||
{RESTART} {
|
||||
l3typ = mTrestart;
|
||||
l3level = currentController ? currentController->layer3[l3typ] : 0;
|
||||
BEGIN Level3;
|
||||
}
|
||||
{RESTART_ACKNOWLEDGE} {
|
||||
l3typ = mTrestart_acknowledge;
|
||||
l3level = currentController ? currentController->layer3[l3typ] : 0;
|
||||
BEGIN Level3;
|
||||
}
|
||||
{SEGMENT} {
|
||||
l3typ = mTsegment;
|
||||
l3level = currentController ? currentController->layer3[l3typ] : 0;
|
||||
BEGIN Level3;
|
||||
}
|
||||
{CONGESTION_CONTROL} {
|
||||
l3typ = mTcongestion_control;
|
||||
l3level = currentController ? currentController->layer3[l3typ] : 0;
|
||||
BEGIN Level3;
|
||||
}
|
||||
{INFORMATION} {
|
||||
l3typ = mTinformation;
|
||||
l3level = currentController ? currentController->layer3[l3typ] : 0;
|
||||
BEGIN Level3;
|
||||
}
|
||||
{FACILITY} {
|
||||
l3typ = mTfacility;
|
||||
l3level = currentController ? currentController->layer3[l3typ] : 0;
|
||||
BEGIN Level3;
|
||||
}
|
||||
{NOTIFY} {
|
||||
l3typ = mTnotify;
|
||||
l3level = currentController ? currentController->layer3[l3typ] : 0;
|
||||
BEGIN Level3;
|
||||
}
|
||||
{STATUS} {
|
||||
l3typ = mTstatus;
|
||||
l3level = currentController ? currentController->layer3[l3typ] : 0;
|
||||
BEGIN Level3;
|
||||
}
|
||||
{STATUS_ENQUIRY} {
|
||||
l3typ = mTstatus_enquiry;
|
||||
l3level = currentController ? currentController->layer3[l3typ] : 0;
|
||||
BEGIN Level3;
|
||||
}
|
||||
{HOLD} {
|
||||
l3typ = mThold;
|
||||
l3level = currentController ? currentController->layer3[l3typ] : 0;
|
||||
BEGIN Level3;
|
||||
}
|
||||
{HOLD_ACKNOWLEDGE} {
|
||||
l3typ = mThold_acknowledge;
|
||||
l3level = currentController ? currentController->layer3[l3typ] : 0;
|
||||
BEGIN Level3;
|
||||
}
|
||||
{HOLD_REJECT} {
|
||||
l3typ = mThold_reject;
|
||||
l3level = currentController ? currentController->layer3[l3typ] : 0;
|
||||
BEGIN Level3;
|
||||
}
|
||||
{RETRIEVE} {
|
||||
l3typ = mTretrieve;
|
||||
l3level = currentController ? currentController->layer3[l3typ] : 0;
|
||||
BEGIN Level3;
|
||||
}
|
||||
{RETRIEVE_ACKNOWLEDGE} {
|
||||
l3typ = mTretrieve_acknowledge;
|
||||
l3level = currentController ? currentController->layer3[l3typ] : 0;
|
||||
BEGIN Level3;
|
||||
}
|
||||
{RETRIEVE_REJECT} {
|
||||
l3typ = mTretrieve_reject;
|
||||
l3level = currentController ? currentController->layer3[l3typ] : 0;
|
||||
BEGIN Level3;
|
||||
}
|
||||
{REGISTER} {
|
||||
l3typ = mTregister;
|
||||
l3level = currentController ? currentController->layer3[l3typ] : 0;
|
||||
BEGIN Level3;
|
||||
}
|
||||
{LEXT} ;
|
||||
. {
|
||||
yyless(0);
|
||||
BEGIN ErrorOut;
|
||||
}
|
||||
}
|
||||
|
||||
<Level3>{
|
||||
{WSP}+ ;
|
||||
#.* ;
|
||||
{DISABLE} |
|
||||
{FALSE} l3level = l3vDISABLE;
|
||||
{ENABLE} |
|
||||
{TRUE} l3level |= l3vENABLE;
|
||||
{VERBOSE} l3level |= l3vVERBOSE;
|
||||
{HEX} |
|
||||
{HEXDUMP} l3level |= l3vHEX;
|
||||
[0-7] l3level = atoi(yytext);
|
||||
\n {
|
||||
if (setLayer3(l3typ, l3level))
|
||||
return -1;
|
||||
l3typ = -2;
|
||||
l3level = -2;
|
||||
BEGIN Section;
|
||||
}
|
||||
. {
|
||||
yyless(0);
|
||||
BEGIN ErrorOut;
|
||||
}
|
||||
}
|
||||
|
||||
<SysLog>{
|
||||
{WSP}+ ;
|
||||
#.* ;
|
||||
{FALSE} setValue(syslog, 0);
|
||||
{TRUE} |
|
||||
{INFO} setValue(syslog, LOG_INFO);
|
||||
{NOTICE} setValue(syslog, LOG_NOTICE);
|
||||
. {
|
||||
yyless(0);
|
||||
BEGIN ErrorOut;
|
||||
}
|
||||
{LEXT} ;
|
||||
\n BEGIN Section;
|
||||
}
|
||||
|
||||
<GetPath>{
|
||||
{WSP}+ ;
|
||||
#.* ;
|
||||
{PATHCHR}+/[ \t#\n]* {
|
||||
if (currentController) {
|
||||
if (filetyp == 1) {
|
||||
if (defController == currentController)
|
||||
fprintf(stderr, "dumpfile ignored for global section\n");
|
||||
else
|
||||
strncpy(currentController->dumpfile, yytext, MAX_FILE_NAME - 1);
|
||||
} else if (filetyp == 2) {
|
||||
strncpy(currentController->logfile, yytext, MAX_FILE_NAME - 1);
|
||||
} else {
|
||||
fprintf(stderr, "Got unhandled filetype %d with %s - abort\n", filetyp, yytext);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
filetyp = 0;
|
||||
}
|
||||
{LEXT} ;
|
||||
\n {
|
||||
if (filetyp) {
|
||||
fprintf(stderr, "Need file path argument for filetyp=%d\n", filetyp);
|
||||
return -1;
|
||||
}
|
||||
BEGIN Section;
|
||||
}
|
||||
. {
|
||||
yyless(0);
|
||||
BEGIN ErrorOut;
|
||||
}
|
||||
}
|
||||
|
||||
<ErrorOut>{
|
||||
.+ {
|
||||
fprintf(stderr, "Unknown item '%s' on line %d\n", yytext, yyget_lineno());
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
%%
|
||||
|
||||
|
||||
static int new_controller(void)
|
||||
{
|
||||
if (controller >= mI_ControllerCount) {
|
||||
currentController = NULL;
|
||||
return 0;
|
||||
}
|
||||
if (controller == -1) { /* global */
|
||||
currentController = defController;
|
||||
l1_val = 0;
|
||||
l2_val = 0;
|
||||
return 1;
|
||||
}
|
||||
if (controller < 0) {
|
||||
currentController = NULL;
|
||||
return -1;
|
||||
}
|
||||
currentController = &defController[controller + 1];
|
||||
/* set defaults */
|
||||
memcpy(currentController, defController, sizeof(*currentController));
|
||||
currentController->mNr = controller;
|
||||
l1_val = currentController->layer1;
|
||||
l2_val = currentController->layer2;
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int setLayer3(int typ, int level)
|
||||
{
|
||||
if (!currentController)
|
||||
return 0;
|
||||
if (typ == mTall) {
|
||||
int i;
|
||||
for (i = 0; i < mTall; i++)
|
||||
currentController->layer3[i] = level;
|
||||
} else if (typ < 0 || typ > mTall) {
|
||||
fprintf(stderr, "Line %d: layer3 message type %d out of range\n", yyget_lineno(), typ);
|
||||
return -1;
|
||||
} else
|
||||
currentController->layer3[typ] = level;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int yywrap(void)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
int parse_config(FILE *f)
|
||||
{
|
||||
int ret;
|
||||
|
||||
yyin = f;
|
||||
BEGIN Start;
|
||||
ret = yylex();
|
||||
yylex_destroy();
|
||||
return ret;
|
||||
}
|
||||
|
324
tools/loghex.c
324
tools/loghex.c
|
@ -1,5 +1,6 @@
|
|||
/*
|
||||
*
|
||||
* Copyright 2015 Karsten Keil <keil@b1-systems.de>
|
||||
* Copyright 2008 Karsten Keil <kkeil@suse.de>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
|
@ -41,26 +42,24 @@
|
|||
|
||||
static int dch_echo = 0;
|
||||
|
||||
static void usage(pname)
|
||||
char *pname;
|
||||
static void usage(char *pname)
|
||||
{
|
||||
fprintf(stderr,"Call with %s [options]\n",pname);
|
||||
fprintf(stderr,"\n");
|
||||
fprintf(stderr,"\n Valid options are:\n");
|
||||
fprintf(stderr,"\n");
|
||||
fprintf(stderr," -? Usage ; printout this information\n");
|
||||
fprintf(stderr," -c<n> use card number n (default 0)\n");
|
||||
fprintf(stderr," -e try using echo channel for TX data\n");
|
||||
fprintf(stderr," -w <file> write wiresharkdump <file>\n");
|
||||
fprintf(stderr,"\n");
|
||||
fprintf(stderr, "Call with %s [options]\n", pname);
|
||||
fprintf(stderr, "\n");
|
||||
fprintf(stderr, "\n Valid options are:\n");
|
||||
fprintf(stderr, "\n");
|
||||
fprintf(stderr, " -? Usage ; printout this information\n");
|
||||
fprintf(stderr, " -c<n> use card number n (default 0)\n");
|
||||
fprintf(stderr, " -e try using echo channel for TX data\n");
|
||||
fprintf(stderr, " -w <file> write wiresharkdump <file>\n");
|
||||
fprintf(stderr, "\n");
|
||||
}
|
||||
|
||||
|
||||
static void write_esc (FILE *file, unsigned char *buf, int len)
|
||||
static void write_esc(FILE * file, unsigned char *buf, int len)
|
||||
{
|
||||
int i, byte;
|
||||
int i, byte;
|
||||
|
||||
for (i = 0; i < len; ++i) {
|
||||
for (i = 0; i < len; ++i) {
|
||||
byte = buf[i];
|
||||
if (byte == 0xff || byte == 0xfe) {
|
||||
fputc(0xfe, file);
|
||||
|
@ -75,10 +74,10 @@ static void write_esc (FILE *file, unsigned char *buf, int len)
|
|||
}
|
||||
}
|
||||
|
||||
static void write_wfile(FILE *f, unsigned char *buf, int len, struct timeval *tv, int protocol)
|
||||
static void write_wfile(FILE * f, unsigned char *buf, int len, struct timeval *tv, int protocol)
|
||||
{
|
||||
struct mISDNhead *hh = (struct mISDNhead *)buf;
|
||||
u_char head[12], origin;
|
||||
struct mISDNhead *hh = (struct mISDNhead *)buf;
|
||||
u_char head[12], origin;
|
||||
|
||||
/* skip PH_DATA_REQ if PH_DATA_E_IND are expected */
|
||||
if (dch_echo && (hh->prim == PH_DATA_REQ))
|
||||
|
@ -87,15 +86,13 @@ static void write_wfile(FILE *f, unsigned char *buf, int len, struct timeval *tv
|
|||
if (!dch_echo && (hh->prim == PH_DATA_E_IND))
|
||||
return;
|
||||
/* skip all none data */
|
||||
if ((hh->prim != PH_DATA_REQ) && (hh->prim != PH_DATA_IND) &&
|
||||
(hh->prim != PH_DATA_E_IND))
|
||||
if ((hh->prim != PH_DATA_REQ) && (hh->prim != PH_DATA_IND) && (hh->prim != PH_DATA_E_IND))
|
||||
return;
|
||||
|
||||
if (protocol == ISDN_P_NT_S0 || 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;
|
||||
origin = ((hh->prim == PH_DATA_REQ) || (hh->prim == PH_DATA_E_IND)) ? 1 : 0;
|
||||
|
||||
len -= MISDN_HEADER_LEN;
|
||||
|
||||
|
@ -109,26 +106,25 @@ static void write_wfile(FILE *f, unsigned char *buf, int len, struct timeval *tv
|
|||
head[5] = (unsigned char)(0xff & (tv->tv_sec >> 16));
|
||||
head[6] = (unsigned char)(0xff & (tv->tv_sec >> 8));
|
||||
head[7] = (unsigned char)(0xff & tv->tv_sec);
|
||||
head[8] = (unsigned char) 0;
|
||||
head[9] = (unsigned char) origin;
|
||||
head[10]= (unsigned char)(0xff & (len >> 8));
|
||||
head[11]= (unsigned char)(0xff & len);
|
||||
head[8] = (unsigned char)0;
|
||||
head[9] = (unsigned char)origin;
|
||||
head[10] = (unsigned char)(0xff & (len >> 8));
|
||||
head[11] = (unsigned char)(0xff & len);
|
||||
|
||||
write_esc(f, head, 12);
|
||||
write_esc(f, &buf[MISDN_HEADER_LEN], len);
|
||||
fflush(f);
|
||||
}
|
||||
|
||||
|
||||
static void printhex(unsigned char *p, int len, int head)
|
||||
{
|
||||
int i,j;
|
||||
int i, j;
|
||||
|
||||
for (i = 1; i <= len; i++) {
|
||||
printf(" %02x", *p++);
|
||||
if ((i!=len) && !(i % 4) && (i % 16))
|
||||
if ((i != len) && !(i % 4) && (i % 16))
|
||||
printf(" ");
|
||||
if ((i!=len) && !(i % 16)) {
|
||||
if ((i != len) && !(i % 16)) {
|
||||
printf("\n");
|
||||
for (j = 0; j < head; j++)
|
||||
printf(" ");
|
||||
|
@ -138,81 +134,80 @@ static void printhex(unsigned char *p, int len, int head)
|
|||
}
|
||||
|
||||
struct ctstamp {
|
||||
size_t cmsg_len;
|
||||
int cmsg_level;
|
||||
int cmsg_type;
|
||||
struct timeval tv;
|
||||
size_t cmsg_len;
|
||||
int cmsg_level;
|
||||
int cmsg_type;
|
||||
struct timeval tv;
|
||||
};
|
||||
|
||||
int
|
||||
main(argc, argv)
|
||||
int argc;
|
||||
char *argv[];
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
int aidx=1, idx, i, channel;
|
||||
int cardnr = 0;
|
||||
int log_socket;
|
||||
struct sockaddr_mISDN log_addr;
|
||||
int buflen = 512;
|
||||
char sw;
|
||||
char wfilename[512];
|
||||
int head = 0;
|
||||
char *pn, pns[32];
|
||||
u_char buffer[buflen];
|
||||
struct msghdr mh;
|
||||
struct iovec iov[1];
|
||||
struct ctstamp cts;
|
||||
struct tm *mt;
|
||||
int result;
|
||||
int opt;
|
||||
u_int cnt;
|
||||
struct mISDN_devinfo di;
|
||||
struct mISDNhead *hh;
|
||||
struct mISDNversion ver;
|
||||
FILE *wfile = NULL;
|
||||
int aidx = 1, idx, i, channel;
|
||||
int cardnr = 0;
|
||||
int log_socket;
|
||||
struct sockaddr_mISDN log_addr;
|
||||
int buflen = 512;
|
||||
char sw;
|
||||
char wfilename[512];
|
||||
int head = 0;
|
||||
const char *pn;
|
||||
char pns[32];
|
||||
u_char buffer[buflen];
|
||||
struct msghdr mh;
|
||||
struct iovec iov[1];
|
||||
struct ctstamp cts;
|
||||
struct tm *mt;
|
||||
int result;
|
||||
int opt;
|
||||
u_int cnt;
|
||||
struct mISDN_devinfo di;
|
||||
struct mISDNhead *hh;
|
||||
struct mISDNversion ver;
|
||||
FILE *wfile = NULL;
|
||||
|
||||
*wfilename = 0;
|
||||
while (aidx < argc) {
|
||||
if (argv[aidx] && argv[aidx][0]=='-') {
|
||||
sw=argv[aidx][1];
|
||||
if (argv[aidx] && argv[aidx][0] == '-') {
|
||||
sw = argv[aidx][1];
|
||||
switch (sw) {
|
||||
case 'c':
|
||||
if (argv[aidx][2]) {
|
||||
cardnr=atol(&argv[aidx][2]);
|
||||
}
|
||||
break;
|
||||
case 'w':
|
||||
if (!argv[aidx][2]) {
|
||||
idx = 0;
|
||||
aidx++;
|
||||
} else {
|
||||
idx=2;
|
||||
}
|
||||
if (aidx<=argc) {
|
||||
if (512 <= strlen(&argv[aidx][idx])) {
|
||||
fprintf(stderr," -w filename too long\n");
|
||||
exit(1);
|
||||
}
|
||||
strcpy(wfilename, &argv[aidx][idx]);
|
||||
} else {
|
||||
fprintf(stderr," Switch %c without value\n",sw);
|
||||
case 'c':
|
||||
if (argv[aidx][2]) {
|
||||
cardnr = atol(&argv[aidx][2]);
|
||||
}
|
||||
break;
|
||||
case 'w':
|
||||
if (!argv[aidx][2]) {
|
||||
idx = 0;
|
||||
aidx++;
|
||||
} else {
|
||||
idx = 2;
|
||||
}
|
||||
if (aidx <= argc) {
|
||||
if (512 <= strlen(&argv[aidx][idx])) {
|
||||
fprintf(stderr, " -w filename too long\n");
|
||||
exit(1);
|
||||
}
|
||||
break;
|
||||
case 'e':
|
||||
dch_echo = 1;
|
||||
break;
|
||||
case '?' :
|
||||
usage(argv[0]);
|
||||
strcpy(wfilename, &argv[aidx][idx]);
|
||||
} else {
|
||||
fprintf(stderr, " Switch %c without value\n", sw);
|
||||
exit(1);
|
||||
break;
|
||||
default : fprintf(stderr,"Unknown Switch %c\n",sw);
|
||||
usage(argv[0]);
|
||||
exit(1);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case 'e':
|
||||
dch_echo = 1;
|
||||
break;
|
||||
case '?':
|
||||
usage(argv[0]);
|
||||
exit(1);
|
||||
break;
|
||||
default:
|
||||
fprintf(stderr, "Unknown Switch %c\n", sw);
|
||||
usage(argv[0]);
|
||||
exit(1);
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
fprintf(stderr,"Undefined argument %s\n",argv[aidx]);
|
||||
} else {
|
||||
fprintf(stderr, "Undefined argument %s\n", argv[aidx]);
|
||||
usage(argv[0]);
|
||||
exit(1);
|
||||
}
|
||||
|
@ -220,7 +215,7 @@ char *argv[];
|
|||
}
|
||||
|
||||
if (cardnr < 0) {
|
||||
fprintf(stderr,"card nr may not be negative\n");
|
||||
fprintf(stderr, "card nr may not be negative\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
|
@ -235,7 +230,8 @@ char *argv[];
|
|||
exit(1);
|
||||
}
|
||||
if (ver.release & MISDN_GIT_RELEASE)
|
||||
printf("mISDN kernel version %d.%02d.%d (git.misdn.eu) found\n", ver.major, ver.minor, ver.release & ~MISDN_GIT_RELEASE);
|
||||
printf("mISDN kernel version %d.%02d.%d (git.misdn.eu) found\n", ver.major, ver.minor,
|
||||
ver.release & ~MISDN_GIT_RELEASE);
|
||||
else
|
||||
printf("mISDN kernel version %d.%02d.%d found\n", ver.major, ver.minor, ver.release);
|
||||
|
||||
|
@ -251,7 +247,7 @@ char *argv[];
|
|||
printf("ioctl error %s\n", strerror(errno));
|
||||
exit(1);
|
||||
} else
|
||||
printf("%d controller%s found\n", cnt, (cnt==1)?"":"s");
|
||||
printf("%d controller%s found\n", cnt, (cnt == 1) ? "" : "s");
|
||||
|
||||
di.id = cardnr;
|
||||
result = ioctl(log_socket, IMGETDEVINFO, &di);
|
||||
|
@ -272,7 +268,7 @@ char *argv[];
|
|||
|
||||
close(log_socket);
|
||||
|
||||
if (di.protocol == ISDN_P_NONE) /* default TE */
|
||||
if (di.protocol == ISDN_P_NONE) /* default TE */
|
||||
di.protocol = ISDN_P_TE_S0;
|
||||
|
||||
if ((log_socket = socket(PF_ISDN, SOCK_DGRAM, di.protocol)) < 0) {
|
||||
|
@ -289,8 +285,7 @@ char *argv[];
|
|||
|
||||
while ((result < 0) && (channel >= 0)) {
|
||||
log_addr.channel = (unsigned char)channel;
|
||||
result = bind(log_socket, (struct sockaddr *) &log_addr,
|
||||
sizeof(log_addr));
|
||||
result = bind(log_socket, (struct sockaddr *)&log_addr, sizeof(log_addr));
|
||||
printf("log bind ch(%i) return %d\n", log_addr.channel, result);
|
||||
if (result < 0) {
|
||||
printf("log bind error %s\n", strerror(errno));
|
||||
|
@ -345,75 +340,76 @@ char *argv[];
|
|||
printf("received message with msg_flags(%x)\n", mh.msg_flags);
|
||||
}
|
||||
if (cts.cmsg_type == MISDN_TIME_STAMP) {
|
||||
mt = localtime((time_t *)&cts.tv.tv_sec);
|
||||
head = printf("%02d.%02d.%04d %02d:%02d:%02d.%06ld", mt->tm_mday, mt->tm_mon + 1, mt->tm_year + 1900,
|
||||
mt->tm_hour, mt->tm_min, mt->tm_sec, cts.tv.tv_usec);
|
||||
mt = localtime((time_t *) & cts.tv.tv_sec);
|
||||
head =
|
||||
printf("%02d.%02d.%04d %02d:%02d:%02d.%06ld", mt->tm_mday, mt->tm_mon + 1, mt->tm_year + 1900,
|
||||
mt->tm_hour, mt->tm_min, mt->tm_sec, cts.tv.tv_usec);
|
||||
} else {
|
||||
cts.tv.tv_sec = 0;
|
||||
cts.tv.tv_usec = 0;
|
||||
}
|
||||
switch (hh->prim) {
|
||||
case PH_DATA_E_IND:
|
||||
pn = "ECHO IND";
|
||||
break;
|
||||
case PH_DATA_IND:
|
||||
pn = "DATA IND";
|
||||
break;
|
||||
case PH_DATA_REQ:
|
||||
pn = "DATA REQ";
|
||||
break;
|
||||
case PH_DATA_CNF:
|
||||
pn = "DATA CNF";
|
||||
break;
|
||||
case PH_ACTIVATE_IND:
|
||||
pn = "ACTIVATE IND";
|
||||
break;
|
||||
case PH_ACTIVATE_REQ:
|
||||
pn = "ACTIVATE REQ";
|
||||
break;
|
||||
case PH_ACTIVATE_CNF:
|
||||
pn = "ACTIVATE CNF";
|
||||
break;
|
||||
case PH_DEACTIVATE_IND:
|
||||
pn = "DEACTIVATE IND";
|
||||
break;
|
||||
case PH_DEACTIVATE_REQ:
|
||||
pn = "DEACTIVATE REQ";
|
||||
break;
|
||||
case PH_DEACTIVATE_CNF:
|
||||
pn = "DEACTIVATE CNF";
|
||||
break;
|
||||
case MPH_ACTIVATE_IND:
|
||||
pn = "MPH ACTIVATE IND";
|
||||
break;
|
||||
case MPH_ACTIVATE_REQ:
|
||||
pn = "MPH ACTIVATE REQ";
|
||||
break;
|
||||
case MPH_INFORMATION_REQ:
|
||||
pn = "MPH INFORMATION REQ";
|
||||
break;
|
||||
case MPH_DEACTIVATE_IND:
|
||||
pn = "MPH DEACTIVATE IND";
|
||||
break;
|
||||
case MPH_DEACTIVATE_REQ:
|
||||
pn = "MPH DEACTIVATE REQ";
|
||||
break;
|
||||
case MPH_INFORMATION_IND:
|
||||
pn = "MPH INFORMATION IND";
|
||||
break;
|
||||
case PH_CONTROL_REQ:
|
||||
pn = "PH CONTROL REQ";
|
||||
break;
|
||||
case PH_CONTROL_IND:
|
||||
pn = "PH CONTROL IND";
|
||||
break;
|
||||
case PH_CONTROL_CNF:
|
||||
pn = "PH CONTROL CNF";
|
||||
break;
|
||||
default:
|
||||
sprintf(pns,"Unknown %04x", hh->prim);
|
||||
pn = pns;
|
||||
break;
|
||||
case PH_DATA_E_IND:
|
||||
pn = "ECHO IND";
|
||||
break;
|
||||
case PH_DATA_IND:
|
||||
pn = "DATA IND";
|
||||
break;
|
||||
case PH_DATA_REQ:
|
||||
pn = "DATA REQ";
|
||||
break;
|
||||
case PH_DATA_CNF:
|
||||
pn = "DATA CNF";
|
||||
break;
|
||||
case PH_ACTIVATE_IND:
|
||||
pn = "ACTIVATE IND";
|
||||
break;
|
||||
case PH_ACTIVATE_REQ:
|
||||
pn = "ACTIVATE REQ";
|
||||
break;
|
||||
case PH_ACTIVATE_CNF:
|
||||
pn = "ACTIVATE CNF";
|
||||
break;
|
||||
case PH_DEACTIVATE_IND:
|
||||
pn = "DEACTIVATE IND";
|
||||
break;
|
||||
case PH_DEACTIVATE_REQ:
|
||||
pn = "DEACTIVATE REQ";
|
||||
break;
|
||||
case PH_DEACTIVATE_CNF:
|
||||
pn = "DEACTIVATE CNF";
|
||||
break;
|
||||
case MPH_ACTIVATE_IND:
|
||||
pn = "MPH ACTIVATE IND";
|
||||
break;
|
||||
case MPH_ACTIVATE_REQ:
|
||||
pn = "MPH ACTIVATE REQ";
|
||||
break;
|
||||
case MPH_INFORMATION_REQ:
|
||||
pn = "MPH INFORMATION REQ";
|
||||
break;
|
||||
case MPH_DEACTIVATE_IND:
|
||||
pn = "MPH DEACTIVATE IND";
|
||||
break;
|
||||
case MPH_DEACTIVATE_REQ:
|
||||
pn = "MPH DEACTIVATE REQ";
|
||||
break;
|
||||
case MPH_INFORMATION_IND:
|
||||
pn = "MPH INFORMATION IND";
|
||||
break;
|
||||
case PH_CONTROL_REQ:
|
||||
pn = "PH CONTROL REQ";
|
||||
break;
|
||||
case PH_CONTROL_IND:
|
||||
pn = "PH CONTROL IND";
|
||||
break;
|
||||
case PH_CONTROL_CNF:
|
||||
pn = "PH CONTROL CNF";
|
||||
break;
|
||||
default:
|
||||
sprintf(pns, "Unknown %04x", hh->prim);
|
||||
pn = pns;
|
||||
break;
|
||||
}
|
||||
head += printf(" %s id=%08x", pn, hh->id);
|
||||
if (wfile && (result > MISDN_HEADER_LEN))
|
||||
|
|
|
@ -0,0 +1,43 @@
|
|||
# example config file for misdnlogger
|
||||
#
|
||||
# A section for a not detected controller is ignored
|
||||
#
|
||||
# global section, set default values for all controllers need to be placed before any controller section
|
||||
[global]
|
||||
# log to syslog
|
||||
syslog true
|
||||
# logfile name - should be used only aternatively to syslog because same info get written twice
|
||||
# logfile /var/log/misdn.log
|
||||
enable # default all found controllers are enabled
|
||||
echo enable # enable use of echo channel if controller supports it
|
||||
# Layer1 activation/deactivation logging (enable or disable)
|
||||
Layer1 enable
|
||||
# Layer2 logging any combination of disable enable tei control sapi keepalive
|
||||
# tei - TEI managment logged
|
||||
# control - L2 establish/release logged
|
||||
# sapi - other SAPI values (e.g. X.31 logged)
|
||||
# keepalive - RR/RNR messages logged
|
||||
Layer2 enable
|
||||
# Layer3 loglevel defines values for each message type
|
||||
# the loglevel value could be a combination of disable enable verbose hexdump
|
||||
# message type all - for all messages (need be first)
|
||||
# message type unknown - for unknown L3 message types (e.g. coding/transmit errors)
|
||||
# enable - only the message type is logged
|
||||
# verbose - all used infoelements of the message are logged
|
||||
# hexdump - the complete L3 message is dumped in hex
|
||||
Layer3 all enable
|
||||
Layer3 unknown hexdump
|
||||
Layer3 Setup verbose
|
||||
Layer3 SetupAcknowledge verbose
|
||||
Layer3 Information verbose
|
||||
Layer3 Connect verbose
|
||||
Layer3 ConnectAcknowledge verbose
|
||||
Layer3 Disconnect verbose
|
||||
Layer3 Release verbose
|
||||
Layer3 Status verbose
|
||||
[0] # short for controller 0
|
||||
#config for controller 0
|
||||
echo disable # disable use of ECHO channel
|
||||
[controller 1] #config for controller 1
|
||||
Layer2 tei sapi control
|
||||
logfile /tmp/misdn.log
|
|
@ -8,8 +8,7 @@
|
|||
** **
|
||||
** user space utility to rename a mISDN device **
|
||||
** **
|
||||
\*****************************************************************************/
|
||||
|
||||
\*****************************************************************************/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
@ -31,19 +30,17 @@ int main(int argc, char *argv[])
|
|||
int sock;
|
||||
|
||||
if (argc != 3) {
|
||||
fprintf(stderr,"Usage: %s <old name or ID> <new name>\n",
|
||||
argv[0]);
|
||||
fprintf(stderr, "Usage: %s <old name or ID> <new name>\n", argv[0]);
|
||||
exit(2);
|
||||
}
|
||||
if (! argv[2][0] || strlen(argv[2]) >= MISDN_MAX_IDLEN) {
|
||||
fprintf(stderr,"New device name: must be at most %d bytes long.\n",MISDN_MAX_IDLEN-1);
|
||||
if (!argv[2][0] || strlen(argv[2]) >= MISDN_MAX_IDLEN) {
|
||||
fprintf(stderr, "New device name: must be at most %d bytes long.\n", MISDN_MAX_IDLEN - 1);
|
||||
exit(2);
|
||||
}
|
||||
|
||||
/* open mISDN */
|
||||
sock = socket(PF_ISDN, SOCK_RAW, ISDN_P_BASE);
|
||||
if (sock < 0)
|
||||
{
|
||||
if (sock < 0) {
|
||||
fprintf(stderr, "Cannot open mISDN due to %s. (Does your Kernel support socket based mISDN?)\n", strerror(errno));
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
@ -51,8 +48,7 @@ int main(int argc, char *argv[])
|
|||
/* get number of stacks */
|
||||
i = 1;
|
||||
ret = ioctl(sock, IMGETCOUNT, &ii);
|
||||
if (ret < 0)
|
||||
{
|
||||
if (ret < 0) {
|
||||
fprintf(stderr, "Cannot get number of mISDN devices: %s\n", strerror(errno));
|
||||
goto done;
|
||||
}
|
||||
|
@ -61,49 +57,45 @@ int main(int argc, char *argv[])
|
|||
goto done;
|
||||
}
|
||||
|
||||
if(isdigit(argv[1][0])) {
|
||||
if (isdigit(argv[1][0])) {
|
||||
i = atoi(argv[1]);
|
||||
if (i < 0) {
|
||||
fprintf(stderr,"Interface number must be >= zero.\n");
|
||||
fprintf(stderr, "Interface number must be >= zero.\n");
|
||||
exit(1);
|
||||
}
|
||||
} else {
|
||||
if (! argv[1][0] || strlen(argv[1]) >= MISDN_MAX_IDLEN) {
|
||||
fprintf(stderr,"Old device name: may be at most %d bytes long.\n",MISDN_MAX_IDLEN-1);
|
||||
if (!argv[1][0] || strlen(argv[1]) >= MISDN_MAX_IDLEN) {
|
||||
fprintf(stderr, "Old device name: may be at most %d bytes long.\n", MISDN_MAX_IDLEN - 1);
|
||||
exit(2);
|
||||
}
|
||||
|
||||
i = 0;
|
||||
while(ii && i <= MAX_DEVICE_ID)
|
||||
{
|
||||
while (ii && i <= MAX_DEVICE_ID) {
|
||||
devinfo.id = i;
|
||||
ret = ioctl(sock, IMGETDEVINFO, &devinfo);
|
||||
if (ret < 0)
|
||||
{
|
||||
fprintf(stderr, "error getting info for device %d: %s\n", i,strerror(errno));
|
||||
if (ret < 0) {
|
||||
fprintf(stderr, "error getting info for device %d: %s\n", i, strerror(errno));
|
||||
goto next_dev;
|
||||
}
|
||||
if (!strcmp (argv[1], devinfo.name))
|
||||
if (!strcmp(argv[1], devinfo.name))
|
||||
goto found_dev;
|
||||
--ii;
|
||||
next_dev:
|
||||
next_dev:
|
||||
i++;
|
||||
}
|
||||
fprintf(stderr,"Interface not found.\n");
|
||||
fprintf(stderr, "Interface not found.\n");
|
||||
goto done;
|
||||
}
|
||||
found_dev:
|
||||
devname.id = i;
|
||||
strncpy(devname.name,argv[2],MISDN_MAX_IDLEN);
|
||||
strncpy(devname.name, argv[2], MISDN_MAX_IDLEN - 1);
|
||||
ret = ioctl(sock, IMSETDEVNAME, &devname);
|
||||
if (ret < 0)
|
||||
{
|
||||
if (ret < 0) {
|
||||
fprintf(stderr, "Cannot set device name for port %d: %s\n", i, strerror(errno));
|
||||
exit(1);
|
||||
}
|
||||
|
||||
done:
|
||||
close(sock);
|
||||
return(0);
|
||||
return (0);
|
||||
}
|
||||
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
/*
|
||||
*
|
||||
* Copyright 2015 Karsten Keil <keil@b1-systems.de>
|
||||
* Copyright 2012 Karsten Keil <kkeil@suse.de>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
|
@ -21,7 +22,6 @@
|
|||
*
|
||||
*/
|
||||
|
||||
|
||||
/*
|
||||
* This tool is not specific to mISDN it does read a D-channel trace from a hex/text
|
||||
* file into binary wireshark format
|
||||
|
@ -31,8 +31,7 @@
|
|||
* > FCFF030F01FF01FF 05.06. 13:23:33
|
||||
* < FEFF030F01FF0285 05.06. 13:23:33
|
||||
*
|
||||
*/
|
||||
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
@ -47,24 +46,21 @@
|
|||
#include <malloc.h>
|
||||
#include <time.h>
|
||||
|
||||
|
||||
static void usage(pname)
|
||||
char *pname;
|
||||
static void usage(char *pname)
|
||||
{
|
||||
fprintf(stderr,"\n\nCall with %s [options] <infile> <outfile>\n",pname);
|
||||
fprintf(stderr,"\n");
|
||||
fprintf(stderr,"\n Valid options are:\n");
|
||||
fprintf(stderr,"\n");
|
||||
fprintf(stderr," -? Usage ; printout this information\n");
|
||||
fprintf(stderr,"\n");
|
||||
fprintf(stderr, "\n\nCall with %s [options] <infile> <outfile>\n", pname);
|
||||
fprintf(stderr, "\n");
|
||||
fprintf(stderr, "\n Valid options are:\n");
|
||||
fprintf(stderr, "\n");
|
||||
fprintf(stderr, " -? Usage ; printout this information\n");
|
||||
fprintf(stderr, "\n");
|
||||
}
|
||||
|
||||
|
||||
static void write_esc (FILE *file, unsigned char *buf, int len)
|
||||
static void write_esc(FILE * file, unsigned char *buf, int len)
|
||||
{
|
||||
int i, byte;
|
||||
int i, byte;
|
||||
|
||||
for (i = 0; i < len; ++i) {
|
||||
for (i = 0; i < len; ++i) {
|
||||
byte = buf[i];
|
||||
if (byte == 0xff || byte == 0xfe) {
|
||||
fputc(0xfe, file);
|
||||
|
@ -79,9 +75,9 @@ static void write_esc (FILE *file, unsigned char *buf, int len)
|
|||
}
|
||||
}
|
||||
|
||||
static void write_wfile(FILE *f, unsigned char *buf, int len, struct timeval *tv, int origin)
|
||||
static void write_wfile(FILE * f, unsigned char *buf, int len, struct timeval *tv, int origin)
|
||||
{
|
||||
u_char head[12];
|
||||
u_char head[12];
|
||||
|
||||
fputc(0xff, f);
|
||||
head[0] = (unsigned char)(0xff & (tv->tv_usec >> 16));
|
||||
|
@ -92,17 +88,18 @@ static void write_wfile(FILE *f, unsigned char *buf, int len, struct timeval *tv
|
|||
head[5] = (unsigned char)(0xff & (tv->tv_sec >> 16));
|
||||
head[6] = (unsigned char)(0xff & (tv->tv_sec >> 8));
|
||||
head[7] = (unsigned char)(0xff & tv->tv_sec);
|
||||
head[8] = (unsigned char) 0;
|
||||
head[9] = (unsigned char) origin & 0xff;
|
||||
head[10]= (unsigned char)(0xff & (len >> 8));
|
||||
head[11]= (unsigned char)(0xff & len);
|
||||
head[8] = (unsigned char)0;
|
||||
head[9] = (unsigned char)origin & 0xff;
|
||||
head[10] = (unsigned char)(0xff & (len >> 8));
|
||||
head[11] = (unsigned char)(0xff & len);
|
||||
|
||||
write_esc(f, head, 12);
|
||||
write_esc(f, buf, len);
|
||||
fflush(f);
|
||||
}
|
||||
|
||||
static char *skip_space(char *buf) {
|
||||
static char *skip_space(char *buf)
|
||||
{
|
||||
while (*buf) {
|
||||
switch (*buf) {
|
||||
case ' ':
|
||||
|
@ -132,7 +129,7 @@ static int getvalue(char *p)
|
|||
return v;
|
||||
}
|
||||
|
||||
static int analyse_line(char *line, u_char *buf, int *org, struct tm *tm)
|
||||
static int analyse_line(char *line, u_char * buf, int *org, struct tm *tm)
|
||||
{
|
||||
char *p = line;
|
||||
int len = 0, val;
|
||||
|
@ -148,7 +145,7 @@ static int analyse_line(char *line, u_char *buf, int *org, struct tm *tm)
|
|||
p = skip_space(p);
|
||||
if (*p == 0)
|
||||
return len;
|
||||
while(*p) {
|
||||
while (*p) {
|
||||
if (isspace(*p))
|
||||
break;
|
||||
val = getvalue(p);
|
||||
|
@ -173,41 +170,38 @@ static void normalize_tv(struct timeval *tv)
|
|||
}
|
||||
}
|
||||
|
||||
int
|
||||
main(argc, argv)
|
||||
int argc;
|
||||
char *argv[];
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
char *infilename = NULL;
|
||||
char *outfilename = NULL;
|
||||
char *infilename = NULL;
|
||||
char *outfilename = NULL;
|
||||
char sw;
|
||||
char line[4096];
|
||||
u_char buffer[512];
|
||||
char line[4096];
|
||||
u_char buffer[512];
|
||||
struct timeval main_tv, cur_tv;
|
||||
struct tm main_tm, cur_tm;
|
||||
time_t sec, last_sec;
|
||||
suseconds_t usec;
|
||||
int len, org, aidx = 1;
|
||||
int param = 0;
|
||||
FILE *ifile, *ofile;
|
||||
int len, org, aidx = 1;
|
||||
int param = 0;
|
||||
FILE *ifile, *ofile;
|
||||
|
||||
while (aidx < argc) {
|
||||
if (argv[aidx] && argv[aidx][0]=='-') {
|
||||
sw=argv[aidx][1];
|
||||
if (argv[aidx] && argv[aidx][0] == '-') {
|
||||
sw = argv[aidx][1];
|
||||
switch (sw) {
|
||||
case '?':
|
||||
usage(argv[0]);
|
||||
exit(1);
|
||||
break;
|
||||
default:
|
||||
fprintf(stderr,"Unknown Switch %c\n",sw);
|
||||
fprintf(stderr, "Unknown Switch %c\n", sw);
|
||||
usage(argv[0]);
|
||||
exit(1);
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
} else {
|
||||
if (strlen(argv[aidx]) >= 512) {
|
||||
fprintf(stderr,"%s filename too long\n", param ? "out" : "in");
|
||||
fprintf(stderr, "%s filename too long\n", param ? "out" : "in");
|
||||
exit(1);
|
||||
}
|
||||
if (param == 0) {
|
||||
|
@ -215,7 +209,7 @@ char *argv[];
|
|||
} else if (param == 1) {
|
||||
outfilename = argv[aidx];
|
||||
} else {
|
||||
fprintf(stderr,"Too many parameter (%d) item (%s)\n", argc - 1, argv[aidx]);
|
||||
fprintf(stderr, "Too many parameter (%d) item (%s)\n", argc - 1, argv[aidx]);
|
||||
usage(argv[0]);
|
||||
exit(1);
|
||||
}
|
||||
|
@ -225,22 +219,22 @@ char *argv[];
|
|||
}
|
||||
|
||||
if (param < 2) {
|
||||
fprintf(stderr,"Only %d parameter given but need <infile> and <outfile>\n", param);
|
||||
fprintf(stderr, "Only %d parameter given but need <infile> and <outfile>\n", param);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
ifile = fopen(infilename, "rt");
|
||||
if (!ifile) {
|
||||
fprintf(stderr,"cannot open %s for input - %s\n", infilename, strerror(errno));
|
||||
fprintf(stderr, "cannot open %s for input - %s\n", infilename, strerror(errno));
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
ofile = fopen(outfilename, "w");
|
||||
if (!ofile) {
|
||||
fprintf(stderr,"cannot open %s for output - %s\n", outfilename, strerror(errno));
|
||||
fprintf(stderr, "cannot open %s for output - %s\n", outfilename, strerror(errno));
|
||||
fclose(ifile);
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
fprintf(ofile, "EyeSDN");
|
||||
fflush(ofile);
|
||||
|
||||
|
@ -251,7 +245,7 @@ char *argv[];
|
|||
usec = 0;
|
||||
while (1) {
|
||||
if (!fgets(line, 4096, ifile)) {
|
||||
fprintf(stderr,"EOF or error reading file %s\n", infilename);
|
||||
fprintf(stderr, "EOF or error reading file %s\n", infilename);
|
||||
break;
|
||||
}
|
||||
org = 0;
|
||||
|
|
Loading…
Reference in New Issue