FreeSWITCH ebuilds updated

Ebuilds for FreeSWITCH-1.0.5_pre3 and FreeSWITCH-sounds-1.0.12 are now in the axsentis-overlay.


Project: LibISDN ASN.1 En-/Decoder

Motivation: Handle Q.932 ROSE RPC calls.

Status: Early code, decoding mostly works, parts have to be rewritten for encoding to work (in a usable way).

Target Milestone: Being able to handle incoming MWI request from my ISDN phone and sent an answer that will make the icon on its LC-Display light up.

Project: libRTCP

Motivation: En-/Decoding of RTCP messages.

Status: Early version, can already decode some RTCP messages, needs more work.

Target Milestone: Working en-/decoding of XR and most other RTCP messages.

Project: mod_netlink

Motivation: Receive netlink events from linux kernel about IP-Address and HW-Configuration changes and inject them into the FreeSWITCH core.

Status: Some proof-of-concept code written (Binding to netlink multicast groups and receiving events + dumping them in hex+ascii / text)

Notes: Will need linux-2.6.30+ (unless you really want to run FreeSWITCH as root).

Target Milestone: Turn PoC code into mod_netlink.c, handle incoming network interface + ip address change events, handle incoming CPU up/down events, turn them into FreeSWITCH events.

Project: mod_http_rpc

Motivation: Current mod_xml_rpc sucks.

Status: Basic HTTP access works, using embedded mongoose.

Target Milestone: HTTP/XML-RPC API calls working, authentication via user directory.

Project: RTP Acceleration

Motivation: 10k+ calls on a single box, without ending up in context-switch hell caused by RTP recv/send syscalls.

Status: Working on early proof-of-concept code (userspace UDP/IP stack).

Notes: New test hardware: Managed 8-port 1GigE (HP 1800-8G, ~11.6Mpps), Dual-Port PCIe Intel 1000/PT, two Broadcom NetXtreme BCM5721 PCIe cards. Full setup will be completed after dead PSU has been replaced in test01.

Next milestone: Get UDP recv+send and ARP working in PoC, adapt code to lastest TX-Ring changes in 2.6.31+, start benchmarking.

Project: Improve FreeSWITCH startup time by starting modules in parallel

Motivation: Spend less time loading and initializing modules, some of which may block for some time in their startup function. Track inter-module dependencies and parallelize loading using a set/pool of threads executing the startup routines.

Status: Planning

Project: Improve configuration option handling of OpenZAP modules

Motivation: The current situation sucks completely

Status: Some option handling code written, needs to be integrated into OpenZAP (+ modified to fit)

Next milestone: Try to integrate this into OpenZAP, using mod_isdn

Project: Complete clean rewrite of the FreeSWITCH buildsystem using GNU Make, current Autools, system libs and support for the FHS.

Motivation: Meh… (we already depend on GNU Make anyway and some of us are able to roll their own controlled environment)

Status: Already started this some time ago, need to find a way to create a GIT repo that only contains and syncs the source code parts.

Target Milestone: Build core and most important modules using system libs, maybe add some of that fancy “make mod_foo” stuff via a makefile include that adds the neccessary rules. Add proper pkg-config support for the core (and remove fsxs).

Project: New work desk.

Motivation: Totally sucks to have no space to put stuff on (one of the reasons there’s not much progress in LibISDN development right now)

Status: Need to get vacation first (*sigh*)

FreeSWITCH-1.0.4 released!

Ebuilds have been updated. The freeswitch-sounds-1.0.11 ebuild includes support for the russian ‘elena’ set, use LINGUAS=”ru_RU” to install it.

Ebuilds are here: axsentis overlay Git repository

See for the announcement.

libisdn: ASN.1

This has been on my ToDo list for a while now. Decoding works so far, but i’ll have to change things a bit to get encoding working too. Sample output:

successfully decoded ASN.1 BER data
duration 0 seconds, 102419 nanoseconds

===================================== ASN.1 =====================================

context specific element, tag: 1
        integer:        757
                context specific element, tag: 1
                        context specific element, tag: 0, size: 4 octets
                              [ 31 30 30 31 ]
                context specific element, tag: 2
                        enumerated:     0
                context specific element, tag: 3
                        integer:        0
                context specific element, tag: 4
                        context specific element, tag: 0, size: 4 octets
                              [ 31 30 30 31 ]
                context specific element, tag: 6
                                integer:        0
                                enumerated:     0


This is an MWI Indication Invocation call sent from the ISDN phone on my desk to the OpenZAP NT it is connected to.

libisdn: call information dumping

Still have to change a couple of things here to get it working with the “api” interface of the OpenZAP module, but this is what it looks like right now:

API CALL [oz(isdn dump 1 calls)] output:
+OK call information dumped to log      

2009-07-07 23:55:22.500881 [DEBUG] Span:1 Information of all active calls:
==================================== Calldump ===================================
* CRV:  76 (0x76)                                                                
        Global call:   No                                                        
        Direction:     Inbound                                                   
        State:         258 'Overlap sending'
        L4 User data:  0x24632e0
        Timer:         T302, timeout in: 14372 ms, expire count: 0
        Events queued: 0
-----------------------------------------------------------------[  1 call(s) ]--

Command to get this output (debug loglevel!): oz isdn dump <span id> calls


libisdn: advanced error reporting, part 1

Just a short update on libisdn (the current name of the OpenZAP ISDN stack), before i fall asleep

This is how IE errors will be reported as of now, if you’ve turned on debug loglevel (i’m only abusing ERR for the pretty red color):

2009-07-07 01:02:25.848853 [ERR] Span:1 Message parser error(s)
=================== Errors reported for message -   5 (0x05) ===================
* IE id:  24 (0x18), name: "N/A", size:   3, offset:   9

  [01]  error message: Size invalid
        diagnostic:    Message element is either too small or too large
        details:       expected size: 3 - 0 octet(s)
                |-{9}-> 18 01 83

---------------------------------------------------------------[  1 error(s) ]--

I’m going to add some more information (IE / Message names / Call info) in the future. Next step is to change parts of the message decoding function to relax some of the IE checks or, if possible, skip decoding a faulty IE so we can still check them all and report multiple issues in one report. Another thing we can add now is diagnostic information in Cause IEs sent to the other side (e.g. ID of the invalid IE in a message).

UPDATE: Some minor modifications to the output format:

2009-07-07 21:52:55.38692 [DEBUG] Span:1 Q931Umes[Q.931 NT][5]() returned -3002
2009-07-07 21:52:55.38692 [ERR] Span:1 Message parser error(s)
=================== Errors reported for message -   5 (0x05) ===================
* IE id:   4 (0x04), name: "N/A", size:   5, offset:   4

  <01>  error message: Not allowed here
        description:   Message element is not allowed in this state/message
        details:       N/A
        raw octets:
              [ 04 03 80 90 a3 ]

---------------------------------------------------------------[  1 error(s) ]--

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 (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).


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…

« Previous PageNext Page »