Wed Oct 28 13:32:18 2009

Asterisk developer's documentation


chan_unistim.c File Reference

chan_unistim channel driver for Asterisk More...

#include "asterisk.h"
#include <sys/stat.h>
#include <signal.h>
#include "asterisk/paths.h"
#include "asterisk/network.h"
#include "asterisk/channel.h"
#include "asterisk/config.h"
#include "asterisk/module.h"
#include "asterisk/pbx.h"
#include "asterisk/event.h"
#include "asterisk/rtp_engine.h"
#include "asterisk/netsock.h"
#include "asterisk/acl.h"
#include "asterisk/callerid.h"
#include "asterisk/cli.h"
#include "asterisk/app.h"
#include "asterisk/musiconhold.h"
#include "asterisk/causes.h"
#include "asterisk/indications.h"

Include dependency graph for chan_unistim.c:

Go to the source code of this file.

Data Structures

struct  systemtime
struct  tone_zone_unistim
struct  unistim_device
 A device containing one or more lines. More...
struct  unistim_line
struct  unistim_subchannel
struct  unistimsession
struct  wsabuf

Defines

#define AST_CONFIG_MAX_PATH   255
#define BUFFSEND   unsigned char buffsend[64] = { 0x00, 0x00, 0xaa, 0xbb, 0x02, 0x01 }
#define CAPABILITY   AST_FORMAT_ALAW | AST_FORMAT_ULAW
#define DEBUG_TIMER   dummy
#define DEFAULT_CODEC   0x00
#define DEFAULTCALLERID   "Unknown"
#define DEFAULTCALLERNAME   " "
#define DEFAULTCONTEXT   "default"
#define DEVICE_NAME_LEN   16
#define FAV_BLINK_FAST   0x20
#define FAV_BLINK_SLOW   0x40
#define FAV_ICON_BOX   0x3F
#define FAV_ICON_CALL_CENTER   0x34
#define FAV_ICON_CITY   0x31
#define FAV_ICON_COMPUTER   0x38
#define FAV_ICON_FAX   0x35
#define FAV_ICON_FORWARD   0x39
#define FAV_ICON_HEADPHONES   0x2E
#define FAV_ICON_HEADPHONES_ONHOLD   0x2F
#define FAV_ICON_HOME   0x30
#define FAV_ICON_INBOX   0x3C
#define FAV_ICON_LOCKED   0x3A
#define FAV_ICON_MAILBOX   0x36
#define FAV_ICON_MEETING   0x3E
#define FAV_ICON_NONE   0x00
#define FAV_ICON_OFFHOOK_BLACK   0x24
#define FAV_ICON_OFFHOOK_WHITE   0x25
#define FAV_ICON_ONHOLD_BLACK   0x26
#define FAV_ICON_ONHOLD_WHITE   0x27
#define FAV_ICON_ONHOOK_BLACK   0x20
#define FAV_ICON_ONHOOK_WHITE   0x21
#define FAV_ICON_OUTBOX   0x3D
#define FAV_ICON_PAGER   0x33
#define FAV_ICON_PHONE_BLACK   0x2A
#define FAV_ICON_PHONE_WHITE   0x2B
#define FAV_ICON_REFLECT   0x37
#define FAV_ICON_SHARP   0x32
#define FAV_ICON_SPEAKER_OFFHOOK_BLACK   0x28
#define FAV_ICON_SPEAKER_OFFHOOK_WHITE   0x29
#define FAV_ICON_SPEAKER_ONHOLD_BLACK   0x2C
#define FAV_ICON_SPEAKER_ONHOLD_WHITE   0x2D
#define FAV_ICON_SPEAKER_ONHOOK_BLACK   0x22
#define FAV_ICON_SPEAKER_ONHOOK_WHITE   0x23
#define FAV_ICON_TRASH   0x3B
#define FAV_MAX_LENGTH   0x0A
#define IDLE_WAIT   1000
#define MAX_BUF_NUMBER   50
#define MAX_BUF_SIZE   64
#define MAX_ENTRY_LOG   30
#define MAX_SUBS   2
#define MUTE_OFF   0x00
#define MUTE_ON   0xFF
#define MUTE_ON_DISCRET   0xCE
#define NB_MAX_RETRANSMIT   8
#define OUTPUT_HANDSET   0xC0
#define OUTPUT_HEADPHONE   0xC1
#define OUTPUT_SPEAKER   0xC2
#define RETRANSMIT_TIMER   2000
#define SELECTCODEC_MAX_LENGTH   2
#define SELECTCODEC_MSG   "Codec number : .."
#define SELECTCODEC_START_ENTRY_POS   15
#define SELECTEXTENSION_MAX_LENGTH   10
#define SELECTEXTENSION_MSG   ".........."
#define SELECTEXTENSION_START_ENTRY_POS   0
#define SIZE_HEADER   6
#define SIZE_MAC_ADDR   17
#define SIZE_PAGE   4096
#define STATUS_LENGTH_MAX   28
#define SUB_REAL   0
#define SUB_THREEWAY   1
#define TEXT_INVERSE   0x25
#define TEXT_LENGTH_MAX   24
#define TEXT_LINE0   0x00
#define TEXT_LINE1   0x20
#define TEXT_LINE2   0x40
#define TEXT_NORMAL   0x05
#define TIMER_MWI   10000
#define USTM_LOG_DIR   "unistimHistory"
#define VOLUME_INSANELY_LOUD   0x07
#define VOLUME_LOW   0x01
#define VOLUME_LOW_SPEAKER   0x03
#define VOLUME_NORMAL   0x02

Enumerations

enum  autoprov_extn { EXTENSION_NONE = 0, EXTENSION_ASK, EXTENSION_LINE, EXTENSION_TN }
enum  autoprovision { AUTOPROVISIONING_NO = 0, AUTOPROVISIONING_YES, AUTOPROVISIONING_DB, AUTOPROVISIONING_TN }
enum  handset_state { STATE_ONHOOK, STATE_OFFHOOK }
enum  phone_key {
  KEY_0 = 0x40, KEY_1 = 0x41, KEY_2 = 0x42, KEY_3 = 0x43,
  KEY_4 = 0x44, KEY_5 = 0x45, KEY_6 = 0x46, KEY_7 = 0x47,
  KEY_8 = 0x48, KEY_9 = 0x49, KEY_STAR = 0x4a, KEY_SHARP = 0x4b,
  KEY_UP = 0x4c, KEY_DOWN = 0x4d, KEY_RIGHT = 0x4e, KEY_LEFT = 0x4f,
  KEY_QUIT = 0x50, KEY_COPY = 0x51, KEY_FUNC1 = 0x54, KEY_FUNC2 = 0x55,
  KEY_FUNC3 = 0x56, KEY_FUNC4 = 0x57, KEY_ONHOLD = 0x5b, KEY_HANGUP = 0x5c,
  KEY_MUTE = 0x5d, KEY_HEADPHN = 0x5e, KEY_LOUDSPK = 0x5f, KEY_FAV0 = 0x60,
  KEY_FAV1 = 0x61, KEY_FAV2 = 0x62, KEY_FAV3 = 0x63, KEY_FAV4 = 0x64,
  KEY_FAV5 = 0x65, KEY_COMPUTR = 0x7b, KEY_CONF = 0x7c, KEY_SNDHIST = 0x7d,
  KEY_RCVHIST = 0x7e, KEY_INDEX = 0x7f
}
enum  phone_state {
  STATE_INIT, STATE_AUTHDENY, STATE_MAINPAGE, STATE_EXTENSION,
  STATE_DIALPAGE, STATE_RINGING, STATE_CALL, STATE_SELECTCODEC,
  STATE_CLEANING, STATE_HISTORY
}

Functions

static void __reg_module (void)
static void __unreg_module (void)
static int alloc_sub (struct unistim_line *l, int x)
static int attempt_transfer (struct unistim_subchannel *p1, struct unistim_subchannel *p2)
static struct unistim_devicebuild_device (const char *cat, const struct ast_variable *v)
static void cancel_dial (struct unistimsession *pte)
static void change_callerid (struct unistimsession *pte, int type, char *callerid)
static void change_favorite_icon (struct unistimsession *pte, unsigned char status)
static struct unistimsessionchannel_to_session (struct ast_channel *ast)
static void check_send_queue (struct unistimsession *pte)
static void close_call (struct unistimsession *pte)
static void close_client (struct unistimsession *s)
static char * control2str (int ind)
static struct unistimsessioncreate_client (const struct sockaddr_in *addr_from)
static void display_last_error (const char *sz_msg)
static void * do_monitor (void *data)
static void dummy (char *unused,...)
static struct unistim_subchannelfind_subchannel_by_name (const char *dest)
static void finish_bookmark (void)
static unsigned int get_tick_count (void)
static int get_to_address (int fd, struct sockaddr_in *toAddr)
static void handle_dial_page (struct unistimsession *pte)
static void HandleCallIncoming (struct unistimsession *s)
static void HandleCallOutgoing (struct unistimsession *s)
static void HandleSelectCodec (struct unistimsession *pte)
static void IgnoreCall (struct unistimsession *pte)
static void in_band_indication (struct ast_channel *ast, const struct ast_tone_zone *tz, const char *indication)
static void init_phone_step2 (struct unistimsession *pte)
static void key_call (struct unistimsession *pte, char keycode)
static void key_dial_page (struct unistimsession *pte, char keycode)
static void key_history (struct unistimsession *pte, char keycode)
static void key_main_page (struct unistimsession *pte, char keycode)
static void key_ringing (struct unistimsession *pte, char keycode)
static void key_select_codec (struct unistimsession *pte, char keycode)
static void key_select_extension (struct unistimsession *pte, char keycode)
static void Keyfavorite (struct unistimsession *pte, char keycode)
static int load_module (void)
static char OpenHistory (struct unistimsession *pte, char way, FILE **f)
static int ParseBookmark (const char *text, struct unistim_device *d)
static void parsing (int size, unsigned char *buf, struct unistimsession *pte, struct sockaddr_in *addr_from)
static void process_request (int size, unsigned char *buf, struct unistimsession *pte)
static void rcv_mac_addr (struct unistimsession *pte, const unsigned char *buf)
static void rcv_resume_connection_with_server (struct unistimsession *pte)
static int ReformatNumber (char *number)
static void refresh_all_favorite (struct unistimsession *pte)
static int RegisterExtension (const struct unistimsession *pte)
static int reload (void)
static int reload_config (void)
static int restart_monitor (void)
static void send_blink_cursor (struct unistimsession *pte)
static void send_client (int size, const unsigned char *data, struct unistimsession *pte)
static void send_cursor_pos (struct unistimsession *pte, unsigned char pos)
static void send_date_time (struct unistimsession *pte)
static void send_date_time2 (struct unistimsession *pte)
static void send_date_time3 (struct unistimsession *pte)
static void send_end_call (struct unistimsession *pte)
static void send_favorite (unsigned char pos, unsigned char status, struct unistimsession *pte, const char *text)
static void send_led_update (struct unistimsession *pte, unsigned char led)
static void send_no_ring (struct unistimsession *pte)
static void send_ping (struct unistimsession *pte)
static void send_raw_client (int size, const unsigned char *data, struct sockaddr_in *addr_to, const struct sockaddr_in *addr_ourip)
static int send_retransmit (struct unistimsession *pte)
static void send_ring (struct unistimsession *pte, char volume, char style)
static void send_select_output (struct unistimsession *pte, unsigned char output, unsigned char volume, unsigned char mute)
static void send_start_timer (struct unistimsession *pte)
static void send_stop_timer (struct unistimsession *pte)
static void send_text (unsigned char pos, unsigned char inverse, struct unistimsession *pte, const char *text)
static void send_text_status (struct unistimsession *pte, const char *text)
static void send_texttitle (struct unistimsession *pte, const char *text)
static void send_tone (struct unistimsession *pte, uint16_t tone1, uint16_t tone2)
static void SendDialTone (struct unistimsession *pte)
static void Sendicon (unsigned char pos, unsigned char status, struct unistimsession *pte)
static void set_ping_timer (struct unistimsession *pte)
static void show_entry_history (struct unistimsession *pte, FILE **f)
static void show_history (struct unistimsession *pte, char way)
static void show_main_page (struct unistimsession *pte)
static void ShowExtensionPage (struct unistimsession *pte)
static void start_rtp (struct unistim_subchannel *sub)
static void swap_subs (struct unistim_line *p, int a, int b)
static void TransferCallStep1 (struct unistimsession *pte)
static int unalloc_sub (struct unistim_line *p, int x)
static int unistim_answer (struct ast_channel *ast)
static int unistim_call (struct ast_channel *ast, char *dest, int timeout)
static char * unistim_do_debug (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
static int unistim_do_senddigit (struct unistimsession *pte, char digit)
static int unistim_fixup (struct ast_channel *oldchan, struct ast_channel *newchan)
static enum ast_rtp_glue_result unistim_get_rtp_peer (struct ast_channel *chan, struct ast_rtp_instance **instance)
static int unistim_hangup (struct ast_channel *ast)
static int unistim_indicate (struct ast_channel *ast, int ind, const void *data, size_t datalen)
static char * unistim_info (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
static struct ast_channelunistim_new (struct unistim_subchannel *sub, int state, const char *linkedid)
static struct ast_frameunistim_read (struct ast_channel *ast)
static int unistim_register (struct unistimsession *s)
static char * unistim_reload (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
 --- unistim_reload: Force reload of module from cli --- Runs in the asterisk main thread, so don't do anything useful but setting a flag and waiting for do_monitor to do the job in our thread
static struct ast_channelunistim_request (const char *type, int format, const struct ast_channel *requestor, void *data, int *cause)
static struct ast_frameunistim_rtp_read (const struct ast_channel *ast, const struct unistim_subchannel *sub)
static int unistim_send_mwi_to_peer (struct unistimsession *s, unsigned int tick)
static int unistim_senddigit_begin (struct ast_channel *ast, char digit)
static int unistim_senddigit_end (struct ast_channel *ast, char digit, unsigned int duration)
static int unistim_sendtext (struct ast_channel *ast, const char *text)
static char * unistim_sp (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
static void * unistim_ss (void *data)
static int unistim_write (struct ast_channel *ast, struct ast_frame *frame)
static int unistimsock_read (int *id, int fd, short events, void *ignore)
static int unload_module (void)
static void unquote (char *out, const char *src, int maxlen)
static int UnregisterExtension (const struct unistimsession *pte)
static int write_entry_history (struct unistimsession *pte, FILE *f, char c, char *line1)
static int write_history (struct unistimsession *pte, char way, char ismissed)

Variables

static struct ast_module_info __mod_info = { .name = AST_MODULE, .flags = AST_MODFLAG_DEFAULT , .description = "UNISTIM Protocol (USTM)" , .key = "This paragraph is copyright (c) 2006 by Digium, Inc. \In order for your module to load, it must return this \key via a function called \"key\". Any code which \includes this paragraph must be licensed under the GNU \General Public License version 2 or later (at your \option). In addition to Digium's general reservations \of rights, Digium expressly reserves the right to \allow other parties to license this paragraph under \different terms. Any use of Digium, Inc. trademarks or \logos (including \"Asterisk\" or \"Digium\") without \express written permission of Digium, Inc. is prohibited.\n" , .buildopt_sum = AST_BUILDOPT_SUM, .load = load_module, .unload = unload_module, .reload = reload, }
static struct sockaddr_in address_from
static struct ast_module_infoast_module_info = &__mod_info
static enum autoprovision autoprovisioning = AUTOPROVISIONING_NO
static unsigned char * buff
static const char channel_type [] = "USTM"
static struct ast_jb_conf default_jbconf
 Global jitterbuffer configuration - by default, jb is disabled.
static ast_mutex_t devicelock = ((ast_mutex_t) PTHREAD_MUTEX_INITIALIZER )
static struct unistim_devicedevices
 A device containing one or more lines.
static struct tone_zone_unistim frequency []
static struct ast_jb_conf global_jbconf
static struct io_contextio
static pthread_t monitor_thread = AST_PTHREADT_NULL
static ast_mutex_t monlock = ((ast_mutex_t) PTHREAD_MUTEX_INITIALIZER )
static const unsigned char packet_rcv_discovery []
static const unsigned char packet_recv_firm_version []
static const unsigned char packet_recv_hangup []
static const unsigned char packet_recv_mac_addr []
static const unsigned char packet_recv_pick_up []
static const unsigned char packet_recv_pressed_key []
static const unsigned char packet_recv_r2 [] = { 0x00, 0x00, 0x00, 0x13, 0x96, 0x03, 0x03 }
static const unsigned char packet_recv_resume_connection_with_server []
static const unsigned char packet_send_arrow [] = { 0x17, 0x04, 0x04, 0x00 }
static const unsigned char packet_send_blink_cursor [] = { 0x17, 0x04, 0x10, 0x86 }
static const unsigned char packet_send_call []
static const unsigned char packet_send_Contrast []
static const unsigned char packet_send_date_time []
static const unsigned char packet_send_date_time2 []
static const unsigned char packet_send_date_time3 []
static const unsigned char packet_send_discovery_ack []
static const unsigned char packet_send_end_call []
static const unsigned char packet_send_favorite []
static const unsigned char packet_send_icon [] = { 0x17, 0x05, 0x14, 0x00, 0x25 }
static const unsigned char packet_send_jitter_buffer_conf []
static const unsigned char packet_send_led_update [] = { 0x19, 0x04, 0x00, 0x00 }
static const unsigned char packet_send_no_ring []
static const unsigned char packet_send_open_audio_stream_rx []
static const unsigned char packet_send_open_audio_stream_rx3 []
static const unsigned char packet_send_open_audio_stream_tx []
static const unsigned char packet_send_open_audio_stream_tx3 []
static unsigned char packet_send_ping []
static const unsigned char packet_send_query_basic_manager_04 [] = { 0x1a, 0x04, 0x01, 0x04 }
static const unsigned char packet_send_query_basic_manager_10 [] = { 0x1a, 0x04, 0x01, 0x10 }
static const unsigned char packet_send_query_mac_address [] = { 0x1a, 0x04, 0x01, 0x08 }
static const unsigned char packet_send_ring []
static const unsigned char packet_send_rtp_packet_size []
static const unsigned char packet_send_S1 [] = { 0x1a, 0x07, 0x07, 0x00, 0x00, 0x00, 0x13 }
static const unsigned char packet_send_s4 []
static const unsigned char packet_send_S7 [] = { 0x17, 0x06, 0x0f, 0x30, 0x07, 0x07 }
static const unsigned char packet_send_s9 []
static const unsigned char packet_send_select_output []
static const unsigned char packet_send_set_pos_cursor []
static const unsigned char packet_send_StartTimer []
static const unsigned char packet_send_status []
static const unsigned char packet_send_status2 []
static const unsigned char packet_send_stop_timer [] = { 0x17, 0x05, 0x0b, 0x02, 0x00 }
static const unsigned char packet_send_stream_based_tone_dial_freq []
static const unsigned char packet_send_stream_based_tone_off []
static const unsigned char packet_send_stream_based_tone_on []
static const unsigned char packet_send_stream_based_tone_single_freq []
static const unsigned char packet_send_text []
static const unsigned char packet_send_title []
static struct sockaddr_in public_ip = { 0, }
struct {
   unsigned int   cos
   unsigned int   cos_audio
   unsigned int   tos
   unsigned int   tos_audio
qos
static struct sched_contextsched
static ast_mutex_t sessionlock = ((ast_mutex_t) PTHREAD_MUTEX_INITIALIZER )
static struct unistimsessionsessions
static unsigned int size_addr_from = sizeof(address_from)
static const char tdesc [] = "UNISTIM Channel Driver"
static struct ast_cli_entry unistim_cli []
static int unistim_keepalive
static int unistim_port
static ast_mutex_t unistim_reload_lock = ((ast_mutex_t) PTHREAD_MUTEX_INITIALIZER )
static int unistim_reloading = 0
static struct ast_rtp_glue unistim_rtp_glue
static struct ast_channel_tech unistim_tech
static int unistimdebug = 0
static int unistimsock = -1
static int usecnt = 0
static ast_mutex_t usecnt_lock = ((ast_mutex_t) PTHREAD_MUTEX_INITIALIZER )


Detailed Description

chan_unistim channel driver for Asterisk

Author:
Cedric Hans <cedric.hans@mlkj.net>
Unistim (Unified Networks IP Stimulus) channel driver for Nortel i2002, i2004 and i2050

Definition in file chan_unistim.c.


Define Documentation

#define AST_CONFIG_MAX_PATH   255

Definition at line 97 of file chan_unistim.c.

Referenced by OpenHistory(), and write_history().

#define BUFFSEND   unsigned char buffsend[64] = { 0x00, 0x00, 0xaa, 0xbb, 0x02, 0x01 }

#define CAPABILITY   AST_FORMAT_ALAW | AST_FORMAT_ULAW

Beware, G729 and G723 are not supported by asterisk, except with the proper licence

Definition at line 74 of file chan_unistim.c.

Referenced by build_device(), unistim_new(), and unistim_request().

#define DEBUG_TIMER   dummy

Definition at line 202 of file chan_unistim.c.

Referenced by do_monitor(), and set_ping_timer().

#define DEFAULT_CODEC   0x00

Not used

Definition at line 94 of file chan_unistim.c.

Referenced by key_select_extension(), and unistim_register().

#define DEFAULTCALLERID   "Unknown"

Definition at line 77 of file chan_unistim.c.

Referenced by unistim_call().

#define DEFAULTCALLERNAME   " "

Definition at line 78 of file chan_unistim.c.

Referenced by unistim_call().

#define DEFAULTCONTEXT   "default"

Definition at line 76 of file chan_unistim.c.

Referenced by build_device().

#define DEVICE_NAME_LEN   16

Definition at line 96 of file chan_unistim.c.

#define FAV_BLINK_FAST   0x20

Definition at line 178 of file chan_unistim.c.

Referenced by unistim_call().

#define FAV_BLINK_SLOW   0x40

Definition at line 179 of file chan_unistim.c.

Referenced by show_main_page().

#define FAV_ICON_BOX   0x3F

Definition at line 176 of file chan_unistim.c.

#define FAV_ICON_CALL_CENTER   0x34

Definition at line 165 of file chan_unistim.c.

Referenced by show_main_page().

#define FAV_ICON_CITY   0x31

Definition at line 162 of file chan_unistim.c.

#define FAV_ICON_COMPUTER   0x38

Definition at line 169 of file chan_unistim.c.

#define FAV_ICON_FAX   0x35

Definition at line 166 of file chan_unistim.c.

#define FAV_ICON_FORWARD   0x39

Definition at line 170 of file chan_unistim.c.

#define FAV_ICON_HEADPHONES   0x2E

Definition at line 159 of file chan_unistim.c.

Referenced by send_select_output().

#define FAV_ICON_HEADPHONES_ONHOLD   0x2F

Definition at line 160 of file chan_unistim.c.

Referenced by refresh_all_favorite(), and send_select_output().

#define FAV_ICON_HOME   0x30

Definition at line 161 of file chan_unistim.c.

#define FAV_ICON_INBOX   0x3C

Definition at line 173 of file chan_unistim.c.

#define FAV_ICON_LOCKED   0x3A

Definition at line 171 of file chan_unistim.c.

#define FAV_ICON_MAILBOX   0x36

Definition at line 167 of file chan_unistim.c.

#define FAV_ICON_MEETING   0x3E

Definition at line 175 of file chan_unistim.c.

#define FAV_ICON_NONE   0x00

Definition at line 144 of file chan_unistim.c.

Referenced by close_client(), handle_dial_page(), key_main_page(), and unistim_call().

#define FAV_ICON_OFFHOOK_BLACK   0x24

Definition at line 149 of file chan_unistim.c.

Referenced by send_select_output().

#define FAV_ICON_OFFHOOK_WHITE   0x25

Definition at line 150 of file chan_unistim.c.

#define FAV_ICON_ONHOLD_BLACK   0x26

Definition at line 151 of file chan_unistim.c.

Referenced by send_select_output().

#define FAV_ICON_ONHOLD_WHITE   0x27

Definition at line 152 of file chan_unistim.c.

#define FAV_ICON_ONHOOK_BLACK   0x20

Definition at line 145 of file chan_unistim.c.

Referenced by build_device(), and show_main_page().

#define FAV_ICON_ONHOOK_WHITE   0x21

Definition at line 146 of file chan_unistim.c.

#define FAV_ICON_OUTBOX   0x3D

Definition at line 174 of file chan_unistim.c.

#define FAV_ICON_PAGER   0x33

Definition at line 164 of file chan_unistim.c.

#define FAV_ICON_PHONE_BLACK   0x2A

Definition at line 155 of file chan_unistim.c.

Referenced by handle_dial_page().

#define FAV_ICON_PHONE_WHITE   0x2B

Definition at line 156 of file chan_unistim.c.

#define FAV_ICON_REFLECT   0x37

Definition at line 168 of file chan_unistim.c.

Referenced by show_main_page().

#define FAV_ICON_SHARP   0x32

Definition at line 163 of file chan_unistim.c.

Referenced by ParseBookmark().

#define FAV_ICON_SPEAKER_OFFHOOK_BLACK   0x28

Definition at line 153 of file chan_unistim.c.

Referenced by send_select_output().

#define FAV_ICON_SPEAKER_OFFHOOK_WHITE   0x29

Definition at line 154 of file chan_unistim.c.

#define FAV_ICON_SPEAKER_ONHOLD_BLACK   0x2C

Definition at line 157 of file chan_unistim.c.

Referenced by send_select_output().

#define FAV_ICON_SPEAKER_ONHOLD_WHITE   0x2D

Definition at line 158 of file chan_unistim.c.

#define FAV_ICON_SPEAKER_ONHOOK_BLACK   0x22

Definition at line 147 of file chan_unistim.c.

Referenced by send_select_output(), and unistim_call().

#define FAV_ICON_SPEAKER_ONHOOK_WHITE   0x23

Definition at line 148 of file chan_unistim.c.

#define FAV_ICON_TRASH   0x3B

Definition at line 172 of file chan_unistim.c.

#define FAV_MAX_LENGTH   0x0A

Definition at line 181 of file chan_unistim.c.

Referenced by send_favorite().

#define IDLE_WAIT   1000

Nb of milliseconds waited when no events are scheduled

Definition at line 88 of file chan_unistim.c.

Referenced by do_monitor().

#define MAX_BUF_NUMBER   50

Number of slots for the transmit queue

Definition at line 84 of file chan_unistim.c.

Referenced by create_client(), and send_client().

#define MAX_BUF_SIZE   64

Size of the transmit buffer

Definition at line 82 of file chan_unistim.c.

#define MAX_ENTRY_LOG   30

Definition at line 98 of file chan_unistim.c.

Referenced by OpenHistory(), and write_history().

#define MAX_SUBS   2

Definition at line 102 of file chan_unistim.c.

#define MUTE_OFF   0x00

#define MUTE_ON   0xFF

Definition at line 131 of file chan_unistim.c.

Referenced by key_call(), and send_select_output().

#define MUTE_ON_DISCRET   0xCE

Definition at line 132 of file chan_unistim.c.

Referenced by send_select_output(), and show_main_page().

#define NB_MAX_RETRANSMIT   8

Try x times before removing the phone

Definition at line 86 of file chan_unistim.c.

Referenced by reload_config(), and send_retransmit().

#define OUTPUT_HANDSET   0xC0

#define OUTPUT_HEADPHONE   0xC1

#define OUTPUT_SPEAKER   0xC2

#define RETRANSMIT_TIMER   2000

Wait x milliseconds before resending a packet

Definition at line 90 of file chan_unistim.c.

Referenced by create_client(), reload_config(), send_client(), and send_retransmit().

#define SELECTCODEC_MAX_LENGTH   2

Definition at line 2773 of file chan_unistim.c.

Referenced by key_select_codec().

#define SELECTCODEC_MSG   "Codec number : .."

Definition at line 2774 of file chan_unistim.c.

Referenced by HandleSelectCodec(), and key_select_codec().

#define SELECTCODEC_START_ENTRY_POS   15

Definition at line 2772 of file chan_unistim.c.

Referenced by HandleSelectCodec(), and key_select_codec().

#define SELECTEXTENSION_MAX_LENGTH   10

Definition at line 2850 of file chan_unistim.c.

Referenced by key_select_extension().

#define SELECTEXTENSION_MSG   ".........."

Definition at line 2851 of file chan_unistim.c.

Referenced by key_select_extension(), and ShowExtensionPage().

#define SELECTEXTENSION_START_ENTRY_POS   0

Definition at line 2849 of file chan_unistim.c.

Referenced by key_select_extension(), and ShowExtensionPage().

#define SIZE_HEADER   6

#define SIZE_MAC_ADDR   17

Definition at line 135 of file chan_unistim.c.

#define SIZE_PAGE   4096

Definition at line 95 of file chan_unistim.c.

Referenced by load_module(), and unistimsock_read().

#define STATUS_LENGTH_MAX   28

Definition at line 142 of file chan_unistim.c.

Referenced by send_text_status(), and show_entry_history().

#define SUB_REAL   0

Definition at line 100 of file chan_unistim.c.

#define SUB_THREEWAY   1

Definition at line 101 of file chan_unistim.c.

#define TEXT_INVERSE   0x25

Definition at line 141 of file chan_unistim.c.

Referenced by HandleSelectCodec(), and key_select_codec().

#define TEXT_LENGTH_MAX   24

#define TEXT_LINE0   0x00

#define TEXT_LINE1   0x20

#define TEXT_LINE2   0x40

#define TEXT_NORMAL   0x05

#define TIMER_MWI   10000

How often the mailbox is checked for new messages

Definition at line 92 of file chan_unistim.c.

Referenced by unistim_send_mwi_to_peer().

#define USTM_LOG_DIR   "unistimHistory"

Definition at line 79 of file chan_unistim.c.

Referenced by OpenHistory(), and write_history().

#define VOLUME_INSANELY_LOUD   0x07

Definition at line 128 of file chan_unistim.c.

#define VOLUME_LOW   0x01

Definition at line 125 of file chan_unistim.c.

Referenced by build_device(), and send_select_output().

#define VOLUME_LOW_SPEAKER   0x03

Definition at line 126 of file chan_unistim.c.

Referenced by send_select_output().

#define VOLUME_NORMAL   0x02

Definition at line 127 of file chan_unistim.c.


Enumeration Type Documentation

Enumerator:
EXTENSION_NONE  Do not create an extension into the default dialplan
EXTENSION_ASK  Prompt user for an extension number and register it
EXTENSION_LINE  Register an extension with the line=> value
EXTENSION_TN  Used with AUTOPROVISIONING_TN

Definition at line 111 of file chan_unistim.c.

00111                    {
00112    /*! Do not create an extension into the default dialplan */
00113    EXTENSION_NONE = 0,
00114    /*! Prompt user for an extension number and register it */
00115    EXTENSION_ASK,
00116    /*! Register an extension with the line=> value */
00117    EXTENSION_LINE,
00118    /*! Used with AUTOPROVISIONING_TN */
00119    EXTENSION_TN
00120 };

Enumerator:
AUTOPROVISIONING_NO 
AUTOPROVISIONING_YES 
AUTOPROVISIONING_DB 
AUTOPROVISIONING_TN 

Definition at line 104 of file chan_unistim.c.

00104                    {
00105    AUTOPROVISIONING_NO = 0,
00106    AUTOPROVISIONING_YES,
00107    AUTOPROVISIONING_DB,
00108    AUTOPROVISIONING_TN
00109 };

Enumerator:
STATE_ONHOOK 
STATE_OFFHOOK 

Definition at line 257 of file chan_unistim.c.

00257                    {
00258    STATE_ONHOOK,
00259    STATE_OFFHOOK,
00260 };

enum phone_key

Enumerator:
KEY_0 
KEY_1 
KEY_2 
KEY_3 
KEY_4 
KEY_5 
KEY_6 
KEY_7 
KEY_8 
KEY_9 
KEY_STAR 
KEY_SHARP 
KEY_UP 
KEY_DOWN 
KEY_RIGHT 
KEY_LEFT 
KEY_QUIT 
KEY_COPY 
KEY_FUNC1 
KEY_FUNC2 
KEY_FUNC3 
KEY_FUNC4 
KEY_ONHOLD 
KEY_HANGUP 
KEY_MUTE 
KEY_HEADPHN 
KEY_LOUDSPK 
KEY_FAV0 
KEY_FAV1 
KEY_FAV2 
KEY_FAV3 
KEY_FAV4 
KEY_FAV5 
KEY_COMPUTR 
KEY_CONF 
KEY_SNDHIST 
KEY_RCVHIST 
KEY_INDEX 

Definition at line 262 of file chan_unistim.c.

00262                {
00263    KEY_0 = 0x40,
00264    KEY_1 = 0x41,
00265    KEY_2 = 0x42,
00266    KEY_3 = 0x43,
00267    KEY_4 = 0x44,
00268    KEY_5 = 0x45,
00269    KEY_6 = 0x46,
00270    KEY_7 = 0x47,
00271    KEY_8 = 0x48,
00272    KEY_9 = 0x49,
00273    KEY_STAR = 0x4a,
00274    KEY_SHARP = 0x4b,
00275    KEY_UP = 0x4c,
00276    KEY_DOWN = 0x4d,
00277    KEY_RIGHT = 0x4e,
00278    KEY_LEFT = 0x4f,
00279    KEY_QUIT = 0x50,
00280    KEY_COPY = 0x51,
00281    KEY_FUNC1 = 0x54,
00282    KEY_FUNC2 = 0x55,
00283    KEY_FUNC3 = 0x56,
00284    KEY_FUNC4 = 0x57,
00285    KEY_ONHOLD = 0x5b,
00286    KEY_HANGUP = 0x5c,
00287    KEY_MUTE = 0x5d,
00288    KEY_HEADPHN = 0x5e,
00289    KEY_LOUDSPK = 0x5f,
00290    KEY_FAV0 = 0x60,
00291    KEY_FAV1 = 0x61,
00292    KEY_FAV2 = 0x62,
00293    KEY_FAV3 = 0x63,
00294    KEY_FAV4 = 0x64,
00295    KEY_FAV5 = 0x65,
00296    KEY_COMPUTR = 0x7b,
00297    KEY_CONF = 0x7c,
00298    KEY_SNDHIST = 0x7d,
00299    KEY_RCVHIST = 0x7e,
00300    KEY_INDEX = 0x7f
00301 };

Enumerator:
STATE_INIT 
STATE_AUTHDENY 
STATE_MAINPAGE 
STATE_EXTENSION 
STATE_DIALPAGE 
STATE_RINGING 
STATE_CALL 
STATE_SELECTCODEC 
STATE_CLEANING 
STATE_HISTORY 

Definition at line 244 of file chan_unistim.c.

00244                  {
00245    STATE_INIT,
00246    STATE_AUTHDENY,
00247    STATE_MAINPAGE,
00248    STATE_EXTENSION,
00249    STATE_DIALPAGE,
00250    STATE_RINGING,
00251    STATE_CALL,
00252    STATE_SELECTCODEC,
00253    STATE_CLEANING,
00254    STATE_HISTORY
00255 };


Function Documentation

static void __reg_module ( void   )  [static]

Definition at line 5636 of file chan_unistim.c.

static void __unreg_module ( void   )  [static]

Definition at line 5636 of file chan_unistim.c.

static int alloc_sub ( struct unistim_line l,
int  x 
) [static]

Definition at line 1483 of file chan_unistim.c.

References ast_calloc, ast_mutex_init(), ast_verb, unistim_subchannel::lock, unistim_device::name, unistim_line::name, unistim_subchannel::parent, unistim_line::parent, unistim_line::subs, and unistim_subchannel::subtype.

01484 {
01485    struct unistim_subchannel *sub;
01486    if (!(sub = ast_calloc(1, sizeof(*sub))))
01487       return 0;
01488 
01489    if (unistimdebug)
01490       ast_verb(3, "Allocating UNISTIM subchannel #%d on %s@%s ptr=%p\n", x, l->name, l->parent->name, sub);
01491    sub->parent = l;
01492    sub->subtype = x;
01493    l->subs[x] = sub;
01494    ast_mutex_init(&sub->lock);
01495    return 1;
01496 }

static int attempt_transfer ( struct unistim_subchannel p1,
struct unistim_subchannel p2 
) [static]

Definition at line 1887 of file chan_unistim.c.

References ast_bridged_channel(), ast_cdr_append(), ast_channel_masquerade(), ast_log(), AST_SOFTHANGUP_DEV, ast_softhangup_nolock(), ast_channel::cdr, LOG_NOTICE, LOG_WARNING, and unistim_subchannel::owner.

01888 {
01889    int res = 0;
01890    struct ast_channel
01891     *chana = NULL, *chanb = NULL, *bridgea = NULL, *bridgeb = NULL, *peera =
01892       NULL, *peerb = NULL, *peerc = NULL, *peerd = NULL;
01893 
01894    if (!p1->owner || !p2->owner) {
01895       ast_log(LOG_WARNING, "Transfer attempted without dual ownership?\n");
01896       return -1;
01897    }
01898    chana = p1->owner;
01899    chanb = p2->owner;
01900    bridgea = ast_bridged_channel(chana);
01901    bridgeb = ast_bridged_channel(chanb);
01902 
01903    if (bridgea) {
01904       peera = chana;
01905       peerb = chanb;
01906       peerc = bridgea;
01907       peerd = bridgeb;
01908    } else if (bridgeb) {
01909       peera = chanb;
01910       peerb = chana;
01911       peerc = bridgeb;
01912       peerd = bridgea;
01913    }
01914 
01915    if (peera && peerb && peerc && (peerb != peerc)) {
01916       /*ast_quiet_chan(peera);
01917          ast_quiet_chan(peerb);
01918          ast_quiet_chan(peerc);
01919          ast_quiet_chan(peerd); */
01920 
01921       if (peera->cdr && peerb->cdr) {
01922          peerb->cdr = ast_cdr_append(peerb->cdr, peera->cdr);
01923       } else if (peera->cdr) {
01924          peerb->cdr = peera->cdr;
01925       }
01926       peera->cdr = NULL;
01927 
01928       if (peerb->cdr && peerc->cdr) {
01929          peerb->cdr = ast_cdr_append(peerb->cdr, peerc->cdr);
01930       } else if (peerc->cdr) {
01931          peerb->cdr = peerc->cdr;
01932       }
01933       peerc->cdr = NULL;
01934 
01935       if (ast_channel_masquerade(peerb, peerc)) {
01936          ast_log(LOG_WARNING, "Failed to masquerade %s into %s\n", peerb->name,
01937                peerc->name);
01938          res = -1;
01939       }
01940       return res;
01941    } else {
01942       ast_log(LOG_NOTICE,
01943             "Transfer attempted with no appropriate bridged calls to transfer\n");
01944       if (chana)
01945          ast_softhangup_nolock(chana, AST_SOFTHANGUP_DEV);
01946       if (chanb)
01947          ast_softhangup_nolock(chanb, AST_SOFTHANGUP_DEV);
01948       return -1;
01949    }
01950    return 0;
01951 }

static struct unistim_device* build_device ( const char *  cat,
const struct ast_variable v 
) [static, read]

Definition at line 4999 of file chan_unistim.c.

References unistim_line::accountcode, alloc_sub(), unistim_line::amaflags, ast_append_ha(), ast_calloc, ast_cdr_amaflags2int(), ast_copy_string(), ast_free, ast_get_group(), ast_get_indication_zone(), ast_localtime(), ast_log(), AST_MAX_EXTENSION, ast_mutex_destroy(), ast_mutex_init(), ast_mutex_lock(), ast_mutex_unlock(), ast_strlen_zero(), ast_tone_zone_unref(), ast_true(), ast_tvnow(), ast_verb, AUTOPROVISIONING_TN, unistim_line::callgroup, unistim_device::callhistory, CAPABILITY, unistim_line::capability, unistim_line::cid_num, unistim_line::context, context, unistim_device::contrast, unistim_device::country, dateformat, unistim_device::datetimeformat, DEFAULTCONTEXT, devicelock, display_last_error(), unistim_device::extension, EXTENSION_ASK, EXTENSION_LINE, EXTENSION_NONE, unistim_device::extension_number, EXTENSION_TN, FAV_ICON_ONHOOK_BLACK, unistim_line::fullname, unistim_device::ha, unistim_device::id, unistim_line::language, len(), ast_variable::lineno, unistim_device::lines, unistim_line::lock, LOG_ERROR, LOG_WARNING, unistim_line::mailbox, unistim_device::maintext0, unistim_device::maintext1, unistim_device::maintext2, unistim_line::musicclass, unistim_device::mute, MUTE_OFF, unistim_line::name, ast_variable::name, unistim_device::name, unistim_device::nat, ast_variable::next, unistim_line::next, unistim_device::next, unistim_device::output, OUTPUT_HANDSET, unistim_line::parent, unistim_line::parkinglot, ParseBookmark(), unistim_line::pickupgroup, unistim_device::previous_output, unistim_device::ringstyle, unistim_device::ringvolume, unistim_device::rtp_method, unistim_device::rtp_port, unistim_device::softkeydevice, unistim_device::softkeyicon, unistim_device::softkeylabel, unistim_device::softkeylinepos, unistim_device::softkeynumber, unistim_device::sp, unistim_device::status_method, SUB_REAL, unistim_device::titledefault, ast_tm::tm_zone, unistim_device::to_delete, unistim_device::tz, unquote(), ast_variable::value, unistim_device::volume, and VOLUME_LOW.

05000 {
05001    struct unistim_device *d;
05002    struct unistim_line *l = NULL;
05003    int create = 1;
05004    int nbsoftkey, dateformat, timeformat, callhistory;
05005    char linelabel[AST_MAX_EXTENSION];
05006    char context[AST_MAX_EXTENSION];
05007    char ringvolume, ringstyle;
05008 
05009    /* First, we need to know if we already have this name in our list */
05010    /* Get a lock for the device chained list */
05011    ast_mutex_lock(&devicelock);
05012    d = devices;
05013    while (d) {
05014       if (!strcmp(d->name, cat)) {
05015          /* Yep, we alreay have this one */
05016          if (unistimsock < 0) {
05017             /* It's a dupe */
05018             ast_log(LOG_WARNING, "Duplicate entry found (%s), ignoring.\n", cat);
05019             ast_mutex_unlock(&devicelock);
05020             return NULL;
05021          }
05022          /* we're reloading right now */
05023          create = 0;
05024          l = d->lines;
05025          break;
05026       }
05027       d = d->next;
05028    }
05029    ast_mutex_unlock(&devicelock);
05030    if (create) {
05031       if (!(d = ast_calloc(1, sizeof(*d))))
05032          return NULL;
05033 
05034       if (!(l = ast_calloc(1, sizeof(*l)))) {
05035          ast_free(d);
05036          return NULL;
05037       }
05038       ast_copy_string(d->name, cat, sizeof(d->name));
05039    }
05040    ast_copy_string(context, DEFAULTCONTEXT, sizeof(context));
05041    d->contrast = -1;
05042    d->output = OUTPUT_HANDSET;
05043    d->previous_output = OUTPUT_HANDSET;
05044    d->volume = VOLUME_LOW;
05045    d->mute = MUTE_OFF;
05046    linelabel[0] = '\0';
05047    dateformat = 1;
05048    timeformat = 1;
05049    ringvolume = 2;
05050    callhistory = 1;
05051    ringstyle = 3;
05052    nbsoftkey = 0;
05053    while (v) {
05054       if (!strcasecmp(v->name, "rtp_port"))
05055          d->rtp_port = atoi(v->value);
05056       else if (!strcasecmp(v->name, "rtp_method"))
05057          d->rtp_method = atoi(v->value);
05058       else if (!strcasecmp(v->name, "status_method"))
05059          d->status_method = atoi(v->value);
05060       else if (!strcasecmp(v->name, "device"))
05061          ast_copy_string(d->id, v->value, sizeof(d->id));
05062       else if (!strcasecmp(v->name, "tn"))
05063          ast_copy_string(d->extension_number, v->value, sizeof(d->extension_number));
05064       else if (!strcasecmp(v->name, "permit") || !strcasecmp(v->name, "deny"))
05065          d->ha = ast_append_ha(v->name, v->value, d->ha, NULL);
05066       else if (!strcasecmp(v->name, "context"))
05067          ast_copy_string(context, v->value, sizeof(context));
05068       else if (!strcasecmp(v->name, "maintext0"))
05069          unquote(d->maintext0, v->value, sizeof(d->maintext0) - 1);
05070       else if (!strcasecmp(v->name, "maintext1"))
05071          unquote(d->maintext1, v->value, sizeof(d->maintext1) - 1);
05072       else if (!strcasecmp(v->name, "maintext2"))
05073          unquote(d->maintext2, v->value, sizeof(d->maintext2) - 1);
05074       else if (!strcasecmp(v->name, "titledefault"))
05075          unquote(d->titledefault, v->value, sizeof(d->titledefault) - 1);
05076       else if (!strcasecmp(v->name, "dateformat"))
05077          dateformat = atoi(v->value);
05078       else if (!strcasecmp(v->name, "timeformat"))
05079          timeformat = atoi(v->value);
05080       else if (!strcasecmp(v->name, "contrast")) {
05081          d->contrast = atoi(v->value);
05082          if ((d->contrast < 0) || (d->contrast > 15)) {
05083             ast_log(LOG_WARNING, "constrast must be beetween 0 and 15");
05084             d->contrast = 8;
05085          }
05086       } else if (!strcasecmp(v->name, "nat"))
05087          d->nat = ast_true(v->value);
05088       else if (!strcasecmp(v->name, "ringvolume"))
05089          ringvolume = atoi(v->value);
05090       else if (!strcasecmp(v->name, "ringstyle"))
05091          ringstyle = atoi(v->value);
05092       else if (!strcasecmp(v->name, "callhistory"))
05093          callhistory = atoi(v->value);
05094       else if (!strcasecmp(v->name, "callerid")) {
05095          if (!strcasecmp(v->value, "asreceived"))
05096             l->cid_num[0] = '\0';
05097          else
05098             ast_copy_string(l->cid_num, v->value, sizeof(l->cid_num));
05099       } else if (!strcasecmp(v->name, "language"))
05100          ast_copy_string(l->language, v->value, sizeof(l->language));
05101       else if (!strcasecmp(v->name, "country"))
05102          ast_copy_string(d->country, v->value, sizeof(d->country));
05103       else if (!strcasecmp(v->name, "accountcode"))
05104          ast_copy_string(l->accountcode, v->value, sizeof(l->accountcode));
05105       else if (!strcasecmp(v->name, "amaflags")) {
05106          int y;
05107          y = ast_cdr_amaflags2int(v->value);
05108          if (y < 0)
05109             ast_log(LOG_WARNING, "Invalid AMA flags: %s at line %d\n", v->value,
05110                   v->lineno);
05111          else
05112             l->amaflags = y;
05113       } else if (!strcasecmp(v->name, "musiconhold"))
05114          ast_copy_string(l->musicclass, v->value, sizeof(l->musicclass));
05115       else if (!strcasecmp(v->name, "callgroup"))
05116          l->callgroup = ast_get_group(v->value);
05117       else if (!strcasecmp(v->name, "pickupgroup"))
05118          l->pickupgroup = ast_get_group(v->value);
05119       else if (!strcasecmp(v->name, "mailbox"))
05120          ast_copy_string(l->mailbox, v->value, sizeof(l->mailbox));
05121       else if (!strcasecmp(v->name, "parkinglot"))
05122          ast_copy_string(l->parkinglot, v->value, sizeof(l->parkinglot));
05123       else if (!strcasecmp(v->name, "linelabel"))
05124          unquote(linelabel, v->value, sizeof(linelabel) - 1);
05125       else if (!strcasecmp(v->name, "extension")) {
05126          if (!strcasecmp(v->value, "none"))
05127             d->extension = EXTENSION_NONE;
05128          else if (!strcasecmp(v->value, "ask"))
05129             d->extension = EXTENSION_ASK;
05130          else if (!strcasecmp(v->value, "line"))
05131             d->extension = EXTENSION_LINE;
05132          else
05133             ast_log(LOG_WARNING, "Unknown extension option.\n");
05134       } else if (!strcasecmp(v->name, "bookmark")) {
05135          if (nbsoftkey > 5)
05136             ast_log(LOG_WARNING,
05137                   "More than 6 softkeys defined. Ignoring new entries.\n");
05138          else {
05139             if (ParseBookmark(v->value, d))
05140                nbsoftkey++;
05141          }
05142       } else if (!strcasecmp(v->name, "line")) {
05143          int len = strlen(linelabel);
05144 
05145          if (nbsoftkey) {
05146             ast_log(LOG_WARNING,
05147                   "You must use bookmark AFTER line=>. Only one line is supported in this version\n");
05148             if (create) {
05149                ast_free(d);
05150                ast_free(l);
05151             }
05152             return NULL;
05153          }
05154          if (create) {
05155             ast_mutex_init(&l->lock);
05156          } else {
05157             d->to_delete = 0;
05158             /* reset bookmarks */
05159             memset(d->softkeylabel, 0, sizeof(d->softkeylabel));
05160             memset(d->softkeynumber, 0, sizeof(d->softkeynumber));
05161             memset(d->softkeyicon, 0, sizeof(d->softkeyicon));
05162             memset(d->softkeydevice, 0, sizeof(d->softkeydevice));
05163             memset(d->sp, 0, sizeof(d->sp));
05164          }
05165          ast_copy_string(l->name, v->value, sizeof(l->name));
05166          snprintf(l->fullname, sizeof(l->fullname), "USTM/%s@%s", l->name, d->name);
05167          d->softkeyicon[0] = FAV_ICON_ONHOOK_BLACK;
05168          if (!len)             /* label is undefined ? */
05169             ast_copy_string(d->softkeylabel[0], v->value, sizeof(d->softkeylabel[0]));
05170          else {
05171             if ((len > 2) && (linelabel[1] == '@')) {
05172                d->softkeylinepos = linelabel[0];
05173                if ((d->softkeylinepos >= '0') && (d->softkeylinepos <= '5')) {
05174                   d->softkeylinepos -= '0';
05175                   d->softkeyicon[0] = 0;
05176                } else {
05177                   ast_log(LOG_WARNING,
05178                         "Invalid position for linelabel : must be between 0 and 5\n");
05179                   d->softkeylinepos = 0;
05180                }
05181                ast_copy_string(d->softkeylabel[d->softkeylinepos], linelabel + 2,
05182                            sizeof(d->softkeylabel[d->softkeylinepos]));
05183                d->softkeyicon[d->softkeylinepos] = FAV_ICON_ONHOOK_BLACK;
05184             } else
05185                ast_copy_string(d->softkeylabel[0], linelabel,
05186                            sizeof(d->softkeylabel[0]));
05187          }
05188          nbsoftkey++;
05189          ast_copy_string(l->context, context, sizeof(l->context));
05190          if (!ast_strlen_zero(l->mailbox)) {
05191             if (unistimdebug)
05192                ast_verb(3, "Setting mailbox '%s' on %s@%s\n", l->mailbox, d->name, l->name);
05193          }
05194 
05195          l->capability = CAPABILITY;
05196          l->parent = d;
05197 
05198          if (create) {
05199             if (!alloc_sub(l, SUB_REAL)) {
05200                ast_mutex_destroy(&l->lock);
05201                ast_free(l);
05202                ast_free(d);
05203                return NULL;
05204             }
05205             l->next = d->lines;
05206             d->lines = l;
05207          }
05208       } else
05209          ast_log(LOG_WARNING, "Don't know keyword '%s' at line %d\n", v->name,
05210                v->lineno);
05211       v = v->next;
05212    }
05213    d->ringvolume = ringvolume;
05214    d->ringstyle = ringstyle;
05215    d->callhistory = callhistory;
05216    d->tz = ast_get_indication_zone(d->country);
05217    if ((d->tz == NULL) && !ast_strlen_zero(d->country))
05218       ast_log(LOG_WARNING, "Country '%s' was not found in indications.conf\n",
05219             d->country);
05220    d->datetimeformat = 56 + (dateformat * 4);
05221    d->datetimeformat += timeformat;
05222    if (!d->lines) {
05223       ast_log(LOG_ERROR, "An Unistim device must have at least one line!\n");
05224       ast_mutex_destroy(&l->lock);
05225       ast_free(l);
05226       if (d->tz) {
05227          d->tz = ast_tone_zone_unref(d->tz);
05228       }
05229       ast_free(d);
05230       return NULL;
05231    }
05232    if ((autoprovisioning == AUTOPROVISIONING_TN) &&
05233       (!ast_strlen_zero(d->extension_number))) {
05234       d->extension = EXTENSION_TN;
05235       if (!ast_strlen_zero(d->id))
05236          ast_log(LOG_WARNING,
05237                "tn= and device= can't be used together. Ignoring device= entry\n");
05238       d->id[0] = 'T';       /* magic : this is a tn entry */
05239       ast_copy_string((d->id) + 1, d->extension_number, sizeof(d->id) - 1);
05240       d->extension_number[0] = '\0';
05241    } else if (ast_strlen_zero(d->id)) {
05242       if (strcmp(d->name, "template")) {
05243          ast_log(LOG_ERROR, "You must specify the mac address with device=\n");
05244          ast_mutex_destroy(&l->lock);
05245          ast_free(l);
05246          if (d->tz) {
05247             d->tz = ast_tone_zone_unref(d->tz);
05248          }
05249          ast_free(d);
05250          return NULL;
05251       } else
05252          strcpy(d->id, "000000000000");
05253    }
05254    if (!d->rtp_port)
05255       d->rtp_port = 10000;
05256    if (d->contrast == -1)
05257       d->contrast = 8;
05258    if (ast_strlen_zero(d->maintext0))
05259       strcpy(d->maintext0, "Welcome");
05260    if (ast_strlen_zero(d->maintext1))
05261       strcpy(d->maintext1, d->name);
05262    if (ast_strlen_zero(d->titledefault)) {
05263       struct ast_tm tm = { 0, };
05264       struct timeval cur_time = ast_tvnow();
05265 
05266       if ((ast_localtime(&cur_time, &tm, 0)) == 0 || ast_strlen_zero(tm.tm_zone)) {
05267          display_last_error("Error in ast_localtime()");
05268          ast_copy_string(d->titledefault, "UNISTIM for*", 12);
05269       } else {
05270          if (strlen(tm.tm_zone) < 4) {
05271             strcpy(d->titledefault, "TimeZone ");
05272             strcat(d->titledefault, tm.tm_zone);
05273          } else if (strlen(tm.tm_zone) < 9) {
05274             strcpy(d->titledefault, "TZ ");
05275             strcat(d->titledefault, tm.tm_zone);
05276          } else
05277             ast_copy_string(d->titledefault, tm.tm_zone, 12);
05278       }
05279    }
05280    /* Update the chained link if it's a new device */
05281    if (create) {
05282       ast_mutex_lock(&devicelock);
05283       d->next = devices;
05284       devices = d;
05285       ast_mutex_unlock(&devicelock);
05286       ast_verb(3, "Added device '%s'\n", d->name);
05287    } else {
05288       ast_verb(3, "Device '%s' reloaded\n", d->name);
05289    }
05290    return d;
05291 }

static void cancel_dial ( struct unistimsession pte  )  [static]

Definition at line 1850 of file chan_unistim.c.

References unistimsession::device, unistim_device::missed_call, send_no_ring(), show_main_page(), and write_history().

Referenced by unistim_hangup().

01851 {
01852    send_no_ring(pte);
01853    pte->device->missed_call++;
01854    write_history(pte, 'i', 1);
01855    show_main_page(pte);
01856    return;
01857 }

void change_callerid ( struct unistimsession pte,
int  type,
char *  callerid 
) [static]

Definition at line 1953 of file chan_unistim.c.

References ast_channel::data, unistimsession::device, unistim_device::lst_cid, unistim_device::lst_cnm, and TEXT_LENGTH_MAX.

Referenced by close_call(), and unistim_call().

01954 {
01955    char *data;
01956    int size;
01957 
01958    if (type)
01959       data = pte->device->lst_cnm;
01960    else
01961       data = pte->device->lst_cid;
01962 
01963    /* This is very nearly strncpy(), except that the remaining buffer
01964     * is padded with ' ', instead of '\0' */
01965    memset(data, ' ', TEXT_LENGTH_MAX);
01966    size = strlen(callerid);
01967    if (size > TEXT_LENGTH_MAX)
01968       size = TEXT_LENGTH_MAX;
01969    memcpy(data, callerid, size);
01970 }

static void change_favorite_icon ( struct unistimsession pte,
unsigned char  status 
) [static]

Definition at line 1067 of file chan_unistim.c.

References unistimsession::device, unistim_device::next, send_favorite(), unistim_device::session, unistim_device::softkeyicon, unistim_device::softkeylabel, unistim_device::softkeylinepos, unistim_device::sp, unistimsession::state, and STATE_CLEANING.

Referenced by close_client(), handle_dial_page(), send_select_output(), show_main_page(), and unistim_call().

01068 {
01069    struct unistim_device *d = devices;
01070    int i;
01071    /* Update the current phone */
01072    if (pte->state != STATE_CLEANING)
01073       send_favorite(pte->device->softkeylinepos, status, pte,
01074                 pte->device->softkeylabel[pte->device->softkeylinepos]);
01075    /* Notify other phones if we're in their bookmark */
01076    while (d) {
01077       for (i = 0; i < 6; i++) {
01078          if (d->sp[i] == pte->device) {  /* It's us ? */
01079             if (d->softkeyicon[i] != status) {      /* Avoid resending the same icon */
01080                d->softkeyicon[i] = status;
01081                if (d->session)
01082                   send_favorite(i, status + 1, d->session, d->softkeylabel[i]);
01083             }
01084          }
01085       }
01086       d = d->next;
01087    }
01088 }

static struct unistimsession* channel_to_session ( struct ast_channel ast  )  [static, read]

Definition at line 3622 of file chan_unistim.c.

References ast_log(), LOG_WARNING, unistim_line::parent, unistim_subchannel::parent, unistim_device::session, and ast_channel::tech_pvt.

Referenced by unistim_answer(), unistim_call(), unistim_hangup(), unistim_indicate(), unistim_senddigit_begin(), unistim_senddigit_end(), and unistim_sendtext().

03623 {
03624    struct unistim_subchannel *sub;
03625    if (!ast) {
03626       ast_log(LOG_WARNING, "Unistim callback function called with a null channel\n");
03627       return NULL;
03628    }
03629    if (!ast->tech_pvt) {
03630       ast_log(LOG_WARNING, "Unistim callback function called without a tech_pvt\n");
03631       return NULL;
03632    }
03633    sub = ast->tech_pvt;
03634 
03635    if (!sub->parent) {
03636       ast_log(LOG_WARNING, "Unistim callback function called without a line\n");
03637       return NULL;
03638    }
03639    if (!sub->parent->parent) {
03640       ast_log(LOG_WARNING, "Unistim callback function called without a device\n");
03641       return NULL;
03642    }
03643    if (!sub->parent->parent->session) {
03644       ast_log(LOG_WARNING, "Unistim callback function called without a session\n");
03645       return NULL;
03646    }
03647    return sub->parent->parent->session;
03648 }

static void check_send_queue ( struct unistimsession pte  )  [static]

Definition at line 922 of file chan_unistim.c.

References ast_verb, unistimsession::last_buf_available, unistimsession::last_seq_ack, unistimsession::seq_server, and set_ping_timer().

Referenced by parsing().

00923 {
00924    /* Check if our send queue contained only one element */
00925    if (pte->last_buf_available == 1) {
00926       if (unistimdebug)
00927          ast_verb(6, "Our single packet was ACKed.\n");
00928       pte->last_buf_available--;
00929       set_ping_timer(pte);
00930       return;
00931    }
00932    /* Check if this ACK catch up our latest packet */
00933    else if (pte->last_seq_ack + 1 == pte->seq_server + 1) {
00934       if (unistimdebug)
00935          ast_verb(6, "Our send queue is completely ACKed.\n");
00936       pte->last_buf_available = 0;    /* Purge the send queue */
00937       set_ping_timer(pte);
00938       return;
00939    }
00940    if (unistimdebug)
00941       ast_verb(6, "We still have packets in our send queue\n");
00942    return;
00943 }

static void close_call ( struct unistimsession pte  )  [static]

Definition at line 1972 of file chan_unistim.c.

References unistim_subchannel::alreadygone, AST_CAUSE_NORMAL_CLEARING, ast_log(), ast_queue_hangup(), ast_queue_hangup_with_cause(), ast_verb, attempt_transfer(), change_callerid(), unistimsession::device, unistim_device::lines, LOG_WARNING, unistim_device::missed_call, unistim_device::name, unistim_line::name, unistim_subchannel::owner, unistim_line::parent, unistim_subchannel::parent, unistim_device::redial_number, send_stop_timer(), show_main_page(), SUB_REAL, SUB_THREEWAY, unistim_line::subs, unistim_subchannel::subtype, and write_history().

Referenced by key_call(), process_request(), and unistim_hangup().

01973 {
01974    struct unistim_subchannel *sub;
01975    struct unistim_line *l = pte->device->lines;
01976 
01977    sub = pte->device->lines->subs[SUB_REAL];
01978    send_stop_timer(pte);
01979    if (sub->owner) {
01980       sub->alreadygone = 1;
01981       if (l->subs[SUB_THREEWAY]) {
01982          l->subs[SUB_THREEWAY]->alreadygone = 1;
01983          if (attempt_transfer(sub, l->subs[SUB_THREEWAY]) < 0)
01984             ast_verb(0, "attempt_transfer failed.\n");
01985       } else
01986          ast_queue_hangup(sub->owner);
01987    } else {
01988       if (l->subs[SUB_THREEWAY]) {
01989          if (l->subs[SUB_THREEWAY]->owner)
01990             ast_queue_hangup_with_cause(l->subs[SUB_THREEWAY]->owner, AST_CAUSE_NORMAL_CLEARING);
01991          else
01992             ast_log(LOG_WARNING, "threeway sub without owner\n");
01993       } else
01994          ast_verb(0, "USTM(%s@%s-%d) channel already destroyed\n", sub->parent->name,
01995                   sub->parent->parent->name, sub->subtype);
01996    }
01997    change_callerid(pte, 0, pte->device->redial_number);
01998    change_callerid(pte, 1, "");
01999    write_history(pte, 'o', pte->device->missed_call);
02000    pte->device->missed_call = 0;
02001    show_main_page(pte);
02002    return;
02003 }

static void close_client ( struct unistimsession s  )  [static]

Definition at line 1111 of file chan_unistim.c.

References AST_CAUSE_NETWORK_OUT_OF_ORDER, ast_free, ast_log(), ast_mutex_destroy(), ast_mutex_lock(), ast_mutex_unlock(), ast_queue_hangup_with_cause(), ast_strlen_zero(), ast_verb, change_favorite_icon(), unistimsession::device, unistim_device::extension_number, FAV_ICON_NONE, unistim_device::lines, unistimsession::lock, LOG_WARNING, unistimsession::next, unistim_subchannel::owner, unistim_device::session, sessionlock, unistimsession::state, STATE_CLEANING, SUB_REAL, unistim_line::subs, and UnregisterExtension().

Referenced by parsing(), and send_retransmit().

01112 {
01113    struct unistim_subchannel *sub;
01114    struct unistimsession *cur, *prev = NULL;
01115    ast_mutex_lock(&sessionlock);
01116    cur = sessions;
01117    /* Looking for the session in the linked chain */
01118    while (cur) {
01119       if (cur == s)
01120          break;
01121       prev = cur;
01122       cur = cur->next;
01123    }
01124    if (cur) {                 /* Session found ? */
01125       if (cur->device) {         /* This session was registered ? */
01126          s->state = STATE_CLEANING;
01127          if (unistimdebug)
01128             ast_verb(0, "close_client session %p device %p lines %p sub %p\n",
01129                      s, s->device, s->device->lines,
01130                      s->device->lines->subs[SUB_REAL]);
01131          change_favorite_icon(s, FAV_ICON_NONE);
01132          sub = s->device->lines->subs[SUB_REAL];
01133          if (sub) {
01134             if (sub->owner) {       /* Call in progress ? */
01135                if (unistimdebug)
01136                   ast_verb(0, "Aborting call\n");
01137                ast_queue_hangup_with_cause(sub->owner, AST_CAUSE_NETWORK_OUT_OF_ORDER);
01138             }
01139          } else
01140             ast_log(LOG_WARNING, "Freeing a client with no subchannel !\n");
01141          if (!ast_strlen_zero(s->device->extension_number))
01142             UnregisterExtension(s);
01143          cur->device->session = NULL;
01144       } else {
01145          if (unistimdebug)
01146             ast_verb(0, "Freeing an unregistered client\n");
01147       }
01148       if (prev)
01149          prev->next = cur->next;
01150       else
01151          sessions = cur->next;
01152       ast_mutex_destroy(&s->lock);
01153       ast_free(s);
01154    } else
01155       ast_log(LOG_WARNING, "Trying to delete non-existent session %p?\n", s);
01156    ast_mutex_unlock(&sessionlock);
01157    return;
01158 }

static char* control2str ( int  ind  )  [static]

Definition at line 4028 of file chan_unistim.c.

References AST_CONTROL_ANSWER, AST_CONTROL_BUSY, AST_CONTROL_CONGESTION, AST_CONTROL_FLASH, AST_CONTROL_HANGUP, AST_CONTROL_OFFHOOK, AST_CONTROL_OPTION, AST_CONTROL_RADIO_KEY, AST_CONTROL_RADIO_UNKEY, AST_CONTROL_RING, AST_CONTROL_RINGING, AST_CONTROL_TAKEOFFHOOK, and AST_CONTROL_WINK.

04029 {
04030    switch (ind) {
04031    case AST_CONTROL_HANGUP:
04032       return "Other end has hungup";
04033    case AST_CONTROL_RING:
04034       return "Local ring";
04035    case AST_CONTROL_RINGING:
04036       return "Remote end is ringing";
04037    case AST_CONTROL_ANSWER:
04038       return "Remote end has answered";
04039    case AST_CONTROL_BUSY:
04040       return "Remote end is busy";
04041    case AST_CONTROL_TAKEOFFHOOK:
04042       return "Make it go off hook";
04043    case AST_CONTROL_OFFHOOK:
04044       return "Line is off hook";
04045    case AST_CONTROL_CONGESTION:
04046       return "Congestion (circuits busy)";
04047    case AST_CONTROL_FLASH:
04048       return "Flash hook";
04049    case AST_CONTROL_WINK:
04050       return "Wink";
04051    case AST_CONTROL_OPTION:
04052       return "Set a low-level option";
04053    case AST_CONTROL_RADIO_KEY:
04054       return "Key Radio";
04055    case AST_CONTROL_RADIO_UNKEY:
04056       return "Un-Key Radio";
04057    case -1:
04058       return "Stop tone";
04059    }
04060    return "UNKNOWN";
04061 }

static struct unistimsession* create_client ( const struct sockaddr_in *  addr_from  )  [static, read]

Definition at line 867 of file chan_unistim.c.

References ast_calloc, ast_inet_ntoa(), ast_mutex_init(), ast_mutex_lock(), ast_mutex_unlock(), ast_verb, unistimsession::buf, wsabuf::buf, get_tick_count(), get_to_address(), unistimsession::last_buf_available, unistimsession::last_seq_ack, unistimsession::lock, MAX_BUF_NUMBER, unistimsession::nb_retransmit, unistimsession::next, RETRANSMIT_TIMER, s, unistimsession::seq_phone, unistimsession::seq_server, sessionlock, unistimsession::sin, unistimsession::sout, unistimsession::state, STATE_INIT, unistimsession::tick_next_ping, unistimsession::timeout, and unistimsession::wsabufsend.

Referenced by parsing().

00868 {
00869    int tmp;
00870    struct unistimsession *s;
00871 
00872    if (!(s = ast_calloc(1, sizeof(*s))))
00873       return NULL;
00874 
00875    memcpy(&s->sin, addr_from, sizeof(struct sockaddr_in));
00876    get_to_address(unistimsock, &s->sout);
00877    if (unistimdebug) {
00878       ast_verb(0, "Creating a new entry for the phone from %s received via server ip %s\n",
00879           ast_inet_ntoa(addr_from->sin_addr), ast_inet_ntoa(s->sout.sin_addr));
00880    }
00881    ast_mutex_init(&s->lock);
00882    ast_mutex_lock(&sessionlock);
00883    s->next = sessions;
00884    sessions = s;
00885 
00886    s->timeout = get_tick_count() + RETRANSMIT_TIMER;
00887    s->seq_phone = (short) 0x0000;
00888    s->seq_server = (short) 0x0000;
00889    s->last_seq_ack = (short) 0x000;
00890    s->last_buf_available = 0;
00891    s->nb_retransmit = 0;
00892    s->state = STATE_INIT;
00893    s->tick_next_ping = get_tick_count() + unistim_keepalive;
00894    /* Initialize struct wsabuf  */
00895    for (tmp = 0; tmp < MAX_BUF_NUMBER; tmp++) {
00896       s->wsabufsend[tmp].buf = s->buf[tmp];
00897    }
00898    ast_mutex_unlock(&sessionlock);
00899    return s;
00900 }

static void display_last_error ( const char *  sz_msg  )  [static]

Definition at line 717 of file chan_unistim.c.

References ast_log(), errno, and LOG_WARNING.

Referenced by build_device(), HandleCallOutgoing(), key_history(), OpenHistory(), send_raw_client(), show_entry_history(), write_entry_history(), and write_history().

00718 {
00719    time_t cur_time;
00720    
00721    time(&cur_time);
00722 
00723    /* Display the error message */
00724    ast_log(LOG_WARNING, "%s %s : (%u) %s\n", ctime(&cur_time), sz_msg, errno,
00725          strerror(errno));
00726 }

static void* do_monitor ( void *  data  )  [static]

Definition at line 4510 of file chan_unistim.c.

References ast_io_add(), AST_IO_IN, ast_io_wait(), ast_mutex_lock(), ast_mutex_unlock(), ast_strlen_zero(), ast_verb, DEBUG_TIMER, unistimsession::device, get_tick_count(), IDLE_WAIT, unistimsession::last_buf_available, unistim_device::lines, unistim_line::mailbox, unistimsession::next, unistim_line::nextmsgcheck, reload_config(), send_ping(), send_retransmit(), sessionlock, unistimsession::timeout, unistim_reload_lock, unistim_send_mwi_to_peer(), and unistimsock_read().

04511 {
04512    struct unistimsession *cur = NULL;
04513    unsigned int dw_timeout = 0;
04514    unsigned int tick;
04515    int res;
04516    int reloading;
04517 
04518    /* Add an I/O event to our UDP socket */
04519    if (unistimsock > -1)
04520       ast_io_add(io, unistimsock, unistimsock_read, AST_IO_IN, NULL);
04521 
04522    /* This thread monitors our UDP socket and timers */
04523    for (;;) {
04524       /* This loop is executed at least every IDLE_WAITus (1s) or every time a packet is received */
04525       /* Looking for the smallest time-out value */
04526       tick = get_tick_count();
04527       dw_timeout = UINT_MAX;
04528       ast_mutex_lock(&sessionlock);
04529       cur = sessions;
04530       DEBUG_TIMER("checking timeout for session %p with tick = %u\n", cur, tick);
04531       while (cur) {
04532          DEBUG_TIMER("checking timeout for session %p timeout = %u\n", cur,
04533                   cur->timeout);
04534          /* Check if we have miss something */
04535          if (cur->timeout <= tick) {
04536             DEBUG_TIMER("Event for session %p\n", cur);
04537             /* If the queue is empty, send a ping */
04538             if (cur->last_buf_available == 0)
04539                send_ping(cur);
04540             else {
04541                if (send_retransmit(cur)) {
04542                   DEBUG_TIMER("The chained link was modified, restarting...\n");
04543                   cur = sessions;
04544                   dw_timeout = UINT_MAX;
04545                   continue;
04546                }
04547             }
04548          }
04549          if (dw_timeout > cur->timeout - tick)
04550             dw_timeout = cur->timeout - tick;
04551          /* Checking if the phone is logged on for a new MWI */
04552          if (cur->device) {
04553             if ((!ast_strlen_zero(cur->device->lines->mailbox)) &&
04554                ((tick >= cur->device->lines->nextmsgcheck))) {
04555                DEBUG_TIMER("Checking mailbox for MWI\n");
04556                unistim_send_mwi_to_peer(cur, tick);
04557                break;
04558             }
04559          }
04560          cur = cur->next;
04561       }
04562       ast_mutex_unlock(&sessionlock);
04563       DEBUG_TIMER("Waiting for %dus\n", dw_timeout);
04564       res = dw_timeout;
04565       /* We should not wait more than IDLE_WAIT */
04566       if ((res < 0) || (res > IDLE_WAIT))
04567          res = IDLE_WAIT;
04568       /* Wait for UDP messages for a maximum of res us */
04569       res = ast_io_wait(io, res);     /* This function will call unistimsock_read if a packet is received */
04570       /* Check for a reload request */
04571       ast_mutex_lock(&unistim_reload_lock);
04572       reloading = unistim_reloading;
04573       unistim_reloading = 0;
04574       ast_mutex_unlock(&unistim_reload_lock);
04575       if (reloading) {
04576          ast_verb(1, "Reloading unistim.conf...\n");
04577          reload_config();
04578       }
04579       pthread_testcancel();
04580    }
04581    /* Never reached */
04582    return NULL;
04583 }

static void dummy ( char *  unused,
  ... 
) [static]

static struct unistim_subchannel* find_subchannel_by_name ( const char *  dest  )  [static, read]

Definition at line 4145 of file chan_unistim.c.

References ast_copy_string(), ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_verb, devicelock, unistim_device::lines, LOG_NOTICE, LOG_WARNING, unistim_line::name, unistim_device::name, unistim_device::next, unistim_line::next, unistim_subchannel::ringstyle, unistim_subchannel::ringvolume, SUB_REAL, and unistim_line::subs.

Referenced by unistim_request(), and unistim_sp().

04146 {
04147    struct unistim_line *l;
04148    struct unistim_device *d;
04149    char line[256];
04150    char *at;
04151    char *device;
04152 
04153    ast_copy_string(line, dest, sizeof(line));
04154    at = strchr(line, '@');
04155    if (!at) {
04156       ast_log(LOG_NOTICE, "Device '%s' has no @ (at) sign!\n", dest);
04157       return NULL;
04158    }
04159    *at = '\0';
04160    at++;
04161    device = at;
04162    ast_mutex_lock(&devicelock);
04163    d = devices;
04164    at = strchr(device, '/');       /* Extra options ? */
04165    if (at)
04166       *at = '\0';
04167    while (d) {
04168       if (!strcasecmp(d->name, device)) {
04169          if (unistimdebug)
04170             ast_verb(0, "Found device: %s\n", d->name);
04171          /* Found the device */
04172          l = d->lines;
04173          while (l) {
04174             /* Search for the right line */
04175             if (!strcasecmp(l->name, line)) {
04176                l->subs[SUB_REAL]->ringvolume = -1;
04177                l->subs[SUB_REAL]->ringstyle = -1;
04178                if (at) {       /* Other options ? */
04179                   at++;   /* Skip slash */
04180                   if (*at == 'r') {       /* distinctive ring */
04181                      at++;
04182                      if ((*at < '0') || (*at > '7')) /* ring style */
04183                         ast_log(LOG_WARNING, "Invalid ring selection (%s)", at);
04184                      else {
04185                         char ring_volume = -1;
04186                         char ring_style = *at - '0';
04187                         at++;
04188                         if ((*at >= '0') && (*at <= '3'))       /* ring volume */
04189                            ring_volume = *at - '0';
04190                         if (unistimdebug)
04191                            ast_verb(0, "Distinctive ring : style #%d volume %d\n",
04192                                ring_style, ring_volume);
04193                         l->subs[SUB_REAL]->ringvolume = ring_volume;
04194                         l->subs[SUB_REAL]->ringstyle = ring_style;
04195                      }
04196                   }
04197                }
04198                ast_mutex_unlock(&devicelock);
04199                return l->subs[SUB_REAL];
04200             }
04201             l = l->next;
04202          }
04203       }
04204       d = d->next;
04205    }
04206    /* Device not found */
04207    ast_mutex_unlock(&devicelock);
04208 
04209    return NULL;
04210 }

static void finish_bookmark ( void   )  [static]

Definition at line 4974 of file chan_unistim.c.

References ast_log(), LOG_NOTICE, unistim_device::name, unistim_device::next, unistim_device::softkeydevice, unistim_device::softkeyicon, and unistim_device::sp.

Referenced by reload_config().

04975 {
04976    struct unistim_device *d = devices;
04977    int i;
04978    while (d) {
04979       for (i = 0; i < 6; i++) {
04980          if (d->softkeyicon[i] == 1) {   /* Something for us */
04981             struct unistim_device *d2 = devices;
04982             while (d2) {
04983                if (!strcmp(d->softkeydevice[i], d2->name)) {
04984                   d->sp[i] = d2;
04985                   d->softkeyicon[i] = 0;
04986                   break;
04987                }
04988                d2 = d2->next;
04989             }
04990             if (d->sp[i] == NULL)
04991                ast_log(LOG_NOTICE, "Bookmark entry with device %s not found\n",
04992                      d->softkeydevice[i]);
04993          }
04994       }
04995       d = d->next;
04996    }
04997 }

static unsigned int get_tick_count ( void   )  [static]

Definition at line 728 of file chan_unistim.c.

References ast_tvnow().

Referenced by create_client(), do_monitor(), send_client(), send_ping(), and send_retransmit().

00729 {
00730    struct timeval now = ast_tvnow();
00731 
00732    return (now.tv_sec * 1000) + (now.tv_usec / 1000);
00733 }

static int get_to_address ( int  fd,
struct sockaddr_in *  toAddr 
) [static]

Definition at line 834 of file chan_unistim.c.

References ast_log(), errno, len(), and LOG_WARNING.

Referenced by create_client().

00835 {
00836 #ifdef HAVE_PKTINFO
00837    int err;
00838    struct msghdr msg;
00839    struct {
00840       struct cmsghdr cm;
00841       int len;
00842       struct in_addr address;
00843    } ip_msg;
00844 
00845    /* Zero out the structures before we use them */
00846    /* This sets several key values to NULL */
00847    memset(&msg, 0, sizeof(msg));
00848    memset(&ip_msg, 0, sizeof(ip_msg));
00849 
00850    /* Initialize the message structure */
00851    msg.msg_control = &ip_msg;
00852    msg.msg_controllen = sizeof(ip_msg);
00853    /* Get info about the incoming packet */
00854    err = recvmsg(fd, &msg, MSG_PEEK);
00855    if (err == -1)
00856       ast_log(LOG_WARNING, "recvmsg returned an error: %s\n", strerror(errno));
00857    memcpy(&toAddr->sin_addr, &ip_msg.address, sizeof(struct in_addr));
00858    return err;
00859 #else
00860    memcpy(&toAddr, &public_ip, sizeof(&toAddr));
00861    return 0;
00862 #endif
00863 }

static void handle_dial_page ( struct unistimsession pte  )  [static]

Definition at line 2259 of file chan_unistim.c.

References ast_copy_string(), unistim_device::call_forward, change_favorite_icon(), unistimsession::device, FAV_ICON_NONE, FAV_ICON_PHONE_BLACK, unistim_device::missed_call, MUTE_OFF, unistim_device::output, OUTPUT_HANDSET, OUTPUT_SPEAKER, unistim_device::phone_number, unistim_device::receiver_state, send_blink_cursor(), send_cursor_pos(), send_led_update(), send_select_output(), send_text(), send_text_status(), SendDialTone(), Sendicon(), unistim_device::size_phone_number, unistimsession::state, STATE_DIALPAGE, STATE_ONHOOK, TEXT_LENGTH_MAX, TEXT_LINE0, TEXT_LINE1, TEXT_LINE2, TEXT_NORMAL, and unistim_device::volume.

Referenced by key_main_page(), process_request(), and TransferCallStep1().

02260 {
02261    pte->state = STATE_DIALPAGE;
02262    if (pte->device->call_forward[0] == -1) {
02263       send_text(TEXT_LINE0, TEXT_NORMAL, pte, "");
02264       send_text(TEXT_LINE1, TEXT_NORMAL, pte, "Enter forward");
02265       send_text_status(pte, "ForwardCancel BackSpcErase");
02266       if (pte->device->call_forward[1] != 0) {
02267          char tmp[TEXT_LENGTH_MAX + 1];
02268 
02269          ast_copy_string(pte->device->phone_number, pte->device->call_forward + 1,
02270                      sizeof(pte->device->phone_number));
02271          pte->device->size_phone_number = strlen(pte->device->phone_number);
02272          if (pte->device->size_phone_number > 15)
02273             pte->device->size_phone_number = 15;
02274          strcpy(tmp, "Number : ...............");
02275          memcpy(tmp + 9, pte->device->phone_number, pte->device->size_phone_number);
02276          send_text(TEXT_LINE2, TEXT_NORMAL, pte, tmp);
02277          send_blink_cursor(pte);
02278          send_cursor_pos(pte,
02279                     (unsigned char) (TEXT_LINE2 + 0x09 +
02280                                  pte->device->size_phone_number));
02281          send_led_update(pte, 0);
02282          return;
02283       }
02284    } else {
02285       if ((pte->device->output == OUTPUT_HANDSET) &&
02286          (pte->device->receiver_state == STATE_ONHOOK))
02287          send_select_output(pte, OUTPUT_SPEAKER, pte->device->volume, MUTE_OFF);
02288       else
02289          send_select_output(pte, pte->device->output, pte->device->volume, MUTE_OFF);
02290       SendDialTone(pte);
02291       send_text(TEXT_LINE0, TEXT_NORMAL, pte, "Enter the number to dial");
02292       send_text(TEXT_LINE1, TEXT_NORMAL, pte, "and press Call");
02293       send_text_status(pte, "Call   Redial BackSpcErase");
02294    }
02295    send_text(TEXT_LINE2, TEXT_NORMAL, pte, "Number : ...............");
02296    send_blink_cursor(pte);
02297    send_cursor_pos(pte, TEXT_LINE2 + 0x09);
02298    pte->device->size_phone_number = 0;
02299    pte->device->phone_number[0] = 0;
02300    change_favorite_icon(pte, FAV_ICON_PHONE_BLACK);
02301    Sendicon(TEXT_LINE0, FAV_ICON_NONE, pte);
02302    pte->device->missed_call = 0;
02303    send_led_update(pte, 0);
02304    return;
02305 }

static void HandleCallIncoming ( struct unistimsession s  )  [static]

Definition at line 2443 of file chan_unistim.c.

References AST_CONTROL_ANSWER, ast_log(), ast_queue_control(), ast_verb, unistimsession::device, unistim_device::lines, LOG_NOTICE, LOG_WARNING, unistim_device::missed_call, MUTE_OFF, unistim_line::name, unistim_device::name, unistim_device::output, OUTPUT_HANDSET, OUTPUT_SPEAKER, unistim_subchannel::owner, unistim_subchannel::parent, unistim_device::receiver_state, unistim_subchannel::rtp, send_no_ring(), send_select_output(), send_start_timer(), send_text(), send_text_status(), unistim_device::start_call_timestamp, start_rtp(), unistimsession::state, STATE_CALL, STATE_ONHOOK, SUB_REAL, unistim_line::subs, TEXT_LINE2, TEXT_NORMAL, unistim_device::volume, and write_history().

Referenced by key_ringing(), and process_request().

02444 {
02445    struct unistim_subchannel *sub;
02446    s->state = STATE_CALL;
02447    s->device->missed_call = 0;
02448    send_no_ring(s);
02449    sub = s->device->lines->subs[SUB_REAL];
02450    if (!sub) {
02451       ast_log(LOG_NOTICE, "No available lines on: %s\n", s->device->name);
02452       return;
02453    } else if (unistimdebug)
02454       ast_verb(0, "Handle Call Incoming for %s@%s\n", sub->parent->name,
02455                s->device->name);
02456    start_rtp(sub);
02457    if (!sub->rtp)
02458       ast_log(LOG_WARNING, "Unable to create channel for %s@%s\n", sub->parent->name,
02459             s->device->name);
02460    ast_queue_control(sub->owner, AST_CONTROL_ANSWER);
02461    send_text(TEXT_LINE2, TEXT_NORMAL, s, "is on-line");
02462    send_text_status(s, "Hangup Transf");
02463    send_start_timer(s);
02464 
02465    if ((s->device->output == OUTPUT_HANDSET) &&
02466       (s->device->receiver_state == STATE_ONHOOK))
02467       send_select_output(s, OUTPUT_SPEAKER, s->device->volume, MUTE_OFF);
02468    else
02469       send_select_output(s, s->device->output, s->device->volume, MUTE_OFF);
02470    s->device->start_call_timestamp = time(0);
02471    write_history(s, 'i', 0);
02472    return;
02473 }

static void HandleCallOutgoing ( struct unistimsession s  )  [static]

Definition at line 2354 of file chan_unistim.c.

References alloc_sub(), AST_CAUSE_SWITCH_CONGESTION, ast_channel_stop_silence_generator(), ast_debug, ast_hangup(), ast_log(), ast_pthread_create, ast_queue_hangup_with_cause(), AST_STATE_DOWN, ast_verb, unistimsession::device, display_last_error(), unistim_device::lines, LOG_NOTICE, LOG_WARNING, unistim_device::moh, MUTE_OFF, ast_channel::name, unistim_line::name, unistim_device::name, unistim_device::output, unistim_subchannel::owner, unistim_subchannel::parent, unistim_device::phone_number, unistim_subchannel::rtp, send_select_output(), send_text(), send_text_status(), send_tone(), unistim_device::silence_generator, start_rtp(), unistimsession::state, STATE_CALL, SUB_REAL, SUB_THREEWAY, unistim_line::subs, unistim_subchannel::subtype, swap_subs(), TEXT_LINE0, TEXT_LINE1, TEXT_LINE2, TEXT_NORMAL, unistim_new(), unistim_ss(), and unistim_device::volume.

Referenced by key_dial_page(), key_main_page(), and Keyfavorite().

02355 {
02356    struct ast_channel *c;
02357    struct unistim_subchannel *sub;
02358    pthread_t t;
02359    s->state = STATE_CALL;
02360    sub = s->device->lines->subs[SUB_REAL];
02361    if (!sub) {
02362       ast_log(LOG_NOTICE, "No available lines on: %s\n", s->device->name);
02363       return;
02364    }
02365    if (!sub->owner) {            /* A call is already in progress ? */
02366       c = unistim_new(sub, AST_STATE_DOWN, NULL);   /* No, starting a new one */
02367       if (c) {
02368          /* Need to start RTP before calling ast_pbx_run */
02369          if (!sub->rtp)
02370             start_rtp(sub);
02371          send_select_output(s, s->device->output, s->device->volume, MUTE_OFF);
02372          send_text(TEXT_LINE0, TEXT_NORMAL, s, "Calling :");
02373          send_text(TEXT_LINE1, TEXT_NORMAL, s, s->device->phone_number);
02374          send_text(TEXT_LINE2, TEXT_NORMAL, s, "Dialing...");
02375          send_text_status(s, "Hangup");
02376          /* start switch */
02377          if (ast_pthread_create(&t, NULL, unistim_ss, c)) {
02378             display_last_error("Unable to create switch thread");
02379             ast_queue_hangup_with_cause(c, AST_CAUSE_SWITCH_CONGESTION);
02380          }
02381       } else
02382          ast_log(LOG_WARNING, "Unable to create channel for %s@%s\n",
02383                sub->parent->name, s->device->name);
02384    } else {             /* We already have a call, so we switch in a threeway call */
02385 
02386       if (s->device->moh) {
02387          struct unistim_subchannel *subchannel;
02388          struct unistim_line *p = s->device->lines;
02389          subchannel = p->subs[SUB_REAL];
02390 
02391          if (!subchannel->owner) {
02392             ast_log(LOG_WARNING, "Unable to find subchannel for music on hold\n");
02393             return;
02394          }
02395          if (p->subs[SUB_THREEWAY]) {
02396             ast_log(LOG_WARNING,
02397                   "Can't transfer while an another transfer is taking place\n");
02398             return;
02399          }
02400          if (!alloc_sub(p, SUB_THREEWAY)) {
02401             ast_log(LOG_WARNING, "Unable to allocate three-way subchannel\n");
02402             return;
02403          }
02404          /* Stop the silence generator */
02405          if (s->device->silence_generator) {
02406             if (unistimdebug)
02407                ast_verb(0, "Stopping silence generator\n");
02408             ast_channel_stop_silence_generator(subchannel->owner,
02409                                        s->device->silence_generator);
02410             s->device->silence_generator = NULL;
02411          }
02412          send_tone(s, 0, 0);
02413          /* Make new channel */
02414          c = unistim_new(p->subs[SUB_THREEWAY], AST_STATE_DOWN, NULL);
02415          if (!c) {
02416             ast_log(LOG_WARNING, "Cannot allocate new structure on channel %p\n", p);
02417             return;
02418          }
02419          /* Swap things around between the three-way and real call */
02420          swap_subs(p, SUB_THREEWAY, SUB_REAL);
02421          send_select_output(s, s->device->output, s->device->volume, MUTE_OFF);
02422          send_text(TEXT_LINE0, TEXT_NORMAL, s, "Calling (pre-transfer)");
02423          send_text(TEXT_LINE1, TEXT_NORMAL, s, s->device->phone_number);
02424          send_text(TEXT_LINE2, TEXT_NORMAL, s, "Dialing...");
02425          send_text_status(s, "TransfrCancel");
02426 
02427          if (ast_pthread_create(&t, NULL, unistim_ss, p->subs[SUB_THREEWAY]->owner)) {
02428             ast_log(LOG_WARNING, "Unable to start simple switch on channel %p\n", p);
02429             ast_hangup(c);
02430             return;
02431          }
02432          if (unistimdebug)
02433             ast_verb(0, "Started three way call on channel %p (%s) subchan %d\n",
02434                 p->subs[SUB_THREEWAY]->owner, p->subs[SUB_THREEWAY]->owner->name,
02435                 p->subs[SUB_THREEWAY]->subtype);
02436       } else
02437          ast_debug(1, "Current sub [%s] already has owner\n", sub->owner->name);
02438    }
02439    return;
02440 }

static void HandleSelectCodec ( struct unistimsession pte  )  [static]

Definition at line 2775 of file chan_unistim.c.

References buf, buf2, unistim_device::codec_number, unistimsession::device, SELECTCODEC_MSG, SELECTCODEC_START_ENTRY_POS, send_blink_cursor(), send_cursor_pos(), send_text(), send_text_status(), unistimsession::size_buff_entry, unistimsession::state, STATE_SELECTCODEC, TEXT_INVERSE, TEXT_LINE0, TEXT_LINE1, TEXT_LINE2, and TEXT_NORMAL.

Referenced by key_main_page().

02776 {
02777    char buf[30], buf2[5];
02778 
02779    pte->state = STATE_SELECTCODEC;
02780    strcpy(buf, "Using codec ");
02781    sprintf(buf2, "%d", pte->device->codec_number);
02782    strcat(buf, buf2);
02783    strcat(buf, " (G711u=0,");
02784 
02785    send_text(TEXT_LINE0, TEXT_NORMAL, pte, buf);
02786    send_text(TEXT_LINE1, TEXT_NORMAL, pte, "G723=4,G711a=8,G729A=18)");
02787    send_text(TEXT_LINE2, TEXT_INVERSE, pte, SELECTCODEC_MSG);
02788    send_blink_cursor(pte);
02789    send_cursor_pos(pte, TEXT_LINE2 + SELECTCODEC_START_ENTRY_POS);
02790    pte->size_buff_entry = 0;
02791    send_text_status(pte, "Select BackSpcErase  Cancel");
02792    return;
02793 }

static void IgnoreCall ( struct unistimsession pte  )  [static]

Definition at line 2005 of file chan_unistim.c.

References send_no_ring().

Referenced by key_ringing().

02006 {
02007    send_no_ring(pte);
02008    return;
02009 }

static void in_band_indication ( struct ast_channel ast,
const struct ast_tone_zone tz,
const char *  indication 
) [static]

Definition at line 4063 of file chan_unistim.c.

References ast_get_indication_tone(), ast_log(), ast_playtones_start(), ast_tone_zone_sound_unref(), ast_tone_zone_sound::data, and LOG_WARNING.

Referenced by unistim_indicate().

04065 {
04066    struct ast_tone_zone_sound *ts = NULL;
04067 
04068    if ((ts = ast_get_indication_tone(tz, indication))) {
04069       ast_playtones_start(ast, 0, ts->data, 1);
04070       ts = ast_tone_zone_sound_unref(ts);
04071    } else {
04072       ast_log(LOG_WARNING, "Unable to get indication tone for %s\n", indication);
04073    }
04074 }

static void init_phone_step2 ( struct unistimsession pte  )  [static]

Definition at line 3287 of file chan_unistim.c.

References ast_verb, AUTOPROVISIONING_TN, BUFFSEND, unistim_device::contrast, unistimsession::device, unistimsession::macaddr, refresh_all_favorite(), send_client(), send_date_time2(), send_date_time3(), send_favorite(), send_led_update(), send_no_ring(), send_ping(), send_text(), send_text_status(), send_texttitle(), show_main_page(), ShowExtensionPage(), SIZE_HEADER, unistimsession::state, STATE_MAINPAGE, TEXT_LINE0, TEXT_LINE1, TEXT_LINE2, and TEXT_NORMAL.

Referenced by process_request().

03288 {
03289    BUFFSEND;
03290    if (unistimdebug)
03291       ast_verb(0, "Sending S4\n");
03292    memcpy(buffsend + SIZE_HEADER, packet_send_s4, sizeof(packet_send_s4));
03293    send_client(SIZE_HEADER + sizeof(packet_send_s4), buffsend, pte);
03294    send_date_time2(pte);
03295    send_date_time3(pte);
03296    if (unistimdebug)
03297       ast_verb(0, "Sending S7\n");
03298    memcpy(buffsend + SIZE_HEADER, packet_send_S7, sizeof(packet_send_S7));
03299    send_client(SIZE_HEADER + sizeof(packet_send_S7), buffsend, pte);
03300    if (unistimdebug)
03301       ast_verb(0, "Sending Contrast\n");
03302    memcpy(buffsend + SIZE_HEADER, packet_send_Contrast, sizeof(packet_send_Contrast));
03303    if (pte->device != NULL)
03304       buffsend[9] = pte->device->contrast;
03305    send_client(SIZE_HEADER + sizeof(packet_send_Contrast), buffsend, pte);
03306 
03307    if (unistimdebug)
03308       ast_verb(0, "Sending S9\n");
03309    memcpy(buffsend + SIZE_HEADER, packet_send_s9, sizeof(packet_send_s9));
03310    send_client(SIZE_HEADER + sizeof(packet_send_s9), buffsend, pte);
03311    send_no_ring(pte);
03312 
03313    if (unistimdebug)
03314       ast_verb(0, "Sending S7\n");
03315    memcpy(buffsend + SIZE_HEADER, packet_send_S7, sizeof(packet_send_S7));
03316    send_client(SIZE_HEADER + sizeof(packet_send_S7), buffsend, pte);
03317    send_led_update(pte, 0);
03318    send_ping(pte);
03319    if (pte->state < STATE_MAINPAGE) {
03320       if (autoprovisioning == AUTOPROVISIONING_TN) {
03321          ShowExtensionPage(pte);
03322          return;
03323       } else {
03324          int i;
03325          char tmp[30];
03326 
03327          for (i = 1; i < 6; i++)
03328             send_favorite(i, 0, pte, "");
03329          send_text(TEXT_LINE0, TEXT_NORMAL, pte, "Sorry, this phone is not");
03330          send_text(TEXT_LINE1, TEXT_NORMAL, pte, "registered in unistim.cfg");
03331          strcpy(tmp, "MAC = ");
03332          strcat(tmp, pte->macaddr);
03333          send_text(TEXT_LINE2, TEXT_NORMAL, pte, tmp);
03334          send_text_status(pte, "");
03335          send_texttitle(pte, "UNISTIM for*");
03336          return;
03337       }
03338    }
03339    show_main_page(pte);
03340    refresh_all_favorite(pte);
03341    if (unistimdebug)
03342       ast_verb(0, "Sending arrow\n");
03343    memcpy(buffsend + SIZE_HEADER, packet_send_arrow, sizeof(packet_send_arrow));
03344    send_client(SIZE_HEADER + sizeof(packet_send_arrow), buffsend, pte);
03345    return;
03346 }

static void key_call ( struct unistimsession pte,
char  keycode 
) [static]

Definition at line 2547 of file chan_unistim.c.

References ast_bridged_channel(), ast_log(), ast_moh_start(), ast_moh_stop(), close_call(), unistimsession::device, KEY_0, KEY_FUNC1, KEY_FUNC2, KEY_HANGUP, KEY_HEADPHN, KEY_LOUDSPK, KEY_MUTE, KEY_ONHOLD, KEY_SHARP, KEY_STAR, unistim_device::lines, LOG_WARNING, unistim_device::moh, unistim_line::musicclass, unistim_device::mute, MUTE_OFF, MUTE_ON, unistim_device::output, OUTPUT_HANDSET, OUTPUT_HEADPHONE, OUTPUT_SPEAKER, unistim_subchannel::owner, unistim_device::previous_output, send_select_output(), SUB_REAL, unistim_line::subs, TransferCallStep1(), unistim_do_senddigit(), and unistim_device::volume.

Referenced by process_request().

02548 {
02549    if ((keycode >= KEY_0) && (keycode <= KEY_SHARP)) {
02550       if (keycode == KEY_SHARP)
02551          keycode = '#';
02552       else if (keycode == KEY_STAR)
02553          keycode = '*';
02554       else
02555          keycode -= 0x10;
02556       unistim_do_senddigit(pte, keycode);
02557       return;
02558    }
02559    switch (keycode) {
02560    case KEY_HANGUP:
02561    case KEY_FUNC1:
02562       close_call(pte);
02563       break;
02564    case KEY_FUNC2:
02565       TransferCallStep1(pte);
02566       break;
02567    case KEY_HEADPHN:
02568       if (pte->device->output == OUTPUT_HEADPHONE)
02569          send_select_output(pte, OUTPUT_HANDSET, pte->device->volume, MUTE_OFF);
02570       else
02571          send_select_output(pte, OUTPUT_HEADPHONE, pte->device->volume, MUTE_OFF);
02572       break;
02573    case KEY_LOUDSPK:
02574       if (pte->device->output != OUTPUT_SPEAKER)
02575          send_select_output(pte, OUTPUT_SPEAKER, pte->device->volume, MUTE_OFF);
02576       else
02577          send_select_output(pte, pte->device->previous_output, pte->device->volume,
02578                       MUTE_OFF);
02579       break;
02580    case KEY_MUTE:
02581       if (!pte->device->moh) {
02582          if (pte->device->mute == MUTE_ON)
02583             send_select_output(pte, pte->device->output, pte->device->volume, MUTE_OFF);
02584          else
02585             send_select_output(pte, pte->device->output, pte->device->volume, MUTE_ON);
02586          break;
02587       }
02588    case KEY_ONHOLD:
02589       {
02590          struct unistim_subchannel *sub;
02591          struct ast_channel *bridgepeer = NULL;
02592          sub = pte->device->lines->subs[SUB_REAL];
02593          if (!sub->owner) {
02594             ast_log(LOG_WARNING, "Unable to find subchannel for music on hold\n");
02595             return;
02596          }
02597          if ((bridgepeer = ast_bridged_channel(sub->owner))) {
02598             if (pte->device->moh) {
02599                ast_moh_stop(bridgepeer);
02600                pte->device->moh = 0;
02601                send_select_output(pte, pte->device->output, pte->device->volume,
02602                             MUTE_OFF);
02603             } else {
02604                ast_moh_start(bridgepeer, pte->device->lines->musicclass, NULL);
02605                pte->device->moh = 1;
02606                send_select_output(pte, pte->device->output, pte->device->volume,
02607                             MUTE_ON);
02608             }
02609          } else
02610             ast_log(LOG_WARNING,
02611                   "Unable to find peer subchannel for music on hold\n");
02612          break;
02613       }
02614    }
02615    return;
02616 }

static void key_dial_page ( struct unistimsession pte,
char  keycode 
) [static]

Definition at line 2655 of file chan_unistim.c.

References ast_bridged_channel(), ast_channel_stop_silence_generator(), ast_copy_string(), ast_moh_stop(), ast_strlen_zero(), ast_verb, unistim_device::call_forward, unistimsession::device, HandleCallOutgoing(), KEY_0, KEY_FAV1, KEY_FAV2, KEY_FAV3, KEY_FAV4, KEY_FAV5, KEY_FUNC1, KEY_FUNC2, KEY_FUNC3, KEY_FUNC4, KEY_HANGUP, KEY_HEADPHN, KEY_LOUDSPK, KEY_SHARP, KEY_STAR, Keyfavorite(), unistim_device::lines, unistim_device::moh, MUTE_OFF, unistim_device::output, OUTPUT_HANDSET, OUTPUT_HEADPHONE, OUTPUT_SPEAKER, unistim_subchannel::owner, unistim_device::phone_number, unistim_device::previous_output, unistim_device::receiver_state, unistim_device::redial_number, send_blink_cursor(), send_cursor_pos(), send_select_output(), send_text(), send_text_status(), send_tone(), show_main_page(), unistim_device::silence_generator, unistim_device::size_phone_number, unistimsession::state, STATE_CALL, STATE_OFFHOOK, SUB_REAL, unistim_line::subs, TEXT_LINE0, TEXT_LINE1, TEXT_LINE2, TEXT_NORMAL, and unistim_device::volume.

Referenced by key_main_page(), and process_request().

02656 {
02657    if (keycode == KEY_FUNC3) {
02658       if (pte->device->size_phone_number <= 1)
02659          keycode = KEY_FUNC4;
02660       else {
02661          pte->device->size_phone_number -= 2;
02662          keycode = pte->device->phone_number[pte->device->size_phone_number] + 0x10;
02663       }
02664    }
02665    if ((keycode >= KEY_0) && (keycode <= KEY_SHARP)) {
02666       char tmpbuf[] = "Number : ...............";
02667       int i = 0;
02668 
02669       if (pte->device->size_phone_number >= 15)
02670          return;
02671       if (pte->device->size_phone_number == 0)
02672          send_tone(pte, 0, 0);
02673       while (i < pte->device->size_phone_number) {
02674          tmpbuf[i + 9] = pte->device->phone_number[i];
02675          i++;
02676       }
02677       if (keycode == KEY_SHARP)
02678          keycode = '#';
02679       else if (keycode == KEY_STAR)
02680          keycode = '*';
02681       else
02682          keycode -= 0x10;
02683       tmpbuf[i + 9] = keycode;
02684       pte->device->phone_number[i] = keycode;
02685       pte->device->size_phone_number++;
02686       pte->device->phone_number[i + 1] = 0;
02687       send_text(TEXT_LINE2, TEXT_NORMAL, pte, tmpbuf);
02688       send_blink_cursor(pte);
02689       send_cursor_pos(pte, (unsigned char) (TEXT_LINE2 + 0x0a + i));
02690       return;
02691    }
02692    if (keycode == KEY_FUNC4) {
02693 
02694       pte->device->size_phone_number = 0;
02695       send_text(TEXT_LINE2, TEXT_NORMAL, pte, "Number : ...............");
02696       send_blink_cursor(pte);
02697       send_cursor_pos(pte, TEXT_LINE2 + 0x09);
02698       return;
02699    }
02700 
02701    if (pte->device->call_forward[0] == -1) {
02702       if (keycode == KEY_FUNC1) {
02703          ast_copy_string(pte->device->call_forward, pte->device->phone_number,
02704                      sizeof(pte->device->call_forward));
02705          show_main_page(pte);
02706       } else if ((keycode == KEY_FUNC2) || (keycode == KEY_HANGUP)) {
02707          pte->device->call_forward[0] = '\0';
02708          show_main_page(pte);
02709       }
02710       return;
02711    }
02712    switch (keycode) {
02713    case KEY_FUNC2:
02714       if (ast_strlen_zero(pte->device->redial_number))
02715          break;
02716       ast_copy_string(pte->device->phone_number, pte->device->redial_number,
02717                   sizeof(pte->device->phone_number));
02718    case KEY_FUNC1:
02719       HandleCallOutgoing(pte);
02720       break;
02721    case KEY_HANGUP:
02722       if (pte->device->lines->subs[SUB_REAL]->owner) {
02723          /* Stop the silence generator */
02724          if (pte->device->silence_generator) {
02725             if (unistimdebug)
02726                ast_verb(0, "Stopping silence generator\n");
02727             ast_channel_stop_silence_generator(pte->device->lines->subs[SUB_REAL]->
02728                                        owner, pte->device->silence_generator);
02729             pte->device->silence_generator = NULL;
02730          }
02731          send_tone(pte, 0, 0);
02732          ast_moh_stop(ast_bridged_channel(pte->device->lines->subs[SUB_REAL]->owner));
02733          pte->device->moh = 0;
02734          pte->state = STATE_CALL;
02735          send_text(TEXT_LINE0, TEXT_NORMAL, pte, "Dialing canceled,");
02736          send_text(TEXT_LINE1, TEXT_NORMAL, pte, "switching back to");
02737          send_text(TEXT_LINE2, TEXT_NORMAL, pte, "previous call.");
02738          send_text_status(pte, "Hangup Transf");
02739       } else
02740          show_main_page(pte);
02741       break;
02742    case KEY_FAV1:
02743    case KEY_FAV2:
02744    case KEY_FAV3:
02745    case KEY_FAV4:
02746    case KEY_FAV5:
02747       Keyfavorite(pte, keycode);
02748       break;
02749    case KEY_LOUDSPK:
02750       if (pte->device->output == OUTPUT_SPEAKER) {
02751          if (pte->device->receiver_state == STATE_OFFHOOK)
02752             send_select_output(pte, pte->device->previous_output, pte->device->volume,
02753                          MUTE_OFF);
02754          else
02755             show_main_page(pte);
02756       } else
02757          send_select_output(pte, OUTPUT_SPEAKER, pte->device->volume, MUTE_OFF);
02758       break;
02759    case KEY_HEADPHN:
02760       if (pte->device->output == OUTPUT_HEADPHONE) {
02761          if (pte->device->receiver_state == STATE_OFFHOOK)
02762             send_select_output(pte, OUTPUT_HANDSET, pte->device->volume, MUTE_OFF);
02763          else
02764             show_main_page(pte);
02765       } else
02766          send_select_output(pte, OUTPUT_HEADPHONE, pte->device->volume, MUTE_OFF);
02767       break;
02768    }
02769    return;
02770 }

static void key_history ( struct unistimsession pte,
char  keycode 
) [static]

Definition at line 3219 of file chan_unistim.c.

References ast_copy_string(), unistimsession::buff_entry, unistimsession::device, display_last_error(), f, KEY_DOWN, KEY_FUNC1, KEY_FUNC2, KEY_FUNC3, KEY_FUNC4, KEY_HANGUP, KEY_LEFT, key_main_page(), KEY_RCVHIST, KEY_RIGHT, KEY_SNDHIST, KEY_UP, unistim_device::lst_cid, OpenHistory(), unistim_device::redial_number, ReformatNumber(), show_entry_history(), show_history(), show_main_page(), and TEXT_LENGTH_MAX.

Referenced by process_request().

03220 {
03221    FILE *f;
03222    char count;
03223    long offset;
03224 
03225    switch (keycode) {
03226    case KEY_UP:
03227    case KEY_LEFT:
03228    case KEY_FUNC1:
03229       if (pte->buff_entry[2] <= 1)
03230          return;
03231       pte->buff_entry[2]--;
03232       count = OpenHistory(pte, pte->buff_entry[0], &f);
03233       if (!count)
03234          return;
03235       offset = ((pte->buff_entry[2] - 1) * TEXT_LENGTH_MAX * 3);
03236       if (fseek(f, offset, SEEK_CUR)) {
03237          display_last_error("Unable to seek history entry.");
03238          fclose(f);
03239          return;
03240       }
03241       show_entry_history(pte, &f);
03242       break;
03243    case KEY_DOWN:
03244    case KEY_RIGHT:
03245    case KEY_FUNC2:
03246       if (pte->buff_entry[2] >= pte->buff_entry[1])
03247          return;
03248       pte->buff_entry[2]++;
03249       count = OpenHistory(pte, pte->buff_entry[0], &f);
03250       if (!count)
03251          return;
03252       offset = ((pte->buff_entry[2] - 1) * TEXT_LENGTH_MAX * 3);
03253       if (fseek(f, offset, SEEK_CUR)) {
03254          display_last_error("Unable to seek history entry.");
03255          fclose(f);
03256          return;
03257       }
03258       show_entry_history(pte, &f);
03259       break;
03260    case KEY_FUNC3:
03261       if (!ReformatNumber(pte->device->lst_cid))
03262          break;
03263       ast_copy_string(pte->device->redial_number, pte->device->lst_cid,
03264                   sizeof(pte->device->redial_number));
03265       key_main_page(pte, KEY_FUNC2);
03266       break;
03267    case KEY_FUNC4:
03268    case KEY_HANGUP:
03269       show_main_page(pte);
03270       break;
03271    case KEY_SNDHIST:
03272       if (pte->buff_entry[0] == 'i')
03273          show_history(pte, 'o');
03274       else
03275          show_main_page(pte);
03276       break;
03277    case KEY_RCVHIST:
03278       if (pte->buff_entry[0] == 'i')
03279          show_main_page(pte);
03280       else
03281          show_history(pte, 'i');
03282       break;
03283    }
03284    return;
03285 }

static void key_main_page ( struct unistimsession pte,
char  keycode 
) [static]

Definition at line 3125 of file chan_unistim.c.

References ast_copy_string(), ast_mutex_lock(), ast_mutex_unlock(), ast_strlen_zero(), unistimsession::buff_entry, unistim_device::call_forward, unistimsession::device, devicelock, unistim_device::extension, EXTENSION_ASK, unistim_device::extension_number, EXTENSION_TN, FAV_ICON_NONE, handle_dial_page(), HandleCallOutgoing(), HandleSelectCodec(), unistim_device::id, KEY_0, KEY_CONF, key_dial_page(), KEY_FAV0, KEY_FAV1, KEY_FAV2, KEY_FAV3, KEY_FAV4, KEY_FAV5, KEY_FUNC1, KEY_FUNC2, KEY_FUNC3, KEY_FUNC4, KEY_HEADPHN, KEY_LOUDSPK, KEY_RCVHIST, KEY_SHARP, KEY_SNDHIST, Keyfavorite(), unistim_device::missed_call, MUTE_OFF, unistim_device::output, OUTPUT_HANDSET, OUTPUT_HEADPHONE, OUTPUT_SPEAKER, unistim_device::phone_number, unistim_device::receiver_state, unistim_device::redial_number, send_select_output(), Sendicon(), unistim_device::session, show_history(), show_main_page(), ShowExtensionPage(), unistimsession::size_buff_entry, STATE_ONHOOK, TEXT_LINE0, UnregisterExtension(), and unistim_device::volume.

Referenced by key_history(), and process_request().

03126 {
03127    if (pte->device->missed_call) {
03128       Sendicon(TEXT_LINE0, FAV_ICON_NONE, pte);
03129       pte->device->missed_call = 0;
03130    }
03131    if ((keycode >= KEY_0) && (keycode <= KEY_SHARP)) {
03132       handle_dial_page(pte);
03133       key_dial_page(pte, keycode);
03134       return;
03135    }
03136    switch (keycode) {
03137    case KEY_FUNC1:
03138       handle_dial_page(pte);
03139       break;
03140    case KEY_FUNC2:
03141       if (ast_strlen_zero(pte->device->redial_number))
03142          break;
03143       if ((pte->device->output == OUTPUT_HANDSET) &&
03144          (pte->device->receiver_state == STATE_ONHOOK))
03145          send_select_output(pte, OUTPUT_SPEAKER, pte->device->volume, MUTE_OFF);
03146       else
03147          send_select_output(pte, pte->device->output, pte->device->volume, MUTE_OFF);
03148 
03149       ast_copy_string(pte->device->phone_number, pte->device->redial_number,
03150                   sizeof(pte->device->phone_number));
03151       HandleCallOutgoing(pte);
03152       break;
03153    case KEY_FUNC3:
03154       if (!ast_strlen_zero(pte->device->call_forward)) {
03155          /* Cancel call forwarding */
03156          memmove(pte->device->call_forward + 1, pte->device->call_forward,
03157                sizeof(pte->device->call_forward));
03158          pte->device->call_forward[0] = '\0';
03159          Sendicon(TEXT_LINE0, FAV_ICON_NONE, pte);
03160          pte->device->output = OUTPUT_HANDSET;   /* Seems to be reseted somewhere */
03161          show_main_page(pte);
03162          break;
03163       }
03164       pte->device->call_forward[0] = -1;
03165       handle_dial_page(pte);
03166       break;
03167    case KEY_FUNC4:
03168       if (pte->device->extension == EXTENSION_ASK) {
03169          UnregisterExtension(pte);
03170          pte->device->extension_number[0] = '\0';
03171          ShowExtensionPage(pte);
03172       } else if (pte->device->extension == EXTENSION_TN) {
03173          ast_mutex_lock(&devicelock);
03174          strcpy(pte->device->id, pte->device->extension_number);
03175          pte->buff_entry[0] = '\0';
03176          pte->size_buff_entry = 0;
03177          pte->device->session = NULL;
03178          pte->device = NULL;
03179          ast_mutex_unlock(&devicelock);
03180          ShowExtensionPage(pte);
03181       }
03182       break;
03183    case KEY_FAV0:
03184       handle_dial_page(pte);
03185       break;
03186    case KEY_FAV1:
03187    case KEY_FAV2:
03188    case KEY_FAV3:
03189    case KEY_FAV4:
03190    case KEY_FAV5:
03191       if ((pte->device->output == OUTPUT_HANDSET) &&
03192          (pte->device->receiver_state == STATE_ONHOOK))
03193          send_select_output(pte, OUTPUT_SPEAKER, pte->device->volume, MUTE_OFF);
03194       else
03195          send_select_output(pte, pte->device->output, pte->device->volume, MUTE_OFF);
03196       Keyfavorite(pte, keycode);
03197       break;
03198    case KEY_CONF:
03199       HandleSelectCodec(pte);
03200       break;
03201    case KEY_LOUDSPK:
03202       send_select_output(pte, OUTPUT_SPEAKER, pte->device->volume, MUTE_OFF);
03203       handle_dial_page(pte);
03204       break;
03205    case KEY_HEADPHN:
03206       send_select_output(pte, OUTPUT_HEADPHONE, pte->device->volume, MUTE_OFF);
03207       handle_dial_page(pte);
03208       break;
03209    case KEY_SNDHIST:
03210       show_history(pte, 'o');
03211       break;
03212    case KEY_RCVHIST:
03213       show_history(pte, 'i');
03214       break;
03215    }
03216    return;
03217 }

static void key_ringing ( struct unistimsession pte,
char  keycode 
) [static]

Definition at line 2618 of file chan_unistim.c.

References unistimsession::device, HandleCallIncoming(), IgnoreCall(), KEY_FAV0, KEY_FUNC1, KEY_FUNC4, KEY_HANGUP, and unistim_device::softkeylinepos.

Referenced by process_request().

02619 {
02620    if (keycode == KEY_FAV0 + pte->device->softkeylinepos) {
02621       HandleCallIncoming(pte);
02622       return;
02623    }
02624    switch (keycode) {
02625    case KEY_HANGUP:
02626    case KEY_FUNC4:
02627       IgnoreCall(pte);
02628       break;
02629    case KEY_FUNC1:
02630       HandleCallIncoming(pte);
02631       break;
02632    }
02633    return;
02634 }

static void key_select_codec ( struct unistimsession pte,
char  keycode 
) [static]

Definition at line 2795 of file chan_unistim.c.

References unistimsession::buff_entry, unistim_device::codec_number, unistimsession::device, KEY_0, KEY_9, KEY_FUNC1, KEY_FUNC2, KEY_FUNC3, KEY_FUNC4, KEY_HANGUP, SELECTCODEC_MAX_LENGTH, SELECTCODEC_MSG, SELECTCODEC_START_ENTRY_POS, send_blink_cursor(), send_cursor_pos(), send_text(), show_main_page(), unistimsession::size_buff_entry, TEXT_INVERSE, and TEXT_LINE2.

Referenced by process_request().

02796 {
02797    if (keycode == KEY_FUNC2) {
02798       if (pte->size_buff_entry <= 1)
02799          keycode = KEY_FUNC3;
02800       else {
02801          pte->size_buff_entry -= 2;
02802          keycode = pte->buff_entry[pte->size_buff_entry] + 0x10;
02803       }
02804    }
02805    if ((keycode >= KEY_0) && (keycode <= KEY_9)) {
02806       char tmpbuf[] = SELECTCODEC_MSG;
02807       int i = 0;
02808 
02809       if (pte->size_buff_entry >= SELECTCODEC_MAX_LENGTH)
02810          return;
02811 
02812       while (i < pte->size_buff_entry) {
02813          tmpbuf[i + SELECTCODEC_START_ENTRY_POS] = pte->buff_entry[i];
02814          i++;
02815       }
02816       tmpbuf[i + SELECTCODEC_START_ENTRY_POS] = keycode - 0x10;
02817       pte->buff_entry[i] = keycode - 0x10;
02818       pte->size_buff_entry++;
02819       send_text(TEXT_LINE2, TEXT_INVERSE, pte, tmpbuf);
02820       send_blink_cursor(pte);
02821       send_cursor_pos(pte,
02822                  (unsigned char) (TEXT_LINE2 + SELECTCODEC_START_ENTRY_POS + 1 + i));
02823       return;
02824    }
02825 
02826    switch (keycode) {
02827    case KEY_FUNC1:
02828       if (pte->size_buff_entry == 1)
02829          pte->device->codec_number = pte->buff_entry[0] - 48;
02830       else if (pte->size_buff_entry == 2)
02831          pte->device->codec_number =
02832             ((pte->buff_entry[0] - 48) * 10) + (pte->buff_entry[1] - 48);
02833       show_main_page(pte);
02834       break;
02835    case KEY_FUNC3:
02836       pte->size_buff_entry = 0;
02837       send_text(TEXT_LINE2, TEXT_INVERSE, pte, SELECTCODEC_MSG);
02838       send_blink_cursor(pte);
02839       send_cursor_pos(pte, TEXT_LINE2 + SELECTCODEC_START_ENTRY_POS);
02840       break;
02841    case KEY_HANGUP:
02842    case KEY_FUNC4:
02843       show_main_page(pte);
02844       break;
02845    }
02846    return;
02847 }

static void key_select_extension ( struct unistimsession pte,
char  keycode 
) [static]

Definition at line 2866 of file chan_unistim.c.

References ast_copy_string(), ast_mutex_lock(), ast_mutex_unlock(), AUTOPROVISIONING_TN, unistimsession::buff_entry, unistim_device::codec_number, DEFAULT_CODEC, unistimsession::device, devicelock, unistim_device::extension, unistim_device::extension_number, EXTENSION_TN, unistim_device::id, KEY_0, KEY_9, KEY_FUNC1, KEY_FUNC2, KEY_FUNC3, unistimsession::macaddr, unistim_device::missed_call, unistim_device::next, unistim_device::pos_fav, unistim_device::receiver_state, refresh_all_favorite(), RegisterExtension(), SELECTEXTENSION_MAX_LENGTH, SELECTEXTENSION_MSG, SELECTEXTENSION_START_ENTRY_POS, send_blink_cursor(), send_cursor_pos(), send_text(), unistim_device::session, show_main_page(), unistimsession::size_buff_entry, STATE_ONHOOK, TEXT_LINE0, TEXT_LINE1, TEXT_LINE2, and TEXT_NORMAL.

Referenced by process_request().

02867 {
02868    if (keycode == KEY_FUNC2) {
02869       if (pte->size_buff_entry <= 1)
02870          keycode = KEY_FUNC3;
02871       else {
02872          pte->size_buff_entry -= 2;
02873          keycode = pte->buff_entry[pte->size_buff_entry] + 0x10;
02874       }
02875    }
02876    if ((keycode >= KEY_0) && (keycode <= KEY_9)) {
02877       char tmpbuf[] = SELECTEXTENSION_MSG;
02878       int i = 0;
02879 
02880       if (pte->size_buff_entry >= SELECTEXTENSION_MAX_LENGTH)
02881          return;
02882 
02883       while (i < pte->size_buff_entry) {
02884          tmpbuf[i + SELECTEXTENSION_START_ENTRY_POS] = pte->buff_entry[i];
02885          i++;
02886       }
02887       tmpbuf[i + SELECTEXTENSION_START_ENTRY_POS] = keycode - 0x10;
02888       pte->buff_entry[i] = keycode - 0x10;
02889       pte->size_buff_entry++;
02890       send_text(TEXT_LINE2, TEXT_NORMAL, pte, tmpbuf);
02891       send_blink_cursor(pte);
02892       send_cursor_pos(pte,
02893                  (unsigned char) (TEXT_LINE2 + SELECTEXTENSION_START_ENTRY_POS + 1 +
02894                               i));
02895       return;
02896    }
02897 
02898    switch (keycode) {
02899    case KEY_FUNC1:
02900       if (pte->size_buff_entry < 1)
02901          return;
02902       if (autoprovisioning == AUTOPROVISIONING_TN) {
02903          struct unistim_device *d;
02904 
02905          /* First step : looking for this TN in our device list */
02906          ast_mutex_lock(&devicelock);
02907          d = devices;
02908          pte->buff_entry[pte->size_buff_entry] = '\0';
02909          while (d) {
02910             if (d->id[0] == 'T') {  /* It's a TN device ? */
02911                /* It's the TN we're looking for ? */
02912                if (!strcmp((d->id) + 1, pte->buff_entry)) {
02913                   pte->device = d;
02914                   d->session = pte;
02915                   d->codec_number = DEFAULT_CODEC;
02916                   d->pos_fav = 0;
02917                   d->missed_call = 0;
02918                   d->receiver_state = STATE_ONHOOK;
02919                   strcpy(d->id, pte->macaddr);
02920                   pte->device->extension_number[0] = 'T';
02921                   pte->device->extension = EXTENSION_TN;
02922                   ast_copy_string((pte->device->extension_number) + 1,
02923                               pte->buff_entry, pte->size_buff_entry + 1);
02924                   ast_mutex_unlock(&devicelock);
02925                   show_main_page(pte);
02926                   refresh_all_favorite(pte);
02927                   return;
02928                }
02929             }
02930             d = d->next;
02931          }
02932          ast_mutex_unlock(&devicelock);
02933          send_text(TEXT_LINE0, TEXT_NORMAL, pte, "Invalid Terminal Number.");
02934          send_text(TEXT_LINE1, TEXT_NORMAL, pte, "Please try again :");
02935          send_cursor_pos(pte,
02936                     (unsigned char) (TEXT_LINE2 + SELECTEXTENSION_START_ENTRY_POS +
02937                                  pte->size_buff_entry));
02938          send_blink_cursor(pte);
02939       } else {
02940          ast_copy_string(pte->device->extension_number, pte->buff_entry,
02941                      pte->size_buff_entry + 1);
02942          if (RegisterExtension(pte)) {
02943             send_text(TEXT_LINE0, TEXT_NORMAL, pte, "Invalid extension.");
02944             send_text(TEXT_LINE1, TEXT_NORMAL, pte, "Please try again :");
02945             send_cursor_pos(pte,
02946                        (unsigned char) (TEXT_LINE2 +
02947                                     SELECTEXTENSION_START_ENTRY_POS +
02948                                     pte->size_buff_entry));
02949             send_blink_cursor(pte);
02950          } else
02951             show_main_page(pte);
02952       }
02953       break;
02954    case KEY_FUNC3:
02955       pte->size_buff_entry = 0;
02956       send_text(TEXT_LINE2, TEXT_NORMAL, pte, SELECTEXTENSION_MSG);
02957       send_blink_cursor(pte);
02958       send_cursor_pos(pte, TEXT_LINE2 + SELECTEXTENSION_START_ENTRY_POS);
02959       break;
02960    }
02961    return;
02962 }

static void Keyfavorite ( struct unistimsession pte,
char  keycode 
) [static]

Definition at line 2636 of file chan_unistim.c.

References ast_copy_string(), ast_log(), unistimsession::device, HandleCallOutgoing(), KEY_FAV0, KEY_FAV1, KEY_FAV5, LOG_WARNING, unistim_device::phone_number, unistim_device::softkeyicon, and unistim_device::softkeynumber.

Referenced by key_dial_page(), and key_main_page().

02637 {
02638    int fav;
02639 
02640    if ((keycode < KEY_FAV1) && (keycode > KEY_FAV5)) {
02641       ast_log(LOG_WARNING, "It's not a favorite key\n");
02642       return;
02643    }
02644    if (keycode == KEY_FAV0)
02645       return;
02646    fav = keycode - KEY_FAV0;
02647    if (pte->device->softkeyicon[fav] == 0)
02648       return;
02649    ast_copy_string(pte->device->phone_number, pte->device->softkeynumber[fav],
02650                sizeof(pte->device->phone_number));
02651    HandleCallOutgoing(pte);
02652    return;
02653 }

int load_module ( void   )  [static]

XXX

Todo:
Leaking anything allocated by reload_config() ...

Definition at line 5546 of file chan_unistim.c.

References ARRAY_LEN, ast_channel_register(), ast_cli_register_multiple(), ast_free, ast_log(), ast_malloc, AST_MODULE_LOAD_DECLINE, AST_MODULE_LOAD_FAILURE, AST_MODULE_LOAD_SUCCESS, ast_rtp_glue_register, io_context_create(), io_context_destroy(), LOG_ERROR, reload_config(), restart_monitor(), sched_context_create(), sched_context_destroy(), and SIZE_PAGE.

05547 {
05548    int res;
05549 
05550    if (!(buff = ast_malloc(SIZE_PAGE)))
05551       goto buff_failed;
05552 
05553    io = io_context_create();
05554    if (!io) {
05555       ast_log(LOG_ERROR, "Failed to allocate IO context\n");
05556       goto io_failed;
05557    }
05558 
05559    sched = sched_context_create();
05560    if (!sched) {
05561       ast_log(LOG_ERROR, "Failed to allocate scheduler context\n");
05562       goto sched_failed;
05563    }
05564 
05565    res = reload_config();
05566    if (res)
05567       return AST_MODULE_LOAD_DECLINE;
05568 
05569    /* Make sure we can register our unistim channel type */
05570    if (ast_channel_register(&unistim_tech)) {
05571       ast_log(LOG_ERROR, "Unable to register channel type '%s'\n", channel_type);
05572       goto chanreg_failed;
05573    } 
05574 
05575    ast_rtp_glue_register(&unistim_rtp_glue);
05576 
05577    ast_cli_register_multiple(unistim_cli, ARRAY_LEN(unistim_cli));
05578 
05579    restart_monitor();
05580 
05581    return AST_MODULE_LOAD_SUCCESS;
05582 
05583 chanreg_failed:
05584    /*! XXX \todo Leaking anything allocated by reload_config() ... */
05585    sched_context_destroy(sched);
05586    sched = NULL;
05587 sched_failed:
05588    io_context_destroy(io);
05589    io = NULL;
05590 io_failed:
05591    ast_free(buff);
05592    buff = NULL;
05593 buff_failed:
05594    return AST_MODULE_LOAD_FAILURE;
05595 }

static char OpenHistory ( struct unistimsession pte,
char  way,
FILE **  f 
) [static]

Definition at line 3031 of file chan_unistim.c.

References ast_config_AST_LOG_DIR, AST_CONFIG_MAX_PATH, ast_log(), unistimsession::device, display_last_error(), LOG_WARNING, MAX_ENTRY_LOG, unistim_device::name, and USTM_LOG_DIR.

Referenced by key_history(), and show_history().

03032 {
03033    char tmp[AST_CONFIG_MAX_PATH];
03034    char count;
03035 
03036    snprintf(tmp, sizeof(tmp), "%s/%s/%s-%c.csv", ast_config_AST_LOG_DIR,
03037           USTM_LOG_DIR, pte->device->name, way);
03038    *f = fopen(tmp, "r");
03039    if (!*f) {
03040       display_last_error("Unable to open history file");
03041       return 0;
03042    }
03043    if (fread(&count, 1, 1, *f) != 1) {
03044       display_last_error("Unable to read history header - display.");
03045       fclose(*f);
03046       return 0;
03047    }
03048    if (count > MAX_ENTRY_LOG) {
03049       ast_log(LOG_WARNING, "Invalid count in history header of %s (%d max %d)\n", tmp,
03050             count, MAX_ENTRY_LOG);
03051       fclose(*f);
03052       return 0;
03053    }
03054    return count;
03055 }

static int ParseBookmark ( const char *  text,
struct unistim_device d 
) [static]

Definition at line 4893 of file chan_unistim.c.

References ast_copy_string(), ast_log(), ast_strlen_zero(), ast_verb, FAV_ICON_SHARP, len(), LOG_NOTICE, LOG_WARNING, unistim_device::softkeydevice, unistim_device::softkeyicon, unistim_device::softkeylabel, and unistim_device::softkeynumber.

Referenced by build_device().

04894 {
04895    char line[256];
04896    char *at;
04897    char *number;
04898    char *icon;
04899    int p;
04900    int len = strlen(text);
04901 
04902    ast_copy_string(line, text, sizeof(line));
04903    /* Position specified ? */
04904    if ((len > 2) && (line[1] == '@')) {
04905       p = line[0];
04906       if ((p >= '0') && (p <= '5'))
04907          p -= '0';
04908       else {
04909          ast_log(LOG_WARNING,
04910                "Invalid position for bookmark : must be between 0 and 5\n");
04911          return 0;
04912       }
04913       if (d->softkeyicon[p] != 0) {
04914          ast_log(LOG_WARNING, "Invalid position %d for bookmark : already used\n:", p);
04915          return 0;
04916       }
04917       memmove(line, line + 2, sizeof(line));
04918    } else {
04919       /* No position specified, looking for a free slot */
04920       for (p = 0; p <= 5; p++) {
04921          if (!d->softkeyicon[p])
04922             break;
04923       }
04924       if (p > 5) {
04925          ast_log(LOG_WARNING, "No more free bookmark position\n");
04926          return 0;
04927       }
04928    }
04929    at = strchr(line, '@');
04930    if (!at) {
04931       ast_log(LOG_NOTICE, "Bookmark entry '%s' has no @ (at) sign!\n", text);
04932       return 0;
04933    }
04934    *at = '\0';
04935    at++;
04936    number = at;
04937    at = strchr(at, '@');
04938    if (ast_strlen_zero(number)) {
04939       ast_log(LOG_NOTICE, "Bookmark entry '%s' has no number\n", text);
04940       return 0;
04941    }
04942    if (ast_strlen_zero(line)) {
04943       ast_log(LOG_NOTICE, "Bookmark entry '%s' has no description\n", text);
04944       return 0;
04945    }
04946 
04947    at = strchr(number, '@');
04948    if (!at)
04949       d->softkeyicon[p] = FAV_ICON_SHARP;     /* default icon */
04950    else {
04951       *at = '\0';
04952       at++;
04953       icon = at;
04954       if (ast_strlen_zero(icon)) {
04955          ast_log(LOG_NOTICE, "Bookmark entry '%s' has no icon value\n", text);
04956          return 0;
04957       }
04958       if (strncmp(icon, "USTM/", 5))
04959          d->softkeyicon[p] = atoi(icon);
04960       else {
04961          d->softkeyicon[p] = 1;
04962          ast_copy_string(d->softkeydevice[p], icon + 5, sizeof(d->softkeydevice[p]));
04963       }
04964    }
04965    ast_copy_string(d->softkeylabel[p], line, sizeof(d->softkeylabel[p]));
04966    ast_copy_string(d->softkeynumber[p], number, sizeof(d->softkeynumber[p]));
04967    if (unistimdebug)
04968       ast_verb(0, "New bookmark at pos %d label='%s' number='%s' icon=%x\n",
04969                p, d->softkeylabel[p], d->softkeynumber[p], d->softkeyicon[p]);
04970    return 1;
04971 }

static void parsing ( int  size,
unsigned char *  buf,
struct unistimsession pte,
struct sockaddr_in *  addr_from 
) [static]

Definition at line 3467 of file chan_unistim.c.

References ast_inet_ntoa(), ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_verb, check_send_queue(), close_client(), create_client(), unistimsession::last_seq_ack, unistimsession::lock, LOG_NOTICE, LOG_WARNING, unistimsession::nb_retransmit, process_request(), send_raw_client(), send_retransmit(), seq, unistimsession::seq_phone, unistimsession::seq_server, SIZE_HEADER, unistimsession::sout, unistimsession::state, and STATE_INIT.

Referenced by unistimsock_read().

03469 {
03470    unsigned short *sbuf = (unsigned short *) buf;
03471    unsigned short seq;
03472    char tmpbuf[255];
03473 
03474    strcpy(tmpbuf, ast_inet_ntoa(addr_from->sin_addr));
03475 
03476    if (size < 10) {
03477       if (size == 0) {
03478          ast_log(LOG_WARNING, "%s Read error\n", tmpbuf);
03479       } else {
03480          ast_log(LOG_NOTICE, "%s Packet too short - ignoring\n", tmpbuf);
03481       }
03482       return;
03483    }
03484    if (sbuf[0] == 0xffff) {   /* Starting with 0xffff ? *//* Yes, discovery packet ? */
03485       if (size != sizeof(packet_rcv_discovery)) {
03486          ast_log(LOG_NOTICE, "%s Invalid size of a discovery packet\n", tmpbuf);
03487       } else {
03488          if (memcmp(buf, packet_rcv_discovery, sizeof(packet_rcv_discovery)) == 0) {
03489             if (unistimdebug)
03490                ast_verb(0, "Discovery packet received - Sending Discovery ACK\n");
03491             if (pte) {        /* A session was already active for this IP ? */
03492                if (pte->state == STATE_INIT) { /* Yes, but it's a dupe */
03493                   if (unistimdebug)
03494                      ast_verb(1, "Duplicated Discovery packet\n");
03495                   send_raw_client(sizeof(packet_send_discovery_ack),
03496                              packet_send_discovery_ack, addr_from, &pte->sout);
03497                   pte->seq_phone = (short) 0x0000; /* reset sequence number */
03498                } else { /* No, probably a reboot, phone side */
03499                   close_client(pte);       /* Cleanup the previous session */
03500                   if (create_client(addr_from))
03501                      send_raw_client(sizeof(packet_send_discovery_ack),
03502                                 packet_send_discovery_ack, addr_from, &pte->sout);
03503                }
03504             } else {
03505                /* Creating new entry in our phone list */
03506                if ((pte = create_client(addr_from)))
03507                   send_raw_client(sizeof(packet_send_discovery_ack),
03508                              packet_send_discovery_ack, addr_from, &pte->sout);
03509             }
03510             return;
03511          }
03512          ast_log(LOG_NOTICE, "%s Invalid discovery packet\n", tmpbuf);
03513       }
03514       return;
03515    }
03516    if (!pte) {
03517       if (unistimdebug)
03518          ast_verb(0, "%s Not a discovery packet from an unknown source : ignoring\n",
03519                   tmpbuf);
03520       return;
03521    }
03522 
03523    if (sbuf[0] != 0) {          /* Starting with something else than 0x0000 ? */
03524       ast_log(LOG_NOTICE, "Unknown packet received - ignoring\n");
03525       return;
03526    }
03527    if (buf[5] != 2) {
03528       ast_log(LOG_NOTICE, "%s Wrong direction : got 0x%.2x expected 0x02\n", tmpbuf,
03529             buf[5]);
03530       return;
03531    }
03532    seq = ntohs(sbuf[1]);
03533    if (buf[4] == 1) {
03534       ast_mutex_lock(&pte->lock);
03535       if (unistimdebug)
03536          ast_verb(6, "ACK received for packet #0x%.4x\n", seq);
03537       pte->nb_retransmit = 0;
03538 
03539       if ((pte->last_seq_ack) + 1 == seq) {
03540          pte->last_seq_ack++;
03541          check_send_queue(pte);
03542          ast_mutex_unlock(&pte->lock);
03543          return;
03544       }
03545       if (pte->last_seq_ack > seq) {
03546          if (pte->last_seq_ack == 0xffff) {
03547             ast_verb(0, "ACK at 0xffff, restarting counter.\n");
03548             pte->last_seq_ack = 0;
03549          } else
03550             ast_log(LOG_NOTICE,
03551                   "%s Warning : ACK received for an already ACKed packet : #0x%.4x we are at #0x%.4x\n",
03552                   tmpbuf, seq, pte->last_seq_ack);
03553          ast_mutex_unlock(&pte->lock);
03554          return;
03555       }
03556       if (pte->seq_server < seq) {
03557          ast_log(LOG_NOTICE,
03558                "%s Error : ACK received for a non-existent packet : #0x%.4x\n",
03559                tmpbuf, pte->seq_server);
03560          ast_mutex_unlock(&pte->lock);
03561          return;
03562       }
03563       if (unistimdebug)
03564          ast_verb(0, "%s ACK gap : Received ACK #0x%.4x, previous was #0x%.4x\n",
03565                   tmpbuf, seq, pte->last_seq_ack);
03566       pte->last_seq_ack = seq;
03567       check_send_queue(pte);
03568       ast_mutex_unlock(&pte->lock);
03569       return;
03570    }
03571    if (buf[4] == 2) {
03572       if (unistimdebug)
03573          ast_verb(0, "Request received\n");
03574       if (pte->seq_phone == seq) {
03575          /* Send ACK */
03576          buf[4] = 1;
03577          buf[5] = 1;
03578          send_raw_client(SIZE_HEADER, buf, addr_from, &pte->sout);
03579          pte->seq_phone++;
03580 
03581          process_request(size, buf, pte);
03582          return;
03583       }
03584       if (pte->seq_phone > seq) {
03585          ast_log(LOG_NOTICE,
03586                "%s Warning : received a retransmitted packet : #0x%.4x (we are at #0x%.4x)\n",
03587                tmpbuf, seq, pte->seq_phone);
03588          /* BUG ? pte->device->seq_phone = seq; */
03589          /* Send ACK */
03590          buf[4] = 1;
03591          buf[5] = 1;
03592          send_raw_client(SIZE_HEADER, buf, addr_from, &pte->sout);
03593          return;
03594       }
03595       ast_log(LOG_NOTICE,
03596             "%s Warning : we lost a packet : received #0x%.4x (we are at #0x%.4x)\n",
03597             tmpbuf, seq, pte->seq_phone);
03598       return;
03599    }
03600    if (buf[4] == 0) {
03601       ast_log(LOG_NOTICE, "%s Retransmit request for packet #0x%.4x\n", tmpbuf, seq);
03602       if (pte->last_seq_ack > seq) {
03603          ast_log(LOG_NOTICE,
03604                "%s Error : received a request for an already ACKed packet : #0x%.4x\n",
03605                tmpbuf, pte->last_seq_ack);
03606          return;
03607       }
03608       if (pte->seq_server < seq) {
03609          ast_log(LOG_NOTICE,
03610                "%s Error : received a request for a non-existent packet : #0x%.4x\n",
03611                tmpbuf, pte->seq_server);
03612          return;
03613       }
03614       send_retransmit(pte);
03615       return;
03616    }
03617    ast_log(LOG_NOTICE, "%s Unknown request : got 0x%.2x expected 0x00,0x01 or 0x02\n",
03618          tmpbuf, buf[4]);
03619    return;
03620 }

static void process_request ( int  size,
unsigned char *  buf,
struct unistimsession pte 
) [static]

Definition at line 3348 of file chan_unistim.c.

References ast_debug, ast_inet_ntoa(), ast_log(), ast_verb, close_call(), unistimsession::device, handle_dial_page(), HandleCallIncoming(), init_phone_step2(), key_call(), key_dial_page(), key_history(), key_main_page(), key_ringing(), key_select_codec(), key_select_extension(), unistim_device::lines, LOG_WARNING, MUTE_OFF, unistim_device::output, OUTPUT_HANDSET, OUTPUT_HEADPHONE, unistim_subchannel::owner, rcv_mac_addr(), rcv_resume_connection_with_server(), unistim_device::receiver_state, send_select_output(), show_main_page(), unistimsession::sin, SIZE_HEADER, unistimsession::state, STATE_AUTHDENY, STATE_CALL, STATE_DIALPAGE, STATE_EXTENSION, STATE_HISTORY, STATE_INIT, STATE_MAINPAGE, STATE_OFFHOOK, STATE_ONHOOK, STATE_RINGING, STATE_SELECTCODEC, SUB_REAL, unistim_line::subs, and unistim_device::volume.

Referenced by parsing().

03349 {
03350    char tmpbuf[255];
03351    if (memcmp
03352       (buf + SIZE_HEADER, packet_recv_resume_connection_with_server,
03353        sizeof(packet_recv_resume_connection_with_server)) == 0) {
03354       rcv_resume_connection_with_server(pte);
03355       return;
03356    }
03357    if (memcmp(buf + SIZE_HEADER, packet_recv_firm_version, sizeof(packet_recv_firm_version)) ==
03358       0) {
03359       buf[size] = 0;
03360       if (unistimdebug)
03361          ast_verb(0, "Got the firmware version : '%s'\n", buf + 13);
03362       init_phone_step2(pte);
03363       return;
03364    }
03365    if (memcmp(buf + SIZE_HEADER, packet_recv_mac_addr, sizeof(packet_recv_mac_addr)) == 0) {
03366       rcv_mac_addr(pte, buf);
03367       return;
03368    }
03369    if (memcmp(buf + SIZE_HEADER, packet_recv_r2, sizeof(packet_recv_r2)) == 0) {
03370       if (unistimdebug)
03371          ast_verb(0, "R2 received\n");
03372       return;
03373    }
03374 
03375    if (pte->state < STATE_MAINPAGE) {
03376       if (unistimdebug)
03377          ast_verb(0, "Request not authorized in this state\n");
03378       return;
03379    }
03380    if (!memcmp(buf + SIZE_HEADER, packet_recv_pressed_key, sizeof(packet_recv_pressed_key))) {
03381       char keycode = buf[13];
03382 
03383       if (unistimdebug)
03384          ast_verb(0, "Key pressed : keycode = 0x%.2x - current state : %d\n", keycode,
03385                   pte->state);
03386 
03387       switch (pte->state) {
03388       case STATE_INIT:
03389          if (unistimdebug)
03390             ast_verb(0, "No keys allowed in the init state\n");
03391          break;
03392       case STATE_AUTHDENY:
03393          if (unistimdebug)
03394             ast_verb(0, "No keys allowed in authdeny state\n");
03395          break;
03396       case STATE_MAINPAGE:
03397          key_main_page(pte, keycode);
03398          break;
03399       case STATE_DIALPAGE:
03400          key_dial_page(pte, keycode);
03401          break;
03402       case STATE_RINGING:
03403          key_ringing(pte, keycode);
03404          break;
03405       case STATE_CALL:
03406          key_call(pte, keycode);
03407          break;
03408       case STATE_EXTENSION:
03409          key_select_extension(pte, keycode);
03410          break;
03411       case STATE_SELECTCODEC:
03412          key_select_codec(pte, keycode);
03413          break;
03414       case STATE_HISTORY:
03415          key_history(pte, keycode);
03416          break;
03417       default:
03418          ast_log(LOG_WARNING, "Key : Unknown state\n");
03419       }
03420       return;
03421    }
03422    if (memcmp(buf + SIZE_HEADER, packet_recv_pick_up, sizeof(packet_recv_pick_up)) == 0) {
03423       if (unistimdebug)
03424          ast_verb(0, "Handset off hook\n");
03425       if (!pte->device)        /* We are not yet registered (asking for a TN in AUTOPROVISIONING_TN) */
03426          return;
03427       pte->device->receiver_state = STATE_OFFHOOK;
03428       if (pte->device->output == OUTPUT_HEADPHONE)
03429          send_select_output(pte, OUTPUT_HEADPHONE, pte->device->volume, MUTE_OFF);
03430       else
03431          send_select_output(pte, OUTPUT_HANDSET, pte->device->volume, MUTE_OFF);
03432       if (pte->state == STATE_RINGING)
03433          HandleCallIncoming(pte);
03434       else if ((pte->state == STATE_DIALPAGE) || (pte->state == STATE_CALL))
03435          send_select_output(pte, OUTPUT_HANDSET, pte->device->volume, MUTE_OFF);
03436       else if (pte->state == STATE_EXTENSION) /* We must have a TN before calling */
03437          return;
03438       else {
03439          send_select_output(pte, OUTPUT_HANDSET, pte->device->volume, MUTE_OFF);
03440          handle_dial_page(pte);
03441       }
03442       return;
03443    }
03444    if (memcmp(buf + SIZE_HEADER, packet_recv_hangup, sizeof(packet_recv_hangup)) == 0) {
03445       if (unistimdebug)
03446          ast_verb(0, "Handset on hook\n");
03447       if (!pte->device)
03448          return;
03449       pte->device->receiver_state = STATE_ONHOOK;
03450       if (pte->state == STATE_CALL)
03451          close_call(pte);
03452       else if (pte->device->lines->subs[SUB_REAL]->owner)
03453          close_call(pte);
03454       else if (pte->state == STATE_EXTENSION)
03455          return;
03456       else
03457          show_main_page(pte);
03458       return;
03459    }
03460    strcpy(tmpbuf, ast_inet_ntoa(pte->sin.sin_addr));
03461    strcat(tmpbuf, " Unknown request packet\n");
03462    if (unistimdebug)
03463       ast_debug(1, "%s", tmpbuf);
03464    return;
03465 }

static void rcv_mac_addr ( struct unistimsession pte,
const unsigned char *  buf 
) [static]

Definition at line 1514 of file chan_unistim.c.

References alloc_sub(), ast_copy_string(), ast_free, ast_log(), ast_malloc, ast_mutex_lock(), ast_mutex_unlock(), ast_strlen_zero(), ast_verb, AUTOPROVISIONING_DB, AUTOPROVISIONING_NO, AUTOPROVISIONING_TN, AUTOPROVISIONING_YES, BUFFSEND, unistimsession::device, devicelock, unistim_device::extension, EXTENSION_ASK, EXTENSION_LINE, EXTENSION_NONE, unistim_device::extension_number, EXTENSION_TN, unistim_line::fullname, unistim_device::id, unistim_device::lines, LOG_WARNING, unistimsession::macaddr, unistim_line::name, unistim_device::name, unistim_device::next, unistim_line::parent, unistim_device::receiver_state, RegisterExtension(), send_client(), send_date_time(), unistim_device::session, SIZE_HEADER, unistimsession::state, STATE_AUTHDENY, STATE_EXTENSION, STATE_MAINPAGE, STATE_ONHOOK, SUB_REAL, unistim_device::to_delete, and unistim_register().

Referenced by process_request().

01515 {
01516    BUFFSEND;
01517    int tmp, i = 0;
01518    char addrmac[19];
01519    int res = 0;
01520    if (unistimdebug)
01521       ast_verb(0, "Mac Address received : ");
01522    for (tmp = 15; tmp < 15 + SIZE_HEADER; tmp++) {
01523       sprintf(&addrmac[i], "%.2x", (unsigned char) buf[tmp]);
01524       i += 2;
01525    }
01526    if (unistimdebug)
01527       ast_verb(0, "%s\n", addrmac);
01528    strcpy(pte->macaddr, addrmac);
01529    res = unistim_register(pte);
01530    if (!res) {
01531       switch (autoprovisioning) {
01532       case AUTOPROVISIONING_NO:
01533          ast_log(LOG_WARNING, "No entry found for this phone : %s\n", addrmac);
01534          pte->state = STATE_AUTHDENY;
01535          break;
01536       case AUTOPROVISIONING_YES:
01537          {
01538             struct unistim_device *d, *newd;
01539             struct unistim_line *newl;
01540             if (unistimdebug)
01541                ast_verb(0, "New phone, autoprovisioning on\n");
01542             /* First : locate the [template] section */
01543             ast_mutex_lock(&devicelock);
01544             d = devices;
01545             while (d) {
01546                if (!strcasecmp(d->name, "template")) {
01547                   /* Found, cloning this entry */
01548                   if (!(newd = ast_malloc(sizeof(*newd)))) {
01549                      ast_mutex_unlock(&devicelock);
01550                      return;
01551                   }
01552 
01553                   memcpy(newd, d, sizeof(*newd));
01554                   if (!(newl = ast_malloc(sizeof(*newl)))) {
01555                      ast_free(newd);
01556                      ast_mutex_unlock(&devicelock);
01557                      return;
01558                   }
01559 
01560                   memcpy(newl, d->lines, sizeof(*newl));
01561                   if (!alloc_sub(newl, SUB_REAL)) {
01562                      ast_free(newd);
01563                      ast_free(newl);
01564                      ast_mutex_unlock(&devicelock);
01565                      return;
01566                   }
01567                   /* Ok, now updating some fields */
01568                   ast_copy_string(newd->id, addrmac, sizeof(newd->id));
01569                   ast_copy_string(newd->name, addrmac, sizeof(newd->name));
01570                   if (newd->extension == EXTENSION_NONE)
01571                      newd->extension = EXTENSION_ASK;
01572                   newd->lines = newl;
01573                   newd->receiver_state = STATE_ONHOOK;
01574                   newd->session = pte;
01575                   newd->to_delete = -1;
01576                   pte->device = newd;
01577                   newd->next = NULL;
01578                   newl->parent = newd;
01579                   strcpy(newl->name, d->lines->name);
01580                   snprintf(d->lines->name, sizeof(d->lines->name), "%d",
01581                          atoi(d->lines->name) + 1);
01582                   snprintf(newl->fullname, sizeof(newl->fullname), "USTM/%s@%s",
01583                          newl->name, newd->name);
01584                   /* Go to the end of the linked chain */
01585                   while (d->next) {
01586                      d = d->next;
01587                   }
01588                   d->next = newd;
01589                   d = newd;
01590                   break;
01591                }
01592                d = d->next;
01593             }
01594             ast_mutex_unlock(&devicelock);
01595             if (!d) {
01596                ast_log(LOG_WARNING, "No entry [template] found in unistim.conf\n");
01597                pte->state = STATE_AUTHDENY;
01598             }
01599          }
01600          break;
01601       case AUTOPROVISIONING_TN:
01602          pte->state = STATE_AUTHDENY;
01603          break;
01604       case AUTOPROVISIONING_DB:
01605          ast_log(LOG_WARNING,
01606                "Autoprovisioning with database is not yet functional\n");
01607          break;
01608       default:
01609          ast_log(LOG_WARNING, "Internal error : unknown autoprovisioning value = %d\n",
01610                autoprovisioning);
01611       }
01612    }
01613    if (pte->state != STATE_AUTHDENY) {
01614       ast_verb(3, "Device '%s' successfuly registered\n", pte->device->name);
01615       switch (pte->device->extension) {
01616       case EXTENSION_NONE:
01617          pte->state = STATE_MAINPAGE;
01618          break;
01619       case EXTENSION_ASK:
01620          /* Checking if we already have an extension number */
01621          if (ast_strlen_zero(pte->device->extension_number))
01622             pte->state = STATE_EXTENSION;
01623          else {
01624             /* Yes, because of a phone reboot. We don't ask again for the TN */
01625             if (RegisterExtension(pte))
01626                pte->state = STATE_EXTENSION;
01627             else
01628                pte->state = STATE_MAINPAGE;
01629          }
01630          break;
01631       case EXTENSION_LINE:
01632          ast_copy_string(pte->device->extension_number, pte->device->lines->name,
01633                      sizeof(pte->device->extension_number));
01634          if (RegisterExtension(pte))
01635             pte->state = STATE_EXTENSION;
01636          else
01637             pte->state = STATE_MAINPAGE;
01638          break;
01639       case EXTENSION_TN:
01640          /* If we are here, it's because of a phone reboot */
01641          pte->state = STATE_MAINPAGE;
01642          break;
01643       default:
01644          ast_log(LOG_WARNING, "Internal error, extension value unknown : %d\n",
01645                pte->device->extension);
01646          pte->state = STATE_AUTHDENY;
01647          break;
01648       }
01649    }
01650    if (pte->state == STATE_EXTENSION) {
01651       if (pte->device->extension != EXTENSION_TN)
01652          pte->device->extension = EXTENSION_ASK;
01653       pte->device->extension_number[0] = '\0';
01654    }
01655    if (unistimdebug)
01656       ast_verb(0, "\nSending S1\n");
01657    memcpy(buffsend + SIZE_HEADER, packet_send_S1, sizeof(packet_send_S1));
01658    send_client(SIZE_HEADER + sizeof(packet_send_S1), buffsend, pte);
01659 
01660    if (unistimdebug)
01661       ast_verb(0, "Sending query_basic_manager_04\n");
01662    memcpy(buffsend + SIZE_HEADER, packet_send_query_basic_manager_04,
01663          sizeof(packet_send_query_basic_manager_04));
01664    send_client(SIZE_HEADER + sizeof(packet_send_query_basic_manager_04), buffsend, pte);
01665 
01666    if (unistimdebug)
01667       ast_verb(0, "Sending query_basic_manager_10\n");
01668    memcpy(buffsend + SIZE_HEADER, packet_send_query_basic_manager_10,
01669          sizeof(packet_send_query_basic_manager_10));
01670    send_client(SIZE_HEADER + sizeof(packet_send_query_basic_manager_10), buffsend, pte);
01671 
01672    send_date_time(pte);
01673    return;
01674 }

static void rcv_resume_connection_with_server ( struct unistimsession pte  )  [static]

Definition at line 1443 of file chan_unistim.c.

References ast_verb, BUFFSEND, send_client(), and SIZE_HEADER.

Referenced by process_request().

01444 {
01445    BUFFSEND;
01446    if (unistimdebug) {
01447       ast_verb(0, "ResumeConnectionWithServer received\n");
01448       ast_verb(0, "Sending packet_send_query_mac_address\n");
01449    }
01450    memcpy(buffsend + SIZE_HEADER, packet_send_query_mac_address,
01451          sizeof(packet_send_query_mac_address));
01452    send_client(SIZE_HEADER + sizeof(packet_send_query_mac_address), buffsend, pte);
01453    return;
01454 }

static int ReformatNumber ( char *  number  )  [static]

Definition at line 2964 of file chan_unistim.c.

Referenced by key_history(), and show_entry_history().

02965 {
02966    int pos = 0, i = 0, size = strlen(number);
02967 
02968    for (; i < size; i++) {
02969       if ((number[i] >= '0') && (number[i] <= '9')) {
02970          if (i == pos) {
02971             pos++;
02972             continue;
02973          }
02974          number[pos] = number[i];
02975          pos++;
02976       }
02977    }
02978    number[pos] = 0;
02979    return pos;
02980 }

static void refresh_all_favorite ( struct unistimsession pte  )  [static]

Definition at line 1047 of file chan_unistim.c.

References ast_verb, unistimsession::device, FAV_ICON_HEADPHONES_ONHOLD, send_favorite(), unistim_device::softkeyicon, unistim_device::softkeylabel, and unistim_device::softkeylinepos.

Referenced by init_phone_step2(), key_select_extension(), and reload_config().

01048 {
01049    int i = 0;
01050 
01051    if (unistimdebug)
01052       ast_verb(0, "Refreshing all favorite\n");
01053    for (i = 0; i < 6; i++) {
01054       if ((pte->device->softkeyicon[i] <= FAV_ICON_HEADPHONES_ONHOLD) &&
01055          (pte->device->softkeylinepos != i))
01056          send_favorite((unsigned char) i, pte->device->softkeyicon[i] + 1, pte,
01057                    pte->device->softkeylabel[i]);
01058       else
01059          send_favorite((unsigned char) i, pte->device->softkeyicon[i], pte,
01060                    pte->device->softkeylabel[i]);
01061 
01062    }
01063 }

static int RegisterExtension ( const struct unistimsession pte  )  [static]

Definition at line 1090 of file chan_unistim.c.

References ast_add_extension(), ast_verb, unistim_line::context, unistimsession::device, unistim_device::extension_number, unistim_line::fullname, and unistim_device::lines.

Referenced by key_select_extension(), and rcv_mac_addr().

01091 {
01092    if (unistimdebug)
01093       ast_verb(0, "Trying to register extension '%s' into context '%s' to %s\n",
01094                pte->device->extension_number, pte->device->lines->context,
01095                pte->device->lines->fullname);
01096    return ast_add_extension(pte->device->lines->context, 0,
01097                       pte->device->extension_number, 1, NULL, NULL, "Dial",
01098                       pte->device->lines->fullname, 0, "Unistim");
01099 }

static int reload ( void   )  [static]

reload: Part of Asterisk module interface ---

static int reload_config ( void   )  [static]

Definition at line 5294 of file chan_unistim.c.

References ast_category_browse(), ast_config_destroy(), ast_config_load, ast_free, ast_gethostbyname(), ast_inet_ntoa(), ast_jb_read_conf(), ast_log(), ast_mutex_destroy(), ast_mutex_lock(), ast_mutex_unlock(), ast_netsock_set_qos(), ast_str2cos(), ast_str2tos(), ast_strlen_zero(), ast_tone_zone_unref(), ast_variable_browse(), ast_verb, AUTOPROVISIONING_DB, AUTOPROVISIONING_NO, AUTOPROVISIONING_TN, AUTOPROVISIONING_YES, build_device(), config, CONFIG_STATUS_FILEINVALID, unistimsession::device, devicelock, errno, finish_bookmark(), global_jbconf, hp, ast_variable::lineno, unistim_device::lines, unistimsession::lock, unistim_line::lock, unistim_subchannel::lock, LOG_ERROR, LOG_WARNING, MAX_SUBS, unistim_device::name, ast_variable::name, NB_MAX_RETRANSMIT, unistimsession::next, unistim_device::next, ast_variable::next, unistim_subchannel::owner, qos, refresh_all_favorite(), RETRANSMIT_TIMER, s, unistim_device::session, sessionlock, unistim_line::subs, unistim_device::to_delete, unistim_device::tz, and ast_variable::value.

05295 {
05296    struct ast_config *cfg;
05297    struct ast_variable *v;
05298    struct ast_hostent ahp;
05299    struct hostent *hp;
05300    struct sockaddr_in bindaddr = { 0, };
05301    char *config = "unistim.conf";
05302    char *cat;
05303    struct unistim_device *d;
05304    const int reuseFlag = 1;
05305    struct unistimsession *s;
05306    struct ast_flags config_flags = { 0, };
05307 
05308    cfg = ast_config_load(config, config_flags);
05309    /* We *must* have a config file otherwise stop immediately */
05310    if (!cfg) {
05311       ast_log(LOG_ERROR, "Unable to load config %s\n", config);
05312       return -1;
05313    } else if (cfg == CONFIG_STATUS_FILEINVALID) {
05314       ast_log(LOG_ERROR, "Config file %s is in an invalid format.  Aborting.\n", config);
05315       return -1;
05316    }
05317    
05318    /* Copy the default jb config over global_jbconf */
05319    memcpy(&global_jbconf, &default_jbconf, sizeof(struct ast_jb_conf));
05320 
05321    unistim_keepalive = 120;
05322    unistim_port = 0;
05323    v = ast_variable_browse(cfg, "general");
05324    while (v) {
05325       /* handle jb conf */
05326       if (!ast_jb_read_conf(&global_jbconf, v->name, v->value))
05327          continue;   
05328    
05329       if (!strcasecmp(v->name, "keepalive"))
05330          unistim_keepalive = atoi(v->value);
05331       else if (!strcasecmp(v->name, "port"))
05332          unistim_port = atoi(v->value);
05333                 else if (!strcasecmp(v->name, "tos")) {
05334                         if (ast_str2tos(v->value, &qos.tos))
05335                             ast_log(LOG_WARNING, "Invalid tos value at line %d, refer to QoS documentation\n", v->lineno);
05336                 } else if (!strcasecmp(v->name, "tos_audio")) {
05337                         if (ast_str2tos(v->value, &qos.tos_audio))
05338                             ast_log(LOG_WARNING, "Invalid tos_audio value at line %d, refer to QoS documentation\n", v->lineno);
05339                 } else if (!strcasecmp(v->name, "cos")) {
05340                         if (ast_str2cos(v->value, &qos.cos))
05341                             ast_log(LOG_WARNING, "Invalid cos value at line %d, refer to QoS documentation\n", v->lineno);
05342                 } else if (!strcasecmp(v->name, "cos_audio")) {
05343                         if (ast_str2cos(v->value, &qos.cos_audio))
05344                             ast_log(LOG_WARNING, "Invalid cos_audio value at line %d, refer to QoS documentation\n", v->lineno);
05345       } else if (!strcasecmp(v->name, "autoprovisioning")) {
05346          if (!strcasecmp(v->value, "no"))
05347             autoprovisioning = AUTOPROVISIONING_NO;
05348          else if (!strcasecmp(v->value, "yes"))
05349             autoprovisioning = AUTOPROVISIONING_YES;
05350          else if (!strcasecmp(v->value, "db"))
05351             autoprovisioning = AUTOPROVISIONING_DB;
05352          else if (!strcasecmp(v->value, "tn"))
05353             autoprovisioning = AUTOPROVISIONING_TN;
05354          else
05355             ast_log(LOG_WARNING, "Unknown autoprovisioning option.\n");
05356       } else if (!strcasecmp(v->name, "public_ip")) {
05357          if (!ast_strlen_zero(v->value)) {
05358             if (!(hp = ast_gethostbyname(v->value, &ahp)))
05359                ast_log(LOG_WARNING, "Invalid address: %s\n", v->value);
05360             else {
05361                memcpy(&public_ip.sin_addr, hp->h_addr, sizeof(public_ip.sin_addr));
05362                public_ip.sin_family = AF_INET;
05363             }
05364          }
05365       }
05366       v = v->next;
05367    }
05368    if ((unistim_keepalive < 10) ||
05369       (unistim_keepalive >
05370        255 - (((NB_MAX_RETRANSMIT + 1) * RETRANSMIT_TIMER) / 1000))) {
05371       ast_log(LOG_ERROR, "keepalive is invalid in %s\n", config);
05372       ast_config_destroy(cfg);
05373       return -1;
05374    }
05375    packet_send_ping[4] =
05376       unistim_keepalive + (((NB_MAX_RETRANSMIT + 1) * RETRANSMIT_TIMER) / 1000);
05377    if ((unistim_port < 1) || (unistim_port > 65535)) {
05378       ast_log(LOG_ERROR, "port is not set or invalid in %s\n", config);
05379       ast_config_destroy(cfg);
05380       return -1;
05381    }
05382    unistim_keepalive *= 1000;
05383 
05384    ast_mutex_lock(&devicelock);
05385    d = devices;
05386    while (d) {
05387       if (d->to_delete >= 0)
05388          d->to_delete = 1;
05389       d = d->next;
05390    }
05391    ast_mutex_unlock(&devicelock);
05392    /* load the device sections */
05393    cat = ast_category_browse(cfg, NULL);
05394    while (cat) {
05395       if (strcasecmp(cat, "general")) {
05396          d = build_device(cat, ast_variable_browse(cfg, cat));
05397       }
05398       cat = ast_category_browse(cfg, cat);
05399    }
05400    ast_mutex_lock(&devicelock);
05401    d = devices;
05402    while (d) {
05403       if (d->to_delete) {
05404          int i;
05405 
05406          if (unistimdebug)
05407             ast_verb(0, "Removing device '%s'\n", d->name);
05408          if (!d->lines) {
05409             ast_log(LOG_ERROR, "Device '%s' without a line !, aborting\n", d->name);
05410             ast_config_destroy(cfg);
05411             return 0;
05412          }
05413          if (!d->lines->subs[0]) {
05414             ast_log(LOG_ERROR, "Device '%s' without a subchannel !, aborting\n",
05415                   d->name);
05416             ast_config_destroy(cfg);
05417             return 0;
05418          }
05419          if (d->lines->subs[0]->owner) {
05420             ast_log(LOG_WARNING,
05421                   "Device '%s' was not deleted : a call is in progress. Try again later.\n",
05422                   d->name);
05423             d = d->next;
05424             continue;
05425          }
05426          ast_mutex_destroy(&d->lines->subs[0]->lock);
05427          ast_free(d->lines->subs[0]);
05428          for (i = 1; i < MAX_SUBS; i++) {
05429             if (d->lines->subs[i]) {
05430                ast_log(LOG_WARNING,
05431                      "Device '%s' with threeway call subchannels allocated, aborting.\n",
05432                      d->name);
05433                break;
05434             }
05435          }
05436          if (i < MAX_SUBS) {
05437             d = d->next;
05438             continue;
05439          }
05440          ast_mutex_destroy(&d->lines->lock);
05441          ast_free(d->lines);
05442          if (d->session) {
05443             if (sessions == d->session)
05444                sessions = d->session->next;
05445             else {
05446                s = sessions;
05447                while (s) {
05448                   if (s->next == d->session) {
05449                      s->next = d->session->next;
05450                      break;
05451                   }
05452                   s = s->next;
05453                }
05454             }
05455             ast_mutex_destroy(&d->session->lock);
05456             ast_free(d->session);
05457          }
05458          if (devices == d)
05459             devices = d->next;
05460          else {
05461             struct unistim_device *d2 = devices;
05462             while (d2) {
05463                if (d2->next == d) {
05464                   d2->next = d->next;
05465                   break;
05466                }
05467                d2 = d2->next;
05468             }
05469          }
05470          if (d->tz) {
05471             d->tz = ast_tone_zone_unref(d->tz);
05472          }
05473          ast_free(d);
05474          d = devices;
05475          continue;
05476       }
05477       d = d->next;
05478    }
05479    finish_bookmark();
05480    ast_mutex_unlock(&devicelock);
05481    ast_config_destroy(cfg);
05482    ast_mutex_lock(&sessionlock);
05483    s = sessions;
05484    while (s) {
05485       if (s->device)
05486          refresh_all_favorite(s);
05487       s = s->next;
05488    }
05489    ast_mutex_unlock(&sessionlock);
05490    /* We don't recreate a socket when reloading (locks would be necessary). */
05491    if (unistimsock > -1)
05492       return 0;
05493    bindaddr.sin_addr.s_addr = INADDR_ANY;
05494    bindaddr.sin_port = htons(unistim_port);
05495    bindaddr.sin_family = AF_INET;
05496    unistimsock = socket(AF_INET, SOCK_DGRAM, 0);
05497    if (unistimsock < 0) {
05498       ast_log(LOG_WARNING, "Unable to create UNISTIM socket: %s\n", strerror(errno));
05499       return -1;
05500    }
05501 #ifdef HAVE_PKTINFO
05502    {
05503       const int pktinfoFlag = 1;
05504       setsockopt(unistimsock, IPPROTO_IP, IP_PKTINFO, &pktinfoFlag,
05505                sizeof(pktinfoFlag));
05506    }
05507 #else
05508    if (public_ip.sin_family == 0) {
05509       ast_log(LOG_WARNING,
05510             "Your OS does not support IP_PKTINFO, you must set public_ip.\n");
05511       unistimsock = -1;
05512       return -1;
05513    }
05514 #endif
05515    setsockopt(unistimsock, SOL_SOCKET, SO_REUSEADDR, (const char *) &reuseFlag,
05516             sizeof(reuseFlag));
05517    if (bind(unistimsock, (struct sockaddr *) &bindaddr, sizeof(bindaddr)) < 0) {
05518       ast_log(LOG_WARNING, "Failed to bind to %s:%d: %s\n",
05519             ast_inet_ntoa(bindaddr.sin_addr), htons(bindaddr.sin_port),
05520             strerror(errno));
05521       close(unistimsock);
05522       unistimsock = -1;
05523    } else {
05524       ast_verb(2, "UNISTIM Listening on %s:%d\n", ast_inet_ntoa(bindaddr.sin_addr), htons(bindaddr.sin_port));
05525       ast_netsock_set_qos(unistimsock, qos.tos, qos.cos, "UNISTIM");
05526    }
05527    return 0;
05528 }

static int restart_monitor ( void   )  [static]

Definition at line 4586 of file chan_unistim.c.

References ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_pthread_create, AST_PTHREADT_NULL, AST_PTHREADT_STOP, do_monitor(), LOG_ERROR, LOG_WARNING, and monlock.

04587 {
04588    pthread_attr_t attr;
04589    /* If we're supposed to be stopped -- stay stopped */
04590    if (monitor_thread == AST_PTHREADT_STOP)
04591       return 0;
04592    if (ast_mutex_lock(&monlock)) {
04593       ast_log(LOG_WARNING, "Unable to lock monitor\n");
04594       return -1;
04595    }
04596    if (monitor_thread == pthread_self()) {
04597       ast_mutex_unlock(&monlock);
04598       ast_log(LOG_WARNING, "Cannot kill myself\n");
04599       return -1;
04600    }
04601    if (monitor_thread != AST_PTHREADT_NULL) {
04602       /* Wake up the thread */
04603       pthread_kill(monitor_thread, SIGURG);
04604    } else {
04605       pthread_attr_init(&attr);
04606       pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE);
04607       /* Start a new monitor */
04608       if (ast_pthread_create(&monitor_thread, &attr, do_monitor, NULL) < 0) {
04609          ast_mutex_unlock(&monlock);
04610          ast_log(LOG_ERROR, "Unable to start monitor thread.\n");
04611          return -1;
04612       }
04613    }
04614    ast_mutex_unlock(&monlock);
04615    return 0;
04616 }

static void send_blink_cursor ( struct unistimsession pte  )  [static]

Definition at line 1420 of file chan_unistim.c.

References ast_verb, BUFFSEND, send_client(), and SIZE_HEADER.

Referenced by handle_dial_page(), HandleSelectCodec(), key_dial_page(), key_select_codec(), key_select_extension(), and ShowExtensionPage().

01421 {
01422    BUFFSEND;
01423    if (unistimdebug)
01424       ast_verb(0, "Sending set blink\n");
01425    memcpy(buffsend + SIZE_HEADER, packet_send_blink_cursor, sizeof(packet_send_blink_cursor));
01426    send_client(SIZE_HEADER + sizeof(packet_send_blink_cursor), buffsend, pte);
01427    return;
01428 }

static void send_client ( int  size,
const unsigned char *  data,
struct unistimsession pte 
) [static]

Definition at line 793 of file chan_unistim.c.

References ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_verb, wsabuf::buf, get_tick_count(), unistimsession::last_buf_available, wsabuf::len, unistimsession::lock, LOG_WARNING, MAX_BUF_NUMBER, RETRANSMIT_TIMER, send_raw_client(), unistimsession::seq_server, unistimsession::sin, unistimsession::sout, unistimsession::timeout, and unistimsession::wsabufsend.

Referenced by init_phone_step2(), rcv_mac_addr(), rcv_resume_connection_with_server(), send_blink_cursor(), send_cursor_pos(), send_date_time(), send_date_time2(), send_date_time3(), send_end_call(), send_favorite(), send_led_update(), send_no_ring(), send_ping(), send_ring(), send_select_output(), send_start_timer(), send_stop_timer(), send_text(), send_text_status(), send_texttitle(), send_tone(), Sendicon(), start_rtp(), and unistim_sp().

00794 {
00795    unsigned int tick;
00796    int buf_pos;
00797    unsigned short *sdata = (unsigned short *) data;
00798 
00799    ast_mutex_lock(&pte->lock);
00800    buf_pos = pte->last_buf_available;
00801 
00802    if (buf_pos >= MAX_BUF_NUMBER) {
00803       ast_log(LOG_WARNING, "Error : send queue overflow\n");
00804       ast_mutex_unlock(&pte->lock);
00805       return;
00806    }
00807    sdata[1] = ntohs(++(pte->seq_server));
00808    pte->wsabufsend[buf_pos].len = size;
00809    memcpy(pte->wsabufsend[buf_pos].buf, data, size);
00810 
00811    tick = get_tick_count();
00812    pte->timeout = tick + RETRANSMIT_TIMER;
00813 
00814 /*#ifdef DUMP_PACKET */
00815    if (unistimdebug)
00816       ast_verb(6, "Sending datas with seq #0x%.4x Using slot #%d :\n", pte->seq_server, buf_pos);
00817 /*#endif */
00818    send_raw_client(pte->wsabufsend[buf_pos].len, pte->wsabufsend[buf_pos].buf, &(pte->sin),
00819               &(pte->sout));
00820    pte->last_buf_available++;
00821    ast_mutex_unlock(&pte->lock);
00822 }

static void send_cursor_pos ( struct unistimsession pte,
unsigned char  pos 
) [static]

Definition at line 1431 of file chan_unistim.c.

References ast_verb, BUFFSEND, send_client(), and SIZE_HEADER.

Referenced by handle_dial_page(), HandleSelectCodec(), key_dial_page(), key_select_codec(), key_select_extension(), and ShowExtensionPage().

01432 {
01433    BUFFSEND;
01434    if (unistimdebug)
01435       ast_verb(0, "Sending set cursor position\n");
01436    memcpy(buffsend + SIZE_HEADER, packet_send_set_pos_cursor,
01437          sizeof(packet_send_set_pos_cursor));
01438    buffsend[11] = pos;
01439    send_client(SIZE_HEADER + sizeof(packet_send_set_pos_cursor), buffsend, pte);
01440    return;
01441 }

static void send_date_time ( struct unistimsession pte  )  [static]

Definition at line 1365 of file chan_unistim.c.

References ast_localtime(), ast_tvnow(), ast_verb, BUFFSEND, send_client(), SIZE_HEADER, ast_tm::tm_hour, ast_tm::tm_mday, ast_tm::tm_min, and ast_tm::tm_mon.

Referenced by rcv_mac_addr().

01366 {
01367    BUFFSEND;
01368    struct timeval now = ast_tvnow();
01369    struct ast_tm atm = { 0, };
01370 
01371    if (unistimdebug)
01372       ast_verb(0, "Sending Time & Date\n");
01373    memcpy(buffsend + SIZE_HEADER, packet_send_date_time, sizeof(packet_send_date_time));
01374    ast_localtime(&now, &atm, NULL);
01375    buffsend[10] = (unsigned char) atm.tm_mon + 1;
01376    buffsend[11] = (unsigned char) atm.tm_mday;
01377    buffsend[12] = (unsigned char) atm.tm_hour;
01378    buffsend[13] = (unsigned char) atm.tm_min;
01379    send_client(SIZE_HEADER + sizeof(packet_send_date_time), buffsend, pte);
01380 }

static void send_date_time2 ( struct unistimsession pte  )  [static]

Definition at line 1382 of file chan_unistim.c.

References ast_localtime(), ast_tvnow(), ast_verb, BUFFSEND, unistim_device::datetimeformat, unistimsession::device, send_client(), SIZE_HEADER, ast_tm::tm_hour, ast_tm::tm_mday, ast_tm::tm_min, and ast_tm::tm_mon.

Referenced by init_phone_step2().

01383 {
01384    BUFFSEND;
01385    struct timeval now = ast_tvnow();
01386    struct ast_tm atm = { 0, };
01387 
01388    if (unistimdebug)
01389       ast_verb(0, "Sending Time & Date #2\n");
01390    memcpy(buffsend + SIZE_HEADER, packet_send_date_time2, sizeof(packet_send_date_time2));
01391    ast_localtime(&now, &atm, NULL);
01392    if (pte->device)
01393       buffsend[9] = pte->device->datetimeformat;
01394    else
01395       buffsend[9] = 61;
01396    buffsend[14] = (unsigned char) atm.tm_mon + 1;
01397    buffsend[15] = (unsigned char) atm.tm_mday;
01398    buffsend[16] = (unsigned char) atm.tm_hour;
01399    buffsend[17] = (unsigned char) atm.tm_min;
01400    send_client(SIZE_HEADER + sizeof(packet_send_date_time2), buffsend, pte);
01401 }

static void send_date_time3 ( struct unistimsession pte  )  [static]

Definition at line 1403 of file chan_unistim.c.

References ast_localtime(), ast_tvnow(), ast_verb, BUFFSEND, send_client(), SIZE_HEADER, ast_tm::tm_hour, ast_tm::tm_mday, ast_tm::tm_min, and ast_tm::tm_mon.

Referenced by init_phone_step2().

01404 {
01405    BUFFSEND;
01406    struct timeval now = ast_tvnow();
01407    struct ast_tm atm = { 0, };
01408 
01409    if (unistimdebug)
01410       ast_verb(0, "Sending Time & Date #3\n");
01411    memcpy(buffsend + SIZE_HEADER, packet_send_date_time3, sizeof(packet_send_date_time3));
01412    ast_localtime(&now, &atm, NULL);
01413    buffsend[10] = (unsigned char) atm.tm_mon + 1;
01414    buffsend[11] = (unsigned char) atm.tm_mday;
01415    buffsend[12] = (unsigned char) atm.tm_hour;
01416    buffsend[13] = (unsigned char) atm.tm_min;
01417    send_client(SIZE_HEADER + sizeof(packet_send_date_time3), buffsend, pte);
01418 }

static void send_end_call ( struct unistimsession pte  )  [static]

Definition at line 902 of file chan_unistim.c.

References ast_verb, BUFFSEND, send_client(), and SIZE_HEADER.

Referenced by unistim_hangup().

00903 {
00904    BUFFSEND;
00905    if (unistimdebug)
00906       ast_verb(0, "Sending end call\n");
00907    memcpy(buffsend + SIZE_HEADER, packet_send_end_call, sizeof(packet_send_end_call));
00908    send_client(SIZE_HEADER + sizeof(packet_send_end_call), buffsend, pte);
00909 }

static void send_favorite ( unsigned char  pos,
unsigned char  status,
struct unistimsession pte,
const char *  text 
) [static]

Definition at line 1028 of file chan_unistim.c.

References ast_verb, BUFFSEND, FAV_MAX_LENGTH, send_client(), and SIZE_HEADER.

Referenced by change_favorite_icon(), init_phone_step2(), refresh_all_favorite(), show_main_page(), and unistim_sendtext().

01030 {
01031    BUFFSEND;
01032    int i;
01033 
01034    if (unistimdebug)
01035       ast_verb(0, "Sending favorite pos %d with status 0x%.2x\n", pos, status);
01036    memcpy(buffsend + SIZE_HEADER, packet_send_favorite, sizeof(packet_send_favorite));
01037    buffsend[10] = pos;
01038    buffsend[24] = pos;
01039    buffsend[25] = status;
01040    i = strlen(text);
01041    if (i > FAV_MAX_LENGTH)
01042       i = FAV_MAX_LENGTH;
01043    memcpy(buffsend + FAV_MAX_LENGTH + 1, text, i);
01044    send_client(SIZE_HEADER + sizeof(packet_send_favorite), buffsend, pte);
01045 }

static void send_led_update ( struct unistimsession pte,
unsigned char  led 
) [static]

Definition at line 1256 of file chan_unistim.c.

References ast_verb, BUFFSEND, send_client(), and SIZE_HEADER.

Referenced by handle_dial_page(), init_phone_step2(), send_select_output(), and unistim_send_mwi_to_peer().

01257 {
01258    BUFFSEND;
01259    if (unistimdebug)
01260       ast_verb(0, "Sending led_update (%x)\n", led);
01261    memcpy(buffsend + SIZE_HEADER, packet_send_led_update, sizeof(packet_send_led_update));
01262    buffsend[9] = led;
01263    send_client(SIZE_HEADER + sizeof(packet_send_led_update), buffsend, pte);
01264 }

static void send_no_ring ( struct unistimsession pte  )  [static]

Definition at line 1341 of file chan_unistim.c.

References ast_verb, BUFFSEND, send_client(), and SIZE_HEADER.

Referenced by cancel_dial(), HandleCallIncoming(), IgnoreCall(), init_phone_step2(), and unistim_hangup().

01342 {
01343    BUFFSEND;
01344    if (unistimdebug)
01345       ast_verb(0, "Sending no ring packet\n");
01346    memcpy(buffsend + SIZE_HEADER, packet_send_no_ring, sizeof(packet_send_no_ring));
01347    send_client(SIZE_HEADER + sizeof(packet_send_no_ring), buffsend, pte);
01348 }

static void send_ping ( struct unistimsession pte  )  [static]

Definition at line 824 of file chan_unistim.c.

References ast_verb, BUFFSEND, get_tick_count(), send_client(), SIZE_HEADER, and unistimsession::tick_next_ping.

00825 {
00826    BUFFSEND;
00827    if (unistimdebug)
00828       ast_verb(6, "Sending ping\n");
00829    pte->tick_next_ping = get_tick_count() + unistim_keepalive;
00830    memcpy(buffsend + SIZE_HEADER, packet_send_ping, sizeof(packet_send_ping));
00831    send_client(SIZE_HEADER + sizeof(packet_send_ping), buffsend, pte);
00832 }

static void send_raw_client ( int  size,
const unsigned char *  data,
struct sockaddr_in *  addr_to,
const struct sockaddr_in *  addr_ourip 
) [static]

Definition at line 736 of file chan_unistim.c.

References ast_inet_ntoa(), ast_verb, and display_last_error().

Referenced by parsing(), send_client(), and send_retransmit().

00738 {
00739 #ifdef HAVE_PKTINFO
00740    struct iovec msg_iov;
00741    struct msghdr msg;
00742    char buffer[CMSG_SPACE(sizeof(struct in_pktinfo))];
00743    struct cmsghdr *ip_msg = (struct cmsghdr *) buffer;
00744    struct in_pktinfo *pki = (struct in_pktinfo *) CMSG_DATA(ip_msg);
00745 
00746    /* cast this to a non-const pointer, since the sendmsg() API
00747     * does not provide read-only and write-only flavors of the
00748     * structures used for its arguments, but in this case we know
00749     * the data will not be modified
00750     */
00751    msg_iov.iov_base = (char *) data;
00752    msg_iov.iov_len = size;
00753 
00754    msg.msg_name = addr_to;  /* optional address */
00755    msg.msg_namelen = sizeof(struct sockaddr_in);   /* size of address */
00756    msg.msg_iov = &msg_iov;  /* scatter/gather array */
00757    msg.msg_iovlen = 1;          /* # elements in msg_iov */
00758    msg.msg_control = ip_msg;       /* ancillary data */
00759    msg.msg_controllen = sizeof(buffer);    /* ancillary data buffer len */
00760    msg.msg_flags = 0;            /* flags on received message */
00761 
00762    ip_msg->cmsg_len = CMSG_LEN(sizeof(*pki));
00763    ip_msg->cmsg_level = IPPROTO_IP;
00764    ip_msg->cmsg_type = IP_PKTINFO;
00765    pki->ipi_ifindex = 0;      /* Interface index, 0 = use interface specified in routing table */
00766    pki->ipi_spec_dst.s_addr = addr_ourip->sin_addr.s_addr; /* Local address */
00767    /* pki->ipi_addr = ;   Header Destination address - ignored by kernel */
00768 
00769 #ifdef DUMP_PACKET
00770    if (unistimdebug) {
00771       int tmp;
00772       char iabuf[INET_ADDRSTRLEN];
00773       char iabuf2[INET_ADDRSTRLEN];
00774       ast_verb(0, "\n**> From %s sending %d bytes to %s ***\n",
00775                ast_inet_ntoa(addr_ourip->sin_addr), (int) size,
00776                ast_inet_ntoa(addr_to->sin_addr));
00777       for (tmp = 0; tmp < size; tmp++)
00778          ast_verb(0, "%.2x ", (unsigned char) data[tmp]);
00779       ast_verb(0, "\n******************************************\n");
00780 
00781    }
00782 #endif
00783 
00784    if (sendmsg(unistimsock, &msg, 0) == -1)
00785       display_last_error("Error sending datas");
00786 #else
00787    if (sendto(unistimsock, data, size, 0, (struct sockaddr *) addr_to, sizeof(*addr_to))
00788       == -1)
00789       display_last_error("Error sending datas");
00790 #endif
00791 }

static int send_retransmit ( struct unistimsession pte  )  [static]

Definition at line 1161 of file chan_unistim.c.

References ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_verb, wsabuf::buf, close_client(), get_tick_count(), unistimsession::last_buf_available, unistimsession::last_seq_ack, wsabuf::len, unistimsession::lock, LOG_WARNING, NB_MAX_RETRANSMIT, unistimsession::nb_retransmit, RETRANSMIT_TIMER, send_raw_client(), seq, unistimsession::seq_server, unistimsession::sin, unistimsession::sout, unistimsession::timeout, and unistimsession::wsabufsend.

Referenced by do_monitor(), and parsing().

01162 {
01163    int i;
01164 
01165    ast_mutex_lock(&pte->lock);
01166    if (++pte->nb_retransmit >= NB_MAX_RETRANSMIT) {
01167       if (unistimdebug)
01168          ast_verb(0, "Too many retransmit - freeing client\n");
01169       ast_mutex_unlock(&pte->lock);
01170       close_client(pte);
01171       return 1;
01172    }
01173    pte->timeout = get_tick_count() + RETRANSMIT_TIMER;
01174 
01175    for (i = pte->last_buf_available - (pte->seq_server - pte->last_seq_ack);
01176        i < pte->last_buf_available; i++) {
01177       if (i < 0) {
01178          ast_log(LOG_WARNING,
01179                "Asked to retransmit an ACKed slot ! last_buf_available=%d, seq_server = #0x%.4x last_seq_ack = #0x%.4x\n",
01180                pte->last_buf_available, pte->seq_server, pte->last_seq_ack);
01181          continue;
01182       }
01183 
01184       if (unistimdebug) {
01185          unsigned short *sbuf = (unsigned short *) pte->wsabufsend[i].buf;
01186          unsigned short seq;
01187 
01188          seq = ntohs(sbuf[1]);
01189          ast_verb(0, "Retransmit slot #%d (seq=#0x%.4x), last ack was #0x%.4x\n", i,
01190                   seq, pte->last_seq_ack);
01191       }
01192       send_raw_client(pte->wsabufsend[i].len, pte->wsabufsend[i].buf, &pte->sin,
01193                  &pte->sout);
01194    }
01195    ast_mutex_unlock(&pte->lock);
01196    return 0;
01197 }

static void send_ring ( struct unistimsession pte,
char  volume,
char  style 
) [static]

Definition at line 1330 of file chan_unistim.c.

References ast_verb, BUFFSEND, send_client(), and SIZE_HEADER.

Referenced by unistim_call().

01331 {
01332    BUFFSEND;
01333    if (unistimdebug)
01334       ast_verb(0, "Sending ring packet\n");
01335    memcpy(buffsend + SIZE_HEADER, packet_send_ring, sizeof(packet_send_ring));
01336    buffsend[24] = style + 0x10;
01337    buffsend[29] = volume * 0x10;
01338    send_client(SIZE_HEADER + sizeof(packet_send_ring), buffsend, pte);
01339 }

static void send_select_output ( struct unistimsession pte,
unsigned char  output,
unsigned char  volume,
unsigned char  mute 
) [static]

Definition at line 1270 of file chan_unistim.c.

References ast_log(), ast_verb, BUFFSEND, change_favorite_icon(), unistimsession::device, FAV_ICON_HEADPHONES, FAV_ICON_HEADPHONES_ONHOLD, FAV_ICON_OFFHOOK_BLACK, FAV_ICON_ONHOLD_BLACK, FAV_ICON_SPEAKER_OFFHOOK_BLACK, FAV_ICON_SPEAKER_ONHOLD_BLACK, FAV_ICON_SPEAKER_ONHOOK_BLACK, LOG_WARNING, unistim_device::mute, MUTE_OFF, MUTE_ON, MUTE_ON_DISCRET, unistim_device::output, OUTPUT_HANDSET, OUTPUT_HEADPHONE, OUTPUT_SPEAKER, unistim_device::previous_output, unistim_device::receiver_state, send_client(), send_led_update(), SIZE_HEADER, STATE_OFFHOOK, VOLUME_LOW, and VOLUME_LOW_SPEAKER.

Referenced by handle_dial_page(), HandleCallIncoming(), HandleCallOutgoing(), key_call(), key_dial_page(), key_main_page(), process_request(), and show_main_page().

01272 {
01273    BUFFSEND;
01274    if (unistimdebug)
01275       ast_verb(0, "Sending select output packet output=%x volume=%x mute=%x\n", output,
01276                volume, mute);
01277    memcpy(buffsend + SIZE_HEADER, packet_send_select_output,
01278          sizeof(packet_send_select_output));
01279    buffsend[9] = output;
01280    if (output == OUTPUT_SPEAKER)
01281       volume = VOLUME_LOW_SPEAKER;
01282    else
01283       volume = VOLUME_LOW;
01284    buffsend[10] = volume;
01285    if (mute == MUTE_ON_DISCRET)
01286       buffsend[11] = MUTE_ON;
01287    else
01288       buffsend[11] = mute;
01289    send_client(SIZE_HEADER + sizeof(packet_send_select_output), buffsend, pte);
01290    if (mute == MUTE_OFF)
01291       send_led_update(pte, 0x18);
01292    else if (mute == MUTE_ON)
01293       send_led_update(pte, 0x19);
01294    pte->device->mute = mute;
01295    if (output == OUTPUT_HANDSET) {
01296       if (mute == MUTE_ON)
01297          change_favorite_icon(pte, FAV_ICON_ONHOLD_BLACK);
01298       else
01299          change_favorite_icon(pte, FAV_ICON_OFFHOOK_BLACK);
01300       send_led_update(pte, 0x08);
01301       send_led_update(pte, 0x10);
01302    } else if (output == OUTPUT_HEADPHONE) {
01303       if (mute == MUTE_ON)
01304          change_favorite_icon(pte, FAV_ICON_HEADPHONES_ONHOLD);
01305       else
01306          change_favorite_icon(pte, FAV_ICON_HEADPHONES);
01307       send_led_update(pte, 0x08);
01308       send_led_update(pte, 0x11);
01309    } else if (output == OUTPUT_SPEAKER) {
01310       send_led_update(pte, 0x10);
01311       send_led_update(pte, 0x09);
01312       if (pte->device->receiver_state == STATE_OFFHOOK) {
01313          if (mute == MUTE_ON)
01314             change_favorite_icon(pte, FAV_ICON_SPEAKER_ONHOLD_BLACK);
01315          else
01316             change_favorite_icon(pte, FAV_ICON_SPEAKER_ONHOOK_BLACK);
01317       } else {
01318          if (mute == MUTE_ON)
01319             change_favorite_icon(pte, FAV_ICON_SPEAKER_ONHOLD_BLACK);
01320          else
01321             change_favorite_icon(pte, FAV_ICON_SPEAKER_OFFHOOK_BLACK);
01322       }
01323    } else
01324       ast_log(LOG_WARNING, "Invalid ouput (%d)\n", output);
01325    if (output != pte->device->output)
01326       pte->device->previous_output = pte->device->output;
01327    pte->device->output = output;
01328 }

static void send_start_timer ( struct unistimsession pte  )  [static]

Definition at line 945 of file chan_unistim.c.

References ast_verb, BUFFSEND, send_client(), and SIZE_HEADER.

Referenced by HandleCallIncoming(), and unistim_answer().

00946 {
00947    BUFFSEND;
00948    if (unistimdebug)
00949       ast_verb(0, "Sending start timer\n");
00950    memcpy(buffsend + SIZE_HEADER, packet_send_StartTimer, sizeof(packet_send_StartTimer));
00951    send_client(SIZE_HEADER + sizeof(packet_send_StartTimer), buffsend, pte);
00952 }

static void send_stop_timer ( struct unistimsession pte  )  [static]

Definition at line 954 of file chan_unistim.c.

References ast_verb, BUFFSEND, send_client(), and SIZE_HEADER.

Referenced by close_call().

00955 {
00956    BUFFSEND;
00957    if (unistimdebug)
00958       ast_verb(0, "Sending stop timer\n");
00959    memcpy(buffsend + SIZE_HEADER, packet_send_stop_timer, sizeof(packet_send_stop_timer));
00960    send_client(SIZE_HEADER + sizeof(packet_send_stop_timer), buffsend, pte);
00961 }

static void send_text ( unsigned char  pos,
unsigned char  inverse,
struct unistimsession pte,
const char *  text 
) [static]

Definition at line 1201 of file chan_unistim.c.

References ast_verb, BUFFSEND, send_client(), SIZE_HEADER, and TEXT_LENGTH_MAX.

Referenced by handle_dial_page(), HandleCallIncoming(), HandleCallOutgoing(), HandleSelectCodec(), init_phone_step2(), key_dial_page(), key_select_codec(), key_select_extension(), show_entry_history(), show_main_page(), ShowExtensionPage(), unistim_answer(), unistim_call(), unistim_hangup(), unistim_indicate(), and unistim_sendtext().

01203 {
01204    int i;
01205    BUFFSEND;
01206    if (unistimdebug)
01207       ast_verb(0, "Sending text at pos %d, inverse flag %d\n", pos, inverse);
01208    memcpy(buffsend + SIZE_HEADER, packet_send_text, sizeof(packet_send_text));
01209    buffsend[10] = pos;
01210    buffsend[11] = inverse;
01211    i = strlen(text);
01212    if (i > TEXT_LENGTH_MAX)
01213       i = TEXT_LENGTH_MAX;
01214    memcpy(buffsend + 12, text, i);
01215    send_client(SIZE_HEADER + sizeof(packet_send_text), buffsend, pte);
01216 }

static void send_text_status ( struct unistimsession pte,
const char *  text 
) [static]

Definition at line 1218 of file chan_unistim.c.

References ast_verb, BUFFSEND, unistimsession::device, send_client(), SIZE_HEADER, STATUS_LENGTH_MAX, and unistim_device::status_method.

Referenced by handle_dial_page(), HandleCallIncoming(), HandleCallOutgoing(), HandleSelectCodec(), init_phone_step2(), key_dial_page(), show_entry_history(), show_main_page(), ShowExtensionPage(), unistim_answer(), unistim_call(), and unistim_hangup().

01219 {
01220    BUFFSEND;
01221    int i;
01222    if (unistimdebug)
01223       ast_verb(0, "Sending status text\n");
01224    if (pte->device) {
01225       if (pte->device->status_method == 1) {  /* For new firmware and i2050 soft phone */
01226          int n = strlen(text);
01227          /* Must send individual button separately */
01228          int j;
01229          for (i = 0, j = 0; i < 4; i++, j += 7) {
01230             int pos = 0x08 + (i * 0x20);
01231             memcpy(buffsend + SIZE_HEADER, packet_send_status2,
01232                   sizeof(packet_send_status2));
01233 
01234             buffsend[9] = pos;
01235             memcpy(buffsend + 10, (j < n) ? (text + j) : "       ", 7);
01236             send_client(SIZE_HEADER + sizeof(packet_send_status2), buffsend, pte);
01237          }
01238          return;
01239       }
01240    }
01241 
01242 
01243    memcpy(buffsend + SIZE_HEADER, packet_send_status, sizeof(packet_send_status));
01244    i = strlen(text);
01245    if (i > STATUS_LENGTH_MAX)
01246       i = STATUS_LENGTH_MAX;
01247    memcpy(buffsend + 10, text, i);
01248    send_client(SIZE_HEADER + sizeof(packet_send_status), buffsend, pte);
01249 
01250 }

static void send_texttitle ( struct unistimsession pte,
const char *  text 
) [static]

Definition at line 1350 of file chan_unistim.c.

References ast_verb, BUFFSEND, send_client(), and SIZE_HEADER.

Referenced by init_phone_step2(), show_entry_history(), and show_main_page().

01351 {
01352    BUFFSEND;
01353    int i;
01354    if (unistimdebug)
01355       ast_verb(0, "Sending title text\n");
01356    memcpy(buffsend + SIZE_HEADER, packet_send_title, sizeof(packet_send_title));
01357    i = strlen(text);
01358    if (i > 12)
01359       i = 12;
01360    memcpy(buffsend + 10, text, i);
01361    send_client(SIZE_HEADER + sizeof(packet_send_title), buffsend, pte);
01362 
01363 }

static void send_tone ( struct unistimsession pte,
uint16_t  tone1,
uint16_t  tone2 
) [static]

Definition at line 974 of file chan_unistim.c.

References ast_verb, BUFFSEND, send_client(), and SIZE_HEADER.

Referenced by HandleCallOutgoing(), key_dial_page(), SendDialTone(), show_main_page(), unistim_do_senddigit(), unistim_senddigit_end(), and unistim_ss().

00975 {
00976    BUFFSEND;
00977    if (!tone1) {
00978       if (unistimdebug)
00979          ast_verb(0, "Sending Stream Based Tone Off\n");
00980       memcpy(buffsend + SIZE_HEADER, packet_send_stream_based_tone_off,
00981             sizeof(packet_send_stream_based_tone_off));
00982       send_client(SIZE_HEADER + sizeof(packet_send_stream_based_tone_off), buffsend, pte);
00983       return;
00984    }
00985    /* Since most of the world use a continuous tone, it's useless
00986       if (unistimdebug)
00987       ast_verb(0, "Sending Stream Based Tone Cadence Download\n");
00988       memcpy (buffsend + SIZE_HEADER, packet_send_StreamBasedToneCad, sizeof (packet_send_StreamBasedToneCad));
00989       send_client (SIZE_HEADER + sizeof (packet_send_StreamBasedToneCad), buffsend, pte); */
00990    if (unistimdebug)
00991       ast_verb(0, "Sending Stream Based Tone Frequency Component List Download %d %d\n", tone1, tone2);
00992    tone1 *= 8;
00993    if (!tone2) {
00994       memcpy(buffsend + SIZE_HEADER, packet_send_stream_based_tone_single_freq,
00995             sizeof(packet_send_stream_based_tone_single_freq));
00996       buffsend[10] = (tone1 & 0xff00) >> 8;
00997       buffsend[11] = (tone1 & 0x00ff);
00998       send_client(SIZE_HEADER + sizeof(packet_send_stream_based_tone_single_freq), buffsend,
00999                pte);
01000    } else {
01001       tone2 *= 8;
01002       memcpy(buffsend + SIZE_HEADER, packet_send_stream_based_tone_dial_freq,
01003             sizeof(packet_send_stream_based_tone_dial_freq));
01004       buffsend[10] = (tone1 & 0xff00) >> 8;
01005       buffsend[11] = (tone1 & 0x00ff);
01006       buffsend[12] = (tone2 & 0xff00) >> 8;
01007       buffsend[13] = (tone2 & 0x00ff);
01008       send_client(SIZE_HEADER + sizeof(packet_send_stream_based_tone_dial_freq), buffsend,
01009                pte);
01010    }
01011 
01012    if (unistimdebug)
01013       ast_verb(0, "Sending Stream Based Tone On\n");
01014    memcpy(buffsend + SIZE_HEADER, packet_send_stream_based_tone_on,
01015          sizeof(packet_send_stream_based_tone_on));
01016    send_client(SIZE_HEADER + sizeof(packet_send_stream_based_tone_on), buffsend, pte);
01017 }

static void SendDialTone ( struct unistimsession pte  )  [static]

Definition at line 2230 of file chan_unistim.c.

References ast_strlen_zero(), ast_verb, tone_zone_unistim::country, country, unistim_device::country, unistimsession::device, and send_tone().

Referenced by handle_dial_page().

02231 {
02232    int i;
02233    /* No country defined ? Using US tone */
02234    if (ast_strlen_zero(pte->device->country)) {
02235       if (unistimdebug)
02236          ast_verb(0, "No country defined, using US tone\n");
02237       send_tone(pte, 350, 440);
02238       return;
02239    }
02240    if (strlen(pte->device->country) != 2) {
02241       if (unistimdebug)
02242          ast_verb(0, "Country code != 2 char, using US tone\n");
02243       send_tone(pte, 350, 440);
02244       return;
02245    }
02246    i = 0;
02247    while (frequency[i].freq1) {
02248       if ((frequency[i].country[0] == pte->device->country[0]) &&
02249          (frequency[i].country[1] == pte->device->country[1])) {
02250          if (unistimdebug)
02251             ast_verb(0, "Country code found (%s), freq1=%d freq2=%d\n",
02252                      frequency[i].country, frequency[i].freq1, frequency[i].freq2);
02253          send_tone(pte, frequency[i].freq1, frequency[i].freq2);
02254       }
02255       i++;
02256    }
02257 }

static void Sendicon ( unsigned char  pos,
unsigned char  status,
struct unistimsession pte 
) [static]

Definition at line 963 of file chan_unistim.c.

References ast_verb, BUFFSEND, send_client(), and SIZE_HEADER.

Referenced by handle_dial_page(), key_main_page(), show_main_page(), and unistim_call().

00964 {
00965    BUFFSEND;
00966    if (unistimdebug)
00967       ast_verb(0, "Sending icon pos %d with status 0x%.2x\n", pos, status);
00968    memcpy(buffsend + SIZE_HEADER, packet_send_icon, sizeof(packet_send_icon));
00969    buffsend[9] = pos;
00970    buffsend[10] = status;
00971    send_client(SIZE_HEADER + sizeof(packet_send_icon), buffsend, pte);
00972 }

static void set_ping_timer ( struct unistimsession pte  )  [static]

Definition at line 911 of file chan_unistim.c.

References DEBUG_TIMER, unistimsession::tick_next_ping, and unistimsession::timeout.

Referenced by check_send_queue().

00912 {
00913    unsigned int tick = 0;  /* XXX what is this for, anyways */
00914 
00915    pte->timeout = pte->tick_next_ping;
00916    DEBUG_TIMER("tick = %u next ping at %u tick\n", tick, pte->timeout);
00917    return;
00918 }

static void show_entry_history ( struct unistimsession pte,
FILE **  f 
) [static]

Definition at line 2982 of file chan_unistim.c.

References ast_copy_string(), unistimsession::buff_entry, unistimsession::device, display_last_error(), unistim_device::lst_cid, ReformatNumber(), send_text(), send_text_status(), send_texttitle(), status, STATUS_LENGTH_MAX, TEXT_LENGTH_MAX, TEXT_LINE0, TEXT_LINE1, TEXT_LINE2, and TEXT_NORMAL.

Referenced by key_history(), and show_history().

02983 {
02984    char line[TEXT_LENGTH_MAX + 1], status[STATUS_LENGTH_MAX + 1], func1[10], func2[10],
02985       func3[10];
02986 
02987    if (fread(line, TEXT_LENGTH_MAX, 1, *f) != 1) {
02988       display_last_error("Can't read history date entry");
02989       fclose(*f);
02990       return;
02991    }
02992    line[sizeof(line) - 1] = '\0';
02993    send_text(TEXT_LINE0, TEXT_NORMAL, pte, line);
02994    if (fread(line, TEXT_LENGTH_MAX, 1, *f) != 1) {
02995       display_last_error("Can't read callerid entry");
02996       fclose(*f);
02997       return;
02998    }
02999    line[sizeof(line) - 1] = '\0';
03000    ast_copy_string(pte->device->lst_cid, line, sizeof(pte->device->lst_cid));
03001    send_text(TEXT_LINE1, TEXT_NORMAL, pte, line);
03002    if (fread(line, TEXT_LENGTH_MAX, 1, *f) != 1) {
03003       display_last_error("Can't read callername entry");
03004       fclose(*f);
03005       return;
03006    }
03007    line[sizeof(line) - 1] = '\0';
03008    send_text(TEXT_LINE2, TEXT_NORMAL, pte, line);
03009    fclose(*f);
03010 
03011    snprintf(line, sizeof(line), "Call %03d/%03d", pte->buff_entry[2],
03012           pte->buff_entry[1]);
03013    send_texttitle(pte, line);
03014 
03015    if (pte->buff_entry[2] == 1)
03016       strcpy(func1, "       ");
03017    else
03018       strcpy(func1, "Prvious");
03019    if (pte->buff_entry[2] >= pte->buff_entry[1])
03020       strcpy(func2, "       ");
03021    else
03022       strcpy(func2, "Next   ");
03023    if (ReformatNumber(pte->device->lst_cid))
03024       strcpy(func3, "Redial ");
03025    else
03026       strcpy(func3, "       ");
03027    snprintf(status, sizeof(status), "%s%s%sCancel", func1, func2, func3);
03028    send_text_status(pte, status);
03029 }

static void show_history ( struct unistimsession pte,
char  way 
) [static]

Definition at line 3057 of file chan_unistim.c.

References unistimsession::buff_entry, unistim_device::callhistory, unistimsession::device, f, OpenHistory(), show_entry_history(), unistimsession::state, and STATE_HISTORY.

Referenced by key_history(), and key_main_page().

03058 {
03059    FILE *f;
03060    char count;
03061 
03062    if (!pte->device)
03063       return;
03064    if (!pte->device->callhistory)
03065       return;
03066    count = OpenHistory(pte, way, &f);
03067    if (!count)
03068       return;
03069    pte->buff_entry[0] = way;
03070    pte->buff_entry[1] = count;
03071    pte->buff_entry[2] = 1;
03072    show_entry_history(pte, &f);
03073    pte->state = STATE_HISTORY;
03074 }

static void show_main_page ( struct unistimsession pte  )  [static]

Definition at line 3076 of file chan_unistim.c.

References ast_inet_ntoa(), ast_strlen_zero(), unistim_device::call_forward, change_favorite_icon(), unistimsession::device, unistim_device::extension, EXTENSION_ASK, unistim_device::extension_number, EXTENSION_TN, FAV_BLINK_SLOW, FAV_ICON_CALL_CENTER, FAV_ICON_ONHOOK_BLACK, FAV_ICON_REFLECT, unistim_line::lastmsgssent, unistim_device::lines, unistim_device::maintext0, unistim_device::maintext1, unistim_device::maintext2, unistim_device::missed_call, MUTE_ON_DISCRET, unistim_device::output, send_favorite(), send_select_output(), send_text(), send_text_status(), send_texttitle(), send_tone(), Sendicon(), ShowExtensionPage(), unistimsession::sin, unistim_device::softkeylabel, unistim_device::softkeylinepos, unistimsession::state, STATE_MAINPAGE, TEXT_LENGTH_MAX, TEXT_LINE0, TEXT_LINE1, TEXT_LINE2, TEXT_NORMAL, unistim_device::titledefault, and unistim_device::volume.

Referenced by cancel_dial(), close_call(), init_phone_step2(), key_dial_page(), key_history(), key_main_page(), key_select_codec(), key_select_extension(), and process_request().

03077 {
03078    char tmpbuf[TEXT_LENGTH_MAX + 1];
03079 
03080 
03081    if ((pte->device->extension == EXTENSION_ASK) &&
03082       (ast_strlen_zero(pte->device->extension_number))) {
03083       ShowExtensionPage(pte);
03084       return;
03085    }
03086 
03087    pte->state = STATE_MAINPAGE;
03088 
03089    send_tone(pte, 0, 0);
03090    send_select_output(pte, pte->device->output, pte->device->volume, MUTE_ON_DISCRET);
03091    pte->device->lines->lastmsgssent = 0;
03092    send_favorite(pte->device->softkeylinepos, FAV_ICON_ONHOOK_BLACK, pte,
03093              pte->device->softkeylabel[pte->device->softkeylinepos]);
03094    if (!ast_strlen_zero(pte->device->call_forward)) {
03095       send_text(TEXT_LINE0, TEXT_NORMAL, pte, "Call forwarded to :");
03096       send_text(TEXT_LINE1, TEXT_NORMAL, pte, pte->device->call_forward);
03097       Sendicon(TEXT_LINE0, FAV_ICON_REFLECT + FAV_BLINK_SLOW, pte);
03098       send_text_status(pte, "Dial   Redial NoForwd");
03099    } else {
03100       if ((pte->device->extension == EXTENSION_ASK) ||
03101          (pte->device->extension == EXTENSION_TN))
03102          send_text_status(pte, "Dial   Redial ForwardUnregis");
03103       else
03104          send_text_status(pte, "Dial   Redial Forward");
03105 
03106       send_text(TEXT_LINE1, TEXT_NORMAL, pte, pte->device->maintext1);
03107       if (pte->device->missed_call == 0)
03108          send_text(TEXT_LINE0, TEXT_NORMAL, pte, pte->device->maintext0);
03109       else {
03110          sprintf(tmpbuf, "%d unanswered call(s)", pte->device->missed_call);
03111          send_text(TEXT_LINE0, TEXT_NORMAL, pte, tmpbuf);
03112          Sendicon(TEXT_LINE0, FAV_ICON_CALL_CENTER + FAV_BLINK_SLOW, pte);
03113       }
03114    }
03115    if (ast_strlen_zero(pte->device->maintext2)) {
03116       strcpy(tmpbuf, "IP : ");
03117       strcat(tmpbuf, ast_inet_ntoa(pte->sin.sin_addr));
03118       send_text(TEXT_LINE2, TEXT_NORMAL, pte, tmpbuf);
03119    } else
03120       send_text(TEXT_LINE2, TEXT_NORMAL, pte, pte->device->maintext2);
03121    send_texttitle(pte, pte->device->titledefault);
03122    change_favorite_icon(pte, FAV_ICON_ONHOOK_BLACK);
03123 }

static void ShowExtensionPage ( struct unistimsession pte  )  [static]

static void start_rtp ( struct unistim_subchannel sub  )  [static]

Definition at line 2032 of file chan_unistim.c.

References ast_best_codec(), AST_FORMAT_ALAW, AST_FORMAT_G723_1, AST_FORMAT_G729A, AST_FORMAT_ULAW, ast_getformatname(), ast_inet_ntoa(), ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_rtp_codecs_payload_code(), ast_rtp_instance_fd(), ast_rtp_instance_get_codecs(), ast_rtp_instance_get_local_address(), ast_rtp_instance_new(), ast_rtp_instance_set_prop(), ast_rtp_instance_set_qos(), ast_rtp_instance_set_remote_address(), AST_RTP_PROPERTY_NAT, AST_RTP_PROPERTY_RTCP, ast_verb, BUFFSEND, errno, ast_channel::fds, unistim_subchannel::lock, LOG_WARNING, unistim_device::nat, ast_channel::nativeformats, unistim_subchannel::owner, unistim_line::parent, unistim_subchannel::parent, qos, ast_channel::readformat, unistim_subchannel::rtp, unistim_device::rtp_method, unistim_device::rtp_port, send_client(), unistim_device::session, unistimsession::sin, SIZE_HEADER, unistimsession::sout, and ast_channel::writeformat.

02033 {
02034    BUFFSEND;
02035    struct sockaddr_in us = { 0, };
02036    struct sockaddr_in public = { 0, };
02037    struct sockaddr_in sin = { 0, };
02038    int codec;
02039    struct sockaddr_in sout = { 0, };
02040 
02041    /* Sanity checks */
02042    if (!sub) {
02043       ast_log(LOG_WARNING, "start_rtp with a null subchannel !\n");
02044       return;
02045    }
02046    if (!sub->parent) {
02047       ast_log(LOG_WARNING, "start_rtp with a null line !\n");
02048       return;
02049    }
02050    if (!sub->parent->parent) {
02051       ast_log(LOG_WARNING, "start_rtp with a null device !\n");
02052       return;
02053    }
02054    if (!sub->parent->parent->session) {
02055       ast_log(LOG_WARNING, "start_rtp with a null session !\n");
02056       return;
02057    }
02058    sout = sub->parent->parent->session->sout;
02059 
02060    ast_mutex_lock(&sub->lock);
02061    /* Allocate the RTP */
02062    if (unistimdebug)
02063       ast_verb(0, "Starting RTP. Bind on %s\n", ast_inet_ntoa(sout.sin_addr));
02064    sub->rtp = ast_rtp_instance_new("asterisk", sched, &sout, NULL);
02065    if (!sub->rtp) {
02066       ast_log(LOG_WARNING, "Unable to create RTP session: %s binaddr=%s\n",
02067             strerror(errno), ast_inet_ntoa(sout.sin_addr));
02068       ast_mutex_unlock(&sub->lock);
02069       return;
02070    }
02071    ast_rtp_instance_set_prop(sub->rtp, AST_RTP_PROPERTY_RTCP, 1);
02072    if (sub->owner) {
02073       sub->owner->fds[0] = ast_rtp_instance_fd(sub->rtp, 0);
02074       sub->owner->fds[1] = ast_rtp_instance_fd(sub->rtp, 1);
02075    }
02076    ast_rtp_instance_set_qos(sub->rtp, qos.tos_audio, qos.cos_audio, "UNISTIM RTP");
02077    ast_rtp_instance_set_prop(sub->rtp, AST_RTP_PROPERTY_NAT, sub->parent->parent->nat);
02078 
02079    /* Create the RTP connection */
02080    ast_rtp_instance_get_local_address(sub->rtp, &us);
02081    sin.sin_family = AF_INET;
02082    /* Setting up RTP for our side */
02083    memcpy(&sin.sin_addr, &sub->parent->parent->session->sin.sin_addr,
02084          sizeof(sin.sin_addr));
02085    sin.sin_port = htons(sub->parent->parent->rtp_port);
02086    ast_rtp_instance_set_remote_address(sub->rtp, &sin);
02087    if (!(sub->owner->nativeformats & sub->owner->readformat)) {
02088       int fmt;
02089       fmt = ast_best_codec(sub->owner->nativeformats);
02090       ast_log(LOG_WARNING,
02091             "Our read/writeformat has been changed to something incompatible : %s (%d), using %s (%d) best codec from %d\n",
02092             ast_getformatname(sub->owner->readformat),
02093             sub->owner->readformat, ast_getformatname(fmt), fmt,
02094             sub->owner->nativeformats);
02095       sub->owner->readformat = fmt;
02096       sub->owner->writeformat = fmt;
02097    }
02098    codec = ast_rtp_codecs_payload_code(ast_rtp_instance_get_codecs(sub->rtp), 1, sub->owner->readformat);
02099    /* Setting up RTP of the phone */
02100    if (public_ip.sin_family == 0)  /* NAT IP override ?   */
02101       memcpy(&public, &us, sizeof(public));   /* No defined, using IP from recvmsg  */
02102    else
02103       memcpy(&public, &public_ip, sizeof(public));    /* override  */
02104    if (unistimdebug) {
02105       ast_verb(0, "RTP started : Our IP/port is : %s:%hd with codec %s (%d)\n",
02106           ast_inet_ntoa(us.sin_addr),
02107           htons(us.sin_port), ast_getformatname(sub->owner->readformat),
02108           sub->owner->readformat);
02109       ast_verb(0, "Starting phone RTP stack. Our public IP is %s\n",
02110                ast_inet_ntoa(public.sin_addr));
02111    }
02112    if ((sub->owner->readformat == AST_FORMAT_ULAW) ||
02113       (sub->owner->readformat == AST_FORMAT_ALAW)) {
02114       if (unistimdebug)
02115          ast_verb(0, "Sending packet_send_rtp_packet_size for codec %d\n", codec);
02116       memcpy(buffsend + SIZE_HEADER, packet_send_rtp_packet_size,
02117             sizeof(packet_send_rtp_packet_size));
02118       buffsend[10] = codec;
02119       send_client(SIZE_HEADER + sizeof(packet_send_rtp_packet_size), buffsend,
02120                sub->parent->parent->session);
02121    }
02122    if (unistimdebug)
02123       ast_verb(0, "Sending Jitter Buffer Parameters Configuration\n");
02124    memcpy(buffsend + SIZE_HEADER, packet_send_jitter_buffer_conf,
02125          sizeof(packet_send_jitter_buffer_conf));
02126    send_client(SIZE_HEADER + sizeof(packet_send_jitter_buffer_conf), buffsend,
02127             sub->parent->parent->session);
02128    if (sub->parent->parent->rtp_method != 0) {
02129       uint16_t rtcpsin_port = htons(us.sin_port) + 1; /* RTCP port is RTP + 1 */
02130 
02131       if (unistimdebug)
02132          ast_verb(0, "Sending OpenAudioStreamTX using method #%d\n",
02133                   sub->parent->parent->rtp_method);
02134       if (sub->parent->parent->rtp_method == 3)
02135          memcpy(buffsend + SIZE_HEADER, packet_send_open_audio_stream_tx3,
02136                sizeof(packet_send_open_audio_stream_tx3));
02137       else
02138          memcpy(buffsend + SIZE_HEADER, packet_send_open_audio_stream_tx,
02139                sizeof(packet_send_open_audio_stream_tx));
02140       if (sub->parent->parent->rtp_method != 2) {
02141          memcpy(buffsend + 28, &public.sin_addr, sizeof(public.sin_addr));
02142          buffsend[20] = (htons(sin.sin_port) & 0xff00) >> 8;
02143          buffsend[21] = (htons(sin.sin_port) & 0x00ff);
02144          buffsend[23] = (rtcpsin_port & 0x00ff);
02145          buffsend[22] = (rtcpsin_port & 0xff00) >> 8;
02146          buffsend[25] = (us.sin_port & 0xff00) >> 8;
02147          buffsend[24] = (us.sin_port & 0x00ff);
02148          buffsend[27] = (rtcpsin_port & 0x00ff);
02149          buffsend[26] = (rtcpsin_port & 0xff00) >> 8;
02150       } else {
02151          memcpy(buffsend + 23, &public.sin_addr, sizeof(public.sin_addr));
02152          buffsend[15] = (htons(sin.sin_port) & 0xff00) >> 8;
02153          buffsend[16] = (htons(sin.sin_port) & 0x00ff);
02154          buffsend[20] = (us.sin_port & 0xff00) >> 8;
02155          buffsend[19] = (us.sin_port & 0x00ff);
02156          buffsend[11] = codec;
02157       }
02158       buffsend[12] = codec;
02159       send_client(SIZE_HEADER + sizeof(packet_send_open_audio_stream_tx), buffsend,
02160                sub->parent->parent->session);
02161 
02162       if (unistimdebug)
02163          ast_verb(0, "Sending OpenAudioStreamRX\n");
02164       if (sub->parent->parent->rtp_method == 3)
02165          memcpy(buffsend + SIZE_HEADER, packet_send_open_audio_stream_rx3,
02166                sizeof(packet_send_open_audio_stream_rx3));
02167       else
02168          memcpy(buffsend + SIZE_HEADER, packet_send_open_audio_stream_rx,
02169                sizeof(packet_send_open_audio_stream_rx));
02170       if (sub->parent->parent->rtp_method != 2) {
02171          memcpy(buffsend + 28, &public.sin_addr, sizeof(public.sin_addr));
02172          buffsend[20] = (htons(sin.sin_port) & 0xff00) >> 8;
02173          buffsend[21] = (htons(sin.sin_port) & 0x00ff);
02174          buffsend[23] = (rtcpsin_port & 0x00ff);
02175          buffsend[22] = (rtcpsin_port & 0xff00) >> 8;
02176          buffsend[25] = (us.sin_port & 0xff00) >> 8;
02177          buffsend[24] = (us.sin_port & 0x00ff);
02178          buffsend[27] = (rtcpsin_port & 0x00ff);
02179          buffsend[26] = (rtcpsin_port & 0xff00) >> 8;
02180       } else {
02181          memcpy(buffsend + 23, &public.sin_addr, sizeof(public.sin_addr));
02182          buffsend[15] = (htons(sin.sin_port) & 0xff00) >> 8;
02183          buffsend[16] = (htons(sin.sin_port) & 0x00ff);
02184          buffsend[20] = (us.sin_port & 0xff00) >> 8;
02185          buffsend[19] = (us.sin_port & 0x00ff);
02186          buffsend[12] = codec;
02187       }
02188       buffsend[11] = codec;
02189       send_client(SIZE_HEADER + sizeof(packet_send_open_audio_stream_rx), buffsend,
02190                sub->parent->parent->session);
02191    } else {
02192       uint16_t rtcpsin_port = htons(us.sin_port) + 1; /* RTCP port is RTP + 1 */
02193 
02194       if (unistimdebug)
02195          ast_verb(0, "Sending packet_send_call default method\n");
02196 
02197       memcpy(buffsend + SIZE_HEADER, packet_send_call, sizeof(packet_send_call));
02198       memcpy(buffsend + 53, &public.sin_addr, sizeof(public.sin_addr));
02199       /* Destination port when sending RTP */
02200       buffsend[49] = (us.sin_port & 0x00ff);
02201       buffsend[50] = (us.sin_port & 0xff00) >> 8;
02202       /* Destination port when sending RTCP */
02203       buffsend[52] = (rtcpsin_port & 0x00ff);
02204       buffsend[51] = (rtcpsin_port & 0xff00) >> 8;
02205       /* Codec */
02206       buffsend[40] = codec;
02207       buffsend[41] = codec;
02208       if (sub->owner->readformat == AST_FORMAT_ULAW)
02209          buffsend[42] = 1;       /* 1 = 20ms (160 bytes), 2 = 40ms (320 bytes) */
02210       else if (sub->owner->readformat == AST_FORMAT_ALAW)
02211          buffsend[42] = 1;       /* 1 = 20ms (160 bytes), 2 = 40ms (320 bytes) */
02212       else if (sub->owner->readformat == AST_FORMAT_G723_1)
02213          buffsend[42] = 2;       /* 1 = 30ms (24 bytes), 2 = 60 ms (48 bytes) */
02214       else if (sub->owner->readformat == AST_FORMAT_G729A)
02215          buffsend[42] = 2;       /* 1 = 10ms (10 bytes), 2 = 20ms (20 bytes) */
02216       else
02217          ast_log(LOG_WARNING, "Unsupported codec %s (%d) !\n",
02218                ast_getformatname(sub->owner->readformat), sub->owner->readformat);
02219       /* Source port for transmit RTP and Destination port for receiving RTP */
02220       buffsend[45] = (htons(sin.sin_port) & 0xff00) >> 8;
02221       buffsend[46] = (htons(sin.sin_port) & 0x00ff);
02222       buffsend[47] = (rtcpsin_port & 0xff00) >> 8;
02223       buffsend[48] = (rtcpsin_port & 0x00ff);
02224       send_client(SIZE_HEADER + sizeof(packet_send_call), buffsend,
02225                sub->parent->parent->session);
02226    }
02227    ast_mutex_unlock(&sub->lock);
02228 }

static void swap_subs ( struct unistim_line p,
int  a,
int  b 
) [static]

Definition at line 1859 of file chan_unistim.c.

References ast_log(), ast_verb, ast_channel::fds, LOG_WARNING, unistim_subchannel::owner, unistim_subchannel::rtp, and unistim_line::subs.

01860 {
01861 /*  struct ast_channel *towner; */
01862    struct ast_rtp_instance *rtp;
01863    int fds;
01864 
01865    if (unistimdebug)
01866       ast_verb(0, "Swapping %d and %d\n", a, b);
01867 
01868    if ((!p->subs[a]->owner) || (!p->subs[b]->owner)) {
01869       ast_log(LOG_WARNING,
01870             "Attempted to swap subchannels with a null owner : sub #%d=%p sub #%d=%p\n",
01871             a, p->subs[a]->owner, b, p->subs[b]->owner);
01872       return;
01873    }
01874    rtp = p->subs[a]->rtp;
01875    p->subs[a]->rtp = p->subs[b]->rtp;
01876    p->subs[b]->rtp = rtp;
01877 
01878    fds = p->subs[a]->owner->fds[0];
01879    p->subs[a]->owner->fds[0] = p->subs[b]->owner->fds[0];
01880    p->subs[b]->owner->fds[0] = fds;
01881 
01882    fds = p->subs[a]->owner->fds[1];
01883    p->subs[a]->owner->fds[1] = p->subs[b]->owner->fds[1];
01884    p->subs[b]->owner->fds[1] = fds;
01885 }

static void TransferCallStep1 ( struct unistimsession pte  )  [static]

Definition at line 2308 of file chan_unistim.c.

References ast_bridged_channel(), AST_CAUSE_NORMAL_CLEARING, ast_channel_start_silence_generator(), ast_log(), ast_moh_start(), ast_queue_hangup_with_cause(), ast_verb, unistimsession::device, handle_dial_page(), unistim_device::lines, LOG_WARNING, unistim_device::moh, unistim_line::musicclass, unistim_subchannel::owner, unistim_device::silence_generator, SUB_REAL, SUB_THREEWAY, and unistim_line::subs.

Referenced by key_call().

02309 {
02310    struct unistim_subchannel *sub;
02311    struct unistim_line *p = pte->device->lines;
02312 
02313    sub = p->subs[SUB_REAL];
02314 
02315    if (!sub->owner) {
02316       ast_log(LOG_WARNING, "Unable to find subchannel for music on hold\n");
02317       return;
02318    }
02319    if (p->subs[SUB_THREEWAY]) {
02320       if (unistimdebug)
02321          ast_verb(0, "Transfer canceled, hangup our threeway channel\n");
02322       if (p->subs[SUB_THREEWAY]->owner)
02323          ast_queue_hangup_with_cause(p->subs[SUB_THREEWAY]->owner, AST_CAUSE_NORMAL_CLEARING);
02324       else
02325          ast_log(LOG_WARNING, "Canceling a threeway channel without owner\n");
02326       return;
02327    }
02328    /* Start music on hold if appropriate */
02329    if (pte->device->moh)
02330       ast_log(LOG_WARNING, "Transfer with peer already listening music on hold\n");
02331    else {
02332       if (ast_bridged_channel(p->subs[SUB_REAL]->owner)) {
02333          ast_moh_start(ast_bridged_channel(p->subs[SUB_REAL]->owner),
02334                     pte->device->lines->musicclass, NULL);
02335          pte->device->moh = 1;
02336       } else {
02337          ast_log(LOG_WARNING, "Unable to find peer subchannel for music on hold\n");
02338          return;
02339       }
02340    }
02341    /* Silence our channel */
02342    if (!pte->device->silence_generator) {
02343       pte->device->silence_generator =
02344          ast_channel_start_silence_generator(p->subs[SUB_REAL]->owner);
02345       if (pte->device->silence_generator == NULL)
02346          ast_log(LOG_WARNING, "Unable to start a silence generator.\n");
02347       else if (unistimdebug)
02348          ast_verb(0, "Starting silence generator\n");
02349    }
02350    handle_dial_page(pte);
02351 }

static int unalloc_sub ( struct unistim_line p,
int  x 
) [static]

Definition at line 1498 of file chan_unistim.c.

References ast_debug, ast_free, ast_log(), ast_mutex_destroy(), unistim_line::lock, LOG_WARNING, unistim_device::name, unistim_line::name, unistim_line::parent, and unistim_line::subs.

01499 {
01500    if (!x) {
01501       ast_log(LOG_WARNING, "Trying to unalloc the real channel %s@%s?!?\n", p->name,
01502             p->parent->name);
01503       return -1;
01504    }
01505    if (unistimdebug)
01506       ast_debug(1, "Released sub %d of channel %s@%s\n", x, p->name,
01507             p->parent->name);
01508    ast_mutex_destroy(&p->lock);
01509    ast_free(p->subs[x]);
01510    p->subs[x] = 0;
01511    return 0;
01512 }

static int unistim_answer ( struct ast_channel ast  )  [static]

Definition at line 3818 of file chan_unistim.c.

References ast_channel::_state, ast_log(), ast_setstate(), AST_STATE_UP, ast_verb, channel_to_session(), LOG_WARNING, unistim_device::name, unistim_line::name, ast_channel::name, unistim_line::parent, unistim_subchannel::parent, unistim_subchannel::rtp, s, send_start_timer(), send_text(), send_text_status(), unistim_device::session, start_rtp(), SUB_THREEWAY, unistim_line::subs, unistim_subchannel::subtype, ast_channel::tech_pvt, TEXT_LINE2, and TEXT_NORMAL.

03819 {
03820    int res = 0;
03821    struct unistim_subchannel *sub;
03822    struct unistim_line *l;
03823    struct unistimsession *s;
03824 
03825    s = channel_to_session(ast);
03826    if (!s) {
03827       ast_log(LOG_WARNING, "unistim_answer on a disconnected device ?\n");
03828       return -1;
03829    }
03830    sub = ast->tech_pvt;
03831    l = sub->parent;
03832 
03833    if ((!sub->rtp) && (!l->subs[SUB_THREEWAY]))
03834       start_rtp(sub);
03835    if (unistimdebug)
03836       ast_verb(0, "unistim_answer(%s) on %s@%s-%d\n", ast->name, l->name,
03837                l->parent->name, sub->subtype);
03838    send_text(TEXT_LINE2, TEXT_NORMAL, l->parent->session, "is now on-line");
03839    if (l->subs[SUB_THREEWAY])
03840       send_text_status(l->parent->session, "Transf Cancel");
03841    else
03842       send_text_status(l->parent->session, "Hangup Transf");
03843    send_start_timer(l->parent->session);
03844    if (ast->_state != AST_STATE_UP)
03845       ast_setstate(ast, AST_STATE_UP);
03846    return res;
03847 }

static int unistim_call ( struct ast_channel ast,
char *  dest,
int  timeout 
) [static]

Definition at line 3652 of file chan_unistim.c.

References ast_channel::_state, AST_CONTROL_RINGING, ast_log(), ast_queue_control(), ast_setstate(), AST_STATE_DOWN, AST_STATE_RESERVED, AST_STATE_RINGING, ast_verb, change_callerid(), change_favorite_icon(), channel_to_session(), ast_channel::connected, DEFAULTCALLERID, DEFAULTCALLERNAME, unistimsession::device, FAV_BLINK_FAST, FAV_ICON_NONE, FAV_ICON_SPEAKER_ONHOOK_BLACK, ast_party_connected_line::id, LOG_ERROR, LOG_WARNING, ast_party_id::name, ast_channel::name, ast_party_id::number, unistim_subchannel::owner, unistim_device::ringstyle, unistim_subchannel::ringstyle, unistim_subchannel::ringvolume, unistim_device::ringvolume, send_ring(), send_text(), send_text_status(), Sendicon(), unistimsession::state, STATE_RINGING, ast_channel::tech_pvt, TEXT_LINE0, TEXT_LINE1, TEXT_LINE2, and TEXT_NORMAL.

03653 {
03654    int res = 0;
03655    struct unistim_subchannel *sub;
03656    struct unistimsession *session;
03657 
03658    session = channel_to_session(ast);
03659    if (!session) {
03660       ast_log(LOG_ERROR, "Device not registered, cannot call %s\n", dest);
03661       return -1;
03662    }
03663 
03664    sub = ast->tech_pvt;
03665    if ((ast->_state != AST_STATE_DOWN) && (ast->_state != AST_STATE_RESERVED)) {
03666       ast_log(LOG_WARNING, "unistim_call called on %s, neither down nor reserved\n",
03667             ast->name);
03668       return -1;
03669    }
03670 
03671    if (unistimdebug)
03672       ast_verb(3, "unistim_call(%s)\n", ast->name);
03673 
03674    session->state = STATE_RINGING;
03675    Sendicon(TEXT_LINE0, FAV_ICON_NONE, session);
03676 
03677    if (sub->owner) {
03678       if (sub->owner->connected.id.number) {
03679          send_text(TEXT_LINE1, TEXT_NORMAL, session, sub->owner->connected.id.number);
03680          change_callerid(session, 0, sub->owner->connected.id.number);
03681       } else {
03682          send_text(TEXT_LINE1, TEXT_NORMAL, session, DEFAULTCALLERID);
03683          change_callerid(session, 0, DEFAULTCALLERID);
03684       }
03685       if (sub->owner->connected.id.name) {
03686          send_text(TEXT_LINE0, TEXT_NORMAL, session, sub->owner->connected.id.name);
03687          change_callerid(session, 1, sub->owner->connected.id.name);
03688       } else {
03689          send_text(TEXT_LINE0, TEXT_NORMAL, session, DEFAULTCALLERNAME);
03690          change_callerid(session, 1, DEFAULTCALLERNAME);
03691       }
03692    }
03693    send_text(TEXT_LINE2, TEXT_NORMAL, session, "is calling you.");
03694    send_text_status(session, "Accept          Ignore");
03695 
03696    if (sub->ringstyle == -1)
03697       send_ring(session, session->device->ringvolume, session->device->ringstyle);
03698    else {
03699       if (sub->ringvolume == -1)
03700          send_ring(session, session->device->ringvolume, sub->ringstyle);
03701       else
03702          send_ring(session, sub->ringvolume, sub->ringstyle);
03703    }
03704    change_favorite_icon(session, FAV_ICON_SPEAKER_ONHOOK_BLACK + FAV_BLINK_FAST);
03705 
03706    ast_setstate(ast, AST_STATE_RINGING);
03707    ast_queue_control(ast, AST_CONTROL_RINGING);
03708    return res;
03709 }

static char* unistim_do_debug ( struct ast_cli_entry e,
int  cmd,
struct ast_cli_args a 
) [static]

Definition at line 4804 of file chan_unistim.c.

References ast_cli_args::argc, ast_cli_entry::args, ast_cli_args::argv, ast_cli(), CLI_GENERATE, CLI_INIT, CLI_SHOWUSAGE, CLI_SUCCESS, ast_cli_entry::command, ast_cli_args::fd, and ast_cli_entry::usage.

04805 {
04806    switch (cmd) {
04807    case CLI_INIT:
04808       e->command = "unistim set debug {on|off}";
04809       e->usage =
04810          "Usage: unistim set debug\n" 
04811          "       Display debug messages.\n";
04812       return NULL;
04813 
04814    case CLI_GENERATE:
04815       return NULL;   /* no completion */
04816    }
04817 
04818    if (a->argc != e->args)
04819       return CLI_SHOWUSAGE;
04820 
04821    if (!strcasecmp(a->argv[3], "on")) {
04822       unistimdebug = 1;
04823       ast_cli(a->fd, "UNISTIM Debugging Enabled\n");
04824    } else if (!strcasecmp(a->argv[3], "off")) {
04825       unistimdebug = 0;
04826       ast_cli(a->fd, "UNISTIM Debugging Disabled\n");
04827    } else
04828       return CLI_SHOWUSAGE;
04829 
04830    return CLI_SUCCESS;
04831 }

static int unistim_do_senddigit ( struct unistimsession pte,
char  digit 
) [static]

Definition at line 2475 of file chan_unistim.c.

References unistim_subchannel::alreadygone, AST_FRAME_DTMF, ast_log(), ast_queue_frame(), ast_verb, unistimsession::device, ast_frame::frametype, unistim_device::lines, LOG_WARNING, unistim_subchannel::owner, send_tone(), SUB_REAL, and unistim_line::subs.

Referenced by key_call(), and unistim_senddigit_begin().

02476 {
02477    struct ast_frame f = { .frametype = AST_FRAME_DTMF, .subclass = digit, .src = "unistim" };
02478    struct unistim_subchannel *sub;
02479    sub = pte->device->lines->subs[SUB_REAL];
02480    if (!sub->owner || sub->alreadygone) {
02481       ast_log(LOG_WARNING, "Unable to find subchannel in dtmf senddigit\n");
02482       return -1;
02483    }
02484 
02485    /* Send DTMF indication _before_ playing sounds */
02486    ast_queue_frame(sub->owner, &f);
02487 
02488    if (unistimdebug)
02489       ast_verb(0, "Send Digit %c\n", digit);
02490    switch (digit) {
02491    case '0':
02492       send_tone(pte, 941, 1336);
02493       break;
02494    case '1':
02495       send_tone(pte, 697, 1209);
02496       break;
02497    case '2':
02498       send_tone(pte, 697, 1336);
02499       break;
02500    case '3':
02501       send_tone(pte, 697, 1477);
02502       break;
02503    case '4':
02504       send_tone(pte, 770, 1209);
02505       break;
02506    case '5':
02507       send_tone(pte, 770, 1336);
02508       break;
02509    case '6':
02510       send_tone(pte, 770, 1477);
02511       break;
02512    case '7':
02513       send_tone(pte, 852, 1209);
02514       break;
02515    case '8':
02516       send_tone(pte, 852, 1336);
02517       break;
02518    case '9':
02519       send_tone(pte, 852, 1477);
02520       break;
02521    case 'A':
02522       send_tone(pte, 697, 1633);
02523       break;
02524    case 'B':
02525       send_tone(pte, 770, 1633);
02526       break;
02527    case 'C':
02528       send_tone(pte, 852, 1633);
02529       break;
02530    case 'D':
02531       send_tone(pte, 941, 1633);
02532       break;
02533    case '*':
02534       send_tone(pte, 941, 1209);
02535       break;
02536    case '#':
02537       send_tone(pte, 941, 1477);
02538       break;
02539    default:
02540       send_tone(pte, 500, 2000);
02541    }
02542    usleep(150000);          /* XXX Less than perfect, blocking an important thread is not a good idea */
02543    send_tone(pte, 0, 0);
02544    return 0;
02545 }

static int unistim_fixup ( struct ast_channel oldchan,
struct ast_channel newchan 
) [static]

Definition at line 4004 of file chan_unistim.c.

References ast_debug, ast_log(), ast_mutex_lock(), ast_mutex_unlock(), unistim_subchannel::lock, LOG_WARNING, ast_channel::name, unistim_device::name, unistim_line::name, unistim_subchannel::owner, unistim_line::parent, unistim_subchannel::parent, unistim_subchannel::subtype, and ast_channel::tech_pvt.

04005 {
04006    struct unistim_subchannel *p = newchan->tech_pvt;
04007    struct unistim_line *l = p->parent;
04008 
04009    ast_mutex_lock(&p->lock);
04010 
04011    ast_debug(1, "New owner for channel USTM/%s@%s-%d is %s\n", l->name,
04012          l->parent->name, p->subtype, newchan->name);
04013 
04014    if (p->owner != oldchan) {
04015       ast_log(LOG_WARNING, "old channel wasn't %s (%p) but was %s (%p)\n",
04016             oldchan->name, oldchan, p->owner->name, p->owner);
04017       return -1;
04018    }
04019 
04020    p->owner = newchan;
04021 
04022    ast_mutex_unlock(&p->lock);
04023 
04024    return 0;
04025 
04026 }

static enum ast_rtp_glue_result unistim_get_rtp_peer ( struct ast_channel chan,
struct ast_rtp_instance **  instance 
) [static]

Definition at line 5530 of file chan_unistim.c.

References ao2_ref, AST_RTP_GLUE_RESULT_LOCAL, unistim_subchannel::rtp, and ast_channel::tech_pvt.

05531 {
05532    struct unistim_subchannel *sub = chan->tech_pvt;
05533 
05534    ao2_ref(sub->rtp, +1);
05535    *instance = sub->rtp;
05536 
05537    return AST_RTP_GLUE_RESULT_LOCAL;
05538 }

static int unistim_hangup ( struct ast_channel ast  )  [static]