Fri Aug 17 00:17:35 2018

Asterisk developer's documentation


chan_unistim.c File Reference

chan_unistim channel driver for Asterisk More...

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

Go to the source code of this file.

Data Structures

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

Defines

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

Enumerations

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

Functions

static int alloc_sub (struct unistim_line *l, int x)
 AST_MODULE_INFO (ASTERISK_GPL_KEY, AST_MODFLAG_DEFAULT,"UNISTIM Protocol (USTM)",.load=load_module,.unload=unload_module,.reload=reload,)
 AST_MUTEX_DEFINE_STATIC (devicelock)
 AST_MUTEX_DEFINE_STATIC (sessionlock)
 AST_MUTEX_DEFINE_STATIC (monlock)
 AST_MUTEX_DEFINE_STATIC (usecnt_lock)
 AST_MUTEX_DEFINE_STATIC (unistim_reload_lock)
static int attempt_transfer (struct unistim_subchannel *p1, struct unistim_subchannel *p2)
static struct unistim_devicebuild_device (const char *cat, const struct ast_variable *v)
static void cancel_dial (struct unistimsession *pte)
static void change_callerid (struct unistimsession *pte, int type, char *callerid)
static void change_favorite_icon (struct unistimsession *pte, unsigned char status)
static struct unistimsessionchannel_to_session (struct ast_channel *ast)
static void check_send_queue (struct unistimsession *pte)
static void close_call (struct unistimsession *pte)
static void close_client (struct unistimsession *s)
static char * control2str (int ind)
static struct unistimsessioncreate_client (const struct sockaddr_in *addr_from)
static void display_last_error (const char *sz_msg)
static void * do_monitor (void *data)
static void dummy (char *unused,...)
static struct unistim_subchannelfind_subchannel_by_name (const char *dest)
static void finish_bookmark (void)
static unsigned int get_tick_count (void)
static int get_to_address (int fd, struct sockaddr_in *toAddr)
static void handle_dial_page (struct unistimsession *pte)
static void HandleCallIncoming (struct unistimsession *s)
static void HandleCallOutgoing (struct unistimsession *s)
static void HandleSelectCodec (struct unistimsession *pte)
static void IgnoreCall (struct unistimsession *pte)
static void in_band_indication (struct ast_channel *ast, const struct ast_tone_zone *tz, const char *indication)
static void init_phone_step2 (struct unistimsession *pte)
static void key_call (struct unistimsession *pte, char keycode)
static void key_dial_page (struct unistimsession *pte, char keycode)
static void key_history (struct unistimsession *pte, char keycode)
static void key_main_page (struct unistimsession *pte, char keycode)
static void key_ringing (struct unistimsession *pte, char keycode)
static void key_select_codec (struct unistimsession *pte, char keycode)
static void key_select_extension (struct unistimsession *pte, char keycode)
static void Keyfavorite (struct unistimsession *pte, char keycode)
static int load_module (void)
static char OpenHistory (struct unistimsession *pte, char way, FILE **f)
static int ParseBookmark (const char *text, struct unistim_device *d)
static void parsing (int size, unsigned char *buf, struct unistimsession *pte, struct sockaddr_in *addr_from)
static void process_request (int size, unsigned char *buf, struct unistimsession *pte)
static void rcv_mac_addr (struct unistimsession *pte, const unsigned char *buf)
static void rcv_resume_connection_with_server (struct unistimsession *pte)
static int ReformatNumber (char *number)
static void refresh_all_favorite (struct unistimsession *pte)
static int RegisterExtension (const struct unistimsession *pte)
static int reload (void)
static int reload_config (void)
static int restart_monitor (void)
static void send_blink_cursor (struct unistimsession *pte)
static void send_client (int size, const unsigned char *data, struct unistimsession *pte)
static void send_cursor_pos (struct unistimsession *pte, unsigned char pos)
static void send_date_time (struct unistimsession *pte)
static void send_date_time2 (struct unistimsession *pte)
static void send_date_time3 (struct unistimsession *pte)
static void send_end_call (struct unistimsession *pte)
static void send_favorite (unsigned char pos, unsigned char status, struct unistimsession *pte, const char *text)
static void send_led_update (struct unistimsession *pte, unsigned char led)
static void send_no_ring (struct unistimsession *pte)
static void send_ping (struct unistimsession *pte)
static void send_raw_client (int size, const unsigned char *data, struct sockaddr_in *addr_to, const struct sockaddr_in *addr_ourip)
static int send_retransmit (struct unistimsession *pte)
static void send_ring (struct unistimsession *pte, char volume, char style)
static void send_select_output (struct unistimsession *pte, unsigned char output, unsigned char volume, unsigned char mute)
static void send_start_timer (struct unistimsession *pte)
static void send_stop_timer (struct unistimsession *pte)
static void send_text (unsigned char pos, unsigned char inverse, struct unistimsession *pte, const char *text)
static void send_text_status (struct unistimsession *pte, const char *text)
static void send_texttitle (struct unistimsession *pte, const char *text)
static void send_tone (struct unistimsession *pte, uint16_t tone1, uint16_t tone2)
static void SendDialTone (struct unistimsession *pte)
static void Sendicon (unsigned char pos, unsigned char status, struct unistimsession *pte)
static void set_ping_timer (struct unistimsession *pte)
static void show_entry_history (struct unistimsession *pte, FILE **f)
static void show_history (struct unistimsession *pte, char way)
static void show_main_page (struct unistimsession *pte)
static void ShowExtensionPage (struct unistimsession *pte)
static void start_rtp (struct unistim_subchannel *sub)
static void swap_subs (struct unistim_line *p, int a, int b)
static void TransferCallStep1 (struct unistimsession *pte)
static int unalloc_sub (struct unistim_line *p, int x)
static int unistim_answer (struct ast_channel *ast)
static int unistim_call (struct ast_channel *ast, char *dest, int timeout)
static char * unistim_do_debug (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
static int unistim_do_senddigit (struct unistimsession *pte, char digit)
static int unistim_fixup (struct ast_channel *oldchan, struct ast_channel *newchan)
static enum ast_rtp_glue_result unistim_get_rtp_peer (struct ast_channel *chan, struct ast_rtp_instance **instance)
static int unistim_hangup (struct ast_channel *ast)
static int unistim_indicate (struct ast_channel *ast, int ind, const void *data, size_t datalen)
static char * unistim_info (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
static struct ast_channelunistim_new (struct unistim_subchannel *sub, int state, const char *linkedid)
static struct ast_frameunistim_read (struct ast_channel *ast)
static int unistim_register (struct unistimsession *s)
static char * unistim_reload (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
 --- unistim_reload: Force reload of module from cli --- Runs in the asterisk main thread, so don't do anything useful but setting a flag and waiting for do_monitor to do the job in our thread
static struct ast_channelunistim_request (const char *type, format_t format, const struct ast_channel *requestor, void *data, int *cause)
static struct ast_frameunistim_rtp_read (const struct ast_channel *ast, const struct unistim_subchannel *sub)
static int unistim_send_mwi_to_peer (struct unistimsession *s, unsigned int tick)
static int unistim_senddigit_begin (struct ast_channel *ast, char digit)
static int unistim_senddigit_end (struct ast_channel *ast, char digit, unsigned int duration)
static int unistim_sendtext (struct ast_channel *ast, const char *text)
static int unistim_set_rtp_peer (struct ast_channel *chan, struct ast_rtp_instance *rtp, struct ast_rtp_instance *vrtp, struct ast_rtp_instance *trtp, format_t 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 sockaddr_in address_from
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 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 const unsigned char packet_rcv_discovery []
static const unsigned char packet_recv_firm_version []
static const unsigned char packet_recv_hangup []
static const unsigned char packet_recv_mac_addr []
static const unsigned char packet_recv_pick_up []
static const unsigned char packet_recv_pressed_key []
static const unsigned char packet_recv_r2 [] = { 0x00, 0x00, 0x00, 0x13, 0x96, 0x03, 0x03 }
static const unsigned char packet_recv_resume_connection_with_server []
static const unsigned char packet_send_arrow [] = { 0x17, 0x04, 0x04, 0x00 }
static const unsigned char packet_send_blink_cursor [] = { 0x17, 0x04, 0x10, 0x86 }
static const unsigned char packet_send_call []
static const unsigned char packet_send_Contrast []
static const unsigned char packet_send_date_time []
static const unsigned char packet_send_date_time2 []
static const unsigned char packet_send_date_time3 []
static const unsigned char packet_send_discovery_ack []
static const unsigned char packet_send_end_call []
static const unsigned char packet_send_favorite []
static const unsigned char packet_send_icon [] = { 0x17, 0x05, 0x14, 0x00, 0x25 }
static const unsigned char packet_send_jitter_buffer_conf []
static const unsigned char packet_send_led_update [] = { 0x19, 0x04, 0x00, 0x00 }
static const unsigned char packet_send_no_ring []
static const unsigned char packet_send_open_audio_stream_rx []
static const unsigned char packet_send_open_audio_stream_rx3 []
static const unsigned char packet_send_open_audio_stream_tx []
static const unsigned char packet_send_open_audio_stream_tx3 []
static unsigned char packet_send_ping []
static const unsigned char packet_send_query_basic_manager_04 [] = { 0x1a, 0x04, 0x01, 0x04 }
static const unsigned char packet_send_query_basic_manager_10 [] = { 0x1a, 0x04, 0x01, 0x10 }
static const unsigned char packet_send_query_mac_address [] = { 0x1a, 0x04, 0x01, 0x08 }
static const unsigned char packet_send_ring []
static const unsigned char packet_send_rtp_packet_size []
static const unsigned char packet_send_S1 [] = { 0x1a, 0x07, 0x07, 0x00, 0x00, 0x00, 0x13 }
static const unsigned char packet_send_s4 []
static const unsigned char packet_send_S7 [] = { 0x17, 0x06, 0x0f, 0x30, 0x07, 0x07 }
static const unsigned char packet_send_s9 []
static const unsigned char packet_send_select_output []
static const unsigned char packet_send_set_pos_cursor []
static const unsigned char packet_send_StartTimer []
static const unsigned char packet_send_status []
static const unsigned char packet_send_status2 []
static const unsigned char packet_send_stop_timer [] = { 0x17, 0x05, 0x0b, 0x02, 0x00 }
static const unsigned char packet_send_stream_based_tone_dial_freq []
static const unsigned char packet_send_stream_based_tone_off []
static const unsigned char packet_send_stream_based_tone_on []
static const unsigned char packet_send_stream_based_tone_single_freq []
static const unsigned char packet_send_text []
static const unsigned char packet_send_title []
static struct sockaddr_in public_ip = { 0, }
struct {
   unsigned int   cos
   unsigned int   cos_audio
   unsigned int   tos
   unsigned int   tos_audio
qos
static struct sched_contextsched
static 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 int unistim_reloading = 0
static struct ast_rtp_glue unistim_rtp_glue
static struct ast_channel_tech unistim_tech
static int unistimdebug = 0
static int unistimsock = -1
static int usecnt = 0

Detailed Description

chan_unistim channel driver for Asterisk

Author:
Cedric Hans <cedric.hans@mlkj.net>

Unistim (Unified Networks IP Stimulus) channel driver for Nortel i2002, i2004 and i2050

Definition in file chan_unistim.c.


Define Documentation

#define AST_CONFIG_MAX_PATH   255

Definition at line 102 of file chan_unistim.c.

Referenced by OpenHistory(), and write_history().

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

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

Definition at line 78 of file chan_unistim.c.

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

#define DEBUG_TIMER   dummy

Definition at line 209 of file chan_unistim.c.

Referenced by do_monitor(), and set_ping_timer().

#define DEFAULT_CODEC   0x00

Not used

Definition at line 99 of file chan_unistim.c.

Referenced by key_select_extension(), and unistim_register().

#define DEFAULTCALLERID   "Unknown"

Definition at line 81 of file chan_unistim.c.

Referenced by unistim_call().

#define DEFAULTCALLERNAME   " "

Definition at line 82 of file chan_unistim.c.

Referenced by unistim_call().

#define DEFAULTCONTEXT   "default"

Definition at line 80 of file chan_unistim.c.

Referenced by build_device().

#define DEFAULTHEIGHT   3

Definition at line 83 of file chan_unistim.c.

Referenced by build_device().

#define DEVICE_NAME_LEN   16

Definition at line 101 of file chan_unistim.c.

#define FAV_BLINK_FAST   0x20

Definition at line 183 of file chan_unistim.c.

Referenced by unistim_call().

#define FAV_BLINK_SLOW   0x40

Definition at line 184 of file chan_unistim.c.

Referenced by show_main_page().

#define FAV_ICON_BOX   0x3F

Definition at line 181 of file chan_unistim.c.

#define FAV_ICON_CALL_CENTER   0x34

Definition at line 170 of file chan_unistim.c.

Referenced by show_main_page().

#define FAV_ICON_CITY   0x31

Definition at line 167 of file chan_unistim.c.

#define FAV_ICON_COMPUTER   0x38

Definition at line 174 of file chan_unistim.c.

#define FAV_ICON_FAX   0x35

Definition at line 171 of file chan_unistim.c.

#define FAV_ICON_FORWARD   0x39

Definition at line 175 of file chan_unistim.c.

#define FAV_ICON_HEADPHONES   0x2E

Definition at line 164 of file chan_unistim.c.

Referenced by send_select_output().

#define FAV_ICON_HEADPHONES_ONHOLD   0x2F

Definition at line 165 of file chan_unistim.c.

Referenced by refresh_all_favorite(), and send_select_output().

#define FAV_ICON_HOME   0x30

Definition at line 166 of file chan_unistim.c.

#define FAV_ICON_INBOX   0x3C

Definition at line 178 of file chan_unistim.c.

#define FAV_ICON_LOCKED   0x3A

Definition at line 176 of file chan_unistim.c.

#define FAV_ICON_MAILBOX   0x36

Definition at line 172 of file chan_unistim.c.

#define FAV_ICON_MEETING   0x3E

Definition at line 180 of file chan_unistim.c.

#define FAV_ICON_NONE   0x00

Definition at line 149 of file chan_unistim.c.

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

#define FAV_ICON_OFFHOOK_BLACK   0x24

Definition at line 154 of file chan_unistim.c.

Referenced by send_select_output().

#define FAV_ICON_OFFHOOK_WHITE   0x25

Definition at line 155 of file chan_unistim.c.

#define FAV_ICON_ONHOLD_BLACK   0x26

Definition at line 156 of file chan_unistim.c.

Referenced by send_select_output().

#define FAV_ICON_ONHOLD_WHITE   0x27

Definition at line 157 of file chan_unistim.c.

#define FAV_ICON_ONHOOK_BLACK   0x20

Definition at line 150 of file chan_unistim.c.

Referenced by build_device(), and show_main_page().

#define FAV_ICON_ONHOOK_WHITE   0x21

Definition at line 151 of file chan_unistim.c.

#define FAV_ICON_OUTBOX   0x3D

Definition at line 179 of file chan_unistim.c.

#define FAV_ICON_PAGER   0x33

Definition at line 169 of file chan_unistim.c.

#define FAV_ICON_PHONE_BLACK   0x2A

Definition at line 160 of file chan_unistim.c.

Referenced by handle_dial_page().

#define FAV_ICON_PHONE_WHITE   0x2B

Definition at line 161 of file chan_unistim.c.

#define FAV_ICON_REFLECT   0x37

Definition at line 173 of file chan_unistim.c.

Referenced by show_main_page().

#define FAV_ICON_SHARP   0x32

Definition at line 168 of file chan_unistim.c.

Referenced by ParseBookmark().

#define FAV_ICON_SPEAKER_OFFHOOK_BLACK   0x28

Definition at line 158 of file chan_unistim.c.

Referenced by send_select_output().

#define FAV_ICON_SPEAKER_OFFHOOK_WHITE   0x29

Definition at line 159 of file chan_unistim.c.

#define FAV_ICON_SPEAKER_ONHOLD_BLACK   0x2C

Definition at line 162 of file chan_unistim.c.

Referenced by send_select_output().

#define FAV_ICON_SPEAKER_ONHOLD_WHITE   0x2D

Definition at line 163 of file chan_unistim.c.

#define FAV_ICON_SPEAKER_ONHOOK_BLACK   0x22

Definition at line 152 of file chan_unistim.c.

Referenced by send_select_output(), and unistim_call().

#define FAV_ICON_SPEAKER_ONHOOK_WHITE   0x23

Definition at line 153 of file chan_unistim.c.

#define FAV_ICON_TRASH   0x3B

Definition at line 177 of file chan_unistim.c.

#define FAV_MAX_LENGTH   0x0A

Definition at line 186 of file chan_unistim.c.

Referenced by send_favorite().

#define IDLE_WAIT   1000

Nb of milliseconds waited when no events are scheduled

Definition at line 93 of file chan_unistim.c.

Referenced by do_monitor().

#define MAX_BUF_NUMBER   50

Number of slots for the transmit queue

Definition at line 89 of file chan_unistim.c.

Referenced by create_client(), and send_client().

#define MAX_BUF_SIZE   64

Size of the transmit buffer

Definition at line 87 of file chan_unistim.c.

#define MAX_ENTRY_LOG   30

Definition at line 103 of file chan_unistim.c.

Referenced by OpenHistory(), and write_history().

#define MAX_SUBS   2

Definition at line 107 of file chan_unistim.c.

#define MUTE_OFF   0x00
#define MUTE_ON   0xFF

Definition at line 136 of file chan_unistim.c.

Referenced by key_call(), and send_select_output().

#define MUTE_ON_DISCRET   0xCE

Definition at line 137 of file chan_unistim.c.

Referenced by send_select_output(), and show_main_page().

#define NB_MAX_RETRANSMIT   8

Try x times before removing the phone

Definition at line 91 of file chan_unistim.c.

Referenced by reload_config(), and send_retransmit().

#define OUTPUT_HANDSET   0xC0
#define OUTPUT_HEADPHONE   0xC1
#define OUTPUT_SPEAKER   0xC2
#define RETRANSMIT_TIMER   2000

Wait x milliseconds before resending a packet

Definition at line 95 of file chan_unistim.c.

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

#define SELECTCODEC_MAX_LENGTH   2

Definition at line 2817 of file chan_unistim.c.

Referenced by key_select_codec().

#define SELECTCODEC_MSG   "Codec number : .."

Definition at line 2818 of file chan_unistim.c.

Referenced by HandleSelectCodec(), and key_select_codec().

#define SELECTCODEC_START_ENTRY_POS   15

Definition at line 2816 of file chan_unistim.c.

Referenced by HandleSelectCodec(), and key_select_codec().

#define SELECTEXTENSION_MAX_LENGTH   10

Definition at line 2894 of file chan_unistim.c.

Referenced by key_select_extension().

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

Definition at line 2895 of file chan_unistim.c.

Referenced by key_select_extension(), and ShowExtensionPage().

#define SELECTEXTENSION_START_ENTRY_POS   0

Definition at line 2893 of file chan_unistim.c.

Referenced by key_select_extension(), and ShowExtensionPage().

#define SIZE_HEADER   6
#define SIZE_MAC_ADDR   17

Definition at line 140 of file chan_unistim.c.

#define SIZE_PAGE   4096

Definition at line 100 of file chan_unistim.c.

Referenced by load_module(), and unistimsock_read().

#define STATUS_LENGTH_MAX   28

Definition at line 147 of file chan_unistim.c.

Referenced by send_text_status(), and show_entry_history().

#define SUB_REAL   0

Definition at line 105 of file chan_unistim.c.

#define SUB_THREEWAY   1

Definition at line 106 of file chan_unistim.c.

#define TEXT_INVERSE   0x25

Definition at line 146 of file chan_unistim.c.

Referenced by HandleSelectCodec(), and key_select_codec().

#define TEXT_LENGTH_MAX   24
#define TEXT_LINE0   0x00
#define TEXT_LINE1   0x20
#define TEXT_LINE2   0x40
#define TEXT_NORMAL   0x05
#define TIMER_MWI   10000

How often the mailbox is checked for new messages

Definition at line 97 of file chan_unistim.c.

Referenced by unistim_send_mwi_to_peer().

#define USTM_LOG_DIR   "unistimHistory"

Definition at line 84 of file chan_unistim.c.

Referenced by OpenHistory(), and write_history().

#define VOLUME_INSANELY_LOUD   0x07

Definition at line 133 of file chan_unistim.c.

#define VOLUME_LOW   0x01

Definition at line 130 of file chan_unistim.c.

Referenced by build_device(), and send_select_output().

#define VOLUME_LOW_SPEAKER   0x03

Definition at line 131 of file chan_unistim.c.

Referenced by send_select_output().

#define VOLUME_NORMAL   0x02

Definition at line 132 of file chan_unistim.c.


Enumeration Type Documentation

Enumerator:
EXTENSION_NONE 

Do not create an extension into the default dialplan

EXTENSION_ASK 

Prompt user for an extension number and register it

EXTENSION_LINE 

Register an extension with the line=> value

EXTENSION_TN 

Used with AUTOPROVISIONING_TN

Definition at line 116 of file chan_unistim.c.

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

Enumerator:
AUTOPROVISIONING_NO 
AUTOPROVISIONING_YES 
AUTOPROVISIONING_DB 
AUTOPROVISIONING_TN 

Definition at line 109 of file chan_unistim.c.

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

Enumerator:
STATE_ONHOOK 
STATE_OFFHOOK 

Definition at line 264 of file chan_unistim.c.

00264                    {
00265    STATE_ONHOOK,
00266    STATE_OFFHOOK,
00267 };

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

Definition at line 269 of file chan_unistim.c.

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

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

Definition at line 251 of file chan_unistim.c.

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


Function Documentation

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

Definition at line 1492 of file chan_unistim.c.

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

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

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

AST_MODULE_INFO ( ASTERISK_GPL_KEY  ,
AST_MODFLAG_DEFAULT  ,
"UNISTIM Protocol (USTM)"  ,
load = load_module,
unload = unload_module,
reload = reload 
)
AST_MUTEX_DEFINE_STATIC ( devicelock   ) 

Protect the device list

AST_MUTEX_DEFINE_STATIC ( sessionlock   ) 

Protect the session list

AST_MUTEX_DEFINE_STATIC ( monlock   ) 

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

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

Definition at line 1895 of file chan_unistim.c.

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

Referenced by close_call().

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

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

Definition at line 5078 of file chan_unistim.c.

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

Referenced by reload_config().

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

static void cancel_dial ( struct unistimsession pte  )  [static]

Definition at line 1858 of file chan_unistim.c.

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

Referenced by unistim_hangup().

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

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

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

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

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

Definition at line 1076 of file chan_unistim.c.

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

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

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

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

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

03671 {
03672    struct unistim_subchannel *sub;
03673    if (!ast) {
03674       ast_log(LOG_WARNING, "Unistim callback function called with a null channel\n");
03675       return NULL;
03676    }
03677    if (!ast->tech_pvt) {
03678       ast_log(LOG_WARNING, "Unistim callback function called without a tech_pvt\n");
03679       return NULL;
03680    }
03681    sub = ast->tech_pvt;
03682 
03683    if (!sub->parent) {
03684       ast_log(LOG_WARNING, "Unistim callback function called without a line\n");
03685       return NULL;
03686    }
03687    if (!sub->parent->parent) {
03688       ast_log(LOG_WARNING, "Unistim callback function called without a device\n");
03689       return NULL;
03690    }
03691    if (!sub->parent->parent->session) {
03692       ast_log(LOG_WARNING, "Unistim callback function called without a session\n");
03693       return NULL;
03694    }
03695    return sub->parent->parent->session;
03696 }

static void check_send_queue ( struct unistimsession pte  )  [static]

Definition at line 931 of file chan_unistim.c.

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

Referenced by parsing().

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

static void close_call ( struct unistimsession pte  )  [static]

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

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

static void close_client ( struct unistimsession s  )  [static]

Definition at line 1120 of file chan_unistim.c.

References AST_CAUSE_NETWORK_OUT_OF_ORDER, ast_free, ast_log(), ast_mutex_destroy, ast_mutex_lock, ast_mutex_unlock, ast_queue_hangup_with_cause(), ast_strlen_zero(), ast_verb, change_favorite_icon(), unistimsession::device, unistim_device::extension_number, FAV_ICON_NONE, unistim_device::lines, unistimsession::lock, LOG_WARNING, unistimsession::next, unistim_subchannel::owner, unistim_device::session, sessions, unistimsession::state, STATE_CLEANING, SUB_REAL, unistim_line::subs, and UnregisterExtension().

Referenced by parsing(), and send_retransmit().

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

static char* control2str ( int  ind  )  [static]

Definition at line 4087 of file chan_unistim.c.

References AST_CONTROL_ANSWER, AST_CONTROL_BUSY, AST_CONTROL_CONGESTION, AST_CONTROL_FLASH, AST_CONTROL_HANGUP, AST_CONTROL_OFFHOOK, AST_CONTROL_OPTION, AST_CONTROL_RADIO_KEY, AST_CONTROL_RADIO_UNKEY, AST_CONTROL_RING, AST_CONTROL_RINGING, AST_CONTROL_TAKEOFFHOOK, and AST_CONTROL_WINK.

Referenced by unistim_indicate().

04088 {
04089    switch (ind) {
04090    case AST_CONTROL_HANGUP:
04091       return "Other end has hungup";
04092    case AST_CONTROL_RING:
04093       return "Local ring";
04094    case AST_CONTROL_RINGING:
04095       return "Remote end is ringing";
04096    case AST_CONTROL_ANSWER:
04097       return "Remote end has answered";
04098    case AST_CONTROL_BUSY:
04099       return "Remote end is busy";
04100    case AST_CONTROL_TAKEOFFHOOK:
04101       return "Make it go off hook";
04102    case AST_CONTROL_OFFHOOK:
04103       return "Line is off hook";
04104    case AST_CONTROL_CONGESTION:
04105       return "Congestion (circuits busy)";
04106    case AST_CONTROL_FLASH:
04107       return "Flash hook";
04108    case AST_CONTROL_WINK:
04109       return "Wink";
04110    case AST_CONTROL_OPTION:
04111       return "Set a low-level option";
04112    case AST_CONTROL_RADIO_KEY:
04113       return "Key Radio";
04114    case AST_CONTROL_RADIO_UNKEY:
04115       return "Un-Key Radio";
04116    case -1:
04117       return "Stop tone";
04118    }
04119    return "UNKNOWN";
04120 }

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

Definition at line 875 of file chan_unistim.c.

References ast_calloc, ast_inet_ntoa(), ast_mutex_init, ast_mutex_lock, ast_mutex_unlock, ast_verb, unistimsession::buf, wsabuf::buf, get_tick_count(), get_to_address(), unistimsession::last_buf_available, unistimsession::last_seq_ack, unistimsession::lock, MAX_BUF_NUMBER, unistimsession::nb_retransmit, unistimsession::next, RETRANSMIT_TIMER, unistimsession::seq_phone, unistimsession::seq_server, sessions, unistimsession::sin, unistimsession::sout, unistimsession::state, STATE_INIT, unistimsession::tick_next_ping, unistimsession::timeout, and unistimsession::wsabufsend.

Referenced by parsing().

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

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

Definition at line 725 of file chan_unistim.c.

References ast_log(), errno, and LOG_WARNING.

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

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

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

Definition at line 4587 of file chan_unistim.c.

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

Referenced by restart_monitor().

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

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

Definition at line 4209 of file chan_unistim.c.

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

Referenced by unistim_request(), and unistim_sp().

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

static void finish_bookmark ( void   )  [static]

Definition at line 5053 of file chan_unistim.c.

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

Referenced by reload_config().

05054 {
05055    struct unistim_device *d = devices;
05056    int i;
05057    while (d) {
05058       for (i = 0; i < 6; i++) {
05059          if (d->softkeyicon[i] == 1) {   /* Something for us */
05060             struct unistim_device *d2 = devices;
05061             while (d2) {
05062                if (!strcmp(d->softkeydevice[i], d2->name)) {
05063                   d->sp[i] = d2;
05064                   d->softkeyicon[i] = 0;
05065                   break;
05066                }
05067                d2 = d2->next;
05068             }
05069             if (d->sp[i] == NULL)
05070                ast_log(LOG_NOTICE, "Bookmark entry with device %s not found\n",
05071                      d->softkeydevice[i]);
05072          }
05073       }
05074       d = d->next;
05075    }
05076 }

static unsigned int get_tick_count ( void   )  [static]

Definition at line 736 of file chan_unistim.c.

References ast_tvnow().

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

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

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

Definition at line 842 of file chan_unistim.c.

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

Referenced by create_client().

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

static void handle_dial_page ( struct unistimsession pte  )  [static]

Definition at line 2257 of file chan_unistim.c.

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

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

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

static void HandleCallIncoming ( struct unistimsession s  )  [static]

Definition at line 2472 of file chan_unistim.c.

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

Referenced by key_ringing(), and process_request().

02473 {
02474    struct unistim_subchannel *sub;
02475    s->state = STATE_CALL;
02476    s->device->missed_call = 0;
02477    send_no_ring(s);
02478    sub = s->device->lines->subs[SUB_REAL];
02479    if (!sub) {
02480       ast_log(LOG_NOTICE, "No available lines on: %s\n", s->device->name);
02481       return;
02482    } else if (unistimdebug)
02483       ast_verb(0, "Handle Call Incoming for %s@%s\n", sub->parent->name,
02484                s->device->name);
02485    start_rtp(sub);
02486    if (!sub->rtp)
02487       ast_log(LOG_WARNING, "Unable to create channel for %s@%s\n", sub->parent->name,
02488             s->device->name);
02489    ast_queue_control(sub->owner, AST_CONTROL_ANSWER);
02490    send_text(TEXT_LINE2, TEXT_NORMAL, s, "is on-line");
02491    send_text_status(s, "Hangup Transf");
02492    send_start_timer(s);
02493 
02494    if ((s->device->output == OUTPUT_HANDSET) &&
02495       (s->device->receiver_state == STATE_ONHOOK))
02496       send_select_output(s, OUTPUT_SPEAKER, s->device->volume, MUTE_OFF);
02497    else
02498       send_select_output(s, s->device->output, s->device->volume, MUTE_OFF);
02499    s->device->start_call_timestamp = time(0);
02500    write_history(s, 'i', 0);
02501    return;
02502 }

static void HandleCallOutgoing ( struct unistimsession s  )  [static]

Definition at line 2372 of file chan_unistim.c.

References alloc_sub(), AST_CAUSE_SWITCH_CONGESTION, ast_channel_stop_silence_generator(), ast_debug, ast_hangup(), ast_log(), ast_pthread_create, ast_queue_hangup_with_cause(), AST_STATE_DOWN, ast_verb, unistimsession::device, display_last_error(), unistim_device::height, unistim_device::lines, LOG_NOTICE, LOG_WARNING, unistim_device::moh, MUTE_OFF, unistim_line::name, unistim_device::name, unistim_device::output, unistim_subchannel::owner, unistim_subchannel::parent, unistim_device::phone_number, unistim_subchannel::rtp, send_select_output(), send_text(), send_text_status(), send_tone(), unistim_device::silence_generator, start_rtp(), unistimsession::state, STATE_CALL, SUB_REAL, SUB_THREEWAY, unistim_line::subs, unistim_subchannel::subtype, swap_subs(), TEXT_LINE0, TEXT_LINE1, TEXT_LINE2, TEXT_NORMAL, unistim_new(), unistim_ss(), and unistim_device::volume.

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

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

static void HandleSelectCodec ( struct unistimsession pte  )  [static]

Definition at line 2819 of file chan_unistim.c.

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

02820 {
02821    char buf[30], buf2[5];
02822 
02823    pte->state = STATE_SELECTCODEC;
02824    strcpy(buf, "Using codec ");
02825    sprintf(buf2, "%d", pte->device->codec_number);
02826    strcat(buf, buf2);
02827    strcat(buf, " (G711u=0,");
02828 
02829    send_text(TEXT_LINE0, TEXT_NORMAL, pte, buf);
02830    send_text(TEXT_LINE1, TEXT_NORMAL, pte, "G723=4,G711a=8,G729A=18)");
02831    send_text(TEXT_LINE2, TEXT_INVERSE, pte, SELECTCODEC_MSG);
02832    send_blink_cursor(pte);
02833    send_cursor_pos(pte, TEXT_LINE2 + SELECTCODEC_START_ENTRY_POS);
02834    pte->size_buff_entry = 0;
02835    send_text_status(pte, "Select BackSpcErase  Cancel");
02836    return;
02837 }

static void IgnoreCall ( struct unistimsession pte  )  [static]

Definition at line 1997 of file chan_unistim.c.

References send_no_ring().

Referenced by key_ringing().

01998 {
01999    send_no_ring(pte);
02000    return;
02001 }

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

Definition at line 4122 of file chan_unistim.c.

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

Referenced by unistim_indicate().

04124 {
04125    struct ast_tone_zone_sound *ts = NULL;
04126 
04127    if ((ts = ast_get_indication_tone(tz, indication))) {
04128       ast_playtones_start(ast, 0, ts->data, 1);
04129       ts = ast_tone_zone_sound_unref(ts);
04130    } else {
04131       ast_log(LOG_WARNING, "Unable to get indication tone for %s\n", indication);
04132    }
04133 }

static void init_phone_step2 ( struct unistimsession pte  )  [static]

Definition at line 3335 of file chan_unistim.c.

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

Referenced by process_request().

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

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

Definition at line 2576 of file chan_unistim.c.

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

Referenced by process_request().

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

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

Definition at line 2684 of file chan_unistim.c.

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

Referenced by key_main_page(), and process_request().

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

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

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

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

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

Definition at line 3173 of file chan_unistim.c.

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

Referenced by key_history(), and process_request().

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

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

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

02648 {
02649    if (keycode == KEY_FAV0 + pte->device->softkeylinepos) {
02650       HandleCallIncoming(pte);
02651       return;
02652    }
02653    switch (keycode) {
02654    case KEY_HANGUP:
02655    case KEY_FUNC4:
02656       IgnoreCall(pte);
02657       break;
02658    case KEY_FUNC1:
02659       HandleCallIncoming(pte);
02660       break;
02661    }
02662    return;
02663 }

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

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

02840 {
02841    if (keycode == KEY_FUNC2) {
02842       if (pte->size_buff_entry <= 1)
02843          keycode = KEY_FUNC3;
02844       else {
02845          pte->size_buff_entry -= 2;
02846          keycode = pte->buff_entry[pte->size_buff_entry] + 0x10;
02847       }
02848    }
02849    if ((keycode >= KEY_0) && (keycode <= KEY_9)) {
02850       char tmpbuf[] = SELECTCODEC_MSG;
02851       int i = 0;
02852 
02853       if (pte->size_buff_entry >= SELECTCODEC_MAX_LENGTH)
02854          return;
02855 
02856       while (i < pte->size_buff_entry) {
02857          tmpbuf[i + SELECTCODEC_START_ENTRY_POS] = pte->buff_entry[i];
02858          i++;
02859       }
02860       tmpbuf[i + SELECTCODEC_START_ENTRY_POS] = keycode - 0x10;
02861       pte->buff_entry[i] = keycode - 0x10;
02862       pte->size_buff_entry++;
02863       send_text(TEXT_LINE2, TEXT_INVERSE, pte, tmpbuf);
02864       send_blink_cursor(pte);
02865       send_cursor_pos(pte,
02866                  (unsigned char) (TEXT_LINE2 + SELECTCODEC_START_ENTRY_POS + 1 + i));
02867       return;
02868    }
02869 
02870    switch (keycode) {
02871    case KEY_FUNC1:
02872       if (pte->size_buff_entry == 1)
02873          pte->device->codec_number = pte->buff_entry[0] - 48;
02874       else if (pte->size_buff_entry == 2)
02875          pte->device->codec_number =
02876             ((pte->buff_entry[0] - 48) * 10) + (pte->buff_entry[1] - 48);
02877       show_main_page(pte);
02878       break;
02879    case KEY_FUNC3:
02880       pte->size_buff_entry = 0;
02881       send_text(TEXT_LINE2, TEXT_INVERSE, pte, SELECTCODEC_MSG);
02882       send_blink_cursor(pte);
02883       send_cursor_pos(pte, TEXT_LINE2 + SELECTCODEC_START_ENTRY_POS);
02884       break;
02885    case KEY_HANGUP:
02886    case KEY_FUNC4:
02887       show_main_page(pte);
02888       break;
02889    }
02890    return;
02891 }

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

Definition at line 2910 of file chan_unistim.c.

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

Referenced by process_request().

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

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

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

02666 {
02667    int fav;
02668 
02669    if ((keycode < KEY_FAV1) && (keycode > KEY_FAV5)) {
02670       ast_log(LOG_WARNING, "It's not a favorite key\n");
02671       return;
02672    }
02673    if (keycode == KEY_FAV0)
02674       return;
02675    fav = keycode - KEY_FAV0;
02676    if (pte->device->softkeyicon[fav] == 0)
02677       return;
02678    ast_copy_string(pte->device->phone_number, pte->device->softkeynumber[fav],
02679                sizeof(pte->device->phone_number));
02680    HandleCallOutgoing(pte);
02681    return;
02682 }

int load_module ( void   )  [static]

XXX

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

Definition at line 5666 of file chan_unistim.c.

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

05667 {
05668    int res;
05669 
05670    if (!(buff = ast_malloc(SIZE_PAGE)))
05671       goto buff_failed;
05672 
05673    io = io_context_create();
05674    if (!io) {
05675       ast_log(LOG_ERROR, "Failed to allocate IO context\n");
05676       goto io_failed;
05677    }
05678 
05679    sched = sched_context_create();
05680    if (!sched) {
05681       ast_log(LOG_ERROR, "Failed to allocate scheduler context\n");
05682       goto sched_failed;
05683    }
05684 
05685    res = reload_config();
05686    if (res)
05687       return AST_MODULE_LOAD_DECLINE;
05688 
05689    /* Make sure we can register our unistim channel type */
05690    if (ast_channel_register(&unistim_tech)) {
05691       ast_log(LOG_ERROR, "Unable to register channel type '%s'\n", channel_type);
05692       goto chanreg_failed;
05693    } 
05694 
05695    ast_rtp_glue_register(&unistim_rtp_glue);
05696 
05697    ast_cli_register_multiple(unistim_cli, ARRAY_LEN(unistim_cli));
05698 
05699    restart_monitor();
05700 
05701    return AST_MODULE_LOAD_SUCCESS;
05702 
05703 chanreg_failed:
05704    /*! XXX \todo Leaking anything allocated by reload_config() ... */
05705    sched_context_destroy(sched);
05706    sched = NULL;
05707 sched_failed:
05708    io_context_destroy(io);
05709    io = NULL;
05710 io_failed:
05711    ast_free(buff);
05712    buff = NULL;
05713 buff_failed:
05714    return AST_MODULE_LOAD_FAILURE;
05715 }

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

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

03076 {
03077    char tmp[AST_CONFIG_MAX_PATH];
03078    char count;
03079 
03080    snprintf(tmp, sizeof(tmp), "%s/%s/%s-%c.csv", ast_config_AST_LOG_DIR,
03081           USTM_LOG_DIR, pte->device->name, way);
03082    *f = fopen(tmp, "r");
03083    if (!*f) {
03084       display_last_error("Unable to open history file");
03085       return 0;
03086    }
03087    if (fread(&count, 1, 1, *f) != 1) {
03088       display_last_error("Unable to read history header - display.");
03089       fclose(*f);
03090       return 0;
03091    }
03092    if (count > MAX_ENTRY_LOG) {
03093       ast_log(LOG_WARNING, "Invalid count in history header of %s (%d max %d)\n", tmp,
03094             count, MAX_ENTRY_LOG);
03095       fclose(*f);
03096       return 0;
03097    }
03098    return count;
03099 }

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

Definition at line 4972 of file chan_unistim.c.

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

Referenced by build_device().

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

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

Definition at line 3515 of file chan_unistim.c.

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

Referenced by unistimsock_read().

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

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

Definition at line 3396 of file chan_unistim.c.

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

Referenced by parsing().

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

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

Definition at line 1523 of file chan_unistim.c.

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

Referenced by process_request().

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

static void rcv_resume_connection_with_server ( struct unistimsession pte  )  [static]

Definition at line 1452 of file chan_unistim.c.

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

Referenced by process_request().

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

static int ReformatNumber ( char *  number  )  [static]

Definition at line 3008 of file chan_unistim.c.

Referenced by key_history(), and show_entry_history().

03009 {
03010    int pos = 0, i = 0, size = strlen(number);
03011 
03012    for (; i < size; i++) {
03013       if ((number[i] >= '0') && (number[i] <= '9')) {
03014          if (i == pos) {
03015             pos++;
03016             continue;
03017          }
03018          number[pos] = number[i];
03019          pos++;
03020       }
03021    }
03022    number[pos] = 0;
03023    return pos;
03024 }

static void refresh_all_favorite ( struct unistimsession pte  )  [static]

Definition at line 1056 of file chan_unistim.c.

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

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

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

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

Definition at line 1099 of file chan_unistim.c.

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

Referenced by key_select_extension(), and rcv_mac_addr().

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

int reload ( void   )  [static]

reload: Part of Asterisk module interface ---

Definition at line 5746 of file chan_unistim.c.

References unistim_reload().

05747 {
05748    unistim_reload(NULL, 0, NULL);
05749    return 0;
05750 }

static int reload_config ( void   )  [static]

Definition at line 5378 of file chan_unistim.c.

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

Referenced by do_monitor(), and load_module().

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

static int restart_monitor ( void   )  [static]

Definition at line 4663 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, and LOG_WARNING.

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

04664 {
04665    pthread_attr_t attr;
04666    /* If we're supposed to be stopped -- stay stopped */
04667    if (monitor_thread == AST_PTHREADT_STOP)
04668       return 0;
04669    if (ast_mutex_lock(&monlock)) {
04670       ast_log(LOG_WARNING, "Unable to lock monitor\n");
04671       return -1;
04672    }
04673    if (monitor_thread == pthread_self()) {
04674       ast_mutex_unlock(&monlock);
04675       ast_log(LOG_WARNING, "Cannot kill myself\n");
04676       return -1;
04677    }
04678    if (monitor_thread != AST_PTHREADT_NULL) {
04679       /* Wake up the thread */
04680       pthread_kill(monitor_thread, SIGURG);
04681    } else {
04682       pthread_attr_init(&attr);
04683       pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE);
04684       /* Start a new monitor */
04685       if (ast_pthread_create(&monitor_thread, &attr, do_monitor, NULL) < 0) {
04686          ast_mutex_unlock(&monlock);
04687          ast_log(LOG_ERROR, "Unable to start monitor thread.\n");
04688          return -1;
04689       }
04690    }
04691    ast_mutex_unlock(&monlock);
04692    return 0;
04693 }

static void send_blink_cursor ( struct unistimsession pte  )  [static]

Definition at line 1429 of file chan_unistim.c.

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

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

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

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

Definition at line 801 of file chan_unistim.c.

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

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

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

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

Definition at line 1440 of file chan_unistim.c.

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

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

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

static void send_date_time ( struct unistimsession pte  )  [static]

Definition at line 1374 of file chan_unistim.c.

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

Referenced by rcv_mac_addr().

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

static void send_date_time2 ( struct unistimsession pte  )  [static]

Definition at line 1391 of file chan_unistim.c.

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

Referenced by init_phone_step2().

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

static void send_date_time3 ( struct unistimsession pte  )  [static]

Definition at line 1412 of file chan_unistim.c.

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

Referenced by init_phone_step2().

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

static void send_end_call ( struct unistimsession pte  )  [static]

Definition at line 911 of file chan_unistim.c.

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

Referenced by unistim_hangup().

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

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

Definition at line 1037 of file chan_unistim.c.

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

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

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

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

Definition at line 1265 of file chan_unistim.c.

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

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

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

static void send_no_ring ( struct unistimsession pte  )  [static]

Definition at line 1350 of file chan_unistim.c.

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

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

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

static void send_ping ( struct unistimsession pte  )  [static]

Definition at line 832 of file chan_unistim.c.

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

Referenced by do_monitor(), and init_phone_step2().

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

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

Definition at line 744 of file chan_unistim.c.

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

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

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

static int send_retransmit ( struct unistimsession pte  )  [static]

Definition at line 1170 of file chan_unistim.c.

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

Referenced by do_monitor(), and parsing().

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

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

Definition at line 1339 of file chan_unistim.c.

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

Referenced by unistim_call().

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

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

Definition at line 1279 of file chan_unistim.c.

References ast_log(), ast_verb, BUFFSEND, change_favorite_icon(), unistimsession::device, FAV_ICON_HEADPHONES, FAV_ICON_HEADPHONES_ONHOLD, FAV_ICON_OFFHOOK_BLACK, FAV_ICON_ONHOLD_BLACK, FAV_ICON_SPEAKER_OFFHOOK_BLACK, FAV_ICON_SPEAKER_ONHOLD_BLACK, FAV_ICON_SPEAKER_ONHOOK_BLACK, LOG_WARNING, unistim_device::mute, MUTE_OFF, MUTE_ON, MUTE_ON_DISCRET, unistim_device::output, OUTPUT_HANDSET, OUTPUT_HEADPHONE, OUTPUT_SPEAKER, unistim_device::previous_output, unistim_device::receiver_state, send_client(), send_led_update(), SIZE_HEADER, STATE_OFFHOOK, VOLUME_LOW, and VOLUME_LOW_SPEAKER.

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

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

static void send_start_timer ( struct unistimsession pte  )  [static]

Definition at line 954 of file chan_unistim.c.

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

Referenced by HandleCallIncoming(), and unistim_answer().

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

static void send_stop_timer ( struct unistimsession pte  )  [static]

Definition at line 963 of file chan_unistim.c.

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

Referenced by close_call().

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

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

Definition at line 1210 of file chan_unistim.c.

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

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

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

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

Definition at line 1227 of file chan_unistim.c.

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

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

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

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

Definition at line 1359 of file chan_unistim.c.

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

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

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

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

Definition at line 983 of file chan_unistim.c.

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

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

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

static void SendDialTone ( struct unistimsession pte  )  [static]

Definition at line 2228 of file chan_unistim.c.

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

Referenced by handle_dial_page().

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

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

Definition at line 972 of file chan_unistim.c.

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

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

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

static void set_ping_timer ( struct unistimsession pte  )  [static]

Definition at line 920 of file chan_unistim.c.

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

Referenced by check_send_queue().

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

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

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

03027 {
03028    char line[TEXT_LENGTH_MAX + 1], status[STATUS_LENGTH_MAX + 1], func1[10], func2[10],
03029       func3[10];
03030 
03031    if (fread(line, TEXT_LENGTH_MAX, 1, *f) != 1) {
03032       display_last_error("Can't read history date entry");
03033       fclose(*f);
03034       return;
03035    }
03036    line[sizeof(line) - 1] = '\0';
03037    send_text(TEXT_LINE0, TEXT_NORMAL, pte, line);
03038    if (fread(line, TEXT_LENGTH_MAX, 1, *f) != 1) {
03039       display_last_error("Can't read callerid entry");
03040       fclose(*f);
03041       return;
03042    }
03043    line[sizeof(line) - 1] = '\0';
03044    ast_copy_string(pte->device->lst_cid, line, sizeof(pte->device->lst_cid));
03045    send_text(TEXT_LINE1, TEXT_NORMAL, pte, line);
03046    if (fread(line, TEXT_LENGTH_MAX, 1, *f) != 1) {
03047       display_last_error("Can't read callername entry");
03048       fclose(*f);
03049       return;
03050    }
03051    line[sizeof(line) - 1] = '\0';
03052    send_text(TEXT_LINE2, TEXT_NORMAL, pte, line);
03053    fclose(*f);
03054 
03055    snprintf(line, sizeof(line), "Call %03d/%03d", pte->buff_entry[2],
03056           pte->buff_entry[1]);
03057    send_texttitle(pte, line);
03058 
03059    if (pte->buff_entry[2] == 1)
03060       strcpy(func1, "       ");
03061    else
03062       strcpy(func1, "Prvious");
03063    if (pte->buff_entry[2] >= pte->buff_entry[1])
03064       strcpy(func2, "       ");
03065    else
03066       strcpy(func2, "Next   ");
03067    if (ReformatNumber(pte->device->lst_cid))
03068       strcpy(func3, "Redial ");
03069    else
03070       strcpy(func3, "       ");
03071    snprintf(status, sizeof(status), "%s%s%sCancel", func1, func2, func3);
03072    send_text_status(pte, status);
03073 }

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

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

03102 {
03103    FILE *f;
03104    char count;
03105 
03106    if (!pte->device)
03107       return;
03108    if (!pte->device->callhistory)
03109       return;
03110    count = OpenHistory(pte, way, &f);
03111    if (!count)
03112       return;
03113    pte->buff_entry[0] = way;
03114    pte->buff_entry[1] = count;
03115    pte->buff_entry[2] = 1;
03116    show_entry_history(pte, &f);
03117    pte->state = STATE_HISTORY;
03118 }

static void show_main_page ( struct unistimsession pte  )  [static]

Definition at line 3120 of file chan_unistim.c.

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

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

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

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

Definition at line 2024 of file chan_unistim.c.

References ast_best_codec(), AST_FORMAT_ALAW, AST_FORMAT_G723_1, AST_FORMAT_G729A, AST_FORMAT_ULAW, ast_getformatname(), ast_getformatname_multiple(), ast_inet_ntoa(), ast_log(), ast_mutex_lock, ast_mutex_unlock, ast_rtp_codecs_payload_code(), ast_rtp_instance_fd(), ast_rtp_instance_get_codecs(), ast_rtp_instance_get_local_address(), ast_rtp_instance_new(), ast_rtp_instance_set_prop(), ast_rtp_instance_set_qos(), ast_rtp_instance_set_remote_address(), AST_RTP_PROPERTY_NAT, AST_RTP_PROPERTY_RTCP, ast_sockaddr_from_sin, ast_sockaddr_to_sin, ast_verb, BUFFSEND, errno, ast_channel::fds, unistim_subchannel::lock, LOG_WARNING, unistim_device::nat, ast_channel::nativeformats, unistim_subchannel::owner, unistim_line::parent, unistim_subchannel::parent, qos, ast_channel::readformat, unistim_subchannel::rtp, unistim_device::rtp_method, unistim_device::rtp_port, send_client(), unistim_device::session, unistimsession::sin, SIZE_HEADER, unistimsession::sout, and ast_channel::writeformat.

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

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

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

Definition at line 1867 of file chan_unistim.c.

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

Referenced by HandleCallOutgoing(), and unistim_hangup().

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

static void TransferCallStep1 ( struct unistimsession pte  )  [static]

Definition at line 2326 of file chan_unistim.c.

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

Referenced by key_call().

02327 {
02328    struct unistim_subchannel *sub;
02329    struct unistim_line *p = pte->device->lines;
02330 
02331    sub = p->subs[SUB_REAL];
02332 
02333    if (!sub->owner) {
02334       ast_log(LOG_WARNING, "Unable to find subchannel for music on hold\n");
02335       return;
02336    }
02337    if (p->subs[SUB_THREEWAY]) {
02338       if (unistimdebug)
02339          ast_verb(0, "Transfer canceled, hangup our threeway channel\n");
02340       if (p->subs[SUB_THREEWAY]->owner)
02341          ast_queue_hangup_with_cause(p->subs[SUB_THREEWAY]->owner, AST_CAUSE_NORMAL_CLEARING);
02342       else
02343          ast_log(LOG_WARNING, "Canceling a threeway channel without owner\n");
02344       return;
02345    }
02346    /* Start music on hold if appropriate */
02347    if (pte->device->moh)
02348       ast_log(LOG_WARNING, "Transfer with peer already listening music on hold\n");
02349    else {
02350       if (ast_bridged_channel(p->subs[SUB_REAL]->owner)) {
02351          ast_moh_start(ast_bridged_channel(p->subs[SUB_REAL]->owner),
02352                     pte->device->lines->musicclass, NULL);
02353          pte->device->moh = 1;
02354       } else {
02355          ast_log(LOG_WARNING, "Unable to find peer subchannel for music on hold\n");
02356          return;
02357       }
02358    }
02359    /* Silence our channel */
02360    if (!pte->device->silence_generator) {
02361       pte->device->silence_generator =
02362          ast_channel_start_silence_generator(p->subs[SUB_REAL]->owner);
02363       if (pte->device->silence_generator == NULL)
02364          ast_log(LOG_WARNING, "Unable to start a silence generator.\n");
02365       else if (unistimdebug)
02366          ast_verb(0, "Starting silence generator\n");
02367    }
02368    handle_dial_page(pte);
02369 }

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

Definition at line 1507 of file chan_unistim.c.

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

Referenced by unistim_hangup().

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

static int unistim_answer ( struct ast_channel ast  )  [static]

Definition at line 3876 of file chan_unistim.c.

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

03877 {
03878    int res = 0;
03879    struct unistim_subchannel *sub;
03880    struct unistim_line *l;
03881    struct unistimsession *s;
03882 
03883    s = channel_to_session(ast);
03884    if (!s) {
03885       ast_log(LOG_WARNING, "unistim_answer on a disconnected device ?\n");
03886       return -1;
03887    }
03888    sub = ast->tech_pvt;
03889    l = sub->parent;
03890 
03891    if ((!sub->rtp) && (!l->subs[SUB_THREEWAY]))
03892       start_rtp(sub);
03893    if (unistimdebug)
03894       ast_verb(0, "unistim_answer(%s) on %s@%s-%u\n", ast->name, l->name,
03895                l->parent->name, sub->subtype);
03896    send_text(TEXT_LINE2, TEXT_NORMAL, l->parent->session, "is now on-line");
03897    if (l->subs[SUB_THREEWAY])
03898       send_text_status(l->parent->session, "Transf Cancel");
03899    else
03900       send_text_status(l->parent->session, "Hangup Transf");
03901    send_start_timer(l->parent->session);
03902    if (ast->_state != AST_STATE_UP)
03903       ast_setstate(ast, AST_STATE_UP);
03904    return res;
03905 }

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

Definition at line 3700 of file chan_unistim.c.

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

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

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

Definition at line 4883 of file chan_unistim.c.

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

04884 {
04885    switch (cmd) {
04886    case CLI_INIT:
04887       e->command = "unistim set debug {on|off}";
04888       e->usage =
04889          "Usage: unistim set debug\n" 
04890          "       Display debug messages.\n";
04891       return NULL;
04892 
04893    case CLI_GENERATE:
04894       return NULL;   /* no completion */
04895    }
04896 
04897    if (a->argc != e->args)
04898       return CLI_SHOWUSAGE;
04899 
04900    if (!strcasecmp(a->argv[3], "on")) {
04901       unistimdebug = 1;
04902       ast_cli(a->fd, "UNISTIM Debugging Enabled\n");
04903    } else if (!strcasecmp(a->argv[3], "off")) {
04904       unistimdebug = 0;
04905       ast_cli(a->fd, "UNISTIM Debugging Disabled\n");
04906    } else
04907       return CLI_SHOWUSAGE;
04908 
04909    return CLI_SUCCESS;
04910 }

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

Definition at line 2504 of file chan_unistim.c.

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

Referenced by key_call(), and unistim_senddigit_begin().

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

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

Definition at line 4062 of file chan_unistim.c.

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

04063 {
04064    struct unistim_subchannel *p = newchan->tech_pvt;
04065    struct unistim_line *l = p->parent;
04066 
04067    ast_mutex_lock(&p->lock);
04068 
04069    ast_debug(1, "New owner for channel USTM/%s@%s-%u is %s\n", l->name,
04070          l->parent->name, p->subtype, newchan->name);
04071 
04072    if (p->owner != oldchan) {
04073       ast_log(LOG_WARNING, "old channel wasn't %s (%p) but was %s (%p)\n",
04074             oldchan->name, oldchan, p->owner->name, p->owner);
04075       ast_mutex_unlock(&p->lock);
04076       return -1;
04077    }
04078 
04079    p->owner = newchan;
04080 
04081    ast_mutex_unlock(&p->lock);
04082 
04083    return 0;
04084 
04085 }

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

Definition at line 5614 of file chan_unistim.c.

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

05615 {
05616    struct unistim_subchannel *sub = chan->tech_pvt;
05617 
05618    if (!sub) {
05619       return AST_RTP_GLUE_RESULT_FORBID;
05620    }
05621    if (!sub->rtp) {
05622       return AST_RTP_GLUE_RESULT_FORBID;
05623    }
05624 
05625    ao2_ref(sub->rtp, +1);
05626    *instance = sub->rtp;
05627 
05628    return AST_RTP_GLUE_RESULT_LOCAL;
05629 }

static int unistim_hangup ( struct ast_channel ast  )  [static]

Definition at line 3770 of file chan_unistim.c.

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

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

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

Definition at line 4135 of file chan_unistim.c.

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

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

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

Definition at line 4753 of file chan_unistim.c.

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

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

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

Protos

Definition at line 4493 of file chan_unistim.c.

References unistim_line::accountcode, ast_channel::adsicpe, unistim_line::amaflags, AST_ADSI_UNAVAILABLE, ast_best_codec(), ast_callerid_parse(), ast_channel_alloc, ast_free, ast_getformatname(), ast_getformatname_multiple(), ast_hangup(), ast_jb_configure(), ast_log(), ast_mutex_lock, ast_mutex_unlock, ast_pbx_start(), ast_rtp_instance_fd(), ast_setstate(), AST_STATE_DOWN, AST_STATE_RING, ast_strdup, ast_string_field_set, ast_strlen_zero(), ast_update_use_count(), ast_verb, unistim_device::call_forward, ast_channel::caller, unistim_line::callgroup, ast_channel::callgroup, CAPABILITY, unistim_line::capability, unistim_line::cid_num, unistim_line::context, unistim_line::exten, ast_channel::fds, global_jbconf, ast_party_caller::id, language, unistim_line::language, LOG_WARNING, ast_party_id::name, name, unistim_device::name, unistim_line::name, ast_channel::nativeformats, ast_party_id::number, unistim_subchannel::owner, unistim_line::parent, unistim_subchannel::parent, unistim_line::pickupgroup, ast_channel::pickupgroup, ast_channel::priority, ast_channel::rawreadformat, ast_channel::rawwriteformat, ast_channel::readformat, ast_channel::rings, unistim_subchannel::rtp, ast_party_name::str, ast_party_number::str, unistim_subchannel::subtype, ast_channel::tech, ast_channel::tech_pvt, ast_party_name::valid, ast_party_number::valid, and ast_channel::writeformat.

Referenced by HandleCallOutgoing(), and unistim_request().

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

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

Definition at line 4013 of file chan_unistim.c.

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

04014 {
04015    struct ast_frame *fr;
04016    struct unistim_subchannel *sub = ast->tech_pvt;
04017 
04018    ast_mutex_lock(&sub->lock);
04019    fr = unistim_rtp_read(ast, sub);
04020    ast_mutex_unlock(&sub->lock);
04021 
04022    return fr;
04023 }

static int unistim_register ( struct unistimsession s  )  [static]

Definition at line 1465 of file chan_unistim.c.

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

Referenced by rcv_mac_addr().

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

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

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

Definition at line 4916 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(), and ast_cli_entry::usage.

Referenced by reload().

04917 {
04918    switch (cmd) {
04919    case CLI_INIT:
04920       e->command = "unistim reload";
04921       e->usage =
04922          "Usage: unistim reload\n" 
04923          "       Reloads UNISTIM configuration from unistim.conf\n";
04924       return NULL;
04925 
04926    case CLI_GENERATE:
04927       return NULL;   /* no completion */
04928    }
04929 
04930    if (e && a && a->argc != e->args)
04931       return CLI_SHOWUSAGE;
04932 
04933    if (unistimdebug)
04934       ast_verb(0, "reload unistim\n");
04935 
04936    ast_mutex_lock(&unistim_reload_lock);
04937    if (!unistim_reloading)
04938       unistim_reloading = 1;
04939    ast_mutex_unlock(&unistim_reload_lock);
04940 
04941    restart_monitor();
04942 
04943    return CLI_SUCCESS;
04944 }

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

Definition at line 4697 of file chan_unistim.c.

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

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

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

Definition at line 3966 of file chan_unistim.c.

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

Referenced by unistim_read().

03968 {
03969    /* Retrieve audio/etc from channel.  Assumes sub->lock is already held. */
03970    struct ast_frame *f;
03971 
03972    if (!ast) {
03973       ast_log(LOG_WARNING, "Channel NULL while reading\n");
03974       return &ast_null_frame;
03975    }
03976 
03977    if (!sub->rtp) {
03978       ast_log(LOG_WARNING, "RTP handle NULL while reading on subchannel %u\n",
03979             sub->subtype);
03980       return &ast_null_frame;
03981    }
03982 
03983    switch (ast->fdno) {
03984    case 0:
03985       f = ast_rtp_instance_read(sub->rtp, 0);     /* RTP Audio */
03986       break;
03987    case 1:
03988       f = ast_rtp_instance_read(sub->rtp, 1);    /* RTCP Control Channel */
03989       break;
03990    default:
03991       f = &ast_null_frame;
03992    }
03993 
03994    if (sub->owner) {
03995       /* We already hold the channel lock */
03996       if (f->frametype == AST_FRAME_VOICE) {
03997          if (f->subclass.codec != sub->owner->nativeformats) {
03998             ast_debug(1,
03999                   "Oooh, format changed from %s to %s\n",
04000                   ast_getformatname(sub->owner->nativeformats),
04001                   ast_getformatname(f->subclass.codec));
04002 
04003             sub->owner->nativeformats = f->subclass.codec;
04004             ast_set_read_format(sub->owner, sub->owner->readformat);
04005             ast_set_write_format(sub->owner, sub->owner->writeformat);
04006          }
04007       }
04008    }
04009 
04010    return f;
04011 }

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

Definition at line 4450 of file chan_unistim.c.

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

Referenced by do_monitor().

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

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

Definition at line 4276 of file chan_unistim.c.

References channel_to_session(), and unistim_do_senddigit().

04277 {
04278    struct unistimsession *pte = channel_to_session(ast);
04279 
04280    if (!pte)
04281       return -1;
04282 
04283    return unistim_do_senddigit(pte, digit);
04284 }

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

Definition at line 4286 of file chan_unistim.c.

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

04287 {
04288    struct unistimsession *pte = channel_to_session(ast);
04289    struct ast_frame f = { 0, };
04290    struct unistim_subchannel *sub;
04291 
04292    sub = pte->device->lines->subs[SUB_REAL];
04293 
04294    if (!sub->owner || sub->alreadygone) {
04295       ast_log(LOG_WARNING, "Unable to find subchannel in dtmf senddigit_end\n");
04296       return -1;
04297    }
04298 
04299    if (unistimdebug)
04300       ast_verb(0, "Send Digit off %c\n", digit);
04301 
04302    if (!pte)
04303       return -1;
04304 
04305    send_tone(pte, 0, 0);
04306    f.frametype = AST_FRAME_DTMF;
04307    f.subclass.integer = digit;
04308    f.src = "unistim";
04309    ast_queue_frame(sub->owner, &f);
04310 
04311    return 0;
04312 }

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

Definition at line 4316 of file chan_unistim.c.

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

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

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

Definition at line 5631 of file chan_unistim.c.

References ast_log(), ast_rtp_instance_get_local_address(), ast_rtp_instance_get_remote_address(), ast_sockaddr_to_sin, LOG_ERROR, and ast_channel::tech_pvt.

05632 {
05633    struct unistim_subchannel *sub;
05634    struct sockaddr_in them = { 0, };
05635    struct sockaddr_in us = { 0, };
05636 
05637    if (!rtp) {
05638       return 0;
05639    }
05640    
05641    sub = chan->tech_pvt;
05642    if (!sub) {
05643       ast_log(LOG_ERROR, "No Private Structure, this is bad\n");
05644       return -1;
05645    }
05646    {
05647       struct ast_sockaddr tmp;
05648       ast_rtp_instance_get_remote_address(rtp, &tmp);
05649       ast_sockaddr_to_sin(&tmp, &them);
05650       ast_rtp_instance_get_local_address(rtp, &tmp);
05651       ast_sockaddr_to_sin(&tmp, &us);
05652    }
05653    
05654    /* TODO: Set rtp on phone in case of direct rtp (not implemented) */
05655    
05656    return 0;
05657 }

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

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

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

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

Definition at line 2003 of file chan_unistim.c.

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

Referenced by HandleCallOutgoing().

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

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

Definition at line 4025 of file chan_unistim.c.

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

04026 {
04027    struct unistim_subchannel *sub = ast->tech_pvt;
04028    int res = 0;
04029 
04030    if (frame->frametype != AST_FRAME_VOICE) {
04031       if (frame->frametype == AST_FRAME_IMAGE)
04032          return 0;
04033       else {
04034          ast_log(LOG_WARNING, "Can't send %u type frames with unistim_write\n",
04035                frame->frametype);
04036          return 0;
04037       }
04038    } else {
04039       if (!(frame->subclass.codec & ast->nativeformats)) {
04040          char tmp[256];
04041          ast_log(LOG_WARNING,
04042                "Asked to transmit frame type %s, while native formats is %s (read/write = (%s/%s)\n",
04043                ast_getformatname(frame->subclass.codec),
04044                ast_getformatname_multiple(tmp, sizeof(tmp), ast->nativeformats),
04045                ast_getformatname(ast->readformat),
04046                ast_getformatname(ast->writeformat));
04047          return -1;
04048       }
04049    }
04050 
04051    if (sub) {
04052       ast_mutex_lock(&sub->lock);
04053       if (sub->rtp) {
04054          res = ast_rtp_instance_write(sub->rtp, frame);
04055       }
04056       ast_mutex_unlock(&sub->lock);
04057    }
04058 
04059    return res;
04060 }

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

Definition at line 3909 of file chan_unistim.c.

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

Referenced by do_monitor().

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

static int unload_module ( void   )  [static]

Definition at line 5717 of file chan_unistim.c.

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

05718 {
05719    /* First, take us out of the channel loop */
05720    if (sched)
05721       sched_context_destroy(sched);
05722 
05723    ast_cli_unregister_multiple(unistim_cli, ARRAY_LEN(unistim_cli));
05724 
05725    ast_channel_unregister(&unistim_tech);
05726    ast_rtp_glue_unregister(&unistim_rtp_glue);
05727 
05728    ast_mutex_lock(&monlock);
05729    if (monitor_thread && (monitor_thread != AST_PTHREADT_STOP) && (monitor_thread != AST_PTHREADT_NULL)) {
05730       pthread_cancel(monitor_thread);
05731       pthread_kill(monitor_thread, SIGURG);
05732       pthread_join(monitor_thread, NULL);
05733    }
05734    monitor_thread = AST_PTHREADT_STOP;
05735    ast_mutex_unlock(&monlock);
05736 
05737    if (buff)
05738       ast_free(buff);
05739    if (unistimsock > -1)
05740       close(unistimsock);
05741 
05742    return 0;
05743 }

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

Definition at line 4953 of file chan_unistim.c.

References len().

Referenced by build_device().

04954 {
04955    int len = strlen(src);
04956    if (!len)
04957       return;
04958    if ((len > 1) && src[0] == '\"') {
04959       /* This is a quoted string */
04960       src++;
04961       /* Don't take more than what's there */
04962       len--;
04963       if (maxlen > len - 1)
04964          maxlen = len - 1;
04965       memcpy(out, src, maxlen);
04966       ((char *) out)[maxlen] = '\0';
04967    } else
04968       memcpy(out, src, maxlen);
04969    return;
04970 }

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

Definition at line 1110 of file chan_unistim.c.

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

Referenced by close_client(), and key_main_page().

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

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

Definition at line 1684 of file chan_unistim.c.

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

Referenced by write_history().

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

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

Definition at line 1705 of file chan_unistim.c.

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

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

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


Variable Documentation

struct sockaddr_in address_from [static]

give the IP address for the last packet received

Definition at line 228 of file chan_unistim.c.

enum autoprovision autoprovisioning = AUTOPROVISIONING_NO [static]

Definition at line 213 of file chan_unistim.c.

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

Definition at line 678 of file chan_unistim.c.

unsigned int cos

Definition at line 220 of file chan_unistim.c.

unsigned int cos_audio

Definition at line 221 of file chan_unistim.c.

struct ast_jb_conf default_jbconf [static]

Global jitterbuffer configuration - by default, jb is disabled.

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

Definition at line 195 of file chan_unistim.c.

struct unistim_device * devices [static]
struct tone_zone_unistim frequency[] [static]

Definition at line 316 of file chan_unistim.c.

struct ast_jb_conf global_jbconf [static]

Definition at line 203 of file chan_unistim.c.

Referenced by reload_config(), and unistim_new().

struct io_context* io [static]

Definition at line 224 of file chan_unistim.c.

pthread_t monitor_thread = AST_PTHREADT_NULL [static]

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

Definition at line 241 of file chan_unistim.c.

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

Definition at line 511 of file chan_unistim.c.

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

Definition at line 516 of file chan_unistim.c.

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

Definition at line 522 of file chan_unistim.c.

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

Definition at line 529 of file chan_unistim.c.

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

Definition at line 520 of file chan_unistim.c.

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

Definition at line 518 of file chan_unistim.c.

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

Definition at line 524 of file chan_unistim.c.

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

TransportAdapter

Definition at line 527 of file chan_unistim.c.

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

Definition at line 624 of file chan_unistim.c.

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

Definition at line 625 of file chan_unistim.c.

const unsigned char packet_send_call[] [static]

Definition at line 552 of file chan_unistim.c.

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

Definition at line 629 of file chan_unistim.c.

const unsigned char packet_send_date_time[] [static]

Definition at line 536 of file chan_unistim.c.

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

Definition at line 626 of file chan_unistim.c.

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

Definition at line 532 of file chan_unistim.c.

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

Definition at line 513 of file chan_unistim.c.

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

Definition at line 580 of file chan_unistim.c.

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

Definition at line 642 of file chan_unistim.c.

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

Definition at line 635 of file chan_unistim.c.

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

Definition at line 590 of file chan_unistim.c.

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

Definition at line 665 of file chan_unistim.c.

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

Definition at line 543 of file chan_unistim.c.

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

Definition at line 599 of file chan_unistim.c.

const unsigned char packet_send_open_audio_stream_rx3[] [static]

Definition at line 610 of file chan_unistim.c.

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

Definition at line 604 of file chan_unistim.c.

const unsigned char packet_send_open_audio_stream_tx3[] [static]

Definition at line 617 of file chan_unistim.c.

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

Definition at line 672 of file chan_unistim.c.

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

Definition at line 667 of file chan_unistim.c.

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

Definition at line 669 of file chan_unistim.c.

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

Definition at line 668 of file chan_unistim.c.

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

Definition at line 575 of file chan_unistim.c.

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

Definition at line 588 of file chan_unistim.c.

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

Definition at line 670 of file chan_unistim.c.

const unsigned char packet_send_s4[] [static]

Definition at line 545 of file chan_unistim.c.

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

Definition at line 636 of file chan_unistim.c.

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

Definition at line 585 of file chan_unistim.c.

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

Definition at line 573 of file chan_unistim.c.

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

Definition at line 637 of file chan_unistim.c.

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

Definition at line 631 of file chan_unistim.c.

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

Definition at line 656 of file chan_unistim.c.

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

Definition at line 661 of file chan_unistim.c.

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

Definition at line 634 of file chan_unistim.c.

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

Definition at line 571 of file chan_unistim.c.

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

Definition at line 561 of file chan_unistim.c.

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

Definition at line 567 of file chan_unistim.c.

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

Definition at line 569 of file chan_unistim.c.

const unsigned char packet_send_text[] [static]

Definition at line 650 of file chan_unistim.c.

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

Definition at line 647 of file chan_unistim.c.

struct sockaddr_in public_ip = { 0, } [static]

Definition at line 226 of file chan_unistim.c.

struct { ... } qos [static]

Referenced by reload_config(), and start_rtp().

struct sched_context* sched [static]

Definition at line 225 of file chan_unistim.c.

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

size of the sockaddr_in (in WSARecvFrom)

Definition at line 230 of file chan_unistim.c.

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

Definition at line 677 of file chan_unistim.c.

unsigned int tos

Definition at line 218 of file chan_unistim.c.

unsigned int tos_audio

Definition at line 219 of file chan_unistim.c.

struct ast_cli_entry unistim_cli[] [static]

Definition at line 4946 of file chan_unistim.c.

int unistim_keepalive [static]

Definition at line 214 of file chan_unistim.c.

int unistim_port [static]

Definition at line 212 of file chan_unistim.c.

int unistim_reloading = 0 [static]

Definition at line 233 of file chan_unistim.c.

struct ast_rtp_glue unistim_rtp_glue [static]
Initial value:
 {
   .type = channel_type,
   .get_rtp_info = unistim_get_rtp_peer,
   .update_peer = unistim_set_rtp_peer,
}

Definition at line 5659 of file chan_unistim.c.

struct ast_channel_tech unistim_tech [static]

Definition at line 706 of file chan_unistim.c.

int unistimdebug = 0 [static]

Enable verbose output. can also be set with the CLI

Definition at line 211 of file chan_unistim.c.

int unistimsock = -1 [static]

Definition at line 215 of file chan_unistim.c.

int usecnt = 0 [static]

Definition at line 236 of file chan_unistim.c.


Generated on 17 Aug 2018 for Asterisk - The Open Source Telephony Project by  doxygen 1.6.1