Asterisk - The Open Source Telephony Project GIT-master-773870a
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_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 704 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_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 3730 of file chan_unistim.c.

◆ SELECTCODEC_MSG

#define SELECTCODEC_MSG   "Codec number : .."

Definition at line 3731 of file chan_unistim.c.

◆ SELECTCODEC_START_ENTRY_POS

#define SELECTCODEC_START_ENTRY_POS   15

Definition at line 3729 of file chan_unistim.c.

◆ SELECTEXTENSION_MAX_LENGTH

#define SELECTEXTENSION_MAX_LENGTH   10

Definition at line 3874 of file chan_unistim.c.

◆ SELECTEXTENSION_MSG

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

Definition at line 3875 of file chan_unistim.c.

◆ SELECTEXTENSION_START_ENTRY_POS

#define SELECTEXTENSION_START_ENTRY_POS   0

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

◆ __unreg_module()

static void __unreg_module ( void  )
static

Definition at line 7204 of file chan_unistim.c.

◆ AST_MODULE_SELF_SYM()

struct ast_module * AST_MODULE_SELF_SYM ( void  )

Definition at line 7204 of file chan_unistim.c.

◆ attempt_transfer()

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

Definition at line 2440 of file chan_unistim.c.

2441{
2442 RAII_VAR(struct ast_channel *, chana, NULL, ast_channel_unref);
2443 RAII_VAR(struct ast_channel *, chanb, NULL, ast_channel_unref);
2444
2445 if (!p1->owner || !p2->owner) {
2446 ast_log(LOG_WARNING, "Transfer attempted without dual ownership?\n");
2447 return -1;
2448 }
2449 chana = ast_channel_ref(p1->owner);
2450 chanb = ast_channel_ref(p2->owner);
2451
2452 switch (ast_bridge_transfer_attended(chana, chanb)) {
2454 ast_log(LOG_WARNING, "Transfer failed. Invalid bridge setup\n");
2455 break;
2457 ast_log(LOG_WARNING, "Transfer not permitted\n");
2458 break;
2460 ast_log(LOG_WARNING, "Transfer encountered internal error\n");
2461 break;
2463 return 0;
2464 }
2465
2466 /* Control only reaches this point if transfer has failed */
2469 return -1;
2470}
#define ast_log
Definition astobj2.c:42
@ AST_BRIDGE_TRANSFER_NOT_PERMITTED
Definition bridge.h:1106
@ AST_BRIDGE_TRANSFER_SUCCESS
Definition bridge.h:1104
@ AST_BRIDGE_TRANSFER_INVALID
Definition bridge.h:1108
@ AST_BRIDGE_TRANSFER_FAIL
Definition bridge.h:1110
enum ast_transfer_result ast_bridge_transfer_attended(struct ast_channel *to_transferee, struct ast_channel *to_transfer_target)
Attended transfer.
Definition bridge.c:4756
#define ast_channel_ref(c)
Increase channel reference count.
Definition channel.h:3007
#define ast_channel_unref(c)
Decrease channel reference count.
Definition channel.h:3018
int ast_softhangup_nolock(struct ast_channel *chan, int cause)
Softly hangup up a channel (no channel lock)
Definition channel.c:2448
@ AST_SOFTHANGUP_DEV
Definition channel.h:1141
#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 6499 of file chan_unistim.c.

6500{
6501 struct unistim_device *d;
6502 struct unistim_line *l = NULL, *lt = NULL;
6503 int create = 1;
6504 int nbsoftkey, dateformat, timeformat, callhistory, sharpdial, linecnt;
6505 char linelabel[AST_MAX_EXTENSION];
6506 signed char ringvolume, ringstyle, cwvolume, cwstyle;
6507
6508 /* First, we need to know if we already have this name in our list */
6509 /* Get a lock for the device chained list */
6511 d = devices;
6512 while (d) {
6513 if (!strcmp(d->name, cat)) {
6514 /* Yep, we already have this one */
6515 if (unistimsock < 0) {
6516 /* It's a dupe */
6517 ast_log(LOG_WARNING, "Duplicate entry found (%s), ignoring.\n", cat);
6519 return NULL;
6520 }
6521 /* we're reloading right now */
6522 create = 0;
6523 break;
6524 }
6525 d = d->next;
6526 }
6528 if (!(lt = ast_calloc(1, sizeof(*lt)))) {
6529 return NULL;
6530 }
6531 if (create) {
6532 if (!(d = ast_calloc(1, sizeof(*d)))) {
6533 return NULL;
6534 }
6535 ast_mutex_init(&d->lock);
6536 ast_copy_string(d->name, cat, sizeof(d->name));
6537
6538 ast_copy_string(d->context, DEFAULTCONTEXT, sizeof(d->context));
6539 d->contrast = -1;
6540 d->output = OUTPUT_HANDSET;
6541 d->previous_output = OUTPUT_HANDSET;
6542 d->volume = VOLUME_LOW;
6543 d->microphone = MUTE_OFF;
6544 d->height = DEFAULTHEIGHT;
6545 d->selected = -1;
6546 d->interdigit_timer = DEFAULT_INTERDIGIT_TIMER;
6547 } else {
6548 /* Delete existing line information */
6549 AST_LIST_LOCK(&d->lines);
6550 AST_LIST_TRAVERSE_SAFE_BEGIN(&d->lines, l, list){
6553 }
6555 AST_LIST_UNLOCK(&d->lines);
6556
6557 /* reset bookmarks */
6558 memset(d->softkeylabel, 0, sizeof(d->softkeylabel));
6559 memset(d->softkeynumber, 0, sizeof(d->softkeynumber));
6560 memset(d->softkeyicon, 0, sizeof(d->softkeyicon));
6561 memset(d->softkeydevice, 0, sizeof(d->softkeydevice));
6562 memset(d->ssub, 0, sizeof(d->ssub));
6563 memset(d->sline, 0, sizeof(d->sline));
6564 memset(d->sp, 0, sizeof(d->sp));
6565 }
6566 linelabel[0] = '\0';
6567 dateformat = 1;
6568 timeformat = 1;
6569 ringvolume = 2;
6570 cwvolume = 1;
6571 callhistory = 1;
6572 sharpdial = 0;
6573 ringstyle = 3;
6574 cwstyle = 2;
6575 nbsoftkey = 0;
6576 linecnt = 0;
6577 d->dtmfduration = 0;
6578 while (v) {
6579 if (!strcasecmp(v->name, "rtp_port")) {
6580 d->rtp_port = atoi(v->value);
6581 } else if (!strcasecmp(v->name, "rtp_method")) {
6582 d->rtp_method = atoi(v->value);
6583 } else if (!strcasecmp(v->name, "status_method")) {
6584 d->status_method = atoi(v->value);
6585 } else if (!strcasecmp(v->name, "device")) {
6586 ast_copy_string(d->id, v->value, sizeof(d->id));
6587 } else if (!strcasecmp(v->name, "tn")) {
6588 ast_copy_string(d->extension_number, v->value, sizeof(d->extension_number));
6589 } else if (!strcasecmp(v->name, "permit") || !strcasecmp(v->name, "deny")) {
6590 int acl_error = 0;
6591 d->ha = ast_append_ha(v->name, v->value, d->ha, &acl_error);
6592 if (acl_error) {
6593 ast_log(LOG_ERROR, "Invalid ACL '%s' specified for device '%s' on line %d. Deleting device\n",
6594 v->value, cat, v->lineno);
6596 return NULL;
6597 }
6598 } else if (!strcasecmp(v->name, "context")) {
6599 ast_copy_string(d->context, v->value, sizeof(d->context));
6600 } else if (!strcasecmp(v->name, "maintext0")) {
6601 unquote(d->maintext0, v->value, sizeof(d->maintext0) - 1);
6602 } else if (!strcasecmp(v->name, "maintext1")) {
6603 unquote(d->maintext1, v->value, sizeof(d->maintext1) - 1);
6604 } else if (!strcasecmp(v->name, "maintext2")) {
6605 unquote(d->maintext2, v->value, sizeof(d->maintext2) - 1);
6606 } else if (!strcasecmp(v->name, "titledefault")) {
6607 unquote(d->titledefault, v->value, sizeof(d->titledefault) - 1);
6608 } else if (!strcasecmp(v->name, "dateformat")) {
6609 dateformat = atoi(v->value);
6610 } else if (!strcasecmp(v->name, "timeformat")) {
6611 timeformat = atoi(v->value);
6612 } else if (!strcasecmp(v->name, "contrast")) {
6613 d->contrast = atoi(v->value);
6614 if ((d->contrast < 0) || (d->contrast > 15)) {
6615 ast_log(LOG_WARNING, "contrast must be between 0 and 15\n");
6616 d->contrast = 8;
6617 }
6618 } else if (!strcasecmp(v->name, "nat")) {
6619 d->nat = ast_true(v->value);
6620 } else if (!strcasecmp(v->name, "hasexp")) {
6621 d->hasexp = ast_true(v->value);
6622 } else if (!strcasecmp(v->name, "ringvolume")) {
6623 ringvolume = atoi(v->value);
6624 } else if (!strcasecmp(v->name, "ringstyle")) {
6625 ringstyle = atoi(v->value);
6626 } else if (!strcasecmp(v->name, "cwvolume")) {
6627 cwvolume = atoi(v->value);
6628 } else if (!strcasecmp(v->name, "cwstyle")) {
6629 cwstyle = atoi(v->value);
6630 } else if (!strcasecmp(v->name, "callhistory")) {
6631 callhistory = atoi(v->value);
6632 } else if (!strcasecmp(v->name, "sharpdial")) {
6633 sharpdial = ast_true(v->value) ? 1 : 0;
6634 } else if (!strcasecmp(v->name, "interdigit_timer")) {
6635 d->interdigit_timer = atoi(v->value);
6636 } else if (!strcasecmp(v->name, "dtmf_duration")) {
6637 d->dtmfduration = atoi(v->value);
6638 if (d->dtmfduration > 150) {
6639 d->dtmfduration = 150;
6640 }
6641 } else if (!strcasecmp(v->name, "callerid")) {
6642 if (!strcasecmp(v->value, "asreceived")) {
6643 lt->cid_num[0] = '\0';
6644 } else {
6645 ast_copy_string(lt->cid_num, v->value, sizeof(lt->cid_num));
6646 }
6647 } else if (!strcasecmp(v->name, "language")) {
6648 ast_copy_string(d->language, v->value, sizeof(d->language));
6649 } else if (!strcasecmp(v->name, "country")) {
6650 ast_copy_string(d->country, v->value, sizeof(d->country));
6651 } else if (!strcasecmp(v->name, "accountcode")) {
6652 ast_copy_string(lt->accountcode, v->value, sizeof(lt->accountcode));
6653 } else if (!strcasecmp(v->name, "amaflags")) {
6654 int y;
6656 if (y < 0) {
6657 ast_log(LOG_WARNING, "Invalid AMA flags: %s at line %d\n", v->value,
6658 v->lineno);
6659 } else {
6660 lt->amaflags = y;
6661 }
6662 } else if (!strcasecmp(v->name, "musiconhold")) {
6663 ast_copy_string(lt->musicclass, v->value, sizeof(lt->musicclass));
6664 } else if (!strcasecmp(v->name, "callgroup")) {
6665 lt->callgroup = ast_get_group(v->value);
6666 } else if (!strcasecmp(v->name, "pickupgroup")) {
6667 lt->pickupgroup = ast_get_group(v->value);
6668 } else if (!strcasecmp(v->name, "mailbox")) {
6669 ast_copy_string(lt->mailbox, v->value, sizeof(lt->mailbox));
6670 } else if (!strcasecmp(v->name, "parkinglot")) {
6671 ast_copy_string(lt->parkinglot, v->value, sizeof(lt->parkinglot));
6672 } else if (!strcasecmp(v->name, "linelabel")) {
6673 unquote(linelabel, v->value, sizeof(linelabel) - 1);
6674 } else if (!strcasecmp(v->name, "extension")) {
6675 if (!strcasecmp(v->value, "none")) {
6676 d->extension = EXTENSION_NONE;
6677 } else if (!strcasecmp(v->value, "ask")) {
6678 d->extension = EXTENSION_ASK;
6679 } else if (!strcasecmp(v->value, "line")) {
6680 d->extension = EXTENSION_LINE;
6681 } else {
6682 ast_log(LOG_WARNING, "Unknown extension option.\n");
6683 }
6684 } else if (!strcasecmp(v->name, "bookmark")) {
6685 if (nbsoftkey > 5) {
6687 "More than 6 softkeys defined. Ignoring new entries.\n");
6688 } else {
6689 if (parse_bookmark(v->value, d)) {
6690 nbsoftkey++;
6691 }
6692 }
6693 } else if (!strcasecmp(v->name, "line")) {
6694 int len = strlen(linelabel);
6695 int create_line = 0;
6696
6697 l = find_line_by_number(d, v->value);
6698 if (!l) { /* If line still not exists */
6699 if (!(l = unistim_line_alloc())) {
6700 ast_free(d);
6701 ast_free(lt);
6702 return NULL;
6703 }
6704 lt->cap = l->cap;
6705 memcpy(l, lt, sizeof(*l));
6706 ast_mutex_init(&l->lock);
6707 create_line = 1;
6708 }
6709 d->to_delete = 0;
6710
6711 /* Set softkey info for new line*/
6712 d->sline[nbsoftkey] = l;
6713 d->softkeyicon[nbsoftkey] = FAV_LINE_ICON;
6714 if (!len) { /* label is undefined ? */
6715 ast_copy_string(d->softkeylabel[nbsoftkey], v->value, sizeof(d->softkeylabel[nbsoftkey]));
6716 } else {
6717 int softkeylinepos = 0;
6718 if ((len > 2) && (linelabel[1] == '@')) {
6719 softkeylinepos = linelabel[0];
6720 if ((softkeylinepos >= '0') && (softkeylinepos <= '5')) {
6721 softkeylinepos -= '0';
6722 d->softkeyicon[nbsoftkey] = FAV_ICON_NONE;
6723 } else {
6725 "Invalid position for linelabel : must be between 0 and 5\n");
6726 }
6727 ast_copy_string(d->softkeylabel[softkeylinepos], linelabel + 2,
6728 sizeof(d->softkeylabel[softkeylinepos]));
6729 d->softkeyicon[softkeylinepos] = FAV_LINE_ICON;
6730 } else {
6731 ast_copy_string(d->softkeylabel[nbsoftkey], linelabel,
6732 sizeof(d->softkeylabel[nbsoftkey]));
6733 }
6734 }
6735 nbsoftkey++;
6736
6737 if (create_line) {
6738 ast_copy_string(l->name, v->value, sizeof(l->name));
6739 snprintf(l->fullname, sizeof(l->fullname), "USTM/%s@%s", l->name, d->name);
6740 if (!ast_strlen_zero(l->mailbox)) {
6741 if (unistimdebug) {
6742 ast_verb(3, "Setting mailbox '%s' on %s@%s\n", l->mailbox, d->name, l->name);
6743 }
6744 }
6746 l->parent = d;
6747 linecnt++;
6748 AST_LIST_LOCK(&d->lines);
6749 AST_LIST_INSERT_TAIL(&d->lines, l, list);
6750 AST_LIST_UNLOCK(&d->lines);
6751 }
6752 } else if (!strcasecmp(v->name, "height")) {
6753 /* Allow the user to lower the expected display lines on the phone
6754 * For example the Nortel i2001 and i2002 only have one ! */
6755 d->height = atoi(v->value);
6756 } else
6757 ast_log(LOG_WARNING, "Don't know keyword '%s' at line %d\n", v->name,
6758 v->lineno);
6759 v = v->next;
6760 }
6761 ast_free(lt);
6762 if (linecnt == 0) {
6763 ast_log(LOG_ERROR, "An Unistim device must have at least one line!\n");
6764 ast_free(d);
6765 return NULL;
6766 }
6767 d->ringvolume = ringvolume;
6768 d->ringstyle = ringstyle;
6769 d->cwvolume = cwvolume;
6770 d->cwstyle = cwstyle;
6771 d->callhistory = callhistory;
6772 d->sharp_dial = sharpdial;
6773 d->tz = ast_get_indication_zone(d->country);
6774 if ((d->tz == NULL) && !ast_strlen_zero(d->country)) {
6775 ast_log(LOG_WARNING, "Country '%s' was not found in indications.conf\n",
6776 d->country);
6777 }
6778 d->datetimeformat = 48 + (dateformat * 4);
6779 d->datetimeformat += timeformat;
6781 (!ast_strlen_zero(d->extension_number))) {
6782 d->extension = EXTENSION_TN;
6783 if (!ast_strlen_zero(d->id)) {
6785 "tn= and device= can't be used together. Ignoring device= entry\n");
6786 }
6787 d->id[0] = 'T'; /* magic : this is a tn entry */
6788 ast_copy_string((d->id) + 1, d->extension_number, sizeof(d->id) - 1);
6789 d->extension_number[0] = '\0';
6790 } else if (ast_strlen_zero(d->id)) {
6791 if (strcmp(d->name, "template")) {
6792 ast_log(LOG_ERROR, "You must specify the mac address with device=\n");
6793 if (d->tz) {
6794 d->tz = ast_tone_zone_unref(d->tz);
6795 }
6796 ast_free(d);
6797 return NULL;
6798 } else {
6799 strcpy(d->id, "000000000000");
6800 }
6801 }
6802 if (!d->rtp_port) {
6803 d->rtp_port = 10000;
6804 }
6805 if (d->contrast == -1) {
6806 d->contrast = 8;
6807 }
6808 if (ast_strlen_zero(d->maintext1)) {
6809 strcpy(d->maintext1, d->name);
6810 }
6811 if (ast_strlen_zero(d->titledefault)) {
6812 struct ast_tm tm = { 0, };
6813 struct timeval cur_time = ast_tvnow();
6814
6815 if ((ast_localtime(&cur_time, &tm, 0)) == 0 || ast_strlen_zero(tm.tm_zone)) {
6816 ast_log(LOG_WARNING, "Error in ast_localtime()\n");
6817 ast_copy_string(d->titledefault, "UNISTIM for*", 12);
6818 } else {
6819 if (strlen(tm.tm_zone) < 4) {
6820 strcpy(d->titledefault, "TimeZone ");
6821 strcat(d->titledefault, tm.tm_zone);
6822 } else if (strlen(tm.tm_zone) < 9) {
6823 strcpy(d->titledefault, "TZ ");
6824 strcat(d->titledefault, tm.tm_zone);
6825 } else {
6826 ast_copy_string(d->titledefault, tm.tm_zone, 12);
6827 }
6828 }
6829 }
6830 /* Update the chained link if it's a new device */
6831 if (create) {
6833 d->next = devices;
6834 devices = d;
6836 ast_verb(3, "Added device '%s'\n", d->name);
6837 } else {
6838 ast_verb(3, "Device '%s' reloaded\n", d->name);
6839 }
6840 return d;
6841}
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:4354
ast_group_t ast_get_group(const char *s)
Definition channel.c:7630
#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]
struct unistim_line::@140 list
ast_mutex_t lock
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 2472 of file chan_unistim.c.

2473{
2474 char *data;
2475 int size;
2476
2477 if (type) {
2478 data = pte->device->lst_cnm;
2479 } else {
2480 data = pte->device->lst_cid;
2481 }
2482
2483 /* This is very nearly strncpy(), except that the remaining buffer
2484 * is padded with ' ', instead of '\0' */
2485 memset(data, ' ', TEXT_LENGTH_MAX);
2486 size = strlen(callerid);
2487 if (size > TEXT_LENGTH_MAX) {
2488 size = TEXT_LENGTH_MAX;
2489 }
2490 memcpy(data, callerid, size);
2491}
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 1418 of file chan_unistim.c.

1419{
1420 struct unistim_device *d = devices;
1421 int i;
1422 /* Update the current phone line softkey icon */
1423 if (pte->state != STATE_CLEANING) {
1424 int softkeylinepos = get_active_softkey(pte);
1425 if (softkeylinepos != -1) {
1426 send_favorite_short(softkeylinepos, status, pte);
1427 }
1428 }
1429 /* Notify other phones if we're in their bookmark */
1430 while (d) {
1431 for (i = 0; i < FAVNUM; i++) {
1432 if (d->sp[i] == pte->device) { /* It's us ? */
1433 if (d->softkeyicon[i] != status) { /* Avoid resending the same icon */
1434 d->softkeyicon[i] = status;
1435 if (d->session) {
1436 send_favorite(i, status + 1, d->session, d->softkeylabel[i]);
1437 }
1438 }
1439 }
1440 }
1441 d = d->next;
1442 }
1443}
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 4794 of file chan_unistim.c.

4795{
4796 struct unistim_subchannel *sub;
4797 if (!ast) {
4798 ast_log(LOG_WARNING, "Unistim callback function called with a null channel\n");
4799 return NULL;
4800 }
4801 if (!ast_channel_tech_pvt(ast)) {
4802 ast_log(LOG_WARNING, "Unistim callback function called without a tech_pvt\n");
4803 return NULL;
4804 }
4806
4807 if (!sub->parent) {
4808 ast_log(LOG_WARNING, "Unistim callback function called without a line\n");
4809 return NULL;
4810 }
4811 if (!sub->parent->parent) {
4812 ast_log(LOG_WARNING, "Unistim callback function called without a device\n");
4813 return NULL;
4814 }
4815 ast_mutex_lock(&sub->parent->parent->lock);
4816 if (!sub->parent->parent->session) {
4817 ast_log(LOG_WARNING, "Unistim callback function called without a session\n");
4818 ast_mutex_unlock(&sub->parent->parent->lock);
4819 return NULL;
4820 }
4821 ast_mutex_unlock(&sub->parent->parent->lock);
4822 return sub->parent->parent->session;
4823}
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 1101 of file chan_unistim.c.

1102{
1103 /* Check if our send queue contained only one element */
1104 if (pte->last_buf_available == 1) {
1105 if (unistimdebug) {
1106 ast_verb(0, "Our single packet was ACKed.\n");
1107 }
1108 pte->last_buf_available--;
1109 set_ping_timer(pte);
1110 return;
1111 }
1112 /* Check if this ACK catch up our latest packet */
1113 else if (pte->last_seq_ack + 1 == pte->seq_server + 1) {
1114 if (unistimdebug) {
1115 ast_verb(0, "Our send queue is completely ACKed.\n");
1116 }
1117 pte->last_buf_available = 0; /* Purge the send queue */
1118 set_ping_timer(pte);
1119 return;
1120 }
1121 if (unistimdebug) {
1122 ast_verb(0, "We still have packets in our send queue\n");
1123 }
1124 return;
1125}
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 2599 of file chan_unistim.c.

2600{
2601 struct unistim_subchannel *sub, *sub_transf;
2602
2603 sub = get_sub(pte->device, SUB_REAL);
2604 sub_transf = get_sub(pte->device, SUB_THREEWAY);
2605 send_stop_timer(pte);
2606 if (!sub) {
2607 ast_log(LOG_WARNING, "Close call without sub\n");
2608 return;
2609 }
2610 send_favorite_short(sub->softkey, FAV_LINE_ICON, pte);
2611 if (sub->owner) {
2612 sub->alreadygone = 1;
2613 if (sub_transf) {
2614 sub_transf->alreadygone = 1;
2615 if (attempt_transfer(sub, sub_transf) < 0) {
2616 ast_verb(0, "attempt_transfer failed.\n");
2617 }
2618 } else {
2619 ast_queue_hangup(sub->owner);
2620 }
2621 } else {
2622 if (sub_transf) {
2623 if (sub_transf->owner) {
2625 } else {
2626 ast_log(LOG_WARNING, "threeway sub without owner\n");
2627 }
2628 } else {
2629 ast_verb(0, "USTM(%s@%s-%d) channel already destroyed\n", sub->parent->name,
2630 pte->device->name, sub->softkey);
2631 }
2632 }
2633 change_callerid(pte, 0, pte->device->redial_number);
2634 change_callerid(pte, 1, "");
2635 write_history(pte, 'o', pte->device->missed_call);
2636 pte->device->missed_call = 0;
2637 show_main_page(pte);
2638 return;
2639}
#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:1181
int ast_queue_hangup_with_cause(struct ast_channel *chan, int cause)
Queue a hangup frame with hangupcause set.
Definition channel.c:1212
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 1470 of file chan_unistim.c.

1471{
1472 struct unistim_subchannel *sub = NULL;
1473 struct unistimsession *cur, *prev = NULL;
1475 cur = sessions;
1476 /* Looking for the session in the linked chain */
1477 while (cur) {
1478 if (cur == s) {
1479 break;
1480 }
1481 prev = cur;
1482 cur = cur->next;
1483 }
1484 if (cur) { /* Session found ? */
1485 if (cur->device) { /* This session was registered ? */
1486 s->state = STATE_CLEANING;
1487 if (unistimdebug) {
1488 ast_verb(0, "close_client session %p device %p\n", s, s->device);
1489 }
1494 if (!sub) {
1495 continue;
1496 }
1497 if (sub->owner) { /* Call in progress ? */
1498 if (unistimdebug) {
1499 ast_verb(0, "Aborting call\n");
1500 }
1502 } else {
1503 if (unistimdebug) {
1504 ast_debug(1, "Released sub %u of channel %s@%s\n", sub->subtype, sub->parent->name, s->device->name);
1505 }
1508 }
1509 }
1512
1515 }
1516 cur->device->session = NULL;
1518 } else {
1519 if (unistimdebug) {
1520 ast_verb(0, "Freeing an unregistered client\n");
1521 }
1522 }
1523 if (prev) {
1524 prev->next = cur->next;
1525 } else {
1526 sessions = cur->next;
1527 }
1529 ast_free(s);
1530 } else {
1531 ast_log(LOG_WARNING, "Trying to delete non-existent session %p?\n", s);
1532 }
1534 return;
1535}
#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::@141 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 5277 of file chan_unistim.c.

5278{
5279 switch (ind) {
5280 case AST_CONTROL_HANGUP:
5281 return "Other end has hungup";
5282 case AST_CONTROL_RING:
5283 return "Local ring";
5285 return "Remote end is ringing";
5286 case AST_CONTROL_ANSWER:
5287 return "Remote end has answered";
5288 case AST_CONTROL_BUSY:
5289 return "Remote end is busy";
5291 return "Make it go off hook";
5293 return "Line is off hook";
5295 return "Congestion (circuits busy)";
5296 case AST_CONTROL_FLASH:
5297 return "Flash hook";
5298 case AST_CONTROL_WINK:
5299 return "Wink";
5300 case AST_CONTROL_OPTION:
5301 return "Set a low-level option";
5303 return "Key Radio";
5305 return "Un-Key Radio";
5307 return "Remote end changed";
5309 return "RTP source updated";
5311 return "Source of media changed";
5312 case -1:
5313 return "Stop tone";
5314 }
5315 return "UNKNOWN";
5316}
@ 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 1046 of file chan_unistim.c.

1047{
1048 int tmp;
1049 struct unistimsession *s;
1050
1051 if (!(s = ast_calloc(1, sizeof(*s))))
1052 return NULL;
1053
1054 memcpy(&s->sin, addr_from, sizeof(struct sockaddr_in));
1055 if (get_to_address(unistimsock, &s->sout) < 0) {
1056 ast_free(s);
1057 return NULL;
1058 }
1059 s->sout.sin_family = AF_INET;
1060 if (unistimdebug) {
1061 ast_verb(0, "Creating a new entry for the phone from %s received via server ip %s\n",
1062 ast_inet_ntoa(addr_from->sin_addr), ast_inet_ntoa(s->sout.sin_addr));
1063 }
1064 ast_mutex_init(&s->lock);
1066 s->next = sessions;
1067 sessions = s;
1068
1070 s->state = STATE_INIT;
1072 /* Initialize struct wsabuf */
1073 for (tmp = 0; tmp < MAX_BUF_NUMBER; tmp++) {
1074 s->wsabufsend[tmp].buf = s->buf[tmp];
1075 }
1077 return s;
1078}
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 6420 of file chan_unistim.c.

6421{
6422 struct unistim_line *l;
6423 struct unistim_subchannel *sub;
6424 struct unistimsession *s;
6425
6426 if (unistimdebug) {
6427 ast_verb(0, "Removing device '%s'\n", d->name);
6428 }
6429 AST_LIST_LOCK(&d->subs);
6430 AST_LIST_TRAVERSE_SAFE_BEGIN(&d->subs, sub, list){
6431 if (sub->subtype == SUB_REAL) {
6432 if (sub->owner) {
6434 "Device '%s' was not deleted : a call is in progress. Try again later.\n",
6435 d->name);
6436 AST_LIST_UNLOCK(&d->subs);
6437 return;
6438 }
6439 }
6440 if (sub->subtype == SUB_THREEWAY) {
6442 "Device '%s' with threeway call subchannels allocated, aborting.\n",
6443 d->name);
6444 AST_LIST_UNLOCK(&d->subs);
6445 return;
6446 }
6448 ast_mutex_destroy(&sub->lock);
6449 ast_free(sub);
6450 }
6452 AST_LIST_UNLOCK(&d->subs);
6453
6454
6455 AST_LIST_LOCK(&d->lines);
6456 AST_LIST_TRAVERSE_SAFE_BEGIN(&d->lines, l, list){
6460 }
6462 AST_LIST_UNLOCK(&d->lines);
6463
6464 if (d->session) {
6465 if (sessions == d->session) {
6466 sessions = d->session->next;
6467 } else {
6468 s = sessions;
6469 while (s) {
6470 if (s->next == d->session) {
6471 s->next = d->session->next;
6472 break;
6473 }
6474 s = s->next;
6475 }
6476 }
6477 ast_mutex_destroy(&d->session->lock);
6478 ast_free(d->session);
6479 }
6480 if (devices == d) {
6481 devices = d->next;
6482 } else {
6483 struct unistim_device *d2 = devices;
6484 while (d2) {
6485 if (d2->next == d) {
6486 d2->next = d->next;
6487 break;
6488 }
6489 d2 = d2->next;
6490 }
6491 }
6492 if (d->tz) {
6493 d->tz = ast_tone_zone_unref(d->tz);
6494 }
6495 ast_mutex_destroy(&d->lock);
6496 ast_free(d);
6497}
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 2647 of file chan_unistim.c.

2648{
2649 struct unistim_subchannel* sub;
2650 sub = get_sub(pte->device, SUB_RING);
2651 if (!sub) {
2652 return;
2653 }
2654
2656 return;
2657}
#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 889 of file chan_unistim.c.

890{
891 /* Display the error message */
892 ast_log(LOG_WARNING, "%s : (%d) %s\n", sz_msg, errno, strerror(errno));
893}
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 5833 of file chan_unistim.c.

5834{
5835 struct unistimsession *cur = NULL;
5836 unsigned int dw_timeout = 0;
5837 unsigned int tick;
5838 int res;
5839 int reloading;
5840
5841 /* Add an I/O event to our UDP socket */
5842 if (unistimsock > -1) {
5844 }
5845 /* This thread monitors our UDP socket and timers */
5846 for (;;) {
5847 /* This loop is executed at least every IDLE_WAITus (1s) or every time a packet is received */
5848 /* Looking for the smallest time-out value */
5849 tick = get_tick_count();
5850 dw_timeout = UINT_MAX;
5852 cur = sessions;
5853 DEBUG_TIMER("checking timeout for session %p with tick = %u\n", cur, tick);
5854 while (cur) {
5855 DEBUG_TIMER("checking timeout for session %p timeout = %u\n", cur,
5856 cur->timeout);
5857 /* Check if we have miss something */
5858 if (cur->timeout <= tick) {
5859 DEBUG_TIMER("Event for session %p\n", cur);
5860 /* If the queue is empty, send a ping */
5861 if (cur->last_buf_available == 0) {
5862 send_ping(cur);
5863 } else {
5864 if (send_retransmit(cur)) {
5865 DEBUG_TIMER("The chained link was modified, restarting...\n");
5866 cur = sessions;
5867 dw_timeout = UINT_MAX;
5868 continue;
5869 }
5870 }
5871 }
5872 if (dw_timeout > cur->timeout - tick) {
5873 dw_timeout = cur->timeout - tick;
5874 }
5875 /* Checking if the phone is logged on for a new MWI */
5876 if (cur->device) {
5877 struct unistim_line *l;
5878 AST_LIST_LOCK(&cur->device->lines);
5879 AST_LIST_TRAVERSE(&cur->device->lines, l, list) {
5880 if ((!ast_strlen_zero(l->mailbox)) && (tick >= l->parent->nextmsgcheck)) {
5881 DEBUG_TIMER("Checking mailbox for MWI\n");
5882 unistim_send_mwi_to_peer(l, tick);
5883 break;
5884 }
5885 }
5887 if (cur->device->nextdial && tick >= cur->device->nextdial) {
5889 cur->device->nextdial = 0;
5890 }
5891 }
5892 cur = cur->next;
5893 }
5895 DEBUG_TIMER("Waiting for %dus\n", dw_timeout);
5896 res = dw_timeout;
5897 /* We should not wait more than IDLE_WAIT */
5898 if ((res < 0) || (res > IDLE_WAIT)) {
5899 res = IDLE_WAIT;
5900 }
5901 /* Wait for UDP messages for a maximum of res us */
5902 res = ast_io_wait(io, res); /* This function will call unistimsock_read if a packet is received */
5903 /* Check for a reload request */
5905 reloading = unistim_reloading;
5908 if (reloading) {
5909 ast_verb(1, "Reloading unistim.conf...\n");
5910 reload_config();
5911 }
5912 pthread_testcancel();
5913 }
5914 /* Never reached */
5915 return NULL;
5916}
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::@142 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 3807 of file chan_unistim.c.

3808{
3809 int i = 0;
3810 while (options_languages[i].lang_short != NULL) {
3811 if(!strcmp(options_languages[i].lang_short, lang)) {
3812 return i;
3813 }
3814 i++;
3815 }
3816 return 0;
3817}
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 6406 of file chan_unistim.c.

6406 {
6407 struct unistim_line *l, *ret = NULL;
6408
6409 AST_LIST_LOCK(&d->lines);
6410 AST_LIST_TRAVERSE(&d->lines, l, list) {
6411 if (!strcmp(l->name, val)) {
6412 ret = l;
6413 break;
6414 }
6415 }
6416 AST_LIST_UNLOCK(&d->lines);
6417 return ret;
6418}

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

2686{
2687 struct unistim_subchannel *sub = NULL;
2688 int rtp_start = s->parent->parent->rtp_port;
2689 struct ast_sockaddr us_tmp;
2690 struct sockaddr_in us = { 0, };
2691
2693 AST_LIST_TRAVERSE(&s->parent->parent->subs, sub, list) {
2694 if (!sub) {
2695 continue;
2696 }
2697 if (sub->rtp) {
2699 ast_sockaddr_to_sin(&us_tmp, &us);
2700 if (htons(us.sin_port)) {
2701 rtp_start = htons(us.sin_port) + 1;
2702 break;
2703 }
2704 }
2705 }
2707 return rtp_start;
2708}
#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 5419 of file chan_unistim.c.

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

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

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

1381{
1382 return pte->device->selected;
1383}

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

1386{
1387 int i;
1388
1389 if (!is_key_line(pte->device, pte->device->selected)) {
1390 pte->device->selected = -1;
1391 }
1392 for (i = 0; i < FAVNUM; i++) {
1393 if (pte->device->selected != -1 && pte->device->selected != i) {
1394 continue;
1395 }
1396 if (!soft_key_visible(pte->device, i)) {
1397 continue;
1398 }
1399 if (pte->device->ssub[i]) {
1400 continue;
1401 }
1402 if (is_key_line(pte->device, i)) {
1403 if (name && strcmp(name, pte->device->sline[i]->name)) {
1404 continue;
1405 }
1406 if (unistimdebug) {
1407 ast_verb(0, "Found softkey %d for device %s\n", i, name);
1408 }
1409 return i;
1410 }
1411 }
1412 return -1;
1413}
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 2511 of file chan_unistim.c.

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

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

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

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

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

3263{
3264 struct unistim_subchannel *sub = NULL;
3265 int i;
3266
3267 s->state = STATE_CALL;
3268 s->device->missed_call = 0;
3269 send_no_ring(s);
3270 sub = get_sub(s->device, SUB_RING); /* Put other SUB_REAL call on hold */
3271 if (!sub) {
3272 ast_log(LOG_WARNING, "No ringing lines on: %s\n", s->device->name);
3273 return;
3274 }
3275 /* Change icons for all ringing keys */
3276 for (i = 0; i < FAVNUM; i++) {
3277 if (!s->device->ssub[i]) { /* No sub assigned - skip */
3278 continue;
3279 }
3280 if (s->device->ssub[i]->subtype == SUB_REAL) {
3281 sub_hold(s, s->device->ssub[i]);
3282 }
3283 if (s->device->ssub[i] != sub) {
3284 continue;
3285 }
3286 if (sub->softkey == i) { /* If softkey assigned at this moment - do not erase */
3287 continue;
3288 }
3289 if (sub->softkey < 0) { /* If softkey not defined - first one used */
3290 sub->softkey = i;
3291 continue;
3292 }
3294 s->device->ssub[i] = NULL;
3295 }
3296 if (sub->softkey < 0) {
3297 ast_log(LOG_WARNING, "Can not assign softkey for incoming call on: %s\n", s->device->name);
3298 return;
3299 }
3301 sub->parent = s->device->sline[sub->softkey];
3302 sub->subtype = SUB_REAL;
3303 if (unistimdebug) {
3304 ast_verb(0, "Handle Call Incoming for %s@%s\n", sub->parent->name,
3305 s->device->name);
3306 }
3307 start_rtp(sub);
3308 if (!sub->rtp) {
3309 ast_log(LOG_WARNING, "Unable to create channel for %s@%s\n", sub->parent->name, s->device->name);
3310 return;
3311 }
3312 if (sub->owner) {
3314 }
3315 send_text(TEXT_LINE2, TEXT_NORMAL, s, ustmtext("is on-line", s));
3316 send_text_status(s, ustmtext(" Transf Hangup", s));
3318
3319 if ((s->device->output == OUTPUT_HANDSET) &&
3322 } else {
3324 }
3325 write_history(s, 'i', 0);
3326 return;
3327}
#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:1288
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 3111 of file chan_unistim.c.

3112{
3113 struct ast_channel *c;
3114 struct unistim_subchannel *sub;
3115 int softkey;
3116
3117 s->state = STATE_CALL;
3118
3120 if (sub) {
3121 /* If sub for threway call created than we use transfer behavior */
3122 struct unistim_subchannel *sub_trans = NULL;
3123 struct unistim_device *d = s->device;
3124
3125 sub_trans = get_sub(d, SUB_REAL);
3126 if (sub_trans) {
3127 ast_log(LOG_WARNING, "Can't transfer while active subchannel exists!\n");
3128 return;
3129 }
3130 if (!sub->owner) {
3131 ast_log(LOG_WARNING, "Unable to find subchannel with music on hold\n");
3132 return;
3133 }
3134
3135 sub_trans = unistim_alloc_sub(d, SUB_REAL);
3136 if (!sub_trans) {
3137 ast_log(LOG_WARNING, "Unable to allocate three-way subchannel\n");
3138 return;
3139 }
3140 sub_trans->parent = sub->parent;
3142 send_tone(s, 0, 0);
3143 /* Make new channel */
3144 c = unistim_new(sub_trans, AST_STATE_DOWN, NULL, NULL);
3145 if (!c) {
3146 ast_log(LOG_WARNING, "Cannot allocate new structure on channel %p\n", sub->parent);
3147 return;
3148 }
3149 /* Swap things around between the three-way and real call */
3150 swap_subs(sub, sub_trans);
3152 if (s->device->height == 1) {
3154 } else {
3155 send_text(TEXT_LINE0, TEXT_NORMAL, s, ustmtext("Calling (pre-transfer)", s));
3157 send_text(TEXT_LINE2, TEXT_NORMAL, s, ustmtext("Dialing...", s));
3158 }
3159 send_text_status(s, ustmtext("TransfrCancel", s));
3160
3161 if (ast_pthread_create(&sub->ss_thread, NULL, unistim_ss, c)) {
3162 ast_log(LOG_WARNING, "Unable to start simple switch on channel %p\n", c);
3163 sub->ss_thread = AST_PTHREADT_NULL;
3164 ast_hangup(c);
3165 return;
3166 }
3167 if (unistimdebug) {
3168 ast_verb(0, "Started three way call on channel %p (%s) subchan %u\n",
3169 sub_trans->owner, ast_channel_name(sub_trans->owner), sub_trans->subtype);
3170 }
3171 return;
3172 }
3173
3174 softkey = get_avail_softkey(s, NULL);
3175 if (softkey == -1) {
3176 ast_log(LOG_WARNING, "Have no avail softkey for calling\n");
3177 return;
3178 }
3179 sub = get_sub(s->device, SUB_REAL);
3180 if (sub) { /* have already call assigned */
3181 sub_hold(s, sub); /* Need to put on hold */
3182 }
3183 if (!(sub = unistim_alloc_sub(s->device, SUB_REAL))) {
3184 ast_log(LOG_WARNING, "Unable to allocate subchannel!\n");
3185 return;
3186 }
3187 sub->parent = s->device->sline[softkey];
3188 s->device->ssub[softkey] = sub;
3189 sub->softkey = softkey;
3190
3191 if (unistimdebug) {
3192 ast_verb(0, "Using softkey %d, line %p\n", sub->softkey, sub->parent);
3193 }
3195 s->device->selected = -1;
3196 if (!sub->owner) { /* A call is already in progress ? */
3197 RAII_VAR(struct ast_features_pickup_config *, pickup_cfg, NULL, ao2_cleanup);
3198 const char *pickupexten;
3199
3200 c = unistim_new(sub, AST_STATE_DOWN, NULL, NULL); /* No, starting a new one */
3201 if (!sub->rtp) { /* Need to start RTP before calling ast_pbx_run */
3202 start_rtp(sub);
3203 }
3204 if (c) {
3207 if (!pickup_cfg) {
3208 ast_log(LOG_ERROR, "Unable to retrieve pickup configuration options. Unable to detect call pickup extension\n");
3209 pickupexten = "";
3210 } else {
3211 pickupexten = ast_strdupa(pickup_cfg->pickupexten);
3212 }
3214 }
3215 if (c && !strcmp(s->device->phone_number, pickupexten)) {
3216 if (unistimdebug) {
3217 ast_verb(0, "Try to pickup in unistim_new\n");
3218 }
3220 send_text_status(s, ustmtext(" Transf Hangup", s));
3222 if (ast_pickup_call(c)) {
3223 ast_log(LOG_NOTICE, "Nothing to pick up\n");
3225 } else {
3227 }
3228 ast_hangup(c);
3229 c = NULL;
3230 } else if (c) {
3232 send_tone(s, 0, 0); /* Dialing empty number should also stop dial tone */
3233 if (s->device->height == 1) {
3234 if (strlen(s->device->phone_number) > 0) {
3236 } else {
3237 send_text(TEXT_LINE0, TEXT_NORMAL, s, ustmtext("Calling...", s));
3238 }
3239 } else {
3240 send_text(TEXT_LINE0, TEXT_NORMAL, s, ustmtext("Calling :", s));
3242 send_text(TEXT_LINE2, TEXT_NORMAL, s, ustmtext("Dialing...", s));
3243 }
3244 send_text_status(s, ustmtext(" Hangup", s));
3245
3246 /* start switch */
3247 if (ast_pthread_create(&sub->ss_thread, NULL, unistim_ss, c)) {
3248 ast_log(LOG_WARNING, "Unable to create switch thread\n");
3249 sub->ss_thread = AST_PTHREADT_NULL;
3251 }
3252 } else
3253 ast_log(LOG_WARNING, "Unable to create channel for %s@%s\n",
3254 sub->parent->name, s->device->name);
3255 } else {
3256 ast_debug(1, "Current sub [%s] already has owner\n", ast_channel_name(sub->owner));
3257 }
3258 return;
3259}
#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:2538
#define ast_channel_lock(chan)
Definition channel.h:2982
void ast_channel_hangupcause_set(struct ast_channel *chan, int value)
#define ast_channel_unlock(chan)
Definition channel.h:2983
@ 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 2983 of file chan_unistim.c.

2984{
2985 pte->state = STATE_DIALPAGE;
2986 if (pte->device->call_forward[0] == -1) {
2987 send_text(TEXT_LINE0, TEXT_NORMAL, pte, "");
2988 send_text(TEXT_LINE1, TEXT_NORMAL, pte, ustmtext("Enter forward", pte));
2989 send_text_status(pte, ustmtext("Fwd Cancel BackSp Erase", pte));
2990 if (pte->device->call_forward[1] != 0) {
2992 sizeof(pte->device->phone_number));
2993 show_phone_number(pte);
2995 return;
2996 }
2997 } else {
2998 if ((pte->device->output == OUTPUT_HANDSET) &&
2999 (pte->device->receiver_state == STATE_ONHOOK)) {
3001 } else {
3003 }
3004 send_dial_tone(pte);
3005
3006 if (pte->device->height > 1) {
3007 send_text(TEXT_LINE0, TEXT_NORMAL, pte, ustmtext("Enter the number to dial", pte));
3008 send_text(TEXT_LINE1, TEXT_NORMAL, pte, ustmtext("and press Call", pte));
3009 }
3011 send_text_status(pte, ustmtext("Call BackSp Erase", pte));
3012 } else {
3013 send_text_status(pte, ustmtext("Call Redial BackSp Erase", pte));
3014 }
3015 }
3016
3017 pte->device->size_phone_number = 0;
3018 pte->device->phone_number[0] = 0;
3019 show_phone_number(pte);
3022 pte->device->missed_call = 0;
3024 pte->device->lastmsgssent = -1;
3025 return;
3026}
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 3380 of file chan_unistim.c.

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

3733{
3734 char buf[30], buf2[6];
3735
3736 pte->state = STATE_SELECTCODEC;
3737 ast_copy_string(buf, ustmtext("Using codec", pte), sizeof(buf));
3738 snprintf(buf2, sizeof(buf2), " %d", pte->device->codec_number);
3739 strcat(buf, buf2);
3740 strcat(buf, " (G711u=0,");
3741
3743 send_text(TEXT_LINE1, TEXT_NORMAL, pte, "G723=4,G711a=8,G729A=18)");
3745 send_blink_cursor(pte);
3747 pte->size_buff_entry = 0;
3748 send_text_status(pte, ustmtext("Select BackSp Erase Cancel", pte));
3749 return;
3750}
#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 3819 of file chan_unistim.c.

3820{
3821 char tmp_language[40];
3822 struct unistim_languages lang;
3823
3824 if (pte->state != STATE_SELECTLANGUAGE) {
3826 pte->size_buff_entry = 1;
3827 pte->buff_entry[0] = find_language(pte->device->language);
3828 }
3829 lang = options_languages[(int)pte->buff_entry[0]];
3830 ast_copy_string(tmp_language, pte->device->language, sizeof(tmp_language));
3831 ast_copy_string(pte->device->language, lang.lang_short, sizeof(pte->device->language));
3832 send_charset_update(pte, lang.encoding);
3833 send_text(TEXT_LINE0, TEXT_NORMAL, pte, ustmtext(lang.label, pte));
3834
3835 ast_copy_string(pte->device->language, tmp_language, sizeof(pte->device->language));
3837 send_charset_update(pte, lang.encoding);
3838 send_text_status(pte, ustmtext("Select Cancel", pte));
3839 return;
3840}
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 3687 of file chan_unistim.c.

3688{
3689 char tmp[128];
3690
3691 if (pte->state != STATE_SELECTOPTION) {
3693 pte->size_buff_entry = 1;
3694 pte->buff_entry[0] = 0; /* Position in menu */
3695 }
3696 snprintf(tmp, sizeof(tmp), "%d. %s", pte->buff_entry[0] + 1, ustmtext(options_menu[(int)pte->buff_entry[0]].label, pte));
3697 send_text(TEXT_LINE0, TEXT_NORMAL, pte, tmp);
3698 send_text_status(pte, ustmtext("Select Cancel", pte));
3699 return;
3700}
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 2641 of file chan_unistim.c.

2642{
2643 send_no_ring(pte);
2644 return;
2645}

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

5320{
5321 struct ast_tone_zone_sound *ts = NULL;
5322
5323 if ((ts = ast_get_indication_tone(tz, indication))) {
5324 ast_playtones_start(ast, 0, ts->data, 1);
5326 } else {
5327 ast_log(LOG_WARNING, "Unable to get indication tone for %s\n", indication);
5328 }
5329}
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 4381 of file chan_unistim.c.

4382{
4383 BUFFSEND;
4384 if (unistimdebug) {
4385 ast_verb(0, "Sending S4\n");
4386 }
4387 memcpy(buffsend + SIZE_HEADER, packet_send_s4, sizeof(packet_send_s4));
4388 send_client(SIZE_HEADER + sizeof(packet_send_s4), buffsend, pte);
4389 send_date_time2(pte);
4390 send_date_time3(pte);
4391 if (unistimdebug) {
4392 ast_verb(0, "Sending S7\n");
4393 }
4394 memcpy(buffsend + SIZE_HEADER, packet_send_S7, sizeof(packet_send_S7));
4395 send_client(SIZE_HEADER + sizeof(packet_send_S7), buffsend, pte);
4396 if (unistimdebug) {
4397 ast_verb(0, "Sending Contrast\n");
4398 }
4399 memcpy(buffsend + SIZE_HEADER, packet_send_Contrast, sizeof(packet_send_Contrast));
4400 if (pte->device != NULL) {
4401 buffsend[9] = pte->device->contrast;
4402 }
4403 send_client(SIZE_HEADER + sizeof(packet_send_Contrast), buffsend, pte);
4404
4405 if (unistimdebug) {
4406 ast_verb(0, "Sending S9\n");
4407 }
4408 memcpy(buffsend + SIZE_HEADER, packet_send_s9, sizeof(packet_send_s9));
4409 send_client(SIZE_HEADER + sizeof(packet_send_s9), buffsend, pte);
4410 send_no_ring(pte);
4411
4412 if (unistimdebug) {
4413 ast_verb(0, "Sending S7\n");
4414 }
4415 memcpy(buffsend + SIZE_HEADER, packet_send_S7, sizeof(packet_send_S7));
4416 send_client(SIZE_HEADER + sizeof(packet_send_S7), buffsend, pte);
4418 send_ping(pte);
4419 if (unistimdebug) {
4420 ast_verb(0, "Sending init language\n");
4421 }
4422 if (pte->device) {
4424 }
4425 if (pte->state < STATE_MAINPAGE) {
4428 return;
4429 } else {
4430 int i;
4431 char tmp[30];
4432
4433 for (i = 1; i < FAVNUM; i++) {
4434 send_favorite(i, 0, pte, "");
4435 }
4436 send_text(TEXT_LINE0, TEXT_NORMAL, pte, ustmtext("Phone is not registered", pte));
4437 send_text(TEXT_LINE1, TEXT_NORMAL, pte, ustmtext("in unistim.conf", pte));
4438 strcpy(tmp, "MAC = ");
4439 strcat(tmp, pte->macaddr);
4440 send_text(TEXT_LINE2, TEXT_NORMAL, pte, tmp);
4441 send_text_status(pte, "");
4442 send_texttitle(pte, ustmtext("UNISTIM for*", pte));
4443 return;
4444 }
4445 }
4446 show_main_page(pte);
4448 if (unistimdebug) {
4449 ast_verb(0, "Sending arrow\n");
4450 }
4451 memcpy(buffsend + SIZE_HEADER, packet_send_arrow, sizeof(packet_send_arrow));
4452 send_client(SIZE_HEADER + sizeof(packet_send_arrow), buffsend, pte);
4453 return;
4454}
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 1352 of file chan_unistim.c.

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

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

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

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

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

3562{
3564
3565 pte->device->nextdial = 0;
3566 if (keycode == KEY_FUNC3) {
3567 if (pte->device->size_phone_number <= 1) {
3568 keycode = KEY_FUNC4;
3569 } else {
3570 pte->device->size_phone_number -= 2;
3571 keycode = pte->device->phone_number[pte->device->size_phone_number] + 0x10;
3572 }
3573 }
3574 if (keycode == KEY_SHARP && pte->device->sharp_dial == 1) {
3575 keycode = KEY_FUNC1;
3576 }
3577 if ((keycode >= KEY_0) && (keycode <= KEY_SHARP)) {
3578 int i = pte->device->size_phone_number;
3579
3580 if (pte->device->size_phone_number == 0) {
3581 send_tone(pte, 0, 0);
3582 }
3583 if (keycode == KEY_SHARP) {
3584 keycode = '#';
3585 } else if (keycode == KEY_STAR) {
3586 keycode = '*';
3587 } else {
3588 keycode -= 0x10;
3589 }
3590 pte->device->phone_number[i] = keycode;
3591 pte->device->size_phone_number++;
3592 pte->device->phone_number[i + 1] = 0;
3593 show_phone_number(pte);
3594
3597 keycode = KEY_FUNC1;
3598 } else {
3599 if (pte->device->interdigit_timer) {
3601 }
3602 }
3603 }
3604 if (keycode == KEY_FUNC4) {
3605 pte->device->size_phone_number = 0;
3606 show_phone_number(pte);
3607 return;
3608 }
3609
3610 if (pte->device->call_forward[0] == -1) {
3611 if (keycode == KEY_FUNC1) {
3613 sizeof(pte->device->call_forward));
3614 show_main_page(pte);
3615 } else if ((keycode == KEY_FUNC2) || (keycode == KEY_HANGUP)) {
3616 pte->device->call_forward[0] = '\0';
3619 show_main_page(pte);
3620 }
3621 return;
3622 }
3623 switch (keycode) {
3624 case KEY_FUNC2:
3626 break;
3627 }
3629 sizeof(pte->device->phone_number));
3630 case KEY_FUNC1:
3632 break;
3633 case KEY_HANGUP:
3634 if (sub && sub->owner) {
3635 sub_stop_silence(pte, sub);
3636 send_tone(pte, 0, 0);
3637 ast_queue_unhold(sub->owner);
3638 sub->moh = 0;
3639 sub->subtype = SUB_REAL;
3640 pte->state = STATE_CALL;
3641
3642 send_text_status(pte, ustmtext(" Transf Hangup", pte));
3644 } else {
3647 show_main_page(pte);
3648 }
3649 break;
3650 case KEY_FAV0:
3651 case KEY_FAV1:
3652 case KEY_FAV2:
3653 case KEY_FAV3:
3654 case KEY_FAV4:
3655 case KEY_FAV5:
3657 pte->device->selected = -1;
3658 handle_key_fav(pte, keycode);
3659 break;
3660 case KEY_LOUDSPK:
3661 if (pte->device->output == OUTPUT_SPEAKER) {
3662 if (pte->device->receiver_state == STATE_OFFHOOK) {
3664 MUTE_OFF);
3665 } else {
3666 show_main_page(pte);
3667 }
3668 } else {
3670 }
3671 break;
3672 case KEY_HEADPHN:
3673 if (pte->device->output == OUTPUT_HEADPHONE) {
3674 if (pte->device->receiver_state == STATE_OFFHOOK) {
3676 } else {
3677 show_main_page(pte);
3678 }
3679 } else {
3681 }
3682 break;
3683 }
3684 return;
3685}
#define LED_SPEAKER_OFF
#define LED_HEADPHONE_OFF
int ast_queue_unhold(struct ast_channel *chan)
Queue an unhold frame.
Definition channel.c:1273
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:4196
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:4216
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, 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 3548 of file chan_unistim.c.

3549{
3550 int fav = keycode - KEY_FAV0;
3551 if (!is_key_favorite(pte->device, fav)) {
3552 ast_log(LOG_WARNING, "It's not a favorite key\n");
3553 return;
3554 }
3556 sizeof(pte->device->phone_number));
3558 return;
3559}
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 4294 of file chan_unistim.c.

4295{
4296 FILE *f;
4297 char count;
4298 long offset;
4299 int flag = 0;
4300
4301 switch (keycode) {
4302 case KEY_LEFT:
4303 if (pte->device->height == 1) {
4304 if (pte->buff_entry[3] <= 1) {
4305 return;
4306 }
4307 pte->buff_entry[3]--;
4308 flag = 1;
4309 break;
4310 }
4311 case KEY_UP:
4312 case KEY_FUNC1:
4313 if (pte->buff_entry[2] <= 1) {
4314 return;
4315 }
4316 pte->buff_entry[2]--;
4317 flag = 1;
4318 break;
4319 case KEY_RIGHT:
4320 if (pte->device->height == 1) {
4321 if (pte->buff_entry[3] == 3) {
4322 return;
4323 }
4324 pte->buff_entry[3]++;
4325 flag = 1;
4326 break;
4327 }
4328 case KEY_DOWN:
4329 case KEY_FUNC2:
4330 if (pte->buff_entry[2] >= pte->buff_entry[1]) {
4331 return;
4332 }
4333 pte->buff_entry[2]++;
4334 flag = 1;
4335 break;
4336 case KEY_FUNC3:
4337 if (ast_strlen_zero(pte->device->lst_cid)) {
4338 break;
4339 }
4341 sizeof(pte->device->redial_number));
4343 break;
4344 case KEY_FUNC4:
4345 case KEY_HANGUP:
4346 show_main_page(pte);
4347 break;
4348 case KEY_SNDHIST:
4349 if (pte->buff_entry[0] == 'i') {
4350 show_history(pte, 'o');
4351 } else {
4352 show_main_page(pte);
4353 }
4354 break;
4355 case KEY_RCVHIST:
4356 if (pte->buff_entry[0] == 'i') {
4357 show_main_page(pte);
4358 } else {
4359 show_history(pte, 'i');
4360 }
4361 break;
4362 }
4363
4364 if (flag) {
4365 count = open_history(pte, pte->buff_entry[0], &f);
4366 if (!count) {
4367 return;
4368 }
4369 offset = ((pte->buff_entry[2] - 1) * TEXT_LENGTH_MAX * 3);
4370 if (fseek(f, offset, SEEK_CUR)) {
4371 display_last_error("Unable to seek history entry.");
4372 fclose(f);
4373 return;
4374 }
4375 show_entry_history(pte, &f);
4376 }
4377
4378 return;
4379}
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 4191 of file chan_unistim.c.

4192{
4193 if (pte->device->missed_call) {
4195 pte->device->missed_call = 0;
4196 }
4197 if ((keycode >= KEY_0) && (keycode <= KEY_SHARP)) {
4198 handle_dial_page(pte);
4199 key_dial_page(pte, keycode);
4200 return;
4201 }
4202 switch (keycode) {
4203 case KEY_FUNC1:
4204 pte->device->selected = get_avail_softkey(pte, NULL);
4205 handle_dial_page(pte);
4206 break;
4207 case KEY_FUNC2:
4209 break;
4210 }
4211 if ((pte->device->output == OUTPUT_HANDSET) &&
4212 (pte->device->receiver_state == STATE_ONHOOK)) {
4214 } else {
4216 }
4218 sizeof(pte->device->phone_number));
4220 break;
4221 case KEY_FUNC3:
4222 if (!ast_strlen_zero(pte->device->call_forward)) {
4223 /* Cancel call forwarding */
4224 memmove(pte->device->call_forward + 1, pte->device->call_forward,
4225 sizeof(pte->device->call_forward) - 1);
4226 pte->device->call_forward[0] = '\0';
4228 pte->device->output = OUTPUT_HANDSET; /* Seems to be reset somewhere */
4229 show_main_page(pte);
4230 break;
4231 }
4232 pte->device->call_forward[0] = -1;
4233 handle_dial_page(pte);
4234 break;
4235 case KEY_FUNC4:
4236 if (pte->device->extension == EXTENSION_ASK) {
4238 pte->device->extension_number[0] = '\0';
4240 } else if (pte->device->extension == EXTENSION_TN) {
4242 strcpy(pte->device->id, pte->device->extension_number);
4243 pte->buff_entry[0] = '\0';
4244 pte->size_buff_entry = 0;
4245 pte->device->session = NULL;
4246 pte->device = NULL;
4249 } else { /* Pickup function */
4250 /* XXX Is there a way to get a specific channel here? */
4251 RAII_VAR(struct ast_features_pickup_config *, pickup_cfg,
4253
4254 if (!pickup_cfg) {
4255 ast_log(LOG_ERROR, "Unable to retrieve pickup configuration options. Unable to detect call pickup extension\n");
4256 break;
4257 }
4258
4259 pte->device->selected = -1;
4260 ast_copy_string(pte->device->phone_number, pickup_cfg->pickupexten,
4261 sizeof(pte->device->phone_number));
4263 }
4264 break;
4265 case KEY_FAV0:
4266 case KEY_FAV1:
4267 case KEY_FAV2:
4268 case KEY_FAV3:
4269 case KEY_FAV4:
4270 case KEY_FAV5:
4271 handle_key_fav(pte, keycode);
4272 break;
4273 case KEY_CONF:
4275 break;
4276 case KEY_LOUDSPK:
4278 handle_dial_page(pte);
4279 break;
4280 case KEY_HEADPHN:
4282 handle_dial_page(pte);
4283 break;
4284 case KEY_SNDHIST:
4285 show_history(pte, 'o');
4286 break;
4287 case KEY_RCVHIST:
4288 show_history(pte, 'i');
4289 break;
4290 }
4291 return;
4292}
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 3515 of file chan_unistim.c.

3516{
3517 switch (keycode) {
3518 case KEY_FAV0:
3519 case KEY_FAV1:
3520 case KEY_FAV2:
3521 case KEY_FAV3:
3522 case KEY_FAV4:
3523 case KEY_FAV5:
3524 handle_key_fav(pte, keycode);
3525 break;
3526 case KEY_FUNC3:
3527 ignore_call(pte);
3528 break;
3529 case KEY_HANGUP:
3530 case KEY_FUNC4:
3531 discard_call(pte);
3532 break;
3533 case KEY_LOUDSPK:
3536 break;
3537 case KEY_HEADPHN:
3540 break;
3541 case KEY_FUNC1:
3543 break;
3544 }
3545 return;
3546}
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 3752 of file chan_unistim.c.

3753{
3754 if (keycode == KEY_FUNC2) {
3755 if (pte->size_buff_entry <= 1) {
3756 keycode = KEY_FUNC3;
3757 } else {
3758 pte->size_buff_entry -= 2;
3759 keycode = pte->buff_entry[pte->size_buff_entry] + 0x10;
3760 }
3761 }
3762 if ((keycode >= KEY_0) && (keycode <= KEY_9)) {
3763 char tmpbuf[] = SELECTCODEC_MSG;
3764 int i = 0;
3765
3767 return;
3768 }
3769 while (i < pte->size_buff_entry) {
3770 tmpbuf[i + SELECTCODEC_START_ENTRY_POS] = pte->buff_entry[i];
3771 i++;
3772 }
3773 tmpbuf[i + SELECTCODEC_START_ENTRY_POS] = keycode - 0x10;
3774 pte->buff_entry[i] = keycode - 0x10;
3775 pte->size_buff_entry++;
3776 send_text(TEXT_LINE2, TEXT_INVERSE, pte, tmpbuf);
3777 send_blink_cursor(pte);
3778 send_cursor_pos(pte,
3779 (unsigned char) (TEXT_LINE2 + SELECTCODEC_START_ENTRY_POS + 1 + i));
3780 return;
3781 }
3782
3783 switch (keycode) {
3784 case KEY_FUNC1:
3785 if (pte->size_buff_entry == 1) {
3786 pte->device->codec_number = pte->buff_entry[0] - 48;
3787 } else if (pte->size_buff_entry == 2) {
3788 pte->device->codec_number =
3789 ((pte->buff_entry[0] - 48) * 10) + (pte->buff_entry[1] - 48);
3790 }
3791 show_main_page(pte);
3792 break;
3793 case KEY_FUNC3:
3794 pte->size_buff_entry = 0;
3796 send_blink_cursor(pte);
3798 break;
3799 case KEY_HANGUP:
3800 case KEY_FUNC4:
3801 show_main_page(pte);
3802 break;
3803 }
3804 return;
3805}
#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 3890 of file chan_unistim.c.

3891{
3892 if (keycode == KEY_FUNC2) {
3893 if (pte->size_buff_entry <= 1) {
3894 keycode = KEY_FUNC3;
3895 } else {
3896 pte->size_buff_entry -= 2;
3897 keycode = pte->buff_entry[pte->size_buff_entry] + 0x10;
3898 }
3899 }
3900 if ((keycode >= KEY_0) && (keycode <= KEY_9)) {
3901 char tmpbuf[] = SELECTEXTENSION_MSG;
3902 int i = 0;
3903
3905 return;
3906 }
3907 while (i < pte->size_buff_entry) {
3908 tmpbuf[i + SELECTEXTENSION_START_ENTRY_POS] = pte->buff_entry[i];
3909 i++;
3910 }
3911 tmpbuf[i + SELECTEXTENSION_START_ENTRY_POS] = keycode - 0x10;
3912 pte->buff_entry[i] = keycode - 0x10;
3913 pte->size_buff_entry++;
3914 send_text(TEXT_LINE2, TEXT_NORMAL, pte, tmpbuf);
3915 send_blink_cursor(pte);
3916 send_cursor_pos(pte, (unsigned char) (TEXT_LINE2 + SELECTEXTENSION_START_ENTRY_POS + 1 + i));
3917 return;
3918 }
3919
3920 switch (keycode) {
3921 case KEY_FUNC1:
3922 if (pte->size_buff_entry < 1) {
3923 return;
3924 }
3926 struct unistim_device *d;
3927
3928 /* First step : looking for this TN in our device list */
3930 d = devices;
3931 pte->buff_entry[pte->size_buff_entry] = '\0';
3932 while (d) {
3933 if (d->id[0] == 'T') { /* It's a TN device ? */
3934 /* It's the TN we're looking for ? */
3935 if (!strcmp((d->id) + 1, pte->buff_entry)) {
3936 pte->device = d;
3937 d->session = pte;
3938 d->codec_number = DEFAULT_CODEC;
3939 d->missed_call = 0;
3940 d->receiver_state = STATE_ONHOOK;
3941 strcpy(d->id, pte->macaddr);
3942 pte->device->extension_number[0] = 'T';
3945 pte->buff_entry, pte->size_buff_entry + 1);
3947 show_main_page(pte);
3949 return;
3950 }
3951 }
3952 d = d->next;
3953 }
3955 send_text(TEXT_LINE0, TEXT_NORMAL, pte, ustmtext("Invalid Terminal Number.", pte));
3956 send_text(TEXT_LINE1, TEXT_NORMAL, pte, ustmtext("Please try again :", pte));
3958 pte->size_buff_entry));
3959 send_blink_cursor(pte);
3960 } else {
3962 pte->size_buff_entry + 1);
3963 if (register_extension(pte)) {
3964 send_text(TEXT_LINE0, TEXT_NORMAL, pte, ustmtext("Invalid extension.", pte));
3965 send_text(TEXT_LINE1, TEXT_NORMAL, pte, ustmtext("Please try again :", pte));
3966 send_cursor_pos(pte, (unsigned char) (TEXT_LINE2 +
3968 pte->size_buff_entry));
3969 send_blink_cursor(pte);
3970 } else
3971 show_main_page(pte);
3972 }
3973 break;
3974 case KEY_FUNC3:
3975 pte->size_buff_entry = 0;
3977 send_blink_cursor(pte);
3979 break;
3980 }
3981 return;
3982}
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 3842 of file chan_unistim.c.

3843{
3844 switch (keycode) {
3845 case KEY_DOWN:
3846 pte->buff_entry[0]++;
3847 if (options_languages[(int)pte->buff_entry[0]].label == NULL) {
3848 pte->buff_entry[0]--;
3849 }
3850 break;
3851 case KEY_UP:
3852 if (pte->buff_entry[0] > 0) {
3853 pte->buff_entry[0]--;
3854 }
3855 break;
3856 case KEY_FUNC1:
3860 show_main_page(pte);
3861 return;
3862 case KEY_HANGUP:
3863 case KEY_FUNC4:
3865 return;
3866 }
3867
3869 return;
3870}
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 3702 of file chan_unistim.c.

3703{
3704 switch (keycode) {
3705 case KEY_DOWN:
3706 pte->buff_entry[0]++;
3707 if (options_menu[(int)pte->buff_entry[0]].label == NULL) {
3708 pte->buff_entry[0]--;
3709 }
3710 break;
3711 case KEY_UP:
3712 if (pte->buff_entry[0] > 0) {
3713 pte->buff_entry[0]--;
3714 }
3715 break;
3716 case KEY_FUNC1:
3717 options_menu[(int)pte->buff_entry[0]].handle_option(pte);
3718 return;
3719 case KEY_HANGUP:
3720 case KEY_FUNC4:
3721 show_main_page(pte);
3722 return;
3723 }
3724
3726 return;
3727}
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 792 of file chan_unistim.c.

793{
794 struct ustm_lang_entry *entry1 = obj;
795 struct ustm_lang_entry *entry2 = arg;
796
797 return (!strcmp(entry1->str_orig, entry2->str_orig)) ? (CMP_MATCH | CMP_STOP) : 0;
798}
@ 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 786 of file chan_unistim.c.

787{
788 const struct ustm_lang_entry *entry = obj;
789 return ast_str_hash(entry->str_orig);
790}
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 7078 of file chan_unistim.c.

7079{
7080 int res;
7081
7083 goto buff_failed;
7084 }
7086 goto buff_failed;
7087 }
7088
7092
7093 if (!(buff = ast_malloc(SIZE_PAGE))) {
7094 goto buff_failed;
7095 }
7096
7098 if (!io) {
7099 ast_log(LOG_ERROR, "Failed to allocate IO context\n");
7100 goto io_failed;
7101 }
7102
7104 if (!sched) {
7105 ast_log(LOG_ERROR, "Failed to allocate scheduler context\n");
7106 goto sched_failed;
7107 }
7108
7109 res = reload_config();
7110 if (res) {
7112 ao2_ref(global_cap, -1);
7116 }
7117 /* Make sure we can register our unistim channel type */
7119 ast_log(LOG_ERROR, "Unable to register channel type '%s'\n", channel_type);
7120 goto chanreg_failed;
7121 }
7122
7124
7126
7128
7130
7131chanreg_failed:
7132 /*! XXX \todo Leaking anything allocated by reload_config() ... */
7134 sched = NULL;
7135sched_failed:
7137 io = NULL;
7138io_failed:
7139 ast_free(buff);
7140 buff = NULL;
7141buff_failed:
7143 global_cap = NULL;
7147}
#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:539
#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 4457 of file chan_unistim.c.

4458{
4459 if (pte->device->microphone == MUTE_OFF) {
4460 pte->device->microphone = MUTE_ON;
4462 } else if (pte->device->microphone == MUTE_ON) {
4463 pte->device->microphone = MUTE_OFF;
4465 }
4466 send_mute(pte, (pte->device->microphone & 0x01));
4467}
#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 4058 of file chan_unistim.c.

4059{
4060 char tmp[AST_CONFIG_MAX_PATH];
4061 char count;
4062
4063 snprintf(tmp, sizeof(tmp), "%s/%s/%s-%c.csv", ast_config_AST_LOG_DIR,
4064 USTM_LOG_DIR, pte->device->name, way);
4065 *f = fopen(tmp, "r");
4066 if (!*f) {
4067 display_last_error("Unable to open history file");
4068 return 0;
4069 }
4070 if (fread(&count, 1, 1, *f) != 1) {
4071 display_last_error("Unable to read history header - display.");
4072 fclose(*f);
4073 *f = NULL;
4074 return 0;
4075 }
4076 if (count > MAX_ENTRY_LOG) {
4077 ast_log(LOG_WARNING, "Invalid count in history header of %s (%d max %d)\n", tmp,
4078 count, MAX_ENTRY_LOG);
4079 fclose(*f);
4080 *f = NULL;
4081 return 0;
4082 }
4083 return count;
4084}
#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 6295 of file chan_unistim.c.

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

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

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

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

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

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

1908{
1909 BUFFSEND;
1910 if (unistimdebug) {
1911 ast_verb(0, "ResumeConnectionWithServer received\n");
1912 ast_verb(0, "Sending packet_send_query_mac_address\n");
1913 }
1914 memcpy(buffsend + SIZE_HEADER, packet_send_query_mac_address,
1916 send_client(SIZE_HEADER + sizeof(packet_send_query_mac_address), buffsend, pte);
1917 return;
1918}
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 1321 of file chan_unistim.c.

1322{
1323 unsigned char i = 0;
1324 char data[256];
1325 struct unistim_line *line;
1326 line = AST_LIST_FIRST(&pte->device->lines);
1327
1328 if (unistimdebug) {
1329 ast_verb(0, "Refreshing all favorite\n");
1330 }
1331 for (i = 0; i < FAVNUM; i++) {
1332 unsigned char status = pte->device->softkeyicon[i];
1333
1334 if (!soft_key_visible(pte->device, i)) {
1335 continue;
1336 }
1337 if (!strcasecmp(pte->device->softkeylabel[i], "DND") && line) {
1338 if (!ast_db_get("DND", line->name, data, sizeof(data))) {
1340 }
1341 }
1342
1343 send_favorite_short(i, status, pte);
1344 }
1345 if (pte->device->hasexp) {
1346 for (i = 0; i < EXPNUM; i++) {
1348 }
1349 }
1350}
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 1445 of file chan_unistim.c.

1446{
1447 struct unistim_line *line;
1448 line = AST_LIST_FIRST(&pte->device->lines);
1449 if (unistimdebug) {
1450 ast_verb(0, "Trying to register extension '%s' into context '%s' to %s\n",
1452 line->fullname);
1453 }
1454 return ast_add_extension(pte->device->context, 0,
1455 pte->device->extension_number, 1, NULL, NULL, "Dial",
1456 line->fullname, 0, "Unistim");
1457}
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:6953

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

7184{
7185 if (unistimdebug) {
7186 ast_verb(0, "reload unistim\n");
7187 }
7189 if (!unistim_reloading) {
7191 }
7193
7195
7196 return 0;
7197}

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

6845{
6846 struct ast_config *cfg;
6847 struct ast_variable *v;
6848 struct sockaddr_in bindaddr = { 0, };
6849 char *config = "unistim.conf";
6850 char *cat;
6851 struct unistim_device *d;
6852 const int reuseFlag = 1;
6853 struct unistimsession *s;
6854 struct ast_flags config_flags = { 0, };
6855
6856 cfg = ast_config_load(config, config_flags);
6857 /* We *must* have a config file otherwise stop immediately */
6858 if (!cfg) {
6859 ast_log(LOG_ERROR, "Unable to load config %s\n", config);
6860 return -1;
6861 } else if (cfg == CONFIG_STATUS_FILEINVALID) {
6862 ast_log(LOG_ERROR, "Config file %s is in an invalid format. Aborting.\n", config);
6863 return -1;
6864 }
6865
6866 /* Copy the default jb config over global_jbconf */
6867 memcpy(&global_jbconf, &default_jbconf, sizeof(struct ast_jb_conf));
6868
6869 unistim_keepalive = 120;
6870 unistim_port = 0;
6871 v = ast_variable_browse(cfg, "general");
6872 while (v) {
6873 /* handle jb conf */
6874 if (!ast_jb_read_conf(&global_jbconf, v->name, v->value)) {
6875 continue;
6876 }
6877 if (!strcasecmp(v->name, "keepalive")) {
6878 unistim_keepalive = atoi(v->value);
6879 } else if (!strcasecmp(v->name, "port")) {
6880 unistim_port = atoi(v->value);
6881 } else if (!strcasecmp(v->name, "tos")) {
6882 if (ast_str2tos(v->value, &qos.tos)) {
6883 ast_log(LOG_WARNING, "Invalid tos value at line %d, refer to QoS documentation\n", v->lineno);
6884 }
6885 } else if (!strcasecmp(v->name, "tos_audio")) {
6886 if (ast_str2tos(v->value, &qos.tos_audio)) {
6887 ast_log(LOG_WARNING, "Invalid tos_audio value at line %d, refer to QoS documentation\n", v->lineno);
6888 }
6889 } else if (!strcasecmp(v->name, "cos")) {
6890 if (ast_str2cos(v->value, &qos.cos)) {
6891 ast_log(LOG_WARNING, "Invalid cos value at line %d, refer to QoS documentation\n", v->lineno);
6892 }
6893 } else if (!strcasecmp(v->name, "cos_audio")) {
6894 if (ast_str2cos(v->value, &qos.cos_audio)) {
6895 ast_log(LOG_WARNING, "Invalid cos_audio value at line %d, refer to QoS documentation\n", v->lineno);
6896 }
6897 } else if (!strcasecmp(v->name, "debug")) {
6898 if (!strcasecmp(v->value, "no")) {
6899 unistimdebug = 0;
6900 } else if (!strcasecmp(v->value, "yes")) {
6901 unistimdebug = 1;
6902 }
6903 } else if (!strcasecmp(v->name, "autoprovisioning")) {
6904 if (!strcasecmp(v->value, "no")) {
6906 } else if (!strcasecmp(v->value, "yes")) {
6908 } else if (!strcasecmp(v->value, "tn")) {
6910 } else {
6911 ast_log(LOG_WARNING, "Unknown autoprovisioning option.\n");
6912 }
6913 } else if (!strcasecmp(v->name, "public_ip")) {
6914 if (!ast_strlen_zero(v->value)) {
6915 struct ast_sockaddr addr = { {0,} };
6916 if (ast_sockaddr_resolve_first_af(&addr, v->value, PARSE_PORT_FORBID, AF_INET)) {
6917 ast_log(LOG_WARNING, "Invalid address: %s\n", v->value);
6918 } else {
6920 }
6921 }
6922 }
6923 v = v->next;
6924 }
6925 if ((unistim_keepalive < 10) ||
6927 255 - (((NB_MAX_RETRANSMIT + 1) * RETRANSMIT_TIMER) / 1000))) {
6928 ast_log(LOG_ERROR, "keepalive is invalid in %s\n", config);
6929 ast_config_destroy(cfg);
6930 return -1;
6931 }
6932 packet_send_ping[4] =
6934 if ((unistim_port < 1) || (unistim_port > 65535)) {
6935 ast_log(LOG_ERROR, "port is not set or invalid in %s\n", config);
6936 ast_config_destroy(cfg);
6937 return -1;
6938 }
6939 unistim_keepalive *= 1000;
6940
6942 d = devices;
6943 while (d) {
6944 if (d->to_delete >= 0) {
6945 d->to_delete = 1;
6946 }
6947 d = d->next;
6948 }
6950 /* load the device sections */
6951 cat = ast_category_browse(cfg, NULL);
6952 while (cat) {
6953 if (strcasecmp(cat, "general")) {
6954 d = build_device(cat, ast_variable_browse(cfg, cat));
6955 }
6956 cat = ast_category_browse(cfg, cat);
6957 }
6959 d = devices;
6960 while (d) {
6961 if (d->to_delete) {
6963 d = devices;
6964 continue;
6965 }
6966 d = d->next;
6967 }
6970 ast_config_destroy(cfg);
6972 s = sessions;
6973 while (s) {
6974 if (s->device) {
6976 if (ast_strlen_zero(s->device->language)) {
6977 struct unistim_languages lang;
6979 send_charset_update(s, lang.encoding);
6980 }
6981 }
6982 s = s->next;
6983 }
6985 /* We don't recreate a socket when reloading (locks would be necessary). */
6986 if (unistimsock > -1) {
6987 return 0;
6988 }
6989 bindaddr.sin_addr.s_addr = INADDR_ANY;
6990 bindaddr.sin_port = htons(unistim_port);
6991 bindaddr.sin_family = AF_INET;
6992 unistimsock = socket(AF_INET, SOCK_DGRAM, 0);
6993 if (unistimsock < 0) {
6994 ast_log(LOG_WARNING, "Unable to create UNISTIM socket: %s\n", strerror(errno));
6995 return -1;
6996 }
6997#ifdef HAVE_PKTINFO
6998 {
6999 const int pktinfoFlag = 1;
7000 setsockopt(unistimsock, IPPROTO_IP, IP_PKTINFO, &pktinfoFlag,
7001 sizeof(pktinfoFlag));
7002 }
7003#else
7004 if (public_ip.sin_family == 0) {
7006 "Your OS does not support IP_PKTINFO, you must set public_ip.\n");
7007 unistimsock = -1;
7008 return -1;
7009 }
7010#endif
7011 setsockopt(unistimsock, SOL_SOCKET, SO_REUSEADDR, (const char *) &reuseFlag,
7012 sizeof(reuseFlag));
7013 if (bind(unistimsock, (struct sockaddr *) &bindaddr, sizeof(bindaddr)) < 0) {
7014 ast_log(LOG_WARNING, "Failed to bind to %s:%d: %s\n",
7015 ast_inet_ntoa(bindaddr.sin_addr), htons(bindaddr.sin_port),
7016 strerror(errno));
7017 close(unistimsock);
7018 unistimsock = -1;
7019 } else {
7020 ast_verb(2, "UNISTIM Listening on %s:%d\n", ast_inet_ntoa(bindaddr.sin_addr), htons(bindaddr.sin_port));
7021 ast_set_qos(unistimsock, qos.tos, qos.cos, "UNISTIM");
7022 }
7023 return 0;
7024}
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 @138 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 5919 of file chan_unistim.c.

5920{
5921 pthread_attr_t attr;
5922 /* If we're supposed to be stopped -- stay stopped */
5924 return 0;
5925 }
5926 if (ast_mutex_lock(&monlock)) {
5927 ast_log(LOG_WARNING, "Unable to lock monitor\n");
5928 return -1;
5929 }
5930 if (monitor_thread == pthread_self()) {
5932 ast_log(LOG_WARNING, "Cannot kill myself\n");
5933 return -1;
5934 }
5936 /* Wake up the thread */
5937 pthread_kill(monitor_thread, SIGURG);
5938 } else {
5939 pthread_attr_init(&attr);
5940 pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE);
5941 /* Start a new monitor */
5942 if (ast_pthread_create(&monitor_thread, &attr, do_monitor, NULL) < 0) {
5944 ast_log(LOG_ERROR, "Unable to start monitor thread.\n");
5945 return -1;
5946 }
5947 }
5949 return 0;
5950}
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 1844 of file chan_unistim.c.

1845{
1846 BUFFSEND;
1847 if (unistimdebug) {
1848 ast_verb(0, "Sending set blink\n");
1849 }
1851 send_client(SIZE_HEADER + sizeof(packet_send_blink_cursor), buffsend, pte);
1852 return;
1853}
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 4825 of file chan_unistim.c.

4826{
4827 char *cidname_str;
4828 char *cidnum_str;
4829
4830 if (!sub) {
4831 return;
4832 }
4833 if (sub->owner) {
4835 cidnum_str = ast_channel_connected(sub->owner)->id.number.str;
4836 } else {
4837 cidnum_str = DEFAULTCALLERID;
4838 }
4839 change_callerid(pte, 0, cidnum_str);
4840 if (strlen(cidnum_str) == 0) {
4841 cidnum_str = DEFAULTCALLERID;
4842 }
4843
4845 cidname_str = ast_channel_connected(sub->owner)->id.name.str;
4846 } else {
4847 cidname_str = DEFAULTCALLERNAME;
4848 }
4849 change_callerid(pte, 1, cidname_str);
4850 if (strlen(cidname_str) == 0) {
4851 cidname_str = DEFAULTCALLERNAME;
4852 }
4853
4854 if (pte->device->height == 1) {
4855 char tmpstr[256];
4856 snprintf(tmpstr, sizeof(tmpstr), "%s %s", cidnum_str, ustmtext(cidname_str, pte));
4857 send_text(TEXT_LINE0, TEXT_NORMAL, pte, tmpstr);
4858 } else {
4859 send_text(TEXT_LINE0, TEXT_NORMAL, pte, cidname_str);
4860 send_text(TEXT_LINE1, TEXT_NORMAL, pte, ustmtext(cidnum_str, pte));
4861 }
4862 }
4863}
#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 1869 of file chan_unistim.c.

1870{
1871 const unsigned char* packet_send_charset;
1872 int packet_size;
1873 BUFFSEND;
1874 if (unistimdebug) {
1875 ast_verb(0, "Sending set default charset\n");
1876 }
1877 if (charset == LANG_DEFAULT) {
1879 }
1880 switch (charset) {
1881 case ISO_8859_2:
1882 packet_send_charset = packet_send_charset_iso_8859_2;
1883 packet_size = sizeof(packet_send_charset_iso_8859_2);
1884 break;
1885 case ISO_8859_4:
1886 packet_send_charset = packet_send_charset_iso_8859_4;
1887 packet_size = sizeof(packet_send_charset_iso_8859_4);
1888 break;
1889 case ISO_8859_5:
1890 packet_send_charset = packet_send_charset_iso_8859_5;
1891 packet_size = sizeof(packet_send_charset_iso_8859_5);
1892 break;
1893 case ISO_2022_JP:
1894 packet_send_charset = packet_send_charset_iso_2022_jp;
1895 packet_size = sizeof(packet_send_charset_iso_2022_jp);
1896 break;
1897 case ISO_8859_1:
1898 default:
1899 packet_send_charset = packet_send_charset_iso_8859_1;
1900 packet_size = sizeof(packet_send_charset_iso_8859_1);
1901 }
1902 memcpy(buffsend + SIZE_HEADER, packet_send_charset, packet_size);
1903 send_client(SIZE_HEADER + packet_size, buffsend, pte);
1904 return;
1905}
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 959 of file chan_unistim.c.

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

1857{
1858 BUFFSEND;
1859 if (unistimdebug) {
1860 ast_verb(0, "Sending set cursor position\n");
1861 }
1862 memcpy(buffsend + SIZE_HEADER, packet_send_set_pos_cursor,
1864 buffsend[11] = pos;
1865 send_client(SIZE_HEADER + sizeof(packet_send_set_pos_cursor), buffsend, pte);
1866 return;
1867}
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 1784 of file chan_unistim.c.

1785{
1786 BUFFSEND;
1787 struct timeval now = ast_tvnow();
1788 struct ast_tm atm = { 0, };
1789
1790 if (unistimdebug) {
1791 ast_verb(0, "Sending Time & Date\n");
1792 }
1793 memcpy(buffsend + SIZE_HEADER, packet_send_date_time, sizeof(packet_send_date_time));
1794 ast_localtime(&now, &atm, NULL);
1795 buffsend[10] = (unsigned char) atm.tm_mon + 1;
1796 buffsend[11] = (unsigned char) atm.tm_mday;
1797 buffsend[12] = (unsigned char) atm.tm_hour;
1798 buffsend[13] = (unsigned char) atm.tm_min;
1799 send_client(SIZE_HEADER + sizeof(packet_send_date_time), buffsend, pte);
1800 send_month_labels(pte, atm.tm_mon);
1801}
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 1803 of file chan_unistim.c.

1804{
1805 BUFFSEND;
1806 struct timeval now = ast_tvnow();
1807 struct ast_tm atm = { 0, };
1808
1809 if (unistimdebug) {
1810 ast_verb(0, "Sending Time & Date #2\n");
1811 }
1812 memcpy(buffsend + SIZE_HEADER, packet_send_date_time2, sizeof(packet_send_date_time2));
1813 ast_localtime(&now, &atm, NULL);
1814 if (pte->device) {
1815 buffsend[9] = pte->device->datetimeformat;
1816 } else {
1817 buffsend[9] = 61;
1818 }
1819 buffsend[14] = (unsigned char) atm.tm_mon + 1;
1820 buffsend[15] = (unsigned char) atm.tm_mday;
1821 buffsend[16] = (unsigned char) atm.tm_hour;
1822 buffsend[17] = (unsigned char) atm.tm_min;
1823 send_client(SIZE_HEADER + sizeof(packet_send_date_time2), buffsend, pte);
1824}
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 1826 of file chan_unistim.c.

1827{
1828 BUFFSEND;
1829 struct timeval now = ast_tvnow();
1830 struct ast_tm atm = { 0, };
1831
1832 if (unistimdebug) {
1833 ast_verb(0, "Sending Time & Date #3\n");
1834 }
1835 memcpy(buffsend + SIZE_HEADER, packet_send_date_time3, sizeof(packet_send_date_time3));
1836 ast_localtime(&now, &atm, NULL);
1837 buffsend[10] = (unsigned char) atm.tm_mon + 1;
1838 buffsend[11] = (unsigned char) atm.tm_mday;
1839 buffsend[12] = (unsigned char) atm.tm_hour;
1840 buffsend[13] = (unsigned char) atm.tm_min;
1841 send_client(SIZE_HEADER + sizeof(packet_send_date_time3), buffsend, pte);
1842}
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 2924 of file chan_unistim.c.

2925{
2926 struct ast_tone_zone_sound *ts = NULL;
2927 struct ast_tone_zone_part tone_data;
2928 char *s = NULL;
2929 char *ind;
2930
2931 if ((ts = ast_get_indication_tone(pte->device->tz, "dial"))) {
2932 ind = ast_strdupa(ts->data);
2933 s = strsep(&ind, ",");
2934 ast_tone_zone_part_parse(s, &tone_data);
2935 send_tone(pte, tone_data.freq1, tone_data.freq2);
2936 if (unistimdebug) {
2937 ast_verb(0, "Country code found (%s), freq1=%u freq2=%u\n",
2938 pte->device->tz->country, tone_data.freq1, tone_data.freq2);
2939 }
2941 }
2942}
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 3329 of file chan_unistim.c.

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

1081{
1082 BUFFSEND;
1083 if (unistimdebug) {
1084 ast_verb(0, "Sending end call\n");
1085 }
1086 memcpy(buffsend + SIZE_HEADER, packet_send_end_call, sizeof(packet_send_end_call));
1087 send_client(SIZE_HEADER + sizeof(packet_send_end_call), buffsend, pte);
1088}
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 1167 of file chan_unistim.c.

1168{
1169 BUFFSEND;
1170 if (unistimdebug) {
1171 ast_verb(0, "Sending expansion icon pos %d with status 0x%02hhx\n", pos, status);
1172 }
1174 buffsend[10] = pos;
1175 buffsend[11] = status;
1176 send_client(SIZE_HEADER + sizeof(packet_send_expansion_icon), buffsend, pte);
1177}
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 1159 of file chan_unistim.c.

1160{
1161 BUFFSEND;
1163 send_client(SIZE_HEADER + sizeof(packet_send_expansion_next), buffsend, pte);
1164}
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 1306 of file chan_unistim.c.

1306 {
1307 send_expansion_icon(pos, status, pte);
1308 send_expansion_text(pos, pte, ustmtext(pte->device->expsoftkeylabel[pos], pte));
1310 return;
1311}
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 1180 of file chan_unistim.c.

1181{
1182 int i;
1183 BUFFSEND;
1184 if (!text) {
1185 ast_log(LOG_ERROR, "[expansion] Asked to display NULL text (pos %d)\n", pos);
1186 return;
1187 }
1188 if (unistimdebug) {
1189 ast_verb(0, "[expansion] Sending text at pos %d\n", pos);
1190 }
1192 buffsend[10] = pos;
1193 i = strlen(text);
1194 if (i > TEXT_LENGTH_MAX) {
1195 i = TEXT_LENGTH_MAX;
1196 }
1197 memcpy(buffsend + 11, text, i);
1198 send_client(SIZE_HEADER + sizeof(packet_send_expansion_text), buffsend, pte);
1199}
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 1273 of file chan_unistim.c.

1275{
1276 BUFFSEND;
1277 int i;
1278
1279 if (unistimdebug) {
1280 ast_verb(0, "Sending favorite pos %d with status 0x%02hhx\n", pos, status);
1281 }
1282 memcpy(buffsend + SIZE_HEADER, packet_send_favorite, sizeof(packet_send_favorite));
1283 buffsend[10] = pos;
1284 buffsend[24] = pos;
1285 buffsend[25] = status;
1286 i = strlen(ustmtext(text, pte));
1287 if (i > FAV_MAX_LENGTH) {
1288 i = FAV_MAX_LENGTH;
1289 }
1290 memcpy(buffsend + FAV_MAX_LENGTH + 1, ustmtext(text, pte), i);
1291 send_client(SIZE_HEADER + sizeof(packet_send_favorite), buffsend, pte);
1292}
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 1299 of file chan_unistim.c.

1299 {
1300 if (pte->device->selected != -1) {
1302 }
1303 return;
1304}

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

1148{
1149 BUFFSEND;
1150 if (unistimdebug) {
1151 ast_verb(0, "Sending icon pos %d with status 0x%02hhx\n", pos, status);
1152 }
1153 memcpy(buffsend + SIZE_HEADER, packet_send_icon, sizeof(packet_send_icon));
1154 buffsend[9] = pos;
1155 buffsend[10] = status;
1156 send_client(SIZE_HEADER + sizeof(packet_send_icon), buffsend, pte);
1157}
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 1757 of file chan_unistim.c.

1758{
1759 send_text(TEXT_LINE0, TEXT_NORMAL, pte, "");
1760}

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

1640{
1641 BUFFSEND;
1642 if (unistimdebug) {
1643 ast_verb(0, "Sending led_update (%x)\n", (unsigned)led);
1644 }
1645 memcpy(buffsend + SIZE_HEADER, packet_send_led_update, sizeof(packet_send_led_update));
1646 buffsend[9] = led;
1647 send_client(SIZE_HEADER + sizeof(packet_send_led_update), buffsend, pte);
1648}
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 1762 of file chan_unistim.c.

1763{
1764 BUFFSEND;
1765 char month_name[MONTH_LABEL_SIZE + 1];
1766 int i = 0;
1767 if (unistimdebug) {
1768 ast_verb(0, "Sending Month Labels\n");
1769 }
1770 month_name[MONTH_LABEL_SIZE] = '\0';
1772 while (i < 2) {
1773 memcpy(month_name, &monthlabels[month * MONTH_LABEL_SIZE], MONTH_LABEL_SIZE);
1774 memcpy(buffsend + SIZE_HEADER + 3 + i*MONTH_LABEL_SIZE, ustmtext(month_name, pte), MONTH_LABEL_SIZE);
1775 ast_log(LOG_WARNING,"%s\n", month_name);
1776 ast_log(LOG_WARNING,"%s\n", ustmtext(month_name, pte));
1777 month = (month + 1)%12;
1778 i++;
1779 }
1781}
#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 1650 of file chan_unistim.c.

1651{
1652/*
1653 0x00 = unmute TX, 0x01 = mute TX
1654 0x20 = unmute RX, 0x21 = mute RX
1655*/
1656 BUFFSEND;
1657 if (unistimdebug) {
1658 ast_verb(0, "Sending mute packet (%x)\n", (unsigned)mute);
1659 }
1660 memcpy(buffsend + SIZE_HEADER, packet_send_mute, sizeof(packet_send_mute));
1661 buffsend[9] = mute;
1662 send_client(SIZE_HEADER + sizeof(packet_send_mute), buffsend, pte);
1663}
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 1731 of file chan_unistim.c.

1732{
1733 BUFFSEND;
1734 if (unistimdebug) {
1735 ast_verb(0, "Sending no ring packet\n");
1736 }
1737 memcpy(buffsend + SIZE_HEADER, packet_send_no_ring, sizeof(packet_send_no_ring));
1738 send_client(SIZE_HEADER + sizeof(packet_send_no_ring), buffsend, pte);
1739}
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 991 of file chan_unistim.c.

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

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

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

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

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

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

1720{
1721 BUFFSEND;
1722 if (unistimdebug) {
1723 ast_verb(0, "Sending ring packet\n");
1724 }
1725 memcpy(buffsend + SIZE_HEADER, packet_send_ring, sizeof(packet_send_ring));
1726 buffsend[24] = style + 0x10;
1727 buffsend[29] = volume * 0x10;
1728 send_client(SIZE_HEADER + sizeof(packet_send_ring), buffsend, pte);
1729}
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 1670 of file chan_unistim.c.

1672{
1673 BUFFSEND;
1674 int mute_icon = -1;
1675 if (unistimdebug) {
1676 ast_verb(0, "Sending select output packet output=%x volume=%x mute=%x\n",
1677 (unsigned)output, (unsigned)volume, (unsigned)mute);
1678 }
1679 memcpy(buffsend + SIZE_HEADER, packet_send_select_output,
1681 buffsend[9] = output;
1682 if (output == OUTPUT_SPEAKER && volume == VOLUME_LOW) {
1684 }
1685 buffsend[10] = volume;
1686 if (mute == MUTE_ON_DISCRET) {
1687 buffsend[11] = MUTE_ON;
1688 } else {
1689 buffsend[11] = mute;
1690 }
1691 send_client(SIZE_HEADER + sizeof(packet_send_select_output), buffsend, pte);
1692 if (output == OUTPUT_HANDSET) {
1693 mute_icon = (mute == MUTE_ON) ? FAV_ICON_ONHOLD_BLACK : FAV_ICON_OFFHOOK_BLACK;
1696 } else if (output == OUTPUT_HEADPHONE) {
1700 } else if (output == OUTPUT_SPEAKER) {
1703 if (pte->device->receiver_state == STATE_OFFHOOK) {
1705 } else {
1707 }
1708 } else {
1709 ast_log(LOG_WARNING, "Invalid output (%d)\n", output);
1710 }
1711 if (mute_icon != -1) {
1712 change_favorite_icon(pte, mute_icon);
1713 }
1714 if (output != pte->device->output) {
1715 pte->device->previous_output = pte->device->output;
1716 }
1717 pte->device->output = output;
1718}
#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 2710 of file chan_unistim.c.

2711{
2712 BUFFSEND;
2713
2714 int codec;
2715 struct sockaddr_in public = { 0, };
2716 struct sockaddr_in us = { 0, };
2717 struct sockaddr_in sin = { 0, };
2718 struct ast_sockaddr us_tmp;
2719 struct ast_sockaddr sin_tmp;
2720 struct unistimsession *pte;
2721
2723 ast_sockaddr_to_sin(&us_tmp, &us);
2725 ast_sockaddr_to_sin(&sin_tmp, &sin);
2726
2727 /* Setting up RTP of the phone */
2728 if (public_ip.sin_family == 0) { /* NAT IP override ? */
2729 memcpy(&public, &us, sizeof(public)); /* No defined, using IP from recvmsg */
2730 } else {
2731 memcpy(&public, &public_ip, sizeof(public)); /* override */
2732 }
2733 if (unistimdebug) {
2734 ast_verb(0, "RTP started : Our IP/port is : %s:%hd with codec %s\n",
2735 ast_inet_ntoa(us.sin_addr),
2736 htons(us.sin_port), ast_format_get_name(ast_channel_readformat(sub->owner)));
2737 ast_verb(0, "Starting phone RTP stack. Our public IP is %s\n",
2738 ast_inet_ntoa(public.sin_addr));
2739 }
2740
2741 pte = sub->parent->parent->session;
2743 1, ast_channel_readformat(sub->owner), 0);
2746 if (unistimdebug) {
2747 ast_verb(0, "Sending packet_send_rtp_packet_size for codec %d\n", codec);
2748 }
2749 memcpy(buffsend + SIZE_HEADER, packet_send_rtp_packet_size,
2751 buffsend[10] = (int) codec & 0xffffffffLL;
2752 send_client(SIZE_HEADER + sizeof(packet_send_rtp_packet_size), buffsend, pte);
2753 }
2754 if (unistimdebug) {
2755 ast_verb(0, "Sending Jitter Buffer Parameters Configuration\n");
2756 }
2759 send_client(SIZE_HEADER + sizeof(packet_send_jitter_buffer_conf), buffsend, pte);
2760 if (pte->device->rtp_method != 0) {
2761 uint16_t rtcpsin_port = ntohs(us.sin_port) + 1; /* RTCP port is RTP + 1 */
2762
2763 if (unistimdebug) {
2764 ast_verb(0, "Sending OpenAudioStreamTX using method #%d\n", pte->device->rtp_method);
2765 }
2766 if (pte->device->rtp_method == 3) {
2769 } else {
2772 }
2773 if (pte->device->rtp_method != 2) {
2774 memcpy(buffsend + 28, &public.sin_addr, sizeof(public.sin_addr));
2775 put_unaligned_uint16(&buffsend[20], sin.sin_port);
2776 put_unaligned_uint16(&buffsend[22], htons(rtcpsin_port));
2777 put_unaligned_uint16(&buffsend[24], us.sin_port);
2778 put_unaligned_uint16(&buffsend[26], htons(rtcpsin_port));
2779 } else {
2780 memcpy(buffsend + 23, &public.sin_addr, sizeof(public.sin_addr));
2781 put_unaligned_uint16(&buffsend[15], sin.sin_port);
2782 put_unaligned_uint16(&buffsend[19], us.sin_port);
2783 }
2784 buffsend[11] = codec; /* rx */
2785 buffsend[12] = codec; /* tx */
2787
2788 if (unistimdebug) {
2789 ast_verb(0, "Sending OpenAudioStreamRX\n");
2790 }
2791 if (pte->device->rtp_method == 3) {
2794 } else {
2797 }
2798 if (pte->device->rtp_method != 2) {
2799 memcpy(buffsend + 28, &public.sin_addr, sizeof(public.sin_addr));
2800 put_unaligned_uint16(&buffsend[20], sin.sin_port);
2801 put_unaligned_uint16(&buffsend[22], htons(rtcpsin_port));
2802 put_unaligned_uint16(&buffsend[24], us.sin_port);
2803 put_unaligned_uint16(&buffsend[26], htons(rtcpsin_port));
2804 } else {
2805 memcpy(buffsend + 23, &public.sin_addr, sizeof(public.sin_addr));
2806 put_unaligned_uint16(&buffsend[15], sin.sin_port);
2807 put_unaligned_uint16(&buffsend[19], us.sin_port);
2808 }
2809 buffsend[11] = codec; /* rx */
2810 buffsend[12] = codec; /* tx */
2812 } else {
2813 uint16_t rtcpsin_port = htons(us.sin_port) + 1; /* RTCP port is RTP + 1 */
2814
2815 if (unistimdebug) {
2816 ast_verb(0, "Sending packet_send_call default method\n");
2817 }
2818
2819 memcpy(buffsend + SIZE_HEADER, packet_send_call, sizeof(packet_send_call));
2820 memcpy(buffsend + 53, &public.sin_addr, sizeof(public.sin_addr));
2821 /* Destination port when sending RTP */
2822 put_unaligned_uint16(&buffsend[49], us.sin_port);
2823 /* Destination port when sending RTCP */
2824 put_unaligned_uint16(&buffsend[51], htons(rtcpsin_port));
2825 /* Codec */
2826 buffsend[40] = codec;
2827 buffsend[41] = codec;
2829 buffsend[42] = 1; /* 1 = 20ms (160 bytes), 2 = 40ms (320 bytes) */
2831 buffsend[42] = 1; /* 1 = 20ms (160 bytes), 2 = 40ms (320 bytes) */
2833 buffsend[42] = 2; /* 1 = 30ms (24 bytes), 2 = 60 ms (48 bytes) */
2835 buffsend[42] = 2; /* 1 = 10ms (10 bytes), 2 = 20ms (20 bytes) */
2836 } else {
2837 ast_log(LOG_WARNING, "Unsupported codec %s!\n",
2839 }
2840 /* Source port for transmit RTP and Destination port for receiving RTP */
2841 put_unaligned_uint16(&buffsend[45], sin.sin_port);
2842 put_unaligned_uint16(&buffsend[47], htons(rtcpsin_port));
2843 send_client(SIZE_HEADER + sizeof(packet_send_call), buffsend, pte);
2844 }
2845}
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:671
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:755
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 1127 of file chan_unistim.c.

1128{
1129 BUFFSEND;
1130 if (unistimdebug) {
1131 ast_verb(0, "Sending start timer\n");
1132 }
1133 memcpy(buffsend + SIZE_HEADER, packet_send_start_timer, sizeof(packet_send_start_timer));
1134 send_client(SIZE_HEADER + sizeof(packet_send_start_timer), buffsend, pte);
1135}
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 1137 of file chan_unistim.c.

1138{
1139 BUFFSEND;
1140 if (unistimdebug) {
1141 ast_verb(0, "Sending stop timer\n");
1142 }
1143 memcpy(buffsend + SIZE_HEADER, packet_send_stop_timer, sizeof(packet_send_stop_timer));
1144 send_client(SIZE_HEADER + sizeof(packet_send_stop_timer), buffsend, pte);
1145}
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 1578 of file chan_unistim.c.

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

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

1742{
1743 BUFFSEND;
1744 int i;
1745 if (unistimdebug) {
1746 ast_verb(0, "Sending title text\n");
1747 }
1748 memcpy(buffsend + SIZE_HEADER, packet_send_title, sizeof(packet_send_title));
1749 i = strlen(text);
1750 if (i > 12) {
1751 i = 12;
1752 }
1753 memcpy(buffsend + 10, text, i);
1754 send_client(SIZE_HEADER + sizeof(packet_send_title), buffsend, pte);
1755}
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 1201 of file chan_unistim.c.

1202{
1203 BUFFSEND;
1204 if (!tone1) {
1205 if (unistimdebug) {
1206 ast_verb(0, "Sending Stream Based Tone Off\n");
1207 }
1211 return;
1212 }
1213 /* Since most of the world use a continuous tone, it's useless
1214 if (unistimdebug)
1215 ast_verb(0, "Sending Stream Based Tone Cadence Download\n");
1216 memcpy (buffsend + SIZE_HEADER, packet_send_StreamBasedToneCad, sizeof (packet_send_StreamBasedToneCad));
1217 send_client (SIZE_HEADER + sizeof (packet_send_StreamBasedToneCad), buffsend, pte); */
1218 if (unistimdebug) {
1219 ast_verb(0, "Sending Stream Based Tone Frequency Component List Download %d %d\n", tone1, tone2);
1220 }
1221 tone1 *= 8;
1222 if (!tone2) {
1225 put_unaligned_uint16(&buffsend[10], htons(tone1));
1227 pte);
1228 } else {
1229 tone2 *= 8;
1232 put_unaligned_uint16(&buffsend[10], htons(tone1));
1233 put_unaligned_uint16(&buffsend[12], htons(tone2));
1235 pte);
1236 }
1237
1238 if (unistimdebug) {
1239 ast_verb(0, "Sending Stream Based Tone On\n");
1240 }
1244}
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 1090 of file chan_unistim.c.

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

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

3985{
3986 char line[TEXT_LENGTH_MAX + 1], status[STATUS_LENGTH_MAX + 1], func1[10], func2[10],
3987 func3[10];
3988
3989 /* Display date/time and call status */
3990 if (fread(line, TEXT_LENGTH_MAX, 1, *f) != 1) {
3991 display_last_error("Can't read history date entry");
3992 fclose(*f);
3993 return;
3994 }
3995 line[sizeof(line) - 1] = '\0';
3996 if (pte->device->height == 1) {
3997 if (pte->buff_entry[3] == 1) {
3998 send_text(TEXT_LINE0, TEXT_NORMAL, pte, line);
3999 }
4000 } else {
4001 send_text(TEXT_LINE0, TEXT_NORMAL, pte, line);
4002 }
4003 /* Display number */
4004 if (fread(line, TEXT_LENGTH_MAX, 1, *f) != 1) {
4005 display_last_error("Can't read callerid entry");
4006 fclose(*f);
4007 return;
4008 }
4009 line[sizeof(line) - 1] = '\0';
4010 ast_copy_string(pte->device->lst_cid, line, sizeof(pte->device->lst_cid));
4012 if (pte->device->height == 1) {
4013 if (pte->buff_entry[3] == 2) {
4014 send_text(TEXT_LINE0, TEXT_NORMAL, pte, line);
4015 }
4016 } else {
4017 send_text(TEXT_LINE1, TEXT_NORMAL, pte, line);
4018 }
4019 /* Display name */
4020 if (fread(line, TEXT_LENGTH_MAX, 1, *f) != 1) {
4021 display_last_error("Can't read callername entry");
4022 fclose(*f);
4023 return;
4024 }
4025 line[sizeof(line) - 1] = '\0';
4026 if (pte->device->height == 1) {
4027 if (pte->buff_entry[3] == 3) {
4028 send_text(TEXT_LINE0, TEXT_NORMAL, pte, line);
4029 }
4030 } else {
4031 send_text(TEXT_LINE2, TEXT_NORMAL, pte, line);
4032 }
4033 fclose(*f);
4034
4035 snprintf(line, sizeof(line), "%s %03d/%03d", ustmtext("Call", pte), pte->buff_entry[2],
4036 pte->buff_entry[1]);
4037 send_texttitle(pte, line);
4038
4039 if (pte->buff_entry[2] == 1) {
4040 ast_copy_string(func1, " ", sizeof(func1));
4041 } else {
4042 ast_copy_string(func1, ustmtext("Prev ", pte), sizeof(func1));
4043 }
4044 if (pte->buff_entry[2] >= pte->buff_entry[1]) {
4045 ast_copy_string(func2, " ", sizeof(func2));
4046 } else {
4047 ast_copy_string(func2, ustmtext("Next ", pte), sizeof(func2));
4048 }
4049 if (strlen(pte->device->lst_cid)) {
4050 ast_copy_string(func3, ustmtext("Redial ", pte), sizeof(func3));
4051 } else {
4052 ast_copy_string(func3, " ", sizeof(func3));
4053 }
4054 snprintf(status, sizeof(status), "%s%s%s%s", func1, func2, func3, ustmtext("Cancel", pte));
4056}
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 4086 of file chan_unistim.c.

4087{
4088 FILE *f;
4089 char count;
4090
4091 if (!pte->device) {
4092 return;
4093 }
4094 if (!pte->device->callhistory) {
4095 return;
4096 }
4097 count = open_history(pte, way, &f);
4098 if (!count) {
4099 return;
4100 }
4101 pte->buff_entry[0] = way;
4102 pte->buff_entry[1] = count;
4103 pte->buff_entry[2] = 1;
4104 pte->buff_entry[3] = 1;
4105 show_entry_history(pte, &f);
4106 pte->state = STATE_HISTORY;
4107}

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

4110{
4111 char tmpbuf[TEXT_LENGTH_MAX + 1];
4112 const char *text;
4113
4114 if ((pte->device->extension == EXTENSION_ASK) &&
4117 return;
4118 }
4119
4120 pte->state = STATE_MAINPAGE;
4122 pte->device->lastmsgssent = -1;
4123
4124 send_tone(pte, 0, 0);
4125 send_stop_timer(pte); /* case of holding call */
4129
4130 if (!ast_strlen_zero(pte->device->call_forward)) {
4131 if (pte->device->height == 1) {
4132 char tmp_field[100];
4133 snprintf(tmp_field, sizeof(tmp_field), "%s %s", ustmtext("Fwd to:", pte), pte->device->call_forward);
4134 send_text(TEXT_LINE0, TEXT_NORMAL, pte, tmp_field);
4135 } else {
4136 send_text(TEXT_LINE0, TEXT_NORMAL, pte, ustmtext("Call forwarded to :", pte));
4138 }
4141 send_text_status(pte, ustmtext("Dial NoFwd ", pte));
4142 } else {
4143 send_text_status(pte, ustmtext("Dial Redial NoFwd ", pte));
4144 }
4145 } else {
4146 if ((pte->device->extension == EXTENSION_ASK) || (pte->device->extension == EXTENSION_TN)) {
4148 send_text_status(pte, ustmtext("Dial Fwd Unregis", pte));
4149 } else {
4150 send_text_status(pte, ustmtext("Dial Redial Fwd Unregis", pte));
4151 }
4152 } else {
4154 send_text_status(pte, ustmtext("Dial Fwd Pickup", pte));
4155 } else {
4156 send_text_status(pte, ustmtext("Dial Redial Fwd Pickup", pte));
4157 }
4158 }
4160 if (pte->device->missed_call == 0) {
4161 send_date_time2(pte);
4162 send_idle_clock(pte);
4163 if (strlen(pte->device->maintext0)) {
4165 }
4166 } else {
4167 if (pte->device->missed_call == 1) {
4168 text = ustmtext("unanswered call", pte);
4169 } else {
4170 text = ustmtext("unanswered calls", pte);
4171 }
4172 snprintf(tmpbuf, sizeof(tmpbuf), "%d %s", pte->device->missed_call, text);
4173 send_text(TEXT_LINE0, TEXT_NORMAL, pte, tmpbuf);
4175 }
4176 }
4177 if (pte->device->height > 1) {
4178 if (ast_strlen_zero(pte->device->maintext2)) {
4179 strcpy(tmpbuf, "IP : ");
4180 strcat(tmpbuf, ast_inet_ntoa(pte->sin.sin_addr));
4181 send_text(TEXT_LINE2, TEXT_NORMAL, pte, tmpbuf);
4182 } else {
4184 }
4185 }
4186
4187 send_texttitle(pte, ustmtext(pte->device->titledefault, pte));
4189}
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 2944 of file chan_unistim.c.

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

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

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

2848{
2849 struct sockaddr_in sin = { 0, };
2850 struct sockaddr_in sout = { 0, };
2851 struct ast_sockaddr sin_tmp;
2852 struct ast_sockaddr sout_tmp;
2853
2854 /* Sanity checks */
2855 if (!sub) {
2856 ast_log(LOG_WARNING, "start_rtp with a null subchannel !\n");
2857 return;
2858 }
2859 if (!sub->parent) {
2860 ast_log(LOG_WARNING, "start_rtp with a null line!\n");
2861 return;
2862 }
2863 if (!sub->parent->parent) {
2864 ast_log(LOG_WARNING, "start_rtp with a null device!\n");
2865 return;
2866 }
2867 if (!sub->parent->parent->session) {
2868 ast_log(LOG_WARNING, "start_rtp with a null session!\n");
2869 return;
2870 }
2871 if (!sub->owner) {
2872 ast_log(LOG_WARNING, "start_rtp with a null asterisk channel!\n");
2873 return;
2874 }
2875 sout = sub->parent->parent->session->sout;
2876 ast_mutex_lock(&sub->lock);
2877 /* Allocate the RTP */
2878 if (unistimdebug) {
2879 ast_verb(0, "Starting RTP. Bind on %s\n", ast_inet_ntoa(sout.sin_addr));
2880 }
2881 ast_sockaddr_from_sin(&sout_tmp, &sout);
2882 sub->rtp = ast_rtp_instance_new("asterisk", sched, &sout_tmp, NULL);
2883 if (!sub->rtp) {
2884 ast_log(LOG_WARNING, "Unable to create RTP session: %s binaddr=%s\n",
2885 strerror(errno), ast_inet_ntoa(sout.sin_addr));
2886 ast_mutex_unlock(&sub->lock);
2887 return;
2888 }
2893 ast_rtp_instance_set_qos(sub->rtp, qos.tos_audio, qos.cos_audio, "UNISTIM RTP");
2894 ast_rtp_instance_set_prop(sub->rtp, AST_RTP_PROPERTY_NAT, sub->parent->parent->nat);
2895
2896 /* Create the RTP connection */
2897 sin.sin_family = AF_INET;
2898 /* Setting up RTP for our side */
2899 memcpy(&sin.sin_addr, &sub->parent->parent->session->sin.sin_addr,
2900 sizeof(sin.sin_addr));
2901
2902 sin.sin_port = htons(find_rtp_port(sub));
2903 ast_sockaddr_from_sin(&sin_tmp, &sin);
2906 struct ast_format *tmpfmt;
2908
2911 "Our read/writeformat has been changed to something incompatible: %s, using %s best codec from %s\n",
2913 ast_format_get_name(tmpfmt),
2915
2916 ast_channel_set_readformat(sub->owner, tmpfmt);
2917 ast_channel_set_writeformat(sub->owner, tmpfmt);
2918 ao2_ref(tmpfmt, -1);
2919 }
2921 ast_mutex_unlock(&sub->lock);
2922}
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:400
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:581
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:734
#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:493
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:733
#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:581
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 2560 of file chan_unistim.c.

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

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

2530{
2531 /* Silence our channel */
2532 if (!pte->device->silence_generator) {
2535 if (pte->device->silence_generator == NULL) {
2536 ast_log(LOG_WARNING, "Unable to start a silence generator.\n");
2537 } else if (unistimdebug) {
2538 ast_verb(0, "Starting silence generator\n");
2539 }
2540 }
2541
2542}
struct ast_silence_generator * ast_channel_start_silence_generator(struct ast_channel *chan)
Starts a silence generator on the given channel.
Definition channel.c:8208
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 2544 of file chan_unistim.c.

2545{
2546 /* Stop the silence generator */
2547 if (pte->device->silence_generator) {
2548 if (unistimdebug) {
2549 ast_verb(0, "Stopping silence generator\n");
2550 }
2551 if (sub->owner) {
2553 } else {
2554 ast_log(LOG_WARNING, "Trying to stop silence generator on a null channel!\n");
2555 }
2557 }
2558}
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:8254

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

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

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

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

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

3029{
3030 struct ast_rtp_instance *rtp;
3031 int fds;
3032
3033 if (unistimdebug) {
3034 ast_verb(0, "Swapping %p and %p\n", a, b);
3035 }
3036 if ((!a->owner) || (!b->owner)) {
3038 "Attempted to swap subchannels with a null owner : sub #%p=%p sub #%p=%p\n",
3039 a, a->owner, b, b->owner);
3040 return;
3041 }
3042 rtp = a->rtp;
3043 a->rtp = b->rtp;
3044 b->rtp = rtp;
3045
3046 fds = ast_channel_fd(a->owner, 0);
3047 ast_channel_internal_fd_set(a->owner, 0, ast_channel_fd(b->owner, 0));
3048 ast_channel_internal_fd_set(b->owner, 0, fds);
3049
3050 fds = ast_channel_fd(a->owner, 1);
3051 ast_channel_internal_fd_set(a->owner, 1, ast_channel_fd(b->owner, 1));
3052 ast_channel_internal_fd_set(b->owner, 1, fds);
3053}
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 3056 of file chan_unistim.c.

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

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

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

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

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

5055{
5056 int res = 0;
5057 struct unistim_subchannel *sub;
5058 struct unistim_line *l;
5059 struct unistim_device *d;
5060 struct unistimsession *s;
5061
5062 s = channel_to_session(ast);
5063 if (!s) {
5064 ast_log(LOG_WARNING, "unistim_answer on a disconnected device ?\n");
5065 return -1;
5066 }
5068 l = sub->parent;
5069 d = l->parent;
5070
5071 if (unistimdebug) {
5072 ast_verb(0, "unistim_answer(%s) on %s@%s-%d\n", ast_channel_name(ast), l->name,
5073 l->parent->name, sub->softkey);
5074 }
5075 send_text(TEXT_LINE2, TEXT_NORMAL, s, ustmtext("is now on-line", s));
5076 if (get_sub(d, SUB_THREEWAY)) {
5077 send_text_status(s, ustmtext("Transf Cancel", s));
5078 } else {
5079 send_text_status(s, ustmtext(" Transf Hangup", s));
5080 }
5082 if (ast_channel_state(ast) != AST_STATE_UP)
5084 return res;
5085}
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:7398

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

4868{
4869 int res = 0, i;
4870 struct unistim_subchannel *sub, *sub_real;
4871 struct unistimsession *session;
4872 signed char ringstyle, ringvolume;
4873
4875 if (!session) {
4876 ast_log(LOG_ERROR, "Device not registered, cannot call %s\n", dest);
4877 return -1;
4878 }
4880 sub_real = get_sub(session->device, SUB_REAL);
4882 ast_log(LOG_WARNING, "unistim_call called on %s, neither down nor reserved\n",
4883 ast_channel_name(ast));
4884 return -1;
4885 }
4886
4887 if (unistimdebug) {
4888 ast_verb(3, "unistim_call(%s)\n", ast_channel_name(ast));
4889 }
4890 session->state = STATE_RINGING;
4892 if (ast_strlen_zero(ast_channel_call_forward(ast))) { /* Send ring only if no call forward, otherwise short ring will appear */
4893 send_text(TEXT_LINE2, TEXT_NORMAL, session, ustmtext("is calling you.", session));
4894 send_text_status(session, ustmtext("Accept Ignore Hangup", session));
4895
4896 if (sub_real) {
4897 ringstyle = session->device->cwstyle;
4898 ringvolume = session->device->cwvolume;
4899 } else {
4900 ringstyle = (sub->ringstyle == -1) ? session->device->ringstyle : sub->ringstyle;
4901 ringvolume = (sub->ringvolume == -1) ? session->device->ringvolume : sub->ringvolume;
4902 }
4903 send_ring(session, ringvolume, ringstyle);
4905 /* Send call identification to all */
4906 for (i = 0; i < FAVNUM; i++) {
4907 if (!soft_key_visible(session->device, i)) {
4908 continue;
4909 }
4910 if (session->device->ssub[i]) {
4911 continue;
4912 }
4913 if (is_key_line(session->device, i) && !strcmp(sub->parent->name, session->device->sline[i]->name)) {
4914 if (unistimdebug) {
4915 ast_verb(0, "Found softkey %d for line %s\n", i, sub->parent->name);
4916 }
4918 session->device->ssub[i] = sub;
4919 }
4920 }
4921 }
4924 return res;
4925}
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 6210 of file chan_unistim.c.

6211{
6212 switch (cmd) {
6213 case CLI_INIT:
6214 e->command = "unistim set debug {on|off}";
6215 e->usage =
6216 "Usage: unistim set debug\n"
6217 " Display debug messages.\n";
6218 return NULL;
6219
6220 case CLI_GENERATE:
6221 return NULL; /* no completion */
6222 }
6223
6224 if (a->argc != e->args) {
6225 return CLI_SHOWUSAGE;
6226 }
6227 if (!strcasecmp(a->argv[3], "on")) {
6228 unistimdebug = 1;
6229 ast_cli(a->fd, "UNISTIM Debugging Enabled\n");
6230 } else if (!strcasecmp(a->argv[3], "off")) {
6231 unistimdebug = 0;
6232 ast_cli(a->fd, "UNISTIM Debugging Disabled\n");
6233 } else {
6234 return CLI_SHOWUSAGE;
6235 }
6236 return CLI_SUCCESS;
6237}
#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 3356 of file chan_unistim.c.

3357{
3358 struct ast_frame f = { .frametype = AST_FRAME_DTMF, .subclass.integer = digit, .src = "unistim" };
3359 struct unistim_subchannel *sub;
3360
3361 sub = get_sub(pte->device, SUB_REAL);
3362 if (!sub || !sub->owner || sub->alreadygone) {
3363 ast_log(LOG_WARNING, "Unable to find subchannel in dtmf senddigit\n");
3364 return -1;
3365 }
3366
3367 /* Send DTMF indication _before_ playing sounds */
3368 ast_queue_frame(sub->owner, &f);
3369 if (pte->device->dtmfduration > 0) {
3370 if (unistimdebug) {
3371 ast_verb(0, "Send Digit %c (%i ms)\n", digit, pte->device->dtmfduration);
3372 }
3373 send_dtmf_tone(pte, digit);
3374 usleep(pte->device->dtmfduration * 1000); /* XXX Less than perfect, blocking an important thread is not a good idea */
3375 send_tone(pte, 0, 0);
3376 }
3377 return 0;
3378}
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:1170
#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 5252 of file chan_unistim.c.

5253{
5254 struct unistim_subchannel *p = ast_channel_tech_pvt(newchan);
5255 struct unistim_line *l = p->parent;
5256
5257 ast_mutex_lock(&p->lock);
5258
5259 ast_debug(1, "New owner for channel USTM/%s@%s-%u is %s\n", l->name,
5260 l->parent->name, p->subtype, ast_channel_name(newchan));
5261
5262 if (p->owner != oldchan) {
5263 ast_log(LOG_WARNING, "old channel wasn't %s (%p) but was %s (%p)\n",
5264 ast_channel_name(oldchan), oldchan, ast_channel_name(p->owner), p->owner);
5266 return -1;
5267 }
5268
5269 unistim_set_owner(p, newchan);
5270
5272
5273 return 0;
5274
5275}
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 1979 of file chan_unistim.c.

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

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

7027{
7029
7030 if (!sub) {
7032 }
7033 if (!sub->rtp) {
7035 }
7036
7037 ao2_ref(sub->rtp, +1);
7038 *instance = sub->rtp;
7039
7041}
@ 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 4945 of file chan_unistim.c.

4946{
4947 struct unistim_subchannel *sub = NULL, *sub_real = NULL, *sub_trans = NULL;
4948 struct unistim_line *l;
4949 struct unistim_device *d;
4950 struct unistimsession *s;
4951 int i,end_call = 1;
4952
4953 s = channel_to_session(ast);
4955 l = sub->parent;
4956 d = l->parent;
4957 if (!s) {
4958 ast_debug(1, "Asked to hangup channel not connected\n");
4960 return 0;
4961 }
4962 if (unistimdebug) {
4963 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));
4964 }
4965 sub_trans = get_sub(d, SUB_THREEWAY);
4966 sub_real = get_sub(d, SUB_REAL);
4967 if (sub_trans && (sub_trans->owner) && (sub->subtype == SUB_REAL)) { /* 3rd party busy or congested and transfer_cancel_step2 does not called */
4968 if (unistimdebug) {
4969 ast_verb(0, "Threeway call disconnected, switching to real call\n");
4970 }
4971 ast_queue_unhold(sub_trans->owner);
4972 sub_trans->moh = 0;
4973 sub_trans->subtype = SUB_REAL;
4974 swap_subs(sub_trans, sub);
4975 send_text_status(s, ustmtext(" Transf Hangup", s));
4976 send_callerid_screen(s, sub_trans);
4979 return 0;
4980 }
4981 if (sub_real && (sub_real->owner) && (sub->subtype == SUB_THREEWAY) && (s->state == STATE_CALL)) { /* 3way call cancelled by softkey pressed */
4982 if (unistimdebug) {
4983 ast_verb(0, "Real call disconnected, stay in call\n");
4984 }
4985 send_text_status(s, ustmtext(" Transf Hangup", s));
4986 send_callerid_screen(s, sub_real);
4989 return 0;
4990 }
4991 if (sub->subtype == SUB_REAL) {
4993 } else if (sub->subtype == SUB_RING) {
4994 send_no_ring(s);
4995 for (i = 0; i < FAVNUM; i++) {
4996 if (!soft_key_visible(s->device, i)) {
4997 continue;
4998 }
4999 if (d->ssub[i] != sub) {
5000 if (d->ssub[i] != NULL) { /* Found other subchannel active other than hangup'ed one */
5001 end_call = 0;
5002 }
5003 continue;
5004 }
5005 if (is_key_line(d, i) && !strcmp(l->name, d->sline[i]->name)) {
5007 d->ssub[i] = NULL;
5008 continue;
5009 }
5010 }
5011 }
5012 if (end_call) {
5013 send_end_call(s); /* Send end call packet only if ending active call, in other way sound should be loosed */
5014 }
5015 sub->moh = 0;
5016 if (sub->softkey >= 0) {
5018 }
5019 /* Delete assign sub to softkey */
5020 for (i = 0; i < FAVNUM; i++) {
5021 if (d->ssub[i] == sub) {
5022 d->ssub[i] = NULL;
5023 break;
5024 }
5025 }
5026 /*refresh_all_favorite(s); */ /* TODO: Update favicons in case of DND keys */
5027 if (s->state == STATE_RINGING && sub->subtype == SUB_RING) {
5028 send_no_ring(s);
5030 d->missed_call++;
5031 write_history(s, 'i', 1);
5032 }
5033 if (!sub_real) {
5034 show_main_page(s);
5035 } else { /* hangup on a ringing line: reset status to reflect that we're still on an active call */
5036 s->state = STATE_CALL;
5037 send_callerid_screen(s, sub_real);
5038 send_text(TEXT_LINE2, TEXT_NORMAL, s, ustmtext("is on-line", s));
5039 send_text_status(s, ustmtext(" Transf Hangup", s));
5041
5042 }
5043 }
5044 if (s->state == STATE_CALL && sub->subtype == SUB_REAL) {
5045 close_call(s);
5046 }
5047 sub->softkey = -1;
5050 return 0;
5051}
#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 4927 of file chan_unistim.c.

4927 {
4928 ast_mutex_lock(&sub->lock);
4931 sub->alreadygone = 0;
4932 if (sub->rtp) {
4933 if (unistimdebug) {
4934 ast_verb(0, "Destroying RTP session\n");
4935 }
4938 sub->rtp = NULL;
4939 }
4940 ast_mutex_unlock(&sub->lock);
4941 return 0;
4942}
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:464
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 5331 of file chan_unistim.c.

5332{
5333 struct unistim_subchannel *sub;
5334 struct unistim_line *l;
5335 struct unistimsession *s;
5336
5337 if (unistimdebug) {
5338 ast_verb(3, "Asked to indicate '%s' (%d) condition on channel %s\n",
5339 control2str(ind), ind, ast_channel_name(ast));
5340 }
5341
5342 s = channel_to_session(ast);
5343 if (!s) {
5344 return -1;
5345 }
5347 l = sub->parent;
5348
5349 switch (ind) {
5351 if (ast_channel_state(ast) != AST_STATE_UP) {
5352 send_text(TEXT_LINE2, TEXT_NORMAL, s, ustmtext("Ringing...", s));
5353 in_band_indication(ast, l->parent->tz, "ring");
5354 s->device->missed_call = -1;
5355 break;
5356 }
5357 return -1;
5358 case AST_CONTROL_BUSY:
5359 if (ast_channel_state(ast) != AST_STATE_UP) {
5360 sub->alreadygone = 1;
5361 send_text(TEXT_LINE2, TEXT_NORMAL, s, ustmtext("Busy", s));
5362 in_band_indication(ast, l->parent->tz, "busy");
5363 s->device->missed_call = -1;
5364 break;
5365 }
5366 return -1;
5368 /* Overlapped dialing is not currently supported for UNIStim. Treat an indication
5369 * of incomplete as congestion
5370 */
5372 if (ast_channel_state(ast) != AST_STATE_UP) {
5373 sub->alreadygone = 1;
5374 send_text(TEXT_LINE2, TEXT_NORMAL, s, ustmtext("Congestion", s));
5375 in_band_indication(ast, l->parent->tz, "congestion");
5376 s->device->missed_call = -1;
5377 break;
5378 }
5379 return -1;
5380 case AST_CONTROL_HOLD:
5381 ast_moh_start(ast, data, NULL);
5382 break;
5383 case AST_CONTROL_UNHOLD:
5384 ast_moh_stop(ast);
5385 break;
5390 break;
5391 case -1:
5392 ast_playtones_stop(ast);
5393 s->device->missed_call = 0;
5394 break;
5396 ast_log(LOG_NOTICE, "Connected party is now %s <%s>\n",
5397 S_COR(ast_channel_connected(ast)->id.name.valid, ast_channel_connected(ast)->id.name.str, ""),
5398 S_COR(ast_channel_connected(ast)->id.number.valid, ast_channel_connected(ast)->id.number.str, ""));
5399 if (sub->subtype == SUB_REAL) {
5401 }
5402 break;
5404 if (sub->rtp) {
5406 }
5407 break;
5408 default:
5409 ast_log(LOG_WARNING, "Don't know how to indicate condition %d\n", ind);
5410 /* fallthrough */
5413 return -1;
5414 }
5415
5416 return 0;
5417}
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:7778
void ast_moh_stop(struct ast_channel *chan)
Turn off music on hold on a given channel.
Definition channel.c:7788
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 1965 of file chan_unistim.c.

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

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

1948{
1949 struct ast_format_cap *tmp = src->cap;
1950 memcpy(dst, src, sizeof(*dst)); /* this over writes the cap ptr, so we have to reset it */
1951 src->cap = tmp;
1953}
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 1955 of file chan_unistim.c.

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

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

5703{
5704 struct ast_format_cap *caps;
5705 struct ast_channel *tmp;
5706 struct unistim_line *l;
5707 struct ast_format *tmpfmt;
5708
5709 if (!sub) {
5710 ast_log(LOG_WARNING, "subchannel null in unistim_new\n");
5711 return NULL;
5712 }
5713 if (!sub->parent) {
5714 ast_log(LOG_WARNING, "no line for subchannel %p\n", sub);
5715 return NULL;
5716 }
5717
5719 if (!caps) {
5720 return NULL;
5721 }
5722
5723 l = sub->parent;
5724 tmp = ast_channel_alloc(1, state, l->cid_num, NULL, l->accountcode, l->exten,
5725 l->parent->context, assignedids, requestor, l->amaflags, "USTM/%s@%s-%p", l->name, l->parent->name, sub);
5726 if (unistimdebug) {
5727 ast_verb(0, "unistim_new sub=%u (%p) chan=%p line=%s\n", sub->subtype, sub, tmp, l->name);
5728 }
5729 if (!tmp) {
5730 ast_log(LOG_WARNING, "Unable to allocate channel structure\n");
5731 ao2_ref(caps, -1);
5732 return NULL;
5733 }
5734
5736
5737 if (ast_format_cap_count(l->cap)) {
5739 } else {
5741 }
5743 ao2_ref(caps, -1);
5744
5746
5747 if (unistimdebug) {
5748 struct ast_str *native_buf = ast_str_alloca(AST_FORMAT_CAP_NAMES_LEN);
5750 struct ast_str *global_buf = ast_str_alloca(AST_FORMAT_CAP_NAMES_LEN);
5751
5752 ast_verb(0, "Best codec = %s from nativeformats %s (line cap=%s global=%s)\n",
5753 ast_format_get_name(tmpfmt),
5755 ast_format_cap_get_names(l->cap, &cap_buf),
5756 ast_format_cap_get_names(global_cap, &global_buf));
5757 }
5758 if ((sub->rtp) && (sub->subtype == 0)) {
5759 if (unistimdebug) {
5760 ast_verb(0, "New unistim channel with a previous rtp handle ?\n");
5761 }
5764 }
5765 if (sub->rtp) {
5767 }
5768/* tmp->type = type; */
5769 ast_setstate(tmp, state);
5770 if (state == AST_STATE_RING) {
5771 ast_channel_rings_set(tmp, 1);
5772 }
5774
5775 ast_channel_set_writeformat(tmp, tmpfmt);
5776 ast_channel_set_rawwriteformat(tmp, tmpfmt);
5777 ast_channel_set_readformat(tmp, tmpfmt);
5778 ast_channel_set_rawreadformat(tmp, tmpfmt);
5779 ao2_ref(tmpfmt, -1);
5780
5783
5784 if (!ast_strlen_zero(l->parent->language)) {
5785 ast_channel_language_set(tmp, l->parent->language);
5786 }
5787 unistim_set_owner(sub, tmp);
5791 ast_channel_call_forward_set(tmp, l->parent->call_forward);
5792 if (!ast_strlen_zero(l->cid_num)) {
5793 char *name, *loc, *instr;
5794 instr = ast_strdup(l->cid_num);
5795 if (instr) {
5796 ast_callerid_parse(instr, &name, &loc);
5798 ast_free(ast_channel_caller(tmp)->id.number.str);
5800 ast_channel_caller(tmp)->id.name.valid = 1;
5801 ast_free(ast_channel_caller(tmp)->id.name.str);
5803 ast_free(instr);
5804 }
5805 }
5807
5809 ast_channel_unlock(tmp);
5810
5811 if (state != AST_STATE_DOWN) {
5812 if (unistimdebug) {
5813 ast_verb(0, "Starting pbx in unistim_new\n");
5814 }
5815 if (ast_pbx_start(tmp)) {
5816 ast_log(LOG_WARNING, "Unable to start PBX on %s\n", ast_channel_name(tmp));
5817 ast_hangup(tmp);
5818 tmp = NULL;
5819 }
5820 }
5821
5822 return tmp;
5823}
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:395
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:4729
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 5202 of file chan_unistim.c.

5203{
5204 struct ast_frame *fr;
5206
5207 ast_mutex_lock(&sub->lock);
5208 fr = unistim_rtp_read(ast, sub);
5209 ast_mutex_unlock(&sub->lock);
5210
5211 return fr;
5212}
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 1920 of file chan_unistim.c.

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

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

6244{
6245 switch (cmd) {
6246 case CLI_INIT:
6247 e->command = "unistim reload";
6248 e->usage =
6249 "Usage: unistim reload\n"
6250 " Reloads UNISTIM configuration from unistim.conf\n";
6251 return NULL;
6252
6253 case CLI_GENERATE:
6254 return NULL; /* no completion */
6255 }
6256
6257 if (e && a && a->argc != e->args) {
6258 return CLI_SHOWUSAGE;
6259 }
6260 reload();
6261
6262 return CLI_SUCCESS;
6263}
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 5954 of file chan_unistim.c.

5956{
5957 struct unistim_subchannel *sub, *sub_ring, *sub_trans;
5958 struct unistim_device *d;
5959 struct ast_channel *tmpc = NULL;
5960 char tmp[256];
5961
5964 struct ast_str *global_buf = ast_str_alloca(AST_FORMAT_CAP_NAMES_LEN);
5966 "Asked to get a channel of unsupported format %s while capability is %s\n",
5967 ast_format_cap_get_names(cap, &cap_buf),
5968 ast_format_cap_get_names(global_cap, &global_buf));
5969 return NULL;
5970 }
5971
5972 ast_copy_string(tmp, dest, sizeof(tmp));
5973 if (ast_strlen_zero(tmp)) {
5974 ast_log(LOG_NOTICE, "Unistim channels require a device\n");
5975 return NULL;
5976 }
5978 if (!sub) {
5979 ast_log(LOG_NOTICE, "No available lines on: %s\n", dest);
5980 *cause = AST_CAUSE_CONGESTION;
5981 return NULL;
5982 }
5983 d = sub->parent->parent;
5984 sub_ring = get_sub(d, SUB_RING);
5985 sub_trans = get_sub(d, SUB_THREEWAY);
5986 /* Another request already in progress */
5987 if (!d->session) {
5989 *cause = AST_CAUSE_CONGESTION;
5990 return NULL;
5991 }
5992 if (sub_ring || sub_trans) {
5993 if (unistimdebug) {
5994 ast_verb(0, "Can't create channel, request already in progress: Busy!\n");
5995 }
5997 *cause = AST_CAUSE_BUSY;
5998 return NULL;
5999 }
6000 if (d->session->state == STATE_DIALPAGE) {
6001 if (unistimdebug) {
6002 ast_verb(0, "Can't create channel, user on dialpage: Busy!\n");
6003 }
6005 *cause = AST_CAUSE_BUSY;
6006 return NULL;
6007 }
6008
6009 if (get_avail_softkey(d->session, sub->parent->name) == -1) {
6010 if (unistimdebug) {
6011 ast_verb(0, "Can't create channel for line %s, all lines busy\n", sub->parent->name);
6012 }
6014 *cause = AST_CAUSE_BUSY;
6015 return NULL;
6016 }
6017 sub->subtype = SUB_RING;
6018 sub->softkey = -1;
6019
6021 tmpc = unistim_new(sub, AST_STATE_DOWN, assignedids, requestor);
6022 if (!tmpc) {
6023 ast_log(LOG_WARNING, "Unable to make channel for '%s'\n", tmp);
6024 }
6025 if (unistimdebug) {
6026 ast_verb(0, "unistim_request owner = %p\n", sub->owner);
6027 }
6029 /* and finish */
6030 return tmpc;
6031}
#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:653

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

5149{
5150 /* Retrieve audio/etc from channel. Assumes sub->lock is already held. */
5151 struct ast_frame *f;
5152
5153 if (!ast) {
5154 ast_log(LOG_WARNING, "Channel NULL while reading\n");
5155 return &ast_null_frame;
5156 }
5157
5158 if (!sub->rtp) {
5159 ast_log(LOG_WARNING, "RTP handle NULL while reading on subchannel %u\n",
5160 sub->subtype);
5161 return &ast_null_frame;
5162 }
5163
5164 switch (ast_channel_fdno(ast)) {
5165 case 0:
5166 f = ast_rtp_instance_read(sub->rtp, 0); /* RTP Audio */
5167 break;
5168 case 1:
5169 f = ast_rtp_instance_read(sub->rtp, 1); /* RTCP Control Channel */
5170 break;
5171 default:
5172 f = &ast_null_frame;
5173 }
5174
5175 if (sub->owner) {
5176 /* We already hold the channel lock */
5177 if (f->frametype == AST_FRAME_VOICE) {
5180 struct ast_format_cap *caps;
5181
5182 ast_debug(1,
5183 "Oooh, format changed from %s to %s\n",
5186
5188 if (caps) {
5190 ast_channel_nativeformats_set(sub->owner, caps);
5191 ao2_ref(caps, -1);
5192 }
5195 }
5196 }
5197 }
5198
5199 return f;
5200}
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:5757
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:5798
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:606
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 5673 of file chan_unistim.c.

5674{
5675 int new;
5676 RAII_VAR(struct stasis_message *, msg, NULL, ao2_cleanup);
5677
5679 if (msg) {
5680 struct ast_mwi_state *mwi_state = stasis_message_data(msg);
5681 new = mwi_state->new_msgs;
5682 } else { /* Fall back on checking the mailbox directly */
5683 new = ast_app_has_voicemail(peer->mailbox, NULL);
5684 }
5685 ast_debug(3, "MWI Status for mailbox %s is %d, lastmsgsent:%d\n",
5686 peer->mailbox, new, peer->parent->lastmsgssent);
5687 peer->parent->nextmsgcheck = tick + TIMER_MWI;
5688
5689 /* Return now if it's the same thing we told them last time */
5690 if ((peer->parent->session->state != STATE_MAINPAGE) || (new == peer->parent->lastmsgssent)) {
5691 return 0;
5692 }
5693
5694 peer->parent->lastmsgssent = new;
5696
5697 return 0;
5698}
#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 5507 of file chan_unistim.c.

5508{
5509 struct unistimsession *pte = channel_to_session(ast);
5510
5511 if (!pte) {
5512 return -1;
5513 }
5514 return send_dtmf_tone(pte, digit);
5515}

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

5518{
5519 struct unistimsession *pte = channel_to_session(ast);
5520
5521 if (!pte) {
5522 return -1;
5523 }
5524
5525 if (unistimdebug) {
5526 ast_verb(0, "Send Digit off %c (duration %d)\n", digit, duration);
5527 }
5528 send_tone(pte, 0, 0);
5529 return 0;
5530}

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

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

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

5826{
5827 sub->owner = chan;
5828 if (sub->rtp) {
5829 ast_rtp_instance_set_channel_id(sub->rtp, sub->owner ? ast_channel_uniqueid(sub->owner) : "");
5830 }
5831}

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

7044{
7046 struct sockaddr_in them = { 0, };
7047 struct sockaddr_in us = { 0, };
7048
7049 if (!rtp) {
7050 return 0;
7051 }
7052
7053 sub = (struct unistim_subchannel *) ast_channel_tech_pvt(chan);
7054 if (!sub) {
7055 ast_log(LOG_ERROR, "No Private Structure, this is bad\n");
7056 return -1;
7057 }
7058 {
7059 struct ast_sockaddr tmp;
7061 ast_sockaddr_to_sin(&tmp, &them);
7063 ast_sockaddr_to_sin(&tmp, &us);
7064 }
7065
7066 /* TODO: Set rtp on phone in case of direct rtp (not implemented) */
7067
7068 return 0;
7069}

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

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

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

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

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

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

2660{
2661 struct ast_channel *chan = data;
2663 struct unistim_line *l = sub->parent;
2664 struct unistimsession *s = l->parent->session;
2665 int res;
2666
2667 if (!s) {
2668 return NULL;
2669 }
2670 ast_verb(3, "Starting switch on '%s@%s-%d' to %s\n", l->name, l->parent->name, sub->softkey, s->device->phone_number);
2671 ast_channel_lock(chan);
2674 ast_channel_unlock(chan);
2676 sizeof(s->device->redial_number));
2677 res = ast_pbx_run(chan);
2678 if (res) {
2679 ast_log(LOG_WARNING, "PBX exited non-zero\n");
2680 send_tone(s, 1000, 0);
2681 }
2682 return NULL;
2683}
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:4776
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 2007 of file chan_unistim.c.

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

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

5215{
5217 int res = 0;
5218
5219 if (frame->frametype != AST_FRAME_VOICE) {
5220 if (frame->frametype == AST_FRAME_IMAGE) {
5221 return 0;
5222 } else {
5223 ast_log(LOG_WARNING, "Can't send %u type frames with unistim_write\n",
5224 frame->frametype);
5225 return 0;
5226 }
5227 } else {
5230
5232 "Asked to transmit frame type %s, while native formats is %s (read/write = (%s/%s)\n",
5237 return -1;
5238 }
5239 }
5240
5241 if (sub) {
5242 ast_mutex_lock(&sub->lock);
5243 if (sub->rtp) {
5244 res = ast_rtp_instance_write(sub->rtp, frame);
5245 }
5246 ast_mutex_unlock(&sub->lock);
5247 }
5248
5249 return res;
5250}
int ast_rtp_instance_write(struct ast_rtp_instance *instance, struct ast_frame *frame)
Send a frame out over RTP.
Definition rtp_engine.c:596

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

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

7150{
7151 /* First, take us out of the channel loop */
7152 if (sched) {
7154 }
7155
7157
7161
7164 pthread_cancel(monitor_thread);
7165 pthread_kill(monitor_thread, SIGURG);
7166 pthread_join(monitor_thread, NULL);
7167 }
7170
7171 if (buff) {
7172 ast_free(buff);
7173 }
7174 if (unistimsock > -1) {
7175 close(unistimsock);
7176 }
7177 ao2_ref(global_cap, -1);
7178
7179 return 0;
7180}
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:570
int ast_rtp_glue_unregister(struct ast_rtp_glue *glue)
Unregister RTP glue.
Definition rtp_engine.c:414

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

6274{
6275 int len = strlen(src);
6276 if (!len) {
6277 return;
6278 }
6279 if ((len > 1) && src[0] == '\"') {
6280 /* This is a quoted string */
6281 src++;
6282 /* Don't take more than what's there */
6283 len--;
6284 if (maxlen > len - 1) {
6285 maxlen = len - 1;
6286 }
6287 memcpy(out, src, maxlen);
6288 ((char *) out)[maxlen] = '\0';
6289 } else {
6290 memcpy(out, src, maxlen);
6291 }
6292 return;
6293}
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 1459 of file chan_unistim.c.

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

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

801{
802 struct ustm_lang_entry *lang_entry;
803 struct ustm_lang_entry le_search;
804 struct unistim_languages *lang = NULL;
805 int size;
806
807 if (pte->device) {
809 }
810 if (!lang) {
811 return str;
812 }
813 /* Check if specified language exists */
814 if (!lang->trans) {
815 char tmp[1024], *p, *p_orig = NULL, *p_trans = NULL;
816 FILE *f;
817
820 if (!lang->trans) {
821 ast_log(LOG_ERROR, "Unable to allocate container for translation!\n");
822 return str;
823 }
824 snprintf(tmp, sizeof(tmp), "%s/%s/%s.po", ast_config_AST_VAR_DIR,
826 f = fopen(tmp, "r");
827 if (!f) {
828 ast_log(LOG_WARNING, "There is no translation file for '%s'\n", lang->lang_short);
829 return str;
830 }
831 while (fgets(tmp, sizeof(tmp), f)) {
832 if (!(p = strchr(tmp, '\n'))) {
833 ast_log(LOG_ERROR, "Too long line found in language file - truncated!\n");
834 continue;
835 }
836 *p = '\0';
837 if (!(p = strchr(tmp, '"'))) {
838 continue;
839 }
840 if (tmp == strstr(tmp, "msgid")) {
841 p_orig = ast_strdup(p + 1);
842 p = strchr(p_orig, '"');
843 } else if (tmp == strstr(tmp, "msgstr")) {
844 p_trans = ast_strdup(p + 1);
845 p = strchr(p_trans, '"');
846 } else {
847 continue;
848 }
849 *p = '\0';
850 if (!p_trans || !p_orig) {
851 continue;
852 }
853 if (ast_strlen_zero(p_trans)) {
854 ast_free(p_trans);
855 ast_free(p_orig);
856 p_trans = NULL;
857 p_orig = NULL;
858 continue;
859 }
860 if (!(lang_entry = ao2_alloc(sizeof(*lang_entry), NULL))) {
861 fclose(f);
862 return str;
863 }
864
865 lang_entry->str_trans = p_trans;
866 lang_entry->str_orig = p_orig;
867 ao2_link(lang->trans, lang_entry);
868 p_trans = NULL;
869 p_orig = NULL;
870 }
871
872 fclose(f);
873 }
874
875 le_search.str_orig = str;
876 if ((lang_entry = ao2_find(lang->trans, &le_search, OBJ_POINTER))) {
877 size = strlen(lang_entry->str_trans)+1;
878 if (size > 1024) {
879 size = 1024;
880 }
881 memcpy(ustm_strcopy, lang_entry->str_trans, size);
882 ao2_ref(lang_entry, -1);
883 return ustm_strcopy;
884 }
885
886 return str;
887}
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 2260 of file chan_unistim.c.

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

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

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

◆ ast_module_info

const struct ast_module_info* ast_module_info = &__mod_info
static

Definition at line 7204 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 707 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 649 of file chan_unistim.c.

650 { 'J', 'a', 'n', 'F', 'e', 'b', 'M', 'a', 'r', 'A', 'p', 'r', 'M', 'a', 'y', 'J', 'u', 'n',
651 '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 771 of file chan_unistim.c.

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

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

765{
766 {"Change codec", STATE_SELECTCODEC, handle_select_codec},
768 {NULL, 0, NULL}
769};
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 506 of file chan_unistim.c.

507 { 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 524 of file chan_unistim.c.

525 { 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 511 of file chan_unistim.c.

512 { 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 519 of file chan_unistim.c.

520 { 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 513 of file chan_unistim.c.

514 { 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 535 of file chan_unistim.c.

536 { 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 517 of file chan_unistim.c.

518 { 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 515 of file chan_unistim.c.

516 { 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 521 of file chan_unistim.c.

521{ 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 533 of file chan_unistim.c.

534 { 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 633 of file chan_unistim.c.

633{ 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 634 of file chan_unistim.c.

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

Referenced by send_blink_cursor().

◆ packet_send_call

const unsigned char packet_send_call[]
static

Definition at line 558 of file chan_unistim.c.

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

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

692 { 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 679 of file chan_unistim.c.

680 { 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 682 of file chan_unistim.c.

683 { 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 685 of file chan_unistim.c.

686 { 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 688 of file chan_unistim.c.

689 { 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 638 of file chan_unistim.c.

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

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

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

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

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

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

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

509 { 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 592 of file chan_unistim.c.

593 { 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 527 of file chan_unistim.c.

527{ 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 526 of file chan_unistim.c.

526{ 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 528 of file chan_unistim.c.

528 { 0x09, 0x0f, 0x57, 0x19, /*pos */ 0x47, /*text */ 0x20,
529 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 654 of file chan_unistim.c.

655 { 0x17, 0x0f, 0x19, 0x10, /*pos */ 0x01, /*name */ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
6560x20, 0x20, 0x20, 0x20, /*end_name */ 0x19,
657 0x05, 0x0f, /*pos */ 0x01, /*icone */ 0x00
658};

Referenced by send_favorite().

◆ packet_send_icon

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

Definition at line 644 of file chan_unistim.c.

644{ 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 599 of file chan_unistim.c.

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

Referenced by send_start_rtp().

◆ packet_send_led_update

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

Definition at line 694 of file chan_unistim.c.

694{ 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 652 of file chan_unistim.c.

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

570{ 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 549 of file chan_unistim.c.

550 { 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 608 of file chan_unistim.c.

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

Referenced by send_start_rtp().

◆ packet_send_open_audio_stream_rx3

const unsigned char packet_send_open_audio_stream_rx3[]
static

Definition at line 619 of file chan_unistim.c.

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

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

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

Referenced by send_start_rtp().

◆ packet_send_open_audio_stream_tx3

const unsigned char packet_send_open_audio_stream_tx3[]
static

Definition at line 626 of file chan_unistim.c.

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

Referenced by send_start_rtp().

◆ packet_send_ping

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

Definition at line 701 of file chan_unistim.c.

702 { 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 696 of file chan_unistim.c.

696{ 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 698 of file chan_unistim.c.

698{ 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 697 of file chan_unistim.c.

697{ 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 584 of file chan_unistim.c.

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

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

598 { 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 699 of file chan_unistim.c.

699{ 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 551 of file chan_unistim.c.

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

Referenced by init_phone_step2().

◆ packet_send_S7

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

Definition at line 645 of file chan_unistim.c.

645{ 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 594 of file chan_unistim.c.

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

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

582 { 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 646 of file chan_unistim.c.

647 { 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 640 of file chan_unistim.c.

641 { 0x17, 0x05, 0x0b, /*Timer option*/0x05, /* Timer ID */0x00, 0x17, 0x08, 0x16,
642 /* 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 668 of file chan_unistim.c.

669 { 0x17, 0x20, 0x19, 0x08, /*text */ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
6700x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
671 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20 /*end_text */
672};

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

674 { 0x17, 0x0b, 0x19, /* pos [08|28|48|68] */ 0x00, /* text */ 0x20, 0x20, 0x20, 0x20,
6750x20, 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 643 of file chan_unistim.c.

643{ 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 579 of file chan_unistim.c.

580 { 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 567 of file chan_unistim.c.

568 { 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 575 of file chan_unistim.c.

576 { 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 577 of file chan_unistim.c.

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

Referenced by send_tone().

◆ packet_send_text

const unsigned char packet_send_text[]
static

Definition at line 662 of file chan_unistim.c.

663 { 0x17, 0x1e, 0x1b, 0x04, /*pos */ 0x00, /*inverse */ 0x25, /*text */ 0x20, 0x20,
6640x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
665 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
666 /*end_text */ 0x17, 0x04, 0x10, 0x87
667};

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

660 { 0x17, 0x10, 0x19, 0x02, /*text */ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
6610x20, 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 706 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 6265 of file chan_unistim.c.

6265 {
6266 AST_CLI_DEFINE(unistim_reload, "Reload UNISTIM configuration"),
6267 AST_CLI_DEFINE(unistim_show_info, "Show UNISTIM info"),
6268 AST_CLI_DEFINE(unistim_show_devices, "Show UNISTIM devices"),
6269 AST_CLI_DEFINE(unistim_sp, "Send packet (for reverse engineering)"),
6270 AST_CLI_DEFINE(unistim_do_debug, "Toggle UNITSTIM debugging"),
6271};
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 7071 of file chan_unistim.c.

7071 {
7072 .type = channel_type,
7073 .get_rtp_info = unistim_get_rtp_peer,
7074 .update_peer = unistim_set_rtp_peer,
7075};

Referenced by load_module(), and unload_module().

◆ unistim_tech

struct ast_channel_tech unistim_tech
static

Definition at line 736 of file chan_unistim.c.

736 {
737 .type = channel_type,
738 .description = tdesc,
740 .requester = unistim_request,
741 .call = unistim_call,
742 .hangup = unistim_hangup,
743 .answer = unistim_answer,
744 .read = unistim_read,
745 .write = unistim_write,
746 .indicate = unistim_indicate,
747 .fixup = unistim_fixup,
748 .send_digit_begin = unistim_senddigit_begin,
749 .send_digit_end = unistim_senddigit_end,
750 .send_text = unistim_sendtext,
751};
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 779 of file chan_unistim.c.

Referenced by ustmtext().