New test equipment

I (finally) got some test equipment for ISDN / SS7 / GSM development, first thing i managed to buy at an auction on eBay is a Siemens K1103 Protocol Analyzer (monitoring only). The newest “member of the family” is a HP 37900D Protocol Analyzer / Simulator. Both are PRI only so the next thing i’ll have to get is at least one PRI card.

I’d have preferred to get a HFC based one (mISDN is part of the kernel now…), but the prices of those are really insane, i could easily get a double port PCIe card from Digium / OpenVOX / whatever for the amount a single Port HFC-E card would usually cost (~500 – 700Eur)…

I’ll probably just buy some cheap chinese TE110P clones on eBay (cheap as in _really_ cheap, 85Eur + shipping) and hope they’re working reliably enough to use them. 400 – 700Eur is just too much for what is still a hobby (and no, asking vendors to get stuff for free/discounted for OSS development isn’t what i’m going to do).

UPDATE: Minimum record for HFC-E1 cards: 350Eur (+ shipping), an italian online shop.

Random development ideas: mod_upnp

A module based on the (MIT-licensed) MiniUPnP client library that uses UPnP (of course) to auto-discover your router and (with the help of FS’s events) magically forwards RTP traffic on-demand to your FreeSWITCH server.

UPDATE: FreeSWITCH got PMP / UPnP support in the core now, so this item is obsolete now.

Achievement of the day:

openzap overview

(Click to view in full scale)

OpenZAP ISDN: Past, Present and (possible) Future

Well, i had originally planned to make this a long entry about the history of the OpenZAP ISDN stack, what i’ve changed in the past months and how i think it should look and work like in the future, but…

… life sucks and stupid problems ususally come up at the worst time possible.

Let’s start with a short introduction to OpenZAP’s past:

The original OpenZAP ISDN has been written by Case Labs Ltd. and released under a BSD License. It contains both, Q.921 and Q.931 parts, that are loosely coupled. The Q.931 part has been designed to support multiple dialects (e.g. 5ESS, DMS etc.), which is a good thing, since OpenZAP is used by people in different countries and continents.

The old stack “works”… most of the time… well, unless something slighty unexpected happens…

It lacks proper stateful handling of messages, error handling, timers, the higher level API used in ozmod_isdn.c is message-centric instead of call-centric…. in short:

It’s a big mess.

The present:

I started in summer 2008 by rewriting most of the Q.921 layer based on the ITU-T specs (to add BRI support). That work is 80% complete, there are still a couple of things that have to be adressed e.g. error handling (FRMR etc.), resending of frames and sending/receiving events from/to Q.931 (Link activation and deactivation events for example). The initial goal however has been reached, BRI support works (Point-to-Point and Point-to-Multipoint mode) and the Q.921 layer is stateful and has working timers, which is a big improvement compared to what was there before i started.

Of course, if you start working on one part of the stack, you’ll have to touch the other one too…

… so i continued my rampage through the OpenZAP ISDN stack by trying to rewrite the Q.931 stack internals and its API. The current state of that work is available in the so called “api” branch of my private OpenZAP GIT repository on oss.axsentis.de (here is a link to the gitweb running on the server). There are already a lot of changes:

  • A ton of the message decoding/encoding functions have been replaced by a pair of generic ones.
  • The whole thing is stateful, which solves a lot of problems (like some stupid hacks to create a proper response to STATUS ENQUIRY out of the OpenZAP channel states (urgh)).
  • Initial support for timers is in the works (depends on some other bits, but i’ve made some progress this weekend)
  • Proper checking of messages:  Is this message valid in the current call state? Are those Information Elements (IEs) allowed? Are some mandatory ones missing?  -  A lot of that has been added (still needs some work though and testing)
  • API rework:   Slowly making some progress, there’s some initial code to send and queue events to the higher layer now (only for the Q.931 NT dialect right now).

Future:

So, where are we heading?

Let’s start with the high-level api part. The current API works by passing Q.931 messages to the API, which is nice and allows for some *cough* flexibility, but makes life harder on the upper level (creating custom messages piece by piece, keeping track of OpenZAP channel <-> Q.931 call pairs via their CRV (Call Reference Value) etc.). We’d like to retain some of that freedom (sending custom messages) but get rid of most of the manual plumbing by replacing it with a call-centric API. The goal here is being abled to do something like:

struct Q931_Call *call = Q931CallNew(trunk);
/* Add all the details like, Caller ID, Destination number etc.
 * (we'd still need to find a sane way to do that...)
 */

/* Associate the call with our higher level handle */
Q931CallSetPrivate(call, ourhandle);

/* Make the call */
Q931CallSend(call);   /* or something like that */

If you really want to know what this looks like in the old code, ozmod_isdn.c:isdn_request_channel() has it all (pretty, isn’t it?).

I’m taking a little shortcut for now (it’s getting late).

To understand the codebase a little, the most important names:

  • Q931call.c – Call specific functions, timers, lookup by CRV etc.
  • Q931mes.c – Message handling functions, generic message unpack / pack functions (Q931Umes_Generic, Q931Pmes_Generic), Table with Message <-> allowed IE lists for the (= base) Q.931 dialect.
  • Q931State*.c -  Q.931 TE / NT mode Dialect initialization function, Message processing functions and timer callbacks. Either mode is handled as a separate dialect!
  • Q931ie.c  -  Information Element pack / unpack functions (Q931Pie_* and Q931Uie_*).
  • Q931api.c – Misc (API) functions
  • Q931.c – Input / Output routines (Q931Rx* Q931Tx*, Note: Q931Rx43 means: Message coming from Layer 4 into Layer 3 (this is what gets called to send messages from ozmod_isdn.c to the Q.931 stack);   Q931Tx34: Send message to Layer 4), Logging functions, some Dummy functions (that should be moved somewhere else), also things like Q931Umes() : Wrapper functions; Initialization (and tons of other stuff).
  • Q931dialect.c – Dialect handling.
  • 5ESS/* -  5ESS Dialect (work-in-progress, started porting this one over to find parts of the dialect and message handling stuff that need refinement to support other dialects).

to be continued…

CELT support moving into Opal trunk

The last few issues with 32KHz mode and RTP timing have been resolved and the patches are being merged into Opal’s svn trunk.

Hi-def 48KHz VoIP with Ekiga

Took a little longer than planned, due to various little problems that added up, but here it is:

http://oss.axsentis.de/people/stkn/freeswitch/opal-3.4.2-32khz-48khz-celt-codec.patch

A patch that adds 32KHz, 48 KHz sample rate support and a CELT codec plugin to Opal, enabling Ekiga to use the new Ultra-Wideband ulta-low-delay codec developed by Jmspeex of xiph.org.

There are still some glitches in the output (not sure if it’s my code causing them or the codec itself, need to investigate further), but it still sounds totally awesome playing one of my favourite songs.

The patch is for the svn version of opal but can be applied to the latest release tarball too.Note: you have to autoreconf and reconfigure + rebuild after applying the patch to opal.

For those interested in the original annoucement that caused this work:

Another FreeSWITCH First: 48k VoIP

UPDATE: Changed patch URL, and here are a couple of other fixes for opal-3.4.2 and opal-3.5.1 you’ll find useful:

http://oss.axsentis.de/people/stkn/freeswitch/opal-3.4.2-ac_define-fixes.patch

http://oss.axsentis.de/people/stkn/freeswitch/opal-3.4.2-fix-h460-define.patch

http://oss.axsentis.de/people/stkn/freeswitch/opal-3.5.1-ac_define-fixes.patch

mod_ssh: yet another status update

test02 freeswitch-trunk # ssh -p2222 test@localhost
test@localhost's password:
Welcome to FreeSWITCH on test02

fs[1423]/test@test02#

That’s the new (not finished) terminal emulation, together with a customized (well, current ssh.conf.xml default) prompt.

mod_ssh status

Supported features:

  • Useraccounts in ssh.conf.xml, passwords in cleartext, SHA1 or MD5 hashed
  • Connection timeout, listen ip and port configuration via ssh.conf.xml (default: 127.0.0.1 port 2222)
  • Password-based ssh authentication only, the server part of libssh doesn’t support public-key auth at the moment
  • Connecting via ssh client and entering api commands works, the commands will be executed and the result sent to the client. Mod_ssh is still lacking a (simple) terminal emulator so line editing etc. won’t work.
  • Logout via “…” or “logout” (use the “shutdown” api command to shut the switch down)
  • “ssh” api commands to list/kick active sessions and list/lock/unlock accounts

Even more progress…

Output has been cleaned up:

freeswitch@test02> ssh account
API CALL [ssh(account)] output:
===================== Accounts =====================
Username        | Auth-types
----------------------------------------------------
foobar          | password
test            | password
=================================[  2 account(s) ]==

freeswitch@test02> ssh session
API CALL [ssh(session)] output:
===================== Sessions =====================
Username        | Online since        | Misc.
----------------------------------------------------
               - No active sessions -
====================================================

freeswitch@test02> 2008-11-28 17:43:49 [NOTICE] mod_ssh.c:512 ssh_handle_message() User "test" logged in
2008-11-28 17:43:49 [NOTICE] mod_ssh.c:583 ssh_handle_message() User "test" opened a shell session

freeswitch@test02> ssh session
API CALL [ssh(session)] output:
===================== Sessions =====================
Username        | Online since        | Misc.
----------------------------------------------------
test            | 2008-11-28 17:43:49 |
=================================[  1 session(s) ]==

And another command works now:

freeswitch@test02> ssh session kick test
API CALL [ssh(session kick test)] output:
+OK: 1 session(s) kicked

freeswitch@test02> ssh session
API CALL [ssh(session)] output:
===================== Sessions =====================
Username        | Online since        | Misc.
----------------------------------------------------
               - No active sessions -
====================================================

freeswitch@test02>

Some “minor” progress…

stkn@test02 ~ $ ssh -p2222 test@localhost
test@localhost’s password:
[15315] 2008-11-28 12:20:54 API CALL [version()] output:
FreeSwitch Version 1.0.trunk (10523M)

[15315] 2008-11-28 12:20:56 API CALL [status()] output:
Content-Type: text/html

UP 0 years, 0 days, 0 hours, 0 minutes, 57 seconds, 5 milliseconds, 204 microseconds
0 session(s) since startup
0 session(s) 0/30

logoutReceived disconnect from 127.0.0.1: 11: Bye Bye
stkn@test02 ~ $

Next Page »