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