#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 = "8586c2a7d357cb591cc3a6607a8f62d1" , .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 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 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 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" |
Definition in file chan_skinny.c.
#define ACTIVATE_CALL_PLANE_MESSAGE 0x0116 |
#define ALARM_MESSAGE 0x0020 |
#define BT_AUTOANSWER STIMULUS_AUTOANSWER |
Definition at line 534 of file chan_skinny.c.
#define BT_CALLPARK STIMULUS_CALLPARK |
#define BT_CALLPICKUP STIMULUS_CALLPICKUP |
Definition at line 538 of file chan_skinny.c.
#define BT_CONFERENCE STIMULUS_CONFERENCE |
#define BT_CUST_LINE 0xB1 |
Definition at line 545 of file chan_skinny.c.
Referenced by get_button_template(), and handle_button_template_req_message().
#define BT_CUST_LINESPEEDDIAL 0xB0 |
#define BT_DISPLAY STIMULUS_DISPLAY |
#define BT_DND STIMULUS_DND |
Definition at line 535 of file chan_skinny.c.
#define BT_FORWARDALL STIMULUS_FORWARDALL |
#define BT_FORWARDBUSY STIMULUS_FORWARDBUSY |
Definition at line 529 of file chan_skinny.c.
#define BT_FORWARDNOANSWER STIMULUS_FORWARDNOANSWER |
Definition at line 530 of file chan_skinny.c.
#define BT_HOLD STIMULUS_HOLD |
#define BT_LINE STIMULUS_LINE |
Definition at line 532 of file chan_skinny.c.
Referenced by get_button_template(), and handle_button_template_req_message().
#define BT_NONE 0x00 |
Definition at line 539 of file chan_skinny.c.
Referenced by get_button_template(), and handle_button_template_req_message().
#define BT_REDIAL STIMULUS_REDIAL |
#define BT_SPEEDDIAL STIMULUS_SPEEDDIAL |
#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 |
Definition at line 564 of file chan_skinny.c.
#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 |
Definition at line 559 of file chan_skinny.c.
#define ENBLOC_CALL_MESSAGE 0x0004 |
#define FORWARD_STAT_MESSAGE 0x0090 |
#define HEADSET_STATUS_MESSAGE 0x002B |
#define htolel | ( | x | ) | bswap_32(x) |
Definition at line 192 of file chan_skinny.c.
Referenced by get_input(), 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) |
#define IP_PORT_MESSAGE 0x0002 |
#define KEEP_ALIVE_ACK_MESSAGE 0x0100 |
#define KEEP_ALIVE_MESSAGE 0x0000 |
#define KEYDEF_CONNECTED 1 |
Definition at line 618 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 624 of file chan_skinny.c.
#define KEYDEF_CONNWITHTRANS 5 |
Definition at line 622 of file chan_skinny.c.
#define KEYDEF_DADFD 6 |
Definition at line 623 of file chan_skinny.c.
#define KEYDEF_OFFHOOK 4 |
Definition at line 621 of file chan_skinny.c.
Referenced by handle_offhook_message(), handle_soft_key_event_message(), and handle_stimulus_message().
#define KEYDEF_OFFHOOKWITHFEAT 9 |
#define KEYDEF_ONHOLD 2 |
Definition at line 619 of file chan_skinny.c.
Referenced by handle_hold_button(), and handle_soft_key_event_message().
#define KEYDEF_ONHOOK 0 |
Definition at line 617 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 |
#define KEYDEF_RINGOUT 8 |
Definition at line 625 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 627 of file chan_skinny.c.
#define KEYPAD_BUTTON_MESSAGE 0x0003 |
#define letohl | ( | x | ) | bswap_32(x) |
Definition at line 190 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 191 of file chan_skinny.c.
#define LINE_STAT_RES_MESSAGE 0x0092 |
#define LINE_STATE_REQ_MESSAGE 0x000B |
#define OFFHOOK_MESSAGE 0x0006 |
#define ONHOOK_MESSAGE 0x0007 |
#define OPEN_RECEIVE_CHANNEL_ACK_MESSAGE 0x0022 |
#define OPEN_RECEIVE_CHANNEL_MESSAGE 0x0105 |
#define REGISTER_ACK_MESSAGE 0x0081 |
#define REGISTER_AVAILABLE_LINES_MESSAGE 0x002D |
#define REGISTER_MESSAGE 0x0001 |
#define REGISTER_REJ_MESSAGE 0x009D |
#define RESET_MESSAGE 0x009F |
Definition at line 585 of file chan_skinny.c.
Referenced by handle_skinny_reset(), and skinny_reload().
#define SELECT_SOFT_KEYS_MESSAGE 0x0110 |
#define SERVER_REQUEST_MESSAGE 0x0012 |
#define SERVER_RES_MESSAGE 0x009E |
#define SET_LAMP_MESSAGE 0x0086 |
#define SET_MICROPHONE_MESSAGE 0x0089 |
Definition at line 401 of file chan_skinny.c.
#define SET_RINGER_MESSAGE 0x0085 |
#define SET_SPEAKER_MESSAGE 0x0088 |
#define SKINNY_ALERT 0x24 |
#define SKINNY_BUSY 6 |
#define SKINNY_BUSYTONE 0x23 |
#define SKINNY_CALLREMOTEMULTILINE 13 |
#define SKINNY_CALLWAIT 9 |
Definition at line 1102 of file chan_skinny.c.
#define SKINNY_CALLWAITTONE 0x2D |
#define SKINNY_CFWD_ALL (1 << 0) |
Definition at line 1128 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 1129 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 1130 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 |
#define SKINNY_CONNECTED 5 |
Definition at line 1098 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 1136 of file chan_skinny.c.
#define SKINNY_CX_CONFERENCE 3 |
Definition at line 1137 of file chan_skinny.c.
#define SKINNY_CX_INACTIVE 4 |
#define SKINNY_CX_MUTE 4 |
Definition at line 1138 of file chan_skinny.c.
#define SKINNY_CX_RECVONLY 1 |
Definition at line 1134 of file chan_skinny.c.
Referenced by handle_onhook_message(), and handle_soft_key_event_message().
#define SKINNY_CX_SENDONLY 0 |
Definition at line 1133 of file chan_skinny.c.
#define SKINNY_CX_SENDRECV 2 |
#define SKINNY_DEVICE_12 4 |
Definition at line 1054 of file chan_skinny.c.
Referenced by device2str(), and get_button_template().
#define SKINNY_DEVICE_12SP 3 |
Definition at line 1053 of file chan_skinny.c.
Referenced by device2str(), and get_button_template().
#define SKINNY_DEVICE_12SPPLUS 2 |
Definition at line 1052 of file chan_skinny.c.
Referenced by device2str(), and get_button_template().
#define SKINNY_DEVICE_30SPPLUS 1 |
Definition at line 1051 of file chan_skinny.c.
Referenced by device2str(), and get_button_template().
#define SKINNY_DEVICE_30VIP 5 |
Definition at line 1055 of file chan_skinny.c.
Referenced by device2str(), and get_button_template().
#define SKINNY_DEVICE_7902 30008 |
Definition at line 1081 of file chan_skinny.c.
Referenced by device2str(), and get_button_template().
#define SKINNY_DEVICE_7905 20000 |
Definition at line 1077 of file chan_skinny.c.
Referenced by device2str(), and get_button_template().
#define SKINNY_DEVICE_7906 369 |
Definition at line 1070 of file chan_skinny.c.
Referenced by device2str(), and get_button_template().
#define SKINNY_DEVICE_7910 6 |
Definition at line 1056 of file chan_skinny.c.
Referenced by device2str(), and get_button_template().
#define SKINNY_DEVICE_7911 307 |
Definition at line 1065 of file chan_skinny.c.
Referenced by device2str(), and get_button_template().
#define SKINNY_DEVICE_7912 30007 |
Definition at line 1080 of file chan_skinny.c.
Referenced by device2str(), and get_button_template().
#define SKINNY_DEVICE_7914 124 |
Definition at line 1063 of file chan_skinny.c.
Referenced by device2str(), and get_button_template().
#define SKINNY_DEVICE_7920 30002 |
Definition at line 1078 of file chan_skinny.c.
Referenced by device2str(), and get_button_template().
#define SKINNY_DEVICE_7921 365 |
Definition at line 1069 of file chan_skinny.c.
Referenced by device2str(), and get_button_template().
#define SKINNY_DEVICE_7931 348 |
Definition at line 1068 of file chan_skinny.c.
Referenced by device2str(), and get_button_template().
#define SKINNY_DEVICE_7935 9 |
Definition at line 1059 of file chan_skinny.c.
Referenced by device2str(), and get_button_template().
#define SKINNY_DEVICE_7936 30019 |
Definition at line 1084 of file chan_skinny.c.
Referenced by device2str(), and get_button_template().
#define SKINNY_DEVICE_7937 431 |
Definition at line 1072 of file chan_skinny.c.
Referenced by device2str(), and get_button_template().
#define SKINNY_DEVICE_7940 8 |
Definition at line 1058 of file chan_skinny.c.
Referenced by device2str(), and get_button_template().
#define SKINNY_DEVICE_7941 115 |
Definition at line 1061 of file chan_skinny.c.
Referenced by device2str(), and get_button_template().
#define SKINNY_DEVICE_7941GE 309 |
Definition at line 1067 of file chan_skinny.c.
Referenced by device2str(), and get_button_template().
#define SKINNY_DEVICE_7942 434 |
Definition at line 1073 of file chan_skinny.c.
Referenced by device2str(), and get_button_template().
#define SKINNY_DEVICE_7945 435 |
Definition at line 1074 of file chan_skinny.c.
Referenced by device2str(), and get_button_template().
#define SKINNY_DEVICE_7960 7 |
Definition at line 1057 of file chan_skinny.c.
Referenced by device2str(), and get_button_template().
#define SKINNY_DEVICE_7961 30018 |
Definition at line 1083 of file chan_skinny.c.
Referenced by device2str(), and get_button_template().
#define SKINNY_DEVICE_7961GE 308 |
Definition at line 1066 of file chan_skinny.c.
Referenced by device2str(), and get_button_template().
#define SKINNY_DEVICE_7962 404 |
Definition at line 1071 of file chan_skinny.c.
Referenced by device2str(), and get_button_template().
#define SKINNY_DEVICE_7965 436 |
Definition at line 1075 of file chan_skinny.c.
Referenced by device2str(), and get_button_template().
#define SKINNY_DEVICE_7970 30006 |
Definition at line 1079 of file chan_skinny.c.
Referenced by device2str(), and get_button_template().
#define SKINNY_DEVICE_7971 119 |
Definition at line 1062 of file chan_skinny.c.
Referenced by device2str(), and get_button_template().
#define SKINNY_DEVICE_7975 437 |
Definition at line 1076 of file chan_skinny.c.
Referenced by device2str(), and get_button_template().
#define SKINNY_DEVICE_7985 302 |
Definition at line 1064 of file chan_skinny.c.
Referenced by device2str(), and get_button_template().
#define SKINNY_DEVICE_ATA186 12 |
Definition at line 1060 of file chan_skinny.c.
Referenced by device2str(), and get_button_template().
#define SKINNY_DEVICE_CIPC 30016 |
Definition at line 1082 of file chan_skinny.c.
Referenced by device2str(), and get_button_template().
#define SKINNY_DEVICE_NONE 0 |
#define SKINNY_DEVICE_OPTIONS |
Definition at line 1308 of file chan_skinny.c.
#define SKINNY_DEVICE_SCCPGATEWAY_AN 30027 |
Definition at line 1085 of file chan_skinny.c.
Referenced by device2str(), and get_button_template().
#define SKINNY_DEVICE_SCCPGATEWAY_BRI 30028 |
Definition at line 1086 of file chan_skinny.c.
Referenced by device2str(), and get_button_template().
#define SKINNY_DEVICE_UNKNOWN -1 |
#define SKINNY_DEVONLY | ( | code | ) |
Definition at line 135 of file chan_skinny.c.
Referenced by handle_message(), and transmit_response().
#define SKINNY_DIALTONE 0x21 |
Definition at line 1110 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 1101 of file chan_skinny.c.
Referenced by skinny_extensionstate_cb(), and skinny_hold().
#define SKINNY_INVALID 14 |
Definition at line 1107 of file chan_skinny.c.
#define SKINNY_LAMP_BLINK 5 |
Definition at line 1121 of file chan_skinny.c.
Referenced by mwi_event_cb(), skinny_call(), skinny_extensionstate_cb(), and skinny_hangup().
#define SKINNY_LAMP_FLASH 4 |
#define SKINNY_LAMP_OFF 1 |
Definition at line 1117 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 1118 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 1119 of file chan_skinny.c.
Referenced by skinny_extensionstate_cb(), and skinny_hold().
#define SKINNY_LINE_OPTIONS |
Definition at line 1198 of file chan_skinny.c.
#define SKINNY_MAX_CAPABILITIES 18 |
#define SKINNY_MAX_PACKET 1000 |
Definition at line 159 of file chan_skinny.c.
Referenced by handle_register_message(), skinny_req_parse(), and transmit_response().
#define SKINNY_MICOFF 2 |
Definition at line 1092 of file chan_skinny.c.
#define SKINNY_MICON 1 |
Definition at line 1091 of file chan_skinny.c.
#define SKINNY_NOTONE 0x7F |
Definition at line 1115 of file chan_skinny.c.
#define SKINNY_OFFHOOK 1 |
Definition at line 1094 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 1095 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 1104 of file chan_skinny.c.
#define SKINNY_PROGRESS 12 |
Definition at line 1105 of file chan_skinny.c.
Referenced by skinny_indicate(), and update_connectedline().
#define SKINNY_REORDER 0x25 |
Definition at line 1113 of file chan_skinny.c.
Referenced by skinny_indicate(), skinny_newcall(), and skinny_ss().
#define SKINNY_RING_FEATURE 4 |
Definition at line 1126 of file chan_skinny.c.
#define SKINNY_RING_INSIDE 2 |
#define SKINNY_RING_OFF 1 |
Definition at line 1123 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 1125 of file chan_skinny.c.
#define SKINNY_RINGIN 4 |
Definition at line 1097 of file chan_skinny.c.
Referenced by skinny_call(), skinny_extensionstate_cb(), and update_connectedline().
#define SKINNY_RINGOUT 3 |
Definition at line 1096 of file chan_skinny.c.
Referenced by skinny_indicate(), and update_connectedline().
#define SKINNY_SILENCE 0x00 |
Definition at line 1109 of file chan_skinny.c.
#define SKINNY_SPEAKEROFF 2 |
Definition at line 1089 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 1088 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 1103 of file chan_skinny.c.
#define SOFT_KEY_EVENT_MESSAGE 0x0026 |
#define SOFT_KEY_SET_REQ_MESSAGE 0x0025 |
#define SOFT_KEY_SET_RES_MESSAGE 0x0109 |
#define SOFT_KEY_TEMPLATE_REQ_MESSAGE 0x0028 |
#define SOFT_KEY_TEMPLATE_RES_MESSAGE 0x0108 |
#define SOFTKEY_ANSWER 0x0B |
#define SOFTKEY_BKSPC 0x08 |
#define SOFTKEY_CFWDALL 0x05 |
#define SOFTKEY_CFWDBUSY 0x06 |
#define SOFTKEY_CFWDNOANSWER 0x07 |
#define SOFTKEY_CONFRN 0x0D |
#define SOFTKEY_DND 0x13 |
#define SOFTKEY_ENDCALL 0x09 |
#define SOFTKEY_GPICKUP 0x12 |
#define SOFTKEY_HOLD 0x03 |
#define SOFTKEY_IDIVERT 0x14 |
Definition at line 649 of file chan_skinny.c.
#define SOFTKEY_INFO 0x0C |
#define SOFTKEY_JOIN 0x0F |
#define SOFTKEY_MEETME 0x10 |
#define SOFTKEY_NEWCALL 0x02 |
#define SOFTKEY_NONE 0x00 |
#define SOFTKEY_PARK 0x0E |
#define SOFTKEY_PICKUP 0x11 |
#define SOFTKEY_REDIAL 0x01 |
#define SOFTKEY_RESUME 0x0A |
#define SOFTKEY_TRNSFER 0x04 |
#define SPEED_DIAL_STAT_REQ_MESSAGE 0x000A |
#define SPEED_DIAL_STAT_RES_MESSAGE 0x0091 |
#define START_MEDIA_TRANSMISSION_MESSAGE 0x008A |
#define START_TONE_MESSAGE 0x0082 |
#define STIMULUS_AUTOANSWER 0x11 |
Definition at line 516 of file chan_skinny.c.
#define STIMULUS_CALLPARK 0x7E |
#define STIMULUS_CALLPICKUP 0x7F |
Definition at line 520 of file chan_skinny.c.
#define STIMULUS_CONFERENCE 0x7D |
#define STIMULUS_DISPLAY 0x08 |
#define STIMULUS_DND 0x3F |
Definition at line 517 of file chan_skinny.c.
Referenced by handle_soft_key_event_message(), and handle_stimulus_message().
#define STIMULUS_FORWARDALL 0x05 |
Definition at line 510 of file chan_skinny.c.
Referenced by handle_stimulus_message(), and skinny_ss().
#define STIMULUS_FORWARDBUSY 0x06 |
#define STIMULUS_FORWARDNOANSWER 0x07 |
#define STIMULUS_HOLD 0x03 |
#define STIMULUS_LINE 0x09 |
Definition at line 514 of file chan_skinny.c.
Referenced by handle_offhook_message(), handle_soft_key_event_message(), handle_stimulus_message(), skinny_call(), skinny_extensionstate_cb(), skinny_hangup(), skinny_hold(), and skinny_unhold().
#define STIMULUS_MESSAGE 0x0005 |
#define STIMULUS_NONE 0xFF |
Definition at line 521 of file chan_skinny.c.
#define STIMULUS_REDIAL 0x01 |
#define STIMULUS_SPEEDDIAL 0x02 |
#define STIMULUS_TRANSFER 0x04 |
#define STIMULUS_VOICEMAIL 0x0F |
Definition at line 515 of file chan_skinny.c.
Referenced by handle_stimulus_message(), and mwi_event_cb().
#define STOP_MEDIA_TRANSMISSION_MESSAGE 0x008B |
#define STOP_TONE_MESSAGE 0x0083 |
#define TIME_DATE_REQ_MESSAGE 0x000D |
#define TYPE_DEF_DEVICE 2 |
Definition at line 6666 of file chan_skinny.c.
Referenced by config_load(), and config_parse_variables().
#define TYPE_DEF_LINE 4 |
Definition at line 6667 of file chan_skinny.c.
Referenced by config_load(), and config_parse_variables().
#define TYPE_DEVICE 8 |
Definition at line 6668 of file chan_skinny.c.
Referenced by config_device(), and config_parse_variables().
#define TYPE_GENERAL 1 |
Definition at line 6665 of file chan_skinny.c.
Referenced by config_load(), and config_parse_variables().
#define TYPE_LINE 16 |
Definition at line 6669 of file chan_skinny.c.
#define UNREGISTER_MESSAGE 0x0027 |
#define VERSION_REQ_MESSAGE 0x000F |
#define VERSION_RES_MESSAGE 0x0098 |
enum skinny_codecs |
SKINNY_CODEC_ALAW | |
SKINNY_CODEC_ULAW | |
SKINNY_CODEC_G723_1 | |
SKINNY_CODEC_G729A | |
SKINNY_CODEC_G726_32 | |
SKINNY_CODEC_H261 | |
SKINNY_CODEC_H263 |
Definition at line 147 of file chan_skinny.c.
00147 { 00148 SKINNY_CODEC_ALAW = 2, 00149 SKINNY_CODEC_ULAW = 4, 00150 SKINNY_CODEC_G723_1 = 9, 00151 SKINNY_CODEC_G729A = 12, 00152 SKINNY_CODEC_G726_32 = 82, /* XXX Which packing order does this translate to? */ 00153 SKINNY_CODEC_H261 = 100, 00154 SKINNY_CODEC_H263 = 101 00155 };
static void __init_control2str_threadbuf | ( | void | ) | [static] |
static void __init_device2str_threadbuf | ( | void | ) | [static] |
static void __reg_module | ( | void | ) | [static] |
Definition at line 7574 of file chan_skinny.c.
static void __unreg_module | ( | void | ) | [static] |
Definition at line 7574 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 3252 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, skinny_subchannel::list, 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().
03253 { 03254 struct skinny_device *d; 03255 struct skinny_line *l; 03256 struct skinny_speeddial *sd; 03257 struct skinny_addon *sa; 03258 char codec_buf[512]; 03259 03260 if (argc < 4) { 03261 return CLI_SHOWUSAGE; 03262 } 03263 03264 AST_LIST_LOCK(&devices); 03265 AST_LIST_TRAVERSE(&devices, d, list) { 03266 if (!strcasecmp(argv[3], d->id) || !strcasecmp(argv[3], d->name)) { 03267 int numlines = 0, numaddons = 0, numspeeddials = 0; 03268 03269 AST_LIST_TRAVERSE(&d->lines, l, list){ 03270 numlines++; 03271 } 03272 03273 AST_LIST_TRAVERSE(&d->addons, sa, list) { 03274 numaddons++; 03275 } 03276 03277 AST_LIST_TRAVERSE(&d->speeddials, sd, list) { 03278 numspeeddials++; 03279 } 03280 03281 if (type == 0) { /* CLI */ 03282 ast_cli(fd, "Name: %s\n", d->name); 03283 ast_cli(fd, "Id: %s\n", d->id); 03284 ast_cli(fd, "version: %s\n", S_OR(d->version_id, "Unknown")); 03285 ast_cli(fd, "Ip address: %s\n", (d->session ? ast_inet_ntoa(d->session->sin.sin_addr) : "Unknown")); 03286 ast_cli(fd, "Port: %d\n", (d->session ? ntohs(d->session->sin.sin_port) : 0)); 03287 ast_cli(fd, "Device Type: %s\n", device2str(d->type)); 03288 ast_cli(fd, "Conf Codecs:"); 03289 ast_getformatname_multiple(codec_buf, sizeof(codec_buf) - 1, d->confcapability); 03290 ast_cli(fd, "%s\n", codec_buf); 03291 ast_cli(fd, "Neg Codecs: "); 03292 ast_getformatname_multiple(codec_buf, sizeof(codec_buf) - 1, d->capability); 03293 ast_cli(fd, "%s\n", codec_buf); 03294 ast_cli(fd, "Registered: %s\n", (d->registered ? "Yes" : "No")); 03295 ast_cli(fd, "Lines: %d\n", numlines); 03296 AST_LIST_TRAVERSE(&d->lines, l, list) { 03297 ast_cli(fd, " %s (%s)\n", l->name, l->label); 03298 } 03299 AST_LIST_TRAVERSE(&d->addons, sa, list) { 03300 numaddons++; 03301 } 03302 ast_cli(fd, "Addons: %d\n", numaddons); 03303 AST_LIST_TRAVERSE(&d->addons, sa, list) { 03304 ast_cli(fd, " %s\n", sa->type); 03305 } 03306 AST_LIST_TRAVERSE(&d->speeddials, sd, list) { 03307 numspeeddials++; 03308 } 03309 ast_cli(fd, "Speeddials: %d\n", numspeeddials); 03310 AST_LIST_TRAVERSE(&d->speeddials, sd, list) { 03311 ast_cli(fd, " %s (%s) ishint: %d\n", sd->exten, sd->label, sd->isHint); 03312 } 03313 } else { /* manager */ 03314 astman_append(s, "Channeltype: SKINNY\r\n"); 03315 astman_append(s, "ObjectName: %s\r\n", d->name); 03316 astman_append(s, "ChannelObjectType: device\r\n"); 03317 astman_append(s, "Id: %s\r\n", d->id); 03318 astman_append(s, "version: %s\r\n", S_OR(d->version_id, "Unknown")); 03319 astman_append(s, "Ipaddress: %s\r\n", (d->session ? ast_inet_ntoa(d->session->sin.sin_addr) : "Unknown")); 03320 astman_append(s, "Port: %d\r\n", (d->session ? ntohs(d->session->sin.sin_port) : 0)); 03321 astman_append(s, "DeviceType: %s\r\n", device2str(d->type)); 03322 astman_append(s, "Codecs: "); 03323 ast_getformatname_multiple(codec_buf, sizeof(codec_buf) -1, d->confcapability); 03324 astman_append(s, "%s\r\n", codec_buf); 03325 astman_append(s, "CodecOrder: "); 03326 ast_getformatname_multiple(codec_buf, sizeof(codec_buf) -1, d->capability); 03327 astman_append(s, "%s\r\n", codec_buf); 03328 astman_append(s, "Devicestatus: %s\r\n", (d->registered?"registered":"unregistered")); 03329 astman_append(s, "NumberOfLines: %d\r\n", numlines); 03330 AST_LIST_TRAVERSE(&d->lines, l, list) { 03331 astman_append(s, "Line: %s (%s)\r\n", l->name, l->label); 03332 } 03333 astman_append(s, "NumberOfAddons: %d\r\n", numaddons); 03334 AST_LIST_TRAVERSE(&d->addons, sa, list) { 03335 astman_append(s, "Addon: %s\r\n", sa->type); 03336 } 03337 astman_append(s, "NumberOfSpeeddials: %d\r\n", numspeeddials); 03338 AST_LIST_TRAVERSE(&d->speeddials, sd, list) { 03339 astman_append(s, "Speeddial: %s (%s) ishint: %d\r\n", sd->exten, sd->label, sd->isHint); 03340 } 03341 } 03342 } 03343 } 03344 AST_LIST_UNLOCK(&devices); 03345 return CLI_SUCCESS; 03346 }
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 3141 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_subchannel::list, skinny_device::session, and skinnysession::sin.
Referenced by handle_skinny_show_devices(), and manager_skinny_show_devices().
03142 { 03143 struct skinny_device *d; 03144 struct skinny_line *l; 03145 const char *id; 03146 char idtext[256] = ""; 03147 int total_devices = 0; 03148 03149 if (s) { /* Manager - get ActionID */ 03150 id = astman_get_header(m, "ActionID"); 03151 if (!ast_strlen_zero(id)) 03152 snprintf(idtext, sizeof(idtext), "ActionID: %s\r\n", id); 03153 } 03154 03155 switch (argc) { 03156 case 3: 03157 break; 03158 default: 03159 return CLI_SHOWUSAGE; 03160 } 03161 03162 if (!s) { 03163 ast_cli(fd, "Name DeviceId IP Type R NL\n"); 03164 ast_cli(fd, "-------------------- ---------------- --------------- --------------- - --\n"); 03165 } 03166 03167 AST_LIST_LOCK(&devices); 03168 AST_LIST_TRAVERSE(&devices, d, list) { 03169 int numlines = 0; 03170 total_devices++; 03171 AST_LIST_TRAVERSE(&d->lines, l, list) { 03172 numlines++; 03173 } 03174 if (!s) { 03175 ast_cli(fd, "%-20s %-16s %-15s %-15s %c %2d\n", 03176 d->name, 03177 d->id, 03178 d->session?ast_inet_ntoa(d->session->sin.sin_addr):"", 03179 device2str(d->type), 03180 d->registered?'Y':'N', 03181 numlines); 03182 } else { 03183 astman_append(s, 03184 "Event: DeviceEntry\r\n%s" 03185 "Channeltype: SKINNY\r\n" 03186 "ObjectName: %s\r\n" 03187 "ChannelObjectType: device\r\n" 03188 "DeviceId: %s\r\n" 03189 "IPaddress: %s\r\n" 03190 "Type: %s\r\n" 03191 "Devicestatus: %s\r\n" 03192 "NumberOfLines: %d\r\n", 03193 idtext, 03194 d->name, 03195 d->id, 03196 d->session?ast_inet_ntoa(d->session->sin.sin_addr):"-none-", 03197 device2str(d->type), 03198 d->registered?"registered":"unregistered", 03199 numlines); 03200 } 03201 } 03202 AST_LIST_UNLOCK(&devices); 03203 03204 if (total) 03205 *total = total_devices; 03206 03207 return CLI_SUCCESS; 03208 }
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 3513 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, skinny_subchannel::list, 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().
03514 { 03515 struct skinny_device *d; 03516 struct skinny_line *l; 03517 struct ast_codec_pref *pref; 03518 int x = 0, codec = 0; 03519 char codec_buf[512]; 03520 char group_buf[256]; 03521 char cbuf[256]; 03522 03523 switch (argc) { 03524 case 4: 03525 break; 03526 case 6: 03527 break; 03528 default: 03529 return CLI_SHOWUSAGE; 03530 } 03531 03532 AST_LIST_LOCK(&devices); 03533 03534 /* Show all lines matching the one supplied */ 03535 AST_LIST_TRAVERSE(&devices, d, list) { 03536 if (argc == 6 && (strcasecmp(argv[5], d->id) && strcasecmp(argv[5], d->name))) { 03537 continue; 03538 } 03539 AST_LIST_TRAVERSE(&d->lines, l, list) { 03540 if (strcasecmp(argv[3], l->name)) { 03541 continue; 03542 } 03543 if (type == 0) { /* CLI */ 03544 ast_cli(fd, "Line: %s\n", l->name); 03545 ast_cli(fd, "On Device: %s\n", d->name); 03546 ast_cli(fd, "Line Label: %s\n", l->label); 03547 ast_cli(fd, "Extension: %s\n", S_OR(l->exten, "<not set>")); 03548 ast_cli(fd, "Context: %s\n", l->context); 03549 ast_cli(fd, "CallGroup: %s\n", ast_print_group(group_buf, sizeof(group_buf), l->callgroup)); 03550 ast_cli(fd, "PickupGroup: %s\n", ast_print_group(group_buf, sizeof(group_buf), l->pickupgroup)); 03551 ast_cli(fd, "Language: %s\n", S_OR(l->language, "<not set>")); 03552 ast_cli(fd, "Accountcode: %s\n", S_OR(l->accountcode, "<not set>")); 03553 ast_cli(fd, "AmaFlag: %s\n", ast_cdr_flags2str(l->amaflags)); 03554 ast_cli(fd, "CallerId Number: %s\n", S_OR(l->cid_num, "<not set>")); 03555 ast_cli(fd, "CallerId Name: %s\n", S_OR(l->cid_name, "<not set>")); 03556 ast_cli(fd, "Hide CallerId: %s\n", (l->hidecallerid ? "Yes" : "No")); 03557 ast_cli(fd, "CFwdAll: %s\n", S_COR((l->cfwdtype & SKINNY_CFWD_ALL), l->call_forward_all, "<not set>")); 03558 ast_cli(fd, "CFwdBusy: %s\n", S_COR((l->cfwdtype & SKINNY_CFWD_BUSY), l->call_forward_busy, "<not set>")); 03559 ast_cli(fd, "CFwdNoAnswer: %s\n", S_COR((l->cfwdtype & SKINNY_CFWD_NOANSWER), l->call_forward_noanswer, "<not set>")); 03560 ast_cli(fd, "VoicemailBox: %s\n", S_OR(l->mailbox, "<not set>")); 03561 ast_cli(fd, "VoicemailNumber: %s\n", S_OR(l->vmexten, "<not set>")); 03562 ast_cli(fd, "MWIblink: %d\n", l->mwiblink); 03563 ast_cli(fd, "Regextension: %s\n", S_OR(l->regexten, "<not set>")); 03564 ast_cli(fd, "Regcontext: %s\n", S_OR(l->regcontext, "<not set>")); 03565 ast_cli(fd, "MoHInterpret: %s\n", S_OR(l->mohinterpret, "<not set>")); 03566 ast_cli(fd, "MoHSuggest: %s\n", S_OR(l->mohsuggest, "<not set>")); 03567 ast_cli(fd, "Last dialed nr: %s\n", S_OR(l->lastnumberdialed, "<no calls made yet>")); 03568 ast_cli(fd, "Last CallerID: %s\n", S_OR(l->lastcallerid, "<not set>")); 03569 ast_cli(fd, "Transfer enabled: %s\n", (l->transfer ? "Yes" : "No")); 03570 ast_cli(fd, "Callwaiting: %s\n", (l->callwaiting ? "Yes" : "No")); 03571 ast_cli(fd, "3Way Calling: %s\n", (l->threewaycalling ? "Yes" : "No")); 03572 ast_cli(fd, "Can forward: %s\n", (l->cancallforward ? "Yes" : "No")); 03573 ast_cli(fd, "Do Not Disturb: %s\n", (l->dnd ? "Yes" : "No")); 03574 ast_cli(fd, "NAT: %s\n", (l->nat ? "Yes" : "No")); 03575 ast_cli(fd, "immediate: %s\n", (l->immediate ? "Yes" : "No")); 03576 ast_cli(fd, "Group: %d\n", l->group); 03577 ast_cli(fd, "Parkinglot: %s\n", S_OR(l->parkinglot, "<not set>")); 03578 ast_cli(fd, "Conf Codecs: "); 03579 ast_getformatname_multiple(codec_buf, sizeof(codec_buf) - 1, l->confcapability); 03580 ast_cli(fd, "%s\n", codec_buf); 03581 ast_cli(fd, "Neg Codecs: "); 03582 ast_getformatname_multiple(codec_buf, sizeof(codec_buf) - 1, l->capability); 03583 ast_cli(fd, "%s\n", codec_buf); 03584 ast_cli(fd, "Codec Order: ("); 03585 print_codec_to_cli(fd, &l->prefs); 03586 ast_cli(fd, ")\n"); 03587 ast_cli(fd, "\n"); 03588 } else { /* manager */ 03589 astman_append(s, "Channeltype: SKINNY\r\n"); 03590 astman_append(s, "ObjectName: %s\r\n", l->name); 03591 astman_append(s, "ChannelObjectType: line\r\n"); 03592 astman_append(s, "Device: %s\r\n", d->name); 03593 astman_append(s, "LineLabel: %s\r\n", l->label); 03594 astman_append(s, "Extension: %s\r\n", S_OR(l->exten, "<not set>")); 03595 astman_append(s, "Context: %s\r\n", l->context); 03596 astman_append(s, "CallGroup: %s\r\n", ast_print_group(group_buf, sizeof(group_buf), l->callgroup)); 03597 astman_append(s, "PickupGroup: %s\r\n", ast_print_group(group_buf, sizeof(group_buf), l->pickupgroup)); 03598 astman_append(s, "Language: %s\r\n", S_OR(l->language, "<not set>")); 03599 astman_append(s, "Accountcode: %s\r\n", S_OR(l->accountcode, "<not set>")); 03600 astman_append(s, "AMAflags: %s\r\n", ast_cdr_flags2str(l->amaflags)); 03601 astman_append(s, "Callerid: %s\r\n", ast_callerid_merge(cbuf, sizeof(cbuf), l->cid_name, l->cid_num, "")); 03602 astman_append(s, "HideCallerId: %s\r\n", (l->hidecallerid ? "Yes" : "No")); 03603 astman_append(s, "CFwdAll: %s\r\n", S_COR((l->cfwdtype & SKINNY_CFWD_ALL), l->call_forward_all, "<not set>")); 03604 astman_append(s, "CFwdBusy: %s\r\n", S_COR((l->cfwdtype & SKINNY_CFWD_BUSY), l->call_forward_busy, "<not set>")); 03605 astman_append(s, "CFwdNoAnswer: %s\r\n", S_COR((l->cfwdtype & SKINNY_CFWD_NOANSWER), l->call_forward_noanswer, "<not set>")); 03606 astman_append(s, "VoicemailBox: %s\r\n", S_OR(l->mailbox, "<not set>")); 03607 astman_append(s, "VoicemailNumber: %s\r\n", S_OR(l->vmexten, "<not set>")); 03608 astman_append(s, "MWIblink: %d\r\n", l->mwiblink); 03609 astman_append(s, "RegExtension: %s\r\n", S_OR(l->regexten, "<not set>")); 03610 astman_append(s, "Regcontext: %s\r\n", S_OR(l->regcontext, "<not set>")); 03611 astman_append(s, "MoHInterpret: %s\r\n", S_OR(l->mohinterpret, "<not set>")); 03612 astman_append(s, "MoHSuggest: %s\r\n", S_OR(l->mohsuggest, "<not set>")); 03613 astman_append(s, "LastDialedNr: %s\r\n", S_OR(l->lastnumberdialed, "<no calls made yet>")); 03614 astman_append(s, "LastCallerID: %s\r\n", S_OR(l->lastcallerid, "<not set>")); 03615 astman_append(s, "Transfer: %s\r\n", (l->transfer ? "Yes" : "No")); 03616 astman_append(s, "Callwaiting: %s\r\n", (l->callwaiting ? "Yes" : "No")); 03617 astman_append(s, "3WayCalling: %s\r\n", (l->threewaycalling ? "Yes" : "No")); 03618 astman_append(s, "CanForward: %s\r\n", (l->cancallforward ? "Yes" : "No")); 03619 astman_append(s, "DoNotDisturb: %s\r\n", (l->dnd ? "Yes" : "No")); 03620 astman_append(s, "NAT: %s\r\n", (l->nat ? "Yes" : "No")); 03621 astman_append(s, "immediate: %s\r\n", (l->immediate ? "Yes" : "No")); 03622 astman_append(s, "Group: %d\r\n", l->group); 03623 astman_append(s, "Parkinglot: %s\r\n", S_OR(l->parkinglot, "<not set>")); 03624 ast_getformatname_multiple(codec_buf, sizeof(codec_buf) - 1, l->confcapability); 03625 astman_append(s, "Codecs: %s\r\n", codec_buf); 03626 astman_append(s, "CodecOrder: "); 03627 pref = &l->prefs; 03628 for(x = 0; x < 32 ; x++) { 03629 codec = ast_codec_pref_index(pref, x); 03630 if (!codec) 03631 break; 03632 astman_append(s, "%s", ast_getformatname(codec)); 03633 if (x < 31 && ast_codec_pref_index(pref, x+1)) 03634 astman_append(s, ","); 03635 } 03636 astman_append(s, "\r\n"); 03637 } 03638 } 03639 } 03640 03641 AST_LIST_UNLOCK(&devices); 03642 return CLI_SUCCESS; 03643 }
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 3385 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, skinny_subchannel::list, ast_channel::name, skinny_subchannel::owner, and skinny_line::sub.
Referenced by handle_skinny_show_lines(), and manager_skinny_show_lines().
03386 { 03387 struct skinny_line *l; 03388 struct skinny_subchannel *sub; 03389 int total_lines = 0; 03390 int verbose = 0; 03391 const char *id; 03392 char idtext[256] = ""; 03393 03394 if (s) { /* Manager - get ActionID */ 03395 id = astman_get_header(m, "ActionID"); 03396 if (!ast_strlen_zero(id)) 03397 snprintf(idtext, sizeof(idtext), "ActionID: %s\r\n", id); 03398 } 03399 03400 switch (argc) { 03401 case 4: 03402 verbose = 1; 03403 break; 03404 case 3: 03405 verbose = 0; 03406 break; 03407 default: 03408 return CLI_SHOWUSAGE; 03409 } 03410 03411 if (!s) { 03412 ast_cli(fd, "Name Device Name Instance Label \n"); 03413 ast_cli(fd, "-------------------- -------------------- -------- --------------------\n"); 03414 } 03415 AST_LIST_LOCK(&lines); 03416 AST_LIST_TRAVERSE(&lines, l, all) { 03417 total_lines++; 03418 if (!s) { 03419 ast_cli(fd, "%-20s %-20s %8d %-20s\n", 03420 l->name, 03421 (l->device ? l->device->name : "Not connected"), 03422 l->instance, 03423 l->label); 03424 if (verbose) { 03425 AST_LIST_TRAVERSE(&l->sub, sub, list) { 03426 ast_cli(fd, " %s> %s to %s\n", 03427 (sub == l->activesub?"Active ":"Inactive"), 03428 sub->owner->name, 03429 (ast_bridged_channel(sub->owner)?ast_bridged_channel(sub->owner)->name:"") 03430 ); 03431 } 03432 } 03433 } else { 03434 astman_append(s, 03435 "Event: LineEntry\r\n%s" 03436 "Channeltype: SKINNY\r\n" 03437 "ObjectName: %s\r\n" 03438 "ChannelObjectType: line\r\n" 03439 "Device: %s\r\n" 03440 "Instance: %d\r\n" 03441 "Label: %s\r\n", 03442 idtext, 03443 l->name, 03444 (l->device?l->device->name:"None"), 03445 l->instance, 03446 l->label); 03447 } 03448 } 03449 AST_LIST_UNLOCK(&lines); 03450 03451 if (total) { 03452 *total = total_lines; 03453 } 03454 03455 return CLI_SUCCESS; 03456 }
static void* accept_thread | ( | void * | ignore | ) | [static] |
Definition at line 6506 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, skinny_subchannel::list, skinnysession::lock, LOG_ERROR, LOG_NOTICE, LOG_WARNING, skinnysession::sin, skinny_session(), skinnysession::start, and skinnysession::t.
Referenced by config_load().
06507 { 06508 int as; 06509 struct sockaddr_in sin; 06510 socklen_t sinlen; 06511 struct skinnysession *s; 06512 struct protoent *p; 06513 int arg = 1; 06514 06515 for (;;) { 06516 sinlen = sizeof(sin); 06517 as = accept(skinnysock, (struct sockaddr *)&sin, &sinlen); 06518 if (as < 0) { 06519 ast_log(LOG_NOTICE, "Accept returned -1: %s\n", strerror(errno)); 06520 continue; 06521 } 06522 06523 if (ast_atomic_fetchadd_int(&unauth_sessions, +1) >= auth_limit) { 06524 close(as); 06525 ast_atomic_fetchadd_int(&unauth_sessions, -1); 06526 continue; 06527 } 06528 06529 p = getprotobyname("tcp"); 06530 if(p) { 06531 if( setsockopt(as, p->p_proto, TCP_NODELAY, (char *)&arg, sizeof(arg) ) < 0 ) { 06532 ast_log(LOG_WARNING, "Failed to set Skinny tcp connection to TCP_NODELAY mode: %s\n", strerror(errno)); 06533 } 06534 } 06535 if (!(s = ast_calloc(1, sizeof(struct skinnysession)))) { 06536 close(as); 06537 ast_atomic_fetchadd_int(&unauth_sessions, -1); 06538 continue; 06539 } 06540 06541 memcpy(&s->sin, &sin, sizeof(sin)); 06542 ast_mutex_init(&s->lock); 06543 s->fd = as; 06544 06545 if(time(&s->start) == -1) { 06546 ast_log(LOG_ERROR, "error executing time(): %s; disconnecting client\n", strerror(errno)); 06547 destroy_session(s); 06548 continue; 06549 } 06550 06551 AST_LIST_LOCK(&sessions); 06552 AST_LIST_INSERT_HEAD(&sessions, s, list); 06553 AST_LIST_UNLOCK(&sessions); 06554 06555 if (ast_pthread_create(&s->t, NULL, skinny_session, s)) { 06556 destroy_session(s); 06557 } 06558 } 06559 if (skinnydebug) 06560 ast_verb(1, "killing accept thread\n"); 06561 close(as); 06562 return 0; 06563 }
static struct ast_variable* add_var | ( | const char * | buf, | |
struct ast_variable * | list | |||
) | [static] |
implement the setvar config line
Definition at line 1642 of file chan_skinny.c.
References ast_strdupa, ast_variable_new(), skinny_subchannel::list, and ast_variable::next.
01643 { 01644 struct ast_variable *tmpvar = NULL; 01645 char *varname = ast_strdupa(buf), *varval = NULL; 01646 01647 if ((varval = strchr(varname,'='))) { 01648 *varval++ = '\0'; 01649 if ((tmpvar = ast_variable_new(varname, varval, ""))) { 01650 tmpvar->next = list; 01651 list = tmpvar; 01652 } 01653 } 01654 return list; 01655 }
static void cleanup_stale_contexts | ( | char * | new, | |
char * | old | |||
) | [static] |
Definition at line 1803 of file chan_skinny.c.
References ast_context_destroy(), ast_context_find(), ast_copy_string(), AST_MAX_CONTEXT, and strsep().
01804 { 01805 char *oldcontext, *newcontext, *stalecontext, *stringp, newlist[AST_MAX_CONTEXT]; 01806 01807 while ((oldcontext = strsep(&old, "&"))) { 01808 stalecontext = '\0'; 01809 ast_copy_string(newlist, new, sizeof(newlist)); 01810 stringp = newlist; 01811 while ((newcontext = strsep(&stringp, "&"))) { 01812 if (strcmp(newcontext, oldcontext) == 0) { 01813 /* This is not the context you're looking for */ 01814 stalecontext = '\0'; 01815 break; 01816 } else if (strcmp(newcontext, oldcontext)) { 01817 stalecontext = oldcontext; 01818 } 01819 01820 } 01821 if (stalecontext) 01822 ast_context_destroy(ast_context_find(stalecontext), "Skinny"); 01823 } 01824 }
static int codec_ast2skinny | ( | format_t | astcodec | ) | [static] |
Definition at line 1746 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().
01747 { 01748 switch (astcodec) { 01749 case AST_FORMAT_ALAW: 01750 return SKINNY_CODEC_ALAW; 01751 case AST_FORMAT_ULAW: 01752 return SKINNY_CODEC_ULAW; 01753 case AST_FORMAT_G723_1: 01754 return SKINNY_CODEC_G723_1; 01755 case AST_FORMAT_G729A: 01756 return SKINNY_CODEC_G729A; 01757 case AST_FORMAT_G726_AAL2: /* XXX Is this right? */ 01758 return SKINNY_CODEC_G726_32; 01759 case AST_FORMAT_H261: 01760 return SKINNY_CODEC_H261; 01761 case AST_FORMAT_H263: 01762 return SKINNY_CODEC_H263; 01763 default: 01764 return 0; 01765 } 01766 }
static format_t codec_skinny2ast | ( | enum skinny_codecs | skinnycodec | ) | [static] |
Definition at line 1724 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().
01725 { 01726 switch (skinnycodec) { 01727 case SKINNY_CODEC_ALAW: 01728 return AST_FORMAT_ALAW; 01729 case SKINNY_CODEC_ULAW: 01730 return AST_FORMAT_ULAW; 01731 case SKINNY_CODEC_G723_1: 01732 return AST_FORMAT_G723_1; 01733 case SKINNY_CODEC_G729A: 01734 return AST_FORMAT_G729A; 01735 case SKINNY_CODEC_G726_32: 01736 return AST_FORMAT_G726_AAL2; /* XXX Is this right? */ 01737 case SKINNY_CODEC_H261: 01738 return AST_FORMAT_H261; 01739 case SKINNY_CODEC_H263: 01740 return AST_FORMAT_H263; 01741 default: 01742 return 0; 01743 } 01744 }
static char* complete_skinny_devices | ( | const char * | word, | |
int | state | |||
) | [static] |
Definition at line 2945 of file chan_skinny.c.
References AST_LIST_TRAVERSE, ast_strdup, and skinny_subchannel::list.
Referenced by complete_skinny_reset(), and complete_skinny_show_device().
02946 { 02947 struct skinny_device *d; 02948 char *result = NULL; 02949 int wordlen = strlen(word), which = 0; 02950 02951 AST_LIST_TRAVERSE(&devices, d, list) { 02952 if (!strncasecmp(word, d->id, wordlen) && ++which > state) 02953 result = ast_strdup(d->id); 02954 } 02955 02956 return result; 02957 }
static char* complete_skinny_reset | ( | const char * | line, | |
const char * | word, | |||
int | pos, | |||
int | state | |||
) | [static] |
Definition at line 2964 of file chan_skinny.c.
References ast_strdup, and complete_skinny_devices().
Referenced by handle_skinny_reset().
02965 { 02966 return (pos == 2 ? ast_strdup(complete_skinny_devices(word, state)) : NULL); 02967 }
static char* complete_skinny_show_device | ( | 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_show_device().
02960 { 02961 return (pos == 3 ? ast_strdup(complete_skinny_devices(word, state)) : NULL); 02962 }
static char* complete_skinny_show_line | ( | const char * | line, | |
const char * | word, | |||
int | pos, | |||
int | state | |||
) | [static] |
Definition at line 2969 of file chan_skinny.c.
References AST_LIST_TRAVERSE, ast_strdup, skinny_device::lines, and skinny_subchannel::list.
Referenced by handle_skinny_show_line().
02970 { 02971 struct skinny_device *d; 02972 struct skinny_line *l; 02973 char *result = NULL; 02974 int wordlen = strlen(word), which = 0; 02975 02976 if (pos != 3) 02977 return NULL; 02978 02979 AST_LIST_TRAVERSE(&devices, d, list) { 02980 AST_LIST_TRAVERSE(&d->lines, l, list) { 02981 if (!strncasecmp(word, l->name, wordlen) && ++which > state) 02982 result = ast_strdup(l->name); 02983 } 02984 } 02985 02986 return result; 02987 }
static struct skinny_device* config_device | ( | const char * | dname, | |
struct ast_variable * | v | |||
) | [static] |
Definition at line 7127 of file chan_skinny.c.
References 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_subchannel::list, skinny_line::lock, LOG_ERROR, LOG_NOTICE, skinny_subchannel::parent, skinny_device::session, skinny_line::sub, TYPE_DEVICE, and update().
Referenced by config_load().
07128 { 07129 struct skinny_device *d, *temp; 07130 struct skinny_line *l, *ltemp; 07131 struct skinny_subchannel *sub; 07132 int update = 0; 07133 07134 ast_log(LOG_NOTICE, "Configuring skinny device %s.\n", dname); 07135 07136 AST_LIST_LOCK(&devices); 07137 AST_LIST_TRAVERSE(&devices, temp, list) { 07138 if (!strcasecmp(dname, temp->name) && temp->prune) { 07139 update = 1; 07140 break; 07141 } 07142 } 07143 07144 if (!(d = ast_calloc(1, sizeof(*d)))) { 07145 ast_verb(1, "Unable to allocate memory for device %s.\n", dname); 07146 AST_LIST_UNLOCK(&devices); 07147 return NULL; 07148 } 07149 memcpy(d, default_device, sizeof(*default_device)); 07150 ast_mutex_init(&d->lock); 07151 ast_copy_string(d->name, dname, sizeof(d->name)); 07152 AST_LIST_INSERT_TAIL(&devices, d, list); 07153 07154 ast_mutex_lock(&d->lock); 07155 AST_LIST_UNLOCK(&devices); 07156 07157 config_parse_variables(TYPE_DEVICE, d, v); 07158 07159 if (!AST_LIST_FIRST(&d->lines)) { 07160 ast_log(LOG_ERROR, "A Skinny device must have at least one line!\n"); 07161 ast_mutex_unlock(&d->lock); 07162 return NULL; 07163 } 07164 if (/*d->addr.sin_addr.s_addr && */!ntohs(d->addr.sin_port)) { 07165 d->addr.sin_port = htons(DEFAULT_SKINNY_PORT); 07166 } 07167 07168 if (skinnyreload){ 07169 AST_LIST_LOCK(&devices); 07170 AST_LIST_TRAVERSE(&devices, temp, list) { 07171 if (strcasecmp(d->id, temp->id) || !temp->prune || !temp->session) { 07172 continue; 07173 } 07174 ast_mutex_lock(&d->lock); 07175 d->session = temp->session; 07176 d->session->device = d; 07177 07178 AST_LIST_LOCK(&d->lines); 07179 AST_LIST_TRAVERSE(&d->lines, l, list){ 07180 l->device = d; 07181 07182 AST_LIST_LOCK(&temp->lines); 07183 AST_LIST_TRAVERSE(&temp->lines, ltemp, list) { 07184 if (strcasecmp(l->name, ltemp->name)) { 07185 continue; 07186 } 07187 ast_mutex_lock(<emp->lock); 07188 l->instance = ltemp->instance; 07189 l->hookstate = ltemp->hookstate; 07190 if (!AST_LIST_EMPTY(<emp->sub)) { 07191 ast_mutex_lock(&l->lock); 07192 l->sub = ltemp->sub; 07193 AST_LIST_TRAVERSE(&l->sub, sub, list) { 07194 sub->parent = l; 07195 } 07196 ast_mutex_unlock(&l->lock); 07197 } 07198 ast_mutex_unlock(<emp->lock); 07199 } 07200 AST_LIST_UNLOCK(&temp->lines); 07201 } 07202 AST_LIST_UNLOCK(&d->lines); 07203 ast_mutex_unlock(&d->lock); 07204 } 07205 AST_LIST_UNLOCK(&devices); 07206 } 07207 07208 ast_mutex_unlock(&d->lock); 07209 07210 ast_verb(3, "%s config for device '%s'\n", update ? "Updated" : (skinnyreload ? "Reloaded" : "Created"), d->name); 07211 07212 return d; 07213 07214 }
static struct skinny_line* config_line | ( | const char * | lname, | |
struct ast_variable * | v | |||
) | [static] |
Definition at line 7069 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, LOG_NOTICE, mwi_event_cb(), strsep(), TYPE_LINE, and update().
Referenced by config_load().
07070 { 07071 struct skinny_line *l, *temp; 07072 int update = 0; 07073 07074 ast_log(LOG_NOTICE, "Configuring skinny line %s.\n", lname); 07075 07076 /* We find the old line and remove it just before the new 07077 line is created */ 07078 AST_LIST_LOCK(&lines); 07079 AST_LIST_TRAVERSE(&lines, temp, all) { 07080 if (!strcasecmp(lname, temp->name) && temp->prune) { 07081 update = 1; 07082 break; 07083 } 07084 } 07085 07086 if (!(l=ast_calloc(1, sizeof(*l)))) { 07087 ast_verb(1, "Unable to allocate memory for line %s.\n", lname); 07088 AST_LIST_UNLOCK(&lines); 07089 return NULL; 07090 } 07091 07092 memcpy(l, default_line, sizeof(*default_line)); 07093 ast_mutex_init(&l->lock); 07094 ast_copy_string(l->name, lname, sizeof(l->name)); 07095 AST_LIST_INSERT_TAIL(&lines, l, all); 07096 07097 ast_mutex_lock(&l->lock); 07098 AST_LIST_UNLOCK(&lines); 07099 07100 config_parse_variables(TYPE_LINE, l, v); 07101 07102 if (!ast_strlen_zero(l->mailbox)) { 07103 char *cfg_mailbox, *cfg_context; 07104 cfg_context = cfg_mailbox = ast_strdupa(l->mailbox); 07105 ast_verb(3, "Setting mailbox '%s' on line %s\n", cfg_mailbox, l->name); 07106 strsep(&cfg_context, "@"); 07107 if (ast_strlen_zero(cfg_context)) 07108 cfg_context = "default"; 07109 l->mwi_event_sub = ast_event_subscribe(AST_EVENT_MWI, mwi_event_cb, "skinny MWI subsciption", l, 07110 AST_EVENT_IE_MAILBOX, AST_EVENT_IE_PLTYPE_STR, cfg_mailbox, 07111 AST_EVENT_IE_CONTEXT, AST_EVENT_IE_PLTYPE_STR, cfg_context, 07112 AST_EVENT_IE_NEWMSGS, AST_EVENT_IE_PLTYPE_EXISTS, 07113 AST_EVENT_IE_END); 07114 } 07115 07116 ast_mutex_unlock(&l->lock); 07117 07118 /* We do not want to unlink or free the line yet, it needs 07119 to be available to detect a device reconfig when we load the 07120 devices. Old lines will be pruned after the reload completes */ 07121 07122 ast_verb(3, "%s config for line '%s'\n", update ? "Updated" : (skinnyreload ? "Reloaded" : "Created"), l->name); 07123 07124 return l; 07125 }
static int config_load | ( | void | ) | [static] |
Definition at line 7216 of file chan_skinny.c.
References 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, config_device(), config_flags, config_line(), config_parse_variables(), CONFIG_STATUS_FILEINVALID, default_device, default_jbconf, 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().
07217 { 07218 int on = 1; 07219 struct ast_config *cfg; 07220 char *cat; 07221 struct skinny_device *d; 07222 struct skinny_line *l; 07223 int oldport = ntohs(bindaddr.sin_port); 07224 struct ast_flags config_flags = { 0 }; 07225 07226 ast_log(LOG_NOTICE, "Configuring skinny from %s\n", config); 07227 07228 if (gethostname(ourhost, sizeof(ourhost))) { 07229 ast_log(LOG_WARNING, "Unable to get hostname, Skinny disabled.\n"); 07230 return 0; 07231 } 07232 cfg = ast_config_load(config, config_flags); 07233 07234 /* We *must* have a config file otherwise stop immediately */ 07235 if (!cfg || cfg == CONFIG_STATUS_FILEINVALID) { 07236 ast_log(LOG_NOTICE, "Unable to load config %s, Skinny disabled.\n", config); 07237 return -1; 07238 } 07239 memset(&bindaddr, 0, sizeof(bindaddr)); 07240 memset(&default_prefs, 0, sizeof(default_prefs)); 07241 07242 /* Copy the default jb config over global_jbconf */ 07243 memcpy(&global_jbconf, &default_jbconf, sizeof(struct ast_jb_conf)); 07244 07245 /* load the general section */ 07246 cat = ast_category_browse(cfg, "general"); 07247 config_parse_variables(TYPE_GENERAL, NULL, ast_variable_browse(cfg, "general")); 07248 07249 if (ntohl(bindaddr.sin_addr.s_addr)) { 07250 __ourip = bindaddr.sin_addr; 07251 } else { 07252 hp = ast_gethostbyname(ourhost, &ahp); 07253 if (!hp) { 07254 ast_log(LOG_WARNING, "Unable to get our IP address, Skinny disabled\n"); 07255 ast_config_destroy(cfg); 07256 return 0; 07257 } 07258 memcpy(&__ourip, hp->h_addr, sizeof(__ourip)); 07259 } 07260 if (!ntohs(bindaddr.sin_port)) { 07261 bindaddr.sin_port = ntohs(DEFAULT_SKINNY_PORT); 07262 } 07263 bindaddr.sin_family = AF_INET; 07264 07265 /* load the lines sections */ 07266 default_line->confcapability = default_capability; 07267 default_line->confprefs = default_prefs; 07268 config_parse_variables(TYPE_DEF_LINE, default_line, ast_variable_browse(cfg, "lines")); 07269 cat = ast_category_browse(cfg, "lines"); 07270 while (cat && strcasecmp(cat, "general") && strcasecmp(cat, "devices")) { 07271 l = config_line(cat, ast_variable_browse(cfg, cat)); 07272 cat = ast_category_browse(cfg, cat); 07273 } 07274 07275 /* load the devices sections */ 07276 default_device->confcapability = default_capability; 07277 default_device->confprefs = default_prefs; 07278 config_parse_variables(TYPE_DEF_DEVICE, default_device, ast_variable_browse(cfg, "devices")); 07279 cat = ast_category_browse(cfg, "devices"); 07280 while (cat && strcasecmp(cat, "general") && strcasecmp(cat, "lines")) { 07281 d = config_device(cat, ast_variable_browse(cfg, cat)); 07282 cat = ast_category_browse(cfg, cat); 07283 } 07284 07285 ast_mutex_lock(&netlock); 07286 if ((skinnysock > -1) && (ntohs(bindaddr.sin_port) != oldport)) { 07287 close(skinnysock); 07288 skinnysock = -1; 07289 } 07290 if (skinnysock < 0) { 07291 skinnysock = socket(AF_INET, SOCK_STREAM, 0); 07292 if(setsockopt(skinnysock, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on)) == -1) { 07293 ast_log(LOG_ERROR, "Set Socket Options failed: errno %d, %s\n", errno, strerror(errno)); 07294 ast_config_destroy(cfg); 07295 ast_mutex_unlock(&netlock); 07296 return 0; 07297 } 07298 if (skinnysock < 0) { 07299 ast_log(LOG_WARNING, "Unable to create Skinny socket: %s\n", strerror(errno)); 07300 } else { 07301 if (bind(skinnysock, (struct sockaddr *)&bindaddr, sizeof(bindaddr)) < 0) { 07302 ast_log(LOG_WARNING, "Failed to bind to %s:%d: %s\n", 07303 ast_inet_ntoa(bindaddr.sin_addr), ntohs(bindaddr.sin_port), 07304 strerror(errno)); 07305 close(skinnysock); 07306 skinnysock = -1; 07307 ast_config_destroy(cfg); 07308 ast_mutex_unlock(&netlock); 07309 return 0; 07310 } 07311 if (listen(skinnysock, DEFAULT_SKINNY_BACKLOG)) { 07312 ast_log(LOG_WARNING, "Failed to start listening to %s:%d: %s\n", 07313 ast_inet_ntoa(bindaddr.sin_addr), ntohs(bindaddr.sin_port), 07314 strerror(errno)); 07315 close(skinnysock); 07316 skinnysock = -1; 07317 ast_config_destroy(cfg); 07318 ast_mutex_unlock(&netlock); 07319 return 0; 07320 } 07321 ast_verb(2, "Skinny listening on %s:%d\n", 07322 ast_inet_ntoa(bindaddr.sin_addr), ntohs(bindaddr.sin_port)); 07323 ast_netsock_set_qos(skinnysock, qos.tos, qos.cos, "Skinny"); 07324 ast_pthread_create_background(&accept_t, NULL, accept_thread, NULL); 07325 } 07326 } 07327 ast_mutex_unlock(&netlock); 07328 ast_config_destroy(cfg); 07329 return 1; 07330 }
static void config_parse_variables | ( | int | type, | |
void * | item, | |||
struct ast_variable * | vptr | |||
) | [static] |
Definition at line 6676 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(), CDEV, CDEV_OPTS, cleanup_stale_contexts(), CLINE, CLINE_OPTS, context, DEFAULT_AUTH_LIMIT, DEFAULT_AUTH_TIMEOUT, default_prefs, exten, global_jbconf, skinny_speeddial::label, ast_variable::lineno, skinny_device::lines, skinny_subchannel::list, LOG_WARNING, ast_variable::name, ast_variable::next, qos, S_OR, strsep(), 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().
06677 { 06678 struct ast_variable *v; 06679 int lineInstance = 1; 06680 int speeddialInstance = 1; 06681 06682 while(vptr) { 06683 v = vptr; 06684 vptr = vptr->next; 06685 06686 if (type & (TYPE_GENERAL)) { 06687 char newcontexts[AST_MAX_CONTEXT]; 06688 char oldcontexts[AST_MAX_CONTEXT]; 06689 char *stringp, *context, *oldregcontext; 06690 if (!ast_jb_read_conf(&global_jbconf, v->name, v->value)) { 06691 v = v->next; 06692 continue; 06693 } 06694 if (!strcasecmp(v->name, "bindaddr")) { 06695 if (!(hp = ast_gethostbyname(v->value, &ahp))) { 06696 ast_log(LOG_WARNING, "Invalid address: %s\n", v->value); 06697 } else { 06698 memcpy(&bindaddr.sin_addr, hp->h_addr, sizeof(bindaddr.sin_addr)); 06699 } 06700 continue; 06701 } else if (!strcasecmp(v->name, "keepalive")) { 06702 keep_alive = atoi(v->value); 06703 continue; 06704 } else if (!strcasecmp(v->name, "authtimeout")) { 06705 int timeout = atoi(v->value); 06706 06707 if (timeout < 1) { 06708 ast_log(LOG_WARNING, "Invalid authtimeout value '%s', using default value\n", v->value); 06709 auth_timeout = DEFAULT_AUTH_TIMEOUT; 06710 } else { 06711 auth_timeout = timeout; 06712 } 06713 continue; 06714 } else if (!strcasecmp(v->name, "authlimit")) { 06715 int limit = atoi(v->value); 06716 06717 if (limit < 1) { 06718 ast_log(LOG_WARNING, "Invalid authlimit value '%s', using default value\n", v->value); 06719 auth_limit = DEFAULT_AUTH_LIMIT; 06720 } else { 06721 auth_limit = limit; 06722 } 06723 continue; 06724 } else if (!strcasecmp(v->name, "regcontext")) { 06725 ast_copy_string(newcontexts, v->value, sizeof(newcontexts)); 06726 stringp = newcontexts; 06727 /* Initialize copy of current global_regcontext for later use in removing stale contexts */ 06728 ast_copy_string(oldcontexts, regcontext, sizeof(oldcontexts)); 06729 oldregcontext = oldcontexts; 06730 /* Let's remove any contexts that are no longer defined in regcontext */ 06731 cleanup_stale_contexts(stringp, oldregcontext); 06732 /* Create contexts if they don't exist already */ 06733 while ((context = strsep(&stringp, "&"))) { 06734 ast_copy_string(used_context, context, sizeof(used_context)); 06735 ast_context_find_or_create(NULL, NULL, context, "Skinny"); 06736 } 06737 ast_copy_string(regcontext, v->value, sizeof(regcontext)); 06738 continue; 06739 } else if (!strcasecmp(v->name, "dateformat")) { 06740 memcpy(date_format, v->value, sizeof(date_format)); 06741 continue; 06742 } else if (!strcasecmp(v->name, "tos")) { 06743 if (ast_str2tos(v->value, &qos.tos)) 06744 ast_log(LOG_WARNING, "Invalid tos value at line %d, refer to QoS documentation\n", v->lineno); 06745 continue; 06746 } else if (!strcasecmp(v->name, "tos_audio")) { 06747 if (ast_str2tos(v->value, &qos.tos_audio)) 06748 ast_log(LOG_WARNING, "Invalid tos_audio value at line %d, refer to QoS documentation\n", v->lineno); 06749 continue; 06750 } else if (!strcasecmp(v->name, "tos_video")) { 06751 if (ast_str2tos(v->value, &qos.tos_video)) 06752 ast_log(LOG_WARNING, "Invalid tos_video value at line %d, refer to QoS documentation\n", v->lineno); 06753 continue; 06754 } else if (!strcasecmp(v->name, "cos")) { 06755 if (ast_str2cos(v->value, &qos.cos)) 06756 ast_log(LOG_WARNING, "Invalid cos value at line %d, refer to QoS documentation\n", v->lineno); 06757 continue; 06758 } else if (!strcasecmp(v->name, "cos_audio")) { 06759 if (ast_str2cos(v->value, &qos.cos_audio)) 06760 ast_log(LOG_WARNING, "Invalid cos_audio value at line %d, refer to QoS documentation\n", v->lineno); 06761 continue; 06762 } else if (!strcasecmp(v->name, "cos_video")) { 06763 if (ast_str2cos(v->value, &qos.cos_video)) 06764 ast_log(LOG_WARNING, "Invalid cos_video value at line %d, refer to QoS documentation\n", v->lineno); 06765 continue; 06766 } else if (!strcasecmp(v->name, "bindport")) { 06767 if (sscanf(v->value, "%5d", &ourport) == 1) { 06768 bindaddr.sin_port = htons(ourport); 06769 } else { 06770 ast_log(LOG_WARNING, "Invalid bindport '%s' at line %d of %s\n", v->value, v->lineno, config); 06771 } 06772 continue; 06773 } else if (!strcasecmp(v->name, "allow")) { 06774 ast_parse_allow_disallow(&default_prefs, &default_capability, v->value, 1); 06775 continue; 06776 } else if (!strcasecmp(v->name, "disallow")) { 06777 ast_parse_allow_disallow(&default_prefs, &default_capability, v->value, 0); 06778 continue; 06779 } 06780 } 06781 06782 if (!strcasecmp(v->name, "transfer")) { 06783 if (type & (TYPE_DEF_DEVICE | TYPE_DEVICE)) { 06784 CDEV_OPTS->transfer = ast_true(v->value); 06785 continue; 06786 } else if (type & (TYPE_DEF_LINE | TYPE_LINE)) { 06787 CLINE_OPTS->transfer = ast_true(v->value); 06788 continue; 06789 } 06790 } else if (!strcasecmp(v->name, "callwaiting")) { 06791 if (type & (TYPE_DEF_DEVICE | TYPE_DEVICE)) { 06792 CDEV_OPTS->callwaiting = ast_true(v->value); 06793 continue; 06794 } else if (type & (TYPE_DEF_LINE | TYPE_LINE)) { 06795 CLINE_OPTS->callwaiting = ast_true(v->value); 06796 continue; 06797 } 06798 } else if (!strcasecmp(v->name, "directmedia") || !strcasecmp(v->name, "canreinvite")) { 06799 if (type & (TYPE_DEF_LINE | TYPE_LINE)) { 06800 CLINE_OPTS->directmedia = ast_true(v->value); 06801 continue; 06802 } 06803 } else if (!strcasecmp(v->name, "nat")) { 06804 if (type & (TYPE_DEF_LINE | TYPE_LINE)) { 06805 CLINE_OPTS->nat = ast_true(v->value); 06806 continue; 06807 } 06808 } else if (!strcasecmp(v->name, "context")) { 06809 if (type & (TYPE_DEF_LINE | TYPE_LINE)) { 06810 ast_copy_string(CLINE_OPTS->context, v->value, sizeof(CLINE_OPTS->context)); 06811 continue; 06812 } 06813 }else if (!strcasecmp(v->name, "vmexten")) { 06814 if (type & (TYPE_DEF_DEVICE | TYPE_DEVICE)) { 06815 ast_copy_string(CDEV_OPTS->vmexten, v->value, sizeof(CDEV_OPTS->vmexten)); 06816 continue; 06817 } else if (type & (TYPE_DEF_LINE | TYPE_LINE)) { 06818 ast_copy_string(CLINE_OPTS->vmexten, v->value, sizeof(CLINE_OPTS->vmexten)); 06819 continue; 06820 } 06821 } else if (!strcasecmp(v->name, "mwiblink")) { 06822 if (type & (TYPE_DEF_DEVICE | TYPE_DEVICE)) { 06823 CDEV_OPTS->mwiblink = ast_true(v->value); 06824 continue; 06825 } else if (type & (TYPE_DEF_LINE | TYPE_LINE)) { 06826 CLINE_OPTS->mwiblink = ast_true(v->value); 06827 continue; 06828 } 06829 } else if (!strcasecmp(v->name, "linelabel")) { 06830 if (type & (TYPE_DEF_LINE | TYPE_LINE)) { 06831 ast_copy_string(CLINE_OPTS->label, v->value, sizeof(CLINE_OPTS->label)); 06832 continue; 06833 } 06834 } else if (!strcasecmp(v->name, "callerid")) { 06835 if (type & (TYPE_DEF_LINE | TYPE_LINE)) { 06836 if (!strcasecmp(v->value, "asreceived")) { 06837 CLINE_OPTS->cid_num[0] = '\0'; 06838 CLINE_OPTS->cid_name[0] = '\0'; 06839 } else { 06840 ast_callerid_split(v->value, CLINE_OPTS->cid_name, sizeof(CLINE_OPTS->cid_name), CLINE_OPTS->cid_num, sizeof(CLINE_OPTS->cid_num)); 06841 } 06842 continue; 06843 } 06844 } else if (!strcasecmp(v->name, "amaflags")) { 06845 if (type & (TYPE_DEF_LINE | TYPE_LINE)) { 06846 int tempamaflags = ast_cdr_amaflags2int(v->value); 06847 if (tempamaflags < 0) { 06848 ast_log(LOG_WARNING, "Invalid AMA flags: %s at line %d\n", v->value, v->lineno); 06849 } else { 06850 CLINE_OPTS->amaflags = tempamaflags; 06851 } 06852 continue; 06853 } 06854 } else if (!strcasecmp(v->name, "regexten")) { 06855 if (type & (TYPE_DEF_LINE | TYPE_LINE)) { 06856 ast_copy_string(CLINE_OPTS->regexten, v->value, sizeof(CLINE_OPTS->regexten)); 06857 continue; 06858 } 06859 } else if (!strcasecmp(v->name, "language")) { 06860 if (type & (TYPE_DEF_LINE | TYPE_LINE)) { 06861 ast_copy_string(CLINE_OPTS->language, v->value, sizeof(CLINE_OPTS->language)); 06862 continue; 06863 } 06864 } else if (!strcasecmp(v->name, "accountcode")) { 06865 if (type & (TYPE_DEF_LINE | TYPE_LINE)) { 06866 ast_copy_string(CLINE_OPTS->accountcode, v->value, sizeof(CLINE_OPTS->accountcode)); 06867 continue; 06868 } 06869 } else if (!strcasecmp(v->name, "mohinterpret") || !strcasecmp(v->name, "musiconhold")) { 06870 if (type & (TYPE_DEF_LINE | TYPE_LINE)) { 06871 ast_copy_string(CLINE_OPTS->mohinterpret, v->value, sizeof(CLINE_OPTS->mohinterpret)); 06872 continue; 06873 } 06874 } else if (!strcasecmp(v->name, "mohsuggest")) { 06875 if (type & (TYPE_DEF_LINE | TYPE_LINE)) { 06876 ast_copy_string(CLINE_OPTS->mohsuggest, v->value, sizeof(CLINE_OPTS->mohsuggest)); 06877 continue; 06878 } 06879 } else if (!strcasecmp(v->name, "callgroup")) { 06880 if (type & (TYPE_DEF_LINE | TYPE_LINE)) { 06881 CLINE_OPTS->callgroup = ast_get_group(v->value); 06882 continue; 06883 } 06884 } else if (!strcasecmp(v->name, "pickupgroup")) { 06885 if (type & (TYPE_DEF_LINE | TYPE_LINE)) { 06886 CLINE_OPTS->pickupgroup = ast_get_group(v->value); 06887 continue; 06888 } 06889 } else if (!strcasecmp(v->name, "immediate")) { 06890 if (type & (TYPE_DEF_DEVICE | TYPE_DEVICE | TYPE_DEF_LINE | TYPE_LINE)) { 06891 CLINE_OPTS->immediate = ast_true(v->value); 06892 continue; 06893 } 06894 } else if (!strcasecmp(v->name, "cancallforward")) { 06895 if (type & (TYPE_DEF_LINE | TYPE_LINE)) { 06896 CLINE_OPTS->cancallforward = ast_true(v->value); 06897 continue; 06898 } 06899 } else if (!strcasecmp(v->name, "mailbox")) { 06900 if (type & (TYPE_DEF_LINE | TYPE_LINE)) { 06901 ast_copy_string(CLINE_OPTS->mailbox, v->value, sizeof(CLINE_OPTS->mailbox)); 06902 continue; 06903 } 06904 } else if ( !strcasecmp(v->name, "parkinglot")) { 06905 if (type & (TYPE_DEF_LINE | TYPE_LINE)) { 06906 ast_copy_string(CLINE_OPTS->parkinglot, v->value, sizeof(CLINE_OPTS->parkinglot)); 06907 continue; 06908 } 06909 } else if (!strcasecmp(v->name, "hasvoicemail")) { 06910 if (type & (TYPE_LINE)) { 06911 if (ast_true(v->value) && ast_strlen_zero(CLINE->mailbox)) { 06912 ast_copy_string(CLINE->mailbox, CLINE->name, sizeof(CLINE->mailbox)); 06913 } 06914 continue; 06915 } 06916 } else if (!strcasecmp(v->name, "callreturn")) { 06917 if (type & (TYPE_DEF_LINE | TYPE_LINE)) { 06918 CLINE_OPTS->callreturn = ast_true(v->value); 06919 continue; 06920 } 06921 } else if (!strcasecmp(v->name, "threewaycalling")) { 06922 if (type & (TYPE_DEF_LINE | TYPE_LINE)) { 06923 CLINE_OPTS->threewaycalling = ast_true(v->value); 06924 continue; 06925 } 06926 } else if (!strcasecmp(v->name, "setvar")) { 06927 if (type & (TYPE_LINE)) { 06928 CLINE->chanvars = add_var(v->value, CLINE->chanvars); 06929 continue; 06930 } 06931 } else if (!strcasecmp(v->name, "earlyrtp")) { 06932 if (type & (TYPE_DEF_DEVICE | TYPE_DEVICE)) { 06933 CDEV_OPTS->earlyrtp = ast_true(v->value); 06934 continue; 06935 } 06936 } else if (!strcasecmp(v->name, "host")) { 06937 if (type & (TYPE_DEVICE)) { 06938 struct ast_sockaddr CDEV_addr_tmp; 06939 06940 if (ast_get_ip(&CDEV_addr_tmp, v->value)) { 06941 ast_log(LOG_WARNING, "Bad IP '%s' at line %d.\n", v->value, v->lineno); 06942 } 06943 ast_sockaddr_to_sin(&CDEV_addr_tmp, 06944 &CDEV->addr); 06945 continue; 06946 } 06947 } else if (!strcasecmp(v->name, "port")) { 06948 if (type & (TYPE_DEF_DEVICE)) { 06949 CDEV->addr.sin_port = htons(atoi(v->value)); 06950 continue; 06951 } 06952 } else if (!strcasecmp(v->name, "device")) { 06953 if (type & (TYPE_DEVICE)) { 06954 ast_copy_string(CDEV_OPTS->id, v->value, sizeof(CDEV_OPTS->id)); 06955 continue; 06956 } 06957 } else if (!strcasecmp(v->name, "permit") || !strcasecmp(v->name, "deny")) { 06958 if (type & (TYPE_DEVICE)) { 06959 CDEV->ha = ast_append_ha(v->name, v->value, CDEV->ha, NULL); 06960 continue; 06961 } 06962 } else if (!strcasecmp(v->name, "allow")) { 06963 if (type & (TYPE_DEF_DEVICE | TYPE_DEVICE)) { 06964 ast_parse_allow_disallow(&CDEV_OPTS->confprefs, &CDEV_OPTS->confcapability, v->value, 1); 06965 continue; 06966 } 06967 if (type & (TYPE_DEF_LINE | TYPE_LINE)) { 06968 ast_parse_allow_disallow(&CLINE_OPTS->confprefs, &CLINE_OPTS->confcapability, v->value, 1); 06969 continue; 06970 } 06971 } else if (!strcasecmp(v->name, "disallow")) { 06972 if (type & (TYPE_DEF_DEVICE | TYPE_DEVICE)) { 06973 ast_parse_allow_disallow(&CDEV_OPTS->confprefs, &CDEV_OPTS->confcapability, v->value, 0); 06974 continue; 06975 } 06976 if (type & (TYPE_DEF_LINE | TYPE_LINE)) { 06977 ast_parse_allow_disallow(&CLINE_OPTS->confprefs, &CLINE_OPTS->confcapability, v->value, 0); 06978 continue; 06979 } 06980 } else if (!strcasecmp(v->name, "version")) { 06981 if (type & (TYPE_DEF_DEVICE | TYPE_DEVICE)) { 06982 ast_copy_string(CDEV_OPTS->version_id, v->value, sizeof(CDEV_OPTS->version_id)); 06983 continue; 06984 } 06985 } else if (!strcasecmp(v->name, "line")) { 06986 if (type & (TYPE_DEVICE)) { 06987 struct skinny_line *l; 06988 AST_LIST_TRAVERSE(&lines, l, all) { 06989 if (!strcasecmp(v->value, l->name) && !l->prune) { 06990 06991 /* FIXME: temp solution about line conflicts */ 06992 struct skinny_device *d; 06993 struct skinny_line *l2; 06994 int lineinuse = 0; 06995 AST_LIST_TRAVERSE(&devices, d, list) { 06996 AST_LIST_TRAVERSE(&d->lines, l2, list) { 06997 if (l2 == l && strcasecmp(d->id, CDEV->id)) { 06998 ast_log(LOG_WARNING, "Line %s already used by %s. Not connecting to %s.\n", l->name, d->name, CDEV->name); 06999 lineinuse++; 07000 } 07001 } 07002 } 07003 if (!lineinuse) { 07004 if (!AST_LIST_FIRST(&CDEV->lines)) { 07005 CDEV->activeline = l; 07006 } 07007 lineInstance++; 07008 AST_LIST_INSERT_HEAD(&CDEV->lines, l, list); 07009 } 07010 break; 07011 } 07012 } 07013 continue; 07014 } 07015 } else if (!strcasecmp(v->name, "speeddial")) { 07016 if (type & (TYPE_DEVICE)) { 07017 struct skinny_speeddial *sd; 07018 if (!(sd = ast_calloc(1, sizeof(*sd)))) { 07019 ast_log(LOG_WARNING, "Unable to allocate memory for speeddial %s. Ignoring speeddial.\n", v->name); 07020 continue; 07021 } else { 07022 char buf[256]; 07023 char *stringp = buf, *exten, *context, *label; 07024 ast_copy_string(buf, v->value, sizeof(buf)); 07025 exten = strsep(&stringp, ","); 07026 if ((context = strchr(exten, '@'))) { 07027 *context++ = '\0'; 07028 } 07029 label = stringp; 07030 ast_mutex_init(&sd->lock); 07031 ast_copy_string(sd->exten, exten, sizeof(sd->exten)); 07032 if (!ast_strlen_zero(context)) { 07033 sd->isHint = 1; 07034 sd->instance = lineInstance++; 07035 ast_copy_string(sd->context, context, sizeof(sd->context)); 07036 } else { 07037 sd->isHint = 0; 07038 sd->instance = speeddialInstance++; 07039 sd->context[0] = '\0'; 07040 } 07041 ast_copy_string(sd->label, S_OR(label, exten), sizeof(sd->label)); 07042 sd->parent = CDEV; 07043 AST_LIST_INSERT_HEAD(&CDEV->speeddials, sd, list); 07044 } 07045 continue; 07046 } 07047 } else if (!strcasecmp(v->name, "addon")) { 07048 if (type & (TYPE_DEVICE)) { 07049 struct skinny_addon *a; 07050 if (!(a = ast_calloc(1, sizeof(*a)))) { 07051 ast_log(LOG_WARNING, "Unable to allocate memory for addon %s. Ignoring addon.\n", v->name); 07052 continue; 07053 } else { 07054 ast_mutex_init(&a->lock); 07055 ast_copy_string(a->type, v->value, sizeof(a->type)); 07056 AST_LIST_INSERT_HEAD(&CDEV->addons, a, list); 07057 } 07058 continue; 07059 } 07060 07061 } else { 07062 ast_log(LOG_WARNING, "Don't know keyword '%s' at line %d\n", v->name, v->lineno); 07063 continue; 07064 } 07065 ast_log(LOG_WARNING, "Invalid category used: %s at line %d\n", v->name, v->lineno); 07066 } 07067 }
static char* control2str | ( | int | ind | ) | [static] |
Definition at line 4258 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_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.
04258 { 04259 char *tmp; 04260 04261 switch (ind) { 04262 case AST_CONTROL_HANGUP: 04263 return "Other end has hungup"; 04264 case AST_CONTROL_RING: 04265 return "Local ring"; 04266 case AST_CONTROL_RINGING: 04267 return "Remote end is ringing"; 04268 case AST_CONTROL_ANSWER: 04269 return "Remote end has answered"; 04270 case AST_CONTROL_BUSY: 04271 return "Remote end is busy"; 04272 case AST_CONTROL_TAKEOFFHOOK: 04273 return "Make it go off hook"; 04274 case AST_CONTROL_OFFHOOK: 04275 return "Line is off hook"; 04276 case AST_CONTROL_CONGESTION: 04277 return "Congestion (circuits busy)"; 04278 case AST_CONTROL_FLASH: 04279 return "Flash hook"; 04280 case AST_CONTROL_WINK: 04281 return "Wink"; 04282 case AST_CONTROL_OPTION: 04283 return "Set a low-level option"; 04284 case AST_CONTROL_RADIO_KEY: 04285 return "Key Radio"; 04286 case AST_CONTROL_RADIO_UNKEY: 04287 return "Un-Key Radio"; 04288 case AST_CONTROL_PROGRESS: 04289 return "Remote end is making Progress"; 04290 case AST_CONTROL_PROCEEDING: 04291 return "Remote end is proceeding"; 04292 case AST_CONTROL_HOLD: 04293 return "Hold"; 04294 case AST_CONTROL_UNHOLD: 04295 return "Unhold"; 04296 case AST_CONTROL_SRCUPDATE: 04297 return "Media Source Update"; 04298 case AST_CONTROL_CONNECTED_LINE: 04299 return "Connected Line"; 04300 case AST_CONTROL_REDIRECTING: 04301 return "Redirecting"; 04302 case -1: 04303 return "Stop tone"; 04304 default: 04305 if (!(tmp = ast_threadstorage_get(&control2str_threadbuf, CONTROL2STR_BUFSIZE))) 04306 return "Unknown"; 04307 snprintf(tmp, CONTROL2STR_BUFSIZE, "UNKNOWN-%d", ind); 04308 return tmp; 04309 } 04310 }
static void delete_devices | ( | void | ) | [static] |
Definition at line 7332 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, skinny_subchannel::list, and skinny_device::speeddials.
Referenced by unload_module().
07333 { 07334 struct skinny_device *d; 07335 struct skinny_line *l; 07336 struct skinny_speeddial *sd; 07337 struct skinny_addon *a; 07338 07339 AST_LIST_LOCK(&devices); 07340 AST_LIST_LOCK(&lines); 07341 07342 /* Delete all devices */ 07343 while ((d = AST_LIST_REMOVE_HEAD(&devices, list))) { 07344 /* Delete all lines for this device */ 07345 while ((l = AST_LIST_REMOVE_HEAD(&d->lines, list))) { 07346 AST_LIST_REMOVE(&lines, l, all); 07347 free(l); 07348 } 07349 /* Delete all speeddials for this device */ 07350 while ((sd = AST_LIST_REMOVE_HEAD(&d->speeddials, list))) { 07351 free(sd); 07352 } 07353 /* Delete all addons for this device */ 07354 while ((a = AST_LIST_REMOVE_HEAD(&d->addons, list))) { 07355 free(a); 07356 } 07357 free(d); 07358 } 07359 AST_LIST_UNLOCK(&lines); 07360 AST_LIST_UNLOCK(&devices); 07361 }
static void destroy_session | ( | struct skinnysession * | s | ) | [static] |
Definition at line 6323 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, skinny_subchannel::list, skinnysession::lock, and LOG_WARNING.
Referenced by accept_thread(), fax_session_new(), fax_session_reserve(), and skinny_session().
06324 { 06325 struct skinnysession *cur; 06326 AST_LIST_LOCK(&sessions); 06327 AST_LIST_TRAVERSE_SAFE_BEGIN(&sessions, cur, list) { 06328 if (cur == s) { 06329 AST_LIST_REMOVE_CURRENT(list); 06330 if (s->fd > -1) 06331 close(s->fd); 06332 06333 if (!s->device) 06334 ast_atomic_fetchadd_int(&unauth_sessions, -1); 06335 06336 ast_mutex_destroy(&s->lock); 06337 06338 ast_free(s); 06339 } else { 06340 ast_log(LOG_WARNING, "Trying to delete nonexistent session %p?\n", s); 06341 } 06342 } 06343 AST_LIST_TRAVERSE_SAFE_END 06344 AST_LIST_UNLOCK(&sessions); 06345 }
static char* device2str | ( | int | type | ) | [static] |
Definition at line 3034 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().
03035 { 03036 char *tmp; 03037 03038 switch (type) { 03039 case SKINNY_DEVICE_NONE: 03040 return "No Device"; 03041 case SKINNY_DEVICE_30SPPLUS: 03042 return "30SP Plus"; 03043 case SKINNY_DEVICE_12SPPLUS: 03044 return "12SP Plus"; 03045 case SKINNY_DEVICE_12SP: 03046 return "12SP"; 03047 case SKINNY_DEVICE_12: 03048 return "12"; 03049 case SKINNY_DEVICE_30VIP: 03050 return "30VIP"; 03051 case SKINNY_DEVICE_7910: 03052 return "7910"; 03053 case SKINNY_DEVICE_7960: 03054 return "7960"; 03055 case SKINNY_DEVICE_7940: 03056 return "7940"; 03057 case SKINNY_DEVICE_7935: 03058 return "7935"; 03059 case SKINNY_DEVICE_ATA186: 03060 return "ATA186"; 03061 case SKINNY_DEVICE_7941: 03062 return "7941"; 03063 case SKINNY_DEVICE_7971: 03064 return "7971"; 03065 case SKINNY_DEVICE_7914: 03066 return "7914"; 03067 case SKINNY_DEVICE_7985: 03068 return "7985"; 03069 case SKINNY_DEVICE_7911: 03070 return "7911"; 03071 case SKINNY_DEVICE_7961GE: 03072 return "7961GE"; 03073 case SKINNY_DEVICE_7941GE: 03074 return "7941GE"; 03075 case SKINNY_DEVICE_7931: 03076 return "7931"; 03077 case SKINNY_DEVICE_7921: 03078 return "7921"; 03079 case SKINNY_DEVICE_7906: 03080 return "7906"; 03081 case SKINNY_DEVICE_7962: 03082 return "7962"; 03083 case SKINNY_DEVICE_7937: 03084 return "7937"; 03085 case SKINNY_DEVICE_7942: 03086 return "7942"; 03087 case SKINNY_DEVICE_7945: 03088 return "7945"; 03089 case SKINNY_DEVICE_7965: 03090 return "7965"; 03091 case SKINNY_DEVICE_7975: 03092 return "7975"; 03093 case SKINNY_DEVICE_7905: 03094 return "7905"; 03095 case SKINNY_DEVICE_7920: 03096 return "7920"; 03097 case SKINNY_DEVICE_7970: 03098 return "7970"; 03099 case SKINNY_DEVICE_7912: 03100 return "7912"; 03101 case SKINNY_DEVICE_7902: 03102 return "7902"; 03103 case SKINNY_DEVICE_CIPC: 03104 return "IP Communicator"; 03105 case SKINNY_DEVICE_7961: 03106 return "7961"; 03107 case SKINNY_DEVICE_7936: 03108 return "7936"; 03109 case SKINNY_DEVICE_SCCPGATEWAY_AN: 03110 return "SCCPGATEWAY_AN"; 03111 case SKINNY_DEVICE_SCCPGATEWAY_BRI: 03112 return "SCCPGATEWAY_BRI"; 03113 case SKINNY_DEVICE_UNKNOWN: 03114 return "Unknown"; 03115 default: 03116 if (!(tmp = ast_threadstorage_get(&device2str_threadbuf, DEVICE2STR_BUFSIZE))) 03117 return "Unknown"; 03118 snprintf(tmp, DEVICE2STR_BUFSIZE, "UNKNOWN-%d", type); 03119 return tmp; 03120 } 03121 }
static void* do_monitor | ( | void * | data | ) | [static] |
Definition at line 6565 of file chan_skinny.c.
References ast_io_wait(), ast_mutex_lock, ast_mutex_unlock, ast_sched_runq(), ast_sched_wait(), io, monlock, and sched.
06566 { 06567 int res; 06568 06569 /* This thread monitors all the interfaces which are not yet in use 06570 (and thus do not have a separate thread) indefinitely */ 06571 /* From here on out, we die whenever asked */ 06572 for(;;) { 06573 pthread_testcancel(); 06574 /* Wait for sched or io */ 06575 res = ast_sched_wait(sched); 06576 if ((res < 0) || (res > 1000)) { 06577 res = 1000; 06578 } 06579 res = ast_io_wait(io, res); 06580 ast_mutex_lock(&monlock); 06581 if (res >= 0) { 06582 ast_sched_runq(sched); 06583 } 06584 ast_mutex_unlock(&monlock); 06585 } 06586 /* Never reached */ 06587 return NULL; 06588 06589 }
static struct skinny_line* find_line_by_instance | ( | struct skinny_device * | d, | |
int | instance | |||
) | [static] |
Definition at line 1570 of file chan_skinny.c.
References AST_LIST_TRAVERSE, ast_log(), skinny_device::lines, skinny_subchannel::list, 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().
01571 { 01572 struct skinny_line *l; 01573 01574 /*Dialing from on hook or on a 7920 uses instance 0 in requests 01575 but we need to start looking at instance 1 */ 01576 01577 if (!instance) 01578 instance = 1; 01579 01580 AST_LIST_TRAVERSE(&d->lines, l, list){ 01581 if (l->instance == instance) 01582 break; 01583 } 01584 01585 if (!l) { 01586 ast_log(LOG_WARNING, "Could not find line with instance '%d' on device '%s'\n", instance, d->name); 01587 } 01588 return l; 01589 }
static struct skinny_line* find_line_by_name | ( | const char * | dest | ) | [static] |
Definition at line 1591 of file chan_skinny.c.
References ast_copy_string(), AST_LIST_LOCK, AST_LIST_TRAVERSE, AST_LIST_UNLOCK, ast_strlen_zero(), ast_verb, skinny_device::lines, and skinny_subchannel::list.
Referenced by skinny_devicestate(), and skinny_request().
01592 { 01593 struct skinny_line *l; 01594 struct skinny_line *tmpl = NULL; 01595 struct skinny_device *d; 01596 char line[256]; 01597 char *at; 01598 char *device; 01599 int checkdevice = 0; 01600 01601 ast_copy_string(line, dest, sizeof(line)); 01602 at = strchr(line, '@'); 01603 if (at) 01604 *at++ = '\0'; 01605 device = at; 01606 01607 if (!ast_strlen_zero(device)) 01608 checkdevice = 1; 01609 01610 AST_LIST_LOCK(&devices); 01611 AST_LIST_TRAVERSE(&devices, d, list){ 01612 if (checkdevice && tmpl) 01613 break; 01614 else if (!checkdevice) { 01615 /* This is a match, since we're checking for line on every device. */ 01616 } else if (!strcasecmp(d->name, device)) { 01617 if (skinnydebug) 01618 ast_verb(2, "Found device: %s\n", d->name); 01619 } else 01620 continue; 01621 01622 /* Found the device (or we don't care which device) */ 01623 AST_LIST_TRAVERSE(&d->lines, l, list){ 01624 /* Search for the right line */ 01625 if (!strcasecmp(l->name, line)) { 01626 if (tmpl) { 01627 ast_verb(2, "Ambiguous line name: %s\n", line); 01628 AST_LIST_UNLOCK(&devices); 01629 return NULL; 01630 } else 01631 tmpl = l; 01632 } 01633 } 01634 } 01635 AST_LIST_UNLOCK(&devices); 01636 return tmpl; 01637 }
static struct skinny_speeddial* find_speeddial_by_instance | ( | struct skinny_device * | d, | |
int | instance, | |||
int | isHint | |||
) | [static] |
Definition at line 1709 of file chan_skinny.c.
References AST_LIST_TRAVERSE, ast_log(), skinny_speeddial::instance, skinny_speeddial::isHint, skinny_subchannel::list, LOG_WARNING, and skinny_device::speeddials.
Referenced by handle_message(), and handle_stimulus_message().
01710 { 01711 struct skinny_speeddial *sd; 01712 01713 AST_LIST_TRAVERSE(&d->speeddials, sd, list) { 01714 if (sd->isHint == isHint && sd->instance == instance) 01715 break; 01716 } 01717 01718 if (!sd) { 01719 ast_log(LOG_WARNING, "Could not find speeddial with instance '%d' on device '%s'\n", instance, d->name); 01720 } 01721 return sd; 01722 }
static struct skinny_subchannel* find_subchannel_by_instance_reference | ( | struct skinny_device * | d, | |
int | instance, | |||
int | reference | |||
) | [static] |
Definition at line 1658 of file chan_skinny.c.
References AST_LIST_FIRST, AST_LIST_TRAVERSE, ast_log(), skinny_subchannel::callid, find_line_by_instance(), skinny_subchannel::list, 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().
01659 { 01660 struct skinny_line *l = find_line_by_instance(d, instance); 01661 struct skinny_subchannel *sub; 01662 01663 if (!l) { 01664 return NULL; 01665 } 01666 01667 /* 7920 phones set call reference to 0, so use the first 01668 sub-channel on the list. 01669 This MIGHT need more love to be right */ 01670 if (!reference) 01671 sub = AST_LIST_FIRST(&l->sub); 01672 else { 01673 AST_LIST_TRAVERSE(&l->sub, sub, list) { 01674 if (sub->callid == reference) 01675 break; 01676 } 01677 } 01678 if (!sub) { 01679 ast_log(LOG_WARNING, "Could not find subchannel with reference '%d' on '%s'\n", reference, d->name); 01680 } 01681 return sub; 01682 }
static struct skinny_subchannel* find_subchannel_by_reference | ( | struct skinny_device * | d, | |
int | reference | |||
) | [static] |
Definition at line 1685 of file chan_skinny.c.
References AST_LIST_TRAVERSE, ast_log(), skinny_subchannel::callid, skinny_device::lines, skinny_subchannel::list, LOG_WARNING, and skinny_line::sub.
Referenced by handle_open_receive_channel_ack_message().
01686 { 01687 struct skinny_line *l; 01688 struct skinny_subchannel *sub = NULL; 01689 01690 AST_LIST_TRAVERSE(&d->lines, l, list){ 01691 AST_LIST_TRAVERSE(&l->sub, sub, list){ 01692 if (sub->callid == reference) 01693 break; 01694 } 01695 if (sub) 01696 break; 01697 } 01698 01699 if (!l) { 01700 ast_log(LOG_WARNING, "Could not find any lines that contained a subchannel with reference '%d' on device '%s'\n", reference, d->name); 01701 } else { 01702 if (!sub) { 01703 ast_log(LOG_WARNING, "Could not find subchannel with reference '%d' on '%s@%s'\n", reference, l->name, d->name); 01704 } 01705 } 01706 return sub; 01707 }
static void* get_button_template | ( | struct skinnysession * | s, | |
struct button_definition_template * | btn | |||
) | [static] |
Definition at line 1419 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, skinny_subchannel::list, 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().
01420 { 01421 struct skinny_device *d = s->device; 01422 struct skinny_addon *a; 01423 int i; 01424 01425 switch (d->type) { 01426 case SKINNY_DEVICE_30SPPLUS: 01427 case SKINNY_DEVICE_30VIP: 01428 /* 13 rows, 2 columns */ 01429 for (i = 0; i < 4; i++) 01430 (btn++)->buttonDefinition = BT_CUST_LINE; 01431 (btn++)->buttonDefinition = BT_REDIAL; 01432 (btn++)->buttonDefinition = BT_VOICEMAIL; 01433 (btn++)->buttonDefinition = BT_CALLPARK; 01434 (btn++)->buttonDefinition = BT_FORWARDALL; 01435 (btn++)->buttonDefinition = BT_CONFERENCE; 01436 for (i = 0; i < 4; i++) 01437 (btn++)->buttonDefinition = BT_NONE; 01438 for (i = 0; i < 13; i++) 01439 (btn++)->buttonDefinition = BT_SPEEDDIAL; 01440 01441 break; 01442 case SKINNY_DEVICE_12SPPLUS: 01443 case SKINNY_DEVICE_12SP: 01444 case SKINNY_DEVICE_12: 01445 /* 6 rows, 2 columns */ 01446 for (i = 0; i < 2; i++) 01447 (btn++)->buttonDefinition = BT_CUST_LINE; 01448 for (i = 0; i < 4; i++) 01449 (btn++)->buttonDefinition = BT_SPEEDDIAL; 01450 (btn++)->buttonDefinition = BT_HOLD; 01451 (btn++)->buttonDefinition = BT_REDIAL; 01452 (btn++)->buttonDefinition = BT_TRANSFER; 01453 (btn++)->buttonDefinition = BT_FORWARDALL; 01454 (btn++)->buttonDefinition = BT_CALLPARK; 01455 (btn++)->buttonDefinition = BT_VOICEMAIL; 01456 break; 01457 case SKINNY_DEVICE_7910: 01458 (btn++)->buttonDefinition = BT_LINE; 01459 (btn++)->buttonDefinition = BT_HOLD; 01460 (btn++)->buttonDefinition = BT_TRANSFER; 01461 (btn++)->buttonDefinition = BT_DISPLAY; 01462 (btn++)->buttonDefinition = BT_VOICEMAIL; 01463 (btn++)->buttonDefinition = BT_CONFERENCE; 01464 (btn++)->buttonDefinition = BT_FORWARDALL; 01465 for (i = 0; i < 2; i++) 01466 (btn++)->buttonDefinition = BT_SPEEDDIAL; 01467 (btn++)->buttonDefinition = BT_REDIAL; 01468 break; 01469 case SKINNY_DEVICE_7960: 01470 case SKINNY_DEVICE_7961: 01471 case SKINNY_DEVICE_7961GE: 01472 case SKINNY_DEVICE_7962: 01473 case SKINNY_DEVICE_7965: 01474 for (i = 0; i < 6; i++) 01475 (btn++)->buttonDefinition = BT_CUST_LINESPEEDDIAL; 01476 break; 01477 case SKINNY_DEVICE_7940: 01478 case SKINNY_DEVICE_7941: 01479 case SKINNY_DEVICE_7941GE: 01480 case SKINNY_DEVICE_7942: 01481 case SKINNY_DEVICE_7945: 01482 for (i = 0; i < 2; i++) 01483 (btn++)->buttonDefinition = BT_CUST_LINESPEEDDIAL; 01484 break; 01485 case SKINNY_DEVICE_7935: 01486 case SKINNY_DEVICE_7936: 01487 for (i = 0; i < 2; i++) 01488 (btn++)->buttonDefinition = BT_LINE; 01489 break; 01490 case SKINNY_DEVICE_ATA186: 01491 (btn++)->buttonDefinition = BT_LINE; 01492 break; 01493 case SKINNY_DEVICE_7970: 01494 case SKINNY_DEVICE_7971: 01495 case SKINNY_DEVICE_7975: 01496 case SKINNY_DEVICE_CIPC: 01497 for (i = 0; i < 8; i++) 01498 (btn++)->buttonDefinition = BT_CUST_LINESPEEDDIAL; 01499 break; 01500 case SKINNY_DEVICE_7985: 01501 /* XXX I have no idea what the buttons look like on these. */ 01502 ast_log(LOG_WARNING, "Unsupported device type '%d (7985)' found.\n", d->type); 01503 break; 01504 case SKINNY_DEVICE_7912: 01505 case SKINNY_DEVICE_7911: 01506 case SKINNY_DEVICE_7905: 01507 (btn++)->buttonDefinition = BT_LINE; 01508 (btn++)->buttonDefinition = BT_HOLD; 01509 break; 01510 case SKINNY_DEVICE_7920: 01511 /* XXX I don't know if this is right. */ 01512 for (i = 0; i < 4; i++) 01513 (btn++)->buttonDefinition = BT_CUST_LINESPEEDDIAL; 01514 break; 01515 case SKINNY_DEVICE_7921: 01516 for (i = 0; i < 6; i++) 01517 (btn++)->buttonDefinition = BT_CUST_LINESPEEDDIAL; 01518 break; 01519 case SKINNY_DEVICE_7902: 01520 ast_log(LOG_WARNING, "Unsupported device type '%d (7902)' found.\n", d->type); 01521 break; 01522 case SKINNY_DEVICE_7906: 01523 ast_log(LOG_WARNING, "Unsupported device type '%d (7906)' found.\n", d->type); 01524 break; 01525 case SKINNY_DEVICE_7931: 01526 ast_log(LOG_WARNING, "Unsupported device type '%d (7931)' found.\n", d->type); 01527 break; 01528 case SKINNY_DEVICE_7937: 01529 ast_log(LOG_WARNING, "Unsupported device type '%d (7937)' found.\n", d->type); 01530 break; 01531 case SKINNY_DEVICE_7914: 01532 ast_log(LOG_WARNING, "Unsupported device type '%d (7914)' found. Expansion module registered by itself?\n", d->type); 01533 break; 01534 case SKINNY_DEVICE_SCCPGATEWAY_AN: 01535 case SKINNY_DEVICE_SCCPGATEWAY_BRI: 01536 ast_log(LOG_WARNING, "Unsupported device type '%d (SCCP gateway)' found.\n", d->type); 01537 break; 01538 default: 01539 ast_log(LOG_WARNING, "Unknown device type '%d' found.\n", d->type); 01540 break; 01541 } 01542 01543 AST_LIST_LOCK(&d->addons); 01544 AST_LIST_TRAVERSE(&d->addons, a, list) { 01545 if (!strcasecmp(a->type, "7914")) { 01546 for (i = 0; i < 14; i++) 01547 (btn++)->buttonDefinition = BT_CUST_LINESPEEDDIAL; 01548 } else { 01549 ast_log(LOG_WARNING, "Unknown addon type '%s' found. Skipping.\n", a->type); 01550 } 01551 } 01552 AST_LIST_UNLOCK(&d->addons); 01553 01554 return btn; 01555 }
static int get_devicestate | ( | struct skinny_line * | l | ) | [static] |
Definition at line 4229 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::list, skinny_subchannel::onhold, SKINNY_ONHOOK, and skinny_line::sub.
Referenced by skinny_devicestate(), and skinny_new().
04230 { 04231 struct skinny_subchannel *sub; 04232 int res = AST_DEVICE_UNKNOWN; 04233 04234 if (!l) 04235 res = AST_DEVICE_INVALID; 04236 else if (!l->device) 04237 res = AST_DEVICE_UNAVAILABLE; 04238 else if (l->dnd) 04239 res = AST_DEVICE_BUSY; 04240 else { 04241 if (l->hookstate == SKINNY_ONHOOK) { 04242 res = AST_DEVICE_NOT_INUSE; 04243 } else { 04244 res = AST_DEVICE_INUSE; 04245 } 04246 04247 AST_LIST_TRAVERSE(&l->sub, sub, list) { 04248 if (sub->onhold) { 04249 res = AST_DEVICE_ONHOLD; 04250 break; 04251 } 04252 } 04253 } 04254 04255 return res; 04256 }
static int get_input | ( | struct skinnysession * | s | ) | [static] |
Definition at line 6347 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 do_message(), and skinny_session().
06348 { 06349 int res; 06350 int dlen = 0; 06351 int timeout = keep_alive * 1100; 06352 time_t now; 06353 int *bufaddr; 06354 struct pollfd fds[1]; 06355 06356 if (!s->device) { 06357 if(time(&now) == -1) { 06358 ast_log(LOG_ERROR, "error executing time(): %s\n", strerror(errno)); 06359 return -1; 06360 } 06361 06362 timeout = (auth_timeout - (now - s->start)) * 1000; 06363 if (timeout < 0) { 06364 /* we have timed out */ 06365 if (skinnydebug) 06366 ast_verb(1, "Skinny Client failed to authenticate in %d seconds\n", auth_timeout); 06367 return -1; 06368 } 06369 } 06370 06371 fds[0].fd = s->fd; 06372 fds[0].events = POLLIN; 06373 fds[0].revents = 0; 06374 res = ast_poll(fds, 1, timeout); /* If nothing has happen, client is dead */ 06375 /* we add 10% to the keep_alive to deal */ 06376 /* with network delays, etc */ 06377 if (res < 0) { 06378 if (errno != EINTR) { 06379 ast_log(LOG_WARNING, "Select returned error: %s\n", strerror(errno)); 06380 return res; 06381 } 06382 } else if (res == 0) { 06383 if (skinnydebug) { 06384 if (s->device) { 06385 ast_verb(1, "Skinny Client was lost, unregistering\n"); 06386 } else { 06387 ast_verb(1, "Skinny Client failed to authenticate in %d seconds\n", auth_timeout); 06388 } 06389 } 06390 skinny_unregister(NULL, s); 06391 return -1; 06392 } 06393 06394 if (fds[0].revents) { 06395 ast_mutex_lock(&s->lock); 06396 memset(s->inbuf, 0, sizeof(s->inbuf)); 06397 res = read(s->fd, s->inbuf, 4); 06398 if (res < 0) { 06399 ast_log(LOG_WARNING, "read() returned error: %s\n", strerror(errno)); 06400 06401 if (skinnydebug) 06402 ast_verb(1, "Skinny Client was lost, unregistering\n"); 06403 06404 skinny_unregister(NULL, s); 06405 ast_mutex_unlock(&s->lock); 06406 return res; 06407 } else if (res != 4) { 06408 ast_log(LOG_WARNING, "Skinny Client sent less data than expected. Expected 4 but got %d.\n", res); 06409 ast_mutex_unlock(&s->lock); 06410 06411 if (res == 0) { 06412 if (skinnydebug) 06413 ast_verb(1, "Skinny Client was lost, unregistering\n"); 06414 skinny_unregister(NULL, s); 06415 } 06416 06417 return -1; 06418 } 06419 06420 bufaddr = (int *)s->inbuf; 06421 dlen = letohl(*bufaddr); 06422 if (dlen < 4) { 06423 ast_debug(1, "Skinny Client sent invalid data.\n"); 06424 ast_mutex_unlock(&s->lock); 06425 return -1; 06426 } 06427 if (dlen+8 > sizeof(s->inbuf)) { 06428 dlen = sizeof(s->inbuf) - 8; 06429 } 06430 *bufaddr = htolel(dlen); 06431 06432 res = read(s->fd, s->inbuf+4, dlen+4); 06433 ast_mutex_unlock(&s->lock); 06434 if (res < 0) { 06435 ast_log(LOG_WARNING, "read() returned error: %s\n", strerror(errno)); 06436 return res; 06437 } else if (res != (dlen+4)) { 06438 ast_log(LOG_WARNING, "Skinny Client sent less data than expected.\n"); 06439 return -1; 06440 } 06441 return res; 06442 } 06443 return 0; 06444 }
static int handle_button_template_req_message | ( | struct skinny_req * | req, | |
struct skinnysession * | s | |||
) | [static] |
Definition at line 5513 of file chan_skinny.c.
References AST_LIST_TRAVERSE, ast_verb, BT_CUST_LINE, BT_LINE, BT_NONE, BUTTON_TEMPLATE_RES_MESSAGE, button_definition::buttonDefinition, button_definition_template::buttonDefinition, skinny_data::buttontemplate, skinny_req::data, button_template_res_message::definition, skinnysession::device, get_button_template(), skinny_speeddial::instance, button_definition::instanceNumber, skinny_speeddial::isHint, skinny_device::lines, skinny_subchannel::list, req_alloc(), and skinny_device::speeddials.
Referenced by handle_message().
05514 { 05515 struct skinny_device *d = s->device; 05516 struct skinny_line *l; 05517 int i; 05518 05519 struct skinny_speeddial *sd; 05520 struct button_definition_template btn[42]; 05521 int lineInstance = 1; 05522 int speeddialInstance = 1; 05523 int buttonCount = 0; 05524 05525 if (!(req = req_alloc(sizeof(struct button_template_res_message), BUTTON_TEMPLATE_RES_MESSAGE))) 05526 return -1; 05527 05528 memset(&btn, 0, sizeof(btn)); 05529 05530 get_button_template(s, btn); 05531 05532 for (i=0; i<42; i++) { 05533 int btnSet = 0; 05534 switch (btn[i].buttonDefinition) { 05535 case BT_CUST_LINE: 05536 /* assume failure */ 05537 req->data.buttontemplate.definition[i].buttonDefinition = BT_NONE; 05538 req->data.buttontemplate.definition[i].instanceNumber = 0; 05539 05540 AST_LIST_TRAVERSE(&d->lines, l, list) { 05541 if (l->instance == lineInstance) { 05542 ast_verb(0, "Adding button: %d, %d\n", BT_LINE, lineInstance); 05543 req->data.buttontemplate.definition[i].buttonDefinition = BT_LINE; 05544 req->data.buttontemplate.definition[i].instanceNumber = lineInstance; 05545 lineInstance++; 05546 buttonCount++; 05547 btnSet = 1; 05548 break; 05549 } 05550 } 05551 05552 if (!btnSet) { 05553 AST_LIST_TRAVERSE(&d->speeddials, sd, list) { 05554 if (sd->isHint && sd->instance == lineInstance) { 05555 ast_verb(0, "Adding button: %d, %d\n", BT_LINE, lineInstance); 05556 req->data.buttontemplate.definition[i].buttonDefinition = BT_LINE; 05557 req->data.buttontemplate.definition[i].instanceNumber = lineInstance; 05558 lineInstance++; 05559 buttonCount++; 05560 btnSet = 1; 05561 break; 05562 } 05563 } 05564 } 05565 break; 05566 case BT_CUST_LINESPEEDDIAL: 05567 /* assume failure */ 05568 req->data.buttontemplate.definition[i].buttonDefinition = BT_NONE; 05569 req->data.buttontemplate.definition[i].instanceNumber = 0; 05570 05571 AST_LIST_TRAVERSE(&d->lines, l, list) { 05572 if (l->instance == lineInstance) { 05573 ast_verb(0, "Adding button: %d, %d\n", BT_LINE, lineInstance); 05574 req->data.buttontemplate.definition[i].buttonDefinition = BT_LINE; 05575 req->data.buttontemplate.definition[i].instanceNumber = lineInstance; 05576 lineInstance++; 05577 buttonCount++; 05578 btnSet = 1; 05579 break; 05580 } 05581 } 05582 05583 if (!btnSet) { 05584 AST_LIST_TRAVERSE(&d->speeddials, sd, list) { 05585 if (sd->isHint && sd->instance == lineInstance) { 05586 ast_verb(0, "Adding button: %d, %d\n", BT_LINE, lineInstance); 05587 req->data.buttontemplate.definition[i].buttonDefinition = BT_LINE; 05588 req->data.buttontemplate.definition[i].instanceNumber = lineInstance; 05589 lineInstance++; 05590 buttonCount++; 05591 btnSet = 1; 05592 break; 05593 } else if (!sd->isHint && sd->instance == speeddialInstance) { 05594 ast_verb(0, "Adding button: %d, %d\n", BT_SPEEDDIAL, speeddialInstance); 05595 req->data.buttontemplate.definition[i].buttonDefinition = BT_SPEEDDIAL; 05596 req->data.buttontemplate.definition[i].instanceNumber = speeddialInstance; 05597 speeddialInstance++; 05598 buttonCount++; 05599 btnSet = 1; 05600 break; 05601 } 05602 } 05603 } 05604 break; 05605 case BT_LINE: 05606 req->data.buttontemplate.definition[i].buttonDefinition = htolel(BT_NONE); 05607 req->data.buttontemplate.definition[i].instanceNumber = htolel(0); 05608 05609 AST_LIST_TRAVERSE(&d->lines, l, list) { 05610 if (l->instance == lineInstance) { 05611 ast_verb(0, "Adding button: %d, %d\n", BT_LINE, lineInstance); 05612 req->data.buttontemplate.definition[i].buttonDefinition = BT_LINE; 05613 req->data.buttontemplate.definition[i].instanceNumber = lineInstance; 05614 lineInstance++; 05615 buttonCount++; 05616 btnSet = 1; 05617 break; 05618 } 05619 } 05620 break; 05621 case BT_SPEEDDIAL: 05622 req->data.buttontemplate.definition[i].buttonDefinition = BT_NONE; 05623 req->data.buttontemplate.definition[i].instanceNumber = 0; 05624 05625 AST_LIST_TRAVERSE(&d->speeddials, sd, list) { 05626 if (!sd->isHint && sd->instance == speeddialInstance) { 05627 ast_verb(0, "Adding button: %d, %d\n", BT_SPEEDDIAL, speeddialInstance); 05628 req->data.buttontemplate.definition[i].buttonDefinition = BT_SPEEDDIAL; 05629 req->data.buttontemplate.definition[i].instanceNumber = speeddialInstance - 1; 05630 speeddialInstance++; 05631 buttonCount++; 05632 btnSet = 1; 05633 break; 05634 } 05635 } 05636 break; 05637 case BT_NONE: 05638 break; 05639 default: 05640 ast_verb(0, "Adding button: %d, %d\n", btn[i].buttonDefinition, 0); 05641 req->data.buttontemplate.definition[i].buttonDefinition = htolel(btn[i].buttonDefinition); 05642 req->data.buttontemplate.definition[i].instanceNumber = 0; 05643 buttonCount++; 05644 btnSet = 1; 05645 break; 05646 } 05647 } 05648 05649 req->data.buttontemplate.buttonOffset = 0; 05650 req->data.buttontemplate.buttonCount = htolel(buttonCount); 05651 req->data.buttontemplate.totalButtonCount = htolel(buttonCount); 05652 05653 if (skinnydebug) 05654 ast_verb(1, "Sending %d template to %s\n", 05655 d->type, 05656 d->name); 05657 transmit_response(d, req); 05658 return 1; 05659 }
static int handle_callforward_button | ( | struct skinny_subchannel * | sub, | |
int | cfwdtype | |||
) | [static] |
Definition at line 4822 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, set_callforwards(), SKINNY_DIALTONE, SKINNY_OFFHOOK, SKINNY_ONHOOK, SKINNY_SPEAKEROFF, SKINNY_SPEAKERON, skinny_ss(), skinny_line::sub, 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().
04823 { 04824 struct skinny_line *l = sub->parent; 04825 struct skinny_device *d = l->device; 04826 struct ast_channel *c = sub->owner; 04827 pthread_t t; 04828 04829 if (l->hookstate == SKINNY_ONHOOK) { 04830 l->hookstate = SKINNY_OFFHOOK; 04831 transmit_speaker_mode(d, SKINNY_SPEAKERON); 04832 transmit_callstate(d, l->instance, sub->callid, SKINNY_OFFHOOK); 04833 transmit_activatecallplane(d, l); 04834 } 04835 transmit_clear_display_message(d, l->instance, sub->callid); 04836 04837 if (l->cfwdtype & cfwdtype) { 04838 set_callforwards(l, NULL, cfwdtype); 04839 ast_safe_sleep(c, 500); 04840 transmit_speaker_mode(d, SKINNY_SPEAKEROFF); 04841 transmit_closereceivechannel(d, sub); 04842 transmit_stopmediatransmission(d, sub); 04843 transmit_speaker_mode(d, SKINNY_SPEAKEROFF); 04844 transmit_clearpromptmessage(d, l->instance, sub->callid); 04845 transmit_callstate(d, l->instance, sub->callid, SKINNY_ONHOOK); 04846 transmit_selectsoftkeys(d, 0, 0, KEYDEF_ONHOOK); 04847 transmit_activatecallplane(d, l); 04848 transmit_displaynotify(d, "CFwd disabled", 10); 04849 if (sub->owner && sub->owner->_state != AST_STATE_UP) { 04850 ast_indicate(c, -1); 04851 ast_hangup(c); 04852 } 04853 transmit_cfwdstate(d, l); 04854 } else { 04855 l->getforward = cfwdtype; 04856 transmit_start_tone(d, SKINNY_DIALTONE, l->instance, sub->callid); 04857 transmit_selectsoftkeys(d, l->instance, sub->callid, KEYDEF_RINGOUT); 04858 if (ast_pthread_create(&t, NULL, skinny_ss, c)) { 04859 ast_log(LOG_WARNING, "Unable to create switch thread: %s\n", strerror(errno)); 04860 ast_hangup(c); 04861 } 04862 } 04863 return 0; 04864 }
static int handle_capabilities_res_message | ( | struct skinny_req * | req, | |
struct skinnysession * | s | |||
) | [static] |
Definition at line 5477 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_subchannel::list, skinny_line::lock, LOG_WARNING, and SKINNY_MAX_CAPABILITIES.
Referenced by handle_message().
05478 { 05479 struct skinny_device *d = s->device; 05480 struct skinny_line *l; 05481 uint32_t count = 0; 05482 format_t codecs = 0; 05483 int i; 05484 char buf[256]; 05485 05486 count = letohl(req->data.caps.count); 05487 if (count > SKINNY_MAX_CAPABILITIES) { 05488 count = SKINNY_MAX_CAPABILITIES; 05489 ast_log(LOG_WARNING, "Received more capabilities than we can handle (%d). Ignoring the rest.\n", SKINNY_MAX_CAPABILITIES); 05490 } 05491 05492 for (i = 0; i < count; i++) { 05493 format_t acodec = 0; 05494 int scodec = 0; 05495 scodec = letohl(req->data.caps.caps[i].codec); 05496 acodec = codec_skinny2ast(scodec); 05497 if (skinnydebug) 05498 ast_verb(1, "Adding codec capability '%" PRId64 " (%d)'\n", acodec, scodec); 05499 codecs |= acodec; 05500 } 05501 05502 d->capability = d->confcapability & codecs; 05503 ast_verb(0, "Device capability set to '%s'\n", ast_getformatname_multiple(buf, sizeof(buf), d->capability)); 05504 AST_LIST_TRAVERSE(&d->lines, l, list) { 05505 ast_mutex_lock(&l->lock); 05506 l->capability = l->confcapability & d->capability; 05507 ast_mutex_unlock(&l->lock); 05508 } 05509 05510 return 1; 05511 }
static int handle_enbloc_call_message | ( | struct skinny_req * | req, | |
struct skinnysession * | s | |||
) | [static] |
Definition at line 5722 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().
05723 { 05724 struct skinny_device *d = s->device; 05725 struct skinny_line *l; 05726 struct skinny_subchannel *sub = NULL; 05727 struct ast_channel *c; 05728 pthread_t t; 05729 05730 if (skinnydebug) 05731 ast_verb(1, "Received Enbloc Call: %s\n", req->data.enbloccallmessage.calledParty); 05732 05733 sub = find_subchannel_by_instance_reference(d, d->lastlineinstance, d->lastcallreference); 05734 05735 if (!sub) { 05736 l = find_line_by_instance(d, d->lastlineinstance); 05737 if (!l) { 05738 return 0; 05739 } 05740 } else { 05741 l = sub->parent; 05742 } 05743 05744 c = skinny_new(l, AST_STATE_DOWN, NULL); 05745 05746 if(!c) { 05747 ast_log(LOG_WARNING, "Unable to create channel for %s@%s\n", l->name, d->name); 05748 } else { 05749 l->hookstate = SKINNY_OFFHOOK; 05750 05751 sub = c->tech_pvt; 05752 l->activesub = sub; 05753 transmit_callstate(d, l->instance, sub->callid, SKINNY_OFFHOOK); 05754 transmit_activatecallplane(d, l); 05755 transmit_clear_display_message(d, l->instance, sub->callid); 05756 transmit_start_tone(d, SKINNY_DIALTONE, l->instance, sub->callid); 05757 05758 if (!ast_ignore_pattern(c->context, req->data.enbloccallmessage.calledParty)) { 05759 transmit_stop_tone(d, l->instance, sub->callid); 05760 } 05761 ast_copy_string(c->exten, req->data.enbloccallmessage.calledParty, sizeof(c->exten)); 05762 if (ast_pthread_create(&t, NULL, skinny_newcall, c)) { 05763 ast_log(LOG_WARNING, "Unable to create new call thread: %s\n", strerror(errno)); 05764 ast_hangup(c); 05765 } 05766 } 05767 05768 return 1; 05769 }
static int handle_hold_button | ( | struct skinny_subchannel * | sub | ) | [static] |
Definition at line 4662 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().
04663 { 04664 if (!sub) 04665 return -1; 04666 if (sub->related) { 04667 skinny_hold(sub); 04668 skinny_unhold(sub->related); 04669 sub->parent->activesub = sub->related; 04670 } else { 04671 if (sub->onhold) { 04672 skinny_unhold(sub); 04673 transmit_selectsoftkeys(sub->parent->device, sub->parent->instance, sub->callid, KEYDEF_CONNECTED); 04674 } else { 04675 skinny_hold(sub); 04676 transmit_selectsoftkeys(sub->parent->device, sub->parent->instance, sub->callid, KEYDEF_ONHOLD); 04677 } 04678 } 04679 return 1; 04680 }
static int handle_ip_port_message | ( | struct skinny_req * | req, | |
struct skinnysession * | s | |||
) | [static] |
static int handle_keep_alive_message | ( | struct skinny_req * | req, | |
struct skinnysession * | s | |||
) | [static] |
Definition at line 4746 of file chan_skinny.c.
References skinnysession::device, KEEP_ALIVE_ACK_MESSAGE, req_alloc(), and transmit_response().
Referenced by handle_message().
04747 { 04748 if (!(req = req_alloc(0, KEEP_ALIVE_ACK_MESSAGE))) 04749 return -1; 04750 04751 transmit_response(s->device, req); 04752 return 1; 04753 }
static int handle_keypad_button_message | ( | struct skinny_req * | req, | |
struct skinnysession * | s | |||
) | [static] |
Definition at line 4871 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, f, find_subchannel_by_instance_reference(), skinny_data::keypad, letohl, keypad_button_message::lineInstance, skinny_subchannel::list, LOG_WARNING, skinny_subchannel::owner, and skinny_subchannel::parent.
Referenced by handle_message().
04872 { 04873 struct skinny_subchannel *sub = NULL; 04874 struct skinny_line *l; 04875 struct skinny_device *d = s->device; 04876 struct ast_frame f = { 0, }; 04877 char dgt; 04878 int digit; 04879 int lineInstance; 04880 int callReference; 04881 04882 digit = letohl(req->data.keypad.button); 04883 lineInstance = letohl(req->data.keypad.lineInstance); 04884 callReference = letohl(req->data.keypad.callReference); 04885 04886 if (digit == 14) { 04887 dgt = '*'; 04888 } else if (digit == 15) { 04889 dgt = '#'; 04890 } else if (digit >= 0 && digit <= 9) { 04891 dgt = '0' + digit; 04892 } else { 04893 /* digit=10-13 (A,B,C,D ?), or 04894 * digit is bad value 04895 * 04896 * probably should not end up here, but set 04897 * value for backward compatibility, and log 04898 * a warning. 04899 */ 04900 dgt = '0' + digit; 04901 ast_log(LOG_WARNING, "Unsupported digit %d\n", digit); 04902 } 04903 04904 f.subclass.integer = dgt; 04905 04906 f.src = "skinny"; 04907 04908 if (lineInstance && callReference) 04909 sub = find_subchannel_by_instance_reference(d, lineInstance, callReference); 04910 else 04911 sub = d->activeline->activesub; 04912 //sub = find_subchannel_by_instance_reference(d, d->lastlineinstance, d->lastcallreference); 04913 04914 if (!sub) 04915 return 0; 04916 04917 l = sub->parent; 04918 if (sub->owner) { 04919 if (sub->owner->_state == 0) { 04920 f.frametype = AST_FRAME_DTMF_BEGIN; 04921 ast_queue_frame(sub->owner, &f); 04922 } 04923 /* XXX MUST queue this frame to all lines in threeway call if threeway call is active */ 04924 f.frametype = AST_FRAME_DTMF_END; 04925 ast_queue_frame(sub->owner, &f); 04926 /* XXX This seriously needs to be fixed */ 04927 if (AST_LIST_NEXT(sub, list) && AST_LIST_NEXT(sub, list)->owner) { 04928 if (sub->owner->_state == 0) { 04929 f.frametype = AST_FRAME_DTMF_BEGIN; 04930 ast_queue_frame(AST_LIST_NEXT(sub, list)->owner, &f); 04931 } 04932 f.frametype = AST_FRAME_DTMF_END; 04933 ast_queue_frame(AST_LIST_NEXT(sub, list)->owner, &f); 04934 } 04935 } else { 04936 if (skinnydebug) 04937 ast_verb(1, "No owner: %s\n", l->name); 04938 } 04939 return 1; 04940 }
static int handle_message | ( | struct skinny_req * | req, | |
struct skinnysession * | s | |||
) | [static] |
Definition at line 6145 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().
06146 { 06147 int res = 0; 06148 struct skinny_speeddial *sd; 06149 struct skinny_line *l; 06150 struct skinny_device *d = s->device; 06151 06152 if ((!s->device) && (letohl(req->e) != REGISTER_MESSAGE && letohl(req->e) != ALARM_MESSAGE)) { 06153 ast_log(LOG_WARNING, "Client sent message #%d without first registering.\n", req->e); 06154 ast_free(req); 06155 return 0; 06156 } 06157 06158 SKINNY_DEVONLY(if (skinnydebug > 1) { 06159 ast_verb(4, "Received %s from %s\n", message2str(req->e), s->device->name); 06160 }) 06161 06162 switch(letohl(req->e)) { 06163 case KEEP_ALIVE_MESSAGE: 06164 res = handle_keep_alive_message(req, s); 06165 break; 06166 case REGISTER_MESSAGE: 06167 if (skinnydebug) 06168 ast_verb(1, "Device %s is attempting to register\n", req->data.reg.name); 06169 06170 res = handle_register_message(req, s); 06171 break; 06172 case IP_PORT_MESSAGE: 06173 res = handle_ip_port_message(req, s); 06174 break; 06175 case KEYPAD_BUTTON_MESSAGE: 06176 { 06177 struct skinny_device *d = s->device; 06178 struct skinny_subchannel *sub; 06179 int lineInstance; 06180 int callReference; 06181 06182 if (skinnydebug) 06183 ast_verb(1, "Collected digit: [%d]\n", letohl(req->data.keypad.button)); 06184 06185 lineInstance = letohl(req->data.keypad.lineInstance); 06186 callReference = letohl(req->data.keypad.callReference); 06187 06188 if (lineInstance) { 06189 sub = find_subchannel_by_instance_reference(d, lineInstance, callReference); 06190 } else { 06191 sub = d->activeline->activesub; 06192 } 06193 06194 if (sub && ((sub->owner && sub->owner->_state < AST_STATE_UP) || sub->onhold)) { 06195 char dgt; 06196 int digit = letohl(req->data.keypad.button); 06197 06198 if (digit == 14) { 06199 dgt = '*'; 06200 } else if (digit == 15) { 06201 dgt = '#'; 06202 } else if (digit >= 0 && digit <= 9) { 06203 dgt = '0' + digit; 06204 } else { 06205 /* digit=10-13 (A,B,C,D ?), or 06206 * digit is bad value 06207 * 06208 * probably should not end up here, but set 06209 * value for backward compatibility, and log 06210 * a warning. 06211 */ 06212 dgt = '0' + digit; 06213 ast_log(LOG_WARNING, "Unsupported digit %d\n", digit); 06214 } 06215 06216 d->exten[strlen(d->exten)] = dgt; 06217 d->exten[strlen(d->exten)+1] = '\0'; 06218 } else 06219 res = handle_keypad_button_message(req, s); 06220 } 06221 break; 06222 case ENBLOC_CALL_MESSAGE: 06223 res = handle_enbloc_call_message(req, s); 06224 break; 06225 case STIMULUS_MESSAGE: 06226 res = handle_stimulus_message(req, s); 06227 break; 06228 case OFFHOOK_MESSAGE: 06229 res = handle_offhook_message(req, s); 06230 break; 06231 case ONHOOK_MESSAGE: 06232 res = handle_onhook_message(req, s); 06233 break; 06234 case CAPABILITIES_RES_MESSAGE: 06235 if (skinnydebug) 06236 ast_verb(1, "Received CapabilitiesRes\n"); 06237 06238 res = handle_capabilities_res_message(req, s); 06239 break; 06240 case SPEED_DIAL_STAT_REQ_MESSAGE: 06241 if (skinnydebug) 06242 ast_verb(1, "Received SpeedDialStatRequest\n"); 06243 if ( (sd = find_speeddial_by_instance(s->device, letohl(req->data.speeddialreq.speedDialNumber), 0)) ) { 06244 transmit_speeddialstatres(d, sd); 06245 } 06246 break; 06247 case LINE_STATE_REQ_MESSAGE: 06248 if (skinnydebug) 06249 ast_verb(1, "Received LineStatRequest\n"); 06250 if ((l = find_line_by_instance(d, letohl(req->data.line.lineNumber)))) { 06251 transmit_linestatres(d, l); 06252 } 06253 break; 06254 case TIME_DATE_REQ_MESSAGE: 06255 if (skinnydebug) 06256 ast_verb(1, "Received Time/Date Request\n"); 06257 06258 transmit_definetimedate(d); 06259 break; 06260 case BUTTON_TEMPLATE_REQ_MESSAGE: 06261 if (skinnydebug) 06262 ast_verb(1, "Buttontemplate requested\n"); 06263 06264 res = handle_button_template_req_message(req, s); 06265 break; 06266 case VERSION_REQ_MESSAGE: 06267 if (skinnydebug) 06268 ast_verb(1, "Version Request\n"); 06269 transmit_versionres(d); 06270 break; 06271 case SERVER_REQUEST_MESSAGE: 06272 if (skinnydebug) 06273 ast_verb(1, "Received Server Request\n"); 06274 transmit_serverres(d); 06275 break; 06276 case ALARM_MESSAGE: 06277 /* no response necessary */ 06278 if (skinnydebug) 06279 ast_verb(1, "Received Alarm Message: %s\n", req->data.alarm.displayMessage); 06280 break; 06281 case OPEN_RECEIVE_CHANNEL_ACK_MESSAGE: 06282 if (skinnydebug) 06283 ast_verb(1, "Received Open Receive Channel Ack\n"); 06284 06285 res = handle_open_receive_channel_ack_message(req, s); 06286 break; 06287 case SOFT_KEY_SET_REQ_MESSAGE: 06288 if (skinnydebug) 06289 ast_verb(1, "Received SoftKeySetReq\n"); 06290 transmit_softkeysetres(d); 06291 transmit_selectsoftkeys(d, 0, 0, KEYDEF_ONHOOK); 06292 break; 06293 case SOFT_KEY_EVENT_MESSAGE: 06294 res = handle_soft_key_event_message(req, s); 06295 break; 06296 case UNREGISTER_MESSAGE: 06297 if (skinnydebug) 06298 ast_verb(1, "Received Unregister Request\n"); 06299 06300 res = skinny_unregister(req, s); 06301 break; 06302 case SOFT_KEY_TEMPLATE_REQ_MESSAGE: 06303 if (skinnydebug) 06304 ast_verb(1, "Received SoftKey Template Request\n"); 06305 transmit_softkeytemplateres(d); 06306 break; 06307 case HEADSET_STATUS_MESSAGE: 06308 /* XXX umm...okay? Why do I care? */ 06309 break; 06310 case REGISTER_AVAILABLE_LINES_MESSAGE: 06311 /* XXX I have no clue what this is for, but my phone was sending it, so... */ 06312 break; 06313 default: 06314 if (skinnydebug) 06315 ast_verb(1, "RECEIVED UNKNOWN MESSAGE TYPE: %x\n", letohl(req->e)); 06316 break; 06317 } 06318 if (res >= 0 && req) 06319 ast_free(req); 06320 return res; 06321 }
static int handle_offhook_message | ( | struct skinny_req * | req, | |
struct skinnysession * | s | |||
) | [static] |
Definition at line 5294 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_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, skinny_subchannel::list, LOG_WARNING, skinny_data::offhook, offhook_message::reference, 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().
05295 { 05296 struct skinny_device *d = s->device; 05297 struct skinny_line *l; 05298 struct skinny_subchannel *sub; 05299 struct ast_channel *c; 05300 struct skinny_line *tmp; 05301 pthread_t t; 05302 int instance; 05303 int reference; 05304 05305 /* if any line on a device is offhook, than the device must be offhook, 05306 unless we have shared lines CCM seems that it would never get here, 05307 but asterisk does, so we may need to do more work. Ugly, we should 05308 probably move hookstate from line to device, afterall, it's actually 05309 a device that changes hookstates */ 05310 05311 AST_LIST_TRAVERSE(&d->lines, tmp, list) { 05312 if (tmp->hookstate == SKINNY_OFFHOOK) { 05313 ast_verbose(VERBOSE_PREFIX_3 "Got offhook message when device (%s@%s) already offhook\n", tmp->name, d->name); 05314 return 0; 05315 } 05316 } 05317 05318 instance = letohl(req->data.offhook.instance); 05319 reference = letohl(req->data.offhook.reference); 05320 05321 if (instance) { 05322 sub = find_subchannel_by_instance_reference(d, d->lastlineinstance, d->lastcallreference); 05323 if (!sub) { 05324 l = find_line_by_instance(d, d->lastlineinstance); 05325 if (!l) { 05326 return 0; 05327 } 05328 } else { 05329 l = sub->parent; 05330 } 05331 } else { 05332 l = d->activeline; 05333 sub = l->activesub; 05334 } 05335 05336 /* Not ideal, but let's send updated time at onhook and offhook, as it clears the display */ 05337 transmit_definetimedate(d); 05338 05339 transmit_ringer_mode(d, SKINNY_RING_OFF); 05340 l->hookstate = SKINNY_OFFHOOK; 05341 05342 ast_devstate_changed(AST_DEVICE_INUSE, "Skinny/%s@%s", l->name, d->name); 05343 05344 if (sub && sub->onhold) { 05345 return 1; 05346 } 05347 05348 transmit_lamp_indication(d, STIMULUS_LINE, l->instance, SKINNY_LAMP_ON); 05349 05350 if (sub && sub->outgoing) { 05351 /* We're answering a ringing call */ 05352 ast_queue_control(sub->owner, AST_CONTROL_ANSWER); 05353 transmit_callstate(d, l->instance, sub->callid, SKINNY_OFFHOOK); 05354 transmit_activatecallplane(d, l); 05355 transmit_stop_tone(d, l->instance, sub->callid); 05356 transmit_callstate(d, sub->parent->instance, sub->callid, SKINNY_CONNECTED); 05357 transmit_selectsoftkeys(d, l->instance, sub->callid, KEYDEF_CONNECTED); 05358 start_rtp(sub); 05359 ast_setstate(sub->owner, AST_STATE_UP); 05360 } else { 05361 if (sub && sub->owner) { 05362 ast_debug(1, "Current sub [%s] already has owner\n", sub->owner->name); 05363 } else { 05364 c = skinny_new(l, AST_STATE_DOWN, NULL); 05365 if (c) { 05366 sub = c->tech_pvt; 05367 l->activesub = sub; 05368 transmit_callstate(d, l->instance, sub->callid, SKINNY_OFFHOOK); 05369 transmit_activatecallplane(d, l); 05370 transmit_clear_display_message(d, l->instance, sub->callid); 05371 transmit_start_tone(d, SKINNY_DIALTONE, l->instance, sub->callid); 05372 transmit_selectsoftkeys(d, l->instance, sub->callid, KEYDEF_OFFHOOK); 05373 05374 /* start the switch thread */ 05375 if (ast_pthread_create(&t, NULL, skinny_ss, c)) { 05376 ast_log(LOG_WARNING, "Unable to create switch thread: %s\n", strerror(errno)); 05377 ast_hangup(c); 05378 } 05379 } else { 05380 ast_log(LOG_WARNING, "Unable to create channel for %s@%s\n", l->name, d->name); 05381 } 05382 } 05383 } 05384 return 1; 05385 }
static int handle_onhook_message | ( | struct skinny_req * | req, | |
struct skinnysession * | s | |||
) | [static] |
Definition at line 5387 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, skinny_subchannel::list, 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().
05388 { 05389 struct skinny_device *d = s->device; 05390 struct skinny_line *l; 05391 struct skinny_subchannel *sub; 05392 int instance; 05393 int reference; 05394 int onlysub = 0; 05395 05396 instance = letohl(req->data.onhook.instance); 05397 reference = letohl(req->data.onhook.reference); 05398 05399 if (instance && reference) { 05400 sub = find_subchannel_by_instance_reference(d, instance, reference); 05401 if (!sub) { 05402 return 0; 05403 } 05404 l = sub->parent; 05405 } else { 05406 l = d->activeline; 05407 sub = l->activesub; 05408 if (!sub) { 05409 return 0; 05410 } 05411 } 05412 05413 if (l->hookstate == SKINNY_ONHOOK) { 05414 /* Something else already put us back on hook */ 05415 return 0; 05416 } 05417 05418 ast_devstate_changed(AST_DEVICE_NOT_INUSE, "Skinny/%s@%s", l->name, d->name); 05419 05420 if (sub->onhold) { 05421 return 0; 05422 } 05423 05424 if (!AST_LIST_NEXT(sub, list)) { 05425 onlysub = 1; 05426 } else { 05427 AST_LIST_REMOVE(&l->sub, sub, list); 05428 } 05429 05430 sub->cxmode = SKINNY_CX_RECVONLY; 05431 if (onlysub || sub->xferor){ /* is this the only call to this device? */ 05432 l->hookstate = SKINNY_ONHOOK; 05433 if (skinnydebug) 05434 ast_debug(1, "Skinny %s@%s-%d went on hook\n", l->name, d->name, reference); 05435 } 05436 05437 if (l->hookstate == SKINNY_ONHOOK) { 05438 transmit_closereceivechannel(d, sub); 05439 transmit_stopmediatransmission(d, sub); 05440 transmit_speaker_mode(d, SKINNY_SPEAKEROFF); 05441 transmit_clearpromptmessage(d, instance, sub->callid); 05442 transmit_callstate(d, l->instance, sub->callid, SKINNY_ONHOOK); 05443 transmit_selectsoftkeys(d, 0, 0, KEYDEF_ONHOOK); 05444 transmit_activatecallplane(d, l); 05445 } else if (l->hookstate == SKINNY_OFFHOOK) { 05446 transmit_callstate(d, l->instance, sub->callid, SKINNY_OFFHOOK); 05447 transmit_activatecallplane(d, l); 05448 } else { 05449 transmit_callstate(d, l->instance, sub->callid, l->hookstate); 05450 } 05451 05452 if (l->transfer && sub->xferor && sub->owner->_state >= AST_STATE_RING) { 05453 /* We're allowed to transfer, we have two active calls and 05454 we made at least one of the calls. Let's try and transfer */ 05455 handle_transfer_button(sub); 05456 } else { 05457 /* Hangup the current call */ 05458 /* If there is another active call, skinny_hangup will ring the phone with the other call */ 05459 if (sub->xferor && sub->related){ 05460 sub->related->related = NULL; 05461 sub->related->blindxfer = 0; 05462 } 05463 05464 if (sub->owner) { 05465 sub->alreadygone = 1; 05466 ast_queue_hangup(sub->owner); 05467 } else { 05468 ast_log(LOG_WARNING, "Skinny(%s@%s-%d) channel already destroyed\n", 05469 l->name, d->name, sub->callid); 05470 } 05471 /* Not ideal, but let's send updated time at onhook and offhook, as it clears the display */ 05472 transmit_definetimedate(d); 05473 } 05474 return 1; 05475 }
static int handle_open_receive_channel_ack_message | ( | struct skinny_req * | req, | |
struct skinnysession * | s | |||
) | [static] |
Definition at line 5661 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, open_receive_channel_ack_message::status, status, and transmit_startmediatransmission().
Referenced by handle_message().
05662 { 05663 struct skinny_device *d = s->device; 05664 struct skinny_line *l; 05665 struct skinny_subchannel *sub; 05666 struct ast_format_list fmt; 05667 struct sockaddr_in sin = { 0, }; 05668 struct sockaddr_in us = { 0, }; 05669 struct ast_sockaddr sin_tmp; 05670 struct ast_sockaddr us_tmp; 05671 uint32_t addr; 05672 int port; 05673 int status; 05674 int passthruid; 05675 05676 status = letohl(req->data.openreceivechannelack.status); 05677 if (status) { 05678 ast_log(LOG_ERROR, "Open Receive Channel Failure\n"); 05679 return 0; 05680 } 05681 addr = req->data.openreceivechannelack.ipAddr; 05682 port = letohl(req->data.openreceivechannelack.port); 05683 passthruid = letohl(req->data.openreceivechannelack.passThruId); 05684 05685 sin.sin_family = AF_INET; 05686 sin.sin_addr.s_addr = addr; 05687 sin.sin_port = htons(port); 05688 05689 sub = find_subchannel_by_reference(d, passthruid); 05690 05691 if (!sub) 05692 return 0; 05693 05694 l = sub->parent; 05695 05696 if (sub->rtp) { 05697 ast_sockaddr_from_sin(&sin_tmp, &sin); 05698 ast_rtp_instance_set_remote_address(sub->rtp, &sin_tmp); 05699 ast_rtp_instance_get_local_address(sub->rtp, &us_tmp); 05700 ast_sockaddr_to_sin(&us_tmp, &us); 05701 us.sin_addr.s_addr = us.sin_addr.s_addr ? us.sin_addr.s_addr : d->ourip.s_addr; 05702 } else { 05703 ast_log(LOG_ERROR, "No RTP structure, this is very bad\n"); 05704 return 0; 05705 } 05706 05707 if (skinnydebug) { 05708 ast_verb(1, "device ipaddr = %s:%d\n", ast_inet_ntoa(sin.sin_addr), ntohs(sin.sin_port)); 05709 ast_verb(1, "asterisk ipaddr = %s:%d\n", ast_inet_ntoa(us.sin_addr), ntohs(us.sin_port)); 05710 } 05711 05712 fmt = ast_codec_pref_getsize(&l->prefs, ast_best_codec(l->capability)); 05713 05714 if (skinnydebug) 05715 ast_verb(1, "Setting payloadType to '%s' (%d ms)\n", ast_getformatname(fmt.bits), fmt.cur_ms); 05716 05717 transmit_startmediatransmission(d, sub, us, fmt); 05718 05719 return 1; 05720 }
static int handle_register_message | ( | struct skinny_req * | req, | |
struct skinnysession * | s | |||
) | [static] |
Definition at line 4755 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, register_message::name, 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().
04756 { 04757 struct skinny_device *d = NULL; 04758 char name[16]; 04759 int res; 04760 04761 memcpy(&name, req->data.reg.name, sizeof(name)); 04762 04763 res = skinny_register(req, s); 04764 if (!res) { 04765 ast_log(LOG_ERROR, "Rejecting Device %s: Device not found\n", name); 04766 if (!(req = req_alloc(sizeof(struct register_rej_message), REGISTER_REJ_MESSAGE))) 04767 return -1; 04768 04769 snprintf(req->data.regrej.errMsg, sizeof(req->data.regrej.errMsg), "No Authority: %s", name); 04770 04771 /* transmit_respons in line as we don't have a valid d */ 04772 ast_mutex_lock(&s->lock); 04773 04774 if (letohl(req->len) > SKINNY_MAX_PACKET || letohl(req->len) < 0) { 04775 ast_log(LOG_WARNING, "transmit_response: the length (%d) of the request is out of bounds (%d) \n", letohl(req->len), SKINNY_MAX_PACKET); 04776 ast_mutex_unlock(&s->lock); 04777 return -1; 04778 } 04779 04780 memset(s->outbuf, 0, sizeof(s->outbuf)); 04781 memcpy(s->outbuf, req, skinny_header_size); 04782 memcpy(s->outbuf+skinny_header_size, &req->data, letohl(req->len)); 04783 04784 res = write(s->fd, s->outbuf, letohl(req->len)+8); 04785 04786 if (res != letohl(req->len)+8) { 04787 ast_log(LOG_WARNING, "Transmit: write only sent %d out of %d bytes: %s\n", res, letohl(req->len)+8, strerror(errno)); 04788 } 04789 04790 ast_mutex_unlock(&s->lock); 04791 04792 return 0; 04793 } 04794 ast_atomic_fetchadd_int(&unauth_sessions, -1); 04795 04796 ast_verb(3, "Device '%s' successfully registered\n", name); 04797 04798 d = s->device; 04799 04800 if (!(req = req_alloc(sizeof(struct register_ack_message), REGISTER_ACK_MESSAGE))) 04801 return -1; 04802 04803 req->data.regack.res[0] = '0'; 04804 req->data.regack.res[1] = '\0'; 04805 req->data.regack.keepAlive = htolel(keep_alive); 04806 memcpy(req->data.regack.dateTemplate, date_format, sizeof(req->data.regack.dateTemplate)); 04807 req->data.regack.res2[0] = '0'; 04808 req->data.regack.res2[1] = '\0'; 04809 req->data.regack.secondaryKeepAlive = htolel(keep_alive); 04810 transmit_response(d, req); 04811 if (skinnydebug) 04812 ast_verb(1, "Requesting capabilities\n"); 04813 04814 if (!(req = req_alloc(0, CAPABILITIES_REQ_MESSAGE))) 04815 return -1; 04816 04817 transmit_response(d, req); 04818 04819 return res; 04820 }
static char* handle_skinny_reload | ( | struct ast_cli_entry * | e, | |
int | cmd, | |||
struct ast_cli_args * | a | |||
) | [static] |
Definition at line 2924 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.
02925 { 02926 switch (cmd) { 02927 case CLI_INIT: 02928 e->command = "skinny reload"; 02929 e->usage = 02930 "Usage: skinny reload\n" 02931 " Reloads the chan_skinny configuration\n"; 02932 return NULL; 02933 case CLI_GENERATE: 02934 return NULL; 02935 } 02936 02937 if (a->argc != e->args) 02938 return CLI_SHOWUSAGE; 02939 02940 skinny_reload(); 02941 return CLI_SUCCESS; 02942 02943 }
static char* handle_skinny_reset | ( | struct ast_cli_entry * | e, | |
int | cmd, | |||
struct ast_cli_args * | a | |||
) | [static] |
Definition at line 2989 of file chan_skinny.c.
References ast_cli_args::argc, ast_cli_args::argv, AST_LIST_LOCK, AST_LIST_TRAVERSE, AST_LIST_UNLOCK, ast_verb, CLI_GENERATE, CLI_INIT, CLI_SHOWUSAGE, CLI_SUCCESS, complete_skinny_reset(), skinny_req::data, skinny_req::e, ast_cli_args::line, skinny_subchannel::list, ast_cli_args::n, ast_cli_args::pos, req_alloc(), skinny_data::reset, RESET_MESSAGE, reset_message::resetType, skinny_device::session, transmit_response(), and ast_cli_args::word.
02990 { 02991 struct skinny_device *d; 02992 struct skinny_req *req; 02993 02994 switch (cmd) { 02995 case CLI_INIT: 02996 e->command = "skinny reset"; 02997 e->usage = 02998 "Usage: skinny reset <DeviceId|DeviceName|all> [restart]\n" 02999 " Causes a Skinny device to reset itself, optionally with a full restart\n"; 03000 return NULL; 03001 case CLI_GENERATE: 03002 return complete_skinny_reset(a->line, a->word, a->pos, a->n); 03003 } 03004 03005 if (a->argc < 3 || a->argc > 4) 03006 return CLI_SHOWUSAGE; 03007 03008 AST_LIST_LOCK(&devices); 03009 AST_LIST_TRAVERSE(&devices, d, list) { 03010 int fullrestart = 0; 03011 if (!strcasecmp(a->argv[2], d->id) || !strcasecmp(a->argv[2], d->name) || !strcasecmp(a->argv[2], "all")) { 03012 if (!(d->session)) 03013 continue; 03014 03015 if (!(req = req_alloc(sizeof(struct reset_message), RESET_MESSAGE))) 03016 continue; 03017 03018 if (a->argc == 4 && !strcasecmp(a->argv[3], "restart")) 03019 fullrestart = 1; 03020 03021 if (fullrestart) 03022 req->data.reset.resetType = 2; 03023 else 03024 req->data.reset.resetType = 1; 03025 03026 ast_verb(3, "%s device %s.\n", (fullrestart) ? "Restarting" : "Resetting", d->id); 03027 transmit_response(d, req); 03028 } 03029 } 03030 AST_LIST_UNLOCK(&devices); 03031 return CLI_SUCCESS; 03032 }
static char* handle_skinny_set_debug | ( | struct ast_cli_entry * | e, | |
int | cmd, | |||
struct ast_cli_args * | a | |||
) | [static] |
Definition at line 2882 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.
02883 { 02884 switch (cmd) { 02885 case CLI_INIT: 02886 #ifdef SKINNY_DEVMODE 02887 e->command = "skinny set debug {off|on|packet}"; 02888 e->usage = 02889 "Usage: skinny set debug {off|on|packet}\n" 02890 " Enables/Disables dumping of Skinny packets for debugging purposes\n"; 02891 #else 02892 e->command = "skinny set debug {off|on}"; 02893 e->usage = 02894 "Usage: skinny set debug {off|on}\n" 02895 " Enables/Disables dumping of Skinny packets for debugging purposes\n"; 02896 #endif 02897 return NULL; 02898 case CLI_GENERATE: 02899 return NULL; 02900 } 02901 02902 if (a->argc != e->args) 02903 return CLI_SHOWUSAGE; 02904 02905 if (!strncasecmp(a->argv[e->args - 1], "on", 2)) { 02906 skinnydebug = 1; 02907 ast_cli(a->fd, "Skinny Debugging Enabled\n"); 02908 return CLI_SUCCESS; 02909 } else if (!strncasecmp(a->argv[e->args - 1], "off", 3)) { 02910 skinnydebug = 0; 02911 ast_cli(a->fd, "Skinny Debugging Disabled\n"); 02912 return CLI_SUCCESS; 02913 #ifdef SKINNY_DEVMODE 02914 } else if (!strncasecmp(a->argv[e->args - 1], "packet", 6)) { 02915 skinnydebug = 2; 02916 ast_cli(a->fd, "Skinny Debugging Enabled including Packets\n"); 02917 return CLI_SUCCESS; 02918 #endif 02919 } else { 02920 return CLI_SHOWUSAGE; 02921 } 02922 }
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 3369 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.
03370 { 03371 switch (cmd) { 03372 case CLI_INIT: 03373 e->command = "skinny show device"; 03374 e->usage = 03375 "Usage: skinny show device <DeviceId|DeviceName>\n" 03376 " Lists all deviceinformation of a specific device known to the Skinny subsystem.\n"; 03377 return NULL; 03378 case CLI_GENERATE: 03379 return complete_skinny_show_device(a->line, a->word, a->pos, a->n); 03380 } 03381 03382 return _skinny_show_device(0, a->fd, NULL, NULL, a->argc, (const char **) a->argv); 03383 }
static char* handle_skinny_show_devices | ( | struct ast_cli_entry * | e, | |
int | cmd, | |||
struct ast_cli_args * | a | |||
) | [static] |
Definition at line 3235 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.
03236 { 03237 03238 switch (cmd) { 03239 case CLI_INIT: 03240 e->command = "skinny show devices"; 03241 e->usage = 03242 "Usage: skinny show devices\n" 03243 " Lists all devices known to the Skinny subsystem.\n"; 03244 return NULL; 03245 case CLI_GENERATE: 03246 return NULL; 03247 } 03248 03249 return _skinny_show_devices(a->fd, NULL, NULL, NULL, a->argc, (const char **) a->argv); 03250 }
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 3666 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.
03667 { 03668 switch (cmd) { 03669 case CLI_INIT: 03670 e->command = "skinny show line"; 03671 e->usage = 03672 "Usage: skinny show line <Line> [ on <DeviceID|DeviceName> ]\n" 03673 " List all lineinformation of a specific line known to the Skinny subsystem.\n"; 03674 return NULL; 03675 case CLI_GENERATE: 03676 return complete_skinny_show_line(a->line, a->word, a->pos, a->n); 03677 } 03678 03679 return _skinny_show_line(0, a->fd, NULL, NULL, a->argc, (const char **) a->argv); 03680 }
static char* handle_skinny_show_lines | ( | struct ast_cli_entry * | e, | |
int | cmd, | |||
struct ast_cli_args * | a | |||
) | [static] |
Definition at line 3483 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.
03484 { 03485 int verbose = 0; 03486 03487 switch (cmd) { 03488 case CLI_INIT: 03489 e->command = "skinny show lines [verbose]"; 03490 e->usage = 03491 "Usage: skinny show lines\n" 03492 " Lists all lines known to the Skinny subsystem.\n" 03493 " If 'verbose' is specified, the output includes\n" 03494 " information about subs for each line.\n"; 03495 return NULL; 03496 case CLI_GENERATE: 03497 return NULL; 03498 } 03499 03500 if (a->argc == e->args) { 03501 if (!strcasecmp(a->argv[e->args-1], "verbose")) { 03502 verbose = 1; 03503 } else { 03504 return CLI_SHOWUSAGE; 03505 } 03506 } else if (a->argc != e->args - 1) { 03507 return CLI_SHOWUSAGE; 03508 } 03509 03510 return _skinny_show_lines(a->fd, NULL, NULL, NULL, a->argc, (const char **) a->argv); 03511 }
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 3683 of file chan_skinny.c.
References ast_cli_args::argc, ast_cli(), ast_inet_ntoa(), AST_JB_ENABLED, AST_JB_FORCED, AST_JB_LOG, ast_test_flag, CLI_GENERATE, CLI_INIT, CLI_SHOWUSAGE, CLI_SUCCESS, ast_cli_entry::command, ast_cli_args::fd, global_jbconf, ast_jb_conf::impl, ast_jb_conf::max_size, ast_jb_conf::resync_threshold, S_OR, and ast_cli_entry::usage.
03684 { 03685 switch (cmd) { 03686 case CLI_INIT: 03687 e->command = "skinny show settings"; 03688 e->usage = 03689 "Usage: skinny show settings\n" 03690 " Lists all global configuration settings of the Skinny subsystem.\n"; 03691 return NULL; 03692 case CLI_GENERATE: 03693 return NULL; 03694 } 03695 03696 if (a->argc != 3) 03697 return CLI_SHOWUSAGE; 03698 03699 ast_cli(a->fd, "\nGlobal Settings:\n"); 03700 ast_cli(a->fd, " Skinny Port: %d\n", ntohs(bindaddr.sin_port)); 03701 ast_cli(a->fd, " Bindaddress: %s\n", ast_inet_ntoa(bindaddr.sin_addr)); 03702 ast_cli(a->fd, " KeepAlive: %d\n", keep_alive); 03703 ast_cli(a->fd, " Date Format: %s\n", date_format); 03704 ast_cli(a->fd, " Voice Mail Extension: %s\n", S_OR(global_vmexten, "(not set)")); 03705 ast_cli(a->fd, " Reg. context: %s\n", S_OR(regcontext, "(not set)")); 03706 ast_cli(a->fd, " Jitterbuffer enabled: %s\n", (ast_test_flag(&global_jbconf, AST_JB_ENABLED) ? "Yes" : "No")); 03707 ast_cli(a->fd, " Jitterbuffer forced: %s\n", (ast_test_flag(&global_jbconf, AST_JB_FORCED) ? "Yes" : "No")); 03708 ast_cli(a->fd, " Jitterbuffer max size: %ld\n", global_jbconf.max_size); 03709 ast_cli(a->fd, " Jitterbuffer resync: %ld\n", global_jbconf.resync_threshold); 03710 ast_cli(a->fd, " Jitterbuffer impl: %s\n", global_jbconf.impl); 03711 ast_cli(a->fd, " Jitterbuffer log: %s\n", (ast_test_flag(&global_jbconf, AST_JB_LOG) ? "Yes" : "No")); 03712 03713 return CLI_SUCCESS; 03714 }
static int handle_soft_key_event_message | ( | struct skinny_req * | req, | |
struct skinnysession * | s | |||
) | [static] |
Definition at line 5772 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, skinny_subchannel::list, 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().
05773 { 05774 struct skinny_device *d = s->device; 05775 struct skinny_line *l; 05776 struct skinny_subchannel *sub = NULL; 05777 struct ast_channel *c; 05778 pthread_t t; 05779 int event; 05780 int instance; 05781 int callreference; 05782 05783 event = letohl(req->data.softkeyeventmessage.softKeyEvent); 05784 instance = letohl(req->data.softkeyeventmessage.instance); 05785 callreference = letohl(req->data.softkeyeventmessage.callreference); 05786 05787 if (instance) { 05788 l = find_line_by_instance(d, instance); 05789 if (callreference) { 05790 sub = find_subchannel_by_instance_reference(d, instance, callreference); 05791 } else { 05792 sub = find_subchannel_by_instance_reference(d, instance, d->lastcallreference); 05793 } 05794 } else { 05795 l = find_line_by_instance(d, d->lastlineinstance); 05796 } 05797 05798 if (!l) { 05799 if (skinnydebug) 05800 ast_verb(1, "Received Softkey Event: %d(%d/%d)\n", event, instance, callreference); 05801 return 0; 05802 } 05803 05804 ast_devstate_changed(AST_DEVICE_INUSE, "Skinny/%s@%s", l->name, d->name); 05805 05806 switch(event) { 05807 case SOFTKEY_NONE: 05808 if (skinnydebug) 05809 ast_verb(1, "Received Softkey Event: None(%d/%d)\n", instance, callreference); 05810 break; 05811 case SOFTKEY_REDIAL: 05812 if (skinnydebug) 05813 ast_verb(1, "Received Softkey Event: Redial(%d/%d)\n", instance, callreference); 05814 05815 if (ast_strlen_zero(l->lastnumberdialed)) { 05816 ast_log(LOG_WARNING, "Attempted redial, but no previously dialed number found. Ignoring button.\n"); 05817 break; 05818 } 05819 05820 if (!sub || !sub->owner) { 05821 c = skinny_new(l, AST_STATE_DOWN, NULL); 05822 } else { 05823 c = sub->owner; 05824 } 05825 05826 if (!c) { 05827 ast_log(LOG_WARNING, "Unable to create channel for %s@%s\n", l->name, d->name); 05828 } else { 05829 sub = c->tech_pvt; 05830 l->activesub = sub; 05831 if (l->hookstate == SKINNY_ONHOOK) { 05832 l->hookstate = SKINNY_OFFHOOK; 05833 transmit_speaker_mode(d, SKINNY_SPEAKERON); 05834 transmit_callstate(d, l->instance, sub->callid, SKINNY_OFFHOOK); 05835 transmit_activatecallplane(d, l); 05836 } 05837 transmit_clear_display_message(d, l->instance, sub->callid); 05838 transmit_start_tone(d, SKINNY_DIALTONE, l->instance, sub->callid); 05839 transmit_selectsoftkeys(d, l->instance, sub->callid, KEYDEF_RINGOUT); 05840 05841 if (!ast_ignore_pattern(c->context, l->lastnumberdialed)) { 05842 transmit_stop_tone(d, l->instance, sub->callid); 05843 } 05844 ast_copy_string(c->exten, l->lastnumberdialed, sizeof(c->exten)); 05845 if (ast_pthread_create(&t, NULL, skinny_newcall, c)) { 05846 ast_log(LOG_WARNING, "Unable to create new call thread: %s\n", strerror(errno)); 05847 ast_hangup(c); 05848 } 05849 } 05850 break; 05851 case SOFTKEY_NEWCALL: /* Actually the DIAL softkey */ 05852 if (skinnydebug) 05853 ast_verb(1, "Received Softkey Event: New Call(%d/%d)\n", instance, callreference); 05854 05855 /* New Call ALWAYS gets a new sub-channel */ 05856 c = skinny_new(l, AST_STATE_DOWN, NULL); 05857 sub = c->tech_pvt; 05858 05859 /* transmit_ringer_mode(d, SKINNY_RING_OFF); 05860 transmit_lamp_indication(d, STIMULUS_LINE, l->instance, SKINNY_LAMP_ON); */ 05861 05862 /* l->hookstate = SKINNY_OFFHOOK; */ 05863 05864 if (!c) { 05865 ast_log(LOG_WARNING, "Unable to create channel for %s@%s\n", l->name, d->name); 05866 } else { 05867 sub = c->tech_pvt; 05868 l->activesub = sub; 05869 if (l->hookstate == SKINNY_ONHOOK) { 05870 l->hookstate = SKINNY_OFFHOOK; 05871 transmit_speaker_mode(d, SKINNY_SPEAKERON); 05872 } 05873 ast_verb(1, "Call-id: %d\n", sub->callid); 05874 05875 transmit_callstate(d, l->instance, sub->callid, SKINNY_OFFHOOK); 05876 transmit_activatecallplane(d, l); 05877 05878 transmit_clear_display_message(d, l->instance, sub->callid); 05879 transmit_start_tone(d, SKINNY_DIALTONE, l->instance, sub->callid); 05880 transmit_selectsoftkeys(d, l->instance, sub->callid, KEYDEF_OFFHOOK); 05881 05882 /* start the switch thread */ 05883 if (ast_pthread_create(&t, NULL, skinny_ss, c)) { 05884 ast_log(LOG_WARNING, "Unable to create switch thread: %s\n", strerror(errno)); 05885 ast_hangup(c); 05886 } 05887 } 05888 break; 05889 case SOFTKEY_HOLD: 05890 if (skinnydebug) 05891 ast_verb(1, "Received Softkey Event: Hold(%d/%d)\n", instance, callreference); 05892 handle_hold_button(sub); 05893 break; 05894 case SOFTKEY_TRNSFER: 05895 if (skinnydebug) 05896 ast_verb(1, "Received Softkey Event: Transfer(%d/%d)\n", instance, callreference); 05897 if (l->transfer) 05898 handle_transfer_button(sub); 05899 else 05900 transmit_displaynotify(d, "Transfer disabled", 10); 05901 05902 break; 05903 case SOFTKEY_DND: 05904 if (skinnydebug) 05905 ast_verb(1, "Received Softkey Event: DND(%d/%d)\n", instance, callreference); 05906 05907 /* Do not disturb */ 05908 if (l->dnd != 0){ 05909 ast_verb(3, "Disabling DND on %s@%s\n", l->name, d->name); 05910 l->dnd = 0; 05911 transmit_lamp_indication(d, STIMULUS_DND, 1, SKINNY_LAMP_ON); 05912 transmit_displaynotify(d, "DnD disabled", 10); 05913 } else { 05914 ast_verb(3, "Enabling DND on %s@%s\n", l->name, d->name); 05915 l->dnd = 1; 05916 transmit_lamp_indication(d, STIMULUS_DND, 1, SKINNY_LAMP_OFF); 05917 transmit_displaynotify(d, "DnD enabled", 10); 05918 } 05919 break; 05920 case SOFTKEY_CFWDALL: 05921 if (skinnydebug) 05922 ast_verb(1, "Received Softkey Event: Forward All(%d/%d)\n", instance, callreference); 05923 05924 if (!sub || !sub->owner) { 05925 c = skinny_new(l, AST_STATE_DOWN, NULL); 05926 } else { 05927 c = sub->owner; 05928 } 05929 05930 if (!c) { 05931 ast_log(LOG_WARNING, "Unable to create channel for %s@%s\n", l->name, d->name); 05932 } else { 05933 sub = c->tech_pvt; 05934 l->activesub = sub; 05935 handle_callforward_button(sub, SKINNY_CFWD_ALL); 05936 } 05937 break; 05938 case SOFTKEY_CFWDBUSY: 05939 if (skinnydebug) 05940 ast_verb(1, "Received Softkey Event: Forward Busy (%d/%d)\n", instance, callreference); 05941 05942 if (!sub || !sub->owner) { 05943 c = skinny_new(l, AST_STATE_DOWN, NULL); 05944 } else { 05945 c = sub->owner; 05946 } 05947 05948 if (!c) { 05949 ast_log(LOG_WARNING, "Unable to create channel for %s@%s\n", l->name, d->name); 05950 } else { 05951 sub = c->tech_pvt; 05952 l->activesub = sub; 05953 handle_callforward_button(sub, SKINNY_CFWD_BUSY); 05954 } 05955 break; 05956 case SOFTKEY_CFWDNOANSWER: 05957 if (skinnydebug) 05958 ast_verb(1, "Received Softkey Event: Forward No Answer (%d/%d)\n", instance, callreference); 05959 05960 #if 0 /* Not sure how to handle this yet */ 05961 if (!sub || !sub->owner) { 05962 c = skinny_new(l, AST_STATE_DOWN, NULL); 05963 } else { 05964 c = sub->owner; 05965 } 05966 05967 if (!c) { 05968 ast_log(LOG_WARNING, "Unable to create channel for %s@%s\n", l->name, d->name); 05969 } else { 05970 sub = c->tech_pvt; 05971 l->activesub = sub; 05972 handle_callforward_button(sub, SKINNY_CFWD_NOANSWER); 05973 } 05974 #endif 05975 break; 05976 case SOFTKEY_BKSPC: 05977 if (skinnydebug) 05978 ast_verb(1, "Received Softkey Event: Backspace(%d/%d)\n", instance, callreference); 05979 break; 05980 case SOFTKEY_ENDCALL: 05981 if (skinnydebug) 05982 ast_verb(1, "Received Softkey Event: End Call(%d/%d)\n", instance, callreference); 05983 05984 if (l->hookstate == SKINNY_ONHOOK) { 05985 /* Something else already put us back on hook */ 05986 break; 05987 } 05988 if (sub) { 05989 int onlysub = 0; 05990 05991 if (!AST_LIST_NEXT(sub, list)) { 05992 onlysub = 1; 05993 } else { 05994 AST_LIST_REMOVE(&l->sub, sub, list); 05995 } 05996 05997 sub->cxmode = SKINNY_CX_RECVONLY; 05998 if (onlysub || sub->xferor){ /*Are there other calls to this device */ 05999 l->hookstate = SKINNY_ONHOOK; 06000 if (skinnydebug) 06001 ast_debug(1, "Skinny %s@%s-%d went on hook\n", l->name, d->name, callreference); 06002 } 06003 06004 if (l->hookstate == SKINNY_ONHOOK) { 06005 transmit_closereceivechannel(d, sub); 06006 transmit_stopmediatransmission(d, sub); 06007 transmit_speaker_mode(d, SKINNY_SPEAKEROFF); 06008 transmit_clearpromptmessage(d, instance, sub->callid); 06009 transmit_callstate(d, l->instance, sub->callid, SKINNY_ONHOOK); 06010 transmit_selectsoftkeys(d, 0, 0, KEYDEF_ONHOOK); 06011 transmit_activatecallplane(d, l); 06012 } else if (l->hookstate == SKINNY_OFFHOOK) { 06013 transmit_callstate(d, l->instance, sub->callid, SKINNY_OFFHOOK); 06014 transmit_activatecallplane(d, l); 06015 } else { 06016 transmit_callstate(d, l->instance, sub->callid, l->hookstate); 06017 } 06018 06019 ast_devstate_changed(AST_DEVICE_NOT_INUSE, "Skinny/%s@%s", l->name, d->name); 06020 if (skinnydebug) 06021 ast_verb(1, "Skinny %s@%s went on hook\n", l->name, d->name); 06022 if (l->transfer && sub->xferor && sub->owner->_state >= AST_STATE_RING) { 06023 /* We're allowed to transfer, we have two active calls and 06024 we made at least one of the calls. Let's try and transfer */ 06025 handle_transfer_button(sub); 06026 } else { 06027 /* Hangup the current call */ 06028 /* If there is another active call, skinny_hangup will ring the phone with the other call */ 06029 if (sub->xferor && sub->related){ 06030 sub->related->related = NULL; 06031 sub->related->blindxfer = 0; 06032 } 06033 06034 if (sub->owner) { 06035 sub->alreadygone = 1; 06036 ast_queue_hangup(sub->owner); 06037 } else { 06038 ast_log(LOG_WARNING, "Skinny(%s@%s-%d) channel already destroyed\n", 06039 l->name, d->name, sub->callid); 06040 } 06041 } 06042 if ((l->hookstate == SKINNY_ONHOOK) && (AST_LIST_NEXT(sub, list) && !AST_LIST_NEXT(sub, list)->rtp)) { 06043 ast_devstate_changed(AST_DEVICE_NOT_INUSE, "Skinny/%s@%s", l->name, d->name); 06044 } 06045 } 06046 break; 06047 case SOFTKEY_RESUME: 06048 if (skinnydebug) 06049 ast_verb(1, "Received Softkey Event: Resume(%d/%d)\n", instance, callreference); 06050 06051 if (sub) { 06052 if (sub->onhold) { 06053 skinny_unhold(sub); 06054 transmit_selectsoftkeys(d, l->instance, sub->callid, KEYDEF_CONNECTED); 06055 } else { 06056 skinny_hold(sub); 06057 transmit_selectsoftkeys(d, l->instance, sub->callid, KEYDEF_ONHOLD); 06058 } 06059 } 06060 06061 break; 06062 case SOFTKEY_ANSWER: 06063 if (skinnydebug) 06064 ast_verb(1, "Received Softkey Event: Answer(%d/%d)\n", instance, callreference); 06065 06066 transmit_ringer_mode(d, SKINNY_RING_OFF); 06067 transmit_lamp_indication(d, STIMULUS_LINE, l->instance, SKINNY_LAMP_ON); 06068 if (l->hookstate == SKINNY_ONHOOK) { 06069 transmit_speaker_mode(d, SKINNY_SPEAKERON); 06070 l->hookstate = SKINNY_OFFHOOK; 06071 } 06072 06073 if (sub && sub->outgoing) { 06074 /* We're answering a ringing call */ 06075 ast_queue_control(sub->owner, AST_CONTROL_ANSWER); 06076 transmit_callstate(d, l->instance, sub->callid, SKINNY_OFFHOOK); 06077 transmit_activatecallplane(d, l); 06078 transmit_stop_tone(d, l->instance, sub->callid); 06079 transmit_callstate(d, sub->parent->instance, sub->callid, SKINNY_CONNECTED); 06080 transmit_selectsoftkeys(d, l->instance, sub->callid, KEYDEF_CONNECTED); 06081 start_rtp(sub); 06082 ast_setstate(sub->owner, AST_STATE_UP); 06083 } 06084 break; 06085 case SOFTKEY_INFO: 06086 if (skinnydebug) 06087 ast_verb(1, "Received Softkey Event: Info(%d/%d)\n", instance, callreference); 06088 break; 06089 case SOFTKEY_CONFRN: 06090 if (skinnydebug) 06091 ast_verb(1, "Received Softkey Event: Conference(%d/%d)\n", instance, callreference); 06092 /* XXX determine the best way to pull off a conference. Meetme? */ 06093 break; 06094 case SOFTKEY_PARK: 06095 { 06096 int extout; 06097 char message[32]; 06098 06099 if (skinnydebug) 06100 ast_verb(1, "Received Softkey Event: Park Call(%d/%d)\n", instance, callreference); 06101 06102 if ((sub && sub->owner) && (sub->owner->_state == AST_STATE_UP)){ 06103 c = sub->owner; 06104 if (ast_bridged_channel(c)) { 06105 if (!ast_masq_park_call(ast_bridged_channel(c), c, 0, &extout)) { 06106 snprintf(message, sizeof(message), "Call Parked at: %d", extout); 06107 transmit_displaynotify(d, message, 10); 06108 } else { 06109 transmit_displaynotify(d, "Call Park failed", 10); 06110 } 06111 } else { 06112 transmit_displaynotify(d, "Call Park not available", 10); 06113 } 06114 } else { 06115 transmit_displaynotify(d, "Call Park not available", 10); 06116 } 06117 break; 06118 } 06119 case SOFTKEY_JOIN: 06120 if (skinnydebug) 06121 ast_verb(1, "Received Softkey Event: Join(%d/%d)\n", instance, callreference); 06122 break; 06123 case SOFTKEY_MEETME: 06124 /* XXX How is this different from CONFRN? */ 06125 if (skinnydebug) 06126 ast_verb(1, "Received Softkey Event: Meetme(%d/%d)\n", instance, callreference); 06127 break; 06128 case SOFTKEY_PICKUP: 06129 if (skinnydebug) 06130 ast_verb(1, "Received Softkey Event: Pickup(%d/%d)\n", instance, callreference); 06131 break; 06132 case SOFTKEY_GPICKUP: 06133 if (skinnydebug) 06134 ast_verb(1, "Received Softkey Event: Group Pickup(%d/%d)\n", instance, callreference); 06135 break; 06136 default: 06137 if (skinnydebug) 06138 ast_verb(1, "Received unknown Softkey Event: %d(%d/%d)\n", event, instance, callreference); 06139 break; 06140 } 06141 06142 return 1; 06143 }
static int handle_stimulus_message | ( | struct skinny_req * | req, | |
struct skinnysession * | s | |||
) | [static] |
Definition at line 4942 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, skinny_speeddial::exten, ast_channel::exten, find_line_by_instance(), find_speeddial_by_instance(), find_subchannel_by_instance_reference(), handle_callforward_button(), handle_hold_button(), handle_transfer_button(), 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().
04943 { 04944 struct skinny_device *d = s->device; 04945 struct skinny_line *l; 04946 struct skinny_subchannel *sub; 04947 /*struct skinny_speeddial *sd;*/ 04948 struct ast_channel *c; 04949 pthread_t t; 04950 int event; 04951 int instance; 04952 int callreference; 04953 /*int res = 0;*/ 04954 04955 event = letohl(req->data.stimulus.stimulus); 04956 instance = letohl(req->data.stimulus.stimulusInstance); 04957 callreference = letohl(req->data.stimulus.callreference); 04958 if (skinnydebug) 04959 ast_verb(1, "callreference in handle_stimulus_message is '%d'\n", callreference); 04960 04961 /* Note that this call should be using the passed in instance and callreference */ 04962 sub = find_subchannel_by_instance_reference(d, d->lastlineinstance, d->lastcallreference); 04963 04964 if (!sub) { 04965 l = find_line_by_instance(d, d->lastlineinstance); 04966 if (!l) { 04967 return 0; 04968 } 04969 sub = l->activesub; 04970 } else { 04971 l = sub->parent; 04972 } 04973 04974 switch(event) { 04975 case STIMULUS_REDIAL: 04976 if (skinnydebug) 04977 ast_verb(1, "Received Stimulus: Redial(%d/%d)\n", instance, callreference); 04978 04979 if (ast_strlen_zero(l->lastnumberdialed)) { 04980 ast_log(LOG_WARNING, "Attempted redial, but no previously dialed number found.\n"); 04981 l->hookstate = SKINNY_ONHOOK; 04982 transmit_speaker_mode(d, SKINNY_SPEAKEROFF); 04983 transmit_closereceivechannel(d, sub); 04984 transmit_stopmediatransmission(d, sub); 04985 transmit_speaker_mode(d, SKINNY_SPEAKEROFF); 04986 transmit_clearpromptmessage(d, l->instance, sub->callid); 04987 transmit_callstate(d, l->instance, sub->callid, SKINNY_ONHOOK); 04988 transmit_selectsoftkeys(d, 0, 0, KEYDEF_ONHOOK); 04989 transmit_activatecallplane(d, l); 04990 break; 04991 } 04992 04993 c = skinny_new(l, AST_STATE_DOWN, NULL); 04994 if (!c) { 04995 ast_log(LOG_WARNING, "Unable to create channel for %s@%s\n", l->name, d->name); 04996 } else { 04997 sub = c->tech_pvt; 04998 l = sub->parent; 04999 l->activesub = sub; 05000 if (l->hookstate == SKINNY_ONHOOK) { 05001 l->hookstate = SKINNY_OFFHOOK; 05002 transmit_callstate(d, l->instance, sub->callid, SKINNY_OFFHOOK); 05003 transmit_activatecallplane(d, l); 05004 } 05005 transmit_clear_display_message(d, l->instance, sub->callid); 05006 transmit_start_tone(d, SKINNY_DIALTONE, l->instance, sub->callid); 05007 transmit_selectsoftkeys(d, l->instance, sub->callid, KEYDEF_RINGOUT); 05008 05009 if (!ast_ignore_pattern(c->context, l->lastnumberdialed)) { 05010 transmit_stop_tone(d, l->instance, sub->callid); 05011 } 05012 ast_copy_string(c->exten, l->lastnumberdialed, sizeof(c->exten)); 05013 if (ast_pthread_create(&t, NULL, skinny_newcall, c)) { 05014 ast_log(LOG_WARNING, "Unable to create new call thread: %s\n", strerror(errno)); 05015 ast_hangup(c); 05016 } 05017 } 05018 break; 05019 case STIMULUS_SPEEDDIAL: 05020 { 05021 struct skinny_speeddial *sd; 05022 05023 if (skinnydebug) 05024 ast_verb(1, "Received Stimulus: SpeedDial(%d/%d)\n", instance, callreference); 05025 if (!(sd = find_speeddial_by_instance(d, instance, 0))) { 05026 return 0; 05027 } 05028 05029 if (!sub || !sub->owner) 05030 c = skinny_new(l, AST_STATE_DOWN, NULL); 05031 else 05032 c = sub->owner; 05033 05034 if (!c) { 05035 ast_log(LOG_WARNING, "Unable to create channel for %s@%s\n", l->name, d->name); 05036 } else { 05037 sub = c->tech_pvt; 05038 l = sub->parent; 05039 l->activesub = sub; 05040 if (l->hookstate == SKINNY_ONHOOK) { 05041 l->hookstate = SKINNY_OFFHOOK; 05042 transmit_speaker_mode(d, SKINNY_SPEAKERON); 05043 transmit_callstate(d, l->instance, sub->callid, SKINNY_OFFHOOK); 05044 transmit_activatecallplane(d, l); 05045 } 05046 transmit_clear_display_message(d, l->instance, sub->callid); 05047 transmit_start_tone(d, SKINNY_DIALTONE, l->instance, sub->callid); 05048 transmit_selectsoftkeys(d, l->instance, sub->callid, KEYDEF_RINGOUT); 05049 05050 if (!ast_ignore_pattern(c->context, sd->exten)) { 05051 transmit_stop_tone(d, l->instance, sub->callid); 05052 } 05053 if (ast_exists_extension(c, c->context, sd->exten, 1, l->cid_num)) { 05054 ast_copy_string(c->exten, sd->exten, sizeof(c->exten)); 05055 ast_copy_string(l->lastnumberdialed, sd->exten, sizeof(l->lastnumberdialed)); 05056 05057 if (ast_pthread_create(&t, NULL, skinny_newcall, c)) { 05058 ast_log(LOG_WARNING, "Unable to create new call thread: %s\n", strerror(errno)); 05059 ast_hangup(c); 05060 } 05061 break; 05062 } 05063 } 05064 } 05065 break; 05066 case STIMULUS_HOLD: 05067 if (skinnydebug) 05068 ast_verb(1, "Received Stimulus: Hold(%d/%d)\n", instance, callreference); 05069 handle_hold_button(sub); 05070 break; 05071 case STIMULUS_TRANSFER: 05072 if (skinnydebug) 05073 ast_verb(1, "Received Stimulus: Transfer(%d/%d)\n", instance, callreference); 05074 if (l->transfer) 05075 handle_transfer_button(sub); 05076 else 05077 transmit_displaynotify(d, "Transfer disabled", 10); 05078 break; 05079 case STIMULUS_CONFERENCE: 05080 if (skinnydebug) 05081 ast_verb(1, "Received Stimulus: Conference(%d/%d)\n", instance, callreference); 05082 /* XXX determine the best way to pull off a conference. Meetme? */ 05083 break; 05084 case STIMULUS_VOICEMAIL: 05085 if (skinnydebug) 05086 ast_verb(1, "Received Stimulus: Voicemail(%d/%d)\n", instance, callreference); 05087 05088 if (!sub || !sub->owner) { 05089 c = skinny_new(l, AST_STATE_DOWN, NULL); 05090 } else { 05091 c = sub->owner; 05092 } 05093 if (!c) { 05094 ast_log(LOG_WARNING, "Unable to create channel for %s@%s\n", l->name, d->name); 05095 } else { 05096 sub = c->tech_pvt; 05097 l = sub->parent; 05098 l->activesub = sub; 05099 05100 if (ast_strlen_zero(l->vmexten)) /* Exit the call if no VM pilot */ 05101 break; 05102 05103 if (l->hookstate == SKINNY_ONHOOK){ 05104 l->hookstate = SKINNY_OFFHOOK; 05105 transmit_speaker_mode(d, SKINNY_SPEAKERON); 05106 transmit_callstate(d, l->instance, sub->callid, SKINNY_OFFHOOK); 05107 transmit_activatecallplane(d, l); 05108 } 05109 05110 transmit_clear_display_message(d, l->instance, sub->callid); 05111 transmit_start_tone(d, SKINNY_DIALTONE, l->instance, sub->callid); 05112 transmit_selectsoftkeys(d, l->instance, sub->callid, KEYDEF_RINGOUT); 05113 05114 if (!ast_ignore_pattern(c->context, l->vmexten)) { 05115 transmit_stop_tone(d, l->instance, sub->callid); 05116 } 05117 05118 if (ast_exists_extension(c, c->context, l->vmexten, 1, l->cid_num)) { 05119 ast_copy_string(c->exten, l->vmexten, sizeof(c->exten)); 05120 ast_copy_string(l->lastnumberdialed, l->vmexten, sizeof(l->lastnumberdialed)); 05121 if (ast_pthread_create(&t, NULL, skinny_newcall, c)) { 05122 ast_log(LOG_WARNING, "Unable to create new call thread: %s\n", strerror(errno)); 05123 ast_hangup(c); 05124 } 05125 break; 05126 } 05127 } 05128 break; 05129 case STIMULUS_CALLPARK: 05130 { 05131 int extout; 05132 char message[32]; 05133 05134 if (skinnydebug) 05135 ast_verb(1, "Received Stimulus: Park Call(%d/%d)\n", instance, callreference); 05136 05137 if ((sub && sub->owner) && (sub->owner->_state == AST_STATE_UP)){ 05138 c = sub->owner; 05139 if (ast_bridged_channel(c)) { 05140 if (!ast_masq_park_call(ast_bridged_channel(c), c, 0, &extout)) { 05141 snprintf(message, sizeof(message), "Call Parked at: %d", extout); 05142 transmit_displaynotify(d, message, 10); 05143 } else { 05144 transmit_displaynotify(d, "Call Park failed", 10); 05145 } 05146 } else { 05147 transmit_displaynotify(d, "Call Park not available", 10); 05148 } 05149 } else { 05150 transmit_displaynotify(d, "Call Park not available", 10); 05151 } 05152 break; 05153 } 05154 case STIMULUS_DND: 05155 if (skinnydebug) 05156 ast_verb(1, "Received Stimulus: DND (%d/%d)\n", instance, callreference); 05157 05158 /* Do not disturb */ 05159 if (l->dnd != 0){ 05160 ast_verb(3, "Disabling DND on %s@%s\n", l->name, d->name); 05161 l->dnd = 0; 05162 transmit_lamp_indication(d, STIMULUS_DND, 1, SKINNY_LAMP_ON); 05163 transmit_displaynotify(d, "DnD disabled", 10); 05164 } else { 05165 ast_verb(3, "Enabling DND on %s@%s\n", l->name, d->name); 05166 l->dnd = 1; 05167 transmit_lamp_indication(d, STIMULUS_DND, 1, SKINNY_LAMP_OFF); 05168 transmit_displaynotify(d, "DnD enabled", 10); 05169 } 05170 break; 05171 case STIMULUS_FORWARDALL: 05172 if (skinnydebug) 05173 ast_verb(1, "Received Stimulus: Forward All(%d/%d)\n", instance, callreference); 05174 05175 if (!sub || !sub->owner) { 05176 c = skinny_new(l, AST_STATE_DOWN, NULL); 05177 } else { 05178 c = sub->owner; 05179 } 05180 05181 if (!c) { 05182 ast_log(LOG_WARNING, "Unable to create channel for %s@%s\n", l->name, d->name); 05183 } else { 05184 sub = c->tech_pvt; 05185 handle_callforward_button(sub, SKINNY_CFWD_ALL); 05186 } 05187 break; 05188 case STIMULUS_FORWARDBUSY: 05189 if (skinnydebug) 05190 ast_verb(1, "Received Stimulus: Forward Busy (%d/%d)\n", instance, callreference); 05191 05192 if (!sub || !sub->owner) { 05193 c = skinny_new(l, AST_STATE_DOWN, NULL); 05194 } else { 05195 c = sub->owner; 05196 } 05197 05198 if (!c) { 05199 ast_log(LOG_WARNING, "Unable to create channel for %s@%s\n", l->name, d->name); 05200 } else { 05201 sub = c->tech_pvt; 05202 handle_callforward_button(sub, SKINNY_CFWD_BUSY); 05203 } 05204 break; 05205 case STIMULUS_FORWARDNOANSWER: 05206 if (skinnydebug) 05207 ast_verb(1, "Received Stimulus: Forward No Answer (%d/%d)\n", instance, callreference); 05208 05209 #if 0 /* Not sure how to handle this yet */ 05210 if (!sub || !sub->owner) { 05211 c = skinny_new(l, AST_STATE_DOWN, NULL); 05212 } else { 05213 c = sub->owner; 05214 } 05215 05216 if (!c) { 05217 ast_log(LOG_WARNING, "Unable to create channel for %s@%s\n", l->name, d->name); 05218 } else { 05219 sub = c->tech_pvt; 05220 handle_callforward_button(sub, SKINNY_CFWD_NOANSWER); 05221 } 05222 #endif 05223 break; 05224 case STIMULUS_DISPLAY: 05225 /* Not sure what this is */ 05226 if (skinnydebug) 05227 ast_verb(1, "Received Stimulus: Display(%d/%d)\n", instance, callreference); 05228 break; 05229 case STIMULUS_LINE: 05230 if (skinnydebug) 05231 ast_verb(1, "Received Stimulus: Line(%d/%d)\n", instance, callreference); 05232 05233 l = find_line_by_instance(d, instance); 05234 05235 if (!l) { 05236 return 0; 05237 } 05238 05239 d->activeline = l; 05240 05241 /* turn the speaker on */ 05242 transmit_speaker_mode(d, SKINNY_SPEAKERON); 05243 transmit_ringer_mode(d, SKINNY_RING_OFF); 05244 transmit_lamp_indication(d, STIMULUS_LINE, l->instance, SKINNY_LAMP_ON); 05245 05246 l->hookstate = SKINNY_OFFHOOK; 05247 05248 if (sub && sub->outgoing) { 05249 /* We're answering a ringing call */ 05250 ast_queue_control(sub->owner, AST_CONTROL_ANSWER); 05251 transmit_callstate(d, l->instance, sub->callid, SKINNY_OFFHOOK); 05252 transmit_activatecallplane(d, l); 05253 transmit_stop_tone(d, l->instance, sub->callid); 05254 transmit_callstate(d, sub->parent->instance, sub->callid, SKINNY_CONNECTED); 05255 transmit_displaypromptstatus(d, "Connected", 0, l->instance, sub->callid); 05256 transmit_selectsoftkeys(d, l->instance, sub->callid, KEYDEF_CONNECTED); 05257 start_rtp(sub); 05258 ast_setstate(sub->owner, AST_STATE_UP); 05259 } else { 05260 if (sub && sub->owner) { 05261 ast_debug(1, "Current subchannel [%s] already has owner\n", sub->owner->name); 05262 } else { 05263 c = skinny_new(l, AST_STATE_DOWN, NULL); 05264 if (c) { 05265 sub = c->tech_pvt; 05266 l->activesub = sub; 05267 transmit_callstate(d, l->instance, sub->callid, SKINNY_OFFHOOK); 05268 transmit_activatecallplane(d, l); 05269 transmit_clear_display_message(d, l->instance, sub->callid); 05270 transmit_start_tone(d, SKINNY_DIALTONE, l->instance, sub->callid); 05271 transmit_selectsoftkeys(d, l->instance, sub->callid, KEYDEF_OFFHOOK); 05272 05273 /* start the switch thread */ 05274 if (ast_pthread_create(&t, NULL, skinny_ss, c)) { 05275 ast_log(LOG_WARNING, "Unable to create switch thread: %s\n", strerror(errno)); 05276 ast_hangup(c); 05277 } 05278 } else { 05279 ast_log(LOG_WARNING, "Unable to create channel for %s@%s\n", l->name, d->name); 05280 } 05281 } 05282 } 05283 break; 05284 default: 05285 if (skinnydebug) 05286 ast_verb(1, "RECEIVED UNKNOWN STIMULUS: %d(%d/%d)\n", event, instance, callreference); 05287 break; 05288 } 05289 ast_devstate_changed(AST_DEVICE_UNKNOWN, "Skinny/%s@%s", l->name, d->name); 05290 05291 return 1; 05292 }
static int handle_transfer_button | ( | struct skinny_subchannel * | sub | ) | [static] |
Definition at line 4682 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().
04683 { 04684 struct skinny_line *l; 04685 struct skinny_device *d; 04686 struct skinny_subchannel *newsub; 04687 struct ast_channel *c; 04688 pthread_t t; 04689 04690 if (!sub) { 04691 ast_verbose("Transfer: No subchannel to transfer\n"); 04692 return -1; 04693 } 04694 04695 l = sub->parent; 04696 d = l->device; 04697 04698 if (!sub->related) { 04699 /* Another sub has not been created so this must be first XFER press */ 04700 if (!sub->onhold) { 04701 skinny_hold(sub); 04702 } 04703 c = skinny_new(l, AST_STATE_DOWN, NULL); 04704 if (c) { 04705 newsub = c->tech_pvt; 04706 /* point the sub and newsub at each other so we know they are related */ 04707 newsub->related = sub; 04708 sub->related = newsub; 04709 newsub->xferor = 1; 04710 l->activesub = newsub; 04711 transmit_callstate(d, l->instance, sub->callid, SKINNY_OFFHOOK); 04712 transmit_activatecallplane(d, l); 04713 transmit_clear_display_message(d, l->instance, newsub->callid); 04714 transmit_start_tone(d, SKINNY_DIALTONE, l->instance, newsub->callid); 04715 transmit_selectsoftkeys(d, l->instance, newsub->callid, KEYDEF_OFFHOOKWITHFEAT); 04716 /* start the switch thread */ 04717 if (ast_pthread_create(&t, NULL, skinny_ss, c)) { 04718 ast_log(LOG_WARNING, "Unable to create switch thread: %s\n", strerror(errno)); 04719 ast_hangup(c); 04720 } 04721 } else { 04722 ast_log(LOG_WARNING, "Unable to create channel for %s@%s\n", l->name, d->name); 04723 } 04724 } else { 04725 /* We already have a related sub so we can either complete XFER or go into BLINDXFER (or cancel BLINDXFER */ 04726 if (sub->blindxfer) { 04727 /* toggle blindxfer off */ 04728 sub->blindxfer = 0; 04729 sub->related->blindxfer = 0; 04730 /* we really need some indications */ 04731 } else { 04732 /* We were doing attended transfer */ 04733 if (sub->owner->_state == AST_STATE_DOWN || sub->related->owner->_state == AST_STATE_DOWN) { 04734 /* one of the subs so we cant transfer yet, toggle blindxfer on */ 04735 sub->blindxfer = 1; 04736 sub->related->blindxfer = 1; 04737 } else { 04738 /* big assumption we have two channels, lets transfer */ 04739 skinny_transfer(sub); 04740 } 04741 } 04742 } 04743 return 0; 04744 }
static int load_module | ( | void | ) | [static] |
Definition at line 7445 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, 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, sched_context_create(), skinny_rtp_glue, skinny_tech, and soft_key_template_default.
07446 { 07447 int res = 0; 07448 07449 for (; res < ARRAY_LEN(soft_key_template_default); res++) { 07450 soft_key_template_default[res].softKeyEvent = htolel(soft_key_template_default[res].softKeyEvent); 07451 } 07452 /* load and parse config */ 07453 res = config_load(); 07454 if (res == -1) { 07455 return AST_MODULE_LOAD_DECLINE; 07456 } 07457 07458 /* Make sure we can register our skinny channel type */ 07459 if (ast_channel_register(&skinny_tech)) { 07460 ast_log(LOG_ERROR, "Unable to register channel class 'Skinny'\n"); 07461 return -1; 07462 } 07463 07464 ast_rtp_glue_register(&skinny_rtp_glue); 07465 ast_cli_register_multiple(cli_skinny, ARRAY_LEN(cli_skinny)); 07466 07467 ast_manager_register_xml("SKINNYdevices", EVENT_FLAG_SYSTEM | EVENT_FLAG_REPORTING, manager_skinny_show_devices); 07468 ast_manager_register_xml("SKINNYshowdevice", EVENT_FLAG_SYSTEM | EVENT_FLAG_REPORTING, manager_skinny_show_device); 07469 ast_manager_register_xml("SKINNYlines", EVENT_FLAG_SYSTEM | EVENT_FLAG_REPORTING, manager_skinny_show_lines); 07470 ast_manager_register_xml("SKINNYshowline", EVENT_FLAG_SYSTEM | EVENT_FLAG_REPORTING, manager_skinny_show_line); 07471 07472 sched = sched_context_create(); 07473 if (!sched) { 07474 ast_log(LOG_WARNING, "Unable to create schedule context\n"); 07475 } 07476 io = io_context_create(); 07477 if (!io) { 07478 ast_log(LOG_WARNING, "Unable to create I/O context\n"); 07479 } 07480 /* And start the monitor for the first time */ 07481 restart_monitor(); 07482 07483 return AST_MODULE_LOAD_SUCCESS; 07484 }
static int manager_skinny_show_device | ( | struct mansession * | s, | |
const struct message * | m | |||
) | [static] |
Definition at line 3348 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().
03349 { 03350 const char *a[4]; 03351 const char *device; 03352 03353 device = astman_get_header(m, "Device"); 03354 if (ast_strlen_zero(device)) { 03355 astman_send_error(s, m, "Device: <name> missing."); 03356 return 0; 03357 } 03358 a[0] = "skinny"; 03359 a[1] = "show"; 03360 a[2] = "device"; 03361 a[3] = device; 03362 03363 _skinny_show_device(1, -1, s, m, 4, a); 03364 astman_append(s, "\r\n\r\n" ); 03365 return 0; 03366 }
static int manager_skinny_show_devices | ( | struct mansession * | s, | |
const struct message * | m | |||
) | [static] |
Show SKINNY devices in the manager API.
Definition at line 3212 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().
03213 { 03214 const char *id = astman_get_header(m, "ActionID"); 03215 const char *a[] = {"skinny", "show", "devices"}; 03216 char idtext[256] = ""; 03217 int total = 0; 03218 03219 if (!ast_strlen_zero(id)) 03220 snprintf(idtext, sizeof(idtext), "ActionID: %s\r\n", id); 03221 03222 astman_send_listack(s, m, "Device status list will follow", "start"); 03223 /* List the devices in separate manager events */ 03224 _skinny_show_devices(-1, &total, s, m, 3, a); 03225 /* Send final confirmation */ 03226 astman_append(s, 03227 "Event: DevicelistComplete\r\n" 03228 "EventList: Complete\r\n" 03229 "ListItems: %d\r\n" 03230 "%s" 03231 "\r\n", total, idtext); 03232 return 0; 03233 }
static int manager_skinny_show_line | ( | struct mansession * | s, | |
const struct message * | m | |||
) | [static] |
Definition at line 3645 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().
03646 { 03647 const char *a[4]; 03648 const char *line; 03649 03650 line = astman_get_header(m, "Line"); 03651 if (ast_strlen_zero(line)) { 03652 astman_send_error(s, m, "Line: <name> missing."); 03653 return 0; 03654 } 03655 a[0] = "skinny"; 03656 a[1] = "show"; 03657 a[2] = "line"; 03658 a[3] = line; 03659 03660 _skinny_show_line(1, -1, s, m, 4, a); 03661 astman_append(s, "\r\n\r\n" ); 03662 return 0; 03663 }
static int manager_skinny_show_lines | ( | struct mansession * | s, | |
const struct message * | m | |||
) | [static] |
Show Skinny lines in the manager API.
Definition at line 3460 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().
03461 { 03462 const char *id = astman_get_header(m, "ActionID"); 03463 const char *a[] = {"skinny", "show", "lines"}; 03464 char idtext[256] = ""; 03465 int total = 0; 03466 03467 if (!ast_strlen_zero(id)) 03468 snprintf(idtext, sizeof(idtext), "ActionID: %s\r\n", id); 03469 03470 astman_send_listack(s, m, "Line status list will follow", "start"); 03471 /* List the lines in separate manager events */ 03472 _skinny_show_lines(-1, &total, s, m, 3, a); 03473 /* Send final confirmation */ 03474 astman_append(s, 03475 "Event: LinelistComplete\r\n" 03476 "EventList: Complete\r\n" 03477 "ListItems: %d\r\n" 03478 "%s" 03479 "\r\n", total, idtext); 03480 return 0; 03481 }
static void mwi_event_cb | ( | const struct ast_event * | event, | |
void * | userdata | |||
) | [static] |
Definition at line 2731 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_subchannel::list, skinny_line::newmsgs, skinny_device::session, SKINNY_LAMP_BLINK, SKINNY_LAMP_OFF, SKINNY_LAMP_ON, STIMULUS_VOICEMAIL, and transmit_lamp_indication().
02732 { 02733 struct skinny_line *l = userdata; 02734 struct skinny_device *d = l->device; 02735 if (d) { 02736 struct skinnysession *s = d->session; 02737 struct skinny_line *l2; 02738 int new_msgs = 0; 02739 int dev_msgs = 0; 02740 02741 if (s) { 02742 if (event) { 02743 l->newmsgs = ast_event_get_ie_uint(event, AST_EVENT_IE_NEWMSGS); 02744 } 02745 02746 if (l->newmsgs) { 02747 transmit_lamp_indication(d, STIMULUS_VOICEMAIL, l->instance, l->mwiblink?SKINNY_LAMP_BLINK:SKINNY_LAMP_ON); 02748 } else { 02749 transmit_lamp_indication(d, STIMULUS_VOICEMAIL, l->instance, SKINNY_LAMP_OFF); 02750 } 02751 02752 /* find out wether the device lamp should be on or off */ 02753 AST_LIST_TRAVERSE(&d->lines, l2, list) { 02754 if (l2->newmsgs) { 02755 dev_msgs++; 02756 } 02757 } 02758 02759 if (dev_msgs) { 02760 transmit_lamp_indication(d, STIMULUS_VOICEMAIL, 0, d->mwiblink?SKINNY_LAMP_BLINK:SKINNY_LAMP_ON); 02761 } else { 02762 transmit_lamp_indication(d, STIMULUS_VOICEMAIL, 0, SKINNY_LAMP_OFF); 02763 } 02764 ast_verb(3, "Skinny mwi_event_cb found %d new messages\n", new_msgs); 02765 } 02766 } 02767 }
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 3124 of file chan_skinny.c.
References ast_cli(), ast_codec_pref_index(), ast_getformatname(), and ast_codec_pref::framing.
03125 { 03126 int x, codec; 03127 03128 for(x = 0; x < 32 ; x++) { 03129 codec = ast_codec_pref_index(pref, x); 03130 if (!codec) 03131 break; 03132 ast_cli(fd, "%s", ast_getformatname(codec)); 03133 ast_cli(fd, ":%d", pref->framing[x]); 03134 if (x < 31 && ast_codec_pref_index(pref, x + 1)) 03135 ast_cli(fd, ","); 03136 } 03137 if (!x) 03138 ast_cli(fd, "none"); 03139 }
static void register_exten | ( | struct skinny_line * | l | ) | [static] |
Definition at line 1826 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, S_OR, and strsep().
Referenced by skinny_register().
01827 { 01828 char multi[256]; 01829 char *stringp, *ext, *context; 01830 01831 if (ast_strlen_zero(regcontext)) 01832 return; 01833 01834 ast_copy_string(multi, S_OR(l->regexten, l->name), sizeof(multi)); 01835 stringp = multi; 01836 while ((ext = strsep(&stringp, "&"))) { 01837 if ((context = strchr(ext, '@'))) { 01838 *context++ = '\0'; /* split ext@context */ 01839 if (!ast_context_find(context)) { 01840 ast_log(LOG_WARNING, "Context %s must exist in regcontext= in skinny.conf!\n", context); 01841 continue; 01842 } 01843 } else { 01844 context = regcontext; 01845 } 01846 ast_add_extension(context, 1, ext, 1, NULL, NULL, "Noop", 01847 ast_strdup(l->name), ast_free_ptr, "Skinny"); 01848 } 01849 }
static int reload | ( | void | ) | [static] |
Definition at line 7563 of file chan_skinny.c.
References skinny_reload().
07564 { 07565 skinny_reload(); 07566 return 0; 07567 }
static struct skinny_req* req_alloc | ( | size_t | size, | |
int | response_message | |||
) | [static] |
Definition at line 1557 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().
01558 { 01559 struct skinny_req *req; 01560 01561 if (!(req = ast_calloc(1, skinny_header_size + size + 4))) 01562 return NULL; 01563 01564 req->len = htolel(size+4); 01565 req->e = htolel(response_message); 01566 01567 return req; 01568 }
static int restart_monitor | ( | void | ) | [static] |
Definition at line 6591 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.
06592 { 06593 /* If we're supposed to be stopped -- stay stopped */ 06594 if (monitor_thread == AST_PTHREADT_STOP) 06595 return 0; 06596 06597 ast_mutex_lock(&monlock); 06598 if (monitor_thread == pthread_self()) { 06599 ast_mutex_unlock(&monlock); 06600 ast_log(LOG_WARNING, "Cannot kill myself\n"); 06601 return -1; 06602 } 06603 if (monitor_thread != AST_PTHREADT_NULL) { 06604 /* Wake up the thread */ 06605 pthread_kill(monitor_thread, SIGURG); 06606 } else { 06607 /* Start a new monitor */ 06608 if (ast_pthread_create_background(&monitor_thread, NULL, do_monitor, NULL) < 0) { 06609 ast_mutex_unlock(&monlock); 06610 ast_log(LOG_ERROR, "Unable to start monitor thread.\n"); 06611 return -1; 06612 } 06613 } 06614 ast_mutex_unlock(&monlock); 06615 return 0; 06616 }
static int set_callforwards | ( | struct skinny_line * | l, | |
const char * | cfwd, | |||
int | cfwdtype | |||
) | [static] |
Definition at line 1768 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().
01769 { 01770 if (!l) 01771 return 0; 01772 01773 if (!ast_strlen_zero(cfwd)) { 01774 if (cfwdtype & SKINNY_CFWD_ALL) { 01775 l->cfwdtype |= SKINNY_CFWD_ALL; 01776 ast_copy_string(l->call_forward_all, cfwd, sizeof(l->call_forward_all)); 01777 } 01778 if (cfwdtype & SKINNY_CFWD_BUSY) { 01779 l->cfwdtype |= SKINNY_CFWD_BUSY; 01780 ast_copy_string(l->call_forward_busy, cfwd, sizeof(l->call_forward_busy)); 01781 } 01782 if (cfwdtype & SKINNY_CFWD_NOANSWER) { 01783 l->cfwdtype |= SKINNY_CFWD_NOANSWER; 01784 ast_copy_string(l->call_forward_noanswer, cfwd, sizeof(l->call_forward_noanswer)); 01785 } 01786 } else { 01787 if (cfwdtype & SKINNY_CFWD_ALL) { 01788 l->cfwdtype &= ~SKINNY_CFWD_ALL; 01789 memset(l->call_forward_all, 0, sizeof(l->call_forward_all)); 01790 } 01791 if (cfwdtype & SKINNY_CFWD_BUSY) { 01792 l->cfwdtype &= ~SKINNY_CFWD_BUSY; 01793 memset(l->call_forward_busy, 0, sizeof(l->call_forward_busy)); 01794 } 01795 if (cfwdtype & SKINNY_CFWD_NOANSWER) { 01796 l->cfwdtype &= ~SKINNY_CFWD_NOANSWER; 01797 memset(l->call_forward_noanswer, 0, sizeof(l->call_forward_noanswer)); 01798 } 01799 } 01800 return l->cfwdtype; 01801 }
static int skinny_answer | ( | struct ast_channel * | ast | ) | [static] |
Definition at line 4066 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_number::str, ast_party_name::str, skinny_line::sub, ast_channel::tech_pvt, transmit_callinfo(), transmit_callstate(), transmit_dialednumber(), transmit_displaypromptstatus(), transmit_selectsoftkeys(), transmit_stop_tone(), ast_party_number::valid, and ast_party_name::valid.
04067 { 04068 int res = 0; 04069 struct skinny_subchannel *sub = ast->tech_pvt; 04070 struct skinny_line *l = sub->parent; 04071 struct skinny_device *d = l->device; 04072 04073 if (sub->blindxfer) { 04074 if (skinnydebug) 04075 ast_debug(1, "skinny_answer(%s) on %s@%s-%d with BlindXFER, transferring\n", 04076 ast->name, l->name, d->name, sub->callid); 04077 ast_setstate(ast, AST_STATE_UP); 04078 skinny_transfer(sub); 04079 return 0; 04080 } 04081 04082 sub->cxmode = SKINNY_CX_SENDRECV; 04083 if (!sub->rtp) { 04084 start_rtp(sub); 04085 } 04086 if (skinnydebug) 04087 ast_verb(1, "skinny_answer(%s) on %s@%s-%d\n", ast->name, l->name, d->name, sub->callid); 04088 if (ast->_state != AST_STATE_UP) { 04089 ast_setstate(ast, AST_STATE_UP); 04090 } 04091 04092 transmit_stop_tone(d, l->instance, sub->callid); 04093 /* order matters here... 04094 for some reason, transmit_callinfo must be before transmit_callstate, 04095 or you won't get keypad messages in some situations. */ 04096 transmit_callinfo(d, 04097 S_COR(ast->connected.id.name.valid, ast->connected.id.name.str, ""), 04098 S_COR(ast->connected.id.number.valid, ast->connected.id.number.str, ""), 04099 l->lastnumberdialed, l->lastnumberdialed, l->instance, sub->callid, 2); 04100 transmit_callstate(d, sub->parent->instance, sub->callid, SKINNY_CONNECTED); 04101 transmit_selectsoftkeys(d, l->instance, sub->callid, KEYDEF_CONNECTED); 04102 transmit_dialednumber(d, l->lastnumberdialed, l->instance, sub->callid); 04103 transmit_displaypromptstatus(d, "Connected", 0, l->instance, sub->callid); 04104 l->activesub = sub; 04105 return res; 04106 }
static int skinny_call | ( | struct ast_channel * | ast, | |
char * | dest, | |||
int | timeout | |||
) | [static] |
Definition at line 3913 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, skinny_subchannel::list, LOG_ERROR, LOG_WARNING, ast_party_id::name, ast_channel::name, ast_party_id::number, skinny_subchannel::outgoing, skinny_subchannel::parent, S_COR, SKINNY_ALERT, SKINNY_CALLWAITTONE, SKINNY_LAMP_BLINK, SKINNY_OFFHOOK, SKINNY_ONHOOK, SKINNY_RING_INSIDE, SKINNY_RINGIN, STIMULUS_LINE, ast_party_number::str, ast_party_name::str, skinny_line::sub, ast_channel::tech_pvt, transmit_callinfo(), transmit_callstate(), transmit_displaypromptstatus(), transmit_lamp_indication(), transmit_ringer_mode(), transmit_selectsoftkeys(), ast_party_number::valid, and ast_party_name::valid.
03914 { 03915 int res = 0; 03916 int tone = 0; 03917 struct skinny_subchannel *sub = ast->tech_pvt; 03918 struct skinny_line *l = sub->parent; 03919 struct skinny_device *d = l->device; 03920 03921 if (!d->registered) { 03922 ast_log(LOG_ERROR, "Device not registered, cannot call %s\n", dest); 03923 return -1; 03924 } 03925 03926 if ((ast->_state != AST_STATE_DOWN) && (ast->_state != AST_STATE_RESERVED)) { 03927 ast_log(LOG_WARNING, "skinny_call called on %s, neither down nor reserved\n", ast->name); 03928 return -1; 03929 } 03930 03931 if (skinnydebug) 03932 ast_verb(3, "skinny_call(%s)\n", ast->name); 03933 03934 if (l->dnd) { 03935 ast_queue_control(ast, AST_CONTROL_BUSY); 03936 return -1; 03937 } 03938 03939 if (AST_LIST_NEXT(sub,list) && !l->callwaiting) { 03940 ast_queue_control(ast, AST_CONTROL_BUSY); 03941 return -1; 03942 } 03943 03944 switch (l->hookstate) { 03945 case SKINNY_OFFHOOK: 03946 tone = SKINNY_CALLWAITTONE; 03947 break; 03948 case SKINNY_ONHOOK: 03949 tone = SKINNY_ALERT; 03950 l->activesub = sub; 03951 break; 03952 default: 03953 ast_log(LOG_ERROR, "Don't know how to deal with hookstate %d\n", l->hookstate); 03954 break; 03955 } 03956 03957 transmit_callstate(d, sub->parent->instance, sub->callid, SKINNY_RINGIN); 03958 transmit_selectsoftkeys(d, l->instance, sub->callid, KEYDEF_RINGIN); 03959 transmit_displaypromptstatus(d, "Ring-In", 0, l->instance, sub->callid); 03960 transmit_callinfo(d, 03961 S_COR(ast->connected.id.name.valid, ast->connected.id.name.str, ""), 03962 S_COR(ast->connected.id.number.valid, ast->connected.id.number.str, ""), 03963 l->cid_name, l->cid_num, l->instance, sub->callid, 1); 03964 transmit_lamp_indication(d, STIMULUS_LINE, l->instance, SKINNY_LAMP_BLINK); 03965 transmit_ringer_mode(d, SKINNY_RING_INSIDE); 03966 03967 ast_setstate(ast, AST_STATE_RINGING); 03968 ast_queue_control(ast, AST_CONTROL_RINGING); 03969 sub->outgoing = 1; 03970 return res; 03971 }
static int skinny_devicestate | ( | void * | data | ) | [static] |
Definition at line 6618 of file chan_skinny.c.
References ast_strdupa, find_line_by_name(), and get_devicestate().
06619 { 06620 struct skinny_line *l; 06621 char *tmp; 06622 06623 tmp = ast_strdupa(data); 06624 06625 l = find_line_by_name(tmp); 06626 06627 return get_devicestate(l); 06628 }
static int skinny_extensionstate_cb | ( | char * | context, | |
char * | exten, | |||
int | state, | |||
void * | data | |||
) | [static] |
Definition at line 2631 of file chan_skinny.c.
References ast_device_state(), AST_DEVICE_UNAVAILABLE, AST_EXTENSION_BUSY, AST_EXTENSION_DEACTIVATED, AST_EXTENSION_INUSE, AST_EXTENSION_NOT_INUSE, AST_EXTENSION_ONHOLD, AST_EXTENSION_REMOVED, AST_EXTENSION_RINGING, AST_EXTENSION_UNAVAILABLE, ast_get_hint(), AST_MAX_EXTENSION, ast_verb, skinny_speeddial::context, skinny_speeddial::exten, skinny_speeddial::instance, skinny_speeddial::laststate, skinny_speeddial::parent, SKINNY_CALLREMOTEMULTILINE, SKINNY_HOLD, SKINNY_LAMP_BLINK, SKINNY_LAMP_FLASH, SKINNY_LAMP_OFF, SKINNY_LAMP_ON, SKINNY_LAMP_WINK, SKINNY_ONHOOK, SKINNY_RINGIN, skinny_speeddial::stateid, STIMULUS_LINE, transmit_callstate(), and transmit_lamp_indication().
Referenced by skinny_register().
02632 { 02633 struct skinny_speeddial *sd = data; 02634 struct skinny_device *d = sd->parent; 02635 char hint[AST_MAX_EXTENSION]; 02636 02637 if (ast_get_hint(hint, sizeof(hint), NULL, 0, NULL, sd->context, sd->exten)) { 02638 /* If they are not registered, we will override notification and show no availability */ 02639 if (ast_device_state(hint) == AST_DEVICE_UNAVAILABLE) { 02640 transmit_lamp_indication(d, STIMULUS_LINE, sd->instance, SKINNY_LAMP_FLASH); 02641 transmit_callstate(d, sd->instance, SKINNY_ONHOOK, 0); 02642 } 02643 } else { 02644 switch (state) { 02645 case AST_EXTENSION_DEACTIVATED: /* Retry after a while */ 02646 case AST_EXTENSION_REMOVED: /* Extension is gone */ 02647 ast_verb(2, "Extension state: Watcher for hint %s %s. Notify Device %s\n", exten, state == AST_EXTENSION_DEACTIVATED ? "deactivated" : "removed", d->name); 02648 sd->stateid = -1; 02649 transmit_lamp_indication(d, STIMULUS_LINE, sd->instance, SKINNY_LAMP_OFF); 02650 transmit_callstate(d, sd->instance, SKINNY_ONHOOK, 0); 02651 break; 02652 case AST_EXTENSION_RINGING: 02653 case AST_EXTENSION_UNAVAILABLE: 02654 transmit_lamp_indication(d, STIMULUS_LINE, sd->instance, SKINNY_LAMP_BLINK); 02655 transmit_callstate(d, sd->instance, SKINNY_RINGIN, 0); 02656 break; 02657 case AST_EXTENSION_BUSY: /* callstate = SKINNY_BUSY wasn't wanting to work - I'll settle for this */ 02658 case AST_EXTENSION_INUSE: 02659 transmit_lamp_indication(d, STIMULUS_LINE, sd->instance, SKINNY_LAMP_ON); 02660 transmit_callstate(d, sd->instance, SKINNY_CALLREMOTEMULTILINE, 0); 02661 break; 02662 case AST_EXTENSION_ONHOLD: 02663 transmit_lamp_indication(d, STIMULUS_LINE, sd->instance, SKINNY_LAMP_WINK); 02664 transmit_callstate(d, sd->instance, SKINNY_HOLD, 0); 02665 break; 02666 case AST_EXTENSION_NOT_INUSE: 02667 default: 02668 transmit_lamp_indication(d, STIMULUS_LINE, sd->instance, SKINNY_LAMP_OFF); 02669 transmit_callstate(d, sd->instance, SKINNY_ONHOOK, 0); 02670 break; 02671 } 02672 } 02673 02674 sd->laststate = state; 02675 02676 return 0; 02677 }
static int skinny_fixup | ( | struct ast_channel * | oldchan, | |
struct ast_channel * | newchan | |||
) | [static] |
Definition at line 4198 of file chan_skinny.c.
References ast_log(), LOG_NOTICE, LOG_WARNING, ast_channel::name, skinny_subchannel::owner, and ast_channel::tech_pvt.
04199 { 04200 struct skinny_subchannel *sub = newchan->tech_pvt; 04201 ast_log(LOG_NOTICE, "skinny_fixup(%s, %s)\n", oldchan->name, newchan->name); 04202 if (sub->owner != oldchan) { 04203 ast_log(LOG_WARNING, "old channel wasn't %p but was %p\n", oldchan, sub->owner); 04204 return -1; 04205 } 04206 sub->owner = newchan; 04207 return 0; 04208 }
static enum ast_rtp_glue_result skinny_get_rtp_peer | ( | struct ast_channel * | c, | |
struct ast_rtp_instance ** | instance | |||
) | [static] |
Definition at line 2785 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, ast_channel::name, skinny_line::sub, and ast_channel::tech_pvt.
02786 { 02787 struct skinny_subchannel *sub = NULL; 02788 struct skinny_line *l; 02789 enum ast_rtp_glue_result res = AST_RTP_GLUE_RESULT_REMOTE; 02790 02791 if (skinnydebug) 02792 ast_verb(1, "skinny_get_rtp_peer() Channel = %s\n", c->name); 02793 02794 02795 if (!(sub = c->tech_pvt)) 02796 return AST_RTP_GLUE_RESULT_FORBID; 02797 02798 ast_mutex_lock(&sub->lock); 02799 02800 if (!(sub->rtp)){ 02801 ast_mutex_unlock(&sub->lock); 02802 return AST_RTP_GLUE_RESULT_FORBID; 02803 } 02804 02805 ao2_ref(sub->rtp, +1); 02806 *instance = sub->rtp; 02807 02808 l = sub->parent; 02809 02810 if (!l->directmedia || l->nat){ 02811 res = AST_RTP_GLUE_RESULT_LOCAL; 02812 if (skinnydebug) 02813 ast_verb(1, "skinny_get_rtp_peer() Using AST_RTP_GLUE_RESULT_LOCAL \n"); 02814 } 02815 02816 ast_mutex_unlock(&sub->lock); 02817 02818 return res; 02819 02820 }
static enum ast_rtp_glue_result skinny_get_vrtp_peer | ( | struct ast_channel * | c, | |
struct ast_rtp_instance ** | instance | |||
) | [static] |
Definition at line 2772 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.
02773 { 02774 struct skinny_subchannel *sub = NULL; 02775 02776 if (!(sub = c->tech_pvt) || !(sub->vrtp)) 02777 return AST_RTP_GLUE_RESULT_FORBID; 02778 02779 ao2_ref(sub->vrtp, +1); 02780 *instance = sub->vrtp; 02781 02782 return AST_RTP_GLUE_RESULT_REMOTE; 02783 }
static int skinny_hangup | ( | struct ast_channel * | ast | ) | [static] |
Definition at line 3973 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::list, skinny_subchannel::lock, skinny_subchannel::outgoing, skinny_subchannel::owner, skinny_subchannel::parent, skinny_subchannel::related, skinny_subchannel::rtp, skinny_device::session, 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().
03974 { 03975 struct skinny_subchannel *sub = ast->tech_pvt; 03976 struct skinny_line *l; 03977 struct skinny_device *d; 03978 struct skinnysession *s; 03979 03980 if (!sub) { 03981 ast_debug(1, "Asked to hangup channel not connected\n"); 03982 return 0; 03983 } 03984 03985 l = sub->parent; 03986 d = l->device; 03987 s = d->session; 03988 03989 if (skinnydebug) 03990 ast_verb(3,"Hanging up %s/%d\n",d->name,sub->callid); 03991 03992 AST_LIST_REMOVE(&l->sub, sub, list); 03993 03994 if (d->registered) { 03995 /* Ignoring l->type, doesn't seem relevant and previous code 03996 assigned rather than tested, ie always true */ 03997 if (!AST_LIST_EMPTY(&l->sub)) { 03998 if (sub->related) { 03999 sub->related->related = NULL; 04000 04001 } 04002 if (sub == l->activesub) { /* we are killing the active sub, but there are other subs on the line*/ 04003 ast_verb(4,"Killing active sub %d\n", sub->callid); 04004 if (sub->related) { 04005 l->activesub = sub->related; 04006 } else { 04007 if (AST_LIST_NEXT(sub, list)) { 04008 l->activesub = AST_LIST_NEXT(sub, list); 04009 } else { 04010 l->activesub = AST_LIST_FIRST(&l->sub); 04011 } 04012 } 04013 //transmit_callstate(d, l->instance, SKINNY_ONHOOK, sub->callid); 04014 transmit_activatecallplane(d, l); 04015 transmit_closereceivechannel(d, sub); 04016 transmit_stopmediatransmission(d, sub); 04017 transmit_lamp_indication(d, STIMULUS_LINE, l->instance, SKINNY_LAMP_BLINK); 04018 transmit_stop_tone(d, l->instance, sub->callid); 04019 } else { /* we are killing a background sub on the line with other subs*/ 04020 ast_verb(4,"Killing inactive sub %d\n", sub->callid); 04021 if (AST_LIST_NEXT(sub, list)) { 04022 transmit_lamp_indication(d, STIMULUS_LINE, l->instance, SKINNY_LAMP_BLINK); 04023 } else { 04024 transmit_lamp_indication(d, STIMULUS_LINE, l->instance, SKINNY_LAMP_ON); 04025 } 04026 } 04027 } else { /* no more subs on line so make idle */ 04028 ast_verb(4,"Killing only sub %d\n", sub->callid); 04029 l->hookstate = SKINNY_ONHOOK; 04030 transmit_closereceivechannel(d, sub); 04031 transmit_stopmediatransmission(d, sub); 04032 transmit_speaker_mode(d, SKINNY_SPEAKEROFF); 04033 transmit_clearpromptmessage(d, l->instance, sub->callid); 04034 transmit_callstate(d, l->instance, sub->callid, SKINNY_ONHOOK); 04035 transmit_selectsoftkeys(d, 0, 0, KEYDEF_ONHOOK); 04036 transmit_activatecallplane(d, l); 04037 l->activesub = NULL; 04038 transmit_lamp_indication(d, STIMULUS_LINE, l->instance, SKINNY_LAMP_OFF); 04039 if (sub->parent == d->activeline) { 04040 transmit_activatecallplane(d, l); 04041 transmit_closereceivechannel(d, sub); 04042 transmit_stopmediatransmission(d, sub); 04043 transmit_speaker_mode(d, SKINNY_SPEAKEROFF); 04044 transmit_ringer_mode(d, SKINNY_RING_OFF); 04045 transmit_clear_display_message(d, l->instance, sub->callid); 04046 transmit_stop_tone(d, l->instance, sub->callid); 04047 /* we should check to see if we can start the ringer if another line is ringing */ 04048 } 04049 } 04050 } 04051 ast_mutex_lock(&sub->lock); 04052 sub->owner = NULL; 04053 ast->tech_pvt = NULL; 04054 sub->alreadygone = 0; 04055 sub->outgoing = 0; 04056 if (sub->rtp) { 04057 ast_rtp_instance_destroy(sub->rtp); 04058 sub->rtp = NULL; 04059 } 04060 ast_mutex_unlock(&sub->lock); 04061 ast_free(sub); 04062 ast_module_unref(ast_module_info->self); 04063 return 0; 04064 }
static int skinny_hold | ( | struct skinny_subchannel * | sub | ) | [static] |
Definition at line 4610 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, skinny_line::sub, 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().
04611 { 04612 struct skinny_line *l = sub->parent; 04613 struct skinny_device *d = l->device; 04614 04615 /* Don't try to hold a channel that doesn't exist */ 04616 if (!sub || !sub->owner) 04617 return 0; 04618 04619 /* Channel needs to be put on hold */ 04620 if (skinnydebug) 04621 ast_verb(1, "Putting on Hold(%d)\n", l->instance); 04622 04623 ast_queue_control_data(sub->owner, AST_CONTROL_HOLD, 04624 S_OR(l->mohsuggest, NULL), 04625 !ast_strlen_zero(l->mohsuggest) ? strlen(l->mohsuggest) + 1 : 0); 04626 04627 transmit_activatecallplane(d, l); 04628 transmit_closereceivechannel(d, sub); 04629 transmit_stopmediatransmission(d, sub); 04630 04631 transmit_callstate(d, sub->parent->instance, sub->callid, SKINNY_HOLD); 04632 transmit_lamp_indication(d, STIMULUS_LINE, l->instance, SKINNY_LAMP_WINK); 04633 sub->onhold = 1; 04634 return 1; 04635 }
static int skinny_indicate | ( | struct ast_channel * | ast, | |
int | ind, | |||
const void * | data, | |||
size_t | datalen | |||
) | [static] |
Definition at line 4379 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_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_connected_line::id, ast_party_caller::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_number::str, ast_party_name::str, skinny_line::sub, ast_channel::tech_pvt, transmit_callinfo(), transmit_callstate(), transmit_dialednumber(), transmit_displaypromptstatus(), transmit_start_tone(), transmit_stop_tone(), update_connectedline(), ast_party_number::valid, and ast_party_name::valid.
04380 { 04381 struct skinny_subchannel *sub = ast->tech_pvt; 04382 struct skinny_line *l = sub->parent; 04383 struct skinny_device *d = l->device; 04384 struct skinnysession *s = d->session; 04385 04386 if (!s) { 04387 ast_log(LOG_NOTICE, "Asked to indicate '%s' condition on channel %s, but session does not exist.\n", control2str(ind), ast->name); 04388 return -1; 04389 } 04390 04391 if (skinnydebug) 04392 ast_verb(3, "Asked to indicate '%s' condition on channel %s\n", control2str(ind), ast->name); 04393 switch(ind) { 04394 case AST_CONTROL_RINGING: 04395 if (sub->blindxfer) { 04396 if (skinnydebug) 04397 ast_debug(1, "Channel %s set up for Blind Xfer, so Xfer rather than ring device\n", ast->name); 04398 skinny_transfer(sub); 04399 break; 04400 } 04401 if (ast->_state != AST_STATE_UP) { 04402 if (!sub->progress) { 04403 if (!d->earlyrtp) { 04404 transmit_start_tone(d, SKINNY_ALERT, l->instance, sub->callid); 04405 } 04406 transmit_callstate(d, sub->parent->instance, sub->callid, SKINNY_RINGOUT); 04407 transmit_dialednumber(d, l->lastnumberdialed, l->instance, sub->callid); 04408 transmit_displaypromptstatus(d, "Ring Out", 0, l->instance, sub->callid); 04409 transmit_callinfo(d, 04410 S_COR(ast->caller.id.name.valid, ast->caller.id.name.str, ""), 04411 S_COR(ast->caller.id.number.valid, ast->caller.id.number.str, ""), 04412 S_COR(ast->connected.id.name.valid, ast->connected.id.name.str, l->lastnumberdialed), 04413 S_COR(ast->connected.id.number.valid, ast->connected.id.number.str, l->lastnumberdialed), 04414 l->instance, sub->callid, 2); /* 2 = outgoing from phone */ 04415 sub->ringing = 1; 04416 if (!d->earlyrtp) { 04417 break; 04418 } 04419 } 04420 } 04421 return -1; /* Tell asterisk to provide inband signalling */ 04422 case AST_CONTROL_BUSY: 04423 if (ast->_state != AST_STATE_UP) { 04424 if (!d->earlyrtp) { 04425 transmit_start_tone(d, SKINNY_BUSYTONE, l->instance, sub->callid); 04426 } 04427 transmit_callstate(d, sub->parent->instance, sub->callid, SKINNY_BUSY); 04428 sub->alreadygone = 1; 04429 ast_softhangup_nolock(ast, AST_SOFTHANGUP_DEV); 04430 if (!d->earlyrtp) { 04431 break; 04432 } 04433 } 04434 return -1; /* Tell asterisk to provide inband signalling */ 04435 case AST_CONTROL_CONGESTION: 04436 if (ast->_state != AST_STATE_UP) { 04437 if (!d->earlyrtp) { 04438 transmit_start_tone(d, SKINNY_REORDER, l->instance, sub->callid); 04439 } 04440 transmit_callstate(d, sub->parent->instance, sub->callid, SKINNY_CONGESTION); 04441 sub->alreadygone = 1; 04442 ast_softhangup_nolock(ast, AST_SOFTHANGUP_DEV); 04443 if (!d->earlyrtp) { 04444 break; 04445 } 04446 } 04447 return -1; /* Tell asterisk to provide inband signalling */ 04448 case AST_CONTROL_PROGRESS: 04449 if ((ast->_state != AST_STATE_UP) && !sub->progress && !sub->outgoing) { 04450 if (!d->earlyrtp) { 04451 transmit_start_tone(d, SKINNY_ALERT, l->instance, sub->callid); 04452 } 04453 transmit_callstate(d, sub->parent->instance, sub->callid, SKINNY_PROGRESS); 04454 transmit_displaypromptstatus(d, "Call Progress", 0, l->instance, sub->callid); 04455 transmit_callinfo(d, 04456 S_COR(ast->caller.id.name.valid, ast->caller.id.name.str, ""), 04457 S_COR(ast->caller.id.number.valid, ast->caller.id.number.str, ""), 04458 S_COR(ast->connected.id.name.valid, ast->connected.id.name.str, l->lastnumberdialed), 04459 S_COR(ast->connected.id.number.valid, ast->connected.id.number.str, l->lastnumberdialed), 04460 l->instance, sub->callid, 2); /* 2 = outgoing from phone */ 04461 sub->progress = 1; 04462 if (!d->earlyrtp) { 04463 break; 04464 } 04465 } 04466 return -1; /* Tell asterisk to provide inband signalling */ 04467 case -1: /* STOP_TONE */ 04468 transmit_stop_tone(d, l->instance, sub->callid); 04469 break; 04470 case AST_CONTROL_HOLD: 04471 ast_moh_start(ast, data, l->mohinterpret); 04472 break; 04473 case AST_CONTROL_UNHOLD: 04474 ast_moh_stop(ast); 04475 break; 04476 case AST_CONTROL_PROCEEDING: 04477 break; 04478 case AST_CONTROL_SRCUPDATE: 04479 ast_rtp_instance_update_source(sub->rtp); 04480 break; 04481 case AST_CONTROL_SRCCHANGE: 04482 ast_rtp_instance_change_source(sub->rtp); 04483 break; 04484 case AST_CONTROL_CONNECTED_LINE: 04485 update_connectedline(sub, data, datalen); 04486 break; 04487 default: 04488 ast_log(LOG_WARNING, "Don't know how to indicate condition %d\n", ind); 04489 return -1; /* Tell asterisk to provide inband signalling */ 04490 } 04491 return 0; 04492 }
static struct ast_channel* skinny_new | ( | struct skinny_line * | l, | |
int | state, | |||
const char * | linkedid | |||
) | [static] |
Definition at line 4494 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, ast_channel::caller, ast_channel::callgroup, skinny_line::chanvars, ast_channel::context, skinny_line::device, ast_channel::exten, get_devicestate(), global_jbconf, language, skinny_subchannel::list, LOG_WARNING, ast_variable::name, ast_channel::nativeformats, ast_variable::next, ast_party_id::number, parkinglot, pbx_builtin_setvar_helper(), ast_channel::pickupgroup, ast_channel::priority, ast_channel::rawreadformat, ast_channel::rawwriteformat, ast_channel::readformat, ast_channel::rings, SKINNY_CFWD_ALL, SKINNY_CFWD_BUSY, SKINNY_CX_INACTIVE, skinny_tech, ast_party_number::str, skinny_line::sub, ast_channel::tech, ast_channel::tech_pvt, ast_party_number::valid, ast_variable::value, and ast_channel::writeformat.
Referenced by handle_enbloc_call_message(), handle_offhook_message(), handle_soft_key_event_message(), handle_stimulus_message(), handle_transfer_button(), and skinny_request().
04495 { 04496 struct ast_channel *tmp; 04497 struct skinny_subchannel *sub; 04498 struct skinny_device *d = l->device; 04499 struct ast_variable *v = NULL; 04500 int fmt; 04501 04502 if (!l->device) { 04503 ast_log(LOG_WARNING, "Device for line %s is not registered.\n", l->name); 04504 return NULL; 04505 } 04506 04507 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); 04508 if (!tmp) { 04509 ast_log(LOG_WARNING, "Unable to allocate channel structure\n"); 04510 return NULL; 04511 } else { 04512 sub = ast_calloc(1, sizeof(*sub)); 04513 if (!sub) { 04514 ast_log(LOG_WARNING, "Unable to allocate Skinny subchannel\n"); 04515 return NULL; 04516 } else { 04517 ast_mutex_init(&sub->lock); 04518 04519 sub->owner = tmp; 04520 sub->callid = callnums++; 04521 d->lastlineinstance = l->instance; 04522 d->lastcallreference = sub->callid; 04523 sub->cxmode = SKINNY_CX_INACTIVE; 04524 sub->nat = l->nat; 04525 sub->parent = l; 04526 sub->onhold = 0; 04527 sub->blindxfer = 0; 04528 sub->xferor = 0; 04529 sub->related = NULL; 04530 04531 AST_LIST_INSERT_HEAD(&l->sub, sub, list); 04532 //l->activesub = sub; 04533 } 04534 tmp->tech = &skinny_tech; 04535 tmp->tech_pvt = sub; 04536 tmp->nativeformats = l->capability; 04537 if (!tmp->nativeformats) 04538 // Should throw an error 04539 tmp->nativeformats = default_capability; 04540 fmt = ast_best_codec(tmp->nativeformats); 04541 if (skinnydebug) { 04542 char buf[256]; 04543 ast_verb(1, "skinny_new: tmp->nativeformats=%s fmt=%s\n", 04544 ast_getformatname_multiple(buf, sizeof(buf), tmp->nativeformats), 04545 ast_getformatname(fmt)); 04546 } 04547 if (sub->rtp) { 04548 ast_channel_set_fd(tmp, 0, ast_rtp_instance_fd(sub->rtp, 0)); 04549 } 04550 if (state == AST_STATE_RING) { 04551 tmp->rings = 1; 04552 } 04553 tmp->writeformat = fmt; 04554 tmp->rawwriteformat = fmt; 04555 tmp->readformat = fmt; 04556 tmp->rawreadformat = fmt; 04557 if (!ast_strlen_zero(l->language)) 04558 ast_string_field_set(tmp, language, l->language); 04559 if (!ast_strlen_zero(l->accountcode)) 04560 ast_string_field_set(tmp, accountcode, l->accountcode); 04561 if (!ast_strlen_zero(l->parkinglot)) 04562 ast_string_field_set(tmp, parkinglot, l->parkinglot); 04563 if (l->amaflags) 04564 tmp->amaflags = l->amaflags; 04565 04566 ast_module_ref(ast_module_info->self); 04567 tmp->callgroup = l->callgroup; 04568 tmp->pickupgroup = l->pickupgroup; 04569 04570 /* XXX Need to figure out how to handle CFwdNoAnswer */ 04571 if (l->cfwdtype & SKINNY_CFWD_ALL) { 04572 ast_string_field_set(tmp, call_forward, l->call_forward_all); 04573 } else if (l->cfwdtype & SKINNY_CFWD_BUSY) { 04574 if (get_devicestate(l) != AST_DEVICE_NOT_INUSE) { 04575 ast_string_field_set(tmp, call_forward, l->call_forward_busy); 04576 } 04577 } 04578 04579 ast_copy_string(tmp->context, l->context, sizeof(tmp->context)); 04580 ast_copy_string(tmp->exten, l->exten, sizeof(tmp->exten)); 04581 04582 /* Don't use ast_set_callerid() here because it will 04583 * generate a needless NewCallerID event */ 04584 if (!ast_strlen_zero(l->cid_num)) { 04585 tmp->caller.ani.number.valid = 1; 04586 tmp->caller.ani.number.str = ast_strdup(l->cid_num); 04587 } 04588 04589 tmp->priority = 1; 04590 tmp->adsicpe = AST_ADSI_UNAVAILABLE; 04591 04592 if (sub->rtp) 04593 ast_jb_configure(tmp, &global_jbconf); 04594 04595 /* Set channel variables for this call from configuration */ 04596 for (v = l->chanvars ; v ; v = v->next) 04597 pbx_builtin_setvar_helper(tmp, v->name, v->value); 04598 04599 if (state != AST_STATE_DOWN) { 04600 if (ast_pbx_start(tmp)) { 04601 ast_log(LOG_WARNING, "Unable to start PBX on %s\n", tmp->name); 04602 ast_hangup(tmp); 04603 tmp = NULL; 04604 } 04605 } 04606 } 04607 return tmp; 04608 }
static void* skinny_newcall | ( | void * | data | ) | [static] |
Definition at line 3773 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, skinny_line::device, ast_channel::exten, ast_party_connected_line::id, LOG_WARNING, ast_party_id::name, ast_party_id::number, skinny_subchannel::rtp, SKINNY_REORDER, start_rtp(), ast_party_number::str, skinny_line::sub, 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().
03774 { 03775 struct ast_channel *c = data; 03776 struct skinny_subchannel *sub = c->tech_pvt; 03777 struct skinny_line *l = sub->parent; 03778 struct skinny_device *d = l->device; 03779 int res = 0; 03780 03781 ast_copy_string(l->lastnumberdialed, c->exten, sizeof(l->lastnumberdialed)); 03782 ast_set_callerid(c, 03783 l->hidecallerid ? "" : l->cid_num, 03784 l->hidecallerid ? "" : l->cid_name, 03785 c->caller.ani.number.valid ? NULL : l->cid_num); 03786 #if 1 /* XXX This code is probably not necessary */ 03787 ast_party_number_free(&c->connected.id.number); 03788 ast_party_number_init(&c->connected.id.number); 03789 c->connected.id.number.valid = 1; 03790 c->connected.id.number.str = ast_strdup(c->exten); 03791 ast_party_name_free(&c->connected.id.name); 03792 ast_party_name_init(&c->connected.id.name); 03793 #endif 03794 ast_setstate(c, AST_STATE_RING); 03795 if (!sub->rtp) { 03796 start_rtp(sub); 03797 } 03798 res = ast_pbx_run(c); 03799 if (res) { 03800 ast_log(LOG_WARNING, "PBX exited non-zero\n"); 03801 transmit_start_tone(d, SKINNY_REORDER, l->instance, sub->callid); 03802 } 03803 return NULL; 03804 }
static struct ast_frame * skinny_read | ( | struct ast_channel * | ast | ) | [static] |
Definition at line 4156 of file chan_skinny.c.
References ast_mutex_lock, ast_mutex_unlock, skinny_subchannel::lock, skinny_rtp_read(), and ast_channel::tech_pvt.
04157 { 04158 struct ast_frame *fr; 04159 struct skinny_subchannel *sub = ast->tech_pvt; 04160 ast_mutex_lock(&sub->lock); 04161 fr = skinny_rtp_read(sub); 04162 ast_mutex_unlock(&sub->lock); 04163 return fr; 04164 }
static int skinny_register | ( | struct skinny_req * | req, | |
struct skinnysession * | s | |||
) | [static] |
Definition at line 1875 of file chan_skinny.c.
References 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, skinny_subchannel::list, 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().
01876 { 01877 struct skinny_device *d; 01878 struct skinny_line *l; 01879 struct skinny_speeddial *sd; 01880 struct sockaddr_in sin; 01881 socklen_t slen; 01882 int instance; 01883 01884 AST_LIST_LOCK(&devices); 01885 AST_LIST_TRAVERSE(&devices, d, list){ 01886 struct ast_sockaddr addr; 01887 ast_sockaddr_from_sin(&addr, &s->sin); 01888 if (!strcasecmp(req->data.reg.name, d->id) 01889 && ast_apply_ha(d->ha, &addr)) { 01890 s->device = d; 01891 d->type = letohl(req->data.reg.type); 01892 if (ast_strlen_zero(d->version_id)) { 01893 ast_copy_string(d->version_id, version_id, sizeof(d->version_id)); 01894 } 01895 d->registered = 1; 01896 d->session = s; 01897 01898 slen = sizeof(sin); 01899 if (getsockname(s->fd, (struct sockaddr *)&sin, &slen)) { 01900 ast_log(LOG_WARNING, "Cannot get socket name\n"); 01901 sin.sin_addr = __ourip; 01902 } 01903 d->ourip = sin.sin_addr; 01904 01905 AST_LIST_TRAVERSE(&d->speeddials, sd, list) { 01906 sd->stateid = ast_extension_state_add(sd->context, sd->exten, skinny_extensionstate_cb, sd); 01907 } 01908 instance = 0; 01909 AST_LIST_TRAVERSE(&d->lines, l, list) { 01910 instance++; 01911 } 01912 AST_LIST_TRAVERSE(&d->lines, l, list) { 01913 /* FIXME: All sorts of issues will occur if this line is already connected to a device */ 01914 if (l->device) { 01915 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); 01916 ast_verb(1, "Line %s already connected to %s. Not connecting to %s.\n", l->name, l->device->name, d->name); 01917 } else { 01918 l->device = d; 01919 l->capability = l->confcapability & d->capability; 01920 l->prefs = l->confprefs; 01921 if (!l->prefs.order[0]) { 01922 l->prefs = d->confprefs; 01923 } 01924 /* l->capability = d->capability; 01925 l->prefs = d->prefs; */ 01926 l->instance = instance; 01927 l->newmsgs = ast_app_has_voicemail(l->mailbox, NULL); 01928 set_callforwards(l, NULL, 0); 01929 manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", "ChannelType: Skinny\r\nPeer: Skinny/%s@%s\r\nPeerStatus: Registered\r\n", l->name, d->name); 01930 register_exten(l); 01931 /* initialize MWI on line and device */ 01932 mwi_event_cb(0, l); 01933 ast_devstate_changed(AST_DEVICE_NOT_INUSE, "Skinny/%s@%s", l->name, d->name); 01934 } 01935 --instance; 01936 } 01937 break; 01938 } 01939 } 01940 AST_LIST_UNLOCK(&devices); 01941 if (!d) { 01942 return 0; 01943 } 01944 return 1; 01945 }
int skinny_reload | ( | void | ) | [static] |
Definition at line 7363 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, skinny_subchannel::list, 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().
07364 { 07365 struct skinny_device *d; 07366 struct skinny_line *l; 07367 struct skinny_speeddial *sd; 07368 struct skinny_addon *a; 07369 struct skinny_req *req; 07370 07371 if (skinnyreload) { 07372 ast_verb(3, "Chan_skinny is already reloading.\n"); 07373 return 0; 07374 } 07375 07376 skinnyreload = 1; 07377 07378 /* Mark all devices and lines as candidates to be pruned */ 07379 AST_LIST_LOCK(&devices); 07380 AST_LIST_TRAVERSE(&devices, d, list) { 07381 d->prune = 1; 07382 } 07383 AST_LIST_UNLOCK(&devices); 07384 07385 AST_LIST_LOCK(&lines); 07386 AST_LIST_TRAVERSE(&lines, l, all) { 07387 l->prune = 1; 07388 } 07389 AST_LIST_UNLOCK(&lines); 07390 07391 config_load(); 07392 07393 /* Remove any devices that no longer exist in the config */ 07394 AST_LIST_LOCK(&devices); 07395 AST_LIST_TRAVERSE_SAFE_BEGIN(&devices, d, list) { 07396 if (!d->prune) { 07397 continue; 07398 } 07399 ast_verb(3, "Removing device '%s'\n", d->name); 07400 /* Delete all lines for this device. 07401 We do not want to free the line here, that 07402 will happen below. */ 07403 while ((l = AST_LIST_REMOVE_HEAD(&d->lines, list))) { 07404 } 07405 /* Delete all speeddials for this device */ 07406 while ((sd = AST_LIST_REMOVE_HEAD(&d->speeddials, list))) { 07407 free(sd); 07408 } 07409 /* Delete all addons for this device */ 07410 while ((a = AST_LIST_REMOVE_HEAD(&d->addons, list))) { 07411 free(a); 07412 } 07413 AST_LIST_REMOVE_CURRENT(list); 07414 free(d); 07415 } 07416 AST_LIST_TRAVERSE_SAFE_END; 07417 AST_LIST_UNLOCK(&devices); 07418 07419 AST_LIST_LOCK(&lines); 07420 AST_LIST_TRAVERSE_SAFE_BEGIN(&lines, l, all) { 07421 if (l->prune) { 07422 AST_LIST_REMOVE_CURRENT(all); 07423 free(l); 07424 } 07425 } 07426 AST_LIST_TRAVERSE_SAFE_END; 07427 AST_LIST_UNLOCK(&lines); 07428 07429 AST_LIST_TRAVERSE(&devices, d, list) { 07430 /* Do a soft reset to re-register the devices after 07431 cleaning up the removed devices and lines */ 07432 if (d->session) { 07433 ast_verb(3, "Restarting device '%s'\n", d->name); 07434 if ((req = req_alloc(sizeof(struct reset_message), RESET_MESSAGE))) { 07435 req->data.reset.resetType = 2; 07436 transmit_response(d, req); 07437 } 07438 } 07439 } 07440 07441 skinnyreload = 0; 07442 return 0; 07443 }
static struct skinny_req* skinny_req_parse | ( | struct skinnysession * | s | ) | [static] |
Definition at line 6446 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().
06447 { 06448 struct skinny_req *req; 06449 int *bufaddr; 06450 06451 if (!(req = ast_calloc(1, SKINNY_MAX_PACKET))) 06452 return NULL; 06453 06454 ast_mutex_lock(&s->lock); 06455 memcpy(req, s->inbuf, skinny_header_size); 06456 bufaddr = (int *)(s->inbuf); 06457 memcpy(&req->data, s->inbuf+skinny_header_size, letohl(*bufaddr)-4); 06458 06459 ast_mutex_unlock(&s->lock); 06460 06461 if (letohl(req->e) < 0) { 06462 ast_log(LOG_ERROR, "Event Message is NULL from socket %d, This is bad\n", s->fd); 06463 ast_free(req); 06464 return NULL; 06465 } 06466 06467 return req; 06468 }
static struct ast_channel * skinny_request | ( | const char * | type, | |
format_t | format, | |||
const struct ast_channel * | requestor, | |||
void * | data, | |||
int * | cause | |||
) | [static] |
Definition at line 6630 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, find_line_by_name(), ast_channel::linkedid, LOG_NOTICE, LOG_WARNING, restart_monitor(), and skinny_new().
06631 { 06632 format_t oldformat; 06633 06634 struct skinny_line *l; 06635 struct ast_channel *tmpc = NULL; 06636 char tmp[256]; 06637 char *dest = data; 06638 06639 oldformat = format; 06640 06641 if (!(format &= AST_FORMAT_AUDIO_MASK)) { 06642 ast_log(LOG_NOTICE, "Asked to get a channel of unsupported format '%s'\n", ast_getformatname_multiple(tmp, sizeof(tmp), format)); 06643 return NULL; 06644 } 06645 06646 ast_copy_string(tmp, dest, sizeof(tmp)); 06647 if (ast_strlen_zero(tmp)) { 06648 ast_log(LOG_NOTICE, "Skinny channels require a device\n"); 06649 return NULL; 06650 } 06651 l = find_line_by_name(tmp); 06652 if (!l) { 06653 ast_log(LOG_NOTICE, "No available lines on: %s\n", dest); 06654 return NULL; 06655 } 06656 ast_verb(3, "skinny_request(%s)\n", tmp); 06657 tmpc = skinny_new(l, AST_STATE_DOWN, requestor ? requestor->linkedid : NULL); 06658 if (!tmpc) { 06659 ast_log(LOG_WARNING, "Unable to make channel for '%s'\n", tmp); 06660 } 06661 restart_monitor(); 06662 return tmpc; 06663 }
static struct ast_frame* skinny_rtp_read | ( | struct skinny_subchannel * | sub | ) | [static] |
Definition at line 4109 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(), f, ast_channel::fdno, ast_channel::nativeformats, skinny_subchannel::owner, ast_channel::readformat, skinny_subchannel::rtp, skinny_subchannel::vrtp, and ast_channel::writeformat.
Referenced by skinny_read().
04110 { 04111 struct ast_channel *ast = sub->owner; 04112 struct ast_frame *f; 04113 04114 if (!sub->rtp) { 04115 /* We have no RTP allocated for this channel */ 04116 return &ast_null_frame; 04117 } 04118 04119 switch(ast->fdno) { 04120 case 0: 04121 f = ast_rtp_instance_read(sub->rtp, 0); /* RTP Audio */ 04122 break; 04123 case 1: 04124 f = ast_rtp_instance_read(sub->rtp, 1); /* RTCP Control Channel */ 04125 break; 04126 case 2: 04127 f = ast_rtp_instance_read(sub->vrtp, 0); /* RTP Video */ 04128 break; 04129 case 3: 04130 f = ast_rtp_instance_read(sub->vrtp, 1); /* RTCP Control Channel for video */ 04131 break; 04132 #if 0 04133 case 5: 04134 /* Not yet supported */ 04135 f = ast_udptl_read(sub->udptl); /* UDPTL for T.38 */ 04136 break; 04137 #endif 04138 default: 04139 f = &ast_null_frame; 04140 } 04141 04142 if (ast) { 04143 /* We already hold the channel lock */ 04144 if (f->frametype == AST_FRAME_VOICE) { 04145 if (f->subclass.codec != ast->nativeformats) { 04146 ast_debug(1, "Oooh, format changed to %s\n", ast_getformatname(f->subclass.codec)); 04147 ast->nativeformats = f->subclass.codec; 04148 ast_set_read_format(ast, ast->readformat); 04149 ast_set_write_format(ast, ast->writeformat); 04150 } 04151 } 04152 } 04153 return f; 04154 }
static int skinny_senddigit_begin | ( | struct ast_channel * | ast, | |
char | digit | |||
) | [static] |
static int skinny_senddigit_end | ( | struct ast_channel * | ast, | |
char | digit, | |||
unsigned int | duration | |||
) | [static] |
Definition at line 4215 of file chan_skinny.c.
References skinny_line::device, skinny_line::sub, and ast_channel::tech_pvt.
04216 { 04217 #if 0 04218 struct skinny_subchannel *sub = ast->tech_pvt; 04219 struct skinny_line *l = sub->parent; 04220 struct skinny_device *d = l->device; 04221 int tmp; 04222 /* not right */ 04223 sprintf(tmp, "%d", digit); 04224 //transmit_tone(d, digit, l->instance, sub->callid); 04225 #endif 04226 return -1; /* Stop inband indications */ 04227 }
static void* skinny_session | ( | void * | data | ) | [static] |
Definition at line 6470 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().
06471 { 06472 int res; 06473 struct skinny_req *req; 06474 struct skinnysession *s = data; 06475 06476 ast_verb(3, "Starting Skinny session from %s\n", ast_inet_ntoa(s->sin.sin_addr)); 06477 06478 for (;;) { 06479 res = get_input(s); 06480 if (res < 0) { 06481 break; 06482 } 06483 06484 if (res > 0) 06485 { 06486 if (!(req = skinny_req_parse(s))) { 06487 destroy_session(s); 06488 return NULL; 06489 } 06490 06491 res = handle_message(req, s); 06492 if (res < 0) { 06493 destroy_session(s); 06494 return NULL; 06495 } 06496 } 06497 } 06498 ast_debug(3, "Skinny Session returned: %s\n", strerror(errno)); 06499 06500 if (s) 06501 destroy_session(s); 06502 06503 return 0; 06504 }
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 2822 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, skinny_subchannel::rtp, ast_channel::tech_pvt, transmit_startmediatransmission(), and transmit_stopmediatransmission().
02823 { 02824 struct skinny_subchannel *sub; 02825 struct skinny_line *l; 02826 struct skinny_device *d; 02827 struct ast_format_list fmt; 02828 struct sockaddr_in us = { 0, }; 02829 struct sockaddr_in them = { 0, }; 02830 struct ast_sockaddr them_tmp; 02831 struct ast_sockaddr us_tmp; 02832 02833 sub = c->tech_pvt; 02834 02835 if (c->_state != AST_STATE_UP) 02836 return 0; 02837 02838 if (!sub) { 02839 return -1; 02840 } 02841 02842 l = sub->parent; 02843 d = l->device; 02844 02845 if (rtp){ 02846 ast_rtp_instance_get_remote_address(rtp, &them_tmp); 02847 ast_sockaddr_to_sin(&them_tmp, &them); 02848 02849 /* Shutdown any early-media or previous media on re-invite */ 02850 transmit_stopmediatransmission(d, sub); 02851 02852 if (skinnydebug) 02853 ast_verb(1, "Peerip = %s:%d\n", ast_inet_ntoa(them.sin_addr), ntohs(them.sin_port)); 02854 02855 fmt = ast_codec_pref_getsize(&l->prefs, ast_best_codec(l->capability)); 02856 02857 if (skinnydebug) 02858 ast_verb(1, "Setting payloadType to '%s' (%d ms)\n", ast_getformatname(fmt.bits), fmt.cur_ms); 02859 02860 if (!(l->directmedia) || (l->nat)){ 02861 ast_rtp_instance_get_local_address(rtp, &us_tmp); 02862 ast_sockaddr_to_sin(&us_tmp, &us); 02863 us.sin_addr.s_addr = us.sin_addr.s_addr ? us.sin_addr.s_addr : d->ourip.s_addr; 02864 transmit_startmediatransmission(d, sub, us, fmt); 02865 } else { 02866 transmit_startmediatransmission(d, sub, them, fmt); 02867 } 02868 02869 return 0; 02870 } 02871 /* Need a return here to break the bridge */ 02872 return 0; 02873 }
static void* skinny_ss | ( | void * | data | ) | [static] |
Definition at line 3806 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, skinny_line::device, ast_channel::exten, ast_party_caller::id, len(), LOG_WARNING, ast_channel::name, ast_party_id::number, skinny_subchannel::owner, S_COR, set_callforwards(), SKINNY_DIALTONE, SKINNY_LAMP_ON, skinny_newcall(), SKINNY_OFFHOOK, SKINNY_REORDER, STIMULUS_FORWARDALL, ast_party_number::str, skinny_line::sub, 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().
03807 { 03808 struct ast_channel *c = data; 03809 struct skinny_subchannel *sub = c->tech_pvt; 03810 struct skinny_line *l = sub->parent; 03811 struct skinny_device *d = l->device; 03812 int len = 0; 03813 int timeout = firstdigittimeout; 03814 int res = 0; 03815 int loop_pause = 100; 03816 03817 ast_verb(3, "Starting simple switch on '%s@%s'\n", l->name, d->name); 03818 03819 len = strlen(d->exten); 03820 03821 while (len < AST_MAX_EXTENSION-1) { 03822 res = 1; /* Assume that we will get a digit */ 03823 while (strlen(d->exten) == len){ 03824 ast_safe_sleep(c, loop_pause); 03825 timeout -= loop_pause; 03826 if ( (timeout -= loop_pause) <= 0){ 03827 res = 0; 03828 break; 03829 } 03830 res = 1; 03831 } 03832 03833 timeout = 0; 03834 len = strlen(d->exten); 03835 03836 if (!ast_ignore_pattern(c->context, d->exten)) { 03837 transmit_stop_tone(d, l->instance, sub->callid); 03838 } 03839 if (ast_exists_extension(c, c->context, d->exten, 1, l->cid_num)) { 03840 if (!res || !ast_matchmore_extension(c, c->context, d->exten, 1, l->cid_num)) { 03841 if (l->getforward) { 03842 /* Record this as the forwarding extension */ 03843 set_callforwards(l, d->exten, l->getforward); 03844 ast_verb(3, "Setting call forward (%d) to '%s' on channel %s\n", 03845 l->cfwdtype, d->exten, c->name); 03846 transmit_start_tone(d, SKINNY_DIALTONE, l->instance, sub->callid); 03847 transmit_lamp_indication(d, STIMULUS_FORWARDALL, 1, SKINNY_LAMP_ON); 03848 transmit_displaynotify(d, "CFwd enabled", 10); 03849 transmit_cfwdstate(d, l); 03850 ast_safe_sleep(c, 500); 03851 ast_indicate(c, -1); 03852 ast_safe_sleep(c, 1000); 03853 memset(d->exten, 0, sizeof(d->exten)); 03854 len = 0; 03855 l->getforward = 0; 03856 if (sub->owner && sub->owner->_state != AST_STATE_UP) { 03857 ast_indicate(c, -1); 03858 ast_hangup(c); 03859 } 03860 return NULL; 03861 } else { 03862 ast_copy_string(c->exten, d->exten, sizeof(c->exten)); 03863 ast_copy_string(l->lastnumberdialed, d->exten, sizeof(l->lastnumberdialed)); 03864 memset(d->exten, 0, sizeof(d->exten)); 03865 skinny_newcall(c); 03866 return NULL; 03867 } 03868 } else { 03869 /* It's a match, but they just typed a digit, and there is an ambiguous match, 03870 so just set the timeout to matchdigittimeout and wait some more */ 03871 timeout = matchdigittimeout; 03872 } 03873 } else if (res == 0) { 03874 ast_debug(1, "Not enough digits (%s) (and no ambiguous match)...\n", d->exten); 03875 memset(d->exten, 0, sizeof(d->exten)); 03876 if (l->hookstate == SKINNY_OFFHOOK) { 03877 transmit_start_tone(d, SKINNY_REORDER, l->instance, sub->callid); 03878 } 03879 if (sub->owner && sub->owner->_state != AST_STATE_UP) { 03880 ast_indicate(c, -1); 03881 ast_hangup(c); 03882 } 03883 return NULL; 03884 } else if (!ast_canmatch_extension(c, c->context, d->exten, 1, 03885 S_COR(c->caller.id.number.valid, c->caller.id.number.str, NULL)) 03886 && ((d->exten[0] != '*') || (!ast_strlen_zero(d->exten) > 2))) { 03887 ast_log(LOG_WARNING, "Can't match [%s] from '%s' in context %s\n", d->exten, 03888 S_COR(c->caller.id.number.valid, c->caller.id.number.str, "<Unknown Caller>"), 03889 c->context); 03890 memset(d->exten, 0, sizeof(d->exten)); 03891 if (l->hookstate == SKINNY_OFFHOOK) { 03892 transmit_start_tone(d, SKINNY_REORDER, l->instance, sub->callid); 03893 /* hang out for 3 seconds to let congestion play */ 03894 ast_safe_sleep(c, 3000); 03895 } 03896 break; 03897 } 03898 if (!timeout) { 03899 timeout = gendigittimeout; 03900 } 03901 if (len && !ast_ignore_pattern(c->context, d->exten)) { 03902 ast_indicate(c, -1); 03903 } 03904 } 03905 if (c) 03906 ast_hangup(c); 03907 memset(d->exten, 0, sizeof(d->exten)); 03908 return NULL; 03909 }
static int skinny_transfer | ( | struct skinny_subchannel * | sub | ) | [static] |
Definition at line 4312 of file chan_skinny.c.
References ast_bridged_channel(), ast_channel_masquerade(), AST_CONTROL_UNHOLD, ast_debug, ast_get_indication_tone(), ast_log(), ast_playtones_start(), ast_queue_control(), AST_STATE_RING, 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, and skinny_subchannel::xferor.
Referenced by handle_transfer_button(), skinny_answer(), and skinny_indicate().
04313 { 04314 struct skinny_subchannel *xferor; /* the sub doing the transferring */ 04315 struct skinny_subchannel *xferee; /* the sub being transferred */ 04316 struct ast_tone_zone_sound *ts = NULL; 04317 04318 if (ast_bridged_channel(sub->owner) || ast_bridged_channel(sub->related->owner)) { 04319 if (sub->xferor) { 04320 xferor = sub; 04321 xferee = sub->related; 04322 } else { 04323 xferor = sub; 04324 xferee = sub->related; 04325 } 04326 04327 if (skinnydebug) { 04328 ast_debug(1, "Transferee channels (local/remote): %s and %s\n", 04329 xferee->owner->name, ast_bridged_channel(xferee->owner)?ast_bridged_channel(xferee->owner)->name:""); 04330 ast_debug(1, "Transferor channels (local/remote): %s and %s\n", 04331 xferor->owner->name, ast_bridged_channel(xferor->owner)?ast_bridged_channel(xferor->owner)->name:""); 04332 } 04333 if (ast_bridged_channel(xferor->owner)) { 04334 if (ast_bridged_channel(xferee->owner)) { 04335 ast_queue_control(xferee->owner, AST_CONTROL_UNHOLD); 04336 } 04337 if (xferor->owner->_state == AST_STATE_RING) { 04338 /* play ringing inband */ 04339 if ((ts = ast_get_indication_tone(xferor->owner->zone, "ring"))) { 04340 ast_playtones_start(xferor->owner, 0, ts->data, 1); 04341 ts = ast_tone_zone_sound_unref(ts); 04342 } 04343 } 04344 if (skinnydebug) 04345 ast_debug(1, "Transfer Masquerading %s to %s\n", 04346 xferee->owner->name, ast_bridged_channel(xferor->owner)?ast_bridged_channel(xferor->owner)->name:""); 04347 if (ast_channel_masquerade(xferee->owner, ast_bridged_channel(xferor->owner))) { 04348 ast_log(LOG_WARNING, "Unable to masquerade %s as %s\n", 04349 ast_bridged_channel(xferor->owner)->name, xferee->owner->name); 04350 return -1; 04351 } 04352 } else if (ast_bridged_channel(xferee->owner)) { 04353 ast_queue_control(xferee->owner, AST_CONTROL_UNHOLD); 04354 if (xferor->owner->_state == AST_STATE_RING) { 04355 /* play ringing inband */ 04356 if ((ts = ast_get_indication_tone(xferor->owner->zone, "ring"))) { 04357 ast_playtones_start(xferor->owner, 0, ts->data, 1); 04358 ts = ast_tone_zone_sound_unref(ts); 04359 } 04360 } 04361 if (skinnydebug) 04362 ast_debug(1, "Transfer Masquerading %s to %s\n", 04363 xferor->owner->name, ast_bridged_channel(xferee->owner)?ast_bridged_channel(xferee->owner)->name:""); 04364 if (ast_channel_masquerade(xferor->owner, ast_bridged_channel(xferee->owner))) { 04365 ast_log(LOG_WARNING, "Unable to masquerade %s as %s\n", 04366 ast_bridged_channel(xferee->owner)->name, xferor->owner->name); 04367 return -1; 04368 } 04369 return 0; 04370 } else { 04371 if (option_debug) 04372 ast_log(LOG_DEBUG, "Neither %s nor %s are in a bridge, nothing to transfer\n", 04373 xferor->owner->name, xferee->owner->name); 04374 } 04375 } 04376 return 0; 04377 }
static int skinny_unhold | ( | struct skinny_subchannel * | sub | ) | [static] |
Definition at line 4637 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, skinny_line::sub, transmit_activatecallplane(), transmit_callstate(), transmit_connect(), and transmit_lamp_indication().
Referenced by handle_hold_button(), and handle_soft_key_event_message().
04638 { 04639 struct skinny_line *l = sub->parent; 04640 struct skinny_device *d = l->device; 04641 04642 /* Don't try to unhold a channel that doesn't exist */ 04643 if (!sub || !sub->owner) 04644 return 0; 04645 04646 /* Channel is on hold, so we will unhold */ 04647 if (skinnydebug) 04648 ast_verb(1, "Taking off Hold(%d)\n", l->instance); 04649 04650 ast_queue_control(sub->owner, AST_CONTROL_UNHOLD); 04651 04652 transmit_activatecallplane(d, l); 04653 04654 transmit_connect(d, sub); 04655 transmit_callstate(d, sub->parent->instance, sub->callid, SKINNY_CONNECTED); 04656 transmit_lamp_indication(d, STIMULUS_LINE, l->instance, SKINNY_LAMP_ON); 04657 l->hookstate = SKINNY_OFFHOOK; 04658 sub->onhold = 0; 04659 return 1; 04660 }
static int skinny_unregister | ( | struct skinny_req * | req, | |
struct skinnysession * | s | |||
) | [static] |
Definition at line 1947 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, skinny_subchannel::list, manager_event, skinny_device::session, skinny_device::speeddials, skinny_speeddial::stateid, and unregister_exten().
Referenced by get_input(), handle_message(), and transmit_response().
01948 { 01949 struct skinny_device *d; 01950 struct skinny_line *l; 01951 struct skinny_speeddial *sd; 01952 01953 d = s->device; 01954 01955 if (d) { 01956 d->session = NULL; 01957 d->registered = 0; 01958 01959 AST_LIST_TRAVERSE(&d->speeddials, sd, list) { 01960 if (sd->stateid > -1) 01961 ast_extension_state_del(sd->stateid, NULL); 01962 } 01963 AST_LIST_TRAVERSE(&d->lines, l, list) { 01964 if (l->device == d) { 01965 l->device = NULL; 01966 l->capability = 0; 01967 ast_parse_allow_disallow(&l->prefs, &l->capability, "all", 0); 01968 l->instance = 0; 01969 manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", "ChannelType: Skinny\r\nPeer: Skinny/%s@%s\r\nPeerStatus: Unregistered\r\n", l->name, d->name); 01970 unregister_exten(l); 01971 ast_devstate_changed(AST_DEVICE_UNAVAILABLE, "Skinny/%s@%s", l->name, d->name); 01972 } 01973 } 01974 } 01975 01976 return -1; /* main loop will destroy the session */ 01977 }
static int skinny_write | ( | struct ast_channel * | ast, | |
struct ast_frame * | frame | |||
) | [static] |
Definition at line 4166 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.
04167 { 04168 struct skinny_subchannel *sub = ast->tech_pvt; 04169 int res = 0; 04170 if (frame->frametype != AST_FRAME_VOICE) { 04171 if (frame->frametype == AST_FRAME_IMAGE) { 04172 return 0; 04173 } else { 04174 ast_log(LOG_WARNING, "Can't send %d type frames with skinny_write\n", frame->frametype); 04175 return 0; 04176 } 04177 } else { 04178 if (!(frame->subclass.codec & ast->nativeformats)) { 04179 char buf[256]; 04180 ast_log(LOG_WARNING, "Asked to transmit frame type %s, while native formats is %s (read/write = %s/%s)\n", 04181 ast_getformatname(frame->subclass.codec), 04182 ast_getformatname_multiple(buf, sizeof(buf), ast->nativeformats), 04183 ast_getformatname(ast->readformat), 04184 ast_getformatname(ast->writeformat)); 04185 return -1; 04186 } 04187 } 04188 if (sub) { 04189 ast_mutex_lock(&sub->lock); 04190 if (sub->rtp) { 04191 res = ast_rtp_instance_write(sub->rtp, frame); 04192 } 04193 ast_mutex_unlock(&sub->lock); 04194 } 04195 return res; 04196 }
static void start_rtp | ( | struct skinny_subchannel * | sub | ) | [static] |
Definition at line 3727 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, skinny_line::device, skinny_subchannel::lock, skinny_subchannel::owner, qos, skinny_subchannel::rtp, sched, skinny_line::sub, transmit_connect(), and skinny_subchannel::vrtp.
03728 { 03729 struct skinny_line *l = sub->parent; 03730 struct skinny_device *d = l->device; 03731 int hasvideo = 0; 03732 struct ast_sockaddr bindaddr_tmp; 03733 03734 ast_mutex_lock(&sub->lock); 03735 /* Allocate the RTP */ 03736 ast_sockaddr_from_sin(&bindaddr_tmp, &bindaddr); 03737 sub->rtp = ast_rtp_instance_new("asterisk", sched, &bindaddr_tmp, NULL); 03738 if (hasvideo) 03739 sub->vrtp = ast_rtp_instance_new("asterisk", sched, &bindaddr_tmp, NULL); 03740 03741 if (sub->rtp) { 03742 ast_rtp_instance_set_prop(sub->rtp, AST_RTP_PROPERTY_RTCP, 1); 03743 } 03744 if (sub->vrtp) { 03745 ast_rtp_instance_set_prop(sub->vrtp, AST_RTP_PROPERTY_RTCP, 1); 03746 } 03747 03748 if (sub->rtp && sub->owner) { 03749 ast_channel_set_fd(sub->owner, 0, ast_rtp_instance_fd(sub->rtp, 0)); 03750 ast_channel_set_fd(sub->owner, 1, ast_rtp_instance_fd(sub->rtp, 1)); 03751 } 03752 if (hasvideo && sub->vrtp && sub->owner) { 03753 ast_channel_set_fd(sub->owner, 2, ast_rtp_instance_fd(sub->vrtp, 0)); 03754 ast_channel_set_fd(sub->owner, 3, ast_rtp_instance_fd(sub->vrtp, 1)); 03755 } 03756 if (sub->rtp) { 03757 ast_rtp_instance_set_qos(sub->rtp, qos.tos_audio, qos.cos_audio, "Skinny RTP"); 03758 ast_rtp_instance_set_prop(sub->rtp, AST_RTP_PROPERTY_NAT, l->nat); 03759 } 03760 if (sub->vrtp) { 03761 ast_rtp_instance_set_qos(sub->vrtp, qos.tos_video, qos.cos_video, "Skinny VRTP"); 03762 ast_rtp_instance_set_prop(sub->vrtp, AST_RTP_PROPERTY_NAT, l->nat); 03763 } 03764 /* Set Frame packetization */ 03765 if (sub->rtp) 03766 ast_rtp_codecs_packetization_set(ast_rtp_instance_get_codecs(sub->rtp), sub->rtp, &l->prefs); 03767 03768 /* Create the RTP connection */ 03769 transmit_connect(d, sub); 03770 ast_mutex_unlock(&sub->lock); 03771 }
static void transmit_activatecallplane | ( | struct skinny_device * | d, | |
struct skinny_line * | l | |||
) | [static] |
Definition at line 2442 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().
02443 { 02444 struct skinny_req *req; 02445 02446 if (!(req = req_alloc(sizeof(struct activate_call_plane_message), ACTIVATE_CALL_PLANE_MESSAGE))) 02447 return; 02448 02449 req->data.activatecallplane.lineInstance = htolel(l->instance); 02450 transmit_response(d, req); 02451 }
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 2174 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().
02175 { 02176 struct skinny_req *req; 02177 02178 /* We should not be able to get here without a device */ 02179 if (!d) 02180 return; 02181 02182 if (!(req = req_alloc(sizeof(struct call_info_message), CALL_INFO_MESSAGE))) 02183 return; 02184 02185 if (skinnydebug) 02186 ast_verb(1, "Setting Callinfo to %s(%s) from %s(%s) on %s(%d)\n", fromname, fromnum, toname, tonum, d->name, instance); 02187 02188 if (fromname) { 02189 ast_copy_string(req->data.callinfo.callingPartyName, fromname, sizeof(req->data.callinfo.callingPartyName)); 02190 } 02191 if (fromnum) { 02192 ast_copy_string(req->data.callinfo.callingParty, fromnum, sizeof(req->data.callinfo.callingParty)); 02193 } 02194 if (toname) { 02195 ast_copy_string(req->data.callinfo.calledPartyName, toname, sizeof(req->data.callinfo.calledPartyName)); 02196 } 02197 if (tonum) { 02198 ast_copy_string(req->data.callinfo.calledParty, tonum, sizeof(req->data.callinfo.calledParty)); 02199 } 02200 req->data.callinfo.instance = htolel(instance); 02201 req->data.callinfo.reference = htolel(callid); 02202 req->data.callinfo.type = htolel(calltype); 02203 transmit_response(d, req); 02204 }
static void transmit_callstate | ( | struct skinny_device * | d, | |
int | buttonInstance, | |||
unsigned | callid, | |||
int | state | |||
) | [static] |
Definition at line 2453 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().
02454 { 02455 struct skinny_req *req; 02456 02457 if (!(req = req_alloc(sizeof(struct call_state_message), CALL_STATE_MESSAGE))) 02458 return; 02459 02460 req->data.callstate.callState = htolel(state); 02461 req->data.callstate.lineInstance = htolel(buttonInstance); 02462 req->data.callstate.callReference = htolel(callid); 02463 transmit_response(d, req); 02464 }
static void transmit_cfwdstate | ( | struct skinny_device * | d, | |
struct skinny_line * | l | |||
) | [static] |
Definition at line 2466 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().
02467 { 02468 struct skinny_req *req; 02469 int anyon = 0; 02470 02471 if (!(req = req_alloc(sizeof(struct forward_stat_message), FORWARD_STAT_MESSAGE))) 02472 return; 02473 02474 if (l->cfwdtype & SKINNY_CFWD_ALL) { 02475 if (!ast_strlen_zero(l->call_forward_all)) { 02476 ast_copy_string(req->data.forwardstat.fwdallnum, l->call_forward_all, sizeof(req->data.forwardstat.fwdallnum)); 02477 req->data.forwardstat.fwdall = htolel(1); 02478 anyon++; 02479 } else { 02480 req->data.forwardstat.fwdall = htolel(0); 02481 } 02482 } 02483 if (l->cfwdtype & SKINNY_CFWD_BUSY) { 02484 if (!ast_strlen_zero(l->call_forward_busy)) { 02485 ast_copy_string(req->data.forwardstat.fwdbusynum, l->call_forward_busy, sizeof(req->data.forwardstat.fwdbusynum)); 02486 req->data.forwardstat.fwdbusy = htolel(1); 02487 anyon++; 02488 } else { 02489 req->data.forwardstat.fwdbusy = htolel(0); 02490 } 02491 } 02492 if (l->cfwdtype & SKINNY_CFWD_NOANSWER) { 02493 if (!ast_strlen_zero(l->call_forward_noanswer)) { 02494 ast_copy_string(req->data.forwardstat.fwdnoanswernum, l->call_forward_noanswer, sizeof(req->data.forwardstat.fwdnoanswernum)); 02495 req->data.forwardstat.fwdnoanswer = htolel(1); 02496 anyon++; 02497 } else { 02498 req->data.forwardstat.fwdnoanswer = htolel(0); 02499 } 02500 } 02501 req->data.forwardstat.lineNumber = htolel(l->instance); 02502 if (anyon) 02503 req->data.forwardstat.activeforward = htolel(7); 02504 else 02505 req->data.forwardstat.activeforward = htolel(0); 02506 02507 transmit_response(d, req); 02508 }
static void transmit_clear_display_message | ( | struct skinny_device * | d, | |
int | instance, | |||
int | reference | |||
) | [static] |
Definition at line 2299 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().
02300 { 02301 struct skinny_req *req; 02302 if (!(req = req_alloc(0, CLEAR_DISPLAY_MESSAGE))) 02303 return; 02304 02305 //what do we want hear CLEAR_DISPLAY_MESSAGE or CLEAR_PROMPT_STATUS??? 02306 //if we are clearing the display, it appears there is no instance and refernece info (size 0) 02307 //req->data.clearpromptstatus.lineInstance = instance; 02308 //req->data.clearpromptstatus.callReference = reference; 02309 02310 if (skinnydebug) 02311 ast_verb(1, "Clearing Display\n"); 02312 transmit_response(d, req); 02313 }
static void transmit_clearpromptmessage | ( | struct skinny_device * | d, | |
int | instance, | |||
int | callid | |||
) | [static] |
Definition at line 2368 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().
02369 { 02370 struct skinny_req *req; 02371 02372 if (!(req = req_alloc(sizeof(struct clear_prompt_message), CLEAR_PROMPT_MESSAGE))) 02373 return; 02374 02375 req->data.clearpromptstatus.lineInstance = htolel(instance); 02376 req->data.clearpromptstatus.callReference = htolel(callid); 02377 02378 if (skinnydebug) 02379 ast_verb(1, "Clearing Prompt\n"); 02380 02381 transmit_response(d, req); 02382 }
static void transmit_closereceivechannel | ( | struct skinny_device * | d, | |
struct skinny_subchannel * | sub | |||
) | [static] |
Definition at line 2398 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().
02399 { 02400 struct skinny_req *req; 02401 02402 if (!(req = req_alloc(sizeof(struct close_receive_channel_message), CLOSE_RECEIVE_CHANNEL_MESSAGE))) 02403 return; 02404 02405 req->data.closereceivechannel.conferenceId = htolel(0); 02406 req->data.closereceivechannel.partyId = htolel(sub->callid); 02407 transmit_response(d, req); 02408 }
static void transmit_connect | ( | struct skinny_device * | d, | |
struct skinny_subchannel * | sub | |||
) | [static] |
Definition at line 2206 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, open_receive_channel_message::partyId, req_alloc(), skinny_line::sub, and transmit_response().
02207 { 02208 struct skinny_req *req; 02209 struct skinny_line *l = sub->parent; 02210 struct ast_format_list fmt; 02211 02212 if (!(req = req_alloc(sizeof(struct open_receive_channel_message), OPEN_RECEIVE_CHANNEL_MESSAGE))) 02213 return; 02214 02215 fmt = ast_codec_pref_getsize(&l->prefs, ast_best_codec(l->capability)); 02216 02217 req->data.openreceivechannel.conferenceId = htolel(sub->callid); 02218 req->data.openreceivechannel.partyId = htolel(sub->callid); 02219 req->data.openreceivechannel.packets = htolel(fmt.cur_ms); 02220 req->data.openreceivechannel.capability = htolel(codec_ast2skinny(fmt.bits)); 02221 req->data.openreceivechannel.echo = htolel(0); 02222 req->data.openreceivechannel.bitrate = htolel(0); 02223 transmit_response(d, req); 02224 }
static void transmit_definetimedate | ( | struct skinny_device * | d | ) | [static] |
Definition at line 2537 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().
02538 { 02539 struct skinny_req *req; 02540 struct timeval now = ast_tvnow(); 02541 struct ast_tm cmtime; 02542 02543 if (!(req = req_alloc(sizeof(struct definetimedate_message), DEFINETIMEDATE_MESSAGE))) 02544 return; 02545 02546 ast_localtime(&now, &cmtime, NULL); 02547 req->data.definetimedate.year = htolel(cmtime.tm_year+1900); 02548 req->data.definetimedate.month = htolel(cmtime.tm_mon+1); 02549 req->data.definetimedate.dayofweek = htolel(cmtime.tm_wday); 02550 req->data.definetimedate.day = htolel(cmtime.tm_mday); 02551 req->data.definetimedate.hour = htolel(cmtime.tm_hour); 02552 req->data.definetimedate.minute = htolel(cmtime.tm_min); 02553 req->data.definetimedate.seconds = htolel(cmtime.tm_sec); 02554 req->data.definetimedate.milliseconds = htolel(cmtime.tm_usec / 1000); 02555 req->data.definetimedate.timestamp = htolel(now.tv_sec); 02556 transmit_response(d, req); 02557 }
static void transmit_dialednumber | ( | struct skinny_device * | d, | |
const char * | text, | |||
int | instance, | |||
int | callid | |||
) | [static] |
Definition at line 2384 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().
02385 { 02386 struct skinny_req *req; 02387 02388 if (!(req = req_alloc(sizeof(struct dialed_number_message), DIALED_NUMBER_MESSAGE))) 02389 return; 02390 02391 ast_copy_string(req->data.dialednumber.dialedNumber, text, sizeof(req->data.dialednumber.dialedNumber)); 02392 req->data.dialednumber.lineInstance = htolel(instance); 02393 req->data.dialednumber.callReference = htolel(callid); 02394 02395 transmit_response(d, req); 02396 }
static void transmit_displaynotify | ( | struct skinny_device * | d, | |
const char * | text, | |||
int | t | |||
) | [static] |
Definition at line 2334 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().
02335 { 02336 struct skinny_req *req; 02337 02338 if (!(req = req_alloc(sizeof(struct display_notify_message), DISPLAY_NOTIFY_MESSAGE))) 02339 return; 02340 02341 ast_copy_string(req->data.displaynotify.displayMessage, text, sizeof(req->data.displaynotify.displayMessage)); 02342 req->data.displaynotify.displayTimeout = htolel(t); 02343 02344 if (skinnydebug) 02345 ast_verb(1, "Displaying notify '%s'\n", text); 02346 02347 transmit_response(d, req); 02348 }
static void transmit_displaypromptstatus | ( | struct skinny_device * | d, | |
const char * | text, | |||
int | t, | |||
int | instance, | |||
int | callid | |||
) | [static] |
Definition at line 2350 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().
02351 { 02352 struct skinny_req *req; 02353 02354 if (!(req = req_alloc(sizeof(struct display_prompt_status_message), DISPLAY_PROMPT_STATUS_MESSAGE))) 02355 return; 02356 02357 ast_copy_string(req->data.displaypromptstatus.promptMessage, text, sizeof(req->data.displaypromptstatus.promptMessage)); 02358 req->data.displaypromptstatus.messageTimeout = htolel(t); 02359 req->data.displaypromptstatus.lineInstance = htolel(instance); 02360 req->data.displaypromptstatus.callReference = htolel(callid); 02361 02362 if (skinnydebug) 02363 ast_verb(1, "Displaying Prompt Status '%s'\n", text); 02364 02365 transmit_response(d, req); 02366 }
static void transmit_lamp_indication | ( | struct skinny_device * | d, | |
int | stimulus, | |||
int | instance, | |||
int | indication | |||
) | [static] |
Definition at line 2261 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().
02262 { 02263 struct skinny_req *req; 02264 02265 if (!(req = req_alloc(sizeof(struct set_lamp_message), SET_LAMP_MESSAGE))) 02266 return; 02267 02268 req->data.setlamp.stimulus = htolel(stimulus); 02269 req->data.setlamp.stimulusInstance = htolel(instance); 02270 req->data.setlamp.deviceStimulus = htolel(indication); 02271 transmit_response(d, req); 02272 }
static void transmit_linestatres | ( | struct skinny_device * | d, | |
struct skinny_line * | l | |||
) | [static] |
Definition at line 2524 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().
02525 { 02526 struct skinny_req *req; 02527 02528 if (!(req = req_alloc(sizeof(struct line_stat_res_message), LINE_STAT_RES_MESSAGE))) 02529 return; 02530 02531 req->data.linestat.lineNumber = letohl(l->instance); 02532 memcpy(req->data.linestat.lineDirNumber, l->name, sizeof(req->data.linestat.lineDirNumber)); 02533 memcpy(req->data.linestat.lineDisplayName, l->label, sizeof(req->data.linestat.lineDisplayName)); 02534 transmit_response(d, req); 02535 }
static int transmit_response | ( | struct skinny_device * | d, | |
struct skinny_req * | req | |||
) | [static] |
Definition at line 2110 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().
02111 { 02112 struct skinnysession *s = d->session; 02113 int res = 0; 02114 02115 if (!s) { 02116 ast_log(LOG_WARNING, "Asked to transmit to a non-existent session!\n"); 02117 return -1; 02118 } 02119 02120 ast_mutex_lock(&s->lock); 02121 02122 SKINNY_DEVONLY(if (skinnydebug>1) ast_verb(4, "Transmitting %s to %s\n", message2str(req->e), d->name);) 02123 02124 if ((letohl(req->len) > SKINNY_MAX_PACKET) || (letohl(req->len) < 0)) { 02125 ast_log(LOG_WARNING, "transmit_response: the length of the request (%d) is out of bounds (%d)\n", letohl(req->len), SKINNY_MAX_PACKET); 02126 ast_mutex_unlock(&s->lock); 02127 return -1; 02128 } 02129 02130 memset(s->outbuf, 0, sizeof(s->outbuf)); 02131 memcpy(s->outbuf, req, skinny_header_size); 02132 memcpy(s->outbuf+skinny_header_size, &req->data, letohl(req->len)); 02133 02134 res = write(s->fd, s->outbuf, letohl(req->len)+8); 02135 02136 if (res != letohl(req->len)+8) { 02137 ast_log(LOG_WARNING, "Transmit: write only sent %d out of %d bytes: %s\n", res, letohl(req->len)+8, strerror(errno)); 02138 if (res == -1) { 02139 if (skinnydebug) 02140 ast_log(LOG_WARNING, "Transmit: Skinny Client was lost, unregistering\n"); 02141 skinny_unregister(NULL, s); 02142 } 02143 02144 } 02145 02146 ast_free(req); 02147 ast_mutex_unlock(&s->lock); 02148 return 1; 02149 }
static void transmit_ringer_mode | ( | struct skinny_device * | d, | |
int | mode | |||
) | [static] |
Definition at line 2274 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().
02275 { 02276 struct skinny_req *req; 02277 02278 if (skinnydebug) 02279 ast_verb(1, "Setting ringer mode to '%d'.\n", mode); 02280 02281 if (!(req = req_alloc(sizeof(struct set_ringer_message), SET_RINGER_MESSAGE))) 02282 return; 02283 02284 req->data.setringer.ringerMode = htolel(mode); 02285 /* XXX okay, I don't quite know what this is, but here's what happens (on a 7960). 02286 Note: The phone will always show as ringing on the display. 02287 02288 1: phone will audibly ring over and over 02289 2: phone will audibly ring only once 02290 any other value, will NOT cause the phone to audibly ring 02291 */ 02292 req->data.setringer.unknown1 = htolel(1); 02293 /* XXX the value here doesn't seem to change anything. Must be higher than 0. 02294 Perhaps a packet capture can shed some light on this. */ 02295 req->data.setringer.unknown2 = htolel(1); 02296 transmit_response(d, req); 02297 }
static void transmit_selectsoftkeys | ( | struct skinny_device * | d, | |
int | instance, | |||
int | callid, | |||
int | softkey | |||
) | [static] |
Definition at line 2247 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().
02248 { 02249 struct skinny_req *req; 02250 02251 if (!(req = req_alloc(sizeof(struct select_soft_keys_message), SELECT_SOFT_KEYS_MESSAGE))) 02252 return; 02253 02254 req->data.selectsoftkey.instance = htolel(instance); 02255 req->data.selectsoftkey.reference = htolel(callid); 02256 req->data.selectsoftkey.softKeySetIndex = htolel(softkey); 02257 req->data.selectsoftkey.validKeyMask = htolel(0xFFFFFFFF); 02258 transmit_response(d, req); 02259 }
static void transmit_serverres | ( | struct skinny_device * | d | ) | [static] |
Definition at line 2569 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().
02570 { 02571 struct skinny_req *req; 02572 if (!(req = req_alloc(sizeof(struct server_res_message), SERVER_RES_MESSAGE))) 02573 return; 02574 02575 memcpy(req->data.serverres.server[0].serverName, ourhost, 02576 sizeof(req->data.serverres.server[0].serverName)); 02577 req->data.serverres.serverListenPort[0] = htolel(ourport); 02578 req->data.serverres.serverIpAddr[0] = htolel(d->ourip.s_addr); 02579 transmit_response(d, req); 02580 }
static void transmit_softkeysetres | ( | struct skinny_device * | d | ) | [static] |
Definition at line 2582 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_res_message::softKeySetCount, soft_key_set_res_message::softKeySetDefinition, soft_key_set_res_message::softKeySetOffset, skinny_data::softkeysets, soft_key_set_res_message::totalSoftKeySetCount, and transmit_response().
Referenced by handle_message().
02583 { 02584 struct skinny_req *req; 02585 int i; 02586 int x; 02587 int y; 02588 const struct soft_key_definitions *softkeymode = soft_key_default_definitions; 02589 02590 if (!(req = req_alloc(sizeof(struct soft_key_set_res_message), SOFT_KEY_SET_RES_MESSAGE))) 02591 return; 02592 02593 req->data.softkeysets.softKeySetOffset = htolel(0); 02594 req->data.softkeysets.softKeySetCount = htolel(11); 02595 req->data.softkeysets.totalSoftKeySetCount = htolel(11); 02596 for (x = 0; x < sizeof(soft_key_default_definitions) / sizeof(struct soft_key_definitions); x++) { 02597 const uint8_t *defaults = softkeymode->defaults; 02598 /* XXX I wanted to get the size of the array dynamically, but that wasn't wanting to work. 02599 This will have to do for now. */ 02600 for (y = 0; y < softkeymode->count; y++) { 02601 for (i = 0; i < (sizeof(soft_key_template_default) / sizeof(struct soft_key_template_definition)); i++) { 02602 if (defaults[y] == i+1) { 02603 req->data.softkeysets.softKeySetDefinition[softkeymode->mode].softKeyTemplateIndex[y] = (i+1); 02604 req->data.softkeysets.softKeySetDefinition[softkeymode->mode].softKeyInfoIndex[y] = htoles(i+301); 02605 if (skinnydebug) 02606 ast_verbose("softKeySetDefinition : softKeyTemplateIndex: %d softKeyInfoIndex: %d\n", i+1, i+301); 02607 } 02608 } 02609 } 02610 softkeymode++; 02611 } 02612 transmit_response(d, req); 02613 }
static void transmit_softkeytemplateres | ( | struct skinny_device * | d | ) | [static] |
Definition at line 2615 of file chan_skinny.c.
References skinny_req::data, htolel, req_alloc(), soft_key_template_default, SOFT_KEY_TEMPLATE_RES_MESSAGE, soft_key_template_res_message::softKeyCount, soft_key_template_res_message::softKeyOffset, skinny_data::softkeytemplate, soft_key_template_res_message::softKeyTemplateDefinition, soft_key_template_res_message::totalSoftKeyCount, and transmit_response().
Referenced by handle_message().
02616 { 02617 struct skinny_req *req; 02618 if (!(req = req_alloc(sizeof(struct soft_key_template_res_message), SOFT_KEY_TEMPLATE_RES_MESSAGE))) 02619 return; 02620 02621 req->data.softkeytemplate.softKeyOffset = htolel(0); 02622 req->data.softkeytemplate.softKeyCount = htolel(sizeof(soft_key_template_default) / sizeof(struct soft_key_template_definition)); 02623 req->data.softkeytemplate.totalSoftKeyCount = htolel(sizeof(soft_key_template_default) / sizeof(struct soft_key_template_definition)); 02624 memcpy(req->data.softkeytemplate.softKeyTemplateDefinition, 02625 soft_key_template_default, 02626 sizeof(soft_key_template_default)); 02627 transmit_response(d, req); 02628 }
static void transmit_speaker_mode | ( | struct skinny_device * | d, | |
int | mode | |||
) | [static] |
Definition at line 2151 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().
02152 { 02153 struct skinny_req *req; 02154 02155 if (!(req = req_alloc(sizeof(struct set_speaker_message), SET_SPEAKER_MESSAGE))) 02156 return; 02157 02158 req->data.setspeaker.mode = htolel(mode); 02159 transmit_response(d, req); 02160 }
static void transmit_speeddialstatres | ( | struct skinny_device * | d, | |
struct skinny_speeddial * | sd | |||
) | [static] |
Definition at line 2510 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().
02511 { 02512 struct skinny_req *req; 02513 02514 if (!(req = req_alloc(sizeof(struct speed_dial_stat_res_message), SPEED_DIAL_STAT_RES_MESSAGE))) 02515 return; 02516 02517 req->data.speeddialreq.speedDialNumber = htolel(sd->instance); 02518 ast_copy_string(req->data.speeddial.speedDialDirNumber, sd->exten, sizeof(req->data.speeddial.speedDialDirNumber)); 02519 ast_copy_string(req->data.speeddial.speedDialDisplayName, sd->label, sizeof(req->data.speeddial.speedDialDisplayName)); 02520 02521 transmit_response(d, req); 02522 }
static void transmit_start_tone | ( | struct skinny_device * | d, | |
int | tone, | |||
int | instance, | |||
int | reference | |||
) | [static] |
Definition at line 2226 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().
02227 { 02228 struct skinny_req *req; 02229 if (!(req = req_alloc(sizeof(struct start_tone_message), START_TONE_MESSAGE))) 02230 return; 02231 req->data.starttone.tone = htolel(tone); 02232 req->data.starttone.instance = htolel(instance); 02233 req->data.starttone.reference = htolel(reference); 02234 transmit_response(d, req); 02235 }
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 2422 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().
02423 { 02424 struct skinny_req *req; 02425 02426 if (!(req = req_alloc(sizeof(struct start_media_transmission_message), START_MEDIA_TRANSMISSION_MESSAGE))) 02427 return; 02428 02429 req->data.startmedia.conferenceId = htolel(sub->callid); 02430 req->data.startmedia.passThruPartyId = htolel(sub->callid); 02431 req->data.startmedia.remoteIp = dest.sin_addr.s_addr; 02432 req->data.startmedia.remotePort = htolel(ntohs(dest.sin_port)); 02433 req->data.startmedia.packetSize = htolel(fmt.cur_ms); 02434 req->data.startmedia.payloadType = htolel(codec_ast2skinny(fmt.bits)); 02435 req->data.startmedia.qualifier.precedence = htolel(127); 02436 req->data.startmedia.qualifier.vad = htolel(0); 02437 req->data.startmedia.qualifier.packets = htolel(0); 02438 req->data.startmedia.qualifier.bitRate = htolel(0); 02439 transmit_response(d, req); 02440 }
static void transmit_stop_tone | ( | struct skinny_device * | d, | |
int | instance, | |||
int | reference | |||
) | [static] |
Definition at line 2237 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().
02238 { 02239 struct skinny_req *req; 02240 if (!(req = req_alloc(sizeof(struct stop_tone_message), STOP_TONE_MESSAGE))) 02241 return; 02242 req->data.stoptone.instance = htolel(instance); 02243 req->data.stoptone.reference = htolel(reference); 02244 transmit_response(d, req); 02245 }
static void transmit_stopmediatransmission | ( | struct skinny_device * | d, | |
struct skinny_subchannel * | sub | |||
) | [static] |
Definition at line 2410 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().
02411 { 02412 struct skinny_req *req; 02413 02414 if (!(req = req_alloc(sizeof(struct stop_media_transmission_message), STOP_MEDIA_TRANSMISSION_MESSAGE))) 02415 return; 02416 02417 req->data.stopmedia.conferenceId = htolel(0); 02418 req->data.stopmedia.passThruPartyId = htolel(sub->callid); 02419 transmit_response(d, req); 02420 }
static void transmit_versionres | ( | struct skinny_device * | d | ) | [static] |
Definition at line 2559 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().
02560 { 02561 struct skinny_req *req; 02562 if (!(req = req_alloc(sizeof(struct version_res_message), VERSION_RES_MESSAGE))) 02563 return; 02564 02565 ast_copy_string(req->data.version.version, d->version_id, sizeof(req->data.version.version)); 02566 transmit_response(d, req); 02567 }
static int unload_module | ( | void | ) | [static] |
Definition at line 7486 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::list, skinny_subchannel::lock, skinny_line::lock, manager_event, monlock, skinny_line::mwi_event_sub, netlock, skinny_subchannel::owner, sched, sched_context_destroy(), skinny_rtp_glue, skinny_tech, skinny_line::sub, skinnysession::t, and unregister_exten().
07487 { 07488 struct skinnysession *s; 07489 struct skinny_device *d; 07490 struct skinny_line *l; 07491 struct skinny_subchannel *sub; 07492 struct ast_context *con; 07493 07494 ast_rtp_glue_unregister(&skinny_rtp_glue); 07495 ast_channel_unregister(&skinny_tech); 07496 ast_cli_unregister_multiple(cli_skinny, ARRAY_LEN(cli_skinny)); 07497 07498 ast_manager_unregister("SKINNYdevices"); 07499 ast_manager_unregister("SKINNYshowdevice"); 07500 ast_manager_unregister("SKINNYlines"); 07501 ast_manager_unregister("SKINNYshowline"); 07502 07503 AST_LIST_LOCK(&sessions); 07504 /* Destroy all the interfaces and free their memory */ 07505 while((s = AST_LIST_REMOVE_HEAD(&sessions, list))) { 07506 d = s->device; 07507 AST_LIST_TRAVERSE(&d->lines, l, list){ 07508 ast_mutex_lock(&l->lock); 07509 AST_LIST_TRAVERSE(&l->sub, sub, list) { 07510 ast_mutex_lock(&sub->lock); 07511 if (sub->owner) { 07512 sub->alreadygone = 1; 07513 ast_softhangup(sub->owner, AST_SOFTHANGUP_APPUNLOAD); 07514 } 07515 ast_mutex_unlock(&sub->lock); 07516 } 07517 if (l->mwi_event_sub) 07518 ast_event_unsubscribe(l->mwi_event_sub); 07519 ast_mutex_unlock(&l->lock); 07520 manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", "ChannelType: Skinny\r\nPeer: Skinny/%s@%s\r\nPeerStatus: Unregistered\r\n", l->name, d->name); 07521 unregister_exten(l); 07522 } 07523 if (s->fd > -1) 07524 close(s->fd); 07525 pthread_cancel(s->t); 07526 pthread_kill(s->t, SIGURG); 07527 pthread_join(s->t, NULL); 07528 free(s); 07529 } 07530 AST_LIST_UNLOCK(&sessions); 07531 07532 delete_devices(); 07533 07534 ast_mutex_lock(&monlock); 07535 if ((monitor_thread != AST_PTHREADT_NULL) && (monitor_thread != AST_PTHREADT_STOP)) { 07536 pthread_cancel(monitor_thread); 07537 pthread_kill(monitor_thread, SIGURG); 07538 pthread_join(monitor_thread, NULL); 07539 } 07540 monitor_thread = AST_PTHREADT_STOP; 07541 ast_mutex_unlock(&monlock); 07542 07543 ast_mutex_lock(&netlock); 07544 if (accept_t && (accept_t != AST_PTHREADT_STOP)) { 07545 pthread_cancel(accept_t); 07546 pthread_kill(accept_t, SIGURG); 07547 pthread_join(accept_t, NULL); 07548 } 07549 accept_t = AST_PTHREADT_STOP; 07550 ast_mutex_unlock(&netlock); 07551 07552 close(skinnysock); 07553 if (sched) 07554 sched_context_destroy(sched); 07555 07556 con = ast_context_find(used_context); 07557 if (con) 07558 ast_context_destroy(con, "Skinny"); 07559 07560 return 0; 07561 }
static void unregister_exten | ( | struct skinny_line * | l | ) | [static] |
Definition at line 1851 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, S_OR, and strsep().
Referenced by skinny_unregister(), and unload_module().
01852 { 01853 char multi[256]; 01854 char *stringp, *ext, *context; 01855 01856 if (ast_strlen_zero(regcontext)) 01857 return; 01858 01859 ast_copy_string(multi, S_OR(l->regexten, l->name), sizeof(multi)); 01860 stringp = multi; 01861 while ((ext = strsep(&stringp, "&"))) { 01862 if ((context = strchr(ext, '@'))) { 01863 *context++ = '\0'; /* split ext@context */ 01864 if (!ast_context_find(context)) { 01865 ast_log(LOG_WARNING, "Context %s must exist in regcontext= in skinny.conf!\n", context); 01866 continue; 01867 } 01868 } else { 01869 context = regcontext; 01870 } 01871 ast_context_remove_extension(context, ext, 1, NULL); 01872 } 01873 }
static void update_connectedline | ( | struct skinny_subchannel * | sub, | |
const void * | data, | |||
size_t | datalen | |||
) | [static] |
Definition at line 2679 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_connected_line::id, ast_party_caller::id, ast_party_id::name, ast_party_id::number, skinny_subchannel::outgoing, skinny_subchannel::owner, skinny_subchannel::progress, skinny_subchannel::ringing, S_COR, SKINNY_CONNECTED, SKINNY_PROGRESS, SKINNY_RINGIN, SKINNY_RINGOUT, ast_party_name::str, ast_party_number::str, skinny_line::sub, transmit_callinfo(), transmit_callstate(), transmit_displaypromptstatus(), ast_party_name::valid, and ast_party_number::valid.
02680 { 02681 struct ast_channel *c = sub->owner; 02682 struct skinny_line *l = sub->parent; 02683 struct skinny_device *d = l->device; 02684 02685 if (!c->caller.id.number.valid 02686 || ast_strlen_zero(c->caller.id.number.str) 02687 || !c->connected.id.number.valid 02688 || ast_strlen_zero(c->connected.id.number.str)) 02689 return; 02690 02691 if (sub->owner->_state == AST_STATE_UP) { 02692 transmit_callstate(d, l->instance, sub->callid, SKINNY_CONNECTED); 02693 transmit_displaypromptstatus(d, "Connected", 0, l->instance, sub->callid); 02694 if (sub->outgoing) 02695 transmit_callinfo(d, 02696 S_COR(c->connected.id.name.valid, c->connected.id.name.str, ""), 02697 c->connected.id.number.str, 02698 l->cid_name, l->cid_num, l->instance, sub->callid, 1); 02699 else 02700 transmit_callinfo(d, l->cid_name, l->cid_num, 02701 S_COR(c->connected.id.name.valid, c->connected.id.name.str, ""), 02702 c->connected.id.number.str, 02703 l->instance, sub->callid, 2); 02704 } else { 02705 if (sub->outgoing) { 02706 transmit_callstate(d, l->instance, sub->callid, SKINNY_RINGIN); 02707 transmit_displaypromptstatus(d, "Ring-In", 0, l->instance, sub->callid); 02708 transmit_callinfo(d, 02709 S_COR(c->connected.id.name.valid, c->connected.id.name.str, ""), 02710 c->connected.id.number.str, 02711 l->cid_name, l->cid_num, l->instance, sub->callid, 1); 02712 } else { 02713 if (!sub->ringing) { 02714 transmit_callstate(d, l->instance, sub->callid, SKINNY_RINGOUT); 02715 transmit_displaypromptstatus(d, "Ring-Out", 0, l->instance, sub->callid); 02716 sub->ringing = 1; 02717 } else { 02718 transmit_callstate(d, l->instance, sub->callid, SKINNY_PROGRESS); 02719 transmit_displaypromptstatus(d, "Call Progress", 0, l->instance, sub->callid); 02720 sub->progress = 1; 02721 } 02722 02723 transmit_callinfo(d, l->cid_name, l->cid_num, 02724 S_COR(c->connected.id.name.valid, c->connected.id.name.str, ""), 02725 c->connected.id.number.str, 02726 l->instance, sub->callid, 2); 02727 } 02728 } 02729 }
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 = "8586c2a7d357cb591cc3a6607a8f62d1" , .load = load_module, .unload = unload_module, .reload = reload, .load_pri = AST_MODPRI_CHANNEL_DRIVER, } [static] |
Definition at line 7574 of file chan_skinny.c.
struct in_addr __ourip [static] |
Definition at line 1042 of file chan_skinny.c.
pthread_t accept_t [static] |
Definition at line 1046 of file chan_skinny.c.
struct ast_hostent ahp [static] |
Definition at line 1043 of file chan_skinny.c.
Referenced by __ast_http_load(), ast_parse_arg(), config_load(), config_parse_variables(), create_addr(), festival_exec(), gtalk_load_config(), gtalk_update_stun(), jingle_load_config(), jingle_update_stun(), launch_netscript(), process_sdp(), realtime_peer(), realtime_user(), reload_config(), and rpt_exec().
struct ast_module_info* ast_module_info = &__mod_info [static] |
Definition at line 7574 of file chan_skinny.c.
int auth_limit = DEFAULT_AUTH_LIMIT [static] |
Definition at line 174 of file chan_skinny.c.
int auth_timeout = DEFAULT_AUTH_TIMEOUT [static] |
Definition at line 173 of file chan_skinny.c.
struct sockaddr_in bindaddr [static] |
Definition at line 1039 of file chan_skinny.c.
int callnums = 1 [static] |
Definition at line 1047 of file chan_skinny.c.
struct ast_cli_entry cli_skinny[] [static] |
const char config[] = "skinny.conf" [static] |
Definition at line 142 of file chan_skinny.c.
struct ast_threadstorage control2str_threadbuf = { .once = PTHREAD_ONCE_INIT , .key_init = __init_control2str_threadbuf , .custom_init = NULL , } [static] |
unsigned int cos |
Definition at line 167 of file chan_skinny.c.
unsigned int cos_audio |
Definition at line 168 of file chan_skinny.c.
unsigned int cos_video |
Definition at line 169 of file chan_skinny.c.
char date_format[6] = "D-M-Y" [static] |
Definition at line 179 of file chan_skinny.c.
format_t default_capability = AST_FORMAT_ULAW | AST_FORMAT_ALAW [static] |
Definition at line 144 of file chan_skinny.c.
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] |
Global jitterbuffer configuration - by default, jb is disabled
Definition at line 223 of file chan_skinny.c.
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] |
Definition at line 145 of file chan_skinny.c.
struct ast_threadstorage device2str_threadbuf = { .once = PTHREAD_ONCE_INIT , .key_init = __init_device2str_threadbuf , .custom_init = NULL , } [static] |
int firstdigittimeout = 16000 [static] |
Definition at line 1166 of file chan_skinny.c.
int gendigittimeout = 8000 [static] |
Definition at line 1169 of file chan_skinny.c.
struct ast_jb_conf global_jbconf [static] |
Definition at line 231 of file chan_skinny.c.
char global_vmexten[AST_MAX_EXTENSION] [static] |
Definition at line 176 of file chan_skinny.c.
struct hostent* hp [static] |
Definition at line 1044 of file chan_skinny.c.
Referenced by __ast_http_load(), ast_gethostbyname(), 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 1153 of file chan_skinny.c.
int keep_alive = 120 [static] |
Definition at line 172 of file chan_skinny.c.
int matchdigittimeout = 3000 [static] |
Definition at line 1172 of file chan_skinny.c.
pthread_t monitor_thread = AST_PTHREADT_NULL [static] |
Definition at line 1163 of file chan_skinny.c.
ast_mutex_t monlock = { PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP , NULL, 1 } [static] |
Definition at line 1157 of file chan_skinny.c.
ast_mutex_t netlock = { PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP , NULL, 1 } [static] |
Definition at line 1159 of file chan_skinny.c.
char ourhost[256] [static] |
Definition at line 1040 of file chan_skinny.c.
int ourport [static] |
Definition at line 1041 of file chan_skinny.c.
struct { ... } qos [static] |
char regcontext[AST_MAX_CONTEXT] [static] |
Definition at line 178 of file chan_skinny.c.
struct sched_context* sched = NULL [static] |
Definition at line 1152 of file chan_skinny.c.
int skinny_header_size = 12 [static] |
Definition at line 1029 of file chan_skinny.c.
struct ast_rtp_glue skinny_rtp_glue [static] |
struct ast_channel_tech skinny_tech [static] |
Definition at line 1397 of file chan_skinny.c.
Referenced by load_module(), skinny_new(), and unload_module().
int skinnydebug = 0 [static] |
Definition at line 1035 of file chan_skinny.c.
int skinnyreload = 0 [static] |
Definition at line 1036 of file chan_skinny.c.
int skinnysock = -1 [static] |
Definition at line 1045 of file chan_skinny.c.
const uint8_t soft_key_default_connected[] [static] |
Definition at line 824 of file chan_skinny.c.
const uint8_t soft_key_default_connwithconf[] [static] |
const uint8_t soft_key_default_connwithtrans[] [static] |
Definition at line 854 of file chan_skinny.c.
const uint8_t soft_key_default_dadfd[] [static] |
struct soft_key_definitions soft_key_default_definitions[] [static] |
const uint8_t soft_key_default_offhook[] [static] |
Definition at line 846 of file chan_skinny.c.
const uint8_t soft_key_default_offhookwithfeat[] [static] |
Initial value:
Definition at line 877 of file chan_skinny.c.
const uint8_t soft_key_default_onhold[] [static] |
Definition at line 833 of file chan_skinny.c.
const uint8_t soft_key_default_onhook[] [static] |
Definition at line 814 of file chan_skinny.c.
const uint8_t soft_key_default_ringin[] [static] |
Initial value:
Definition at line 840 of file chan_skinny.c.
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] |
Definition at line 651 of file chan_skinny.c.
Referenced by load_module(), transmit_softkeysetres(), and transmit_softkeytemplateres().
const char tdesc[] = "Skinny Client Control Protocol (Skinny)" [static] |
Definition at line 141 of file chan_skinny.c.
unsigned int tos |
Definition at line 164 of file chan_skinny.c.
unsigned int tos_audio |
Definition at line 165 of file chan_skinny.c.
unsigned int tos_video |
Definition at line 166 of file chan_skinny.c.
int unauth_sessions = 0 [static] |
Definition at line 175 of file chan_skinny.c.
char used_context[AST_MAX_EXTENSION] [static] |
Definition at line 177 of file chan_skinny.c.
char version_id[16] = "P002F202" [static] |
Definition at line 180 of file chan_skinny.c.