Compare commits

...

78 Commits

Author SHA1 Message Date
Harald Welte ca72be85e9 sff.c: Fix compiler warnings about old uint32 type
sff.c:509:9: error: ‘uint32’ is deprecated [-Werror=deprecated-declarations]
2022-04-03 15:56:47 +02:00
Harald Welte 3bce40c22a Disable -Werror for array-bounds
Otherwise the library won't build with gcc-11.2

In file included from misc/mbuffer.c:21:
misc/mbuffer.c: In function ‘alloc_mbuffer’:
../include/mISDN/mbuffer.h:160:14: error: array subscript ‘struct mbuffer[0]’ is partly outside array bounds of ‘struct mqueue[1]’ [-Werror=array-bounds]
  160 |         next = prev->next;
      |         ~~~~~^~~~~~~~~~~~
2022-03-13 15:19:56 +01:00
Harald Welte b718bf65e4 capi20/alaw: Use 'extern' to avoid multiple definition
The library fails to compile with gcc-11.2 as 'extern' is missing from
forward declaration of global variables.

/usr/bin/ld: faxl3.o:mISDNuser/capi20/alaw.h:7: multiple definition of `alaw2lin'; daemon.o:mISDNuser/capi20/alaw.h:7: first defined here
/usr/bin/ld: faxl3.o:mISDNuser/capi20/alaw.h:6: multiple definition of `slin2alaw'; daemon.o:mISDNuser/capi20/alaw.h:6: first defined here
/usr/bin/ld: faxl3.o:mISDNuser/capi20/alaw.h:5: multiple definition of `lin2alaw'; daemon.o:mISDNuser/capi20/alaw.h:5: first defined here
/usr/bin/ld: alaw.o:mISDNuser/capi20/alaw.h:5: multiple definition of `lin2alaw'; daemon.o:mISDNuser/capi20/alaw.h:5: first defined here
/usr/bin/ld: alaw.o:mISDNuser/capi20/alaw.h:6: multiple definition of `slin2alaw'; daemon.o:mISDNuser/capi20/alaw.h:6: first defined here
/usr/bin/ld: alaw.o:mISDNuser/capi20/alaw.h:7: multiple definition of `alaw2lin'; daemon.o:mISDNuser/capi20/alaw.h:7: first defined here
2022-03-13 15:13:23 +01:00
Harald Welte 09b37dd814 mlayer3: Improve English language log message
"device do not" is incorrect, "device does not" or "doesn't" is correct.
2022-03-13 15:03:50 +01:00
Harald Welte 465dec0d27 cosmetic: Fix typo in comment 2022-03-13 15:02:31 +01:00
Harald Welte 4d45ae8289 bridge.c: Fix some int vs. unsigned long type error
not only is it a signed/unsigned error, but on some architectures the
sizes of those two types are not identical, leading to a buffer overflow
on the stack. gcc-11.2 is complaining about it:

bridge.c: In function ‘ph_control’:
bridge.c:159:9: error: array subscript 2 is outside array bounds of ‘unsigned char[16]’ [-Werror=array-bounds]
  159 |         *d++ = c2;
      |         ^~~~
bridge.c:150:23: note: while referencing ‘data’
  150 |         unsigned char data[MISDN_HEADER_LEN+sizeof(int)+sizeof(int)];
      |                       ^~~~
2022-03-13 14:53:24 +01:00
Karsten Keil d6818dd9a4
Merge pull request #10 from kristovschulz/remove-timeout-warning
mISDNcapid: remove irritating timeout warning
2019-02-27 00:27:01 +01:00
Christoph Schulz b45d87e52b mISDNcapid: remove irritating timeout warning
The loop within BCthread() continuously emits a warning like the following one

  BCthread(24062):Bchannel1 timeout (release not pending) thread=24062

every 500 ms as long as no data is received over the B-channel. This is very
irritating and noisy and fills up the log file without a good reason. This
commit lets the warning be shown only if the timeout occurs while a release
operation is pending (and this is worth a warning because such a timeout does
not occur under normal circumstances).

Signed-off-by: Christoph Schulz <develop@kristov.de>
2019-02-13 00:00:18 +01:00
Karsten Keil 710b87dcb9 Fix possible buffer overflows detected by newer GCC versions
GCC reports problems like this:

gcc -DHAVE_CONFIG_H -I. -I../include -I../include -Wall -Werror -I./include -D_FORTIFY_SOURCE=2 -march=x86-64 -mtune=generic -O2 -pipe -fstack-protector-strong -fno-plt -MT layer3/q931.lo -MD -MP -MF layer3/.deps/q931.Tpo -c layer3/q931.c  -fPIC -DPIC -o layer3/.libs/q931.o
In file included from /usr/include/string.h:494,
                 from layer3/q931.c:22:
In function ‘strncpy’,
    inlined from ‘mi_encode_redirecting_nr’ at layer3/q931.c:531:3:
/usr/include/bits/string_fortified.h:106:10: error: ‘__builtin_strncpy’ forming offset [25, 31] is out of the bounds [0, 24] of object ‘ie’ with type ‘unsigned char[24]’ [-Werror=array-bounds]
   return __builtin___strncpy_chk (__dest, __src, __len, __bos (__dest));
          ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

Thanks to Tobias Powalowski for reporting this
This commit fixes issue #9 on github.
2018-07-18 07:27:41 +02:00
Karsten Keil e5088699fb
Merge pull request #8 from christian-intra2net/signal-handlers
Signal handlers
2018-06-28 07:39:14 +02:00
Christian Herdtweck a28cb6bc53 Move code from SIGUSR (dump) and SIGTERM signal handlers
There is a very limited list of functions one is allowed to call from a
signal handler (see "man 7 signal"). This list does not include
va_{start,end} required by iprint. Therefore, this commit moves calls to
dump_* from the dumpHandler and the iprint from termHandler to
main_control.

For dumping, this required two new constants MICD_CTRL_DUMP_{1,2}

Note: calling send_master_control from a signal handler is only safe with
argument len==0, because otherwise malloc(), memcpy() and free() would be
called which are VERY unsafe.
2018-06-25 12:34:48 +02:00
Christian Herdtweck 4f7cea4028 Create signal handler for capi20: SIGHUP re-opens debug log file
Create a signal handler just like the termHandler, that sends a new flag
(MICD_CTRL_REOPEN_LOG) to the master control queue. Once main control
encounters that flag, it flushes and closes the debug log file and
re-opens it.
2018-06-25 12:04:51 +02:00
Karsten Keil 0f8548b3d2 Version 2.0.22 2017-07-30 22:30:27 +02:00
Karsten Keil 488c9ea1c8 logger: Fix bearer octet 5 decoding 2017-07-30 22:29:26 +02:00
Karsten Keil c9e711960b Some more const declarations since some crosscompilers are more picky here 2017-07-30 22:29:26 +02:00
Karsten Keil 25c7d7bbf5 Add missing AM_PROG_AR 2017-07-30 22:29:26 +02:00
Thomas Jarosch bdb5d3903c Include misdnlogger.conf.sample in make dist 2017-07-30 22:29:25 +02:00
Karsten Keil 5875f14832 Add LLC logging 2017-07-30 22:29:25 +02:00
Karsten Keil 9097f56457 Support more infoelements and repeated infoelements 2017-07-30 22:29:25 +02:00
Karsten Keil 7d12683f36 export l3_ie2pos() and l3_pos2ie() 2017-07-30 22:29:25 +02:00
Karsten Keil 3c6665d794 Install misdnlogger.conf.sample as default 2017-07-30 22:29:25 +02:00
Karsten Keil d263d37f77 add flex artefact ylwrap 2017-07-30 22:29:25 +02:00
Karsten Keil 46b4dd6a25 Add new misdlogger related artefacts 2017-07-30 22:29:25 +02:00
Karsten Keil 56c333ab10 Export parseQ931 2017-07-30 22:29:24 +02:00
Karsten Keil cc80463f23 First working version of misdnlogger 2017-07-30 22:29:24 +02:00
Karsten Keil 234e9bc9ce Fix none existing octets 5b1/5b2 in bearer capabilities
Here exist two differnt content versions of octet 5b in bearer capabilities
but only alternatively depending on the L1 protocol, so we only need one octet 5b here.
2017-07-30 22:29:24 +02:00
Karsten Keil 4be89daf43 Call logger first not working skeleton version 2017-07-30 22:29:24 +02:00
Karsten Keil 79f85a5f96 Set version to 2.0.21 2017-07-30 22:29:24 +02:00
Karsten Keil ae15977c06 Remove duplicated const const (detected by gcc 7 warning)
Signed-off-by: Karsten Keil <keil@b1-systems.de>
2017-07-24 09:21:13 +02:00
Karsten Keil 9f5d377216 Make intermediate version 2.0.20
Signed-off-by: Karsten Keil <keil@b1-systems.de>
2017-07-24 09:21:13 +02:00
Karsten Keil 002a6e4bcb Merge pull request #6 from kristovschulz/fix-release-link
mISDNcapid: release B3 link properly when using CAPIFLAG_HIGHJACKING
2017-07-24 09:15:42 +02:00
Karsten Keil ce11bd31a3 Merge pull request #5 from kristovschulz/fix-pty-loopback
mISDNcapid: ignore incoming B3 data packets until PTY slave sent data
2017-07-24 09:15:29 +02:00
Karsten Keil 6cdc34ef49 Merge pull request #4 from kristovschulz/fix-lplci-disconnect
mISDNcapid: fix lPLCIDisconnectInd() by returning zero when B3 link is missing
2017-07-24 09:14:57 +02:00
Karsten Keil acd627c996 Merge pull request #3 from kristovschulz/fix-bchannel-activation
mISDNcapid: fix B channel activation
2017-07-24 09:14:12 +02:00
Karsten Keil bf6813426b Merge pull request #2 from kristovschulz/fix-tty-mc-leak
mISDNcapid: fix memory leak when using CAPIFLAG_HIGHJACKING
2017-07-24 09:12:41 +02:00
Karsten Keil f732c35c3d Ignore autogenerated capi20/m_capi_sock.h
Signed-off-by: Karsten Keil <keil@b1-systems.de>
2017-06-11 12:16:15 +02:00
Christoph Schulz 0d7fc6fd37 mISDNcapid: fix memory leak when using CAPIFLAG_HIGHJACKING
If using a tty for sending/receiving B3 data, the mc buffer for data sent is
not freed by ncciDataConf() because this is done only by AnswerDataB3Req()
which is not called when using a tty. Fix this by explicitly freeing the mc
buffer when a tty is used.

Signed-off-by: Christoph Schulz <develop@kristov.de>
2017-02-27 17:48:37 +01:00
Christoph Schulz be0f62c087 mISDNcapid: release B3 link properly when using CAPIFLAG_HIGHJACKING
Until now, B3ReleaseLink() did not care about BType_tty B3 links. This commit
makes them behave like BType_Direct links.

Signed-off-by: Christoph Schulz <develop@kristov.de>
2017-02-27 17:48:24 +01:00
Christoph Schulz cf98743fb3 mISDNcapid: ignore incoming B3 data packets until PTY slave sent data
In hijacking mode (CAPIFLAG_HIGHJACKING), a PTY master/slave pair is created to
pass data back and forth between the application and mISDNcapid. However, there
is a small time window between creating the PTY slave and the application
opening the PTY slave. If a B3 data connection is established before the
application has opened the PTY slave, and B3 data is received and written to the
PTY master end, it is immediately read back by the B3 data receiver thread
(BCthread), which then sends the data back to the original sender, causing a
loopback. This e.g. happens when the application is the PPP daemon pppd which
has been configured to not send any data until it receives a valid LCP packet
("silent" option).

In order to fix this, an additional flag called tty_received remembers whether
the B3 data receiver thread has already read data from the PTY at least once.
Only if this is the case B3 data is written to the PTY master end, otherwise it
is discarded as there is no potential receiver at the PTY slave end yet. This
effectively avoids any loopback situations due to an unconnected PTY slave end.

Signed-off-by: Christoph Schulz <develop@kristov.de>
2017-02-27 17:47:59 +01:00
Christoph Schulz 86da1e4546 mISDNcapid: fix lPLCIDisconnectInd() by returning zero when B3 link is missing
The function lPLCIDisconnectInd() is called by plci_cc_disconnect_ind() when a
EV_L3_DISCONNECT_IND event is being handled. If the B3 link has already gone,
lPLCIDisconnectInd() returns -ENODEV, which prevents plci_cc_disconnect_ind()
from calling lPLCILinkDown() and therefore from cleaning up properly. This
commit makes lPLCIDisconnectInd() returns zero (i.e. success) in such a
situation.

Signed-off-by: Christoph Schulz <develop@kristov.de>
2017-02-27 17:45:58 +01:00
Christoph Schulz c3c05bfb63 mISDNcapid: fix B channel activation
Always sends PH_ACTIVATE_REQ and not DL_ESTABLISH_REQ down the mISDN stack when
opening a B-channel, as DL_ESTABLISH_REQ is only understood by layer-2, and
B-channel management is done at layer-1.

Signed-off-by: Christoph Schulz <develop@kristov.de>
2017-02-27 17:44:26 +01:00
Karsten Keil 1acabc5db3 Set theme jekyll-theme-merlot 2017-02-26 19:58:40 +01:00
Martin Bachem a29326031e testlayer1: polling sockets faster, sleep after bind, etc 2016-06-30 14:29:43 +02:00
Martin Bachem 1bade6d562 testlayer1 starts average rate counter at once for all channels 2016-06-20 15:33:35 +02:00
Martin Bachem b76e29c8c3 layer1 channel activate/deactivate stress test 2016-06-09 17:52:40 +02:00
Maciej S. Szmigiero 21b8c52a64 mISDNcapid: Parse B channel id first from message then its included IEs
If early B3 is enabled we are currently opening channel B on appropriate
"Progress" IE.

If it turns out that this IE arrives in the same message that also sets
which B channel should be used the current code will fail to open
the B channel for early B3 as the current order is to first handle the IEs
then parse channel id.

Change this to first parse the B channel id then handle the IEs so in such
situation the B channel id will already be set at "Progress" IE handling
time.

Signed-off-by: Maciej S. Szmigiero <mail@maciej.szmigiero.name>
2016-04-14 23:41:43 +02:00
Maciej S. Szmigiero e3e71a7f94 mISDNcapid: Add experimental partial early B3 support
Early B3 support is an useful functionality not only to listen to actual
exchange ringback tone but also to hear announcements like number changed,
line not provisioned, etc.

This commit adds partial early B3 support: mISDNcapid will try to open
B channel on "Call is not end-to-end ISDN; further call progress
information may be available in-band" and "In-band information or an
appropriate pattern is now available" progress indications, so CAPI
application will be able to connect to this B channel with CONNECT_B3_REQ
message.

Doing it this way needs only minimal changes to existing code - we just
need to make sure that B channel opening function ( lPLCILinkUp() )
doesn't try do it again when it is called for the second time.

Full early B3 support would need further decoupling NCCI management
from PLCI management so B channel could be opened on demand when CAPI
application issues CONNECT_B3_REQ.

While we are at it also make sure that lPLCILinkUp() function also
cleans up what it has already done when it exits early with an error.

Since this functionality is experimental it is not enabled by default -
a define needs to be uncommented at top of capi20/lplci.c to enable it.

Signed-off-by: Maciej S. Szmigiero <mail@maciej.szmigiero.name>
2016-04-14 23:24:17 +02:00
Maciej S. Szmigiero 6e79260425 mISDNcapid: Send also second and next IEs as INFO_IND to CAPI application
According to Q.931 (05/98) some of variable length information elements
may occur more than once in a message.

parseQ931() from mISDN layer3 library would store such second and next
occurrence of particular IE in an "extra" array of l3 struct.

This commit adds support for sending these repeated IEs to mISDNcapid
INFO_IND IE posting function ( lPLCIInfoIndIE() ) so they will be
available to CAPI applications.

Signed-off-by: Maciej S. Szmigiero <mail@maciej.szmigiero.name>
2016-04-14 00:35:26 +02:00
Maciej S. Szmigiero a50c5b93da mISDNcapid: Fix INFO_IND IE posting function early return condition
lPLCIInfoIndIE() in lplci.c returned early when mc->l3m was set and
continued execution when it was NULL, however from code further in this
function it is clear that opposite behavior was meant.

This caused CAPI applications to not receive INFO_IND with information
elements, as this function was no-op when called correctly.

Signed-off-by: Maciej S. Szmigiero <mail@maciej.szmigiero.name>
2016-04-13 23:33:05 +02:00
Maciej S. Szmigiero 0cac6f5176 testlayer3: Normalize successful write() return value in bch_worker()
bch_worker() on {DL,PH}_DATA_IND returns what write() call has returned.
This function returns number of bytes written, however bch_worker() caller
main_worker() treats any non-zero return value of bch_worker() as signal
to disconnect the call.

This all meant that call terminated on first received chunk of data.

Fix it by normalizing a positive return value of write() in bch_worker()
to zero.

Signed-off-by: Maciej S. Szmigiero <mail@maciej.szmigiero.name>
Signed-off-by: Karsten Keil <keil@b1-systems.de>
2016-03-29 12:47:49 +02:00
Maciej S. Szmigiero 99bccfa7b9 testlayer3: Add missing break in MT_CONNECT case in do_control_worker()
MT_CONNECT case in do_control_worker() was missing final break so on this
message code in next (identical) case of MT_CONNECT_ACKNOWLEDGE was
executed, too.

In "send and receive voice" mode this resulted in
"bchannel_senddata: next_skb exist ERROR (skb->len=64 next_skb->len=64)"
error and immediate call disconnection due to TX data being submitted
twice.

Signed-off-by: Maciej S. Szmigiero <mail@maciej.szmigiero.name>
Signed-off-by: Karsten Keil <keil@b1-systems.de>
2016-03-29 12:47:43 +02:00
Karsten Keil 7e1924062d Create the socket directory on runtime
Since nowadays often the /var/run is /run and is in tmpfs creating it on the fly should be
a better solution.
2016-03-29 12:31:22 +02:00
Karsten Keil c686153484 mISDNcapid: Add hint for the -d --debug parameter in help output 2016-03-15 12:53:33 +01:00
Maciej S. Szmigiero b4b3e62516 Fix CAPI-initiated disconnection in direct layer 1 mode
When CAPI application asks for B3 disconnection the NCCI state machine
sends disconnect request further down the stack and then goes into N_4
state waiting for disconnection confirmation.

If B channel was in direct layer 1 mode the disconnect request will be
sent as PH_DEACTIVATE_REQ which will go all the way down to an individual
mISDN chip driver.

It looks like all current chip drivers reply to such requests by sending
only PH_DEACTIVATE_IND message, however the state machine in N_4 state
only reacts to PH_DEACTIVATE_CNF message (translated into
EV_DL_RELEASE_CONF).

This means that such call will get stuck until remote side disconnects it.

Fix this by reacting to PH_DEACTIVATE_IND message also in N_4 state,
just like it is done in N_ACT state.

Signed-off-by: Maciej S. Szmigiero <mail@maciej.szmigiero.name>
2016-03-13 18:54:03 +01:00
Maciej S. Szmigiero 06ed113c3d Use Reject parameter for deciding what happens to call via CONNECT_B3_RESP
CAPI specs say that CONNECT_B3_RESP message uses Reject parameter for
deciding what happens to incoming connection, however mISDNcapid code
used Info instead.

Signed-off-by: Maciej S. Szmigiero <mail@maciej.szmigiero.name>
2016-03-13 18:52:55 +01:00
Maciej S. Szmigiero 4caaa5ac72 Parse channel information from CALL PROCEEDING message too in mISDNcapid
According to Q.931 (05/98) on user-originated calls that did not select
a particular B channel in a SETUP message the selected B channel is sent
in a first message returned by the network in a response to
the SETUP message.

This Recommendation explicitly mentions SETUP ACKNOWLEDGE or
CALL PROCEEDING as examples of such response messages, however mISDNcapid
code ignored channel indication in CALL PROCEEDING messages.

This resulted in a no channel selected error on outgoing calls
on exchanges that reply with CALL PROCEEDING to SETUP.

Signed-off-by: Maciej S. Szmigiero <mail@maciej.szmigiero.name>
2016-03-13 18:52:16 +01:00
Karsten Keil 40aa4b22c1 Convert tools sources to codestyle 2015-08-02 16:35:49 +02:00
Thomas Jarosch 6c25cdacd3 Fix memory leak on read() error
Detected by cppcheck.
2015-08-01 18:06:43 +02:00
Martin Bachem bc5d24d5b2 testlayer1: fixing usage hints for --help output 2015-04-23 10:31:28 +02:00
Karsten Keil 3638cf36df Release v2.0.19 2014-10-20 14:18:55 +02:00
Karsten Keil bd6ea3f85f Fix overwriting ret in action loop, improve debug/error messages. 2014-10-20 14:11:35 +02:00
Karsten Keil fc757c58dc Better refcount locking to avoid use after free
Under some conditions it could be happen that on a freeing capi object
a other thread still get a reference and then it use the already freed object.
To avoid this, we do 2 things, we only take a refernce if get_obj() succeed, it
do not longer succeed if the object is already cleaned. We also force scheduling
after releaseing the lock before really freeing the object - so the waiting thread
will not get a new reference.
2014-10-14 14:39:44 +02:00
Karsten Keil d9a97bb810 Lock refcnt changes for Root objects too
In theory the Root object are never freed so the refcounting is not critical, but it should also not harm
to protect it to avoid wrong refcounts.
2014-10-03 17:27:11 +02:00
Karsten Keil 69cd05567c ignore ar-lib 2014-10-03 16:58:34 +02:00
Karsten Keil 70c61ca931 Some debug to detect use after free 2014-10-03 16:52:20 +02:00
Karsten Keil ed6c40581e release v2.0.18 2014-09-22 01:51:02 +02:00
Karsten Keil 50b4970832 Always close socket in error cases
Thanks to Thomas Jarosch <thomas.jarosch@intra2net.com> for fixing this
2014-09-22 01:41:30 +02:00
Karsten Keil 43cd10a657 Better debugging for descriptor leaks and fixing application release leak 2014-09-22 01:35:42 +02:00
Karsten Keil 8a0d743a08 return code of write need checking 2014-09-22 01:32:09 +02:00
Karsten Keil d927b710c6 Mutex should be unlocked before setting bi to NULL - fix SEGFAULT 2014-09-15 08:32:05 +02:00
Karsten Keil dee4e5684a Try to fix filedescriptor leak and add additional debug output to get more info about the leak 2014-09-09 12:55:50 +02:00
Karsten Keil ec4ac2763f Fix compile error with newer gcc (and a reaL BUG)
layer3/q931.c: In function 'mi_encode_hlc':
layer3/q931.c:360:3: error: statement with no effect [-Werror=unused-value]
   ie[1] | 0x80;
   ^
Thanks to Tobias Powalowski pointing to this issue
.
2013-05-20 15:16:19 +02:00
Andreas Eversberg 1dc4c24d27 Fix: misdn_bridge now activates correct interface when L1 is down
When layer 1 is down, an incomming message will now activate the
correct interface. This is required to pass a message when layer 1
is down, like PTMP interfaces.
2012-12-21 22:16:32 +01:00
Joerg Dorchain 3293be0592 Fix compile error when configured --disable-softdsp 2012-12-05 10:40:19 +01:00
Norbert Weyrich df131f57d4 decode and encode functions for notification indicator information element 2012-11-14 14:19:01 +01:00
Karsten Keil 640ba25164 Add special testmode 16 to testcon - Reject calls with cause values
- cleanup
2012-11-13 20:35:48 +01:00
Karsten Keil 7e5e9df238 Fix printf format string
It should be OK to use printf with a format only, but it seems some gcc version has an issue here.

Signed-off-by: Karsten Keil <kkeil@linux-pingi.de>
2012-09-29 17:44:03 +02:00
Karsten Keil d980284891 Add missing cause values for facility reject
Signed-off-by: Karsten Keil <keil@b1-systems.de>
2012-09-23 20:20:48 +02:00
48 changed files with 4522 additions and 1020 deletions

3
.gitignore vendored
View File

@ -45,3 +45,6 @@ config.sub
DEADJOE
.dirstamp
libtool
ar-lib
capi20/m_capi_sock.h
ylwrap

1
_config.yml Normal file
View File

@ -0,0 +1 @@
theme: jekyll-theme-merlot

View File

@ -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);
}

View File

@ -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'

View File

@ -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,

View File

@ -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

View File

@ -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));
}
}

View File

@ -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)

View File

@ -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)

View File

@ -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

View File

@ -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;
}
}

View File

@ -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;

View File

@ -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 *);

View File

@ -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

View File

@ -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))) {

View File

@ -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;
}

View File

@ -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:

View File

@ -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
])

View File

@ -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;

View File

@ -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));

View File

@ -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);

View File

@ -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;

View File

@ -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

View File

@ -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);

View File

@ -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 = *~ */*~

View File

@ -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

View File

@ -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 {

View File

@ -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

View File

@ -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];

View File

@ -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];

View File

@ -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",

View File

@ -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);

View File

@ -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*) &notInd);
}
/* 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",

View File

@ -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;

View File

@ -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;

View File

@ -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;

5
tools/.gitignore vendored
View File

@ -2,4 +2,7 @@
/misdn_info
/misdn_log
/misdn_rename
/misdn_E1test
/misdn_E1test
/isdn_text2wireshark
/logger_config_parser.c
/misdnlogger

View File

@ -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;
}
}

View File

@ -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'

View File

@ -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) {

View File

@ -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);
}

2346
tools/logger.c Normal file

File diff suppressed because it is too large Load Diff

124
tools/logger.h Normal file
View File

@ -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 */

View File

@ -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;
}

View File

@ -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))

View File

@ -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

View File

@ -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);
}

View File

@ -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;