Thu Jul 9 13:41:11 2009

Asterisk developer's documentation


chan_unistim.c File Reference

chan_unistim channel driver for Asterisk More...

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

Go to the source code of this file.

Data Structures

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

Defines

#define AST_CONFIG_MAX_PATH   255
#define BUFFSEND   unsigned char buffsend[64] = { 0x00, 0x00, 0xaa, 0xbb, 0x02, 0x01 }
#define CAPABILITY   AST_FORMAT_ALAW | AST_FORMAT_ULAW
#define DEBUG_TIMER   dummy
#define DEFAULT_CODEC   0x00
#define DEFAULTCALLERID   "Unknown"
#define DEFAULTCALLERNAME   " "
#define DEFAULTCONTEXT   "default"
#define 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 *dummy,...)
static struct unistim_subchannelfind_subchannel_by_name (const char *dest)
static void finish_bookmark (void)
static unsigned int get_tick_count (void)
static int get_to_address (int fd, struct sockaddr_in *toAddr)
static void handle_dial_page (struct unistimsession *pte)
static void HandleCallIncoming (struct unistimsession *s)
static void HandleCallOutgoing (struct unistimsession *s)
static void HandleSelectCodec (struct unistimsession *pte)
static void IgnoreCall (struct unistimsession *pte)
static void in_band_indication (struct ast_channel *ast, const struct tone_zone *tz, const char *indication)
static void init_phone_step2 (struct unistimsession *pte)
static void key_call (struct unistimsession *pte, char keycode)
static void key_dial_page (struct unistimsession *pte, char keycode)
static void key_history (struct unistimsession *pte, char keycode)
static void key_main_page (struct unistimsession *pte, char keycode)
static void key_ringing (struct unistimsession *pte, char keycode)
static void key_select_codec (struct unistimsession *pte, char keycode)
static void key_select_extension (struct unistimsession *pte, char keycode)
static void Keyfavorite (struct unistimsession *pte, char keycode)
static int load_module (void)
static char OpenHistory (struct unistimsession *pte, char way, FILE **f)
static int ParseBookmark (const char *text, struct unistim_device *d)
static void parsing (int size, unsigned char *buf, struct unistimsession *pte, struct sockaddr_in *addr_from)
static void process_request (int size, unsigned char *buf, struct unistimsession *pte)
static void rcv_mac_addr (struct unistimsession *pte, const unsigned char *buf)
static void rcv_resume_connection_with_server (struct unistimsession *pte)
static int ReformatNumber (char *number)
static void refresh_all_favorite (struct unistimsession *pte)
static int RegisterExtension (const struct unistimsession *pte)
static int reload (void)
static int reload_config (void)
static int restart_monitor (void)
static void send_blink_cursor (struct unistimsession *pte)
static void send_client (int size, const unsigned char *data, struct unistimsession *pte)
static void send_cursor_pos (struct unistimsession *pte, unsigned char pos)
static void send_date_time (struct unistimsession *pte)
static void send_date_time2 (struct unistimsession *pte)
static void send_date_time3 (struct unistimsession *pte)
static void send_end_call (struct unistimsession *pte)
static void send_favorite (unsigned char pos, unsigned char status, struct unistimsession *pte, const char *text)
static void send_led_update (struct unistimsession *pte, unsigned char led)
static void send_no_ring (struct unistimsession *pte)
static void send_ping (struct unistimsession *pte)
static void send_raw_client (int size, unsigned char *data, struct sockaddr_in *addr_to, const struct sockaddr_in *addr_ourip)
static int send_retransmit (struct unistimsession *pte)
static void send_ring (struct unistimsession *pte, char volume, char style)
static void send_select_output (struct unistimsession *pte, unsigned char output, unsigned char volume, unsigned char mute)
static void send_start_timer (struct unistimsession *pte)
static void send_stop_timer (struct unistimsession *pte)
static void send_text (unsigned char pos, unsigned char inverse, struct unistimsession *pte, const char *text)
static void send_text_status (struct unistimsession *pte, const char *text)
static void send_texttitle (struct unistimsession *pte, const char *text)
static void send_tone (struct unistimsession *pte, uint16_t tone1, uint16_t tone2)
static void SendDialTone (struct unistimsession *pte)
static void Sendicon (unsigned char pos, unsigned char status, struct unistimsession *pte)
static void set_ping_timer (struct unistimsession *pte)
static void show_entry_history (struct unistimsession *pte, FILE **f)
static void show_history (struct unistimsession *pte, char way)
static void show_main_page (struct unistimsession *pte)
static void ShowExtensionPage (struct unistimsession *pte)
static void start_rtp (struct unistim_subchannel *sub)
static void swap_subs (struct unistim_line *p, int a, int b)
static void TransferCallStep1 (struct unistimsession *pte)
static int unalloc_sub (struct unistim_line *p, int x)
static int unistim_answer (struct ast_channel *ast)
static int unistim_call (struct ast_channel *ast, char *dest, int timeout)
static char * unistim_do_debug (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
static int unistim_do_senddigit (struct unistimsession *pte, char digit)
static int unistim_fixup (struct ast_channel *oldchan, struct ast_channel *newchan)
static enum ast_rtp_get_result unistim_get_rtp_peer (struct ast_channel *chan, struct ast_rtp **rtp)
static enum ast_rtp_get_result unistim_get_vrtp_peer (struct ast_channel *chan, struct ast_rtp **rtp)
static int unistim_hangup (struct ast_channel *ast)
static int unistim_indicate (struct ast_channel *ast, int ind, const void *data, size_t datalen)
static char * unistim_info (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
static struct ast_channelunistim_new (struct unistim_subchannel *sub, int state)
static struct ast_frameunistim_read (struct ast_channel *ast)
static int unistim_register (struct unistimsession *s)
static char * unistim_reload (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
 --- unistim_reload: Force reload of module from cli --- Runs in the asterisk main thread, so don't do anything useful but setting a flag and waiting for do_monitor to do the job in our thread
static struct ast_channelunistim_request (const char *type, int format, void *data, int *cause)
static struct ast_frameunistim_rtp_read (const struct ast_channel *ast, const struct unistim_subchannel *sub)
static int unistim_send_mwi_to_peer (struct unistimsession *s, unsigned int tick)
static int unistim_senddigit_begin (struct ast_channel *ast, char digit)
static int unistim_senddigit_end (struct ast_channel *ast, char digit, unsigned int duration)
static int unistim_sendtext (struct ast_channel *ast, const char *text)
static int unistim_set_rtp_peer (struct ast_channel *chan, struct ast_rtp *rtp, struct ast_rtp *vrtp, struct ast_rtp *trtp, int codecs, int nat_active)
static char * unistim_sp (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
static void * unistim_ss (void *data)
static int unistim_write (struct ast_channel *ast, struct ast_frame *frame)
static int unistimsock_read (int *id, int fd, short events, void *ignore)
static int unload_module (void)
static void unquote (char *out, const char *src, int maxlen)
static int UnregisterExtension (const struct unistimsession *pte)
static int write_entry_history (struct unistimsession *pte, FILE *f, char c, char *line1)
static int write_history (struct unistimsession *pte, char way, char ismissed)

Variables

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


Detailed Description

chan_unistim channel driver for Asterisk

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

Definition in file chan_unistim.c.


Define Documentation

#define AST_CONFIG_MAX_PATH   255

Definition at line 97 of file chan_unistim.c.

Referenced by OpenHistory(), and write_history().

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

Definition at line 661 of file chan_unistim.c.

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

#define CAPABILITY   AST_FORMAT_ALAW | AST_FORMAT_ULAW

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

Definition at line 74 of file chan_unistim.c.

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

#define DEBUG_TIMER   dummy

Definition at line 202 of file chan_unistim.c.

Referenced by do_monitor(), and set_ping_timer().

#define DEFAULT_CODEC   0x00

Not used

Definition at line 94 of file chan_unistim.c.

Referenced by key_select_extension(), and unistim_register().

#define DEFAULTCALLERID   "Unknown"

Definition at line 77 of file chan_unistim.c.

Referenced by unistim_call().

#define DEFAULTCALLERNAME   " "

Definition at line 78 of file chan_unistim.c.

Referenced by unistim_call().

#define DEFAULTCONTEXT   "default"

Definition at line 76 of file chan_unistim.c.

Referenced by build_device().

#define DEVICE_NAME_LEN   16

Definition at line 96 of file chan_unistim.c.

#define FAV_BLINK_FAST   0x20

Definition at line 178 of file chan_unistim.c.

Referenced by unistim_call().

#define FAV_BLINK_SLOW   0x40

Definition at line 179 of file chan_unistim.c.

Referenced by show_main_page().

#define FAV_ICON_BOX   0x3F

Definition at line 176 of file chan_unistim.c.

#define FAV_ICON_CALL_CENTER   0x34

Definition at line 165 of file chan_unistim.c.

Referenced by show_main_page().

#define FAV_ICON_CITY   0x31

Definition at line 162 of file chan_unistim.c.

#define FAV_ICON_COMPUTER   0x38

Definition at line 169 of file chan_unistim.c.

#define FAV_ICON_FAX   0x35

Definition at line 166 of file chan_unistim.c.

#define FAV_ICON_FORWARD   0x39

Definition at line 170 of file chan_unistim.c.

#define FAV_ICON_HEADPHONES   0x2E

Definition at line 159 of file chan_unistim.c.

Referenced by send_select_output().

#define FAV_ICON_HEADPHONES_ONHOLD   0x2F

Definition at line 160 of file chan_unistim.c.

Referenced by refresh_all_favorite(), and send_select_output().

#define FAV_ICON_HOME   0x30

Definition at line 161 of file chan_unistim.c.

#define FAV_ICON_INBOX   0x3C

Definition at line 173 of file chan_unistim.c.

#define FAV_ICON_LOCKED   0x3A

Definition at line 171 of file chan_unistim.c.

#define FAV_ICON_MAILBOX   0x36

Definition at line 167 of file chan_unistim.c.

#define FAV_ICON_MEETING   0x3E

Definition at line 175 of file chan_unistim.c.

#define FAV_ICON_NONE   0x00

Definition at line 144 of file chan_unistim.c.

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

#define FAV_ICON_OFFHOOK_BLACK   0x24

Definition at line 149 of file chan_unistim.c.

Referenced by send_select_output().

#define FAV_ICON_OFFHOOK_WHITE   0x25

Definition at line 150 of file chan_unistim.c.

#define FAV_ICON_ONHOLD_BLACK   0x26

Definition at line 151 of file chan_unistim.c.

Referenced by send_select_output().

#define FAV_ICON_ONHOLD_WHITE   0x27

Definition at line 152 of file chan_unistim.c.

#define FAV_ICON_ONHOOK_BLACK   0x20

Definition at line 145 of file chan_unistim.c.

Referenced by build_device(), and show_main_page().

#define FAV_ICON_ONHOOK_WHITE   0x21

Definition at line 146 of file chan_unistim.c.

#define FAV_ICON_OUTBOX   0x3D

Definition at line 174 of file chan_unistim.c.

#define FAV_ICON_PAGER   0x33

Definition at line 164 of file chan_unistim.c.

#define FAV_ICON_PHONE_BLACK   0x2A

Definition at line 155 of file chan_unistim.c.

Referenced by handle_dial_page().

#define FAV_ICON_PHONE_WHITE   0x2B

Definition at line 156 of file chan_unistim.c.

#define FAV_ICON_REFLECT   0x37

Definition at line 168 of file chan_unistim.c.

Referenced by show_main_page().

#define FAV_ICON_SHARP   0x32

Definition at line 163 of file chan_unistim.c.

Referenced by ParseBookmark().

#define FAV_ICON_SPEAKER_OFFHOOK_BLACK   0x28

Definition at line 153 of file chan_unistim.c.

Referenced by send_select_output().

#define FAV_ICON_SPEAKER_OFFHOOK_WHITE   0x29

Definition at line 154 of file chan_unistim.c.

#define FAV_ICON_SPEAKER_ONHOLD_BLACK   0x2C

Definition at line 157 of file chan_unistim.c.

Referenced by send_select_output().

#define FAV_ICON_SPEAKER_ONHOLD_WHITE   0x2D

Definition at line 158 of file chan_unistim.c.

#define FAV_ICON_SPEAKER_ONHOOK_BLACK   0x22

Definition at line 147 of file chan_unistim.c.

Referenced by send_select_output(), and unistim_call().

#define FAV_ICON_SPEAKER_ONHOOK_WHITE   0x23

Definition at line 148 of file chan_unistim.c.

#define FAV_ICON_TRASH   0x3B

Definition at line 172 of file chan_unistim.c.

#define FAV_MAX_LENGTH   0x0A

Definition at line 181 of file chan_unistim.c.

Referenced by send_favorite().

#define IDLE_WAIT   1000

Nb of milliseconds waited when no events are scheduled

Definition at line 88 of file chan_unistim.c.

Referenced by do_monitor().

#define MAX_BUF_NUMBER   50

Number of slots for the transmit queue

Definition at line 84 of file chan_unistim.c.

Referenced by create_client(), and send_client().

#define MAX_BUF_SIZE   64

Size of the transmit buffer

Definition at line 82 of file chan_unistim.c.

#define MAX_ENTRY_LOG   30

Definition at line 98 of file chan_unistim.c.

Referenced by OpenHistory(), and write_history().

#define MAX_SUBS   2

Definition at line 102 of file chan_unistim.c.

#define MUTE_OFF   0x00

Definition at line 130 of file chan_unistim.c.

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

#define MUTE_ON   0xFF

Definition at line 131 of file chan_unistim.c.

Referenced by key_call(), and send_select_output().

#define MUTE_ON_DISCRET   0xCE

Definition at line 132 of file chan_unistim.c.

Referenced by send_select_output(), and show_main_page().

#define NB_MAX_RETRANSMIT   8

Try x times before removing the phone

Definition at line 86 of file chan_unistim.c.

Referenced by reload_config(), and send_retransmit().

#define OUTPUT_HANDSET   0xC0

Definition at line 121 of file chan_unistim.c.

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

#define OUTPUT_HEADPHONE   0xC1

Definition at line 122 of file chan_unistim.c.

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

#define OUTPUT_SPEAKER   0xC2

Definition at line 123 of file chan_unistim.c.

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

#define RETRANSMIT_TIMER   2000

Wait x milliseconds before resending a packet

Definition at line 90 of file chan_unistim.c.

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

#define SELECTCODEC_MAX_LENGTH   2

Definition at line 2763 of file chan_unistim.c.

Referenced by key_select_codec().

#define SELECTCODEC_MSG   "Codec number : .."

Definition at line 2764 of file chan_unistim.c.

Referenced by HandleSelectCodec(), and key_select_codec().

#define SELECTCODEC_START_ENTRY_POS   15

Definition at line 2762 of file chan_unistim.c.

Referenced by HandleSelectCodec(), and key_select_codec().

#define SELECTEXTENSION_MAX_LENGTH   10

Definition at line 2840 of file chan_unistim.c.

Referenced by key_select_extension().

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

Definition at line 2841 of file chan_unistim.c.

Referenced by key_select_extension(), and ShowExtensionPage().

#define SELECTEXTENSION_START_ENTRY_POS   0

Definition at line 2839 of file chan_unistim.c.

Referenced by key_select_extension(), and ShowExtensionPage().

#define SIZE_HEADER   6

Definition at line 134 of file chan_unistim.c.

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

#define SIZE_MAC_ADDR   17

Definition at line 135 of file chan_unistim.c.

#define SIZE_PAGE   4096

Definition at line 95 of file chan_unistim.c.

Referenced by load_module(), and unistimsock_read().

#define STATUS_LENGTH_MAX   28

Definition at line 142 of file chan_unistim.c.

Referenced by send_text_status(), and show_entry_history().

#define SUB_REAL   0

Definition at line 100 of file chan_unistim.c.

#define SUB_THREEWAY   1

Definition at line 101 of file chan_unistim.c.

#define TEXT_INVERSE   0x25

Definition at line 141 of file chan_unistim.c.

Referenced by HandleSelectCodec(), and key_select_codec().

#define TEXT_LENGTH_MAX   24

Definition at line 136 of file chan_unistim.c.

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

#define TEXT_LINE0   0x00

Definition at line 137 of file chan_unistim.c.

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

#define TEXT_LINE1   0x20

Definition at line 138 of file chan_unistim.c.

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

#define TEXT_LINE2   0x40

Definition at line 139 of file chan_unistim.c.

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

#define TEXT_NORMAL   0x05

Definition at line 140 of file chan_unistim.c.

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

#define TIMER_MWI   10000

How often the mailbox is checked for new messages

Definition at line 92 of file chan_unistim.c.

Referenced by unistim_send_mwi_to_peer().

#define USTM_LOG_DIR   "unistimHistory"

Definition at line 79 of file chan_unistim.c.

Referenced by OpenHistory(), and write_history().

#define VOLUME_INSANELY_LOUD   0x07

Definition at line 128 of file chan_unistim.c.

#define VOLUME_LOW   0x01

Definition at line 125 of file chan_unistim.c.

Referenced by build_device(), and send_select_output().

#define VOLUME_LOW_SPEAKER   0x03

Definition at line 126 of file chan_unistim.c.

Referenced by send_select_output().

#define VOLUME_NORMAL   0x02

Definition at line 127 of file chan_unistim.c.


Enumeration Type Documentation

enum autoprov_extn

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

Definition at line 111 of file chan_unistim.c.

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

enum autoprovision

Enumerator:
AUTOPROVISIONING_NO 
AUTOPROVISIONING_YES 
AUTOPROVISIONING_DB 
AUTOPROVISIONING_TN 

Definition at line 104 of file chan_unistim.c.

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

enum handset_state

Enumerator:
STATE_ONHOOK 
STATE_OFFHOOK 

Definition at line 253 of file chan_unistim.c.

00253                    {
00254    STATE_ONHOOK,
00255    STATE_OFFHOOK,
00256 };

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

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

enum phone_state

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

Definition at line 240 of file chan_unistim.c.

00240                  {
00241    STATE_INIT,
00242    STATE_AUTHDENY,
00243    STATE_MAINPAGE,
00244    STATE_EXTENSION,
00245    STATE_DIALPAGE,
00246    STATE_RINGING,
00247    STATE_CALL,
00248    STATE_SELECTCODEC,
00249    STATE_CLEANING,
00250    STATE_HISTORY
00251 };


Function Documentation

static void __reg_module ( void   )  [static]

Definition at line 5646 of file chan_unistim.c.

static void __unreg_module ( void   )  [static]

Definition at line 5646 of file chan_unistim.c.

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

Definition at line 1472 of file chan_unistim.c.

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

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

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

Definition at line 1876 of file chan_unistim.c.

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

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

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

Definition at line 4991 of file chan_unistim.c.

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

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

static void cancel_dial ( struct unistimsession pte  )  [static]

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

01840 {
01841    send_no_ring(pte);
01842    pte->device->missed_call++;
01843    write_history(pte, 'i', 1);
01844    show_main_page(pte);
01845    return;
01846 }

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

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

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

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

Definition at line 1056 of file chan_unistim.c.

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

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

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

Definition at line 3612 of file chan_unistim.c.

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

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

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

static void check_send_queue ( struct unistimsession pte  )  [static]

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

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

static void close_call ( struct unistimsession pte  )  [static]

Definition at line 1961 of file chan_unistim.c.

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

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

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

static void close_client ( struct unistimsession s  )  [static]

Definition at line 1100 of file chan_unistim.c.

References ast_free, ast_log(), ast_mutex_destroy(), ast_mutex_lock(), ast_mutex_unlock(), ast_queue_hangup(), ast_strlen_zero(), ast_verb, change_favorite_icon(), unistimsession::device, FAV_ICON_NONE, LOG_WARNING, unistimsession::next, unistim_subchannel::owner, s, unistim_device::session, sessionlock, STATE_CLEANING, SUB_REAL, unistimdebug, and UnregisterExtension().

Referenced by parsing(), and send_retransmit().

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

static char* control2str ( int  ind  )  [static]

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

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

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

Definition at line 856 of file chan_unistim.c.

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

Referenced by parsing().

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

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

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

00712 {
00713    time_t cur_time;
00714    
00715    time(&cur_time);
00716 
00717    /* Display the error message */
00718    ast_log(LOG_WARNING, "%s %s : (%u) %s\n", ctime(&cur_time), sz_msg, errno,
00719          strerror(errno));
00720 }

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

Definition at line 4502 of file chan_unistim.c.

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

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

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

Definition at line 183 of file chan_unistim.c.

Referenced by app_exec(), ast_fdisset(), check_user_full(), custom_log(), get_sdp(), handle_cli_misdn_send_facility(), manager_log(), osp_finish(), osp_lookup(), osp_validate_token(), packsms16(), packsms7(), packsms8(), parse_args(), reload_config(), sqlite3_log(), and transmit_request_with_auth().

00184 {
00185    return;
00186 }

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

Definition at line 4135 of file chan_unistim.c.

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

Referenced by unistim_request(), and unistim_sp().

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

static void finish_bookmark ( void   )  [static]

Definition at line 4966 of file chan_unistim.c.

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

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

static unsigned int get_tick_count ( void   )  [static]

Definition at line 722 of file chan_unistim.c.

References ast_tvnow().

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

00723 {
00724    struct timeval tv = ast_tvnow();
00725 
00726    return (tv.tv_sec * 1000) + (tv.tv_usec / 1000);
00727 }

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

Definition at line 823 of file chan_unistim.c.

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

Referenced by create_client().

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

static void handle_dial_page ( struct unistimsession pte  )  [static]

Definition at line 2249 of file chan_unistim.c.

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

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

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

static void HandleCallIncoming ( struct unistimsession s  )  [static]

Definition at line 2433 of file chan_unistim.c.

References AST_CONTROL_ANSWER, ast_log(), ast_queue_control(), ast_verb, LOG_NOTICE, LOG_WARNING, MUTE_OFF, unistim_line::name, OUTPUT_HANDSET, OUTPUT_SPEAKER, unistim_subchannel::owner, unistim_subchannel::parent, unistim_subchannel::rtp, s, send_no_ring(), send_select_output(), send_start_timer(), send_text(), send_text_status(), start_rtp(), STATE_CALL, STATE_ONHOOK, SUB_REAL, TEXT_LINE2, TEXT_NORMAL, unistimdebug, and write_history().

Referenced by key_ringing(), and process_request().

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

static void HandleCallOutgoing ( struct unistimsession s  )  [static]

Definition at line 2344 of file chan_unistim.c.

References alloc_sub(), ast_channel_stop_silence_generator(), ast_debug, ast_hangup(), ast_log(), ast_pthread_create, ast_queue_hangup(), AST_STATE_DOWN, ast_verb, display_last_error(), LOG_NOTICE, LOG_WARNING, MUTE_OFF, ast_channel::name, unistim_line::name, unistim_subchannel::owner, unistim_subchannel::parent, unistim_subchannel::rtp, s, send_select_output(), send_text(), send_text_status(), send_tone(), start_rtp(), STATE_CALL, SUB_REAL, SUB_THREEWAY, unistim_line::subs, swap_subs(), TEXT_LINE0, TEXT_LINE1, TEXT_LINE2, TEXT_NORMAL, unistim_new(), unistim_ss(), and unistimdebug.

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

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

static void HandleSelectCodec ( struct unistimsession pte  )  [static]

Definition at line 2765 of file chan_unistim.c.

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

Referenced by key_main_page().

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

static void IgnoreCall ( struct unistimsession pte  )  [static]

Definition at line 1994 of file chan_unistim.c.

References send_no_ring().

Referenced by key_ringing().

01995 {
01996    send_no_ring(pte);
01997    return;
01998 }

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

Definition at line 4053 of file chan_unistim.c.

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

Referenced by unistim_indicate().

04055 {
04056    const struct tone_zone_sound *ts = NULL;
04057 
04058    ts = ast_get_indication_tone(tz, indication);
04059 
04060    if (ts && ts->data[0])
04061       ast_playtones_start(ast, 0, ts->data, 1);
04062    else
04063       ast_log(LOG_WARNING, "Unable to get indication tone for %s\n", indication);
04064 }

static void init_phone_step2 ( struct unistimsession pte  )  [static]

Definition at line 3277 of file chan_unistim.c.

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

Referenced by process_request().

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

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

Definition at line 2537 of file chan_unistim.c.

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

Referenced by process_request().

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

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

Definition at line 2645 of file chan_unistim.c.

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

Referenced by key_main_page(), and process_request().

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

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

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

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

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

Definition at line 3115 of file chan_unistim.c.

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

Referenced by key_history(), and process_request().

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

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

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

02609 {
02610    if (keycode == KEY_FAV0 + pte->device->softkeylinepos) {
02611       HandleCallIncoming(pte);
02612       return;
02613    }
02614    switch (keycode) {
02615    case KEY_HANGUP:
02616    case KEY_FUNC4:
02617       IgnoreCall(pte);
02618       break;
02619    case KEY_FUNC1:
02620       HandleCallIncoming(pte);
02621       break;
02622    }
02623    return;
02624 }

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

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

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

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

Definition at line 2856 of file chan_unistim.c.

References ast_copy_string(), ast_mutex_lock(), ast_mutex_unlock(), autoprovisioning, AUTOPROVISIONING_TN, unistimsession::buff_entry, unistim_device::codec_number, DEFAULT_CODEC, unistimsession::device, devicelock, devices, 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().

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

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

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

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

int load_module ( void   )  [static]

Definition at line 5556 of file chan_unistim.c.

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

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

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

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

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

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

Definition at line 4885 of file chan_unistim.c.

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

Referenced by build_device().

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

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

Definition at line 3457 of file chan_unistim.c.

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

Referenced by unistimsock_read().

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

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

Definition at line 3338 of file chan_unistim.c.

References ast_debug, ast_inet_ntoa(), ast_log(), ast_verb, close_call(), unistimsession::device, handle_dial_page(), HandleCallIncoming(), init_phone_step2(), key_call(), key_dial_page(), key_history(), key_main_page(), key_ringing(), key_select_codec(), key_select_extension(), LOG_WARNING, MUTE_OFF, unistim_device::output, OUTPUT_HANDSET, OUTPUT_HEADPHONE, packet_recv_firm_version, packet_recv_hangup, packet_recv_mac_addr, packet_recv_pick_up, packet_recv_pressed_key, packet_recv_r2, packet_recv_resume_connection_with_server, rcv_mac_addr(), rcv_resume_connection_with_server(), unistim_device::receiver_state, send_select_output(), show_main_page(), unistimsession::sin, SIZE_HEADER, unistimsession::state, STATE_AUTHDENY, STATE_CALL, STATE_DIALPAGE, STATE_EXTENSION, STATE_HISTORY, STATE_INIT, STATE_MAINPAGE, STATE_OFFHOOK, STATE_ONHOOK, STATE_RINGING, STATE_SELECTCODEC, SUB_REAL, and unistimdebug.

Referenced by parsing().

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

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

Definition at line 1503 of file chan_unistim.c.

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

Referenced by process_request().

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

static void rcv_resume_connection_with_server ( struct unistimsession pte  )  [static]

Definition at line 1432 of file chan_unistim.c.

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

Referenced by process_request().

01433 {
01434    BUFFSEND;
01435    if (unistimdebug) {
01436       ast_verb(0, "ResumeConnectionWithServer received\n");
01437       ast_verb(0, "Sending packet_send_query_mac_address\n");
01438    }
01439    memcpy(buffsend + SIZE_HEADER, packet_send_query_mac_address,
01440          sizeof(packet_send_query_mac_address));
01441    send_client(SIZE_HEADER + sizeof(packet_send_query_mac_address), buffsend, pte);
01442    return;
01443 }

static int ReformatNumber ( char *  number  )  [static]

Definition at line 2954 of file chan_unistim.c.

Referenced by key_history(), and show_entry_history().

02955 {
02956    int pos = 0, i = 0, size = strlen(number);
02957 
02958    for (; i < size; i++) {
02959       if ((number[i] >= '0') && (number[i] <= '9')) {
02960          if (i == pos) {
02961             pos++;
02962             continue;
02963          }
02964          number[pos] = number[i];
02965          pos++;
02966       }
02967    }
02968    number[pos] = 0;
02969    return pos;
02970 }

static void refresh_all_favorite ( struct unistimsession pte  )  [static]

Definition at line 1036 of file chan_unistim.c.

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

Referenced by init_phone_step2(), and key_select_extension().

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

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

Definition at line 1079 of file chan_unistim.c.

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

Referenced by key_select_extension(), and rcv_mac_addr().

01080 {
01081    if (unistimdebug)
01082       ast_verb(0, "Trying to register extension '%s' into context '%s' to %s\n",
01083                pte->device->extension_number, pte->device->lines->context,
01084                pte->device->lines->fullname);
01085    return ast_add_extension(pte->device->lines->context, 0,
01086                       pte->device->extension_number, 1, NULL, NULL, "Dial",
01087                       pte->device->lines->fullname, 0, "Unistim");
01088 }

static int reload ( void   )  [static]

reload: Part of Asterisk module interface ---

static int reload_config ( void   )  [static]

Definition at line 5278 of file chan_unistim.c.

References ahp, ast_category_browse(), ast_config_destroy(), ast_config_load, ast_free, ast_gethostbyname(), ast_jb_read_conf(), ast_log(), ast_mutex_destroy(), ast_mutex_lock(), ast_mutex_unlock(), ast_str2cos(), ast_str2tos(), ast_strlen_zero(), ast_variable_browse(), ast_verb, autoprovisioning, AUTOPROVISIONING_DB, AUTOPROVISIONING_NO, AUTOPROVISIONING_TN, AUTOPROVISIONING_YES, build_device(), config, cos, cos_audio, default_jbconf, devicelock, devices, global_jbconf, hp, ast_variable::lineno, unistim_device::lines, unistimsession::lock, unistim_line::lock, unistim_subchannel::lock, LOG_ERROR, LOG_WARNING, MAX_SUBS, unistim_device::name, ast_variable::name, NB_MAX_RETRANSMIT, unistimsession::next, unistim_device::next, ast_variable::next, unistim_subchannel::owner, packet_send_ping, public_ip, RETRANSMIT_TIMER, s, unistim_device::session, unistim_line::subs, unistim_device::to_delete, tos, tos_audio, unistim_keepalive, unistim_port, unistimdebug, and ast_variable::value.

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

static int restart_monitor ( void   )  [static]

Definition at line 4578 of file chan_unistim.c.

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

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

static void send_blink_cursor ( struct unistimsession pte  )  [static]

Definition at line 1409 of file chan_unistim.c.

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

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

01410 {
01411    BUFFSEND;
01412    if (unistimdebug)
01413       ast_verb(0, "Sending set blink\n");
01414    memcpy(buffsend + SIZE_HEADER, packet_send_blink_cursor, sizeof(packet_send_blink_cursor));
01415    send_client(SIZE_HEADER + sizeof(packet_send_blink_cursor), buffsend, pte);
01416    return;
01417 }

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

Definition at line 782 of file chan_unistim.c.

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

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

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

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

Definition at line 1420 of file chan_unistim.c.

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

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

01421 {
01422    BUFFSEND;
01423    if (unistimdebug)
01424       ast_verb(0, "Sending set cursor position\n");
01425    memcpy(buffsend + SIZE_HEADER, packet_send_set_pos_cursor,
01426          sizeof(packet_send_set_pos_cursor));
01427    buffsend[11] = pos;
01428    send_client(SIZE_HEADER + sizeof(packet_send_set_pos_cursor), buffsend, pte);
01429    return;
01430 }

static void send_date_time ( struct unistimsession pte  )  [static]

Definition at line 1354 of file chan_unistim.c.

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

Referenced by rcv_mac_addr().

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

static void send_date_time2 ( struct unistimsession pte  )  [static]

Definition at line 1371 of file chan_unistim.c.

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

Referenced by init_phone_step2().

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

static void send_date_time3 ( struct unistimsession pte  )  [static]

Definition at line 1392 of file chan_unistim.c.

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

Referenced by init_phone_step2().

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

static void send_end_call ( struct unistimsession pte  )  [static]

Definition at line 891 of file chan_unistim.c.

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

Referenced by unistim_hangup().

00892 {
00893    BUFFSEND;
00894    if (unistimdebug)
00895       ast_verb(0, "Sending end call\n");
00896    memcpy(buffsend + SIZE_HEADER, packet_send_end_call, sizeof(packet_send_end_call));
00897    send_client(SIZE_HEADER + sizeof(packet_send_end_call), buffsend, pte);
00898 }

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

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

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

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

Definition at line 1245 of file chan_unistim.c.

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

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

01246 {
01247    BUFFSEND;
01248    if (unistimdebug)
01249       ast_verb(0, "Sending led_update (%x)\n", led);
01250    memcpy(buffsend + SIZE_HEADER, packet_send_led_update, sizeof(packet_send_led_update));
01251    buffsend[9] = led;
01252    send_client(SIZE_HEADER + sizeof(packet_send_led_update), buffsend, pte);
01253 }

static void send_no_ring ( struct unistimsession pte  )  [static]

Definition at line 1330 of file chan_unistim.c.

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

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

01331 {
01332    BUFFSEND;
01333    if (unistimdebug)
01334       ast_verb(0, "Sending no ring packet\n");
01335    memcpy(buffsend + SIZE_HEADER, packet_send_no_ring, sizeof(packet_send_no_ring));
01336    send_client(SIZE_HEADER + sizeof(packet_send_no_ring), buffsend, pte);
01337 }

static void send_ping ( struct unistimsession pte  )  [static]

Definition at line 813 of file chan_unistim.c.

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

00814 {
00815    BUFFSEND;
00816    if (unistimdebug)
00817       ast_verb(6, "Sending ping\n");
00818    pte->tick_next_ping = get_tick_count() + unistim_keepalive;
00819    memcpy(buffsend + SIZE_HEADER, packet_send_ping, sizeof(packet_send_ping));
00820    send_client(SIZE_HEADER + sizeof(packet_send_ping), buffsend, pte);
00821 }

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

Definition at line 730 of file chan_unistim.c.

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

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

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

static int send_retransmit ( struct unistimsession pte  )  [static]

Definition at line 1150 of file chan_unistim.c.

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

Referenced by do_monitor(), and parsing().

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

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

Definition at line 1319 of file chan_unistim.c.

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

Referenced by unistim_call().

01320 {
01321    BUFFSEND;
01322    if (unistimdebug)
01323       ast_verb(0, "Sending ring packet\n");
01324    memcpy(buffsend + SIZE_HEADER, packet_send_ring, sizeof(packet_send_ring));
01325    buffsend[24] = style + 0x10;
01326    buffsend[29] = volume * 0x10;
01327    send_client(SIZE_HEADER + sizeof(packet_send_ring), buffsend, pte);
01328 }

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

Definition at line 1259 of file chan_unistim.c.

References ast_log(), ast_verb, BUFFSEND, change_favorite_icon(), FAV_ICON_HEADPHONES, FAV_ICON_HEADPHONES_ONHOLD, FAV_ICON_OFFHOOK_BLACK, FAV_ICON_ONHOLD_BLACK, FAV_ICON_SPEAKER_OFFHOOK_BLACK, FAV_ICON_SPEAKER_ONHOLD_BLACK, FAV_ICON_SPEAKER_ONHOOK_BLACK, LOG_WARNING, MUTE_OFF, MUTE_ON, MUTE_ON_DISCRET, OUTPUT_HANDSET, OUTPUT_HEADPHONE, OUTPUT_SPEAKER, packet_send_select_output, send_client(), send_led_update(), SIZE_HEADER, STATE_OFFHOOK, unistimdebug, VOLUME_LOW, and VOLUME_LOW_SPEAKER.

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

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

static void send_start_timer ( struct unistimsession pte  )  [static]

Definition at line 934 of file chan_unistim.c.

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

Referenced by HandleCallIncoming(), and unistim_answer().

00935 {
00936    BUFFSEND;
00937    if (unistimdebug)
00938       ast_verb(0, "Sending start timer\n");
00939    memcpy(buffsend + SIZE_HEADER, packet_send_StartTimer, sizeof(packet_send_StartTimer));
00940    send_client(SIZE_HEADER + sizeof(packet_send_StartTimer), buffsend, pte);
00941 }

static void send_stop_timer ( struct unistimsession pte  )  [static]

Definition at line 943 of file chan_unistim.c.

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

Referenced by close_call().

00944 {
00945    BUFFSEND;
00946    if (unistimdebug)
00947       ast_verb(0, "Sending stop timer\n");
00948    memcpy(buffsend + SIZE_HEADER, packet_send_stop_timer, sizeof(packet_send_stop_timer));
00949    send_client(SIZE_HEADER + sizeof(packet_send_stop_timer), buffsend, pte);
00950 }

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

Definition at line 1190 of file chan_unistim.c.

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

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

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

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

Definition at line 1207 of file chan_unistim.c.

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

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

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

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

Definition at line 1339 of file chan_unistim.c.

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

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

01340 {
01341    BUFFSEND;
01342    int i;
01343    if (unistimdebug)
01344       ast_verb(0, "Sending title text\n");
01345    memcpy(buffsend + SIZE_HEADER, packet_send_title, sizeof(packet_send_title));
01346    i = strlen(text);
01347    if (i > 12)
01348       i = 12;
01349    memcpy(buffsend + 10, text, i);
01350    send_client(SIZE_HEADER + sizeof(packet_send_title), buffsend, pte);
01351 
01352 }

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

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

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

static void SendDialTone ( struct unistimsession pte  )  [static]

Definition at line 2220 of file chan_unistim.c.

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

Referenced by handle_dial_page().

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

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

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

00953 {
00954    BUFFSEND;
00955    if (unistimdebug)
00956       ast_verb(0, "Sending icon pos %d with status 0x%.2x\n", pos, status);
00957    memcpy(buffsend + SIZE_HEADER, packet_send_icon, sizeof(packet_send_icon));
00958    buffsend[9] = pos;
00959    buffsend[10] = status;
00960    send_client(SIZE_HEADER + sizeof(packet_send_icon), buffsend, pte);
00961 }

static void set_ping_timer ( struct unistimsession pte  )  [static]

Definition at line 900 of file chan_unistim.c.

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

Referenced by check_send_queue().

00901 {
00902    unsigned int tick = 0;  /* XXX what is this for, anyways */
00903 
00904    pte->timeout = pte->tick_next_ping;
00905    DEBUG_TIMER("tick = %u next ping at %u tick\n", tick, pte->timeout);
00906    return;
00907 }

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

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

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

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

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

03048 {
03049    FILE *f;
03050    char count;
03051 
03052    if (!pte->device)
03053       return;
03054    if (!pte->device->callhistory)
03055       return;
03056    count = OpenHistory(pte, way, &f);
03057    if (!count)
03058       return;
03059    pte->buff_entry[0] = way;
03060    pte->buff_entry[1] = count;
03061    pte->buff_entry[2] = 1;
03062    show_entry_history(pte, &f);
03063    pte->state = STATE_HISTORY;
03064 }

static void show_main_page ( struct unistimsession pte  )  [static]

Definition at line 3066 of file chan_unistim.c.

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

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

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

static void ShowExtensionPage ( struct unistimsession pte  )  [static]

Definition at line 2842 of file chan_unistim.c.

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

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

02843 {
02844    pte->state = STATE_EXTENSION;
02845 
02846    send_text(TEXT_LINE0, TEXT_NORMAL, pte, "Please enter a Terminal");
02847    send_text(TEXT_LINE1, TEXT_NORMAL, pte, "Number (TN) :");
02848    send_text(TEXT_LINE2, TEXT_NORMAL, pte, SELECTEXTENSION_MSG);
02849    send_blink_cursor(pte);
02850    send_cursor_pos(pte, TEXT_LINE2 + SELECTEXTENSION_START_ENTRY_POS);
02851    send_text_status(pte, "Enter  BackSpcErase");
02852    pte->size_buff_entry = 0;
02853    return;
02854 }

static void start_rtp ( struct unistim_subchannel sub  )  [static]

Definition at line 2021 of file chan_unistim.c.

References ast_best_codec(), AST_FORMAT_ALAW, AST_FORMAT_G723_1, AST_FORMAT_G729A, AST_FORMAT_ULAW, ast_getformatname(), ast_inet_ntoa(), ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_rtcp_fd(), ast_rtp_fd(), ast_rtp_get_us(), ast_rtp_lookup_code(), ast_rtp_new_with_bindaddr(), ast_rtp_set_peer(), ast_rtp_setnat(), ast_rtp_setqos(), ast_verb, BUFFSEND, cos_audio, errno, ast_channel::fds, io, unistim_subchannel::lock, LOG_WARNING, unistim_device::nat, ast_channel::nativeformats, unistim_subchannel::owner, packet_send_call, packet_send_jitter_buffer_conf, packet_send_open_audio_stream_rx, packet_send_open_audio_stream_rx3, packet_send_open_audio_stream_tx, packet_send_open_audio_stream_tx3, packet_send_rtp_packet_size, unistim_line::parent, unistim_subchannel::parent, public_ip, 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, tos_audio, unistimdebug, and ast_channel::writeformat.

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

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

Definition at line 1848 of file chan_unistim.c.

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

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

static void TransferCallStep1 ( struct unistimsession pte  )  [static]

Definition at line 2298 of file chan_unistim.c.

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

Referenced by key_call().

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

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

Definition at line 1487 of file chan_unistim.c.

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

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

static int unistim_answer ( struct ast_channel ast  )  [static]

Definition at line 3808 of file chan_unistim.c.

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

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

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

Definition at line 3642 of file chan_unistim.c.

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

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

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

Definition at line 4796 of file chan_unistim.c.

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

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

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

Definition at line 2465 of file chan_unistim.c.

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

Referenced by key_call(), and unistim_senddigit_begin().

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

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

Definition at line 3994 of file chan_unistim.c.

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

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

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

Definition at line 5514 of file chan_unistim.c.

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

05516 {
05517    struct unistim_subchannel *sub;
05518    enum ast_rtp_get_result res = AST_RTP_GET_FAILED;
05519 
05520    if (unistimdebug)
05521       ast_verb(0, "unistim_get_rtp_peer called\n");
05522       
05523    sub = chan->tech_pvt;
05524    if (sub && sub->rtp) {
05525       *rtp = sub->rtp;
05526       res = AST_RTP_TRY_NATIVE;
05527    }
05528 
05529    return res;
05530 }

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

Definition at line 5508 of file chan_unistim.c.

References AST_RTP_TRY_NATIVE.

05510 {
05511    return AST_RTP_TRY_NATIVE;
05512 }

static int unistim_hangup ( struct ast_channel ast  )  [static]

Definition at line 3702 of file chan_unistim.c.

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

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

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

Definition at line 4066 of file chan_unistim.c.

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

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

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

Definition at line 4666 of file chan_unistim.c.

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

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

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

Protos

Definition at line 4415 of file chan_unistim.c.

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

Referenced by HandleCallOutgoing(), and unistim_request().

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

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

Definition at line 3946 of file chan_unistim.c.

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

03947 {
03948    struct ast_frame *fr;
03949    struct unistim_subchannel *sub = ast->tech_pvt;
03950 
03951    ast_mutex_lock(&sub->lock);
03952    fr = unistim_rtp_read(ast, sub);
03953    ast_mutex_unlock(&sub->lock);
03954 
03955    return fr;
03956 }

static int unistim_register ( struct unistimsession s  )  [static]

Definition at line 1445 of file chan_unistim.c.

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

Referenced by rcv_mac_addr().

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

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

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

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

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

Definition at line 4612 of file chan_unistim.c.

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

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

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

Definition at line 3898 of file chan_unistim.c.

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

Referenced by unistim_read().

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

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

Definition at line 4372 of file chan_unistim.c.

References ast_app_inboxcount(), 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_OLDMSGS, AST_EVENT_IE_PLTYPE_EXISTS, AST_EVENT_IE_PLTYPE_STR, AST_EVENT_MWI, ast_strdupa, ast_strlen_zero(), context, unistim_line::lastmsgssent, unistim_line::mailbox, mailbox, unistim_line::nextmsgcheck, s, send_led_update(), strsep(), and TIMER_MWI.

Referenced by do_monitor().

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

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

Definition at line 4202 of file chan_unistim.c.

References channel_to_session(), and unistim_do_senddigit().

04203 {
04204    struct unistimsession *pte = channel_to_session(ast);
04205 
04206    if (!pte)
04207       return -1;
04208 
04209    return unistim_do_senddigit(pte, digit);
04210 }

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

Definition at line 4212 of file chan_unistim.c.

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

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

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

Definition at line 4242 of file chan_unistim.c.

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

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

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

Definition at line 5532 of file chan_unistim.c.

References ast_verb, chan, ast_channel::tech_pvt, and unistimdebug.

05534 {
05535    struct unistim_subchannel *sub;
05536 
05537    if (unistimdebug)
05538       ast_verb(0, "unistim_set_rtp_peer called\n");
05539 
05540    sub = chan->tech_pvt;
05541 
05542    if (sub)
05543       return 0;
05544 
05545    return -1;
05546 }

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

Definition at line 4736 of file chan_unistim.c.

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

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

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

Definition at line 2000 of file chan_unistim.c.

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

Referenced by HandleCallOutgoing().

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

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

Definition at line 3958 of file chan_unistim.c.

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

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

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

Definition at line 3841 of file chan_unistim.c.

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

Referenced by do_monitor().

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

static int unload_module ( void   )  [static]

Definition at line 5607 of file chan_unistim.c.

References ARRAY_LEN, ast_channel_unregister(), ast_cli_unregister_multiple(), ast_free, ast_mutex_lock(), ast_mutex_unlock(), AST_PTHREADT_NULL, AST_PTHREADT_STOP, ast_rtp_proto_unregister(), buff, monitor_thread, monlock, sched_context_destroy(), unistim_cli, unistim_rtp, unistim_tech, and unistimsock.

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

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

Definition at line 4866 of file chan_unistim.c.

References len().

Referenced by build_device().

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

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

Definition at line 1090 of file chan_unistim.c.

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

Referenced by close_client(), and key_main_page().

01091 {
01092    if (unistimdebug)
01093       ast_verb(0, "Trying to unregister extension '%s' context '%s'\n",
01094                pte->device->extension_number, pte->device->lines->context);
01095    return ast_context_remove_extension(pte->device->lines->context,
01096                               pte->device->extension_number, 1, "Unistim");
01097 }

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

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

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

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

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

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


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

Definition at line 5646 of file chan_unistim.c.

struct sockaddr_in addr_from [static]

give the IP address for the last packet received

Definition at line 217 of file chan_unistim.c.

const struct ast_module_info* ast_module_info = &__mod_info [static]

Definition at line 5646 of file chan_unistim.c.

enum autoprovision autoprovisioning = AUTOPROVISIONING_NO [static]

Definition at line 206 of file chan_unistim.c.

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

unsigned char* buff [static]

Receive buffer address

Definition at line 221 of file chan_unistim.c.

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

unsigned int cos = 0 [static]

Definition at line 211 of file chan_unistim.c.

unsigned int cos_audio = 0 [static]

Definition at line 212 of file chan_unistim.c.

struct ast_jb_conf default_jbconf [static]

Global jitterbuffer configuration - by default, jb is disabled.

Definition at line 189 of file chan_unistim.c.

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

Protect the device list

Definition at line 238 of file chan_unistim.c.

struct unistim_device * devices [static]

A device containing one or more lines.

struct tone_zone_unistim frequency[] [static]

Definition at line 305 of file chan_unistim.c.

Referenced by SendDialTone().

struct ast_jb_conf global_jbconf [static]

Definition at line 196 of file chan_unistim.c.

struct io_context* io [static]

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

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

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

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

Referenced by parsing().

const unsigned char packet_recv_firm_version[] [static]

Initial value:

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

Definition at line 502 of file chan_unistim.c.

Referenced by process_request().

const unsigned char packet_recv_hangup[] [static]

Initial value:

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

Definition at line 508 of file chan_unistim.c.

Referenced by process_request().

const unsigned char packet_recv_mac_addr[] [static]

Initial value:

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

Definition at line 515 of file chan_unistim.c.

Referenced by process_request().

const unsigned char packet_recv_pick_up[] [static]

Initial value:

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

Definition at line 506 of file chan_unistim.c.

Referenced by process_request().

const unsigned char packet_recv_pressed_key[] [static]

Initial value:

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

Definition at line 504 of file chan_unistim.c.

Referenced by process_request().

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

Definition at line 510 of file chan_unistim.c.

Referenced by process_request().

const unsigned char packet_recv_resume_connection_with_server[] [static]

Initial value:

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

Definition at line 513 of file chan_unistim.c.

Referenced by process_request().

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

Definition at line 610 of file chan_unistim.c.

Referenced by init_phone_step2().

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

Definition at line 611 of file chan_unistim.c.

Referenced by send_blink_cursor().

const unsigned char packet_send_call[] [static]

Definition at line 538 of file chan_unistim.c.

Referenced by start_rtp().

const unsigned char packet_send_Contrast[] [static]

Initial value:

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

Definition at line 615 of file chan_unistim.c.

Referenced by init_phone_step2().

const unsigned char packet_send_date_time[] [static]

Definition at line 522 of file chan_unistim.c.

Referenced by send_date_time().

const unsigned char packet_send_date_time2[] [static]

Initial value:

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

Definition at line 612 of file chan_unistim.c.

Referenced by send_date_time2().

const unsigned char packet_send_date_time3[] [static]

Initial value:

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

Definition at line 518 of file chan_unistim.c.

Referenced by send_date_time3().

unsigned char packet_send_discovery_ack[] [static]

Initial value:

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

Definition at line 499 of file chan_unistim.c.

Referenced by parsing().

const unsigned char packet_send_end_call[] [static]

Initial value:

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

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

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

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

Referenced by start_rtp().

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

Definition at line 651 of file chan_unistim.c.

Referenced by send_led_update().

const unsigned char packet_send_no_ring[] [static]

Initial value:

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

Definition at line 529 of file chan_unistim.c.

Referenced by send_no_ring().

const unsigned char packet_send_open_audio_stream_rx[] [static]

Initial value:

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

Definition at line 585 of file chan_unistim.c.

Referenced by start_rtp().

const unsigned char packet_send_open_audio_stream_rx3[] [static]

Definition at line 596 of file chan_unistim.c.

Referenced by start_rtp().

const unsigned char packet_send_open_audio_stream_tx[] [static]

Initial value:

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

Definition at line 590 of file chan_unistim.c.

Referenced by start_rtp().

const unsigned char packet_send_open_audio_stream_tx3[] [static]

Definition at line 603 of file chan_unistim.c.

Referenced by start_rtp().

unsigned char packet_send_ping[] [static]

Initial value:

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

Definition at line 658 of file chan_unistim.c.

Referenced by reload_config().

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

Definition at line 653 of file chan_unistim.c.

Referenced by rcv_mac_addr().

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

Definition at line 655 of file chan_unistim.c.

Referenced by rcv_mac_addr().

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

Definition at line 654 of file chan_unistim.c.

Referenced by rcv_resume_connection_with_server().

const unsigned char packet_send_ring[] [static]

Initial value:

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

Definition at line 561 of file chan_unistim.c.

Referenced by send_ring().

const unsigned char packet_send_rtp_packet_size[] [static]

Initial value:

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

Definition at line 574 of file chan_unistim.c.

Referenced by start_rtp().

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

Definition at line 656 of file chan_unistim.c.

Referenced by rcv_mac_addr().

const unsigned char packet_send_s4[] [static]

Definition at line 531 of file chan_unistim.c.

Referenced by init_phone_step2().

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

Definition at line 622 of file chan_unistim.c.

Referenced by init_phone_step2().

const unsigned char packet_send_s9[] [static]

Initial value:

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

Definition at line 571 of file chan_unistim.c.

Referenced by init_phone_step2().

const unsigned char packet_send_select_output[] [static]

Initial value:

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

Definition at line 559 of file chan_unistim.c.

Referenced by send_select_output().

const unsigned char packet_send_set_pos_cursor[] [static]

Initial value:

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

Definition at line 623 of file chan_unistim.c.

Referenced by send_cursor_pos().

const unsigned char packet_send_StartTimer[] [static]

Initial value:

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

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

Referenced by send_text_status().

const unsigned char packet_send_status2[] [static]

Initial value:

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

Definition at line 647 of file chan_unistim.c.

Referenced by send_text_status().

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

Definition at line 620 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 557 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 547 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 553 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 555 of file chan_unistim.c.

const unsigned char packet_send_text[] [static]

Definition at line 636 of file chan_unistim.c.

Referenced by send_text().

const unsigned char packet_send_title[] [static]

Initial value:

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

Definition at line 633 of file chan_unistim.c.

Referenced by send_texttitle().

struct sockaddr_in public_ip = { 0, } [static]

Definition at line 215 of file chan_unistim.c.

Referenced by reload_config(), and start_rtp().

struct sched_context* sched [static]

Definition at line 214 of file chan_unistim.c.

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

Protect the session list

Definition at line 236 of file chan_unistim.c.

struct unistimsession * sessions [static]

unsigned int size_addr_from = sizeof(addr_from) [static]

size of the sockaddr_in (in WSARecvFrom)

Definition at line 219 of file chan_unistim.c.

Referenced by unistimsock_read().

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

Definition at line 663 of file chan_unistim.c.

unsigned int tos = 0 [static]

Definition at line 209 of file chan_unistim.c.

unsigned int tos_audio = 0 [static]

Definition at line 210 of file chan_unistim.c.

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

Definition at line 664 of file chan_unistim.c.

struct ast_cli_entry unistim_cli[] [static]

Definition at line 4859 of file chan_unistim.c.

Referenced by load_module(), and unload_module().

int unistim_keepalive [static]

Definition at line 207 of file chan_unistim.c.

Referenced by reload_config().

int unistim_port [static]

Definition at line 205 of file chan_unistim.c.

Referenced by reload_config().

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

Definition at line 223 of file chan_unistim.c.

Referenced by do_monitor(), and unistim_reload().

int unistim_reloading = 0 [static]

Definition at line 222 of file chan_unistim.c.

Referenced by do_monitor(), and unistim_reload().

struct ast_rtp_protocol unistim_rtp [static]

Definition at line 5548 of file chan_unistim.c.

Referenced by load_module(), and unload_module().

struct ast_channel_tech unistim_tech [static]

Definition at line 692 of file chan_unistim.c.

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

int unistimdebug = 0 [static]

Enable verbose output. can also be set with the CLI

Definition at line 204 of file chan_unistim.c.

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

int unistimsock = -1 [static]

Definition at line 208 of file chan_unistim.c.

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

int usecnt = 0 [static]

Definition at line 225 of file chan_unistim.c.

Referenced by unistim_new().

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

Definition at line 224 of file chan_unistim.c.

Referenced by unistim_new().


Generated on Thu Jul 9 13:41:12 2009 for Asterisk - the Open Source PBX by  doxygen 1.4.7