Wed Mar 3 22:50:58 2010

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.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 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, 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_get_result unistim_get_rtp_peer (struct ast_channel *chan, struct ast_rtp **rtp)
static enum ast_rtp_get_result unistim_get_vrtp_peer (struct ast_channel *chan, struct ast_rtp **rtp)
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)
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, 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 int unistim_set_rtp_peer (struct ast_channel *chan, struct ast_rtp *rtp, struct ast_rtp *vrtp, struct ast_rtp *trtp, int codecs, int nat_active)
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 = "a9c98e5d177805051735cb5b0b16b0a0" , .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_RECURSIVE_MUTEX_INITIALIZER_NP )
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_RECURSIVE_MUTEX_INITIALIZER_NP )
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 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_RECURSIVE_MUTEX_INITIALIZER_NP )
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_RECURSIVE_MUTEX_INITIALIZER_NP )
static int unistim_reloading = 0
static struct ast_rtp_protocol unistim_rtp
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_RECURSIVE_MUTEX_INITIALIZER_NP )

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 2769 of file chan_unistim.c.

Referenced by key_select_codec().

#define SELECTCODEC_MSG   "Codec number : .."

Definition at line 2770 of file chan_unistim.c.

Referenced by HandleSelectCodec(), and key_select_codec().

#define SELECTCODEC_START_ENTRY_POS   15

Definition at line 2768 of file chan_unistim.c.

Referenced by HandleSelectCodec(), and key_select_codec().

#define SELECTEXTENSION_MAX_LENGTH   10

Definition at line 2846 of file chan_unistim.c.

Referenced by key_select_extension().

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

Definition at line 2847 of file chan_unistim.c.

Referenced by key_select_extension(), and ShowExtensionPage().

#define SELECTEXTENSION_START_ENTRY_POS   0

Definition at line 2845 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 5654 of file chan_unistim.c.

static void __unreg_module ( void   )  [static]

Definition at line 5654 of file chan_unistim.c.

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

Definition at line 1478 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.

Referenced by build_device(), HandleCallOutgoing(), and rcv_mac_addr().

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

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

Definition at line 1882 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.

Referenced by close_call().

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

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

Definition at line 4997 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_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(), linelabel, 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.

Referenced by reload_config().

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

static void cancel_dial ( struct unistimsession pte  )  [static]

Definition at line 1845 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().

01846 {
01847    send_no_ring(pte);
01848    pte->device->missed_call++;
01849    write_history(pte, 'i', 1);
01850    show_main_page(pte);
01851    return;
01852 }

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

Definition at line 1948 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().

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

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

Definition at line 1062 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().

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

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

Definition at line 3618 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().

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

static void check_send_queue ( struct unistimsession pte  )  [static]

Definition at line 917 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().

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

static void close_call ( struct unistimsession pte  )  [static]

Definition at line 1967 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().

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

static void close_client ( struct unistimsession s  )  [static]

Definition at line 1106 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().

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

static char* control2str ( int  ind  )  [static]

Definition at line 4024 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.

Referenced by unistim_indicate().

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

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

Definition at line 862 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().

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

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

Referenced by restart_monitor().

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

static void dummy ( char *  unused,
  ... 
) [static]
static struct unistim_subchannel* find_subchannel_by_name ( const char *  dest  )  [static, read]

Definition at line 4141 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().

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

static void finish_bookmark ( void   )  [static]

Definition at line 4972 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().

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

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 829 of file chan_unistim.c.

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

Referenced by create_client().

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

static void handle_dial_page ( struct unistimsession pte  )  [static]

Definition at line 2255 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().

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

static void HandleCallIncoming ( struct unistimsession s  )  [static]

Definition at line 2439 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().

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

static void HandleCallOutgoing ( struct unistimsession s  )  [static]

Definition at line 2350 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, 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().

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

static void HandleSelectCodec ( struct unistimsession pte  )  [static]

Definition at line 2771 of file chan_unistim.c.

References buf, 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().

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

static void IgnoreCall ( struct unistimsession pte  )  [static]

Definition at line 2000 of file chan_unistim.c.

References send_no_ring().

Referenced by key_ringing().

02001 {
02002    send_no_ring(pte);
02003    return;
02004 }

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

Definition at line 4059 of file chan_unistim.c.

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

Referenced by unistim_indicate().

04061 {
04062    const struct tone_zone_sound *ts = NULL;
04063 
04064    ts = ast_get_indication_tone(tz, indication);
04065 
04066    if (ts && ts->data[0])
04067       ast_playtones_start(ast, 0, ts->data, 1);
04068    else
04069       ast_log(LOG_WARNING, "Unable to get indication tone for %s\n", indication);
04070 }

static void init_phone_step2 ( struct unistimsession pte  )  [static]

Definition at line 3283 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().

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

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

Definition at line 2543 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().

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

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

Definition at line 2651 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().

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

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

Definition at line 3215 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().

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

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

Definition at line 3121 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().

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

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

Definition at line 2614 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().

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

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

Definition at line 2791 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().

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

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

Definition at line 2862 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().

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

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

Definition at line 2632 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().

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

int load_module ( void   )  [static]

XXX

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

Definition at line 5564 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_proto_register(), io_context_create(), io_context_destroy(), LOG_ERROR, reload_config(), restart_monitor(), sched_context_create(), sched_context_destroy(), and SIZE_PAGE.

05565 {
05566    int res;
05567 
05568    if (!(buff = ast_malloc(SIZE_PAGE)))
05569       goto buff_failed;
05570 
05571    io = io_context_create();
05572    if (!io) {
05573       ast_log(LOG_ERROR, "Failed to allocate IO context\n");
05574       goto io_failed;
05575    }
05576 
05577    sched = sched_context_create();
05578    if (!sched) {
05579       ast_log(LOG_ERROR, "Failed to allocate scheduler context\n");
05580       goto sched_failed;
05581    }
05582 
05583    res = reload_config();
05584    if (res)
05585       return AST_MODULE_LOAD_DECLINE;
05586 
05587    /* Make sure we can register our unistim channel type */
05588    if (ast_channel_register(&unistim_tech)) {
05589       ast_log(LOG_ERROR, "Unable to register channel type '%s'\n", channel_type);
05590       goto chanreg_failed;
05591    } 
05592 
05593    ast_rtp_proto_register(&unistim_rtp);
05594 
05595    ast_cli_register_multiple(unistim_cli, ARRAY_LEN(unistim_cli));
05596 
05597    restart_monitor();
05598 
05599    return AST_MODULE_LOAD_SUCCESS;
05600 
05601 chanreg_failed:
05602    /*! XXX \todo Leaking anything allocated by reload_config() ... */
05603    sched_context_destroy(sched);
05604    sched = NULL;
05605 sched_failed:
05606    io_context_destroy(io);
05607    io = NULL;
05608 io_failed:
05609    ast_free(buff);
05610    buff = NULL;
05611 buff_failed:
05612    return AST_MODULE_LOAD_FAILURE;
05613 }

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

Definition at line 3027 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().

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

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

Definition at line 4891 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().

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

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

Definition at line 3463 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().

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

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

Definition at line 3344 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().

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

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

Definition at line 1509 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().

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

static void rcv_resume_connection_with_server ( struct unistimsession pte  )  [static]

Definition at line 1438 of file chan_unistim.c.

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

Referenced by process_request().

01439 {
01440    BUFFSEND;
01441    if (unistimdebug) {
01442       ast_verb(0, "ResumeConnectionWithServer received\n");
01443       ast_verb(0, "Sending packet_send_query_mac_address\n");
01444    }
01445    memcpy(buffsend + SIZE_HEADER, packet_send_query_mac_address,
01446          sizeof(packet_send_query_mac_address));
01447    send_client(SIZE_HEADER + sizeof(packet_send_query_mac_address), buffsend, pte);
01448    return;
01449 }

static int ReformatNumber ( char *  number  )  [static]

Definition at line 2960 of file chan_unistim.c.

Referenced by key_history(), and show_entry_history().

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

static void refresh_all_favorite ( struct unistimsession pte  )  [static]

Definition at line 1042 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().

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

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

Definition at line 1085 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().

01086 {
01087    if (unistimdebug)
01088       ast_verb(0, "Trying to register extension '%s' into context '%s' to %s\n",
01089                pte->device->extension_number, pte->device->lines->context,
01090                pte->device->lines->fullname);
01091    return ast_add_extension(pte->device->lines->context, 0,
01092                       pte->device->extension_number, 1, NULL, NULL, "Dial",
01093                       pte->device->lines->fullname, 0, "Unistim");
01094 }

static int reload ( void   )  [static]

reload: Part of Asterisk module interface ---

Definition at line 5644 of file chan_unistim.c.

References unistim_reload().

05645 {
05646    unistim_reload(NULL, 0, NULL);
05647    return 0;
05648 }

static int reload_config ( void   )  [static]

Definition at line 5286 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_variable_browse(), ast_verb, AUTOPROVISIONING_DB, AUTOPROVISIONING_NO, AUTOPROVISIONING_TN, AUTOPROVISIONING_YES, build_device(), config, 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, and ast_variable::value.

Referenced by do_monitor(), and load_module().

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

static int restart_monitor ( void   )  [static]

Definition at line 4584 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.

Referenced by load_module(), unistim_reload(), and unistim_request().

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

static void send_blink_cursor ( struct unistimsession pte  )  [static]

Definition at line 1415 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().

01416 {
01417    BUFFSEND;
01418    if (unistimdebug)
01419       ast_verb(0, "Sending set blink\n");
01420    memcpy(buffsend + SIZE_HEADER, packet_send_blink_cursor, sizeof(packet_send_blink_cursor));
01421    send_client(SIZE_HEADER + sizeof(packet_send_blink_cursor), buffsend, pte);
01422    return;
01423 }

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

Definition at line 788 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().

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

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

Definition at line 1426 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().

01427 {
01428    BUFFSEND;
01429    if (unistimdebug)
01430       ast_verb(0, "Sending set cursor position\n");
01431    memcpy(buffsend + SIZE_HEADER, packet_send_set_pos_cursor,
01432          sizeof(packet_send_set_pos_cursor));
01433    buffsend[11] = pos;
01434    send_client(SIZE_HEADER + sizeof(packet_send_set_pos_cursor), buffsend, pte);
01435    return;
01436 }

static void send_date_time ( struct unistimsession pte  )  [static]

Definition at line 1360 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().

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

static void send_date_time2 ( struct unistimsession pte  )  [static]

Definition at line 1377 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().

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

static void send_date_time3 ( struct unistimsession pte  )  [static]

Definition at line 1398 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().

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

static void send_end_call ( struct unistimsession pte  )  [static]

Definition at line 897 of file chan_unistim.c.

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

Referenced by unistim_hangup().

00898 {
00899    BUFFSEND;
00900    if (unistimdebug)
00901       ast_verb(0, "Sending end call\n");
00902    memcpy(buffsend + SIZE_HEADER, packet_send_end_call, sizeof(packet_send_end_call));
00903    send_client(SIZE_HEADER + sizeof(packet_send_end_call), buffsend, pte);
00904 }

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

Definition at line 1023 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().

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

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

Definition at line 1251 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().

01252 {
01253    BUFFSEND;
01254    if (unistimdebug)
01255       ast_verb(0, "Sending led_update (%x)\n", led);
01256    memcpy(buffsend + SIZE_HEADER, packet_send_led_update, sizeof(packet_send_led_update));
01257    buffsend[9] = led;
01258    send_client(SIZE_HEADER + sizeof(packet_send_led_update), buffsend, pte);
01259 }

static void send_no_ring ( struct unistimsession pte  )  [static]

Definition at line 1336 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().

01337 {
01338    BUFFSEND;
01339    if (unistimdebug)
01340       ast_verb(0, "Sending no ring packet\n");
01341    memcpy(buffsend + SIZE_HEADER, packet_send_no_ring, sizeof(packet_send_no_ring));
01342    send_client(SIZE_HEADER + sizeof(packet_send_no_ring), buffsend, pte);
01343 }

static void send_ping ( struct unistimsession pte  )  [static]

Definition at line 819 of file chan_unistim.c.

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

Referenced by do_monitor(), and init_phone_step2().

00820 {
00821    BUFFSEND;
00822    if (unistimdebug)
00823       ast_verb(6, "Sending ping\n");
00824    pte->tick_next_ping = get_tick_count() + unistim_keepalive;
00825    memcpy(buffsend + SIZE_HEADER, packet_send_ping, sizeof(packet_send_ping));
00826    send_client(SIZE_HEADER + sizeof(packet_send_ping), buffsend, pte);
00827 }

static void send_raw_client ( int  size,
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    msg_iov.iov_base = data;
00747    msg_iov.iov_len = size;
00748 
00749    msg.msg_name = addr_to;  /* optional address */
00750    msg.msg_namelen = sizeof(struct sockaddr_in);   /* size of address */
00751    msg.msg_iov = &msg_iov;  /* scatter/gather array */
00752    msg.msg_iovlen = 1;          /* # elements in msg_iov */
00753    msg.msg_control = ip_msg;       /* ancillary data */
00754    msg.msg_controllen = sizeof(buffer);    /* ancillary data buffer len */
00755    msg.msg_flags = 0;            /* flags on received message */
00756 
00757    ip_msg->cmsg_len = CMSG_LEN(sizeof(*pki));
00758    ip_msg->cmsg_level = IPPROTO_IP;
00759    ip_msg->cmsg_type = IP_PKTINFO;
00760    pki->ipi_ifindex = 0;      /* Interface index, 0 = use interface specified in routing table */
00761    pki->ipi_spec_dst.s_addr = addr_ourip->sin_addr.s_addr; /* Local address */
00762    /* pki->ipi_addr = ;   Header Destination address - ignored by kernel */
00763 
00764 #ifdef DUMP_PACKET
00765    if (unistimdebug) {
00766       int tmp;
00767       char iabuf[INET_ADDRSTRLEN];
00768       char iabuf2[INET_ADDRSTRLEN];
00769       ast_verb(0, "\n**> From %s sending %d bytes to %s ***\n",
00770                ast_inet_ntoa(addr_ourip->sin_addr), (int) size,
00771                ast_inet_ntoa(addr_to->sin_addr));
00772       for (tmp = 0; tmp < size; tmp++)
00773          ast_verb(0, "%.2x ", (unsigned char) data[tmp]);
00774       ast_verb(0, "\n******************************************\n");
00775 
00776    }
00777 #endif
00778 
00779    if (sendmsg(unistimsock, &msg, 0) == -1)
00780       display_last_error("Error sending datas");
00781 #else
00782    if (sendto(unistimsock, data, size, 0, (struct sockaddr *) addr_to, sizeof(*addr_to))
00783       == -1)
00784       display_last_error("Error sending datas");
00785 #endif
00786 }

static int send_retransmit ( struct unistimsession pte  )  [static]

Definition at line 1156 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().

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

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

Definition at line 1325 of file chan_unistim.c.

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

Referenced by unistim_call().

01326 {
01327    BUFFSEND;
01328    if (unistimdebug)
01329       ast_verb(0, "Sending ring packet\n");
01330    memcpy(buffsend + SIZE_HEADER, packet_send_ring, sizeof(packet_send_ring));
01331    buffsend[24] = style + 0x10;
01332    buffsend[29] = volume * 0x10;
01333    send_client(SIZE_HEADER + sizeof(packet_send_ring), buffsend, pte);
01334 }

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

Definition at line 1265 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().

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

static void send_start_timer ( struct unistimsession pte  )  [static]

Definition at line 940 of file chan_unistim.c.

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

Referenced by HandleCallIncoming(), and unistim_answer().

00941 {
00942    BUFFSEND;
00943    if (unistimdebug)
00944       ast_verb(0, "Sending start timer\n");
00945    memcpy(buffsend + SIZE_HEADER, packet_send_StartTimer, sizeof(packet_send_StartTimer));
00946    send_client(SIZE_HEADER + sizeof(packet_send_StartTimer), buffsend, pte);
00947 }

static void send_stop_timer ( struct unistimsession pte  )  [static]

Definition at line 949 of file chan_unistim.c.

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

Referenced by close_call().

00950 {
00951    BUFFSEND;
00952    if (unistimdebug)
00953       ast_verb(0, "Sending stop timer\n");
00954    memcpy(buffsend + SIZE_HEADER, packet_send_stop_timer, sizeof(packet_send_stop_timer));
00955    send_client(SIZE_HEADER + sizeof(packet_send_stop_timer), buffsend, pte);
00956 }

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

Definition at line 1196 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().

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

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

Definition at line 1213 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().

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

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

Definition at line 1345 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().

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

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

Definition at line 969 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().

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

static void SendDialTone ( struct unistimsession pte  )  [static]

Definition at line 2226 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().

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

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

Definition at line 958 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().

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

static void set_ping_timer ( struct unistimsession pte  )  [static]

Definition at line 906 of file chan_unistim.c.

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

Referenced by check_send_queue().

00907 {
00908    unsigned int tick = 0;  /* XXX what is this for, anyways */
00909 
00910    pte->timeout = pte->tick_next_ping;
00911    DEBUG_TIMER("tick = %u next ping at %u tick\n", tick, pte->timeout);
00912    return;
00913 }

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

Definition at line 2978 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().

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

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

Definition at line 3053 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().

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

static void show_main_page ( struct unistimsession pte  )  [static]

Definition at line 3072 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().

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

static void ShowExtensionPage ( struct unistimsession pte  )  [static]
static void start_rtp ( struct unistim_subchannel sub  )  [static]

Definition at line 2027 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_rtcp_fd(), ast_rtp_fd(), ast_rtp_get_us(), ast_rtp_lookup_code(), ast_rtp_new_with_bindaddr(), ast_rtp_set_peer(), ast_rtp_setnat(), ast_rtp_setqos(), 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.

Referenced by HandleCallIncoming(), HandleCallOutgoing(), and unistim_answer().

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

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

Definition at line 1854 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.

Referenced by HandleCallOutgoing(), and unistim_hangup().

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

static void TransferCallStep1 ( struct unistimsession pte  )  [static]

Definition at line 2304 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().

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

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

Definition at line 1493 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.

Referenced by unistim_hangup().

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

static int unistim_answer ( struct ast_channel ast  )  [static]

Definition at line 3814 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, 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.

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

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

Definition at line 3648 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::cid, ast_callerid::cid_name, ast_callerid::cid_num, DEFAULTCALLERID, DEFAULTCALLERNAME, unistimsession::device, FAV_BLINK_FAST, FAV_ICON_NONE, FAV_ICON_SPEAKER_ONHOOK_BLACK, LOG_ERROR, LOG_WARNING, 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.

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

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

Definition at line 4802 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.

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

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

Definition at line 2471 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().

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

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

Definition at line 4000 of file chan_unistim.c.

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

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

static enum ast_rtp_get_result unistim_get_rtp_peer ( struct ast_channel chan,
struct ast_rtp **  rtp 
) [static]

Definition at line 5522 of file chan_unistim.c.

References AST_RTP_GET_FAILED, AST_RTP_TRY_NATIVE, ast_verb, unistim_subchannel::rtp, and ast_channel::tech_pvt.

05524 {
05525    struct unistim_subchannel *sub;
05526    enum ast_rtp_get_result res = AST_RTP_GET_FAILED;
05527 
05528    if (unistimdebug)
05529       ast_verb(0, "unistim_get_rtp_peer called\n");
05530       
05531    sub = chan->tech_pvt;
05532    if (sub && sub->rtp) {
05533       *rtp = sub->rtp;
05534       res = AST_RTP_TRY_NATIVE;
05535    }
05536 
05537    return res;
05538 }

static enum ast_rtp_get_result unistim_get_vrtp_peer ( struct ast_channel chan,
struct ast_rtp **  rtp 
) [static]

Definition at line 5516 of file chan_unistim.c.

References AST_RTP_TRY_NATIVE.

05518 {
05519    return AST_RTP_TRY_NATIVE;
05520 }

static int unistim_hangup ( struct ast_channel ast  )  [static]

Definition at line 3708 of file chan_unistim.c.

References unistim_subchannel::alreadygone, ast_bridged_channel(), ast_channel_stop_silence_generator(), ast_debug, ast_log(), ast_moh_stop(), ast_mutex_lock(), ast_mutex_unlock(), ast_rtp_destroy(), ast_verb, cancel_dial(), channel_to_session(), close_call(), unistimsession::device, unistim_subchannel::lock, LOG_WARNING, unistim_device::moh, unistim_device::name, unistim_line::name, unistim_subchannel::owner, unistim_line::parent, unistim_subchannel::parent, unistim_subchannel::rtp, s, send_end_call(), send_no_ring(), send_text(), send_text_status(), unistim_device::silence_generator, unistimsession::state, STATE_CALL, STATE_RINGING, SUB_REAL, SUB_THREEWAY, unistim_line::subs, unistim_subchannel::subtype, swap_subs(), ast_channel::tech_pvt, TEXT_LINE0, TEXT_LINE1, TEXT_LINE2, TEXT_NORMAL, and unalloc_sub().

03709 {
03710    struct unistim_subchannel *sub;
03711    struct unistim_line *l;
03712    struct unistimsession *s;
03713 
03714    s = channel_to_session(ast);
03715    sub = ast->tech_pvt;
03716    if (!s) {
03717       ast_debug(1, "Asked to hangup channel not connected\n");
03718       ast_mutex_lock(&sub->lock);
03719       sub->owner = NULL;
03720       ast->tech_pvt = NULL;
03721       sub->alreadygone = 0;
03722       ast_mutex_unlock(&sub->lock);
03723       if (sub->rtp) {
03724          if (unistimdebug)
03725             ast_verb(0, "Destroying RTP session\n");
03726          ast_rtp_destroy(sub->rtp);
03727          sub->rtp = NULL;
03728       }
03729       return 0;
03730    }
03731    l = sub->parent;
03732    if (unistimdebug)
03733       ast_verb(0, "unistim_hangup(%s) on %s@%s\n", ast->name, l->name, l->parent->name);
03734 
03735    if ((l->subs[SUB_THREEWAY]) && (sub->subtype == SUB_REAL)) {
03736       if (unistimdebug)
03737          ast_verb(0, "Real call disconnected while talking to threeway\n");
03738       sub->owner = NULL;
03739       ast->tech_pvt = NULL;
03740       return 0;
03741    }
03742    if ((l->subs[SUB_REAL]->owner) && (sub->subtype == SUB_THREEWAY) &&
03743       (sub->alreadygone == 0)) {
03744       if (unistimdebug)
03745          ast_verb(0, "threeway call disconnected, switching to real call\n");
03746       send_text(TEXT_LINE0, TEXT_NORMAL, s, "Three way call canceled,");
03747       send_text(TEXT_LINE1, TEXT_NORMAL, s, "switching back to");
03748       send_text(TEXT_LINE2, TEXT_NORMAL, s, "previous call.");
03749       send_text_status(s, "Hangup Transf");
03750       ast_moh_stop(ast_bridged_channel(l->subs[SUB_REAL]->owner));
03751       swap_subs(l, SUB_THREEWAY, SUB_REAL);
03752       l->parent->moh = 0;
03753       ast_mutex_lock(&sub->lock);
03754       sub->owner = NULL;
03755       ast->tech_pvt = NULL;
03756       ast_mutex_unlock(&sub->lock);
03757       unalloc_sub(l, SUB_THREEWAY);
03758       return 0;
03759    }
03760    ast_mutex_lock(&sub->lock);
03761    sub->owner = NULL;
03762    ast->tech_pvt = NULL;
03763    sub->alreadygone = 0;
03764    ast_mutex_unlock(&sub->lock);
03765    if (!s) {
03766       if (unistimdebug)
03767          ast_verb(0, "Asked to hangup channel not connected (no session)\n");
03768       if (sub->rtp) {
03769          if (unistimdebug)
03770             ast_verb(0, "Destroying RTP session\n");
03771          ast_rtp_destroy(sub->rtp);
03772          sub->rtp = NULL;
03773       }
03774       return 0;
03775    }
03776    if (sub->subtype == SUB_REAL) {
03777       /* Stop the silence generator */
03778       if (s->device->silence_generator) {
03779          if (unistimdebug)
03780             ast_verb(0, "Stopping silence generator\n");
03781          if (sub->owner)
03782             ast_channel_stop_silence_generator(sub->owner,
03783                                        s->device->silence_generator);
03784          else
03785             ast_log(LOG_WARNING,
03786                   "Trying to stop silence generator on a null channel !\n");
03787          s->device->silence_generator = NULL;
03788       }
03789    }
03790    l->parent->moh = 0;
03791    send_no_ring(s);
03792    send_end_call(s);
03793    if (sub->rtp) {
03794       if (unistimdebug)
03795          ast_verb(0, "Destroying RTP session\n");
03796       ast_rtp_destroy(sub->rtp);
03797       sub->rtp = NULL;
03798    } else if (unistimdebug)
03799       ast_verb(0, "No RTP session to destroy\n");
03800    if (l->subs[SUB_THREEWAY]) {
03801       if (unistimdebug)
03802          ast_verb(0, "Cleaning other subchannels\n");
03803       unalloc_sub(l, SUB_THREEWAY);
03804    }
03805    if (s->state == STATE_RINGING)
03806       cancel_dial(s);
03807    else if (s->state == STATE_CALL)
03808       close_call(s);
03809 
03810    return 0;
03811 }

static int unistim_indicate ( struct ast_channel ast,
int  ind,
const void *  data,
size_t  datalen 
) [static]

Definition at line 4072 of file chan_unistim.c.

References ast_channel::_state, unistim_subchannel::alreadygone, AST_CONTROL_BUSY, AST_CONTROL_CONGESTION, AST_CONTROL_HOLD, AST_CONTROL_PROCEEDING, AST_CONTROL_PROGRESS, AST_CONTROL_RINGING, AST_CONTROL_SRCUPDATE, AST_CONTROL_UNHOLD, ast_log(), ast_moh_start(), ast_moh_stop(), ast_playtones_stop(), AST_STATE_UP, ast_verb, channel_to_session(), control2str(), unistimsession::device, in_band_indication(), LOG_WARNING, unistim_device::missed_call, unistim_line::parent, unistim_subchannel::parent, s, send_text(), ast_channel::tech_pvt, TEXT_LINE2, TEXT_NORMAL, and unistim_device::tz.

04074 {
04075    struct unistim_subchannel *sub;
04076    struct unistim_line *l;
04077    struct unistimsession *s;
04078 
04079    if (unistimdebug) {
04080       ast_verb(3, "Asked to indicate '%s' condition on channel %s\n",
04081                control2str(ind), ast->name);
04082    }
04083 
04084    s = channel_to_session(ast);
04085    if (!s)
04086       return -1;
04087 
04088    sub = ast->tech_pvt;
04089    l = sub->parent;
04090 
04091    switch (ind) {
04092    case AST_CONTROL_RINGING:
04093       if (ast->_state != AST_STATE_UP) {
04094          send_text(TEXT_LINE2, TEXT_NORMAL, s, "Ringing...");
04095          in_band_indication(ast, l->parent->tz, "ring");
04096          s->device->missed_call = -1;
04097          break;
04098       }
04099       return -1;
04100    case AST_CONTROL_BUSY:
04101       if (ast->_state != AST_STATE_UP) {
04102          sub->alreadygone = 1;
04103          send_text(TEXT_LINE2, TEXT_NORMAL, s, "Busy");
04104          in_band_indication(ast, l->parent->tz, "busy");
04105          s->device->missed_call = -1;
04106          break;
04107       }
04108       return -1;
04109    case AST_CONTROL_CONGESTION:
04110       if (ast->_state != AST_STATE_UP) {
04111          sub->alreadygone = 1;
04112          send_text(TEXT_LINE2, TEXT_NORMAL, s, "Congestion");
04113          in_band_indication(ast, l->parent->tz, "congestion");
04114          s->device->missed_call = -1;
04115          break;
04116       }
04117       return -1;
04118    case AST_CONTROL_HOLD:
04119       ast_moh_start(ast, data, NULL);
04120       break;
04121    case AST_CONTROL_UNHOLD:
04122       ast_moh_stop(ast);
04123       break;
04124    case AST_CONTROL_PROGRESS:
04125    case AST_CONTROL_SRCUPDATE:
04126       break;
04127    case -1:
04128       ast_playtones_stop(ast);
04129       s->device->missed_call = 0;
04130       break;
04131    case AST_CONTROL_PROCEEDING:
04132       break;
04133    default:
04134       ast_log(LOG_WARNING, "Don't know how to indicate condition %d\n", ind);
04135       return -1;
04136    }
04137 
04138    return 0;
04139 }

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

Definition at line 4672 of file chan_unistim.c.

References ast_channel::_bridge, unistim_subchannel::alreadygone, ast_cli_args::argc, ast_cli_entry::args, ast_cli(), ast_inet_ntoa(), ast_mutex_lock(), ast_mutex_unlock(), unistim_line::capability, unistim_line::cid_num, CLI_GENERATE, CLI_INIT, CLI_SHOWUSAGE, CLI_SUCCESS, ast_cli_entry::command, unistimsession::device, unistim_line::exten, ast_cli_args::fd, unistim_line::fullname, unistim_device::ha, unistim_device::id, unistim_device::lines, unistimsession::macaddr, MAX_SUBS, unistim_line::name, unistim_device::name, unistimsession::next, unistim_device::next, unistim_line::next, unistim_subchannel::owner, unistim_subchannel::parent, unistim_line::parent, unistim_subchannel::rtp, s, unistim_device::session, sessionlock, unistimsession::sin, unistimsession::state, unistim_line::subs, unistim_subchannel::subtype, unistimsession::timeout, and ast_cli_entry::usage.

04673 {
04674    struct unistim_device *device = devices;
04675    struct unistim_line *line;
04676    struct unistim_subchannel *sub;
04677    struct unistimsession *s;
04678    int i;
04679    struct ast_channel *tmp;
04680 
04681    switch (cmd) {
04682    case CLI_INIT:
04683       e->command = "unistim info";
04684       e->usage =
04685          "Usage: unistim info\n" 
04686          "       Dump internal structures.\n";
04687       return NULL;
04688 
04689    case CLI_GENERATE:
04690       return NULL;   /* no completion */
04691    }
04692 
04693    if (a->argc != e->args)
04694       return CLI_SHOWUSAGE;
04695 
04696    ast_cli(a->fd, "Dumping internal structures :\ndevice\n->line\n-->sub\n");
04697    while (device) {
04698       ast_cli(a->fd, "\nname=%s id=%s line=%p ha=%p sess=%p device=%p\n",
04699             device->name, device->id, device->lines, device->ha, device->session,
04700             device);
04701       line = device->lines;
04702       while (line) {
04703          ast_cli(a->fd,
04704                "->name=%s fullname=%s exten=%s callid=%s cap=%d device=%p line=%p\n",
04705                line->name, line->fullname, line->exten, line->cid_num,
04706                line->capability, line->parent, line);
04707          for (i = 0; i < MAX_SUBS; i++) {
04708             sub = line->subs[i];
04709             if (!sub)
04710                continue;
04711             if (!sub->owner)
04712                tmp = (void *) -42;
04713             else
04714                tmp = sub->owner->_bridge;
04715             if (sub->subtype != i)
04716                ast_cli(a->fd, "Warning ! subchannel->subs[%d] have a subtype=%d\n", i,
04717                      sub->subtype);
04718             ast_cli(a->fd,
04719                   "-->subtype=%d chan=%p rtp=%p bridge=%p line=%p alreadygone=%d\n",
04720                   sub->subtype, sub->owner, sub->rtp, tmp, sub->parent,
04721                   sub->alreadygone);
04722          }
04723          line = line->next;
04724       }
04725       device = device->next;
04726    }
04727    ast_cli(a->fd, "\nSessions:\n");
04728    ast_mutex_lock(&sessionlock);
04729    s = sessions;
04730    while (s) {
04731       ast_cli(a->fd,
04732             "sin=%s timeout=%u state=%d macaddr=%s device=%p session=%p\n",
04733             ast_inet_ntoa(s->sin.sin_addr), s->timeout, s->state, s->macaddr,
04734             s->device, s);
04735       s = s->next;
04736    }
04737    ast_mutex_unlock(&sessionlock);
04738 
04739    return CLI_SUCCESS;
04740 }

static struct ast_channel * unistim_new ( struct unistim_subchannel sub,
int  state 
) [static, read]

Protos

Definition at line 4421 of file chan_unistim.c.

References unistim_line::accountcode, ast_channel::adsicpe, unistim_line::amaflags, AST_ADSI_UNAVAILABLE, ast_best_codec(), ast_callerid_parse(), ast_channel_alloc, ast_free, ast_hangup(), ast_jb_configure(), ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_pbx_start(), ast_rtcp_fd(), ast_rtp_fd(), ast_setstate(), AST_STATE_DOWN, AST_STATE_RING, ast_strdup, ast_string_field_build, ast_string_field_set, ast_strlen_zero(), ast_update_use_count(), ast_verb, unistim_device::call_forward, unistim_line::callgroup, ast_channel::callgroup, CAPABILITY, unistim_line::capability, ast_channel::cid, ast_callerid::cid_name, ast_callerid::cid_num, unistim_line::cid_num, unistim_line::context, unistim_line::exten, ast_channel::fds, unistim_line::fullname, global_jbconf, language, unistim_line::language, LOG_WARNING, unistim_device::name, unistim_line::name, name, ast_channel::nativeformats, unistim_line::parent, unistim_subchannel::parent, unistim_line::pickupgroup, ast_channel::pickupgroup, ast_channel::priority, ast_channel::rawreadformat, ast_channel::rawwriteformat, ast_channel::readformat, ast_channel::rings, ast_channel::tech, ast_channel::tech_pvt, usecnt_lock, and ast_channel::writeformat.

Referenced by HandleCallOutgoing(), and unistim_request().

04422 {
04423    struct ast_channel *tmp;
04424    struct unistim_line *l;
04425    int fmt;
04426 
04427    if (!sub) {
04428       ast_log(LOG_WARNING, "subchannel null in unistim_new\n");
04429       return NULL;
04430    }
04431    if (!sub->parent) {
04432       ast_log(LOG_WARNING, "no line for subchannel %p\n", sub);
04433       return NULL;
04434    }
04435    l = sub->parent;
04436    tmp = ast_channel_alloc(1, state, l->cid_num, NULL, l->accountcode, l->exten, 
04437       l->context, l->amaflags, "%s-%08x", l->fullname, (int) (long) sub);
04438    if (unistimdebug)
04439       ast_verb(0, "unistim_new sub=%d (%p) chan=%p\n", sub->subtype, sub, tmp);
04440    if (!tmp) {
04441       ast_log(LOG_WARNING, "Unable to allocate channel structure\n");
04442       return NULL;
04443    }
04444 
04445    tmp->nativeformats = l->capability;
04446    if (!tmp->nativeformats)
04447       tmp->nativeformats = CAPABILITY;
04448    fmt = ast_best_codec(tmp->nativeformats);
04449    if (unistimdebug)
04450       ast_verb(0, "Best codec = %d from nativeformats %d (line cap=%d global=%d)\n", fmt,
04451           tmp->nativeformats, l->capability, CAPABILITY);
04452    ast_string_field_build(tmp, name, "USTM/%s@%s-%d", l->name, l->parent->name,
04453                      sub->subtype);
04454    if ((sub->rtp) && (sub->subtype == 0)) {
04455       if (unistimdebug)
04456          ast_verb(0, "New unistim channel with a previous rtp handle ?\n");
04457       tmp->fds[0] = ast_rtp_fd(sub->rtp);
04458       tmp->fds[1] = ast_rtcp_fd(sub->rtp);
04459    }
04460    if (sub->rtp)
04461       ast_jb_configure(tmp, &global_jbconf);
04462       
04463 /*      tmp->type = type; */
04464    ast_setstate(tmp, state);
04465    if (state == AST_STATE_RING)
04466       tmp->rings = 1;
04467    tmp->adsicpe = AST_ADSI_UNAVAILABLE;
04468    tmp->writeformat = fmt;
04469    tmp->rawwriteformat = fmt;
04470    tmp->readformat = fmt;
04471    tmp->rawreadformat = fmt;
04472    tmp->tech_pvt = sub;
04473    tmp->tech = &unistim_tech;
04474    if (!ast_strlen_zero(l->language))
04475       ast_string_field_set(tmp, language, l->language);
04476    sub->owner = tmp;
04477    ast_mutex_lock(&usecnt_lock);
04478    usecnt++;
04479    ast_mutex_unlock(&usecnt_lock);
04480    ast_update_use_count();
04481    tmp->callgroup = l->callgroup;
04482    tmp->pickupgroup = l->pickupgroup;
04483    ast_string_field_set(tmp, call_forward, l->parent->call_forward);
04484    if (!ast_strlen_zero(l->cid_num)) {
04485       char *name, *loc, *instr;
04486       instr = ast_strdup(l->cid_num);
04487       if (instr) {
04488          ast_callerid_parse(instr, &name, &loc);
04489          tmp->cid.cid_num = ast_strdup(loc);
04490          tmp->cid.cid_name = ast_strdup(name);
04491          ast_free(instr);
04492       }
04493    }
04494    tmp->priority = 1;
04495    if (state != AST_STATE_DOWN) {
04496       if (unistimdebug)
04497          ast_verb(0, "Starting pbx in unistim_new\n");
04498       if (ast_pbx_start(tmp)) {
04499          ast_log(LOG_WARNING, "Unable to start PBX on %s\n", tmp->name);
04500          ast_hangup(tmp);
04501          tmp = NULL;
04502       }
04503    }
04504 
04505    return tmp;
04506 }

static struct ast_frame * unistim_read ( struct ast_channel ast  )  [static, read]

Definition at line 3952 of file chan_unistim.c.

References ast_mutex_lock(), ast_mutex_unlock(), unistim_subchannel::lock, ast_channel::tech_pvt, and unistim_rtp_read().

03953 {
03954    struct ast_frame *fr;
03955    struct unistim_subchannel *sub = ast->tech_pvt;
03956 
03957    ast_mutex_lock(&sub->lock);
03958    fr = unistim_rtp_read(ast, sub);
03959    ast_mutex_unlock(&sub->lock);
03960 
03961    return fr;
03962 }

static int unistim_register ( struct unistimsession s  )  [static]

Definition at line 1451 of file chan_unistim.c.

References ast_mutex_lock(), ast_mutex_unlock(), unistim_device::codec_number, DEFAULT_CODEC, unistimsession::device, devicelock, unistim_device::id, unistimsession::macaddr, unistim_device::missed_call, unistim_device::next, unistim_device::pos_fav, unistim_device::receiver_state, unistim_device::session, and STATE_ONHOOK.

Referenced by rcv_mac_addr().

01452 {
01453    struct unistim_device *d;
01454 
01455    ast_mutex_lock(&devicelock);
01456    d = devices;
01457    while (d) {
01458       if (!strcasecmp(s->macaddr, d->id)) {
01459          /* XXX Deal with IP authentication */
01460          s->device = d;
01461          d->session = s;
01462          d->codec_number = DEFAULT_CODEC;
01463          d->pos_fav = 0;
01464          d->missed_call = 0;
01465          d->receiver_state = STATE_ONHOOK;
01466          break;
01467       }
01468       d = d->next;
01469    }
01470    ast_mutex_unlock(&devicelock);
01471 
01472    if (!d)
01473       return 0;
01474 
01475    return 1;
01476 }

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

--- 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

Definition at line 4835 of file chan_unistim.c.

References ast_cli_args::argc, ast_cli_entry::args, ast_mutex_lock(), ast_mutex_unlock(), ast_verb, CLI_GENERATE, CLI_INIT, CLI_SHOWUSAGE, CLI_SUCCESS, ast_cli_entry::command, restart_monitor(), unistim_reload_lock, and ast_cli_entry::usage.

Referenced by reload().

04836 {
04837    switch (cmd) {
04838    case CLI_INIT:
04839       e->command = "unistim reload";
04840       e->usage =
04841          "Usage: unistim reload\n" 
04842          "       Reloads UNISTIM configuration from unistim.conf\n";
04843       return NULL;
04844 
04845    case CLI_GENERATE:
04846       return NULL;   /* no completion */
04847    }
04848 
04849    if (e && a && a->argc != e->args)
04850       return CLI_SHOWUSAGE;
04851 
04852    if (unistimdebug)
04853       ast_verb(0, "reload unistim\n");
04854 
04855    ast_mutex_lock(&unistim_reload_lock);
04856    if (!unistim_reloading)
04857       unistim_reloading = 1;
04858    ast_mutex_unlock(&unistim_reload_lock);
04859 
04860    restart_monitor();
04861 
04862    return CLI_SUCCESS;
04863 }

static struct ast_channel * unistim_request ( const char *  type,
int  format,
void *  data,
int *  cause 
) [static, read]

Definition at line 4618 of file chan_unistim.c.

References AST_CAUSE_BUSY, AST_CAUSE_CONGESTION, ast_copy_string(), ast_getformatname(), ast_log(), AST_STATE_DOWN, ast_strlen_zero(), ast_verb, unistim_line::capability, CAPABILITY, find_subchannel_by_name(), LOG_NOTICE, LOG_WARNING, unistim_subchannel::owner, unistim_subchannel::parent, restart_monitor(), and unistim_new().

04620 {
04621    int oldformat;
04622    struct unistim_subchannel *sub;
04623    struct ast_channel *tmpc = NULL;
04624    char tmp[256];
04625    char *dest = data;
04626 
04627    oldformat = format;
04628    format &= CAPABILITY;
04629    ast_log(LOG_NOTICE,
04630          "Asked to get a channel of format %s while capability is %d result : %s (%d) \n",
04631          ast_getformatname(oldformat), CAPABILITY, ast_getformatname(format), format);
04632    if (!format) {
04633       ast_log(LOG_NOTICE,
04634             "Asked to get a channel of unsupported format %s while capability is %s\n",
04635             ast_getformatname(oldformat), ast_getformatname(CAPABILITY));
04636       return NULL;
04637    }
04638 
04639    ast_copy_string(tmp, dest, sizeof(tmp));
04640    if (ast_strlen_zero(tmp)) {
04641       ast_log(LOG_NOTICE, "Unistim channels require a device\n");
04642       return NULL;
04643    }
04644 
04645    sub = find_subchannel_by_name(tmp);
04646    if (!sub) {
04647       ast_log(LOG_NOTICE, "No available lines on: %s\n", dest);
04648       *cause = AST_CAUSE_CONGESTION;
04649       return NULL;
04650    }
04651 
04652    ast_verb(3, "unistim_request(%s)\n", tmp);
04653    /* Busy ? */
04654    if (sub->owner) {
04655       if (unistimdebug)
04656          ast_verb(0, "Can't create channel : Busy !\n");
04657       *cause = AST_CAUSE_BUSY;
04658       return NULL;
04659    }
04660    sub->parent->capability = format;
04661    tmpc = unistim_new(sub, AST_STATE_DOWN);
04662    if (!tmpc)
04663       ast_log(LOG_WARNING, "Unable to make channel for '%s'\n", tmp);
04664    if (unistimdebug)
04665       ast_verb(0, "unistim_request owner = %p\n", sub->owner);
04666    restart_monitor();
04667 
04668    /* and finish */
04669    return tmpc;
04670 }

static struct ast_frame* unistim_rtp_read ( const struct ast_channel ast,
const struct unistim_subchannel sub 
) [static, read]

Definition at line 3904 of file chan_unistim.c.

References ast_debug, AST_FRAME_VOICE, ast_getformatname(), ast_log(), ast_null_frame, ast_rtcp_read(), ast_rtp_read(), ast_set_read_format(), ast_set_write_format(), f, ast_channel::fdno, ast_frame::frametype, LOG_WARNING, ast_channel::nativeformats, unistim_subchannel::owner, ast_channel::readformat, unistim_subchannel::rtp, ast_frame::subclass, unistim_subchannel::subtype, and ast_channel::writeformat.

Referenced by unistim_read().

03906 {
03907    /* Retrieve audio/etc from channel.  Assumes sub->lock is already held. */
03908    struct ast_frame *f;
03909 
03910    if (!ast) {
03911       ast_log(LOG_WARNING, "Channel NULL while reading\n");
03912       return &ast_null_frame;
03913    }
03914 
03915    if (!sub->rtp) {
03916       ast_log(LOG_WARNING, "RTP handle NULL while reading on subchannel %d\n",
03917             sub->subtype);
03918       return &ast_null_frame;
03919    }
03920 
03921    switch (ast->fdno) {
03922    case 0:
03923       f = ast_rtp_read(sub->rtp);     /* RTP Audio */
03924       break;
03925    case 1:
03926       f = ast_rtcp_read(sub->rtp);    /* RTCP Control Channel */
03927       break;
03928    default:
03929       f = &ast_null_frame;
03930    }
03931 
03932    if (sub->owner) {
03933       /* We already hold the channel lock */
03934       if (f->frametype == AST_FRAME_VOICE) {
03935          if (f->subclass != sub->owner->nativeformats) {
03936             ast_debug(1,
03937                   "Oooh, format changed from %s (%d) to %s (%d)\n",
03938                   ast_getformatname(sub->owner->nativeformats),
03939                   sub->owner->nativeformats, ast_getformatname(f->subclass),
03940                   f->subclass);
03941 
03942             sub->owner->nativeformats = f->subclass;
03943             ast_set_read_format(sub->owner, sub->owner->readformat);
03944             ast_set_write_format(sub->owner, sub->owner->writeformat);
03945          }
03946       }
03947    }
03948 
03949    return f;
03950 }

static int unistim_send_mwi_to_peer ( struct unistimsession s,
unsigned int  tick 
) [static]

Definition at line 4378 of file chan_unistim.c.

References ast_app_has_voicemail(), ast_event_destroy(), ast_event_get_cached(), ast_event_get_ie_uint(), AST_EVENT_IE_CONTEXT, AST_EVENT_IE_END, AST_EVENT_IE_MAILBOX, AST_EVENT_IE_NEWMSGS, AST_EVENT_IE_PLTYPE_STR, AST_EVENT_MWI, ast_strdupa, ast_strlen_zero(), context, unistimsession::device, unistim_line::lastmsgssent, unistim_device::lines, unistim_line::mailbox, mailbox, unistim_line::nextmsgcheck, send_led_update(), strsep(), and TIMER_MWI.

Referenced by do_monitor().

04379 {
04380    struct ast_event *event;
04381    int new;
04382    char *mailbox, *context;
04383    struct unistim_line *peer = s->device->lines;
04384 
04385    context = mailbox = ast_strdupa(peer->mailbox);
04386    strsep(&context, "@");
04387    if (ast_strlen_zero(context))
04388       context = "default";
04389 
04390    event = ast_event_get_cached(AST_EVENT_MWI,
04391       AST_EVENT_IE_MAILBOX, AST_EVENT_IE_PLTYPE_STR, mailbox,
04392       AST_EVENT_IE_CONTEXT, AST_EVENT_IE_PLTYPE_STR, context,
04393       AST_EVENT_IE_END);
04394 
04395    if (event) {
04396       new = ast_event_get_ie_uint(event, AST_EVENT_IE_NEWMSGS);
04397       ast_event_destroy(event);
04398    } else { /* Fall back on checking the mailbox directly */
04399       new = ast_app_has_voicemail(peer->mailbox, "INBOX");
04400    }
04401 
04402    peer->nextmsgcheck = tick + TIMER_MWI;
04403 
04404    /* Return now if it's the same thing we told them last time */
04405    if (new == peer->lastmsgssent) {
04406       return 0;
04407    }
04408 
04409    peer->lastmsgssent = new;
04410    if (new == 0) {
04411       send_led_update(s, 0);
04412    } else {
04413       send_led_update(s, 1);
04414    }
04415 
04416    return 0;
04417 }

static int unistim_senddigit_begin ( struct ast_channel ast,
char  digit 
) [static]

Definition at line 4208 of file chan_unistim.c.

References channel_to_session(), and unistim_do_senddigit().

04209 {
04210    struct unistimsession *pte = channel_to_session(ast);
04211 
04212    if (!pte)
04213       return -1;
04214 
04215    return unistim_do_senddigit(pte, digit);
04216 }

static int unistim_senddigit_end ( struct ast_channel ast,
char  digit,
unsigned int  duration 
) [static]

Definition at line 4218 of file chan_unistim.c.

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

04219 {
04220    struct unistimsession *pte = channel_to_session(ast);
04221    struct ast_frame f = { 0, };
04222    struct unistim_subchannel *sub;
04223 
04224    sub = pte->device->lines->subs[SUB_REAL];
04225 
04226    if (!sub->owner || sub->alreadygone) {
04227       ast_log(LOG_WARNING, "Unable to find subchannel in dtmf senddigit_end\n");
04228       return -1;
04229    }
04230 
04231    if (unistimdebug)
04232       ast_verb(0, "Send Digit off %c\n", digit);
04233 
04234    if (!pte)
04235       return -1;
04236 
04237    send_tone(pte, 0, 0);
04238    f.frametype = AST_FRAME_DTMF;
04239    f.subclass = digit;
04240    f.src = "unistim";
04241    ast_queue_frame(sub->owner, &f);
04242 
04243    return 0;
04244 }

static int unistim_sendtext ( struct ast_channel ast,
const char *  text 
) [static]

Definition at line 4248 of file chan_unistim.c.

References ast_log(), ast_verb, channel_to_session(), unistimsession::device, LOG_WARNING, send_favorite(), send_text(), unistim_device::softkeyicon, unistim_device::softkeylabel, unistim_device::softkeynumber, TEXT_LENGTH_MAX, TEXT_LINE0, TEXT_LINE1, TEXT_LINE2, and TEXT_NORMAL.

04249 {
04250    struct unistimsession *pte = channel_to_session(ast);
04251    int size;
04252    char tmp[TEXT_LENGTH_MAX + 1];
04253 
04254    if (unistimdebug)
04255       ast_verb(0, "unistim_sendtext called\n");
04256 
04257    if (!text) {
04258       ast_log(LOG_WARNING, "unistim_sendtext called with a null text\n");
04259       return 1;
04260    }
04261 
04262    size = strlen(text);
04263    if (text[0] == '@') {
04264       int pos = 0, i = 1, tok = 0, sz = 0;
04265       char label[11];
04266       char number[16];
04267       char icon = '\0';
04268       char cur = '\0';
04269 
04270       memset(label, 0, 11);
04271       memset(number, 0, 16);
04272       while (text[i]) {
04273          cur = text[i++];
04274          switch (tok) {
04275          case 0:
04276             if ((cur < '0') && (cur > '5')) {
04277                ast_log(LOG_WARNING,
04278                      "sendtext failed : position must be a number beetween 0 and 5\n");
04279                return 1;
04280             }
04281             pos = cur - '0';
04282             tok = 1;
04283             continue;
04284          case 1:
04285             if (cur != '@') {
04286                ast_log(LOG_WARNING, "sendtext failed : invalid position\n");
04287                return 1;
04288             }
04289             tok = 2;
04290             continue;
04291          case 2:
04292             if ((cur < '3') && (cur > '6')) {
04293                ast_log(LOG_WARNING,
04294                      "sendtext failed : icon must be a number beetween 32 and 63 (first digit invalid)\n");
04295                return 1;
04296             }
04297             icon = (cur - '0') * 10;
04298             tok = 3;
04299             continue;
04300          case 3:
04301             if ((cur < '0') && (cur > '9')) {
04302                ast_log(LOG_WARNING,
04303                      "sendtext failed : icon must be a number beetween 32 and 63 (second digit invalid)\n");
04304                return 1;
04305             }
04306             icon += (cur - '0');
04307             tok = 4;
04308             continue;
04309          case 4:
04310             if (cur != '@') {
04311                ast_log(LOG_WARNING,
04312                      "sendtext failed : icon must be a number beetween 32 and 63 (too many digits)\n");
04313                return 1;
04314             }
04315             tok = 5;
04316             continue;
04317          case 5:
04318             if (cur == '@') {
04319                tok = 6;
04320                sz = 0;
04321                continue;
04322             }
04323             if (sz > 10)
04324                continue;
04325             label[sz] = cur;
04326             sz++;
04327             continue;
04328          case 6:
04329             if (sz > 15) {
04330                ast_log(LOG_WARNING,
04331                      "sendtext failed : extension too long = %d (15 car max)\n",
04332                      sz);
04333                return 1;
04334             }
04335             number[sz] = cur;
04336             sz++;
04337             continue;
04338          }
04339       }
04340       if (tok != 6) {
04341          ast_log(LOG_WARNING, "sendtext failed : incomplet command\n");
04342          return 1;
04343       }
04344       if (!pte->device) {
04345          ast_log(LOG_WARNING, "sendtext failed : no device ?\n");
04346          return 1;
04347       }
04348       strcpy(pte->device->softkeylabel[pos], label);
04349       strcpy(pte->device->softkeynumber[pos], number);
04350       pte->device->softkeyicon[pos] = icon;
04351       send_favorite(pos, icon, pte, label);
04352       return 0;
04353    }
04354 
04355    if (size <= TEXT_LENGTH_MAX * 2) {
04356       send_text(TEXT_LINE0, TEXT_NORMAL, pte, "Message :");
04357       send_text(TEXT_LINE1, TEXT_NORMAL, pte, text);
04358       if (size <= TEXT_LENGTH_MAX) {
04359          send_text(TEXT_LINE2, TEXT_NORMAL, pte, "");
04360          return 0;
04361       }
04362       memcpy(tmp, text + TEXT_LENGTH_MAX, TEXT_LENGTH_MAX);
04363       tmp[sizeof(tmp) - 1] = '\0';
04364       send_text(TEXT_LINE2, TEXT_NORMAL, pte, tmp);
04365       return 0;
04366    }
04367    send_text(TEXT_LINE0, TEXT_NORMAL, pte, text);
04368    memcpy(tmp, text + TEXT_LENGTH_MAX, TEXT_LENGTH_MAX);
04369    tmp[sizeof(tmp) - 1] = '\0';
04370    send_text(TEXT_LINE1, TEXT_NORMAL, pte, tmp);
04371    memcpy(tmp, text + TEXT_LENGTH_MAX * 2, TEXT_LENGTH_MAX);
04372    tmp[sizeof(tmp) - 1] = '\0';
04373    send_text(TEXT_LINE2, TEXT_NORMAL, pte, tmp);
04374    return 0;
04375 }

static int unistim_set_rtp_peer ( struct ast_channel chan,
struct ast_rtp rtp,
struct ast_rtp vrtp,
struct ast_rtp trtp,
int  codecs,
int  nat_active 
) [static]

Definition at line 5540 of file chan_unistim.c.

References ast_verb, and ast_channel::tech_pvt.

05542 {
05543    struct unistim_subchannel *sub;
05544 
05545    if (unistimdebug)
05546       ast_verb(0, "unistim_set_rtp_peer called\n");
05547 
05548    sub = chan->tech_pvt;
05549 
05550    if (sub)
05551       return 0;
05552 
05553    return -1;
05554 }

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

Definition at line 4742 of file chan_unistim.c.

References ast_cli_args::argc, ast_cli_args::argv, ast_cli(), ast_copy_string(), BUFFSEND, CLI_GENERATE, CLI_INIT, CLI_SHOWUSAGE, CLI_SUCCESS, ast_cli_entry::command, ast_cli_args::fd, find_subchannel_by_name(), len(), unistim_line::parent, unistim_subchannel::parent, send_client(), unistim_device::session, SIZE_HEADER, and ast_cli_entry::usage.

04743 {
04744    BUFFSEND;
04745    struct unistim_subchannel *sub;
04746    int i, j = 0, len;
04747    unsigned char c, cc;
04748    char tmp[256];
04749 
04750    switch (cmd) {
04751    case CLI_INIT:
04752       e->command = "unistim sp";
04753       e->usage =
04754          "Usage: unistim sp USTM/line@name hexa\n"
04755          "       unistim sp USTM/1000@hans 19040004\n";
04756       return NULL;
04757 
04758    case CLI_GENERATE:
04759       return NULL;   /* no completion */
04760    }
04761    
04762    if (a->argc < 4)
04763       return CLI_SHOWUSAGE;
04764 
04765    if (strlen(a->argv[2]) < 9)
04766       return CLI_SHOWUSAGE;
04767 
04768    len = strlen(a->argv[3]);
04769    if (len % 2)
04770       return CLI_SHOWUSAGE;
04771 
04772    ast_copy_string(tmp, a->argv[2] + 5, sizeof(tmp));
04773    sub = find_subchannel_by_name(tmp);
04774    if (!sub) {
04775       ast_cli(a->fd, "Can't find '%s'\n", tmp);
04776       return CLI_SUCCESS;
04777    }
04778    if (!sub->parent->parent->session) {
04779       ast_cli(a->fd, "'%s' is not connected\n", tmp);
04780       return CLI_SUCCESS;
04781    }
04782    ast_cli(a->fd, "Sending '%s' to %s (%p)\n", a->argv[3], tmp, sub->parent->parent->session);
04783    for (i = 0; i < len; i++) {
04784       c = a->argv[3][i];
04785       if (c >= 'a')
04786          c -= 'a' - 10;
04787       else
04788          c -= '0';
04789       i++;
04790       cc = a->argv[3][i];
04791       if (cc >= 'a')
04792          cc -= 'a' - 10;
04793       else
04794          cc -= '0';
04795       tmp[j++] = (c << 4) | cc;
04796    }
04797    memcpy(buffsend + SIZE_HEADER, tmp, j);
04798    send_client(SIZE_HEADER + j, buffsend, sub->parent->parent->session);
04799    return CLI_SUCCESS;
04800 }

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

Definition at line 2006 of file chan_unistim.c.

References ast_copy_string(), ast_log(), ast_pbx_run(), ast_setstate(), AST_STATE_RING, ast_verb, chan, unistimsession::device, ast_channel::exten, LOG_WARNING, unistim_device::name, unistim_line::name, unistim_line::parent, unistim_subchannel::parent, unistim_device::phone_number, unistim_device::redial_number, s, send_tone(), unistim_device::session, unistim_subchannel::subtype, and ast_channel::tech_pvt.

Referenced by HandleCallOutgoing().

02007 {
02008    struct ast_channel *chan = data;
02009    struct unistim_subchannel *sub = chan->tech_pvt;
02010    struct unistim_line *l = sub->parent;
02011    struct unistimsession *s = l->parent->session;
02012    int res;
02013 
02014    ast_verb(3, "Starting switch on '%s@%s-%d' to %s\n", l->name, l->parent->name, sub->subtype, s->device->phone_number);
02015    ast_copy_string(chan->exten, s->device->phone_number, sizeof(chan->exten));
02016    ast_copy_string(s->device->redial_number, s->device->phone_number,
02017                sizeof(s->device->redial_number));
02018    ast_setstate(chan, AST_STATE_RING);
02019    res = ast_pbx_run(chan);
02020    if (res) {
02021       ast_log(LOG_WARNING, "PBX exited non-zero\n");
02022       send_tone(s, 1000, 0);;
02023    }
02024    return NULL;
02025 }

static int unistim_write ( struct ast_channel ast,
struct ast_frame frame 
) [static]

Definition at line 3964 of file chan_unistim.c.

References AST_FRAME_IMAGE, AST_FRAME_VOICE, ast_getformatname(), ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_rtp_write(), ast_frame::frametype, unistim_subchannel::lock, LOG_WARNING, ast_channel::nativeformats, ast_channel::readformat, unistim_subchannel::rtp, ast_frame::subclass, ast_channel::tech_pvt, and ast_channel::writeformat.

03965 {
03966    struct unistim_subchannel *sub = ast->tech_pvt;
03967    int res = 0;
03968 
03969    if (frame->frametype != AST_FRAME_VOICE) {
03970       if (frame->frametype == AST_FRAME_IMAGE)
03971          return 0;
03972       else {
03973          ast_log(LOG_WARNING, "Can't send %d type frames with unistim_write\n",
03974                frame->frametype);
03975          return 0;
03976       }
03977    } else {
03978       if (!(frame->subclass & ast->nativeformats)) {
03979          ast_log(LOG_WARNING,
03980                "Asked to transmit frame type %s (%d), while native formats is %s (%d) (read/write = %s (%d)/%d)\n",
03981                ast_getformatname(frame->subclass), frame->subclass,
03982                ast_getformatname(ast->nativeformats), ast->nativeformats,
03983                ast_getformatname(ast->readformat), ast->readformat,
03984                ast->writeformat);
03985          return -1;
03986       }
03987    }
03988 
03989    if (sub) {
03990       ast_mutex_lock(&sub->lock);
03991       if (sub->rtp) {
03992          res = ast_rtp_write(sub->rtp, frame);
03993       }
03994       ast_mutex_unlock(&sub->lock);
03995    }
03996 
03997    return res;
03998 }

static int unistimsock_read ( int *  id,
int  fd,
short  events,
void *  ignore 
) [static]

Definition at line 3847 of file chan_unistim.c.

References ast_inet_ntoa(), ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_verb, errno, LOG_NOTICE, LOG_WARNING, unistimsession::next, parsing(), sessionlock, unistimsession::sin, and SIZE_PAGE.

Referenced by do_monitor().

03848 {
03849    struct sockaddr_in addr_from = { 0, };
03850    struct unistimsession *cur = NULL;
03851    int found = 0;
03852    int tmp = 0;
03853    int dw_num_bytes_rcvd;
03854 #ifdef DUMP_PACKET
03855    int dw_num_bytes_rcvdd;
03856    char iabuf[INET_ADDRSTRLEN];
03857 #endif
03858 
03859    dw_num_bytes_rcvd =
03860       recvfrom(unistimsock, buff, SIZE_PAGE, 0, (struct sockaddr *) &addr_from,
03861              &size_addr_from);
03862    if (dw_num_bytes_rcvd == -1) {
03863       if (errno == EAGAIN)
03864          ast_log(LOG_NOTICE, "UNISTIM: Received packet with bad UDP checksum\n");
03865       else if (errno != ECONNREFUSED)
03866          ast_log(LOG_WARNING, "Recv error %d (%s)\n", errno, strerror(errno));
03867       return 1;
03868    }
03869 
03870    /* Looking in the phone list if we already have a registration for him */
03871    ast_mutex_lock(&sessionlock);
03872    cur = sessions;
03873    while (cur) {
03874       if (cur->sin.sin_addr.s_addr == addr_from.sin_addr.s_addr) {
03875          found = 1;
03876          break;
03877       }
03878       tmp++;
03879       cur = cur->next;
03880    }
03881    ast_mutex_unlock(&sessionlock);
03882 
03883 #ifdef DUMP_PACKET
03884    if (unistimdebug)
03885       ast_verb(0, "\n*** Dump %d bytes from %s - phone_table[%d] ***\n",
03886                dw_num_bytes_rcvd, ast_inet_ntoa(addr_from.sin_addr), tmp);
03887    for (dw_num_bytes_rcvdd = 0; dw_num_bytes_rcvdd < dw_num_bytes_rcvd;
03888        dw_num_bytes_rcvdd++)
03889       ast_verb(0, "%.2x ", (unsigned char) buff[dw_num_bytes_rcvdd]);
03890    ast_verb(0, "\n******************************************\n");
03891 #endif
03892 
03893    if (!found) {
03894       if (unistimdebug)
03895          ast_verb(0, "Received a packet from an unknown source\n");
03896       parsing(dw_num_bytes_rcvd, buff, NULL, (struct sockaddr_in *) &addr_from);
03897 
03898    } else
03899       parsing(dw_num_bytes_rcvd, buff, cur, (struct sockaddr_in *) &addr_from);
03900 
03901    return 1;
03902 }

static int unload_module ( void   )  [static]

Definition at line 5615 of file chan_unistim.c.

References ARRAY_LEN, ast_channel_unregister(), ast_cli_unregister_multiple(), ast_free, ast_mutex_lock(), ast_mutex_unlock(), AST_PTHREADT_NULL, AST_PTHREADT_STOP, ast_rtp_proto_unregister(), monlock, and sched_context_destroy().

05616 {
05617    /* First, take us out of the channel loop */
05618    if (sched)
05619       sched_context_destroy(sched);
05620 
05621    ast_cli_unregister_multiple(unistim_cli, ARRAY_LEN(unistim_cli));
05622 
05623    ast_channel_unregister(&unistim_tech);
05624    ast_rtp_proto_unregister(&unistim_rtp);
05625 
05626    ast_mutex_lock(&monlock);
05627    if (monitor_thread && (monitor_thread != AST_PTHREADT_STOP) && (monitor_thread != AST_PTHREADT_NULL)) {
05628       pthread_cancel(monitor_thread);
05629       pthread_kill(monitor_thread, SIGURG);
05630       pthread_join(monitor_thread, NULL);
05631    }
05632    monitor_thread = AST_PTHREADT_STOP;
05633    ast_mutex_unlock(&monlock);
05634 
05635    if (buff)
05636       ast_free(buff);
05637    if (unistimsock > -1)
05638       close(unistimsock);
05639 
05640    return 0;
05641 }

static void unquote ( char *  out,
const char *  src,
int  maxlen 
) [static]

Definition at line 4872 of file chan_unistim.c.

References len().

Referenced by build_device().

04873 {
04874    int len = strlen(src);
04875    if (!len)
04876       return;
04877    if ((len > 1) && src[0] == '\"') {
04878       /* This is a quoted string */
04879       src++;
04880       /* Don't take more than what's there */
04881       len--;
04882       if (maxlen > len - 1)
04883          maxlen = len - 1;
04884       memcpy(out, src, maxlen);
04885       ((char *) out)[maxlen] = '\0';
04886    } else
04887       memcpy(out, src, maxlen);
04888    return;
04889 }

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

Definition at line 1096 of file chan_unistim.c.

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

Referenced by close_client(), and key_main_page().

01097 {
01098    if (unistimdebug)
01099       ast_verb(0, "Trying to unregister extension '%s' context '%s'\n",
01100                pte->device->extension_number, pte->device->lines->context);
01101    return ast_context_remove_extension(pte->device->lines->context,
01102                               pte->device->extension_number, 1, "Unistim");
01103 }

static int write_entry_history ( struct unistimsession pte,
FILE *  f,
char  c,
char *  line1 
) [static]

Definition at line 1671 of file chan_unistim.c.

References unistimsession::device, display_last_error(), unistim_device::lst_cid, unistim_device::lst_cnm, and TEXT_LENGTH_MAX.

Referenced by write_history().

01672 {
01673    if (fwrite(&c, 1, 1, f) != 1) {
01674       display_last_error("Unable to write history log header.");
01675       return -1;
01676    }
01677    if (fwrite(line1, TEXT_LENGTH_MAX, 1, f) != 1) {
01678       display_last_error("Unable to write history entry - date.");
01679       return -1;
01680    }
01681    if (fwrite(pte->device->lst_cid, TEXT_LENGTH_MAX, 1, f) != 1) {
01682       display_last_error("Unable to write history entry - callerid.");
01683       return -1;
01684    }
01685    if (fwrite(pte->device->lst_cnm, TEXT_LENGTH_MAX, 1, f) != 1) {
01686       display_last_error("Unable to write history entry - callername.");
01687       return -1;
01688    }
01689    return 0;
01690 }

static int write_history ( struct unistimsession pte,
char  way,
char  ismissed 
) [static]

Definition at line 1692 of file chan_unistim.c.

References ast_config_AST_LOG_DIR, AST_CONFIG_MAX_PATH, ast_free, ast_localtime(), ast_log(), ast_malloc, ast_mkdir(), ast_tvnow(), unistim_device::callhistory, unistimsession::device, display_last_error(), errno, f, LOG_WARNING, MAX_ENTRY_LOG, unistim_device::name, TEXT_LENGTH_MAX, ast_tm::tm_hour, ast_tm::tm_mday, ast_tm::tm_min, ast_tm::tm_mon, ast_tm::tm_sec, ast_tm::tm_year, USTM_LOG_DIR, and write_entry_history().

Referenced by cancel_dial(), close_call(), and HandleCallIncoming().

01693 {
01694    char tmp[AST_CONFIG_MAX_PATH], tmp2[AST_CONFIG_MAX_PATH];
01695    char line1[TEXT_LENGTH_MAX + 1];
01696    char count = 0, *histbuf;
01697    int size;
01698    FILE *f, *f2;
01699    struct timeval now = ast_tvnow();
01700    struct ast_tm atm = { 0, };
01701 
01702    if (!pte->device)
01703       return -1;
01704    if (!pte->device->callhistory)
01705       return 0;
01706    if (strchr(pte->device->name, '/') || (pte->device->name[0] == '.')) {
01707       ast_log(LOG_WARNING, "Account code '%s' insecure for writing file\n",
01708             pte->device->name);
01709       return -1;
01710    }
01711 
01712    snprintf(tmp, sizeof(tmp), "%s/%s", ast_config_AST_LOG_DIR, USTM_LOG_DIR);
01713    if (ast_mkdir(tmp, 0770)) {
01714       if (errno != EEXIST) {
01715          display_last_error("Unable to create directory for history");
01716          return -1;
01717       }
01718    }
01719 
01720    ast_localtime(&now, &atm, NULL);
01721    if (ismissed) {
01722       if (way == 'i')
01723          strcpy(tmp2, "Miss");
01724       else
01725          strcpy(tmp2, "Fail");
01726    } else
01727       strcpy(tmp2, "Answ");
01728    snprintf(line1, sizeof(line1), "%04d/%02d/%02d %02d:%02d:%02d %s",
01729           atm.tm_year + 1900, atm.tm_mon + 1, atm.tm_mday, atm.tm_hour,
01730           atm.tm_min, atm.tm_sec, tmp2);
01731 
01732    snprintf(tmp, sizeof(tmp), "%s/%s/%s-%c.csv", ast_config_AST_LOG_DIR,
01733           USTM_LOG_DIR, pte->device->name, way);
01734    if ((f = fopen(tmp, "r"))) {
01735       struct stat bufstat;
01736 
01737       if (stat(tmp, &bufstat)) {
01738          display_last_error("Unable to stat history log.");
01739          fclose(f);
01740          return -1;
01741       }
01742       size = 1 + (MAX_ENTRY_LOG * TEXT_LENGTH_MAX * 3);
01743       if (bufstat.st_size != size) {
01744          ast_log(LOG_WARNING,
01745                "History file %s has an incorrect size (%d instead of %d). It will be replaced by a new one.",
01746                tmp, (int) bufstat.st_size, size);
01747          fclose(f);
01748          f = NULL;
01749          count = 1;
01750       }
01751    }
01752 
01753    /* If we can't open the log file, we create a brand new one */
01754    if (!f) {
01755       char c = 1;
01756       int i;
01757 
01758       if ((errno != ENOENT) && (count == 0)) {
01759          display_last_error("Unable to open history log.");
01760          return -1;
01761       }
01762       f = fopen(tmp, "w");
01763       if (!f) {
01764          display_last_error("Unable to create history log.");
01765          return -1;
01766       }
01767       if (write_entry_history(pte, f, c, line1)) {
01768          fclose(f);
01769          return -1;
01770       }
01771       memset(line1, ' ', TEXT_LENGTH_MAX);
01772       for (i = 3; i < MAX_ENTRY_LOG * 3; i++) {
01773          if (fwrite(line1, TEXT_LENGTH_MAX, 1, f) != 1) {
01774             display_last_error("Unable to write history entry - stuffing.");
01775             fclose(f);
01776             return -1;
01777          }
01778       }
01779       if (fclose(f))
01780          display_last_error("Unable to close history - creation.");
01781       return 0;
01782    }
01783    /* We can open the log file, we create a temporary one, we add our entry and copy the rest */
01784    if (fread(&count, 1, 1, f) != 1) {
01785       display_last_error("Unable to read history header.");
01786       fclose(f);
01787       return -1;
01788    }
01789    if (count > MAX_ENTRY_LOG) {
01790       ast_log(LOG_WARNING, "Invalid count in history header of %s (%d max %d)\n", tmp,
01791             count, MAX_ENTRY_LOG);
01792       fclose(f);
01793       return -1;
01794    }
01795    snprintf(tmp2, sizeof(tmp2), "%s/%s/%s-%c.csv.tmp", ast_config_AST_LOG_DIR,
01796           USTM_LOG_DIR, pte->device->name, way);
01797    if (!(f2 = fopen(tmp2, "w"))) {
01798       display_last_error("Unable to create temporary history log.");
01799       fclose(f);
01800       return -1;
01801    }
01802 
01803    if (++count > MAX_ENTRY_LOG)
01804       count = MAX_ENTRY_LOG;
01805 
01806    if (write_entry_history(pte, f2, count, line1)) {
01807       fclose(f);
01808       fclose(f2);
01809       return -1;
01810    }
01811 
01812    size = (MAX_ENTRY_LOG - 1) * TEXT_LENGTH_MAX * 3;
01813    if (!(histbuf = ast_malloc(size))) {
01814       fclose(f);
01815       fclose(f2);
01816       return -1;
01817    }
01818 
01819    if (fread(histbuf, size, 1, f) != 1) {
01820       ast_free(histbuf);
01821       fclose(f);
01822       fclose(f2);
01823       display_last_error("Unable to read previous history entries.");
01824       return -1;
01825    }
01826    if (fwrite(histbuf, size, 1, f2) != 1) {
01827       ast_free(histbuf);
01828       fclose(f);
01829       fclose(f2);
01830       display_last_error("Unable to write previous history entries.");
01831       return -1;
01832    }
01833    ast_free(histbuf);
01834    if (fclose(f))
01835       display_last_error("Unable to close history log.");
01836    if (fclose(f2))
01837       display_last_error("Unable to close temporary history log.");
01838    if (unlink(tmp))
01839       display_last_error("Unable to remove old history log.");
01840    if (rename(tmp2, tmp))
01841       display_last_error("Unable to rename new history log.");
01842    return 0;
01843 }


Variable Documentation

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 = "a9c98e5d177805051735cb5b0b16b0a0" , .load = load_module, .unload = unload_module, .reload = reload, } [static]

Definition at line 5654 of file chan_unistim.c.

struct sockaddr_in address_from [static]

give the IP address for the last packet received

Definition at line 221 of file chan_unistim.c.

Definition at line 5654 of file chan_unistim.c.

enum autoprovision autoprovisioning = AUTOPROVISIONING_NO [static]

Definition at line 206 of file chan_unistim.c.

unsigned char* buff [static]
const char channel_type[] = "USTM" [static]

Definition at line 670 of file chan_unistim.c.

unsigned int cos

Definition at line 213 of file chan_unistim.c.

unsigned int cos_audio

Definition at line 214 of file chan_unistim.c.

struct ast_jb_conf default_jbconf [static]

Global jitterbuffer configuration - by default, jb is disabled.

Definition at line 189 of file chan_unistim.c.

ast_mutex_t devicelock = ((ast_mutex_t) PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP ) [static]
struct unistim_device * devices [static]

A device containing one or more lines.

struct tone_zone_unistim frequency[] [static]

Definition at line 309 of file chan_unistim.c.

struct ast_jb_conf global_jbconf [static]

Definition at line 196 of file chan_unistim.c.

Referenced by reload_config(), and unistim_new().

struct io_context* io [static]

Definition at line 217 of file chan_unistim.c.

pthread_t monitor_thread = AST_PTHREADT_NULL [static]

This is the thread for the monitor which checks for input on the channels which are not currently in use.

Definition at line 234 of file chan_unistim.c.

ast_mutex_t monlock = ((ast_mutex_t) PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP ) [static]

Protect the monitoring thread, so only one process can kill or start it, and not when it's doing something critical.

Definition at line 238 of file chan_unistim.c.

Referenced by restart_monitor(), and unload_module().

const unsigned char packet_rcv_discovery[] [static]
Initial value:
   { 0xff, 0xff, 0xff, 0xff, 0x02, 0x02, 0xff, 0xff, 0xff, 0xff, 0x9e, 0x03, 0x08 }

Definition at line 503 of file chan_unistim.c.

const unsigned char packet_recv_firm_version[] [static]
Initial value:
   { 0x00, 0x00, 0x00, 0x13, 0x9a, 0x0a, 0x02 }

Definition at line 508 of file chan_unistim.c.

const unsigned char packet_recv_hangup[] [static]
Initial value:
   { 0x00, 0x00, 0x00, 0x13, 0x99, 0x03, 0x03 }

Definition at line 514 of file chan_unistim.c.

const unsigned char packet_recv_mac_addr[] [static]
Initial value:
   { 0xff, 0xff, 0xff, 0xff, 0x9a, 0x0d, 0x07   }

Definition at line 521 of file chan_unistim.c.

const unsigned char packet_recv_pick_up[] [static]
Initial value:
   { 0x00, 0x00, 0x00, 0x13, 0x99, 0x03, 0x04 }

Definition at line 512 of file chan_unistim.c.

const unsigned char packet_recv_pressed_key[] [static]
Initial value:
   { 0x00, 0x00, 0x00, 0x13, 0x99, 0x04, 0x00 }

Definition at line 510 of file chan_unistim.c.

const unsigned char packet_recv_r2[] = { 0x00, 0x00, 0x00, 0x13, 0x96, 0x03, 0x03 } [static]

Definition at line 516 of file chan_unistim.c.

const unsigned char packet_recv_resume_connection_with_server[] [static]
Initial value:
   { 0xff, 0xff, 0xff, 0xff, 0x9e, 0x03, 0x08 }

TransportAdapter

Definition at line 519 of file chan_unistim.c.

const unsigned char packet_send_arrow[] = { 0x17, 0x04, 0x04, 0x00 } [static]

Definition at line 616 of file chan_unistim.c.

const unsigned char packet_send_blink_cursor[] = { 0x17, 0x04, 0x10, 0x86 } [static]

Definition at line 617 of file chan_unistim.c.

const unsigned char packet_send_call[] [static]

Definition at line 544 of file chan_unistim.c.

const unsigned char packet_send_Contrast[] [static]
Initial value:
   { 0x17, 0x04, 0x24,  0x08 }

Definition at line 621 of file chan_unistim.c.

const unsigned char packet_send_date_time[] [static]

Definition at line 528 of file chan_unistim.c.

const unsigned char packet_send_date_time2[] [static]
Initial value:
 { 0x17, 0x04, 0x17, 0x3d, 0x11, 0x09, 0x02, 0x0a,  0x05,   
   0x06,  0x07,  0x08, 0x32
}

Definition at line 618 of file chan_unistim.c.

const unsigned char packet_send_date_time3[] [static]
Initial value:
   { 0x11, 0x09, 0x02, 0x02,  0x05,  0x06,  0x07,
 0x08, 0x32
}

Definition at line 524 of file chan_unistim.c.

unsigned char packet_send_discovery_ack[] [static]
Initial value:
   { 0x00, 0x00,  0x00, 0x00, 0x00, 0x01 }

Definition at line 505 of file chan_unistim.c.

const unsigned char packet_send_end_call[] [static]
Initial value:
   { 0x16, 0x06, 0x32, 0xdf, 0x00, 0xff, 0x16, 0x05, 0x31, 0x00, 0x00, 0x19, 0x04, 0x00,
0x10, 0x19, 0x04, 0x00, 0x18, 0x16, 0x05,
   0x04, 0x00, 0x00, 0x16, 0x04, 0x37, 0x10
}

Definition at line 572 of file chan_unistim.c.

const unsigned char packet_send_favorite[] [static]
Initial value:
   { 0x17, 0x0f, 0x19, 0x10,  0x01,  0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
0x20, 0x20, 0x20, 0x20,  0x19,
   0x05, 0x0f,  0x01,  0x00
}

Definition at line 634 of file chan_unistim.c.

const unsigned char packet_send_icon[] = { 0x17, 0x05, 0x14, 0x00, 0x25 } [static]

Definition at line 627 of file chan_unistim.c.

const unsigned char packet_send_jitter_buffer_conf[] [static]
Initial value:
   { 0x16, 0x0e, 0x3a, 0x00,  0x02,  0x04, 0x00, 0x00,
 0x3e, 0x80,
   0x00, 0x00,  0x3e, 0x80
}

Definition at line 582 of file chan_unistim.c.

const unsigned char packet_send_led_update[] = { 0x19, 0x04, 0x00, 0x00 } [static]

Definition at line 657 of file chan_unistim.c.

const unsigned char packet_send_no_ring[] [static]
Initial value:
   { 0x16, 0x04, 0x1a, 0x00, 0x16, 0x04, 0x11, 0x00 }

Definition at line 535 of file chan_unistim.c.

const unsigned char packet_send_open_audio_stream_rx[] [static]
Initial value:
   { 0x16, 0x1a, 0x30, 0x00, 0xff,  0x00, 0x00, 0x01, 0x00, 0xb8, 0xb8, 0x0e,
0x0e, 0x01,  0x14, 0x50, 0x00,
   0x00,  0x14, 0x50, 0x00, 0x00,  0x0a, 0x93, 0x69, 0x05
}

Definition at line 591 of file chan_unistim.c.

const unsigned char packet_send_open_audio_stream_rx3[] [static]

Definition at line 602 of file chan_unistim.c.

const unsigned char packet_send_open_audio_stream_tx[] [static]
Initial value:
   { 0x16, 0x1a, 0x30, 0xff, 0x00, 0x00,  0x00, 0x01, 0x00, 0xb8, 0xb8, 0x0e,
0x0e, 0x01,  0x14, 0x50,
   0x00, 0x00,  0x14, 0x50, 0x00, 0x00,  0x0a, 0x93, 0x69, 0x05
}

Definition at line 596 of file chan_unistim.c.

const unsigned char packet_send_open_audio_stream_tx3[] [static]

Definition at line 609 of file chan_unistim.c.

unsigned char packet_send_ping[] [static]
Initial value:
   { 0x1e, 0x05, 0x12, 0x00,  0x78 }

Definition at line 664 of file chan_unistim.c.

const unsigned char packet_send_query_basic_manager_04[] = { 0x1a, 0x04, 0x01, 0x04 } [static]

Definition at line 659 of file chan_unistim.c.

const unsigned char packet_send_query_basic_manager_10[] = { 0x1a, 0x04, 0x01, 0x10 } [static]

Definition at line 661 of file chan_unistim.c.

const unsigned char packet_send_query_mac_address[] = { 0x1a, 0x04, 0x01, 0x08 } [static]

Definition at line 660 of file chan_unistim.c.

const unsigned char packet_send_ring[] [static]
Initial value:
   { 0x16, 0x06, 0x32, 0xdf, 0x00, 0xff, 0x16, 0x05, 0x1c, 0x00, 0x00, 0x16,
   0x04, 0x1a, 0x01, 0x16, 0x05, 0x12, 0x13  , 0x18, 0x16, 0x04, 0x18,     
   0x20, 0x16, 0x04, 0x10, 0x00
}

Definition at line 567 of file chan_unistim.c.

const unsigned char packet_send_rtp_packet_size[] [static]
Initial value:
   { 0x16, 0x08, 0x38, 0x00, 0x00, 0xe0, 0x00, 0xa0 }

Definition at line 580 of file chan_unistim.c.

const unsigned char packet_send_S1[] = { 0x1a, 0x07, 0x07, 0x00, 0x00, 0x00, 0x13 } [static]

Definition at line 662 of file chan_unistim.c.

const unsigned char packet_send_s4[] [static]

Definition at line 537 of file chan_unistim.c.

const unsigned char packet_send_S7[] = { 0x17, 0x06, 0x0f, 0x30, 0x07, 0x07 } [static]

Definition at line 628 of file chan_unistim.c.

const unsigned char packet_send_s9[] [static]
Initial value:
   { 0x16, 0x06, 0x32, 0xdf, 0x00, 0xff, 0x19, 0x04, 0x00, 0x10, 0x16, 0x05, 0x1c, 0x00,
0x00 }

Definition at line 577 of file chan_unistim.c.

const unsigned char packet_send_select_output[] [static]
Initial value:
   { 0x16, 0x06, 0x32, 0xc0, 0x01, 0x00 }

Definition at line 565 of file chan_unistim.c.

const unsigned char packet_send_set_pos_cursor[] [static]
Initial value:
   { 0x17, 0x06, 0x10, 0x81, 0x04,  0x20 }

Definition at line 629 of file chan_unistim.c.

const unsigned char packet_send_StartTimer[] [static]
Initial value:
   { 0x17, 0x05, 0x0b, 0x05, 0x00, 0x17, 0x08, 0x16,  0x44, 0x75, 0x72, 0xe9,
0x65 }

Definition at line 623 of file chan_unistim.c.

const unsigned char packet_send_status[] [static]
Initial value:
   { 0x17, 0x20, 0x19, 0x08,  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
   0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20    
}

Definition at line 648 of file chan_unistim.c.

const unsigned char packet_send_status2[] [static]
Initial value:
   { 0x17, 0x0b, 0x19,  0x00,  0x20, 0x20, 0x20, 0x20,
0x20, 0x20, 0x20   }

Definition at line 653 of file chan_unistim.c.

const unsigned char packet_send_stop_timer[] = { 0x17, 0x05, 0x0b, 0x02, 0x00 } [static]

Definition at line 626 of file chan_unistim.c.

const unsigned char packet_send_stream_based_tone_dial_freq[] [static]
Initial value:
   { 0x16, 0x08, 0x1d, 0x00, 0x01, 0xb8, 0x01, 0x5e }

Definition at line 563 of file chan_unistim.c.

const unsigned char packet_send_stream_based_tone_off[] [static]
Initial value:
   { 0x16, 0x05, 0x1c, 0x00, 0x00 }

Definition at line 553 of file chan_unistim.c.

const unsigned char packet_send_stream_based_tone_on[] [static]
Initial value:
   { 0x16, 0x06, 0x1b, 0x00, 0x00, 0x05 }

Definition at line 559 of file chan_unistim.c.

const unsigned char packet_send_stream_based_tone_single_freq[] [static]
Initial value:
   { 0x16, 0x06, 0x1d, 0x00, 0x01, 0xb8 }

Definition at line 561 of file chan_unistim.c.

const unsigned char packet_send_text[] [static]

Definition at line 642 of file chan_unistim.c.

const unsigned char packet_send_title[] [static]
Initial value:
   { 0x17, 0x10, 0x19, 0x02,  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
0x20, 0x20, 0x20, 0x20   }

Definition at line 639 of file chan_unistim.c.

struct sockaddr_in public_ip = { 0, } [static]

Definition at line 219 of file chan_unistim.c.

struct { ... } qos [static]

Referenced by reload_config(), and start_rtp().

struct sched_context* sched [static]

Definition at line 218 of file chan_unistim.c.

ast_mutex_t sessionlock = ((ast_mutex_t) PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP ) [static]

Protect the session list

Definition at line 240 of file chan_unistim.c.

Referenced by close_client(), create_client(), do_monitor(), reload_config(), unistim_info(), and unistimsock_read().

struct unistimsession * sessions [static]
unsigned int size_addr_from = sizeof(address_from) [static]

size of the sockaddr_in (in WSARecvFrom)

Definition at line 223 of file chan_unistim.c.

const char tdesc[] = "UNISTIM Channel Driver" [static]

Definition at line 669 of file chan_unistim.c.

unsigned int tos

Definition at line 211 of file chan_unistim.c.

unsigned int tos_audio

Definition at line 212 of file chan_unistim.c.

struct ast_cli_entry unistim_cli[] [static]

Definition at line 4865 of file chan_unistim.c.

int unistim_keepalive [static]

Definition at line 207 of file chan_unistim.c.

int unistim_port [static]

Definition at line 205 of file chan_unistim.c.

ast_mutex_t unistim_reload_lock = ((ast_mutex_t) PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP ) [static]

Definition at line 227 of file chan_unistim.c.

Referenced by do_monitor(), and unistim_reload().

int unistim_reloading = 0 [static]

Definition at line 226 of file chan_unistim.c.

struct ast_rtp_protocol unistim_rtp [static]

Definition at line 5556 of file chan_unistim.c.

struct ast_channel_tech unistim_tech [static]

Definition at line 698 of file chan_unistim.c.

int unistimdebug = 0 [static]

Enable verbose output. can also be set with the CLI

Definition at line 204 of file chan_unistim.c.

int unistimsock = -1 [static]

Definition at line 208 of file chan_unistim.c.

int usecnt = 0 [static]

Definition at line 229 of file chan_unistim.c.

ast_mutex_t usecnt_lock = ((ast_mutex_t) PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP ) [static]

Definition at line 228 of file chan_unistim.c.

Referenced by unistim_new().


Generated on 3 Mar 2010 for Asterisk - the Open Source PBX by  doxygen 1.6.1