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