#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 = "ac1f6a56484a8820659555499174e588" , .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 6701 of file chan_skinny.c.
Referenced by config_load(), and config_parse_variables().
#define TYPE_DEF_LINE 4 |
Definition at line 6702 of file chan_skinny.c.
Referenced by config_load(), and config_parse_variables().
#define TYPE_DEVICE 8 |
Definition at line 6703 of file chan_skinny.c.
Referenced by config_device(), and config_parse_variables().
#define TYPE_GENERAL 1 |
Definition at line 6700 of file chan_skinny.c.
Referenced by config_load(), and config_parse_variables().
#define TYPE_LINE 16 |
Definition at line 6704 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 7608 of file chan_skinny.c.
static void __unreg_module | ( | void | ) | [static] |
Definition at line 7608 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 3251 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().
03252 { 03253 struct skinny_device *d; 03254 struct skinny_line *l; 03255 struct skinny_speeddial *sd; 03256 struct skinny_addon *sa; 03257 char codec_buf[512]; 03258 03259 if (argc < 4) { 03260 return CLI_SHOWUSAGE; 03261 } 03262 03263 AST_LIST_LOCK(&devices); 03264 AST_LIST_TRAVERSE(&devices, d, list) { 03265 if (!strcasecmp(argv[3], d->id) || !strcasecmp(argv[3], d->name)) { 03266 int numlines = 0, numaddons = 0, numspeeddials = 0; 03267 03268 AST_LIST_TRAVERSE(&d->lines, l, list){ 03269 numlines++; 03270 } 03271 03272 AST_LIST_TRAVERSE(&d->addons, sa, list) { 03273 numaddons++; 03274 } 03275 03276 AST_LIST_TRAVERSE(&d->speeddials, sd, list) { 03277 numspeeddials++; 03278 } 03279 03280 if (type == 0) { /* CLI */ 03281 ast_cli(fd, "Name: %s\n", d->name); 03282 ast_cli(fd, "Id: %s\n", d->id); 03283 ast_cli(fd, "version: %s\n", S_OR(d->version_id, "Unknown")); 03284 ast_cli(fd, "Ip address: %s\n", (d->session ? ast_inet_ntoa(d->session->sin.sin_addr) : "Unknown")); 03285 ast_cli(fd, "Port: %d\n", (d->session ? ntohs(d->session->sin.sin_port) : 0)); 03286 ast_cli(fd, "Device Type: %s\n", device2str(d->type)); 03287 ast_cli(fd, "Conf Codecs:"); 03288 ast_getformatname_multiple(codec_buf, sizeof(codec_buf) - 1, d->confcapability); 03289 ast_cli(fd, "%s\n", codec_buf); 03290 ast_cli(fd, "Neg Codecs: "); 03291 ast_getformatname_multiple(codec_buf, sizeof(codec_buf) - 1, d->capability); 03292 ast_cli(fd, "%s\n", codec_buf); 03293 ast_cli(fd, "Registered: %s\n", (d->registered ? "Yes" : "No")); 03294 ast_cli(fd, "Lines: %d\n", numlines); 03295 AST_LIST_TRAVERSE(&d->lines, l, list) { 03296 ast_cli(fd, " %s (%s)\n", l->name, l->label); 03297 } 03298 AST_LIST_TRAVERSE(&d->addons, sa, list) { 03299 numaddons++; 03300 } 03301 ast_cli(fd, "Addons: %d\n", numaddons); 03302 AST_LIST_TRAVERSE(&d->addons, sa, list) { 03303 ast_cli(fd, " %s\n", sa->type); 03304 } 03305 AST_LIST_TRAVERSE(&d->speeddials, sd, list) { 03306 numspeeddials++; 03307 } 03308 ast_cli(fd, "Speeddials: %d\n", numspeeddials); 03309 AST_LIST_TRAVERSE(&d->speeddials, sd, list) { 03310 ast_cli(fd, " %s (%s) ishint: %d\n", sd->exten, sd->label, sd->isHint); 03311 } 03312 } else { /* manager */ 03313 astman_append(s, "Channeltype: SKINNY\r\n"); 03314 astman_append(s, "ObjectName: %s\r\n", d->name); 03315 astman_append(s, "ChannelObjectType: device\r\n"); 03316 astman_append(s, "Id: %s\r\n", d->id); 03317 astman_append(s, "version: %s\r\n", S_OR(d->version_id, "Unknown")); 03318 astman_append(s, "Ipaddress: %s\r\n", (d->session ? ast_inet_ntoa(d->session->sin.sin_addr) : "Unknown")); 03319 astman_append(s, "Port: %d\r\n", (d->session ? ntohs(d->session->sin.sin_port) : 0)); 03320 astman_append(s, "DeviceType: %s\r\n", device2str(d->type)); 03321 astman_append(s, "Codecs: "); 03322 ast_getformatname_multiple(codec_buf, sizeof(codec_buf) -1, d->confcapability); 03323 astman_append(s, "%s\r\n", codec_buf); 03324 astman_append(s, "CodecOrder: "); 03325 ast_getformatname_multiple(codec_buf, sizeof(codec_buf) -1, d->capability); 03326 astman_append(s, "%s\r\n", codec_buf); 03327 astman_append(s, "Devicestatus: %s\r\n", (d->registered?"registered":"unregistered")); 03328 astman_append(s, "NumberOfLines: %d\r\n", numlines); 03329 AST_LIST_TRAVERSE(&d->lines, l, list) { 03330 astman_append(s, "Line: %s (%s)\r\n", l->name, l->label); 03331 } 03332 astman_append(s, "NumberOfAddons: %d\r\n", numaddons); 03333 AST_LIST_TRAVERSE(&d->addons, sa, list) { 03334 astman_append(s, "Addon: %s\r\n", sa->type); 03335 } 03336 astman_append(s, "NumberOfSpeeddials: %d\r\n", numspeeddials); 03337 AST_LIST_TRAVERSE(&d->speeddials, sd, list) { 03338 astman_append(s, "Speeddial: %s (%s) ishint: %d\r\n", sd->exten, sd->label, sd->isHint); 03339 } 03340 } 03341 } 03342 } 03343 AST_LIST_UNLOCK(&devices); 03344 return CLI_SUCCESS; 03345 }
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 3140 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().
03141 { 03142 struct skinny_device *d; 03143 struct skinny_line *l; 03144 const char *id; 03145 char idtext[256] = ""; 03146 int total_devices = 0; 03147 03148 if (s) { /* Manager - get ActionID */ 03149 id = astman_get_header(m, "ActionID"); 03150 if (!ast_strlen_zero(id)) 03151 snprintf(idtext, sizeof(idtext), "ActionID: %s\r\n", id); 03152 } 03153 03154 switch (argc) { 03155 case 3: 03156 break; 03157 default: 03158 return CLI_SHOWUSAGE; 03159 } 03160 03161 if (!s) { 03162 ast_cli(fd, "Name DeviceId IP Type R NL\n"); 03163 ast_cli(fd, "-------------------- ---------------- --------------- --------------- - --\n"); 03164 } 03165 03166 AST_LIST_LOCK(&devices); 03167 AST_LIST_TRAVERSE(&devices, d, list) { 03168 int numlines = 0; 03169 total_devices++; 03170 AST_LIST_TRAVERSE(&d->lines, l, list) { 03171 numlines++; 03172 } 03173 if (!s) { 03174 ast_cli(fd, "%-20s %-16s %-15s %-15s %c %2d\n", 03175 d->name, 03176 d->id, 03177 d->session?ast_inet_ntoa(d->session->sin.sin_addr):"", 03178 device2str(d->type), 03179 d->registered?'Y':'N', 03180 numlines); 03181 } else { 03182 astman_append(s, 03183 "Event: DeviceEntry\r\n%s" 03184 "Channeltype: SKINNY\r\n" 03185 "ObjectName: %s\r\n" 03186 "ChannelObjectType: device\r\n" 03187 "DeviceId: %s\r\n" 03188 "IPaddress: %s\r\n" 03189 "Type: %s\r\n" 03190 "Devicestatus: %s\r\n" 03191 "NumberOfLines: %d\r\n", 03192 idtext, 03193 d->name, 03194 d->id, 03195 d->session?ast_inet_ntoa(d->session->sin.sin_addr):"-none-", 03196 device2str(d->type), 03197 d->registered?"registered":"unregistered", 03198 numlines); 03199 } 03200 } 03201 AST_LIST_UNLOCK(&devices); 03202 03203 if (total) 03204 *total = total_devices; 03205 03206 return CLI_SUCCESS; 03207 }
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 3508 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().
03509 { 03510 struct skinny_device *d; 03511 struct skinny_line *l; 03512 struct ast_codec_pref *pref; 03513 int x = 0, codec = 0; 03514 char codec_buf[512]; 03515 char group_buf[256]; 03516 char cbuf[256]; 03517 03518 switch (argc) { 03519 case 4: 03520 break; 03521 case 6: 03522 break; 03523 default: 03524 return CLI_SHOWUSAGE; 03525 } 03526 03527 AST_LIST_LOCK(&devices); 03528 03529 /* Show all lines matching the one supplied */ 03530 AST_LIST_TRAVERSE(&devices, d, list) { 03531 if (argc == 6 && (strcasecmp(argv[5], d->id) && strcasecmp(argv[5], d->name))) { 03532 continue; 03533 } 03534 AST_LIST_TRAVERSE(&d->lines, l, list) { 03535 if (strcasecmp(argv[3], l->name)) { 03536 continue; 03537 } 03538 if (type == 0) { /* CLI */ 03539 ast_cli(fd, "Line: %s\n", l->name); 03540 ast_cli(fd, "On Device: %s\n", d->name); 03541 ast_cli(fd, "Line Label: %s\n", l->label); 03542 ast_cli(fd, "Extension: %s\n", S_OR(l->exten, "<not set>")); 03543 ast_cli(fd, "Context: %s\n", l->context); 03544 ast_cli(fd, "CallGroup: %s\n", ast_print_group(group_buf, sizeof(group_buf), l->callgroup)); 03545 ast_cli(fd, "PickupGroup: %s\n", ast_print_group(group_buf, sizeof(group_buf), l->pickupgroup)); 03546 ast_cli(fd, "Language: %s\n", S_OR(l->language, "<not set>")); 03547 ast_cli(fd, "Accountcode: %s\n", S_OR(l->accountcode, "<not set>")); 03548 ast_cli(fd, "AmaFlag: %s\n", ast_cdr_flags2str(l->amaflags)); 03549 ast_cli(fd, "CallerId Number: %s\n", S_OR(l->cid_num, "<not set>")); 03550 ast_cli(fd, "CallerId Name: %s\n", S_OR(l->cid_name, "<not set>")); 03551 ast_cli(fd, "Hide CallerId: %s\n", (l->hidecallerid ? "Yes" : "No")); 03552 ast_cli(fd, "CFwdAll: %s\n", S_COR((l->cfwdtype & SKINNY_CFWD_ALL), l->call_forward_all, "<not set>")); 03553 ast_cli(fd, "CFwdBusy: %s\n", S_COR((l->cfwdtype & SKINNY_CFWD_BUSY), l->call_forward_busy, "<not set>")); 03554 ast_cli(fd, "CFwdNoAnswer: %s\n", S_COR((l->cfwdtype & SKINNY_CFWD_NOANSWER), l->call_forward_noanswer, "<not set>")); 03555 ast_cli(fd, "VoicemailBox: %s\n", S_OR(l->mailbox, "<not set>")); 03556 ast_cli(fd, "VoicemailNumber: %s\n", S_OR(l->vmexten, "<not set>")); 03557 ast_cli(fd, "MWIblink: %d\n", l->mwiblink); 03558 ast_cli(fd, "Regextension: %s\n", S_OR(l->regexten, "<not set>")); 03559 ast_cli(fd, "Regcontext: %s\n", S_OR(l->regcontext, "<not set>")); 03560 ast_cli(fd, "MoHInterpret: %s\n", S_OR(l->mohinterpret, "<not set>")); 03561 ast_cli(fd, "MoHSuggest: %s\n", S_OR(l->mohsuggest, "<not set>")); 03562 ast_cli(fd, "Last dialed nr: %s\n", S_OR(l->lastnumberdialed, "<no calls made yet>")); 03563 ast_cli(fd, "Last CallerID: %s\n", S_OR(l->lastcallerid, "<not set>")); 03564 ast_cli(fd, "Transfer enabled: %s\n", (l->transfer ? "Yes" : "No")); 03565 ast_cli(fd, "Callwaiting: %s\n", (l->callwaiting ? "Yes" : "No")); 03566 ast_cli(fd, "3Way Calling: %s\n", (l->threewaycalling ? "Yes" : "No")); 03567 ast_cli(fd, "Can forward: %s\n", (l->cancallforward ? "Yes" : "No")); 03568 ast_cli(fd, "Do Not Disturb: %s\n", (l->dnd ? "Yes" : "No")); 03569 ast_cli(fd, "NAT: %s\n", (l->nat ? "Yes" : "No")); 03570 ast_cli(fd, "immediate: %s\n", (l->immediate ? "Yes" : "No")); 03571 ast_cli(fd, "Group: %d\n", l->group); 03572 ast_cli(fd, "Parkinglot: %s\n", S_OR(l->parkinglot, "<not set>")); 03573 ast_cli(fd, "Conf Codecs: "); 03574 ast_getformatname_multiple(codec_buf, sizeof(codec_buf) - 1, l->confcapability); 03575 ast_cli(fd, "%s\n", codec_buf); 03576 ast_cli(fd, "Neg Codecs: "); 03577 ast_getformatname_multiple(codec_buf, sizeof(codec_buf) - 1, l->capability); 03578 ast_cli(fd, "%s\n", codec_buf); 03579 ast_cli(fd, "Codec Order: ("); 03580 print_codec_to_cli(fd, &l->prefs); 03581 ast_cli(fd, ")\n"); 03582 ast_cli(fd, "\n"); 03583 } else { /* manager */ 03584 astman_append(s, "Channeltype: SKINNY\r\n"); 03585 astman_append(s, "ObjectName: %s\r\n", l->name); 03586 astman_append(s, "ChannelObjectType: line\r\n"); 03587 astman_append(s, "Device: %s\r\n", d->name); 03588 astman_append(s, "LineLabel: %s\r\n", l->label); 03589 astman_append(s, "Extension: %s\r\n", S_OR(l->exten, "<not set>")); 03590 astman_append(s, "Context: %s\r\n", l->context); 03591 astman_append(s, "CallGroup: %s\r\n", ast_print_group(group_buf, sizeof(group_buf), l->callgroup)); 03592 astman_append(s, "PickupGroup: %s\r\n", ast_print_group(group_buf, sizeof(group_buf), l->pickupgroup)); 03593 astman_append(s, "Language: %s\r\n", S_OR(l->language, "<not set>")); 03594 astman_append(s, "Accountcode: %s\r\n", S_OR(l->accountcode, "<not set>")); 03595 astman_append(s, "AMAflags: %s\r\n", ast_cdr_flags2str(l->amaflags)); 03596 astman_append(s, "Callerid: %s\r\n", ast_callerid_merge(cbuf, sizeof(cbuf), l->cid_name, l->cid_num, "")); 03597 astman_append(s, "HideCallerId: %s\r\n", (l->hidecallerid ? "Yes" : "No")); 03598 astman_append(s, "CFwdAll: %s\r\n", S_COR((l->cfwdtype & SKINNY_CFWD_ALL), l->call_forward_all, "<not set>")); 03599 astman_append(s, "CFwdBusy: %s\r\n", S_COR((l->cfwdtype & SKINNY_CFWD_BUSY), l->call_forward_busy, "<not set>")); 03600 astman_append(s, "CFwdNoAnswer: %s\r\n", S_COR((l->cfwdtype & SKINNY_CFWD_NOANSWER), l->call_forward_noanswer, "<not set>")); 03601 astman_append(s, "VoicemailBox: %s\r\n", S_OR(l->mailbox, "<not set>")); 03602 astman_append(s, "VoicemailNumber: %s\r\n", S_OR(l->vmexten, "<not set>")); 03603 astman_append(s, "MWIblink: %d\r\n", l->mwiblink); 03604 astman_append(s, "RegExtension: %s\r\n", S_OR(l->regexten, "<not set>")); 03605 astman_append(s, "Regcontext: %s\r\n", S_OR(l->regcontext, "<not set>")); 03606 astman_append(s, "MoHInterpret: %s\r\n", S_OR(l->mohinterpret, "<not set>")); 03607 astman_append(s, "MoHSuggest: %s\r\n", S_OR(l->mohsuggest, "<not set>")); 03608 astman_append(s, "LastDialedNr: %s\r\n", S_OR(l->lastnumberdialed, "<no calls made yet>")); 03609 astman_append(s, "LastCallerID: %s\r\n", S_OR(l->lastcallerid, "<not set>")); 03610 astman_append(s, "Transfer: %s\r\n", (l->transfer ? "Yes" : "No")); 03611 astman_append(s, "Callwaiting: %s\r\n", (l->callwaiting ? "Yes" : "No")); 03612 astman_append(s, "3WayCalling: %s\r\n", (l->threewaycalling ? "Yes" : "No")); 03613 astman_append(s, "CanForward: %s\r\n", (l->cancallforward ? "Yes" : "No")); 03614 astman_append(s, "DoNotDisturb: %s\r\n", (l->dnd ? "Yes" : "No")); 03615 astman_append(s, "NAT: %s\r\n", (l->nat ? "Yes" : "No")); 03616 astman_append(s, "immediate: %s\r\n", (l->immediate ? "Yes" : "No")); 03617 astman_append(s, "Group: %d\r\n", l->group); 03618 astman_append(s, "Parkinglot: %s\r\n", S_OR(l->parkinglot, "<not set>")); 03619 ast_getformatname_multiple(codec_buf, sizeof(codec_buf) - 1, l->confcapability); 03620 astman_append(s, "Codecs: %s\r\n", codec_buf); 03621 astman_append(s, "CodecOrder: "); 03622 pref = &l->prefs; 03623 for(x = 0; x < 32 ; x++) { 03624 codec = ast_codec_pref_index(pref, x); 03625 if (!codec) 03626 break; 03627 astman_append(s, "%s", ast_getformatname(codec)); 03628 if (x < 31 && ast_codec_pref_index(pref, x+1)) 03629 astman_append(s, ","); 03630 } 03631 astman_append(s, "\r\n"); 03632 } 03633 } 03634 } 03635 03636 AST_LIST_UNLOCK(&devices); 03637 return CLI_SUCCESS; 03638 }
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 3384 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().
03385 { 03386 struct skinny_line *l; 03387 struct skinny_subchannel *sub; 03388 int total_lines = 0; 03389 int verbose = 0; 03390 const char *id; 03391 char idtext[256] = ""; 03392 03393 if (s) { /* Manager - get ActionID */ 03394 id = astman_get_header(m, "ActionID"); 03395 if (!ast_strlen_zero(id)) 03396 snprintf(idtext, sizeof(idtext), "ActionID: %s\r\n", id); 03397 } 03398 03399 switch (argc) { 03400 case 4: 03401 verbose = 1; 03402 break; 03403 case 3: 03404 verbose = 0; 03405 break; 03406 default: 03407 return CLI_SHOWUSAGE; 03408 } 03409 03410 if (!s) { 03411 ast_cli(fd, "Name Device Name Instance Label \n"); 03412 ast_cli(fd, "-------------------- -------------------- -------- --------------------\n"); 03413 } 03414 AST_LIST_LOCK(&lines); 03415 AST_LIST_TRAVERSE(&lines, l, all) { 03416 total_lines++; 03417 if (!s) { 03418 ast_cli(fd, "%-20s %-20s %8d %-20s\n", 03419 l->name, 03420 (l->device ? l->device->name : "Not connected"), 03421 l->instance, 03422 l->label); 03423 if (verbose) { 03424 AST_LIST_TRAVERSE(&l->sub, sub, list) { 03425 ast_cli(fd, " %s> %s to %s\n", 03426 (sub == l->activesub?"Active ":"Inactive"), 03427 sub->owner->name, 03428 (ast_bridged_channel(sub->owner)?ast_bridged_channel(sub->owner)->name:"") 03429 ); 03430 } 03431 } 03432 } else { 03433 astman_append(s, 03434 "Event: LineEntry\r\n%s" 03435 "Channeltype: SKINNY\r\n" 03436 "ObjectName: %s\r\n" 03437 "ChannelObjectType: line\r\n" 03438 "Device: %s\r\n" 03439 "Instance: %d\r\n" 03440 "Label: %s\r\n", 03441 idtext, 03442 l->name, 03443 (l->device?l->device->name:"None"), 03444 l->instance, 03445 l->label); 03446 } 03447 } 03448 AST_LIST_UNLOCK(&lines); 03449 03450 if (total) { 03451 *total = total_lines; 03452 } 03453 03454 return CLI_SUCCESS; 03455 }
static void* accept_thread | ( | void * | ignore | ) | [static] |
Definition at line 6545 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().
06546 { 06547 int as; 06548 struct sockaddr_in sin; 06549 socklen_t sinlen; 06550 struct skinnysession *s; 06551 struct protoent *p; 06552 int arg = 1; 06553 06554 for (;;) { 06555 sinlen = sizeof(sin); 06556 as = accept(skinnysock, (struct sockaddr *)&sin, &sinlen); 06557 if (as < 0) { 06558 ast_log(LOG_NOTICE, "Accept returned -1: %s\n", strerror(errno)); 06559 continue; 06560 } 06561 06562 if (ast_atomic_fetchadd_int(&unauth_sessions, +1) >= auth_limit) { 06563 close(as); 06564 ast_atomic_fetchadd_int(&unauth_sessions, -1); 06565 continue; 06566 } 06567 06568 p = getprotobyname("tcp"); 06569 if(p) { 06570 if( setsockopt(as, p->p_proto, TCP_NODELAY, (char *)&arg, sizeof(arg) ) < 0 ) { 06571 ast_log(LOG_WARNING, "Failed to set Skinny tcp connection to TCP_NODELAY mode: %s\n", strerror(errno)); 06572 } 06573 } 06574 if (!(s = ast_calloc(1, sizeof(struct skinnysession)))) { 06575 close(as); 06576 ast_atomic_fetchadd_int(&unauth_sessions, -1); 06577 continue; 06578 } 06579 06580 memcpy(&s->sin, &sin, sizeof(sin)); 06581 ast_mutex_init(&s->lock); 06582 s->fd = as; 06583 06584 if(time(&s->start) == -1) { 06585 ast_log(LOG_ERROR, "error executing time(): %s; disconnecting client\n", strerror(errno)); 06586 destroy_session(s); 06587 continue; 06588 } 06589 06590 AST_LIST_LOCK(&sessions); 06591 AST_LIST_INSERT_HEAD(&sessions, s, list); 06592 AST_LIST_UNLOCK(&sessions); 06593 06594 if (ast_pthread_create(&s->t, NULL, skinny_session, s)) { 06595 destroy_session(s); 06596 } 06597 } 06598 if (skinnydebug) 06599 ast_verb(1, "killing accept thread\n"); 06600 close(as); 06601 return 0; 06602 }
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 2944 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().
02945 { 02946 struct skinny_device *d; 02947 char *result = NULL; 02948 int wordlen = strlen(word), which = 0; 02949 02950 AST_LIST_TRAVERSE(&devices, d, list) { 02951 if (!strncasecmp(word, d->id, wordlen) && ++which > state) 02952 result = ast_strdup(d->id); 02953 } 02954 02955 return result; 02956 }
static char* complete_skinny_reset | ( | const char * | line, | |
const char * | word, | |||
int | pos, | |||
int | state | |||
) | [static] |
Definition at line 2963 of file chan_skinny.c.
References ast_strdup, and complete_skinny_devices().
Referenced by handle_skinny_reset().
02964 { 02965 return (pos == 2 ? ast_strdup(complete_skinny_devices(word, state)) : NULL); 02966 }
static char* complete_skinny_show_device | ( | const char * | line, | |
const char * | word, | |||
int | pos, | |||
int | state | |||
) | [static] |
Definition at line 2958 of file chan_skinny.c.
References ast_strdup, and complete_skinny_devices().
Referenced by handle_skinny_show_device().
02959 { 02960 return (pos == 3 ? ast_strdup(complete_skinny_devices(word, state)) : NULL); 02961 }
static char* complete_skinny_show_line | ( | const char * | line, | |
const char * | word, | |||
int | pos, | |||
int | state | |||
) | [static] |
Definition at line 2968 of file chan_skinny.c.
References AST_LIST_TRAVERSE, ast_strdup, skinny_device::lines, and skinny_subchannel::list.
Referenced by handle_skinny_show_line().
02969 { 02970 struct skinny_device *d; 02971 struct skinny_line *l; 02972 char *result = NULL; 02973 int wordlen = strlen(word), which = 0; 02974 02975 if (pos != 3) 02976 return NULL; 02977 02978 AST_LIST_TRAVERSE(&devices, d, list) { 02979 AST_LIST_TRAVERSE(&d->lines, l, list) { 02980 if (!strncasecmp(word, l->name, wordlen) && ++which > state) 02981 result = ast_strdup(l->name); 02982 } 02983 } 02984 02985 return result; 02986 }
static struct skinny_device* config_device | ( | const char * | dname, | |
struct ast_variable * | v | |||
) | [static] |
Definition at line 7163 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().
07164 { 07165 struct skinny_device *d, *temp; 07166 struct skinny_line *l, *ltemp; 07167 struct skinny_subchannel *sub; 07168 int update = 0; 07169 07170 ast_log(LOG_NOTICE, "Configuring skinny device %s.\n", dname); 07171 07172 AST_LIST_LOCK(&devices); 07173 AST_LIST_TRAVERSE(&devices, temp, list) { 07174 if (!strcasecmp(dname, temp->name) && temp->prune) { 07175 update = 1; 07176 break; 07177 } 07178 } 07179 07180 if (!(d = ast_calloc(1, sizeof(*d)))) { 07181 ast_verb(1, "Unable to allocate memory for device %s.\n", dname); 07182 AST_LIST_UNLOCK(&devices); 07183 return NULL; 07184 } 07185 memcpy(d, default_device, sizeof(*default_device)); 07186 ast_mutex_init(&d->lock); 07187 ast_copy_string(d->name, dname, sizeof(d->name)); 07188 AST_LIST_INSERT_TAIL(&devices, d, list); 07189 07190 ast_mutex_lock(&d->lock); 07191 AST_LIST_UNLOCK(&devices); 07192 07193 config_parse_variables(TYPE_DEVICE, d, v); 07194 07195 if (!AST_LIST_FIRST(&d->lines)) { 07196 ast_log(LOG_ERROR, "A Skinny device must have at least one line!\n"); 07197 ast_mutex_unlock(&d->lock); 07198 return NULL; 07199 } 07200 if (/*d->addr.sin_addr.s_addr && */!ntohs(d->addr.sin_port)) { 07201 d->addr.sin_port = htons(DEFAULT_SKINNY_PORT); 07202 } 07203 07204 if (skinnyreload){ 07205 AST_LIST_LOCK(&devices); 07206 AST_LIST_TRAVERSE(&devices, temp, list) { 07207 if (strcasecmp(d->id, temp->id) || !temp->prune || !temp->session) { 07208 continue; 07209 } 07210 ast_mutex_lock(&d->lock); 07211 d->session = temp->session; 07212 d->session->device = d; 07213 07214 AST_LIST_LOCK(&d->lines); 07215 AST_LIST_TRAVERSE(&d->lines, l, list){ 07216 l->device = d; 07217 07218 AST_LIST_LOCK(&temp->lines); 07219 AST_LIST_TRAVERSE(&temp->lines, ltemp, list) { 07220 if (strcasecmp(l->name, ltemp->name)) { 07221 continue; 07222 } 07223 ast_mutex_lock(<emp->lock); 07224 l->instance = ltemp->instance; 07225 l->hookstate = ltemp->hookstate; 07226 if (!AST_LIST_EMPTY(<emp->sub)) { 07227 ast_mutex_lock(&l->lock); 07228 l->sub = ltemp->sub; 07229 AST_LIST_TRAVERSE(&l->sub, sub, list) { 07230 sub->parent = l; 07231 } 07232 ast_mutex_unlock(&l->lock); 07233 } 07234 ast_mutex_unlock(<emp->lock); 07235 } 07236 AST_LIST_UNLOCK(&temp->lines); 07237 } 07238 AST_LIST_UNLOCK(&d->lines); 07239 ast_mutex_unlock(&d->lock); 07240 } 07241 AST_LIST_UNLOCK(&devices); 07242 } 07243 07244 ast_mutex_unlock(&d->lock); 07245 07246 ast_verb(3, "%s config for device '%s'\n", update ? "Updated" : (skinnyreload ? "Reloaded" : "Created"), d->name); 07247 07248 return d; 07249 07250 }
static struct skinny_line* config_line | ( | const char * | lname, | |
struct ast_variable * | v | |||
) | [static] |
Definition at line 7105 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().
07106 { 07107 struct skinny_line *l, *temp; 07108 int update = 0; 07109 07110 ast_log(LOG_NOTICE, "Configuring skinny line %s.\n", lname); 07111 07112 /* We find the old line and remove it just before the new 07113 line is created */ 07114 AST_LIST_LOCK(&lines); 07115 AST_LIST_TRAVERSE(&lines, temp, all) { 07116 if (!strcasecmp(lname, temp->name) && temp->prune) { 07117 update = 1; 07118 break; 07119 } 07120 } 07121 07122 if (!(l=ast_calloc(1, sizeof(*l)))) { 07123 ast_verb(1, "Unable to allocate memory for line %s.\n", lname); 07124 AST_LIST_UNLOCK(&lines); 07125 return NULL; 07126 } 07127 07128 memcpy(l, default_line, sizeof(*default_line)); 07129 ast_mutex_init(&l->lock); 07130 ast_copy_string(l->name, lname, sizeof(l->name)); 07131 AST_LIST_INSERT_TAIL(&lines, l, all); 07132 07133 ast_mutex_lock(&l->lock); 07134 AST_LIST_UNLOCK(&lines); 07135 07136 config_parse_variables(TYPE_LINE, l, v); 07137 07138 if (!ast_strlen_zero(l->mailbox)) { 07139 char *cfg_mailbox, *cfg_context; 07140 cfg_context = cfg_mailbox = ast_strdupa(l->mailbox); 07141 ast_verb(3, "Setting mailbox '%s' on line %s\n", cfg_mailbox, l->name); 07142 strsep(&cfg_context, "@"); 07143 if (ast_strlen_zero(cfg_context)) 07144 cfg_context = "default"; 07145 l->mwi_event_sub = ast_event_subscribe(AST_EVENT_MWI, mwi_event_cb, "skinny MWI subsciption", l, 07146 AST_EVENT_IE_MAILBOX, AST_EVENT_IE_PLTYPE_STR, cfg_mailbox, 07147 AST_EVENT_IE_CONTEXT, AST_EVENT_IE_PLTYPE_STR, cfg_context, 07148 AST_EVENT_IE_NEWMSGS, AST_EVENT_IE_PLTYPE_EXISTS, 07149 AST_EVENT_IE_END); 07150 } 07151 07152 ast_mutex_unlock(&l->lock); 07153 07154 /* We do not want to unlink or free the line yet, it needs 07155 to be available to detect a device reconfig when we load the 07156 devices. Old lines will be pruned after the reload completes */ 07157 07158 ast_verb(3, "%s config for line '%s'\n", update ? "Updated" : (skinnyreload ? "Reloaded" : "Created"), l->name); 07159 07160 return l; 07161 }
static int config_load | ( | void | ) | [static] |
Definition at line 7252 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_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().
07253 { 07254 int on = 1; 07255 struct ast_config *cfg; 07256 char *cat; 07257 int oldport = ntohs(bindaddr.sin_port); 07258 struct ast_flags config_flags = { 0 }; 07259 07260 ast_log(LOG_NOTICE, "Configuring skinny from %s\n", config); 07261 07262 if (gethostname(ourhost, sizeof(ourhost))) { 07263 ast_log(LOG_WARNING, "Unable to get hostname, Skinny disabled.\n"); 07264 return 0; 07265 } 07266 cfg = ast_config_load(config, config_flags); 07267 07268 /* We *must* have a config file otherwise stop immediately */ 07269 if (!cfg || cfg == CONFIG_STATUS_FILEINVALID) { 07270 ast_log(LOG_NOTICE, "Unable to load config %s, Skinny disabled.\n", config); 07271 return -1; 07272 } 07273 memset(&bindaddr, 0, sizeof(bindaddr)); 07274 memset(&default_prefs, 0, sizeof(default_prefs)); 07275 07276 /* Copy the default jb config over global_jbconf */ 07277 memcpy(&global_jbconf, &default_jbconf, sizeof(struct ast_jb_conf)); 07278 07279 /* load the general section */ 07280 cat = ast_category_browse(cfg, "general"); 07281 config_parse_variables(TYPE_GENERAL, NULL, ast_variable_browse(cfg, "general")); 07282 07283 if (ntohl(bindaddr.sin_addr.s_addr)) { 07284 __ourip = bindaddr.sin_addr; 07285 } else { 07286 hp = ast_gethostbyname(ourhost, &ahp); 07287 if (!hp) { 07288 ast_log(LOG_WARNING, "Unable to get our IP address, Skinny disabled\n"); 07289 ast_config_destroy(cfg); 07290 return 0; 07291 } 07292 memcpy(&__ourip, hp->h_addr, sizeof(__ourip)); 07293 } 07294 if (!ntohs(bindaddr.sin_port)) { 07295 bindaddr.sin_port = htons(DEFAULT_SKINNY_PORT); 07296 } 07297 bindaddr.sin_family = AF_INET; 07298 07299 /* load the lines sections */ 07300 default_line->confcapability = default_capability; 07301 default_line->confprefs = default_prefs; 07302 config_parse_variables(TYPE_DEF_LINE, default_line, ast_variable_browse(cfg, "lines")); 07303 cat = ast_category_browse(cfg, "lines"); 07304 while (cat && strcasecmp(cat, "general") && strcasecmp(cat, "devices")) { 07305 config_line(cat, ast_variable_browse(cfg, cat)); 07306 cat = ast_category_browse(cfg, cat); 07307 } 07308 07309 /* load the devices sections */ 07310 default_device->confcapability = default_capability; 07311 default_device->confprefs = default_prefs; 07312 config_parse_variables(TYPE_DEF_DEVICE, default_device, ast_variable_browse(cfg, "devices")); 07313 cat = ast_category_browse(cfg, "devices"); 07314 while (cat && strcasecmp(cat, "general") && strcasecmp(cat, "lines")) { 07315 config_device(cat, ast_variable_browse(cfg, cat)); 07316 cat = ast_category_browse(cfg, cat); 07317 } 07318 07319 ast_mutex_lock(&netlock); 07320 if ((skinnysock > -1) && (ntohs(bindaddr.sin_port) != oldport)) { 07321 close(skinnysock); 07322 skinnysock = -1; 07323 } 07324 if (skinnysock < 0) { 07325 skinnysock = socket(AF_INET, SOCK_STREAM, 0); 07326 if(setsockopt(skinnysock, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on)) == -1) { 07327 ast_log(LOG_ERROR, "Set Socket Options failed: errno %d, %s\n", errno, strerror(errno)); 07328 ast_config_destroy(cfg); 07329 ast_mutex_unlock(&netlock); 07330 return 0; 07331 } 07332 if (skinnysock < 0) { 07333 ast_log(LOG_WARNING, "Unable to create Skinny socket: %s\n", strerror(errno)); 07334 } else { 07335 if (bind(skinnysock, (struct sockaddr *)&bindaddr, sizeof(bindaddr)) < 0) { 07336 ast_log(LOG_WARNING, "Failed to bind to %s:%d: %s\n", 07337 ast_inet_ntoa(bindaddr.sin_addr), ntohs(bindaddr.sin_port), 07338 strerror(errno)); 07339 close(skinnysock); 07340 skinnysock = -1; 07341 ast_config_destroy(cfg); 07342 ast_mutex_unlock(&netlock); 07343 return 0; 07344 } 07345 if (listen(skinnysock, DEFAULT_SKINNY_BACKLOG)) { 07346 ast_log(LOG_WARNING, "Failed to start listening to %s:%d: %s\n", 07347 ast_inet_ntoa(bindaddr.sin_addr), ntohs(bindaddr.sin_port), 07348 strerror(errno)); 07349 close(skinnysock); 07350 skinnysock = -1; 07351 ast_config_destroy(cfg); 07352 ast_mutex_unlock(&netlock); 07353 return 0; 07354 } 07355 ast_verb(2, "Skinny listening on %s:%d\n", 07356 ast_inet_ntoa(bindaddr.sin_addr), ntohs(bindaddr.sin_port)); 07357 ast_netsock_set_qos(skinnysock, qos.tos, qos.cos, "Skinny"); 07358 ast_pthread_create_background(&accept_t, NULL, accept_thread, NULL); 07359 } 07360 } 07361 ast_mutex_unlock(&netlock); 07362 ast_config_destroy(cfg); 07363 return 1; 07364 }
static void config_parse_variables | ( | int | type, | |
void * | item, | |||
struct ast_variable * | vptr | |||
) | [static] |
Definition at line 6711 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().
06712 { 06713 struct ast_variable *v; 06714 int lineInstance = 1; 06715 int speeddialInstance = 1; 06716 06717 while(vptr) { 06718 v = vptr; 06719 vptr = vptr->next; 06720 06721 if (type & (TYPE_GENERAL)) { 06722 char newcontexts[AST_MAX_CONTEXT]; 06723 char oldcontexts[AST_MAX_CONTEXT]; 06724 char *stringp, *context, *oldregcontext; 06725 if (!ast_jb_read_conf(&global_jbconf, v->name, v->value)) { 06726 v = v->next; 06727 continue; 06728 } 06729 if (!strcasecmp(v->name, "bindaddr")) { 06730 if (!(hp = ast_gethostbyname(v->value, &ahp))) { 06731 ast_log(LOG_WARNING, "Invalid address: %s\n", v->value); 06732 } else { 06733 memcpy(&bindaddr.sin_addr, hp->h_addr, sizeof(bindaddr.sin_addr)); 06734 } 06735 continue; 06736 } else if (!strcasecmp(v->name, "keepalive")) { 06737 keep_alive = atoi(v->value); 06738 continue; 06739 } else if (!strcasecmp(v->name, "authtimeout")) { 06740 int timeout = atoi(v->value); 06741 06742 if (timeout < 1) { 06743 ast_log(LOG_WARNING, "Invalid authtimeout value '%s', using default value\n", v->value); 06744 auth_timeout = DEFAULT_AUTH_TIMEOUT; 06745 } else { 06746 auth_timeout = timeout; 06747 } 06748 continue; 06749 } else if (!strcasecmp(v->name, "authlimit")) { 06750 int limit = atoi(v->value); 06751 06752 if (limit < 1) { 06753 ast_log(LOG_WARNING, "Invalid authlimit value '%s', using default value\n", v->value); 06754 auth_limit = DEFAULT_AUTH_LIMIT; 06755 } else { 06756 auth_limit = limit; 06757 } 06758 continue; 06759 } else if (!strcasecmp(v->name, "regcontext")) { 06760 ast_copy_string(newcontexts, v->value, sizeof(newcontexts)); 06761 stringp = newcontexts; 06762 /* Initialize copy of current global_regcontext for later use in removing stale contexts */ 06763 ast_copy_string(oldcontexts, regcontext, sizeof(oldcontexts)); 06764 oldregcontext = oldcontexts; 06765 /* Let's remove any contexts that are no longer defined in regcontext */ 06766 cleanup_stale_contexts(stringp, oldregcontext); 06767 /* Create contexts if they don't exist already */ 06768 while ((context = strsep(&stringp, "&"))) { 06769 ast_copy_string(used_context, context, sizeof(used_context)); 06770 ast_context_find_or_create(NULL, NULL, context, "Skinny"); 06771 } 06772 ast_copy_string(regcontext, v->value, sizeof(regcontext)); 06773 continue; 06774 } else if (!strcasecmp(v->name, "dateformat")) { 06775 memcpy(date_format, v->value, sizeof(date_format)); 06776 continue; 06777 } else if (!strcasecmp(v->name, "tos")) { 06778 if (ast_str2tos(v->value, &qos.tos)) 06779 ast_log(LOG_WARNING, "Invalid tos value at line %d, refer to QoS documentation\n", v->lineno); 06780 continue; 06781 } else if (!strcasecmp(v->name, "tos_audio")) { 06782 if (ast_str2tos(v->value, &qos.tos_audio)) 06783 ast_log(LOG_WARNING, "Invalid tos_audio value at line %d, refer to QoS documentation\n", v->lineno); 06784 continue; 06785 } else if (!strcasecmp(v->name, "tos_video")) { 06786 if (ast_str2tos(v->value, &qos.tos_video)) 06787 ast_log(LOG_WARNING, "Invalid tos_video value at line %d, refer to QoS documentation\n", v->lineno); 06788 continue; 06789 } else if (!strcasecmp(v->name, "cos")) { 06790 if (ast_str2cos(v->value, &qos.cos)) 06791 ast_log(LOG_WARNING, "Invalid cos value at line %d, refer to QoS documentation\n", v->lineno); 06792 continue; 06793 } else if (!strcasecmp(v->name, "cos_audio")) { 06794 if (ast_str2cos(v->value, &qos.cos_audio)) 06795 ast_log(LOG_WARNING, "Invalid cos_audio value at line %d, refer to QoS documentation\n", v->lineno); 06796 continue; 06797 } else if (!strcasecmp(v->name, "cos_video")) { 06798 if (ast_str2cos(v->value, &qos.cos_video)) 06799 ast_log(LOG_WARNING, "Invalid cos_video value at line %d, refer to QoS documentation\n", v->lineno); 06800 continue; 06801 } else if (!strcasecmp(v->name, "bindport")) { 06802 if (sscanf(v->value, "%5d", &ourport) == 1) { 06803 bindaddr.sin_port = htons(ourport); 06804 } else { 06805 ast_log(LOG_WARNING, "Invalid bindport '%s' at line %d of %s\n", v->value, v->lineno, config); 06806 } 06807 continue; 06808 } else if (!strcasecmp(v->name, "allow")) { 06809 ast_parse_allow_disallow(&default_prefs, &default_capability, v->value, 1); 06810 continue; 06811 } else if (!strcasecmp(v->name, "disallow")) { 06812 ast_parse_allow_disallow(&default_prefs, &default_capability, v->value, 0); 06813 continue; 06814 } 06815 } 06816 06817 if (!strcasecmp(v->name, "transfer")) { 06818 if (type & (TYPE_DEF_DEVICE | TYPE_DEVICE)) { 06819 CDEV_OPTS->transfer = ast_true(v->value); 06820 continue; 06821 } else if (type & (TYPE_DEF_LINE | TYPE_LINE)) { 06822 CLINE_OPTS->transfer = ast_true(v->value); 06823 continue; 06824 } 06825 } else if (!strcasecmp(v->name, "callwaiting")) { 06826 if (type & (TYPE_DEF_DEVICE | TYPE_DEVICE)) { 06827 CDEV_OPTS->callwaiting = ast_true(v->value); 06828 continue; 06829 } else if (type & (TYPE_DEF_LINE | TYPE_LINE)) { 06830 CLINE_OPTS->callwaiting = ast_true(v->value); 06831 continue; 06832 } 06833 } else if (!strcasecmp(v->name, "directmedia") || !strcasecmp(v->name, "canreinvite")) { 06834 if (type & (TYPE_DEF_LINE | TYPE_LINE)) { 06835 CLINE_OPTS->directmedia = ast_true(v->value); 06836 continue; 06837 } 06838 } else if (!strcasecmp(v->name, "nat")) { 06839 if (type & (TYPE_DEF_LINE | TYPE_LINE)) { 06840 CLINE_OPTS->nat = ast_true(v->value); 06841 continue; 06842 } 06843 } else if (!strcasecmp(v->name, "context")) { 06844 if (type & (TYPE_DEF_LINE | TYPE_LINE)) { 06845 ast_copy_string(CLINE_OPTS->context, v->value, sizeof(CLINE_OPTS->context)); 06846 continue; 06847 } 06848 }else if (!strcasecmp(v->name, "vmexten")) { 06849 if (type & (TYPE_DEF_DEVICE | TYPE_DEVICE)) { 06850 ast_copy_string(CDEV_OPTS->vmexten, v->value, sizeof(CDEV_OPTS->vmexten)); 06851 continue; 06852 } else if (type & (TYPE_DEF_LINE | TYPE_LINE)) { 06853 ast_copy_string(CLINE_OPTS->vmexten, v->value, sizeof(CLINE_OPTS->vmexten)); 06854 continue; 06855 } 06856 } else if (!strcasecmp(v->name, "mwiblink")) { 06857 if (type & (TYPE_DEF_DEVICE | TYPE_DEVICE)) { 06858 CDEV_OPTS->mwiblink = ast_true(v->value); 06859 continue; 06860 } else if (type & (TYPE_DEF_LINE | TYPE_LINE)) { 06861 CLINE_OPTS->mwiblink = ast_true(v->value); 06862 continue; 06863 } 06864 } else if (!strcasecmp(v->name, "linelabel")) { 06865 if (type & (TYPE_DEF_LINE | TYPE_LINE)) { 06866 ast_copy_string(CLINE_OPTS->label, v->value, sizeof(CLINE_OPTS->label)); 06867 continue; 06868 } 06869 } else if (!strcasecmp(v->name, "callerid")) { 06870 if (type & (TYPE_DEF_LINE | TYPE_LINE)) { 06871 if (!strcasecmp(v->value, "asreceived")) { 06872 CLINE_OPTS->cid_num[0] = '\0'; 06873 CLINE_OPTS->cid_name[0] = '\0'; 06874 } else { 06875 ast_callerid_split(v->value, CLINE_OPTS->cid_name, sizeof(CLINE_OPTS->cid_name), CLINE_OPTS->cid_num, sizeof(CLINE_OPTS->cid_num)); 06876 } 06877 continue; 06878 } 06879 } else if (!strcasecmp(v->name, "amaflags")) { 06880 if (type & (TYPE_DEF_LINE | TYPE_LINE)) { 06881 int tempamaflags = ast_cdr_amaflags2int(v->value); 06882 if (tempamaflags < 0) { 06883 ast_log(LOG_WARNING, "Invalid AMA flags: %s at line %d\n", v->value, v->lineno); 06884 } else { 06885 CLINE_OPTS->amaflags = tempamaflags; 06886 } 06887 continue; 06888 } 06889 } else if (!strcasecmp(v->name, "regexten")) { 06890 if (type & (TYPE_DEF_LINE | TYPE_LINE)) { 06891 ast_copy_string(CLINE_OPTS->regexten, v->value, sizeof(CLINE_OPTS->regexten)); 06892 continue; 06893 } 06894 } else if (!strcasecmp(v->name, "language")) { 06895 if (type & (TYPE_DEF_LINE | TYPE_LINE)) { 06896 ast_copy_string(CLINE_OPTS->language, v->value, sizeof(CLINE_OPTS->language)); 06897 continue; 06898 } 06899 } else if (!strcasecmp(v->name, "accountcode")) { 06900 if (type & (TYPE_DEF_LINE | TYPE_LINE)) { 06901 ast_copy_string(CLINE_OPTS->accountcode, v->value, sizeof(CLINE_OPTS->accountcode)); 06902 continue; 06903 } 06904 } else if (!strcasecmp(v->name, "mohinterpret") || !strcasecmp(v->name, "musiconhold")) { 06905 if (type & (TYPE_DEF_LINE | TYPE_LINE)) { 06906 ast_copy_string(CLINE_OPTS->mohinterpret, v->value, sizeof(CLINE_OPTS->mohinterpret)); 06907 continue; 06908 } 06909 } else if (!strcasecmp(v->name, "mohsuggest")) { 06910 if (type & (TYPE_DEF_LINE | TYPE_LINE)) { 06911 ast_copy_string(CLINE_OPTS->mohsuggest, v->value, sizeof(CLINE_OPTS->mohsuggest)); 06912 continue; 06913 } 06914 } else if (!strcasecmp(v->name, "callgroup")) { 06915 if (type & (TYPE_DEF_LINE | TYPE_LINE)) { 06916 CLINE_OPTS->callgroup = ast_get_group(v->value); 06917 continue; 06918 } 06919 } else if (!strcasecmp(v->name, "pickupgroup")) { 06920 if (type & (TYPE_DEF_LINE | TYPE_LINE)) { 06921 CLINE_OPTS->pickupgroup = ast_get_group(v->value); 06922 continue; 06923 } 06924 } else if (!strcasecmp(v->name, "immediate")) { 06925 if (type & (TYPE_DEF_DEVICE | TYPE_DEVICE | TYPE_DEF_LINE | TYPE_LINE)) { 06926 CLINE_OPTS->immediate = ast_true(v->value); 06927 continue; 06928 } 06929 } else if (!strcasecmp(v->name, "cancallforward")) { 06930 if (type & (TYPE_DEF_LINE | TYPE_LINE)) { 06931 CLINE_OPTS->cancallforward = ast_true(v->value); 06932 continue; 06933 } 06934 } else if (!strcasecmp(v->name, "mailbox")) { 06935 if (type & (TYPE_DEF_LINE | TYPE_LINE)) { 06936 ast_copy_string(CLINE_OPTS->mailbox, v->value, sizeof(CLINE_OPTS->mailbox)); 06937 continue; 06938 } 06939 } else if ( !strcasecmp(v->name, "parkinglot")) { 06940 if (type & (TYPE_DEF_LINE | TYPE_LINE)) { 06941 ast_copy_string(CLINE_OPTS->parkinglot, v->value, sizeof(CLINE_OPTS->parkinglot)); 06942 continue; 06943 } 06944 } else if (!strcasecmp(v->name, "hasvoicemail")) { 06945 if (type & (TYPE_LINE)) { 06946 if (ast_true(v->value) && ast_strlen_zero(CLINE->mailbox)) { 06947 ast_copy_string(CLINE->mailbox, CLINE->name, sizeof(CLINE->mailbox)); 06948 } 06949 continue; 06950 } 06951 } else if (!strcasecmp(v->name, "callreturn")) { 06952 if (type & (TYPE_DEF_LINE | TYPE_LINE)) { 06953 CLINE_OPTS->callreturn = ast_true(v->value); 06954 continue; 06955 } 06956 } else if (!strcasecmp(v->name, "threewaycalling")) { 06957 if (type & (TYPE_DEF_LINE | TYPE_LINE)) { 06958 CLINE_OPTS->threewaycalling = ast_true(v->value); 06959 continue; 06960 } 06961 } else if (!strcasecmp(v->name, "setvar")) { 06962 if (type & (TYPE_LINE)) { 06963 CLINE->chanvars = add_var(v->value, CLINE->chanvars); 06964 continue; 06965 } 06966 } else if (!strcasecmp(v->name, "earlyrtp")) { 06967 if (type & (TYPE_DEF_DEVICE | TYPE_DEVICE)) { 06968 CDEV_OPTS->earlyrtp = ast_true(v->value); 06969 continue; 06970 } 06971 } else if (!strcasecmp(v->name, "host")) { 06972 if (type & (TYPE_DEVICE)) { 06973 struct ast_sockaddr CDEV_addr_tmp; 06974 06975 CDEV_addr_tmp.ss.ss_family = AF_INET; 06976 if (ast_get_ip(&CDEV_addr_tmp, v->value)) { 06977 ast_log(LOG_WARNING, "Bad IP '%s' at line %d.\n", v->value, v->lineno); 06978 } 06979 ast_sockaddr_to_sin(&CDEV_addr_tmp, 06980 &CDEV->addr); 06981 continue; 06982 } 06983 } else if (!strcasecmp(v->name, "port")) { 06984 if (type & (TYPE_DEF_DEVICE)) { 06985 CDEV->addr.sin_port = htons(atoi(v->value)); 06986 continue; 06987 } 06988 } else if (!strcasecmp(v->name, "device")) { 06989 if (type & (TYPE_DEVICE)) { 06990 ast_copy_string(CDEV_OPTS->id, v->value, sizeof(CDEV_OPTS->id)); 06991 continue; 06992 } 06993 } else if (!strcasecmp(v->name, "permit") || !strcasecmp(v->name, "deny")) { 06994 if (type & (TYPE_DEVICE)) { 06995 CDEV->ha = ast_append_ha(v->name, v->value, CDEV->ha, NULL); 06996 continue; 06997 } 06998 } else if (!strcasecmp(v->name, "allow")) { 06999 if (type & (TYPE_DEF_DEVICE | TYPE_DEVICE)) { 07000 ast_parse_allow_disallow(&CDEV_OPTS->confprefs, &CDEV_OPTS->confcapability, v->value, 1); 07001 continue; 07002 } 07003 if (type & (TYPE_DEF_LINE | TYPE_LINE)) { 07004 ast_parse_allow_disallow(&CLINE_OPTS->confprefs, &CLINE_OPTS->confcapability, v->value, 1); 07005 continue; 07006 } 07007 } else if (!strcasecmp(v->name, "disallow")) { 07008 if (type & (TYPE_DEF_DEVICE | TYPE_DEVICE)) { 07009 ast_parse_allow_disallow(&CDEV_OPTS->confprefs, &CDEV_OPTS->confcapability, v->value, 0); 07010 continue; 07011 } 07012 if (type & (TYPE_DEF_LINE | TYPE_LINE)) { 07013 ast_parse_allow_disallow(&CLINE_OPTS->confprefs, &CLINE_OPTS->confcapability, v->value, 0); 07014 continue; 07015 } 07016 } else if (!strcasecmp(v->name, "version")) { 07017 if (type & (TYPE_DEF_DEVICE | TYPE_DEVICE)) { 07018 ast_copy_string(CDEV_OPTS->version_id, v->value, sizeof(CDEV_OPTS->version_id)); 07019 continue; 07020 } 07021 } else if (!strcasecmp(v->name, "line")) { 07022 if (type & (TYPE_DEVICE)) { 07023 struct skinny_line *l; 07024 AST_LIST_TRAVERSE(&lines, l, all) { 07025 if (!strcasecmp(v->value, l->name) && !l->prune) { 07026 07027 /* FIXME: temp solution about line conflicts */ 07028 struct skinny_device *d; 07029 struct skinny_line *l2; 07030 int lineinuse = 0; 07031 AST_LIST_TRAVERSE(&devices, d, list) { 07032 AST_LIST_TRAVERSE(&d->lines, l2, list) { 07033 if (l2 == l && strcasecmp(d->id, CDEV->id)) { 07034 ast_log(LOG_WARNING, "Line %s already used by %s. Not connecting to %s.\n", l->name, d->name, CDEV->name); 07035 lineinuse++; 07036 } 07037 } 07038 } 07039 if (!lineinuse) { 07040 if (!AST_LIST_FIRST(&CDEV->lines)) { 07041 CDEV->activeline = l; 07042 } 07043 lineInstance++; 07044 AST_LIST_INSERT_HEAD(&CDEV->lines, l, list); 07045 } 07046 break; 07047 } 07048 } 07049 continue; 07050 } 07051 } else if (!strcasecmp(v->name, "speeddial")) { 07052 if (type & (TYPE_DEVICE)) { 07053 struct skinny_speeddial *sd; 07054 if (!(sd = ast_calloc(1, sizeof(*sd)))) { 07055 ast_log(LOG_WARNING, "Unable to allocate memory for speeddial %s. Ignoring speeddial.\n", v->name); 07056 continue; 07057 } else { 07058 char buf[256]; 07059 char *stringp = buf, *exten, *context, *label; 07060 ast_copy_string(buf, v->value, sizeof(buf)); 07061 exten = strsep(&stringp, ","); 07062 if ((context = strchr(exten, '@'))) { 07063 *context++ = '\0'; 07064 } 07065 label = stringp; 07066 ast_mutex_init(&sd->lock); 07067 ast_copy_string(sd->exten, exten, sizeof(sd->exten)); 07068 if (!ast_strlen_zero(context)) { 07069 sd->isHint = 1; 07070 sd->instance = lineInstance++; 07071 ast_copy_string(sd->context, context, sizeof(sd->context)); 07072 } else { 07073 sd->isHint = 0; 07074 sd->instance = speeddialInstance++; 07075 sd->context[0] = '\0'; 07076 } 07077 ast_copy_string(sd->label, S_OR(label, exten), sizeof(sd->label)); 07078 sd->parent = CDEV; 07079 AST_LIST_INSERT_HEAD(&CDEV->speeddials, sd, list); 07080 } 07081 continue; 07082 } 07083 } else if (!strcasecmp(v->name, "addon")) { 07084 if (type & (TYPE_DEVICE)) { 07085 struct skinny_addon *a; 07086 if (!(a = ast_calloc(1, sizeof(*a)))) { 07087 ast_log(LOG_WARNING, "Unable to allocate memory for addon %s. Ignoring addon.\n", v->name); 07088 continue; 07089 } else { 07090 ast_mutex_init(&a->lock); 07091 ast_copy_string(a->type, v->value, sizeof(a->type)); 07092 AST_LIST_INSERT_HEAD(&CDEV->addons, a, list); 07093 } 07094 continue; 07095 } 07096 07097 } else { 07098 ast_log(LOG_WARNING, "Don't know keyword '%s' at line %d\n", v->name, v->lineno); 07099 continue; 07100 } 07101 ast_log(LOG_WARNING, "Invalid category used: %s at line %d\n", v->name, v->lineno); 07102 } 07103 }
static char* control2str | ( | int | ind | ) | [static] |
Definition at line 4263 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.
04263 { 04264 char *tmp; 04265 04266 switch (ind) { 04267 case AST_CONTROL_HANGUP: 04268 return "Other end has hungup"; 04269 case AST_CONTROL_RING: 04270 return "Local ring"; 04271 case AST_CONTROL_RINGING: 04272 return "Remote end is ringing"; 04273 case AST_CONTROL_ANSWER: 04274 return "Remote end has answered"; 04275 case AST_CONTROL_BUSY: 04276 return "Remote end is busy"; 04277 case AST_CONTROL_TAKEOFFHOOK: 04278 return "Make it go off hook"; 04279 case AST_CONTROL_OFFHOOK: 04280 return "Line is off hook"; 04281 case AST_CONTROL_CONGESTION: 04282 return "Congestion (circuits busy)"; 04283 case AST_CONTROL_FLASH: 04284 return "Flash hook"; 04285 case AST_CONTROL_WINK: 04286 return "Wink"; 04287 case AST_CONTROL_OPTION: 04288 return "Set a low-level option"; 04289 case AST_CONTROL_RADIO_KEY: 04290 return "Key Radio"; 04291 case AST_CONTROL_RADIO_UNKEY: 04292 return "Un-Key Radio"; 04293 case AST_CONTROL_PROGRESS: 04294 return "Remote end is making Progress"; 04295 case AST_CONTROL_PROCEEDING: 04296 return "Remote end is proceeding"; 04297 case AST_CONTROL_HOLD: 04298 return "Hold"; 04299 case AST_CONTROL_UNHOLD: 04300 return "Unhold"; 04301 case AST_CONTROL_SRCUPDATE: 04302 return "Media Source Update"; 04303 case AST_CONTROL_CONNECTED_LINE: 04304 return "Connected Line"; 04305 case AST_CONTROL_REDIRECTING: 04306 return "Redirecting"; 04307 case AST_CONTROL_INCOMPLETE: 04308 return "Incomplete"; 04309 case -1: 04310 return "Stop tone"; 04311 default: 04312 if (!(tmp = ast_threadstorage_get(&control2str_threadbuf, CONTROL2STR_BUFSIZE))) 04313 return "Unknown"; 04314 snprintf(tmp, CONTROL2STR_BUFSIZE, "UNKNOWN-%d", ind); 04315 return tmp; 04316 } 04317 }
static void delete_devices | ( | void | ) | [static] |
Definition at line 7366 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().
07367 { 07368 struct skinny_device *d; 07369 struct skinny_line *l; 07370 struct skinny_speeddial *sd; 07371 struct skinny_addon *a; 07372 07373 AST_LIST_LOCK(&devices); 07374 AST_LIST_LOCK(&lines); 07375 07376 /* Delete all devices */ 07377 while ((d = AST_LIST_REMOVE_HEAD(&devices, list))) { 07378 /* Delete all lines for this device */ 07379 while ((l = AST_LIST_REMOVE_HEAD(&d->lines, list))) { 07380 AST_LIST_REMOVE(&lines, l, all); 07381 free(l); 07382 } 07383 /* Delete all speeddials for this device */ 07384 while ((sd = AST_LIST_REMOVE_HEAD(&d->speeddials, list))) { 07385 free(sd); 07386 } 07387 /* Delete all addons for this device */ 07388 while ((a = AST_LIST_REMOVE_HEAD(&d->addons, list))) { 07389 free(a); 07390 } 07391 free(d); 07392 } 07393 AST_LIST_UNLOCK(&lines); 07394 AST_LIST_UNLOCK(&devices); 07395 }
static void destroy_session | ( | struct skinnysession * | s | ) | [static] |
Definition at line 6362 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().
06363 { 06364 struct skinnysession *cur; 06365 AST_LIST_LOCK(&sessions); 06366 AST_LIST_TRAVERSE_SAFE_BEGIN(&sessions, cur, list) { 06367 if (cur == s) { 06368 AST_LIST_REMOVE_CURRENT(list); 06369 if (s->fd > -1) 06370 close(s->fd); 06371 06372 if (!s->device) 06373 ast_atomic_fetchadd_int(&unauth_sessions, -1); 06374 06375 ast_mutex_destroy(&s->lock); 06376 06377 ast_free(s); 06378 } else { 06379 ast_log(LOG_WARNING, "Trying to delete nonexistent session %p?\n", s); 06380 } 06381 } 06382 AST_LIST_TRAVERSE_SAFE_END 06383 AST_LIST_UNLOCK(&sessions); 06384 }
static char* device2str | ( | int | type | ) | [static] |
Definition at line 3033 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().
03034 { 03035 char *tmp; 03036 03037 switch (type) { 03038 case SKINNY_DEVICE_NONE: 03039 return "No Device"; 03040 case SKINNY_DEVICE_30SPPLUS: 03041 return "30SP Plus"; 03042 case SKINNY_DEVICE_12SPPLUS: 03043 return "12SP Plus"; 03044 case SKINNY_DEVICE_12SP: 03045 return "12SP"; 03046 case SKINNY_DEVICE_12: 03047 return "12"; 03048 case SKINNY_DEVICE_30VIP: 03049 return "30VIP"; 03050 case SKINNY_DEVICE_7910: 03051 return "7910"; 03052 case SKINNY_DEVICE_7960: 03053 return "7960"; 03054 case SKINNY_DEVICE_7940: 03055 return "7940"; 03056 case SKINNY_DEVICE_7935: 03057 return "7935"; 03058 case SKINNY_DEVICE_ATA186: 03059 return "ATA186"; 03060 case SKINNY_DEVICE_7941: 03061 return "7941"; 03062 case SKINNY_DEVICE_7971: 03063 return "7971"; 03064 case SKINNY_DEVICE_7914: 03065 return "7914"; 03066 case SKINNY_DEVICE_7985: 03067 return "7985"; 03068 case SKINNY_DEVICE_7911: 03069 return "7911"; 03070 case SKINNY_DEVICE_7961GE: 03071 return "7961GE"; 03072 case SKINNY_DEVICE_7941GE: 03073 return "7941GE"; 03074 case SKINNY_DEVICE_7931: 03075 return "7931"; 03076 case SKINNY_DEVICE_7921: 03077 return "7921"; 03078 case SKINNY_DEVICE_7906: 03079 return "7906"; 03080 case SKINNY_DEVICE_7962: 03081 return "7962"; 03082 case SKINNY_DEVICE_7937: 03083 return "7937"; 03084 case SKINNY_DEVICE_7942: 03085 return "7942"; 03086 case SKINNY_DEVICE_7945: 03087 return "7945"; 03088 case SKINNY_DEVICE_7965: 03089 return "7965"; 03090 case SKINNY_DEVICE_7975: 03091 return "7975"; 03092 case SKINNY_DEVICE_7905: 03093 return "7905"; 03094 case SKINNY_DEVICE_7920: 03095 return "7920"; 03096 case SKINNY_DEVICE_7970: 03097 return "7970"; 03098 case SKINNY_DEVICE_7912: 03099 return "7912"; 03100 case SKINNY_DEVICE_7902: 03101 return "7902"; 03102 case SKINNY_DEVICE_CIPC: 03103 return "IP Communicator"; 03104 case SKINNY_DEVICE_7961: 03105 return "7961"; 03106 case SKINNY_DEVICE_7936: 03107 return "7936"; 03108 case SKINNY_DEVICE_SCCPGATEWAY_AN: 03109 return "SCCPGATEWAY_AN"; 03110 case SKINNY_DEVICE_SCCPGATEWAY_BRI: 03111 return "SCCPGATEWAY_BRI"; 03112 case SKINNY_DEVICE_UNKNOWN: 03113 return "Unknown"; 03114 default: 03115 if (!(tmp = ast_threadstorage_get(&device2str_threadbuf, DEVICE2STR_BUFSIZE))) 03116 return "Unknown"; 03117 snprintf(tmp, DEVICE2STR_BUFSIZE, "UNKNOWN-%d", type); 03118 return tmp; 03119 } 03120 }
static void* do_monitor | ( | void * | data | ) | [static] |
Definition at line 6604 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.
06605 { 06606 int res; 06607 06608 /* This thread monitors all the interfaces which are not yet in use 06609 (and thus do not have a separate thread) indefinitely */ 06610 /* From here on out, we die whenever asked */ 06611 for(;;) { 06612 pthread_testcancel(); 06613 /* Wait for sched or io */ 06614 res = ast_sched_wait(sched); 06615 if ((res < 0) || (res > 1000)) { 06616 res = 1000; 06617 } 06618 res = ast_io_wait(io, res); 06619 ast_mutex_lock(&monlock); 06620 if (res >= 0) { 06621 ast_sched_runq(sched); 06622 } 06623 ast_mutex_unlock(&monlock); 06624 } 06625 /* Never reached */ 06626 return NULL; 06627 06628 }
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 4234 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().
04235 { 04236 struct skinny_subchannel *sub; 04237 int res = AST_DEVICE_UNKNOWN; 04238 04239 if (!l) 04240 res = AST_DEVICE_INVALID; 04241 else if (!l->device) 04242 res = AST_DEVICE_UNAVAILABLE; 04243 else if (l->dnd) 04244 res = AST_DEVICE_BUSY; 04245 else { 04246 if (l->hookstate == SKINNY_ONHOOK) { 04247 res = AST_DEVICE_NOT_INUSE; 04248 } else { 04249 res = AST_DEVICE_INUSE; 04250 } 04251 04252 AST_LIST_TRAVERSE(&l->sub, sub, list) { 04253 if (sub->onhold) { 04254 res = AST_DEVICE_ONHOLD; 04255 break; 04256 } 04257 } 04258 } 04259 04260 return res; 04261 }
static int get_input | ( | struct skinnysession * | s | ) | [static] |
Definition at line 6386 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().
06387 { 06388 int res; 06389 int dlen = 0; 06390 int timeout = keep_alive * 1100; 06391 time_t now; 06392 int *bufaddr; 06393 struct pollfd fds[1]; 06394 06395 if (!s->device) { 06396 if(time(&now) == -1) { 06397 ast_log(LOG_ERROR, "error executing time(): %s\n", strerror(errno)); 06398 return -1; 06399 } 06400 06401 timeout = (auth_timeout - (now - s->start)) * 1000; 06402 if (timeout < 0) { 06403 /* we have timed out */ 06404 if (skinnydebug) 06405 ast_verb(1, "Skinny Client failed to authenticate in %d seconds\n", auth_timeout); 06406 return -1; 06407 } 06408 } 06409 06410 fds[0].fd = s->fd; 06411 fds[0].events = POLLIN; 06412 fds[0].revents = 0; 06413 res = ast_poll(fds, 1, timeout); /* If nothing has happen, client is dead */ 06414 /* we add 10% to the keep_alive to deal */ 06415 /* with network delays, etc */ 06416 if (res < 0) { 06417 if (errno != EINTR) { 06418 ast_log(LOG_WARNING, "Select returned error: %s\n", strerror(errno)); 06419 return res; 06420 } 06421 } else if (res == 0) { 06422 if (skinnydebug) { 06423 if (s->device) { 06424 ast_verb(1, "Skinny Client was lost, unregistering\n"); 06425 } else { 06426 ast_verb(1, "Skinny Client failed to authenticate in %d seconds\n", auth_timeout); 06427 } 06428 } 06429 skinny_unregister(NULL, s); 06430 return -1; 06431 } 06432 06433 if (fds[0].revents) { 06434 ast_mutex_lock(&s->lock); 06435 memset(s->inbuf, 0, sizeof(s->inbuf)); 06436 res = read(s->fd, s->inbuf, 4); 06437 if (res < 0) { 06438 ast_log(LOG_WARNING, "read() returned error: %s\n", strerror(errno)); 06439 06440 if (skinnydebug) 06441 ast_verb(1, "Skinny Client was lost, unregistering\n"); 06442 06443 skinny_unregister(NULL, s); 06444 ast_mutex_unlock(&s->lock); 06445 return res; 06446 } else if (res != 4) { 06447 ast_log(LOG_WARNING, "Skinny Client sent less data than expected. Expected 4 but got %d.\n", res); 06448 ast_mutex_unlock(&s->lock); 06449 06450 if (res == 0) { 06451 if (skinnydebug) 06452 ast_verb(1, "Skinny Client was lost, unregistering\n"); 06453 skinny_unregister(NULL, s); 06454 } 06455 06456 return -1; 06457 } 06458 06459 bufaddr = (int *)s->inbuf; 06460 dlen = letohl(*bufaddr); 06461 if (dlen < 4) { 06462 ast_debug(1, "Skinny Client sent invalid data.\n"); 06463 ast_mutex_unlock(&s->lock); 06464 return -1; 06465 } 06466 if (dlen+8 > sizeof(s->inbuf)) { 06467 dlen = sizeof(s->inbuf) - 8; 06468 } 06469 *bufaddr = htolel(dlen); 06470 06471 res = read(s->fd, s->inbuf+4, dlen+4); 06472 ast_mutex_unlock(&s->lock); 06473 if (res < 0) { 06474 ast_log(LOG_WARNING, "read() returned error: %s\n", strerror(errno)); 06475 return res; 06476 } else if (res != (dlen+4)) { 06477 ast_log(LOG_WARNING, "Skinny Client sent less data than expected.\n"); 06478 return -1; 06479 } 06480 return res; 06481 } 06482 return 0; 06483 }
static int handle_button_template_req_message | ( | struct skinny_req * | req, | |
struct skinnysession * | s | |||
) | [static] |
Definition at line 5546 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().
05547 { 05548 struct skinny_device *d = s->device; 05549 struct skinny_line *l; 05550 int i; 05551 05552 struct skinny_speeddial *sd; 05553 struct button_definition_template btn[42]; 05554 int lineInstance = 1; 05555 int speeddialInstance = 1; 05556 int buttonCount = 0; 05557 05558 if (!(req = req_alloc(sizeof(struct button_template_res_message), BUTTON_TEMPLATE_RES_MESSAGE))) 05559 return -1; 05560 05561 memset(&btn, 0, sizeof(btn)); 05562 05563 get_button_template(s, btn); 05564 05565 for (i=0; i<42; i++) { 05566 int btnSet = 0; 05567 switch (btn[i].buttonDefinition) { 05568 case BT_CUST_LINE: 05569 /* assume failure */ 05570 req->data.buttontemplate.definition[i].buttonDefinition = BT_NONE; 05571 req->data.buttontemplate.definition[i].instanceNumber = 0; 05572 05573 AST_LIST_TRAVERSE(&d->lines, l, list) { 05574 if (l->instance == lineInstance) { 05575 ast_verb(0, "Adding button: %d, %d\n", BT_LINE, lineInstance); 05576 req->data.buttontemplate.definition[i].buttonDefinition = BT_LINE; 05577 req->data.buttontemplate.definition[i].instanceNumber = lineInstance; 05578 lineInstance++; 05579 buttonCount++; 05580 btnSet = 1; 05581 break; 05582 } 05583 } 05584 05585 if (!btnSet) { 05586 AST_LIST_TRAVERSE(&d->speeddials, sd, list) { 05587 if (sd->isHint && sd->instance == lineInstance) { 05588 ast_verb(0, "Adding button: %d, %d\n", BT_LINE, lineInstance); 05589 req->data.buttontemplate.definition[i].buttonDefinition = BT_LINE; 05590 req->data.buttontemplate.definition[i].instanceNumber = lineInstance; 05591 lineInstance++; 05592 buttonCount++; 05593 btnSet = 1; 05594 break; 05595 } 05596 } 05597 } 05598 break; 05599 case BT_CUST_LINESPEEDDIAL: 05600 /* assume failure */ 05601 req->data.buttontemplate.definition[i].buttonDefinition = BT_NONE; 05602 req->data.buttontemplate.definition[i].instanceNumber = 0; 05603 05604 AST_LIST_TRAVERSE(&d->lines, l, list) { 05605 if (l->instance == lineInstance) { 05606 ast_verb(0, "Adding button: %d, %d\n", BT_LINE, lineInstance); 05607 req->data.buttontemplate.definition[i].buttonDefinition = BT_LINE; 05608 req->data.buttontemplate.definition[i].instanceNumber = lineInstance; 05609 lineInstance++; 05610 buttonCount++; 05611 btnSet = 1; 05612 break; 05613 } 05614 } 05615 05616 if (!btnSet) { 05617 AST_LIST_TRAVERSE(&d->speeddials, sd, list) { 05618 if (sd->isHint && sd->instance == lineInstance) { 05619 ast_verb(0, "Adding button: %d, %d\n", BT_LINE, lineInstance); 05620 req->data.buttontemplate.definition[i].buttonDefinition = BT_LINE; 05621 req->data.buttontemplate.definition[i].instanceNumber = lineInstance; 05622 lineInstance++; 05623 buttonCount++; 05624 btnSet = 1; 05625 break; 05626 } else if (!sd->isHint && sd->instance == speeddialInstance) { 05627 ast_verb(0, "Adding button: %d, %d\n", BT_SPEEDDIAL, speeddialInstance); 05628 req->data.buttontemplate.definition[i].buttonDefinition = BT_SPEEDDIAL; 05629 req->data.buttontemplate.definition[i].instanceNumber = speeddialInstance; 05630 speeddialInstance++; 05631 buttonCount++; 05632 btnSet = 1; 05633 break; 05634 } 05635 } 05636 } 05637 break; 05638 case BT_LINE: 05639 req->data.buttontemplate.definition[i].buttonDefinition = htolel(BT_NONE); 05640 req->data.buttontemplate.definition[i].instanceNumber = htolel(0); 05641 05642 AST_LIST_TRAVERSE(&d->lines, l, list) { 05643 if (l->instance == lineInstance) { 05644 ast_verb(0, "Adding button: %d, %d\n", BT_LINE, lineInstance); 05645 req->data.buttontemplate.definition[i].buttonDefinition = BT_LINE; 05646 req->data.buttontemplate.definition[i].instanceNumber = lineInstance; 05647 lineInstance++; 05648 buttonCount++; 05649 btnSet = 1; 05650 break; 05651 } 05652 } 05653 break; 05654 case BT_SPEEDDIAL: 05655 req->data.buttontemplate.definition[i].buttonDefinition = BT_NONE; 05656 req->data.buttontemplate.definition[i].instanceNumber = 0; 05657 05658 AST_LIST_TRAVERSE(&d->speeddials, sd, list) { 05659 if (!sd->isHint && sd->instance == speeddialInstance) { 05660 ast_verb(0, "Adding button: %d, %d\n", BT_SPEEDDIAL, speeddialInstance); 05661 req->data.buttontemplate.definition[i].buttonDefinition = BT_SPEEDDIAL; 05662 req->data.buttontemplate.definition[i].instanceNumber = speeddialInstance - 1; 05663 speeddialInstance++; 05664 buttonCount++; 05665 btnSet = 1; 05666 break; 05667 } 05668 } 05669 break; 05670 case BT_NONE: 05671 break; 05672 default: 05673 ast_verb(0, "Adding button: %d, %d\n", btn[i].buttonDefinition, 0); 05674 req->data.buttontemplate.definition[i].buttonDefinition = htolel(btn[i].buttonDefinition); 05675 req->data.buttontemplate.definition[i].instanceNumber = 0; 05676 buttonCount++; 05677 btnSet = 1; 05678 break; 05679 } 05680 } 05681 05682 req->data.buttontemplate.buttonOffset = 0; 05683 req->data.buttontemplate.buttonCount = htolel(buttonCount); 05684 req->data.buttontemplate.totalButtonCount = htolel(buttonCount); 05685 05686 if (skinnydebug) 05687 ast_verb(1, "Sending %d template to %s\n", 05688 d->type, 05689 d->name); 05690 transmit_response(d, req); 05691 return 1; 05692 }
static int handle_callforward_button | ( | struct skinny_subchannel * | sub, | |
int | cfwdtype | |||
) | [static] |
Definition at line 4852 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().
04853 { 04854 struct skinny_line *l = sub->parent; 04855 struct skinny_device *d = l->device; 04856 struct ast_channel *c = sub->owner; 04857 pthread_t t; 04858 04859 if (!d) { 04860 ast_log(LOG_WARNING, "Device for line %s is not registered.\n", l->name); 04861 return 0; 04862 } 04863 04864 if (l->hookstate == SKINNY_ONHOOK) { 04865 l->hookstate = SKINNY_OFFHOOK; 04866 transmit_speaker_mode(d, SKINNY_SPEAKERON); 04867 transmit_callstate(d, l->instance, sub->callid, SKINNY_OFFHOOK); 04868 transmit_activatecallplane(d, l); 04869 } 04870 transmit_clear_display_message(d, l->instance, sub->callid); 04871 04872 if (l->cfwdtype & cfwdtype) { 04873 set_callforwards(l, NULL, cfwdtype); 04874 ast_safe_sleep(c, 500); 04875 transmit_speaker_mode(d, SKINNY_SPEAKEROFF); 04876 transmit_closereceivechannel(d, sub); 04877 transmit_stopmediatransmission(d, sub); 04878 transmit_speaker_mode(d, SKINNY_SPEAKEROFF); 04879 transmit_clearpromptmessage(d, l->instance, sub->callid); 04880 transmit_callstate(d, l->instance, sub->callid, SKINNY_ONHOOK); 04881 transmit_selectsoftkeys(d, 0, 0, KEYDEF_ONHOOK); 04882 transmit_activatecallplane(d, l); 04883 transmit_displaynotify(d, "CFwd disabled", 10); 04884 if (sub->owner && sub->owner->_state != AST_STATE_UP) { 04885 ast_indicate(c, -1); 04886 ast_hangup(c); 04887 } 04888 transmit_cfwdstate(d, l); 04889 } else { 04890 l->getforward = cfwdtype; 04891 transmit_start_tone(d, SKINNY_DIALTONE, l->instance, sub->callid); 04892 transmit_selectsoftkeys(d, l->instance, sub->callid, KEYDEF_RINGOUT); 04893 if (ast_pthread_create(&t, NULL, skinny_ss, c)) { 04894 ast_log(LOG_WARNING, "Unable to create switch thread: %s\n", strerror(errno)); 04895 ast_hangup(c); 04896 } 04897 } 04898 return 0; 04899 }
static int handle_capabilities_res_message | ( | struct skinny_req * | req, | |
struct skinnysession * | s | |||
) | [static] |
Definition at line 5510 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().
05511 { 05512 struct skinny_device *d = s->device; 05513 struct skinny_line *l; 05514 uint32_t count = 0; 05515 format_t codecs = 0; 05516 int i; 05517 char buf[256]; 05518 05519 count = letohl(req->data.caps.count); 05520 if (count > SKINNY_MAX_CAPABILITIES) { 05521 count = SKINNY_MAX_CAPABILITIES; 05522 ast_log(LOG_WARNING, "Received more capabilities than we can handle (%d). Ignoring the rest.\n", SKINNY_MAX_CAPABILITIES); 05523 } 05524 05525 for (i = 0; i < count; i++) { 05526 format_t acodec = 0; 05527 int scodec = 0; 05528 scodec = letohl(req->data.caps.caps[i].codec); 05529 acodec = codec_skinny2ast(scodec); 05530 if (skinnydebug) 05531 ast_verb(1, "Adding codec capability '%" PRId64 " (%d)'\n", acodec, scodec); 05532 codecs |= acodec; 05533 } 05534 05535 d->capability = d->confcapability & codecs; 05536 ast_verb(0, "Device capability set to '%s'\n", ast_getformatname_multiple(buf, sizeof(buf), d->capability)); 05537 AST_LIST_TRAVERSE(&d->lines, l, list) { 05538 ast_mutex_lock(&l->lock); 05539 l->capability = l->confcapability & d->capability; 05540 ast_mutex_unlock(&l->lock); 05541 } 05542 05543 return 1; 05544 }
static int handle_enbloc_call_message | ( | struct skinny_req * | req, | |
struct skinnysession * | s | |||
) | [static] |
Definition at line 5755 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().
05756 { 05757 struct skinny_device *d = s->device; 05758 struct skinny_line *l; 05759 struct skinny_subchannel *sub = NULL; 05760 struct ast_channel *c; 05761 pthread_t t; 05762 05763 if (skinnydebug) 05764 ast_verb(1, "Received Enbloc Call: %s\n", req->data.enbloccallmessage.calledParty); 05765 05766 sub = find_subchannel_by_instance_reference(d, d->lastlineinstance, d->lastcallreference); 05767 05768 if (!sub) { 05769 l = find_line_by_instance(d, d->lastlineinstance); 05770 if (!l) { 05771 return 0; 05772 } 05773 } else { 05774 l = sub->parent; 05775 } 05776 05777 c = skinny_new(l, AST_STATE_DOWN, NULL); 05778 05779 if(!c) { 05780 ast_log(LOG_WARNING, "Unable to create channel for %s@%s\n", l->name, d->name); 05781 } else { 05782 l->hookstate = SKINNY_OFFHOOK; 05783 05784 sub = c->tech_pvt; 05785 l->activesub = sub; 05786 transmit_callstate(d, l->instance, sub->callid, SKINNY_OFFHOOK); 05787 transmit_activatecallplane(d, l); 05788 transmit_clear_display_message(d, l->instance, sub->callid); 05789 transmit_start_tone(d, SKINNY_DIALTONE, l->instance, sub->callid); 05790 05791 if (!ast_ignore_pattern(c->context, req->data.enbloccallmessage.calledParty)) { 05792 transmit_stop_tone(d, l->instance, sub->callid); 05793 } 05794 ast_copy_string(c->exten, req->data.enbloccallmessage.calledParty, sizeof(c->exten)); 05795 if (ast_pthread_create(&t, NULL, skinny_newcall, c)) { 05796 ast_log(LOG_WARNING, "Unable to create new call thread: %s\n", strerror(errno)); 05797 ast_hangup(c); 05798 } 05799 } 05800 05801 return 1; 05802 }
static int handle_hold_button | ( | struct skinny_subchannel * | sub | ) | [static] |
Definition at line 4687 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().
04688 { 04689 if (!sub) 04690 return -1; 04691 if (sub->related) { 04692 skinny_hold(sub); 04693 skinny_unhold(sub->related); 04694 sub->parent->activesub = sub->related; 04695 } else { 04696 if (sub->onhold) { 04697 skinny_unhold(sub); 04698 transmit_selectsoftkeys(sub->parent->device, sub->parent->instance, sub->callid, KEYDEF_CONNECTED); 04699 } else { 04700 skinny_hold(sub); 04701 transmit_selectsoftkeys(sub->parent->device, sub->parent->instance, sub->callid, KEYDEF_ONHOLD); 04702 } 04703 } 04704 return 1; 04705 }
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 4776 of file chan_skinny.c.
References skinnysession::device, KEEP_ALIVE_ACK_MESSAGE, req_alloc(), and transmit_response().
Referenced by handle_message().
04777 { 04778 if (!(req = req_alloc(0, KEEP_ALIVE_ACK_MESSAGE))) 04779 return -1; 04780 04781 transmit_response(s->device, req); 04782 return 1; 04783 }
static int handle_keypad_button_message | ( | struct skinny_req * | req, | |
struct skinnysession * | s | |||
) | [static] |
Definition at line 4906 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().
04907 { 04908 struct skinny_subchannel *sub = NULL; 04909 struct skinny_line *l; 04910 struct skinny_device *d = s->device; 04911 struct ast_frame f = { 0, }; 04912 char dgt; 04913 int digit; 04914 int lineInstance; 04915 int callReference; 04916 04917 digit = letohl(req->data.keypad.button); 04918 lineInstance = letohl(req->data.keypad.lineInstance); 04919 callReference = letohl(req->data.keypad.callReference); 04920 04921 if (digit == 14) { 04922 dgt = '*'; 04923 } else if (digit == 15) { 04924 dgt = '#'; 04925 } else if (digit >= 0 && digit <= 9) { 04926 dgt = '0' + digit; 04927 } else { 04928 /* digit=10-13 (A,B,C,D ?), or 04929 * digit is bad value 04930 * 04931 * probably should not end up here, but set 04932 * value for backward compatibility, and log 04933 * a warning. 04934 */ 04935 dgt = '0' + digit; 04936 ast_log(LOG_WARNING, "Unsupported digit %d\n", digit); 04937 } 04938 04939 f.subclass.integer = dgt; 04940 04941 f.src = "skinny"; 04942 04943 if (lineInstance && callReference) 04944 sub = find_subchannel_by_instance_reference(d, lineInstance, callReference); 04945 else 04946 sub = d->activeline->activesub; 04947 //sub = find_subchannel_by_instance_reference(d, d->lastlineinstance, d->lastcallreference); 04948 04949 if (!sub) 04950 return 0; 04951 04952 l = sub->parent; 04953 if (sub->owner) { 04954 if (sub->owner->_state == 0) { 04955 f.frametype = AST_FRAME_DTMF_BEGIN; 04956 ast_queue_frame(sub->owner, &f); 04957 } 04958 /* XXX MUST queue this frame to all lines in threeway call if threeway call is active */ 04959 f.frametype = AST_FRAME_DTMF_END; 04960 ast_queue_frame(sub->owner, &f); 04961 /* XXX This seriously needs to be fixed */ 04962 if (AST_LIST_NEXT(sub, list) && AST_LIST_NEXT(sub, list)->owner) { 04963 if (sub->owner->_state == 0) { 04964 f.frametype = AST_FRAME_DTMF_BEGIN; 04965 ast_queue_frame(AST_LIST_NEXT(sub, list)->owner, &f); 04966 } 04967 f.frametype = AST_FRAME_DTMF_END; 04968 ast_queue_frame(AST_LIST_NEXT(sub, list)->owner, &f); 04969 } 04970 } else { 04971 if (skinnydebug) 04972 ast_verb(1, "No owner: %s\n", l->name); 04973 } 04974 return 1; 04975 }
static int handle_message | ( | struct skinny_req * | req, | |
struct skinnysession * | s | |||
) | [static] |
Definition at line 6178 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_LOG_WARNING, 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, len(), 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().
06179 { 06180 int res = 0; 06181 struct skinny_speeddial *sd; 06182 struct skinny_line *l; 06183 struct skinny_device *d = s->device; 06184 size_t len; 06185 06186 if ((!s->device) && (letohl(req->e) != REGISTER_MESSAGE && letohl(req->e) != ALARM_MESSAGE)) { 06187 ast_log(LOG_WARNING, "Client sent message #%d without first registering.\n", req->e); 06188 ast_free(req); 06189 return 0; 06190 } 06191 06192 SKINNY_DEVONLY(if (skinnydebug > 1) { 06193 ast_verb(4, "Received %s from %s\n", message2str(req->e), s->device->name); 06194 }) 06195 06196 switch(letohl(req->e)) { 06197 case KEEP_ALIVE_MESSAGE: 06198 res = handle_keep_alive_message(req, s); 06199 break; 06200 case REGISTER_MESSAGE: 06201 if (skinnydebug) 06202 ast_verb(1, "Device %s is attempting to register\n", req->data.reg.name); 06203 06204 res = handle_register_message(req, s); 06205 break; 06206 case IP_PORT_MESSAGE: 06207 res = handle_ip_port_message(req, s); 06208 break; 06209 case KEYPAD_BUTTON_MESSAGE: 06210 { 06211 struct skinny_device *d = s->device; 06212 struct skinny_subchannel *sub; 06213 int lineInstance; 06214 int callReference; 06215 06216 if (skinnydebug) 06217 ast_verb(1, "Collected digit: [%d]\n", letohl(req->data.keypad.button)); 06218 06219 lineInstance = letohl(req->data.keypad.lineInstance); 06220 callReference = letohl(req->data.keypad.callReference); 06221 06222 if (lineInstance) { 06223 sub = find_subchannel_by_instance_reference(d, lineInstance, callReference); 06224 } else { 06225 sub = d->activeline->activesub; 06226 } 06227 06228 if (sub && ((sub->owner && sub->owner->_state < AST_STATE_UP) || sub->onhold)) { 06229 char dgt; 06230 int digit = letohl(req->data.keypad.button); 06231 06232 if (digit == 14) { 06233 dgt = '*'; 06234 } else if (digit == 15) { 06235 dgt = '#'; 06236 } else if (digit >= 0 && digit <= 9) { 06237 dgt = '0' + digit; 06238 } else { 06239 /* digit=10-13 (A,B,C,D ?), or 06240 * digit is bad value 06241 * 06242 * probably should not end up here, but set 06243 * value for backward compatibility, and log 06244 * a warning. 06245 */ 06246 dgt = '0' + digit; 06247 ast_log(LOG_WARNING, "Unsupported digit %d\n", digit); 06248 } 06249 06250 len = strlen(d->exten); 06251 if (len < sizeof(d->exten) - 1) { 06252 d->exten[len] = dgt; 06253 d->exten[len + 1] = '\0'; 06254 } else { 06255 ast_log(AST_LOG_WARNING, "Dropping digit with value %d because digit queue is full\n", dgt); 06256 } 06257 } else 06258 res = handle_keypad_button_message(req, s); 06259 } 06260 break; 06261 case ENBLOC_CALL_MESSAGE: 06262 res = handle_enbloc_call_message(req, s); 06263 break; 06264 case STIMULUS_MESSAGE: 06265 res = handle_stimulus_message(req, s); 06266 break; 06267 case OFFHOOK_MESSAGE: 06268 res = handle_offhook_message(req, s); 06269 break; 06270 case ONHOOK_MESSAGE: 06271 res = handle_onhook_message(req, s); 06272 break; 06273 case CAPABILITIES_RES_MESSAGE: 06274 if (skinnydebug) 06275 ast_verb(1, "Received CapabilitiesRes\n"); 06276 06277 res = handle_capabilities_res_message(req, s); 06278 break; 06279 case SPEED_DIAL_STAT_REQ_MESSAGE: 06280 if (skinnydebug) 06281 ast_verb(1, "Received SpeedDialStatRequest\n"); 06282 if ( (sd = find_speeddial_by_instance(s->device, letohl(req->data.speeddialreq.speedDialNumber), 0)) ) { 06283 transmit_speeddialstatres(d, sd); 06284 } 06285 break; 06286 case LINE_STATE_REQ_MESSAGE: 06287 if (skinnydebug) 06288 ast_verb(1, "Received LineStatRequest\n"); 06289 if ((l = find_line_by_instance(d, letohl(req->data.line.lineNumber)))) { 06290 transmit_linestatres(d, l); 06291 } 06292 break; 06293 case TIME_DATE_REQ_MESSAGE: 06294 if (skinnydebug) 06295 ast_verb(1, "Received Time/Date Request\n"); 06296 06297 transmit_definetimedate(d); 06298 break; 06299 case BUTTON_TEMPLATE_REQ_MESSAGE: 06300 if (skinnydebug) 06301 ast_verb(1, "Buttontemplate requested\n"); 06302 06303 res = handle_button_template_req_message(req, s); 06304 break; 06305 case VERSION_REQ_MESSAGE: 06306 if (skinnydebug) 06307 ast_verb(1, "Version Request\n"); 06308 transmit_versionres(d); 06309 break; 06310 case SERVER_REQUEST_MESSAGE: 06311 if (skinnydebug) 06312 ast_verb(1, "Received Server Request\n"); 06313 transmit_serverres(d); 06314 break; 06315 case ALARM_MESSAGE: 06316 /* no response necessary */ 06317 if (skinnydebug) 06318 ast_verb(1, "Received Alarm Message: %s\n", req->data.alarm.displayMessage); 06319 break; 06320 case OPEN_RECEIVE_CHANNEL_ACK_MESSAGE: 06321 if (skinnydebug) 06322 ast_verb(1, "Received Open Receive Channel Ack\n"); 06323 06324 res = handle_open_receive_channel_ack_message(req, s); 06325 break; 06326 case SOFT_KEY_SET_REQ_MESSAGE: 06327 if (skinnydebug) 06328 ast_verb(1, "Received SoftKeySetReq\n"); 06329 transmit_softkeysetres(d); 06330 transmit_selectsoftkeys(d, 0, 0, KEYDEF_ONHOOK); 06331 break; 06332 case SOFT_KEY_EVENT_MESSAGE: 06333 res = handle_soft_key_event_message(req, s); 06334 break; 06335 case UNREGISTER_MESSAGE: 06336 if (skinnydebug) 06337 ast_verb(1, "Received Unregister Request\n"); 06338 06339 res = skinny_unregister(req, s); 06340 break; 06341 case SOFT_KEY_TEMPLATE_REQ_MESSAGE: 06342 if (skinnydebug) 06343 ast_verb(1, "Received SoftKey Template Request\n"); 06344 transmit_softkeytemplateres(d); 06345 break; 06346 case HEADSET_STATUS_MESSAGE: 06347 /* XXX umm...okay? Why do I care? */ 06348 break; 06349 case REGISTER_AVAILABLE_LINES_MESSAGE: 06350 /* XXX I have no clue what this is for, but my phone was sending it, so... */ 06351 break; 06352 default: 06353 if (skinnydebug) 06354 ast_verb(1, "RECEIVED UNKNOWN MESSAGE TYPE: %x\n", letohl(req->e)); 06355 break; 06356 } 06357 if (res >= 0 && req) 06358 ast_free(req); 06359 return res; 06360 }
static int handle_offhook_message | ( | struct skinny_req * | req, | |
struct skinnysession * | s | |||
) | [static] |
Definition at line 5329 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().
05330 { 05331 struct skinny_device *d = s->device; 05332 struct skinny_line *l; 05333 struct skinny_subchannel *sub; 05334 struct ast_channel *c; 05335 struct skinny_line *tmp; 05336 pthread_t t; 05337 int instance; 05338 05339 /* if any line on a device is offhook, than the device must be offhook, 05340 unless we have shared lines CCM seems that it would never get here, 05341 but asterisk does, so we may need to do more work. Ugly, we should 05342 probably move hookstate from line to device, afterall, it's actually 05343 a device that changes hookstates */ 05344 05345 AST_LIST_TRAVERSE(&d->lines, tmp, list) { 05346 if (tmp->hookstate == SKINNY_OFFHOOK) { 05347 ast_verbose(VERBOSE_PREFIX_3 "Got offhook message when device (%s@%s) already offhook\n", tmp->name, d->name); 05348 return 0; 05349 } 05350 } 05351 05352 instance = letohl(req->data.offhook.instance); 05353 05354 if (instance) { 05355 sub = find_subchannel_by_instance_reference(d, d->lastlineinstance, d->lastcallreference); 05356 if (!sub) { 05357 l = find_line_by_instance(d, d->lastlineinstance); 05358 if (!l) { 05359 return 0; 05360 } 05361 } else { 05362 l = sub->parent; 05363 } 05364 } else { 05365 l = d->activeline; 05366 sub = l->activesub; 05367 } 05368 05369 /* Not ideal, but let's send updated time at onhook and offhook, as it clears the display */ 05370 transmit_definetimedate(d); 05371 05372 transmit_ringer_mode(d, SKINNY_RING_OFF); 05373 l->hookstate = SKINNY_OFFHOOK; 05374 05375 ast_devstate_changed(AST_DEVICE_INUSE, "Skinny/%s@%s", l->name, d->name); 05376 05377 if (sub && sub->onhold) { 05378 return 1; 05379 } 05380 05381 transmit_lamp_indication(d, STIMULUS_LINE, l->instance, SKINNY_LAMP_ON); 05382 05383 if (sub && sub->outgoing) { 05384 /* We're answering a ringing call */ 05385 ast_queue_control(sub->owner, AST_CONTROL_ANSWER); 05386 transmit_callstate(d, l->instance, sub->callid, SKINNY_OFFHOOK); 05387 transmit_activatecallplane(d, l); 05388 transmit_stop_tone(d, l->instance, sub->callid); 05389 transmit_callstate(d, sub->parent->instance, sub->callid, SKINNY_CONNECTED); 05390 transmit_selectsoftkeys(d, l->instance, sub->callid, KEYDEF_CONNECTED); 05391 start_rtp(sub); 05392 ast_setstate(sub->owner, AST_STATE_UP); 05393 } else { 05394 if (sub && sub->owner) { 05395 ast_debug(1, "Current sub [%s] already has owner\n", sub->owner->name); 05396 } else { 05397 c = skinny_new(l, AST_STATE_DOWN, NULL); 05398 if (c) { 05399 sub = c->tech_pvt; 05400 l->activesub = sub; 05401 transmit_callstate(d, l->instance, sub->callid, SKINNY_OFFHOOK); 05402 transmit_activatecallplane(d, l); 05403 transmit_clear_display_message(d, l->instance, sub->callid); 05404 transmit_start_tone(d, SKINNY_DIALTONE, l->instance, sub->callid); 05405 transmit_selectsoftkeys(d, l->instance, sub->callid, KEYDEF_OFFHOOK); 05406 05407 /* start the switch thread */ 05408 if (ast_pthread_create(&t, NULL, skinny_ss, c)) { 05409 ast_log(LOG_WARNING, "Unable to create switch thread: %s\n", strerror(errno)); 05410 ast_hangup(c); 05411 } 05412 } else { 05413 ast_log(LOG_WARNING, "Unable to create channel for %s@%s\n", l->name, d->name); 05414 } 05415 } 05416 } 05417 return 1; 05418 }
static int handle_onhook_message | ( | struct skinny_req * | req, | |
struct skinnysession * | s | |||
) | [static] |
Definition at line 5420 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().
05421 { 05422 struct skinny_device *d = s->device; 05423 struct skinny_line *l; 05424 struct skinny_subchannel *sub; 05425 int instance; 05426 int reference; 05427 int onlysub = 0; 05428 05429 instance = letohl(req->data.onhook.instance); 05430 reference = letohl(req->data.onhook.reference); 05431 05432 if (instance && reference) { 05433 sub = find_subchannel_by_instance_reference(d, instance, reference); 05434 if (!sub) { 05435 return 0; 05436 } 05437 l = sub->parent; 05438 } else { 05439 l = d->activeline; 05440 sub = l->activesub; 05441 if (!sub) { 05442 return 0; 05443 } 05444 } 05445 05446 if (l->hookstate == SKINNY_ONHOOK) { 05447 /* Something else already put us back on hook */ 05448 return 0; 05449 } 05450 05451 ast_devstate_changed(AST_DEVICE_NOT_INUSE, "Skinny/%s@%s", l->name, d->name); 05452 05453 if (sub->onhold) { 05454 return 0; 05455 } 05456 05457 if (!AST_LIST_NEXT(sub, list)) { 05458 onlysub = 1; 05459 } else { 05460 AST_LIST_REMOVE(&l->sub, sub, list); 05461 } 05462 05463 sub->cxmode = SKINNY_CX_RECVONLY; 05464 if (onlysub || sub->xferor){ /* is this the only call to this device? */ 05465 l->hookstate = SKINNY_ONHOOK; 05466 if (skinnydebug) 05467 ast_debug(1, "Skinny %s@%s-%d went on hook\n", l->name, d->name, reference); 05468 } 05469 05470 if (l->hookstate == SKINNY_ONHOOK) { 05471 transmit_closereceivechannel(d, sub); 05472 transmit_stopmediatransmission(d, sub); 05473 transmit_speaker_mode(d, SKINNY_SPEAKEROFF); 05474 transmit_clearpromptmessage(d, instance, sub->callid); 05475 transmit_callstate(d, l->instance, sub->callid, SKINNY_ONHOOK); 05476 transmit_selectsoftkeys(d, 0, 0, KEYDEF_ONHOOK); 05477 transmit_activatecallplane(d, l); 05478 } else if (l->hookstate == SKINNY_OFFHOOK) { 05479 transmit_callstate(d, l->instance, sub->callid, SKINNY_OFFHOOK); 05480 transmit_activatecallplane(d, l); 05481 } else { 05482 transmit_callstate(d, l->instance, sub->callid, l->hookstate); 05483 } 05484 05485 if (l->transfer && sub->xferor && sub->owner->_state >= AST_STATE_RING) { 05486 /* We're allowed to transfer, we have two active calls and 05487 we made at least one of the calls. Let's try and transfer */ 05488 handle_transfer_button(sub); 05489 } else { 05490 /* Hangup the current call */ 05491 /* If there is another active call, skinny_hangup will ring the phone with the other call */ 05492 if (sub->xferor && sub->related){ 05493 sub->related->related = NULL; 05494 sub->related->blindxfer = 0; 05495 } 05496 05497 if (sub->owner) { 05498 sub->alreadygone = 1; 05499 ast_queue_hangup(sub->owner); 05500 } else { 05501 ast_log(LOG_WARNING, "Skinny(%s@%s-%d) channel already destroyed\n", 05502 l->name, d->name, sub->callid); 05503 } 05504 /* Not ideal, but let's send updated time at onhook and offhook, as it clears the display */ 05505 transmit_definetimedate(d); 05506 } 05507 return 1; 05508 }
static int handle_open_receive_channel_ack_message | ( | struct skinny_req * | req, | |
struct skinnysession * | s | |||
) | [static] |
Definition at line 5694 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().
05695 { 05696 struct skinny_device *d = s->device; 05697 struct skinny_line *l; 05698 struct skinny_subchannel *sub; 05699 struct ast_format_list fmt; 05700 struct sockaddr_in sin = { 0, }; 05701 struct sockaddr_in us = { 0, }; 05702 struct ast_sockaddr sin_tmp; 05703 struct ast_sockaddr us_tmp; 05704 uint32_t addr; 05705 int port; 05706 int status; 05707 int passthruid; 05708 05709 status = letohl(req->data.openreceivechannelack.status); 05710 if (status) { 05711 ast_log(LOG_ERROR, "Open Receive Channel Failure\n"); 05712 return 0; 05713 } 05714 addr = req->data.openreceivechannelack.ipAddr; 05715 port = letohl(req->data.openreceivechannelack.port); 05716 passthruid = letohl(req->data.openreceivechannelack.passThruId); 05717 05718 sin.sin_family = AF_INET; 05719 sin.sin_addr.s_addr = addr; 05720 sin.sin_port = htons(port); 05721 05722 sub = find_subchannel_by_reference(d, passthruid); 05723 05724 if (!sub) 05725 return 0; 05726 05727 l = sub->parent; 05728 05729 if (sub->rtp) { 05730 ast_sockaddr_from_sin(&sin_tmp, &sin); 05731 ast_rtp_instance_set_remote_address(sub->rtp, &sin_tmp); 05732 ast_rtp_instance_get_local_address(sub->rtp, &us_tmp); 05733 ast_sockaddr_to_sin(&us_tmp, &us); 05734 us.sin_addr.s_addr = us.sin_addr.s_addr ? us.sin_addr.s_addr : d->ourip.s_addr; 05735 } else { 05736 ast_log(LOG_ERROR, "No RTP structure, this is very bad\n"); 05737 return 0; 05738 } 05739 05740 if (skinnydebug) { 05741 ast_verb(1, "device ipaddr = %s:%d\n", ast_inet_ntoa(sin.sin_addr), ntohs(sin.sin_port)); 05742 ast_verb(1, "asterisk ipaddr = %s:%d\n", ast_inet_ntoa(us.sin_addr), ntohs(us.sin_port)); 05743 } 05744 05745 fmt = ast_codec_pref_getsize(&l->prefs, ast_best_codec(l->capability)); 05746 05747 if (skinnydebug) 05748 ast_verb(1, "Setting payloadType to '%s' (%d ms)\n", ast_getformatname(fmt.bits), fmt.cur_ms); 05749 05750 transmit_startmediatransmission(d, sub, us, fmt); 05751 05752 return 1; 05753 }
static int handle_register_message | ( | struct skinny_req * | req, | |
struct skinnysession * | s | |||
) | [static] |
Definition at line 4785 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().
04786 { 04787 struct skinny_device *d = NULL; 04788 char name[16]; 04789 int res; 04790 04791 memcpy(&name, req->data.reg.name, sizeof(name)); 04792 04793 res = skinny_register(req, s); 04794 if (!res) { 04795 ast_log(LOG_ERROR, "Rejecting Device %s: Device not found\n", name); 04796 if (!(req = req_alloc(sizeof(struct register_rej_message), REGISTER_REJ_MESSAGE))) 04797 return -1; 04798 04799 snprintf(req->data.regrej.errMsg, sizeof(req->data.regrej.errMsg), "No Authority: %s", name); 04800 04801 /* transmit_respons in line as we don't have a valid d */ 04802 ast_mutex_lock(&s->lock); 04803 04804 if (letohl(req->len) > SKINNY_MAX_PACKET || letohl(req->len) < 0) { 04805 ast_log(LOG_WARNING, "transmit_response: the length (%d) of the request is out of bounds (%d) \n", letohl(req->len), SKINNY_MAX_PACKET); 04806 ast_mutex_unlock(&s->lock); 04807 return -1; 04808 } 04809 04810 memset(s->outbuf, 0, sizeof(s->outbuf)); 04811 memcpy(s->outbuf, req, skinny_header_size); 04812 memcpy(s->outbuf+skinny_header_size, &req->data, letohl(req->len)); 04813 04814 res = write(s->fd, s->outbuf, letohl(req->len)+8); 04815 04816 if (res != letohl(req->len)+8) { 04817 ast_log(LOG_WARNING, "Transmit: write only sent %d out of %d bytes: %s\n", res, letohl(req->len)+8, strerror(errno)); 04818 } 04819 04820 ast_mutex_unlock(&s->lock); 04821 04822 return 0; 04823 } 04824 ast_atomic_fetchadd_int(&unauth_sessions, -1); 04825 04826 ast_verb(3, "Device '%s' successfully registered\n", name); 04827 04828 d = s->device; 04829 04830 if (!(req = req_alloc(sizeof(struct register_ack_message), REGISTER_ACK_MESSAGE))) 04831 return -1; 04832 04833 req->data.regack.res[0] = '0'; 04834 req->data.regack.res[1] = '\0'; 04835 req->data.regack.keepAlive = htolel(keep_alive); 04836 memcpy(req->data.regack.dateTemplate, date_format, sizeof(req->data.regack.dateTemplate)); 04837 req->data.regack.res2[0] = '0'; 04838 req->data.regack.res2[1] = '\0'; 04839 req->data.regack.secondaryKeepAlive = htolel(keep_alive); 04840 transmit_response(d, req); 04841 if (skinnydebug) 04842 ast_verb(1, "Requesting capabilities\n"); 04843 04844 if (!(req = req_alloc(0, CAPABILITIES_REQ_MESSAGE))) 04845 return -1; 04846 04847 transmit_response(d, req); 04848 04849 return res; 04850 }
static char* handle_skinny_reload | ( | struct ast_cli_entry * | e, | |
int | cmd, | |||
struct ast_cli_args * | a | |||
) | [static] |
Definition at line 2923 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.
02924 { 02925 switch (cmd) { 02926 case CLI_INIT: 02927 e->command = "skinny reload"; 02928 e->usage = 02929 "Usage: skinny reload\n" 02930 " Reloads the chan_skinny configuration\n"; 02931 return NULL; 02932 case CLI_GENERATE: 02933 return NULL; 02934 } 02935 02936 if (a->argc != e->args) 02937 return CLI_SHOWUSAGE; 02938 02939 skinny_reload(); 02940 return CLI_SUCCESS; 02941 02942 }
static char* handle_skinny_reset | ( | struct ast_cli_entry * | e, | |
int | cmd, | |||
struct ast_cli_args * | a | |||
) | [static] |
Definition at line 2988 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.
02989 { 02990 struct skinny_device *d; 02991 struct skinny_req *req; 02992 02993 switch (cmd) { 02994 case CLI_INIT: 02995 e->command = "skinny reset"; 02996 e->usage = 02997 "Usage: skinny reset <DeviceId|DeviceName|all> [restart]\n" 02998 " Causes a Skinny device to reset itself, optionally with a full restart\n"; 02999 return NULL; 03000 case CLI_GENERATE: 03001 return complete_skinny_reset(a->line, a->word, a->pos, a->n); 03002 } 03003 03004 if (a->argc < 3 || a->argc > 4) 03005 return CLI_SHOWUSAGE; 03006 03007 AST_LIST_LOCK(&devices); 03008 AST_LIST_TRAVERSE(&devices, d, list) { 03009 int fullrestart = 0; 03010 if (!strcasecmp(a->argv[2], d->id) || !strcasecmp(a->argv[2], d->name) || !strcasecmp(a->argv[2], "all")) { 03011 if (!(d->session)) 03012 continue; 03013 03014 if (!(req = req_alloc(sizeof(struct reset_message), RESET_MESSAGE))) 03015 continue; 03016 03017 if (a->argc == 4 && !strcasecmp(a->argv[3], "restart")) 03018 fullrestart = 1; 03019 03020 if (fullrestart) 03021 req->data.reset.resetType = 2; 03022 else 03023 req->data.reset.resetType = 1; 03024 03025 ast_verb(3, "%s device %s.\n", (fullrestart) ? "Restarting" : "Resetting", d->id); 03026 transmit_response(d, req); 03027 } 03028 } 03029 AST_LIST_UNLOCK(&devices); 03030 return CLI_SUCCESS; 03031 }
static char* handle_skinny_set_debug | ( | struct ast_cli_entry * | e, | |
int | cmd, | |||
struct ast_cli_args * | a | |||
) | [static] |
Definition at line 2881 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.
02882 { 02883 switch (cmd) { 02884 case CLI_INIT: 02885 #ifdef SKINNY_DEVMODE 02886 e->command = "skinny set debug {off|on|packet}"; 02887 e->usage = 02888 "Usage: skinny set debug {off|on|packet}\n" 02889 " Enables/Disables dumping of Skinny packets for debugging purposes\n"; 02890 #else 02891 e->command = "skinny set debug {off|on}"; 02892 e->usage = 02893 "Usage: skinny set debug {off|on}\n" 02894 " Enables/Disables dumping of Skinny packets for debugging purposes\n"; 02895 #endif 02896 return NULL; 02897 case CLI_GENERATE: 02898 return NULL; 02899 } 02900 02901 if (a->argc != e->args) 02902 return CLI_SHOWUSAGE; 02903 02904 if (!strncasecmp(a->argv[e->args - 1], "on", 2)) { 02905 skinnydebug = 1; 02906 ast_cli(a->fd, "Skinny Debugging Enabled\n"); 02907 return CLI_SUCCESS; 02908 } else if (!strncasecmp(a->argv[e->args - 1], "off", 3)) { 02909 skinnydebug = 0; 02910 ast_cli(a->fd, "Skinny Debugging Disabled\n"); 02911 return CLI_SUCCESS; 02912 #ifdef SKINNY_DEVMODE 02913 } else if (!strncasecmp(a->argv[e->args - 1], "packet", 6)) { 02914 skinnydebug = 2; 02915 ast_cli(a->fd, "Skinny Debugging Enabled including Packets\n"); 02916 return CLI_SUCCESS; 02917 #endif 02918 } else { 02919 return CLI_SHOWUSAGE; 02920 } 02921 }
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 3368 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.
03369 { 03370 switch (cmd) { 03371 case CLI_INIT: 03372 e->command = "skinny show device"; 03373 e->usage = 03374 "Usage: skinny show device <DeviceId|DeviceName>\n" 03375 " Lists all deviceinformation of a specific device known to the Skinny subsystem.\n"; 03376 return NULL; 03377 case CLI_GENERATE: 03378 return complete_skinny_show_device(a->line, a->word, a->pos, a->n); 03379 } 03380 03381 return _skinny_show_device(0, a->fd, NULL, NULL, a->argc, (const char **) a->argv); 03382 }
static char* handle_skinny_show_devices | ( | struct ast_cli_entry * | e, | |
int | cmd, | |||
struct ast_cli_args * | a | |||
) | [static] |
Definition at line 3234 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.
03235 { 03236 03237 switch (cmd) { 03238 case CLI_INIT: 03239 e->command = "skinny show devices"; 03240 e->usage = 03241 "Usage: skinny show devices\n" 03242 " Lists all devices known to the Skinny subsystem.\n"; 03243 return NULL; 03244 case CLI_GENERATE: 03245 return NULL; 03246 } 03247 03248 return _skinny_show_devices(a->fd, NULL, NULL, NULL, a->argc, (const char **) a->argv); 03249 }
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 3661 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.
03662 { 03663 switch (cmd) { 03664 case CLI_INIT: 03665 e->command = "skinny show line"; 03666 e->usage = 03667 "Usage: skinny show line <Line> [ on <DeviceID|DeviceName> ]\n" 03668 " List all lineinformation of a specific line known to the Skinny subsystem.\n"; 03669 return NULL; 03670 case CLI_GENERATE: 03671 return complete_skinny_show_line(a->line, a->word, a->pos, a->n); 03672 } 03673 03674 return _skinny_show_line(0, a->fd, NULL, NULL, a->argc, (const char **) a->argv); 03675 }
static char* handle_skinny_show_lines | ( | struct ast_cli_entry * | e, | |
int | cmd, | |||
struct ast_cli_args * | a | |||
) | [static] |
Definition at line 3482 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.
03483 { 03484 switch (cmd) { 03485 case CLI_INIT: 03486 e->command = "skinny show lines [verbose]"; 03487 e->usage = 03488 "Usage: skinny show lines\n" 03489 " Lists all lines known to the Skinny subsystem.\n" 03490 " If 'verbose' is specified, the output includes\n" 03491 " information about subs for each line.\n"; 03492 return NULL; 03493 case CLI_GENERATE: 03494 return NULL; 03495 } 03496 03497 if (a->argc == e->args) { 03498 if (strcasecmp(a->argv[e->args-1], "verbose")) { 03499 return CLI_SHOWUSAGE; 03500 } 03501 } else if (a->argc != e->args - 1) { 03502 return CLI_SHOWUSAGE; 03503 } 03504 03505 return _skinny_show_lines(a->fd, NULL, NULL, NULL, a->argc, (const char **) a->argv); 03506 }
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 3678 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.
03679 { 03680 switch (cmd) { 03681 case CLI_INIT: 03682 e->command = "skinny show settings"; 03683 e->usage = 03684 "Usage: skinny show settings\n" 03685 " Lists all global configuration settings of the Skinny subsystem.\n"; 03686 return NULL; 03687 case CLI_GENERATE: 03688 return NULL; 03689 } 03690 03691 if (a->argc != 3) 03692 return CLI_SHOWUSAGE; 03693 03694 ast_cli(a->fd, "\nGlobal Settings:\n"); 03695 ast_cli(a->fd, " Skinny Port: %d\n", ntohs(bindaddr.sin_port)); 03696 ast_cli(a->fd, " Bindaddress: %s\n", ast_inet_ntoa(bindaddr.sin_addr)); 03697 ast_cli(a->fd, " KeepAlive: %d\n", keep_alive); 03698 ast_cli(a->fd, " Date Format: %s\n", date_format); 03699 ast_cli(a->fd, " Voice Mail Extension: %s\n", S_OR(global_vmexten, "(not set)")); 03700 ast_cli(a->fd, " Reg. context: %s\n", S_OR(regcontext, "(not set)")); 03701 ast_cli(a->fd, " Jitterbuffer enabled: %s\n", AST_CLI_YESNO(ast_test_flag(&global_jbconf, AST_JB_ENABLED))); 03702 if (ast_test_flag(&global_jbconf, AST_JB_ENABLED)) { 03703 ast_cli(a->fd, " Jitterbuffer forced: %s\n", AST_CLI_YESNO(ast_test_flag(&global_jbconf, AST_JB_FORCED))); 03704 ast_cli(a->fd, " Jitterbuffer max size: %ld\n", global_jbconf.max_size); 03705 ast_cli(a->fd, " Jitterbuffer resync: %ld\n", global_jbconf.resync_threshold); 03706 ast_cli(a->fd, " Jitterbuffer impl: %s\n", global_jbconf.impl); 03707 if (!strcasecmp(global_jbconf.impl, "adaptive")) { 03708 ast_cli(a->fd, " Jitterbuffer tgt extra: %ld\n", global_jbconf.target_extra); 03709 } 03710 ast_cli(a->fd, " Jitterbuffer log: %s\n", AST_CLI_YESNO(ast_test_flag(&global_jbconf, AST_JB_LOG))); 03711 } 03712 03713 return CLI_SUCCESS; 03714 }
static int handle_soft_key_event_message | ( | struct skinny_req * | req, | |
struct skinnysession * | s | |||
) | [static] |
Definition at line 5805 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().
05806 { 05807 struct skinny_device *d = s->device; 05808 struct skinny_line *l; 05809 struct skinny_subchannel *sub = NULL; 05810 struct ast_channel *c; 05811 pthread_t t; 05812 int event; 05813 int instance; 05814 int callreference; 05815 05816 event = letohl(req->data.softkeyeventmessage.softKeyEvent); 05817 instance = letohl(req->data.softkeyeventmessage.instance); 05818 callreference = letohl(req->data.softkeyeventmessage.callreference); 05819 05820 if (instance) { 05821 l = find_line_by_instance(d, instance); 05822 if (callreference) { 05823 sub = find_subchannel_by_instance_reference(d, instance, callreference); 05824 } else { 05825 sub = find_subchannel_by_instance_reference(d, instance, d->lastcallreference); 05826 } 05827 } else { 05828 l = find_line_by_instance(d, d->lastlineinstance); 05829 } 05830 05831 if (!l) { 05832 if (skinnydebug) 05833 ast_verb(1, "Received Softkey Event: %d(%d/%d)\n", event, instance, callreference); 05834 return 0; 05835 } 05836 05837 ast_devstate_changed(AST_DEVICE_INUSE, "Skinny/%s@%s", l->name, d->name); 05838 05839 switch(event) { 05840 case SOFTKEY_NONE: 05841 if (skinnydebug) 05842 ast_verb(1, "Received Softkey Event: None(%d/%d)\n", instance, callreference); 05843 break; 05844 case SOFTKEY_REDIAL: 05845 if (skinnydebug) 05846 ast_verb(1, "Received Softkey Event: Redial(%d/%d)\n", instance, callreference); 05847 05848 if (ast_strlen_zero(l->lastnumberdialed)) { 05849 ast_log(LOG_WARNING, "Attempted redial, but no previously dialed number found. Ignoring button.\n"); 05850 break; 05851 } 05852 05853 if (!sub || !sub->owner) { 05854 c = skinny_new(l, AST_STATE_DOWN, NULL); 05855 } else { 05856 c = sub->owner; 05857 } 05858 05859 if (!c) { 05860 ast_log(LOG_WARNING, "Unable to create channel for %s@%s\n", l->name, d->name); 05861 } else { 05862 sub = c->tech_pvt; 05863 l->activesub = sub; 05864 if (l->hookstate == SKINNY_ONHOOK) { 05865 l->hookstate = SKINNY_OFFHOOK; 05866 transmit_speaker_mode(d, SKINNY_SPEAKERON); 05867 transmit_callstate(d, l->instance, sub->callid, SKINNY_OFFHOOK); 05868 transmit_activatecallplane(d, l); 05869 } 05870 transmit_clear_display_message(d, l->instance, sub->callid); 05871 transmit_start_tone(d, SKINNY_DIALTONE, l->instance, sub->callid); 05872 transmit_selectsoftkeys(d, l->instance, sub->callid, KEYDEF_RINGOUT); 05873 05874 if (!ast_ignore_pattern(c->context, l->lastnumberdialed)) { 05875 transmit_stop_tone(d, l->instance, sub->callid); 05876 } 05877 ast_copy_string(c->exten, l->lastnumberdialed, sizeof(c->exten)); 05878 if (ast_pthread_create(&t, NULL, skinny_newcall, c)) { 05879 ast_log(LOG_WARNING, "Unable to create new call thread: %s\n", strerror(errno)); 05880 ast_hangup(c); 05881 } 05882 } 05883 break; 05884 case SOFTKEY_NEWCALL: /* Actually the DIAL softkey */ 05885 if (skinnydebug) 05886 ast_verb(1, "Received Softkey Event: New Call(%d/%d)\n", instance, callreference); 05887 05888 /* New Call ALWAYS gets a new sub-channel */ 05889 c = skinny_new(l, AST_STATE_DOWN, NULL); 05890 sub = c->tech_pvt; 05891 05892 /* transmit_ringer_mode(d, SKINNY_RING_OFF); 05893 transmit_lamp_indication(d, STIMULUS_LINE, l->instance, SKINNY_LAMP_ON); */ 05894 05895 /* l->hookstate = SKINNY_OFFHOOK; */ 05896 05897 if (!c) { 05898 ast_log(LOG_WARNING, "Unable to create channel for %s@%s\n", l->name, d->name); 05899 } else { 05900 sub = c->tech_pvt; 05901 l->activesub = sub; 05902 if (l->hookstate == SKINNY_ONHOOK) { 05903 l->hookstate = SKINNY_OFFHOOK; 05904 transmit_speaker_mode(d, SKINNY_SPEAKERON); 05905 } 05906 ast_verb(1, "Call-id: %d\n", sub->callid); 05907 05908 transmit_callstate(d, l->instance, sub->callid, SKINNY_OFFHOOK); 05909 transmit_activatecallplane(d, l); 05910 05911 transmit_clear_display_message(d, l->instance, sub->callid); 05912 transmit_start_tone(d, SKINNY_DIALTONE, l->instance, sub->callid); 05913 transmit_selectsoftkeys(d, l->instance, sub->callid, KEYDEF_OFFHOOK); 05914 05915 /* start the switch thread */ 05916 if (ast_pthread_create(&t, NULL, skinny_ss, c)) { 05917 ast_log(LOG_WARNING, "Unable to create switch thread: %s\n", strerror(errno)); 05918 ast_hangup(c); 05919 } 05920 } 05921 break; 05922 case SOFTKEY_HOLD: 05923 if (skinnydebug) 05924 ast_verb(1, "Received Softkey Event: Hold(%d/%d)\n", instance, callreference); 05925 handle_hold_button(sub); 05926 break; 05927 case SOFTKEY_TRNSFER: 05928 if (skinnydebug) 05929 ast_verb(1, "Received Softkey Event: Transfer(%d/%d)\n", instance, callreference); 05930 if (l->transfer) 05931 handle_transfer_button(sub); 05932 else 05933 transmit_displaynotify(d, "Transfer disabled", 10); 05934 05935 break; 05936 case SOFTKEY_DND: 05937 if (skinnydebug) 05938 ast_verb(1, "Received Softkey Event: DND(%d/%d)\n", instance, callreference); 05939 05940 /* Do not disturb */ 05941 if (l->dnd != 0){ 05942 ast_verb(3, "Disabling DND on %s@%s\n", l->name, d->name); 05943 l->dnd = 0; 05944 transmit_lamp_indication(d, STIMULUS_DND, 1, SKINNY_LAMP_ON); 05945 transmit_displaynotify(d, "DnD disabled", 10); 05946 } else { 05947 ast_verb(3, "Enabling DND on %s@%s\n", l->name, d->name); 05948 l->dnd = 1; 05949 transmit_lamp_indication(d, STIMULUS_DND, 1, SKINNY_LAMP_OFF); 05950 transmit_displaynotify(d, "DnD enabled", 10); 05951 } 05952 break; 05953 case SOFTKEY_CFWDALL: 05954 if (skinnydebug) 05955 ast_verb(1, "Received Softkey Event: Forward All(%d/%d)\n", instance, callreference); 05956 05957 if (!sub || !sub->owner) { 05958 c = skinny_new(l, AST_STATE_DOWN, NULL); 05959 } else { 05960 c = sub->owner; 05961 } 05962 05963 if (!c) { 05964 ast_log(LOG_WARNING, "Unable to create channel for %s@%s\n", l->name, d->name); 05965 } else { 05966 sub = c->tech_pvt; 05967 l->activesub = sub; 05968 handle_callforward_button(sub, SKINNY_CFWD_ALL); 05969 } 05970 break; 05971 case SOFTKEY_CFWDBUSY: 05972 if (skinnydebug) 05973 ast_verb(1, "Received Softkey Event: Forward Busy (%d/%d)\n", instance, callreference); 05974 05975 if (!sub || !sub->owner) { 05976 c = skinny_new(l, AST_STATE_DOWN, NULL); 05977 } else { 05978 c = sub->owner; 05979 } 05980 05981 if (!c) { 05982 ast_log(LOG_WARNING, "Unable to create channel for %s@%s\n", l->name, d->name); 05983 } else { 05984 sub = c->tech_pvt; 05985 l->activesub = sub; 05986 handle_callforward_button(sub, SKINNY_CFWD_BUSY); 05987 } 05988 break; 05989 case SOFTKEY_CFWDNOANSWER: 05990 if (skinnydebug) 05991 ast_verb(1, "Received Softkey Event: Forward No Answer (%d/%d)\n", instance, callreference); 05992 05993 #if 0 /* Not sure how to handle this yet */ 05994 if (!sub || !sub->owner) { 05995 c = skinny_new(l, AST_STATE_DOWN, NULL); 05996 } else { 05997 c = sub->owner; 05998 } 05999 06000 if (!c) { 06001 ast_log(LOG_WARNING, "Unable to create channel for %s@%s\n", l->name, d->name); 06002 } else { 06003 sub = c->tech_pvt; 06004 l->activesub = sub; 06005 handle_callforward_button(sub, SKINNY_CFWD_NOANSWER); 06006 } 06007 #endif 06008 break; 06009 case SOFTKEY_BKSPC: 06010 if (skinnydebug) 06011 ast_verb(1, "Received Softkey Event: Backspace(%d/%d)\n", instance, callreference); 06012 break; 06013 case SOFTKEY_ENDCALL: 06014 if (skinnydebug) 06015 ast_verb(1, "Received Softkey Event: End Call(%d/%d)\n", instance, callreference); 06016 06017 if (l->hookstate == SKINNY_ONHOOK) { 06018 /* Something else already put us back on hook */ 06019 break; 06020 } 06021 if (sub) { 06022 int onlysub = 0; 06023 06024 if (!AST_LIST_NEXT(sub, list)) { 06025 onlysub = 1; 06026 } else { 06027 AST_LIST_REMOVE(&l->sub, sub, list); 06028 } 06029 06030 sub->cxmode = SKINNY_CX_RECVONLY; 06031 if (onlysub || sub->xferor){ /*Are there other calls to this device */ 06032 l->hookstate = SKINNY_ONHOOK; 06033 if (skinnydebug) 06034 ast_debug(1, "Skinny %s@%s-%d went on hook\n", l->name, d->name, callreference); 06035 } 06036 06037 if (l->hookstate == SKINNY_ONHOOK) { 06038 transmit_closereceivechannel(d, sub); 06039 transmit_stopmediatransmission(d, sub); 06040 transmit_speaker_mode(d, SKINNY_SPEAKEROFF); 06041 transmit_clearpromptmessage(d, instance, sub->callid); 06042 transmit_callstate(d, l->instance, sub->callid, SKINNY_ONHOOK); 06043 transmit_selectsoftkeys(d, 0, 0, KEYDEF_ONHOOK); 06044 transmit_activatecallplane(d, l); 06045 } else if (l->hookstate == SKINNY_OFFHOOK) { 06046 transmit_callstate(d, l->instance, sub->callid, SKINNY_OFFHOOK); 06047 transmit_activatecallplane(d, l); 06048 } else { 06049 transmit_callstate(d, l->instance, sub->callid, l->hookstate); 06050 } 06051 06052 ast_devstate_changed(AST_DEVICE_NOT_INUSE, "Skinny/%s@%s", l->name, d->name); 06053 if (skinnydebug) 06054 ast_verb(1, "Skinny %s@%s went on hook\n", l->name, d->name); 06055 if (l->transfer && sub->xferor && sub->owner->_state >= AST_STATE_RING) { 06056 /* We're allowed to transfer, we have two active calls and 06057 we made at least one of the calls. Let's try and transfer */ 06058 handle_transfer_button(sub); 06059 } else { 06060 /* Hangup the current call */ 06061 /* If there is another active call, skinny_hangup will ring the phone with the other call */ 06062 if (sub->xferor && sub->related){ 06063 sub->related->related = NULL; 06064 sub->related->blindxfer = 0; 06065 } 06066 06067 if (sub->owner) { 06068 sub->alreadygone = 1; 06069 ast_queue_hangup(sub->owner); 06070 } else { 06071 ast_log(LOG_WARNING, "Skinny(%s@%s-%d) channel already destroyed\n", 06072 l->name, d->name, sub->callid); 06073 } 06074 } 06075 if ((l->hookstate == SKINNY_ONHOOK) && (AST_LIST_NEXT(sub, list) && !AST_LIST_NEXT(sub, list)->rtp)) { 06076 ast_devstate_changed(AST_DEVICE_NOT_INUSE, "Skinny/%s@%s", l->name, d->name); 06077 } 06078 } 06079 break; 06080 case SOFTKEY_RESUME: 06081 if (skinnydebug) 06082 ast_verb(1, "Received Softkey Event: Resume(%d/%d)\n", instance, callreference); 06083 06084 if (sub) { 06085 if (sub->onhold) { 06086 skinny_unhold(sub); 06087 transmit_selectsoftkeys(d, l->instance, sub->callid, KEYDEF_CONNECTED); 06088 } else { 06089 skinny_hold(sub); 06090 transmit_selectsoftkeys(d, l->instance, sub->callid, KEYDEF_ONHOLD); 06091 } 06092 } 06093 06094 break; 06095 case SOFTKEY_ANSWER: 06096 if (skinnydebug) 06097 ast_verb(1, "Received Softkey Event: Answer(%d/%d)\n", instance, callreference); 06098 06099 transmit_ringer_mode(d, SKINNY_RING_OFF); 06100 transmit_lamp_indication(d, STIMULUS_LINE, l->instance, SKINNY_LAMP_ON); 06101 if (l->hookstate == SKINNY_ONHOOK) { 06102 transmit_speaker_mode(d, SKINNY_SPEAKERON); 06103 l->hookstate = SKINNY_OFFHOOK; 06104 } 06105 06106 if (sub && sub->outgoing) { 06107 /* We're answering a ringing call */ 06108 ast_queue_control(sub->owner, AST_CONTROL_ANSWER); 06109 transmit_callstate(d, l->instance, sub->callid, SKINNY_OFFHOOK); 06110 transmit_activatecallplane(d, l); 06111 transmit_stop_tone(d, l->instance, sub->callid); 06112 transmit_callstate(d, sub->parent->instance, sub->callid, SKINNY_CONNECTED); 06113 transmit_selectsoftkeys(d, l->instance, sub->callid, KEYDEF_CONNECTED); 06114 start_rtp(sub); 06115 ast_setstate(sub->owner, AST_STATE_UP); 06116 } 06117 break; 06118 case SOFTKEY_INFO: 06119 if (skinnydebug) 06120 ast_verb(1, "Received Softkey Event: Info(%d/%d)\n", instance, callreference); 06121 break; 06122 case SOFTKEY_CONFRN: 06123 if (skinnydebug) 06124 ast_verb(1, "Received Softkey Event: Conference(%d/%d)\n", instance, callreference); 06125 /* XXX determine the best way to pull off a conference. Meetme? */ 06126 break; 06127 case SOFTKEY_PARK: 06128 { 06129 int extout; 06130 char message[32]; 06131 06132 if (skinnydebug) 06133 ast_verb(1, "Received Softkey Event: Park Call(%d/%d)\n", instance, callreference); 06134 06135 if ((sub && sub->owner) && (sub->owner->_state == AST_STATE_UP)){ 06136 c = sub->owner; 06137 if (ast_bridged_channel(c)) { 06138 if (!ast_masq_park_call(ast_bridged_channel(c), c, 0, &extout)) { 06139 snprintf(message, sizeof(message), "Call Parked at: %d", extout); 06140 transmit_displaynotify(d, message, 10); 06141 } else { 06142 transmit_displaynotify(d, "Call Park failed", 10); 06143 } 06144 } else { 06145 transmit_displaynotify(d, "Call Park not available", 10); 06146 } 06147 } else { 06148 transmit_displaynotify(d, "Call Park not available", 10); 06149 } 06150 break; 06151 } 06152 case SOFTKEY_JOIN: 06153 if (skinnydebug) 06154 ast_verb(1, "Received Softkey Event: Join(%d/%d)\n", instance, callreference); 06155 break; 06156 case SOFTKEY_MEETME: 06157 /* XXX How is this different from CONFRN? */ 06158 if (skinnydebug) 06159 ast_verb(1, "Received Softkey Event: Meetme(%d/%d)\n", instance, callreference); 06160 break; 06161 case SOFTKEY_PICKUP: 06162 if (skinnydebug) 06163 ast_verb(1, "Received Softkey Event: Pickup(%d/%d)\n", instance, callreference); 06164 break; 06165 case SOFTKEY_GPICKUP: 06166 if (skinnydebug) 06167 ast_verb(1, "Received Softkey Event: Group Pickup(%d/%d)\n", instance, callreference); 06168 break; 06169 default: 06170 if (skinnydebug) 06171 ast_verb(1, "Received unknown Softkey Event: %d(%d/%d)\n", event, instance, callreference); 06172 break; 06173 } 06174 06175 return 1; 06176 }
static int handle_stimulus_message | ( | struct skinny_req * | req, | |
struct skinnysession * | s | |||
) | [static] |
Definition at line 4977 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().
04978 { 04979 struct skinny_device *d = s->device; 04980 struct skinny_line *l; 04981 struct skinny_subchannel *sub; 04982 /*struct skinny_speeddial *sd;*/ 04983 struct ast_channel *c; 04984 pthread_t t; 04985 int event; 04986 int instance; 04987 int callreference; 04988 /*int res = 0;*/ 04989 04990 event = letohl(req->data.stimulus.stimulus); 04991 instance = letohl(req->data.stimulus.stimulusInstance); 04992 callreference = letohl(req->data.stimulus.callreference); 04993 if (skinnydebug) 04994 ast_verb(1, "callreference in handle_stimulus_message is '%d'\n", callreference); 04995 04996 /* Note that this call should be using the passed in instance and callreference */ 04997 sub = find_subchannel_by_instance_reference(d, d->lastlineinstance, d->lastcallreference); 04998 04999 if (!sub) { 05000 l = find_line_by_instance(d, d->lastlineinstance); 05001 if (!l) { 05002 return 0; 05003 } 05004 sub = l->activesub; 05005 } else { 05006 l = sub->parent; 05007 } 05008 05009 switch(event) { 05010 case STIMULUS_REDIAL: 05011 if (skinnydebug) 05012 ast_verb(1, "Received Stimulus: Redial(%d/%d)\n", instance, callreference); 05013 05014 if (ast_strlen_zero(l->lastnumberdialed)) { 05015 ast_log(LOG_WARNING, "Attempted redial, but no previously dialed number found.\n"); 05016 l->hookstate = SKINNY_ONHOOK; 05017 transmit_speaker_mode(d, SKINNY_SPEAKEROFF); 05018 transmit_closereceivechannel(d, sub); 05019 transmit_stopmediatransmission(d, sub); 05020 transmit_speaker_mode(d, SKINNY_SPEAKEROFF); 05021 transmit_clearpromptmessage(d, l->instance, sub->callid); 05022 transmit_callstate(d, l->instance, sub->callid, SKINNY_ONHOOK); 05023 transmit_selectsoftkeys(d, 0, 0, KEYDEF_ONHOOK); 05024 transmit_activatecallplane(d, l); 05025 break; 05026 } 05027 05028 c = skinny_new(l, AST_STATE_DOWN, NULL); 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_callstate(d, l->instance, sub->callid, SKINNY_OFFHOOK); 05038 transmit_activatecallplane(d, l); 05039 } 05040 transmit_clear_display_message(d, l->instance, sub->callid); 05041 transmit_start_tone(d, SKINNY_DIALTONE, l->instance, sub->callid); 05042 transmit_selectsoftkeys(d, l->instance, sub->callid, KEYDEF_RINGOUT); 05043 05044 if (!ast_ignore_pattern(c->context, l->lastnumberdialed)) { 05045 transmit_stop_tone(d, l->instance, sub->callid); 05046 } 05047 ast_copy_string(c->exten, l->lastnumberdialed, sizeof(c->exten)); 05048 if (ast_pthread_create(&t, NULL, skinny_newcall, c)) { 05049 ast_log(LOG_WARNING, "Unable to create new call thread: %s\n", strerror(errno)); 05050 ast_hangup(c); 05051 } 05052 } 05053 break; 05054 case STIMULUS_SPEEDDIAL: 05055 { 05056 struct skinny_speeddial *sd; 05057 05058 if (skinnydebug) 05059 ast_verb(1, "Received Stimulus: SpeedDial(%d/%d)\n", instance, callreference); 05060 if (!(sd = find_speeddial_by_instance(d, instance, 0))) { 05061 return 0; 05062 } 05063 05064 if (!sub || !sub->owner) 05065 c = skinny_new(l, AST_STATE_DOWN, NULL); 05066 else 05067 c = sub->owner; 05068 05069 if (!c) { 05070 ast_log(LOG_WARNING, "Unable to create channel for %s@%s\n", l->name, d->name); 05071 } else { 05072 sub = c->tech_pvt; 05073 l = sub->parent; 05074 l->activesub = sub; 05075 if (l->hookstate == SKINNY_ONHOOK) { 05076 l->hookstate = SKINNY_OFFHOOK; 05077 transmit_speaker_mode(d, SKINNY_SPEAKERON); 05078 transmit_callstate(d, l->instance, sub->callid, SKINNY_OFFHOOK); 05079 transmit_activatecallplane(d, l); 05080 } 05081 transmit_clear_display_message(d, l->instance, sub->callid); 05082 transmit_start_tone(d, SKINNY_DIALTONE, l->instance, sub->callid); 05083 transmit_selectsoftkeys(d, l->instance, sub->callid, KEYDEF_RINGOUT); 05084 05085 if (!ast_ignore_pattern(c->context, sd->exten)) { 05086 transmit_stop_tone(d, l->instance, sub->callid); 05087 } 05088 if (ast_exists_extension(c, c->context, sd->exten, 1, l->cid_num)) { 05089 ast_copy_string(c->exten, sd->exten, sizeof(c->exten)); 05090 ast_copy_string(l->lastnumberdialed, sd->exten, sizeof(l->lastnumberdialed)); 05091 05092 if (ast_pthread_create(&t, NULL, skinny_newcall, c)) { 05093 ast_log(LOG_WARNING, "Unable to create new call thread: %s\n", strerror(errno)); 05094 ast_hangup(c); 05095 } 05096 break; 05097 } 05098 } 05099 } 05100 break; 05101 case STIMULUS_HOLD: 05102 if (skinnydebug) 05103 ast_verb(1, "Received Stimulus: Hold(%d/%d)\n", instance, callreference); 05104 handle_hold_button(sub); 05105 break; 05106 case STIMULUS_TRANSFER: 05107 if (skinnydebug) 05108 ast_verb(1, "Received Stimulus: Transfer(%d/%d)\n", instance, callreference); 05109 if (l->transfer) 05110 handle_transfer_button(sub); 05111 else 05112 transmit_displaynotify(d, "Transfer disabled", 10); 05113 break; 05114 case STIMULUS_CONFERENCE: 05115 if (skinnydebug) 05116 ast_verb(1, "Received Stimulus: Conference(%d/%d)\n", instance, callreference); 05117 /* XXX determine the best way to pull off a conference. Meetme? */ 05118 break; 05119 case STIMULUS_VOICEMAIL: 05120 if (skinnydebug) 05121 ast_verb(1, "Received Stimulus: Voicemail(%d/%d)\n", instance, callreference); 05122 05123 if (!sub || !sub->owner) { 05124 c = skinny_new(l, AST_STATE_DOWN, NULL); 05125 } else { 05126 c = sub->owner; 05127 } 05128 if (!c) { 05129 ast_log(LOG_WARNING, "Unable to create channel for %s@%s\n", l->name, d->name); 05130 } else { 05131 sub = c->tech_pvt; 05132 l = sub->parent; 05133 l->activesub = sub; 05134 05135 if (ast_strlen_zero(l->vmexten)) /* Exit the call if no VM pilot */ 05136 break; 05137 05138 if (l->hookstate == SKINNY_ONHOOK){ 05139 l->hookstate = SKINNY_OFFHOOK; 05140 transmit_speaker_mode(d, SKINNY_SPEAKERON); 05141 transmit_callstate(d, l->instance, sub->callid, SKINNY_OFFHOOK); 05142 transmit_activatecallplane(d, l); 05143 } 05144 05145 transmit_clear_display_message(d, l->instance, sub->callid); 05146 transmit_start_tone(d, SKINNY_DIALTONE, l->instance, sub->callid); 05147 transmit_selectsoftkeys(d, l->instance, sub->callid, KEYDEF_RINGOUT); 05148 05149 if (!ast_ignore_pattern(c->context, l->vmexten)) { 05150 transmit_stop_tone(d, l->instance, sub->callid); 05151 } 05152 05153 if (ast_exists_extension(c, c->context, l->vmexten, 1, l->cid_num)) { 05154 ast_copy_string(c->exten, l->vmexten, sizeof(c->exten)); 05155 ast_copy_string(l->lastnumberdialed, l->vmexten, sizeof(l->lastnumberdialed)); 05156 if (ast_pthread_create(&t, NULL, skinny_newcall, c)) { 05157 ast_log(LOG_WARNING, "Unable to create new call thread: %s\n", strerror(errno)); 05158 ast_hangup(c); 05159 } 05160 break; 05161 } 05162 } 05163 break; 05164 case STIMULUS_CALLPARK: 05165 { 05166 int extout; 05167 char message[32]; 05168 05169 if (skinnydebug) 05170 ast_verb(1, "Received Stimulus: Park Call(%d/%d)\n", instance, callreference); 05171 05172 if ((sub && sub->owner) && (sub->owner->_state == AST_STATE_UP)){ 05173 c = sub->owner; 05174 if (ast_bridged_channel(c)) { 05175 if (!ast_masq_park_call(ast_bridged_channel(c), c, 0, &extout)) { 05176 snprintf(message, sizeof(message), "Call Parked at: %d", extout); 05177 transmit_displaynotify(d, message, 10); 05178 } else { 05179 transmit_displaynotify(d, "Call Park failed", 10); 05180 } 05181 } else { 05182 transmit_displaynotify(d, "Call Park not available", 10); 05183 } 05184 } else { 05185 transmit_displaynotify(d, "Call Park not available", 10); 05186 } 05187 break; 05188 } 05189 case STIMULUS_DND: 05190 if (skinnydebug) 05191 ast_verb(1, "Received Stimulus: DND (%d/%d)\n", instance, callreference); 05192 05193 /* Do not disturb */ 05194 if (l->dnd != 0){ 05195 ast_verb(3, "Disabling DND on %s@%s\n", l->name, d->name); 05196 l->dnd = 0; 05197 transmit_lamp_indication(d, STIMULUS_DND, 1, SKINNY_LAMP_ON); 05198 transmit_displaynotify(d, "DnD disabled", 10); 05199 } else { 05200 ast_verb(3, "Enabling DND on %s@%s\n", l->name, d->name); 05201 l->dnd = 1; 05202 transmit_lamp_indication(d, STIMULUS_DND, 1, SKINNY_LAMP_OFF); 05203 transmit_displaynotify(d, "DnD enabled", 10); 05204 } 05205 break; 05206 case STIMULUS_FORWARDALL: 05207 if (skinnydebug) 05208 ast_verb(1, "Received Stimulus: Forward All(%d/%d)\n", instance, callreference); 05209 05210 if (!sub || !sub->owner) { 05211 c = skinny_new(l, AST_STATE_DOWN, NULL); 05212 } else { 05213 c = sub->owner; 05214 } 05215 05216 if (!c) { 05217 ast_log(LOG_WARNING, "Unable to create channel for %s@%s\n", l->name, d->name); 05218 } else { 05219 sub = c->tech_pvt; 05220 handle_callforward_button(sub, SKINNY_CFWD_ALL); 05221 } 05222 break; 05223 case STIMULUS_FORWARDBUSY: 05224 if (skinnydebug) 05225 ast_verb(1, "Received Stimulus: Forward Busy (%d/%d)\n", instance, callreference); 05226 05227 if (!sub || !sub->owner) { 05228 c = skinny_new(l, AST_STATE_DOWN, NULL); 05229 } else { 05230 c = sub->owner; 05231 } 05232 05233 if (!c) { 05234 ast_log(LOG_WARNING, "Unable to create channel for %s@%s\n", l->name, d->name); 05235 } else { 05236 sub = c->tech_pvt; 05237 handle_callforward_button(sub, SKINNY_CFWD_BUSY); 05238 } 05239 break; 05240 case STIMULUS_FORWARDNOANSWER: 05241 if (skinnydebug) 05242 ast_verb(1, "Received Stimulus: Forward No Answer (%d/%d)\n", instance, callreference); 05243 05244 #if 0 /* Not sure how to handle this yet */ 05245 if (!sub || !sub->owner) { 05246 c = skinny_new(l, AST_STATE_DOWN, NULL); 05247 } else { 05248 c = sub->owner; 05249 } 05250 05251 if (!c) { 05252 ast_log(LOG_WARNING, "Unable to create channel for %s@%s\n", l->name, d->name); 05253 } else { 05254 sub = c->tech_pvt; 05255 handle_callforward_button(sub, SKINNY_CFWD_NOANSWER); 05256 } 05257 #endif 05258 break; 05259 case STIMULUS_DISPLAY: 05260 /* Not sure what this is */ 05261 if (skinnydebug) 05262 ast_verb(1, "Received Stimulus: Display(%d/%d)\n", instance, callreference); 05263 break; 05264 case STIMULUS_LINE: 05265 if (skinnydebug) 05266 ast_verb(1, "Received Stimulus: Line(%d/%d)\n", instance, callreference); 05267 05268 l = find_line_by_instance(d, instance); 05269 05270 if (!l) { 05271 return 0; 05272 } 05273 05274 d->activeline = l; 05275 05276 /* turn the speaker on */ 05277 transmit_speaker_mode(d, SKINNY_SPEAKERON); 05278 transmit_ringer_mode(d, SKINNY_RING_OFF); 05279 transmit_lamp_indication(d, STIMULUS_LINE, l->instance, SKINNY_LAMP_ON); 05280 05281 l->hookstate = SKINNY_OFFHOOK; 05282 05283 if (sub && sub->outgoing) { 05284 /* We're answering a ringing call */ 05285 ast_queue_control(sub->owner, AST_CONTROL_ANSWER); 05286 transmit_callstate(d, l->instance, sub->callid, SKINNY_OFFHOOK); 05287 transmit_activatecallplane(d, l); 05288 transmit_stop_tone(d, l->instance, sub->callid); 05289 transmit_callstate(d, sub->parent->instance, sub->callid, SKINNY_CONNECTED); 05290 transmit_displaypromptstatus(d, "Connected", 0, l->instance, sub->callid); 05291 transmit_selectsoftkeys(d, l->instance, sub->callid, KEYDEF_CONNECTED); 05292 start_rtp(sub); 05293 ast_setstate(sub->owner, AST_STATE_UP); 05294 } else { 05295 if (sub && sub->owner) { 05296 ast_debug(1, "Current subchannel [%s] already has owner\n", sub->owner->name); 05297 } else { 05298 c = skinny_new(l, AST_STATE_DOWN, NULL); 05299 if (c) { 05300 sub = c->tech_pvt; 05301 l->activesub = sub; 05302 transmit_callstate(d, l->instance, sub->callid, SKINNY_OFFHOOK); 05303 transmit_activatecallplane(d, l); 05304 transmit_clear_display_message(d, l->instance, sub->callid); 05305 transmit_start_tone(d, SKINNY_DIALTONE, l->instance, sub->callid); 05306 transmit_selectsoftkeys(d, l->instance, sub->callid, KEYDEF_OFFHOOK); 05307 05308 /* start the switch thread */ 05309 if (ast_pthread_create(&t, NULL, skinny_ss, c)) { 05310 ast_log(LOG_WARNING, "Unable to create switch thread: %s\n", strerror(errno)); 05311 ast_hangup(c); 05312 } 05313 } else { 05314 ast_log(LOG_WARNING, "Unable to create channel for %s@%s\n", l->name, d->name); 05315 } 05316 } 05317 } 05318 break; 05319 default: 05320 if (skinnydebug) 05321 ast_verb(1, "RECEIVED UNKNOWN STIMULUS: %d(%d/%d)\n", event, instance, callreference); 05322 break; 05323 } 05324 ast_devstate_changed(AST_DEVICE_UNKNOWN, "Skinny/%s@%s", l->name, d->name); 05325 05326 return 1; 05327 }
static int handle_transfer_button | ( | struct skinny_subchannel * | sub | ) | [static] |
Definition at line 4707 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().
04708 { 04709 struct skinny_line *l; 04710 struct skinny_device *d; 04711 struct skinny_subchannel *newsub; 04712 struct ast_channel *c; 04713 pthread_t t; 04714 04715 if (!sub) { 04716 ast_verbose("Transfer: No subchannel to transfer\n"); 04717 return -1; 04718 } 04719 04720 l = sub->parent; 04721 d = l->device; 04722 04723 if (!d) { 04724 ast_log(LOG_WARNING, "Device for line %s is not registered.\n", l->name); 04725 return -1; 04726 } 04727 04728 if (!sub->related) { 04729 /* Another sub has not been created so this must be first XFER press */ 04730 if (!sub->onhold) { 04731 skinny_hold(sub); 04732 } 04733 c = skinny_new(l, AST_STATE_DOWN, NULL); 04734 if (c) { 04735 newsub = c->tech_pvt; 04736 /* point the sub and newsub at each other so we know they are related */ 04737 newsub->related = sub; 04738 sub->related = newsub; 04739 newsub->xferor = 1; 04740 l->activesub = newsub; 04741 transmit_callstate(d, l->instance, sub->callid, SKINNY_OFFHOOK); 04742 transmit_activatecallplane(d, l); 04743 transmit_clear_display_message(d, l->instance, newsub->callid); 04744 transmit_start_tone(d, SKINNY_DIALTONE, l->instance, newsub->callid); 04745 transmit_selectsoftkeys(d, l->instance, newsub->callid, KEYDEF_OFFHOOKWITHFEAT); 04746 /* start the switch thread */ 04747 if (ast_pthread_create(&t, NULL, skinny_ss, c)) { 04748 ast_log(LOG_WARNING, "Unable to create switch thread: %s\n", strerror(errno)); 04749 ast_hangup(c); 04750 } 04751 } else { 04752 ast_log(LOG_WARNING, "Unable to create channel for %s@%s\n", l->name, d->name); 04753 } 04754 } else { 04755 /* We already have a related sub so we can either complete XFER or go into BLINDXFER (or cancel BLINDXFER */ 04756 if (sub->blindxfer) { 04757 /* toggle blindxfer off */ 04758 sub->blindxfer = 0; 04759 sub->related->blindxfer = 0; 04760 /* we really need some indications */ 04761 } else { 04762 /* We were doing attended transfer */ 04763 if (sub->owner->_state == AST_STATE_DOWN || sub->related->owner->_state == AST_STATE_DOWN) { 04764 /* one of the subs so we cant transfer yet, toggle blindxfer on */ 04765 sub->blindxfer = 1; 04766 sub->related->blindxfer = 1; 04767 } else { 04768 /* big assumption we have two channels, lets transfer */ 04769 skinny_transfer(sub); 04770 } 04771 } 04772 } 04773 return 0; 04774 }
static int load_module | ( | void | ) | [static] |
Definition at line 7479 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.
07480 { 07481 int res = 0; 07482 07483 for (; res < ARRAY_LEN(soft_key_template_default); res++) { 07484 soft_key_template_default[res].softKeyEvent = htolel(soft_key_template_default[res].softKeyEvent); 07485 } 07486 /* load and parse config */ 07487 res = config_load(); 07488 if (res == -1) { 07489 return AST_MODULE_LOAD_DECLINE; 07490 } 07491 07492 /* Make sure we can register our skinny channel type */ 07493 if (ast_channel_register(&skinny_tech)) { 07494 ast_log(LOG_ERROR, "Unable to register channel class 'Skinny'\n"); 07495 return -1; 07496 } 07497 07498 ast_rtp_glue_register(&skinny_rtp_glue); 07499 ast_cli_register_multiple(cli_skinny, ARRAY_LEN(cli_skinny)); 07500 07501 ast_manager_register_xml("SKINNYdevices", EVENT_FLAG_SYSTEM | EVENT_FLAG_REPORTING, manager_skinny_show_devices); 07502 ast_manager_register_xml("SKINNYshowdevice", EVENT_FLAG_SYSTEM | EVENT_FLAG_REPORTING, manager_skinny_show_device); 07503 ast_manager_register_xml("SKINNYlines", EVENT_FLAG_SYSTEM | EVENT_FLAG_REPORTING, manager_skinny_show_lines); 07504 ast_manager_register_xml("SKINNYshowline", EVENT_FLAG_SYSTEM | EVENT_FLAG_REPORTING, manager_skinny_show_line); 07505 07506 sched = sched_context_create(); 07507 if (!sched) { 07508 ast_log(LOG_WARNING, "Unable to create schedule context\n"); 07509 } 07510 io = io_context_create(); 07511 if (!io) { 07512 ast_log(LOG_WARNING, "Unable to create I/O context\n"); 07513 } 07514 /* And start the monitor for the first time */ 07515 restart_monitor(); 07516 07517 return AST_MODULE_LOAD_SUCCESS; 07518 }
static int manager_skinny_show_device | ( | struct mansession * | s, | |
const struct message * | m | |||
) | [static] |
Definition at line 3347 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().
03348 { 03349 const char *a[4]; 03350 const char *device; 03351 03352 device = astman_get_header(m, "Device"); 03353 if (ast_strlen_zero(device)) { 03354 astman_send_error(s, m, "Device: <name> missing."); 03355 return 0; 03356 } 03357 a[0] = "skinny"; 03358 a[1] = "show"; 03359 a[2] = "device"; 03360 a[3] = device; 03361 03362 _skinny_show_device(1, -1, s, m, 4, a); 03363 astman_append(s, "\r\n\r\n" ); 03364 return 0; 03365 }
static int manager_skinny_show_devices | ( | struct mansession * | s, | |
const struct message * | m | |||
) | [static] |
Show SKINNY devices in the manager API.
Definition at line 3211 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().
03212 { 03213 const char *id = astman_get_header(m, "ActionID"); 03214 const char *a[] = {"skinny", "show", "devices"}; 03215 char idtext[256] = ""; 03216 int total = 0; 03217 03218 if (!ast_strlen_zero(id)) 03219 snprintf(idtext, sizeof(idtext), "ActionID: %s\r\n", id); 03220 03221 astman_send_listack(s, m, "Device status list will follow", "start"); 03222 /* List the devices in separate manager events */ 03223 _skinny_show_devices(-1, &total, s, m, 3, a); 03224 /* Send final confirmation */ 03225 astman_append(s, 03226 "Event: DevicelistComplete\r\n" 03227 "EventList: Complete\r\n" 03228 "ListItems: %d\r\n" 03229 "%s" 03230 "\r\n", total, idtext); 03231 return 0; 03232 }
static int manager_skinny_show_line | ( | struct mansession * | s, | |
const struct message * | m | |||
) | [static] |
Definition at line 3640 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().
03641 { 03642 const char *a[4]; 03643 const char *line; 03644 03645 line = astman_get_header(m, "Line"); 03646 if (ast_strlen_zero(line)) { 03647 astman_send_error(s, m, "Line: <name> missing."); 03648 return 0; 03649 } 03650 a[0] = "skinny"; 03651 a[1] = "show"; 03652 a[2] = "line"; 03653 a[3] = line; 03654 03655 _skinny_show_line(1, -1, s, m, 4, a); 03656 astman_append(s, "\r\n\r\n" ); 03657 return 0; 03658 }
static int manager_skinny_show_lines | ( | struct mansession * | s, | |
const struct message * | m | |||
) | [static] |
Show Skinny lines in the manager API.
Definition at line 3459 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().
03460 { 03461 const char *id = astman_get_header(m, "ActionID"); 03462 const char *a[] = {"skinny", "show", "lines"}; 03463 char idtext[256] = ""; 03464 int total = 0; 03465 03466 if (!ast_strlen_zero(id)) 03467 snprintf(idtext, sizeof(idtext), "ActionID: %s\r\n", id); 03468 03469 astman_send_listack(s, m, "Line status list will follow", "start"); 03470 /* List the lines in separate manager events */ 03471 _skinny_show_lines(-1, &total, s, m, 3, a); 03472 /* Send final confirmation */ 03473 astman_append(s, 03474 "Event: LinelistComplete\r\n" 03475 "EventList: Complete\r\n" 03476 "ListItems: %d\r\n" 03477 "%s" 03478 "\r\n", total, idtext); 03479 return 0; 03480 }
static void mwi_event_cb | ( | const struct ast_event * | event, | |
void * | userdata | |||
) | [static] |
Definition at line 2730 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().
02731 { 02732 struct skinny_line *l = userdata; 02733 struct skinny_device *d = l->device; 02734 if (d) { 02735 struct skinnysession *s = d->session; 02736 struct skinny_line *l2; 02737 int new_msgs = 0; 02738 int dev_msgs = 0; 02739 02740 if (s) { 02741 if (event) { 02742 l->newmsgs = ast_event_get_ie_uint(event, AST_EVENT_IE_NEWMSGS); 02743 } 02744 02745 if (l->newmsgs) { 02746 transmit_lamp_indication(d, STIMULUS_VOICEMAIL, l->instance, l->mwiblink?SKINNY_LAMP_BLINK:SKINNY_LAMP_ON); 02747 } else { 02748 transmit_lamp_indication(d, STIMULUS_VOICEMAIL, l->instance, SKINNY_LAMP_OFF); 02749 } 02750 02751 /* find out wether the device lamp should be on or off */ 02752 AST_LIST_TRAVERSE(&d->lines, l2, list) { 02753 if (l2->newmsgs) { 02754 dev_msgs++; 02755 } 02756 } 02757 02758 if (dev_msgs) { 02759 transmit_lamp_indication(d, STIMULUS_VOICEMAIL, 0, d->mwiblink?SKINNY_LAMP_BLINK:SKINNY_LAMP_ON); 02760 } else { 02761 transmit_lamp_indication(d, STIMULUS_VOICEMAIL, 0, SKINNY_LAMP_OFF); 02762 } 02763 ast_verb(3, "Skinny mwi_event_cb found %d new messages\n", new_msgs); 02764 } 02765 } 02766 }
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 3123 of file chan_skinny.c.
References ast_cli(), ast_codec_pref_index(), ast_getformatname(), and ast_codec_pref::framing.
03124 { 03125 int x, codec; 03126 03127 for(x = 0; x < 32 ; x++) { 03128 codec = ast_codec_pref_index(pref, x); 03129 if (!codec) 03130 break; 03131 ast_cli(fd, "%s", ast_getformatname(codec)); 03132 ast_cli(fd, ":%d", pref->framing[x]); 03133 if (x < 31 && ast_codec_pref_index(pref, x + 1)) 03134 ast_cli(fd, ","); 03135 } 03136 if (!x) 03137 ast_cli(fd, "none"); 03138 }
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 7597 of file chan_skinny.c.
References skinny_reload().
07598 { 07599 skinny_reload(); 07600 return 0; 07601 }
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 6630 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.
06631 { 06632 /* If we're supposed to be stopped -- stay stopped */ 06633 if (monitor_thread == AST_PTHREADT_STOP) 06634 return 0; 06635 06636 ast_mutex_lock(&monlock); 06637 if (monitor_thread == pthread_self()) { 06638 ast_mutex_unlock(&monlock); 06639 ast_log(LOG_WARNING, "Cannot kill myself\n"); 06640 return -1; 06641 } 06642 if (monitor_thread != AST_PTHREADT_NULL) { 06643 /* Wake up the thread */ 06644 pthread_kill(monitor_thread, SIGURG); 06645 } else { 06646 /* Start a new monitor */ 06647 if (ast_pthread_create_background(&monitor_thread, NULL, do_monitor, NULL) < 0) { 06648 ast_mutex_unlock(&monlock); 06649 ast_log(LOG_ERROR, "Unable to start monitor thread.\n"); 06650 return -1; 06651 } 06652 } 06653 ast_mutex_unlock(&monlock); 06654 return 0; 06655 }
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 4071 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.
04072 { 04073 int res = 0; 04074 struct skinny_subchannel *sub = ast->tech_pvt; 04075 struct skinny_line *l = sub->parent; 04076 struct skinny_device *d = l->device; 04077 04078 if (sub->blindxfer) { 04079 if (skinnydebug) 04080 ast_debug(1, "skinny_answer(%s) on %s@%s-%d with BlindXFER, transferring\n", 04081 ast->name, l->name, d->name, sub->callid); 04082 ast_setstate(ast, AST_STATE_UP); 04083 skinny_transfer(sub); 04084 return 0; 04085 } 04086 04087 sub->cxmode = SKINNY_CX_SENDRECV; 04088 if (!sub->rtp) { 04089 start_rtp(sub); 04090 } 04091 if (skinnydebug) 04092 ast_verb(1, "skinny_answer(%s) on %s@%s-%d\n", ast->name, l->name, d->name, sub->callid); 04093 if (ast->_state != AST_STATE_UP) { 04094 ast_setstate(ast, AST_STATE_UP); 04095 } 04096 04097 transmit_stop_tone(d, l->instance, sub->callid); 04098 /* order matters here... 04099 for some reason, transmit_callinfo must be before transmit_callstate, 04100 or you won't get keypad messages in some situations. */ 04101 transmit_callinfo(d, 04102 S_COR(ast->connected.id.name.valid, ast->connected.id.name.str, ""), 04103 S_COR(ast->connected.id.number.valid, ast->connected.id.number.str, ""), 04104 l->lastnumberdialed, l->lastnumberdialed, l->instance, sub->callid, 2); 04105 transmit_callstate(d, sub->parent->instance, sub->callid, SKINNY_CONNECTED); 04106 transmit_selectsoftkeys(d, l->instance, sub->callid, KEYDEF_CONNECTED); 04107 transmit_dialednumber(d, l->lastnumberdialed, l->instance, sub->callid); 04108 transmit_displaypromptstatus(d, "Connected", 0, l->instance, sub->callid); 04109 l->activesub = sub; 04110 return res; 04111 }
static int skinny_call | ( | struct ast_channel * | ast, | |
char * | dest, | |||
int | timeout | |||
) | [static] |
Definition at line 3918 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.
03919 { 03920 int res = 0; 03921 struct skinny_subchannel *sub = ast->tech_pvt; 03922 struct skinny_line *l = sub->parent; 03923 struct skinny_device *d = l->device; 03924 03925 if (!d || !d->registered) { 03926 ast_log(LOG_ERROR, "Device not registered, cannot call %s\n", dest); 03927 return -1; 03928 } 03929 03930 if ((ast->_state != AST_STATE_DOWN) && (ast->_state != AST_STATE_RESERVED)) { 03931 ast_log(LOG_WARNING, "skinny_call called on %s, neither down nor reserved\n", ast->name); 03932 return -1; 03933 } 03934 03935 if (skinnydebug) 03936 ast_verb(3, "skinny_call(%s)\n", ast->name); 03937 03938 if (l->dnd) { 03939 ast_queue_control(ast, AST_CONTROL_BUSY); 03940 return -1; 03941 } 03942 03943 if (AST_LIST_NEXT(sub,list) && !l->callwaiting) { 03944 ast_queue_control(ast, AST_CONTROL_BUSY); 03945 return -1; 03946 } 03947 03948 switch (l->hookstate) { 03949 case SKINNY_OFFHOOK: 03950 break; 03951 case SKINNY_ONHOOK: 03952 l->activesub = sub; 03953 break; 03954 default: 03955 ast_log(LOG_ERROR, "Don't know how to deal with hookstate %d\n", l->hookstate); 03956 break; 03957 } 03958 03959 transmit_callstate(d, sub->parent->instance, sub->callid, SKINNY_RINGIN); 03960 transmit_selectsoftkeys(d, l->instance, sub->callid, KEYDEF_RINGIN); 03961 transmit_displaypromptstatus(d, "Ring-In", 0, l->instance, sub->callid); 03962 transmit_callinfo(d, 03963 S_COR(ast->connected.id.name.valid, ast->connected.id.name.str, ""), 03964 S_COR(ast->connected.id.number.valid, ast->connected.id.number.str, ""), 03965 l->cid_name, l->cid_num, l->instance, sub->callid, 1); 03966 transmit_lamp_indication(d, STIMULUS_LINE, l->instance, SKINNY_LAMP_BLINK); 03967 transmit_ringer_mode(d, SKINNY_RING_INSIDE); 03968 03969 ast_setstate(ast, AST_STATE_RINGING); 03970 ast_queue_control(ast, AST_CONTROL_RINGING); 03971 sub->outgoing = 1; 03972 return res; 03973 }
static int skinny_devicestate | ( | void * | data | ) | [static] |
Definition at line 6657 of file chan_skinny.c.
References ast_strdupa, find_line_by_name(), and get_devicestate().
06658 { 06659 struct skinny_line *l; 06660 char *tmp; 06661 06662 tmp = ast_strdupa(data); 06663 06664 l = find_line_by_name(tmp); 06665 06666 return get_devicestate(l); 06667 }
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 4203 of file chan_skinny.c.
References ast_log(), LOG_NOTICE, LOG_WARNING, ast_channel::name, skinny_subchannel::owner, and ast_channel::tech_pvt.
04204 { 04205 struct skinny_subchannel *sub = newchan->tech_pvt; 04206 ast_log(LOG_NOTICE, "skinny_fixup(%s, %s)\n", oldchan->name, newchan->name); 04207 if (sub->owner != oldchan) { 04208 ast_log(LOG_WARNING, "old channel wasn't %p but was %p\n", oldchan, sub->owner); 04209 return -1; 04210 } 04211 sub->owner = newchan; 04212 return 0; 04213 }
static enum ast_rtp_glue_result skinny_get_rtp_peer | ( | struct ast_channel * | c, | |
struct ast_rtp_instance ** | instance | |||
) | [static] |
Definition at line 2784 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.
02785 { 02786 struct skinny_subchannel *sub = NULL; 02787 struct skinny_line *l; 02788 enum ast_rtp_glue_result res = AST_RTP_GLUE_RESULT_REMOTE; 02789 02790 if (skinnydebug) 02791 ast_verb(1, "skinny_get_rtp_peer() Channel = %s\n", c->name); 02792 02793 02794 if (!(sub = c->tech_pvt)) 02795 return AST_RTP_GLUE_RESULT_FORBID; 02796 02797 ast_mutex_lock(&sub->lock); 02798 02799 if (!(sub->rtp)){ 02800 ast_mutex_unlock(&sub->lock); 02801 return AST_RTP_GLUE_RESULT_FORBID; 02802 } 02803 02804 ao2_ref(sub->rtp, +1); 02805 *instance = sub->rtp; 02806 02807 l = sub->parent; 02808 02809 if (!l->directmedia || l->nat){ 02810 res = AST_RTP_GLUE_RESULT_LOCAL; 02811 if (skinnydebug) 02812 ast_verb(1, "skinny_get_rtp_peer() Using AST_RTP_GLUE_RESULT_LOCAL \n"); 02813 } 02814 02815 ast_mutex_unlock(&sub->lock); 02816 02817 return res; 02818 02819 }
static enum ast_rtp_glue_result skinny_get_vrtp_peer | ( | struct ast_channel * | c, | |
struct ast_rtp_instance ** | instance | |||
) | [static] |
Definition at line 2771 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.
02772 { 02773 struct skinny_subchannel *sub = NULL; 02774 02775 if (!(sub = c->tech_pvt) || !(sub->vrtp)) 02776 return AST_RTP_GLUE_RESULT_FORBID; 02777 02778 ao2_ref(sub->vrtp, +1); 02779 *instance = sub->vrtp; 02780 02781 return AST_RTP_GLUE_RESULT_REMOTE; 02782 }
static int skinny_hangup | ( | struct ast_channel * | ast | ) | [static] |
Definition at line 3975 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_log(), 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, LOG_WARNING, 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().
03976 { 03977 struct skinny_subchannel *sub = ast->tech_pvt; 03978 struct skinny_line *l; 03979 struct skinny_device *d; 03980 03981 if (!sub) { 03982 ast_debug(1, "Asked to hangup channel not connected\n"); 03983 return 0; 03984 } 03985 03986 l = sub->parent; 03987 d = l->device; 03988 03989 if (!d) { 03990 ast_log(LOG_WARNING, "Device for line %s is not registered.\n", l->name); 03991 return 0; 03992 } 03993 03994 if (skinnydebug) 03995 ast_verb(3,"Hanging up %s/%d\n",d->name,sub->callid); 03996 03997 AST_LIST_REMOVE(&l->sub, sub, list); 03998 03999 if (d->registered) { 04000 /* Ignoring l->type, doesn't seem relevant and previous code 04001 assigned rather than tested, ie always true */ 04002 if (!AST_LIST_EMPTY(&l->sub)) { 04003 if (sub->related) { 04004 sub->related->related = NULL; 04005 04006 } 04007 if (sub == l->activesub) { /* we are killing the active sub, but there are other subs on the line*/ 04008 ast_verb(4,"Killing active sub %d\n", sub->callid); 04009 if (sub->related) { 04010 l->activesub = sub->related; 04011 } else { 04012 if (AST_LIST_NEXT(sub, list)) { 04013 l->activesub = AST_LIST_NEXT(sub, list); 04014 } else { 04015 l->activesub = AST_LIST_FIRST(&l->sub); 04016 } 04017 } 04018 //transmit_callstate(d, l->instance, SKINNY_ONHOOK, sub->callid); 04019 transmit_activatecallplane(d, l); 04020 transmit_closereceivechannel(d, sub); 04021 transmit_stopmediatransmission(d, sub); 04022 transmit_lamp_indication(d, STIMULUS_LINE, l->instance, SKINNY_LAMP_BLINK); 04023 transmit_stop_tone(d, l->instance, sub->callid); 04024 } else { /* we are killing a background sub on the line with other subs*/ 04025 ast_verb(4,"Killing inactive sub %d\n", sub->callid); 04026 if (AST_LIST_NEXT(sub, list)) { 04027 transmit_lamp_indication(d, STIMULUS_LINE, l->instance, SKINNY_LAMP_BLINK); 04028 } else { 04029 transmit_lamp_indication(d, STIMULUS_LINE, l->instance, SKINNY_LAMP_ON); 04030 } 04031 } 04032 } else { /* no more subs on line so make idle */ 04033 ast_verb(4,"Killing only sub %d\n", sub->callid); 04034 l->hookstate = SKINNY_ONHOOK; 04035 transmit_closereceivechannel(d, sub); 04036 transmit_stopmediatransmission(d, sub); 04037 transmit_speaker_mode(d, SKINNY_SPEAKEROFF); 04038 transmit_clearpromptmessage(d, l->instance, sub->callid); 04039 transmit_callstate(d, l->instance, sub->callid, SKINNY_ONHOOK); 04040 transmit_selectsoftkeys(d, 0, 0, KEYDEF_ONHOOK); 04041 transmit_activatecallplane(d, l); 04042 l->activesub = NULL; 04043 transmit_lamp_indication(d, STIMULUS_LINE, l->instance, SKINNY_LAMP_OFF); 04044 if (sub->parent == d->activeline) { 04045 transmit_activatecallplane(d, l); 04046 transmit_closereceivechannel(d, sub); 04047 transmit_stopmediatransmission(d, sub); 04048 transmit_speaker_mode(d, SKINNY_SPEAKEROFF); 04049 transmit_ringer_mode(d, SKINNY_RING_OFF); 04050 transmit_clear_display_message(d, l->instance, sub->callid); 04051 transmit_stop_tone(d, l->instance, sub->callid); 04052 /* we should check to see if we can start the ringer if another line is ringing */ 04053 } 04054 } 04055 } 04056 ast_mutex_lock(&sub->lock); 04057 sub->owner = NULL; 04058 ast->tech_pvt = NULL; 04059 sub->alreadygone = 0; 04060 sub->outgoing = 0; 04061 if (sub->rtp) { 04062 ast_rtp_instance_destroy(sub->rtp); 04063 sub->rtp = NULL; 04064 } 04065 ast_mutex_unlock(&sub->lock); 04066 ast_free(sub); 04067 ast_module_unref(ast_module_info->self); 04068 return 0; 04069 }
static int skinny_hold | ( | struct skinny_subchannel * | sub | ) | [static] |
Definition at line 4625 of file chan_skinny.c.
References AST_CONTROL_HOLD, ast_log(), ast_queue_control_data(), ast_strlen_zero(), ast_verb, skinny_subchannel::callid, skinny_line::device, LOG_WARNING, 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().
04626 { 04627 struct skinny_line *l = sub->parent; 04628 struct skinny_device *d = l->device; 04629 04630 /* Don't try to hold a channel that doesn't exist */ 04631 if (!sub || !sub->owner) { 04632 return 0; 04633 } 04634 if (!d) { 04635 ast_log(LOG_WARNING, "Device for line %s is not registered.\n", l->name); 04636 return 0; 04637 } 04638 04639 /* Channel needs to be put on hold */ 04640 if (skinnydebug) 04641 ast_verb(1, "Putting on Hold(%d)\n", l->instance); 04642 04643 ast_queue_control_data(sub->owner, AST_CONTROL_HOLD, 04644 S_OR(l->mohsuggest, NULL), 04645 !ast_strlen_zero(l->mohsuggest) ? strlen(l->mohsuggest) + 1 : 0); 04646 04647 transmit_activatecallplane(d, l); 04648 transmit_closereceivechannel(d, sub); 04649 transmit_stopmediatransmission(d, sub); 04650 04651 transmit_callstate(d, sub->parent->instance, sub->callid, SKINNY_HOLD); 04652 transmit_lamp_indication(d, STIMULUS_LINE, l->instance, SKINNY_LAMP_WINK); 04653 sub->onhold = 1; 04654 return 1; 04655 }
static int skinny_indicate | ( | struct ast_channel * | ast, | |
int | ind, | |||
const void * | data, | |||
size_t | datalen | |||
) | [static] |
Definition at line 4386 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.
04387 { 04388 struct skinny_subchannel *sub = ast->tech_pvt; 04389 struct skinny_line *l = sub->parent; 04390 struct skinny_device *d = l->device; 04391 struct skinnysession *s; 04392 04393 if (!d) { 04394 ast_log(LOG_WARNING, "Device for line %s is not registered.\n", l->name); 04395 return -1; 04396 } 04397 s = d->session; 04398 04399 if (!s) { 04400 ast_log(LOG_NOTICE, "Asked to indicate '%s' condition on channel %s, but session does not exist.\n", control2str(ind), ast->name); 04401 return -1; 04402 } 04403 04404 if (skinnydebug) 04405 ast_verb(3, "Asked to indicate '%s' condition on channel %s\n", control2str(ind), ast->name); 04406 switch(ind) { 04407 case AST_CONTROL_RINGING: 04408 if (sub->blindxfer) { 04409 if (skinnydebug) 04410 ast_debug(1, "Channel %s set up for Blind Xfer, so Xfer rather than ring device\n", ast->name); 04411 skinny_transfer(sub); 04412 break; 04413 } 04414 if (ast->_state != AST_STATE_UP) { 04415 if (!sub->progress) { 04416 if (!d->earlyrtp) { 04417 transmit_start_tone(d, SKINNY_ALERT, l->instance, sub->callid); 04418 } 04419 transmit_callstate(d, sub->parent->instance, sub->callid, SKINNY_RINGOUT); 04420 transmit_dialednumber(d, l->lastnumberdialed, l->instance, sub->callid); 04421 transmit_displaypromptstatus(d, "Ring Out", 0, l->instance, sub->callid); 04422 transmit_callinfo(d, 04423 S_COR(ast->caller.id.name.valid, ast->caller.id.name.str, ""), 04424 S_COR(ast->caller.id.number.valid, ast->caller.id.number.str, ""), 04425 S_COR(ast->connected.id.name.valid, ast->connected.id.name.str, l->lastnumberdialed), 04426 S_COR(ast->connected.id.number.valid, ast->connected.id.number.str, l->lastnumberdialed), 04427 l->instance, sub->callid, 2); /* 2 = outgoing from phone */ 04428 sub->ringing = 1; 04429 if (!d->earlyrtp) { 04430 break; 04431 } 04432 } 04433 } 04434 return -1; /* Tell asterisk to provide inband signalling */ 04435 case AST_CONTROL_BUSY: 04436 if (ast->_state != AST_STATE_UP) { 04437 if (!d->earlyrtp) { 04438 transmit_start_tone(d, SKINNY_BUSYTONE, l->instance, sub->callid); 04439 } 04440 transmit_callstate(d, sub->parent->instance, sub->callid, SKINNY_BUSY); 04441 sub->alreadygone = 1; 04442 ast_softhangup_nolock(ast, AST_SOFTHANGUP_DEV); 04443 if (!d->earlyrtp) { 04444 break; 04445 } 04446 } 04447 return -1; /* Tell asterisk to provide inband signalling */ 04448 case AST_CONTROL_INCOMPLETE: 04449 /* Support for incomplete not supported for chan_skinny; treat as congestion */ 04450 case AST_CONTROL_CONGESTION: 04451 if (ast->_state != AST_STATE_UP) { 04452 if (!d->earlyrtp) { 04453 transmit_start_tone(d, SKINNY_REORDER, l->instance, sub->callid); 04454 } 04455 transmit_callstate(d, sub->parent->instance, sub->callid, SKINNY_CONGESTION); 04456 sub->alreadygone = 1; 04457 ast_softhangup_nolock(ast, AST_SOFTHANGUP_DEV); 04458 if (!d->earlyrtp) { 04459 break; 04460 } 04461 } 04462 return -1; /* Tell asterisk to provide inband signalling */ 04463 case AST_CONTROL_PROGRESS: 04464 if ((ast->_state != AST_STATE_UP) && !sub->progress && !sub->outgoing) { 04465 if (!d->earlyrtp) { 04466 transmit_start_tone(d, SKINNY_ALERT, l->instance, sub->callid); 04467 } 04468 transmit_callstate(d, sub->parent->instance, sub->callid, SKINNY_PROGRESS); 04469 transmit_displaypromptstatus(d, "Call Progress", 0, l->instance, sub->callid); 04470 transmit_callinfo(d, 04471 S_COR(ast->caller.id.name.valid, ast->caller.id.name.str, ""), 04472 S_COR(ast->caller.id.number.valid, ast->caller.id.number.str, ""), 04473 S_COR(ast->connected.id.name.valid, ast->connected.id.name.str, l->lastnumberdialed), 04474 S_COR(ast->connected.id.number.valid, ast->connected.id.number.str, l->lastnumberdialed), 04475 l->instance, sub->callid, 2); /* 2 = outgoing from phone */ 04476 sub->progress = 1; 04477 if (!d->earlyrtp) { 04478 break; 04479 } 04480 } 04481 return -1; /* Tell asterisk to provide inband signalling */ 04482 case -1: /* STOP_TONE */ 04483 transmit_stop_tone(d, l->instance, sub->callid); 04484 break; 04485 case AST_CONTROL_HOLD: 04486 ast_moh_start(ast, data, l->mohinterpret); 04487 break; 04488 case AST_CONTROL_UNHOLD: 04489 ast_moh_stop(ast); 04490 break; 04491 case AST_CONTROL_PROCEEDING: 04492 break; 04493 case AST_CONTROL_SRCUPDATE: 04494 ast_rtp_instance_update_source(sub->rtp); 04495 break; 04496 case AST_CONTROL_SRCCHANGE: 04497 ast_rtp_instance_change_source(sub->rtp); 04498 break; 04499 case AST_CONTROL_CONNECTED_LINE: 04500 update_connectedline(sub, data, datalen); 04501 break; 04502 default: 04503 ast_log(LOG_WARNING, "Don't know how to indicate condition %d\n", ind); 04504 return -1; /* Tell asterisk to provide inband signalling */ 04505 } 04506 return 0; 04507 }
static struct ast_channel* skinny_new | ( | struct skinny_line * | l, | |
int | state, | |||
const char * | linkedid | |||
) | [static] |
Definition at line 4509 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().
04510 { 04511 struct ast_channel *tmp; 04512 struct skinny_subchannel *sub; 04513 struct skinny_device *d = l->device; 04514 struct ast_variable *v = NULL; 04515 int fmt; 04516 04517 if (!l->device) { 04518 ast_log(LOG_WARNING, "Device for line %s is not registered.\n", l->name); 04519 return NULL; 04520 } 04521 04522 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); 04523 if (!tmp) { 04524 ast_log(LOG_WARNING, "Unable to allocate channel structure\n"); 04525 return NULL; 04526 } else { 04527 sub = ast_calloc(1, sizeof(*sub)); 04528 if (!sub) { 04529 ast_log(LOG_WARNING, "Unable to allocate Skinny subchannel\n"); 04530 return NULL; 04531 } else { 04532 ast_mutex_init(&sub->lock); 04533 04534 sub->owner = tmp; 04535 sub->callid = callnums++; 04536 d->lastlineinstance = l->instance; 04537 d->lastcallreference = sub->callid; 04538 sub->cxmode = SKINNY_CX_INACTIVE; 04539 sub->nat = l->nat; 04540 sub->parent = l; 04541 sub->onhold = 0; 04542 sub->blindxfer = 0; 04543 sub->xferor = 0; 04544 sub->related = NULL; 04545 04546 AST_LIST_INSERT_HEAD(&l->sub, sub, list); 04547 //l->activesub = sub; 04548 } 04549 tmp->tech = &skinny_tech; 04550 tmp->tech_pvt = sub; 04551 tmp->nativeformats = l->capability; 04552 if (!tmp->nativeformats) 04553 // Should throw an error 04554 tmp->nativeformats = default_capability; 04555 fmt = ast_best_codec(tmp->nativeformats); 04556 if (skinnydebug) { 04557 char buf[256]; 04558 ast_verb(1, "skinny_new: tmp->nativeformats=%s fmt=%s\n", 04559 ast_getformatname_multiple(buf, sizeof(buf), tmp->nativeformats), 04560 ast_getformatname(fmt)); 04561 } 04562 if (sub->rtp) { 04563 ast_channel_set_fd(tmp, 0, ast_rtp_instance_fd(sub->rtp, 0)); 04564 } 04565 if (state == AST_STATE_RING) { 04566 tmp->rings = 1; 04567 } 04568 tmp->writeformat = fmt; 04569 tmp->rawwriteformat = fmt; 04570 tmp->readformat = fmt; 04571 tmp->rawreadformat = fmt; 04572 if (!ast_strlen_zero(l->language)) 04573 ast_string_field_set(tmp, language, l->language); 04574 if (!ast_strlen_zero(l->accountcode)) 04575 ast_string_field_set(tmp, accountcode, l->accountcode); 04576 if (!ast_strlen_zero(l->parkinglot)) 04577 ast_string_field_set(tmp, parkinglot, l->parkinglot); 04578 if (l->amaflags) 04579 tmp->amaflags = l->amaflags; 04580 04581 ast_module_ref(ast_module_info->self); 04582 tmp->callgroup = l->callgroup; 04583 tmp->pickupgroup = l->pickupgroup; 04584 04585 /* XXX Need to figure out how to handle CFwdNoAnswer */ 04586 if (l->cfwdtype & SKINNY_CFWD_ALL) { 04587 ast_string_field_set(tmp, call_forward, l->call_forward_all); 04588 } else if (l->cfwdtype & SKINNY_CFWD_BUSY) { 04589 if (get_devicestate(l) != AST_DEVICE_NOT_INUSE) { 04590 ast_string_field_set(tmp, call_forward, l->call_forward_busy); 04591 } 04592 } 04593 04594 ast_copy_string(tmp->context, l->context, sizeof(tmp->context)); 04595 ast_copy_string(tmp->exten, l->exten, sizeof(tmp->exten)); 04596 04597 /* Don't use ast_set_callerid() here because it will 04598 * generate a needless NewCallerID event */ 04599 if (!ast_strlen_zero(l->cid_num)) { 04600 tmp->caller.ani.number.valid = 1; 04601 tmp->caller.ani.number.str = ast_strdup(l->cid_num); 04602 } 04603 04604 tmp->priority = 1; 04605 tmp->adsicpe = AST_ADSI_UNAVAILABLE; 04606 04607 if (sub->rtp) 04608 ast_jb_configure(tmp, &global_jbconf); 04609 04610 /* Set channel variables for this call from configuration */ 04611 for (v = l->chanvars ; v ; v = v->next) 04612 pbx_builtin_setvar_helper(tmp, v->name, v->value); 04613 04614 if (state != AST_STATE_DOWN) { 04615 if (ast_pbx_start(tmp)) { 04616 ast_log(LOG_WARNING, "Unable to start PBX on %s\n", tmp->name); 04617 ast_hangup(tmp); 04618 tmp = NULL; 04619 } 04620 } 04621 } 04622 return tmp; 04623 }
static void* skinny_newcall | ( | void * | data | ) | [static] |
Definition at line 3773 of file chan_skinny.c.
References ast_party_caller::ani, ast_copy_string(), ast_log(), ast_party_name_free(), ast_party_name_init(), ast_party_number_free(), ast_party_number_init(), ast_pbx_run(), ast_set_callerid(), ast_setstate(), AST_STATE_RING, ast_strdup, ast_channel::caller, skinny_subchannel::callid, ast_channel::connected, skinny_line::device, ast_channel::exten, ast_party_connected_line::id, LOG_WARNING, ast_party_id::name, ast_party_id::number, skinny_subchannel::rtp, SKINNY_REORDER, start_rtp(), ast_party_number::str, skinny_line::sub, ast_channel::tech_pvt, transmit_start_tone(), and ast_party_number::valid.
Referenced by handle_enbloc_call_message(), handle_soft_key_event_message(), handle_stimulus_message(), and skinny_ss().
03774 { 03775 struct ast_channel *c = data; 03776 struct skinny_subchannel *sub = c->tech_pvt; 03777 struct skinny_line *l = sub->parent; 03778 struct skinny_device *d = l->device; 03779 int res = 0; 03780 03781 ast_copy_string(l->lastnumberdialed, c->exten, sizeof(l->lastnumberdialed)); 03782 ast_set_callerid(c, 03783 l->hidecallerid ? "" : l->cid_num, 03784 l->hidecallerid ? "" : l->cid_name, 03785 c->caller.ani.number.valid ? NULL : l->cid_num); 03786 #if 1 /* XXX This code is probably not necessary */ 03787 ast_party_number_free(&c->connected.id.number); 03788 ast_party_number_init(&c->connected.id.number); 03789 c->connected.id.number.valid = 1; 03790 c->connected.id.number.str = ast_strdup(c->exten); 03791 ast_party_name_free(&c->connected.id.name); 03792 ast_party_name_init(&c->connected.id.name); 03793 #endif 03794 ast_setstate(c, AST_STATE_RING); 03795 if (!sub->rtp) { 03796 start_rtp(sub); 03797 } 03798 res = ast_pbx_run(c); 03799 if (res) { 03800 ast_log(LOG_WARNING, "PBX exited non-zero\n"); 03801 transmit_start_tone(d, SKINNY_REORDER, l->instance, sub->callid); 03802 } 03803 return NULL; 03804 }
static struct ast_frame * skinny_read | ( | struct ast_channel * | ast | ) | [static] |
Definition at line 4161 of file chan_skinny.c.
References ast_mutex_lock, ast_mutex_unlock, skinny_subchannel::lock, skinny_rtp_read(), and ast_channel::tech_pvt.
04162 { 04163 struct ast_frame *fr; 04164 struct skinny_subchannel *sub = ast->tech_pvt; 04165 ast_mutex_lock(&sub->lock); 04166 fr = skinny_rtp_read(sub); 04167 ast_mutex_unlock(&sub->lock); 04168 return fr; 04169 }
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 7397 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().
07398 { 07399 struct skinny_device *d; 07400 struct skinny_line *l; 07401 struct skinny_speeddial *sd; 07402 struct skinny_addon *a; 07403 struct skinny_req *req; 07404 07405 if (skinnyreload) { 07406 ast_verb(3, "Chan_skinny is already reloading.\n"); 07407 return 0; 07408 } 07409 07410 skinnyreload = 1; 07411 07412 /* Mark all devices and lines as candidates to be pruned */ 07413 AST_LIST_LOCK(&devices); 07414 AST_LIST_TRAVERSE(&devices, d, list) { 07415 d->prune = 1; 07416 } 07417 AST_LIST_UNLOCK(&devices); 07418 07419 AST_LIST_LOCK(&lines); 07420 AST_LIST_TRAVERSE(&lines, l, all) { 07421 l->prune = 1; 07422 } 07423 AST_LIST_UNLOCK(&lines); 07424 07425 config_load(); 07426 07427 /* Remove any devices that no longer exist in the config */ 07428 AST_LIST_LOCK(&devices); 07429 AST_LIST_TRAVERSE_SAFE_BEGIN(&devices, d, list) { 07430 if (!d->prune) { 07431 continue; 07432 } 07433 ast_verb(3, "Removing device '%s'\n", d->name); 07434 /* Delete all lines for this device. 07435 We do not want to free the line here, that 07436 will happen below. */ 07437 while ((l = AST_LIST_REMOVE_HEAD(&d->lines, list))) { 07438 } 07439 /* Delete all speeddials for this device */ 07440 while ((sd = AST_LIST_REMOVE_HEAD(&d->speeddials, list))) { 07441 free(sd); 07442 } 07443 /* Delete all addons for this device */ 07444 while ((a = AST_LIST_REMOVE_HEAD(&d->addons, list))) { 07445 free(a); 07446 } 07447 AST_LIST_REMOVE_CURRENT(list); 07448 free(d); 07449 } 07450 AST_LIST_TRAVERSE_SAFE_END; 07451 AST_LIST_UNLOCK(&devices); 07452 07453 AST_LIST_LOCK(&lines); 07454 AST_LIST_TRAVERSE_SAFE_BEGIN(&lines, l, all) { 07455 if (l->prune) { 07456 AST_LIST_REMOVE_CURRENT(all); 07457 free(l); 07458 } 07459 } 07460 AST_LIST_TRAVERSE_SAFE_END; 07461 AST_LIST_UNLOCK(&lines); 07462 07463 AST_LIST_TRAVERSE(&devices, d, list) { 07464 /* Do a soft reset to re-register the devices after 07465 cleaning up the removed devices and lines */ 07466 if (d->session) { 07467 ast_verb(3, "Restarting device '%s'\n", d->name); 07468 if ((req = req_alloc(sizeof(struct reset_message), RESET_MESSAGE))) { 07469 req->data.reset.resetType = 2; 07470 transmit_response(d, req); 07471 } 07472 } 07473 } 07474 07475 skinnyreload = 0; 07476 return 0; 07477 }
static struct skinny_req* skinny_req_parse | ( | struct skinnysession * | s | ) | [static] |
Definition at line 6485 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().
06486 { 06487 struct skinny_req *req; 06488 int *bufaddr; 06489 06490 if (!(req = ast_calloc(1, SKINNY_MAX_PACKET))) 06491 return NULL; 06492 06493 ast_mutex_lock(&s->lock); 06494 memcpy(req, s->inbuf, skinny_header_size); 06495 bufaddr = (int *)(s->inbuf); 06496 memcpy(&req->data, s->inbuf+skinny_header_size, letohl(*bufaddr)-4); 06497 06498 ast_mutex_unlock(&s->lock); 06499 06500 if (letohl(req->e) < 0) { 06501 ast_log(LOG_ERROR, "Event Message is NULL from socket %d, This is bad\n", s->fd); 06502 ast_free(req); 06503 return NULL; 06504 } 06505 06506 return req; 06507 }
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 6669 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().
06670 { 06671 struct skinny_line *l; 06672 struct ast_channel *tmpc = NULL; 06673 char tmp[256]; 06674 char *dest = data; 06675 06676 if (!(format &= AST_FORMAT_AUDIO_MASK)) { 06677 ast_log(LOG_NOTICE, "Asked to get a channel of unsupported format '%s'\n", ast_getformatname_multiple(tmp, sizeof(tmp), format)); 06678 return NULL; 06679 } 06680 06681 ast_copy_string(tmp, dest, sizeof(tmp)); 06682 if (ast_strlen_zero(tmp)) { 06683 ast_log(LOG_NOTICE, "Skinny channels require a device\n"); 06684 return NULL; 06685 } 06686 l = find_line_by_name(tmp); 06687 if (!l) { 06688 ast_log(LOG_NOTICE, "No available lines on: %s\n", dest); 06689 return NULL; 06690 } 06691 ast_verb(3, "skinny_request(%s)\n", tmp); 06692 tmpc = skinny_new(l, AST_STATE_DOWN, requestor ? requestor->linkedid : NULL); 06693 if (!tmpc) { 06694 ast_log(LOG_WARNING, "Unable to make channel for '%s'\n", tmp); 06695 } 06696 restart_monitor(); 06697 return tmpc; 06698 }
static struct ast_frame* skinny_rtp_read | ( | struct skinny_subchannel * | sub | ) | [static] |
Definition at line 4114 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().
04115 { 04116 struct ast_channel *ast = sub->owner; 04117 struct ast_frame *f; 04118 04119 if (!sub->rtp) { 04120 /* We have no RTP allocated for this channel */ 04121 return &ast_null_frame; 04122 } 04123 04124 switch(ast->fdno) { 04125 case 0: 04126 f = ast_rtp_instance_read(sub->rtp, 0); /* RTP Audio */ 04127 break; 04128 case 1: 04129 f = ast_rtp_instance_read(sub->rtp, 1); /* RTCP Control Channel */ 04130 break; 04131 case 2: 04132 f = ast_rtp_instance_read(sub->vrtp, 0); /* RTP Video */ 04133 break; 04134 case 3: 04135 f = ast_rtp_instance_read(sub->vrtp, 1); /* RTCP Control Channel for video */ 04136 break; 04137 #if 0 04138 case 5: 04139 /* Not yet supported */ 04140 f = ast_udptl_read(sub->udptl); /* UDPTL for T.38 */ 04141 break; 04142 #endif 04143 default: 04144 f = &ast_null_frame; 04145 } 04146 04147 if (ast) { 04148 /* We already hold the channel lock */ 04149 if (f->frametype == AST_FRAME_VOICE) { 04150 if (f->subclass.codec != ast->nativeformats) { 04151 ast_debug(1, "Oooh, format changed to %s\n", ast_getformatname(f->subclass.codec)); 04152 ast->nativeformats = f->subclass.codec; 04153 ast_set_read_format(ast, ast->readformat); 04154 ast_set_write_format(ast, ast->writeformat); 04155 } 04156 } 04157 } 04158 return f; 04159 }
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 4220 of file chan_skinny.c.
References skinny_line::device, skinny_line::sub, and ast_channel::tech_pvt.
04221 { 04222 #if 0 04223 struct skinny_subchannel *sub = ast->tech_pvt; 04224 struct skinny_line *l = sub->parent; 04225 struct skinny_device *d = l->device; 04226 int tmp; 04227 /* not right */ 04228 sprintf(tmp, "%d", digit); 04229 //transmit_tone(d, digit, l->instance, sub->callid); 04230 #endif 04231 return -1; /* Stop inband indications */ 04232 }
static void* skinny_session | ( | void * | data | ) | [static] |
Definition at line 6509 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().
06510 { 06511 int res; 06512 struct skinny_req *req; 06513 struct skinnysession *s = data; 06514 06515 ast_verb(3, "Starting Skinny session from %s\n", ast_inet_ntoa(s->sin.sin_addr)); 06516 06517 for (;;) { 06518 res = get_input(s); 06519 if (res < 0) { 06520 break; 06521 } 06522 06523 if (res > 0) 06524 { 06525 if (!(req = skinny_req_parse(s))) { 06526 destroy_session(s); 06527 return NULL; 06528 } 06529 06530 res = handle_message(req, s); 06531 if (res < 0) { 06532 destroy_session(s); 06533 return NULL; 06534 } 06535 } 06536 } 06537 ast_debug(3, "Skinny Session returned: %s\n", strerror(errno)); 06538 06539 if (s) 06540 destroy_session(s); 06541 06542 return 0; 06543 }
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 2821 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().
02822 { 02823 struct skinny_subchannel *sub; 02824 struct skinny_line *l; 02825 struct skinny_device *d; 02826 struct ast_format_list fmt; 02827 struct sockaddr_in us = { 0, }; 02828 struct sockaddr_in them = { 0, }; 02829 struct ast_sockaddr them_tmp; 02830 struct ast_sockaddr us_tmp; 02831 02832 sub = c->tech_pvt; 02833 02834 if (c->_state != AST_STATE_UP) 02835 return 0; 02836 02837 if (!sub) { 02838 return -1; 02839 } 02840 02841 l = sub->parent; 02842 d = l->device; 02843 02844 if (rtp){ 02845 ast_rtp_instance_get_remote_address(rtp, &them_tmp); 02846 ast_sockaddr_to_sin(&them_tmp, &them); 02847 02848 /* Shutdown any early-media or previous media on re-invite */ 02849 transmit_stopmediatransmission(d, sub); 02850 02851 if (skinnydebug) 02852 ast_verb(1, "Peerip = %s:%d\n", ast_inet_ntoa(them.sin_addr), ntohs(them.sin_port)); 02853 02854 fmt = ast_codec_pref_getsize(&l->prefs, ast_best_codec(l->capability)); 02855 02856 if (skinnydebug) 02857 ast_verb(1, "Setting payloadType to '%s' (%d ms)\n", ast_getformatname(fmt.bits), fmt.cur_ms); 02858 02859 if (!(l->directmedia) || (l->nat)){ 02860 ast_rtp_instance_get_local_address(rtp, &us_tmp); 02861 ast_sockaddr_to_sin(&us_tmp, &us); 02862 us.sin_addr.s_addr = us.sin_addr.s_addr ? us.sin_addr.s_addr : d->ourip.s_addr; 02863 transmit_startmediatransmission(d, sub, us, fmt); 02864 } else { 02865 transmit_startmediatransmission(d, sub, them, fmt); 02866 } 02867 02868 return 0; 02869 } 02870 /* Need a return here to break the bridge */ 02871 return 0; 02872 }
static void* skinny_ss | ( | void * | data | ) | [static] |
Definition at line 3806 of file chan_skinny.c.
References ast_channel::_state, ast_canmatch_extension(), ast_copy_string(), ast_debug, ast_exists_extension(), ast_hangup(), ast_ignore_pattern(), ast_indicate(), ast_log(), ast_matchmore_extension(), AST_MAX_EXTENSION, ast_safe_sleep(), AST_STATE_UP, ast_strlen_zero(), ast_verb, ast_channel::caller, skinny_subchannel::callid, ast_channel::context, skinny_line::device, ast_channel::exten, ast_party_caller::id, len(), LOG_WARNING, ast_channel::name, ast_party_id::number, skinny_subchannel::owner, S_COR, set_callforwards(), SKINNY_DIALTONE, SKINNY_LAMP_ON, skinny_newcall(), SKINNY_OFFHOOK, SKINNY_REORDER, STIMULUS_FORWARDALL, ast_party_number::str, skinny_line::sub, ast_channel::tech_pvt, transmit_cfwdstate(), transmit_displaynotify(), transmit_lamp_indication(), transmit_start_tone(), transmit_stop_tone(), and ast_party_number::valid.
Referenced by handle_callforward_button(), handle_offhook_message(), handle_soft_key_event_message(), handle_stimulus_message(), and handle_transfer_button().
03807 { 03808 struct ast_channel *c = data; 03809 struct skinny_subchannel *sub = c->tech_pvt; 03810 struct skinny_line *l = sub->parent; 03811 struct skinny_device *d = l->device; 03812 int len = 0; 03813 int timeout = firstdigittimeout; 03814 int res = 0; 03815 int loop_pause = 100; 03816 03817 if (!d) { 03818 ast_log(LOG_WARNING, "Device for line %s is not registered.\n", l->name); 03819 return NULL; 03820 } 03821 03822 ast_verb(3, "Starting simple switch on '%s@%s'\n", l->name, d->name); 03823 03824 len = strlen(d->exten); 03825 03826 while (len < AST_MAX_EXTENSION-1) { 03827 res = 1; /* Assume that we will get a digit */ 03828 while (strlen(d->exten) == len){ 03829 ast_safe_sleep(c, loop_pause); 03830 timeout -= loop_pause; 03831 if ( (timeout -= loop_pause) <= 0){ 03832 res = 0; 03833 break; 03834 } 03835 res = 1; 03836 } 03837 03838 timeout = 0; 03839 len = strlen(d->exten); 03840 03841 if (!ast_ignore_pattern(c->context, d->exten)) { 03842 transmit_stop_tone(d, l->instance, sub->callid); 03843 } 03844 if (ast_exists_extension(c, c->context, d->exten, 1, l->cid_num)) { 03845 if (!res || !ast_matchmore_extension(c, c->context, d->exten, 1, l->cid_num)) { 03846 if (l->getforward) { 03847 /* Record this as the forwarding extension */ 03848 set_callforwards(l, d->exten, l->getforward); 03849 ast_verb(3, "Setting call forward (%d) to '%s' on channel %s\n", 03850 l->cfwdtype, d->exten, c->name); 03851 transmit_start_tone(d, SKINNY_DIALTONE, l->instance, sub->callid); 03852 transmit_lamp_indication(d, STIMULUS_FORWARDALL, 1, SKINNY_LAMP_ON); 03853 transmit_displaynotify(d, "CFwd enabled", 10); 03854 transmit_cfwdstate(d, l); 03855 ast_safe_sleep(c, 500); 03856 ast_indicate(c, -1); 03857 ast_safe_sleep(c, 1000); 03858 memset(d->exten, 0, sizeof(d->exten)); 03859 len = 0; 03860 l->getforward = 0; 03861 if (sub->owner && sub->owner->_state != AST_STATE_UP) { 03862 ast_indicate(c, -1); 03863 ast_hangup(c); 03864 } 03865 return NULL; 03866 } else { 03867 ast_copy_string(c->exten, d->exten, sizeof(c->exten)); 03868 ast_copy_string(l->lastnumberdialed, d->exten, sizeof(l->lastnumberdialed)); 03869 memset(d->exten, 0, sizeof(d->exten)); 03870 skinny_newcall(c); 03871 return NULL; 03872 } 03873 } else { 03874 /* It's a match, but they just typed a digit, and there is an ambiguous match, 03875 so just set the timeout to matchdigittimeout and wait some more */ 03876 timeout = matchdigittimeout; 03877 } 03878 } else if (res == 0) { 03879 ast_debug(1, "Not enough digits (%s) (and no ambiguous match)...\n", d->exten); 03880 memset(d->exten, 0, sizeof(d->exten)); 03881 if (l->hookstate == SKINNY_OFFHOOK) { 03882 transmit_start_tone(d, SKINNY_REORDER, l->instance, sub->callid); 03883 } 03884 if (sub->owner && sub->owner->_state != AST_STATE_UP) { 03885 ast_indicate(c, -1); 03886 ast_hangup(c); 03887 } 03888 return NULL; 03889 } else if (!ast_canmatch_extension(c, c->context, d->exten, 1, 03890 S_COR(c->caller.id.number.valid, c->caller.id.number.str, NULL)) 03891 && ((d->exten[0] != '*') || (!ast_strlen_zero(d->exten) > 2))) { 03892 ast_log(LOG_WARNING, "Can't match [%s] from '%s' in context %s\n", d->exten, 03893 S_COR(c->caller.id.number.valid, c->caller.id.number.str, "<Unknown Caller>"), 03894 c->context); 03895 memset(d->exten, 0, sizeof(d->exten)); 03896 if (l->hookstate == SKINNY_OFFHOOK) { 03897 transmit_start_tone(d, SKINNY_REORDER, l->instance, sub->callid); 03898 /* hang out for 3 seconds to let congestion play */ 03899 ast_safe_sleep(c, 3000); 03900 } 03901 break; 03902 } 03903 if (!timeout) { 03904 timeout = gendigittimeout; 03905 } 03906 if (len && !ast_ignore_pattern(c->context, d->exten)) { 03907 ast_indicate(c, -1); 03908 } 03909 } 03910 if (c) 03911 ast_hangup(c); 03912 memset(d->exten, 0, sizeof(d->exten)); 03913 return NULL; 03914 }
static int skinny_transfer | ( | struct skinny_subchannel * | sub | ) | [static] |
Definition at line 4319 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().
04320 { 04321 struct skinny_subchannel *xferor; /* the sub doing the transferring */ 04322 struct skinny_subchannel *xferee; /* the sub being transferred */ 04323 struct ast_tone_zone_sound *ts = NULL; 04324 04325 if (ast_bridged_channel(sub->owner) || ast_bridged_channel(sub->related->owner)) { 04326 if (sub->xferor) { 04327 xferor = sub; 04328 xferee = sub->related; 04329 } else { 04330 xferor = sub; 04331 xferee = sub->related; 04332 } 04333 04334 if (skinnydebug) { 04335 ast_debug(1, "Transferee channels (local/remote): %s and %s\n", 04336 xferee->owner->name, ast_bridged_channel(xferee->owner)?ast_bridged_channel(xferee->owner)->name:""); 04337 ast_debug(1, "Transferor channels (local/remote): %s and %s\n", 04338 xferor->owner->name, ast_bridged_channel(xferor->owner)?ast_bridged_channel(xferor->owner)->name:""); 04339 } 04340 if (ast_bridged_channel(xferor->owner)) { 04341 if (ast_bridged_channel(xferee->owner)) { 04342 ast_queue_control(xferee->owner, AST_CONTROL_UNHOLD); 04343 } 04344 if (xferor->owner->_state == AST_STATE_RING) { 04345 /* play ringing inband */ 04346 if ((ts = ast_get_indication_tone(xferor->owner->zone, "ring"))) { 04347 ast_playtones_start(xferor->owner, 0, ts->data, 1); 04348 ts = ast_tone_zone_sound_unref(ts); 04349 } 04350 } 04351 if (skinnydebug) 04352 ast_debug(1, "Transfer Masquerading %s to %s\n", 04353 xferee->owner->name, ast_bridged_channel(xferor->owner)?ast_bridged_channel(xferor->owner)->name:""); 04354 if (ast_channel_masquerade(xferee->owner, ast_bridged_channel(xferor->owner))) { 04355 ast_log(LOG_WARNING, "Unable to masquerade %s as %s\n", 04356 ast_bridged_channel(xferor->owner)->name, xferee->owner->name); 04357 return -1; 04358 } 04359 } else if (ast_bridged_channel(xferee->owner)) { 04360 ast_queue_control(xferee->owner, AST_CONTROL_UNHOLD); 04361 if (xferor->owner->_state == AST_STATE_RING) { 04362 /* play ringing inband */ 04363 if ((ts = ast_get_indication_tone(xferor->owner->zone, "ring"))) { 04364 ast_playtones_start(xferor->owner, 0, ts->data, 1); 04365 ts = ast_tone_zone_sound_unref(ts); 04366 } 04367 } 04368 if (skinnydebug) 04369 ast_debug(1, "Transfer Masquerading %s to %s\n", 04370 xferor->owner->name, ast_bridged_channel(xferee->owner)?ast_bridged_channel(xferee->owner)->name:""); 04371 if (ast_channel_masquerade(xferor->owner, ast_bridged_channel(xferee->owner))) { 04372 ast_log(LOG_WARNING, "Unable to masquerade %s as %s\n", 04373 ast_bridged_channel(xferee->owner)->name, xferor->owner->name); 04374 return -1; 04375 } 04376 return 0; 04377 } else { 04378 if (option_debug) 04379 ast_log(LOG_DEBUG, "Neither %s nor %s are in a bridge, nothing to transfer\n", 04380 xferor->owner->name, xferee->owner->name); 04381 } 04382 } 04383 return 0; 04384 }
static int skinny_unhold | ( | struct skinny_subchannel * | sub | ) | [static] |
Definition at line 4657 of file chan_skinny.c.
References AST_CONTROL_UNHOLD, ast_log(), ast_queue_control(), ast_verb, skinny_subchannel::callid, skinny_line::device, LOG_WARNING, 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().
04658 { 04659 struct skinny_line *l = sub->parent; 04660 struct skinny_device *d = l->device; 04661 04662 /* Don't try to unhold a channel that doesn't exist */ 04663 if (!sub || !sub->owner) { 04664 return 0; 04665 } 04666 if (!d) { 04667 ast_log(LOG_WARNING, "Device for line %s is not registered.\n", l->name); 04668 return 0; 04669 } 04670 04671 /* Channel is on hold, so we will unhold */ 04672 if (skinnydebug) 04673 ast_verb(1, "Taking off Hold(%d)\n", l->instance); 04674 04675 ast_queue_control(sub->owner, AST_CONTROL_UNHOLD); 04676 04677 transmit_activatecallplane(d, l); 04678 04679 transmit_connect(d, sub); 04680 transmit_callstate(d, sub->parent->instance, sub->callid, SKINNY_CONNECTED); 04681 transmit_lamp_indication(d, STIMULUS_LINE, l->instance, SKINNY_LAMP_ON); 04682 l->hookstate = SKINNY_OFFHOOK; 04683 sub->onhold = 0; 04684 return 1; 04685 }
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 4171 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.
04172 { 04173 struct skinny_subchannel *sub = ast->tech_pvt; 04174 int res = 0; 04175 if (frame->frametype != AST_FRAME_VOICE) { 04176 if (frame->frametype == AST_FRAME_IMAGE) { 04177 return 0; 04178 } else { 04179 ast_log(LOG_WARNING, "Can't send %d type frames with skinny_write\n", frame->frametype); 04180 return 0; 04181 } 04182 } else { 04183 if (!(frame->subclass.codec & ast->nativeformats)) { 04184 char buf[256]; 04185 ast_log(LOG_WARNING, "Asked to transmit frame type %s, while native formats is %s (read/write = %s/%s)\n", 04186 ast_getformatname(frame->subclass.codec), 04187 ast_getformatname_multiple(buf, sizeof(buf), ast->nativeformats), 04188 ast_getformatname(ast->readformat), 04189 ast_getformatname(ast->writeformat)); 04190 return -1; 04191 } 04192 } 04193 if (sub) { 04194 ast_mutex_lock(&sub->lock); 04195 if (sub->rtp) { 04196 res = ast_rtp_instance_write(sub->rtp, frame); 04197 } 04198 ast_mutex_unlock(&sub->lock); 04199 } 04200 return res; 04201 }
static void start_rtp | ( | struct skinny_subchannel * | sub | ) | [static] |
Definition at line 3727 of file chan_skinny.c.
References ast_channel_set_fd(), ast_mutex_lock, ast_mutex_unlock, ast_rtp_codecs_packetization_set(), ast_rtp_instance_fd(), ast_rtp_instance_get_codecs(), ast_rtp_instance_new(), ast_rtp_instance_set_prop(), ast_rtp_instance_set_qos(), AST_RTP_PROPERTY_NAT, AST_RTP_PROPERTY_RTCP, ast_sockaddr_from_sin, skinny_line::device, skinny_subchannel::lock, skinny_subchannel::owner, qos, skinny_subchannel::rtp, sched, skinny_line::sub, transmit_connect(), and skinny_subchannel::vrtp.
03728 { 03729 struct skinny_line *l = sub->parent; 03730 struct skinny_device *d = l->device; 03731 int hasvideo = 0; 03732 struct ast_sockaddr bindaddr_tmp; 03733 03734 ast_mutex_lock(&sub->lock); 03735 /* Allocate the RTP */ 03736 ast_sockaddr_from_sin(&bindaddr_tmp, &bindaddr); 03737 sub->rtp = ast_rtp_instance_new("asterisk", sched, &bindaddr_tmp, NULL); 03738 if (hasvideo) 03739 sub->vrtp = ast_rtp_instance_new("asterisk", sched, &bindaddr_tmp, NULL); 03740 03741 if (sub->rtp) { 03742 ast_rtp_instance_set_prop(sub->rtp, AST_RTP_PROPERTY_RTCP, 1); 03743 } 03744 if (sub->vrtp) { 03745 ast_rtp_instance_set_prop(sub->vrtp, AST_RTP_PROPERTY_RTCP, 1); 03746 } 03747 03748 if (sub->rtp && sub->owner) { 03749 ast_channel_set_fd(sub->owner, 0, ast_rtp_instance_fd(sub->rtp, 0)); 03750 ast_channel_set_fd(sub->owner, 1, ast_rtp_instance_fd(sub->rtp, 1)); 03751 } 03752 if (hasvideo && sub->vrtp && sub->owner) { 03753 ast_channel_set_fd(sub->owner, 2, ast_rtp_instance_fd(sub->vrtp, 0)); 03754 ast_channel_set_fd(sub->owner, 3, ast_rtp_instance_fd(sub->vrtp, 1)); 03755 } 03756 if (sub->rtp) { 03757 ast_rtp_instance_set_qos(sub->rtp, qos.tos_audio, qos.cos_audio, "Skinny RTP"); 03758 ast_rtp_instance_set_prop(sub->rtp, AST_RTP_PROPERTY_NAT, l->nat); 03759 } 03760 if (sub->vrtp) { 03761 ast_rtp_instance_set_qos(sub->vrtp, qos.tos_video, qos.cos_video, "Skinny VRTP"); 03762 ast_rtp_instance_set_prop(sub->vrtp, AST_RTP_PROPERTY_NAT, l->nat); 03763 } 03764 /* Set Frame packetization */ 03765 if (sub->rtp) 03766 ast_rtp_codecs_packetization_set(ast_rtp_instance_get_codecs(sub->rtp), sub->rtp, &l->prefs); 03767 03768 /* Create the RTP connection */ 03769 transmit_connect(d, sub); 03770 ast_mutex_unlock(&sub->lock); 03771 }
static void transmit_activatecallplane | ( | struct skinny_device * | d, | |
struct skinny_line * | l | |||
) | [static] |
Definition at line 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 7520 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().
07521 { 07522 struct skinnysession *s; 07523 struct skinny_device *d; 07524 struct skinny_line *l; 07525 struct skinny_subchannel *sub; 07526 struct ast_context *con; 07527 07528 ast_rtp_glue_unregister(&skinny_rtp_glue); 07529 ast_channel_unregister(&skinny_tech); 07530 ast_cli_unregister_multiple(cli_skinny, ARRAY_LEN(cli_skinny)); 07531 07532 ast_manager_unregister("SKINNYdevices"); 07533 ast_manager_unregister("SKINNYshowdevice"); 07534 ast_manager_unregister("SKINNYlines"); 07535 ast_manager_unregister("SKINNYshowline"); 07536 07537 AST_LIST_LOCK(&sessions); 07538 /* Destroy all the interfaces and free their memory */ 07539 while((s = AST_LIST_REMOVE_HEAD(&sessions, list))) { 07540 d = s->device; 07541 AST_LIST_TRAVERSE(&d->lines, l, list){ 07542 ast_mutex_lock(&l->lock); 07543 AST_LIST_TRAVERSE(&l->sub, sub, list) { 07544 ast_mutex_lock(&sub->lock); 07545 if (sub->owner) { 07546 sub->alreadygone = 1; 07547 ast_softhangup(sub->owner, AST_SOFTHANGUP_APPUNLOAD); 07548 } 07549 ast_mutex_unlock(&sub->lock); 07550 } 07551 if (l->mwi_event_sub) 07552 ast_event_unsubscribe(l->mwi_event_sub); 07553 ast_mutex_unlock(&l->lock); 07554 manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", "ChannelType: Skinny\r\nPeer: Skinny/%s@%s\r\nPeerStatus: Unregistered\r\n", l->name, d->name); 07555 unregister_exten(l); 07556 } 07557 if (s->fd > -1) 07558 close(s->fd); 07559 pthread_cancel(s->t); 07560 pthread_kill(s->t, SIGURG); 07561 pthread_join(s->t, NULL); 07562 free(s); 07563 } 07564 AST_LIST_UNLOCK(&sessions); 07565 07566 delete_devices(); 07567 07568 ast_mutex_lock(&monlock); 07569 if ((monitor_thread != AST_PTHREADT_NULL) && (monitor_thread != AST_PTHREADT_STOP)) { 07570 pthread_cancel(monitor_thread); 07571 pthread_kill(monitor_thread, SIGURG); 07572 pthread_join(monitor_thread, NULL); 07573 } 07574 monitor_thread = AST_PTHREADT_STOP; 07575 ast_mutex_unlock(&monlock); 07576 07577 ast_mutex_lock(&netlock); 07578 if (accept_t && (accept_t != AST_PTHREADT_STOP)) { 07579 pthread_cancel(accept_t); 07580 pthread_kill(accept_t, SIGURG); 07581 pthread_join(accept_t, NULL); 07582 } 07583 accept_t = AST_PTHREADT_STOP; 07584 ast_mutex_unlock(&netlock); 07585 07586 close(skinnysock); 07587 if (sched) 07588 sched_context_destroy(sched); 07589 07590 con = ast_context_find(used_context); 07591 if (con) 07592 ast_context_destroy(con, "Skinny"); 07593 07594 return 0; 07595 }
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 (!d) { 02681 return; 02682 } 02683 02684 if (!c->caller.id.number.valid 02685 || ast_strlen_zero(c->caller.id.number.str) 02686 || !c->connected.id.number.valid 02687 || ast_strlen_zero(c->connected.id.number.str)) 02688 return; 02689 02690 if (sub->owner->_state == AST_STATE_UP) { 02691 transmit_callstate(d, l->instance, sub->callid, SKINNY_CONNECTED); 02692 transmit_displaypromptstatus(d, "Connected", 0, l->instance, sub->callid); 02693 if (sub->outgoing) 02694 transmit_callinfo(d, 02695 S_COR(c->connected.id.name.valid, c->connected.id.name.str, ""), 02696 c->connected.id.number.str, 02697 l->cid_name, l->cid_num, l->instance, sub->callid, 1); 02698 else 02699 transmit_callinfo(d, l->cid_name, l->cid_num, 02700 S_COR(c->connected.id.name.valid, c->connected.id.name.str, ""), 02701 c->connected.id.number.str, 02702 l->instance, sub->callid, 2); 02703 } else { 02704 if (sub->outgoing) { 02705 transmit_callstate(d, l->instance, sub->callid, SKINNY_RINGIN); 02706 transmit_displaypromptstatus(d, "Ring-In", 0, l->instance, sub->callid); 02707 transmit_callinfo(d, 02708 S_COR(c->connected.id.name.valid, c->connected.id.name.str, ""), 02709 c->connected.id.number.str, 02710 l->cid_name, l->cid_num, l->instance, sub->callid, 1); 02711 } else { 02712 if (!sub->ringing) { 02713 transmit_callstate(d, l->instance, sub->callid, SKINNY_RINGOUT); 02714 transmit_displaypromptstatus(d, "Ring-Out", 0, l->instance, sub->callid); 02715 sub->ringing = 1; 02716 } else { 02717 transmit_callstate(d, l->instance, sub->callid, SKINNY_PROGRESS); 02718 transmit_displaypromptstatus(d, "Call Progress", 0, l->instance, sub->callid); 02719 sub->progress = 1; 02720 } 02721 02722 transmit_callinfo(d, l->cid_name, l->cid_num, 02723 S_COR(c->connected.id.name.valid, c->connected.id.name.str, ""), 02724 c->connected.id.number.str, 02725 l->instance, sub->callid, 2); 02726 } 02727 } 02728 }
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 = "ac1f6a56484a8820659555499174e588" , .load = load_module, .unload = unload_module, .reload = reload, .load_pri = AST_MODPRI_CHANNEL_DRIVER, } [static] |
Definition at line 7608 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(), and reload_config().
struct ast_module_info* ast_module_info = &__mod_info [static] |
Definition at line 7608 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(), 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.