From 17b8c591af45939545f7e1dc35e40fe3f35997de Mon Sep 17 00:00:00 2001 From: Felix Fietkau Date: Mon, 2 Feb 2009 17:26:20 +0000 Subject: [PATCH] sync some packages with trunk SVN-Revision: 14365 --- ...-rename-tslibdevice-option-to-device.patch | 29 + .../patches/011-ifdef-debug-output.patch | 58 + .../patches/012-deleteinput.patch | 39 + Xorg/xorg/xserver/xorg-kdrive/Config.in | 28 + Xorg/xorg/xserver/xorg-kdrive/Makefile | 147 ++ .../patches/001-tslib.patch | 0 .../patches/002-480x640-support.patch | 0 Xorg/xorg/xserver/xorg-server/Makefile | 248 +-- .../020-fix-dri-build-without-xinerama.patch | 44 + net/asterisk-1.4.x/Makefile | 7 +- .../patches/023-autoconf-chan_h323.patch | 18 +- .../patches/030-acinclude.patch | 20 +- .../035-main-asterisk-uclibc-daemon.patch | 52 +- net/asterisk-1.6.x/Makefile | 12 +- net/asterisk-addons-1.4.x/Makefile | 2 +- .../patches/011-chan_mobile.patch | 1611 +++++++++-------- net/hiawatha/Makefile | 55 + net/hiawatha/files/httpd.conf | 115 ++ net/hiawatha/files/mimetype.conf | 16 + .../100-add_x_requested_http_headers.patch | 11 + net/stun/Makefile | 2 +- net/stun/patches/002-linking_order.patch | 19 + utils/dt/Makefile | 53 + 23 files changed, 1547 insertions(+), 1039 deletions(-) create mode 100644 Xorg/driver/xf86-input-tslib/patches/010-rename-tslibdevice-option-to-device.patch create mode 100644 Xorg/driver/xf86-input-tslib/patches/011-ifdef-debug-output.patch create mode 100644 Xorg/driver/xf86-input-tslib/patches/012-deleteinput.patch create mode 100644 Xorg/xorg/xserver/xorg-kdrive/Config.in create mode 100644 Xorg/xorg/xserver/xorg-kdrive/Makefile rename Xorg/xorg/xserver/{xorg-server => xorg-kdrive}/patches/001-tslib.patch (100%) rename Xorg/xorg/xserver/{xorg-server => xorg-kdrive}/patches/002-480x640-support.patch (100%) create mode 100644 Xorg/xorg/xserver/xorg-server/patches/020-fix-dri-build-without-xinerama.patch create mode 100644 net/hiawatha/Makefile create mode 100644 net/hiawatha/files/httpd.conf create mode 100644 net/hiawatha/files/mimetype.conf create mode 100644 net/hiawatha/patches/100-add_x_requested_http_headers.patch create mode 100644 net/stun/patches/002-linking_order.patch create mode 100644 utils/dt/Makefile diff --git a/Xorg/driver/xf86-input-tslib/patches/010-rename-tslibdevice-option-to-device.patch b/Xorg/driver/xf86-input-tslib/patches/010-rename-tslibdevice-option-to-device.patch new file mode 100644 index 000000000..dd36fa2e9 --- /dev/null +++ b/Xorg/driver/xf86-input-tslib/patches/010-rename-tslibdevice-option-to-device.patch @@ -0,0 +1,29 @@ +commit fe65976e2f006643950e70d33684b91c33a87e3a +Author: Lars-Peter Clausen +Date: Sun Feb 1 16:42:27 2009 +0100 + + Rename "TslibDevice" option to "Device" to be more consistant with other + drivers. + +diff --git a/src/tslib.c b/src/tslib.c +index edc14b2..e91a949 100644 +--- a/src/tslib.c ++++ b/src/tslib.c +@@ -73,7 +73,7 @@ struct ts_priv { + }; + + static const char *DEFAULTS[] = { +- "TslibDevice", "/dev/event0", ++ "Device", "/dev/event0", + NULL + }; + +@@ -334,7 +334,7 @@ xf86TslibInit(InputDriverPtr drv, IDevPtr dev, int flags) + priv->rotate = TSLIB_ROTATE_NONE; + } + +- s = xf86SetStrOption(pInfo->options, "TslibDevice", NULL); ++ s = xf86SetStrOption(pInfo->options, "Device", NULL); + + priv->ts = ts_open(s, 0); + if (!priv->ts) { diff --git a/Xorg/driver/xf86-input-tslib/patches/011-ifdef-debug-output.patch b/Xorg/driver/xf86-input-tslib/patches/011-ifdef-debug-output.patch new file mode 100644 index 000000000..83b2bc5a4 --- /dev/null +++ b/Xorg/driver/xf86-input-tslib/patches/011-ifdef-debug-output.patch @@ -0,0 +1,58 @@ +commit 69fcc78ea931f8a84497f4ee9021f4493f45a778 +Author: Lars-Peter Clausen +Date: Sun Feb 1 16:44:24 2009 +0100 + + Put #ifdef DEBUG around debug output. + +diff --git a/src/tslib.c b/src/tslib.c +index e91a949..ad43abb 100644 +--- a/src/tslib.c ++++ b/src/tslib.c +@@ -80,21 +80,27 @@ static const char *DEFAULTS[] = { + static void + BellProc(int percent, DeviceIntPtr pDev, pointer ctrl, int unused) + { ++#ifdef DEBUG + ErrorF("%s\n", __FUNCTION__); ++#endif + return; + } + + static void + KeyControlProc(DeviceIntPtr pDev, KeybdCtrl * ctrl) + { ++#ifdef DEBUG + ErrorF("%s\n", __FUNCTION__); ++#endif + return; + } + + static void + PointerControlProc(DeviceIntPtr dev, PtrCtrl * ctrl) + { ++#ifdef DEBUG + ErrorF("%s\n", __FUNCTION__); ++#endif + return; + } + +@@ -186,7 +192,9 @@ xf86TslibControlProc(DeviceIntPtr device, int what) + int i; + struct ts_priv *priv; + ++#ifdef DEBUG + ErrorF("%s\n", __FUNCTION__); ++#endif + pInfo = device->public.devicePrivate; + priv = pInfo->private; + +@@ -258,7 +266,9 @@ xf86TslibControlProc(DeviceIntPtr device, int what) + static void + xf86TslibUninit(InputDriverPtr drv, InputInfoPtr pInfo, int flags) + { ++#ifdef DEBUG + ErrorF("%s\n", __FUNCTION__); ++#endif + xf86TslibControlProc(pInfo->dev, DEVICE_OFF); + xfree(pInfo->private); + } diff --git a/Xorg/driver/xf86-input-tslib/patches/012-deleteinput.patch b/Xorg/driver/xf86-input-tslib/patches/012-deleteinput.patch new file mode 100644 index 000000000..b8460d381 --- /dev/null +++ b/Xorg/driver/xf86-input-tslib/patches/012-deleteinput.patch @@ -0,0 +1,39 @@ +commit de4ec145ea88253dc469ee81f094fa73de36b773 +Author: Lars-Peter Clausen +Date: Sun Feb 1 16:54:55 2009 +0100 + + Call xf86DeleteInput in UnInit or if something goes wrong in the Init procedure. + If xf86DeleteInput is not called the server will end up with corrupted memory. + +diff --git a/src/tslib.c b/src/tslib.c +index ad43abb..3eba078 100644 +--- a/src/tslib.c ++++ b/src/tslib.c +@@ -271,6 +271,7 @@ xf86TslibUninit(InputDriverPtr drv, InputInfoPtr pInfo, int flags) + #endif + xf86TslibControlProc(pInfo->dev, DEVICE_OFF); + xfree(pInfo->private); ++ xf86DeleteInput(pInfo, 0); + } + + /* +@@ -347,15 +348,17 @@ xf86TslibInit(InputDriverPtr drv, IDevPtr dev, int flags) + s = xf86SetStrOption(pInfo->options, "Device", NULL); + + priv->ts = ts_open(s, 0); ++ xfree(s); ++ + if (!priv->ts) { + ErrorF("ts_open failed (device=%s)\n",s); ++ xf86DeleteInput(pInfo, 0); + return NULL; + } + +- xfree(s); +- + if (ts_config(priv->ts)) { + ErrorF("ts_config failed\n"); ++ xf86DeleteInput(pInfo, 0); + return NULL; + } + diff --git a/Xorg/xorg/xserver/xorg-kdrive/Config.in b/Xorg/xorg/xserver/xorg-kdrive/Config.in new file mode 100644 index 000000000..1644e0602 --- /dev/null +++ b/Xorg/xorg/xserver/xorg-kdrive/Config.in @@ -0,0 +1,28 @@ +menu "kdrive library support" +depends on PACKAGE_xserver-kdrive-xvesa || PACKAGE_xserver-kdrive-xfbdev || PACKAGE_xserver-kdrive-xglamo || PACKAGE_xserver-kdrive-xephyr + + config X_TSLIB + bool + prompt "enable support for tslib" + +# config X_XCALIBRATE +# bool +# prompt "enable support for xcalibrate" + +# config X_DRI +# bool +# prompt "enable support for DRI" + + config X_COMPOSITE + bool + prompt "enable support for composite" + + config X_XINERAMA + bool + prompt "enable support for xinerama" + +# config X_GLX +# bool +# prompt "enable support for GLX" + +endmenu diff --git a/Xorg/xorg/xserver/xorg-kdrive/Makefile b/Xorg/xorg/xserver/xorg-kdrive/Makefile new file mode 100644 index 000000000..6c23468b9 --- /dev/null +++ b/Xorg/xorg/xserver/xorg-kdrive/Makefile @@ -0,0 +1,147 @@ +# +# Copyright (C) 2009 OpenWrt.org +# +# This is free software, licensed under the GNU General Public License v2. +# See /LICENSE for more information. +# +# $Id$ + +include $(TOPDIR)/rules.mk + +PKG_NAME:=xserver-kdrive +PKG_RELEASE:=1 +PKG_VERSION:=1.5.1 +PKG_SOURCE_URL:=http://xorg.freedesktop.org/releases/X11R7.4/src/xserver/ +PKG_SOURCE:=xorg-server-$(PKG_VERSION).tar.bz2 +PKG_BUILD_DIR=$(BUILD_DIR)/Xorg/xserver/$(PKG_NAME)/xorg-server-$(PKG_VERSION)/ +PKG_BUILD_DEPENDS:=randrproto renderproto fixesproto damageproto xcmiscproto \ + xextproto xproto bigreqsproto resourceproto \ + fontsproto inputproto kbproto videoproto resourceproto \ + xf86dgaproto xtrans xf86driproto calibrateproto \ + compositeproto xineramaproto +PKG_INSTALL:=1 + +include $(INCLUDE_DIR)/package.mk + +define Package/xserver-kdrive-xvesa/config + source "$(SOURCE)/Config.in" +endef + +define Package/xserver-kdrive/Default + PROVIDES:=xserver + SECTION:=xorg-server + CATEGORY:=Xorg + SUBMENU:=server + URL:=http://xorg.freedesktop.org/ + DEPENDS:=@!avr32 \ + +xserver-common \ + +libpthread \ + +libxkbfile \ + +libXfont \ + +libXau \ + +libXv \ + +libfontenc \ + +pixman \ + +libopenssl \ + @DISPLAY_SUPPORT \ + +X_TSLIB:tslib \ + +X_DRI:libdrm +endef + +define Package/xserver-kdrive-xvesa +$(call Package/xserver-kdrive/Default) + TITLE:=Kdrive vesa xserver + DEPENDS+= @TARGET_x86 +endef + +define Package/xserver-kdrive-xfbdev +$(call Package/xserver-kdrive/Default) + TITLE:=Kdrive framebuffer xserver +endef + +define Package/xserver-kdrive-xephyr +$(call Package/xserver-kdrive/Default) + TITLE:=Kdrive ephyr xserver +endef + +STAMP_CONFIGURED:=$(STAMP_CONFIGURED)_$(call confvar, \ + CONFIG_PACKAGE_xserver-kdrive-xvesa CONFIG_PACKAGE-xserver-kdrive-fbdev \ + CONFIG_PACKAGE_xserver-kdrive-xephyr CONFIG_X_TSLIB CONFIG_X_COMPOSITE \ + CONFIG_X_XINERAMA CONFIG_X_XCALIBRATE) + +define Build/Configure + $(call Build/Configure/Default, \ + --enable-kdrive \ + $(if $(CONFIG_PACKAGE_xserver-kdrive-xvesa), \ + --enable-kdrive-vesa, \ + --disable-kdrive-vesa) \ + $(if $(CONFIG_PACKAGE_xserver-kdrive-xfbdev), \ + --enable-xfbdev, \ + --disable-xfbdev) \ + $(if $(CONFIG_PACKAGE_xserver-kdrive-xephyr), \ + --enable-xephyr, \ + --disable-xephyr) \ + $(if $(CONFIG_X_TSLIB),--enable-tslib,--disable-tslib) \ + $(if $(CONFIG_X_COMPOSITE),--enable-composite,--disable-composite) \ + $(if $(CONFIG_X_XINERAMA),--enable-xinerama,--disable-xinerama) \ + $(if $(CONFIG_X_XCALIBRATE),--enable-xcalibrate,--disable-xcalibrate) \ + --disable-xorg \ + --disable-aiglx \ + --disable-glx-tls \ + --disable-dga \ + --disable-xdmcp \ + --disable-xdm-auth-1 \ + --disable-config-hal \ + --disable-xf86misc \ + --disable-xf86vidmode \ + --disable-xf86bigfont \ + --disable-xorgcfg \ + --disable-xkb \ + --disable-xnest \ + --disable-xquartz \ + --disable-xwin \ + --disable-x11app \ + --disable-xsdl \ + --disable-xfake \ + --disable-install-setuid \ + --disable-kbd_mode \ + --disable-xvfb \ + --disable-xevie \ + --disable-xprint \ + --disable-xtrap \ + --disable-dmx \ + --disable-glx \ + --disable-xinerama \ + --disable-xfree86-utils \ + --disable-cup \ + --disable-xevie \ + --disable-evi \ + --disable-screensaver \ + --enable-builtin-fonts \ + ) +endef + +define Package/xserver-kdrive-xfbdev/install + $(INSTALL_DIR) $(1)/usr/bin + $(INSTALL_BIN) \ + $(PKG_INSTALL_DIR)/usr/bin/Xfbdev \ + $(1)/usr/bin/ +endef + +define Package/xserver-kdrive-xvesa/install + $(INSTALL_DIR) $(1)/usr/bin + $(INSTALL_BIN) \ + $(PKG_INSTALL_DIR)/usr/bin/Xvesa \ + $(1)/usr/bin/ +endef + +define Package/xserver-kdrive-xephyr/install + $(INSTALL_DIR) $(1)/usr/bin + $(INSTALL_BIN) \ + $(PKG_INSTALL_DIR)/usr/bin/Xephyr \ + $(1)/usr/bin/ +endef + +$(eval $(call BuildPackage,xserver-kdrive-xvesa)) +$(eval $(call BuildPackage,xserver-kdrive-xfbdev)) +$(eval $(call BuildPackage,xserver-kdrive-xephyr)) diff --git a/Xorg/xorg/xserver/xorg-server/patches/001-tslib.patch b/Xorg/xorg/xserver/xorg-kdrive/patches/001-tslib.patch similarity index 100% rename from Xorg/xorg/xserver/xorg-server/patches/001-tslib.patch rename to Xorg/xorg/xserver/xorg-kdrive/patches/001-tslib.patch diff --git a/Xorg/xorg/xserver/xorg-server/patches/002-480x640-support.patch b/Xorg/xorg/xserver/xorg-kdrive/patches/002-480x640-support.patch similarity index 100% rename from Xorg/xorg/xserver/xorg-server/patches/002-480x640-support.patch rename to Xorg/xorg/xserver/xorg-kdrive/patches/002-480x640-support.patch diff --git a/Xorg/xorg/xserver/xorg-server/Makefile b/Xorg/xorg/xserver/xorg-server/Makefile index 290303376..bca8c440b 100644 --- a/Xorg/xorg/xserver/xorg-server/Makefile +++ b/Xorg/xorg/xserver/xorg-server/Makefile @@ -1,10 +1,10 @@ # -# Copyright (C) 2006 OpenWrt.org +# Copyright (C) 2006-2009 OpenWrt.org # # This is free software, licensed under the GNU General Public License v2. # See /LICENSE for more information. # -# blogic@openwrt.org +# $Id$ include $(TOPDIR)/rules.mk @@ -13,101 +13,15 @@ PKG_RELEASE:=1 PKG_VERSION:=1.5.1 PKG_SOURCE_URL:=http://xorg.freedesktop.org/releases/X11R7.4/src/xserver/ PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.bz2 -PKG_BUILD_DIR=$(BUILD_DIR)/Xorg/xserver/xorg-server-$(PKG_VERSION)/ +PKG_BUILD_DIR=$(BUILD_DIR)/Xorg/xserver/$(PKG_NAME)-$(PKG_VERSION)/ PKG_BUILD_DEPENDS:=randrproto renderproto fixesproto damageproto xcmiscproto \ - xextproto xproto scrnsaverproto bigreqsproto resourceproto \ - fontsproto inputproto kbproto videoproto resourceproto \ - xf86dgaproto + xextproto xproto scrnsaverproto bigreqsproto resourceproto \ + fontsproto inputproto kbproto videoproto resourceproto \ + xf86dgaproto xtrans xf86driproto -include $(INCLUDE_DIR)/package.mk - -EXTRA_CFLAGS+= \ - -I$(STAGING_DIR)/usr/include/X11/GL \ - -I$(STAGING_DIR)/usr/include/X11/dri/ \ - -I$(STAGING_DIR)/usr/include/X11/ \ - -Wl,-rpath-link=$(STAGING_DIR)/usr/lib - -CONFIGURE_ARGS+= \ - --disable-aiglx \ - --disable-glx-tls \ - --disable-dga \ - --disable-xdmcp \ - --disable-xdm-auth-1 \ - --disable-config-hal \ - --disable-xf86misc \ - --disable-xf86vidmode \ - --disable-xf86bigfont \ - --disable-xorgcfg \ - --disable-xkb \ - --disable-xnest \ - --disable-xquartz \ - --disable-xwin \ - --disable-x11app \ - --disable-xsdl \ - --disable-xfake \ - --disable-install-setuid \ - --disable-kbd_mode \ - --disable-xvfb \ - --disable-xevie \ - --disable-xprint \ - --disable-xtrap \ - --disable-dmx \ - --disable-glx \ - --enable-builtin-fonts \ - --with-default-font-path=built-ins \ - -CONFIGURE_VARS+=ac_cv_file__usr_share_sgml_X11_defs_ent=yes +PKG_INSTALL:=1 -#FIXME: make full blowed xorg-xserver work - -#DEPENDS_SERVER:=+calibrateproto \ -# +compositeproto \ -# +damageproto \ -# +fixesproto \ -# +recordproto \ -# +resourceproto \ -# +scrnsaverproto \ -# +videoproto \ -# +xextproto \ -# +xproto \ -# +libXext \ -# +libXdmcp \ -# +libXfont \ -# +libXrandr \ -# +xtrans \ -# +libX11 \ -# +glproto \ -# +xf86driproto \ -# +applewmproto \ -# +dmxproto \ -# +printproto \ -# +windowswmproto \ -# +xf86rushproto \ -# +xproxymanagementprotocol \ -# +libdrm \ -# +xf86miscproto \ -# +xf86vidmodeproto \ -# +xf86dgaproto \ -# +trapproto \ -# +xineramaproto \ -# +evieext \ -# +libxkbfile \ -# +libXt \ -# +libSM \ -# +libxkbui \ -# +libXxf86misc \ -# +libXxf86vm \ -# +libXaw \ -# +libXmu \ -# +libXpm \ -# +libnotimpl \ -# +Mesa \ -# +pixman \ -# @DISPLAY_SUPPORT - -define Package/xserver-common/config - source "$(SOURCE)/Config.in" -endef +include $(INCLUDE_DIR)/package.mk X_CONFIG=generic ifeq ($(CONFIG_TARGET_olpc),y) @@ -118,7 +32,6 @@ ifeq ($(CONFIG_TARGET_om_gta02),y) endif define Package/xorg/Default - PROVIDES:=xserver SECTION:=xorg-server CATEGORY:=Xorg SUBMENU:=server @@ -126,11 +39,12 @@ define Package/xorg/Default URL:=http://xorg.freedesktop.org/ endef -define Package/xserver/Default +define Package/xserver-xorg $(call Package/xorg/Default) + PROVIDES:=xserver + TITLE:=Xorg xserver DEPENDS:=+xserver-common \ +libpthread \ - +xtrans \ +libxkbfile \ +libXfont \ +libXau \ @@ -139,43 +53,9 @@ $(call Package/xorg/Default) +pixman \ +libopenssl \ +libpciaccess \ - @DISPLAY_SUPPORT -endef - -define Package/xserver-xorg -$(call Package/xserver/Default) - PROVIDES:=xserver - TITLE:=Xorg xserver - DEPENDS+=+libdrm \ - +xf86driproto \ + +libdrm \ +libgl-mesa \ - +xineramaproto -endef - -define Package/xserver-kdrive/Default -$(call Package/xserver/Default) - DEPENDS+=+X_TSLIB:tslib \ - +X_DRI:xf86driproto \ - +X_DRI:libdrm \ - +X_XCALIBRATE:calibrateproto \ - +X_COMPOSITE:compositeproto \ - +X_XINERAMA:xineramaproto -endef - -define Package/xserver-kdrive-xvesa -$(call Package/xserver-kdrive/Default) - TITLE:=Kdrive vesa xserver - DEPENDS+=@TARGET_x86 -endef - -define Package/xserver-kdrive-xfbdev -$(call Package/xserver-kdrive/Default) - TITLE:=Kdrive framebuffer xserver -endef - -define Package/xserver-kdrive-xephyr -$(call Package/xserver-kdrive/Default) - TITLE:=Kdrive ephyr xserver + @DISPLAY_SUPPORT endef define Package/xserver-xorg-config @@ -191,30 +71,46 @@ endef define Build/Configure $(call Build/Configure/Default, \ - $(if $(CONFIG_PACKAGE_xserver-xorg),--enable-xorg --enable-dri,--disable-xorg --disable-dri) \ - $(if $(CONFIG_PACKAGE_xserver-kdrive-xvesa), \ - --enable-kdrive \ - --enable-kdrive-vesa, \ - --disable-kdrive-vesa) \ - $(if $(CONFIG_PACKAGE_xserver-kdrive-xfbdev), \ - --enable-kdrive \ - --enable-xfbdev, \ - --disable-xfbdev) \ - $(if $(CONFIG_PACKAGE_xserver-kdrive-xephyr), \ - --enable-kdrive \ - --enable-xephyr, \ - --disable-xephyr) \ - $(if $(CONFIG_X_TSLIB),--enable-tslib,--disable-tslib) \ - $(if $(CONFIG_X_COMPOSITE),--enable-composite,--disable-composite) \ - $(if $(CONFIG_X_XINERAMA),--enable-xinerama,--disable-xinerama) \ - $(if $(CONFIG_X_XCALIBRATE),--enable-xcalibrate,--disable-xcalibrate) \ + --enable-xorg \ + --enable-dri \ + --disable-kdrive \ + --disable-cfb \ + --disable-afb \ + --disable-mfb \ + --disable-aiglx \ + --disable-glx-tls \ + --disable-dga \ + --disable-xdmcp \ + --disable-xdm-auth-1 \ + --disable-config-hal \ + --disable-xf86misc \ + --disable-xf86vidmode \ + --disable-xf86bigfont \ + --disable-xorgcfg \ + --disable-xkb \ + --disable-xnest \ + --disable-xquartz \ + --disable-xwin \ + --disable-x11app \ + --disable-xsdl \ + --disable-xfake \ + --disable-install-setuid \ + --disable-kbd_mode \ + --disable-xvfb \ + --disable-xprint \ + --disable-xtrap \ + --disable-dmx \ + --disable-glx \ + --disable-xinerama \ + --disable-xfree86-utils \ + --disable-cup \ + --disable-xevie \ + --disable-evi \ + --disable-screensaver \ + --enable-builtin-fonts \ ) endef -define Build/Compile - DESTDIR="$(PKG_INSTALL_DIR)" $(MAKE) -C $(PKG_BUILD_DIR) install -endef - define Package/xserver-common/install $(INSTALL_DIR) $(1)/etc/{init.d,config} $(INSTALL_BIN) \ @@ -225,32 +121,6 @@ define Package/xserver-common/install ./files/config/$(X_CONFIG) \ $(1)/etc/config/x11 \ ) - - $(INSTALL_DIR) $(1)/usr/lib/xorg - $(INSTALL_DATA) \ - $(PKG_INSTALL_DIR)/usr/lib/xorg/protocol.txt \ - $(1)/usr/lib/xorg/ -endef - -define Package/xserver-kdrive-xfbdev/install - $(INSTALL_DIR) $(1)/usr/bin - $(INSTALL_BIN) \ - $(PKG_INSTALL_DIR)/usr/bin/Xfbdev \ - $(1)/usr/bin/ -endef - -define Package/xserver-kdrive-xvesa/install - $(INSTALL_DIR) $(1)/usr/bin - $(INSTALL_BIN) \ - $(PKG_INSTALL_DIR)/usr/bin/Xvesa \ - $(1)/usr/bin/ -endef - -define Package/xserver-kdrive-xephyr/install - $(INSTALL_DIR) $(1)/usr/bin - $(INSTALL_BIN) \ - $(PKG_INSTALL_DIR)/usr/bin/Xephyr \ - $(1)/usr/bin/ endef define Package/xserver-xorg/install @@ -259,28 +129,18 @@ define Package/xserver-xorg/install $(PKG_INSTALL_DIR)/usr/bin/Xorg \ $(1)/usr/bin/ - $(INSTALL_DIR) $(1)/usr/lib/X11 - $(INSTALL_DATA) \ - $(PKG_INSTALL_DIR)/usr/lib/X11/* \ - $(1)/usr/lib/X11/ - $(INSTALL_DIR) $(1)/usr/lib/xorg/modules/{extensions,fonts,linux,multimedia} $(INSTALL_DATA) \ $(PKG_INSTALL_DIR)/usr/lib/xorg/modules/*.so \ $(1)/usr/lib/xorg/modules/ - $(for dir,extensions fonts linux multimedia, \ + $(foreach d,extensions fonts linux multimedia, \ $(INSTALL_DATA) \ $(PKG_INSTALL_DIR)/usr/lib/xorg/modules/$(d)/*.so \ - $(1)/usr/lib/xorg/modules/$(d) \ + $(1)/usr/lib/xorg/modules/$(d)/; \ ) endef -define Packages/xorg-server-config/install - $(INSTALL_DIR) $(1)/usr/bin - $(INSTALL_BIN) $(PKG_INSTALL_DIR)/usr/bin/xorgconfig $(1)/usr/bin/ -endef - define Build/InstallDev $(INSTALL_DIR) $(1)/usr/share/aclocal/ $(INSTALL_DATA) \ @@ -301,7 +161,3 @@ endef $(eval $(call BuildPackage,xserver-common)) $(eval $(call BuildPackage,xserver-xorg)) -$(eval $(call BuildPackage,xserver-kdrive-xvesa)) -$(eval $(call BuildPackage,xserver-kdrive-xfbdev)) -$(eval $(call BuildPackage,xserver-kdrive-xephyr)) -$(eval $(call BuildPackage,xserver-xorg-config)) diff --git a/Xorg/xorg/xserver/xorg-server/patches/020-fix-dri-build-without-xinerama.patch b/Xorg/xorg/xserver/xorg-server/patches/020-fix-dri-build-without-xinerama.patch new file mode 100644 index 000000000..810342969 --- /dev/null +++ b/Xorg/xorg/xserver/xorg-server/patches/020-fix-dri-build-without-xinerama.patch @@ -0,0 +1,44 @@ +diff --git a/hw/xfree86/dri/dri.c b/hw/xfree86/dri/dri.c +index b736c6a..3f14705 100644 +--- a/hw/xfree86/dri/dri.c ++++ b/hw/xfree86/dri/dri.c +@@ -73,7 +73,7 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + + #define PCI_BUS_NO_DOMAIN(bus) ((bus) & 0xffu) + +-#if !defined(PANORAMIX) ++#ifdef PANORAMIX + extern Bool noPanoramiXExtension; + #endif + +@@ -307,7 +307,6 @@ DRIScreenInit(ScreenPtr pScreen, DRIInfoPtr pDRIInfo, int *pDRMFD) + drm_context_t * reserved; + int reserved_count; + int i; +- Bool xineramaInCore = FALSE; + DRIEntPrivPtr pDRIEntPriv; + ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; + DRIContextFlags flags = 0; +@@ -320,20 +319,18 @@ DRIScreenInit(ScreenPtr pScreen, DRIInfoPtr pDRIInfo, int *pDRMFD) + return FALSE; + } + ++#ifdef PANORAMIX + /* + * If Xinerama is on, don't allow DRI to initialise. It won't be usable + * anyway. + */ +- if (xf86LoaderCheckSymbol("noPanoramiXExtension")) +- xineramaInCore = TRUE; + +- if (xineramaInCore) { + if (!noPanoramiXExtension) { + DRIDrvMsg(pScreen->myNum, X_WARNING, + "Direct rendering is not supported when Xinerama is enabled\n"); + return FALSE; + } +- } ++#endif + + if (!DRIOpenDRMMaster(pScrn, pDRIInfo->SAREASize, + pDRIInfo->busIdString, diff --git a/net/asterisk-1.4.x/Makefile b/net/asterisk-1.4.x/Makefile index b3c5faf04..eb77ac03d 100644 --- a/net/asterisk-1.4.x/Makefile +++ b/net/asterisk-1.4.x/Makefile @@ -9,13 +9,12 @@ include $(TOPDIR)/rules.mk PKG_NAME:=asterisk -PKG_VERSION:=1.4.22 -PKG_RELEASE:=2 +PKG_VERSION:=1.4.23.1 +PKG_RELEASE:=1 PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz PKG_SOURCE_URL:=http://downloads.digium.com/pub/asterisk/releases/ -#PKG_MD5SUM:=c4cf69eb6eae3105806b08d3efc28ec7 -PKG_MD5SUM:=7626febc4a01e16e012dfccb9e4ab9d2 +PKG_MD5SUM:=4788954a93f5fbf78e55e2aa6e03329f PKG_BUILD_DEPENDS:= libopenh323 pwlib diff --git a/net/asterisk-1.4.x/patches/023-autoconf-chan_h323.patch b/net/asterisk-1.4.x/patches/023-autoconf-chan_h323.patch index 629bb382a..a101c47ba 100644 --- a/net/asterisk-1.4.x/patches/023-autoconf-chan_h323.patch +++ b/net/asterisk-1.4.x/patches/023-autoconf-chan_h323.patch @@ -1,7 +1,7 @@ -diff -Nru asterisk-1.4.22.org/acinclude.m4 asterisk-1.4.22/acinclude.m4 ---- asterisk-1.4.22.org/acinclude.m4 2008-07-22 22:49:41.000000000 +0200 -+++ asterisk-1.4.22/acinclude.m4 2008-11-29 15:06:28.000000000 +0100 -@@ -588,6 +588,7 @@ +diff -Nru asterisk-1.4.23.1.org/autoconf/ast_check_openh323.m4 asterisk-1.4.23.1/autoconf/ast_check_openh323.m4 +--- asterisk-1.4.23.1.org/autoconf/ast_check_openh323.m4 2008-10-20 06:57:33.000000000 +0200 ++++ asterisk-1.4.23.1/autoconf/ast_check_openh323.m4 2009-01-31 15:30:03.000000000 +0100 +@@ -119,6 +119,7 @@ ;; esac AC_MSG_RESULT(${OPENH323_BUILD}) @@ -9,12 +9,12 @@ diff -Nru asterisk-1.4.22.org/acinclude.m4 asterisk-1.4.22/acinclude.m4 AC_SUBST([OPENH323_SUFFIX]) AC_SUBST([OPENH323_BUILD]) -diff -Nru asterisk-1.4.22.org/configure.ac asterisk-1.4.22/configure.ac ---- asterisk-1.4.22.org/configure.ac 2008-09-08 18:26:00.000000000 +0200 -+++ asterisk-1.4.22/configure.ac 2008-11-29 15:06:28.000000000 +0100 -@@ -1259,7 +1259,7 @@ +diff -Nru asterisk-1.4.23.1.org/configure.ac asterisk-1.4.23.1/configure.ac +--- asterisk-1.4.23.1.org/configure.ac 2008-12-15 18:43:59.000000000 +0100 ++++ asterisk-1.4.23.1/configure.ac 2009-01-31 15:29:14.000000000 +0100 +@@ -1278,7 +1278,7 @@ if test "${HAS_PWLIB:-unset}" != "unset"; then - AST_CHECK_OPENH323_PLATFORM() + AST_CHECK_PWLIB_PLATFORM() - PLATFORM_PWLIB="pt_${PWLIB_PLATFORM}_r" + PLATFORM_PWLIB="pt_${PWLIB_PLATFORM}_r_s" diff --git a/net/asterisk-1.4.x/patches/030-acinclude.patch b/net/asterisk-1.4.x/patches/030-acinclude.patch index 7ca79b64e..25818c62e 100644 --- a/net/asterisk-1.4.x/patches/030-acinclude.patch +++ b/net/asterisk-1.4.x/patches/030-acinclude.patch @@ -1,7 +1,7 @@ -diff -Nru asterisk-1.4.22.org/acinclude.m4 asterisk-1.4.22/acinclude.m4 ---- asterisk-1.4.22.org/acinclude.m4 2008-07-22 22:49:41.000000000 +0200 -+++ asterisk-1.4.22/acinclude.m4 2008-11-29 15:08:07.000000000 +0100 -@@ -664,7 +664,7 @@ +diff -Nru asterisk-1.4.23.1.org/autoconf/ast_prog_ld.m4 asterisk-1.4.23.1/autoconf/ast_prog_ld.m4 +--- asterisk-1.4.23.1.org/autoconf/ast_prog_ld.m4 2008-10-20 06:45:56.000000000 +0200 ++++ asterisk-1.4.23.1/autoconf/ast_prog_ld.m4 2009-01-31 15:46:48.000000000 +0100 +@@ -7,7 +7,7 @@ [assume the C compiler uses GNU ld @<:@default=no@:>@])], [test "$withval" = no || with_gnu_ld=yes], [with_gnu_ld=no]) @@ -10,10 +10,10 @@ diff -Nru asterisk-1.4.22.org/acinclude.m4 asterisk-1.4.22/acinclude.m4 AC_REQUIRE([AC_PROG_CC])dnl AC_REQUIRE([AC_CANONICAL_HOST])dnl AC_REQUIRE([AC_CANONICAL_BUILD])dnl -@@ -769,28 +769,6 @@ - AC_SUBST([EGREP]) - ])]) # AST_PROG_EGREP - +diff -Nru asterisk-1.4.23.1.org/autoconf/ast_prog_sed.m4 asterisk-1.4.23.1/autoconf/ast_prog_sed.m4 +--- asterisk-1.4.23.1.org/autoconf/ast_prog_sed.m4 2008-10-20 06:45:56.000000000 +0200 ++++ asterisk-1.4.23.1/autoconf/ast_prog_sed.m4 1970-01-01 01:00:00.000000000 +0100 +@@ -1,21 +0,0 @@ -# AST_PROG_SED -# ----------- -# Check for a fully functional sed program that truncates @@ -35,7 +35,3 @@ diff -Nru asterisk-1.4.22.org/acinclude.m4 asterisk-1.4.22/acinclude.m4 - AC_SUBST([SED])dnl - rm -f conftest.sed -])# AST_PROG_SED -- - dnl @synopsis ACX_PTHREAD([ACTION-IF-FOUND[, ACTION-IF-NOT-FOUND]]) - dnl - dnl @summary figure out how to build C programs using POSIX threads diff --git a/net/asterisk-1.4.x/patches/035-main-asterisk-uclibc-daemon.patch b/net/asterisk-1.4.x/patches/035-main-asterisk-uclibc-daemon.patch index 262bed4a7..82159d495 100644 --- a/net/asterisk-1.4.x/patches/035-main-asterisk-uclibc-daemon.patch +++ b/net/asterisk-1.4.x/patches/035-main-asterisk-uclibc-daemon.patch @@ -1,12 +1,14 @@ -diff -Nru asterisk-1.4.22.org/main/asterisk.c asterisk-1.4.22/main/asterisk.c ---- asterisk-1.4.22.org/main/asterisk.c 2008-07-26 17:31:21.000000000 +0200 -+++ asterisk-1.4.22/main/asterisk.c 2008-12-20 22:49:58.000000000 +0100 -@@ -2935,7 +2935,38 @@ +diff -Nru asterisk-1.4.23.1.org/main/asterisk.c asterisk-1.4.23.1/main/asterisk.c +--- asterisk-1.4.23.1.org/main/asterisk.c 2008-12-23 16:35:38.000000000 +0100 ++++ asterisk-1.4.23.1/main/asterisk.c 2009-01-31 15:41:40.000000000 +0100 +@@ -2986,9 +2986,40 @@ #if HAVE_WORKING_FORK if (ast_opt_always_fork || !ast_opt_no_fork) { #ifndef HAVE_SBIN_LAUNCHD +#ifndef __UCLIBC__ - daemon(1, 0); + if (daemon(1, 0) < 0) { + ast_log(LOG_ERROR, "daemon() failed: %s\n", strerror(errno)); + } +#else +/* + workaround for uClibc-0.9.29 mipsel bug: @@ -16,26 +18,26 @@ diff -Nru asterisk-1.4.22.org/main/asterisk.c asterisk-1.4.22/main/asterisk.c + (same code works if daemon() is not called) + but duplication of uClibc daemon.c code in here does work. +*/ -+ int fd; -+ switch (fork()) { -+ case -1: -+ exit(1); -+ case 0: -+ break; -+ default: -+ _exit(0); -+ } -+ if (setsid() == -1) -+ exit(1); -+ if (fork()) -+ _exit(0); -+ if ((fd = open("/dev/null", O_RDWR, 0)) != -1) { -+ dup2(fd, STDIN_FILENO); -+ dup2(fd, STDOUT_FILENO); -+ dup2(fd, STDERR_FILENO); -+ if (fd > 2) -+ close(fd); -+ } ++ int fd; ++ switch (fork()) { ++ case -1: ++ exit(1); ++ case 0: ++ break; ++ default: ++ _exit(0); ++ } ++ if (setsid() == -1) ++ exit(1); ++ if (fork()) ++ _exit(0); ++ if ((fd = open("/dev/null", O_RDWR, 0)) != -1) { ++ dup2(fd, STDIN_FILENO); ++ dup2(fd, STDOUT_FILENO); ++ dup2(fd, STDERR_FILENO); ++ if (fd > 2) ++ close(fd); ++ } +#endif ast_mainpid = getpid(); /* Blindly re-write pid file since we are forking */ diff --git a/net/asterisk-1.6.x/Makefile b/net/asterisk-1.6.x/Makefile index 7c976e5a1..9adf71661 100644 --- a/net/asterisk-1.6.x/Makefile +++ b/net/asterisk-1.6.x/Makefile @@ -57,7 +57,7 @@ endef define Package/asterisk16 $(call Package/asterisk16/Default) TITLE:=Complete open source PBX - DEPENDS:= +libncurses +libpopt +libpthread +zlib @!TARGET_avr32 + DEPENDS:= +libncurses +libpopt +libpthread +zlib @!TARGET_avr32 @!PACKAGE_asterisk14 endef define Package/asterisk16/description @@ -162,11 +162,11 @@ define Build/Compile $(SED) 's|/var/lib/asterisk|/usr/lib/asterisk|g' $(PKG_INSTALL_DIR)/etc/asterisk/musiconhold.conf endef -define Build/InstallDev - mkdir -p $(1)/usr/include/asterisk/ - $(CP) $(PKG_INSTALL_DIR)/usr/include/asterisk/*.h $(1)/usr/include/asterisk/ - $(CP) $(PKG_INSTALL_DIR)/usr/include/asterisk.h $(1)/usr/include/ -endef +#define Build/InstallDev +# mkdir -p $(1)/usr/include/asterisk/ +# $(CP) $(PKG_INSTALL_DIR)/usr/include/asterisk/*.h $(1)/usr/include/asterisk/ +# $(CP) $(PKG_INSTALL_DIR)/usr/include/asterisk.h $(1)/usr/include/ +#endef define Package/asterisk16/conffiles /etc/asterisk/asterisk.conf diff --git a/net/asterisk-addons-1.4.x/Makefile b/net/asterisk-addons-1.4.x/Makefile index d630c9dd7..72a84cc79 100644 --- a/net/asterisk-addons-1.4.x/Makefile +++ b/net/asterisk-addons-1.4.x/Makefile @@ -10,7 +10,7 @@ include $(TOPDIR)/rules.mk PKG_NAME:=asterisk-addons PKG_VERSION:=1.4.7 -PKG_RELEASE:=1 +PKG_RELEASE:=2 PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz PKG_SOURCE_URL:=http://downloads.digium.com/pub/asterisk/releases/ diff --git a/net/asterisk-addons-1.4.x/patches/011-chan_mobile.patch b/net/asterisk-addons-1.4.x/patches/011-chan_mobile.patch index 2c22aa8e6..297739766 100644 --- a/net/asterisk-addons-1.4.x/patches/011-chan_mobile.patch +++ b/net/asterisk-addons-1.4.x/patches/011-chan_mobile.patch @@ -1,14 +1,14 @@ -diff -Nru asterisk-addons-1.4.6.org/build_tools/menuselect-deps.in asterisk-addons-1.4.6/build_tools/menuselect-deps.in ---- asterisk-addons-1.4.6.org/build_tools/menuselect-deps.in 2007-05-14 18:22:44.000000000 +0200 -+++ asterisk-addons-1.4.6/build_tools/menuselect-deps.in 2008-03-06 08:38:14.000000000 +0100 +diff -Nru asterisk-addons-1.4.7.org/build_tools/menuselect-deps.in asterisk-addons-1.4.7/build_tools/menuselect-deps.in +--- asterisk-addons-1.4.7.org/build_tools/menuselect-deps.in 2007-05-14 18:22:44.000000000 +0200 ++++ asterisk-addons-1.4.7/build_tools/menuselect-deps.in 2009-02-01 08:45:32.000000000 +0100 @@ -1,2 +1,3 @@ +BLUETOOTH=@PBX_BLUETOOTH@ MYSQLCLIENT=@PBX_MYSQLCLIENT@ ASTERISK=@PBX_ASTERISK@ -diff -Nru asterisk-addons-1.4.6.org/channels/chan_mobile.c asterisk-addons-1.4.6/channels/chan_mobile.c ---- asterisk-addons-1.4.6.org/channels/chan_mobile.c 1970-01-01 01:00:00.000000000 +0100 -+++ asterisk-addons-1.4.6/channels/chan_mobile.c 2008-03-06 08:38:57.000000000 +0100 -@@ -0,0 +1,1867 @@ +diff -Nru asterisk-addons-1.4.7.org/channels/chan_mobile.c asterisk-addons-1.4.7/channels/chan_mobile.c +--- asterisk-addons-1.4.7.org/channels/chan_mobile.c 1970-01-01 01:00:00.000000000 +0100 ++++ asterisk-addons-1.4.7/channels/chan_mobile.c 2009-02-01 08:44:17.000000000 +0100 +@@ -0,0 +1,2150 @@ +/* + * Asterisk -- An open source telephony toolkit. + * @@ -30,7 +30,7 @@ diff -Nru asterisk-addons-1.4.6.org/channels/chan_mobile.c asterisk-addons-1.4.6 +/*! \file + * + * \brief Bluetooth Mobile Device channel driver -+ * ++ * + * \author Dave Bowerman + * + * \ingroup channel_drivers @@ -42,7 +42,7 @@ diff -Nru asterisk-addons-1.4.6.org/channels/chan_mobile.c asterisk-addons-1.4.6 + +#include + -+ASTERISK_FILE_VERSION(__FILE__, "$Revision: 416 $") ++ASTERISK_FILE_VERSION(__FILE__, "$Revision$") + +#include +#include @@ -63,6 +63,7 @@ diff -Nru asterisk-addons-1.4.6.org/channels/chan_mobile.c asterisk-addons-1.4.6 +#include +#include +#include ++#include + +#include +#include @@ -77,23 +78,19 @@ diff -Nru asterisk-addons-1.4.6.org/channels/chan_mobile.c asterisk-addons-1.4.6 +#include +#include +#include -+ -+#ifndef ast_debug -+#define ast_debug(level, ...) do { \ -+ if (option_debug >= (level)) { \ -+ ast_log(LOG_DEBUG, __VA_ARGS__); \ -+ } \ -+} while (0) -+#endif -+ -+#define AST_MODULE "chan_mobile" ++#include ++#include + +#define MBL_CONFIG "mobile.conf" + -+static int prefformat = AST_FORMAT_SLINEAR; ++#define DEVICE_FRAME_SIZE 48 ++#define DEVICE_FRAME_FORMAT AST_FORMAT_SLINEAR ++#define CHANNEL_FRAME_SIZE 320 ++ ++static int prefformat = DEVICE_FRAME_FORMAT; + -+static int discovery_interval = 60; /* The device discovery interval, default 60 seconds. */ -+static int sco_socket; /* This is global so it can be closed on module unload outside of the listener thread */ ++static int discovery_interval = 60; /* The device discovery interval, default 60 seconds. */ ++static pthread_t discovery_thread = AST_PTHREADT_NULL; /* The discovery thread */ +static sdp_session_t *sdp_session; + +enum mbl_type { @@ -109,6 +106,7 @@ diff -Nru asterisk-addons-1.4.6.org/channels/chan_mobile.c asterisk-addons-1.4.6 + MBL_STATE_INIT4, + MBL_STATE_INIT5, + MBL_STATE_INIT6, ++ MBL_STATE_INIT7, + MBL_STATE_PREIDLE, + MBL_STATE_IDLE, + MBL_STATE_DIAL, @@ -125,50 +123,67 @@ diff -Nru asterisk-addons-1.4.6.org/channels/chan_mobile.c asterisk-addons-1.4.6 + MBL_STATE_OUTSMS2 +}; + ++struct adapter_pvt { ++ int dev_id; /* device id */ ++ int hci_socket; /* device descriptor */ ++ char id[31]; /* the 'name' from mobile.conf */ ++ bdaddr_t addr; /* adddress of adapter */ ++ unsigned int inuse:1; /* are we in use ? */ ++ unsigned int alignment_detection:1; /* do alignment detection on this adpater? */ ++ int sco_socket; ++ AST_LIST_ENTRY(adapter_pvt) entry; ++}; ++ ++static AST_RWLIST_HEAD_STATIC(adapters, adapter_pvt); ++ +struct mbl_pvt { -+ struct ast_channel *owner; /* Channel we belong to, possibly NULL */ -+ struct ast_frame fr; /* "null" frame */ -+ enum mbl_type type; /* Phone or Headset */ -+ char id[31]; /* The id from mobile.conf */ -+ char bdaddr[18]; /* the bdaddr of the device */ -+ char context[AST_MAX_CONTEXT]; /* the context for incoming calls */ -+ char connected; /* is it connected? */ -+ int rfcomm_port; /* rfcomm port number */ -+ int rfcomm_socket; /* rfcomm socket descriptor */ ++ struct ast_channel *owner; /* Channel we belong to, possibly NULL */ ++ struct ast_frame fr; /* "null" frame */ ++ enum mbl_type type; /* Phone or Headset */ ++ char id[31]; /* The id from mobile.conf */ ++ int group; /* group number for group dialling */ ++ bdaddr_t addr; /* address of device */ ++ struct adapter_pvt *adapter; /* the adapter we use */ ++ char context[AST_MAX_CONTEXT]; /* the context for incoming calls */ ++ char connected; /* is it connected? */ ++ int rfcomm_port; /* rfcomm port number */ ++ int rfcomm_socket; /* rfcomm socket descriptor */ + char rfcomm_buf[256]; -+ int sco_socket; /* sco socket descriptor */ -+ enum mbl_state state; /* monitor thread current state */ -+ pthread_t monitor_thread; /* monitor thread handle */ -+ char sco_in_buf[48 + AST_FRIENDLY_OFFSET]; -+ char sco_out_buf[352]; -+ char *sco_out_ptr; -+ int sco_out_len; -+ char dial_number[AST_MAX_EXTENSION]; /* number for the monitor thread to dial */ ++ char io_buf[CHANNEL_FRAME_SIZE + AST_FRIENDLY_OFFSET]; ++ char io_save_buf[DEVICE_FRAME_SIZE]; ++ int io_save_len; ++ int io_pipe[2]; ++ int sco_socket; /* sco socket descriptor */ ++ pthread_t sco_listener_thread; /* inbound sco listener for this device */ ++ enum mbl_state state; /* monitor thread current state */ ++ pthread_t monitor_thread; /* monitor thread handle */ ++ char dial_number[AST_MAX_EXTENSION]; /* number for the monitor thread to dial */ + int dial_timeout; -+ char ciev_call_0[4]; /* dynamically build reponse strings */ -+ char ciev_call_1[4]; -+ char ciev_callsetup_0[4]; -+ char ciev_callsetup_1[4]; -+ char ciev_callsetup_2[4]; -+ char ciev_callsetup_3[4]; -+ char no_callsetup; -+ char has_sms; -+ char sms_txt[161]; ++ char ciev_call_0[5]; /* dynamically built reponse strings */ ++ char ciev_call_1[5]; ++ char ciev_callsetup_0[5]; ++ char ciev_callsetup_1[5]; ++ char ciev_callsetup_2[5]; ++ char ciev_callsetup_3[5]; ++ unsigned int no_callsetup:1; ++ unsigned int has_sms:1; ++ unsigned int sent_answer:1; ++ unsigned int do_alignment_detection:1; ++ unsigned int alignment_detection_triggered:1; ++ unsigned int do_hangup:1; ++ unsigned int blackberry:1; ++ short alignment_samples[4]; ++ int alignment_count; ++ char sms_txt[160]; + struct ast_dsp *dsp; + struct ast_frame *dsp_fr; + int dtmf_skip; + int skip_frames; -+ char sent_answer; + char hangup_count; + AST_LIST_ENTRY(mbl_pvt) entry; +}; + -+static AST_LIST_HEAD_STATIC(devices, mbl_pvt); -+ -+/* The discovery thread */ -+static pthread_t discovery_thread = AST_PTHREADT_NULL; -+/* The sco listener thread */ -+static pthread_t sco_listener_thread = AST_PTHREADT_NULL; ++static AST_RWLIST_HEAD_STATIC(devices, mbl_pvt); + +/* CLI stuff */ +static const char show_usage[] = @@ -183,14 +198,14 @@ diff -Nru asterisk-addons-1.4.6.org/channels/chan_mobile.c asterisk-addons-1.4.6 +"Usage: mobile rfcomm command\n" +" Send command to the rfcomm port.\n"; + -+static int do_show_devices(int, int, char **); -+static int do_search_devices(int, int, char **); -+static int do_send_rfcomm(int, int, char **); ++static int handle_cli_mobile_show_devices(int fd, int argc, char **argv); ++static int handle_cli_mobile_search(int fd, int argc, char **argv); ++static int handle_cli_mobile_rfcomm(int fd, int argc, char **argv); + +static struct ast_cli_entry mbl_cli[] = { -+ {{"mobile", "show", "devices", NULL}, do_show_devices, "Show Bluetooth Cell / Mobile devices", show_usage}, -+ {{"mobile", "search", NULL}, do_search_devices, "Search for Bluetooth Cell / Mobile devices", search_usage}, -+ {{"mobile", "rfcomm", NULL}, do_send_rfcomm, "Send commands to the rfcomm port for debugging", rfcomm_usage} ++ {{"mobile", "show", "devices", NULL}, handle_cli_mobile_show_devices, "Show Bluetooth Cell / Mobile devices", show_usage}, ++ {{"mobile", "search", NULL}, handle_cli_mobile_search, "Search for Bluetooth Cell / Mobile devices", search_usage}, ++ {{"mobile", "rfcomm", NULL}, handle_cli_mobile_rfcomm, "Send commands to the rfcomm port for debugging", rfcomm_usage}, +}; + +/* App stuff */ @@ -210,6 +225,7 @@ diff -Nru asterisk-addons-1.4.6.org/channels/chan_mobile.c asterisk-addons-1.4.6 +" Dest - destination\n" +" Message - text of the message\n"; + ++static struct ast_channel *mbl_new(int state, struct mbl_pvt *pvt, char *cid_num); +static struct ast_channel *mbl_request(const char *type, int format, void *data, int *cause); +static int mbl_call(struct ast_channel *ast, char *dest, int timeout); +static int mbl_hangup(struct ast_channel *ast); @@ -220,11 +236,18 @@ diff -Nru asterisk-addons-1.4.6.org/channels/chan_mobile.c asterisk-addons-1.4.6 +static int mbl_write(struct ast_channel *ast, struct ast_frame *frame); +static int mbl_fixup(struct ast_channel *oldchan, struct ast_channel *newchan); +static int mbl_devicestate(void *data); -+static struct ast_channel *mbl_new(int state, struct mbl_pvt *pvt, char *cid_num); + ++static void do_alignment_detection(struct mbl_pvt *pvt, char *buf, int buflen); ++ ++static int rfcomm_connect(bdaddr_t src, bdaddr_t dst, int remote_channel); +static int rfcomm_write(struct mbl_pvt *pvt, char *buf); +static int rfcomm_read(struct mbl_pvt *pvt, char *buf, char flush, int timeout); -+static int sco_connect(char *bdaddr); ++ ++static int sco_connect(bdaddr_t src, bdaddr_t dst); ++static int sco_write(int s, char *buf, int len); ++static int sco_read(int s, char *buf, int len); ++ ++static void *do_sco_listen(void *data); +static int sdp_search(char *addr, int profile); + +static const struct ast_channel_tech mbl_tech = { @@ -243,117 +266,157 @@ diff -Nru asterisk-addons-1.4.6.org/channels/chan_mobile.c asterisk-addons-1.4.6 + .devicestate = mbl_devicestate +}; + -+static int do_show_devices(int fd, int argc, char **argv) -+{ ++/* CLI Commands implementation */ + ++static int handle_cli_mobile_show_devices(int fd, int argc, char **argv) ++{ + struct mbl_pvt *pvt; ++ char bdaddr[18]; ++ char group[6]; ++ ++#define FORMAT1 "%-15.15s %-17.17s %-5.5s %-15.15s %-9.9s %-5.5s %-3.3s\n" ++ ++ if (argc != 3) ++ return RESULT_SHOWUSAGE; ++ ++ ast_cli(fd, FORMAT1, "ID", "Address", "Group", "Adapter", "Connected", "State", "SMS"); ++ AST_RWLIST_RDLOCK(&devices); ++ AST_RWLIST_TRAVERSE(&devices, pvt, entry) { ++ ba2str(&pvt->addr, bdaddr); ++ snprintf(group, 5, "%d", pvt->group); ++ ast_cli(fd, FORMAT1, pvt->id, bdaddr, group, pvt->adapter->id, pvt->connected ? "Yes" : "No", ++ (pvt->state == MBL_STATE_IDLE) ? "Free" : (pvt->state < MBL_STATE_IDLE) ? "Init" : "Busy", ++ (pvt->has_sms) ? "Yes" : "No"); ++ } ++ AST_RWLIST_UNLOCK(&devices); + -+ #define FORMAT "%-15.15s %-17.17s %-9.9s %-5.5s %-3.3s\n" -+ -+ ast_cli(fd, FORMAT, "ID", "Address", "Connected", "State", "SMS"); -+ AST_LIST_TRAVERSE(&devices, pvt, entry) { -+ ast_cli(fd, FORMAT, pvt->id, pvt->bdaddr, pvt->connected?"Yes":"No", (pvt->state == MBL_STATE_IDLE)?"Free":(pvt->state < MBL_STATE_IDLE)?"Init":"Busy", (pvt->has_sms)?"Yes":"No"); -+ } ++#undef FORMAT1 + + return RESULT_SUCCESS; -+ +} + -+static int do_search_devices(int fd, int argc, char **argv) ++static int handle_cli_mobile_search(int fd, int argc, char **argv) +{ -+ -+ int hci_socket; ++ struct adapter_pvt *adapter; + inquiry_info *ii = NULL; + int max_rsp, num_rsp; -+ int dev_id, len, flags; ++ int len, flags; + int i, phport, hsport; + char addr[19] = {0}; + char name[31] = {0}; + -+ #define FORMAT2 "%-17.17s %-30.30s %-6.6s %-7.7s %-4.4s\n" -+ #define FORMAT3 "%-17.17s %-30.30s %-6.6s %-7.7s %d\n" ++#define FORMAT1 "%-17.17s %-30.30s %-6.6s %-7.7s %-4.4s\n" ++#define FORMAT2 "%-17.17s %-30.30s %-6.6s %-7.7s %d\n" ++ ++ if (argc != 2) ++ return RESULT_SHOWUSAGE; ++ ++ /* find a free adapter */ ++ AST_RWLIST_RDLOCK(&adapters); ++ AST_RWLIST_TRAVERSE(&adapters, adapter, entry) { ++ if (!adapter->inuse) ++ break; ++ } ++ AST_RWLIST_UNLOCK(&adapters); ++ ++ if (!adapter) { ++ ast_cli(fd, "All Bluetooth adapters are in use at this time.\n"); ++ return RESULT_SUCCESS; ++ } + -+ dev_id = hci_get_route(NULL); -+ hci_socket = hci_open_dev(dev_id); + len = 8; + max_rsp = 255; + flags = IREQ_CACHE_FLUSH; + -+ ii = (inquiry_info*)malloc(max_rsp * sizeof(inquiry_info)); -+ num_rsp = hci_inquiry(dev_id, len, max_rsp, NULL, &ii, flags); ++ ii = alloca(max_rsp * sizeof(inquiry_info)); ++ num_rsp = hci_inquiry(adapter->dev_id, len, max_rsp, NULL, &ii, flags); + if (num_rsp > 0) { -+ ast_cli(fd, FORMAT2, "Address", "Name", "Usable", "Type", "Port"); ++ ast_cli(fd, FORMAT1, "Address", "Name", "Usable", "Type", "Port"); + for (i = 0; i < num_rsp; i++) { -+ ba2str(&(ii+i)->bdaddr, addr); ++ ba2str(&(ii + i)->bdaddr, addr); + name[0] = 0x00; -+ if (hci_read_remote_name(hci_socket, &(ii+i)->bdaddr, sizeof(name)-1, name, 0) < 0) ++ if (hci_read_remote_name(adapter->hci_socket, &(ii + i)->bdaddr, sizeof(name) - 1, name, 0) < 0) + strcpy(name, "[unknown]"); + phport = sdp_search(addr, HANDSFREE_AGW_PROFILE_ID); + if (!phport) + hsport = sdp_search(addr, HEADSET_PROFILE_ID); + else + hsport = 0; -+ ast_cli(fd, FORMAT3, addr, name, (phport > 0 || hsport > 0)?"Yes":"No", (phport > 0)?"Phone":"Headset", (phport > 0)?phport:hsport); ++ ast_cli(fd, FORMAT2, addr, name, (phport > 0 || hsport > 0) ? "Yes" : "No", ++ (phport > 0) ? "Phone" : "Headset", (phport > 0) ? phport : hsport); + } + } else + ast_cli(fd, "No Bluetooth Cell / Mobile devices found.\n"); + -+ free(ii); -+ -+ hci_close_dev(hci_socket); ++#undef FORMAT1 ++#undef FORMAT2 + + return RESULT_SUCCESS; -+ +} + -+static int do_send_rfcomm(int fd, int argc, char **argv) ++static int handle_cli_mobile_rfcomm(int fd, int argc, char **argv) +{ -+ -+ struct mbl_pvt *pvt; + char buf[128]; ++ struct mbl_pvt *pvt = NULL; + -+ AST_LIST_TRAVERSE(&devices, pvt, entry) { ++ if (argc != 4) ++ return RESULT_SHOWUSAGE; ++ ++ AST_RWLIST_RDLOCK(&devices); ++ AST_RWLIST_TRAVERSE(&devices, pvt, entry) { + if (!strcmp(pvt->id, argv[2])) + break; + } ++ AST_RWLIST_UNLOCK(&devices); + + if (!pvt || !pvt->connected) { -+ sprintf(buf, "Device %s not found.\n", argv[2]); -+ ast_cli(fd, buf); ++ ast_cli(fd, "Device %s not found.\n", argv[2]); + return RESULT_SUCCESS; + } + -+ sprintf(buf, "%s\r", argv[3]); ++ snprintf(buf, sizeof(buf), "%s\r", argv[3]); + rfcomm_write(pvt, buf); + + return RESULT_SUCCESS; -+ +} + ++/* ++ ++ Dialplan applications implementation ++ ++*/ ++ +static int mbl_status_exec(struct ast_channel *ast, void *data) +{ + + struct mbl_pvt *pvt; -+ char *args = NULL, *device = NULL, *variable = NULL; ++ char *parse; + int stat; + char status[2]; + -+ if (!data) ++ AST_DECLARE_APP_ARGS(args, ++ AST_APP_ARG(device); ++ AST_APP_ARG(variable); ++ ); ++ ++ if (ast_strlen_zero(data)) + return -1; + -+ args = ast_strdupa((char *)data); -+ device = strsep(&args, "|"); -+ if (device && (device[0] != 0x00)) { -+ variable = args; -+ } else ++ parse = ast_strdupa(data); ++ ++ AST_STANDARD_APP_ARGS(args, parse); ++ ++ if (ast_strlen_zero(args.device) || ast_strlen_zero(args.variable)) + return -1; + + stat = 1; + -+ AST_LIST_TRAVERSE(&devices, pvt, entry) { -+ if (!strcmp(pvt->id, device)) ++ AST_RWLIST_RDLOCK(&devices); ++ AST_RWLIST_TRAVERSE(&devices, pvt, entry) { ++ if (!strcmp(pvt->id, args.device)) + break; + } ++ AST_RWLIST_UNLOCK(&devices); + + if (pvt) { + if (pvt->connected) @@ -362,8 +425,8 @@ diff -Nru asterisk-addons-1.4.6.org/channels/chan_mobile.c asterisk-addons-1.4.6 + stat = 3; + } + -+ sprintf(status, "%d", stat); -+ pbx_builtin_setvar_helper(ast, variable, status); ++ snprintf(status, sizeof(status), "%d", stat); ++ pbx_builtin_setvar_helper(ast, args.variable, status); + + return 0; + @@ -373,66 +436,121 @@ diff -Nru asterisk-addons-1.4.6.org/channels/chan_mobile.c asterisk-addons-1.4.6 +{ + + struct mbl_pvt *pvt; -+ char *args = NULL, *device = NULL, *dest = NULL, *message = NULL; ++ char *parse; + -+ if (!data) ++ AST_DECLARE_APP_ARGS(args, ++ AST_APP_ARG(device); ++ AST_APP_ARG(dest); ++ AST_APP_ARG(message); ++ ); ++ ++ if (ast_strlen_zero(data)) + return -1; + -+ args = ast_strdupa((char *)data); -+ device = strsep(&args, "|"); -+ if (device && (device[0] != 0x00)) { -+ dest = strsep(&args, "|"); -+ if (dest && (dest[0] != 0x00)) { -+ message = args; -+ if (!message || (message[0] == 0x00)) { -+ ast_log(LOG_ERROR,"NULL Message to be sent-- SMS will not be sent.\n"); -+ return -1; -+ } -+ } else { -+ ast_log(LOG_ERROR,"NULL destination for message -- SMS will not be sent.\n"); -+ return -1; -+ } -+ -+ } else { ++ parse = ast_strdupa(data); ++ ++ AST_STANDARD_APP_ARGS(args, parse); ++ ++ if (ast_strlen_zero(args.device)) { + ast_log(LOG_ERROR,"NULL device for message -- SMS will not be sent.\n"); + return -1; + } -+ + -+ AST_LIST_TRAVERSE(&devices, pvt, entry) { -+ if (!strcmp(pvt->id, device)) ++ if (ast_strlen_zero(args.dest)) { ++ ast_log(LOG_ERROR,"NULL destination for message -- SMS will not be sent.\n"); ++ return -1; ++ } ++ ++ if (ast_strlen_zero(args.message)) { ++ ast_log(LOG_ERROR,"NULL Message to be sent -- SMS will not be sent.\n"); ++ return -1; ++ } ++ ++ AST_RWLIST_RDLOCK(&devices); ++ AST_RWLIST_TRAVERSE(&devices, pvt, entry) { ++ if (!strcmp(pvt->id, args.device)) + break; + } ++ AST_RWLIST_UNLOCK(&devices); + + if (!pvt) { -+ ast_log(LOG_ERROR,"Bluetooth device %s wasn't found in the list -- SMS will not be sent.\n",device); ++ ast_log(LOG_ERROR,"Bluetooth device %s wasn't found in the list -- SMS will not be sent.\n", args.device); + return -1; + } -+ ++ + if (!pvt->connected) { -+ ast_log(LOG_ERROR,"bluetooth device %s wasn't connected -- SMS will not be sent.\n",device); ++ ast_log(LOG_ERROR,"Bluetooth device %s wasn't connected -- SMS will not be sent.\n", args.device); + return -1; + } -+ ++ + if (!pvt->has_sms) { -+ ast_log(LOG_ERROR,"bluetooth device %s doesn't handle SMS -- SMS will not be sent.\n",device); ++ ast_log(LOG_ERROR,"Bluetooth device %s doesn't handle SMS -- SMS will not be sent.\n", args.device); + return -1; + } -+ ++ + if (pvt->state != MBL_STATE_IDLE) { -+ ast_log(LOG_ERROR,"bluetooth device %s isn't IDLE -- SMS will not be sent.\n",device); ++ ast_log(LOG_ERROR,"Bluetooth device %s isn't IDLE -- SMS will not be sent.\n", args.device); + return -1; + } -+ -+ strcpy(pvt->dial_number, dest); -+ memset(pvt->sms_txt, 0x0, sizeof(pvt->sms_txt)); -+ strncpy(pvt->sms_txt, message, 160); ++ ++ ast_copy_string(pvt->dial_number, args.dest, sizeof(pvt->dial_number)); ++ ast_copy_string(pvt->sms_txt, args.message, sizeof(pvt->sms_txt)); + pvt->state = MBL_STATE_OUTSMS; + + return 0; + +} + ++/* ++ ++ Channel Driver callbacks ++ ++*/ ++ ++static struct ast_channel *mbl_new(int state, struct mbl_pvt *pvt, char *cid_num) ++{ ++ ++ struct ast_channel *chn; ++ ++ if (pipe(pvt->io_pipe) == -1) { ++ ast_log(LOG_ERROR, "Failed to create io_pipe.\n"); ++ return NULL; ++ } ++ ++ if (pvt->sco_socket != -1) ++ close(pvt->sco_socket); ++ pvt->sco_socket = -1; ++ pvt->io_save_len = 0; ++ pvt->sent_answer = 0; ++ pvt->skip_frames = 0; ++ pvt->alignment_count = 0; ++ pvt->alignment_detection_triggered = 0; ++ if (pvt->adapter->alignment_detection) ++ pvt->do_alignment_detection = 1; ++ else ++ pvt->do_alignment_detection = 0; ++ pvt->do_hangup = 1; ++ chn = ast_channel_alloc(1, state, cid_num, pvt->id, 0, 0, pvt->context, 0, "Mobile/%s-%04lx", pvt->id, ast_random() & 0xffff); ++ if (chn) { ++ chn->tech = &mbl_tech; ++ chn->nativeformats = prefformat; ++ chn->rawreadformat = prefformat; ++ chn->rawwriteformat = prefformat; ++ chn->writeformat = prefformat; ++ chn->readformat = prefformat; ++ chn->tech_pvt = pvt; ++ chn->fds[0] = pvt->io_pipe[0]; ++ if (state == AST_STATE_RING) ++ chn->rings = 1; ++ ast_string_field_set(chn, language, "en"); ++ pvt->owner = chn; ++ return chn; ++ } ++ ++ return NULL; ++ ++} ++ +static struct ast_channel *mbl_request(const char *type, int format, void *data, int *cause) +{ + @@ -440,7 +558,7 @@ diff -Nru asterisk-addons-1.4.6.org/channels/chan_mobile.c asterisk-addons-1.4.6 + struct mbl_pvt *pvt; + char *dest_dev = NULL; + char *dest_num = NULL; -+ int oldformat; ++ int oldformat, group = -1; + + if (!data) { + ast_log(LOG_WARNING, "Channel requested with no data\n"); @@ -462,12 +580,20 @@ diff -Nru asterisk-addons-1.4.6.org/channels/chan_mobile.c asterisk-addons-1.4.6 + if (dest_num) + *dest_num++ = 0x00; + -+ /* Find requested device and make sure its connected. */ -+ AST_LIST_TRAVERSE(&devices, pvt, entry) { -+ if (!strcmp(pvt->id, dest_dev)) { ++ if (((dest_dev[0] == 'g') || (dest_dev[0] == 'G')) && ((dest_dev[1] >= '0') && (dest_dev[1] <= '9'))) { ++ group = atoi(&dest_dev[1]); ++ } ++ ++ /* Find requested device and make sure it's connected. */ ++ AST_RWLIST_RDLOCK(&devices); ++ AST_RWLIST_TRAVERSE(&devices, pvt, entry) { ++ if (group > -1 && pvt->group == group && pvt->connected && !pvt->owner) { ++ break; ++ } else if (!strcmp(pvt->id, dest_dev)) { + break; + } + } ++ AST_RWLIST_UNLOCK(&devices); + if (!pvt || !pvt->connected || pvt->owner) { + ast_log(LOG_WARNING, "Request to call on device %s which is not connected / already in use.\n", dest_dev); + *cause = AST_CAUSE_REQUESTED_CHAN_UNAVAIL; @@ -475,17 +601,14 @@ diff -Nru asterisk-addons-1.4.6.org/channels/chan_mobile.c asterisk-addons-1.4.6 + } + + if ((pvt->type == MBL_TYPE_PHONE) && !dest_num) { -+ ast_log(LOG_WARNING, "Cant determine destination number.\n"); ++ ast_log(LOG_WARNING, "Can't determine destination number.\n"); + *cause = AST_CAUSE_INCOMPATIBLE_DESTINATION; + return NULL; + } + -+ pvt->sco_out_ptr = pvt->sco_out_buf; -+ pvt->sco_out_len = 0; -+ + chn = mbl_new(AST_STATE_DOWN, pvt, NULL); + if (!chn) { -+ ast_log(LOG_WARNING, "Unable to allocate channel structure\n"); ++ ast_log(LOG_WARNING, "Unable to allocate channel structure.\n"); + *cause = AST_CAUSE_REQUESTED_CHAN_UNAVAIL; + return NULL; + } @@ -519,7 +642,7 @@ diff -Nru asterisk-addons-1.4.6.org/channels/chan_mobile.c asterisk-addons-1.4.6 + return -1; + } + -+ ast_debug(1, "Calling %s on %s\n", dest, ast->name); ++ ast_log(LOG_DEBUG, "Calling %s on %s\n", dest, ast->name); + + if (pvt->type == MBL_TYPE_PHONE) { + ast_copy_string(pvt->dial_number, dest_num, sizeof(pvt->dial_number)); @@ -529,7 +652,6 @@ diff -Nru asterisk-addons-1.4.6.org/channels/chan_mobile.c asterisk-addons-1.4.6 + pvt->state = MBL_STATE_RING; + } + -+ + return 0; + +} @@ -545,11 +667,12 @@ diff -Nru asterisk-addons-1.4.6.org/channels/chan_mobile.c asterisk-addons-1.4.6 + } + pvt = ast->tech_pvt; + -+ ast_debug(1, "Hanging up device %s.\n", pvt->id); ++ ast_log(LOG_DEBUG, "Hanging up device %s.\n", pvt->id); + -+ ast_channel_lock(ast); + ast->fds[0] = -1; -+ ast_channel_unlock(ast); ++ ++ close(pvt->io_pipe[0]); ++ close(pvt->io_pipe[1]); + + if (pvt->type == MBL_TYPE_HEADSET && pvt->sco_socket != -1) { + close(pvt->sco_socket); @@ -557,7 +680,9 @@ diff -Nru asterisk-addons-1.4.6.org/channels/chan_mobile.c asterisk-addons-1.4.6 + } + + if ((pvt->state == MBL_STATE_INCOMING || pvt->state == MBL_STATE_OUTGOING || pvt->state == MBL_STATE_DIAL1 || pvt->state == MBL_STATE_RING3) && pvt->type == MBL_TYPE_PHONE) { -+ rfcomm_write(pvt, "AT+CHUP\r"); ++ if (pvt->do_hangup) { ++ rfcomm_write(pvt, "AT+CHUP\r"); ++ } + pvt->state = MBL_STATE_HANGUP; + pvt->hangup_count = 0; + } else @@ -600,13 +725,13 @@ diff -Nru asterisk-addons-1.4.6.org/channels/chan_mobile.c asterisk-addons-1.4.6 + + struct mbl_pvt *pvt; + char buf[11]; -+ ++ + pvt = ast->tech_pvt; + + if (pvt->type == MBL_TYPE_HEADSET) + return 0; + -+ ast_debug(1, "Dialed %c\n", digit); ++ ast_log(LOG_DEBUG, "Dialed %c\n", digit); + + switch(digit) { + case '0': @@ -621,7 +746,7 @@ diff -Nru asterisk-addons-1.4.6.org/channels/chan_mobile.c asterisk-addons-1.4.6 + case '9': + case '*': + case '#': -+ sprintf(buf, "AT+VTS=%c\r", digit); ++ snprintf(buf, sizeof(buf), "AT+VTS=%c\r", digit); + rfcomm_write(pvt, buf); + break; + default: @@ -633,113 +758,95 @@ diff -Nru asterisk-addons-1.4.6.org/channels/chan_mobile.c asterisk-addons-1.4.6 + +} + -+/* -+ -+ The SCO protocol basically delivers audio in 48 byte 'frames' in slin format. -+ Here we just package these into an ast_frame and return them. -+ The SCO connection from the device to Asterisk happens asynchronously, so it is feasible -+ that Asterisk will call mbl_read() before the device has connected. In that case we just return -+ a null frame. -+ -+*/ -+ +static struct ast_frame *mbl_read(struct ast_channel *ast) +{ + + struct mbl_pvt *pvt = ast->tech_pvt; -+ int r; + struct ast_frame *f; ++ int r; + -+ if (!pvt->owner) { -+ return &ast_null_frame; -+ } ++ //ast_log(LOG_DEBUG, "*** mbl_read()\n"); + -+ if (pvt->state == MBL_STATE_HANGUP) { -+ return &ast_null_frame; -+ } -+ -+ if (pvt->sco_socket == -1) { ++ if (!pvt->owner) { + return &ast_null_frame; + } -+ ++ memset(&pvt->fr, 0x00, sizeof(struct ast_frame)); + pvt->fr.frametype = AST_FRAME_VOICE; -+ pvt->fr.subclass = AST_FORMAT_SLINEAR; -+ pvt->fr.data = pvt->sco_in_buf + AST_FRIENDLY_OFFSET; -+ -+ if ((r = read(pvt->sco_socket, pvt->fr.data, 48)) == 48) { -+ if (pvt->skip_frames == 0) { -+ f = ast_dsp_process(0, pvt->dsp, &pvt->fr); -+ if (f && (f->frametype == AST_FRAME_DTMF_END)) { -+ pvt->fr.frametype = AST_FRAME_DTMF_END; -+ pvt->fr.subclass = f->subclass; -+ pvt->skip_frames = pvt->dtmf_skip; -+ } -+ return &pvt->fr; ++ pvt->fr.subclass = DEVICE_FRAME_FORMAT; ++ pvt->fr.datalen = CHANNEL_FRAME_SIZE; ++ pvt->fr.samples = CHANNEL_FRAME_SIZE / 2; ++ pvt->fr.src = "Mobile"; ++ pvt->fr.offset = AST_FRIENDLY_OFFSET; ++ pvt->fr.mallocd = 0; ++ pvt->fr.delivery.tv_sec = 0; ++ pvt->fr.delivery.tv_usec = 0; ++ pvt->fr.data = pvt->io_buf + AST_FRIENDLY_OFFSET; ++ ++ if ((r = read(pvt->io_pipe[0], pvt->fr.data, CHANNEL_FRAME_SIZE)) != CHANNEL_FRAME_SIZE) { ++ if (r == -1) { ++ ast_log(LOG_ERROR, "read error %d\n", errno); ++ return &ast_null_frame; + } else { -+ pvt->skip_frames--; ++ pvt->fr.datalen = r; ++ pvt->fr.samples = r / 2; + } -+ } else if (r == -1) { -+ ast_debug(1, "mbl_read() read error %d.\n", errno); -+ close(pvt->sco_socket); -+ pvt->sco_socket = -1; -+ ast_channel_lock(ast); -+ ast->fds[0] = -1; -+ ast_channel_unlock(ast); -+ } else { -+ ast_debug(1, "mbl_read() read short frame. (%d)\n", r); + } + -+ return &ast_null_frame; -+ -+} -+ -+/* ++ f = ast_dsp_process(0, pvt->dsp, &pvt->fr); ++ if (f && (f->frametype == AST_FRAME_DTMF_END)) { ++ pvt->fr.frametype = AST_FRAME_DTMF_END; ++ pvt->fr.subclass = f->subclass; ++ } + -+ We need to deliver 48 byte 'frames' of slin format audio to the device. -+ mbl_write() handles this by buffering short frames until the next time we are called. ++ return &pvt->fr; + -+*/ ++} + +static int mbl_write(struct ast_channel *ast, struct ast_frame *frame) +{ + + struct mbl_pvt *pvt = ast->tech_pvt; -+ int num_frames, i, r; -+ char *pfr; ++ int i, r, io_need, num_frames; ++ char *pfr, buf[DEVICE_FRAME_SIZE]; + -+ if (frame->frametype != AST_FRAME_VOICE) { -+ return 0; -+ } -+ if (pvt->sco_socket == -1) { -+ return 0; -+ } ++ //ast_log(LOG_DEBUG, "*** mbl_write\n"); + -+ if (pvt->state == MBL_STATE_HANGUP) { ++ if (frame->frametype != AST_FRAME_VOICE) { + return 0; + } + -+ if (frame->datalen > sizeof(pvt->sco_out_buf) - pvt->sco_out_len) { -+ frame->datalen = sizeof(pvt->sco_out_buf) - pvt->sco_out_len; -+ ast_debug(1, "Overrun on sco_out_buf detected.\n"); ++ io_need = 0; ++ if (pvt->io_save_len > 0) { ++ io_need = DEVICE_FRAME_SIZE - pvt->io_save_len; ++ memcpy(pvt->io_save_buf + pvt->io_save_len, frame->data, io_need); ++ sco_write(pvt->sco_socket, pvt->io_save_buf, DEVICE_FRAME_SIZE); ++ if ((r = sco_read(pvt->sco_socket, buf, DEVICE_FRAME_SIZE))) { ++ if (pvt->do_alignment_detection) ++ do_alignment_detection(pvt, buf, r); ++ if (ast->_state == AST_STATE_UP) /* Dont queue the audio in the pipe if the call is not up yet. just toss it. */ ++ sco_write(pvt->io_pipe[1], buf, r); ++ } + } + -+ memmove(pvt->sco_out_ptr, frame->data, frame->datalen); -+ pvt->sco_out_len += frame->datalen; -+ num_frames = pvt->sco_out_len / 48; ++ num_frames = (frame->datalen - io_need) / DEVICE_FRAME_SIZE; ++ pfr = frame->data + io_need; + -+ pfr = pvt->sco_out_buf; + for (i=0; isco_socket, pfr, 48)) == -1) { -+ close(pvt->sco_socket); -+ pvt->sco_socket = -1; ++ sco_write(pvt->sco_socket, pfr, DEVICE_FRAME_SIZE); ++ if ((r = sco_read(pvt->sco_socket, buf, DEVICE_FRAME_SIZE))) { ++ if (pvt->do_alignment_detection) ++ do_alignment_detection(pvt, buf, r); ++ if (ast->_state == AST_STATE_UP) ++ sco_write(pvt->io_pipe[1], buf, r); + } -+ pfr += 48; ++ pfr += DEVICE_FRAME_SIZE; ++ } ++ ++ pvt->io_save_len = (frame->datalen - io_need) - (num_frames * DEVICE_FRAME_SIZE); ++ if (pvt->io_save_len > 0) { ++ memcpy(pvt->io_save_buf, pfr, pvt->io_save_len); + } + -+ pvt->sco_out_len = pvt->sco_out_len - (num_frames * 48); -+ memmove(pvt->sco_out_buf, pfr, pvt->sco_out_len); -+ pvt->sco_out_ptr = pvt->sco_out_buf + pvt->sco_out_len; -+ + return 0; + +} @@ -765,12 +872,14 @@ diff -Nru asterisk-addons-1.4.6.org/channels/chan_mobile.c asterisk-addons-1.4.6 + + device = ast_strdupa(S_OR(data, "")); + -+ ast_debug(1, "Checking device state for device %s\n", device); ++ ast_log(LOG_DEBUG, "Checking device state for device %s\n", device); + -+ AST_LIST_TRAVERSE(&devices, pvt, entry) { ++ AST_RWLIST_RDLOCK(&devices); ++ AST_RWLIST_TRAVERSE(&devices, pvt, entry) { + if (!strcmp(pvt->id, device)) + break; + } ++ AST_RWLIST_UNLOCK(&devices); + + if (pvt) { + if (pvt->connected) { @@ -785,57 +894,95 @@ diff -Nru asterisk-addons-1.4.6.org/channels/chan_mobile.c asterisk-addons-1.4.6 + +} + -+static struct ast_channel *mbl_new(int state, struct mbl_pvt *pvt, char *cid_num) ++/* ++ ++ Callback helpers ++ ++*/ ++ ++/* ++ ++ do_alignment_detection() ++ ++ This routine attempts to detect where we get misaligned sco audio data from the bluetooth adaptor. ++ ++ Its enabled by alignmentdetect=yes under the adapter entry in mobile.conf ++ ++ Some adapters suffer a problem where occasionally they will byte shift the audio stream one byte to the right. ++ The result is static or white noise on the inbound (from the adapter) leg of the call. ++ This is characterised by a sudden jump in magnitude of the value of the 16 bit samples. ++ ++ Here we look at the first 4 48 byte frames. We average the absolute values of each sample in the frame, ++ then average the sum of the averages of frames 1, 2, and 3. ++ Frame zero is usually zero. ++ If the end result > 100, and it usually is if we have the problem, set a flag and compensate by shifting the bytes ++ for each subsequent frame during the call. ++ ++ If the result is <= 100 then clear the flag so we dont come back in here... ++ ++ This seems to work OK.... ++ ++*/ ++ ++static void do_alignment_detection(struct mbl_pvt *pvt, char *buf, int buflen) +{ + -+ struct ast_channel *chn; ++ int i; ++ short a, *s; ++ char *p; + -+ chn = ast_channel_alloc(1, state, 0, 0, 0, 0, 0, 0, "Mobile/%s-%04lx", pvt->id, ast_random() & 0xffff); -+ if (chn) { -+ chn->tech = &mbl_tech; -+ chn->nativeformats = prefformat; -+ chn->rawreadformat = prefformat; -+ chn->rawwriteformat = prefformat; -+ chn->writeformat = prefformat; -+ chn->readformat = prefformat; -+ chn->readq.first = NULL; -+ pvt->fr.frametype = AST_FRAME_VOICE; -+ pvt->fr.subclass = AST_FORMAT_SLINEAR; -+ pvt->fr.datalen = 48; -+ pvt->fr.samples = 24; -+ pvt->fr.src = "Mobile"; -+ pvt->fr.offset = AST_FRIENDLY_OFFSET; -+ pvt->fr.mallocd = 0; -+ pvt->fr.delivery.tv_sec = 0; -+ pvt->fr.delivery.tv_usec = 0; -+ pvt->fr.data = pvt->sco_in_buf + AST_FRIENDLY_OFFSET; -+ chn->tech_pvt = pvt; -+ if (state == AST_STATE_RING) -+ chn->rings = 1; -+ ast_copy_string(chn->context, pvt->context, sizeof(chn->context)); -+ ast_copy_string(chn->exten, "s", sizeof(chn->exten)); -+ ast_string_field_set(chn, language, "en"); -+ if (cid_num) -+ chn->cid.cid_num = ast_strdup(cid_num); -+ chn->cid.cid_name = ast_strdup(pvt->id); -+ pvt->owner = chn; ++ if (pvt->alignment_detection_triggered) { ++ for (i=buflen, p=buf+buflen-1; i>0; i--, p--) ++ *p = *(p-1); ++ *(p+1) = 0; ++ return; ++ } + ++ if (pvt->alignment_count < 4) { ++ s = (short *)buf; ++ for (i=0, a=0; ialignment_samples[pvt->alignment_count++] = a; ++ return; + } + -+ return chn; ++ ast_log(LOG_DEBUG, "Alignment Detection result is [%-d %-d %-d %-d]\n", pvt->alignment_samples[0], pvt->alignment_samples[1], pvt->alignment_samples[2], pvt->alignment_samples[3]); ++ ++ a = abs(pvt->alignment_samples[1]) + abs(pvt->alignment_samples[2]) + abs(pvt->alignment_samples[3]); ++ a /= 3; ++ if (a > 100) { ++ pvt->alignment_detection_triggered = 1; ++ ast_log(LOG_DEBUG, "Alignment Detection Triggered.\n"); ++ } else ++ pvt->do_alignment_detection = 0; + +} + -+static int rfcomm_connect(char *bdaddr, int remote_channel) { ++/* ++ ++ rfcomm helpers ++ ++*/ ++ ++static int rfcomm_connect(bdaddr_t src, bdaddr_t dst, int remote_channel) { + -+ bdaddr_t dst; + struct sockaddr_rc addr; + int s; + -+ str2ba(bdaddr, &dst); -+ + if ((s = socket(PF_BLUETOOTH, SOCK_STREAM, BTPROTO_RFCOMM)) < 0) { -+ ast_debug(1, "socket() failed (%d).\n", errno); ++ ast_log(LOG_DEBUG, "socket() failed (%d).\n", errno); ++ return -1; ++ } ++ ++ memset(&addr, 0, sizeof(addr)); ++ addr.rc_family = AF_BLUETOOTH; ++ bacpy(&addr.rc_bdaddr, &src); ++ addr.rc_channel = (uint8_t) 1; ++ if (bind(s, (struct sockaddr *)&addr, sizeof(addr)) < 0) { ++ ast_log(LOG_DEBUG, "bind() failed (%d).\n", errno); ++ close(s); + return -1; + } + @@ -844,7 +991,7 @@ diff -Nru asterisk-addons-1.4.6.org/channels/chan_mobile.c asterisk-addons-1.4.6 + bacpy(&addr.rc_bdaddr, &dst); + addr.rc_channel = remote_channel; + if (connect(s, (struct sockaddr *)&addr, sizeof(addr)) < 0) { -+ ast_debug(1, "connect() failed (%d).\n", errno); ++ ast_log(LOG_DEBUG, "connect() failed (%d).\n", errno); + close(s); + return -1; + } @@ -860,12 +1007,12 @@ diff -Nru asterisk-addons-1.4.6.org/channels/chan_mobile.c asterisk-addons-1.4.6 + ssize_t num_write; + int len; + -+ ast_debug(1, "rfcomm_write() (%s) [%s]\n", pvt->id, buf); ++ ast_log(LOG_DEBUG, "rfcomm_write() (%s) [%s]\n", pvt->id, buf); + len = strlen(buf); + p = buf; + while (len > 0) { + if ((num_write = write(pvt->rfcomm_socket, p, len)) == -1) { -+ ast_debug(1, "rfcomm_write() error [%d]\n", errno); ++ ast_log(LOG_DEBUG, "rfcomm_write() error [%d]\n", errno); + return 0; + } + len -= num_write; @@ -942,17 +1089,29 @@ diff -Nru asterisk-addons-1.4.6.org/channels/chan_mobile.c asterisk-addons-1.4.6 + +} + -+static int sco_connect(char *bdaddr) ++/* ++ ++ sco helpers ++ ++*/ ++ ++static int sco_connect(bdaddr_t src, bdaddr_t dst) +{ + -+ bdaddr_t dst; + struct sockaddr_sco addr; + int s; + -+ str2ba(bdaddr, &dst); -+ + if ((s = socket(PF_BLUETOOTH, SOCK_SEQPACKET, BTPROTO_SCO)) < 0) { -+ ast_debug(1, "socket() failed (%d).\n", errno); ++ ast_log(LOG_DEBUG, "socket() failed (%d).\n", errno); ++ return -1; ++ } ++ ++ memset(&addr, 0, sizeof(addr)); ++ addr.sco_family = AF_BLUETOOTH; ++ bacpy(&addr.sco_bdaddr, &src); ++ if (bind(s, (struct sockaddr *)&addr, sizeof(addr)) < 0) { ++ ast_log(LOG_DEBUG, "bind() failed (%d).\n", errno); ++ close(s); + return -1; + } + @@ -961,7 +1120,7 @@ diff -Nru asterisk-addons-1.4.6.org/channels/chan_mobile.c asterisk-addons-1.4.6 + bacpy(&addr.sco_bdaddr, &dst); + + if (connect(s, (struct sockaddr *)&addr, sizeof(addr)) < 0) { -+ ast_debug(1, "sco connect() failed (%d).\n", errno); ++ ast_log(LOG_DEBUG, "sco connect() failed (%d).\n", errno); + close(s); + return -1; + } @@ -970,10 +1129,53 @@ diff -Nru asterisk-addons-1.4.6.org/channels/chan_mobile.c asterisk-addons-1.4.6 + +} + ++static int sco_write(int s, char *buf, int len) ++{ ++ ++ int r; ++ ++ if (s == -1) { ++ ast_log(LOG_DEBUG, "sco_write() not ready\n"); ++ return 0; ++ } ++ ++ ast_log(LOG_DEBUG, "sco_write()\n"); ++ ++ r = write(s, buf, len); ++ if (r == -1) { ++ ast_log(LOG_DEBUG, "sco write error %d\n", errno); ++ return 0; ++ } ++ ++ return 1; ++ ++} ++ ++static int sco_read(int s, char *buf, int len) ++{ ++ ++ int r; ++ ++ if (s == -1) { ++ ast_log(LOG_DEBUG, "sco_read() not ready\n"); ++ return 0; ++ } ++ ++ ast_log(LOG_DEBUG, "sco_read()\n"); ++ ++ r = read(s, buf, len); ++ if (r == -1) { ++ ast_log(LOG_DEBUG, "sco_read() error %d\n", errno); ++ return 0; ++ } ++ ++ return r; ++ ++} ++ +/* + -+ sdp_search() performs a service discovery on the given device to determine whether -+ or not it supports the Handsfree Profile. ++ sdp helpers + +*/ + @@ -993,7 +1195,7 @@ diff -Nru asterisk-addons-1.4.6.org/channels/chan_mobile.c asterisk-addons-1.4.6 + port = 0; + session = sdp_connect(BDADDR_ANY, &bdaddr, SDP_RETRY_IF_BUSY); + if (!session) { -+ ast_debug(1, "sdp_connect() failed on device %s.\n", addr); ++ ast_log(LOG_DEBUG, "sdp_connect() failed on device %s.\n", addr); + return 0; + } + @@ -1013,10 +1215,9 @@ diff -Nru asterisk-addons-1.4.6.org/channels/chan_mobile.c asterisk-addons-1.4.6 + sdp_record_free(sdprec); + sdp_list_free(response_list, 0); + } else -+ ast_debug(1, "No responses returned for device %s.\n", addr); ++ ast_log(LOG_DEBUG, "No responses returned for device %s.\n", addr); + } else -+ ast_debug(1, "sdp_service_search_attr_req() failed on device %s.\n", addr); -+ ++ ast_log(LOG_DEBUG, "sdp_service_search_attr_req() failed on device %s.\n", addr); + + sdp_list_free(search_list, 0); + sdp_list_free(attrid_list, 0); @@ -1026,16 +1227,6 @@ diff -Nru asterisk-addons-1.4.6.org/channels/chan_mobile.c asterisk-addons-1.4.6 + +} + -+/* -+ -+ sdp_register() -+ -+ Register GENERIC_AUDIO & HEADSET with the SDP daemon on the Asterisk Box. -+ This assists connections to phones/pda's with dud bluetooth stacks like the IMate Jasjam -+ and some Nokia's -+ -+*/ -+ +static sdp_session_t *sdp_register(void) +{ + @@ -1100,11 +1291,7 @@ diff -Nru asterisk-addons-1.4.6.org/channels/chan_mobile.c asterisk-addons-1.4.6 + +/* + -+ Phone Monitor Thread -+ -+ This thread is spun once a phone device is discovered and considered capable of being used, i.e. supports Handsfree Profile, -+ and its configured in mobile.conf. -+ The thread lives for the lifetime of the bluetooth connection, and handles the 'control' side of all calls. ++ Thread routines + +*/ + @@ -1121,7 +1308,7 @@ diff -Nru asterisk-addons-1.4.6.org/channels/chan_mobile.c asterisk-addons-1.4.6 + int callp = 0, callsetupp; + char brsf, nsmode, *p, *p1; + char sms_src[13]; -+ char sms_txt[161]; ++ char sms_txt[160]; + + brsf = nsmode = 0; + @@ -1144,18 +1331,23 @@ diff -Nru asterisk-addons-1.4.6.org/channels/chan_mobile.c asterisk-addons-1.4.6 + s = rfcomm_read(pvt, buf, 0, t); + + if ((s > 0) && (buf[0] != 0x0) && (buf[0] != '\r')) { -+ ast_debug(1, "rfcomm_read() (%s) [%s]\n", pvt->id, buf); ++ ast_log(LOG_DEBUG, "rfcomm_read() (%s) [%s]\n", pvt->id, buf); + switch (pvt->state) { + case MBL_STATE_INIT: + if (strstr(buf, "+BRSF:")) { + brsf = 1; -+ } else if (strstr(buf, "ERROR") && !nsmode) { /* Hmmm, Non-Standard Phone, just continue */ ++ } else if (strstr(buf, "ERROR") && !nsmode) { /* Hmmm, Non-Standard Phone, just continue */ + rfcomm_write(pvt, "AT+CIND=?\r"); + pvt->state++; + nsmode = 1; + } else if (strstr(buf, "OK") && brsf) { -+ rfcomm_write(pvt, "AT+CIND=?\r"); -+ pvt->state++; ++ if (pvt->blackberry) { ++ rfcomm_write(pvt, "AT+CMER=3,0,0,1\r"); ++ pvt->state = MBL_STATE_INIT3; ++ } else { ++ rfcomm_write(pvt, "AT+CIND=?\r"); ++ pvt->state++; ++ } + } + break; + case MBL_STATE_INIT1: @@ -1171,21 +1363,21 @@ diff -Nru asterisk-addons-1.4.6.org/channels/chan_mobile.c asterisk-addons-1.4.6 + group2++; + } + if (strstr(buf+i, "\"call\"")) -+ callp = group2; ++ callp = group2; + if (strstr(buf+i, "\"call_setup\"")) + callsetupp = group2; + if (strstr(buf+i, "\"callsetup\"")) + callsetupp = group2; + } -+ sprintf(pvt->ciev_call_0, "%d,0", callp); -+ sprintf(pvt->ciev_call_1, "%d,1", callp); -+ sprintf(pvt->ciev_callsetup_0, "%d,0", callsetupp); -+ sprintf(pvt->ciev_callsetup_1, "%d,1", callsetupp); -+ sprintf(pvt->ciev_callsetup_2, "%d,2", callsetupp); -+ sprintf(pvt->ciev_callsetup_3, "%d,3", callsetupp); ++ snprintf(pvt->ciev_call_0, sizeof(pvt->ciev_call_0), "%d,0", callp); ++ snprintf(pvt->ciev_call_1, sizeof(pvt->ciev_call_1), "%d,1", callp); ++ snprintf(pvt->ciev_callsetup_0, sizeof(pvt->ciev_callsetup_0), "%d,0", callsetupp); ++ snprintf(pvt->ciev_callsetup_1, sizeof(pvt->ciev_callsetup_1), "%d,1", callsetupp); ++ snprintf(pvt->ciev_callsetup_2, sizeof(pvt->ciev_callsetup_2), "%d,2", callsetupp); ++ snprintf(pvt->ciev_callsetup_3, sizeof(pvt->ciev_callsetup_3), "%d,3", callsetupp); + if (callsetupp == 0) /* This phone has no call setup indication!! ... */ + pvt->no_callsetup = 1; -+ ast_debug(1, "CIEV_CALL=%d CIEV_CALLSETUP=%d\n", callp, callsetupp); ++ ast_log(LOG_DEBUG, "CIEV_CALL=%d CIEV_CALLSETUP=%d\n", callp, callsetupp); + } + if (strstr(buf, "OK")) { + rfcomm_write(pvt, "AT+CIND?\r"); @@ -1200,44 +1392,59 @@ diff -Nru asterisk-addons-1.4.6.org/channels/chan_mobile.c asterisk-addons-1.4.6 + monitor = 0; + } + } else if (strstr(buf, "OK")) { -+ rfcomm_write(pvt, "AT+CMER=3,0,0,1\r"); -+ pvt->state++; ++ if (pvt->blackberry) { ++ rfcomm_write(pvt, "AT+CLIP=1\r"); ++ pvt->state = MBL_STATE_INIT4; ++ } else { ++ rfcomm_write(pvt, "AT+CMER=3,0,0,1\r"); ++ pvt->state++; ++ } + } + break; + case MBL_STATE_INIT3: + if (strstr(buf, "OK")) { -+ rfcomm_write(pvt, "AT+CLIP=1\r"); -+ pvt->state++; ++ if (pvt->blackberry) { ++ rfcomm_write(pvt, "AT+CIND=?\r"); ++ pvt->state = MBL_STATE_INIT1; ++ } else { ++ rfcomm_write(pvt, "AT+CLIP=1\r"); ++ pvt->state++; ++ } + } + break; + case MBL_STATE_INIT4: + if (strstr(buf, "OK")) { -+ rfcomm_write(pvt, "AT+CMGF=1\r"); ++ rfcomm_write(pvt, "AT+VGS=15\r"); + pvt->state++; + } + break; + case MBL_STATE_INIT5: -+ if (strstr(buf, "ERROR")) { /* No SMS Support ! */ ++ if (strstr(buf, "OK")) { ++ rfcomm_write(pvt, "AT+CMGF=1\r"); ++ pvt->state++; ++ } ++ break; ++ case MBL_STATE_INIT6: ++ if (strstr(buf, "ERROR")) { /* No SMS Support ! */ + pvt->state = MBL_STATE_PREIDLE; + } else if (strstr(buf, "OK")) { + rfcomm_write(pvt, "AT+CNMI=2,1,0,1,0\r"); + pvt->state++; + } + break; -+ case MBL_STATE_INIT6: -+ if (strstr(buf, "OK")) { /* We have SMS Support */ ++ case MBL_STATE_INIT7: ++ if (strstr(buf, "OK")) { /* We have SMS Support */ + pvt->has_sms = 1; + pvt->state = MBL_STATE_PREIDLE; + } else if (strstr(buf, "ERROR")) { + pvt->has_sms = 0; -+ ast_log(LOG_NOTICE,"Device %s has no bluetooth SMS capability.\n", pvt->id); + pvt->state = MBL_STATE_PREIDLE; + } + break; + case MBL_STATE_PREIDLE: /* Nothing handled here, wait for timeout, then off we go... */ + break; + case MBL_STATE_IDLE: -+ ast_debug(1, "Device %s %s [%s]\n", pvt->bdaddr, pvt->id, buf); ++ ast_log(LOG_DEBUG, "Device %s [%s]\n", pvt->id, buf); + if (strstr(buf, "RING")) { + pvt->state = MBL_STATE_RING; + } else if (strstr(buf, "+CIEV:")) { @@ -1261,6 +1468,7 @@ diff -Nru asterisk-addons-1.4.6.org/channels/chan_mobile.c asterisk-addons-1.4.6 + case MBL_STATE_OUTGOING: + if (strstr(buf, "+CIEV")) { + if (strstr(buf, pvt->ciev_call_0)) { /* call was hung up */ ++ pvt->do_hangup = 0; + ast_queue_control(pvt->owner, AST_CONTROL_HANGUP); + } else if (strstr(buf, pvt->ciev_callsetup_3)) { /* b-party ringing */ + ast_queue_control(pvt->owner, AST_CONTROL_RINGING); @@ -1278,9 +1486,6 @@ diff -Nru asterisk-addons-1.4.6.org/channels/chan_mobile.c asterisk-addons-1.4.6 + cid_num[pcide - pcids - 1] = 0x00; + } + } -+ pvt->sco_out_ptr = pvt->sco_out_buf; -+ pvt->sco_out_len = 0; -+ pvt->sent_answer = 0; + chn = mbl_new(AST_STATE_RING, pvt, cid_num); + if (chn) { + if (ast_pbx_start(chn)) { @@ -1296,9 +1501,6 @@ diff -Nru asterisk-addons-1.4.6.org/channels/chan_mobile.c asterisk-addons-1.4.6 + } + break; + case MBL_STATE_RING2: -+ pvt->sco_out_ptr = pvt->sco_out_buf; -+ pvt->sco_out_len = 0; -+ pvt->sent_answer = 0; + chn = mbl_new(AST_STATE_RING, pvt, cid_num); + if (chn) { + if (ast_pbx_start(chn)) { @@ -1319,7 +1521,6 @@ diff -Nru asterisk-addons-1.4.6.org/channels/chan_mobile.c asterisk-addons-1.4.6 + pvt->state = MBL_STATE_INCOMING; + } else { /* User answered on handset!, disconnect */ + pvt->state = MBL_STATE_IDLE; -+ ast_log(LOG_NOTICE,"Closing the sco_socket in RING3 with CIEV\n"); + if (pvt->sco_socket > -1) + close(pvt->sco_socket); + ast_queue_control(pvt->owner, AST_CONTROL_HANGUP); @@ -1333,12 +1534,15 @@ diff -Nru asterisk-addons-1.4.6.org/channels/chan_mobile.c asterisk-addons-1.4.6 + case MBL_STATE_INCOMING: + if (strstr(buf, "+CIEV")) { + if (strstr(buf, pvt->ciev_call_0)) { ++ pvt->do_hangup = 0; + ast_queue_control(pvt->owner, AST_CONTROL_HANGUP); + } + } + break; + case MBL_STATE_HANGUP: + if (strstr(buf, "OK") || strstr(buf, pvt->ciev_call_0)) { ++ close(pvt->sco_socket); ++ pvt->sco_socket = -1; + pvt->state = MBL_STATE_IDLE; + } + break; @@ -1364,8 +1568,7 @@ diff -Nru asterisk-addons-1.4.6.org/channels/chan_mobile.c asterisk-addons-1.4.6 + ast_log(LOG_ERROR, "Unable to start pbx on incoming sms.\n"); + pvt->state = MBL_STATE_IDLE; + } else { -+ memset(sms_txt, 0x00, sizeof(sms_txt)); -+ strncpy(sms_txt, buf, strlen(buf)); ++ ast_copy_string(sms_txt, buf, sizeof(sms_txt)); + } + break; + case MBL_STATE_OUTSMS: @@ -1385,7 +1588,7 @@ diff -Nru asterisk-addons-1.4.6.org/channels/chan_mobile.c asterisk-addons-1.4.6 + p++; + smsi = atoi(p); + if (smsi > 0) { -+ sprintf(buf, "AT+CMGR=%d\r", smsi); ++ snprintf(buf, sizeof(buf), "AT+CMGR=%d\r", smsi); + rfcomm_write(pvt, buf); + pvt->state = MBL_STATE_INSMS; + } @@ -1397,14 +1600,14 @@ diff -Nru asterisk-addons-1.4.6.org/channels/chan_mobile.c asterisk-addons-1.4.6 + pvt->state++; + rfcomm_write(pvt, "AT+CMER=3,0,0,1\r"); + } else if (pvt->state == MBL_STATE_INIT3) { /* Some devices dont respond to AT+CMER=3,0,0,1 properly. VK 2020 for example */ -+ pvt->state++; -+ rfcomm_write(pvt, "AT+CLIP=1\r"); ++ pvt->state++; ++ rfcomm_write(pvt, "AT+CLIP=1\r"); + } else if (pvt->state == MBL_STATE_PREIDLE) { + pvt->connected = 1; + ast_verbose(VERBOSE_PREFIX_3 "Bluetooth Device %s initialised and ready.\n", pvt->id); + pvt->state = MBL_STATE_IDLE; + } else if (pvt->state == MBL_STATE_DIAL) { -+ sprintf(buf, "ATD%s;\r", pvt->dial_number); ++ snprintf(buf, sizeof(buf), "ATD%s;\r", pvt->dial_number); + if (!rfcomm_write(pvt, buf)) { + ast_log(LOG_ERROR, "Dial failed on %s state %d\n", pvt->owner->name, pvt->state); + ast_queue_control(pvt->owner, AST_CONTROL_CONGESTION); @@ -1420,19 +1623,22 @@ diff -Nru asterisk-addons-1.4.6.org/channels/chan_mobile.c asterisk-addons-1.4.6 + } else if (pvt->state == MBL_STATE_RING) { /* No CLIP?, bump it */ + pvt->state = MBL_STATE_RING2; + } else if (pvt->state == MBL_STATE_HANGUP) { -+ if (pvt->hangup_count == 6) { -+ ast_debug(1, "Device %s failed to hangup after 6 tries, disconnecting.\n", pvt->id); -+ monitor = 0; -+ } -+ rfcomm_write(pvt, "AT+CHUP\r"); -+ pvt->hangup_count++; ++ if (pvt->do_hangup) { ++ if (pvt->hangup_count == 6) { ++ ast_log(LOG_DEBUG, "Device %s failed to hangup after 6 tries, disconnecting.\n", pvt->id); ++ monitor = 0; ++ } ++ rfcomm_write(pvt, "AT+CHUP\r"); ++ pvt->hangup_count++; ++ } else ++ pvt->state = MBL_STATE_IDLE; + } else if (pvt->state == MBL_STATE_OUTSMS) { -+ sprintf(buf, "AT+CMGS=\"%s\"\r", pvt->dial_number); ++ snprintf(buf, sizeof(buf), "AT+CMGS=\"%s\"\r", pvt->dial_number); + rfcomm_write(pvt, buf); + pvt->state = MBL_STATE_OUTSMS1; + } else if (pvt->state == MBL_STATE_OUTSMS1) { + if (pvt->rfcomm_buf[0] == '>') { -+ sprintf(buf, "%s%c", pvt->sms_txt, 0x1a); ++ snprintf(buf, sizeof(buf), "%s%c", pvt->sms_txt, 0x1a); + rfcomm_write(pvt, buf); + pvt->state = MBL_STATE_OUTSMS2; + } else { @@ -1451,25 +1657,27 @@ diff -Nru asterisk-addons-1.4.6.org/channels/chan_mobile.c asterisk-addons-1.4.6 + + } + -+ close(pvt->rfcomm_socket); -+ close(pvt->sco_socket); ++ if (pvt->rfcomm_socket > -1) ++ close(pvt->rfcomm_socket); ++ if (pvt->sco_socket > -1) ++ close(pvt->sco_socket); + pvt->sco_socket = -1; + pvt->connected = 0; + pvt->monitor_thread = AST_PTHREADT_NULL; + -+ return NULL; ++ pthread_cancel(pvt->sco_listener_thread); ++ pthread_join(pvt->sco_listener_thread, NULL); ++ pvt->sco_listener_thread = AST_PTHREADT_NULL; + -+} ++ close(pvt->adapter->sco_socket); + -+/* ++ manager_event(EVENT_FLAG_SYSTEM, "MobileStatus", "Status: Disconnect\r\nDevice: %s\r\n", pvt->id); + -+ Headset Monitor Thread ++ pvt->adapter->inuse = 0; + -+ This thread is spun once a headset device is discovered and considered capable of being used, i.e. supports Headset Profile, -+ and its configured in mobile.conf. -+ The thread lives for the lifetime of the bluetooth connection, and handles the 'control' side of all calls. ++ return NULL; + -+*/ ++} + +static void *do_monitor_headset(void *data) +{ @@ -1490,14 +1698,10 @@ diff -Nru asterisk-addons-1.4.6.org/channels/chan_mobile.c asterisk-addons-1.4.6 + s = rfcomm_read(pvt, buf, 0, t); + + if ((s > 0) && (buf[0] != 0x0) && (buf[0] != '\r')) { -+ ast_debug(1, "rfcomm_read() (%s) [%s]\n", pvt->id, buf); ++ ast_log(LOG_DEBUG, "rfcomm_read() (%s) [%s]\n", pvt->id, buf); + switch (pvt->state) { + case MBL_STATE_RING2: + if (strstr(buf, "AT+CKPD=")) { -+ ast_channel_lock(pvt->owner); -+ pvt->owner->fds[0] = pvt->sco_socket; -+ ast_log(LOG_NOTICE,"pvt-sco_socket used for fds in headphone code\n"); -+ ast_channel_unlock(pvt->owner); + ast_queue_control(pvt->owner, AST_CONTROL_ANSWER); + pvt->state = MBL_STATE_INCOMING; + rfcomm_write(pvt, "\r\n+VGS=13\r\n"); @@ -1523,9 +1727,8 @@ diff -Nru asterisk-addons-1.4.6.org/channels/chan_mobile.c asterisk-addons-1.4.6 + ast_verbose(VERBOSE_PREFIX_3 "Bluetooth Device %s initialised and ready.\n", pvt->id); + pvt->state = MBL_STATE_IDLE; + } else if (pvt->state == MBL_STATE_RING) { -+ pvt->sco_socket = sco_connect(pvt->bdaddr); ++ pvt->sco_socket = sco_connect(pvt->adapter->addr, pvt->addr); + if (pvt->sco_socket > -1) { -+ ast_log(LOG_NOTICE,"sco_connect returned -1 in state RING\n"); + ast_setstate(pvt->owner, AST_STATE_RINGING); + ast_queue_control(pvt->owner, AST_CONTROL_RINGING); + pvt->state = MBL_STATE_RING2; @@ -1543,6 +1746,18 @@ diff -Nru asterisk-addons-1.4.6.org/channels/chan_mobile.c asterisk-addons-1.4.6 + + } + ++ if (pvt->rfcomm_socket > -1) ++ close(pvt->rfcomm_socket); ++ if (pvt->sco_socket > -1) ++ close(pvt->sco_socket); ++ pvt->sco_socket = -1; ++ pvt->connected = 0; ++ pvt->monitor_thread = AST_PTHREADT_NULL; ++ ++ manager_event(EVENT_FLAG_SYSTEM, "MobileStatus", "Status: Disconnect\r\nDevice: %s\r\n", pvt->id); ++ ++ pvt->adapter->inuse = 0; ++ + return NULL; + +} @@ -1555,6 +1770,11 @@ diff -Nru asterisk-addons-1.4.6.org/channels/chan_mobile.c asterisk-addons-1.4.6 + pvt->monitor_thread = AST_PTHREADT_NULL; + return 0; + } ++ /* we are a phone, so spin the sco listener on the adapter as well */ ++ if (ast_pthread_create_background(&pvt->sco_listener_thread, NULL, do_sco_listen, pvt->adapter) < 0) { ++ ast_log(LOG_ERROR, "Unable to create sco listener thread for device %s.\n", pvt->id); ++ } ++ + } else { + if (ast_pthread_create_background(&pvt->monitor_thread, NULL, do_monitor_headset, pvt) < 0) { + pvt->monitor_thread = AST_PTHREADT_NULL; @@ -1566,36 +1786,35 @@ diff -Nru asterisk-addons-1.4.6.org/channels/chan_mobile.c asterisk-addons-1.4.6 + +} + -+/* -+ -+ Device Discovery Thread. -+ -+ This thread wakes every 'discovery_interval' seconds and trys to connect to -+ those configured devices which are not connected. This saves the user from having -+ to manually connect his/her cell phone to the asterisk box. Once a successful -+ connection is made, a monitor thread is spun on the device which lives for the -+ lifetime of the connection. -+ -+*/ -+ +static void *do_discovery(void *data) +{ + -+ struct mbl_pvt *pvt = data; ++ struct adapter_pvt *adapter; ++ struct mbl_pvt *pvt; + + for (;;) { -+ AST_LIST_TRAVERSE(&devices, pvt, entry) { -+ if (!pvt->connected) { -+ if ((pvt->rfcomm_socket = rfcomm_connect(pvt->bdaddr, pvt->rfcomm_port)) > -1) { -+ pvt->state = 0; -+ if (start_monitor(pvt)) { -+ pvt->connected = 1; -+ if (option_verbose > 2) -+ ast_verbose(VERBOSE_PREFIX_3 "Bluetooth Device %s has connected.\n", pvt->id); ++ AST_RWLIST_RDLOCK(&adapters); ++ AST_RWLIST_TRAVERSE(&adapters, adapter, entry) { ++ if (!adapter->inuse) { ++ AST_RWLIST_RDLOCK(&devices); ++ AST_RWLIST_TRAVERSE(&devices, pvt, entry) { ++ if (!adapter->inuse && !pvt->connected && !strcmp(adapter->id, pvt->adapter->id)) { ++ if ((pvt->rfcomm_socket = rfcomm_connect(adapter->addr, pvt->addr, pvt->rfcomm_port)) > -1) { ++ pvt->state = 0; ++ if (start_monitor(pvt)) { ++ pvt->connected = 1; ++ adapter->inuse = 1; ++ manager_event(EVENT_FLAG_SYSTEM, "MobileStatus", "Status: Connect\r\nDevice: %s\r\n", pvt->id); ++ if (option_verbose > 2) ++ ast_verbose(VERBOSE_PREFIX_3 "Bluetooth Device %s has connected.\n", pvt->id); ++ } ++ } + } + } ++ AST_RWLIST_UNLOCK(&devices); + } + } ++ AST_RWLIST_UNLOCK(&adapters); + /* Go to sleep */ + sleep(discovery_interval); + } @@ -1603,98 +1822,93 @@ diff -Nru asterisk-addons-1.4.6.org/channels/chan_mobile.c asterisk-addons-1.4.6 + return NULL; +} + -+/* -+ -+ This thread listens for incoming sco connections. -+ Although the Bluetooth Handsfree Profile Specification says that either end may initiate the audio connection, -+ in practice some devices (LG TU500) get upset unless they initiate the connection. -+ We leave all sco initiation to the device. -+ On an inbound sco connection, we need to find the appropriate device, and set the channel fd accordingly. -+ -+*/ -+ +static void *do_sco_listen(void *data) +{ + + int ns; -+ bdaddr_t local; + struct sockaddr_sco addr; ++ char saddr[18]; + struct sco_options so; + socklen_t len; + int opt = 1; -+ char saddr[18]; + socklen_t addrlen; + struct mbl_pvt *pvt; ++ struct adapter_pvt *adapter = (struct adapter_pvt *) data; + -+ hci_devba(0, &local); -+ -+ if ((sco_socket = socket(PF_BLUETOOTH, SOCK_SEQPACKET, BTPROTO_SCO)) < 0) { ++ if ((adapter->sco_socket = socket(PF_BLUETOOTH, SOCK_SEQPACKET, BTPROTO_SCO)) < 0) { + ast_log(LOG_ERROR, "Unable to create sco listener socket.\n"); + return NULL; + } + memset(&addr, 0, sizeof(addr)); + addr.sco_family = AF_BLUETOOTH; -+ bacpy(&addr.sco_bdaddr, &local); -+ if (bind(sco_socket, (struct sockaddr *)&addr, sizeof(addr)) < 0) { ++ bacpy(&addr.sco_bdaddr, &adapter->addr); ++ if (bind(adapter->sco_socket, (struct sockaddr *)&addr, sizeof(addr)) < 0) { + ast_log(LOG_ERROR, "Unable to bind sco listener socket. (%d)\n", errno); -+ close(sco_socket); ++ close(adapter->sco_socket); + return NULL; + } -+ if (setsockopt(sco_socket, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt)) == -1) { ++ if (setsockopt(adapter->sco_socket, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt)) == -1) { + ast_log(LOG_ERROR, "Unable to setsockopt sco listener socket.\n"); -+ close(sco_socket); ++ close(adapter->sco_socket); + return NULL; + } -+ if (listen(sco_socket, 5) < 0) { ++ if (listen(adapter->sco_socket, 5) < 0) { + ast_log(LOG_ERROR, "Unable to listen sco listener socket.\n"); -+ close(sco_socket); ++ close(adapter->sco_socket); + return NULL; + } + while (1) { -+ addrlen = sizeof(struct sockaddr); -+ ast_log(LOG_NOTICE, "About to accept the sco_socket...\n"); -+ if ((ns = accept(sco_socket, (struct sockaddr *)&addr, &addrlen)) > -1) { -+ ast_log(LOG_NOTICE, "sco_socket returns %d...\n",ns); -+ ba2str(&addr.sco_bdaddr, saddr); -+ ++ ast_log(LOG_DEBUG, "About to accept() socket.\n"); ++ addrlen = sizeof(struct sockaddr_sco); ++ if ((ns = accept(adapter->sco_socket, (struct sockaddr *)&addr, &addrlen)) > -1) { ++ ast_log(LOG_DEBUG, "accept()ed socket.\n"); + len = sizeof(so); + getsockopt(ns, SOL_SCO, SCO_OPTIONS, &so, &len); + -+ ast_debug(1, "Incoming Audio Connection from device %s MTU is %d\n", saddr, so.mtu); ++ ba2str(&addr.sco_bdaddr, saddr); ++ ast_log(LOG_DEBUG, "Incoming Audio Connection from device %s MTU is %d\n", saddr, so.mtu); + + pvt = NULL; -+ AST_LIST_TRAVERSE(&devices, pvt, entry) { -+ if (!strcmp(pvt->bdaddr, saddr)) ++ AST_RWLIST_RDLOCK(&devices); ++ AST_RWLIST_TRAVERSE(&devices, pvt, entry) { ++ if (!bacmp(&pvt->addr, &addr.sco_bdaddr)) + break; + } ++ AST_RWLIST_UNLOCK(&devices); + if (pvt) { -+ ast_log(LOG_NOTICE,"about to close the pvt-sco_socket and set it ns\n"); + if (pvt->sco_socket != -1) + close(pvt->sco_socket); + pvt->sco_socket = ns; -+ if (pvt->owner) { -+ ast_channel_lock(pvt->owner); -+ pvt->owner->fds[0] = ns; -+ ast_channel_unlock(pvt->owner); -+ } + } else -+ ast_debug(1, "Could not find device for incoming Audio Connection.\n"); ++ ast_log(LOG_DEBUG, "Could not find device for incoming Audio Connection.\n"); ++ } else { ++ ast_log(LOG_ERROR, "accept() failed %d\n", errno); + } -+ else ast_log(LOG_NOTICE, "Accept got a -1...."); + } + + return NULL; + +} + ++/* ++ ++ Module ++ ++*/ ++ +static int mbl_load_config(void) +{ + + struct ast_config *cfg = NULL; + char *cat = NULL; + struct ast_variable *var; -+ const char *address, *port, *context, *type, *skip; ++ const char *id, *address, *useadapter, *port, *context, *type, *skip, *group, *master, *nocallsetup, *aligndetect, *blackberry; + struct mbl_pvt *pvt; ++ struct adapter_pvt *adapter; ++ uint16_t vs; ++ struct hci_dev_req dr; ++ char nadapters = 0; ++ // struct ast_flags config_flags = { 0 }; + + cfg = ast_config_load(MBL_CONFIG); + if (!cfg) @@ -1705,48 +1919,130 @@ diff -Nru asterisk-addons-1.4.6.org/channels/chan_mobile.c asterisk-addons-1.4.6 + discovery_interval = atoi(var->value); + } + ++ /* load adapters first */ ++ cat = ast_category_browse(cfg, NULL); ++ while (cat) { ++ if (!strcasecmp(cat, "adapter")) { ++ id = ast_variable_retrieve(cfg, cat, "id"); ++ address = ast_variable_retrieve(cfg, cat, "address"); ++ master = ast_variable_retrieve(cfg, cat, "forcemaster"); ++ aligndetect = ast_variable_retrieve(cfg, cat, "alignmentdetection"); ++ ast_log(LOG_DEBUG, "Loading adapter %s %s.\n", id, address); ++ if (!ast_strlen_zero(id) && !ast_strlen_zero(address)) { ++ if ((adapter = ast_calloc(1, sizeof(*adapter)))) { ++ ast_copy_string(adapter->id, id, sizeof(adapter->id)); ++ str2ba(address, &adapter->addr); ++ if (!ast_strlen_zero(aligndetect)) { ++ if (*aligndetect == 'Y' || *aligndetect == 'y') ++ adapter->alignment_detection = 1; ++ } ++ adapter->dev_id = hci_devid(address); ++ adapter->hci_socket = hci_open_dev(adapter->dev_id); ++ if (adapter->dev_id < 0 || adapter->hci_socket < 0) { ++ ast_log(LOG_ERROR, "Unable to open adapter %s. It won't be enabled.\n", adapter->id); ++ ast_free(adapter); ++ } else { ++ if ((master) && (*master)) { ++ dr.dev_id = adapter->dev_id; ++ if (hci_strtolm("master", &dr.dev_opt)) { ++ if (ioctl(adapter->hci_socket, HCISETLINKMODE, (unsigned long) &dr) < 0) { ++ ast_log(LOG_WARNING, "Unable to set adapter %s link mode to MASTER.\n", adapter->id); ++ } ++ } ++ } ++ hci_read_voice_setting(adapter->hci_socket, &vs, 1000); ++ vs = htobs(vs); ++ if (vs != 0x0060) { ++ ast_log(LOG_ERROR, "Incorrect voice setting for adapter %s, it must be 0x0060 - see 'man hciconfig' for details.\n", adapter->id); ++ hci_close_dev(adapter->hci_socket); ++ ast_free(adapter); ++ } else { ++ AST_RWLIST_WRLOCK(&adapters); ++ AST_RWLIST_INSERT_HEAD(&adapters, adapter, entry); ++ AST_RWLIST_UNLOCK(&adapters); ++ nadapters++; ++ } ++ } ++ } ++ } else ++ ast_log(LOG_ERROR, "id/address missing for adapter %s. It won't be enabled.\n", cat); ++ } ++ cat = ast_category_browse(cfg, cat); ++ } ++ ++ if (!nadapters) { ++ ast_log(LOG_WARNING, "***********************************************************************\n"); ++ ast_log(LOG_WARNING, "No Adapters defined. Please review mobile.conf. See sample for details.\n"); ++ ast_log(LOG_WARNING, "***********************************************************************\n"); ++ } ++ ++ /* now load devices */ + cat = ast_category_browse(cfg, NULL); + while (cat) { -+ if (strcasecmp(cat, "general")) { -+ ast_debug(1, "Loading device %s.\n", cat); ++ if (strcasecmp(cat, "general") && strcasecmp(cat, "adapter")) { ++ ast_log(LOG_DEBUG, "Loading device %s.\n", cat); + address = ast_variable_retrieve(cfg, cat, "address"); ++ useadapter = ast_variable_retrieve(cfg, cat, "adapter"); + port = ast_variable_retrieve(cfg, cat, "port"); + context = ast_variable_retrieve(cfg, cat, "context"); -+ ast_log(LOG_NOTICE, "context for non-general category %s was %s\n", cat, context); + type = ast_variable_retrieve(cfg, cat, "type"); + skip = ast_variable_retrieve(cfg, cat, "dtmfskip"); -+ if (address && port) { -+ if ((pvt = ast_malloc(sizeof(struct mbl_pvt)))) { ++ group = ast_variable_retrieve(cfg, cat, "group"); ++ nocallsetup = ast_variable_retrieve(cfg, cat, "nocallsetup"); ++ blackberry = ast_variable_retrieve(cfg, cat, "blackberry"); ++ if (!ast_strlen_zero(address) && !ast_strlen_zero(port) && !ast_strlen_zero(useadapter)) { ++ /* find the adapter */ ++ AST_RWLIST_RDLOCK(&adapters); ++ AST_RWLIST_TRAVERSE(&adapters, adapter, entry) { ++ if (!strcmp(adapter->id, useadapter)) ++ break; ++ } ++ AST_RWLIST_UNLOCK(&adapters); ++ if (!adapter) { ++ ast_log(LOG_ERROR, "Device %s configured to use unknown adapter %s. It won't be enabled.\n", cat, useadapter); ++ break; ++ } ++ if ((pvt = ast_calloc(1, sizeof(*pvt)))) { + if (type && !strcmp(type, "headset")) + pvt->type = MBL_TYPE_HEADSET; + else + pvt->type = MBL_TYPE_PHONE; ++ ++ if (blackberry) ++ pvt->blackberry = ast_true(blackberry); ++ + ast_copy_string(pvt->id, cat, sizeof(pvt->id)); -+ ast_copy_string(pvt->bdaddr, address, sizeof(pvt->bdaddr)); ++ str2ba(address, &pvt->addr); + ast_copy_string(pvt->context, S_OR(context, "default"), sizeof(pvt->context)); -+ pvt->connected = 0; ++ if (group) ++ pvt->group = atoi(group); /* group 0 if invalid */ + pvt->state = MBL_STATE_INIT; + pvt->rfcomm_socket = -1; + pvt->rfcomm_port = atoi(port); -+ pvt->rfcomm_buf[0] = 0x00; + pvt->sco_socket = -1; + pvt->monitor_thread = AST_PTHREADT_NULL; -+ pvt->owner = NULL; -+ pvt->no_callsetup = 0; -+ pvt->has_sms = 0; ++ pvt->sco_listener_thread = AST_PTHREADT_NULL; ++ if (!ast_strlen_zero(nocallsetup)) { ++ if ((*nocallsetup == 'y') || (*nocallsetup == 'Y')) { ++ pvt->no_callsetup = 1; ++ ast_log(LOG_DEBUG, "Setting nocallsetup mode for device %s.\n", pvt->id); ++ } ++ } + pvt->dsp = ast_dsp_new(); + if (skip) { + if ((pvt->dtmf_skip = atoi(skip)) == 0) + pvt->dtmf_skip = 200; + } else + pvt->dtmf_skip = 200; -+ pvt->skip_frames = 0; + ast_dsp_set_features(pvt->dsp, DSP_FEATURE_DTMF_DETECT); + ast_dsp_digitmode(pvt->dsp, DSP_DIGITMODE_DTMF | DSP_DIGITMODE_RELAXDTMF); -+ AST_LIST_INSERT_HEAD(&devices, pvt, entry); ++ pvt->adapter = adapter; ++ AST_RWLIST_WRLOCK(&devices); ++ AST_RWLIST_INSERT_HEAD(&devices, pvt, entry); ++ AST_RWLIST_UNLOCK(&devices); + } + } else { -+ ast_log(LOG_ERROR, "Device %s has no address/port configured. It wont be enabled.\n", cat); ++ ast_log(LOG_ERROR, "Device %s has no address/port/adapter configured. It won't be enabled.\n", cat); + } + } + cat = ast_category_browse(cfg, cat); @@ -1758,17 +2054,11 @@ diff -Nru asterisk-addons-1.4.6.org/channels/chan_mobile.c asterisk-addons-1.4.6 + +} + -+static int reload_module(void) -+{ -+ -+ return 0; -+ -+} -+ +static int unload_module(void) +{ + + struct mbl_pvt *pvt; ++ struct adapter_pvt *adapter; + + /* First, take us out of the channel loop */ + ast_channel_unregister(&mbl_tech); @@ -1778,38 +2068,48 @@ diff -Nru asterisk-addons-1.4.6.org/channels/chan_mobile.c asterisk-addons-1.4.6 + pthread_cancel(discovery_thread); + pthread_join(discovery_thread, NULL); + } -+ /* Kill the sco listener thread */ -+ if (sco_listener_thread != AST_PTHREADT_NULL) { -+ pthread_cancel(sco_listener_thread); -+ pthread_join(sco_listener_thread, NULL); -+ } -+ if ((close(sco_socket) == -1)) -+ ast_log(LOG_ERROR, "Unable to close sco_socket %d.\n", errno); -+ -+ /* Unregister the CLI & APP */ -+ ast_cli_unregister_multiple(mbl_cli, sizeof(mbl_cli) / sizeof(mbl_cli[0])); -+ ast_unregister_application(app_mblstatus); -+ ast_unregister_application(app_mblsendsms); + + /* Destroy the device list */ -+ while ((pvt = AST_LIST_REMOVE_HEAD(&devices, entry))) { ++ AST_RWLIST_WRLOCK(&devices); ++ while ((pvt = AST_RWLIST_REMOVE_HEAD(&devices, entry))) { + if (pvt->monitor_thread != AST_PTHREADT_NULL) { + pthread_cancel(pvt->monitor_thread); + pthread_join(pvt->monitor_thread, NULL); + } ++ if (pvt->sco_listener_thread != AST_PTHREADT_NULL) { ++ pthread_cancel(pvt->sco_listener_thread); ++ pthread_join(pvt->sco_listener_thread, NULL); ++ } + if (pvt->sco_socket > -1) { + close(pvt->sco_socket); + } ++ if (pvt->adapter->sco_socket > -1) { ++ close(pvt->adapter->sco_socket); ++ } + if (pvt->rfcomm_socket > -1) { + close(pvt->rfcomm_socket); + } + ast_dsp_free(pvt->dsp); -+ free(pvt); ++ ast_free(pvt); ++ } ++ AST_RWLIST_UNLOCK(&devices); ++ ++ /* Destroy the adapter list */ ++ AST_RWLIST_WRLOCK(&adapters); ++ while ((adapter = AST_RWLIST_REMOVE_HEAD(&adapters, entry))) { ++ hci_close_dev(adapter->hci_socket); ++ ast_free(adapter); + } ++ AST_RWLIST_UNLOCK(&adapters); + + if (sdp_session) + sdp_close(sdp_session); + ++ /* Unregister the CLI & APP */ ++ ast_cli_unregister_multiple(mbl_cli, sizeof(mbl_cli) / sizeof(mbl_cli[0])); ++ ast_unregister_application(app_mblstatus); ++ ast_unregister_application(app_mblsendsms); ++ + return 0; + +} @@ -1818,7 +2118,6 @@ diff -Nru asterisk-addons-1.4.6.org/channels/chan_mobile.c asterisk-addons-1.4.6 +{ + + int dev_id, s; -+ uint16_t vs; + + /* Check if we have Bluetooth, no point loading otherwise... */ + dev_id = hci_get_route(NULL); @@ -1828,14 +2127,6 @@ diff -Nru asterisk-addons-1.4.6.org/channels/chan_mobile.c asterisk-addons-1.4.6 + return AST_MODULE_LOAD_DECLINE; + } + -+ hci_read_voice_setting(s, &vs, 1000); -+ vs = htobs(vs); -+ if (vs != 0x0060) { -+ ast_log(LOG_ERROR, "Bluetooth voice setting must be 0x0060 - see hciconfig hci0 voice.\n"); -+ hci_close_dev(s); -+ return AST_MODULE_LOAD_DECLINE; -+ } -+ + hci_close_dev(s); + + if (!mbl_load_config()) { @@ -1850,13 +2141,6 @@ diff -Nru asterisk-addons-1.4.6.org/channels/chan_mobile.c asterisk-addons-1.4.6 + ast_log(LOG_ERROR, "Unable to create discovery thread.\n"); + return AST_MODULE_LOAD_DECLINE; + } -+ /* Spin the sco listener thread */ -+ if (ast_pthread_create_background(&sco_listener_thread, NULL, do_sco_listen, NULL) < 0) { -+ ast_log(LOG_ERROR, "Unable to create sco listener thread.\n"); -+ pthread_cancel(discovery_thread); -+ pthread_join(discovery_thread, NULL); -+ return AST_MODULE_LOAD_DECLINE; -+ } + + ast_cli_register_multiple(mbl_cli, sizeof(mbl_cli) / sizeof(mbl_cli[0])); + ast_register_application(app_mblstatus, mbl_status_exec, mblstatus_synopsis, mblstatus_desc); @@ -1874,46 +2158,83 @@ diff -Nru asterisk-addons-1.4.6.org/channels/chan_mobile.c asterisk-addons-1.4.6 +AST_MODULE_INFO(ASTERISK_GPL_KEY, AST_MODFLAG_DEFAULT, "Bluetooth Mobile Device Channel Driver", + .load = load_module, + .unload = unload_module, -+ .reload = reload_module, +); -diff -Nru asterisk-addons-1.4.6.org/configs/mobile.conf.sample asterisk-addons-1.4.6/configs/mobile.conf.sample ---- asterisk-addons-1.4.6.org/configs/mobile.conf.sample 1970-01-01 01:00:00.000000000 +0100 -+++ asterisk-addons-1.4.6/configs/mobile.conf.sample 2008-03-06 08:38:14.000000000 +0100 -@@ -0,0 +1,30 @@ +diff -Nru asterisk-addons-1.4.7.org/configs/mobile.conf.sample asterisk-addons-1.4.7/configs/mobile.conf.sample +--- asterisk-addons-1.4.7.org/configs/mobile.conf.sample 1970-01-01 01:00:00.000000000 +0100 ++++ asterisk-addons-1.4.7/configs/mobile.conf.sample 2009-02-01 08:46:24.000000000 +0100 +@@ -0,0 +1,68 @@ +; +; mobile.conf ++; configuration file for chan_mobile +; + +[general] -+interval=60 ; Number of seconds between trying to connect to devices. ++interval=30 ; Number of seconds between trying to connect to devices. ++ ++; The following is a list of adapters we use. ++; id must be unique and address is the bdaddr of the adapter from hciconfig. ++; Each adapter may only have one device (headset or phone) connected at a time. ++; Add an [adapter] entry for each adapter you have. ++ ++[adapter] ++id=blue ++address=00:09:DD:60:01:A3 ++;forcemaster=yes ; attempt to force adapter into master mode. default is no. ++;alignmentdetection=yes ; enable this if you sometimes get 'white noise' on asterisk side of the call ++ ; its a bug in the bluetooth adapter firmware, enabling this will compensate for it. ++ ; default is no. ++ ++[adapter] ++id=dlink ++address=00:80:C8:35:52:78 + +; The following is a list of the devices we deal with. +; Every device listed below will be available for calls in and out of Asterisk. -+; Discovered devices not in this list are not available. ++; Each device needs an adapter=xxxx entry which determines which bluetooth adapter is used. +; Use the CLI command 'mobile search' to discover devices. +; Use the CLI command 'mobile show devices' to see device status. +; -+; To place out through a cell phone use Dial(Mobile/[device]/NNN.....) in your dialplan. ++; To place a call out through a mobile phone use Dial(Mobile/[device]/NNN.....) or Dial(Mobile/gn/NNN......) in your dialplan. +; To call a headset use Dial(Mobile/[device]). + -+;[dave] -+;address=00:12:56:90:6E:00 -+;port=4 -+;context=incoming-mobile -+ -+;[blackberry] -+;address=00:0F:86:0E:AE:42 -+;port=2 -+;context=incoming-mobile -+ -+;[headset] -+;address=00:0B:9E:11:74:A5 -+;port=1 -+;type=headset -diff -Nru asterisk-addons-1.4.6.org/configure.ac asterisk-addons-1.4.6/configure.ac ---- asterisk-addons-1.4.6.org/configure.ac 2008-02-13 23:58:11.000000000 +0100 -+++ asterisk-addons-1.4.6/configure.ac 2008-03-06 08:38:14.000000000 +0100 -@@ -161,13 +161,14 @@ ++[LGTU550] ++address=00:E0:91:7F:46:44 ; the address of the phone ++port=4 ; the rfcomm port number (from mobile search) ++context=incoming-mobile ; dialplan context for incoming calls ++adapter=dlink ; adapter to use ++group=1 ; this phone is in channel group 1 ++;nocallsetup=yes ; set this only if your phone reports that it supports call progress notification, but does not do it. Motorola L6 for example. ++ ++[blackberry] ++address=00:60:57:32:7E:B2 ++port=2 ++context=incoming-mobile ++adapter=dlink ++group=1 ++;blackberry=yes ; set this if you are using a blackberry device ++ ++[6310i] ++address=00:60:57:32:7E:B1 ++port=13 ++context=incoming-mobile ++adapter=dlink ++group=1 ; this phone is in channel group 1 also. ++ ++[headset] ++address=00:0B:9E:11:AE:C6 ++port=1 ++type=headset ; This is a headset, not a Phone ! ++adapter=blue ++ ++[headset1] ++address=00:0B:9E:11:74:A5 ++port=1 ++type=headset ++adapter=dlink +diff -Nru asterisk-addons-1.4.7.org/configure.ac asterisk-addons-1.4.7/configure.ac +--- asterisk-addons-1.4.7.org/configure.ac 2008-02-13 23:58:11.000000000 +0100 ++++ asterisk-addons-1.4.7/configure.ac 2009-02-01 08:48:08.000000000 +0100 +@@ -161,11 +161,13 @@ # from here on down, library checking should be done in alphabetical order # by the --with option name, to make things easier for the users :-) @@ -1925,291 +2246,11 @@ diff -Nru asterisk-addons-1.4.6.org/configure.ac asterisk-addons-1.4.6/configure +AST_EXT_LIB_CHECK([BLUETOOTH], [bluetooth], [ba2str], [bluetooth/bluetooth.h]) AST_EXT_LIB_CHECK([CURSES], [curses], [initscr], [curses.h]) -- - AST_EXT_LIB_CHECK([NCURSES], [ncurses], [initscr], [curses.h]) - - MYSQL_CONFIG=No -diff -Nru asterisk-addons-1.4.6.org/doc/chan_mobile.txt asterisk-addons-1.4.6/doc/chan_mobile.txt ---- asterisk-addons-1.4.6.org/doc/chan_mobile.txt 1970-01-01 01:00:00.000000000 +0100 -+++ asterisk-addons-1.4.6/doc/chan_mobile.txt 2008-03-06 08:38:14.000000000 +0100 -@@ -0,0 +1,262 @@ -+chan_mobile -+ -+Asterisk Channel Driver to allow Bluetooth Cell/Mobile Phones to be used as FXO devices, and Headsets as FXS devices. -+ -+Features :- -+ -+Multiple cell phones can be connected. -+Multiple headsets can be connected. -+Asterisk automatically connects to each configured cell phone / headset when it comes in range. -+CLI command to discover bluetooth devices. -+Inbound calls on the cell network to the cell phones are handled by Asterisk, just like inbound calls on a Zap channel. -+CLI passed through on inbound calls. -+Dial outbound on a cell phone using Dial(Mobile/device/nnnnnnn) in the dialplan. -+Dial a headset using Dial(Mobile/device) in the dialplan. -+Application MobileStatus can be used in the dialplan to see if a cell phone / headset is connected. -+Supports devicestate for dialplan hinting. -+Supports Inbound and Outbound SMS. -+ -+Using chan_mobile :- -+ -+In order to use chan_mobile, you must have a working bluetooth subsystem on your Asterisk box. -+This means a working bluetooth adapter, and the BlueZ packages. -+ -+Any bluetooth adapter supported by the Linux kernel will do, including usb bluetooth dongles. -+ -+The BlueZ package you need is bluez-utils. If you are using a GUI then you might want to install bluez-pin also. -+You also need libbluetooth, and libbluetooth-dev if you are compiling Asterisk from source. -+ -+You need to get bluetooth working with your phone before attempting to use chan_mobile. -+This means 'pairing' your phone with your Asterisk box. I dont describe how to do this here as the process -+differs from distro to distro. You only need to pair once. -+ -+However, the easist way to pair, is to use you cell phone to search for bluetooth devices, select your Asterisk box -+and enter the requested PIN. -+ -+See www.bluez.org for other details about setting up Bluetooth under Linux. -+ -+Assuming you have bluetooth working ok:- -+ -+Load chan_mobile.so -+ -+Search for your bluetooth devices using the CLI command 'mobile search'. Be patient with this command as -+it will take 8 - 10 seconds to do the discovery. -+ -+Headsets will generally have to be put into 'pairing' mode before they will show up here. -+ -+This will return something like the following :- -+ -+*CLI> mobile search -+Address Name Usable Type Port -+00:12:56:90:6E:00 LG TU500 Yes Phone 4 -+00:80:C8:35:52:78 Toaster No Headset 0 -+00:0B:9E:11:74:A5 Hello II Plus Yes Headset 1 -+00:0F:86:0E:AE:42 Daves Blackberry Yes Phone 7 -+ -+This is a list of all bluetooth devices seen and whether or not they are usable with chan_cellphone. -+The Address field contains the 'bd address' of the device. This is like an ethernet mac address. -+The Name field is whatever is configured into the device as its name. -+The Usable field tells you whether or not the device supports the Bluetooth Handsfree Profile or Headset profile. -+The Type field tells you whether the device is usable as a Phone line (FXO) or a headset (FXS) -+The Port field is the number to put in the configuration file. -+ -+Choose which device(s) you want to use and edit /etc/asterisk/mobile.conf. There is a sample included -+with the Asterisk source under configs/mobile.conf.sample. -+ -+Assuming we want to use the devices above, mobile.conf needs to look like this :- -+ -+=================================================================================== -+; -+; mobile.conf -+; -+ -+[general] -+interval=60 ; Number of seconds between trying to connect to devices. -+ -+; The following is a list of the devices we deal with. -+; Every device listed below will be available for calls in and out of Asterisk. -+; Discovered devices not in this list are not available. -+; Use the CLI command 'mobile search' to discover devices. -+; Use the CLI command 'mobile show devices' to see device status. -+; -+; To place a call use Dial(Mobile/[device]/NNN.....) in your dialplan. -+ -+[dave] -+address=00:12:56:90:6E:00 -+port=4 -+context=incoming-mobile -+ -+[headset] -+address=00:0B:9E:11:74:A5 -+port=1 -+type=headset -+=================================================================================== -+ -+Be sure to configure the right bd address and port number from the search. If you want inbound -+calls on a device to go to a specific context, add a context= line, otherwise the default will -+be used. The 'id' of the device [bitinbrackets] can be anything you like, just make the unique. -+ -+If your are configuring a Headset be sure to include the type=headset line, if left out it defaults -+to phone. -+ -+Having done this, unload chan_mobile and load it again. -+ -+The CLI command 'mobile show devices' can be used at any time to show the status of configured devices, -+and whether or not the device is capable of sending / receiving SMS via bluetooth. -+ -+*CLI> mobile show devices -+ID Address Connected State SMS -+blackberry 00:0F:86:0E:AE:42 Yes Free Yes -+dave 00:12:56:90:6E:00 Yes Free No -+headset 00:0B:9E:11:74:A5 Yes Free No -+*CLI> -+ -+ -+All being well Asterisk will now try and establish a connection to each configured device. If it cant -+it will retry after 'interval' seconds, infinately. -+ -+This means that as your cell phone comes into range and goes out of range, Asterisk will automatically -+connect and disconnect from it. You dont need to worry about it. -+ -+As each phone is connected you will see a message on the Asterisk console :- -+ -+ Loaded chan_mobile.so => (Bluetooth Mobile Device Channel Driver) -+ -- Bluetooth Device blackberry has connected. -+ -- Bluetooth Device dave has connected. -+ -+If someone calls your cell phone now, Asterisk will handle the call and it will be sent into the -+context you specified, or the default context. Mostly likely this means some SIP phone somewhere will -+ring, pick it up and take the call. -+ -+To make outbound calls, add something to you Dialplan like the following :- (modify to suit) -+ -+; Calls via TU500 -+exten => _9X.,1,Dial(Mobile/dave/${EXTEN:1},45) -+exten => _9X.,n,Hangup -+; Calls via Blackberry -+exten => _8X.,1,Dial(Mobile/blackberry/${EXTEN:1},45) -+exten => _8X.,n,Hangup -+ -+Pick up a SIP phone and dial 9 and the call vill go via the device 'dave' in -+mobile.conf. -+ -+To incoming calls to a headset do something like this :- -+ -+[incoming-context] -+exten => s,1,Dial(Mobile/headset,30) -+exten => s,n,Hangup() -+ -+To dial out on a headset, you need to use some other mechanism, because the headset is not likely -+to have all the needed buttons on it. res_clioriginate is good for this :- -+ -+*CLI> originate Mobile/headset extension NNNNN@context -+ -+This will call your headset, once you answer Asterisk will call NNNNN at context context -+ -+Dialplan hints :- -+ -+chan_mobile supports 'device status' so you can do somthing like -+ -+exten => 1234,hint,SIP/30&Mobile/dave&Mobile/blackberry -+ -+ -+MobileStatus Application :- -+ -+chan_mobile also registers an application named MobileStatus. You can use this in your Dialplan -+to determine the 'state' of a device. -+ -+For example, suppose you wanted to call dave's extension, but only if he was in the office. You could -+test to see if his cell phone was attached to Asterisk, if it is dial his extension, otherwise dial his -+cell phone. -+ -+exten => 40,1,MobileStatus(dave,DAVECELL) -+exten => 40,2,GotoIf($["${DAVECELL}" = "1"]?3:5) -+exten => 40,3,Dial(ZAP/g1/0427466412,45,tT) -+exten => 40,4,Hangup -+exten => 40,5,Dial(SIP/40,45,tT) -+exten => 40,6,Hangup -+ -+MobileStatus sets the value of the given variable to :- -+ -+1 = Disconnected. i.e. Device not in range of Asterisk, or turned off etc etc -+2 = Connected and Not on a call. i.e. Free -+3 = Connected and on a call. i.e. Busy -+ -+ -+SMS Sending / Receiving -+ -+If Asterisk has detected your cell phone is capable of SMS via bluetooth, you will be able to send and -+receive SMS. -+ -+Incoming SMS's cause Asterisk to create an inbound call to the context you defined in mobile.conf or the default -+context if you did not define one. The call will start at extension 'sms'. Two channel variables will be available, -+SMSSRC = the number of the originator of the SMS and SMSTXT which is the text of the SMS. -+This is not a voice call, so grab the values of the variables and hang the call up. -+ -+So, to handle incoming SMS's, do something like the following in your dialplan -+ -+[incoming-mobile] -+exten => sms,1,Verbose(Incoming SMS from ${SMSSRC} ${SMSTXT}) -+exten => sms,n,Hangup() -+ -+The above will just print the message on the console. -+ -+If you use res_jabber, you could do something like this :- -+ -+[incoming-mobile] -+exten => sms,1,JabberSend(transport,user@jabber.somewhere.com,SMS from ${SMSRC} ${SMSTXT}) -+exten => sms,2,Hangup() -+ -+To send an SMS, use the application MobileSendSMS like the following :- -+ -+exten => 99,1,MobileSendSMS(dave,0427123456,Hello World) -+ -+This will send 'Hello World' via device 'dave' to '0427123456' -+ -+ -+DTMF Debouncing :- -+ -+DTMF detection varies from phone to phone. There is a configuration variable that allows you to tune -+this to your needs. e.g. in mobile.conf -+ -+[dave] -+address=00:12:56:90:6E:00 -+port=4 -+context=incoming-mobile -+dtmfskip=50 -+ -+change dtmfskip to suit your phone. The default is 200. The larger the number, the more chance of missed DTMF. -+The smaller the number the more chance of multiple digits being detected. -+ -+ -+Debugging :- -+ -+Different phone manufacturers have different interpretations of the Bluetooth Handsfree Profile Spec. -+This means that not all phones work the same way, particularly in the connection setup / initialisation -+sequence. I've tried to make chan_cellphone as general as possible, but it may need modification to -+support some phone i've never tested. -+ -+The RIM Blackberry 7250 works extremely well. So does the LG TU500. -+ -+Some phones, most notably Sony Ericsson 'T' series, dont quite conform to the Bluetooth HFP spec. -+chan_mobile will detect these and adapt accordingly. The T-610 and T-630 have been tested and -+work fine. -+ -+If your phone doesnt behave has expected, turn on Asterisk debugging with 'core set debug 1'. -+ -+This will log a bunch of debug messages indicating what the phone is doing, importantly the rfcomm -+conversation between Asterisk and the phone. This can be used to sort out what your phone is doing -+and make chan_mobile support it. -+ -+Be aware also, that just about all cell phones behave differently. For example my LG TU500 wont dial unless -+the phone is a the 'idle' screen. i.e. if the phone is showing a 'menu' on the display, when you dial via -+Asterisk, the call will not work. chan_mobile handles this, but there may be other phones that do -+other things too... -+ -+Important: Watch what your cell phone is doing the first few times. Asterisk wont make random calls but -+if chan_mobile fails to hangup for some reason and you get a huge bill from your telco, dont blame me. -+ -+ -+Feedback, Support, Please can you make Cell Phone X work... etc :- -+ -+email me at david.bowerman at gmail.com or dseeb_ on #asterisk & #asterisk-dev irc. -diff -Nru asterisk-addons-1.4.6.org/Makefile asterisk-addons-1.4.6/Makefile ---- asterisk-addons-1.4.6.org/Makefile 2008-02-13 23:58:11.000000000 +0100 -+++ asterisk-addons-1.4.6/Makefile 2008-03-06 08:38:14.000000000 +0100 -@@ -215,6 +215,8 @@ - - gmenuconfig: gmenuselect -+menuconfig: menuselect -+ - menuselect: menuselect/menuselect menuselect-tree - -@menuselect/menuselect $(GLOBAL_MAKEOPTS) $(USER_MAKEOPTS) menuselect.makeopts && echo "menuselect changes saved!" || echo "menuselect changes NOT saved!" - -diff -Nru asterisk-addons-1.4.6.org/makeopts.in asterisk-addons-1.4.6/makeopts.in ---- asterisk-addons-1.4.6.org/makeopts.in 2008-02-13 23:58:11.000000000 +0100 -+++ asterisk-addons-1.4.6/makeopts.in 2008-03-06 08:38:14.000000000 +0100 + AST_EXT_LIB_CHECK([NCURSES], [ncurses], [initscr], [curses.h]) +diff -Nru asterisk-addons-1.4.7.org/makeopts.in asterisk-addons-1.4.7/makeopts.in +--- asterisk-addons-1.4.7.org/makeopts.in 2008-02-13 23:58:11.000000000 +0100 ++++ asterisk-addons-1.4.7/makeopts.in 2009-02-01 08:49:46.000000000 +0100 @@ -34,6 +34,9 @@ sharedstatedir = @sharedstatedir@ sysconfdir = @sysconfdir@ diff --git a/net/hiawatha/Makefile b/net/hiawatha/Makefile new file mode 100644 index 000000000..5a0556ab9 --- /dev/null +++ b/net/hiawatha/Makefile @@ -0,0 +1,55 @@ +# +# Copyright (C) 2009 OpenWrt.org +# +# This is free software, licensed under the GNU General Public License v2. +# See /LICENSE for more information. +# +# $Id$ + +include $(TOPDIR)/rules.mk + +PKG_NAME:=hiawatha +PKG_VERSION:=6.10 +PKG_RELEASE:=1 + +PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz +PKG_SOURCE_URL:=http://www.hiawatha-webserver.org/files/ +PKG_MD5SUM:=78d364b586a766a428b94b4461d4aa04 + +include $(INCLUDE_DIR)/package.mk + +define Package/hiawatha + CATEGORY:=Network + SECTION:=net + SUBMENU:=Web + TITLE:=A very lightweight web server + URL:=http://www.hiawatha-webserver.org/ + DEPENDS:=+libpthread +endef + +define Package/hiawatha/description + Hiawatha is a webserver for Unix. +endef + +CONFIGURE_ARGS+= \ + --disable-cache \ + --disable-ssl \ + --disable-ipv6 + +CONFIGURE_VARS+= \ + ac_cv_file__dev_urandom=yes + +define Package/hiawatha/conffiles +/etc/hiawatha/httpd.conf +/etc/hiawatha/mimetype.conf +endef + +define Package/hiawatha/install + $(INSTALL_DIR) $(1)/usr/sbin + $(INSTALL_BIN) $(PKG_BUILD_DIR)/hiawatha $(1)/usr/sbin/ + $(INSTALL_DIR) $(1)/etc/hiawatha + $(INSTALL_DATA) ./files/httpd.conf $(1)/etc/hiawatha/ + $(INSTALL_DATA) ./files/mimetype.conf $(1)/etc/hiawatha/ +endef + +$(eval $(call BuildPackage,hiawatha)) diff --git a/net/hiawatha/files/httpd.conf b/net/hiawatha/files/httpd.conf new file mode 100644 index 000000000..b6d02d351 --- /dev/null +++ b/net/hiawatha/files/httpd.conf @@ -0,0 +1,115 @@ +# Hiawatha main configuration file +# + + +# GENERAL SETTINGS +# +#ServerId = www-data +ConnectionsTotal = 150 +ConnectionsPerIP = 10 +SystemLogfile = /var/log/hiawatha/system.log +GarbageLogfile = /var/log/hiawatha/garbage.log + + +# BINDING SETTINGS +# A binding is where a client can connect to. +# +Binding { + Port = 80 +# Interface = 127.0.0.1 +# MaxKeepAlive = 30 +# TimeForRequest = 3,20 +} +# +#Binding { +# Port = 443 +# Interface = ::1 +# MaxKeepAlive = 30 +# TimeForRequest = 3,20 +# ServerKey = hiawatha.pem +# UseSSL = yes +#} + + +# BANNING SETTINGS +# Deny service to clients who misbehave. +# +#BanOnGarbage = 300 +#BanOnMaxPerIP = 60 +#BanOnMaxReqSize = 300 +#KickOnBan = yes +#RebanDuringBan = yes + + +# COMMON GATEWAY INTERFACE (CGI) SETTINGS +# These settings can be used to run CGI applications. Use the 'php-fcgi' +# tool to start PHP as a FastCGI daemon. +# +#CGIhandler = /usr/bin/php-cgi:php +#CGIhandler = /usr/bin/perl:pl +#CGIhandler = /usr/bin/python:py +#CGIextension = cgi +# +#FastCGIserver { +# FastCGIid = PHP4 +# ConnectTo = 127.0.0.1:2004 +# Extension = php, php4 +#} +# +#FastCGIserver { +# FastCGIid = PHP5 +# ConnectTo = 10.0.0.100:2005, 10.0.0.101:2005 +# Extension = php, php5 +# SessionTimeout = 30 +#} + + +# URL TOOLKIT +# These URL toolkit rules are made for the Skeleton PHP framework, +# which can be downloaded from: http://skeleton.leisink.org/ +# +#UrlToolkit { +# ToolkitID = skeleton +# Match ^/$ Return +# RequestURI isfile Exit +# Match (.*)\?(.*) Rewrite $1&$2 +# Match /(.*) Rewrite /index.php?page=$1 +#} + + +# DEFAULT WEBSITE +# It is wise to use your IP address as the hostname of the default website +# and give it a blank webpage. By doing so, automated webscanners won't find +# your possible vulnerable website. +# +Hostname = 127.0.0.1 +WebsiteRoot = /www/ +StartFile = index.html +AccessLogfile = /var/log/hiawatha/access.log +ErrorLogfile = /var/log/hiawatha/error.log +#ErrorHandler = 404:/error.cgi + + +# VIRTUAL HOSTS +# Use a VirtualHost section to declare the websites you want to host. +# +#VirtualHost { +# Hostname = www.my-domain.com +# WebsiteRoot = /var/www/my-domain/public +# StartFile = index.php +# AccessLogfile = /var/www/my-domain/log/access.log +# ErrorLogfile = /var/www/my-domain/log/error.log +# ExecuteCGI = yes +# FastCGI = PHP4 +# TimeForCGI = 5 +#} + + +# DIRECTORY SETTINGS +# You can specify some settings per directory. +# +#Directory { +# Path = /home/baduser +# ExecuteCGI = no +# UploadSpeed = 10,2 +#} diff --git a/net/hiawatha/files/mimetype.conf b/net/hiawatha/files/mimetype.conf new file mode 100644 index 000000000..7e876c796 --- /dev/null +++ b/net/hiawatha/files/mimetype.conf @@ -0,0 +1,16 @@ +application/pdf pdf +application/octet-stream class +application/x-ns-proxy-autoconfig pac +application/x-shockwave-flash swf +audio/x-wav wav +image/gif gif +image/jpeg jpg +image/jpeg jpeg +image/png png +text/css css +text/html html +text/html htm +text/javascript js +text/plain txt +text/xml dtd +text/xml xml diff --git a/net/hiawatha/patches/100-add_x_requested_http_headers.patch b/net/hiawatha/patches/100-add_x_requested_http_headers.patch new file mode 100644 index 000000000..630db8b3d --- /dev/null +++ b/net/hiawatha/patches/100-add_x_requested_http_headers.patch @@ -0,0 +1,11 @@ +--- a/envir.c ++++ b/envir.c +@@ -189,6 +189,8 @@ void set_environment(t_session *session, + headerfield_to_environment(session, fcgi_buffer, "User-Agent:", "HTTP_USER_AGENT"); + headerfield_to_environment(session, fcgi_buffer, "Via:", "HTTP_VIA"); + headerfield_to_environment(session, fcgi_buffer, "X-Forwarded-For:", "HTTP_X_FORWARDED_FOR"); ++ headerfield_to_environment(session, fcgi_buffer, "X-Requested-With:", "HTTP_X_REQUESTED_WITH"); ++ headerfield_to_environment(session, fcgi_buffer, "X-Requested-Handler:", "HTTP_X_REQUESTED_HANDLER"); + + if (session->path_info != NULL) { + add_to_environment(fcgi_buffer, "PATH_INFO", session->path_info); diff --git a/net/stun/Makefile b/net/stun/Makefile index d30d6fe3a..86f94bbfe 100644 --- a/net/stun/Makefile +++ b/net/stun/Makefile @@ -60,7 +60,7 @@ define Build/Compile CXXFLAGS="$$$$CXXFLAGS -fno-builtin -fno-rtti -nostdinc++" \ CPPFLAGS="$$$$CPPFLAGS -I$(STAGING_DIR)/usr/include/uClibc++ -I$(STAGING_DIR)/usr/include -I$(STAGING_DIR)/include" \ LDFLAGS="$$$$LDFLAGS -L$(STAGING_DIR)/usr/lib -L$(STAGING_DIR)/lib -L$(TOOLCHAIN_DIR)/usr/lib \ - -nodefaultlibs -luClibc++ -lgcc" \ + -nodefaultlibs -luClibc++ $(LIBGCC_S)" \ all endef diff --git a/net/stun/patches/002-linking_order.patch b/net/stun/patches/002-linking_order.patch new file mode 100644 index 000000000..c9a23f167 --- /dev/null +++ b/net/stun/patches/002-linking_order.patch @@ -0,0 +1,19 @@ +--- a/Makefile ++++ b/Makefile +@@ -37,13 +37,13 @@ + $(addprefix stund/, $(TARS)) + + server: server.o stun.o udp.o +- $(CXX) $(LDFLAGS) -o $@ $^ ++ $(CXX) -o $@ $^ $(LDFLAGS) + + tlsServer: tlsServer.o stun.o udp.o +- $(CXX) $(LDFLAGS) -o $@ $^ ++ $(CXX) -o $@ $^ $(LDFLAGS) + + client: client.o stun.o udp.o +- $(CXX) $(LDFLAGS) -o $@ $^ ++ $(CXX) -o $@ $^ $(LDFLAGS) + + %.o:%.cxx + $(CXX) -c $(CPPFLAGS) $(CXXFLAGS) $< -o $@ diff --git a/utils/dt/Makefile b/utils/dt/Makefile new file mode 100644 index 000000000..821d85911 --- /dev/null +++ b/utils/dt/Makefile @@ -0,0 +1,53 @@ +# +# Copyright (C) 2009 OpenWrt.org +# +# This is free software, licensed under the GNU General Public License v2. +# See /LICENSE for more information. +# +# $Id$ + +include $(TOPDIR)/rules.mk + +PKG_NAME:=dt +PKG_VERSION:=15.14 +PKG_RELEASE:=1 + +PKG_SOURCE:=$(PKG_NAME)-source.tar.gz +PKG_SOURCE_URL:=http://home.comcast.net/~SCSIguy/SCSI_FAQ/RMiller_Tools/ftp/$(PKG_NAME)/ +PKG_MD5SUM:=5776233a2d301a50b314306538257a45 + +PKG_UNPACK= \ + zcat $(DL_DIR)/$(PKG_SOURCE) | \ + $(TAR) -C $(PKG_BUILD_DIR) --strip-components 2 $(TAR_OPTIONS); + +include $(INCLUDE_DIR)/package.mk + +define Package/dt + CATEGORY:=Utilities + SECTION:=utils + TITLE:=A generic data test program + URL:=http://www.scsifaq.org/RMiller_Tools/index.html + DEPENDS:=+libpthread +endef + +define Package/dt/description + dt is a generic data test program used to verify proper operation of peripherals, + file systems, device drivers, or any data stream supported by the operating system. + In its' simplest mode of operation, dt writes and then verifys its' default data pattern, + then displays performance statisics and other test parameters before exiting. + Since verification of data is performed, dt can be thought of as a generic diagnostic tool. +endef + +define Build/Compile + $(MAKE) -C $(PKG_BUILD_DIR) -f Makefile.linux \ + CC="$(TARGET_CC)" \ + CFLAGS="$(TARGET_CFLAGS) -DFIFO -DMMAP -DTTY -D__linux__ -D_GNU_SOURCE -D_FILE_OFFSET_BITS=64" \ + dt +endef + +define Package/dt/install + $(INSTALL_DIR) $(1)/usr/bin + $(INSTALL_BIN) $(PKG_BUILD_DIR)/dt $(1)/usr/bin/ +endef + +$(eval $(call BuildPackage,dt)) -- 2.30.2