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

Variables

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


Detailed Description

chan_unistim channel driver for Asterisk

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

Definition in file chan_unistim.c.


Define Documentation

#define AST_CONFIG_MAX_PATH   255

Definition at line 97 of file chan_unistim.c.

Referenced by OpenHistory(), and write_history().

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

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

Referenced by key_select_codec().

#define SELECTCODEC_MSG   "Codec number : .."

Definition at line 2771 of file chan_unistim.c.

Referenced by HandleSelectCodec(), and key_select_codec().

#define SELECTCODEC_START_ENTRY_POS   15

Definition at line 2769 of file chan_unistim.c.

Referenced by HandleSelectCodec(), and key_select_codec().

#define SELECTEXTENSION_MAX_LENGTH   10

Definition at line 2847 of file chan_unistim.c.

Referenced by key_select_extension().

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

Definition at line 2848 of file chan_unistim.c.

Referenced by key_select_extension(), and ShowExtensionPage().

#define SELECTEXTENSION_START_ENTRY_POS   0

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

00257                    {
00258    STATE_ONHOOK,
00259    STATE_OFFHOOK,
00260 };

enum phone_key

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

Definition at line 262 of file chan_unistim.c.

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

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

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


Function Documentation

static void __reg_module ( void   )  [static]

Definition at line 5655 of file chan_unistim.c.

static void __unreg_module ( void   )  [static]

Definition at line 5655 of file chan_unistim.c.

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

Definition at line 1478 of file chan_unistim.c.

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

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

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

Definition at line 1882 of file chan_unistim.c.

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

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

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

Definition at line 4998 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, display_last_error(), unistim_device::extension, EXTENSION_ASK, EXTENSION_LINE, EXTENSION_NONE, unistim_device::extension_number, EXTENSION_TN, FAV_ICON_ONHOOK_BLACK, unistim_line::fullname, unistim_device::ha, unistim_device::id, unistim_line::language, len(), linelabel, ast_variable::lineno, unistim_device::lines, unistim_line::lock, LOG_ERROR, LOG_WARNING, unistim_line::mailbox, unistim_device::maintext0, unistim_device::maintext1, unistim_device::maintext2, unistim_line::musicclass, unistim_device::mute, MUTE_OFF, unistim_line::name, ast_variable::name, unistim_device::name, unistim_device::nat, ast_variable::next, unistim_line::next, unistim_device::next, unistim_device::output, OUTPUT_HANDSET, unistim_line::parent, unistim_line::parkinglot, ParseBookmark(), unistim_line::pickupgroup, unistim_device::previous_output, unistim_device::ringstyle, unistim_device::ringvolume, unistim_device::rtp_method, unistim_device::rtp_port, unistim_device::softkeydevice, unistim_device::softkeyicon, unistim_device::softkeylabel, unistim_device::softkeylinepos, unistim_device::softkeynumber, unistim_device::sp, unistim_device::status_method, SUB_REAL, unistim_device::titledefault, ast_tm::tm_zone, unistim_device::to_delete, unistim_device::tz, unistimdebug, unistimsock, unquote(), ast_variable::value, unistim_device::volume, and VOLUME_LOW.

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

static void cancel_dial ( struct unistimsession pte  )  [static]

Definition at line 1845 of file chan_unistim.c.

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

Referenced by unistim_hangup().

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

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

Definition at line 1948 of file chan_unistim.c.

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

Referenced by close_call(), and unistim_call().

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

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

Definition at line 1062 of file chan_unistim.c.

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

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

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

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

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

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

static void check_send_queue ( struct unistimsession pte  )  [static]

Definition at line 917 of file chan_unistim.c.

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

Referenced by parsing().

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

static void close_call ( struct unistimsession pte  )  [static]

Definition at line 1967 of file chan_unistim.c.

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

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

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

static void close_client ( struct unistimsession s  )  [static]

Definition at line 1106 of file chan_unistim.c.

References AST_CAUSE_NETWORK_OUT_OF_ORDER, ast_free, ast_log(), ast_mutex_destroy(), ast_mutex_lock(), ast_mutex_unlock(), ast_queue_hangup_with_cause(), ast_strlen_zero(), ast_verb, change_favorite_icon(), unistimsession::device, 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().

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

static char* control2str ( int  ind  )  [static]

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

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

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

Definition at line 862 of file chan_unistim.c.

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

Referenced by parsing().

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

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

Definition at line 717 of file chan_unistim.c.

References ast_log(), errno, and LOG_WARNING.

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

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

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

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

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

static void dummy ( char *  unused,
  ... 
) [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 4142 of file chan_unistim.c.

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

Referenced by unistim_request(), and unistim_sp().

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

static void finish_bookmark ( void   )  [static]

Definition at line 4973 of file chan_unistim.c.

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

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

static unsigned int get_tick_count ( void   )  [static]

Definition at line 728 of file chan_unistim.c.

References ast_tvnow().

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

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

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

Definition at line 829 of file chan_unistim.c.

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

Referenced by create_client().

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

static void handle_dial_page ( struct unistimsession pte  )  [static]

Definition at line 2255 of file chan_unistim.c.

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

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

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

static void HandleCallIncoming ( struct unistimsession s  )  [static]

Definition at line 2439 of file chan_unistim.c.

References AST_CONTROL_ANSWER, ast_log(), ast_queue_control(), ast_verb, 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().

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

static void HandleCallOutgoing ( struct unistimsession s  )  [static]

Definition at line 2350 of file chan_unistim.c.

References alloc_sub(), AST_CAUSE_SWITCH_CONGESTION, ast_channel_stop_silence_generator(), ast_debug, ast_hangup(), ast_log(), ast_pthread_create, ast_queue_hangup_with_cause(), AST_STATE_DOWN, ast_verb, 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().

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

static void HandleSelectCodec ( struct unistimsession pte  )  [static]

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

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

static void IgnoreCall ( struct unistimsession pte  )  [static]

Definition at line 2000 of file chan_unistim.c.

References send_no_ring().

Referenced by key_ringing().

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

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

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

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

static void init_phone_step2 ( struct unistimsession pte  )  [static]

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

Definition at line 2863 of file chan_unistim.c.

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

Referenced by process_request().

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

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

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

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

int load_module ( void   )  [static]

Definition at line 5565 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, channel_type, io, io_context_create(), io_context_destroy(), LOG_ERROR, reload_config(), restart_monitor(), sched_context_create(), sched_context_destroy(), SIZE_PAGE, unistim_cli, unistim_rtp, and unistim_tech.

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

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

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

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

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

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

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

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

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

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

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

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

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

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

Definition at line 1509 of file chan_unistim.c.

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

Referenced by process_request().

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

static void rcv_resume_connection_with_server ( struct unistimsession pte  )  [static]

Definition at line 1438 of file chan_unistim.c.

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

Referenced by process_request().

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

static int ReformatNumber ( char *  number  )  [static]

Definition at line 2961 of file chan_unistim.c.

Referenced by key_history(), and show_entry_history().

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

static void refresh_all_favorite ( struct unistimsession pte  )  [static]

Definition at line 1042 of file chan_unistim.c.

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

Referenced by init_phone_step2(), and key_select_extension().

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

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

Definition at line 1085 of file chan_unistim.c.

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

Referenced by key_select_extension(), and rcv_mac_addr().

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

static int reload ( void   )  [static]

reload: Part of Asterisk module interface ---

static int reload_config ( void   )  [static]

Definition at line 5287 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, config_flags, default_jbconf, devicelock, global_jbconf, hp, ast_variable::lineno, unistim_device::lines, unistimsession::lock, unistim_line::lock, unistim_subchannel::lock, LOG_ERROR, LOG_WARNING, MAX_SUBS, unistim_device::name, ast_variable::name, NB_MAX_RETRANSMIT, unistimsession::next, unistim_device::next, ast_variable::next, unistim_subchannel::owner, packet_send_ping, public_ip, qos, RETRANSMIT_TIMER, s, unistim_device::session, unistim_line::subs, unistim_device::to_delete, unistim_keepalive, unistim_port, unistimdebug, and ast_variable::value.

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

static int restart_monitor ( void   )  [static]

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

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

static void send_blink_cursor ( struct unistimsession pte  )  [static]

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

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

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

Definition at line 788 of file chan_unistim.c.

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

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

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

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

Definition at line 1426 of file chan_unistim.c.

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

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

static void send_date_time ( struct unistimsession pte  )  [static]

Definition at line 1360 of file chan_unistim.c.

References ast_localtime(), ast_tvnow(), ast_verb, BUFFSEND, 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().

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

static void send_date_time2 ( struct unistimsession pte  )  [static]

Definition at line 1377 of file chan_unistim.c.

References ast_localtime(), ast_tvnow(), ast_verb, BUFFSEND, unistim_device::datetimeformat, unistimsession::device, 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().

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

static void send_date_time3 ( struct unistimsession pte  )  [static]

Definition at line 1398 of file chan_unistim.c.

References ast_localtime(), ast_tvnow(), ast_verb, BUFFSEND, 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().

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

static void send_end_call ( struct unistimsession pte  )  [static]

Definition at line 897 of file chan_unistim.c.

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

Referenced by unistim_hangup().

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

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

Definition at line 1023 of file chan_unistim.c.

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

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

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

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

Definition at line 1251 of file chan_unistim.c.

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

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

static void send_no_ring ( struct unistimsession pte  )  [static]

Definition at line 1336 of file chan_unistim.c.

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

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

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

static void send_ping ( struct unistimsession pte  )  [static]

Definition at line 819 of file chan_unistim.c.

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

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

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

Definition at line 736 of file chan_unistim.c.

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

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

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

static int send_retransmit ( struct unistimsession pte  )  [static]

Definition at line 1156 of file chan_unistim.c.

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

Referenced by do_monitor(), and parsing().

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

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

Definition at line 1325 of file chan_unistim.c.

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

Referenced by unistim_call().

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

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

Definition at line 1265 of file chan_unistim.c.

References ast_log(), ast_verb, BUFFSEND, change_favorite_icon(), 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().

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

static void send_start_timer ( struct unistimsession pte  )  [static]

Definition at line 940 of file chan_unistim.c.

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

Referenced by HandleCallIncoming(), and unistim_answer().

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

static void send_stop_timer ( struct unistimsession pte  )  [static]

Definition at line 949 of file chan_unistim.c.

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

Referenced by close_call().

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

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

Definition at line 1196 of file chan_unistim.c.

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

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

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

Definition at line 1213 of file chan_unistim.c.

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

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

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

Definition at line 1345 of file chan_unistim.c.

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

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

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

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

Definition at line 969 of file chan_unistim.c.

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

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

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

static void SendDialTone ( struct unistimsession pte  )  [static]

Definition at line 2226 of file chan_unistim.c.

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

Referenced by handle_dial_page().

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

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

Definition at line 958 of file chan_unistim.c.

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

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

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

static void set_ping_timer ( struct unistimsession pte  )  [static]

Definition at line 906 of file chan_unistim.c.

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

Referenced by check_send_queue().

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

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

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

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

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

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

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

static void show_main_page ( struct unistimsession pte  )  [static]

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

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

static void ShowExtensionPage ( struct unistimsession pte  )  [static]

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

02850 {
02851    pte->state = STATE_EXTENSION;
02852 
02853    send_text(TEXT_LINE0, TEXT_NORMAL, pte, "Please enter a Terminal");
02854    send_text(TEXT_LINE1, TEXT_NORMAL, pte, "Number (TN) :");
02855    send_text(TEXT_LINE2, TEXT_NORMAL, pte, SELECTEXTENSION_MSG);
02856    send_blink_cursor(pte);
02857    send_cursor_pos(pte, TEXT_LINE2 + SELECTEXTENSION_START_ENTRY_POS);
02858    send_text_status(pte, "Enter  BackSpcErase");
02859    pte->size_buff_entry = 0;
02860    return;
02861 }

static void start_rtp ( struct unistim_subchannel sub  )  [static]

Definition at line 2027 of file chan_unistim.c.

References ast_best_codec(), AST_FORMAT_ALAW, AST_FORMAT_G723_1, AST_FORMAT_G729A, AST_FORMAT_ULAW, ast_getformatname(), ast_inet_ntoa(), ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_rtcp_fd(), ast_rtp_fd(), ast_rtp_get_us(), ast_rtp_lookup_code(), ast_rtp_new_with_bindaddr(), ast_rtp_set_peer(), ast_rtp_setnat(), ast_rtp_setqos(), ast_verb, BUFFSEND, errno, ast_channel::fds, 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, qos, ast_channel::readformat, unistim_subchannel::rtp, unistim_device::rtp_method, unistim_device::rtp_port, send_client(), unistim_device::session, unistimsession::sin, SIZE_HEADER, unistimsession::sout, unistimdebug, and ast_channel::writeformat.

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

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

Definition at line 1854 of file chan_unistim.c.

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

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

static void TransferCallStep1 ( struct unistimsession pte  )  [static]

Definition at line 2304 of file chan_unistim.c.

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

Referenced by key_call().

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

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

Definition at line 1493 of file chan_unistim.c.

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

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

static int unistim_answer ( struct ast_channel ast  )  [static]

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

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

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

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

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

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

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

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

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

Definition at line 2471 of file chan_unistim.c.

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

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

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

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

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

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

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

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

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

Definition at line 5517 of file chan_unistim.c.

References AST_RTP_TRY_NATIVE.

05519 {
05520    return AST_RTP_TRY_NATIVE;
05521 }

static int unistim_hangup ( struct ast_channel ast  )  [static]

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

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

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

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

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

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

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

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

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

Protos

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

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

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

Definition at line 3953 of file chan_unistim.c.

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

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

static int unistim_register ( struct unistimsession s  )  [static]

Definition at line 1451 of file chan_unistim.c.

References ast_mutex_lock(), ast_mutex_unlock(), unistim_device::codec_number, DEFAULT_CODEC, devicelock, 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().

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

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

--- unistim_reload: Force reload of module from cli --- Runs in the asterisk main thread, so don't do anything useful but setting a flag and waiting for do_monitor to do the job in our thread

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

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

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

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

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

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

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

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

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

Definition at line 4379 of file chan_unistim.c.

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

Referenced by do_monitor().

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

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

Definition at line 4209 of file chan_unistim.c.

References channel_to_session(), and unistim_do_senddigit().

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

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

Definition at line 4219 of file chan_unistim.c.

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

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

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

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

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

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

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

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

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

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

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

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

Definition at line 2006 of file chan_unistim.c.

References ast_copy_string(), ast_log(), ast_pbx_run(), ast_setstate(), AST_STATE_RING, ast_verb, chan, 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().

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

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

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

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

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

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

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

static int unload_module ( void   )  [static]

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

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

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

Definition at line 4873 of file chan_unistim.c.

References len().

Referenced by build_device().

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

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

Definition at line 1096 of file chan_unistim.c.

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

Referenced by close_client(), and key_main_page().

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

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

Definition at line 1671 of file chan_unistim.c.

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

Referenced by write_history().

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

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

Definition at line 1692 of file chan_unistim.c.

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

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

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


Variable Documentation

struct ast_module_info __mod_info = { .name = AST_MODULE, .flags = AST_MODFLAG_DEFAULT , .description = "UNISTIM Protocol (USTM)" , .key = "This paragraph is copyright (c) 2006 by Digium, Inc. \In order for your module to load, it must return this \key via a function called \"key\". Any code which \includes this paragraph must be licensed under the GNU \General Public License version 2 or later (at your \option). In addition to Digium's general reservations \of rights, Digium expressly reserves the right to \allow other parties to license this paragraph under \different terms. Any use of Digium, Inc. trademarks or \logos (including \"Asterisk\" or \"Digium\") without \express written permission of Digium, Inc. is prohibited.\n" , .buildopt_sum = "a9c98e5d177805051735cb5b0b16b0a0" , .load = load_module, .unload = unload_module, .reload = reload, } [static]

Definition at line 5655 of file chan_unistim.c.

struct sockaddr_in address_from [static]

give the IP address for the last packet received

Definition at line 221 of file chan_unistim.c.

struct ast_module_info* ast_module_info = &__mod_info [static]

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

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

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

Definition at line 670 of file chan_unistim.c.

unsigned int cos

Definition at line 213 of file chan_unistim.c.

unsigned int cos_audio

Definition at line 214 of file chan_unistim.c.

struct ast_jb_conf default_jbconf [static]

Global jitterbuffer configuration - by default, jb is disabled.

Definition at line 189 of file chan_unistim.c.

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

Protect the device list

Definition at line 242 of file chan_unistim.c.

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

struct unistim_device * devices [static]

A device containing one or more lines.

struct tone_zone_unistim frequency[] [static]

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

pthread_t monitor_thread = AST_PTHREADT_NULL [static]

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

Definition at line 234 of file chan_unistim.c.

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

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

Definition at line 238 of file chan_unistim.c.

const unsigned char packet_rcv_discovery[] [static]

Initial value:

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

Definition at line 503 of file chan_unistim.c.

Referenced by parsing().

const unsigned char packet_recv_firm_version[] [static]

Initial value:

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

Definition at line 508 of file chan_unistim.c.

Referenced by process_request().

const unsigned char packet_recv_hangup[] [static]

Initial value:

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

Definition at line 514 of file chan_unistim.c.

Referenced by process_request().

const unsigned char packet_recv_mac_addr[] [static]

Initial value:

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

Definition at line 521 of file chan_unistim.c.

Referenced by process_request().

const unsigned char packet_recv_pick_up[] [static]

Initial value:

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

Definition at line 512 of file chan_unistim.c.

Referenced by process_request().

const unsigned char packet_recv_pressed_key[] [static]

Initial value:

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

Definition at line 510 of file chan_unistim.c.

Referenced by process_request().

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

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

Referenced by process_request().

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

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

Referenced by send_blink_cursor().

const unsigned char packet_send_call[] [static]

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

Referenced by init_phone_step2().

const unsigned char packet_send_date_time[] [static]

Definition at line 528 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 618 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 524 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 505 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 572 of file chan_unistim.c.

const unsigned char packet_send_favorite[] [static]

Initial value:

   { 0x17, 0x0f, 0x19, 0x10,  0x01,  0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
0x20, 0x20, 0x20, 0x20,  0x19,
   0x05, 0x0f,  0x01,  0x00
}

Definition at line 634 of file chan_unistim.c.

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

Definition at line 627 of file chan_unistim.c.

const unsigned char packet_send_jitter_buffer_conf[] [static]

Initial value:

   { 0x16, 0x0e, 0x3a, 0x00,  0x02,  0x04, 0x00, 0x00,
 0x3e, 0x80,
   0x00, 0x00,  0x3e, 0x80
}

Definition at line 582 of file chan_unistim.c.

Referenced by start_rtp().

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

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

Referenced by start_rtp().

const unsigned char packet_send_open_audio_stream_rx3[] [static]

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

Referenced by start_rtp().

const unsigned char packet_send_open_audio_stream_tx3[] [static]

Definition at line 609 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 664 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 659 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 661 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 660 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 567 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 580 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 662 of file chan_unistim.c.

Referenced by rcv_mac_addr().

const unsigned char packet_send_s4[] [static]

Definition at line 537 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 628 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 577 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 565 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 629 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 623 of file chan_unistim.c.

const unsigned char packet_send_status[] [static]

Initial value:

   { 0x17, 0x20, 0x19, 0x08,  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
   0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20    
}

Definition at line 648 of file chan_unistim.c.

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

const unsigned char packet_send_stream_based_tone_dial_freq[] [static]

Initial value:

   { 0x16, 0x08, 0x1d, 0x00, 0x01, 0xb8, 0x01, 0x5e }

Definition at line 563 of file chan_unistim.c.

const unsigned char packet_send_stream_based_tone_off[] [static]

Initial value:

   { 0x16, 0x05, 0x1c, 0x00, 0x00 }

Definition at line 553 of file chan_unistim.c.

const unsigned char packet_send_stream_based_tone_on[] [static]

Initial value:

   { 0x16, 0x06, 0x1b, 0x00, 0x00, 0x05 }

Definition at line 559 of file chan_unistim.c.

const unsigned char packet_send_stream_based_tone_single_freq[] [static]

Initial value:

   { 0x16, 0x06, 0x1d, 0x00, 0x01, 0xb8 }

Definition at line 561 of file chan_unistim.c.

const unsigned char packet_send_text[] [static]

Definition at line 642 of file chan_unistim.c.

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

Referenced by send_texttitle().

struct sockaddr_in public_ip = { 0, } [static]

Definition at line 219 of file chan_unistim.c.

Referenced by reload_config(), and start_rtp().

struct { ... } qos [static]

struct sched_context* sched [static]

Definition at line 218 of file chan_unistim.c.

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

Protect the session list

Definition at line 240 of file chan_unistim.c.

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

struct unistimsession * sessions [static]

unsigned int size_addr_from = sizeof(address_from) [static]

size of the sockaddr_in (in WSARecvFrom)

Definition at line 223 of file chan_unistim.c.

Referenced by unistimsock_read().

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

Definition at line 669 of file chan_unistim.c.

unsigned int tos

Definition at line 211 of file chan_unistim.c.

unsigned int tos_audio

Definition at line 212 of file chan_unistim.c.

struct ast_cli_entry unistim_cli[] [static]

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

Referenced by do_monitor(), and unistim_reload().

int unistim_reloading = 0 [static]

Definition at line 226 of file chan_unistim.c.

Referenced by do_monitor(), and unistim_reload().

struct ast_rtp_protocol unistim_rtp [static]

Definition at line 5557 of file chan_unistim.c.

Referenced by load_module(), and unload_module().

struct ast_channel_tech unistim_tech [static]

Definition at line 698 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 229 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 228 of file chan_unistim.c.

Referenced by unistim_new().


Generated on Fri Jun 19 12:10:27 2009 for Asterisk - the Open Source PBX by  doxygen 1.4.7