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_engine.h"#include "asterisk/netsock.h"#include "asterisk/acl.h"#include "asterisk/callerid.h"#include "asterisk/cli.h"#include "asterisk/manager.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 | lines |
| 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_device_options |
| struct | skinny_line |
| struct | skinny_line_options |
| 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 | CDEV ((struct skinny_device *)item) |
| #define | CDEV_OPTS ((struct skinny_device_options *)item) |
| #define | CLEAR_DISPLAY_MESSAGE 0x009A |
| #define | CLEAR_NOTIFY_MESSAGE 0x0115 |
| #define | CLEAR_PROMPT_MESSAGE 0x0113 |
| #define | CLINE ((struct skinny_line *)item) |
| #define | CLINE_OPTS ((struct skinny_line_options *)item) |
| #define | CLOSE_RECEIVE_CHANNEL_MESSAGE 0x0106 |
| #define | CONTROL2STR_BUFSIZE 100 |
| #define | DEFAULT_AUTH_LIMIT 50 |
| #define | DEFAULT_AUTH_TIMEOUT 30 |
| #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_OPTIONS |
| #define | SKINNY_DEVICE_SCCPGATEWAY_AN 30027 |
| #define | SKINNY_DEVICE_SCCPGATEWAY_BRI 30028 |
| #define | SKINNY_DEVICE_UNKNOWN -1 |
| #define | SKINNY_DEVONLY(code) |
| #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_LINE_OPTIONS |
| #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_DEF_DEVICE 2 |
| #define | TYPE_DEF_LINE 4 |
| #define | TYPE_DEVICE 8 |
| #define | TYPE_GENERAL 1 |
| #define | TYPE_LINE 16 |
| #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 char * | _skinny_show_device (int type, int fd, struct mansession *s, const struct message *m, int argc, const char *argv[]) |
| static char * | _skinny_show_devices (int fd, int *total, struct mansession *s, const struct message *m, int argc, const char *argv[]) |
| static char * | _skinny_show_line (int type, int fd, struct mansession *s, const struct message *m, int argc, const char *argv[]) |
| static char * | _skinny_show_lines (int fd, int *total, struct mansession *s, const struct message *m, int argc, const char *argv[]) |
| static void * | accept_thread (void *ignore) |
| static struct ast_variable * | add_var (const char *buf, struct ast_variable *list) |
| static void | cleanup_stale_contexts (char *new, char *old) |
| static int | codec_ast2skinny (format_t astcodec) |
| static format_t | 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 struct skinny_device * | config_device (const char *dname, struct ast_variable *v) |
| static struct skinny_line * | config_line (const char *lname, struct ast_variable *v) |
| static int | config_load (void) |
| static void | config_parse_variables (int type, void *item, struct ast_variable *vptr) |
| 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_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_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_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_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_message (struct skinny_req *req, struct skinnysession *s) |
| static char * | handle_skinny_reload (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a) |
| 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_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_stimulus_message (struct skinny_req *req, struct skinnysession *s) |
| static int | handle_transfer_button (struct skinny_subchannel *sub) |
| static int | load_module (void) |
| static int | manager_skinny_show_device (struct mansession *s, const struct message *m) |
| static int | manager_skinny_show_devices (struct mansession *s, const struct message *m) |
| Show SKINNY devices in the manager API. | |
| static int | manager_skinny_show_line (struct mansession *s, const struct message *m) |
| static int | manager_skinny_show_lines (struct mansession *s, const struct message *m) |
| Show Skinny lines in the manager API. | |
| 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 (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_glue_result | skinny_get_rtp_peer (struct ast_channel *c, struct ast_rtp_instance **instance) |
| static enum ast_rtp_glue_result | skinny_get_vrtp_peer (struct ast_channel *c, struct ast_rtp_instance **instance) |
| 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, const char *linkedid) |
| 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 int | skinny_reload (void) |
| static struct skinny_req * | skinny_req_parse (struct skinnysession *s) |
| static struct ast_channel * | skinny_request (const char *type, format_t format, const struct ast_channel *requestor, 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_instance *rtp, struct ast_rtp_instance *vrtp, struct ast_rtp_instance *trtp, format_t 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 buttonInstance, unsigned callid, int state) |
| static void | transmit_cfwdstate (struct skinny_device *d, struct skinny_line *l) |
| static void | transmit_clear_display_message (struct skinny_device *d, int instance, int reference) |
| static void | transmit_clearpromptmessage (struct skinny_device *d, int instance, int callid) |
| 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_definetimedate (struct skinny_device *d) |
| static void | transmit_dialednumber (struct skinny_device *d, const char *text, int instance, int callid) |
| 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 void | transmit_linestatres (struct skinny_device *d, struct skinny_line *l) |
| 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_serverres (struct skinny_device *d) |
| static void | transmit_softkeysetres (struct skinny_device *d) |
| static void | transmit_softkeytemplateres (struct skinny_device *d) |
| static void | transmit_speaker_mode (struct skinny_device *d, int mode) |
| static void | transmit_speeddialstatres (struct skinny_device *d, struct skinny_speeddial *sd) |
| static void | transmit_start_tone (struct skinny_device *d, int tone, int instance, int reference) |
| static void | transmit_startmediatransmission (struct skinny_device *d, struct skinny_subchannel *sub, struct sockaddr_in dest, struct ast_format_list fmt) |
| static void | transmit_stop_tone (struct skinny_device *d, int instance, int reference) |
| static void | transmit_stopmediatransmission (struct skinny_device *d, struct skinny_subchannel *sub) |
| static void | transmit_versionres (struct skinny_device *d) |
| static int | unload_module (void) |
| static void | unregister_exten (struct skinny_line *l) |
| static void | update_connectedline (struct skinny_subchannel *sub, const void *data, size_t datalen) |
Variables | |
| static struct ast_module_info | __mod_info = { .name = AST_MODULE, .flags = AST_MODFLAG_LOAD_ORDER , .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 = AST_BUILDOPT_SUM, .load = load_module, .unload = unload_module, .reload = reload, .load_pri = AST_MODPRI_CHANNEL_DRIVER, } |
| static struct in_addr | __ourip |
| static pthread_t | accept_t |
| static struct ast_hostent | ahp |
| static struct ast_module_info * | ast_module_info = &__mod_info |
| static int | auth_limit = DEFAULT_AUTH_LIMIT |
| static int | auth_timeout = DEFAULT_AUTH_TIMEOUT |
| static struct sockaddr_in | bindaddr |
| static int | callnums = 1 |
| static struct ast_cli_entry | cli_skinny [] |
| 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 char | date_format [6] = "D-M-Y" |
| static format_t | default_capability = AST_FORMAT_ULAW | AST_FORMAT_ALAW |
| static struct skinny_device_options * | default_device = &default_device_struct |
| static struct skinny_device_options | default_device_struct |
| static struct ast_jb_conf | default_jbconf |
| static struct skinny_line_options * | default_line = &default_line_struct |
| static struct skinny_line_options | default_line_struct |
| 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 struct devices | devices |
| static int | firstdigittimeout = 16000 |
| static int | gendigittimeout = 8000 |
| static struct ast_jb_conf | global_jbconf |
| static char | global_vmexten [AST_MAX_EXTENSION] |
| static struct hostent * | hp |
| static struct io_context * | io |
| static int | keep_alive = 120 |
| static struct lines | lines |
| static int | matchdigittimeout = 3000 |
| static pthread_t | monitor_thread = AST_PTHREADT_NULL |
| static ast_mutex_t | monlock = { PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP , NULL, 1 } |
| static ast_mutex_t | netlock = { PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP , NULL, 1 } |
| static char | ourhost [256] |
| static int | ourport |
| 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 struct sched_context * | sched = NULL |
| static struct sessions | sessions |
| static int | skinny_header_size = 12 |
| static struct ast_rtp_glue | skinny_rtp_glue |
| static struct ast_channel_tech | skinny_tech |
| static int | skinnydebug = 0 |
| static int | skinnyreload = 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 [] |
| static struct soft_key_template_definition | soft_key_template_default [] |
| static const char | tdesc [] = "Skinny Client Control Protocol (Skinny)" |
| static int | unauth_sessions = 0 |
| static char | used_context [AST_MAX_EXTENSION] |
| static char | version_id [16] = "P002F202" |
Implementation of the Skinny protocol.
Definition in file chan_skinny.c.
| #define ACTIVATE_CALL_PLANE_MESSAGE 0x0116 |
Definition at line 964 of file chan_skinny.c.
Referenced by transmit_activatecallplane().
| #define ALARM_MESSAGE 0x0020 |
Definition at line 331 of file chan_skinny.c.
Referenced by handle_message().
| #define BT_AUTOANSWER STIMULUS_AUTOANSWER |
Definition at line 538 of file chan_skinny.c.
| #define BT_CALLPARK STIMULUS_CALLPARK |
Definition at line 541 of file chan_skinny.c.
Referenced by get_button_template().
| #define BT_CALLPICKUP STIMULUS_CALLPICKUP |
Definition at line 542 of file chan_skinny.c.
| #define BT_CONFERENCE STIMULUS_CONFERENCE |
Definition at line 540 of file chan_skinny.c.
Referenced by get_button_template().
| #define BT_CUST_LINE 0xB1 |
Definition at line 549 of file chan_skinny.c.
Referenced by get_button_template(), and handle_button_template_req_message().
| #define BT_CUST_LINESPEEDDIAL 0xB0 |
Definition at line 548 of file chan_skinny.c.
Referenced by get_button_template(), and handle_button_template_req_message().
| #define BT_DISPLAY STIMULUS_DISPLAY |
Definition at line 535 of file chan_skinny.c.
Referenced by get_button_template().
| #define BT_DND STIMULUS_DND |
Definition at line 539 of file chan_skinny.c.
| #define BT_FORWARDALL STIMULUS_FORWARDALL |
Definition at line 532 of file chan_skinny.c.
Referenced by get_button_template().
| #define BT_FORWARDBUSY STIMULUS_FORWARDBUSY |
Definition at line 533 of file chan_skinny.c.
| #define BT_FORWARDNOANSWER STIMULUS_FORWARDNOANSWER |
Definition at line 534 of file chan_skinny.c.
| #define BT_HOLD STIMULUS_HOLD |
Definition at line 530 of file chan_skinny.c.
Referenced by get_button_template().
| #define BT_LINE STIMULUS_LINE |
Definition at line 536 of file chan_skinny.c.
Referenced by get_button_template(), and handle_button_template_req_message().
| #define BT_NONE 0x00 |
Definition at line 543 of file chan_skinny.c.
Referenced by get_button_template(), and handle_button_template_req_message().
| #define BT_REDIAL STIMULUS_REDIAL |
Definition at line 528 of file chan_skinny.c.
Referenced by get_button_template().
| #define BT_SPEEDDIAL STIMULUS_SPEEDDIAL |
Definition at line 529 of file chan_skinny.c.
Referenced by get_button_template(), and handle_button_template_req_message().
| #define BT_TRANSFER STIMULUS_TRANSFER |
Definition at line 531 of file chan_skinny.c.
Referenced by get_button_template().
| #define BT_VOICEMAIL STIMULUS_VOICEMAIL |
Definition at line 537 of file chan_skinny.c.
Referenced by get_button_template().
| #define BUTTON_TEMPLATE_REQ_MESSAGE 0x000E |
Definition at line 327 of file chan_skinny.c.
Referenced by handle_message().
| #define BUTTON_TEMPLATE_RES_MESSAGE 0x0097 |
Definition at line 498 of file chan_skinny.c.
Referenced by handle_button_template_req_message().
| #define CALL_INFO_MESSAGE 0x008F |
Definition at line 436 of file chan_skinny.c.
Referenced by transmit_callinfo().
| #define CALL_STATE_MESSAGE 0x0111 |
Definition at line 935 of file chan_skinny.c.
Referenced by transmit_callstate().
| #define CAPABILITIES_REQ_MESSAGE 0x009B |
Definition at line 571 of file chan_skinny.c.
Referenced by handle_register_message().
| #define CAPABILITIES_RES_MESSAGE 0x0010 |
Definition at line 299 of file chan_skinny.c.
Referenced by handle_message().
| #define CDEV ((struct skinny_device *)item) |
Definition at line 6663 of file chan_skinny.c.
Referenced by config_parse_variables().
| #define CDEV_OPTS ((struct skinny_device_options *)item) |
Definition at line 6662 of file chan_skinny.c.
Referenced by config_parse_variables().
| #define CLEAR_DISPLAY_MESSAGE 0x009A |
Definition at line 569 of file chan_skinny.c.
Referenced by transmit_clear_display_message().
| #define CLEAR_NOTIFY_MESSAGE 0x0115 |
Definition at line 568 of file chan_skinny.c.
| #define CLEAR_PROMPT_MESSAGE 0x0113 |
Definition at line 952 of file chan_skinny.c.
Referenced by transmit_clearpromptmessage().
| #define CLINE ((struct skinny_line *)item) |
Definition at line 6661 of file chan_skinny.c.
Referenced by config_parse_variables().
| #define CLINE_OPTS ((struct skinny_line_options *)item) |
Definition at line 6660 of file chan_skinny.c.
Referenced by config_parse_variables().
| #define CLOSE_RECEIVE_CHANNEL_MESSAGE 0x0106 |
Definition at line 607 of file chan_skinny.c.
Referenced by transmit_closereceivechannel().
| #define CONTROL2STR_BUFSIZE 100 |
Definition at line 246 of file chan_skinny.c.
Referenced by control2str().
| #define DEFAULT_AUTH_LIMIT 50 |
Definition at line 164 of file chan_skinny.c.
Referenced by config_parse_variables().
| #define DEFAULT_AUTH_TIMEOUT 30 |
Definition at line 163 of file chan_skinny.c.
Referenced by config_parse_variables().
| #define DEFAULT_SKINNY_BACKLOG 2 |
Definition at line 161 of file chan_skinny.c.
Referenced by config_load().
| #define DEFAULT_SKINNY_PORT 2000 |
Definition at line 160 of file chan_skinny.c.
Referenced by config_device(), and config_load().
| #define DEFINETIMEDATE_MESSAGE 0x0094 |
Definition at line 485 of file chan_skinny.c.
Referenced by transmit_definetimedate().
| #define DEVICE2STR_BUFSIZE 15 |
Definition at line 243 of file chan_skinny.c.
Referenced by device2str().
| #define DIALED_NUMBER_MESSAGE 0x011D |
Definition at line 969 of file chan_skinny.c.
Referenced by transmit_dialednumber().
| #define DISPLAY_NOTIFY_MESSAGE 0x0114 |
Definition at line 958 of file chan_skinny.c.
Referenced by transmit_displaynotify().
| #define DISPLAY_PROMPT_STATUS_MESSAGE 0x0112 |
Definition at line 943 of file chan_skinny.c.
Referenced by transmit_displaypromptstatus().
| #define DISPLAYTEXT_MESSAGE 0x0099 |
Definition at line 563 of file chan_skinny.c.
| #define ENBLOC_CALL_MESSAGE 0x0004 |
Definition at line 275 of file chan_skinny.c.
Referenced by handle_message().
| #define FORWARD_STAT_MESSAGE 0x0090 |
Definition at line 458 of file chan_skinny.c.
Referenced by transmit_cfwdstate().
| #define HEADSET_STATUS_MESSAGE 0x002B |
Definition at line 358 of file chan_skinny.c.
Referenced by handle_message().
| #define htolel | ( | x | ) | bswap_32(x) |
Definition at line 195 of file chan_skinny.c.
Referenced by get_input(), handle_button_template_req_message(), handle_register_message(), load_module(), req_alloc(), transmit_activatecallplane(), transmit_callinfo(), transmit_callstate(), transmit_cfwdstate(), transmit_clearpromptmessage(), transmit_closereceivechannel(), transmit_connect(), transmit_definetimedate(), transmit_dialednumber(), transmit_displaynotify(), transmit_displaypromptstatus(), transmit_lamp_indication(), transmit_ringer_mode(), transmit_selectsoftkeys(), transmit_serverres(), transmit_softkeysetres(), transmit_softkeytemplateres(), transmit_speaker_mode(), transmit_speeddialstatres(), transmit_start_tone(), transmit_startmediatransmission(), transmit_stop_tone(), and transmit_stopmediatransmission().
| #define htoles | ( | x | ) | bswap_16(x) |
Definition at line 196 of file chan_skinny.c.
Referenced by transmit_softkeysetres().
| #define IP_PORT_MESSAGE 0x0002 |
Definition at line 265 of file chan_skinny.c.
Referenced by handle_message().
| #define KEEP_ALIVE_ACK_MESSAGE 0x0100 |
Definition at line 594 of file chan_skinny.c.
Referenced by handle_keep_alive_message().
| #define KEEP_ALIVE_MESSAGE 0x0000 |
Definition at line 252 of file chan_skinny.c.
Referenced by handle_message().
| #define KEYDEF_CONNECTED 1 |
Definition at line 622 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 628 of file chan_skinny.c.
| #define KEYDEF_CONNWITHTRANS 5 |
Definition at line 626 of file chan_skinny.c.
| #define KEYDEF_DADFD 6 |
Definition at line 627 of file chan_skinny.c.
| #define KEYDEF_OFFHOOK 4 |
Definition at line 625 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 630 of file chan_skinny.c.
Referenced by handle_transfer_button().
| #define KEYDEF_ONHOLD 2 |
Definition at line 623 of file chan_skinny.c.
Referenced by handle_hold_button(), and handle_soft_key_event_message().
| #define KEYDEF_ONHOOK 0 |
Definition at line 621 of file chan_skinny.c.
Referenced by handle_callforward_button(), handle_message(), handle_onhook_message(), handle_soft_key_event_message(), handle_stimulus_message(), and skinny_hangup().
| #define KEYDEF_RINGIN 3 |
Definition at line 624 of file chan_skinny.c.
Referenced by skinny_call().
| #define KEYDEF_RINGOUT 8 |
Definition at line 629 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 631 of file chan_skinny.c.
| #define KEYPAD_BUTTON_MESSAGE 0x0003 |
Definition at line 267 of file chan_skinny.c.
Referenced by handle_message().
| #define letohl | ( | x | ) | bswap_32(x) |
Definition at line 193 of file chan_skinny.c.
Referenced by get_input(), handle_capabilities_res_message(), handle_keypad_button_message(), handle_message(), handle_offhook_message(), handle_onhook_message(), handle_open_receive_channel_ack_message(), handle_register_message(), handle_soft_key_event_message(), handle_stimulus_message(), skinny_register(), skinny_req_parse(), transmit_linestatres(), and transmit_response().
| #define letohs | ( | x | ) | bswap_16(x) |
Definition at line 194 of file chan_skinny.c.
| #define LINE_STAT_RES_MESSAGE 0x0092 |
Definition at line 477 of file chan_skinny.c.
Referenced by transmit_linestatres().
| #define LINE_STATE_REQ_MESSAGE 0x000B |
Definition at line 321 of file chan_skinny.c.
Referenced by handle_message().
| #define OFFHOOK_MESSAGE 0x0006 |
Definition at line 287 of file chan_skinny.c.
Referenced by handle_message().
| #define ONHOOK_MESSAGE 0x0007 |
Definition at line 293 of file chan_skinny.c.
Referenced by handle_message().
| #define OPEN_RECEIVE_CHANNEL_ACK_MESSAGE 0x0022 |
Definition at line 339 of file chan_skinny.c.
Referenced by handle_message().
| #define OPEN_RECEIVE_CHANNEL_MESSAGE 0x0105 |
Definition at line 596 of file chan_skinny.c.
Referenced by transmit_connect().
| #define REGISTER_ACK_MESSAGE 0x0081 |
Definition at line 361 of file chan_skinny.c.
Referenced by handle_register_message().
| #define REGISTER_AVAILABLE_LINES_MESSAGE 0x002D |
Definition at line 359 of file chan_skinny.c.
Referenced by handle_message().
| #define REGISTER_MESSAGE 0x0001 |
Definition at line 255 of file chan_skinny.c.
Referenced by handle_message().
| #define REGISTER_REJ_MESSAGE 0x009D |
Definition at line 573 of file chan_skinny.c.
Referenced by handle_register_message().
| #define RESET_MESSAGE 0x009F |
Definition at line 589 of file chan_skinny.c.
Referenced by handle_skinny_reset(), and skinny_reload().
| #define SELECT_SOFT_KEYS_MESSAGE 0x0110 |
Definition at line 927 of file chan_skinny.c.
Referenced by transmit_selectsoftkeys().
| #define SERVER_REQUEST_MESSAGE 0x0012 |
Definition at line 329 of file chan_skinny.c.
Referenced by handle_message().
| #define SERVER_RES_MESSAGE 0x009E |
Definition at line 578 of file chan_skinny.c.
Referenced by transmit_serverres().
| #define SET_LAMP_MESSAGE 0x0086 |
Definition at line 392 of file chan_skinny.c.
Referenced by transmit_lamp_indication().
| #define SET_MICROPHONE_MESSAGE 0x0089 |
Definition at line 405 of file chan_skinny.c.
| #define SET_RINGER_MESSAGE 0x0085 |
Definition at line 384 of file chan_skinny.c.
Referenced by transmit_ringer_mode().
| #define SET_SPEAKER_MESSAGE 0x0088 |
Definition at line 399 of file chan_skinny.c.
Referenced by transmit_speaker_mode().
| #define SKINNY_ALERT 0x24 |
Definition at line 1116 of file chan_skinny.c.
Referenced by skinny_indicate().
| #define SKINNY_BUSY 6 |
Definition at line 1103 of file chan_skinny.c.
Referenced by skinny_indicate().
| #define SKINNY_BUSYTONE 0x23 |
Definition at line 1115 of file chan_skinny.c.
Referenced by skinny_indicate().
| #define SKINNY_CALLREMOTEMULTILINE 13 |
Definition at line 1110 of file chan_skinny.c.
Referenced by skinny_extensionstate_cb().
| #define SKINNY_CALLWAIT 9 |
Definition at line 1106 of file chan_skinny.c.
| #define SKINNY_CALLWAITTONE 0x2D |
Definition at line 1118 of file chan_skinny.c.
| #define SKINNY_CFWD_ALL (1 << 0) |
Definition at line 1132 of file chan_skinny.c.
Referenced by _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 1133 of file chan_skinny.c.
Referenced by _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 1134 of file chan_skinny.c.
Referenced by _skinny_show_line(), handle_soft_key_event_message(), handle_stimulus_message(), set_callforwards(), and transmit_cfwdstate().
| #define SKINNY_CONGESTION 7 |
Definition at line 1104 of file chan_skinny.c.
Referenced by skinny_indicate().
| #define SKINNY_CONNECTED 5 |
Definition at line 1102 of file chan_skinny.c.
Referenced by handle_offhook_message(), handle_soft_key_event_message(), handle_stimulus_message(), skinny_answer(), skinny_unhold(), and update_connectedline().
| #define SKINNY_CX_CONF 3 |
Definition at line 1140 of file chan_skinny.c.
| #define SKINNY_CX_CONFERENCE 3 |
Definition at line 1141 of file chan_skinny.c.
| #define SKINNY_CX_INACTIVE 4 |
Definition at line 1143 of file chan_skinny.c.
Referenced by skinny_new().
| #define SKINNY_CX_MUTE 4 |
Definition at line 1142 of file chan_skinny.c.
| #define SKINNY_CX_RECVONLY 1 |
Definition at line 1138 of file chan_skinny.c.
Referenced by handle_onhook_message(), and handle_soft_key_event_message().
| #define SKINNY_CX_SENDONLY 0 |
Definition at line 1137 of file chan_skinny.c.
| #define SKINNY_CX_SENDRECV 2 |
Definition at line 1139 of file chan_skinny.c.
Referenced by skinny_answer().
| #define SKINNY_DEVICE_12 4 |
Definition at line 1058 of file chan_skinny.c.
Referenced by device2str(), and get_button_template().
| #define SKINNY_DEVICE_12SP 3 |
Definition at line 1057 of file chan_skinny.c.
Referenced by device2str(), and get_button_template().
| #define SKINNY_DEVICE_12SPPLUS 2 |
Definition at line 1056 of file chan_skinny.c.
Referenced by device2str(), and get_button_template().
| #define SKINNY_DEVICE_30SPPLUS 1 |
Definition at line 1055 of file chan_skinny.c.
Referenced by device2str(), and get_button_template().
| #define SKINNY_DEVICE_30VIP 5 |
Definition at line 1059 of file chan_skinny.c.
Referenced by device2str(), and get_button_template().
| #define SKINNY_DEVICE_7902 30008 |
Definition at line 1085 of file chan_skinny.c.
Referenced by device2str(), and get_button_template().
| #define SKINNY_DEVICE_7905 20000 |
Definition at line 1081 of file chan_skinny.c.
Referenced by device2str(), and get_button_template().
| #define SKINNY_DEVICE_7906 369 |
Definition at line 1074 of file chan_skinny.c.
Referenced by device2str(), and get_button_template().
| #define SKINNY_DEVICE_7910 6 |
Definition at line 1060 of file chan_skinny.c.
Referenced by device2str(), and get_button_template().
| #define SKINNY_DEVICE_7911 307 |
Definition at line 1069 of file chan_skinny.c.
Referenced by device2str(), and get_button_template().
| #define SKINNY_DEVICE_7912 30007 |
Definition at line 1084 of file chan_skinny.c.
Referenced by device2str(), and get_button_template().
| #define SKINNY_DEVICE_7914 124 |
Definition at line 1067 of file chan_skinny.c.
Referenced by device2str(), and get_button_template().
| #define SKINNY_DEVICE_7920 30002 |
Definition at line 1082 of file chan_skinny.c.
Referenced by device2str(), and get_button_template().
| #define SKINNY_DEVICE_7921 365 |
Definition at line 1073 of file chan_skinny.c.
Referenced by device2str(), and get_button_template().
| #define SKINNY_DEVICE_7931 348 |
Definition at line 1072 of file chan_skinny.c.
Referenced by device2str(), and get_button_template().
| #define SKINNY_DEVICE_7935 9 |
Definition at line 1063 of file chan_skinny.c.
Referenced by device2str(), and get_button_template().
| #define SKINNY_DEVICE_7936 30019 |
Definition at line 1088 of file chan_skinny.c.
Referenced by device2str(), and get_button_template().
| #define SKINNY_DEVICE_7937 431 |
Definition at line 1076 of file chan_skinny.c.
Referenced by device2str(), and get_button_template().
| #define SKINNY_DEVICE_7940 8 |
Definition at line 1062 of file chan_skinny.c.
Referenced by device2str(), and get_button_template().
| #define SKINNY_DEVICE_7941 115 |
Definition at line 1065 of file chan_skinny.c.
Referenced by device2str(), and get_button_template().
| #define SKINNY_DEVICE_7941GE 309 |
Definition at line 1071 of file chan_skinny.c.
Referenced by device2str(), and get_button_template().
| #define SKINNY_DEVICE_7942 434 |
Definition at line 1077 of file chan_skinny.c.
Referenced by device2str(), and get_button_template().
| #define SKINNY_DEVICE_7945 435 |
Definition at line 1078 of file chan_skinny.c.
Referenced by device2str(), and get_button_template().
| #define SKINNY_DEVICE_7960 7 |
Definition at line 1061 of file chan_skinny.c.
Referenced by device2str(), and get_button_template().
| #define SKINNY_DEVICE_7961 30018 |
Definition at line 1087 of file chan_skinny.c.
Referenced by device2str(), and get_button_template().
| #define SKINNY_DEVICE_7961GE 308 |
Definition at line 1070 of file chan_skinny.c.
Referenced by device2str(), and get_button_template().
| #define SKINNY_DEVICE_7962 404 |
Definition at line 1075 of file chan_skinny.c.
Referenced by device2str(), and get_button_template().
| #define SKINNY_DEVICE_7965 436 |
Definition at line 1079 of file chan_skinny.c.
Referenced by device2str(), and get_button_template().
| #define SKINNY_DEVICE_7970 30006 |
Definition at line 1083 of file chan_skinny.c.
Referenced by device2str(), and get_button_template().
| #define SKINNY_DEVICE_7971 119 |
Definition at line 1066 of file chan_skinny.c.
Referenced by device2str(), and get_button_template().
| #define SKINNY_DEVICE_7975 437 |
Definition at line 1080 of file chan_skinny.c.
Referenced by device2str(), and get_button_template().
| #define SKINNY_DEVICE_7985 302 |
Definition at line 1068 of file chan_skinny.c.
Referenced by device2str(), and get_button_template().
| #define SKINNY_DEVICE_ATA186 12 |
Definition at line 1064 of file chan_skinny.c.
Referenced by device2str(), and get_button_template().
| #define SKINNY_DEVICE_CIPC 30016 |
Definition at line 1086 of file chan_skinny.c.
Referenced by device2str(), and get_button_template().
| #define SKINNY_DEVICE_NONE 0 |
Definition at line 1054 of file chan_skinny.c.
Referenced by device2str().
| #define SKINNY_DEVICE_OPTIONS |
Definition at line 1312 of file chan_skinny.c.
| #define SKINNY_DEVICE_SCCPGATEWAY_AN 30027 |
Definition at line 1089 of file chan_skinny.c.
Referenced by device2str(), and get_button_template().
| #define SKINNY_DEVICE_SCCPGATEWAY_BRI 30028 |
Definition at line 1090 of file chan_skinny.c.
Referenced by device2str(), and get_button_template().
| #define SKINNY_DEVICE_UNKNOWN -1 |
Definition at line 1053 of file chan_skinny.c.
Referenced by device2str().
| #define SKINNY_DEVONLY | ( | code | ) |
Definition at line 138 of file chan_skinny.c.
Referenced by handle_message(), and transmit_response().
| #define SKINNY_DIALTONE 0x21 |
Definition at line 1114 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 1105 of file chan_skinny.c.
Referenced by skinny_extensionstate_cb(), and skinny_hold().
| #define SKINNY_INVALID 14 |
Definition at line 1111 of file chan_skinny.c.
| #define SKINNY_LAMP_BLINK 5 |
Definition at line 1125 of file chan_skinny.c.
Referenced by mwi_event_cb(), skinny_call(), skinny_extensionstate_cb(), and skinny_hangup().
| #define SKINNY_LAMP_FLASH 4 |
Definition at line 1124 of file chan_skinny.c.
Referenced by skinny_extensionstate_cb().
| #define SKINNY_LAMP_OFF 1 |
Definition at line 1121 of file chan_skinny.c.
Referenced by handle_soft_key_event_message(), handle_stimulus_message(), mwi_event_cb(), skinny_extensionstate_cb(), and skinny_hangup().
| #define SKINNY_LAMP_ON 2 |
Definition at line 1122 of file chan_skinny.c.
Referenced by handle_offhook_message(), handle_soft_key_event_message(), handle_stimulus_message(), mwi_event_cb(), skinny_extensionstate_cb(), skinny_hangup(), skinny_ss(), and skinny_unhold().
| #define SKINNY_LAMP_WINK 3 |
Definition at line 1123 of file chan_skinny.c.
Referenced by skinny_extensionstate_cb(), and skinny_hold().
| #define SKINNY_LINE_OPTIONS |
Definition at line 1202 of file chan_skinny.c.
| #define SKINNY_MAX_CAPABILITIES 18 |
Definition at line 309 of file chan_skinny.c.
Referenced by handle_capabilities_res_message().
| #define SKINNY_MAX_PACKET 1000 |
Definition at line 162 of file chan_skinny.c.
Referenced by handle_register_message(), skinny_req_parse(), and transmit_response().
| #define SKINNY_MICOFF 2 |
Definition at line 1096 of file chan_skinny.c.
| #define SKINNY_MICON 1 |
Definition at line 1095 of file chan_skinny.c.
| #define SKINNY_NOTONE 0x7F |
Definition at line 1119 of file chan_skinny.c.
| #define SKINNY_OFFHOOK 1 |
Definition at line 1098 of file chan_skinny.c.
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_call(), skinny_ss(), and skinny_unhold().
| #define SKINNY_ONHOOK 2 |
Definition at line 1099 of file chan_skinny.c.
Referenced by get_devicestate(), handle_callforward_button(), handle_onhook_message(), handle_soft_key_event_message(), handle_stimulus_message(), skinny_call(), skinny_extensionstate_cb(), and skinny_hangup().
| #define SKINNY_PARK 11 |
Definition at line 1108 of file chan_skinny.c.
| #define SKINNY_PROGRESS 12 |
Definition at line 1109 of file chan_skinny.c.
Referenced by skinny_indicate(), and update_connectedline().
| #define SKINNY_REORDER 0x25 |
Definition at line 1117 of file chan_skinny.c.
Referenced by skinny_indicate(), skinny_newcall(), and skinny_ss().
| #define SKINNY_RING_FEATURE 4 |
Definition at line 1130 of file chan_skinny.c.
| #define SKINNY_RING_INSIDE 2 |
Definition at line 1128 of file chan_skinny.c.
Referenced by skinny_call().
| #define SKINNY_RING_OFF 1 |
Definition at line 1127 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 1129 of file chan_skinny.c.
| #define SKINNY_RINGIN 4 |
Definition at line 1101 of file chan_skinny.c.
Referenced by skinny_call(), skinny_extensionstate_cb(), and update_connectedline().
| #define SKINNY_RINGOUT 3 |
Definition at line 1100 of file chan_skinny.c.
Referenced by skinny_indicate(), and update_connectedline().
| #define SKINNY_SILENCE 0x00 |
Definition at line 1113 of file chan_skinny.c.
| #define SKINNY_SPEAKEROFF 2 |
Definition at line 1093 of file chan_skinny.c.
Referenced by handle_callforward_button(), handle_onhook_message(), handle_soft_key_event_message(), handle_stimulus_message(), and skinny_hangup().
| #define SKINNY_SPEAKERON 1 |
Definition at line 1092 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 1107 of file chan_skinny.c.
| #define SOFT_KEY_EVENT_MESSAGE 0x0026 |
Definition at line 349 of file chan_skinny.c.
Referenced by handle_message().
| #define SOFT_KEY_SET_REQ_MESSAGE 0x0025 |
Definition at line 347 of file chan_skinny.c.
Referenced by handle_message().
| #define SOFT_KEY_SET_RES_MESSAGE 0x0109 |
Definition at line 912 of file chan_skinny.c.
Referenced by transmit_softkeysetres().
| #define SOFT_KEY_TEMPLATE_REQ_MESSAGE 0x0028 |
Definition at line 357 of file chan_skinny.c.
Referenced by handle_message().
| #define SOFT_KEY_TEMPLATE_RES_MESSAGE 0x0108 |
Definition at line 614 of file chan_skinny.c.
Referenced by transmit_softkeytemplateres().
| #define SOFTKEY_ANSWER 0x0B |
Definition at line 644 of file chan_skinny.c.
Referenced by handle_soft_key_event_message().
| #define SOFTKEY_BKSPC 0x08 |
Definition at line 641 of file chan_skinny.c.
Referenced by handle_soft_key_event_message().
| #define SOFTKEY_CFWDALL 0x05 |
Definition at line 638 of file chan_skinny.c.
Referenced by handle_soft_key_event_message().
| #define SOFTKEY_CFWDBUSY 0x06 |
Definition at line 639 of file chan_skinny.c.
Referenced by handle_soft_key_event_message().
| #define SOFTKEY_CFWDNOANSWER 0x07 |
Definition at line 640 of file chan_skinny.c.
Referenced by handle_soft_key_event_message().
| #define SOFTKEY_CONFRN 0x0D |
Definition at line 646 of file chan_skinny.c.
Referenced by handle_soft_key_event_message().
| #define SOFTKEY_DND 0x13 |
Definition at line 652 of file chan_skinny.c.
Referenced by handle_soft_key_event_message().
| #define SOFTKEY_ENDCALL 0x09 |
Definition at line 642 of file chan_skinny.c.
Referenced by handle_soft_key_event_message().
| #define SOFTKEY_GPICKUP 0x12 |
Definition at line 651 of file chan_skinny.c.
Referenced by handle_soft_key_event_message().
| #define SOFTKEY_HOLD 0x03 |
Definition at line 636 of file chan_skinny.c.
Referenced by handle_soft_key_event_message().
| #define SOFTKEY_IDIVERT 0x14 |
Definition at line 653 of file chan_skinny.c.
| #define SOFTKEY_INFO 0x0C |
Definition at line 645 of file chan_skinny.c.
Referenced by handle_soft_key_event_message().
| #define SOFTKEY_JOIN 0x0F |
Definition at line 648 of file chan_skinny.c.
Referenced by handle_soft_key_event_message().
| #define SOFTKEY_MEETME 0x10 |
Definition at line 649 of file chan_skinny.c.
Referenced by handle_soft_key_event_message().
| #define SOFTKEY_NEWCALL 0x02 |
Definition at line 635 of file chan_skinny.c.
Referenced by handle_soft_key_event_message().
| #define SOFTKEY_NONE 0x00 |
Definition at line 633 of file chan_skinny.c.
Referenced by handle_soft_key_event_message().
| #define SOFTKEY_PARK 0x0E |
Definition at line 647 of file chan_skinny.c.
Referenced by handle_soft_key_event_message().
| #define SOFTKEY_PICKUP 0x11 |
Definition at line 650 of file chan_skinny.c.
Referenced by handle_soft_key_event_message().
| #define SOFTKEY_REDIAL 0x01 |
Definition at line 634 of file chan_skinny.c.
Referenced by handle_soft_key_event_message().
| #define SOFTKEY_RESUME 0x0A |
Definition at line 643 of file chan_skinny.c.
Referenced by handle_soft_key_event_message().
| #define SOFTKEY_TRNSFER 0x04 |
Definition at line 637 of file chan_skinny.c.
Referenced by handle_soft_key_event_message().
| #define SPEED_DIAL_STAT_REQ_MESSAGE 0x000A |
Definition at line 316 of file chan_skinny.c.
Referenced by handle_message().
| #define SPEED_DIAL_STAT_RES_MESSAGE 0x0091 |
Definition at line 470 of file chan_skinny.c.
Referenced by transmit_speeddialstatres().
| #define START_MEDIA_TRANSMISSION_MESSAGE 0x008A |
Definition at line 410 of file chan_skinny.c.
Referenced by transmit_startmediatransmission().
| #define START_TONE_MESSAGE 0x0082 |
Definition at line 370 of file chan_skinny.c.
Referenced by transmit_start_tone().
| #define STIMULUS_AUTOANSWER 0x11 |
Definition at line 520 of file chan_skinny.c.
| #define STIMULUS_CALLPARK 0x7E |
Definition at line 523 of file chan_skinny.c.
Referenced by handle_stimulus_message().
| #define STIMULUS_CALLPICKUP 0x7F |
Definition at line 524 of file chan_skinny.c.
| #define STIMULUS_CONFERENCE 0x7D |
Definition at line 522 of file chan_skinny.c.
Referenced by handle_stimulus_message().
| #define STIMULUS_DISPLAY 0x08 |
Definition at line 517 of file chan_skinny.c.
Referenced by handle_stimulus_message().
| #define STIMULUS_DND 0x3F |
Definition at line 521 of file chan_skinny.c.
Referenced by handle_soft_key_event_message(), and handle_stimulus_message().
| #define STIMULUS_FORWARDALL 0x05 |
Definition at line 514 of file chan_skinny.c.
Referenced by handle_stimulus_message(), and skinny_ss().
| #define STIMULUS_FORWARDBUSY 0x06 |
Definition at line 515 of file chan_skinny.c.
Referenced by handle_stimulus_message().
| #define STIMULUS_FORWARDNOANSWER 0x07 |
Definition at line 516 of file chan_skinny.c.
Referenced by handle_stimulus_message().
| #define STIMULUS_HOLD 0x03 |
Definition at line 512 of file chan_skinny.c.
Referenced by handle_stimulus_message().
| #define STIMULUS_LINE 0x09 |
Definition at line 518 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 280 of file chan_skinny.c.
Referenced by handle_message().
| #define STIMULUS_NONE 0xFF |
Definition at line 525 of file chan_skinny.c.
| #define STIMULUS_REDIAL 0x01 |
Definition at line 510 of file chan_skinny.c.
Referenced by handle_stimulus_message().
| #define STIMULUS_SPEEDDIAL 0x02 |
Definition at line 511 of file chan_skinny.c.
Referenced by handle_stimulus_message().
| #define STIMULUS_TRANSFER 0x04 |
Definition at line 513 of file chan_skinny.c.
Referenced by handle_stimulus_message().
| #define STIMULUS_VOICEMAIL 0x0F |
Definition at line 519 of file chan_skinny.c.
Referenced by handle_stimulus_message(), and mwi_event_cb().
| #define STOP_MEDIA_TRANSMISSION_MESSAGE 0x008B |
Definition at line 429 of file chan_skinny.c.
Referenced by transmit_stopmediatransmission().
| #define STOP_TONE_MESSAGE 0x0083 |
Definition at line 378 of file chan_skinny.c.
Referenced by transmit_stop_tone().
| #define TIME_DATE_REQ_MESSAGE 0x000D |
Definition at line 326 of file chan_skinny.c.
Referenced by handle_message().
| #define TYPE_DEF_DEVICE 2 |
Definition at line 6655 of file chan_skinny.c.
Referenced by config_load(), and config_parse_variables().
| #define TYPE_DEF_LINE 4 |
Definition at line 6656 of file chan_skinny.c.
Referenced by config_load(), and config_parse_variables().
| #define TYPE_DEVICE 8 |
Definition at line 6657 of file chan_skinny.c.
Referenced by config_device(), and config_parse_variables().
| #define TYPE_GENERAL 1 |
Definition at line 6654 of file chan_skinny.c.
Referenced by config_load(), and config_parse_variables().
| #define TYPE_LINE 16 |
Definition at line 6658 of file chan_skinny.c.
Referenced by config_line(), and config_parse_variables().
| #define UNREGISTER_MESSAGE 0x0027 |
Definition at line 356 of file chan_skinny.c.
Referenced by handle_message().
| #define VERSION_REQ_MESSAGE 0x000F |
Definition at line 328 of file chan_skinny.c.
Referenced by handle_message().
| #define VERSION_RES_MESSAGE 0x0098 |
Definition at line 558 of file chan_skinny.c.
Referenced by transmit_versionres().
| 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 150 of file chan_skinny.c.
{
SKINNY_CODEC_ALAW = 2,
SKINNY_CODEC_ULAW = 4,
SKINNY_CODEC_G723_1 = 9,
SKINNY_CODEC_G729A = 12,
SKINNY_CODEC_G726_32 = 82, /* XXX Which packing order does this translate to? */
SKINNY_CODEC_H261 = 100,
SKINNY_CODEC_H263 = 101
};
| static void __init_control2str_threadbuf | ( | void | ) | [static] |
Definition at line 245 of file chan_skinny.c.
{
| static void __init_device2str_threadbuf | ( | void | ) | [static] |
Definition at line 242 of file chan_skinny.c.
{
| static void __reg_module | ( | void | ) | [static] |
Definition at line 7562 of file chan_skinny.c.
| static void __unreg_module | ( | void | ) | [static] |
Definition at line 7562 of file chan_skinny.c.
| static char* _skinny_show_device | ( | int | type, |
| int | fd, | ||
| struct mansession * | s, | ||
| const struct message * | m, | ||
| int | argc, | ||
| const char * | argv[] | ||
| ) | [static] |
Definition at line 3247 of file chan_skinny.c.
References skinny_device::addons, ast_cli(), ast_getformatname_multiple(), ast_inet_ntoa(), AST_LIST_LOCK, AST_LIST_TRAVERSE, AST_LIST_UNLOCK, astman_append(), CLI_SHOWUSAGE, CLI_SUCCESS, device2str(), skinny_speeddial::exten, skinny_speeddial::isHint, skinny_speeddial::label, skinny_device::lines, S_OR, skinny_device::session, skinnysession::sin, skinny_device::speeddials, and skinny_addon::type.
Referenced by handle_skinny_show_device(), and manager_skinny_show_device().
{
struct skinny_device *d;
struct skinny_line *l;
struct skinny_speeddial *sd;
struct skinny_addon *sa;
char codec_buf[512];
if (argc < 4) {
return CLI_SHOWUSAGE;
}
AST_LIST_LOCK(&devices);
AST_LIST_TRAVERSE(&devices, d, list) {
if (!strcasecmp(argv[3], d->id) || !strcasecmp(argv[3], d->name)) {
int numlines = 0, numaddons = 0, numspeeddials = 0;
AST_LIST_TRAVERSE(&d->lines, l, list){
numlines++;
}
AST_LIST_TRAVERSE(&d->addons, sa, list) {
numaddons++;
}
AST_LIST_TRAVERSE(&d->speeddials, sd, list) {
numspeeddials++;
}
if (type == 0) { /* CLI */
ast_cli(fd, "Name: %s\n", d->name);
ast_cli(fd, "Id: %s\n", d->id);
ast_cli(fd, "version: %s\n", S_OR(d->version_id, "Unknown"));
ast_cli(fd, "Ip address: %s\n", (d->session ? ast_inet_ntoa(d->session->sin.sin_addr) : "Unknown"));
ast_cli(fd, "Port: %d\n", (d->session ? ntohs(d->session->sin.sin_port) : 0));
ast_cli(fd, "Device Type: %s\n", device2str(d->type));
ast_cli(fd, "Conf Codecs:");
ast_getformatname_multiple(codec_buf, sizeof(codec_buf) - 1, d->confcapability);
ast_cli(fd, "%s\n", codec_buf);
ast_cli(fd, "Neg Codecs: ");
ast_getformatname_multiple(codec_buf, sizeof(codec_buf) - 1, d->capability);
ast_cli(fd, "%s\n", codec_buf);
ast_cli(fd, "Registered: %s\n", (d->registered ? "Yes" : "No"));
ast_cli(fd, "Lines: %d\n", numlines);
AST_LIST_TRAVERSE(&d->lines, l, list) {
ast_cli(fd, " %s (%s)\n", l->name, l->label);
}
AST_LIST_TRAVERSE(&d->addons, sa, list) {
numaddons++;
}
ast_cli(fd, "Addons: %d\n", numaddons);
AST_LIST_TRAVERSE(&d->addons, sa, list) {
ast_cli(fd, " %s\n", sa->type);
}
AST_LIST_TRAVERSE(&d->speeddials, sd, list) {
numspeeddials++;
}
ast_cli(fd, "Speeddials: %d\n", numspeeddials);
AST_LIST_TRAVERSE(&d->speeddials, sd, list) {
ast_cli(fd, " %s (%s) ishint: %d\n", sd->exten, sd->label, sd->isHint);
}
} else { /* manager */
astman_append(s, "Channeltype: SKINNY\r\n");
astman_append(s, "ObjectName: %s\r\n", d->name);
astman_append(s, "ChannelObjectType: device\r\n");
astman_append(s, "Id: %s\r\n", d->id);
astman_append(s, "version: %s\r\n", S_OR(d->version_id, "Unknown"));
astman_append(s, "Ipaddress: %s\r\n", (d->session ? ast_inet_ntoa(d->session->sin.sin_addr) : "Unknown"));
astman_append(s, "Port: %d\r\n", (d->session ? ntohs(d->session->sin.sin_port) : 0));
astman_append(s, "DeviceType: %s\r\n", device2str(d->type));
astman_append(s, "Codecs: ");
ast_getformatname_multiple(codec_buf, sizeof(codec_buf) -1, d->confcapability);
astman_append(s, "%s\r\n", codec_buf);
astman_append(s, "CodecOrder: ");
ast_getformatname_multiple(codec_buf, sizeof(codec_buf) -1, d->capability);
astman_append(s, "%s\r\n", codec_buf);
astman_append(s, "Devicestatus: %s\r\n", (d->registered?"registered":"unregistered"));
astman_append(s, "NumberOfLines: %d\r\n", numlines);
AST_LIST_TRAVERSE(&d->lines, l, list) {
astman_append(s, "Line: %s (%s)\r\n", l->name, l->label);
}
astman_append(s, "NumberOfAddons: %d\r\n", numaddons);
AST_LIST_TRAVERSE(&d->addons, sa, list) {
astman_append(s, "Addon: %s\r\n", sa->type);
}
astman_append(s, "NumberOfSpeeddials: %d\r\n", numspeeddials);
AST_LIST_TRAVERSE(&d->speeddials, sd, list) {
astman_append(s, "Speeddial: %s (%s) ishint: %d\r\n", sd->exten, sd->label, sd->isHint);
}
}
}
}
AST_LIST_UNLOCK(&devices);
return CLI_SUCCESS;
}
| static char* _skinny_show_devices | ( | int | fd, |
| int * | total, | ||
| struct mansession * | s, | ||
| const struct message * | m, | ||
| int | argc, | ||
| const char * | argv[] | ||
| ) | [static] |
Definition at line 3136 of file chan_skinny.c.
References ast_cli(), ast_inet_ntoa(), AST_LIST_LOCK, AST_LIST_TRAVERSE, AST_LIST_UNLOCK, ast_strlen_zero(), astman_append(), astman_get_header(), CLI_SHOWUSAGE, CLI_SUCCESS, device2str(), id, skinny_device::lines, skinny_device::session, and skinnysession::sin.
Referenced by handle_skinny_show_devices(), and manager_skinny_show_devices().
{
struct skinny_device *d;
struct skinny_line *l;
const char *id;
char idtext[256] = "";
int total_devices = 0;
if (s) { /* Manager - get ActionID */
id = astman_get_header(m, "ActionID");
if (!ast_strlen_zero(id))
snprintf(idtext, sizeof(idtext), "ActionID: %s\r\n", id);
}
switch (argc) {
case 3:
break;
default:
return CLI_SHOWUSAGE;
}
if (!s) {
ast_cli(fd, "Name DeviceId IP Type R NL\n");
ast_cli(fd, "-------------------- ---------------- --------------- --------------- - --\n");
}
AST_LIST_LOCK(&devices);
AST_LIST_TRAVERSE(&devices, d, list) {
int numlines = 0;
total_devices++;
AST_LIST_TRAVERSE(&d->lines, l, list) {
numlines++;
}
if (!s) {
ast_cli(fd, "%-20s %-16s %-15s %-15s %c %2d\n",
d->name,
d->id,
d->session?ast_inet_ntoa(d->session->sin.sin_addr):"",
device2str(d->type),
d->registered?'Y':'N',
numlines);
} else {
astman_append(s,
"Event: DeviceEntry\r\n%s"
"Channeltype: SKINNY\r\n"
"ObjectName: %s\r\n"
"ChannelObjectType: device\r\n"
"DeviceId: %s\r\n"
"IPaddress: %s\r\n"
"Type: %s\r\n"
"Devicestatus: %s\r\n"
"NumberOfLines: %d\r\n",
idtext,
d->name,
d->id,
d->session?ast_inet_ntoa(d->session->sin.sin_addr):"-none-",
device2str(d->type),
d->registered?"registered":"unregistered",
numlines);
}
}
AST_LIST_UNLOCK(&devices);
if (total)
*total = total_devices;
return CLI_SUCCESS;
}
| static char* _skinny_show_line | ( | int | type, |
| int | fd, | ||
| struct mansession * | s, | ||
| const struct message * | m, | ||
| int | argc, | ||
| const char * | argv[] | ||
| ) | [static] |
Definition at line 3504 of file chan_skinny.c.
References ast_callerid_merge(), ast_cdr_flags2str(), ast_cli(), ast_codec_pref_index(), ast_getformatname(), ast_getformatname_multiple(), AST_LIST_LOCK, AST_LIST_TRAVERSE, AST_LIST_UNLOCK, ast_print_group(), astman_append(), CLI_SHOWUSAGE, CLI_SUCCESS, skinny_device::lines, print_codec_to_cli(), S_COR, S_OR, SKINNY_CFWD_ALL, SKINNY_CFWD_BUSY, and SKINNY_CFWD_NOANSWER.
Referenced by handle_skinny_show_line(), and manager_skinny_show_line().
{
struct skinny_device *d;
struct skinny_line *l;
struct ast_codec_pref *pref;
int x = 0, codec = 0;
char codec_buf[512];
char group_buf[256];
char cbuf[256];
switch (argc) {
case 4:
break;
case 6:
break;
default:
return CLI_SHOWUSAGE;
}
AST_LIST_LOCK(&devices);
/* Show all lines matching the one supplied */
AST_LIST_TRAVERSE(&devices, d, list) {
if (argc == 6 && (strcasecmp(argv[5], d->id) && strcasecmp(argv[5], d->name))) {
continue;
}
AST_LIST_TRAVERSE(&d->lines, l, list) {
if (strcasecmp(argv[3], l->name)) {
continue;
}
if (type == 0) { /* CLI */
ast_cli(fd, "Line: %s\n", l->name);
ast_cli(fd, "On Device: %s\n", d->name);
ast_cli(fd, "Line Label: %s\n", l->label);
ast_cli(fd, "Extension: %s\n", S_OR(l->exten, "<not set>"));
ast_cli(fd, "Context: %s\n", l->context);
ast_cli(fd, "CallGroup: %s\n", ast_print_group(group_buf, sizeof(group_buf), l->callgroup));
ast_cli(fd, "PickupGroup: %s\n", ast_print_group(group_buf, sizeof(group_buf), l->pickupgroup));
ast_cli(fd, "Language: %s\n", S_OR(l->language, "<not set>"));
ast_cli(fd, "Accountcode: %s\n", S_OR(l->accountcode, "<not set>"));
ast_cli(fd, "AmaFlag: %s\n", ast_cdr_flags2str(l->amaflags));
ast_cli(fd, "CallerId Number: %s\n", S_OR(l->cid_num, "<not set>"));
ast_cli(fd, "CallerId Name: %s\n", S_OR(l->cid_name, "<not set>"));
ast_cli(fd, "Hide CallerId: %s\n", (l->hidecallerid ? "Yes" : "No"));
ast_cli(fd, "CFwdAll: %s\n", S_COR((l->cfwdtype & SKINNY_CFWD_ALL), l->call_forward_all, "<not set>"));
ast_cli(fd, "CFwdBusy: %s\n", S_COR((l->cfwdtype & SKINNY_CFWD_BUSY), l->call_forward_busy, "<not set>"));
ast_cli(fd, "CFwdNoAnswer: %s\n", S_COR((l->cfwdtype & SKINNY_CFWD_NOANSWER), l->call_forward_noanswer, "<not set>"));
ast_cli(fd, "VoicemailBox: %s\n", S_OR(l->mailbox, "<not set>"));
ast_cli(fd, "VoicemailNumber: %s\n", S_OR(l->vmexten, "<not set>"));
ast_cli(fd, "MWIblink: %d\n", l->mwiblink);
ast_cli(fd, "Regextension: %s\n", S_OR(l->regexten, "<not set>"));
ast_cli(fd, "Regcontext: %s\n", S_OR(l->regcontext, "<not set>"));
ast_cli(fd, "MoHInterpret: %s\n", S_OR(l->mohinterpret, "<not set>"));
ast_cli(fd, "MoHSuggest: %s\n", S_OR(l->mohsuggest, "<not set>"));
ast_cli(fd, "Last dialed nr: %s\n", S_OR(l->lastnumberdialed, "<no calls made yet>"));
ast_cli(fd, "Last CallerID: %s\n", S_OR(l->lastcallerid, "<not set>"));
ast_cli(fd, "Transfer enabled: %s\n", (l->transfer ? "Yes" : "No"));
ast_cli(fd, "Callwaiting: %s\n", (l->callwaiting ? "Yes" : "No"));
ast_cli(fd, "3Way Calling: %s\n", (l->threewaycalling ? "Yes" : "No"));
ast_cli(fd, "Can forward: %s\n", (l->cancallforward ? "Yes" : "No"));
ast_cli(fd, "Do Not Disturb: %s\n", (l->dnd ? "Yes" : "No"));
ast_cli(fd, "NAT: %s\n", (l->nat ? "Yes" : "No"));
ast_cli(fd, "immediate: %s\n", (l->immediate ? "Yes" : "No"));
ast_cli(fd, "Group: %d\n", l->group);
ast_cli(fd, "Parkinglot: %s\n", S_OR(l->parkinglot, "<not set>"));
ast_cli(fd, "Conf Codecs: ");
ast_getformatname_multiple(codec_buf, sizeof(codec_buf) - 1, l->confcapability);
ast_cli(fd, "%s\n", codec_buf);
ast_cli(fd, "Neg Codecs: ");
ast_getformatname_multiple(codec_buf, sizeof(codec_buf) - 1, l->capability);
ast_cli(fd, "%s\n", codec_buf);
ast_cli(fd, "Codec Order: (");
print_codec_to_cli(fd, &l->prefs);
ast_cli(fd, ")\n");
ast_cli(fd, "\n");
} else { /* manager */
astman_append(s, "Channeltype: SKINNY\r\n");
astman_append(s, "ObjectName: %s\r\n", l->name);
astman_append(s, "ChannelObjectType: line\r\n");
astman_append(s, "Device: %s\r\n", d->name);
astman_append(s, "LineLabel: %s\r\n", l->label);
astman_append(s, "Extension: %s\r\n", S_OR(l->exten, "<not set>"));
astman_append(s, "Context: %s\r\n", l->context);
astman_append(s, "CallGroup: %s\r\n", ast_print_group(group_buf, sizeof(group_buf), l->callgroup));
astman_append(s, "PickupGroup: %s\r\n", ast_print_group(group_buf, sizeof(group_buf), l->pickupgroup));
astman_append(s, "Language: %s\r\n", S_OR(l->language, "<not set>"));
astman_append(s, "Accountcode: %s\r\n", S_OR(l->accountcode, "<not set>"));
astman_append(s, "AMAflags: %s\r\n", ast_cdr_flags2str(l->amaflags));
astman_append(s, "Callerid: %s\r\n", ast_callerid_merge(cbuf, sizeof(cbuf), l->cid_name, l->cid_num, ""));
astman_append(s, "HideCallerId: %s\r\n", (l->hidecallerid ? "Yes" : "No"));
astman_append(s, "CFwdAll: %s\r\n", S_COR((l->cfwdtype & SKINNY_CFWD_ALL), l->call_forward_all, "<not set>"));
astman_append(s, "CFwdBusy: %s\r\n", S_COR((l->cfwdtype & SKINNY_CFWD_BUSY), l->call_forward_busy, "<not set>"));
astman_append(s, "CFwdNoAnswer: %s\r\n", S_COR((l->cfwdtype & SKINNY_CFWD_NOANSWER), l->call_forward_noanswer, "<not set>"));
astman_append(s, "VoicemailBox: %s\r\n", S_OR(l->mailbox, "<not set>"));
astman_append(s, "VoicemailNumber: %s\r\n", S_OR(l->vmexten, "<not set>"));
astman_append(s, "MWIblink: %d\r\n", l->mwiblink);
astman_append(s, "RegExtension: %s\r\n", S_OR(l->regexten, "<not set>"));
astman_append(s, "Regcontext: %s\r\n", S_OR(l->regcontext, "<not set>"));
astman_append(s, "MoHInterpret: %s\r\n", S_OR(l->mohinterpret, "<not set>"));
astman_append(s, "MoHSuggest: %s\r\n", S_OR(l->mohsuggest, "<not set>"));
astman_append(s, "LastDialedNr: %s\r\n", S_OR(l->lastnumberdialed, "<no calls made yet>"));
astman_append(s, "LastCallerID: %s\r\n", S_OR(l->lastcallerid, "<not set>"));
astman_append(s, "Transfer: %s\r\n", (l->transfer ? "Yes" : "No"));
astman_append(s, "Callwaiting: %s\r\n", (l->callwaiting ? "Yes" : "No"));
astman_append(s, "3WayCalling: %s\r\n", (l->threewaycalling ? "Yes" : "No"));
astman_append(s, "CanForward: %s\r\n", (l->cancallforward ? "Yes" : "No"));
astman_append(s, "DoNotDisturb: %s\r\n", (l->dnd ? "Yes" : "No"));
astman_append(s, "NAT: %s\r\n", (l->nat ? "Yes" : "No"));
astman_append(s, "immediate: %s\r\n", (l->immediate ? "Yes" : "No"));
astman_append(s, "Group: %d\r\n", l->group);
astman_append(s, "Parkinglot: %s\r\n", S_OR(l->parkinglot, "<not set>"));
ast_getformatname_multiple(codec_buf, sizeof(codec_buf) - 1, l->confcapability);
astman_append(s, "Codecs: %s\r\n", codec_buf);
astman_append(s, "CodecOrder: ");
pref = &l->prefs;
for(x = 0; x < 32 ; x++) {
codec = ast_codec_pref_index(pref, x);
if (!codec)
break;
astman_append(s, "%s", ast_getformatname(codec));
if (x < 31 && ast_codec_pref_index(pref, x+1))
astman_append(s, ",");
}
astman_append(s, "\r\n");
}
}
}
AST_LIST_UNLOCK(&devices);
return CLI_SUCCESS;
}
| static char* _skinny_show_lines | ( | int | fd, |
| int * | total, | ||
| struct mansession * | s, | ||
| const struct message * | m, | ||
| int | argc, | ||
| const char * | argv[] | ||
| ) | [static] |
Definition at line 3380 of file chan_skinny.c.
References skinny_line::activesub, ast_bridged_channel(), ast_cli(), AST_LIST_LOCK, AST_LIST_TRAVERSE, AST_LIST_UNLOCK, ast_strlen_zero(), astman_append(), astman_get_header(), CLI_SHOWUSAGE, CLI_SUCCESS, skinny_line::device, id, ast_channel::name, skinny_subchannel::owner, and skinny_line::sub.
Referenced by handle_skinny_show_lines(), and manager_skinny_show_lines().
{
struct skinny_line *l;
struct skinny_subchannel *sub;
int total_lines = 0;
int verbose = 0;
const char *id;
char idtext[256] = "";
if (s) { /* Manager - get ActionID */
id = astman_get_header(m, "ActionID");
if (!ast_strlen_zero(id))
snprintf(idtext, sizeof(idtext), "ActionID: %s\r\n", id);
}
switch (argc) {
case 4:
verbose = 1;
break;
case 3:
verbose = 0;
break;
default:
return CLI_SHOWUSAGE;
}
if (!s) {
ast_cli(fd, "Name Device Name Instance Label \n");
ast_cli(fd, "-------------------- -------------------- -------- --------------------\n");
}
AST_LIST_LOCK(&lines);
AST_LIST_TRAVERSE(&lines, l, all) {
total_lines++;
if (!s) {
ast_cli(fd, "%-20s %-20s %8d %-20s\n",
l->name,
(l->device ? l->device->name : "Not connected"),
l->instance,
l->label);
if (verbose) {
AST_LIST_TRAVERSE(&l->sub, sub, list) {
ast_cli(fd, " %s> %s to %s\n",
(sub == l->activesub?"Active ":"Inactive"),
sub->owner->name,
(ast_bridged_channel(sub->owner)?ast_bridged_channel(sub->owner)->name:"")
);
}
}
} else {
astman_append(s,
"Event: LineEntry\r\n%s"
"Channeltype: SKINNY\r\n"
"ObjectName: %s\r\n"
"ChannelObjectType: line\r\n"
"Device: %s\r\n"
"Instance: %d\r\n"
"Label: %s\r\n",
idtext,
l->name,
(l->device?l->device->name:"None"),
l->instance,
l->label);
}
}
AST_LIST_UNLOCK(&lines);
if (total) {
*total = total_lines;
}
return CLI_SUCCESS;
}
| static void* accept_thread | ( | void * | ignore | ) | [static] |
Definition at line 6499 of file chan_skinny.c.
References ast_atomic_fetchadd_int(), ast_calloc, AST_LIST_INSERT_HEAD, AST_LIST_LOCK, AST_LIST_UNLOCK, ast_log(), ast_mutex_init, ast_pthread_create, ast_verb, destroy_session(), errno, skinnysession::fd, skinnysession::lock, LOG_ERROR, LOG_NOTICE, LOG_WARNING, skinnysession::sin, skinny_session(), skinnysession::start, and skinnysession::t.
Referenced by config_load().
{
int as;
struct sockaddr_in sin;
socklen_t sinlen;
struct skinnysession *s;
struct protoent *p;
int arg = 1;
for (;;) {
sinlen = sizeof(sin);
as = accept(skinnysock, (struct sockaddr *)&sin, &sinlen);
if (as < 0) {
ast_log(LOG_NOTICE, "Accept returned -1: %s\n", strerror(errno));
continue;
}
if (ast_atomic_fetchadd_int(&unauth_sessions, +1) >= auth_limit) {
close(as);
ast_atomic_fetchadd_int(&unauth_sessions, -1);
continue;
}
p = getprotobyname("tcp");
if(p) {
if( setsockopt(as, p->p_proto, TCP_NODELAY, (char *)&arg, sizeof(arg) ) < 0 ) {
ast_log(LOG_WARNING, "Failed to set Skinny tcp connection to TCP_NODELAY mode: %s\n", strerror(errno));
}
}
if (!(s = ast_calloc(1, sizeof(struct skinnysession)))) {
close(as);
ast_atomic_fetchadd_int(&unauth_sessions, -1);
continue;
}
memcpy(&s->sin, &sin, sizeof(sin));
ast_mutex_init(&s->lock);
s->fd = as;
if(time(&s->start) == -1) {
ast_log(LOG_ERROR, "error executing time(): %s; disconnecting client\n", strerror(errno));
destroy_session(s);
continue;
}
AST_LIST_LOCK(&sessions);
AST_LIST_INSERT_HEAD(&sessions, s, list);
AST_LIST_UNLOCK(&sessions);
if (ast_pthread_create(&s->t, NULL, skinny_session, s)) {
destroy_session(s);
}
}
if (skinnydebug)
ast_verb(1, "killing accept thread\n");
close(as);
return 0;
}
| static struct ast_variable* add_var | ( | const char * | buf, |
| struct ast_variable * | list | ||
| ) | [static, read] |
implement the setvar config line
Definition at line 1637 of file chan_skinny.c.
References ast_strdupa, ast_variable_new(), skinny_subchannel::list, and ast_variable::next.
Referenced by config_parse_variables().
{
struct ast_variable *tmpvar = NULL;
char *varname = ast_strdupa(buf), *varval = NULL;
if ((varval = strchr(varname,'='))) {
*varval++ = '\0';
if ((tmpvar = ast_variable_new(varname, varval, ""))) {
tmpvar->next = list;
list = tmpvar;
}
}
return list;
}
| static void cleanup_stale_contexts | ( | char * | new, |
| char * | old | ||
| ) | [static] |
Definition at line 1798 of file chan_skinny.c.
References ast_context_destroy(), ast_context_find(), ast_copy_string(), AST_MAX_CONTEXT, and strsep().
Referenced by config_parse_variables().
{
char *oldcontext, *newcontext, *stalecontext, *stringp, newlist[AST_MAX_CONTEXT];
while ((oldcontext = strsep(&old, "&"))) {
stalecontext = '\0';
ast_copy_string(newlist, new, sizeof(newlist));
stringp = newlist;
while ((newcontext = strsep(&stringp, "&"))) {
if (strcmp(newcontext, oldcontext) == 0) {
/* This is not the context you're looking for */
stalecontext = '\0';
break;
} else if (strcmp(newcontext, oldcontext)) {
stalecontext = oldcontext;
}
}
if (stalecontext)
ast_context_destroy(ast_context_find(stalecontext), "Skinny");
}
}
| static int codec_ast2skinny | ( | format_t | astcodec | ) | [static] |
Definition at line 1741 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 transmit_connect(), and transmit_startmediatransmission().
{
switch (astcodec) {
case AST_FORMAT_ALAW:
return SKINNY_CODEC_ALAW;
case AST_FORMAT_ULAW:
return SKINNY_CODEC_ULAW;
case AST_FORMAT_G723_1:
return SKINNY_CODEC_G723_1;
case AST_FORMAT_G729A:
return SKINNY_CODEC_G729A;
case AST_FORMAT_G726_AAL2: /* XXX Is this right? */
return SKINNY_CODEC_G726_32;
case AST_FORMAT_H261:
return SKINNY_CODEC_H261;
case AST_FORMAT_H263:
return SKINNY_CODEC_H263;
default:
return 0;
}
}
| static format_t codec_skinny2ast | ( | enum skinny_codecs | skinnycodec | ) | [static] |
Definition at line 1719 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().
{
switch (skinnycodec) {
case SKINNY_CODEC_ALAW:
return AST_FORMAT_ALAW;
case SKINNY_CODEC_ULAW:
return AST_FORMAT_ULAW;
case SKINNY_CODEC_G723_1:
return AST_FORMAT_G723_1;
case SKINNY_CODEC_G729A:
return AST_FORMAT_G729A;
case SKINNY_CODEC_G726_32:
return AST_FORMAT_G726_AAL2; /* XXX Is this right? */
case SKINNY_CODEC_H261:
return AST_FORMAT_H261;
case SKINNY_CODEC_H263:
return AST_FORMAT_H263;
default:
return 0;
}
}
| static char* complete_skinny_devices | ( | const char * | word, |
| int | state | ||
| ) | [static] |
Definition at line 2940 of file chan_skinny.c.
References AST_LIST_TRAVERSE, and ast_strdup.
Referenced by complete_skinny_reset(), and complete_skinny_show_device().
{
struct skinny_device *d;
char *result = NULL;
int wordlen = strlen(word), which = 0;
AST_LIST_TRAVERSE(&devices, d, list) {
if (!strncasecmp(word, d->id, wordlen) && ++which > state)
result = ast_strdup(d->id);
}
return result;
}
| static char* complete_skinny_reset | ( | const char * | line, |
| const char * | word, | ||
| int | pos, | ||
| int | state | ||
| ) | [static] |
Definition at line 2959 of file chan_skinny.c.
References ast_strdup, and complete_skinny_devices().
Referenced by handle_skinny_reset().
{
return (pos == 2 ? ast_strdup(complete_skinny_devices(word, state)) : NULL);
}
| static char* complete_skinny_show_device | ( | const char * | line, |
| const char * | word, | ||
| int | pos, | ||
| int | state | ||
| ) | [static] |
Definition at line 2954 of file chan_skinny.c.
References ast_strdup, and complete_skinny_devices().
Referenced by handle_skinny_show_device().
{
return (pos == 3 ? ast_strdup(complete_skinny_devices(word, state)) : NULL);
}
| static char* complete_skinny_show_line | ( | const char * | line, |
| const char * | word, | ||
| int | pos, | ||
| int | state | ||
| ) | [static] |
Definition at line 2964 of file chan_skinny.c.
References AST_LIST_TRAVERSE, ast_strdup, and skinny_device::lines.
Referenced by handle_skinny_show_line().
{
struct skinny_device *d;
struct skinny_line *l;
char *result = NULL;
int wordlen = strlen(word), which = 0;
if (pos != 3)
return NULL;
AST_LIST_TRAVERSE(&devices, d, list) {
AST_LIST_TRAVERSE(&d->lines, l, list) {
if (!strncasecmp(word, l->name, wordlen) && ++which > state)
result = ast_strdup(l->name);
}
}
return result;
}
| static struct skinny_device* config_device | ( | const char * | dname, |
| struct ast_variable * | v | ||
| ) | [static, read] |
Definition at line 7117 of file chan_skinny.c.
References skinny_device::addr, ast_calloc, ast_copy_string(), AST_LIST_EMPTY, AST_LIST_FIRST, AST_LIST_INSERT_TAIL, AST_LIST_LOCK, AST_LIST_TRAVERSE, AST_LIST_UNLOCK, ast_log(), ast_mutex_init, ast_mutex_lock, ast_mutex_unlock, ast_verb, config_parse_variables(), default_device, DEFAULT_SKINNY_PORT, skinny_line::device, skinnysession::device, skinny_device::lines, skinny_line::lock, skinny_device::lock, LOG_ERROR, LOG_NOTICE, skinny_subchannel::parent, skinny_device::session, skinny_line::sub, TYPE_DEVICE, and update().
Referenced by config_load().
{
struct skinny_device *d, *temp;
struct skinny_line *l, *ltemp;
struct skinny_subchannel *sub;
int update = 0;
ast_log(LOG_NOTICE, "Configuring skinny device %s.\n", dname);
AST_LIST_LOCK(&devices);
AST_LIST_TRAVERSE(&devices, temp, list) {
if (!strcasecmp(dname, temp->name) && temp->prune) {
update = 1;
break;
}
}
if (!(d = ast_calloc(1, sizeof(*d)))) {
ast_verb(1, "Unable to allocate memory for device %s.\n", dname);
AST_LIST_UNLOCK(&devices);
return NULL;
}
memcpy(d, default_device, sizeof(*default_device));
ast_mutex_init(&d->lock);
ast_copy_string(d->name, dname, sizeof(d->name));
AST_LIST_INSERT_TAIL(&devices, d, list);
ast_mutex_lock(&d->lock);
AST_LIST_UNLOCK(&devices);
config_parse_variables(TYPE_DEVICE, d, v);
if (!AST_LIST_FIRST(&d->lines)) {
ast_log(LOG_ERROR, "A Skinny device must have at least one line!\n");
ast_mutex_unlock(&d->lock);
return NULL;
}
if (/*d->addr.sin_addr.s_addr && */!ntohs(d->addr.sin_port)) {
d->addr.sin_port = htons(DEFAULT_SKINNY_PORT);
}
if (skinnyreload){
AST_LIST_LOCK(&devices);
AST_LIST_TRAVERSE(&devices, temp, list) {
if (strcasecmp(d->id, temp->id) || !temp->prune || !temp->session) {
continue;
}
ast_mutex_lock(&d->lock);
d->session = temp->session;
d->session->device = d;
AST_LIST_LOCK(&d->lines);
AST_LIST_TRAVERSE(&d->lines, l, list){
l->device = d;
AST_LIST_LOCK(&temp->lines);
AST_LIST_TRAVERSE(&temp->lines, ltemp, list) {
if (strcasecmp(l->name, ltemp->name)) {
continue;
}
ast_mutex_lock(<emp->lock);
l->instance = ltemp->instance;
l->hookstate = ltemp->hookstate;
if (!AST_LIST_EMPTY(<emp->sub)) {
ast_mutex_lock(&l->lock);
l->sub = ltemp->sub;
AST_LIST_TRAVERSE(&l->sub, sub, list) {
sub->parent = l;
}
ast_mutex_unlock(&l->lock);
}
ast_mutex_unlock(<emp->lock);
}
AST_LIST_UNLOCK(&temp->lines);
}
AST_LIST_UNLOCK(&d->lines);
ast_mutex_unlock(&d->lock);
}
AST_LIST_UNLOCK(&devices);
}
ast_mutex_unlock(&d->lock);
ast_verb(3, "%s config for device '%s'\n", update ? "Updated" : (skinnyreload ? "Reloaded" : "Created"), d->name);
return d;
}
| static struct skinny_line* config_line | ( | const char * | lname, |
| struct ast_variable * | v | ||
| ) | [static, read] |
Definition at line 7059 of file chan_skinny.c.
References skinny_line::all, ast_calloc, 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_LIST_INSERT_TAIL, AST_LIST_LOCK, AST_LIST_TRAVERSE, AST_LIST_UNLOCK, ast_log(), ast_mutex_init, ast_mutex_lock, ast_mutex_unlock, ast_strdupa, ast_strlen_zero(), ast_verb, config_parse_variables(), default_line, skinny_line::lock, LOG_NOTICE, mwi_event_cb(), skinny_line::mwi_event_sub, strsep(), TYPE_LINE, and update().
Referenced by config_load().
{
struct skinny_line *l, *temp;
int update = 0;
ast_log(LOG_NOTICE, "Configuring skinny line %s.\n", lname);
/* We find the old line and remove it just before the new
line is created */
AST_LIST_LOCK(&lines);
AST_LIST_TRAVERSE(&lines, temp, all) {
if (!strcasecmp(lname, temp->name) && temp->prune) {
update = 1;
break;
}
}
if (!(l=ast_calloc(1, sizeof(*l)))) {
ast_verb(1, "Unable to allocate memory for line %s.\n", lname);
AST_LIST_UNLOCK(&lines);
return NULL;
}
memcpy(l, default_line, sizeof(*default_line));
ast_mutex_init(&l->lock);
ast_copy_string(l->name, lname, sizeof(l->name));
AST_LIST_INSERT_TAIL(&lines, l, all);
ast_mutex_lock(&l->lock);
AST_LIST_UNLOCK(&lines);
config_parse_variables(TYPE_LINE, l, v);
if (!ast_strlen_zero(l->mailbox)) {
char *cfg_mailbox, *cfg_context;
cfg_context = cfg_mailbox = ast_strdupa(l->mailbox);
ast_verb(3, "Setting mailbox '%s' on line %s\n", cfg_mailbox, l->name);
strsep(&cfg_context, "@");
if (ast_strlen_zero(cfg_context))
cfg_context = "default";
l->mwi_event_sub = ast_event_subscribe(AST_EVENT_MWI, mwi_event_cb, "skinny MWI subsciption", l,
AST_EVENT_IE_MAILBOX, AST_EVENT_IE_PLTYPE_STR, cfg_mailbox,
AST_EVENT_IE_CONTEXT, AST_EVENT_IE_PLTYPE_STR, cfg_context,
AST_EVENT_IE_NEWMSGS, AST_EVENT_IE_PLTYPE_EXISTS,
AST_EVENT_IE_END);
}
ast_mutex_unlock(&l->lock);
/* We do not want to unlink or free the line yet, it needs
to be available to detect a device reconfig when we load the
devices. Old lines will be pruned after the reload completes */
ast_verb(3, "%s config for line '%s'\n", update ? "Updated" : (skinnyreload ? "Reloaded" : "Created"), l->name);
return l;
}
| static int config_load | ( | void | ) | [static] |
Definition at line 7206 of file chan_skinny.c.
References __ourip, accept_thread(), ahp, ast_category_browse(), ast_config_destroy(), ast_config_load, ast_gethostbyname(), ast_inet_ntoa(), ast_log(), ast_mutex_lock, ast_mutex_unlock, ast_netsock_set_qos(), ast_pthread_create_background, ast_variable_browse(), ast_verb, bindaddr, config_device(), config_line(), config_parse_variables(), CONFIG_STATUS_FILEINVALID, default_capability, default_device, default_line, default_prefs, DEFAULT_SKINNY_BACKLOG, DEFAULT_SKINNY_PORT, errno, global_jbconf, LOG_ERROR, LOG_NOTICE, LOG_WARNING, netlock, qos, TYPE_DEF_DEVICE, TYPE_DEF_LINE, and TYPE_GENERAL.
Referenced by load_module(), and skinny_reload().
{
int on = 1;
struct ast_config *cfg;
char *cat;
int oldport = ntohs(bindaddr.sin_port);
struct ast_flags config_flags = { 0 };
ast_log(LOG_NOTICE, "Configuring skinny from %s\n", config);
if (gethostname(ourhost, sizeof(ourhost))) {
ast_log(LOG_WARNING, "Unable to get hostname, Skinny disabled.\n");
return 0;
}
cfg = ast_config_load(config, config_flags);
/* We *must* have a config file otherwise stop immediately */
if (!cfg || cfg == CONFIG_STATUS_FILEINVALID) {
ast_log(LOG_NOTICE, "Unable to load config %s, Skinny disabled.\n", config);
return -1;
}
memset(&bindaddr, 0, sizeof(bindaddr));
memset(&default_prefs, 0, sizeof(default_prefs));
/* Copy the default jb config over global_jbconf */
memcpy(&global_jbconf, &default_jbconf, sizeof(struct ast_jb_conf));
/* load the general section */
cat = ast_category_browse(cfg, "general");
config_parse_variables(TYPE_GENERAL, NULL, ast_variable_browse(cfg, "general"));
if (ntohl(bindaddr.sin_addr.s_addr)) {
__ourip = bindaddr.sin_addr;
} else {
hp = ast_gethostbyname(ourhost, &ahp);
if (!hp) {
ast_log(LOG_WARNING, "Unable to get our IP address, Skinny disabled\n");
ast_config_destroy(cfg);
return 0;
}
memcpy(&__ourip, hp->h_addr, sizeof(__ourip));
}
if (!ntohs(bindaddr.sin_port)) {
bindaddr.sin_port = htons(DEFAULT_SKINNY_PORT);
}
bindaddr.sin_family = AF_INET;
/* load the lines sections */
default_line->confcapability = default_capability;
default_line->confprefs = default_prefs;
config_parse_variables(TYPE_DEF_LINE, default_line, ast_variable_browse(cfg, "lines"));
cat = ast_category_browse(cfg, "lines");
while (cat && strcasecmp(cat, "general") && strcasecmp(cat, "devices")) {
config_line(cat, ast_variable_browse(cfg, cat));
cat = ast_category_browse(cfg, cat);
}
/* load the devices sections */
default_device->confcapability = default_capability;
default_device->confprefs = default_prefs;
config_parse_variables(TYPE_DEF_DEVICE, default_device, ast_variable_browse(cfg, "devices"));
cat = ast_category_browse(cfg, "devices");
while (cat && strcasecmp(cat, "general") && strcasecmp(cat, "lines")) {
config_device(cat, ast_variable_browse(cfg, cat));
cat = ast_category_browse(cfg, cat);
}
ast_mutex_lock(&netlock);
if ((skinnysock > -1) && (ntohs(bindaddr.sin_port) != oldport)) {
close(skinnysock);
skinnysock = -1;
}
if (skinnysock < 0) {
skinnysock = socket(AF_INET, SOCK_STREAM, 0);
if(setsockopt(skinnysock, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on)) == -1) {
ast_log(LOG_ERROR, "Set Socket Options failed: errno %d, %s\n", errno, strerror(errno));
ast_config_destroy(cfg);
ast_mutex_unlock(&netlock);
return 0;
}
if (skinnysock < 0) {
ast_log(LOG_WARNING, "Unable to create Skinny socket: %s\n", strerror(errno));
} else {
if (bind(skinnysock, (struct sockaddr *)&bindaddr, sizeof(bindaddr)) < 0) {
ast_log(LOG_WARNING, "Failed to bind to %s:%d: %s\n",
ast_inet_ntoa(bindaddr.sin_addr), ntohs(bindaddr.sin_port),
strerror(errno));
close(skinnysock);
skinnysock = -1;
ast_config_destroy(cfg);
ast_mutex_unlock(&netlock);
return 0;
}
if (listen(skinnysock, DEFAULT_SKINNY_BACKLOG)) {
ast_log(LOG_WARNING, "Failed to start listening to %s:%d: %s\n",
ast_inet_ntoa(bindaddr.sin_addr), ntohs(bindaddr.sin_port),
strerror(errno));
close(skinnysock);
skinnysock = -1;
ast_config_destroy(cfg);
ast_mutex_unlock(&netlock);
return 0;
}
ast_verb(2, "Skinny listening on %s:%d\n",
ast_inet_ntoa(bindaddr.sin_addr), ntohs(bindaddr.sin_port));
ast_netsock_set_qos(skinnysock, qos.tos, qos.cos, "Skinny");
ast_pthread_create_background(&accept_t, NULL, accept_thread, NULL);
}
}
ast_mutex_unlock(&netlock);
ast_config_destroy(cfg);
return 1;
}
| static void config_parse_variables | ( | int | type, |
| void * | item, | ||
| struct ast_variable * | vptr | ||
| ) | [static] |
Definition at line 6665 of file chan_skinny.c.
References add_var(), ahp, skinny_line::all, ast_append_ha(), ast_callerid_split(), ast_calloc, ast_cdr_amaflags2int(), ast_context_find_or_create(), ast_copy_string(), ast_get_group(), ast_get_ip(), ast_gethostbyname(), ast_jb_read_conf(), AST_LIST_FIRST, AST_LIST_INSERT_HEAD, AST_LIST_TRAVERSE, ast_log(), AST_MAX_CONTEXT, ast_mutex_init, ast_parse_allow_disallow(), ast_sockaddr_to_sin, ast_str2cos(), ast_str2tos(), ast_strlen_zero(), ast_true(), bindaddr, CDEV, CDEV_OPTS, cleanup_stale_contexts(), CLINE, CLINE_OPTS, context, skinny_speeddial::context, DEFAULT_AUTH_LIMIT, DEFAULT_AUTH_TIMEOUT, default_prefs, exten, skinny_speeddial::exten, global_jbconf, skinny_speeddial::instance, skinny_speeddial::isHint, skinny_speeddial::label, ast_variable::lineno, skinny_device::lines, skinny_speeddial::lock, skinny_addon::lock, LOG_WARNING, ast_variable::name, ast_variable::next, skinny_speeddial::parent, qos, S_OR, ast_sockaddr::ss, strsep(), skinny_addon::type, TYPE_DEF_DEVICE, TYPE_DEF_LINE, TYPE_DEVICE, TYPE_GENERAL, TYPE_LINE, and ast_variable::value.
Referenced by config_device(), config_line(), and config_load().
{
struct ast_variable *v;
int lineInstance = 1;
int speeddialInstance = 1;
while(vptr) {
v = vptr;
vptr = vptr->next;
if (type & (TYPE_GENERAL)) {
char newcontexts[AST_MAX_CONTEXT];
char oldcontexts[AST_MAX_CONTEXT];
char *stringp, *context, *oldregcontext;
if (!ast_jb_read_conf(&global_jbconf, v->name, v->value)) {
v = v->next;
continue;
}
if (!strcasecmp(v->name, "bindaddr")) {
if (!(hp = ast_gethostbyname(v->value, &ahp))) {
ast_log(LOG_WARNING, "Invalid address: %s\n", v->value);
} else {
memcpy(&bindaddr.sin_addr, hp->h_addr, sizeof(bindaddr.sin_addr));
}
continue;
} else if (!strcasecmp(v->name, "keepalive")) {
keep_alive = atoi(v->value);
continue;
} else if (!strcasecmp(v->name, "authtimeout")) {
int timeout = atoi(v->value);
if (timeout < 1) {
ast_log(LOG_WARNING, "Invalid authtimeout value '%s', using default value\n", v->value);
auth_timeout = DEFAULT_AUTH_TIMEOUT;
} else {
auth_timeout = timeout;
}
continue;
} else if (!strcasecmp(v->name, "authlimit")) {
int limit = atoi(v->value);
if (limit < 1) {
ast_log(LOG_WARNING, "Invalid authlimit value '%s', using default value\n", v->value);
auth_limit = DEFAULT_AUTH_LIMIT;
} else {
auth_limit = limit;
}
continue;
} else if (!strcasecmp(v->name, "regcontext")) {
ast_copy_string(newcontexts, v->value, sizeof(newcontexts));
stringp = newcontexts;
/* Initialize copy of current global_regcontext for later use in removing stale contexts */
ast_copy_string(oldcontexts, regcontext, sizeof(oldcontexts));
oldregcontext = oldcontexts;
/* Let's remove any contexts that are no longer defined in regcontext */
cleanup_stale_contexts(stringp, oldregcontext);
/* Create contexts if they don't exist already */
while ((context = strsep(&stringp, "&"))) {
ast_copy_string(used_context, context, sizeof(used_context));
ast_context_find_or_create(NULL, NULL, context, "Skinny");
}
ast_copy_string(regcontext, v->value, sizeof(regcontext));
continue;
} else if (!strcasecmp(v->name, "dateformat")) {
memcpy(date_format, v->value, sizeof(date_format));
continue;
} else if (!strcasecmp(v->name, "tos")) {
if (ast_str2tos(v->value, &qos.tos))
ast_log(LOG_WARNING, "Invalid tos value at line %d, refer to QoS documentation\n", v->lineno);
continue;
} else if (!strcasecmp(v->name, "tos_audio")) {
if (ast_str2tos(v->value, &qos.tos_audio))
ast_log(LOG_WARNING, "Invalid tos_audio value at line %d, refer to QoS documentation\n", v->lineno);
continue;
} else if (!strcasecmp(v->name, "tos_video")) {
if (ast_str2tos(v->value, &qos.tos_video))
ast_log(LOG_WARNING, "Invalid tos_video value at line %d, refer to QoS documentation\n", v->lineno);
continue;
} else if (!strcasecmp(v->name, "cos")) {
if (ast_str2cos(v->value, &qos.cos))
ast_log(LOG_WARNING, "Invalid cos value at line %d, refer to QoS documentation\n", v->lineno);
continue;
} else if (!strcasecmp(v->name, "cos_audio")) {
if (ast_str2cos(v->value, &qos.cos_audio))
ast_log(LOG_WARNING, "Invalid cos_audio value at line %d, refer to QoS documentation\n", v->lineno);
continue;
} else if (!strcasecmp(v->name, "cos_video")) {
if (ast_str2cos(v->value, &qos.cos_video))
ast_log(LOG_WARNING, "Invalid cos_video value at line %d, refer to QoS documentation\n", v->lineno);
continue;
} else if (!strcasecmp(v->name, "bindport")) {
if (sscanf(v->value, "%5d", &ourport) == 1) {
bindaddr.sin_port = htons(ourport);
} else {
ast_log(LOG_WARNING, "Invalid bindport '%s' at line %d of %s\n", v->value, v->lineno, config);
}
continue;
} else if (!strcasecmp(v->name, "allow")) {
ast_parse_allow_disallow(&default_prefs, &default_capability, v->value, 1);
continue;
} else if (!strcasecmp(v->name, "disallow")) {
ast_parse_allow_disallow(&default_prefs, &default_capability, v->value, 0);
continue;
}
}
if (!strcasecmp(v->name, "transfer")) {
if (type & (TYPE_DEF_DEVICE | TYPE_DEVICE)) {
CDEV_OPTS->transfer = ast_true(v->value);
continue;
} else if (type & (TYPE_DEF_LINE | TYPE_LINE)) {
CLINE_OPTS->transfer = ast_true(v->value);
continue;
}
} else if (!strcasecmp(v->name, "callwaiting")) {
if (type & (TYPE_DEF_DEVICE | TYPE_DEVICE)) {
CDEV_OPTS->callwaiting = ast_true(v->value);
continue;
} else if (type & (TYPE_DEF_LINE | TYPE_LINE)) {
CLINE_OPTS->callwaiting = ast_true(v->value);
continue;
}
} else if (!strcasecmp(v->name, "directmedia") || !strcasecmp(v->name, "canreinvite")) {
if (type & (TYPE_DEF_LINE | TYPE_LINE)) {
CLINE_OPTS->directmedia = ast_true(v->value);
continue;
}
} else if (!strcasecmp(v->name, "nat")) {
if (type & (TYPE_DEF_LINE | TYPE_LINE)) {
CLINE_OPTS->nat = ast_true(v->value);
continue;
}
} else if (!strcasecmp(v->name, "context")) {
if (type & (TYPE_DEF_LINE | TYPE_LINE)) {
ast_copy_string(CLINE_OPTS->context, v->value, sizeof(CLINE_OPTS->context));
continue;
}
}else if (!strcasecmp(v->name, "vmexten")) {
if (type & (TYPE_DEF_DEVICE | TYPE_DEVICE)) {
ast_copy_string(CDEV_OPTS->vmexten, v->value, sizeof(CDEV_OPTS->vmexten));
continue;
} else if (type & (TYPE_DEF_LINE | TYPE_LINE)) {
ast_copy_string(CLINE_OPTS->vmexten, v->value, sizeof(CLINE_OPTS->vmexten));
continue;
}
} else if (!strcasecmp(v->name, "mwiblink")) {
if (type & (TYPE_DEF_DEVICE | TYPE_DEVICE)) {
CDEV_OPTS->mwiblink = ast_true(v->value);
continue;
} else if (type & (TYPE_DEF_LINE | TYPE_LINE)) {
CLINE_OPTS->mwiblink = ast_true(v->value);
continue;
}
} else if (!strcasecmp(v->name, "linelabel")) {
if (type & (TYPE_DEF_LINE | TYPE_LINE)) {
ast_copy_string(CLINE_OPTS->label, v->value, sizeof(CLINE_OPTS->label));
continue;
}
} else if (!strcasecmp(v->name, "callerid")) {
if (type & (TYPE_DEF_LINE | TYPE_LINE)) {
if (!strcasecmp(v->value, "asreceived")) {
CLINE_OPTS->cid_num[0] = '\0';
CLINE_OPTS->cid_name[0] = '\0';
} else {
ast_callerid_split(v->value, CLINE_OPTS->cid_name, sizeof(CLINE_OPTS->cid_name), CLINE_OPTS->cid_num, sizeof(CLINE_OPTS->cid_num));
}
continue;
}
} else if (!strcasecmp(v->name, "amaflags")) {
if (type & (TYPE_DEF_LINE | TYPE_LINE)) {
int tempamaflags = ast_cdr_amaflags2int(v->value);
if (tempamaflags < 0) {
ast_log(LOG_WARNING, "Invalid AMA flags: %s at line %d\n", v->value, v->lineno);
} else {
CLINE_OPTS->amaflags = tempamaflags;
}
continue;
}
} else if (!strcasecmp(v->name, "regexten")) {
if (type & (TYPE_DEF_LINE | TYPE_LINE)) {
ast_copy_string(CLINE_OPTS->regexten, v->value, sizeof(CLINE_OPTS->regexten));
continue;
}
} else if (!strcasecmp(v->name, "language")) {
if (type & (TYPE_DEF_LINE | TYPE_LINE)) {
ast_copy_string(CLINE_OPTS->language, v->value, sizeof(CLINE_OPTS->language));
continue;
}
} else if (!strcasecmp(v->name, "accountcode")) {
if (type & (TYPE_DEF_LINE | TYPE_LINE)) {
ast_copy_string(CLINE_OPTS->accountcode, v->value, sizeof(CLINE_OPTS->accountcode));
continue;
}
} else if (!strcasecmp(v->name, "mohinterpret") || !strcasecmp(v->name, "musiconhold")) {
if (type & (TYPE_DEF_LINE | TYPE_LINE)) {
ast_copy_string(CLINE_OPTS->mohinterpret, v->value, sizeof(CLINE_OPTS->mohinterpret));
continue;
}
} else if (!strcasecmp(v->name, "mohsuggest")) {
if (type & (TYPE_DEF_LINE | TYPE_LINE)) {
ast_copy_string(CLINE_OPTS->mohsuggest, v->value, sizeof(CLINE_OPTS->mohsuggest));
continue;
}
} else if (!strcasecmp(v->name, "callgroup")) {
if (type & (TYPE_DEF_LINE | TYPE_LINE)) {
CLINE_OPTS->callgroup = ast_get_group(v->value);
continue;
}
} else if (!strcasecmp(v->name, "pickupgroup")) {
if (type & (TYPE_DEF_LINE | TYPE_LINE)) {
CLINE_OPTS->pickupgroup = ast_get_group(v->value);
continue;
}
} else if (!strcasecmp(v->name, "immediate")) {
if (type & (TYPE_DEF_DEVICE | TYPE_DEVICE | TYPE_DEF_LINE | TYPE_LINE)) {
CLINE_OPTS->immediate = ast_true(v->value);
continue;
}
} else if (!strcasecmp(v->name, "cancallforward")) {
if (type & (TYPE_DEF_LINE | TYPE_LINE)) {
CLINE_OPTS->cancallforward = ast_true(v->value);
continue;
}
} else if (!strcasecmp(v->name, "mailbox")) {
if (type & (TYPE_DEF_LINE | TYPE_LINE)) {
ast_copy_string(CLINE_OPTS->mailbox, v->value, sizeof(CLINE_OPTS->mailbox));
continue;
}
} else if ( !strcasecmp(v->name, "parkinglot")) {
if (type & (TYPE_DEF_LINE | TYPE_LINE)) {
ast_copy_string(CLINE_OPTS->parkinglot, v->value, sizeof(CLINE_OPTS->parkinglot));
continue;
}
} else if (!strcasecmp(v->name, "hasvoicemail")) {
if (type & (TYPE_LINE)) {
if (ast_true(v->value) && ast_strlen_zero(CLINE->mailbox)) {
ast_copy_string(CLINE->mailbox, CLINE->name, sizeof(CLINE->mailbox));
}
continue;
}
} else if (!strcasecmp(v->name, "callreturn")) {
if (type & (TYPE_DEF_LINE | TYPE_LINE)) {
CLINE_OPTS->callreturn = ast_true(v->value);
continue;
}
} else if (!strcasecmp(v->name, "threewaycalling")) {
if (type & (TYPE_DEF_LINE | TYPE_LINE)) {
CLINE_OPTS->threewaycalling = ast_true(v->value);
continue;
}
} else if (!strcasecmp(v->name, "setvar")) {
if (type & (TYPE_LINE)) {
CLINE->chanvars = add_var(v->value, CLINE->chanvars);
continue;
}
} else if (!strcasecmp(v->name, "earlyrtp")) {
if (type & (TYPE_DEF_DEVICE | TYPE_DEVICE)) {
CDEV_OPTS->earlyrtp = ast_true(v->value);
continue;
}
} else if (!strcasecmp(v->name, "host")) {
if (type & (TYPE_DEVICE)) {
struct ast_sockaddr CDEV_addr_tmp;
CDEV_addr_tmp.ss.ss_family = AF_INET;
if (ast_get_ip(&CDEV_addr_tmp, v->value)) {
ast_log(LOG_WARNING, "Bad IP '%s' at line %d.\n", v->value, v->lineno);
}
ast_sockaddr_to_sin(&CDEV_addr_tmp,
&CDEV->addr);
continue;
}
} else if (!strcasecmp(v->name, "port")) {
if (type & (TYPE_DEF_DEVICE)) {
CDEV->addr.sin_port = htons(atoi(v->value));
continue;
}
} else if (!strcasecmp(v->name, "device")) {
if (type & (TYPE_DEVICE)) {
ast_copy_string(CDEV_OPTS->id, v->value, sizeof(CDEV_OPTS->id));
continue;
}
} else if (!strcasecmp(v->name, "permit") || !strcasecmp(v->name, "deny")) {
if (type & (TYPE_DEVICE)) {
CDEV->ha = ast_append_ha(v->name, v->value, CDEV->ha, NULL);
continue;
}
} else if (!strcasecmp(v->name, "allow")) {
if (type & (TYPE_DEF_DEVICE | TYPE_DEVICE)) {
ast_parse_allow_disallow(&CDEV_OPTS->confprefs, &CDEV_OPTS->confcapability, v->value, 1);
continue;
}
if (type & (TYPE_DEF_LINE | TYPE_LINE)) {
ast_parse_allow_disallow(&CLINE_OPTS->confprefs, &CLINE_OPTS->confcapability, v->value, 1);
continue;
}
} else if (!strcasecmp(v->name, "disallow")) {
if (type & (TYPE_DEF_DEVICE | TYPE_DEVICE)) {
ast_parse_allow_disallow(&CDEV_OPTS->confprefs, &CDEV_OPTS->confcapability, v->value, 0);
continue;
}
if (type & (TYPE_DEF_LINE | TYPE_LINE)) {
ast_parse_allow_disallow(&CLINE_OPTS->confprefs, &CLINE_OPTS->confcapability, v->value, 0);
continue;
}
} else if (!strcasecmp(v->name, "version")) {
if (type & (TYPE_DEF_DEVICE | TYPE_DEVICE)) {
ast_copy_string(CDEV_OPTS->version_id, v->value, sizeof(CDEV_OPTS->version_id));
continue;
}
} else if (!strcasecmp(v->name, "line")) {
if (type & (TYPE_DEVICE)) {
struct skinny_line *l;
AST_LIST_TRAVERSE(&lines, l, all) {
if (!strcasecmp(v->value, l->name) && !l->prune) {
/* FIXME: temp solution about line conflicts */
struct skinny_device *d;
struct skinny_line *l2;
int lineinuse = 0;
AST_LIST_TRAVERSE(&devices, d, list) {
AST_LIST_TRAVERSE(&d->lines, l2, list) {
if (l2 == l && strcasecmp(d->id, CDEV->id)) {
ast_log(LOG_WARNING, "Line %s already used by %s. Not connecting to %s.\n", l->name, d->name, CDEV->name);
lineinuse++;
}
}
}
if (!lineinuse) {
if (!AST_LIST_FIRST(&CDEV->lines)) {
CDEV->activeline = l;
}
lineInstance++;
AST_LIST_INSERT_HEAD(&CDEV->lines, l, list);
}
break;
}
}
continue;
}
} else if (!strcasecmp(v->name, "speeddial")) {
if (type & (TYPE_DEVICE)) {
struct skinny_speeddial *sd;
if (!(sd = ast_calloc(1, sizeof(*sd)))) {
ast_log(LOG_WARNING, "Unable to allocate memory for speeddial %s. Ignoring speeddial.\n", v->name);
continue;
} else {
char buf[256];
char *stringp = buf, *exten, *context, *label;
ast_copy_string(buf, v->value, sizeof(buf));
exten = strsep(&stringp, ",");
if ((context = strchr(exten, '@'))) {
*context++ = '\0';
}
label = stringp;
ast_mutex_init(&sd->lock);
ast_copy_string(sd->exten, exten, sizeof(sd->exten));
if (!ast_strlen_zero(context)) {
sd->isHint = 1;
sd->instance = lineInstance++;
ast_copy_string(sd->context, context, sizeof(sd->context));
} else {
sd->isHint = 0;
sd->instance = speeddialInstance++;
sd->context[0] = '\0';
}
ast_copy_string(sd->label, S_OR(label, exten), sizeof(sd->label));
sd->parent = CDEV;
AST_LIST_INSERT_HEAD(&CDEV->speeddials, sd, list);
}
continue;
}
} else if (!strcasecmp(v->name, "addon")) {
if (type & (TYPE_DEVICE)) {
struct skinny_addon *a;
if (!(a = ast_calloc(1, sizeof(*a)))) {
ast_log(LOG_WARNING, "Unable to allocate memory for addon %s. Ignoring addon.\n", v->name);
continue;
} else {
ast_mutex_init(&a->lock);
ast_copy_string(a->type, v->value, sizeof(a->type));
AST_LIST_INSERT_HEAD(&CDEV->addons, a, list);
}
continue;
}
} else {
ast_log(LOG_WARNING, "Don't know keyword '%s' at line %d\n", v->name, v->lineno);
continue;
}
ast_log(LOG_WARNING, "Invalid category used: %s at line %d\n", v->name, v->lineno);
}
}
| static char* control2str | ( | int | ind | ) | [static] |
Definition at line 4249 of file chan_skinny.c.
References AST_CONTROL_ANSWER, AST_CONTROL_BUSY, AST_CONTROL_CONGESTION, AST_CONTROL_CONNECTED_LINE, AST_CONTROL_FLASH, AST_CONTROL_HANGUP, AST_CONTROL_HOLD, AST_CONTROL_INCOMPLETE, AST_CONTROL_OFFHOOK, AST_CONTROL_OPTION, AST_CONTROL_PROCEEDING, AST_CONTROL_PROGRESS, AST_CONTROL_RADIO_KEY, AST_CONTROL_RADIO_UNKEY, AST_CONTROL_REDIRECTING, AST_CONTROL_RING, AST_CONTROL_RINGING, AST_CONTROL_SRCUPDATE, AST_CONTROL_TAKEOFFHOOK, AST_CONTROL_UNHOLD, AST_CONTROL_WINK, ast_threadstorage_get(), CONTROL2STR_BUFSIZE, and control2str_threadbuf.
Referenced by skinny_indicate().
{
char *tmp;
switch (ind) {
case AST_CONTROL_HANGUP:
return "Other end has hungup";
case AST_CONTROL_RING:
return "Local ring";
case AST_CONTROL_RINGING:
return "Remote end is ringing";
case AST_CONTROL_ANSWER:
return "Remote end has answered";
case AST_CONTROL_BUSY:
return "Remote end is busy";
case AST_CONTROL_TAKEOFFHOOK:
return "Make it go off hook";
case AST_CONTROL_OFFHOOK:
return "Line is off hook";
case AST_CONTROL_CONGESTION:
return "Congestion (circuits busy)";
case AST_CONTROL_FLASH:
return "Flash hook";
case AST_CONTROL_WINK:
return "Wink";
case AST_CONTROL_OPTION:
return "Set a low-level option";
case AST_CONTROL_RADIO_KEY:
return "Key Radio";
case AST_CONTROL_RADIO_UNKEY:
return "Un-Key Radio";
case AST_CONTROL_PROGRESS:
return "Remote end is making Progress";
case AST_CONTROL_PROCEEDING:
return "Remote end is proceeding";
case AST_CONTROL_HOLD:
return "Hold";
case AST_CONTROL_UNHOLD:
return "Unhold";
case AST_CONTROL_SRCUPDATE:
return "Media Source Update";
case AST_CONTROL_CONNECTED_LINE:
return "Connected Line";
case AST_CONTROL_REDIRECTING:
return "Redirecting";
case AST_CONTROL_INCOMPLETE:
return "Incomplete";
case -1:
return "Stop tone";
default:
if (!(tmp = ast_threadstorage_get(&control2str_threadbuf, CONTROL2STR_BUFSIZE)))
return "Unknown";
snprintf(tmp, CONTROL2STR_BUFSIZE, "UNKNOWN-%d", ind);
return tmp;
}
}
| static void delete_devices | ( | void | ) | [static] |
Definition at line 7320 of file chan_skinny.c.
References skinny_device::addons, AST_LIST_LOCK, AST_LIST_REMOVE, AST_LIST_REMOVE_HEAD, AST_LIST_UNLOCK, free, skinny_device::lines, and skinny_device::speeddials.
Referenced by unload_module().
{
struct skinny_device *d;
struct skinny_line *l;
struct skinny_speeddial *sd;
struct skinny_addon *a;
AST_LIST_LOCK(&devices);
AST_LIST_LOCK(&lines);
/* Delete all devices */
while ((d = AST_LIST_REMOVE_HEAD(&devices, list))) {
/* Delete all lines for this device */
while ((l = AST_LIST_REMOVE_HEAD(&d->lines, list))) {
AST_LIST_REMOVE(&lines, l, all);
free(l);
}
/* Delete all speeddials for this device */
while ((sd = AST_LIST_REMOVE_HEAD(&d->speeddials, list))) {
free(sd);
}
/* Delete all addons for this device */
while ((a = AST_LIST_REMOVE_HEAD(&d->addons, list))) {
free(a);
}
free(d);
}
AST_LIST_UNLOCK(&lines);
AST_LIST_UNLOCK(&devices);
}
| static void destroy_session | ( | struct skinnysession * | s | ) | [static] |
Definition at line 6316 of file chan_skinny.c.
References ast_atomic_fetchadd_int(), 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::device, skinnysession::fd, skinnysession::lock, and LOG_WARNING.
Referenced by accept_thread(), and skinny_session().
{
struct skinnysession *cur;
AST_LIST_LOCK(&sessions);
AST_LIST_TRAVERSE_SAFE_BEGIN(&sessions, cur, list) {
if (cur == s) {
AST_LIST_REMOVE_CURRENT(list);
if (s->fd > -1)
close(s->fd);
if (!s->device)
ast_atomic_fetchadd_int(&unauth_sessions, -1);
ast_mutex_destroy(&s->lock);
ast_free(s);
} else {
ast_log(LOG_WARNING, "Trying to delete nonexistent session %p?\n", s);
}
}
AST_LIST_TRAVERSE_SAFE_END
AST_LIST_UNLOCK(&sessions);
}
| static char* device2str | ( | int | type | ) | [static] |
Definition at line 3029 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 _skinny_show_device(), and _skinny_show_devices().
{
char *tmp;
switch (type) {
case SKINNY_DEVICE_NONE:
return "No Device";
case SKINNY_DEVICE_30SPPLUS:
return "30SP Plus";
case SKINNY_DEVICE_12SPPLUS:
return "12SP Plus";
case SKINNY_DEVICE_12SP:
return "12SP";
case SKINNY_DEVICE_12:
return "12";
case SKINNY_DEVICE_30VIP:
return "30VIP";
case SKINNY_DEVICE_7910:
return "7910";
case SKINNY_DEVICE_7960:
return "7960";
case SKINNY_DEVICE_7940:
return "7940";
case SKINNY_DEVICE_7935:
return "7935";
case SKINNY_DEVICE_ATA186:
return "ATA186";
case SKINNY_DEVICE_7941:
return "7941";
case SKINNY_DEVICE_7971:
return "7971";
case SKINNY_DEVICE_7914:
return "7914";
case SKINNY_DEVICE_7985:
return "7985";
case SKINNY_DEVICE_7911:
return "7911";
case SKINNY_DEVICE_7961GE:
return "7961GE";
case SKINNY_DEVICE_7941GE:
return "7941GE";
case SKINNY_DEVICE_7931:
return "7931";
case SKINNY_DEVICE_7921:
return "7921";
case SKINNY_DEVICE_7906:
return "7906";
case SKINNY_DEVICE_7962:
return "7962";
case SKINNY_DEVICE_7937:
return "7937";
case SKINNY_DEVICE_7942:
return "7942";
case SKINNY_DEVICE_7945:
return "7945";
case SKINNY_DEVICE_7965:
return "7965";
case SKINNY_DEVICE_7975:
return "7975";
case SKINNY_DEVICE_7905:
return "7905";
case SKINNY_DEVICE_7920:
return "7920";
case SKINNY_DEVICE_7970:
return "7970";
case SKINNY_DEVICE_7912:
return "7912";
case SKINNY_DEVICE_7902:
return "7902";
case SKINNY_DEVICE_CIPC:
return "IP Communicator";
case SKINNY_DEVICE_7961:
return "7961";
case SKINNY_DEVICE_7936:
return "7936";
case SKINNY_DEVICE_SCCPGATEWAY_AN:
return "SCCPGATEWAY_AN";
case SKINNY_DEVICE_SCCPGATEWAY_BRI:
return "SCCPGATEWAY_BRI";
case SKINNY_DEVICE_UNKNOWN:
return "Unknown";
default:
if (!(tmp = ast_threadstorage_get(&device2str_threadbuf, DEVICE2STR_BUFSIZE)))
return "Unknown";
snprintf(tmp, DEVICE2STR_BUFSIZE, "UNKNOWN-%d", type);
return tmp;
}
}
| static void* do_monitor | ( | void * | data | ) | [static] |
Definition at line 6558 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().
{
int res;
/* This thread monitors all the interfaces which are not yet in use
(and thus do not have a separate thread) indefinitely */
/* From here on out, we die whenever asked */
for(;;) {
pthread_testcancel();
/* Wait for sched or io */
res = ast_sched_wait(sched);
if ((res < 0) || (res > 1000)) {
res = 1000;
}
res = ast_io_wait(io, res);
ast_mutex_lock(&monlock);
if (res >= 0) {
ast_sched_runq(sched);
}
ast_mutex_unlock(&monlock);
}
/* Never reached */
return NULL;
}
| static struct skinny_line* find_line_by_instance | ( | struct skinny_device * | d, |
| int | instance | ||
| ) | [static, read] |
Definition at line 1565 of file chan_skinny.c.
References AST_LIST_TRAVERSE, ast_log(), skinny_device::lines, and LOG_WARNING.
Referenced by find_subchannel_by_instance_reference(), handle_enbloc_call_message(), handle_message(), handle_offhook_message(), handle_soft_key_event_message(), and handle_stimulus_message().
{
struct skinny_line *l;
/*Dialing from on hook or on a 7920 uses instance 0 in requests
but we need to start looking at instance 1 */
if (!instance)
instance = 1;
AST_LIST_TRAVERSE(&d->lines, l, list){
if (l->instance == instance)
break;
}
if (!l) {
ast_log(LOG_WARNING, "Could not find line with instance '%d' on device '%s'\n", instance, d->name);
}
return l;
}
| static struct skinny_line* find_line_by_name | ( | const char * | dest | ) | [static, read] |
Definition at line 1586 of file chan_skinny.c.
References ast_copy_string(), AST_LIST_LOCK, AST_LIST_TRAVERSE, AST_LIST_UNLOCK, ast_strlen_zero(), ast_verb, and skinny_device::lines.
Referenced by skinny_devicestate(), and skinny_request().
{
struct skinny_line *l;
struct skinny_line *tmpl = NULL;
struct skinny_device *d;
char line[256];
char *at;
char *device;
int checkdevice = 0;
ast_copy_string(line, dest, sizeof(line));
at = strchr(line, '@');
if (at)
*at++ = '\0';
device = at;
if (!ast_strlen_zero(device))
checkdevice = 1;
AST_LIST_LOCK(&devices);
AST_LIST_TRAVERSE(&devices, d, list){
if (checkdevice && tmpl)
break;
else if (!checkdevice) {
/* This is a match, since we're checking for line on every device. */
} else if (!strcasecmp(d->name, device)) {
if (skinnydebug)
ast_verb(2, "Found device: %s\n", d->name);
} else
continue;
/* Found the device (or we don't care which device) */
AST_LIST_TRAVERSE(&d->lines, l, list){
/* Search for the right line */
if (!strcasecmp(l->name, line)) {
if (tmpl) {
ast_verb(2, "Ambiguous line name: %s\n", line);
AST_LIST_UNLOCK(&devices);
return NULL;
} else
tmpl = l;
}
}
}
AST_LIST_UNLOCK(&devices);
return tmpl;
}
| static struct skinny_speeddial* find_speeddial_by_instance | ( | struct skinny_device * | d, |
| int | instance, | ||
| int | isHint | ||
| ) | [static, read] |
Definition at line 1704 of file chan_skinny.c.
References AST_LIST_TRAVERSE, ast_log(), skinny_speeddial::instance, skinny_speeddial::isHint, LOG_WARNING, and skinny_device::speeddials.
Referenced by handle_message(), and handle_stimulus_message().
{
struct skinny_speeddial *sd;
AST_LIST_TRAVERSE(&d->speeddials, sd, list) {
if (sd->isHint == isHint && sd->instance == instance)
break;
}
if (!sd) {
ast_log(LOG_WARNING, "Could not find speeddial with instance '%d' on device '%s'\n", instance, d->name);
}
return sd;
}
| static struct skinny_subchannel* find_subchannel_by_instance_reference | ( | struct skinny_device * | d, |
| int | instance, | ||
| int | reference | ||
| ) | [static, read] |
Definition at line 1653 of file chan_skinny.c.
References AST_LIST_FIRST, AST_LIST_TRAVERSE, ast_log(), skinny_subchannel::callid, find_line_by_instance(), LOG_WARNING, 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().
{
struct skinny_line *l = find_line_by_instance(d, instance);
struct skinny_subchannel *sub;
if (!l) {
return NULL;
}
/* 7920 phones set call reference to 0, so use the first
sub-channel on the list.
This MIGHT need more love to be right */
if (!reference)
sub = AST_LIST_FIRST(&l->sub);
else {
AST_LIST_TRAVERSE(&l->sub, sub, list) {
if (sub->callid == reference)
break;
}
}
if (!sub) {
ast_log(LOG_WARNING, "Could not find subchannel with reference '%d' on '%s'\n", reference, d->name);
}
return sub;
}
| static struct skinny_subchannel* find_subchannel_by_reference | ( | struct skinny_device * | d, |
| int | reference | ||
| ) | [static, read] |
Definition at line 1680 of file chan_skinny.c.
References AST_LIST_TRAVERSE, ast_log(), skinny_subchannel::callid, skinny_device::lines, LOG_WARNING, and skinny_line::sub.
Referenced by handle_open_receive_channel_ack_message().
{
struct skinny_line *l;
struct skinny_subchannel *sub = NULL;
AST_LIST_TRAVERSE(&d->lines, l, list){
AST_LIST_TRAVERSE(&l->sub, sub, list){
if (sub->callid == reference)
break;
}
if (sub)
break;
}
if (!l) {
ast_log(LOG_WARNING, "Could not find any lines that contained a subchannel with reference '%d' on device '%s'\n", reference, d->name);
} else {
if (!sub) {
ast_log(LOG_WARNING, "Could not find subchannel with reference '%d' on '%s@%s'\n", reference, l->name, d->name);
}
}
return sub;
}
| static void* get_button_template | ( | struct skinnysession * | s, |
| struct button_definition_template * | btn | ||
| ) | [static] |
Definition at line 1414 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, and skinny_addon::type.
Referenced by handle_button_template_req_message().
{
struct skinny_device *d = s->device;
struct skinny_addon *a;
int i;
switch (d->type) {
case SKINNY_DEVICE_30SPPLUS:
case SKINNY_DEVICE_30VIP:
/* 13 rows, 2 columns */
for (i = 0; i < 4; i++)
(btn++)->buttonDefinition = BT_CUST_LINE;
(btn++)->buttonDefinition = BT_REDIAL;
(btn++)->buttonDefinition = BT_VOICEMAIL;
(btn++)->buttonDefinition = BT_CALLPARK;
(btn++)->buttonDefinition = BT_FORWARDALL;
(btn++)->buttonDefinition = BT_CONFERENCE;
for (i = 0; i < 4; i++)
(btn++)->buttonDefinition = BT_NONE;
for (i = 0; i < 13; i++)
(btn++)->buttonDefinition = BT_SPEEDDIAL;
break;
case SKINNY_DEVICE_12SPPLUS:
case SKINNY_DEVICE_12SP:
case SKINNY_DEVICE_12:
/* 6 rows, 2 columns */
for (i = 0; i < 2; i++)
(btn++)->buttonDefinition = BT_CUST_LINE;
for (i = 0; i < 4; i++)
(btn++)->buttonDefinition = BT_SPEEDDIAL;
(btn++)->buttonDefinition = BT_HOLD;
(btn++)->buttonDefinition = BT_REDIAL;
(btn++)->buttonDefinition = BT_TRANSFER;
(btn++)->buttonDefinition = BT_FORWARDALL;
(btn++)->buttonDefinition = BT_CALLPARK;
(btn++)->buttonDefinition = BT_VOICEMAIL;
break;
case SKINNY_DEVICE_7910:
(btn++)->buttonDefinition = BT_LINE;
(btn++)->buttonDefinition = BT_HOLD;
(btn++)->buttonDefinition = BT_TRANSFER;
(btn++)->buttonDefinition = BT_DISPLAY;
(btn++)->buttonDefinition = BT_VOICEMAIL;
(btn++)->buttonDefinition = BT_CONFERENCE;
(btn++)->buttonDefinition = BT_FORWARDALL;
for (i = 0; i < 2; i++)
(btn++)->buttonDefinition = BT_SPEEDDIAL;
(btn++)->buttonDefinition = BT_REDIAL;
break;
case SKINNY_DEVICE_7960:
case SKINNY_DEVICE_7961:
case SKINNY_DEVICE_7961GE:
case SKINNY_DEVICE_7962:
case SKINNY_DEVICE_7965:
for (i = 0; i < 6; i++)
(btn++)->buttonDefinition = BT_CUST_LINESPEEDDIAL;
break;
case SKINNY_DEVICE_7940:
case SKINNY_DEVICE_7941:
case SKINNY_DEVICE_7941GE:
case SKINNY_DEVICE_7942:
case SKINNY_DEVICE_7945:
for (i = 0; i < 2; i++)
(btn++)->buttonDefinition = BT_CUST_LINESPEEDDIAL;
break;
case SKINNY_DEVICE_7935:
case SKINNY_DEVICE_7936:
for (i = 0; i < 2; i++)
(btn++)->buttonDefinition = BT_LINE;
break;
case SKINNY_DEVICE_ATA186:
(btn++)->buttonDefinition = BT_LINE;
break;
case SKINNY_DEVICE_7970:
case SKINNY_DEVICE_7971:
case SKINNY_DEVICE_7975:
case SKINNY_DEVICE_CIPC:
for (i = 0; i < 8; i++)
(btn++)->buttonDefinition = BT_CUST_LINESPEEDDIAL;
break;
case SKINNY_DEVICE_7985:
/* XXX I have no idea what the buttons look like on these. */
ast_log(LOG_WARNING, "Unsupported device type '%d (7985)' found.\n", d->type);
break;
case SKINNY_DEVICE_7912:
case SKINNY_DEVICE_7911:
case SKINNY_DEVICE_7905:
(btn++)->buttonDefinition = BT_LINE;
(btn++)->buttonDefinition = BT_HOLD;
break;
case SKINNY_DEVICE_7920:
/* XXX I don't know if this is right. */
for (i = 0; i < 4; i++)
(btn++)->buttonDefinition = BT_CUST_LINESPEEDDIAL;
break;
case SKINNY_DEVICE_7921:
for (i = 0; i < 6; i++)
(btn++)->buttonDefinition = BT_CUST_LINESPEEDDIAL;
break;
case SKINNY_DEVICE_7902:
ast_log(LOG_WARNING, "Unsupported device type '%d (7902)' found.\n", d->type);
break;
case SKINNY_DEVICE_7906:
ast_log(LOG_WARNING, "Unsupported device type '%d (7906)' found.\n", d->type);
break;
case SKINNY_DEVICE_7931:
ast_log(LOG_WARNING, "Unsupported device type '%d (7931)' found.\n", d->type);
break;
case SKINNY_DEVICE_7937:
ast_log(LOG_WARNING, "Unsupported device type '%d (7937)' found.\n", d->type);
break;
case SKINNY_DEVICE_7914:
ast_log(LOG_WARNING, "Unsupported device type '%d (7914)' found. Expansion module registered by itself?\n", d->type);
break;
case SKINNY_DEVICE_SCCPGATEWAY_AN:
case SKINNY_DEVICE_SCCPGATEWAY_BRI:
ast_log(LOG_WARNING, "Unsupported device type '%d (SCCP gateway)' found.\n", d->type);
break;
default:
ast_log(LOG_WARNING, "Unknown device type '%d' found.\n", d->type);
break;
}
AST_LIST_LOCK(&d->addons);
AST_LIST_TRAVERSE(&d->addons, a, list) {
if (!strcasecmp(a->type, "7914")) {
for (i = 0; i < 14; i++)
(btn++)->buttonDefinition = BT_CUST_LINESPEEDDIAL;
} else {
ast_log(LOG_WARNING, "Unknown addon type '%s' found. Skipping.\n", a->type);
}
}
AST_LIST_UNLOCK(&d->addons);
return btn;
}
| static int get_devicestate | ( | struct skinny_line * | l | ) | [static] |
Definition at line 4220 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::device, skinny_subchannel::onhold, SKINNY_ONHOOK, and skinny_line::sub.
Referenced by skinny_devicestate(), and skinny_new().
{
struct skinny_subchannel *sub;
int res = AST_DEVICE_UNKNOWN;
if (!l)
res = AST_DEVICE_INVALID;
else if (!l->device)
res = AST_DEVICE_UNAVAILABLE;
else if (l->dnd)
res = AST_DEVICE_BUSY;
else {
if (l->hookstate == SKINNY_ONHOOK) {
res = AST_DEVICE_NOT_INUSE;
} else {
res = AST_DEVICE_INUSE;
}
AST_LIST_TRAVERSE(&l->sub, sub, list) {
if (sub->onhold) {
res = AST_DEVICE_ONHOLD;
break;
}
}
}
return res;
}
| static int get_input | ( | struct skinnysession * | s | ) | [static] |
Definition at line 6340 of file chan_skinny.c.
References ast_debug, ast_log(), ast_mutex_lock, ast_mutex_unlock, ast_poll, ast_verb, skinnysession::device, errno, skinnysession::fd, htolel, skinnysession::inbuf, letohl, skinnysession::lock, LOG_ERROR, LOG_WARNING, skinny_unregister(), and skinnysession::start.
Referenced by skinny_session().
{
int res;
int dlen = 0;
int timeout = keep_alive * 1100;
time_t now;
int *bufaddr;
struct pollfd fds[1];
if (!s->device) {
if(time(&now) == -1) {
ast_log(LOG_ERROR, "error executing time(): %s\n", strerror(errno));
return -1;
}
timeout = (auth_timeout - (now - s->start)) * 1000;
if (timeout < 0) {
/* we have timed out */
if (skinnydebug)
ast_verb(1, "Skinny Client failed to authenticate in %d seconds\n", auth_timeout);
return -1;
}
}
fds[0].fd = s->fd;
fds[0].events = POLLIN;
fds[0].revents = 0;
res = ast_poll(fds, 1, timeout); /* If nothing has happen, client is dead */
/* we add 10% to the keep_alive to deal */
/* with network delays, etc */
if (res < 0) {
if (errno != EINTR) {
ast_log(LOG_WARNING, "Select returned error: %s\n", strerror(errno));
return res;
}
} else if (res == 0) {
if (skinnydebug) {
if (s->device) {
ast_verb(1, "Skinny Client was lost, unregistering\n");
} else {
ast_verb(1, "Skinny Client failed to authenticate in %d seconds\n", auth_timeout);
}
}
skinny_unregister(NULL, s);
return -1;
}
if (fds[0].revents) {
ast_mutex_lock(&s->lock);
memset(s->inbuf, 0, sizeof(s->inbuf));
res = read(s->fd, s->inbuf, 4);
if (res < 0) {
ast_log(LOG_WARNING, "read() returned error: %s\n", strerror(errno));
if (skinnydebug)
ast_verb(1, "Skinny Client was lost, unregistering\n");
skinny_unregister(NULL, s);
ast_mutex_unlock(&s->lock);
return res;
} else if (res != 4) {
ast_log(LOG_WARNING, "Skinny Client sent less data than expected. Expected 4 but got %d.\n", res);
ast_mutex_unlock(&s->lock);
if (res == 0) {
if (skinnydebug)
ast_verb(1, "Skinny Client was lost, unregistering\n");
skinny_unregister(NULL, s);
}
return -1;
}
bufaddr = (int *)s->inbuf;
dlen = letohl(*bufaddr);
if (dlen < 4) {
ast_debug(1, "Skinny Client sent invalid data.\n");
ast_mutex_unlock(&s->lock);
return -1;
}
if (dlen+8 > sizeof(s->inbuf)) {
dlen = sizeof(s->inbuf) - 8;
}
*bufaddr = htolel(dlen);
res = read(s->fd, s->inbuf+4, dlen+4);
ast_mutex_unlock(&s->lock);
if (res < 0) {
ast_log(LOG_WARNING, "read() returned error: %s\n", strerror(errno));
return res;
} else if (res != (dlen+4)) {
ast_log(LOG_WARNING, "Skinny Client sent less data than expected.\n");
return -1;
}
return res;
}
return 0;
}
| static int handle_button_template_req_message | ( | struct skinny_req * | req, |
| struct skinnysession * | s | ||
| ) | [static] |
Definition at line 5506 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, button_definition::instanceNumber, skinny_speeddial::isHint, skinny_device::lines, req_alloc(), skinny_device::speeddials, button_template_res_message::totalButtonCount, and transmit_response().
Referenced by handle_message().
{
struct skinny_device *d = s->device;
struct skinny_line *l;
int i;
struct skinny_speeddial *sd;
struct button_definition_template btn[42];
int lineInstance = 1;
int speeddialInstance = 1;
int buttonCount = 0;
if (!(req = req_alloc(sizeof(struct button_template_res_message), BUTTON_TEMPLATE_RES_MESSAGE)))
return -1;
memset(&btn, 0, sizeof(btn));
get_button_template(s, btn);
for (i=0; i<42; i++) {
int btnSet = 0;
switch (btn[i].buttonDefinition) {
case BT_CUST_LINE:
/* assume failure */
req->data.buttontemplate.definition[i].buttonDefinition = BT_NONE;
req->data.buttontemplate.definition[i].instanceNumber = 0;
AST_LIST_TRAVERSE(&d->lines, l, list) {
if (l->instance == lineInstance) {
ast_verb(0, "Adding button: %d, %d\n", BT_LINE, lineInstance);
req->data.buttontemplate.definition[i].buttonDefinition = BT_LINE;
req->data.buttontemplate.definition[i].instanceNumber = lineInstance;
lineInstance++;
buttonCount++;
btnSet = 1;
break;
}
}
if (!btnSet) {
AST_LIST_TRAVERSE(&d->speeddials, sd, list) {
if (sd->isHint && sd->instance == lineInstance) {
ast_verb(0, "Adding button: %d, %d\n", BT_LINE, lineInstance);
req->data.buttontemplate.definition[i].buttonDefinition = BT_LINE;
req->data.buttontemplate.definition[i].instanceNumber = lineInstance;
lineInstance++;
buttonCount++;
btnSet = 1;
break;
}
}
}
break;
case BT_CUST_LINESPEEDDIAL:
/* assume failure */
req->data.buttontemplate.definition[i].buttonDefinition = BT_NONE;
req->data.buttontemplate.definition[i].instanceNumber = 0;
AST_LIST_TRAVERSE(&d->lines, l, list) {
if (l->instance == lineInstance) {
ast_verb(0, "Adding button: %d, %d\n", BT_LINE, lineInstance);
req->data.buttontemplate.definition[i].buttonDefinition = BT_LINE;
req->data.buttontemplate.definition[i].instanceNumber = lineInstance;
lineInstance++;
buttonCount++;
btnSet = 1;
break;
}
}
if (!btnSet) {
AST_LIST_TRAVERSE(&d->speeddials, sd, list) {
if (sd->isHint && sd->instance == lineInstance) {
ast_verb(0, "Adding button: %d, %d\n", BT_LINE, lineInstance);
req->data.buttontemplate.definition[i].buttonDefinition = BT_LINE;
req->data.buttontemplate.definition[i].instanceNumber = lineInstance;
lineInstance++;
buttonCount++;
btnSet = 1;
break;
} else if (!sd->isHint && sd->instance == speeddialInstance) {
ast_verb(0, "Adding button: %d, %d\n", BT_SPEEDDIAL, speeddialInstance);
req->data.buttontemplate.definition[i].buttonDefinition = BT_SPEEDDIAL;
req->data.buttontemplate.definition[i].instanceNumber = speeddialInstance;
speeddialInstance++;
buttonCount++;
btnSet = 1;
break;
}
}
}
break;
case BT_LINE:
req->data.buttontemplate.definition[i].buttonDefinition = htolel(BT_NONE);
req->data.buttontemplate.definition[i].instanceNumber = htolel(0);
AST_LIST_TRAVERSE(&d->lines, l, list) {
if (l->instance == lineInstance) {
ast_verb(0, "Adding button: %d, %d\n", BT_LINE, lineInstance);
req->data.buttontemplate.definition[i].buttonDefinition = BT_LINE;
req->data.buttontemplate.definition[i].instanceNumber = lineInstance;
lineInstance++;
buttonCount++;
btnSet = 1;
break;
}
}
break;
case BT_SPEEDDIAL:
req->data.buttontemplate.definition[i].buttonDefinition = BT_NONE;
req->data.buttontemplate.definition[i].instanceNumber = 0;
AST_LIST_TRAVERSE(&d->speeddials, sd, list) {
if (!sd->isHint && sd->instance == speeddialInstance) {
ast_verb(0, "Adding button: %d, %d\n", BT_SPEEDDIAL, speeddialInstance);
req->data.buttontemplate.definition[i].buttonDefinition = BT_SPEEDDIAL;
req->data.buttontemplate.definition[i].instanceNumber = speeddialInstance - 1;
speeddialInstance++;
buttonCount++;
btnSet = 1;
break;
}
}
break;
case BT_NONE:
break;
default:
ast_verb(0, "Adding button: %d, %d\n", btn[i].buttonDefinition, 0);
req->data.buttontemplate.definition[i].buttonDefinition = htolel(btn[i].buttonDefinition);
req->data.buttontemplate.definition[i].instanceNumber = 0;
buttonCount++;
btnSet = 1;
break;
}
}
req->data.buttontemplate.buttonOffset = 0;
req->data.buttontemplate.buttonCount = htolel(buttonCount);
req->data.buttontemplate.totalButtonCount = htolel(buttonCount);
if (skinnydebug)
ast_verb(1, "Sending %d template to %s\n",
d->type,
d->name);
transmit_response(d, req);
return 1;
}
| static int handle_callforward_button | ( | struct skinny_subchannel * | sub, |
| int | cfwdtype | ||
| ) | [static] |
Definition at line 4817 of file chan_skinny.c.
References ast_channel::_state, ast_hangup(), ast_indicate(), ast_log(), ast_pthread_create, ast_safe_sleep(), AST_STATE_UP, skinny_subchannel::callid, skinny_line::device, errno, KEYDEF_ONHOOK, KEYDEF_RINGOUT, LOG_WARNING, skinny_subchannel::owner, skinny_subchannel::parent, set_callforwards(), SKINNY_DIALTONE, SKINNY_OFFHOOK, SKINNY_ONHOOK, SKINNY_SPEAKEROFF, SKINNY_SPEAKERON, skinny_ss(), transmit_activatecallplane(), transmit_callstate(), transmit_cfwdstate(), transmit_clear_display_message(), transmit_clearpromptmessage(), transmit_closereceivechannel(), transmit_displaynotify(), transmit_selectsoftkeys(), transmit_speaker_mode(), transmit_start_tone(), and transmit_stopmediatransmission().
Referenced by handle_soft_key_event_message(), and handle_stimulus_message().
{
struct skinny_line *l = sub->parent;
struct skinny_device *d = l->device;
struct ast_channel *c = sub->owner;
pthread_t t;
if (l->hookstate == SKINNY_ONHOOK) {
l->hookstate = SKINNY_OFFHOOK;
transmit_speaker_mode(d, SKINNY_SPEAKERON);
transmit_callstate(d, l->instance, sub->callid, SKINNY_OFFHOOK);
transmit_activatecallplane(d, l);
}
transmit_clear_display_message(d, l->instance, sub->callid);
if (l->cfwdtype & cfwdtype) {
set_callforwards(l, NULL, cfwdtype);
ast_safe_sleep(c, 500);
transmit_speaker_mode(d, SKINNY_SPEAKEROFF);
transmit_closereceivechannel(d, sub);
transmit_stopmediatransmission(d, sub);
transmit_speaker_mode(d, SKINNY_SPEAKEROFF);
transmit_clearpromptmessage(d, l->instance, sub->callid);
transmit_callstate(d, l->instance, sub->callid, SKINNY_ONHOOK);
transmit_selectsoftkeys(d, 0, 0, KEYDEF_ONHOOK);
transmit_activatecallplane(d, l);
transmit_displaynotify(d, "CFwd disabled", 10);
if (sub->owner && sub->owner->_state != AST_STATE_UP) {
ast_indicate(c, -1);
ast_hangup(c);
}
transmit_cfwdstate(d, l);
} else {
l->getforward = cfwdtype;
transmit_start_tone(d, SKINNY_DIALTONE, l->instance, sub->callid);
transmit_selectsoftkeys(d, l->instance, sub->callid, KEYDEF_RINGOUT);
if (ast_pthread_create(&t, NULL, skinny_ss, c)) {
ast_log(LOG_WARNING, "Unable to create switch thread: %s\n", strerror(errno));
ast_hangup(c);
}
}
return 0;
}
| static int handle_capabilities_res_message | ( | struct skinny_req * | req, |
| struct skinnysession * | s | ||
| ) | [static] |
Definition at line 5470 of file chan_skinny.c.
References ast_getformatname_multiple(), AST_LIST_TRAVERSE, ast_log(), ast_mutex_lock, ast_mutex_unlock, ast_verb, 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().
{
struct skinny_device *d = s->device;
struct skinny_line *l;
uint32_t count = 0;
format_t codecs = 0;
int i;
char buf[256];
count = letohl(req->data.caps.count);
if (count > SKINNY_MAX_CAPABILITIES) {
count = SKINNY_MAX_CAPABILITIES;
ast_log(LOG_WARNING, "Received more capabilities than we can handle (%d). Ignoring the rest.\n", SKINNY_MAX_CAPABILITIES);
}
for (i = 0; i < count; i++) {
format_t acodec = 0;
int scodec = 0;
scodec = letohl(req->data.caps.caps[i].codec);
acodec = codec_skinny2ast(scodec);
if (skinnydebug)
ast_verb(1, "Adding codec capability '%" PRId64 " (%d)'\n", acodec, scodec);
codecs |= acodec;
}
d->capability = d->confcapability & codecs;
ast_verb(0, "Device capability set to '%s'\n", ast_getformatname_multiple(buf, sizeof(buf), d->capability));
AST_LIST_TRAVERSE(&d->lines, l, list) {
ast_mutex_lock(&l->lock);
l->capability = l->confcapability & d->capability;
ast_mutex_unlock(&l->lock);
}
return 1;
}
| static int handle_enbloc_call_message | ( | struct skinny_req * | req, |
| struct skinnysession * | s | ||
| ) | [static] |
Definition at line 5715 of file chan_skinny.c.
References skinny_line::activesub, 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(), LOG_WARNING, skinny_subchannel::parent, SKINNY_DIALTONE, skinny_new(), skinny_newcall(), SKINNY_OFFHOOK, ast_channel::tech_pvt, transmit_activatecallplane(), transmit_callstate(), transmit_clear_display_message(), transmit_start_tone(), and transmit_stop_tone().
Referenced by handle_message().
{
struct skinny_device *d = s->device;
struct skinny_line *l;
struct skinny_subchannel *sub = NULL;
struct ast_channel *c;
pthread_t t;
if (skinnydebug)
ast_verb(1, "Received Enbloc Call: %s\n", req->data.enbloccallmessage.calledParty);
sub = find_subchannel_by_instance_reference(d, d->lastlineinstance, d->lastcallreference);
if (!sub) {
l = find_line_by_instance(d, d->lastlineinstance);
if (!l) {
return 0;
}
} else {
l = sub->parent;
}
c = skinny_new(l, AST_STATE_DOWN, NULL);
if(!c) {
ast_log(LOG_WARNING, "Unable to create channel for %s@%s\n", l->name, d->name);
} else {
l->hookstate = SKINNY_OFFHOOK;
sub = c->tech_pvt;
l->activesub = sub;
transmit_callstate(d, l->instance, sub->callid, SKINNY_OFFHOOK);
transmit_activatecallplane(d, l);
transmit_clear_display_message(d, l->instance, sub->callid);
transmit_start_tone(d, SKINNY_DIALTONE, l->instance, sub->callid);
if (!ast_ignore_pattern(c->context, req->data.enbloccallmessage.calledParty)) {
transmit_stop_tone(d, l->instance, sub->callid);
}
ast_copy_string(c->exten, req->data.enbloccallmessage.calledParty, sizeof(c->exten));
if (ast_pthread_create(&t, NULL, skinny_newcall, c)) {
ast_log(LOG_WARNING, "Unable to create new call thread: %s\n", strerror(errno));
ast_hangup(c);
}
}
return 1;
}
| static int handle_hold_button | ( | struct skinny_subchannel * | sub | ) | [static] |
Definition at line 4657 of file chan_skinny.c.
References skinny_line::activesub, skinny_subchannel::callid, skinny_line::device, KEYDEF_CONNECTED, KEYDEF_ONHOLD, skinny_subchannel::onhold, skinny_subchannel::parent, skinny_subchannel::related, skinny_hold(), skinny_unhold(), and transmit_selectsoftkeys().
Referenced by handle_soft_key_event_message(), and handle_stimulus_message().
{
if (!sub)
return -1;
if (sub->related) {
skinny_hold(sub);
skinny_unhold(sub->related);
sub->parent->activesub = sub->related;
} else {
if (sub->onhold) {
skinny_unhold(sub);
transmit_selectsoftkeys(sub->parent->device, sub->parent->instance, sub->callid, KEYDEF_CONNECTED);
} else {
skinny_hold(sub);
transmit_selectsoftkeys(sub->parent->device, sub->parent->instance, sub->callid, KEYDEF_ONHOLD);
}
}
return 1;
}
| static int handle_ip_port_message | ( | struct skinny_req * | req, |
| struct skinnysession * | s | ||
| ) | [static] |
Definition at line 4860 of file chan_skinny.c.
Referenced by handle_message().
{
/* no response necessary */
return 1;
}
| static int handle_keep_alive_message | ( | struct skinny_req * | req, |
| struct skinnysession * | s | ||
| ) | [static] |
Definition at line 4741 of file chan_skinny.c.
References skinnysession::device, KEEP_ALIVE_ACK_MESSAGE, req_alloc(), and transmit_response().
Referenced by handle_message().
{
if (!(req = req_alloc(0, KEEP_ALIVE_ACK_MESSAGE)))
return -1;
transmit_response(s->device, req);
return 1;
}
| static int handle_keypad_button_message | ( | struct skinny_req * | req, |
| struct skinnysession * | s | ||
| ) | [static] |
Definition at line 4866 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, ast_frame_subclass::integer, skinny_data::keypad, letohl, keypad_button_message::lineInstance, LOG_WARNING, skinny_subchannel::owner, skinny_subchannel::parent, ast_frame::src, and ast_frame::subclass.
Referenced by handle_message().
{
struct skinny_subchannel *sub = NULL;
struct skinny_line *l;
struct skinny_device *d = s->device;
struct ast_frame f = { 0, };
char dgt;
int digit;
int lineInstance;
int callReference;
digit = letohl(req->data.keypad.button);
lineInstance = letohl(req->data.keypad.lineInstance);
callReference = letohl(req->data.keypad.callReference);
if (digit == 14) {
dgt = '*';
} else if (digit == 15) {
dgt = '#';
} else if (digit >= 0 && digit <= 9) {
dgt = '0' + digit;
} else {
/* digit=10-13 (A,B,C,D ?), or
* digit is bad value
*
* probably should not end up here, but set
* value for backward compatibility, and log
* a warning.
*/
dgt = '0' + digit;
ast_log(LOG_WARNING, "Unsupported digit %d\n", digit);
}
f.subclass.integer = dgt;
f.src = "skinny";
if (lineInstance && callReference)
sub = find_subchannel_by_instance_reference(d, lineInstance, callReference);
else
sub = d->activeline->activesub;
//sub = find_subchannel_by_instance_reference(d, d->lastlineinstance, d->lastcallreference);
if (!sub)
return 0;
l = sub->parent;
if (sub->owner) {
if (sub->owner->_state == 0) {
f.frametype = AST_FRAME_DTMF_BEGIN;
ast_queue_frame(sub->owner, &f);
}
/* XXX MUST queue this frame to all lines in threeway call if threeway call is active */
f.frametype = AST_FRAME_DTMF_END;
ast_queue_frame(sub->owner, &f);
/* XXX This seriously needs to be fixed */
if (AST_LIST_NEXT(sub, list) && AST_LIST_NEXT(sub, list)->owner) {
if (sub->owner->_state == 0) {
f.frametype = AST_FRAME_DTMF_BEGIN;
ast_queue_frame(AST_LIST_NEXT(sub, list)->owner, &f);
}
f.frametype = AST_FRAME_DTMF_END;
ast_queue_frame(AST_LIST_NEXT(sub, list)->owner, &f);
}
} else {
if (skinnydebug)
ast_verb(1, "No owner: %s\n", l->name);
}
return 1;
}
| static int handle_message | ( | struct skinny_req * | req, |
| struct skinnysession * | s | ||
| ) | [static] |
Definition at line 6138 of file chan_skinny.c.
References ast_channel::_state, skinny_device::activeline, skinny_line::activesub, skinny_data::alarm, 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, alarm_message::displayMessage, skinny_req::e, ENBLOC_CALL_MESSAGE, find_line_by_instance(), find_speeddial_by_instance(), find_subchannel_by_instance_reference(), handle_button_template_req_message(), handle_capabilities_res_message(), handle_enbloc_call_message(), handle_ip_port_message(), handle_keep_alive_message(), handle_keypad_button_message(), handle_offhook_message(), handle_onhook_message(), handle_open_receive_channel_ack_message(), handle_register_message(), handle_soft_key_event_message(), handle_stimulus_message(), HEADSET_STATUS_MESSAGE, IP_PORT_MESSAGE, KEEP_ALIVE_MESSAGE, KEYDEF_ONHOOK, skinny_data::keypad, KEYPAD_BUTTON_MESSAGE, letohl, skinny_data::line, LINE_STATE_REQ_MESSAGE, keypad_button_message::lineInstance, line_state_req_message::lineNumber, 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, SKINNY_DEVONLY, skinny_unregister(), SOFT_KEY_EVENT_MESSAGE, SOFT_KEY_SET_REQ_MESSAGE, SOFT_KEY_TEMPLATE_REQ_MESSAGE, SPEED_DIAL_STAT_REQ_MESSAGE, speed_dial_stat_req_message::speedDialNumber, skinny_data::speeddialreq, STIMULUS_MESSAGE, TIME_DATE_REQ_MESSAGE, transmit_definetimedate(), transmit_linestatres(), transmit_selectsoftkeys(), transmit_serverres(), transmit_softkeysetres(), transmit_softkeytemplateres(), transmit_speeddialstatres(), transmit_versionres(), UNREGISTER_MESSAGE, and VERSION_REQ_MESSAGE.
Referenced by skinny_session().
{
int res = 0;
struct skinny_speeddial *sd;
struct skinny_line *l;
struct skinny_device *d = s->device;
if ((!s->device) && (letohl(req->e) != REGISTER_MESSAGE && letohl(req->e) != ALARM_MESSAGE)) {
ast_log(LOG_WARNING, "Client sent message #%d without first registering.\n", req->e);
ast_free(req);
return 0;
}
SKINNY_DEVONLY(if (skinnydebug > 1) {
ast_verb(4, "Received %s from %s\n", message2str(req->e), s->device->name);
})
switch(letohl(req->e)) {
case KEEP_ALIVE_MESSAGE:
res = handle_keep_alive_message(req, s);
break;
case REGISTER_MESSAGE:
if (skinnydebug)
ast_verb(1, "Device %s is attempting to register\n", req->data.reg.name);
res = handle_register_message(req, s);
break;
case IP_PORT_MESSAGE:
res = handle_ip_port_message(req, s);
break;
case KEYPAD_BUTTON_MESSAGE:
{
struct skinny_device *d = s->device;
struct skinny_subchannel *sub;
int lineInstance;
int callReference;
if (skinnydebug)
ast_verb(1, "Collected digit: [%d]\n", letohl(req->data.keypad.button));
lineInstance = letohl(req->data.keypad.lineInstance);
callReference = letohl(req->data.keypad.callReference);
if (lineInstance) {
sub = find_subchannel_by_instance_reference(d, lineInstance, callReference);
} else {
sub = d->activeline->activesub;
}
if (sub && ((sub->owner && sub->owner->_state < AST_STATE_UP) || sub->onhold)) {
char dgt;
int digit = letohl(req->data.keypad.button);
if (digit == 14) {
dgt = '*';
} else if (digit == 15) {
dgt = '#';
} else if (digit >= 0 && digit <= 9) {
dgt = '0' + digit;
} else {
/* digit=10-13 (A,B,C,D ?), or
* digit is bad value
*
* probably should not end up here, but set
* value for backward compatibility, and log
* a warning.
*/
dgt = '0' + digit;
ast_log(LOG_WARNING, "Unsupported digit %d\n", digit);
}
d->exten[strlen(d->exten)] = dgt;
d->exten[strlen(d->exten)+1] = '\0';
} else
res = handle_keypad_button_message(req, s);
}
break;
case ENBLOC_CALL_MESSAGE:
res = handle_enbloc_call_message(req, s);
break;
case STIMULUS_MESSAGE:
res = handle_stimulus_message(req, s);
break;
case OFFHOOK_MESSAGE:
res = handle_offhook_message(req, s);
break;
case ONHOOK_MESSAGE:
res = handle_onhook_message(req, s);
break;
case CAPABILITIES_RES_MESSAGE:
if (skinnydebug)
ast_verb(1, "Received CapabilitiesRes\n");
res = handle_capabilities_res_message(req, s);
break;
case SPEED_DIAL_STAT_REQ_MESSAGE:
if (skinnydebug)
ast_verb(1, "Received SpeedDialStatRequest\n");
if ( (sd = find_speeddial_by_instance(s->device, letohl(req->data.speeddialreq.speedDialNumber), 0)) ) {
transmit_speeddialstatres(d, sd);
}
break;
case LINE_STATE_REQ_MESSAGE:
if (skinnydebug)
ast_verb(1, "Received LineStatRequest\n");
if ((l = find_line_by_instance(d, letohl(req->data.line.lineNumber)))) {
transmit_linestatres(d, l);
}
break;
case TIME_DATE_REQ_MESSAGE:
if (skinnydebug)
ast_verb(1, "Received Time/Date Request\n");
transmit_definetimedate(d);
break;
case BUTTON_TEMPLATE_REQ_MESSAGE:
if (skinnydebug)
ast_verb(1, "Buttontemplate requested\n");
res = handle_button_template_req_message(req, s);
break;
case VERSION_REQ_MESSAGE:
if (skinnydebug)
ast_verb(1, "Version Request\n");
transmit_versionres(d);
break;
case SERVER_REQUEST_MESSAGE:
if (skinnydebug)
ast_verb(1, "Received Server Request\n");
transmit_serverres(d);
break;
case ALARM_MESSAGE:
/* no response necessary */
if (skinnydebug)
ast_verb(1, "Received Alarm Message: %s\n", req->data.alarm.displayMessage);
break;
case OPEN_RECEIVE_CHANNEL_ACK_MESSAGE:
if (skinnydebug)
ast_verb(1, "Received Open Receive Channel Ack\n");
res = handle_open_receive_channel_ack_message(req, s);
break;
case SOFT_KEY_SET_REQ_MESSAGE:
if (skinnydebug)
ast_verb(1, "Received SoftKeySetReq\n");
transmit_softkeysetres(d);
transmit_selectsoftkeys(d, 0, 0, KEYDEF_ONHOOK);
break;
case SOFT_KEY_EVENT_MESSAGE:
res = handle_soft_key_event_message(req, s);
break;
case UNREGISTER_MESSAGE:
if (skinnydebug)
ast_verb(1, "Received Unregister Request\n");
res = skinny_unregister(req, s);
break;
case SOFT_KEY_TEMPLATE_REQ_MESSAGE:
if (skinnydebug)
ast_verb(1, "Received SoftKey Template Request\n");
transmit_softkeytemplateres(d);
break;
case HEADSET_STATUS_MESSAGE:
/* XXX umm...okay? Why do I care? */
break;
case REGISTER_AVAILABLE_LINES_MESSAGE:
/* XXX I have no clue what this is for, but my phone was sending it, so... */
break;
default:
if (skinnydebug)
ast_verb(1, "RECEIVED UNKNOWN MESSAGE TYPE: %x\n", letohl(req->e));
break;
}
if (res >= 0 && req)
ast_free(req);
return res;
}
| static int handle_offhook_message | ( | struct skinny_req * | req, |
| struct skinnysession * | s | ||
| ) | [static] |
Definition at line 5289 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_verbose(), skinny_subchannel::callid, skinny_req::data, skinnysession::device, errno, find_line_by_instance(), find_subchannel_by_instance_reference(), offhook_message::instance, KEYDEF_CONNECTED, KEYDEF_OFFHOOK, letohl, skinny_device::lines, LOG_WARNING, ast_channel::name, skinny_data::offhook, skinny_subchannel::onhold, skinny_subchannel::outgoing, skinny_subchannel::owner, skinny_subchannel::parent, SKINNY_CONNECTED, SKINNY_DIALTONE, SKINNY_LAMP_ON, skinny_new(), SKINNY_OFFHOOK, SKINNY_RING_OFF, skinny_ss(), start_rtp(), STIMULUS_LINE, skinny_line::sub, ast_channel::tech_pvt, transmit_activatecallplane(), transmit_callstate(), transmit_clear_display_message(), transmit_definetimedate(), transmit_lamp_indication(), transmit_ringer_mode(), transmit_selectsoftkeys(), transmit_start_tone(), transmit_stop_tone(), and VERBOSE_PREFIX_3.
Referenced by handle_message().
{
struct skinny_device *d = s->device;
struct skinny_line *l;
struct skinny_subchannel *sub;
struct ast_channel *c;
struct skinny_line *tmp;
pthread_t t;
int instance;
/* if any line on a device is offhook, than the device must be offhook,
unless we have shared lines CCM seems that it would never get here,
but asterisk does, so we may need to do more work. Ugly, we should
probably move hookstate from line to device, afterall, it's actually
a device that changes hookstates */
AST_LIST_TRAVERSE(&d->lines, tmp, list) {
if (tmp->hookstate == SKINNY_OFFHOOK) {
ast_verbose(VERBOSE_PREFIX_3 "Got offhook message when device (%s@%s) already offhook\n", tmp->name, d->name);
return 0;
}
}
instance = letohl(req->data.offhook.instance);
if (instance) {
sub = find_subchannel_by_instance_reference(d, d->lastlineinstance, d->lastcallreference);
if (!sub) {
l = find_line_by_instance(d, d->lastlineinstance);
if (!l) {
return 0;
}
} else {
l = sub->parent;
}
} else {
l = d->activeline;
sub = l->activesub;
}
/* Not ideal, but let's send updated time at onhook and offhook, as it clears the display */
transmit_definetimedate(d);
transmit_ringer_mode(d, SKINNY_RING_OFF);
l->hookstate = SKINNY_OFFHOOK;
ast_devstate_changed(AST_DEVICE_INUSE, "Skinny/%s@%s", l->name, d->name);
if (sub && sub->onhold) {
return 1;
}
transmit_lamp_indication(d, STIMULUS_LINE, l->instance, SKINNY_LAMP_ON);
if (sub && sub->outgoing) {
/* We're answering a ringing call */
ast_queue_control(sub->owner, AST_CONTROL_ANSWER);
transmit_callstate(d, l->instance, sub->callid, SKINNY_OFFHOOK);
transmit_activatecallplane(d, l);
transmit_stop_tone(d, l->instance, sub->callid);
transmit_callstate(d, sub->parent->instance, sub->callid, SKINNY_CONNECTED);
transmit_selectsoftkeys(d, l->instance, sub->callid, KEYDEF_CONNECTED);
start_rtp(sub);
ast_setstate(sub->owner, AST_STATE_UP);
} else {
if (sub && sub->owner) {
ast_debug(1, "Current sub [%s] already has owner\n", sub->owner->name);
} else {
c = skinny_new(l, AST_STATE_DOWN, NULL);
if (c) {
sub = c->tech_pvt;
l->activesub = sub;
transmit_callstate(d, l->instance, sub->callid, SKINNY_OFFHOOK);
transmit_activatecallplane(d, l);
transmit_clear_display_message(d, l->instance, sub->callid);
transmit_start_tone(d, SKINNY_DIALTONE, l->instance, sub->callid);
transmit_selectsoftkeys(d, l->instance, sub->callid, KEYDEF_OFFHOOK);
/* start the switch thread */
if (ast_pthread_create(&t, NULL, skinny_ss, c)) {
ast_log(LOG_WARNING, "Unable to create switch thread: %s\n", strerror(errno));
ast_hangup(c);
}
} else {
ast_log(LOG_WARNING, "Unable to create channel for %s@%s\n", l->name, d->name);
}
}
}
return 1;
}
| static int handle_onhook_message | ( | struct skinny_req * | req, |
| struct skinnysession * | s | ||
| ) | [static] |
Definition at line 5380 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, find_subchannel_by_instance_reference(), handle_transfer_button(), onhook_message::instance, KEYDEF_ONHOOK, letohl, LOG_WARNING, skinny_subchannel::onhold, skinny_data::onhook, skinny_subchannel::owner, skinny_subchannel::parent, onhook_message::reference, skinny_subchannel::related, SKINNY_CX_RECVONLY, SKINNY_OFFHOOK, SKINNY_ONHOOK, SKINNY_SPEAKEROFF, skinny_line::sub, transmit_activatecallplane(), transmit_callstate(), transmit_clearpromptmessage(), transmit_closereceivechannel(), transmit_definetimedate(), transmit_selectsoftkeys(), transmit_speaker_mode(), transmit_stopmediatransmission(), and skinny_subchannel::xferor.
Referenced by handle_message().
{
struct skinny_device *d = s->device;
struct skinny_line *l;
struct skinny_subchannel *sub;
int instance;
int reference;
int onlysub = 0;
instance = letohl(req->data.onhook.instance);
reference = letohl(req->data.onhook.reference);
if (instance && reference) {
sub = find_subchannel_by_instance_reference(d, instance, reference);
if (!sub) {
return 0;
}
l = sub->parent;
} else {
l = d->activeline;
sub = l->activesub;
if (!sub) {
return 0;
}
}
if (l->hookstate == SKINNY_ONHOOK) {
/* Something else already put us back on hook */
return 0;
}
ast_devstate_changed(AST_DEVICE_NOT_INUSE, "Skinny/%s@%s", l->name, d->name);
if (sub->onhold) {
return 0;
}
if (!AST_LIST_NEXT(sub, list)) {
onlysub = 1;
} else {
AST_LIST_REMOVE(&l->sub, sub, list);
}
sub->cxmode = SKINNY_CX_RECVONLY;
if (onlysub || sub->xferor){ /* is this the only call to this device? */
l->hookstate = SKINNY_ONHOOK;
if (skinnydebug)
ast_debug(1, "Skinny %s@%s-%d went on hook\n", l->name, d->name, reference);
}
if (l->hookstate == SKINNY_ONHOOK) {
transmit_closereceivechannel(d, sub);
transmit_stopmediatransmission(d, sub);
transmit_speaker_mode(d, SKINNY_SPEAKEROFF);
transmit_clearpromptmessage(d, instance, sub->callid);
transmit_callstate(d, l->instance, sub->callid, SKINNY_ONHOOK);
transmit_selectsoftkeys(d, 0, 0, KEYDEF_ONHOOK);
transmit_activatecallplane(d, l);
} else if (l->hookstate == SKINNY_OFFHOOK) {
transmit_callstate(d, l->instance, sub->callid, SKINNY_OFFHOOK);
transmit_activatecallplane(d, l);
} else {
transmit_callstate(d, l->instance, sub->callid, l->hookstate);
}
if (l->transfer && sub->xferor && sub->owner->_state >= AST_STATE_RING) {
/* We're allowed to transfer, we have two active calls and
we made at least one of the calls. Let's try and transfer */
handle_transfer_button(sub);
} else {
/* Hangup the current call */
/* If there is another active call, skinny_hangup will ring the phone with the other call */
if (sub->xferor && sub->related){
sub->related->related = NULL;
sub->related->blindxfer = 0;
}
if (sub->owner) {
sub->alreadygone = 1;
ast_queue_hangup(sub->owner);
} else {
ast_log(LOG_WARNING, "Skinny(%s@%s-%d) channel already destroyed\n",
l->name, d->name, sub->callid);
}
/* Not ideal, but let's send updated time at onhook and offhook, as it clears the display */
transmit_definetimedate(d);
}
return 1;
}
| static int handle_open_receive_channel_ack_message | ( | struct skinny_req * | req, |
| struct skinnysession * | s | ||
| ) | [static] |
Definition at line 5654 of file chan_skinny.c.
References ast_best_codec(), ast_codec_pref_getsize(), ast_getformatname(), ast_inet_ntoa(), ast_log(), ast_rtp_instance_get_local_address(), ast_rtp_instance_set_remote_address(), ast_sockaddr_from_sin, ast_sockaddr_to_sin, ast_verb, ast_format_list::bits, ast_format_list::cur_ms, skinny_req::data, skinnysession::device, find_subchannel_by_reference(), open_receive_channel_ack_message::ipAddr, letohl, LOG_ERROR, skinny_data::openreceivechannelack, skinny_device::ourip, skinny_subchannel::parent, open_receive_channel_ack_message::passThruId, open_receive_channel_ack_message::port, skinny_subchannel::rtp, status, open_receive_channel_ack_message::status, and transmit_startmediatransmission().
Referenced by handle_message().
{
struct skinny_device *d = s->device;
struct skinny_line *l;
struct skinny_subchannel *sub;
struct ast_format_list fmt;
struct sockaddr_in sin = { 0, };
struct sockaddr_in us = { 0, };
struct ast_sockaddr sin_tmp;
struct ast_sockaddr us_tmp;
uint32_t addr;
int port;
int status;
int passthruid;
status = letohl(req->data.openreceivechannelack.status);
if (status) {
ast_log(LOG_ERROR, "Open Receive Channel Failure\n");
return 0;
}
addr = req->data.openreceivechannelack.ipAddr;
port = letohl(req->data.openreceivechannelack.port);
passthruid = letohl(req->data.openreceivechannelack.passThruId);
sin.sin_family = AF_INET;
sin.sin_addr.s_addr = addr;
sin.sin_port = htons(port);
sub = find_subchannel_by_reference(d, passthruid);
if (!sub)
return 0;
l = sub->parent;
if (sub->rtp) {
ast_sockaddr_from_sin(&sin_tmp, &sin);
ast_rtp_instance_set_remote_address(sub->rtp, &sin_tmp);
ast_rtp_instance_get_local_address(sub->rtp, &us_tmp);
ast_sockaddr_to_sin(&us_tmp, &us);
us.sin_addr.s_addr = us.sin_addr.s_addr ? us.sin_addr.s_addr : d->ourip.s_addr;
} else {
ast_log(LOG_ERROR, "No RTP structure, this is very bad\n");
return 0;
}
if (skinnydebug) {
ast_verb(1, "device ipaddr = %s:%d\n", ast_inet_ntoa(sin.sin_addr), ntohs(sin.sin_port));
ast_verb(1, "asterisk ipaddr = %s:%d\n", ast_inet_ntoa(us.sin_addr), ntohs(us.sin_port));
}
fmt = ast_codec_pref_getsize(&l->prefs, ast_best_codec(l->capability));
if (skinnydebug)
ast_verb(1, "Setting payloadType to '%s' (%d ms)\n", ast_getformatname(fmt.bits), fmt.cur_ms);
transmit_startmediatransmission(d, sub, us, fmt);
return 1;
}
| static int handle_register_message | ( | struct skinny_req * | req, |
| struct skinnysession * | s | ||
| ) | [static] |
Definition at line 4750 of file chan_skinny.c.
References ast_atomic_fetchadd_int(), 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, name, 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().
{
struct skinny_device *d = NULL;
char name[16];
int res;
memcpy(&name, req->data.reg.name, sizeof(name));
res = skinny_register(req, s);
if (!res) {
ast_log(LOG_ERROR, "Rejecting Device %s: Device not found\n", name);
if (!(req = req_alloc(sizeof(struct register_rej_message), REGISTER_REJ_MESSAGE)))
return -1;
snprintf(req->data.regrej.errMsg, sizeof(req->data.regrej.errMsg), "No Authority: %s", name);
/* transmit_respons in line as we don't have a valid d */
ast_mutex_lock(&s->lock);
if (letohl(req->len) > SKINNY_MAX_PACKET || letohl(req->len) < 0) {
ast_log(LOG_WARNING, "transmit_response: the length (%d) of the request is out of bounds (%d) \n", letohl(req->len), SKINNY_MAX_PACKET);
ast_mutex_unlock(&s->lock);
return -1;
}
memset(s->outbuf, 0, sizeof(s->outbuf));
memcpy(s->outbuf, req, skinny_header_size);
memcpy(s->outbuf+skinny_header_size, &req->data, letohl(req->len));
res = write(s->fd, s->outbuf, letohl(req->len)+8);
if (res != letohl(req->len)+8) {
ast_log(LOG_WARNING, "Transmit: write only sent %d out of %d bytes: %s\n", res, letohl(req->len)+8, strerror(errno));
}
ast_mutex_unlock(&s->lock);
return 0;
}
ast_atomic_fetchadd_int(&unauth_sessions, -1);
ast_verb(3, "Device '%s' successfully registered\n", name);
d = s->device;
if (!(req = req_alloc(sizeof(struct register_ack_message), REGISTER_ACK_MESSAGE)))
return -1;
req->data.regack.res[0] = '0';
req->data.regack.res[1] = '\0';
req->data.regack.keepAlive = htolel(keep_alive);
memcpy(req->data.regack.dateTemplate, date_format, sizeof(req->data.regack.dateTemplate));
req->data.regack.res2[0] = '0';
req->data.regack.res2[1] = '\0';
req->data.regack.secondaryKeepAlive = htolel(keep_alive);
transmit_response(d, req);
if (skinnydebug)
ast_verb(1, "Requesting capabilities\n");
if (!(req = req_alloc(0, CAPABILITIES_REQ_MESSAGE)))
return -1;
transmit_response(d, req);
return res;
}
| static char* handle_skinny_reload | ( | struct ast_cli_entry * | e, |
| int | cmd, | ||
| struct ast_cli_args * | a | ||
| ) | [static] |
Definition at line 2919 of file chan_skinny.c.
References ast_cli_args::argc, ast_cli_entry::args, CLI_GENERATE, CLI_INIT, CLI_SHOWUSAGE, CLI_SUCCESS, ast_cli_entry::command, skinny_reload(), and ast_cli_entry::usage.
{
switch (cmd) {
case CLI_INIT:
e->command = "skinny reload";
e->usage =
"Usage: skinny reload\n"
" Reloads the chan_skinny configuration\n";
return NULL;
case CLI_GENERATE:
return NULL;
}
if (a->argc != e->args)
return CLI_SHOWUSAGE;
skinny_reload();
return CLI_SUCCESS;
}
| static char* handle_skinny_reset | ( | struct ast_cli_entry * | e, |
| int | cmd, | ||
| struct ast_cli_args * | a | ||
| ) | [static] |
Definition at line 2984 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, ast_cli_args::line, ast_cli_args::n, 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.
{
struct skinny_device *d;
struct skinny_req *req;
switch (cmd) {
case CLI_INIT:
e->command = "skinny reset";
e->usage =
"Usage: skinny reset <DeviceId|DeviceName|all> [restart]\n"
" Causes a Skinny device to reset itself, optionally with a full restart\n";
return NULL;
case CLI_GENERATE:
return complete_skinny_reset(a->line, a->word, a->pos, a->n);
}
if (a->argc < 3 || a->argc > 4)
return CLI_SHOWUSAGE;
AST_LIST_LOCK(&devices);
AST_LIST_TRAVERSE(&devices, d, list) {
int fullrestart = 0;
if (!strcasecmp(a->argv[2], d->id) || !strcasecmp(a->argv[2], d->name) || !strcasecmp(a->argv[2], "all")) {
if (!(d->session))
continue;
if (!(req = req_alloc(sizeof(struct reset_message), RESET_MESSAGE)))
continue;
if (a->argc == 4 && !strcasecmp(a->argv[3], "restart"))
fullrestart = 1;
if (fullrestart)
req->data.reset.resetType = 2;
else
req->data.reset.resetType = 1;
ast_verb(3, "%s device %s.\n", (fullrestart) ? "Restarting" : "Resetting", d->id);
transmit_response(d, req);
}
}
AST_LIST_UNLOCK(&devices);
return CLI_SUCCESS;
}
| static char* handle_skinny_set_debug | ( | struct ast_cli_entry * | e, |
| int | cmd, | ||
| struct ast_cli_args * | a | ||
| ) | [static] |
Definition at line 2877 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.
{
switch (cmd) {
case CLI_INIT:
#ifdef SKINNY_DEVMODE
e->command = "skinny set debug {off|on|packet}";
e->usage =
"Usage: skinny set debug {off|on|packet}\n"
" Enables/Disables dumping of Skinny packets for debugging purposes\n";
#else
e->command = "skinny set debug {off|on}";
e->usage =
"Usage: skinny set debug {off|on}\n"
" Enables/Disables dumping of Skinny packets for debugging purposes\n";
#endif
return NULL;
case CLI_GENERATE:
return NULL;
}
if (a->argc != e->args)
return CLI_SHOWUSAGE;
if (!strncasecmp(a->argv[e->args - 1], "on", 2)) {
skinnydebug = 1;
ast_cli(a->fd, "Skinny Debugging Enabled\n");
return CLI_SUCCESS;
} else if (!strncasecmp(a->argv[e->args - 1], "off", 3)) {
skinnydebug = 0;
ast_cli(a->fd, "Skinny Debugging Disabled\n");
return CLI_SUCCESS;
#ifdef SKINNY_DEVMODE
} else if (!strncasecmp(a->argv[e->args - 1], "packet", 6)) {
skinnydebug = 2;
ast_cli(a->fd, "Skinny Debugging Enabled including Packets\n");
return CLI_SUCCESS;
#endif
} else {
return CLI_SHOWUSAGE;
}
}
| 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 3364 of file chan_skinny.c.
References _skinny_show_device(), ast_cli_args::argc, ast_cli_args::argv, CLI_GENERATE, CLI_INIT, ast_cli_entry::command, complete_skinny_show_device(), ast_cli_args::fd, ast_cli_args::line, ast_cli_args::n, ast_cli_args::pos, ast_cli_entry::usage, and ast_cli_args::word.
{
switch (cmd) {
case CLI_INIT:
e->command = "skinny show device";
e->usage =
"Usage: skinny show device <DeviceId|DeviceName>\n"
" Lists all deviceinformation of a specific device known to the Skinny subsystem.\n";
return NULL;
case CLI_GENERATE:
return complete_skinny_show_device(a->line, a->word, a->pos, a->n);
}
return _skinny_show_device(0, a->fd, NULL, NULL, a->argc, (const char **) a->argv);
}
| static char* handle_skinny_show_devices | ( | struct ast_cli_entry * | e, |
| int | cmd, | ||
| struct ast_cli_args * | a | ||
| ) | [static] |
Definition at line 3230 of file chan_skinny.c.
References _skinny_show_devices(), ast_cli_args::argc, ast_cli_args::argv, CLI_GENERATE, CLI_INIT, ast_cli_entry::command, ast_cli_args::fd, and ast_cli_entry::usage.
{
switch (cmd) {
case CLI_INIT:
e->command = "skinny show devices";
e->usage =
"Usage: skinny show devices\n"
" Lists all devices known to the Skinny subsystem.\n";
return NULL;
case CLI_GENERATE:
return NULL;
}
return _skinny_show_devices(a->fd, NULL, NULL, NULL, a->argc, (const char **) a->argv);
}
| 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 3657 of file chan_skinny.c.
References _skinny_show_line(), ast_cli_args::argc, ast_cli_args::argv, CLI_GENERATE, CLI_INIT, ast_cli_entry::command, complete_skinny_show_line(), ast_cli_args::fd, ast_cli_args::line, ast_cli_args::n, ast_cli_args::pos, ast_cli_entry::usage, and ast_cli_args::word.
{
switch (cmd) {
case CLI_INIT:
e->command = "skinny show line";
e->usage =
"Usage: skinny show line <Line> [ on <DeviceID|DeviceName> ]\n"
" List all lineinformation of a specific line known to the Skinny subsystem.\n";
return NULL;
case CLI_GENERATE:
return complete_skinny_show_line(a->line, a->word, a->pos, a->n);
}
return _skinny_show_line(0, a->fd, NULL, NULL, a->argc, (const char **) a->argv);
}
| static char* handle_skinny_show_lines | ( | struct ast_cli_entry * | e, |
| int | cmd, | ||
| struct ast_cli_args * | a | ||
| ) | [static] |
Definition at line 3478 of file chan_skinny.c.
References _skinny_show_lines(), ast_cli_args::argc, ast_cli_entry::args, ast_cli_args::argv, CLI_GENERATE, CLI_INIT, CLI_SHOWUSAGE, ast_cli_entry::command, ast_cli_args::fd, and ast_cli_entry::usage.
{
switch (cmd) {
case CLI_INIT:
e->command = "skinny show lines [verbose]";
e->usage =
"Usage: skinny show lines\n"
" Lists all lines known to the Skinny subsystem.\n"
" If 'verbose' is specified, the output includes\n"
" information about subs for each line.\n";
return NULL;
case CLI_GENERATE:
return NULL;
}
if (a->argc == e->args) {
if (strcasecmp(a->argv[e->args-1], "verbose")) {
return CLI_SHOWUSAGE;
}
} else if (a->argc != e->args - 1) {
return CLI_SHOWUSAGE;
}
return _skinny_show_lines(a->fd, NULL, NULL, NULL, a->argc, (const char **) a->argv);
}
| 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 3674 of file chan_skinny.c.
References ast_cli_args::argc, ast_cli(), AST_CLI_YESNO, 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, ast_jb_conf::target_extra, and ast_cli_entry::usage.
{
switch (cmd) {
case CLI_INIT:
e->command = "skinny show settings";
e->usage =
"Usage: skinny show settings\n"
" Lists all global configuration settings of the Skinny subsystem.\n";
return NULL;
case CLI_GENERATE:
return NULL;
}
if (a->argc != 3)
return CLI_SHOWUSAGE;
ast_cli(a->fd, "\nGlobal Settings:\n");
ast_cli(a->fd, " Skinny Port: %d\n", ntohs(bindaddr.sin_port));
ast_cli(a->fd, " Bindaddress: %s\n", ast_inet_ntoa(bindaddr.sin_addr));
ast_cli(a->fd, " KeepAlive: %d\n", keep_alive);
ast_cli(a->fd, " Date Format: %s\n", date_format);
ast_cli(a->fd, " Voice Mail Extension: %s\n", S_OR(global_vmexten, "(not set)"));
ast_cli(a->fd, " Reg. context: %s\n", S_OR(regcontext, "(not set)"));
ast_cli(a->fd, " Jitterbuffer enabled: %s\n", AST_CLI_YESNO(ast_test_flag(&global_jbconf, AST_JB_ENABLED)));
if (ast_test_flag(&global_jbconf, AST_JB_ENABLED)) {
ast_cli(a->fd, " Jitterbuffer forced: %s\n", AST_CLI_YESNO(ast_test_flag(&global_jbconf, AST_JB_FORCED)));
ast_cli(a->fd, " Jitterbuffer max size: %ld\n", global_jbconf.max_size);
ast_cli(a->fd, " Jitterbuffer resync: %ld\n", global_jbconf.resync_threshold);
ast_cli(a->fd, " Jitterbuffer impl: %s\n", global_jbconf.impl);
if (!strcasecmp(global_jbconf.impl, "adaptive")) {
ast_cli(a->fd, " Jitterbuffer tgt extra: %ld\n", global_jbconf.target_extra);
}
ast_cli(a->fd, " Jitterbuffer log: %s\n", AST_CLI_YESNO(ast_test_flag(&global_jbconf, AST_JB_LOG)));
}
return CLI_SUCCESS;
}
| static int handle_soft_key_event_message | ( | struct skinny_req * | req, |
| struct skinnysession * | s | ||
| ) | [static] |
Definition at line 5765 of file chan_skinny.c.
References ast_channel::_state, skinny_line::activesub, 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, errno, ast_channel::exten, find_line_by_instance(), find_subchannel_by_instance_reference(), handle_callforward_button(), handle_hold_button(), handle_transfer_button(), soft_key_event_message::instance, KEYDEF_CONNECTED, KEYDEF_OFFHOOK, KEYDEF_ONHOLD, KEYDEF_ONHOOK, KEYDEF_RINGOUT, letohl, LOG_WARNING, skinny_subchannel::onhold, skinny_subchannel::outgoing, skinny_subchannel::owner, skinny_subchannel::parent, 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_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, transmit_activatecallplane(), transmit_callstate(), transmit_clear_display_message(), transmit_clearpromptmessage(), transmit_closereceivechannel(), transmit_displaynotify(), transmit_lamp_indication(), transmit_ringer_mode(), transmit_selectsoftkeys(), transmit_speaker_mode(), transmit_start_tone(), transmit_stop_tone(), transmit_stopmediatransmission(), and skinny_subchannel::xferor.
Referenced by handle_message().
{
struct skinny_device *d = s->device;
struct skinny_line *l;
struct skinny_subchannel *sub = NULL;
struct ast_channel *c;
pthread_t t;
int event;
int instance;
int callreference;
event = letohl(req->data.softkeyeventmessage.softKeyEvent);
instance = letohl(req->data.softkeyeventmessage.instance);
callreference = letohl(req->data.softkeyeventmessage.callreference);
if (instance) {
l = find_line_by_instance(d, instance);
if (callreference) {
sub = find_subchannel_by_instance_reference(d, instance, callreference);
} else {
sub = find_subchannel_by_instance_reference(d, instance, d->lastcallreference);
}
} else {
l = find_line_by_instance(d, d->lastlineinstance);
}
if (!l) {
if (skinnydebug)
ast_verb(1, "Received Softkey Event: %d(%d/%d)\n", event, instance, callreference);
return 0;
}
ast_devstate_changed(AST_DEVICE_INUSE, "Skinny/%s@%s", l->name, d->name);
switch(event) {
case SOFTKEY_NONE:
if (skinnydebug)
ast_verb(1, "Received Softkey Event: None(%d/%d)\n", instance, callreference);
break;
case SOFTKEY_REDIAL:
if (skinnydebug)
ast_verb(1, "Received Softkey Event: Redial(%d/%d)\n", instance, callreference);
if (ast_strlen_zero(l->lastnumberdialed)) {
ast_log(LOG_WARNING, "Attempted redial, but no previously dialed number found. Ignoring button.\n");
break;
}
if (!sub || !sub->owner) {
c = skinny_new(l, AST_STATE_DOWN, NULL);
} else {
c = sub->owner;
}
if (!c) {
ast_log(LOG_WARNING, "Unable to create channel for %s@%s\n", l->name, d->name);
} else {
sub = c->tech_pvt;
l->activesub = sub;
if (l->hookstate == SKINNY_ONHOOK) {
l->hookstate = SKINNY_OFFHOOK;
transmit_speaker_mode(d, SKINNY_SPEAKERON);
transmit_callstate(d, l->instance, sub->callid, SKINNY_OFFHOOK);
transmit_activatecallplane(d, l);
}
transmit_clear_display_message(d, l->instance, sub->callid);
transmit_start_tone(d, SKINNY_DIALTONE, l->instance, sub->callid);
transmit_selectsoftkeys(d, l->instance, sub->callid, KEYDEF_RINGOUT);
if (!ast_ignore_pattern(c->context, l->lastnumberdialed)) {
transmit_stop_tone(d, l->instance, sub->callid);
}
ast_copy_string(c->exten, l->lastnumberdialed, sizeof(c->exten));
if (ast_pthread_create(&t, NULL, skinny_newcall, c)) {
ast_log(LOG_WARNING, "Unable to create new call thread: %s\n", strerror(errno));
ast_hangup(c);
}
}
break;
case SOFTKEY_NEWCALL: /* Actually the DIAL softkey */
if (skinnydebug)
ast_verb(1, "Received Softkey Event: New Call(%d/%d)\n", instance, callreference);
/* New Call ALWAYS gets a new sub-channel */
c = skinny_new(l, AST_STATE_DOWN, NULL);
sub = c->tech_pvt;
/* transmit_ringer_mode(d, SKINNY_RING_OFF);
transmit_lamp_indication(d, STIMULUS_LINE, l->instance, SKINNY_LAMP_ON); */
/* l->hookstate = SKINNY_OFFHOOK; */
if (!c) {
ast_log(LOG_WARNING, "Unable to create channel for %s@%s\n", l->name, d->name);
} else {
sub = c->tech_pvt;
l->activesub = sub;
if (l->hookstate == SKINNY_ONHOOK) {
l->hookstate = SKINNY_OFFHOOK;
transmit_speaker_mode(d, SKINNY_SPEAKERON);
}
ast_verb(1, "Call-id: %d\n", sub->callid);
transmit_callstate(d, l->instance, sub->callid, SKINNY_OFFHOOK);
transmit_activatecallplane(d, l);
transmit_clear_display_message(d, l->instance, sub->callid);
transmit_start_tone(d, SKINNY_DIALTONE, l->instance, sub->callid);
transmit_selectsoftkeys(d, l->instance, sub->callid, KEYDEF_OFFHOOK);
/* start the switch thread */
if (ast_pthread_create(&t, NULL, skinny_ss, c)) {
ast_log(LOG_WARNING, "Unable to create switch thread: %s\n", strerror(errno));
ast_hangup(c);
}
}
break;
case SOFTKEY_HOLD:
if (skinnydebug)
ast_verb(1, "Received Softkey Event: Hold(%d/%d)\n", instance, callreference);
handle_hold_button(sub);
break;
case SOFTKEY_TRNSFER:
if (skinnydebug)
ast_verb(1, "Received Softkey Event: Transfer(%d/%d)\n", instance, callreference);
if (l->transfer)
handle_transfer_button(sub);
else
transmit_displaynotify(d, "Transfer disabled", 10);
break;
case SOFTKEY_DND:
if (skinnydebug)
ast_verb(1, "Received Softkey Event: DND(%d/%d)\n", instance, callreference);
/* Do not disturb */
if (l->dnd != 0){
ast_verb(3, "Disabling DND on %s@%s\n", l->name, d->name);
l->dnd = 0;
transmit_lamp_indication(d, STIMULUS_DND, 1, SKINNY_LAMP_ON);
transmit_displaynotify(d, "DnD disabled", 10);
} else {
ast_verb(3, "Enabling DND on %s@%s\n", l->name, d->name);
l->dnd = 1;
transmit_lamp_indication(d, STIMULUS_DND, 1, SKINNY_LAMP_OFF);
transmit_displaynotify(d, "DnD enabled", 10);
}
break;
case SOFTKEY_CFWDALL:
if (skinnydebug)
ast_verb(1, "Received Softkey Event: Forward All(%d/%d)\n", instance, callreference);
if (!sub || !sub->owner) {
c = skinny_new(l, AST_STATE_DOWN, NULL);
} else {
c = sub->owner;
}
if (!c) {
ast_log(LOG_WARNING, "Unable to create channel for %s@%s\n", l->name, d->name);
} else {
sub = c->tech_pvt;
l->activesub = sub;
handle_callforward_button(sub, SKINNY_CFWD_ALL);
}
break;
case SOFTKEY_CFWDBUSY:
if (skinnydebug)
ast_verb(1, "Received Softkey Event: Forward Busy (%d/%d)\n", instance, callreference);
if (!sub || !sub->owner) {
c = skinny_new(l, AST_STATE_DOWN, NULL);
} else {
c = sub->owner;
}
if (!c) {
ast_log(LOG_WARNING, "Unable to create channel for %s@%s\n", l->name, d->name);
} else {
sub = c->tech_pvt;
l->activesub = sub;
handle_callforward_button(sub, SKINNY_CFWD_BUSY);
}
break;
case SOFTKEY_CFWDNOANSWER:
if (skinnydebug)
ast_verb(1, "Received Softkey Event: Forward No Answer (%d/%d)\n", instance, callreference);
#if 0 /* Not sure how to handle this yet */
if (!sub || !sub->owner) {
c = skinny_new(l, AST_STATE_DOWN, NULL);
} else {
c = sub->owner;
}
if (!c) {
ast_log(LOG_WARNING, "Unable to create channel for %s@%s\n", l->name, d->name);
} else {
sub = c->tech_pvt;
l->activesub = sub;
handle_callforward_button(sub, SKINNY_CFWD_NOANSWER);
}
#endif
break;
case SOFTKEY_BKSPC:
if (skinnydebug)
ast_verb(1, "Received Softkey Event: Backspace(%d/%d)\n", instance, callreference);
break;
case SOFTKEY_ENDCALL:
if (skinnydebug)
ast_verb(1, "Received Softkey Event: End Call(%d/%d)\n", instance, callreference);
if (l->hookstate == SKINNY_ONHOOK) {
/* Something else already put us back on hook */
break;
}
if (sub) {
int onlysub = 0;
if (!AST_LIST_NEXT(sub, list)) {
onlysub = 1;
} else {
AST_LIST_REMOVE(&l->sub, sub, list);
}
sub->cxmode = SKINNY_CX_RECVONLY;
if (onlysub || sub->xferor){ /*Are there other calls to this device */
l->hookstate = SKINNY_ONHOOK;
if (skinnydebug)
ast_debug(1, "Skinny %s@%s-%d went on hook\n", l->name, d->name, callreference);
}
if (l->hookstate == SKINNY_ONHOOK) {
transmit_closereceivechannel(d, sub);
transmit_stopmediatransmission(d, sub);
transmit_speaker_mode(d, SKINNY_SPEAKEROFF);
transmit_clearpromptmessage(d, instance, sub->callid);
transmit_callstate(d, l->instance, sub->callid, SKINNY_ONHOOK);
transmit_selectsoftkeys(d, 0, 0, KEYDEF_ONHOOK);
transmit_activatecallplane(d, l);
} else if (l->hookstate == SKINNY_OFFHOOK) {
transmit_callstate(d, l->instance, sub->callid, SKINNY_OFFHOOK);
transmit_activatecallplane(d, l);
} else {
transmit_callstate(d, l->instance, sub->callid, l->hookstate);
}
ast_devstate_changed(AST_DEVICE_NOT_INUSE, "Skinny/%s@%s", l->name, d->name);
if (skinnydebug)
ast_verb(1, "Skinny %s@%s went on hook\n", l->name, d->name);
if (l->transfer && sub->xferor && sub->owner->_state >= AST_STATE_RING) {
/* We're allowed to transfer, we have two active calls and
we made at least one of the calls. Let's try and transfer */
handle_transfer_button(sub);
} else {
/* Hangup the current call */
/* If there is another active call, skinny_hangup will ring the phone with the other call */
if (sub->xferor && sub->related){
sub->related->related = NULL;
sub->related->blindxfer = 0;
}
if (sub->owner) {
sub->alreadygone = 1;
ast_queue_hangup(sub->owner);
} else {
ast_log(LOG_WARNING, "Skinny(%s@%s-%d) channel already destroyed\n",
l->name, d->name, sub->callid);
}
}
if ((l->hookstate == SKINNY_ONHOOK) && (AST_LIST_NEXT(sub, list) && !AST_LIST_NEXT(sub, list)->rtp)) {
ast_devstate_changed(AST_DEVICE_NOT_INUSE, "Skinny/%s@%s", l->name, d->name);
}
}
break;
case SOFTKEY_RESUME:
if (skinnydebug)
ast_verb(1, "Received Softkey Event: Resume(%d/%d)\n", instance, callreference);
if (sub) {
if (sub->onhold) {
skinny_unhold(sub);
transmit_selectsoftkeys(d, l->instance, sub->callid, KEYDEF_CONNECTED);
} else {
skinny_hold(sub);
transmit_selectsoftkeys(d, l->instance, sub->callid, KEYDEF_ONHOLD);
}
}
break;
case SOFTKEY_ANSWER:
if (skinnydebug)
ast_verb(1, "Received Softkey Event: Answer(%d/%d)\n", instance, callreference);
transmit_ringer_mode(d, SKINNY_RING_OFF);
transmit_lamp_indication(d, STIMULUS_LINE, l->instance, SKINNY_LAMP_ON);
if (l->hookstate == SKINNY_ONHOOK) {
transmit_speaker_mode(d, SKINNY_SPEAKERON);
l->hookstate = SKINNY_OFFHOOK;
}
if (sub && sub->outgoing) {
/* We're answering a ringing call */
ast_queue_control(sub->owner, AST_CONTROL_ANSWER);
transmit_callstate(d, l->instance, sub->callid, SKINNY_OFFHOOK);
transmit_activatecallplane(d, l);
transmit_stop_tone(d, l->instance, sub->callid);
transmit_callstate(d, sub->parent->instance, sub->callid, SKINNY_CONNECTED);
transmit_selectsoftkeys(d, l->instance, sub->callid, KEYDEF_CONNECTED);
start_rtp(sub);
ast_setstate(sub->owner, AST_STATE_UP);
}
break;
case SOFTKEY_INFO:
if (skinnydebug)
ast_verb(1, "Received Softkey Event: Info(%d/%d)\n", instance, callreference);
break;
case SOFTKEY_CONFRN:
if (skinnydebug)
ast_verb(1, "Received Softkey Event: Conference(%d/%d)\n", instance, callreference);
/* XXX determine the best way to pull off a conference. Meetme? */
break;
case SOFTKEY_PARK:
{
int extout;
char message[32];
if (skinnydebug)
ast_verb(1, "Received Softkey Event: Park Call(%d/%d)\n", instance, callreference);
if ((sub && sub->owner) && (sub->owner->_state == AST_STATE_UP)){
c = sub->owner;
if (ast_bridged_channel(c)) {
if (!ast_masq_park_call(ast_bridged_channel(c), c, 0, &extout)) {
snprintf(message, sizeof(message), "Call Parked at: %d", extout);
transmit_displaynotify(d, message, 10);
} else {
transmit_displaynotify(d, "Call Park failed", 10);
}
} else {
transmit_displaynotify(d, "Call Park not available", 10);
}
} else {
transmit_displaynotify(d, "Call Park not available", 10);
}
break;
}
case SOFTKEY_JOIN:
if (skinnydebug)
ast_verb(1, "Received Softkey Event: Join(%d/%d)\n", instance, callreference);
break;
case SOFTKEY_MEETME:
/* XXX How is this different from CONFRN? */
if (skinnydebug)
ast_verb(1, "Received Softkey Event: Meetme(%d/%d)\n", instance, callreference);
break;
case SOFTKEY_PICKUP:
if (skinnydebug)
ast_verb(1, "Received Softkey Event: Pickup(%d/%d)\n", instance, callreference);
break;
case SOFTKEY_GPICKUP:
if (skinnydebug)
ast_verb(1, "Received Softkey Event: Group Pickup(%d/%d)\n", instance, callreference);
break;
default:
if (skinnydebug)
ast_verb(1, "Received unknown Softkey Event: %d(%d/%d)\n", event, instance, callreference);
break;
}
return 1;
}
| static int handle_stimulus_message | ( | struct skinny_req * | req, |
| struct skinnysession * | s | ||
| ) | [static] |
Definition at line 4937 of file chan_skinny.c.
References ast_channel::_state, skinny_device::activeline, skinny_line::activesub, 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, ast_channel::context, skinny_req::data, skinnysession::device, errno, ast_channel::exten, skinny_speeddial::exten, find_line_by_instance(), find_speeddial_by_instance(), find_subchannel_by_instance_reference(), handle_callforward_button(), handle_hold_button(), handle_transfer_button(), KEYDEF_CONNECTED, KEYDEF_OFFHOOK, KEYDEF_ONHOOK, KEYDEF_RINGOUT, letohl, LOG_WARNING, ast_channel::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_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, transmit_activatecallplane(), transmit_callstate(), transmit_clear_display_message(), transmit_clearpromptmessage(), transmit_closereceivechannel(), transmit_displaynotify(), transmit_displaypromptstatus(), transmit_lamp_indication(), transmit_ringer_mode(), transmit_selectsoftkeys(), transmit_speaker_mode(), transmit_start_tone(), transmit_stop_tone(), and transmit_stopmediatransmission().
Referenced by handle_message().
{
struct skinny_device *d = s->device;
struct skinny_line *l;
struct skinny_subchannel *sub;
/*struct skinny_speeddial *sd;*/
struct ast_channel *c;
pthread_t t;
int event;
int instance;
int callreference;
/*int res = 0;*/
event = letohl(req->data.stimulus.stimulus);
instance = letohl(req->data.stimulus.stimulusInstance);
callreference = letohl(req->data.stimulus.callreference);
if (skinnydebug)
ast_verb(1, "callreference in handle_stimulus_message is '%d'\n", callreference);
/* Note that this call should be using the passed in instance and callreference */
sub = find_subchannel_by_instance_reference(d, d->lastlineinstance, d->lastcallreference);
if (!sub) {
l = find_line_by_instance(d, d->lastlineinstance);
if (!l) {
return 0;
}
sub = l->activesub;
} else {
l = sub->parent;
}
switch(event) {
case STIMULUS_REDIAL:
if (skinnydebug)
ast_verb(1, "Received Stimulus: Redial(%d/%d)\n", instance, callreference);
if (ast_strlen_zero(l->lastnumberdialed)) {
ast_log(LOG_WARNING, "Attempted redial, but no previously dialed number found.\n");
l->hookstate = SKINNY_ONHOOK;
transmit_speaker_mode(d, SKINNY_SPEAKEROFF);
transmit_closereceivechannel(d, sub);
transmit_stopmediatransmission(d, sub);
transmit_speaker_mode(d, SKINNY_SPEAKEROFF);
transmit_clearpromptmessage(d, l->instance, sub->callid);
transmit_callstate(d, l->instance, sub->callid, SKINNY_ONHOOK);
transmit_selectsoftkeys(d, 0, 0, KEYDEF_ONHOOK);
transmit_activatecallplane(d, l);
break;
}
c = skinny_new(l, AST_STATE_DOWN, NULL);
if (!c) {
ast_log(LOG_WARNING, "Unable to create channel for %s@%s\n", l->name, d->name);
} else {
sub = c->tech_pvt;
l = sub->parent;
l->activesub = sub;
if (l->hookstate == SKINNY_ONHOOK) {
l->hookstate = SKINNY_OFFHOOK;
transmit_callstate(d, l->instance, sub->callid, SKINNY_OFFHOOK);
transmit_activatecallplane(d, l);
}
transmit_clear_display_message(d, l->instance, sub->callid);
transmit_start_tone(d, SKINNY_DIALTONE, l->instance, sub->callid);
transmit_selectsoftkeys(d, l->instance, sub->callid, KEYDEF_RINGOUT);
if (!ast_ignore_pattern(c->context, l->lastnumberdialed)) {
transmit_stop_tone(d, l->instance, sub->callid);
}
ast_copy_string(c->exten, l->lastnumberdialed, sizeof(c->exten));
if (ast_pthread_create(&t, NULL, skinny_newcall, c)) {
ast_log(LOG_WARNING, "Unable to create new call thread: %s\n", strerror(errno));
ast_hangup(c);
}
}
break;
case STIMULUS_SPEEDDIAL:
{
struct skinny_speeddial *sd;
if (skinnydebug)
ast_verb(1, "Received Stimulus: SpeedDial(%d/%d)\n", instance, callreference);
if (!(sd = find_speeddial_by_instance(d, instance, 0))) {
return 0;
}
if (!sub || !sub->owner)
c = skinny_new(l, AST_STATE_DOWN, NULL);
else
c = sub->owner;
if (!c) {
ast_log(LOG_WARNING, "Unable to create channel for %s@%s\n", l->name, d->name);
} else {
sub = c->tech_pvt;
l = sub->parent;
l->activesub = sub;
if (l->hookstate == SKINNY_ONHOOK) {
l->hookstate = SKINNY_OFFHOOK;
transmit_speaker_mode(d, SKINNY_SPEAKERON);
transmit_callstate(d, l->instance, sub->callid, SKINNY_OFFHOOK);
transmit_activatecallplane(d, l);
}
transmit_clear_display_message(d, l->instance, sub->callid);
transmit_start_tone(d, SKINNY_DIALTONE, l->instance, sub->callid);
transmit_selectsoftkeys(d, l->instance, sub->callid, KEYDEF_RINGOUT);
if (!ast_ignore_pattern(c->context, sd->exten)) {
transmit_stop_tone(d, l->instance, sub->callid);
}
if (ast_exists_extension(c, c->context, sd->exten, 1, l->cid_num)) {
ast_copy_string(c->exten, sd->exten, sizeof(c->exten));
ast_copy_string(l->lastnumberdialed, sd->exten, sizeof(l->lastnumberdialed));
if (ast_pthread_create(&t, NULL, skinny_newcall, c)) {
ast_log(LOG_WARNING, "Unable to create new call thread: %s\n", strerror(errno));
ast_hangup(c);
}
break;
}
}
}
break;
case STIMULUS_HOLD:
if (skinnydebug)
ast_verb(1, "Received Stimulus: Hold(%d/%d)\n", instance, callreference);
handle_hold_button(sub);
break;
case STIMULUS_TRANSFER:
if (skinnydebug)
ast_verb(1, "Received Stimulus: Transfer(%d/%d)\n", instance, callreference);
if (l->transfer)
handle_transfer_button(sub);
else
transmit_displaynotify(d, "Transfer disabled", 10);
break;
case STIMULUS_CONFERENCE:
if (skinnydebug)
ast_verb(1, "Received Stimulus: Conference(%d/%d)\n", instance, callreference);
/* XXX determine the best way to pull off a conference. Meetme? */
break;
case STIMULUS_VOICEMAIL:
if (skinnydebug)
ast_verb(1, "Received Stimulus: Voicemail(%d/%d)\n", instance, callreference);
if (!sub || !sub->owner) {
c = skinny_new(l, AST_STATE_DOWN, NULL);
} else {
c = sub->owner;
}
if (!c) {
ast_log(LOG_WARNING, "Unable to create channel for %s@%s\n", l->name, d->name);
} else {
sub = c->tech_pvt;
l = sub->parent;
l->activesub = sub;
if (ast_strlen_zero(l->vmexten)) /* Exit the call if no VM pilot */
break;
if (l->hookstate == SKINNY_ONHOOK){
l->hookstate = SKINNY_OFFHOOK;
transmit_speaker_mode(d, SKINNY_SPEAKERON);
transmit_callstate(d, l->instance, sub->callid, SKINNY_OFFHOOK);
transmit_activatecallplane(d, l);
}
transmit_clear_display_message(d, l->instance, sub->callid);
transmit_start_tone(d, SKINNY_DIALTONE, l->instance, sub->callid);
transmit_selectsoftkeys(d, l->instance, sub->callid, KEYDEF_RINGOUT);
if (!ast_ignore_pattern(c->context, l->vmexten)) {
transmit_stop_tone(d, l->instance, sub->callid);
}
if (ast_exists_extension(c, c->context, l->vmexten, 1, l->cid_num)) {
ast_copy_string(c->exten, l->vmexten, sizeof(c->exten));
ast_copy_string(l->lastnumberdialed, l->vmexten, sizeof(l->lastnumberdialed));
if (ast_pthread_create(&t, NULL, skinny_newcall, c)) {
ast_log(LOG_WARNING, "Unable to create new call thread: %s\n", strerror(errno));
ast_hangup(c);
}
break;
}
}
break;
case STIMULUS_CALLPARK:
{
int extout;
char message[32];
if (skinnydebug)
ast_verb(1, "Received Stimulus: Park Call(%d/%d)\n", instance, callreference);
if ((sub && sub->owner) && (sub->owner->_state == AST_STATE_UP)){
c = sub->owner;
if (ast_bridged_channel(c)) {
if (!ast_masq_park_call(ast_bridged_channel(c), c, 0, &extout)) {
snprintf(message, sizeof(message), "Call Parked at: %d", extout);
transmit_displaynotify(d, message, 10);
} else {
transmit_displaynotify(d, "Call Park failed", 10);
}
} else {
transmit_displaynotify(d, "Call Park not available", 10);
}
} else {
transmit_displaynotify(d, "Call Park not available", 10);
}
break;
}
case STIMULUS_DND:
if (skinnydebug)
ast_verb(1, "Received Stimulus: DND (%d/%d)\n", instance, callreference);
/* Do not disturb */
if (l->dnd != 0){
ast_verb(3, "Disabling DND on %s@%s\n", l->name, d->name);
l->dnd = 0;
transmit_lamp_indication(d, STIMULUS_DND, 1, SKINNY_LAMP_ON);
transmit_displaynotify(d, "DnD disabled", 10);
} else {
ast_verb(3, "Enabling DND on %s@%s\n", l->name, d->name);
l->dnd = 1;
transmit_lamp_indication(d, STIMULUS_DND, 1, SKINNY_LAMP_OFF);
transmit_displaynotify(d, "DnD enabled", 10);
}
break;
case STIMULUS_FORWARDALL:
if (skinnydebug)
ast_verb(1, "Received Stimulus: Forward All(%d/%d)\n", instance, callreference);
if (!sub || !sub->owner) {
c = skinny_new(l, AST_STATE_DOWN, NULL);
} else {
c = sub->owner;
}
if (!c) {
ast_log(LOG_WARNING, "Unable to create channel for %s@%s\n", l->name, d->name);
} else {
sub = c->tech_pvt;
handle_callforward_button(sub, SKINNY_CFWD_ALL);
}
break;
case STIMULUS_FORWARDBUSY:
if (skinnydebug)
ast_verb(1, "Received Stimulus: Forward Busy (%d/%d)\n", instance, callreference);
if (!sub || !sub->owner) {
c = skinny_new(l, AST_STATE_DOWN, NULL);
} else {
c = sub->owner;
}
if (!c) {
ast_log(LOG_WARNING, "Unable to create channel for %s@%s\n", l->name, d->name);
} else {
sub = c->tech_pvt;
handle_callforward_button(sub, SKINNY_CFWD_BUSY);
}
break;
case STIMULUS_FORWARDNOANSWER:
if (skinnydebug)
ast_verb(1, "Received Stimulus: Forward No Answer (%d/%d)\n", instance, callreference);
#if 0 /* Not sure how to handle this yet */
if (!sub || !sub->owner) {
c = skinny_new(l, AST_STATE_DOWN, NULL);
} else {
c = sub->owner;
}
if (!c) {
ast_log(LOG_WARNING, "Unable to create channel for %s@%s\n", l->name, d->name);
} else {
sub = c->tech_pvt;
handle_callforward_button(sub, SKINNY_CFWD_NOANSWER);
}
#endif
break;
case STIMULUS_DISPLAY:
/* Not sure what this is */
if (skinnydebug)
ast_verb(1, "Received Stimulus: Display(%d/%d)\n", instance, callreference);
break;
case STIMULUS_LINE:
if (skinnydebug)
ast_verb(1, "Received Stimulus: Line(%d/%d)\n", instance, callreference);
l = find_line_by_instance(d, instance);
if (!l) {
return 0;
}
d->activeline = l;
/* turn the speaker on */
transmit_speaker_mode(d, SKINNY_SPEAKERON);
transmit_ringer_mode(d, SKINNY_RING_OFF);
transmit_lamp_indication(d, STIMULUS_LINE, l->instance, SKINNY_LAMP_ON);
l->hookstate = SKINNY_OFFHOOK;
if (sub && sub->outgoing) {
/* We're answering a ringing call */
ast_queue_control(sub->owner, AST_CONTROL_ANSWER);
transmit_callstate(d, l->instance, sub->callid, SKINNY_OFFHOOK);
transmit_activatecallplane(d, l);
transmit_stop_tone(d, l->instance, sub->callid);
transmit_callstate(d, sub->parent->instance, sub->callid, SKINNY_CONNECTED);
transmit_displaypromptstatus(d, "Connected", 0, l->instance, sub->callid);
transmit_selectsoftkeys(d, l->instance, sub->callid, KEYDEF_CONNECTED);
start_rtp(sub);
ast_setstate(sub->owner, AST_STATE_UP);
} else {
if (sub && sub->owner) {
ast_debug(1, "Current subchannel [%s] already has owner\n", sub->owner->name);
} else {
c = skinny_new(l, AST_STATE_DOWN, NULL);
if (c) {
sub = c->tech_pvt;
l->activesub = sub;
transmit_callstate(d, l->instance, sub->callid, SKINNY_OFFHOOK);
transmit_activatecallplane(d, l);
transmit_clear_display_message(d, l->instance, sub->callid);
transmit_start_tone(d, SKINNY_DIALTONE, l->instance, sub->callid);
transmit_selectsoftkeys(d, l->instance, sub->callid, KEYDEF_OFFHOOK);
/* start the switch thread */
if (ast_pthread_create(&t, NULL, skinny_ss, c)) {
ast_log(LOG_WARNING, "Unable to create switch thread: %s\n", strerror(errno));
ast_hangup(c);
}
} else {
ast_log(LOG_WARNING, "Unable to create channel for %s@%s\n", l->name, d->name);
}
}
}
break;
default:
if (skinnydebug)
ast_verb(1, "RECEIVED UNKNOWN STIMULUS: %d(%d/%d)\n", event, instance, callreference);
break;
}
ast_devstate_changed(AST_DEVICE_UNKNOWN, "Skinny/%s@%s", l->name, d->name);
return 1;
}
| static int handle_transfer_button | ( | struct skinny_subchannel * | sub | ) | [static] |
Definition at line 4677 of file chan_skinny.c.
References ast_channel::_state, skinny_line::activesub, ast_hangup(), ast_log(), ast_pthread_create, AST_STATE_DOWN, ast_verbose(), skinny_subchannel::blindxfer, skinny_subchannel::callid, skinny_line::device, errno, KEYDEF_OFFHOOKWITHFEAT, LOG_WARNING, skinny_subchannel::onhold, skinny_subchannel::owner, skinny_subchannel::parent, skinny_subchannel::related, SKINNY_DIALTONE, skinny_hold(), skinny_new(), SKINNY_OFFHOOK, skinny_ss(), skinny_transfer(), ast_channel::tech_pvt, transmit_activatecallplane(), transmit_callstate(), transmit_clear_display_message(), transmit_selectsoftkeys(), transmit_start_tone(), and skinny_subchannel::xferor.
Referenced by handle_onhook_message(), handle_soft_key_event_message(), and handle_stimulus_message().
{
struct skinny_line *l;
struct skinny_device *d;
struct skinny_subchannel *newsub;
struct ast_channel *c;
pthread_t t;
if (!sub) {
ast_verbose("Transfer: No subchannel to transfer\n");
return -1;
}
l = sub->parent;
d = l->device;
if (!sub->related) {
/* Another sub has not been created so this must be first XFER press */
if (!sub->onhold) {
skinny_hold(sub);
}
c = skinny_new(l, AST_STATE_DOWN, NULL);
if (c) {
newsub = c->tech_pvt;
/* point the sub and newsub at each other so we know they are related */
newsub->related = sub;
sub->related = newsub;
newsub->xferor = 1;
l->activesub = newsub;
transmit_callstate(d, l->instance, sub->callid, SKINNY_OFFHOOK);
transmit_activatecallplane(d, l);
transmit_clear_display_message(d, l->instance, newsub->callid);
transmit_start_tone(d, SKINNY_DIALTONE, l->instance, newsub->callid);
transmit_selectsoftkeys(d, l->instance, newsub->callid, KEYDEF_OFFHOOKWITHFEAT);
/* start the switch thread */
if (ast_pthread_create(&t, NULL, skinny_ss, c)) {
ast_log(LOG_WARNING, "Unable to create switch thread: %s\n", strerror(errno));
ast_hangup(c);
}
} else {
ast_log(LOG_WARNING, "Unable to create channel for %s@%s\n", l->name, d->name);
}
} else {
/* We already have a related sub so we can either complete XFER or go into BLINDXFER (or cancel BLINDXFER */
if (sub->blindxfer) {
/* toggle blindxfer off */
sub->blindxfer = 0;
sub->related->blindxfer = 0;
/* we really need some indications */
} else {
/* We were doing attended transfer */
if (sub->owner->_state == AST_STATE_DOWN || sub->related->owner->_state == AST_STATE_DOWN) {
/* one of the subs so we cant transfer yet, toggle blindxfer on */
sub->blindxfer = 1;
sub->related->blindxfer = 1;
} else {
/* big assumption we have two channels, lets transfer */
skinny_transfer(sub);
}
}
}
return 0;
}
| static int load_module | ( | void | ) | [static] |
Definition at line 7433 of file chan_skinny.c.
References ARRAY_LEN, ast_channel_register(), ast_cli_register_multiple(), ast_log(), ast_manager_register_xml, AST_MODULE_LOAD_DECLINE, AST_MODULE_LOAD_SUCCESS, ast_rtp_glue_register, cli_skinny, config_load(), EVENT_FLAG_REPORTING, EVENT_FLAG_SYSTEM, htolel, io_context_create(), LOG_ERROR, LOG_WARNING, manager_skinny_show_device(), manager_skinny_show_devices(), manager_skinny_show_line(), manager_skinny_show_lines(), skinny_req::res, restart_monitor(), sched_context_create(), skinny_rtp_glue, skinny_tech, and soft_key_template_definition::softKeyEvent.
{
int res = 0;
for (; res < ARRAY_LEN(soft_key_template_default); res++) {
soft_key_template_default[res].softKeyEvent = htolel(soft_key_template_default[res].softKeyEvent);
}
/* load and parse config */
res = config_load();
if (res == -1) {
return AST_MODULE_LOAD_DECLINE;
}
/* Make sure we can register our skinny channel type */
if (ast_channel_register(&skinny_tech)) {
ast_log(LOG_ERROR, "Unable to register channel class 'Skinny'\n");
return -1;
}
ast_rtp_glue_register(&skinny_rtp_glue);
ast_cli_register_multiple(cli_skinny, ARRAY_LEN(cli_skinny));
ast_manager_register_xml("SKINNYdevices", EVENT_FLAG_SYSTEM | EVENT_FLAG_REPORTING, manager_skinny_show_devices);
ast_manager_register_xml("SKINNYshowdevice", EVENT_FLAG_SYSTEM | EVENT_FLAG_REPORTING, manager_skinny_show_device);
ast_manager_register_xml("SKINNYlines", EVENT_FLAG_SYSTEM | EVENT_FLAG_REPORTING, manager_skinny_show_lines);
ast_manager_register_xml("SKINNYshowline", EVENT_FLAG_SYSTEM | EVENT_FLAG_REPORTING, manager_skinny_show_line);
sched = sched_context_create();
if (!sched) {
ast_log(LOG_WARNING, "Unable to create schedule context\n");
}
io = io_context_create();
if (!io) {
ast_log(LOG_WARNING, "Unable to create I/O context\n");
}
/* And start the monitor for the first time */
restart_monitor();
return AST_MODULE_LOAD_SUCCESS;
}
| static int manager_skinny_show_device | ( | struct mansession * | s, |
| const struct message * | m | ||
| ) | [static] |
Definition at line 3343 of file chan_skinny.c.
References _skinny_show_device(), ast_strlen_zero(), astman_append(), astman_get_header(), and astman_send_error().
Referenced by load_module().
{
const char *a[4];
const char *device;
device = astman_get_header(m, "Device");
if (ast_strlen_zero(device)) {
astman_send_error(s, m, "Device: <name> missing.");
return 0;
}
a[0] = "skinny";
a[1] = "show";
a[2] = "device";
a[3] = device;
_skinny_show_device(1, -1, s, m, 4, a);
astman_append(s, "\r\n\r\n" );
return 0;
}
| static int manager_skinny_show_devices | ( | struct mansession * | s, |
| const struct message * | m | ||
| ) | [static] |
Show SKINNY devices in the manager API.
Definition at line 3207 of file chan_skinny.c.
References _skinny_show_devices(), ast_strlen_zero(), astman_append(), astman_get_header(), astman_send_listack(), and total.
Referenced by load_module().
{
const char *id = astman_get_header(m, "ActionID");
const char *a[] = {"skinny", "show", "devices"};
char idtext[256] = "";
int total = 0;
if (!ast_strlen_zero(id))
snprintf(idtext, sizeof(idtext), "ActionID: %s\r\n", id);
astman_send_listack(s, m, "Device status list will follow", "start");
/* List the devices in separate manager events */
_skinny_show_devices(-1, &total, s, m, 3, a);
/* Send final confirmation */
astman_append(s,
"Event: DevicelistComplete\r\n"
"EventList: Complete\r\n"
"ListItems: %d\r\n"
"%s"
"\r\n", total, idtext);
return 0;
}
| static int manager_skinny_show_line | ( | struct mansession * | s, |
| const struct message * | m | ||
| ) | [static] |
Definition at line 3636 of file chan_skinny.c.
References _skinny_show_line(), ast_strlen_zero(), astman_append(), astman_get_header(), and astman_send_error().
Referenced by load_module().
{
const char *a[4];
const char *line;
line = astman_get_header(m, "Line");
if (ast_strlen_zero(line)) {
astman_send_error(s, m, "Line: <name> missing.");
return 0;
}
a[0] = "skinny";
a[1] = "show";
a[2] = "line";
a[3] = line;
_skinny_show_line(1, -1, s, m, 4, a);
astman_append(s, "\r\n\r\n" );
return 0;
}
| static int manager_skinny_show_lines | ( | struct mansession * | s, |
| const struct message * | m | ||
| ) | [static] |
Show Skinny lines in the manager API.
Definition at line 3455 of file chan_skinny.c.
References _skinny_show_lines(), ast_strlen_zero(), astman_append(), astman_get_header(), astman_send_listack(), and total.
Referenced by load_module().
{
const char *id = astman_get_header(m, "ActionID");
const char *a[] = {"skinny", "show", "lines"};
char idtext[256] = "";
int total = 0;
if (!ast_strlen_zero(id))
snprintf(idtext, sizeof(idtext), "ActionID: %s\r\n", id);
astman_send_listack(s, m, "Line status list will follow", "start");
/* List the lines in separate manager events */
_skinny_show_lines(-1, &total, s, m, 3, a);
/* Send final confirmation */
astman_append(s,
"Event: LinelistComplete\r\n"
"EventList: Complete\r\n"
"ListItems: %d\r\n"
"%s"
"\r\n", total, idtext);
return 0;
}
| static void mwi_event_cb | ( | const struct ast_event * | event, |
| void * | userdata | ||
| ) | [static] |
Definition at line 2726 of file chan_skinny.c.
References ast_event_get_ie_uint(), AST_EVENT_IE_NEWMSGS, AST_LIST_TRAVERSE, ast_verb, skinny_line::device, skinny_device::lines, skinny_line::newmsgs, skinny_device::session, SKINNY_LAMP_BLINK, SKINNY_LAMP_OFF, SKINNY_LAMP_ON, STIMULUS_VOICEMAIL, and transmit_lamp_indication().
Referenced by config_line(), and skinny_register().
{
struct skinny_line *l = userdata;
struct skinny_device *d = l->device;
if (d) {
struct skinnysession *s = d->session;
struct skinny_line *l2;
int new_msgs = 0;
int dev_msgs = 0;
if (s) {
if (event) {
l->newmsgs = ast_event_get_ie_uint(event, AST_EVENT_IE_NEWMSGS);
}
if (l->newmsgs) {
transmit_lamp_indication(d, STIMULUS_VOICEMAIL, l->instance, l->mwiblink?SKINNY_LAMP_BLINK:SKINNY_LAMP_ON);
} else {
transmit_lamp_indication(d, STIMULUS_VOICEMAIL, l->instance, SKINNY_LAMP_OFF);
}
/* find out wether the device lamp should be on or off */
AST_LIST_TRAVERSE(&d->lines, l2, list) {
if (l2->newmsgs) {
dev_msgs++;
}
}
if (dev_msgs) {
transmit_lamp_indication(d, STIMULUS_VOICEMAIL, 0, d->mwiblink?SKINNY_LAMP_BLINK:SKINNY_LAMP_ON);
} else {
transmit_lamp_indication(d, STIMULUS_VOICEMAIL, 0, SKINNY_LAMP_OFF);
}
ast_verb(3, "Skinny mwi_event_cb found %d new messages\n", new_msgs);
}
}
}
| 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 3119 of file chan_skinny.c.
References ast_cli(), ast_codec_pref_index(), ast_getformatname(), and ast_codec_pref::framing.
Referenced by _skinny_show_line().
{
int x, codec;
for(x = 0; x < 32 ; x++) {
codec = ast_codec_pref_index(pref, x);
if (!codec)
break;
ast_cli(fd, "%s", ast_getformatname(codec));
ast_cli(fd, ":%d", pref->framing[x]);
if (x < 31 && ast_codec_pref_index(pref, x + 1))
ast_cli(fd, ",");
}
if (!x)
ast_cli(fd, "none");
}
| static void register_exten | ( | struct skinny_line * | l | ) | [static] |
Definition at line 1821 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(), context, ext, LOG_WARNING, regcontext, S_OR, and strsep().
Referenced by skinny_register().
{
char multi[256];
char *stringp, *ext, *context;
if (ast_strlen_zero(regcontext))
return;
ast_copy_string(multi, S_OR(l->regexten, l->name), sizeof(multi));
stringp = multi;
while ((ext = strsep(&stringp, "&"))) {
if ((context = strchr(ext, '@'))) {
*context++ = '\0'; /* split ext@context */
if (!ast_context_find(context)) {
ast_log(LOG_WARNING, "Context %s must exist in regcontext= in skinny.conf!\n", context);
continue;
}
} else {
context = regcontext;
}
ast_add_extension(context, 1, ext, 1, NULL, NULL, "Noop",
ast_strdup(l->name), ast_free_ptr, "Skinny");
}
}
| static int reload | ( | void | ) | [static] |
Definition at line 7551 of file chan_skinny.c.
References skinny_reload().
{
skinny_reload();
return 0;
}
| static struct skinny_req* req_alloc | ( | size_t | size, |
| int | response_message | ||
| ) | [static, read] |
Definition at line 1552 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_register_message(), handle_skinny_reset(), skinny_reload(), transmit_activatecallplane(), transmit_callinfo(), transmit_callstate(), transmit_cfwdstate(), transmit_clear_display_message(), transmit_clearpromptmessage(), transmit_closereceivechannel(), transmit_connect(), transmit_definetimedate(), transmit_dialednumber(), transmit_displaynotify(), transmit_displaypromptstatus(), transmit_lamp_indication(), transmit_linestatres(), transmit_ringer_mode(), transmit_selectsoftkeys(), transmit_serverres(), transmit_softkeysetres(), transmit_softkeytemplateres(), transmit_speaker_mode(), transmit_speeddialstatres(), transmit_start_tone(), transmit_startmediatransmission(), transmit_stop_tone(), transmit_stopmediatransmission(), and transmit_versionres().
{
struct skinny_req *req;
if (!(req = ast_calloc(1, skinny_header_size + size + 4)))
return NULL;
req->len = htolel(size+4);
req->e = htolel(response_message);
return req;
}
| static int restart_monitor | ( | void | ) | [static] |
Definition at line 6584 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().
{
/* If we're supposed to be stopped -- stay stopped */
if (monitor_thread == AST_PTHREADT_STOP)
return 0;
ast_mutex_lock(&monlock);
if (monitor_thread == pthread_self()) {
ast_mutex_unlock(&monlock);
ast_log(LOG_WARNING, "Cannot kill myself\n");
return -1;
}
if (monitor_thread != AST_PTHREADT_NULL) {
/* Wake up the thread */
pthread_kill(monitor_thread, SIGURG);
} else {
/* Start a new monitor */
if (ast_pthread_create_background(&monitor_thread, NULL, do_monitor, NULL) < 0) {
ast_mutex_unlock(&monlock);
ast_log(LOG_ERROR, "Unable to start monitor thread.\n");
return -1;
}
}
ast_mutex_unlock(&monlock);
return 0;
}
| static int set_callforwards | ( | struct skinny_line * | l, |
| const char * | cfwd, | ||
| int | cfwdtype | ||
| ) | [static] |
Definition at line 1763 of file chan_skinny.c.
References ast_copy_string(), ast_strlen_zero(), SKINNY_CFWD_ALL, SKINNY_CFWD_BUSY, and SKINNY_CFWD_NOANSWER.
Referenced by handle_callforward_button(), skinny_register(), and skinny_ss().
{
if (!l)
return 0;
if (!ast_strlen_zero(cfwd)) {
if (cfwdtype & SKINNY_CFWD_ALL) {
l->cfwdtype |= SKINNY_CFWD_ALL;
ast_copy_string(l->call_forward_all, cfwd, sizeof(l->call_forward_all));
}
if (cfwdtype & SKINNY_CFWD_BUSY) {
l->cfwdtype |= SKINNY_CFWD_BUSY;
ast_copy_string(l->call_forward_busy, cfwd, sizeof(l->call_forward_busy));
}
if (cfwdtype & SKINNY_CFWD_NOANSWER) {
l->cfwdtype |= SKINNY_CFWD_NOANSWER;
ast_copy_string(l->call_forward_noanswer, cfwd, sizeof(l->call_forward_noanswer));
}
} else {
if (cfwdtype & SKINNY_CFWD_ALL) {
l->cfwdtype &= ~SKINNY_CFWD_ALL;
memset(l->call_forward_all, 0, sizeof(l->call_forward_all));
}
if (cfwdtype & SKINNY_CFWD_BUSY) {
l->cfwdtype &= ~SKINNY_CFWD_BUSY;
memset(l->call_forward_busy, 0, sizeof(l->call_forward_busy));
}
if (cfwdtype & SKINNY_CFWD_NOANSWER) {
l->cfwdtype &= ~SKINNY_CFWD_NOANSWER;
memset(l->call_forward_noanswer, 0, sizeof(l->call_forward_noanswer));
}
}
return l->cfwdtype;
}
| static int skinny_answer | ( | struct ast_channel * | ast | ) | [static] |
Definition at line 4057 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::connected, skinny_subchannel::cxmode, skinny_line::device, ast_party_connected_line::id, KEYDEF_CONNECTED, ast_party_id::name, ast_channel::name, ast_party_id::number, skinny_subchannel::parent, skinny_subchannel::rtp, S_COR, SKINNY_CONNECTED, SKINNY_CX_SENDRECV, skinny_transfer(), start_rtp(), ast_party_name::str, ast_party_number::str, ast_channel::tech_pvt, transmit_callinfo(), transmit_callstate(), transmit_dialednumber(), transmit_displaypromptstatus(), transmit_selectsoftkeys(), transmit_stop_tone(), ast_party_name::valid, and ast_party_number::valid.
{
int res = 0;
struct skinny_subchannel *sub = ast->tech_pvt;
struct skinny_line *l = sub->parent;
struct skinny_device *d = l->device;
if (sub->blindxfer) {
if (skinnydebug)
ast_debug(1, "skinny_answer(%s) on %s@%s-%d with BlindXFER, transferring\n",
ast->name, l->name, d->name, sub->callid);
ast_setstate(ast, AST_STATE_UP);
skinny_transfer(sub);
return 0;
}
sub->cxmode = SKINNY_CX_SENDRECV;
if (!sub->rtp) {
start_rtp(sub);
}
if (skinnydebug)
ast_verb(1, "skinny_answer(%s) on %s@%s-%d\n", ast->name, l->name, d->name, sub->callid);
if (ast->_state != AST_STATE_UP) {
ast_setstate(ast, AST_STATE_UP);
}
transmit_stop_tone(d, l->instance, sub->callid);
/* order matters here...
for some reason, transmit_callinfo must be before transmit_callstate,
or you won't get keypad messages in some situations. */
transmit_callinfo(d,
S_COR(ast->connected.id.name.valid, ast->connected.id.name.str, ""),
S_COR(ast->connected.id.number.valid, ast->connected.id.number.str, ""),
l->lastnumberdialed, l->lastnumberdialed, l->instance, sub->callid, 2);
transmit_callstate(d, sub->parent->instance, sub->callid, SKINNY_CONNECTED);
transmit_selectsoftkeys(d, l->instance, sub->callid, KEYDEF_CONNECTED);
transmit_dialednumber(d, l->lastnumberdialed, l->instance, sub->callid);
transmit_displaypromptstatus(d, "Connected", 0, l->instance, sub->callid);
l->activesub = sub;
return res;
}
| static int skinny_call | ( | struct ast_channel * | ast, |
| char * | dest, | ||
| int | timeout | ||
| ) | [static] |
Definition at line 3909 of file chan_skinny.c.
References ast_channel::_state, skinny_line::activesub, AST_CONTROL_BUSY, AST_CONTROL_RINGING, AST_LIST_NEXT, ast_log(), ast_queue_control(), ast_setstate(), AST_STATE_DOWN, AST_STATE_RESERVED, AST_STATE_RINGING, ast_verb, skinny_subchannel::callid, ast_channel::connected, skinny_line::device, ast_party_connected_line::id, KEYDEF_RINGIN, LOG_ERROR, LOG_WARNING, ast_party_id::name, ast_channel::name, ast_party_id::number, skinny_subchannel::outgoing, skinny_subchannel::parent, S_COR, SKINNY_LAMP_BLINK, SKINNY_OFFHOOK, SKINNY_ONHOOK, SKINNY_RING_INSIDE, SKINNY_RINGIN, STIMULUS_LINE, ast_party_name::str, ast_party_number::str, ast_channel::tech_pvt, transmit_callinfo(), transmit_callstate(), transmit_displaypromptstatus(), transmit_lamp_indication(), transmit_ringer_mode(), transmit_selectsoftkeys(), ast_party_name::valid, and ast_party_number::valid.
{
int res = 0;
struct skinny_subchannel *sub = ast->tech_pvt;
struct skinny_line *l = sub->parent;
struct skinny_device *d = l->device;
if (!d->registered) {
ast_log(LOG_ERROR, "Device not registered, cannot call %s\n", dest);
return -1;
}
if ((ast->_state != AST_STATE_DOWN) && (ast->_state != AST_STATE_RESERVED)) {
ast_log(LOG_WARNING, "skinny_call called on %s, neither down nor reserved\n", ast->name);
return -1;
}
if (skinnydebug)
ast_verb(3, "skinny_call(%s)\n", ast->name);
if (l->dnd) {
ast_queue_control(ast, AST_CONTROL_BUSY);
return -1;
}
if (AST_LIST_NEXT(sub,list) && !l->callwaiting) {
ast_queue_control(ast, AST_CONTROL_BUSY);
return -1;
}
switch (l->hookstate) {
case SKINNY_OFFHOOK:
break;
case SKINNY_ONHOOK:
l->activesub = sub;
break;
default:
ast_log(LOG_ERROR, "Don't know how to deal with hookstate %d\n", l->hookstate);
break;
}
transmit_callstate(d, sub->parent->instance, sub->callid, SKINNY_RINGIN);
transmit_selectsoftkeys(d, l->instance, sub->callid, KEYDEF_RINGIN);
transmit_displaypromptstatus(d, "Ring-In", 0, l->instance, sub->callid);
transmit_callinfo(d,
S_COR(ast->connected.id.name.valid, ast->connected.id.name.str, ""),
S_COR(ast->connected.id.number.valid, ast->connected.id.number.str, ""),
l->cid_name, l->cid_num, l->instance, sub->callid, 1);
transmit_lamp_indication(d, STIMULUS_LINE, l->instance, SKINNY_LAMP_BLINK);
transmit_ringer_mode(d, SKINNY_RING_INSIDE);
ast_setstate(ast, AST_STATE_RINGING);
ast_queue_control(ast, AST_CONTROL_RINGING);
sub->outgoing = 1;
return res;
}
| static int skinny_devicestate | ( | void * | data | ) | [static] |
Definition at line 6611 of file chan_skinny.c.
References ast_strdupa, find_line_by_name(), and get_devicestate().
{
struct skinny_line *l;
char *tmp;
tmp = ast_strdupa(data);
l = find_line_by_name(tmp);
return get_devicestate(l);
}
| static int skinny_extensionstate_cb | ( | char * | context, |
| char * | exten, | ||
| int | state, | ||
| void * | data | ||
| ) | [static] |
Definition at line 2626 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_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, state, skinny_speeddial::stateid, STIMULUS_LINE, transmit_callstate(), and transmit_lamp_indication().
Referenced by skinny_register().
{
struct skinny_speeddial *sd = data;
struct skinny_device *d = sd->parent;
char hint[AST_MAX_EXTENSION];
if (ast_get_hint(hint, sizeof(hint), NULL, 0, NULL, sd->context, sd->exten)) {
/* If they are not registered, we will override notification and show no availability */
if (ast_device_state(hint) == AST_DEVICE_UNAVAILABLE) {
transmit_lamp_indication(d, STIMULUS_LINE, sd->instance, SKINNY_LAMP_FLASH);
transmit_callstate(d, sd->instance, SKINNY_ONHOOK, 0);
}
} else {
switch (state) {
case AST_EXTENSION_DEACTIVATED: /* Retry after a while */
case AST_EXTENSION_REMOVED: /* Extension is gone */
ast_verb(2, "Extension state: Watcher for hint %s %s. Notify Device %s\n", exten, state == AST_EXTENSION_DEACTIVATED ? "deactivated" : "removed", d->name);
sd->stateid = -1;
transmit_lamp_indication(d, STIMULUS_LINE, sd->instance, SKINNY_LAMP_OFF);
transmit_callstate(d, sd->instance, SKINNY_ONHOOK, 0);
break;
case AST_EXTENSION_RINGING:
case AST_EXTENSION_UNAVAILABLE:
transmit_lamp_indication(d, STIMULUS_LINE, sd->instance, SKINNY_LAMP_BLINK);
transmit_callstate(d, sd->instance, SKINNY_RINGIN, 0);
break;
case AST_EXTENSION_BUSY: /* callstate = SKINNY_BUSY wasn't wanting to work - I'll settle for this */
case AST_EXTENSION_INUSE:
transmit_lamp_indication(d, STIMULUS_LINE, sd->instance, SKINNY_LAMP_ON);
transmit_callstate(d, sd->instance, SKINNY_CALLREMOTEMULTILINE, 0);
break;
case AST_EXTENSION_ONHOLD:
transmit_lamp_indication(d, STIMULUS_LINE, sd->instance, SKINNY_LAMP_WINK);
transmit_callstate(d, sd->instance, SKINNY_HOLD, 0);
break;
case AST_EXTENSION_NOT_INUSE:
default:
transmit_lamp_indication(d, STIMULUS_LINE, sd->instance, SKINNY_LAMP_OFF);
transmit_callstate(d, sd->instance, SKINNY_ONHOOK, 0);
break;
}
}
sd->laststate = state;
return 0;
}
| static int skinny_fixup | ( | struct ast_channel * | oldchan, |
| struct ast_channel * | newchan | ||
| ) | [static] |
Definition at line 4189 of file chan_skinny.c.
References ast_log(), LOG_NOTICE, LOG_WARNING, ast_channel::name, skinny_subchannel::owner, and ast_channel::tech_pvt.
{
struct skinny_subchannel *sub = newchan->tech_pvt;
ast_log(LOG_NOTICE, "skinny_fixup(%s, %s)\n", oldchan->name, newchan->name);
if (sub->owner != oldchan) {
ast_log(LOG_WARNING, "old channel wasn't %p but was %p\n", oldchan, sub->owner);
return -1;
}
sub->owner = newchan;
return 0;
}
| static enum ast_rtp_glue_result skinny_get_rtp_peer | ( | struct ast_channel * | c, |
| struct ast_rtp_instance ** | instance | ||
| ) | [static] |
Definition at line 2780 of file chan_skinny.c.
References ao2_ref, ast_mutex_lock, ast_mutex_unlock, AST_RTP_GLUE_RESULT_FORBID, AST_RTP_GLUE_RESULT_LOCAL, AST_RTP_GLUE_RESULT_REMOTE, ast_verb, skinny_subchannel::lock, ast_channel::name, skinny_subchannel::parent, skinny_subchannel::rtp, and ast_channel::tech_pvt.
{
struct skinny_subchannel *sub = NULL;
struct skinny_line *l;
enum ast_rtp_glue_result res = AST_RTP_GLUE_RESULT_REMOTE;
if (skinnydebug)
ast_verb(1, "skinny_get_rtp_peer() Channel = %s\n", c->name);
if (!(sub = c->tech_pvt))
return AST_RTP_GLUE_RESULT_FORBID;
ast_mutex_lock(&sub->lock);
if (!(sub->rtp)){
ast_mutex_unlock(&sub->lock);
return AST_RTP_GLUE_RESULT_FORBID;
}
ao2_ref(sub->rtp, +1);
*instance = sub->rtp;
l = sub->parent;
if (!l->directmedia || l->nat){
res = AST_RTP_GLUE_RESULT_LOCAL;
if (skinnydebug)
ast_verb(1, "skinny_get_rtp_peer() Using AST_RTP_GLUE_RESULT_LOCAL \n");
}
ast_mutex_unlock(&sub->lock);
return res;
}
| static enum ast_rtp_glue_result skinny_get_vrtp_peer | ( | struct ast_channel * | c, |
| struct ast_rtp_instance ** | instance | ||
| ) | [static] |
Definition at line 2767 of file chan_skinny.c.
References ao2_ref, AST_RTP_GLUE_RESULT_FORBID, AST_RTP_GLUE_RESULT_REMOTE, ast_channel::tech_pvt, and skinny_subchannel::vrtp.
{
struct skinny_subchannel *sub = NULL;
if (!(sub = c->tech_pvt) || !(sub->vrtp))
return AST_RTP_GLUE_RESULT_FORBID;
ao2_ref(sub->vrtp, +1);
*instance = sub->vrtp;
return AST_RTP_GLUE_RESULT_REMOTE;
}
| static int skinny_hangup | ( | struct ast_channel * | ast | ) | [static] |
Definition at line 3966 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_module_unref(), ast_mutex_lock, ast_mutex_unlock, ast_rtp_instance_destroy(), ast_verb, skinny_subchannel::callid, skinny_line::device, KEYDEF_ONHOOK, skinny_subchannel::lock, skinny_subchannel::outgoing, skinny_subchannel::owner, skinny_subchannel::parent, skinny_subchannel::related, skinny_subchannel::rtp, ast_module_info::self, SKINNY_LAMP_BLINK, SKINNY_LAMP_OFF, SKINNY_LAMP_ON, SKINNY_ONHOOK, SKINNY_RING_OFF, SKINNY_SPEAKEROFF, STIMULUS_LINE, skinny_line::sub, ast_channel::tech_pvt, transmit_activatecallplane(), transmit_callstate(), transmit_clear_display_message(), transmit_clearpromptmessage(), transmit_closereceivechannel(), transmit_lamp_indication(), transmit_ringer_mode(), transmit_selectsoftkeys(), transmit_speaker_mode(), transmit_stop_tone(), and transmit_stopmediatransmission().
{
struct skinny_subchannel *sub = ast->tech_pvt;
struct skinny_line *l;
struct skinny_device *d;
if (!sub) {
ast_debug(1, "Asked to hangup channel not connected\n");
return 0;
}
l = sub->parent;
d = l->device;
if (skinnydebug)
ast_verb(3,"Hanging up %s/%d\n",d->name,sub->callid);
AST_LIST_REMOVE(&l->sub, sub, list);
if (d->registered) {
/* Ignoring l->type, doesn't seem relevant and previous code
assigned rather than tested, ie always true */
if (!AST_LIST_EMPTY(&l->sub)) {
if (sub->related) {
sub->related->related = NULL;
}
if (sub == l->activesub) { /* we are killing the active sub, but there are other subs on the line*/
ast_verb(4,"Killing active sub %d\n", sub->callid);
if (sub->related) {
l->activesub = sub->related;
} else {
if (AST_LIST_NEXT(sub, list)) {
l->activesub = AST_LIST_NEXT(sub, list);
} else {
l->activesub = AST_LIST_FIRST(&l->sub);
}
}
//transmit_callstate(d, l->instance, SKINNY_ONHOOK, sub->callid);
transmit_activatecallplane(d, l);
transmit_closereceivechannel(d, sub);
transmit_stopmediatransmission(d, sub);
transmit_lamp_indication(d, STIMULUS_LINE, l->instance, SKINNY_LAMP_BLINK);
transmit_stop_tone(d, l->instance, sub->callid);
} else { /* we are killing a background sub on the line with other subs*/
ast_verb(4,"Killing inactive sub %d\n", sub->callid);
if (AST_LIST_NEXT(sub, list)) {
transmit_lamp_indication(d, STIMULUS_LINE, l->instance, SKINNY_LAMP_BLINK);
} else {
transmit_lamp_indication(d, STIMULUS_LINE, l->instance, SKINNY_LAMP_ON);
}
}
} else { /* no more subs on line so make idle */
ast_verb(4,"Killing only sub %d\n", sub->callid);
l->hookstate = SKINNY_ONHOOK;
transmit_closereceivechannel(d, sub);
transmit_stopmediatransmission(d, sub);
transmit_speaker_mode(d, SKINNY_SPEAKEROFF);
transmit_clearpromptmessage(d, l->instance, sub->callid);
transmit_callstate(d, l->instance, sub->callid, SKINNY_ONHOOK);
transmit_selectsoftkeys(d, 0, 0, KEYDEF_ONHOOK);
transmit_activatecallplane(d, l);
l->activesub = NULL;
transmit_lamp_indication(d, STIMULUS_LINE, l->instance, SKINNY_LAMP_OFF);
if (sub->parent == d->activeline) {
transmit_activatecallplane(d, l);
transmit_closereceivechannel(d, sub);
transmit_stopmediatransmission(d, sub);
transmit_speaker_mode(d, SKINNY_SPEAKEROFF);
transmit_ringer_mode(d, SKINNY_RING_OFF);
transmit_clear_display_message(d, l->instance, sub->callid);
transmit_stop_tone(d, l->instance, sub->callid);
/* we should check to see if we can start the ringer if another line is ringing */
}
}
}
ast_mutex_lock(&sub->lock);
sub->owner = NULL;
ast->tech_pvt = NULL;
sub->alreadygone = 0;
sub->outgoing = 0;
if (sub->rtp) {
ast_rtp_instance_destroy(sub->rtp);
sub->rtp = NULL;
}
ast_mutex_unlock(&sub->lock);
ast_free(sub);
ast_module_unref(ast_module_info->self);
return 0;
}
| static int skinny_hold | ( | struct skinny_subchannel * | sub | ) | [static] |
Definition at line 4605 of file chan_skinny.c.
References AST_CONTROL_HOLD, ast_queue_control_data(), ast_strlen_zero(), ast_verb, skinny_subchannel::callid, skinny_line::device, skinny_subchannel::onhold, skinny_subchannel::owner, skinny_subchannel::parent, S_OR, SKINNY_HOLD, SKINNY_LAMP_WINK, STIMULUS_LINE, transmit_activatecallplane(), transmit_callstate(), transmit_closereceivechannel(), transmit_lamp_indication(), and transmit_stopmediatransmission().
Referenced by handle_hold_button(), handle_soft_key_event_message(), and handle_transfer_button().
{
struct skinny_line *l = sub->parent;
struct skinny_device *d = l->device;
/* Don't try to hold a channel that doesn't exist */
if (!sub || !sub->owner)
return 0;
/* Channel needs to be put on hold */
if (skinnydebug)
ast_verb(1, "Putting on Hold(%d)\n", l->instance);
ast_queue_control_data(sub->owner, AST_CONTROL_HOLD,
S_OR(l->mohsuggest, NULL),
!ast_strlen_zero(l->mohsuggest) ? strlen(l->mohsuggest) + 1 : 0);
transmit_activatecallplane(d, l);
transmit_closereceivechannel(d, sub);
transmit_stopmediatransmission(d, sub);
transmit_callstate(d, sub->parent->instance, sub->callid, SKINNY_HOLD);
transmit_lamp_indication(d, STIMULUS_LINE, l->instance, SKINNY_LAMP_WINK);
sub->onhold = 1;
return 1;
}
| static int skinny_indicate | ( | struct ast_channel * | ast, |
| int | ind, | ||
| const void * | data, | ||
| size_t | datalen | ||
| ) | [static] |
Definition at line 4372 of file chan_skinny.c.
References ast_channel::_state, skinny_subchannel::alreadygone, AST_CONTROL_BUSY, AST_CONTROL_CONGESTION, AST_CONTROL_CONNECTED_LINE, AST_CONTROL_HOLD, AST_CONTROL_INCOMPLETE, AST_CONTROL_PROCEEDING, AST_CONTROL_PROGRESS, AST_CONTROL_RINGING, AST_CONTROL_SRCCHANGE, AST_CONTROL_SRCUPDATE, AST_CONTROL_UNHOLD, ast_debug, ast_log(), ast_moh_start(), ast_moh_stop(), ast_rtp_instance_change_source(), ast_rtp_instance_update_source(), AST_SOFTHANGUP_DEV, ast_softhangup_nolock(), AST_STATE_UP, ast_verb, skinny_subchannel::blindxfer, ast_channel::caller, skinny_subchannel::callid, ast_channel::connected, control2str(), skinny_line::device, ast_party_caller::id, ast_party_connected_line::id, LOG_NOTICE, LOG_WARNING, ast_party_id::name, ast_channel::name, ast_party_id::number, skinny_subchannel::outgoing, skinny_subchannel::parent, skinny_subchannel::progress, skinny_subchannel::ringing, skinny_subchannel::rtp, S_COR, skinny_device::session, SKINNY_ALERT, SKINNY_BUSY, SKINNY_BUSYTONE, SKINNY_CONGESTION, SKINNY_PROGRESS, SKINNY_REORDER, SKINNY_RINGOUT, skinny_transfer(), ast_party_name::str, ast_party_number::str, ast_channel::tech_pvt, transmit_callinfo(), transmit_callstate(), transmit_dialednumber(), transmit_displaypromptstatus(), transmit_start_tone(), transmit_stop_tone(), update_connectedline(), ast_party_name::valid, and ast_party_number::valid.
{
struct skinny_subchannel *sub = ast->tech_pvt;
struct skinny_line *l = sub->parent;
struct skinny_device *d = l->device;
struct skinnysession *s = d->session;
if (!s) {
ast_log(LOG_NOTICE, "Asked to indicate '%s' condition on channel %s, but session does not exist.\n", control2str(ind), ast->name);
return -1;
}
if (skinnydebug)
ast_verb(3, "Asked to indicate '%s' condition on channel %s\n", control2str(ind), ast->name);
switch(ind) {
case AST_CONTROL_RINGING:
if (sub->blindxfer) {
if (skinnydebug)
ast_debug(1, "Channel %s set up for Blind Xfer, so Xfer rather than ring device\n", ast->name);
skinny_transfer(sub);
break;
}
if (ast->_state != AST_STATE_UP) {
if (!sub->progress) {
if (!d->earlyrtp) {
transmit_start_tone(d, SKINNY_ALERT, l->instance, sub->callid);
}
transmit_callstate(d, sub->parent->instance, sub->callid, SKINNY_RINGOUT);
transmit_dialednumber(d, l->lastnumberdialed, l->instance, sub->callid);
transmit_displaypromptstatus(d, "Ring Out", 0, l->instance, sub->callid);
transmit_callinfo(d,
S_COR(ast->caller.id.name.valid, ast->caller.id.name.str, ""),
S_COR(ast->caller.id.number.valid, ast->caller.id.number.str, ""),
S_COR(ast->connected.id.name.valid, ast->connected.id.name.str, l->lastnumberdialed),
S_COR(ast->connected.id.number.valid, ast->connected.id.number.str, l->lastnumberdialed),
l->instance, sub->callid, 2); /* 2 = outgoing from phone */
sub->ringing = 1;
if (!d->earlyrtp) {
break;
}
}
}
return -1; /* Tell asterisk to provide inband signalling */
case AST_CONTROL_BUSY:
if (ast->_state != AST_STATE_UP) {
if (!d->earlyrtp) {
transmit_start_tone(d, SKINNY_BUSYTONE, l->instance, sub->callid);
}
transmit_callstate(d, sub->parent->instance, sub->callid, SKINNY_BUSY);
sub->alreadygone = 1;
ast_softhangup_nolock(ast, AST_SOFTHANGUP_DEV);
if (!d->earlyrtp) {
break;
}
}
return -1; /* Tell asterisk to provide inband signalling */
case AST_CONTROL_INCOMPLETE:
/* Support for incomplete not supported for chan_skinny; treat as congestion */
case AST_CONTROL_CONGESTION:
if (ast->_state != AST_STATE_UP) {
if (!d->earlyrtp) {
transmit_start_tone(d, SKINNY_REORDER, l->instance, sub->callid);
}
transmit_callstate(d, sub->parent->instance, sub->callid, SKINNY_CONGESTION);
sub->alreadygone = 1;
ast_softhangup_nolock(ast, AST_SOFTHANGUP_DEV);
if (!d->earlyrtp) {
break;
}
}
return -1; /* Tell asterisk to provide inband signalling */
case AST_CONTROL_PROGRESS:
if ((ast->_state != AST_STATE_UP) && !sub->progress && !sub->outgoing) {
if (!d->earlyrtp) {
transmit_start_tone(d, SKINNY_ALERT, l->instance, sub->callid);
}
transmit_callstate(d, sub->parent->instance, sub->callid, SKINNY_PROGRESS);
transmit_displaypromptstatus(d, "Call Progress", 0, l->instance, sub->callid);
transmit_callinfo(d,
S_COR(ast->caller.id.name.valid, ast->caller.id.name.str, ""),
S_COR(ast->caller.id.number.valid, ast->caller.id.number.str, ""),
S_COR(ast->connected.id.name.valid, ast->connected.id.name.str, l->lastnumberdialed),
S_COR(ast->connected.id.number.valid, ast->connected.id.number.str, l->lastnumberdialed),
l->instance, sub->callid, 2); /* 2 = outgoing from phone */
sub->progress = 1;
if (!d->earlyrtp) {
break;
}
}
return -1; /* Tell asterisk to provide inband signalling */
case -1: /* STOP_TONE */
transmit_stop_tone(d, l->instance, sub->callid);
break;
case AST_CONTROL_HOLD:
ast_moh_start(ast, data, l->mohinterpret);
break;
case AST_CONTROL_UNHOLD:
ast_moh_stop(ast);
break;
case AST_CONTROL_PROCEEDING:
break;
case AST_CONTROL_SRCUPDATE:
ast_rtp_instance_update_source(sub->rtp);
break;
case AST_CONTROL_SRCCHANGE:
ast_rtp_instance_change_source(sub->rtp);
break;
case AST_CONTROL_CONNECTED_LINE:
update_connectedline(sub, data, datalen);
break;
default:
ast_log(LOG_WARNING, "Don't know how to indicate condition %d\n", ind);
return -1; /* Tell asterisk to provide inband signalling */
}
return 0;
}
| static struct ast_channel* skinny_new | ( | struct skinny_line * | l, |
| int | state, | ||
| const char * | linkedid | ||
| ) | [static, read] |
Definition at line 4489 of file chan_skinny.c.
References accountcode, ast_channel::adsicpe, ast_channel::amaflags, ast_party_caller::ani, AST_ADSI_UNAVAILABLE, ast_best_codec(), ast_calloc, ast_channel_alloc(), ast_channel_set_fd(), ast_copy_string(), AST_DEVICE_NOT_INUSE, ast_getformatname(), ast_getformatname_multiple(), ast_hangup(), ast_jb_configure(), AST_LIST_INSERT_HEAD, ast_log(), ast_module_ref(), ast_mutex_init, ast_pbx_start(), ast_rtp_instance_fd(), AST_STATE_DOWN, AST_STATE_RING, ast_strdup, ast_string_field_set, ast_strlen_zero(), ast_verb, skinny_subchannel::blindxfer, ast_channel::caller, ast_channel::callgroup, skinny_subchannel::callid, skinny_line::chanvars, ast_channel::context, skinny_subchannel::cxmode, default_capability, skinny_line::device, ast_channel::exten, get_devicestate(), global_jbconf, language, skinny_subchannel::lock, LOG_WARNING, ast_variable::name, ast_channel::name, skinny_subchannel::nat, ast_channel::nativeformats, ast_variable::next, ast_party_id::number, skinny_subchannel::onhold, skinny_subchannel::owner, skinny_subchannel::parent, parkinglot, pbx_builtin_setvar_helper(), ast_channel::pickupgroup, ast_channel::priority, ast_channel::rawreadformat, ast_channel::rawwriteformat, ast_channel::readformat, skinny_subchannel::related, ast_channel::rings, skinny_subchannel::rtp, ast_module_info::self, SKINNY_CFWD_ALL, SKINNY_CFWD_BUSY, SKINNY_CX_INACTIVE, skinny_tech, ast_party_number::str, skinny_line::sub, ast_channel::tech, ast_channel::tech_pvt, ast_party_number::valid, 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().
{
struct ast_channel *tmp;
struct skinny_subchannel *sub;
struct skinny_device *d = l->device;
struct ast_variable *v = NULL;
int fmt;
if (!l->device) {
ast_log(LOG_WARNING, "Device for line %s is not registered.\n", l->name);
return NULL;
}
tmp = ast_channel_alloc(1, state, l->cid_num, l->cid_name, l->accountcode, l->exten, l->context, linkedid, l->amaflags, "Skinny/%s@%s-%d", l->name, d->name, callnums);
if (!tmp) {
ast_log(LOG_WARNING, "Unable to allocate channel structure\n");
return NULL;
} else {
sub = ast_calloc(1, sizeof(*sub));
if (!sub) {
ast_log(LOG_WARNING, "Unable to allocate Skinny subchannel\n");
return NULL;
} else {
ast_mutex_init(&sub->lock);
sub->owner = tmp;
sub->callid = callnums++;
d->lastlineinstance = l->instance;
d->lastcallreference = sub->callid;
sub->cxmode = SKINNY_CX_INACTIVE;
sub->nat = l->nat;
sub->parent = l;
sub->onhold = 0;
sub->blindxfer = 0;
sub->xferor = 0;
sub->related = NULL;
AST_LIST_INSERT_HEAD(&l->sub, sub, list);
//l->activesub = sub;
}
tmp->tech = &skinny_tech;
tmp->tech_pvt = sub;
tmp->nativeformats = l->capability;
if (!tmp->nativeformats)
// Should throw an error
tmp->nativeformats = default_capability;
fmt = ast_best_codec(tmp->nativeformats);
if (skinnydebug) {
char buf[256];
ast_verb(1, "skinny_new: tmp->nativeformats=%s fmt=%s\n",
ast_getformatname_multiple(buf, sizeof(buf), tmp->nativeformats),
ast_getformatname(fmt));
}
if (sub->rtp) {
ast_channel_set_fd(tmp, 0, ast_rtp_instance_fd(sub->rtp, 0));
}
if (state == AST_STATE_RING) {
tmp->rings = 1;
}
tmp->writeformat = fmt;
tmp->rawwriteformat = fmt;
tmp->readformat = fmt;
tmp->rawreadformat = fmt;
if (!ast_strlen_zero(l->language))
ast_string_field_set(tmp, language, l->language);
if (!ast_strlen_zero(l->accountcode))
ast_string_field_set(tmp, accountcode, l->accountcode);
if (!ast_strlen_zero(l->parkinglot))
ast_string_field_set(tmp, parkinglot, l->parkinglot);
if (l->amaflags)
tmp->amaflags = l->amaflags;
ast_module_ref(ast_module_info->self);
tmp->callgroup = l->callgroup;
tmp->pickupgroup = l->pickupgroup;
/* XXX Need to figure out how to handle CFwdNoAnswer */
if (l->cfwdtype & SKINNY_CFWD_ALL) {
ast_string_field_set(tmp, call_forward, l->call_forward_all);
} else if (l->cfwdtype & SKINNY_CFWD_BUSY) {
if (get_devicestate(l) != AST_DEVICE_NOT_INUSE) {
ast_string_field_set(tmp, call_forward, l->call_forward_busy);
}
}
ast_copy_string(tmp->context, l->context, sizeof(tmp->context));
ast_copy_string(tmp->exten, l->exten, sizeof(tmp->exten));
/* Don't use ast_set_callerid() here because it will
* generate a needless NewCallerID event */
if (!ast_strlen_zero(l->cid_num)) {
tmp->caller.ani.number.valid = 1;
tmp->caller.ani.number.str = ast_strdup(l->cid_num);
}
tmp->priority = 1;
tmp->adsicpe = AST_ADSI_UNAVAILABLE;
if (sub->rtp)
ast_jb_configure(tmp, &global_jbconf);
/* Set channel variables for this call from configuration */
for (v = l->chanvars ; v ; v = v->next)
pbx_builtin_setvar_helper(tmp, v->name, v->value);
if (state != AST_STATE_DOWN) {
if (ast_pbx_start(tmp)) {
ast_log(LOG_WARNING, "Unable to start PBX on %s\n", tmp->name);
ast_hangup(tmp);
tmp = NULL;
}
}
}
return tmp;
}
| static void* skinny_newcall | ( | void * | data | ) | [static] |
Definition at line 3769 of file chan_skinny.c.
References ast_party_caller::ani, ast_copy_string(), ast_log(), ast_party_name_free(), ast_party_name_init(), ast_party_number_free(), ast_party_number_init(), ast_pbx_run(), ast_set_callerid(), ast_setstate(), AST_STATE_RING, ast_strdup, ast_channel::caller, skinny_subchannel::callid, ast_channel::connected, ast_channel::data, skinny_line::device, ast_channel::exten, ast_party_connected_line::id, LOG_WARNING, ast_party_id::name, ast_party_id::number, skinny_subchannel::parent, skinny_subchannel::rtp, SKINNY_REORDER, start_rtp(), ast_party_number::str, ast_channel::tech_pvt, transmit_start_tone(), and ast_party_number::valid.
Referenced by handle_enbloc_call_message(), handle_soft_key_event_message(), handle_stimulus_message(), and skinny_ss().
{
struct ast_channel *c = data;
struct skinny_subchannel *sub = c->tech_pvt;
struct skinny_line *l = sub->parent;
struct skinny_device *d = l->device;
int res = 0;
ast_copy_string(l->lastnumberdialed, c->exten, sizeof(l->lastnumberdialed));
ast_set_callerid(c,
l->hidecallerid ? "" : l->cid_num,
l->hidecallerid ? "" : l->cid_name,
c->caller.ani.number.valid ? NULL : l->cid_num);
#if 1 /* XXX This code is probably not necessary */
ast_party_number_free(&c->connected.id.number);
ast_party_number_init(&c->connected.id.number);
c->connected.id.number.valid = 1;
c->connected.id.number.str = ast_strdup(c->exten);
ast_party_name_free(&c->connected.id.name);
ast_party_name_init(&c->connected.id.name);
#endif
ast_setstate(c, AST_STATE_RING);
if (!sub->rtp) {
start_rtp(sub);
}
res = ast_pbx_run(c);
if (res) {
ast_log(LOG_WARNING, "PBX exited non-zero\n");
transmit_start_tone(d, SKINNY_REORDER, l->instance, sub->callid);
}
return NULL;
}
| static struct ast_frame * skinny_read | ( | struct ast_channel * | ast | ) | [static, read] |
Definition at line 4147 of file chan_skinny.c.
References ast_mutex_lock, ast_mutex_unlock, skinny_subchannel::lock, skinny_rtp_read(), and ast_channel::tech_pvt.
{
struct ast_frame *fr;
struct skinny_subchannel *sub = ast->tech_pvt;
ast_mutex_lock(&sub->lock);
fr = skinny_rtp_read(sub);
ast_mutex_unlock(&sub->lock);
return fr;
}
| static int skinny_register | ( | struct skinny_req * | req, |
| struct skinnysession * | s | ||
| ) | [static] |
Definition at line 1870 of file chan_skinny.c.
References __ourip, ast_app_has_voicemail(), 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_sockaddr_from_sin, ast_strlen_zero(), ast_verb, skinny_speeddial::context, skinny_req::data, skinny_line::device, skinnysession::device, EVENT_FLAG_SYSTEM, skinny_speeddial::exten, skinnysession::fd, skinny_device::ha, letohl, skinny_device::lines, LOG_WARNING, manager_event, mwi_event_cb(), register_message::name, skinny_line::newmsgs, skinny_device::ourip, skinny_data::reg, register_exten(), skinny_device::session, set_callforwards(), skinnysession::sin, skinny_extensionstate_cb(), skinny_device::speeddials, skinny_speeddial::stateid, and register_message::type.
Referenced by handle_register_message().
{
struct skinny_device *d;
struct skinny_line *l;
struct skinny_speeddial *sd;
struct sockaddr_in sin;
socklen_t slen;
int instance;
AST_LIST_LOCK(&devices);
AST_LIST_TRAVERSE(&devices, d, list){
struct ast_sockaddr addr;
ast_sockaddr_from_sin(&addr, &s->sin);
if (!strcasecmp(req->data.reg.name, d->id)
&& ast_apply_ha(d->ha, &addr)) {
s->device = d;
d->type = letohl(req->data.reg.type);
if (ast_strlen_zero(d->version_id)) {
ast_copy_string(d->version_id, version_id, sizeof(d->version_id));
}
d->registered = 1;
d->session = s;
slen = sizeof(sin);
if (getsockname(s->fd, (struct sockaddr *)&sin, &slen)) {
ast_log(LOG_WARNING, "Cannot get socket name\n");
sin.sin_addr = __ourip;
}
d->ourip = sin.sin_addr;
AST_LIST_TRAVERSE(&d->speeddials, sd, list) {
sd->stateid = ast_extension_state_add(sd->context, sd->exten, skinny_extensionstate_cb, sd);
}
instance = 0;
AST_LIST_TRAVERSE(&d->lines, l, list) {
instance++;
}
AST_LIST_TRAVERSE(&d->lines, l, list) {
/* FIXME: All sorts of issues will occur if this line is already connected to a device */
if (l->device) {
manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", "ChannelType: Skinny\r\nPeer: Skinny/%s@%s\r\nPeerStatus: Rejected\r\nCause: LINE_ALREADY_CONNECTED\r\n", l->name, l->device->name);
ast_verb(1, "Line %s already connected to %s. Not connecting to %s.\n", l->name, l->device->name, d->name);
} else {
l->device = d;
l->capability = l->confcapability & d->capability;
l->prefs = l->confprefs;
if (!l->prefs.order[0]) {
l->prefs = d->confprefs;
}
/* l->capability = d->capability;
l->prefs = d->prefs; */
l->instance = instance;
l->newmsgs = ast_app_has_voicemail(l->mailbox, NULL);
set_callforwards(l, NULL, 0);
manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", "ChannelType: Skinny\r\nPeer: Skinny/%s@%s\r\nPeerStatus: Registered\r\n", l->name, d->name);
register_exten(l);
/* initialize MWI on line and device */
mwi_event_cb(0, l);
ast_devstate_changed(AST_DEVICE_NOT_INUSE, "Skinny/%s@%s", l->name, d->name);
}
--instance;
}
break;
}
}
AST_LIST_UNLOCK(&devices);
if (!d) {
return 0;
}
return 1;
}
| int skinny_reload | ( | void | ) | [static] |
Definition at line 7351 of file chan_skinny.c.
References skinny_device::addons, AST_LIST_LOCK, AST_LIST_REMOVE_CURRENT, AST_LIST_REMOVE_HEAD, AST_LIST_TRAVERSE, AST_LIST_TRAVERSE_SAFE_BEGIN, AST_LIST_TRAVERSE_SAFE_END, AST_LIST_UNLOCK, ast_verb, config_load(), skinny_req::data, free, skinny_device::lines, req_alloc(), skinny_data::reset, RESET_MESSAGE, reset_message::resetType, skinny_device::session, skinny_device::speeddials, and transmit_response().
Referenced by handle_skinny_reload(), and reload().
{
struct skinny_device *d;
struct skinny_line *l;
struct skinny_speeddial *sd;
struct skinny_addon *a;
struct skinny_req *req;
if (skinnyreload) {
ast_verb(3, "Chan_skinny is already reloading.\n");
return 0;
}
skinnyreload = 1;
/* Mark all devices and lines as candidates to be pruned */
AST_LIST_LOCK(&devices);
AST_LIST_TRAVERSE(&devices, d, list) {
d->prune = 1;
}
AST_LIST_UNLOCK(&devices);
AST_LIST_LOCK(&lines);
AST_LIST_TRAVERSE(&lines, l, all) {
l->prune = 1;
}
AST_LIST_UNLOCK(&lines);
config_load();
/* Remove any devices that no longer exist in the config */
AST_LIST_LOCK(&devices);
AST_LIST_TRAVERSE_SAFE_BEGIN(&devices, d, list) {
if (!d->prune) {
continue;
}
ast_verb(3, "Removing device '%s'\n", d->name);
/* Delete all lines for this device.
We do not want to free the line here, that
will happen below. */
while ((l = AST_LIST_REMOVE_HEAD(&d->lines, list))) {
}
/* Delete all speeddials for this device */
while ((sd = AST_LIST_REMOVE_HEAD(&d->speeddials, list))) {
free(sd);
}
/* Delete all addons for this device */
while ((a = AST_LIST_REMOVE_HEAD(&d->addons, list))) {
free(a);
}
AST_LIST_REMOVE_CURRENT(list);
free(d);
}
AST_LIST_TRAVERSE_SAFE_END;
AST_LIST_UNLOCK(&devices);
AST_LIST_LOCK(&lines);
AST_LIST_TRAVERSE_SAFE_BEGIN(&lines, l, all) {
if (l->prune) {
AST_LIST_REMOVE_CURRENT(all);
free(l);
}
}
AST_LIST_TRAVERSE_SAFE_END;
AST_LIST_UNLOCK(&lines);
AST_LIST_TRAVERSE(&devices, d, list) {
/* Do a soft reset to re-register the devices after
cleaning up the removed devices and lines */
if (d->session) {
ast_verb(3, "Restarting device '%s'\n", d->name);
if ((req = req_alloc(sizeof(struct reset_message), RESET_MESSAGE))) {
req->data.reset.resetType = 2;
transmit_response(d, req);
}
}
}
skinnyreload = 0;
return 0;
}
| static struct skinny_req* skinny_req_parse | ( | struct skinnysession * | s | ) | [static, read] |
Definition at line 6439 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().
{
struct skinny_req *req;
int *bufaddr;
if (!(req = ast_calloc(1, SKINNY_MAX_PACKET)))
return NULL;
ast_mutex_lock(&s->lock);
memcpy(req, s->inbuf, skinny_header_size);
bufaddr = (int *)(s->inbuf);
memcpy(&req->data, s->inbuf+skinny_header_size, letohl(*bufaddr)-4);
ast_mutex_unlock(&s->lock);
if (letohl(req->e) < 0) {
ast_log(LOG_ERROR, "Event Message is NULL from socket %d, This is bad\n", s->fd);
ast_free(req);
return NULL;
}
return req;
}
| static struct ast_channel * skinny_request | ( | const char * | type, |
| format_t | format, | ||
| const struct ast_channel * | requestor, | ||
| void * | data, | ||
| int * | cause | ||
| ) | [static, read] |
Definition at line 6623 of file chan_skinny.c.
References ast_copy_string(), AST_FORMAT_AUDIO_MASK, ast_getformatname_multiple(), ast_log(), AST_STATE_DOWN, ast_strlen_zero(), ast_verb, ast_channel::data, find_line_by_name(), ast_channel::linkedid, LOG_NOTICE, LOG_WARNING, restart_monitor(), and skinny_new().
{
struct skinny_line *l;
struct ast_channel *tmpc = NULL;
char tmp[256];
char *dest = data;
if (!(format &= AST_FORMAT_AUDIO_MASK)) {
ast_log(LOG_NOTICE, "Asked to get a channel of unsupported format '%s'\n", ast_getformatname_multiple(tmp, sizeof(tmp), format));
return NULL;
}
ast_copy_string(tmp, dest, sizeof(tmp));
if (ast_strlen_zero(tmp)) {
ast_log(LOG_NOTICE, "Skinny channels require a device\n");
return NULL;
}
l = find_line_by_name(tmp);
if (!l) {
ast_log(LOG_NOTICE, "No available lines on: %s\n", dest);
return NULL;
}
ast_verb(3, "skinny_request(%s)\n", tmp);
tmpc = skinny_new(l, AST_STATE_DOWN, requestor ? requestor->linkedid : NULL);
if (!tmpc) {
ast_log(LOG_WARNING, "Unable to make channel for '%s'\n", tmp);
}
restart_monitor();
return tmpc;
}
| static struct ast_frame* skinny_rtp_read | ( | struct skinny_subchannel * | sub | ) | [static, read] |
Definition at line 4100 of file chan_skinny.c.
References ast_debug, AST_FRAME_VOICE, ast_getformatname(), ast_null_frame, ast_rtp_instance_read(), ast_set_read_format(), ast_set_write_format(), ast_udptl_read(), ast_frame_subclass::codec, 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().
{
struct ast_channel *ast = sub->owner;
struct ast_frame *f;
if (!sub->rtp) {
/* We have no RTP allocated for this channel */
return &ast_null_frame;
}
switch(ast->fdno) {
case 0:
f = ast_rtp_instance_read(sub->rtp, 0); /* RTP Audio */
break;
case 1:
f = ast_rtp_instance_read(sub->rtp, 1); /* RTCP Control Channel */
break;
case 2:
f = ast_rtp_instance_read(sub->vrtp, 0); /* RTP Video */
break;
case 3:
f = ast_rtp_instance_read(sub->vrtp, 1); /* RTCP Control Channel for video */
break;
#if 0
case 5:
/* Not yet supported */
f = ast_udptl_read(sub->udptl); /* UDPTL for T.38 */
break;
#endif
default:
f = &ast_null_frame;
}
if (ast) {
/* We already hold the channel lock */
if (f->frametype == AST_FRAME_VOICE) {
if (f->subclass.codec != ast->nativeformats) {
ast_debug(1, "Oooh, format changed to %s\n", ast_getformatname(f->subclass.codec));
ast->nativeformats = f->subclass.codec;
ast_set_read_format(ast, ast->readformat);
ast_set_write_format(ast, ast->writeformat);
}
}
}
return f;
}
| static int skinny_senddigit_begin | ( | struct ast_channel * | ast, |
| char | digit | ||
| ) | [static] |
Definition at line 4201 of file chan_skinny.c.
{
return -1; /* Start inband indications */
}
| static int skinny_senddigit_end | ( | struct ast_channel * | ast, |
| char | digit, | ||
| unsigned int | duration | ||
| ) | [static] |
Definition at line 4206 of file chan_skinny.c.
References skinny_line::device, skinny_subchannel::parent, and ast_channel::tech_pvt.
{
#if 0
struct skinny_subchannel *sub = ast->tech_pvt;
struct skinny_line *l = sub->parent;
struct skinny_device *d = l->device;
int tmp;
/* not right */
sprintf(tmp, "%d", digit);
//transmit_tone(d, digit, l->instance, sub->callid);
#endif
return -1; /* Stop inband indications */
}
| static void* skinny_session | ( | void * | data | ) | [static] |
Definition at line 6463 of file chan_skinny.c.
References ast_debug, ast_inet_ntoa(), ast_verb, destroy_session(), errno, get_input(), handle_message(), skinny_req::res, skinnysession::sin, and skinny_req_parse().
Referenced by accept_thread().
{
int res;
struct skinny_req *req;
struct skinnysession *s = data;
ast_verb(3, "Starting Skinny session from %s\n", ast_inet_ntoa(s->sin.sin_addr));
for (;;) {
res = get_input(s);
if (res < 0) {
break;
}
if (res > 0)
{
if (!(req = skinny_req_parse(s))) {
destroy_session(s);
return NULL;
}
res = handle_message(req, s);
if (res < 0) {
destroy_session(s);
return NULL;
}
}
}
ast_debug(3, "Skinny Session returned: %s\n", strerror(errno));
if (s)
destroy_session(s);
return 0;
}
| static int skinny_set_rtp_peer | ( | struct ast_channel * | c, |
| struct ast_rtp_instance * | rtp, | ||
| struct ast_rtp_instance * | vrtp, | ||
| struct ast_rtp_instance * | trtp, | ||
| format_t | codecs, | ||
| int | nat_active | ||
| ) | [static] |
Definition at line 2817 of file chan_skinny.c.
References ast_channel::_state, ast_best_codec(), ast_codec_pref_getsize(), ast_getformatname(), ast_inet_ntoa(), ast_rtp_instance_get_local_address(), ast_rtp_instance_get_remote_address(), ast_sockaddr_to_sin, AST_STATE_UP, ast_verb, ast_format_list::bits, ast_format_list::cur_ms, skinny_line::device, skinny_device::ourip, ast_channel::tech_pvt, transmit_startmediatransmission(), and transmit_stopmediatransmission().
{
struct skinny_subchannel *sub;
struct skinny_line *l;
struct skinny_device *d;
struct ast_format_list fmt;
struct sockaddr_in us = { 0, };
struct sockaddr_in them = { 0, };
struct ast_sockaddr them_tmp;
struct ast_sockaddr us_tmp;
sub = c->tech_pvt;
if (c->_state != AST_STATE_UP)
return 0;
if (!sub) {
return -1;
}
l = sub->parent;
d = l->device;
if (rtp){
ast_rtp_instance_get_remote_address(rtp, &them_tmp);
ast_sockaddr_to_sin(&them_tmp, &them);
/* Shutdown any early-media or previous media on re-invite */
transmit_stopmediatransmission(d, sub);
if (skinnydebug)
ast_verb(1, "Peerip = %s:%d\n", ast_inet_ntoa(them.sin_addr), ntohs(them.sin_port));
fmt = ast_codec_pref_getsize(&l->prefs, ast_best_codec(l->capability));
if (skinnydebug)
ast_verb(1, "Setting payloadType to '%s' (%d ms)\n", ast_getformatname(fmt.bits), fmt.cur_ms);
if (!(l->directmedia) || (l->nat)){
ast_rtp_instance_get_local_address(rtp, &us_tmp);
ast_sockaddr_to_sin(&us_tmp, &us);
us.sin_addr.s_addr = us.sin_addr.s_addr ? us.sin_addr.s_addr : d->ourip.s_addr;
transmit_startmediatransmission(d, sub, us, fmt);
} else {
transmit_startmediatransmission(d, sub, them, fmt);
}
return 0;
}
/* Need a return here to break the bridge */
return 0;
}
| static void* skinny_ss | ( | void * | data | ) | [static] |
Definition at line 3802 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, ast_channel::caller, skinny_subchannel::callid, ast_channel::context, ast_channel::data, skinny_line::device, ast_channel::exten, firstdigittimeout, gendigittimeout, ast_party_caller::id, len(), LOG_WARNING, matchdigittimeout, ast_channel::name, ast_party_id::number, skinny_subchannel::owner, skinny_subchannel::parent, S_COR, set_callforwards(), SKINNY_DIALTONE, SKINNY_LAMP_ON, skinny_newcall(), SKINNY_OFFHOOK, SKINNY_REORDER, STIMULUS_FORWARDALL, ast_party_number::str, ast_channel::tech_pvt, transmit_cfwdstate(), transmit_displaynotify(), transmit_lamp_indication(), transmit_start_tone(), transmit_stop_tone(), and ast_party_number::valid.
Referenced by handle_callforward_button(), handle_offhook_message(), handle_soft_key_event_message(), handle_stimulus_message(), and handle_transfer_button().
{
struct ast_channel *c = data;
struct skinny_subchannel *sub = c->tech_pvt;
struct skinny_line *l = sub->parent;
struct skinny_device *d = l->device;
int len = 0;
int timeout = firstdigittimeout;
int res = 0;
int loop_pause = 100;
ast_verb(3, "Starting simple switch on '%s@%s'\n", l->name, d->name);
len = strlen(d->exten);
while (len < AST_MAX_EXTENSION-1) {
res = 1; /* Assume that we will get a digit */
while (strlen(d->exten) == len){
ast_safe_sleep(c, loop_pause);
timeout -= loop_pause;
if ( (timeout -= loop_pause) <= 0){
res = 0;
break;
}
res = 1;
}
timeout = 0;
len = strlen(d->exten);
if (!ast_ignore_pattern(c->context, d->exten)) {
transmit_stop_tone(d, l->instance, sub->callid);
}
if (ast_exists_extension(c, c->context, d->exten, 1, l->cid_num)) {
if (!res || !ast_matchmore_extension(c, c->context, d->exten, 1, l->cid_num)) {
if (l->getforward) {
/* Record this as the forwarding extension */
set_callforwards(l, d->exten, l->getforward);
ast_verb(3, "Setting call forward (%d) to '%s' on channel %s\n",
l->cfwdtype, d->exten, c->name);
transmit_start_tone(d, SKINNY_DIALTONE, l->instance, sub->callid);
transmit_lamp_indication(d, STIMULUS_FORWARDALL, 1, SKINNY_LAMP_ON);
transmit_displaynotify(d, "CFwd enabled", 10);
transmit_cfwdstate(d, l);
ast_safe_sleep(c, 500);
ast_indicate(c, -1);
ast_safe_sleep(c, 1000);
memset(d->exten, 0, sizeof(d->exten));
len = 0;
l->getforward = 0;
if (sub->owner && sub->owner->_state != AST_STATE_UP) {
ast_indicate(c, -1);
ast_hangup(c);
}
return NULL;
} else {
ast_copy_string(c->exten, d->exten, sizeof(c->exten));
ast_copy_string(l->lastnumberdialed, d->exten, sizeof(l->lastnumberdialed));
memset(d->exten, 0, sizeof(d->exten));
skinny_newcall(c);
return NULL;
}
} else {
/* It's a match, but they just typed a digit, and there is an ambiguous match,
so just set the timeout to matchdigittimeout and wait some more */
timeout = matchdigittimeout;
}
} else if (res == 0) {
ast_debug(1, "Not enough digits (%s) (and no ambiguous match)...\n", d->exten);
memset(d->exten, 0, sizeof(d->exten));
if (l->hookstate == SKINNY_OFFHOOK) {
transmit_start_tone(d, SKINNY_REORDER, l->instance, sub->callid);
}
if (sub->owner && sub->owner->_state != AST_STATE_UP) {
ast_indicate(c, -1);
ast_hangup(c);
}
return NULL;
} else if (!ast_canmatch_extension(c, c->context, d->exten, 1,
S_COR(c->caller.id.number.valid, c->caller.id.number.str, NULL))
&& ((d->exten[0] != '*') || (!ast_strlen_zero(d->exten) > 2))) {
ast_log(LOG_WARNING, "Can't match [%s] from '%s' in context %s\n", d->exten,
S_COR(c->caller.id.number.valid, c->caller.id.number.str, "<Unknown Caller>"),
c->context);
memset(d->exten, 0, sizeof(d->exten));
if (l->hookstate == SKINNY_OFFHOOK) {
transmit_start_tone(d, SKINNY_REORDER, l->instance, sub->callid);
/* hang out for 3 seconds to let congestion play */
ast_safe_sleep(c, 3000);
}
break;
}
if (!timeout) {
timeout = gendigittimeout;
}
if (len && !ast_ignore_pattern(c->context, d->exten)) {
ast_indicate(c, -1);
}
}
if (c)
ast_hangup(c);
memset(d->exten, 0, sizeof(d->exten));
return NULL;
}
| static int skinny_transfer | ( | struct skinny_subchannel * | sub | ) | [static] |
Definition at line 4305 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, ast_tone_zone_sound_unref(), ast_tone_zone_sound::data, LOG_DEBUG, LOG_WARNING, ast_channel::name, 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().
{
struct skinny_subchannel *xferor; /* the sub doing the transferring */
struct skinny_subchannel *xferee; /* the sub being transferred */
struct ast_tone_zone_sound *ts = NULL;
if (ast_bridged_channel(sub->owner) || ast_bridged_channel(sub->related->owner)) {
if (sub->xferor) {
xferor = sub;
xferee = sub->related;
} else {
xferor = sub;
xferee = sub->related;
}
if (skinnydebug) {
ast_debug(1, "Transferee channels (local/remote): %s and %s\n",
xferee->owner->name, ast_bridged_channel(xferee->owner)?ast_bridged_channel(xferee->owner)->name:"");
ast_debug(1, "Transferor channels (local/remote): %s and %s\n",
xferor->owner->name, ast_bridged_channel(xferor->owner)?ast_bridged_channel(xferor->owner)->name:"");
}
if (ast_bridged_channel(xferor->owner)) {
if (ast_bridged_channel(xferee->owner)) {
ast_queue_control(xferee->owner, AST_CONTROL_UNHOLD);
}
if (xferor->owner->_state == AST_STATE_RING) {
/* play ringing inband */
if ((ts = ast_get_indication_tone(xferor->owner->zone, "ring"))) {
ast_playtones_start(xferor->owner, 0, ts->data, 1);
ts = ast_tone_zone_sound_unref(ts);
}
}
if (skinnydebug)
ast_debug(1, "Transfer Masquerading %s to %s\n",
xferee->owner->name, ast_bridged_channel(xferor->owner)?ast_bridged_channel(xferor->owner)->name:"");
if (ast_channel_masquerade(xferee->owner, ast_bridged_channel(xferor->owner))) {
ast_log(LOG_WARNING, "Unable to masquerade %s as %s\n",
ast_bridged_channel(xferor->owner)->name, xferee->owner->name);
return -1;
}
} else if (ast_bridged_channel(xferee->owner)) {
ast_queue_control(xferee->owner, AST_CONTROL_UNHOLD);
if (xferor->owner->_state == AST_STATE_RING) {
/* play ringing inband */
if ((ts = ast_get_indication_tone(xferor->owner->zone, "ring"))) {
ast_playtones_start(xferor->owner, 0, ts->data, 1);
ts = ast_tone_zone_sound_unref(ts);
}
}
if (skinnydebug)
ast_debug(1, "Transfer Masquerading %s to %s\n",
xferor->owner->name, ast_bridged_channel(xferee->owner)?ast_bridged_channel(xferee->owner)->name:"");
if (ast_channel_masquerade(xferor->owner, ast_bridged_channel(xferee->owner))) {
ast_log(LOG_WARNING, "Unable to masquerade %s as %s\n",
ast_bridged_channel(xferee->owner)->name, xferor->owner->name);
return -1;
}
return 0;
} else {
if (option_debug)
ast_log(LOG_DEBUG, "Neither %s nor %s are in a bridge, nothing to transfer\n",
xferor->owner->name, xferee->owner->name);
}
}
return 0;
}
| static int skinny_unhold | ( | struct skinny_subchannel * | sub | ) | [static] |
Definition at line 4632 of file chan_skinny.c.
References AST_CONTROL_UNHOLD, ast_queue_control(), ast_verb, skinny_subchannel::callid, skinny_line::device, skinny_subchannel::onhold, skinny_subchannel::owner, skinny_subchannel::parent, SKINNY_CONNECTED, SKINNY_LAMP_ON, SKINNY_OFFHOOK, STIMULUS_LINE, transmit_activatecallplane(), transmit_callstate(), transmit_connect(), and transmit_lamp_indication().
Referenced by handle_hold_button(), and handle_soft_key_event_message().
{
struct skinny_line *l = sub->parent;
struct skinny_device *d = l->device;
/* Don't try to unhold a channel that doesn't exist */
if (!sub || !sub->owner)
return 0;
/* Channel is on hold, so we will unhold */
if (skinnydebug)
ast_verb(1, "Taking off Hold(%d)\n", l->instance);
ast_queue_control(sub->owner, AST_CONTROL_UNHOLD);
transmit_activatecallplane(d, l);
transmit_connect(d, sub);
transmit_callstate(d, sub->parent->instance, sub->callid, SKINNY_CONNECTED);
transmit_lamp_indication(d, STIMULUS_LINE, l->instance, SKINNY_LAMP_ON);
l->hookstate = SKINNY_OFFHOOK;
sub->onhold = 0;
return 1;
}
| static int skinny_unregister | ( | struct skinny_req * | req, |
| struct skinnysession * | s | ||
| ) | [static] |
Definition at line 1942 of file chan_skinny.c.
References AST_DEVICE_UNAVAILABLE, ast_devstate_changed(), ast_extension_state_del(), AST_LIST_TRAVERSE, ast_parse_allow_disallow(), skinny_line::device, skinnysession::device, EVENT_FLAG_SYSTEM, skinny_device::lines, manager_event, skinny_device::session, skinny_device::speeddials, skinny_speeddial::stateid, and unregister_exten().
Referenced by get_input(), handle_message(), and transmit_response().
{
struct skinny_device *d;
struct skinny_line *l;
struct skinny_speeddial *sd;
d = s->device;
if (d) {
d->session = NULL;
d->registered = 0;
AST_LIST_TRAVERSE(&d->speeddials, sd, list) {
if (sd->stateid > -1)
ast_extension_state_del(sd->stateid, NULL);
}
AST_LIST_TRAVERSE(&d->lines, l, list) {
if (l->device == d) {
l->device = NULL;
l->capability = 0;
ast_parse_allow_disallow(&l->prefs, &l->capability, "all", 0);
l->instance = 0;
manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", "ChannelType: Skinny\r\nPeer: Skinny/%s@%s\r\nPeerStatus: Unregistered\r\n", l->name, d->name);
unregister_exten(l);
ast_devstate_changed(AST_DEVICE_UNAVAILABLE, "Skinny/%s@%s", l->name, d->name);
}
}
}
return -1; /* main loop will destroy the session */
}
| static int skinny_write | ( | struct ast_channel * | ast, |
| struct ast_frame * | frame | ||
| ) | [static] |
Definition at line 4157 of file chan_skinny.c.
References AST_FRAME_IMAGE, AST_FRAME_VOICE, ast_getformatname(), ast_getformatname_multiple(), ast_log(), ast_mutex_lock, ast_mutex_unlock, ast_rtp_instance_write(), ast_frame_subclass::codec, 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.
{
struct skinny_subchannel *sub = ast->tech_pvt;
int res = 0;
if (frame->frametype != AST_FRAME_VOICE) {
if (frame->frametype == AST_FRAME_IMAGE) {
return 0;
} else {
ast_log(LOG_WARNING, "Can't send %d type frames with skinny_write\n", frame->frametype);
return 0;
}
} else {
if (!(frame->subclass.codec & ast->nativeformats)) {
char buf[256];
ast_log(LOG_WARNING, "Asked to transmit frame type %s, while native formats is %s (read/write = %s/%s)\n",
ast_getformatname(frame->subclass.codec),
ast_getformatname_multiple(buf, sizeof(buf), ast->nativeformats),
ast_getformatname(ast->readformat),
ast_getformatname(ast->writeformat));
return -1;
}
}
if (sub) {
ast_mutex_lock(&sub->lock);
if (sub->rtp) {
res = ast_rtp_instance_write(sub->rtp, frame);
}
ast_mutex_unlock(&sub->lock);
}
return res;
}
| static void start_rtp | ( | struct skinny_subchannel * | sub | ) | [static] |
Definition at line 3723 of file chan_skinny.c.
References ast_channel_set_fd(), ast_mutex_lock, ast_mutex_unlock, ast_rtp_codecs_packetization_set(), ast_rtp_instance_fd(), ast_rtp_instance_get_codecs(), ast_rtp_instance_new(), ast_rtp_instance_set_prop(), ast_rtp_instance_set_qos(), AST_RTP_PROPERTY_NAT, AST_RTP_PROPERTY_RTCP, ast_sockaddr_from_sin, bindaddr, skinny_line::device, skinny_subchannel::lock, skinny_subchannel::owner, skinny_subchannel::parent, 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().
{
struct skinny_line *l = sub->parent;
struct skinny_device *d = l->device;
int hasvideo = 0;
struct ast_sockaddr bindaddr_tmp;
ast_mutex_lock(&sub->lock);
/* Allocate the RTP */
ast_sockaddr_from_sin(&bindaddr_tmp, &bindaddr);
sub->rtp = ast_rtp_instance_new("asterisk", sched, &bindaddr_tmp, NULL);
if (hasvideo)
sub->vrtp = ast_rtp_instance_new("asterisk", sched, &bindaddr_tmp, NULL);
if (sub->rtp) {
ast_rtp_instance_set_prop(sub->rtp, AST_RTP_PROPERTY_RTCP, 1);
}
if (sub->vrtp) {
ast_rtp_instance_set_prop(sub->vrtp, AST_RTP_PROPERTY_RTCP, 1);
}
if (sub->rtp && sub->owner) {
ast_channel_set_fd(sub->owner, 0, ast_rtp_instance_fd(sub->rtp, 0));
ast_channel_set_fd(sub->owner, 1, ast_rtp_instance_fd(sub->rtp, 1));
}
if (hasvideo && sub->vrtp && sub->owner) {
ast_channel_set_fd(sub->owner, 2, ast_rtp_instance_fd(sub->vrtp, 0));
ast_channel_set_fd(sub->owner, 3, ast_rtp_instance_fd(sub->vrtp, 1));
}
if (sub->rtp) {
ast_rtp_instance_set_qos(sub->rtp, qos.tos_audio, qos.cos_audio, "Skinny RTP");
ast_rtp_instance_set_prop(sub->rtp, AST_RTP_PROPERTY_NAT, l->nat);
}
if (sub->vrtp) {
ast_rtp_instance_set_qos(sub->vrtp, qos.tos_video, qos.cos_video, "Skinny VRTP");
ast_rtp_instance_set_prop(sub->vrtp, AST_RTP_PROPERTY_NAT, l->nat);
}
/* Set Frame packetization */
if (sub->rtp)
ast_rtp_codecs_packetization_set(ast_rtp_instance_get_codecs(sub->rtp), sub->rtp, &l->prefs);
/* Create the RTP connection */
transmit_connect(d, sub);
ast_mutex_unlock(&sub->lock);
}
| static void transmit_activatecallplane | ( | struct skinny_device * | d, |
| struct skinny_line * | l | ||
| ) | [static] |
Definition at line 2437 of file chan_skinny.c.
References ACTIVATE_CALL_PLANE_MESSAGE, skinny_data::activatecallplane, skinny_req::data, htolel, activate_call_plane_message::lineInstance, req_alloc(), and transmit_response().
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_hangup(), skinny_hold(), and skinny_unhold().
{
struct skinny_req *req;
if (!(req = req_alloc(sizeof(struct activate_call_plane_message), ACTIVATE_CALL_PLANE_MESSAGE)))
return;
req->data.activatecallplane.lineInstance = htolel(l->instance);
transmit_response(d, req);
}
| 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 2169 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, call_info_message::reference, req_alloc(), transmit_response(), and call_info_message::type.
Referenced by skinny_answer(), skinny_call(), skinny_indicate(), and update_connectedline().
{
struct skinny_req *req;
/* We should not be able to get here without a device */
if (!d)
return;
if (!(req = req_alloc(sizeof(struct call_info_message), CALL_INFO_MESSAGE)))
return;
if (skinnydebug)
ast_verb(1, "Setting Callinfo to %s(%s) from %s(%s) on %s(%d)\n", fromname, fromnum, toname, tonum, d->name, instance);
if (fromname) {
ast_copy_string(req->data.callinfo.callingPartyName, fromname, sizeof(req->data.callinfo.callingPartyName));
}
if (fromnum) {
ast_copy_string(req->data.callinfo.callingParty, fromnum, sizeof(req->data.callinfo.callingParty));
}
if (toname) {
ast_copy_string(req->data.callinfo.calledPartyName, toname, sizeof(req->data.callinfo.calledPartyName));
}
if (tonum) {
ast_copy_string(req->data.callinfo.calledParty, tonum, sizeof(req->data.callinfo.calledParty));
}
req->data.callinfo.instance = htolel(instance);
req->data.callinfo.reference = htolel(callid);
req->data.callinfo.type = htolel(calltype);
transmit_response(d, req);
}
| static void transmit_callstate | ( | struct skinny_device * | d, |
| int | buttonInstance, | ||
| unsigned | callid, | ||
| int | state | ||
| ) | [static] |
Definition at line 2448 of file chan_skinny.c.
References CALL_STATE_MESSAGE, call_state_message::callReference, call_state_message::callState, skinny_data::callstate, skinny_req::data, htolel, call_state_message::lineInstance, req_alloc(), and transmit_response().
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_answer(), skinny_call(), skinny_extensionstate_cb(), skinny_hangup(), skinny_hold(), skinny_indicate(), skinny_unhold(), and update_connectedline().
{
struct skinny_req *req;
if (!(req = req_alloc(sizeof(struct call_state_message), CALL_STATE_MESSAGE)))
return;
req->data.callstate.callState = htolel(state);
req->data.callstate.lineInstance = htolel(buttonInstance);
req->data.callstate.callReference = htolel(callid);
transmit_response(d, req);
}
| static void transmit_cfwdstate | ( | struct skinny_device * | d, |
| struct skinny_line * | l | ||
| ) | [static] |
Definition at line 2461 of file chan_skinny.c.
References forward_stat_message::activeforward, ast_copy_string(), ast_strlen_zero(), 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, 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().
{
struct skinny_req *req;
int anyon = 0;
if (!(req = req_alloc(sizeof(struct forward_stat_message), FORWARD_STAT_MESSAGE)))
return;
if (l->cfwdtype & SKINNY_CFWD_ALL) {
if (!ast_strlen_zero(l->call_forward_all)) {
ast_copy_string(req->data.forwardstat.fwdallnum, l->call_forward_all, sizeof(req->data.forwardstat.fwdallnum));
req->data.forwardstat.fwdall = htolel(1);
anyon++;
} else {
req->data.forwardstat.fwdall = htolel(0);
}
}
if (l->cfwdtype & SKINNY_CFWD_BUSY) {
if (!ast_strlen_zero(l->call_forward_busy)) {
ast_copy_string(req->data.forwardstat.fwdbusynum, l->call_forward_busy, sizeof(req->data.forwardstat.fwdbusynum));
req->data.forwardstat.fwdbusy = htolel(1);
anyon++;
} else {
req->data.forwardstat.fwdbusy = htolel(0);
}
}
if (l->cfwdtype & SKINNY_CFWD_NOANSWER) {
if (!ast_strlen_zero(l->call_forward_noanswer)) {
ast_copy_string(req->data.forwardstat.fwdnoanswernum, l->call_forward_noanswer, sizeof(req->data.forwardstat.fwdnoanswernum));
req->data.forwardstat.fwdnoanswer = htolel(1);
anyon++;
} else {
req->data.forwardstat.fwdnoanswer = htolel(0);
}
}
req->data.forwardstat.lineNumber = htolel(l->instance);
if (anyon)
req->data.forwardstat.activeforward = htolel(7);
else
req->data.forwardstat.activeforward = htolel(0);
transmit_response(d, req);
}
| static void transmit_clear_display_message | ( | struct skinny_device * | d, |
| int | instance, | ||
| int | reference | ||
| ) | [static] |
Definition at line 2294 of file chan_skinny.c.
References ast_verb, CLEAR_DISPLAY_MESSAGE, req_alloc(), 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(), and skinny_hangup().
{
struct skinny_req *req;
if (!(req = req_alloc(0, CLEAR_DISPLAY_MESSAGE)))
return;
//what do we want hear CLEAR_DISPLAY_MESSAGE or CLEAR_PROMPT_STATUS???
//if we are clearing the display, it appears there is no instance and refernece info (size 0)
//req->data.clearpromptstatus.lineInstance = instance;
//req->data.clearpromptstatus.callReference = reference;
if (skinnydebug)
ast_verb(1, "Clearing Display\n");
transmit_response(d, req);
}
| static void transmit_clearpromptmessage | ( | struct skinny_device * | d, |
| int | instance, | ||
| int | callid | ||
| ) | [static] |
Definition at line 2363 of file chan_skinny.c.
References ast_verb, clear_prompt_message::callReference, CLEAR_PROMPT_MESSAGE, skinny_data::clearpromptstatus, skinny_req::data, htolel, clear_prompt_message::lineInstance, req_alloc(), and transmit_response().
Referenced by handle_callforward_button(), handle_onhook_message(), handle_soft_key_event_message(), handle_stimulus_message(), and skinny_hangup().
{
struct skinny_req *req;
if (!(req = req_alloc(sizeof(struct clear_prompt_message), CLEAR_PROMPT_MESSAGE)))
return;
req->data.clearpromptstatus.lineInstance = htolel(instance);
req->data.clearpromptstatus.callReference = htolel(callid);
if (skinnydebug)
ast_verb(1, "Clearing Prompt\n");
transmit_response(d, req);
}
| static void transmit_closereceivechannel | ( | struct skinny_device * | d, |
| struct skinny_subchannel * | sub | ||
| ) | [static] |
Definition at line 2393 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 handle_callforward_button(), handle_onhook_message(), handle_soft_key_event_message(), handle_stimulus_message(), skinny_hangup(), and skinny_hold().
{
struct skinny_req *req;
if (!(req = req_alloc(sizeof(struct close_receive_channel_message), CLOSE_RECEIVE_CHANNEL_MESSAGE)))
return;
req->data.closereceivechannel.conferenceId = htolel(0);
req->data.closereceivechannel.partyId = htolel(sub->callid);
transmit_response(d, req);
}
| static void transmit_connect | ( | struct skinny_device * | d, |
| struct skinny_subchannel * | sub | ||
| ) | [static] |
Definition at line 2201 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, 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, req_alloc(), and transmit_response().
Referenced by skinny_unhold(), and start_rtp().
{
struct skinny_req *req;
struct skinny_line *l = sub->parent;
struct ast_format_list fmt;
if (!(req = req_alloc(sizeof(struct open_receive_channel_message), OPEN_RECEIVE_CHANNEL_MESSAGE)))
return;
fmt = ast_codec_pref_getsize(&l->prefs, ast_best_codec(l->capability));
req->data.openreceivechannel.conferenceId = htolel(sub->callid);
req->data.openreceivechannel.partyId = htolel(sub->callid);
req->data.openreceivechannel.packets = htolel(fmt.cur_ms);
req->data.openreceivechannel.capability = htolel(codec_ast2skinny(fmt.bits));
req->data.openreceivechannel.echo = htolel(0);
req->data.openreceivechannel.bitrate = htolel(0);
transmit_response(d, req);
}
| static void transmit_definetimedate | ( | struct skinny_device * | d | ) | [static] |
Definition at line 2532 of file chan_skinny.c.
References ast_localtime(), ast_tvnow(), skinny_req::data, definetimedate_message::day, definetimedate_message::dayofweek, skinny_data::definetimedate, DEFINETIMEDATE_MESSAGE, definetimedate_message::hour, htolel, definetimedate_message::milliseconds, definetimedate_message::minute, definetimedate_message::month, req_alloc(), 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 handle_message(), handle_offhook_message(), and handle_onhook_message().
{
struct skinny_req *req;
struct timeval now = ast_tvnow();
struct ast_tm cmtime;
if (!(req = req_alloc(sizeof(struct definetimedate_message), DEFINETIMEDATE_MESSAGE)))
return;
ast_localtime(&now, &cmtime, NULL);
req->data.definetimedate.year = htolel(cmtime.tm_year+1900);
req->data.definetimedate.month = htolel(cmtime.tm_mon+1);
req->data.definetimedate.dayofweek = htolel(cmtime.tm_wday);
req->data.definetimedate.day = htolel(cmtime.tm_mday);
req->data.definetimedate.hour = htolel(cmtime.tm_hour);
req->data.definetimedate.minute = htolel(cmtime.tm_min);
req->data.definetimedate.seconds = htolel(cmtime.tm_sec);
req->data.definetimedate.milliseconds = htolel(cmtime.tm_usec / 1000);
req->data.definetimedate.timestamp = htolel(now.tv_sec);
transmit_response(d, req);
}
| static void transmit_dialednumber | ( | struct skinny_device * | d, |
| const char * | text, | ||
| int | instance, | ||
| int | callid | ||
| ) | [static] |
Definition at line 2379 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().
{
struct skinny_req *req;
if (!(req = req_alloc(sizeof(struct dialed_number_message), DIALED_NUMBER_MESSAGE)))
return;
ast_copy_string(req->data.dialednumber.dialedNumber, text, sizeof(req->data.dialednumber.dialedNumber));
req->data.dialednumber.lineInstance = htolel(instance);
req->data.dialednumber.callReference = htolel(callid);
transmit_response(d, req);
}
| static void transmit_displaynotify | ( | struct skinny_device * | d, |
| const char * | text, | ||
| int | t | ||
| ) | [static] |
Definition at line 2329 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().
{
struct skinny_req *req;
if (!(req = req_alloc(sizeof(struct display_notify_message), DISPLAY_NOTIFY_MESSAGE)))
return;
ast_copy_string(req->data.displaynotify.displayMessage, text, sizeof(req->data.displaynotify.displayMessage));
req->data.displaynotify.displayTimeout = htolel(t);
if (skinnydebug)
ast_verb(1, "Displaying notify '%s'\n", text);
transmit_response(d, req);
}
| static void transmit_displaypromptstatus | ( | struct skinny_device * | d, |
| const char * | text, | ||
| int | t, | ||
| int | instance, | ||
| int | callid | ||
| ) | [static] |
Definition at line 2345 of file chan_skinny.c.
References ast_copy_string(), ast_verb, display_prompt_status_message::callReference, skinny_req::data, DISPLAY_PROMPT_STATUS_MESSAGE, skinny_data::displaypromptstatus, htolel, display_prompt_status_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 update_connectedline().
{
struct skinny_req *req;
if (!(req = req_alloc(sizeof(struct display_prompt_status_message), DISPLAY_PROMPT_STATUS_MESSAGE)))
return;
ast_copy_string(req->data.displaypromptstatus.promptMessage, text, sizeof(req->data.displaypromptstatus.promptMessage));
req->data.displaypromptstatus.messageTimeout = htolel(t);
req->data.displaypromptstatus.lineInstance = htolel(instance);
req->data.displaypromptstatus.callReference = htolel(callid);
if (skinnydebug)
ast_verb(1, "Displaying Prompt Status '%s'\n", text);
transmit_response(d, req);
}
| static void transmit_lamp_indication | ( | struct skinny_device * | d, |
| int | stimulus, | ||
| int | instance, | ||
| int | indication | ||
| ) | [static] |
Definition at line 2256 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 handle_offhook_message(), handle_soft_key_event_message(), handle_stimulus_message(), mwi_event_cb(), skinny_call(), skinny_extensionstate_cb(), skinny_hangup(), skinny_hold(), skinny_ss(), and skinny_unhold().
{
struct skinny_req *req;
if (!(req = req_alloc(sizeof(struct set_lamp_message), SET_LAMP_MESSAGE)))
return;
req->data.setlamp.stimulus = htolel(stimulus);
req->data.setlamp.stimulusInstance = htolel(instance);
req->data.setlamp.deviceStimulus = htolel(indication);
transmit_response(d, req);
}
| static void transmit_linestatres | ( | struct skinny_device * | d, |
| struct skinny_line * | l | ||
| ) | [static] |
Definition at line 2519 of file chan_skinny.c.
References skinny_req::data, letohl, LINE_STAT_RES_MESSAGE, line_stat_res_message::lineDirNumber, line_stat_res_message::lineDisplayName, line_stat_res_message::lineNumber, skinny_data::linestat, req_alloc(), and transmit_response().
Referenced by handle_message().
{
struct skinny_req *req;
if (!(req = req_alloc(sizeof(struct line_stat_res_message), LINE_STAT_RES_MESSAGE)))
return;
req->data.linestat.lineNumber = letohl(l->instance);
memcpy(req->data.linestat.lineDirNumber, l->name, sizeof(req->data.linestat.lineDirNumber));
memcpy(req->data.linestat.lineDisplayName, l->label, sizeof(req->data.linestat.lineDisplayName));
transmit_response(d, req);
}
| static int transmit_response | ( | struct skinny_device * | d, |
| struct skinny_req * | req | ||
| ) | [static] |
Definition at line 2105 of file chan_skinny.c.
References ast_free, ast_log(), ast_mutex_lock, ast_mutex_unlock, ast_verb, skinny_req::data, skinny_req::e, errno, skinnysession::fd, skinny_req::len, letohl, skinnysession::lock, LOG_WARNING, skinnysession::outbuf, skinny_device::session, SKINNY_DEVONLY, SKINNY_MAX_PACKET, and skinny_unregister().
Referenced by handle_button_template_req_message(), handle_keep_alive_message(), handle_register_message(), handle_skinny_reset(), skinny_reload(), transmit_activatecallplane(), transmit_callinfo(), transmit_callstate(), transmit_cfwdstate(), transmit_clear_display_message(), transmit_clearpromptmessage(), transmit_closereceivechannel(), transmit_connect(), transmit_definetimedate(), transmit_dialednumber(), transmit_displaynotify(), transmit_displaypromptstatus(), transmit_lamp_indication(), transmit_linestatres(), transmit_ringer_mode(), transmit_selectsoftkeys(), transmit_serverres(), transmit_softkeysetres(), transmit_softkeytemplateres(), transmit_speaker_mode(), transmit_speeddialstatres(), transmit_start_tone(), transmit_startmediatransmission(), transmit_stop_tone(), transmit_stopmediatransmission(), and transmit_versionres().
{
struct skinnysession *s = d->session;
int res = 0;
if (!s) {
ast_log(LOG_WARNING, "Asked to transmit to a non-existent session!\n");
return -1;
}
ast_mutex_lock(&s->lock);
SKINNY_DEVONLY(if (skinnydebug>1) ast_verb(4, "Transmitting %s to %s\n", message2str(req->e), d->name);)
if ((letohl(req->len) > SKINNY_MAX_PACKET) || (letohl(req->len) < 0)) {
ast_log(LOG_WARNING, "transmit_response: the length of the request (%d) is out of bounds (%d)\n", letohl(req->len), SKINNY_MAX_PACKET);
ast_mutex_unlock(&s->lock);
return -1;
}
memset(s->outbuf, 0, sizeof(s->outbuf));
memcpy(s->outbuf, req, skinny_header_size);
memcpy(s->outbuf+skinny_header_size, &req->data, letohl(req->len));
res = write(s->fd, s->outbuf, letohl(req->len)+8);
if (res != letohl(req->len)+8) {
ast_log(LOG_WARNING, "Transmit: write only sent %d out of %d bytes: %s\n", res, letohl(req->len)+8, strerror(errno));
if (res == -1) {
if (skinnydebug)
ast_log(LOG_WARNING, "Transmit: Skinny Client was lost, unregistering\n");
skinny_unregister(NULL, s);
}
}
ast_free(req);
ast_mutex_unlock(&s->lock);
return 1;
}
| static void transmit_ringer_mode | ( | struct skinny_device * | d, |
| int | mode | ||
| ) | [static] |
Definition at line 2269 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().
{
struct skinny_req *req;
if (skinnydebug)
ast_verb(1, "Setting ringer mode to '%d'.\n", mode);
if (!(req = req_alloc(sizeof(struct set_ringer_message), SET_RINGER_MESSAGE)))
return;
req->data.setringer.ringerMode = htolel(mode);
/* XXX okay, I don't quite know what this is, but here's what happens (on a 7960).
Note: The phone will always show as ringing on the display.
1: phone will audibly ring over and over
2: phone will audibly ring only once
any other value, will NOT cause the phone to audibly ring
*/
req->data.setringer.unknown1 = htolel(1);
/* XXX the value here doesn't seem to change anything. Must be higher than 0.
Perhaps a packet capture can shed some light on this. */
req->data.setringer.unknown2 = htolel(1);
transmit_response(d, req);
}
| static void transmit_selectsoftkeys | ( | struct skinny_device * | d, |
| int | instance, | ||
| int | callid, | ||
| int | softkey | ||
| ) | [static] |
Definition at line 2242 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_message(), handle_offhook_message(), handle_onhook_message(), handle_soft_key_event_message(), handle_stimulus_message(), handle_transfer_button(), skinny_answer(), skinny_call(), and skinny_hangup().
{
struct skinny_req *req;
if (!(req = req_alloc(sizeof(struct select_soft_keys_message), SELECT_SOFT_KEYS_MESSAGE)))
return;
req->data.selectsoftkey.instance = htolel(instance);
req->data.selectsoftkey.reference = htolel(callid);
req->data.selectsoftkey.softKeySetIndex = htolel(softkey);
req->data.selectsoftkey.validKeyMask = htolel(0xFFFFFFFF);
transmit_response(d, req);
}
| static void transmit_serverres | ( | struct skinny_device * | d | ) | [static] |
Definition at line 2564 of file chan_skinny.c.
References skinny_req::data, 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().
{
struct skinny_req *req;
if (!(req = req_alloc(sizeof(struct server_res_message), SERVER_RES_MESSAGE)))
return;
memcpy(req->data.serverres.server[0].serverName, ourhost,
sizeof(req->data.serverres.server[0].serverName));
req->data.serverres.serverListenPort[0] = htolel(ourport);
req->data.serverres.serverIpAddr[0] = htolel(d->ourip.s_addr);
transmit_response(d, req);
}
| static void transmit_softkeysetres | ( | struct skinny_device * | d | ) | [static] |
Definition at line 2577 of file chan_skinny.c.
References ast_verbose(), soft_key_definitions::count, skinny_req::data, soft_key_definitions::defaults, htolel, htoles, soft_key_definitions::mode, req_alloc(), soft_key_default_definitions, SOFT_KEY_SET_RES_MESSAGE, soft_key_template_default, soft_key_set_definition::softKeyInfoIndex, soft_key_set_res_message::softKeySetCount, soft_key_set_res_message::softKeySetDefinition, soft_key_set_res_message::softKeySetOffset, skinny_data::softkeysets, soft_key_set_definition::softKeyTemplateIndex, soft_key_set_res_message::totalSoftKeySetCount, and transmit_response().
Referenced by handle_message().
{
struct skinny_req *req;
int i;
int x;
int y;
const struct soft_key_definitions *softkeymode = soft_key_default_definitions;
if (!(req = req_alloc(sizeof(struct soft_key_set_res_message), SOFT_KEY_SET_RES_MESSAGE)))
return;
req->data.softkeysets.softKeySetOffset = htolel(0);
req->data.softkeysets.softKeySetCount = htolel(11);
req->data.softkeysets.totalSoftKeySetCount = htolel(11);
for (x = 0; x < sizeof(soft_key_default_definitions) / sizeof(struct soft_key_definitions); x++) {
const uint8_t *defaults = softkeymode->defaults;
/* XXX I wanted to get the size of the array dynamically, but that wasn't wanting to work.
This will have to do for now. */
for (y = 0; y < softkeymode->count; y++) {
for (i = 0; i < (sizeof(soft_key_template_default) / sizeof(struct soft_key_template_definition)); i++) {
if (defaults[y] == i+1) {
req->data.softkeysets.softKeySetDefinition[softkeymode->mode].softKeyTemplateIndex[y] = (i+1);
req->data.softkeysets.softKeySetDefinition[softkeymode->mode].softKeyInfoIndex[y] = htoles(i+301);
if (skinnydebug)
ast_verbose("softKeySetDefinition : softKeyTemplateIndex: %d softKeyInfoIndex: %d\n", i+1, i+301);
}
}
}
softkeymode++;
}
transmit_response(d, req);
}
| static void transmit_softkeytemplateres | ( | struct skinny_device * | d | ) | [static] |
Definition at line 2610 of file chan_skinny.c.
References skinny_req::data, 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().
{
struct skinny_req *req;
if (!(req = req_alloc(sizeof(struct soft_key_template_res_message), SOFT_KEY_TEMPLATE_RES_MESSAGE)))
return;
req->data.softkeytemplate.softKeyOffset = htolel(0);
req->data.softkeytemplate.softKeyCount = htolel(sizeof(soft_key_template_default) / sizeof(struct soft_key_template_definition));
req->data.softkeytemplate.totalSoftKeyCount = htolel(sizeof(soft_key_template_default) / sizeof(struct soft_key_template_definition));
memcpy(req->data.softkeytemplate.softKeyTemplateDefinition,
soft_key_template_default,
sizeof(soft_key_template_default));
transmit_response(d, req);
}
| static void transmit_speaker_mode | ( | struct skinny_device * | d, |
| int | mode | ||
| ) | [static] |
Definition at line 2146 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_onhook_message(), handle_soft_key_event_message(), handle_stimulus_message(), and skinny_hangup().
{
struct skinny_req *req;
if (!(req = req_alloc(sizeof(struct set_speaker_message), SET_SPEAKER_MESSAGE)))
return;
req->data.setspeaker.mode = htolel(mode);
transmit_response(d, req);
}
| static void transmit_speeddialstatres | ( | struct skinny_device * | d, |
| struct skinny_speeddial * | sd | ||
| ) | [static] |
Definition at line 2505 of file chan_skinny.c.
References ast_copy_string(), skinny_req::data, skinny_speeddial::exten, htolel, skinny_speeddial::instance, skinny_speeddial::label, 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().
{
struct skinny_req *req;
if (!(req = req_alloc(sizeof(struct speed_dial_stat_res_message), SPEED_DIAL_STAT_RES_MESSAGE)))
return;
req->data.speeddialreq.speedDialNumber = htolel(sd->instance);
ast_copy_string(req->data.speeddial.speedDialDirNumber, sd->exten, sizeof(req->data.speeddial.speedDialDirNumber));
ast_copy_string(req->data.speeddial.speedDialDisplayName, sd->label, sizeof(req->data.speeddial.speedDialDisplayName));
transmit_response(d, req);
}
| static void transmit_start_tone | ( | struct skinny_device * | d, |
| int | tone, | ||
| int | instance, | ||
| int | reference | ||
| ) | [static] |
Definition at line 2221 of file chan_skinny.c.
References skinny_req::data, htolel, start_tone_message::instance, start_tone_message::reference, req_alloc(), START_TONE_MESSAGE, skinny_data::starttone, 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_indicate(), skinny_newcall(), and skinny_ss().
{
struct skinny_req *req;
if (!(req = req_alloc(sizeof(struct start_tone_message), START_TONE_MESSAGE)))
return;
req->data.starttone.tone = htolel(tone);
req->data.starttone.instance = htolel(instance);
req->data.starttone.reference = htolel(reference);
transmit_response(d, req);
}
| static void transmit_startmediatransmission | ( | struct skinny_device * | d, |
| struct skinny_subchannel * | sub, | ||
| struct sockaddr_in | dest, | ||
| struct ast_format_list | fmt | ||
| ) | [static] |
Definition at line 2417 of file chan_skinny.c.
References media_qualifier::bitRate, ast_format_list::bits, skinny_subchannel::callid, codec_ast2skinny(), start_media_transmission_message::conferenceId, ast_format_list::cur_ms, skinny_req::data, htolel, media_qualifier::packets, start_media_transmission_message::packetSize, start_media_transmission_message::passThruPartyId, start_media_transmission_message::payloadType, media_qualifier::precedence, start_media_transmission_message::qualifier, start_media_transmission_message::remoteIp, start_media_transmission_message::remotePort, req_alloc(), START_MEDIA_TRANSMISSION_MESSAGE, skinny_data::startmedia, transmit_response(), and media_qualifier::vad.
Referenced by handle_open_receive_channel_ack_message(), and skinny_set_rtp_peer().
{
struct skinny_req *req;
if (!(req = req_alloc(sizeof(struct start_media_transmission_message), START_MEDIA_TRANSMISSION_MESSAGE)))
return;
req->data.startmedia.conferenceId = htolel(sub->callid);
req->data.startmedia.passThruPartyId = htolel(sub->callid);
req->data.startmedia.remoteIp = dest.sin_addr.s_addr;
req->data.startmedia.remotePort = htolel(ntohs(dest.sin_port));
req->data.startmedia.packetSize = htolel(fmt.cur_ms);
req->data.startmedia.payloadType = htolel(codec_ast2skinny(fmt.bits));
req->data.startmedia.qualifier.precedence = htolel(127);
req->data.startmedia.qualifier.vad = htolel(0);
req->data.startmedia.qualifier.packets = htolel(0);
req->data.startmedia.qualifier.bitRate = htolel(0);
transmit_response(d, req);
}
| static void transmit_stop_tone | ( | struct skinny_device * | d, |
| int | instance, | ||
| int | reference | ||
| ) | [static] |
Definition at line 2232 of file chan_skinny.c.
References skinny_req::data, htolel, stop_tone_message::instance, stop_tone_message::reference, req_alloc(), STOP_TONE_MESSAGE, skinny_data::stoptone, and transmit_response().
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().
{
struct skinny_req *req;
if (!(req = req_alloc(sizeof(struct stop_tone_message), STOP_TONE_MESSAGE)))
return;
req->data.stoptone.instance = htolel(instance);
req->data.stoptone.reference = htolel(reference);
transmit_response(d, req);
}
| static void transmit_stopmediatransmission | ( | struct skinny_device * | d, |
| struct skinny_subchannel * | sub | ||
| ) | [static] |
Definition at line 2405 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 handle_callforward_button(), handle_onhook_message(), handle_soft_key_event_message(), handle_stimulus_message(), skinny_hangup(), skinny_hold(), and skinny_set_rtp_peer().
{
struct skinny_req *req;
if (!(req = req_alloc(sizeof(struct stop_media_transmission_message), STOP_MEDIA_TRANSMISSION_MESSAGE)))
return;
req->data.stopmedia.conferenceId = htolel(0);
req->data.stopmedia.passThruPartyId = htolel(sub->callid);
transmit_response(d, req);
}
| static void transmit_versionres | ( | struct skinny_device * | d | ) | [static] |
Definition at line 2554 of file chan_skinny.c.
References ast_copy_string(), skinny_req::data, req_alloc(), transmit_response(), version_res_message::version, skinny_data::version, and VERSION_RES_MESSAGE.
Referenced by handle_message().
{
struct skinny_req *req;
if (!(req = req_alloc(sizeof(struct version_res_message), VERSION_RES_MESSAGE)))
return;
ast_copy_string(req->data.version.version, d->version_id, sizeof(req->data.version.version));
transmit_response(d, req);
}
| static int unload_module | ( | void | ) | [static] |
Definition at line 7474 of file chan_skinny.c.
References skinny_subchannel::alreadygone, ARRAY_LEN, 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_manager_unregister(), ast_mutex_lock, ast_mutex_unlock, AST_PTHREADT_NULL, AST_PTHREADT_STOP, ast_rtp_glue_unregister(), ast_softhangup(), AST_SOFTHANGUP_APPUNLOAD, cli_skinny, delete_devices(), skinnysession::device, EVENT_FLAG_SYSTEM, skinnysession::fd, free, skinny_device::lines, skinny_subchannel::lock, skinny_line::lock, manager_event, monlock, skinny_line::mwi_event_sub, netlock, skinny_subchannel::owner, sched_context_destroy(), skinny_rtp_glue, skinny_tech, skinny_line::sub, skinnysession::t, and unregister_exten().
{
struct skinnysession *s;
struct skinny_device *d;
struct skinny_line *l;
struct skinny_subchannel *sub;
struct ast_context *con;
ast_rtp_glue_unregister(&skinny_rtp_glue);
ast_channel_unregister(&skinny_tech);
ast_cli_unregister_multiple(cli_skinny, ARRAY_LEN(cli_skinny));
ast_manager_unregister("SKINNYdevices");
ast_manager_unregister("SKINNYshowdevice");
ast_manager_unregister("SKINNYlines");
ast_manager_unregister("SKINNYshowline");
AST_LIST_LOCK(&sessions);
/* Destroy all the interfaces and free their memory */
while((s = AST_LIST_REMOVE_HEAD(&sessions, list))) {
d = s->device;
AST_LIST_TRAVERSE(&d->lines, l, list){
ast_mutex_lock(&l->lock);
AST_LIST_TRAVERSE(&l->sub, sub, list) {
ast_mutex_lock(&sub->lock);
if (sub->owner) {
sub->alreadygone = 1;
ast_softhangup(sub->owner, AST_SOFTHANGUP_APPUNLOAD);
}
ast_mutex_unlock(&sub->lock);
}
if (l->mwi_event_sub)
ast_event_unsubscribe(l->mwi_event_sub);
ast_mutex_unlock(&l->lock);
manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", "ChannelType: Skinny\r\nPeer: Skinny/%s@%s\r\nPeerStatus: Unregistered\r\n", l->name, d->name);
unregister_exten(l);
}
if (s->fd > -1)
close(s->fd);
pthread_cancel(s->t);
pthread_kill(s->t, SIGURG);
pthread_join(s->t, NULL);
free(s);
}
AST_LIST_UNLOCK(&sessions);
delete_devices();
ast_mutex_lock(&monlock);
if ((monitor_thread != AST_PTHREADT_NULL) && (monitor_thread != AST_PTHREADT_STOP)) {
pthread_cancel(monitor_thread);
pthread_kill(monitor_thread, SIGURG);
pthread_join(monitor_thread, NULL);
}
monitor_thread = AST_PTHREADT_STOP;
ast_mutex_unlock(&monlock);
ast_mutex_lock(&netlock);
if (accept_t && (accept_t != AST_PTHREADT_STOP)) {
pthread_cancel(accept_t);
pthread_kill(accept_t, SIGURG);
pthread_join(accept_t, NULL);
}
accept_t = AST_PTHREADT_STOP;
ast_mutex_unlock(&netlock);
close(skinnysock);
if (sched)
sched_context_destroy(sched);
con = ast_context_find(used_context);
if (con)
ast_context_destroy(con, "Skinny");
return 0;
}
| static void unregister_exten | ( | struct skinny_line * | l | ) | [static] |
Definition at line 1846 of file chan_skinny.c.
References ast_context_find(), ast_context_remove_extension(), ast_copy_string(), ast_log(), ast_strlen_zero(), context, ext, LOG_WARNING, regcontext, S_OR, and strsep().
Referenced by skinny_unregister(), and unload_module().
{
char multi[256];
char *stringp, *ext, *context;
if (ast_strlen_zero(regcontext))
return;
ast_copy_string(multi, S_OR(l->regexten, l->name), sizeof(multi));
stringp = multi;
while ((ext = strsep(&stringp, "&"))) {
if ((context = strchr(ext, '@'))) {
*context++ = '\0'; /* split ext@context */
if (!ast_context_find(context)) {
ast_log(LOG_WARNING, "Context %s must exist in regcontext= in skinny.conf!\n", context);
continue;
}
} else {
context = regcontext;
}
ast_context_remove_extension(context, ext, 1, NULL);
}
}
| static void update_connectedline | ( | struct skinny_subchannel * | sub, |
| const void * | data, | ||
| size_t | datalen | ||
| ) | [static] |
Definition at line 2674 of file chan_skinny.c.
References ast_channel::_state, AST_STATE_UP, ast_strlen_zero(), ast_channel::caller, skinny_subchannel::callid, ast_channel::connected, skinny_line::device, ast_party_caller::id, ast_party_connected_line::id, ast_party_id::name, ast_party_id::number, skinny_subchannel::outgoing, skinny_subchannel::owner, skinny_subchannel::parent, skinny_subchannel::progress, skinny_subchannel::ringing, S_COR, SKINNY_CONNECTED, SKINNY_PROGRESS, SKINNY_RINGIN, SKINNY_RINGOUT, ast_party_name::str, ast_party_number::str, transmit_callinfo(), transmit_callstate(), transmit_displaypromptstatus(), ast_party_name::valid, and ast_party_number::valid.
Referenced by skinny_indicate().
{
struct ast_channel *c = sub->owner;
struct skinny_line *l = sub->parent;
struct skinny_device *d = l->device;
if (!c->caller.id.number.valid
|| ast_strlen_zero(c->caller.id.number.str)
|| !c->connected.id.number.valid
|| ast_strlen_zero(c->connected.id.number.str))
return;
if (sub->owner->_state == AST_STATE_UP) {
transmit_callstate(d, l->instance, sub->callid, SKINNY_CONNECTED);
transmit_displaypromptstatus(d, "Connected", 0, l->instance, sub->callid);
if (sub->outgoing)
transmit_callinfo(d,
S_COR(c->connected.id.name.valid, c->connected.id.name.str, ""),
c->connected.id.number.str,
l->cid_name, l->cid_num, l->instance, sub->callid, 1);
else
transmit_callinfo(d, l->cid_name, l->cid_num,
S_COR(c->connected.id.name.valid, c->connected.id.name.str, ""),
c->connected.id.number.str,
l->instance, sub->callid, 2);
} else {
if (sub->outgoing) {
transmit_callstate(d, l->instance, sub->callid, SKINNY_RINGIN);
transmit_displaypromptstatus(d, "Ring-In", 0, l->instance, sub->callid);
transmit_callinfo(d,
S_COR(c->connected.id.name.valid, c->connected.id.name.str, ""),
c->connected.id.number.str,
l->cid_name, l->cid_num, l->instance, sub->callid, 1);
} else {
if (!sub->ringing) {
transmit_callstate(d, l->instance, sub->callid, SKINNY_RINGOUT);
transmit_displaypromptstatus(d, "Ring-Out", 0, l->instance, sub->callid);
sub->ringing = 1;
} else {
transmit_callstate(d, l->instance, sub->callid, SKINNY_PROGRESS);
transmit_displaypromptstatus(d, "Call Progress", 0, l->instance, sub->callid);
sub->progress = 1;
}
transmit_callinfo(d, l->cid_name, l->cid_num,
S_COR(c->connected.id.name.valid, c->connected.id.name.str, ""),
c->connected.id.number.str,
l->instance, sub->callid, 2);
}
}
}
struct ast_module_info __mod_info = { .name = AST_MODULE, .flags = AST_MODFLAG_LOAD_ORDER , .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 = AST_BUILDOPT_SUM, .load = load_module, .unload = unload_module, .reload = reload, .load_pri = AST_MODPRI_CHANNEL_DRIVER, } [static] |
Definition at line 7562 of file chan_skinny.c.
struct in_addr __ourip [static] |
Definition at line 1046 of file chan_skinny.c.
Referenced by config_load(), and skinny_register().
pthread_t accept_t [static] |
Definition at line 1050 of file chan_skinny.c.
struct ast_hostent ahp [static] |
Definition at line 1047 of file chan_skinny.c.
Referenced by config_load(), config_parse_variables(), and rpt_exec().
struct ast_module_info* ast_module_info = &__mod_info [static] |
Definition at line 7562 of file chan_skinny.c.
int auth_limit = DEFAULT_AUTH_LIMIT [static] |
Definition at line 177 of file chan_skinny.c.
int auth_timeout = DEFAULT_AUTH_TIMEOUT [static] |
Definition at line 176 of file chan_skinny.c.
struct sockaddr_in bindaddr [static] |
Definition at line 1043 of file chan_skinny.c.
int callnums = 1 [static] |
Definition at line 1051 of file chan_skinny.c.
struct ast_cli_entry cli_skinny[] [static] |
Definition at line 3712 of file chan_skinny.c.
Referenced by load_module(), and unload_module().
const char config[] = "skinny.conf" [static] |
Definition at line 145 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 245 of file chan_skinny.c.
Referenced by control2str().
| unsigned int cos |
Definition at line 170 of file chan_skinny.c.
| unsigned int cos_audio |
Definition at line 171 of file chan_skinny.c.
| unsigned int cos_video |
Definition at line 172 of file chan_skinny.c.
char date_format[6] = "D-M-Y" [static] |
Definition at line 182 of file chan_skinny.c.
format_t default_capability = AST_FORMAT_ULAW | AST_FORMAT_ALAW [static] |
Definition at line 147 of file chan_skinny.c.
Referenced by config_load(), and skinny_new().
struct skinny_device_options* default_device = &default_device_struct [static] |
Definition at line 1360 of file chan_skinny.c.
Referenced by config_device(), and config_load().
struct skinny_device_options default_device_struct [static] |
struct ast_jb_conf default_jbconf [static] |
Global jitterbuffer configuration - by default, jb is disabled
Definition at line 227 of file chan_skinny.c.
struct skinny_line_options* default_line = &default_line_struct [static] |
Definition at line 1287 of file chan_skinny.c.
Referenced by config_line(), and config_load().
struct skinny_line_options default_line_struct [static] |
struct ast_codec_pref default_prefs [static] |
Definition at line 148 of file chan_skinny.c.
Referenced by config_load(), and config_parse_variables().
struct ast_threadstorage device2str_threadbuf = { .once = PTHREAD_ONCE_INIT , .key_init = __init_device2str_threadbuf , .custom_init = NULL , } [static] |
Definition at line 242 of file chan_skinny.c.
Referenced by device2str().
int firstdigittimeout = 16000 [static] |
Definition at line 1170 of file chan_skinny.c.
Referenced by skinny_ss().
int gendigittimeout = 8000 [static] |
Definition at line 1173 of file chan_skinny.c.
Referenced by skinny_ss().
struct ast_jb_conf global_jbconf [static] |
Definition at line 235 of file chan_skinny.c.
Referenced by config_load(), config_parse_variables(), handle_skinny_show_settings(), and skinny_new().
char global_vmexten[AST_MAX_EXTENSION] [static] |
Definition at line 179 of file chan_skinny.c.
struct hostent* hp [static] |
Definition at line 1048 of file chan_skinny.c.
Referenced by __ast_http_load(), ast_parse_arg(), build_peer(), connect_sphinx(), create_addr(), gtalk_load_config(), gtalk_update_stun(), iax_template_parse(), jingle_load_config(), jingle_update_stun(), launch_netscript(), process_sdp(), realtime_peer(), realtime_user(), reload_config(), rpt_exec(), and set_config().
struct io_context* io [static] |
Definition at line 1157 of file chan_skinny.c.
int keep_alive = 120 [static] |
Definition at line 175 of file chan_skinny.c.
int matchdigittimeout = 3000 [static] |
Definition at line 1176 of file chan_skinny.c.
Referenced by skinny_ss().
pthread_t monitor_thread = AST_PTHREADT_NULL [static] |
Definition at line 1167 of file chan_skinny.c.
ast_mutex_t monlock = { PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP , NULL, 1 } [static] |
Definition at line 1161 of file chan_skinny.c.
Referenced by do_monitor(), restart_monitor(), and unload_module().
ast_mutex_t netlock = { PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP , NULL, 1 } [static] |
Definition at line 1163 of file chan_skinny.c.
Referenced by config_load(), and unload_module().
char ourhost[256] [static] |
Definition at line 1044 of file chan_skinny.c.
int ourport [static] |
Definition at line 1045 of file chan_skinny.c.
struct { ... } qos [static] |
Referenced by config_load(), config_parse_variables(), and start_rtp().
char regcontext[AST_MAX_CONTEXT] [static] |
Definition at line 181 of file chan_skinny.c.
Referenced by register_exten(), and unregister_exten().
struct sched_context* sched = NULL [static] |
Definition at line 1156 of file chan_skinny.c.
int skinny_header_size = 12 [static] |
Definition at line 1033 of file chan_skinny.c.
struct ast_rtp_glue skinny_rtp_glue [static] |
Definition at line 2870 of file chan_skinny.c.
Referenced by load_module(), and unload_module().
struct ast_channel_tech skinny_tech [static] |
Definition at line 1392 of file chan_skinny.c.
Referenced by load_module(), skinny_new(), and unload_module().
int skinnydebug = 0 [static] |
Definition at line 1039 of file chan_skinny.c.
int skinnyreload = 0 [static] |
Definition at line 1040 of file chan_skinny.c.
int skinnysock = -1 [static] |
Definition at line 1049 of file chan_skinny.c.
const uint8_t soft_key_default_connected[] [static] |
Definition at line 828 of file chan_skinny.c.
const uint8_t soft_key_default_connwithconf[] [static] |
{
SOFTKEY_NONE,
}
Definition at line 872 of file chan_skinny.c.
const uint8_t soft_key_default_connwithtrans[] [static] |
Definition at line 858 of file chan_skinny.c.
const uint8_t soft_key_default_dadfd[] [static] |
{
SOFTKEY_BKSPC,
SOFTKEY_ENDCALL,
}
Definition at line 867 of file chan_skinny.c.
struct soft_key_definitions soft_key_default_definitions[] [static] |
Definition at line 891 of file chan_skinny.c.
Referenced by transmit_softkeysetres().
const uint8_t soft_key_default_offhook[] [static] |
Definition at line 850 of file chan_skinny.c.
const uint8_t soft_key_default_offhookwithfeat[] [static] |
Definition at line 881 of file chan_skinny.c.
const uint8_t soft_key_default_onhold[] [static] |
Definition at line 837 of file chan_skinny.c.
const uint8_t soft_key_default_onhook[] [static] |
Definition at line 818 of file chan_skinny.c.
const uint8_t soft_key_default_ringin[] [static] |
Definition at line 844 of file chan_skinny.c.
const uint8_t soft_key_default_ringout[] [static] |
{
SOFTKEY_NONE,
SOFTKEY_ENDCALL,
}
Definition at line 876 of file chan_skinny.c.
const uint8_t soft_key_default_unknown[] [static] |
{
SOFTKEY_NONE,
}
Definition at line 887 of file chan_skinny.c.
struct soft_key_template_definition soft_key_template_default[] [static] |
Definition at line 655 of file chan_skinny.c.
Referenced by transmit_softkeysetres().
const char tdesc[] = "Skinny Client Control Protocol (Skinny)" [static] |
Definition at line 144 of file chan_skinny.c.
| unsigned int tos |
Definition at line 167 of file chan_skinny.c.
| unsigned int tos_audio |
Definition at line 168 of file chan_skinny.c.
| unsigned int tos_video |
Definition at line 169 of file chan_skinny.c.
int unauth_sessions = 0 [static] |
Definition at line 178 of file chan_skinny.c.
char used_context[AST_MAX_EXTENSION] [static] |
Definition at line 180 of file chan_skinny.c.
char version_id[16] = "P002F202" [static] |
Definition at line 183 of file chan_skinny.c.