Hello community, here is the log from the commit of package mISDNuser for openSUSE:Factory checked in at 2015-03-18 13:04:39 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Comparing /work/SRC/openSUSE:Factory/mISDNuser (Old) and /work/SRC/openSUSE:Factory/.mISDNuser.new (New) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "mISDNuser" Changes: -------- --- /work/SRC/openSUSE:Factory/mISDNuser/mISDNuser.changes 2014-01-03 19:46:57.000000000 +0100 +++ /work/SRC/openSUSE:Factory/.mISDNuser.new/mISDNuser.changes 2015-03-18 13:04:44.000000000 +0100 @@ -1,0 +2,9 @@ +Sun Mar 1 18:11:38 UTC 2015 - p.drou...@gmail.com + +- Update to version 2.0.19 + * no changelog available +- Re-enable Werror (fixes on upstream release) +- Remove 0001-Fix-compile-error-with-newer-gcc-and-a-reaL-BUG.patch + merged on upstream release + +------------------------------------------------------------------- Old: ---- 0001-Fix-compile-error-with-newer-gcc-and-a-reaL-BUG.patch mISDNuser-2.0.17.tar.xz New: ---- mISDNuser-2.0.19.tar.xz ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ mISDNuser.spec ++++++ --- /var/tmp/diff_new_pack.kwt7hQ/_old 2015-03-18 13:04:45.000000000 +0100 +++ /var/tmp/diff_new_pack.kwt7hQ/_new 2015-03-18 13:04:45.000000000 +0100 @@ -1,7 +1,7 @@ # # spec file for package mISDNuser # -# Copyright (c) 2013 SUSE LINUX Products GmbH, Nuernberg, Germany. +# Copyright (c) 2015 SUSE LINUX GmbH, Nuernberg, Germany. # # All modifications and additions to the file contributed by third parties # remain the property of their copyright owners, unless otherwise agreed @@ -17,18 +17,17 @@ Name: mISDNuser +Version: 2.0.19 +Release: 0 Summary: Tools and library for mISDN License: GPL-2.0 and LGPL-2.1 Group: Hardware/ISDN -Version: 2.0.17 -Release: 0 Url: http://misdn.org/ #Git-Clone: git://git.misdn.eu/mISDNuser #Changelog: http://misdn.org/index.php/MISDN_Release_Notes -# There seem to be no tarballs. Generated one from git. +# There seem to be no tarballs. Generated from git. Source: %name-%version.tar.xz -Patch1: 0001-Fix-compile-error-with-newer-gcc-and-a-reaL-BUG.patch BuildRequires: autoconf >= 2.63 BuildRequires: automake BuildRequires: libtool >= 2 @@ -57,22 +56,18 @@ %prep %setup -qn %name -%patch -P 1 -p1 %build if [ ! -e configure ]; then mkdir -p m4; autoreconf -fi; fi; -export CFLAGS="%optflags -Wno-error" -export CXXFLAGS="$CFLAGS" %configure --disable-static make %{?_smp_mflags}; %install -b="%buildroot"; -make install DESTDIR="$b"; -find "$b/%_libdir" -type f -name "*.la" -delete; +%make_install +find "%buildroot/%_libdir" -type f -name "*.la" -delete; %post -n libmisdn1 -p /sbin/ldconfig ++++++ mISDNuser-2.0.17.tar.xz -> mISDNuser-2.0.19.tar.xz ++++++ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/mISDNuser/.gitignore new/mISDNuser/.gitignore --- old/mISDNuser/.gitignore 2012-11-15 02:41:37.000000000 +0100 +++ new/mISDNuser/.gitignore 2015-03-01 20:43:42.000000000 +0100 @@ -45,3 +45,4 @@ DEADJOE .dirstamp libtool +ar-lib diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/mISDNuser/bridge/bridge.c new/mISDNuser/bridge/bridge.c --- old/mISDNuser/bridge/bridge.c 2012-11-15 02:41:37.000000000 +0100 +++ new/mISDNuser/bridge/bridge.c 2015-03-01 20:43:42.000000000 +0100 @@ -324,7 +324,7 @@ 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 @@ 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); } diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/mISDNuser/capi20/application.c new/mISDNuser/capi20/application.c --- old/mISDNuser/capi20/application.c 2012-11-15 02:41:37.000000000 +0100 +++ new/mISDNuser/capi20/application.c 2015-03-01 20:43:42.000000000 +0100 @@ -1,4 +1,4 @@ -/* +/* * application.c * * Written by Karsten Keil <kk...@linux-pingi.de> @@ -103,8 +103,12 @@ 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 @@ 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 @@ } 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 @@ 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 @@ 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 @@ 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)); } } diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/mISDNuser/capi20/capi_obj.c new/mISDNuser/capi20/capi_obj.c --- old/mISDNuser/capi20/capi_obj.c 2012-11-15 02:41:37.000000000 +0100 +++ new/mISDNuser/capi20/capi_obj.c 2015-03-01 20:43:42.000000000 +0100 @@ -26,6 +26,8 @@ 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 @@ 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) #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); + } + 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)); } - co->refcnt++; - coref_dbg("%s\n", CAPIobjIDstr(co)); - if (co->parent) - pthread_rwlock_unlock(&co->parent->lock); + 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 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 @@ 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 @@ } } 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 @@ 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 @@ 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) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/mISDNuser/capi20/daemon.c new/mISDNuser/capi20/daemon.c --- old/mISDNuser/capi20/daemon.c 2012-11-15 02:41:37.000000000 +0100 +++ new/mISDNuser/capi20/daemon.c 2015-03-01 20:43:42.000000000 +0100 @@ -618,6 +618,7 @@ 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 +642,7 @@ 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 +794,13 @@ /* 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)); @@ -831,15 +834,18 @@ 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,6 +854,7 @@ 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; } @@ -988,11 +995,14 @@ { 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 +1023,7 @@ 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 +1070,7 @@ } 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 +1129,24 @@ 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 +1168,10 @@ 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 +1188,16 @@ 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 +1252,11 @@ 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 +1269,11 @@ 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 +1283,11 @@ 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 +1296,11 @@ } 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 +1341,14 @@ #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; @@ -1440,10 +1474,12 @@ 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 +1628,14 @@ 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 +1737,10 @@ 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 +1962,8 @@ 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 +2072,10 @@ 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 +2114,11 @@ } 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); } } @@ -2268,6 +2311,8 @@ 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,6 +2362,7 @@ 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 = bind(mCsock, (struct sockaddr *)&mcaddr, sizeof(mcaddr)); diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/mISDNuser/capi20/faxl3.c new/mISDNuser/capi20/faxl3.c --- old/mISDNuser/capi20/faxl3.c 2012-11-15 02:41:37.000000000 +0100 +++ new/mISDNuser/capi20/faxl3.c 2015-03-01 20:43:42.000000000 +0100 @@ -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 @@ 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 @@ 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 diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/mISDNuser/capi20/listen.c new/mISDNuser/capi20/listen.c --- old/mISDNuser/capi20/listen.c 2012-11-15 02:41:37.000000000 +0100 +++ new/mISDNuser/capi20/listen.c 2015-03-01 20:43:42.000000000 +0100 @@ -128,14 +128,19 @@ 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 @@ 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; } } diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/mISDNuser/capi20/lplci.c new/mISDNuser/capi20/lplci.c --- old/mISDNuser/capi20/lplci.c 2012-11-15 02:41:37.000000000 +0100 +++ new/mISDNuser/capi20/lplci.c 2015-03-01 20:43:42.000000000 +0100 @@ -1747,10 +1747,24 @@ 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 +1776,15 @@ 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; } diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/mISDNuser/capi20/m_capi.h new/mISDNuser/capi20/m_capi.h --- old/mISDNuser/capi20/m_capi.h 2012-11-15 02:41:37.000000000 +0100 +++ new/mISDNuser/capi20/m_capi.h 2015-03-01 20:43:42.000000000 +0100 @@ -133,19 +133,26 @@ #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 diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/mISDNuser/capi20/ncci.c new/mISDNuser/capi20/ncci.c --- old/mISDNuser/capi20/ncci.c 2012-11-15 02:41:37.000000000 +0100 +++ new/mISDNuser/capi20/ncci.c 2015-03-01 20:43:42.000000000 +0100 @@ -640,6 +640,7 @@ { struct mNCCI *nc; int err; + struct mApplication *appl = NULL; nc = calloc(1, sizeof(*nc)); if (!nc) { @@ -647,6 +648,15 @@ 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 +664,7 @@ 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 +718,8 @@ nc->osize = 256; dprint(MIDEBUG_NCCI, "%s: created\n", CAPIobjIDstr(&nc->cobj)); } else { + if (appl) + put_cobj(&appl->cobj); free(nc); nc = NULL; } diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/mISDNuser/configure.ac new/mISDNuser/configure.ac --- old/mISDNuser/configure.ac 2012-11-15 02:41:37.000000000 +0100 +++ new/mISDNuser/configure.ac 2015-03-01 20:43:42.000000000 +0100 @@ -2,7 +2,7 @@ # Process this file with autoconf to produce a configure script. AC_PREREQ([2.63]) -AC_INIT([mISDNuser],[2.0.17],[i4ldevelo...@isdn4linux.de],[mISDNuser]) +AC_INIT([mISDNuser],[2.0.19],[i4ldevelo...@isdn4linux.de],[mISDNuser]) AC_CONFIG_SRCDIR([tools/]) AC_CONFIG_HEADERS([include/config.h]) AC_CONFIG_MACRO_DIR([m4]) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/mISDNuser/example/testcon.c new/mISDNuser/example/testcon.c --- old/mISDNuser/example/testcon.c 2012-11-15 02:43:00.000000000 +0100 +++ new/mISDNuser/example/testcon.c 2015-03-01 20:43:42.000000000 +0100 @@ -81,6 +81,7 @@ 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 +91,7 @@ int cardnr; int func; char phonenr[32]; + unsigned char cause; int layer2; struct sockaddr_mISDN l2addr; int bchan; @@ -142,7 +144,7 @@ *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 +170,7 @@ 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 +203,7 @@ return ret; } -int setup_bchannel(devinfo_t *di) { +static int setup_bchannel(devinfo_t *di) { int ret; struct sockaddr_mISDN addr; @@ -241,7 +243,7 @@ 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 +280,82 @@ 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 +417,7 @@ 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 +484,7 @@ } #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 +500,7 @@ } #endif -void +static void do_hw_loop(devinfo_t *di) { struct mISDN_ctrl_req creq; @@ -439,7 +516,7 @@ di->flag |= FLG_BCHANNEL_LOOPSET; } -void +static void del_hw_loop(devinfo_t *di) { struct mISDN_ctrl_req creq; @@ -456,9 +533,10 @@ 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 +549,10 @@ 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 +568,9 @@ } } 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 +587,11 @@ #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 +626,15 @@ } 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 +663,11 @@ 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 +678,7 @@ 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 +783,40 @@ 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 +829,24 @@ } } } - 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 +877,8 @@ 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 +903,27 @@ 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 +996,7 @@ 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 +1009,12 @@ 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 +1047,25 @@ 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 +1115,6 @@ 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 +1152,8 @@ 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 +1164,9 @@ 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 +1176,9 @@ 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 +1189,9 @@ 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 +1201,9 @@ 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 +1213,9 @@ 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 +1270,30 @@ 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; @@ -1206,8 +1352,8 @@ } break; case 'n': - if (!argv[aidx][2]) { - idx = 0; + if (!argv[aidx][2]) { + idx = 0; aidx++; } else { idx=2; @@ -1239,7 +1385,7 @@ exit(1); } } - aidx++; + aidx++; } while (aidx<argc); } err = socket(PF_ISDN, SOCK_RAW, ISDN_P_BASE); diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/mISDNuser/example/testlayer3.c new/mISDNuser/example/testlayer3.c --- old/mISDNuser/example/testlayer3.c 2012-11-15 02:41:37.000000000 +0100 +++ new/mISDNuser/example/testlayer3.c 2015-03-01 20:43:42.000000000 +0100 @@ -1292,7 +1292,9 @@ 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)); break; case PH_DATA_CNF: /* get ACK of send data, so we can diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/mISDNuser/include/mISDN/q931.h new/mISDNuser/include/mISDN/q931.h --- old/mISDNuser/include/mISDN/q931.h 2012-11-15 02:43:00.000000000 +0100 +++ new/mISDNuser/include/mISDN/q931.h 2015-03-01 20:43:42.000000000 +0100 @@ -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,6 +330,7 @@ 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 */ extern int mi_decode_progress(struct l3_msg *, struct misdn_progress_info *); @@ -345,6 +349,7 @@ 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); diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/mISDNuser/lib/layer3/mlayer3.c new/mISDNuser/lib/layer3/mlayer3.c --- old/mISDNuser/lib/layer3/mlayer3.c 2012-11-15 02:41:37.000000000 +0100 +++ new/mISDNuser/lib/layer3/mlayer3.c 2015-03-01 20:43:42.000000000 +0100 @@ -107,11 +107,14 @@ /* 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; diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/mISDNuser/lib/layer3/q931.c new/mISDNuser/lib/layer3/q931.c --- old/mISDNuser/lib/layer3/q931.c 2012-11-15 02:43:00.000000000 +0100 +++ new/mISDNuser/lib/layer3/q931.c 2015-03-01 20:43:42.000000000 +0100 @@ -357,7 +357,7 @@ ie[1] = hlc & 0x7f; if (ehlc < 0) - ie[1] | 0x80; + ie[1] |= 0x80; else { l = 3; ie[2] = 0x80 | (ehlc & 0x7f); @@ -678,6 +678,15 @@ 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) @@ -1123,6 +1132,17 @@ 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) { diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/mISDNuser/tools/.gitignore new/mISDNuser/tools/.gitignore --- old/mISDNuser/tools/.gitignore 2012-11-15 02:43:00.000000000 +0100 +++ new/mISDNuser/tools/.gitignore 2015-03-01 20:43:42.000000000 +0100 @@ -2,4 +2,5 @@ /misdn_info /misdn_log /misdn_rename -/misdn_E1test \ No newline at end of file +/misdn_E1test +/isdn_text2wireshark diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/mISDNuser/tools/info.c new/mISDNuser/tools/info.c --- old/mISDNuser/tools/info.c 2012-11-15 02:43:00.000000000 +0100 +++ new/mISDNuser/tools/info.c 2015-03-01 20:43:42.000000000 +0100 @@ -71,7 +71,7 @@ /* 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 "); -- To unsubscribe, e-mail: opensuse-commit+unsubscr...@opensuse.org For additional commands, e-mail: opensuse-commit+h...@opensuse.org