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