chan_capi with Asterisk 10.12

When configured for ISDN lines, updating Asterisk usually requires to upgrade chan_capi, too – else you risk running into i.e. SEGV crashes during Asterisk start-up.

The upgrade within a single version usually is a matter of minutes, especially if you have prepared the chan_capi module in advance. You need the latest Asterisk development package plus a (probably current) source archive of chan_capi.

Trouble compiling chan_capi against Asterisk 10.12

Our latest upgrade experience was a bit different, though: After fetching and installing the latest development packages for Asterisk (version 10.12.1 in our case) and the sources for chan_capi 1.1.6, invoking “make” resulted in a tirade of error messages.

Having let out a major sigh and then trying to estimate the efforts required to adopt chan_capi to the suspected changes in Asterisk’s API, it quickly became apparent that those messages all concerned long-established API features, which chan_capi’s code didn’t seem to expect. This came as a surprise to us, as chan_capi is well-maintained – and indeed, it wasn’t the sources’ fault, but caused by the version detection script “create_config.sh” (contained in the chan_capi tar ball), which decided we had an unknown version of Asterisk, so it’d be safest to use API version 1.2:

 # ./create_config.sh /usr/include
Checking Asterisk version... 10.12.1
Using Asterisk 1.2 API
 * found stringfield in ast_channel
 * found 'indicate' with data
 * no extended ast_channel_alloc
 * found second extended ast_channel_alloc
 * found send_digit_end with duration
 * without generic jitter-buffer patch
config.h complete

The problem arises from the pattern matching in the create_config.sh script, used to distinguish the version numbers:

case "$AVERSIONNUM" in
        100*)
                echo "#define CC_AST_HAS_VERSION_1_6" >>$CONFIGFILE
                echo "#define CC_AST_HAS_VERSION_1_8" >>$CONFIGFILE
                echo "#define CC_AST_HAS_VERSION_10_0" >>$CONFIGFILE
                echo "#define CC_AST_HAS_EVENT_MWI"   >>$CONFIGFILE
                echo " * found Asterisk version 10"
                VER=10_0
                ;;
        108*)
                echo "#define CC_AST_HAS_VERSION_1_6" >>$CONFIGFILE
                echo "#define CC_AST_HAS_VERSION_1_8" >>$CONFIGFILE
                echo "#define CC_AST_HAS_EVENT_MWI"   >>$CONFIGFILE
                echo " * found Asterisk version 1.8"
                VER=1_8
                ;;
        106*)
                echo "#define CC_AST_HAS_VERSION_1_6" >>$CONFIGFILE
                echo "#define CC_AST_HAS_EVENT_MWI"   >>$CONFIGFILE
                echo " * found Asterisk version 1.6"
                VER=1_6
                ;;
        104*)
                echo "#define CC_AST_HAS_VERSION_1_4" >>$CONFIGFILE
                echo " * found Asterisk version 1.4"
                VER=1_4
                ;;
        99999)
                echo "#define CC_AST_HAS_VERSION_1_4" >>$CONFIGFILE
                echo " * assuming Asterisk version 1.4"
                VER=1_4
                ;;
        999999)
                echo "#define CC_AST_HAS_VERSION_1_6" >>$CONFIGFILE
                echo " * assuming Asterisk version 1.6"
                VER=1_6
                ;;
        *)
                if [ "$VER" = "1_6" ]; then
                        echo "#define CC_AST_HAS_VERSION_1_6" >>$CONFIGFILE
                        echo " * assuming Asterisk version 1.6"
                else
                        echo "#undef CC_AST_HAS_VERSION_1_4" >>$CONFIGFILE
                fi
                ;;
esac

With this scheme, some version 10.aa.bb cannot easily be distinguished from 1.0a.ab, as further up in the code, AVERSIONNUM is set to a pseudo-numeric string without the separating “.”.

The fix

The solution seems fairly easy: don’t use the “match-all” wildcard (“*”), but rather take the length of the string into account, too. If you then change the code to assume that any version 10 can be supported, you end with:

case "$AVERSIONNUM" in
        10????)
                echo "#define CC_AST_HAS_VERSION_1_6" >>$CONFIGFILE
                echo "#define CC_AST_HAS_VERSION_1_8" >>$CONFIGFILE
                echo "#define CC_AST_HAS_VERSION_10_0" >>$CONFIGFILE
                echo "#define CC_AST_HAS_EVENT_MWI"   >>$CONFIGFILE
                echo " * found Asterisk version 10"
                VER=10_0
                ;;
        108??)
                echo "#define CC_AST_HAS_VERSION_1_6" >>$CONFIGFILE
                echo "#define CC_AST_HAS_VERSION_1_8" >>$CONFIGFILE
                echo "#define CC_AST_HAS_EVENT_MWI"   >>$CONFIGFILE
                echo " * found Asterisk version 1.8"
                VER=1_8
                ;;
        106??)
                echo "#define CC_AST_HAS_VERSION_1_6" >>$CONFIGFILE
                echo "#define CC_AST_HAS_EVENT_MWI"   >>$CONFIGFILE
                echo " * found Asterisk version 1.6"
                VER=1_6
                ;;
        104??)
                echo "#define CC_AST_HAS_VERSION_1_4" >>$CONFIGFILE
                echo " * found Asterisk version 1.4"
                VER=1_4
                ;;
        99999)
                echo "#define CC_AST_HAS_VERSION_1_4" >>$CONFIGFILE
                echo " * assuming Asterisk version 1.4"
                VER=1_4
                ;;
        999999)
                echo "#define CC_AST_HAS_VERSION_1_6" >>$CONFIGFILE
                echo " * assuming Asterisk version 1.6"
                VER=1_6
                ;;
        *)
                if [ "$VER" = "1_6" ]; then
                        echo "#define CC_AST_HAS_VERSION_1_6" >>$CONFIGFILE
                        echo " * assuming Asterisk version 1.6"
                else
                        echo "#undef CC_AST_HAS_VERSION_1_4" >>$CONFIGFILE
                fi
                ;;
esac

This, unfortunately, does only get you to compile against version 10.0x – but there’s a patch on the net that adds the required changes to the source and create_config.sh to adopt to a change introduced in Asterisk version 10.11.1 – once that is applied, too, you’re all set to compile and use chan_capi 1.1.6 with Asterisk 10.12!

Further up in the create_config.sh script, some measures are taken to detect “unset” version numbers, i.e. to work with latest development versions. As these are script-internally set to three-digit numbers, those would have to be changed to have the length required by the new “case” patterns – but that’s no show stopper, for sure 😉

As a side note: The HEAD version as of 2013-02-23 already contains the required changes for Asterisk 10.11, but it’s create_config.sh still chokes on the 10.1x version numbers… so until the above script changes have been incorporated upstream, you’ll still need to update at least that single pattern for your specific 10.x or 11.x case.

This entry was posted in Asterisk, howto, Linux. Bookmark the permalink.

Leave a Reply