From bb0dc52ad9a45908f8cc70c636d51519eac1a25b Mon Sep 17 00:00:00 2001 From: sthen Date: Fri, 28 Sep 2012 00:03:57 +0000 Subject: [PATCH] Update the asterisk port to 10.8.0 - This is a major update, notable changes: - If using ConfBridge, note that the dialplan arguments have changed. - If using the built-in HTTP server, note that a bindaddr must now be given, previously the default was 0.0.0.0 but this must now be given explicitly. - Internal database now uses SQLite3 not BDB, conversion tools are provided. See share/doc/asterisk/UPGRADE.txt for more. --- telephony/asterisk/Makefile | 10 +- telephony/asterisk/distinfo | 4 +- telephony/asterisk/patches/patch-Makefile | 12 +- .../patches/patch-addons_chan_ooh323_c | 14 - .../patches/patch-channels_chan_unistim_c | 4370 ----------------- .../patch-configs_asterisk_conf_sample | 10 +- .../patch-configs_res_odbc_conf_sample | 13 + .../patches/patch-configs_sip_conf_sample | 18 + telephony/asterisk/patches/patch-configure_ac | 12 +- .../patch-contrib_scripts_safe_asterisk | 38 +- .../asterisk/patches/patch-pbx_pbx_spool_c | 8 +- telephony/asterisk/pkg/PLIST-main | 21 +- telephony/asterisk/pkg/README-main | 11 +- 13 files changed, 103 insertions(+), 4438 deletions(-) delete mode 100644 telephony/asterisk/patches/patch-addons_chan_ooh323_c delete mode 100644 telephony/asterisk/patches/patch-channels_chan_unistim_c create mode 100644 telephony/asterisk/patches/patch-configs_res_odbc_conf_sample create mode 100644 telephony/asterisk/patches/patch-configs_sip_conf_sample diff --git a/telephony/asterisk/Makefile b/telephony/asterisk/Makefile index 382a494f5ea..d19599b6b1a 100644 --- a/telephony/asterisk/Makefile +++ b/telephony/asterisk/Makefile @@ -1,10 +1,9 @@ -# $OpenBSD: Makefile,v 1.160 2012/09/25 21:58:46 sthen Exp $ +# $OpenBSD: Makefile,v 1.161 2012/09/28 00:03:57 sthen Exp $ SHARED_ONLY= Yes COMMENT-main= open source multi-protocol PBX and telephony toolkit -VER= 1.8.16.0 -REVISION-main= 0 +VER= 10.8.0 DISTNAME= asterisk-${VER:S/beta/-beta/:S/rc/-rc/} PKGNAME-main= asterisk-${VER} @@ -77,11 +76,14 @@ MAKE_FLAGS+= ASTCFLAGS="${CFLAGS}" \ NOISY_BUILD="Yes" \ OPTIMIZE= +CONFIGURE_ARGS+= --localstatedir=/var + CONFIGURE_ARGS+= --with-asound=no \ --with-avcodec=no \ --with-cap=no \ --with-dahdi=no \ --with-gtk2=no \ + --with-h323=no \ --with-isdnnet=no \ --with-misdn=no \ --with-nbs=no \ @@ -89,6 +91,7 @@ CONFIGURE_ARGS+= --with-asound=no \ --with-osptk=no \ --with-oss=no \ --with-pri=no \ + --with-pwlib=no \ --with-SDL_image=no \ --with-sdl=no \ --with-sqlite=no \ @@ -101,7 +104,6 @@ CONFIGURE_ARGS+= --with-asound=no \ CONFIGURE_ARGS+= --with-jack=no \ --with-lua=no \ --with-portaudio=no \ - --with-pwlib=no \ --with-radius=no \ --with-resample=no \ --with-tds=no diff --git a/telephony/asterisk/distinfo b/telephony/asterisk/distinfo index 978ba5d69ab..c8f12bf8eae 100644 --- a/telephony/asterisk/distinfo +++ b/telephony/asterisk/distinfo @@ -1,11 +1,11 @@ -SHA256 (asterisk-1.8.16.0.tar.gz) = xFqJWbBr14nSfmFrz75QTUjj8tN5k8RbPIvJyzYk0tw= +SHA256 (asterisk-10.8.0.tar.gz) = FKqzPnKcGFFGU7LrwvspXeYMoMRnmJ5bQWzRXgx9R+o= SHA256 (asterisk-core-sounds-en-gsm-1.4.22.tar.gz) = eRdRl6ZRwlu2KYjnIQI+m7cRx+7yisouy6KR1D7j5mc= SHA256 (asterisk-core-sounds-en-gsm-1.4.22.tar.gz.sha1) = ye/FmyBQU27CFiXULLsvWqivxjKK8NIIvq0rWJ8rRzI= SHA256 (asterisk-extra-sounds-en-gsm-1.4.11.tar.gz) = 1fAxzDHr6+yZzj/PRP+Ue9eye16VZaezphhcLRvaCUw= SHA256 (asterisk-extra-sounds-en-gsm-1.4.11.tar.gz.sha1) = a0BErk9wQ3/hT5gPUVL6uk6iqitdhAKMAhOrL2XHSR8= SHA256 (asterisk-moh-opsound-wav-2.03.tar.gz) = RJ+4ENFlAsMFL+3wL353s2IGrFoUXz2s9Bd4Q6L8tTg= SHA256 (asterisk-moh-opsound-wav-2.03.tar.gz.sha1) = Y8VUFsoRQmGrGvT9EVIyLy7GnZGrw0vEzufTKByuDZc= -SIZE (asterisk-1.8.16.0.tar.gz) = 25085895 +SIZE (asterisk-10.8.0.tar.gz) = 25007513 SIZE (asterisk-core-sounds-en-gsm-1.4.22.tar.gz) = 2042362 SIZE (asterisk-core-sounds-en-gsm-1.4.22.tar.gz.sha1) = 84 SIZE (asterisk-extra-sounds-en-gsm-1.4.11.tar.gz) = 3349898 diff --git a/telephony/asterisk/patches/patch-Makefile b/telephony/asterisk/patches/patch-Makefile index 1e706c777e0..fbadb297414 100644 --- a/telephony/asterisk/patches/patch-Makefile +++ b/telephony/asterisk/patches/patch-Makefile @@ -1,7 +1,7 @@ -$OpenBSD: patch-Makefile,v 1.32 2012/06/07 10:39:25 sthen Exp $ ---- Makefile.orig Thu Apr 12 15:26:06 2012 -+++ Makefile Wed Jun 6 21:57:09 2012 -@@ -121,7 +121,7 @@ ASTTOPDIR:=$(subst $(space),\$(space),$(CURDIR)) +$OpenBSD: patch-Makefile,v 1.33 2012/09/28 00:03:57 sthen Exp $ +--- Makefile.orig Wed Jun 13 15:30:34 2012 ++++ Makefile Tue Sep 18 23:47:38 2012 +@@ -123,7 +123,7 @@ ASTTOPDIR:=$(subst $(space),\$(space),$(CURDIR)) OVERWRITE=y # Include debug and macro symbols in the executables (-g) and profiling info (-pg) @@ -10,7 +10,7 @@ $OpenBSD: patch-Makefile,v 1.32 2012/06/07 10:39:25 sthen Exp $ # Asterisk.conf is located in ASTETCDIR or by using the -C flag # when starting Asterisk -@@ -151,8 +151,10 @@ LINKER_SYMBOL_PREFIX= +@@ -153,8 +153,10 @@ LINKER_SYMBOL_PREFIX= # The file /etc/asterisk.makeopts will also be included but can be overridden # by the file in your home directory. @@ -21,7 +21,7 @@ $OpenBSD: patch-Makefile,v 1.32 2012/06/07 10:39:25 sthen Exp $ MOD_SUBDIR_CFLAGS="-I$(ASTTOPDIR)/include" OTHER_SUBDIR_CFLAGS="-I$(ASTTOPDIR)/include" -@@ -162,7 +164,9 @@ OPTIONS= +@@ -164,7 +166,9 @@ OPTIONS= ifeq ($(findstring -save-temps,$(_ASTCFLAGS) $(ASTCFLAGS)),) ifeq ($(findstring -pipe,$(_ASTCFLAGS) $(ASTCFLAGS)),) diff --git a/telephony/asterisk/patches/patch-addons_chan_ooh323_c b/telephony/asterisk/patches/patch-addons_chan_ooh323_c deleted file mode 100644 index f46a9420b3e..00000000000 --- a/telephony/asterisk/patches/patch-addons_chan_ooh323_c +++ /dev/null @@ -1,14 +0,0 @@ -$OpenBSD: patch-addons_chan_ooh323_c,v 1.4 2012/08/04 21:53:56 sthen Exp $ ---- addons/chan_ooh323.c.orig Wed Jun 20 10:15:22 2012 -+++ addons/chan_ooh323.c Mon Jul 30 23:13:44 2012 -@@ -2729,8 +2729,10 @@ int reload_config(int reload) - gTOS = IPTOS_THROUGHPUT; - else if (!strcasecmp(v->value, "reliability")) - gTOS = IPTOS_RELIABILITY; -+#ifdef IPTOS_MINCOST - else if (!strcasecmp(v->value, "mincost")) - gTOS = IPTOS_MINCOST; -+#endif - else if (!strcasecmp(v->value, "none")) - gTOS = 0; - else diff --git a/telephony/asterisk/patches/patch-channels_chan_unistim_c b/telephony/asterisk/patches/patch-channels_chan_unistim_c deleted file mode 100644 index 16dfc39c9fa..00000000000 --- a/telephony/asterisk/patches/patch-channels_chan_unistim_c +++ /dev/null @@ -1,4370 +0,0 @@ -$OpenBSD: patch-channels_chan_unistim_c,v 1.7 2012/03/23 22:42:25 sthen Exp $ - -Patch is from https://issues.asterisk.org/jira/browse/18229 -https://issues.asterisk.org/jira/secure/attachment/38296/chan_unistim.c.1.8.2.2-9.diff - ---- channels/chan_unistim.c.orig Fri Sep 9 17:09:09 2011 -+++ channels/chan_unistim.c Sat Dec 10 14:34:33 2011 -@@ -73,6 +73,8 @@ ASTERISK_FILE_VERSION(__FILE__, "$Revision: 1.7 $") - #include "asterisk/musiconhold.h" - #include "asterisk/causes.h" - #include "asterisk/indications.h" -+#include "asterisk/features.h" -+#include "asterisk/astobj2.h" - - /*! Beware, G729 and G723 are not supported by asterisk, except with the proper licence */ - #define CAPABILITY AST_FORMAT_ALAW | AST_FORMAT_ULAW /* | AST_FORMAT_G729A | AST_FORMAT_G723_1 */ -@@ -82,11 +84,14 @@ ASTERISK_FILE_VERSION(__FILE__, "$Revision: 1.7 $") - #define DEFAULTCALLERNAME " " - #define DEFAULTHEIGHT 3 - #define USTM_LOG_DIR "unistimHistory" -+#define USTM_LANG_DIR "unistimLang" - - /*! Size of the transmit buffer */ - #define MAX_BUF_SIZE 64 - /*! Number of slots for the transmit queue */ - #define MAX_BUF_NUMBER 50 -+/*! Number of digits displayed on screen */ -+#define MAX_SCREEN_NUMBER 15 - /*! Try x times before removing the phone */ - #define NB_MAX_RETRANSMIT 8 - /*! Nb of milliseconds waited when no events are scheduled */ -@@ -103,8 +108,9 @@ ASTERISK_FILE_VERSION(__FILE__, "$Revision: 1.7 $") - #define MAX_ENTRY_LOG 30 - - #define SUB_REAL 0 --#define SUB_THREEWAY 1 --#define MAX_SUBS 2 -+#define SUB_RING 1 -+#define SUB_THREEWAY 2 -+#define SUB_ONHOLD 3 - - enum autoprovision { - AUTOPROVISIONING_NO = 0, -@@ -185,6 +191,14 @@ enum autoprov_extn { - - #define FAV_MAX_LENGTH 0x0A - -+#define FAVNUM 6 -+#define FAV_LINE_ICON FAV_ICON_ONHOOK_BLACK -+ -+#define CALL_TIMER_START 0x01 -+#define CALL_TIMER_RESET 0x02 -+#define CALL_TIMER_DISPLAY 0x04 -+#define CALL_TIMER_DELAY 0x08 -+ - static void dummy(char *unused, ...) - { - return; -@@ -222,7 +236,7 @@ static struct { - } qos = { 0, 0, 0, 0 }; - - static struct io_context *io; --static struct sched_context *sched; -+static struct ast_sched_context *sched; - static struct sockaddr_in public_ip = { 0, }; - /*! give the IP address for the last packet received */ - static struct sockaddr_in address_from; -@@ -256,7 +270,10 @@ enum phone_state { - STATE_DIALPAGE, - STATE_RINGING, - STATE_CALL, -+ STATE_SELECTOPTION, - STATE_SELECTCODEC, -+ STATE_SELECTCONTRAST, -+ STATE_SELECTLANGUAGE, - STATE_CLEANING, - STATE_HISTORY - }; -@@ -307,45 +324,17 @@ enum phone_key { - KEY_INDEX = 0x7f - }; - --struct tone_zone_unistim { -- char country[3]; -- int freq1; -- int freq2; -+enum charset { -+ LANG_DEFAULT, -+ ISO_8859_1, -+ ISO_8859_2, -+ ISO_8859_4, -+ ISO_8859_5, -+ ISO_2022_JP, - }; - --static const struct tone_zone_unistim frequency[] = { -- {"us", 350, 440}, -- {"fr", 440, 0}, -- {"au", 413, 438}, -- {"nl", 425, 0}, -- {"uk", 350, 440}, -- {"fi", 425, 0}, -- {"es", 425, 0}, -- {"jp", 400, 0}, -- {"no", 425, 0}, -- {"at", 420, 0}, -- {"nz", 400, 0}, -- {"tw", 350, 440}, -- {"cl", 400, 0}, -- {"se", 425, 0}, -- {"be", 425, 0}, -- {"sg", 425, 0}, -- {"il", 414, 0}, -- {"br", 425, 0}, -- {"hu", 425, 0}, -- {"lt", 425, 0}, -- {"pl", 425, 0}, -- {"za", 400, 0}, -- {"pt", 425, 0}, -- {"ee", 425, 0}, -- {"mx", 425, 0}, -- {"in", 400, 0}, -- {"de", 425, 0}, -- {"ch", 425, 0}, -- {"dk", 425, 0}, -- {"cn", 450, 0}, -- {"--", 0, 0} --}; -+static const int dtmf_row[] = { 697, 770, 852, 941 }; -+static const float dtmf_col[] = { 1209, 1336, 1477, 1633 }; - - struct wsabuf { - u_long len; -@@ -365,7 +354,7 @@ struct systemtime { - - struct unistim_subchannel { - ast_mutex_t lock; -- /*! SUBS_REAL or SUBS_THREEWAY */ -+ /*! SUB_REAL, SUB_THREEWAY or SUB_ONHOLD */ - unsigned int subtype; - /*! Asterisk channel used by the subchannel */ - struct ast_channel *owner; -@@ -373,9 +362,14 @@ struct unistim_subchannel { - struct unistim_line *parent; - /*! RTP handle */ - struct ast_rtp_instance *rtp; -+ /*! Softkey assigned */ -+ int softkey; -+ time_t start_call_timestamp; /*!< timestamp for the length calculation of the call */ - int alreadygone; - char ringvolume; - char ringstyle; -+ int moh; /*!< Music on hold in progress */ -+ AST_LIST_ENTRY(unistim_subchannel) list; - }; - - /*! -@@ -387,14 +381,10 @@ struct unistim_line { - char name[80]; - /*! Like USTM/200\@black */ - char fullname[80]; -- /*! pointer to our current connection, channel... */ -- struct unistim_subchannel *subs[MAX_SUBS]; - /*! Extension where to start */ - char exten[AST_MAX_EXTENSION]; - /*! Context to start in */ - char context[AST_MAX_EXTENSION]; -- /*! Language for asterisk sounds */ -- char language[MAX_LANGUAGE]; - /*! CallerID Number */ - char cid_num[AST_MAX_EXTENSION]; - /*! Mailbox for MWI */ -@@ -419,6 +409,7 @@ struct unistim_line { - char parkinglot[AST_MAX_CONTEXT]; - struct unistim_line *next; - struct unistim_device *parent; -+ AST_LIST_ENTRY(unistim_line) list; - }; - - /*! -@@ -427,19 +418,21 @@ struct unistim_line { - static struct unistim_device { - int receiver_state; /*!< state of the receiver (see ReceiverState) */ - int size_phone_number; /*!< size of the phone number */ -- char phone_number[16]; /*!< the phone number entered by the user */ -- char redial_number[16]; /*!< the last phone number entered by the user */ -+ char phone_number[AST_MAX_EXTENSION]; /*!< the phone number entered by the user */ -+ char redial_number[AST_MAX_EXTENSION]; /*!< the last phone number entered by the user */ - int phone_current; /*!< Number of the current phone */ - int pos_fav; /*!< Position of the displayed favorites (used for scrolling) */ - char id[18]; /*!< mac address of the current phone in ascii */ - char name[DEVICE_NAME_LEN]; /*!< name of the device */ -- int softkeylinepos; /*!< position of the line softkey (default 0) */ -- char softkeylabel[6][11]; /*!< soft key label */ -- char softkeynumber[6][16]; /*!< number dialed when the soft key is pressed */ -- char softkeyicon[6]; /*!< icon number */ -- char softkeydevice[6][16]; /*!< name of the device monitored */ -- struct unistim_device *sp[6]; /*!< pointer to the device monitored by this soft key */ -- int height; /*!< The number of lines the phone can display */ -+ char softkeylabel[FAVNUM][11]; /*!< soft key label */ -+ char softkeynumber[FAVNUM][AST_MAX_EXTENSION]; /*!< number dialed when the soft key is pressed */ -+ char softkeyicon[FAVNUM]; /*!< icon number */ -+ char softkeydevice[FAVNUM][16]; /*!< name of the device monitored */ -+ struct unistim_subchannel *ssub[FAVNUM]; -+ struct unistim_line *sline[FAVNUM]; -+ struct unistim_device *sp[FAVNUM]; /*!< pointer to the device monitored by this soft key */ -+ char language[MAX_LANGUAGE]; /*!< Language for asterisk sounds */ -+ int height; /*!< The number of lines the phone can display */ - char maintext0[25]; /*!< when the phone is idle, display this string on line 0 */ - char maintext1[25]; /*!< when the phone is idle, display this string on line 1 */ - char maintext2[25]; /*!< when the phone is idle, display this string on line 2 */ -@@ -450,12 +443,16 @@ static struct unistim_device { - struct ast_tone_zone *tz; /*!< Tone zone for res_indications (ring, busy, congestion) */ - char ringvolume; /*!< Ring volume */ - char ringstyle; /*!< Ring melody */ -- int rtp_port; /*!< RTP port used by the phone */ -+ char cwvolume; /*!< Ring volume on call waiting */ -+ char cwstyle; /*!< Ring melody on call waiting */ -+ int rtp_port; /*!< RTP port used by the phone */ - int rtp_method; /*!< Select the unistim data used to establish a RTP session */ - int status_method; /*!< Select the unistim packet used for sending status text */ - char codec_number; /*!< The current codec used to make calls */ - int missed_call; /*!< Number of call unanswered */ - int callhistory; /*!< Allowed to record call history */ -+ int selected; /*!< softkey selected */ -+ int sharp_dial; /*!< Execute Dial on '#' or not */ - char lst_cid[TEXT_LENGTH_MAX]; /*!< Last callerID received */ - char lst_cnm[TEXT_LENGTH_MAX]; /*!< Last callername recevied */ - char call_forward[AST_MAX_EXTENSION]; /*!< Forward number */ -@@ -463,15 +460,14 @@ static struct unistim_device { - int previous_output; /*!< Previous output */ - int volume; /*!< Default volume */ - int mute; /*!< Mute mode */ -- int moh; /*!< Music on hold in progress */ - int nat; /*!< Used by the obscure ast_rtp_setnat */ - enum autoprov_extn extension; /*!< See ifdef EXTENSION for valid values */ - char extension_number[11]; /*!< Extension number entered by the user */ - char to_delete; /*!< Used in reload */ -- time_t start_call_timestamp; /*!< timestamp for the length calculation of the call */ - struct ast_silence_generator *silence_generator; -- struct unistim_line *lines; -- struct ast_ha *ha; -+ AST_LIST_HEAD(,unistim_subchannel) subs; /*!< pointer to our current connection, channel... */ -+ AST_LIST_HEAD(,unistim_line) lines; -+ struct ast_ha *ha; - struct unistimsession *session; - struct unistim_device *next; - } *devices = NULL; -@@ -494,9 +490,23 @@ static struct unistimsession { - struct wsabuf wsabufsend[MAX_BUF_NUMBER]; /*!< Size of each paquet stored in the buffer array & pointer to this buffer */ - unsigned char buf[MAX_BUF_NUMBER][MAX_BUF_SIZE]; /*!< Buffer array used to keep the lastest non-acked paquets */ - struct unistim_device *device; -- struct unistimsession *next; -+ struct unistim_subchannel *active_sub; /*!< Active subchannel for detect active softkey */ -+ struct unistimsession *next; - } *sessions = NULL; - -+struct unistim_menu_item { -+ char *label; -+ int state; -+ void (*handle_option)(struct unistimsession *); -+}; -+ -+struct unistim_languages { -+ char *label; -+ char *lang_short; -+ int encoding; -+ struct ao2_container *trans; -+}; -+ - /*! - * \page Unistim datagram formats - * -@@ -628,10 +638,14 @@ static const unsigned char packet_send_date_time2[] = - }; - static const unsigned char packet_send_Contrast[] = - { 0x17, 0x04, 0x24, /*Contrast */ 0x08 }; --static const unsigned char packet_send_StartTimer[] = -- { 0x17, 0x05, 0x0b, 0x05, 0x00, 0x17, 0x08, 0x16, /* Text */ 0x44, 0x75, 0x72, 0xe9, --0x65 }; --static const unsigned char packet_send_stop_timer[] = { 0x17, 0x05, 0x0b, 0x02, 0x00 }; -+static const unsigned char packet_send_start_timer[] = -+ { 0x17, 0x05, 0x0b, /*Timer option*/0x05, /* Timer ID */0x00, 0x17, 0x08, 0x16, -+ /* Text */ 0x44, 0x75, 0x72, 0xe9, 0x65 }; -+ -+static const unsigned char packet_send_delay_timer[] = { 0x17, 0x04, 0x0d, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; -+static const unsigned char packet_send_hide_timer[] = { 0x17, 0x05, 0x0b, CALL_TIMER_RESET, 0x00 }; -+static const unsigned char packet_send_show_timer[] = { 0x17, 0x05, 0x0b, 0x05 & CALL_TIMER_DELAY, 0x00 }; -+static const unsigned char packet_send_stop_timer[] = { 0x17, 0x05, 0x0b, CALL_TIMER_RESET, 0x00 }; - static const unsigned char packet_send_icon[] = { 0x17, 0x05, 0x14, /*pos */ 0x00, /*icon */ 0x25 }; /* display an icon in front of the text zone */ - static const unsigned char packet_send_S7[] = { 0x17, 0x06, 0x0f, 0x30, 0x07, 0x07 }; - static const unsigned char packet_send_set_pos_cursor[] = -@@ -662,6 +676,23 @@ static const unsigned char packet_send_status2[] = - { 0x17, 0x0b, 0x19, /* pos [08|28|48|68] */ 0x00, /* text */ 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x20 /* end_text */ }; - -+/* Multiple character set support */ -+/* ISO-8859-1 - Western European) */ -+static const unsigned char packet_send_charset_iso_8859_1[] = -+ { 0x17, 0x08, 0x21, 0x1b, 0x2d, 0x41, 0x1b, 0x00 }; -+/* ISO-8859-2 - Central European) */ -+static const unsigned char packet_send_charset_iso_8859_2[] = -+ { 0x17, 0x08, 0x21, 0x1b, 0x2d, 0x42, 0x1b, 0x00 }; -+/* ISO-8859-4 - Baltic) */ -+static const unsigned char packet_send_charset_iso_8859_4[] = -+ { 0x17, 0x08, 0x21, 0x1b, 0x2d, 0x44, 0x1b, 0x00 }; -+/* ISO 8859-5 - cyrilic */ -+static const unsigned char packet_send_charset_iso_8859_5[] = -+ { 0x17, 0x08, 0x21, 0x1b, 0x2d, 0x4c, 0x1b, 0x00 }; -+/* Japaneese (ISO-2022-JP ?) */ -+static const unsigned char packet_send_charset_iso_2022_jp[] = -+ { 0x17, 0x08, 0x21, 0x1b, 0x29, 0x49, 0x1b, 0x7e }; -+ - static const unsigned char packet_send_led_update[] = { 0x19, 0x04, 0x00, 0x00 }; - - static const unsigned char packet_send_query_basic_manager_04[] = { 0x1a, 0x04, 0x01, 0x04 }; -@@ -722,15 +753,125 @@ static const struct ast_channel_tech unistim_tech = { - .bridge = ast_rtp_instance_bridge, - }; - --static void display_last_error(const char *sz_msg) -+static void send_start_rtp(struct unistim_subchannel *); -+ -+static void send_callerid_screen(struct unistimsession *, struct unistim_subchannel *sub); -+static void key_favorite(struct unistimsession *, char); -+ -+static void handle_select_codec(struct unistimsession *); -+static void handle_select_contrast(struct unistimsession *); -+static void handle_select_language(struct unistimsession *); -+static int find_language(const char*); -+ -+struct unistim_menu_item options_menu[] = - { -- time_t cur_time; -- -- time(&cur_time); -+ {"Change codec", STATE_SELECTCODEC, handle_select_codec}, -+ {"Contrast", STATE_SELECTCONTRAST, handle_select_contrast}, -+ {"Language", STATE_SELECTLANGUAGE, handle_select_language}, -+ {NULL, 0, NULL} -+}; - -+struct unistim_languages options_languages[] = -+{ -+ {"English", "en", ISO_8859_1, NULL}, -+ {"Russian", "ru", ISO_8859_5, NULL}, -+ {NULL, NULL, 0, NULL} -+}; -+ -+struct ustm_lang_entry { -+ const char *str_orig; -+ const char *str_trans; -+}; -+ -+static void lang_entry_destructor(void *obj) -+{ -+ return; -+} -+ -+static int lang_hash_fn(const void *obj, const int flags) -+{ -+ const struct ustm_lang_entry *entry = obj; -+ return ast_str_hash(entry->str_orig); -+} -+ -+static int lang_cmp_fn(void *obj, void *arg, int flags) -+{ -+ struct ustm_lang_entry *entry1 = obj; -+ struct ustm_lang_entry *entry2 = arg; -+ -+ return (!strcmp(entry1->str_orig, entry2->str_orig)) ? (CMP_MATCH | CMP_STOP) : 0; -+} -+ -+static const char *ustmtext(const char *str, struct unistimsession *pte) { -+ struct ustm_lang_entry *lang_entry; -+ struct ustm_lang_entry le_search; -+ struct unistim_languages *lang; -+ -+ lang = &options_languages[find_language(pte->device->language)]; -+ if (!lang) -+ return str; -+ /* Check if specified language exists */ -+ if (!lang->trans) { -+ char tmp[1024], *p, *p_orig = NULL, *p_trans = NULL; -+ FILE *f; -+ -+ lang->trans = ao2_container_alloc(8, lang_hash_fn, lang_cmp_fn); -+ snprintf(tmp, sizeof(tmp), "%s/%s/%s.po", ast_config_AST_VAR_DIR, -+ USTM_LANG_DIR, lang->lang_short); -+ f = fopen(tmp, "r"); -+ if (!f) { -+ return str; -+ } -+ while (fgets(tmp, sizeof(tmp), f)) { -+ if (!(p = strchr(tmp, '\n'))) { -+ ast_log(LOG_ERROR, "input line too long.\n"); -+ } -+ *p = '\0'; -+ if (tmp == strstr(tmp, "msgid")) { -+ p_orig = ast_strdup(strchr(tmp, '"') + 1); -+ p = strchr(p_orig, '"'); -+ *p = '\0'; -+ } else if (tmp == strstr(tmp, "msgstr")) { -+ p_trans = ast_strdup(strchr(tmp, '"') + 1); -+ p = strchr(p_trans, '"'); -+ *p = '\0'; -+ } else { -+ continue; -+ } -+ if (!p_trans || !p_orig) -+ continue; -+ if (!strlen(p_trans)) { -+ p_trans = NULL; -+ p_orig = NULL; -+ continue; -+ } -+ if (!(lang_entry = ao2_alloc(sizeof(*lang_entry), lang_entry_destructor))) { -+ return str; -+ } -+ -+ lang_entry->str_trans = p_trans; -+ lang_entry->str_orig = p_orig; -+ ao2_link(lang->trans, lang_entry); -+ p_trans = NULL; -+ p_orig = NULL; -+ } -+ -+ fclose(f); -+ } -+ -+ le_search.str_orig = ast_strdup(str); -+ lang_entry = ao2_find(lang->trans, &le_search, OBJ_POINTER); -+ //lang_entry = NULL; -+ if (lang_entry) -+ return lang_entry->str_trans; -+ -+ return str; -+} -+ -+static void display_last_error(const char *sz_msg) -+{ - /* Display the error message */ -- ast_log(LOG_WARNING, "%s %s : (%u) %s\n", ctime(&cur_time), sz_msg, errno, -- strerror(errno)); -+ ast_log(LOG_WARNING, "%s : (%u) %s\n", sz_msg, errno, strerror(errno)); - } - - static unsigned int get_tick_count(void) -@@ -956,10 +1097,44 @@ static void send_start_timer(struct unistimsession *pt - BUFFSEND; - if (unistimdebug) - ast_verb(0, "Sending start timer\n"); -- memcpy(buffsend + SIZE_HEADER, packet_send_StartTimer, sizeof(packet_send_StartTimer)); -- send_client(SIZE_HEADER + sizeof(packet_send_StartTimer), buffsend, pte); -+ memcpy(buffsend + SIZE_HEADER, packet_send_start_timer, sizeof(packet_send_start_timer)); -+ send_client(SIZE_HEADER + sizeof(packet_send_start_timer), buffsend, pte); - } - -+static void send_start_timer_id(struct unistimsession *pte, const int id) -+{ -+ BUFFSEND; -+ if (unistimdebug) -+ ast_verb(0, "Sending start timer\n"); -+ memcpy(buffsend + SIZE_HEADER, packet_send_start_timer, sizeof(packet_send_start_timer)); -+ //buffsend[10] = id; -+ send_client(SIZE_HEADER + sizeof(packet_send_start_timer), buffsend, pte); -+} -+ -+static void send_hide_timer_id(struct unistimsession *pte, const int id) -+{ -+ BUFFSEND; -+ if (unistimdebug) -+ ast_verb(0, "Sending start timer\n"); -+ memcpy(buffsend + SIZE_HEADER, packet_send_hide_timer, sizeof(packet_send_hide_timer)); -+ //buffsend[10] = id; -+ send_client(SIZE_HEADER + sizeof(packet_send_hide_timer), buffsend, pte); -+} -+ -+static void send_show_timer_id(struct unistimsession *pte, const int id) -+{ -+ BUFFSEND; -+ if (unistimdebug) -+ ast_verb(0, "Sending start timer\n"); -+ memcpy(buffsend + SIZE_HEADER, packet_send_delay_timer, sizeof(packet_send_delay_timer)); -+ //buffsend[10] = id; -+ send_client(SIZE_HEADER + sizeof(packet_send_delay_timer), buffsend, pte); -+ -+ memset(buffsend + SIZE_HEADER, 0, sizeof(packet_send_delay_timer)); -+ memcpy(buffsend + SIZE_HEADER, packet_send_show_timer, sizeof(packet_send_show_timer)); -+ send_client(SIZE_HEADER + sizeof(packet_send_show_timer), buffsend, pte); -+} -+ - static void send_stop_timer(struct unistimsession *pte) - { - BUFFSEND; -@@ -969,7 +1144,7 @@ static void send_stop_timer(struct unistimsession *pte - send_client(SIZE_HEADER + sizeof(packet_send_stop_timer), buffsend, pte); - } - --static void Sendicon(unsigned char pos, unsigned char status, struct unistimsession *pte) -+static void send_icon(unsigned char pos, unsigned char status, struct unistimsession *pte) - { - BUFFSEND; - if (unistimdebug) -@@ -1027,9 +1202,9 @@ static void send_tone(struct unistimsession *pte, uint - - /* Positions for favorites - |--------------------| -- | 5 2 | -- | 4 1 | -- | 3 0 | -+ | 5 2 | <-- not on screen in i2002 -+ | 4 1 | -+ | 3 0 | - */ - - /* status (icons) : 00 = nothing, 2x/3x = see parser.h, 4x/5x = blink fast, 6x/7x = blink slow */ -@@ -1046,44 +1221,122 @@ send_favorite(unsigned char pos, unsigned char status, - buffsend[10] = pos; - buffsend[24] = pos; - buffsend[25] = status; -- i = strlen(text); -+ i = strlen(ustmtext(text, pte)); - if (i > FAV_MAX_LENGTH) - i = FAV_MAX_LENGTH; -- memcpy(buffsend + FAV_MAX_LENGTH + 1, text, i); -+ memcpy(buffsend + FAV_MAX_LENGTH + 1, ustmtext(text, pte), i); - send_client(SIZE_HEADER + sizeof(packet_send_favorite), buffsend, pte); - } - -+static void send_favorite_short(unsigned char pos, unsigned char status, struct unistimsession *pte) { -+ send_favorite(pos, status, pte, pte->device->softkeylabel[pos]); -+ return; -+} -+ -+static void send_favorite_selected(unsigned char status, struct unistimsession *pte) { -+ if (pte->device->selected != -1) -+ send_favorite(pte->device->selected, status, pte, pte->device->softkeylabel[pte->device->selected]); -+ return; -+} -+ -+static int soft_key_visible(struct unistim_device* d, int num) -+{ -+ if(d->height == 1 && num%3 == 2) { -+ return 0; -+ } -+ return 1; -+} -+ - static void refresh_all_favorite(struct unistimsession *pte) - { - int i = 0; - - if (unistimdebug) - ast_verb(0, "Refreshing all favorite\n"); -- for (i = 0; i < 6; i++) { -- if ((pte->device->softkeyicon[i] <= FAV_ICON_HEADPHONES_ONHOLD) && -- (pte->device->softkeylinepos != i)) -- send_favorite((unsigned char) i, pte->device->softkeyicon[i] + 1, pte, -- pte->device->softkeylabel[i]); -+ for (i = 0; i < FAVNUM; i++) { -+ if (!soft_key_visible(pte->device, i)) -+ continue; -+ /* XXX Here icon for the lines displayed */ -+ if ((pte->device->softkeyicon[i] <= FAV_ICON_HEADPHONES_ONHOLD)/* && -+ (pte->device->softkeylinepos != i)*/) -+ send_favorite_short((unsigned char) i, pte->device->softkeyicon[i]/* + 1*/, pte); - else -- send_favorite((unsigned char) i, pte->device->softkeyicon[i], pte, -- pte->device->softkeylabel[i]); -+ send_favorite_short((unsigned char) i, pte->device->softkeyicon[i], pte); - - } - } - -+static int is_key_favorite(struct unistim_device *d, int fav) -+{ -+ if ((fav < 0) && (fav > 5)) -+ return 0; -+ if (d->sline[fav]) -+ return 0; -+ if (d->softkeynumber[fav][0] == '\0') -+ return 0; -+ return 1; -+} -+ -+static int is_key_line(struct unistim_device *d, int fav) -+{ -+ if ((fav < 0) && (fav > 5)) -+ return 0; -+ if (!d->sline[fav]) -+ return 0; -+ if (is_key_favorite(d, fav)) -+ return 0; -+ -+ return 1; -+} -+ -+static int get_active_softkey(struct unistimsession *pte) -+{ -+ return pte->device->selected; -+} -+ -+static int get_avail_softkey(struct unistimsession *pte, const char* name) -+{ -+ int i; -+ -+ if (!is_key_line(pte->device, pte->device->selected)) { -+ pte->device->selected = -1; -+ } -+ for (i = 0; i < FAVNUM; i++) { -+ if (pte->device->selected != -1 && pte->device->selected != i) { -+ continue; -+ } -+ if (!soft_key_visible(pte->device, i)) -+ continue; -+ if (pte->device->ssub[i]) -+ continue; -+ if (is_key_line(pte->device, i)) { -+ if (name && strcmp(name, pte->device->sline[i]->name)) { -+ continue; -+ } -+ if (unistimdebug) -+ ast_verb(0, "Found softkey %d for device %s\n", i, name); -+ return i; -+ } -+ } -+ return -1; -+} -+ -+ - /* Change the status for this phone (pte) and update for each phones where pte is bookmarked - * use FAV_ICON_*_BLACK constant in status parameters */ - static void change_favorite_icon(struct unistimsession *pte, unsigned char status) - { - struct unistim_device *d = devices; - int i; -- /* Update the current phone */ -- if (pte->state != STATE_CLEANING) -- send_favorite(pte->device->softkeylinepos, status, pte, -- pte->device->softkeylabel[pte->device->softkeylinepos]); -+ /* Update the current phone line softkey icon */ -+ if (pte->state != STATE_CLEANING) { -+ int softkeylinepos = get_active_softkey(pte); -+ if (softkeylinepos != -1) -+ send_favorite_short(softkeylinepos, status, pte); -+ } - /* Notify other phones if we're in their bookmark */ - while (d) { -- for (i = 0; i < 6; i++) { -+ for (i = 0; i < FAVNUM; i++) { - if (d->sp[i] == pte->device) { /* It's us ? */ - if (d->softkeyicon[i] != status) { /* Avoid resending the same icon */ - d->softkeyicon[i] = status; -@@ -1096,30 +1349,40 @@ static void change_favorite_icon(struct unistimsession - } - } - --static int RegisterExtension(const struct unistimsession *pte) -+/* XXX Check all places where get_main_line used, as it is a hack and may be better usage possible */ -+static struct unistim_line* get_main_line(const struct unistim_device *d) - { -+ return AST_LIST_FIRST(&d->lines); -+} -+ -+static int register_extension(const struct unistimsession *pte) -+{ -+ struct unistim_line *line; -+ line = get_main_line(pte->device); - if (unistimdebug) - ast_verb(0, "Trying to register extension '%s' into context '%s' to %s\n", -- pte->device->extension_number, pte->device->lines->context, -- pte->device->lines->fullname); -- return ast_add_extension(pte->device->lines->context, 0, -+ pte->device->extension_number, line->context, -+ line->fullname); -+ return ast_add_extension(line->context, 0, - pte->device->extension_number, 1, NULL, NULL, "Dial", -- pte->device->lines->fullname, 0, "Unistim"); -+ line->fullname, 0, "Unistim"); - } - --static int UnregisterExtension(const struct unistimsession *pte) -+static int unregister_extension(const struct unistimsession *pte) - { -+ struct unistim_line *line; -+ line = get_main_line(pte->device); - if (unistimdebug) - ast_verb(0, "Trying to unregister extension '%s' context '%s'\n", -- pte->device->extension_number, pte->device->lines->context); -- return ast_context_remove_extension(pte->device->lines->context, -+ pte->device->extension_number, line->context); -+ return ast_context_remove_extension(line->context, - pte->device->extension_number, 1, "Unistim"); - } - - /* Free memory allocated for a phone */ - static void close_client(struct unistimsession *s) - { -- struct unistim_subchannel *sub; -+ struct unistim_subchannel *sub = NULL; - struct unistimsession *cur, *prev = NULL; - ast_mutex_lock(&sessionlock); - cur = sessions; -@@ -1133,12 +1396,11 @@ static void close_client(struct unistimsession *s) - if (cur) { /* Session found ? */ - if (cur->device) { /* This session was registered ? */ - s->state = STATE_CLEANING; -- if (unistimdebug) -+ /* !!! sub seems to be never used and uninitialized */ -+ if (unistimdebug) - ast_verb(0, "close_client session %p device %p lines %p sub %p\n", -- s, s->device, s->device->lines, -- s->device->lines->subs[SUB_REAL]); -+ s, s->device, get_main_line(s->device), sub); - change_favorite_icon(s, FAV_ICON_NONE); -- sub = s->device->lines->subs[SUB_REAL]; - if (sub) { - if (sub->owner) { /* Call in progress ? */ - if (unistimdebug) -@@ -1148,7 +1410,7 @@ static void close_client(struct unistimsession *s) - } else - ast_log(LOG_WARNING, "Freeing a client with no subchannel !\n"); - if (!ast_strlen_zero(s->device->extension_number)) -- UnregisterExtension(s); -+ unregister_extension(s); - cur->device->session = NULL; - } else { - if (unistimdebug) -@@ -1212,6 +1474,12 @@ send_text(unsigned char pos, unsigned char inverse, st - { - int i; - BUFFSEND; -+ if (!text) { -+ ast_log(LOG_ERROR, "Asked to display NULL text (pos %d, inverse flag %d)\n", pos, inverse); -+ return; -+ } -+ if (pte->device->height == 1 && pos != TEXT_LINE0) -+ return; - if (unistimdebug) - ast_verb(0, "Sending text at pos %d, inverse flag %d\n", pos, inverse); - memcpy(buffsend + SIZE_HEADER, packet_send_text, sizeof(packet_send_text)); -@@ -1371,12 +1639,21 @@ static void send_texttitle(struct unistimsession *pte, - - } - -+static void send_idle_clock(struct unistimsession *pte) -+{ -+ char text[2]; -+ -+ memset(text, 0x00, 2); -+ send_text(TEXT_LINE0, TEXT_NORMAL, pte, text); -+} -+ - static void send_date_time(struct unistimsession *pte) - { - BUFFSEND; - struct timeval now = ast_tvnow(); - struct ast_tm atm = { 0, }; - -+ ast_log(LOG_WARNING, "Time Received\n"); - if (unistimdebug) - ast_verb(0, "Sending Time & Date\n"); - memcpy(buffsend + SIZE_HEADER, packet_send_date_time, sizeof(packet_send_date_time)); -@@ -1449,6 +1726,43 @@ static void send_cursor_pos(struct unistimsession *pte - return; - } - -+static void send_charset_update(struct unistimsession *pte, int charset) -+{ -+ const unsigned char* packet_send_charset; -+ int packet_size; -+ BUFFSEND; -+ if (unistimdebug) -+ ast_verb(0, "Sending set default charset\n"); -+ if (charset == LANG_DEFAULT) { -+ charset = options_languages[find_language(pte->device->language)].encoding; -+ } -+ switch (charset) { -+ case ISO_8859_2: -+ packet_send_charset = packet_send_charset_iso_8859_2; -+ packet_size = sizeof(packet_send_charset_iso_8859_2); -+ break; -+ case ISO_8859_4: -+ packet_send_charset = packet_send_charset_iso_8859_4; -+ packet_size = sizeof(packet_send_charset_iso_8859_4); -+ break; -+ case ISO_8859_5: -+ packet_send_charset = packet_send_charset_iso_8859_5; -+ packet_size = sizeof(packet_send_charset_iso_8859_5); -+ break; -+ case ISO_2022_JP: -+ packet_send_charset = packet_send_charset_iso_2022_jp; -+ packet_size = sizeof(packet_send_charset_iso_2022_jp); -+ break; -+ case ISO_8859_1: -+ default: -+ packet_send_charset = packet_send_charset_iso_8859_1; -+ packet_size = sizeof(packet_send_charset_iso_8859_1); -+ } -+ memcpy(buffsend + SIZE_HEADER, packet_send_charset, packet_size); -+ send_client(SIZE_HEADER + packet_size, buffsend, pte); -+ return; -+} -+ - static void rcv_resume_connection_with_server(struct unistimsession *pte) - { - BUFFSEND; -@@ -1489,37 +1803,91 @@ static int unistim_register(struct unistimsession *s) - return 1; - } - --static int alloc_sub(struct unistim_line *l, int x) -+static struct unistim_subchannel *alloc_sub(struct unistim_device *d, int x) - { - struct unistim_subchannel *sub; - if (!(sub = ast_calloc(1, sizeof(*sub)))) -- return 0; -+ return NULL; - - if (unistimdebug) -- ast_verb(3, "Allocating UNISTIM subchannel #%d on %s@%s ptr=%p\n", x, l->name, l->parent->name, sub); -- sub->parent = l; -+ ast_verb(3, "Allocating UNISTIM subchannel #%d on %s ptr=%p\n", x, d->name, sub); -+ sub->parent = NULL; - sub->subtype = x; -- l->subs[x] = sub; -+ AST_LIST_LOCK(&d->subs); -+ AST_LIST_INSERT_TAIL(&d->subs, sub, list); -+ AST_LIST_UNLOCK(&d->subs); - ast_mutex_init(&sub->lock); -- return 1; -+ return sub; - } - --static int unalloc_sub(struct unistim_line *p, int x) -+static int unalloc_sub(struct unistim_device *d, struct unistim_subchannel *sub) - { -- if (!x) { -- ast_log(LOG_WARNING, "Trying to unalloc the real channel %s@%s?!?\n", p->name, -- p->parent->name); -- return -1; -- } -- if (unistimdebug) -- ast_debug(1, "Released sub %d of channel %s@%s\n", x, p->name, -- p->parent->name); -- ast_mutex_destroy(&p->lock); -- ast_free(p->subs[x]); -- p->subs[x] = 0; -- return 0; -+ struct unistim_subchannel *s; -+ -+ AST_LIST_LOCK(&d->subs); -+ AST_LIST_TRAVERSE_SAFE_BEGIN(&d->subs, s, list) { -+ if (!s) -+ continue; -+ if (s != sub) -+ continue; -+ AST_LIST_REMOVE_CURRENT(list); -+ if (unistimdebug) -+ ast_debug(1, "Released sub %d of channel %s@%s\n", sub->subtype, sub->parent->name, d->name); -+ -+ ast_free(sub); -+ } -+ AST_LIST_TRAVERSE_SAFE_END; -+ AST_LIST_UNLOCK(&d->subs); -+ //ast_mutex_destroy(&p->lock); TODO -+ return 0; - } - -+static const char *subtype_tostr(const int type) { -+ switch (type) { -+ case SUB_REAL: -+ return "REAL"; -+ case SUB_ONHOLD: -+ return "ONHOLD"; -+ case SUB_RING: -+ return "RINGING"; -+ case SUB_THREEWAY: -+ return "THREEWAY"; -+ } -+ return "UNKNOWN"; -+} -+ -+static const char *ptestate_tostr(const int type) { -+ switch (type) { -+ case STATE_INIT: -+ return "INIT"; -+ case STATE_AUTHDENY: -+ return "AUTHDENY"; -+ case STATE_MAINPAGE: -+ return "MAINPAGE"; -+ case STATE_EXTENSION: -+ return "EXTENSION"; -+ case STATE_DIALPAGE: -+ return "DIALPAGE"; -+ case STATE_RINGING: -+ return "RINGING"; -+ case STATE_CALL: -+ return "CALL"; -+ case STATE_SELECTOPTION: -+ return "SELECTOPTION"; -+ case STATE_SELECTCODEC: -+ return "SELECTCODEC"; -+ case STATE_SELECTCONTRAST: -+ return "SELECTCONTRAST"; -+ case STATE_SELECTLANGUAGE: -+ return "SELECTLANGUAGE"; -+ case STATE_CLEANING: -+ return "CLEARING"; -+ case STATE_HISTORY: -+ return "HISTORY"; -+ } -+ return "UNKNOWN"; -+} -+ - static void rcv_mac_addr(struct unistimsession *pte, const unsigned char *buf) - { - BUFFSEND; -@@ -1553,6 +1921,7 @@ static void rcv_mac_addr(struct unistimsession *pte, c - d = devices; - while (d) { - if (!strcasecmp(d->name, "template")) { -+ struct unistim_line *l; - /* Found, cloning this entry */ - if (!(newd = ast_malloc(sizeof(*newd)))) { - ast_mutex_unlock(&devicelock); -@@ -1566,8 +1935,9 @@ static void rcv_mac_addr(struct unistimsession *pte, c - return; - } - -- memcpy(newl, d->lines, sizeof(*newl)); -- if (!alloc_sub(newl, SUB_REAL)) { -+ l = get_main_line(d); -+ memcpy(newl, l, sizeof(*newl)); -+ if (!alloc_sub(newd, SUB_REAL)) { - ast_free(newd); - ast_free(newl); - ast_mutex_unlock(&devicelock); -@@ -1578,16 +1948,16 @@ static void rcv_mac_addr(struct unistimsession *pte, c - ast_copy_string(newd->name, addrmac, sizeof(newd->name)); - if (newd->extension == EXTENSION_NONE) - newd->extension = EXTENSION_ASK; -- newd->lines = newl; -+ //newd->lines = newl; TODO - newd->receiver_state = STATE_ONHOOK; - newd->session = pte; - newd->to_delete = -1; - pte->device = newd; - newd->next = NULL; - newl->parent = newd; -- strcpy(newl->name, d->lines->name); -- snprintf(d->lines->name, sizeof(d->lines->name), "%d", -- atoi(d->lines->name) + 1); -+ strcpy(newl->name, l->name); -+ snprintf(l->name, sizeof(l->name), "%d", -+ atoi(l->name) + 1); - snprintf(newl->fullname, sizeof(newl->fullname), "USTM/%s@%s", - newl->name, newd->name); - /* Go to the end of the linked chain */ -@@ -1631,16 +2001,16 @@ static void rcv_mac_addr(struct unistimsession *pte, c - pte->state = STATE_EXTENSION; - else { - /* Yes, because of a phone reboot. We don't ask again for the TN */ -- if (RegisterExtension(pte)) -+ if (register_extension(pte)) - pte->state = STATE_EXTENSION; - else - pte->state = STATE_MAINPAGE; - } - break; - case EXTENSION_LINE: -- ast_copy_string(pte->device->extension_number, pte->device->lines->name, -+ ast_copy_string(pte->device->extension_number, get_main_line(pte->device)->name, - sizeof(pte->device->extension_number)); -- if (RegisterExtension(pte)) -+ if (register_extension(pte)) - pte->state = STATE_EXTENSION; - else - pte->state = STATE_MAINPAGE; -@@ -1725,20 +2095,18 @@ static int write_history(struct unistimsession *pte, c - - snprintf(tmp, sizeof(tmp), "%s/%s", ast_config_AST_LOG_DIR, USTM_LOG_DIR); - if (ast_mkdir(tmp, 0770)) { -- if (errno != EEXIST) { -- display_last_error("Unable to create directory for history"); -- return -1; -- } -+ ast_log(LOG_WARNING, "Unable to create directory for history"); -+ return -1; - } - - ast_localtime(&now, &atm, NULL); - if (ismissed) { - if (way == 'i') -- strcpy(tmp2, "Miss"); -+ strcpy(tmp2, ustmtext("Miss", pte)); - else -- strcpy(tmp2, "Fail"); -+ strcpy(tmp2, ustmtext("Fail", pte)); - } else -- strcpy(tmp2, "Answ"); -+ strcpy(tmp2, ustmtext("Answ", pte)); - snprintf(line1, sizeof(line1), "%04d/%02d/%02d %02d:%02d:%02d %s", - atm.tm_year + 1900, atm.tm_mon + 1, atm.tm_mday, atm.tm_hour, - atm.tm_min, atm.tm_sec, tmp2); -@@ -1856,41 +2224,14 @@ static int write_history(struct unistimsession *pte, c - return 0; - } - --static void cancel_dial(struct unistimsession *pte) -+static void unistim_quiet_chan(struct ast_channel *chan) - { -- send_no_ring(pte); -- pte->device->missed_call++; -- write_history(pte, 'i', 1); -- show_main_page(pte); -- return; --} -- --static void swap_subs(struct unistim_line *p, int a, int b) --{ --/* struct ast_channel *towner; */ -- struct ast_rtp_instance *rtp; -- int fds; -- -- if (unistimdebug) -- ast_verb(0, "Swapping %d and %d\n", a, b); -- -- if ((!p->subs[a]->owner) || (!p->subs[b]->owner)) { -- ast_log(LOG_WARNING, -- "Attempted to swap subchannels with a null owner : sub #%d=%p sub #%d=%p\n", -- a, p->subs[a]->owner, b, p->subs[b]->owner); -- return; -+ if (chan && chan->_state == AST_STATE_UP) { -+ if (ast_test_flag(chan, AST_FLAG_MOH)) -+ ast_moh_stop(chan); -+ else if (chan->generatordata) -+ ast_deactivate_generator(chan); - } -- rtp = p->subs[a]->rtp; -- p->subs[a]->rtp = p->subs[b]->rtp; -- p->subs[b]->rtp = rtp; -- -- fds = p->subs[a]->owner->fds[0]; -- p->subs[a]->owner->fds[0] = p->subs[b]->owner->fds[0]; -- p->subs[b]->owner->fds[0] = fds; -- -- fds = p->subs[a]->owner->fds[1]; -- p->subs[a]->owner->fds[1] = p->subs[b]->owner->fds[1]; -- p->subs[b]->owner->fds[1] = fds; - } - - static int attempt_transfer(struct unistim_subchannel *p1, struct unistim_subchannel *p2) -@@ -1920,25 +2261,13 @@ static int attempt_transfer(struct unistim_subchannel - } - - if (peera && peerb && peerc && (peerb != peerc)) { -- /*ast_quiet_chan(peera); -- ast_quiet_chan(peerb); -- ast_quiet_chan(peerc); -- ast_quiet_chan(peerd); */ -+ unistim_quiet_chan(peera); -+ unistim_quiet_chan(peerb); -+ unistim_quiet_chan(peerc); -+ /* if (peerd) -+ unistim_quiet_chan(peerd); */ - -- if (peera->cdr && peerb->cdr) { -- peerb->cdr = ast_cdr_append(peerb->cdr, peera->cdr); -- } else if (peera->cdr) { -- peerb->cdr = peera->cdr; -- } -- peera->cdr = NULL; -- -- if (peerb->cdr && peerc->cdr) { -- peerb->cdr = ast_cdr_append(peerb->cdr, peerc->cdr); -- } else if (peerc->cdr) { -- peerb->cdr = peerc->cdr; -- } -- peerc->cdr = NULL; -- -+ ast_debug(4, "UNISTIM transfer: trying to masquerade %s into %s\n", peerc->name, peerb->name); - if (ast_channel_masquerade(peerb, peerc)) { - ast_log(LOG_WARNING, "Failed to masquerade %s into %s\n", peerb->name, - peerc->name); -@@ -1976,32 +2305,122 @@ void change_callerid(struct unistimsession *pte, int t - memcpy(data, callerid, size); - } - -+static struct unistim_subchannel* get_sub(struct unistim_device *device, int type) { -+ struct unistim_subchannel *sub = NULL; -+ -+ AST_LIST_LOCK(&device->subs); -+ AST_LIST_TRAVERSE(&device->subs, sub, list) { -+ if (!sub) -+ continue; -+ if (sub->subtype == type) { -+ break; -+ } -+ } -+ AST_LIST_UNLOCK(&device->subs); -+ -+ return sub; -+} -+ -+static void sub_start_silence(struct unistimsession *pte, struct unistim_subchannel *sub) { -+ /* Silence our channel */ -+ if (!pte->device->silence_generator) { -+ pte->device->silence_generator = -+ ast_channel_start_silence_generator(sub->owner); -+ if (pte->device->silence_generator == NULL) -+ ast_log(LOG_WARNING, "Unable to start a silence generator.\n"); -+ else if (unistimdebug) -+ ast_verb(0, "Starting silence generator\n"); -+ } -+ -+} -+ -+static void sub_stop_silence(struct unistimsession *pte, struct unistim_subchannel *sub) { -+ /* Stop the silence generator */ -+ if (pte->device->silence_generator) { -+ if (unistimdebug) -+ ast_verb(0, "Stopping silence generator\n"); -+ if (sub->owner) -+ ast_channel_stop_silence_generator(sub->owner, pte->device->silence_generator); -+ else -+ ast_log(LOG_WARNING, "Trying to stop silence generator on a null channel !\n"); -+ pte->device->silence_generator = NULL; -+ } -+} -+ -+static void sub_hold(struct unistimsession *pte, struct unistim_subchannel *sub) { -+ if (!sub) { -+ return; -+ } -+ sub->moh = 1; -+ sub->subtype = SUB_ONHOLD; -+ send_favorite_short(sub->softkey, FAV_ICON_ONHOLD_BLACK + FAV_BLINK_SLOW, pte); -+ send_select_output(pte, pte->device->output, pte->device->volume, MUTE_ON); -+ send_hide_timer_id(pte, sub->softkey); -+ if (sub->owner) { -+ ast_queue_control_data(sub->owner, AST_CONTROL_HOLD, NULL, 0); -+ send_end_call(pte); -+ } -+ return; -+} -+ -+static void sub_unhold(struct unistimsession *pte, struct unistim_subchannel *sub) { -+ struct unistim_subchannel *sub_real; -+ -+ sub_real = get_sub(pte->device, SUB_REAL); -+ if (sub_real) { -+ sub_hold(pte, sub_real); -+ } -+ -+ sub->moh = 0; -+ sub->subtype = SUB_REAL; -+ send_favorite_short(sub->softkey, FAV_ICON_OFFHOOK_BLACK, pte); -+ send_select_output(pte, pte->device->output, pte->device->volume, MUTE_OFF); -+ send_show_timer_id(pte, sub->softkey); -+ if (sub->owner) { -+ ast_queue_control_data(sub->owner, AST_CONTROL_UNHOLD, NULL, 0); -+ if (sub->rtp) -+ send_start_rtp(sub); -+ } -+ return; -+} -+ - static void close_call(struct unistimsession *pte) - { -- struct unistim_subchannel *sub; -- struct unistim_line *l = pte->device->lines; -+ struct unistim_subchannel *sub, *sub_transf; - -- sub = pte->device->lines->subs[SUB_REAL]; -+ sub = get_sub(pte->device, SUB_REAL); -+ sub_transf = get_sub(pte->device, SUB_THREEWAY); - send_stop_timer(pte); -+ if (!sub) { -+ ast_log(LOG_WARNING, "Close call without sub\n"); -+ return; -+ } -+ send_favorite_short(sub->softkey, FAV_LINE_ICON, pte); - if (sub->owner) { - sub->alreadygone = 1; -- if (l->subs[SUB_THREEWAY]) { -- l->subs[SUB_THREEWAY]->alreadygone = 1; -- if (attempt_transfer(sub, l->subs[SUB_THREEWAY]) < 0) -+ if (sub_transf) { -+ sub_transf->alreadygone = 1; -+ ast_moh_stop(ast_bridged_channel(sub_transf->owner)); -+ sub_transf->moh = 0; -+ if (attempt_transfer(sub, sub_transf) < 0) - ast_verb(0, "attempt_transfer failed.\n"); - } else - ast_queue_hangup(sub->owner); - } else { -- if (l->subs[SUB_THREEWAY]) { -- if (l->subs[SUB_THREEWAY]->owner) -- ast_queue_hangup_with_cause(l->subs[SUB_THREEWAY]->owner, AST_CAUSE_NORMAL_CLEARING); -+ if (sub_transf) { -+ if (sub_transf->owner) -+ ast_queue_hangup_with_cause(sub_transf->owner, AST_CAUSE_NORMAL_CLEARING); - else - ast_log(LOG_WARNING, "threeway sub without owner\n"); -- } else -+ } else { - ast_verb(0, "USTM(%s@%s-%d) channel already destroyed\n", sub->parent->name, -- sub->parent->parent->name, sub->subtype); -- } -- change_callerid(pte, 0, pte->device->redial_number); -+ pte->device->name, sub->softkey); -+ /* XXX Crash because of outputing strings in log? probably sub->parent->name going wrong -+ * when buttons very fast pressed -+ */ -+ } -+ } -+ change_callerid(pte, 0, pte->device->redial_number); - change_callerid(pte, 1, ""); - write_history(pte, 'o', pte->device->missed_call); - pte->device->missed_call = 0; -@@ -2009,9 +2428,10 @@ static void close_call(struct unistimsession *pte) - return; - } - --static void IgnoreCall(struct unistimsession *pte) -+static void ignore_call(struct unistimsession *pte) - { - send_no_ring(pte); -+ /* XXX Add option to hangup incoming call or forward it to voicemail/exten */ - return; - } - -@@ -2023,7 +2443,7 @@ static void *unistim_ss(void *data) - struct unistimsession *s = l->parent->session; - int res; - -- ast_verb(3, "Starting switch on '%s@%s-%d' to %s\n", l->name, l->parent->name, sub->subtype, s->device->phone_number); -+ ast_verb(3, "Starting switch on '%s@%s-%d' to %s\n", l->name, l->parent->name, sub->softkey, s->device->phone_number); - ast_copy_string(chan->exten, s->device->phone_number, sizeof(chan->exten)); - ast_copy_string(s->device->redial_number, s->device->phone_number, - sizeof(s->device->redial_number)); -@@ -2031,85 +2451,50 @@ static void *unistim_ss(void *data) - res = ast_pbx_run(chan); - if (res) { - ast_log(LOG_WARNING, "PBX exited non-zero\n"); -- send_tone(s, 1000, 0);; -+ send_tone(s, 1000, 0); - } - return NULL; - } - --static void start_rtp(struct unistim_subchannel *sub) --{ -+static int find_rtp_port(struct unistim_subchannel *s) { -+ struct unistim_subchannel *sub = NULL; -+ int rtp_start = s->parent->parent->rtp_port; -+ struct ast_sockaddr us_tmp; -+ struct sockaddr_in us = { 0, }; -+ -+ AST_LIST_LOCK(&s->parent->parent->subs); -+ AST_LIST_TRAVERSE(&s->parent->parent->subs, sub, list) { -+ if (!sub) -+ continue; -+ if (sub->rtp) { -+ ast_rtp_instance_get_remote_address(sub->rtp, &us_tmp); -+ ast_sockaddr_to_sin(&us_tmp, &us); -+ if (htons(us.sin_port)) { -+ rtp_start = htons(us.sin_port) + 1; -+ break; -+ } -+ } -+ } -+ AST_LIST_UNLOCK(&s->parent->parent->subs); -+ return rtp_start; -+} -+ -+static void send_start_rtp(struct unistim_subchannel *sub) { - BUFFSEND; -- struct sockaddr_in us = { 0, }; -+ -+ format_t codec; - struct sockaddr_in public = { 0, }; -+ struct sockaddr_in us = { 0, }; - struct sockaddr_in sin = { 0, }; -- format_t codec; -- struct sockaddr_in sout = { 0, }; - struct ast_sockaddr us_tmp; - struct ast_sockaddr sin_tmp; -- struct ast_sockaddr sout_tmp; -+ struct unistimsession *pte; - -- /* Sanity checks */ -- if (!sub) { -- ast_log(LOG_WARNING, "start_rtp with a null subchannel !\n"); -- return; -- } -- if (!sub->parent) { -- ast_log(LOG_WARNING, "start_rtp with a null line !\n"); -- return; -- } -- if (!sub->parent->parent) { -- ast_log(LOG_WARNING, "start_rtp with a null device !\n"); -- return; -- } -- if (!sub->parent->parent->session) { -- ast_log(LOG_WARNING, "start_rtp with a null session !\n"); -- return; -- } -- sout = sub->parent->parent->session->sout; -- -- ast_mutex_lock(&sub->lock); -- /* Allocate the RTP */ -- if (unistimdebug) -- ast_verb(0, "Starting RTP. Bind on %s\n", ast_inet_ntoa(sout.sin_addr)); -- ast_sockaddr_from_sin(&sout_tmp, &sout); -- sub->rtp = ast_rtp_instance_new("asterisk", sched, &sout_tmp, NULL); -- if (!sub->rtp) { -- ast_log(LOG_WARNING, "Unable to create RTP session: %s binaddr=%s\n", -- strerror(errno), ast_inet_ntoa(sout.sin_addr)); -- ast_mutex_unlock(&sub->lock); -- return; -- } -- ast_rtp_instance_set_prop(sub->rtp, AST_RTP_PROPERTY_RTCP, 1); -- if (sub->owner) { -- sub->owner->fds[0] = ast_rtp_instance_fd(sub->rtp, 0); -- sub->owner->fds[1] = ast_rtp_instance_fd(sub->rtp, 1); -- } -- ast_rtp_instance_set_qos(sub->rtp, qos.tos_audio, qos.cos_audio, "UNISTIM RTP"); -- ast_rtp_instance_set_prop(sub->rtp, AST_RTP_PROPERTY_NAT, sub->parent->parent->nat); -- -- /* Create the RTP connection */ - ast_rtp_instance_get_local_address(sub->rtp, &us_tmp); - ast_sockaddr_to_sin(&us_tmp, &us); -- sin.sin_family = AF_INET; -- /* Setting up RTP for our side */ -- memcpy(&sin.sin_addr, &sub->parent->parent->session->sin.sin_addr, -- sizeof(sin.sin_addr)); -- sin.sin_port = htons(sub->parent->parent->rtp_port); -- ast_sockaddr_from_sin(&sin_tmp, &sin); -- ast_rtp_instance_set_remote_address(sub->rtp, &sin_tmp); -- if (!(sub->owner->nativeformats & sub->owner->readformat)) { -- format_t fmt; -- char tmp[256]; -- fmt = ast_best_codec(sub->owner->nativeformats); -- ast_log(LOG_WARNING, -- "Our read/writeformat has been changed to something incompatible: %s, using %s best codec from %s\n", -- ast_getformatname(sub->owner->readformat), -- ast_getformatname(fmt), -- ast_getformatname_multiple(tmp, sizeof(tmp), sub->owner->nativeformats)); -- sub->owner->readformat = fmt; -- sub->owner->writeformat = fmt; -- } -- codec = ast_rtp_codecs_payload_code(ast_rtp_instance_get_codecs(sub->rtp), 1, sub->owner->readformat); -+ ast_rtp_instance_get_remote_address(sub->rtp, &sin_tmp); -+ ast_sockaddr_to_sin(&sin_tmp, &sin); -+ - /* Setting up RTP of the phone */ - if (public_ip.sin_family == 0) /* NAT IP override ? */ - memcpy(&public, &us, sizeof(public)); /* No defined, using IP from recvmsg */ -@@ -2122,35 +2507,35 @@ static void start_rtp(struct unistim_subchannel *sub) - ast_verb(0, "Starting phone RTP stack. Our public IP is %s\n", - ast_inet_ntoa(public.sin_addr)); - } -- if ((sub->owner->readformat == AST_FORMAT_ULAW) || -+ -+ pte = sub->parent->parent->session; -+ codec = ast_rtp_codecs_payload_code(ast_rtp_instance_get_codecs(sub->rtp), 1, sub->owner->readformat); -+ if ((sub->owner->readformat == AST_FORMAT_ULAW) || - (sub->owner->readformat == AST_FORMAT_ALAW)) { - if (unistimdebug) - ast_verb(0, "Sending packet_send_rtp_packet_size for codec %s\n", ast_getformatname(codec)); - memcpy(buffsend + SIZE_HEADER, packet_send_rtp_packet_size, - sizeof(packet_send_rtp_packet_size)); - buffsend[10] = (int) codec & 0xffffffffLL; -- send_client(SIZE_HEADER + sizeof(packet_send_rtp_packet_size), buffsend, -- sub->parent->parent->session); -+ send_client(SIZE_HEADER + sizeof(packet_send_rtp_packet_size), buffsend, pte); - } - if (unistimdebug) - ast_verb(0, "Sending Jitter Buffer Parameters Configuration\n"); - memcpy(buffsend + SIZE_HEADER, packet_send_jitter_buffer_conf, - sizeof(packet_send_jitter_buffer_conf)); -- send_client(SIZE_HEADER + sizeof(packet_send_jitter_buffer_conf), buffsend, -- sub->parent->parent->session); -- if (sub->parent->parent->rtp_method != 0) { -+ send_client(SIZE_HEADER + sizeof(packet_send_jitter_buffer_conf), buffsend, pte); -+ if (pte->device->rtp_method != 0) { - uint16_t rtcpsin_port = htons(us.sin_port) + 1; /* RTCP port is RTP + 1 */ - - if (unistimdebug) -- ast_verb(0, "Sending OpenAudioStreamTX using method #%d\n", -- sub->parent->parent->rtp_method); -- if (sub->parent->parent->rtp_method == 3) -+ ast_verb(0, "Sending OpenAudioStreamTX using method #%d\n", pte->device->rtp_method); -+ if (pte->device->rtp_method == 3) - memcpy(buffsend + SIZE_HEADER, packet_send_open_audio_stream_tx3, - sizeof(packet_send_open_audio_stream_tx3)); - else - memcpy(buffsend + SIZE_HEADER, packet_send_open_audio_stream_tx, - sizeof(packet_send_open_audio_stream_tx)); -- if (sub->parent->parent->rtp_method != 2) { -+ if (pte->device->rtp_method != 2) { - memcpy(buffsend + 28, &public.sin_addr, sizeof(public.sin_addr)); - buffsend[20] = (htons(sin.sin_port) & 0xff00) >> 8; - buffsend[21] = (htons(sin.sin_port) & 0x00ff); -@@ -2169,18 +2554,17 @@ static void start_rtp(struct unistim_subchannel *sub) - buffsend[11] = codec; - } - buffsend[12] = codec; -- send_client(SIZE_HEADER + sizeof(packet_send_open_audio_stream_tx), buffsend, -- sub->parent->parent->session); -+ send_client(SIZE_HEADER + sizeof(packet_send_open_audio_stream_tx), buffsend, pte); - - if (unistimdebug) - ast_verb(0, "Sending OpenAudioStreamRX\n"); -- if (sub->parent->parent->rtp_method == 3) -+ if (pte->device->rtp_method == 3) - memcpy(buffsend + SIZE_HEADER, packet_send_open_audio_stream_rx3, - sizeof(packet_send_open_audio_stream_rx3)); - else - memcpy(buffsend + SIZE_HEADER, packet_send_open_audio_stream_rx, - sizeof(packet_send_open_audio_stream_rx)); -- if (sub->parent->parent->rtp_method != 2) { -+ if (pte->device->rtp_method != 2) { - memcpy(buffsend + 28, &public.sin_addr, sizeof(public.sin_addr)); - buffsend[20] = (htons(sin.sin_port) & 0xff00) >> 8; - buffsend[21] = (htons(sin.sin_port) & 0x00ff); -@@ -2199,8 +2583,7 @@ static void start_rtp(struct unistim_subchannel *sub) - buffsend[12] = codec; - } - buffsend[11] = codec; -- send_client(SIZE_HEADER + sizeof(packet_send_open_audio_stream_rx), buffsend, -- sub->parent->parent->session); -+ send_client(SIZE_HEADER + sizeof(packet_send_open_audio_stream_rx), buffsend, pte); - } else { - uint16_t rtcpsin_port = htons(us.sin_port) + 1; /* RTCP port is RTP + 1 */ - -@@ -2234,73 +2617,152 @@ static void start_rtp(struct unistim_subchannel *sub) - buffsend[46] = (htons(sin.sin_port) & 0x00ff); - buffsend[47] = (rtcpsin_port & 0xff00) >> 8; - buffsend[48] = (rtcpsin_port & 0x00ff); -- send_client(SIZE_HEADER + sizeof(packet_send_call), buffsend, -- sub->parent->parent->session); -+ send_client(SIZE_HEADER + sizeof(packet_send_call), buffsend, pte); - } -- ast_mutex_unlock(&sub->lock); - } - --static void SendDialTone(struct unistimsession *pte) -+static void start_rtp(struct unistim_subchannel *sub) - { -- int i; -- /* No country defined ? Using US tone */ -- if (ast_strlen_zero(pte->device->country)) { -- if (unistimdebug) -- ast_verb(0, "No country defined, using US tone\n"); -- send_tone(pte, 350, 440); -+ struct sockaddr_in sin = { 0, }; -+ struct sockaddr_in sout = { 0, }; -+ struct ast_sockaddr sin_tmp; -+ struct ast_sockaddr sout_tmp; -+ -+ /* Sanity checks */ -+ if (!sub) { -+ ast_log(LOG_WARNING, "start_rtp with a null subchannel !\n"); - return; - } -- if (strlen(pte->device->country) != 2) { -- if (unistimdebug) -- ast_verb(0, "Country code != 2 char, using US tone\n"); -- send_tone(pte, 350, 440); -+ if (!sub->parent) { -+ ast_log(LOG_WARNING, "start_rtp with a null line!\n"); - return; - } -- i = 0; -- while (frequency[i].freq1) { -- if ((frequency[i].country[0] == pte->device->country[0]) && -- (frequency[i].country[1] == pte->device->country[1])) { -- if (unistimdebug) -- ast_verb(0, "Country code found (%s), freq1=%d freq2=%d\n", -- frequency[i].country, frequency[i].freq1, frequency[i].freq2); -- send_tone(pte, frequency[i].freq1, frequency[i].freq2); -- } -- i++; -+ if (!sub->parent->parent) { -+ ast_log(LOG_WARNING, "start_rtp with a null device!\n"); -+ return; - } -+ if (!sub->parent->parent->session) { -+ ast_log(LOG_WARNING, "start_rtp with a null session!\n"); -+ return; -+ } -+ if (!sub->owner) { -+ ast_log(LOG_WARNING, "start_rtp with a null asterisk channel!\n"); -+ return; -+ } -+ sout = sub->parent->parent->session->sout; -+ sout.sin_family = AF_INET; -+ ast_mutex_lock(&sub->lock); -+ /* Allocate the RTP */ -+ if (unistimdebug) -+ ast_verb(0, "Starting RTP. Bind on %s\n", ast_inet_ntoa(sout.sin_addr)); -+ ast_sockaddr_from_sin(&sout_tmp, &sout); -+ sub->rtp = ast_rtp_instance_new("asterisk", sched, &sout_tmp, NULL); -+ if (!sub->rtp) { -+ ast_log(LOG_WARNING, "Unable to create RTP session: %s binaddr=%s\n", -+ strerror(errno), ast_inet_ntoa(sout.sin_addr)); -+ ast_mutex_unlock(&sub->lock); -+ return; -+ } -+ ast_rtp_instance_set_prop(sub->rtp, AST_RTP_PROPERTY_RTCP, 1); -+ sub->owner->fds[0] = ast_rtp_instance_fd(sub->rtp, 0); -+ sub->owner->fds[1] = ast_rtp_instance_fd(sub->rtp, 1); -+ ast_rtp_instance_set_qos(sub->rtp, qos.tos_audio, qos.cos_audio, "UNISTIM RTP"); -+ ast_rtp_instance_set_prop(sub->rtp, AST_RTP_PROPERTY_NAT, sub->parent->parent->nat); -+ -+ /* Create the RTP connection */ -+ sin.sin_family = AF_INET; -+ /* Setting up RTP for our side */ -+ memcpy(&sin.sin_addr, &sub->parent->parent->session->sin.sin_addr, -+ sizeof(sin.sin_addr)); -+ -+ sin.sin_port = htons(find_rtp_port(sub)); -+ ast_sockaddr_from_sin(&sin_tmp, &sin); -+ ast_rtp_instance_set_remote_address(sub->rtp, &sin_tmp); -+ if (!(sub->owner->nativeformats & sub->owner->readformat)) { -+ format_t fmt; -+ char tmp[256]; -+ fmt = ast_best_codec(sub->owner->nativeformats); -+ ast_log(LOG_WARNING, -+ "Our read/writeformat has been changed to something incompatible: %s, using %s best codec from %s\n", -+ ast_getformatname(sub->owner->readformat), -+ ast_getformatname(fmt), -+ ast_getformatname_multiple(tmp, sizeof(tmp), sub->owner->nativeformats)); -+ sub->owner->readformat = fmt; -+ sub->owner->writeformat = fmt; -+ } -+ -+ send_start_rtp(sub); -+ -+ ast_mutex_unlock(&sub->lock); - } - -+static void send_dial_tone(struct unistimsession *pte) -+{ -+ struct ast_tone_zone_sound *ts = NULL; -+ struct ast_tone_zone_part tone_data; -+ char *s = NULL; -+ char *ind; -+ -+ if ((ts = ast_get_indication_tone(pte->device->tz, "dial"))) { -+ ind = ast_strdupa(ts->data); -+ s = strsep(&ind, ","); -+ ast_tone_zone_part_parse(s, &tone_data); -+ if (tone_data.modulate) -+ tone_data.freq2 = 0; -+ -+ send_tone(pte, tone_data.freq1, tone_data.freq2); -+ if (unistimdebug) -+ ast_verb(0, "Country code found (%s), freq1=%d freq2=%d\n", -+ pte->device->tz->country, tone_data.freq1, tone_data.freq2); -+ -+ ts = ast_tone_zone_sound_unref(ts); -+ } -+} -+ -+static void show_phone_number(struct unistimsession *pte) -+{ -+ char tmp[TEXT_LENGTH_MAX + 1]; -+ const char *tmp_number = ustmtext("Number:", pte); -+ int line, offset = 0, i; -+ -+ pte->device->phone_number[pte->device->size_phone_number] = '\0'; -+ if (pte->device->size_phone_number > MAX_SCREEN_NUMBER) { -+ offset = pte->device->size_phone_number - MAX_SCREEN_NUMBER - 1; -+ if (offset > strlen(tmp_number)) -+ offset = strlen(tmp_number); -+ memcpy(tmp, tmp_number + offset, strlen(tmp_number) - offset + 1); -+ } else { -+ strcpy(tmp, tmp_number); -+ } -+ -+ offset = (pte->device->size_phone_number >= TEXT_LENGTH_MAX) ? (pte->device->size_phone_number - TEXT_LENGTH_MAX +1) : 0; -+ if (pte->device->size_phone_number) -+ memcpy(tmp + strlen(tmp), pte->device->phone_number + offset, pte->device->size_phone_number - offset + 1); -+ offset = strlen(tmp); -+ -+ for (i = strlen(tmp); i < TEXT_LENGTH_MAX; i++) { -+ tmp[i] = '.'; -+ } -+ tmp[i] = '\0'; -+ -+ line = (pte->device->height == 1) ? TEXT_LINE0 : TEXT_LINE2; -+ send_text(line, TEXT_NORMAL, pte, tmp); -+ send_blink_cursor(pte); -+ send_cursor_pos(pte, (unsigned char) (line + offset)); -+ send_led_update(pte, 0); -+} -+ - static void handle_dial_page(struct unistimsession *pte) - { - pte->state = STATE_DIALPAGE; - if (pte->device->call_forward[0] == -1) { - send_text(TEXT_LINE0, TEXT_NORMAL, pte, ""); -- send_text(TEXT_LINE1, TEXT_NORMAL, pte, "Enter forward"); -- send_text_status(pte, "ForwardCancel BackSpcErase"); -+ send_text(TEXT_LINE1, TEXT_NORMAL, pte, ustmtext("Enter forward", pte)); -+ send_text_status(pte, ustmtext("Fwd Cancel BackSp Erase", pte)); - if (pte->device->call_forward[1] != 0) { -- char tmp[TEXT_LENGTH_MAX + 1]; -- - ast_copy_string(pte->device->phone_number, pte->device->call_forward + 1, - sizeof(pte->device->phone_number)); -- pte->device->size_phone_number = strlen(pte->device->phone_number); -- if (pte->device->size_phone_number > 15) -- pte->device->size_phone_number = 15; -- strcpy(tmp, "Number : ..............."); -- memcpy(tmp + 9, pte->device->phone_number, pte->device->size_phone_number); -- -- if (pte->device->height == 1) { -- send_text(TEXT_LINE0, TEXT_NORMAL, pte, tmp); -- send_blink_cursor(pte); -- send_cursor_pos(pte, -- (unsigned char) (TEXT_LINE0 + 0x09 + -- pte->device->size_phone_number)); -- } else { -- send_text(TEXT_LINE2, TEXT_NORMAL, pte, tmp); -- send_blink_cursor(pte); -- send_cursor_pos(pte, -- (unsigned char) (TEXT_LINE2 + 0x09 + -- pte->device->size_phone_number)); -- } -- -+ show_phone_number(pte); - send_led_update(pte, 0); - return; - } -@@ -2310,191 +2772,268 @@ static void handle_dial_page(struct unistimsession *pt - send_select_output(pte, OUTPUT_SPEAKER, pte->device->volume, MUTE_OFF); - else - send_select_output(pte, pte->device->output, pte->device->volume, MUTE_OFF); -- SendDialTone(pte); -+ send_dial_tone(pte); - - if (pte->device->height > 1) { -- send_text(TEXT_LINE0, TEXT_NORMAL, pte, "Enter the number to dial"); -- send_text(TEXT_LINE1, TEXT_NORMAL, pte, "and press Call"); -+ send_text(TEXT_LINE0, TEXT_NORMAL, pte, ustmtext("Enter the number to dial", pte)); -+ send_text(TEXT_LINE1, TEXT_NORMAL, pte, ustmtext("and press Call", pte)); - } -- send_text_status(pte, "Call Redial BackSpcErase"); -+ send_text_status(pte, ustmtext("Call Redial BackSp Erase", pte)); - } - -- if (pte->device->height == 1) { -- send_text(TEXT_LINE0, TEXT_NORMAL, pte, "Number : ..............."); -- send_blink_cursor(pte); -- send_cursor_pos(pte, TEXT_LINE0 + 0x09); -- } else { -- send_text(TEXT_LINE2, TEXT_NORMAL, pte, "Number : ..............."); -- send_blink_cursor(pte); -- send_cursor_pos(pte, TEXT_LINE2 + 0x09); -- } - pte->device->size_phone_number = 0; - pte->device->phone_number[0] = 0; -- change_favorite_icon(pte, FAV_ICON_PHONE_BLACK); -- Sendicon(TEXT_LINE0, FAV_ICON_NONE, pte); -+ show_phone_number(pte); -+ change_favorite_icon(pte, FAV_ICON_PHONE_BLACK); -+ send_icon(TEXT_LINE0, FAV_ICON_NONE, pte); - pte->device->missed_call = 0; - send_led_update(pte, 0); - return; - } - -+static void swap_subs(struct unistim_subchannel *a, struct unistim_subchannel *b) -+{ -+/* struct ast_channel *towner; */ -+ struct ast_rtp_instance *rtp; -+ int fds; -+ -+ if (unistimdebug) -+ ast_verb(0, "Swapping %p and %p\n", a, b); -+ -+ if ((!a->owner) || (!b->owner)) { -+ ast_log(LOG_WARNING, -+ "Attempted to swap subchannels with a null owner : sub #%p=%p sub #%p=%p\n", -+ a, a->owner, b, b->owner); -+ return; -+ } -+ rtp = a->rtp; -+ a->rtp = b->rtp; -+ b->rtp = rtp; -+ -+ fds = a->owner->fds[0]; -+ a->owner->fds[0] = b->owner->fds[0]; -+ b->owner->fds[0] = fds; -+ -+ fds = a->owner->fds[1]; -+ a->owner->fds[1] = b->owner->fds[1]; -+ b->owner->fds[1] = fds; -+} -+ - /* Step 1 : Music On Hold for peer, Dialing screen for us */ --static void TransferCallStep1(struct unistimsession *pte) -+static void transfer_call_step1(struct unistimsession *pte) - { -- struct unistim_subchannel *sub; -- struct unistim_line *p = pte->device->lines; -+ struct unistim_subchannel *sub, *sub_trans; -+ struct unistim_device *d = pte->device; - -- sub = p->subs[SUB_REAL]; -+ sub = get_sub(d, SUB_REAL); -+ sub_trans = get_sub(d, SUB_THREEWAY); - -- if (!sub->owner) { -+ if (!sub || !sub->owner) { - ast_log(LOG_WARNING, "Unable to find subchannel for music on hold\n"); - return; - } -- if (p->subs[SUB_THREEWAY]) { -+ if (sub_trans) { - if (unistimdebug) - ast_verb(0, "Transfer canceled, hangup our threeway channel\n"); -- if (p->subs[SUB_THREEWAY]->owner) -- ast_queue_hangup_with_cause(p->subs[SUB_THREEWAY]->owner, AST_CAUSE_NORMAL_CLEARING); -- else -+ if (sub->owner) { -+ swap_subs(sub, sub_trans); -+ ast_moh_stop(ast_bridged_channel(sub_trans->owner)); -+ sub_trans->moh = 0; -+ sub_trans->subtype = SUB_REAL; -+ ast_queue_hangup_with_cause(sub->owner, AST_CAUSE_NORMAL_CLEARING); -+ } else - ast_log(LOG_WARNING, "Canceling a threeway channel without owner\n"); - return; - } - /* Start music on hold if appropriate */ -- if (pte->device->moh) -+ if (sub->moh) - ast_log(LOG_WARNING, "Transfer with peer already listening music on hold\n"); - else { -- if (ast_bridged_channel(p->subs[SUB_REAL]->owner)) { -- ast_moh_start(ast_bridged_channel(p->subs[SUB_REAL]->owner), -- pte->device->lines->musicclass, NULL); -- pte->device->moh = 1; -+ if (ast_bridged_channel(sub->owner)) { -+ ast_moh_start(ast_bridged_channel(sub->owner), -+ sub->parent->musicclass, NULL); -+ sub->moh = 1; -+ sub->subtype = SUB_THREEWAY; - } else { - ast_log(LOG_WARNING, "Unable to find peer subchannel for music on hold\n"); - return; - } - } -- /* Silence our channel */ -- if (!pte->device->silence_generator) { -- pte->device->silence_generator = -- ast_channel_start_silence_generator(p->subs[SUB_REAL]->owner); -- if (pte->device->silence_generator == NULL) -- ast_log(LOG_WARNING, "Unable to start a silence generator.\n"); -- else if (unistimdebug) -- ast_verb(0, "Starting silence generator\n"); -- } -+ sub_start_silence(pte, sub); - handle_dial_page(pte); - } - - /* From phone to PBX */ --static void HandleCallOutgoing(struct unistimsession *s) -+static void handle_call_outgoing(struct unistimsession *s) - { - struct ast_channel *c; - struct unistim_subchannel *sub; -+ int softkey; - pthread_t t; -+ - s->state = STATE_CALL; -- sub = s->device->lines->subs[SUB_REAL]; -- if (!sub) { -- ast_log(LOG_NOTICE, "No available lines on: %s\n", s->device->name); -- return; -- } -+ s->sout.sin_family = AF_INET; -+ -+ sub = get_sub(s->device, SUB_THREEWAY); -+ if (sub) { -+ /* If sub for threway call created than we use transfer behaviuor */ -+ struct unistim_subchannel *sub_trans = NULL; -+ struct unistim_device *d = s->device; -+ -+ sub_trans = get_sub(d, SUB_REAL); -+ if (sub_trans) { -+ ast_log(LOG_WARNING, -+ "Can't transfer while active subchannel exists!\n"); -+ return; -+ } -+ if (!sub->owner) { -+ ast_log(LOG_WARNING, "Unable to find subchannel with music on hold\n"); -+ return; -+ } -+ -+ sub_trans = alloc_sub(d, SUB_REAL); -+ sub_trans->parent = sub->parent; -+ if (!sub_trans) { -+ ast_log(LOG_WARNING, "Unable to allocate three-way subchannel\n"); -+ return; -+ } -+ sub_stop_silence(s, sub); -+ send_tone(s, 0, 0); -+ /* Make new channel */ -+ c = unistim_new(sub_trans, AST_STATE_DOWN, NULL); -+ if (!c) { -+ ast_log(LOG_WARNING, "Cannot allocate new structure on channel %p\n", sub->parent); -+ return; -+ } -+ /* Swap things around between the three-way and real call */ -+ swap_subs(sub, sub_trans); -+ send_select_output(s, s->device->output, s->device->volume, MUTE_OFF); -+ if (s->device->height == 1) { -+ send_text(TEXT_LINE0, TEXT_NORMAL, s, s->device->phone_number); -+ } else { -+ send_text(TEXT_LINE0, TEXT_NORMAL, s, ustmtext("Calling (pre-transfer)", s)); -+ send_text(TEXT_LINE1, TEXT_NORMAL, s, s->device->phone_number); -+ send_text(TEXT_LINE2, TEXT_NORMAL, s, ustmtext("Dialing...", s)); -+ } -+ send_text_status(s, ustmtext("TransfrCancel", s)); -+ -+ if (ast_pthread_create(&t, NULL, unistim_ss, c)) { -+ ast_log(LOG_WARNING, "Unable to start simple switch on channel %p\n", c); -+ ast_hangup(c); -+ return; -+ } -+ if (unistimdebug) -+ ast_verb(0, "Started three way call on channel %p (%s) subchan %d\n", -+ sub_trans->owner, sub_trans->owner->name, sub_trans->subtype); -+ return; -+ } -+ -+ softkey = get_avail_softkey(s, NULL); -+ if (softkey == -1) { -+ ast_log(LOG_WARNING, "Have no avail softkey for calling\n"); -+ return; -+ } -+ sub = get_sub(s->device, SUB_REAL); -+ if (sub) { /* have already call assigned */ -+ sub_hold(s, sub); /* Need to put on hold */ -+ } -+ sub = alloc_sub(s->device, SUB_REAL); -+ sub->parent = s->device->sline[softkey]; -+ s->device->ssub[softkey] = sub; -+ sub->softkey = softkey; -+ -+ if (unistimdebug) -+ ast_verb(0, "Using softkey %d, line %p\n", sub->softkey, sub->parent); -+ send_favorite_short(sub->softkey, FAV_ICON_OFFHOOK_BLACK, s); -+ s->device->selected = -1; - if (!sub->owner) { /* A call is already in progress ? */ - c = unistim_new(sub, AST_STATE_DOWN, NULL); /* No, starting a new one */ -- if (c) { -- /* Need to start RTP before calling ast_pbx_run */ -- if (!sub->rtp) -- start_rtp(sub); -- send_select_output(s, s->device->output, s->device->volume, MUTE_OFF); -+ if (!sub->rtp) /* Need to start RTP before calling ast_pbx_run */ -+ start_rtp(sub); -+ if (!strcmp(s->device->phone_number, ast_pickup_ext())) { -+ if (unistimdebug) -+ ast_verb(0, "Try to pickup in unistim_new\n"); - -+ send_text(TEXT_LINE0, TEXT_NORMAL, s, ""); -+ send_text_status(s, ustmtext("Hangup Transf", s)); -+ send_start_timer_id(s, sub->softkey); -+ if (ast_pickup_call(c)) { -+ ast_log(LOG_NOTICE, "Nothing to pick up\n"); -+ c->hangupcause = AST_CAUSE_CALL_REJECTED; -+ } else { -+ c->hangupcause = AST_CAUSE_NORMAL_CLEARING; -+ } -+ ast_hangup(c); -+ c = NULL; -+ } else if (c) { -+ send_select_output(s, s->device->output, s->device->volume, MUTE_OFF); -+ send_tone(s, 0, 0); /* Dialing empty number should also stop dial tone */ - if (s->device->height == 1) { -- send_text(TEXT_LINE0, TEXT_NORMAL, s, s->device->phone_number); -+ if (strlen(s->device->phone_number) > 0) { -+ send_text(TEXT_LINE0, TEXT_NORMAL, s, s->device->phone_number); -+ } else { -+ send_text(TEXT_LINE0, TEXT_NORMAL, s, ustmtext("Calling...", s)); -+ } - } else { -- send_text(TEXT_LINE0, TEXT_NORMAL, s, "Calling :"); -+ send_text(TEXT_LINE0, TEXT_NORMAL, s, ustmtext("Calling :", s)); - send_text(TEXT_LINE1, TEXT_NORMAL, s, s->device->phone_number); -- send_text(TEXT_LINE2, TEXT_NORMAL, s, "Dialing..."); -+ send_text(TEXT_LINE2, TEXT_NORMAL, s, ustmtext("Dialing...", s)); - } -- send_text_status(s, "Hangup"); -+ send_text_status(s, ustmtext("Hangup", s)); - - /* start switch */ - if (ast_pthread_create(&t, NULL, unistim_ss, c)) { -- display_last_error("Unable to create switch thread"); -+ ast_log(LOG_WARNING, "Unable to create switch thread\n"); - ast_queue_hangup_with_cause(c, AST_CAUSE_SWITCH_CONGESTION); - } - } else - ast_log(LOG_WARNING, "Unable to create channel for %s@%s\n", - sub->parent->name, s->device->name); -- } else { /* We already have a call, so we switch in a threeway call */ -- -- if (s->device->moh) { -- struct unistim_subchannel *subchannel; -- struct unistim_line *p = s->device->lines; -- subchannel = p->subs[SUB_REAL]; -- -- if (!subchannel->owner) { -- ast_log(LOG_WARNING, "Unable to find subchannel for music on hold\n"); -- return; -- } -- if (p->subs[SUB_THREEWAY]) { -- ast_log(LOG_WARNING, -- "Can't transfer while an another transfer is taking place\n"); -- return; -- } -- if (!alloc_sub(p, SUB_THREEWAY)) { -- ast_log(LOG_WARNING, "Unable to allocate three-way subchannel\n"); -- return; -- } -- /* Stop the silence generator */ -- if (s->device->silence_generator) { -- if (unistimdebug) -- ast_verb(0, "Stopping silence generator\n"); -- ast_channel_stop_silence_generator(subchannel->owner, -- s->device->silence_generator); -- s->device->silence_generator = NULL; -- } -- send_tone(s, 0, 0); -- /* Make new channel */ -- c = unistim_new(p->subs[SUB_THREEWAY], AST_STATE_DOWN, NULL); -- if (!c) { -- ast_log(LOG_WARNING, "Cannot allocate new structure on channel %p\n", p); -- return; -- } -- /* Swap things around between the three-way and real call */ -- swap_subs(p, SUB_THREEWAY, SUB_REAL); -- send_select_output(s, s->device->output, s->device->volume, MUTE_OFF); -- -- if (s->device->height == 1) { -- send_text(TEXT_LINE0, TEXT_NORMAL, s, s->device->phone_number); -- } else { -- send_text(TEXT_LINE0, TEXT_NORMAL, s, "Calling (pre-transfer)"); -- send_text(TEXT_LINE1, TEXT_NORMAL, s, s->device->phone_number); -- send_text(TEXT_LINE2, TEXT_NORMAL, s, "Dialing..."); -- } -- send_text_status(s, "TransfrCancel"); -- -- if (ast_pthread_create(&t, NULL, unistim_ss, p->subs[SUB_THREEWAY]->owner)) { -- ast_log(LOG_WARNING, "Unable to start simple switch on channel %p\n", p); -- ast_hangup(c); -- return; -- } -- if (unistimdebug) -- ast_verb(0, "Started three way call on channel %p (%s) subchan %d\n", -- p->subs[SUB_THREEWAY]->owner, p->subs[SUB_THREEWAY]->owner->name, -- p->subs[SUB_THREEWAY]->subtype); -- } else -- ast_debug(1, "Current sub [%s] already has owner\n", sub->owner->name); -+ } else { -+ ast_debug(1, "Current sub [%s] already has owner\n", sub->owner->name); - } - return; - } - - /* From PBX to phone */ --static void HandleCallIncoming(struct unistimsession *s) -+static void handle_call_incoming(struct unistimsession *s) - { -- struct unistim_subchannel *sub; -+ struct unistim_subchannel *sub = NULL; -+ int i; -+ - s->state = STATE_CALL; - s->device->missed_call = 0; - send_no_ring(s); -- sub = s->device->lines->subs[SUB_REAL]; -+ sub = get_sub(s->device, SUB_RING); /* Put other SUB_REAL call on hold */ - if (!sub) { -- ast_log(LOG_NOTICE, "No available lines on: %s\n", s->device->name); -+ ast_log(LOG_WARNING, "No ringing lines on: %s\n", s->device->name); - return; -- } else if (unistimdebug) -+ } -+ /* Change icons for all ringing keys */ -+ for (i = 0; i < FAVNUM; i++) { -+ if (!s->device->ssub[i]) /* No sub assigned - skip */ -+ continue; -+ if (s->device->ssub[i]->subtype == SUB_REAL) -+ sub_hold(s, s->device->ssub[i]); -+ if (s->device->ssub[i] != sub) -+ continue; -+ if (sub->softkey == i) /* If softkey assigned at this moment - do not erase */ -+ continue; -+ if (sub->softkey < 0) { /* If softkey not defined - first one used */ -+ sub->softkey = i; -+ continue; -+ } -+ send_favorite_short(i, FAV_LINE_ICON, s); -+ s->device->ssub[i] = NULL; -+ } -+ if (sub->softkey < 0) { -+ ast_log(LOG_WARNING, "Can not assign softkey for incoming call on: %s\n", s->device->name); -+ return; -+ } -+ send_favorite_short(sub->softkey, FAV_ICON_OFFHOOK_BLACK, s); -+ sub->parent = s->device->sline[sub->softkey]; -+ sub->subtype = SUB_REAL; -+ if (unistimdebug) - ast_verb(0, "Handle Call Incoming for %s@%s\n", sub->parent->name, - s->device->name); - start_rtp(sub); -@@ -2502,16 +3041,16 @@ static void HandleCallIncoming(struct unistimsession * - ast_log(LOG_WARNING, "Unable to create channel for %s@%s\n", sub->parent->name, - s->device->name); - ast_queue_control(sub->owner, AST_CONTROL_ANSWER); -- send_text(TEXT_LINE2, TEXT_NORMAL, s, "is on-line"); -- send_text_status(s, "Hangup Transf"); -- send_start_timer(s); -+ send_text(TEXT_LINE2, TEXT_NORMAL, s, ustmtext("is on-line", s)); -+ send_text_status(s, ustmtext("Hangup Transf", s)); -+ send_start_timer_id(s, sub->softkey); - - if ((s->device->output == OUTPUT_HANDSET) && - (s->device->receiver_state == STATE_ONHOOK)) - send_select_output(s, OUTPUT_SPEAKER, s->device->volume, MUTE_OFF); - else - send_select_output(s, s->device->output, s->device->volume, MUTE_OFF); -- s->device->start_call_timestamp = time(0); -+ sub->start_call_timestamp = time(0); - write_history(s, 'i', 0); - return; - } -@@ -2520,8 +3059,10 @@ static int unistim_do_senddigit(struct unistimsession - { - struct ast_frame f = { .frametype = AST_FRAME_DTMF, .subclass.integer = digit, .src = "unistim" }; - struct unistim_subchannel *sub; -- sub = pte->device->lines->subs[SUB_REAL]; -- if (!sub->owner || sub->alreadygone) { -+ int row, col; -+ -+ sub = get_sub(pte->device, SUB_REAL); -+ if (!sub || !sub->owner || sub->alreadygone) { - ast_log(LOG_WARNING, "Unable to find subchannel in dtmf senddigit\n"); - return -1; - } -@@ -2531,65 +3072,80 @@ static int unistim_do_senddigit(struct unistimsession - - if (unistimdebug) - ast_verb(0, "Send Digit %c\n", digit); -- switch (digit) { -- case '0': -- send_tone(pte, 941, 1336); -- break; -- case '1': -- send_tone(pte, 697, 1209); -- break; -- case '2': -- send_tone(pte, 697, 1336); -- break; -- case '3': -- send_tone(pte, 697, 1477); -- break; -- case '4': -- send_tone(pte, 770, 1209); -- break; -- case '5': -- send_tone(pte, 770, 1336); -- break; -- case '6': -- send_tone(pte, 770, 1477); -- break; -- case '7': -- send_tone(pte, 852, 1209); -- break; -- case '8': -- send_tone(pte, 852, 1336); -- break; -- case '9': -- send_tone(pte, 852, 1477); -- break; -- case 'A': -- send_tone(pte, 697, 1633); -- break; -- case 'B': -- send_tone(pte, 770, 1633); -- break; -- case 'C': -- send_tone(pte, 852, 1633); -- break; -- case 'D': -- send_tone(pte, 941, 1633); -- break; -- case '*': -- send_tone(pte, 941, 1209); -- break; -- case '#': -- send_tone(pte, 941, 1477); -- break; -- default: -- send_tone(pte, 500, 2000); -- } -+ -+ row = (digit-'1')%3; -+ col = (digit-'1'-row)/3; -+ if (digit >= '1' && digit <='9') -+ send_tone(pte, dtmf_row[row], dtmf_col[col]); -+ else if (digit >= 'A' && digit <= 'D') -+ send_tone(pte, dtmf_row[digit-'A'], dtmf_col[3]); -+ else if (digit == '*') -+ send_tone(pte, dtmf_row[3], dtmf_col[0]); -+ else if (digit == '0') -+ send_tone(pte, dtmf_row[3], dtmf_col[1]); -+ else if (digit == '#') -+ send_tone(pte, dtmf_row[3], dtmf_col[2]); -+ else -+ send_tone(pte, 500, 2000); -+ - usleep(150000); /* XXX Less than perfect, blocking an important thread is not a good idea */ - send_tone(pte, 0, 0); - return 0; - } - -+static void handle_key_fav(struct unistimsession *pte, char keycode) { -+ int keynum = keycode - KEY_FAV0; -+ struct unistim_subchannel *sub; -+ -+ sub = get_sub(pte->device, SUB_REAL); -+ -+ /* Make an action on selected favorite key */ -+ if (!pte->device->ssub[keynum]) { /* Key have no assigned call */ -+ send_favorite_selected(FAV_LINE_ICON, pte); -+ if (is_key_line(pte->device, keynum)) { -+ if (unistimdebug) -+ ast_verb(0, "Handle line w/o sub - dialpage\n"); -+ pte->device->selected = keynum; -+ sub_hold(pte, sub); /* Put active call on hold */ -+ send_stop_timer(pte); -+ handle_dial_page(pte); -+ } else if (is_key_favorite(pte->device, keynum)) { -+ /* Put active call on hold in handle_call_outgoing function, after preparation and -+ checking if lines available for calling */ -+ if (unistimdebug) -+ ast_verb(0, "Handle favorite w/o sub - dialing\n"); -+ if ((pte->device->output == OUTPUT_HANDSET) && -+ (pte->device->receiver_state == STATE_ONHOOK)) -+ send_select_output(pte, OUTPUT_SPEAKER, pte->device->volume, MUTE_OFF); -+ else -+ send_select_output(pte, pte->device->output, pte->device->volume, MUTE_OFF); -+ -+ key_favorite(pte, keycode); -+ } -+ } else { -+ sub = pte->device->ssub[keynum]; -+ /* Favicon have assigned sub, activate it and put current on hold */ -+ if (sub->subtype == SUB_REAL) { -+ sub_hold(pte, sub); -+ show_main_page(pte); -+ } else if (sub->subtype == SUB_RING) { -+ sub->softkey = keynum; -+ handle_call_incoming(pte); -+ } else if (sub->subtype == SUB_ONHOLD) { -+ if (pte->state == STATE_DIALPAGE){ -+ send_tone(pte, 0, 0); -+ } -+ send_callerid_screen(pte, sub); -+ //send_start_timer_id(pte, sub->softkey); -+ sub_unhold(pte, sub); -+ pte->state = STATE_CALL; -+ } -+ } -+} -+ - static void key_call(struct unistimsession *pte, char keycode) - { -+ struct unistim_subchannel *sub = NULL; - if ((keycode >= KEY_0) && (keycode <= KEY_SHARP)) { - if (keycode == KEY_SHARP) - keycode = '#'; -@@ -2606,9 +3162,17 @@ static void key_call(struct unistimsession *pte, char - close_call(pte); - break; - case KEY_FUNC2: -- TransferCallStep1(pte); -+ transfer_call_step1(pte); - break; -- case KEY_HEADPHN: -+ case KEY_FAV0: -+ case KEY_FAV1: -+ case KEY_FAV2: -+ case KEY_FAV3: -+ case KEY_FAV4: -+ case KEY_FAV5: -+ handle_key_fav(pte, keycode); -+ break; -+ case KEY_HEADPHN: - if (pte->device->output == OUTPUT_HEADPHONE) - send_select_output(pte, OUTPUT_HANDSET, pte->device->volume, MUTE_OFF); - else -@@ -2622,82 +3186,71 @@ static void key_call(struct unistimsession *pte, char - MUTE_OFF); - break; - case KEY_MUTE: -- if (!pte->device->moh) { -- if (pte->device->mute == MUTE_ON) -- send_select_output(pte, pte->device->output, pte->device->volume, MUTE_OFF); -- else -- send_select_output(pte, pte->device->output, pte->device->volume, MUTE_ON); -- break; -- } -+ sub = get_sub(pte->device, SUB_REAL); -+ if (!sub || !sub->owner) { -+ ast_log(LOG_WARNING, "Unable to find subchannel for music on hold\n"); -+ return; -+ } -+ if (!sub->moh) { -+ if (pte->device->mute == MUTE_ON) -+ send_select_output(pte, pte->device->output, pte->device->volume, MUTE_OFF); -+ else -+ send_select_output(pte, pte->device->output, pte->device->volume, MUTE_ON); -+ break; -+ } -+ break; - case KEY_ONHOLD: -- { -- struct unistim_subchannel *sub; -- struct ast_channel *bridgepeer = NULL; -- sub = pte->device->lines->subs[SUB_REAL]; -- if (!sub->owner) { -- ast_log(LOG_WARNING, "Unable to find subchannel for music on hold\n"); -- return; -- } -- if ((bridgepeer = ast_bridged_channel(sub->owner))) { -- if (pte->device->moh) { -- ast_moh_stop(bridgepeer); -- pte->device->moh = 0; -- send_select_output(pte, pte->device->output, pte->device->volume, -- MUTE_OFF); -- } else { -- ast_moh_start(bridgepeer, pte->device->lines->musicclass, NULL); -- pte->device->moh = 1; -- send_select_output(pte, pte->device->output, pte->device->volume, -- MUTE_ON); -- } -- } else -- ast_log(LOG_WARNING, -- "Unable to find peer subchannel for music on hold\n"); -- break; -- } -+ sub = get_sub(pte->device, SUB_REAL); -+ if (!sub) { -+ if(pte->device->ssub[pte->device->selected]) { -+ sub_hold(pte, pte->device->ssub[pte->device->selected]); -+ } -+ } else -+ sub_hold(pte, sub); -+ break; - } - return; - } - - static void key_ringing(struct unistimsession *pte, char keycode) - { -- if (keycode == KEY_FAV0 + pte->device->softkeylinepos) { -- HandleCallIncoming(pte); -- return; -- } - switch (keycode) { -+ case KEY_FAV0: -+ case KEY_FAV1: -+ case KEY_FAV2: -+ case KEY_FAV3: -+ case KEY_FAV4: -+ case KEY_FAV5: -+ handle_key_fav(pte, keycode); -+ break; - case KEY_HANGUP: - case KEY_FUNC4: -- IgnoreCall(pte); -+ ignore_call(pte); - break; - case KEY_FUNC1: -- HandleCallIncoming(pte); -+ handle_call_incoming(pte); - break; - } - return; - } - --static void Keyfavorite(struct unistimsession *pte, char keycode) -+static void key_favorite(struct unistimsession *pte, char keycode) - { -- int fav; -- -- if ((keycode < KEY_FAV1) && (keycode > KEY_FAV5)) { -- ast_log(LOG_WARNING, "It's not a favorite key\n"); -- return; -- } -- if (keycode == KEY_FAV0) -- return; -- fav = keycode - KEY_FAV0; -- if (pte->device->softkeyicon[fav] == 0) -- return; -+ int fav = keycode - KEY_FAV0; -+ if (!is_key_favorite(pte->device, fav)) { -+ ast_log(LOG_WARNING, "It's not a favorite key\n"); -+ return; -+ } - ast_copy_string(pte->device->phone_number, pte->device->softkeynumber[fav], - sizeof(pte->device->phone_number)); -- HandleCallOutgoing(pte); -+ handle_call_outgoing(pte); - return; - } - - static void key_dial_page(struct unistimsession *pte, char keycode) - { -+ struct unistim_subchannel *sub = get_sub(pte->device, SUB_REAL); -+ - if (keycode == KEY_FUNC3) { - if (pte->device->size_phone_number <= 1) - keycode = KEY_FUNC4; -@@ -2706,50 +3259,32 @@ static void key_dial_page(struct unistimsession *pte, - keycode = pte->device->phone_number[pte->device->size_phone_number] + 0x10; - } - } -+ if (keycode == KEY_SHARP && pte->device->sharp_dial == 1) { -+ keycode = KEY_FUNC1; -+ } - if ((keycode >= KEY_0) && (keycode <= KEY_SHARP)) { -- char tmpbuf[] = "Number : ..............."; -- int i = 0; -+ int i = pte->device->size_phone_number; - -- if (pte->device->size_phone_number >= 15) -- return; - if (pte->device->size_phone_number == 0) - send_tone(pte, 0, 0); -- while (i < pte->device->size_phone_number) { -- tmpbuf[i + 9] = pte->device->phone_number[i]; -- i++; -- } -- if (keycode == KEY_SHARP) -- keycode = '#'; -+ -+ if (keycode == KEY_SHARP) -+ keycode = '#'; - else if (keycode == KEY_STAR) - keycode = '*'; - else - keycode -= 0x10; -- tmpbuf[i + 9] = keycode; - pte->device->phone_number[i] = keycode; - pte->device->size_phone_number++; - pte->device->phone_number[i + 1] = 0; -- if (pte->device->height == 1) { -- send_text(TEXT_LINE0, TEXT_NORMAL, pte, tmpbuf); -- } else { -- send_text(TEXT_LINE2, TEXT_NORMAL, pte, tmpbuf); -- } -- send_blink_cursor(pte); -- send_cursor_pos(pte, (unsigned char) (TEXT_LINE2 + 0x0a + i)); -+ -+ show_phone_number(pte); - return; - } - if (keycode == KEY_FUNC4) { -- - pte->device->size_phone_number = 0; -- if (pte->device->height == 1) { -- send_text(TEXT_LINE0, TEXT_NORMAL, pte, "Number : ..............."); -- send_blink_cursor(pte); -- send_cursor_pos(pte, TEXT_LINE0 + 0x09); -- } else { -- send_text(TEXT_LINE2, TEXT_NORMAL, pte, "Number : ..............."); -- send_blink_cursor(pte); -- send_cursor_pos(pte, TEXT_LINE2 + 0x09); -- } -- return; -+ show_phone_number(pte); -+ return; - } - - if (pte->device->call_forward[0] == -1) { -@@ -2759,7 +3294,9 @@ static void key_dial_page(struct unistimsession *pte, - show_main_page(pte); - } else if ((keycode == KEY_FUNC2) || (keycode == KEY_HANGUP)) { - pte->device->call_forward[0] = '\0'; -- show_main_page(pte); -+ send_led_update(pte, 0x08); -+ send_led_update(pte, 0x10); -+ show_main_page(pte); - } - return; - } -@@ -2770,40 +3307,43 @@ static void key_dial_page(struct unistimsession *pte, - ast_copy_string(pte->device->phone_number, pte->device->redial_number, - sizeof(pte->device->phone_number)); - case KEY_FUNC1: -- HandleCallOutgoing(pte); -+ handle_call_outgoing(pte); - break; - case KEY_HANGUP: -- if (pte->device->lines->subs[SUB_REAL]->owner) { -- /* Stop the silence generator */ -- if (pte->device->silence_generator) { -- if (unistimdebug) -- ast_verb(0, "Stopping silence generator\n"); -- ast_channel_stop_silence_generator(pte->device->lines->subs[SUB_REAL]-> -- owner, pte->device->silence_generator); -- pte->device->silence_generator = NULL; -- } -- send_tone(pte, 0, 0); -- ast_moh_stop(ast_bridged_channel(pte->device->lines->subs[SUB_REAL]->owner)); -- pte->device->moh = 0; -+ if (sub && sub->owner) { -+ struct ast_channel *bridgepeer = NULL; -+ -+ sub_stop_silence(pte, sub); -+ send_tone(pte, 0, 0); -+ if ((bridgepeer = ast_bridged_channel(sub->owner))) { -+ ast_moh_stop(bridgepeer); -+ } -+ get_sub(pte->device, SUB_REAL)->moh = 0; - pte->state = STATE_CALL; - - if (pte->device->height == 1) { -- send_text(TEXT_LINE0, TEXT_NORMAL, pte, "Dial Cancel,back to priv. call."); -+ send_text(TEXT_LINE0, TEXT_NORMAL, pte, ustmtext("Dial Cancel,back to priv. call.", pte)); - } else { -- send_text(TEXT_LINE0, TEXT_NORMAL, pte, "Dialing canceled,"); -- send_text(TEXT_LINE1, TEXT_NORMAL, pte, "switching back to"); -- send_text(TEXT_LINE2, TEXT_NORMAL, pte, "previous call."); -+ send_text(TEXT_LINE0, TEXT_NORMAL, pte, ustmtext("Dialing canceled,", pte)); -+ send_text(TEXT_LINE1, TEXT_NORMAL, pte, ustmtext("switching back to", pte)); -+ send_text(TEXT_LINE2, TEXT_NORMAL, pte, ustmtext("previous call.", pte)); - } -- send_text_status(pte, "Hangup Transf"); -- } else -+ send_text_status(pte, ustmtext("Hangup Transf", pte)); -+ } else { -+ send_led_update(pte, 0x08); -+ send_led_update(pte, 0x10); - show_main_page(pte); -+ } - break; -- case KEY_FAV1: -+ case KEY_FAV0: -+ case KEY_FAV1: - case KEY_FAV2: - case KEY_FAV3: - case KEY_FAV4: - case KEY_FAV5: -- Keyfavorite(pte, keycode); -+ send_favorite_selected(FAV_LINE_ICON, pte); -+ pte->device->selected = -1; -+ handle_key_fav(pte, keycode); - break; - case KEY_LOUDSPK: - if (pte->device->output == OUTPUT_SPEAKER) { -@@ -2828,16 +3368,56 @@ static void key_dial_page(struct unistimsession *pte, - return; - } - -+static void handle_select_option(struct unistimsession *pte) -+{ -+ char tmp[128]; -+ -+ if (pte->state != STATE_SELECTOPTION) { -+ pte->state = STATE_SELECTOPTION; -+ pte->size_buff_entry = 1; -+ pte->buff_entry[0] = 0; /* Position in menu */ -+ } -+ sprintf(tmp, "%d. %s", pte->buff_entry[0] + 1, ustmtext(options_menu[(int)pte->buff_entry[0]].label, pte)); -+ send_text(TEXT_LINE0, TEXT_NORMAL, pte, tmp); -+ send_text_status(pte, ustmtext("Select Cancel", pte)); -+ return; -+} -+ -+static void key_select_option(struct unistimsession *pte, char keycode) -+{ -+ switch (keycode) { -+ case KEY_DOWN: -+ pte->buff_entry[0]++; -+ if (options_menu[(int)pte->buff_entry[0]].label == NULL) -+ pte->buff_entry[0]--; -+ break; -+ case KEY_UP: -+ if (pte->buff_entry[0] > 0) -+ pte->buff_entry[0]--; -+ break; -+ case KEY_FUNC1: -+ options_menu[(int)pte->buff_entry[0]].handle_option(pte); -+ return; -+ case KEY_HANGUP: -+ case KEY_FUNC4: -+ show_main_page(pte); -+ return; -+ } -+ -+ handle_select_option(pte); -+ return; -+} -+ - #define SELECTCODEC_START_ENTRY_POS 15 - #define SELECTCODEC_MAX_LENGTH 2 - #define SELECTCODEC_MSG "Codec number : .." --static void HandleSelectCodec(struct unistimsession *pte) -+static void handle_select_codec(struct unistimsession *pte) - { - char buf[30], buf2[5]; - - pte->state = STATE_SELECTCODEC; -- strcpy(buf, "Using codec "); -- sprintf(buf2, "%d", pte->device->codec_number); -+ strcpy(buf, ustmtext("Using codec", pte)); -+ sprintf(buf2, " %d", pte->device->codec_number); - strcat(buf, buf2); - strcat(buf, " (G711u=0,"); - -@@ -2847,7 +3427,7 @@ static void HandleSelectCodec(struct unistimsession *p - send_blink_cursor(pte); - send_cursor_pos(pte, TEXT_LINE2 + SELECTCODEC_START_ENTRY_POS); - pte->size_buff_entry = 0; -- send_text_status(pte, "Select BackSpcErase Cancel"); -+ send_text_status(pte, ustmtext("Select BackSp Erase Cancel", pte)); - return; - } - -@@ -2905,19 +3485,110 @@ static void key_select_codec(struct unistimsession *pt - return; - } - -+static void handle_select_contrast(struct unistimsession *pte) -+{ -+ return; -+} -+ -+static void key_select_contrast(struct unistimsession *pte, char keycode) -+{ -+ switch (keycode) { -+ case KEY_DOWN: -+ pte->buff_entry[0]++; -+ break; -+ case KEY_UP: -+ if (pte->buff_entry[0] > 0) -+ pte->buff_entry[0]--; -+ break; -+ case KEY_FUNC1: -+ show_main_page(pte); -+ return; -+ case KEY_HANGUP: -+ case KEY_FUNC4: -+ handle_select_option(pte); -+ return; -+ } -+ -+ handle_select_contrast(pte); -+ return; -+} -+ -+static int find_language(const char* lang) -+{ -+ int i = 0; -+ while (options_languages[i].lang_short != NULL) { -+ if(!strcmp(options_languages[i].lang_short, lang)) -+ return i; -+ i++; -+ } -+ return 0; -+} -+ -+static void handle_select_language(struct unistimsession *pte) -+{ -+ char tmp_language[40]; -+ struct unistim_languages lang; -+ -+ if (pte->state != STATE_SELECTLANGUAGE) { -+ pte->state = STATE_SELECTLANGUAGE; -+ pte->size_buff_entry = 1; -+ pte->buff_entry[0] = find_language(pte->device->language); -+ } -+ lang = options_languages[(int)pte->buff_entry[0]]; -+ strcpy(tmp_language, pte->device->language); -+ strcpy(pte->device->language, lang.lang_short); -+ send_charset_update(pte, lang.encoding); -+ send_text(TEXT_LINE0, TEXT_NORMAL, pte, ustmtext(lang.label, pte)); -+ -+ strcpy(pte->device->language, tmp_language); -+ lang = options_languages[find_language(pte->device->language)]; -+ send_charset_update(pte, lang.encoding); -+ send_text_status(pte, ustmtext("Select Cancel", pte)); -+ return; -+} -+ -+static void key_select_language(struct unistimsession *pte, char keycode) -+{ -+ switch (keycode) { -+ case KEY_DOWN: -+ pte->buff_entry[0]++; -+ if (options_languages[(int)pte->buff_entry[0]].label == NULL) -+ pte->buff_entry[0]--; -+ break; -+ case KEY_UP: -+ if (pte->buff_entry[0] > 0) -+ pte->buff_entry[0]--; -+ break; -+ case KEY_FUNC1: -+ ast_copy_string(pte->device->language, options_languages[(int)pte->buff_entry[0]].lang_short, sizeof(pte->device->language)); -+ send_charset_update(pte, options_languages[(int)pte->buff_entry[0]].encoding); -+ refresh_all_favorite(pte); -+ show_main_page(pte); -+ return; -+ case KEY_HANGUP: -+ case KEY_FUNC4: -+ handle_select_option(pte); -+ return; -+ } -+ -+ handle_select_language(pte); -+ return; -+} -+ -+ - #define SELECTEXTENSION_START_ENTRY_POS 0 - #define SELECTEXTENSION_MAX_LENGTH 10 - #define SELECTEXTENSION_MSG ".........." --static void ShowExtensionPage(struct unistimsession *pte) -+static void show_extension_page(struct unistimsession *pte) - { - pte->state = STATE_EXTENSION; - -- send_text(TEXT_LINE0, TEXT_NORMAL, pte, "Please enter a Terminal"); -- send_text(TEXT_LINE1, TEXT_NORMAL, pte, "Number (TN) :"); -+ send_text(TEXT_LINE0, TEXT_NORMAL, pte, ustmtext("Please enter a Terminal", pte)); -+ send_text(TEXT_LINE1, TEXT_NORMAL, pte, ustmtext("Number (TN) :", pte)); - send_text(TEXT_LINE2, TEXT_NORMAL, pte, SELECTEXTENSION_MSG); - send_blink_cursor(pte); - send_cursor_pos(pte, TEXT_LINE2 + SELECTEXTENSION_START_ENTRY_POS); -- send_text_status(pte, "Enter BackSpcErase"); -+ send_text_status(pte, ustmtext("Enter BackSpcErase", pte)); - pte->size_buff_entry = 0; - return; - } -@@ -2989,8 +3660,8 @@ static void key_select_extension(struct unistimsession - d = d->next; - } - ast_mutex_unlock(&devicelock); -- send_text(TEXT_LINE0, TEXT_NORMAL, pte, "Invalid Terminal Number."); -- send_text(TEXT_LINE1, TEXT_NORMAL, pte, "Please try again :"); -+ send_text(TEXT_LINE0, TEXT_NORMAL, pte, ustmtext("Invalid Terminal Number.", pte)); -+ send_text(TEXT_LINE1, TEXT_NORMAL, pte, ustmtext("Please try again :", pte)); - send_cursor_pos(pte, - (unsigned char) (TEXT_LINE2 + SELECTEXTENSION_START_ENTRY_POS + - pte->size_buff_entry)); -@@ -2998,9 +3669,9 @@ static void key_select_extension(struct unistimsession - } else { - ast_copy_string(pte->device->extension_number, pte->buff_entry, - pte->size_buff_entry + 1); -- if (RegisterExtension(pte)) { -- send_text(TEXT_LINE0, TEXT_NORMAL, pte, "Invalid extension."); -- send_text(TEXT_LINE1, TEXT_NORMAL, pte, "Please try again :"); -+ if (register_extension(pte)) { -+ send_text(TEXT_LINE0, TEXT_NORMAL, pte, ustmtext("Invalid extension.", pte)); -+ send_text(TEXT_LINE1, TEXT_NORMAL, pte, ustmtext("Please try again :", pte)); - send_cursor_pos(pte, - (unsigned char) (TEXT_LINE2 + - SELECTEXTENSION_START_ENTRY_POS + -@@ -3020,12 +3691,13 @@ static void key_select_extension(struct unistimsession - return; - } - --static int ReformatNumber(char *number) -+static int reformat_number(char *number) - { - int pos = 0, i = 0, size = strlen(number); - - for (; i < size; i++) { -- if ((number[i] >= '0') && (number[i] <= '9')) { -+ if (((number[i] >= '0') && (number[i] <= '9')) || -+ (number[i] == '*') || (number[i] == '#')) { - if (i == pos) { - pos++; - continue; -@@ -3049,22 +3721,37 @@ static void show_entry_history(struct unistimsession * - return; - } - line[sizeof(line) - 1] = '\0'; -- send_text(TEXT_LINE0, TEXT_NORMAL, pte, line); -- if (fread(line, TEXT_LENGTH_MAX, 1, *f) != 1) { -+ if (pte->device->height == 1) { -+ if (pte->buff_entry[3] == 1) -+ send_text(TEXT_LINE0, TEXT_NORMAL, pte, line); -+ } else { -+ send_text(TEXT_LINE0, TEXT_NORMAL, pte, line); -+ } -+ if (fread(line, TEXT_LENGTH_MAX, 1, *f) != 1) { - display_last_error("Can't read callerid entry"); - fclose(*f); - return; - } - line[sizeof(line) - 1] = '\0'; - ast_copy_string(pte->device->lst_cid, line, sizeof(pte->device->lst_cid)); -- send_text(TEXT_LINE1, TEXT_NORMAL, pte, line); -- if (fread(line, TEXT_LENGTH_MAX, 1, *f) != 1) { -+ if (pte->device->height == 1) { -+ if (pte->buff_entry[3] == 2) -+ send_text(TEXT_LINE0, TEXT_NORMAL, pte, line); -+ } else { -+ send_text(TEXT_LINE1, TEXT_NORMAL, pte, line); -+ } -+ if (fread(line, TEXT_LENGTH_MAX, 1, *f) != 1) { - display_last_error("Can't read callername entry"); - fclose(*f); - return; - } - line[sizeof(line) - 1] = '\0'; -- send_text(TEXT_LINE2, TEXT_NORMAL, pte, line); -+ if (pte->device->height == 1) { -+ if (pte->buff_entry[3] == 3) -+ send_text(TEXT_LINE0, TEXT_NORMAL, pte, line); -+ } else { -+ send_text(TEXT_LINE2, TEXT_NORMAL, pte, line); -+ } - fclose(*f); - - snprintf(line, sizeof(line), "Call %03d/%03d", pte->buff_entry[2], -@@ -3074,20 +3761,20 @@ static void show_entry_history(struct unistimsession * - if (pte->buff_entry[2] == 1) - strcpy(func1, " "); - else -- strcpy(func1, "Prvious"); -+ strcpy(func1, ustmtext("Prev ", pte)); - if (pte->buff_entry[2] >= pte->buff_entry[1]) - strcpy(func2, " "); - else -- strcpy(func2, "Next "); -- if (ReformatNumber(pte->device->lst_cid)) -- strcpy(func3, "Redial "); -+ strcpy(func2, ustmtext("Next ", pte)); -+ if (reformat_number(pte->device->lst_cid)) -+ strcpy(func3, ustmtext("Redial ", pte)); - else - strcpy(func3, " "); -- snprintf(status, sizeof(status), "%s%s%sCancel", func1, func2, func3); -+ snprintf(status, sizeof(status), ustmtext("%s%s%sCancel", pte), func1, func2, func3); - send_text_status(pte, status); - } - --static char OpenHistory(struct unistimsession *pte, char way, FILE ** f) -+static char open_history(struct unistimsession *pte, char way, FILE ** f) - { - char tmp[AST_CONFIG_MAX_PATH]; - char count; -@@ -3122,12 +3809,13 @@ static void show_history(struct unistimsession *pte, c - return; - if (!pte->device->callhistory) - return; -- count = OpenHistory(pte, way, &f); -+ count = open_history(pte, way, &f); - if (!count) - return; - pte->buff_entry[0] = way; - pte->buff_entry[1] = count; - pte->buff_entry[2] = 1; -+ pte->buff_entry[3] = 1; - show_entry_history(pte, &f); - pte->state = STATE_HISTORY; - } -@@ -3135,60 +3823,73 @@ static void show_history(struct unistimsession *pte, c - static void show_main_page(struct unistimsession *pte) - { - char tmpbuf[TEXT_LENGTH_MAX + 1]; -+ const char *text; - -- - if ((pte->device->extension == EXTENSION_ASK) && - (ast_strlen_zero(pte->device->extension_number))) { -- ShowExtensionPage(pte); -+ show_extension_page(pte); - return; - } - - pte->state = STATE_MAINPAGE; - - send_tone(pte, 0, 0); -+ send_stop_timer(pte); /* case of holding call */ - send_select_output(pte, pte->device->output, pte->device->volume, MUTE_ON_DISCRET); -- pte->device->lines->lastmsgssent = 0; -- send_favorite(pte->device->softkeylinepos, FAV_ICON_ONHOOK_BLACK, pte, -- pte->device->softkeylabel[pte->device->softkeylinepos]); -+ send_led_update(pte, 0x08); -+ send_led_update(pte, 0x10); -+ get_main_line(pte->device)->lastmsgssent = 0; - if (!ast_strlen_zero(pte->device->call_forward)) { - if (pte->device->height == 1) { -- send_text(TEXT_LINE0, TEXT_NORMAL, pte, "Forwarding ON"); -+ char tmp_field[100]; -+ sprintf(tmp_field, ustmtext("Fwd to: %s", pte), pte->device->call_forward); -+ send_text(TEXT_LINE0, TEXT_NORMAL, pte, tmp_field); - } else { -- send_text(TEXT_LINE0, TEXT_NORMAL, pte, "Call forwarded to :"); -+ send_text(TEXT_LINE0, TEXT_NORMAL, pte, ustmtext("Call forwarded to :", pte)); - send_text(TEXT_LINE1, TEXT_NORMAL, pte, pte->device->call_forward); - } -- Sendicon(TEXT_LINE0, FAV_ICON_REFLECT + FAV_BLINK_SLOW, pte); -- send_text_status(pte, "Dial Redial NoForwd"); -+ send_icon(TEXT_LINE0, FAV_ICON_REFLECT + FAV_BLINK_SLOW, pte); -+ send_text_status(pte, ustmtext("Dial Redial NoFwd ", pte)); - } else { - if ((pte->device->extension == EXTENSION_ASK) || - (pte->device->extension == EXTENSION_TN)) -- send_text_status(pte, "Dial Redial ForwardUnregis"); -+ send_text_status(pte, ustmtext("Dial Recal Fwd Unregis", pte)); - else -- send_text_status(pte, "Dial Redial Forward"); -+ send_text_status(pte, ustmtext("Dial Recal Fwd Pickup", pte)); - - send_text(TEXT_LINE1, TEXT_NORMAL, pte, pte->device->maintext1); -- if (pte->device->missed_call == 0) -- send_text(TEXT_LINE0, TEXT_NORMAL, pte, pte->device->maintext0); -- else { -- sprintf(tmpbuf, "%d unanswered call(s)", pte->device->missed_call); -- send_text(TEXT_LINE0, TEXT_NORMAL, pte, tmpbuf); -- Sendicon(TEXT_LINE0, FAV_ICON_CALL_CENTER + FAV_BLINK_SLOW, pte); -+ if (pte->device->missed_call == 0) { -+ send_date_time2(pte); -+ send_idle_clock(pte); -+ if (strlen(pte->device->maintext0)) -+ send_text(TEXT_LINE0, TEXT_NORMAL, pte, pte->device->maintext0); -+ } else { -+ if (pte->device->missed_call == 1) -+ text = ustmtext("%d unanswered call", pte); -+ else -+ text = ustmtext("%d unanswered calls", pte); -+ sprintf(tmpbuf, text, pte->device->missed_call); -+ send_text(TEXT_LINE0, TEXT_NORMAL, pte, tmpbuf); -+ send_icon(TEXT_LINE0, FAV_ICON_CALL_CENTER + FAV_BLINK_SLOW, pte); - } - } -- if (ast_strlen_zero(pte->device->maintext2)) { -- strcpy(tmpbuf, "IP : "); -- strcat(tmpbuf, ast_inet_ntoa(pte->sin.sin_addr)); -- send_text(TEXT_LINE2, TEXT_NORMAL, pte, tmpbuf); -- } else -- send_text(TEXT_LINE2, TEXT_NORMAL, pte, pte->device->maintext2); -+ if (pte->device->height > 1) { -+ if (ast_strlen_zero(pte->device->maintext2)) { -+ strcpy(tmpbuf, "IP : "); -+ strcat(tmpbuf, ast_inet_ntoa(pte->sin.sin_addr)); -+ send_text(TEXT_LINE2, TEXT_NORMAL, pte, tmpbuf); -+ } else -+ send_text(TEXT_LINE2, TEXT_NORMAL, pte, pte->device->maintext2); -+ } -+ - send_texttitle(pte, pte->device->titledefault); -- change_favorite_icon(pte, FAV_ICON_ONHOOK_BLACK); -+ change_favorite_icon(pte, FAV_LINE_ICON); - } - - static void key_main_page(struct unistimsession *pte, char keycode) - { - if (pte->device->missed_call) { -- Sendicon(TEXT_LINE0, FAV_ICON_NONE, pte); -+ send_icon(TEXT_LINE0, FAV_ICON_NONE, pte); - pte->device->missed_call = 0; - } - if ((keycode >= KEY_0) && (keycode <= KEY_SHARP)) { -@@ -3198,6 +3899,7 @@ static void key_main_page(struct unistimsession *pte, - } - switch (keycode) { - case KEY_FUNC1: -+ pte->device->selected = get_avail_softkey(pte, NULL); - handle_dial_page(pte); - break; - case KEY_FUNC2: -@@ -3211,7 +3913,7 @@ static void key_main_page(struct unistimsession *pte, - - ast_copy_string(pte->device->phone_number, pte->device->redial_number, - sizeof(pte->device->phone_number)); -- HandleCallOutgoing(pte); -+ handle_call_outgoing(pte); - break; - case KEY_FUNC3: - if (!ast_strlen_zero(pte->device->call_forward)) { -@@ -3219,7 +3921,7 @@ static void key_main_page(struct unistimsession *pte, - memmove(pte->device->call_forward + 1, pte->device->call_forward, - sizeof(pte->device->call_forward)); - pte->device->call_forward[0] = '\0'; -- Sendicon(TEXT_LINE0, FAV_ICON_NONE, pte); -+ send_icon(TEXT_LINE0, FAV_ICON_NONE, pte); - pte->device->output = OUTPUT_HANDSET; /* Seems to be reseted somewhere */ - show_main_page(pte); - break; -@@ -3229,9 +3931,9 @@ static void key_main_page(struct unistimsession *pte, - break; - case KEY_FUNC4: - if (pte->device->extension == EXTENSION_ASK) { -- UnregisterExtension(pte); -+ unregister_extension(pte); - pte->device->extension_number[0] = '\0'; -- ShowExtensionPage(pte); -+ show_extension_page(pte); - } else if (pte->device->extension == EXTENSION_TN) { - ast_mutex_lock(&devicelock); - strcpy(pte->device->id, pte->device->extension_number); -@@ -3240,26 +3942,25 @@ static void key_main_page(struct unistimsession *pte, - pte->device->session = NULL; - pte->device = NULL; - ast_mutex_unlock(&devicelock); -- ShowExtensionPage(pte); -- } -+ show_extension_page(pte); -+ } else { /* Pickup function */ -+ pte->device->selected = -1; -+ ast_copy_string(pte->device->phone_number, ast_pickup_ext(), -+ sizeof(pte->device->phone_number)); -+ handle_call_outgoing(pte); -+ -+ } - break; -- case KEY_FAV0: -- handle_dial_page(pte); -- break; -+ case KEY_FAV0: - case KEY_FAV1: - case KEY_FAV2: - case KEY_FAV3: - case KEY_FAV4: - case KEY_FAV5: -- if ((pte->device->output == OUTPUT_HANDSET) && -- (pte->device->receiver_state == STATE_ONHOOK)) -- send_select_output(pte, OUTPUT_SPEAKER, pte->device->volume, MUTE_OFF); -- else -- send_select_output(pte, pte->device->output, pte->device->volume, MUTE_OFF); -- Keyfavorite(pte, keycode); -+ handle_key_fav(pte, keycode); - break; - case KEY_CONF: -- HandleSelectCodec(pte); -+ handle_select_option(pte); - break; - case KEY_LOUDSPK: - send_select_output(pte, OUTPUT_SPEAKER, pte->device->volume, MUTE_OFF); -@@ -3284,44 +3985,41 @@ static void key_history(struct unistimsession *pte, ch - FILE *f; - char count; - long offset; -+ int flag = 0; - - switch (keycode) { -+ case KEY_LEFT: -+ if (pte->device->height == 1) { -+ if (pte->buff_entry[3] <= 1) -+ return; -+ pte->buff_entry[3]--; -+ flag = 1; -+ break; -+ } - case KEY_UP: -- case KEY_LEFT: - case KEY_FUNC1: - if (pte->buff_entry[2] <= 1) - return; - pte->buff_entry[2]--; -- count = OpenHistory(pte, pte->buff_entry[0], &f); -- if (!count) -- return; -- offset = ((pte->buff_entry[2] - 1) * TEXT_LENGTH_MAX * 3); -- if (fseek(f, offset, SEEK_CUR)) { -- display_last_error("Unable to seek history entry."); -- fclose(f); -- return; -- } -- show_entry_history(pte, &f); -+ flag = 1; - break; -- case KEY_DOWN: -- case KEY_RIGHT: -+ case KEY_RIGHT: -+ if (pte->device->height == 1) { -+ if (pte->buff_entry[3] == 3) -+ return; -+ pte->buff_entry[3]++; -+ flag = 1; -+ break; -+ } -+ case KEY_DOWN: - case KEY_FUNC2: - if (pte->buff_entry[2] >= pte->buff_entry[1]) - return; - pte->buff_entry[2]++; -- count = OpenHistory(pte, pte->buff_entry[0], &f); -- if (!count) -- return; -- offset = ((pte->buff_entry[2] - 1) * TEXT_LENGTH_MAX * 3); -- if (fseek(f, offset, SEEK_CUR)) { -- display_last_error("Unable to seek history entry."); -- fclose(f); -- return; -- } -- show_entry_history(pte, &f); -+ flag = 1; - break; - case KEY_FUNC3: -- if (!ReformatNumber(pte->device->lst_cid)) -+ if (!reformat_number(pte->device->lst_cid)) - break; - ast_copy_string(pte->device->redial_number, pte->device->lst_cid, - sizeof(pte->device->redial_number)); -@@ -3344,6 +4042,20 @@ static void key_history(struct unistimsession *pte, ch - show_history(pte, 'i'); - break; - } -+ -+ if (flag) { -+ count = open_history(pte, pte->buff_entry[0], &f); -+ if (!count) -+ return; -+ offset = ((pte->buff_entry[2] - 1) * TEXT_LENGTH_MAX * 3); -+ if (fseek(f, offset, SEEK_CUR)) { -+ display_last_error("Unable to seek history entry."); -+ fclose(f); -+ return; -+ } -+ show_entry_history(pte, &f); -+ } -+ - return; - } - -@@ -3354,7 +4066,7 @@ static void init_phone_step2(struct unistimsession *pt - ast_verb(0, "Sending S4\n"); - memcpy(buffsend + SIZE_HEADER, packet_send_s4, sizeof(packet_send_s4)); - send_client(SIZE_HEADER + sizeof(packet_send_s4), buffsend, pte); -- send_date_time2(pte); -+ send_date_time2(pte); - send_date_time3(pte); - if (unistimdebug) - ast_verb(0, "Sending S7\n"); -@@ -3379,9 +4091,13 @@ static void init_phone_step2(struct unistimsession *pt - send_client(SIZE_HEADER + sizeof(packet_send_S7), buffsend, pte); - send_led_update(pte, 0); - send_ping(pte); -- if (pte->state < STATE_MAINPAGE) { -+ if (unistimdebug) -+ ast_verb(0, "Sending init language\n"); -+ send_charset_update(pte, options_languages[find_language(pte->device->language)].encoding); -+ -+ if (pte->state < STATE_MAINPAGE) { - if (autoprovisioning == AUTOPROVISIONING_TN) { -- ShowExtensionPage(pte); -+ show_extension_page(pte); - return; - } else { - int i; -@@ -3389,8 +4105,8 @@ static void init_phone_step2(struct unistimsession *pt - - for (i = 1; i < 6; i++) - send_favorite(i, 0, pte, ""); -- send_text(TEXT_LINE0, TEXT_NORMAL, pte, "Sorry, this phone is not"); -- send_text(TEXT_LINE1, TEXT_NORMAL, pte, "registered in unistim.cfg"); -+ send_text(TEXT_LINE0, TEXT_NORMAL, pte, ustmtext("Sorry, this phone is not", pte)); -+ send_text(TEXT_LINE1, TEXT_NORMAL, pte, ustmtext("registered in unistim.cfg", pte)); - strcpy(tmp, "MAC = "); - strcat(tmp, pte->macaddr); - send_text(TEXT_LINE2, TEXT_NORMAL, pte, tmp); -@@ -3444,8 +4160,8 @@ static void process_request(int size, unsigned char *b - char keycode = buf[13]; - - if (unistimdebug) -- ast_verb(0, "Key pressed : keycode = 0x%.2x - current state : %d\n", keycode, -- pte->state); -+ ast_verb(0, "Key pressed: keycode = 0x%.2x - current state: %s\n", keycode, -+ ptestate_tostr(pte->state)); - - switch (pte->state) { - case STATE_INIT: -@@ -3471,10 +4187,19 @@ static void process_request(int size, unsigned char *b - case STATE_EXTENSION: - key_select_extension(pte, keycode); - break; -+ case STATE_SELECTOPTION: -+ key_select_option(pte, keycode); -+ break; - case STATE_SELECTCODEC: - key_select_codec(pte, keycode); - break; -- case STATE_HISTORY: -+ case STATE_SELECTCONTRAST: -+ key_select_contrast(pte, keycode); -+ break; -+ case STATE_SELECTLANGUAGE: -+ key_select_language(pte, keycode); -+ break; -+ case STATE_HISTORY: - key_history(pte, keycode); - break; - default: -@@ -3492,13 +4217,15 @@ static void process_request(int size, unsigned char *b - send_select_output(pte, OUTPUT_HEADPHONE, pte->device->volume, MUTE_OFF); - else - send_select_output(pte, OUTPUT_HANDSET, pte->device->volume, MUTE_OFF); -- if (pte->state == STATE_RINGING) -- HandleCallIncoming(pte); -- else if ((pte->state == STATE_DIALPAGE) || (pte->state == STATE_CALL)) -+ if (pte->state == STATE_RINGING) { -+ handle_call_incoming(pte); -+ -+ } else if ((pte->state == STATE_DIALPAGE) || (pte->state == STATE_CALL)) - send_select_output(pte, OUTPUT_HANDSET, pte->device->volume, MUTE_OFF); - else if (pte->state == STATE_EXTENSION) /* We must have a TN before calling */ - return; - else { -+ pte->device->selected = get_avail_softkey(pte, NULL); - send_select_output(pte, OUTPUT_HANDSET, pte->device->volume, MUTE_OFF); - handle_dial_page(pte); - } -@@ -3512,7 +4239,7 @@ static void process_request(int size, unsigned char *b - pte->device->receiver_state = STATE_ONHOOK; - if (pte->state == STATE_CALL) - close_call(pte); -- else if (pte->device->lines->subs[SUB_REAL]->owner) -+ else if (get_sub(pte->device, SUB_REAL) && get_sub(pte->device, SUB_REAL)->owner) - close_call(pte); - else if (pte->state == STATE_EXTENSION) - return; -@@ -3710,13 +4437,52 @@ static struct unistimsession *channel_to_session(struc - return sub->parent->parent->session; - } - -+static void send_callerid_screen(struct unistimsession *pte, struct unistim_subchannel *sub) { -+ char *cidname_str; -+ char *cidnum_str; -+ -+ if (!sub) -+ return; -+ if (sub->owner) { -+ if (sub->owner->connected.id.number.valid && sub->owner->connected.id.number.str) { -+ cidnum_str = sub->owner->connected.id.number.str; -+ } else { -+ cidnum_str = DEFAULTCALLERID; -+ } -+ change_callerid(pte, 0, cidnum_str); -+ if (strlen(cidnum_str) == 0) { -+ cidnum_str = DEFAULTCALLERID; -+ } -+ -+ if (sub->owner->connected.id.name.valid && sub->owner->connected.id.name.str) { -+ cidname_str = sub->owner->connected.id.name.str; -+ } else { -+ cidname_str = DEFAULTCALLERNAME; -+ } -+ change_callerid(pte, 1, cidname_str); -+ if (strlen(cidname_str) == 0) { -+ cidname_str = DEFAULTCALLERNAME; -+ } -+ -+ if (pte->device->height == 1) { -+ char tmpstr[256]; -+ sprintf(tmpstr, "%s %s", cidnum_str, ustmtext(cidname_str, pte)); -+ send_text(TEXT_LINE0, TEXT_NORMAL, pte, tmpstr); -+ } else { -+ send_text(TEXT_LINE0, TEXT_NORMAL, pte, cidname_str); -+ send_text(TEXT_LINE1, TEXT_NORMAL, pte, ustmtext(cidnum_str, pte)); -+ } -+ } -+} -+ - /*--- unistim_call: Initiate UNISTIM call from PBX ---*/ - /* used from the dial() application */ - static int unistim_call(struct ast_channel *ast, char *dest, int timeout) - { -- int res = 0; -- struct unistim_subchannel *sub; -+ int res = 0, i; -+ struct unistim_subchannel *sub, *sub_real; - struct unistimsession *session; -+ char ringstyle, ringvolume; - - session = channel_to_session(ast); - if (!session) { -@@ -3725,6 +4491,7 @@ static int unistim_call(struct ast_channel *ast, char - } - - sub = ast->tech_pvt; -+ sub_real = get_sub(session->device, SUB_REAL); - if ((ast->_state != AST_STATE_DOWN) && (ast->_state != AST_STATE_RESERVED)) { - ast_log(LOG_WARNING, "unistim_call called on %s, neither down nor reserved\n", - ast->name); -@@ -3735,58 +4502,49 @@ static int unistim_call(struct ast_channel *ast, char - ast_verb(3, "unistim_call(%s)\n", ast->name); - - session->state = STATE_RINGING; -- Sendicon(TEXT_LINE0, FAV_ICON_NONE, session); -+ //send_icon(TEXT_LINE0, FAV_ICON_NONE, session); - -- if (sub->owner) { -- if (sub->owner->connected.id.number.valid -- && sub->owner->connected.id.number.str) { -- if (session->device->height == 1) { -- send_text(TEXT_LINE0, TEXT_NORMAL, session, sub->owner->connected.id.number.str); -- } else { -- send_text(TEXT_LINE1, TEXT_NORMAL, session, sub->owner->connected.id.number.str); -- } -- change_callerid(session, 0, sub->owner->connected.id.number.str); -- } else { -- if (session->device->height == 1) { -- send_text(TEXT_LINE0, TEXT_NORMAL, session, DEFAULTCALLERID); -- } else { -- send_text(TEXT_LINE1, TEXT_NORMAL, session, DEFAULTCALLERID); -- } -- change_callerid(session, 0, DEFAULTCALLERID); -- } -- if (sub->owner->connected.id.name.valid -- && sub->owner->connected.id.name.str) { -- send_text(TEXT_LINE0, TEXT_NORMAL, session, sub->owner->connected.id.name.str); -- change_callerid(session, 1, sub->owner->connected.id.name.str); -- } else { -- send_text(TEXT_LINE0, TEXT_NORMAL, session, DEFAULTCALLERNAME); -- change_callerid(session, 1, DEFAULTCALLERNAME); -- } -- } -- send_text(TEXT_LINE2, TEXT_NORMAL, session, "is calling you."); -- send_text_status(session, "Accept Ignore"); -+ send_callerid_screen(session, sub); -+ if (!strlen(ast->call_forward)) { /* Send ring only if no call forward, otherwise short ring will apear */ -+ send_text(TEXT_LINE2, TEXT_NORMAL, session, ustmtext("is calling you.", session)); -+ send_text_status(session, ustmtext("Accept Ignore", session)); - -- if (sub->ringstyle == -1) -- send_ring(session, session->device->ringvolume, session->device->ringstyle); -- else { -- if (sub->ringvolume == -1) -- send_ring(session, session->device->ringvolume, sub->ringstyle); -- else -- send_ring(session, sub->ringvolume, sub->ringstyle); -- } -- change_favorite_icon(session, FAV_ICON_SPEAKER_ONHOOK_BLACK + FAV_BLINK_FAST); -- -- ast_setstate(ast, AST_STATE_RINGING); -- ast_queue_control(ast, AST_CONTROL_RINGING); -- return res; -+ if (sub_real) { -+ ringstyle = session->device->cwstyle; -+ ringvolume = session->device->cwvolume; -+ } else { -+ ringstyle = (sub->ringstyle == -1) ? session->device->ringstyle : sub->ringstyle; -+ ringvolume = (sub->ringvolume == -1) ? session->device->ringvolume : sub->ringvolume; -+ } -+ send_ring(session, ringvolume, ringstyle); -+ change_favorite_icon(session, FAV_ICON_SPEAKER_ONHOOK_BLACK + FAV_BLINK_FAST); -+ /* Send call identification to all */ -+ for (i = 0; i < FAVNUM; i++) { -+ if (!soft_key_visible(session->device, i)) -+ continue; -+ if (session->device->ssub[i]) -+ continue; -+ if (is_key_line(session->device, i) && !strcmp(sub->parent->name, session->device->sline[i]->name)) { -+ if (unistimdebug) -+ ast_verb(0, "Found softkey %d for line %s\n", i, sub->parent->name); -+ send_favorite_short(i, FAV_ICON_SPEAKER_ONHOOK_BLACK + FAV_BLINK_FAST, session); -+ session->device->ssub[i] = sub; -+ } -+ } -+ } -+ ast_setstate(ast, AST_STATE_RINGING); -+ ast_queue_control(ast, AST_CONTROL_RINGING); -+ return res; - } - - /*--- unistim_hangup: Hangup UNISTIM call */ - static int unistim_hangup(struct ast_channel *ast) - { -- struct unistim_subchannel *sub; -+ struct unistim_subchannel *sub = NULL, *sub_real = NULL, *sub_trans = NULL; - struct unistim_line *l; -- struct unistimsession *s; -+ struct unistim_device *d; -+ struct unistimsession *s; -+ int i; - - s = channel_to_session(ast); - sub = ast->tech_pvt; -@@ -3806,32 +4564,43 @@ static int unistim_hangup(struct ast_channel *ast) - return 0; - } - l = sub->parent; -+ d = s->device; - if (unistimdebug) - ast_verb(0, "unistim_hangup(%s) on %s@%s\n", ast->name, l->name, l->parent->name); -- -- if ((l->subs[SUB_THREEWAY]) && (sub->subtype == SUB_REAL)) { -+ sub_trans = get_sub(d, SUB_THREEWAY); -+ if (sub_trans && sub_trans->owner && (sub->subtype == SUB_REAL)) { // (sub->alreadygone == 0) - if (unistimdebug) -- ast_verb(0, "Real call disconnected while talking to threeway\n"); -+ ast_verb(0, "Threeway call disconnected, switching to real call\n"); -+ if (ast_bridged_channel(sub_trans->owner)) { -+ ast_moh_stop(ast_bridged_channel(sub_trans->owner)); -+ } -+ sub_trans->moh = 0; -+ sub_trans->subtype = SUB_REAL; -+ swap_subs(sub_trans, sub); -+ -+ ast_mutex_lock(&sub->lock); - sub->owner = NULL; - ast->tech_pvt = NULL; -+ ast_mutex_unlock(&sub->lock); -+ unalloc_sub(d, sub); - return 0; - } -- if ((l->subs[SUB_REAL]->owner) && (sub->subtype == SUB_THREEWAY) && -+ sub_real = get_sub(d, SUB_REAL); -+ if (sub_real && (sub_real->owner) && (sub->subtype == SUB_THREEWAY) && - (sub->alreadygone == 0)) { - if (unistimdebug) -- ast_verb(0, "threeway call disconnected, switching to real call\n"); -- send_text(TEXT_LINE0, TEXT_NORMAL, s, "Three way call canceled,"); -- send_text(TEXT_LINE1, TEXT_NORMAL, s, "switching back to"); -- send_text(TEXT_LINE2, TEXT_NORMAL, s, "previous call."); -- send_text_status(s, "Hangup Transf"); -- ast_moh_stop(ast_bridged_channel(l->subs[SUB_REAL]->owner)); -- swap_subs(l, SUB_THREEWAY, SUB_REAL); -- l->parent->moh = 0; -+ ast_verb(0, "Real call disconnected, stay in call\n"); -+ -+ send_text(TEXT_LINE0, TEXT_NORMAL, s, ustmtext("Three way call canceled", s)); -+ send_text(TEXT_LINE1, TEXT_NORMAL, s, ustmtext("switching back", s)); -+ send_text(TEXT_LINE2, TEXT_NORMAL, s, ustmtext("to previous call.", s)); -+ send_text_status(s, ustmtext("Hangup Transf", s)); -+ - ast_mutex_lock(&sub->lock); - sub->owner = NULL; - ast->tech_pvt = NULL; - ast_mutex_unlock(&sub->lock); -- unalloc_sub(l, SUB_THREEWAY); -+ unalloc_sub(d, sub); - return 0; - } - ast_mutex_lock(&sub->lock); -@@ -3839,34 +4608,26 @@ static int unistim_hangup(struct ast_channel *ast) - ast->tech_pvt = NULL; - sub->alreadygone = 0; - ast_mutex_unlock(&sub->lock); -- if (!s) { -- if (unistimdebug) -- ast_verb(0, "Asked to hangup channel not connected (no session)\n"); -- if (sub->rtp) { -- if (unistimdebug) -- ast_verb(0, "Destroying RTP session\n"); -- ast_rtp_instance_destroy(sub->rtp); -- sub->rtp = NULL; -- } -- return 0; -- } -+ - if (sub->subtype == SUB_REAL) { -- /* Stop the silence generator */ -- if (s->device->silence_generator) { -- if (unistimdebug) -- ast_verb(0, "Stopping silence generator\n"); -- if (sub->owner) -- ast_channel_stop_silence_generator(sub->owner, -- s->device->silence_generator); -- else -- ast_log(LOG_WARNING, -- "Trying to stop silence generator on a null channel !\n"); -- s->device->silence_generator = NULL; -- } -- } -- l->parent->moh = 0; -- send_no_ring(s); -- send_end_call(s); -+ sub_stop_silence(s, sub); -+ send_end_call(s); /* Send end call packet only if ending active call, in other way sound should be loosed */ -+ } else if (sub->subtype == SUB_RING) { -+ send_no_ring(s); -+ for (i = 0; i < FAVNUM; i++) { -+ if (!soft_key_visible(s->device, i)) -+ continue; -+ if (d->ssub[i] != sub) -+ continue; -+ if (is_key_line(d, i) && !strcmp(l->name, d->sline[i]->name)) { -+ send_favorite_short(i, FAV_LINE_ICON, s); -+ d->ssub[i] = NULL; -+ } -+ } -+ } -+ sub->moh = 0; -+ if (sub->softkey >= 0) -+ send_favorite_short(sub->softkey, FAV_LINE_ICON, s); - if (sub->rtp) { - if (unistimdebug) - ast_verb(0, "Destroying RTP session\n"); -@@ -3874,16 +4635,27 @@ static int unistim_hangup(struct ast_channel *ast) - sub->rtp = NULL; - } else if (unistimdebug) - ast_verb(0, "No RTP session to destroy\n"); -- if (l->subs[SUB_THREEWAY]) { -- if (unistimdebug) -- ast_verb(0, "Cleaning other subchannels\n"); -- unalloc_sub(l, SUB_THREEWAY); -- } -- if (s->state == STATE_RINGING) -- cancel_dial(s); -- else if (s->state == STATE_CALL) -- close_call(s); -- -+ /* Delete assign sub to softkey */ -+ for (i = 0; i < FAVNUM; i++) { -+ if (d->ssub[i] == sub) { -+ d->ssub[i] = NULL; -+ break; -+ } -+ } -+ if (unistimdebug) -+ ast_verb(0, "Closing call while state STATE_%s\n", ptestate_tostr(s->state)); -+ if (s->state == STATE_RINGING && sub->subtype == SUB_RING) { -+ send_no_ring(s); -+ d->missed_call++; -+ write_history(s, 'i', 1); -+ if (!sub_real) -+ show_main_page(s); -+ } -+ if (s->state == STATE_CALL && sub->subtype == SUB_REAL) { -+ close_call(s); -+ } -+ sub->softkey = -1; -+ unalloc_sub(d, sub); - return 0; - } - -@@ -3893,6 +4665,7 @@ static int unistim_answer(struct ast_channel *ast) - int res = 0; - struct unistim_subchannel *sub; - struct unistim_line *l; -+ struct unistim_device *d; - struct unistimsession *s; - - s = channel_to_session(ast); -@@ -3902,18 +4675,19 @@ static int unistim_answer(struct ast_channel *ast) - } - sub = ast->tech_pvt; - l = sub->parent; -+ d = l->parent; - -- if ((!sub->rtp) && (!l->subs[SUB_THREEWAY])) -+ if ((!sub->rtp) && (!get_sub(d, SUB_THREEWAY))) - start_rtp(sub); - if (unistimdebug) - ast_verb(0, "unistim_answer(%s) on %s@%s-%d\n", ast->name, l->name, -- l->parent->name, sub->subtype); -- send_text(TEXT_LINE2, TEXT_NORMAL, l->parent->session, "is now on-line"); -- if (l->subs[SUB_THREEWAY]) -- send_text_status(l->parent->session, "Transf Cancel"); -+ l->parent->name, sub->softkey); -+ send_text(TEXT_LINE2, TEXT_NORMAL, s, ustmtext("is now on-line", s)); -+ if (get_sub(d, SUB_THREEWAY)) -+ send_text_status(s, ustmtext("Transf Cancel", s)); - else -- send_text_status(l->parent->session, "Hangup Transf"); -- send_start_timer(l->parent->session); -+ send_text_status(s, ustmtext("Hangup Transf", s)); -+ send_start_timer(s); - if (ast->_state != AST_STATE_UP) - ast_setstate(ast, AST_STATE_UP); - return res; -@@ -4051,14 +4825,16 @@ static int unistim_write(struct ast_channel *ast, stru - return 0; - } - } else { -- if (!(frame->subclass.codec & ast->nativeformats)) { -+ if (!(frame->subclass.codec & ast->nativeformats)) { - char tmp[256]; - ast_log(LOG_WARNING, -- "Asked to transmit frame type %s, while native formats is %s (read/write = (%s/%s)\n", -+ "Asked to transmit frame type %s, while native formats is %s (read/write = (%s/%s)) (raw read/write = (%s/%s))\n", - ast_getformatname(frame->subclass.codec), - ast_getformatname_multiple(tmp, sizeof(tmp), ast->nativeformats), - ast_getformatname(ast->readformat), -- ast_getformatname(ast->writeformat)); -+ ast_getformatname(ast->writeformat), -+ ast_getformatname(ast->rawwriteformat), -+ ast_getformatname(ast->rawreadformat)); - return -1; - } - } -@@ -4127,7 +4903,13 @@ static char *control2str(int ind) - return "Key Radio"; - case AST_CONTROL_RADIO_UNKEY: - return "Un-Key Radio"; -- case -1: -+ case AST_CONTROL_CONNECTED_LINE: -+ return "Remote end changed"; -+ case AST_CONTROL_SRCCHANGE: -+ return "RTP source updated"; -+ case AST_CONTROL_SRCUPDATE: -+ return "Source of media changed"; -+ case -1: - return "Stop tone"; - } - return "UNKNOWN"; -@@ -4154,8 +4936,8 @@ static int unistim_indicate(struct ast_channel *ast, i - struct unistimsession *s; - - if (unistimdebug) { -- ast_verb(3, "Asked to indicate '%s' condition on channel %s\n", -- control2str(ind), ast->name); -+ ast_verb(3, "Asked to indicate '%s' (%d) condition on channel %s\n", -+ control2str(ind), ind, ast->name); - } - - s = channel_to_session(ast); -@@ -4168,7 +4950,7 @@ static int unistim_indicate(struct ast_channel *ast, i - switch (ind) { - case AST_CONTROL_RINGING: - if (ast->_state != AST_STATE_UP) { -- send_text(TEXT_LINE2, TEXT_NORMAL, s, "Ringing..."); -+ send_text(TEXT_LINE2, TEXT_NORMAL, s, ustmtext("Ringing...", s)); - in_band_indication(ast, l->parent->tz, "ring"); - s->device->missed_call = -1; - break; -@@ -4177,7 +4959,7 @@ static int unistim_indicate(struct ast_channel *ast, i - case AST_CONTROL_BUSY: - if (ast->_state != AST_STATE_UP) { - sub->alreadygone = 1; -- send_text(TEXT_LINE2, TEXT_NORMAL, s, "Busy"); -+ send_text(TEXT_LINE2, TEXT_NORMAL, s, ustmtext("Busy", s)); - in_band_indication(ast, l->parent->tz, "busy"); - s->device->missed_call = -1; - break; -@@ -4190,7 +4972,7 @@ static int unistim_indicate(struct ast_channel *ast, i - case AST_CONTROL_CONGESTION: - if (ast->_state != AST_STATE_UP) { - sub->alreadygone = 1; -- send_text(TEXT_LINE2, TEXT_NORMAL, s, "Congestion"); -+ send_text(TEXT_LINE2, TEXT_NORMAL, s, ustmtext("Congestion", s)); - in_band_indication(ast, l->parent->tz, "congestion"); - s->device->missed_call = -1; - break; -@@ -4204,13 +4986,23 @@ static int unistim_indicate(struct ast_channel *ast, i - break; - case AST_CONTROL_PROGRESS: - case AST_CONTROL_SRCUPDATE: -+ case AST_CONTROL_PROCEEDING: - break; - case -1: - ast_playtones_stop(ast); - s->device->missed_call = 0; - break; -- case AST_CONTROL_PROCEEDING: -- break; -+ case AST_CONTROL_CONNECTED_LINE: -+ ast_log(LOG_NOTICE, "Connected party is now %s <%s>\n", -+ S_COR(ast->connected.id.name.valid, ast->connected.id.name.str, ""), -+ S_COR(ast->connected.id.number.valid, ast->connected.id.number.str, "")); -+ if (sub->subtype == SUB_REAL) { -+ send_callerid_screen(s, sub); -+ } -+ break; -+ case AST_CONTROL_SRCCHANGE: -+ ast_rtp_instance_change_source(sub->rtp); -+ break; - default: - ast_log(LOG_WARNING, "Don't know how to indicate condition %d\n", ind); - return -1; -@@ -4223,6 +5015,7 @@ static struct unistim_subchannel *find_subchannel_by_n - { - struct unistim_line *l; - struct unistim_device *d; -+ struct unistim_subchannel *sub = NULL; - char line[256]; - char *at; - char *device; -@@ -4246,12 +5039,22 @@ static struct unistim_subchannel *find_subchannel_by_n - if (unistimdebug) - ast_verb(0, "Found device: %s\n", d->name); - /* Found the device */ -- l = d->lines; -- while (l) { -+ AST_LIST_LOCK(&d->lines); -+ AST_LIST_TRAVERSE(&d->lines, l, list) { - /* Search for the right line */ - if (!strcasecmp(l->name, line)) { -- l->subs[SUB_REAL]->ringvolume = -1; -- l->subs[SUB_REAL]->ringstyle = -1; -+ if (unistimdebug) -+ ast_verb(0, "Found line: %s\n", l->name); -+ sub = get_sub(d, SUB_REAL); -+ if (!sub) { -+ sub = alloc_sub(d, SUB_REAL); -+ } -+ if (sub->owner) { -+ /* Allocate additional channel if asterisk channel already here */ -+ sub = alloc_sub(d, SUB_ONHOLD); -+ } -+ sub->ringvolume = -1; -+ sub->ringstyle = -1; - if (at) { /* Other options ? */ - at++; /* Skip slash */ - if (*at == 'r') { /* distinctive ring */ -@@ -4267,16 +5070,20 @@ static struct unistim_subchannel *find_subchannel_by_n - if (unistimdebug) - ast_verb(0, "Distinctive ring : style #%d volume %d\n", - ring_style, ring_volume); -- l->subs[SUB_REAL]->ringvolume = ring_volume; -- l->subs[SUB_REAL]->ringstyle = ring_style; -+ sub->ringvolume = ring_volume; -+ sub->ringstyle = ring_style; - } - } - } -- ast_mutex_unlock(&devicelock); -- return l->subs[SUB_REAL]; -+ sub->parent = l; -+ break; - } -- l = l->next; - } -+ AST_LIST_UNLOCK(&d->lines); -+ if (sub) { -+ ast_mutex_unlock(&devicelock); -+ return sub; -+ } - } - d = d->next; - } -@@ -4302,9 +5109,9 @@ static int unistim_senddigit_end(struct ast_channel *a - struct ast_frame f = { 0, }; - struct unistim_subchannel *sub; - -- sub = pte->device->lines->subs[SUB_REAL]; -+ sub = get_sub(pte->device, SUB_REAL); - -- if (!sub->owner || sub->alreadygone) { -+ if (!sub || !sub->owner || sub->alreadygone) { - ast_log(LOG_WARNING, "Unable to find subchannel in dtmf senddigit_end\n"); - return -1; - } -@@ -4437,7 +5244,7 @@ static int unistim_sendtext(struct ast_channel *ast, c - if (pte->device->height == 1) { - send_text(TEXT_LINE0, TEXT_NORMAL, pte, text); - } else { -- send_text(TEXT_LINE0, TEXT_NORMAL, pte, "Message :"); -+ send_text(TEXT_LINE0, TEXT_NORMAL, pte, ustmtext("Message :", pte)); - send_text(TEXT_LINE1, TEXT_NORMAL, pte, text); - } - if (size <= TEXT_LENGTH_MAX) { -@@ -4465,7 +5272,7 @@ static int unistim_send_mwi_to_peer(struct unistimsess - struct ast_event *event; - int new; - char *mailbox, *context; -- struct unistim_line *peer = s->device->lines; -+ struct unistim_line *peer = get_main_line(s->device); - - context = mailbox = ast_strdupa(peer->mailbox); - strsep(&context, "@"); -@@ -4519,9 +5326,9 @@ static struct ast_channel *unistim_new(struct unistim_ - } - l = sub->parent; - tmp = ast_channel_alloc(1, state, l->cid_num, NULL, l->accountcode, l->exten, -- l->context, linkedid, l->amaflags, "%s@%s-%d", l->name, l->parent->name, sub->subtype); -+ l->context, linkedid, l->amaflags, "USTM/%s@%s-%p", l->name, l->parent->name, sub); - if (unistimdebug) -- ast_verb(0, "unistim_new sub=%d (%p) chan=%p\n", sub->subtype, sub, tmp); -+ ast_verb(0, "unistim_new sub=%d (%p) chan=%p line=%s\n", sub->subtype, sub, tmp, l->name); - if (!tmp) { - ast_log(LOG_WARNING, "Unable to allocate channel structure\n"); - return NULL; -@@ -4559,8 +5366,8 @@ static struct ast_channel *unistim_new(struct unistim_ - tmp->rawreadformat = fmt; - tmp->tech_pvt = sub; - tmp->tech = &unistim_tech; -- if (!ast_strlen_zero(l->language)) -- ast_string_field_set(tmp, language, l->language); -+ if (!ast_strlen_zero(l->parent->language)) -+ ast_string_field_set(tmp, language, l->parent->language); - sub->owner = tmp; - ast_mutex_lock(&usecnt_lock); - usecnt++; -@@ -4584,14 +5391,14 @@ static struct ast_channel *unistim_new(struct unistim_ - } - } - tmp->priority = 1; -- if (state != AST_STATE_DOWN) { -- if (unistimdebug) -- ast_verb(0, "Starting pbx in unistim_new\n"); -- if (ast_pbx_start(tmp)) { -- ast_log(LOG_WARNING, "Unable to start PBX on %s\n", tmp->name); -- ast_hangup(tmp); -- tmp = NULL; -- } -+ if (state != AST_STATE_DOWN) { -+ if (unistimdebug) -+ ast_verb(0, "Starting pbx in unistim_new\n"); -+ if (ast_pbx_start(tmp)) { -+ ast_log(LOG_WARNING, "Unable to start PBX on %s\n", tmp->name); -+ ast_hangup(tmp); -+ tmp = NULL; -+ } - } - - return tmp; -@@ -4640,8 +5447,8 @@ static void *do_monitor(void *data) - dw_timeout = cur->timeout - tick; - /* Checking if the phone is logged on for a new MWI */ - if (cur->device) { -- if ((!ast_strlen_zero(cur->device->lines->mailbox)) && -- ((tick >= cur->device->lines->nextmsgcheck))) { -+ if ((!ast_strlen_zero(get_main_line(cur->device)->mailbox)) && -+ ((tick >= get_main_line(cur->device)->nextmsgcheck))) { - DEBUG_TIMER("Checking mailbox for MWI\n"); - unistim_send_mwi_to_peer(cur, tick); - break; -@@ -4711,7 +5518,8 @@ static struct ast_channel *unistim_request(const char - int *cause) - { - format_t oldformat; -- struct unistim_subchannel *sub; -+ struct unistim_subchannel *sub, *sub_ring, *sub_trans; -+ struct unistim_device *d; - struct ast_channel *tmpc = NULL; - char tmp[256]; - char *dest = data; -@@ -4735,22 +5543,39 @@ static struct ast_channel *unistim_request(const char - ast_log(LOG_NOTICE, "Unistim channels require a device\n"); - return NULL; - } -- - sub = find_subchannel_by_name(tmp); - if (!sub) { - ast_log(LOG_NOTICE, "No available lines on: %s\n", dest); - *cause = AST_CAUSE_CONGESTION; - return NULL; - } -- -- ast_verb(3, "unistim_request(%s)\n", tmp); -- /* Busy ? */ -- if (sub->owner) { -+ d = sub->parent->parent; -+ sub_ring = get_sub(d, SUB_RING); -+ sub_trans = get_sub(d, SUB_THREEWAY); -+ /* Another request already in progress */ -+ if (!d->session) { -+ unalloc_sub(d, sub); -+ *cause = AST_CAUSE_CONGESTION; -+ return NULL; -+ } -+ if (sub_ring || sub_trans) { - if (unistimdebug) -- ast_verb(0, "Can't create channel : Busy !\n"); -+ ast_verb(0, "Can't create channel, request already in progress: Busy!\n"); -+ unalloc_sub(d, sub); - *cause = AST_CAUSE_BUSY; - return NULL; - } -+ if (get_avail_softkey(d->session, sub->parent->name) == -1) { -+ if (unistimdebug) -+ ast_verb(0, "Can't create channel for line %s, all lines busy\n", sub->parent->name); -+ unalloc_sub(d, sub); -+ *cause = AST_CAUSE_BUSY; -+ return NULL; -+ } -+ -+ ast_verb(3, "unistim_request(%s)\n", tmp); -+ sub->subtype = SUB_RING; -+ sub->softkey = -1; - sub->parent->capability = format; - tmpc = unistim_new(sub, AST_STATE_DOWN, requestor ? requestor->linkedid : NULL); - if (!tmpc) -@@ -4769,7 +5594,6 @@ static char *unistim_info(struct ast_cli_entry *e, int - struct unistim_line *line; - struct unistim_subchannel *sub; - struct unistimsession *s; -- int i; - struct ast_channel *tmp; - - switch (cmd) { -@@ -4787,44 +5611,55 @@ static char *unistim_info(struct ast_cli_entry *e, int - if (a->argc != e->args) - return CLI_SHOWUSAGE; - -- ast_cli(a->fd, "Dumping internal structures :\ndevice\n->line\n-->sub\n"); -+ ast_cli(a->fd, "Dumping internal structures :\ndevice\n->line\n-->sub\n==>key\n"); - while (device) { -- ast_cli(a->fd, "\nname=%s id=%s line=%p ha=%p sess=%p device=%p\n", -- device->name, device->id, device->lines, device->ha, device->session, -- device); -- line = device->lines; -- while (line) { -+ int i; -+ -+ ast_cli(a->fd, "\nname=%s id=%s ha=%p sess=%p device=%p selected=%d height=%d\n", -+ device->name, device->id, device->ha, device->session, -+ device, device->selected, device->height); -+ AST_LIST_LOCK(&device->lines); -+ AST_LIST_TRAVERSE(&device->lines,line,list) { - ast_cli(a->fd, -- "->name=%s fullname=%s exten=%s callid=%s cap=%" PRId64 " device=%p line=%p\n", -+ "->name=%s fullname=%s exten=%s callid=%s cap=%" PRId64 " line=%p\n", - line->name, line->fullname, line->exten, line->cid_num, -- line->capability, line->parent, line); -- for (i = 0; i < MAX_SUBS; i++) { -- sub = line->subs[i]; -- if (!sub) -- continue; -- if (!sub->owner) -- tmp = (void *) -42; -- else -- tmp = sub->owner->_bridge; -- if (sub->subtype != i) -- ast_cli(a->fd, "Warning ! subchannel->subs[%d] have a subtype=%d\n", i, -- sub->subtype); -- ast_cli(a->fd, -- "-->subtype=%d chan=%p rtp=%p bridge=%p line=%p alreadygone=%d\n", -- sub->subtype, sub->owner, sub->rtp, tmp, sub->parent, -- sub->alreadygone); -- } -- line = line->next; -+ line->capability, line); - } -- device = device->next; -+ AST_LIST_UNLOCK(&device->lines); -+ -+ AST_LIST_LOCK(&device->subs); -+ AST_LIST_TRAVERSE(&device->subs, sub, list) { -+ if (!sub) -+ continue; -+ if (!sub->owner) -+ tmp = (void *) -42; -+ else -+ tmp = sub->owner->_bridge; -+ ast_cli(a->fd, -+ "-->subtype=%s chan=%p rtp=%p bridge=%p line=%p alreadygone=%d softkey=%d\n", -+ subtype_tostr(sub->subtype), sub->owner, sub->rtp, tmp, sub->parent, -+ sub->alreadygone, sub->softkey); -+ } -+ AST_LIST_UNLOCK(&device->subs); -+ -+ for (i = 0; i < FAVNUM; i++) { -+ if (!soft_key_visible(device, i)) { -+ continue; -+ } -+ ast_cli(a->fd, "==> %d. dev=%s icon=%#x label=%-8s number=%-5s sub=%p line=%p\n", -+ i, device->softkeydevice[i], device->softkeyicon[i], device->softkeylabel[i], device->softkeynumber[i], -+ device->ssub[i], device->sline[i]); -+ } -+ -+ device = device->next; - } - ast_cli(a->fd, "\nSessions:\n"); - ast_mutex_lock(&sessionlock); - s = sessions; - while (s) { - ast_cli(a->fd, -- "sin=%s timeout=%u state=%d macaddr=%s device=%p session=%p\n", -- ast_inet_ntoa(s->sin.sin_addr), s->timeout, s->state, s->macaddr, -+ "sin=%s timeout=%u state=%s macaddr=%s device=%p session=%p\n", -+ ast_inet_ntoa(s->sin.sin_addr), s->timeout, ptestate_tostr(s->state), s->macaddr, - s->device, s); - s = s->next; - } -@@ -4982,7 +5817,7 @@ static void unquote(char *out, const char *src, int ma - return; - } - --static int ParseBookmark(const char *text, struct unistim_device *d) -+static int parse_bookmark(const char *text, struct unistim_device *d) - { - char line[256]; - char *at; -@@ -5057,7 +5892,7 @@ static int ParseBookmark(const char *text, struct unis - ast_copy_string(d->softkeylabel[p], line, sizeof(d->softkeylabel[p])); - ast_copy_string(d->softkeynumber[p], number, sizeof(d->softkeynumber[p])); - if (unistimdebug) -- ast_verb(0, "New bookmark at pos %d label='%s' number='%s' icon=%x\n", -+ ast_verb(0, "New bookmark at pos %d label='%s' number='%s' icon=%#x\n", - p, d->softkeylabel[p], d->softkeynumber[p], d->softkeyicon[p]); - return 1; - } -@@ -5088,15 +5923,29 @@ static void finish_bookmark(void) - } - } - -+static struct unistim_line *find_line_by_number(struct unistim_device *d, const char *val) { -+ struct unistim_line *l, *ret = NULL; -+ -+ AST_LIST_LOCK(&d->lines); -+ AST_LIST_TRAVERSE(&d->lines, l, list) { -+ if (!strcmp(l->name, val)) { -+ ret = l; -+ break; -+ } -+ } -+ AST_LIST_UNLOCK(&d->lines); -+ return ret; -+} -+ - static struct unistim_device *build_device(const char *cat, const struct ast_variable *v) - { - struct unistim_device *d; -- struct unistim_line *l = NULL; -+ struct unistim_line *l = NULL, *lt = NULL; - int create = 1; -- int nbsoftkey, dateformat, timeformat, callhistory; -+ int nbsoftkey, dateformat, timeformat, callhistory, sharpdial; - char linelabel[AST_MAX_EXTENSION]; - char context[AST_MAX_EXTENSION]; -- char ringvolume, ringstyle; -+ char ringvolume, ringstyle, cwvolume, cwstyle; - - /* First, we need to know if we already have this name in our list */ - /* Get a lock for the device chained list */ -@@ -5113,22 +5962,39 @@ static struct unistim_device *build_device(const char - } - /* we're reloading right now */ - create = 0; -- l = d->lines; -+ /* l = d->lines;*/ - break; - } - d = d->next; - } -+ if (!(lt = ast_calloc(1, sizeof(*lt)))) { -+ return NULL; -+ } - ast_mutex_unlock(&devicelock); - if (create) { - if (!(d = ast_calloc(1, sizeof(*d)))) - return NULL; -+ ast_copy_string(d->name, cat, sizeof(d->name)); -+ } else { -+ /* Delete existing line information */ -+ AST_LIST_LOCK(&d->lines); -+ AST_LIST_TRAVERSE_SAFE_BEGIN(&d->lines, l, list){ -+ AST_LIST_REMOVE_CURRENT(list); -+ ast_free(l); -+ } -+ AST_LIST_TRAVERSE_SAFE_END -+ AST_LIST_UNLOCK(&d->lines); -+ } - -- if (!(l = ast_calloc(1, sizeof(*l)))) { -- ast_free(d); -- return NULL; -- } -- ast_copy_string(d->name, cat, sizeof(d->name)); -- } -+ /* reset bookmarks */ -+ memset(d->softkeylabel, 0, sizeof(d->softkeylabel)); -+ memset(d->softkeynumber, 0, sizeof(d->softkeynumber)); -+ memset(d->softkeyicon, 0, sizeof(d->softkeyicon)); -+ memset(d->softkeydevice, 0, sizeof(d->softkeydevice)); -+ memset(d->ssub, 0, sizeof(d->ssub)); -+ memset(d->sline, 0, sizeof(d->sline)); -+ memset(d->sp, 0, sizeof(d->sp)); -+ - ast_copy_string(context, DEFAULTCONTEXT, sizeof(context)); - d->contrast = -1; - d->output = OUTPUT_HANDSET; -@@ -5136,12 +6002,16 @@ static struct unistim_device *build_device(const char - d->volume = VOLUME_LOW; - d->mute = MUTE_OFF; - d->height = DEFAULTHEIGHT; -+ d->selected = -1; - linelabel[0] = '\0'; - dateformat = 1; - timeformat = 1; - ringvolume = 2; -+ cwvolume = 1; - callhistory = 1; -+ sharpdial = 0; - ringstyle = 3; -+ cwstyle = 2; - nbsoftkey = 0; - while (v) { - if (!strcasecmp(v->name, "rtp_port")) -@@ -5182,19 +6052,25 @@ static struct unistim_device *build_device(const char - ringvolume = atoi(v->value); - else if (!strcasecmp(v->name, "ringstyle")) - ringstyle = atoi(v->value); -- else if (!strcasecmp(v->name, "callhistory")) -+ else if (!strcasecmp(v->name, "cwvolume")) -+ cwvolume = atoi(v->value); -+ else if (!strcasecmp(v->name, "cwstyle")) -+ cwstyle = atoi(v->value); -+ else if (!strcasecmp(v->name, "callhistory")) - callhistory = atoi(v->value); -- else if (!strcasecmp(v->name, "callerid")) { -+ else if (!strcasecmp(v->name, "sharpdial")) { -+ sharpdial = ast_true(v->value) ? 1 : 0; -+ } else if (!strcasecmp(v->name, "callerid")) { - if (!strcasecmp(v->value, "asreceived")) -- l->cid_num[0] = '\0'; -+ lt->cid_num[0] = '\0'; - else -- ast_copy_string(l->cid_num, v->value, sizeof(l->cid_num)); -+ ast_copy_string(lt->cid_num, v->value, sizeof(lt->cid_num)); - } else if (!strcasecmp(v->name, "language")) -- ast_copy_string(l->language, v->value, sizeof(l->language)); -+ ast_copy_string(d->language, v->value, sizeof(d->language)); - else if (!strcasecmp(v->name, "country")) - ast_copy_string(d->country, v->value, sizeof(d->country)); - else if (!strcasecmp(v->name, "accountcode")) -- ast_copy_string(l->accountcode, v->value, sizeof(l->accountcode)); -+ ast_copy_string(lt->accountcode, v->value, sizeof(lt->accountcode)); - else if (!strcasecmp(v->name, "amaflags")) { - int y; - y = ast_cdr_amaflags2int(v->value); -@@ -5202,17 +6078,17 @@ static struct unistim_device *build_device(const char - ast_log(LOG_WARNING, "Invalid AMA flags: %s at line %d\n", v->value, - v->lineno); - else -- l->amaflags = y; -+ lt->amaflags = y; - } else if (!strcasecmp(v->name, "musiconhold")) -- ast_copy_string(l->musicclass, v->value, sizeof(l->musicclass)); -+ ast_copy_string(lt->musicclass, v->value, sizeof(lt->musicclass)); - else if (!strcasecmp(v->name, "callgroup")) -- l->callgroup = ast_get_group(v->value); -+ lt->callgroup = ast_get_group(v->value); - else if (!strcasecmp(v->name, "pickupgroup")) -- l->pickupgroup = ast_get_group(v->value); -+ lt->pickupgroup = ast_get_group(v->value); - else if (!strcasecmp(v->name, "mailbox")) -- ast_copy_string(l->mailbox, v->value, sizeof(l->mailbox)); -+ ast_copy_string(lt->mailbox, v->value, sizeof(lt->mailbox)); - else if (!strcasecmp(v->name, "parkinglot")) -- ast_copy_string(l->parkinglot, v->value, sizeof(l->parkinglot)); -+ ast_copy_string(lt->parkinglot, v->value, sizeof(lt->parkinglot)); - else if (!strcasecmp(v->name, "linelabel")) - unquote(linelabel, v->value, sizeof(linelabel) - 1); - else if (!strcasecmp(v->name, "extension")) { -@@ -5229,103 +6105,93 @@ static struct unistim_device *build_device(const char - ast_log(LOG_WARNING, - "More than 6 softkeys defined. Ignoring new entries.\n"); - else { -- if (ParseBookmark(v->value, d)) -+ if (parse_bookmark(v->value, d)) - nbsoftkey++; - } - } else if (!strcasecmp(v->name, "line")) { -- int len = strlen(linelabel); -+ int len = strlen(linelabel); -+ int create_line = 0; -+ -+ l = find_line_by_number(d, v->value); -+ if (!l) { /* If line still not exists */ -+ if (!(l = ast_calloc(1, sizeof(*l)))) { -+ ast_free(d); -+ return NULL; -+ } -+ memcpy(l, lt, sizeof(*l)); -+ ast_mutex_init(&l->lock); -+ create_line = 1; -+ } -+ d->to_delete = 0; - -- if (nbsoftkey) { -- ast_log(LOG_WARNING, -- "You must use bookmark AFTER line=>. Only one line is supported in this version\n"); -- if (create) { -- ast_free(d); -- ast_free(l); -- } -- return NULL; -- } -- if (create) { -- ast_mutex_init(&l->lock); -- } else { -- d->to_delete = 0; -- /* reset bookmarks */ -- memset(d->softkeylabel, 0, sizeof(d->softkeylabel)); -- memset(d->softkeynumber, 0, sizeof(d->softkeynumber)); -- memset(d->softkeyicon, 0, sizeof(d->softkeyicon)); -- memset(d->softkeydevice, 0, sizeof(d->softkeydevice)); -- memset(d->sp, 0, sizeof(d->sp)); -- } -- ast_copy_string(l->name, v->value, sizeof(l->name)); -- snprintf(l->fullname, sizeof(l->fullname), "USTM/%s@%s", l->name, d->name); -- d->softkeyicon[0] = FAV_ICON_ONHOOK_BLACK; -+ /* Set softkey info for new line*/ -+ d->sline[nbsoftkey] = l; -+ d->softkeyicon[nbsoftkey] = FAV_LINE_ICON; - if (!len) /* label is undefined ? */ -- ast_copy_string(d->softkeylabel[0], v->value, sizeof(d->softkeylabel[0])); -+ ast_copy_string(d->softkeylabel[nbsoftkey], v->value, sizeof(d->softkeylabel[nbsoftkey])); - else { -+ int softkeylinepos = 0; - if ((len > 2) && (linelabel[1] == '@')) { -- d->softkeylinepos = linelabel[0]; -- if ((d->softkeylinepos >= '0') && (d->softkeylinepos <= '5')) { -- d->softkeylinepos -= '0'; -- d->softkeyicon[0] = 0; -+ softkeylinepos = linelabel[0]; -+ if ((softkeylinepos >= '0') && (softkeylinepos <= '5')) { -+ softkeylinepos -= '0'; -+ d->softkeyicon[nbsoftkey] = FAV_ICON_NONE; - } else { - ast_log(LOG_WARNING, - "Invalid position for linelabel : must be between 0 and 5\n"); -- d->softkeylinepos = 0; - } -- ast_copy_string(d->softkeylabel[d->softkeylinepos], linelabel + 2, -- sizeof(d->softkeylabel[d->softkeylinepos])); -- d->softkeyicon[d->softkeylinepos] = FAV_ICON_ONHOOK_BLACK; -+ ast_copy_string(d->softkeylabel[softkeylinepos], linelabel + 2, -+ sizeof(d->softkeylabel[softkeylinepos])); -+ d->softkeyicon[softkeylinepos] = FAV_LINE_ICON; - } else -- ast_copy_string(d->softkeylabel[0], linelabel, -- sizeof(d->softkeylabel[0])); -+ ast_copy_string(d->softkeylabel[nbsoftkey], linelabel, -+ sizeof(d->softkeylabel[nbsoftkey])); - } - nbsoftkey++; -- ast_copy_string(l->context, context, sizeof(l->context)); -- if (!ast_strlen_zero(l->mailbox)) { -- if (unistimdebug) -- ast_verb(3, "Setting mailbox '%s' on %s@%s\n", l->mailbox, d->name, l->name); -- } -+ -+ if (create_line) { -+ ast_copy_string(l->name, v->value, sizeof(l->name)); -+ snprintf(l->fullname, sizeof(l->fullname), "USTM/%s@%s", l->name, d->name); -+ ast_copy_string(l->context, context, sizeof(l->context)); -+ if (!ast_strlen_zero(l->mailbox)) { -+ if (unistimdebug) -+ ast_verb(3, "Setting mailbox '%s' on %s@%s\n", l->mailbox, d->name, l->name); -+ } - -- l->capability = CAPABILITY; -- l->parent = d; -+ l->capability = CAPABILITY; -+ l->parent = d; - -- if (create) { -- if (!alloc_sub(l, SUB_REAL)) { -- ast_mutex_destroy(&l->lock); -- ast_free(l); -- ast_free(d); -- return NULL; -- } -- l->next = d->lines; -- d->lines = l; -- } -- } else if (!strcasecmp(v->name, "height")) { -+ AST_LIST_LOCK(&d->lines); -+ AST_LIST_INSERT_TAIL(&d->lines, l, list); -+ AST_LIST_UNLOCK(&d->lines); -+ } -+ -+ } else if (!strcasecmp(v->name, "height")) { - /* Allow the user to lower the expected display lines on the phone -- * For example the Nortal I2001 and I2002 only have one ! */ -+ * For example the Nortel i2001 and i2002 only have one ! */ - d->height = atoi(v->value); - } else - ast_log(LOG_WARNING, "Don't know keyword '%s' at line %d\n", v->name, - v->lineno); - v = v->next; - } -- d->ringvolume = ringvolume; -+ if (!get_main_line(d)) { -+ ast_log(LOG_ERROR, "An Unistim device must have at least one line!\n"); -+ ast_free(d); -+ return NULL; -+ } -+ d->ringvolume = ringvolume; - d->ringstyle = ringstyle; -- d->callhistory = callhistory; -+ d->cwvolume = cwvolume; -+ d->cwstyle = cwstyle; -+ d->callhistory = callhistory; -+ d->sharp_dial = sharpdial; - d->tz = ast_get_indication_zone(d->country); - if ((d->tz == NULL) && !ast_strlen_zero(d->country)) - ast_log(LOG_WARNING, "Country '%s' was not found in indications.conf\n", - d->country); - d->datetimeformat = 56 + (dateformat * 4); - d->datetimeformat += timeformat; -- if (!d->lines) { -- ast_log(LOG_ERROR, "An Unistim device must have at least one line!\n"); -- ast_mutex_destroy(&l->lock); -- ast_free(l); -- if (d->tz) { -- d->tz = ast_tone_zone_unref(d->tz); -- } -- ast_free(d); -- return NULL; -- } - if ((autoprovisioning == AUTOPROVISIONING_TN) && - (!ast_strlen_zero(d->extension_number))) { - d->extension = EXTENSION_TN; -@@ -5338,8 +6204,6 @@ static struct unistim_device *build_device(const char - } else if (ast_strlen_zero(d->id)) { - if (strcmp(d->name, "template")) { - ast_log(LOG_ERROR, "You must specify the mac address with device=\n"); -- ast_mutex_destroy(&l->lock); -- ast_free(l); - if (d->tz) { - d->tz = ast_tone_zone_unref(d->tz); - } -@@ -5352,8 +6216,6 @@ static struct unistim_device *build_device(const char - d->rtp_port = 10000; - if (d->contrast == -1) - d->contrast = 8; -- if (ast_strlen_zero(d->maintext0)) -- strcpy(d->maintext0, "Welcome"); - if (ast_strlen_zero(d->maintext1)) - strcpy(d->maintext1, d->name); - if (ast_strlen_zero(d->titledefault)) { -@@ -5361,7 +6223,7 @@ static struct unistim_device *build_device(const char - struct timeval cur_time = ast_tvnow(); - - if ((ast_localtime(&cur_time, &tm, 0)) == 0 || ast_strlen_zero(tm.tm_zone)) { -- display_last_error("Error in ast_localtime()"); -+ ast_log(LOG_WARNING, "Error in ast_localtime()"); - ast_copy_string(d->titledefault, "UNISTIM for*", 12); - } else { - if (strlen(tm.tm_zone) < 4) { -@@ -5439,8 +6301,13 @@ static int reload_config(void) - } else if (!strcasecmp(v->name, "cos_audio")) { - if (ast_str2cos(v->value, &qos.cos_audio)) - ast_log(LOG_WARNING, "Invalid cos_audio value at line %d, refer to QoS documentation\n", v->lineno); -- } else if (!strcasecmp(v->name, "autoprovisioning")) { -+ } else if (!strcasecmp(v->name, "debug")) { - if (!strcasecmp(v->value, "no")) -+ unistimdebug = 0; -+ else if (!strcasecmp(v->value, "yes")) -+ unistimdebug = 1; -+ } else if (!strcasecmp(v->name, "autoprovisioning")) { -+ if (!strcasecmp(v->value, "no")) - autoprovisioning = AUTOPROVISIONING_NO; - else if (!strcasecmp(v->value, "yes")) - autoprovisioning = AUTOPROVISIONING_YES; -@@ -5498,44 +6365,57 @@ static int reload_config(void) - d = devices; - while (d) { - if (d->to_delete) { -- int i; -+ struct unistim_line *l; -+ struct unistim_subchannel *sub; - - if (unistimdebug) - ast_verb(0, "Removing device '%s'\n", d->name); -- if (!d->lines) { -+ if (!get_main_line(d)) { - ast_log(LOG_ERROR, "Device '%s' without a line !, aborting\n", d->name); - ast_config_destroy(cfg); - return 0; - } -- if (!d->lines->subs[0]) { -- ast_log(LOG_ERROR, "Device '%s' without a subchannel !, aborting\n", -- d->name); -- ast_config_destroy(cfg); -- return 0; -- } -- if (d->lines->subs[0]->owner) { -- ast_log(LOG_WARNING, -- "Device '%s' was not deleted : a call is in progress. Try again later.\n", -- d->name); -- d = d->next; -- continue; -- } -- ast_mutex_destroy(&d->lines->subs[0]->lock); -- ast_free(d->lines->subs[0]); -- for (i = 1; i < MAX_SUBS; i++) { -- if (d->lines->subs[i]) { -- ast_log(LOG_WARNING, -- "Device '%s' with threeway call subchannels allocated, aborting.\n", -- d->name); -- break; -- } -- } -- if (i < MAX_SUBS) { -- d = d->next; -- continue; -- } -- ast_mutex_destroy(&d->lines->lock); -- ast_free(d->lines); -+ -+ AST_LIST_LOCK(&d->subs); -+ AST_LIST_TRAVERSE_SAFE_BEGIN(&d->subs, sub, list){ -+ if (sub->subtype == SUB_REAL) { -+ if (!sub) { -+ ast_log(LOG_ERROR, "Device '%s' without a subchannel !, aborting\n", -+ d->name); -+ ast_config_destroy(cfg); -+ return 0; -+ } -+ if (sub->owner) { -+ ast_log(LOG_WARNING, -+ "Device '%s' was not deleted : a call is in progress. Try again later.\n", -+ d->name); -+ d = d->next; -+ continue; -+ } -+ } -+ if (sub->subtype == SUB_THREEWAY) { -+ ast_log(LOG_WARNING, -+ "Device '%s' with threeway call subchannels allocated, aborting.\n", -+ d->name); -+ break; -+ } -+ AST_LIST_REMOVE_CURRENT(list); -+ ast_mutex_destroy(&sub->lock); -+ ast_free(sub); -+ } -+ AST_LIST_TRAVERSE_SAFE_END -+ AST_LIST_UNLOCK(&d->subs); -+ -+ -+ AST_LIST_LOCK(&d->lines); -+ AST_LIST_TRAVERSE_SAFE_BEGIN(&d->lines, l, list){ -+ AST_LIST_REMOVE_CURRENT(list); -+ ast_mutex_destroy(&l->lock); -+ ast_free(l); -+ } -+ AST_LIST_TRAVERSE_SAFE_END -+ AST_LIST_UNLOCK(&d->lines); -+ - if (d->session) { - if (sessions == d->session) - sessions = d->session->next; -@@ -5579,9 +6459,15 @@ static int reload_config(void) - ast_mutex_lock(&sessionlock); - s = sessions; - while (s) { -- if (s->device) -+ if (s->device) { - refresh_all_favorite(s); -- s = s->next; -+ if (ast_strlen_zero(s->device->language)) { -+ struct unistim_languages lang; -+ lang = options_languages[find_language(s->device->language)]; -+ send_charset_update(s, lang.encoding); -+ } -+ } -+ s = s->next; - } - ast_mutex_unlock(&sessionlock); - /* We don't recreate a socket when reloading (locks would be necessary). */ -@@ -5694,8 +6580,9 @@ buff_failed: - static int unload_module(void) - { - /* First, take us out of the channel loop */ -- if (sched) -+ if (sched) { - sched_context_destroy(sched); -+ } - - ast_cli_unregister_multiple(unistim_cli, ARRAY_LEN(unistim_cli)); - diff --git a/telephony/asterisk/patches/patch-configs_asterisk_conf_sample b/telephony/asterisk/patches/patch-configs_asterisk_conf_sample index 19de68223c0..f1eda83cd13 100644 --- a/telephony/asterisk/patches/patch-configs_asterisk_conf_sample +++ b/telephony/asterisk/patches/patch-configs_asterisk_conf_sample @@ -1,7 +1,7 @@ -$OpenBSD: patch-configs_asterisk_conf_sample,v 1.2 2011/05/11 15:07:15 sthen Exp $ ---- configs/asterisk.conf.sample.orig Tue Feb 8 20:22:35 2011 -+++ configs/asterisk.conf.sample Wed May 11 10:11:21 2011 -@@ -57,8 +57,8 @@ astlogdir => /var/log/asterisk +$OpenBSD: patch-configs_asterisk_conf_sample,v 1.3 2012/09/28 00:03:57 sthen Exp $ +--- configs/asterisk.conf.sample.orig Wed Dec 7 20:12:53 2011 ++++ configs/asterisk.conf.sample Thu Jan 5 19:41:24 2012 +@@ -58,8 +58,8 @@ astsbindir => /usr/sbin ; not otherwise require one. ;transcode_via_sln = yes ; Build transcode paths via SLINEAR, instead of ; directly. @@ -12,7 +12,7 @@ $OpenBSD: patch-configs_asterisk_conf_sample,v 1.2 2011/05/11 15:07:15 sthen Exp ;lightbackground = yes ; If your terminal is set for a light-colored ; background. ;forceblackbackground = yes ; Force the background of the terminal to be -@@ -75,11 +75,11 @@ documentation_language = en_US ; Set the language you +@@ -76,11 +76,11 @@ documentation_language = en_US ; Set the language you ; lock. ; Changing the following lines may compromise your security. diff --git a/telephony/asterisk/patches/patch-configs_res_odbc_conf_sample b/telephony/asterisk/patches/patch-configs_res_odbc_conf_sample new file mode 100644 index 00000000000..1e54e42f22c --- /dev/null +++ b/telephony/asterisk/patches/patch-configs_res_odbc_conf_sample @@ -0,0 +1,13 @@ +$OpenBSD: patch-configs_res_odbc_conf_sample,v 1.1 2012/09/28 00:03:57 sthen Exp $ +--- configs/res_odbc.conf.sample.orig Thu Sep 20 13:29:33 2012 ++++ configs/res_odbc.conf.sample Thu Sep 20 13:30:00 2012 +@@ -19,8 +19,7 @@ + ; If not specified, it is assumed the section is enabled. + enabled => no + ; +-; This value should match an entry in /etc/odbc.ini +-; (or /usr/local/etc/odbc.ini, on FreeBSD and similar systems). ++; This value should match an entry in /etc/iodbc/odbc.ini + dsn => asterisk + ; + ; Username for connecting to the database. The default user is "root". diff --git a/telephony/asterisk/patches/patch-configs_sip_conf_sample b/telephony/asterisk/patches/patch-configs_sip_conf_sample new file mode 100644 index 00000000000..eaf5bfb92df --- /dev/null +++ b/telephony/asterisk/patches/patch-configs_sip_conf_sample @@ -0,0 +1,18 @@ +$OpenBSD: patch-configs_sip_conf_sample,v 1.1 2012/09/28 00:03:57 sthen Exp $ +--- configs/sip.conf.sample.orig Thu Sep 20 14:02:08 2012 ++++ configs/sip.conf.sample Thu Sep 20 14:03:03 2012 +@@ -148,11 +148,11 @@ allowoverlap=no ; Disable overlap dial + ; a) Listen on a specific IPv4 address. Example: bindaddr=192.0.2.1 + ; b) Listen on a specific IPv6 address. Example: bindaddr=2001:db8::1 + ; c) Listen on the IPv4 wildcard. Example: bindaddr=0.0.0.0 +-; d) Listen on the IPv4 and IPv6 wildcards. Example: bindaddr=:: ++; d) Listen on the IPv6 wildcard. Example: bindaddr=:: + ; (You can choose independently for UDP, TCP, and TLS, by specifying different values for + ; "udpbindaddr", "tcpbindaddr", and "tlsbindaddr".) +-; (Note that using bindaddr=:: will show only a single IPv6 socket in netstat. +-; IPv4 is supported at the same time using IPv4-mapped IPv6 addresses.) ++; (Note that on OpenBSD, using bindaddr=:: will only allow IPv6 connections. ++; OpenBSD does *not* permit IPv4-mapped IPv6 addresses.) + ; + ; You may optionally add a port number. (The default is port 5060 for UDP and TCP, 5061 + ; for TLS). diff --git a/telephony/asterisk/patches/patch-configure_ac b/telephony/asterisk/patches/patch-configure_ac index a0617140a91..87e1e843548 100644 --- a/telephony/asterisk/patches/patch-configure_ac +++ b/telephony/asterisk/patches/patch-configure_ac @@ -1,7 +1,7 @@ -$OpenBSD: patch-configure_ac,v 1.25 2012/06/07 10:39:25 sthen Exp $ ---- configure.ac.orig Thu Apr 12 15:26:06 2012 -+++ configure.ac Wed Jun 6 21:57:10 2012 -@@ -55,7 +55,7 @@ AC_SUBST([astvarrundir], ['${localstatedir}/run/a +$OpenBSD: patch-configure_ac,v 1.26 2012/09/28 00:03:57 sthen Exp $ +--- configure.ac.orig Thu Apr 12 16:01:13 2012 ++++ configure.ac Tue Sep 18 23:44:17 2012 +@@ -59,7 +59,7 @@ AC_SUBST([astvarrundir], ['${localstatedir}/run/a case "${host_os}" in *bsd*) @@ -10,7 +10,7 @@ $OpenBSD: patch-configure_ac,v 1.25 2012/06/07 10:39:25 sthen Exp $ astvarlibdir='${prefix}/share/asterisk' astdbdir='${localstatedir}/db/asterisk' fi -@@ -1605,7 +1605,7 @@ if test "${USE_IMAP_TK}" != "no"; then +@@ -1617,7 +1617,7 @@ if test "${USE_IMAP_TK}" != "no"; then ) else #looking in imap directory didn't work, try c-client imap_ldflags="" @@ -19,7 +19,7 @@ $OpenBSD: patch-configure_ac,v 1.25 2012/06/07 10:39:25 sthen Exp $ imap_include="-DUSE_SYSTEM_CCLIENT" CPPFLAGS="${saved_cppflags}" LIBS="${saved_libs}" -@@ -1791,7 +1791,7 @@ AST_EXT_TOOL_CHECK([NETSNMP], [net-snmp-config], , [-- +@@ -1803,7 +1803,7 @@ AST_EXT_TOOL_CHECK([NETSNMP], [net-snmp-config], , [-- AST_EXT_LIB_CHECK([NEWT], [newt], [newtBell], [newt.h]) diff --git a/telephony/asterisk/patches/patch-contrib_scripts_safe_asterisk b/telephony/asterisk/patches/patch-contrib_scripts_safe_asterisk index 870ed3d92d9..4bf9f989b27 100644 --- a/telephony/asterisk/patches/patch-contrib_scripts_safe_asterisk +++ b/telephony/asterisk/patches/patch-contrib_scripts_safe_asterisk @@ -1,26 +1,26 @@ -$OpenBSD: patch-contrib_scripts_safe_asterisk,v 1.13 2011/07/12 19:54:39 sthen Exp $ +$OpenBSD: patch-contrib_scripts_safe_asterisk,v 1.14 2012/09/28 00:03:57 sthen Exp $ - more useful defaults - create /var/run/asterisk with sane ownership/perms ---- contrib/scripts/safe_asterisk.orig Thu May 5 16:04:24 2011 -+++ contrib/scripts/safe_asterisk Mon Jul 11 23:45:36 2011 -@@ -2,9 +2,9 @@ - # vim:textwidth=80:tabstop=4:shiftwidth=4:smartindent:autoindent +--- contrib/scripts/safe_asterisk.orig Thu May 5 16:06:59 2011 ++++ contrib/scripts/safe_asterisk Thu Jan 5 19:56:40 2012 +@@ -6,9 +6,9 @@ ASTVARRUNDIR=__ASTERISK_VARRUN_DIR__ + ASTVARLOGDIR=__ASTERISK_LOG_DIR__ - CLIARGS="$*" # Grab any args passed to safe_asterisk + CLIARGS="$*" # Grab any args passed to safe_asterisk -TTY=9 # TTY (if you want one) for Asterisk to run on -CONSOLE=yes # Whether or not you want a console --#NOTIFY=ben@alkaloid.net # Who to notify about crashes -+TTY="" # TTY (if you want one) for Asterisk to run on -+CONSOLE=no # Whether or not you want a console -+NOTIFY=root # Who to notify about crashes - #EXEC=/path/to/somescript # Run this command if Asterisk crashes - #LOGFILE=/path/to/logfile # Where to place the normal logfile (disabled if blank) - #SYSLOG=local0 # Which syslog facility to use (disabled if blank) -@@ -14,10 +14,11 @@ SLEEPSECS=4 - ASTSBINDIR=__ASTERISK_SBIN_DIR__ - ASTVARRUNDIR=__ASTERISK_VARRUN_DIR__ +-#NOTIFY=root@localhost.localdomain # Who to notify about crashes ++TTY= # TTY (if you want one) for Asterisk to run on ++CONSOLE=no # Whether or not you want a console ++NOTIFY=root # Who to notify about crashes + #EXEC=/path/to/somescript # Run this command if Asterisk crashes + #LOGFILE=${ASTVARLOGDIR}/safe_asterisk.log # Where to place the normal logfile (disabled if blank) + #SYSLOG=local0 # Which syslog facility to use (disabled if blank) +@@ -16,10 +16,11 @@ MACHINE=`hostname` # To specify which machine has c + DUMPDROP=/tmp + SLEEPSECS=4 ASTPIDFILE=${ASTVARRUNDIR}/asterisk.pid +VARRUNOWNER="_asterisk:wheel" # chown __ASTERISK_VARRUN_DIR__ if it's created. @@ -32,7 +32,7 @@ $OpenBSD: patch-contrib_scripts_safe_asterisk,v 1.13 2011/07/12 19:54:39 sthen E # run asterisk with this priority PRIORITY=0 -@@ -43,6 +44,19 @@ message() { +@@ -45,6 +46,19 @@ message() { fi } @@ -52,7 +52,7 @@ $OpenBSD: patch-contrib_scripts_safe_asterisk,v 1.13 2011/07/12 19:54:39 sthen E # Check if Asterisk is already running. If it is, then bug out, because # starting safe_asterisk when Asterisk is running is very bad. VERSION=`${ASTSBINDIR}/asterisk -nrx 'core show version'` -@@ -71,7 +85,7 @@ else +@@ -73,7 +87,7 @@ else fi fi SYSCTL_MAXFILES="fs.file-max" @@ -61,7 +61,7 @@ $OpenBSD: patch-contrib_scripts_safe_asterisk,v 1.13 2011/07/12 19:54:39 sthen E SYSCTL_MAXFILES="kern.maxfiles" fi -@@ -82,8 +96,10 @@ else +@@ -84,8 +98,10 @@ else fi fi diff --git a/telephony/asterisk/patches/patch-pbx_pbx_spool_c b/telephony/asterisk/patches/patch-pbx_pbx_spool_c index 03d990a6748..8368b9a08a6 100644 --- a/telephony/asterisk/patches/patch-pbx_pbx_spool_c +++ b/telephony/asterisk/patches/patch-pbx_pbx_spool_c @@ -1,7 +1,7 @@ -$OpenBSD: patch-pbx_pbx_spool_c,v 1.1 2012/03/17 23:08:20 sthen Exp $ ---- pbx/pbx_spool.c.orig Tue Oct 25 20:08:04 2011 -+++ pbx/pbx_spool.c Sat Mar 17 22:57:23 2012 -@@ -716,6 +716,12 @@ static void *scan_thread(void *unused) +$OpenBSD: patch-pbx_pbx_spool_c,v 1.2 2012/09/28 00:03:57 sthen Exp $ +--- pbx/pbx_spool.c.orig Mon Feb 13 22:03:33 2012 ++++ pbx/pbx_spool.c Thu Mar 29 21:47:56 2012 +@@ -723,6 +723,12 @@ static void *scan_thread(void *unused) queue_created_files(); #else struct timespec ts2 = { next - now, 0 }; diff --git a/telephony/asterisk/pkg/PLIST-main b/telephony/asterisk/pkg/PLIST-main index a069bb00486..8eeceb9e687 100644 --- a/telephony/asterisk/pkg/PLIST-main +++ b/telephony/asterisk/pkg/PLIST-main @@ -1,4 +1,4 @@ -@comment $OpenBSD: PLIST-main,v 1.45 2012/09/25 21:58:46 sthen Exp $ +@comment $OpenBSD: PLIST-main,v 1.46 2012/09/28 00:03:57 sthen Exp $ @conflict asterisk-sounds-<=1.2.1p2 @conflict asterisk-curl-* @conflict asterisk-fax-* @@ -48,6 +48,7 @@ include/asterisk/causes.h include/asterisk/ccss.h include/asterisk/cdr.h include/asterisk/cel.h +include/asterisk/celt.h include/asterisk/channel.h include/asterisk/channelstate.h include/asterisk/chanvars.h @@ -81,6 +82,9 @@ include/asterisk/event_defs.h include/asterisk/extconf.h include/asterisk/features.h include/asterisk/file.h +include/asterisk/format.h +include/asterisk/format_cap.h +include/asterisk/format_pref.h include/asterisk/frame.h include/asterisk/frame_defs.h include/asterisk/framehook.h @@ -103,6 +107,7 @@ include/asterisk/lock.h include/asterisk/logger.h include/asterisk/manager.h include/asterisk/md5.h +include/asterisk/message.h include/asterisk/mod_format.h include/asterisk/module.h include/asterisk/monitor.h @@ -128,6 +133,7 @@ include/asterisk/security_events.h include/asterisk/security_events_defs.h include/asterisk/select.h include/asterisk/sha1.h +include/asterisk/silk.h include/asterisk/slin.h include/asterisk/slinfactory.h include/asterisk/smdi.h @@ -198,12 +204,10 @@ lib/asterisk/modules/app_privacy.so lib/asterisk/modules/app_queue.so lib/asterisk/modules/app_read.so lib/asterisk/modules/app_readexten.so -lib/asterisk/modules/app_readfile.so lib/asterisk/modules/app_record.so lib/asterisk/modules/app_sayunixtime.so lib/asterisk/modules/app_senddtmf.so lib/asterisk/modules/app_sendtext.so -lib/asterisk/modules/app_setcallerid.so lib/asterisk/modules/app_sms.so lib/asterisk/modules/app_softhangup.so lib/asterisk/modules/app_speech_utils.so @@ -237,7 +241,6 @@ lib/asterisk/modules/chan_agent.so lib/asterisk/modules/chan_bridge.so lib/asterisk/modules/chan_gtalk.so lib/asterisk/modules/chan_iax2.so -lib/asterisk/modules/chan_jingle.so lib/asterisk/modules/chan_local.so lib/asterisk/modules/chan_mgcp.so lib/asterisk/modules/chan_multicast_rtp.so @@ -252,6 +255,7 @@ lib/asterisk/modules/codec_g726.so lib/asterisk/modules/codec_gsm.so lib/asterisk/modules/codec_ilbc.so lib/asterisk/modules/codec_lpc10.so +lib/asterisk/modules/codec_resample.so lib/asterisk/modules/codec_ulaw.so lib/asterisk/modules/format_g719.so lib/asterisk/modules/format_g723.so @@ -267,7 +271,6 @@ lib/asterisk/modules/format_pcm.so lib/asterisk/modules/format_siren14.so lib/asterisk/modules/format_siren7.so lib/asterisk/modules/format_sln.so -lib/asterisk/modules/format_sln16.so lib/asterisk/modules/format_vox.so lib/asterisk/modules/format_wav.so lib/asterisk/modules/format_wav_gsm.so @@ -293,6 +296,7 @@ lib/asterisk/modules/func_frame_trace.so lib/asterisk/modules/func_global.so lib/asterisk/modules/func_groupcount.so lib/asterisk/modules/func_iconv.so +lib/asterisk/modules/func_jitterbuffer.so lib/asterisk/modules/func_lock.so lib/asterisk/modules/func_logic.so lib/asterisk/modules/func_math.so @@ -329,6 +333,8 @@ lib/asterisk/modules/res_crypto.so lib/asterisk/modules/res_curl.so lib/asterisk/modules/res_fax.so lib/asterisk/modules/res_fax_spandsp.so +lib/asterisk/modules/res_format_attr_celt.so +lib/asterisk/modules/res_format_attr_silk.so lib/asterisk/modules/res_jabber.so lib/asterisk/modules/res_limit.so lib/asterisk/modules/res_monitor.so @@ -349,6 +355,8 @@ lib/asterisk/modules/res_timing_pthread.so @man man/man8/autosupport.8 @man man/man8/safe_asterisk.8 @bin sbin/astcanary +@bin sbin/astdb2bdb +@bin sbin/astdb2sqlite3 @bin sbin/asterisk sbin/astgenkey sbin/autosupport @@ -396,6 +404,7 @@ share/doc/asterisk/README.txt share/doc/asterisk/UPGRADE-1.2.txt share/doc/asterisk/UPGRADE-1.4.txt share/doc/asterisk/UPGRADE-1.6.txt +share/doc/asterisk/UPGRADE-1.8.txt share/doc/asterisk/UPGRADE.txt share/doc/asterisk/api-1.6.0-changes.odt share/doc/asterisk/api-1.6.2-changes.txt @@ -437,6 +446,7 @@ share/examples/asterisk/default/cli.conf share/examples/asterisk/default/cli_aliases.conf share/examples/asterisk/default/cli_permissions.conf share/examples/asterisk/default/codecs.conf +share/examples/asterisk/default/confbridge.conf share/examples/asterisk/default/console.conf share/examples/asterisk/default/dbsep.conf share/examples/asterisk/default/dnsmgr.conf @@ -551,7 +561,6 @@ share/examples/asterisk/openbsd/voicemail.conf.sample @sample /var/log/asterisk/ @sample /var/log/asterisk/cdr-csv/ @sample /var/log/asterisk/cdr-custom/ -@owner _asterisk @sample /var/spool/asterisk/voicemail/ @sample /var/spool/asterisk/voicemail/default/ @sample /var/spool/asterisk/voicemail/default/1234/ diff --git a/telephony/asterisk/pkg/README-main b/telephony/asterisk/pkg/README-main index 78b6958ec86..14800e8536c 100644 --- a/telephony/asterisk/pkg/README-main +++ b/telephony/asterisk/pkg/README-main @@ -1,4 +1,4 @@ -$OpenBSD: README-main,v 1.2 2011/06/02 13:41:41 ajacoutot Exp $ +$OpenBSD: README-main,v 1.3 2012/09/28 00:03:57 sthen Exp $ +----------------------------------------------------------------------- | Running ${FULLPKGNAME} on OpenBSD @@ -8,7 +8,14 @@ Configuration ============= Simplified sample configuration files have been provided in ${SYSCONFDIR}/asterisk; the full set from the Asterisk distribution -is available in ${PREFIX}/share/examples/asterisk/default. +is available in ${PREFIX}/share/examples/asterisk/default; some or all +of these can be copied to ${SYSCONFDIR}/asterisk and edited. + +Asterisk logs to /var/log/asterisk/messages by default; log rotation +can be handled by adding a line like the following to /etc/newsyslog.conf: + +/var/log/asterisk/messages 640 5 1000 * Z "asterisk -rx 'logger reload'" + Documentation =============