#include "asterisk.h"
#include <sys/socket.h>
#include <netinet/in.h>
#include <netinet/tcp.h>
#include <sys/ioctl.h>
#include <net/if.h>
#include <fcntl.h>
#include <netdb.h>
#include <arpa/inet.h>
#include <sys/signal.h>
#include <signal.h>
#include <ctype.h>
#include "asterisk/lock.h"
#include "asterisk/channel.h"
#include "asterisk/config.h"
#include "asterisk/module.h"
#include "asterisk/pbx.h"
#include "asterisk/sched.h"
#include "asterisk/io.h"
#include "asterisk/rtp.h"
#include "asterisk/netsock.h"
#include "asterisk/acl.h"
#include "asterisk/callerid.h"
#include "asterisk/cli.h"
#include "asterisk/say.h"
#include "asterisk/cdr.h"
#include "asterisk/astdb.h"
#include "asterisk/features.h"
#include "asterisk/app.h"
#include "asterisk/musiconhold.h"
#include "asterisk/utils.h"
#include "asterisk/dsp.h"
#include "asterisk/stringfields.h"
#include "asterisk/abstract_jb.h"
#include "asterisk/threadstorage.h"
#include "asterisk/devicestate.h"
#include "asterisk/event.h"
#include "asterisk/indications.h"
#include "asterisk/linkedlists.h"
#include <byteswap.h>
Go to the source code of this file.
Data Structures | |
struct | activate_call_plane_message |
struct | alarm_message |
struct | button_definition |
struct | button_definition_template |
struct | button_template_res_message |
struct | call_info_message |
struct | call_state_message |
struct | capabilities_res_message |
struct | clear_prompt_message |
struct | close_receive_channel_message |
struct | definetimedate_message |
struct | devices |
struct | dialed_number_message |
struct | display_notify_message |
struct | display_prompt_status_message |
struct | displaytext_message |
struct | enbloc_call_message |
struct | forward_stat_message |
struct | keypad_button_message |
struct | line_stat_res_message |
struct | line_state_req_message |
struct | media_qualifier |
struct | offhook_message |
struct | onhook_message |
struct | open_receive_channel_ack_message |
struct | open_receive_channel_message |
struct | register_ack_message |
struct | register_message |
struct | register_rej_message |
struct | reset_message |
struct | select_soft_keys_message |
struct | server_identifier |
struct | server_res_message |
struct | sessions |
struct | set_lamp_message |
struct | set_microphone_message |
struct | set_ringer_message |
struct | set_speaker_message |
struct | skinny_addon |
union | skinny_data |
struct | skinny_device |
struct | skinny_line |
struct | skinny_req |
struct | skinny_speeddial |
struct | skinny_subchannel |
struct | skinnysession |
struct | soft_key_definitions |
struct | soft_key_event_message |
struct | soft_key_set_definition |
struct | soft_key_set_res_message |
struct | soft_key_template_definition |
struct | soft_key_template_res_message |
struct | speed_dial_stat_req_message |
struct | speed_dial_stat_res_message |
struct | start_media_transmission_message |
struct | start_tone_message |
struct | station_capabilities |
struct | stimulus_message |
struct | stop_media_transmission_message |
struct | stop_tone_message |
struct | version_res_message |
Defines | |
#define | ACTIVATE_CALL_PLANE_MESSAGE 0x0116 |
#define | ALARM_MESSAGE 0x0020 |
#define | BT_AUTOANSWER STIMULUS_AUTOANSWER |
#define | BT_CALLPARK STIMULUS_CALLPARK |
#define | BT_CALLPICKUP STIMULUS_CALLPICKUP |
#define | BT_CONFERENCE STIMULUS_CONFERENCE |
#define | BT_CUST_LINE 0xB1 |
#define | BT_CUST_LINESPEEDDIAL 0xB0 |
#define | BT_DISPLAY STIMULUS_DISPLAY |
#define | BT_DND STIMULUS_DND |
#define | BT_FORWARDALL STIMULUS_FORWARDALL |
#define | BT_FORWARDBUSY STIMULUS_FORWARDBUSY |
#define | BT_FORWARDNOANSWER STIMULUS_FORWARDNOANSWER |
#define | BT_HOLD STIMULUS_HOLD |
#define | BT_LINE STIMULUS_LINE |
#define | BT_NONE 0x00 |
#define | BT_REDIAL STIMULUS_REDIAL |
#define | BT_SPEEDDIAL STIMULUS_SPEEDDIAL |
#define | BT_TRANSFER STIMULUS_TRANSFER |
#define | BT_VOICEMAIL STIMULUS_VOICEMAIL |
#define | BUTTON_TEMPLATE_REQ_MESSAGE 0x000E |
#define | BUTTON_TEMPLATE_RES_MESSAGE 0x0097 |
#define | CALL_INFO_MESSAGE 0x008F |
#define | CALL_STATE_MESSAGE 0x0111 |
#define | CAPABILITIES_REQ_MESSAGE 0x009B |
#define | CAPABILITIES_RES_MESSAGE 0x0010 |
#define | CLEAR_DISPLAY_MESSAGE 0x009A |
#define | CLEAR_NOTIFY_MESSAGE 0x0115 |
#define | CLEAR_PROMPT_MESSAGE 0x0113 |
#define | CLOSE_RECEIVE_CHANNEL_MESSAGE 0x0106 |
#define | CONTROL2STR_BUFSIZE 100 |
#define | DEFAULT_SKINNY_BACKLOG 2 |
#define | DEFAULT_SKINNY_PORT 2000 |
#define | DEFINETIMEDATE_MESSAGE 0x0094 |
#define | DEVICE2STR_BUFSIZE 15 |
#define | DIALED_NUMBER_MESSAGE 0x011D |
#define | DISPLAY_NOTIFY_MESSAGE 0x0114 |
#define | DISPLAY_PROMPT_STATUS_MESSAGE 0x0112 |
#define | DISPLAYTEXT_MESSAGE 0x0099 |
#define | ENBLOC_CALL_MESSAGE 0x0004 |
#define | FORWARD_STAT_MESSAGE 0x0090 |
#define | HEADSET_STATUS_MESSAGE 0x002B |
#define | htolel(x) bswap_32(x) |
#define | htoles(x) bswap_16(x) |
#define | IP_PORT_MESSAGE 0x0002 |
#define | KEEP_ALIVE_ACK_MESSAGE 0x0100 |
#define | KEEP_ALIVE_MESSAGE 0x0000 |
#define | KEYDEF_CONNECTED 1 |
#define | KEYDEF_CONNWITHCONF 7 |
#define | KEYDEF_CONNWITHTRANS 5 |
#define | KEYDEF_DADFD 6 |
#define | KEYDEF_OFFHOOK 4 |
#define | KEYDEF_OFFHOOKWITHFEAT 9 |
#define | KEYDEF_ONHOLD 2 |
#define | KEYDEF_ONHOOK 0 |
#define | KEYDEF_RINGIN 3 |
#define | KEYDEF_RINGOUT 8 |
#define | KEYDEF_UNKNOWN 10 |
#define | KEYPAD_BUTTON_MESSAGE 0x0003 |
#define | letohl(x) bswap_32(x) |
#define | letohs(x) bswap_16(x) |
#define | LINE_STAT_RES_MESSAGE 0x0092 |
#define | LINE_STATE_REQ_MESSAGE 0x000B |
#define | OFFHOOK_MESSAGE 0x0006 |
#define | ONHOOK_MESSAGE 0x0007 |
#define | OPEN_RECEIVE_CHANNEL_ACK_MESSAGE 0x0022 |
#define | OPEN_RECEIVE_CHANNEL_MESSAGE 0x0105 |
#define | REGISTER_ACK_MESSAGE 0x0081 |
#define | REGISTER_AVAILABLE_LINES_MESSAGE 0x002D |
#define | REGISTER_MESSAGE 0x0001 |
#define | REGISTER_REJ_MESSAGE 0x009D |
#define | RESET_MESSAGE 0x009F |
#define | SELECT_SOFT_KEYS_MESSAGE 0x0110 |
#define | SERVER_REQUEST_MESSAGE 0x0012 |
#define | SERVER_RES_MESSAGE 0x009E |
#define | SET_LAMP_MESSAGE 0x0086 |
#define | SET_MICROPHONE_MESSAGE 0x0089 |
#define | SET_RINGER_MESSAGE 0x0085 |
#define | SET_SPEAKER_MESSAGE 0x0088 |
#define | SKINNY_ALERT 0x24 |
#define | SKINNY_BUSY 6 |
#define | SKINNY_BUSYTONE 0x23 |
#define | SKINNY_CALLREMOTEMULTILINE 13 |
#define | SKINNY_CALLWAIT 9 |
#define | SKINNY_CALLWAITTONE 0x2D |
#define | SKINNY_CFWD_ALL (1 << 0) |
#define | SKINNY_CFWD_BUSY (1 << 1) |
#define | SKINNY_CFWD_NOANSWER (1 << 2) |
#define | SKINNY_CONGESTION 7 |
#define | SKINNY_CONNECTED 5 |
#define | SKINNY_CX_CONF 3 |
#define | SKINNY_CX_CONFERENCE 3 |
#define | SKINNY_CX_INACTIVE 4 |
#define | SKINNY_CX_MUTE 4 |
#define | SKINNY_CX_RECVONLY 1 |
#define | SKINNY_CX_SENDONLY 0 |
#define | SKINNY_CX_SENDRECV 2 |
#define | SKINNY_DEVICE_12 4 |
#define | SKINNY_DEVICE_12SP 3 |
#define | SKINNY_DEVICE_12SPPLUS 2 |
#define | SKINNY_DEVICE_30SPPLUS 1 |
#define | SKINNY_DEVICE_30VIP 5 |
#define | SKINNY_DEVICE_7902 30008 |
#define | SKINNY_DEVICE_7905 20000 |
#define | SKINNY_DEVICE_7906 369 |
#define | SKINNY_DEVICE_7910 6 |
#define | SKINNY_DEVICE_7911 307 |
#define | SKINNY_DEVICE_7912 30007 |
#define | SKINNY_DEVICE_7914 124 |
#define | SKINNY_DEVICE_7920 30002 |
#define | SKINNY_DEVICE_7921 365 |
#define | SKINNY_DEVICE_7931 348 |
#define | SKINNY_DEVICE_7935 9 |
#define | SKINNY_DEVICE_7936 30019 |
#define | SKINNY_DEVICE_7937 431 |
#define | SKINNY_DEVICE_7940 8 |
#define | SKINNY_DEVICE_7941 115 |
#define | SKINNY_DEVICE_7941GE 309 |
#define | SKINNY_DEVICE_7942 434 |
#define | SKINNY_DEVICE_7945 435 |
#define | SKINNY_DEVICE_7960 7 |
#define | SKINNY_DEVICE_7961 30018 |
#define | SKINNY_DEVICE_7961GE 308 |
#define | SKINNY_DEVICE_7962 404 |
#define | SKINNY_DEVICE_7965 436 |
#define | SKINNY_DEVICE_7970 30006 |
#define | SKINNY_DEVICE_7971 119 |
#define | SKINNY_DEVICE_7975 437 |
#define | SKINNY_DEVICE_7985 302 |
#define | SKINNY_DEVICE_ATA186 12 |
#define | SKINNY_DEVICE_CIPC 30016 |
#define | SKINNY_DEVICE_NONE 0 |
#define | SKINNY_DEVICE_SCCPGATEWAY_AN 30027 |
#define | SKINNY_DEVICE_SCCPGATEWAY_BRI 30028 |
#define | SKINNY_DEVICE_UNKNOWN -1 |
#define | SKINNY_DIALTONE 0x21 |
#define | SKINNY_HOLD 8 |
#define | SKINNY_INVALID 14 |
#define | SKINNY_LAMP_BLINK 5 |
#define | SKINNY_LAMP_FLASH 4 |
#define | SKINNY_LAMP_OFF 1 |
#define | SKINNY_LAMP_ON 2 |
#define | SKINNY_LAMP_WINK 3 |
#define | SKINNY_MAX_CAPABILITIES 18 |
#define | SKINNY_MAX_PACKET 1000 |
#define | SKINNY_MICOFF 2 |
#define | SKINNY_MICON 1 |
#define | SKINNY_NOTONE 0x7F |
#define | SKINNY_OFFHOOK 1 |
#define | SKINNY_ONHOOK 2 |
#define | SKINNY_PARK 11 |
#define | SKINNY_PROGRESS 12 |
#define | SKINNY_REORDER 0x25 |
#define | SKINNY_RING_FEATURE 4 |
#define | SKINNY_RING_INSIDE 2 |
#define | SKINNY_RING_OFF 1 |
#define | SKINNY_RING_OUTSIDE 3 |
#define | SKINNY_RINGIN 4 |
#define | SKINNY_RINGOUT 3 |
#define | SKINNY_SILENCE 0x00 |
#define | SKINNY_SPEAKEROFF 2 |
#define | SKINNY_SPEAKERON 1 |
#define | SKINNY_TRANSFER 10 |
#define | SOFT_KEY_EVENT_MESSAGE 0x0026 |
#define | SOFT_KEY_SET_REQ_MESSAGE 0x0025 |
#define | SOFT_KEY_SET_RES_MESSAGE 0x0109 |
#define | SOFT_KEY_TEMPLATE_REQ_MESSAGE 0x0028 |
#define | SOFT_KEY_TEMPLATE_RES_MESSAGE 0x0108 |
#define | SOFTKEY_ANSWER 0x0B |
#define | SOFTKEY_BKSPC 0x08 |
#define | SOFTKEY_CFWDALL 0x05 |
#define | SOFTKEY_CFWDBUSY 0x06 |
#define | SOFTKEY_CFWDNOANSWER 0x07 |
#define | SOFTKEY_CONFRN 0x0D |
#define | SOFTKEY_DND 0x13 |
#define | SOFTKEY_ENDCALL 0x09 |
#define | SOFTKEY_GPICKUP 0x12 |
#define | SOFTKEY_HOLD 0x03 |
#define | SOFTKEY_IDIVERT 0x14 |
#define | SOFTKEY_INFO 0x0C |
#define | SOFTKEY_JOIN 0x0F |
#define | SOFTKEY_MEETME 0x10 |
#define | SOFTKEY_NEWCALL 0x02 |
#define | SOFTKEY_NONE 0x00 |
#define | SOFTKEY_PARK 0x0E |
#define | SOFTKEY_PICKUP 0x11 |
#define | SOFTKEY_REDIAL 0x01 |
#define | SOFTKEY_RESUME 0x0A |
#define | SOFTKEY_TRNSFER 0x04 |
#define | SPEED_DIAL_STAT_REQ_MESSAGE 0x000A |
#define | SPEED_DIAL_STAT_RES_MESSAGE 0x0091 |
#define | START_MEDIA_TRANSMISSION_MESSAGE 0x008A |
#define | START_TONE_MESSAGE 0x0082 |
#define | STIMULUS_AUTOANSWER 0x11 |
#define | STIMULUS_CALLPARK 0x7E |
#define | STIMULUS_CALLPICKUP 0x7F |
#define | STIMULUS_CONFERENCE 0x7D |
#define | STIMULUS_DISPLAY 0x08 |
#define | STIMULUS_DND 0x3F |
#define | STIMULUS_FORWARDALL 0x05 |
#define | STIMULUS_FORWARDBUSY 0x06 |
#define | STIMULUS_FORWARDNOANSWER 0x07 |
#define | STIMULUS_HOLD 0x03 |
#define | STIMULUS_LINE 0x09 |
#define | STIMULUS_MESSAGE 0x0005 |
#define | STIMULUS_NONE 0xFF |
#define | STIMULUS_REDIAL 0x01 |
#define | STIMULUS_SPEEDDIAL 0x02 |
#define | STIMULUS_TRANSFER 0x04 |
#define | STIMULUS_VOICEMAIL 0x0F |
#define | STOP_MEDIA_TRANSMISSION_MESSAGE 0x008B |
#define | STOP_TONE_MESSAGE 0x0083 |
#define | TIME_DATE_REQ_MESSAGE 0x000D |
#define | TYPE_LINE 2 |
#define | TYPE_TRUNK 1 |
#define | UNREGISTER_MESSAGE 0x0027 |
#define | VERSION_REQ_MESSAGE 0x000F |
#define | VERSION_RES_MESSAGE 0x0098 |
Enumerations | |
enum | skinny_codecs { SKINNY_CODEC_ALAW = 2, SKINNY_CODEC_ULAW = 4, SKINNY_CODEC_G723_1 = 9, SKINNY_CODEC_G729A = 12, SKINNY_CODEC_G726_32 = 82, SKINNY_CODEC_H261 = 100, SKINNY_CODEC_H263 = 101 } |
Functions | |
static void | __init_control2str_threadbuf (void) |
static void | __init_device2str_threadbuf (void) |
static void | __reg_module (void) |
static void | __unreg_module (void) |
static void * | accept_thread (void *ignore) |
static struct ast_variable * | add_var (const char *buf, struct ast_variable *list) |
static struct skinny_device * | build_device (const char *cat, struct ast_variable *v) |
static void | cleanup_stale_contexts (char *new, char *old) |
static int | codec_ast2skinny (int astcodec) |
static int | codec_skinny2ast (enum skinny_codecs skinnycodec) |
static char * | complete_skinny_devices (const char *word, int state) |
static char * | complete_skinny_reset (const char *line, const char *word, int pos, int state) |
static char * | complete_skinny_show_device (const char *line, const char *word, int pos, int state) |
static char * | complete_skinny_show_line (const char *line, const char *word, int pos, int state) |
static char * | control2str (int ind) |
static void | delete_devices (void) |
static void | destroy_session (struct skinnysession *s) |
static char * | device2str (int type) |
static void | do_housekeeping (struct skinnysession *s) |
static void * | do_monitor (void *data) |
static struct skinny_line * | find_line_by_instance (struct skinny_device *d, int instance) |
static struct skinny_line * | find_line_by_name (const char *dest) |
static struct skinny_speeddial * | find_speeddial_by_instance (struct skinny_device *d, int instance, int isHint) |
static struct skinny_subchannel * | find_subchannel_by_instance_reference (struct skinny_device *d, int instance, int reference) |
static struct skinny_subchannel * | find_subchannel_by_reference (struct skinny_device *d, int reference) |
static void * | get_button_template (struct skinnysession *s, struct button_definition_template *btn) |
static int | get_devicestate (struct skinny_line *l) |
static int | get_input (struct skinnysession *s) |
static int | handle_alarm_message (struct skinny_req *req, struct skinnysession *s) |
static int | handle_button_template_req_message (struct skinny_req *req, struct skinnysession *s) |
static int | handle_callforward_button (struct skinny_subchannel *sub, int cfwdtype) |
static int | handle_capabilities_res_message (struct skinny_req *req, struct skinnysession *s) |
static int | handle_enbloc_call_message (struct skinny_req *req, struct skinnysession *s) |
static int | handle_headset_status_message (struct skinny_req *req, struct skinnysession *s) |
static int | handle_hold_button (struct skinny_subchannel *sub) |
static int | handle_ip_port_message (struct skinny_req *req, struct skinnysession *s) |
static int | handle_keep_alive_message (struct skinny_req *req, struct skinnysession *s) |
static int | handle_keypad_button_message (struct skinny_req *req, struct skinnysession *s) |
static int | handle_line_state_req_message (struct skinny_req *req, struct skinnysession *s) |
static int | handle_message (struct skinny_req *req, struct skinnysession *s) |
static int | handle_offhook_message (struct skinny_req *req, struct skinnysession *s) |
static int | handle_onhook_message (struct skinny_req *req, struct skinnysession *s) |
static int | handle_open_receive_channel_ack_message (struct skinny_req *req, struct skinnysession *s) |
static int | handle_register_available_lines_message (struct skinny_req *req, struct skinnysession *s) |
static int | handle_register_message (struct skinny_req *req, struct skinnysession *s) |
static int | handle_server_request_message (struct skinny_req *req, struct skinnysession *s) |
static char * | handle_skinny_reset (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a) |
static char * | handle_skinny_set_debug (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a) |
static char * | handle_skinny_set_debug_deprecated (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a) |
static char * | handle_skinny_show_device (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a) |
Show device information. | |
static char * | handle_skinny_show_devices (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a) |
static char * | handle_skinny_show_line (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a) |
List line information. | |
static char * | handle_skinny_show_lines (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a) |
static char * | handle_skinny_show_settings (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a) |
List global settings for the Skinny subsystem. | |
static int | handle_soft_key_event_message (struct skinny_req *req, struct skinnysession *s) |
static int | handle_soft_key_set_req_message (struct skinny_req *req, struct skinnysession *s) |
static int | handle_soft_key_template_req_message (struct skinny_req *req, struct skinnysession *s) |
static int | handle_speed_dial_stat_req_message (struct skinny_req *req, struct skinnysession *s) |
static int | handle_stimulus_message (struct skinny_req *req, struct skinnysession *s) |
static int | handle_time_date_req_message (struct skinny_req *req, struct skinnysession *s) |
static int | handle_transfer_button (struct skinny_subchannel *sub) |
static int | handle_unregister_message (struct skinny_req *req, struct skinnysession *s) |
static int | handle_version_req_message (struct skinny_req *req, struct skinnysession *s) |
static int | has_voicemail (struct skinny_line *l) |
static int | load_module (void) |
static void | mwi_event_cb (const struct ast_event *event, void *userdata) |
static void | print_codec_to_cli (int fd, struct ast_codec_pref *pref) |
Print codec list from preference to CLI/manager. | |
static void | register_exten (struct skinny_line *l) |
static int | reload_config (void) |
static struct skinny_req * | req_alloc (size_t size, int response_message) |
static int | restart_monitor (void) |
static int | set_callforwards (struct skinny_line *l, const char *cfwd, int cfwdtype) |
static int | skinny_answer (struct ast_channel *ast) |
static int | skinny_call (struct ast_channel *ast, char *dest, int timeout) |
static int | skinny_devicestate (void *data) |
static int | skinny_extensionstate_cb (char *context, char *exten, int state, void *data) |
static int | skinny_fixup (struct ast_channel *oldchan, struct ast_channel *newchan) |
static enum ast_rtp_get_result | skinny_get_rtp_peer (struct ast_channel *c, struct ast_rtp **rtp) |
static enum ast_rtp_get_result | skinny_get_vrtp_peer (struct ast_channel *c, struct ast_rtp **rtp) |
static int | skinny_hangup (struct ast_channel *ast) |
static int | skinny_hold (struct skinny_subchannel *sub) |
static int | skinny_indicate (struct ast_channel *ast, int ind, const void *data, size_t datalen) |
static struct ast_channel * | skinny_new (struct skinny_line *l, int state) |
static void * | skinny_newcall (void *data) |
static struct ast_frame * | skinny_read (struct ast_channel *ast) |
static int | skinny_register (struct skinny_req *req, struct skinnysession *s) |
static struct skinny_req * | skinny_req_parse (struct skinnysession *s) |
static struct ast_channel * | skinny_request (const char *type, int format, void *data, int *cause) |
static struct ast_frame * | skinny_rtp_read (struct skinny_subchannel *sub) |
static int | skinny_senddigit_begin (struct ast_channel *ast, char digit) |
static int | skinny_senddigit_end (struct ast_channel *ast, char digit, unsigned int duration) |
static void * | skinny_session (void *data) |
static int | skinny_set_rtp_peer (struct ast_channel *c, struct ast_rtp *rtp, struct ast_rtp *vrtp, struct ast_rtp *trtp, int codecs, int nat_active) |
static void * | skinny_ss (void *data) |
static int | skinny_transfer (struct skinny_subchannel *sub) |
static int | skinny_unhold (struct skinny_subchannel *sub) |
static int | skinny_unregister (struct skinny_req *req, struct skinnysession *s) |
static int | skinny_write (struct ast_channel *ast, struct ast_frame *frame) |
static void | start_rtp (struct skinny_subchannel *sub) |
static void | transmit_activatecallplane (struct skinny_device *d, struct skinny_line *l) |
static void | transmit_callinfo (struct skinny_device *d, const char *fromname, const char *fromnum, const char *toname, const char *tonum, int instance, int callid, int calltype) |
static void | transmit_callstate (struct skinny_device *d, int instance, int state, unsigned callid) |
static void | transmit_callstateonly (struct skinny_device *d, struct skinny_subchannel *sub, int state) |
static void | transmit_cfwdstate (struct skinny_device *d, struct skinny_line *l) |
static void | transmit_closereceivechannel (struct skinny_device *d, struct skinny_subchannel *sub) |
static void | transmit_connect (struct skinny_device *d, struct skinny_subchannel *sub) |
static void | transmit_dialednumber (struct skinny_device *d, const char *text, int instance, int callid) |
static void | transmit_displaymessage (struct skinny_device *d, const char *text, int instance, int reference) |
static void | transmit_displaynotify (struct skinny_device *d, const char *text, int t) |
static void | transmit_displaypromptstatus (struct skinny_device *d, const char *text, int t, int instance, int callid) |
static void | transmit_lamp_indication (struct skinny_device *d, int stimulus, int instance, int indication) |
static int | transmit_response (struct skinny_device *d, struct skinny_req *req) |
static void | transmit_ringer_mode (struct skinny_device *d, int mode) |
static void | transmit_selectsoftkeys (struct skinny_device *d, int instance, int callid, int softkey) |
static void | transmit_speaker_mode (struct skinny_device *d, int mode) |
static void | transmit_stopmediatransmission (struct skinny_device *d, struct skinny_subchannel *sub) |
static void | transmit_tone (struct skinny_device *d, int tone, int instance, int reference) |
static int | unload_module (void) |
static void | unregister_exten (struct skinny_line *l) |
Variables | |
static struct ast_module_info | __mod_info = { .name = AST_MODULE, .flags = AST_MODFLAG_DEFAULT , .description = "Skinny Client Control Protocol (Skinny)" , .key = "This paragraph is copyright (c) 2006 by Digium, Inc. \In order for your module to load, it must return this \key via a function called \"key\". Any code which \includes this paragraph must be licensed under the GNU \General Public License version 2 or later (at your \option). In addition to Digium's general reservations \of rights, Digium expressly reserves the right to \allow other parties to license this paragraph under \different terms. Any use of Digium, Inc. trademarks or \logos (including \"Asterisk\" or \"Digium\") without \express written permission of Digium, Inc. is prohibited.\n" , .buildopt_sum = "a9c98e5d177805051735cb5b0b16b0a0" , .load = load_module, .unload = unload_module, } |
static struct in_addr | __ourip |
static pthread_t | accept_t |
static char | accountcode [AST_MAX_ACCOUNT_CODE] = "" |
ast_hostent | ahp |
static int | amaflags = 0 |
static struct ast_module_info * | ast_module_info = &__mod_info |
static struct sockaddr_in | bindaddr |
static int | callnums = 1 |
static int | callreturn = 0 |
static int | callwaiting = 0 |
static int | cancallforward = 0 |
static int | canreinvite = 0 |
static char | cid_name [AST_MAX_EXTENSION] = "" |
static char | cid_num [AST_MAX_EXTENSION] = "" |
static struct ast_cli_entry | cli_skinny [] |
static struct ast_cli_entry | cli_skinny_set_debug_deprecated = { .handler = handle_skinny_set_debug_deprecated , .summary = "Enable/Disable Skinny debugging" ,__VA_ARGS__ } |
static const char | config [] = "skinny.conf" |
static struct ast_threadstorage | control2str_threadbuf = { .once = PTHREAD_ONCE_INIT, .key_init = __init_control2str_threadbuf , .custom_init = NULL , } |
static ast_group_t | cur_callergroup = 0 |
static ast_group_t | cur_pickupgroup = 0 |
static char | date_format [6] = "D-M-Y" |
static int | default_capability = AST_FORMAT_ULAW | AST_FORMAT_ALAW |
static struct ast_jb_conf | default_jbconf |
static struct ast_codec_pref | default_prefs |
static struct ast_threadstorage | device2str_threadbuf = { .once = PTHREAD_ONCE_INIT, .key_init = __init_device2str_threadbuf , .custom_init = NULL , } |
static int | firstdigittimeout = 16000 |
static int | gendigittimeout = 8000 |
static char | global_context [AST_MAX_CONTEXT] = "default" |
static struct ast_jb_conf | global_jbconf |
hostent * | hp |
static int | immediate = 0 |
static struct io_context * | io |
static int | keep_alive = 120 |
static char | language [MAX_LANGUAGE] = "" |
static char | linelabel [AST_MAX_EXTENSION] = "" |
static char | mailbox [AST_MAX_EXTENSION] |
static int | matchdigittimeout = 3000 |
static char | mohinterpret [MAX_MUSICCLASS] = "default" |
static char | mohsuggest [MAX_MUSICCLASS] = "" |
static pthread_t | monitor_thread = AST_PTHREADT_NULL |
static ast_mutex_t | monlock = ((ast_mutex_t) PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP ) |
static int | mwiblink = 0 |
static int | nat = 0 |
static ast_mutex_t | netlock = ((ast_mutex_t) PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP ) |
static char | ourhost [256] |
static int | ourport |
static char | parkinglot [AST_MAX_CONTEXT] = "" |
struct { | |
unsigned int cos | |
unsigned int cos_audio | |
unsigned int cos_video | |
unsigned int tos | |
unsigned int tos_audio | |
unsigned int tos_video | |
} | qos |
static char | regcontext [AST_MAX_CONTEXT] |
static char | regexten [AST_MAX_EXTENSION] |
static struct sched_context * | sched = NULL |
int | skinny_header_size = 12 |
static struct ast_rtp_protocol | skinny_rtp |
static struct ast_channel_tech | skinny_tech |
static int | skinnydebug = 0 |
static int | skinnysock = -1 |
static const uint8_t | soft_key_default_connected [] |
static const uint8_t | soft_key_default_connwithconf [] |
static const uint8_t | soft_key_default_connwithtrans [] |
static const uint8_t | soft_key_default_dadfd [] |
static struct soft_key_definitions | soft_key_default_definitions [] |
static const uint8_t | soft_key_default_offhook [] |
static const uint8_t | soft_key_default_offhookwithfeat [] |
static const uint8_t | soft_key_default_onhold [] |
static const uint8_t | soft_key_default_onhook [] |
static const uint8_t | soft_key_default_ringin [] |
static const uint8_t | soft_key_default_ringout [] |
static const uint8_t | soft_key_default_unknown [] |
soft_key_template_definition | soft_key_template_default [] |
static const char | tdesc [] = "Skinny Client Control Protocol (Skinny)" |
static int | threewaycalling = 0 |
static int | transfer = 0 |
static char | used_context [AST_MAX_EXTENSION] |
static char | version_id [16] = "P002F202" |
static char | vmexten [AST_MAX_EXTENSION] |
Definition in file chan_skinny.c.
#define ACTIVATE_CALL_PLANE_MESSAGE 0x0116 |
Definition at line 884 of file chan_skinny.c.
Referenced by transmit_activatecallplane(), and transmit_callstate().
#define ALARM_MESSAGE 0x0020 |
#define BT_AUTOANSWER STIMULUS_AUTOANSWER |
Definition at line 458 of file chan_skinny.c.
#define BT_CALLPARK STIMULUS_CALLPARK |
#define BT_CALLPICKUP STIMULUS_CALLPICKUP |
Definition at line 462 of file chan_skinny.c.
#define BT_CONFERENCE STIMULUS_CONFERENCE |
#define BT_CUST_LINE 0xB1 |
Definition at line 469 of file chan_skinny.c.
Referenced by get_button_template(), and handle_button_template_req_message().
#define BT_CUST_LINESPEEDDIAL 0xB0 |
Definition at line 468 of file chan_skinny.c.
Referenced by get_button_template(), and handle_button_template_req_message().
#define BT_DISPLAY STIMULUS_DISPLAY |
#define BT_DND STIMULUS_DND |
Definition at line 459 of file chan_skinny.c.
#define BT_FORWARDALL STIMULUS_FORWARDALL |
#define BT_FORWARDBUSY STIMULUS_FORWARDBUSY |
Definition at line 453 of file chan_skinny.c.
#define BT_FORWARDNOANSWER STIMULUS_FORWARDNOANSWER |
Definition at line 454 of file chan_skinny.c.
#define BT_HOLD STIMULUS_HOLD |
#define BT_LINE STIMULUS_LINE |
Definition at line 456 of file chan_skinny.c.
Referenced by get_button_template(), and handle_button_template_req_message().
#define BT_NONE 0x00 |
Definition at line 463 of file chan_skinny.c.
Referenced by get_button_template(), and handle_button_template_req_message().
#define BT_REDIAL STIMULUS_REDIAL |
#define BT_SPEEDDIAL STIMULUS_SPEEDDIAL |
Definition at line 449 of file chan_skinny.c.
Referenced by get_button_template(), and handle_button_template_req_message().
#define BT_TRANSFER STIMULUS_TRANSFER |
#define BT_VOICEMAIL STIMULUS_VOICEMAIL |
#define BUTTON_TEMPLATE_REQ_MESSAGE 0x000E |
#define BUTTON_TEMPLATE_RES_MESSAGE 0x0097 |
#define CALL_INFO_MESSAGE 0x008F |
#define CALL_STATE_MESSAGE 0x0111 |
Definition at line 855 of file chan_skinny.c.
Referenced by transmit_callstate(), and transmit_callstateonly().
#define CAPABILITIES_REQ_MESSAGE 0x009B |
#define CAPABILITIES_RES_MESSAGE 0x0010 |
#define CLEAR_DISPLAY_MESSAGE 0x009A |
#define CLEAR_NOTIFY_MESSAGE 0x0115 |
Definition at line 488 of file chan_skinny.c.
#define CLEAR_PROMPT_MESSAGE 0x0113 |
#define CLOSE_RECEIVE_CHANNEL_MESSAGE 0x0106 |
Definition at line 527 of file chan_skinny.c.
Referenced by transmit_callstate(), and transmit_closereceivechannel().
#define CONTROL2STR_BUFSIZE 100 |
#define DEFAULT_SKINNY_BACKLOG 2 |
#define DEFAULT_SKINNY_PORT 2000 |
#define DEFINETIMEDATE_MESSAGE 0x0094 |
#define DEVICE2STR_BUFSIZE 15 |
#define DIALED_NUMBER_MESSAGE 0x011D |
#define DISPLAY_NOTIFY_MESSAGE 0x0114 |
#define DISPLAY_PROMPT_STATUS_MESSAGE 0x0112 |
#define DISPLAYTEXT_MESSAGE 0x0099 |
#define ENBLOC_CALL_MESSAGE 0x0004 |
#define FORWARD_STAT_MESSAGE 0x0090 |
#define HEADSET_STATUS_MESSAGE 0x002B |
#define htolel | ( | x | ) | bswap_32(x) |
Definition at line 122 of file chan_skinny.c.
Referenced by get_input(), handle_button_template_req_message(), handle_open_receive_channel_ack_message(), handle_register_message(), handle_server_request_message(), handle_soft_key_set_req_message(), handle_soft_key_template_req_message(), handle_speed_dial_stat_req_message(), handle_time_date_req_message(), load_module(), req_alloc(), skinny_set_rtp_peer(), transmit_activatecallplane(), transmit_callinfo(), transmit_callstate(), transmit_callstateonly(), transmit_cfwdstate(), transmit_closereceivechannel(), transmit_connect(), transmit_dialednumber(), transmit_displaynotify(), transmit_displaypromptstatus(), transmit_lamp_indication(), transmit_ringer_mode(), transmit_selectsoftkeys(), transmit_speaker_mode(), transmit_stopmediatransmission(), and transmit_tone().
#define htoles | ( | x | ) | bswap_16(x) |
Definition at line 123 of file chan_skinny.c.
#define IP_PORT_MESSAGE 0x0002 |
#define KEEP_ALIVE_ACK_MESSAGE 0x0100 |
#define KEEP_ALIVE_MESSAGE 0x0000 |
#define KEYDEF_CONNECTED 1 |
Definition at line 542 of file chan_skinny.c.
Referenced by handle_hold_button(), handle_offhook_message(), handle_soft_key_event_message(), handle_stimulus_message(), and skinny_answer().
#define KEYDEF_CONNWITHCONF 7 |
Definition at line 548 of file chan_skinny.c.
#define KEYDEF_CONNWITHTRANS 5 |
Definition at line 546 of file chan_skinny.c.
#define KEYDEF_DADFD 6 |
Definition at line 547 of file chan_skinny.c.
#define KEYDEF_OFFHOOK 4 |
Definition at line 545 of file chan_skinny.c.
Referenced by handle_offhook_message(), handle_soft_key_event_message(), and handle_stimulus_message().
#define KEYDEF_OFFHOOKWITHFEAT 9 |
#define KEYDEF_ONHOLD 2 |
Definition at line 543 of file chan_skinny.c.
Referenced by handle_hold_button(), and handle_soft_key_event_message().
#define KEYDEF_ONHOOK 0 |
Definition at line 541 of file chan_skinny.c.
Referenced by handle_soft_key_set_req_message(), and transmit_callstate().
#define KEYDEF_RINGIN 3 |
#define KEYDEF_RINGOUT 8 |
Definition at line 549 of file chan_skinny.c.
Referenced by handle_callforward_button(), handle_soft_key_event_message(), and handle_stimulus_message().
#define KEYDEF_UNKNOWN 10 |
Definition at line 551 of file chan_skinny.c.
#define KEYPAD_BUTTON_MESSAGE 0x0003 |
#define letohl | ( | x | ) | bswap_32(x) |
Definition at line 120 of file chan_skinny.c.
Referenced by get_input(), handle_capabilities_res_message(), handle_keypad_button_message(), handle_line_state_req_message(), handle_message(), handle_offhook_message(), handle_onhook_message(), handle_open_receive_channel_ack_message(), handle_register_message(), handle_soft_key_event_message(), handle_speed_dial_stat_req_message(), handle_stimulus_message(), skinny_register(), skinny_req_parse(), and transmit_response().
#define letohs | ( | x | ) | bswap_16(x) |
Definition at line 121 of file chan_skinny.c.
#define LINE_STAT_RES_MESSAGE 0x0092 |
#define LINE_STATE_REQ_MESSAGE 0x000B |
#define OFFHOOK_MESSAGE 0x0006 |
#define ONHOOK_MESSAGE 0x0007 |
#define OPEN_RECEIVE_CHANNEL_ACK_MESSAGE 0x0022 |
#define OPEN_RECEIVE_CHANNEL_MESSAGE 0x0105 |
#define REGISTER_ACK_MESSAGE 0x0081 |
#define REGISTER_AVAILABLE_LINES_MESSAGE 0x002D |
#define REGISTER_MESSAGE 0x0001 |
#define REGISTER_REJ_MESSAGE 0x009D |
#define RESET_MESSAGE 0x009F |
#define SELECT_SOFT_KEYS_MESSAGE 0x0110 |
#define SERVER_REQUEST_MESSAGE 0x0012 |
#define SERVER_RES_MESSAGE 0x009E |
#define SET_LAMP_MESSAGE 0x0086 |
#define SET_MICROPHONE_MESSAGE 0x0089 |
Definition at line 325 of file chan_skinny.c.
#define SET_RINGER_MESSAGE 0x0085 |
#define SET_SPEAKER_MESSAGE 0x0088 |
#define SKINNY_ALERT 0x24 |
#define SKINNY_BUSY 6 |
#define SKINNY_BUSYTONE 0x23 |
#define SKINNY_CALLREMOTEMULTILINE 13 |
#define SKINNY_CALLWAIT 9 |
Definition at line 1050 of file chan_skinny.c.
#define SKINNY_CALLWAITTONE 0x2D |
#define SKINNY_CFWD_ALL (1 << 0) |
Definition at line 1076 of file chan_skinny.c.
Referenced by handle_skinny_show_line(), handle_soft_key_event_message(), handle_stimulus_message(), set_callforwards(), skinny_new(), and transmit_cfwdstate().
#define SKINNY_CFWD_BUSY (1 << 1) |
Definition at line 1077 of file chan_skinny.c.
Referenced by handle_skinny_show_line(), handle_soft_key_event_message(), handle_stimulus_message(), set_callforwards(), skinny_new(), and transmit_cfwdstate().
#define SKINNY_CFWD_NOANSWER (1 << 2) |
Definition at line 1078 of file chan_skinny.c.
Referenced by handle_skinny_show_line(), handle_soft_key_event_message(), handle_stimulus_message(), set_callforwards(), and transmit_cfwdstate().
#define SKINNY_CONGESTION 7 |
#define SKINNY_CONNECTED 5 |
Definition at line 1046 of file chan_skinny.c.
Referenced by handle_offhook_message(), handle_soft_key_event_message(), handle_stimulus_message(), skinny_answer(), and skinny_unhold().
#define SKINNY_CX_CONF 3 |
Definition at line 1087 of file chan_skinny.c.
#define SKINNY_CX_CONFERENCE 3 |
Definition at line 1088 of file chan_skinny.c.
#define SKINNY_CX_INACTIVE 4 |
#define SKINNY_CX_MUTE 4 |
Definition at line 1089 of file chan_skinny.c.
#define SKINNY_CX_RECVONLY 1 |
Definition at line 1085 of file chan_skinny.c.
Referenced by handle_onhook_message(), and handle_soft_key_event_message().
#define SKINNY_CX_SENDONLY 0 |
Definition at line 1084 of file chan_skinny.c.
#define SKINNY_CX_SENDRECV 2 |
#define SKINNY_DEVICE_12 4 |
Definition at line 1002 of file chan_skinny.c.
Referenced by device2str(), and get_button_template().
#define SKINNY_DEVICE_12SP 3 |
Definition at line 1001 of file chan_skinny.c.
Referenced by device2str(), and get_button_template().
#define SKINNY_DEVICE_12SPPLUS 2 |
Definition at line 1000 of file chan_skinny.c.
Referenced by device2str(), and get_button_template().
#define SKINNY_DEVICE_30SPPLUS 1 |
Definition at line 999 of file chan_skinny.c.
Referenced by device2str(), and get_button_template().
#define SKINNY_DEVICE_30VIP 5 |
Definition at line 1003 of file chan_skinny.c.
Referenced by device2str(), and get_button_template().
#define SKINNY_DEVICE_7902 30008 |
Definition at line 1029 of file chan_skinny.c.
Referenced by device2str(), and get_button_template().
#define SKINNY_DEVICE_7905 20000 |
Definition at line 1025 of file chan_skinny.c.
Referenced by device2str(), and get_button_template().
#define SKINNY_DEVICE_7906 369 |
Definition at line 1018 of file chan_skinny.c.
Referenced by device2str(), and get_button_template().
#define SKINNY_DEVICE_7910 6 |
Definition at line 1004 of file chan_skinny.c.
Referenced by device2str(), and get_button_template().
#define SKINNY_DEVICE_7911 307 |
Definition at line 1013 of file chan_skinny.c.
Referenced by device2str(), and get_button_template().
#define SKINNY_DEVICE_7912 30007 |
Definition at line 1028 of file chan_skinny.c.
Referenced by device2str(), and get_button_template().
#define SKINNY_DEVICE_7914 124 |
Definition at line 1011 of file chan_skinny.c.
Referenced by device2str(), and get_button_template().
#define SKINNY_DEVICE_7920 30002 |
Definition at line 1026 of file chan_skinny.c.
Referenced by device2str(), and get_button_template().
#define SKINNY_DEVICE_7921 365 |
Definition at line 1017 of file chan_skinny.c.
Referenced by device2str(), and get_button_template().
#define SKINNY_DEVICE_7931 348 |
Definition at line 1016 of file chan_skinny.c.
Referenced by device2str(), and get_button_template().
#define SKINNY_DEVICE_7935 9 |
Definition at line 1007 of file chan_skinny.c.
Referenced by device2str(), and get_button_template().
#define SKINNY_DEVICE_7936 30019 |
Definition at line 1032 of file chan_skinny.c.
Referenced by device2str(), and get_button_template().
#define SKINNY_DEVICE_7937 431 |
Definition at line 1020 of file chan_skinny.c.
Referenced by device2str(), and get_button_template().
#define SKINNY_DEVICE_7940 8 |
Definition at line 1006 of file chan_skinny.c.
Referenced by device2str(), and get_button_template().
#define SKINNY_DEVICE_7941 115 |
Definition at line 1009 of file chan_skinny.c.
Referenced by device2str(), and get_button_template().
#define SKINNY_DEVICE_7941GE 309 |
Definition at line 1015 of file chan_skinny.c.
Referenced by device2str(), and get_button_template().
#define SKINNY_DEVICE_7942 434 |
Definition at line 1021 of file chan_skinny.c.
Referenced by device2str(), and get_button_template().
#define SKINNY_DEVICE_7945 435 |
Definition at line 1022 of file chan_skinny.c.
Referenced by device2str(), and get_button_template().
#define SKINNY_DEVICE_7960 7 |
Definition at line 1005 of file chan_skinny.c.
Referenced by device2str(), and get_button_template().
#define SKINNY_DEVICE_7961 30018 |
Definition at line 1031 of file chan_skinny.c.
Referenced by device2str(), and get_button_template().
#define SKINNY_DEVICE_7961GE 308 |
Definition at line 1014 of file chan_skinny.c.
Referenced by device2str(), and get_button_template().
#define SKINNY_DEVICE_7962 404 |
Definition at line 1019 of file chan_skinny.c.
Referenced by device2str(), and get_button_template().
#define SKINNY_DEVICE_7965 436 |
Definition at line 1023 of file chan_skinny.c.
Referenced by device2str(), and get_button_template().
#define SKINNY_DEVICE_7970 30006 |
Definition at line 1027 of file chan_skinny.c.
Referenced by device2str(), and get_button_template().
#define SKINNY_DEVICE_7971 119 |
Definition at line 1010 of file chan_skinny.c.
Referenced by device2str(), and get_button_template().
#define SKINNY_DEVICE_7975 437 |
Definition at line 1024 of file chan_skinny.c.
Referenced by device2str(), and get_button_template().
#define SKINNY_DEVICE_7985 302 |
Definition at line 1012 of file chan_skinny.c.
Referenced by device2str(), and get_button_template().
#define SKINNY_DEVICE_ATA186 12 |
Definition at line 1008 of file chan_skinny.c.
Referenced by device2str(), and get_button_template().
#define SKINNY_DEVICE_CIPC 30016 |
Definition at line 1030 of file chan_skinny.c.
Referenced by device2str(), and get_button_template().
#define SKINNY_DEVICE_NONE 0 |
#define SKINNY_DEVICE_SCCPGATEWAY_AN 30027 |
Definition at line 1033 of file chan_skinny.c.
Referenced by device2str(), and get_button_template().
#define SKINNY_DEVICE_SCCPGATEWAY_BRI 30028 |
Definition at line 1034 of file chan_skinny.c.
Referenced by device2str(), and get_button_template().
#define SKINNY_DEVICE_UNKNOWN -1 |
#define SKINNY_DIALTONE 0x21 |
Definition at line 1058 of file chan_skinny.c.
Referenced by handle_callforward_button(), handle_enbloc_call_message(), handle_offhook_message(), handle_soft_key_event_message(), handle_stimulus_message(), handle_transfer_button(), and skinny_ss().
#define SKINNY_HOLD 8 |
Definition at line 1049 of file chan_skinny.c.
Referenced by skinny_extensionstate_cb(), and skinny_hold().
#define SKINNY_INVALID 14 |
Definition at line 1055 of file chan_skinny.c.
#define SKINNY_LAMP_BLINK 5 |
Definition at line 1069 of file chan_skinny.c.
Referenced by do_housekeeping(), skinny_call(), skinny_extensionstate_cb(), and skinny_hangup().
#define SKINNY_LAMP_FLASH 4 |
#define SKINNY_LAMP_OFF 1 |
Definition at line 1065 of file chan_skinny.c.
Referenced by do_housekeeping(), handle_soft_key_event_message(), handle_stimulus_message(), skinny_extensionstate_cb(), and skinny_hangup().
#define SKINNY_LAMP_ON 2 |
Definition at line 1066 of file chan_skinny.c.
Referenced by do_housekeeping(), handle_offhook_message(), handle_soft_key_event_message(), handle_stimulus_message(), skinny_extensionstate_cb(), skinny_hangup(), skinny_ss(), and skinny_unhold().
#define SKINNY_LAMP_WINK 3 |
Definition at line 1067 of file chan_skinny.c.
Referenced by skinny_extensionstate_cb(), and skinny_hold().
#define SKINNY_MAX_CAPABILITIES 18 |
#define SKINNY_MAX_PACKET 1000 |
Definition at line 94 of file chan_skinny.c.
Referenced by handle_register_message(), skinny_req_parse(), and transmit_response().
#define SKINNY_MICOFF 2 |
Definition at line 1040 of file chan_skinny.c.
#define SKINNY_MICON 1 |
Definition at line 1039 of file chan_skinny.c.
#define SKINNY_NOTONE 0x7F |
#define SKINNY_OFFHOOK 1 |
Definition at line 1042 of file chan_skinny.c.
Referenced by handle_callforward_button(), handle_enbloc_call_message(), handle_offhook_message(), handle_soft_key_event_message(), handle_stimulus_message(), handle_transfer_button(), skinny_call(), skinny_ss(), skinny_unhold(), and transmit_callstate().
#define SKINNY_ONHOOK 2 |
Definition at line 1043 of file chan_skinny.c.
Referenced by build_device(), get_devicestate(), handle_callforward_button(), handle_onhook_message(), handle_soft_key_event_message(), handle_stimulus_message(), skinny_call(), skinny_extensionstate_cb(), skinny_hangup(), and transmit_callstate().
#define SKINNY_PARK 11 |
Definition at line 1052 of file chan_skinny.c.
#define SKINNY_PROGRESS 12 |
#define SKINNY_REORDER 0x25 |
Definition at line 1061 of file chan_skinny.c.
Referenced by skinny_indicate(), skinny_newcall(), and skinny_ss().
#define SKINNY_RING_FEATURE 4 |
Definition at line 1074 of file chan_skinny.c.
#define SKINNY_RING_INSIDE 2 |
#define SKINNY_RING_OFF 1 |
Definition at line 1071 of file chan_skinny.c.
Referenced by handle_offhook_message(), handle_soft_key_event_message(), handle_stimulus_message(), and skinny_hangup().
#define SKINNY_RING_OUTSIDE 3 |
Definition at line 1073 of file chan_skinny.c.
#define SKINNY_RINGIN 4 |
Definition at line 1045 of file chan_skinny.c.
Referenced by skinny_call(), and skinny_extensionstate_cb().
#define SKINNY_RINGOUT 3 |
#define SKINNY_SILENCE 0x00 |
Definition at line 1057 of file chan_skinny.c.
Referenced by handle_enbloc_call_message(), handle_offhook_message(), handle_soft_key_event_message(), handle_stimulus_message(), skinny_answer(), skinny_hangup(), skinny_indicate(), and skinny_ss().
#define SKINNY_SPEAKEROFF 2 |
Definition at line 1037 of file chan_skinny.c.
Referenced by handle_callforward_button(), handle_soft_key_event_message(), handle_stimulus_message(), skinny_hangup(), and transmit_callstate().
#define SKINNY_SPEAKERON 1 |
Definition at line 1036 of file chan_skinny.c.
Referenced by handle_callforward_button(), handle_soft_key_event_message(), and handle_stimulus_message().
#define SKINNY_TRANSFER 10 |
Definition at line 1051 of file chan_skinny.c.
#define SOFT_KEY_EVENT_MESSAGE 0x0026 |
#define SOFT_KEY_SET_REQ_MESSAGE 0x0025 |
#define SOFT_KEY_SET_RES_MESSAGE 0x0109 |
#define SOFT_KEY_TEMPLATE_REQ_MESSAGE 0x0028 |
#define SOFT_KEY_TEMPLATE_RES_MESSAGE 0x0108 |
#define SOFTKEY_ANSWER 0x0B |
#define SOFTKEY_BKSPC 0x08 |
#define SOFTKEY_CFWDALL 0x05 |
#define SOFTKEY_CFWDBUSY 0x06 |
#define SOFTKEY_CFWDNOANSWER 0x07 |
#define SOFTKEY_CONFRN 0x0D |
#define SOFTKEY_DND 0x13 |
#define SOFTKEY_ENDCALL 0x09 |
#define SOFTKEY_GPICKUP 0x12 |
#define SOFTKEY_HOLD 0x03 |
#define SOFTKEY_IDIVERT 0x14 |
Definition at line 573 of file chan_skinny.c.
#define SOFTKEY_INFO 0x0C |
#define SOFTKEY_JOIN 0x0F |
#define SOFTKEY_MEETME 0x10 |
#define SOFTKEY_NEWCALL 0x02 |
#define SOFTKEY_NONE 0x00 |
#define SOFTKEY_PARK 0x0E |
#define SOFTKEY_PICKUP 0x11 |
#define SOFTKEY_REDIAL 0x01 |
#define SOFTKEY_RESUME 0x0A |
#define SOFTKEY_TRNSFER 0x04 |
#define SPEED_DIAL_STAT_REQ_MESSAGE 0x000A |
#define SPEED_DIAL_STAT_RES_MESSAGE 0x0091 |
#define START_MEDIA_TRANSMISSION_MESSAGE 0x008A |
Definition at line 330 of file chan_skinny.c.
Referenced by handle_open_receive_channel_ack_message(), and skinny_set_rtp_peer().
#define START_TONE_MESSAGE 0x0082 |
#define STIMULUS_AUTOANSWER 0x11 |
Definition at line 440 of file chan_skinny.c.
#define STIMULUS_CALLPARK 0x7E |
#define STIMULUS_CALLPICKUP 0x7F |
Definition at line 444 of file chan_skinny.c.
#define STIMULUS_CONFERENCE 0x7D |
#define STIMULUS_DISPLAY 0x08 |
#define STIMULUS_DND 0x3F |
Definition at line 441 of file chan_skinny.c.
Referenced by handle_soft_key_event_message(), and handle_stimulus_message().
#define STIMULUS_FORWARDALL 0x05 |
Definition at line 434 of file chan_skinny.c.
Referenced by handle_stimulus_message(), and skinny_ss().
#define STIMULUS_FORWARDBUSY 0x06 |
#define STIMULUS_FORWARDNOANSWER 0x07 |
#define STIMULUS_HOLD 0x03 |
#define STIMULUS_LINE 0x09 |
Definition at line 438 of file chan_skinny.c.
Referenced by handle_offhook_message(), handle_soft_key_event_message(), handle_stimulus_message(), skinny_call(), skinny_extensionstate_cb(), skinny_hangup(), skinny_hold(), and skinny_unhold().
#define STIMULUS_MESSAGE 0x0005 |
#define STIMULUS_NONE 0xFF |
Definition at line 445 of file chan_skinny.c.
#define STIMULUS_REDIAL 0x01 |
#define STIMULUS_SPEEDDIAL 0x02 |
#define STIMULUS_TRANSFER 0x04 |
#define STIMULUS_VOICEMAIL 0x0F |
Definition at line 439 of file chan_skinny.c.
Referenced by do_housekeeping(), and handle_stimulus_message().
#define STOP_MEDIA_TRANSMISSION_MESSAGE 0x008B |
Definition at line 349 of file chan_skinny.c.
Referenced by skinny_set_rtp_peer(), transmit_callstate(), and transmit_stopmediatransmission().
#define STOP_TONE_MESSAGE 0x0083 |
#define TIME_DATE_REQ_MESSAGE 0x000D |
#define TYPE_LINE 2 |
Definition at line 1081 of file chan_skinny.c.
#define TYPE_TRUNK 1 |
Definition at line 1080 of file chan_skinny.c.
#define UNREGISTER_MESSAGE 0x0027 |
#define VERSION_REQ_MESSAGE 0x000F |
#define VERSION_RES_MESSAGE 0x0098 |
enum skinny_codecs |
SKINNY_CODEC_ALAW | |
SKINNY_CODEC_ULAW | |
SKINNY_CODEC_G723_1 | |
SKINNY_CODEC_G729A | |
SKINNY_CODEC_G726_32 | |
SKINNY_CODEC_H261 | |
SKINNY_CODEC_H263 |
Definition at line 82 of file chan_skinny.c.
00082 { 00083 SKINNY_CODEC_ALAW = 2, 00084 SKINNY_CODEC_ULAW = 4, 00085 SKINNY_CODEC_G723_1 = 9, 00086 SKINNY_CODEC_G729A = 12, 00087 SKINNY_CODEC_G726_32 = 82, /* XXX Which packing order does this translate to? */ 00088 SKINNY_CODEC_H261 = 100, 00089 SKINNY_CODEC_H263 = 101 00090 };
static void __init_control2str_threadbuf | ( | void | ) | [static] |
static void __init_device2str_threadbuf | ( | void | ) | [static] |
static void __reg_module | ( | void | ) | [static] |
Definition at line 6486 of file chan_skinny.c.
static void __unreg_module | ( | void | ) | [static] |
Definition at line 6486 of file chan_skinny.c.
static void* accept_thread | ( | void * | ignore | ) | [static] |
Definition at line 6019 of file chan_skinny.c.
References ast_calloc, AST_LIST_INSERT_HEAD, AST_LIST_LOCK, AST_LIST_UNLOCK, ast_log(), ast_mutex_init(), ast_pthread_create_detached, ast_verb, destroy_session(), errno, LOG_NOTICE, LOG_WARNING, s, and skinny_session().
Referenced by reload_config().
06020 { 06021 int as; 06022 struct sockaddr_in sin; 06023 socklen_t sinlen; 06024 struct skinnysession *s; 06025 struct protoent *p; 06026 int arg = 1; 06027 pthread_t tcp_thread; 06028 06029 for (;;) { 06030 sinlen = sizeof(sin); 06031 as = accept(skinnysock, (struct sockaddr *)&sin, &sinlen); 06032 if (as < 0) { 06033 ast_log(LOG_NOTICE, "Accept returned -1: %s\n", strerror(errno)); 06034 continue; 06035 } 06036 p = getprotobyname("tcp"); 06037 if(p) { 06038 if( setsockopt(as, p->p_proto, TCP_NODELAY, (char *)&arg, sizeof(arg) ) < 0 ) { 06039 ast_log(LOG_WARNING, "Failed to set Skinny tcp connection to TCP_NODELAY mode: %s\n", strerror(errno)); 06040 } 06041 } 06042 if (!(s = ast_calloc(1, sizeof(struct skinnysession)))) 06043 continue; 06044 06045 memcpy(&s->sin, &sin, sizeof(sin)); 06046 ast_mutex_init(&s->lock); 06047 s->fd = as; 06048 AST_LIST_LOCK(&sessions); 06049 AST_LIST_INSERT_HEAD(&sessions, s, list); 06050 AST_LIST_UNLOCK(&sessions); 06051 06052 if (ast_pthread_create_detached(&tcp_thread, NULL, skinny_session, s)) { 06053 destroy_session(s); 06054 } 06055 } 06056 if (skinnydebug) 06057 ast_verb(1, "killing accept thread\n"); 06058 close(as); 06059 return 0; 06060 }
static struct ast_variable* add_var | ( | const char * | buf, | |
struct ast_variable * | list | |||
) | [static] |
implement the setvar config line
Definition at line 1526 of file chan_skinny.c.
References ast_strdupa, ast_variable_new(), skinny_subchannel::list, and ast_variable::next.
01527 { 01528 struct ast_variable *tmpvar = NULL; 01529 char *varname = ast_strdupa(buf), *varval = NULL; 01530 01531 if ((varval = strchr(varname,'='))) { 01532 *varval++ = '\0'; 01533 if ((tmpvar = ast_variable_new(varname, varval, ""))) { 01534 tmpvar->next = list; 01535 list = tmpvar; 01536 } 01537 } 01538 return list; 01539 }
static struct skinny_device* build_device | ( | const char * | cat, | |
struct ast_variable * | v | |||
) | [static] |
Definition at line 3009 of file chan_skinny.c.
References add_var(), ast_append_ha(), ast_callerid_split(), ast_calloc, ast_cdr_amaflags2int(), ast_copy_string(), AST_EVENT_IE_CONTEXT, AST_EVENT_IE_END, AST_EVENT_IE_MAILBOX, AST_EVENT_IE_NEWMSGS, AST_EVENT_IE_PLTYPE_EXISTS, AST_EVENT_IE_PLTYPE_STR, AST_EVENT_MWI, ast_event_subscribe(), ast_free, ast_get_group(), ast_get_ip(), AST_LIST_FIRST, AST_LIST_INSERT_HEAD, ast_log(), AST_MAX_EXTENSION, ast_mutex_init(), ast_parse_allow_disallow(), ast_strdupa, ast_strlen_zero(), ast_true(), ast_verb, buf, default_prefs, DEFAULT_SKINNY_PORT, ast_variable::lineno, LOG_ERROR, LOG_WARNING, mwi_event_cb(), ast_variable::name, ast_variable::next, S_OR, set_callforwards(), SKINNY_ONHOOK, strsep(), TYPE_LINE, TYPE_TRUNK, and ast_variable::value.
03010 { 03011 struct skinny_device *d; 03012 struct skinny_line *l; 03013 struct skinny_speeddial *sd; 03014 struct skinny_addon *a; 03015 char device_vmexten[AST_MAX_EXTENSION]; 03016 struct ast_variable *chanvars = NULL; 03017 int lineInstance = 1; 03018 int speeddialInstance = 1; 03019 int y = 0; 03020 03021 if (!(d = ast_calloc(1, sizeof(*d)))) { 03022 return NULL; 03023 } else { 03024 ast_copy_string(d->name, cat, sizeof(d->name)); 03025 d->lastlineinstance = 1; 03026 d->capability = default_capability; 03027 d->prefs = default_prefs; 03028 if (!ast_strlen_zero(vmexten)) 03029 ast_copy_string(device_vmexten, vmexten, sizeof(device_vmexten)); 03030 else 03031 memset(device_vmexten, 0, sizeof(device_vmexten)); 03032 03033 d->earlyrtp = 1; 03034 while(v) { 03035 if (!strcasecmp(v->name, "host")) { 03036 if (ast_get_ip(&d->addr, v->value)) { 03037 ast_free(d); 03038 return NULL; 03039 } 03040 } else if (!strcasecmp(v->name, "port")) { 03041 d->addr.sin_port = htons(atoi(v->value)); 03042 } else if (!strcasecmp(v->name, "device")) { 03043 ast_copy_string(d->id, v->value, sizeof(d->id)); 03044 } else if (!strcasecmp(v->name, "permit") || !strcasecmp(v->name, "deny")) { 03045 d->ha = ast_append_ha(v->name, v->value, d->ha, NULL); 03046 } else if (!strcasecmp(v->name, "vmexten")) { 03047 ast_copy_string(device_vmexten, v->value, sizeof(device_vmexten)); 03048 } else if (!strcasecmp(v->name, "context")) { 03049 ast_copy_string(global_context, v->value, sizeof(global_context)); 03050 } else if (!strcasecmp(v->name, "regexten")) { 03051 ast_copy_string(regexten, v->value, sizeof(regexten)); 03052 } else if (!strcasecmp(v->name, "allow")) { 03053 ast_parse_allow_disallow(&d->prefs, &d->capability, v->value, 1); 03054 } else if (!strcasecmp(v->name, "disallow")) { 03055 ast_parse_allow_disallow(&d->prefs, &d->capability, v->value, 0); 03056 } else if (!strcasecmp(v->name, "version")) { 03057 ast_copy_string(d->version_id, v->value, sizeof(d->version_id)); 03058 } else if (!strcasecmp(v->name, "canreinvite")) { 03059 canreinvite = ast_true(v->value); 03060 } else if (!strcasecmp(v->name, "earlyrtp")) { 03061 d->earlyrtp = ast_true(v->value); 03062 } else if (!strcasecmp(v->name, "nat")) { 03063 nat = ast_true(v->value); 03064 } else if (!strcasecmp(v->name, "callerid")) { 03065 if (!strcasecmp(v->value, "asreceived")) { 03066 cid_num[0] = '\0'; 03067 cid_name[0] = '\0'; 03068 } else { 03069 ast_callerid_split(v->value, cid_name, sizeof(cid_name), cid_num, sizeof(cid_num)); 03070 } 03071 } else if (!strcasecmp(v->name, "language")) { 03072 ast_copy_string(language, v->value, sizeof(language)); 03073 } else if (!strcasecmp(v->name, "accountcode")) { 03074 ast_copy_string(accountcode, v->value, sizeof(accountcode)); 03075 } else if (!strcasecmp(v->name, "amaflags")) { 03076 y = ast_cdr_amaflags2int(v->value); 03077 if (y < 0) { 03078 ast_log(LOG_WARNING, "Invalid AMA flags: %s at line %d\n", v->value, v->lineno); 03079 } else { 03080 amaflags = y; 03081 } 03082 } else if (!strcasecmp(v->name, "mohinterpret") || !strcasecmp(v->name, "musiconhold")) { 03083 ast_copy_string(mohinterpret, v->value, sizeof(mohinterpret)); 03084 } else if (!strcasecmp(v->name, "mohsuggest")) { 03085 ast_copy_string(mohsuggest, v->value, sizeof(mohsuggest)); 03086 } else if (!strcasecmp(v->name, "callgroup")) { 03087 cur_callergroup = ast_get_group(v->value); 03088 } else if (!strcasecmp(v->name, "pickupgroup")) { 03089 cur_pickupgroup = ast_get_group(v->value); 03090 } else if (!strcasecmp(v->name, "immediate")) { 03091 immediate = ast_true(v->value); 03092 } else if (!strcasecmp(v->name, "cancallforward")) { 03093 cancallforward = ast_true(v->value); 03094 } else if (!strcasecmp(v->name, "mailbox")) { 03095 ast_copy_string(mailbox, v->value, sizeof(mailbox)); 03096 } else if (!strcasecmp(v->name, "hasvoicemail")) { 03097 if (ast_true(v->value) && ast_strlen_zero(mailbox)) { 03098 ast_copy_string(mailbox, cat, sizeof(mailbox)); 03099 } 03100 } else if (!strcasecmp(v->name, "callreturn")) { 03101 callreturn = ast_true(v->value); 03102 } else if (!strcasecmp(v->name, "callwaiting")) { 03103 callwaiting = ast_true(v->value); 03104 } else if (!strcasecmp(v->name, "transfer")) { 03105 transfer = ast_true(v->value); 03106 } else if (!strcasecmp(v->name, "threewaycalling")) { 03107 threewaycalling = ast_true(v->value); 03108 } else if (!strcasecmp(v->name, "mwiblink")) { 03109 mwiblink = ast_true(v->value); 03110 } else if (!strcasecmp(v->name, "linelabel")) { 03111 ast_copy_string(linelabel, v->value, sizeof(linelabel)); 03112 } else if (!strcasecmp(v->name, "setvar")) { 03113 chanvars = add_var(v->value, chanvars); 03114 } else if ( !strcasecmp(v->name, "parkinglot")) { 03115 ast_copy_string(parkinglot, v->value, sizeof(parkinglot)); 03116 } else if (!strcasecmp(v->name, "speeddial")) { 03117 if (!(sd = ast_calloc(1, sizeof(*sd)))) { 03118 return NULL; 03119 } else { 03120 char buf[256]; 03121 char *stringp = buf, *exten, *context, *label; 03122 03123 ast_copy_string(buf, v->value, sizeof(buf)); 03124 exten = strsep(&stringp, ","); 03125 if ((context = strchr(exten, '@'))) { 03126 *context++ = '\0'; 03127 } 03128 label = stringp; 03129 ast_mutex_init(&sd->lock); 03130 ast_copy_string(sd->exten, exten, sizeof(sd->exten)); 03131 if (!ast_strlen_zero(context)) { 03132 sd->isHint = 1; 03133 sd->instance = lineInstance++; 03134 ast_copy_string(sd->context, context, sizeof(sd->context)); 03135 } else { 03136 sd->isHint = 0; 03137 sd->instance = speeddialInstance++; 03138 sd->context[0] = '\0'; 03139 } 03140 ast_copy_string(sd->label, S_OR(label, exten), sizeof(sd->label)); 03141 03142 sd->parent = d; 03143 03144 AST_LIST_INSERT_HEAD(&d->speeddials, sd, list); 03145 } 03146 } else if (!strcasecmp(v->name, "addon")) { 03147 if (!(a = ast_calloc(1, sizeof(*a)))) { 03148 return NULL; 03149 } else { 03150 ast_mutex_init(&a->lock); 03151 ast_copy_string(a->type, v->value, sizeof(a->type)); 03152 03153 AST_LIST_INSERT_HEAD(&d->addons, a, list); 03154 } 03155 } else if (!strcasecmp(v->name, "trunk") || !strcasecmp(v->name, "line")) { 03156 if (!(l = ast_calloc(1, sizeof(*l)))) { 03157 return NULL; 03158 } else { 03159 ast_mutex_init(&l->lock); 03160 ast_copy_string(l->name, v->value, sizeof(l->name)); 03161 03162 /* XXX Should we check for uniqueness?? XXX */ 03163 ast_copy_string(l->context, global_context, sizeof(l->context)); 03164 ast_copy_string(l->cid_num, cid_num, sizeof(l->cid_num)); 03165 ast_copy_string(l->cid_name, cid_name, sizeof(l->cid_name)); 03166 ast_copy_string(l->label, linelabel, sizeof(l->label)); 03167 ast_copy_string(l->parkinglot, parkinglot, sizeof(l->parkinglot)); 03168 ast_copy_string(l->language, language, sizeof(l->language)); 03169 ast_copy_string(l->mohinterpret, mohinterpret, sizeof(l->mohinterpret)); 03170 ast_copy_string(l->mohsuggest, mohsuggest, sizeof(l->mohsuggest)); 03171 ast_copy_string(l->regexten, regexten, sizeof(l->regexten)); 03172 ast_copy_string(l->mailbox, mailbox, sizeof(l->mailbox)); 03173 if (!ast_strlen_zero(mailbox)) { 03174 char *cfg_mailbox, *cfg_context; 03175 cfg_context = cfg_mailbox = ast_strdupa(l->mailbox); 03176 ast_verb(3, "Setting mailbox '%s' on %s@%s\n", cfg_mailbox, d->name, l->name); 03177 strsep(&cfg_context, "@"); 03178 if (ast_strlen_zero(cfg_context)) 03179 cfg_context = "default"; 03180 l->mwi_event_sub = ast_event_subscribe(AST_EVENT_MWI, mwi_event_cb, NULL, 03181 AST_EVENT_IE_MAILBOX, AST_EVENT_IE_PLTYPE_STR, cfg_mailbox, 03182 AST_EVENT_IE_CONTEXT, AST_EVENT_IE_PLTYPE_STR, cfg_context, 03183 AST_EVENT_IE_NEWMSGS, AST_EVENT_IE_PLTYPE_EXISTS, 03184 AST_EVENT_IE_END); 03185 } 03186 ast_copy_string(l->vmexten, device_vmexten, sizeof(vmexten)); 03187 l->chanvars = chanvars; 03188 l->msgstate = -1; 03189 l->capability = d->capability; 03190 l->prefs = d->prefs; 03191 l->parent = d; 03192 if (!strcasecmp(v->name, "trunk")) { 03193 l->type = TYPE_TRUNK; 03194 } else { 03195 l->type = TYPE_LINE; 03196 } 03197 l->immediate = immediate; 03198 l->callgroup = cur_callergroup; 03199 l->pickupgroup = cur_pickupgroup; 03200 l->callreturn = callreturn; 03201 l->cancallforward = cancallforward; 03202 l->getforward = 0; 03203 set_callforwards(l, NULL, 0); 03204 l->callwaiting = callwaiting; 03205 l->transfer = transfer; 03206 l->threewaycalling = threewaycalling; 03207 l->mwiblink = mwiblink; 03208 l->onhooktime = time(NULL); 03209 l->instance = lineInstance++; 03210 /* ASSUME we're onhook at this point */ 03211 l->hookstate = SKINNY_ONHOOK; 03212 l->nat = nat; 03213 l->canreinvite = canreinvite; 03214 03215 if (!AST_LIST_FIRST(&d->lines)) { 03216 d->activeline = l; 03217 } 03218 AST_LIST_INSERT_HEAD(&d->lines, l, list); 03219 } 03220 } else { 03221 ast_log(LOG_WARNING, "Don't know keyword '%s' at line %d\n", v->name, v->lineno); 03222 } 03223 v = v->next; 03224 } 03225 03226 if (!AST_LIST_FIRST(&d->lines)) { 03227 ast_log(LOG_ERROR, "A Skinny device must have at least one line!\n"); 03228 return NULL; 03229 } 03230 if (/*d->addr.sin_addr.s_addr && */!ntohs(d->addr.sin_port)) { 03231 d->addr.sin_port = htons(DEFAULT_SKINNY_PORT); 03232 } 03233 } 03234 return d; 03235 }
static void cleanup_stale_contexts | ( | char * | new, | |
char * | old | |||
) | [static] |
Definition at line 1687 of file chan_skinny.c.
References ast_context_destroy(), ast_context_find(), ast_copy_string(), AST_MAX_CONTEXT, and strsep().
01688 { 01689 char *oldcontext, *newcontext, *stalecontext, *stringp, newlist[AST_MAX_CONTEXT]; 01690 01691 while ((oldcontext = strsep(&old, "&"))) { 01692 stalecontext = '\0'; 01693 ast_copy_string(newlist, new, sizeof(newlist)); 01694 stringp = newlist; 01695 while ((newcontext = strsep(&stringp, "&"))) { 01696 if (strcmp(newcontext, oldcontext) == 0) { 01697 /* This is not the context you're looking for */ 01698 stalecontext = '\0'; 01699 break; 01700 } else if (strcmp(newcontext, oldcontext)) { 01701 stalecontext = oldcontext; 01702 } 01703 01704 } 01705 if (stalecontext) 01706 ast_context_destroy(ast_context_find(stalecontext), "Skinny"); 01707 } 01708 }
static int codec_ast2skinny | ( | int | astcodec | ) | [static] |
Definition at line 1630 of file chan_skinny.c.
References AST_FORMAT_ALAW, AST_FORMAT_G723_1, AST_FORMAT_G726_AAL2, AST_FORMAT_G729A, AST_FORMAT_H261, AST_FORMAT_H263, AST_FORMAT_ULAW, SKINNY_CODEC_ALAW, SKINNY_CODEC_G723_1, SKINNY_CODEC_G726_32, SKINNY_CODEC_G729A, SKINNY_CODEC_H261, SKINNY_CODEC_H263, and SKINNY_CODEC_ULAW.
Referenced by handle_open_receive_channel_ack_message(), skinny_set_rtp_peer(), and transmit_connect().
01631 { 01632 switch (astcodec) { 01633 case AST_FORMAT_ALAW: 01634 return SKINNY_CODEC_ALAW; 01635 case AST_FORMAT_ULAW: 01636 return SKINNY_CODEC_ULAW; 01637 case AST_FORMAT_G723_1: 01638 return SKINNY_CODEC_G723_1; 01639 case AST_FORMAT_G729A: 01640 return SKINNY_CODEC_G729A; 01641 case AST_FORMAT_G726_AAL2: /* XXX Is this right? */ 01642 return SKINNY_CODEC_G726_32; 01643 case AST_FORMAT_H261: 01644 return SKINNY_CODEC_H261; 01645 case AST_FORMAT_H263: 01646 return SKINNY_CODEC_H263; 01647 default: 01648 return 0; 01649 } 01650 }
static int codec_skinny2ast | ( | enum skinny_codecs | skinnycodec | ) | [static] |
Definition at line 1608 of file chan_skinny.c.
References AST_FORMAT_ALAW, AST_FORMAT_G723_1, AST_FORMAT_G726_AAL2, AST_FORMAT_G729A, AST_FORMAT_H261, AST_FORMAT_H263, AST_FORMAT_ULAW, SKINNY_CODEC_ALAW, SKINNY_CODEC_G723_1, SKINNY_CODEC_G726_32, SKINNY_CODEC_G729A, SKINNY_CODEC_H261, SKINNY_CODEC_H263, and SKINNY_CODEC_ULAW.
Referenced by handle_capabilities_res_message().
01609 { 01610 switch (skinnycodec) { 01611 case SKINNY_CODEC_ALAW: 01612 return AST_FORMAT_ALAW; 01613 case SKINNY_CODEC_ULAW: 01614 return AST_FORMAT_ULAW; 01615 case SKINNY_CODEC_G723_1: 01616 return AST_FORMAT_G723_1; 01617 case SKINNY_CODEC_G729A: 01618 return AST_FORMAT_G729A; 01619 case SKINNY_CODEC_G726_32: 01620 return AST_FORMAT_G726_AAL2; /* XXX Is this right? */ 01621 case SKINNY_CODEC_H261: 01622 return AST_FORMAT_H261; 01623 case SKINNY_CODEC_H263: 01624 return AST_FORMAT_H263; 01625 default: 01626 return 0; 01627 } 01628 }
static char* complete_skinny_devices | ( | const char * | word, | |
int | state | |||
) | [static] |
Definition at line 2551 of file chan_skinny.c.
References AST_LIST_TRAVERSE, ast_strdup, and skinny_device::id.
Referenced by complete_skinny_reset(), and complete_skinny_show_device().
02552 { 02553 struct skinny_device *d; 02554 char *result = NULL; 02555 int wordlen = strlen(word), which = 0; 02556 02557 AST_LIST_TRAVERSE(&devices, d, list) { 02558 if (!strncasecmp(word, d->id, wordlen) && ++which > state) 02559 result = ast_strdup(d->id); 02560 } 02561 02562 return result; 02563 }
static char* complete_skinny_reset | ( | const char * | line, | |
const char * | word, | |||
int | pos, | |||
int | state | |||
) | [static] |
Definition at line 2570 of file chan_skinny.c.
References ast_strdup, and complete_skinny_devices().
Referenced by handle_skinny_reset().
02571 { 02572 return (pos == 2 ? ast_strdup(complete_skinny_devices(word, state)) : NULL); 02573 }
static char* complete_skinny_show_device | ( | const char * | line, | |
const char * | word, | |||
int | pos, | |||
int | state | |||
) | [static] |
Definition at line 2565 of file chan_skinny.c.
References ast_strdup, and complete_skinny_devices().
Referenced by handle_skinny_show_device().
02566 { 02567 return (pos == 3 ? ast_strdup(complete_skinny_devices(word, state)) : NULL); 02568 }
static char* complete_skinny_show_line | ( | const char * | line, | |
const char * | word, | |||
int | pos, | |||
int | state | |||
) | [static] |
Definition at line 2575 of file chan_skinny.c.
References AST_LIST_TRAVERSE, ast_strdup, skinny_device::lines, and skinny_line::name.
Referenced by handle_skinny_show_line().
02576 { 02577 struct skinny_device *d; 02578 struct skinny_line *l; 02579 char *result = NULL; 02580 int wordlen = strlen(word), which = 0; 02581 02582 if (pos != 3) 02583 return NULL; 02584 02585 AST_LIST_TRAVERSE(&devices, d, list) { 02586 AST_LIST_TRAVERSE(&d->lines, l, list) { 02587 if (!strncasecmp(word, l->name, wordlen) && ++which > state) 02588 result = ast_strdup(l->name); 02589 } 02590 } 02591 02592 return result; 02593 }
static char* control2str | ( | int | ind | ) | [static] |
Definition at line 3718 of file chan_skinny.c.
References AST_CONTROL_ANSWER, AST_CONTROL_BUSY, AST_CONTROL_CONGESTION, AST_CONTROL_FLASH, AST_CONTROL_HANGUP, AST_CONTROL_HOLD, AST_CONTROL_OFFHOOK, AST_CONTROL_OPTION, AST_CONTROL_PROCEEDING, AST_CONTROL_PROGRESS, AST_CONTROL_RADIO_KEY, AST_CONTROL_RADIO_UNKEY, AST_CONTROL_RING, AST_CONTROL_RINGING, AST_CONTROL_TAKEOFFHOOK, AST_CONTROL_UNHOLD, AST_CONTROL_WINK, ast_threadstorage_get(), CONTROL2STR_BUFSIZE, and control2str_threadbuf.
03718 { 03719 char *tmp; 03720 03721 switch (ind) { 03722 case AST_CONTROL_HANGUP: 03723 return "Other end has hungup"; 03724 case AST_CONTROL_RING: 03725 return "Local ring"; 03726 case AST_CONTROL_RINGING: 03727 return "Remote end is ringing"; 03728 case AST_CONTROL_ANSWER: 03729 return "Remote end has answered"; 03730 case AST_CONTROL_BUSY: 03731 return "Remote end is busy"; 03732 case AST_CONTROL_TAKEOFFHOOK: 03733 return "Make it go off hook"; 03734 case AST_CONTROL_OFFHOOK: 03735 return "Line is off hook"; 03736 case AST_CONTROL_CONGESTION: 03737 return "Congestion (circuits busy)"; 03738 case AST_CONTROL_FLASH: 03739 return "Flash hook"; 03740 case AST_CONTROL_WINK: 03741 return "Wink"; 03742 case AST_CONTROL_OPTION: 03743 return "Set a low-level option"; 03744 case AST_CONTROL_RADIO_KEY: 03745 return "Key Radio"; 03746 case AST_CONTROL_RADIO_UNKEY: 03747 return "Un-Key Radio"; 03748 case AST_CONTROL_PROGRESS: 03749 return "Remote end is making Progress"; 03750 case AST_CONTROL_PROCEEDING: 03751 return "Remote end is proceeding"; 03752 case AST_CONTROL_HOLD: 03753 return "Hold"; 03754 case AST_CONTROL_UNHOLD: 03755 return "Unhold"; 03756 case -1: 03757 return "Stop tone"; 03758 default: 03759 if (!(tmp = ast_threadstorage_get(&control2str_threadbuf, CONTROL2STR_BUFSIZE))) 03760 return "Unknown"; 03761 snprintf(tmp, CONTROL2STR_BUFSIZE, "UNKNOWN-%d", ind); 03762 return tmp; 03763 } 03764 }
static void delete_devices | ( | void | ) | [static] |
Definition at line 6339 of file chan_skinny.c.
References skinny_device::addons, AST_LIST_LOCK, AST_LIST_REMOVE_HEAD, AST_LIST_UNLOCK, free, skinny_device::lines, and skinny_device::speeddials.
Referenced by unload_module().
06340 { 06341 struct skinny_device *d; 06342 struct skinny_line *l; 06343 struct skinny_speeddial *sd; 06344 struct skinny_addon *a; 06345 06346 AST_LIST_LOCK(&devices); 06347 06348 /* Delete all devices */ 06349 while ((d = AST_LIST_REMOVE_HEAD(&devices, list))) { 06350 /* Delete all lines for this device */ 06351 while ((l = AST_LIST_REMOVE_HEAD(&d->lines, list))) { 06352 free(l); 06353 } 06354 /* Delete all speeddials for this device */ 06355 while ((sd = AST_LIST_REMOVE_HEAD(&d->speeddials, list))) { 06356 free(sd); 06357 } 06358 /* Delete all addons for this device */ 06359 while ((a = AST_LIST_REMOVE_HEAD(&d->addons, list))) { 06360 free(a); 06361 } 06362 free(d); 06363 } 06364 AST_LIST_UNLOCK(&devices); 06365 }
static void destroy_session | ( | struct skinnysession * | s | ) | [static] |
Definition at line 5865 of file chan_skinny.c.
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(), LOG_WARNING, and s.
05866 { 05867 struct skinnysession *cur; 05868 AST_LIST_LOCK(&sessions); 05869 AST_LIST_TRAVERSE_SAFE_BEGIN(&sessions, cur, list) { 05870 if (cur == s) { 05871 AST_LIST_REMOVE_CURRENT(list); 05872 if (s->fd > -1) 05873 close(s->fd); 05874 05875 ast_mutex_destroy(&s->lock); 05876 05877 ast_free(s); 05878 } else { 05879 ast_log(LOG_WARNING, "Trying to delete nonexistent session %p?\n", s); 05880 } 05881 } 05882 AST_LIST_TRAVERSE_SAFE_END 05883 AST_LIST_UNLOCK(&sessions); 05884 }
static char* device2str | ( | int | type | ) | [static] |
Definition at line 2640 of file chan_skinny.c.
References ast_threadstorage_get(), DEVICE2STR_BUFSIZE, device2str_threadbuf, SKINNY_DEVICE_12, SKINNY_DEVICE_12SP, SKINNY_DEVICE_12SPPLUS, SKINNY_DEVICE_30SPPLUS, SKINNY_DEVICE_30VIP, SKINNY_DEVICE_7902, SKINNY_DEVICE_7905, SKINNY_DEVICE_7906, SKINNY_DEVICE_7910, SKINNY_DEVICE_7911, SKINNY_DEVICE_7912, SKINNY_DEVICE_7914, SKINNY_DEVICE_7920, SKINNY_DEVICE_7921, SKINNY_DEVICE_7931, SKINNY_DEVICE_7935, SKINNY_DEVICE_7936, SKINNY_DEVICE_7937, SKINNY_DEVICE_7940, SKINNY_DEVICE_7941, SKINNY_DEVICE_7941GE, SKINNY_DEVICE_7942, SKINNY_DEVICE_7945, SKINNY_DEVICE_7960, SKINNY_DEVICE_7961, SKINNY_DEVICE_7961GE, SKINNY_DEVICE_7962, SKINNY_DEVICE_7965, SKINNY_DEVICE_7970, SKINNY_DEVICE_7971, SKINNY_DEVICE_7975, SKINNY_DEVICE_7985, SKINNY_DEVICE_ATA186, SKINNY_DEVICE_CIPC, SKINNY_DEVICE_NONE, SKINNY_DEVICE_SCCPGATEWAY_AN, SKINNY_DEVICE_SCCPGATEWAY_BRI, and SKINNY_DEVICE_UNKNOWN.
Referenced by handle_skinny_show_device(), and handle_skinny_show_devices().
02641 { 02642 char *tmp; 02643 02644 switch (type) { 02645 case SKINNY_DEVICE_NONE: 02646 return "No Device"; 02647 case SKINNY_DEVICE_30SPPLUS: 02648 return "30SP Plus"; 02649 case SKINNY_DEVICE_12SPPLUS: 02650 return "12SP Plus"; 02651 case SKINNY_DEVICE_12SP: 02652 return "12SP"; 02653 case SKINNY_DEVICE_12: 02654 return "12"; 02655 case SKINNY_DEVICE_30VIP: 02656 return "30VIP"; 02657 case SKINNY_DEVICE_7910: 02658 return "7910"; 02659 case SKINNY_DEVICE_7960: 02660 return "7960"; 02661 case SKINNY_DEVICE_7940: 02662 return "7940"; 02663 case SKINNY_DEVICE_7935: 02664 return "7935"; 02665 case SKINNY_DEVICE_ATA186: 02666 return "ATA186"; 02667 case SKINNY_DEVICE_7941: 02668 return "7941"; 02669 case SKINNY_DEVICE_7971: 02670 return "7971"; 02671 case SKINNY_DEVICE_7914: 02672 return "7914"; 02673 case SKINNY_DEVICE_7985: 02674 return "7985"; 02675 case SKINNY_DEVICE_7911: 02676 return "7911"; 02677 case SKINNY_DEVICE_7961GE: 02678 return "7961GE"; 02679 case SKINNY_DEVICE_7941GE: 02680 return "7941GE"; 02681 case SKINNY_DEVICE_7931: 02682 return "7931"; 02683 case SKINNY_DEVICE_7921: 02684 return "7921"; 02685 case SKINNY_DEVICE_7906: 02686 return "7906"; 02687 case SKINNY_DEVICE_7962: 02688 return "7962"; 02689 case SKINNY_DEVICE_7937: 02690 return "7937"; 02691 case SKINNY_DEVICE_7942: 02692 return "7942"; 02693 case SKINNY_DEVICE_7945: 02694 return "7945"; 02695 case SKINNY_DEVICE_7965: 02696 return "7965"; 02697 case SKINNY_DEVICE_7975: 02698 return "7975"; 02699 case SKINNY_DEVICE_7905: 02700 return "7905"; 02701 case SKINNY_DEVICE_7920: 02702 return "7920"; 02703 case SKINNY_DEVICE_7970: 02704 return "7970"; 02705 case SKINNY_DEVICE_7912: 02706 return "7912"; 02707 case SKINNY_DEVICE_7902: 02708 return "7902"; 02709 case SKINNY_DEVICE_CIPC: 02710 return "IP Communicator"; 02711 case SKINNY_DEVICE_7961: 02712 return "7961"; 02713 case SKINNY_DEVICE_7936: 02714 return "7936"; 02715 case SKINNY_DEVICE_SCCPGATEWAY_AN: 02716 return "SCCPGATEWAY_AN"; 02717 case SKINNY_DEVICE_SCCPGATEWAY_BRI: 02718 return "SCCPGATEWAY_BRI"; 02719 case SKINNY_DEVICE_UNKNOWN: 02720 return "Unknown"; 02721 default: 02722 if (!(tmp = ast_threadstorage_get(&device2str_threadbuf, DEVICE2STR_BUFSIZE))) 02723 return "Unknown"; 02724 snprintf(tmp, DEVICE2STR_BUFSIZE, "UNKNOWN-%d", type); 02725 return tmp; 02726 } 02727 }
static void do_housekeeping | ( | struct skinnysession * | s | ) | [static] |
Definition at line 2336 of file chan_skinny.c.
References AST_LIST_TRAVERSE, ast_verb, handle_time_date_req_message(), has_voicemail(), skinny_line::instance, skinny_device::lines, skinny_line::mwiblink, skinny_device::name, skinny_line::name, s, SKINNY_LAMP_BLINK, SKINNY_LAMP_OFF, SKINNY_LAMP_ON, STIMULUS_VOICEMAIL, and transmit_lamp_indication().
Referenced by handle_keep_alive_message(), handle_onhook_message(), and handle_soft_key_event_message().
02337 { 02338 int device_lamp = 0; 02339 struct skinny_device *d = s->device; 02340 struct skinny_line *l; 02341 02342 /* Update time on device */ 02343 handle_time_date_req_message(NULL, s); 02344 02345 /* Set MWI on individual lines */ 02346 AST_LIST_TRAVERSE(&d->lines, l, list) { 02347 if (has_voicemail(l)) { 02348 if (skinnydebug) 02349 ast_verb(1, "Checking for voicemail Skinny %s@%s\n", l->name, d->name); 02350 if (skinnydebug) 02351 ast_verb(1, "Skinny %s@%s has voicemail!\n", l->name, d->name); 02352 transmit_lamp_indication(d, STIMULUS_VOICEMAIL, l->instance, l->mwiblink?SKINNY_LAMP_BLINK:SKINNY_LAMP_ON); 02353 device_lamp++; 02354 } else { 02355 transmit_lamp_indication(d, STIMULUS_VOICEMAIL, l->instance, SKINNY_LAMP_OFF); 02356 } 02357 } 02358 /* If at least one line has VM, turn the device level lamp on */ 02359 if (device_lamp) 02360 transmit_lamp_indication(d, STIMULUS_VOICEMAIL, 0, SKINNY_LAMP_ON); 02361 else 02362 transmit_lamp_indication(d, STIMULUS_VOICEMAIL, 0, SKINNY_LAMP_OFF); 02363 }
static void* do_monitor | ( | void * | data | ) | [static] |
Definition at line 6062 of file chan_skinny.c.
References ast_io_wait(), ast_mutex_lock(), ast_mutex_unlock(), ast_sched_runq(), ast_sched_wait(), io, monlock, and sched.
06063 { 06064 int res; 06065 06066 /* This thread monitors all the interfaces which are not yet in use 06067 (and thus do not have a separate thread) indefinitely */ 06068 /* From here on out, we die whenever asked */ 06069 for(;;) { 06070 pthread_testcancel(); 06071 /* Wait for sched or io */ 06072 res = ast_sched_wait(sched); 06073 if ((res < 0) || (res > 1000)) { 06074 res = 1000; 06075 } 06076 res = ast_io_wait(io, res); 06077 ast_mutex_lock(&monlock); 06078 if (res >= 0) { 06079 ast_sched_runq(sched); 06080 } 06081 ast_mutex_unlock(&monlock); 06082 } 06083 /* Never reached */ 06084 return NULL; 06085 06086 }
static struct skinny_line* find_line_by_instance | ( | struct skinny_device * | d, | |
int | instance | |||
) | [static] |
Definition at line 1454 of file chan_skinny.c.
References AST_LIST_TRAVERSE, ast_log(), skinny_line::instance, skinny_device::lines, LOG_WARNING, and skinny_device::name.
Referenced by find_subchannel_by_instance_reference(), handle_enbloc_call_message(), handle_line_state_req_message(), handle_offhook_message(), handle_soft_key_event_message(), and handle_stimulus_message().
01455 { 01456 struct skinny_line *l; 01457 01458 /*Dialing from on hook or on a 7920 uses instance 0 in requests 01459 but we need to start looking at instance 1 */ 01460 01461 if (!instance) 01462 instance = 1; 01463 01464 AST_LIST_TRAVERSE(&d->lines, l, list){ 01465 if (l->instance == instance) 01466 break; 01467 } 01468 01469 if (!l) { 01470 ast_log(LOG_WARNING, "Could not find line with instance '%d' on device '%s'\n", instance, d->name); 01471 } 01472 return l; 01473 }
static struct skinny_line* find_line_by_name | ( | const char * | dest | ) | [static] |
Definition at line 1475 of file chan_skinny.c.
References ast_copy_string(), AST_LIST_LOCK, AST_LIST_TRAVERSE, AST_LIST_UNLOCK, ast_strlen_zero(), ast_verb, skinny_device::lines, skinny_line::name, and skinny_device::name.
Referenced by skinny_devicestate(), and skinny_request().
01476 { 01477 struct skinny_line *l; 01478 struct skinny_line *tmpl = NULL; 01479 struct skinny_device *d; 01480 char line[256]; 01481 char *at; 01482 char *device; 01483 int checkdevice = 0; 01484 01485 ast_copy_string(line, dest, sizeof(line)); 01486 at = strchr(line, '@'); 01487 if (at) 01488 *at++ = '\0'; 01489 device = at; 01490 01491 if (!ast_strlen_zero(device)) 01492 checkdevice = 1; 01493 01494 AST_LIST_LOCK(&devices); 01495 AST_LIST_TRAVERSE(&devices, d, list){ 01496 if (checkdevice && tmpl) 01497 break; 01498 else if (!checkdevice) { 01499 /* This is a match, since we're checking for line on every device. */ 01500 } else if (!strcasecmp(d->name, device)) { 01501 if (skinnydebug) 01502 ast_verb(2, "Found device: %s\n", d->name); 01503 } else 01504 continue; 01505 01506 /* Found the device (or we don't care which device) */ 01507 AST_LIST_TRAVERSE(&d->lines, l, list){ 01508 /* Search for the right line */ 01509 if (!strcasecmp(l->name, line)) { 01510 if (tmpl) { 01511 ast_verb(2, "Ambiguous line name: %s\n", line); 01512 AST_LIST_UNLOCK(&devices); 01513 return NULL; 01514 } else 01515 tmpl = l; 01516 } 01517 } 01518 } 01519 AST_LIST_UNLOCK(&devices); 01520 return tmpl; 01521 }
static struct skinny_speeddial* find_speeddial_by_instance | ( | struct skinny_device * | d, | |
int | instance, | |||
int | isHint | |||
) | [static] |
Definition at line 1593 of file chan_skinny.c.
References AST_LIST_TRAVERSE, ast_log(), skinny_speeddial::instance, skinny_speeddial::isHint, LOG_WARNING, skinny_device::name, and skinny_device::speeddials.
Referenced by handle_line_state_req_message(), handle_speed_dial_stat_req_message(), and handle_stimulus_message().
01594 { 01595 struct skinny_speeddial *sd; 01596 01597 AST_LIST_TRAVERSE(&d->speeddials, sd, list) { 01598 if (sd->isHint == isHint && sd->instance == instance) 01599 break; 01600 } 01601 01602 if (!sd) { 01603 ast_log(LOG_WARNING, "Could not find speeddial with instance '%d' on device '%s'\n", instance, d->name); 01604 } 01605 return sd; 01606 }
static struct skinny_subchannel* find_subchannel_by_instance_reference | ( | struct skinny_device * | d, | |
int | instance, | |||
int | reference | |||
) | [static] |
Definition at line 1542 of file chan_skinny.c.
References AST_LIST_FIRST, AST_LIST_TRAVERSE, ast_log(), skinny_subchannel::callid, find_line_by_instance(), LOG_WARNING, skinny_device::name, and skinny_line::sub.
Referenced by handle_enbloc_call_message(), handle_keypad_button_message(), handle_message(), handle_offhook_message(), handle_onhook_message(), handle_soft_key_event_message(), and handle_stimulus_message().
01543 { 01544 struct skinny_line *l = find_line_by_instance(d, instance); 01545 struct skinny_subchannel *sub; 01546 01547 if (!l) { 01548 return NULL; 01549 } 01550 01551 /* 7920 phones set call reference to 0, so use the first 01552 sub-channel on the list. 01553 This MIGHT need more love to be right */ 01554 if (!reference) 01555 sub = AST_LIST_FIRST(&l->sub); 01556 else { 01557 AST_LIST_TRAVERSE(&l->sub, sub, list) { 01558 if (sub->callid == reference) 01559 break; 01560 } 01561 } 01562 if (!sub) { 01563 ast_log(LOG_WARNING, "Could not find subchannel with reference '%d' on '%s'\n", reference, d->name); 01564 } 01565 return sub; 01566 }
static struct skinny_subchannel* find_subchannel_by_reference | ( | struct skinny_device * | d, | |
int | reference | |||
) | [static] |
Definition at line 1569 of file chan_skinny.c.
References AST_LIST_TRAVERSE, ast_log(), skinny_subchannel::callid, skinny_device::lines, LOG_WARNING, skinny_line::name, skinny_device::name, and skinny_line::sub.
Referenced by handle_open_receive_channel_ack_message().
01570 { 01571 struct skinny_line *l; 01572 struct skinny_subchannel *sub = NULL; 01573 01574 AST_LIST_TRAVERSE(&d->lines, l, list){ 01575 AST_LIST_TRAVERSE(&l->sub, sub, list){ 01576 if (sub->callid == reference) 01577 break; 01578 } 01579 if (sub) 01580 break; 01581 } 01582 01583 if (!l) { 01584 ast_log(LOG_WARNING, "Could not find any lines that contained a subchannel with reference '%d' on device '%s'\n", reference, d->name); 01585 } else { 01586 if (!sub) { 01587 ast_log(LOG_WARNING, "Could not find subchannel with reference '%d' on '%s@%s'\n", reference, l->name, d->name); 01588 } 01589 } 01590 return sub; 01591 }
static void* get_button_template | ( | struct skinnysession * | s, | |
struct button_definition_template * | btn | |||
) | [static] |
Definition at line 1303 of file chan_skinny.c.
References skinny_device::addons, AST_LIST_LOCK, AST_LIST_TRAVERSE, AST_LIST_UNLOCK, ast_log(), BT_CALLPARK, BT_CONFERENCE, BT_CUST_LINE, BT_CUST_LINESPEEDDIAL, BT_DISPLAY, BT_FORWARDALL, BT_HOLD, BT_LINE, BT_NONE, BT_REDIAL, BT_SPEEDDIAL, BT_TRANSFER, BT_VOICEMAIL, LOG_WARNING, s, SKINNY_DEVICE_12, SKINNY_DEVICE_12SP, SKINNY_DEVICE_12SPPLUS, SKINNY_DEVICE_30SPPLUS, SKINNY_DEVICE_30VIP, SKINNY_DEVICE_7902, SKINNY_DEVICE_7905, SKINNY_DEVICE_7906, SKINNY_DEVICE_7910, SKINNY_DEVICE_7911, SKINNY_DEVICE_7912, SKINNY_DEVICE_7914, SKINNY_DEVICE_7920, SKINNY_DEVICE_7921, SKINNY_DEVICE_7931, SKINNY_DEVICE_7935, SKINNY_DEVICE_7936, SKINNY_DEVICE_7937, SKINNY_DEVICE_7940, SKINNY_DEVICE_7941, SKINNY_DEVICE_7941GE, SKINNY_DEVICE_7942, SKINNY_DEVICE_7945, SKINNY_DEVICE_7960, SKINNY_DEVICE_7961, SKINNY_DEVICE_7961GE, SKINNY_DEVICE_7962, SKINNY_DEVICE_7965, SKINNY_DEVICE_7970, SKINNY_DEVICE_7971, SKINNY_DEVICE_7975, SKINNY_DEVICE_7985, SKINNY_DEVICE_ATA186, SKINNY_DEVICE_CIPC, SKINNY_DEVICE_SCCPGATEWAY_AN, SKINNY_DEVICE_SCCPGATEWAY_BRI, skinny_addon::type, and skinny_device::type.
Referenced by handle_button_template_req_message().
01304 { 01305 struct skinny_device *d = s->device; 01306 struct skinny_addon *a; 01307 int i; 01308 01309 switch (d->type) { 01310 case SKINNY_DEVICE_30SPPLUS: 01311 case SKINNY_DEVICE_30VIP: 01312 /* 13 rows, 2 columns */ 01313 for (i = 0; i < 4; i++) 01314 (btn++)->buttonDefinition = BT_CUST_LINE; 01315 (btn++)->buttonDefinition = BT_REDIAL; 01316 (btn++)->buttonDefinition = BT_VOICEMAIL; 01317 (btn++)->buttonDefinition = BT_CALLPARK; 01318 (btn++)->buttonDefinition = BT_FORWARDALL; 01319 (btn++)->buttonDefinition = BT_CONFERENCE; 01320 for (i = 0; i < 4; i++) 01321 (btn++)->buttonDefinition = BT_NONE; 01322 for (i = 0; i < 13; i++) 01323 (btn++)->buttonDefinition = BT_SPEEDDIAL; 01324 01325 break; 01326 case SKINNY_DEVICE_12SPPLUS: 01327 case SKINNY_DEVICE_12SP: 01328 case SKINNY_DEVICE_12: 01329 /* 6 rows, 2 columns */ 01330 for (i = 0; i < 2; i++) 01331 (btn++)->buttonDefinition = BT_CUST_LINE; 01332 for (i = 0; i < 4; i++) 01333 (btn++)->buttonDefinition = BT_SPEEDDIAL; 01334 (btn++)->buttonDefinition = BT_HOLD; 01335 (btn++)->buttonDefinition = BT_REDIAL; 01336 (btn++)->buttonDefinition = BT_TRANSFER; 01337 (btn++)->buttonDefinition = BT_FORWARDALL; 01338 (btn++)->buttonDefinition = BT_CALLPARK; 01339 (btn++)->buttonDefinition = BT_VOICEMAIL; 01340 break; 01341 case SKINNY_DEVICE_7910: 01342 (btn++)->buttonDefinition = BT_LINE; 01343 (btn++)->buttonDefinition = BT_HOLD; 01344 (btn++)->buttonDefinition = BT_TRANSFER; 01345 (btn++)->buttonDefinition = BT_DISPLAY; 01346 (btn++)->buttonDefinition = BT_VOICEMAIL; 01347 (btn++)->buttonDefinition = BT_CONFERENCE; 01348 (btn++)->buttonDefinition = BT_FORWARDALL; 01349 for (i = 0; i < 2; i++) 01350 (btn++)->buttonDefinition = BT_SPEEDDIAL; 01351 (btn++)->buttonDefinition = BT_REDIAL; 01352 break; 01353 case SKINNY_DEVICE_7960: 01354 case SKINNY_DEVICE_7961: 01355 case SKINNY_DEVICE_7961GE: 01356 case SKINNY_DEVICE_7962: 01357 case SKINNY_DEVICE_7965: 01358 for (i = 0; i < 6; i++) 01359 (btn++)->buttonDefinition = BT_CUST_LINESPEEDDIAL; 01360 break; 01361 case SKINNY_DEVICE_7940: 01362 case SKINNY_DEVICE_7941: 01363 case SKINNY_DEVICE_7941GE: 01364 case SKINNY_DEVICE_7942: 01365 case SKINNY_DEVICE_7945: 01366 for (i = 0; i < 2; i++) 01367 (btn++)->buttonDefinition = BT_CUST_LINESPEEDDIAL; 01368 break; 01369 case SKINNY_DEVICE_7935: 01370 case SKINNY_DEVICE_7936: 01371 for (i = 0; i < 2; i++) 01372 (btn++)->buttonDefinition = BT_LINE; 01373 break; 01374 case SKINNY_DEVICE_ATA186: 01375 (btn++)->buttonDefinition = BT_LINE; 01376 break; 01377 case SKINNY_DEVICE_7970: 01378 case SKINNY_DEVICE_7971: 01379 case SKINNY_DEVICE_7975: 01380 case SKINNY_DEVICE_CIPC: 01381 for (i = 0; i < 8; i++) 01382 (btn++)->buttonDefinition = BT_CUST_LINESPEEDDIAL; 01383 break; 01384 case SKINNY_DEVICE_7985: 01385 /* XXX I have no idea what the buttons look like on these. */ 01386 ast_log(LOG_WARNING, "Unsupported device type '%d (7985)' found.\n", d->type); 01387 break; 01388 case SKINNY_DEVICE_7912: 01389 case SKINNY_DEVICE_7911: 01390 case SKINNY_DEVICE_7905: 01391 (btn++)->buttonDefinition = BT_LINE; 01392 (btn++)->buttonDefinition = BT_HOLD; 01393 break; 01394 case SKINNY_DEVICE_7920: 01395 /* XXX I don't know if this is right. */ 01396 for (i = 0; i < 4; i++) 01397 (btn++)->buttonDefinition = BT_CUST_LINESPEEDDIAL; 01398 break; 01399 case SKINNY_DEVICE_7921: 01400 for (i = 0; i < 6; i++) 01401 (btn++)->buttonDefinition = BT_CUST_LINESPEEDDIAL; 01402 break; 01403 case SKINNY_DEVICE_7902: 01404 ast_log(LOG_WARNING, "Unsupported device type '%d (7902)' found.\n", d->type); 01405 break; 01406 case SKINNY_DEVICE_7906: 01407 ast_log(LOG_WARNING, "Unsupported device type '%d (7906)' found.\n", d->type); 01408 break; 01409 case SKINNY_DEVICE_7931: 01410 ast_log(LOG_WARNING, "Unsupported device type '%d (7931)' found.\n", d->type); 01411 break; 01412 case SKINNY_DEVICE_7937: 01413 ast_log(LOG_WARNING, "Unsupported device type '%d (7937)' found.\n", d->type); 01414 break; 01415 case SKINNY_DEVICE_7914: 01416 ast_log(LOG_WARNING, "Unsupported device type '%d (7914)' found. Expansion module registered by itself?\n", d->type); 01417 break; 01418 case SKINNY_DEVICE_SCCPGATEWAY_AN: 01419 case SKINNY_DEVICE_SCCPGATEWAY_BRI: 01420 ast_log(LOG_WARNING, "Unsupported device type '%d (SCCP gateway)' found.\n", d->type); 01421 break; 01422 default: 01423 ast_log(LOG_WARNING, "Unknown device type '%d' found.\n", d->type); 01424 break; 01425 } 01426 01427 AST_LIST_LOCK(&d->addons); 01428 AST_LIST_TRAVERSE(&d->addons, a, list) { 01429 if (!strcasecmp(a->type, "7914")) { 01430 for (i = 0; i < 14; i++) 01431 (btn++)->buttonDefinition = BT_CUST_LINESPEEDDIAL; 01432 } else { 01433 ast_log(LOG_WARNING, "Unknown addon type '%s' found. Skipping.\n", a->type); 01434 } 01435 } 01436 AST_LIST_UNLOCK(&d->addons); 01437 01438 return btn; 01439 }
static int get_devicestate | ( | struct skinny_line * | l | ) | [static] |
Definition at line 3689 of file chan_skinny.c.
References AST_DEVICE_BUSY, AST_DEVICE_INUSE, AST_DEVICE_INVALID, AST_DEVICE_NOT_INUSE, AST_DEVICE_ONHOLD, AST_DEVICE_UNAVAILABLE, AST_DEVICE_UNKNOWN, AST_LIST_TRAVERSE, skinny_line::dnd, skinny_line::hookstate, skinny_subchannel::onhold, skinny_line::parent, SKINNY_ONHOOK, and skinny_line::sub.
Referenced by skinny_devicestate(), and skinny_new().
03690 { 03691 struct skinny_subchannel *sub; 03692 int res = AST_DEVICE_UNKNOWN; 03693 03694 if (!l) 03695 res = AST_DEVICE_INVALID; 03696 else if (!l->parent) 03697 res = AST_DEVICE_UNAVAILABLE; 03698 else if (l->dnd) 03699 res = AST_DEVICE_BUSY; 03700 else { 03701 if (l->hookstate == SKINNY_ONHOOK) { 03702 res = AST_DEVICE_NOT_INUSE; 03703 } else { 03704 res = AST_DEVICE_INUSE; 03705 } 03706 03707 AST_LIST_TRAVERSE(&l->sub, sub, list) { 03708 if (sub->onhold) { 03709 res = AST_DEVICE_ONHOLD; 03710 break; 03711 } 03712 } 03713 } 03714 03715 return res; 03716 }
static int get_input | ( | struct skinnysession * | s | ) | [static] |
Definition at line 5886 of file chan_skinny.c.
References ast_debug, ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_poll, ast_verb, errno, htolel, letohl, LOG_WARNING, s, and skinny_unregister().
05887 { 05888 int res; 05889 int dlen = 0; 05890 struct pollfd fds[1]; 05891 05892 fds[0].fd = s->fd; 05893 fds[0].events = POLLIN; 05894 fds[0].revents = 0; 05895 res = ast_poll(fds, 1, (keep_alive * 1100)); /* If nothing has happen, client is dead */ 05896 /* we add 10% to the keep_alive to deal */ 05897 /* with network delays, etc */ 05898 if (res < 0) { 05899 if (errno != EINTR) { 05900 ast_log(LOG_WARNING, "Select returned error: %s\n", strerror(errno)); 05901 return res; 05902 } 05903 } else if (res == 0) { 05904 if (skinnydebug) 05905 ast_verb(1, "Skinny Client was lost, unregistering\n"); 05906 skinny_unregister(NULL, s); 05907 return -1; 05908 } 05909 05910 if (fds[0].revents) { 05911 ast_mutex_lock(&s->lock); 05912 memset(s->inbuf, 0, sizeof(s->inbuf)); 05913 res = read(s->fd, s->inbuf, 4); 05914 if (res < 0) { 05915 ast_log(LOG_WARNING, "read() returned error: %s\n", strerror(errno)); 05916 05917 if (skinnydebug) 05918 ast_verb(1, "Skinny Client was lost, unregistering\n"); 05919 05920 skinny_unregister(NULL, s); 05921 ast_mutex_unlock(&s->lock); 05922 return res; 05923 } else if (res != 4) { 05924 ast_log(LOG_WARNING, "Skinny Client sent less data than expected. Expected 4 but got %d.\n", res); 05925 ast_mutex_unlock(&s->lock); 05926 05927 if (res == 0) { 05928 if (skinnydebug) 05929 ast_verb(1, "Skinny Client was lost, unregistering\n"); 05930 skinny_unregister(NULL, s); 05931 } 05932 05933 return -1; 05934 } 05935 05936 dlen = letohl(*(int *)s->inbuf); 05937 if (dlen < 4) { 05938 ast_debug(1, "Skinny Client sent invalid data.\n"); 05939 ast_mutex_unlock(&s->lock); 05940 return -1; 05941 } 05942 if (dlen+8 > sizeof(s->inbuf)) { 05943 dlen = sizeof(s->inbuf) - 8; 05944 } 05945 *(int *)s->inbuf = htolel(dlen); 05946 05947 res = read(s->fd, s->inbuf+4, dlen+4); 05948 ast_mutex_unlock(&s->lock); 05949 if (res < 0) { 05950 ast_log(LOG_WARNING, "read() returned error: %s\n", strerror(errno)); 05951 return res; 05952 } else if (res != (dlen+4)) { 05953 ast_log(LOG_WARNING, "Skinny Client sent less data than expected.\n"); 05954 return -1; 05955 } 05956 return res; 05957 } 05958 return 0; 05959 }
static int handle_alarm_message | ( | struct skinny_req * | req, | |
struct skinnysession * | s | |||
) | [static] |
Definition at line 5150 of file chan_skinny.c.
References skinny_data::alarm, ast_verb, skinny_req::data, and alarm_message::displayMessage.
Referenced by handle_message().
05151 { 05152 /* no response necessary */ 05153 if (skinnydebug) 05154 ast_verb(1, "Received Alarm Message: %s\n", req->data.alarm.displayMessage); 05155 05156 return 1; 05157 }
static int handle_button_template_req_message | ( | struct skinny_req * | req, | |
struct skinnysession * | s | |||
) | [static] |
Definition at line 4977 of file chan_skinny.c.
References AST_LIST_TRAVERSE, ast_verb, BT_CUST_LINE, BT_CUST_LINESPEEDDIAL, BT_LINE, BT_NONE, BT_SPEEDDIAL, BUTTON_TEMPLATE_RES_MESSAGE, button_template_res_message::buttonCount, button_definition::buttonDefinition, button_definition_template::buttonDefinition, button_template_res_message::buttonOffset, skinny_data::buttontemplate, skinny_req::data, button_template_res_message::definition, get_button_template(), htolel, skinny_speeddial::instance, skinny_line::instance, button_definition::instanceNumber, skinny_speeddial::isHint, skinny_device::lines, skinny_device::name, req_alloc(), s, skinny_device::speeddials, button_template_res_message::totalButtonCount, transmit_response(), and skinny_device::type.
Referenced by handle_message().
04978 { 04979 struct skinny_device *d = s->device; 04980 struct skinny_line *l; 04981 int i; 04982 04983 struct skinny_speeddial *sd; 04984 struct button_definition_template btn[42]; 04985 int lineInstance = 1; 04986 int speeddialInstance = 1; 04987 int buttonCount = 0; 04988 04989 if (!(req = req_alloc(sizeof(struct button_template_res_message), BUTTON_TEMPLATE_RES_MESSAGE))) 04990 return -1; 04991 04992 memset(&btn, 0, sizeof(btn)); 04993 04994 get_button_template(s, btn); 04995 04996 for (i=0; i<42; i++) { 04997 int btnSet = 0; 04998 switch (btn[i].buttonDefinition) { 04999 case BT_CUST_LINE: 05000 /* assume failure */ 05001 req->data.buttontemplate.definition[i].buttonDefinition = BT_NONE; 05002 req->data.buttontemplate.definition[i].instanceNumber = htolel(0); 05003 05004 AST_LIST_TRAVERSE(&d->lines, l, list) { 05005 if (l->instance == lineInstance) { 05006 ast_verb(0, "Adding button: %d, %d\n", BT_LINE, lineInstance); 05007 req->data.buttontemplate.definition[i].buttonDefinition = BT_LINE; 05008 req->data.buttontemplate.definition[i].instanceNumber = htolel(lineInstance); 05009 lineInstance++; 05010 buttonCount++; 05011 btnSet = 1; 05012 break; 05013 } 05014 } 05015 05016 if (!btnSet) { 05017 AST_LIST_TRAVERSE(&d->speeddials, sd, list) { 05018 if (sd->isHint && sd->instance == lineInstance) { 05019 ast_verb(0, "Adding button: %d, %d\n", BT_LINE, lineInstance); 05020 req->data.buttontemplate.definition[i].buttonDefinition = BT_LINE; 05021 req->data.buttontemplate.definition[i].instanceNumber = htolel(lineInstance); 05022 lineInstance++; 05023 buttonCount++; 05024 btnSet = 1; 05025 break; 05026 } 05027 } 05028 } 05029 break; 05030 case BT_CUST_LINESPEEDDIAL: 05031 /* assume failure */ 05032 req->data.buttontemplate.definition[i].buttonDefinition = BT_NONE; 05033 req->data.buttontemplate.definition[i].instanceNumber = htolel(0); 05034 05035 AST_LIST_TRAVERSE(&d->lines, l, list) { 05036 if (l->instance == lineInstance) { 05037 ast_verb(0, "Adding button: %d, %d\n", BT_LINE, lineInstance); 05038 req->data.buttontemplate.definition[i].buttonDefinition = BT_LINE; 05039 req->data.buttontemplate.definition[i].instanceNumber = htolel(lineInstance); 05040 lineInstance++; 05041 buttonCount++; 05042 btnSet = 1; 05043 break; 05044 } 05045 } 05046 05047 if (!btnSet) { 05048 AST_LIST_TRAVERSE(&d->speeddials, sd, list) { 05049 if (sd->isHint && sd->instance == lineInstance) { 05050 ast_verb(0, "Adding button: %d, %d\n", BT_LINE, lineInstance); 05051 req->data.buttontemplate.definition[i].buttonDefinition = BT_LINE; 05052 req->data.buttontemplate.definition[i].instanceNumber = htolel(lineInstance); 05053 lineInstance++; 05054 buttonCount++; 05055 btnSet = 1; 05056 break; 05057 } else if (!sd->isHint && sd->instance == speeddialInstance) { 05058 ast_verb(0, "Adding button: %d, %d\n", BT_SPEEDDIAL, speeddialInstance); 05059 req->data.buttontemplate.definition[i].buttonDefinition = BT_SPEEDDIAL; 05060 req->data.buttontemplate.definition[i].instanceNumber = htolel(speeddialInstance); 05061 speeddialInstance++; 05062 buttonCount++; 05063 btnSet = 1; 05064 break; 05065 } 05066 } 05067 } 05068 break; 05069 case BT_LINE: 05070 req->data.buttontemplate.definition[i].buttonDefinition = htolel(BT_NONE); 05071 req->data.buttontemplate.definition[i].instanceNumber = htolel(0); 05072 05073 AST_LIST_TRAVERSE(&d->lines, l, list) { 05074 if (l->instance == lineInstance) { 05075 ast_verb(0, "Adding button: %d, %d\n", BT_LINE, lineInstance); 05076 req->data.buttontemplate.definition[i].buttonDefinition = BT_LINE; 05077 req->data.buttontemplate.definition[i].instanceNumber = htolel(lineInstance); 05078 lineInstance++; 05079 buttonCount++; 05080 btnSet = 1; 05081 break; 05082 } 05083 } 05084 break; 05085 case BT_SPEEDDIAL: 05086 req->data.buttontemplate.definition[i].buttonDefinition = BT_NONE; 05087 req->data.buttontemplate.definition[i].instanceNumber = 0; 05088 05089 AST_LIST_TRAVERSE(&d->speeddials, sd, list) { 05090 if (!sd->isHint && sd->instance == speeddialInstance) { 05091 ast_verb(0, "Adding button: %d, %d\n", BT_SPEEDDIAL, speeddialInstance); 05092 req->data.buttontemplate.definition[i].buttonDefinition = BT_SPEEDDIAL; 05093 req->data.buttontemplate.definition[i].instanceNumber = htolel(speeddialInstance - 1); 05094 speeddialInstance++; 05095 buttonCount++; 05096 btnSet = 1; 05097 break; 05098 } 05099 } 05100 break; 05101 case BT_NONE: 05102 break; 05103 default: 05104 ast_verb(0, "Adding button: %d, %d\n", btn[i].buttonDefinition, 0); 05105 req->data.buttontemplate.definition[i].buttonDefinition = htolel(btn[i].buttonDefinition); 05106 req->data.buttontemplate.definition[i].instanceNumber = htolel(0); 05107 buttonCount++; 05108 btnSet = 1; 05109 break; 05110 } 05111 } 05112 05113 req->data.buttontemplate.buttonOffset = htolel(0); 05114 req->data.buttontemplate.buttonCount = htolel(buttonCount); 05115 req->data.buttontemplate.totalButtonCount = htolel(buttonCount); 05116 05117 if (skinnydebug) 05118 ast_verb(1, "Sending %d template to %s\n", 05119 d->type, 05120 d->name); 05121 transmit_response(d, req); 05122 return 1; 05123 }
static int handle_callforward_button | ( | struct skinny_subchannel * | sub, | |
int | cfwdtype | |||
) | [static] |
Definition at line 4237 of file chan_skinny.c.
References ast_channel::_state, ast_hangup(), ast_indicate(), ast_log(), ast_pthread_create, ast_safe_sleep(), AST_STATE_UP, ast_verb, skinny_subchannel::callid, skinny_line::cfwdtype, errno, skinny_line::getforward, skinny_line::hookstate, skinny_line::instance, KEYDEF_RINGOUT, LOG_WARNING, skinny_device::name, skinny_line::name, skinny_subchannel::owner, skinny_line::parent, set_callforwards(), SKINNY_DIALTONE, SKINNY_OFFHOOK, SKINNY_ONHOOK, SKINNY_SPEAKEROFF, SKINNY_SPEAKERON, skinny_ss(), skinny_line::sub, transmit_callstate(), transmit_cfwdstate(), transmit_displaymessage(), transmit_displaynotify(), transmit_selectsoftkeys(), transmit_speaker_mode(), and transmit_tone().
Referenced by handle_soft_key_event_message(), and handle_stimulus_message().
04238 { 04239 struct skinny_line *l = sub->parent; 04240 struct skinny_device *d = l->parent; 04241 struct ast_channel *c = sub->owner; 04242 pthread_t t; 04243 04244 if (l->hookstate == SKINNY_ONHOOK) { 04245 l->hookstate = SKINNY_OFFHOOK; 04246 transmit_speaker_mode(d, SKINNY_SPEAKERON); 04247 transmit_callstate(d, l->instance, SKINNY_OFFHOOK, sub->callid); 04248 } 04249 if (skinnydebug) 04250 ast_verb(1, "Attempting to Clear display on Skinny %s@%s\n", l->name, d->name); 04251 transmit_displaymessage(d, NULL, l->instance, sub->callid); /* clear display */ 04252 04253 if (l->cfwdtype & cfwdtype) { 04254 set_callforwards(l, NULL, cfwdtype); 04255 ast_safe_sleep(c, 500); 04256 transmit_speaker_mode(d, SKINNY_SPEAKEROFF); 04257 transmit_callstate(d, l->instance, SKINNY_ONHOOK, sub->callid); 04258 transmit_displaynotify(d, "CFwd disabled", 10); 04259 if (sub->owner && sub->owner->_state != AST_STATE_UP) { 04260 ast_indicate(c, -1); 04261 ast_hangup(c); 04262 } 04263 transmit_cfwdstate(d, l); 04264 } else { 04265 l->getforward = cfwdtype; 04266 transmit_tone(d, SKINNY_DIALTONE, l->instance, sub->callid); 04267 transmit_selectsoftkeys(d, l->instance, sub->callid, KEYDEF_RINGOUT); 04268 if (ast_pthread_create(&t, NULL, skinny_ss, c)) { 04269 ast_log(LOG_WARNING, "Unable to create switch thread: %s\n", strerror(errno)); 04270 ast_hangup(c); 04271 } 04272 } 04273 return 0; 04274 }
static int handle_capabilities_res_message | ( | struct skinny_req * | req, | |
struct skinnysession * | s | |||
) | [static] |
Definition at line 4857 of file chan_skinny.c.
References AST_LIST_TRAVERSE, ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_verb, skinny_line::capability, skinny_device::capability, capabilities_res_message::caps, skinny_data::caps, station_capabilities::codec, codec_skinny2ast(), capabilities_res_message::count, skinny_req::data, letohl, skinny_device::lines, skinny_line::lock, LOG_WARNING, s, and SKINNY_MAX_CAPABILITIES.
Referenced by handle_message().
04858 { 04859 struct skinny_device *d = s->device; 04860 struct skinny_line *l; 04861 uint32_t count = 0; 04862 int codecs = 0; 04863 int i; 04864 04865 count = letohl(req->data.caps.count); 04866 if (count > SKINNY_MAX_CAPABILITIES) { 04867 count = SKINNY_MAX_CAPABILITIES; 04868 ast_log(LOG_WARNING, "Received more capabilities than we can handle (%d). Ignoring the rest.\n", SKINNY_MAX_CAPABILITIES); 04869 } 04870 04871 for (i = 0; i < count; i++) { 04872 int acodec = 0; 04873 int scodec = 0; 04874 scodec = letohl(req->data.caps.caps[i].codec); 04875 acodec = codec_skinny2ast(scodec); 04876 if (skinnydebug) 04877 ast_verb(1, "Adding codec capability '%d (%d)'\n", acodec, scodec); 04878 codecs |= acodec; 04879 } 04880 04881 d->capability &= codecs; 04882 ast_verb(0, "Device capability set to '%d'\n", d->capability); 04883 AST_LIST_TRAVERSE(&d->lines, l, list) { 04884 ast_mutex_lock(&l->lock); 04885 l->capability = d->capability; 04886 ast_mutex_unlock(&l->lock); 04887 } 04888 04889 return 1; 04890 }
static int handle_enbloc_call_message | ( | struct skinny_req * | req, | |
struct skinnysession * | s | |||
) | [static] |
Definition at line 5226 of file chan_skinny.c.
References ast_copy_string(), ast_hangup(), ast_ignore_pattern(), ast_log(), ast_pthread_create, AST_STATE_DOWN, ast_verb, enbloc_call_message::calledParty, skinny_subchannel::callid, ast_channel::context, skinny_req::data, skinny_data::enbloccallmessage, errno, ast_channel::exten, find_line_by_instance(), find_subchannel_by_instance_reference(), skinny_line::hookstate, skinny_line::instance, skinny_device::lastcallreference, skinny_device::lastlineinstance, LOG_WARNING, skinny_device::name, skinny_line::name, skinny_subchannel::parent, s, SKINNY_DIALTONE, skinny_new(), skinny_newcall(), SKINNY_OFFHOOK, SKINNY_SILENCE, ast_channel::tech_pvt, transmit_callstate(), transmit_displaymessage(), and transmit_tone().
Referenced by handle_message().
05227 { 05228 struct skinny_device *d = s->device; 05229 struct skinny_line *l; 05230 struct skinny_subchannel *sub = NULL; 05231 struct ast_channel *c; 05232 pthread_t t; 05233 05234 if (skinnydebug) 05235 ast_verb(1, "Received Enbloc Call: %s\n", req->data.enbloccallmessage.calledParty); 05236 05237 sub = find_subchannel_by_instance_reference(d, d->lastlineinstance, d->lastcallreference); 05238 05239 if (!sub) { 05240 l = find_line_by_instance(d, d->lastlineinstance); 05241 if (!l) { 05242 return 0; 05243 } 05244 } else { 05245 l = sub->parent; 05246 } 05247 05248 c = skinny_new(l, AST_STATE_DOWN); 05249 05250 if(!c) { 05251 ast_log(LOG_WARNING, "Unable to create channel for %s@%s\n", l->name, d->name); 05252 } else { 05253 l->hookstate = SKINNY_OFFHOOK; 05254 05255 sub = c->tech_pvt; 05256 transmit_callstate(d, l->instance, SKINNY_OFFHOOK, sub->callid); 05257 if (skinnydebug) 05258 ast_verb(1, "Attempting to Clear display on Skinny %s@%s\n", l->name, d->name); 05259 transmit_displaymessage(d, NULL, l->instance, sub->callid); /* clear display */ 05260 transmit_tone(d, SKINNY_DIALTONE, l->instance, sub->callid); 05261 05262 if (!ast_ignore_pattern(c->context, req->data.enbloccallmessage.calledParty)) { 05263 transmit_tone(d, SKINNY_SILENCE, l->instance, sub->callid); 05264 } 05265 ast_copy_string(c->exten, req->data.enbloccallmessage.calledParty, sizeof(c->exten)); 05266 if (ast_pthread_create(&t, NULL, skinny_newcall, c)) { 05267 ast_log(LOG_WARNING, "Unable to create new call thread: %s\n", strerror(errno)); 05268 ast_hangup(c); 05269 } 05270 } 05271 05272 return 1; 05273 }
static int handle_headset_status_message | ( | struct skinny_req * | req, | |
struct skinnysession * | s | |||
) | [static] |
static int handle_hold_button | ( | struct skinny_subchannel * | sub | ) | [static] |
Definition at line 4081 of file chan_skinny.c.
References skinny_line::activesub, skinny_subchannel::callid, skinny_line::instance, KEYDEF_CONNECTED, KEYDEF_ONHOLD, skinny_subchannel::onhold, skinny_line::parent, skinny_subchannel::parent, skinny_subchannel::related, skinny_hold(), skinny_unhold(), and transmit_selectsoftkeys().
Referenced by handle_soft_key_event_message(), and handle_stimulus_message().
04082 { 04083 if (!sub) 04084 return -1; 04085 if (sub->related) { 04086 skinny_hold(sub); 04087 skinny_unhold(sub->related); 04088 sub->parent->activesub = sub->related; 04089 } else { 04090 if (sub->onhold) { 04091 skinny_unhold(sub); 04092 transmit_selectsoftkeys(sub->parent->parent, sub->parent->instance, sub->callid, KEYDEF_CONNECTED); 04093 } else { 04094 skinny_hold(sub); 04095 transmit_selectsoftkeys(sub->parent->parent, sub->parent->instance, sub->callid, KEYDEF_ONHOLD); 04096 } 04097 } 04098 return 1; 04099 }
static int handle_ip_port_message | ( | struct skinny_req * | req, | |
struct skinnysession * | s | |||
) | [static] |
static int handle_keep_alive_message | ( | struct skinny_req * | req, | |
struct skinnysession * | s | |||
) | [static] |
Definition at line 4162 of file chan_skinny.c.
References do_housekeeping(), KEEP_ALIVE_ACK_MESSAGE, req_alloc(), s, and transmit_response().
Referenced by handle_message().
04163 { 04164 if (!(req = req_alloc(0, KEEP_ALIVE_ACK_MESSAGE))) 04165 return -1; 04166 04167 transmit_response(s->device, req); 04168 do_housekeeping(s); 04169 return 1; 04170 }
static int handle_keypad_button_message | ( | struct skinny_req * | req, | |
struct skinnysession * | s | |||
) | [static] |
Definition at line 4281 of file chan_skinny.c.
References ast_channel::_state, skinny_device::activeline, skinny_line::activesub, AST_FRAME_DTMF_BEGIN, AST_FRAME_DTMF_END, AST_LIST_NEXT, ast_log(), ast_queue_frame(), ast_verb, keypad_button_message::button, keypad_button_message::callReference, skinny_req::data, f, find_subchannel_by_instance_reference(), skinny_data::keypad, letohl, keypad_button_message::lineInstance, LOG_WARNING, skinny_line::name, skinny_subchannel::owner, skinny_subchannel::parent, and s.
Referenced by handle_message().
04282 { 04283 struct skinny_subchannel *sub = NULL; 04284 struct skinny_line *l; 04285 struct skinny_device *d = s->device; 04286 struct ast_frame f = { 0, }; 04287 char dgt; 04288 int digit; 04289 int lineInstance; 04290 int callReference; 04291 04292 digit = letohl(req->data.keypad.button); 04293 lineInstance = letohl(req->data.keypad.lineInstance); 04294 callReference = letohl(req->data.keypad.callReference); 04295 04296 if (digit == 14) { 04297 dgt = '*'; 04298 } else if (digit == 15) { 04299 dgt = '#'; 04300 } else if (digit >= 0 && digit <= 9) { 04301 dgt = '0' + digit; 04302 } else { 04303 /* digit=10-13 (A,B,C,D ?), or 04304 * digit is bad value 04305 * 04306 * probably should not end up here, but set 04307 * value for backward compatibility, and log 04308 * a warning. 04309 */ 04310 dgt = '0' + digit; 04311 ast_log(LOG_WARNING, "Unsupported digit %d\n", digit); 04312 } 04313 04314 f.subclass = dgt; 04315 04316 f.src = "skinny"; 04317 04318 if (lineInstance && callReference) 04319 sub = find_subchannel_by_instance_reference(d, lineInstance, callReference); 04320 else 04321 sub = d->activeline->activesub; 04322 //sub = find_subchannel_by_instance_reference(d, d->lastlineinstance, d->lastcallreference); 04323 04324 if (!sub) 04325 return 0; 04326 04327 l = sub->parent; 04328 if (sub->owner) { 04329 if (sub->owner->_state == 0) { 04330 f.frametype = AST_FRAME_DTMF_BEGIN; 04331 ast_queue_frame(sub->owner, &f); 04332 } 04333 /* XXX MUST queue this frame to all lines in threeway call if threeway call is active */ 04334 f.frametype = AST_FRAME_DTMF_END; 04335 ast_queue_frame(sub->owner, &f); 04336 /* XXX This seriously needs to be fixed */ 04337 if (AST_LIST_NEXT(sub, list) && AST_LIST_NEXT(sub, list)->owner) { 04338 if (sub->owner->_state == 0) { 04339 f.frametype = AST_FRAME_DTMF_BEGIN; 04340 ast_queue_frame(AST_LIST_NEXT(sub, list)->owner, &f); 04341 } 04342 f.frametype = AST_FRAME_DTMF_END; 04343 ast_queue_frame(AST_LIST_NEXT(sub, list)->owner, &f); 04344 } 04345 } else { 04346 if (skinnydebug) 04347 ast_verb(1, "No owner: %s\n", l->name); 04348 } 04349 return 1; 04350 }
static int handle_line_state_req_message | ( | struct skinny_req * | req, | |
struct skinnysession * | s | |||
) | [static] |
Definition at line 4917 of file chan_skinny.c.
References AST_LIST_LOCK, AST_LIST_UNLOCK, skinny_req::data, find_line_by_instance(), find_speeddial_by_instance(), skinny_line::label, skinny_speeddial::label, letohl, skinny_data::line, LINE_STAT_RES_MESSAGE, line_stat_res_message::lineDirNumber, line_stat_res_message::lineDisplayName, line_stat_res_message::lineNumber, line_state_req_message::lineNumber, skinny_data::linestat, skinny_line::name, req_alloc(), s, and transmit_response().
Referenced by handle_message().
04918 { 04919 struct skinny_device *d = s->device; 04920 struct skinny_line *l; 04921 struct skinny_speeddial *sd = NULL; 04922 int instance; 04923 04924 instance = letohl(req->data.line.lineNumber); 04925 04926 AST_LIST_LOCK(&devices); 04927 04928 l = find_line_by_instance(d, instance); 04929 04930 if (!l) { 04931 sd = find_speeddial_by_instance(d, instance, 1); 04932 } 04933 04934 if (!l && !sd) { 04935 return 0; 04936 } 04937 04938 AST_LIST_UNLOCK(&devices); 04939 04940 if (!(req = req_alloc(sizeof(struct line_stat_res_message), LINE_STAT_RES_MESSAGE))) 04941 return -1; 04942 04943 req->data.linestat.lineNumber = letohl(instance); 04944 if (!l) { 04945 memcpy(req->data.linestat.lineDirNumber, sd->label, sizeof(req->data.linestat.lineDirNumber)); 04946 memcpy(req->data.linestat.lineDisplayName, sd->label, sizeof(req->data.linestat.lineDisplayName)); 04947 } else { 04948 memcpy(req->data.linestat.lineDirNumber, l->name, sizeof(req->data.linestat.lineDirNumber)); 04949 memcpy(req->data.linestat.lineDisplayName, l->label, sizeof(req->data.linestat.lineDisplayName)); 04950 } 04951 transmit_response(d, req); 04952 return 1; 04953 }
static int handle_message | ( | struct skinny_req * | req, | |
struct skinnysession * | s | |||
) | [static] |
Definition at line 5696 of file chan_skinny.c.
References ast_channel::_state, skinny_device::activeline, skinny_line::activesub, ALARM_MESSAGE, ast_free, ast_log(), AST_STATE_UP, ast_verb, keypad_button_message::button, BUTTON_TEMPLATE_REQ_MESSAGE, keypad_button_message::callReference, CAPABILITIES_RES_MESSAGE, skinny_req::data, skinny_req::e, ENBLOC_CALL_MESSAGE, skinny_device::exten, find_subchannel_by_instance_reference(), handle_alarm_message(), handle_button_template_req_message(), handle_capabilities_res_message(), handle_enbloc_call_message(), handle_headset_status_message(), handle_ip_port_message(), handle_keep_alive_message(), handle_keypad_button_message(), handle_line_state_req_message(), handle_offhook_message(), handle_onhook_message(), handle_open_receive_channel_ack_message(), handle_register_available_lines_message(), handle_register_message(), handle_server_request_message(), handle_soft_key_event_message(), handle_soft_key_set_req_message(), handle_soft_key_template_req_message(), handle_speed_dial_stat_req_message(), handle_stimulus_message(), handle_time_date_req_message(), handle_unregister_message(), handle_version_req_message(), HEADSET_STATUS_MESSAGE, IP_PORT_MESSAGE, KEEP_ALIVE_MESSAGE, skinny_data::keypad, KEYPAD_BUTTON_MESSAGE, letohl, LINE_STATE_REQ_MESSAGE, keypad_button_message::lineInstance, LOG_WARNING, register_message::name, OFFHOOK_MESSAGE, skinny_subchannel::onhold, ONHOOK_MESSAGE, OPEN_RECEIVE_CHANNEL_ACK_MESSAGE, skinny_subchannel::owner, skinny_data::reg, REGISTER_AVAILABLE_LINES_MESSAGE, REGISTER_MESSAGE, s, SERVER_REQUEST_MESSAGE, SOFT_KEY_EVENT_MESSAGE, SOFT_KEY_SET_REQ_MESSAGE, SOFT_KEY_TEMPLATE_REQ_MESSAGE, SPEED_DIAL_STAT_REQ_MESSAGE, STIMULUS_MESSAGE, TIME_DATE_REQ_MESSAGE, UNREGISTER_MESSAGE, and VERSION_REQ_MESSAGE.
Referenced by skinny_session().
05697 { 05698 int res = 0; 05699 05700 if ((!s->device) && (letohl(req->e) != REGISTER_MESSAGE && letohl(req->e) != ALARM_MESSAGE)) { 05701 ast_log(LOG_WARNING, "Client sent message #%d without first registering.\n", req->e); 05702 ast_free(req); 05703 return 0; 05704 } 05705 05706 switch(letohl(req->e)) { 05707 case KEEP_ALIVE_MESSAGE: 05708 res = handle_keep_alive_message(req, s); 05709 break; 05710 case REGISTER_MESSAGE: 05711 if (skinnydebug) 05712 ast_verb(1, "Device %s is attempting to register\n", req->data.reg.name); 05713 05714 res = handle_register_message(req, s); 05715 break; 05716 case IP_PORT_MESSAGE: 05717 res = handle_ip_port_message(req, s); 05718 break; 05719 case KEYPAD_BUTTON_MESSAGE: 05720 { 05721 struct skinny_device *d = s->device; 05722 struct skinny_subchannel *sub; 05723 int lineInstance; 05724 int callReference; 05725 05726 if (skinnydebug) 05727 ast_verb(1, "Collected digit: [%d]\n", letohl(req->data.keypad.button)); 05728 05729 lineInstance = letohl(req->data.keypad.lineInstance); 05730 callReference = letohl(req->data.keypad.callReference); 05731 05732 if (lineInstance) { 05733 sub = find_subchannel_by_instance_reference(d, lineInstance, callReference); 05734 } else { 05735 sub = d->activeline->activesub; 05736 } 05737 05738 if (sub && ((sub->owner && sub->owner->_state < AST_STATE_UP) || sub->onhold)) { 05739 char dgt; 05740 int digit = letohl(req->data.keypad.button); 05741 05742 if (digit == 14) { 05743 dgt = '*'; 05744 } else if (digit == 15) { 05745 dgt = '#'; 05746 } else if (digit >= 0 && digit <= 9) { 05747 dgt = '0' + digit; 05748 } else { 05749 /* digit=10-13 (A,B,C,D ?), or 05750 * digit is bad value 05751 * 05752 * probably should not end up here, but set 05753 * value for backward compatibility, and log 05754 * a warning. 05755 */ 05756 dgt = '0' + digit; 05757 ast_log(LOG_WARNING, "Unsupported digit %d\n", digit); 05758 } 05759 05760 d->exten[strlen(d->exten)] = dgt; 05761 d->exten[strlen(d->exten)+1] = '\0'; 05762 } else 05763 res = handle_keypad_button_message(req, s); 05764 } 05765 break; 05766 case ENBLOC_CALL_MESSAGE: 05767 res = handle_enbloc_call_message(req, s); 05768 break; 05769 case STIMULUS_MESSAGE: 05770 res = handle_stimulus_message(req, s); 05771 break; 05772 case OFFHOOK_MESSAGE: 05773 res = handle_offhook_message(req, s); 05774 break; 05775 case ONHOOK_MESSAGE: 05776 res = handle_onhook_message(req, s); 05777 break; 05778 case CAPABILITIES_RES_MESSAGE: 05779 if (skinnydebug) 05780 ast_verb(1, "Received CapabilitiesRes\n"); 05781 05782 res = handle_capabilities_res_message(req, s); 05783 break; 05784 case SPEED_DIAL_STAT_REQ_MESSAGE: 05785 if (skinnydebug) 05786 ast_verb(1, "Received SpeedDialStatRequest\n"); 05787 05788 res = handle_speed_dial_stat_req_message(req, s); 05789 break; 05790 case LINE_STATE_REQ_MESSAGE: 05791 if (skinnydebug) 05792 ast_verb(1, "Received LineStatRequest\n"); 05793 res = handle_line_state_req_message(req, s); 05794 break; 05795 case TIME_DATE_REQ_MESSAGE: 05796 if (skinnydebug) 05797 ast_verb(1, "Received Time/Date Request\n"); 05798 05799 res = handle_time_date_req_message(req, s); 05800 break; 05801 case BUTTON_TEMPLATE_REQ_MESSAGE: 05802 if (skinnydebug) 05803 ast_verb(1, "Buttontemplate requested\n"); 05804 05805 res = handle_button_template_req_message(req, s); 05806 break; 05807 case VERSION_REQ_MESSAGE: 05808 if (skinnydebug) 05809 ast_verb(1, "Version Request\n"); 05810 05811 res = handle_version_req_message(req, s); 05812 break; 05813 case SERVER_REQUEST_MESSAGE: 05814 if (skinnydebug) 05815 ast_verb(1, "Received Server Request\n"); 05816 05817 res = handle_server_request_message(req, s); 05818 break; 05819 case ALARM_MESSAGE: 05820 res = handle_alarm_message(req, s); 05821 break; 05822 case OPEN_RECEIVE_CHANNEL_ACK_MESSAGE: 05823 if (skinnydebug) 05824 ast_verb(1, "Received Open Receive Channel Ack\n"); 05825 05826 res = handle_open_receive_channel_ack_message(req, s); 05827 break; 05828 case SOFT_KEY_SET_REQ_MESSAGE: 05829 if (skinnydebug) 05830 ast_verb(1, "Received SoftKeySetReq\n"); 05831 05832 res = handle_soft_key_set_req_message(req, s); 05833 break; 05834 case SOFT_KEY_EVENT_MESSAGE: 05835 res = handle_soft_key_event_message(req, s); 05836 break; 05837 case UNREGISTER_MESSAGE: 05838 if (skinnydebug) 05839 ast_verb(1, "Received Unregister Request\n"); 05840 05841 res = handle_unregister_message(req, s); 05842 break; 05843 case SOFT_KEY_TEMPLATE_REQ_MESSAGE: 05844 if (skinnydebug) 05845 ast_verb(1, "Received SoftKey Template Request\n"); 05846 05847 res = handle_soft_key_template_req_message(req, s); 05848 break; 05849 case HEADSET_STATUS_MESSAGE: 05850 res = handle_headset_status_message(req, s); 05851 break; 05852 case REGISTER_AVAILABLE_LINES_MESSAGE: 05853 res = handle_register_available_lines_message(req, s); 05854 break; 05855 default: 05856 if (skinnydebug) 05857 ast_verb(1, "RECEIVED UNKNOWN MESSAGE TYPE: %x\n", letohl(req->e)); 05858 break; 05859 } 05860 if (res >= 0 && req) 05861 ast_free(req); 05862 return res; 05863 }
static int handle_offhook_message | ( | struct skinny_req * | req, | |
struct skinnysession * | s | |||
) | [static] |
Definition at line 4693 of file chan_skinny.c.
References skinny_device::activeline, skinny_line::activesub, AST_CONTROL_ANSWER, ast_debug, AST_DEVICE_INUSE, ast_devstate_changed(), ast_hangup(), AST_LIST_TRAVERSE, ast_log(), ast_pthread_create, ast_queue_control(), ast_setstate(), AST_STATE_DOWN, AST_STATE_UP, ast_verb, ast_verbose, skinny_req::data, errno, find_line_by_instance(), find_subchannel_by_instance_reference(), skinny_line::hookstate, skinny_line::instance, offhook_message::instance, KEYDEF_CONNECTED, KEYDEF_OFFHOOK, skinny_device::lastcallreference, skinny_device::lastlineinstance, letohl, skinny_device::lines, LOG_WARNING, skinny_device::name, skinny_line::name, skinny_data::offhook, offhook_message::reference, s, SKINNY_CONNECTED, SKINNY_DIALTONE, SKINNY_LAMP_ON, skinny_new(), SKINNY_OFFHOOK, SKINNY_RING_OFF, SKINNY_SILENCE, skinny_ss(), start_rtp(), STIMULUS_LINE, skinny_line::sub, ast_channel::tech_pvt, transmit_callstate(), transmit_callstateonly(), transmit_displaymessage(), transmit_lamp_indication(), transmit_ringer_mode(), transmit_selectsoftkeys(), transmit_tone(), and VERBOSE_PREFIX_3.
Referenced by handle_message().
04694 { 04695 struct skinny_device *d = s->device; 04696 struct skinny_line *l; 04697 struct skinny_subchannel *sub; 04698 struct ast_channel *c; 04699 struct skinny_line *tmp; 04700 pthread_t t; 04701 int instance; 04702 int reference; 04703 04704 /* if any line on a device is offhook, than the device must be offhook, 04705 unless we have shared lines CCM seems that it would never get here, 04706 but asterisk does, so we may need to do more work. Ugly, we should 04707 probably move hookstate from line to device, afterall, it's actually 04708 a device that changes hookstates */ 04709 04710 AST_LIST_TRAVERSE(&d->lines, tmp, list) { 04711 if (tmp->hookstate == SKINNY_OFFHOOK) { 04712 ast_verbose(VERBOSE_PREFIX_3 "Got offhook message when device (%s@%s) already offhook\n", tmp->name, d->name); 04713 return 0; 04714 } 04715 } 04716 04717 instance = letohl(req->data.offhook.instance); 04718 reference = letohl(req->data.offhook.reference); 04719 04720 if (instance) { 04721 sub = find_subchannel_by_instance_reference(d, d->lastlineinstance, d->lastcallreference); 04722 if (!sub) { 04723 l = find_line_by_instance(d, d->lastlineinstance); 04724 if (!l) { 04725 return 0; 04726 } 04727 } else { 04728 l = sub->parent; 04729 } 04730 } else { 04731 l = d->activeline; 04732 sub = l->activesub; 04733 } 04734 04735 transmit_ringer_mode(d, SKINNY_RING_OFF); 04736 l->hookstate = SKINNY_OFFHOOK; 04737 04738 ast_devstate_changed(AST_DEVICE_INUSE, "Skinny/%s@%s", l->name, d->name); 04739 04740 if (sub && sub->onhold) { 04741 return 1; 04742 } 04743 04744 transmit_lamp_indication(d, STIMULUS_LINE, l->instance, SKINNY_LAMP_ON); 04745 04746 if (sub && sub->outgoing) { 04747 /* We're answering a ringing call */ 04748 ast_queue_control(sub->owner, AST_CONTROL_ANSWER); 04749 transmit_callstate(d, l->instance, SKINNY_OFFHOOK, sub->callid); 04750 transmit_tone(d, SKINNY_SILENCE, l->instance, sub->callid); 04751 transmit_callstateonly(d, sub, SKINNY_CONNECTED); 04752 transmit_selectsoftkeys(d, l->instance, sub->callid, KEYDEF_CONNECTED); 04753 start_rtp(sub); 04754 ast_setstate(sub->owner, AST_STATE_UP); 04755 } else { 04756 if (sub && sub->owner) { 04757 ast_debug(1, "Current sub [%s] already has owner\n", sub->owner->name); 04758 } else { 04759 c = skinny_new(l, AST_STATE_DOWN); 04760 if (c) { 04761 sub = c->tech_pvt; 04762 transmit_callstate(d, l->instance, SKINNY_OFFHOOK, sub->callid); 04763 if (skinnydebug) 04764 ast_verb(1, "Attempting to Clear display on Skinny %s@%s\n", l->name, d->name); 04765 transmit_displaymessage(d, NULL, l->instance, sub->callid); /* clear display */ 04766 transmit_tone(d, SKINNY_DIALTONE, l->instance, sub->callid); 04767 transmit_selectsoftkeys(d, l->instance, sub->callid, KEYDEF_OFFHOOK); 04768 04769 /* start the switch thread */ 04770 if (ast_pthread_create(&t, NULL, skinny_ss, c)) { 04771 ast_log(LOG_WARNING, "Unable to create switch thread: %s\n", strerror(errno)); 04772 ast_hangup(c); 04773 } 04774 } else { 04775 ast_log(LOG_WARNING, "Unable to create channel for %s@%s\n", l->name, d->name); 04776 } 04777 } 04778 } 04779 return 1; 04780 }
static int handle_onhook_message | ( | struct skinny_req * | req, | |
struct skinnysession * | s | |||
) | [static] |
Definition at line 4782 of file chan_skinny.c.
References ast_channel::_state, skinny_device::activeline, skinny_line::activesub, skinny_subchannel::alreadygone, ast_debug, AST_DEVICE_NOT_INUSE, ast_devstate_changed(), AST_LIST_NEXT, AST_LIST_REMOVE, ast_log(), ast_queue_hangup(), AST_STATE_RING, skinny_subchannel::blindxfer, skinny_subchannel::callid, skinny_subchannel::cxmode, skinny_req::data, do_housekeeping(), find_subchannel_by_instance_reference(), handle_transfer_button(), skinny_line::hookstate, skinny_line::instance, onhook_message::instance, letohl, LOG_WARNING, skinny_device::name, skinny_line::name, skinny_subchannel::onhold, skinny_data::onhook, skinny_subchannel::owner, skinny_subchannel::parent, onhook_message::reference, skinny_subchannel::related, s, SKINNY_CX_RECVONLY, SKINNY_ONHOOK, skinny_line::sub, skinny_line::transfer, transmit_callstate(), and skinny_subchannel::xferor.
Referenced by handle_message().
04783 { 04784 struct skinny_device *d = s->device; 04785 struct skinny_line *l; 04786 struct skinny_subchannel *sub; 04787 int instance; 04788 int reference; 04789 int onlysub = 0; 04790 04791 instance = letohl(req->data.onhook.instance); 04792 reference = letohl(req->data.onhook.reference); 04793 04794 if (instance && reference) { 04795 sub = find_subchannel_by_instance_reference(d, instance, reference); 04796 if (!sub) { 04797 return 0; 04798 } 04799 l = sub->parent; 04800 } else { 04801 l = d->activeline; 04802 sub = l->activesub; 04803 } 04804 04805 if (l->hookstate == SKINNY_ONHOOK) { 04806 /* Something else already put us back on hook */ 04807 return 0; 04808 } 04809 04810 ast_devstate_changed(AST_DEVICE_NOT_INUSE, "Skinny/%s@%s", l->name, d->name); 04811 04812 if (sub->onhold) { 04813 return 0; 04814 } 04815 04816 if (!AST_LIST_NEXT(sub, list)) { 04817 onlysub = 1; 04818 } else { 04819 AST_LIST_REMOVE(&l->sub, sub, list); 04820 } 04821 04822 sub->cxmode = SKINNY_CX_RECVONLY; 04823 if (onlysub || sub->xferor){ /* is this the only call to this device? */ 04824 l->hookstate = SKINNY_ONHOOK; 04825 if (skinnydebug) 04826 ast_debug(1, "Skinny %s@%s-%d went on hook\n", l->name, d->name, reference); 04827 } 04828 04829 transmit_callstate(d, l->instance, l->hookstate, sub->callid); 04830 if (l->transfer && sub->xferor && sub->owner->_state >= AST_STATE_RING) { 04831 /* We're allowed to transfer, we have two active calls and 04832 we made at least one of the calls. Let's try and transfer */ 04833 handle_transfer_button(sub); 04834 } else { 04835 /* Hangup the current call */ 04836 /* If there is another active call, skinny_hangup will ring the phone with the other call */ 04837 if (sub->xferor && sub->related){ 04838 sub->related->related = NULL; 04839 sub->related->blindxfer = 0; 04840 } 04841 04842 if (sub->owner) { 04843 sub->alreadygone = 1; 04844 ast_queue_hangup(sub->owner); 04845 } else { 04846 ast_log(LOG_WARNING, "Skinny(%s@%s-%d) channel already destroyed\n", 04847 l->name, d->name, sub->callid); 04848 } 04849 } 04850 /* The bit commented below gives a very occasional core dump. */ 04851 if ((l->hookstate == SKINNY_ONHOOK) && (AST_LIST_NEXT(sub, list) /*&& !AST_LIST_NEXT(sub, list)->rtp*/)) { 04852 do_housekeeping(s); 04853 } 04854 return 1; 04855 }
static int handle_open_receive_channel_ack_message | ( | struct skinny_req * | req, | |
struct skinnysession * | s | |||
) | [static] |
Definition at line 5159 of file chan_skinny.c.
References ast_best_codec(), ast_codec_pref_getsize(), ast_inet_ntoa(), ast_log(), ast_rtp_get_us(), ast_rtp_set_peer(), ast_verb, media_qualifier::bitRate, ast_format_list::bits, skinny_subchannel::callid, skinny_line::capability, codec_ast2skinny(), start_media_transmission_message::conferenceId, ast_format_list::cur_ms, skinny_req::data, find_subchannel_by_reference(), htolel, open_receive_channel_ack_message::ipAddr, letohl, LOG_ERROR, skinny_data::openreceivechannelack, skinny_device::ourip, media_qualifier::packets, start_media_transmission_message::packetSize, skinny_subchannel::parent, open_receive_channel_ack_message::passThruId, start_media_transmission_message::passThruPartyId, start_media_transmission_message::payloadType, open_receive_channel_ack_message::port, media_qualifier::precedence, skinny_line::prefs, start_media_transmission_message::qualifier, start_media_transmission_message::remoteIp, start_media_transmission_message::remotePort, req_alloc(), skinny_subchannel::rtp, s, START_MEDIA_TRANSMISSION_MESSAGE, skinny_data::startmedia, open_receive_channel_ack_message::status, status, transmit_response(), and media_qualifier::vad.
Referenced by handle_message().
05160 { 05161 struct skinny_device *d = s->device; 05162 struct skinny_line *l; 05163 struct skinny_subchannel *sub; 05164 struct ast_format_list fmt; 05165 struct sockaddr_in sin; 05166 struct sockaddr_in us; 05167 uint32_t addr; 05168 int port; 05169 int status; 05170 int passthruid; 05171 05172 status = letohl(req->data.openreceivechannelack.status); 05173 if (status) { 05174 ast_log(LOG_ERROR, "Open Receive Channel Failure\n"); 05175 return 0; 05176 } 05177 addr = letohl(req->data.openreceivechannelack.ipAddr); 05178 port = letohl(req->data.openreceivechannelack.port); 05179 passthruid = letohl(req->data.openreceivechannelack.passThruId); 05180 05181 sin.sin_family = AF_INET; 05182 sin.sin_addr.s_addr = addr; 05183 sin.sin_port = htons(port); 05184 05185 sub = find_subchannel_by_reference(d, passthruid); 05186 05187 if (!sub) 05188 return 0; 05189 05190 l = sub->parent; 05191 05192 if (sub->rtp) { 05193 ast_rtp_set_peer(sub->rtp, &sin); 05194 ast_rtp_get_us(sub->rtp, &us); 05195 } else { 05196 ast_log(LOG_ERROR, "No RTP structure, this is very bad\n"); 05197 return 0; 05198 } 05199 05200 if (skinnydebug) 05201 ast_verb(1, "ipaddr = %s:%d\n", ast_inet_ntoa(sin.sin_addr), ntohs(sin.sin_port)); 05202 05203 if (!(req = req_alloc(sizeof(struct start_media_transmission_message), START_MEDIA_TRANSMISSION_MESSAGE))) 05204 return -1; 05205 05206 fmt = ast_codec_pref_getsize(&l->prefs, ast_best_codec(l->capability)); 05207 05208 if (skinnydebug) 05209 ast_verb(1, "Setting payloadType to '%d' (%d ms)\n", fmt.bits, fmt.cur_ms); 05210 05211 req->data.startmedia.conferenceId = htolel(sub->callid); 05212 req->data.startmedia.passThruPartyId = htolel(sub->callid); 05213 req->data.startmedia.remoteIp = htolel(d->ourip.s_addr); 05214 req->data.startmedia.remotePort = htolel(ntohs(us.sin_port)); 05215 req->data.startmedia.packetSize = htolel(fmt.cur_ms); 05216 req->data.startmedia.payloadType = htolel(codec_ast2skinny(fmt.bits)); 05217 req->data.startmedia.qualifier.precedence = htolel(127); 05218 req->data.startmedia.qualifier.vad = htolel(0); 05219 req->data.startmedia.qualifier.packets = htolel(0); 05220 req->data.startmedia.qualifier.bitRate = htolel(0); 05221 transmit_response(d, req); 05222 05223 return 1; 05224 }
static int handle_register_available_lines_message | ( | struct skinny_req * | req, | |
struct skinnysession * | s | |||
) | [static] |
Definition at line 5690 of file chan_skinny.c.
Referenced by handle_message().
05691 { 05692 /* XXX I have no clue what this is for, but my phone was sending it, so... */ 05693 return 1; 05694 }
static int handle_register_message | ( | struct skinny_req * | req, | |
struct skinnysession * | s | |||
) | [static] |
Definition at line 4172 of file chan_skinny.c.
References ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_verb, CAPABILITIES_REQ_MESSAGE, skinny_req::data, register_ack_message::dateTemplate, register_rej_message::errMsg, errno, htolel, register_ack_message::keepAlive, skinny_req::len, letohl, LOG_ERROR, LOG_WARNING, register_message::name, skinny_data::reg, skinny_data::regack, REGISTER_ACK_MESSAGE, REGISTER_REJ_MESSAGE, skinny_data::regrej, req_alloc(), register_ack_message::res, register_ack_message::res2, s, register_ack_message::secondaryKeepAlive, SKINNY_MAX_PACKET, skinny_register(), and transmit_response().
Referenced by handle_message().
04173 { 04174 struct skinny_device *d = NULL; 04175 char name[16]; 04176 int res; 04177 04178 memcpy(&name, req->data.reg.name, sizeof(name)); 04179 04180 res = skinny_register(req, s); 04181 if (!res) { 04182 ast_log(LOG_ERROR, "Rejecting Device %s: Device not found\n", name); 04183 if (!(req = req_alloc(sizeof(struct register_rej_message), REGISTER_REJ_MESSAGE))) 04184 return -1; 04185 04186 snprintf(req->data.regrej.errMsg, sizeof(req->data.regrej.errMsg), "No Authority: %s", name); 04187 04188 /* transmit_respons in line as we don't have a valid d */ 04189 ast_mutex_lock(&s->lock); 04190 04191 if (letohl(req->len > SKINNY_MAX_PACKET) || letohl(req->len < 0)) { 04192 ast_log(LOG_WARNING, "transmit_response: the length of the request is out of bounds\n"); 04193 ast_mutex_unlock(&s->lock); 04194 return -1; 04195 } 04196 04197 memset(s->outbuf, 0, sizeof(s->outbuf)); 04198 memcpy(s->outbuf, req, skinny_header_size); 04199 memcpy(s->outbuf+skinny_header_size, &req->data, letohl(req->len)); 04200 04201 res = write(s->fd, s->outbuf, letohl(req->len)+8); 04202 04203 if (res != letohl(req->len)+8) { 04204 ast_log(LOG_WARNING, "Transmit: write only sent %d out of %d bytes: %s\n", res, letohl(req->len)+8, strerror(errno)); 04205 } 04206 04207 ast_mutex_unlock(&s->lock); 04208 04209 return 0; 04210 } 04211 ast_verb(3, "Device '%s' successfully registered\n", name); 04212 04213 d = s->device; 04214 04215 if (!(req = req_alloc(sizeof(struct register_ack_message), REGISTER_ACK_MESSAGE))) 04216 return -1; 04217 04218 req->data.regack.res[0] = '0'; 04219 req->data.regack.res[1] = '\0'; 04220 req->data.regack.keepAlive = htolel(keep_alive); 04221 memcpy(req->data.regack.dateTemplate, date_format, sizeof(req->data.regack.dateTemplate)); 04222 req->data.regack.res2[0] = '0'; 04223 req->data.regack.res2[1] = '\0'; 04224 req->data.regack.secondaryKeepAlive = htolel(keep_alive); 04225 transmit_response(d, req); 04226 if (skinnydebug) 04227 ast_verb(1, "Requesting capabilities\n"); 04228 04229 if (!(req = req_alloc(0, CAPABILITIES_REQ_MESSAGE))) 04230 return -1; 04231 04232 transmit_response(d, req); 04233 04234 return res; 04235 }
static int handle_server_request_message | ( | struct skinny_req * | req, | |
struct skinnysession * | s | |||
) | [static] |
Definition at line 5136 of file chan_skinny.c.
References skinny_req::data, htolel, skinny_device::ourip, req_alloc(), s, server_res_message::server, SERVER_RES_MESSAGE, server_res_message::serverIpAddr, server_res_message::serverListenPort, server_identifier::serverName, skinny_data::serverres, and transmit_response().
Referenced by handle_message().
05137 { 05138 struct skinny_device *d = s->device; 05139 if (!(req = req_alloc(sizeof(struct server_res_message), SERVER_RES_MESSAGE))) 05140 return -1; 05141 05142 memcpy(req->data.serverres.server[0].serverName, ourhost, 05143 sizeof(req->data.serverres.server[0].serverName)); 05144 req->data.serverres.serverListenPort[0] = htolel(ourport); 05145 req->data.serverres.serverIpAddr[0] = htolel(d->ourip.s_addr); 05146 transmit_response(d, req); 05147 return 1; 05148 }
static char* handle_skinny_reset | ( | struct ast_cli_entry * | e, | |
int | cmd, | |||
struct ast_cli_args * | a | |||
) | [static] |
Definition at line 2595 of file chan_skinny.c.
References ast_cli_args::argc, ast_cli_args::argv, AST_LIST_LOCK, AST_LIST_TRAVERSE, AST_LIST_UNLOCK, ast_verb, CLI_GENERATE, CLI_INIT, CLI_SHOWUSAGE, CLI_SUCCESS, complete_skinny_reset(), skinny_req::data, skinny_req::e, skinny_device::id, ast_cli_args::line, ast_cli_args::n, skinny_device::name, ast_cli_args::pos, req_alloc(), skinny_data::reset, RESET_MESSAGE, reset_message::resetType, skinny_device::session, transmit_response(), and ast_cli_args::word.
02596 { 02597 struct skinny_device *d; 02598 struct skinny_req *req; 02599 02600 switch (cmd) { 02601 case CLI_INIT: 02602 e->command = "skinny reset"; 02603 e->usage = 02604 "Usage: skinny reset <DeviceId|DeviceName|all> [restart]\n" 02605 " Causes a Skinny device to reset itself, optionally with a full restart\n"; 02606 return NULL; 02607 case CLI_GENERATE: 02608 return complete_skinny_reset(a->line, a->word, a->pos, a->n); 02609 } 02610 02611 if (a->argc < 3 || a->argc > 4) 02612 return CLI_SHOWUSAGE; 02613 02614 AST_LIST_LOCK(&devices); 02615 AST_LIST_TRAVERSE(&devices, d, list) { 02616 int fullrestart = 0; 02617 if (!strcasecmp(a->argv[2], d->id) || !strcasecmp(a->argv[2], d->name) || !strcasecmp(a->argv[2], "all")) { 02618 if (!(d->session)) 02619 continue; 02620 02621 if (!(req = req_alloc(sizeof(struct reset_message), RESET_MESSAGE))) 02622 continue; 02623 02624 if (a->argc == 4 && !strcasecmp(a->argv[3], "restart")) 02625 fullrestart = 1; 02626 02627 if (fullrestart) 02628 req->data.reset.resetType = 2; 02629 else 02630 req->data.reset.resetType = 1; 02631 02632 ast_verb(3, "%s device %s.\n", (fullrestart) ? "Restarting" : "Resetting", d->id); 02633 transmit_response(d, req); 02634 } 02635 } 02636 AST_LIST_UNLOCK(&devices); 02637 return CLI_SUCCESS; 02638 }
static char* handle_skinny_set_debug | ( | struct ast_cli_entry * | e, | |
int | cmd, | |||
struct ast_cli_args * | a | |||
) | [static] |
Definition at line 2522 of file chan_skinny.c.
References ast_cli_args::argc, ast_cli_entry::args, ast_cli_args::argv, ast_cli(), CLI_GENERATE, CLI_INIT, CLI_SHOWUSAGE, CLI_SUCCESS, ast_cli_entry::command, ast_cli_args::fd, and ast_cli_entry::usage.
02523 { 02524 switch (cmd) { 02525 case CLI_INIT: 02526 e->command = "skinny set debug {on|off}"; 02527 e->usage = 02528 "Usage: skinny set debug {on|off}\n" 02529 " Enables/Disables dumping of Skinny packets for debugging purposes\n"; 02530 return NULL; 02531 case CLI_GENERATE: 02532 return NULL; 02533 } 02534 02535 if (a->argc != e->args) 02536 return CLI_SHOWUSAGE; 02537 02538 if (!strncasecmp(a->argv[e->args - 1], "on", 2)) { 02539 skinnydebug = 1; 02540 ast_cli(a->fd, "Skinny Debugging Enabled\n"); 02541 return CLI_SUCCESS; 02542 } else if (!strncasecmp(a->argv[e->args - 1], "off", 3)) { 02543 skinnydebug = 0; 02544 ast_cli(a->fd, "Skinny Debugging Disabled\n"); 02545 return CLI_SUCCESS; 02546 } else { 02547 return CLI_SHOWUSAGE; 02548 } 02549 }
static char* handle_skinny_set_debug_deprecated | ( | struct ast_cli_entry * | e, | |
int | cmd, | |||
struct ast_cli_args * | a | |||
) | [static] |
Definition at line 2493 of file chan_skinny.c.
References ast_cli_args::argc, ast_cli_args::argv, ast_cli(), CLI_GENERATE, CLI_INIT, CLI_SHOWUSAGE, CLI_SUCCESS, ast_cli_entry::command, ast_cli_args::fd, and ast_cli_entry::usage.
02494 { 02495 switch (cmd) { 02496 case CLI_INIT: 02497 e->command = "skinny set debug [off]"; 02498 e->usage = 02499 "Usage: skinny set debug [off]\n" 02500 " Enables/Disables dumping of Skinny packets for debugging purposes\n"; 02501 return NULL; 02502 case CLI_GENERATE: 02503 return NULL; 02504 } 02505 02506 if (a->argc < 3 || a->argc > 4) 02507 return CLI_SHOWUSAGE; 02508 02509 if (a->argc == 3) { 02510 skinnydebug = 1; 02511 ast_cli(a->fd, "Skinny Debugging Enabled\n"); 02512 return CLI_SUCCESS; 02513 } else if (!strncasecmp(a->argv[3], "off", 3)) { 02514 skinnydebug = 0; 02515 ast_cli(a->fd, "Skinny Debugging Disabled\n"); 02516 return CLI_SUCCESS; 02517 } else { 02518 return CLI_SHOWUSAGE; 02519 } 02520 }
static char* handle_skinny_show_device | ( | struct ast_cli_entry * | e, | |
int | cmd, | |||
struct ast_cli_args * | a | |||
) | [static] |
Show device information.
Definition at line 2789 of file chan_skinny.c.
References skinny_device::addons, ast_cli_args::argc, ast_cli_args::argv, ast_cli(), ast_inet_ntoa(), AST_LIST_LOCK, AST_LIST_TRAVERSE, AST_LIST_UNLOCK, CLI_GENERATE, CLI_INIT, CLI_SHOWUSAGE, CLI_SUCCESS, ast_cli_entry::command, complete_skinny_show_device(), device2str(), skinny_speeddial::exten, ast_cli_args::fd, skinny_device::id, skinny_speeddial::isHint, skinny_speeddial::label, skinny_line::label, ast_cli_args::line, skinny_device::lines, ast_cli_args::n, skinny_line::name, skinny_device::name, ast_cli_args::pos, skinny_device::registered, S_OR, skinny_device::session, skinnysession::sin, skinny_device::speeddials, skinny_addon::type, skinny_device::type, ast_cli_entry::usage, skinny_device::version_id, and ast_cli_args::word.
02790 { 02791 struct skinny_device *d; 02792 struct skinny_line *l; 02793 struct skinny_speeddial *sd; 02794 struct skinny_addon *sa; 02795 02796 switch (cmd) { 02797 case CLI_INIT: 02798 e->command = "skinny show device"; 02799 e->usage = 02800 "Usage: skinny show device <DeviceId|DeviceName>\n" 02801 " Lists all deviceinformation of a specific device known to the Skinny subsystem.\n"; 02802 return NULL; 02803 case CLI_GENERATE: 02804 return complete_skinny_show_device(a->line, a->word, a->pos, a->n); 02805 } 02806 02807 if (a->argc < 4) 02808 return CLI_SHOWUSAGE; 02809 02810 AST_LIST_LOCK(&devices); 02811 AST_LIST_TRAVERSE(&devices, d, list) { 02812 if (!strcasecmp(a->argv[3], d->id) || !strcasecmp(a->argv[3], d->name)) { 02813 int numlines = 0, numaddons = 0, numspeeddials = 0; 02814 02815 AST_LIST_TRAVERSE(&d->lines, l, list){ 02816 numlines++; 02817 } 02818 02819 ast_cli(a->fd, "Name: %s\n", d->name); 02820 ast_cli(a->fd, "Id: %s\n", d->id); 02821 ast_cli(a->fd, "version: %s\n", S_OR(d->version_id, "Unknown")); 02822 ast_cli(a->fd, "Ip address: %s\n", (d->session ? ast_inet_ntoa(d->session->sin.sin_addr) : "Unknown")); 02823 ast_cli(a->fd, "Port: %d\n", (d->session ? ntohs(d->session->sin.sin_port) : 0)); 02824 ast_cli(a->fd, "Device Type: %s\n", device2str(d->type)); 02825 ast_cli(a->fd, "Registered: %s\n", (d->registered ? "Yes" : "No")); 02826 ast_cli(a->fd, "Lines: %d\n", numlines); 02827 AST_LIST_TRAVERSE(&d->lines, l, list) { 02828 ast_cli(a->fd, " %s (%s)\n", l->name, l->label); 02829 } 02830 AST_LIST_TRAVERSE(&d->addons, sa, list) { 02831 numaddons++; 02832 } 02833 ast_cli(a->fd, "Addons: %d\n", numaddons); 02834 AST_LIST_TRAVERSE(&d->addons, sa, list) { 02835 ast_cli(a->fd, " %s\n", sa->type); 02836 } 02837 AST_LIST_TRAVERSE(&d->speeddials, sd, list) { 02838 numspeeddials++; 02839 } 02840 ast_cli(a->fd, "Speeddials: %d\n", numspeeddials); 02841 AST_LIST_TRAVERSE(&d->speeddials, sd, list) { 02842 ast_cli(a->fd, " %s (%s) ishint: %d\n", sd->exten, sd->label, sd->isHint); 02843 } 02844 } 02845 } 02846 AST_LIST_UNLOCK(&devices); 02847 return CLI_SUCCESS; 02848 }
static char* handle_skinny_show_devices | ( | struct ast_cli_entry * | e, | |
int | cmd, | |||
struct ast_cli_args * | a | |||
) | [static] |
Definition at line 2747 of file chan_skinny.c.
References ast_cli_args::argc, ast_cli(), ast_inet_ntoa(), AST_LIST_LOCK, AST_LIST_TRAVERSE, AST_LIST_UNLOCK, CLI_GENERATE, CLI_INIT, CLI_SHOWUSAGE, CLI_SUCCESS, ast_cli_entry::command, device2str(), ast_cli_args::fd, skinny_device::id, skinny_device::lines, skinny_device::name, skinny_device::registered, skinny_device::session, skinnysession::sin, skinny_device::type, and ast_cli_entry::usage.
02748 { 02749 struct skinny_device *d; 02750 struct skinny_line *l; 02751 02752 switch (cmd) { 02753 case CLI_INIT: 02754 e->command = "skinny show devices"; 02755 e->usage = 02756 "Usage: skinny show devices\n" 02757 " Lists all devices known to the Skinny subsystem.\n"; 02758 return NULL; 02759 case CLI_GENERATE: 02760 return NULL; 02761 } 02762 02763 if (a->argc != 3) 02764 return CLI_SHOWUSAGE; 02765 02766 ast_cli(a->fd, "Name DeviceId IP Type R NL\n"); 02767 ast_cli(a->fd, "-------------------- ---------------- --------------- --------------- - --\n"); 02768 02769 AST_LIST_LOCK(&devices); 02770 AST_LIST_TRAVERSE(&devices, d, list) { 02771 int numlines = 0; 02772 AST_LIST_TRAVERSE(&d->lines, l, list) { 02773 numlines++; 02774 } 02775 02776 ast_cli(a->fd, "%-20s %-16s %-15s %-15s %c %2d\n", 02777 d->name, 02778 d->id, 02779 d->session?ast_inet_ntoa(d->session->sin.sin_addr):"", 02780 device2str(d->type), 02781 d->registered?'Y':'N', 02782 numlines); 02783 } 02784 AST_LIST_UNLOCK(&devices); 02785 return CLI_SUCCESS; 02786 }
static char* handle_skinny_show_line | ( | struct ast_cli_entry * | e, | |
int | cmd, | |||
struct ast_cli_args * | a | |||
) | [static] |
List line information.
Definition at line 2887 of file chan_skinny.c.
References skinny_line::accountcode, skinny_line::amaflags, ast_cli_args::argc, ast_cli_args::argv, ast_cdr_flags2str(), ast_cli(), ast_getformatname_multiple(), AST_LIST_LOCK, AST_LIST_TRAVERSE, AST_LIST_UNLOCK, ast_print_group(), skinny_line::call_forward_all, skinny_line::call_forward_busy, skinny_line::call_forward_noanswer, skinny_line::callgroup, skinny_line::callwaiting, skinny_line::cancallforward, skinny_line::capability, skinny_line::cfwdtype, skinny_line::cid_name, skinny_line::cid_num, CLI_GENERATE, CLI_INIT, CLI_SHOWUSAGE, CLI_SUCCESS, ast_cli_entry::command, complete_skinny_show_line(), skinny_line::context, skinny_line::dnd, skinny_line::exten, ast_cli_args::fd, skinny_line::group, skinny_line::hidecallerid, skinny_device::id, skinny_line::immediate, skinny_line::label, skinny_line::language, skinny_line::lastcallerid, skinny_line::lastnumberdialed, ast_cli_args::line, skinny_device::lines, skinny_line::mailbox, skinny_line::mohinterpret, skinny_line::mohsuggest, skinny_line::mwiblink, ast_cli_args::n, skinny_line::name, skinny_device::name, skinny_line::nat, skinny_line::pickupgroup, ast_cli_args::pos, skinny_line::prefs, print_codec_to_cli(), skinny_line::regcontext, skinny_line::regexten, S_COR, S_OR, SKINNY_CFWD_ALL, SKINNY_CFWD_BUSY, SKINNY_CFWD_NOANSWER, skinny_line::threewaycalling, skinny_line::transfer, ast_cli_entry::usage, skinny_line::vmexten, and ast_cli_args::word.
02888 { 02889 struct skinny_device *d; 02890 struct skinny_line *l; 02891 char codec_buf[512]; 02892 char group_buf[256]; 02893 02894 switch (cmd) { 02895 case CLI_INIT: 02896 e->command = "skinny show line"; 02897 e->usage = 02898 "Usage: skinny show line <Line> [ on <DeviceID|DeviceName> ]\n" 02899 " List all lineinformation of a specific line known to the Skinny subsystem.\n"; 02900 return NULL; 02901 case CLI_GENERATE: 02902 return complete_skinny_show_line(a->line, a->word, a->pos, a->n); 02903 } 02904 02905 if (a->argc < 4) 02906 return CLI_SHOWUSAGE; 02907 02908 AST_LIST_LOCK(&devices); 02909 02910 /* Show all lines matching the one supplied */ 02911 AST_LIST_TRAVERSE(&devices, d, list) { 02912 if (a->argc == 6 && (strcasecmp(a->argv[5], d->id) && strcasecmp(a->argv[5], d->name))) 02913 continue; 02914 AST_LIST_TRAVERSE(&d->lines, l, list) { 02915 if (strcasecmp(a->argv[3], l->name)) 02916 continue; 02917 ast_cli(a->fd, "Line: %s\n", l->name); 02918 ast_cli(a->fd, "On Device: %s\n", d->name); 02919 ast_cli(a->fd, "Line Label: %s\n", l->label); 02920 ast_cli(a->fd, "Extension: %s\n", S_OR(l->exten, "<not set>")); 02921 ast_cli(a->fd, "Context: %s\n", l->context); 02922 ast_cli(a->fd, "CallGroup: %s\n", ast_print_group(group_buf, sizeof(group_buf), l->callgroup)); 02923 ast_cli(a->fd, "PickupGroup: %s\n", ast_print_group(group_buf, sizeof(group_buf), l->pickupgroup)); 02924 ast_cli(a->fd, "Language: %s\n", S_OR(l->language, "<not set>")); 02925 ast_cli(a->fd, "Accountcode: %s\n", S_OR(l->accountcode, "<not set>")); 02926 ast_cli(a->fd, "AmaFlag: %s\n", ast_cdr_flags2str(l->amaflags)); 02927 ast_cli(a->fd, "CallerId Number: %s\n", S_OR(l->cid_num, "<not set>")); 02928 ast_cli(a->fd, "CallerId Name: %s\n", S_OR(l->cid_name, "<not set>")); 02929 ast_cli(a->fd, "Hide CallerId: %s\n", (l->hidecallerid ? "Yes" : "No")); 02930 ast_cli(a->fd, "CFwdAll: %s\n", S_COR((l->cfwdtype & SKINNY_CFWD_ALL), l->call_forward_all, "<not set>")); 02931 ast_cli(a->fd, "CFwdBusy: %s\n", S_COR((l->cfwdtype & SKINNY_CFWD_BUSY), l->call_forward_busy, "<not set>")); 02932 ast_cli(a->fd, "CFwdNoAnswer: %s\n", S_COR((l->cfwdtype & SKINNY_CFWD_NOANSWER), l->call_forward_noanswer, "<not set>")); 02933 ast_cli(a->fd, "VoicemailBox: %s\n", S_OR(l->mailbox, "<not set>")); 02934 ast_cli(a->fd, "VoicemailNumber: %s\n", S_OR(l->vmexten, "<not set>")); 02935 ast_cli(a->fd, "MWIblink: %d\n", l->mwiblink); 02936 ast_cli(a->fd, "Regextension: %s\n", S_OR(l->regexten, "<not set>")); 02937 ast_cli(a->fd, "Regcontext: %s\n", S_OR(l->regcontext, "<not set>")); 02938 ast_cli(a->fd, "MoHInterpret: %s\n", S_OR(l->mohinterpret, "<not set>")); 02939 ast_cli(a->fd, "MoHSuggest: %s\n", S_OR(l->mohsuggest, "<not set>")); 02940 ast_cli(a->fd, "Last dialed nr: %s\n", S_OR(l->lastnumberdialed, "<no calls made yet>")); 02941 ast_cli(a->fd, "Last CallerID: %s\n", S_OR(l->lastcallerid, "<not set>")); 02942 ast_cli(a->fd, "Transfer enabled: %s\n", (l->transfer ? "Yes" : "No")); 02943 ast_cli(a->fd, "Callwaiting: %s\n", (l->callwaiting ? "Yes" : "No")); 02944 ast_cli(a->fd, "3Way Calling: %s\n", (l->threewaycalling ? "Yes" : "No")); 02945 ast_cli(a->fd, "Can forward: %s\n", (l->cancallforward ? "Yes" : "No")); 02946 ast_cli(a->fd, "Do Not Disturb: %s\n", (l->dnd ? "Yes" : "No")); 02947 ast_cli(a->fd, "NAT: %s\n", (l->nat ? "Yes" : "No")); 02948 ast_cli(a->fd, "immediate: %s\n", (l->immediate ? "Yes" : "No")); 02949 ast_cli(a->fd, "Group: %d\n", l->group); 02950 ast_cli(a->fd, "Codecs: "); 02951 ast_getformatname_multiple(codec_buf, sizeof(codec_buf) - 1, l->capability); 02952 ast_cli(a->fd, "%s\n", codec_buf); 02953 ast_cli(a->fd, "Codec Order: ("); 02954 print_codec_to_cli(a->fd, &l->prefs); 02955 ast_cli(a->fd, ")\n"); 02956 ast_cli(a->fd, "\n"); 02957 } 02958 } 02959 02960 AST_LIST_UNLOCK(&devices); 02961 return CLI_SUCCESS; 02962 }
static char* handle_skinny_show_lines | ( | struct ast_cli_entry * | e, | |
int | cmd, | |||
struct ast_cli_args * | a | |||
) | [static] |
Definition at line 2850 of file chan_skinny.c.
References ast_cli_args::argc, ast_cli(), AST_LIST_LOCK, AST_LIST_TRAVERSE, AST_LIST_UNLOCK, CLI_GENERATE, CLI_INIT, CLI_SHOWUSAGE, CLI_SUCCESS, ast_cli_entry::command, ast_cli_args::fd, skinny_line::instance, skinny_line::label, skinny_device::lines, skinny_line::name, skinny_device::name, and ast_cli_entry::usage.
02851 { 02852 struct skinny_device *d; 02853 struct skinny_line *l; 02854 02855 switch (cmd) { 02856 case CLI_INIT: 02857 e->command = "skinny show lines"; 02858 e->usage = 02859 "Usage: skinny show lines\n" 02860 " Lists all lines known to the Skinny subsystem.\n"; 02861 return NULL; 02862 case CLI_GENERATE: 02863 return NULL; 02864 } 02865 02866 if (a->argc != 3) 02867 return CLI_SHOWUSAGE; 02868 02869 02870 ast_cli(a->fd, "Device Name Instance Name Label \n"); 02871 ast_cli(a->fd, "-------------------- -------- -------------------- --------------------\n"); 02872 AST_LIST_LOCK(&devices); 02873 AST_LIST_TRAVERSE(&devices, d, list) { 02874 AST_LIST_TRAVERSE(&d->lines, l, list) { 02875 ast_cli(a->fd, "%-20s %8d %-20s %-20s\n", 02876 d->name, 02877 l->instance, 02878 l->name, 02879 l->label); 02880 } 02881 } 02882 AST_LIST_UNLOCK(&devices); 02883 return CLI_SUCCESS; 02884 }
static char* handle_skinny_show_settings | ( | struct ast_cli_entry * | e, | |
int | cmd, | |||
struct ast_cli_args * | a | |||
) | [static] |
List global settings for the Skinny subsystem.
Definition at line 2965 of file chan_skinny.c.
References ast_cli_args::argc, ast_cli(), ast_inet_ntoa(), AST_JB_ENABLED, AST_JB_FORCED, AST_JB_LOG, ast_test_flag, CLI_GENERATE, CLI_INIT, CLI_SHOWUSAGE, CLI_SUCCESS, ast_cli_entry::command, ast_cli_args::fd, global_jbconf, ast_jb_conf::impl, ast_jb_conf::max_size, ast_jb_conf::resync_threshold, S_OR, and ast_cli_entry::usage.
02966 { 02967 switch (cmd) { 02968 case CLI_INIT: 02969 e->command = "skinny show settings"; 02970 e->usage = 02971 "Usage: skinny show settings\n" 02972 " Lists all global configuration settings of the Skinny subsystem.\n"; 02973 return NULL; 02974 case CLI_GENERATE: 02975 return NULL; 02976 } 02977 02978 if (a->argc != 3) 02979 return CLI_SHOWUSAGE; 02980 02981 ast_cli(a->fd, "\nGlobal Settings:\n"); 02982 ast_cli(a->fd, " Skinny Port: %d\n", ntohs(bindaddr.sin_port)); 02983 ast_cli(a->fd, " Bindaddress: %s\n", ast_inet_ntoa(bindaddr.sin_addr)); 02984 ast_cli(a->fd, " KeepAlive: %d\n", keep_alive); 02985 ast_cli(a->fd, " Date Format: %s\n", date_format); 02986 ast_cli(a->fd, " Voice Mail Extension: %s\n", S_OR(vmexten, "(not set)")); 02987 ast_cli(a->fd, " Reg. context: %s\n", S_OR(regcontext, "(not set)")); 02988 ast_cli(a->fd, " Jitterbuffer enabled: %s\n", (ast_test_flag(&global_jbconf, AST_JB_ENABLED) ? "Yes" : "No")); 02989 ast_cli(a->fd, " Jitterbuffer forced: %s\n", (ast_test_flag(&global_jbconf, AST_JB_FORCED) ? "Yes" : "No")); 02990 ast_cli(a->fd, " Jitterbuffer max size: %ld\n", global_jbconf.max_size); 02991 ast_cli(a->fd, " Jitterbuffer resync: %ld\n", global_jbconf.resync_threshold); 02992 ast_cli(a->fd, " Jitterbuffer impl: %s\n", global_jbconf.impl); 02993 ast_cli(a->fd, " Jitterbuffer log: %s\n", (ast_test_flag(&global_jbconf, AST_JB_LOG) ? "Yes" : "No")); 02994 02995 return CLI_SUCCESS; 02996 }
static int handle_soft_key_event_message | ( | struct skinny_req * | req, | |
struct skinnysession * | s | |||
) | [static] |
Definition at line 5309 of file chan_skinny.c.
References ast_channel::_state, skinny_subchannel::alreadygone, ast_bridged_channel(), AST_CONTROL_ANSWER, ast_copy_string(), ast_debug, AST_DEVICE_INUSE, AST_DEVICE_NOT_INUSE, ast_devstate_changed(), ast_hangup(), ast_ignore_pattern(), AST_LIST_NEXT, AST_LIST_REMOVE, ast_log(), ast_masq_park_call(), ast_pthread_create, ast_queue_control(), ast_queue_hangup(), ast_setstate(), AST_STATE_DOWN, AST_STATE_RING, AST_STATE_UP, ast_strlen_zero(), ast_verb, skinny_subchannel::blindxfer, skinny_subchannel::callid, soft_key_event_message::callreference, ast_channel::context, skinny_subchannel::cxmode, skinny_req::data, skinny_line::dnd, do_housekeeping(), errno, ast_channel::exten, find_line_by_instance(), find_subchannel_by_instance_reference(), handle_callforward_button(), handle_hold_button(), handle_transfer_button(), skinny_line::hookstate, skinny_line::instance, soft_key_event_message::instance, KEYDEF_CONNECTED, KEYDEF_OFFHOOK, KEYDEF_ONHOLD, KEYDEF_RINGOUT, skinny_device::lastcallreference, skinny_device::lastlineinstance, skinny_line::lastnumberdialed, letohl, LOG_WARNING, skinny_device::name, skinny_line::name, skinny_subchannel::onhold, skinny_subchannel::outgoing, skinny_subchannel::owner, skinny_subchannel::related, skinny_subchannel::rtp, s, SKINNY_CFWD_ALL, SKINNY_CFWD_BUSY, SKINNY_CFWD_NOANSWER, SKINNY_CONNECTED, SKINNY_CX_RECVONLY, SKINNY_DIALTONE, skinny_hold(), SKINNY_LAMP_OFF, SKINNY_LAMP_ON, skinny_new(), skinny_newcall(), SKINNY_OFFHOOK, SKINNY_ONHOOK, SKINNY_RING_OFF, SKINNY_SILENCE, SKINNY_SPEAKEROFF, SKINNY_SPEAKERON, skinny_ss(), skinny_unhold(), SOFTKEY_ANSWER, SOFTKEY_BKSPC, SOFTKEY_CFWDALL, SOFTKEY_CFWDBUSY, SOFTKEY_CFWDNOANSWER, SOFTKEY_CONFRN, SOFTKEY_DND, SOFTKEY_ENDCALL, SOFTKEY_GPICKUP, SOFTKEY_HOLD, SOFTKEY_INFO, SOFTKEY_JOIN, SOFTKEY_MEETME, SOFTKEY_NEWCALL, SOFTKEY_NONE, SOFTKEY_PARK, SOFTKEY_PICKUP, SOFTKEY_REDIAL, SOFTKEY_RESUME, SOFTKEY_TRNSFER, soft_key_event_message::softKeyEvent, skinny_data::softkeyeventmessage, start_rtp(), STIMULUS_DND, STIMULUS_LINE, skinny_line::sub, ast_channel::tech_pvt, skinny_line::transfer, transmit_callstate(), transmit_callstateonly(), transmit_displaymessage(), transmit_displaynotify(), transmit_lamp_indication(), transmit_ringer_mode(), transmit_selectsoftkeys(), transmit_speaker_mode(), transmit_tone(), and skinny_subchannel::xferor.
Referenced by handle_message().
05310 { 05311 struct skinny_device *d = s->device; 05312 struct skinny_line *l; 05313 struct skinny_subchannel *sub = NULL; 05314 struct ast_channel *c; 05315 pthread_t t; 05316 int event; 05317 int instance; 05318 int callreference; 05319 05320 event = letohl(req->data.softkeyeventmessage.softKeyEvent); 05321 instance = letohl(req->data.softkeyeventmessage.instance); 05322 callreference = letohl(req->data.softkeyeventmessage.callreference); 05323 05324 if (instance) { 05325 l = find_line_by_instance(d, instance); 05326 if (callreference) { 05327 sub = find_subchannel_by_instance_reference(d, instance, callreference); 05328 } else { 05329 sub = find_subchannel_by_instance_reference(d, instance, d->lastcallreference); 05330 } 05331 } else { 05332 l = find_line_by_instance(d, d->lastlineinstance); 05333 } 05334 05335 if (!l) { 05336 if (skinnydebug) 05337 ast_verb(1, "Received Softkey Event: %d(%d/%d)\n", event, instance, callreference); 05338 return 0; 05339 } 05340 05341 ast_devstate_changed(AST_DEVICE_INUSE, "Skinny/%s@%s", l->name, d->name); 05342 05343 switch(event) { 05344 case SOFTKEY_NONE: 05345 if (skinnydebug) 05346 ast_verb(1, "Received Softkey Event: None(%d/%d)\n", instance, callreference); 05347 break; 05348 case SOFTKEY_REDIAL: 05349 if (skinnydebug) 05350 ast_verb(1, "Received Softkey Event: Redial(%d/%d)\n", instance, callreference); 05351 05352 if (ast_strlen_zero(l->lastnumberdialed)) { 05353 ast_log(LOG_WARNING, "Attempted redial, but no previously dialed number found.\n"); 05354 l->hookstate = SKINNY_ONHOOK; 05355 transmit_speaker_mode(d, SKINNY_SPEAKEROFF); 05356 transmit_callstate(d, l->instance, SKINNY_ONHOOK, instance); 05357 break; 05358 } 05359 05360 if (!sub || !sub->owner) { 05361 c = skinny_new(l, AST_STATE_DOWN); 05362 } else { 05363 c = sub->owner; 05364 } 05365 05366 if (!c) { 05367 ast_log(LOG_WARNING, "Unable to create channel for %s@%s\n", l->name, d->name); 05368 } else { 05369 sub = c->tech_pvt; 05370 if (l->hookstate == SKINNY_ONHOOK) { 05371 l->hookstate = SKINNY_OFFHOOK; 05372 transmit_speaker_mode(d, SKINNY_SPEAKERON); 05373 transmit_callstate(d, l->instance, SKINNY_OFFHOOK, sub->callid); 05374 } 05375 if (skinnydebug) 05376 ast_verb(1, "Attempting to Clear display on Skinny %s@%s\n", l->name, d->name); 05377 transmit_displaymessage(d, NULL, l->instance, sub->callid); /* clear display */ 05378 transmit_tone(d, SKINNY_DIALTONE, l->instance, sub->callid); 05379 transmit_selectsoftkeys(d, l->instance, sub->callid, KEYDEF_RINGOUT); 05380 05381 if (!ast_ignore_pattern(c->context, l->lastnumberdialed)) { 05382 transmit_tone(d, SKINNY_SILENCE, l->instance, sub->callid); 05383 } 05384 ast_copy_string(c->exten, l->lastnumberdialed, sizeof(c->exten)); 05385 if (ast_pthread_create(&t, NULL, skinny_newcall, c)) { 05386 ast_log(LOG_WARNING, "Unable to create new call thread: %s\n", strerror(errno)); 05387 ast_hangup(c); 05388 } 05389 } 05390 break; 05391 case SOFTKEY_NEWCALL: /* Actually the DIAL softkey */ 05392 if (skinnydebug) 05393 ast_verb(1, "Received Softkey Event: New Call(%d/%d)\n", instance, callreference); 05394 05395 /* New Call ALWAYS gets a new sub-channel */ 05396 c = skinny_new(l, AST_STATE_DOWN); 05397 sub = c->tech_pvt; 05398 05399 /* transmit_ringer_mode(d, SKINNY_RING_OFF); 05400 transmit_lamp_indication(d, STIMULUS_LINE, l->instance, SKINNY_LAMP_ON); */ 05401 05402 /* l->hookstate = SKINNY_OFFHOOK; */ 05403 05404 if (!c) { 05405 ast_log(LOG_WARNING, "Unable to create channel for %s@%s\n", l->name, d->name); 05406 } else { 05407 sub = c->tech_pvt; 05408 if (l->hookstate == SKINNY_ONHOOK) { 05409 l->hookstate = SKINNY_OFFHOOK; 05410 transmit_speaker_mode(d, SKINNY_SPEAKERON); 05411 } 05412 ast_verb(1, "Call-id: %d\n", sub->callid); 05413 05414 transmit_callstate(d, l->instance, SKINNY_OFFHOOK, sub->callid); 05415 05416 if (skinnydebug) 05417 ast_verb(1, "Attempting to Clear display on Skinny %s@%s\n", l->name, d->name); 05418 transmit_displaymessage(d, NULL, l->instance, sub->callid); /* clear display */ 05419 transmit_tone(d, SKINNY_DIALTONE, l->instance, sub->callid); 05420 transmit_selectsoftkeys(d, l->instance, sub->callid, KEYDEF_OFFHOOK); 05421 05422 /* start the switch thread */ 05423 if (ast_pthread_create(&t, NULL, skinny_ss, c)) { 05424 ast_log(LOG_WARNING, "Unable to create switch thread: %s\n", strerror(errno)); 05425 ast_hangup(c); 05426 } 05427 } 05428 break; 05429 case SOFTKEY_HOLD: 05430 if (skinnydebug) 05431 ast_verb(1, "Received Softkey Event: Hold(%d/%d)\n", instance, callreference); 05432 handle_hold_button(sub); 05433 break; 05434 case SOFTKEY_TRNSFER: 05435 if (skinnydebug) 05436 ast_verb(1, "Received Softkey Event: Transfer(%d/%d)\n", instance, callreference); 05437 if (l->transfer) 05438 handle_transfer_button(sub); 05439 else 05440 transmit_displaynotify(d, "Transfer disabled", 10); 05441 05442 break; 05443 case SOFTKEY_DND: 05444 if (skinnydebug) 05445 ast_verb(1, "Received Softkey Event: DND(%d/%d)\n", instance, callreference); 05446 05447 /* Do not disturb */ 05448 if (l->dnd != 0){ 05449 ast_verb(3, "Disabling DND on %s@%s\n", l->name, d->name); 05450 l->dnd = 0; 05451 transmit_lamp_indication(d, STIMULUS_DND, 1, SKINNY_LAMP_ON); 05452 transmit_displaynotify(d, "DnD disabled", 10); 05453 } else { 05454 ast_verb(3, "Enabling DND on %s@%s\n", l->name, d->name); 05455 l->dnd = 1; 05456 transmit_lamp_indication(d, STIMULUS_DND, 1, SKINNY_LAMP_OFF); 05457 transmit_displaynotify(d, "DnD enabled", 10); 05458 } 05459 break; 05460 case SOFTKEY_CFWDALL: 05461 if (skinnydebug) 05462 ast_verb(1, "Received Softkey Event: Forward All(%d/%d)\n", instance, callreference); 05463 05464 if (!sub || !sub->owner) { 05465 c = skinny_new(l, AST_STATE_DOWN); 05466 } else { 05467 c = sub->owner; 05468 } 05469 05470 if (!c) { 05471 ast_log(LOG_WARNING, "Unable to create channel for %s@%s\n", l->name, d->name); 05472 } else { 05473 sub = c->tech_pvt; 05474 handle_callforward_button(sub, SKINNY_CFWD_ALL); 05475 } 05476 break; 05477 case SOFTKEY_CFWDBUSY: 05478 if (skinnydebug) 05479 ast_verb(1, "Received Softkey Event: Forward Busy (%d/%d)\n", instance, callreference); 05480 05481 if (!sub || !sub->owner) { 05482 c = skinny_new(l, AST_STATE_DOWN); 05483 } else { 05484 c = sub->owner; 05485 } 05486 05487 if (!c) { 05488 ast_log(LOG_WARNING, "Unable to create channel for %s@%s\n", l->name, d->name); 05489 } else { 05490 sub = c->tech_pvt; 05491 handle_callforward_button(sub, SKINNY_CFWD_BUSY); 05492 } 05493 break; 05494 case SOFTKEY_CFWDNOANSWER: 05495 if (skinnydebug) 05496 ast_verb(1, "Received Softkey Event: Forward No Answer (%d/%d)\n", instance, callreference); 05497 05498 #if 0 /* Not sure how to handle this yet */ 05499 if (!sub || !sub->owner) { 05500 c = skinny_new(l, AST_STATE_DOWN); 05501 } else { 05502 c = sub->owner; 05503 } 05504 05505 if (!c) { 05506 ast_log(LOG_WARNING, "Unable to create channel for %s@%s\n", l->name, d->name); 05507 } else { 05508 sub = c->tech_pvt; 05509 handle_callforward_button(sub, SKINNY_CFWD_NOANSWER); 05510 } 05511 #endif 05512 break; 05513 case SOFTKEY_BKSPC: 05514 if (skinnydebug) 05515 ast_verb(1, "Received Softkey Event: Backspace(%d/%d)\n", instance, callreference); 05516 break; 05517 case SOFTKEY_ENDCALL: 05518 if (skinnydebug) 05519 ast_verb(1, "Received Softkey Event: End Call(%d/%d)\n", instance, callreference); 05520 05521 if (l->hookstate == SKINNY_ONHOOK) { 05522 /* Something else already put us back on hook */ 05523 break; 05524 } 05525 if (sub) { 05526 int onlysub = 0; 05527 05528 if (!AST_LIST_NEXT(sub, list)) { 05529 onlysub = 1; 05530 } else { 05531 AST_LIST_REMOVE(&l->sub, sub, list); 05532 } 05533 05534 sub->cxmode = SKINNY_CX_RECVONLY; 05535 if (onlysub || sub->xferor){ /*Are there other calls to this device */ 05536 l->hookstate = SKINNY_ONHOOK; 05537 if (skinnydebug) 05538 ast_debug(1, "Skinny %s@%s-%d went on hook\n", l->name, d->name, callreference); 05539 } 05540 05541 transmit_callstate(d, l->instance, l->hookstate, sub->callid); 05542 ast_devstate_changed(AST_DEVICE_NOT_INUSE, "Skinny/%s@%s", l->name, d->name); 05543 if (skinnydebug) 05544 ast_verb(1, "Skinny %s@%s went on hook\n", l->name, d->name); 05545 if (l->transfer && sub->xferor && sub->owner->_state >= AST_STATE_RING) { 05546 /* We're allowed to transfer, we have two active calls and 05547 we made at least one of the calls. Let's try and transfer */ 05548 handle_transfer_button(sub); 05549 } else { 05550 /* Hangup the current call */ 05551 /* If there is another active call, skinny_hangup will ring the phone with the other call */ 05552 if (sub->xferor && sub->related){ 05553 sub->related->related = NULL; 05554 sub->related->blindxfer = 0; 05555 } 05556 05557 if (sub->owner) { 05558 sub->alreadygone = 1; 05559 ast_queue_hangup(sub->owner); 05560 } else { 05561 ast_log(LOG_WARNING, "Skinny(%s@%s-%d) channel already destroyed\n", 05562 l->name, d->name, sub->callid); 05563 } 05564 } 05565 if ((l->hookstate == SKINNY_ONHOOK) && (AST_LIST_NEXT(sub, list) && !AST_LIST_NEXT(sub, list)->rtp)) { 05566 do_housekeeping(s); 05567 ast_devstate_changed(AST_DEVICE_NOT_INUSE, "Skinny/%s@%s", l->name, d->name); 05568 } 05569 } 05570 break; 05571 case SOFTKEY_RESUME: 05572 if (skinnydebug) 05573 ast_verb(1, "Received Softkey Event: Resume(%d/%d)\n", instance, callreference); 05574 05575 if (sub) { 05576 if (sub->onhold) { 05577 skinny_unhold(sub); 05578 transmit_selectsoftkeys(d, l->instance, sub->callid, KEYDEF_CONNECTED); 05579 } else { 05580 skinny_hold(sub); 05581 transmit_selectsoftkeys(d, l->instance, sub->callid, KEYDEF_ONHOLD); 05582 } 05583 } 05584 05585 break; 05586 case SOFTKEY_ANSWER: 05587 if (skinnydebug) 05588 ast_verb(1, "Received Softkey Event: Answer(%d/%d)\n", instance, callreference); 05589 05590 transmit_ringer_mode(d, SKINNY_RING_OFF); 05591 transmit_lamp_indication(d, STIMULUS_LINE, l->instance, SKINNY_LAMP_ON); 05592 if (l->hookstate == SKINNY_ONHOOK) { 05593 transmit_speaker_mode(d, SKINNY_SPEAKERON); 05594 l->hookstate = SKINNY_OFFHOOK; 05595 } 05596 05597 if (sub && sub->outgoing) { 05598 /* We're answering a ringing call */ 05599 ast_queue_control(sub->owner, AST_CONTROL_ANSWER); 05600 transmit_callstate(d, l->instance, SKINNY_OFFHOOK, sub->callid); 05601 transmit_tone(d, SKINNY_SILENCE, l->instance, sub->callid); 05602 transmit_callstateonly(d, sub, SKINNY_CONNECTED); 05603 transmit_selectsoftkeys(d, l->instance, sub->callid, KEYDEF_CONNECTED); 05604 start_rtp(sub); 05605 ast_setstate(sub->owner, AST_STATE_UP); 05606 } 05607 break; 05608 case SOFTKEY_INFO: 05609 if (skinnydebug) 05610 ast_verb(1, "Received Softkey Event: Info(%d/%d)\n", instance, callreference); 05611 break; 05612 case SOFTKEY_CONFRN: 05613 if (skinnydebug) 05614 ast_verb(1, "Received Softkey Event: Conference(%d/%d)\n", instance, callreference); 05615 /* XXX determine the best way to pull off a conference. Meetme? */ 05616 break; 05617 case SOFTKEY_PARK: 05618 { 05619 int extout; 05620 char message[32]; 05621 05622 if (skinnydebug) 05623 ast_verb(1, "Received Softkey Event: Park Call(%d/%d)\n", instance, callreference); 05624 05625 if ((sub && sub->owner) && (sub->owner->_state == AST_STATE_UP)){ 05626 c = sub->owner; 05627 if (!ast_masq_park_call(ast_bridged_channel(c), c, 0, &extout)) { 05628 snprintf(message, sizeof(message), "Call Parked at: %d", extout); 05629 transmit_displaynotify(d, message, 10); 05630 } else { 05631 transmit_displaynotify(d, "Call Park failed", 10); 05632 } 05633 } else { 05634 transmit_displaynotify(d, "Call Park not available", 10); 05635 } 05636 } 05637 break; 05638 case SOFTKEY_JOIN: 05639 if (skinnydebug) 05640 ast_verb(1, "Received Softkey Event: Join(%d/%d)\n", instance, callreference); 05641 break; 05642 case SOFTKEY_MEETME: 05643 /* XXX How is this different from CONFRN? */ 05644 if (skinnydebug) 05645 ast_verb(1, "Received Softkey Event: Meetme(%d/%d)\n", instance, callreference); 05646 break; 05647 case SOFTKEY_PICKUP: 05648 if (skinnydebug) 05649 ast_verb(1, "Received Softkey Event: Pickup(%d/%d)\n", instance, callreference); 05650 break; 05651 case SOFTKEY_GPICKUP: 05652 if (skinnydebug) 05653 ast_verb(1, "Received Softkey Event: Group Pickup(%d/%d)\n", instance, callreference); 05654 break; 05655 default: 05656 if (skinnydebug) 05657 ast_verb(1, "Received unknown Softkey Event: %d(%d/%d)\n", event, instance, callreference); 05658 break; 05659 } 05660 05661 return 1; 05662 }
static int handle_soft_key_set_req_message | ( | struct skinny_req * | req, | |
struct skinnysession * | s | |||
) | [static] |
Definition at line 5276 of file chan_skinny.c.
References soft_key_definitions::count, skinny_req::data, soft_key_definitions::defaults, htolel, KEYDEF_ONHOOK, soft_key_definitions::mode, req_alloc(), s, soft_key_default_definitions, SOFT_KEY_SET_RES_MESSAGE, soft_key_template_default, soft_key_set_definition::softKeyInfoIndex, soft_key_set_res_message::softKeySetCount, soft_key_set_res_message::softKeySetDefinition, soft_key_set_res_message::softKeySetOffset, skinny_data::softkeysets, soft_key_set_res_message::totalSoftKeySetCount, transmit_response(), and transmit_selectsoftkeys().
Referenced by handle_message().
05277 { 05278 int i; 05279 int x; 05280 int y; 05281 const struct soft_key_definitions *softkeymode = soft_key_default_definitions; 05282 struct skinny_device *d = s->device; 05283 05284 if (!(req = req_alloc(sizeof(struct soft_key_set_res_message), SOFT_KEY_SET_RES_MESSAGE))) 05285 return -1; 05286 05287 req->data.softkeysets.softKeySetOffset = htolel(0); 05288 req->data.softkeysets.softKeySetCount = htolel(11); 05289 req->data.softkeysets.totalSoftKeySetCount = htolel(11); 05290 for (x = 0; x < sizeof(soft_key_default_definitions) / sizeof(struct soft_key_definitions); x++) { 05291 const uint8_t *defaults = softkeymode->defaults; 05292 /* XXX I wanted to get the size of the array dynamically, but that wasn't wanting to work. 05293 This will have to do for now. */ 05294 for (y = 0; y < softkeymode->count; y++) { 05295 for (i = 0; i < (sizeof(soft_key_template_default) / sizeof(struct soft_key_template_definition)); i++) { 05296 if (defaults[y] == i+1) { 05297 req->data.softkeysets.softKeySetDefinition[softkeymode->mode].softKeyTemplateIndex[y] = htolel(i+1); 05298 req->data.softkeysets.softKeySetDefinition[softkeymode->mode].softKeyInfoIndex[y] = htolel(i+301); 05299 } 05300 } 05301 } 05302 softkeymode++; 05303 } 05304 transmit_response(d, req); 05305 transmit_selectsoftkeys(d, 0, 0, KEYDEF_ONHOOK); 05306 return 1; 05307 }
static int handle_soft_key_template_req_message | ( | struct skinny_req * | req, | |
struct skinnysession * | s | |||
) | [static] |
Definition at line 5669 of file chan_skinny.c.
References skinny_req::data, htolel, req_alloc(), s, soft_key_template_default, SOFT_KEY_TEMPLATE_RES_MESSAGE, soft_key_template_res_message::softKeyCount, soft_key_template_res_message::softKeyOffset, skinny_data::softkeytemplate, soft_key_template_res_message::softKeyTemplateDefinition, soft_key_template_res_message::totalSoftKeyCount, and transmit_response().
Referenced by handle_message().
05670 { 05671 if (!(req = req_alloc(sizeof(struct soft_key_template_res_message), SOFT_KEY_TEMPLATE_RES_MESSAGE))) 05672 return -1; 05673 05674 req->data.softkeytemplate.softKeyOffset = htolel(0); 05675 req->data.softkeytemplate.softKeyCount = htolel(sizeof(soft_key_template_default) / sizeof(struct soft_key_template_definition)); 05676 req->data.softkeytemplate.totalSoftKeyCount = htolel(sizeof(soft_key_template_default) / sizeof(struct soft_key_template_definition)); 05677 memcpy(req->data.softkeytemplate.softKeyTemplateDefinition, 05678 soft_key_template_default, 05679 sizeof(soft_key_template_default)); 05680 transmit_response(s->device, req); 05681 return 1; 05682 }
static int handle_speed_dial_stat_req_message | ( | struct skinny_req * | req, | |
struct skinnysession * | s | |||
) | [static] |
Definition at line 4892 of file chan_skinny.c.
References ast_copy_string(), skinny_req::data, skinny_speeddial::exten, find_speeddial_by_instance(), htolel, skinny_speeddial::label, letohl, req_alloc(), s, SPEED_DIAL_STAT_RES_MESSAGE, skinny_data::speeddial, speed_dial_stat_res_message::speedDialDirNumber, speed_dial_stat_res_message::speedDialDisplayName, speed_dial_stat_req_message::speedDialNumber, skinny_data::speeddialreq, and transmit_response().
Referenced by handle_message().
04893 { 04894 struct skinny_device *d = s->device; 04895 struct skinny_speeddial *sd; 04896 int instance; 04897 04898 instance = letohl(req->data.speeddialreq.speedDialNumber); 04899 04900 sd = find_speeddial_by_instance(d, instance, 0); 04901 04902 if (!sd) { 04903 return 0; 04904 } 04905 04906 if (!(req = req_alloc(sizeof(struct speed_dial_stat_res_message), SPEED_DIAL_STAT_RES_MESSAGE))) 04907 return -1; 04908 04909 req->data.speeddialreq.speedDialNumber = htolel(instance); 04910 ast_copy_string(req->data.speeddial.speedDialDirNumber, sd->exten, sizeof(req->data.speeddial.speedDialDirNumber)); 04911 ast_copy_string(req->data.speeddial.speedDialDisplayName, sd->label, sizeof(req->data.speeddial.speedDialDisplayName)); 04912 04913 transmit_response(d, req); 04914 return 1; 04915 }
static int handle_stimulus_message | ( | struct skinny_req * | req, | |
struct skinnysession * | s | |||
) | [static] |
Definition at line 4352 of file chan_skinny.c.
References ast_channel::_state, skinny_device::activeline, ast_bridged_channel(), AST_CONTROL_ANSWER, ast_copy_string(), ast_debug, AST_DEVICE_UNKNOWN, ast_devstate_changed(), ast_exists_extension(), ast_hangup(), ast_ignore_pattern(), ast_log(), ast_masq_park_call(), ast_pthread_create, ast_queue_control(), ast_setstate(), AST_STATE_DOWN, AST_STATE_UP, ast_strlen_zero(), ast_verb, skinny_subchannel::callid, stimulus_message::callreference, skinny_line::cid_num, ast_channel::context, skinny_req::data, skinny_line::dnd, errno, skinny_speeddial::exten, ast_channel::exten, find_line_by_instance(), find_speeddial_by_instance(), find_subchannel_by_instance_reference(), handle_callforward_button(), handle_hold_button(), handle_transfer_button(), skinny_line::hookstate, skinny_line::instance, KEYDEF_CONNECTED, KEYDEF_OFFHOOK, KEYDEF_RINGOUT, skinny_device::lastcallreference, skinny_device::lastlineinstance, skinny_line::lastnumberdialed, letohl, LOG_WARNING, ast_channel::name, skinny_device::name, skinny_line::name, skinny_subchannel::outgoing, skinny_subchannel::owner, skinny_subchannel::parent, s, SKINNY_CFWD_ALL, SKINNY_CFWD_BUSY, SKINNY_CFWD_NOANSWER, SKINNY_CONNECTED, SKINNY_DIALTONE, SKINNY_LAMP_OFF, SKINNY_LAMP_ON, skinny_new(), skinny_newcall(), SKINNY_OFFHOOK, SKINNY_ONHOOK, SKINNY_RING_OFF, SKINNY_SILENCE, SKINNY_SPEAKEROFF, SKINNY_SPEAKERON, skinny_ss(), start_rtp(), stimulus_message::stimulus, skinny_data::stimulus, STIMULUS_CALLPARK, STIMULUS_CONFERENCE, STIMULUS_DISPLAY, STIMULUS_DND, STIMULUS_FORWARDALL, STIMULUS_FORWARDBUSY, STIMULUS_FORWARDNOANSWER, STIMULUS_HOLD, STIMULUS_LINE, STIMULUS_REDIAL, STIMULUS_SPEEDDIAL, STIMULUS_TRANSFER, STIMULUS_VOICEMAIL, stimulus_message::stimulusInstance, ast_channel::tech_pvt, skinny_line::transfer, transmit_callstate(), transmit_callstateonly(), transmit_displaymessage(), transmit_displaynotify(), transmit_displaypromptstatus(), transmit_lamp_indication(), transmit_ringer_mode(), transmit_selectsoftkeys(), transmit_speaker_mode(), transmit_tone(), and skinny_line::vmexten.
Referenced by handle_message().
04353 { 04354 struct skinny_device *d = s->device; 04355 struct skinny_line *l; 04356 struct skinny_subchannel *sub; 04357 /*struct skinny_speeddial *sd;*/ 04358 struct ast_channel *c; 04359 pthread_t t; 04360 int event; 04361 int instance; 04362 int callreference; 04363 /*int res = 0;*/ 04364 04365 event = letohl(req->data.stimulus.stimulus); 04366 instance = letohl(req->data.stimulus.stimulusInstance); 04367 callreference = letohl(req->data.stimulus.callreference); 04368 if (skinnydebug) 04369 ast_verb(1, "callreference in handle_stimulus_message is '%d'\n", callreference); 04370 04371 /* Note that this call should be using the passed in instance and callreference */ 04372 sub = find_subchannel_by_instance_reference(d, d->lastlineinstance, d->lastcallreference); 04373 04374 if (!sub) { 04375 l = find_line_by_instance(d, d->lastlineinstance); 04376 if (!l) { 04377 return 0; 04378 } 04379 } else { 04380 l = sub->parent; 04381 } 04382 04383 switch(event) { 04384 case STIMULUS_REDIAL: 04385 if (skinnydebug) 04386 ast_verb(1, "Received Stimulus: Redial(%d/%d)\n", instance, callreference); 04387 04388 if (ast_strlen_zero(l->lastnumberdialed)) { 04389 ast_log(LOG_WARNING, "Attempted redial, but no previously dialed number found.\n"); 04390 l->hookstate = SKINNY_ONHOOK; 04391 transmit_speaker_mode(d, SKINNY_SPEAKEROFF); 04392 transmit_callstate(d, l->instance, SKINNY_ONHOOK, instance); 04393 break; 04394 } 04395 04396 c = skinny_new(l, AST_STATE_DOWN); 04397 if (!c) { 04398 ast_log(LOG_WARNING, "Unable to create channel for %s@%s\n", l->name, d->name); 04399 } else { 04400 sub = c->tech_pvt; 04401 l = sub->parent; 04402 if (l->hookstate == SKINNY_ONHOOK) { 04403 l->hookstate = SKINNY_OFFHOOK; 04404 transmit_callstate(d, l->instance, SKINNY_OFFHOOK, sub->callid); 04405 } 04406 if (skinnydebug) 04407 ast_verb(1, "Attempting to Clear display on Skinny %s@%s\n", l->name, d->name); 04408 transmit_displaymessage(d, NULL, l->instance, sub->callid); /* clear display */ 04409 transmit_tone(d, SKINNY_DIALTONE, l->instance, sub->callid); 04410 transmit_selectsoftkeys(d, l->instance, sub->callid, KEYDEF_RINGOUT); 04411 04412 if (!ast_ignore_pattern(c->context, l->lastnumberdialed)) { 04413 transmit_tone(d, SKINNY_SILENCE, l->instance, sub->callid); 04414 } 04415 ast_copy_string(c->exten, l->lastnumberdialed, sizeof(c->exten)); 04416 if (ast_pthread_create(&t, NULL, skinny_newcall, c)) { 04417 ast_log(LOG_WARNING, "Unable to create new call thread: %s\n", strerror(errno)); 04418 ast_hangup(c); 04419 } 04420 } 04421 break; 04422 case STIMULUS_SPEEDDIAL: 04423 { 04424 struct skinny_speeddial *sd; 04425 04426 if (skinnydebug) 04427 ast_verb(1, "Received Stimulus: SpeedDial(%d/%d)\n", instance, callreference); 04428 if (!(sd = find_speeddial_by_instance(d, instance, 0))) { 04429 return 0; 04430 } 04431 04432 if (!sub || !sub->owner) 04433 c = skinny_new(l, AST_STATE_DOWN); 04434 else 04435 c = sub->owner; 04436 04437 if (!c) { 04438 ast_log(LOG_WARNING, "Unable to create channel for %s@%s\n", l->name, d->name); 04439 } else { 04440 sub = c->tech_pvt; 04441 l = sub->parent; 04442 if (l->hookstate == SKINNY_ONHOOK) { 04443 l->hookstate = SKINNY_OFFHOOK; 04444 transmit_speaker_mode(d, SKINNY_SPEAKERON); 04445 transmit_callstate(d, l->instance, SKINNY_OFFHOOK, sub->callid); 04446 } 04447 if (skinnydebug) 04448 ast_verb(1, "Attempting to Clear display on Skinny %s@%s\n", l->name, d->name); 04449 transmit_displaymessage(d, NULL, l->instance, sub->callid); /* clear display */ 04450 transmit_tone(d, SKINNY_DIALTONE, l->instance, sub->callid); 04451 transmit_selectsoftkeys(d, l->instance, sub->callid, KEYDEF_RINGOUT); 04452 04453 if (!ast_ignore_pattern(c->context, sd->exten)) { 04454 transmit_tone(d, SKINNY_SILENCE, l->instance, sub->callid); 04455 } 04456 if (ast_exists_extension(c, c->context, sd->exten, 1, l->cid_num)) { 04457 ast_copy_string(c->exten, sd->exten, sizeof(c->exten)); 04458 ast_copy_string(l->lastnumberdialed, sd->exten, sizeof(l->lastnumberdialed)); 04459 04460 if (ast_pthread_create(&t, NULL, skinny_newcall, c)) { 04461 ast_log(LOG_WARNING, "Unable to create new call thread: %s\n", strerror(errno)); 04462 ast_hangup(c); 04463 } 04464 break; 04465 } 04466 } 04467 } 04468 break; 04469 case STIMULUS_HOLD: 04470 if (skinnydebug) 04471 ast_verb(1, "Received Stimulus: Hold(%d/%d)\n", instance, callreference); 04472 handle_hold_button(sub); 04473 break; 04474 case STIMULUS_TRANSFER: 04475 if (skinnydebug) 04476 ast_verb(1, "Received Stimulus: Transfer(%d/%d)\n", instance, callreference); 04477 if (l->transfer) 04478 handle_transfer_button(sub); 04479 else 04480 transmit_displaynotify(d, "Transfer disabled", 10); 04481 break; 04482 case STIMULUS_CONFERENCE: 04483 if (skinnydebug) 04484 ast_verb(1, "Received Stimulus: Conference(%d/%d)\n", instance, callreference); 04485 /* XXX determine the best way to pull off a conference. Meetme? */ 04486 break; 04487 case STIMULUS_VOICEMAIL: 04488 if (skinnydebug) 04489 ast_verb(1, "Received Stimulus: Voicemail(%d/%d)\n", instance, callreference); 04490 04491 if (!sub || !sub->owner) { 04492 c = skinny_new(l, AST_STATE_DOWN); 04493 } else { 04494 c = sub->owner; 04495 } 04496 if (!c) { 04497 ast_log(LOG_WARNING, "Unable to create channel for %s@%s\n", l->name, d->name); 04498 } else { 04499 sub = c->tech_pvt; 04500 l = sub->parent; 04501 04502 if (ast_strlen_zero(l->vmexten)) /* Exit the call if no VM pilot */ 04503 break; 04504 04505 if (l->hookstate == SKINNY_ONHOOK){ 04506 l->hookstate = SKINNY_OFFHOOK; 04507 transmit_speaker_mode(d, SKINNY_SPEAKERON); 04508 transmit_callstate(d, l->instance, SKINNY_OFFHOOK, sub->callid); 04509 } 04510 04511 if (skinnydebug) 04512 ast_verb(1, "Attempting to Clear display on Skinny %s@%s\n", l->name, d->name); 04513 04514 transmit_displaymessage(d, NULL, l->instance, sub->callid); /* clear display */ 04515 transmit_tone(d, SKINNY_DIALTONE, l->instance, sub->callid); 04516 transmit_selectsoftkeys(d, l->instance, sub->callid, KEYDEF_RINGOUT); 04517 04518 if (!ast_ignore_pattern(c->context, vmexten)) { 04519 transmit_tone(d, SKINNY_SILENCE, l->instance, sub->callid); 04520 } 04521 04522 if (ast_exists_extension(c, c->context, l->vmexten, 1, l->cid_num)) { 04523 ast_copy_string(c->exten, l->vmexten, sizeof(c->exten)); 04524 ast_copy_string(l->lastnumberdialed, l->vmexten, sizeof(l->lastnumberdialed)); 04525 if (ast_pthread_create(&t, NULL, skinny_newcall, c)) { 04526 ast_log(LOG_WARNING, "Unable to create new call thread: %s\n", strerror(errno)); 04527 ast_hangup(c); 04528 } 04529 break; 04530 } 04531 } 04532 break; 04533 case STIMULUS_CALLPARK: 04534 { 04535 int extout; 04536 char message[32]; 04537 04538 if (skinnydebug) 04539 ast_verb(1, "Received Stimulus: Park Call(%d/%d)\n", instance, callreference); 04540 04541 if ((sub && sub->owner) && (sub->owner->_state == AST_STATE_UP)){ 04542 c = sub->owner; 04543 if (!ast_masq_park_call(ast_bridged_channel(c), c, 0, &extout)) { 04544 snprintf(message, sizeof(message), "Call Parked at: %d", extout); 04545 transmit_displaynotify(d, message, 10); 04546 } else { 04547 transmit_displaynotify(d, "Call Park failed", 10); 04548 } 04549 } else { 04550 transmit_displaynotify(d, "Call Park not available", 10); 04551 } 04552 } 04553 break; 04554 case STIMULUS_DND: 04555 if (skinnydebug) 04556 ast_verb(1, "Received Stimulus: DND (%d/%d)\n", instance, callreference); 04557 04558 /* Do not disturb */ 04559 if (l->dnd != 0){ 04560 ast_verb(3, "Disabling DND on %s@%s\n", l->name, d->name); 04561 l->dnd = 0; 04562 transmit_lamp_indication(d, STIMULUS_DND, 1, SKINNY_LAMP_ON); 04563 transmit_displaynotify(d, "DnD disabled", 10); 04564 } else { 04565 ast_verb(3, "Enabling DND on %s@%s\n", l->name, d->name); 04566 l->dnd = 1; 04567 transmit_lamp_indication(d, STIMULUS_DND, 1, SKINNY_LAMP_OFF); 04568 transmit_displaynotify(d, "DnD enabled", 10); 04569 } 04570 break; 04571 case STIMULUS_FORWARDALL: 04572 if (skinnydebug) 04573 ast_verb(1, "Received Stimulus: Forward All(%d/%d)\n", instance, callreference); 04574 04575 if (!sub || !sub->owner) { 04576 c = skinny_new(l, AST_STATE_DOWN); 04577 } else { 04578 c = sub->owner; 04579 } 04580 04581 if (!c) { 04582 ast_log(LOG_WARNING, "Unable to create channel for %s@%s\n", l->name, d->name); 04583 } else { 04584 sub = c->tech_pvt; 04585 handle_callforward_button(sub, SKINNY_CFWD_ALL); 04586 } 04587 break; 04588 case STIMULUS_FORWARDBUSY: 04589 if (skinnydebug) 04590 ast_verb(1, "Received Stimulus: Forward Busy (%d/%d)\n", instance, callreference); 04591 04592 if (!sub || !sub->owner) { 04593 c = skinny_new(l, AST_STATE_DOWN); 04594 } else { 04595 c = sub->owner; 04596 } 04597 04598 if (!c) { 04599 ast_log(LOG_WARNING, "Unable to create channel for %s@%s\n", l->name, d->name); 04600 } else { 04601 sub = c->tech_pvt; 04602 handle_callforward_button(sub, SKINNY_CFWD_BUSY); 04603 } 04604 break; 04605 case STIMULUS_FORWARDNOANSWER: 04606 if (skinnydebug) 04607 ast_verb(1, "Received Stimulus: Forward No Answer (%d/%d)\n", instance, callreference); 04608 04609 #if 0 /* Not sure how to handle this yet */ 04610 if (!sub || !sub->owner) { 04611 c = skinny_new(l, AST_STATE_DOWN); 04612 } else { 04613 c = sub->owner; 04614 } 04615 04616 if (!c) { 04617 ast_log(LOG_WARNING, "Unable to create channel for %s@%s\n", l->name, d->name); 04618 } else { 04619 sub = c->tech_pvt; 04620 handle_callforward_button(sub, SKINNY_CFWD_NOANSWER); 04621 } 04622 #endif 04623 break; 04624 case STIMULUS_DISPLAY: 04625 /* Not sure what this is */ 04626 if (skinnydebug) 04627 ast_verb(1, "Received Stimulus: Display(%d/%d)\n", instance, callreference); 04628 break; 04629 case STIMULUS_LINE: 04630 if (skinnydebug) 04631 ast_verb(1, "Received Stimulus: Line(%d/%d)\n", instance, callreference); 04632 04633 l = find_line_by_instance(d, instance); 04634 04635 if (!l) { 04636 return 0; 04637 } 04638 04639 d->activeline = l; 04640 04641 /* turn the speaker on */ 04642 transmit_speaker_mode(d, SKINNY_SPEAKERON); 04643 transmit_ringer_mode(d, SKINNY_RING_OFF); 04644 transmit_lamp_indication(d, STIMULUS_LINE, l->instance, SKINNY_LAMP_ON); 04645 04646 l->hookstate = SKINNY_OFFHOOK; 04647 04648 if (sub && sub->outgoing) { 04649 /* We're answering a ringing call */ 04650 ast_queue_control(sub->owner, AST_CONTROL_ANSWER); 04651 transmit_callstate(d, l->instance, SKINNY_OFFHOOK, sub->callid); 04652 transmit_tone(d, SKINNY_SILENCE, l->instance, sub->callid); 04653 transmit_callstateonly(d, sub, SKINNY_CONNECTED); 04654 transmit_displaypromptstatus(d, "Connected", 0, l->instance, sub->callid); 04655 transmit_selectsoftkeys(d, l->instance, sub->callid, KEYDEF_CONNECTED); 04656 start_rtp(sub); 04657 ast_setstate(sub->owner, AST_STATE_UP); 04658 } else { 04659 if (sub && sub->owner) { 04660 ast_debug(1, "Current subchannel [%s] already has owner\n", sub->owner->name); 04661 } else { 04662 c = skinny_new(l, AST_STATE_DOWN); 04663 if (c) { 04664 sub = c->tech_pvt; 04665 transmit_callstate(d, l->instance, SKINNY_OFFHOOK, sub->callid); 04666 if (skinnydebug) 04667 ast_verb(1, "Attempting to Clear display on Skinny %s@%s\n", l->name, d->name); 04668 transmit_displaymessage(d, NULL, l->instance, sub->callid); /* clear display */ 04669 transmit_tone(d, SKINNY_DIALTONE, l->instance, sub->callid); 04670 transmit_selectsoftkeys(d, l->instance, sub->callid, KEYDEF_OFFHOOK); 04671 04672 /* start the switch thread */ 04673 if (ast_pthread_create(&t, NULL, skinny_ss, c)) { 04674 ast_log(LOG_WARNING, "Unable to create switch thread: %s\n", strerror(errno)); 04675 ast_hangup(c); 04676 } 04677 } else { 04678 ast_log(LOG_WARNING, "Unable to create channel for %s@%s\n", l->name, d->name); 04679 } 04680 } 04681 } 04682 break; 04683 default: 04684 if (skinnydebug) 04685 ast_verb(1, "RECEIVED UNKNOWN STIMULUS: %d(%d/%d)\n", event, instance, callreference); 04686 break; 04687 } 04688 ast_devstate_changed(AST_DEVICE_UNKNOWN, "Skinny/%s@%s", l->name, d->name); 04689 04690 return 1; 04691 }
static int handle_time_date_req_message | ( | struct skinny_req * | req, | |
struct skinnysession * | s | |||
) | [static] |
Definition at line 4955 of file chan_skinny.c.
References ast_localtime(), ast_tvnow(), skinny_req::data, definetimedate_message::day, definetimedate_message::dayofweek, skinny_data::definetimedate, DEFINETIMEDATE_MESSAGE, definetimedate_message::hour, htolel, definetimedate_message::milliseconds, definetimedate_message::minute, definetimedate_message::month, req_alloc(), s, definetimedate_message::seconds, definetimedate_message::timestamp, ast_tm::tm_hour, ast_tm::tm_mday, ast_tm::tm_min, ast_tm::tm_mon, ast_tm::tm_sec, ast_tm::tm_usec, ast_tm::tm_wday, ast_tm::tm_year, transmit_response(), and definetimedate_message::year.
Referenced by do_housekeeping(), and handle_message().
04956 { 04957 struct timeval now = ast_tvnow(); 04958 struct ast_tm cmtime; 04959 04960 if (!(req = req_alloc(sizeof(struct definetimedate_message), DEFINETIMEDATE_MESSAGE))) 04961 return -1; 04962 04963 ast_localtime(&now, &cmtime, NULL); 04964 req->data.definetimedate.year = htolel(cmtime.tm_year+1900); 04965 req->data.definetimedate.month = htolel(cmtime.tm_mon+1); 04966 req->data.definetimedate.dayofweek = htolel(cmtime.tm_wday); 04967 req->data.definetimedate.day = htolel(cmtime.tm_mday); 04968 req->data.definetimedate.hour = htolel(cmtime.tm_hour); 04969 req->data.definetimedate.minute = htolel(cmtime.tm_min); 04970 req->data.definetimedate.seconds = htolel(cmtime.tm_sec); 04971 req->data.definetimedate.milliseconds = htolel(cmtime.tm_usec / 1000); 04972 req->data.definetimedate.timestamp = htolel(now.tv_sec); 04973 transmit_response(s->device, req); 04974 return 1; 04975 }
static int handle_transfer_button | ( | struct skinny_subchannel * | sub | ) | [static] |
Definition at line 4101 of file chan_skinny.c.
References ast_channel::_state, skinny_line::activesub, ast_debug, ast_hangup(), ast_log(), ast_pthread_create, AST_STATE_DOWN, ast_verbose, skinny_subchannel::blindxfer, skinny_subchannel::callid, errno, skinny_line::instance, KEYDEF_OFFHOOKWITHFEAT, LOG_WARNING, skinny_device::name, skinny_line::name, skinny_subchannel::onhold, skinny_subchannel::owner, skinny_line::parent, skinny_subchannel::related, SKINNY_DIALTONE, skinny_hold(), skinny_new(), SKINNY_OFFHOOK, skinny_ss(), skinny_transfer(), skinny_line::sub, ast_channel::tech_pvt, transmit_callstate(), transmit_displaymessage(), transmit_selectsoftkeys(), transmit_tone(), and skinny_subchannel::xferor.
Referenced by handle_onhook_message(), handle_soft_key_event_message(), and handle_stimulus_message().
04102 { 04103 struct skinny_line *l = sub->parent; 04104 struct skinny_device *d = l->parent; 04105 struct skinny_subchannel *newsub; 04106 struct ast_channel *c; 04107 pthread_t t; 04108 04109 if (!sub) { 04110 ast_verbose("Transfer: No subchannel to transfer\n"); 04111 return -1; 04112 } 04113 if (!sub->related) { 04114 /* Another sub has not been created so this must be first XFER press */ 04115 if (!sub->onhold) { 04116 skinny_hold(sub); 04117 } 04118 c = skinny_new(l, AST_STATE_DOWN); 04119 if (c) { 04120 newsub = c->tech_pvt; 04121 /* point the sub and newsub at each other so we know they are related */ 04122 newsub->related = sub; 04123 sub->related = newsub; 04124 newsub->xferor = 1; 04125 l->activesub = newsub; 04126 transmit_callstate(d, l->instance, SKINNY_OFFHOOK, newsub->callid); 04127 if (skinnydebug) 04128 ast_debug(1, "Attempting to Clear display on Skinny %s@%s\n", l->name, d->name); 04129 transmit_displaymessage(d, NULL, l->instance, newsub->callid); /* clear display */ 04130 transmit_tone(d, SKINNY_DIALTONE, l->instance, newsub->callid); 04131 transmit_selectsoftkeys(d, l->instance, newsub->callid, KEYDEF_OFFHOOKWITHFEAT); 04132 /* start the switch thread */ 04133 if (ast_pthread_create(&t, NULL, skinny_ss, c)) { 04134 ast_log(LOG_WARNING, "Unable to create switch thread: %s\n", strerror(errno)); 04135 ast_hangup(c); 04136 } 04137 } else { 04138 ast_log(LOG_WARNING, "Unable to create channel for %s@%s\n", l->name, d->name); 04139 } 04140 } else { 04141 /* We already have a related sub so we can either complete XFER or go into BLINDXFER (or cancel BLINDXFER */ 04142 if (sub->blindxfer) { 04143 /* toggle blindxfer off */ 04144 sub->blindxfer = 0; 04145 sub->related->blindxfer = 0; 04146 /* we really need some indications */ 04147 } else { 04148 /* We were doing attended transfer */ 04149 if (sub->owner->_state == AST_STATE_DOWN || sub->related->owner->_state == AST_STATE_DOWN) { 04150 /* one of the subs so we cant transfer yet, toggle blindxfer on */ 04151 sub->blindxfer = 1; 04152 sub->related->blindxfer = 1; 04153 } else { 04154 /* big assumption we have two channels, lets transfer */ 04155 skinny_transfer(sub); 04156 } 04157 } 04158 } 04159 return 0; 04160 }
static int handle_unregister_message | ( | struct skinny_req * | req, | |
struct skinnysession * | s | |||
) | [static] |
Definition at line 5664 of file chan_skinny.c.
References s, and skinny_unregister().
Referenced by handle_message().
05665 { 05666 return skinny_unregister(req, s); 05667 }
static int handle_version_req_message | ( | struct skinny_req * | req, | |
struct skinnysession * | s | |||
) | [static] |
Definition at line 5125 of file chan_skinny.c.
References ast_copy_string(), skinny_req::data, req_alloc(), s, transmit_response(), version_res_message::version, skinny_data::version, skinny_device::version_id, and VERSION_RES_MESSAGE.
Referenced by handle_message().
05126 { 05127 struct skinny_device *d = s->device; 05128 if (!(req = req_alloc(sizeof(struct version_res_message), VERSION_RES_MESSAGE))) 05129 return -1; 05130 05131 ast_copy_string(req->data.version.version, d->version_id, sizeof(req->data.version.version)); 05132 transmit_response(d, req); 05133 return 1; 05134 }
static int has_voicemail | ( | struct skinny_line * | l | ) | [static] |
Definition at line 2311 of file chan_skinny.c.
References ast_app_has_voicemail(), ast_event_destroy(), ast_event_get_cached(), ast_event_get_ie_uint(), AST_EVENT_IE_CONTEXT, AST_EVENT_IE_END, AST_EVENT_IE_MAILBOX, AST_EVENT_IE_NEWMSGS, AST_EVENT_IE_PLTYPE_STR, AST_EVENT_MWI, ast_strdupa, ast_strlen_zero(), skinny_line::mailbox, mbox(), and strsep().
02312 { 02313 int new_msgs; 02314 struct ast_event *event; 02315 char *mbox, *context; 02316 02317 context = mbox = ast_strdupa(l->mailbox); 02318 strsep(&context, "@"); 02319 if (ast_strlen_zero(context)) 02320 context = "default"; 02321 02322 event = ast_event_get_cached(AST_EVENT_MWI, 02323 AST_EVENT_IE_MAILBOX, AST_EVENT_IE_PLTYPE_STR, mbox, 02324 AST_EVENT_IE_CONTEXT, AST_EVENT_IE_PLTYPE_STR, context, 02325 AST_EVENT_IE_END); 02326 02327 if (event) { 02328 new_msgs = ast_event_get_ie_uint(event, AST_EVENT_IE_NEWMSGS); 02329 ast_event_destroy(event); 02330 } else 02331 new_msgs = ast_app_has_voicemail(l->mailbox, NULL); 02332 02333 return new_msgs; 02334 }
static int load_module | ( | void | ) | [static] |
Definition at line 6381 of file chan_skinny.c.
References ARRAY_LEN, ast_channel_register(), ast_cli_register_multiple(), ast_log(), AST_MODULE_LOAD_DECLINE, ast_rtp_proto_register(), cli_skinny, htolel, io, io_context_create(), LOG_ERROR, LOG_WARNING, reload_config(), restart_monitor(), sched, sched_context_create(), skinny_rtp, skinny_tech, and soft_key_template_default.
06382 { 06383 int res = 0; 06384 06385 for (; res < ARRAY_LEN(soft_key_template_default); res++) { 06386 soft_key_template_default[res].softKeyEvent = htolel(soft_key_template_default[res].softKeyEvent); 06387 } 06388 /* load and parse config */ 06389 res = reload_config(); 06390 if (res == -1) { 06391 return AST_MODULE_LOAD_DECLINE; 06392 } 06393 06394 /* Make sure we can register our skinny channel type */ 06395 if (ast_channel_register(&skinny_tech)) { 06396 ast_log(LOG_ERROR, "Unable to register channel class 'Skinny'\n"); 06397 return -1; 06398 } 06399 06400 ast_rtp_proto_register(&skinny_rtp); 06401 ast_cli_register_multiple(cli_skinny, sizeof(cli_skinny) / sizeof(struct ast_cli_entry)); 06402 sched = sched_context_create(); 06403 if (!sched) { 06404 ast_log(LOG_WARNING, "Unable to create schedule context\n"); 06405 } 06406 io = io_context_create(); 06407 if (!io) { 06408 ast_log(LOG_WARNING, "Unable to create I/O context\n"); 06409 } 06410 /* And start the monitor for the first time */ 06411 restart_monitor(); 06412 06413 return res; 06414 }
static void mwi_event_cb | ( | const struct ast_event * | event, | |
void * | userdata | |||
) | [static] |
Definition at line 2303 of file chan_skinny.c.
02304 { 02305 /* This module does not handle MWI in an event-based manner. However, it 02306 * subscribes to MWI for each mailbox that is configured so that the core 02307 * knows that we care about it. Then, chan_skinny will get the MWI from the 02308 * event cache instead of checking the mailbox directly. */ 02309 }
static void print_codec_to_cli | ( | int | fd, | |
struct ast_codec_pref * | pref | |||
) | [static] |
Print codec list from preference to CLI/manager.
Definition at line 2730 of file chan_skinny.c.
References ast_cli(), ast_codec_pref_index(), ast_getformatname(), and ast_codec_pref::framing.
02731 { 02732 int x, codec; 02733 02734 for(x = 0; x < 32 ; x++) { 02735 codec = ast_codec_pref_index(pref, x); 02736 if (!codec) 02737 break; 02738 ast_cli(fd, "%s", ast_getformatname(codec)); 02739 ast_cli(fd, ":%d", pref->framing[x]); 02740 if (x < 31 && ast_codec_pref_index(pref, x + 1)) 02741 ast_cli(fd, ","); 02742 } 02743 if (!x) 02744 ast_cli(fd, "none"); 02745 }
static void register_exten | ( | struct skinny_line * | l | ) | [static] |
Definition at line 1710 of file chan_skinny.c.
References ast_add_extension(), ast_context_find(), ast_copy_string(), ast_free_ptr, ast_log(), ast_strdup, ast_strlen_zero(), ext, LOG_WARNING, skinny_line::name, skinny_line::regexten, S_OR, and strsep().
Referenced by skinny_register().
01711 { 01712 char multi[256]; 01713 char *stringp, *ext, *context; 01714 01715 if (ast_strlen_zero(regcontext)) 01716 return; 01717 01718 ast_copy_string(multi, S_OR(l->regexten, l->name), sizeof(multi)); 01719 stringp = multi; 01720 while ((ext = strsep(&stringp, "&"))) { 01721 if ((context = strchr(ext, '@'))) { 01722 *context++ = '\0'; /* split ext@context */ 01723 if (!ast_context_find(context)) { 01724 ast_log(LOG_WARNING, "Context %s must exist in regcontext= in skinny.conf!\n", context); 01725 continue; 01726 } 01727 } else { 01728 context = regcontext; 01729 } 01730 ast_add_extension(context, 1, ext, 1, NULL, NULL, "Noop", 01731 ast_strdup(l->name), ast_free_ptr, "Skinny"); 01732 } 01733 }
static int reload_config | ( | void | ) | [static] |
Definition at line 6162 of file chan_skinny.c.
References accept_thread(), ahp, ast_category_browse(), ast_config_destroy(), ast_config_load, ast_context_find_or_create(), ast_copy_string(), ast_gethostbyname(), ast_inet_ntoa(), ast_jb_read_conf(), AST_LIST_INSERT_HEAD, AST_LIST_LOCK, AST_LIST_UNLOCK, ast_log(), AST_MAX_CONTEXT, ast_mutex_lock(), ast_mutex_unlock(), ast_netsock_set_qos(), ast_parse_allow_disallow(), ast_pthread_create_background, ast_str2cos(), ast_str2tos(), ast_variable_browse(), ast_verb, build_device(), cleanup_stale_contexts(), config_flags, default_jbconf, default_prefs, DEFAULT_SKINNY_BACKLOG, DEFAULT_SKINNY_PORT, errno, global_jbconf, ast_variable::lineno, LOG_ERROR, LOG_NOTICE, LOG_WARNING, skinny_device::name, ast_variable::name, netlock, ast_variable::next, qos, strsep(), and ast_variable::value.
06163 { 06164 int on = 1; 06165 struct ast_config *cfg; 06166 struct ast_variable *v; 06167 char *cat; 06168 struct skinny_device *d; 06169 int oldport = ntohs(bindaddr.sin_port); 06170 char *stringp, *context, *oldregcontext; 06171 char newcontexts[AST_MAX_CONTEXT], oldcontexts[AST_MAX_CONTEXT]; 06172 struct ast_flags config_flags = { 0 }; 06173 06174 if (gethostname(ourhost, sizeof(ourhost))) { 06175 ast_log(LOG_WARNING, "Unable to get hostname, Skinny disabled\n"); 06176 return 0; 06177 } 06178 cfg = ast_config_load(config, config_flags); 06179 06180 /* We *must* have a config file otherwise stop immediately */ 06181 if (!cfg) { 06182 ast_log(LOG_NOTICE, "Unable to load config %s, Skinny disabled\n", config); 06183 return -1; 06184 } 06185 memset(&bindaddr, 0, sizeof(bindaddr)); 06186 memset(&default_prefs, 0, sizeof(default_prefs)); 06187 06188 /* Initialize copy of current global_regcontext for later use in removing stale contexts */ 06189 ast_copy_string(oldcontexts, regcontext, sizeof(oldcontexts)); 06190 oldregcontext = oldcontexts; 06191 06192 /* Copy the default jb config over global_jbconf */ 06193 memcpy(&global_jbconf, &default_jbconf, sizeof(struct ast_jb_conf)); 06194 06195 /* load the general section */ 06196 v = ast_variable_browse(cfg, "general"); 06197 while (v) { 06198 /* handle jb conf */ 06199 if (!ast_jb_read_conf(&global_jbconf, v->name, v->value)) { 06200 v = v->next; 06201 continue; 06202 } 06203 06204 /* Create the interface list */ 06205 if (!strcasecmp(v->name, "bindaddr")) { 06206 if (!(hp = ast_gethostbyname(v->value, &ahp))) { 06207 ast_log(LOG_WARNING, "Invalid address: %s\n", v->value); 06208 } else { 06209 memcpy(&bindaddr.sin_addr, hp->h_addr, sizeof(bindaddr.sin_addr)); 06210 } 06211 } else if (!strcasecmp(v->name, "keepalive")) { 06212 keep_alive = atoi(v->value); 06213 } else if (!strcasecmp(v->name, "vmexten")) { 06214 ast_copy_string(vmexten, v->value, sizeof(vmexten)); 06215 } else if (!strcasecmp(v->name, "regcontext")) { 06216 ast_copy_string(newcontexts, v->value, sizeof(newcontexts)); 06217 stringp = newcontexts; 06218 /* Let's remove any contexts that are no longer defined in regcontext */ 06219 cleanup_stale_contexts(stringp, oldregcontext); 06220 /* Create contexts if they don't exist already */ 06221 while ((context = strsep(&stringp, "&"))) { 06222 ast_copy_string(used_context, context, sizeof(used_context)); 06223 ast_context_find_or_create(NULL, NULL, context, "Skinny"); 06224 } 06225 ast_copy_string(regcontext, v->value, sizeof(regcontext)); 06226 } else if (!strcasecmp(v->name, "dateformat")) { 06227 memcpy(date_format, v->value, sizeof(date_format)); 06228 } else if (!strcasecmp(v->name, "tos")) { 06229 if (ast_str2tos(v->value, &qos.tos)) 06230 ast_log(LOG_WARNING, "Invalid tos value at line %d, refer to QoS documentation\n", v->lineno); 06231 } else if (!strcasecmp(v->name, "tos_audio")) { 06232 if (ast_str2tos(v->value, &qos.tos_audio)) 06233 ast_log(LOG_WARNING, "Invalid tos_audio value at line %d, refer to QoS documentation\n", v->lineno); 06234 } else if (!strcasecmp(v->name, "tos_video")) { 06235 if (ast_str2tos(v->value, &qos.tos_video)) 06236 ast_log(LOG_WARNING, "Invalid tos_video value at line %d, refer to QoS documentation\n", v->lineno); 06237 } else if (!strcasecmp(v->name, "cos")) { 06238 if (ast_str2cos(v->value, &qos.cos)) 06239 ast_log(LOG_WARNING, "Invalid cos value at line %d, refer to QoS documentation\n", v->lineno); 06240 } else if (!strcasecmp(v->name, "cos_audio")) { 06241 if (ast_str2cos(v->value, &qos.cos_audio)) 06242 ast_log(LOG_WARNING, "Invalid cos_audio value at line %d, refer to QoS documentation\n", v->lineno); 06243 } else if (!strcasecmp(v->name, "cos_video")) { 06244 if (ast_str2cos(v->value, &qos.cos_video)) 06245 ast_log(LOG_WARNING, "Invalid cos_video value at line %d, refer to QoS documentation\n", v->lineno); 06246 } else if (!strcasecmp(v->name, "allow")) { 06247 ast_parse_allow_disallow(&default_prefs, &default_capability, v->value, 1); 06248 } else if (!strcasecmp(v->name, "disallow")) { 06249 ast_parse_allow_disallow(&default_prefs, &default_capability, v->value, 0); 06250 } else if (!strcasecmp(v->name, "bindport")) { 06251 if (sscanf(v->value, "%d", &ourport) == 1) { 06252 bindaddr.sin_port = htons(ourport); 06253 } else { 06254 ast_log(LOG_WARNING, "Invalid bindport '%s' at line %d of %s\n", v->value, v->lineno, config); 06255 } 06256 } 06257 v = v->next; 06258 } 06259 06260 if (ntohl(bindaddr.sin_addr.s_addr)) { 06261 __ourip = bindaddr.sin_addr; 06262 } else { 06263 hp = ast_gethostbyname(ourhost, &ahp); 06264 if (!hp) { 06265 ast_log(LOG_WARNING, "Unable to get our IP address, Skinny disabled\n"); 06266 ast_config_destroy(cfg); 06267 return 0; 06268 } 06269 memcpy(&__ourip, hp->h_addr, sizeof(__ourip)); 06270 } 06271 if (!ntohs(bindaddr.sin_port)) { 06272 bindaddr.sin_port = ntohs(DEFAULT_SKINNY_PORT); 06273 } 06274 bindaddr.sin_family = AF_INET; 06275 06276 /* load the device sections */ 06277 cat = ast_category_browse(cfg, NULL); 06278 while(cat) { 06279 if (!strcasecmp(cat, "general")) { 06280 /* Nothing to do */ 06281 } else { 06282 d = build_device(cat, ast_variable_browse(cfg, cat)); 06283 if (d) { 06284 ast_verb(3, "Added device '%s'\n", d->name); 06285 AST_LIST_LOCK(&devices); 06286 AST_LIST_INSERT_HEAD(&devices, d, list); 06287 AST_LIST_UNLOCK(&devices); 06288 } 06289 } 06290 cat = ast_category_browse(cfg, cat); 06291 } 06292 ast_mutex_lock(&netlock); 06293 if ((skinnysock > -1) && (ntohs(bindaddr.sin_port) != oldport)) { 06294 close(skinnysock); 06295 skinnysock = -1; 06296 } 06297 if (skinnysock < 0) { 06298 skinnysock = socket(AF_INET, SOCK_STREAM, 0); 06299 if(setsockopt(skinnysock, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on)) == -1) { 06300 ast_log(LOG_ERROR, "Set Socket Options failed: errno %d, %s\n", errno, strerror(errno)); 06301 ast_config_destroy(cfg); 06302 ast_mutex_unlock(&netlock); 06303 return 0; 06304 } 06305 if (skinnysock < 0) { 06306 ast_log(LOG_WARNING, "Unable to create Skinny socket: %s\n", strerror(errno)); 06307 } else { 06308 if (bind(skinnysock, (struct sockaddr *)&bindaddr, sizeof(bindaddr)) < 0) { 06309 ast_log(LOG_WARNING, "Failed to bind to %s:%d: %s\n", 06310 ast_inet_ntoa(bindaddr.sin_addr), ntohs(bindaddr.sin_port), 06311 strerror(errno)); 06312 close(skinnysock); 06313 skinnysock = -1; 06314 ast_config_destroy(cfg); 06315 ast_mutex_unlock(&netlock); 06316 return 0; 06317 } 06318 if (listen(skinnysock, DEFAULT_SKINNY_BACKLOG)) { 06319 ast_log(LOG_WARNING, "Failed to start listening to %s:%d: %s\n", 06320 ast_inet_ntoa(bindaddr.sin_addr), ntohs(bindaddr.sin_port), 06321 strerror(errno)); 06322 close(skinnysock); 06323 skinnysock = -1; 06324 ast_config_destroy(cfg); 06325 ast_mutex_unlock(&netlock); 06326 return 0; 06327 } 06328 ast_verb(2, "Skinny listening on %s:%d\n", 06329 ast_inet_ntoa(bindaddr.sin_addr), ntohs(bindaddr.sin_port)); 06330 ast_netsock_set_qos(skinnysock, qos.tos, qos.cos, "Skinny"); 06331 ast_pthread_create_background(&accept_t, NULL, accept_thread, NULL); 06332 } 06333 } 06334 ast_mutex_unlock(&netlock); 06335 ast_config_destroy(cfg); 06336 return 1; 06337 }
static struct skinny_req* req_alloc | ( | size_t | size, | |
int | response_message | |||
) | [static] |
Definition at line 1441 of file chan_skinny.c.
References ast_calloc, skinny_req::e, htolel, and skinny_req::len.
Referenced by handle_button_template_req_message(), handle_keep_alive_message(), handle_line_state_req_message(), handle_open_receive_channel_ack_message(), handle_register_message(), handle_server_request_message(), handle_skinny_reset(), handle_soft_key_set_req_message(), handle_soft_key_template_req_message(), handle_speed_dial_stat_req_message(), handle_time_date_req_message(), handle_version_req_message(), skinny_set_rtp_peer(), transmit_activatecallplane(), transmit_callinfo(), transmit_callstate(), transmit_callstateonly(), transmit_cfwdstate(), transmit_closereceivechannel(), transmit_connect(), transmit_dialednumber(), transmit_displaymessage(), transmit_displaynotify(), transmit_displaypromptstatus(), transmit_lamp_indication(), transmit_ringer_mode(), transmit_selectsoftkeys(), transmit_speaker_mode(), transmit_stopmediatransmission(), and transmit_tone().
01442 { 01443 struct skinny_req *req; 01444 01445 if (!(req = ast_calloc(1, skinny_header_size + size + 4))) 01446 return NULL; 01447 01448 req->len = htolel(size+4); 01449 req->e = htolel(response_message); 01450 01451 return req; 01452 }
static int restart_monitor | ( | void | ) | [static] |
Definition at line 6088 of file chan_skinny.c.
References ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_pthread_create_background, AST_PTHREADT_NULL, AST_PTHREADT_STOP, do_monitor(), LOG_ERROR, LOG_WARNING, and monlock.
06089 { 06090 /* If we're supposed to be stopped -- stay stopped */ 06091 if (monitor_thread == AST_PTHREADT_STOP) 06092 return 0; 06093 06094 ast_mutex_lock(&monlock); 06095 if (monitor_thread == pthread_self()) { 06096 ast_mutex_unlock(&monlock); 06097 ast_log(LOG_WARNING, "Cannot kill myself\n"); 06098 return -1; 06099 } 06100 if (monitor_thread != AST_PTHREADT_NULL) { 06101 /* Wake up the thread */ 06102 pthread_kill(monitor_thread, SIGURG); 06103 } else { 06104 /* Start a new monitor */ 06105 if (ast_pthread_create_background(&monitor_thread, NULL, do_monitor, NULL) < 0) { 06106 ast_mutex_unlock(&monlock); 06107 ast_log(LOG_ERROR, "Unable to start monitor thread.\n"); 06108 return -1; 06109 } 06110 } 06111 ast_mutex_unlock(&monlock); 06112 return 0; 06113 }
static int set_callforwards | ( | struct skinny_line * | l, | |
const char * | cfwd, | |||
int | cfwdtype | |||
) | [static] |
Definition at line 1652 of file chan_skinny.c.
References ast_copy_string(), ast_strlen_zero(), skinny_line::call_forward_all, skinny_line::call_forward_busy, skinny_line::call_forward_noanswer, skinny_line::cfwdtype, SKINNY_CFWD_ALL, SKINNY_CFWD_BUSY, and SKINNY_CFWD_NOANSWER.
Referenced by build_device(), handle_callforward_button(), and skinny_ss().
01653 { 01654 if (!l) 01655 return 0; 01656 01657 if (!ast_strlen_zero(cfwd)) { 01658 if (cfwdtype & SKINNY_CFWD_ALL) { 01659 l->cfwdtype |= SKINNY_CFWD_ALL; 01660 ast_copy_string(l->call_forward_all, cfwd, sizeof(l->call_forward_all)); 01661 } 01662 if (cfwdtype & SKINNY_CFWD_BUSY) { 01663 l->cfwdtype |= SKINNY_CFWD_BUSY; 01664 ast_copy_string(l->call_forward_busy, cfwd, sizeof(l->call_forward_busy)); 01665 } 01666 if (cfwdtype & SKINNY_CFWD_NOANSWER) { 01667 l->cfwdtype |= SKINNY_CFWD_NOANSWER; 01668 ast_copy_string(l->call_forward_noanswer, cfwd, sizeof(l->call_forward_noanswer)); 01669 } 01670 } else { 01671 if (cfwdtype & SKINNY_CFWD_ALL) { 01672 l->cfwdtype &= ~SKINNY_CFWD_ALL; 01673 memset(l->call_forward_all, 0, sizeof(l->call_forward_all)); 01674 } 01675 if (cfwdtype & SKINNY_CFWD_BUSY) { 01676 l->cfwdtype &= ~SKINNY_CFWD_BUSY; 01677 memset(l->call_forward_busy, 0, sizeof(l->call_forward_busy)); 01678 } 01679 if (cfwdtype & SKINNY_CFWD_NOANSWER) { 01680 l->cfwdtype &= ~SKINNY_CFWD_NOANSWER; 01681 memset(l->call_forward_noanswer, 0, sizeof(l->call_forward_noanswer)); 01682 } 01683 } 01684 return l->cfwdtype; 01685 }
static int skinny_answer | ( | struct ast_channel * | ast | ) | [static] |
Definition at line 3533 of file chan_skinny.c.
References ast_channel::_state, skinny_line::activesub, ast_debug, ast_setstate(), AST_STATE_UP, ast_verb, skinny_subchannel::blindxfer, skinny_subchannel::callid, ast_channel::cid, ast_callerid::cid_name, ast_callerid::cid_num, skinny_subchannel::cxmode, skinny_line::instance, KEYDEF_CONNECTED, skinny_line::lastnumberdialed, skinny_device::name, skinny_line::name, ast_channel::name, skinny_line::parent, skinny_subchannel::rtp, SKINNY_CONNECTED, SKINNY_CX_SENDRECV, SKINNY_SILENCE, skinny_transfer(), start_rtp(), skinny_line::sub, ast_channel::tech_pvt, transmit_callinfo(), transmit_callstateonly(), transmit_dialednumber(), transmit_displaypromptstatus(), transmit_selectsoftkeys(), and transmit_tone().
03534 { 03535 int res = 0; 03536 struct skinny_subchannel *sub = ast->tech_pvt; 03537 struct skinny_line *l = sub->parent; 03538 struct skinny_device *d = l->parent; 03539 03540 if (sub->blindxfer) { 03541 if (skinnydebug) 03542 ast_debug(1, "skinny_answer(%s) on %s@%s-%d with BlindXFER, transferring\n", 03543 ast->name, l->name, d->name, sub->callid); 03544 ast_setstate(ast, AST_STATE_UP); 03545 skinny_transfer(sub); 03546 return 0; 03547 } 03548 03549 sub->cxmode = SKINNY_CX_SENDRECV; 03550 if (!sub->rtp) { 03551 start_rtp(sub); 03552 } 03553 if (skinnydebug) 03554 ast_verb(1, "skinny_answer(%s) on %s@%s-%d\n", ast->name, l->name, d->name, sub->callid); 03555 if (ast->_state != AST_STATE_UP) { 03556 ast_setstate(ast, AST_STATE_UP); 03557 } 03558 03559 transmit_tone(d, SKINNY_SILENCE, l->instance, sub->callid); 03560 /* order matters here... 03561 for some reason, transmit_callinfo must be before transmit_callstate, 03562 or you won't get keypad messages in some situations. */ 03563 transmit_callinfo(d, ast->cid.cid_name, ast->cid.cid_num, l->lastnumberdialed, l->lastnumberdialed, l->instance, sub->callid, 2); 03564 transmit_callstateonly(d, sub, SKINNY_CONNECTED); 03565 transmit_selectsoftkeys(d, l->instance, sub->callid, KEYDEF_CONNECTED); 03566 transmit_dialednumber(d, l->lastnumberdialed, l->instance, sub->callid); 03567 transmit_displaypromptstatus(d, "Connected", 0, l->instance, sub->callid); 03568 l->activesub = sub; 03569 return res; 03570 }
static int skinny_call | ( | struct ast_channel * | ast, | |
char * | dest, | |||
int | timeout | |||
) | [static] |
Definition at line 3403 of file chan_skinny.c.
References ast_channel::_state, AST_CONTROL_BUSY, AST_CONTROL_RINGING, ast_log(), ast_queue_control(), ast_setstate(), AST_STATE_DOWN, AST_STATE_RESERVED, AST_STATE_RINGING, ast_verb, skinny_subchannel::callid, ast_channel::cid, skinny_line::cid_name, ast_callerid::cid_name, skinny_line::cid_num, ast_callerid::cid_num, skinny_line::dnd, skinny_line::hookstate, skinny_line::instance, KEYDEF_RINGIN, LOG_ERROR, LOG_WARNING, ast_channel::name, skinny_subchannel::outgoing, skinny_line::parent, skinny_device::registered, SKINNY_ALERT, SKINNY_CALLWAITTONE, SKINNY_LAMP_BLINK, SKINNY_OFFHOOK, SKINNY_ONHOOK, SKINNY_RING_INSIDE, SKINNY_RINGIN, STIMULUS_LINE, skinny_line::sub, ast_channel::tech_pvt, transmit_callinfo(), transmit_callstateonly(), transmit_displaypromptstatus(), transmit_lamp_indication(), transmit_ringer_mode(), and transmit_selectsoftkeys().
03404 { 03405 int res = 0; 03406 int tone = 0; 03407 struct skinny_subchannel *sub = ast->tech_pvt; 03408 struct skinny_line *l = sub->parent; 03409 struct skinny_device *d = l->parent; 03410 03411 if (!d->registered) { 03412 ast_log(LOG_ERROR, "Device not registered, cannot call %s\n", dest); 03413 return -1; 03414 } 03415 03416 if ((ast->_state != AST_STATE_DOWN) && (ast->_state != AST_STATE_RESERVED)) { 03417 ast_log(LOG_WARNING, "skinny_call called on %s, neither down nor reserved\n", ast->name); 03418 return -1; 03419 } 03420 03421 if (skinnydebug) 03422 ast_verb(3, "skinny_call(%s)\n", ast->name); 03423 03424 if (l->dnd) { 03425 ast_queue_control(ast, AST_CONTROL_BUSY); 03426 return -1; 03427 } 03428 03429 switch (l->hookstate) { 03430 case SKINNY_OFFHOOK: 03431 tone = SKINNY_CALLWAITTONE; 03432 break; 03433 case SKINNY_ONHOOK: 03434 tone = SKINNY_ALERT; 03435 break; 03436 default: 03437 ast_log(LOG_ERROR, "Don't know how to deal with hookstate %d\n", l->hookstate); 03438 break; 03439 } 03440 03441 transmit_callstateonly(d, sub, SKINNY_RINGIN); 03442 transmit_selectsoftkeys(d, l->instance, sub->callid, KEYDEF_RINGIN); 03443 transmit_displaypromptstatus(d, "Ring-In", 0, l->instance, sub->callid); 03444 transmit_callinfo(d, ast->cid.cid_name, ast->cid.cid_num, l->cid_name, l->cid_num, l->instance, sub->callid, 1); 03445 transmit_lamp_indication(d, STIMULUS_LINE, l->instance, SKINNY_LAMP_BLINK); 03446 transmit_ringer_mode(d, SKINNY_RING_INSIDE); 03447 03448 ast_setstate(ast, AST_STATE_RINGING); 03449 ast_queue_control(ast, AST_CONTROL_RINGING); 03450 sub->outgoing = 1; 03451 return res; 03452 }
static int skinny_devicestate | ( | void * | data | ) | [static] |
Definition at line 6115 of file chan_skinny.c.
References ast_strdupa, find_line_by_name(), and get_devicestate().
06116 { 06117 struct skinny_line *l; 06118 char *tmp; 06119 06120 tmp = ast_strdupa(data); 06121 06122 l = find_line_by_name(tmp); 06123 06124 return get_devicestate(l); 06125 }
static int skinny_extensionstate_cb | ( | char * | context, | |
char * | exten, | |||
int | state, | |||
void * | data | |||
) | [static] |
Definition at line 2251 of file chan_skinny.c.
References ast_device_state(), AST_DEVICE_UNAVAILABLE, AST_EXTENSION_BUSY, AST_EXTENSION_DEACTIVATED, AST_EXTENSION_INUSE, AST_EXTENSION_NOT_INUSE, AST_EXTENSION_ONHOLD, AST_EXTENSION_REMOVED, AST_EXTENSION_RINGING, AST_EXTENSION_UNAVAILABLE, ast_get_hint(), AST_MAX_EXTENSION, ast_verb, skinny_speeddial::context, skinny_speeddial::exten, skinny_speeddial::instance, skinny_speeddial::laststate, skinny_device::name, skinny_speeddial::parent, SKINNY_CALLREMOTEMULTILINE, SKINNY_HOLD, SKINNY_LAMP_BLINK, SKINNY_LAMP_FLASH, SKINNY_LAMP_OFF, SKINNY_LAMP_ON, SKINNY_LAMP_WINK, SKINNY_ONHOOK, SKINNY_RINGIN, skinny_speeddial::stateid, STIMULUS_LINE, transmit_callstate(), and transmit_lamp_indication().
Referenced by skinny_register().
02252 { 02253 struct skinny_speeddial *sd = data; 02254 struct skinny_device *d = sd->parent; 02255 char hint[AST_MAX_EXTENSION]; 02256 int callstate = SKINNY_CALLREMOTEMULTILINE; 02257 int lamp = SKINNY_LAMP_OFF; 02258 02259 switch (state) { 02260 case AST_EXTENSION_DEACTIVATED: /* Retry after a while */ 02261 case AST_EXTENSION_REMOVED: /* Extension is gone */ 02262 ast_verb(2, "Extension state: Watcher for hint %s %s. Notify Device %s\n", exten, state == AST_EXTENSION_DEACTIVATED ? "deactivated" : "removed", d->name); 02263 sd->stateid = -1; 02264 callstate = SKINNY_ONHOOK; 02265 lamp = SKINNY_LAMP_OFF; 02266 break; 02267 case AST_EXTENSION_RINGING: 02268 case AST_EXTENSION_UNAVAILABLE: 02269 callstate = SKINNY_RINGIN; 02270 lamp = SKINNY_LAMP_BLINK; 02271 break; 02272 case AST_EXTENSION_BUSY: /* callstate = SKINNY_BUSY wasn't wanting to work - I'll settle for this */ 02273 case AST_EXTENSION_INUSE: 02274 callstate = SKINNY_CALLREMOTEMULTILINE; 02275 lamp = SKINNY_LAMP_ON; 02276 break; 02277 case AST_EXTENSION_ONHOLD: 02278 callstate = SKINNY_HOLD; 02279 lamp = SKINNY_LAMP_WINK; 02280 break; 02281 case AST_EXTENSION_NOT_INUSE: 02282 default: 02283 callstate = SKINNY_ONHOOK; 02284 lamp = SKINNY_LAMP_OFF; 02285 break; 02286 } 02287 02288 if (ast_get_hint(hint, sizeof(hint), NULL, 0, NULL, sd->context, sd->exten)) { 02289 /* If they are not registered, we will override notification and show no availability */ 02290 if (ast_device_state(hint) == AST_DEVICE_UNAVAILABLE) { 02291 callstate = SKINNY_ONHOOK; 02292 lamp = SKINNY_LAMP_FLASH; 02293 } 02294 } 02295 02296 transmit_lamp_indication(d, STIMULUS_LINE, sd->instance, lamp); 02297 transmit_callstate(d, sd->instance, callstate, 0); 02298 sd->laststate = state; 02299 02300 return 0; 02301 }
static int skinny_fixup | ( | struct ast_channel * | oldchan, | |
struct ast_channel * | newchan | |||
) | [static] |
Definition at line 3658 of file chan_skinny.c.
References ast_log(), LOG_NOTICE, LOG_WARNING, ast_channel::name, skinny_subchannel::owner, and ast_channel::tech_pvt.
03659 { 03660 struct skinny_subchannel *sub = newchan->tech_pvt; 03661 ast_log(LOG_NOTICE, "skinny_fixup(%s, %s)\n", oldchan->name, newchan->name); 03662 if (sub->owner != oldchan) { 03663 ast_log(LOG_WARNING, "old channel wasn't %p but was %p\n", oldchan, sub->owner); 03664 return -1; 03665 } 03666 sub->owner = newchan; 03667 return 0; 03668 }
static enum ast_rtp_get_result skinny_get_rtp_peer | ( | struct ast_channel * | c, | |
struct ast_rtp ** | rtp | |||
) | [static] |
Definition at line 2380 of file chan_skinny.c.
References ast_mutex_lock(), ast_mutex_unlock(), AST_RTP_GET_FAILED, AST_RTP_TRY_NATIVE, AST_RTP_TRY_PARTIAL, ast_verb, skinny_line::canreinvite, ast_channel::name, skinny_line::nat, skinny_subchannel::rtp, skinny_line::sub, and ast_channel::tech_pvt.
02381 { 02382 struct skinny_subchannel *sub = NULL; 02383 struct skinny_line *l; 02384 enum ast_rtp_get_result res = AST_RTP_TRY_NATIVE; 02385 02386 if (skinnydebug) 02387 ast_verb(1, "skinny_get_rtp_peer() Channel = %s\n", c->name); 02388 02389 02390 if (!(sub = c->tech_pvt)) 02391 return AST_RTP_GET_FAILED; 02392 02393 ast_mutex_lock(&sub->lock); 02394 02395 if (!(sub->rtp)){ 02396 ast_mutex_unlock(&sub->lock); 02397 return AST_RTP_GET_FAILED; 02398 } 02399 02400 *rtp = sub->rtp; 02401 02402 l = sub->parent; 02403 02404 if (!l->canreinvite || l->nat){ 02405 res = AST_RTP_TRY_PARTIAL; 02406 if (skinnydebug) 02407 ast_verb(1, "skinny_get_rtp_peer() Using AST_RTP_TRY_PARTIAL \n"); 02408 } 02409 02410 ast_mutex_unlock(&sub->lock); 02411 02412 return res; 02413 02414 }
static enum ast_rtp_get_result skinny_get_vrtp_peer | ( | struct ast_channel * | c, | |
struct ast_rtp ** | rtp | |||
) | [static] |
Definition at line 2368 of file chan_skinny.c.
References AST_RTP_GET_FAILED, AST_RTP_TRY_NATIVE, skinny_subchannel::rtp, ast_channel::tech_pvt, and skinny_subchannel::vrtp.
02369 { 02370 struct skinny_subchannel *sub = NULL; 02371 02372 if (!(sub = c->tech_pvt) || !(sub->vrtp)) 02373 return AST_RTP_GET_FAILED; 02374 02375 *rtp = sub->vrtp; 02376 02377 return AST_RTP_TRY_NATIVE; 02378 }
static int skinny_hangup | ( | struct ast_channel * | ast | ) | [static] |
Definition at line 3454 of file chan_skinny.c.
References skinny_device::activeline, skinny_line::activesub, skinny_subchannel::alreadygone, ast_debug, ast_free, AST_LIST_EMPTY, AST_LIST_FIRST, AST_LIST_NEXT, AST_LIST_REMOVE, ast_mutex_lock(), ast_mutex_unlock(), ast_rtp_destroy(), skinny_subchannel::callid, skinny_line::hookstate, skinny_line::instance, skinny_subchannel::lock, skinny_subchannel::outgoing, skinny_subchannel::owner, skinny_line::parent, skinny_subchannel::parent, skinny_device::registered, skinny_subchannel::related, skinny_subchannel::rtp, s, skinny_device::session, SKINNY_LAMP_BLINK, SKINNY_LAMP_OFF, SKINNY_LAMP_ON, SKINNY_ONHOOK, SKINNY_RING_OFF, SKINNY_SILENCE, SKINNY_SPEAKEROFF, STIMULUS_LINE, skinny_line::sub, ast_channel::tech_pvt, transmit_activatecallplane(), transmit_callstate(), transmit_closereceivechannel(), transmit_lamp_indication(), transmit_ringer_mode(), transmit_speaker_mode(), transmit_stopmediatransmission(), and transmit_tone().
03455 { 03456 struct skinny_subchannel *sub = ast->tech_pvt; 03457 struct skinny_line *l; 03458 struct skinny_device *d; 03459 struct skinnysession *s; 03460 03461 if (!sub) { 03462 ast_debug(1, "Asked to hangup channel not connected\n"); 03463 return 0; 03464 } 03465 l = sub->parent; 03466 d = l->parent; 03467 s = d->session; 03468 03469 AST_LIST_REMOVE(&l->sub, sub, list); 03470 03471 if (d->registered) { 03472 /* Ignoring l->type, doesn't seem relevant and previous code 03473 assigned rather than tested, ie always true */ 03474 if (!AST_LIST_EMPTY(&l->sub)) { 03475 if (sub->related) { 03476 sub->related->related = NULL; 03477 03478 } 03479 if (sub == l->activesub) { /* we are killing the active sub, but there are other subs on the line*/ 03480 if (sub->related) { 03481 l->activesub = sub->related; 03482 } else { 03483 if (AST_LIST_NEXT(sub, list)) { 03484 l->activesub = AST_LIST_NEXT(sub, list); 03485 } else { 03486 l->activesub = AST_LIST_FIRST(&l->sub); 03487 } 03488 } 03489 transmit_callstate(d, l->instance, SKINNY_ONHOOK, sub->callid); 03490 transmit_activatecallplane(d, l); 03491 transmit_closereceivechannel(d, sub); 03492 transmit_stopmediatransmission(d, sub); 03493 transmit_lamp_indication(d, STIMULUS_LINE, l->instance, SKINNY_LAMP_BLINK); 03494 transmit_tone(d, SKINNY_SILENCE, l->instance, sub->callid); 03495 } else { /* we are killing a background sub on the line with other subs*/ 03496 if (AST_LIST_NEXT(sub, list)) { 03497 transmit_lamp_indication(d, STIMULUS_LINE, l->instance, SKINNY_LAMP_BLINK); 03498 } else { 03499 transmit_lamp_indication(d, STIMULUS_LINE, l->instance, SKINNY_LAMP_ON); 03500 } 03501 } 03502 } else { /* no more subs on line so make idle */ 03503 03504 l->hookstate = SKINNY_ONHOOK; 03505 transmit_callstate(d, l->instance, SKINNY_ONHOOK, sub->callid); 03506 l->activesub = NULL; 03507 transmit_lamp_indication(d, STIMULUS_LINE, l->instance, SKINNY_LAMP_OFF); 03508 if (sub->parent == d->activeline) { 03509 transmit_activatecallplane(d, l); 03510 transmit_closereceivechannel(d, sub); 03511 transmit_stopmediatransmission(d, sub); 03512 transmit_speaker_mode(d, SKINNY_SPEAKEROFF); 03513 transmit_ringer_mode(d, SKINNY_RING_OFF); 03514 transmit_tone(d, SKINNY_SILENCE, l->instance, sub->callid); 03515 /* we should check to see if we can start the ringer if another line is ringing */ 03516 } 03517 } 03518 } 03519 ast_mutex_lock(&sub->lock); 03520 sub->owner = NULL; 03521 ast->tech_pvt = NULL; 03522 sub->alreadygone = 0; 03523 sub->outgoing = 0; 03524 if (sub->rtp) { 03525 ast_rtp_destroy(sub->rtp); 03526 sub->rtp = NULL; 03527 } 03528 ast_mutex_unlock(&sub->lock); 03529 ast_free(sub); 03530 return 0; 03531 }
static int skinny_hold | ( | struct skinny_subchannel * | sub | ) | [static] |
Definition at line 4029 of file chan_skinny.c.
References AST_CONTROL_HOLD, ast_queue_control_data(), ast_strlen_zero(), ast_verb, skinny_line::instance, skinny_line::mohsuggest, skinny_subchannel::onhold, skinny_subchannel::owner, skinny_line::parent, S_OR, SKINNY_HOLD, SKINNY_LAMP_WINK, STIMULUS_LINE, skinny_line::sub, transmit_activatecallplane(), transmit_callstateonly(), transmit_closereceivechannel(), transmit_lamp_indication(), and transmit_stopmediatransmission().
Referenced by handle_hold_button(), handle_soft_key_event_message(), and handle_transfer_button().
04030 { 04031 struct skinny_line *l = sub->parent; 04032 struct skinny_device *d = l->parent; 04033 04034 /* Don't try to hold a channel that doesn't exist */ 04035 if (!sub || !sub->owner) 04036 return 0; 04037 04038 /* Channel needs to be put on hold */ 04039 if (skinnydebug) 04040 ast_verb(1, "Putting on Hold(%d)\n", l->instance); 04041 04042 ast_queue_control_data(sub->owner, AST_CONTROL_HOLD, 04043 S_OR(l->mohsuggest, NULL), 04044 !ast_strlen_zero(l->mohsuggest) ? strlen(l->mohsuggest) + 1 : 0); 04045 04046 transmit_activatecallplane(d, l); 04047 transmit_closereceivechannel(d, sub); 04048 transmit_stopmediatransmission(d, sub); 04049 04050 transmit_callstateonly(d, sub, SKINNY_HOLD); 04051 transmit_lamp_indication(d, STIMULUS_LINE, l->instance, SKINNY_LAMP_WINK); 04052 sub->onhold = 1; 04053 return 1; 04054 }
static int skinny_indicate | ( | struct ast_channel * | ast, | |
int | ind, | |||
const void * | data, | |||
size_t | datalen | |||
) | [static] |
Definition at line 3829 of file chan_skinny.c.
References ast_channel::_state, skinny_subchannel::alreadygone, AST_CONTROL_BUSY, AST_CONTROL_CONGESTION, AST_CONTROL_HOLD, AST_CONTROL_PROCEEDING, AST_CONTROL_PROGRESS, AST_CONTROL_RINGING, AST_CONTROL_SRCUPDATE, AST_CONTROL_UNHOLD, ast_debug, ast_log(), ast_moh_start(), ast_moh_stop(), ast_rtp_new_source(), AST_SOFTHANGUP_DEV, ast_softhangup_nolock(), AST_STATE_UP, ast_verb, skinny_subchannel::blindxfer, skinny_subchannel::callid, ast_channel::cid, ast_callerid::cid_name, ast_callerid::cid_num, control2str(), skinny_device::earlyrtp, skinny_line::instance, skinny_line::lastnumberdialed, LOG_NOTICE, LOG_WARNING, skinny_line::mohinterpret, ast_channel::name, skinny_subchannel::outgoing, skinny_line::parent, skinny_subchannel::progress, skinny_subchannel::ringing, skinny_subchannel::rtp, s, skinny_device::session, SKINNY_ALERT, SKINNY_BUSY, SKINNY_BUSYTONE, SKINNY_CONGESTION, SKINNY_PROGRESS, SKINNY_REORDER, SKINNY_RINGOUT, SKINNY_SILENCE, skinny_transfer(), skinny_line::sub, ast_channel::tech_pvt, transmit_callinfo(), transmit_callstateonly(), transmit_dialednumber(), transmit_displaypromptstatus(), and transmit_tone().
03830 { 03831 struct skinny_subchannel *sub = ast->tech_pvt; 03832 struct skinny_line *l = sub->parent; 03833 struct skinny_device *d = l->parent; 03834 struct skinnysession *s = d->session; 03835 03836 if (!s) { 03837 ast_log(LOG_NOTICE, "Asked to indicate '%s' condition on channel %s, but session does not exist.\n", control2str(ind), ast->name); 03838 return -1; 03839 } 03840 03841 if (skinnydebug) 03842 ast_verb(3, "Asked to indicate '%s' condition on channel %s\n", control2str(ind), ast->name); 03843 switch(ind) { 03844 case AST_CONTROL_RINGING: 03845 if (sub->blindxfer) { 03846 if (skinnydebug) 03847 ast_debug(1, "Channel %s set up for Blind Xfer, so Xfer rather than ring device\n", ast->name); 03848 skinny_transfer(sub); 03849 break; 03850 } 03851 if (ast->_state != AST_STATE_UP) { 03852 if (!sub->progress) { 03853 if (!d->earlyrtp) { 03854 transmit_tone(d, SKINNY_ALERT, l->instance, sub->callid); 03855 } 03856 transmit_callstateonly(d, sub, SKINNY_RINGOUT); 03857 transmit_dialednumber(d, l->lastnumberdialed, l->instance, sub->callid); 03858 transmit_displaypromptstatus(d, "Ring Out", 0, l->instance, sub->callid); 03859 transmit_callinfo(d, ast->cid.cid_name, ast->cid.cid_num, l->lastnumberdialed, l->lastnumberdialed, l->instance, sub->callid, 2); /* 2 = outgoing from phone */ 03860 sub->ringing = 1; 03861 if (!d->earlyrtp) { 03862 break; 03863 } 03864 } 03865 } 03866 return -1; /* Tell asterisk to provide inband signalling */ 03867 case AST_CONTROL_BUSY: 03868 if (ast->_state != AST_STATE_UP) { 03869 if (!d->earlyrtp) { 03870 transmit_tone(d, SKINNY_BUSYTONE, l->instance, sub->callid); 03871 } 03872 transmit_callstateonly(d, sub, SKINNY_BUSY); 03873 sub->alreadygone = 1; 03874 ast_softhangup_nolock(ast, AST_SOFTHANGUP_DEV); 03875 if (!d->earlyrtp) { 03876 break; 03877 } 03878 } 03879 return -1; /* Tell asterisk to provide inband signalling */ 03880 case AST_CONTROL_CONGESTION: 03881 if (ast->_state != AST_STATE_UP) { 03882 if (!d->earlyrtp) { 03883 transmit_tone(d, SKINNY_REORDER, l->instance, sub->callid); 03884 } 03885 transmit_callstateonly(d, sub, SKINNY_CONGESTION); 03886 sub->alreadygone = 1; 03887 ast_softhangup_nolock(ast, AST_SOFTHANGUP_DEV); 03888 if (!d->earlyrtp) { 03889 break; 03890 } 03891 } 03892 return -1; /* Tell asterisk to provide inband signalling */ 03893 case AST_CONTROL_PROGRESS: 03894 if ((ast->_state != AST_STATE_UP) && !sub->progress && !sub->outgoing) { 03895 if (!d->earlyrtp) { 03896 transmit_tone(d, SKINNY_ALERT, l->instance, sub->callid); 03897 } 03898 transmit_callstateonly(d, sub, SKINNY_PROGRESS); 03899 transmit_displaypromptstatus(d, "Call Progress", 0, l->instance, sub->callid); 03900 transmit_callinfo(d, ast->cid.cid_name, ast->cid.cid_num, l->lastnumberdialed, l->lastnumberdialed, l->instance, sub->callid, 2); /* 2 = outgoing from phone */ 03901 sub->progress = 1; 03902 if (!d->earlyrtp) { 03903 break; 03904 } 03905 } 03906 return -1; /* Tell asterisk to provide inband signalling */ 03907 case -1: /* STOP_TONE */ 03908 transmit_tone(d, SKINNY_SILENCE, l->instance, sub->callid); 03909 break; 03910 case AST_CONTROL_HOLD: 03911 ast_moh_start(ast, data, l->mohinterpret); 03912 break; 03913 case AST_CONTROL_UNHOLD: 03914 ast_moh_stop(ast); 03915 break; 03916 case AST_CONTROL_PROCEEDING: 03917 break; 03918 case AST_CONTROL_SRCUPDATE: 03919 ast_rtp_new_source(sub->rtp); 03920 break; 03921 default: 03922 ast_log(LOG_WARNING, "Don't know how to indicate condition %d\n", ind); 03923 return -1; /* Tell asterisk to provide inband signalling */ 03924 } 03925 return 0; 03926 }
static struct ast_channel* skinny_new | ( | struct skinny_line * | l, | |
int | state | |||
) | [static] |
Definition at line 3928 of file chan_skinny.c.
References skinny_line::accountcode, skinny_line::activesub, ast_channel::adsicpe, ast_channel::amaflags, skinny_line::amaflags, AST_ADSI_UNAVAILABLE, ast_best_codec(), ast_calloc, ast_channel_alloc(), ast_channel_set_fd(), ast_copy_string(), AST_DEVICE_NOT_INUSE, ast_hangup(), ast_jb_configure(), AST_LIST_INSERT_HEAD, ast_log(), ast_module_ref(), ast_mutex_init(), ast_pbx_start(), ast_rtp_fd(), AST_STATE_DOWN, AST_STATE_RING, ast_strdup, ast_string_field_set, ast_strlen_zero(), ast_verb, skinny_line::call_forward_all, skinny_line::callgroup, ast_channel::callgroup, skinny_line::capability, skinny_line::cfwdtype, skinny_line::chanvars, ast_channel::cid, ast_callerid::cid_ani, skinny_line::cid_name, skinny_line::cid_num, ast_channel::context, skinny_line::context, ast_channel::exten, skinny_line::exten, get_devicestate(), global_jbconf, skinny_line::instance, skinny_line::language, skinny_device::lastcallreference, skinny_device::lastlineinstance, LOG_WARNING, ast_variable::name, skinny_device::name, skinny_line::name, skinny_line::nat, ast_channel::nativeformats, ast_variable::next, skinny_line::parent, pbx_builtin_setvar_helper(), skinny_line::pickupgroup, ast_channel::pickupgroup, ast_channel::priority, ast_channel::rawreadformat, ast_channel::rawwriteformat, ast_channel::readformat, ast_channel::rings, SKINNY_CFWD_ALL, SKINNY_CFWD_BUSY, SKINNY_CX_INACTIVE, skinny_tech, skinny_line::sub, ast_channel::tech, ast_channel::tech_pvt, ast_variable::value, and ast_channel::writeformat.
Referenced by handle_enbloc_call_message(), handle_offhook_message(), handle_soft_key_event_message(), handle_stimulus_message(), handle_transfer_button(), and skinny_request().
03929 { 03930 struct ast_channel *tmp; 03931 struct skinny_subchannel *sub; 03932 struct skinny_device *d = l->parent; 03933 struct ast_variable *v = NULL; 03934 int fmt; 03935 03936 tmp = ast_channel_alloc(1, state, l->cid_num, l->cid_name, l->accountcode, l->exten, l->context, l->amaflags, "Skinny/%s@%s-%d", l->name, d->name, callnums); 03937 if (!tmp) { 03938 ast_log(LOG_WARNING, "Unable to allocate channel structure\n"); 03939 return NULL; 03940 } else { 03941 sub = ast_calloc(1, sizeof(*sub)); 03942 if (!sub) { 03943 ast_log(LOG_WARNING, "Unable to allocate Skinny subchannel\n"); 03944 return NULL; 03945 } else { 03946 ast_mutex_init(&sub->lock); 03947 03948 sub->owner = tmp; 03949 sub->callid = callnums++; 03950 d->lastlineinstance = l->instance; 03951 d->lastcallreference = sub->callid; 03952 sub->cxmode = SKINNY_CX_INACTIVE; 03953 sub->nat = l->nat; 03954 sub->parent = l; 03955 sub->onhold = 0; 03956 sub->blindxfer = 0; 03957 sub->xferor = 0; 03958 sub->related = NULL; 03959 03960 AST_LIST_INSERT_HEAD(&l->sub, sub, list); 03961 l->activesub = sub; 03962 } 03963 tmp->tech = &skinny_tech; 03964 tmp->tech_pvt = sub; 03965 tmp->nativeformats = l->capability; 03966 if (!tmp->nativeformats) 03967 tmp->nativeformats = default_capability; 03968 fmt = ast_best_codec(tmp->nativeformats); 03969 if (skinnydebug) 03970 ast_verb(1, "skinny_new: tmp->nativeformats=%d fmt=%d\n", tmp->nativeformats, fmt); 03971 if (sub->rtp) { 03972 ast_channel_set_fd(tmp, 0, ast_rtp_fd(sub->rtp)); 03973 } 03974 if (state == AST_STATE_RING) { 03975 tmp->rings = 1; 03976 } 03977 tmp->writeformat = fmt; 03978 tmp->rawwriteformat = fmt; 03979 tmp->readformat = fmt; 03980 tmp->rawreadformat = fmt; 03981 if (!ast_strlen_zero(l->language)) 03982 ast_string_field_set(tmp, language, l->language); 03983 if (!ast_strlen_zero(l->accountcode)) 03984 ast_string_field_set(tmp, accountcode, l->accountcode); 03985 if (l->amaflags) 03986 tmp->amaflags = l->amaflags; 03987 03988 ast_module_ref(ast_module_info->self); 03989 tmp->callgroup = l->callgroup; 03990 tmp->pickupgroup = l->pickupgroup; 03991 03992 /* XXX Need to figure out how to handle CFwdNoAnswer */ 03993 if (l->cfwdtype & SKINNY_CFWD_ALL) { 03994 ast_string_field_set(tmp, call_forward, l->call_forward_all); 03995 } else if (l->cfwdtype & SKINNY_CFWD_BUSY) { 03996 if (get_devicestate(l) != AST_DEVICE_NOT_INUSE) { 03997 ast_string_field_set(tmp, call_forward, l->call_forward_busy); 03998 } 03999 } 04000 04001 ast_copy_string(tmp->context, l->context, sizeof(tmp->context)); 04002 ast_copy_string(tmp->exten, l->exten, sizeof(tmp->exten)); 04003 04004 /* Don't use ast_set_callerid() here because it will 04005 * generate a needless NewCallerID event */ 04006 tmp->cid.cid_ani = ast_strdup(l->cid_num); 04007 04008 tmp->priority = 1; 04009 tmp->adsicpe = AST_ADSI_UNAVAILABLE; 04010 04011 if (sub->rtp) 04012 ast_jb_configure(tmp, &global_jbconf); 04013 04014 /* Set channel variables for this call from configuration */ 04015 for (v = l->chanvars ; v ; v = v->next) 04016 pbx_builtin_setvar_helper(tmp, v->name, v->value); 04017 04018 if (state != AST_STATE_DOWN) { 04019 if (ast_pbx_start(tmp)) { 04020 ast_log(LOG_WARNING, "Unable to start PBX on %s\n", tmp->name); 04021 ast_hangup(tmp); 04022 tmp = NULL; 04023 } 04024 } 04025 } 04026 return tmp; 04027 }
static void* skinny_newcall | ( | void * | data | ) | [static] |
Definition at line 3274 of file chan_skinny.c.
References ast_copy_string(), ast_log(), ast_pbx_run(), ast_set_callerid(), ast_setstate(), AST_STATE_RING, skinny_subchannel::callid, ast_channel::cid, ast_callerid::cid_ani, skinny_line::cid_name, skinny_line::cid_num, ast_channel::exten, skinny_line::hidecallerid, skinny_line::instance, skinny_line::lastnumberdialed, LOG_WARNING, skinny_line::parent, skinny_subchannel::rtp, SKINNY_REORDER, start_rtp(), skinny_line::sub, ast_channel::tech_pvt, and transmit_tone().
Referenced by handle_enbloc_call_message(), handle_soft_key_event_message(), handle_stimulus_message(), and skinny_ss().
03275 { 03276 struct ast_channel *c = data; 03277 struct skinny_subchannel *sub = c->tech_pvt; 03278 struct skinny_line *l = sub->parent; 03279 struct skinny_device *d = l->parent; 03280 int res = 0; 03281 03282 ast_copy_string(l->lastnumberdialed, c->exten, sizeof(l->lastnumberdialed)); 03283 ast_set_callerid(c, 03284 l->hidecallerid ? "" : l->cid_num, 03285 l->hidecallerid ? "" : l->cid_name, 03286 c->cid.cid_ani ? NULL : l->cid_num); 03287 ast_setstate(c, AST_STATE_RING); 03288 if (!sub->rtp) { 03289 start_rtp(sub); 03290 } 03291 res = ast_pbx_run(c); 03292 if (res) { 03293 ast_log(LOG_WARNING, "PBX exited non-zero\n"); 03294 transmit_tone(d, SKINNY_REORDER, l->instance, sub->callid); 03295 } 03296 return NULL; 03297 }
static struct ast_frame * skinny_read | ( | struct ast_channel * | ast | ) | [static] |
Definition at line 3620 of file chan_skinny.c.
References ast_mutex_lock(), ast_mutex_unlock(), skinny_subchannel::lock, skinny_rtp_read(), and ast_channel::tech_pvt.
03621 { 03622 struct ast_frame *fr; 03623 struct skinny_subchannel *sub = ast->tech_pvt; 03624 ast_mutex_lock(&sub->lock); 03625 fr = skinny_rtp_read(sub); 03626 ast_mutex_unlock(&sub->lock); 03627 return fr; 03628 }
static int skinny_register | ( | struct skinny_req * | req, | |
struct skinnysession * | s | |||
) | [static] |
Definition at line 1759 of file chan_skinny.c.
References ast_apply_ha(), ast_copy_string(), AST_DEVICE_NOT_INUSE, ast_devstate_changed(), ast_extension_state_add(), AST_LIST_LOCK, AST_LIST_TRAVERSE, AST_LIST_UNLOCK, ast_log(), ast_strlen_zero(), skinny_speeddial::context, skinny_req::data, skinny_speeddial::exten, skinny_device::ha, skinny_device::id, letohl, skinny_device::lines, LOG_WARNING, skinny_device::name, skinny_line::name, register_message::name, skinny_device::ourip, skinny_data::reg, register_exten(), skinny_device::registered, s, skinny_device::session, skinny_extensionstate_cb(), skinny_device::speeddials, skinny_speeddial::stateid, register_message::type, skinny_device::type, and skinny_device::version_id.
Referenced by handle_register_message().
01760 { 01761 struct skinny_device *d; 01762 struct skinny_line *l; 01763 struct skinny_speeddial *sd; 01764 struct sockaddr_in sin; 01765 socklen_t slen; 01766 01767 AST_LIST_LOCK(&devices); 01768 AST_LIST_TRAVERSE(&devices, d, list){ 01769 if (!strcasecmp(req->data.reg.name, d->id) 01770 && ast_apply_ha(d->ha, &(s->sin))) { 01771 s->device = d; 01772 d->type = letohl(req->data.reg.type); 01773 if (ast_strlen_zero(d->version_id)) { 01774 ast_copy_string(d->version_id, version_id, sizeof(d->version_id)); 01775 } 01776 d->registered = 1; 01777 d->session = s; 01778 01779 slen = sizeof(sin); 01780 if (getsockname(s->fd, (struct sockaddr *)&sin, &slen)) { 01781 ast_log(LOG_WARNING, "Cannot get socket name\n"); 01782 sin.sin_addr = __ourip; 01783 } 01784 d->ourip = sin.sin_addr; 01785 01786 AST_LIST_TRAVERSE(&d->speeddials, sd, list) { 01787 sd->stateid = ast_extension_state_add(sd->context, sd->exten, skinny_extensionstate_cb, sd); 01788 } 01789 AST_LIST_TRAVERSE(&d->lines, l, list) { 01790 register_exten(l); 01791 ast_devstate_changed(AST_DEVICE_NOT_INUSE, "Skinny/%s@%s", l->name, d->name); 01792 } 01793 break; 01794 } 01795 } 01796 AST_LIST_UNLOCK(&devices); 01797 if (!d) { 01798 return 0; 01799 } 01800 return 1; 01801 }
static struct skinny_req* skinny_req_parse | ( | struct skinnysession * | s | ) | [static] |
Definition at line 5961 of file chan_skinny.c.
References ast_calloc, ast_free, ast_log(), ast_mutex_lock(), ast_mutex_unlock(), skinny_req::data, skinny_req::e, letohl, LOG_ERROR, s, and SKINNY_MAX_PACKET.
Referenced by skinny_session().
05962 { 05963 struct skinny_req *req; 05964 05965 if (!(req = ast_calloc(1, SKINNY_MAX_PACKET))) 05966 return NULL; 05967 05968 ast_mutex_lock(&s->lock); 05969 memcpy(req, s->inbuf, skinny_header_size); 05970 memcpy(&req->data, s->inbuf+skinny_header_size, letohl(*(int*)(s->inbuf))-4); 05971 05972 ast_mutex_unlock(&s->lock); 05973 05974 if (letohl(req->e) < 0) { 05975 ast_log(LOG_ERROR, "Event Message is NULL from socket %d, This is bad\n", s->fd); 05976 ast_free(req); 05977 return NULL; 05978 } 05979 05980 return req; 05981 }
static struct ast_channel * skinny_request | ( | const char * | type, | |
int | format, | |||
void * | data, | |||
int * | cause | |||
) | [static] |
Definition at line 6127 of file chan_skinny.c.
References ast_copy_string(), AST_FORMAT_AUDIO_MASK, ast_log(), AST_STATE_DOWN, ast_strlen_zero(), ast_verb, find_line_by_name(), LOG_NOTICE, LOG_WARNING, restart_monitor(), and skinny_new().
06128 { 06129 int oldformat; 06130 06131 struct skinny_line *l; 06132 struct ast_channel *tmpc = NULL; 06133 char tmp[256]; 06134 char *dest = data; 06135 06136 oldformat = format; 06137 06138 if (!(format &= AST_FORMAT_AUDIO_MASK)) { 06139 ast_log(LOG_NOTICE, "Asked to get a channel of unsupported format '%d'\n", format); 06140 return NULL; 06141 } 06142 06143 ast_copy_string(tmp, dest, sizeof(tmp)); 06144 if (ast_strlen_zero(tmp)) { 06145 ast_log(LOG_NOTICE, "Skinny channels require a device\n"); 06146 return NULL; 06147 } 06148 l = find_line_by_name(tmp); 06149 if (!l) { 06150 ast_log(LOG_NOTICE, "No available lines on: %s\n", dest); 06151 return NULL; 06152 } 06153 ast_verb(3, "skinny_request(%s)\n", tmp); 06154 tmpc = skinny_new(l, AST_STATE_DOWN); 06155 if (!tmpc) { 06156 ast_log(LOG_WARNING, "Unable to make channel for '%s'\n", tmp); 06157 } 06158 restart_monitor(); 06159 return tmpc; 06160 }
static struct ast_frame* skinny_rtp_read | ( | struct skinny_subchannel * | sub | ) | [static] |
Definition at line 3573 of file chan_skinny.c.
References ast_debug, AST_FRAME_VOICE, ast_null_frame, ast_rtcp_read(), ast_rtp_read(), ast_set_read_format(), ast_set_write_format(), ast_udptl_read(), f, ast_channel::fdno, ast_channel::nativeformats, skinny_subchannel::owner, ast_channel::readformat, skinny_subchannel::rtp, skinny_subchannel::vrtp, and ast_channel::writeformat.
Referenced by skinny_read().
03574 { 03575 struct ast_channel *ast = sub->owner; 03576 struct ast_frame *f; 03577 03578 if (!sub->rtp) { 03579 /* We have no RTP allocated for this channel */ 03580 return &ast_null_frame; 03581 } 03582 03583 switch(ast->fdno) { 03584 case 0: 03585 f = ast_rtp_read(sub->rtp); /* RTP Audio */ 03586 break; 03587 case 1: 03588 f = ast_rtcp_read(sub->rtp); /* RTCP Control Channel */ 03589 break; 03590 case 2: 03591 f = ast_rtp_read(sub->vrtp); /* RTP Video */ 03592 break; 03593 case 3: 03594 f = ast_rtcp_read(sub->vrtp); /* RTCP Control Channel for video */ 03595 break; 03596 #if 0 03597 case 5: 03598 /* Not yet supported */ 03599 f = ast_udptl_read(sub->udptl); /* UDPTL for T.38 */ 03600 break; 03601 #endif 03602 default: 03603 f = &ast_null_frame; 03604 } 03605 03606 if (ast) { 03607 /* We already hold the channel lock */ 03608 if (f->frametype == AST_FRAME_VOICE) { 03609 if (f->subclass != ast->nativeformats) { 03610 ast_debug(1, "Oooh, format changed to %d\n", f->subclass); 03611 ast->nativeformats = f->subclass; 03612 ast_set_read_format(ast, ast->readformat); 03613 ast_set_write_format(ast, ast->writeformat); 03614 } 03615 } 03616 } 03617 return f; 03618 }
static int skinny_senddigit_begin | ( | struct ast_channel * | ast, | |
char | digit | |||
) | [static] |
static int skinny_senddigit_end | ( | struct ast_channel * | ast, | |
char | digit, | |||
unsigned int | duration | |||
) | [static] |
Definition at line 3675 of file chan_skinny.c.
References skinny_subchannel::callid, skinny_line::instance, skinny_line::parent, skinny_line::sub, ast_channel::tech_pvt, and transmit_tone().
03676 { 03677 #if 0 03678 struct skinny_subchannel *sub = ast->tech_pvt; 03679 struct skinny_line *l = sub->parent; 03680 struct skinny_device *d = l->parent; 03681 int tmp; 03682 /* not right */ 03683 sprintf(tmp, "%d", digit); 03684 transmit_tone(d, digit, l->instance, sub->callid); 03685 #endif 03686 return -1; /* Stop inband indications */ 03687 }
static void* skinny_session | ( | void * | data | ) | [static] |
Definition at line 5983 of file chan_skinny.c.
References ast_debug, ast_inet_ntoa(), ast_verb, destroy_session(), errno, get_input(), handle_message(), skinny_req::res, s, and skinny_req_parse().
Referenced by accept_thread().
05984 { 05985 int res; 05986 struct skinny_req *req; 05987 struct skinnysession *s = data; 05988 05989 ast_verb(3, "Starting Skinny session from %s\n", ast_inet_ntoa(s->sin.sin_addr)); 05990 05991 for (;;) { 05992 res = get_input(s); 05993 if (res < 0) { 05994 break; 05995 } 05996 05997 if (res > 0) 05998 { 05999 if (!(req = skinny_req_parse(s))) { 06000 destroy_session(s); 06001 return NULL; 06002 } 06003 06004 res = handle_message(req, s); 06005 if (res < 0) { 06006 destroy_session(s); 06007 return NULL; 06008 } 06009 } 06010 } 06011 ast_debug(3, "Skinny Session returned: %s\n", strerror(errno)); 06012 06013 if (s) 06014 destroy_session(s); 06015 06016 return 0; 06017 }
static int skinny_set_rtp_peer | ( | struct ast_channel * | c, | |
struct ast_rtp * | rtp, | |||
struct ast_rtp * | vrtp, | |||
struct ast_rtp * | trtp, | |||
int | codecs, | |||
int | nat_active | |||
) | [static] |
Definition at line 2416 of file chan_skinny.c.
References ast_channel::_state, ast_best_codec(), ast_codec_pref_getsize(), ast_inet_ntoa(), ast_rtp_get_peer(), ast_rtp_get_us(), AST_STATE_UP, ast_verb, media_qualifier::bitRate, ast_format_list::bits, skinny_subchannel::callid, skinny_line::canreinvite, skinny_line::capability, codec_ast2skinny(), start_media_transmission_message::conferenceId, stop_media_transmission_message::conferenceId, ast_format_list::cur_ms, skinny_req::data, htolel, skinny_line::nat, skinny_device::ourip, media_qualifier::packets, start_media_transmission_message::packetSize, skinny_line::parent, skinny_subchannel::parent, start_media_transmission_message::passThruPartyId, stop_media_transmission_message::passThruPartyId, start_media_transmission_message::payloadType, media_qualifier::precedence, skinny_line::prefs, start_media_transmission_message::qualifier, start_media_transmission_message::remoteIp, start_media_transmission_message::remotePort, req_alloc(), skinny_subchannel::rtp, s, skinny_device::session, START_MEDIA_TRANSMISSION_MESSAGE, skinny_data::startmedia, STOP_MEDIA_TRANSMISSION_MESSAGE, skinny_data::stopmedia, ast_channel::tech_pvt, transmit_response(), and media_qualifier::vad.
02417 { 02418 struct skinny_subchannel *sub; 02419 struct skinny_line *l; 02420 struct skinny_device *d; 02421 struct skinnysession *s; 02422 struct ast_format_list fmt; 02423 struct sockaddr_in us; 02424 struct sockaddr_in them; 02425 struct skinny_req *req; 02426 02427 sub = c->tech_pvt; 02428 02429 if (c->_state != AST_STATE_UP) 02430 return 0; 02431 02432 if (!sub) { 02433 return -1; 02434 } 02435 02436 l = sub->parent; 02437 d = l->parent; 02438 s = d->session; 02439 02440 if (rtp){ 02441 ast_rtp_get_peer(rtp, &them); 02442 02443 /* Shutdown any early-media or previous media on re-invite */ 02444 if (!(req = req_alloc(sizeof(struct stop_media_transmission_message), STOP_MEDIA_TRANSMISSION_MESSAGE))) 02445 return -1; 02446 02447 req->data.stopmedia.conferenceId = htolel(sub->callid); 02448 req->data.stopmedia.passThruPartyId = htolel(sub->callid); 02449 transmit_response(d, req); 02450 02451 if (skinnydebug) 02452 ast_verb(1, "Peerip = %s:%d\n", ast_inet_ntoa(them.sin_addr), ntohs(them.sin_port)); 02453 02454 if (!(req = req_alloc(sizeof(struct start_media_transmission_message), START_MEDIA_TRANSMISSION_MESSAGE))) 02455 return -1; 02456 02457 fmt = ast_codec_pref_getsize(&l->prefs, ast_best_codec(l->capability)); 02458 02459 if (skinnydebug) 02460 ast_verb(1, "Setting payloadType to '%d' (%d ms)\n", fmt.bits, fmt.cur_ms); 02461 02462 req->data.startmedia.conferenceId = htolel(sub->callid); 02463 req->data.startmedia.passThruPartyId = htolel(sub->callid); 02464 if (!(l->canreinvite) || (l->nat)){ 02465 ast_rtp_get_us(rtp, &us); 02466 req->data.startmedia.remoteIp = htolel(d->ourip.s_addr); 02467 req->data.startmedia.remotePort = htolel(ntohs(us.sin_port)); 02468 } else { 02469 req->data.startmedia.remoteIp = htolel(them.sin_addr.s_addr); 02470 req->data.startmedia.remotePort = htolel(ntohs(them.sin_port)); 02471 } 02472 req->data.startmedia.packetSize = htolel(fmt.cur_ms); 02473 req->data.startmedia.payloadType = htolel(codec_ast2skinny(fmt.bits)); 02474 req->data.startmedia.qualifier.precedence = htolel(127); 02475 req->data.startmedia.qualifier.vad = htolel(0); 02476 req->data.startmedia.qualifier.packets = htolel(0); 02477 req->data.startmedia.qualifier.bitRate = htolel(0); 02478 transmit_response(d, req); 02479 02480 return 0; 02481 } 02482 /* Need a return here to break the bridge */ 02483 return 0; 02484 }
static void* skinny_ss | ( | void * | data | ) | [static] |
Definition at line 3299 of file chan_skinny.c.
References ast_channel::_state, ast_canmatch_extension(), ast_copy_string(), ast_debug, ast_exists_extension(), ast_hangup(), ast_ignore_pattern(), ast_indicate(), ast_log(), ast_matchmore_extension(), AST_MAX_EXTENSION, ast_safe_sleep(), AST_STATE_UP, ast_strlen_zero(), ast_verb, skinny_subchannel::callid, skinny_line::cfwdtype, ast_channel::cid, ast_callerid::cid_num, skinny_line::cid_num, ast_channel::context, ast_channel::exten, skinny_device::exten, skinny_line::getforward, skinny_line::hookstate, skinny_line::instance, skinny_line::lastnumberdialed, len(), LOG_WARNING, ast_channel::name, skinny_device::name, skinny_line::name, skinny_subchannel::owner, skinny_line::parent, set_callforwards(), SKINNY_DIALTONE, SKINNY_LAMP_ON, skinny_newcall(), SKINNY_OFFHOOK, SKINNY_REORDER, SKINNY_SILENCE, STIMULUS_FORWARDALL, skinny_line::sub, ast_channel::tech_pvt, transmit_cfwdstate(), transmit_displaynotify(), transmit_lamp_indication(), and transmit_tone().
Referenced by handle_callforward_button(), handle_offhook_message(), handle_soft_key_event_message(), handle_stimulus_message(), and handle_transfer_button().
03300 { 03301 struct ast_channel *c = data; 03302 struct skinny_subchannel *sub = c->tech_pvt; 03303 struct skinny_line *l = sub->parent; 03304 struct skinny_device *d = l->parent; 03305 int len = 0; 03306 int timeout = firstdigittimeout; 03307 int res = 0; 03308 int loop_pause = 100; 03309 03310 ast_verb(3, "Starting simple switch on '%s@%s'\n", l->name, d->name); 03311 03312 len = strlen(d->exten); 03313 03314 while (len < AST_MAX_EXTENSION-1) { 03315 res = 1; /* Assume that we will get a digit */ 03316 while (strlen(d->exten) == len){ 03317 ast_safe_sleep(c, loop_pause); 03318 timeout -= loop_pause; 03319 if ( (timeout -= loop_pause) <= 0){ 03320 res = 0; 03321 break; 03322 } 03323 res = 1; 03324 } 03325 03326 timeout = 0; 03327 len = strlen(d->exten); 03328 03329 if (!ast_ignore_pattern(c->context, d->exten)) { 03330 transmit_tone(d, SKINNY_SILENCE, l->instance, sub->callid); 03331 } 03332 if (ast_exists_extension(c, c->context, d->exten, 1, l->cid_num)) { 03333 if (!res || !ast_matchmore_extension(c, c->context, d->exten, 1, l->cid_num)) { 03334 if (l->getforward) { 03335 /* Record this as the forwarding extension */ 03336 set_callforwards(l, d->exten, l->getforward); 03337 ast_verb(3, "Setting call forward (%d) to '%s' on channel %s\n", 03338 l->cfwdtype, d->exten, c->name); 03339 transmit_tone(d, SKINNY_DIALTONE, l->instance, sub->callid); 03340 transmit_lamp_indication(d, STIMULUS_FORWARDALL, 1, SKINNY_LAMP_ON); 03341 transmit_displaynotify(d, "CFwd enabled", 10); 03342 transmit_cfwdstate(d, l); 03343 ast_safe_sleep(c, 500); 03344 ast_indicate(c, -1); 03345 ast_safe_sleep(c, 1000); 03346 memset(d->exten, 0, sizeof(d->exten)); 03347 len = 0; 03348 l->getforward = 0; 03349 if (sub->owner && sub->owner->_state != AST_STATE_UP) { 03350 ast_indicate(c, -1); 03351 ast_hangup(c); 03352 } 03353 return NULL; 03354 } else { 03355 ast_copy_string(c->exten, d->exten, sizeof(c->exten)); 03356 ast_copy_string(l->lastnumberdialed, d->exten, sizeof(l->lastnumberdialed)); 03357 memset(d->exten, 0, sizeof(d->exten)); 03358 skinny_newcall(c); 03359 return NULL; 03360 } 03361 } else { 03362 /* It's a match, but they just typed a digit, and there is an ambiguous match, 03363 so just set the timeout to matchdigittimeout and wait some more */ 03364 timeout = matchdigittimeout; 03365 } 03366 } else if (res == 0) { 03367 ast_debug(1, "Not enough digits (%s) (and no ambiguous match)...\n", d->exten); 03368 memset(d->exten, 0, sizeof(d->exten)); 03369 if (l->hookstate == SKINNY_OFFHOOK) { 03370 transmit_tone(d, SKINNY_REORDER, l->instance, sub->callid); 03371 } 03372 if (sub->owner && sub->owner->_state != AST_STATE_UP) { 03373 ast_indicate(c, -1); 03374 ast_hangup(c); 03375 } 03376 return NULL; 03377 } else if (!ast_canmatch_extension(c, c->context, d->exten, 1, c->cid.cid_num) && 03378 ((d->exten[0] != '*') || (!ast_strlen_zero(d->exten) > 2))) { 03379 ast_log(LOG_WARNING, "Can't match [%s] from '%s' in context %s\n", d->exten, c->cid.cid_num ? c->cid.cid_num : "<Unknown Caller>", c->context); 03380 memset(d->exten, 0, sizeof(d->exten)); 03381 if (l->hookstate == SKINNY_OFFHOOK) { 03382 transmit_tone(d, SKINNY_REORDER, l->instance, sub->callid); 03383 /* hang out for 3 seconds to let congestion play */ 03384 ast_safe_sleep(c, 3000); 03385 } 03386 break; 03387 } 03388 if (!timeout) { 03389 timeout = gendigittimeout; 03390 } 03391 if (len && !ast_ignore_pattern(c->context, d->exten)) { 03392 ast_indicate(c, -1); 03393 } 03394 } 03395 if (c) 03396 ast_hangup(c); 03397 memset(d->exten, 0, sizeof(d->exten)); 03398 return NULL; 03399 }
static int skinny_transfer | ( | struct skinny_subchannel * | sub | ) | [static] |
Definition at line 3766 of file chan_skinny.c.
References ast_bridged_channel(), ast_channel_masquerade(), AST_CONTROL_UNHOLD, ast_debug, ast_get_indication_tone(), ast_log(), ast_playtones_start(), ast_queue_control(), AST_STATE_RING, tone_zone_sound::data, LOG_DEBUG, LOG_WARNING, ast_channel::name, option_debug, skinny_subchannel::owner, skinny_subchannel::related, and skinny_subchannel::xferor.
Referenced by handle_transfer_button(), skinny_answer(), and skinny_indicate().
03767 { 03768 struct skinny_subchannel *xferor; /* the sub doing the transferring */ 03769 struct skinny_subchannel *xferee; /* the sub being transferred */ 03770 const struct tone_zone_sound *ts = NULL; 03771 03772 if (ast_bridged_channel(sub->owner) || ast_bridged_channel(sub->related->owner)) { 03773 if (sub->xferor) { 03774 xferor = sub; 03775 xferee = sub->related; 03776 } else { 03777 xferor = sub; 03778 xferee = sub->related; 03779 } 03780 03781 if (skinnydebug) { 03782 ast_debug(1, "Transferee channels (local/remote): %s and %s\n", 03783 xferee->owner->name, ast_bridged_channel(xferee->owner)?ast_bridged_channel(xferee->owner)->name:""); 03784 ast_debug(1, "Transferor channels (local/remote): %s and %s\n", 03785 xferor->owner->name, ast_bridged_channel(xferor->owner)?ast_bridged_channel(xferor->owner)->name:""); 03786 } 03787 if (ast_bridged_channel(xferor->owner)) { 03788 if (ast_bridged_channel(xferee->owner)) { 03789 ast_queue_control(xferee->owner, AST_CONTROL_UNHOLD); 03790 } 03791 if (xferor->owner->_state == AST_STATE_RING) { 03792 /* play ringing inband */ 03793 ts = ast_get_indication_tone(xferor->owner->zone, "ring"); 03794 ast_playtones_start(xferor->owner, 0, ts->data, 1); 03795 } 03796 if (skinnydebug) 03797 ast_debug(1, "Transfer Masquerading %s to %s\n", 03798 xferee->owner->name, ast_bridged_channel(xferor->owner)?ast_bridged_channel(xferor->owner)->name:""); 03799 if (ast_channel_masquerade(xferee->owner, ast_bridged_channel(xferor->owner))) { 03800 ast_log(LOG_WARNING, "Unable to masquerade %s as %s\n", 03801 ast_bridged_channel(xferor->owner)->name, xferee->owner->name); 03802 return -1; 03803 } 03804 } else if (ast_bridged_channel(xferee->owner)) { 03805 ast_queue_control(xferee->owner, AST_CONTROL_UNHOLD); 03806 if (xferor->owner->_state == AST_STATE_RING) { 03807 /* play ringing inband */ 03808 ts = ast_get_indication_tone(xferor->owner->zone, "ring"); 03809 ast_playtones_start(xferor->owner, 0, ts->data, 1); 03810 } 03811 if (skinnydebug) 03812 ast_debug(1, "Transfer Masquerading %s to %s\n", 03813 xferor->owner->name, ast_bridged_channel(xferee->owner)?ast_bridged_channel(xferee->owner)->name:""); 03814 if (ast_channel_masquerade(xferor->owner, ast_bridged_channel(xferee->owner))) { 03815 ast_log(LOG_WARNING, "Unable to masquerade %s as %s\n", 03816 ast_bridged_channel(xferee->owner)->name, xferor->owner->name); 03817 return -1; 03818 } 03819 return 0; 03820 } else { 03821 if (option_debug) 03822 ast_log(LOG_DEBUG, "Neither %s nor %s are in a bridge, nothing to transfer\n", 03823 xferor->owner->name, xferee->owner->name); 03824 } 03825 } 03826 return 0; 03827 }
static int skinny_unhold | ( | struct skinny_subchannel * | sub | ) | [static] |
Definition at line 4056 of file chan_skinny.c.
References AST_CONTROL_UNHOLD, ast_queue_control(), ast_verb, skinny_line::hookstate, skinny_line::instance, skinny_subchannel::onhold, skinny_subchannel::owner, skinny_line::parent, SKINNY_CONNECTED, SKINNY_LAMP_ON, SKINNY_OFFHOOK, STIMULUS_LINE, skinny_line::sub, transmit_activatecallplane(), transmit_callstateonly(), transmit_connect(), and transmit_lamp_indication().
Referenced by handle_hold_button(), and handle_soft_key_event_message().
04057 { 04058 struct skinny_line *l = sub->parent; 04059 struct skinny_device *d = l->parent; 04060 04061 /* Don't try to unhold a channel that doesn't exist */ 04062 if (!sub || !sub->owner) 04063 return 0; 04064 04065 /* Channel is on hold, so we will unhold */ 04066 if (skinnydebug) 04067 ast_verb(1, "Taking off Hold(%d)\n", l->instance); 04068 04069 ast_queue_control(sub->owner, AST_CONTROL_UNHOLD); 04070 04071 transmit_activatecallplane(d, l); 04072 04073 transmit_connect(d, sub); 04074 transmit_callstateonly(d, sub, SKINNY_CONNECTED); 04075 transmit_lamp_indication(d, STIMULUS_LINE, l->instance, SKINNY_LAMP_ON); 04076 l->hookstate = SKINNY_OFFHOOK; 04077 sub->onhold = 0; 04078 return 1; 04079 }
static int skinny_unregister | ( | struct skinny_req * | req, | |
struct skinnysession * | s | |||
) | [static] |
Definition at line 1803 of file chan_skinny.c.
References AST_DEVICE_UNAVAILABLE, ast_devstate_changed(), ast_extension_state_del(), AST_LIST_TRAVERSE, skinny_device::lines, skinny_device::name, skinny_line::name, skinny_device::registered, s, skinny_device::session, skinny_device::speeddials, skinny_speeddial::stateid, and unregister_exten().
Referenced by get_input(), handle_unregister_message(), and transmit_response().
01804 { 01805 struct skinny_device *d; 01806 struct skinny_line *l; 01807 struct skinny_speeddial *sd; 01808 01809 d = s->device; 01810 01811 if (d) { 01812 d->session = NULL; 01813 d->registered = 0; 01814 01815 AST_LIST_TRAVERSE(&d->speeddials, sd, list) { 01816 if (sd->stateid > -1) 01817 ast_extension_state_del(sd->stateid, NULL); 01818 } 01819 AST_LIST_TRAVERSE(&d->lines, l, list) { 01820 unregister_exten(l); 01821 ast_devstate_changed(AST_DEVICE_UNAVAILABLE, "Skinny/%s@%s", l->name, d->name); 01822 } 01823 } 01824 01825 return -1; /* main loop will destroy the session */ 01826 }
static int skinny_write | ( | struct ast_channel * | ast, | |
struct ast_frame * | frame | |||
) | [static] |
Definition at line 3630 of file chan_skinny.c.
References AST_FRAME_IMAGE, AST_FRAME_VOICE, ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_rtp_write(), ast_frame::frametype, skinny_subchannel::lock, LOG_WARNING, ast_channel::nativeformats, ast_channel::readformat, skinny_subchannel::rtp, ast_frame::subclass, ast_channel::tech_pvt, and ast_channel::writeformat.
03631 { 03632 struct skinny_subchannel *sub = ast->tech_pvt; 03633 int res = 0; 03634 if (frame->frametype != AST_FRAME_VOICE) { 03635 if (frame->frametype == AST_FRAME_IMAGE) { 03636 return 0; 03637 } else { 03638 ast_log(LOG_WARNING, "Can't send %d type frames with skinny_write\n", frame->frametype); 03639 return 0; 03640 } 03641 } else { 03642 if (!(frame->subclass & ast->nativeformats)) { 03643 ast_log(LOG_WARNING, "Asked to transmit frame type %d, while native formats is %d (read/write = %d/%d)\n", 03644 frame->subclass, ast->nativeformats, ast->readformat, ast->writeformat); 03645 return -1; 03646 } 03647 } 03648 if (sub) { 03649 ast_mutex_lock(&sub->lock); 03650 if (sub->rtp) { 03651 res = ast_rtp_write(sub->rtp, frame); 03652 } 03653 ast_mutex_unlock(&sub->lock); 03654 } 03655 return res; 03656 }
static void start_rtp | ( | struct skinny_subchannel * | sub | ) | [static] |
Definition at line 3237 of file chan_skinny.c.
References ast_channel_set_fd(), ast_mutex_lock(), ast_mutex_unlock(), ast_rtcp_fd(), ast_rtp_codec_setpref(), ast_rtp_fd(), ast_rtp_new_with_bindaddr(), ast_rtp_setnat(), ast_rtp_setqos(), io, skinny_subchannel::lock, skinny_line::nat, skinny_subchannel::owner, skinny_line::parent, skinny_line::prefs, qos, skinny_subchannel::rtp, sched, skinny_line::sub, transmit_connect(), and skinny_subchannel::vrtp.
03238 { 03239 struct skinny_line *l = sub->parent; 03240 struct skinny_device *d = l->parent; 03241 int hasvideo = 0; 03242 03243 ast_mutex_lock(&sub->lock); 03244 /* Allocate the RTP */ 03245 sub->rtp = ast_rtp_new_with_bindaddr(sched, io, 1, 0, bindaddr.sin_addr); 03246 if (hasvideo) 03247 sub->vrtp = ast_rtp_new_with_bindaddr(sched, io, 1, 0, bindaddr.sin_addr); 03248 03249 if (sub->rtp && sub->owner) { 03250 ast_channel_set_fd(sub->owner, 0, ast_rtp_fd(sub->rtp)); 03251 ast_channel_set_fd(sub->owner, 1, ast_rtcp_fd(sub->rtp)); 03252 } 03253 if (hasvideo && sub->vrtp && sub->owner) { 03254 ast_channel_set_fd(sub->owner, 2, ast_rtp_fd(sub->vrtp)); 03255 ast_channel_set_fd(sub->owner, 3, ast_rtcp_fd(sub->vrtp)); 03256 } 03257 if (sub->rtp) { 03258 ast_rtp_setqos(sub->rtp, qos.tos_audio, qos.cos_audio, "Skinny RTP"); 03259 ast_rtp_setnat(sub->rtp, l->nat); 03260 } 03261 if (sub->vrtp) { 03262 ast_rtp_setqos(sub->vrtp, qos.tos_video, qos.cos_video, "Skinny VRTP"); 03263 ast_rtp_setnat(sub->vrtp, l->nat); 03264 } 03265 /* Set Frame packetization */ 03266 if (sub->rtp) 03267 ast_rtp_codec_setpref(sub->rtp, &l->prefs); 03268 03269 /* Create the RTP connection */ 03270 transmit_connect(d, sub); 03271 ast_mutex_unlock(&sub->lock); 03272 }
static void transmit_activatecallplane | ( | struct skinny_device * | d, | |
struct skinny_line * | l | |||
) | [static] |
Definition at line 2137 of file chan_skinny.c.
References ACTIVATE_CALL_PLANE_MESSAGE, skinny_data::activatecallplane, skinny_req::data, htolel, skinny_line::instance, activate_call_plane_message::lineInstance, req_alloc(), and transmit_response().
Referenced by skinny_hangup(), skinny_hold(), and skinny_unhold().
02138 { 02139 struct skinny_req *req; 02140 02141 if (!(req = req_alloc(sizeof(struct activate_call_plane_message), ACTIVATE_CALL_PLANE_MESSAGE))) 02142 return; 02143 02144 req->data.activatecallplane.lineInstance = htolel(l->instance); 02145 transmit_response(d, req); 02146 }
static void transmit_callinfo | ( | struct skinny_device * | d, | |
const char * | fromname, | |||
const char * | fromnum, | |||
const char * | toname, | |||
const char * | tonum, | |||
int | instance, | |||
int | callid, | |||
int | calltype | |||
) | [static] |
Definition at line 1893 of file chan_skinny.c.
References ast_copy_string(), ast_verb, CALL_INFO_MESSAGE, call_info_message::calledParty, call_info_message::calledPartyName, skinny_data::callinfo, call_info_message::callingParty, call_info_message::callingPartyName, skinny_req::data, htolel, call_info_message::instance, skinny_device::name, call_info_message::reference, req_alloc(), transmit_response(), and call_info_message::type.
Referenced by skinny_answer(), skinny_call(), and skinny_indicate().
01894 { 01895 struct skinny_req *req; 01896 01897 /* We should not be able to get here without a device */ 01898 if (!d) 01899 return; 01900 01901 if (!(req = req_alloc(sizeof(struct call_info_message), CALL_INFO_MESSAGE))) 01902 return; 01903 01904 if (skinnydebug) 01905 ast_verb(1, "Setting Callinfo to %s(%s) from %s(%s) on %s(%d)\n", fromname, fromnum, toname, tonum, d->name, instance); 01906 01907 if (fromname) { 01908 ast_copy_string(req->data.callinfo.callingPartyName, fromname, sizeof(req->data.callinfo.callingPartyName)); 01909 } 01910 if (fromnum) { 01911 ast_copy_string(req->data.callinfo.callingParty, fromnum, sizeof(req->data.callinfo.callingParty)); 01912 } 01913 if (toname) { 01914 ast_copy_string(req->data.callinfo.calledPartyName, toname, sizeof(req->data.callinfo.calledPartyName)); 01915 } 01916 if (tonum) { 01917 ast_copy_string(req->data.callinfo.calledParty, tonum, sizeof(req->data.callinfo.calledParty)); 01918 } 01919 req->data.callinfo.instance = htolel(instance); 01920 req->data.callinfo.reference = htolel(callid); 01921 req->data.callinfo.type = htolel(calltype); 01922 transmit_response(d, req); 01923 }
static void transmit_callstate | ( | struct skinny_device * | d, | |
int | instance, | |||
int | state, | |||
unsigned | callid | |||
) | [static] |
Definition at line 2161 of file chan_skinny.c.
References ACTIVATE_CALL_PLANE_MESSAGE, skinny_data::activatecallplane, CALL_STATE_MESSAGE, call_state_message::callReference, call_state_message::callState, skinny_data::callstate, CLOSE_RECEIVE_CHANNEL_MESSAGE, skinny_data::closereceivechannel, stop_media_transmission_message::conferenceId, close_receive_channel_message::conferenceId, skinny_req::data, htolel, KEYDEF_ONHOOK, activate_call_plane_message::lineInstance, call_state_message::lineInstance, close_receive_channel_message::partyId, stop_media_transmission_message::passThruPartyId, req_alloc(), SKINNY_OFFHOOK, SKINNY_ONHOOK, SKINNY_SPEAKEROFF, STOP_MEDIA_TRANSMISSION_MESSAGE, skinny_data::stopmedia, transmit_displaypromptstatus(), transmit_response(), transmit_selectsoftkeys(), and transmit_speaker_mode().
Referenced by handle_callforward_button(), handle_enbloc_call_message(), handle_offhook_message(), handle_onhook_message(), handle_soft_key_event_message(), handle_stimulus_message(), handle_transfer_button(), skinny_extensionstate_cb(), and skinny_hangup().
02162 { 02163 struct skinny_req *req; 02164 02165 if (state == SKINNY_ONHOOK) { 02166 if (!(req = req_alloc(sizeof(struct close_receive_channel_message), CLOSE_RECEIVE_CHANNEL_MESSAGE))) 02167 return; 02168 02169 req->data.closereceivechannel.conferenceId = htolel(callid); 02170 req->data.closereceivechannel.partyId = htolel(callid); 02171 transmit_response(d, req); 02172 02173 if (!(req = req_alloc(sizeof(struct stop_media_transmission_message), STOP_MEDIA_TRANSMISSION_MESSAGE))) 02174 return; 02175 02176 req->data.stopmedia.conferenceId = htolel(callid); 02177 req->data.stopmedia.passThruPartyId = htolel(callid); 02178 transmit_response(d, req); 02179 02180 transmit_speaker_mode(d, SKINNY_SPEAKEROFF); 02181 02182 transmit_displaypromptstatus(d, NULL, 0, instance, callid); 02183 } 02184 02185 if (!(req = req_alloc(sizeof(struct call_state_message), CALL_STATE_MESSAGE))) 02186 return; 02187 02188 req->data.callstate.callState = htolel(state); 02189 req->data.callstate.lineInstance = htolel(instance); 02190 req->data.callstate.callReference = htolel(callid); 02191 transmit_response(d, req); 02192 02193 if (state == SKINNY_ONHOOK) { 02194 transmit_selectsoftkeys(d, 0, 0, KEYDEF_ONHOOK); 02195 } 02196 02197 if (state == SKINNY_OFFHOOK || state == SKINNY_ONHOOK) { 02198 if (!(req = req_alloc(sizeof(struct activate_call_plane_message), ACTIVATE_CALL_PLANE_MESSAGE))) 02199 return; 02200 02201 req->data.activatecallplane.lineInstance = htolel(instance); 02202 transmit_response(d, req); 02203 } 02204 }
static void transmit_callstateonly | ( | struct skinny_device * | d, | |
struct skinny_subchannel * | sub, | |||
int | state | |||
) | [static] |
Definition at line 2148 of file chan_skinny.c.
References CALL_STATE_MESSAGE, skinny_subchannel::callid, call_state_message::callReference, call_state_message::callState, skinny_data::callstate, skinny_req::data, htolel, skinny_line::instance, call_state_message::lineInstance, skinny_subchannel::parent, req_alloc(), and transmit_response().
Referenced by handle_offhook_message(), handle_soft_key_event_message(), handle_stimulus_message(), skinny_answer(), skinny_call(), skinny_hold(), skinny_indicate(), and skinny_unhold().
02149 { 02150 struct skinny_req *req; 02151 02152 if (!(req = req_alloc(sizeof(struct call_state_message), CALL_STATE_MESSAGE))) 02153 return; 02154 02155 req->data.callstate.callState = htolel(state); 02156 req->data.callstate.lineInstance = htolel(sub->parent->instance); 02157 req->data.callstate.callReference = htolel(sub->callid); 02158 transmit_response(d, req); 02159 }
static void transmit_cfwdstate | ( | struct skinny_device * | d, | |
struct skinny_line * | l | |||
) | [static] |
Definition at line 2207 of file chan_skinny.c.
References forward_stat_message::activeforward, ast_copy_string(), ast_strlen_zero(), skinny_line::call_forward_all, skinny_line::call_forward_busy, skinny_line::call_forward_noanswer, skinny_line::cfwdtype, skinny_req::data, FORWARD_STAT_MESSAGE, skinny_data::forwardstat, forward_stat_message::fwdall, forward_stat_message::fwdallnum, forward_stat_message::fwdbusy, forward_stat_message::fwdbusynum, forward_stat_message::fwdnoanswer, forward_stat_message::fwdnoanswernum, htolel, skinny_line::instance, forward_stat_message::lineNumber, req_alloc(), SKINNY_CFWD_ALL, SKINNY_CFWD_BUSY, SKINNY_CFWD_NOANSWER, and transmit_response().
Referenced by handle_callforward_button(), and skinny_ss().
02208 { 02209 struct skinny_req *req; 02210 int anyon = 0; 02211 02212 if (!(req = req_alloc(sizeof(struct forward_stat_message), FORWARD_STAT_MESSAGE))) 02213 return; 02214 02215 if (l->cfwdtype & SKINNY_CFWD_ALL) { 02216 if (!ast_strlen_zero(l->call_forward_all)) { 02217 ast_copy_string(req->data.forwardstat.fwdallnum, l->call_forward_all, sizeof(req->data.forwardstat.fwdallnum)); 02218 req->data.forwardstat.fwdall = htolel(1); 02219 anyon++; 02220 } else { 02221 req->data.forwardstat.fwdall = htolel(0); 02222 } 02223 } 02224 if (l->cfwdtype & SKINNY_CFWD_BUSY) { 02225 if (!ast_strlen_zero(l->call_forward_busy)) { 02226 ast_copy_string(req->data.forwardstat.fwdbusynum, l->call_forward_busy, sizeof(req->data.forwardstat.fwdbusynum)); 02227 req->data.forwardstat.fwdbusy = htolel(1); 02228 anyon++; 02229 } else { 02230 req->data.forwardstat.fwdbusy = htolel(0); 02231 } 02232 } 02233 if (l->cfwdtype & SKINNY_CFWD_NOANSWER) { 02234 if (!ast_strlen_zero(l->call_forward_noanswer)) { 02235 ast_copy_string(req->data.forwardstat.fwdnoanswernum, l->call_forward_noanswer, sizeof(req->data.forwardstat.fwdnoanswernum)); 02236 req->data.forwardstat.fwdnoanswer = htolel(1); 02237 anyon++; 02238 } else { 02239 req->data.forwardstat.fwdnoanswer = htolel(0); 02240 } 02241 } 02242 req->data.forwardstat.lineNumber = htolel(l->instance); 02243 if (anyon) 02244 req->data.forwardstat.activeforward = htolel(7); 02245 else 02246 req->data.forwardstat.activeforward = htolel(0); 02247 02248 transmit_response(d, req); 02249 }
static void transmit_closereceivechannel | ( | struct skinny_device * | d, | |
struct skinny_subchannel * | sub | |||
) | [static] |
Definition at line 2113 of file chan_skinny.c.
References skinny_subchannel::callid, CLOSE_RECEIVE_CHANNEL_MESSAGE, skinny_data::closereceivechannel, close_receive_channel_message::conferenceId, skinny_req::data, htolel, close_receive_channel_message::partyId, req_alloc(), and transmit_response().
Referenced by skinny_hangup(), and skinny_hold().
02114 { 02115 struct skinny_req *req; 02116 02117 if (!(req = req_alloc(sizeof(struct close_receive_channel_message), CLOSE_RECEIVE_CHANNEL_MESSAGE))) 02118 return; 02119 02120 req->data.closereceivechannel.conferenceId = htolel(0); 02121 req->data.closereceivechannel.partyId = htolel(sub->callid); 02122 transmit_response(d, req); 02123 }
static void transmit_connect | ( | struct skinny_device * | d, | |
struct skinny_subchannel * | sub | |||
) | [static] |
Definition at line 1925 of file chan_skinny.c.
References ast_best_codec(), ast_codec_pref_getsize(), open_receive_channel_message::bitrate, ast_format_list::bits, skinny_subchannel::callid, open_receive_channel_message::capability, skinny_line::capability, codec_ast2skinny(), open_receive_channel_message::conferenceId, ast_format_list::cur_ms, skinny_req::data, open_receive_channel_message::echo, htolel, OPEN_RECEIVE_CHANNEL_MESSAGE, skinny_data::openreceivechannel, open_receive_channel_message::packets, open_receive_channel_message::partyId, skinny_line::prefs, req_alloc(), skinny_line::sub, and transmit_response().
Referenced by skinny_unhold(), and start_rtp().
01926 { 01927 struct skinny_req *req; 01928 struct skinny_line *l = sub->parent; 01929 struct ast_format_list fmt; 01930 01931 if (!(req = req_alloc(sizeof(struct open_receive_channel_message), OPEN_RECEIVE_CHANNEL_MESSAGE))) 01932 return; 01933 01934 fmt = ast_codec_pref_getsize(&l->prefs, ast_best_codec(l->capability)); 01935 01936 req->data.openreceivechannel.conferenceId = htolel(sub->callid); 01937 req->data.openreceivechannel.partyId = htolel(sub->callid); 01938 req->data.openreceivechannel.packets = htolel(fmt.cur_ms); 01939 req->data.openreceivechannel.capability = htolel(codec_ast2skinny(fmt.bits)); 01940 req->data.openreceivechannel.echo = htolel(0); 01941 req->data.openreceivechannel.bitrate = htolel(0); 01942 transmit_response(d, req); 01943 }
static void transmit_dialednumber | ( | struct skinny_device * | d, | |
const char * | text, | |||
int | instance, | |||
int | callid | |||
) | [static] |
Definition at line 2099 of file chan_skinny.c.
References ast_copy_string(), dialed_number_message::callReference, skinny_req::data, DIALED_NUMBER_MESSAGE, dialed_number_message::dialedNumber, skinny_data::dialednumber, htolel, dialed_number_message::lineInstance, req_alloc(), and transmit_response().
Referenced by skinny_answer(), and skinny_indicate().
02100 { 02101 struct skinny_req *req; 02102 02103 if (!(req = req_alloc(sizeof(struct dialed_number_message), DIALED_NUMBER_MESSAGE))) 02104 return; 02105 02106 ast_copy_string(req->data.dialednumber.dialedNumber, text, sizeof(req->data.dialednumber.dialedNumber)); 02107 req->data.dialednumber.lineInstance = htolel(instance); 02108 req->data.dialednumber.callReference = htolel(callid); 02109 02110 transmit_response(d, req); 02111 }
static void transmit_displaymessage | ( | struct skinny_device * | d, | |
const char * | text, | |||
int | instance, | |||
int | reference | |||
) | [static] |
Definition at line 2027 of file chan_skinny.c.
References ast_copy_string(), ast_verb, CLEAR_DISPLAY_MESSAGE, skinny_req::data, skinny_data::displaytext, DISPLAYTEXT_MESSAGE, req_alloc(), displaytext_message::text, and transmit_response().
Referenced by handle_callforward_button(), handle_enbloc_call_message(), handle_offhook_message(), handle_soft_key_event_message(), handle_stimulus_message(), and handle_transfer_button().
02028 { 02029 struct skinny_req *req; 02030 02031 if (text == 0) { 02032 if (!(req = req_alloc(0, CLEAR_DISPLAY_MESSAGE))) 02033 return; 02034 02035 //what do we want hear CLEAR_DISPLAY_MESSAGE or CLEAR_PROMPT_STATUS??? 02036 //if we are clearing the display, it appears there is no instance and refernece info (size 0) 02037 //req->data.clearpromptstatus.lineInstance = instance; 02038 //req->data.clearpromptstatus.callReference = reference; 02039 02040 if (skinnydebug) 02041 ast_verb(1, "Clearing Display\n"); 02042 } else { 02043 if (!(req = req_alloc(sizeof(struct displaytext_message), DISPLAYTEXT_MESSAGE))) 02044 return; 02045 02046 ast_copy_string(req->data.displaytext.text, text, sizeof(req->data.displaytext.text)); 02047 if (skinnydebug) 02048 ast_verb(1, "Displaying message '%s'\n", req->data.displaytext.text); 02049 } 02050 02051 transmit_response(d, req); 02052 }
static void transmit_displaynotify | ( | struct skinny_device * | d, | |
const char * | text, | |||
int | t | |||
) | [static] |
Definition at line 2054 of file chan_skinny.c.
References ast_copy_string(), ast_verb, skinny_req::data, DISPLAY_NOTIFY_MESSAGE, display_notify_message::displayMessage, skinny_data::displaynotify, display_notify_message::displayTimeout, htolel, req_alloc(), and transmit_response().
Referenced by handle_callforward_button(), handle_soft_key_event_message(), handle_stimulus_message(), and skinny_ss().
02055 { 02056 struct skinny_req *req; 02057 02058 if (!(req = req_alloc(sizeof(struct display_notify_message), DISPLAY_NOTIFY_MESSAGE))) 02059 return; 02060 02061 ast_copy_string(req->data.displaynotify.displayMessage, text, sizeof(req->data.displaynotify.displayMessage)); 02062 req->data.displaynotify.displayTimeout = htolel(t); 02063 02064 if (skinnydebug) 02065 ast_verb(1, "Displaying notify '%s'\n", text); 02066 02067 transmit_response(d, req); 02068 }
static void transmit_displaypromptstatus | ( | struct skinny_device * | d, | |
const char * | text, | |||
int | t, | |||
int | instance, | |||
int | callid | |||
) | [static] |
Definition at line 2070 of file chan_skinny.c.
References ast_copy_string(), ast_verb, display_prompt_status_message::callReference, clear_prompt_message::callReference, CLEAR_PROMPT_MESSAGE, skinny_data::clearpromptstatus, skinny_req::data, DISPLAY_PROMPT_STATUS_MESSAGE, skinny_data::displaypromptstatus, htolel, display_prompt_status_message::lineInstance, clear_prompt_message::lineInstance, display_prompt_status_message::messageTimeout, display_prompt_status_message::promptMessage, req_alloc(), and transmit_response().
Referenced by handle_stimulus_message(), skinny_answer(), skinny_call(), skinny_indicate(), and transmit_callstate().
02071 { 02072 struct skinny_req *req; 02073 02074 if (text == 0) { 02075 if (!(req = req_alloc(sizeof(struct clear_prompt_message), CLEAR_PROMPT_MESSAGE))) 02076 return; 02077 02078 req->data.clearpromptstatus.lineInstance = htolel(instance); 02079 req->data.clearpromptstatus.callReference = htolel(callid); 02080 02081 if (skinnydebug) 02082 ast_verb(1, "Clearing Prompt\n"); 02083 } else { 02084 if (!(req = req_alloc(sizeof(struct display_prompt_status_message), DISPLAY_PROMPT_STATUS_MESSAGE))) 02085 return; 02086 02087 ast_copy_string(req->data.displaypromptstatus.promptMessage, text, sizeof(req->data.displaypromptstatus.promptMessage)); 02088 req->data.displaypromptstatus.messageTimeout = htolel(t); 02089 req->data.displaypromptstatus.lineInstance = htolel(instance); 02090 req->data.displaypromptstatus.callReference = htolel(callid); 02091 02092 if (skinnydebug) 02093 ast_verb(1, "Displaying Prompt Status '%s'\n", text); 02094 } 02095 02096 transmit_response(d, req); 02097 }
static void transmit_lamp_indication | ( | struct skinny_device * | d, | |
int | stimulus, | |||
int | instance, | |||
int | indication | |||
) | [static] |
Definition at line 1989 of file chan_skinny.c.
References skinny_req::data, set_lamp_message::deviceStimulus, htolel, req_alloc(), SET_LAMP_MESSAGE, skinny_data::setlamp, set_lamp_message::stimulus, set_lamp_message::stimulusInstance, and transmit_response().
Referenced by do_housekeeping(), handle_offhook_message(), handle_soft_key_event_message(), handle_stimulus_message(), skinny_call(), skinny_extensionstate_cb(), skinny_hangup(), skinny_hold(), skinny_ss(), and skinny_unhold().
01990 { 01991 struct skinny_req *req; 01992 01993 if (!(req = req_alloc(sizeof(struct set_lamp_message), SET_LAMP_MESSAGE))) 01994 return; 01995 01996 req->data.setlamp.stimulus = htolel(stimulus); 01997 req->data.setlamp.stimulusInstance = htolel(instance); 01998 req->data.setlamp.deviceStimulus = htolel(indication); 01999 transmit_response(d, req); 02000 }
static int transmit_response | ( | struct skinny_device * | d, | |
struct skinny_req * | req | |||
) | [static] |
Definition at line 1828 of file chan_skinny.c.
References ast_free, ast_log(), ast_mutex_lock(), ast_mutex_unlock(), skinny_req::data, skinny_req::e, errno, skinny_req::len, letohl, LOG_VERBOSE, LOG_WARNING, s, skinny_device::session, SKINNY_MAX_PACKET, and skinny_unregister().
01829 { 01830 struct skinnysession *s = d->session; 01831 int res = 0; 01832 01833 if (!s) { 01834 ast_log(LOG_WARNING, "Asked to transmit to a non-existent session!\n"); 01835 return -1; 01836 } 01837 01838 ast_mutex_lock(&s->lock); 01839 01840 if (skinnydebug) 01841 ast_log(LOG_VERBOSE, "writing packet type %04X (%d bytes) to socket %d\n", letohl(req->e), letohl(req->len)+8, s->fd); 01842 01843 if (letohl(req->len > SKINNY_MAX_PACKET) || letohl(req->len < 0)) { 01844 ast_log(LOG_WARNING, "transmit_response: the length of the request is out of bounds\n"); 01845 ast_mutex_unlock(&s->lock); 01846 return -1; 01847 } 01848 01849 memset(s->outbuf, 0, sizeof(s->outbuf)); 01850 memcpy(s->outbuf, req, skinny_header_size); 01851 memcpy(s->outbuf+skinny_header_size, &req->data, letohl(req->len)); 01852 01853 res = write(s->fd, s->outbuf, letohl(req->len)+8); 01854 01855 if (res != letohl(req->len)+8) { 01856 ast_log(LOG_WARNING, "Transmit: write only sent %d out of %d bytes: %s\n", res, letohl(req->len)+8, strerror(errno)); 01857 if (res == -1) { 01858 if (skinnydebug) 01859 ast_log(LOG_WARNING, "Transmit: Skinny Client was lost, unregistering\n"); 01860 skinny_unregister(NULL, s); 01861 } 01862 01863 } 01864 01865 ast_free(req); 01866 ast_mutex_unlock(&s->lock); 01867 return 1; 01868 }
static void transmit_ringer_mode | ( | struct skinny_device * | d, | |
int | mode | |||
) | [static] |
Definition at line 2002 of file chan_skinny.c.
References ast_verb, skinny_req::data, htolel, req_alloc(), set_ringer_message::ringerMode, SET_RINGER_MESSAGE, skinny_data::setringer, transmit_response(), set_ringer_message::unknown1, and set_ringer_message::unknown2.
Referenced by handle_offhook_message(), handle_soft_key_event_message(), handle_stimulus_message(), skinny_call(), and skinny_hangup().
02003 { 02004 struct skinny_req *req; 02005 02006 if (skinnydebug) 02007 ast_verb(1, "Setting ringer mode to '%d'.\n", mode); 02008 02009 if (!(req = req_alloc(sizeof(struct set_ringer_message), SET_RINGER_MESSAGE))) 02010 return; 02011 02012 req->data.setringer.ringerMode = htolel(mode); 02013 /* XXX okay, I don't quite know what this is, but here's what happens (on a 7960). 02014 Note: The phone will always show as ringing on the display. 02015 02016 1: phone will audibly ring over and over 02017 2: phone will audibly ring only once 02018 any other value, will NOT cause the phone to audibly ring 02019 */ 02020 req->data.setringer.unknown1 = htolel(1); 02021 /* XXX the value here doesn't seem to change anything. Must be higher than 0. 02022 Perhaps a packet capture can shed some light on this. */ 02023 req->data.setringer.unknown2 = htolel(1); 02024 transmit_response(d, req); 02025 }
static void transmit_selectsoftkeys | ( | struct skinny_device * | d, | |
int | instance, | |||
int | callid, | |||
int | softkey | |||
) | [static] |
Definition at line 1975 of file chan_skinny.c.
References skinny_req::data, htolel, select_soft_keys_message::instance, select_soft_keys_message::reference, req_alloc(), SELECT_SOFT_KEYS_MESSAGE, skinny_data::selectsoftkey, select_soft_keys_message::softKeySetIndex, transmit_response(), and select_soft_keys_message::validKeyMask.
Referenced by handle_callforward_button(), handle_hold_button(), handle_offhook_message(), handle_soft_key_event_message(), handle_soft_key_set_req_message(), handle_stimulus_message(), handle_transfer_button(), skinny_answer(), skinny_call(), and transmit_callstate().
01976 { 01977 struct skinny_req *req; 01978 01979 if (!(req = req_alloc(sizeof(struct select_soft_keys_message), SELECT_SOFT_KEYS_MESSAGE))) 01980 return; 01981 01982 req->data.selectsoftkey.instance = htolel(instance); 01983 req->data.selectsoftkey.reference = htolel(callid); 01984 req->data.selectsoftkey.softKeySetIndex = htolel(softkey); 01985 req->data.selectsoftkey.validKeyMask = htolel(0xFFFFFFFF); 01986 transmit_response(d, req); 01987 }
static void transmit_speaker_mode | ( | struct skinny_device * | d, | |
int | mode | |||
) | [static] |
Definition at line 1870 of file chan_skinny.c.
References skinny_req::data, htolel, set_speaker_message::mode, req_alloc(), SET_SPEAKER_MESSAGE, skinny_data::setspeaker, and transmit_response().
Referenced by handle_callforward_button(), handle_soft_key_event_message(), handle_stimulus_message(), skinny_hangup(), and transmit_callstate().
01871 { 01872 struct skinny_req *req; 01873 01874 if (!(req = req_alloc(sizeof(struct set_speaker_message), SET_SPEAKER_MESSAGE))) 01875 return; 01876 01877 req->data.setspeaker.mode = htolel(mode); 01878 transmit_response(d, req); 01879 }
static void transmit_stopmediatransmission | ( | struct skinny_device * | d, | |
struct skinny_subchannel * | sub | |||
) | [static] |
Definition at line 2125 of file chan_skinny.c.
References skinny_subchannel::callid, stop_media_transmission_message::conferenceId, skinny_req::data, htolel, stop_media_transmission_message::passThruPartyId, req_alloc(), STOP_MEDIA_TRANSMISSION_MESSAGE, skinny_data::stopmedia, and transmit_response().
Referenced by skinny_hangup(), and skinny_hold().
02126 { 02127 struct skinny_req *req; 02128 02129 if (!(req = req_alloc(sizeof(struct stop_media_transmission_message), STOP_MEDIA_TRANSMISSION_MESSAGE))) 02130 return; 02131 02132 req->data.stopmedia.conferenceId = htolel(0); 02133 req->data.stopmedia.passThruPartyId = htolel(sub->callid); 02134 transmit_response(d, req); 02135 }
static void transmit_tone | ( | struct skinny_device * | d, | |
int | tone, | |||
int | instance, | |||
int | reference | |||
) | [static] |
Definition at line 1945 of file chan_skinny.c.
References skinny_req::data, htolel, stop_tone_message::instance, start_tone_message::instance, stop_tone_message::reference, start_tone_message::reference, req_alloc(), SKINNY_NOTONE, START_TONE_MESSAGE, skinny_data::starttone, STOP_TONE_MESSAGE, skinny_data::stoptone, start_tone_message::tone, and transmit_response().
Referenced by handle_callforward_button(), handle_enbloc_call_message(), handle_offhook_message(), handle_soft_key_event_message(), handle_stimulus_message(), handle_transfer_button(), skinny_answer(), skinny_hangup(), skinny_indicate(), skinny_newcall(), skinny_senddigit_end(), and skinny_ss().
01946 { 01947 struct skinny_req *req; 01948 01949 if (tone == SKINNY_NOTONE) { 01950 /* This is bad, mmm'kay? */ 01951 return; 01952 } 01953 01954 if (tone > 0) { 01955 if (!(req = req_alloc(sizeof(struct start_tone_message), START_TONE_MESSAGE))) 01956 return; 01957 req->data.starttone.tone = htolel(tone); 01958 req->data.starttone.instance = htolel(instance); 01959 req->data.starttone.reference = htolel(reference); 01960 } else { 01961 if (!(req = req_alloc(sizeof(struct stop_tone_message), STOP_TONE_MESSAGE))) 01962 return; 01963 req->data.stoptone.instance = htolel(instance); 01964 req->data.stoptone.reference = htolel(reference); 01965 } 01966 01967 //Bad, tone is already set so this is redundant and a change to the if above 01968 //may lead to issues where we try to set a tone to a stop_tone_message 01969 //if (tone > 0) { 01970 // req->data.starttone.tone = htolel(tone); 01971 //} 01972 transmit_response(d, req); 01973 }
static int unload_module | ( | void | ) | [static] |
Definition at line 6416 of file chan_skinny.c.
References skinny_subchannel::alreadygone, ast_channel_unregister(), ast_cli_unregister_multiple(), ast_context_destroy(), ast_context_find(), ast_event_unsubscribe(), AST_LIST_LOCK, AST_LIST_REMOVE_HEAD, AST_LIST_TRAVERSE, AST_LIST_UNLOCK, ast_mutex_lock(), ast_mutex_unlock(), AST_PTHREADT_NULL, AST_PTHREADT_STOP, ast_rtp_proto_unregister(), ast_softhangup(), AST_SOFTHANGUP_APPUNLOAD, cli_skinny, delete_devices(), free, skinny_device::lines, skinny_subchannel::lock, skinny_line::lock, monlock, skinny_line::mwi_event_sub, netlock, skinny_subchannel::owner, s, sched, sched_context_destroy(), skinny_rtp, skinny_tech, and skinny_line::sub.
06417 { 06418 struct skinnysession *s; 06419 struct skinny_device *d; 06420 struct skinny_line *l; 06421 struct skinny_subchannel *sub; 06422 struct ast_context *con; 06423 06424 AST_LIST_LOCK(&sessions); 06425 /* Destroy all the interfaces and free their memory */ 06426 while((s = AST_LIST_REMOVE_HEAD(&sessions, list))) { 06427 d = s->device; 06428 AST_LIST_TRAVERSE(&d->lines, l, list){ 06429 ast_mutex_lock(&l->lock); 06430 AST_LIST_TRAVERSE(&l->sub, sub, list) { 06431 ast_mutex_lock(&sub->lock); 06432 if (sub->owner) { 06433 sub->alreadygone = 1; 06434 ast_softhangup(sub->owner, AST_SOFTHANGUP_APPUNLOAD); 06435 } 06436 ast_mutex_unlock(&sub->lock); 06437 } 06438 if (l->mwi_event_sub) 06439 ast_event_unsubscribe(l->mwi_event_sub); 06440 ast_mutex_unlock(&l->lock); 06441 } 06442 if (s->fd > -1) 06443 close(s->fd); 06444 free(s); 06445 } 06446 AST_LIST_UNLOCK(&sessions); 06447 06448 delete_devices(); 06449 06450 ast_mutex_lock(&monlock); 06451 if ((monitor_thread != AST_PTHREADT_NULL) && (monitor_thread != AST_PTHREADT_STOP)) { 06452 pthread_cancel(monitor_thread); 06453 pthread_kill(monitor_thread, SIGURG); 06454 pthread_join(monitor_thread, NULL); 06455 } 06456 monitor_thread = AST_PTHREADT_STOP; 06457 ast_mutex_unlock(&monlock); 06458 06459 ast_mutex_lock(&netlock); 06460 if (accept_t && (accept_t != AST_PTHREADT_STOP)) { 06461 pthread_cancel(accept_t); 06462 pthread_kill(accept_t, SIGURG); 06463 pthread_join(accept_t, NULL); 06464 } 06465 accept_t = AST_PTHREADT_STOP; 06466 ast_mutex_unlock(&netlock); 06467 06468 ast_rtp_proto_unregister(&skinny_rtp); 06469 ast_channel_unregister(&skinny_tech); 06470 ast_cli_unregister_multiple(cli_skinny, sizeof(cli_skinny) / sizeof(struct ast_cli_entry)); 06471 06472 close(skinnysock); 06473 if (sched) 06474 sched_context_destroy(sched); 06475 06476 con = ast_context_find(used_context); 06477 if (con) 06478 ast_context_destroy(con, "Skinny"); 06479 06480 return 0; 06481 }
static void unregister_exten | ( | struct skinny_line * | l | ) | [static] |
Definition at line 1735 of file chan_skinny.c.
References ast_context_find(), ast_context_remove_extension(), ast_copy_string(), ast_log(), ast_strlen_zero(), ext, LOG_WARNING, skinny_line::name, skinny_line::regexten, S_OR, and strsep().
Referenced by skinny_unregister().
01736 { 01737 char multi[256]; 01738 char *stringp, *ext, *context; 01739 01740 if (ast_strlen_zero(regcontext)) 01741 return; 01742 01743 ast_copy_string(multi, S_OR(l->regexten, l->name), sizeof(multi)); 01744 stringp = multi; 01745 while ((ext = strsep(&stringp, "&"))) { 01746 if ((context = strchr(ext, '@'))) { 01747 *context++ = '\0'; /* split ext@context */ 01748 if (!ast_context_find(context)) { 01749 ast_log(LOG_WARNING, "Context %s must exist in regcontext= in skinny.conf!\n", context); 01750 continue; 01751 } 01752 } else { 01753 context = regcontext; 01754 } 01755 ast_context_remove_extension(context, ext, 1, NULL); 01756 } 01757 }
struct ast_module_info __mod_info = { .name = AST_MODULE, .flags = AST_MODFLAG_DEFAULT , .description = "Skinny Client Control Protocol (Skinny)" , .key = "This paragraph is copyright (c) 2006 by Digium, Inc. \In order for your module to load, it must return this \key via a function called \"key\". Any code which \includes this paragraph must be licensed under the GNU \General Public License version 2 or later (at your \option). In addition to Digium's general reservations \of rights, Digium expressly reserves the right to \allow other parties to license this paragraph under \different terms. Any use of Digium, Inc. trademarks or \logos (including \"Asterisk\" or \"Digium\") without \express written permission of Digium, Inc. is prohibited.\n" , .buildopt_sum = "a9c98e5d177805051735cb5b0b16b0a0" , .load = load_module, .unload = unload_module, } [static] |
Definition at line 6486 of file chan_skinny.c.
struct in_addr __ourip [static] |
Definition at line 965 of file chan_skinny.c.
pthread_t accept_t [static] |
Definition at line 969 of file chan_skinny.c.
char accountcode[AST_MAX_ACCOUNT_CODE] = "" [static] |
Definition at line 990 of file chan_skinny.c.
struct ast_hostent ahp |
Definition at line 966 of file chan_skinny.c.
Referenced by __ast_http_load(), __init_manager(), __set_address_from_contact(), ast_find_ourip(), ast_get_ip_or_srv(), ast_parse_arg(), check_via(), create_addr(), festival_exec(), gtalk_load_config(), gtalk_update_stun(), handle_cli_udptl_debug_deprecated(), handle_cli_udptl_set_debug(), jingle_load_config(), jingle_update_stun(), launch_netscript(), parse_register_contact(), process_sdp(), realtime_peer(), realtime_user(), reload_config(), rpt_exec(), rtcp_do_debug_ip(), rtp_do_debug_ip(), set_destination(), and sip_do_debug_ip().
int amaflags = 0 [static] |
Definition at line 993 of file chan_skinny.c.
struct ast_module_info* ast_module_info = &__mod_info [static] |
Definition at line 6486 of file chan_skinny.c.
struct sockaddr_in bindaddr [static] |
Definition at line 962 of file chan_skinny.c.
int callnums = 1 [static] |
Definition at line 994 of file chan_skinny.c.
int callreturn = 0 [static] |
Definition at line 983 of file chan_skinny.c.
int callwaiting = 0 [static] |
Definition at line 982 of file chan_skinny.c.
int cancallforward = 0 [static] |
Definition at line 988 of file chan_skinny.c.
int canreinvite = 0 [static] |
Definition at line 995 of file chan_skinny.c.
char cid_name[AST_MAX_EXTENSION] = "" [static] |
Definition at line 975 of file chan_skinny.c.
char cid_num[AST_MAX_EXTENSION] = "" [static] |
Definition at line 974 of file chan_skinny.c.
struct ast_cli_entry cli_skinny[] [static] |
struct ast_cli_entry cli_skinny_set_debug_deprecated = { .handler = handle_skinny_set_debug_deprecated , .summary = "Enable/Disable Skinny debugging" ,__VA_ARGS__ } [static] |
Definition at line 2998 of file chan_skinny.c.
const char config[] = "skinny.conf" [static] |
Definition at line 77 of file chan_skinny.c.
struct ast_threadstorage control2str_threadbuf = { .once = PTHREAD_ONCE_INIT, .key_init = __init_control2str_threadbuf , .custom_init = NULL , } [static] |
unsigned int cos |
Definition at line 100 of file chan_skinny.c.
unsigned int cos_audio |
Definition at line 101 of file chan_skinny.c.
unsigned int cos_video |
Definition at line 102 of file chan_skinny.c.
ast_group_t cur_callergroup = 0 [static] |
Definition at line 979 of file chan_skinny.c.
ast_group_t cur_pickupgroup = 0 [static] |
Definition at line 980 of file chan_skinny.c.
char date_format[6] = "D-M-Y" [static] |
Definition at line 109 of file chan_skinny.c.
int default_capability = AST_FORMAT_ULAW | AST_FORMAT_ALAW [static] |
Definition at line 79 of file chan_skinny.c.
struct ast_jb_conf default_jbconf [static] |
Global jitterbuffer configuration - by default, jb is disabled
Definition at line 153 of file chan_skinny.c.
struct ast_codec_pref default_prefs [static] |
Definition at line 80 of file chan_skinny.c.
struct ast_threadstorage device2str_threadbuf = { .once = PTHREAD_ONCE_INIT, .key_init = __init_device2str_threadbuf , .custom_init = NULL , } [static] |
int firstdigittimeout = 16000 [static] |
Definition at line 1117 of file chan_skinny.c.
int gendigittimeout = 8000 [static] |
Definition at line 1120 of file chan_skinny.c.
char global_context[AST_MAX_CONTEXT] = "default" [static] |
Definition at line 970 of file chan_skinny.c.
struct ast_jb_conf global_jbconf [static] |
Definition at line 160 of file chan_skinny.c.
struct hostent* hp |
Definition at line 967 of file chan_skinny.c.
Referenced by __ast_http_load(), __init_manager(), __set_address_from_contact(), ast_find_ourip(), ast_get_ip_or_srv(), ast_gethostbyname(), ast_parse_arg(), build_peer(), check_via(), connect_sphinx(), create_addr(), gtalk_load_config(), gtalk_update_stun(), handle_cli_udptl_debug_deprecated(), handle_cli_udptl_set_debug(), iax_template_parse(), jingle_load_config(), jingle_update_stun(), launch_netscript(), parse_register_contact(), process_sdp(), realtime_peer(), realtime_user(), reload_config(), rpt_exec(), rtcp_do_debug_ip(), rtp_do_debug_ip(), set_config(), set_destination(), and sip_do_debug_ip().
int immediate = 0 [static] |
Definition at line 981 of file chan_skinny.c.
struct io_context* io [static] |
Definition at line 1104 of file chan_skinny.c.
int keep_alive = 120 [static] |
Definition at line 105 of file chan_skinny.c.
char language[MAX_LANGUAGE] = "" [static] |
Definition at line 971 of file chan_skinny.c.
char linelabel[AST_MAX_EXTENSION] = "" [static] |
char mailbox[AST_MAX_EXTENSION] [static] |
Definition at line 991 of file chan_skinny.c.
int matchdigittimeout = 3000 [static] |
Definition at line 1123 of file chan_skinny.c.
char mohinterpret[MAX_MUSICCLASS] = "default" [static] |
Definition at line 972 of file chan_skinny.c.
char mohsuggest[MAX_MUSICCLASS] = "" [static] |
Definition at line 973 of file chan_skinny.c.
pthread_t monitor_thread = AST_PTHREADT_NULL [static] |
Definition at line 1114 of file chan_skinny.c.
ast_mutex_t monlock = ((ast_mutex_t) PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP ) [static] |
Definition at line 1108 of file chan_skinny.c.
int mwiblink = 0 [static] |
Definition at line 985 of file chan_skinny.c.
int nat = 0 [static] |
Definition at line 978 of file chan_skinny.c.
ast_mutex_t netlock = ((ast_mutex_t) PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP ) [static] |
Definition at line 1110 of file chan_skinny.c.
char ourhost[256] [static] |
Definition at line 963 of file chan_skinny.c.
int ourport [static] |
Definition at line 964 of file chan_skinny.c.
char parkinglot[AST_MAX_CONTEXT] = "" [static] |
Definition at line 977 of file chan_skinny.c.
struct { ... } qos [static] |
char regcontext[AST_MAX_CONTEXT] [static] |
Definition at line 108 of file chan_skinny.c.
char regexten[AST_MAX_EXTENSION] [static] |
struct sched_context* sched = NULL [static] |
Definition at line 1103 of file chan_skinny.c.
int skinny_header_size = 12 |
Definition at line 953 of file chan_skinny.c.
struct ast_rtp_protocol skinny_rtp [static] |
struct ast_channel_tech skinny_tech [static] |
Definition at line 1281 of file chan_skinny.c.
Referenced by load_module(), skinny_new(), and unload_module().
int skinnydebug = 0 [static] |
Definition at line 959 of file chan_skinny.c.
int skinnysock = -1 [static] |
Definition at line 968 of file chan_skinny.c.
const uint8_t soft_key_default_connected[] [static] |
Definition at line 748 of file chan_skinny.c.
const uint8_t soft_key_default_connwithconf[] [static] |
const uint8_t soft_key_default_connwithtrans[] [static] |
Definition at line 778 of file chan_skinny.c.
const uint8_t soft_key_default_dadfd[] [static] |
struct soft_key_definitions soft_key_default_definitions[] [static] |
const uint8_t soft_key_default_offhook[] [static] |
Definition at line 770 of file chan_skinny.c.
const uint8_t soft_key_default_offhookwithfeat[] [static] |
Initial value:
Definition at line 801 of file chan_skinny.c.
const uint8_t soft_key_default_onhold[] [static] |
Definition at line 757 of file chan_skinny.c.
const uint8_t soft_key_default_onhook[] [static] |
Definition at line 738 of file chan_skinny.c.
const uint8_t soft_key_default_ringin[] [static] |
Initial value:
Definition at line 764 of file chan_skinny.c.
const uint8_t soft_key_default_ringout[] [static] |
const uint8_t soft_key_default_unknown[] [static] |
Definition at line 575 of file chan_skinny.c.
Referenced by handle_soft_key_set_req_message(), handle_soft_key_template_req_message(), and load_module().
const char tdesc[] = "Skinny Client Control Protocol (Skinny)" [static] |
Definition at line 76 of file chan_skinny.c.
int threewaycalling = 0 [static] |
Definition at line 984 of file chan_skinny.c.
unsigned int tos |
Definition at line 97 of file chan_skinny.c.
unsigned int tos_audio |
Definition at line 98 of file chan_skinny.c.
unsigned int tos_video |
Definition at line 99 of file chan_skinny.c.
int transfer = 0 [static] |
Definition at line 987 of file chan_skinny.c.
char used_context[AST_MAX_EXTENSION] [static] |
Definition at line 107 of file chan_skinny.c.
char version_id[16] = "P002F202" [static] |
Definition at line 110 of file chan_skinny.c.
char vmexten[AST_MAX_EXTENSION] [static] |
Definition at line 106 of file chan_skinny.c.