Sat Feb 11 06:34:52 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"

Include dependency graph for chan_unistim.c:

Go to the source code of this file.

Data Structures

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

Defines

#define AST_CONFIG_MAX_PATH   255
#define BUFFSEND   unsigned char buffsend[64] = { 0x00, 0x00, 0xaa, 0xbb, 0x02, 0x01 }
#define 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, const 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 unistim_lineunistim_line_alloc (void)
static void unistim_line_copy (struct unistim_line *dst, struct unistim_line *src)
static struct unistim_lineunistim_line_destroy (struct unistim_line *l)
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, struct ast_format_cap *cap, const struct ast_channel *requestor, const char *dest, int *cause)
static struct ast_frameunistim_rtp_read (const struct ast_channel *ast, const struct unistim_subchannel *sub)
static int unistim_send_mwi_to_peer (struct unistimsession *s, unsigned int tick)
static int unistim_senddigit_begin (struct ast_channel *ast, char digit)
static int unistim_senddigit_end (struct ast_channel *ast, char digit, unsigned int duration)
static int unistim_sendtext (struct ast_channel *ast, const char *text)
static char * unistim_sp (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
static void * unistim_ss (void *data)
static int unistim_write (struct ast_channel *ast, struct ast_frame *frame)
static int unistimsock_read (int *id, int fd, short events, void *ignore)
static int unload_module (void)
static void unquote (char *out, const char *src, int maxlen)
static int UnregisterExtension (const struct unistimsession *pte)
static int write_entry_history (struct unistimsession *pte, FILE *f, char c, char *line1)
static int write_history (struct unistimsession *pte, char way, char ismissed)

Variables

static struct ast_module_info __mod_info = { .name = AST_MODULE, .flags = AST_MODFLAG_DEFAULT , .description = "UNISTIM Protocol (USTM)" , .key = "This paragraph is copyright (c) 2006 by Digium, Inc. \In order for your module to load, it must return this \key via a function called \"key\". Any code which \includes this paragraph must be licensed under the GNU \General Public License version 2 or later (at your \option). In addition to Digium's general reservations \of rights, Digium expressly reserves the right to \allow other parties to license this paragraph under \different terms. Any use of Digium, Inc. trademarks or \logos (including \"Asterisk\" or \"Digium\") without \express written permission of Digium, Inc. is prohibited.\n" , .buildopt_sum = AST_BUILDOPT_SUM, .load = load_module, .unload = unload_module, .reload = reload, }
static struct sockaddr_in address_from
static struct ast_module_infoast_module_info = &__mod_info
static enum autoprovision autoprovisioning = AUTOPROVISIONING_NO
static unsigned char * buff
static const char channel_type [] = "USTM"
static struct ast_jb_conf default_jbconf
 Global jitterbuffer configuration - by default, jb is disabled.
static ast_mutex_t devicelock = { PTHREAD_MUTEX_INITIALIZER , NULL, 1 }
static struct unistim_devicedevices
 A device containing one or more lines.
static struct tone_zone_unistim frequency []
struct ast_format_capglobal_cap
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_MUTEX_INITIALIZER , 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 ast_sched_contextsched
static ast_mutex_t sessionlock = { PTHREAD_MUTEX_INITIALIZER , 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_MUTEX_INITIALIZER , 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_MUTEX_INITIALIZER , 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 101 of file chan_unistim.c.

Referenced by OpenHistory(), and write_history().

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

#define DEBUG_TIMER   dummy

Definition at line 210 of file chan_unistim.c.

Referenced by do_monitor(), and set_ping_timer().

#define DEFAULT_CODEC   0x00

Not used

Definition at line 98 of file chan_unistim.c.

Referenced by key_select_extension(), and unistim_register().

#define DEFAULTCALLERID   "Unknown"

Definition at line 80 of file chan_unistim.c.

Referenced by unistim_call().

#define DEFAULTCALLERNAME   " "

Definition at line 81 of file chan_unistim.c.

Referenced by unistim_call().

#define DEFAULTCONTEXT   "default"

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

Definition at line 79 of file chan_unistim.c.

Referenced by build_device().

#define DEFAULTHEIGHT   3

Definition at line 82 of file chan_unistim.c.

Referenced by build_device().

#define DEVICE_NAME_LEN   16

Definition at line 100 of file chan_unistim.c.

#define FAV_BLINK_FAST   0x20

Definition at line 184 of file chan_unistim.c.

Referenced by unistim_call().

#define FAV_BLINK_SLOW   0x40

Definition at line 185 of file chan_unistim.c.

Referenced by show_main_page().

#define FAV_ICON_BOX   0x3F

Definition at line 182 of file chan_unistim.c.

#define FAV_ICON_CALL_CENTER   0x34

Definition at line 171 of file chan_unistim.c.

Referenced by show_main_page().

#define FAV_ICON_CITY   0x31

Definition at line 168 of file chan_unistim.c.

#define FAV_ICON_COMPUTER   0x38

Definition at line 175 of file chan_unistim.c.

#define FAV_ICON_FAX   0x35

Definition at line 172 of file chan_unistim.c.

#define FAV_ICON_FORWARD   0x39

Definition at line 176 of file chan_unistim.c.

#define FAV_ICON_HEADPHONES   0x2E

Definition at line 165 of file chan_unistim.c.

Referenced by send_select_output().

#define FAV_ICON_HEADPHONES_ONHOLD   0x2F

Definition at line 166 of file chan_unistim.c.

Referenced by refresh_all_favorite(), and send_select_output().

#define FAV_ICON_HOME   0x30

Definition at line 167 of file chan_unistim.c.

#define FAV_ICON_INBOX   0x3C

Definition at line 179 of file chan_unistim.c.

#define FAV_ICON_LOCKED   0x3A

Definition at line 177 of file chan_unistim.c.

#define FAV_ICON_MAILBOX   0x36

Definition at line 173 of file chan_unistim.c.

#define FAV_ICON_MEETING   0x3E

Definition at line 181 of file chan_unistim.c.

#define FAV_ICON_NONE   0x00

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

Referenced by send_select_output().

#define FAV_ICON_OFFHOOK_WHITE   0x25

Definition at line 156 of file chan_unistim.c.

#define FAV_ICON_ONHOLD_BLACK   0x26

Definition at line 157 of file chan_unistim.c.

Referenced by send_select_output().

#define FAV_ICON_ONHOLD_WHITE   0x27

Definition at line 158 of file chan_unistim.c.

#define FAV_ICON_ONHOOK_BLACK   0x20

Definition at line 151 of file chan_unistim.c.

Referenced by build_device(), and show_main_page().

#define FAV_ICON_ONHOOK_WHITE   0x21

Definition at line 152 of file chan_unistim.c.

#define FAV_ICON_OUTBOX   0x3D

Definition at line 180 of file chan_unistim.c.

#define FAV_ICON_PAGER   0x33

Definition at line 170 of file chan_unistim.c.

#define FAV_ICON_PHONE_BLACK   0x2A

Definition at line 161 of file chan_unistim.c.

Referenced by handle_dial_page().

#define FAV_ICON_PHONE_WHITE   0x2B

Definition at line 162 of file chan_unistim.c.

#define FAV_ICON_REFLECT   0x37

Definition at line 174 of file chan_unistim.c.

Referenced by show_main_page().

#define FAV_ICON_SHARP   0x32

Definition at line 169 of file chan_unistim.c.

Referenced by ParseBookmark().

#define FAV_ICON_SPEAKER_OFFHOOK_BLACK   0x28

Definition at line 159 of file chan_unistim.c.

Referenced by send_select_output().

#define FAV_ICON_SPEAKER_OFFHOOK_WHITE   0x29

Definition at line 160 of file chan_unistim.c.

#define FAV_ICON_SPEAKER_ONHOLD_BLACK   0x2C

Definition at line 163 of file chan_unistim.c.

Referenced by send_select_output().

#define FAV_ICON_SPEAKER_ONHOLD_WHITE   0x2D

Definition at line 164 of file chan_unistim.c.

#define FAV_ICON_SPEAKER_ONHOOK_BLACK   0x22

Definition at line 153 of file chan_unistim.c.

Referenced by send_select_output(), and unistim_call().

#define FAV_ICON_SPEAKER_ONHOOK_WHITE   0x23

Definition at line 154 of file chan_unistim.c.

#define FAV_ICON_TRASH   0x3B

Definition at line 178 of file chan_unistim.c.

#define FAV_MAX_LENGTH   0x0A

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

Referenced by do_monitor().

#define MAX_BUF_NUMBER   50

Number of slots for the transmit queue

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

#define MAX_ENTRY_LOG   30

Definition at line 102 of file chan_unistim.c.

Referenced by OpenHistory(), and write_history().

#define MAX_SUBS   2

Definition at line 106 of file chan_unistim.c.

#define MUTE_OFF   0x00

#define MUTE_ON   0xFF

Definition at line 137 of file chan_unistim.c.

Referenced by key_call(), and send_select_output().

#define MUTE_ON_DISCRET   0xCE

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

Referenced by reload_config(), and send_retransmit().

#define OUTPUT_HANDSET   0xC0

#define OUTPUT_HEADPHONE   0xC1

#define OUTPUT_SPEAKER   0xC2

#define RETRANSMIT_TIMER   2000

Wait x milliseconds before resending a packet

Definition at line 94 of file chan_unistim.c.

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

#define SELECTCODEC_MAX_LENGTH   2

Definition at line 2864 of file chan_unistim.c.

Referenced by key_select_codec().

#define SELECTCODEC_MSG   "Codec number : .."

Definition at line 2865 of file chan_unistim.c.

Referenced by HandleSelectCodec(), and key_select_codec().

#define SELECTCODEC_START_ENTRY_POS   15

Definition at line 2863 of file chan_unistim.c.

Referenced by HandleSelectCodec(), and key_select_codec().

#define SELECTEXTENSION_MAX_LENGTH   10

Definition at line 2941 of file chan_unistim.c.

Referenced by key_select_extension().

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

Definition at line 2942 of file chan_unistim.c.

Referenced by key_select_extension(), and ShowExtensionPage().

#define SELECTEXTENSION_START_ENTRY_POS   0

Definition at line 2940 of file chan_unistim.c.

Referenced by key_select_extension(), and ShowExtensionPage().

#define SIZE_HEADER   6

#define SIZE_MAC_ADDR   17

Definition at line 141 of file chan_unistim.c.

#define SIZE_PAGE   4096

Definition at line 99 of file chan_unistim.c.

Referenced by load_module(), and unistimsock_read().

#define STATUS_LENGTH_MAX   28

Definition at line 148 of file chan_unistim.c.

Referenced by send_text_status(), and show_entry_history().

#define SUB_REAL   0

Definition at line 104 of file chan_unistim.c.

#define SUB_THREEWAY   1

Definition at line 105 of file chan_unistim.c.

#define TEXT_INVERSE   0x25

Definition at line 147 of file chan_unistim.c.

Referenced by HandleSelectCodec(), and key_select_codec().

#define TEXT_LENGTH_MAX   24

#define TEXT_LINE0   0x00

#define TEXT_LINE1   0x20

#define TEXT_LINE2   0x40

#define TEXT_NORMAL   0x05

#define TIMER_MWI   10000

How often the mailbox is checked for new messages

Definition at line 96 of file chan_unistim.c.

Referenced by unistim_send_mwi_to_peer().

#define USTM_LOG_DIR   "unistimHistory"

Definition at line 83 of file chan_unistim.c.

Referenced by OpenHistory(), and write_history().

#define VOLUME_INSANELY_LOUD   0x07

Definition at line 134 of file chan_unistim.c.

#define VOLUME_LOW   0x01

Definition at line 131 of file chan_unistim.c.

Referenced by build_device(), and send_select_output().

#define VOLUME_LOW_SPEAKER   0x03

Definition at line 132 of file chan_unistim.c.

Referenced by send_select_output().

#define VOLUME_NORMAL   0x02

Definition at line 133 of file chan_unistim.c.


Enumeration Type Documentation

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

Definition at line 117 of file chan_unistim.c.

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

Enumerator:
AUTOPROVISIONING_NO 
AUTOPROVISIONING_YES 
AUTOPROVISIONING_DB 
AUTOPROVISIONING_TN 

Definition at line 110 of file chan_unistim.c.

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

Enumerator:
STATE_ONHOOK 
STATE_OFFHOOK 

Definition at line 265 of file chan_unistim.c.

00265                    {
00266    STATE_ONHOOK,
00267    STATE_OFFHOOK,
00268 };

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

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

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

Definition at line 252 of file chan_unistim.c.

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


Function Documentation

static void __reg_module ( void   )  [static]

Definition at line 5776 of file chan_unistim.c.

static void __unreg_module ( void   )  [static]

Definition at line 5776 of file chan_unistim.c.

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

Definition at line 1524 of file chan_unistim.c.

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

01525 {
01526    struct unistim_subchannel *sub;
01527    if (!(sub = ast_calloc(1, sizeof(*sub))))
01528       return 0;
01529 
01530    if (unistimdebug)
01531       ast_verb(3, "Allocating UNISTIM subchannel #%d on %s@%s ptr=%p\n", x, l->name, l->parent->name, sub);
01532    sub->parent = l;
01533    sub->subtype = x;
01534    l->subs[x] = sub;
01535    ast_mutex_init(&sub->lock);
01536    return 1;
01537 }

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

Definition at line 1928 of file chan_unistim.c.

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

01929 {
01930    int res = 0;
01931    struct ast_channel
01932     *chana = NULL, *chanb = NULL, *bridgea = NULL, *bridgeb = NULL, *peera =
01933       NULL, *peerb = NULL, *peerc = NULL;
01934 
01935    if (!p1->owner || !p2->owner) {
01936       ast_log(LOG_WARNING, "Transfer attempted without dual ownership?\n");
01937       return -1;
01938    }
01939    chana = p1->owner;
01940    chanb = p2->owner;
01941    bridgea = ast_bridged_channel(chana);
01942    bridgeb = ast_bridged_channel(chanb);
01943 
01944    if (bridgea) {
01945       peera = chana;
01946       peerb = chanb;
01947       peerc = bridgea;
01948    } else if (bridgeb) {
01949       peera = chanb;
01950       peerb = chana;
01951       peerc = bridgeb;
01952    }
01953 
01954    if (peera && peerb && peerc && (peerb != peerc)) {
01955       /*ast_quiet_chan(peera);
01956          ast_quiet_chan(peerb);
01957          ast_quiet_chan(peerc);
01958          ast_quiet_chan(peerd); */
01959 
01960       if (peera->cdr && peerb->cdr) {
01961          peerb->cdr = ast_cdr_append(peerb->cdr, peera->cdr);
01962       } else if (peera->cdr) {
01963          peerb->cdr = peera->cdr;
01964       }
01965       peera->cdr = NULL;
01966 
01967       if (peerb->cdr && peerc->cdr) {
01968          peerb->cdr = ast_cdr_append(peerb->cdr, peerc->cdr);
01969       } else if (peerc->cdr) {
01970          peerb->cdr = peerc->cdr;
01971       }
01972       peerc->cdr = NULL;
01973 
01974       if (ast_channel_masquerade(peerb, peerc)) {
01975          ast_log(LOG_WARNING, "Failed to masquerade %s into %s\n", ast_channel_name(peerb),
01976                ast_channel_name(peerc));
01977          res = -1;
01978       }
01979       return res;
01980    } else {
01981       ast_log(LOG_NOTICE,
01982             "Transfer attempted with no appropriate bridged calls to transfer\n");
01983       if (chana)
01984          ast_softhangup_nolock(chana, AST_SOFTHANGUP_DEV);
01985       if (chanb)
01986          ast_softhangup_nolock(chanb, AST_SOFTHANGUP_DEV);
01987       return -1;
01988    }
01989    return 0;
01990 }

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

Definition at line 5118 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_format_cap_copy(), ast_free, ast_get_group(), ast_get_indication_zone(), ast_localtime(), ast_log(), AST_MAX_EXTENSION, ast_mutex_destroy, ast_mutex_init, ast_mutex_lock, ast_mutex_unlock, ast_strlen_zero(), ast_tone_zone_unref(), ast_true(), ast_tvnow(), ast_verb, AUTOPROVISIONING_TN, unistim_line::callgroup, unistim_device::callhistory, unistim_line::cap, 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, unistim_line_alloc(), unistim_line_destroy(), unquote(), ast_variable::value, unistim_device::volume, and VOLUME_LOW.

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

static void cancel_dial ( struct unistimsession pte  )  [static]

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

01892 {
01893    send_no_ring(pte);
01894    pte->device->missed_call++;
01895    write_history(pte, 'i', 1);
01896    show_main_page(pte);
01897    return;
01898 }

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

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

01993 {
01994    char *data;
01995    int size;
01996 
01997    if (type)
01998       data = pte->device->lst_cnm;
01999    else
02000       data = pte->device->lst_cid;
02001 
02002    /* This is very nearly strncpy(), except that the remaining buffer
02003     * is padded with ' ', instead of '\0' */
02004    memset(data, ' ', TEXT_LENGTH_MAX);
02005    size = strlen(callerid);
02006    if (size > TEXT_LENGTH_MAX)
02007       size = TEXT_LENGTH_MAX;
02008    memcpy(data, callerid, size);
02009 }

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

Definition at line 1076 of file chan_unistim.c.

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

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

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, read]

Definition at line 3717 of file chan_unistim.c.

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

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

03718 {
03719    struct unistim_subchannel *sub;
03720    if (!ast) {
03721       ast_log(LOG_WARNING, "Unistim callback function called with a null channel\n");
03722       return NULL;
03723    }
03724    if (!ast->tech_pvt) {
03725       ast_log(LOG_WARNING, "Unistim callback function called without a tech_pvt\n");
03726       return NULL;
03727    }
03728    sub = ast->tech_pvt;
03729 
03730    if (!sub->parent) {
03731       ast_log(LOG_WARNING, "Unistim callback function called without a line\n");
03732       return NULL;
03733    }
03734    if (!sub->parent->parent) {
03735       ast_log(LOG_WARNING, "Unistim callback function called without a device\n");
03736       return NULL;
03737    }
03738    if (!sub->parent->parent->session) {
03739       ast_log(LOG_WARNING, "Unistim callback function called without a session\n");
03740       return NULL;
03741    }
03742    return sub->parent->parent->session;
03743 }

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 2011 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, SUB_REAL, SUB_THREEWAY, unistim_line::subs, unistim_subchannel::subtype, and write_history().

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

02012 {
02013    struct unistim_subchannel *sub;
02014    struct unistim_line *l = pte->device->lines;
02015 
02016    sub = pte->device->lines->subs[SUB_REAL];
02017    send_stop_timer(pte);
02018    if (sub->owner) {
02019       sub->alreadygone = 1;
02020       if (l->subs[SUB_THREEWAY]) {
02021          l->subs[SUB_THREEWAY]->alreadygone = 1;
02022          if (attempt_transfer(sub, l->subs[SUB_THREEWAY]) < 0)
02023             ast_verb(0, "attempt_transfer failed.\n");
02024       } else
02025          ast_queue_hangup(sub->owner);
02026    } else {
02027       if (l->subs[SUB_THREEWAY]) {
02028          if (l->subs[SUB_THREEWAY]->owner)
02029             ast_queue_hangup_with_cause(l->subs[SUB_THREEWAY]->owner, AST_CAUSE_NORMAL_CLEARING);
02030          else
02031             ast_log(LOG_WARNING, "threeway sub without owner\n");
02032       } else
02033          ast_verb(0, "USTM(%s@%s-%d) channel already destroyed\n", sub->parent->name,
02034                   sub->parent->parent->name, sub->subtype);
02035    }
02036    change_callerid(pte, 0, pte->device->redial_number);
02037    change_callerid(pte, 1, "");
02038    write_history(pte, 'o', pte->device->missed_call);
02039    pte->device->missed_call = 0;
02040    show_main_page(pte);
02041    return;
02042 }

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, SUB_REAL, unistim_line::subs, 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 4134 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.

04135 {
04136    switch (ind) {
04137    case AST_CONTROL_HANGUP:
04138       return "Other end has hungup";
04139    case AST_CONTROL_RING:
04140       return "Local ring";
04141    case AST_CONTROL_RINGING:
04142       return "Remote end is ringing";
04143    case AST_CONTROL_ANSWER:
04144       return "Remote end has answered";
04145    case AST_CONTROL_BUSY:
04146       return "Remote end is busy";
04147    case AST_CONTROL_TAKEOFFHOOK:
04148       return "Make it go off hook";
04149    case AST_CONTROL_OFFHOOK:
04150       return "Line is off hook";
04151    case AST_CONTROL_CONGESTION:
04152       return "Congestion (circuits busy)";
04153    case AST_CONTROL_FLASH:
04154       return "Flash hook";
04155    case AST_CONTROL_WINK:
04156       return "Wink";
04157    case AST_CONTROL_OPTION:
04158       return "Set a low-level option";
04159    case AST_CONTROL_RADIO_KEY:
04160       return "Key Radio";
04161    case AST_CONTROL_RADIO_UNKEY:
04162       return "Un-Key Radio";
04163    case -1:
04164       return "Stop tone";
04165    }
04166    return "UNKNOWN";
04167 }

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

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, unistimsession::buf, wsabuf::buf, get_tick_count(), get_to_address(), unistimsession::last_buf_available, unistimsession::last_seq_ack, unistimsession::lock, MAX_BUF_NUMBER, unistimsession::nb_retransmit, unistimsession::next, RETRANSMIT_TIMER, unistimsession::seq_phone, unistimsession::seq_server, sessionlock, unistimsession::sin, unistimsession::sout, unistimsession::state, STATE_INIT, unistimsession::tick_next_ping, unistimsession::timeout, and unistimsession::wsabufsend.

Referenced by parsing().

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

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

04634 {
04635    struct unistimsession *cur = NULL;
04636    unsigned int dw_timeout = 0;
04637    unsigned int tick;
04638    int res;
04639    int reloading;
04640 
04641    /* Add an I/O event to our UDP socket */
04642    if (unistimsock > -1)
04643       ast_io_add(io, unistimsock, unistimsock_read, AST_IO_IN, NULL);
04644 
04645    /* This thread monitors our UDP socket and timers */
04646    for (;;) {
04647       /* This loop is executed at least every IDLE_WAITus (1s) or every time a packet is received */
04648       /* Looking for the smallest time-out value */
04649       tick = get_tick_count();
04650       dw_timeout = UINT_MAX;
04651       ast_mutex_lock(&sessionlock);
04652       cur = sessions;
04653       DEBUG_TIMER("checking timeout for session %p with tick = %u\n", cur, tick);
04654       while (cur) {
04655          DEBUG_TIMER("checking timeout for session %p timeout = %u\n", cur,
04656                   cur->timeout);
04657          /* Check if we have miss something */
04658          if (cur->timeout <= tick) {
04659             DEBUG_TIMER("Event for session %p\n", cur);
04660             /* If the queue is empty, send a ping */
04661             if (cur->last_buf_available == 0)
04662                send_ping(cur);
04663             else {
04664                if (send_retransmit(cur)) {
04665                   DEBUG_TIMER("The chained link was modified, restarting...\n");
04666                   cur = sessions;
04667                   dw_timeout = UINT_MAX;
04668                   continue;
04669                }
04670             }
04671          }
04672          if (dw_timeout > cur->timeout - tick)
04673             dw_timeout = cur->timeout - tick;
04674          /* Checking if the phone is logged on for a new MWI */
04675          if (cur->device) {
04676             if ((!ast_strlen_zero(cur->device->lines->mailbox)) &&
04677                ((tick >= cur->device->lines->nextmsgcheck))) {
04678                DEBUG_TIMER("Checking mailbox for MWI\n");
04679                unistim_send_mwi_to_peer(cur, tick);
04680                break;
04681             }
04682          }
04683          cur = cur->next;
04684       }
04685       ast_mutex_unlock(&sessionlock);
04686       DEBUG_TIMER("Waiting for %dus\n", dw_timeout);
04687       res = dw_timeout;
04688       /* We should not wait more than IDLE_WAIT */
04689       if ((res < 0) || (res > IDLE_WAIT))
04690          res = IDLE_WAIT;
04691       /* Wait for UDP messages for a maximum of res us */
04692       res = ast_io_wait(io, res);     /* This function will call unistimsock_read if a packet is received */
04693       /* Check for a reload request */
04694       ast_mutex_lock(&unistim_reload_lock);
04695       reloading = unistim_reloading;
04696       unistim_reloading = 0;
04697       ast_mutex_unlock(&unistim_reload_lock);
04698       if (reloading) {
04699          ast_verb(1, "Reloading unistim.conf...\n");
04700          reload_config();
04701       }
04702       pthread_testcancel();
04703    }
04704    /* Never reached */
04705    return NULL;
04706 }

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

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

Definition at line 4255 of file chan_unistim.c.

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

Referenced by unistim_request(), and unistim_sp().

04256 {
04257    struct unistim_line *l;
04258    struct unistim_device *d;
04259    char line[256];
04260    char *at;
04261    char *device;
04262 
04263    ast_copy_string(line, dest, sizeof(line));
04264    at = strchr(line, '@');
04265    if (!at) {
04266       ast_log(LOG_NOTICE, "Device '%s' has no @ (at) sign!\n", dest);
04267       return NULL;
04268    }
04269    *at = '\0';
04270    at++;
04271    device = at;
04272    ast_mutex_lock(&devicelock);
04273    d = devices;
04274    at = strchr(device, '/');       /* Extra options ? */
04275    if (at)
04276       *at = '\0';
04277    while (d) {
04278       if (!strcasecmp(d->name, device)) {
04279          if (unistimdebug)
04280             ast_verb(0, "Found device: %s\n", d->name);
04281          /* Found the device */
04282          l = d->lines;
04283          while (l) {
04284             /* Search for the right line */
04285             if (!strcasecmp(l->name, line)) {
04286                l->subs[SUB_REAL]->ringvolume = -1;
04287                l->subs[SUB_REAL]->ringstyle = -1;
04288                if (at) {       /* Other options ? */
04289                   at++;   /* Skip slash */
04290                   if (*at == 'r') {       /* distinctive ring */
04291                      at++;
04292                      if ((*at < '0') || (*at > '7')) /* ring style */
04293                         ast_log(LOG_WARNING, "Invalid ring selection (%s)", at);
04294                      else {
04295                         char ring_volume = -1;
04296                         char ring_style = *at - '0';
04297                         at++;
04298                         if ((*at >= '0') && (*at <= '3'))       /* ring volume */
04299                            ring_volume = *at - '0';
04300                         if (unistimdebug)
04301                            ast_verb(0, "Distinctive ring : style #%d volume %d\n",
04302                                ring_style, ring_volume);
04303                         l->subs[SUB_REAL]->ringvolume = ring_volume;
04304                         l->subs[SUB_REAL]->ringstyle = ring_style;
04305                      }
04306                   }
04307                }
04308                ast_mutex_unlock(&devicelock);
04309                return l->subs[SUB_REAL];
04310             }
04311             l = l->next;
04312          }
04313       }
04314       d = d->next;
04315    }
04316    /* Device not found */
04317    ast_mutex_unlock(&devicelock);
04318 
04319    return NULL;
04320 }

static void finish_bookmark ( void   )  [static]

Definition at line 5092 of file chan_unistim.c.

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

Referenced by reload_config().

05093 {
05094    struct unistim_device *d = devices;
05095    int i;
05096    while (d) {
05097       for (i = 0; i < 6; i++) {
05098          if (d->softkeyicon[i] == 1) {   /* Something for us */
05099             struct unistim_device *d2 = devices;
05100             while (d2) {
05101                if (!strcmp(d->softkeydevice[i], d2->name)) {
05102                   d->sp[i] = d2;
05103                   d->softkeyicon[i] = 0;
05104                   break;
05105                }
05106                d2 = d2->next;
05107             }
05108             if (d->sp[i] == NULL)
05109                ast_log(LOG_NOTICE, "Bookmark entry with device %s not found\n",
05110                      d->softkeydevice[i]);
05111          }
05112       }
05113       d = d->next;
05114    }
05115 }

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 2304 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, TEXT_NORMAL, and unistim_device::volume.

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

02305 {
02306    pte->state = STATE_DIALPAGE;
02307    if (pte->device->call_forward[0] == -1) {
02308       send_text(TEXT_LINE0, TEXT_NORMAL, pte, "");
02309       send_text(TEXT_LINE1, TEXT_NORMAL, pte, "Enter forward");
02310       send_text_status(pte, "ForwardCancel BackSpcErase");
02311       if (pte->device->call_forward[1] != 0) {
02312          char tmp[TEXT_LENGTH_MAX + 1];
02313 
02314          ast_copy_string(pte->device->phone_number, pte->device->call_forward + 1,
02315                      sizeof(pte->device->phone_number));
02316          pte->device->size_phone_number = strlen(pte->device->phone_number);
02317          if (pte->device->size_phone_number > 15)
02318             pte->device->size_phone_number = 15;
02319          strcpy(tmp, "Number : ...............");
02320          memcpy(tmp + 9, pte->device->phone_number, pte->device->size_phone_number);
02321 
02322          if (pte->device->height == 1) {
02323             send_text(TEXT_LINE0, TEXT_NORMAL, pte, tmp);
02324             send_blink_cursor(pte);
02325             send_cursor_pos(pte,
02326                     (unsigned char) (TEXT_LINE0 + 0x09 +
02327                                  pte->device->size_phone_number));
02328          } else {
02329             send_text(TEXT_LINE2, TEXT_NORMAL, pte, tmp);
02330             send_blink_cursor(pte);
02331             send_cursor_pos(pte,
02332                     (unsigned char) (TEXT_LINE2 + 0x09 +
02333                                  pte->device->size_phone_number));
02334          }
02335 
02336          send_led_update(pte, 0);
02337          return;
02338       }
02339    } else {
02340       if ((pte->device->output == OUTPUT_HANDSET) &&
02341          (pte->device->receiver_state == STATE_ONHOOK))
02342          send_select_output(pte, OUTPUT_SPEAKER, pte->device->volume, MUTE_OFF);
02343       else
02344          send_select_output(pte, pte->device->output, pte->device->volume, MUTE_OFF);
02345       SendDialTone(pte);
02346 
02347       if (pte->device->height > 1) {
02348          send_text(TEXT_LINE0, TEXT_NORMAL, pte, "Enter the number to dial");
02349          send_text(TEXT_LINE1, TEXT_NORMAL, pte, "and press Call");
02350       }
02351       send_text_status(pte, "Call   Redial BackSpcErase");
02352    }
02353 
02354    if (pte->device->height == 1) {
02355       send_text(TEXT_LINE0, TEXT_NORMAL, pte, "Number : ...............");
02356       send_blink_cursor(pte);
02357       send_cursor_pos(pte, TEXT_LINE0 + 0x09);
02358    } else {
02359       send_text(TEXT_LINE2, TEXT_NORMAL, pte, "Number : ...............");
02360       send_blink_cursor(pte);
02361       send_cursor_pos(pte, TEXT_LINE2 + 0x09);
02362    }
02363    pte->device->size_phone_number = 0;
02364    pte->device->phone_number[0] = 0;
02365    change_favorite_icon(pte, FAV_ICON_PHONE_BLACK);
02366    Sendicon(TEXT_LINE0, FAV_ICON_NONE, pte);
02367    pte->device->missed_call = 0;
02368    send_led_update(pte, 0);
02369    return;
02370 }

static void HandleCallIncoming ( struct unistimsession s  )  [static]

Definition at line 2519 of file chan_unistim.c.

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

Referenced by key_ringing(), and process_request().

02520 {
02521    struct unistim_subchannel *sub;
02522    s->state = STATE_CALL;
02523    s->device->missed_call = 0;
02524    send_no_ring(s);
02525    sub = s->device->lines->subs[SUB_REAL];
02526    if (!sub) {
02527       ast_log(LOG_NOTICE, "No available lines on: %s\n", s->device->name);
02528       return;
02529    } else if (unistimdebug)
02530       ast_verb(0, "Handle Call Incoming for %s@%s\n", sub->parent->name,
02531                s->device->name);
02532    start_rtp(sub);
02533    if (!sub->rtp)
02534       ast_log(LOG_WARNING, "Unable to create channel for %s@%s\n", sub->parent->name,
02535             s->device->name);
02536    ast_queue_control(sub->owner, AST_CONTROL_ANSWER);
02537    send_text(TEXT_LINE2, TEXT_NORMAL, s, "is on-line");
02538    send_text_status(s, "Hangup Transf");
02539    send_start_timer(s);
02540 
02541    if ((s->device->output == OUTPUT_HANDSET) &&
02542       (s->device->receiver_state == STATE_ONHOOK))
02543       send_select_output(s, OUTPUT_SPEAKER, s->device->volume, MUTE_OFF);
02544    else
02545       send_select_output(s, s->device->output, s->device->volume, MUTE_OFF);
02546    s->device->start_call_timestamp = time(0);
02547    write_history(s, 'i', 0);
02548    return;
02549 }

static void HandleCallOutgoing ( struct unistimsession s  )  [static]

Definition at line 2419 of file chan_unistim.c.

References alloc_sub(), AST_CAUSE_SWITCH_CONGESTION, ast_channel_name(), 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, 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, SUB_REAL, SUB_THREEWAY, unistim_line::subs, unistim_subchannel::subtype, swap_subs(), TEXT_LINE0, TEXT_LINE1, TEXT_LINE2, TEXT_NORMAL, unistim_new(), unistim_ss(), and unistim_device::volume.

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

02420 {
02421    struct ast_channel *c;
02422    struct unistim_subchannel *sub;
02423    pthread_t t;
02424    s->state = STATE_CALL;
02425    sub = s->device->lines->subs[SUB_REAL];
02426    if (!sub) {
02427       ast_log(LOG_NOTICE, "No available lines on: %s\n", s->device->name);
02428       return;
02429    }
02430    if (!sub->owner) {            /* A call is already in progress ? */
02431       c = unistim_new(sub, AST_STATE_DOWN, NULL);   /* No, starting a new one */
02432       if (c) {
02433          /* Need to start RTP before calling ast_pbx_run */
02434          if (!sub->rtp)
02435             start_rtp(sub);
02436          send_select_output(s, s->device->output, s->device->volume, MUTE_OFF);
02437 
02438          if (s->device->height == 1) {
02439             send_text(TEXT_LINE0, TEXT_NORMAL, s, s->device->phone_number);
02440          } else {
02441             send_text(TEXT_LINE0, TEXT_NORMAL, s, "Calling :");
02442             send_text(TEXT_LINE1, TEXT_NORMAL, s, s->device->phone_number);
02443             send_text(TEXT_LINE2, TEXT_NORMAL, s, "Dialing...");
02444          }
02445          send_text_status(s, "Hangup");
02446 
02447          /* start switch */
02448          if (ast_pthread_create(&t, NULL, unistim_ss, c)) {
02449             display_last_error("Unable to create switch thread");
02450             ast_queue_hangup_with_cause(c, AST_CAUSE_SWITCH_CONGESTION);
02451          }
02452       } else
02453          ast_log(LOG_WARNING, "Unable to create channel for %s@%s\n",
02454                sub->parent->name, s->device->name);
02455    } else {             /* We already have a call, so we switch in a threeway call */
02456 
02457       if (s->device->moh) {
02458          struct unistim_subchannel *subchannel;
02459          struct unistim_line *p = s->device->lines;
02460          subchannel = p->subs[SUB_REAL];
02461 
02462          if (!subchannel->owner) {
02463             ast_log(LOG_WARNING, "Unable to find subchannel for music on hold\n");
02464             return;
02465          }
02466          if (p->subs[SUB_THREEWAY]) {
02467             ast_log(LOG_WARNING,
02468                   "Can't transfer while an another transfer is taking place\n");
02469             return;
02470          }
02471          if (!alloc_sub(p, SUB_THREEWAY)) {
02472             ast_log(LOG_WARNING, "Unable to allocate three-way subchannel\n");
02473             return;
02474          }
02475          /* Stop the silence generator */
02476          if (s->device->silence_generator) {
02477             if (unistimdebug)
02478                ast_verb(0, "Stopping silence generator\n");
02479             ast_channel_stop_silence_generator(subchannel->owner,
02480                                        s->device->silence_generator);
02481             s->device->silence_generator = NULL;
02482          }
02483          send_tone(s, 0, 0);
02484          /* Make new channel */
02485          c = unistim_new(p->subs[SUB_THREEWAY], AST_STATE_DOWN, NULL);
02486          if (!c) {
02487             ast_log(LOG_WARNING, "Cannot allocate new structure on channel %p\n", p);
02488             return;
02489          }
02490          /* Swap things around between the three-way and real call */
02491          swap_subs(p, SUB_THREEWAY, SUB_REAL);
02492          send_select_output(s, s->device->output, s->device->volume, MUTE_OFF);
02493 
02494          if (s->device->height == 1) {
02495             send_text(TEXT_LINE0, TEXT_NORMAL, s, s->device->phone_number);
02496          } else {
02497             send_text(TEXT_LINE0, TEXT_NORMAL, s, "Calling (pre-transfer)");
02498             send_text(TEXT_LINE1, TEXT_NORMAL, s, s->device->phone_number);
02499             send_text(TEXT_LINE2, TEXT_NORMAL, s, "Dialing...");
02500          }
02501          send_text_status(s, "TransfrCancel");
02502 
02503          if (ast_pthread_create(&t, NULL, unistim_ss, p->subs[SUB_THREEWAY]->owner)) {
02504             ast_log(LOG_WARNING, "Unable to start simple switch on channel %p\n", p);
02505             ast_hangup(c);
02506             return;
02507          }
02508          if (unistimdebug)
02509             ast_verb(0, "Started three way call on channel %p (%s) subchan %d\n",
02510                 p->subs[SUB_THREEWAY]->owner, ast_channel_name(p->subs[SUB_THREEWAY]->owner),
02511                 p->subs[SUB_THREEWAY]->subtype);
02512       } else
02513          ast_debug(1, "Current sub [%s] already has owner\n", ast_channel_name(sub->owner));
02514    }
02515    return;
02516 }

static void HandleSelectCodec ( struct unistimsession pte  )  [static]

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

02867 {
02868    char buf[30], buf2[5];
02869 
02870    pte->state = STATE_SELECTCODEC;
02871    strcpy(buf, "Using codec ");
02872    sprintf(buf2, "%d", pte->device->codec_number);
02873    strcat(buf, buf2);
02874    strcat(buf, " (G711u=0,");
02875 
02876    send_text(TEXT_LINE0, TEXT_NORMAL, pte, buf);
02877    send_text(TEXT_LINE1, TEXT_NORMAL, pte, "G723=4,G711a=8,G729A=18)");
02878    send_text(TEXT_LINE2, TEXT_INVERSE, pte, SELECTCODEC_MSG);
02879    send_blink_cursor(pte);
02880    send_cursor_pos(pte, TEXT_LINE2 + SELECTCODEC_START_ENTRY_POS);
02881    pte->size_buff_entry = 0;
02882    send_text_status(pte, "Select BackSpcErase  Cancel");
02883    return;
02884 }

static void IgnoreCall ( struct unistimsession pte  )  [static]

Definition at line 2044 of file chan_unistim.c.

References send_no_ring().

Referenced by key_ringing().

02045 {
02046    send_no_ring(pte);
02047    return;
02048 }

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

Definition at line 4169 of file chan_unistim.c.

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

Referenced by unistim_indicate().

04171 {
04172    struct ast_tone_zone_sound *ts = NULL;
04173 
04174    if ((ts = ast_get_indication_tone(tz, indication))) {
04175       ast_playtones_start(ast, 0, ts->data, 1);
04176       ts = ast_tone_zone_sound_unref(ts);
04177    } else {
04178       ast_log(LOG_WARNING, "Unable to get indication tone for %s\n", indication);
04179    }
04180 }

static void init_phone_step2 ( struct unistimsession pte  )  [static]

Definition at line 3382 of file chan_unistim.c.

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

Referenced by process_request().

03383 {
03384    BUFFSEND;
03385    if (unistimdebug)
03386       ast_verb(0, "Sending S4\n");
03387    memcpy(buffsend + SIZE_HEADER, packet_send_s4, sizeof(packet_send_s4));
03388    send_client(SIZE_HEADER + sizeof(packet_send_s4), buffsend, pte);
03389    send_date_time2(pte);
03390    send_date_time3(pte);
03391    if (unistimdebug)
03392       ast_verb(0, "Sending S7\n");
03393    memcpy(buffsend + SIZE_HEADER, packet_send_S7, sizeof(packet_send_S7));
03394    send_client(SIZE_HEADER + sizeof(packet_send_S7), buffsend, pte);
03395    if (unistimdebug)
03396       ast_verb(0, "Sending Contrast\n");
03397    memcpy(buffsend + SIZE_HEADER, packet_send_Contrast, sizeof(packet_send_Contrast));
03398    if (pte->device != NULL)
03399       buffsend[9] = pte->device->contrast;
03400    send_client(SIZE_HEADER + sizeof(packet_send_Contrast), buffsend, pte);
03401 
03402    if (unistimdebug)
03403       ast_verb(0, "Sending S9\n");
03404    memcpy(buffsend + SIZE_HEADER, packet_send_s9, sizeof(packet_send_s9));
03405    send_client(SIZE_HEADER + sizeof(packet_send_s9), buffsend, pte);
03406    send_no_ring(pte);
03407 
03408    if (unistimdebug)
03409       ast_verb(0, "Sending S7\n");
03410    memcpy(buffsend + SIZE_HEADER, packet_send_S7, sizeof(packet_send_S7));
03411    send_client(SIZE_HEADER + sizeof(packet_send_S7), buffsend, pte);
03412    send_led_update(pte, 0);
03413    send_ping(pte);
03414    if (pte->state < STATE_MAINPAGE) {
03415       if (autoprovisioning == AUTOPROVISIONING_TN) {
03416          ShowExtensionPage(pte);
03417          return;
03418       } else {
03419          int i;
03420          char tmp[30];
03421 
03422          for (i = 1; i < 6; i++)
03423             send_favorite(i, 0, pte, "");
03424          send_text(TEXT_LINE0, TEXT_NORMAL, pte, "Sorry, this phone is not");
03425          send_text(TEXT_LINE1, TEXT_NORMAL, pte, "registered in unistim.cfg");
03426          strcpy(tmp, "MAC = ");
03427          strcat(tmp, pte->macaddr);
03428          send_text(TEXT_LINE2, TEXT_NORMAL, pte, tmp);
03429          send_text_status(pte, "");
03430          send_texttitle(pte, "UNISTIM for*");
03431          return;
03432       }
03433    }
03434    show_main_page(pte);
03435    refresh_all_favorite(pte);
03436    if (unistimdebug)
03437       ast_verb(0, "Sending arrow\n");
03438    memcpy(buffsend + SIZE_HEADER, packet_send_arrow, sizeof(packet_send_arrow));
03439    send_client(SIZE_HEADER + sizeof(packet_send_arrow), buffsend, pte);
03440    return;
03441 }

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

Definition at line 2623 of file chan_unistim.c.

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

Referenced by process_request().

02624 {
02625    if ((keycode >= KEY_0) && (keycode <= KEY_SHARP)) {
02626       if (keycode == KEY_SHARP)
02627          keycode = '#';
02628       else if (keycode == KEY_STAR)
02629          keycode = '*';
02630       else
02631          keycode -= 0x10;
02632       unistim_do_senddigit(pte, keycode);
02633       return;
02634    }
02635    switch (keycode) {
02636    case KEY_HANGUP:
02637    case KEY_FUNC1:
02638       close_call(pte);
02639       break;
02640    case KEY_FUNC2:
02641       TransferCallStep1(pte);
02642       break;
02643    case KEY_HEADPHN:
02644       if (pte->device->output == OUTPUT_HEADPHONE)
02645          send_select_output(pte, OUTPUT_HANDSET, pte->device->volume, MUTE_OFF);
02646       else
02647          send_select_output(pte, OUTPUT_HEADPHONE, pte->device->volume, MUTE_OFF);
02648       break;
02649    case KEY_LOUDSPK:
02650       if (pte->device->output != OUTPUT_SPEAKER)
02651          send_select_output(pte, OUTPUT_SPEAKER, pte->device->volume, MUTE_OFF);
02652       else
02653          send_select_output(pte, pte->device->previous_output, pte->device->volume,
02654                       MUTE_OFF);
02655       break;
02656    case KEY_MUTE:
02657       if (!pte->device->moh) {
02658          if (pte->device->mute == MUTE_ON)
02659             send_select_output(pte, pte->device->output, pte->device->volume, MUTE_OFF);
02660          else
02661             send_select_output(pte, pte->device->output, pte->device->volume, MUTE_ON);
02662          break;
02663       }
02664    case KEY_ONHOLD:
02665       {
02666          struct unistim_subchannel *sub;
02667          struct ast_channel *bridgepeer = NULL;
02668          sub = pte->device->lines->subs[SUB_REAL];
02669          if (!sub->owner) {
02670             ast_log(LOG_WARNING, "Unable to find subchannel for music on hold\n");
02671             return;
02672          }
02673          if ((bridgepeer = ast_bridged_channel(sub->owner))) {
02674             if (pte->device->moh) {
02675                ast_moh_stop(bridgepeer);
02676                pte->device->moh = 0;
02677                send_select_output(pte, pte->device->output, pte->device->volume,
02678                             MUTE_OFF);
02679             } else {
02680                ast_moh_start(bridgepeer, pte->device->lines->musicclass, NULL);
02681                pte->device->moh = 1;
02682                send_select_output(pte, pte->device->output, pte->device->volume,
02683                             MUTE_ON);
02684             }
02685          } else
02686             ast_log(LOG_WARNING,
02687                   "Unable to find peer subchannel for music on hold\n");
02688          break;
02689       }
02690    }
02691    return;
02692 }

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

Definition at line 2731 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_subchannel::owner, unistim_device::phone_number, unistim_device::previous_output, unistim_device::receiver_state, unistim_device::redial_number, send_blink_cursor(), send_cursor_pos(), send_select_output(), send_text(), send_text_status(), send_tone(), show_main_page(), unistim_device::silence_generator, unistim_device::size_phone_number, unistimsession::state, STATE_CALL, STATE_OFFHOOK, SUB_REAL, unistim_line::subs, TEXT_LINE0, TEXT_LINE1, TEXT_LINE2, TEXT_NORMAL, and unistim_device::volume.

Referenced by key_main_page(), and process_request().

02732 {
02733    if (keycode == KEY_FUNC3) {
02734       if (pte->device->size_phone_number <= 1)
02735          keycode = KEY_FUNC4;
02736       else {
02737          pte->device->size_phone_number -= 2;
02738          keycode = pte->device->phone_number[pte->device->size_phone_number] + 0x10;
02739       }
02740    }
02741    if ((keycode >= KEY_0) && (keycode <= KEY_SHARP)) {
02742       char tmpbuf[] = "Number : ...............";
02743       int i = 0;
02744 
02745       if (pte->device->size_phone_number >= 15)
02746          return;
02747       if (pte->device->size_phone_number == 0)
02748          send_tone(pte, 0, 0);
02749       while (i < pte->device->size_phone_number) {
02750          tmpbuf[i + 9] = pte->device->phone_number[i];
02751          i++;
02752       }
02753       if (keycode == KEY_SHARP)
02754          keycode = '#';
02755       else if (keycode == KEY_STAR)
02756          keycode = '*';
02757       else
02758          keycode -= 0x10;
02759       tmpbuf[i + 9] = keycode;
02760       pte->device->phone_number[i] = keycode;
02761       pte->device->size_phone_number++;
02762       pte->device->phone_number[i + 1] = 0;
02763       if (pte->device->height == 1) {
02764          send_text(TEXT_LINE0, TEXT_NORMAL, pte, tmpbuf);
02765       } else {
02766          send_text(TEXT_LINE2, TEXT_NORMAL, pte, tmpbuf);
02767       }
02768       send_blink_cursor(pte);
02769       send_cursor_pos(pte, (unsigned char) (TEXT_LINE2 + 0x0a + i));
02770       return;
02771    }
02772    if (keycode == KEY_FUNC4) {
02773 
02774       pte->device->size_phone_number = 0;
02775       if (pte->device->height == 1) {
02776          send_text(TEXT_LINE0, TEXT_NORMAL, pte, "Number : ...............");
02777          send_blink_cursor(pte);
02778          send_cursor_pos(pte, TEXT_LINE0 + 0x09);
02779       } else {
02780          send_text(TEXT_LINE2, TEXT_NORMAL, pte, "Number : ...............");
02781          send_blink_cursor(pte);
02782          send_cursor_pos(pte, TEXT_LINE2 + 0x09);
02783       }
02784       return;
02785    }
02786 
02787    if (pte->device->call_forward[0] == -1) {
02788       if (keycode == KEY_FUNC1) {
02789          ast_copy_string(pte->device->call_forward, pte->device->phone_number,
02790                      sizeof(pte->device->call_forward));
02791          show_main_page(pte);
02792       } else if ((keycode == KEY_FUNC2) || (keycode == KEY_HANGUP)) {
02793          pte->device->call_forward[0] = '\0';
02794          show_main_page(pte);
02795       }
02796       return;
02797    }
02798    switch (keycode) {
02799    case KEY_FUNC2:
02800       if (ast_strlen_zero(pte->device->redial_number))
02801          break;
02802       ast_copy_string(pte->device->phone_number, pte->device->redial_number,
02803                   sizeof(pte->device->phone_number));
02804    case KEY_FUNC1:
02805       HandleCallOutgoing(pte);
02806       break;
02807    case KEY_HANGUP:
02808       if (pte->device->lines->subs[SUB_REAL]->owner) {
02809          /* Stop the silence generator */
02810          if (pte->device->silence_generator) {
02811             if (unistimdebug)
02812                ast_verb(0, "Stopping silence generator\n");
02813             ast_channel_stop_silence_generator(pte->device->lines->subs[SUB_REAL]->
02814                                        owner, pte->device->silence_generator);
02815             pte->device->silence_generator = NULL;
02816          }
02817          send_tone(pte, 0, 0);
02818          ast_moh_stop(ast_bridged_channel(pte->device->lines->subs[SUB_REAL]->owner));
02819          pte->device->moh = 0;
02820          pte->state = STATE_CALL;
02821 
02822          if (pte->device->height == 1) {
02823             send_text(TEXT_LINE0, TEXT_NORMAL, pte, "Dial Cancel,back to priv. call.");
02824          } else {
02825             send_text(TEXT_LINE0, TEXT_NORMAL, pte, "Dialing canceled,");
02826             send_text(TEXT_LINE1, TEXT_NORMAL, pte, "switching back to");
02827             send_text(TEXT_LINE2, TEXT_NORMAL, pte, "previous call.");
02828          }
02829          send_text_status(pte, "Hangup Transf");
02830       } else
02831          show_main_page(pte);
02832       break;
02833    case KEY_FAV1:
02834    case KEY_FAV2:
02835    case KEY_FAV3:
02836    case KEY_FAV4:
02837    case KEY_FAV5:
02838       Keyfavorite(pte, keycode);
02839       break;
02840    case KEY_LOUDSPK:
02841       if (pte->device->output == OUTPUT_SPEAKER) {
02842          if (pte->device->receiver_state == STATE_OFFHOOK)
02843             send_select_output(pte, pte->device->previous_output, pte->device->volume,
02844                          MUTE_OFF);
02845          else
02846             show_main_page(pte);
02847       } else
02848          send_select_output(pte, OUTPUT_SPEAKER, pte->device->volume, MUTE_OFF);
02849       break;
02850    case KEY_HEADPHN:
02851       if (pte->device->output == OUTPUT_HEADPHONE) {
02852          if (pte->device->receiver_state == STATE_OFFHOOK)
02853             send_select_output(pte, OUTPUT_HANDSET, pte->device->volume, MUTE_OFF);
02854          else
02855             show_main_page(pte);
02856       } else
02857          send_select_output(pte, OUTPUT_HEADPHONE, pte->device->volume, MUTE_OFF);
02858       break;
02859    }
02860    return;
02861 }

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

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

03315 {
03316    FILE *f;
03317    char count;
03318    long offset;
03319 
03320    switch (keycode) {
03321    case KEY_UP:
03322    case KEY_LEFT:
03323    case KEY_FUNC1:
03324       if (pte->buff_entry[2] <= 1)
03325          return;
03326       pte->buff_entry[2]--;
03327       count = OpenHistory(pte, pte->buff_entry[0], &f);
03328       if (!count)
03329          return;
03330       offset = ((pte->buff_entry[2] - 1) * TEXT_LENGTH_MAX * 3);
03331       if (fseek(f, offset, SEEK_CUR)) {
03332          display_last_error("Unable to seek history entry.");
03333          fclose(f);
03334          return;
03335       }
03336       show_entry_history(pte, &f);
03337       break;
03338    case KEY_DOWN:
03339    case KEY_RIGHT:
03340    case KEY_FUNC2:
03341       if (pte->buff_entry[2] >= pte->buff_entry[1])
03342          return;
03343       pte->buff_entry[2]++;
03344       count = OpenHistory(pte, pte->buff_entry[0], &f);
03345       if (!count)
03346          return;
03347       offset = ((pte->buff_entry[2] - 1) * TEXT_LENGTH_MAX * 3);
03348       if (fseek(f, offset, SEEK_CUR)) {
03349          display_last_error("Unable to seek history entry.");
03350          fclose(f);
03351          return;
03352       }
03353       show_entry_history(pte, &f);
03354       break;
03355    case KEY_FUNC3:
03356       if (!ReformatNumber(pte->device->lst_cid))
03357          break;
03358       ast_copy_string(pte->device->redial_number, pte->device->lst_cid,
03359                   sizeof(pte->device->redial_number));
03360       key_main_page(pte, KEY_FUNC2);
03361       break;
03362    case KEY_FUNC4:
03363    case KEY_HANGUP:
03364       show_main_page(pte);
03365       break;
03366    case KEY_SNDHIST:
03367       if (pte->buff_entry[0] == 'i')
03368          show_history(pte, 'o');
03369       else
03370          show_main_page(pte);
03371       break;
03372    case KEY_RCVHIST:
03373       if (pte->buff_entry[0] == 'i')
03374          show_main_page(pte);
03375       else
03376          show_history(pte, 'i');
03377       break;
03378    }
03379    return;
03380 }

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

Definition at line 3220 of file chan_unistim.c.

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

Referenced by key_history(), and process_request().

03221 {
03222    if (pte->device->missed_call) {
03223       Sendicon(TEXT_LINE0, FAV_ICON_NONE, pte);
03224       pte->device->missed_call = 0;
03225    }
03226    if ((keycode >= KEY_0) && (keycode <= KEY_SHARP)) {
03227       handle_dial_page(pte);
03228       key_dial_page(pte, keycode);
03229       return;
03230    }
03231    switch (keycode) {
03232    case KEY_FUNC1:
03233       handle_dial_page(pte);
03234       break;
03235    case KEY_FUNC2:
03236       if (ast_strlen_zero(pte->device->redial_number))
03237          break;
03238       if ((pte->device->output == OUTPUT_HANDSET) &&
03239          (pte->device->receiver_state == STATE_ONHOOK))
03240          send_select_output(pte, OUTPUT_SPEAKER, pte->device->volume, MUTE_OFF);
03241       else
03242          send_select_output(pte, pte->device->output, pte->device->volume, MUTE_OFF);
03243 
03244       ast_copy_string(pte->device->phone_number, pte->device->redial_number,
03245                   sizeof(pte->device->phone_number));
03246       HandleCallOutgoing(pte);
03247       break;
03248    case KEY_FUNC3:
03249       if (!ast_strlen_zero(pte->device->call_forward)) {
03250          /* Cancel call forwarding */
03251          memmove(pte->device->call_forward + 1, pte->device->call_forward,
03252                sizeof(pte->device->call_forward));
03253          pte->device->call_forward[0] = '\0';
03254          Sendicon(TEXT_LINE0, FAV_ICON_NONE, pte);
03255          pte->device->output = OUTPUT_HANDSET;   /* Seems to be reseted somewhere */
03256          show_main_page(pte);
03257          break;
03258       }
03259       pte->device->call_forward[0] = -1;
03260       handle_dial_page(pte);
03261       break;
03262    case KEY_FUNC4:
03263       if (pte->device->extension == EXTENSION_ASK) {
03264          UnregisterExtension(pte);
03265          pte->device->extension_number[0] = '\0';
03266          ShowExtensionPage(pte);
03267       } else if (pte->device->extension == EXTENSION_TN) {
03268          ast_mutex_lock(&devicelock);
03269          strcpy(pte->device->id, pte->device->extension_number);
03270          pte->buff_entry[0] = '\0';
03271          pte->size_buff_entry = 0;
03272          pte->device->session = NULL;
03273          pte->device = NULL;
03274          ast_mutex_unlock(&devicelock);
03275          ShowExtensionPage(pte);
03276       }
03277       break;
03278    case KEY_FAV0:
03279       handle_dial_page(pte);
03280       break;
03281    case KEY_FAV1:
03282    case KEY_FAV2:
03283    case KEY_FAV3:
03284    case KEY_FAV4:
03285    case KEY_FAV5:
03286       if ((pte->device->output == OUTPUT_HANDSET) &&
03287          (pte->device->receiver_state == STATE_ONHOOK))
03288          send_select_output(pte, OUTPUT_SPEAKER, pte->device->volume, MUTE_OFF);
03289       else
03290          send_select_output(pte, pte->device->output, pte->device->volume, MUTE_OFF);
03291       Keyfavorite(pte, keycode);
03292       break;
03293    case KEY_CONF:
03294       HandleSelectCodec(pte);
03295       break;
03296    case KEY_LOUDSPK:
03297       send_select_output(pte, OUTPUT_SPEAKER, pte->device->volume, MUTE_OFF);
03298       handle_dial_page(pte);
03299       break;
03300    case KEY_HEADPHN:
03301       send_select_output(pte, OUTPUT_HEADPHONE, pte->device->volume, MUTE_OFF);
03302       handle_dial_page(pte);
03303       break;
03304    case KEY_SNDHIST:
03305       show_history(pte, 'o');
03306       break;
03307    case KEY_RCVHIST:
03308       show_history(pte, 'i');
03309       break;
03310    }
03311    return;
03312 }

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

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

02695 {
02696    if (keycode == KEY_FAV0 + pte->device->softkeylinepos) {
02697       HandleCallIncoming(pte);
02698       return;
02699    }
02700    switch (keycode) {
02701    case KEY_HANGUP:
02702    case KEY_FUNC4:
02703       IgnoreCall(pte);
02704       break;
02705    case KEY_FUNC1:
02706       HandleCallIncoming(pte);
02707       break;
02708    }
02709    return;
02710 }

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

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

02887 {
02888    if (keycode == KEY_FUNC2) {
02889       if (pte->size_buff_entry <= 1)
02890          keycode = KEY_FUNC3;
02891       else {
02892          pte->size_buff_entry -= 2;
02893          keycode = pte->buff_entry[pte->size_buff_entry] + 0x10;
02894       }
02895    }
02896    if ((keycode >= KEY_0) && (keycode <= KEY_9)) {
02897       char tmpbuf[] = SELECTCODEC_MSG;
02898       int i = 0;
02899 
02900       if (pte->size_buff_entry >= SELECTCODEC_MAX_LENGTH)
02901          return;
02902 
02903       while (i < pte->size_buff_entry) {
02904          tmpbuf[i + SELECTCODEC_START_ENTRY_POS] = pte->buff_entry[i];
02905          i++;
02906       }
02907       tmpbuf[i + SELECTCODEC_START_ENTRY_POS] = keycode - 0x10;
02908       pte->buff_entry[i] = keycode - 0x10;
02909       pte->size_buff_entry++;
02910       send_text(TEXT_LINE2, TEXT_INVERSE, pte, tmpbuf);
02911       send_blink_cursor(pte);
02912       send_cursor_pos(pte,
02913                  (unsigned char) (TEXT_LINE2 + SELECTCODEC_START_ENTRY_POS + 1 + i));
02914       return;
02915    }
02916 
02917    switch (keycode) {
02918    case KEY_FUNC1:
02919       if (pte->size_buff_entry == 1)
02920          pte->device->codec_number = pte->buff_entry[0] - 48;
02921       else if (pte->size_buff_entry == 2)
02922          pte->device->codec_number =
02923             ((pte->buff_entry[0] - 48) * 10) + (pte->buff_entry[1] - 48);
02924       show_main_page(pte);
02925       break;
02926    case KEY_FUNC3:
02927       pte->size_buff_entry = 0;
02928       send_text(TEXT_LINE2, TEXT_INVERSE, pte, SELECTCODEC_MSG);
02929       send_blink_cursor(pte);
02930       send_cursor_pos(pte, TEXT_LINE2 + SELECTCODEC_START_ENTRY_POS);
02931       break;
02932    case KEY_HANGUP:
02933    case KEY_FUNC4:
02934       show_main_page(pte);
02935       break;
02936    }
02937    return;
02938 }

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

Definition at line 2957 of file chan_unistim.c.

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

Referenced by process_request().

02958 {
02959    if (keycode == KEY_FUNC2) {
02960       if (pte->size_buff_entry <= 1)
02961          keycode = KEY_FUNC3;
02962       else {
02963          pte->size_buff_entry -= 2;
02964          keycode = pte->buff_entry[pte->size_buff_entry] + 0x10;
02965       }
02966    }
02967    if ((keycode >= KEY_0) && (keycode <= KEY_9)) {
02968       char tmpbuf[] = SELECTEXTENSION_MSG;
02969       int i = 0;
02970 
02971       if (pte->size_buff_entry >= SELECTEXTENSION_MAX_LENGTH)
02972          return;
02973 
02974       while (i < pte->size_buff_entry) {
02975          tmpbuf[i + SELECTEXTENSION_START_ENTRY_POS] = pte->buff_entry[i];
02976          i++;
02977       }
02978       tmpbuf[i + SELECTEXTENSION_START_ENTRY_POS] = keycode - 0x10;
02979       pte->buff_entry[i] = keycode - 0x10;
02980       pte->size_buff_entry++;
02981       send_text(TEXT_LINE2, TEXT_NORMAL, pte, tmpbuf);
02982       send_blink_cursor(pte);
02983       send_cursor_pos(pte,
02984                  (unsigned char) (TEXT_LINE2 + SELECTEXTENSION_START_ENTRY_POS + 1 +
02985                               i));
02986       return;
02987    }
02988 
02989    switch (keycode) {
02990    case KEY_FUNC1:
02991       if (pte->size_buff_entry < 1)
02992          return;
02993       if (autoprovisioning == AUTOPROVISIONING_TN) {
02994          struct unistim_device *d;
02995 
02996          /* First step : looking for this TN in our device list */
02997          ast_mutex_lock(&devicelock);
02998          d = devices;
02999          pte->buff_entry[pte->size_buff_entry] = '\0';
03000          while (d) {
03001             if (d->id[0] == 'T') {  /* It's a TN device ? */
03002                /* It's the TN we're looking for ? */
03003                if (!strcmp((d->id) + 1, pte->buff_entry)) {
03004                   pte->device = d;
03005                   d->session = pte;
03006                   d->codec_number = DEFAULT_CODEC;
03007                   d->pos_fav = 0;
03008                   d->missed_call = 0;
03009                   d->receiver_state = STATE_ONHOOK;
03010                   strcpy(d->id, pte->macaddr);
03011                   pte->device->extension_number[0] = 'T';
03012                   pte->device->extension = EXTENSION_TN;
03013                   ast_copy_string((pte->device->extension_number) + 1,
03014                               pte->buff_entry, pte->size_buff_entry + 1);
03015                   ast_mutex_unlock(&devicelock);
03016                   show_main_page(pte);
03017                   refresh_all_favorite(pte);
03018                   return;
03019                }
03020             }
03021             d = d->next;
03022          }
03023          ast_mutex_unlock(&devicelock);
03024          send_text(TEXT_LINE0, TEXT_NORMAL, pte, "Invalid Terminal Number.");
03025          send_text(TEXT_LINE1, TEXT_NORMAL, pte, "Please try again :");
03026          send_cursor_pos(pte,
03027                     (unsigned char) (TEXT_LINE2 + SELECTEXTENSION_START_ENTRY_POS +
03028                                  pte->size_buff_entry));
03029          send_blink_cursor(pte);
03030       } else {
03031          ast_copy_string(pte->device->extension_number, pte->buff_entry,
03032                      pte->size_buff_entry + 1);
03033          if (RegisterExtension(pte)) {
03034             send_text(TEXT_LINE0, TEXT_NORMAL, pte, "Invalid extension.");
03035             send_text(TEXT_LINE1, TEXT_NORMAL, pte, "Please try again :");
03036             send_cursor_pos(pte,
03037                        (unsigned char) (TEXT_LINE2 +
03038                                     SELECTEXTENSION_START_ENTRY_POS +
03039                                     pte->size_buff_entry));
03040             send_blink_cursor(pte);
03041          } else
03042             show_main_page(pte);
03043       }
03044       break;
03045    case KEY_FUNC3:
03046       pte->size_buff_entry = 0;
03047       send_text(TEXT_LINE2, TEXT_NORMAL, pte, SELECTEXTENSION_MSG);
03048       send_blink_cursor(pte);
03049       send_cursor_pos(pte, TEXT_LINE2 + SELECTEXTENSION_START_ENTRY_POS);
03050       break;
03051    }
03052    return;
03053 }

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

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

02713 {
02714    int fav;
02715 
02716    if ((keycode < KEY_FAV1) && (keycode > KEY_FAV5)) {
02717       ast_log(LOG_WARNING, "It's not a favorite key\n");
02718       return;
02719    }
02720    if (keycode == KEY_FAV0)
02721       return;
02722    fav = keycode - KEY_FAV0;
02723    if (pte->device->softkeyicon[fav] == 0)
02724       return;
02725    ast_copy_string(pte->device->phone_number, pte->device->softkeynumber[fav],
02726                sizeof(pte->device->phone_number));
02727    HandleCallOutgoing(pte);
02728    return;
02729 }

int load_module ( void   )  [static]

XXX

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

Definition at line 5670 of file chan_unistim.c.

References ARRAY_LEN, ast_channel_register(), ast_cli_register_multiple(), AST_FORMAT_ALAW, ast_format_cap_add(), ast_format_cap_alloc(), ast_format_cap_copy(), ast_format_cap_destroy(), ast_format_set(), AST_FORMAT_ULAW, ast_free, ast_log(), ast_malloc, AST_MODULE_LOAD_DECLINE, AST_MODULE_LOAD_FAILURE, AST_MODULE_LOAD_SUCCESS, ast_rtp_glue_register, ast_sched_context_create(), ast_sched_context_destroy(), ast_channel_tech::capabilities, io_context_create(), io_context_destroy(), LOG_ERROR, reload_config(), restart_monitor(), and SIZE_PAGE.

05671 {
05672    int res;
05673    struct ast_format tmpfmt;
05674    if (!(global_cap = ast_format_cap_alloc())) {
05675       goto buff_failed;
05676    }
05677    if (!(unistim_tech.capabilities = ast_format_cap_alloc())) {
05678       goto buff_failed;
05679    }
05680 
05681    ast_format_cap_add(global_cap, ast_format_set(&tmpfmt, AST_FORMAT_ULAW, 0));
05682    ast_format_cap_add(global_cap, ast_format_set(&tmpfmt, AST_FORMAT_ALAW, 0));
05683    ast_format_cap_copy(unistim_tech.capabilities, global_cap);
05684    if (!(buff = ast_malloc(SIZE_PAGE)))
05685       goto buff_failed;
05686 
05687    io = io_context_create();
05688    if (!io) {
05689       ast_log(LOG_ERROR, "Failed to allocate IO context\n");
05690       goto io_failed;
05691    }
05692 
05693    sched = ast_sched_context_create();
05694    if (!sched) {
05695       ast_log(LOG_ERROR, "Failed to allocate scheduler context\n");
05696       goto sched_failed;
05697    }
05698 
05699    res = reload_config();
05700    if (res)
05701       return AST_MODULE_LOAD_DECLINE;
05702 
05703    /* Make sure we can register our unistim channel type */
05704    if (ast_channel_register(&unistim_tech)) {
05705       ast_log(LOG_ERROR, "Unable to register channel type '%s'\n", channel_type);
05706       goto chanreg_failed;
05707    } 
05708 
05709    ast_rtp_glue_register(&unistim_rtp_glue);
05710 
05711    ast_cli_register_multiple(unistim_cli, ARRAY_LEN(unistim_cli));
05712 
05713    restart_monitor();
05714 
05715    return AST_MODULE_LOAD_SUCCESS;
05716 
05717 chanreg_failed:
05718    /*! XXX \todo Leaking anything allocated by reload_config() ... */
05719    ast_sched_context_destroy(sched);
05720    sched = NULL;
05721 sched_failed:
05722    io_context_destroy(io);
05723    io = NULL;
05724 io_failed:
05725    ast_free(buff);
05726    buff = NULL;
05727    global_cap = ast_format_cap_destroy(global_cap);
05728    unistim_tech.capabilities = ast_format_cap_destroy(unistim_tech.capabilities);
05729 buff_failed:
05730    return AST_MODULE_LOAD_FAILURE;
05731 }

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

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

03123 {
03124    char tmp[AST_CONFIG_MAX_PATH];
03125    char count;
03126 
03127    snprintf(tmp, sizeof(tmp), "%s/%s/%s-%c.csv", ast_config_AST_LOG_DIR,
03128           USTM_LOG_DIR, pte->device->name, way);
03129    *f = fopen(tmp, "r");
03130    if (!*f) {
03131       display_last_error("Unable to open history file");
03132       return 0;
03133    }
03134    if (fread(&count, 1, 1, *f) != 1) {
03135       display_last_error("Unable to read history header - display.");
03136       fclose(*f);
03137       return 0;
03138    }
03139    if (count > MAX_ENTRY_LOG) {
03140       ast_log(LOG_WARNING, "Invalid count in history header of %s (%d max %d)\n", tmp,
03141             count, MAX_ENTRY_LOG);
03142       fclose(*f);
03143       return 0;
03144    }
03145    return count;
03146 }

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

Definition at line 5011 of file chan_unistim.c.

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

Referenced by build_device().

05012 {
05013    char line[256];
05014    char *at;
05015    char *number;
05016    char *icon;
05017    int p;
05018    int len = strlen(text);
05019 
05020    ast_copy_string(line, text, sizeof(line));
05021    /* Position specified ? */
05022    if ((len > 2) && (line[1] == '@')) {
05023       p = line[0];
05024       if ((p >= '0') && (p <= '5'))
05025          p -= '0';
05026       else {
05027          ast_log(LOG_WARNING,
05028                "Invalid position for bookmark : must be between 0 and 5\n");
05029          return 0;
05030       }
05031       if (d->softkeyicon[p] != 0) {
05032          ast_log(LOG_WARNING, "Invalid position %d for bookmark : already used\n:", p);
05033          return 0;
05034       }
05035       memmove(line, line + 2, sizeof(line));
05036    } else {
05037       /* No position specified, looking for a free slot */
05038       for (p = 0; p <= 5; p++) {
05039          if (!d->softkeyicon[p])
05040             break;
05041       }
05042       if (p > 5) {
05043          ast_log(LOG_WARNING, "No more free bookmark position\n");
05044          return 0;
05045       }
05046    }
05047    at = strchr(line, '@');
05048    if (!at) {
05049       ast_log(LOG_NOTICE, "Bookmark entry '%s' has no @ (at) sign!\n", text);
05050       return 0;
05051    }
05052    *at = '\0';
05053    at++;
05054    number = at;
05055    at = strchr(at, '@');
05056    if (ast_strlen_zero(number)) {
05057       ast_log(LOG_NOTICE, "Bookmark entry '%s' has no number\n", text);
05058       return 0;
05059    }
05060    if (ast_strlen_zero(line)) {
05061       ast_log(LOG_NOTICE, "Bookmark entry '%s' has no description\n", text);
05062       return 0;
05063    }
05064 
05065    at = strchr(number, '@');
05066    if (!at)
05067       d->softkeyicon[p] = FAV_ICON_SHARP;     /* default icon */
05068    else {
05069       *at = '\0';
05070       at++;
05071       icon = at;
05072       if (ast_strlen_zero(icon)) {
05073          ast_log(LOG_NOTICE, "Bookmark entry '%s' has no icon value\n", text);
05074          return 0;
05075       }
05076       if (strncmp(icon, "USTM/", 5))
05077          d->softkeyicon[p] = atoi(icon);
05078       else {
05079          d->softkeyicon[p] = 1;
05080          ast_copy_string(d->softkeydevice[p], icon + 5, sizeof(d->softkeydevice[p]));
05081       }
05082    }
05083    ast_copy_string(d->softkeylabel[p], line, sizeof(d->softkeylabel[p]));
05084    ast_copy_string(d->softkeynumber[p], number, sizeof(d->softkeynumber[p]));
05085    if (unistimdebug)
05086       ast_verb(0, "New bookmark at pos %d label='%s' number='%s' icon=%x\n",
05087                p, d->softkeylabel[p], d->softkeynumber[p], d->softkeyicon[p]);
05088    return 1;
05089 }

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

Definition at line 3562 of file chan_unistim.c.

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

Referenced by unistimsock_read().

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

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

Definition at line 3443 of file chan_unistim.c.

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

Referenced by parsing().

03444 {
03445    char tmpbuf[255];
03446    if (memcmp
03447       (buf + SIZE_HEADER, packet_recv_resume_connection_with_server,
03448        sizeof(packet_recv_resume_connection_with_server)) == 0) {
03449       rcv_resume_connection_with_server(pte);
03450       return;
03451    }
03452    if (memcmp(buf + SIZE_HEADER, packet_recv_firm_version, sizeof(packet_recv_firm_version)) ==
03453       0) {
03454       buf[size] = 0;
03455       if (unistimdebug)
03456          ast_verb(0, "Got the firmware version : '%s'\n", buf + 13);
03457       init_phone_step2(pte);
03458       return;
03459    }
03460    if (memcmp(buf + SIZE_HEADER, packet_recv_mac_addr, sizeof(packet_recv_mac_addr)) == 0) {
03461       rcv_mac_addr(pte, buf);
03462       return;
03463    }
03464    if (memcmp(buf + SIZE_HEADER, packet_recv_r2, sizeof(packet_recv_r2)) == 0) {
03465       if (unistimdebug)
03466          ast_verb(0, "R2 received\n");
03467       return;
03468    }
03469 
03470    if (pte->state < STATE_MAINPAGE) {
03471       if (unistimdebug)
03472          ast_verb(0, "Request not authorized in this state\n");
03473       return;
03474    }
03475    if (!memcmp(buf + SIZE_HEADER, packet_recv_pressed_key, sizeof(packet_recv_pressed_key))) {
03476       char keycode = buf[13];
03477 
03478       if (unistimdebug)
03479          ast_verb(0, "Key pressed : keycode = 0x%.2x - current state : %d\n", keycode,
03480                   pte->state);
03481 
03482       switch (pte->state) {
03483       case STATE_INIT:
03484          if (unistimdebug)
03485             ast_verb(0, "No keys allowed in the init state\n");
03486          break;
03487       case STATE_AUTHDENY:
03488          if (unistimdebug)
03489             ast_verb(0, "No keys allowed in authdeny state\n");
03490          break;
03491       case STATE_MAINPAGE:
03492          key_main_page(pte, keycode);
03493          break;
03494       case STATE_DIALPAGE:
03495          key_dial_page(pte, keycode);
03496          break;
03497       case STATE_RINGING:
03498          key_ringing(pte, keycode);
03499          break;
03500       case STATE_CALL:
03501          key_call(pte, keycode);
03502          break;
03503       case STATE_EXTENSION:
03504          key_select_extension(pte, keycode);
03505          break;
03506       case STATE_SELECTCODEC:
03507          key_select_codec(pte, keycode);
03508          break;
03509       case STATE_HISTORY:
03510          key_history(pte, keycode);
03511          break;
03512       default:
03513          ast_log(LOG_WARNING, "Key : Unknown state\n");
03514       }
03515       return;
03516    }
03517    if (memcmp(buf + SIZE_HEADER, packet_recv_pick_up, sizeof(packet_recv_pick_up)) == 0) {
03518       if (unistimdebug)
03519          ast_verb(0, "Handset off hook\n");
03520       if (!pte->device)        /* We are not yet registered (asking for a TN in AUTOPROVISIONING_TN) */
03521          return;
03522       pte->device->receiver_state = STATE_OFFHOOK;
03523       if (pte->device->output == OUTPUT_HEADPHONE)
03524          send_select_output(pte, OUTPUT_HEADPHONE, pte->device->volume, MUTE_OFF);
03525       else
03526          send_select_output(pte, OUTPUT_HANDSET, pte->device->volume, MUTE_OFF);
03527       if (pte->state == STATE_RINGING)
03528          HandleCallIncoming(pte);
03529       else if ((pte->state == STATE_DIALPAGE) || (pte->state == STATE_CALL))
03530          send_select_output(pte, OUTPUT_HANDSET, pte->device->volume, MUTE_OFF);
03531       else if (pte->state == STATE_EXTENSION) /* We must have a TN before calling */
03532          return;
03533       else {
03534          send_select_output(pte, OUTPUT_HANDSET, pte->device->volume, MUTE_OFF);
03535          handle_dial_page(pte);
03536       }
03537       return;
03538    }
03539    if (memcmp(buf + SIZE_HEADER, packet_recv_hangup, sizeof(packet_recv_hangup)) == 0) {
03540       if (unistimdebug)
03541          ast_verb(0, "Handset on hook\n");
03542       if (!pte->device)
03543          return;
03544       pte->device->receiver_state = STATE_ONHOOK;
03545       if (pte->state == STATE_CALL)
03546          close_call(pte);
03547       else if (pte->device->lines->subs[SUB_REAL]->owner)
03548          close_call(pte);
03549       else if (pte->state == STATE_EXTENSION)
03550          return;
03551       else
03552          show_main_page(pte);
03553       return;
03554    }
03555    strcpy(tmpbuf, ast_inet_ntoa(pte->sin.sin_addr));
03556    strcat(tmpbuf, " Unknown request packet\n");
03557    if (unistimdebug)
03558       ast_debug(1, "%s", tmpbuf);
03559    return;
03560 }

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

Definition at line 1555 of file chan_unistim.c.

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

Referenced by process_request().

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

static void rcv_resume_connection_with_server ( struct unistimsession pte  )  [static]

Definition at line 1452 of file chan_unistim.c.

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

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

Referenced by key_history(), and show_entry_history().

03056 {
03057    int pos = 0, i = 0, size = strlen(number);
03058 
03059    for (; i < size; i++) {
03060       if ((number[i] >= '0') && (number[i] <= '9')) {
03061          if (i == pos) {
03062             pos++;
03063             continue;
03064          }
03065          number[pos] = number[i];
03066          pos++;
03067       }
03068    }
03069    number[pos] = 0;
03070    return pos;
03071 }

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(), key_select_extension(), and reload_config().

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, and unistim_device::lines.

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

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

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

static int restart_monitor ( void   )  [static]

Definition at line 4709 of file chan_unistim.c.

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

04710 {
04711    pthread_attr_t attr;
04712    /* If we're supposed to be stopped -- stay stopped */
04713    if (monitor_thread == AST_PTHREADT_STOP)
04714       return 0;
04715    if (ast_mutex_lock(&monlock)) {
04716       ast_log(LOG_WARNING, "Unable to lock monitor\n");
04717       return -1;
04718    }
04719    if (monitor_thread == pthread_self()) {
04720       ast_mutex_unlock(&monlock);
04721       ast_log(LOG_WARNING, "Cannot kill myself\n");
04722       return -1;
04723    }
04724    if (monitor_thread != AST_PTHREADT_NULL) {
04725       /* Wake up the thread */
04726       pthread_kill(monitor_thread, SIGURG);
04727    } else {
04728       pthread_attr_init(&attr);
04729       pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE);
04730       /* Start a new monitor */
04731       if (ast_pthread_create(&monitor_thread, &attr, do_monitor, NULL) < 0) {
04732          ast_mutex_unlock(&monlock);
04733          ast_log(LOG_ERROR, "Unable to start monitor thread.\n");
04734          return -1;
04735       }
04736    }
04737    ast_mutex_unlock(&monlock);
04738    return 0;
04739 }

static void send_blink_cursor ( struct unistimsession pte  )  [static]

Definition at line 1429 of file chan_unistim.c.

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

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

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, send_client(), and SIZE_HEADER.

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, send_client(), SIZE_HEADER, ast_tm::tm_hour, ast_tm::tm_mday, ast_tm::tm_min, and ast_tm::tm_mon.

Referenced by rcv_mac_addr().

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, send_client(), SIZE_HEADER, ast_tm::tm_hour, ast_tm::tm_mday, ast_tm::tm_min, and ast_tm::tm_mon.

Referenced by init_phone_step2().

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, send_client(), SIZE_HEADER, ast_tm::tm_hour, ast_tm::tm_mday, ast_tm::tm_min, and ast_tm::tm_mon.

Referenced by init_phone_step2().

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, send_client(), and SIZE_HEADER.

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, send_client(), and SIZE_HEADER.

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, 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, send_client(), and SIZE_HEADER.

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(), unistimsession::device, FAV_ICON_HEADPHONES, FAV_ICON_HEADPHONES_ONHOLD, FAV_ICON_OFFHOOK_BLACK, FAV_ICON_ONHOLD_BLACK, FAV_ICON_SPEAKER_OFFHOOK_BLACK, FAV_ICON_SPEAKER_ONHOLD_BLACK, FAV_ICON_SPEAKER_ONHOOK_BLACK, LOG_WARNING, unistim_device::mute, MUTE_OFF, MUTE_ON, MUTE_ON_DISCRET, unistim_device::output, OUTPUT_HANDSET, OUTPUT_HEADPHONE, OUTPUT_SPEAKER, unistim_device::previous_output, unistim_device::receiver_state, send_client(), send_led_update(), SIZE_HEADER, STATE_OFFHOOK, VOLUME_LOW, and VOLUME_LOW_SPEAKER.

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

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, send_client(), SIZE_HEADER, and TEXT_LENGTH_MAX.

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

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, send_client(), SIZE_HEADER, STATUS_LENGTH_MAX, and unistim_device::status_method.

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

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, send_client(), and SIZE_HEADER.

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

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

Referenced by handle_dial_page().

02276 {
02277    int i;
02278    /* No country defined ? Using US tone */
02279    if (ast_strlen_zero(pte->device->country)) {
02280       if (unistimdebug)
02281          ast_verb(0, "No country defined, using US tone\n");
02282       send_tone(pte, 350, 440);
02283       return;
02284    }
02285    if (strlen(pte->device->country) != 2) {
02286       if (unistimdebug)
02287          ast_verb(0, "Country code != 2 char, using US tone\n");
02288       send_tone(pte, 350, 440);
02289       return;
02290    }
02291    i = 0;
02292    while (frequency[i].freq1) {
02293       if ((frequency[i].country[0] == pte->device->country[0]) &&
02294          (frequency[i].country[1] == pte->device->country[1])) {
02295          if (unistimdebug)
02296             ast_verb(0, "Country code found (%s), freq1=%d freq2=%d\n",
02297                      frequency[i].country, frequency[i].freq1, frequency[i].freq2);
02298          send_tone(pte, frequency[i].freq1, frequency[i].freq2);
02299       }
02300       i++;
02301    }
02302 }

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

03074 {
03075    char line[TEXT_LENGTH_MAX + 1], status[STATUS_LENGTH_MAX + 1], func1[10], func2[10],
03076       func3[10];
03077 
03078    if (fread(line, TEXT_LENGTH_MAX, 1, *f) != 1) {
03079       display_last_error("Can't read history date entry");
03080       fclose(*f);
03081       return;
03082    }
03083    line[sizeof(line) - 1] = '\0';
03084    send_text(TEXT_LINE0, TEXT_NORMAL, pte, line);
03085    if (fread(line, TEXT_LENGTH_MAX, 1, *f) != 1) {
03086       display_last_error("Can't read callerid entry");
03087       fclose(*f);
03088       return;
03089    }
03090    line[sizeof(line) - 1] = '\0';
03091    ast_copy_string(pte->device->lst_cid, line, sizeof(pte->device->lst_cid));
03092    send_text(TEXT_LINE1, TEXT_NORMAL, pte, line);
03093    if (fread(line, TEXT_LENGTH_MAX, 1, *f) != 1) {
03094       display_last_error("Can't read callername entry");
03095       fclose(*f);
03096       return;
03097    }
03098    line[sizeof(line) - 1] = '\0';
03099    send_text(TEXT_LINE2, TEXT_NORMAL, pte, line);
03100    fclose(*f);
03101 
03102    snprintf(line, sizeof(line), "Call %03d/%03d", pte->buff_entry[2],
03103           pte->buff_entry[1]);
03104    send_texttitle(pte, line);
03105 
03106    if (pte->buff_entry[2] == 1)
03107       strcpy(func1, "       ");
03108    else
03109       strcpy(func1, "Prvious");
03110    if (pte->buff_entry[2] >= pte->buff_entry[1])
03111       strcpy(func2, "       ");
03112    else
03113       strcpy(func2, "Next   ");
03114    if (ReformatNumber(pte->device->lst_cid))
03115       strcpy(func3, "Redial ");
03116    else
03117       strcpy(func3, "       ");
03118    snprintf(status, sizeof(status), "%s%s%sCancel", func1, func2, func3);
03119    send_text_status(pte, status);
03120 }

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

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

03149 {
03150    FILE *f;
03151    char count;
03152 
03153    if (!pte->device)
03154       return;
03155    if (!pte->device->callhistory)
03156       return;
03157    count = OpenHistory(pte, way, &f);
03158    if (!count)
03159       return;
03160    pte->buff_entry[0] = way;
03161    pte->buff_entry[1] = count;
03162    pte->buff_entry[2] = 1;
03163    show_entry_history(pte, &f);
03164    pte->state = STATE_HISTORY;
03165 }

static void show_main_page ( struct unistimsession pte  )  [static]

Definition at line 3167 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::maintext0, unistim_device::maintext1, unistim_device::maintext2, unistim_device::missed_call, MUTE_ON_DISCRET, unistim_device::output, send_favorite(), send_select_output(), send_text(), send_text_status(), send_texttitle(), send_tone(), Sendicon(), ShowExtensionPage(), unistimsession::sin, unistim_device::softkeylabel, unistim_device::softkeylinepos, unistimsession::state, STATE_MAINPAGE, TEXT_LENGTH_MAX, TEXT_LINE0, TEXT_LINE1, TEXT_LINE2, TEXT_NORMAL, unistim_device::titledefault, and unistim_device::volume.

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

03168 {
03169    char tmpbuf[TEXT_LENGTH_MAX + 1];
03170 
03171 
03172    if ((pte->device->extension == EXTENSION_ASK) &&
03173       (ast_strlen_zero(pte->device->extension_number))) {
03174       ShowExtensionPage(pte);
03175       return;
03176    }
03177 
03178    pte->state = STATE_MAINPAGE;
03179 
03180    send_tone(pte, 0, 0);
03181    send_select_output(pte, pte->device->output, pte->device->volume, MUTE_ON_DISCRET);
03182    pte->device->lines->lastmsgssent = 0;
03183    send_favorite(pte->device->softkeylinepos, FAV_ICON_ONHOOK_BLACK, pte,
03184              pte->device->softkeylabel[pte->device->softkeylinepos]);
03185    if (!ast_strlen_zero(pte->device->call_forward)) {
03186       if (pte->device->height == 1) {
03187          send_text(TEXT_LINE0, TEXT_NORMAL, pte, "Forwarding ON");
03188       } else {
03189          send_text(TEXT_LINE0, TEXT_NORMAL, pte, "Call forwarded to :");
03190          send_text(TEXT_LINE1, TEXT_NORMAL, pte, pte->device->call_forward);
03191       }
03192       Sendicon(TEXT_LINE0, FAV_ICON_REFLECT + FAV_BLINK_SLOW, pte);
03193       send_text_status(pte, "Dial   Redial NoForwd");
03194    } else {
03195       if ((pte->device->extension == EXTENSION_ASK) ||
03196          (pte->device->extension == EXTENSION_TN))
03197          send_text_status(pte, "Dial   Redial ForwardUnregis");
03198       else
03199          send_text_status(pte, "Dial   Redial Forward");
03200 
03201       send_text(TEXT_LINE1, TEXT_NORMAL, pte, pte->device->maintext1);
03202       if (pte->device->missed_call == 0)
03203          send_text(TEXT_LINE0, TEXT_NORMAL, pte, pte->device->maintext0);
03204       else {
03205          sprintf(tmpbuf, "%d unanswered call(s)", pte->device->missed_call);
03206          send_text(TEXT_LINE0, TEXT_NORMAL, pte, tmpbuf);
03207          Sendicon(TEXT_LINE0, FAV_ICON_CALL_CENTER + FAV_BLINK_SLOW, pte);
03208       }
03209    }
03210    if (ast_strlen_zero(pte->device->maintext2)) {
03211       strcpy(tmpbuf, "IP : ");
03212       strcat(tmpbuf, ast_inet_ntoa(pte->sin.sin_addr));
03213       send_text(TEXT_LINE2, TEXT_NORMAL, pte, tmpbuf);
03214    } else
03215       send_text(TEXT_LINE2, TEXT_NORMAL, pte, pte->device->maintext2);
03216    send_texttitle(pte, pte->device->titledefault);
03217    change_favorite_icon(pte, FAV_ICON_ONHOOK_BLACK);
03218 }

static void ShowExtensionPage ( struct unistimsession pte  )  [static]

static void start_rtp ( struct unistim_subchannel sub  )  [static]

Definition at line 2071 of file chan_unistim.c.

References ast_best_codec(), AST_FORMAT_ALAW, ast_format_cap_iscompatible(), ast_format_copy(), 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, ast_format::id, unistim_subchannel::lock, LOG_WARNING, unistim_device::nat, ast_channel::nativeformats, unistim_subchannel::owner, unistim_line::parent, unistim_subchannel::parent, qos, ast_channel::readformat, unistim_subchannel::rtp, unistim_device::rtp_method, unistim_device::rtp_port, send_client(), unistim_device::session, unistimsession::sin, SIZE_HEADER, unistimsession::sout, and ast_channel::writeformat.

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

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

Definition at line 1900 of file chan_unistim.c.

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

01901 {
01902 /*  struct ast_channel *towner; */
01903    struct ast_rtp_instance *rtp;
01904    int fds;
01905 
01906    if (unistimdebug)
01907       ast_verb(0, "Swapping %d and %d\n", a, b);
01908 
01909    if ((!p->subs[a]->owner) || (!p->subs[b]->owner)) {
01910       ast_log(LOG_WARNING,
01911             "Attempted to swap subchannels with a null owner : sub #%d=%p sub #%d=%p\n",
01912             a, p->subs[a]->owner, b, p->subs[b]->owner);
01913       return;
01914    }
01915    rtp = p->subs[a]->rtp;
01916    p->subs[a]->rtp = p->subs[b]->rtp;
01917    p->subs[b]->rtp = rtp;
01918 
01919    fds = p->subs[a]->owner->fds[0];
01920    p->subs[a]->owner->fds[0] = p->subs[b]->owner->fds[0];
01921    p->subs[b]->owner->fds[0] = fds;
01922 
01923    fds = p->subs[a]->owner->fds[1];
01924    p->subs[a]->owner->fds[1] = p->subs[b]->owner->fds[1];
01925    p->subs[b]->owner->fds[1] = fds;
01926 }

static void TransferCallStep1 ( struct unistimsession pte  )  [static]

Definition at line 2373 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, SUB_REAL, SUB_THREEWAY, and unistim_line::subs.

Referenced by key_call().

02374 {
02375    struct unistim_subchannel *sub;
02376    struct unistim_line *p = pte->device->lines;
02377 
02378    sub = p->subs[SUB_REAL];
02379 
02380    if (!sub->owner) {
02381       ast_log(LOG_WARNING, "Unable to find subchannel for music on hold\n");
02382       return;
02383    }
02384    if (p->subs[SUB_THREEWAY]) {
02385       if (unistimdebug)
02386          ast_verb(0, "Transfer canceled, hangup our threeway channel\n");
02387       if (p->subs[SUB_THREEWAY]->owner)
02388          ast_queue_hangup_with_cause(p->subs[SUB_THREEWAY]->owner, AST_CAUSE_NORMAL_CLEARING);
02389       else
02390          ast_log(LOG_WARNING, "Canceling a threeway channel without owner\n");
02391       return;
02392    }
02393    /* Start music on hold if appropriate */
02394    if (pte->device->moh)
02395       ast_log(LOG_WARNING, "Transfer with peer already listening music on hold\n");
02396    else {
02397       if (ast_bridged_channel(p->subs[SUB_REAL]->owner)) {
02398          ast_moh_start(ast_bridged_channel(p->subs[SUB_REAL]->owner),
02399                     pte->device->lines->musicclass, NULL);
02400          pte->device->moh = 1;
02401       } else {
02402          ast_log(LOG_WARNING, "Unable to find peer subchannel for music on hold\n");
02403          return;
02404       }
02405    }
02406    /* Silence our channel */
02407    if (!pte->device->silence_generator) {
02408       pte->device->silence_generator =
02409          ast_channel_start_silence_generator(p->subs[SUB_REAL]->owner);
02410       if (pte->device->silence_generator == NULL)
02411          ast_log(LOG_WARNING, "Unable to start a silence generator.\n");
02412       else if (unistimdebug)
02413          ast_verb(0, "Starting silence generator\n");
02414    }
02415    handle_dial_page(pte);
02416 }

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

Definition at line 1539 of file chan_unistim.c.

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

01540 {
01541    if (!x) {
01542       ast_log(LOG_WARNING, "Trying to unalloc the real channel %s@%s?!?\n", p->name,
01543             p->parent->name);
01544       return -1;
01545    }
01546    if (unistimdebug)
01547       ast_debug(1, "Released sub %d of channel %s@%s\n", x, p->name,
01548             p->parent->name);
01549    ast_mutex_destroy(&p->lock);
01550    ast_free(p->subs[x]);
01551    p->subs[x] = 0;
01552    return 0;
01553 }

static int unistim_answer ( struct ast_channel ast  )  [static]

Definition at line 3923 of file chan_unistim.c.

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

03924 {
03925    int res = 0;
03926    struct unistim_subchannel *sub;
03927    struct unistim_line *l;
03928    struct unistimsession *s;
03929 
03930    s = channel_to_session(ast);
03931    if (!s) {
03932       ast_log(LOG_WARNING, "unistim_answer on a disconnected device ?\n");
03933       return -1;
03934    }
03935    sub = ast->tech_pvt;
03936    l = sub->parent;
03937 
03938    if ((!sub->rtp) && (!l->subs[SUB_THREEWAY]))
03939       start_rtp(sub);
03940    if (unistimdebug)
03941       ast_verb(0, "unistim_answer(%s) on %s@%s-%d\n", ast_channel_name(ast), l->name,
03942                l->parent->name, sub->subtype);
03943    send_text(TEXT_LINE2, TEXT_NORMAL, l->parent->session, "is now on-line");
03944    if (l->subs[SUB_THREEWAY])
03945       send_text_status(l->parent->session, "Transf Cancel");
03946    else
03947       send_text_status(l->parent->session, "Hangup Transf");
03948    send_start_timer(l->parent->session);
03949    if (ast->_state != AST_STATE_UP)
03950       ast_setstate(ast, AST_STATE_UP);
03951    return res;
03952 }

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

Definition at line 3747 of file chan_unistim.c.

References ast_channel::_state, ast_channel_name(), 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_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, sub, ast_channel::tech_pvt, TEXT_LINE0, TEXT_LINE1, TEXT_LINE2, TEXT_NORMAL, ast_party_name::valid, and ast_party_number::valid.

03748 {
03749    int res = 0;
03750    struct unistim_subchannel *sub;
03751    struct unistimsession *session;
03752 
03753    session = channel_to_session(ast);
03754    if (!session) {
03755       ast_log(LOG_ERROR, "Device not registered, cannot call %s\n", dest);
03756       return -1;
03757    }
03758 
03759    sub = ast->tech_pvt;
03760    if ((ast->_state != AST_STATE_DOWN) && (ast->_state != AST_STATE_RESERVED)) {
03761       ast_log(LOG_WARNING, "unistim_call called on %s, neither down nor reserved\n",
03762             ast_channel_name(ast));
03763       return -1;
03764    }
03765 
03766    if (unistimdebug)
03767       ast_verb(3, "unistim_call(%s)\n", ast_channel_name(ast));
03768 
03769    session->state = STATE_RINGING;
03770    Sendicon(TEXT_LINE0, FAV_ICON_NONE, session);
03771 
03772    if (sub->owner) {
03773       if (sub->owner->connected.id.number.valid
03774          && sub->owner->connected.id.number.str) {
03775          if (session->device->height == 1) {
03776             send_text(TEXT_LINE0, TEXT_NORMAL, session, sub->owner->connected.id.number.str);
03777          } else {
03778             send_text(TEXT_LINE1, TEXT_NORMAL, session, sub->owner->connected.id.number.str);
03779          }
03780          change_callerid(session, 0, sub->owner->connected.id.number.str);
03781       } else {
03782          if (session->device->height == 1) {
03783             send_text(TEXT_LINE0, TEXT_NORMAL, session, DEFAULTCALLERID);
03784          } else {
03785             send_text(TEXT_LINE1, TEXT_NORMAL, session, DEFAULTCALLERID);
03786          }
03787          change_callerid(session, 0, DEFAULTCALLERID);
03788       }
03789       if (sub->owner->connected.id.name.valid
03790          && sub->owner->connected.id.name.str) {
03791          send_text(TEXT_LINE0, TEXT_NORMAL, session, sub->owner->connected.id.name.str);
03792          change_callerid(session, 1, sub->owner->connected.id.name.str);
03793       } else {
03794          send_text(TEXT_LINE0, TEXT_NORMAL, session, DEFAULTCALLERNAME);
03795          change_callerid(session, 1, DEFAULTCALLERNAME);
03796       }
03797    }
03798    send_text(TEXT_LINE2, TEXT_NORMAL, session, "is calling you.");
03799    send_text_status(session, "Accept              Ignore");
03800 
03801    if (sub->ringstyle == -1)
03802       send_ring(session, session->device->ringvolume, session->device->ringstyle);
03803    else {
03804       if (sub->ringvolume == -1)
03805          send_ring(session, session->device->ringvolume, sub->ringstyle);
03806       else
03807          send_ring(session, sub->ringvolume, sub->ringstyle);
03808    }
03809    change_favorite_icon(session, FAV_ICON_SPEAKER_ONHOOK_BLACK + FAV_BLINK_FAST);
03810 
03811    ast_setstate(ast, AST_STATE_RINGING);
03812    ast_queue_control(ast, AST_CONTROL_RINGING);
03813    return res;
03814 }

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

Definition at line 4922 of file chan_unistim.c.

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

04923 {
04924    switch (cmd) {
04925    case CLI_INIT:
04926       e->command = "unistim set debug {on|off}";
04927       e->usage =
04928          "Usage: unistim set debug\n" 
04929          "       Display debug messages.\n";
04930       return NULL;
04931 
04932    case CLI_GENERATE:
04933       return NULL;   /* no completion */
04934    }
04935 
04936    if (a->argc != e->args)
04937       return CLI_SHOWUSAGE;
04938 
04939    if (!strcasecmp(a->argv[3], "on")) {
04940       unistimdebug = 1;
04941       ast_cli(a->fd, "UNISTIM Debugging Enabled\n");
04942    } else if (!strcasecmp(a->argv[3], "off")) {
04943       unistimdebug = 0;
04944       ast_cli(a->fd, "UNISTIM Debugging Disabled\n");
04945    } else
04946       return CLI_SHOWUSAGE;
04947 
04948    return CLI_SUCCESS;
04949 }

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

Definition at line 2551 of file chan_unistim.c.

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

Referenced by key_call(), and unistim_senddigit_begin().

02552 {
02553    struct ast_frame f = { .frametype = AST_FRAME_DTMF, .subclass.integer = digit, .src = "unistim" };
02554    struct unistim_subchannel *sub;
02555    sub = pte->device->lines->subs[SUB_REAL];
02556    if (!sub->owner || sub->alreadygone) {
02557       ast_log(LOG_WARNING, "Unable to find subchannel in dtmf senddigit\n");
02558       return -1;
02559    }
02560 
02561    /* Send DTMF indication _before_ playing sounds */
02562    ast_queue_frame(sub->owner, &f);
02563 
02564    if (unistimdebug)
02565       ast_verb(0, "Send Digit %c\n", digit);
02566    switch (digit) {
02567    case '0':
02568       send_tone(pte, 941, 1336);
02569       break;
02570    case '1':
02571       send_tone(pte, 697, 1209);
02572       break;
02573    case '2':
02574       send_tone(pte, 697, 1336);
02575       break;
02576    case '3':
02577       send_tone(pte, 697, 1477);
02578       break;
02579    case '4':
02580       send_tone(pte, 770, 1209);
02581       break;
02582    case '5':
02583       send_tone(pte, 770, 1336);
02584       break;
02585    case '6':
02586       send_tone(pte, 770, 1477);
02587       break;
02588    case '7':
02589       send_tone(pte, 852, 1209);
02590       break;
02591    case '8':
02592       send_tone(pte, 852, 1336);
02593       break;
02594    case '9':
02595       send_tone(pte, 852, 1477);
02596       break;
02597    case 'A':
02598       send_tone(pte, 697, 1633);
02599       break;
02600    case 'B':
02601       send_tone(pte, 770, 1633);
02602       break;
02603    case 'C':
02604       send_tone(pte, 852, 1633);
02605       break;
02606    case 'D':
02607       send_tone(pte, 941, 1633);
02608       break;
02609    case '*':
02610       send_tone(pte, 941, 1209);
02611       break;
02612    case '#':
02613       send_tone(pte, 941, 1477);
02614       break;
02615    default:
02616       send_tone(pte, 500, 2000);
02617    }
02618    usleep(150000);          /* XXX Less than perfect, blocking an important thread is not a good idea */
02619    send_tone(pte, 0, 0);
02620    return 0;
02621 }

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

Definition at line 4110 of file chan_unistim.c.

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

04111 {
04112    struct unistim_subchannel *p = newchan->tech_pvt;
04113    struct unistim_line *l = p->parent;
04114 
04115    ast_mutex_lock(&p->lock);
04116 
04117    ast_debug(1, "New owner for channel USTM/%s@%s-%d is %s\n", l->name,
04118          l->parent->name, p->subtype, ast_channel_name(newchan));
04119 
04120    if (p->owner != oldchan) {
04121       ast_log(LOG_WARNING, "old channel wasn't %s (%p) but was %s (%p)\n",
04122             ast_channel_name(oldchan), oldchan, ast_channel_name(p->owner), p->owner);
04123       return -1;
04124    }
04125 
04126    p->owner = newchan;
04127 
04128    ast_mutex_unlock(&p->lock);
04129 
04130    return 0;
04131 
04132 }

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

Definition at line 5654 of file chan_unistim.c.

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

05655 {
05656    struct unistim_subchannel *sub = chan->tech_pvt;
05657 
05658    ao2_ref(sub->rtp, +1);
05659    *instance = sub->rtp;
05660 
05661    return AST_RTP_GLUE_RESULT_LOCAL;
05662 }

static int unistim_hangup ( struct ast_channel ast  )  [static]

Definition at line 3817 of file chan_unistim.c.

References unistim_subchannel::alreadygone, ast_bridged_channel(), ast_channel_name(), 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, 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, SUB_REAL, SUB_THREEWAY, unistim_line::subs, unistim_subchannel::subtype, swap_subs(), ast_channel::tech_pvt, TEXT_LINE0, TEXT_LINE1, TEXT_LINE2, TEXT_NORMAL, and unalloc_sub().

03818 {
03819    struct unistim_subchannel *sub;
03820    struct unistim_line *l;
03821    struct unistimsession *s;
03822 
03823    s = channel_to_session(ast);
03824    sub = ast->tech_pvt;
03825    if (!s) {
03826       ast_debug(1, "Asked to hangup channel not connected\n");
03827       ast_mutex_lock(&sub->lock);
03828       sub->owner = NULL;
03829       ast->tech_pvt = NULL;
03830       sub->alreadygone = 0;
03831       ast_mutex_unlock(&sub->lock);
03832       if (sub->rtp) {
03833          if (unistimdebug)
03834             ast_verb(0, "Destroying RTP session\n");
03835          ast_rtp_instance_destroy(sub->rtp);
03836          sub->rtp = NULL;
03837       }
03838       return 0;
03839    }
03840    l = sub->parent;
03841    if (unistimdebug)
03842       ast_verb(0, "unistim_hangup(%s) on %s@%s\n", ast_channel_name(ast), l->name, l->parent->name);
03843 
03844    if ((l->subs[SUB_THREEWAY]) && (sub->subtype == SUB_REAL)) {
03845       if (unistimdebug)
03846          ast_verb(0, "Real call disconnected while talking to threeway\n");
03847       sub->owner = NULL;
03848       ast->tech_pvt = NULL;
03849       return 0;
03850    }
03851    if ((l->subs[SUB_REAL]->owner) && (sub->subtype == SUB_THREEWAY) &&
03852       (sub->alreadygone == 0)) {
03853       if (unistimdebug)
03854          ast_verb(0, "threeway call disconnected, switching to real call\n");
03855       send_text(TEXT_LINE0, TEXT_NORMAL, s, "Three way call canceled,");
03856       send_text(TEXT_LINE1, TEXT_NORMAL, s, "switching back to");
03857       send_text(TEXT_LINE2, TEXT_NORMAL, s, "previous call.");
03858       send_text_status(s, "Hangup Transf");
03859       ast_moh_stop(ast_bridged_channel(l->subs[SUB_REAL]->owner));
03860       swap_subs(l, SUB_THREEWAY, SUB_REAL);
03861       l->parent->moh = 0;
03862       ast_mutex_lock(&sub->lock);
03863       sub->owner = NULL;
03864       ast->tech_pvt = NULL;
03865       ast_mutex_unlock(&sub->lock);
03866       unalloc_sub(l, SUB_THREEWAY);
03867       return 0;
03868    }
03869    ast_mutex_lock(&sub->lock);
03870    sub->owner = NULL;
03871    ast->tech_pvt = NULL;
03872    sub->alreadygone = 0;
03873    ast_mutex_unlock(&sub->lock);
03874    if (!s) {
03875       if (unistimdebug)
03876          ast_verb(0, "Asked to hangup channel not connected (no session)\n");
03877       if (sub->rtp) {
03878          if (unistimdebug)
03879             ast_verb(0, "Destroying RTP session\n");
03880          ast_rtp_instance_destroy(sub->rtp);
03881          sub->rtp = NULL;
03882       }
03883       return 0;
03884    }
03885    if (sub->subtype == SUB_REAL) {
03886       /* Stop the silence generator */
03887       if (s->device->silence_generator) {
03888          if (unistimdebug)
03889             ast_verb(0, "Stopping silence generator\n");
03890          if (sub->owner)
03891             ast_channel_stop_silence_generator(sub->owner,
03892                                        s->device->silence_generator);
03893          else
03894             ast_log(LOG_WARNING,
03895                   "Trying to stop silence generator on a null channel !\n");
03896          s->device->silence_generator = NULL;
03897       }
03898    }
03899    l->parent->moh = 0;
03900    send_no_ring(s);
03901    send_end_call(s);
03902    if (sub->rtp) {
03903       if (unistimdebug)
03904          ast_verb(0, "Destroying RTP session\n");
03905       ast_rtp_instance_destroy(sub->rtp);
03906       sub->rtp = NULL;
03907    } else if (unistimdebug)
03908       ast_verb(0, "No RTP session to destroy\n");
03909    if (l->subs[SUB_THREEWAY]) {
03910       if (unistimdebug)
03911          ast_verb(0, "Cleaning other subchannels\n");
03912       unalloc_sub(l, SUB_THREEWAY);
03913    }
03914    if (s->state == STATE_RINGING)
03915       cancel_dial(s);
03916    else if (s->state == STATE_CALL)
03917       close_call(s);
03918 
03919    return 0;
03920 }

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

Definition at line 4182 of file chan_unistim.c.

References ast_channel::_state, unistim_subchannel::alreadygone, ast_channel_name(), 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, unistim_line::parent, unistim_subchannel::parent, send_text(), sub, ast_channel::tech_pvt, TEXT_LINE2, TEXT_NORMAL, and unistim_device::tz.

04184 {
04185    struct unistim_subchannel *sub;
04186    struct unistim_line *l;
04187    struct unistimsession *s;
04188 
04189    if (unistimdebug) {
04190       ast_verb(3, "Asked to indicate '%s' condition on channel %s\n",
04191                control2str(ind), ast_channel_name(ast));
04192    }
04193 
04194    s = channel_to_session(ast);
04195    if (!s)
04196       return -1;
04197 
04198    sub = ast->tech_pvt;
04199    l = sub->parent;
04200 
04201    switch (ind) {
04202    case AST_CONTROL_RINGING:
04203       if (ast->_state != AST_STATE_UP) {
04204          send_text(TEXT_LINE2, TEXT_NORMAL, s, "Ringing...");
04205          in_band_indication(ast, l->parent->tz, "ring");
04206          s->device->missed_call = -1;
04207          break;
04208       }
04209       return -1;
04210    case AST_CONTROL_BUSY:
04211       if (ast->_state != AST_STATE_UP) {
04212          sub->alreadygone = 1;
04213          send_text(TEXT_LINE2, TEXT_NORMAL, s, "Busy");
04214          in_band_indication(ast, l->parent->tz, "busy");
04215          s->device->missed_call = -1;
04216          break;
04217       }
04218       return -1;
04219    case AST_CONTROL_INCOMPLETE:
04220       /* Overlapped dialing is not currently supported for UNIStim.  Treat an indication
04221        * of incomplete as congestion
04222        */
04223    case AST_CONTROL_CONGESTION:
04224       if (ast->_state != AST_STATE_UP) {
04225          sub->alreadygone = 1;
04226          send_text(TEXT_LINE2, TEXT_NORMAL, s, "Congestion");
04227          in_band_indication(ast, l->parent->tz, "congestion");
04228          s->device->missed_call = -1;
04229          break;
04230       }
04231       return -1;
04232    case AST_CONTROL_HOLD:
04233       ast_moh_start(ast, data, NULL);
04234       break;
04235    case AST_CONTROL_UNHOLD:
04236       ast_moh_stop(ast);
04237       break;
04238    case AST_CONTROL_PROGRESS:
04239    case AST_CONTROL_SRCUPDATE:
04240       break;
04241    case -1:
04242       ast_playtones_stop(ast);
04243       s->device->missed_call = 0;
04244       break;
04245    case AST_CONTROL_PROCEEDING:
04246       break;
04247    default:
04248       ast_log(LOG_WARNING, "Don't know how to indicate condition %d\n", ind);
04249       return -1;
04250    }
04251 
04252    return 0;
04253 }

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

Definition at line 4791 of file chan_unistim.c.

References ast_channel::_bridge, unistim_subchannel::alreadygone, ast_cli_args::argc, ast_cli_entry::args, ast_cli(), ast_getformatname_multiple(), ast_inet_ntoa(), ast_mutex_lock, ast_mutex_unlock, unistim_line::cap, 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, sub, unistim_line::subs, unistim_subchannel::subtype, unistimsession::timeout, and ast_cli_entry::usage.

04792 {
04793    struct unistim_device *device = devices;
04794    struct unistim_line *line;
04795    struct unistim_subchannel *sub;
04796    struct unistimsession *s;
04797    int i;
04798    struct ast_channel *tmp;
04799 
04800    switch (cmd) {
04801    case CLI_INIT:
04802       e->command = "unistim show info";
04803       e->usage =
04804          "Usage: unistim show info\n" 
04805          "       Dump internal structures.\n";
04806       return NULL;
04807 
04808    case CLI_GENERATE:
04809       return NULL;   /* no completion */
04810    }
04811 
04812    if (a->argc != e->args)
04813       return CLI_SHOWUSAGE;
04814 
04815    ast_cli(a->fd, "Dumping internal structures :\ndevice\n->line\n-->sub\n");
04816    while (device) {
04817       ast_cli(a->fd, "\nname=%s id=%s line=%p ha=%p sess=%p device=%p\n",
04818             device->name, device->id, device->lines, device->ha, device->session,
04819             device);
04820       line = device->lines;
04821       while (line) {
04822          char tmp2[256];
04823          ast_cli(a->fd,
04824                "->name=%s fullname=%s exten=%s callid=%s cap=%s device=%p line=%p\n",
04825                line->name, line->fullname, line->exten, line->cid_num,
04826                ast_getformatname_multiple(tmp2, sizeof(tmp2), line->cap), line->parent, line);
04827          for (i = 0; i < MAX_SUBS; i++) {
04828             sub = line->subs[i];
04829             if (!sub)
04830                continue;
04831             if (!sub->owner)
04832                tmp = (void *) -42;
04833             else
04834                tmp = sub->owner->_bridge;
04835             if (sub->subtype != i)
04836                ast_cli(a->fd, "Warning ! subchannel->subs[%d] have a subtype=%d\n", i,
04837                      sub->subtype);
04838             ast_cli(a->fd,
04839                   "-->subtype=%d chan=%p rtp=%p bridge=%p line=%p alreadygone=%d\n",
04840                   sub->subtype, sub->owner, sub->rtp, tmp, sub->parent,
04841                   sub->alreadygone);
04842          }
04843          line = line->next;
04844       }
04845       device = device->next;
04846    }
04847    ast_cli(a->fd, "\nSessions:\n");
04848    ast_mutex_lock(&sessionlock);
04849    s = sessions;
04850    while (s) {
04851       ast_cli(a->fd,
04852             "sin=%s timeout=%u state=%d macaddr=%s device=%p session=%p\n",
04853             ast_inet_ntoa(s->sin.sin_addr), s->timeout, s->state, s->macaddr,
04854             s->device, s);
04855       s = s->next;
04856    }
04857    ast_mutex_unlock(&sessionlock);
04858 
04859    return CLI_SUCCESS;
04860 }

static struct unistim_line* unistim_line_alloc ( void   )  [static, read]

Definition at line 1510 of file chan_unistim.c.

References ast_calloc, ast_format_cap_alloc_nolock(), ast_free, and unistim_line::cap.

Referenced by build_device(), and rcv_mac_addr().

01511 {
01512    struct unistim_line *l;
01513    if (!(l = ast_calloc(1, sizeof(*l)))) {
01514       return NULL;
01515    }
01516 
01517    if (!(l->cap = ast_format_cap_alloc_nolock())) {
01518       ast_free(l);
01519       return NULL;
01520    }
01521    return l;
01522 }

static void unistim_line_copy ( struct unistim_line dst,
struct unistim_line src 
) [static]

Definition at line 1492 of file chan_unistim.c.

References ast_format_cap_copy(), and unistim_line::cap.

Referenced by rcv_mac_addr().

01493 {
01494    struct ast_format_cap *tmp = src->cap;
01495    memcpy(dst, src, sizeof(*dst)); /* this over writes the cap ptr, so we have to reset it */
01496    src->cap = tmp;
01497    ast_format_cap_copy(src->cap, dst->cap);
01498 }

static struct unistim_line* unistim_line_destroy ( struct unistim_line l  )  [static, read]

Definition at line 1500 of file chan_unistim.c.

References ast_format_cap_destroy(), ast_free, and unistim_line::cap.

Referenced by build_device(), and rcv_mac_addr().

01501 {
01502    if (!l) {
01503       return NULL;
01504    }
01505    l->cap = ast_format_cap_destroy(l->cap);
01506    ast_free(l);
01507    return NULL;
01508 }

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

Protos

Definition at line 4539 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_channel_name(), ast_format_cap_copy(), ast_format_cap_is_empty(), ast_format_copy(), 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_strlen_zero(), ast_update_use_count(), ast_verb, unistim_device::call_forward, ast_channel::caller, unistim_line::callgroup, ast_channel::callgroup, unistim_line::cap, unistim_line::cid_num, unistim_line::context, unistim_line::exten, ast_channel::fds, global_jbconf, ast_party_caller::id, unistim_line::language, LOG_WARNING, 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, usecnt_lock, ast_party_name::valid, ast_party_number::valid, and ast_channel::writeformat.

Referenced by HandleCallOutgoing(), and unistim_request().

04540 {
04541    struct ast_channel *tmp;
04542    struct unistim_line *l;
04543    struct ast_format tmpfmt;
04544 
04545    if (!sub) {
04546       ast_log(LOG_WARNING, "subchannel null in unistim_new\n");
04547       return NULL;
04548    }
04549    if (!sub->parent) {
04550       ast_log(LOG_WARNING, "no line for subchannel %p\n", sub);
04551       return NULL;
04552    }
04553    l = sub->parent;
04554    tmp = ast_channel_alloc(1, state, l->cid_num, NULL, l->accountcode, l->exten,
04555       l->context, linkedid, l->amaflags, "%s@%s-%d", l->name, l->parent->name, sub->subtype);
04556    if (unistimdebug)
04557       ast_verb(0, "unistim_new sub=%d (%p) chan=%p\n", sub->subtype, sub, tmp);
04558    if (!tmp) {
04559       ast_log(LOG_WARNING, "Unable to allocate channel structure\n");
04560       return NULL;
04561    }
04562 
04563    ast_format_cap_copy(tmp->nativeformats, l->cap);
04564    if (ast_format_cap_is_empty(tmp->nativeformats))
04565       ast_format_cap_copy(tmp->nativeformats, global_cap);
04566    ast_best_codec(tmp->nativeformats, &tmpfmt);
04567    if (unistimdebug) {
04568       char tmp1[256], tmp2[256], tmp3[256];
04569       ast_verb(0, "Best codec = %s from nativeformats %s (line cap=%s global=%s)\n",
04570          ast_getformatname(&tmpfmt),
04571          ast_getformatname_multiple(tmp1, sizeof(tmp1), tmp->nativeformats),
04572          ast_getformatname_multiple(tmp2, sizeof(tmp2), l->cap),
04573          ast_getformatname_multiple(tmp3, sizeof(tmp3), global_cap));
04574    }
04575    if ((sub->rtp) && (sub->subtype == 0)) {
04576       if (unistimdebug)
04577          ast_verb(0, "New unistim channel with a previous rtp handle ?\n");
04578       tmp->fds[0] = ast_rtp_instance_fd(sub->rtp, 0);
04579       tmp->fds[1] = ast_rtp_instance_fd(sub->rtp, 1);
04580    }
04581    if (sub->rtp)
04582       ast_jb_configure(tmp, &global_jbconf);
04583       
04584 /*      tmp->type = type; */
04585    ast_setstate(tmp, state);
04586    if (state == AST_STATE_RING)
04587       tmp->rings = 1;
04588    tmp->adsicpe = AST_ADSI_UNAVAILABLE;
04589    ast_format_copy(&tmp->writeformat, &tmpfmt);
04590    ast_format_copy(&tmp->rawwriteformat, &tmpfmt);
04591    ast_format_copy(&tmp->readformat, &tmpfmt);
04592    ast_format_copy(&tmp->rawreadformat, &tmpfmt);
04593    tmp->tech_pvt = sub;
04594    tmp->tech = &unistim_tech;
04595    if (!ast_strlen_zero(l->language))
04596       ast_channel_language_set(tmp, l->language);
04597    sub->owner = tmp;
04598    ast_mutex_lock(&usecnt_lock);
04599    usecnt++;
04600    ast_mutex_unlock(&usecnt_lock);
04601    ast_update_use_count();
04602    tmp->callgroup = l->callgroup;
04603    tmp->pickupgroup = l->pickupgroup;
04604    ast_channel_call_forward_set(tmp, l->parent->call_forward);
04605    if (!ast_strlen_zero(l->cid_num)) {
04606       char *name, *loc, *instr;
04607       instr = ast_strdup(l->cid_num);
04608       if (instr) {
04609          ast_callerid_parse(instr, &name, &loc);
04610          tmp->caller.id.number.valid = 1;
04611          ast_free(tmp->caller.id.number.str);
04612          tmp->caller.id.number.str = ast_strdup(loc);
04613          tmp->caller.id.name.valid = 1;
04614          ast_free(tmp->caller.id.name.str);
04615          tmp->caller.id.name.str = ast_strdup(name);
04616          ast_free(instr);
04617       }
04618    }
04619    tmp->priority = 1;
04620    if (state != AST_STATE_DOWN) {
04621       if (unistimdebug)
04622          ast_verb(0, "Starting pbx in unistim_new\n");
04623       if (ast_pbx_start(tmp)) {
04624          ast_log(LOG_WARNING, "Unable to start PBX on %s\n", ast_channel_name(tmp));
04625          ast_hangup(tmp);
04626          tmp = NULL;
04627       }
04628    }
04629 
04630    return tmp;
04631 }

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

Definition at line 4061 of file chan_unistim.c.

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

04062 {
04063    struct ast_frame *fr;
04064    struct unistim_subchannel *sub = ast->tech_pvt;
04065 
04066    ast_mutex_lock(&sub->lock);
04067    fr = unistim_rtp_read(ast, sub);
04068    ast_mutex_unlock(&sub->lock);
04069 
04070    return fr;
04071 }

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

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

04956 {
04957    switch (cmd) {
04958    case CLI_INIT:
04959       e->command = "unistim reload";
04960       e->usage =
04961          "Usage: unistim reload\n" 
04962          "       Reloads UNISTIM configuration from unistim.conf\n";
04963       return NULL;
04964 
04965    case CLI_GENERATE:
04966       return NULL;   /* no completion */
04967    }
04968 
04969    if (e && a && a->argc != e->args)
04970       return CLI_SHOWUSAGE;
04971 
04972    if (unistimdebug)
04973       ast_verb(0, "reload unistim\n");
04974 
04975    ast_mutex_lock(&unistim_reload_lock);
04976    if (!unistim_reloading)
04977       unistim_reloading = 1;
04978    ast_mutex_unlock(&unistim_reload_lock);
04979 
04980    restart_monitor();
04981 
04982    return CLI_SUCCESS;
04983 }

static struct ast_channel * unistim_request ( const char *  type,
struct ast_format_cap cap,
const struct ast_channel requestor,
const char *  dest,
int *  cause 
) [static, read]

Definition at line 4743 of file chan_unistim.c.

References AST_CAUSE_BUSY, AST_CAUSE_CONGESTION, ast_channel_linkedid(), ast_copy_string(), ast_format_cap_copy(), ast_format_cap_has_joint(), ast_getformatname_multiple(), ast_log(), AST_STATE_DOWN, ast_strlen_zero(), ast_verb, unistim_line::cap, find_subchannel_by_name(), LOG_NOTICE, LOG_WARNING, unistim_subchannel::owner, unistim_subchannel::parent, restart_monitor(), sub, and unistim_new().

04745 {
04746    struct unistim_subchannel *sub;
04747    struct ast_channel *tmpc = NULL;
04748    char tmp[256];
04749    char tmp2[256];
04750 
04751    if (!(ast_format_cap_has_joint(cap, global_cap))) {
04752       ast_log(LOG_NOTICE,
04753             "Asked to get a channel of unsupported format %s while capability is %s\n",
04754             ast_getformatname_multiple(tmp2, sizeof(tmp2), cap), ast_getformatname_multiple(tmp, sizeof(tmp), global_cap));
04755       return NULL;
04756    }
04757 
04758    ast_copy_string(tmp, dest, sizeof(tmp));
04759    if (ast_strlen_zero(tmp)) {
04760       ast_log(LOG_NOTICE, "Unistim channels require a device\n");
04761       return NULL;
04762    }
04763 
04764    sub = find_subchannel_by_name(tmp);
04765    if (!sub) {
04766       ast_log(LOG_NOTICE, "No available lines on: %s\n", dest);
04767       *cause = AST_CAUSE_CONGESTION;
04768       return NULL;
04769    }
04770 
04771    ast_verb(3, "unistim_request(%s)\n", tmp);
04772    /* Busy ? */
04773    if (sub->owner) {
04774       if (unistimdebug)
04775          ast_verb(0, "Can't create channel : Busy !\n");
04776       *cause = AST_CAUSE_BUSY;
04777       return NULL;
04778    }
04779    ast_format_cap_copy(sub->parent->cap, cap);
04780    tmpc = unistim_new(sub, AST_STATE_DOWN, requestor ? ast_channel_linkedid(requestor) : NULL);
04781    if (!tmpc)
04782       ast_log(LOG_WARNING, "Unable to make channel for '%s'\n", tmp);
04783    if (unistimdebug)
04784       ast_verb(0, "unistim_request owner = %p\n", sub->owner);
04785    restart_monitor();
04786 
04787    /* and finish */
04788    return tmpc;
04789 }

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

Definition at line 4013 of file chan_unistim.c.

References ast_debug, ast_format_cap_iscompatible(), ast_format_cap_set(), AST_FRAME_VOICE, ast_getformatname(), ast_getformatname_multiple(), ast_log(), ast_null_frame, ast_rtp_instance_read(), ast_set_read_format(), ast_set_write_format(), f, ast_channel::fdno, ast_frame_subclass::format, ast_frame::frametype, LOG_WARNING, ast_channel::nativeformats, unistim_subchannel::owner, ast_channel::readformat, unistim_subchannel::rtp, ast_frame::subclass, unistim_subchannel::subtype, and ast_channel::writeformat.

Referenced by unistim_read().

04015 {
04016    /* Retrieve audio/etc from channel.  Assumes sub->lock is already held. */
04017    struct ast_frame *f;
04018 
04019    if (!ast) {
04020       ast_log(LOG_WARNING, "Channel NULL while reading\n");
04021       return &ast_null_frame;
04022    }
04023 
04024    if (!sub->rtp) {
04025       ast_log(LOG_WARNING, "RTP handle NULL while reading on subchannel %d\n",
04026             sub->subtype);
04027       return &ast_null_frame;
04028    }
04029 
04030    switch (ast->fdno) {
04031    case 0:
04032       f = ast_rtp_instance_read(sub->rtp, 0);     /* RTP Audio */
04033       break;
04034    case 1:
04035       f = ast_rtp_instance_read(sub->rtp, 1);    /* RTCP Control Channel */
04036       break;
04037    default:
04038       f = &ast_null_frame;
04039    }
04040 
04041    if (sub->owner) {
04042       /* We already hold the channel lock */
04043       if (f->frametype == AST_FRAME_VOICE) {
04044          if (!(ast_format_cap_iscompatible(sub->owner->nativeformats, &f->subclass.format))) {
04045             char tmp[256];
04046             ast_debug(1,
04047                   "Oooh, format changed from %s to %s\n",
04048                   ast_getformatname_multiple(tmp, sizeof(tmp), sub->owner->nativeformats),
04049                   ast_getformatname(&f->subclass.format));
04050 
04051             ast_format_cap_set(sub->owner->nativeformats, &f->subclass.format);
04052             ast_set_read_format(sub->owner, &sub->owner->readformat);
04053             ast_set_write_format(sub->owner, &sub->owner->writeformat);
04054          }
04055       }
04056    }
04057 
04058    return f;
04059 }

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

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

04497 {
04498    struct ast_event *event;
04499    int new;
04500    char *mailbox, *context;
04501    struct unistim_line *peer = s->device->lines;
04502 
04503    context = mailbox = ast_strdupa(peer->mailbox);
04504    strsep(&context, "@");
04505    if (ast_strlen_zero(context))
04506       context = "default";
04507 
04508    event = ast_event_get_cached(AST_EVENT_MWI,
04509       AST_EVENT_IE_MAILBOX, AST_EVENT_IE_PLTYPE_STR, mailbox,
04510       AST_EVENT_IE_CONTEXT, AST_EVENT_IE_PLTYPE_STR, context,
04511       AST_EVENT_IE_END);
04512 
04513    if (event) {
04514       new = ast_event_get_ie_uint(event, AST_EVENT_IE_NEWMSGS);
04515       ast_event_destroy(event);
04516    } else { /* Fall back on checking the mailbox directly */
04517       new = ast_app_has_voicemail(peer->mailbox, "INBOX");
04518    }
04519 
04520    peer->nextmsgcheck = tick + TIMER_MWI;
04521 
04522    /* Return now if it's the same thing we told them last time */
04523    if (new == peer->lastmsgssent) {
04524       return 0;
04525    }
04526 
04527    peer->lastmsgssent = new;
04528    if (new == 0) {
04529       send_led_update(s, 0);
04530    } else {
04531       send_led_update(s, 1);
04532    }
04533 
04534    return 0;
04535 }

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

Definition at line 4322 of file chan_unistim.c.

References channel_to_session(), and unistim_do_senddigit().

04323 {
04324    struct unistimsession *pte = channel_to_session(ast);
04325 
04326    if (!pte)
04327       return -1;
04328 
04329    return unistim_do_senddigit(pte, digit);
04330 }

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

Definition at line 4332 of file chan_unistim.c.

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

04333 {
04334    struct unistimsession *pte = channel_to_session(ast);
04335    struct ast_frame f = { 0, };
04336    struct unistim_subchannel *sub;
04337 
04338    sub = pte->device->lines->subs[SUB_REAL];
04339 
04340    if (!sub->owner || sub->alreadygone) {
04341       ast_log(LOG_WARNING, "Unable to find subchannel in dtmf senddigit_end\n");
04342       return -1;
04343    }
04344 
04345    if (unistimdebug)
04346       ast_verb(0, "Send Digit off %c\n", digit);
04347 
04348    if (!pte)
04349       return -1;
04350 
04351    send_tone(pte, 0, 0);
04352    f.frametype = AST_FRAME_DTMF;
04353    f.subclass.integer = digit;
04354    f.src = "unistim";
04355    ast_queue_frame(sub->owner, &f);
04356 
04357    return 0;
04358 }

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

Definition at line 4362 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, and TEXT_NORMAL.

04363 {
04364    struct unistimsession *pte = channel_to_session(ast);
04365    int size;
04366    char tmp[TEXT_LENGTH_MAX + 1];
04367 
04368    if (unistimdebug)
04369       ast_verb(0, "unistim_sendtext called\n");
04370 
04371    if (!text) {
04372       ast_log(LOG_WARNING, "unistim_sendtext called with a null text\n");
04373       return 1;
04374    }
04375 
04376    size = strlen(text);
04377    if (text[0] == '@') {
04378       int pos = 0, i = 1, tok = 0, sz = 0;
04379       char label[11];
04380       char number[16];
04381       char icon = '\0';
04382       char cur = '\0';
04383 
04384       memset(label, 0, 11);
04385       memset(number, 0, 16);
04386       while (text[i]) {
04387          cur = text[i++];
04388          switch (tok) {
04389          case 0:
04390             if ((cur < '0') && (cur > '5')) {
04391                ast_log(LOG_WARNING,
04392                      "sendtext failed : position must be a number beetween 0 and 5\n");
04393                return 1;
04394             }
04395             pos = cur - '0';
04396             tok = 1;
04397             continue;
04398          case 1:
04399             if (cur != '@') {
04400                ast_log(LOG_WARNING, "sendtext failed : invalid position\n");
04401                return 1;
04402             }
04403             tok = 2;
04404             continue;
04405          case 2:
04406             if ((cur < '3') && (cur > '6')) {
04407                ast_log(LOG_WARNING,
04408                      "sendtext failed : icon must be a number beetween 32 and 63 (first digit invalid)\n");
04409                return 1;
04410             }
04411             icon = (cur - '0') * 10;
04412             tok = 3;
04413             continue;
04414          case 3:
04415             if ((cur < '0') && (cur > '9')) {
04416                ast_log(LOG_WARNING,
04417                      "sendtext failed : icon must be a number beetween 32 and 63 (second digit invalid)\n");
04418                return 1;
04419             }
04420             icon += (cur - '0');
04421             tok = 4;
04422             continue;
04423          case 4:
04424             if (cur != '@') {
04425                ast_log(LOG_WARNING,
04426                      "sendtext failed : icon must be a number beetween 32 and 63 (too many digits)\n");
04427                return 1;
04428             }
04429             tok = 5;
04430             continue;
04431          case 5:
04432             if (cur == '@') {
04433                tok = 6;
04434                sz = 0;
04435                continue;
04436             }
04437             if (sz > 10)
04438                continue;
04439             label[sz] = cur;
04440             sz++;
04441             continue;
04442          case 6:
04443             if (sz > 15) {
04444                ast_log(LOG_WARNING,
04445                      "sendtext failed : extension too long = %d (15 car max)\n",
04446                      sz);
04447                return 1;
04448             }
04449             number[sz] = cur;
04450             sz++;
04451             continue;
04452          }
04453       }
04454       if (tok != 6) {
04455          ast_log(LOG_WARNING, "sendtext failed : incomplet command\n");
04456          return 1;
04457       }
04458       if (!pte->device) {
04459          ast_log(LOG_WARNING, "sendtext failed : no device ?\n");
04460          return 1;
04461       }
04462       strcpy(pte->device->softkeylabel[pos], label);
04463       strcpy(pte->device->softkeynumber[pos], number);
04464       pte->device->softkeyicon[pos] = icon;
04465       send_favorite(pos, icon, pte, label);
04466       return 0;
04467    }
04468 
04469    if (size <= TEXT_LENGTH_MAX * 2) {
04470       if (pte->device->height == 1) {
04471          send_text(TEXT_LINE0, TEXT_NORMAL, pte, text);
04472       } else {
04473          send_text(TEXT_LINE0, TEXT_NORMAL, pte, "Message :");
04474          send_text(TEXT_LINE1, TEXT_NORMAL, pte, text);
04475       }
04476       if (size <= TEXT_LENGTH_MAX) {
04477          send_text(TEXT_LINE2, TEXT_NORMAL, pte, "");
04478          return 0;
04479       }
04480       memcpy(tmp, text + TEXT_LENGTH_MAX, TEXT_LENGTH_MAX);
04481       tmp[sizeof(tmp) - 1] = '\0';
04482       send_text(TEXT_LINE2, TEXT_NORMAL, pte, tmp);
04483       return 0;
04484    }
04485    send_text(TEXT_LINE0, TEXT_NORMAL, pte, text);
04486    memcpy(tmp, text + TEXT_LENGTH_MAX, TEXT_LENGTH_MAX);
04487    tmp[sizeof(tmp) - 1] = '\0';
04488    send_text(TEXT_LINE1, TEXT_NORMAL, pte, tmp);
04489    memcpy(tmp, text + TEXT_LENGTH_MAX * 2, TEXT_LENGTH_MAX);
04490    tmp[sizeof(tmp) - 1] = '\0';
04491    send_text(TEXT_LINE2, TEXT_NORMAL, pte, tmp);
04492    return 0;
04493 }

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

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

04863 {
04864    BUFFSEND;
04865    struct unistim_subchannel *sub;
04866    int i, j = 0, len;
04867    unsigned char c, cc;
04868    char tmp[256];
04869 
04870    switch (cmd) {
04871    case CLI_INIT:
04872       e->command = "unistim send packet";
04873       e->usage =
04874          "Usage: unistim send packet USTM/line@name hexa\n"
04875          "       unistim send packet USTM/1000@hans 19040004\n";
04876       return NULL;
04877 
04878    case CLI_GENERATE:
04879       return NULL;   /* no completion */
04880    }
04881    
04882    if (a->argc < 5)
04883       return CLI_SHOWUSAGE;
04884 
04885    if (strlen(a->argv[3]) < 9)
04886       return CLI_SHOWUSAGE;
04887 
04888    len = strlen(a->argv[4]);
04889    if (len % 2)
04890       return CLI_SHOWUSAGE;
04891 
04892    ast_copy_string(tmp, a->argv[3] + 5, sizeof(tmp));
04893    sub = find_subchannel_by_name(tmp);
04894    if (!sub) {
04895       ast_cli(a->fd, "Can't find '%s'\n", tmp);
04896       return CLI_SUCCESS;
04897    }
04898    if (!sub->parent->parent->session) {
04899       ast_cli(a->fd, "'%s' is not connected\n", tmp);
04900       return CLI_SUCCESS;
04901    }
04902    ast_cli(a->fd, "Sending '%s' to %s (%p)\n", a->argv[4], tmp, sub->parent->parent->session);
04903    for (i = 0; i < len; i++) {
04904       c = a->argv[4][i];
04905       if (c >= 'a')
04906          c -= 'a' - 10;
04907       else
04908          c -= '0';
04909       i++;
04910       cc = a->argv[4][i];
04911       if (cc >= 'a')
04912          cc -= 'a' - 10;
04913       else
04914          cc -= '0';
04915       tmp[j++] = (c << 4) | cc;
04916    }
04917    memcpy(buffsend + SIZE_HEADER, tmp, j);
04918    send_client(SIZE_HEADER + j, buffsend, sub->parent->parent->session);
04919    return CLI_SUCCESS;
04920 }

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

Definition at line 2050 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, sub, unistim_subchannel::subtype, and ast_channel::tech_pvt.

Referenced by HandleCallOutgoing().

02051 {
02052    struct ast_channel *chan = data;
02053    struct unistim_subchannel *sub = chan->tech_pvt;
02054    struct unistim_line *l = sub->parent;
02055    struct unistimsession *s = l->parent->session;
02056    int res;
02057 
02058    ast_verb(3, "Starting switch on '%s@%s-%d' to %s\n", l->name, l->parent->name, sub->subtype, s->device->phone_number);
02059    ast_copy_string(chan->exten, s->device->phone_number, sizeof(chan->exten));
02060    ast_copy_string(s->device->redial_number, s->device->phone_number,
02061                sizeof(s->device->redial_number));
02062    ast_setstate(chan, AST_STATE_RING);
02063    res = ast_pbx_run(chan);
02064    if (res) {
02065       ast_log(LOG_WARNING, "PBX exited non-zero\n");
02066       send_tone(s, 1000, 0);;
02067    }
02068    return NULL;
02069 }

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

Definition at line 4073 of file chan_unistim.c.

References ast_format_cap_iscompatible(), 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::format, ast_frame::frametype, unistim_subchannel::lock, LOG_WARNING, ast_channel::nativeformats, ast_channel::readformat, unistim_subchannel::rtp, sub, ast_frame::subclass, ast_channel::tech_pvt, and ast_channel::writeformat.

04074 {
04075    struct unistim_subchannel *sub = ast->tech_pvt;
04076    int res = 0;
04077 
04078    if (frame->frametype != AST_FRAME_VOICE) {
04079       if (frame->frametype == AST_FRAME_IMAGE)
04080          return 0;
04081       else {
04082          ast_log(LOG_WARNING, "Can't send %d type frames with unistim_write\n",
04083                frame->frametype);
04084          return 0;
04085       }
04086    } else {
04087       if (!(ast_format_cap_iscompatible(ast->nativeformats, &frame->subclass.format))) {
04088          char tmp[256];
04089          ast_log(LOG_WARNING,
04090                "Asked to transmit frame type %s, while native formats is %s (read/write = (%s/%s)\n",
04091                ast_getformatname(&frame->subclass.format),
04092                ast_getformatname_multiple(tmp, sizeof(tmp), ast->nativeformats),
04093                ast_getformatname(&ast->readformat),
04094                ast_getformatname(&ast->writeformat));
04095          return -1;
04096       }
04097    }
04098 
04099    if (sub) {
04100       ast_mutex_lock(&sub->lock);
04101       if (sub->rtp) {
04102          res = ast_rtp_instance_write(sub->rtp, frame);
04103       }
04104       ast_mutex_unlock(&sub->lock);
04105    }
04106 
04107    return res;
04108 }

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

Definition at line 3956 of file chan_unistim.c.

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

Referenced by do_monitor().

03957 {
03958    struct sockaddr_in addr_from = { 0, };
03959    struct unistimsession *cur = NULL;
03960    int found = 0;
03961    int tmp = 0;
03962    int dw_num_bytes_rcvd;
03963 #ifdef DUMP_PACKET
03964    int dw_num_bytes_rcvdd;
03965    char iabuf[INET_ADDRSTRLEN];
03966 #endif
03967 
03968    dw_num_bytes_rcvd =
03969       recvfrom(unistimsock, buff, SIZE_PAGE, 0, (struct sockaddr *) &addr_from,
03970              &size_addr_from);
03971    if (dw_num_bytes_rcvd == -1) {
03972       if (errno == EAGAIN)
03973          ast_log(LOG_NOTICE, "UNISTIM: Received packet with bad UDP checksum\n");
03974       else if (errno != ECONNREFUSED)
03975          ast_log(LOG_WARNING, "Recv error %d (%s)\n", errno, strerror(errno));
03976       return 1;
03977    }
03978 
03979    /* Looking in the phone list if we already have a registration for him */
03980    ast_mutex_lock(&sessionlock);
03981    cur = sessions;
03982    while (cur) {
03983       if (cur->sin.sin_addr.s_addr == addr_from.sin_addr.s_addr) {
03984          found = 1;
03985          break;
03986       }
03987       tmp++;
03988       cur = cur->next;
03989    }
03990    ast_mutex_unlock(&sessionlock);
03991 
03992 #ifdef DUMP_PACKET
03993    if (unistimdebug)
03994       ast_verb(0, "\n*** Dump %d bytes from %s - phone_table[%d] ***\n",
03995                dw_num_bytes_rcvd, ast_inet_ntoa(addr_from.sin_addr), tmp);
03996    for (dw_num_bytes_rcvdd = 0; dw_num_bytes_rcvdd < dw_num_bytes_rcvd;
03997        dw_num_bytes_rcvdd++)
03998       ast_verb(0, "%.2x ", (unsigned char) buff[dw_num_bytes_rcvdd]);
03999    ast_verb(0, "\n******************************************\n");
04000 #endif
04001 
04002    if (!found) {
04003       if (unistimdebug)
04004          ast_verb(0, "Received a packet from an unknown source\n");
04005       parsing(dw_num_bytes_rcvd, buff, NULL, (struct sockaddr_in *) &addr_from);
04006 
04007    } else
04008       parsing(dw_num_bytes_rcvd, buff, cur, (struct sockaddr_in *) &addr_from);
04009 
04010    return 1;
04011 }

static int unload_module ( void   )  [static]

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

Definition at line 4992 of file chan_unistim.c.

References len().

Referenced by build_device().

04993 {
04994    int len = strlen(src);
04995    if (!len)
04996       return;
04997    if ((len > 1) && src[0] == '\"') {
04998       /* This is a quoted string */
04999       src++;
05000       /* Don't take more than what's there */
05001       len--;
05002       if (maxlen > len - 1)
05003          maxlen = len - 1;
05004       memcpy(out, src, maxlen);
05005       ((char *) out)[maxlen] = '\0';
05006    } else
05007       memcpy(out, src, maxlen);
05008    return;
05009 }

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, and unistim_device::lines.

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

01718 {
01719    if (fwrite(&c, 1, 1, f) != 1) {
01720       display_last_error("Unable to write history log header.");
01721       return -1;
01722    }
01723    if (fwrite(line1, TEXT_LENGTH_MAX, 1, f) != 1) {
01724       display_last_error("Unable to write history entry - date.");
01725       return -1;
01726    }
01727    if (fwrite(pte->device->lst_cid, TEXT_LENGTH_MAX, 1, f) != 1) {
01728       display_last_error("Unable to write history entry - callerid.");
01729       return -1;
01730    }
01731    if (fwrite(pte->device->lst_cnm, TEXT_LENGTH_MAX, 1, f) != 1) {
01732       display_last_error("Unable to write history entry - callername.");
01733       return -1;
01734    }
01735    return 0;
01736 }

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

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

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


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

Definition at line 5776 of file chan_unistim.c.

struct sockaddr_in address_from [static]

give the IP address for the last packet received

Definition at line 229 of file chan_unistim.c.

Definition at line 5776 of file chan_unistim.c.

enum autoprovision autoprovisioning = AUTOPROVISIONING_NO [static]

Definition at line 214 of file chan_unistim.c.

unsigned char* buff [static]

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

Definition at line 679 of file chan_unistim.c.

unsigned int cos

Definition at line 221 of file chan_unistim.c.

unsigned int cos_audio

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

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

struct unistim_device * devices [static]

A device containing one or more lines.

struct tone_zone_unistim frequency[] [static]

Definition at line 317 of file chan_unistim.c.

Definition at line 108 of file chan_unistim.c.

struct ast_jb_conf global_jbconf [static]

Definition at line 204 of file chan_unistim.c.

struct io_context* io [static]

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

ast_mutex_t monlock = { PTHREAD_MUTEX_INITIALIZER , 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 246 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 512 of file chan_unistim.c.

const unsigned char packet_recv_firm_version[] [static]

Initial value:

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

Definition at line 517 of file chan_unistim.c.

const unsigned char packet_recv_hangup[] [static]

Initial value:

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

Definition at line 523 of file chan_unistim.c.

const unsigned char packet_recv_mac_addr[] [static]

Initial value:

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

Definition at line 530 of file chan_unistim.c.

const unsigned char packet_recv_pick_up[] [static]

Initial value:

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

Definition at line 521 of file chan_unistim.c.

const unsigned char packet_recv_pressed_key[] [static]

Initial value:

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

Definition at line 519 of file chan_unistim.c.

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

Definition at line 525 of file chan_unistim.c.

const unsigned char packet_recv_resume_connection_with_server[] [static]

Initial value:

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

Definition at line 528 of file chan_unistim.c.

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

Definition at line 625 of file chan_unistim.c.

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

Definition at line 626 of file chan_unistim.c.

const unsigned char packet_send_call[] [static]

Definition at line 553 of file chan_unistim.c.

const unsigned char packet_send_Contrast[] [static]

Initial value:

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

Definition at line 630 of file chan_unistim.c.

const unsigned char packet_send_date_time[] [static]

Definition at line 537 of file chan_unistim.c.

const unsigned char packet_send_date_time2[] [static]

Initial value:

 { 0x17, 0x04, 0x17, 0x3d, 0x11, 0x09, 0x02, 0x0a,  0x05,   
   0x06,  0x07,  0x08, 0x32
}

Definition at line 627 of file chan_unistim.c.

const unsigned char packet_send_date_time3[] [static]

Initial value:

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

Definition at line 533 of file chan_unistim.c.

const unsigned char packet_send_discovery_ack[] [static]

Initial value:

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

Definition at line 514 of file chan_unistim.c.

const unsigned char packet_send_end_call[] [static]

Initial value:

   { 0x16, 0x06, 0x32, 0xdf, 0x00, 0xff, 0x16, 0x05, 0x31, 0x00, 0x00, 0x19, 0x04, 0x00,
0x10, 0x19, 0x04, 0x00, 0x18, 0x16, 0x05,
   0x04, 0x00, 0x00, 0x16, 0x04, 0x37, 0x10
}

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

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

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

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

Definition at line 666 of file chan_unistim.c.

const unsigned char packet_send_no_ring[] [static]

Initial value:

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

Definition at line 544 of file chan_unistim.c.

const unsigned char packet_send_open_audio_stream_rx[] [static]

Initial value:

   { 0x16, 0x1a, 0x30, 0x00, 0xff,  0x00, 0x00, 0x01, 0x00, 0xb8, 0xb8, 0x0e,
0x0e, 0x01,  0x14, 0x50, 0x00,
   0x00,  0x14, 0x50, 0x00, 0x00,  0x0a, 0x93, 0x69, 0x05
}

Definition at line 600 of file chan_unistim.c.

const unsigned char packet_send_open_audio_stream_rx3[] [static]

Definition at line 611 of file chan_unistim.c.

const unsigned char packet_send_open_audio_stream_tx[] [static]

Initial value:

   { 0x16, 0x1a, 0x30, 0xff, 0x00, 0x00,  0x00, 0x01, 0x00, 0xb8, 0xb8, 0x0e,
0x0e, 0x01,  0x14, 0x50,
   0x00, 0x00,  0x14, 0x50, 0x00, 0x00,  0x0a, 0x93, 0x69, 0x05
}

Definition at line 605 of file chan_unistim.c.

const unsigned char packet_send_open_audio_stream_tx3[] [static]

Definition at line 618 of file chan_unistim.c.

unsigned char packet_send_ping[] [static]

Initial value:

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

Definition at line 673 of file chan_unistim.c.

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

Definition at line 668 of file chan_unistim.c.

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

Definition at line 670 of file chan_unistim.c.

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

Definition at line 669 of file chan_unistim.c.

const unsigned char packet_send_ring[] [static]

Initial value:

   { 0x16, 0x06, 0x32, 0xdf, 0x00, 0xff, 0x16, 0x05, 0x1c, 0x00, 0x00, 0x16,
   0x04, 0x1a, 0x01, 0x16, 0x05, 0x12, 0x13  , 0x18, 0x16, 0x04, 0x18,     
   0x20, 0x16, 0x04, 0x10, 0x00
}

Definition at line 576 of file chan_unistim.c.

const unsigned char packet_send_rtp_packet_size[] [static]

Initial value:

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

Definition at line 589 of file chan_unistim.c.

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

Definition at line 671 of file chan_unistim.c.

const unsigned char packet_send_s4[] [static]

Definition at line 546 of file chan_unistim.c.

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

Definition at line 637 of file chan_unistim.c.

const unsigned char packet_send_s9[] [static]

Initial value:

   { 0x16, 0x06, 0x32, 0xdf, 0x00, 0xff, 0x19, 0x04, 0x00, 0x10, 0x16, 0x05, 0x1c, 0x00,
0x00 }

Definition at line 586 of file chan_unistim.c.

const unsigned char packet_send_select_output[] [static]

Initial value:

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

Definition at line 574 of file chan_unistim.c.

const unsigned char packet_send_set_pos_cursor[] [static]

Initial value:

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

Definition at line 638 of file chan_unistim.c.

const unsigned char packet_send_StartTimer[] [static]

Initial value:

   { 0x17, 0x05, 0x0b, 0x05, 0x00, 0x17, 0x08, 0x16,  0x44, 0x75, 0x72, 0xe9,
0x65 }

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

const unsigned char packet_send_status2[] [static]

Initial value:

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

Definition at line 662 of file chan_unistim.c.

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

Definition at line 635 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 572 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 562 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 568 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 570 of file chan_unistim.c.

const unsigned char packet_send_text[] [static]

Definition at line 651 of file chan_unistim.c.

const unsigned char packet_send_title[] [static]

Initial value:

   { 0x17, 0x10, 0x19, 0x02,  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
0x20, 0x20, 0x20, 0x20   }

Definition at line 648 of file chan_unistim.c.

struct sockaddr_in public_ip = { 0, } [static]

Definition at line 227 of file chan_unistim.c.

struct { ... } qos [static]

struct ast_sched_context* sched [static]

Definition at line 226 of file chan_unistim.c.

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

Protect the session list

Definition at line 248 of file chan_unistim.c.

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

struct unistimsession * sessions [static]

unsigned int size_addr_from = sizeof(address_from) [static]

size of the sockaddr_in (in WSARecvFrom)

Definition at line 231 of file chan_unistim.c.

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

Definition at line 678 of file chan_unistim.c.

unsigned int tos

Definition at line 219 of file chan_unistim.c.

unsigned int tos_audio

Definition at line 220 of file chan_unistim.c.

struct ast_cli_entry unistim_cli[] [static]

Definition at line 4985 of file chan_unistim.c.

int unistim_keepalive [static]

Definition at line 215 of file chan_unistim.c.

int unistim_port [static]

Definition at line 213 of file chan_unistim.c.

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

Definition at line 235 of file chan_unistim.c.

Referenced by do_monitor(), and unistim_reload().

int unistim_reloading = 0 [static]

Definition at line 234 of file chan_unistim.c.

struct ast_rtp_glue unistim_rtp_glue [static]

Initial value:

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

Definition at line 5664 of file chan_unistim.c.

struct ast_channel_tech unistim_tech [static]

Definition at line 707 of file chan_unistim.c.

int unistimdebug = 0 [static]

Enable verbose output. can also be set with the CLI

Definition at line 212 of file chan_unistim.c.

int unistimsock = -1 [static]

Definition at line 216 of file chan_unistim.c.

int usecnt = 0 [static]

Definition at line 237 of file chan_unistim.c.

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

Definition at line 236 of file chan_unistim.c.

Referenced by unistim_new().


Generated on Sat Feb 11 06:34:53 2012 for Asterisk - The Open Source Telephony Project by  doxygen 1.5.6