Mon Oct 8 12:39:19 2012

Asterisk developer's documentation


chan_unistim.c File Reference

chan_unistim channel driver for Asterisk More...

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

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

Enumerations

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

Functions

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

Variables

static struct ast_module_info __mod_info = { .name = AST_MODULE, .flags = AST_MODFLAG_DEFAULT , .description = "UNISTIM Protocol (USTM)" , .key = "This paragraph is copyright (c) 2006 by Digium, Inc. \In order for your module to load, it must return this \key via a function called \"key\". Any code which \includes this paragraph must be licensed under the GNU \General Public License version 2 or later (at your \option). In addition to Digium's general reservations \of rights, Digium expressly reserves the right to \allow other parties to license this paragraph under \different terms. Any use of Digium, Inc. trademarks or \logos (including \"Asterisk\" or \"Digium\") without \express written permission of Digium, Inc. is prohibited.\n" , .buildopt_sum = "ac1f6a56484a8820659555499174e588" , .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 = { PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP , NULL, 1 }
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 = { PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP , NULL, 1 }
static const unsigned char packet_rcv_discovery []
static const unsigned char packet_recv_firm_version []
static const unsigned char packet_recv_hangup []
static const unsigned char packet_recv_mac_addr []
static const unsigned char packet_recv_pick_up []
static const unsigned char packet_recv_pressed_key []
static const unsigned char packet_recv_r2 [] = { 0x00, 0x00, 0x00, 0x13, 0x96, 0x03, 0x03 }
static const unsigned char packet_recv_resume_connection_with_server []
static const unsigned char packet_send_arrow [] = { 0x17, 0x04, 0x04, 0x00 }
static const unsigned char packet_send_blink_cursor [] = { 0x17, 0x04, 0x10, 0x86 }
static const unsigned char packet_send_call []
static const unsigned char packet_send_Contrast []
static const unsigned char packet_send_date_time []
static const unsigned char packet_send_date_time2 []
static const unsigned char packet_send_date_time3 []
static const unsigned char packet_send_discovery_ack []
static const unsigned char packet_send_end_call []
static const unsigned char packet_send_favorite []
static const unsigned char packet_send_icon [] = { 0x17, 0x05, 0x14, 0x00, 0x25 }
static const unsigned char packet_send_jitter_buffer_conf []
static const unsigned char packet_send_led_update [] = { 0x19, 0x04, 0x00, 0x00 }
static const unsigned char packet_send_no_ring []
static const unsigned char packet_send_open_audio_stream_rx []
static const unsigned char packet_send_open_audio_stream_rx3 []
static const unsigned char packet_send_open_audio_stream_tx []
static const unsigned char packet_send_open_audio_stream_tx3 []
static unsigned char packet_send_ping []
static const unsigned char packet_send_query_basic_manager_04 [] = { 0x1a, 0x04, 0x01, 0x04 }
static const unsigned char packet_send_query_basic_manager_10 [] = { 0x1a, 0x04, 0x01, 0x10 }
static const unsigned char packet_send_query_mac_address [] = { 0x1a, 0x04, 0x01, 0x08 }
static const unsigned char packet_send_ring []
static const unsigned char packet_send_rtp_packet_size []
static const unsigned char packet_send_S1 [] = { 0x1a, 0x07, 0x07, 0x00, 0x00, 0x00, 0x13 }
static const unsigned char packet_send_s4 []
static const unsigned char packet_send_S7 [] = { 0x17, 0x06, 0x0f, 0x30, 0x07, 0x07 }
static const unsigned char packet_send_s9 []
static const unsigned char packet_send_select_output []
static const unsigned char packet_send_set_pos_cursor []
static const unsigned char packet_send_StartTimer []
static const unsigned char packet_send_status []
static const unsigned char packet_send_status2 []
static const unsigned char packet_send_stop_timer [] = { 0x17, 0x05, 0x0b, 0x02, 0x00 }
static const unsigned char packet_send_stream_based_tone_dial_freq []
static const unsigned char packet_send_stream_based_tone_off []
static const unsigned char packet_send_stream_based_tone_on []
static const unsigned char packet_send_stream_based_tone_single_freq []
static const unsigned char packet_send_text []
static const unsigned char packet_send_title []
static struct sockaddr_in public_ip = { 0, }
struct {
   unsigned int   cos
   unsigned int   cos_audio
   unsigned int   tos
   unsigned int   tos_audio
qos
static struct sched_contextsched
static ast_mutex_t sessionlock = { PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP , NULL, 1 }
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 = { PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP , NULL, 1 }
static int unistim_reloading = 0
static struct ast_rtp_glue unistim_rtp_glue
static struct ast_channel_tech unistim_tech
static int unistimdebug = 0
static int unistimsock = -1
static int usecnt = 0
static ast_mutex_t usecnt_lock = { PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP , NULL, 1 }


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

Referenced by OpenHistory(), and write_history().

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

Definition at line 675 of file chan_unistim.c.

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

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

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

#define DEBUG_TIMER   dummy

Definition at line 209 of file chan_unistim.c.

Referenced by do_monitor(), and set_ping_timer().

#define DEFAULT_CODEC   0x00

Not used

Definition at line 99 of file chan_unistim.c.

Referenced by key_select_extension(), and unistim_register().

#define DEFAULTCALLERID   "Unknown"

Definition at line 81 of file chan_unistim.c.

Referenced by unistim_call().

#define DEFAULTCALLERNAME   " "

Definition at line 82 of file chan_unistim.c.

Referenced by unistim_call().

#define DEFAULTCONTEXT   "default"

Definition at line 80 of file chan_unistim.c.

Referenced by build_device().

#define DEFAULTHEIGHT   3

Definition at line 83 of file chan_unistim.c.

Referenced by build_device().

#define DEVICE_NAME_LEN   16

Definition at line 101 of file chan_unistim.c.

#define FAV_BLINK_FAST   0x20

Definition at line 183 of file chan_unistim.c.

Referenced by unistim_call().

#define FAV_BLINK_SLOW   0x40

Definition at line 184 of file chan_unistim.c.

Referenced by show_main_page().

#define FAV_ICON_BOX   0x3F

Definition at line 181 of file chan_unistim.c.

#define FAV_ICON_CALL_CENTER   0x34

Definition at line 170 of file chan_unistim.c.

Referenced by show_main_page().

#define FAV_ICON_CITY   0x31

Definition at line 167 of file chan_unistim.c.

#define FAV_ICON_COMPUTER   0x38

Definition at line 174 of file chan_unistim.c.

#define FAV_ICON_FAX   0x35

Definition at line 171 of file chan_unistim.c.

#define FAV_ICON_FORWARD   0x39

Definition at line 175 of file chan_unistim.c.

#define FAV_ICON_HEADPHONES   0x2E

Definition at line 164 of file chan_unistim.c.

Referenced by send_select_output().

#define FAV_ICON_HEADPHONES_ONHOLD   0x2F

Definition at line 165 of file chan_unistim.c.

Referenced by refresh_all_favorite(), and send_select_output().

#define FAV_ICON_HOME   0x30

Definition at line 166 of file chan_unistim.c.

#define FAV_ICON_INBOX   0x3C

Definition at line 178 of file chan_unistim.c.

#define FAV_ICON_LOCKED   0x3A

Definition at line 176 of file chan_unistim.c.

#define FAV_ICON_MAILBOX   0x36

Definition at line 172 of file chan_unistim.c.

#define FAV_ICON_MEETING   0x3E

Definition at line 180 of file chan_unistim.c.

#define FAV_ICON_NONE   0x00

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

Referenced by send_select_output().

#define FAV_ICON_OFFHOOK_WHITE   0x25

Definition at line 155 of file chan_unistim.c.

#define FAV_ICON_ONHOLD_BLACK   0x26

Definition at line 156 of file chan_unistim.c.

Referenced by send_select_output().

#define FAV_ICON_ONHOLD_WHITE   0x27

Definition at line 157 of file chan_unistim.c.

#define FAV_ICON_ONHOOK_BLACK   0x20

Definition at line 150 of file chan_unistim.c.

Referenced by build_device(), and show_main_page().

#define FAV_ICON_ONHOOK_WHITE   0x21

Definition at line 151 of file chan_unistim.c.

#define FAV_ICON_OUTBOX   0x3D

Definition at line 179 of file chan_unistim.c.

#define FAV_ICON_PAGER   0x33

Definition at line 169 of file chan_unistim.c.

#define FAV_ICON_PHONE_BLACK   0x2A

Definition at line 160 of file chan_unistim.c.

Referenced by handle_dial_page().

#define FAV_ICON_PHONE_WHITE   0x2B

Definition at line 161 of file chan_unistim.c.

#define FAV_ICON_REFLECT   0x37

Definition at line 173 of file chan_unistim.c.

Referenced by show_main_page().

#define FAV_ICON_SHARP   0x32

Definition at line 168 of file chan_unistim.c.

Referenced by ParseBookmark().

#define FAV_ICON_SPEAKER_OFFHOOK_BLACK   0x28

Definition at line 158 of file chan_unistim.c.

Referenced by send_select_output().

#define FAV_ICON_SPEAKER_OFFHOOK_WHITE   0x29

Definition at line 159 of file chan_unistim.c.

#define FAV_ICON_SPEAKER_ONHOLD_BLACK   0x2C

Definition at line 162 of file chan_unistim.c.

Referenced by send_select_output().

#define FAV_ICON_SPEAKER_ONHOLD_WHITE   0x2D

Definition at line 163 of file chan_unistim.c.

#define FAV_ICON_SPEAKER_ONHOOK_BLACK   0x22

Definition at line 152 of file chan_unistim.c.

Referenced by send_select_output(), and unistim_call().

#define FAV_ICON_SPEAKER_ONHOOK_WHITE   0x23

Definition at line 153 of file chan_unistim.c.

#define FAV_ICON_TRASH   0x3B

Definition at line 177 of file chan_unistim.c.

#define FAV_MAX_LENGTH   0x0A

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

Referenced by do_monitor().

#define MAX_BUF_NUMBER   50

Number of slots for the transmit queue

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

#define MAX_ENTRY_LOG   30

Definition at line 103 of file chan_unistim.c.

Referenced by OpenHistory(), and write_history().

#define MAX_SUBS   2

Definition at line 107 of file chan_unistim.c.

#define MUTE_OFF   0x00

Definition at line 135 of file chan_unistim.c.

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

#define MUTE_ON   0xFF

Definition at line 136 of file chan_unistim.c.

Referenced by key_call(), and send_select_output().

#define MUTE_ON_DISCRET   0xCE

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

Referenced by reload_config(), and send_retransmit().

#define OUTPUT_HANDSET   0xC0

Definition at line 126 of file chan_unistim.c.

Referenced by build_device(), handle_dial_page(), HandleCallIncoming(), key_call(), key_dial_page(), key_main_page(), process_request(), and send_select_output().

#define OUTPUT_HEADPHONE   0xC1

Definition at line 127 of file chan_unistim.c.

Referenced by key_call(), key_dial_page(), key_main_page(), process_request(), and send_select_output().

#define OUTPUT_SPEAKER   0xC2

Definition at line 128 of file chan_unistim.c.

Referenced by handle_dial_page(), HandleCallIncoming(), key_call(), key_dial_page(), key_main_page(), and send_select_output().

#define RETRANSMIT_TIMER   2000

Wait x milliseconds before resending a packet

Definition at line 95 of file chan_unistim.c.

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

#define SELECTCODEC_MAX_LENGTH   2

Definition at line 2831 of file chan_unistim.c.

Referenced by key_select_codec().

#define SELECTCODEC_MSG   "Codec number : .."

Definition at line 2832 of file chan_unistim.c.

Referenced by HandleSelectCodec(), and key_select_codec().

#define SELECTCODEC_START_ENTRY_POS   15

Definition at line 2830 of file chan_unistim.c.

Referenced by HandleSelectCodec(), and key_select_codec().

#define SELECTEXTENSION_MAX_LENGTH   10

Definition at line 2908 of file chan_unistim.c.

Referenced by key_select_extension().

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

Definition at line 2909 of file chan_unistim.c.

Referenced by key_select_extension(), and ShowExtensionPage().

#define SELECTEXTENSION_START_ENTRY_POS   0

Definition at line 2907 of file chan_unistim.c.

Referenced by key_select_extension(), and ShowExtensionPage().

#define SIZE_HEADER   6

Definition at line 139 of file chan_unistim.c.

Referenced by init_phone_step2(), parsing(), process_request(), 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().

#define SIZE_MAC_ADDR   17

Definition at line 140 of file chan_unistim.c.

#define SIZE_PAGE   4096

Definition at line 100 of file chan_unistim.c.

Referenced by load_module(), and unistimsock_read().

#define STATUS_LENGTH_MAX   28

Definition at line 147 of file chan_unistim.c.

Referenced by send_text_status(), and show_entry_history().

#define SUB_REAL   0

Definition at line 105 of file chan_unistim.c.

#define SUB_THREEWAY   1

Definition at line 106 of file chan_unistim.c.

#define TEXT_INVERSE   0x25

Definition at line 146 of file chan_unistim.c.

Referenced by HandleSelectCodec(), and key_select_codec().

#define TEXT_LENGTH_MAX   24

Definition at line 141 of file chan_unistim.c.

Referenced by change_callerid(), handle_dial_page(), key_history(), send_text(), show_entry_history(), show_main_page(), unistim_sendtext(), write_entry_history(), and write_history().

#define TEXT_LINE0   0x00

Definition at line 142 of file chan_unistim.c.

Referenced by handle_dial_page(), HandleCallOutgoing(), HandleSelectCodec(), init_phone_step2(), key_dial_page(), key_main_page(), key_select_extension(), show_entry_history(), show_main_page(), ShowExtensionPage(), unistim_call(), unistim_hangup(), and unistim_sendtext().

#define TEXT_LINE1   0x20

Definition at line 143 of file chan_unistim.c.

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

#define TEXT_LINE2   0x40

Definition at line 144 of file chan_unistim.c.

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

#define TEXT_NORMAL   0x05

Definition at line 145 of file chan_unistim.c.

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

#define TIMER_MWI   10000

How often the mailbox is checked for new messages

Definition at line 97 of file chan_unistim.c.

Referenced by unistim_send_mwi_to_peer().

#define USTM_LOG_DIR   "unistimHistory"

Definition at line 84 of file chan_unistim.c.

Referenced by OpenHistory(), and write_history().

#define VOLUME_INSANELY_LOUD   0x07

Definition at line 133 of file chan_unistim.c.

#define VOLUME_LOW   0x01

Definition at line 130 of file chan_unistim.c.

Referenced by build_device(), and send_select_output().

#define VOLUME_LOW_SPEAKER   0x03

Definition at line 131 of file chan_unistim.c.

Referenced by send_select_output().

#define VOLUME_NORMAL   0x02

Definition at line 132 of file chan_unistim.c.


Enumeration Type Documentation

enum autoprov_extn

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

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

enum autoprovision

Enumerator:
AUTOPROVISIONING_NO 
AUTOPROVISIONING_YES 
AUTOPROVISIONING_DB 
AUTOPROVISIONING_TN 

Definition at line 109 of file chan_unistim.c.

00109                    {
00110    AUTOPROVISIONING_NO = 0,
00111    AUTOPROVISIONING_YES,
00112    AUTOPROVISIONING_DB,
00113    AUTOPROVISIONING_TN
00114 };

enum handset_state

Enumerator:
STATE_ONHOOK 
STATE_OFFHOOK 

Definition at line 264 of file chan_unistim.c.

00264                    {
00265    STATE_ONHOOK,
00266    STATE_OFFHOOK,
00267 };

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

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

enum phone_state

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

Definition at line 251 of file chan_unistim.c.

00251                  {
00252    STATE_INIT,
00253    STATE_AUTHDENY,
00254    STATE_MAINPAGE,
00255    STATE_EXTENSION,
00256    STATE_DIALPAGE,
00257    STATE_RINGING,
00258    STATE_CALL,
00259    STATE_SELECTCODEC,
00260    STATE_CLEANING,
00261    STATE_HISTORY
00262 };


Function Documentation

static void __reg_module ( void   )  [static]

Definition at line 5732 of file chan_unistim.c.

static void __unreg_module ( void   )  [static]

Definition at line 5732 of file chan_unistim.c.

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

Definition at line 1492 of file chan_unistim.c.

References ast_calloc, ast_mutex_init, ast_verb, unistim_device::name, unistim_line::name, unistim_line::parent, unistim_line::subs, and unistimdebug.

01493 {
01494    struct unistim_subchannel *sub;
01495    if (!(sub = ast_calloc(1, sizeof(*sub))))
01496       return 0;
01497 
01498    if (unistimdebug)
01499       ast_verb(3, "Allocating UNISTIM subchannel #%d on %s@%s ptr=%p\n", x, l->name, l->parent->name, sub);
01500    sub->parent = l;
01501    sub->subtype = x;
01502    l->subs[x] = sub;
01503    ast_mutex_init(&sub->lock);
01504    return 1;
01505 }

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

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

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

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

Definition at line 5090 of file chan_unistim.c.

References unistim_line::accountcode, alloc_sub(), unistim_line::amaflags, ast_append_ha(), ast_calloc, ast_cdr_amaflags2int(), ast_copy_string(), ast_free, ast_get_group(), ast_get_indication_zone(), ast_localtime(), ast_log(), AST_MAX_EXTENSION, ast_mutex_destroy, ast_mutex_init, ast_mutex_lock, ast_mutex_unlock, ast_strlen_zero(), ast_tone_zone_unref(), ast_true(), ast_tvnow(), ast_verb, autoprovisioning, 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, DEFAULTHEIGHT, 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::height, unistim_device::id, unistim_line::language, len(), ast_variable::lineno, unistim_device::lines, unistim_line::lock, LOG_ERROR, LOG_WARNING, unistim_line::mailbox, unistim_device::maintext0, unistim_device::maintext1, unistim_device::maintext2, unistim_line::musicclass, unistim_device::mute, MUTE_OFF, unistim_line::name, ast_variable::name, unistim_device::name, unistim_device::nat, ast_variable::next, unistim_line::next, unistim_device::next, unistim_device::output, OUTPUT_HANDSET, unistim_line::parent, unistim_line::parkinglot, ParseBookmark(), unistim_line::pickupgroup, unistim_device::previous_output, unistim_device::ringstyle, unistim_device::ringvolume, unistim_device::rtp_method, unistim_device::rtp_port, unistim_device::softkeydevice, unistim_device::softkeyicon, unistim_device::softkeylabel, unistim_device::softkeylinepos, unistim_device::softkeynumber, unistim_device::sp, unistim_device::status_method, SUB_REAL, unistim_device::titledefault, ast_tm::tm_zone, unistim_device::to_delete, unistim_device::tz, unistimdebug, unistimsock, unquote(), ast_variable::value, unistim_device::volume, and VOLUME_LOW.

05091 {
05092    struct unistim_device *d;
05093    struct unistim_line *l = NULL;
05094    int create = 1;
05095    int nbsoftkey, dateformat, timeformat, callhistory;
05096    char linelabel[AST_MAX_EXTENSION];
05097    char context[AST_MAX_EXTENSION];
05098    char ringvolume, ringstyle;
05099 
05100    /* First, we need to know if we already have this name in our list */
05101    /* Get a lock for the device chained list */
05102    ast_mutex_lock(&devicelock);
05103    d = devices;
05104    while (d) {
05105       if (!strcmp(d->name, cat)) {
05106          /* Yep, we alreay have this one */
05107          if (unistimsock < 0) {
05108             /* It's a dupe */
05109             ast_log(LOG_WARNING, "Duplicate entry found (%s), ignoring.\n", cat);
05110             ast_mutex_unlock(&devicelock);
05111             return NULL;
05112          }
05113          /* we're reloading right now */
05114          create = 0;
05115          l = d->lines;
05116          break;
05117       }
05118       d = d->next;
05119    }
05120    ast_mutex_unlock(&devicelock);
05121    if (create) {
05122       if (!(d = ast_calloc(1, sizeof(*d))))
05123          return NULL;
05124 
05125       if (!(l = ast_calloc(1, sizeof(*l)))) {
05126          ast_free(d);
05127          return NULL;
05128       }
05129       ast_copy_string(d->name, cat, sizeof(d->name));
05130    }
05131    ast_copy_string(context, DEFAULTCONTEXT, sizeof(context));
05132    d->contrast = -1;
05133    d->output = OUTPUT_HANDSET;
05134    d->previous_output = OUTPUT_HANDSET;
05135    d->volume = VOLUME_LOW;
05136    d->mute = MUTE_OFF;
05137    d->height = DEFAULTHEIGHT;
05138    linelabel[0] = '\0';
05139    dateformat = 1;
05140    timeformat = 1;
05141    ringvolume = 2;
05142    callhistory = 1;
05143    ringstyle = 3;
05144    nbsoftkey = 0;
05145    while (v) {
05146       if (!strcasecmp(v->name, "rtp_port"))
05147          d->rtp_port = atoi(v->value);
05148       else if (!strcasecmp(v->name, "rtp_method"))
05149          d->rtp_method = atoi(v->value);
05150       else if (!strcasecmp(v->name, "status_method"))
05151          d->status_method = atoi(v->value);
05152       else if (!strcasecmp(v->name, "device"))
05153          ast_copy_string(d->id, v->value, sizeof(d->id));
05154       else if (!strcasecmp(v->name, "tn"))
05155          ast_copy_string(d->extension_number, v->value, sizeof(d->extension_number));
05156       else if (!strcasecmp(v->name, "permit") || !strcasecmp(v->name, "deny"))
05157          d->ha = ast_append_ha(v->name, v->value, d->ha, NULL);
05158       else if (!strcasecmp(v->name, "context"))
05159          ast_copy_string(context, v->value, sizeof(context));
05160       else if (!strcasecmp(v->name, "maintext0"))
05161          unquote(d->maintext0, v->value, sizeof(d->maintext0) - 1);
05162       else if (!strcasecmp(v->name, "maintext1"))
05163          unquote(d->maintext1, v->value, sizeof(d->maintext1) - 1);
05164       else if (!strcasecmp(v->name, "maintext2"))
05165          unquote(d->maintext2, v->value, sizeof(d->maintext2) - 1);
05166       else if (!strcasecmp(v->name, "titledefault"))
05167          unquote(d->titledefault, v->value, sizeof(d->titledefault) - 1);
05168       else if (!strcasecmp(v->name, "dateformat"))
05169          dateformat = atoi(v->value);
05170       else if (!strcasecmp(v->name, "timeformat"))
05171          timeformat = atoi(v->value);
05172       else if (!strcasecmp(v->name, "contrast")) {
05173          d->contrast = atoi(v->value);
05174          if ((d->contrast < 0) || (d->contrast > 15)) {
05175             ast_log(LOG_WARNING, "contrast must be beetween 0 and 15\n");
05176             d->contrast = 8;
05177          }
05178       } else if (!strcasecmp(v->name, "nat"))
05179          d->nat = ast_true(v->value);
05180       else if (!strcasecmp(v->name, "ringvolume"))
05181          ringvolume = atoi(v->value);
05182       else if (!strcasecmp(v->name, "ringstyle"))
05183          ringstyle = atoi(v->value);
05184       else if (!strcasecmp(v->name, "callhistory"))
05185          callhistory = atoi(v->value);
05186       else if (!strcasecmp(v->name, "callerid")) {
05187          if (!strcasecmp(v->value, "asreceived"))
05188             l->cid_num[0] = '\0';
05189          else
05190             ast_copy_string(l->cid_num, v->value, sizeof(l->cid_num));
05191       } else if (!strcasecmp(v->name, "language"))
05192          ast_copy_string(l->language, v->value, sizeof(l->language));
05193       else if (!strcasecmp(v->name, "country"))
05194          ast_copy_string(d->country, v->value, sizeof(d->country));
05195       else if (!strcasecmp(v->name, "accountcode"))
05196          ast_copy_string(l->accountcode, v->value, sizeof(l->accountcode));
05197       else if (!strcasecmp(v->name, "amaflags")) {
05198          int y;
05199          y = ast_cdr_amaflags2int(v->value);
05200          if (y < 0)
05201             ast_log(LOG_WARNING, "Invalid AMA flags: %s at line %d\n", v->value,
05202                   v->lineno);
05203          else
05204             l->amaflags = y;
05205       } else if (!strcasecmp(v->name, "musiconhold"))
05206          ast_copy_string(l->musicclass, v->value, sizeof(l->musicclass));
05207       else if (!strcasecmp(v->name, "callgroup"))
05208          l->callgroup = ast_get_group(v->value);
05209       else if (!strcasecmp(v->name, "pickupgroup"))
05210          l->pickupgroup = ast_get_group(v->value);
05211       else if (!strcasecmp(v->name, "mailbox"))
05212          ast_copy_string(l->mailbox, v->value, sizeof(l->mailbox));
05213       else if (!strcasecmp(v->name, "parkinglot"))
05214          ast_copy_string(l->parkinglot, v->value, sizeof(l->parkinglot));
05215       else if (!strcasecmp(v->name, "linelabel"))
05216          unquote(linelabel, v->value, sizeof(linelabel) - 1);
05217       else if (!strcasecmp(v->name, "extension")) {
05218          if (!strcasecmp(v->value, "none"))
05219             d->extension = EXTENSION_NONE;
05220          else if (!strcasecmp(v->value, "ask"))
05221             d->extension = EXTENSION_ASK;
05222          else if (!strcasecmp(v->value, "line"))
05223             d->extension = EXTENSION_LINE;
05224          else
05225             ast_log(LOG_WARNING, "Unknown extension option.\n");
05226       } else if (!strcasecmp(v->name, "bookmark")) {
05227          if (nbsoftkey > 5)
05228             ast_log(LOG_WARNING,
05229                   "More than 6 softkeys defined. Ignoring new entries.\n");
05230          else {
05231             if (ParseBookmark(v->value, d))
05232                nbsoftkey++;
05233          }
05234       } else if (!strcasecmp(v->name, "line")) {
05235          int len = strlen(linelabel);
05236 
05237          if (nbsoftkey) {
05238             ast_log(LOG_WARNING,
05239                   "You must use bookmark AFTER line=>. Only one line is supported in this version\n");
05240             if (create) {
05241                ast_free(d);
05242                ast_free(l);
05243             }
05244             return NULL;
05245          }
05246          if (create) {
05247             ast_mutex_init(&l->lock);
05248          } else {
05249             d->to_delete = 0;
05250             /* reset bookmarks */
05251             memset(d->softkeylabel, 0, sizeof(d->softkeylabel));
05252             memset(d->softkeynumber, 0, sizeof(d->softkeynumber));
05253             memset(d->softkeyicon, 0, sizeof(d->softkeyicon));
05254             memset(d->softkeydevice, 0, sizeof(d->softkeydevice));
05255             memset(d->sp, 0, sizeof(d->sp));
05256          }
05257          ast_copy_string(l->name, v->value, sizeof(l->name));
05258          snprintf(l->fullname, sizeof(l->fullname), "USTM/%s@%s", l->name, d->name);
05259          d->softkeyicon[0] = FAV_ICON_ONHOOK_BLACK;
05260          if (!len)             /* label is undefined ? */
05261             ast_copy_string(d->softkeylabel[0], v->value, sizeof(d->softkeylabel[0]));
05262          else {
05263             if ((len > 2) && (linelabel[1] == '@')) {
05264                d->softkeylinepos = linelabel[0];
05265                if ((d->softkeylinepos >= '0') && (d->softkeylinepos <= '5')) {
05266                   d->softkeylinepos -= '0';
05267                   d->softkeyicon[0] = 0;
05268                } else {
05269                   ast_log(LOG_WARNING,
05270                         "Invalid position for linelabel : must be between 0 and 5\n");
05271                   d->softkeylinepos = 0;
05272                }
05273                ast_copy_string(d->softkeylabel[d->softkeylinepos], linelabel + 2,
05274                            sizeof(d->softkeylabel[d->softkeylinepos]));
05275                d->softkeyicon[d->softkeylinepos] = FAV_ICON_ONHOOK_BLACK;
05276             } else
05277                ast_copy_string(d->softkeylabel[0], linelabel,
05278                            sizeof(d->softkeylabel[0]));
05279          }
05280          nbsoftkey++;
05281          ast_copy_string(l->context, context, sizeof(l->context));
05282          if (!ast_strlen_zero(l->mailbox)) {
05283             if (unistimdebug)
05284                ast_verb(3, "Setting mailbox '%s' on %s@%s\n", l->mailbox, d->name, l->name);
05285          }
05286 
05287          l->capability = CAPABILITY;
05288          l->parent = d;
05289 
05290          if (create) {
05291             if (!alloc_sub(l, SUB_REAL)) {
05292                ast_mutex_destroy(&l->lock);
05293                ast_free(l);
05294                ast_free(d);
05295                return NULL;
05296             }
05297             l->next = d->lines;
05298             d->lines = l;
05299          }
05300       } else if (!strcasecmp(v->name, "height")) {
05301          /* Allow the user to lower the expected display lines on the phone
05302           * For example the Nortal I2001 and I2002 only have one ! */
05303          d->height = atoi(v->value);
05304       } else
05305          ast_log(LOG_WARNING, "Don't know keyword '%s' at line %d\n", v->name,
05306                v->lineno);
05307       v = v->next;
05308    }
05309    d->ringvolume = ringvolume;
05310    d->ringstyle = ringstyle;
05311    d->callhistory = callhistory;
05312    d->tz = ast_get_indication_zone(d->country);
05313    if ((d->tz == NULL) && !ast_strlen_zero(d->country))
05314       ast_log(LOG_WARNING, "Country '%s' was not found in indications.conf\n",
05315             d->country);
05316    d->datetimeformat = 56 + (dateformat * 4);
05317    d->datetimeformat += timeformat;
05318    if (!d->lines) {
05319       ast_log(LOG_ERROR, "An Unistim device must have at least one line!\n");
05320       ast_mutex_destroy(&l->lock);
05321       ast_free(l);
05322       if (d->tz) {
05323          d->tz = ast_tone_zone_unref(d->tz);
05324       }
05325       ast_free(d);
05326       return NULL;
05327    }
05328    if ((autoprovisioning == AUTOPROVISIONING_TN) &&
05329       (!ast_strlen_zero(d->extension_number))) {
05330       d->extension = EXTENSION_TN;
05331       if (!ast_strlen_zero(d->id))
05332          ast_log(LOG_WARNING,
05333                "tn= and device= can't be used together. Ignoring device= entry\n");
05334       d->id[0] = 'T';       /* magic : this is a tn entry */
05335       ast_copy_string((d->id) + 1, d->extension_number, sizeof(d->id) - 1);
05336       d->extension_number[0] = '\0';
05337    } else if (ast_strlen_zero(d->id)) {
05338       if (strcmp(d->name, "template")) {
05339          ast_log(LOG_ERROR, "You must specify the mac address with device=\n");
05340          ast_mutex_destroy(&l->lock);
05341          ast_free(l);
05342          if (d->tz) {
05343             d->tz = ast_tone_zone_unref(d->tz);
05344          }
05345          ast_free(d);
05346          return NULL;
05347       } else
05348          strcpy(d->id, "000000000000");
05349    }
05350    if (!d->rtp_port)
05351       d->rtp_port = 10000;
05352    if (d->contrast == -1)
05353       d->contrast = 8;
05354    if (ast_strlen_zero(d->maintext0))
05355       strcpy(d->maintext0, "Welcome");
05356    if (ast_strlen_zero(d->maintext1))
05357       strcpy(d->maintext1, d->name);
05358    if (ast_strlen_zero(d->titledefault)) {
05359       struct ast_tm tm = { 0, };
05360       struct timeval cur_time = ast_tvnow();
05361 
05362       if ((ast_localtime(&cur_time, &tm, 0)) == 0 || ast_strlen_zero(tm.tm_zone)) {
05363          display_last_error("Error in ast_localtime()");
05364          ast_copy_string(d->titledefault, "UNISTIM for*", 12);
05365       } else {
05366          if (strlen(tm.tm_zone) < 4) {
05367             strcpy(d->titledefault, "TimeZone ");
05368             strcat(d->titledefault, tm.tm_zone);
05369          } else if (strlen(tm.tm_zone) < 9) {
05370             strcpy(d->titledefault, "TZ ");
05371             strcat(d->titledefault, tm.tm_zone);
05372          } else
05373             ast_copy_string(d->titledefault, tm.tm_zone, 12);
05374       }
05375    }
05376    /* Update the chained link if it's a new device */
05377    if (create) {
05378       ast_mutex_lock(&devicelock);
05379       d->next = devices;
05380       devices = d;
05381       ast_mutex_unlock(&devicelock);
05382       ast_verb(3, "Added device '%s'\n", d->name);
05383    } else {
05384       ast_verb(3, "Device '%s' reloaded\n", d->name);
05385    }
05386    return d;
05387 }

static void cancel_dial ( struct unistimsession pte  )  [static]

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

01859 {
01860    send_no_ring(pte);
01861    pte->device->missed_call++;
01862    write_history(pte, 'i', 1);
01863    show_main_page(pte);
01864    return;
01865 }

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

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

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

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

Definition at line 1076 of file chan_unistim.c.

References unistimsession::device, 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().

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

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

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

03685 {
03686    struct unistim_subchannel *sub;
03687    if (!ast) {
03688       ast_log(LOG_WARNING, "Unistim callback function called with a null channel\n");
03689       return NULL;
03690    }
03691    if (!ast->tech_pvt) {
03692       ast_log(LOG_WARNING, "Unistim callback function called without a tech_pvt\n");
03693       return NULL;
03694    }
03695    sub = ast->tech_pvt;
03696 
03697    if (!sub->parent) {
03698       ast_log(LOG_WARNING, "Unistim callback function called without a line\n");
03699       return NULL;
03700    }
03701    if (!sub->parent->parent) {
03702       ast_log(LOG_WARNING, "Unistim callback function called without a device\n");
03703       return NULL;
03704    }
03705    if (!sub->parent->parent->session) {
03706       ast_log(LOG_WARNING, "Unistim callback function called without a session\n");
03707       return NULL;
03708    }
03709    return sub->parent->parent->session;
03710 }

static void check_send_queue ( struct unistimsession pte  )  [static]

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

00932 {
00933    /* Check if our send queue contained only one element */
00934    if (pte->last_buf_available == 1) {
00935       if (unistimdebug)
00936          ast_verb(6, "Our single packet was ACKed.\n");
00937       pte->last_buf_available--;
00938       set_ping_timer(pte);
00939       return;
00940    }
00941    /* Check if this ACK catch up our latest packet */
00942    else if (pte->last_seq_ack + 1 == pte->seq_server + 1) {
00943       if (unistimdebug)
00944          ast_verb(6, "Our send queue is completely ACKed.\n");
00945       pte->last_buf_available = 0;    /* Purge the send queue */
00946       set_ping_timer(pte);
00947       return;
00948    }
00949    if (unistimdebug)
00950       ast_verb(6, "We still have packets in our send queue\n");
00951    return;
00952 }

static void close_call ( struct unistimsession pte  )  [static]

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

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

static void close_client ( struct unistimsession s  )  [static]

Definition at line 1120 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, unistimdebug, and UnregisterExtension().

Referenced by parsing(), and send_retransmit().

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

static char* control2str ( int  ind  )  [static]

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

04101 {
04102    switch (ind) {
04103    case AST_CONTROL_HANGUP:
04104       return "Other end has hungup";
04105    case AST_CONTROL_RING:
04106       return "Local ring";
04107    case AST_CONTROL_RINGING:
04108       return "Remote end is ringing";
04109    case AST_CONTROL_ANSWER:
04110       return "Remote end has answered";
04111    case AST_CONTROL_BUSY:
04112       return "Remote end is busy";
04113    case AST_CONTROL_TAKEOFFHOOK:
04114       return "Make it go off hook";
04115    case AST_CONTROL_OFFHOOK:
04116       return "Line is off hook";
04117    case AST_CONTROL_CONGESTION:
04118       return "Congestion (circuits busy)";
04119    case AST_CONTROL_FLASH:
04120       return "Flash hook";
04121    case AST_CONTROL_WINK:
04122       return "Wink";
04123    case AST_CONTROL_OPTION:
04124       return "Set a low-level option";
04125    case AST_CONTROL_RADIO_KEY:
04126       return "Key Radio";
04127    case AST_CONTROL_RADIO_UNKEY:
04128       return "Un-Key Radio";
04129    case -1:
04130       return "Stop tone";
04131    }
04132    return "UNKNOWN";
04133 }

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

Definition at line 875 of file chan_unistim.c.

References ast_calloc, ast_inet_ntoa(), ast_mutex_init, ast_mutex_lock, ast_mutex_unlock, ast_verb, get_tick_count(), get_to_address(), MAX_BUF_NUMBER, RETRANSMIT_TIMER, sessionlock, and STATE_INIT.

Referenced by parsing().

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

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

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

00726 {
00727    time_t cur_time;
00728    
00729    time(&cur_time);
00730 
00731    /* Display the error message */
00732    ast_log(LOG_WARNING, "%s %s : (%u) %s\n", ctime(&cur_time), sz_msg, errno,
00733          strerror(errno));
00734 }

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

Definition at line 4599 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, io, 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_reloading, unistim_send_mwi_to_peer(), unistimsock, and unistimsock_read().

04600 {
04601    struct unistimsession *cur = NULL;
04602    unsigned int dw_timeout = 0;
04603    unsigned int tick;
04604    int res;
04605    int reloading;
04606 
04607    /* Add an I/O event to our UDP socket */
04608    if (unistimsock > -1)
04609       ast_io_add(io, unistimsock, unistimsock_read, AST_IO_IN, NULL);
04610 
04611    /* This thread monitors our UDP socket and timers */
04612    for (;;) {
04613       /* This loop is executed at least every IDLE_WAITus (1s) or every time a packet is received */
04614       /* Looking for the smallest time-out value */
04615       tick = get_tick_count();
04616       dw_timeout = UINT_MAX;
04617       ast_mutex_lock(&sessionlock);
04618       cur = sessions;
04619       DEBUG_TIMER("checking timeout for session %p with tick = %u\n", cur, tick);
04620       while (cur) {
04621          DEBUG_TIMER("checking timeout for session %p timeout = %u\n", cur,
04622                   cur->timeout);
04623          /* Check if we have miss something */
04624          if (cur->timeout <= tick) {
04625             DEBUG_TIMER("Event for session %p\n", cur);
04626             /* If the queue is empty, send a ping */
04627             if (cur->last_buf_available == 0)
04628                send_ping(cur);
04629             else {
04630                if (send_retransmit(cur)) {
04631                   DEBUG_TIMER("The chained link was modified, restarting...\n");
04632                   cur = sessions;
04633                   dw_timeout = UINT_MAX;
04634                   continue;
04635                }
04636             }
04637          }
04638          if (dw_timeout > cur->timeout - tick)
04639             dw_timeout = cur->timeout - tick;
04640          /* Checking if the phone is logged on for a new MWI */
04641          if (cur->device) {
04642             if ((!ast_strlen_zero(cur->device->lines->mailbox)) &&
04643                ((tick >= cur->device->lines->nextmsgcheck))) {
04644                DEBUG_TIMER("Checking mailbox for MWI\n");
04645                unistim_send_mwi_to_peer(cur, tick);
04646                break;
04647             }
04648          }
04649          cur = cur->next;
04650       }
04651       ast_mutex_unlock(&sessionlock);
04652       DEBUG_TIMER("Waiting for %dus\n", dw_timeout);
04653       res = dw_timeout;
04654       /* We should not wait more than IDLE_WAIT */
04655       if ((res < 0) || (res > IDLE_WAIT))
04656          res = IDLE_WAIT;
04657       /* Wait for UDP messages for a maximum of res us */
04658       res = ast_io_wait(io, res);     /* This function will call unistimsock_read if a packet is received */
04659       /* Check for a reload request */
04660       ast_mutex_lock(&unistim_reload_lock);
04661       reloading = unistim_reloading;
04662       unistim_reloading = 0;
04663       ast_mutex_unlock(&unistim_reload_lock);
04664       if (reloading) {
04665          ast_verb(1, "Reloading unistim.conf...\n");
04666          reload_config();
04667       }
04668       pthread_testcancel();
04669    }
04670    /* Never reached */
04671    return NULL;
04672 }

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

Definition at line 188 of file chan_unistim.c.

Referenced by app_exec(), ast_fdisset(), cc_request_state_change(), custom_log(), get_name_and_number(), handle_cli_misdn_send_facility(), manager_log(), osp_finish(), osp_lookup(), osp_validate_token(), packsms16(), packsms7(), packsms8(), parked_call_exec(), parse_args(), rcvfax_exec(), reload_config(), sndfax_exec(), syslog_log(), transmit_request_with_auth(), and write_cdr().

00189 {
00190    return;
00191 }

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

Definition at line 4221 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, unistim_line::subs, and unistimdebug.

Referenced by unistim_request(), and unistim_sp().

04222 {
04223    struct unistim_line *l;
04224    struct unistim_device *d;
04225    char line[256];
04226    char *at;
04227    char *device;
04228 
04229    ast_copy_string(line, dest, sizeof(line));
04230    at = strchr(line, '@');
04231    if (!at) {
04232       ast_log(LOG_NOTICE, "Device '%s' has no @ (at) sign!\n", dest);
04233       return NULL;
04234    }
04235    *at = '\0';
04236    at++;
04237    device = at;
04238    ast_mutex_lock(&devicelock);
04239    d = devices;
04240    at = strchr(device, '/');       /* Extra options ? */
04241    if (at)
04242       *at = '\0';
04243    while (d) {
04244       if (!strcasecmp(d->name, device)) {
04245          if (unistimdebug)
04246             ast_verb(0, "Found device: %s\n", d->name);
04247          /* Found the device */
04248          l = d->lines;
04249          while (l) {
04250             /* Search for the right line */
04251             if (!strcasecmp(l->name, line)) {
04252                l->subs[SUB_REAL]->ringvolume = -1;
04253                l->subs[SUB_REAL]->ringstyle = -1;
04254                if (at) {       /* Other options ? */
04255                   at++;   /* Skip slash */
04256                   if (*at == 'r') {       /* distinctive ring */
04257                      at++;
04258                      if ((*at < '0') || (*at > '7')) /* ring style */
04259                         ast_log(LOG_WARNING, "Invalid ring selection (%s)", at);
04260                      else {
04261                         char ring_volume = -1;
04262                         char ring_style = *at - '0';
04263                         at++;
04264                         if ((*at >= '0') && (*at <= '3'))       /* ring volume */
04265                            ring_volume = *at - '0';
04266                         if (unistimdebug)
04267                            ast_verb(0, "Distinctive ring : style #%d volume %d\n",
04268                                ring_style, ring_volume);
04269                         l->subs[SUB_REAL]->ringvolume = ring_volume;
04270                         l->subs[SUB_REAL]->ringstyle = ring_style;
04271                      }
04272                   }
04273                }
04274                ast_mutex_unlock(&devicelock);
04275                return l->subs[SUB_REAL];
04276             }
04277             l = l->next;
04278          }
04279       }
04280       d = d->next;
04281    }
04282    /* Device not found */
04283    ast_mutex_unlock(&devicelock);
04284 
04285    return NULL;
04286 }

static void finish_bookmark ( void   )  [static]

Definition at line 5065 of file chan_unistim.c.

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

05066 {
05067    struct unistim_device *d = devices;
05068    int i;
05069    while (d) {
05070       for (i = 0; i < 6; i++) {
05071          if (d->softkeyicon[i] == 1) {   /* Something for us */
05072             struct unistim_device *d2 = devices;
05073             while (d2) {
05074                if (!strcmp(d->softkeydevice[i], d2->name)) {
05075                   d->sp[i] = d2;
05076                   d->softkeyicon[i] = 0;
05077                   break;
05078                }
05079                d2 = d2->next;
05080             }
05081             if (d->sp[i] == NULL)
05082                ast_log(LOG_NOTICE, "Bookmark entry with device %s not found\n",
05083                      d->softkeydevice[i]);
05084          }
05085       }
05086       d = d->next;
05087    }
05088 }

static unsigned int get_tick_count ( void   )  [static]

Definition at line 736 of file chan_unistim.c.

References ast_tvnow().

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

00737 {
00738    struct timeval now = ast_tvnow();
00739 
00740    return (now.tv_sec * 1000) + (now.tv_usec / 1000);
00741 }

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

Definition at line 842 of file chan_unistim.c.

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

Referenced by create_client().

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

static void handle_dial_page ( struct unistimsession pte  )  [static]

Definition at line 2271 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::height, 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, and TEXT_NORMAL.

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

02272 {
02273    pte->state = STATE_DIALPAGE;
02274    if (pte->device->call_forward[0] == -1) {
02275       send_text(TEXT_LINE0, TEXT_NORMAL, pte, "");
02276       send_text(TEXT_LINE1, TEXT_NORMAL, pte, "Enter forward");
02277       send_text_status(pte, "ForwardCancel BackSpcErase");
02278       if (pte->device->call_forward[1] != 0) {
02279          char tmp[TEXT_LENGTH_MAX + 1];
02280 
02281          ast_copy_string(pte->device->phone_number, pte->device->call_forward + 1,
02282                      sizeof(pte->device->phone_number));
02283          pte->device->size_phone_number = strlen(pte->device->phone_number);
02284          if (pte->device->size_phone_number > 15)
02285             pte->device->size_phone_number = 15;
02286          strcpy(tmp, "Number : ...............");
02287          memcpy(tmp + 9, pte->device->phone_number, pte->device->size_phone_number);
02288 
02289          if (pte->device->height == 1) {
02290             send_text(TEXT_LINE0, TEXT_NORMAL, pte, tmp);
02291             send_blink_cursor(pte);
02292             send_cursor_pos(pte,
02293                     (unsigned char) (TEXT_LINE0 + 0x09 +
02294                                  pte->device->size_phone_number));
02295          } else {
02296             send_text(TEXT_LINE2, TEXT_NORMAL, pte, tmp);
02297             send_blink_cursor(pte);
02298             send_cursor_pos(pte,
02299                     (unsigned char) (TEXT_LINE2 + 0x09 +
02300                                  pte->device->size_phone_number));
02301          }
02302 
02303          send_led_update(pte, 0);
02304          return;
02305       }
02306    } else {
02307       if ((pte->device->output == OUTPUT_HANDSET) &&
02308          (pte->device->receiver_state == STATE_ONHOOK))
02309          send_select_output(pte, OUTPUT_SPEAKER, pte->device->volume, MUTE_OFF);
02310       else
02311          send_select_output(pte, pte->device->output, pte->device->volume, MUTE_OFF);
02312       SendDialTone(pte);
02313 
02314       if (pte->device->height > 1) {
02315          send_text(TEXT_LINE0, TEXT_NORMAL, pte, "Enter the number to dial");
02316          send_text(TEXT_LINE1, TEXT_NORMAL, pte, "and press Call");
02317       }
02318       send_text_status(pte, "Call   Redial BackSpcErase");
02319    }
02320 
02321    if (pte->device->height == 1) {
02322       send_text(TEXT_LINE0, TEXT_NORMAL, pte, "Number : ...............");
02323       send_blink_cursor(pte);
02324       send_cursor_pos(pte, TEXT_LINE0 + 0x09);
02325    } else {
02326       send_text(TEXT_LINE2, TEXT_NORMAL, pte, "Number : ...............");
02327       send_blink_cursor(pte);
02328       send_cursor_pos(pte, TEXT_LINE2 + 0x09);
02329    }
02330    pte->device->size_phone_number = 0;
02331    pte->device->phone_number[0] = 0;
02332    change_favorite_icon(pte, FAV_ICON_PHONE_BLACK);
02333    Sendicon(TEXT_LINE0, FAV_ICON_NONE, pte);
02334    pte->device->missed_call = 0;
02335    send_led_update(pte, 0);
02336    return;
02337 }

static void HandleCallIncoming ( struct unistimsession s  )  [static]

Definition at line 2486 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(), start_rtp(), unistimsession::state, STATE_CALL, STATE_ONHOOK, SUB_REAL, unistim_line::subs, TEXT_LINE2, TEXT_NORMAL, unistimdebug, and write_history().

Referenced by key_ringing(), and process_request().

02487 {
02488    struct unistim_subchannel *sub;
02489    s->state = STATE_CALL;
02490    s->device->missed_call = 0;
02491    send_no_ring(s);
02492    sub = s->device->lines->subs[SUB_REAL];
02493    if (!sub) {
02494       ast_log(LOG_NOTICE, "No available lines on: %s\n", s->device->name);
02495       return;
02496    } else if (unistimdebug)
02497       ast_verb(0, "Handle Call Incoming for %s@%s\n", sub->parent->name,
02498                s->device->name);
02499    start_rtp(sub);
02500    if (!sub->rtp)
02501       ast_log(LOG_WARNING, "Unable to create channel for %s@%s\n", sub->parent->name,
02502             s->device->name);
02503    ast_queue_control(sub->owner, AST_CONTROL_ANSWER);
02504    send_text(TEXT_LINE2, TEXT_NORMAL, s, "is on-line");
02505    send_text_status(s, "Hangup Transf");
02506    send_start_timer(s);
02507 
02508    if ((s->device->output == OUTPUT_HANDSET) &&
02509       (s->device->receiver_state == STATE_ONHOOK))
02510       send_select_output(s, OUTPUT_SPEAKER, s->device->volume, MUTE_OFF);
02511    else
02512       send_select_output(s, s->device->output, s->device->volume, MUTE_OFF);
02513    s->device->start_call_timestamp = time(0);
02514    write_history(s, 'i', 0);
02515    return;
02516 }

static void HandleCallOutgoing ( struct unistimsession s  )  [static]

Definition at line 2386 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::height, unistim_device::lines, LOG_NOTICE, LOG_WARNING, unistim_device::moh, MUTE_OFF, ast_channel::name, unistim_line::name, unistim_device::name, unistim_device::output, unistim_subchannel::owner, unistim_subchannel::parent, unistim_device::phone_number, unistim_subchannel::rtp, send_select_output(), send_text(), send_text_status(), send_tone(), unistim_device::silence_generator, start_rtp(), unistimsession::state, STATE_CALL, SUB_REAL, SUB_THREEWAY, unistim_line::subs, swap_subs(), TEXT_LINE0, TEXT_LINE1, TEXT_LINE2, TEXT_NORMAL, unistim_new(), unistim_ss(), unistimdebug, and unistim_device::volume.

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

02387 {
02388    struct ast_channel *c;
02389    struct unistim_subchannel *sub;
02390    pthread_t t;
02391    s->state = STATE_CALL;
02392    sub = s->device->lines->subs[SUB_REAL];
02393    if (!sub) {
02394       ast_log(LOG_NOTICE, "No available lines on: %s\n", s->device->name);
02395       return;
02396    }
02397    if (!sub->owner) {            /* A call is already in progress ? */
02398       c = unistim_new(sub, AST_STATE_DOWN, NULL);   /* No, starting a new one */
02399       if (c) {
02400          /* Need to start RTP before calling ast_pbx_run */
02401          if (!sub->rtp)
02402             start_rtp(sub);
02403          send_select_output(s, s->device->output, s->device->volume, MUTE_OFF);
02404 
02405          if (s->device->height == 1) {
02406             send_text(TEXT_LINE0, TEXT_NORMAL, s, s->device->phone_number);
02407          } else {
02408             send_text(TEXT_LINE0, TEXT_NORMAL, s, "Calling :");
02409             send_text(TEXT_LINE1, TEXT_NORMAL, s, s->device->phone_number);
02410             send_text(TEXT_LINE2, TEXT_NORMAL, s, "Dialing...");
02411          }
02412          send_text_status(s, "Hangup");
02413 
02414          /* start switch */
02415          if (ast_pthread_create(&t, NULL, unistim_ss, c)) {
02416             display_last_error("Unable to create switch thread");
02417             ast_queue_hangup_with_cause(c, AST_CAUSE_SWITCH_CONGESTION);
02418          }
02419       } else
02420          ast_log(LOG_WARNING, "Unable to create channel for %s@%s\n",
02421                sub->parent->name, s->device->name);
02422    } else {             /* We already have a call, so we switch in a threeway call */
02423 
02424       if (s->device->moh) {
02425          struct unistim_subchannel *subchannel;
02426          struct unistim_line *p = s->device->lines;
02427          subchannel = p->subs[SUB_REAL];
02428 
02429          if (!subchannel->owner) {
02430             ast_log(LOG_WARNING, "Unable to find subchannel for music on hold\n");
02431             return;
02432          }
02433          if (p->subs[SUB_THREEWAY]) {
02434             ast_log(LOG_WARNING,
02435                   "Can't transfer while an another transfer is taking place\n");
02436             return;
02437          }
02438          if (!alloc_sub(p, SUB_THREEWAY)) {
02439             ast_log(LOG_WARNING, "Unable to allocate three-way subchannel\n");
02440             return;
02441          }
02442          /* Stop the silence generator */
02443          if (s->device->silence_generator) {
02444             if (unistimdebug)
02445                ast_verb(0, "Stopping silence generator\n");
02446             ast_channel_stop_silence_generator(subchannel->owner,
02447                                        s->device->silence_generator);
02448             s->device->silence_generator = NULL;
02449          }
02450          send_tone(s, 0, 0);
02451          /* Make new channel */
02452          c = unistim_new(p->subs[SUB_THREEWAY], AST_STATE_DOWN, NULL);
02453          if (!c) {
02454             ast_log(LOG_WARNING, "Cannot allocate new structure on channel %p\n", p);
02455             return;
02456          }
02457          /* Swap things around between the three-way and real call */
02458          swap_subs(p, SUB_THREEWAY, SUB_REAL);
02459          send_select_output(s, s->device->output, s->device->volume, MUTE_OFF);
02460 
02461          if (s->device->height == 1) {
02462             send_text(TEXT_LINE0, TEXT_NORMAL, s, s->device->phone_number);
02463          } else {
02464             send_text(TEXT_LINE0, TEXT_NORMAL, s, "Calling (pre-transfer)");
02465             send_text(TEXT_LINE1, TEXT_NORMAL, s, s->device->phone_number);
02466             send_text(TEXT_LINE2, TEXT_NORMAL, s, "Dialing...");
02467          }
02468          send_text_status(s, "TransfrCancel");
02469 
02470          if (ast_pthread_create(&t, NULL, unistim_ss, p->subs[SUB_THREEWAY]->owner)) {
02471             ast_log(LOG_WARNING, "Unable to start simple switch on channel %p\n", p);
02472             ast_hangup(c);
02473             return;
02474          }
02475          if (unistimdebug)
02476             ast_verb(0, "Started three way call on channel %p (%s) subchan %d\n",
02477                 p->subs[SUB_THREEWAY]->owner, p->subs[SUB_THREEWAY]->owner->name,
02478                 p->subs[SUB_THREEWAY]->subtype);
02479       } else
02480          ast_debug(1, "Current sub [%s] already has owner\n", sub->owner->name);
02481    }
02482    return;
02483 }

static void HandleSelectCodec ( struct unistimsession pte  )  [static]

Definition at line 2833 of file chan_unistim.c.

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

Referenced by key_main_page().

02834 {
02835    char buf[30], buf2[5];
02836 
02837    pte->state = STATE_SELECTCODEC;
02838    strcpy(buf, "Using codec ");
02839    sprintf(buf2, "%d", pte->device->codec_number);
02840    strcat(buf, buf2);
02841    strcat(buf, " (G711u=0,");
02842 
02843    send_text(TEXT_LINE0, TEXT_NORMAL, pte, buf);
02844    send_text(TEXT_LINE1, TEXT_NORMAL, pte, "G723=4,G711a=8,G729A=18)");
02845    send_text(TEXT_LINE2, TEXT_INVERSE, pte, SELECTCODEC_MSG);
02846    send_blink_cursor(pte);
02847    send_cursor_pos(pte, TEXT_LINE2 + SELECTCODEC_START_ENTRY_POS);
02848    pte->size_buff_entry = 0;
02849    send_text_status(pte, "Select BackSpcErase  Cancel");
02850    return;
02851 }

static void IgnoreCall ( struct unistimsession pte  )  [static]

Definition at line 2011 of file chan_unistim.c.

References send_no_ring().

Referenced by key_ringing().

02012 {
02013    send_no_ring(pte);
02014    return;
02015 }

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

Definition at line 4135 of file chan_unistim.c.

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

Referenced by unistim_indicate().

04137 {
04138    struct ast_tone_zone_sound *ts = NULL;
04139 
04140    if ((ts = ast_get_indication_tone(tz, indication))) {
04141       ast_playtones_start(ast, 0, ts->data, 1);
04142       ts = ast_tone_zone_sound_unref(ts);
04143    } else {
04144       ast_log(LOG_WARNING, "Unable to get indication tone for %s\n", indication);
04145    }
04146 }

static void init_phone_step2 ( struct unistimsession pte  )  [static]

Definition at line 3349 of file chan_unistim.c.

References ast_verb, autoprovisioning, AUTOPROVISIONING_TN, BUFFSEND, unistim_device::contrast, unistimsession::device, unistimsession::macaddr, packet_send_arrow, packet_send_Contrast, packet_send_s4, packet_send_S7, packet_send_s9, 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, TEXT_NORMAL, and unistimdebug.

Referenced by process_request().

03350 {
03351    BUFFSEND;
03352    if (unistimdebug)
03353       ast_verb(0, "Sending S4\n");
03354    memcpy(buffsend + SIZE_HEADER, packet_send_s4, sizeof(packet_send_s4));
03355    send_client(SIZE_HEADER + sizeof(packet_send_s4), buffsend, pte);
03356    send_date_time2(pte);
03357    send_date_time3(pte);
03358    if (unistimdebug)
03359       ast_verb(0, "Sending S7\n");
03360    memcpy(buffsend + SIZE_HEADER, packet_send_S7, sizeof(packet_send_S7));
03361    send_client(SIZE_HEADER + sizeof(packet_send_S7), buffsend, pte);
03362    if (unistimdebug)
03363       ast_verb(0, "Sending Contrast\n");
03364    memcpy(buffsend + SIZE_HEADER, packet_send_Contrast, sizeof(packet_send_Contrast));
03365    if (pte->device != NULL)
03366       buffsend[9] = pte->device->contrast;
03367    send_client(SIZE_HEADER + sizeof(packet_send_Contrast), buffsend, pte);
03368 
03369    if (unistimdebug)
03370       ast_verb(0, "Sending S9\n");
03371    memcpy(buffsend + SIZE_HEADER, packet_send_s9, sizeof(packet_send_s9));
03372    send_client(SIZE_HEADER + sizeof(packet_send_s9), buffsend, pte);
03373    send_no_ring(pte);
03374 
03375    if (unistimdebug)
03376       ast_verb(0, "Sending S7\n");
03377    memcpy(buffsend + SIZE_HEADER, packet_send_S7, sizeof(packet_send_S7));
03378    send_client(SIZE_HEADER + sizeof(packet_send_S7), buffsend, pte);
03379    send_led_update(pte, 0);
03380    send_ping(pte);
03381    if (pte->state < STATE_MAINPAGE) {
03382       if (autoprovisioning == AUTOPROVISIONING_TN) {
03383          ShowExtensionPage(pte);
03384          return;
03385       } else {
03386          int i;
03387          char tmp[30];
03388 
03389          for (i = 1; i < 6; i++)
03390             send_favorite(i, 0, pte, "");
03391          send_text(TEXT_LINE0, TEXT_NORMAL, pte, "Sorry, this phone is not");
03392          send_text(TEXT_LINE1, TEXT_NORMAL, pte, "registered in unistim.cfg");
03393          strcpy(tmp, "MAC = ");
03394          strcat(tmp, pte->macaddr);
03395          send_text(TEXT_LINE2, TEXT_NORMAL, pte, tmp);
03396          send_text_status(pte, "");
03397          send_texttitle(pte, "UNISTIM for*");
03398          return;
03399       }
03400    }
03401    show_main_page(pte);
03402    refresh_all_favorite(pte);
03403    if (unistimdebug)
03404       ast_verb(0, "Sending arrow\n");
03405    memcpy(buffsend + SIZE_HEADER, packet_send_arrow, sizeof(packet_send_arrow));
03406    send_client(SIZE_HEADER + sizeof(packet_send_arrow), buffsend, pte);
03407    return;
03408 }

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

Definition at line 2590 of file chan_unistim.c.

References ast_bridged_channel(), ast_log(), ast_moh_start(), ast_moh_stop(), close_call(), KEY_0, KEY_FUNC1, KEY_FUNC2, KEY_HANGUP, KEY_HEADPHN, KEY_LOUDSPK, KEY_MUTE, KEY_ONHOLD, KEY_SHARP, KEY_STAR, LOG_WARNING, ast_channel::musicclass, MUTE_OFF, MUTE_ON, OUTPUT_HANDSET, OUTPUT_HEADPHONE, OUTPUT_SPEAKER, unistim_subchannel::owner, send_select_output(), SUB_REAL, TransferCallStep1(), and unistim_do_senddigit().

Referenced by process_request().

02591 {
02592    if ((keycode >= KEY_0) && (keycode <= KEY_SHARP)) {
02593       if (keycode == KEY_SHARP)
02594          keycode = '#';
02595       else if (keycode == KEY_STAR)
02596          keycode = '*';
02597       else
02598          keycode -= 0x10;
02599       unistim_do_senddigit(pte, keycode);
02600       return;
02601    }
02602    switch (keycode) {
02603    case KEY_HANGUP:
02604    case KEY_FUNC1:
02605       close_call(pte);
02606       break;
02607    case KEY_FUNC2:
02608       TransferCallStep1(pte);
02609       break;
02610    case KEY_HEADPHN:
02611       if (pte->device->output == OUTPUT_HEADPHONE)
02612          send_select_output(pte, OUTPUT_HANDSET, pte->device->volume, MUTE_OFF);
02613       else
02614          send_select_output(pte, OUTPUT_HEADPHONE, pte->device->volume, MUTE_OFF);
02615       break;
02616    case KEY_LOUDSPK:
02617       if (pte->device->output != OUTPUT_SPEAKER)
02618          send_select_output(pte, OUTPUT_SPEAKER, pte->device->volume, MUTE_OFF);
02619       else
02620          send_select_output(pte, pte->device->previous_output, pte->device->volume,
02621                       MUTE_OFF);
02622       break;
02623    case KEY_MUTE:
02624       if (!pte->device->moh) {
02625          if (pte->device->mute == MUTE_ON)
02626             send_select_output(pte, pte->device->output, pte->device->volume, MUTE_OFF);
02627          else
02628             send_select_output(pte, pte->device->output, pte->device->volume, MUTE_ON);
02629          break;
02630       }
02631    case KEY_ONHOLD:
02632       {
02633          struct unistim_subchannel *sub;
02634          struct ast_channel *bridgepeer = NULL;
02635          sub = pte->device->lines->subs[SUB_REAL];
02636          if (!sub->owner) {
02637             ast_log(LOG_WARNING, "Unable to find subchannel for music on hold\n");
02638             return;
02639          }
02640          if ((bridgepeer = ast_bridged_channel(sub->owner))) {
02641             if (pte->device->moh) {
02642                ast_moh_stop(bridgepeer);
02643                pte->device->moh = 0;
02644                send_select_output(pte, pte->device->output, pte->device->volume,
02645                             MUTE_OFF);
02646             } else {
02647                ast_moh_start(bridgepeer, pte->device->lines->musicclass, NULL);
02648                pte->device->moh = 1;
02649                send_select_output(pte, pte->device->output, pte->device->volume,
02650                             MUTE_ON);
02651             }
02652          } else
02653             ast_log(LOG_WARNING,
02654                   "Unable to find peer subchannel for music on hold\n");
02655          break;
02656       }
02657    }
02658    return;
02659 }

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

Definition at line 2698 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(), unistim_device::height, 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_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, unistimdebug, and unistim_device::volume.

Referenced by key_main_page(), and process_request().

02699 {
02700    if (keycode == KEY_FUNC3) {
02701       if (pte->device->size_phone_number <= 1)
02702          keycode = KEY_FUNC4;
02703       else {
02704          pte->device->size_phone_number -= 2;
02705          keycode = pte->device->phone_number[pte->device->size_phone_number] + 0x10;
02706       }
02707    }
02708    if ((keycode >= KEY_0) && (keycode <= KEY_SHARP)) {
02709       char tmpbuf[] = "Number : ...............";
02710       int i = 0;
02711 
02712       if (pte->device->size_phone_number >= 15)
02713          return;
02714       if (pte->device->size_phone_number == 0)
02715          send_tone(pte, 0, 0);
02716       while (i < pte->device->size_phone_number) {
02717          tmpbuf[i + 9] = pte->device->phone_number[i];
02718          i++;
02719       }
02720       if (keycode == KEY_SHARP)
02721          keycode = '#';
02722       else if (keycode == KEY_STAR)
02723          keycode = '*';
02724       else
02725          keycode -= 0x10;
02726       tmpbuf[i + 9] = keycode;
02727       pte->device->phone_number[i] = keycode;
02728       pte->device->size_phone_number++;
02729       pte->device->phone_number[i + 1] = 0;
02730       if (pte->device->height == 1) {
02731          send_text(TEXT_LINE0, TEXT_NORMAL, pte, tmpbuf);
02732       } else {
02733          send_text(TEXT_LINE2, TEXT_NORMAL, pte, tmpbuf);
02734       }
02735       send_blink_cursor(pte);
02736       send_cursor_pos(pte, (unsigned char) (TEXT_LINE2 + 0x0a + i));
02737       return;
02738    }
02739    if (keycode == KEY_FUNC4) {
02740 
02741       pte->device->size_phone_number = 0;
02742       if (pte->device->height == 1) {
02743          send_text(TEXT_LINE0, TEXT_NORMAL, pte, "Number : ...............");
02744          send_blink_cursor(pte);
02745          send_cursor_pos(pte, TEXT_LINE0 + 0x09);
02746       } else {
02747          send_text(TEXT_LINE2, TEXT_NORMAL, pte, "Number : ...............");
02748          send_blink_cursor(pte);
02749          send_cursor_pos(pte, TEXT_LINE2 + 0x09);
02750       }
02751       return;
02752    }
02753 
02754    if (pte->device->call_forward[0] == -1) {
02755       if (keycode == KEY_FUNC1) {
02756          ast_copy_string(pte->device->call_forward, pte->device->phone_number,
02757                      sizeof(pte->device->call_forward));
02758          show_main_page(pte);
02759       } else if ((keycode == KEY_FUNC2) || (keycode == KEY_HANGUP)) {
02760          pte->device->call_forward[0] = '\0';
02761          show_main_page(pte);
02762       }
02763       return;
02764    }
02765    switch (keycode) {
02766    case KEY_FUNC2:
02767       if (ast_strlen_zero(pte->device->redial_number))
02768          break;
02769       ast_copy_string(pte->device->phone_number, pte->device->redial_number,
02770                   sizeof(pte->device->phone_number));
02771    case KEY_FUNC1:
02772       HandleCallOutgoing(pte);
02773       break;
02774    case KEY_HANGUP:
02775       if (pte->device->lines->subs[SUB_REAL]->owner) {
02776          /* Stop the silence generator */
02777          if (pte->device->silence_generator) {
02778             if (unistimdebug)
02779                ast_verb(0, "Stopping silence generator\n");
02780             ast_channel_stop_silence_generator(pte->device->lines->subs[SUB_REAL]->
02781                                        owner, pte->device->silence_generator);
02782             pte->device->silence_generator = NULL;
02783          }
02784          send_tone(pte, 0, 0);
02785          ast_moh_stop(ast_bridged_channel(pte->device->lines->subs[SUB_REAL]->owner));
02786          pte->device->moh = 0;
02787          pte->state = STATE_CALL;
02788 
02789          if (pte->device->height == 1) {
02790             send_text(TEXT_LINE0, TEXT_NORMAL, pte, "Dial Cancel,back to priv. call.");
02791          } else {
02792             send_text(TEXT_LINE0, TEXT_NORMAL, pte, "Dialing canceled,");
02793             send_text(TEXT_LINE1, TEXT_NORMAL, pte, "switching back to");
02794             send_text(TEXT_LINE2, TEXT_NORMAL, pte, "previous call.");
02795          }
02796          send_text_status(pte, "Hangup Transf");
02797       } else
02798          show_main_page(pte);
02799       break;
02800    case KEY_FAV1:
02801    case KEY_FAV2:
02802    case KEY_FAV3:
02803    case KEY_FAV4:
02804    case KEY_FAV5:
02805       Keyfavorite(pte, keycode);
02806       break;
02807    case KEY_LOUDSPK:
02808       if (pte->device->output == OUTPUT_SPEAKER) {
02809          if (pte->device->receiver_state == STATE_OFFHOOK)
02810             send_select_output(pte, pte->device->previous_output, pte->device->volume,
02811                          MUTE_OFF);
02812          else
02813             show_main_page(pte);
02814       } else
02815          send_select_output(pte, OUTPUT_SPEAKER, pte->device->volume, MUTE_OFF);
02816       break;
02817    case KEY_HEADPHN:
02818       if (pte->device->output == OUTPUT_HEADPHONE) {
02819          if (pte->device->receiver_state == STATE_OFFHOOK)
02820             send_select_output(pte, OUTPUT_HANDSET, pte->device->volume, MUTE_OFF);
02821          else
02822             show_main_page(pte);
02823       } else
02824          send_select_output(pte, OUTPUT_HEADPHONE, pte->device->volume, MUTE_OFF);
02825       break;
02826    }
02827    return;
02828 }

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

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

03282 {
03283    FILE *f;
03284    char count;
03285    long offset;
03286 
03287    switch (keycode) {
03288    case KEY_UP:
03289    case KEY_LEFT:
03290    case KEY_FUNC1:
03291       if (pte->buff_entry[2] <= 1)
03292          return;
03293       pte->buff_entry[2]--;
03294       count = OpenHistory(pte, pte->buff_entry[0], &f);
03295       if (!count)
03296          return;
03297       offset = ((pte->buff_entry[2] - 1) * TEXT_LENGTH_MAX * 3);
03298       if (fseek(f, offset, SEEK_CUR)) {
03299          display_last_error("Unable to seek history entry.");
03300          fclose(f);
03301          return;
03302       }
03303       show_entry_history(pte, &f);
03304       break;
03305    case KEY_DOWN:
03306    case KEY_RIGHT:
03307    case KEY_FUNC2:
03308       if (pte->buff_entry[2] >= pte->buff_entry[1])
03309          return;
03310       pte->buff_entry[2]++;
03311       count = OpenHistory(pte, pte->buff_entry[0], &f);
03312       if (!count)
03313          return;
03314       offset = ((pte->buff_entry[2] - 1) * TEXT_LENGTH_MAX * 3);
03315       if (fseek(f, offset, SEEK_CUR)) {
03316          display_last_error("Unable to seek history entry.");
03317          fclose(f);
03318          return;
03319       }
03320       show_entry_history(pte, &f);
03321       break;
03322    case KEY_FUNC3:
03323       if (!ReformatNumber(pte->device->lst_cid))
03324          break;
03325       ast_copy_string(pte->device->redial_number, pte->device->lst_cid,
03326                   sizeof(pte->device->redial_number));
03327       key_main_page(pte, KEY_FUNC2);
03328       break;
03329    case KEY_FUNC4:
03330    case KEY_HANGUP:
03331       show_main_page(pte);
03332       break;
03333    case KEY_SNDHIST:
03334       if (pte->buff_entry[0] == 'i')
03335          show_history(pte, 'o');
03336       else
03337          show_main_page(pte);
03338       break;
03339    case KEY_RCVHIST:
03340       if (pte->buff_entry[0] == 'i')
03341          show_main_page(pte);
03342       else
03343          show_history(pte, 'i');
03344       break;
03345    }
03346    return;
03347 }

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

Definition at line 3187 of file chan_unistim.c.

References ast_copy_string(), ast_mutex_lock, ast_mutex_unlock, ast_strlen_zero(), unistimsession::device, devicelock, EXTENSION_ASK, EXTENSION_TN, FAV_ICON_NONE, handle_dial_page(), HandleCallOutgoing(), HandleSelectCodec(), 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, OUTPUT_HANDSET, OUTPUT_HEADPHONE, OUTPUT_SPEAKER, send_select_output(), Sendicon(), show_history(), show_main_page(), ShowExtensionPage(), STATE_ONHOOK, TEXT_LINE0, and UnregisterExtension().

Referenced by key_history(), and process_request().

03188 {
03189    if (pte->device->missed_call) {
03190       Sendicon(TEXT_LINE0, FAV_ICON_NONE, pte);
03191       pte->device->missed_call = 0;
03192    }
03193    if ((keycode >= KEY_0) && (keycode <= KEY_SHARP)) {
03194       handle_dial_page(pte);
03195       key_dial_page(pte, keycode);
03196       return;
03197    }
03198    switch (keycode) {
03199    case KEY_FUNC1:
03200       handle_dial_page(pte);
03201       break;
03202    case KEY_FUNC2:
03203       if (ast_strlen_zero(pte->device->redial_number))
03204          break;
03205       if ((pte->device->output == OUTPUT_HANDSET) &&
03206          (pte->device->receiver_state == STATE_ONHOOK))
03207          send_select_output(pte, OUTPUT_SPEAKER, pte->device->volume, MUTE_OFF);
03208       else
03209          send_select_output(pte, pte->device->output, pte->device->volume, MUTE_OFF);
03210 
03211       ast_copy_string(pte->device->phone_number, pte->device->redial_number,
03212                   sizeof(pte->device->phone_number));
03213       HandleCallOutgoing(pte);
03214       break;
03215    case KEY_FUNC3:
03216       if (!ast_strlen_zero(pte->device->call_forward)) {
03217          /* Cancel call forwarding */
03218          memmove(pte->device->call_forward + 1, pte->device->call_forward,
03219                sizeof(pte->device->call_forward) - 1);
03220          pte->device->call_forward[0] = '\0';
03221          Sendicon(TEXT_LINE0, FAV_ICON_NONE, pte);
03222          pte->device->output = OUTPUT_HANDSET;   /* Seems to be reseted somewhere */
03223          show_main_page(pte);
03224          break;
03225       }
03226       pte->device->call_forward[0] = -1;
03227       handle_dial_page(pte);
03228       break;
03229    case KEY_FUNC4:
03230       if (pte->device->extension == EXTENSION_ASK) {
03231          UnregisterExtension(pte);
03232          pte->device->extension_number[0] = '\0';
03233          ShowExtensionPage(pte);
03234       } else if (pte->device->extension == EXTENSION_TN) {
03235          ast_mutex_lock(&devicelock);
03236          strcpy(pte->device->id, pte->device->extension_number);
03237          pte->buff_entry[0] = '\0';
03238          pte->size_buff_entry = 0;
03239          pte->device->session = NULL;
03240          pte->device = NULL;
03241          ast_mutex_unlock(&devicelock);
03242          ShowExtensionPage(pte);
03243       }
03244       break;
03245    case KEY_FAV0:
03246       handle_dial_page(pte);
03247       break;
03248    case KEY_FAV1:
03249    case KEY_FAV2:
03250    case KEY_FAV3:
03251    case KEY_FAV4:
03252    case KEY_FAV5:
03253       if ((pte->device->output == OUTPUT_HANDSET) &&
03254          (pte->device->receiver_state == STATE_ONHOOK))
03255          send_select_output(pte, OUTPUT_SPEAKER, pte->device->volume, MUTE_OFF);
03256       else
03257          send_select_output(pte, pte->device->output, pte->device->volume, MUTE_OFF);
03258       Keyfavorite(pte, keycode);
03259       break;
03260    case KEY_CONF:
03261       HandleSelectCodec(pte);
03262       break;
03263    case KEY_LOUDSPK:
03264       send_select_output(pte, OUTPUT_SPEAKER, pte->device->volume, MUTE_OFF);
03265       handle_dial_page(pte);
03266       break;
03267    case KEY_HEADPHN:
03268       send_select_output(pte, OUTPUT_HEADPHONE, pte->device->volume, MUTE_OFF);
03269       handle_dial_page(pte);
03270       break;
03271    case KEY_SNDHIST:
03272       show_history(pte, 'o');
03273       break;
03274    case KEY_RCVHIST:
03275       show_history(pte, 'i');
03276       break;
03277    }
03278    return;
03279 }

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

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

02662 {
02663    if (keycode == KEY_FAV0 + pte->device->softkeylinepos) {
02664       HandleCallIncoming(pte);
02665       return;
02666    }
02667    switch (keycode) {
02668    case KEY_HANGUP:
02669    case KEY_FUNC4:
02670       IgnoreCall(pte);
02671       break;
02672    case KEY_FUNC1:
02673       HandleCallIncoming(pte);
02674       break;
02675    }
02676    return;
02677 }

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

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

02854 {
02855    if (keycode == KEY_FUNC2) {
02856       if (pte->size_buff_entry <= 1)
02857          keycode = KEY_FUNC3;
02858       else {
02859          pte->size_buff_entry -= 2;
02860          keycode = pte->buff_entry[pte->size_buff_entry] + 0x10;
02861       }
02862    }
02863    if ((keycode >= KEY_0) && (keycode <= KEY_9)) {
02864       char tmpbuf[] = SELECTCODEC_MSG;
02865       int i = 0;
02866 
02867       if (pte->size_buff_entry >= SELECTCODEC_MAX_LENGTH)
02868          return;
02869 
02870       while (i < pte->size_buff_entry) {
02871          tmpbuf[i + SELECTCODEC_START_ENTRY_POS] = pte->buff_entry[i];
02872          i++;
02873       }
02874       tmpbuf[i + SELECTCODEC_START_ENTRY_POS] = keycode - 0x10;
02875       pte->buff_entry[i] = keycode - 0x10;
02876       pte->size_buff_entry++;
02877       send_text(TEXT_LINE2, TEXT_INVERSE, pte, tmpbuf);
02878       send_blink_cursor(pte);
02879       send_cursor_pos(pte,
02880                  (unsigned char) (TEXT_LINE2 + SELECTCODEC_START_ENTRY_POS + 1 + i));
02881       return;
02882    }
02883 
02884    switch (keycode) {
02885    case KEY_FUNC1:
02886       if (pte->size_buff_entry == 1)
02887          pte->device->codec_number = pte->buff_entry[0] - 48;
02888       else if (pte->size_buff_entry == 2)
02889          pte->device->codec_number =
02890             ((pte->buff_entry[0] - 48) * 10) + (pte->buff_entry[1] - 48);
02891       show_main_page(pte);
02892       break;
02893    case KEY_FUNC3:
02894       pte->size_buff_entry = 0;
02895       send_text(TEXT_LINE2, TEXT_INVERSE, pte, SELECTCODEC_MSG);
02896       send_blink_cursor(pte);
02897       send_cursor_pos(pte, TEXT_LINE2 + SELECTCODEC_START_ENTRY_POS);
02898       break;
02899    case KEY_HANGUP:
02900    case KEY_FUNC4:
02901       show_main_page(pte);
02902       break;
02903    }
02904    return;
02905 }

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

Definition at line 2924 of file chan_unistim.c.

References ast_copy_string(), ast_mutex_lock, ast_mutex_unlock, autoprovisioning, 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().

02925 {
02926    if (keycode == KEY_FUNC2) {
02927       if (pte->size_buff_entry <= 1)
02928          keycode = KEY_FUNC3;
02929       else {
02930          pte->size_buff_entry -= 2;
02931          keycode = pte->buff_entry[pte->size_buff_entry] + 0x10;
02932       }
02933    }
02934    if ((keycode >= KEY_0) && (keycode <= KEY_9)) {
02935       char tmpbuf[] = SELECTEXTENSION_MSG;
02936       int i = 0;
02937 
02938       if (pte->size_buff_entry >= SELECTEXTENSION_MAX_LENGTH)
02939          return;
02940 
02941       while (i < pte->size_buff_entry) {
02942          tmpbuf[i + SELECTEXTENSION_START_ENTRY_POS] = pte->buff_entry[i];
02943          i++;
02944       }
02945       tmpbuf[i + SELECTEXTENSION_START_ENTRY_POS] = keycode - 0x10;
02946       pte->buff_entry[i] = keycode - 0x10;
02947       pte->size_buff_entry++;
02948       send_text(TEXT_LINE2, TEXT_NORMAL, pte, tmpbuf);
02949       send_blink_cursor(pte);
02950       send_cursor_pos(pte,
02951                  (unsigned char) (TEXT_LINE2 + SELECTEXTENSION_START_ENTRY_POS + 1 +
02952                               i));
02953       return;
02954    }
02955 
02956    switch (keycode) {
02957    case KEY_FUNC1:
02958       if (pte->size_buff_entry < 1)
02959          return;
02960       if (autoprovisioning == AUTOPROVISIONING_TN) {
02961          struct unistim_device *d;
02962 
02963          /* First step : looking for this TN in our device list */
02964          ast_mutex_lock(&devicelock);
02965          d = devices;
02966          pte->buff_entry[pte->size_buff_entry] = '\0';
02967          while (d) {
02968             if (d->id[0] == 'T') {  /* It's a TN device ? */
02969                /* It's the TN we're looking for ? */
02970                if (!strcmp((d->id) + 1, pte->buff_entry)) {
02971                   pte->device = d;
02972                   d->session = pte;
02973                   d->codec_number = DEFAULT_CODEC;
02974                   d->pos_fav = 0;
02975                   d->missed_call = 0;
02976                   d->receiver_state = STATE_ONHOOK;
02977                   strcpy(d->id, pte->macaddr);
02978                   pte->device->extension_number[0] = 'T';
02979                   pte->device->extension = EXTENSION_TN;
02980                   ast_copy_string((pte->device->extension_number) + 1,
02981                               pte->buff_entry, pte->size_buff_entry + 1);
02982                   ast_mutex_unlock(&devicelock);
02983                   show_main_page(pte);
02984                   refresh_all_favorite(pte);
02985                   return;
02986                }
02987             }
02988             d = d->next;
02989          }
02990          ast_mutex_unlock(&devicelock);
02991          send_text(TEXT_LINE0, TEXT_NORMAL, pte, "Invalid Terminal Number.");
02992          send_text(TEXT_LINE1, TEXT_NORMAL, pte, "Please try again :");
02993          send_cursor_pos(pte,
02994                     (unsigned char) (TEXT_LINE2 + SELECTEXTENSION_START_ENTRY_POS +
02995                                  pte->size_buff_entry));
02996          send_blink_cursor(pte);
02997       } else {
02998          ast_copy_string(pte->device->extension_number, pte->buff_entry,
02999                      pte->size_buff_entry + 1);
03000          if (RegisterExtension(pte)) {
03001             send_text(TEXT_LINE0, TEXT_NORMAL, pte, "Invalid extension.");
03002             send_text(TEXT_LINE1, TEXT_NORMAL, pte, "Please try again :");
03003             send_cursor_pos(pte,
03004                        (unsigned char) (TEXT_LINE2 +
03005                                     SELECTEXTENSION_START_ENTRY_POS +
03006                                     pte->size_buff_entry));
03007             send_blink_cursor(pte);
03008          } else
03009             show_main_page(pte);
03010       }
03011       break;
03012    case KEY_FUNC3:
03013       pte->size_buff_entry = 0;
03014       send_text(TEXT_LINE2, TEXT_NORMAL, pte, SELECTEXTENSION_MSG);
03015       send_blink_cursor(pte);
03016       send_cursor_pos(pte, TEXT_LINE2 + SELECTEXTENSION_START_ENTRY_POS);
03017       break;
03018    }
03019    return;
03020 }

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

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

02680 {
02681    int fav;
02682 
02683    if ((keycode < KEY_FAV1) && (keycode > KEY_FAV5)) {
02684       ast_log(LOG_WARNING, "It's not a favorite key\n");
02685       return;
02686    }
02687    if (keycode == KEY_FAV0)
02688       return;
02689    fav = keycode - KEY_FAV0;
02690    if (pte->device->softkeyicon[fav] == 0)
02691       return;
02692    ast_copy_string(pte->device->phone_number, pte->device->softkeynumber[fav],
02693                sizeof(pte->device->phone_number));
02694    HandleCallOutgoing(pte);
02695    return;
02696 }

int load_module ( void   )  [static]

Definition at line 5642 of file chan_unistim.c.

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

05643 {
05644    int res;
05645 
05646    if (!(buff = ast_malloc(SIZE_PAGE)))
05647       goto buff_failed;
05648 
05649    io = io_context_create();
05650    if (!io) {
05651       ast_log(LOG_ERROR, "Failed to allocate IO context\n");
05652       goto io_failed;
05653    }
05654 
05655    sched = sched_context_create();
05656    if (!sched) {
05657       ast_log(LOG_ERROR, "Failed to allocate scheduler context\n");
05658       goto sched_failed;
05659    }
05660 
05661    res = reload_config();
05662    if (res)
05663       return AST_MODULE_LOAD_DECLINE;
05664 
05665    /* Make sure we can register our unistim channel type */
05666    if (ast_channel_register(&unistim_tech)) {
05667       ast_log(LOG_ERROR, "Unable to register channel type '%s'\n", channel_type);
05668       goto chanreg_failed;
05669    } 
05670 
05671    ast_rtp_glue_register(&unistim_rtp_glue);
05672 
05673    ast_cli_register_multiple(unistim_cli, ARRAY_LEN(unistim_cli));
05674 
05675    restart_monitor();
05676 
05677    return AST_MODULE_LOAD_SUCCESS;
05678 
05679 chanreg_failed:
05680    /*! XXX \todo Leaking anything allocated by reload_config() ... */
05681    sched_context_destroy(sched);
05682    sched = NULL;
05683 sched_failed:
05684    io_context_destroy(io);
05685    io = NULL;
05686 io_failed:
05687    ast_free(buff);
05688    buff = NULL;
05689 buff_failed:
05690    return AST_MODULE_LOAD_FAILURE;
05691 }

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

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

03090 {
03091    char tmp[AST_CONFIG_MAX_PATH];
03092    char count;
03093 
03094    snprintf(tmp, sizeof(tmp), "%s/%s/%s-%c.csv", ast_config_AST_LOG_DIR,
03095           USTM_LOG_DIR, pte->device->name, way);
03096    *f = fopen(tmp, "r");
03097    if (!*f) {
03098       display_last_error("Unable to open history file");
03099       return 0;
03100    }
03101    if (fread(&count, 1, 1, *f) != 1) {
03102       display_last_error("Unable to read history header - display.");
03103       fclose(*f);
03104       return 0;
03105    }
03106    if (count > MAX_ENTRY_LOG) {
03107       ast_log(LOG_WARNING, "Invalid count in history header of %s (%d max %d)\n", tmp,
03108             count, MAX_ENTRY_LOG);
03109       fclose(*f);
03110       return 0;
03111    }
03112    return count;
03113 }

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

Definition at line 4984 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, unistim_device::softkeynumber, and unistimdebug.

Referenced by build_device().

04985 {
04986    char line[256];
04987    char *at;
04988    char *number;
04989    char *icon;
04990    int p;
04991    int len = strlen(text);
04992 
04993    ast_copy_string(line, text, sizeof(line));
04994    /* Position specified ? */
04995    if ((len > 2) && (line[1] == '@')) {
04996       p = line[0];
04997       if ((p >= '0') && (p <= '5'))
04998          p -= '0';
04999       else {
05000          ast_log(LOG_WARNING,
05001                "Invalid position for bookmark : must be between 0 and 5\n");
05002          return 0;
05003       }
05004       if (d->softkeyicon[p] != 0) {
05005          ast_log(LOG_WARNING, "Invalid position %d for bookmark : already used\n:", p);
05006          return 0;
05007       }
05008       memmove(line, line + 2, sizeof(line) - 2);
05009    } else {
05010       /* No position specified, looking for a free slot */
05011       for (p = 0; p <= 5; p++) {
05012          if (!d->softkeyicon[p])
05013             break;
05014       }
05015       if (p > 5) {
05016          ast_log(LOG_WARNING, "No more free bookmark position\n");
05017          return 0;
05018       }
05019    }
05020    at = strchr(line, '@');
05021    if (!at) {
05022       ast_log(LOG_NOTICE, "Bookmark entry '%s' has no @ (at) sign!\n", text);
05023       return 0;
05024    }
05025    *at = '\0';
05026    at++;
05027    number = at;
05028    at = strchr(at, '@');
05029    if (ast_strlen_zero(number)) {
05030       ast_log(LOG_NOTICE, "Bookmark entry '%s' has no number\n", text);
05031       return 0;
05032    }
05033    if (ast_strlen_zero(line)) {
05034       ast_log(LOG_NOTICE, "Bookmark entry '%s' has no description\n", text);
05035       return 0;
05036    }
05037 
05038    at = strchr(number, '@');
05039    if (!at)
05040       d->softkeyicon[p] = FAV_ICON_SHARP;     /* default icon */
05041    else {
05042       *at = '\0';
05043       at++;
05044       icon = at;
05045       if (ast_strlen_zero(icon)) {
05046          ast_log(LOG_NOTICE, "Bookmark entry '%s' has no icon value\n", text);
05047          return 0;
05048       }
05049       if (strncmp(icon, "USTM/", 5))
05050          d->softkeyicon[p] = atoi(icon);
05051       else {
05052          d->softkeyicon[p] = 1;
05053          ast_copy_string(d->softkeydevice[p], icon + 5, sizeof(d->softkeydevice[p]));
05054       }
05055    }
05056    ast_copy_string(d->softkeylabel[p], line, sizeof(d->softkeylabel[p]));
05057    ast_copy_string(d->softkeynumber[p], number, sizeof(d->softkeynumber[p]));
05058    if (unistimdebug)
05059       ast_verb(0, "New bookmark at pos %d label='%s' number='%s' icon=%x\n",
05060                p, d->softkeylabel[p], d->softkeynumber[p], d->softkeyicon[p]);
05061    return 1;
05062 }

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

Definition at line 3529 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, packet_rcv_discovery, packet_send_discovery_ack, process_request(), send_raw_client(), send_retransmit(), seq, unistimsession::seq_phone, unistimsession::seq_server, SIZE_HEADER, unistimsession::sout, unistimsession::state, STATE_INIT, and unistimdebug.

Referenced by unistimsock_read().

03531 {
03532    unsigned short *sbuf = (unsigned short *) buf;
03533    unsigned short seq;
03534    char tmpbuf[255];
03535 
03536    strcpy(tmpbuf, ast_inet_ntoa(addr_from->sin_addr));
03537 
03538    if (size < 10) {
03539       if (size == 0) {
03540          ast_log(LOG_WARNING, "%s Read error\n", tmpbuf);
03541       } else {
03542          ast_log(LOG_NOTICE, "%s Packet too short - ignoring\n", tmpbuf);
03543       }
03544       return;
03545    }
03546    if (sbuf[0] == 0xffff) {   /* Starting with 0xffff ? *//* Yes, discovery packet ? */
03547       if (size != sizeof(packet_rcv_discovery)) {
03548          ast_log(LOG_NOTICE, "%s Invalid size of a discovery packet\n", tmpbuf);
03549       } else {
03550          if (memcmp(buf, packet_rcv_discovery, sizeof(packet_rcv_discovery)) == 0) {
03551             if (unistimdebug)
03552                ast_verb(0, "Discovery packet received - Sending Discovery ACK\n");
03553             if (pte) {        /* A session was already active for this IP ? */
03554                if (pte->state == STATE_INIT) { /* Yes, but it's a dupe */
03555                   if (unistimdebug)
03556                      ast_verb(1, "Duplicated Discovery packet\n");
03557                   send_raw_client(sizeof(packet_send_discovery_ack),
03558                              packet_send_discovery_ack, addr_from, &pte->sout);
03559                   pte->seq_phone = (short) 0x0000; /* reset sequence number */
03560                } else { /* No, probably a reboot, phone side */
03561                   close_client(pte);       /* Cleanup the previous session */
03562                   if (create_client(addr_from))
03563                      send_raw_client(sizeof(packet_send_discovery_ack),
03564                                 packet_send_discovery_ack, addr_from, &pte->sout);
03565                }
03566             } else {
03567                /* Creating new entry in our phone list */
03568                if ((pte = create_client(addr_from)))
03569                   send_raw_client(sizeof(packet_send_discovery_ack),
03570                              packet_send_discovery_ack, addr_from, &pte->sout);
03571             }
03572             return;
03573          }
03574          ast_log(LOG_NOTICE, "%s Invalid discovery packet\n", tmpbuf);
03575       }
03576       return;
03577    }
03578    if (!pte) {
03579       if (unistimdebug)
03580          ast_verb(0, "%s Not a discovery packet from an unknown source : ignoring\n",
03581                   tmpbuf);
03582       return;
03583    }
03584 
03585    if (sbuf[0] != 0) {          /* Starting with something else than 0x0000 ? */
03586       ast_log(LOG_NOTICE, "Unknown packet received - ignoring\n");
03587       return;
03588    }
03589    if (buf[5] != 2) {
03590       ast_log(LOG_NOTICE, "%s Wrong direction : got 0x%.2x expected 0x02\n", tmpbuf,
03591             buf[5]);
03592       return;
03593    }
03594    seq = ntohs(sbuf[1]);
03595    if (buf[4] == 1) {
03596       ast_mutex_lock(&pte->lock);
03597       if (unistimdebug)
03598          ast_verb(6, "ACK received for packet #0x%.4x\n", seq);
03599       pte->nb_retransmit = 0;
03600 
03601       if ((pte->last_seq_ack) + 1 == seq) {
03602          pte->last_seq_ack++;
03603          check_send_queue(pte);
03604          ast_mutex_unlock(&pte->lock);
03605          return;
03606       }
03607       if (pte->last_seq_ack > seq) {
03608          if (pte->last_seq_ack == 0xffff) {
03609             ast_verb(0, "ACK at 0xffff, restarting counter.\n");
03610             pte->last_seq_ack = 0;
03611          } else
03612             ast_log(LOG_NOTICE,
03613                   "%s Warning : ACK received for an already ACKed packet : #0x%.4x we are at #0x%.4x\n",
03614                   tmpbuf, seq, pte->last_seq_ack);
03615          ast_mutex_unlock(&pte->lock);
03616          return;
03617       }
03618       if (pte->seq_server < seq) {
03619          ast_log(LOG_NOTICE,
03620                "%s Error : ACK received for a non-existent packet : #0x%.4x\n",
03621                tmpbuf, pte->seq_server);
03622          ast_mutex_unlock(&pte->lock);
03623          return;
03624       }
03625       if (unistimdebug)
03626          ast_verb(0, "%s ACK gap : Received ACK #0x%.4x, previous was #0x%.4x\n",
03627                   tmpbuf, seq, pte->last_seq_ack);
03628       pte->last_seq_ack = seq;
03629       check_send_queue(pte);
03630       ast_mutex_unlock(&pte->lock);
03631       return;
03632    }
03633    if (buf[4] == 2) {
03634       if (unistimdebug)
03635          ast_verb(0, "Request received\n");
03636       if (pte->seq_phone == seq) {
03637          /* Send ACK */
03638          buf[4] = 1;
03639          buf[5] = 1;
03640          send_raw_client(SIZE_HEADER, buf, addr_from, &pte->sout);
03641          pte->seq_phone++;
03642 
03643          process_request(size, buf, pte);
03644          return;
03645       }
03646       if (pte->seq_phone > seq) {
03647          ast_log(LOG_NOTICE,
03648                "%s Warning : received a retransmitted packet : #0x%.4x (we are at #0x%.4x)\n",
03649                tmpbuf, seq, pte->seq_phone);
03650          /* BUG ? pte->device->seq_phone = seq; */
03651          /* Send ACK */
03652          buf[4] = 1;
03653          buf[5] = 1;
03654          send_raw_client(SIZE_HEADER, buf, addr_from, &pte->sout);
03655          return;
03656       }
03657       ast_log(LOG_NOTICE,
03658             "%s Warning : we lost a packet : received #0x%.4x (we are at #0x%.4x)\n",
03659             tmpbuf, seq, pte->seq_phone);
03660       return;
03661    }
03662    if (buf[4] == 0) {
03663       ast_log(LOG_NOTICE, "%s Retransmit request for packet #0x%.4x\n", tmpbuf, seq);
03664       if (pte->last_seq_ack > seq) {
03665          ast_log(LOG_NOTICE,
03666                "%s Error : received a request for an already ACKed packet : #0x%.4x\n",
03667                tmpbuf, pte->last_seq_ack);
03668          return;
03669       }
03670       if (pte->seq_server < seq) {
03671          ast_log(LOG_NOTICE,
03672                "%s Error : received a request for a non-existent packet : #0x%.4x\n",
03673                tmpbuf, pte->seq_server);
03674          return;
03675       }
03676       send_retransmit(pte);
03677       return;
03678    }
03679    ast_log(LOG_NOTICE, "%s Unknown request : got 0x%.2x expected 0x00,0x01 or 0x02\n",
03680          tmpbuf, buf[4]);
03681    return;
03682 }

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

Definition at line 3410 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(), LOG_WARNING, MUTE_OFF, unistim_device::output, OUTPUT_HANDSET, OUTPUT_HEADPHONE, packet_recv_firm_version, packet_recv_hangup, packet_recv_mac_addr, packet_recv_pick_up, packet_recv_pressed_key, packet_recv_r2, packet_recv_resume_connection_with_server, 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, and unistimdebug.

Referenced by parsing().

03411 {
03412    char tmpbuf[255];
03413    if (memcmp
03414       (buf + SIZE_HEADER, packet_recv_resume_connection_with_server,
03415        sizeof(packet_recv_resume_connection_with_server)) == 0) {
03416       rcv_resume_connection_with_server(pte);
03417       return;
03418    }
03419    if (memcmp(buf + SIZE_HEADER, packet_recv_firm_version, sizeof(packet_recv_firm_version)) ==
03420       0) {
03421       buf[size] = 0;
03422       if (unistimdebug)
03423          ast_verb(0, "Got the firmware version : '%s'\n", buf + 13);
03424       init_phone_step2(pte);
03425       return;
03426    }
03427    if (memcmp(buf + SIZE_HEADER, packet_recv_mac_addr, sizeof(packet_recv_mac_addr)) == 0) {
03428       rcv_mac_addr(pte, buf);
03429       return;
03430    }
03431    if (memcmp(buf + SIZE_HEADER, packet_recv_r2, sizeof(packet_recv_r2)) == 0) {
03432       if (unistimdebug)
03433          ast_verb(0, "R2 received\n");
03434       return;
03435    }
03436 
03437    if (pte->state < STATE_MAINPAGE) {
03438       if (unistimdebug)
03439          ast_verb(0, "Request not authorized in this state\n");
03440       return;
03441    }
03442    if (!memcmp(buf + SIZE_HEADER, packet_recv_pressed_key, sizeof(packet_recv_pressed_key))) {
03443       char keycode = buf[13];
03444 
03445       if (unistimdebug)
03446          ast_verb(0, "Key pressed : keycode = 0x%.2x - current state : %d\n", keycode,
03447                   pte->state);
03448 
03449       switch (pte->state) {
03450       case STATE_INIT:
03451          if (unistimdebug)
03452             ast_verb(0, "No keys allowed in the init state\n");
03453          break;
03454       case STATE_AUTHDENY:
03455          if (unistimdebug)
03456             ast_verb(0, "No keys allowed in authdeny state\n");
03457          break;
03458       case STATE_MAINPAGE:
03459          key_main_page(pte, keycode);
03460          break;
03461       case STATE_DIALPAGE:
03462          key_dial_page(pte, keycode);
03463          break;
03464       case STATE_RINGING:
03465          key_ringing(pte, keycode);
03466          break;
03467       case STATE_CALL:
03468          key_call(pte, keycode);
03469          break;
03470       case STATE_EXTENSION:
03471          key_select_extension(pte, keycode);
03472          break;
03473       case STATE_SELECTCODEC:
03474          key_select_codec(pte, keycode);
03475          break;
03476       case STATE_HISTORY:
03477          key_history(pte, keycode);
03478          break;
03479       default:
03480          ast_log(LOG_WARNING, "Key : Unknown state\n");
03481       }
03482       return;
03483    }
03484    if (memcmp(buf + SIZE_HEADER, packet_recv_pick_up, sizeof(packet_recv_pick_up)) == 0) {
03485       if (unistimdebug)
03486          ast_verb(0, "Handset off hook\n");
03487       if (!pte->device)        /* We are not yet registered (asking for a TN in AUTOPROVISIONING_TN) */
03488          return;
03489       pte->device->receiver_state = STATE_OFFHOOK;
03490       if (pte->device->output == OUTPUT_HEADPHONE)
03491          send_select_output(pte, OUTPUT_HEADPHONE, pte->device->volume, MUTE_OFF);
03492       else
03493          send_select_output(pte, OUTPUT_HANDSET, pte->device->volume, MUTE_OFF);
03494       if (pte->state == STATE_RINGING)
03495          HandleCallIncoming(pte);
03496       else if ((pte->state == STATE_DIALPAGE) || (pte->state == STATE_CALL))
03497          send_select_output(pte, OUTPUT_HANDSET, pte->device->volume, MUTE_OFF);
03498       else if (pte->state == STATE_EXTENSION) /* We must have a TN before calling */
03499          return;
03500       else {
03501          send_select_output(pte, OUTPUT_HANDSET, pte->device->volume, MUTE_OFF);
03502          handle_dial_page(pte);
03503       }
03504       return;
03505    }
03506    if (memcmp(buf + SIZE_HEADER, packet_recv_hangup, sizeof(packet_recv_hangup)) == 0) {
03507       if (unistimdebug)
03508          ast_verb(0, "Handset on hook\n");
03509       if (!pte->device)
03510          return;
03511       pte->device->receiver_state = STATE_ONHOOK;
03512       if (pte->state == STATE_CALL)
03513          close_call(pte);
03514       else if (pte->device->lines->subs[SUB_REAL]->owner)
03515          close_call(pte);
03516       else if (pte->state == STATE_EXTENSION)
03517          return;
03518       else
03519          show_main_page(pte);
03520       return;
03521    }
03522    strcpy(tmpbuf, ast_inet_ntoa(pte->sin.sin_addr));
03523    strcat(tmpbuf, " Unknown request packet\n");
03524    if (unistimdebug)
03525       ast_debug(1, "%s", tmpbuf);
03526    return;
03527 }

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

Definition at line 1523 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, 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_device::lines, LOG_WARNING, unistimsession::macaddr, unistim_line::name, unistim_device::name, unistim_device::next, packet_send_query_basic_manager_04, packet_send_query_basic_manager_10, packet_send_S1, RegisterExtension(), send_client(), send_date_time(), SIZE_HEADER, unistimsession::state, STATE_AUTHDENY, STATE_EXTENSION, STATE_MAINPAGE, STATE_ONHOOK, SUB_REAL, unistim_register(), and unistimdebug.

Referenced by process_request().

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

static void rcv_resume_connection_with_server ( struct unistimsession pte  )  [static]

Definition at line 1452 of file chan_unistim.c.

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

Referenced by process_request().

01453 {
01454    BUFFSEND;
01455    if (unistimdebug) {
01456       ast_verb(0, "ResumeConnectionWithServer received\n");
01457       ast_verb(0, "Sending packet_send_query_mac_address\n");
01458    }
01459    memcpy(buffsend + SIZE_HEADER, packet_send_query_mac_address,
01460          sizeof(packet_send_query_mac_address));
01461    send_client(SIZE_HEADER + sizeof(packet_send_query_mac_address), buffsend, pte);
01462    return;
01463 }

static int ReformatNumber ( char *  number  )  [static]

Definition at line 3022 of file chan_unistim.c.

Referenced by key_history(), and show_entry_history().

03023 {
03024    int pos = 0, i = 0, size = strlen(number);
03025 
03026    for (; i < size; i++) {
03027       if ((number[i] >= '0') && (number[i] <= '9')) {
03028          if (i == pos) {
03029             pos++;
03030             continue;
03031          }
03032          number[pos] = number[i];
03033          pos++;
03034       }
03035    }
03036    number[pos] = 0;
03037    return pos;
03038 }

static void refresh_all_favorite ( struct unistimsession pte  )  [static]

Definition at line 1056 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(), and key_select_extension().

01057 {
01058    int i = 0;
01059 
01060    if (unistimdebug)
01061       ast_verb(0, "Refreshing all favorite\n");
01062    for (i = 0; i < 6; i++) {
01063       if ((pte->device->softkeyicon[i] <= FAV_ICON_HEADPHONES_ONHOLD) &&
01064          (pte->device->softkeylinepos != i))
01065          send_favorite((unsigned char) i, pte->device->softkeyicon[i] + 1, pte,
01066                    pte->device->softkeylabel[i]);
01067       else
01068          send_favorite((unsigned char) i, pte->device->softkeyicon[i], pte,
01069                    pte->device->softkeylabel[i]);
01070 
01071    }
01072 }

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

Definition at line 1099 of file chan_unistim.c.

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

Referenced by key_select_extension(), and rcv_mac_addr().

01100 {
01101    if (unistimdebug)
01102       ast_verb(0, "Trying to register extension '%s' into context '%s' to %s\n",
01103                pte->device->extension_number, pte->device->lines->context,
01104                pte->device->lines->fullname);
01105    return ast_add_extension(pte->device->lines->context, 0,
01106                       pte->device->extension_number, 1, NULL, NULL, "Dial",
01107                       pte->device->lines->fullname, 0, "Unistim");
01108 }

static int reload ( void   )  [static]

reload: Part of Asterisk module interface ---

static int reload_config ( void   )  [static]

Definition at line 5390 of file chan_unistim.c.

References ahp, ast_category_browse(), ast_config_destroy(), ast_config_load, ast_free, ast_gethostbyname(), ast_jb_read_conf(), ast_log(), ast_mutex_destroy, ast_mutex_lock, ast_mutex_unlock, ast_str2cos(), ast_str2tos(), ast_strlen_zero(), ast_tone_zone_unref(), ast_variable_browse(), ast_verb, autoprovisioning, AUTOPROVISIONING_DB, AUTOPROVISIONING_NO, AUTOPROVISIONING_TN, AUTOPROVISIONING_YES, build_device(), config, CONFIG_STATUS_FILEINVALID, default_jbconf, devicelock, 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, packet_send_ping, public_ip, qos, RETRANSMIT_TIMER, unistim_device::session, unistim_line::subs, unistim_device::to_delete, unistim_device::tz, unistim_keepalive, unistim_port, unistimdebug, and ast_variable::value.

05391 {
05392    struct ast_config *cfg;
05393    struct ast_variable *v;
05394    struct ast_hostent ahp;
05395    struct hostent *hp;
05396    struct sockaddr_in bindaddr = { 0, };
05397    char *config = "unistim.conf";
05398    char *cat;
05399    struct unistim_device *d;
05400    const int reuseFlag = 1;
05401    struct unistimsession *s;
05402    struct ast_flags config_flags = { 0, };
05403 
05404    cfg = ast_config_load(config, config_flags);
05405    /* We *must* have a config file otherwise stop immediately */
05406    if (!cfg) {
05407       ast_log(LOG_ERROR, "Unable to load config %s\n", config);
05408       return -1;
05409    } else if (cfg == CONFIG_STATUS_FILEINVALID) {
05410       ast_log(LOG_ERROR, "Config file %s is in an invalid format.  Aborting.\n", config);
05411       return -1;
05412    }
05413    
05414    /* Copy the default jb config over global_jbconf */
05415    memcpy(&global_jbconf, &default_jbconf, sizeof(struct ast_jb_conf));
05416 
05417    unistim_keepalive = 120;
05418    unistim_port = 0;
05419    v = ast_variable_browse(cfg, "general");
05420    while (v) {
05421       /* handle jb conf */
05422       if (!ast_jb_read_conf(&global_jbconf, v->name, v->value))
05423          continue;   
05424    
05425       if (!strcasecmp(v->name, "keepalive"))
05426          unistim_keepalive = atoi(v->value);
05427       else if (!strcasecmp(v->name, "port"))
05428          unistim_port = atoi(v->value);
05429                 else if (!strcasecmp(v->name, "tos")) {
05430                         if (ast_str2tos(v->value, &qos.tos))
05431                             ast_log(LOG_WARNING, "Invalid tos value at line %d, refer to QoS documentation\n", v->lineno);
05432                 } else if (!strcasecmp(v->name, "tos_audio")) {
05433                         if (ast_str2tos(v->value, &qos.tos_audio))
05434                             ast_log(LOG_WARNING, "Invalid tos_audio value at line %d, refer to QoS documentation\n", v->lineno);
05435                 } else if (!strcasecmp(v->name, "cos")) {
05436                         if (ast_str2cos(v->value, &qos.cos))
05437                             ast_log(LOG_WARNING, "Invalid cos value at line %d, refer to QoS documentation\n", v->lineno);
05438                 } else if (!strcasecmp(v->name, "cos_audio")) {
05439                         if (ast_str2cos(v->value, &qos.cos_audio))
05440                             ast_log(LOG_WARNING, "Invalid cos_audio value at line %d, refer to QoS documentation\n", v->lineno);
05441       } else if (!strcasecmp(v->name, "autoprovisioning")) {
05442          if (!strcasecmp(v->value, "no"))
05443             autoprovisioning = AUTOPROVISIONING_NO;
05444          else if (!strcasecmp(v->value, "yes"))
05445             autoprovisioning = AUTOPROVISIONING_YES;
05446          else if (!strcasecmp(v->value, "db"))
05447             autoprovisioning = AUTOPROVISIONING_DB;
05448          else if (!strcasecmp(v->value, "tn"))
05449             autoprovisioning = AUTOPROVISIONING_TN;
05450          else
05451             ast_log(LOG_WARNING, "Unknown autoprovisioning option.\n");
05452       } else if (!strcasecmp(v->name, "public_ip")) {
05453          if (!ast_strlen_zero(v->value)) {
05454             if (!(hp = ast_gethostbyname(v->value, &ahp)))
05455                ast_log(LOG_WARNING, "Invalid address: %s\n", v->value);
05456             else {
05457                memcpy(&public_ip.sin_addr, hp->h_addr, sizeof(public_ip.sin_addr));
05458                public_ip.sin_family = AF_INET;
05459             }
05460          }
05461       }
05462       v = v->next;
05463    }
05464    if ((unistim_keepalive < 10) ||
05465       (unistim_keepalive >
05466        255 - (((NB_MAX_RETRANSMIT + 1) * RETRANSMIT_TIMER) / 1000))) {
05467       ast_log(LOG_ERROR, "keepalive is invalid in %s\n", config);
05468       ast_config_destroy(cfg);
05469       return -1;
05470    }
05471    packet_send_ping[4] =
05472       unistim_keepalive + (((NB_MAX_RETRANSMIT + 1) * RETRANSMIT_TIMER) / 1000);
05473    if ((unistim_port < 1) || (unistim_port > 65535)) {
05474       ast_log(LOG_ERROR, "port is not set or invalid in %s\n", config);
05475       ast_config_destroy(cfg);
05476       return -1;
05477    }
05478    unistim_keepalive *= 1000;
05479 
05480    ast_mutex_lock(&devicelock);
05481    d = devices;
05482    while (d) {
05483       if (d->to_delete >= 0)
05484          d->to_delete = 1;
05485       d = d->next;
05486    }
05487    ast_mutex_unlock(&devicelock);
05488    /* load the device sections */
05489    cat = ast_category_browse(cfg, NULL);
05490    while (cat) {
05491       if (strcasecmp(cat, "general")) {
05492          d = build_device(cat, ast_variable_browse(cfg, cat));
05493       }
05494       cat = ast_category_browse(cfg, cat);
05495    }
05496    ast_mutex_lock(&devicelock);
05497    d = devices;
05498    while (d) {
05499       if (d->to_delete) {
05500          int i;
05501 
05502          if (unistimdebug)
05503             ast_verb(0, "Removing device '%s'\n", d->name);
05504          if (!d->lines) {
05505             ast_log(LOG_ERROR, "Device '%s' without a line !, aborting\n", d->name);
05506             ast_config_destroy(cfg);
05507             return 0;
05508          }
05509          if (!d->lines->subs[0]) {
05510             ast_log(LOG_ERROR, "Device '%s' without a subchannel !, aborting\n",
05511                   d->name);
05512             ast_config_destroy(cfg);
05513             return 0;
05514          }
05515          if (d->lines->subs[0]->owner) {
05516             ast_log(LOG_WARNING,
05517                   "Device '%s' was not deleted : a call is in progress. Try again later.\n",
05518                   d->name);
05519             d = d->next;
05520             continue;
05521          }
05522          ast_mutex_destroy(&d->lines->subs[0]->lock);
05523          ast_free(d->lines->subs[0]);
05524          for (i = 1; i < MAX_SUBS; i++) {
05525             if (d->lines->subs[i]) {
05526                ast_log(LOG_WARNING,
05527                      "Device '%s' with threeway call subchannels allocated, aborting.\n",
05528                      d->name);
05529                break;
05530             }
05531          }
05532          if (i < MAX_SUBS) {
05533             d = d->next;
05534             continue;
05535          }
05536          ast_mutex_destroy(&d->lines->lock);
05537          ast_free(d->lines);
05538          if (d->session) {
05539             if (sessions == d->session)
05540                sessions = d->session->next;
05541             else {
05542                s = sessions;
05543                while (s) {
05544                   if (s->next == d->session) {
05545                      s->next = d->session->next;
05546                      break;
05547                   }
05548                   s = s->next;
05549                }
05550             }
05551             ast_mutex_destroy(&d->session->lock);
05552             ast_free(d->session);
05553          }
05554          if (devices == d)
05555             devices = d->next;
05556          else {
05557             struct unistim_device *d2 = devices;
05558             while (d2) {
05559                if (d2->next == d) {
05560                   d2->next = d->next;
05561                   break;
05562                }
05563                d2 = d2->next;
05564             }
05565          }
05566          if (d->tz) {
05567             d->tz = ast_tone_zone_unref(d->tz);
05568          }
05569          ast_free(d);
05570          d = devices;
05571          continue;
05572       }
05573       d = d->next;
05574    }
05575    finish_bookmark();
05576    ast_mutex_unlock(&devicelock);
05577    ast_config_destroy(cfg);
05578    ast_mutex_lock(&sessionlock);
05579    s = sessions;
05580    while (s) {
05581       if (s->device)
05582          refresh_all_favorite(s);
05583       s = s->next;
05584    }
05585    ast_mutex_unlock(&sessionlock);
05586    /* We don't recreate a socket when reloading (locks would be necessary). */
05587    if (unistimsock > -1)
05588       return 0;
05589    bindaddr.sin_addr.s_addr = INADDR_ANY;
05590    bindaddr.sin_port = htons(unistim_port);
05591    bindaddr.sin_family = AF_INET;
05592    unistimsock = socket(AF_INET, SOCK_DGRAM, 0);
05593    if (unistimsock < 0) {
05594       ast_log(LOG_WARNING, "Unable to create UNISTIM socket: %s\n", strerror(errno));
05595       return -1;
05596    }
05597 #ifdef HAVE_PKTINFO
05598    {
05599       const int pktinfoFlag = 1;
05600       setsockopt(unistimsock, IPPROTO_IP, IP_PKTINFO, &pktinfoFlag,
05601                sizeof(pktinfoFlag));
05602    }
05603 #else
05604    if (public_ip.sin_family == 0) {
05605       ast_log(LOG_WARNING,
05606             "Your OS does not support IP_PKTINFO, you must set public_ip.\n");
05607       unistimsock = -1;
05608       return -1;
05609    }
05610 #endif
05611    setsockopt(unistimsock, SOL_SOCKET, SO_REUSEADDR, (const char *) &reuseFlag,
05612             sizeof(reuseFlag));
05613    if (bind(unistimsock, (struct sockaddr *) &bindaddr, sizeof(bindaddr)) < 0) {
05614       ast_log(LOG_WARNING, "Failed to bind to %s:%d: %s\n",
05615             ast_inet_ntoa(bindaddr.sin_addr), htons(bindaddr.sin_port),
05616             strerror(errno));
05617       close(unistimsock);
05618       unistimsock = -1;
05619    } else {
05620       ast_verb(2, "UNISTIM Listening on %s:%d\n", ast_inet_ntoa(bindaddr.sin_addr), htons(bindaddr.sin_port));
05621       ast_netsock_set_qos(unistimsock, qos.tos, qos.cos, "UNISTIM");
05622    }
05623    return 0;
05624 }

static int restart_monitor ( void   )  [static]

Definition at line 4675 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, monitor_thread, and monlock.

04676 {
04677    pthread_attr_t attr;
04678    /* If we're supposed to be stopped -- stay stopped */
04679    if (monitor_thread == AST_PTHREADT_STOP)
04680       return 0;
04681    if (ast_mutex_lock(&monlock)) {
04682       ast_log(LOG_WARNING, "Unable to lock monitor\n");
04683       return -1;
04684    }
04685    if (monitor_thread == pthread_self()) {
04686       ast_mutex_unlock(&monlock);
04687       ast_log(LOG_WARNING, "Cannot kill myself\n");
04688       return -1;
04689    }
04690    if (monitor_thread != AST_PTHREADT_NULL) {
04691       /* Wake up the thread */
04692       pthread_kill(monitor_thread, SIGURG);
04693    } else {
04694       pthread_attr_init(&attr);
04695       pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE);
04696       /* Start a new monitor */
04697       if (ast_pthread_create(&monitor_thread, &attr, do_monitor, NULL) < 0) {
04698          ast_mutex_unlock(&monlock);
04699          ast_log(LOG_ERROR, "Unable to start monitor thread.\n");
04700          return -1;
04701       }
04702    }
04703    ast_mutex_unlock(&monlock);
04704    return 0;
04705 }

static void send_blink_cursor ( struct unistimsession pte  )  [static]

Definition at line 1429 of file chan_unistim.c.

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

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

01430 {
01431    BUFFSEND;
01432    if (unistimdebug)
01433       ast_verb(0, "Sending set blink\n");
01434    memcpy(buffsend + SIZE_HEADER, packet_send_blink_cursor, sizeof(packet_send_blink_cursor));
01435    send_client(SIZE_HEADER + sizeof(packet_send_blink_cursor), buffsend, pte);
01436    return;
01437 }

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

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

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

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

Definition at line 1440 of file chan_unistim.c.

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

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

01441 {
01442    BUFFSEND;
01443    if (unistimdebug)
01444       ast_verb(0, "Sending set cursor position\n");
01445    memcpy(buffsend + SIZE_HEADER, packet_send_set_pos_cursor,
01446          sizeof(packet_send_set_pos_cursor));
01447    buffsend[11] = pos;
01448    send_client(SIZE_HEADER + sizeof(packet_send_set_pos_cursor), buffsend, pte);
01449    return;
01450 }

static void send_date_time ( struct unistimsession pte  )  [static]

Definition at line 1374 of file chan_unistim.c.

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

Referenced by rcv_mac_addr().

01375 {
01376    BUFFSEND;
01377    struct timeval now = ast_tvnow();
01378    struct ast_tm atm = { 0, };
01379 
01380    if (unistimdebug)
01381       ast_verb(0, "Sending Time & Date\n");
01382    memcpy(buffsend + SIZE_HEADER, packet_send_date_time, sizeof(packet_send_date_time));
01383    ast_localtime(&now, &atm, NULL);
01384    buffsend[10] = (unsigned char) atm.tm_mon + 1;
01385    buffsend[11] = (unsigned char) atm.tm_mday;
01386    buffsend[12] = (unsigned char) atm.tm_hour;
01387    buffsend[13] = (unsigned char) atm.tm_min;
01388    send_client(SIZE_HEADER + sizeof(packet_send_date_time), buffsend, pte);
01389 }

static void send_date_time2 ( struct unistimsession pte  )  [static]

Definition at line 1391 of file chan_unistim.c.

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

Referenced by init_phone_step2().

01392 {
01393    BUFFSEND;
01394    struct timeval now = ast_tvnow();
01395    struct ast_tm atm = { 0, };
01396 
01397    if (unistimdebug)
01398       ast_verb(0, "Sending Time & Date #2\n");
01399    memcpy(buffsend + SIZE_HEADER, packet_send_date_time2, sizeof(packet_send_date_time2));
01400    ast_localtime(&now, &atm, NULL);
01401    if (pte->device)
01402       buffsend[9] = pte->device->datetimeformat;
01403    else
01404       buffsend[9] = 61;
01405    buffsend[14] = (unsigned char) atm.tm_mon + 1;
01406    buffsend[15] = (unsigned char) atm.tm_mday;
01407    buffsend[16] = (unsigned char) atm.tm_hour;
01408    buffsend[17] = (unsigned char) atm.tm_min;
01409    send_client(SIZE_HEADER + sizeof(packet_send_date_time2), buffsend, pte);
01410 }

static void send_date_time3 ( struct unistimsession pte  )  [static]

Definition at line 1412 of file chan_unistim.c.

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

Referenced by init_phone_step2().

01413 {
01414    BUFFSEND;
01415    struct timeval now = ast_tvnow();
01416    struct ast_tm atm = { 0, };
01417 
01418    if (unistimdebug)
01419       ast_verb(0, "Sending Time & Date #3\n");
01420    memcpy(buffsend + SIZE_HEADER, packet_send_date_time3, sizeof(packet_send_date_time3));
01421    ast_localtime(&now, &atm, NULL);
01422    buffsend[10] = (unsigned char) atm.tm_mon + 1;
01423    buffsend[11] = (unsigned char) atm.tm_mday;
01424    buffsend[12] = (unsigned char) atm.tm_hour;
01425    buffsend[13] = (unsigned char) atm.tm_min;
01426    send_client(SIZE_HEADER + sizeof(packet_send_date_time3), buffsend, pte);
01427 }

static void send_end_call ( struct unistimsession pte  )  [static]

Definition at line 911 of file chan_unistim.c.

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

Referenced by unistim_hangup().

00912 {
00913    BUFFSEND;
00914    if (unistimdebug)
00915       ast_verb(0, "Sending end call\n");
00916    memcpy(buffsend + SIZE_HEADER, packet_send_end_call, sizeof(packet_send_end_call));
00917    send_client(SIZE_HEADER + sizeof(packet_send_end_call), buffsend, pte);
00918 }

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

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

01039 {
01040    BUFFSEND;
01041    int i;
01042 
01043    if (unistimdebug)
01044       ast_verb(0, "Sending favorite pos %d with status 0x%.2x\n", pos, status);
01045    memcpy(buffsend + SIZE_HEADER, packet_send_favorite, sizeof(packet_send_favorite));
01046    buffsend[10] = pos;
01047    buffsend[24] = pos;
01048    buffsend[25] = status;
01049    i = strlen(text);
01050    if (i > FAV_MAX_LENGTH)
01051       i = FAV_MAX_LENGTH;
01052    memcpy(buffsend + FAV_MAX_LENGTH + 1, text, i);
01053    send_client(SIZE_HEADER + sizeof(packet_send_favorite), buffsend, pte);
01054 }

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

Definition at line 1265 of file chan_unistim.c.

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

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

01266 {
01267    BUFFSEND;
01268    if (unistimdebug)
01269       ast_verb(0, "Sending led_update (%x)\n", led);
01270    memcpy(buffsend + SIZE_HEADER, packet_send_led_update, sizeof(packet_send_led_update));
01271    buffsend[9] = led;
01272    send_client(SIZE_HEADER + sizeof(packet_send_led_update), buffsend, pte);
01273 }

static void send_no_ring ( struct unistimsession pte  )  [static]

Definition at line 1350 of file chan_unistim.c.

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

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

01351 {
01352    BUFFSEND;
01353    if (unistimdebug)
01354       ast_verb(0, "Sending no ring packet\n");
01355    memcpy(buffsend + SIZE_HEADER, packet_send_no_ring, sizeof(packet_send_no_ring));
01356    send_client(SIZE_HEADER + sizeof(packet_send_no_ring), buffsend, pte);
01357 }

static void send_ping ( struct unistimsession pte  )  [static]

Definition at line 832 of file chan_unistim.c.

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

00833 {
00834    BUFFSEND;
00835    if (unistimdebug)
00836       ast_verb(6, "Sending ping\n");
00837    pte->tick_next_ping = get_tick_count() + unistim_keepalive;
00838    memcpy(buffsend + SIZE_HEADER, packet_send_ping, sizeof(packet_send_ping));
00839    send_client(SIZE_HEADER + sizeof(packet_send_ping), buffsend, pte);
00840 }

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

Definition at line 744 of file chan_unistim.c.

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

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

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

static int send_retransmit ( struct unistimsession pte  )  [static]

Definition at line 1170 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, unistimdebug, and unistimsession::wsabufsend.

Referenced by do_monitor(), and parsing().

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

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

Definition at line 1339 of file chan_unistim.c.

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

Referenced by unistim_call().

01340 {
01341    BUFFSEND;
01342    if (unistimdebug)
01343       ast_verb(0, "Sending ring packet\n");
01344    memcpy(buffsend + SIZE_HEADER, packet_send_ring, sizeof(packet_send_ring));
01345    buffsend[24] = style + 0x10;
01346    buffsend[29] = volume * 0x10;
01347    send_client(SIZE_HEADER + sizeof(packet_send_ring), buffsend, pte);
01348 }

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

Definition at line 1279 of file chan_unistim.c.

References ast_log(), ast_verb, BUFFSEND, change_favorite_icon(), 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, MUTE_OFF, MUTE_ON, MUTE_ON_DISCRET, OUTPUT_HANDSET, OUTPUT_HEADPHONE, OUTPUT_SPEAKER, packet_send_select_output, send_client(), send_led_update(), SIZE_HEADER, STATE_OFFHOOK, unistimdebug, 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().

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

static void send_start_timer ( struct unistimsession pte  )  [static]

Definition at line 954 of file chan_unistim.c.

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

Referenced by HandleCallIncoming(), and unistim_answer().

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

static void send_stop_timer ( struct unistimsession pte  )  [static]

Definition at line 963 of file chan_unistim.c.

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

Referenced by close_call().

00964 {
00965    BUFFSEND;
00966    if (unistimdebug)
00967       ast_verb(0, "Sending stop timer\n");
00968    memcpy(buffsend + SIZE_HEADER, packet_send_stop_timer, sizeof(packet_send_stop_timer));
00969    send_client(SIZE_HEADER + sizeof(packet_send_stop_timer), buffsend, pte);
00970 }

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

Definition at line 1210 of file chan_unistim.c.

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

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

01212 {
01213    int i;
01214    BUFFSEND;
01215    if (unistimdebug)
01216       ast_verb(0, "Sending text at pos %d, inverse flag %d\n", pos, inverse);
01217    memcpy(buffsend + SIZE_HEADER, packet_send_text, sizeof(packet_send_text));
01218    buffsend[10] = pos;
01219    buffsend[11] = inverse;
01220    i = strlen(text);
01221    if (i > TEXT_LENGTH_MAX)
01222       i = TEXT_LENGTH_MAX;
01223    memcpy(buffsend + 12, text, i);
01224    send_client(SIZE_HEADER + sizeof(packet_send_text), buffsend, pte);
01225 }

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

Definition at line 1227 of file chan_unistim.c.

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

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

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

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

Definition at line 1359 of file chan_unistim.c.

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

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

01360 {
01361    BUFFSEND;
01362    int i;
01363    if (unistimdebug)
01364       ast_verb(0, "Sending title text\n");
01365    memcpy(buffsend + SIZE_HEADER, packet_send_title, sizeof(packet_send_title));
01366    i = strlen(text);
01367    if (i > 12)
01368       i = 12;
01369    memcpy(buffsend + 10, text, i);
01370    send_client(SIZE_HEADER + sizeof(packet_send_title), buffsend, pte);
01371 
01372 }

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

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

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

static void SendDialTone ( struct unistimsession pte  )  [static]

Definition at line 2242 of file chan_unistim.c.

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

Referenced by handle_dial_page().

02243 {
02244    int i;
02245    /* No country defined ? Using US tone */
02246    if (ast_strlen_zero(pte->device->country)) {
02247       if (unistimdebug)
02248          ast_verb(0, "No country defined, using US tone\n");
02249       send_tone(pte, 350, 440);
02250       return;
02251    }
02252    if (strlen(pte->device->country) != 2) {
02253       if (unistimdebug)
02254          ast_verb(0, "Country code != 2 char, using US tone\n");
02255       send_tone(pte, 350, 440);
02256       return;
02257    }
02258    i = 0;
02259    while (frequency[i].freq1) {
02260       if ((frequency[i].country[0] == pte->device->country[0]) &&
02261          (frequency[i].country[1] == pte->device->country[1])) {
02262          if (unistimdebug)
02263             ast_verb(0, "Country code found (%s), freq1=%d freq2=%d\n",
02264                      frequency[i].country, frequency[i].freq1, frequency[i].freq2);
02265          send_tone(pte, frequency[i].freq1, frequency[i].freq2);
02266       }
02267       i++;
02268    }
02269 }

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

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

00973 {
00974    BUFFSEND;
00975    if (unistimdebug)
00976       ast_verb(0, "Sending icon pos %d with status 0x%.2x\n", pos, status);
00977    memcpy(buffsend + SIZE_HEADER, packet_send_icon, sizeof(packet_send_icon));
00978    buffsend[9] = pos;
00979    buffsend[10] = status;
00980    send_client(SIZE_HEADER + sizeof(packet_send_icon), buffsend, pte);
00981 }

static void set_ping_timer ( struct unistimsession pte  )  [static]

Definition at line 920 of file chan_unistim.c.

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

Referenced by check_send_queue().

00921 {
00922    unsigned int tick = 0;  /* XXX what is this for, anyways */
00923 
00924    pte->timeout = pte->tick_next_ping;
00925    DEBUG_TIMER("tick = %u next ping at %u tick\n", tick, pte->timeout);
00926    return;
00927 }

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

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

03041 {
03042    char line[TEXT_LENGTH_MAX + 1], status[STATUS_LENGTH_MAX + 1], func1[10], func2[10],
03043       func3[10];
03044 
03045    if (fread(line, TEXT_LENGTH_MAX, 1, *f) != 1) {
03046       display_last_error("Can't read history date entry");
03047       fclose(*f);
03048       return;
03049    }
03050    line[sizeof(line) - 1] = '\0';
03051    send_text(TEXT_LINE0, TEXT_NORMAL, pte, line);
03052    if (fread(line, TEXT_LENGTH_MAX, 1, *f) != 1) {
03053       display_last_error("Can't read callerid entry");
03054       fclose(*f);
03055       return;
03056    }
03057    line[sizeof(line) - 1] = '\0';
03058    ast_copy_string(pte->device->lst_cid, line, sizeof(pte->device->lst_cid));
03059    send_text(TEXT_LINE1, TEXT_NORMAL, pte, line);
03060    if (fread(line, TEXT_LENGTH_MAX, 1, *f) != 1) {
03061       display_last_error("Can't read callername entry");
03062       fclose(*f);
03063       return;
03064    }
03065    line[sizeof(line) - 1] = '\0';
03066    send_text(TEXT_LINE2, TEXT_NORMAL, pte, line);
03067    fclose(*f);
03068 
03069    snprintf(line, sizeof(line), "Call %03d/%03d", pte->buff_entry[2],
03070           pte->buff_entry[1]);
03071    send_texttitle(pte, line);
03072 
03073    if (pte->buff_entry[2] == 1)
03074       strcpy(func1, "       ");
03075    else
03076       strcpy(func1, "Prvious");
03077    if (pte->buff_entry[2] >= pte->buff_entry[1])
03078       strcpy(func2, "       ");
03079    else
03080       strcpy(func2, "Next   ");
03081    if (ReformatNumber(pte->device->lst_cid))
03082       strcpy(func3, "Redial ");
03083    else
03084       strcpy(func3, "       ");
03085    snprintf(status, sizeof(status), "%s%s%sCancel", func1, func2, func3);
03086    send_text_status(pte, status);
03087 }

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

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

03116 {
03117    FILE *f;
03118    char count;
03119 
03120    if (!pte->device)
03121       return;
03122    if (!pte->device->callhistory)
03123       return;
03124    count = OpenHistory(pte, way, &f);
03125    if (!count)
03126       return;
03127    pte->buff_entry[0] = way;
03128    pte->buff_entry[1] = count;
03129    pte->buff_entry[2] = 1;
03130    show_entry_history(pte, &f);
03131    pte->state = STATE_HISTORY;
03132 }

static void show_main_page ( struct unistimsession pte  )  [static]

Definition at line 3134 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_device::height, unistim_line::lastmsgssent, unistim_device::lines, unistim_device::maintext2, 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().

03135 {
03136    char tmpbuf[TEXT_LENGTH_MAX + 1];
03137 
03138 
03139    if ((pte->device->extension == EXTENSION_ASK) &&
03140       (ast_strlen_zero(pte->device->extension_number))) {
03141       ShowExtensionPage(pte);
03142       return;
03143    }
03144 
03145    pte->state = STATE_MAINPAGE;
03146 
03147    send_tone(pte, 0, 0);
03148    send_select_output(pte, pte->device->output, pte->device->volume, MUTE_ON_DISCRET);
03149    pte->device->lines->lastmsgssent = 0;
03150    send_favorite(pte->device->softkeylinepos, FAV_ICON_ONHOOK_BLACK, pte,
03151              pte->device->softkeylabel[pte->device->softkeylinepos]);
03152    if (!ast_strlen_zero(pte->device->call_forward)) {
03153       if (pte->device->height == 1) {
03154          send_text(TEXT_LINE0, TEXT_NORMAL, pte, "Forwarding ON");
03155       } else {
03156          send_text(TEXT_LINE0, TEXT_NORMAL, pte, "Call forwarded to :");
03157          send_text(TEXT_LINE1, TEXT_NORMAL, pte, pte->device->call_forward);
03158       }
03159       Sendicon(TEXT_LINE0, FAV_ICON_REFLECT + FAV_BLINK_SLOW, pte);
03160       send_text_status(pte, "Dial   Redial NoForwd");
03161    } else {
03162       if ((pte->device->extension == EXTENSION_ASK) ||
03163          (pte->device->extension == EXTENSION_TN))
03164          send_text_status(pte, "Dial   Redial ForwardUnregis");
03165       else
03166          send_text_status(pte, "Dial   Redial Forward");
03167 
03168       send_text(TEXT_LINE1, TEXT_NORMAL, pte, pte->device->maintext1);
03169       if (pte->device->missed_call == 0)
03170          send_text(TEXT_LINE0, TEXT_NORMAL, pte, pte->device->maintext0);
03171       else {
03172          sprintf(tmpbuf, "%d unanswered call(s)", pte->device->missed_call);
03173          send_text(TEXT_LINE0, TEXT_NORMAL, pte, tmpbuf);
03174          Sendicon(TEXT_LINE0, FAV_ICON_CALL_CENTER + FAV_BLINK_SLOW, pte);
03175       }
03176    }
03177    if (ast_strlen_zero(pte->device->maintext2)) {
03178       strcpy(tmpbuf, "IP : ");
03179       strcat(tmpbuf, ast_inet_ntoa(pte->sin.sin_addr));
03180       send_text(TEXT_LINE2, TEXT_NORMAL, pte, tmpbuf);
03181    } else
03182       send_text(TEXT_LINE2, TEXT_NORMAL, pte, pte->device->maintext2);
03183    send_texttitle(pte, pte->device->titledefault);
03184    change_favorite_icon(pte, FAV_ICON_ONHOOK_BLACK);
03185 }

static void ShowExtensionPage ( struct unistimsession pte  )  [static]

Definition at line 2910 of file chan_unistim.c.

References SELECTEXTENSION_MSG, SELECTEXTENSION_START_ENTRY_POS, send_blink_cursor(), send_cursor_pos(), send_text(), send_text_status(), unistimsession::size_buff_entry, unistimsession::state, STATE_EXTENSION, TEXT_LINE0, TEXT_LINE1, TEXT_LINE2, and TEXT_NORMAL.

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

02911 {
02912    pte->state = STATE_EXTENSION;
02913 
02914    send_text(TEXT_LINE0, TEXT_NORMAL, pte, "Please enter a Terminal");
02915    send_text(TEXT_LINE1, TEXT_NORMAL, pte, "Number (TN) :");
02916    send_text(TEXT_LINE2, TEXT_NORMAL, pte, SELECTEXTENSION_MSG);
02917    send_blink_cursor(pte);
02918    send_cursor_pos(pte, TEXT_LINE2 + SELECTEXTENSION_START_ENTRY_POS);
02919    send_text_status(pte, "Enter  BackSpcErase");
02920    pte->size_buff_entry = 0;
02921    return;
02922 }

static void start_rtp ( struct unistim_subchannel sub  )  [static]

Definition at line 2038 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_getformatname_multiple(), ast_inet_ntoa(), ast_log(), ast_mutex_lock, ast_mutex_unlock, ast_rtp_codecs_payload_code(), ast_rtp_instance_fd(), ast_rtp_instance_get_codecs(), ast_rtp_instance_get_local_address(), ast_rtp_instance_new(), ast_rtp_instance_set_prop(), ast_rtp_instance_set_qos(), ast_rtp_instance_set_remote_address(), AST_RTP_PROPERTY_NAT, AST_RTP_PROPERTY_RTCP, ast_sockaddr_from_sin, ast_sockaddr_to_sin, ast_verb, BUFFSEND, errno, ast_channel::fds, unistim_subchannel::lock, LOG_WARNING, unistim_device::nat, ast_channel::nativeformats, unistim_subchannel::owner, packet_send_call, packet_send_jitter_buffer_conf, packet_send_open_audio_stream_rx, packet_send_open_audio_stream_rx3, packet_send_open_audio_stream_tx, packet_send_open_audio_stream_tx3, packet_send_rtp_packet_size, unistim_line::parent, unistim_subchannel::parent, public_ip, 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, unistimdebug, and ast_channel::writeformat.

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

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

Definition at line 1867 of file chan_unistim.c.

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

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

static void TransferCallStep1 ( struct unistimsession pte  )  [static]

Definition at line 2340 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, unistim_line::subs, and unistimdebug.

Referenced by key_call().

02341 {
02342    struct unistim_subchannel *sub;
02343    struct unistim_line *p = pte->device->lines;
02344 
02345    sub = p->subs[SUB_REAL];
02346 
02347    if (!sub->owner) {
02348       ast_log(LOG_WARNING, "Unable to find subchannel for music on hold\n");
02349       return;
02350    }
02351    if (p->subs[SUB_THREEWAY]) {
02352       if (unistimdebug)
02353          ast_verb(0, "Transfer canceled, hangup our threeway channel\n");
02354       if (p->subs[SUB_THREEWAY]->owner)
02355          ast_queue_hangup_with_cause(p->subs[SUB_THREEWAY]->owner, AST_CAUSE_NORMAL_CLEARING);
02356       else
02357          ast_log(LOG_WARNING, "Canceling a threeway channel without owner\n");
02358       return;
02359    }
02360    /* Start music on hold if appropriate */
02361    if (pte->device->moh)
02362       ast_log(LOG_WARNING, "Transfer with peer already listening music on hold\n");
02363    else {
02364       if (ast_bridged_channel(p->subs[SUB_REAL]->owner)) {
02365          ast_moh_start(ast_bridged_channel(p->subs[SUB_REAL]->owner),
02366                     pte->device->lines->musicclass, NULL);
02367          pte->device->moh = 1;
02368       } else {
02369          ast_log(LOG_WARNING, "Unable to find peer subchannel for music on hold\n");
02370          return;
02371       }
02372    }
02373    /* Silence our channel */
02374    if (!pte->device->silence_generator) {
02375       pte->device->silence_generator =
02376          ast_channel_start_silence_generator(p->subs[SUB_REAL]->owner);
02377       if (pte->device->silence_generator == NULL)
02378          ast_log(LOG_WARNING, "Unable to start a silence generator.\n");
02379       else if (unistimdebug)
02380          ast_verb(0, "Starting silence generator\n");
02381    }
02382    handle_dial_page(pte);
02383 }

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

Definition at line 1507 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, unistim_line::subs, and unistimdebug.

01508 {
01509    if (!x) {
01510       ast_log(LOG_WARNING, "Trying to unalloc the real channel %s@%s?!?\n", p->name,
01511             p->parent->name);
01512       return -1;
01513    }
01514    if (unistimdebug)
01515       ast_debug(1, "Released sub %d of channel %s@%s\n", x, p->name,
01516             p->parent->name);
01517    ast_mutex_destroy(&p->lock);
01518    ast_free(p->subs[x]);
01519    p->subs[x] = 0;
01520    return 0;
01521 }

static int unistim_answer ( struct ast_channel ast  )  [static]

Definition at line 3890 of file chan_unistim.c.

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

03891 {
03892    int res = 0;
03893    struct unistim_subchannel *sub;
03894    struct unistim_line *l;
03895    struct unistimsession *s;
03896 
03897    s = channel_to_session(ast);
03898    if (!s) {
03899       ast_log(LOG_WARNING, "unistim_answer on a disconnected device ?\n");
03900       return -1;
03901    }
03902    sub = ast->tech_pvt;
03903    l = sub->parent;
03904 
03905    if ((!sub->rtp) && (!l->subs[SUB_THREEWAY]))
03906       start_rtp(sub);
03907    if (unistimdebug)
03908       ast_verb(0, "unistim_answer(%s) on %s@%s-%d\n", ast->name, l->name,
03909                l->parent->name, sub->subtype);
03910    send_text(TEXT_LINE2, TEXT_NORMAL, l->parent->session, "is now on-line");
03911    if (l->subs[SUB_THREEWAY])
03912       send_text_status(l->parent->session, "Transf Cancel");
03913    else
03914       send_text_status(l->parent->session, "Hangup Transf");
03915    send_start_timer(l->parent->session);
03916    if (ast->_state != AST_STATE_UP)
03917       ast_setstate(ast, AST_STATE_UP);
03918    return res;
03919 }

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

Definition at line 3714 of file chan_unistim.c.

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

03715 {
03716    int res = 0;
03717    struct unistim_subchannel *sub;
03718    struct unistimsession *session;
03719 
03720    session = channel_to_session(ast);
03721    if (!session) {
03722       ast_log(LOG_ERROR, "Device not registered, cannot call %s\n", dest);
03723       return -1;
03724    }
03725 
03726    sub = ast->tech_pvt;
03727    if ((ast->_state != AST_STATE_DOWN) && (ast->_state != AST_STATE_RESERVED)) {
03728       ast_log(LOG_WARNING, "unistim_call called on %s, neither down nor reserved\n",
03729             ast->name);
03730       return -1;
03731    }
03732 
03733    if (unistimdebug)
03734       ast_verb(3, "unistim_call(%s)\n", ast->name);
03735 
03736    session->state = STATE_RINGING;
03737    Sendicon(TEXT_LINE0, FAV_ICON_NONE, session);
03738 
03739    if (sub->owner) {
03740       if (sub->owner->connected.id.number.valid
03741          && sub->owner->connected.id.number.str) {
03742          if (session->device->height == 1) {
03743             send_text(TEXT_LINE0, TEXT_NORMAL, session, sub->owner->connected.id.number.str);
03744          } else {
03745             send_text(TEXT_LINE1, TEXT_NORMAL, session, sub->owner->connected.id.number.str);
03746          }
03747          change_callerid(session, 0, sub->owner->connected.id.number.str);
03748       } else {
03749          if (session->device->height == 1) {
03750             send_text(TEXT_LINE0, TEXT_NORMAL, session, DEFAULTCALLERID);
03751          } else {
03752             send_text(TEXT_LINE1, TEXT_NORMAL, session, DEFAULTCALLERID);
03753          }
03754          change_callerid(session, 0, DEFAULTCALLERID);
03755       }
03756       if (sub->owner->connected.id.name.valid
03757          && sub->owner->connected.id.name.str) {
03758          send_text(TEXT_LINE0, TEXT_NORMAL, session, sub->owner->connected.id.name.str);
03759          change_callerid(session, 1, sub->owner->connected.id.name.str);
03760       } else {
03761          send_text(TEXT_LINE0, TEXT_NORMAL, session, DEFAULTCALLERNAME);
03762          change_callerid(session, 1, DEFAULTCALLERNAME);
03763       }
03764    }
03765    send_text(TEXT_LINE2, TEXT_NORMAL, session, "is calling you.");
03766    send_text_status(session, "Accept              Ignore");
03767 
03768    if (sub->ringstyle == -1)
03769       send_ring(session, session->device->ringvolume, session->device->ringstyle);
03770    else {
03771       if (sub->ringvolume == -1)
03772          send_ring(session, session->device->ringvolume, sub->ringstyle);
03773       else
03774          send_ring(session, sub->ringvolume, sub->ringstyle);
03775    }
03776    change_favorite_icon(session, FAV_ICON_SPEAKER_ONHOOK_BLACK + FAV_BLINK_FAST);
03777 
03778    ast_setstate(ast, AST_STATE_RINGING);
03779    ast_queue_control(ast, AST_CONTROL_RINGING);
03780    return res;
03781 }

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

Definition at line 4895 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, unistimdebug, and ast_cli_entry::usage.

04896 {
04897    switch (cmd) {
04898    case CLI_INIT:
04899       e->command = "unistim set debug {on|off}";
04900       e->usage =
04901          "Usage: unistim set debug\n" 
04902          "       Display debug messages.\n";
04903       return NULL;
04904 
04905    case CLI_GENERATE:
04906       return NULL;   /* no completion */
04907    }
04908 
04909    if (a->argc != e->args)
04910       return CLI_SHOWUSAGE;
04911 
04912    if (!strcasecmp(a->argv[3], "on")) {
04913       unistimdebug = 1;
04914       ast_cli(a->fd, "UNISTIM Debugging Enabled\n");
04915    } else if (!strcasecmp(a->argv[3], "off")) {
04916       unistimdebug = 0;
04917       ast_cli(a->fd, "UNISTIM Debugging Disabled\n");
04918    } else
04919       return CLI_SHOWUSAGE;
04920 
04921    return CLI_SUCCESS;
04922 }

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

Definition at line 2518 of file chan_unistim.c.

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

Referenced by key_call(), and unistim_senddigit_begin().

02519 {
02520    struct ast_frame f = { .frametype = AST_FRAME_DTMF, .subclass.integer = digit, .src = "unistim" };
02521    struct unistim_subchannel *sub;
02522    sub = pte->device->lines->subs[SUB_REAL];
02523    if (!sub->owner || sub->alreadygone) {
02524       ast_log(LOG_WARNING, "Unable to find subchannel in dtmf senddigit\n");
02525       return -1;
02526    }
02527 
02528    /* Send DTMF indication _before_ playing sounds */
02529    ast_queue_frame(sub->owner, &f);
02530 
02531    if (unistimdebug)
02532       ast_verb(0, "Send Digit %c\n", digit);
02533    switch (digit) {
02534    case '0':
02535       send_tone(pte, 941, 1336);
02536       break;
02537    case '1':
02538       send_tone(pte, 697, 1209);
02539       break;
02540    case '2':
02541       send_tone(pte, 697, 1336);
02542       break;
02543    case '3':
02544       send_tone(pte, 697, 1477);
02545       break;
02546    case '4':
02547       send_tone(pte, 770, 1209);
02548       break;
02549    case '5':
02550       send_tone(pte, 770, 1336);
02551       break;
02552    case '6':
02553       send_tone(pte, 770, 1477);
02554       break;
02555    case '7':
02556       send_tone(pte, 852, 1209);
02557       break;
02558    case '8':
02559       send_tone(pte, 852, 1336);
02560       break;
02561    case '9':
02562       send_tone(pte, 852, 1477);
02563       break;
02564    case 'A':
02565       send_tone(pte, 697, 1633);
02566       break;
02567    case 'B':
02568       send_tone(pte, 770, 1633);
02569       break;
02570    case 'C':
02571       send_tone(pte, 852, 1633);
02572       break;
02573    case 'D':
02574       send_tone(pte, 941, 1633);
02575       break;
02576    case '*':
02577       send_tone(pte, 941, 1209);
02578       break;
02579    case '#':
02580       send_tone(pte, 941, 1477);
02581       break;
02582    default:
02583       send_tone(pte, 500, 2000);
02584    }
02585    usleep(150000);          /* XXX Less than perfect, blocking an important thread is not a good idea */
02586    send_tone(pte, 0, 0);
02587    return 0;
02588 }

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

Definition at line 4076 of file chan_unistim.c.

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

04077 {
04078    struct unistim_subchannel *p = newchan->tech_pvt;
04079    struct unistim_line *l = p->parent;
04080 
04081    ast_mutex_lock(&p->lock);
04082 
04083    ast_debug(1, "New owner for channel USTM/%s@%s-%d is %s\n", l->name,
04084          l->parent->name, p->subtype, newchan->name);
04085 
04086    if (p->owner != oldchan) {
04087       ast_log(LOG_WARNING, "old channel wasn't %s (%p) but was %s (%p)\n",
04088             oldchan->name, oldchan, p->owner->name, p->owner);
04089       return -1;
04090    }
04091 
04092    p->owner = newchan;
04093 
04094    ast_mutex_unlock(&p->lock);
04095 
04096    return 0;
04097 
04098 }

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

Definition at line 5626 of file chan_unistim.c.

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

05627 {
05628    struct unistim_subchannel *sub = chan->tech_pvt;
05629 
05630    ao2_ref(sub->rtp, +1);
05631    *instance = sub->rtp;
05632 
05633    return AST_RTP_GLUE_RESULT_LOCAL;
05634 }

static int unistim_hangup ( struct ast_channel ast  )  [static]

Definition at line 3784 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_instance_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, ast_channel::name, unistim_subchannel::owner, unistim_line::parent, unistim_subchannel::parent, unistim_subchannel::rtp, 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, unalloc_sub(), and unistimdebug.

03785 {
03786    struct unistim_subchannel *sub;
03787    struct unistim_line *l;
03788    struct unistimsession *s;
03789 
03790    s = channel_to_session(ast);
03791    sub = ast->tech_pvt;
03792    if (!s) {
03793       ast_debug(1, "Asked to hangup channel not connected\n");
03794       ast_mutex_lock(&sub->lock);
03795       sub->owner = NULL;
03796       ast->tech_pvt = NULL;
03797       sub->alreadygone = 0;
03798       ast_mutex_unlock(&sub->lock);
03799       if (sub->rtp) {
03800          if (unistimdebug)
03801             ast_verb(0, "Destroying RTP session\n");
03802          ast_rtp_instance_destroy(sub->rtp);
03803          sub->rtp = NULL;
03804       }
03805       return 0;
03806    }
03807    l = sub->parent;
03808    if (unistimdebug)
03809       ast_verb(0, "unistim_hangup(%s) on %s@%s\n", ast->name, l->name, l->parent->name);
03810 
03811    if ((l->subs[SUB_THREEWAY]) && (sub->subtype == SUB_REAL)) {
03812       if (unistimdebug)
03813          ast_verb(0, "Real call disconnected while talking to threeway\n");
03814       sub->owner = NULL;
03815       ast->tech_pvt = NULL;
03816       return 0;
03817    }
03818    if ((l->subs[SUB_REAL]->owner) && (sub->subtype == SUB_THREEWAY) &&
03819       (sub->alreadygone == 0)) {
03820       if (unistimdebug)
03821          ast_verb(0, "threeway call disconnected, switching to real call\n");
03822       send_text(TEXT_LINE0, TEXT_NORMAL, s, "Three way call canceled,");
03823       send_text(TEXT_LINE1, TEXT_NORMAL, s, "switching back to");
03824       send_text(TEXT_LINE2, TEXT_NORMAL, s, "previous call.");
03825       send_text_status(s, "Hangup Transf");
03826       ast_moh_stop(ast_bridged_channel(l->subs[SUB_REAL]->owner));
03827       swap_subs(l, SUB_THREEWAY, SUB_REAL);
03828       l->parent->moh = 0;
03829       ast_mutex_lock(&sub->lock);
03830       sub->owner = NULL;
03831       ast->tech_pvt = NULL;
03832       ast_mutex_unlock(&sub->lock);
03833       unalloc_sub(l, SUB_THREEWAY);
03834       return 0;
03835    }
03836    ast_mutex_lock(&sub->lock);
03837    sub->owner = NULL;
03838    ast->tech_pvt = NULL;
03839    sub->alreadygone = 0;
03840    ast_mutex_unlock(&sub->lock);
03841    if (!s) {
03842       if (unistimdebug)
03843          ast_verb(0, "Asked to hangup channel not connected (no session)\n");
03844       if (sub->rtp) {
03845          if (unistimdebug)
03846             ast_verb(0, "Destroying RTP session\n");
03847          ast_rtp_instance_destroy(sub->rtp);
03848          sub->rtp = NULL;
03849       }
03850       return 0;
03851    }
03852    if (sub->subtype == SUB_REAL) {
03853       /* Stop the silence generator */
03854       if (s->device->silence_generator) {
03855          if (unistimdebug)
03856             ast_verb(0, "Stopping silence generator\n");
03857          if (sub->owner)
03858             ast_channel_stop_silence_generator(sub->owner,
03859                                        s->device->silence_generator);
03860          else
03861             ast_log(LOG_WARNING,
03862                   "Trying to stop silence generator on a null channel !\n");
03863          s->device->silence_generator = NULL;
03864       }
03865    }
03866    l->parent->moh = 0;
03867    send_no_ring(s);
03868    send_end_call(s);
03869    if (sub->rtp) {
03870       if (unistimdebug)
03871          ast_verb(0, "Destroying RTP session\n");
03872       ast_rtp_instance_destroy(sub->rtp);
03873       sub->rtp = NULL;
03874    } else if (unistimdebug)
03875       ast_verb(0, "No RTP session to destroy\n");
03876    if (l->subs[SUB_THREEWAY]) {
03877       if (unistimdebug)
03878          ast_verb(0, "Cleaning other subchannels\n");
03879       unalloc_sub(l, SUB_THREEWAY);
03880    }
03881    if (s->state == STATE_RINGING)
03882       cancel_dial(s);
03883    else if (s->state == STATE_CALL)
03884       close_call(s);
03885 
03886    return 0;
03887 }

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

Definition at line 4148 of file chan_unistim.c.

References ast_channel::_state, unistim_subchannel::alreadygone, AST_CONTROL_BUSY, AST_CONTROL_CONGESTION, AST_CONTROL_HOLD, AST_CONTROL_INCOMPLETE, 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, ast_channel::name, unistim_line::parent, unistim_subchannel::parent, send_text(), ast_channel::tech_pvt, TEXT_LINE2, TEXT_NORMAL, unistim_device::tz, and unistimdebug.

04150 {
04151    struct unistim_subchannel *sub;
04152    struct unistim_line *l;
04153    struct unistimsession *s;
04154 
04155    if (unistimdebug) {
04156       ast_verb(3, "Asked to indicate '%s' condition on channel %s\n",
04157                control2str(ind), ast->name);
04158    }
04159 
04160    s = channel_to_session(ast);
04161    if (!s)
04162       return -1;
04163 
04164    sub = ast->tech_pvt;
04165    l = sub->parent;
04166 
04167    switch (ind) {
04168    case AST_CONTROL_RINGING:
04169       if (ast->_state != AST_STATE_UP) {
04170          send_text(TEXT_LINE2, TEXT_NORMAL, s, "Ringing...");
04171          in_band_indication(ast, l->parent->tz, "ring");
04172          s->device->missed_call = -1;
04173          break;
04174       }
04175       return -1;
04176    case AST_CONTROL_BUSY:
04177       if (ast->_state != AST_STATE_UP) {
04178          sub->alreadygone = 1;
04179          send_text(TEXT_LINE2, TEXT_NORMAL, s, "Busy");
04180          in_band_indication(ast, l->parent->tz, "busy");
04181          s->device->missed_call = -1;
04182          break;
04183       }
04184       return -1;
04185    case AST_CONTROL_INCOMPLETE:
04186       /* Overlapped dialing is not currently supported for UNIStim.  Treat an indication
04187        * of incomplete as congestion
04188        */
04189    case AST_CONTROL_CONGESTION:
04190       if (ast->_state != AST_STATE_UP) {
04191          sub->alreadygone = 1;
04192          send_text(TEXT_LINE2, TEXT_NORMAL, s, "Congestion");
04193          in_band_indication(ast, l->parent->tz, "congestion");
04194          s->device->missed_call = -1;
04195          break;
04196       }
04197       return -1;
04198    case AST_CONTROL_HOLD:
04199       ast_moh_start(ast, data, NULL);
04200       break;
04201    case AST_CONTROL_UNHOLD:
04202       ast_moh_stop(ast);
04203       break;
04204    case AST_CONTROL_PROGRESS:
04205    case AST_CONTROL_SRCUPDATE:
04206       break;
04207    case -1:
04208       ast_playtones_stop(ast);
04209       s->device->missed_call = 0;
04210       break;
04211    case AST_CONTROL_PROCEEDING:
04212       break;
04213    default:
04214       ast_log(LOG_WARNING, "Don't know how to indicate condition %d\n", ind);
04215       return -1;
04216    }
04217 
04218    return 0;
04219 }

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

Definition at line 4765 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, unistim_device::session, sessionlock, unistimsession::sin, unistimsession::state, unistim_line::subs, unistim_subchannel::subtype, unistimsession::timeout, and ast_cli_entry::usage.

04766 {
04767    struct unistim_device *device = devices;
04768    struct unistim_line *line;
04769    struct unistim_subchannel *sub;
04770    struct unistimsession *s;
04771    int i;
04772    struct ast_channel *tmp;
04773 
04774    switch (cmd) {
04775    case CLI_INIT:
04776       e->command = "unistim show info";
04777       e->usage =
04778          "Usage: unistim show info\n" 
04779          "       Dump internal structures.\n";
04780       return NULL;
04781 
04782    case CLI_GENERATE:
04783       return NULL;   /* no completion */
04784    }
04785 
04786    if (a->argc != e->args)
04787       return CLI_SHOWUSAGE;
04788 
04789    ast_cli(a->fd, "Dumping internal structures :\ndevice\n->line\n-->sub\n");
04790    while (device) {
04791       ast_cli(a->fd, "\nname=%s id=%s line=%p ha=%p sess=%p device=%p\n",
04792             device->name, device->id, device->lines, device->ha, device->session,
04793             device);
04794       line = device->lines;
04795       while (line) {
04796          ast_cli(a->fd,
04797                "->name=%s fullname=%s exten=%s callid=%s cap=%" PRId64 " device=%p line=%p\n",
04798                line->name, line->fullname, line->exten, line->cid_num,
04799                line->capability, line->parent, line);
04800          for (i = 0; i < MAX_SUBS; i++) {
04801             sub = line->subs[i];
04802             if (!sub)
04803                continue;
04804             if (!sub->owner)
04805                tmp = (void *) -42;
04806             else
04807                tmp = sub->owner->_bridge;
04808             if (sub->subtype != i)
04809                ast_cli(a->fd, "Warning ! subchannel->subs[%d] have a subtype=%d\n", i,
04810                      sub->subtype);
04811             ast_cli(a->fd,
04812                   "-->subtype=%d chan=%p rtp=%p bridge=%p line=%p alreadygone=%d\n",
04813                   sub->subtype, sub->owner, sub->rtp, tmp, sub->parent,
04814                   sub->alreadygone);
04815          }
04816          line = line->next;
04817       }
04818       device = device->next;
04819    }
04820    ast_cli(a->fd, "\nSessions:\n");
04821    ast_mutex_lock(&sessionlock);
04822    s = sessions;
04823    while (s) {
04824       ast_cli(a->fd,
04825             "sin=%s timeout=%u state=%d macaddr=%s device=%p session=%p\n",
04826             ast_inet_ntoa(s->sin.sin_addr), s->timeout, s->state, s->macaddr,
04827             s->device, s);
04828       s = s->next;
04829    }
04830    ast_mutex_unlock(&sessionlock);
04831 
04832    return CLI_SUCCESS;
04833 }

static struct ast_channel * unistim_new ( struct unistim_subchannel sub,
int  state,
const char *  linkedid 
) [static]

Protos

Definition at line 4505 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_getformatname(), ast_getformatname_multiple(), ast_hangup(), ast_jb_configure(), ast_log(), ast_mutex_lock, ast_mutex_unlock, ast_pbx_start(), ast_rtp_instance_fd(), ast_setstate(), AST_STATE_DOWN, AST_STATE_RING, ast_strdup, ast_string_field_set, ast_strlen_zero(), ast_update_use_count(), ast_verb, unistim_device::call_forward, ast_channel::caller, unistim_line::callgroup, ast_channel::callgroup, CAPABILITY, unistim_line::capability, unistim_line::cid_num, unistim_line::context, unistim_line::exten, ast_channel::fds, global_jbconf, ast_party_caller::id, language, unistim_line::language, LOG_WARNING, ast_channel::name, ast_party_id::name, name, unistim_device::name, unistim_line::name, ast_channel::nativeformats, ast_party_id::number, unistim_subchannel::owner, 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, unistim_subchannel::rtp, ast_party_name::str, ast_party_number::str, unistim_subchannel::subtype, ast_channel::tech, ast_channel::tech_pvt, unistim_tech, unistimdebug, usecnt, usecnt_lock, ast_party_name::valid, ast_party_number::valid, and ast_channel::writeformat.

Referenced by HandleCallOutgoing(), and unistim_request().

04506 {
04507    struct ast_channel *tmp;
04508    struct unistim_line *l;
04509    int fmt;
04510 
04511    if (!sub) {
04512       ast_log(LOG_WARNING, "subchannel null in unistim_new\n");
04513       return NULL;
04514    }
04515    if (!sub->parent) {
04516       ast_log(LOG_WARNING, "no line for subchannel %p\n", sub);
04517       return NULL;
04518    }
04519    l = sub->parent;
04520    tmp = ast_channel_alloc(1, state, l->cid_num, NULL, l->accountcode, l->exten,
04521       l->context, linkedid, l->amaflags, "%s@%s-%d", l->name, l->parent->name, sub->subtype);
04522    if (unistimdebug)
04523       ast_verb(0, "unistim_new sub=%d (%p) chan=%p\n", sub->subtype, sub, tmp);
04524    if (!tmp) {
04525       ast_log(LOG_WARNING, "Unable to allocate channel structure\n");
04526       return NULL;
04527    }
04528 
04529    tmp->nativeformats = l->capability;
04530    if (!tmp->nativeformats)
04531       tmp->nativeformats = CAPABILITY;
04532    fmt = ast_best_codec(tmp->nativeformats);
04533    if (unistimdebug) {
04534       char tmp1[256], tmp2[256], tmp3[256];
04535       ast_verb(0, "Best codec = %s from nativeformats %s (line cap=%s global=%s)\n",
04536          ast_getformatname(fmt),
04537          ast_getformatname_multiple(tmp1, sizeof(tmp1), tmp->nativeformats),
04538          ast_getformatname_multiple(tmp2, sizeof(tmp2), l->capability),
04539          ast_getformatname_multiple(tmp3, sizeof(tmp3), CAPABILITY));
04540    }
04541    if ((sub->rtp) && (sub->subtype == 0)) {
04542       if (unistimdebug)
04543          ast_verb(0, "New unistim channel with a previous rtp handle ?\n");
04544       tmp->fds[0] = ast_rtp_instance_fd(sub->rtp, 0);
04545       tmp->fds[1] = ast_rtp_instance_fd(sub->rtp, 1);
04546    }
04547    if (sub->rtp)
04548       ast_jb_configure(tmp, &global_jbconf);
04549       
04550 /*      tmp->type = type; */
04551    ast_setstate(tmp, state);
04552    if (state == AST_STATE_RING)
04553       tmp->rings = 1;
04554    tmp->adsicpe = AST_ADSI_UNAVAILABLE;
04555    tmp->writeformat = fmt;
04556    tmp->rawwriteformat = fmt;
04557    tmp->readformat = fmt;
04558    tmp->rawreadformat = fmt;
04559    tmp->tech_pvt = sub;
04560    tmp->tech = &unistim_tech;
04561    if (!ast_strlen_zero(l->language))
04562       ast_string_field_set(tmp, language, l->language);
04563    sub->owner = tmp;
04564    ast_mutex_lock(&usecnt_lock);
04565    usecnt++;
04566    ast_mutex_unlock(&usecnt_lock);
04567    ast_update_use_count();
04568    tmp->callgroup = l->callgroup;
04569    tmp->pickupgroup = l->pickupgroup;
04570    ast_string_field_set(tmp, call_forward, l->parent->call_forward);
04571    if (!ast_strlen_zero(l->cid_num)) {
04572       char *name, *loc, *instr;
04573       instr = ast_strdup(l->cid_num);
04574       if (instr) {
04575          ast_callerid_parse(instr, &name, &loc);
04576          tmp->caller.id.number.valid = 1;
04577          ast_free(tmp->caller.id.number.str);
04578          tmp->caller.id.number.str = ast_strdup(loc);
04579          tmp->caller.id.name.valid = 1;
04580          ast_free(tmp->caller.id.name.str);
04581          tmp->caller.id.name.str = ast_strdup(name);
04582          ast_free(instr);
04583       }
04584    }
04585    tmp->priority = 1;
04586    if (state != AST_STATE_DOWN) {
04587       if (unistimdebug)
04588          ast_verb(0, "Starting pbx in unistim_new\n");
04589       if (ast_pbx_start(tmp)) {
04590          ast_log(LOG_WARNING, "Unable to start PBX on %s\n", tmp->name);
04591          ast_hangup(tmp);
04592          tmp = NULL;
04593       }
04594    }
04595 
04596    return tmp;
04597 }

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

Definition at line 4027 of file chan_unistim.c.

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

04028 {
04029    struct ast_frame *fr;
04030    struct unistim_subchannel *sub = ast->tech_pvt;
04031 
04032    ast_mutex_lock(&sub->lock);
04033    fr = unistim_rtp_read(ast, sub);
04034    ast_mutex_unlock(&sub->lock);
04035 
04036    return fr;
04037 }

static int unistim_register ( struct unistimsession s  )  [static]

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

01466 {
01467    struct unistim_device *d;
01468 
01469    ast_mutex_lock(&devicelock);
01470    d = devices;
01471    while (d) {
01472       if (!strcasecmp(s->macaddr, d->id)) {
01473          /* XXX Deal with IP authentication */
01474          s->device = d;
01475          d->session = s;
01476          d->codec_number = DEFAULT_CODEC;
01477          d->pos_fav = 0;
01478          d->missed_call = 0;
01479          d->receiver_state = STATE_ONHOOK;
01480          break;
01481       }
01482       d = d->next;
01483    }
01484    ast_mutex_unlock(&devicelock);
01485 
01486    if (!d)
01487       return 0;
01488 
01489    return 1;
01490 }

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 4928 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, unistim_reloading, unistimdebug, and ast_cli_entry::usage.

04929 {
04930    switch (cmd) {
04931    case CLI_INIT:
04932       e->command = "unistim reload";
04933       e->usage =
04934          "Usage: unistim reload\n" 
04935          "       Reloads UNISTIM configuration from unistim.conf\n";
04936       return NULL;
04937 
04938    case CLI_GENERATE:
04939       return NULL;   /* no completion */
04940    }
04941 
04942    if (e && a && a->argc != e->args)
04943       return CLI_SHOWUSAGE;
04944 
04945    if (unistimdebug)
04946       ast_verb(0, "reload unistim\n");
04947 
04948    ast_mutex_lock(&unistim_reload_lock);
04949    if (!unistim_reloading)
04950       unistim_reloading = 1;
04951    ast_mutex_unlock(&unistim_reload_lock);
04952 
04953    restart_monitor();
04954 
04955    return CLI_SUCCESS;
04956 }

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

Definition at line 4709 of file chan_unistim.c.

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

04711 {
04712    format_t oldformat;
04713    struct unistim_subchannel *sub;
04714    struct ast_channel *tmpc = NULL;
04715    char tmp[256];
04716    char *dest = data;
04717 
04718    oldformat = format;
04719    format &= CAPABILITY;
04720    ast_log(LOG_NOTICE,
04721          "Asked to get a channel of format %s while capability is %s result : %s\n",
04722          ast_getformatname(oldformat),
04723          ast_getformatname_multiple(tmp, sizeof(tmp), CAPABILITY),
04724          ast_getformatname(format));
04725    if (!format) {
04726       ast_log(LOG_NOTICE,
04727             "Asked to get a channel of unsupported format %s while capability is %s\n",
04728             ast_getformatname(oldformat), ast_getformatname_multiple(tmp, sizeof(tmp), CAPABILITY));
04729       return NULL;
04730    }
04731 
04732    ast_copy_string(tmp, dest, sizeof(tmp));
04733    if (ast_strlen_zero(tmp)) {
04734       ast_log(LOG_NOTICE, "Unistim channels require a device\n");
04735       return NULL;
04736    }
04737 
04738    sub = find_subchannel_by_name(tmp);
04739    if (!sub) {
04740       ast_log(LOG_NOTICE, "No available lines on: %s\n", dest);
04741       *cause = AST_CAUSE_CONGESTION;
04742       return NULL;
04743    }
04744 
04745    ast_verb(3, "unistim_request(%s)\n", tmp);
04746    /* Busy ? */
04747    if (sub->owner) {
04748       if (unistimdebug)
04749          ast_verb(0, "Can't create channel : Busy !\n");
04750       *cause = AST_CAUSE_BUSY;
04751       return NULL;
04752    }
04753    sub->parent->capability = format;
04754    tmpc = unistim_new(sub, AST_STATE_DOWN, requestor ? requestor->linkedid : NULL);
04755    if (!tmpc)
04756       ast_log(LOG_WARNING, "Unable to make channel for '%s'\n", tmp);
04757    if (unistimdebug)
04758       ast_verb(0, "unistim_request owner = %p\n", sub->owner);
04759    restart_monitor();
04760 
04761    /* and finish */
04762    return tmpc;
04763 }

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

Definition at line 3980 of file chan_unistim.c.

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

Referenced by unistim_read().

03982 {
03983    /* Retrieve audio/etc from channel.  Assumes sub->lock is already held. */
03984    struct ast_frame *f;
03985 
03986    if (!ast) {
03987       ast_log(LOG_WARNING, "Channel NULL while reading\n");
03988       return &ast_null_frame;
03989    }
03990 
03991    if (!sub->rtp) {
03992       ast_log(LOG_WARNING, "RTP handle NULL while reading on subchannel %d\n",
03993             sub->subtype);
03994       return &ast_null_frame;
03995    }
03996 
03997    switch (ast->fdno) {
03998    case 0:
03999       f = ast_rtp_instance_read(sub->rtp, 0);     /* RTP Audio */
04000       break;
04001    case 1:
04002       f = ast_rtp_instance_read(sub->rtp, 1);    /* RTCP Control Channel */
04003       break;
04004    default:
04005       f = &ast_null_frame;
04006    }
04007 
04008    if (sub->owner) {
04009       /* We already hold the channel lock */
04010       if (f->frametype == AST_FRAME_VOICE) {
04011          if (f->subclass.codec != sub->owner->nativeformats) {
04012             ast_debug(1,
04013                   "Oooh, format changed from %s to %s\n",
04014                   ast_getformatname(sub->owner->nativeformats),
04015                   ast_getformatname(f->subclass.codec));
04016 
04017             sub->owner->nativeformats = f->subclass.codec;
04018             ast_set_read_format(sub->owner, sub->owner->readformat);
04019             ast_set_write_format(sub->owner, sub->owner->writeformat);
04020          }
04021       }
04022    }
04023 
04024    return f;
04025 }

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

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

04463 {
04464    struct ast_event *event;
04465    int new;
04466    char *mailbox, *context;
04467    struct unistim_line *peer = s->device->lines;
04468 
04469    context = mailbox = ast_strdupa(peer->mailbox);
04470    strsep(&context, "@");
04471    if (ast_strlen_zero(context))
04472       context = "default";
04473 
04474    event = ast_event_get_cached(AST_EVENT_MWI,
04475       AST_EVENT_IE_MAILBOX, AST_EVENT_IE_PLTYPE_STR, mailbox,
04476       AST_EVENT_IE_CONTEXT, AST_EVENT_IE_PLTYPE_STR, context,
04477       AST_EVENT_IE_END);
04478 
04479    if (event) {
04480       new = ast_event_get_ie_uint(event, AST_EVENT_IE_NEWMSGS);
04481       ast_event_destroy(event);
04482    } else { /* Fall back on checking the mailbox directly */
04483       new = ast_app_has_voicemail(peer->mailbox, "INBOX");
04484    }
04485 
04486    peer->nextmsgcheck = tick + TIMER_MWI;
04487 
04488    /* Return now if it's the same thing we told them last time */
04489    if (new == peer->lastmsgssent) {
04490       return 0;
04491    }
04492 
04493    peer->lastmsgssent = new;
04494    if (new == 0) {
04495       send_led_update(s, 0);
04496    } else {
04497       send_led_update(s, 1);
04498    }
04499 
04500    return 0;
04501 }

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

Definition at line 4288 of file chan_unistim.c.

References channel_to_session(), and unistim_do_senddigit().

04289 {
04290    struct unistimsession *pte = channel_to_session(ast);
04291 
04292    if (!pte)
04293       return -1;
04294 
04295    return unistim_do_senddigit(pte, digit);
04296 }

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

Definition at line 4298 of file chan_unistim.c.

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

04299 {
04300    struct unistimsession *pte = channel_to_session(ast);
04301    struct ast_frame f = { 0, };
04302    struct unistim_subchannel *sub;
04303 
04304    sub = pte->device->lines->subs[SUB_REAL];
04305 
04306    if (!sub->owner || sub->alreadygone) {
04307       ast_log(LOG_WARNING, "Unable to find subchannel in dtmf senddigit_end\n");
04308       return -1;
04309    }
04310 
04311    if (unistimdebug)
04312       ast_verb(0, "Send Digit off %c\n", digit);
04313 
04314    if (!pte)
04315       return -1;
04316 
04317    send_tone(pte, 0, 0);
04318    f.frametype = AST_FRAME_DTMF;
04319    f.subclass.integer = digit;
04320    f.src = "unistim";
04321    ast_queue_frame(sub->owner, &f);
04322 
04323    return 0;
04324 }

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

Definition at line 4328 of file chan_unistim.c.

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

04329 {
04330    struct unistimsession *pte = channel_to_session(ast);
04331    int size;
04332    char tmp[TEXT_LENGTH_MAX + 1];
04333 
04334    if (unistimdebug)
04335       ast_verb(0, "unistim_sendtext called\n");
04336 
04337    if (!text) {
04338       ast_log(LOG_WARNING, "unistim_sendtext called with a null text\n");
04339       return 1;
04340    }
04341 
04342    size = strlen(text);
04343    if (text[0] == '@') {
04344       int pos = 0, i = 1, tok = 0, sz = 0;
04345       char label[11];
04346       char number[16];
04347       char icon = '\0';
04348       char cur = '\0';
04349 
04350       memset(label, 0, 11);
04351       memset(number, 0, 16);
04352       while (text[i]) {
04353          cur = text[i++];
04354          switch (tok) {
04355          case 0:
04356             if ((cur < '0') && (cur > '5')) {
04357                ast_log(LOG_WARNING,
04358                      "sendtext failed : position must be a number beetween 0 and 5\n");
04359                return 1;
04360             }
04361             pos = cur - '0';
04362             tok = 1;
04363             continue;
04364          case 1:
04365             if (cur != '@') {
04366                ast_log(LOG_WARNING, "sendtext failed : invalid position\n");
04367                return 1;
04368             }
04369             tok = 2;
04370             continue;
04371          case 2:
04372             if ((cur < '3') && (cur > '6')) {
04373                ast_log(LOG_WARNING,
04374                      "sendtext failed : icon must be a number beetween 32 and 63 (first digit invalid)\n");
04375                return 1;
04376             }
04377             icon = (cur - '0') * 10;
04378             tok = 3;
04379             continue;
04380          case 3:
04381             if ((cur < '0') && (cur > '9')) {
04382                ast_log(LOG_WARNING,
04383                      "sendtext failed : icon must be a number beetween 32 and 63 (second digit invalid)\n");
04384                return 1;
04385             }
04386             icon += (cur - '0');
04387             tok = 4;
04388             continue;
04389          case 4:
04390             if (cur != '@') {
04391                ast_log(LOG_WARNING,
04392                      "sendtext failed : icon must be a number beetween 32 and 63 (too many digits)\n");
04393                return 1;
04394             }
04395             tok = 5;
04396             continue;
04397          case 5:
04398             if (cur == '@') {
04399                tok = 6;
04400                sz = 0;
04401                continue;
04402             }
04403             if (sz > 10)
04404                continue;
04405             label[sz] = cur;
04406             sz++;
04407             continue;
04408          case 6:
04409             if (sz > 15) {
04410                ast_log(LOG_WARNING,
04411                      "sendtext failed : extension too long = %d (15 car max)\n",
04412                      sz);
04413                return 1;
04414             }
04415             number[sz] = cur;
04416             sz++;
04417             continue;
04418          }
04419       }
04420       if (tok != 6) {
04421          ast_log(LOG_WARNING, "sendtext failed : incomplet command\n");
04422          return 1;
04423       }
04424       if (!pte->device) {
04425          ast_log(LOG_WARNING, "sendtext failed : no device ?\n");
04426          return 1;
04427       }
04428       strcpy(pte->device->softkeylabel[pos], label);
04429       strcpy(pte->device->softkeynumber[pos], number);
04430       pte->device->softkeyicon[pos] = icon;
04431       send_favorite(pos, icon, pte, label);
04432       return 0;
04433    }
04434 
04435    if (size <= TEXT_LENGTH_MAX * 2) {
04436       if (pte->device->height == 1) {
04437          send_text(TEXT_LINE0, TEXT_NORMAL, pte, text);
04438       } else {
04439          send_text(TEXT_LINE0, TEXT_NORMAL, pte, "Message :");
04440          send_text(TEXT_LINE1, TEXT_NORMAL, pte, text);
04441       }
04442       if (size <= TEXT_LENGTH_MAX) {
04443          send_text(TEXT_LINE2, TEXT_NORMAL, pte, "");
04444          return 0;
04445       }
04446       memcpy(tmp, text + TEXT_LENGTH_MAX, TEXT_LENGTH_MAX);
04447       tmp[sizeof(tmp) - 1] = '\0';
04448       send_text(TEXT_LINE2, TEXT_NORMAL, pte, tmp);
04449       return 0;
04450    }
04451    send_text(TEXT_LINE0, TEXT_NORMAL, pte, text);
04452    memcpy(tmp, text + TEXT_LENGTH_MAX, TEXT_LENGTH_MAX);
04453    tmp[sizeof(tmp) - 1] = '\0';
04454    send_text(TEXT_LINE1, TEXT_NORMAL, pte, tmp);
04455    memcpy(tmp, text + TEXT_LENGTH_MAX * 2, TEXT_LENGTH_MAX);
04456    tmp[sizeof(tmp) - 1] = '\0';
04457    send_text(TEXT_LINE2, TEXT_NORMAL, pte, tmp);
04458    return 0;
04459 }

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

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

04836 {
04837    BUFFSEND;
04838    struct unistim_subchannel *sub;
04839    int i, j = 0, len;
04840    unsigned char c, cc;
04841    char tmp[256];
04842 
04843    switch (cmd) {
04844    case CLI_INIT:
04845       e->command = "unistim send packet";
04846       e->usage =
04847          "Usage: unistim send packet USTM/line@name hexa\n"
04848          "       unistim send packet USTM/1000@hans 19040004\n";
04849       return NULL;
04850 
04851    case CLI_GENERATE:
04852       return NULL;   /* no completion */
04853    }
04854    
04855    if (a->argc < 5)
04856       return CLI_SHOWUSAGE;
04857 
04858    if (strlen(a->argv[3]) < 9)
04859       return CLI_SHOWUSAGE;
04860 
04861    len = strlen(a->argv[4]);
04862    if (len % 2)
04863       return CLI_SHOWUSAGE;
04864 
04865    ast_copy_string(tmp, a->argv[3] + 5, sizeof(tmp));
04866    sub = find_subchannel_by_name(tmp);
04867    if (!sub) {
04868       ast_cli(a->fd, "Can't find '%s'\n", tmp);
04869       return CLI_SUCCESS;
04870    }
04871    if (!sub->parent->parent->session) {
04872       ast_cli(a->fd, "'%s' is not connected\n", tmp);
04873       return CLI_SUCCESS;
04874    }
04875    ast_cli(a->fd, "Sending '%s' to %s (%p)\n", a->argv[4], tmp, sub->parent->parent->session);
04876    for (i = 0; i < len; i++) {
04877       c = a->argv[4][i];
04878       if (c >= 'a')
04879          c -= 'a' - 10;
04880       else
04881          c -= '0';
04882       i++;
04883       cc = a->argv[4][i];
04884       if (cc >= 'a')
04885          cc -= 'a' - 10;
04886       else
04887          cc -= '0';
04888       tmp[j++] = (c << 4) | cc;
04889    }
04890    memcpy(buffsend + SIZE_HEADER, tmp, j);
04891    send_client(SIZE_HEADER + j, buffsend, sub->parent->parent->session);
04892    return CLI_SUCCESS;
04893 }

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

Definition at line 2017 of file chan_unistim.c.

References ast_copy_string(), ast_log(), ast_pbx_run(), ast_setstate(), AST_STATE_RING, ast_verb, 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, send_tone(), unistim_device::session, unistim_subchannel::subtype, and ast_channel::tech_pvt.

Referenced by HandleCallOutgoing().

02018 {
02019    struct ast_channel *chan = data;
02020    struct unistim_subchannel *sub = chan->tech_pvt;
02021    struct unistim_line *l = sub->parent;
02022    struct unistimsession *s = l->parent->session;
02023    int res;
02024 
02025    ast_verb(3, "Starting switch on '%s@%s-%d' to %s\n", l->name, l->parent->name, sub->subtype, s->device->phone_number);
02026    ast_copy_string(chan->exten, s->device->phone_number, sizeof(chan->exten));
02027    ast_copy_string(s->device->redial_number, s->device->phone_number,
02028                sizeof(s->device->redial_number));
02029    ast_setstate(chan, AST_STATE_RING);
02030    res = ast_pbx_run(chan);
02031    if (res) {
02032       ast_log(LOG_WARNING, "PBX exited non-zero\n");
02033       send_tone(s, 1000, 0);;
02034    }
02035    return NULL;
02036 }

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

Definition at line 4039 of file chan_unistim.c.

References AST_FRAME_IMAGE, AST_FRAME_VOICE, ast_getformatname(), ast_getformatname_multiple(), ast_log(), ast_mutex_lock, ast_mutex_unlock, ast_rtp_instance_write(), ast_frame_subclass::codec, 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.

04040 {
04041    struct unistim_subchannel *sub = ast->tech_pvt;
04042    int res = 0;
04043 
04044    if (frame->frametype != AST_FRAME_VOICE) {
04045       if (frame->frametype == AST_FRAME_IMAGE)
04046          return 0;
04047       else {
04048          ast_log(LOG_WARNING, "Can't send %d type frames with unistim_write\n",
04049                frame->frametype);
04050          return 0;
04051       }
04052    } else {
04053       if (!(frame->subclass.codec & ast->nativeformats)) {
04054          char tmp[256];
04055          ast_log(LOG_WARNING,
04056                "Asked to transmit frame type %s, while native formats is %s (read/write = (%s/%s)\n",
04057                ast_getformatname(frame->subclass.codec),
04058                ast_getformatname_multiple(tmp, sizeof(tmp), ast->nativeformats),
04059                ast_getformatname(ast->readformat),
04060                ast_getformatname(ast->writeformat));
04061          return -1;
04062       }
04063    }
04064 
04065    if (sub) {
04066       ast_mutex_lock(&sub->lock);
04067       if (sub->rtp) {
04068          res = ast_rtp_instance_write(sub->rtp, frame);
04069       }
04070       ast_mutex_unlock(&sub->lock);
04071    }
04072 
04073    return res;
04074 }

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

Definition at line 3923 of file chan_unistim.c.

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

Referenced by do_monitor().

03924 {
03925    struct sockaddr_in addr_from = { 0, };
03926    struct unistimsession *cur = NULL;
03927    int found = 0;
03928    int tmp = 0;
03929    int dw_num_bytes_rcvd;
03930 #ifdef DUMP_PACKET
03931    int dw_num_bytes_rcvdd;
03932    char iabuf[INET_ADDRSTRLEN];
03933 #endif
03934 
03935    dw_num_bytes_rcvd =
03936       recvfrom(unistimsock, buff, SIZE_PAGE, 0, (struct sockaddr *) &addr_from,
03937              &size_addr_from);
03938    if (dw_num_bytes_rcvd == -1) {
03939       if (errno == EAGAIN)
03940          ast_log(LOG_NOTICE, "UNISTIM: Received packet with bad UDP checksum\n");
03941       else if (errno != ECONNREFUSED)
03942          ast_log(LOG_WARNING, "Recv error %d (%s)\n", errno, strerror(errno));
03943       return 1;
03944    }
03945 
03946    /* Looking in the phone list if we already have a registration for him */
03947    ast_mutex_lock(&sessionlock);
03948    cur = sessions;
03949    while (cur) {
03950       if (cur->sin.sin_addr.s_addr == addr_from.sin_addr.s_addr) {
03951          found = 1;
03952          break;
03953       }
03954       tmp++;
03955       cur = cur->next;
03956    }
03957    ast_mutex_unlock(&sessionlock);
03958 
03959 #ifdef DUMP_PACKET
03960    if (unistimdebug)
03961       ast_verb(0, "\n*** Dump %d bytes from %s - phone_table[%d] ***\n",
03962                dw_num_bytes_rcvd, ast_inet_ntoa(addr_from.sin_addr), tmp);
03963    for (dw_num_bytes_rcvdd = 0; dw_num_bytes_rcvdd < dw_num_bytes_rcvd;
03964        dw_num_bytes_rcvdd++)
03965       ast_verb(0, "%.2x ", (unsigned char) buff[dw_num_bytes_rcvdd]);
03966    ast_verb(0, "\n******************************************\n");
03967 #endif
03968 
03969    if (!found) {
03970       if (unistimdebug)
03971          ast_verb(0, "Received a packet from an unknown source\n");
03972       parsing(dw_num_bytes_rcvd, buff, NULL, (struct sockaddr_in *) &addr_from);
03973 
03974    } else
03975       parsing(dw_num_bytes_rcvd, buff, cur, (struct sockaddr_in *) &addr_from);
03976 
03977    return 1;
03978 }

static int unload_module ( void   )  [static]

Definition at line 5693 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_glue_unregister(), buff, monitor_thread, monlock, sched_context_destroy(), unistim_cli, unistim_rtp_glue, unistim_tech, and unistimsock.

05694 {
05695    /* First, take us out of the channel loop */
05696    if (sched)
05697       sched_context_destroy(sched);
05698 
05699    ast_cli_unregister_multiple(unistim_cli, ARRAY_LEN(unistim_cli));
05700 
05701    ast_channel_unregister(&unistim_tech);
05702    ast_rtp_glue_unregister(&unistim_rtp_glue);
05703 
05704    ast_mutex_lock(&monlock);
05705    if (monitor_thread && (monitor_thread != AST_PTHREADT_STOP) && (monitor_thread != AST_PTHREADT_NULL)) {
05706       pthread_cancel(monitor_thread);
05707       pthread_kill(monitor_thread, SIGURG);
05708       pthread_join(monitor_thread, NULL);
05709    }
05710    monitor_thread = AST_PTHREADT_STOP;
05711    ast_mutex_unlock(&monlock);
05712 
05713    if (buff)
05714       ast_free(buff);
05715    if (unistimsock > -1)
05716       close(unistimsock);
05717 
05718    return 0;
05719 }

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

Definition at line 4965 of file chan_unistim.c.

References len().

Referenced by build_device().

04966 {
04967    int len = strlen(src);
04968    if (!len)
04969       return;
04970    if ((len > 1) && src[0] == '\"') {
04971       /* This is a quoted string */
04972       src++;
04973       /* Don't take more than what's there */
04974       len--;
04975       if (maxlen > len - 1)
04976          maxlen = len - 1;
04977       memcpy(out, src, maxlen);
04978       ((char *) out)[maxlen] = '\0';
04979    } else
04980       memcpy(out, src, maxlen);
04981    return;
04982 }

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

Definition at line 1110 of file chan_unistim.c.

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

Referenced by close_client(), and key_main_page().

01111 {
01112    if (unistimdebug)
01113       ast_verb(0, "Trying to unregister extension '%s' context '%s'\n",
01114                pte->device->extension_number, pte->device->lines->context);
01115    return ast_context_remove_extension(pte->device->lines->context,
01116                               pte->device->extension_number, 1, "Unistim");
01117 }

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

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

01685 {
01686    if (fwrite(&c, 1, 1, f) != 1) {
01687       display_last_error("Unable to write history log header.");
01688       return -1;
01689    }
01690    if (fwrite(line1, TEXT_LENGTH_MAX, 1, f) != 1) {
01691       display_last_error("Unable to write history entry - date.");
01692       return -1;
01693    }
01694    if (fwrite(pte->device->lst_cid, TEXT_LENGTH_MAX, 1, f) != 1) {
01695       display_last_error("Unable to write history entry - callerid.");
01696       return -1;
01697    }
01698    if (fwrite(pte->device->lst_cnm, TEXT_LENGTH_MAX, 1, f) != 1) {
01699       display_last_error("Unable to write history entry - callername.");
01700       return -1;
01701    }
01702    return 0;
01703 }

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

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

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


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

Definition at line 5732 of file chan_unistim.c.

struct sockaddr_in address_from [static]

give the IP address for the last packet received

Definition at line 228 of file chan_unistim.c.

struct ast_module_info* ast_module_info = &__mod_info [static]

Definition at line 5732 of file chan_unistim.c.

enum autoprovision autoprovisioning = AUTOPROVISIONING_NO [static]

Definition at line 213 of file chan_unistim.c.

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

unsigned char* buff [static]

Receive buffer address

Definition at line 232 of file chan_unistim.c.

Referenced by clean_up_bc(), init_bc(), isdn_port_info(), load_module(), moh_class_destructor(), setup_bc(), socket_receive_file_to_buff(), stack_init(), te_lib_init(), unistimsock_read(), and unload_module().

const char channel_type[] = "USTM" [static]

Definition at line 678 of file chan_unistim.c.

unsigned int cos

Definition at line 220 of file chan_unistim.c.

unsigned int cos_audio

Definition at line 221 of file chan_unistim.c.

struct ast_jb_conf default_jbconf [static]

Global jitterbuffer configuration - by default, jb is disabled.

Note:
Values shown here match the defaults shown in unistim.conf.sample

Definition at line 195 of file chan_unistim.c.

ast_mutex_t devicelock = { PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP , NULL, 1 } [static]

Protect the device list

Definition at line 249 of file chan_unistim.c.

Referenced by build_device(), find_subchannel_by_name(), key_main_page(), key_select_extension(), rcv_mac_addr(), reload_config(), and unistim_register().

struct unistim_device * devices [static]

A device containing one or more lines.

struct tone_zone_unistim frequency[] [static]

Definition at line 316 of file chan_unistim.c.

Referenced by SendDialTone().

struct ast_jb_conf global_jbconf [static]

Definition at line 203 of file chan_unistim.c.

struct io_context* io [static]

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

ast_mutex_t monlock = { PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP , NULL, 1 } [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 245 of file chan_unistim.c.

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

Referenced by parsing().

const unsigned char packet_recv_firm_version[] [static]

Initial value:

   { 0x00, 0x00, 0x00, 0x13, 0x9a, 0x0a, 0x02 }

Definition at line 516 of file chan_unistim.c.

Referenced by process_request().

const unsigned char packet_recv_hangup[] [static]

Initial value:

   { 0x00, 0x00, 0x00, 0x13, 0x99, 0x03, 0x03 }

Definition at line 522 of file chan_unistim.c.

Referenced by process_request().

const unsigned char packet_recv_mac_addr[] [static]

Initial value:

   { 0xff, 0xff, 0xff, 0xff, 0x9a, 0x0d, 0x07   }

Definition at line 529 of file chan_unistim.c.

Referenced by process_request().

const unsigned char packet_recv_pick_up[] [static]

Initial value:

   { 0x00, 0x00, 0x00, 0x13, 0x99, 0x03, 0x04 }

Definition at line 520 of file chan_unistim.c.

Referenced by process_request().

const unsigned char packet_recv_pressed_key[] [static]

Initial value:

   { 0x00, 0x00, 0x00, 0x13, 0x99, 0x04, 0x00 }

Definition at line 518 of file chan_unistim.c.

Referenced by process_request().

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

Definition at line 524 of file chan_unistim.c.

Referenced by process_request().

const unsigned char packet_recv_resume_connection_with_server[] [static]

Initial value:

   { 0xff, 0xff, 0xff, 0xff, 0x9e, 0x03, 0x08 }
TransportAdapter

Definition at line 527 of file chan_unistim.c.

Referenced by process_request().

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

Definition at line 624 of file chan_unistim.c.

Referenced by init_phone_step2().

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

Definition at line 625 of file chan_unistim.c.

Referenced by send_blink_cursor().

const unsigned char packet_send_call[] [static]

Definition at line 552 of file chan_unistim.c.

Referenced by start_rtp().

const unsigned char packet_send_Contrast[] [static]

Initial value:

   { 0x17, 0x04, 0x24,  0x08 }

Definition at line 629 of file chan_unistim.c.

Referenced by init_phone_step2().

const unsigned char packet_send_date_time[] [static]

Definition at line 536 of file chan_unistim.c.

Referenced by send_date_time().

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

Referenced by send_date_time2().

const unsigned char packet_send_date_time3[] [static]

Initial value:

   { 0x11, 0x09, 0x02, 0x02,  0x05,  0x06,  0x07,
 0x08, 0x32
}

Definition at line 532 of file chan_unistim.c.

Referenced by send_date_time3().

const unsigned char packet_send_discovery_ack[] [static]

Initial value:

   { 0x00, 0x00,  0x00, 0x00, 0x00, 0x01 }

Definition at line 513 of file chan_unistim.c.

Referenced by parsing().

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

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

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

Referenced by start_rtp().

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

Definition at line 665 of file chan_unistim.c.

Referenced by send_led_update().

const unsigned char packet_send_no_ring[] [static]

Initial value:

   { 0x16, 0x04, 0x1a, 0x00, 0x16, 0x04, 0x11, 0x00 }

Definition at line 543 of file chan_unistim.c.

Referenced by send_no_ring().

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

Referenced by start_rtp().

const unsigned char packet_send_open_audio_stream_rx3[] [static]

Definition at line 610 of file chan_unistim.c.

Referenced by start_rtp().

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

Referenced by start_rtp().

const unsigned char packet_send_open_audio_stream_tx3[] [static]

Definition at line 617 of file chan_unistim.c.

Referenced by start_rtp().

unsigned char packet_send_ping[] [static]

Initial value:

   { 0x1e, 0x05, 0x12, 0x00,  0x78 }

Definition at line 672 of file chan_unistim.c.

Referenced by reload_config().

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

Definition at line 667 of file chan_unistim.c.

Referenced by rcv_mac_addr().

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

Definition at line 669 of file chan_unistim.c.

Referenced by rcv_mac_addr().

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

Definition at line 668 of file chan_unistim.c.

Referenced by rcv_resume_connection_with_server().

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

Referenced by send_ring().

const unsigned char packet_send_rtp_packet_size[] [static]

Initial value:

   { 0x16, 0x08, 0x38, 0x00, 0x00, 0xe0, 0x00, 0xa0 }

Definition at line 588 of file chan_unistim.c.

Referenced by start_rtp().

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

Definition at line 670 of file chan_unistim.c.

Referenced by rcv_mac_addr().

const unsigned char packet_send_s4[] [static]

Definition at line 545 of file chan_unistim.c.

Referenced by init_phone_step2().

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

Definition at line 636 of file chan_unistim.c.

Referenced by init_phone_step2().

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

Referenced by init_phone_step2().

const unsigned char packet_send_select_output[] [static]

Initial value:

   { 0x16, 0x06, 0x32, 0xc0, 0x01, 0x00 }

Definition at line 573 of file chan_unistim.c.

Referenced by send_select_output().

const unsigned char packet_send_set_pos_cursor[] [static]

Initial value:

   { 0x17, 0x06, 0x10, 0x81, 0x04,  0x20 }

Definition at line 637 of file chan_unistim.c.

Referenced by send_cursor_pos().

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

Referenced by send_text_status().

const unsigned char packet_send_status2[] [static]

Initial value:

   { 0x17, 0x0b, 0x19,  0x00,  0x20, 0x20, 0x20, 0x20,
0x20, 0x20, 0x20   }

Definition at line 661 of file chan_unistim.c.

Referenced by send_text_status().

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

Definition at line 634 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 571 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 561 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 567 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 569 of file chan_unistim.c.

const unsigned char packet_send_text[] [static]

Definition at line 650 of file chan_unistim.c.

Referenced by send_text().

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

Referenced by send_texttitle().

struct sockaddr_in public_ip = { 0, } [static]

Definition at line 226 of file chan_unistim.c.

Referenced by reload_config(), and start_rtp().

struct { ... } qos [static]

struct sched_context* sched [static]

Definition at line 225 of file chan_unistim.c.

ast_mutex_t sessionlock = { PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP , NULL, 1 } [static]

Protect the session list

Definition at line 247 of file chan_unistim.c.

Referenced by close_client(), create_client(), do_monitor(), 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 230 of file chan_unistim.c.

Referenced by unistimsock_read().

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

Definition at line 677 of file chan_unistim.c.

unsigned int tos

Definition at line 218 of file chan_unistim.c.

unsigned int tos_audio

Definition at line 219 of file chan_unistim.c.

struct ast_cli_entry unistim_cli[] [static]

Definition at line 4958 of file chan_unistim.c.

Referenced by load_module(), and unload_module().

int unistim_keepalive [static]

Definition at line 214 of file chan_unistim.c.

Referenced by reload_config().

int unistim_port [static]

Definition at line 212 of file chan_unistim.c.

Referenced by reload_config().

ast_mutex_t unistim_reload_lock = { PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP , NULL, 1 } [static]

Definition at line 234 of file chan_unistim.c.

Referenced by do_monitor(), and unistim_reload().

int unistim_reloading = 0 [static]

Definition at line 233 of file chan_unistim.c.

Referenced by do_monitor(), and unistim_reload().

struct ast_rtp_glue unistim_rtp_glue [static]

Initial value:

 {
   .type = channel_type,
   .get_rtp_info = unistim_get_rtp_peer,
}

Definition at line 5636 of file chan_unistim.c.

Referenced by load_module(), and unload_module().

struct ast_channel_tech unistim_tech [static]

Definition at line 706 of file chan_unistim.c.

Referenced by load_module(), unistim_new(), and unload_module().

int unistimdebug = 0 [static]

Enable verbose output. can also be set with the CLI

Definition at line 211 of file chan_unistim.c.

Referenced by alloc_sub(), build_device(), close_client(), find_subchannel_by_name(), HandleCallIncoming(), HandleCallOutgoing(), init_phone_step2(), key_dial_page(), ParseBookmark(), parsing(), process_request(), rcv_mac_addr(), rcv_resume_connection_with_server(), RegisterExtension(), reload_config(), send_blink_cursor(), send_cursor_pos(), send_date_time(), send_date_time2(), send_date_time3(), send_led_update(), send_no_ring(), send_retransmit(), send_ring(), send_select_output(), send_text(), send_text_status(), send_texttitle(), SendDialTone(), start_rtp(), swap_subs(), TransferCallStep1(), unalloc_sub(), unistim_answer(), unistim_call(), unistim_do_debug(), unistim_do_senddigit(), unistim_hangup(), unistim_indicate(), unistim_new(), unistim_reload(), unistim_request(), unistim_senddigit_end(), unistim_sendtext(), unistimsock_read(), and UnregisterExtension().

int unistimsock = -1 [static]

Definition at line 215 of file chan_unistim.c.

Referenced by build_device(), do_monitor(), unistimsock_read(), and unload_module().

int usecnt = 0 [static]

Definition at line 236 of file chan_unistim.c.

Referenced by unistim_new().

ast_mutex_t usecnt_lock = { PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP , NULL, 1 } [static]

Definition at line 235 of file chan_unistim.c.

Referenced by unistim_new().


Generated on Mon Oct 8 12:39:19 2012 for Asterisk - The Open Source Telephony Project by  doxygen 1.4.7