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