Asterisk - The Open Source Telephony Project GIT-master-5467495
Loading...
Searching...
No Matches
Data Structures | Macros | Enumerations | Functions | Variables
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/rtp_engine.h"
#include "asterisk/unaligned.h"
#include "asterisk/netsock2.h"
#include "asterisk/acl.h"
#include "asterisk/callerid.h"
#include "asterisk/cli.h"
#include "asterisk/app.h"
#include "asterisk/mwi.h"
#include "asterisk/musiconhold.h"
#include "asterisk/causes.h"
#include "asterisk/indications.h"
#include "asterisk/pickup.h"
#include "asterisk/astobj2.h"
#include "asterisk/astdb.h"
#include "asterisk/features_config.h"
#include "asterisk/bridge.h"
#include "asterisk/stasis_channels.h"
#include "asterisk/format_cache.h"
Include dependency graph for chan_unistim.c:

Go to the source code of this file.

Data Structures

struct  unistim_device
 A device containing one or more lines. More...
 
struct  unistim_languages
 
struct  unistim_line
 
struct  unistim_menu_item
 
struct  unistim_subchannel
 
struct  unistimsession
 
struct  ustm_lang_entry
 
struct  wsabuf
 

Macros

#define AST_CONFIG_MAX_PATH   255
 
#define BUFFSEND   unsigned char buffsend[64] = { 0x00, 0x00, 0xaa, 0xbb, 0x02, 0x01 }
 
#define DEBUG_TIMER   dummy
 
#define DEFAULT_CODEC   0x00
 
#define DEFAULT_INTERDIGIT_TIMER   4000
 
#define DEFAULTCALLERID   "Unknown"
 
#define DEFAULTCALLERNAME   " "
 
#define DEFAULTCONTEXT   "default"
 
#define DEFAULTHEIGHT   3
 
#define DEVICE_NAME_LEN   16
 
#define EXPNUM   24
 
#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_LINE_ICON   FAV_ICON_ONHOOK_BLACK
 
#define FAV_MAX_LENGTH   0x0A
 
#define FAVNUM   6
 
#define IDLE_WAIT   1000
 
#define LED_BAR_OFF   0x00 /* bar off */
 
#define LED_BAR_ON   0x01 /* bar on */
 
#define LED_BAR_P2   0x02 /* bar 1s on/1s */
 
#define LED_BAR_P3   0x03 /* bar 2.5s on/0.5s off */
 
#define LED_BAR_P4   0x04 /* bar 0.6s on/0.3s off */
 
#define LED_BAR_P5   0x05 /* bar 0.5s on/0.5s off */
 
#define LED_BAR_P6   0x06 /* bar 2s on/0.5s off */
 
#define LED_BAR_P7   0x07 /* bar off */
 
#define LED_HEADPHONE_OFF   0x010
 
#define LED_HEADPHONE_ON   0x011
 
#define LED_MUTE_BLINK   0x1A
 
#define LED_MUTE_OFF   0x018
 
#define LED_MUTE_ON   0x019
 
#define LED_SPEAKER_OFF   0x08
 
#define LED_SPEAKER_ON   0x09
 
#define MAX_BUF_NUMBER   150
 
#define MAX_BUF_SIZE   64
 
#define MAX_ENTRY_LOG   30
 
#define MAX_PHONE_NUMBER_LENGTH   (AST_MAX_EXTENSION - 1)
 
#define MAX_SCREEN_NUMBER   15
 
#define MONTH_LABEL_SIZE   3
 
#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_RING   1
 
#define SUB_THREEWAY   2
 
#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   5000
 
#define USTM_LANG_DIR   "unistimLang"
 
#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_TN }
 
enum  charset {
  LANG_DEFAULT , ISO_8859_1 , ISO_8859_2 , ISO_8859_4 ,
  ISO_8859_5 , ISO_2022_JP
}
 
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_SELECTOPTION ,
  STATE_SELECTCODEC , STATE_SELECTLANGUAGE , STATE_CLEANING , STATE_HISTORY
}
 

Functions

static void __reg_module (void)
 
static void __unreg_module (void)
 
struct ast_moduleAST_MODULE_SELF_SYM (void)
 
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 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 delete_device (struct unistim_device *d)
 
static void discard_call (struct unistimsession *pte)
 
static void display_last_error (const char *sz_msg)
 
static void * do_monitor (void *data)
 
static void dummy (char *unused,...)
 
static int find_language (const char *)
 
static struct unistim_linefind_line_by_number (struct unistim_device *d, const char *val)
 
static int find_rtp_port (struct unistim_subchannel *s)
 
static struct unistim_subchannelfind_subchannel_by_name (const char *dest)
 
static void finish_bookmark (void)
 
static int get_active_softkey (struct unistimsession *pte)
 
static int get_avail_softkey (struct unistimsession *pte, const char *name)
 
static struct unistim_subchannelget_sub (struct unistim_device *device, int type)
 
static struct unistim_subchannelget_sub_holding (struct unistim_device *device, int type, int holding)
 
static unsigned int get_tick_count (void)
 
static int get_to_address (int fd, struct sockaddr_in *toAddr)
 
static void handle_call_incoming (struct unistimsession *s)
 
static void handle_call_outgoing (struct unistimsession *s)
 
static void handle_dial_page (struct unistimsession *pte)
 
static void handle_key_fav (struct unistimsession *pte, char keycode)
 
static void handle_select_codec (struct unistimsession *)
 
static void handle_select_language (struct unistimsession *)
 
static void handle_select_option (struct unistimsession *pte)
 
static void ignore_call (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 int is_key_favorite (struct unistim_device *d, int fav)
 
static int is_key_line (struct unistim_device *d, int fav)
 
static void key_call (struct unistimsession *pte, char keycode)
 
static void key_dial_page (struct unistimsession *pte, char keycode)
 
static void key_favorite (struct unistimsession *, char)
 
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 key_select_language (struct unistimsession *pte, char keycode)
 
static void key_select_option (struct unistimsession *pte, char keycode)
 
static int lang_cmp_fn (void *obj, void *arg, int flags)
 
static int lang_hash_fn (const void *obj, const int flags)
 
static int load_module (void)
 
static void microphone_mute_toggle (struct unistimsession *pte)
 
static char open_history (struct unistimsession *pte, char way, FILE **f)
 
static int parse_bookmark (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 const char * ptestate_tostr (const int type)
 
static void rcv_mac_addr (struct unistimsession *pte, const unsigned char *buf)
 
static void rcv_resume_connection_with_server (struct unistimsession *pte)
 
static void refresh_all_favorite (struct unistimsession *pte)
 
static int register_extension (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_callerid_screen (struct unistimsession *, struct unistim_subchannel *)
 
static void send_charset_update (struct unistimsession *pte, int charset)
 
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_dial_tone (struct unistimsession *pte)
 
static int send_dtmf_tone (struct unistimsession *pte, char digit)
 
static void send_end_call (struct unistimsession *pte)
 
static void send_expansion_icon (unsigned char pos, unsigned char status, struct unistimsession *pte)
 
static void send_expansion_next (struct unistimsession *pte)
 
static void send_expansion_short (unsigned char pos, unsigned char status, struct unistimsession *pte)
 
static void send_expansion_text (unsigned char pos, struct unistimsession *pte, const char *text)
 
static void send_favorite (unsigned char pos, unsigned char status, struct unistimsession *pte, const char *text)
 
static void send_favorite_selected (unsigned char status, struct unistimsession *pte)
 
static void send_favorite_short (unsigned char pos, unsigned char status, struct unistimsession *pte)
 
static void send_icon (unsigned char pos, unsigned char status, struct unistimsession *pte)
 
static void send_idle_clock (struct unistimsession *pte)
 
static void send_led_update (struct unistimsession *pte, unsigned char led)
 
static void send_month_labels (struct unistimsession *pte, int month)
 
static void send_mute (struct unistimsession *pte, unsigned char mute)
 
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, signed char volume, signed char style)
 
static void send_select_output (struct unistimsession *pte, unsigned char output, unsigned char volume, unsigned char mute)
 
static void send_start_rtp (struct unistim_subchannel *)
 
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 set_ping_timer (struct unistimsession *pte)
 
static void show_entry_history (struct unistimsession *pte, FILE **f)
 
static void show_extension_page (struct unistimsession *pte)
 
static void show_history (struct unistimsession *pte, char way)
 
static void show_main_page (struct unistimsession *pte)
 
static void show_phone_number (struct unistimsession *pte)
 
static int soft_key_visible (struct unistim_device *d, unsigned char num)
 
static void start_rtp (struct unistim_subchannel *sub)
 
static void sub_hold (struct unistimsession *pte, struct unistim_subchannel *sub)
 
static void sub_start_silence (struct unistimsession *pte, struct unistim_subchannel *sub)
 
static void sub_stop_silence (struct unistimsession *pte, struct unistim_subchannel *sub)
 
static void sub_unhold (struct unistimsession *pte, struct unistim_subchannel *sub)
 
static const char * subtype_tostr (const int type)
 
static void swap_subs (struct unistim_subchannel *a, struct unistim_subchannel *b)
 
static void transfer_call_step1 (struct unistimsession *pte)
 
static void transfer_cancel_step2 (struct unistimsession *pte)
 
static struct unistim_subchannelunistim_alloc_sub (struct unistim_device *d, int x)
 
static int unistim_answer (struct ast_channel *ast)
 
static int unistim_call (struct ast_channel *ast, const char *dest, int timeout)
 
static char * unistim_do_debug (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
 
static int unistim_do_senddigit (struct unistimsession *pte, char digit)
 
static int unistim_fixup (struct ast_channel *oldchan, struct ast_channel *newchan)
 
static int unistim_free_sub (struct unistim_subchannel *)
 
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_hangup_clean (struct ast_channel *ast, struct unistim_subchannel *sub)
 
static int unistim_indicate (struct ast_channel *ast, int ind, const void *data, size_t datalen)
 
static struct unistim_lineunistim_line_alloc (void)
 
static void unistim_line_copy (struct unistim_line *dst, struct unistim_line *src)
 
static struct unistim_lineunistim_line_destroy (struct unistim_line *l)
 
static struct ast_channelunistim_new (struct unistim_subchannel *sub, int state, const struct ast_assigned_ids *assignedids, const struct ast_channel *requestor)
 
static struct ast_frameunistim_read (struct ast_channel *ast)
 
static int unistim_register (struct unistimsession *s)
 
static char * unistim_reload (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
 — unistim_reload: Force reload of module from cli — Runs in the asterisk main thread, so don't do anything useful but setting a flag and waiting for do_monitor to do the job in our thread
 
static struct ast_channelunistim_request (const char *type, struct ast_format_cap *cap, const struct ast_assigned_ids *assignedids, const struct ast_channel *requestor, const char *dest, int *cause)
 
static struct ast_frameunistim_rtp_read (const struct ast_channel *ast, const struct unistim_subchannel *sub)
 
static int unistim_send_mwi_to_peer (struct unistim_line *peer, 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 void unistim_set_owner (struct unistim_subchannel *sub, struct ast_channel *chan)
 
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, const struct ast_format_cap *codecs, int nat_active)
 
static char * unistim_show_devices (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
 
static char * unistim_show_info (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
 
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_unalloc_sub (struct unistim_device *d, struct unistim_subchannel *sub)
 
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 unregister_extension (const struct unistimsession *pte)
 
static const char * ustmtext (const char *str, struct unistimsession *pte)
 
static int write_entry_history (struct unistimsession *pte, FILE *f, char c, char *line1)
 
static int write_history (struct unistimsession *pte, char way, char ismissed)
 

Variables

static struct ast_module_info __mod_info = { .name = AST_MODULE, .flags = AST_MODFLAG_DEFAULT , .description = "UNISTIM Protocol (USTM)" , .key = ASTERISK_GPL_KEY , .buildopt_sum = AST_BUILDOPT_SUM, .support_level = AST_MODULE_SUPPORT_EXTENDED, .load = load_module, .unload = unload_module, .reload = reload, }
 
static const struct ast_module_infoast_module_info = &__mod_info
 
static enum autoprovision autoprovisioning = AUTOPROVISIONING_NO
 
static unsigned char * buff
 
static const char channel_type [] = "USTM"
 
static struct ast_jb_conf default_jbconf
 Global jitterbuffer configuration - by default, jb is disabled.
 
static ast_mutex_t devicelock = AST_MUTEX_INIT_VALUE
 
static struct unistim_devicedevices = NULL
 
static const float dtmf_col [] = { 1209, 1336, 1477, 1633 }
 
static const int dtmf_row [] = { 697, 770, 852, 941 }
 
struct ast_format_capglobal_cap
 
static struct ast_jb_conf global_jbconf
 
static struct io_contextio
 
static pthread_t monitor_thread = AST_PTHREADT_NULL
 
static ast_mutex_t monlock = AST_MUTEX_INIT_VALUE
 
static unsigned char monthlabels []
 
static struct unistim_languages options_languages []
 
static struct unistim_menu_item options_menu []
 
static const unsigned char packet_rcv_discovery []
 
static const unsigned char packet_recv_expansion_pressed_key []
 
static const unsigned char packet_recv_firm_version []
 
static const unsigned char packet_recv_hangup []
 
static const unsigned char packet_recv_it_type []
 
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_charset_iso_2022_jp []
 
static const unsigned char packet_send_charset_iso_8859_1 []
 
static const unsigned char packet_send_charset_iso_8859_2 []
 
static const unsigned char packet_send_charset_iso_8859_4 []
 
static const unsigned char packet_send_charset_iso_8859_5 []
 
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_expansion_icon [] = { 0x09, 0x06, 0x59, 0x05, 0x47, 0x20 }
 
static const unsigned char packet_send_expansion_next [] = { 0x09, 0x03, 0x17 }
 
static const unsigned char packet_send_expansion_text []
 
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 unsigned char packet_send_monthlabels_download []
 
static const unsigned char packet_send_mute [] = { 0x16, 0x05, 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_start_timer []
 
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_dual_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 = { 0, 0, 0, 0 } 
 
static struct ast_sched_contextsched
 
static ast_mutex_t sessionlock = AST_MUTEX_INIT_VALUE
 
static struct unistimsessionsessions = NULL
 
static const char tdesc [] = "UNISTIM Channel Driver"
 
static struct ast_cli_entry unistim_cli []
 
static int unistim_keepalive
 
static int unistim_port
 
static ast_mutex_t unistim_reload_lock = AST_MUTEX_INIT_VALUE
 
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 char ustm_strcopy [1024]
 

Detailed Description

chan_unistim channel driver for Asterisk

Author
Cedric Hans cedri.nosp@m.c.ha.nosp@m.ns@ml.nosp@m.kj.n.nosp@m.et

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

Definition in file chan_unistim.c.

Macro Definition Documentation

◆ AST_CONFIG_MAX_PATH

#define AST_CONFIG_MAX_PATH   255

Definition at line 113 of file chan_unistim.c.

◆ BUFFSEND

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

Definition at line 706 of file chan_unistim.c.

◆ DEBUG_TIMER

#define DEBUG_TIMER   dummy

Definition at line 241 of file chan_unistim.c.

◆ DEFAULT_CODEC

#define DEFAULT_CODEC   0x00

Not used

Definition at line 110 of file chan_unistim.c.

◆ DEFAULT_INTERDIGIT_TIMER

#define DEFAULT_INTERDIGIT_TIMER   4000

Timeout value for entered number being dialed

Definition at line 107 of file chan_unistim.c.

◆ DEFAULTCALLERID

#define DEFAULTCALLERID   "Unknown"

Definition at line 84 of file chan_unistim.c.

◆ DEFAULTCALLERNAME

#define DEFAULTCALLERNAME   " "

Definition at line 85 of file chan_unistim.c.

◆ DEFAULTCONTEXT

#define DEFAULTCONTEXT   "default"

Definition at line 83 of file chan_unistim.c.

◆ DEFAULTHEIGHT

#define DEFAULTHEIGHT   3

Definition at line 86 of file chan_unistim.c.

◆ DEVICE_NAME_LEN

#define DEVICE_NAME_LEN   16

Definition at line 112 of file chan_unistim.c.

◆ EXPNUM

#define EXPNUM   24

Definition at line 217 of file chan_unistim.c.

◆ FAV_BLINK_FAST

#define FAV_BLINK_FAST   0x20

Definition at line 211 of file chan_unistim.c.

◆ FAV_BLINK_SLOW

#define FAV_BLINK_SLOW   0x40

Definition at line 212 of file chan_unistim.c.

◆ FAV_ICON_BOX

#define FAV_ICON_BOX   0x3F

Definition at line 209 of file chan_unistim.c.

◆ FAV_ICON_CALL_CENTER

#define FAV_ICON_CALL_CENTER   0x34

Definition at line 198 of file chan_unistim.c.

◆ FAV_ICON_CITY

#define FAV_ICON_CITY   0x31

Definition at line 195 of file chan_unistim.c.

◆ FAV_ICON_COMPUTER

#define FAV_ICON_COMPUTER   0x38

Definition at line 202 of file chan_unistim.c.

◆ FAV_ICON_FAX

#define FAV_ICON_FAX   0x35

Definition at line 199 of file chan_unistim.c.

◆ FAV_ICON_FORWARD

#define FAV_ICON_FORWARD   0x39

Definition at line 203 of file chan_unistim.c.

◆ FAV_ICON_HEADPHONES

#define FAV_ICON_HEADPHONES   0x2E

Definition at line 192 of file chan_unistim.c.

◆ FAV_ICON_HEADPHONES_ONHOLD

#define FAV_ICON_HEADPHONES_ONHOLD   0x2F

Definition at line 193 of file chan_unistim.c.

◆ FAV_ICON_HOME

#define FAV_ICON_HOME   0x30

Definition at line 194 of file chan_unistim.c.

◆ FAV_ICON_INBOX

#define FAV_ICON_INBOX   0x3C

Definition at line 206 of file chan_unistim.c.

◆ FAV_ICON_LOCKED

#define FAV_ICON_LOCKED   0x3A

Definition at line 204 of file chan_unistim.c.

◆ FAV_ICON_MAILBOX

#define FAV_ICON_MAILBOX   0x36

Definition at line 200 of file chan_unistim.c.

◆ FAV_ICON_MEETING

#define FAV_ICON_MEETING   0x3E

Definition at line 208 of file chan_unistim.c.

◆ FAV_ICON_NONE

#define FAV_ICON_NONE   0x00

Definition at line 177 of file chan_unistim.c.

◆ FAV_ICON_OFFHOOK_BLACK

#define FAV_ICON_OFFHOOK_BLACK   0x24

Definition at line 182 of file chan_unistim.c.

◆ FAV_ICON_OFFHOOK_WHITE

#define FAV_ICON_OFFHOOK_WHITE   0x25

Definition at line 183 of file chan_unistim.c.

◆ FAV_ICON_ONHOLD_BLACK

#define FAV_ICON_ONHOLD_BLACK   0x26

Definition at line 184 of file chan_unistim.c.

◆ FAV_ICON_ONHOLD_WHITE

#define FAV_ICON_ONHOLD_WHITE   0x27

Definition at line 185 of file chan_unistim.c.

◆ FAV_ICON_ONHOOK_BLACK

#define FAV_ICON_ONHOOK_BLACK   0x20

Definition at line 178 of file chan_unistim.c.

◆ FAV_ICON_ONHOOK_WHITE

#define FAV_ICON_ONHOOK_WHITE   0x21

Definition at line 179 of file chan_unistim.c.

◆ FAV_ICON_OUTBOX

#define FAV_ICON_OUTBOX   0x3D

Definition at line 207 of file chan_unistim.c.

◆ FAV_ICON_PAGER

#define FAV_ICON_PAGER   0x33

Definition at line 197 of file chan_unistim.c.

◆ FAV_ICON_PHONE_BLACK

#define FAV_ICON_PHONE_BLACK   0x2A

Definition at line 188 of file chan_unistim.c.

◆ FAV_ICON_PHONE_WHITE

#define FAV_ICON_PHONE_WHITE   0x2B

Definition at line 189 of file chan_unistim.c.

◆ FAV_ICON_REFLECT

#define FAV_ICON_REFLECT   0x37

Definition at line 201 of file chan_unistim.c.

◆ FAV_ICON_SHARP

#define FAV_ICON_SHARP   0x32

Definition at line 196 of file chan_unistim.c.

◆ FAV_ICON_SPEAKER_OFFHOOK_BLACK

#define FAV_ICON_SPEAKER_OFFHOOK_BLACK   0x28

Definition at line 186 of file chan_unistim.c.

◆ FAV_ICON_SPEAKER_OFFHOOK_WHITE

#define FAV_ICON_SPEAKER_OFFHOOK_WHITE   0x29

Definition at line 187 of file chan_unistim.c.

◆ FAV_ICON_SPEAKER_ONHOLD_BLACK

#define FAV_ICON_SPEAKER_ONHOLD_BLACK   0x2C

Definition at line 190 of file chan_unistim.c.

◆ FAV_ICON_SPEAKER_ONHOLD_WHITE

#define FAV_ICON_SPEAKER_ONHOLD_WHITE   0x2D

Definition at line 191 of file chan_unistim.c.

◆ FAV_ICON_SPEAKER_ONHOOK_BLACK

#define FAV_ICON_SPEAKER_ONHOOK_BLACK   0x22

Definition at line 180 of file chan_unistim.c.

◆ FAV_ICON_SPEAKER_ONHOOK_WHITE

#define FAV_ICON_SPEAKER_ONHOOK_WHITE   0x23

Definition at line 181 of file chan_unistim.c.

◆ FAV_ICON_TRASH

#define FAV_ICON_TRASH   0x3B

Definition at line 205 of file chan_unistim.c.

◆ FAV_LINE_ICON

#define FAV_LINE_ICON   FAV_ICON_ONHOOK_BLACK

Definition at line 218 of file chan_unistim.c.

◆ FAV_MAX_LENGTH

#define FAV_MAX_LENGTH   0x0A

Definition at line 214 of file chan_unistim.c.

◆ FAVNUM

#define FAVNUM   6

Definition at line 216 of file chan_unistim.c.

◆ IDLE_WAIT

#define IDLE_WAIT   1000

Nb of milliseconds waited when no events are scheduled

Definition at line 101 of file chan_unistim.c.

◆ LED_BAR_OFF

#define LED_BAR_OFF   0x00 /* bar off */

Definition at line 151 of file chan_unistim.c.

◆ LED_BAR_ON

#define LED_BAR_ON   0x01 /* bar on */

Definition at line 152 of file chan_unistim.c.

◆ LED_BAR_P2

#define LED_BAR_P2   0x02 /* bar 1s on/1s */

Definition at line 153 of file chan_unistim.c.

◆ LED_BAR_P3

#define LED_BAR_P3   0x03 /* bar 2.5s on/0.5s off */

Definition at line 154 of file chan_unistim.c.

◆ LED_BAR_P4

#define LED_BAR_P4   0x04 /* bar 0.6s on/0.3s off */

Definition at line 155 of file chan_unistim.c.

◆ LED_BAR_P5

#define LED_BAR_P5   0x05 /* bar 0.5s on/0.5s off */

Definition at line 156 of file chan_unistim.c.

◆ LED_BAR_P6

#define LED_BAR_P6   0x06 /* bar 2s on/0.5s off */

Definition at line 157 of file chan_unistim.c.

◆ LED_BAR_P7

#define LED_BAR_P7   0x07 /* bar off */

Definition at line 158 of file chan_unistim.c.

◆ LED_HEADPHONE_OFF

#define LED_HEADPHONE_OFF   0x010

Definition at line 161 of file chan_unistim.c.

◆ LED_HEADPHONE_ON

#define LED_HEADPHONE_ON   0x011

Definition at line 162 of file chan_unistim.c.

◆ LED_MUTE_BLINK

#define LED_MUTE_BLINK   0x1A

Definition at line 165 of file chan_unistim.c.

◆ LED_MUTE_OFF

#define LED_MUTE_OFF   0x018

Definition at line 163 of file chan_unistim.c.

◆ LED_MUTE_ON

#define LED_MUTE_ON   0x019

Definition at line 164 of file chan_unistim.c.

◆ LED_SPEAKER_OFF

#define LED_SPEAKER_OFF   0x08

Definition at line 159 of file chan_unistim.c.

◆ LED_SPEAKER_ON

#define LED_SPEAKER_ON   0x09

Definition at line 160 of file chan_unistim.c.

◆ MAX_BUF_NUMBER

#define MAX_BUF_NUMBER   150

Number of slots for the transmit queue

Definition at line 93 of file chan_unistim.c.

◆ MAX_BUF_SIZE

#define MAX_BUF_SIZE   64

Size of the transmit buffer

Definition at line 91 of file chan_unistim.c.

◆ MAX_ENTRY_LOG

#define MAX_ENTRY_LOG   30

Definition at line 114 of file chan_unistim.c.

◆ MAX_PHONE_NUMBER_LENGTH

#define MAX_PHONE_NUMBER_LENGTH   (AST_MAX_EXTENSION - 1)

Definition at line 458 of file chan_unistim.c.

◆ MAX_SCREEN_NUMBER

#define MAX_SCREEN_NUMBER   15

Number of digits displayed on screen

Definition at line 95 of file chan_unistim.c.

◆ MONTH_LABEL_SIZE

#define MONTH_LABEL_SIZE   3

Length of month label size

Definition at line 97 of file chan_unistim.c.

◆ MUTE_OFF

#define MUTE_OFF   0x00

Definition at line 147 of file chan_unistim.c.

◆ MUTE_ON

#define MUTE_ON   0xFF

Definition at line 148 of file chan_unistim.c.

◆ MUTE_ON_DISCRET

#define MUTE_ON_DISCRET   0xCE

Definition at line 149 of file chan_unistim.c.

◆ NB_MAX_RETRANSMIT

#define NB_MAX_RETRANSMIT   8

Try x times before removing the phone

Definition at line 99 of file chan_unistim.c.

◆ OUTPUT_HANDSET

#define OUTPUT_HANDSET   0xC0

Definition at line 138 of file chan_unistim.c.

◆ OUTPUT_HEADPHONE

#define OUTPUT_HEADPHONE   0xC1

Definition at line 139 of file chan_unistim.c.

◆ OUTPUT_SPEAKER

#define OUTPUT_SPEAKER   0xC2

Definition at line 140 of file chan_unistim.c.

◆ RETRANSMIT_TIMER

#define RETRANSMIT_TIMER   2000

Wait x milliseconds before resending a packet

Definition at line 103 of file chan_unistim.c.

◆ SELECTCODEC_MAX_LENGTH

#define SELECTCODEC_MAX_LENGTH   2

Definition at line 3738 of file chan_unistim.c.

◆ SELECTCODEC_MSG

#define SELECTCODEC_MSG   "Codec number : .."

Definition at line 3739 of file chan_unistim.c.

◆ SELECTCODEC_START_ENTRY_POS

#define SELECTCODEC_START_ENTRY_POS   15

Definition at line 3737 of file chan_unistim.c.

◆ SELECTEXTENSION_MAX_LENGTH

#define SELECTEXTENSION_MAX_LENGTH   10

Definition at line 3882 of file chan_unistim.c.

◆ SELECTEXTENSION_MSG

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

Definition at line 3883 of file chan_unistim.c.

◆ SELECTEXTENSION_START_ENTRY_POS

#define SELECTEXTENSION_START_ENTRY_POS   0

Definition at line 3881 of file chan_unistim.c.

◆ SIZE_HEADER

#define SIZE_HEADER   6

Definition at line 167 of file chan_unistim.c.

◆ SIZE_MAC_ADDR

#define SIZE_MAC_ADDR   17

Definition at line 168 of file chan_unistim.c.

◆ SIZE_PAGE

#define SIZE_PAGE   4096

Definition at line 111 of file chan_unistim.c.

◆ STATUS_LENGTH_MAX

#define STATUS_LENGTH_MAX   28

Definition at line 175 of file chan_unistim.c.

◆ SUB_REAL

#define SUB_REAL   0

Definition at line 116 of file chan_unistim.c.

◆ SUB_RING

#define SUB_RING   1

Definition at line 117 of file chan_unistim.c.

◆ SUB_THREEWAY

#define SUB_THREEWAY   2

Definition at line 118 of file chan_unistim.c.

◆ TEXT_INVERSE

#define TEXT_INVERSE   0x25

Definition at line 174 of file chan_unistim.c.

◆ TEXT_LENGTH_MAX

#define TEXT_LENGTH_MAX   24

Definition at line 169 of file chan_unistim.c.

◆ TEXT_LINE0

#define TEXT_LINE0   0x00

Definition at line 170 of file chan_unistim.c.

◆ TEXT_LINE1

#define TEXT_LINE1   0x20

Definition at line 171 of file chan_unistim.c.

◆ TEXT_LINE2

#define TEXT_LINE2   0x40

Definition at line 172 of file chan_unistim.c.

◆ TEXT_NORMAL

#define TEXT_NORMAL   0x05

Definition at line 173 of file chan_unistim.c.

◆ TIMER_MWI

#define TIMER_MWI   5000

How often the mailbox is checked for new messages

Definition at line 105 of file chan_unistim.c.

◆ USTM_LANG_DIR

#define USTM_LANG_DIR   "unistimLang"

Definition at line 88 of file chan_unistim.c.

◆ USTM_LOG_DIR

#define USTM_LOG_DIR   "unistimHistory"

Definition at line 87 of file chan_unistim.c.

◆ VOLUME_INSANELY_LOUD

#define VOLUME_INSANELY_LOUD   0x07

Definition at line 145 of file chan_unistim.c.

◆ VOLUME_LOW

#define VOLUME_LOW   0x01

Definition at line 142 of file chan_unistim.c.

◆ VOLUME_LOW_SPEAKER

#define VOLUME_LOW_SPEAKER   0x03

Definition at line 143 of file chan_unistim.c.

◆ VOLUME_NORMAL

#define VOLUME_NORMAL   0x02

Definition at line 144 of file chan_unistim.c.

Enumeration Type Documentation

◆ autoprov_extn

Enumerator
EXTENSION_NONE 

Do not create an extension into the default dialplan

EXTENSION_ASK 

Prompt user for an extension number and register it

EXTENSION_LINE 

Register an extension with the line=> value

EXTENSION_TN 

Used with AUTOPROVISIONING_TN

Definition at line 128 of file chan_unistim.c.

128 {
129 /*! Do not create an extension into the default dialplan */
130 EXTENSION_NONE = 0,
131 /*! Prompt user for an extension number and register it */
133 /*! Register an extension with the line=> value */
135 /*! Used with AUTOPROVISIONING_TN */
137};
@ EXTENSION_ASK
@ EXTENSION_LINE
@ EXTENSION_TN
@ EXTENSION_NONE

◆ autoprovision

Enumerator
AUTOPROVISIONING_NO 
AUTOPROVISIONING_YES 
AUTOPROVISIONING_TN 

Definition at line 122 of file chan_unistim.c.

122 {
126};
@ AUTOPROVISIONING_NO
@ AUTOPROVISIONING_TN
@ AUTOPROVISIONING_YES

◆ charset

enum charset
Enumerator
LANG_DEFAULT 
ISO_8859_1 
ISO_8859_2 
ISO_8859_4 
ISO_8859_5 
ISO_2022_JP 

Definition at line 336 of file chan_unistim.c.

336 {
343};
@ ISO_8859_1
@ ISO_8859_4
@ LANG_DEFAULT
@ ISO_8859_5
@ ISO_2022_JP
@ ISO_8859_2

◆ handset_state

Enumerator
STATE_ONHOOK 
STATE_OFFHOOK 

Definition at line 290 of file chan_unistim.c.

290 {
293};
@ STATE_OFFHOOK
@ STATE_ONHOOK

◆ phone_key

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

295 {
296 KEY_0 = 0x40,
297 KEY_1 = 0x41,
298 KEY_2 = 0x42,
299 KEY_3 = 0x43,
300 KEY_4 = 0x44,
301 KEY_5 = 0x45,
302 KEY_6 = 0x46,
303 KEY_7 = 0x47,
304 KEY_8 = 0x48,
305 KEY_9 = 0x49,
306 KEY_STAR = 0x4a,
307 KEY_SHARP = 0x4b,
308 KEY_UP = 0x4c,
309 KEY_DOWN = 0x4d,
310 KEY_RIGHT = 0x4e,
311 KEY_LEFT = 0x4f,
312 KEY_QUIT = 0x50,
313 KEY_COPY = 0x51,
314 KEY_FUNC1 = 0x54,
315 KEY_FUNC2 = 0x55,
316 KEY_FUNC3 = 0x56,
317 KEY_FUNC4 = 0x57,
318 KEY_ONHOLD = 0x5b,
319 KEY_HANGUP = 0x5c,
320 KEY_MUTE = 0x5d,
321 KEY_HEADPHN = 0x5e,
322 KEY_LOUDSPK = 0x5f,
323 KEY_FAV0 = 0x60,
324 KEY_FAV1 = 0x61,
325 KEY_FAV2 = 0x62,
326 KEY_FAV3 = 0x63,
327 KEY_FAV4 = 0x64,
328 KEY_FAV5 = 0x65,
329 KEY_COMPUTR = 0x7b,
330 KEY_CONF = 0x7c,
331 KEY_SNDHIST = 0x7d,
332 KEY_RCVHIST = 0x7e,
333 KEY_INDEX = 0x7f
334};
@ KEY_INDEX
@ KEY_FAV0
@ KEY_QUIT
@ KEY_UP
@ KEY_HANGUP
@ KEY_2
@ KEY_6
@ KEY_FUNC4
@ KEY_1
@ KEY_RCVHIST
@ KEY_FAV3
@ KEY_COMPUTR
@ KEY_9
@ KEY_LEFT
@ KEY_RIGHT
@ KEY_0
@ KEY_FAV2
@ KEY_FUNC3
@ KEY_SNDHIST
@ KEY_CONF
@ KEY_SHARP
@ KEY_FAV4
@ KEY_DOWN
@ KEY_8
@ KEY_MUTE
@ KEY_COPY
@ KEY_STAR
@ KEY_ONHOLD
@ KEY_LOUDSPK
@ KEY_FAV1
@ KEY_FAV5
@ KEY_HEADPHN
@ KEY_FUNC1
@ KEY_7
@ KEY_4
@ KEY_5
@ KEY_FUNC2
@ KEY_3

◆ phone_state

Enumerator
STATE_INIT 
STATE_AUTHDENY 
STATE_MAINPAGE 
STATE_EXTENSION 
STATE_DIALPAGE 
STATE_RINGING 
STATE_CALL 
STATE_SELECTOPTION 
STATE_SELECTCODEC 
STATE_SELECTLANGUAGE 
STATE_CLEANING 
STATE_HISTORY 

Definition at line 275 of file chan_unistim.c.

275 {
288};
@ STATE_EXTENSION
@ STATE_HISTORY
@ STATE_AUTHDENY
@ STATE_SELECTOPTION
@ STATE_CLEANING
@ STATE_CALL
@ STATE_SELECTCODEC
@ STATE_INIT
@ STATE_MAINPAGE
@ STATE_SELECTLANGUAGE
@ STATE_DIALPAGE
@ STATE_RINGING

Function Documentation

◆ __reg_module()

static void __reg_module ( void  )
static

Definition at line 7212 of file chan_unistim.c.

◆ __unreg_module()

static void __unreg_module ( void  )
static

Definition at line 7212 of file chan_unistim.c.

◆ AST_MODULE_SELF_SYM()

struct ast_module * AST_MODULE_SELF_SYM ( void  )

Definition at line 7212 of file chan_unistim.c.

◆ attempt_transfer()

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

Definition at line 2442 of file chan_unistim.c.

2443{
2444 RAII_VAR(struct ast_channel *, chana, NULL, ast_channel_unref);
2445 RAII_VAR(struct ast_channel *, chanb, NULL, ast_channel_unref);
2446
2447 if (!p1->owner || !p2->owner) {
2448 ast_log(LOG_WARNING, "Transfer attempted without dual ownership?\n");
2449 return -1;
2450 }
2451 chana = ast_channel_ref(p1->owner);
2452 chanb = ast_channel_ref(p2->owner);
2453
2454 switch (ast_bridge_transfer_attended(chana, chanb)) {
2456 ast_log(LOG_WARNING, "Transfer failed. Invalid bridge setup\n");
2457 break;
2459 ast_log(LOG_WARNING, "Transfer not permitted\n");
2460 break;
2462 ast_log(LOG_WARNING, "Transfer encountered internal error\n");
2463 break;
2465 return 0;
2466 }
2467
2468 /* Control only reaches this point if transfer has failed */
2471 return -1;
2472}
#define ast_log
Definition astobj2.c:42
@ AST_BRIDGE_TRANSFER_NOT_PERMITTED
Definition bridge.h:1163
@ AST_BRIDGE_TRANSFER_SUCCESS
Definition bridge.h:1161
@ AST_BRIDGE_TRANSFER_INVALID
Definition bridge.h:1165
@ AST_BRIDGE_TRANSFER_FAIL
Definition bridge.h:1167
enum ast_transfer_result ast_bridge_transfer_attended(struct ast_channel *to_transferee, struct ast_channel *to_transfer_target)
Attended transfer.
Definition bridge.c:4886
#define ast_channel_ref(c)
Increase channel reference count.
Definition channel.h:3008
#define ast_channel_unref(c)
Decrease channel reference count.
Definition channel.h:3019
@ AST_SOFTHANGUP_DEV
Definition channel.h:1141
int ast_softhangup_nolock(struct ast_channel *chan, int cause)
Softly hangup up a channel (no channel lock)
Definition channel.c:2449
#define LOG_WARNING
#define NULL
Definition resample.c:96
Main Channel structure associated with a channel.
struct ast_channel * owner
#define RAII_VAR(vartype, varname, initval, dtor)
Declare a variable that will call a destructor function when it goes out of scope.
Definition utils.h:981

References ast_bridge_transfer_attended(), AST_BRIDGE_TRANSFER_FAIL, AST_BRIDGE_TRANSFER_INVALID, AST_BRIDGE_TRANSFER_NOT_PERMITTED, AST_BRIDGE_TRANSFER_SUCCESS, ast_channel_ref, ast_channel_unref, ast_log, AST_SOFTHANGUP_DEV, ast_softhangup_nolock(), LOG_WARNING, NULL, unistim_subchannel::owner, and RAII_VAR.

Referenced by close_call().

◆ build_device()

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

Definition at line 6507 of file chan_unistim.c.

6508{
6509 struct unistim_device *d;
6510 struct unistim_line *l = NULL, *lt = NULL;
6511 int create = 1;
6512 int nbsoftkey, dateformat, timeformat, callhistory, sharpdial, linecnt;
6513 char linelabel[AST_MAX_EXTENSION];
6514 signed char ringvolume, ringstyle, cwvolume, cwstyle;
6515
6516 /* First, we need to know if we already have this name in our list */
6517 /* Get a lock for the device chained list */
6519 d = devices;
6520 while (d) {
6521 if (!strcmp(d->name, cat)) {
6522 /* Yep, we already have this one */
6523 if (unistimsock < 0) {
6524 /* It's a dupe */
6525 ast_log(LOG_WARNING, "Duplicate entry found (%s), ignoring.\n", cat);
6527 return NULL;
6528 }
6529 /* we're reloading right now */
6530 create = 0;
6531 break;
6532 }
6533 d = d->next;
6534 }
6536 if (!(lt = ast_calloc(1, sizeof(*lt)))) {
6537 return NULL;
6538 }
6539 if (create) {
6540 if (!(d = ast_calloc(1, sizeof(*d)))) {
6541 return NULL;
6542 }
6543 ast_mutex_init(&d->lock);
6544 ast_copy_string(d->name, cat, sizeof(d->name));
6545
6546 ast_copy_string(d->context, DEFAULTCONTEXT, sizeof(d->context));
6547 d->contrast = -1;
6548 d->output = OUTPUT_HANDSET;
6549 d->previous_output = OUTPUT_HANDSET;
6550 d->volume = VOLUME_LOW;
6551 d->microphone = MUTE_OFF;
6552 d->height = DEFAULTHEIGHT;
6553 d->selected = -1;
6554 d->interdigit_timer = DEFAULT_INTERDIGIT_TIMER;
6555 } else {
6556 /* Delete existing line information */
6557 AST_LIST_LOCK(&d->lines);
6558 AST_LIST_TRAVERSE_SAFE_BEGIN(&d->lines, l, list){
6561 }
6563 AST_LIST_UNLOCK(&d->lines);
6564
6565 /* reset bookmarks */
6566 memset(d->softkeylabel, 0, sizeof(d->softkeylabel));
6567 memset(d->softkeynumber, 0, sizeof(d->softkeynumber));
6568 memset(d->softkeyicon, 0, sizeof(d->softkeyicon));
6569 memset(d->softkeydevice, 0, sizeof(d->softkeydevice));
6570 memset(d->ssub, 0, sizeof(d->ssub));
6571 memset(d->sline, 0, sizeof(d->sline));
6572 memset(d->sp, 0, sizeof(d->sp));
6573 }
6574 linelabel[0] = '\0';
6575 dateformat = 1;
6576 timeformat = 1;
6577 ringvolume = 2;
6578 cwvolume = 1;
6579 callhistory = 1;
6580 sharpdial = 0;
6581 ringstyle = 3;
6582 cwstyle = 2;
6583 nbsoftkey = 0;
6584 linecnt = 0;
6585 d->dtmfduration = 0;
6586 while (v) {
6587 if (!strcasecmp(v->name, "rtp_port")) {
6588 d->rtp_port = atoi(v->value);
6589 } else if (!strcasecmp(v->name, "rtp_method")) {
6590 d->rtp_method = atoi(v->value);
6591 } else if (!strcasecmp(v->name, "status_method")) {
6592 d->status_method = atoi(v->value);
6593 } else if (!strcasecmp(v->name, "device")) {
6594 ast_copy_string(d->id, v->value, sizeof(d->id));
6595 } else if (!strcasecmp(v->name, "tn")) {
6596 ast_copy_string(d->extension_number, v->value, sizeof(d->extension_number));
6597 } else if (!strcasecmp(v->name, "permit") || !strcasecmp(v->name, "deny")) {
6598 int acl_error = 0;
6599 d->ha = ast_append_ha(v->name, v->value, d->ha, &acl_error);
6600 if (acl_error) {
6601 ast_log(LOG_ERROR, "Invalid ACL '%s' specified for device '%s' on line %d. Deleting device\n",
6602 v->value, cat, v->lineno);
6604 return NULL;
6605 }
6606 } else if (!strcasecmp(v->name, "context")) {
6607 ast_copy_string(d->context, v->value, sizeof(d->context));
6608 } else if (!strcasecmp(v->name, "maintext0")) {
6609 unquote(d->maintext0, v->value, sizeof(d->maintext0) - 1);
6610 } else if (!strcasecmp(v->name, "maintext1")) {
6611 unquote(d->maintext1, v->value, sizeof(d->maintext1) - 1);
6612 } else if (!strcasecmp(v->name, "maintext2")) {
6613 unquote(d->maintext2, v->value, sizeof(d->maintext2) - 1);
6614 } else if (!strcasecmp(v->name, "titledefault")) {
6615 unquote(d->titledefault, v->value, sizeof(d->titledefault) - 1);
6616 } else if (!strcasecmp(v->name, "dateformat")) {
6617 dateformat = atoi(v->value);
6618 } else if (!strcasecmp(v->name, "timeformat")) {
6619 timeformat = atoi(v->value);
6620 } else if (!strcasecmp(v->name, "contrast")) {
6621 d->contrast = atoi(v->value);
6622 if ((d->contrast < 0) || (d->contrast > 15)) {
6623 ast_log(LOG_WARNING, "contrast must be between 0 and 15\n");
6624 d->contrast = 8;
6625 }
6626 } else if (!strcasecmp(v->name, "nat")) {
6627 d->nat = ast_true(v->value);
6628 } else if (!strcasecmp(v->name, "hasexp")) {
6629 d->hasexp = ast_true(v->value);
6630 } else if (!strcasecmp(v->name, "ringvolume")) {
6631 ringvolume = atoi(v->value);
6632 } else if (!strcasecmp(v->name, "ringstyle")) {
6633 ringstyle = atoi(v->value);
6634 } else if (!strcasecmp(v->name, "cwvolume")) {
6635 cwvolume = atoi(v->value);
6636 } else if (!strcasecmp(v->name, "cwstyle")) {
6637 cwstyle = atoi(v->value);
6638 } else if (!strcasecmp(v->name, "callhistory")) {
6639 callhistory = atoi(v->value);
6640 } else if (!strcasecmp(v->name, "sharpdial")) {
6641 sharpdial = ast_true(v->value) ? 1 : 0;
6642 } else if (!strcasecmp(v->name, "interdigit_timer")) {
6643 d->interdigit_timer = atoi(v->value);
6644 } else if (!strcasecmp(v->name, "dtmf_duration")) {
6645 d->dtmfduration = atoi(v->value);
6646 if (d->dtmfduration > 150) {
6647 d->dtmfduration = 150;
6648 }
6649 } else if (!strcasecmp(v->name, "callerid")) {
6650 if (!strcasecmp(v->value, "asreceived")) {
6651 lt->cid_num[0] = '\0';
6652 } else {
6653 ast_copy_string(lt->cid_num, v->value, sizeof(lt->cid_num));
6654 }
6655 } else if (!strcasecmp(v->name, "language")) {
6656 ast_copy_string(d->language, v->value, sizeof(d->language));
6657 } else if (!strcasecmp(v->name, "country")) {
6658 ast_copy_string(d->country, v->value, sizeof(d->country));
6659 } else if (!strcasecmp(v->name, "accountcode")) {
6660 ast_copy_string(lt->accountcode, v->value, sizeof(lt->accountcode));
6661 } else if (!strcasecmp(v->name, "amaflags")) {
6662 int y;
6664 if (y < 0) {
6665 ast_log(LOG_WARNING, "Invalid AMA flags: %s at line %d\n", v->value,
6666 v->lineno);
6667 } else {
6668 lt->amaflags = y;
6669 }
6670 } else if (!strcasecmp(v->name, "musiconhold")) {
6671 ast_copy_string(lt->musicclass, v->value, sizeof(lt->musicclass));
6672 } else if (!strcasecmp(v->name, "callgroup")) {
6673 lt->callgroup = ast_get_group(v->value);
6674 } else if (!strcasecmp(v->name, "pickupgroup")) {
6675 lt->pickupgroup = ast_get_group(v->value);
6676 } else if (!strcasecmp(v->name, "mailbox")) {
6677 ast_copy_string(lt->mailbox, v->value, sizeof(lt->mailbox));
6678 } else if (!strcasecmp(v->name, "parkinglot")) {
6679 ast_copy_string(lt->parkinglot, v->value, sizeof(lt->parkinglot));
6680 } else if (!strcasecmp(v->name, "linelabel")) {
6681 unquote(linelabel, v->value, sizeof(linelabel) - 1);
6682 } else if (!strcasecmp(v->name, "extension")) {
6683 if (!strcasecmp(v->value, "none")) {
6684 d->extension = EXTENSION_NONE;
6685 } else if (!strcasecmp(v->value, "ask")) {
6686 d->extension = EXTENSION_ASK;
6687 } else if (!strcasecmp(v->value, "line")) {
6688 d->extension = EXTENSION_LINE;
6689 } else {
6690 ast_log(LOG_WARNING, "Unknown extension option.\n");
6691 }
6692 } else if (!strcasecmp(v->name, "bookmark")) {
6693 if (nbsoftkey > 5) {
6695 "More than 6 softkeys defined. Ignoring new entries.\n");
6696 } else {
6697 if (parse_bookmark(v->value, d)) {
6698 nbsoftkey++;
6699 }
6700 }
6701 } else if (!strcasecmp(v->name, "line")) {
6702 int len = strlen(linelabel);
6703 int create_line = 0;
6704
6705 l = find_line_by_number(d, v->value);
6706 if (!l) { /* If line still not exists */
6707 if (!(l = unistim_line_alloc())) {
6708 ast_free(d);
6709 ast_free(lt);
6710 return NULL;
6711 }
6712 lt->cap = l->cap;
6713 memcpy(l, lt, sizeof(*l));
6714 ast_mutex_init(&l->lock);
6715 create_line = 1;
6716 }
6717 d->to_delete = 0;
6718
6719 /* Set softkey info for new line*/
6720 d->sline[nbsoftkey] = l;
6721 d->softkeyicon[nbsoftkey] = FAV_LINE_ICON;
6722 if (!len) { /* label is undefined ? */
6723 ast_copy_string(d->softkeylabel[nbsoftkey], v->value, sizeof(d->softkeylabel[nbsoftkey]));
6724 } else {
6725 int softkeylinepos = 0;
6726 if ((len > 2) && (linelabel[1] == '@')) {
6727 softkeylinepos = linelabel[0];
6728 if ((softkeylinepos >= '0') && (softkeylinepos <= '5')) {
6729 softkeylinepos -= '0';
6730 d->softkeyicon[nbsoftkey] = FAV_ICON_NONE;
6731 } else {
6733 "Invalid position for linelabel : must be between 0 and 5\n");
6734 }
6735 ast_copy_string(d->softkeylabel[softkeylinepos], linelabel + 2,
6736 sizeof(d->softkeylabel[softkeylinepos]));
6737 d->softkeyicon[softkeylinepos] = FAV_LINE_ICON;
6738 } else {
6739 ast_copy_string(d->softkeylabel[nbsoftkey], linelabel,
6740 sizeof(d->softkeylabel[nbsoftkey]));
6741 }
6742 }
6743 nbsoftkey++;
6744
6745 if (create_line) {
6746 ast_copy_string(l->name, v->value, sizeof(l->name));
6747 snprintf(l->fullname, sizeof(l->fullname), "USTM/%s@%s", l->name, d->name);
6748 if (!ast_strlen_zero(l->mailbox)) {
6749 if (unistimdebug) {
6750 ast_verb(3, "Setting mailbox '%s' on %s@%s\n", l->mailbox, d->name, l->name);
6751 }
6752 }
6754 l->parent = d;
6755 linecnt++;
6756 AST_LIST_LOCK(&d->lines);
6757 AST_LIST_INSERT_TAIL(&d->lines, l, list);
6758 AST_LIST_UNLOCK(&d->lines);
6759 }
6760 } else if (!strcasecmp(v->name, "height")) {
6761 /* Allow the user to lower the expected display lines on the phone
6762 * For example the Nortel i2001 and i2002 only have one ! */
6763 d->height = atoi(v->value);
6764 } else
6765 ast_log(LOG_WARNING, "Don't know keyword '%s' at line %d\n", v->name,
6766 v->lineno);
6767 v = v->next;
6768 }
6769 ast_free(lt);
6770 if (linecnt == 0) {
6771 ast_log(LOG_ERROR, "An Unistim device must have at least one line!\n");
6772 ast_free(d);
6773 return NULL;
6774 }
6775 d->ringvolume = ringvolume;
6776 d->ringstyle = ringstyle;
6777 d->cwvolume = cwvolume;
6778 d->cwstyle = cwstyle;
6779 d->callhistory = callhistory;
6780 d->sharp_dial = sharpdial;
6781 d->tz = ast_get_indication_zone(d->country);
6782 if ((d->tz == NULL) && !ast_strlen_zero(d->country)) {
6783 ast_log(LOG_WARNING, "Country '%s' was not found in indications.conf\n",
6784 d->country);
6785 }
6786 d->datetimeformat = 48 + (dateformat * 4);
6787 d->datetimeformat += timeformat;
6789 (!ast_strlen_zero(d->extension_number))) {
6790 d->extension = EXTENSION_TN;
6791 if (!ast_strlen_zero(d->id)) {
6793 "tn= and device= can't be used together. Ignoring device= entry\n");
6794 }
6795 d->id[0] = 'T'; /* magic : this is a tn entry */
6796 ast_copy_string((d->id) + 1, d->extension_number, sizeof(d->id) - 1);
6797 d->extension_number[0] = '\0';
6798 } else if (ast_strlen_zero(d->id)) {
6799 if (strcmp(d->name, "template")) {
6800 ast_log(LOG_ERROR, "You must specify the mac address with device=\n");
6801 if (d->tz) {
6802 d->tz = ast_tone_zone_unref(d->tz);
6803 }
6804 ast_free(d);
6805 return NULL;
6806 } else {
6807 strcpy(d->id, "000000000000");
6808 }
6809 }
6810 if (!d->rtp_port) {
6811 d->rtp_port = 10000;
6812 }
6813 if (d->contrast == -1) {
6814 d->contrast = 8;
6815 }
6816 if (ast_strlen_zero(d->maintext1)) {
6817 strcpy(d->maintext1, d->name);
6818 }
6819 if (ast_strlen_zero(d->titledefault)) {
6820 struct ast_tm tm = { 0, };
6821 struct timeval cur_time = ast_tvnow();
6822
6823 if ((ast_localtime(&cur_time, &tm, 0)) == 0 || ast_strlen_zero(tm.tm_zone)) {
6824 ast_log(LOG_WARNING, "Error in ast_localtime()\n");
6825 ast_copy_string(d->titledefault, "UNISTIM for*", 12);
6826 } else {
6827 if (strlen(tm.tm_zone) < 4) {
6828 strcpy(d->titledefault, "TimeZone ");
6829 strcat(d->titledefault, tm.tm_zone);
6830 } else if (strlen(tm.tm_zone) < 9) {
6831 strcpy(d->titledefault, "TZ ");
6832 strcat(d->titledefault, tm.tm_zone);
6833 } else {
6834 ast_copy_string(d->titledefault, tm.tm_zone, 12);
6835 }
6836 }
6837 }
6838 /* Update the chained link if it's a new device */
6839 if (create) {
6841 d->next = devices;
6842 devices = d;
6844 ast_verb(3, "Added device '%s'\n", d->name);
6845 } else {
6846 ast_verb(3, "Device '%s' reloaded\n", d->name);
6847 }
6848 return d;
6849}
struct ast_ha * ast_append_ha(const char *sense, const char *stuff, struct ast_ha *path, int *error)
Add a new rule to a list of HAs.
Definition acl.c:712
#define ast_free(a)
Definition astmm.h:180
#define ast_calloc(num, len)
A wrapper for calloc()
Definition astmm.h:202
static int unistimsock
static struct unistim_line * find_line_by_number(struct unistim_device *d, const char *val)
static int unistimdebug
static enum autoprovision autoprovisioning
#define VOLUME_LOW
static struct unistim_line * unistim_line_destroy(struct unistim_line *l)
static struct unistim_line * unistim_line_alloc(void)
#define MUTE_OFF
static struct unistim_device * devices
static ast_mutex_t devicelock
static void delete_device(struct unistim_device *d)
#define DEFAULTCONTEXT
#define FAV_LINE_ICON
#define OUTPUT_HANDSET
#define DEFAULT_INTERDIGIT_TIMER
static int parse_bookmark(const char *text, struct unistim_device *d)
struct ast_format_cap * global_cap
#define DEFAULTHEIGHT
#define FAV_ICON_NONE
static void unquote(char *out, const char *src, int maxlen)
enum ama_flags ast_channel_string2amaflag(const char *flag)
Convert a string to a detail record AMA flag.
Definition channel.c:4382
ast_group_t ast_get_group(const char *s)
Definition channel.c:7654
#define AST_MAX_EXTENSION
Definition channel.h:134
@ AST_MEDIA_TYPE_UNKNOWN
Definition codec.h:31
int ast_format_cap_append_from_cap(struct ast_format_cap *dst, const struct ast_format_cap *src, enum ast_media_type type)
Append the formats of provided type in src to dst.
Definition format_cap.c:269
static int len(struct ast_channel *chan, const char *cmd, char *data, char *buf, size_t buflen)
#define LOG_ERROR
#define ast_verb(level,...)
static struct ast_tone_zone * ast_tone_zone_unref(struct ast_tone_zone *tz)
Release a reference to an ast_tone_zone.
struct ast_tone_zone * ast_get_indication_zone(const char *country)
locate ast_tone_zone
#define AST_LIST_INSERT_TAIL(head, elm, field)
Appends a list entry to the tail of a list.
#define AST_LIST_TRAVERSE_SAFE_END
Closes a safe loop traversal block.
#define AST_LIST_LOCK(head)
Locks a list.
Definition linkedlists.h:40
#define AST_LIST_TRAVERSE_SAFE_BEGIN(head, var, field)
Loops safely over (traverses) the entries in a list.
#define AST_LIST_REMOVE_CURRENT(field)
Removes the current entry from a list during a traversal.
#define AST_LIST_UNLOCK(head)
Attempts to unlock a list.
struct ast_tm * ast_localtime(const struct timeval *timep, struct ast_tm *p_tm, const char *zone)
Timezone-independent version of localtime_r(3).
Definition localtime.c:1739
#define ast_mutex_init(pmutex)
Definition lock.h:193
#define ast_mutex_unlock(a)
Definition lock.h:197
#define ast_mutex_lock(a)
Definition lock.h:196
static char dateformat[256]
Definition logger.c:78
int attribute_pure ast_true(const char *val)
Make sure something is true. Determine if a string containing a boolean value is "true"....
Definition utils.c:2233
static force_inline int attribute_pure ast_strlen_zero(const char *s)
Definition strings.h:65
void ast_copy_string(char *dst, const char *src, size_t size)
Size-limited null-terminating string copy.
Definition strings.h:425
char * tm_zone
Definition localtime.h:46
struct ast_variable * next
struct test_val * next
const char * name
A device containing one or more lines.
char fullname[101]
char name[80]
struct ast_format_cap * cap
struct unistim_device * parent
char mailbox[AST_MAX_EXTENSION]
ast_mutex_t lock
struct unistim_line::@136 list
static struct test_val d
struct timeval ast_tvnow(void)
Returns current timeval. Meant to replace calls to gettimeofday().
Definition time.h:159

References ast_append_ha(), ast_calloc, ast_channel_string2amaflag(), ast_copy_string(), ast_format_cap_append_from_cap(), ast_free, ast_get_group(), ast_get_indication_zone(), AST_LIST_INSERT_TAIL, AST_LIST_LOCK, AST_LIST_REMOVE_CURRENT, AST_LIST_TRAVERSE_SAFE_BEGIN, AST_LIST_TRAVERSE_SAFE_END, AST_LIST_UNLOCK, ast_localtime(), ast_log, AST_MAX_EXTENSION, AST_MEDIA_TYPE_UNKNOWN, ast_mutex_init, ast_mutex_lock, ast_mutex_unlock, ast_strlen_zero(), ast_tone_zone_unref(), ast_true(), ast_tvnow(), ast_verb, autoprovisioning, AUTOPROVISIONING_TN, unistim_line::cap, d, dateformat, DEFAULT_INTERDIGIT_TIMER, DEFAULTCONTEXT, DEFAULTHEIGHT, delete_device(), devicelock, devices, EXTENSION_ASK, EXTENSION_LINE, EXTENSION_NONE, EXTENSION_TN, FAV_ICON_NONE, FAV_LINE_ICON, find_line_by_number(), unistim_line::fullname, global_cap, len(), ast_variable::lineno, unistim_line::list, unistim_line::lock, LOG_ERROR, LOG_WARNING, unistim_line::mailbox, MUTE_OFF, unistim_line::name, ast_variable::name, test_val::name, ast_variable::next, test_val::next, NULL, OUTPUT_HANDSET, unistim_line::parent, parse_bookmark(), ast_tm::tm_zone, unistim_line_alloc(), unistim_line_destroy(), unistimdebug, unistimsock, unquote(), ast_variable::value, and VOLUME_LOW.

Referenced by reload_config().

◆ change_callerid()

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

Definition at line 2474 of file chan_unistim.c.

2475{
2476 char *data;
2477 int size;
2478
2479 if (type) {
2480 data = pte->device->lst_cnm;
2481 } else {
2482 data = pte->device->lst_cid;
2483 }
2484
2485 /* This is very nearly strncpy(), except that the remaining buffer
2486 * is padded with ' ', instead of '\0' */
2487 memset(data, ' ', TEXT_LENGTH_MAX);
2488 size = strlen(callerid);
2489 if (size > TEXT_LENGTH_MAX) {
2490 size = TEXT_LENGTH_MAX;
2491 }
2492 memcpy(data, callerid, size);
2493}
static const char type[]
#define TEXT_LENGTH_MAX
char lst_cid[TEXT_LENGTH_MAX]
char lst_cnm[TEXT_LENGTH_MAX]
struct unistim_device * device

References unistimsession::device, unistim_device::lst_cid, unistim_device::lst_cnm, TEXT_LENGTH_MAX, and type.

Referenced by close_call(), and send_callerid_screen().

◆ change_favorite_icon()

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

Definition at line 1420 of file chan_unistim.c.

1421{
1422 struct unistim_device *d = devices;
1423 int i;
1424 /* Update the current phone line softkey icon */
1425 if (pte->state != STATE_CLEANING) {
1426 int softkeylinepos = get_active_softkey(pte);
1427 if (softkeylinepos != -1) {
1428 send_favorite_short(softkeylinepos, status, pte);
1429 }
1430 }
1431 /* Notify other phones if we're in their bookmark */
1432 while (d) {
1433 for (i = 0; i < FAVNUM; i++) {
1434 if (d->sp[i] == pte->device) { /* It's us ? */
1435 if (d->softkeyicon[i] != status) { /* Avoid resending the same icon */
1436 d->softkeyicon[i] = status;
1437 if (d->session) {
1438 send_favorite(i, status + 1, d->session, d->softkeylabel[i]);
1439 }
1440 }
1441 }
1442 }
1443 d = d->next;
1444 }
1445}
jack_status_t status
Definition app_jack.c:149
static void send_favorite_short(unsigned char pos, unsigned char status, struct unistimsession *pte)
static void send_favorite(unsigned char pos, unsigned char status, struct unistimsession *pte, const char *text)
static int get_active_softkey(struct unistimsession *pte)
#define FAVNUM

References d, unistimsession::device, devices, FAVNUM, get_active_softkey(), test_val::next, send_favorite(), send_favorite_short(), unistimsession::state, STATE_CLEANING, and status.

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

◆ channel_to_session()

static struct unistimsession * channel_to_session ( struct ast_channel ast)
static

Definition at line 4802 of file chan_unistim.c.

4803{
4804 struct unistim_subchannel *sub;
4805 if (!ast) {
4806 ast_log(LOG_WARNING, "Unistim callback function called with a null channel\n");
4807 return NULL;
4808 }
4809 if (!ast_channel_tech_pvt(ast)) {
4810 ast_log(LOG_WARNING, "Unistim callback function called without a tech_pvt\n");
4811 return NULL;
4812 }
4814
4815 if (!sub->parent) {
4816 ast_log(LOG_WARNING, "Unistim callback function called without a line\n");
4817 return NULL;
4818 }
4819 if (!sub->parent->parent) {
4820 ast_log(LOG_WARNING, "Unistim callback function called without a device\n");
4821 return NULL;
4822 }
4823 ast_mutex_lock(&sub->parent->parent->lock);
4824 if (!sub->parent->parent->session) {
4825 ast_log(LOG_WARNING, "Unistim callback function called without a session\n");
4826 ast_mutex_unlock(&sub->parent->parent->lock);
4827 return NULL;
4828 }
4829 ast_mutex_unlock(&sub->parent->parent->lock);
4830 return sub->parent->parent->session;
4831}
void * ast_channel_tech_pvt(const struct ast_channel *chan)
static struct stasis_subscription * sub
Statsd channel stats. Exmaple of how to subscribe to Stasis events.

References ast_channel_tech_pvt(), ast_log, ast_mutex_lock, ast_mutex_unlock, LOG_WARNING, NULL, and sub.

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

◆ check_send_queue()

static void check_send_queue ( struct unistimsession pte)
static

Definition at line 1103 of file chan_unistim.c.

1104{
1105 /* Check if our send queue contained only one element */
1106 if (pte->last_buf_available == 1) {
1107 if (unistimdebug) {
1108 ast_verb(0, "Our single packet was ACKed.\n");
1109 }
1110 pte->last_buf_available--;
1111 set_ping_timer(pte);
1112 return;
1113 }
1114 /* Check if this ACK catch up our latest packet */
1115 else if (pte->last_seq_ack + 1 == pte->seq_server + 1) {
1116 if (unistimdebug) {
1117 ast_verb(0, "Our send queue is completely ACKed.\n");
1118 }
1119 pte->last_buf_available = 0; /* Purge the send queue */
1120 set_ping_timer(pte);
1121 return;
1122 }
1123 if (unistimdebug) {
1124 ast_verb(0, "We still have packets in our send queue\n");
1125 }
1126 return;
1127}
static void set_ping_timer(struct unistimsession *pte)
unsigned short seq_server
unsigned short last_seq_ack

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

Referenced by parsing().

◆ close_call()

static void close_call ( struct unistimsession pte)
static

Definition at line 2601 of file chan_unistim.c.

2602{
2603 struct unistim_subchannel *sub, *sub_transf;
2604
2605 sub = get_sub(pte->device, SUB_REAL);
2606 sub_transf = get_sub(pte->device, SUB_THREEWAY);
2607 send_stop_timer(pte);
2608 if (!sub) {
2609 ast_log(LOG_WARNING, "Close call without sub\n");
2610 return;
2611 }
2612 send_favorite_short(sub->softkey, FAV_LINE_ICON, pte);
2613 if (sub->owner) {
2614 sub->alreadygone = 1;
2615 if (sub_transf) {
2616 sub_transf->alreadygone = 1;
2617 if (attempt_transfer(sub, sub_transf) < 0) {
2618 ast_verb(0, "attempt_transfer failed.\n");
2619 }
2620 } else {
2621 ast_queue_hangup(sub->owner);
2622 }
2623 } else {
2624 if (sub_transf) {
2625 if (sub_transf->owner) {
2627 } else {
2628 ast_log(LOG_WARNING, "threeway sub without owner\n");
2629 }
2630 } else {
2631 ast_verb(0, "USTM(%s@%s-%d) channel already destroyed\n", sub->parent->name,
2632 pte->device->name, sub->softkey);
2633 }
2634 }
2635 change_callerid(pte, 0, pte->device->redial_number);
2636 change_callerid(pte, 1, "");
2637 write_history(pte, 'o', pte->device->missed_call);
2638 pte->device->missed_call = 0;
2639 show_main_page(pte);
2640 return;
2641}
#define AST_CAUSE_NORMAL_CLEARING
Definition causes.h:106
#define SUB_REAL
#define SUB_THREEWAY
static int attempt_transfer(struct unistim_subchannel *p1, struct unistim_subchannel *p2)
static void show_main_page(struct unistimsession *pte)
static int write_history(struct unistimsession *pte, char way, char ismissed)
static void send_stop_timer(struct unistimsession *pte)
static void change_callerid(struct unistimsession *pte, int type, char *callerid)
static struct unistim_subchannel * get_sub(struct unistim_device *device, int type)
int ast_queue_hangup(struct ast_channel *chan)
Queue a hangup frame.
Definition channel.c:1182
int ast_queue_hangup_with_cause(struct ast_channel *chan, int cause)
Queue a hangup frame with hangupcause set.
Definition channel.c:1213
char redial_number[AST_MAX_EXTENSION]
char name[DEVICE_NAME_LEN]

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, FAV_LINE_ICON, get_sub(), LOG_WARNING, unistim_device::missed_call, unistim_device::name, unistim_subchannel::owner, unistim_device::redial_number, send_favorite_short(), send_stop_timer(), show_main_page(), sub, SUB_REAL, SUB_THREEWAY, and write_history().

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

◆ close_client()

static void close_client ( struct unistimsession s)
static

Definition at line 1472 of file chan_unistim.c.

1473{
1474 struct unistim_subchannel *sub = NULL;
1475 struct unistimsession *cur, *prev = NULL;
1477 cur = sessions;
1478 /* Looking for the session in the linked chain */
1479 while (cur) {
1480 if (cur == s) {
1481 break;
1482 }
1483 prev = cur;
1484 cur = cur->next;
1485 }
1486 if (cur) { /* Session found ? */
1487 if (cur->device) { /* This session was registered ? */
1488 s->state = STATE_CLEANING;
1489 if (unistimdebug) {
1490 ast_verb(0, "close_client session %p device %p\n", s, s->device);
1491 }
1496 if (!sub) {
1497 continue;
1498 }
1499 if (sub->owner) { /* Call in progress ? */
1500 if (unistimdebug) {
1501 ast_verb(0, "Aborting call\n");
1502 }
1504 } else {
1505 if (unistimdebug) {
1506 ast_debug(1, "Released sub %u of channel %s@%s\n", sub->subtype, sub->parent->name, s->device->name);
1507 }
1510 }
1511 }
1514
1517 }
1518 cur->device->session = NULL;
1520 } else {
1521 if (unistimdebug) {
1522 ast_verb(0, "Freeing an unregistered client\n");
1523 }
1524 }
1525 if (prev) {
1526 prev->next = cur->next;
1527 } else {
1528 sessions = cur->next;
1529 }
1531 ast_free(s);
1532 } else {
1533 ast_log(LOG_WARNING, "Trying to delete non-existent session %p?\n", s);
1534 }
1536 return;
1537}
#define AST_CAUSE_NETWORK_OUT_OF_ORDER
Definition causes.h:121
static struct unistimsession * sessions
static void change_favorite_icon(struct unistimsession *pte, unsigned char status)
static ast_mutex_t sessionlock
static int unistim_free_sub(struct unistim_subchannel *)
static int unregister_extension(const struct unistimsession *pte)
#define ast_debug(level,...)
Log a DEBUG message.
#define ast_mutex_destroy(a)
Definition lock.h:195
struct unistim_device::@137 subs
char extension_number[11]
struct unistimsession * session
ast_mutex_t lock
struct unistimsession * next
ast_mutex_t lock

References AST_CAUSE_NETWORK_OUT_OF_ORDER, ast_debug, ast_free, AST_LIST_LOCK, AST_LIST_REMOVE_CURRENT, AST_LIST_TRAVERSE_SAFE_BEGIN, AST_LIST_TRAVERSE_SAFE_END, AST_LIST_UNLOCK, 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::lock, unistimsession::lock, LOG_WARNING, unistim_device::name, unistimsession::next, NULL, unistim_device::session, sessionlock, sessions, unistimsession::state, STATE_CLEANING, sub, unistim_device::subs, unistim_free_sub(), unistimdebug, and unregister_extension().

Referenced by parsing(), and send_retransmit().

◆ control2str()

static char * control2str ( int  ind)
static

Definition at line 5285 of file chan_unistim.c.

5286{
5287 switch (ind) {
5288 case AST_CONTROL_HANGUP:
5289 return "Other end has hungup";
5290 case AST_CONTROL_RING:
5291 return "Local ring";
5293 return "Remote end is ringing";
5294 case AST_CONTROL_ANSWER:
5295 return "Remote end has answered";
5296 case AST_CONTROL_BUSY:
5297 return "Remote end is busy";
5299 return "Make it go off hook";
5301 return "Line is off hook";
5303 return "Congestion (circuits busy)";
5304 case AST_CONTROL_FLASH:
5305 return "Flash hook";
5306 case AST_CONTROL_WINK:
5307 return "Wink";
5308 case AST_CONTROL_OPTION:
5309 return "Set a low-level option";
5311 return "Key Radio";
5313 return "Un-Key Radio";
5315 return "Remote end changed";
5317 return "RTP source updated";
5319 return "Source of media changed";
5320 case -1:
5321 return "Stop tone";
5322 }
5323 return "UNKNOWN";
5324}
@ AST_CONTROL_SRCUPDATE
@ AST_CONTROL_OFFHOOK
@ AST_CONTROL_RADIO_UNKEY
@ AST_CONTROL_TAKEOFFHOOK
@ AST_CONTROL_CONGESTION
@ AST_CONTROL_ANSWER
@ AST_CONTROL_RINGING
@ AST_CONTROL_HANGUP
@ AST_CONTROL_RADIO_KEY
@ AST_CONTROL_OPTION
@ AST_CONTROL_CONNECTED_LINE
@ AST_CONTROL_FLASH
@ AST_CONTROL_SRCCHANGE

References AST_CONTROL_ANSWER, AST_CONTROL_BUSY, AST_CONTROL_CONGESTION, AST_CONTROL_CONNECTED_LINE, 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_SRCCHANGE, AST_CONTROL_SRCUPDATE, AST_CONTROL_TAKEOFFHOOK, and AST_CONTROL_WINK.

Referenced by unistim_indicate().

◆ create_client()

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

Definition at line 1048 of file chan_unistim.c.

1049{
1050 int tmp;
1051 struct unistimsession *s;
1052
1053 if (!(s = ast_calloc(1, sizeof(*s))))
1054 return NULL;
1055
1056 memcpy(&s->sin, addr_from, sizeof(struct sockaddr_in));
1057 if (get_to_address(unistimsock, &s->sout) < 0) {
1058 ast_free(s);
1059 return NULL;
1060 }
1061 s->sout.sin_family = AF_INET;
1062 if (unistimdebug) {
1063 ast_verb(0, "Creating a new entry for the phone from %s received via server ip %s\n",
1064 ast_inet_ntoa(addr_from->sin_addr), ast_inet_ntoa(s->sout.sin_addr));
1065 }
1066 ast_mutex_init(&s->lock);
1068 s->next = sessions;
1069 sessions = s;
1070
1072 s->state = STATE_INIT;
1074 /* Initialize struct wsabuf */
1075 for (tmp = 0; tmp < MAX_BUF_NUMBER; tmp++) {
1076 s->wsabufsend[tmp].buf = s->buf[tmp];
1077 }
1079 return s;
1080}
static int unistim_keepalive
static unsigned int get_tick_count(void)
#define MAX_BUF_NUMBER
#define RETRANSMIT_TIMER
static int get_to_address(int fd, struct sockaddr_in *toAddr)
const char * ast_inet_ntoa(struct in_addr ia)
thread-safe replacement for inet_ntoa().
Definition utils.c:962
unsigned char buf[MAX_BUF_NUMBER][MAX_BUF_SIZE]
struct wsabuf wsabufsend[MAX_BUF_NUMBER]
struct sockaddr_in sout
unsigned long tick_next_ping
struct sockaddr_in sin
unsigned char * buf

References ast_calloc, ast_free, ast_inet_ntoa(), ast_mutex_init, ast_mutex_lock, ast_mutex_unlock, ast_verb, wsabuf::buf, unistimsession::buf, get_tick_count(), get_to_address(), unistimsession::lock, MAX_BUF_NUMBER, unistimsession::next, NULL, RETRANSMIT_TIMER, sessionlock, sessions, unistimsession::sin, unistimsession::sout, unistimsession::state, STATE_INIT, unistimsession::tick_next_ping, unistimsession::timeout, unistim_keepalive, unistimdebug, unistimsock, and unistimsession::wsabufsend.

Referenced by parsing().

◆ delete_device()

static void delete_device ( struct unistim_device d)
static

Definition at line 6428 of file chan_unistim.c.

6429{
6430 struct unistim_line *l;
6431 struct unistim_subchannel *sub;
6432 struct unistimsession *s;
6433
6434 if (unistimdebug) {
6435 ast_verb(0, "Removing device '%s'\n", d->name);
6436 }
6437 AST_LIST_LOCK(&d->subs);
6438 AST_LIST_TRAVERSE_SAFE_BEGIN(&d->subs, sub, list){
6439 if (sub->subtype == SUB_REAL) {
6440 if (sub->owner) {
6442 "Device '%s' was not deleted : a call is in progress. Try again later.\n",
6443 d->name);
6444 AST_LIST_UNLOCK(&d->subs);
6445 return;
6446 }
6447 }
6448 if (sub->subtype == SUB_THREEWAY) {
6450 "Device '%s' with threeway call subchannels allocated, aborting.\n",
6451 d->name);
6452 AST_LIST_UNLOCK(&d->subs);
6453 return;
6454 }
6456 ast_mutex_destroy(&sub->lock);
6457 ast_free(sub);
6458 }
6460 AST_LIST_UNLOCK(&d->subs);
6461
6462
6463 AST_LIST_LOCK(&d->lines);
6464 AST_LIST_TRAVERSE_SAFE_BEGIN(&d->lines, l, list){
6468 }
6470 AST_LIST_UNLOCK(&d->lines);
6471
6472 if (d->session) {
6473 if (sessions == d->session) {
6474 sessions = d->session->next;
6475 } else {
6476 s = sessions;
6477 while (s) {
6478 if (s->next == d->session) {
6479 s->next = d->session->next;
6480 break;
6481 }
6482 s = s->next;
6483 }
6484 }
6485 ast_mutex_destroy(&d->session->lock);
6486 ast_free(d->session);
6487 }
6488 if (devices == d) {
6489 devices = d->next;
6490 } else {
6491 struct unistim_device *d2 = devices;
6492 while (d2) {
6493 if (d2->next == d) {
6494 d2->next = d->next;
6495 break;
6496 }
6497 d2 = d2->next;
6498 }
6499 }
6500 if (d->tz) {
6501 d->tz = ast_tone_zone_unref(d->tz);
6502 }
6503 ast_mutex_destroy(&d->lock);
6504 ast_free(d);
6505}
struct unistim_device * next

References ast_free, AST_LIST_LOCK, AST_LIST_REMOVE_CURRENT, AST_LIST_TRAVERSE_SAFE_BEGIN, AST_LIST_TRAVERSE_SAFE_END, AST_LIST_UNLOCK, ast_log, ast_mutex_destroy, ast_tone_zone_unref(), ast_verb, d, devices, unistim_line::lock, LOG_WARNING, test_val::name, unistim_device::next, unistimsession::next, test_val::next, sessions, sub, SUB_REAL, SUB_THREEWAY, unistim_line_destroy(), and unistimdebug.

Referenced by build_device(), and reload_config().

◆ discard_call()

static void discard_call ( struct unistimsession pte)
static

Definition at line 2649 of file chan_unistim.c.

2650{
2651 struct unistim_subchannel* sub;
2652 sub = get_sub(pte->device, SUB_RING);
2653 if (!sub) {
2654 return;
2655 }
2656
2658 return;
2659}
#define SUB_RING

References AST_CAUSE_NORMAL_CLEARING, ast_queue_hangup_with_cause(), unistimsession::device, get_sub(), sub, and SUB_RING.

Referenced by key_ringing().

◆ display_last_error()

static void display_last_error ( const char *  sz_msg)
static

Definition at line 891 of file chan_unistim.c.

892{
893 /* Display the error message */
894 ast_log(LOG_WARNING, "%s : (%d) %s\n", sz_msg, errno, strerror(errno));
895}
int errno

References ast_log, errno, and LOG_WARNING.

Referenced by key_history(), open_history(), send_raw_client(), show_entry_history(), write_entry_history(), and write_history().

◆ do_monitor()

static void * do_monitor ( void *  data)
static

Definition at line 5841 of file chan_unistim.c.

5842{
5843 struct unistimsession *cur = NULL;
5844 unsigned int dw_timeout = 0;
5845 unsigned int tick;
5846 int res;
5847 int reloading;
5848
5849 /* Add an I/O event to our UDP socket */
5850 if (unistimsock > -1) {
5852 }
5853 /* This thread monitors our UDP socket and timers */
5854 for (;;) {
5855 /* This loop is executed at least every IDLE_WAITus (1s) or every time a packet is received */
5856 /* Looking for the smallest time-out value */
5857 tick = get_tick_count();
5858 dw_timeout = UINT_MAX;
5860 cur = sessions;
5861 DEBUG_TIMER("checking timeout for session %p with tick = %u\n", cur, tick);
5862 while (cur) {
5863 DEBUG_TIMER("checking timeout for session %p timeout = %u\n", cur,
5864 cur->timeout);
5865 /* Check if we have miss something */
5866 if (cur->timeout <= tick) {
5867 DEBUG_TIMER("Event for session %p\n", cur);
5868 /* If the queue is empty, send a ping */
5869 if (cur->last_buf_available == 0) {
5870 send_ping(cur);
5871 } else {
5872 if (send_retransmit(cur)) {
5873 DEBUG_TIMER("The chained link was modified, restarting...\n");
5874 cur = sessions;
5875 dw_timeout = UINT_MAX;
5876 continue;
5877 }
5878 }
5879 }
5880 if (dw_timeout > cur->timeout - tick) {
5881 dw_timeout = cur->timeout - tick;
5882 }
5883 /* Checking if the phone is logged on for a new MWI */
5884 if (cur->device) {
5885 struct unistim_line *l;
5886 AST_LIST_LOCK(&cur->device->lines);
5887 AST_LIST_TRAVERSE(&cur->device->lines, l, list) {
5888 if ((!ast_strlen_zero(l->mailbox)) && (tick >= l->parent->nextmsgcheck)) {
5889 DEBUG_TIMER("Checking mailbox for MWI\n");
5890 unistim_send_mwi_to_peer(l, tick);
5891 break;
5892 }
5893 }
5895 if (cur->device->nextdial && tick >= cur->device->nextdial) {
5897 cur->device->nextdial = 0;
5898 }
5899 }
5900 cur = cur->next;
5901 }
5903 DEBUG_TIMER("Waiting for %dus\n", dw_timeout);
5904 res = dw_timeout;
5905 /* We should not wait more than IDLE_WAIT */
5906 if ((res < 0) || (res > IDLE_WAIT)) {
5907 res = IDLE_WAIT;
5908 }
5909 /* Wait for UDP messages for a maximum of res us */
5910 res = ast_io_wait(io, res); /* This function will call unistimsock_read if a packet is received */
5911 /* Check for a reload request */
5913 reloading = unistim_reloading;
5916 if (reloading) {
5917 ast_verb(1, "Reloading unistim.conf...\n");
5918 reload_config();
5919 }
5920 pthread_testcancel();
5921 }
5922 /* Never reached */
5923 return NULL;
5924}
static ast_mutex_t unistim_reload_lock
static void handle_call_outgoing(struct unistimsession *s)
#define IDLE_WAIT
static int unistim_reloading
static void send_ping(struct unistimsession *pte)
static int unistimsock_read(int *id, int fd, short events, void *ignore)
static int send_retransmit(struct unistimsession *pte)
static int unistim_send_mwi_to_peer(struct unistim_line *peer, unsigned int tick)
static int reload_config(void)
static struct io_context * io
#define DEBUG_TIMER
#define AST_IO_IN
Definition io.h:34
int * ast_io_add(struct io_context *ioc, int fd, ast_io_cb callback, short events, void *data)
Adds an IO context.
Definition io.c:162
int ast_io_wait(struct io_context *ioc, int howlong)
Waits for IO.
Definition io.c:278
#define AST_LIST_TRAVERSE(head, var, field)
Loops over (traverses) the entries in a list.
struct unistim_device::@138 lines

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

Referenced by restart_monitor().

◆ dummy()

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

◆ find_language()

static int find_language ( const char *  lang)
static

Definition at line 3815 of file chan_unistim.c.

3816{
3817 int i = 0;
3818 while (options_languages[i].lang_short != NULL) {
3819 if(!strcmp(options_languages[i].lang_short, lang)) {
3820 return i;
3821 }
3822 i++;
3823 }
3824 return 0;
3825}
static struct unistim_languages options_languages[]

References NULL, and options_languages.

Referenced by handle_select_language(), init_phone_step2(), reload_config(), send_charset_update(), and ustmtext().

◆ find_line_by_number()

static struct unistim_line * find_line_by_number ( struct unistim_device d,
const char *  val 
)
static

Definition at line 6414 of file chan_unistim.c.

6414 {
6415 struct unistim_line *l, *ret = NULL;
6416
6417 AST_LIST_LOCK(&d->lines);
6418 AST_LIST_TRAVERSE(&d->lines, l, list) {
6419 if (!strcmp(l->name, val)) {
6420 ret = l;
6421 break;
6422 }
6423 }
6424 AST_LIST_UNLOCK(&d->lines);
6425 return ret;
6426}

References AST_LIST_LOCK, AST_LIST_TRAVERSE, AST_LIST_UNLOCK, d, unistim_line::list, unistim_line::name, and NULL.

Referenced by build_device().

◆ find_rtp_port()

static int find_rtp_port ( struct unistim_subchannel s)
static

Definition at line 2687 of file chan_unistim.c.

2688{
2689 struct unistim_subchannel *sub = NULL;
2690 int rtp_start = s->parent->parent->rtp_port;
2691 struct ast_sockaddr us_tmp;
2692 struct sockaddr_in us = { 0, };
2693
2695 AST_LIST_TRAVERSE(&s->parent->parent->subs, sub, list) {
2696 if (!sub) {
2697 continue;
2698 }
2699 if (sub->rtp) {
2701 ast_sockaddr_to_sin(&us_tmp, &us);
2702 if (htons(us.sin_port)) {
2703 rtp_start = htons(us.sin_port) + 1;
2704 break;
2705 }
2706 }
2707 }
2709 return rtp_start;
2710}
#define ast_sockaddr_to_sin(addr, sin)
Converts a struct ast_sockaddr to a struct sockaddr_in.
Definition netsock2.h:765
#define ast_rtp_instance_get_remote_address(instance, address)
Get the address of the remote endpoint that we are sending RTP to.
Socket address structure.
Definition netsock2.h:97
struct unistim_line * parent

References AST_LIST_LOCK, AST_LIST_TRAVERSE, AST_LIST_UNLOCK, ast_rtp_instance_get_remote_address, ast_sockaddr_to_sin, NULL, unistim_subchannel::parent, unistim_line::parent, unistim_device::rtp_port, sub, and unistim_device::subs.

Referenced by start_rtp().

◆ find_subchannel_by_name()

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

Definition at line 5427 of file chan_unistim.c.

5428{
5429 struct unistim_line *l;
5430 struct unistim_device *d;
5431 struct unistim_subchannel *sub = NULL;
5432 char line[256];
5433 char *at;
5434 char *device;
5435
5436 ast_copy_string(line, dest, sizeof(line));
5437 at = strchr(line, '@');
5438 if (!at) {
5439 ast_log(LOG_NOTICE, "Device '%s' has no @ (at) sign!\n", dest);
5440 return NULL;
5441 }
5442 *at = '\0';
5443 at++;
5444 device = at;
5446 d = devices;
5447 at = strchr(device, '/'); /* Extra options ? */
5448 if (at) {
5449 *at = '\0';
5450 }
5451 while (d) {
5452 if (!strcasecmp(d->name, device)) {
5453 if (unistimdebug) {
5454 ast_verb(0, "Found device: %s\n", d->name);
5455 }
5456 /* Found the device */
5457 AST_LIST_LOCK(&d->lines);
5458 AST_LIST_TRAVERSE(&d->lines, l, list) {
5459 /* Search for the right line */
5460 if (!strcasecmp(l->name, line)) {
5461 if (unistimdebug) {
5462 ast_verb(0, "Found line: %s\n", l->name);
5463 }
5464 sub = get_sub(d, SUB_REAL);
5465 if (!sub) {
5467 }
5468 if (sub->owner) {
5469 /* Allocate additional channel if asterisk channel already here */
5471 sub->holding = 1;
5472 }
5473 sub->ringvolume = -1;
5474 sub->ringstyle = -1;
5475 if (at) { /* Other options ? */
5476 at++; /* Skip slash */
5477 if (*at == 'r') { /* distinctive ring */
5478 at++;
5479 if ((*at < '0') || (*at > '7')) { /* ring style */
5480 ast_log(LOG_WARNING, "Invalid ring selection (%s)", at);
5481 } else {
5482 signed char ring_volume = -1;
5483 signed char ring_style = *at - '0';
5484 at++;
5485 if ((*at >= '0') && (*at <= '3')) { /* ring volume */
5486 ring_volume = *at - '0';
5487 }
5488 if (unistimdebug) {
5489 ast_verb(0, "Distinctive ring: style #%d volume %d\n",
5490 ring_style, ring_volume);
5491 }
5492 sub->ringvolume = ring_volume;
5493 sub->ringstyle = ring_style;
5494 }
5495 }
5496 }
5497 sub->parent = l;
5498 break;
5499 }
5500 }
5501 AST_LIST_UNLOCK(&d->lines);
5502 if (sub) {
5504 return sub;
5505 }
5506 }
5507 d = d->next;
5508 }
5509 /* Device not found */
5511
5512 return NULL;
5513}
static struct unistim_subchannel * unistim_alloc_sub(struct unistim_device *d, int x)
#define LOG_NOTICE
struct unistim_subchannel::@135 list

References ast_copy_string(), AST_LIST_LOCK, AST_LIST_TRAVERSE, AST_LIST_UNLOCK, ast_log, ast_mutex_lock, ast_mutex_unlock, ast_verb, d, devicelock, devices, get_sub(), unistim_subchannel::list, LOG_NOTICE, LOG_WARNING, unistim_line::name, test_val::name, test_val::next, NULL, sub, SUB_REAL, unistim_alloc_sub(), and unistimdebug.

Referenced by unistim_request(), and unistim_sp().

◆ finish_bookmark()

static void finish_bookmark ( void  )
static

Definition at line 6386 of file chan_unistim.c.

6387{
6388 struct unistim_device *d = devices;
6389 int i;
6391 while (d) {
6392 for (i = 0; i < 6; i++) {
6393 if (d->softkeyicon[i] == 1) { /* Something for us */
6394 struct unistim_device *d2 = devices;
6395 while (d2) {
6396 if (!strcmp(d->softkeydevice[i], d2->name)) {
6397 d->sp[i] = d2;
6398 d->softkeyicon[i] = 0;
6399 break;
6400 }
6401 d2 = d2->next;
6402 }
6403 if (d->sp[i] == NULL) {
6404 ast_log(LOG_NOTICE, "Bookmark entry with device %s not found\n",
6405 d->softkeydevice[i]);
6406 }
6407 }
6408 }
6409 d = d->next;
6410 }
6412}

References ast_log, ast_mutex_lock, ast_mutex_unlock, d, devicelock, devices, LOG_NOTICE, unistim_device::name, unistim_device::next, test_val::next, and NULL.

Referenced by reload_config().

◆ get_active_softkey()

static int get_active_softkey ( struct unistimsession pte)
static

Definition at line 1382 of file chan_unistim.c.

1383{
1384 return pte->device->selected;
1385}

References unistimsession::device, and unistim_device::selected.

Referenced by change_favorite_icon().

◆ get_avail_softkey()

static int get_avail_softkey ( struct unistimsession pte,
const char *  name 
)
static

Definition at line 1387 of file chan_unistim.c.

1388{
1389 int i;
1390
1391 if (!is_key_line(pte->device, pte->device->selected)) {
1392 pte->device->selected = -1;
1393 }
1394 for (i = 0; i < FAVNUM; i++) {
1395 if (pte->device->selected != -1 && pte->device->selected != i) {
1396 continue;
1397 }
1398 if (!soft_key_visible(pte->device, i)) {
1399 continue;
1400 }
1401 if (pte->device->ssub[i]) {
1402 continue;
1403 }
1404 if (is_key_line(pte->device, i)) {
1405 if (name && strcmp(name, pte->device->sline[i]->name)) {
1406 continue;
1407 }
1408 if (unistimdebug) {
1409 ast_verb(0, "Found softkey %d for device %s\n", i, name);
1410 }
1411 return i;
1412 }
1413 }
1414 return -1;
1415}
static int is_key_line(struct unistim_device *d, int fav)
static int soft_key_visible(struct unistim_device *d, unsigned char num)
static const char name[]
Definition format_mp3.c:68
struct unistim_subchannel * ssub[FAVNUM]
struct unistim_line * sline[FAVNUM]

References ast_verb, unistimsession::device, FAVNUM, is_key_line(), unistim_line::name, name, unistim_device::selected, unistim_device::sline, soft_key_visible(), unistim_device::ssub, and unistimdebug.

Referenced by handle_call_outgoing(), key_main_page(), process_request(), and unistim_request().

◆ get_sub()

static struct unistim_subchannel * get_sub ( struct unistim_device device,
int  type 
)
static

◆ get_sub_holding()

static struct unistim_subchannel * get_sub_holding ( struct unistim_device device,
int  type,
int  holding 
)
static

Definition at line 2513 of file chan_unistim.c.

2514{
2515 struct unistim_subchannel *sub = NULL;
2516
2517 AST_LIST_LOCK(&device->subs);
2518 AST_LIST_TRAVERSE(&device->subs, sub, list) {
2519 if (!sub) {
2520 continue;
2521 }
2522 if (sub->subtype == type && sub->holding == holding) {
2523 break;
2524 }
2525 }
2526 AST_LIST_UNLOCK(&device->subs);
2527
2528 return sub;
2529}

References AST_LIST_LOCK, AST_LIST_TRAVERSE, AST_LIST_UNLOCK, unistim_subchannel::holding, unistim_subchannel::list, NULL, sub, unistim_device::subs, and type.

Referenced by handle_key_fav().

◆ get_tick_count()

static unsigned int get_tick_count ( void  )
static

Definition at line 897 of file chan_unistim.c.

898{
899 struct timeval now = ast_tvnow();
900
901 return (now.tv_sec * 1000) + (now.tv_usec / 1000);
902}

References ast_tvnow().

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

◆ get_to_address()

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

Definition at line 1004 of file chan_unistim.c.

1005{
1006#ifdef HAVE_PKTINFO
1007 int err;
1008 char cmbuf[0x100];
1009 struct cmsghdr *cmsg;
1010 struct sockaddr_in peeraddr;
1011 struct in_addr addr;
1012 struct msghdr mh = {
1013 .msg_name = &peeraddr,
1014 .msg_namelen = sizeof(peeraddr),
1015 .msg_control = cmbuf,
1016 .msg_controllen = sizeof(cmbuf),
1017 };
1018 memset(&addr, 0, sizeof(addr));
1019 /* Get info about the incoming packet */
1020 err = recvmsg(fd, &mh, MSG_PEEK);
1021 if (err == -1) {
1022 ast_log(LOG_WARNING, "recvmsg returned an error: %s\n", strerror(errno));
1023 return err;
1024 }
1025 for(cmsg = CMSG_FIRSTHDR(&mh);
1026 cmsg != NULL;
1027 cmsg = CMSG_NXTHDR(&mh, cmsg))
1028 {
1029 if (cmsg->cmsg_level == IPPROTO_IP && cmsg->cmsg_type == IP_PKTINFO) {
1030 struct in_pktinfo *pkt = (struct in_pktinfo*)CMSG_DATA(cmsg);
1031 addr = pkt->ipi_addr;
1032 if (unistimdebug) {
1033 ast_verb(0, "message received on address %s\n", ast_inet_ntoa(addr));
1034 }
1035 }
1036 }
1037 memcpy(&toAddr->sin_addr, &addr, sizeof(struct in_addr));
1038 return err;
1039#else
1040 memcpy(toAddr, &public_ip, sizeof(*toAddr));
1041 return 0;
1042#endif
1043}
static struct sockaddr_in public_ip

References ast_inet_ntoa(), ast_log, ast_verb, errno, LOG_WARNING, NULL, public_ip, and unistimdebug.

Referenced by create_client().

◆ handle_call_incoming()

static void handle_call_incoming ( struct unistimsession s)
static

Definition at line 3264 of file chan_unistim.c.

3265{
3266 struct unistim_subchannel *sub = NULL;
3267 int i;
3268
3269 s->state = STATE_CALL;
3270 s->device->missed_call = 0;
3271 send_no_ring(s);
3272 sub = get_sub(s->device, SUB_RING); /* Put other SUB_REAL call on hold */
3273 if (!sub) {
3274 ast_log(LOG_WARNING, "No ringing lines on: %s\n", s->device->name);
3275 return;
3276 }
3277 /* Change icons for all ringing keys */
3278 for (i = 0; i < FAVNUM; i++) {
3279 if (!s->device->ssub[i]) { /* No sub assigned - skip */
3280 continue;
3281 }
3282 if (s->device->ssub[i]->subtype == SUB_REAL) {
3283 sub_hold(s, s->device->ssub[i]);
3284 }
3285 if (s->device->ssub[i] != sub) {
3286 continue;
3287 }
3288 if (sub->softkey == i) { /* If softkey assigned at this moment - do not erase */
3289 continue;
3290 }
3291 if (sub->softkey < 0) { /* If softkey not defined - first one used */
3292 sub->softkey = i;
3293 continue;
3294 }
3296 s->device->ssub[i] = NULL;
3297 }
3298 if (sub->softkey < 0) {
3299 ast_log(LOG_WARNING, "Can not assign softkey for incoming call on: %s\n", s->device->name);
3300 return;
3301 }
3303 sub->parent = s->device->sline[sub->softkey];
3304 sub->subtype = SUB_REAL;
3305 if (unistimdebug) {
3306 ast_verb(0, "Handle Call Incoming for %s@%s\n", sub->parent->name,
3307 s->device->name);
3308 }
3309 start_rtp(sub);
3310 if (!sub->rtp) {
3311 ast_log(LOG_WARNING, "Unable to create channel for %s@%s\n", sub->parent->name, s->device->name);
3312 return;
3313 }
3314 if (sub->owner) {
3316 }
3317 send_text(TEXT_LINE2, TEXT_NORMAL, s, ustmtext("is on-line", s));
3318 send_text_status(s, ustmtext(" Transf Hangup", s));
3320
3321 if ((s->device->output == OUTPUT_HANDSET) &&
3324 } else {
3326 }
3327 write_history(s, 'i', 0);
3328 return;
3329}
#define TEXT_NORMAL
static void send_text(unsigned char pos, unsigned char inverse, struct unistimsession *pte, const char *text)
static void sub_hold(struct unistimsession *pte, struct unistim_subchannel *sub)
static void start_rtp(struct unistim_subchannel *sub)
static const char * ustmtext(const char *str, struct unistimsession *pte)
#define FAV_ICON_OFFHOOK_BLACK
static void send_select_output(struct unistimsession *pte, unsigned char output, unsigned char volume, unsigned char mute)
static void send_text_status(struct unistimsession *pte, const char *text)
static void send_start_timer(struct unistimsession *pte)
#define TEXT_LINE2
#define OUTPUT_SPEAKER
static void send_no_ring(struct unistimsession *pte)
int ast_queue_control(struct ast_channel *chan, enum ast_control_frame_type control)
Queue a control frame without payload.
Definition channel.c:1289
unsigned int subtype

References AST_CONTROL_ANSWER, ast_log, ast_queue_control(), ast_verb, unistimsession::device, FAV_ICON_OFFHOOK_BLACK, FAV_LINE_ICON, FAVNUM, get_sub(), LOG_WARNING, unistim_device::missed_call, MUTE_OFF, unistim_device::name, NULL, unistim_device::output, OUTPUT_HANDSET, OUTPUT_SPEAKER, unistim_device::receiver_state, send_favorite_short(), send_no_ring(), send_select_output(), send_start_timer(), send_text(), send_text_status(), unistim_device::sline, unistim_device::ssub, start_rtp(), unistimsession::state, STATE_CALL, STATE_ONHOOK, sub, sub_hold(), SUB_REAL, SUB_RING, unistim_subchannel::subtype, TEXT_LINE2, TEXT_NORMAL, unistimdebug, ustmtext(), unistim_device::volume, and write_history().

Referenced by handle_key_fav(), key_ringing(), and process_request().

◆ handle_call_outgoing()

static void handle_call_outgoing ( struct unistimsession s)
static

Definition at line 3113 of file chan_unistim.c.

3114{
3115 struct ast_channel *c;
3116 struct unistim_subchannel *sub;
3117 int softkey;
3118
3119 s->state = STATE_CALL;
3120
3122 if (sub) {
3123 /* If sub for threway call created than we use transfer behavior */
3124 struct unistim_subchannel *sub_trans = NULL;
3125 struct unistim_device *d = s->device;
3126
3127 sub_trans = get_sub(d, SUB_REAL);
3128 if (sub_trans) {
3129 ast_log(LOG_WARNING, "Can't transfer while active subchannel exists!\n");
3130 return;
3131 }
3132 if (!sub->owner) {
3133 ast_log(LOG_WARNING, "Unable to find subchannel with music on hold\n");
3134 return;
3135 }
3136
3137 sub_trans = unistim_alloc_sub(d, SUB_REAL);
3138 if (!sub_trans) {
3139 ast_log(LOG_WARNING, "Unable to allocate three-way subchannel\n");
3140 return;
3141 }
3142 sub_trans->parent = sub->parent;
3144 send_tone(s, 0, 0);
3145 /* Make new channel */
3146 c = unistim_new(sub_trans, AST_STATE_DOWN, NULL, NULL);
3147 if (!c) {
3148 ast_log(LOG_WARNING, "Cannot allocate new structure on channel %p\n", sub->parent);
3149 return;
3150 }
3151 /* Swap things around between the three-way and real call */
3152 swap_subs(sub, sub_trans);
3154 if (s->device->height == 1) {
3156 } else {
3157 send_text(TEXT_LINE0, TEXT_NORMAL, s, ustmtext("Calling (pre-transfer)", s));
3159 send_text(TEXT_LINE2, TEXT_NORMAL, s, ustmtext("Dialing...", s));
3160 }
3161 send_text_status(s, ustmtext("TransfrCancel", s));
3162
3163 if (ast_pthread_create(&sub->ss_thread, NULL, unistim_ss, c)) {
3164 ast_log(LOG_WARNING, "Unable to start simple switch on channel %p\n", c);
3165 sub->ss_thread = AST_PTHREADT_NULL;
3166 ast_hangup(c);
3167 return;
3168 }
3169 if (unistimdebug) {
3170 ast_verb(0, "Started three way call on channel %p (%s) subchan %u\n",
3171 sub_trans->owner, ast_channel_name(sub_trans->owner), sub_trans->subtype);
3172 }
3173 return;
3174 }
3175
3176 softkey = get_avail_softkey(s, NULL);
3177 if (softkey == -1) {
3178 ast_log(LOG_WARNING, "Have no avail softkey for calling\n");
3179 return;
3180 }
3181 sub = get_sub(s->device, SUB_REAL);
3182 if (sub) { /* have already call assigned */
3183 sub_hold(s, sub); /* Need to put on hold */
3184 }
3185 if (!(sub = unistim_alloc_sub(s->device, SUB_REAL))) {
3186 ast_log(LOG_WARNING, "Unable to allocate subchannel!\n");
3187 return;
3188 }
3189 sub->parent = s->device->sline[softkey];
3190 s->device->ssub[softkey] = sub;
3191 sub->softkey = softkey;
3192
3193 if (unistimdebug) {
3194 ast_verb(0, "Using softkey %d, line %p\n", sub->softkey, sub->parent);
3195 }
3197 s->device->selected = -1;
3198 if (!sub->owner) { /* A call is already in progress ? */
3199 RAII_VAR(struct ast_features_pickup_config *, pickup_cfg, NULL, ao2_cleanup);
3200 const char *pickupexten;
3201
3202 c = unistim_new(sub, AST_STATE_DOWN, NULL, NULL); /* No, starting a new one */
3203 if (!sub->rtp) { /* Need to start RTP before calling ast_pbx_run */
3204 start_rtp(sub);
3205 }
3206 if (c) {
3209 if (!pickup_cfg) {
3210 ast_log(LOG_ERROR, "Unable to retrieve pickup configuration options. Unable to detect call pickup extension\n");
3211 pickupexten = "";
3212 } else {
3213 pickupexten = ast_strdupa(pickup_cfg->pickupexten);
3214 }
3216 }
3217 if (c && !strcmp(s->device->phone_number, pickupexten)) {
3218 if (unistimdebug) {
3219 ast_verb(0, "Try to pickup in unistim_new\n");
3220 }
3222 send_text_status(s, ustmtext(" Transf Hangup", s));
3224 if (ast_pickup_call(c)) {
3225 ast_log(LOG_NOTICE, "Nothing to pick up\n");
3227 } else {
3229 }
3230 ast_hangup(c);
3231 c = NULL;
3232 } else if (c) {
3234 send_tone(s, 0, 0); /* Dialing empty number should also stop dial tone */
3235 if (s->device->height == 1) {
3236 if (strlen(s->device->phone_number) > 0) {
3238 } else {
3239 send_text(TEXT_LINE0, TEXT_NORMAL, s, ustmtext("Calling...", s));
3240 }
3241 } else {
3242 send_text(TEXT_LINE0, TEXT_NORMAL, s, ustmtext("Calling :", s));
3244 send_text(TEXT_LINE2, TEXT_NORMAL, s, ustmtext("Dialing...", s));
3245 }
3246 send_text_status(s, ustmtext(" Hangup", s));
3247
3248 /* start switch */
3249 if (ast_pthread_create(&sub->ss_thread, NULL, unistim_ss, c)) {
3250 ast_log(LOG_WARNING, "Unable to create switch thread\n");
3251 sub->ss_thread = AST_PTHREADT_NULL;
3253 }
3254 } else
3255 ast_log(LOG_WARNING, "Unable to create channel for %s@%s\n",
3256 sub->parent->name, s->device->name);
3257 } else {
3258 ast_debug(1, "Current sub [%s] already has owner\n", ast_channel_name(sub->owner));
3259 }
3260 return;
3261}
#define ast_strdupa(s)
duplicate a string in memory from the stack
Definition astmm.h:298
#define ao2_cleanup(obj)
Definition astobj2.h:1934
#define AST_CAUSE_SWITCH_CONGESTION
Definition causes.h:123
#define AST_CAUSE_CALL_REJECTED
Definition causes.h:111
static int get_avail_softkey(struct unistimsession *pte, const char *name)
static struct ast_channel * unistim_new(struct unistim_subchannel *sub, int state, const struct ast_assigned_ids *assignedids, const struct ast_channel *requestor)
static void * unistim_ss(void *data)
static void sub_stop_silence(struct unistimsession *pte, struct unistim_subchannel *sub)
static void send_tone(struct unistimsession *pte, uint16_t tone1, uint16_t tone2)
static void swap_subs(struct unistim_subchannel *a, struct unistim_subchannel *b)
#define TEXT_LINE1
#define TEXT_LINE0
const char * ast_channel_name(const struct ast_channel *chan)
void ast_hangup(struct ast_channel *chan)
Hang up a channel.
Definition channel.c:2540
#define ast_channel_lock(chan)
Definition channel.h:2983
void ast_channel_hangupcause_set(struct ast_channel *chan, int value)
#define ast_channel_unlock(chan)
Definition channel.h:2984
@ AST_STATE_DOWN
struct ast_features_pickup_config * ast_get_chan_features_pickup_config(struct ast_channel *chan)
Get the pickup configuration options for a channel.
#define AST_PTHREADT_NULL
Definition lock.h:73
int ast_pickup_call(struct ast_channel *chan)
Pickup a call.
Definition pickup.c:202
Configuration relating to call pickup.
char phone_number[AST_MAX_EXTENSION]
static struct test_val c
#define ast_pthread_create(a, b, c, d)
Definition utils.h:624

References ao2_cleanup, AST_CAUSE_CALL_REJECTED, AST_CAUSE_NORMAL_CLEARING, AST_CAUSE_SWITCH_CONGESTION, ast_channel_hangupcause_set(), ast_channel_lock, ast_channel_name(), ast_channel_unlock, ast_debug, ast_get_chan_features_pickup_config(), ast_hangup(), ast_log, ast_pickup_call(), ast_pthread_create, AST_PTHREADT_NULL, ast_queue_hangup_with_cause(), AST_STATE_DOWN, ast_strdupa, ast_verb, c, d, unistimsession::device, FAV_ICON_OFFHOOK_BLACK, get_avail_softkey(), get_sub(), unistim_device::height, LOG_ERROR, LOG_NOTICE, LOG_WARNING, MUTE_OFF, unistim_device::name, NULL, unistim_device::output, unistim_subchannel::owner, unistim_subchannel::parent, unistim_device::phone_number, RAII_VAR, unistim_device::selected, send_favorite_short(), send_select_output(), send_start_timer(), send_text(), send_text_status(), send_tone(), unistim_device::sline, unistim_subchannel::softkey, unistim_device::ssub, start_rtp(), unistimsession::state, STATE_CALL, sub, sub_hold(), SUB_REAL, sub_stop_silence(), SUB_THREEWAY, unistim_subchannel::subtype, swap_subs(), TEXT_LINE0, TEXT_LINE1, TEXT_LINE2, TEXT_NORMAL, unistim_alloc_sub(), unistim_new(), unistim_ss(), unistimdebug, ustmtext(), and unistim_device::volume.

Referenced by do_monitor(), key_dial_page(), key_favorite(), and key_main_page().

◆ handle_dial_page()

static void handle_dial_page ( struct unistimsession pte)
static

Definition at line 2985 of file chan_unistim.c.

2986{
2987 pte->state = STATE_DIALPAGE;
2988 if (pte->device->call_forward[0] == -1) {
2989 send_text(TEXT_LINE0, TEXT_NORMAL, pte, "");
2990 send_text(TEXT_LINE1, TEXT_NORMAL, pte, ustmtext("Enter forward", pte));
2991 send_text_status(pte, ustmtext("Fwd Cancel BackSp Erase", pte));
2992 if (pte->device->call_forward[1] != 0) {
2994 sizeof(pte->device->phone_number));
2995 show_phone_number(pte);
2997 return;
2998 }
2999 } else {
3000 if ((pte->device->output == OUTPUT_HANDSET) &&
3001 (pte->device->receiver_state == STATE_ONHOOK)) {
3003 } else {
3005 }
3006 send_dial_tone(pte);
3007
3008 if (pte->device->height > 1) {
3009 send_text(TEXT_LINE0, TEXT_NORMAL, pte, ustmtext("Enter the number to dial", pte));
3010 send_text(TEXT_LINE1, TEXT_NORMAL, pte, ustmtext("and press Call", pte));
3011 }
3013 send_text_status(pte, ustmtext("Call BackSp Erase", pte));
3014 } else {
3015 send_text_status(pte, ustmtext("Call Redial BackSp Erase", pte));
3016 }
3017 }
3018
3019 pte->device->size_phone_number = 0;
3020 pte->device->phone_number[0] = 0;
3021 show_phone_number(pte);
3024 pte->device->missed_call = 0;
3026 pte->device->lastmsgssent = -1;
3027 return;
3028}
static void send_led_update(struct unistimsession *pte, unsigned char led)
static void send_dial_tone(struct unistimsession *pte)
#define LED_BAR_OFF
#define FAV_ICON_PHONE_BLACK
static void show_phone_number(struct unistimsession *pte)
static void send_icon(unsigned char pos, unsigned char status, struct unistimsession *pte)
char call_forward[AST_MAX_EXTENSION]

References ast_copy_string(), ast_strlen_zero(), unistim_device::call_forward, change_favorite_icon(), unistimsession::device, FAV_ICON_NONE, FAV_ICON_PHONE_BLACK, unistim_device::height, unistim_device::lastmsgssent, LED_BAR_OFF, unistim_device::missed_call, MUTE_OFF, unistim_device::output, OUTPUT_HANDSET, OUTPUT_SPEAKER, unistim_device::phone_number, unistim_device::receiver_state, unistim_device::redial_number, send_dial_tone(), send_icon(), send_led_update(), send_select_output(), send_text(), send_text_status(), show_phone_number(), unistim_device::size_phone_number, unistimsession::state, STATE_DIALPAGE, STATE_ONHOOK, TEXT_LINE0, TEXT_LINE1, TEXT_NORMAL, ustmtext(), and unistim_device::volume.

Referenced by handle_key_fav(), key_main_page(), process_request(), and transfer_call_step1().

◆ handle_key_fav()

static void handle_key_fav ( struct unistimsession pte,
char  keycode 
)
static

Definition at line 3382 of file chan_unistim.c.

3383{
3384 int keynum = keycode - KEY_FAV0;
3385 struct unistim_subchannel *sub, *sub_key = NULL;
3386 sub = get_sub_holding(pte->device, SUB_REAL, 0);
3387
3388 /* Make an action on selected favorite key */
3389 if (!pte->device->ssub[keynum]) { /* Key have no assigned call */
3390 sub = get_sub_holding(pte->device, SUB_REAL, 0);
3392 if (is_key_line(pte->device, keynum)) {
3393 if (unistimdebug) {
3394 ast_verb(0, "Handle line w/o sub - dialpage\n");
3395 }
3396 pte->device->selected = keynum;
3397 sub_hold(pte, sub); /* Put active call on hold */
3398 send_stop_timer(pte);
3399 handle_dial_page(pte);
3400 } else if (is_key_favorite(pte->device, keynum)) {
3401 /* Put active call on hold in handle_call_outgoing function, after preparation and
3402 checking if lines available for calling */
3403 if (unistimdebug) {
3404 ast_verb(0, "Handle favorite w/o sub - dialing\n");
3405 }
3406 if ((pte->device->output == OUTPUT_HANDSET) &&
3407 (pte->device->receiver_state == STATE_ONHOOK)) {
3409 } else {
3411 }
3412 key_favorite(pte, keycode);
3413 }
3414 } else {
3415 sub_key = pte->device->ssub[keynum];
3416 /* Favicon have assigned sub, activate it and put current on hold */
3417 if (sub_key->subtype == SUB_REAL && !sub_key->holding) {
3418 sub_hold(pte, sub_key);
3419 show_main_page(pte);
3420 } else if (sub_key->subtype == SUB_REAL && sub_key->holding) {
3421 /* We are going to unhold line (we should put active line on hold, of any) */
3422 if (pte->state == STATE_DIALPAGE){
3423 send_tone(pte, 0, 0);
3424 }
3425 sub_hold(pte, sub);
3426 send_callerid_screen(pte, sub_key);
3427 sub_unhold(pte, sub_key);
3428 pte->state = STATE_CALL;
3429 } else if (sub_key->subtype == SUB_RING) {
3430 sub_hold(pte, sub);
3431 sub_key->softkey = keynum;
3433 }
3434 }
3435}
static struct unistim_subchannel * get_sub_holding(struct unistim_device *device, int type, int holding)
static void handle_call_incoming(struct unistimsession *s)
static void sub_unhold(struct unistimsession *pte, struct unistim_subchannel *sub)
static void send_callerid_screen(struct unistimsession *, struct unistim_subchannel *)
static int is_key_favorite(struct unistim_device *d, int fav)
static void handle_dial_page(struct unistimsession *pte)
static void send_favorite_selected(unsigned char status, struct unistimsession *pte)
static void key_favorite(struct unistimsession *, char)

References ast_verb, unistimsession::device, FAV_LINE_ICON, get_sub_holding(), handle_call_incoming(), handle_dial_page(), unistim_subchannel::holding, is_key_favorite(), is_key_line(), KEY_FAV0, key_favorite(), MUTE_OFF, NULL, unistim_device::output, OUTPUT_HANDSET, OUTPUT_SPEAKER, unistim_device::receiver_state, unistim_device::selected, send_callerid_screen(), send_favorite_selected(), send_select_output(), send_stop_timer(), send_tone(), show_main_page(), unistim_subchannel::softkey, unistim_device::ssub, unistimsession::state, STATE_CALL, STATE_DIALPAGE, STATE_ONHOOK, sub, sub_hold(), SUB_REAL, SUB_RING, sub_unhold(), unistim_subchannel::subtype, unistimdebug, and unistim_device::volume.

Referenced by key_call(), key_dial_page(), key_main_page(), and key_ringing().

◆ handle_select_codec()

static void handle_select_codec ( struct unistimsession pte)
static

Definition at line 3740 of file chan_unistim.c.

3741{
3742 char buf[30], buf2[6];
3743
3744 pte->state = STATE_SELECTCODEC;
3745 ast_copy_string(buf, ustmtext("Using codec", pte), sizeof(buf));
3746 snprintf(buf2, sizeof(buf2), " %d", pte->device->codec_number);
3747 strcat(buf, buf2);
3748 strcat(buf, " (G711u=0,");
3749
3751 send_text(TEXT_LINE1, TEXT_NORMAL, pte, "G723=4,G711a=8,G729A=18)");
3753 send_blink_cursor(pte);
3755 pte->size_buff_entry = 0;
3756 send_text_status(pte, ustmtext("Select BackSp Erase Cancel", pte));
3757 return;
3758}
#define TEXT_INVERSE
static void send_blink_cursor(struct unistimsession *pte)
#define SELECTCODEC_START_ENTRY_POS
#define SELECTCODEC_MSG
static void send_cursor_pos(struct unistimsession *pte, unsigned char pos)
char buf[BUFSIZE]
Definition eagi_proxy.c:66

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

◆ handle_select_language()

static void handle_select_language ( struct unistimsession pte)
static

Definition at line 3827 of file chan_unistim.c.

3828{
3829 char tmp_language[40];
3830 struct unistim_languages lang;
3831
3832 if (pte->state != STATE_SELECTLANGUAGE) {
3834 pte->size_buff_entry = 1;
3835 pte->buff_entry[0] = find_language(pte->device->language);
3836 }
3837 lang = options_languages[(int)pte->buff_entry[0]];
3838 ast_copy_string(tmp_language, pte->device->language, sizeof(tmp_language));
3839 ast_copy_string(pte->device->language, lang.lang_short, sizeof(pte->device->language));
3840 send_charset_update(pte, lang.encoding);
3841 send_text(TEXT_LINE0, TEXT_NORMAL, pte, ustmtext(lang.label, pte));
3842
3843 ast_copy_string(pte->device->language, tmp_language, sizeof(pte->device->language));
3845 send_charset_update(pte, lang.encoding);
3846 send_text_status(pte, ustmtext("Select Cancel", pte));
3847 return;
3848}
static void send_charset_update(struct unistimsession *pte, int charset)
static int find_language(const char *)
char language[MAX_LANGUAGE]
char buff_entry[16]

References ast_copy_string(), unistimsession::buff_entry, unistimsession::device, unistim_languages::encoding, find_language(), unistim_languages::label, unistim_languages::lang_short, unistim_device::language, options_languages, send_charset_update(), send_text(), send_text_status(), unistimsession::size_buff_entry, unistimsession::state, STATE_SELECTLANGUAGE, TEXT_LINE0, TEXT_NORMAL, and ustmtext().

Referenced by key_select_language().

◆ handle_select_option()

static void handle_select_option ( struct unistimsession pte)
static

Definition at line 3695 of file chan_unistim.c.

3696{
3697 char tmp[128];
3698
3699 if (pte->state != STATE_SELECTOPTION) {
3701 pte->size_buff_entry = 1;
3702 pte->buff_entry[0] = 0; /* Position in menu */
3703 }
3704 snprintf(tmp, sizeof(tmp), "%d. %s", pte->buff_entry[0] + 1, ustmtext(options_menu[(int)pte->buff_entry[0]].label, pte));
3705 send_text(TEXT_LINE0, TEXT_NORMAL, pte, tmp);
3706 send_text_status(pte, ustmtext("Select Cancel", pte));
3707 return;
3708}
static struct unistim_menu_item options_menu[]

References unistimsession::buff_entry, unistim_menu_item::label, options_menu, send_text(), send_text_status(), unistimsession::size_buff_entry, unistimsession::state, STATE_SELECTOPTION, TEXT_LINE0, TEXT_NORMAL, and ustmtext().

Referenced by key_main_page(), key_select_language(), and key_select_option().

◆ ignore_call()

static void ignore_call ( struct unistimsession pte)
static

Definition at line 2643 of file chan_unistim.c.

2644{
2645 send_no_ring(pte);
2646 return;
2647}

References send_no_ring().

Referenced by key_ringing().

◆ in_band_indication()

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

Definition at line 5326 of file chan_unistim.c.

5328{
5329 struct ast_tone_zone_sound *ts = NULL;
5330
5331 if ((ts = ast_get_indication_tone(tz, indication))) {
5332 ast_playtones_start(ast, 0, ts->data, 1);
5334 } else {
5335 ast_log(LOG_WARNING, "Unable to get indication tone for %s\n", indication);
5336 }
5337}
static char * tz
Definition cdr_pgsql.c:71
static struct ast_tone_zone_sound * ast_tone_zone_sound_unref(struct ast_tone_zone_sound *ts)
Release a reference to an ast_tone_zone_sound.
int ast_playtones_start(struct ast_channel *chan, int vol, const char *tonelist, int interruptible)
Start playing a list of tones on a channel.
struct ast_tone_zone_sound * ast_get_indication_tone(const struct ast_tone_zone *zone, const char *indication)
Locate a tone zone sound.
Description of a tone.
Definition indications.h:35
const char * data
Description of a tone.
Definition indications.h:52

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

Referenced by unistim_indicate().

◆ init_phone_step2()

static void init_phone_step2 ( struct unistimsession pte)
static

Definition at line 4389 of file chan_unistim.c.

4390{
4391 BUFFSEND;
4392 if (unistimdebug) {
4393 ast_verb(0, "Sending S4\n");
4394 }
4395 memcpy(buffsend + SIZE_HEADER, packet_send_s4, sizeof(packet_send_s4));
4396 send_client(SIZE_HEADER + sizeof(packet_send_s4), buffsend, pte);
4397 send_date_time2(pte);
4398 send_date_time3(pte);
4399 if (unistimdebug) {
4400 ast_verb(0, "Sending S7\n");
4401 }
4402 memcpy(buffsend + SIZE_HEADER, packet_send_S7, sizeof(packet_send_S7));
4403 send_client(SIZE_HEADER + sizeof(packet_send_S7), buffsend, pte);
4404 if (unistimdebug) {
4405 ast_verb(0, "Sending Contrast\n");
4406 }
4407 memcpy(buffsend + SIZE_HEADER, packet_send_Contrast, sizeof(packet_send_Contrast));
4408 if (pte->device != NULL) {
4409 buffsend[9] = pte->device->contrast;
4410 }
4411 send_client(SIZE_HEADER + sizeof(packet_send_Contrast), buffsend, pte);
4412
4413 if (unistimdebug) {
4414 ast_verb(0, "Sending S9\n");
4415 }
4416 memcpy(buffsend + SIZE_HEADER, packet_send_s9, sizeof(packet_send_s9));
4417 send_client(SIZE_HEADER + sizeof(packet_send_s9), buffsend, pte);
4418 send_no_ring(pte);
4419
4420 if (unistimdebug) {
4421 ast_verb(0, "Sending S7\n");
4422 }
4423 memcpy(buffsend + SIZE_HEADER, packet_send_S7, sizeof(packet_send_S7));
4424 send_client(SIZE_HEADER + sizeof(packet_send_S7), buffsend, pte);
4426 send_ping(pte);
4427 if (unistimdebug) {
4428 ast_verb(0, "Sending init language\n");
4429 }
4430 if (pte->device) {
4432 }
4433 if (pte->state < STATE_MAINPAGE) {
4436 return;
4437 } else {
4438 int i;
4439 char tmp[30];
4440
4441 for (i = 1; i < FAVNUM; i++) {
4442 send_favorite(i, 0, pte, "");
4443 }
4444 send_text(TEXT_LINE0, TEXT_NORMAL, pte, ustmtext("Phone is not registered", pte));
4445 send_text(TEXT_LINE1, TEXT_NORMAL, pte, ustmtext("in unistim.conf", pte));
4446 strcpy(tmp, "MAC = ");
4447 strcat(tmp, pte->macaddr);
4448 send_text(TEXT_LINE2, TEXT_NORMAL, pte, tmp);
4449 send_text_status(pte, "");
4450 send_texttitle(pte, ustmtext("UNISTIM for*", pte));
4451 return;
4452 }
4453 }
4454 show_main_page(pte);
4456 if (unistimdebug) {
4457 ast_verb(0, "Sending arrow\n");
4458 }
4459 memcpy(buffsend + SIZE_HEADER, packet_send_arrow, sizeof(packet_send_arrow));
4460 send_client(SIZE_HEADER + sizeof(packet_send_arrow), buffsend, pte);
4461 return;
4462}
static void send_client(int size, const unsigned char *data, struct unistimsession *pte)
static const unsigned char packet_send_s4[]
static const unsigned char packet_send_arrow[]
#define BUFFSEND
static const unsigned char packet_send_s9[]
static const unsigned char packet_send_S7[]
static void show_extension_page(struct unistimsession *pte)
static void send_date_time2(struct unistimsession *pte)
#define SIZE_HEADER
static void refresh_all_favorite(struct unistimsession *pte)
static void send_date_time3(struct unistimsession *pte)
static void send_texttitle(struct unistimsession *pte, const char *text)
static const unsigned char packet_send_Contrast[]
signed char contrast

References ast_verb, autoprovisioning, AUTOPROVISIONING_TN, BUFFSEND, unistim_device::contrast, unistimsession::device, unistim_languages::encoding, FAVNUM, find_language(), unistim_device::language, LED_BAR_OFF, unistimsession::macaddr, NULL, options_languages, packet_send_arrow, packet_send_Contrast, packet_send_s4, packet_send_S7, packet_send_s9, refresh_all_favorite(), send_charset_update(), 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_extension_page(), show_main_page(), SIZE_HEADER, unistimsession::state, STATE_MAINPAGE, TEXT_LINE0, TEXT_LINE1, TEXT_LINE2, TEXT_NORMAL, unistimdebug, and ustmtext().

Referenced by process_request().

◆ is_key_favorite()

static int is_key_favorite ( struct unistim_device d,
int  fav 
)
static

Definition at line 1354 of file chan_unistim.c.

1355{
1356 if ((fav < 0) || (fav >= FAVNUM)) {
1357 return 0;
1358 }
1359 if (d->sline[fav]) {
1360 return 0;
1361 }
1362 if (d->softkeynumber[fav][0] == '\0') {
1363 return 0;
1364 }
1365 return 1;
1366}

References d, and FAVNUM.

Referenced by handle_key_fav(), is_key_line(), and key_favorite().

◆ is_key_line()

static int is_key_line ( struct unistim_device d,
int  fav 
)
static

Definition at line 1368 of file chan_unistim.c.

1369{
1370 if ((fav < 0) || (fav >= FAVNUM)) {
1371 return 0;
1372 }
1373 if (!d->sline[fav]) {
1374 return 0;
1375 }
1376 if (is_key_favorite(d, fav)) {
1377 return 0;
1378 }
1379 return 1;
1380}

References d, FAVNUM, and is_key_favorite().

Referenced by get_avail_softkey(), handle_key_fav(), unistim_call(), and unistim_hangup().

◆ key_call()

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

Definition at line 3437 of file chan_unistim.c.

3438{
3439 struct unistim_subchannel *sub = get_sub(pte->device, SUB_REAL);
3440 struct unistim_subchannel *sub_3way = get_sub(pte->device, SUB_THREEWAY);
3441
3442 if (!sub) {
3443 return;
3444 }
3445 if ((keycode >= KEY_0) && (keycode <= KEY_SHARP)) {
3446 if (keycode == KEY_SHARP) {
3447 keycode = '#';
3448 } else if (keycode == KEY_STAR) {
3449 keycode = '*';
3450 } else {
3451 keycode -= 0x10;
3452 }
3453 unistim_do_senddigit(pte, keycode);
3454 return;
3455 }
3456 switch (keycode) {
3457 case KEY_FUNC1:
3458 if (sub->owner && ast_channel_state(sub->owner) == AST_STATE_UP) {
3459 if (sub_3way) {
3460 close_call(pte);
3461 }
3462 }
3463 break;
3464 case KEY_FUNC2:
3465 if (sub_3way) {
3467 } else if (ast_channel_state(sub->owner) == AST_STATE_UP) {
3469 }
3470 break;
3471 case KEY_HANGUP:
3472 case KEY_FUNC4:
3473 if (!sub_3way) {
3474 close_call(pte);
3475 }
3476 break;
3477 case KEY_FAV0:
3478 case KEY_FAV1:
3479 case KEY_FAV2:
3480 case KEY_FAV3:
3481 case KEY_FAV4:
3482 case KEY_FAV5:
3483 handle_key_fav(pte, keycode);
3484 break;
3485 case KEY_HEADPHN:
3486 if (pte->device->output == OUTPUT_HEADPHONE) {
3488 } else {
3490 }
3491 break;
3492 case KEY_LOUDSPK:
3493 if (pte->device->output != OUTPUT_SPEAKER)
3495 else
3497 MUTE_OFF);
3498 break;
3499 case KEY_ONHOLD:
3500 if (!sub) {
3501 if(pte->device->ssub[pte->device->selected]) {
3502 sub = pte->device->ssub[pte->device->selected];
3503 } else {
3504 break;
3505 }
3506 }
3507 if (sub->holding) {
3508 sub_unhold(pte, sub);
3509 } else {
3510 sub_hold(pte, sub);
3511 }
3512 break;
3513 }
3514 return;
3515}
static void transfer_call_step1(struct unistimsession *pte)
static void handle_key_fav(struct unistimsession *pte, char keycode)
static void close_call(struct unistimsession *pte)
#define OUTPUT_HEADPHONE
static void transfer_cancel_step2(struct unistimsession *pte)
static int unistim_do_senddigit(struct unistimsession *pte, char digit)
ast_channel_state
ast_channel states
@ AST_STATE_UP

References AST_STATE_UP, close_call(), unistimsession::device, get_sub(), handle_key_fav(), KEY_0, KEY_FAV0, KEY_FAV1, KEY_FAV2, KEY_FAV3, KEY_FAV4, KEY_FAV5, KEY_FUNC1, KEY_FUNC2, KEY_FUNC4, KEY_HANGUP, KEY_HEADPHN, KEY_LOUDSPK, KEY_ONHOLD, KEY_SHARP, KEY_STAR, MUTE_OFF, unistim_device::output, OUTPUT_HANDSET, OUTPUT_HEADPHONE, OUTPUT_SPEAKER, unistim_device::previous_output, unistim_device::selected, send_select_output(), unistim_device::ssub, sub, sub_hold(), SUB_REAL, SUB_THREEWAY, sub_unhold(), transfer_call_step1(), transfer_cancel_step2(), unistim_do_senddigit(), and unistim_device::volume.

Referenced by process_request().

◆ key_dial_page()

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

Definition at line 3563 of file chan_unistim.c.

3564{
3566
3567 pte->device->nextdial = 0;
3568 if (keycode == KEY_FUNC3) {
3569 if (pte->device->size_phone_number <= 1) {
3570 keycode = KEY_FUNC4;
3571 } else {
3572 pte->device->size_phone_number -= 2;
3573 keycode = pte->device->phone_number[pte->device->size_phone_number] + 0x10;
3574 }
3575 }
3576 if (keycode == KEY_SHARP && pte->device->sharp_dial == 1) {
3577 keycode = KEY_FUNC1;
3578 }
3579 if ((keycode >= KEY_0) && (keycode <= KEY_SHARP)) {
3580 int i = pte->device->size_phone_number;
3581
3582 /*
3583 * If the phone_number buffer is already full, bail now to prevent an overrun.
3584 */
3586 return;
3587 }
3588 if (pte->device->size_phone_number == 0) {
3589 send_tone(pte, 0, 0);
3590 }
3591 if (keycode == KEY_SHARP) {
3592 keycode = '#';
3593 } else if (keycode == KEY_STAR) {
3594 keycode = '*';
3595 } else {
3596 keycode -= 0x10;
3597 }
3598 pte->device->phone_number[i] = keycode;
3599 pte->device->size_phone_number++;
3600 pte->device->phone_number[i + 1] = 0;
3601 show_phone_number(pte);
3602
3605 keycode = KEY_FUNC1;
3606 } else {
3607 if (pte->device->interdigit_timer) {
3609 }
3610 }
3611 }
3612 if (keycode == KEY_FUNC4) {
3613 pte->device->size_phone_number = 0;
3614 show_phone_number(pte);
3615 return;
3616 }
3617
3618 if (pte->device->call_forward[0] == -1) {
3619 if (keycode == KEY_FUNC1) {
3621 sizeof(pte->device->call_forward));
3622 show_main_page(pte);
3623 } else if ((keycode == KEY_FUNC2) || (keycode == KEY_HANGUP)) {
3624 pte->device->call_forward[0] = '\0';
3627 show_main_page(pte);
3628 }
3629 return;
3630 }
3631 switch (keycode) {
3632 case KEY_FUNC2:
3634 break;
3635 }
3637 sizeof(pte->device->phone_number));
3638 case KEY_FUNC1:
3640 break;
3641 case KEY_HANGUP:
3642 if (sub && sub->owner) {
3643 sub_stop_silence(pte, sub);
3644 send_tone(pte, 0, 0);
3645 ast_queue_unhold(sub->owner);
3646 sub->moh = 0;
3647 sub->subtype = SUB_REAL;
3648 pte->state = STATE_CALL;
3649
3650 send_text_status(pte, ustmtext(" Transf Hangup", pte));
3652 } else {
3655 show_main_page(pte);
3656 }
3657 break;
3658 case KEY_FAV0:
3659 case KEY_FAV1:
3660 case KEY_FAV2:
3661 case KEY_FAV3:
3662 case KEY_FAV4:
3663 case KEY_FAV5:
3665 pte->device->selected = -1;
3666 handle_key_fav(pte, keycode);
3667 break;
3668 case KEY_LOUDSPK:
3669 if (pte->device->output == OUTPUT_SPEAKER) {
3670 if (pte->device->receiver_state == STATE_OFFHOOK) {
3672 MUTE_OFF);
3673 } else {
3674 show_main_page(pte);
3675 }
3676 } else {
3678 }
3679 break;
3680 case KEY_HEADPHN:
3681 if (pte->device->output == OUTPUT_HEADPHONE) {
3682 if (pte->device->receiver_state == STATE_OFFHOOK) {
3684 } else {
3685 show_main_page(pte);
3686 }
3687 } else {
3689 }
3690 break;
3691 }
3692 return;
3693}
#define MAX_PHONE_NUMBER_LENGTH
#define LED_SPEAKER_OFF
#define LED_HEADPHONE_OFF
int ast_queue_unhold(struct ast_channel *chan)
Queue an unhold frame.
Definition channel.c:1274
int ast_exists_extension(struct ast_channel *c, const char *context, const char *exten, int priority, const char *callerid)
Determine whether an extension exists.
Definition pbx.c:2735
int ast_matchmore_extension(struct ast_channel *c, const char *context, const char *exten, int priority, const char *callerid)
Looks to see if adding anything to this extension might match something. (exists ^ canmatch)
Definition pbx.c:2755
char context[AST_MAX_EXTENSION]

References ast_copy_string(), ast_exists_extension(), ast_matchmore_extension(), ast_queue_unhold(), ast_strlen_zero(), unistim_device::call_forward, unistim_device::context, unistimsession::device, FAV_LINE_ICON, get_sub(), get_tick_count(), handle_call_outgoing(), handle_key_fav(), unistim_device::interdigit_timer, KEY_0, KEY_FAV0, 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, LED_HEADPHONE_OFF, LED_SPEAKER_OFF, MAX_PHONE_NUMBER_LENGTH, MUTE_OFF, unistim_device::nextdial, NULL, unistim_device::output, OUTPUT_HANDSET, OUTPUT_HEADPHONE, OUTPUT_SPEAKER, unistim_device::phone_number, unistim_device::previous_output, unistim_device::receiver_state, unistim_device::redial_number, unistim_device::selected, send_callerid_screen(), send_favorite_selected(), send_led_update(), send_select_output(), send_text_status(), send_tone(), unistim_device::sharp_dial, show_main_page(), show_phone_number(), unistim_device::size_phone_number, unistimsession::state, STATE_CALL, STATE_OFFHOOK, sub, SUB_REAL, sub_stop_silence(), SUB_THREEWAY, ustmtext(), and unistim_device::volume.

Referenced by key_main_page(), and process_request().

◆ key_favorite()

static void key_favorite ( struct unistimsession pte,
char  keycode 
)
static

Definition at line 3550 of file chan_unistim.c.

3551{
3552 int fav = keycode - KEY_FAV0;
3553 if (!is_key_favorite(pte->device, fav)) {
3554 ast_log(LOG_WARNING, "It's not a favorite key\n");
3555 return;
3556 }
3558 sizeof(pte->device->phone_number));
3560 return;
3561}
char softkeynumber[FAVNUM][AST_MAX_EXTENSION]

References ast_copy_string(), ast_log, unistimsession::device, handle_call_outgoing(), is_key_favorite(), KEY_FAV0, LOG_WARNING, unistim_device::phone_number, and unistim_device::softkeynumber.

Referenced by handle_key_fav().

◆ key_history()

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

Definition at line 4302 of file chan_unistim.c.

4303{
4304 FILE *f;
4305 char count;
4306 long offset;
4307 int flag = 0;
4308
4309 switch (keycode) {
4310 case KEY_LEFT:
4311 if (pte->device->height == 1) {
4312 if (pte->buff_entry[3] <= 1) {
4313 return;
4314 }
4315 pte->buff_entry[3]--;
4316 flag = 1;
4317 break;
4318 }
4319 case KEY_UP:
4320 case KEY_FUNC1:
4321 if (pte->buff_entry[2] <= 1) {
4322 return;
4323 }
4324 pte->buff_entry[2]--;
4325 flag = 1;
4326 break;
4327 case KEY_RIGHT:
4328 if (pte->device->height == 1) {
4329 if (pte->buff_entry[3] == 3) {
4330 return;
4331 }
4332 pte->buff_entry[3]++;
4333 flag = 1;
4334 break;
4335 }
4336 case KEY_DOWN:
4337 case KEY_FUNC2:
4338 if (pte->buff_entry[2] >= pte->buff_entry[1]) {
4339 return;
4340 }
4341 pte->buff_entry[2]++;
4342 flag = 1;
4343 break;
4344 case KEY_FUNC3:
4345 if (ast_strlen_zero(pte->device->lst_cid)) {
4346 break;
4347 }
4349 sizeof(pte->device->redial_number));
4351 break;
4352 case KEY_FUNC4:
4353 case KEY_HANGUP:
4354 show_main_page(pte);
4355 break;
4356 case KEY_SNDHIST:
4357 if (pte->buff_entry[0] == 'i') {
4358 show_history(pte, 'o');
4359 } else {
4360 show_main_page(pte);
4361 }
4362 break;
4363 case KEY_RCVHIST:
4364 if (pte->buff_entry[0] == 'i') {
4365 show_main_page(pte);
4366 } else {
4367 show_history(pte, 'i');
4368 }
4369 break;
4370 }
4371
4372 if (flag) {
4373 count = open_history(pte, pte->buff_entry[0], &f);
4374 if (!count) {
4375 return;
4376 }
4377 offset = ((pte->buff_entry[2] - 1) * TEXT_LENGTH_MAX * 3);
4378 if (fseek(f, offset, SEEK_CUR)) {
4379 display_last_error("Unable to seek history entry.");
4380 fclose(f);
4381 return;
4382 }
4383 show_entry_history(pte, &f);
4384 }
4385
4386 return;
4387}
static void show_history(struct unistimsession *pte, char way)
static void show_entry_history(struct unistimsession *pte, FILE **f)
static char open_history(struct unistimsession *pte, char way, FILE **f)
static void key_main_page(struct unistimsession *pte, char keycode)
static void display_last_error(const char *sz_msg)
long int flag
Definition f2c.h:83

References ast_copy_string(), ast_strlen_zero(), unistimsession::buff_entry, unistimsession::device, display_last_error(), unistim_device::height, 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, open_history(), unistim_device::redial_number, show_entry_history(), show_history(), show_main_page(), and TEXT_LENGTH_MAX.

Referenced by process_request().

◆ key_main_page()

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

Definition at line 4199 of file chan_unistim.c.

4200{
4201 if (pte->device->missed_call) {
4203 pte->device->missed_call = 0;
4204 }
4205 if ((keycode >= KEY_0) && (keycode <= KEY_SHARP)) {
4206 handle_dial_page(pte);
4207 key_dial_page(pte, keycode);
4208 return;
4209 }
4210 switch (keycode) {
4211 case KEY_FUNC1:
4212 pte->device->selected = get_avail_softkey(pte, NULL);
4213 handle_dial_page(pte);
4214 break;
4215 case KEY_FUNC2:
4217 break;
4218 }
4219 if ((pte->device->output == OUTPUT_HANDSET) &&
4220 (pte->device->receiver_state == STATE_ONHOOK)) {
4222 } else {
4224 }
4226 sizeof(pte->device->phone_number));
4228 break;
4229 case KEY_FUNC3:
4230 if (!ast_strlen_zero(pte->device->call_forward)) {
4231 /* Cancel call forwarding */
4232 memmove(pte->device->call_forward + 1, pte->device->call_forward,
4233 sizeof(pte->device->call_forward) - 1);
4234 pte->device->call_forward[0] = '\0';
4236 pte->device->output = OUTPUT_HANDSET; /* Seems to be reset somewhere */
4237 show_main_page(pte);
4238 break;
4239 }
4240 pte->device->call_forward[0] = -1;
4241 handle_dial_page(pte);
4242 break;
4243 case KEY_FUNC4:
4244 if (pte->device->extension == EXTENSION_ASK) {
4246 pte->device->extension_number[0] = '\0';
4248 } else if (pte->device->extension == EXTENSION_TN) {
4250 strcpy(pte->device->id, pte->device->extension_number);
4251 pte->buff_entry[0] = '\0';
4252 pte->size_buff_entry = 0;
4253 pte->device->session = NULL;
4254 pte->device = NULL;
4257 } else { /* Pickup function */
4258 /* XXX Is there a way to get a specific channel here? */
4259 RAII_VAR(struct ast_features_pickup_config *, pickup_cfg,
4261
4262 if (!pickup_cfg) {
4263 ast_log(LOG_ERROR, "Unable to retrieve pickup configuration options. Unable to detect call pickup extension\n");
4264 break;
4265 }
4266
4267 pte->device->selected = -1;
4268 ast_copy_string(pte->device->phone_number, pickup_cfg->pickupexten,
4269 sizeof(pte->device->phone_number));
4271 }
4272 break;
4273 case KEY_FAV0:
4274 case KEY_FAV1:
4275 case KEY_FAV2:
4276 case KEY_FAV3:
4277 case KEY_FAV4:
4278 case KEY_FAV5:
4279 handle_key_fav(pte, keycode);
4280 break;
4281 case KEY_CONF:
4283 break;
4284 case KEY_LOUDSPK:
4286 handle_dial_page(pte);
4287 break;
4288 case KEY_HEADPHN:
4290 handle_dial_page(pte);
4291 break;
4292 case KEY_SNDHIST:
4293 show_history(pte, 'o');
4294 break;
4295 case KEY_RCVHIST:
4296 show_history(pte, 'i');
4297 break;
4298 }
4299 return;
4300}
static void handle_select_option(struct unistimsession *pte)
static void key_dial_page(struct unistimsession *pte, char keycode)
enum autoprov_extn extension

References ao2_cleanup, ast_copy_string(), ast_get_chan_features_pickup_config(), ast_log, ast_mutex_lock, ast_mutex_unlock, ast_strlen_zero(), unistimsession::buff_entry, unistim_device::call_forward, unistimsession::device, devicelock, unistim_device::extension, EXTENSION_ASK, unistim_device::extension_number, EXTENSION_TN, FAV_ICON_NONE, get_avail_softkey(), handle_call_outgoing(), handle_dial_page(), handle_key_fav(), handle_select_option(), 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, LOG_ERROR, unistim_device::missed_call, MUTE_OFF, NULL, unistim_device::output, OUTPUT_HANDSET, OUTPUT_HEADPHONE, OUTPUT_SPEAKER, unistim_device::phone_number, RAII_VAR, unistim_device::receiver_state, unistim_device::redial_number, unistim_device::selected, send_icon(), send_select_output(), unistim_device::session, show_extension_page(), show_history(), show_main_page(), unistimsession::size_buff_entry, STATE_ONHOOK, TEXT_LINE0, unregister_extension(), and unistim_device::volume.

Referenced by key_history(), and process_request().

◆ key_ringing()

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

Definition at line 3517 of file chan_unistim.c.

3518{
3519 switch (keycode) {
3520 case KEY_FAV0:
3521 case KEY_FAV1:
3522 case KEY_FAV2:
3523 case KEY_FAV3:
3524 case KEY_FAV4:
3525 case KEY_FAV5:
3526 handle_key_fav(pte, keycode);
3527 break;
3528 case KEY_FUNC3:
3529 ignore_call(pte);
3530 break;
3531 case KEY_HANGUP:
3532 case KEY_FUNC4:
3533 discard_call(pte);
3534 break;
3535 case KEY_LOUDSPK:
3538 break;
3539 case KEY_HEADPHN:
3542 break;
3543 case KEY_FUNC1:
3545 break;
3546 }
3547 return;
3548}
static void ignore_call(struct unistimsession *pte)
static void discard_call(struct unistimsession *pte)

References unistimsession::device, discard_call(), handle_call_incoming(), handle_key_fav(), ignore_call(), KEY_FAV0, KEY_FAV1, KEY_FAV2, KEY_FAV3, KEY_FAV4, KEY_FAV5, KEY_FUNC1, KEY_FUNC3, KEY_FUNC4, KEY_HANGUP, KEY_HEADPHN, KEY_LOUDSPK, unistim_device::output, OUTPUT_HEADPHONE, and OUTPUT_SPEAKER.

Referenced by process_request().

◆ key_select_codec()

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

Definition at line 3760 of file chan_unistim.c.

3761{
3762 if (keycode == KEY_FUNC2) {
3763 if (pte->size_buff_entry <= 1) {
3764 keycode = KEY_FUNC3;
3765 } else {
3766 pte->size_buff_entry -= 2;
3767 keycode = pte->buff_entry[pte->size_buff_entry] + 0x10;
3768 }
3769 }
3770 if ((keycode >= KEY_0) && (keycode <= KEY_9)) {
3771 char tmpbuf[] = SELECTCODEC_MSG;
3772 int i = 0;
3773
3775 return;
3776 }
3777 while (i < pte->size_buff_entry) {
3778 tmpbuf[i + SELECTCODEC_START_ENTRY_POS] = pte->buff_entry[i];
3779 i++;
3780 }
3781 tmpbuf[i + SELECTCODEC_START_ENTRY_POS] = keycode - 0x10;
3782 pte->buff_entry[i] = keycode - 0x10;
3783 pte->size_buff_entry++;
3784 send_text(TEXT_LINE2, TEXT_INVERSE, pte, tmpbuf);
3785 send_blink_cursor(pte);
3786 send_cursor_pos(pte,
3787 (unsigned char) (TEXT_LINE2 + SELECTCODEC_START_ENTRY_POS + 1 + i));
3788 return;
3789 }
3790
3791 switch (keycode) {
3792 case KEY_FUNC1:
3793 if (pte->size_buff_entry == 1) {
3794 pte->device->codec_number = pte->buff_entry[0] - 48;
3795 } else if (pte->size_buff_entry == 2) {
3796 pte->device->codec_number =
3797 ((pte->buff_entry[0] - 48) * 10) + (pte->buff_entry[1] - 48);
3798 }
3799 show_main_page(pte);
3800 break;
3801 case KEY_FUNC3:
3802 pte->size_buff_entry = 0;
3804 send_blink_cursor(pte);
3806 break;
3807 case KEY_HANGUP:
3808 case KEY_FUNC4:
3809 show_main_page(pte);
3810 break;
3811 }
3812 return;
3813}
#define SELECTCODEC_MAX_LENGTH

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

◆ key_select_extension()

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

Definition at line 3898 of file chan_unistim.c.

3899{
3900 if (keycode == KEY_FUNC2) {
3901 if (pte->size_buff_entry <= 1) {
3902 keycode = KEY_FUNC3;
3903 } else {
3904 pte->size_buff_entry -= 2;
3905 keycode = pte->buff_entry[pte->size_buff_entry] + 0x10;
3906 }
3907 }
3908 if ((keycode >= KEY_0) && (keycode <= KEY_9)) {
3909 char tmpbuf[] = SELECTEXTENSION_MSG;
3910 int i = 0;
3911
3913 return;
3914 }
3915 while (i < pte->size_buff_entry) {
3916 tmpbuf[i + SELECTEXTENSION_START_ENTRY_POS] = pte->buff_entry[i];
3917 i++;
3918 }
3919 tmpbuf[i + SELECTEXTENSION_START_ENTRY_POS] = keycode - 0x10;
3920 pte->buff_entry[i] = keycode - 0x10;
3921 pte->size_buff_entry++;
3922 send_text(TEXT_LINE2, TEXT_NORMAL, pte, tmpbuf);
3923 send_blink_cursor(pte);
3924 send_cursor_pos(pte, (unsigned char) (TEXT_LINE2 + SELECTEXTENSION_START_ENTRY_POS + 1 + i));
3925 return;
3926 }
3927
3928 switch (keycode) {
3929 case KEY_FUNC1:
3930 if (pte->size_buff_entry < 1) {
3931 return;
3932 }
3934 struct unistim_device *d;
3935
3936 /* First step : looking for this TN in our device list */
3938 d = devices;
3939 pte->buff_entry[pte->size_buff_entry] = '\0';
3940 while (d) {
3941 if (d->id[0] == 'T') { /* It's a TN device ? */
3942 /* It's the TN we're looking for ? */
3943 if (!strcmp((d->id) + 1, pte->buff_entry)) {
3944 pte->device = d;
3945 d->session = pte;
3946 d->codec_number = DEFAULT_CODEC;
3947 d->missed_call = 0;
3948 d->receiver_state = STATE_ONHOOK;
3949 strcpy(d->id, pte->macaddr);
3950 pte->device->extension_number[0] = 'T';
3953 pte->buff_entry, pte->size_buff_entry + 1);
3955 show_main_page(pte);
3957 return;
3958 }
3959 }
3960 d = d->next;
3961 }
3963 send_text(TEXT_LINE0, TEXT_NORMAL, pte, ustmtext("Invalid Terminal Number.", pte));
3964 send_text(TEXT_LINE1, TEXT_NORMAL, pte, ustmtext("Please try again :", pte));
3966 pte->size_buff_entry));
3967 send_blink_cursor(pte);
3968 } else {
3970 pte->size_buff_entry + 1);
3971 if (register_extension(pte)) {
3972 send_text(TEXT_LINE0, TEXT_NORMAL, pte, ustmtext("Invalid extension.", pte));
3973 send_text(TEXT_LINE1, TEXT_NORMAL, pte, ustmtext("Please try again :", pte));
3974 send_cursor_pos(pte, (unsigned char) (TEXT_LINE2 +
3976 pte->size_buff_entry));
3977 send_blink_cursor(pte);
3978 } else
3979 show_main_page(pte);
3980 }
3981 break;
3982 case KEY_FUNC3:
3983 pte->size_buff_entry = 0;
3985 send_blink_cursor(pte);
3987 break;
3988 }
3989 return;
3990}
static int register_extension(const struct unistimsession *pte)
#define SELECTEXTENSION_MAX_LENGTH
#define SELECTEXTENSION_START_ENTRY_POS
#define DEFAULT_CODEC
#define SELECTEXTENSION_MSG

References ast_copy_string(), ast_mutex_lock, ast_mutex_unlock, autoprovisioning, AUTOPROVISIONING_TN, unistimsession::buff_entry, d, DEFAULT_CODEC, unistimsession::device, devicelock, devices, unistim_device::extension, unistim_device::extension_number, EXTENSION_TN, KEY_0, KEY_9, KEY_FUNC1, KEY_FUNC2, KEY_FUNC3, unistimsession::macaddr, test_val::next, refresh_all_favorite(), register_extension(), SELECTEXTENSION_MAX_LENGTH, SELECTEXTENSION_MSG, SELECTEXTENSION_START_ENTRY_POS, send_blink_cursor(), send_cursor_pos(), send_text(), show_main_page(), unistimsession::size_buff_entry, STATE_ONHOOK, TEXT_LINE0, TEXT_LINE1, TEXT_LINE2, TEXT_NORMAL, and ustmtext().

Referenced by process_request().

◆ key_select_language()

static void key_select_language ( struct unistimsession pte,
char  keycode 
)
static

Definition at line 3850 of file chan_unistim.c.

3851{
3852 switch (keycode) {
3853 case KEY_DOWN:
3854 pte->buff_entry[0]++;
3855 if (options_languages[(int)pte->buff_entry[0]].label == NULL) {
3856 pte->buff_entry[0]--;
3857 }
3858 break;
3859 case KEY_UP:
3860 if (pte->buff_entry[0] > 0) {
3861 pte->buff_entry[0]--;
3862 }
3863 break;
3864 case KEY_FUNC1:
3868 show_main_page(pte);
3869 return;
3870 case KEY_HANGUP:
3871 case KEY_FUNC4:
3873 return;
3874 }
3875
3877 return;
3878}
static void handle_select_language(struct unistimsession *)

References ast_copy_string(), unistimsession::buff_entry, unistimsession::device, unistim_languages::encoding, handle_select_language(), handle_select_option(), KEY_DOWN, KEY_FUNC1, KEY_FUNC4, KEY_HANGUP, KEY_UP, unistim_languages::label, unistim_languages::lang_short, unistim_device::language, NULL, options_languages, refresh_all_favorite(), send_charset_update(), and show_main_page().

Referenced by process_request().

◆ key_select_option()

static void key_select_option ( struct unistimsession pte,
char  keycode 
)
static

Definition at line 3710 of file chan_unistim.c.

3711{
3712 switch (keycode) {
3713 case KEY_DOWN:
3714 pte->buff_entry[0]++;
3715 if (options_menu[(int)pte->buff_entry[0]].label == NULL) {
3716 pte->buff_entry[0]--;
3717 }
3718 break;
3719 case KEY_UP:
3720 if (pte->buff_entry[0] > 0) {
3721 pte->buff_entry[0]--;
3722 }
3723 break;
3724 case KEY_FUNC1:
3725 options_menu[(int)pte->buff_entry[0]].handle_option(pte);
3726 return;
3727 case KEY_HANGUP:
3728 case KEY_FUNC4:
3729 show_main_page(pte);
3730 return;
3731 }
3732
3734 return;
3735}
void(* handle_option)(struct unistimsession *)

References unistimsession::buff_entry, unistim_menu_item::handle_option, handle_select_option(), KEY_DOWN, KEY_FUNC1, KEY_FUNC4, KEY_HANGUP, KEY_UP, unistim_menu_item::label, NULL, options_menu, and show_main_page().

Referenced by process_request().

◆ lang_cmp_fn()

static int lang_cmp_fn ( void *  obj,
void *  arg,
int  flags 
)
static

Definition at line 794 of file chan_unistim.c.

795{
796 struct ustm_lang_entry *entry1 = obj;
797 struct ustm_lang_entry *entry2 = arg;
798
799 return (!strcmp(entry1->str_orig, entry2->str_orig)) ? (CMP_MATCH | CMP_STOP) : 0;
800}
@ CMP_MATCH
Definition astobj2.h:1027
@ CMP_STOP
Definition astobj2.h:1028
const char * str_orig

References CMP_MATCH, CMP_STOP, and ustm_lang_entry::str_orig.

Referenced by ustmtext().

◆ lang_hash_fn()

static int lang_hash_fn ( const void *  obj,
const int  flags 
)
static

Definition at line 788 of file chan_unistim.c.

789{
790 const struct ustm_lang_entry *entry = obj;
791 return ast_str_hash(entry->str_orig);
792}
static force_inline int attribute_pure ast_str_hash(const char *str)
Compute a hash value on a string.
Definition strings.h:1259

References ast_str_hash(), and ustm_lang_entry::str_orig.

Referenced by ustmtext().

◆ load_module()

int load_module ( void  )
static

XXX

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

Definition at line 7086 of file chan_unistim.c.

7087{
7088 int res;
7089
7091 goto buff_failed;
7092 }
7094 goto buff_failed;
7095 }
7096
7100
7101 if (!(buff = ast_malloc(SIZE_PAGE))) {
7102 goto buff_failed;
7103 }
7104
7106 if (!io) {
7107 ast_log(LOG_ERROR, "Failed to allocate IO context\n");
7108 goto io_failed;
7109 }
7110
7112 if (!sched) {
7113 ast_log(LOG_ERROR, "Failed to allocate scheduler context\n");
7114 goto sched_failed;
7115 }
7116
7117 res = reload_config();
7118 if (res) {
7120 ao2_ref(global_cap, -1);
7124 }
7125 /* Make sure we can register our unistim channel type */
7127 ast_log(LOG_ERROR, "Unable to register channel type '%s'\n", channel_type);
7128 goto chanreg_failed;
7129 }
7130
7132
7134
7136
7138
7139chanreg_failed:
7140 /*! XXX \todo Leaking anything allocated by reload_config() ... */
7142 sched = NULL;
7143sched_failed:
7145 io = NULL;
7146io_failed:
7147 ast_free(buff);
7148 buff = NULL;
7149buff_failed:
7151 global_cap = NULL;
7155}
#define ast_malloc(len)
A wrapper for malloc()
Definition astmm.h:191
#define ao2_ref(o, delta)
Reference/unreference an object and return the old refcount.
Definition astobj2.h:459
static struct ast_cli_entry unistim_cli[]
static struct ast_channel_tech unistim_tech
#define SIZE_PAGE
static int restart_monitor(void)
static const char channel_type[]
static unsigned char * buff
static struct ast_rtp_glue unistim_rtp_glue
int ast_channel_register(const struct ast_channel_tech *tech)
Register a channel technology (a new channel driver) Called by a channel module to register the kind ...
Definition channel.c:540
#define ast_cli_register_multiple(e, len)
Register multiple commands.
Definition cli.h:265
@ AST_MEDIA_TYPE_AUDIO
Definition codec.h:32
struct ast_format * ast_format_ulaw
Built-in cached ulaw format.
struct ast_format * ast_format_alaw
Built-in cached alaw format.
@ AST_FORMAT_CAP_FLAG_DEFAULT
Definition format_cap.h:38
#define ast_format_cap_append(cap, format, framing)
Add format capability to capabilities structure.
Definition format_cap.h:99
#define ast_format_cap_alloc(flags)
Allocate a new ast_format_cap structure.
Definition format_cap.h:49
struct io_context * io_context_create(void)
Creates a context Create a context for I/O operations Basically mallocs an IO structure and sets up s...
Definition io.c:81
void io_context_destroy(struct io_context *ioc)
Destroys a context.
Definition io.c:107
@ AST_MODULE_LOAD_SUCCESS
Definition module.h:70
@ AST_MODULE_LOAD_DECLINE
Module has failed to load, may be in an inconsistent state.
Definition module.h:78
#define ast_rtp_glue_register(glue)
Definition rtp_engine.h:905
void ast_sched_context_destroy(struct ast_sched_context *c)
destroys a schedule context
Definition sched.c:271
struct ast_sched_context * ast_sched_context_create(void)
Create a scheduler context.
Definition sched.c:238
struct ast_format_cap * capabilities
Definition channel.h:652
Definition sched.c:76
#define ARRAY_LEN(a)
Definition utils.h:706

References ao2_cleanup, ao2_ref, ARRAY_LEN, ast_channel_register(), ast_cli_register_multiple, ast_format_alaw, ast_format_cap_alloc, ast_format_cap_append, ast_format_cap_append_from_cap(), AST_FORMAT_CAP_FLAG_DEFAULT, ast_format_ulaw, ast_free, ast_log, ast_malloc, AST_MEDIA_TYPE_AUDIO, AST_MODULE_LOAD_DECLINE, AST_MODULE_LOAD_SUCCESS, ast_rtp_glue_register, ast_sched_context_create(), ast_sched_context_destroy(), buff, ast_channel_tech::capabilities, channel_type, global_cap, io, io_context_create(), io_context_destroy(), LOG_ERROR, NULL, reload_config(), restart_monitor(), SIZE_PAGE, unistim_cli, unistim_rtp_glue, and unistim_tech.

◆ microphone_mute_toggle()

static void microphone_mute_toggle ( struct unistimsession pte)
static

Definition at line 4465 of file chan_unistim.c.

4466{
4467 if (pte->device->microphone == MUTE_OFF) {
4468 pte->device->microphone = MUTE_ON;
4470 } else if (pte->device->microphone == MUTE_ON) {
4471 pte->device->microphone = MUTE_OFF;
4473 }
4474 send_mute(pte, (pte->device->microphone & 0x01));
4475}
#define LED_MUTE_ON
#define MUTE_ON
static void send_mute(struct unistimsession *pte, unsigned char mute)
#define LED_MUTE_OFF

References unistimsession::device, LED_MUTE_OFF, LED_MUTE_ON, unistim_device::microphone, MUTE_OFF, MUTE_ON, send_led_update(), and send_mute().

Referenced by process_request().

◆ open_history()

static char open_history ( struct unistimsession pte,
char  way,
FILE **  f 
)
static

Definition at line 4066 of file chan_unistim.c.

4067{
4068 char tmp[AST_CONFIG_MAX_PATH];
4069 char count;
4070
4071 snprintf(tmp, sizeof(tmp), "%s/%s/%s-%c.csv", ast_config_AST_LOG_DIR,
4072 USTM_LOG_DIR, pte->device->name, way);
4073 *f = fopen(tmp, "r");
4074 if (!*f) {
4075 display_last_error("Unable to open history file");
4076 return 0;
4077 }
4078 if (fread(&count, 1, 1, *f) != 1) {
4079 display_last_error("Unable to read history header - display.");
4080 fclose(*f);
4081 *f = NULL;
4082 return 0;
4083 }
4084 if (count > MAX_ENTRY_LOG) {
4085 ast_log(LOG_WARNING, "Invalid count in history header of %s (%d max %d)\n", tmp,
4086 count, MAX_ENTRY_LOG);
4087 fclose(*f);
4088 *f = NULL;
4089 return 0;
4090 }
4091 return count;
4092}
#define MAX_ENTRY_LOG
#define AST_CONFIG_MAX_PATH
#define USTM_LOG_DIR
const char * ast_config_AST_LOG_DIR
Definition options.c:160

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, NULL, and USTM_LOG_DIR.

Referenced by key_history(), and show_history().

◆ parse_bookmark()

static int parse_bookmark ( const char *  text,
struct unistim_device d 
)
static

Definition at line 6303 of file chan_unistim.c.

6304{
6305 char line[256];
6306 char *at;
6307 char *number;
6308 char *icon;
6309 int p;
6310 int len = strlen(text);
6311
6312 ast_copy_string(line, text, sizeof(line));
6313 /* Position specified ? */
6314 if ((len > 2) && (line[1] == '@')) {
6315 p = line[0];
6316 if ((p >= '0') && (p <= '5')) {
6317 p -= '0';
6318 } else {
6320 "Invalid position for bookmark : must be between 0 and 5\n");
6321 return 0;
6322 }
6323 if (d->softkeyicon[p] != 0) {
6324 ast_log(LOG_WARNING, "Invalid position %d for bookmark : already used:\n", p);
6325 return 0;
6326 }
6327 memmove(line, line + 2, sizeof(line) - 2);
6328 } else {
6329 /* No position specified, looking for a free slot */
6330 for (p = 0; p < FAVNUM; p++) {
6331 if (!d->softkeyicon[p]) {
6332 break;
6333 }
6334 }
6335 if (p == FAVNUM) {
6336 ast_log(LOG_WARNING, "No more free bookmark position\n");
6337 return 0;
6338 }
6339 }
6340 at = strchr(line, '@');
6341 if (!at) {
6342 ast_log(LOG_NOTICE, "Bookmark entry '%s' has no @ (at) sign!\n", text);
6343 return 0;
6344 }
6345 *at = '\0';
6346 at++;
6347 number = at;
6348 at = strchr(at, '@');
6349 if (ast_strlen_zero(number)) {
6350 ast_log(LOG_NOTICE, "Bookmark entry '%s' has no number\n", text);
6351 return 0;
6352 }
6353 if (ast_strlen_zero(line)) {
6354 ast_log(LOG_NOTICE, "Bookmark entry '%s' has no description\n", text);
6355 return 0;
6356 }
6357
6358 at = strchr(number, '@');
6359 if (!at) {
6360 d->softkeyicon[p] = FAV_ICON_SHARP; /* default icon */
6361 } else {
6362 *at = '\0';
6363 at++;
6364 icon = at;
6365 if (ast_strlen_zero(icon)) {
6366 ast_log(LOG_NOTICE, "Bookmark entry '%s' has no icon value\n", text);
6367 return 0;
6368 }
6369 if (strncmp(icon, "USTM/", 5)) {
6370 d->softkeyicon[p] = atoi(icon);
6371 } else {
6372 d->softkeyicon[p] = 1;
6373 ast_copy_string(d->softkeydevice[p], icon + 5, sizeof(d->softkeydevice[p]));
6374 }
6375 }
6376 ast_copy_string(d->softkeylabel[p], line, sizeof(d->softkeylabel[p]));
6377 ast_copy_string(d->softkeynumber[p], number, sizeof(d->softkeynumber[p]));
6378 if (unistimdebug) {
6379 ast_verb(0, "New bookmark at pos %d label='%s' number='%s' icon=%#x\n",
6380 p, d->softkeylabel[p], d->softkeynumber[p], (unsigned)d->softkeyicon[p]);
6381 }
6382 return 1;
6383}
#define FAV_ICON_SHARP
Number structure.

References ast_copy_string(), ast_log, ast_strlen_zero(), ast_verb, d, FAV_ICON_SHARP, FAVNUM, len(), LOG_NOTICE, LOG_WARNING, text, and unistimdebug.

Referenced by build_device().

◆ parsing()

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

Definition at line 4641 of file chan_unistim.c.

4643{
4644 unsigned short *sbuf = (unsigned short *) buf;
4645 unsigned short seq;
4646 char tmpbuf[255];
4647
4648 strcpy(tmpbuf, ast_inet_ntoa(addr_from->sin_addr));
4649
4650 if (size < 10) {
4651 if (size == 0) {
4652 ast_log(LOG_WARNING, "%s Read error\n", tmpbuf);
4653 } else {
4654 ast_log(LOG_NOTICE, "%s Packet too short - ignoring\n", tmpbuf);
4655 }
4656 return;
4657 }
4658 if (sbuf[0] == 0xffff) { /* Starting with 0xffff ? *//* Yes, discovery packet ? */
4659 if (size != sizeof(packet_rcv_discovery)) {
4660 ast_log(LOG_NOTICE, "%s Invalid size of a discovery packet\n", tmpbuf);
4661 } else {
4662 if (memcmp(buf, packet_rcv_discovery, sizeof(packet_rcv_discovery)) == 0) {
4663 if (unistimdebug) {
4664 ast_verb(0, "Discovery packet received - Sending Discovery ACK\n");
4665 }
4666 if (pte) { /* A session was already active for this IP ? */
4667 if (pte->state == STATE_INIT) { /* Yes, but it's a dupe */
4668 if (unistimdebug) {
4669 ast_verb(1, "Duplicated Discovery packet\n");
4670 }
4672 packet_send_discovery_ack, addr_from, &pte->sout);
4673 pte->seq_phone = (short) 0x0000; /* reset sequence number */
4674 } else { /* No, probably a reboot, phone side */
4675 close_client(pte); /* Cleanup the previous session */
4676 if (create_client(addr_from)) {
4678 packet_send_discovery_ack, addr_from, &pte->sout);
4679 }
4680 }
4681 } else {
4682 /* Creating new entry in our phone list */
4683 if ((pte = create_client(addr_from))) {
4685 packet_send_discovery_ack, addr_from, &pte->sout);
4686 }
4687 }
4688 return;
4689 }
4690 ast_log(LOG_NOTICE, "%s Invalid discovery packet\n", tmpbuf);
4691 }
4692 return;
4693 }
4694 if (!pte) {
4695 if (unistimdebug) {
4696 ast_verb(0, "%s Not a discovery packet from an unknown source : ignoring\n", tmpbuf);
4697 }
4698 return;
4699 }
4700
4701 if (sbuf[0] != 0) { /* Starting with something else than 0x0000 ? */
4702 ast_log(LOG_NOTICE, "Unknown packet received - ignoring\n");
4703 return;
4704 }
4705 if (buf[5] != 2) {
4706 ast_log(LOG_NOTICE, "%s Wrong direction : got 0x%02hhx expected 0x02\n", tmpbuf, buf[5]);
4707 return;
4708 }
4709 seq = ntohs(sbuf[1]);
4710 if (buf[4] == 1) {
4711 ast_mutex_lock(&pte->lock);
4712 if (unistimdebug) {
4713 ast_verb(0, "ACK received for packet #0x%04x\n", (unsigned)seq);
4714 }
4715 pte->nb_retransmit = 0;
4716
4717 if ((pte->last_seq_ack) + 1 == seq) {
4718 pte->last_seq_ack++;
4719 check_send_queue(pte);
4720 ast_mutex_unlock(&pte->lock);
4721 return;
4722 }
4723 if (pte->last_seq_ack > seq) {
4724 if (pte->last_seq_ack == 0xffff) {
4725 ast_verb(0, "ACK at 0xffff, restarting counter.\n");
4726 pte->last_seq_ack = 0;
4727 } else {
4729 "%s Warning : ACK received for an already ACKed packet : #0x%04x we are at #0x%04x\n",
4730 tmpbuf, (unsigned)seq, (unsigned)pte->last_seq_ack);
4731 }
4732 ast_mutex_unlock(&pte->lock);
4733 return;
4734 }
4735 if (pte->seq_server < seq) {
4737 "%s Error : ACK received for a non-existent packet : #0x%04x\n",
4738 tmpbuf, (unsigned)pte->seq_server);
4739 ast_mutex_unlock(&pte->lock);
4740 return;
4741 }
4742 if (unistimdebug) {
4743 ast_verb(0, "%s ACK gap : Received ACK #0x%04x, previous was #0x%04x\n",
4744 tmpbuf, (unsigned)seq, (unsigned)pte->last_seq_ack);
4745 }
4746 pte->last_seq_ack = seq;
4747 check_send_queue(pte);
4748 ast_mutex_unlock(&pte->lock);
4749 return;
4750 }
4751 if (buf[4] == 2) {
4752 if (unistimdebug) {
4753 ast_verb(0, "Request received\n");
4754 }
4755 if (pte->seq_phone == seq) {
4756 /* Send ACK */
4757 buf[4] = 1;
4758 buf[5] = 1;
4759 send_raw_client(SIZE_HEADER, buf, addr_from, &pte->sout);
4760 pte->seq_phone++;
4761
4762 process_request(size, buf, pte);
4763 return;
4764 }
4765 if (pte->seq_phone > seq) {
4767 "%s Warning : received a retransmitted packet : #0x%04x (we are at #0x%04x)\n",
4768 tmpbuf, (unsigned)seq, (unsigned)pte->seq_phone);
4769 /* BUG ? pte->device->seq_phone = seq; */
4770 /* Send ACK */
4771 buf[4] = 1;
4772 buf[5] = 1;
4773 send_raw_client(SIZE_HEADER, buf, addr_from, &pte->sout);
4774 return;
4775 }
4777 "%s Warning : we lost a packet : received #0x%04x (we are at #0x%04x)\n",
4778 tmpbuf, (unsigned)seq, (unsigned)pte->seq_phone);
4779 return;
4780 }
4781 if (buf[4] == 0) {
4782 ast_log(LOG_NOTICE, "%s Retransmit request for packet #0x%04x\n", tmpbuf, (unsigned)seq);
4783 if (pte->last_seq_ack > seq) {
4785 "%s Error : received a request for an already ACKed packet : #0x%04x\n",
4786 tmpbuf, (unsigned)pte->last_seq_ack);
4787 return;
4788 }
4789 if (pte->seq_server < seq) {
4791 "%s Error : received a request for a non-existent packet : #0x%04x\n",
4792 tmpbuf, (unsigned)pte->seq_server);
4793 return;
4794 }
4795 send_retransmit(pte);
4796 return;
4797 }
4798 ast_log(LOG_NOTICE, "%s Unknown request : got 0x%02hhx expected 0x00,0x01 or 0x02\n", tmpbuf, buf[4]);
4799 return;
4800}
static volatile unsigned int seq
Definition app_sms.c:126
static const unsigned char packet_send_discovery_ack[]
static void check_send_queue(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 struct unistimsession * create_client(const struct sockaddr_in *addr_from)
static void process_request(int size, unsigned char *buf, struct unistimsession *pte)
static const unsigned char packet_rcv_discovery[]
static void close_client(struct unistimsession *s)
unsigned short seq_phone

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

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

◆ process_request()

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

Definition at line 4477 of file chan_unistim.c.

4478{
4479 char tmpbuf[255];
4480 if (memcmp
4484 return;
4485 }
4487 buf[size] = 0;
4488 if (unistimdebug) {
4489 ast_verb(0, "Got the firmware version : '%s'\n", buf + 13);
4490 }
4491 ast_copy_string(pte->firmware, (char *) (buf + 13), sizeof(pte->firmware));
4492 init_phone_step2(pte);
4493 return;
4494 }
4495 if (memcmp(buf + SIZE_HEADER, packet_recv_it_type, sizeof(packet_recv_it_type)) == 0) {
4496 char type = buf[13];
4497 if (unistimdebug) {
4498 ast_verb(0, "Got the equipment type: '%d'\n", type);
4499 }
4500 switch (type) {
4501 case 0x03: /* i2002 */
4502 if (pte->device) {
4503 pte->device->height = 1;
4504 }
4505 break;
4506 }
4507 return;
4508 }
4509 if (memcmp(buf + SIZE_HEADER, packet_recv_mac_addr, sizeof(packet_recv_mac_addr)) == 0) {
4510 rcv_mac_addr(pte, buf);
4511 return;
4512 }
4513 if (memcmp(buf + SIZE_HEADER, packet_recv_r2, sizeof(packet_recv_r2)) == 0) {
4514 if (unistimdebug) {
4515 ast_verb(0, "R2 received\n");
4516 }
4517 return;
4518 }
4519
4520 if (pte->state < STATE_MAINPAGE) {
4521 if (unistimdebug) {
4522 ast_verb(0, "Request not authorized in this state\n");
4523 }
4524 return;
4525 }
4527 char keycode = buf[13];
4528
4529 if (unistimdebug) {
4530 ast_verb(0, "Expansion key pressed: keycode = 0x%02hhx - current state: %s\n", (unsigned char)keycode,
4531 ptestate_tostr(pte->state));
4532 }
4533 }
4535 char keycode = buf[13];
4536
4537 if (unistimdebug) {
4538 ast_verb(0, "Key pressed: keycode = 0x%02hhx - current state: %s\n", (unsigned char)keycode,
4539 ptestate_tostr(pte->state));
4540 }
4541 if (keycode == KEY_MUTE) {
4543 }
4544 switch (pte->state) {
4545 case STATE_INIT:
4546 if (unistimdebug) {
4547 ast_verb(0, "No keys allowed in the init state\n");
4548 }
4549 break;
4550 case STATE_AUTHDENY:
4551 if (unistimdebug) {
4552 ast_verb(0, "No keys allowed in authdeny state\n");
4553 }
4554 break;
4555 case STATE_MAINPAGE:
4556 key_main_page(pte, keycode);
4557 break;
4558 case STATE_DIALPAGE:
4559 key_dial_page(pte, keycode);
4560 break;
4561 case STATE_RINGING:
4562 key_ringing(pte, keycode);
4563 break;
4564 case STATE_CALL:
4565 key_call(pte, keycode);
4566 break;
4567 case STATE_EXTENSION:
4568 key_select_extension(pte, keycode);
4569 break;
4570 case STATE_SELECTOPTION:
4571 key_select_option(pte, keycode);
4572 break;
4573 case STATE_SELECTCODEC:
4574 key_select_codec(pte, keycode);
4575 break;
4577 key_select_language(pte, keycode);
4578 break;
4579 case STATE_HISTORY:
4580 key_history(pte, keycode);
4581 break;
4582 default:
4583 ast_log(LOG_WARNING, "Key : Unknown state\n");
4584 }
4585 return;
4586 }
4587 if (memcmp(buf + SIZE_HEADER, packet_recv_pick_up, sizeof(packet_recv_pick_up)) == 0) {
4588 if (unistimdebug) {
4589 ast_verb(0, "Handset off hook, current state: %s\n", ptestate_tostr(pte->state));
4590 }
4591 if (!pte->device) { /* We are not yet registered (asking for a TN in AUTOPROVISIONING_TN) */
4592 return;
4593 }
4595 if (pte->device->output == OUTPUT_HEADPHONE) {
4597 } else {
4599 }
4600 if (pte->state == STATE_RINGING) {
4602 } else if ((pte->state == STATE_DIALPAGE) || (pte->state == STATE_CALL)) {
4604 } else if (pte->state == STATE_EXTENSION) { /* We must have a TN before calling */
4605 return;
4606 } else {
4607 pte->device->selected = get_avail_softkey(pte, NULL);
4609 handle_dial_page(pte);
4610 }
4611 return;
4612 }
4613 if (memcmp(buf + SIZE_HEADER, packet_recv_hangup, sizeof(packet_recv_hangup)) == 0) {
4614 if (unistimdebug) {
4615 ast_verb(0, "Handset on hook, current state: %s\n", ptestate_tostr(pte->state));
4616 }
4617 if (!pte->device) {
4618 return;
4619 }
4621 if (pte->state == STATE_CALL) {
4622 if (pte->device->output != OUTPUT_SPEAKER) {
4623 close_call(pte);
4624 }
4625 } else if (pte->state == STATE_EXTENSION) {
4626 return;
4627 } else {
4628 pte->device->nextdial = 0;
4629 show_main_page(pte);
4630 }
4631 return;
4632 }
4633 strcpy(tmpbuf, ast_inet_ntoa(pte->sin.sin_addr));
4634 strcat(tmpbuf, " Unknown request packet\n");
4635 if (unistimdebug) {
4636 ast_debug(1, "%s", tmpbuf);
4637 }
4638 return;
4639}
static const unsigned char packet_recv_pressed_key[]
static void key_ringing(struct unistimsession *pte, char keycode)
static const unsigned char packet_recv_resume_connection_with_server[]
static void init_phone_step2(struct unistimsession *pte)
static void key_select_language(struct unistimsession *pte, char keycode)
static void key_call(struct unistimsession *pte, char keycode)
static void key_history(struct unistimsession *pte, char keycode)
static const unsigned char packet_recv_it_type[]
static void key_select_option(struct unistimsession *pte, char keycode)
static void key_select_codec(struct unistimsession *pte, char keycode)
static const char * ptestate_tostr(const int type)
static const unsigned char packet_recv_hangup[]
static const unsigned char packet_recv_pick_up[]
static void key_select_extension(struct unistimsession *pte, char keycode)
static const unsigned char packet_recv_firm_version[]
static void microphone_mute_toggle(struct unistimsession *pte)
static void rcv_mac_addr(struct unistimsession *pte, const unsigned char *buf)
static const unsigned char packet_recv_mac_addr[]
static void rcv_resume_connection_with_server(struct unistimsession *pte)
static const unsigned char packet_recv_r2[]
static const unsigned char packet_recv_expansion_pressed_key[]

References ast_copy_string(), ast_debug, ast_inet_ntoa(), ast_log, ast_verb, buf, close_call(), unistimsession::device, unistimsession::firmware, get_avail_softkey(), handle_call_incoming(), handle_dial_page(), unistim_device::height, init_phone_step2(), key_call(), key_dial_page(), key_history(), key_main_page(), KEY_MUTE, key_ringing(), key_select_codec(), key_select_extension(), key_select_language(), key_select_option(), LOG_WARNING, microphone_mute_toggle(), MUTE_OFF, unistim_device::nextdial, NULL, unistim_device::output, OUTPUT_HANDSET, OUTPUT_HEADPHONE, OUTPUT_SPEAKER, packet_recv_expansion_pressed_key, packet_recv_firm_version, packet_recv_hangup, packet_recv_it_type, packet_recv_mac_addr, packet_recv_pick_up, packet_recv_pressed_key, packet_recv_r2, packet_recv_resume_connection_with_server, ptestate_tostr(), rcv_mac_addr(), rcv_resume_connection_with_server(), unistim_device::receiver_state, unistim_device::selected, 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, STATE_SELECTLANGUAGE, STATE_SELECTOPTION, type, unistimdebug, and unistim_device::volume.

Referenced by parsing().

◆ ptestate_tostr()

static const char * ptestate_tostr ( const int  type)
static

Definition at line 2042 of file chan_unistim.c.

2043{
2044 switch (type) {
2045 case STATE_INIT:
2046 return "INIT";
2047 case STATE_AUTHDENY:
2048 return "AUTHDENY";
2049 case STATE_MAINPAGE:
2050 return "MAINPAGE";
2051 case STATE_EXTENSION:
2052 return "EXTENSION";
2053 case STATE_DIALPAGE:
2054 return "DIALPAGE";
2055 case STATE_RINGING:
2056 return "RINGING";
2057 case STATE_CALL:
2058 return "CALL";
2059 case STATE_SELECTOPTION:
2060 return "SELECTOPTION";
2061 case STATE_SELECTCODEC:
2062 return "SELECTCODEC";
2064 return "SELECTLANGUAGE";
2065 case STATE_CLEANING:
2066 return "CLEARING";
2067 case STATE_HISTORY:
2068 return "HISTORY";
2069 }
2070 return "UNKNOWN";
2071}

References STATE_AUTHDENY, STATE_CALL, STATE_CLEANING, STATE_DIALPAGE, STATE_EXTENSION, STATE_HISTORY, STATE_INIT, STATE_MAINPAGE, STATE_RINGING, STATE_SELECTCODEC, STATE_SELECTLANGUAGE, STATE_SELECTOPTION, and type.

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

◆ rcv_mac_addr()

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

Definition at line 2073 of file chan_unistim.c.

2074{
2075 BUFFSEND;
2076 int tmp, i = 0;
2077 char addrmac[19];
2078 int res = 0;
2079 for (tmp = 15; tmp < 15 + SIZE_HEADER; tmp++) {
2080 sprintf(&addrmac[i], "%02hhx", buf[tmp]);
2081 i += 2;
2082 }
2083 if (unistimdebug) {
2084 ast_verb(0, "MAC Address received: %s\n", addrmac);
2085 }
2086 strcpy(pte->macaddr, addrmac);
2087 res = unistim_register(pte);
2088 if (!res) {
2089 switch (autoprovisioning) {
2091 ast_log(LOG_WARNING, "No entry found for this phone : %s\n", addrmac);
2092 pte->state = STATE_AUTHDENY;
2093 break;
2095 {
2096 struct unistim_device *d = NULL, *newd = NULL;
2097 struct unistim_line *newl = NULL, *l = NULL;
2098 if (unistimdebug) {
2099 ast_verb(0, "New phone, autoprovisioning on\n");
2100 }
2101 /* First : locate the [template] section */
2103 d = devices;
2104 while (d) {
2105 if (strcasecmp(d->name, "template")) {
2106 d = d->next;
2107 continue;
2108 }
2109 /* Found, cloning this entry */
2110 if (!(newd = ast_malloc(sizeof(*newd)))) {
2112 return;
2113 }
2114 memcpy(newd, d, sizeof(*newd));
2115 ast_mutex_init(&newd->lock);
2116 newd->lines.first = NULL;
2117 newd->lines.last = NULL;
2118 AST_LIST_LOCK(&d->lines);
2119 AST_LIST_TRAVERSE(&d->lines, l, list) {
2120 if (!(newl = unistim_line_alloc())) {
2121 break;
2122 }
2123 unistim_line_copy(l, newl);
2124 newl->parent = newd;
2125 ast_copy_string(newl->name, l->name, sizeof(newl->name));
2126 snprintf(newl->fullname, sizeof(newl->fullname), "USTM/%s@%s",
2127 newl->name, newd->name);
2128 snprintf(l->name, sizeof(l->name), "%d", atoi(l->name) + 1);
2129
2130 AST_LIST_LOCK(&newd->lines);
2131 AST_LIST_INSERT_TAIL(&newd->lines, newl, list);
2132 AST_LIST_UNLOCK(&newd->lines);
2133 }
2134 AST_LIST_UNLOCK(&d->lines);
2135 if (!newl) {
2136 ast_free(newd);
2138 }
2139
2140 /* Ok, now updating some fields */
2141 ast_copy_string(newd->id, addrmac, sizeof(newd->id));
2142 ast_copy_string(newd->name, addrmac, sizeof(newd->name));
2143 if (newd->extension == EXTENSION_NONE) {
2144 newd->extension = EXTENSION_ASK;
2145 }
2146
2147 newd->receiver_state = STATE_ONHOOK;
2148 newd->session = pte;
2149 newd->language[0] = '\0';
2150 newd->to_delete = -1;
2151 newd->next = NULL;
2152 pte->device = newd;
2153
2154 /* Go to the end of the linked chain */
2155 while (d->next) {
2156 d = d->next;
2157 }
2158 d->next = newd;
2159 d = newd;
2160 break;
2161 }
2163 if (!d) {
2164 ast_log(LOG_WARNING, "No entry [template] found in unistim.conf\n");
2165 pte->state = STATE_AUTHDENY;
2166 }
2167 }
2168 break;
2170 pte->state = STATE_AUTHDENY;
2171 break;
2172 default:
2173 ast_log(LOG_WARNING, "Internal error : unknown autoprovisioning value = %u\n",
2175 }
2176 }
2177 if (pte->state != STATE_AUTHDENY) {
2178 struct unistim_line *line;
2179 struct unistim_subchannel *sub;
2180
2181 ast_verb(3, "Device '%s' successfully registered\n", pte->device->name);
2182
2183 AST_LIST_LOCK(&pte->device->subs);
2185 if (sub) {
2186 ast_log(LOG_ERROR, "Subchannel lost sice reboot. Hanged channel may appear!\n");
2188 ast_free(sub);
2189 }
2190 }
2192 AST_LIST_UNLOCK(&pte->device->subs);
2193
2194 switch (pte->device->extension) {
2195 case EXTENSION_NONE:
2196 pte->state = STATE_MAINPAGE;
2197 break;
2198 case EXTENSION_ASK:
2199 /* Checking if we already have an extension number */
2201 pte->state = STATE_EXTENSION;
2202 } else {
2203 /* Yes, because of a phone reboot. We don't ask again for the TN */
2204 if (register_extension(pte)) {
2205 pte->state = STATE_EXTENSION;
2206 } else {
2207 pte->state = STATE_MAINPAGE;
2208 }
2209 }
2210 break;
2211 case EXTENSION_LINE:
2212 line = AST_LIST_FIRST(&pte->device->lines);
2214 sizeof(pte->device->extension_number));
2215 if (register_extension(pte)) {
2216 pte->state = STATE_EXTENSION;
2217 } else {
2218 pte->state = STATE_MAINPAGE;
2219 }
2220 break;
2221 case EXTENSION_TN:
2222 /* If we are here, it's because of a phone reboot */
2223 pte->state = STATE_MAINPAGE;
2224 break;
2225 default:
2226 ast_log(LOG_WARNING, "Internal error, extension value unknown : %u\n",
2227 pte->device->extension);
2228 pte->state = STATE_AUTHDENY;
2229 break;
2230 }
2231 }
2232 if (pte->state == STATE_EXTENSION) {
2233 if (pte->device->extension != EXTENSION_TN) {
2235 }
2236 pte->device->extension_number[0] = '\0';
2237 }
2238 if (unistimdebug) {
2239 ast_verb(0, "\nSending S1\n");
2240 }
2241 memcpy(buffsend + SIZE_HEADER, packet_send_S1, sizeof(packet_send_S1));
2242 send_client(SIZE_HEADER + sizeof(packet_send_S1), buffsend, pte);
2243
2244 if (unistimdebug) {
2245 ast_verb(0, "Sending query_basic_manager_04\n");
2246 }
2250
2251 if (unistimdebug) {
2252 ast_verb(0, "Sending query_basic_manager_10\n");
2253 }
2257
2258 send_date_time(pte);
2259 return;
2260}
static void unistim_line_copy(struct unistim_line *dst, struct unistim_line *src)
static void send_date_time(struct unistimsession *pte)
static const unsigned char packet_send_query_basic_manager_04[]
static const unsigned char packet_send_query_basic_manager_10[]
static const unsigned char packet_send_S1[]
static int unistim_register(struct unistimsession *s)
#define AST_LIST_FIRST(head)
Returns the first entry contained in a list.

References ast_copy_string(), ast_free, AST_LIST_FIRST, AST_LIST_INSERT_TAIL, AST_LIST_LOCK, AST_LIST_REMOVE_CURRENT, AST_LIST_TRAVERSE, AST_LIST_TRAVERSE_SAFE_BEGIN, AST_LIST_TRAVERSE_SAFE_END, AST_LIST_UNLOCK, ast_log, ast_malloc, ast_mutex_init, ast_mutex_lock, ast_mutex_unlock, ast_strlen_zero(), ast_verb, autoprovisioning, AUTOPROVISIONING_NO, AUTOPROVISIONING_TN, AUTOPROVISIONING_YES, buf, BUFFSEND, d, unistimsession::device, devicelock, devices, unistim_device::extension, EXTENSION_ASK, EXTENSION_LINE, EXTENSION_NONE, unistim_device::extension_number, EXTENSION_TN, unistim_line::fullname, unistim_device::lines, unistim_subchannel::list, unistim_line::list, LOG_ERROR, LOG_WARNING, unistimsession::macaddr, unistim_line::name, unistim_device::name, test_val::name, unistimsession::next, test_val::next, NULL, packet_send_query_basic_manager_04, packet_send_query_basic_manager_10, packet_send_S1, unistim_line::parent, register_extension(), send_client(), send_date_time(), SIZE_HEADER, unistimsession::state, STATE_AUTHDENY, STATE_EXTENSION, STATE_MAINPAGE, STATE_ONHOOK, sub, unistim_device::subs, unistim_line_alloc(), unistim_line_copy(), unistim_register(), and unistimdebug.

Referenced by process_request().

◆ rcv_resume_connection_with_server()

static void rcv_resume_connection_with_server ( struct unistimsession pte)
static

Definition at line 1909 of file chan_unistim.c.

1910{
1911 BUFFSEND;
1912 if (unistimdebug) {
1913 ast_verb(0, "ResumeConnectionWithServer received\n");
1914 ast_verb(0, "Sending packet_send_query_mac_address\n");
1915 }
1916 memcpy(buffsend + SIZE_HEADER, packet_send_query_mac_address,
1918 send_client(SIZE_HEADER + sizeof(packet_send_query_mac_address), buffsend, pte);
1919 return;
1920}
static const unsigned char packet_send_query_mac_address[]

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

Referenced by process_request().

◆ refresh_all_favorite()

static void refresh_all_favorite ( struct unistimsession pte)
static

Definition at line 1323 of file chan_unistim.c.

1324{
1325 unsigned char i = 0;
1326 char data[256];
1327 struct unistim_line *line;
1328 line = AST_LIST_FIRST(&pte->device->lines);
1329
1330 if (unistimdebug) {
1331 ast_verb(0, "Refreshing all favorite\n");
1332 }
1333 for (i = 0; i < FAVNUM; i++) {
1334 unsigned char status = pte->device->softkeyicon[i];
1335
1336 if (!soft_key_visible(pte->device, i)) {
1337 continue;
1338 }
1339 if (!strcasecmp(pte->device->softkeylabel[i], "DND") && line) {
1340 if (!ast_db_get("DND", line->name, data, sizeof(data))) {
1342 }
1343 }
1344
1345 send_favorite_short(i, status, pte);
1346 }
1347 if (pte->device->hasexp) {
1348 for (i = 0; i < EXPNUM; i++) {
1350 }
1351 }
1352}
int ast_db_get(const char *family, const char *key, char *value, int valuelen)
Get key value specified by family/key.
Definition db.c:421
#define EXPNUM
#define FAV_ICON_SPEAKER_ONHOOK_WHITE
static void send_expansion_short(unsigned char pos, unsigned char status, struct unistimsession *pte)
char softkeyicon[FAVNUM]
char softkeylabel[FAVNUM][11]

References ast_db_get(), AST_LIST_FIRST, ast_verb, unistimsession::device, EXPNUM, FAV_ICON_NONE, FAV_ICON_SPEAKER_ONHOOK_WHITE, FAVNUM, unistim_device::hasexp, unistim_device::lines, unistim_line::name, send_expansion_short(), send_favorite_short(), soft_key_visible(), unistim_device::softkeyicon, unistim_device::softkeylabel, status, and unistimdebug.

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

◆ register_extension()

static int register_extension ( const struct unistimsession pte)
static

Definition at line 1447 of file chan_unistim.c.

1448{
1449 struct unistim_line *line;
1450 line = AST_LIST_FIRST(&pte->device->lines);
1451 if (unistimdebug) {
1452 ast_verb(0, "Trying to register extension '%s' into context '%s' to %s\n",
1454 line->fullname);
1455 }
1456 return ast_add_extension(pte->device->context, 0,
1457 pte->device->extension_number, 1, NULL, NULL, "Dial",
1458 line->fullname, 0, "Unistim");
1459}
int ast_add_extension(const char *context, int replace, const char *extension, int priority, const char *label, const char *callerid, const char *application, void *data, void(*datad)(void *), const char *registrar)
Add and extension to an extension context.
Definition pbx.c:5206

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

Referenced by key_select_extension(), and rcv_mac_addr().

◆ reload()

int reload ( void  )
static

reload: Part of Asterisk module interface —

Definition at line 7191 of file chan_unistim.c.

7192{
7193 if (unistimdebug) {
7194 ast_verb(0, "reload unistim\n");
7195 }
7197 if (!unistim_reloading) {
7199 }
7201
7203
7204 return 0;
7205}

References ast_mutex_lock, ast_mutex_unlock, ast_verb, restart_monitor(), unistim_reload_lock, unistim_reloading, and unistimdebug.

Referenced by unistim_reload().

◆ reload_config()

static int reload_config ( void  )
static

Definition at line 6852 of file chan_unistim.c.

6853{
6854 struct ast_config *cfg;
6855 struct ast_variable *v;
6856 struct sockaddr_in bindaddr = { 0, };
6857 char *config = "unistim.conf";
6858 char *cat;
6859 struct unistim_device *d;
6860 const int reuseFlag = 1;
6861 struct unistimsession *s;
6862 struct ast_flags config_flags = { 0, };
6863
6864 cfg = ast_config_load(config, config_flags);
6865 /* We *must* have a config file otherwise stop immediately */
6866 if (!cfg) {
6867 ast_log(LOG_ERROR, "Unable to load config %s\n", config);
6868 return -1;
6869 } else if (cfg == CONFIG_STATUS_FILEINVALID) {
6870 ast_log(LOG_ERROR, "Config file %s is in an invalid format. Aborting.\n", config);
6871 return -1;
6872 }
6873
6874 /* Copy the default jb config over global_jbconf */
6875 memcpy(&global_jbconf, &default_jbconf, sizeof(struct ast_jb_conf));
6876
6877 unistim_keepalive = 120;
6878 unistim_port = 0;
6879 v = ast_variable_browse(cfg, "general");
6880 while (v) {
6881 /* handle jb conf */
6882 if (!ast_jb_read_conf(&global_jbconf, v->name, v->value)) {
6883 continue;
6884 }
6885 if (!strcasecmp(v->name, "keepalive")) {
6886 unistim_keepalive = atoi(v->value);
6887 } else if (!strcasecmp(v->name, "port")) {
6888 unistim_port = atoi(v->value);
6889 } else if (!strcasecmp(v->name, "tos")) {
6890 if (ast_str2tos(v->value, &qos.tos)) {
6891 ast_log(LOG_WARNING, "Invalid tos value at line %d, refer to QoS documentation\n", v->lineno);
6892 }
6893 } else if (!strcasecmp(v->name, "tos_audio")) {
6894 if (ast_str2tos(v->value, &qos.tos_audio)) {
6895 ast_log(LOG_WARNING, "Invalid tos_audio value at line %d, refer to QoS documentation\n", v->lineno);
6896 }
6897 } else if (!strcasecmp(v->name, "cos")) {
6898 if (ast_str2cos(v->value, &qos.cos)) {
6899 ast_log(LOG_WARNING, "Invalid cos value at line %d, refer to QoS documentation\n", v->lineno);
6900 }
6901 } else if (!strcasecmp(v->name, "cos_audio")) {
6902 if (ast_str2cos(v->value, &qos.cos_audio)) {
6903 ast_log(LOG_WARNING, "Invalid cos_audio value at line %d, refer to QoS documentation\n", v->lineno);
6904 }
6905 } else if (!strcasecmp(v->name, "debug")) {
6906 if (!strcasecmp(v->value, "no")) {
6907 unistimdebug = 0;
6908 } else if (!strcasecmp(v->value, "yes")) {
6909 unistimdebug = 1;
6910 }
6911 } else if (!strcasecmp(v->name, "autoprovisioning")) {
6912 if (!strcasecmp(v->value, "no")) {
6914 } else if (!strcasecmp(v->value, "yes")) {
6916 } else if (!strcasecmp(v->value, "tn")) {
6918 } else {
6919 ast_log(LOG_WARNING, "Unknown autoprovisioning option.\n");
6920 }
6921 } else if (!strcasecmp(v->name, "public_ip")) {
6922 if (!ast_strlen_zero(v->value)) {
6923 struct ast_sockaddr addr = { {0,} };
6924 if (ast_sockaddr_resolve_first_af(&addr, v->value, PARSE_PORT_FORBID, AF_INET)) {
6925 ast_log(LOG_WARNING, "Invalid address: %s\n", v->value);
6926 } else {
6928 }
6929 }
6930 }
6931 v = v->next;
6932 }
6933 if ((unistim_keepalive < 10) ||
6935 255 - (((NB_MAX_RETRANSMIT + 1) * RETRANSMIT_TIMER) / 1000))) {
6936 ast_log(LOG_ERROR, "keepalive is invalid in %s\n", config);
6937 ast_config_destroy(cfg);
6938 return -1;
6939 }
6940 packet_send_ping[4] =
6942 if ((unistim_port < 1) || (unistim_port > 65535)) {
6943 ast_log(LOG_ERROR, "port is not set or invalid in %s\n", config);
6944 ast_config_destroy(cfg);
6945 return -1;
6946 }
6947 unistim_keepalive *= 1000;
6948
6950 d = devices;
6951 while (d) {
6952 if (d->to_delete >= 0) {
6953 d->to_delete = 1;
6954 }
6955 d = d->next;
6956 }
6958 /* load the device sections */
6959 cat = ast_category_browse(cfg, NULL);
6960 while (cat) {
6961 if (strcasecmp(cat, "general")) {
6962 d = build_device(cat, ast_variable_browse(cfg, cat));
6963 }
6964 cat = ast_category_browse(cfg, cat);
6965 }
6967 d = devices;
6968 while (d) {
6969 if (d->to_delete) {
6971 d = devices;
6972 continue;
6973 }
6974 d = d->next;
6975 }
6978 ast_config_destroy(cfg);
6980 s = sessions;
6981 while (s) {
6982 if (s->device) {
6984 if (ast_strlen_zero(s->device->language)) {
6985 struct unistim_languages lang;
6987 send_charset_update(s, lang.encoding);
6988 }
6989 }
6990 s = s->next;
6991 }
6993 /* We don't recreate a socket when reloading (locks would be necessary). */
6994 if (unistimsock > -1) {
6995 return 0;
6996 }
6997 bindaddr.sin_addr.s_addr = INADDR_ANY;
6998 bindaddr.sin_port = htons(unistim_port);
6999 bindaddr.sin_family = AF_INET;
7000 unistimsock = socket(AF_INET, SOCK_DGRAM, 0);
7001 if (unistimsock < 0) {
7002 ast_log(LOG_WARNING, "Unable to create UNISTIM socket: %s\n", strerror(errno));
7003 return -1;
7004 }
7005#ifdef HAVE_PKTINFO
7006 {
7007 const int pktinfoFlag = 1;
7008 setsockopt(unistimsock, IPPROTO_IP, IP_PKTINFO, &pktinfoFlag,
7009 sizeof(pktinfoFlag));
7010 }
7011#else
7012 if (public_ip.sin_family == 0) {
7014 "Your OS does not support IP_PKTINFO, you must set public_ip.\n");
7015 unistimsock = -1;
7016 return -1;
7017 }
7018#endif
7019 setsockopt(unistimsock, SOL_SOCKET, SO_REUSEADDR, (const char *) &reuseFlag,
7020 sizeof(reuseFlag));
7021 if (bind(unistimsock, (struct sockaddr *) &bindaddr, sizeof(bindaddr)) < 0) {
7022 ast_log(LOG_WARNING, "Failed to bind to %s:%d: %s\n",
7023 ast_inet_ntoa(bindaddr.sin_addr), htons(bindaddr.sin_port),
7024 strerror(errno));
7025 close(unistimsock);
7026 unistimsock = -1;
7027 } else {
7028 ast_verb(2, "UNISTIM Listening on %s:%d\n", ast_inet_ntoa(bindaddr.sin_addr), htons(bindaddr.sin_port));
7029 ast_set_qos(unistimsock, qos.tos, qos.cos, "UNISTIM");
7030 }
7031 return 0;
7032}
int ast_jb_read_conf(struct ast_jb_conf *conf, const char *varname, const char *value)
Sets jitterbuffer configuration property.
int ast_str2tos(const char *value, unsigned int *tos)
Convert a string to the appropriate TOS value.
Definition acl.c:983
int ast_str2cos(const char *value, unsigned int *cos)
Convert a string to the appropriate COS value.
Definition acl.c:969
struct ast_sockaddr bindaddr
static const char config[]
static int unistim_port
static struct ast_jb_conf default_jbconf
Global jitterbuffer configuration - by default, jb is disabled.
static struct @134 qos
static unsigned char packet_send_ping[]
static void finish_bookmark(void)
#define NB_MAX_RETRANSMIT
static struct ast_jb_conf global_jbconf
static struct unistim_device * build_device(const char *cat, const struct ast_variable *v)
#define ast_config_load(filename, flags)
Load a config file.
char * ast_category_browse(struct ast_config *config, const char *prev_name)
Browse categories.
Definition extconf.c:3324
#define CONFIG_STATUS_FILEINVALID
void ast_config_destroy(struct ast_config *cfg)
Destroys a config.
Definition extconf.c:1287
struct ast_variable * ast_variable_browse(const struct ast_config *config, const char *category_name)
Definition extconf.c:1213
int ast_sockaddr_resolve_first_af(struct ast_sockaddr *addr, const char *name, int flag, int family)
Return the first entry from ast_sockaddr_resolve filtered by address family.
Definition netsock2.c:337
int ast_set_qos(int sockfd, int tos, int cos, const char *desc)
Set type of service.
Definition netsock2.c:621
Structure used to handle boolean flags.
Definition utils.h:220
General jitterbuffer configuration.
Definition abstract_jb.h:70
Structure for variables, used for configurations and for channel variables.

References ast_category_browse(), ast_config_destroy(), ast_config_load, ast_inet_ntoa(), ast_jb_read_conf(), ast_log, ast_mutex_lock, ast_mutex_unlock, ast_set_qos(), ast_sockaddr_resolve_first_af(), ast_sockaddr_to_sin, ast_str2cos(), ast_str2tos(), ast_strlen_zero(), ast_variable_browse(), ast_verb, autoprovisioning, AUTOPROVISIONING_NO, AUTOPROVISIONING_TN, AUTOPROVISIONING_YES, bindaddr, build_device(), config, CONFIG_STATUS_FILEINVALID, d, default_jbconf, delete_device(), unistimsession::device, devicelock, devices, unistim_languages::encoding, errno, find_language(), finish_bookmark(), global_jbconf, unistim_device::language, ast_variable::lineno, LOG_ERROR, LOG_WARNING, ast_variable::name, NB_MAX_RETRANSMIT, unistimsession::next, ast_variable::next, test_val::next, NULL, options_languages, packet_send_ping, PARSE_PORT_FORBID, public_ip, qos, refresh_all_favorite(), RETRANSMIT_TIMER, send_charset_update(), sessionlock, sessions, unistim_keepalive, unistim_port, unistimdebug, unistimsock, and ast_variable::value.

Referenced by acl_change_stasis_cb(), do_monitor(), handle_cli_iax2_reload(), load_module(), load_module(), ooh323_do_reload(), and reload().

◆ restart_monitor()

static int restart_monitor ( void  )
static

Definition at line 5927 of file chan_unistim.c.

5928{
5929 pthread_attr_t attr;
5930 /* If we're supposed to be stopped -- stay stopped */
5932 return 0;
5933 }
5934 if (ast_mutex_lock(&monlock)) {
5935 ast_log(LOG_WARNING, "Unable to lock monitor\n");
5936 return -1;
5937 }
5938 if (monitor_thread == pthread_self()) {
5940 ast_log(LOG_WARNING, "Cannot kill myself\n");
5941 return -1;
5942 }
5944 /* Wake up the thread */
5945 pthread_kill(monitor_thread, SIGURG);
5946 } else {
5947 pthread_attr_init(&attr);
5948 pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE);
5949 /* Start a new monitor */
5950 if (ast_pthread_create(&monitor_thread, &attr, do_monitor, NULL) < 0) {
5952 ast_log(LOG_ERROR, "Unable to start monitor thread.\n");
5953 return -1;
5954 }
5955 }
5957 return 0;
5958}
static void * do_monitor(void *data)
static ast_mutex_t monlock
static pthread_t monitor_thread
#define AST_PTHREADT_STOP
Definition lock.h:74

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

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

◆ send_blink_cursor()

static void send_blink_cursor ( struct unistimsession pte)
static

Definition at line 1846 of file chan_unistim.c.

1847{
1848 BUFFSEND;
1849 if (unistimdebug) {
1850 ast_verb(0, "Sending set blink\n");
1851 }
1853 send_client(SIZE_HEADER + sizeof(packet_send_blink_cursor), buffsend, pte);
1854 return;
1855}
static const unsigned char packet_send_blink_cursor[]

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

Referenced by handle_select_codec(), key_select_codec(), key_select_extension(), show_extension_page(), and show_phone_number().

◆ send_callerid_screen()

static void send_callerid_screen ( struct unistimsession pte,
struct unistim_subchannel sub 
)
static

Definition at line 4833 of file chan_unistim.c.

4834{
4835 char *cidname_str;
4836 char *cidnum_str;
4837
4838 if (!sub) {
4839 return;
4840 }
4841 if (sub->owner) {
4843 cidnum_str = ast_channel_connected(sub->owner)->id.number.str;
4844 } else {
4845 cidnum_str = DEFAULTCALLERID;
4846 }
4847 change_callerid(pte, 0, cidnum_str);
4848 if (strlen(cidnum_str) == 0) {
4849 cidnum_str = DEFAULTCALLERID;
4850 }
4851
4853 cidname_str = ast_channel_connected(sub->owner)->id.name.str;
4854 } else {
4855 cidname_str = DEFAULTCALLERNAME;
4856 }
4857 change_callerid(pte, 1, cidname_str);
4858 if (strlen(cidname_str) == 0) {
4859 cidname_str = DEFAULTCALLERNAME;
4860 }
4861
4862 if (pte->device->height == 1) {
4863 char tmpstr[256];
4864 snprintf(tmpstr, sizeof(tmpstr), "%s %s", cidnum_str, ustmtext(cidname_str, pte));
4865 send_text(TEXT_LINE0, TEXT_NORMAL, pte, tmpstr);
4866 } else {
4867 send_text(TEXT_LINE0, TEXT_NORMAL, pte, cidname_str);
4868 send_text(TEXT_LINE1, TEXT_NORMAL, pte, ustmtext(cidnum_str, pte));
4869 }
4870 }
4871}
#define DEFAULTCALLERID
#define DEFAULTCALLERNAME
struct ast_party_connected_line * ast_channel_connected(struct ast_channel *chan)
struct ast_party_id id
Connected party ID.
Definition channel.h:460
struct ast_party_name name
Subscriber name.
Definition channel.h:342
struct ast_party_number number
Subscriber phone number.
Definition channel.h:344
unsigned char valid
TRUE if the name information is valid/present.
Definition channel.h:281
char * str
Subscriber name (Malloced)
Definition channel.h:266
unsigned char valid
TRUE if the number information is valid/present.
Definition channel.h:299
char * str
Subscriber phone number (Malloced)
Definition channel.h:293

References ast_channel_connected(), change_callerid(), DEFAULTCALLERID, DEFAULTCALLERNAME, unistimsession::device, unistim_device::height, ast_party_connected_line::id, ast_party_id::name, ast_party_id::number, send_text(), ast_party_name::str, ast_party_number::str, sub, TEXT_LINE0, TEXT_LINE1, TEXT_NORMAL, ustmtext(), ast_party_name::valid, and ast_party_number::valid.

Referenced by handle_key_fav(), key_dial_page(), unistim_call(), unistim_hangup(), and unistim_indicate().

◆ send_charset_update()

static void send_charset_update ( struct unistimsession pte,
int  charset 
)
static

Definition at line 1871 of file chan_unistim.c.

1872{
1873 const unsigned char* packet_send_charset;
1874 int packet_size;
1875 BUFFSEND;
1876 if (unistimdebug) {
1877 ast_verb(0, "Sending set default charset\n");
1878 }
1879 if (charset == LANG_DEFAULT) {
1881 }
1882 switch (charset) {
1883 case ISO_8859_2:
1884 packet_send_charset = packet_send_charset_iso_8859_2;
1885 packet_size = sizeof(packet_send_charset_iso_8859_2);
1886 break;
1887 case ISO_8859_4:
1888 packet_send_charset = packet_send_charset_iso_8859_4;
1889 packet_size = sizeof(packet_send_charset_iso_8859_4);
1890 break;
1891 case ISO_8859_5:
1892 packet_send_charset = packet_send_charset_iso_8859_5;
1893 packet_size = sizeof(packet_send_charset_iso_8859_5);
1894 break;
1895 case ISO_2022_JP:
1896 packet_send_charset = packet_send_charset_iso_2022_jp;
1897 packet_size = sizeof(packet_send_charset_iso_2022_jp);
1898 break;
1899 case ISO_8859_1:
1900 default:
1901 packet_send_charset = packet_send_charset_iso_8859_1;
1902 packet_size = sizeof(packet_send_charset_iso_8859_1);
1903 }
1904 memcpy(buffsend + SIZE_HEADER, packet_send_charset, packet_size);
1905 send_client(SIZE_HEADER + packet_size, buffsend, pte);
1906 return;
1907}
static const unsigned char packet_send_charset_iso_2022_jp[]
static const unsigned char packet_send_charset_iso_8859_5[]
charset
static const unsigned char packet_send_charset_iso_8859_4[]
static const unsigned char packet_send_charset_iso_8859_2[]
static const unsigned char packet_send_charset_iso_8859_1[]

References ast_verb, BUFFSEND, unistimsession::device, unistim_languages::encoding, find_language(), ISO_2022_JP, ISO_8859_1, ISO_8859_2, ISO_8859_4, ISO_8859_5, LANG_DEFAULT, unistim_device::language, options_languages, packet_send_charset_iso_2022_jp, packet_send_charset_iso_8859_1, packet_send_charset_iso_8859_2, packet_send_charset_iso_8859_4, packet_send_charset_iso_8859_5, send_client(), SIZE_HEADER, and unistimdebug.

Referenced by handle_select_language(), init_phone_step2(), key_select_language(), and reload_config().

◆ send_client()

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

Definition at line 961 of file chan_unistim.c.

962{
963 unsigned int tick;
964 int buf_pos;
965 unsigned short seq = ntohs(++pte->seq_server);
966
967 ast_mutex_lock(&pte->lock);
968 buf_pos = pte->last_buf_available;
969
970 if (buf_pos >= MAX_BUF_NUMBER) {
971 ast_log(LOG_WARNING, "Error : send queue overflow\n");
972 ast_mutex_unlock(&pte->lock);
973 return;
974 }
975 memcpy((void *)data + sizeof(unsigned short), (void *)&seq, sizeof(unsigned short));
976 pte->wsabufsend[buf_pos].len = size;
977 memcpy(pte->wsabufsend[buf_pos].buf, data, size);
978
979 tick = get_tick_count();
980 pte->timeout = tick + RETRANSMIT_TIMER;
981
982/*#ifdef DUMP_PACKET */
983 if (unistimdebug) {
984 ast_verb(0, "Sending data with seq #0x%04x Using slot #%d :\n", (unsigned)pte->seq_server, buf_pos);
985 }
986/*#endif */
987 send_raw_client(pte->wsabufsend[buf_pos].len, pte->wsabufsend[buf_pos].buf, &(pte->sin),
988 &(pte->sout));
989 pte->last_buf_available++;
990 ast_mutex_unlock(&pte->lock);
991}
u_long len

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, unistimdebug, and unistimsession::wsabufsend.

Referenced by init_phone_step2(), rcv_mac_addr(), rcv_resume_connection_with_server(), send_blink_cursor(), send_charset_update(), send_cursor_pos(), send_date_time(), send_date_time2(), send_date_time3(), send_end_call(), send_expansion_icon(), send_expansion_next(), send_expansion_text(), send_favorite(), send_icon(), send_led_update(), send_month_labels(), send_mute(), send_no_ring(), send_ping(), send_ring(), send_select_output(), send_start_rtp(), send_start_timer(), send_stop_timer(), send_text(), send_text_status(), send_texttitle(), send_tone(), and unistim_sp().

◆ send_cursor_pos()

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

Definition at line 1858 of file chan_unistim.c.

1859{
1860 BUFFSEND;
1861 if (unistimdebug) {
1862 ast_verb(0, "Sending set cursor position\n");
1863 }
1864 memcpy(buffsend + SIZE_HEADER, packet_send_set_pos_cursor,
1866 buffsend[11] = pos;
1867 send_client(SIZE_HEADER + sizeof(packet_send_set_pos_cursor), buffsend, pte);
1868 return;
1869}
static const unsigned char packet_send_set_pos_cursor[]

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

Referenced by handle_select_codec(), key_select_codec(), key_select_extension(), show_extension_page(), and show_phone_number().

◆ send_date_time()

static void send_date_time ( struct unistimsession pte)
static

Definition at line 1786 of file chan_unistim.c.

1787{
1788 BUFFSEND;
1789 struct timeval now = ast_tvnow();
1790 struct ast_tm atm = { 0, };
1791
1792 if (unistimdebug) {
1793 ast_verb(0, "Sending Time & Date\n");
1794 }
1795 memcpy(buffsend + SIZE_HEADER, packet_send_date_time, sizeof(packet_send_date_time));
1796 ast_localtime(&now, &atm, NULL);
1797 buffsend[10] = (unsigned char) atm.tm_mon + 1;
1798 buffsend[11] = (unsigned char) atm.tm_mday;
1799 buffsend[12] = (unsigned char) atm.tm_hour;
1800 buffsend[13] = (unsigned char) atm.tm_min;
1801 send_client(SIZE_HEADER + sizeof(packet_send_date_time), buffsend, pte);
1802 send_month_labels(pte, atm.tm_mon);
1803}
static void send_month_labels(struct unistimsession *pte, int month)
static const unsigned char packet_send_date_time[]
int tm_mday
Definition localtime.h:39
int tm_hour
Definition localtime.h:38
int tm_mon
Definition localtime.h:40

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

Referenced by rcv_mac_addr().

◆ send_date_time2()

static void send_date_time2 ( struct unistimsession pte)
static

Definition at line 1805 of file chan_unistim.c.

1806{
1807 BUFFSEND;
1808 struct timeval now = ast_tvnow();
1809 struct ast_tm atm = { 0, };
1810
1811 if (unistimdebug) {
1812 ast_verb(0, "Sending Time & Date #2\n");
1813 }
1814 memcpy(buffsend + SIZE_HEADER, packet_send_date_time2, sizeof(packet_send_date_time2));
1815 ast_localtime(&now, &atm, NULL);
1816 if (pte->device) {
1817 buffsend[9] = pte->device->datetimeformat;
1818 } else {
1819 buffsend[9] = 61;
1820 }
1821 buffsend[14] = (unsigned char) atm.tm_mon + 1;
1822 buffsend[15] = (unsigned char) atm.tm_mday;
1823 buffsend[16] = (unsigned char) atm.tm_hour;
1824 buffsend[17] = (unsigned char) atm.tm_min;
1825 send_client(SIZE_HEADER + sizeof(packet_send_date_time2), buffsend, pte);
1826}
static const unsigned char packet_send_date_time2[]
int tm_min
Definition localtime.h:37

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

Referenced by init_phone_step2(), and show_main_page().

◆ send_date_time3()

static void send_date_time3 ( struct unistimsession pte)
static

Definition at line 1828 of file chan_unistim.c.

1829{
1830 BUFFSEND;
1831 struct timeval now = ast_tvnow();
1832 struct ast_tm atm = { 0, };
1833
1834 if (unistimdebug) {
1835 ast_verb(0, "Sending Time & Date #3\n");
1836 }
1837 memcpy(buffsend + SIZE_HEADER, packet_send_date_time3, sizeof(packet_send_date_time3));
1838 ast_localtime(&now, &atm, NULL);
1839 buffsend[10] = (unsigned char) atm.tm_mon + 1;
1840 buffsend[11] = (unsigned char) atm.tm_mday;
1841 buffsend[12] = (unsigned char) atm.tm_hour;
1842 buffsend[13] = (unsigned char) atm.tm_min;
1843 send_client(SIZE_HEADER + sizeof(packet_send_date_time3), buffsend, pte);
1844}
static const unsigned char packet_send_date_time3[]

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

Referenced by init_phone_step2().

◆ send_dial_tone()

static void send_dial_tone ( struct unistimsession pte)
static

Definition at line 2926 of file chan_unistim.c.

2927{
2928 struct ast_tone_zone_sound *ts = NULL;
2929 struct ast_tone_zone_part tone_data;
2930 char *s = NULL;
2931 char *ind;
2932
2933 if ((ts = ast_get_indication_tone(pte->device->tz, "dial"))) {
2934 ind = ast_strdupa(ts->data);
2935 s = strsep(&ind, ",");
2936 ast_tone_zone_part_parse(s, &tone_data);
2937 send_tone(pte, tone_data.freq1, tone_data.freq2);
2938 if (unistimdebug) {
2939 ast_verb(0, "Country code found (%s), freq1=%u freq2=%u\n",
2940 pte->device->tz->country, tone_data.freq1, tone_data.freq2);
2941 }
2943 }
2944}
char * strsep(char **str, const char *delims)
int ast_tone_zone_part_parse(const char *s, struct ast_tone_zone_part *tone_data)
Parse a tone part.
A description of a part of a tone.
char country[MAX_TONEZONE_COUNTRY]
Country code that this set of tones is for.
Definition indications.h:76
struct ast_tone_zone * tz

References ast_get_indication_tone(), ast_strdupa, ast_tone_zone_part_parse(), ast_tone_zone_sound_unref(), ast_verb, ast_tone_zone::country, ast_tone_zone_sound::data, unistimsession::device, ast_tone_zone_part::freq1, ast_tone_zone_part::freq2, NULL, send_tone(), strsep(), unistim_device::tz, and unistimdebug.

Referenced by handle_dial_page().

◆ send_dtmf_tone()

static int send_dtmf_tone ( struct unistimsession pte,
char  digit 
)
static

Definition at line 3331 of file chan_unistim.c.

3332{
3333 int row, col;
3334
3335 if (unistimdebug) {
3336 ast_verb(0, "Phone Play Digit %c\n", digit);
3337 }
3338 if (pte->device->dtmfduration > 0) {
3339 row = (digit - '1') % 3;
3340 col = (digit - '1' - row) / 3;
3341 if (digit >= '1' && digit <='9') {
3342 send_tone(pte, dtmf_row[row], dtmf_col[col]);
3343 } else if (digit >= 'A' && digit <= 'D') {
3344 send_tone(pte, dtmf_row[digit-'A'], dtmf_col[3]);
3345 } else if (digit == '*') {
3346 send_tone(pte, dtmf_row[3], dtmf_col[0]);
3347 } else if (digit == '0') {
3348 send_tone(pte, dtmf_row[3], dtmf_col[1]);
3349 } else if (digit == '#') {
3350 send_tone(pte, dtmf_row[3], dtmf_col[2]);
3351 } else {
3352 send_tone(pte, 500, 2000);
3353 }
3354 }
3355 return 0;
3356}
char digit
static const float dtmf_col[]
static const int dtmf_row[]

References ast_verb, unistimsession::device, digit, dtmf_col, dtmf_row, unistim_device::dtmfduration, send_tone(), and unistimdebug.

Referenced by unistim_do_senddigit(), and unistim_senddigit_begin().

◆ send_end_call()

static void send_end_call ( struct unistimsession pte)
static

Definition at line 1082 of file chan_unistim.c.

1083{
1084 BUFFSEND;
1085 if (unistimdebug) {
1086 ast_verb(0, "Sending end call\n");
1087 }
1088 memcpy(buffsend + SIZE_HEADER, packet_send_end_call, sizeof(packet_send_end_call));
1089 send_client(SIZE_HEADER + sizeof(packet_send_end_call), buffsend, pte);
1090}
static const unsigned char packet_send_end_call[]

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

Referenced by unistim_hangup().

◆ send_expansion_icon()

static void send_expansion_icon ( unsigned char  pos,
unsigned char  status,
struct unistimsession pte 
)
static

Definition at line 1169 of file chan_unistim.c.

1170{
1171 BUFFSEND;
1172 if (unistimdebug) {
1173 ast_verb(0, "Sending expansion icon pos %d with status 0x%02hhx\n", pos, status);
1174 }
1176 buffsend[10] = pos;
1177 buffsend[11] = status;
1178 send_client(SIZE_HEADER + sizeof(packet_send_expansion_icon), buffsend, pte);
1179}
static const unsigned char packet_send_expansion_icon[]

References ast_verb, BUFFSEND, packet_send_expansion_icon, send_client(), SIZE_HEADER, status, and unistimdebug.

Referenced by send_expansion_short().

◆ send_expansion_next()

static void send_expansion_next ( struct unistimsession pte)
static

Definition at line 1161 of file chan_unistim.c.

1162{
1163 BUFFSEND;
1165 send_client(SIZE_HEADER + sizeof(packet_send_expansion_next), buffsend, pte);
1166}
static const unsigned char packet_send_expansion_next[]

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

Referenced by send_expansion_short().

◆ send_expansion_short()

static void send_expansion_short ( unsigned char  pos,
unsigned char  status,
struct unistimsession pte 
)
static

Definition at line 1308 of file chan_unistim.c.

1308 {
1309 send_expansion_icon(pos, status, pte);
1310 send_expansion_text(pos, pte, ustmtext(pte->device->expsoftkeylabel[pos], pte));
1312 return;
1313}
static void send_expansion_text(unsigned char pos, struct unistimsession *pte, const char *text)
static void send_expansion_icon(unsigned char pos, unsigned char status, struct unistimsession *pte)
static void send_expansion_next(struct unistimsession *pte)
char expsoftkeylabel[EXPNUM][11]

References unistimsession::device, unistim_device::expsoftkeylabel, send_expansion_icon(), send_expansion_next(), send_expansion_text(), status, and ustmtext().

Referenced by refresh_all_favorite().

◆ send_expansion_text()

static void send_expansion_text ( unsigned char  pos,
struct unistimsession pte,
const char *  text 
)
static

Definition at line 1182 of file chan_unistim.c.

1183{
1184 int i;
1185 BUFFSEND;
1186 if (!text) {
1187 ast_log(LOG_ERROR, "[expansion] Asked to display NULL text (pos %d)\n", pos);
1188 return;
1189 }
1190 if (unistimdebug) {
1191 ast_verb(0, "[expansion] Sending text at pos %d\n", pos);
1192 }
1194 buffsend[10] = pos;
1195 i = strlen(text);
1196 if (i > TEXT_LENGTH_MAX) {
1197 i = TEXT_LENGTH_MAX;
1198 }
1199 memcpy(buffsend + 11, text, i);
1200 send_client(SIZE_HEADER + sizeof(packet_send_expansion_text), buffsend, pte);
1201}
static const unsigned char packet_send_expansion_text[]

References ast_log, ast_verb, BUFFSEND, LOG_ERROR, packet_send_expansion_text, send_client(), SIZE_HEADER, text, TEXT_LENGTH_MAX, and unistimdebug.

Referenced by send_expansion_short().

◆ send_favorite()

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

Definition at line 1275 of file chan_unistim.c.

1277{
1278 BUFFSEND;
1279 int i;
1280
1281 if (unistimdebug) {
1282 ast_verb(0, "Sending favorite pos %d with status 0x%02hhx\n", pos, status);
1283 }
1284 memcpy(buffsend + SIZE_HEADER, packet_send_favorite, sizeof(packet_send_favorite));
1285 buffsend[10] = pos;
1286 buffsend[24] = pos;
1287 buffsend[25] = status;
1288 i = strlen(ustmtext(text, pte));
1289 if (i > FAV_MAX_LENGTH) {
1290 i = FAV_MAX_LENGTH;
1291 }
1292 memcpy(buffsend + FAV_MAX_LENGTH + 1, ustmtext(text, pte), i);
1293 send_client(SIZE_HEADER + sizeof(packet_send_favorite), buffsend, pte);
1294}
static const unsigned char packet_send_favorite[]
#define FAV_MAX_LENGTH

References ast_verb, BUFFSEND, FAV_MAX_LENGTH, packet_send_favorite, send_client(), SIZE_HEADER, status, text, unistimdebug, and ustmtext().

Referenced by change_favorite_icon(), init_phone_step2(), send_favorite_selected(), send_favorite_short(), and unistim_sendtext().

◆ send_favorite_selected()

static void send_favorite_selected ( unsigned char  status,
struct unistimsession pte 
)
static

Definition at line 1301 of file chan_unistim.c.

1301 {
1302 if (pte->device->selected != -1) {
1304 }
1305 return;
1306}

References unistimsession::device, unistim_device::selected, send_favorite(), unistim_device::softkeylabel, and status.

Referenced by handle_key_fav(), and key_dial_page().

◆ send_favorite_short()

static void send_favorite_short ( unsigned char  pos,
unsigned char  status,
struct unistimsession pte 
)
static

◆ send_icon()

static void send_icon ( unsigned char  pos,
unsigned char  status,
struct unistimsession pte 
)
static

Definition at line 1149 of file chan_unistim.c.

1150{
1151 BUFFSEND;
1152 if (unistimdebug) {
1153 ast_verb(0, "Sending icon pos %d with status 0x%02hhx\n", pos, status);
1154 }
1155 memcpy(buffsend + SIZE_HEADER, packet_send_icon, sizeof(packet_send_icon));
1156 buffsend[9] = pos;
1157 buffsend[10] = status;
1158 send_client(SIZE_HEADER + sizeof(packet_send_icon), buffsend, pte);
1159}
static const unsigned char packet_send_icon[]

References ast_verb, BUFFSEND, packet_send_icon, send_client(), SIZE_HEADER, status, and unistimdebug.

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

◆ send_idle_clock()

static void send_idle_clock ( struct unistimsession pte)
static

Definition at line 1759 of file chan_unistim.c.

1760{
1761 send_text(TEXT_LINE0, TEXT_NORMAL, pte, "");
1762}

References send_text(), TEXT_LINE0, and TEXT_NORMAL.

Referenced by show_main_page().

◆ send_led_update()

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

Definition at line 1641 of file chan_unistim.c.

1642{
1643 BUFFSEND;
1644 if (unistimdebug) {
1645 ast_verb(0, "Sending led_update (%x)\n", (unsigned)led);
1646 }
1647 memcpy(buffsend + SIZE_HEADER, packet_send_led_update, sizeof(packet_send_led_update));
1648 buffsend[9] = led;
1649 send_client(SIZE_HEADER + sizeof(packet_send_led_update), buffsend, pte);
1650}
static const unsigned char packet_send_led_update[]

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

Referenced by handle_dial_page(), init_phone_step2(), key_dial_page(), microphone_mute_toggle(), send_select_output(), show_main_page(), show_phone_number(), and unistim_send_mwi_to_peer().

◆ send_month_labels()

static void send_month_labels ( struct unistimsession pte,
int  month 
)
static

Definition at line 1764 of file chan_unistim.c.

1765{
1766 BUFFSEND;
1767 char month_name[MONTH_LABEL_SIZE + 1];
1768 int i = 0;
1769 if (unistimdebug) {
1770 ast_verb(0, "Sending Month Labels\n");
1771 }
1772 month_name[MONTH_LABEL_SIZE] = '\0';
1774 while (i < 2) {
1775 memcpy(month_name, &monthlabels[month * MONTH_LABEL_SIZE], MONTH_LABEL_SIZE);
1776 memcpy(buffsend + SIZE_HEADER + 3 + i*MONTH_LABEL_SIZE, ustmtext(month_name, pte), MONTH_LABEL_SIZE);
1777 ast_log(LOG_WARNING,"%s\n", month_name);
1778 ast_log(LOG_WARNING,"%s\n", ustmtext(month_name, pte));
1779 month = (month + 1)%12;
1780 i++;
1781 }
1783}
#define MONTH_LABEL_SIZE
static unsigned char packet_send_monthlabels_download[]
static unsigned char monthlabels[]

References ast_log, ast_verb, BUFFSEND, LOG_WARNING, MONTH_LABEL_SIZE, monthlabels, packet_send_monthlabels_download, send_client(), SIZE_HEADER, unistimdebug, and ustmtext().

Referenced by send_date_time().

◆ send_mute()

static void send_mute ( struct unistimsession pte,
unsigned char  mute 
)
static

Definition at line 1652 of file chan_unistim.c.

1653{
1654/*
1655 0x00 = unmute TX, 0x01 = mute TX
1656 0x20 = unmute RX, 0x21 = mute RX
1657*/
1658 BUFFSEND;
1659 if (unistimdebug) {
1660 ast_verb(0, "Sending mute packet (%x)\n", (unsigned)mute);
1661 }
1662 memcpy(buffsend + SIZE_HEADER, packet_send_mute, sizeof(packet_send_mute));
1663 buffsend[9] = mute;
1664 send_client(SIZE_HEADER + sizeof(packet_send_mute), buffsend, pte);
1665}
static const unsigned char packet_send_mute[]

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

Referenced by microphone_mute_toggle().

◆ send_no_ring()

static void send_no_ring ( struct unistimsession pte)
static

Definition at line 1733 of file chan_unistim.c.

1734{
1735 BUFFSEND;
1736 if (unistimdebug) {
1737 ast_verb(0, "Sending no ring packet\n");
1738 }
1739 memcpy(buffsend + SIZE_HEADER, packet_send_no_ring, sizeof(packet_send_no_ring));
1740 send_client(SIZE_HEADER + sizeof(packet_send_no_ring), buffsend, pte);
1741}
static const unsigned char packet_send_no_ring[]

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

Referenced by handle_call_incoming(), ignore_call(), init_phone_step2(), and unistim_hangup().

◆ send_ping()

static void send_ping ( struct unistimsession pte)
static

Definition at line 993 of file chan_unistim.c.

994{
995 BUFFSEND;
996 if (unistimdebug) {
997 ast_verb(0, "Sending ping\n");
998 }
1000 memcpy(buffsend + SIZE_HEADER, packet_send_ping, sizeof(packet_send_ping));
1001 send_client(SIZE_HEADER + sizeof(packet_send_ping), buffsend, pte);
1002}

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

Referenced by do_monitor(), and init_phone_step2().

◆ send_raw_client()

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

907{
908#ifdef HAVE_PKTINFO
909 struct iovec msg_iov;
910 struct msghdr msg;
911 char buffer[CMSG_SPACE(sizeof(struct in_pktinfo))];
912 struct cmsghdr *ip_msg = (struct cmsghdr *) buffer;
913 struct in_pktinfo *pki = (struct in_pktinfo *) CMSG_DATA(ip_msg);
914
915 /* cast this to a non-const pointer, since the sendmsg() API
916 * does not provide read-only and write-only flavors of the
917 * structures used for its arguments, but in this case we know
918 * the data will not be modified
919 */
920 msg_iov.iov_base = (char *) data;
921 msg_iov.iov_len = size;
922
923 msg.msg_name = addr_to; /* optional address */
924 msg.msg_namelen = sizeof(struct sockaddr_in); /* size of address */
925 msg.msg_iov = &msg_iov; /* scatter/gather array */
926 msg.msg_iovlen = 1; /* # elements in msg_iov */
927 msg.msg_control = ip_msg; /* ancillary data */
928 msg.msg_controllen = sizeof(buffer); /* ancillary data buffer len */
929 msg.msg_flags = 0; /* flags on received message */
930
931 ip_msg->cmsg_len = CMSG_LEN(sizeof(*pki));
932 ip_msg->cmsg_level = IPPROTO_IP;
933 ip_msg->cmsg_type = IP_PKTINFO;
934 pki->ipi_ifindex = 0; /* Interface index, 0 = use interface specified in routing table */
935 pki->ipi_spec_dst.s_addr = addr_ourip->sin_addr.s_addr; /* Local address */
936 /* pki->ipi_addr = ; Header Destination address - ignored by kernel */
937
938#ifdef DUMP_PACKET
939 if (unistimdebug) {
940 int tmp;
941 ast_verb(0, "\n**> From %s sending %d bytes to %s ***\n",
942 ast_inet_ntoa(addr_ourip->sin_addr), (int) size,
943 ast_inet_ntoa(addr_to->sin_addr));
944 for (tmp = 0; tmp < size; tmp++)
945 ast_verb(0, "%02hhx ", data[tmp]);
946 ast_verb(0, "\n******************************************\n");
947
948 }
949#endif
950
951 if (sendmsg(unistimsock, &msg, 0) == -1) {
952 display_last_error("Error sending data");
953 }
954#else
955 if (sendto(unistimsock, data, size, 0, (struct sockaddr *) addr_to, sizeof(*addr_to))
956 == -1)
957 display_last_error("Error sending data");
958#endif
959}

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

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

◆ send_retransmit()

static int send_retransmit ( struct unistimsession pte)
static

Definition at line 1540 of file chan_unistim.c.

1541{
1542 int i;
1543
1544 ast_mutex_lock(&pte->lock);
1545 if (++pte->nb_retransmit >= NB_MAX_RETRANSMIT) {
1546 if (unistimdebug) {
1547 ast_verb(0, "Too many retransmit - freeing client\n");
1548 }
1549 ast_mutex_unlock(&pte->lock);
1550 close_client(pte);
1551 return 1;
1552 }
1554
1555 for (i = pte->last_buf_available - (pte->seq_server - pte->last_seq_ack);
1556 i < pte->last_buf_available; i++) {
1557 if (i < 0) {
1559 "Asked to retransmit an ACKed slot ! last_buf_available=%d, seq_server = #0x%04x last_seq_ack = #0x%04x\n",
1560 pte->last_buf_available, (unsigned)pte->seq_server, (unsigned)pte->last_seq_ack);
1561 continue;
1562 }
1563
1564 if (unistimdebug) {
1565 unsigned short *sbuf = (unsigned short *) pte->wsabufsend[i].buf;
1566 unsigned short seq;
1567
1568 seq = ntohs(sbuf[1]);
1569 ast_verb(0, "Retransmit slot #%d (seq=#0x%04x), last ack was #0x%04x\n", i,
1570 (unsigned)seq, (unsigned)pte->last_seq_ack);
1571 }
1572 send_raw_client(pte->wsabufsend[i].len, pte->wsabufsend[i].buf, &pte->sin,
1573 &pte->sout);
1574 }
1575 ast_mutex_unlock(&pte->lock);
1576 return 0;
1577}

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

Referenced by do_monitor(), and parsing().

◆ send_ring()

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

Definition at line 1721 of file chan_unistim.c.

1722{
1723 BUFFSEND;
1724 if (unistimdebug) {
1725 ast_verb(0, "Sending ring packet\n");
1726 }
1727 memcpy(buffsend + SIZE_HEADER, packet_send_ring, sizeof(packet_send_ring));
1728 buffsend[24] = style + 0x10;
1729 buffsend[29] = volume * 0x10;
1730 send_client(SIZE_HEADER + sizeof(packet_send_ring), buffsend, pte);
1731}
static const unsigned char packet_send_ring[]

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

Referenced by unistim_call().

◆ send_select_output()

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

Definition at line 1672 of file chan_unistim.c.

1674{
1675 BUFFSEND;
1676 int mute_icon = -1;
1677 if (unistimdebug) {
1678 ast_verb(0, "Sending select output packet output=%x volume=%x mute=%x\n",
1679 (unsigned)output, (unsigned)volume, (unsigned)mute);
1680 }
1681 memcpy(buffsend + SIZE_HEADER, packet_send_select_output,
1683 buffsend[9] = output;
1684 if (output == OUTPUT_SPEAKER && volume == VOLUME_LOW) {
1686 }
1687 buffsend[10] = volume;
1688 if (mute == MUTE_ON_DISCRET) {
1689 buffsend[11] = MUTE_ON;
1690 } else {
1691 buffsend[11] = mute;
1692 }
1693 send_client(SIZE_HEADER + sizeof(packet_send_select_output), buffsend, pte);
1694 if (output == OUTPUT_HANDSET) {
1695 mute_icon = (mute == MUTE_ON) ? FAV_ICON_ONHOLD_BLACK : FAV_ICON_OFFHOOK_BLACK;
1698 } else if (output == OUTPUT_HEADPHONE) {
1702 } else if (output == OUTPUT_SPEAKER) {
1705 if (pte->device->receiver_state == STATE_OFFHOOK) {
1707 } else {
1709 }
1710 } else {
1711 ast_log(LOG_WARNING, "Invalid output (%d)\n", output);
1712 }
1713 if (mute_icon != -1) {
1714 change_favorite_icon(pte, mute_icon);
1715 }
1716 if (output != pte->device->output) {
1717 pte->device->previous_output = pte->device->output;
1718 }
1719 pte->device->output = output;
1720}
#define MUTE_ON_DISCRET
#define LED_SPEAKER_ON
#define LED_HEADPHONE_ON
#define FAV_ICON_SPEAKER_ONHOOK_BLACK
#define FAV_ICON_SPEAKER_ONHOLD_BLACK
#define FAV_ICON_HEADPHONES
#define FAV_ICON_SPEAKER_OFFHOOK_BLACK
#define VOLUME_LOW_SPEAKER
#define FAV_ICON_HEADPHONES_ONHOLD
#define FAV_ICON_ONHOLD_BLACK
static const unsigned char packet_send_select_output[]

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, LED_HEADPHONE_OFF, LED_HEADPHONE_ON, LED_SPEAKER_OFF, LED_SPEAKER_ON, LOG_WARNING, MUTE_ON, MUTE_ON_DISCRET, unistim_device::output, OUTPUT_HANDSET, OUTPUT_HEADPHONE, OUTPUT_SPEAKER, packet_send_select_output, unistim_device::previous_output, unistim_device::receiver_state, send_client(), send_led_update(), SIZE_HEADER, STATE_OFFHOOK, unistimdebug, VOLUME_LOW, and VOLUME_LOW_SPEAKER.

Referenced by handle_call_incoming(), handle_call_outgoing(), handle_dial_page(), handle_key_fav(), key_call(), key_dial_page(), key_main_page(), process_request(), show_main_page(), sub_hold(), and sub_unhold().

◆ send_start_rtp()

static void send_start_rtp ( struct unistim_subchannel sub)
static

Definition at line 2712 of file chan_unistim.c.

2713{
2714 BUFFSEND;
2715
2716 int codec;
2717 struct sockaddr_in public = { 0, };
2718 struct sockaddr_in us = { 0, };
2719 struct sockaddr_in sin = { 0, };
2720 struct ast_sockaddr us_tmp;
2721 struct ast_sockaddr sin_tmp;
2722 struct unistimsession *pte;
2723
2725 ast_sockaddr_to_sin(&us_tmp, &us);
2727 ast_sockaddr_to_sin(&sin_tmp, &sin);
2728
2729 /* Setting up RTP of the phone */
2730 if (public_ip.sin_family == 0) { /* NAT IP override ? */
2731 memcpy(&public, &us, sizeof(public)); /* No defined, using IP from recvmsg */
2732 } else {
2733 memcpy(&public, &public_ip, sizeof(public)); /* override */
2734 }
2735 if (unistimdebug) {
2736 ast_verb(0, "RTP started : Our IP/port is : %s:%hd with codec %s\n",
2737 ast_inet_ntoa(us.sin_addr),
2738 htons(us.sin_port), ast_format_get_name(ast_channel_readformat(sub->owner)));
2739 ast_verb(0, "Starting phone RTP stack. Our public IP is %s\n",
2740 ast_inet_ntoa(public.sin_addr));
2741 }
2742
2743 pte = sub->parent->parent->session;
2745 1, ast_channel_readformat(sub->owner), 0);
2748 if (unistimdebug) {
2749 ast_verb(0, "Sending packet_send_rtp_packet_size for codec %d\n", codec);
2750 }
2751 memcpy(buffsend + SIZE_HEADER, packet_send_rtp_packet_size,
2753 buffsend[10] = (int) codec & 0xffffffffLL;
2754 send_client(SIZE_HEADER + sizeof(packet_send_rtp_packet_size), buffsend, pte);
2755 }
2756 if (unistimdebug) {
2757 ast_verb(0, "Sending Jitter Buffer Parameters Configuration\n");
2758 }
2761 send_client(SIZE_HEADER + sizeof(packet_send_jitter_buffer_conf), buffsend, pte);
2762 if (pte->device->rtp_method != 0) {
2763 uint16_t rtcpsin_port = ntohs(us.sin_port) + 1; /* RTCP port is RTP + 1 */
2764
2765 if (unistimdebug) {
2766 ast_verb(0, "Sending OpenAudioStreamTX using method #%d\n", pte->device->rtp_method);
2767 }
2768 if (pte->device->rtp_method == 3) {
2771 } else {
2774 }
2775 if (pte->device->rtp_method != 2) {
2776 memcpy(buffsend + 28, &public.sin_addr, sizeof(public.sin_addr));
2777 put_unaligned_uint16(&buffsend[20], sin.sin_port);
2778 put_unaligned_uint16(&buffsend[22], htons(rtcpsin_port));
2779 put_unaligned_uint16(&buffsend[24], us.sin_port);
2780 put_unaligned_uint16(&buffsend[26], htons(rtcpsin_port));
2781 } else {
2782 memcpy(buffsend + 23, &public.sin_addr, sizeof(public.sin_addr));
2783 put_unaligned_uint16(&buffsend[15], sin.sin_port);
2784 put_unaligned_uint16(&buffsend[19], us.sin_port);
2785 }
2786 buffsend[11] = codec; /* rx */
2787 buffsend[12] = codec; /* tx */
2789
2790 if (unistimdebug) {
2791 ast_verb(0, "Sending OpenAudioStreamRX\n");
2792 }
2793 if (pte->device->rtp_method == 3) {
2796 } else {
2799 }
2800 if (pte->device->rtp_method != 2) {
2801 memcpy(buffsend + 28, &public.sin_addr, sizeof(public.sin_addr));
2802 put_unaligned_uint16(&buffsend[20], sin.sin_port);
2803 put_unaligned_uint16(&buffsend[22], htons(rtcpsin_port));
2804 put_unaligned_uint16(&buffsend[24], us.sin_port);
2805 put_unaligned_uint16(&buffsend[26], htons(rtcpsin_port));
2806 } else {
2807 memcpy(buffsend + 23, &public.sin_addr, sizeof(public.sin_addr));
2808 put_unaligned_uint16(&buffsend[15], sin.sin_port);
2809 put_unaligned_uint16(&buffsend[19], us.sin_port);
2810 }
2811 buffsend[11] = codec; /* rx */
2812 buffsend[12] = codec; /* tx */
2814 } else {
2815 uint16_t rtcpsin_port = htons(us.sin_port) + 1; /* RTCP port is RTP + 1 */
2816
2817 if (unistimdebug) {
2818 ast_verb(0, "Sending packet_send_call default method\n");
2819 }
2820
2821 memcpy(buffsend + SIZE_HEADER, packet_send_call, sizeof(packet_send_call));
2822 memcpy(buffsend + 53, &public.sin_addr, sizeof(public.sin_addr));
2823 /* Destination port when sending RTP */
2824 put_unaligned_uint16(&buffsend[49], us.sin_port);
2825 /* Destination port when sending RTCP */
2826 put_unaligned_uint16(&buffsend[51], htons(rtcpsin_port));
2827 /* Codec */
2828 buffsend[40] = codec;
2829 buffsend[41] = codec;
2831 buffsend[42] = 1; /* 1 = 20ms (160 bytes), 2 = 40ms (320 bytes) */
2833 buffsend[42] = 1; /* 1 = 20ms (160 bytes), 2 = 40ms (320 bytes) */
2835 buffsend[42] = 2; /* 1 = 30ms (24 bytes), 2 = 60 ms (48 bytes) */
2837 buffsend[42] = 2; /* 1 = 10ms (10 bytes), 2 = 20ms (20 bytes) */
2838 } else {
2839 ast_log(LOG_WARNING, "Unsupported codec %s!\n",
2841 }
2842 /* Source port for transmit RTP and Destination port for receiving RTP */
2843 put_unaligned_uint16(&buffsend[45], sin.sin_port);
2844 put_unaligned_uint16(&buffsend[47], htons(rtcpsin_port));
2845 send_client(SIZE_HEADER + sizeof(packet_send_call), buffsend, pte);
2846 }
2847}
static const unsigned char packet_send_call[]
static const unsigned char packet_send_open_audio_stream_tx[]
static const unsigned char packet_send_open_audio_stream_tx3[]
static const unsigned char packet_send_rtp_packet_size[]
static const unsigned char packet_send_jitter_buffer_conf[]
static const unsigned char packet_send_open_audio_stream_rx3[]
static const unsigned char packet_send_open_audio_stream_rx[]
struct ast_format * ast_channel_readformat(struct ast_channel *chan)
enum ast_format_cmp_res ast_format_cmp(const struct ast_format *format1, const struct ast_format *format2)
Compare two formats.
Definition format.c:201
@ AST_FORMAT_CMP_EQUAL
Definition format.h:36
const char * ast_format_get_name(const struct ast_format *format)
Get the name associated with a format.
Definition format.c:334
struct ast_format * ast_format_g723
Built-in cached g723.1 format.
struct ast_format * ast_format_g729
Built-in cached g729 format.
void ast_rtp_instance_get_local_address(struct ast_rtp_instance *instance, struct ast_sockaddr *address)
Get the local address that we are expecting RTP on.
Definition rtp_engine.c:694
int ast_rtp_codecs_payload_code_tx(struct ast_rtp_codecs *codecs, int asterisk_format, const struct ast_format *format, int code)
Retrieve a tx mapped payload type based on whether it is an Asterisk format and the code.
struct ast_rtp_codecs * ast_rtp_instance_get_codecs(struct ast_rtp_instance *instance)
Get the codecs structure of an RTP instance.
Definition rtp_engine.c:778
static void put_unaligned_uint16(void *p, unsigned short datum)
Definition unaligned.h:65

References ast_channel_readformat(), ast_format_alaw, ast_format_cmp(), AST_FORMAT_CMP_EQUAL, ast_format_g723, ast_format_g729, ast_format_get_name(), ast_format_ulaw, ast_inet_ntoa(), ast_log, ast_rtp_codecs_payload_code_tx(), ast_rtp_instance_get_codecs(), ast_rtp_instance_get_local_address(), ast_rtp_instance_get_remote_address, ast_sockaddr_to_sin, ast_verb, BUFFSEND, unistimsession::device, LOG_WARNING, packet_send_call, packet_send_jitter_buffer_conf, packet_send_open_audio_stream_rx, packet_send_open_audio_stream_rx3, packet_send_open_audio_stream_tx, packet_send_open_audio_stream_tx3, packet_send_rtp_packet_size, public_ip, put_unaligned_uint16(), unistim_device::rtp_method, send_client(), unistimsession::sin, SIZE_HEADER, sub, and unistimdebug.

Referenced by start_rtp(), and sub_unhold().

◆ send_start_timer()

static void send_start_timer ( struct unistimsession pte)
static

Definition at line 1129 of file chan_unistim.c.

1130{
1131 BUFFSEND;
1132 if (unistimdebug) {
1133 ast_verb(0, "Sending start timer\n");
1134 }
1135 memcpy(buffsend + SIZE_HEADER, packet_send_start_timer, sizeof(packet_send_start_timer));
1136 send_client(SIZE_HEADER + sizeof(packet_send_start_timer), buffsend, pte);
1137}
static const unsigned char packet_send_start_timer[]

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

Referenced by handle_call_incoming(), handle_call_outgoing(), sub_unhold(), and unistim_answer().

◆ send_stop_timer()

static void send_stop_timer ( struct unistimsession pte)
static

Definition at line 1139 of file chan_unistim.c.

1140{
1141 BUFFSEND;
1142 if (unistimdebug) {
1143 ast_verb(0, "Sending stop timer\n");
1144 }
1145 memcpy(buffsend + SIZE_HEADER, packet_send_stop_timer, sizeof(packet_send_stop_timer));
1146 send_client(SIZE_HEADER + sizeof(packet_send_stop_timer), buffsend, pte);
1147}
static const unsigned char packet_send_stop_timer[]

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

Referenced by close_call(), handle_key_fav(), show_main_page(), and sub_hold().

◆ send_text()

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

Definition at line 1580 of file chan_unistim.c.

1582{
1583 int i;
1584 BUFFSEND;
1585 if (!text) {
1586 ast_log(LOG_ERROR, "Asked to display NULL text (pos %d, inverse flag %d)\n", pos, inverse);
1587 return;
1588 }
1589 if (pte->device && pte->device->height == 1 && pos != TEXT_LINE0) {
1590 return;
1591 }
1592 if (unistimdebug) {
1593 ast_verb(0, "Sending text at pos %d, inverse flag %d\n", pos, inverse);
1594 }
1595 memcpy(buffsend + SIZE_HEADER, packet_send_text, sizeof(packet_send_text));
1596 buffsend[10] = pos;
1597 buffsend[11] = inverse;
1598 i = strlen(text);
1599 if (i > TEXT_LENGTH_MAX) {
1600 i = TEXT_LENGTH_MAX;
1601 }
1602 memcpy(buffsend + 12, text, i);
1603 send_client(SIZE_HEADER + sizeof(packet_send_text), buffsend, pte);
1604}
static const unsigned char packet_send_text[]

References ast_log, ast_verb, BUFFSEND, unistimsession::device, unistim_device::height, LOG_ERROR, packet_send_text, send_client(), SIZE_HEADER, text, TEXT_LENGTH_MAX, TEXT_LINE0, and unistimdebug.

Referenced by ast_sendtext_data(), handle_call_incoming(), handle_call_outgoing(), handle_dial_page(), handle_select_codec(), handle_select_language(), handle_select_option(), init_phone_step2(), key_select_codec(), key_select_extension(), send_callerid_screen(), send_idle_clock(), sendtext_exec(), show_entry_history(), show_extension_page(), show_main_page(), show_phone_number(), unistim_answer(), unistim_call(), unistim_hangup(), unistim_indicate(), and unistim_sendtext().

◆ send_text_status()

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

Definition at line 1606 of file chan_unistim.c.

1607{
1608 BUFFSEND;
1609 int i;
1610 if (unistimdebug) {
1611 ast_verb(0, "Sending status text\n");
1612 }
1613 if (pte->device) {
1614 if (pte->device->status_method == 1) { /* For new firmware and i2050 soft phone */
1615 int n = strlen(text);
1616 /* Must send individual button separately */
1617 int j;
1618 for (i = 0, j = 0; i < 4; i++, j += 7) {
1619 int pos = 0x08 + (i * 0x20);
1620 memcpy(buffsend + SIZE_HEADER, packet_send_status2,
1621 sizeof(packet_send_status2));
1622
1623 buffsend[9] = pos;
1624 memcpy(buffsend + 10, (j < n) ? (text + j) : " ", 7);
1625 send_client(SIZE_HEADER + sizeof(packet_send_status2), buffsend, pte);
1626 }
1627 return;
1628 }
1629 }
1630
1631 memcpy(buffsend + SIZE_HEADER, packet_send_status, sizeof(packet_send_status));
1632 i = strlen(text);
1633 if (i > STATUS_LENGTH_MAX) {
1635 }
1636 memcpy(buffsend + 10, text, i);
1637 send_client(SIZE_HEADER + sizeof(packet_send_status), buffsend, pte);
1638
1639}
#define STATUS_LENGTH_MAX
static const unsigned char packet_send_status[]
static const unsigned char packet_send_status2[]

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

Referenced by handle_call_incoming(), handle_call_outgoing(), handle_dial_page(), handle_select_codec(), handle_select_language(), handle_select_option(), init_phone_step2(), key_dial_page(), show_entry_history(), show_extension_page(), show_main_page(), unistim_answer(), unistim_call(), and unistim_hangup().

◆ send_texttitle()

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

Definition at line 1743 of file chan_unistim.c.

1744{
1745 BUFFSEND;
1746 int i;
1747 if (unistimdebug) {
1748 ast_verb(0, "Sending title text\n");
1749 }
1750 memcpy(buffsend + SIZE_HEADER, packet_send_title, sizeof(packet_send_title));
1751 i = strlen(text);
1752 if (i > 12) {
1753 i = 12;
1754 }
1755 memcpy(buffsend + 10, text, i);
1756 send_client(SIZE_HEADER + sizeof(packet_send_title), buffsend, pte);
1757}
static const unsigned char packet_send_title[]

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

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

◆ send_tone()

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

Definition at line 1203 of file chan_unistim.c.

1204{
1205 BUFFSEND;
1206 if (!tone1) {
1207 if (unistimdebug) {
1208 ast_verb(0, "Sending Stream Based Tone Off\n");
1209 }
1213 return;
1214 }
1215 /* Since most of the world use a continuous tone, it's useless
1216 if (unistimdebug)
1217 ast_verb(0, "Sending Stream Based Tone Cadence Download\n");
1218 memcpy (buffsend + SIZE_HEADER, packet_send_StreamBasedToneCad, sizeof (packet_send_StreamBasedToneCad));
1219 send_client (SIZE_HEADER + sizeof (packet_send_StreamBasedToneCad), buffsend, pte); */
1220 if (unistimdebug) {
1221 ast_verb(0, "Sending Stream Based Tone Frequency Component List Download %d %d\n", tone1, tone2);
1222 }
1223 tone1 *= 8;
1224 if (!tone2) {
1227 put_unaligned_uint16(&buffsend[10], htons(tone1));
1229 pte);
1230 } else {
1231 tone2 *= 8;
1234 put_unaligned_uint16(&buffsend[10], htons(tone1));
1235 put_unaligned_uint16(&buffsend[12], htons(tone2));
1237 pte);
1238 }
1239
1240 if (unistimdebug) {
1241 ast_verb(0, "Sending Stream Based Tone On\n");
1242 }
1246}
static const unsigned char packet_send_stream_based_tone_on[]
static const unsigned char packet_send_stream_based_tone_dual_freq[]
static const unsigned char packet_send_stream_based_tone_single_freq[]
static const unsigned char packet_send_stream_based_tone_off[]

References ast_verb, BUFFSEND, packet_send_stream_based_tone_dual_freq, packet_send_stream_based_tone_off, packet_send_stream_based_tone_on, packet_send_stream_based_tone_single_freq, put_unaligned_uint16(), send_client(), SIZE_HEADER, and unistimdebug.

Referenced by handle_call_outgoing(), handle_key_fav(), key_dial_page(), send_dial_tone(), send_dtmf_tone(), show_main_page(), unistim_do_senddigit(), unistim_senddigit_end(), and unistim_ss().

◆ set_ping_timer()

static void set_ping_timer ( struct unistimsession pte)
static

Definition at line 1092 of file chan_unistim.c.

1093{
1094 unsigned int tick = 0; /* XXX what is this for, anyways */
1095
1096 pte->timeout = pte->tick_next_ping;
1097 DEBUG_TIMER("tick = %u next ping at %u tick\n", tick, pte->timeout);
1098 return;
1099}

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

Referenced by check_send_queue().

◆ show_entry_history()

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

Definition at line 3992 of file chan_unistim.c.

3993{
3994 char line[TEXT_LENGTH_MAX + 1], status[STATUS_LENGTH_MAX + 1], func1[10], func2[10],
3995 func3[10];
3996
3997 /* Display date/time and call status */
3998 if (fread(line, TEXT_LENGTH_MAX, 1, *f) != 1) {
3999 display_last_error("Can't read history date entry");
4000 fclose(*f);
4001 return;
4002 }
4003 line[sizeof(line) - 1] = '\0';
4004 if (pte->device->height == 1) {
4005 if (pte->buff_entry[3] == 1) {
4006 send_text(TEXT_LINE0, TEXT_NORMAL, pte, line);
4007 }
4008 } else {
4009 send_text(TEXT_LINE0, TEXT_NORMAL, pte, line);
4010 }
4011 /* Display number */
4012 if (fread(line, TEXT_LENGTH_MAX, 1, *f) != 1) {
4013 display_last_error("Can't read callerid entry");
4014 fclose(*f);
4015 return;
4016 }
4017 line[sizeof(line) - 1] = '\0';
4018 ast_copy_string(pte->device->lst_cid, line, sizeof(pte->device->lst_cid));
4020 if (pte->device->height == 1) {
4021 if (pte->buff_entry[3] == 2) {
4022 send_text(TEXT_LINE0, TEXT_NORMAL, pte, line);
4023 }
4024 } else {
4025 send_text(TEXT_LINE1, TEXT_NORMAL, pte, line);
4026 }
4027 /* Display name */
4028 if (fread(line, TEXT_LENGTH_MAX, 1, *f) != 1) {
4029 display_last_error("Can't read callername entry");
4030 fclose(*f);
4031 return;
4032 }
4033 line[sizeof(line) - 1] = '\0';
4034 if (pte->device->height == 1) {
4035 if (pte->buff_entry[3] == 3) {
4036 send_text(TEXT_LINE0, TEXT_NORMAL, pte, line);
4037 }
4038 } else {
4039 send_text(TEXT_LINE2, TEXT_NORMAL, pte, line);
4040 }
4041 fclose(*f);
4042
4043 snprintf(line, sizeof(line), "%s %03d/%03d", ustmtext("Call", pte), pte->buff_entry[2],
4044 pte->buff_entry[1]);
4045 send_texttitle(pte, line);
4046
4047 if (pte->buff_entry[2] == 1) {
4048 ast_copy_string(func1, " ", sizeof(func1));
4049 } else {
4050 ast_copy_string(func1, ustmtext("Prev ", pte), sizeof(func1));
4051 }
4052 if (pte->buff_entry[2] >= pte->buff_entry[1]) {
4053 ast_copy_string(func2, " ", sizeof(func2));
4054 } else {
4055 ast_copy_string(func2, ustmtext("Next ", pte), sizeof(func2));
4056 }
4057 if (strlen(pte->device->lst_cid)) {
4058 ast_copy_string(func3, ustmtext("Redial ", pte), sizeof(func3));
4059 } else {
4060 ast_copy_string(func3, " ", sizeof(func3));
4061 }
4062 snprintf(status, sizeof(status), "%s%s%s%s", func1, func2, func3, ustmtext("Cancel", pte));
4064}
char * ast_trim_blanks(char *str)
Trims trailing whitespace characters from a string.
Definition strings.h:186

References ast_copy_string(), ast_trim_blanks(), unistimsession::buff_entry, unistimsession::device, display_last_error(), unistim_device::height, unistim_device::lst_cid, send_text(), send_text_status(), send_texttitle(), status, STATUS_LENGTH_MAX, TEXT_LENGTH_MAX, TEXT_LINE0, TEXT_LINE1, TEXT_LINE2, TEXT_NORMAL, and ustmtext().

Referenced by key_history(), and show_history().

◆ show_extension_page()

static void show_extension_page ( struct unistimsession pte)
static

◆ show_history()

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

Definition at line 4094 of file chan_unistim.c.

4095{
4096 FILE *f;
4097 char count;
4098
4099 if (!pte->device) {
4100 return;
4101 }
4102 if (!pte->device->callhistory) {
4103 return;
4104 }
4105 count = open_history(pte, way, &f);
4106 if (!count) {
4107 return;
4108 }
4109 pte->buff_entry[0] = way;
4110 pte->buff_entry[1] = count;
4111 pte->buff_entry[2] = 1;
4112 pte->buff_entry[3] = 1;
4113 show_entry_history(pte, &f);
4114 pte->state = STATE_HISTORY;
4115}

References unistimsession::buff_entry, unistim_device::callhistory, unistimsession::device, open_history(), show_entry_history(), unistimsession::state, and STATE_HISTORY.

Referenced by key_history(), and key_main_page().

◆ show_main_page()

static void show_main_page ( struct unistimsession pte)
static

Definition at line 4117 of file chan_unistim.c.

4118{
4119 char tmpbuf[TEXT_LENGTH_MAX + 1];
4120 const char *text;
4121
4122 if ((pte->device->extension == EXTENSION_ASK) &&
4125 return;
4126 }
4127
4128 pte->state = STATE_MAINPAGE;
4130 pte->device->lastmsgssent = -1;
4131
4132 send_tone(pte, 0, 0);
4133 send_stop_timer(pte); /* case of holding call */
4137
4138 if (!ast_strlen_zero(pte->device->call_forward)) {
4139 if (pte->device->height == 1) {
4140 char tmp_field[100];
4141 snprintf(tmp_field, sizeof(tmp_field), "%s %s", ustmtext("Fwd to:", pte), pte->device->call_forward);
4142 send_text(TEXT_LINE0, TEXT_NORMAL, pte, tmp_field);
4143 } else {
4144 send_text(TEXT_LINE0, TEXT_NORMAL, pte, ustmtext("Call forwarded to :", pte));
4146 }
4149 send_text_status(pte, ustmtext("Dial NoFwd ", pte));
4150 } else {
4151 send_text_status(pte, ustmtext("Dial Redial NoFwd ", pte));
4152 }
4153 } else {
4154 if ((pte->device->extension == EXTENSION_ASK) || (pte->device->extension == EXTENSION_TN)) {
4156 send_text_status(pte, ustmtext("Dial Fwd Unregis", pte));
4157 } else {
4158 send_text_status(pte, ustmtext("Dial Redial Fwd Unregis", pte));
4159 }
4160 } else {
4162 send_text_status(pte, ustmtext("Dial Fwd Pickup", pte));
4163 } else {
4164 send_text_status(pte, ustmtext("Dial Redial Fwd Pickup", pte));
4165 }
4166 }
4168 if (pte->device->missed_call == 0) {
4169 send_date_time2(pte);
4170 send_idle_clock(pte);
4171 if (strlen(pte->device->maintext0)) {
4173 }
4174 } else {
4175 if (pte->device->missed_call == 1) {
4176 text = ustmtext("unanswered call", pte);
4177 } else {
4178 text = ustmtext("unanswered calls", pte);
4179 }
4180 snprintf(tmpbuf, sizeof(tmpbuf), "%d %s", pte->device->missed_call, text);
4181 send_text(TEXT_LINE0, TEXT_NORMAL, pte, tmpbuf);
4183 }
4184 }
4185 if (pte->device->height > 1) {
4186 if (ast_strlen_zero(pte->device->maintext2)) {
4187 strcpy(tmpbuf, "IP : ");
4188 strcat(tmpbuf, ast_inet_ntoa(pte->sin.sin_addr));
4189 send_text(TEXT_LINE2, TEXT_NORMAL, pte, tmpbuf);
4190 } else {
4192 }
4193 }
4194
4195 send_texttitle(pte, ustmtext(pte->device->titledefault, pte));
4197}
char * text
Definition app_queue.c:1791
#define FAV_BLINK_SLOW
static void send_idle_clock(struct unistimsession *pte)
#define FAV_ICON_REFLECT
#define FAV_ICON_CALL_CENTER
char maintext2[25]
char maintext1[25]
char titledefault[13]
char maintext0[25]

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_REFLECT, FAV_LINE_ICON, unistim_device::height, unistim_device::lastmsgssent, LED_BAR_OFF, LED_HEADPHONE_OFF, LED_SPEAKER_OFF, unistim_device::maintext0, unistim_device::maintext1, unistim_device::maintext2, unistim_device::missed_call, MUTE_ON_DISCRET, unistim_device::output, unistim_device::redial_number, send_date_time2(), send_icon(), send_idle_clock(), send_led_update(), send_select_output(), send_stop_timer(), send_text(), send_text_status(), send_texttitle(), send_tone(), show_extension_page(), unistimsession::sin, unistimsession::state, STATE_MAINPAGE, text, TEXT_LENGTH_MAX, TEXT_LINE0, TEXT_LINE1, TEXT_LINE2, TEXT_NORMAL, unistim_device::titledefault, ustmtext(), and unistim_device::volume.

Referenced by close_call(), handle_key_fav(), init_phone_step2(), key_dial_page(), key_history(), key_main_page(), key_select_codec(), key_select_extension(), key_select_language(), key_select_option(), process_request(), and unistim_hangup().

◆ show_phone_number()

static void show_phone_number ( struct unistimsession pte)
static

Definition at line 2946 of file chan_unistim.c.

2947{
2948 char tmp[TEXT_LENGTH_MAX + 1];
2949 const char *tmp_number = ustmtext("Number:", pte);
2950 int line, tmp_copy, offset = 0, i;
2951
2952 pte->device->phone_number[pte->device->size_phone_number] = '\0';
2954 offset = pte->device->size_phone_number - MAX_SCREEN_NUMBER - 1;
2955 if (offset > strlen(tmp_number)) {
2956 offset = strlen(tmp_number);
2957 }
2958 tmp_copy = strlen(tmp_number) - offset + 1;
2959 if (tmp_copy > sizeof(tmp)) {
2960 tmp_copy = sizeof(tmp);
2961 }
2962 memcpy(tmp, tmp_number + offset, tmp_copy);
2963 } else {
2964 ast_copy_string(tmp, tmp_number, sizeof(tmp));
2965 }
2966
2967 offset = (pte->device->size_phone_number >= TEXT_LENGTH_MAX) ? (pte->device->size_phone_number - TEXT_LENGTH_MAX +1) : 0;
2968 if (pte->device->size_phone_number) {
2969 memcpy(tmp + strlen(tmp), pte->device->phone_number + offset, pte->device->size_phone_number - offset + 1);
2970 }
2971 offset = strlen(tmp);
2972
2973 for (i = strlen(tmp); i < TEXT_LENGTH_MAX; i++) {
2974 tmp[i] = '.';
2975 }
2976 tmp[i] = '\0';
2977
2978 line = (pte->device->height == 1) ? TEXT_LINE0 : TEXT_LINE2;
2979 send_text(line, TEXT_NORMAL, pte, tmp);
2980 send_blink_cursor(pte);
2981 send_cursor_pos(pte, (unsigned char) (line + offset));
2983}
#define MAX_SCREEN_NUMBER

References ast_copy_string(), unistimsession::device, unistim_device::height, LED_BAR_OFF, MAX_SCREEN_NUMBER, unistim_device::phone_number, send_blink_cursor(), send_cursor_pos(), send_led_update(), send_text(), unistim_device::size_phone_number, TEXT_LENGTH_MAX, TEXT_LINE0, TEXT_LINE2, TEXT_NORMAL, and ustmtext().

Referenced by handle_dial_page(), and key_dial_page().

◆ soft_key_visible()

static int soft_key_visible ( struct unistim_device d,
unsigned char  num 
)
static

Definition at line 1315 of file chan_unistim.c.

1316{
1317 if(d->height == 1 && num % 3 == 2) {
1318 return 0;
1319 }
1320 return 1;
1321}

References d.

Referenced by get_avail_softkey(), refresh_all_favorite(), unistim_call(), unistim_hangup(), and unistim_show_info().

◆ start_rtp()

static void start_rtp ( struct unistim_subchannel sub)
static

Definition at line 2849 of file chan_unistim.c.

2850{
2851 struct sockaddr_in sin = { 0, };
2852 struct sockaddr_in sout = { 0, };
2853 struct ast_sockaddr sin_tmp;
2854 struct ast_sockaddr sout_tmp;
2855
2856 /* Sanity checks */
2857 if (!sub) {
2858 ast_log(LOG_WARNING, "start_rtp with a null subchannel !\n");
2859 return;
2860 }
2861 if (!sub->parent) {
2862 ast_log(LOG_WARNING, "start_rtp with a null line!\n");
2863 return;
2864 }
2865 if (!sub->parent->parent) {
2866 ast_log(LOG_WARNING, "start_rtp with a null device!\n");
2867 return;
2868 }
2869 if (!sub->parent->parent->session) {
2870 ast_log(LOG_WARNING, "start_rtp with a null session!\n");
2871 return;
2872 }
2873 if (!sub->owner) {
2874 ast_log(LOG_WARNING, "start_rtp with a null asterisk channel!\n");
2875 return;
2876 }
2877 sout = sub->parent->parent->session->sout;
2878 ast_mutex_lock(&sub->lock);
2879 /* Allocate the RTP */
2880 if (unistimdebug) {
2881 ast_verb(0, "Starting RTP. Bind on %s\n", ast_inet_ntoa(sout.sin_addr));
2882 }
2883 ast_sockaddr_from_sin(&sout_tmp, &sout);
2884 sub->rtp = ast_rtp_instance_new("asterisk", sched, &sout_tmp, NULL);
2885 if (!sub->rtp) {
2886 ast_log(LOG_WARNING, "Unable to create RTP session: %s binaddr=%s\n",
2887 strerror(errno), ast_inet_ntoa(sout.sin_addr));
2888 ast_mutex_unlock(&sub->lock);
2889 return;
2890 }
2895 ast_rtp_instance_set_qos(sub->rtp, qos.tos_audio, qos.cos_audio, "UNISTIM RTP");
2896 ast_rtp_instance_set_prop(sub->rtp, AST_RTP_PROPERTY_NAT, sub->parent->parent->nat);
2897
2898 /* Create the RTP connection */
2899 sin.sin_family = AF_INET;
2900 /* Setting up RTP for our side */
2901 memcpy(&sin.sin_addr, &sub->parent->parent->session->sin.sin_addr,
2902 sizeof(sin.sin_addr));
2903
2904 sin.sin_port = htons(find_rtp_port(sub));
2905 ast_sockaddr_from_sin(&sin_tmp, &sin);
2908 struct ast_format *tmpfmt;
2910
2913 "Our read/writeformat has been changed to something incompatible: %s, using %s best codec from %s\n",
2915 ast_format_get_name(tmpfmt),
2917
2918 ast_channel_set_readformat(sub->owner, tmpfmt);
2919 ast_channel_set_writeformat(sub->owner, tmpfmt);
2920 ao2_ref(tmpfmt, -1);
2921 }
2923 ast_mutex_unlock(&sub->lock);
2924}
static int find_rtp_port(struct unistim_subchannel *s)
static void send_start_rtp(struct unistim_subchannel *)
struct ast_format_cap * ast_channel_nativeformats(const struct ast_channel *chan)
const char * ast_channel_uniqueid(const struct ast_channel *chan)
void ast_channel_internal_fd_set(struct ast_channel *chan, int which, int value)
void ast_channel_set_readformat(struct ast_channel *chan, struct ast_format *format)
void ast_channel_set_writeformat(struct ast_channel *chan, struct ast_format *format)
@ AST_FORMAT_CMP_NOT_EQUAL
Definition format.h:38
#define AST_FORMAT_CAP_NAMES_LEN
Definition format_cap.h:324
struct ast_format * ast_format_cap_get_format(const struct ast_format_cap *cap, int position)
Get the format at a specific index.
Definition format_cap.c:408
enum ast_format_cmp_res ast_format_cap_iscompatible_format(const struct ast_format_cap *cap, const struct ast_format *format)
Find if ast_format is within the capabilities of the ast_format_cap object.
Definition format_cap.c:589
const char * ast_format_cap_get_names(const struct ast_format_cap *cap, struct ast_str **buf)
Get the names of codecs of a set of formats.
Definition format_cap.c:742
#define ast_sockaddr_from_sin(addr, sin)
Converts a struct sockaddr_in to a struct ast_sockaddr.
Definition netsock2.h:778
struct ast_rtp_instance * ast_rtp_instance_new(const char *engine_name, struct ast_sched_context *sched, const struct ast_sockaddr *sa, void *data)
Create a new RTP instance.
Definition rtp_engine.c:497
void ast_rtp_instance_set_prop(struct ast_rtp_instance *instance, enum ast_rtp_property property, int value)
Set the value of an RTP instance property.
Definition rtp_engine.c:756
#define ast_rtp_instance_set_remote_address(instance, address)
Set the address of the remote endpoint that we are sending RTP to.
@ AST_RTP_PROPERTY_NAT
Definition rtp_engine.h:118
@ AST_RTP_PROPERTY_RTCP
Definition rtp_engine.h:126
int ast_rtp_instance_set_qos(struct ast_rtp_instance *instance, int tos, int cos, const char *desc)
Set QoS parameters on an RTP session.
void ast_rtp_instance_set_channel_id(struct ast_rtp_instance *instance, const char *uniqueid)
Set the channel that owns this RTP instance.
Definition rtp_engine.c:604
int ast_rtp_instance_fd(struct ast_rtp_instance *instance, int rtcp)
Get the file descriptor for an RTP session (or RTCP)
#define ast_str_alloca(init_len)
Definition strings.h:848
Definition of a media format.
Definition format.c:43
Support for dynamic strings.
Definition strings.h:623

References ao2_ref, ast_channel_internal_fd_set(), ast_channel_nativeformats(), ast_channel_readformat(), ast_channel_set_readformat(), ast_channel_set_writeformat(), ast_channel_uniqueid(), ast_format_cap_get_format(), ast_format_cap_get_names(), ast_format_cap_iscompatible_format(), AST_FORMAT_CAP_NAMES_LEN, AST_FORMAT_CMP_NOT_EQUAL, ast_format_get_name(), ast_inet_ntoa(), ast_log, ast_mutex_lock, ast_mutex_unlock, ast_rtp_instance_fd(), ast_rtp_instance_new(), ast_rtp_instance_set_channel_id(), 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_str_alloca, ast_verb, errno, find_rtp_port(), LOG_WARNING, NULL, qos, send_start_rtp(), sub, and unistimdebug.

Referenced by handle_call_incoming(), and handle_call_outgoing().

◆ sub_hold()

static void sub_hold ( struct unistimsession pte,
struct unistim_subchannel sub 
)
static

Definition at line 2562 of file chan_unistim.c.

2563{
2564 if (!sub) {
2565 return;
2566 }
2567 sub->moh = 1;
2568 sub->holding = 1;
2571 send_stop_timer(pte);
2572 if (sub->owner) {
2573 ast_queue_hold(sub->owner, NULL);
2574 }
2575 return;
2576}
int ast_queue_hold(struct ast_channel *chan, const char *musicclass)
Queue a hold frame.
Definition channel.c:1249

References ast_queue_hold(), unistimsession::device, FAV_BLINK_SLOW, FAV_ICON_ONHOLD_BLACK, MUTE_ON, NULL, unistim_device::output, send_favorite_short(), send_select_output(), send_stop_timer(), sub, and unistim_device::volume.

Referenced by handle_call_incoming(), handle_call_outgoing(), handle_key_fav(), key_call(), and sub_unhold().

◆ sub_start_silence()

static void sub_start_silence ( struct unistimsession pte,
struct unistim_subchannel sub 
)
static

Definition at line 2531 of file chan_unistim.c.

2532{
2533 /* Silence our channel */
2534 if (!pte->device->silence_generator) {
2537 if (pte->device->silence_generator == NULL) {
2538 ast_log(LOG_WARNING, "Unable to start a silence generator.\n");
2539 } else if (unistimdebug) {
2540 ast_verb(0, "Starting silence generator\n");
2541 }
2542 }
2543
2544}
struct ast_silence_generator * ast_channel_start_silence_generator(struct ast_channel *chan)
Starts a silence generator on the given channel.
Definition channel.c:8340
struct ast_silence_generator * silence_generator

References ast_channel_start_silence_generator(), ast_log, ast_verb, unistimsession::device, LOG_WARNING, NULL, unistim_device::silence_generator, sub, and unistimdebug.

Referenced by transfer_call_step1().

◆ sub_stop_silence()

static void sub_stop_silence ( struct unistimsession pte,
struct unistim_subchannel sub 
)
static

Definition at line 2546 of file chan_unistim.c.

2547{
2548 /* Stop the silence generator */
2549 if (pte->device->silence_generator) {
2550 if (unistimdebug) {
2551 ast_verb(0, "Stopping silence generator\n");
2552 }
2553 if (sub->owner) {
2555 } else {
2556 ast_log(LOG_WARNING, "Trying to stop silence generator on a null channel!\n");
2557 }
2559 }
2560}
void ast_channel_stop_silence_generator(struct ast_channel *chan, struct ast_silence_generator *state)
Stops a previously-started silence generator on the given channel.
Definition channel.c:8386

References ast_channel_stop_silence_generator(), ast_log, ast_verb, unistimsession::device, LOG_WARNING, NULL, unistim_device::silence_generator, sub, and unistimdebug.

Referenced by handle_call_outgoing(), key_dial_page(), and unistim_hangup().

◆ sub_unhold()

static void sub_unhold ( struct unistimsession pte,
struct unistim_subchannel sub 
)
static

Definition at line 2578 of file chan_unistim.c.

2579{
2580 struct unistim_subchannel *sub_real;
2581
2582 sub_real = get_sub(pte->device, SUB_REAL);
2583 if (sub_real) {
2584 sub_hold(pte, sub_real);
2585 }
2586
2587 sub->moh = 0;
2588 sub->holding = 0;
2591 send_start_timer(pte);
2592 if (sub->owner) {
2593 ast_queue_unhold(sub->owner);
2594 if (sub->rtp) {
2596 }
2597 }
2598 return;
2599}

References ast_queue_unhold(), unistimsession::device, FAV_ICON_OFFHOOK_BLACK, get_sub(), MUTE_OFF, unistim_device::output, send_favorite_short(), send_select_output(), send_start_rtp(), send_start_timer(), sub, sub_hold(), SUB_REAL, and unistim_device::volume.

Referenced by handle_key_fav(), and key_call().

◆ subtype_tostr()

static const char * subtype_tostr ( const int  type)
static

Definition at line 2029 of file chan_unistim.c.

2030{
2031 switch (type) {
2032 case SUB_REAL:
2033 return "REAL";
2034 case SUB_RING:
2035 return "RINGING";
2036 case SUB_THREEWAY:
2037 return "THREEWAY";
2038 }
2039 return "UNKNOWN";
2040}

References SUB_REAL, SUB_RING, SUB_THREEWAY, and type.

Referenced by unistim_show_info().

◆ swap_subs()

static void swap_subs ( struct unistim_subchannel a,
struct unistim_subchannel b 
)
static

Definition at line 3030 of file chan_unistim.c.

3031{
3032 struct ast_rtp_instance *rtp;
3033 int fds;
3034
3035 if (unistimdebug) {
3036 ast_verb(0, "Swapping %p and %p\n", a, b);
3037 }
3038 if ((!a->owner) || (!b->owner)) {
3040 "Attempted to swap subchannels with a null owner : sub #%p=%p sub #%p=%p\n",
3041 a, a->owner, b, b->owner);
3042 return;
3043 }
3044 rtp = a->rtp;
3045 a->rtp = b->rtp;
3046 b->rtp = rtp;
3047
3048 fds = ast_channel_fd(a->owner, 0);
3049 ast_channel_internal_fd_set(a->owner, 0, ast_channel_fd(b->owner, 0));
3050 ast_channel_internal_fd_set(b->owner, 0, fds);
3051
3052 fds = ast_channel_fd(a->owner, 1);
3053 ast_channel_internal_fd_set(a->owner, 1, ast_channel_fd(b->owner, 1));
3054 ast_channel_internal_fd_set(b->owner, 1, fds);
3055}
int ast_channel_fd(const struct ast_channel *chan, int which)
static struct test_val b
static struct test_val a

References a, ast_channel_fd(), ast_channel_internal_fd_set(), ast_log, ast_verb, b, LOG_WARNING, and unistimdebug.

Referenced by handle_call_outgoing(), transfer_cancel_step2(), and unistim_hangup().

◆ transfer_call_step1()

static void transfer_call_step1 ( struct unistimsession pte)
static

Definition at line 3058 of file chan_unistim.c.

3059{
3060 struct unistim_subchannel *sub /*, *sub_trans */;
3061 struct unistim_device *d = pte->device;
3062
3063 sub = get_sub(d, SUB_REAL);
3064 /* sub_trans = get_sub(d, SUB_THREEWAY); */
3065
3066 if (!sub || !sub->owner) {
3067 ast_log(LOG_WARNING, "Unable to find subchannel for music on hold\n");
3068 return;
3069 }
3070 /* Start music on hold if appropriate */
3071 if (sub->moh) {
3072 ast_log(LOG_WARNING, "Transfer with peer already listening music on hold\n");
3073 } else {
3074 ast_queue_hold(sub->owner, sub->parent->musicclass);
3075 sub->moh = 1;
3076 sub->subtype = SUB_THREEWAY;
3077 }
3078 sub_start_silence(pte, sub);
3079 handle_dial_page(pte);
3080}
static void sub_start_silence(struct unistimsession *pte, struct unistim_subchannel *sub)

References ast_log, ast_queue_hold(), d, unistimsession::device, get_sub(), handle_dial_page(), LOG_WARNING, sub, SUB_REAL, sub_start_silence(), and SUB_THREEWAY.

Referenced by key_call().

◆ transfer_cancel_step2()

static void transfer_cancel_step2 ( struct unistimsession pte)
static

Definition at line 3082 of file chan_unistim.c.

3083{
3084 struct unistim_subchannel *sub, *sub_trans;
3085 struct unistim_device *d = pte->device;
3086
3087 sub = get_sub(d, SUB_REAL);
3088 sub_trans = get_sub(d, SUB_THREEWAY);
3089
3090 if (!sub || !sub->owner) {
3091 ast_log(LOG_WARNING, "Unable to find subchannel for music on hold\n");
3092 return;
3093 }
3094 if (sub_trans) {
3095 if (unistimdebug) {
3096 ast_verb(0, "Transfer canceled, hangup our threeway channel\n");
3097 }
3098 if (sub->owner) {
3099 swap_subs(sub, sub_trans);
3100 ast_queue_unhold(sub_trans->owner);
3101 sub_trans->moh = 0;
3102 sub_trans->subtype = SUB_REAL;
3103 sub->subtype = SUB_THREEWAY;
3105 } else {
3106 ast_log(LOG_WARNING, "Canceling a threeway channel without owner\n");
3107 }
3108 return;
3109 }
3110}

References AST_CAUSE_NORMAL_CLEARING, ast_log, ast_queue_hangup_with_cause(), ast_queue_unhold(), ast_verb, d, unistimsession::device, get_sub(), LOG_WARNING, unistim_subchannel::moh, unistim_subchannel::owner, sub, SUB_REAL, SUB_THREEWAY, unistim_subchannel::subtype, swap_subs(), and unistimdebug.

Referenced by key_call().

◆ unistim_alloc_sub()

static struct unistim_subchannel * unistim_alloc_sub ( struct unistim_device d,
int  x 
)
static

Definition at line 1990 of file chan_unistim.c.

1991{
1992 struct unistim_subchannel *sub;
1993 if (!(sub = ast_calloc(1, sizeof(*sub)))) {
1994 return NULL;
1995 }
1996
1997 if (unistimdebug) {
1998 ast_verb(3, "Allocating UNISTIM subchannel #%d on %s ptr=%p\n", x, d->name, sub);
1999 }
2000 sub->ss_thread = AST_PTHREADT_NULL;
2001 sub->subtype = x;
2002 AST_LIST_LOCK(&d->subs);
2003 AST_LIST_INSERT_TAIL(&d->subs, sub, list);
2004 AST_LIST_UNLOCK(&d->subs);
2005 ast_mutex_init(&sub->lock);
2006 return sub;
2007}

References ast_calloc, AST_LIST_INSERT_TAIL, AST_LIST_LOCK, AST_LIST_UNLOCK, ast_mutex_init, AST_PTHREADT_NULL, ast_verb, d, unistim_subchannel::list, test_val::name, NULL, sub, and unistimdebug.

Referenced by find_subchannel_by_name(), and handle_call_outgoing().

◆ unistim_answer()

static int unistim_answer ( struct ast_channel ast)
static

Definition at line 5062 of file chan_unistim.c.

5063{
5064 int res = 0;
5065 struct unistim_subchannel *sub;
5066 struct unistim_line *l;
5067 struct unistim_device *d;
5068 struct unistimsession *s;
5069
5070 s = channel_to_session(ast);
5071 if (!s) {
5072 ast_log(LOG_WARNING, "unistim_answer on a disconnected device ?\n");
5073 return -1;
5074 }
5076 l = sub->parent;
5077 d = l->parent;
5078
5079 if (unistimdebug) {
5080 ast_verb(0, "unistim_answer(%s) on %s@%s-%d\n", ast_channel_name(ast), l->name,
5081 l->parent->name, sub->softkey);
5082 }
5083 send_text(TEXT_LINE2, TEXT_NORMAL, s, ustmtext("is now on-line", s));
5084 if (get_sub(d, SUB_THREEWAY)) {
5085 send_text_status(s, ustmtext("Transf Cancel", s));
5086 } else {
5087 send_text_status(s, ustmtext(" Transf Hangup", s));
5088 }
5090 if (ast_channel_state(ast) != AST_STATE_UP)
5092 return res;
5093}
static struct unistimsession * channel_to_session(struct ast_channel *ast)
int ast_setstate(struct ast_channel *chan, enum ast_channel_state)
Change the state of a channel.
Definition channel.c:7422

References ast_channel_name(), ast_channel_tech_pvt(), ast_log, ast_setstate(), AST_STATE_UP, ast_verb, channel_to_session(), d, get_sub(), LOG_WARNING, unistim_line::name, unistim_device::name, unistim_line::parent, send_start_timer(), send_text(), send_text_status(), sub, SUB_THREEWAY, TEXT_LINE2, TEXT_NORMAL, unistimdebug, and ustmtext().

◆ unistim_call()

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

Definition at line 4875 of file chan_unistim.c.

4876{
4877 int res = 0, i;
4878 struct unistim_subchannel *sub, *sub_real;
4879 struct unistimsession *session;
4880 signed char ringstyle, ringvolume;
4881
4883 if (!session) {
4884 ast_log(LOG_ERROR, "Device not registered, cannot call %s\n", dest);
4885 return -1;
4886 }
4888 sub_real = get_sub(session->device, SUB_REAL);
4890 ast_log(LOG_WARNING, "unistim_call called on %s, neither down nor reserved\n",
4891 ast_channel_name(ast));
4892 return -1;
4893 }
4894
4895 if (unistimdebug) {
4896 ast_verb(3, "unistim_call(%s)\n", ast_channel_name(ast));
4897 }
4898 session->state = STATE_RINGING;
4900 if (ast_strlen_zero(ast_channel_call_forward(ast))) { /* Send ring only if no call forward, otherwise short ring will appear */
4901 send_text(TEXT_LINE2, TEXT_NORMAL, session, ustmtext("is calling you.", session));
4902 send_text_status(session, ustmtext("Accept Ignore Hangup", session));
4903
4904 if (sub_real) {
4905 ringstyle = session->device->cwstyle;
4906 ringvolume = session->device->cwvolume;
4907 } else {
4908 ringstyle = (sub->ringstyle == -1) ? session->device->ringstyle : sub->ringstyle;
4909 ringvolume = (sub->ringvolume == -1) ? session->device->ringvolume : sub->ringvolume;
4910 }
4911 send_ring(session, ringvolume, ringstyle);
4913 /* Send call identification to all */
4914 for (i = 0; i < FAVNUM; i++) {
4915 if (!soft_key_visible(session->device, i)) {
4916 continue;
4917 }
4918 if (session->device->ssub[i]) {
4919 continue;
4920 }
4921 if (is_key_line(session->device, i) && !strcmp(sub->parent->name, session->device->sline[i]->name)) {
4922 if (unistimdebug) {
4923 ast_verb(0, "Found softkey %d for line %s\n", i, sub->parent->name);
4924 }
4926 session->device->ssub[i] = sub;
4927 }
4928 }
4929 }
4932 return res;
4933}
static struct ast_mansession session
static void send_ring(struct unistimsession *pte, signed char volume, signed char style)
#define FAV_BLINK_FAST
const char * ast_channel_call_forward(const struct ast_channel *chan)
@ AST_STATE_RINGING
@ AST_STATE_RESERVED

References ast_channel_call_forward(), ast_channel_name(), ast_channel_tech_pvt(), AST_CONTROL_RINGING, ast_log, ast_queue_control(), ast_setstate(), AST_STATE_DOWN, AST_STATE_RESERVED, AST_STATE_RINGING, ast_strlen_zero(), ast_verb, change_favorite_icon(), channel_to_session(), FAV_BLINK_FAST, FAV_ICON_SPEAKER_ONHOOK_BLACK, FAVNUM, get_sub(), is_key_line(), LOG_ERROR, LOG_WARNING, send_callerid_screen(), send_favorite_short(), send_ring(), send_text(), send_text_status(), session, soft_key_visible(), STATE_RINGING, sub, SUB_REAL, TEXT_LINE2, TEXT_NORMAL, unistimdebug, and ustmtext().

◆ unistim_do_debug()

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

Definition at line 6218 of file chan_unistim.c.

6219{
6220 switch (cmd) {
6221 case CLI_INIT:
6222 e->command = "unistim set debug {on|off}";
6223 e->usage =
6224 "Usage: unistim set debug\n"
6225 " Display debug messages.\n";
6226 return NULL;
6227
6228 case CLI_GENERATE:
6229 return NULL; /* no completion */
6230 }
6231
6232 if (a->argc != e->args) {
6233 return CLI_SHOWUSAGE;
6234 }
6235 if (!strcasecmp(a->argv[3], "on")) {
6236 unistimdebug = 1;
6237 ast_cli(a->fd, "UNISTIM Debugging Enabled\n");
6238 } else if (!strcasecmp(a->argv[3], "off")) {
6239 unistimdebug = 0;
6240 ast_cli(a->fd, "UNISTIM Debugging Disabled\n");
6241 } else {
6242 return CLI_SHOWUSAGE;
6243 }
6244 return CLI_SUCCESS;
6245}
#define CLI_SHOWUSAGE
Definition cli.h:45
#define CLI_SUCCESS
Definition cli.h:44
void ast_cli(int fd, const char *fmt,...)
Definition clicompat.c:6
@ CLI_INIT
Definition cli.h:152
@ CLI_GENERATE
Definition cli.h:153
int args
This gets set in ast_cli_register()
Definition cli.h:185
char * command
Definition cli.h:186
const char * usage
Definition cli.h:177

References a, ast_cli_entry::args, ast_cli(), CLI_GENERATE, CLI_INIT, CLI_SHOWUSAGE, CLI_SUCCESS, ast_cli_entry::command, NULL, unistimdebug, and ast_cli_entry::usage.

◆ unistim_do_senddigit()

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

Definition at line 3358 of file chan_unistim.c.

3359{
3360 struct ast_frame f = { .frametype = AST_FRAME_DTMF, .subclass.integer = digit, .src = "unistim" };
3361 struct unistim_subchannel *sub;
3362
3363 sub = get_sub(pte->device, SUB_REAL);
3364 if (!sub || !sub->owner || sub->alreadygone) {
3365 ast_log(LOG_WARNING, "Unable to find subchannel in dtmf senddigit\n");
3366 return -1;
3367 }
3368
3369 /* Send DTMF indication _before_ playing sounds */
3370 ast_queue_frame(sub->owner, &f);
3371 if (pte->device->dtmfduration > 0) {
3372 if (unistimdebug) {
3373 ast_verb(0, "Send Digit %c (%i ms)\n", digit, pte->device->dtmfduration);
3374 }
3375 send_dtmf_tone(pte, digit);
3376 usleep(pte->device->dtmfduration * 1000); /* XXX Less than perfect, blocking an important thread is not a good idea */
3377 send_tone(pte, 0, 0);
3378 }
3379 return 0;
3380}
static int send_dtmf_tone(struct unistimsession *pte, char digit)
int ast_queue_frame(struct ast_channel *chan, struct ast_frame *f)
Queue one or more frames to a channel's frame queue.
Definition channel.c:1171
#define AST_FRAME_DTMF
Data structure associated with a single frame of data.
enum ast_frame_type frametype

References AST_FRAME_DTMF, ast_log, ast_queue_frame(), ast_verb, unistimsession::device, digit, unistim_device::dtmfduration, ast_frame::frametype, get_sub(), LOG_WARNING, send_dtmf_tone(), send_tone(), sub, SUB_REAL, and unistimdebug.

Referenced by key_call().

◆ unistim_fixup()

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

Definition at line 5260 of file chan_unistim.c.

5261{
5262 struct unistim_subchannel *p = ast_channel_tech_pvt(newchan);
5263 struct unistim_line *l = p->parent;
5264
5265 ast_mutex_lock(&p->lock);
5266
5267 ast_debug(1, "New owner for channel USTM/%s@%s-%u is %s\n", l->name,
5268 l->parent->name, p->subtype, ast_channel_name(newchan));
5269
5270 if (p->owner != oldchan) {
5271 ast_log(LOG_WARNING, "old channel wasn't %s (%p) but was %s (%p)\n",
5272 ast_channel_name(oldchan), oldchan, ast_channel_name(p->owner), p->owner);
5274 return -1;
5275 }
5276
5277 unistim_set_owner(p, newchan);
5278
5280
5281 return 0;
5282
5283}
static void unistim_set_owner(struct unistim_subchannel *sub, struct ast_channel *chan)

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

◆ unistim_free_sub()

static int unistim_free_sub ( struct unistim_subchannel sub)
static

Definition at line 1981 of file chan_unistim.c.

1981 {
1982 if (unistimdebug) {
1983 ast_debug(1, "Released sub %u of channel %s@%s\n", sub->subtype, sub->parent->name, sub->parent->parent->name);
1984 }
1985 ast_mutex_destroy(&sub->lock);
1986 ast_free(sub);
1987 return 0;
1988}

References ast_debug, ast_free, ast_mutex_destroy, sub, and unistimdebug.

Referenced by close_client(), and unistim_unalloc_sub().

◆ unistim_get_rtp_peer()

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

Definition at line 7034 of file chan_unistim.c.

7035{
7037
7038 if (!sub) {
7040 }
7041 if (!sub->rtp) {
7043 }
7044
7045 ao2_ref(sub->rtp, +1);
7046 *instance = sub->rtp;
7047
7049}
@ AST_RTP_GLUE_RESULT_LOCAL
Definition rtp_engine.h:167
@ AST_RTP_GLUE_RESULT_FORBID
Definition rtp_engine.h:163

References ao2_ref, ast_channel_tech_pvt(), AST_RTP_GLUE_RESULT_FORBID, AST_RTP_GLUE_RESULT_LOCAL, and sub.

◆ unistim_hangup()

static int unistim_hangup ( struct ast_channel ast)
static

Definition at line 4953 of file chan_unistim.c.

4954{
4955 struct unistim_subchannel *sub = NULL, *sub_real = NULL, *sub_trans = NULL;
4956 struct unistim_line *l;
4957 struct unistim_device *d;
4958 struct unistimsession *s;
4959 int i,end_call = 1;
4960
4961 s = channel_to_session(ast);
4963 l = sub->parent;
4964 d = l->parent;
4965 if (!s) {
4966 ast_debug(1, "Asked to hangup channel not connected\n");
4968 return 0;
4969 }
4970 if (unistimdebug) {
4971 ast_verb(0, "unistim_hangup(%s) on %s@%s (STATE_%s)\n", ast_channel_name(ast), l->name, l->parent->name, ptestate_tostr(s->state));
4972 }
4973 sub_trans = get_sub(d, SUB_THREEWAY);
4974 sub_real = get_sub(d, SUB_REAL);
4975 if (sub_trans && (sub_trans->owner) && (sub->subtype == SUB_REAL)) { /* 3rd party busy or congested and transfer_cancel_step2 does not called */
4976 if (unistimdebug) {
4977 ast_verb(0, "Threeway call disconnected, switching to real call\n");
4978 }
4979 ast_queue_unhold(sub_trans->owner);
4980 sub_trans->moh = 0;
4981 sub_trans->subtype = SUB_REAL;
4982 swap_subs(sub_trans, sub);
4983 send_text_status(s, ustmtext(" Transf Hangup", s));
4984 send_callerid_screen(s, sub_trans);
4987 return 0;
4988 }
4989 if (sub_real && (sub_real->owner) && (sub->subtype == SUB_THREEWAY) && (s->state == STATE_CALL)) { /* 3way call cancelled by softkey pressed */
4990 if (unistimdebug) {
4991 ast_verb(0, "Real call disconnected, stay in call\n");
4992 }
4993 send_text_status(s, ustmtext(" Transf Hangup", s));
4994 send_callerid_screen(s, sub_real);
4997 return 0;
4998 }
4999 if (sub->subtype == SUB_REAL) {
5001 } else if (sub->subtype == SUB_RING) {
5002 send_no_ring(s);
5003 for (i = 0; i < FAVNUM; i++) {
5004 if (!soft_key_visible(s->device, i)) {
5005 continue;
5006 }
5007 if (d->ssub[i] != sub) {
5008 if (d->ssub[i] != NULL) { /* Found other subchannel active other than hangup'ed one */
5009 end_call = 0;
5010 }
5011 continue;
5012 }
5013 if (is_key_line(d, i) && !strcmp(l->name, d->sline[i]->name)) {
5015 d->ssub[i] = NULL;
5016 continue;
5017 }
5018 }
5019 }
5020 if (end_call) {
5021 send_end_call(s); /* Send end call packet only if ending active call, in other way sound should be loosed */
5022 }
5023 sub->moh = 0;
5024 if (sub->softkey >= 0) {
5026 }
5027 /* Delete assign sub to softkey */
5028 for (i = 0; i < FAVNUM; i++) {
5029 if (d->ssub[i] == sub) {
5030 d->ssub[i] = NULL;
5031 break;
5032 }
5033 }
5034 /*refresh_all_favorite(s); */ /* TODO: Update favicons in case of DND keys */
5035 if (s->state == STATE_RINGING && sub->subtype == SUB_RING) {
5036 send_no_ring(s);
5038 d->missed_call++;
5039 write_history(s, 'i', 1);
5040 }
5041 if (!sub_real) {
5042 show_main_page(s);
5043 } else { /* hangup on a ringing line: reset status to reflect that we're still on an active call */
5044 s->state = STATE_CALL;
5045 send_callerid_screen(s, sub_real);
5046 send_text(TEXT_LINE2, TEXT_NORMAL, s, ustmtext("is on-line", s));
5047 send_text_status(s, ustmtext(" Transf Hangup", s));
5049
5050 }
5051 }
5052 if (s->state == STATE_CALL && sub->subtype == SUB_REAL) {
5053 close_call(s);
5054 }
5055 sub->softkey = -1;
5058 return 0;
5059}
#define AST_CAUSE_ANSWERED_ELSEWHERE
Definition causes.h:114
static void send_end_call(struct unistimsession *pte)
static int unistim_unalloc_sub(struct unistim_device *d, struct unistim_subchannel *sub)
static int unistim_hangup_clean(struct ast_channel *ast, struct unistim_subchannel *sub)
int ast_channel_hangupcause(const struct ast_channel *chan)

References AST_CAUSE_ANSWERED_ELSEWHERE, ast_channel_hangupcause(), ast_channel_name(), ast_channel_tech_pvt(), ast_debug, ast_queue_unhold(), ast_verb, channel_to_session(), close_call(), d, unistimsession::device, FAV_ICON_OFFHOOK_BLACK, FAV_LINE_ICON, FAVNUM, get_sub(), is_key_line(), unistim_line::name, unistim_device::name, test_val::name, NULL, unistim_line::parent, ptestate_tostr(), send_callerid_screen(), send_end_call(), send_favorite_short(), send_no_ring(), send_text(), send_text_status(), show_main_page(), soft_key_visible(), unistimsession::state, STATE_CALL, STATE_RINGING, sub, SUB_REAL, SUB_RING, sub_stop_silence(), SUB_THREEWAY, swap_subs(), TEXT_LINE2, TEXT_NORMAL, unistim_hangup_clean(), unistim_unalloc_sub(), unistimdebug, ustmtext(), and write_history().

◆ unistim_hangup_clean()

static int unistim_hangup_clean ( struct ast_channel ast,
struct unistim_subchannel sub 
)
static

Definition at line 4935 of file chan_unistim.c.

4935 {
4936 ast_mutex_lock(&sub->lock);
4939 sub->alreadygone = 0;
4940 if (sub->rtp) {
4941 if (unistimdebug) {
4942 ast_verb(0, "Destroying RTP session\n");
4943 }
4946 sub->rtp = NULL;
4947 }
4948 ast_mutex_unlock(&sub->lock);
4949 return 0;
4950}
void ast_channel_tech_pvt_set(struct ast_channel *chan, void *value)
int ast_rtp_instance_destroy(struct ast_rtp_instance *instance)
Destroy an RTP instance.
Definition rtp_engine.c:468
void ast_rtp_instance_stop(struct ast_rtp_instance *instance)
Stop an RTP instance.

References ast_channel_tech_pvt_set(), ast_mutex_lock, ast_mutex_unlock, ast_rtp_instance_destroy(), ast_rtp_instance_stop(), ast_verb, NULL, sub, unistim_set_owner(), and unistimdebug.

Referenced by unistim_hangup().

◆ unistim_indicate()

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

Definition at line 5339 of file chan_unistim.c.

5340{
5341 struct unistim_subchannel *sub;
5342 struct unistim_line *l;
5343 struct unistimsession *s;
5344
5345 if (unistimdebug) {
5346 ast_verb(3, "Asked to indicate '%s' (%d) condition on channel %s\n",
5347 control2str(ind), ind, ast_channel_name(ast));
5348 }
5349
5350 s = channel_to_session(ast);
5351 if (!s) {
5352 return -1;
5353 }
5355 l = sub->parent;
5356
5357 switch (ind) {
5359 if (ast_channel_state(ast) != AST_STATE_UP) {
5360 send_text(TEXT_LINE2, TEXT_NORMAL, s, ustmtext("Ringing...", s));
5361 in_band_indication(ast, l->parent->tz, "ring");
5362 s->device->missed_call = -1;
5363 break;
5364 }
5365 return -1;
5366 case AST_CONTROL_BUSY:
5367 if (ast_channel_state(ast) != AST_STATE_UP) {
5368 sub->alreadygone = 1;
5369 send_text(TEXT_LINE2, TEXT_NORMAL, s, ustmtext("Busy", s));
5370 in_band_indication(ast, l->parent->tz, "busy");
5371 s->device->missed_call = -1;
5372 break;
5373 }
5374 return -1;
5376 /* Overlapped dialing is not currently supported for UNIStim. Treat an indication
5377 * of incomplete as congestion
5378 */
5380 if (ast_channel_state(ast) != AST_STATE_UP) {
5381 sub->alreadygone = 1;
5382 send_text(TEXT_LINE2, TEXT_NORMAL, s, ustmtext("Congestion", s));
5383 in_band_indication(ast, l->parent->tz, "congestion");
5384 s->device->missed_call = -1;
5385 break;
5386 }
5387 return -1;
5388 case AST_CONTROL_HOLD:
5389 ast_moh_start(ast, data, NULL);
5390 break;
5391 case AST_CONTROL_UNHOLD:
5392 ast_moh_stop(ast);
5393 break;
5398 break;
5399 case -1:
5400 ast_playtones_stop(ast);
5401 s->device->missed_call = 0;
5402 break;
5404 ast_log(LOG_NOTICE, "Connected party is now %s <%s>\n",
5405 S_COR(ast_channel_connected(ast)->id.name.valid, ast_channel_connected(ast)->id.name.str, ""),
5406 S_COR(ast_channel_connected(ast)->id.number.valid, ast_channel_connected(ast)->id.number.str, ""));
5407 if (sub->subtype == SUB_REAL) {
5409 }
5410 break;
5412 if (sub->rtp) {
5414 }
5415 break;
5416 default:
5417 ast_log(LOG_WARNING, "Don't know how to indicate condition %d\n", ind);
5418 /* fallthrough */
5421 return -1;
5422 }
5423
5424 return 0;
5425}
static void in_band_indication(struct ast_channel *ast, const struct ast_tone_zone *tz, const char *indication)
static char * control2str(int ind)
@ AST_CONTROL_PROGRESS
@ AST_CONTROL_UNHOLD
@ AST_CONTROL_PROCEEDING
@ AST_CONTROL_INCOMPLETE
@ AST_CONTROL_MASQUERADE_NOTIFY
@ AST_CONTROL_PVT_CAUSE_CODE
@ AST_CONTROL_UPDATE_RTP_PEER
void ast_playtones_stop(struct ast_channel *chan)
Stop playing tones on a channel.
int ast_moh_start(struct ast_channel *chan, const char *mclass, const char *interpclass)
Turn on music on hold on a given channel.
Definition channel.c:7802
void ast_moh_stop(struct ast_channel *chan)
Turn off music on hold on a given channel.
Definition channel.c:7812
void ast_rtp_instance_change_source(struct ast_rtp_instance *instance)
Indicate a new source of audio has dropped in and the ssrc should change.
#define S_COR(a, b, c)
returns the equivalent of logic or for strings, with an additional boolean check: second one if not e...
Definition strings.h:87

References ast_channel_connected(), ast_channel_name(), ast_channel_tech_pvt(), AST_CONTROL_BUSY, AST_CONTROL_CONGESTION, AST_CONTROL_CONNECTED_LINE, AST_CONTROL_HOLD, AST_CONTROL_INCOMPLETE, AST_CONTROL_MASQUERADE_NOTIFY, AST_CONTROL_PROCEEDING, AST_CONTROL_PROGRESS, AST_CONTROL_PVT_CAUSE_CODE, AST_CONTROL_RINGING, AST_CONTROL_SRCCHANGE, AST_CONTROL_SRCUPDATE, AST_CONTROL_UNHOLD, AST_CONTROL_UPDATE_RTP_PEER, ast_log, ast_moh_start(), ast_moh_stop(), ast_playtones_stop(), ast_rtp_instance_change_source(), AST_STATE_UP, ast_verb, channel_to_session(), control2str(), unistimsession::device, in_band_indication(), LOG_NOTICE, LOG_WARNING, unistim_device::missed_call, name, NULL, unistim_line::parent, S_COR, send_callerid_screen(), send_text(), sub, SUB_REAL, TEXT_LINE2, TEXT_NORMAL, unistim_device::tz, unistimdebug, and ustmtext().

◆ unistim_line_alloc()

static struct unistim_line * unistim_line_alloc ( void  )
static

Definition at line 1967 of file chan_unistim.c.

1968{
1969 struct unistim_line *l;
1970 if (!(l = ast_calloc(1, sizeof(*l)))) {
1971 return NULL;
1972 }
1973
1975 ast_free(l);
1976 return NULL;
1977 }
1978 return l;
1979}

References ast_calloc, ast_format_cap_alloc, AST_FORMAT_CAP_FLAG_DEFAULT, ast_free, unistim_line::cap, and NULL.

Referenced by build_device(), and rcv_mac_addr().

◆ unistim_line_copy()

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

Definition at line 1949 of file chan_unistim.c.

1950{
1951 struct ast_format_cap *tmp = src->cap;
1952 memcpy(dst, src, sizeof(*dst)); /* this over writes the cap ptr, so we have to reset it */
1953 src->cap = tmp;
1955}
Format capabilities structure, holds formats + preference order + etc.
Definition format_cap.c:54

References ast_format_cap_append_from_cap(), AST_MEDIA_TYPE_UNKNOWN, and unistim_line::cap.

Referenced by rcv_mac_addr().

◆ unistim_line_destroy()

static struct unistim_line * unistim_line_destroy ( struct unistim_line l)
static

Definition at line 1957 of file chan_unistim.c.

1958{
1959 if (!l) {
1960 return NULL;
1961 }
1962 ao2_ref(l->cap, -1);
1963 ast_free(l);
1964 return NULL;
1965}

References ao2_ref, ast_free, unistim_line::cap, and NULL.

Referenced by build_device(), and delete_device().

◆ unistim_new()

static struct ast_channel * unistim_new ( struct unistim_subchannel sub,
int  state,
const struct ast_assigned_ids assignedids,
const struct ast_channel requestor 
)
static

Protos

Definition at line 5710 of file chan_unistim.c.

5711{
5712 struct ast_format_cap *caps;
5713 struct ast_channel *tmp;
5714 struct unistim_line *l;
5715 struct ast_format *tmpfmt;
5716
5717 if (!sub) {
5718 ast_log(LOG_WARNING, "subchannel null in unistim_new\n");
5719 return NULL;
5720 }
5721 if (!sub->parent) {
5722 ast_log(LOG_WARNING, "no line for subchannel %p\n", sub);
5723 return NULL;
5724 }
5725
5727 if (!caps) {
5728 return NULL;
5729 }
5730
5731 l = sub->parent;
5732 tmp = ast_channel_alloc(1, state, l->cid_num, NULL, l->accountcode, l->exten,
5733 l->parent->context, assignedids, requestor, l->amaflags, "USTM/%s@%s-%p", l->name, l->parent->name, sub);
5734 if (unistimdebug) {
5735 ast_verb(0, "unistim_new sub=%u (%p) chan=%p line=%s\n", sub->subtype, sub, tmp, l->name);
5736 }
5737 if (!tmp) {
5738 ast_log(LOG_WARNING, "Unable to allocate channel structure\n");
5739 ao2_ref(caps, -1);
5740 return NULL;
5741 }
5742
5744
5745 if (ast_format_cap_count(l->cap)) {
5747 } else {
5749 }
5751 ao2_ref(caps, -1);
5752
5754
5755 if (unistimdebug) {
5756 struct ast_str *native_buf = ast_str_alloca(AST_FORMAT_CAP_NAMES_LEN);
5758 struct ast_str *global_buf = ast_str_alloca(AST_FORMAT_CAP_NAMES_LEN);
5759
5760 ast_verb(0, "Best codec = %s from nativeformats %s (line cap=%s global=%s)\n",
5761 ast_format_get_name(tmpfmt),
5763 ast_format_cap_get_names(l->cap, &cap_buf),
5764 ast_format_cap_get_names(global_cap, &global_buf));
5765 }
5766 if ((sub->rtp) && (sub->subtype == 0)) {
5767 if (unistimdebug) {
5768 ast_verb(0, "New unistim channel with a previous rtp handle ?\n");
5769 }
5772 }
5773 if (sub->rtp) {
5775 }
5776/* tmp->type = type; */
5777 ast_setstate(tmp, state);
5778 if (state == AST_STATE_RING) {
5779 ast_channel_rings_set(tmp, 1);
5780 }
5782
5783 ast_channel_set_writeformat(tmp, tmpfmt);
5784 ast_channel_set_rawwriteformat(tmp, tmpfmt);
5785 ast_channel_set_readformat(tmp, tmpfmt);
5786 ast_channel_set_rawreadformat(tmp, tmpfmt);
5787 ao2_ref(tmpfmt, -1);
5788
5791
5792 if (!ast_strlen_zero(l->parent->language)) {
5793 ast_channel_language_set(tmp, l->parent->language);
5794 }
5795 unistim_set_owner(sub, tmp);
5799 ast_channel_call_forward_set(tmp, l->parent->call_forward);
5800 if (!ast_strlen_zero(l->cid_num)) {
5801 char *name, *loc, *instr;
5802 instr = ast_strdup(l->cid_num);
5803 if (instr) {
5804 ast_callerid_parse(instr, &name, &loc);
5806 ast_free(ast_channel_caller(tmp)->id.number.str);
5808 ast_channel_caller(tmp)->id.name.valid = 1;
5809 ast_free(ast_channel_caller(tmp)->id.name.str);
5811 ast_free(instr);
5812 }
5813 }
5815
5817 ast_channel_unlock(tmp);
5818
5819 if (state != AST_STATE_DOWN) {
5820 if (unistimdebug) {
5821 ast_verb(0, "Starting pbx in unistim_new\n");
5822 }
5823 if (ast_pbx_start(tmp)) {
5824 ast_log(LOG_WARNING, "Unable to start PBX on %s\n", ast_channel_name(tmp));
5825 ast_hangup(tmp);
5826 tmp = NULL;
5827 }
5828 }
5829
5830 return tmp;
5831}
void ast_jb_configure(struct ast_channel *chan, const struct ast_jb_conf *conf)
Configures a jitterbuffer on a channel.
#define ast_strdup(str)
A wrapper for strdup()
Definition astmm.h:241
int ast_callerid_parse(char *instr, char **name, char **location)
Destructively parse inbuf into name and location (or number)
Definition callerid.c:1162
void ast_channel_rings_set(struct ast_channel *chan, int value)
#define ast_channel_alloc(needqueue, state, cid_num, cid_name, acctcode, exten, context, assignedids, requestor, amaflag,...)
Create a channel structure.
Definition channel.h:1299
void ast_channel_nativeformats_set(struct ast_channel *chan, struct ast_format_cap *value)
@ AST_ADSI_UNAVAILABLE
Definition channel.h:891
void ast_channel_set_rawreadformat(struct ast_channel *chan, struct ast_format *format)
void ast_channel_callgroup_set(struct ast_channel *chan, ast_group_t value)
void ast_channel_set_rawwriteformat(struct ast_channel *chan, struct ast_format *format)
struct ast_party_caller * ast_channel_caller(struct ast_channel *chan)
void ast_channel_priority_set(struct ast_channel *chan, int value)
void ast_channel_pickupgroup_set(struct ast_channel *chan, ast_group_t value)
void ast_channel_adsicpe_set(struct ast_channel *chan, enum ast_channel_adsicpe value)
void ast_channel_tech_set(struct ast_channel *chan, const struct ast_channel_tech *value)
@ AST_STATE_RING
size_t ast_format_cap_count(const struct ast_format_cap *cap)
Get the number of formats present within the capabilities structure.
Definition format_cap.c:403
void ast_channel_stage_snapshot_done(struct ast_channel *chan)
Clear flag to indicate channel snapshot is being staged, and publish snapshot.
void ast_channel_stage_snapshot(struct ast_channel *chan)
Set flag to indicate channel snapshot is being staged.
void ast_update_use_count(void)
Notify when usecount has been changed.
Definition loader.c:2707
enum ast_pbx_result ast_pbx_start(struct ast_channel *c)
Create a new thread and start the PBX.
Definition pbx.c:3268
struct ast_party_id id
Caller party ID.
Definition channel.h:422
char cid_num[AST_MAX_EXTENSION]
char exten[AST_MAX_EXTENSION]
ast_group_t pickupgroup
char accountcode[AST_MAX_ACCOUNT_CODE]
ast_group_t callgroup

References unistim_line::accountcode, unistim_line::amaflags, ao2_ref, AST_ADSI_UNAVAILABLE, ast_callerid_parse(), ast_channel_adsicpe_set(), ast_channel_alloc, ast_channel_caller(), ast_channel_callgroup_set(), ast_channel_internal_fd_set(), ast_channel_name(), ast_channel_nativeformats(), ast_channel_nativeformats_set(), ast_channel_pickupgroup_set(), ast_channel_priority_set(), ast_channel_rings_set(), ast_channel_set_rawreadformat(), ast_channel_set_rawwriteformat(), ast_channel_set_readformat(), ast_channel_set_writeformat(), ast_channel_stage_snapshot(), ast_channel_stage_snapshot_done(), ast_channel_tech_pvt_set(), ast_channel_tech_set(), ast_channel_unlock, ast_format_cap_alloc, ast_format_cap_append_from_cap(), ast_format_cap_count(), AST_FORMAT_CAP_FLAG_DEFAULT, ast_format_cap_get_format(), ast_format_cap_get_names(), AST_FORMAT_CAP_NAMES_LEN, ast_format_get_name(), ast_free, ast_hangup(), ast_jb_configure(), ast_log, AST_MEDIA_TYPE_UNKNOWN, ast_pbx_start(), ast_rtp_instance_fd(), ast_setstate(), AST_STATE_DOWN, AST_STATE_RING, ast_str_alloca, ast_strdup, ast_strlen_zero(), ast_update_use_count(), ast_verb, unistim_device::call_forward, unistim_line::callgroup, unistim_line::cap, unistim_line::cid_num, unistim_device::context, unistim_line::exten, global_cap, global_jbconf, ast_party_caller::id, unistim_device::language, LOG_WARNING, unistim_line::name, name, unistim_device::name, ast_party_id::name, NULL, ast_party_id::number, unistim_line::parent, unistim_line::pickupgroup, ast_party_name::str, ast_party_number::str, sub, unistim_set_owner(), unistim_tech, unistimdebug, ast_party_name::valid, and ast_party_number::valid.

Referenced by handle_call_outgoing(), and unistim_request().

◆ unistim_read()

static struct ast_frame * unistim_read ( struct ast_channel ast)
static

Definition at line 5210 of file chan_unistim.c.

5211{
5212 struct ast_frame *fr;
5214
5215 ast_mutex_lock(&sub->lock);
5216 fr = unistim_rtp_read(ast, sub);
5217 ast_mutex_unlock(&sub->lock);
5218
5219 return fr;
5220}
static struct ast_frame * unistim_rtp_read(const struct ast_channel *ast, const struct unistim_subchannel *sub)

References ast_channel_tech_pvt(), ast_mutex_lock, ast_mutex_unlock, sub, and unistim_rtp_read().

◆ unistim_register()

static int unistim_register ( struct unistimsession s)
static

Definition at line 1922 of file chan_unistim.c.

1923{
1924 struct unistim_device *d;
1925
1927 d = devices;
1928 while (d) {
1929 if (!strcasecmp(s->macaddr, d->id)) {
1930 /* XXX Deal with IP authentication */
1931 s->device = d;
1932 d->session = s;
1933 d->codec_number = DEFAULT_CODEC;
1934 d->missed_call = 0;
1935 d->receiver_state = STATE_ONHOOK;
1936 break;
1937 }
1938 d = d->next;
1939 }
1941
1942 if (!d) {
1943 return 0;
1944 }
1945
1946 return 1;
1947}

References ast_mutex_lock, ast_mutex_unlock, d, DEFAULT_CODEC, unistimsession::device, devicelock, devices, unistimsession::macaddr, test_val::next, and STATE_ONHOOK.

Referenced by rcv_mac_addr().

◆ unistim_reload()

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

6252{
6253 switch (cmd) {
6254 case CLI_INIT:
6255 e->command = "unistim reload";
6256 e->usage =
6257 "Usage: unistim reload\n"
6258 " Reloads UNISTIM configuration from unistim.conf\n";
6259 return NULL;
6260
6261 case CLI_GENERATE:
6262 return NULL; /* no completion */
6263 }
6264
6265 if (e && a && a->argc != e->args) {
6266 return CLI_SHOWUSAGE;
6267 }
6268 reload();
6269
6270 return CLI_SUCCESS;
6271}
static int reload(void)

References a, ast_cli_entry::args, CLI_GENERATE, CLI_INIT, CLI_SHOWUSAGE, CLI_SUCCESS, ast_cli_entry::command, NULL, reload(), and ast_cli_entry::usage.

◆ unistim_request()

static struct ast_channel * unistim_request ( const char *  type,
struct ast_format_cap cap,
const struct ast_assigned_ids assignedids,
const struct ast_channel requestor,
const char *  dest,
int *  cause 
)
static

Definition at line 5962 of file chan_unistim.c.

5964{
5965 struct unistim_subchannel *sub, *sub_ring, *sub_trans;
5966 struct unistim_device *d;
5967 struct ast_channel *tmpc = NULL;
5968 char tmp[256];
5969
5972 struct ast_str *global_buf = ast_str_alloca(AST_FORMAT_CAP_NAMES_LEN);
5974 "Asked to get a channel of unsupported format %s while capability is %s\n",
5975 ast_format_cap_get_names(cap, &cap_buf),
5976 ast_format_cap_get_names(global_cap, &global_buf));
5977 return NULL;
5978 }
5979
5980 ast_copy_string(tmp, dest, sizeof(tmp));
5981 if (ast_strlen_zero(tmp)) {
5982 ast_log(LOG_NOTICE, "Unistim channels require a device\n");
5983 return NULL;
5984 }
5986 if (!sub) {
5987 ast_log(LOG_NOTICE, "No available lines on: %s\n", dest);
5988 *cause = AST_CAUSE_CONGESTION;
5989 return NULL;
5990 }
5991 d = sub->parent->parent;
5992 sub_ring = get_sub(d, SUB_RING);
5993 sub_trans = get_sub(d, SUB_THREEWAY);
5994 /* Another request already in progress */
5995 if (!d->session) {
5997 *cause = AST_CAUSE_CONGESTION;
5998 return NULL;
5999 }
6000 if (sub_ring || sub_trans) {
6001 if (unistimdebug) {
6002 ast_verb(0, "Can't create channel, request already in progress: Busy!\n");
6003 }
6005 *cause = AST_CAUSE_BUSY;
6006 return NULL;
6007 }
6008 if (d->session->state == STATE_DIALPAGE) {
6009 if (unistimdebug) {
6010 ast_verb(0, "Can't create channel, user on dialpage: Busy!\n");
6011 }
6013 *cause = AST_CAUSE_BUSY;
6014 return NULL;
6015 }
6016
6017 if (get_avail_softkey(d->session, sub->parent->name) == -1) {
6018 if (unistimdebug) {
6019 ast_verb(0, "Can't create channel for line %s, all lines busy\n", sub->parent->name);
6020 }
6022 *cause = AST_CAUSE_BUSY;
6023 return NULL;
6024 }
6025 sub->subtype = SUB_RING;
6026 sub->softkey = -1;
6027
6029 tmpc = unistim_new(sub, AST_STATE_DOWN, assignedids, requestor);
6030 if (!tmpc) {
6031 ast_log(LOG_WARNING, "Unable to make channel for '%s'\n", tmp);
6032 }
6033 if (unistimdebug) {
6034 ast_verb(0, "unistim_request owner = %p\n", sub->owner);
6035 }
6037 /* and finish */
6038 return tmpc;
6039}
#define AST_CAUSE_CONGESTION
Definition causes.h:153
#define AST_CAUSE_BUSY
Definition causes.h:149
static struct unistim_subchannel * find_subchannel_by_name(const char *dest)
int ast_format_cap_iscompatible(const struct ast_format_cap *cap1, const struct ast_format_cap *cap2)
Determine if any joint capabilities exist between two capabilities structures.
Definition format_cap.c:661

References AST_CAUSE_BUSY, AST_CAUSE_CONGESTION, ast_copy_string(), ast_format_cap_append_from_cap(), ast_format_cap_get_names(), ast_format_cap_iscompatible(), AST_FORMAT_CAP_NAMES_LEN, ast_log, AST_MEDIA_TYPE_UNKNOWN, AST_STATE_DOWN, ast_str_alloca, ast_strlen_zero(), ast_verb, d, find_subchannel_by_name(), get_avail_softkey(), get_sub(), global_cap, LOG_NOTICE, LOG_WARNING, NULL, restart_monitor(), STATE_DIALPAGE, sub, SUB_RING, SUB_THREEWAY, unistim_new(), unistim_unalloc_sub(), and unistimdebug.

◆ unistim_rtp_read()

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

Definition at line 5155 of file chan_unistim.c.

5157{
5158 /* Retrieve audio/etc from channel. Assumes sub->lock is already held. */
5159 struct ast_frame *f;
5160
5161 if (!ast) {
5162 ast_log(LOG_WARNING, "Channel NULL while reading\n");
5163 return &ast_null_frame;
5164 }
5165
5166 if (!sub->rtp) {
5167 ast_log(LOG_WARNING, "RTP handle NULL while reading on subchannel %u\n",
5168 sub->subtype);
5169 return &ast_null_frame;
5170 }
5171
5172 switch (ast_channel_fdno(ast)) {
5173 case 0:
5174 f = ast_rtp_instance_read(sub->rtp, 0); /* RTP Audio */
5175 break;
5176 case 1:
5177 f = ast_rtp_instance_read(sub->rtp, 1); /* RTCP Control Channel */
5178 break;
5179 default:
5180 f = &ast_null_frame;
5181 }
5182
5183 if (sub->owner) {
5184 /* We already hold the channel lock */
5185 if (f->frametype == AST_FRAME_VOICE) {
5188 struct ast_format_cap *caps;
5189
5190 ast_debug(1,
5191 "Oooh, format changed from %s to %s\n",
5194
5196 if (caps) {
5198 ast_channel_nativeformats_set(sub->owner, caps);
5199 ao2_ref(caps, -1);
5200 }
5203 }
5204 }
5205 }
5206
5207 return f;
5208}
int ast_channel_fdno(const struct ast_channel *chan)
int ast_set_read_format(struct ast_channel *chan, struct ast_format *format)
Sets read format on channel chan.
Definition channel.c:5785
struct ast_format * ast_channel_writeformat(struct ast_channel *chan)
int ast_set_write_format(struct ast_channel *chan, struct ast_format *format)
Sets write format on channel chan.
Definition channel.c:5826
struct ast_frame ast_null_frame
Definition main/frame.c:79
struct ast_frame * ast_rtp_instance_read(struct ast_rtp_instance *instance, int rtcp)
Receive a frame over RTP.
Definition rtp_engine.c:629
struct ast_format * format
struct ast_frame_subclass subclass

References ao2_ref, ast_channel_fdno(), ast_channel_nativeformats(), ast_channel_nativeformats_set(), ast_channel_readformat(), ast_channel_writeformat(), ast_debug, ast_format_cap_alloc, ast_format_cap_append, AST_FORMAT_CAP_FLAG_DEFAULT, ast_format_cap_get_names(), ast_format_cap_iscompatible_format(), AST_FORMAT_CAP_NAMES_LEN, AST_FORMAT_CMP_NOT_EQUAL, ast_format_get_name(), AST_FRAME_VOICE, ast_log, ast_null_frame, ast_rtp_instance_read(), ast_set_read_format(), ast_set_write_format(), ast_str_alloca, ast_frame_subclass::format, ast_frame::frametype, LOG_WARNING, sub, and ast_frame::subclass.

Referenced by unistim_read().

◆ unistim_send_mwi_to_peer()

static int unistim_send_mwi_to_peer ( struct unistim_line peer,
unsigned int  tick 
)
static

Definition at line 5681 of file chan_unistim.c.

5682{
5683 int new;
5684 RAII_VAR(struct stasis_message *, msg, NULL, ao2_cleanup);
5685
5687 if (msg) {
5688 struct ast_mwi_state *mwi_state = stasis_message_data(msg);
5689 new = mwi_state->new_msgs;
5690 } else { /* Fall back on checking the mailbox directly */
5691 new = ast_app_has_voicemail(peer->mailbox, NULL);
5692 }
5693 ast_debug(3, "MWI Status for mailbox %s is %d, lastmsgsent:%d\n",
5694 peer->mailbox, new, peer->parent->lastmsgssent);
5695 peer->parent->nextmsgcheck = tick + TIMER_MWI;
5696
5697 /* Return now if it's the same thing we told them last time */
5698 if ((peer->parent->session->state != STATE_MAINPAGE) || (new == peer->parent->lastmsgssent)) {
5699 return 0;
5700 }
5701
5702 peer->parent->lastmsgssent = new;
5704
5705 return 0;
5706}
#define TIMER_MWI
#define LED_BAR_ON
int ast_app_has_voicemail(const char *mailboxes, const char *folder)
Determine if a given mailbox has any voicemail If folder is NULL, defaults to "INBOX"....
Definition main/app.c:582
struct stasis_message_type * ast_mwi_state_type(void)
Get the Stasis Message Bus API message type for MWI messages.
struct stasis_cache * ast_mwi_state_cache(void)
Backend cache for ast_mwi_topic_cached().
Definition mwi.c:94
void * stasis_message_data(const struct stasis_message *msg)
Get the data contained in a message.
struct stasis_message * stasis_cache_get(struct stasis_cache *cache, struct stasis_message_type *type, const char *id)
Retrieve an item from the cache for the ast_eid_default entity.
The structure that contains MWI state.
Definition mwi.h:455
int new_msgs
Definition mwi.h:459

References ao2_cleanup, ast_app_has_voicemail(), ast_debug, ast_mwi_state_cache(), ast_mwi_state_type(), unistim_device::lastmsgssent, LED_BAR_OFF, LED_BAR_ON, unistim_line::mailbox, ast_mwi_state::new_msgs, unistim_device::nextmsgcheck, NULL, unistim_line::parent, RAII_VAR, send_led_update(), unistim_device::session, stasis_cache_get(), stasis_message_data(), unistimsession::state, STATE_MAINPAGE, and TIMER_MWI.

Referenced by do_monitor().

◆ unistim_senddigit_begin()

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

Definition at line 5515 of file chan_unistim.c.

5516{
5517 struct unistimsession *pte = channel_to_session(ast);
5518
5519 if (!pte) {
5520 return -1;
5521 }
5522 return send_dtmf_tone(pte, digit);
5523}

References channel_to_session(), digit, and send_dtmf_tone().

◆ unistim_senddigit_end()

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

Definition at line 5525 of file chan_unistim.c.

5526{
5527 struct unistimsession *pte = channel_to_session(ast);
5528
5529 if (!pte) {
5530 return -1;
5531 }
5532
5533 if (unistimdebug) {
5534 ast_verb(0, "Send Digit off %c (duration %d)\n", digit, duration);
5535 }
5536 send_tone(pte, 0, 0);
5537 return 0;
5538}

References ast_verb, channel_to_session(), digit, send_tone(), and unistimdebug.

◆ unistim_sendtext()

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

Definition at line 5542 of file chan_unistim.c.

5543{
5544 struct unistimsession *pte = channel_to_session(ast);
5545 int size;
5546 char tmp[TEXT_LENGTH_MAX + 1];
5547
5548 if (unistimdebug) {
5549 ast_verb(0, "unistim_sendtext called\n");
5550 }
5551 if (!text) {
5552 ast_log(LOG_WARNING, "unistim_sendtext called with a null text\n");
5553 return -1;
5554 }
5555
5556 if (!pte) {
5557 return -1;
5558 }
5559
5560 size = strlen(text);
5561 if (text[0] == '@') {
5562 int pos = 0, i = 1, tok = 0, sz = 0;
5563 char label[11];
5564 char number[16];
5565 char icon = '\0';
5566 char cur = '\0';
5567
5568 memset(label, 0, 11);
5569 memset(number, 0, 16);
5570 while (text[i]) {
5571 cur = text[i++];
5572 switch (tok) {
5573 case 0:
5574 if ((cur < '0') && (cur > '5')) {
5576 "sendtext failed : position must be a number between 0 and 5\n");
5577 return 1;
5578 }
5579 pos = cur - '0';
5580 tok = 1;
5581 continue;
5582 case 1:
5583 if (cur != '@') {
5584 ast_log(LOG_WARNING, "sendtext failed : invalid position\n");
5585 return 1;
5586 }
5587 tok = 2;
5588 continue;
5589 case 2:
5590 if ((cur < '3') && (cur > '6')) {
5592 "sendtext failed : icon must be a number between 32 and 63 (first digit invalid)\n");
5593 return 1;
5594 }
5595 icon = (cur - '0') * 10;
5596 tok = 3;
5597 continue;
5598 case 3:
5599 if ((cur < '0') && (cur > '9')) {
5601 "sendtext failed : icon must be a number between 32 and 63 (second digit invalid)\n");
5602 return 1;
5603 }
5604 icon += (cur - '0');
5605 tok = 4;
5606 continue;
5607 case 4:
5608 if (cur != '@') {
5610 "sendtext failed : icon must be a number between 32 and 63 (too many digits)\n");
5611 return 1;
5612 }
5613 tok = 5;
5614 continue;
5615 case 5:
5616 if (cur == '@') {
5617 tok = 6;
5618 sz = 0;
5619 continue;
5620 }
5621 if (sz > 10) {
5622 continue;
5623 }
5624 label[sz] = cur;
5625 sz++;
5626 continue;
5627 case 6:
5628 if (sz > 15) {
5630 "sendtext failed : extension too long = %d (15 car max)\n",
5631 sz);
5632 return 1;
5633 }
5634 number[sz] = cur;
5635 sz++;
5636 continue;
5637 }
5638 }
5639 if (tok != 6) {
5640 ast_log(LOG_WARNING, "sendtext failed : incomplet command\n");
5641 return 1;
5642 }
5643 if (!pte->device) {
5644 ast_log(LOG_WARNING, "sendtext failed : no device ?\n");
5645 return 1;
5646 }
5647 strcpy(pte->device->softkeylabel[pos], label);
5648 strcpy(pte->device->softkeynumber[pos], number);
5649 pte->device->softkeyicon[pos] = icon;
5650 send_favorite(pos, icon, pte, label);
5651 return 0;
5652 }
5653
5654 if (size <= TEXT_LENGTH_MAX * 2) {
5655 if (pte->device->height == 1) {
5656 send_text(TEXT_LINE0, TEXT_NORMAL, pte, text);
5657 } else {
5658 send_text(TEXT_LINE0, TEXT_NORMAL, pte, ustmtext("Message :", pte));
5659 send_text(TEXT_LINE1, TEXT_NORMAL, pte, text);
5660 }
5661 if (size <= TEXT_LENGTH_MAX) {
5662 send_text(TEXT_LINE2, TEXT_NORMAL, pte, "");
5663 return 0;
5664 }
5665 memcpy(tmp, text + TEXT_LENGTH_MAX, TEXT_LENGTH_MAX);
5666 tmp[sizeof(tmp) - 1] = '\0';
5667 send_text(TEXT_LINE2, TEXT_NORMAL, pte, tmp);
5668 return 0;
5669 }
5670 send_text(TEXT_LINE0, TEXT_NORMAL, pte, text);
5671 memcpy(tmp, text + TEXT_LENGTH_MAX, TEXT_LENGTH_MAX);
5672 tmp[sizeof(tmp) - 1] = '\0';
5673 send_text(TEXT_LINE1, TEXT_NORMAL, pte, tmp);
5674 memcpy(tmp, text + TEXT_LENGTH_MAX * 2, TEXT_LENGTH_MAX);
5675 tmp[sizeof(tmp) - 1] = '\0';
5676 send_text(TEXT_LINE2, TEXT_NORMAL, pte, tmp);
5677 return 0;
5678}

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, TEXT_LENGTH_MAX, TEXT_LINE0, TEXT_LINE1, TEXT_LINE2, TEXT_NORMAL, unistimdebug, and ustmtext().

◆ unistim_set_owner()

static void unistim_set_owner ( struct unistim_subchannel sub,
struct ast_channel chan 
)
static

Definition at line 5833 of file chan_unistim.c.

5834{
5835 sub->owner = chan;
5836 if (sub->rtp) {
5837 ast_rtp_instance_set_channel_id(sub->rtp, sub->owner ? ast_channel_uniqueid(sub->owner) : "");
5838 }
5839}

References ast_channel_uniqueid(), ast_rtp_instance_set_channel_id(), and sub.

Referenced by unistim_fixup(), unistim_hangup_clean(), and unistim_new().

◆ unistim_set_rtp_peer()

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,
const struct ast_format_cap codecs,
int  nat_active 
)
static

Definition at line 7051 of file chan_unistim.c.

7052{
7054 struct sockaddr_in them = { 0, };
7055 struct sockaddr_in us = { 0, };
7056
7057 if (!rtp) {
7058 return 0;
7059 }
7060
7061 sub = (struct unistim_subchannel *) ast_channel_tech_pvt(chan);
7062 if (!sub) {
7063 ast_log(LOG_ERROR, "No Private Structure, this is bad\n");
7064 return -1;
7065 }
7066 {
7067 struct ast_sockaddr tmp;
7069 ast_sockaddr_to_sin(&tmp, &them);
7071 ast_sockaddr_to_sin(&tmp, &us);
7072 }
7073
7074 /* TODO: Set rtp on phone in case of direct rtp (not implemented) */
7075
7076 return 0;
7077}

References ast_channel_tech_pvt(), ast_log, ast_rtp_instance_get_local_address(), ast_rtp_instance_get_remote_address, ast_sockaddr_to_sin, LOG_ERROR, and sub.

◆ unistim_show_devices()

static char * unistim_show_devices ( struct ast_cli_entry e,
int  cmd,
struct ast_cli_args a 
)
static

Definition at line 6123 of file chan_unistim.c.

6124{
6125 struct unistim_device *device = devices;
6126
6127 switch (cmd) {
6128 case CLI_INIT:
6129 e->command = "unistim show devices";
6130 e->usage =
6131 "Usage: unistim show devices\n"
6132 " Lists all known Unistim devices.\n";
6133 return NULL;
6134 case CLI_GENERATE:
6135 return NULL; /* no completion */
6136 }
6137
6138 if (a->argc != e->args)
6139 return CLI_SHOWUSAGE;
6140
6141 ast_cli(a->fd, "%-20.20s %-20.20s %-15.15s %-15.15s %s\n", "Name/username", "MAC", "Host", "Firmware", "Status");
6143 while (device) {
6144 ast_cli(a->fd, "%-20.20s %-20.20s %-15.15s %-15.15s %s\n",
6145 device->name, device->id,
6146 (!device->session) ? "(Unspecified)" : ast_inet_ntoa(device->session->sin.sin_addr),
6147 (!device->session) ? "(Unspecified)" : device->session->firmware,
6148 (!device->session) ? "UNKNOWN" : "OK");
6149 device = device->next;
6150 }
6152
6153 return CLI_SUCCESS;
6154}

References a, ast_cli_entry::args, ast_cli(), ast_inet_ntoa(), ast_mutex_lock, ast_mutex_unlock, CLI_GENERATE, CLI_INIT, CLI_SHOWUSAGE, CLI_SUCCESS, ast_cli_entry::command, devicelock, devices, unistimsession::firmware, unistim_device::id, unistim_device::name, unistim_device::next, NULL, unistim_device::session, unistimsession::sin, and ast_cli_entry::usage.

◆ unistim_show_info()

static char * unistim_show_info ( struct ast_cli_entry e,
int  cmd,
struct ast_cli_args a 
)
static

Definition at line 6041 of file chan_unistim.c.

6042{
6043 struct unistim_device *device = devices;
6044 struct unistim_line *line;
6045 struct unistim_subchannel *sub;
6046 struct unistimsession *s;
6048
6049 switch (cmd) {
6050 case CLI_INIT:
6051 e->command = "unistim show info";
6052 e->usage =
6053 "Usage: unistim show info\n"
6054 " Dump internal structures.\n\n"
6055 " device\n"
6056 " ->line\n"
6057 " -->sub\n"
6058 " ==>key\n";
6059 return NULL;
6060
6061 case CLI_GENERATE:
6062 return NULL; /* no completion */
6063 }
6064
6065 if (a->argc != e->args) {
6066 return CLI_SHOWUSAGE;
6067 }
6068 ast_cli(a->fd, "Dumping internal structures:\n");
6070 while (device) {
6071 int i;
6072
6073 ast_cli(a->fd, "\nname=%s id=%s ha=%p sess=%p device=%p selected=%d height=%d\n",
6074 device->name, device->id, device->ha, device->session,
6075 device, device->selected, device->height);
6076 AST_LIST_LOCK(&device->lines);
6077 AST_LIST_TRAVERSE(&device->lines,line,list) {
6078 ast_cli(a->fd,
6079 "->name=%s fullname=%s exten=%s callid=%s cap=%s line=%p\n",
6080 line->name, line->fullname, line->exten, line->cid_num,
6081 ast_format_cap_get_names(line->cap, &cap_buf), line);
6082 }
6083 AST_LIST_UNLOCK(&device->lines);
6084
6085 AST_LIST_LOCK(&device->subs);
6086 AST_LIST_TRAVERSE(&device->subs, sub, list) {
6087 if (!sub) {
6088 continue;
6089 }
6090 ast_cli(a->fd,
6091 "-->subtype=%s chan=%p rtp=%p line=%p alreadygone=%d softkey=%d\n",
6092 subtype_tostr(sub->subtype), sub->owner, sub->rtp, sub->parent,
6093 sub->alreadygone, sub->softkey);
6094 }
6095 AST_LIST_UNLOCK(&device->subs);
6096
6097 for (i = 0; i < FAVNUM; i++) {
6098 if (!soft_key_visible(device, i)) {
6099 continue;
6100 }
6101 ast_cli(a->fd, "==> %d. dev=%s icon=%#-4x label=%-10s number=%-5s sub=%p line=%p\n",
6102 i, device->softkeydevice[i], (unsigned)device->softkeyicon[i], device->softkeylabel[i], device->softkeynumber[i],
6103 device->ssub[i], device->sline[i]);
6104 }
6105 device = device->next;
6106 }
6108 ast_cli(a->fd, "\nSessions:\n");
6110 s = sessions;
6111 while (s) {
6112 ast_cli(a->fd,
6113 "sin=%s timeout=%d state=%s macaddr=%s device=%p session=%p\n",
6114 ast_inet_ntoa(s->sin.sin_addr), s->timeout, ptestate_tostr(s->state), s->macaddr,
6115 s->device, s);
6116 s = s->next;
6117 }
6119
6120 return CLI_SUCCESS;
6121}
static const char * subtype_tostr(const int type)
struct ast_ha * ha
char softkeydevice[FAVNUM][16]

References a, ast_cli_entry::args, ast_cli(), ast_format_cap_get_names(), AST_FORMAT_CAP_NAMES_LEN, ast_inet_ntoa(), AST_LIST_LOCK, AST_LIST_TRAVERSE, AST_LIST_UNLOCK, ast_mutex_lock, ast_mutex_unlock, ast_str_alloca, unistim_line::cap, unistim_line::cid_num, CLI_GENERATE, CLI_INIT, CLI_SHOWUSAGE, CLI_SUCCESS, ast_cli_entry::command, unistimsession::device, devicelock, devices, unistim_line::exten, FAVNUM, unistim_line::fullname, unistim_device::ha, unistim_device::height, unistim_device::id, unistim_device::lines, unistimsession::macaddr, unistim_line::name, unistim_device::name, unistim_device::next, unistimsession::next, NULL, ptestate_tostr(), unistim_device::selected, unistim_device::session, sessionlock, sessions, unistimsession::sin, unistim_device::sline, soft_key_visible(), unistim_device::softkeydevice, unistim_device::softkeyicon, unistim_device::softkeylabel, unistim_device::softkeynumber, unistim_device::ssub, unistimsession::state, sub, unistim_device::subs, subtype_tostr(), unistimsession::timeout, and ast_cli_entry::usage.

◆ unistim_sp()

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

Definition at line 6156 of file chan_unistim.c.

6157{
6158 BUFFSEND;
6159 struct unistim_subchannel *sub;
6160 int i, j = 0, len;
6161 unsigned char c, cc;
6162 char tmp[256];
6163
6164 switch (cmd) {
6165 case CLI_INIT:
6166 e->command = "unistim send packet";
6167 e->usage =
6168 "Usage: unistim send packet USTM/line@name hexa\n"
6169 " unistim send packet USTM/1000@hans 19040004\n";
6170 return NULL;
6171
6172 case CLI_GENERATE:
6173 return NULL; /* no completion */
6174 }
6175
6176 if (a->argc < 5) {
6177 return CLI_SHOWUSAGE;
6178 }
6179 if (strlen(a->argv[3]) < 9) {
6180 return CLI_SHOWUSAGE;
6181 }
6182 len = strlen(a->argv[4]);
6183 if (len % 2) {
6184 return CLI_SHOWUSAGE;
6185 }
6186 ast_copy_string(tmp, a->argv[3] + 5, sizeof(tmp));
6188 if (!sub) {
6189 ast_cli(a->fd, "Can't find '%s'\n", tmp);
6190 return CLI_SUCCESS;
6191 }
6192 if (!sub->parent->parent->session) {
6193 ast_cli(a->fd, "'%s' is not connected\n", tmp);
6194 return CLI_SUCCESS;
6195 }
6196 ast_cli(a->fd, "Sending '%s' to %s (%p)\n", a->argv[4], tmp, sub->parent->parent->session);
6197 for (i = 0; i < len; i++) {
6198 c = a->argv[4][i];
6199 if (c >= 'a') {
6200 c -= 'a' - 10;
6201 } else {
6202 c -= '0';
6203 }
6204 i++;
6205 cc = a->argv[4][i];
6206 if (cc >= 'a') {
6207 cc -= 'a' - 10;
6208 } else {
6209 cc -= '0';
6210 }
6211 tmp[j++] = (c << 4) | cc;
6212 }
6213 memcpy(buffsend + SIZE_HEADER, tmp, j);
6214 send_client(SIZE_HEADER + j, buffsend, sub->parent->parent->session);
6215 return CLI_SUCCESS;
6216}

References a, ast_cli(), ast_copy_string(), BUFFSEND, c, CLI_GENERATE, CLI_INIT, CLI_SHOWUSAGE, CLI_SUCCESS, ast_cli_entry::command, find_subchannel_by_name(), len(), NULL, send_client(), SIZE_HEADER, sub, and ast_cli_entry::usage.

◆ unistim_ss()

static void * unistim_ss ( void *  data)
static

Definition at line 2661 of file chan_unistim.c.

2662{
2663 struct ast_channel *chan = data;
2665 struct unistim_line *l = sub->parent;
2666 struct unistimsession *s = l->parent->session;
2667 int res;
2668
2669 if (!s) {
2670 return NULL;
2671 }
2672 ast_verb(3, "Starting switch on '%s@%s-%d' to %s\n", l->name, l->parent->name, sub->softkey, s->device->phone_number);
2673 ast_channel_lock(chan);
2676 ast_channel_unlock(chan);
2678 sizeof(s->device->redial_number));
2679 res = ast_pbx_run(chan);
2680 if (res) {
2681 ast_log(LOG_WARNING, "PBX exited non-zero\n");
2682 send_tone(s, 1000, 0);
2683 }
2684 return NULL;
2685}
void ast_channel_exten_set(struct ast_channel *chan, const char *value)
enum ast_pbx_result ast_pbx_run(struct ast_channel *c)
Execute the PBX in the current thread.
Definition pbx.c:3315
const char * data

References ast_channel_exten_set(), ast_channel_lock, ast_channel_tech_pvt(), ast_channel_unlock, ast_copy_string(), ast_log, ast_pbx_run(), ast_setstate(), AST_STATE_RING, ast_verb, ast_channel::data, unistimsession::device, LOG_WARNING, unistim_line::name, unistim_device::name, NULL, unistim_line::parent, unistim_device::phone_number, unistim_device::redial_number, send_tone(), unistim_device::session, and sub.

Referenced by handle_call_outgoing().

◆ unistim_unalloc_sub()

static int unistim_unalloc_sub ( struct unistim_device d,
struct unistim_subchannel sub 
)
static

Definition at line 2009 of file chan_unistim.c.

2010{
2011 struct unistim_subchannel *s;
2012
2013 AST_LIST_LOCK(&d->subs);
2014 AST_LIST_TRAVERSE_SAFE_BEGIN(&d->subs, s, list) {
2015 if (!s) {
2016 continue;
2017 }
2018 if (s != sub) {
2019 continue;
2020 }
2023 }
2025 AST_LIST_UNLOCK(&d->subs);
2026 return 0;
2027}

References AST_LIST_LOCK, AST_LIST_REMOVE_CURRENT, AST_LIST_TRAVERSE_SAFE_BEGIN, AST_LIST_TRAVERSE_SAFE_END, AST_LIST_UNLOCK, d, unistim_subchannel::list, sub, and unistim_free_sub().

Referenced by unistim_hangup(), and unistim_request().

◆ unistim_write()

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

Definition at line 5222 of file chan_unistim.c.

5223{
5225 int res = 0;
5226
5227 if (frame->frametype != AST_FRAME_VOICE) {
5228 if (frame->frametype == AST_FRAME_IMAGE) {
5229 return 0;
5230 } else {
5231 ast_log(LOG_WARNING, "Can't send %u type frames with unistim_write\n",
5232 frame->frametype);
5233 return 0;
5234 }
5235 } else {
5238
5240 "Asked to transmit frame type %s, while native formats is %s (read/write = (%s/%s)\n",
5245 return -1;
5246 }
5247 }
5248
5249 if (sub) {
5250 ast_mutex_lock(&sub->lock);
5251 if (sub->rtp) {
5252 res = ast_rtp_instance_write(sub->rtp, frame);
5253 }
5254 ast_mutex_unlock(&sub->lock);
5255 }
5256
5257 return res;
5258}
int ast_rtp_instance_write(struct ast_rtp_instance *instance, struct ast_frame *frame)
Send a frame out over RTP.
Definition rtp_engine.c:619

References ast_channel_nativeformats(), ast_channel_readformat(), ast_channel_tech_pvt(), ast_channel_writeformat(), ast_format_cap_get_names(), ast_format_cap_iscompatible_format(), AST_FORMAT_CAP_NAMES_LEN, AST_FORMAT_CMP_NOT_EQUAL, ast_format_get_name(), AST_FRAME_IMAGE, AST_FRAME_VOICE, ast_log, ast_mutex_lock, ast_mutex_unlock, ast_rtp_instance_write(), ast_str_alloca, ast_frame_subclass::format, ast_frame::frametype, LOG_WARNING, sub, and ast_frame::subclass.

◆ unistimsock_read()

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

Definition at line 5097 of file chan_unistim.c.

5098{
5099 struct sockaddr_in addr_from = { 0, };
5100 struct unistimsession *cur = NULL;
5101 int found = 0;
5102 int dw_num_bytes_rcvd;
5103 unsigned int size_addr_from;
5104#ifdef DUMP_PACKET
5105 int dw_num_bytes_rcvdd;
5106#endif
5107
5108 size_addr_from = sizeof(addr_from);
5109 dw_num_bytes_rcvd =
5110 recvfrom(unistimsock, buff, SIZE_PAGE, 0, (struct sockaddr *) &addr_from,
5111 &size_addr_from);
5112 if (dw_num_bytes_rcvd == -1) {
5113 if (errno == EAGAIN) {
5114 ast_log(LOG_NOTICE, "UNISTIM: Received packet with bad UDP checksum\n");
5115 } else if (errno != ECONNREFUSED) {
5116 ast_log(LOG_WARNING, "Recv error %d (%s)\n", errno, strerror(errno));
5117 }
5118 return 1;
5119 }
5120
5121 /* Looking in the phone list if we already have a registration for him */
5123 cur = sessions;
5124 while (cur) {
5125 if (cur->sin.sin_addr.s_addr == addr_from.sin_addr.s_addr) {
5126 found = 1;
5127 break;
5128 }
5129 cur = cur->next;
5130 }
5132
5133#ifdef DUMP_PACKET
5134 if (unistimdebug)
5135 ast_verb(0, "\n*** Dump %d bytes from %s - phone_table[%d] ***\n",
5136 dw_num_bytes_rcvd, ast_inet_ntoa(addr_from.sin_addr), tmp);
5137 for (dw_num_bytes_rcvdd = 0; dw_num_bytes_rcvdd < dw_num_bytes_rcvd;
5138 dw_num_bytes_rcvdd++)
5139 ast_verb(0, "%02hhx ", buff[dw_num_bytes_rcvdd]);
5140 ast_verb(0, "\n******************************************\n");
5141#endif
5142
5143 if (!found) {
5144 if (unistimdebug) {
5145 ast_verb(0, "Received a packet from an unknown source\n");
5146 }
5147 parsing(dw_num_bytes_rcvd, buff, NULL, (struct sockaddr_in *) &addr_from);
5148
5149 } else {
5150 parsing(dw_num_bytes_rcvd, buff, cur, (struct sockaddr_in *) &addr_from);
5151 }
5152 return 1;
5153}
static void parsing(int size, unsigned char *buf, struct unistimsession *pte, struct sockaddr_in *addr_from)

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

Referenced by do_monitor().

◆ unload_module()

static int unload_module ( void  )
static

Definition at line 7157 of file chan_unistim.c.

7158{
7159 /* First, take us out of the channel loop */
7160 if (sched) {
7162 }
7163
7165
7169
7172 pthread_cancel(monitor_thread);
7173 pthread_kill(monitor_thread, SIGURG);
7174 pthread_join(monitor_thread, NULL);
7175 }
7178
7179 if (buff) {
7180 ast_free(buff);
7181 }
7182 if (unistimsock > -1) {
7183 close(unistimsock);
7184 }
7185 ao2_ref(global_cap, -1);
7186
7187 return 0;
7188}
void ast_cli_unregister_multiple(void)
Definition ael_main.c:408
void ast_channel_unregister(const struct ast_channel_tech *tech)
Unregister a channel technology.
Definition channel.c:571
int ast_rtp_glue_unregister(struct ast_rtp_glue *glue)
Unregister RTP glue.
Definition rtp_engine.c:418

References ao2_cleanup, ao2_ref, 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(), ast_sched_context_destroy(), buff, ast_channel_tech::capabilities, global_cap, monitor_thread, monlock, NULL, unistim_cli, unistim_rtp_glue, unistim_tech, and unistimsock.

◆ unquote()

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

Definition at line 6281 of file chan_unistim.c.

6282{
6283 int len = strlen(src);
6284 if (!len) {
6285 return;
6286 }
6287 if ((len > 1) && src[0] == '\"') {
6288 /* This is a quoted string */
6289 src++;
6290 /* Don't take more than what's there */
6291 len--;
6292 if (maxlen > len - 1) {
6293 maxlen = len - 1;
6294 }
6295 memcpy(out, src, maxlen);
6296 ((char *) out)[maxlen] = '\0';
6297 } else {
6298 memcpy(out, src, maxlen);
6299 }
6300 return;
6301}
FILE * out
Definition utils/frame.c:33

References len(), and out.

Referenced by build_device().

◆ unregister_extension()

static int unregister_extension ( const struct unistimsession pte)
static

Definition at line 1461 of file chan_unistim.c.

1462{
1463 if (unistimdebug) {
1464 ast_verb(0, "Trying to unregister extension '%s' context '%s'\n",
1465 pte->device->extension_number, pte->device->context);
1466 }
1468 pte->device->extension_number, 1, "Unistim");
1469}
int ast_context_remove_extension(const char *context, const char *extension, int priority, const char *registrar)
Simply remove extension from context.
Definition pbx.c:3508

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

Referenced by close_client(), and key_main_page().

◆ ustmtext()

static const char * ustmtext ( const char *  str,
struct unistimsession pte 
)
static

Definition at line 802 of file chan_unistim.c.

803{
804 struct ustm_lang_entry *lang_entry;
805 struct ustm_lang_entry le_search;
806 struct unistim_languages *lang = NULL;
807 int size;
808
809 if (pte->device) {
811 }
812 if (!lang) {
813 return str;
814 }
815 /* Check if specified language exists */
816 if (!lang->trans) {
817 char tmp[1024], *p, *p_orig = NULL, *p_trans = NULL;
818 FILE *f;
819
822 if (!lang->trans) {
823 ast_log(LOG_ERROR, "Unable to allocate container for translation!\n");
824 return str;
825 }
826 snprintf(tmp, sizeof(tmp), "%s/%s/%s.po", ast_config_AST_VAR_DIR,
828 f = fopen(tmp, "r");
829 if (!f) {
830 ast_log(LOG_WARNING, "There is no translation file for '%s'\n", lang->lang_short);
831 return str;
832 }
833 while (fgets(tmp, sizeof(tmp), f)) {
834 if (!(p = strchr(tmp, '\n'))) {
835 ast_log(LOG_ERROR, "Too long line found in language file - truncated!\n");
836 continue;
837 }
838 *p = '\0';
839 if (!(p = strchr(tmp, '"'))) {
840 continue;
841 }
842 if (tmp == strstr(tmp, "msgid")) {
843 p_orig = ast_strdup(p + 1);
844 p = strchr(p_orig, '"');
845 } else if (tmp == strstr(tmp, "msgstr")) {
846 p_trans = ast_strdup(p + 1);
847 p = strchr(p_trans, '"');
848 } else {
849 continue;
850 }
851 *p = '\0';
852 if (!p_trans || !p_orig) {
853 continue;
854 }
855 if (ast_strlen_zero(p_trans)) {
856 ast_free(p_trans);
857 ast_free(p_orig);
858 p_trans = NULL;
859 p_orig = NULL;
860 continue;
861 }
862 if (!(lang_entry = ao2_alloc(sizeof(*lang_entry), NULL))) {
863 fclose(f);
864 return str;
865 }
866
867 lang_entry->str_trans = p_trans;
868 lang_entry->str_orig = p_orig;
869 ao2_link(lang->trans, lang_entry);
870 p_trans = NULL;
871 p_orig = NULL;
872 }
873
874 fclose(f);
875 }
876
877 le_search.str_orig = str;
878 if ((lang_entry = ao2_find(lang->trans, &le_search, OBJ_POINTER))) {
879 size = strlen(lang_entry->str_trans)+1;
880 if (size > 1024) {
881 size = 1024;
882 }
883 memcpy(ustm_strcopy, lang_entry->str_trans, size);
884 ao2_ref(lang_entry, -1);
885 return ustm_strcopy;
886 }
887
888 return str;
889}
const char * str
Definition app_jack.c:150
#define ao2_link(container, obj)
Add an object to a container.
Definition astobj2.h:1532
#define OBJ_POINTER
Definition astobj2.h:1150
@ AO2_ALLOC_OPT_LOCK_MUTEX
Definition astobj2.h:363
#define ao2_find(container, arg, flags)
Definition astobj2.h:1736
#define ao2_alloc(data_size, destructor_fn)
Definition astobj2.h:409
#define ao2_container_alloc_hash(ao2_options, container_options, n_buckets, hash_fn, sort_fn, cmp_fn)
Allocate and initialize a hash container with the desired number of buckets.
Definition astobj2.h:1303
static int lang_hash_fn(const void *obj, const int flags)
static int lang_cmp_fn(void *obj, void *arg, int flags)
static char ustm_strcopy[1024]
#define USTM_LANG_DIR
const char * ast_config_AST_VAR_DIR
Definition options.c:158
struct ao2_container * trans
const char * str_trans

References ao2_alloc, AO2_ALLOC_OPT_LOCK_MUTEX, ao2_container_alloc_hash, ao2_find, ao2_link, ao2_ref, ast_config_AST_VAR_DIR, ast_free, ast_log, ast_strdup, ast_strlen_zero(), unistimsession::device, find_language(), lang_cmp_fn(), lang_hash_fn(), unistim_languages::lang_short, unistim_device::language, LOG_ERROR, LOG_WARNING, NULL, OBJ_POINTER, options_languages, str, ustm_lang_entry::str_orig, ustm_lang_entry::str_trans, unistim_languages::trans, USTM_LANG_DIR, and ustm_strcopy.

Referenced by handle_call_incoming(), handle_call_outgoing(), handle_dial_page(), handle_select_codec(), handle_select_language(), handle_select_option(), init_phone_step2(), key_dial_page(), key_select_extension(), send_callerid_screen(), send_expansion_short(), send_favorite(), send_month_labels(), show_entry_history(), show_extension_page(), show_main_page(), show_phone_number(), unistim_answer(), unistim_call(), unistim_hangup(), unistim_indicate(), unistim_sendtext(), and write_history().

◆ write_entry_history()

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

Definition at line 2262 of file chan_unistim.c.

2263{
2264 if (fwrite(&c, 1, 1, f) != 1) {
2265 display_last_error("Unable to write history log header.");
2266 return -1;
2267 }
2268 if (fwrite(line1, TEXT_LENGTH_MAX, 1, f) != 1) {
2269 display_last_error("Unable to write history entry - date.");
2270 return -1;
2271 }
2272 if (fwrite(pte->device->lst_cid, TEXT_LENGTH_MAX, 1, f) != 1) {
2273 display_last_error("Unable to write history entry - callerid.");
2274 return -1;
2275 }
2276 if (fwrite(pte->device->lst_cnm, TEXT_LENGTH_MAX, 1, f) != 1) {
2277 display_last_error("Unable to write history entry - callername.");
2278 return -1;
2279 }
2280 return 0;
2281}

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

Referenced by write_history().

◆ write_history()

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

Definition at line 2283 of file chan_unistim.c.

2284{
2286 char line1[TEXT_LENGTH_MAX + 1];
2287 char count = 0, *histbuf;
2288 int size;
2289 FILE *f, *f2;
2290 struct timeval now = ast_tvnow();
2291 struct ast_tm atm = { 0, };
2292
2293 if (!pte->device) {
2294 return -1;
2295 }
2296 if (!pte->device->callhistory) {
2297 return 0;
2298 }
2299 if (strchr(pte->device->name, '/') || (pte->device->name[0] == '.')) {
2300 ast_log(LOG_WARNING, "Account code '%s' insecure for writing file\n",
2301 pte->device->name);
2302 return -1;
2303 }
2304
2305 snprintf(tmp, sizeof(tmp), "%s/%s", ast_config_AST_LOG_DIR, USTM_LOG_DIR);
2306 if (ast_mkdir(tmp, 0770)) {
2307 ast_log(LOG_WARNING, "Unable to create directory for history\n");
2308 return -1;
2309 }
2310
2311 ast_localtime(&now, &atm, NULL);
2312 if (ismissed) {
2313 if (way == 'i') {
2314 ast_copy_string(tmp2, ustmtext("Miss", pte), sizeof(tmp2));
2315 } else {
2316 ast_copy_string(tmp2, ustmtext("Fail", pte), sizeof(tmp2));
2317 }
2318 } else {
2319 ast_copy_string(tmp2, ustmtext("Answ", pte), sizeof(tmp2));
2320 }
2321 snprintf(line1, sizeof(line1), "%04d/%02d/%02d %02d:%02d:%02d %s",
2322 atm.tm_year + 1900, atm.tm_mon + 1, atm.tm_mday, atm.tm_hour,
2323 atm.tm_min, atm.tm_sec, tmp2);
2324
2325 snprintf(tmp, sizeof(tmp), "%s/%s/%s-%c.csv", ast_config_AST_LOG_DIR,
2326 USTM_LOG_DIR, pte->device->name, way);
2327 if ((f = fopen(tmp, "r"))) {
2328 struct stat bufstat;
2329
2330 if (stat(tmp, &bufstat)) {
2331 display_last_error("Unable to stat history log.");
2332 fclose(f);
2333 return -1;
2334 }
2335 size = 1 + (MAX_ENTRY_LOG * TEXT_LENGTH_MAX * 3);
2336 if (bufstat.st_size != size) {
2338 "History file %s has an incorrect size (%d instead of %d). It will be replaced by a new one.",
2339 tmp, (int) bufstat.st_size, size);
2340 fclose(f);
2341 f = NULL;
2342 count = 1;
2343 }
2344 }
2345
2346 /* If we can't open the log file, we create a brand new one */
2347 if (!f) {
2348 char c = 1;
2349 int i;
2350
2351 if ((errno != ENOENT) && (count == 0)) {
2352 display_last_error("Unable to open history log.");
2353 return -1;
2354 }
2355 f = fopen(tmp, "w");
2356 if (!f) {
2357 display_last_error("Unable to create history log.");
2358 return -1;
2359 }
2360 if (write_entry_history(pte, f, c, line1)) {
2361 fclose(f);
2362 return -1;
2363 }
2364 memset(line1, ' ', TEXT_LENGTH_MAX);
2365 for (i = 3; i < MAX_ENTRY_LOG * 3; i++) {
2366 if (fwrite(line1, TEXT_LENGTH_MAX, 1, f) != 1) {
2367 display_last_error("Unable to write history entry - stuffing.");
2368 fclose(f);
2369 return -1;
2370 }
2371 }
2372 if (fclose(f)) {
2373 display_last_error("Unable to close history - creation.");
2374 }
2375 return 0;
2376 }
2377 /* We can open the log file, we create a temporary one, we add our entry and copy the rest */
2378 if (fread(&count, 1, 1, f) != 1) {
2379 display_last_error("Unable to read history header.");
2380 fclose(f);
2381 return -1;
2382 }
2383 if (count > MAX_ENTRY_LOG) {
2384 ast_log(LOG_WARNING, "Invalid count in history header of %s (%d max %d)\n", tmp,
2385 count, MAX_ENTRY_LOG);
2386 fclose(f);
2387 return -1;
2388 }
2389 snprintf(tmp2, sizeof(tmp2), "%s/%s/%s-%c.csv.tmp", ast_config_AST_LOG_DIR,
2390 USTM_LOG_DIR, pte->device->name, way);
2391 if (!(f2 = fopen(tmp2, "w"))) {
2392 display_last_error("Unable to create temporary history log.");
2393 fclose(f);
2394 return -1;
2395 }
2396
2397 if (++count > MAX_ENTRY_LOG) {
2398 count = MAX_ENTRY_LOG;
2399 }
2400 if (write_entry_history(pte, f2, count, line1)) {
2401 fclose(f);
2402 fclose(f2);
2403 return -1;
2404 }
2405 size = (MAX_ENTRY_LOG - 1) * TEXT_LENGTH_MAX * 3;
2406 if (!(histbuf = ast_malloc(size))) {
2407 fclose(f);
2408 fclose(f2);
2409 return -1;
2410 }
2411
2412 if (fread(histbuf, size, 1, f) != 1) {
2413 ast_free(histbuf);
2414 fclose(f);
2415 fclose(f2);
2416 display_last_error("Unable to read previous history entries.");
2417 return -1;
2418 }
2419 if (fwrite(histbuf, size, 1, f2) != 1) {
2420 ast_free(histbuf);
2421 fclose(f);
2422 fclose(f2);
2423 display_last_error("Unable to write previous history entries.");
2424 return -1;
2425 }
2426 ast_free(histbuf);
2427 if (fclose(f)) {
2428 display_last_error("Unable to close history log.");
2429 }
2430 if (fclose(f2)) {
2431 display_last_error("Unable to close temporary history log.");
2432 }
2433 if (unlink(tmp)) {
2434 display_last_error("Unable to remove old history log.");
2435 }
2436 if (rename(tmp2, tmp)) {
2437 display_last_error("Unable to rename new history log.");
2438 }
2439 return 0;
2440}
static int write_entry_history(struct unistimsession *pte, FILE *f, char c, char *line1)
int tm_sec
Definition localtime.h:36
int tm_year
Definition localtime.h:41
int ast_mkdir(const char *path, int mode)
Recursively create directory path.
Definition utils.c:2513

References ast_config_AST_LOG_DIR, AST_CONFIG_MAX_PATH, ast_copy_string(), ast_free, ast_localtime(), ast_log, ast_malloc, ast_mkdir(), ast_tvnow(), c, unistim_device::callhistory, unistimsession::device, display_last_error(), errno, LOG_WARNING, MAX_ENTRY_LOG, unistim_device::name, NULL, 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, ustmtext(), and write_entry_history().

Referenced by close_call(), handle_call_incoming(), and unistim_hangup().

Variable Documentation

◆ __mod_info

struct ast_module_info __mod_info = { .name = AST_MODULE, .flags = AST_MODFLAG_DEFAULT , .description = "UNISTIM Protocol (USTM)" , .key = ASTERISK_GPL_KEY , .buildopt_sum = AST_BUILDOPT_SUM, .support_level = AST_MODULE_SUPPORT_EXTENDED, .load = load_module, .unload = unload_module, .reload = reload, }
static

Definition at line 7212 of file chan_unistim.c.

◆ ast_module_info

const struct ast_module_info* ast_module_info = &__mod_info
static

Definition at line 7212 of file chan_unistim.c.

◆ autoprovisioning

enum autoprovision autoprovisioning = AUTOPROVISIONING_NO
static

◆ buff

unsigned char* buff
static

◆ channel_type

const char channel_type[] = "USTM"
static

Definition at line 709 of file chan_unistim.c.

Referenced by load_module().

◆ cos

unsigned int cos

Definition at line 252 of file chan_unistim.c.

◆ cos_audio

unsigned int cos_audio

Definition at line 253 of file chan_unistim.c.

◆ default_jbconf

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

228{
229 .flags = 0,
230 .max_size = 200,
231 .resync_threshold = 1000,
232 .impl = "fixed",
233 .target_extra = 40,
234};

Referenced by reload_config().

◆ devicelock

ast_mutex_t devicelock = AST_MUTEX_INIT_VALUE
static

◆ devices

struct unistim_device * devices = NULL
static

◆ dtmf_col

const float dtmf_col[] = { 1209, 1336, 1477, 1633 }
static

Definition at line 346 of file chan_unistim.c.

346{ 1209, 1336, 1477, 1633 };

Referenced by send_dtmf_tone().

◆ dtmf_row

const int dtmf_row[] = { 697, 770, 852, 941 }
static

Definition at line 345 of file chan_unistim.c.

345{ 697, 770, 852, 941 };

Referenced by send_dtmf_tone().

◆ global_cap

struct ast_format_cap* global_cap

◆ global_jbconf

struct ast_jb_conf global_jbconf
static

Definition at line 235 of file chan_unistim.c.

Referenced by reload_config(), and unistim_new().

◆ io

struct io_context* io
static

Definition at line 256 of file chan_unistim.c.

Referenced by do_monitor(), and load_module().

◆ monitor_thread

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

Referenced by restart_monitor(), and unload_module().

◆ monlock

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

Definition at line 269 of file chan_unistim.c.

Referenced by restart_monitor(), and unload_module().

◆ monthlabels

unsigned char monthlabels[]
static
Initial value:
=
{ 'J', 'a', 'n', 'F', 'e', 'b', 'M', 'a', 'r', 'A', 'p', 'r', 'M', 'a', 'y', 'J', 'u', 'n',
'J', 'u', 'l', 'A', 'u', 'g', 'S', 'e', 'p', 'O', 'c', 't', 'N', 'o', 'v', 'D', 'e', 'c' }

Definition at line 651 of file chan_unistim.c.

652 { 'J', 'a', 'n', 'F', 'e', 'b', 'M', 'a', 'r', 'A', 'p', 'r', 'M', 'a', 'y', 'J', 'u', 'n',
653 'J', 'u', 'l', 'A', 'u', 'g', 'S', 'e', 'p', 'O', 'c', 't', 'N', 'o', 'v', 'D', 'e', 'c' };

Referenced by send_month_labels().

◆ options_languages

struct unistim_languages options_languages[]
static

Definition at line 773 of file chan_unistim.c.

774{
775 {"English", "en", ISO_8859_1, NULL},
776 {"French", "fr", ISO_8859_1, NULL},
777 {"Russian", "ru", ISO_8859_5, NULL},
778 {NULL, NULL, 0, NULL}
779};

Referenced by find_language(), handle_select_language(), init_phone_step2(), key_select_language(), reload_config(), send_charset_update(), and ustmtext().

◆ options_menu

struct unistim_menu_item options_menu[]
static

Definition at line 766 of file chan_unistim.c.

767{
768 {"Change codec", STATE_SELECTCODEC, handle_select_codec},
770 {NULL, 0, NULL}
771};
static void handle_select_codec(struct unistimsession *)

Referenced by handle_select_option(), and key_select_option().

◆ packet_rcv_discovery

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

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

Referenced by parsing().

◆ packet_recv_expansion_pressed_key

const unsigned char packet_recv_expansion_pressed_key[]
static
Initial value:
=
{ 0x00, 0x00, 0x00, 0x13, 0x89, 0x04, 0x59 }

Expansion module (i2004 KEM)

Definition at line 526 of file chan_unistim.c.

527 { 0x00, 0x00, 0x00, 0x13, 0x89, 0x04, 0x59 };

Referenced by process_request().

◆ packet_recv_firm_version

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

Definition at line 513 of file chan_unistim.c.

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

Referenced by process_request().

◆ packet_recv_hangup

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

Definition at line 521 of file chan_unistim.c.

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

Referenced by process_request().

◆ packet_recv_it_type

const unsigned char packet_recv_it_type[]
static
Initial value:
=
{ 0x00, 0x00, 0x00, 0x13, 0x9a, 0x04, 0x03 }

Definition at line 515 of file chan_unistim.c.

516 { 0x00, 0x00, 0x00, 0x13, 0x9a, 0x04, 0x03 };

Referenced by process_request().

◆ packet_recv_mac_addr

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

Definition at line 537 of file chan_unistim.c.

538 { 0xff, 0xff, 0xff, 0xff, 0x9a, 0x0d, 0x07 /*MacAddr */ };

Referenced by process_request().

◆ packet_recv_pick_up

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

Definition at line 519 of file chan_unistim.c.

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

Referenced by process_request().

◆ packet_recv_pressed_key

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

Definition at line 517 of file chan_unistim.c.

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

Referenced by process_request().

◆ packet_recv_r2

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

Definition at line 523 of file chan_unistim.c.

523{ 0x00, 0x00, 0x00, 0x13, 0x96, 0x03, 0x03 };

Referenced by process_request().

◆ packet_recv_resume_connection_with_server

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

TransportAdapter

Definition at line 535 of file chan_unistim.c.

536 { 0xff, 0xff, 0xff, 0xff, 0x9e, 0x03, 0x08 };

Referenced by process_request().

◆ packet_send_arrow

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

Definition at line 635 of file chan_unistim.c.

635{ 0x17, 0x04, 0x04, 0x00 };

Referenced by init_phone_step2().

◆ packet_send_blink_cursor

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

Definition at line 636 of file chan_unistim.c.

636{ 0x17, 0x04, 0x10, 0x86 };

Referenced by send_blink_cursor().

◆ packet_send_call

const unsigned char packet_send_call[]
static

Definition at line 560 of file chan_unistim.c.

561 { 0x16, 0x04, 0x1a, 0x00, 0x16, 0x04, 0x11, 0x00, 0x16, 0x06, 0x32, 0xdf,
562 0x00, 0xff, 0x16, 0x05, 0x1c, 0x00, 0x00, 0x16, 0x0a, 0x38, 0x00, 0x12, 0xca, 0x03,
563 0xc0, 0xc3, 0xc5, 0x16, 0x16, 0x30, 0x00,
564 0x00, /*codec */ 0x12, 0x12, /* frames per packet */ 0x01, 0x5c, 0x00, /*port RTP */
565 0x0f, 0xa0, /* port RTCP */ 0x9c, 0x41,
566 /*port RTP */ 0x0f, 0xa0, /* port RTCP */ 0x9c, 0x41, /* IP Address */ 0x0a, 0x01,
567 0x16, 0x66
568};

Referenced by send_start_rtp().

◆ packet_send_charset_iso_2022_jp

const unsigned char packet_send_charset_iso_2022_jp[]
static
Initial value:
=
{ 0x17, 0x08, 0x21, 0x1b, 0x29, 0x49, 0x1b, 0x7e }

Definition at line 693 of file chan_unistim.c.

694 { 0x17, 0x08, 0x21, 0x1b, 0x29, 0x49, 0x1b, 0x7e };

Referenced by send_charset_update().

◆ packet_send_charset_iso_8859_1

const unsigned char packet_send_charset_iso_8859_1[]
static
Initial value:
=
{ 0x17, 0x08, 0x21, 0x1b, 0x2d, 0x41, 0x1b, 0x00 }

Definition at line 681 of file chan_unistim.c.

682 { 0x17, 0x08, 0x21, 0x1b, 0x2d, 0x41, 0x1b, 0x00 };

Referenced by send_charset_update().

◆ packet_send_charset_iso_8859_2

const unsigned char packet_send_charset_iso_8859_2[]
static
Initial value:
=
{ 0x17, 0x08, 0x21, 0x1b, 0x2d, 0x42, 0x1b, 0x00 }

Definition at line 684 of file chan_unistim.c.

685 { 0x17, 0x08, 0x21, 0x1b, 0x2d, 0x42, 0x1b, 0x00 };

Referenced by send_charset_update().

◆ packet_send_charset_iso_8859_4

const unsigned char packet_send_charset_iso_8859_4[]
static
Initial value:
=
{ 0x17, 0x08, 0x21, 0x1b, 0x2d, 0x44, 0x1b, 0x00 }

Definition at line 687 of file chan_unistim.c.

688 { 0x17, 0x08, 0x21, 0x1b, 0x2d, 0x44, 0x1b, 0x00 };

Referenced by send_charset_update().

◆ packet_send_charset_iso_8859_5

const unsigned char packet_send_charset_iso_8859_5[]
static
Initial value:
=
{ 0x17, 0x08, 0x21, 0x1b, 0x2d, 0x4c, 0x1b, 0x00 }

Definition at line 690 of file chan_unistim.c.

691 { 0x17, 0x08, 0x21, 0x1b, 0x2d, 0x4c, 0x1b, 0x00 };

Referenced by send_charset_update().

◆ packet_send_Contrast

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

Definition at line 640 of file chan_unistim.c.

641 { 0x17, 0x04, 0x24, /*Contrast */ 0x08 };

Referenced by init_phone_step2().

◆ packet_send_date_time

const unsigned char packet_send_date_time[]
static

Definition at line 544 of file chan_unistim.c.

545 { 0x11, 0x09, 0x02, 0x0a, /*Month */ 0x05, /*Day */ 0x06, /*Hour */ 0x07, /*Minutes */
5460x08, 0x32, 0x17, 0x04, 0x24, 0x07, 0x19,
547 0x04, 0x07, 0x00, 0x19, 0x05, 0x09, 0x3e, 0x0f, 0x16, 0x05, 0x00, 0x80, 0x00, 0x1e,
548 0x05, 0x12, 0x00, 0x78
549};

Referenced by send_date_time().

◆ packet_send_date_time2

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

637 { 0x17, 0x04, 0x17, 0x3d, 0x11, 0x09, 0x02, 0x0a, /*Month */ 0x05, /*Day */
638 0x06, /*Hour */ 0x07, /*Minutes */ 0x08, 0x32
639};

Referenced by send_date_time2().

◆ packet_send_date_time3

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

Definition at line 540 of file chan_unistim.c.

541 { 0x11, 0x09, 0x02, 0x02, /*Month */ 0x05, /*Day */ 0x06, /*Hour */ 0x07,
542/*Minutes */ 0x08, 0x32
543};

Referenced by send_date_time3().

◆ packet_send_discovery_ack

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

Definition at line 510 of file chan_unistim.c.

511 { 0x00, 0x00, /*Initial Seq (2 bytes) */ 0x00, 0x00, 0x00, 0x01 };

Referenced by parsing().

◆ packet_send_end_call

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

Definition at line 594 of file chan_unistim.c.

595 { 0x16, 0x06, 0x32, 0xdf, 0x00, 0xff, 0x16, 0x05, 0x31, 0x00, 0x00, /* Query RTCP */ 0x16, 0x04, 0x37, 0x10 };

Referenced by send_end_call().

◆ packet_send_expansion_icon

const unsigned char packet_send_expansion_icon[] = { 0x09, 0x06, 0x59, 0x05, 0x47, 0x20 }
static

Definition at line 529 of file chan_unistim.c.

529{ 0x09, 0x06, 0x59, 0x05, /*pos */ 0x47, /*icon */ 0x20 }; /* display an icon in front of the text zone */

Referenced by send_expansion_icon().

◆ packet_send_expansion_next

const unsigned char packet_send_expansion_next[] = { 0x09, 0x03, 0x17 }
static

Definition at line 528 of file chan_unistim.c.

528{ 0x09, 0x03, 0x17 };

Referenced by send_expansion_next().

◆ packet_send_expansion_text

const unsigned char packet_send_expansion_text[]
static
Initial value:
= { 0x09, 0x0f, 0x57, 0x19, 0x47, 0x20,
0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20 }

Definition at line 530 of file chan_unistim.c.

530 { 0x09, 0x0f, 0x57, 0x19, /*pos */ 0x47, /*text */ 0x20,
531 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20 /*end_text */ };

Referenced by send_expansion_text().

◆ packet_send_favorite

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

657 { 0x17, 0x0f, 0x19, 0x10, /*pos */ 0x01, /*name */ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
6580x20, 0x20, 0x20, 0x20, /*end_name */ 0x19,
659 0x05, 0x0f, /*pos */ 0x01, /*icone */ 0x00
660};

Referenced by send_favorite().

◆ packet_send_icon

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

Definition at line 646 of file chan_unistim.c.

646{ 0x17, 0x05, 0x14, /*pos */ 0x00, /*icon */ 0x25 }; /* display an icon in front of the text zone */

Referenced by send_icon().

◆ packet_send_jitter_buffer_conf

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

602 { 0x16, 0x0e, 0x3a, 0x00, /* jitter */ 0x02, /* high water mark */ 0x04, 0x00, 0x00,
603/* early packet resync 2 bytes */ 0x3e, 0x80,
604 0x00, 0x00, /* late packet resync 2 bytes */ 0x3e, 0x80
605};

Referenced by send_start_rtp().

◆ packet_send_led_update

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

Definition at line 696 of file chan_unistim.c.

696{ 0x19, 0x04, 0x00, 0x00 };

Referenced by send_led_update().

◆ packet_send_monthlabels_download

unsigned char packet_send_monthlabels_download[]
static
Initial value:
=
{ 0x17, 0x0a, 0x15, '-', '-', '-', '-', '-', '-', 0x20 }

Definition at line 654 of file chan_unistim.c.

655 { 0x17, 0x0a, 0x15, /* Month (3 char) */ '-', '-', '-', '-', '-', '-', 0x20 };

Referenced by send_month_labels().

◆ packet_send_mute

const unsigned char packet_send_mute[] = { 0x16, 0x05, 0x04, 0x00, 0x00 }
static

Definition at line 572 of file chan_unistim.c.

572{ 0x16, 0x05, 0x04, 0x00, 0x00 };

Referenced by send_mute().

◆ packet_send_no_ring

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

Definition at line 551 of file chan_unistim.c.

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

Referenced by send_no_ring().

◆ packet_send_open_audio_stream_rx

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

611 { 0x16, 0x1a, 0x30, 0x00, 0xff, /* Codec */ 0x00, 0x00, 0x01, 0x00, 0xb8, 0xb8, 0x0e,
6120x0e, 0x01, /* Port */ 0x14, 0x50, 0x00,
613 0x00, /* Port */ 0x14, 0x50, 0x00, 0x00, /* Dest IP */ 0x0a, 0x93, 0x69, 0x05
614};

Referenced by send_start_rtp().

◆ packet_send_open_audio_stream_rx3

const unsigned char packet_send_open_audio_stream_rx3[]
static

Definition at line 621 of file chan_unistim.c.

622 { 0x16, 0x1a, 0x30, 0x00, 0xff, /* Codec */ 0x00, 0x00, 0x02, 0x01, 0xb8, 0xb8, 0x06,
6230x06, 0x81, /* RTP Port */ 0x14, 0x50,
624/* RTCP Port */ 0x14,
625 0x51, /* RTP Port */ 0x14, 0x50, /* RTCP Port */ 0x00, 0x00, /* Dest IP */ 0x0a, 0x93,
626 0x69, 0x05
627};

Referenced by send_start_rtp().

◆ packet_send_open_audio_stream_tx

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

616 { 0x16, 0x1a, 0x30, 0xff, 0x00, 0x00, /* Codec */ 0x00, 0x01, 0x00, 0xb8, 0xb8, 0x0e,
6170x0e, 0x01, /* Local port */ 0x14, 0x50,
618 0x00, 0x00, /* Rmt Port */ 0x14, 0x50, 0x00, 0x00, /* Dest IP */ 0x0a, 0x93, 0x69, 0x05
619};

Referenced by send_start_rtp().

◆ packet_send_open_audio_stream_tx3

const unsigned char packet_send_open_audio_stream_tx3[]
static

Definition at line 628 of file chan_unistim.c.

629 { 0x16, 0x1a, 0x30, 0xff, 0x00, 0x00, /* Codec */ 0x00, 0x02, 0x01, 0xb8, 0xb8, 0x06,
6300x06, 0x81, /* RTP Local port */ 0x14, 0x50,
631 /* RTCP Port */ 0x00, 0x00, /* RTP Rmt Port */ 0x14, 0x50, /* RTCP Port */ 0x00, 0x00,
632 /* Dest IP */ 0x0a, 0x93, 0x69, 0x05
633};

Referenced by send_start_rtp().

◆ packet_send_ping

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

Definition at line 703 of file chan_unistim.c.

704 { 0x1e, 0x05, 0x12, 0x00, /*Watchdog timer */ 0x78 };

Referenced by reload_config(), and send_ping().

◆ packet_send_query_basic_manager_04

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

Definition at line 698 of file chan_unistim.c.

698{ 0x1a, 0x04, 0x01, 0x04 };

Referenced by rcv_mac_addr().

◆ packet_send_query_basic_manager_10

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

Definition at line 700 of file chan_unistim.c.

700{ 0x1a, 0x04, 0x01, 0x10 };

Referenced by rcv_mac_addr().

◆ packet_send_query_mac_address

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

Definition at line 699 of file chan_unistim.c.

699{ 0x1a, 0x04, 0x01, 0x08 };

Referenced by rcv_resume_connection_with_server().

◆ packet_send_ring

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

587 { 0x16, 0x06, 0x32, 0xdf, 0x00, 0xff, 0x16, 0x05, 0x1c, 0x00, 0x00, 0x16,
588 0x04, 0x1a, 0x01, 0x16, 0x05, 0x12, 0x13 /* Ring type 10 to 17 */ , 0x18, 0x16, 0x04, 0x18, /* volume 00, 10, 20... */
589 0x20, 0x16, 0x04, 0x10, 0x00
590};

Referenced by send_ring().

◆ packet_send_rtp_packet_size

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

Definition at line 599 of file chan_unistim.c.

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

Referenced by send_start_rtp().

◆ packet_send_S1

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

Definition at line 701 of file chan_unistim.c.

701{ 0x1a, 0x07, 0x07, 0x00, 0x00, 0x00, 0x13 };

Referenced by rcv_mac_addr().

◆ packet_send_s4

const unsigned char packet_send_s4[]
static

Definition at line 553 of file chan_unistim.c.

554 { 0x16, 0x04, 0x1a, 0x00, 0x16, 0x04, 0x11, 0x00, 0x16, 0x06, 0x32, 0xdf, 0x00, 0xff,
5550x16, 0x05, 0x1c, 0x00, 0x00, 0x17, 0x05,
556 0x0b, 0x00, 0x00, 0x19, 0x04, 0x00, 0x00, 0x19, 0x04, 0x00, 0x08, 0x19, 0x04, 0x00,
557 0x10, 0x19, 0x04, 0x00, 0x18, 0x16, 0x05,
558 0x31, 0x00, 0x00, 0x16, 0x05, 0x04, 0x00, 0x00
559};

Referenced by init_phone_step2().

◆ packet_send_S7

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

Definition at line 647 of file chan_unistim.c.

647{ 0x17, 0x06, 0x0f, 0x30, 0x07, 0x07 };

Referenced by init_phone_step2().

◆ packet_send_s9

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

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

Referenced by init_phone_step2().

◆ packet_send_select_output

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

Definition at line 583 of file chan_unistim.c.

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

Referenced by send_select_output().

◆ packet_send_set_pos_cursor

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

Definition at line 648 of file chan_unistim.c.

649 { 0x17, 0x06, 0x10, 0x81, 0x04, /*pos */ 0x20 };

Referenced by send_cursor_pos().

◆ packet_send_start_timer

const unsigned char packet_send_start_timer[]
static
Initial value:
=
{ 0x17, 0x05, 0x0b, 0x05, 0x00, 0x17, 0x08, 0x16,
'T', 'i', 'm', 'e', 'r' }

Definition at line 642 of file chan_unistim.c.

643 { 0x17, 0x05, 0x0b, /*Timer option*/0x05, /* Timer ID */0x00, 0x17, 0x08, 0x16,
644 /* Text */ 'T', 'i', 'm', 'e', 'r' };

Referenced by send_start_timer().

◆ packet_send_status

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

671 { 0x17, 0x20, 0x19, 0x08, /*text */ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
6720x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
673 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20 /*end_text */
674};

Referenced by send_text_status().

◆ packet_send_status2

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

Definition at line 675 of file chan_unistim.c.

676 { 0x17, 0x0b, 0x19, /* pos [08|28|48|68] */ 0x00, /* text */ 0x20, 0x20, 0x20, 0x20,
6770x20, 0x20, 0x20 /* end_text */ };

Referenced by send_text_status().

◆ packet_send_stop_timer

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

Definition at line 645 of file chan_unistim.c.

645{ 0x17, 0x05, 0x0b, 0x02, 0x00 };

Referenced by send_stop_timer().

◆ packet_send_stream_based_tone_dual_freq

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

Definition at line 581 of file chan_unistim.c.

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

Referenced by send_tone().

◆ packet_send_stream_based_tone_off

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

Definition at line 569 of file chan_unistim.c.

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

Referenced by send_tone().

◆ packet_send_stream_based_tone_on

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

Definition at line 577 of file chan_unistim.c.

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

Referenced by send_tone().

◆ packet_send_stream_based_tone_single_freq

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

Definition at line 579 of file chan_unistim.c.

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

Referenced by send_tone().

◆ packet_send_text

const unsigned char packet_send_text[]
static

Definition at line 664 of file chan_unistim.c.

665 { 0x17, 0x1e, 0x1b, 0x04, /*pos */ 0x00, /*inverse */ 0x25, /*text */ 0x20, 0x20,
6660x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
667 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
668 /*end_text */ 0x17, 0x04, 0x10, 0x87
669};

Referenced by send_text().

◆ packet_send_title

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

662 { 0x17, 0x10, 0x19, 0x02, /*text */ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
6630x20, 0x20, 0x20, 0x20 /*end_text */ };

Referenced by send_texttitle().

◆ public_ip

struct sockaddr_in public_ip = { 0, }
static

Definition at line 258 of file chan_unistim.c.

258{ 0, };

Referenced by get_to_address(), reload_config(), and send_start_rtp().

◆ [struct]

struct { ... } qos

Referenced by reload_config(), and start_rtp().

◆ sched

struct ast_sched_context* sched
static

Definition at line 257 of file chan_unistim.c.

◆ sessionlock

ast_mutex_t sessionlock = AST_MUTEX_INIT_VALUE
static

Protect the session list

Definition at line 271 of file chan_unistim.c.

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

◆ sessions

struct unistimsession * sessions = NULL
static

◆ tdesc

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

Definition at line 708 of file chan_unistim.c.

◆ tos

unsigned int tos

Definition at line 250 of file chan_unistim.c.

◆ tos_audio

unsigned int tos_audio

Definition at line 251 of file chan_unistim.c.

◆ unistim_cli

struct ast_cli_entry unistim_cli[]
static

Definition at line 6273 of file chan_unistim.c.

6273 {
6274 AST_CLI_DEFINE(unistim_reload, "Reload UNISTIM configuration"),
6275 AST_CLI_DEFINE(unistim_show_info, "Show UNISTIM info"),
6276 AST_CLI_DEFINE(unistim_show_devices, "Show UNISTIM devices"),
6277 AST_CLI_DEFINE(unistim_sp, "Send packet (for reverse engineering)"),
6278 AST_CLI_DEFINE(unistim_do_debug, "Toggle UNITSTIM debugging"),
6279};
static char * unistim_show_info(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
static char * unistim_sp(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
static char * unistim_show_devices(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
static char * unistim_do_debug(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
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,...
#define AST_CLI_DEFINE(fn, txt,...)
Definition cli.h:197

Referenced by load_module(), and unload_module().

◆ unistim_keepalive

int unistim_keepalive
static

Definition at line 246 of file chan_unistim.c.

Referenced by create_client(), reload_config(), and send_ping().

◆ unistim_port

int unistim_port
static

Definition at line 244 of file chan_unistim.c.

Referenced by reload_config().

◆ unistim_reload_lock

ast_mutex_t unistim_reload_lock = AST_MUTEX_INIT_VALUE
static

Definition at line 261 of file chan_unistim.c.

Referenced by do_monitor(), and reload().

◆ unistim_reloading

int unistim_reloading = 0
static

Receive buffer address

Definition at line 260 of file chan_unistim.c.

Referenced by do_monitor(), and reload().

◆ unistim_rtp_glue

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,
}
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, const struct ast_format_cap *codecs, int nat_active)
static enum ast_rtp_glue_result unistim_get_rtp_peer(struct ast_channel *chan, struct ast_rtp_instance **instance)

Definition at line 7079 of file chan_unistim.c.

7079 {
7080 .type = channel_type,
7081 .get_rtp_info = unistim_get_rtp_peer,
7082 .update_peer = unistim_set_rtp_peer,
7083};

Referenced by load_module(), and unload_module().

◆ unistim_tech

struct ast_channel_tech unistim_tech
static

Definition at line 738 of file chan_unistim.c.

738 {
739 .type = channel_type,
740 .description = tdesc,
742 .requester = unistim_request,
743 .call = unistim_call,
744 .hangup = unistim_hangup,
745 .answer = unistim_answer,
746 .read = unistim_read,
747 .write = unistim_write,
748 .indicate = unistim_indicate,
749 .fixup = unistim_fixup,
750 .send_digit_begin = unistim_senddigit_begin,
751 .send_digit_end = unistim_senddigit_end,
752 .send_text = unistim_sendtext,
753};
static int unistim_call(struct ast_channel *ast, const char *dest, int timeout)
static struct ast_frame * unistim_read(struct ast_channel *ast)
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 const char tdesc[]
static int unistim_hangup(struct ast_channel *ast)
static int unistim_write(struct ast_channel *ast, struct ast_frame *frame)
static struct ast_channel * unistim_request(const char *type, struct ast_format_cap *cap, const struct ast_assigned_ids *assignedids, const struct ast_channel *requestor, const char *dest, int *cause)
static int unistim_sendtext(struct ast_channel *ast, const char *text)
static int unistim_fixup(struct ast_channel *oldchan, struct ast_channel *newchan)
static int unistim_indicate(struct ast_channel *ast, int ind, const void *data, size_t datalen)
static int unistim_answer(struct ast_channel *ast)
@ AST_CHAN_TP_WANTSJITTER
Channels have this property if they can accept input with jitter; i.e. most VoIP channels.
Definition channel.h:980
@ AST_CHAN_TP_CREATESJITTER
Channels have this property if they can create jitter; i.e. most VoIP channels.
Definition channel.h:985

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

◆ unistimdebug

int unistimdebug = 0
static

◆ unistimsock

int unistimsock = -1
static

◆ ustm_strcopy

char ustm_strcopy[1024]
static

Definition at line 781 of file chan_unistim.c.

Referenced by ustmtext().