Sat Feb 11 06:34:51 2012

Asterisk developer's documentation


chan_skinny.c File Reference

Implementation of the Skinny protocol. More...

#include "asterisk.h"
#include <sys/socket.h>
#include <netinet/in.h>
#include <netinet/tcp.h>
#include <sys/ioctl.h>
#include <net/if.h>
#include <fcntl.h>
#include <netdb.h>
#include <arpa/inet.h>
#include <sys/signal.h>
#include <signal.h>
#include <ctype.h>
#include "asterisk/lock.h"
#include "asterisk/channel.h"
#include "asterisk/config.h"
#include "asterisk/module.h"
#include "asterisk/pbx.h"
#include "asterisk/sched.h"
#include "asterisk/io.h"
#include "asterisk/rtp_engine.h"
#include "asterisk/netsock.h"
#include "asterisk/acl.h"
#include "asterisk/callerid.h"
#include "asterisk/cli.h"
#include "asterisk/manager.h"
#include "asterisk/say.h"
#include "asterisk/cdr.h"
#include "asterisk/astdb.h"
#include "asterisk/features.h"
#include "asterisk/app.h"
#include "asterisk/musiconhold.h"
#include "asterisk/utils.h"
#include "asterisk/dsp.h"
#include "asterisk/stringfields.h"
#include "asterisk/abstract_jb.h"
#include "asterisk/threadstorage.h"
#include "asterisk/devicestate.h"
#include "asterisk/event.h"
#include "asterisk/indications.h"
#include "asterisk/linkedlists.h"

Include dependency graph for chan_skinny.c:

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_display_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_ip4
struct  open_receive_channel_ack_message_ip6
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
struct  skinny_container
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  skinny_subline
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_ip4
struct  start_media_transmission_message_ip6
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 __bswap_16(x)
#define __bswap_32(x)
#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 CALLSTATE2STR_BUFSIZE   15
#define CAPABILITIES_REQ_MESSAGE   0x009B
#define CAPABILITIES_RES_MESSAGE   0x0010
#define CDEV   ((struct skinny_device *)item)
#define CDEV_OPTS   ((struct skinny_device_options *)item)
#define CLEAR_DISPLAY_MESSAGE   0x009A
#define CLEAR_NOTIFY_MESSAGE   0x0115
#define CLEAR_PROMPT_MESSAGE   0x0113
#define CLINE   ((struct skinny_line *)item)
#define CLINE_OPTS   ((struct skinny_line_options *)item)
#define CLOSE_RECEIVE_CHANNEL_MESSAGE   0x0106
#define CONTROL2STR_BUFSIZE   100
#define DEFAULT_AUTH_LIMIT   50
#define DEFAULT_AUTH_TIMEOUT   30
#define DEFAULT_SKINNY_BACKLOG   2
#define DEFAULT_SKINNY_PORT   2000
#define DEFINETIMEDATE_MESSAGE   0x0094
#define DEVICE2STR_BUFSIZE   15
#define DIALED_NUMBER_MESSAGE   0x011D
#define DISPLAY_NOTIFY_MESSAGE   0x0114
#define DISPLAY_PROMPT_STATUS_MESSAGE   0x0112
#define DISPLAYTEXT_MESSAGE   0x0099
#define ENBLOC_CALL_MESSAGE   0x0004
#define FORWARD_STAT_MESSAGE   0x0090
#define HEADSET_STATUS_MESSAGE   0x002B
#define htolel(x)   __bswap_32(x)
#define htoles(x)   __bswap_16(x)
#define IP_PORT_MESSAGE   0x0002
#define KEEP_ALIVE_ACK_MESSAGE   0x0100
#define KEEP_ALIVE_MESSAGE   0x0000
#define KEYDEF_CONNECTED   1
#define KEYDEF_CONNWITHCONF   7
#define KEYDEF_CONNWITHTRANS   5
#define KEYDEF_DADFD   6
#define KEYDEF_OFFHOOK   4
#define KEYDEF_OFFHOOKWITHFEAT   9
#define KEYDEF_ONHOLD   2
#define KEYDEF_ONHOOK   0
#define KEYDEF_RINGIN   3
#define KEYDEF_RINGOUT   8
#define KEYDEF_SLACONNECTEDNOTACTIVE   12
#define KEYDEF_SLAHOLD   11
#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 MESSAGE2STR_BUFSIZE   35
#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_BARGIN   0x43
#define SKINNY_BEEPBONK   0x33
#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_DEVICECONTAINER   1
#define SKINNY_DEVONLY(code)   code
#define SKINNY_DIALTONE   0x21
#define SKINNY_HOLD   8
#define SKINNY_INCOMING   1
#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_LINECONTAINER   2
#define SKINNY_MAX_CAPABILITIES   18
#define SKINNY_MAX_PACKET   2000
#define SKINNY_MICOFF   2
#define SKINNY_MICON   1
#define SKINNY_NOTONE   0x7F
#define SKINNY_OFFHOOK   1
#define SKINNY_ONHOOK   2
#define SKINNY_OUTGOING   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_SDCONTAINER   4
#define SKINNY_SILENCE   0x00
#define SKINNY_SPEAKEROFF   2
#define SKINNY_SPEAKERON   1
#define SKINNY_SUBLINECONTAINER   3
#define SKINNY_TRANSFER   10
#define SKINNY_ZIP   0x32
#define SKINNY_ZIPZIP   0x31
#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 SUBSTATE2STR_BUFSIZE   15
#define SUBSTATE_BUSY   6
#define SUBSTATE_CALLWAIT   9
#define SUBSTATE_CONGESTION   7
#define SUBSTATE_CONNECTED   5
#define SUBSTATE_DIALING   101
#define SUBSTATE_HOLD   8
#define SUBSTATE_OFFHOOK   1
#define SUBSTATE_ONHOOK   2
#define SUBSTATE_PROGRESS   12
#define SUBSTATE_RINGIN   4
#define SUBSTATE_RINGOUT   3
#define SUBSTATE_UNSET   0
#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_callstate2str_threadbuf (void)
static void __init_control2str_threadbuf (void)
static void __init_device2str_threadbuf (void)
static void __init_message2str_threadbuf (void)
static void __init_substate2str_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 void activatesub (struct skinny_subchannel *sub, int state)
static struct ast_variableadd_var (const char *buf, struct ast_variable *list)
static char * callstate2str (int ind)
static void cleanup_stale_contexts (char *new, char *old)
static int codec_ast2skinny (const struct ast_format *astcodec)
static struct ast_formatcodec_skinny2ast (enum skinny_codecs skinnycodec, struct ast_format *result)
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_deviceconfig_device (const char *dname, struct ast_variable *v)
static struct skinny_lineconfig_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 dialandactivatesub (struct skinny_subchannel *sub, char exten[AST_MAX_EXTENSION])
static void dumpsub (struct skinny_subchannel *sub, int forcehangup)
static struct skinny_linefind_line_by_instance (struct skinny_device *d, int instance)
static struct skinny_linefind_line_by_name (const char *dest)
static struct skinny_speeddialfind_speeddial_by_instance (struct skinny_device *d, int instance, int isHint)
static struct skinny_subchannelfind_subchannel_by_instance_reference (struct skinny_device *d, int instance, int reference)
static struct skinny_subchannelfind_subchannel_by_reference (struct skinny_device *d, int reference)
static struct skinny_sublinefind_subline_by_callid (struct skinny_device *d, int callid)
static struct skinny_sublinefind_subline_by_name (const char *dest)
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_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 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 char * message2str (int type)
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 push_callinfo (struct skinny_subline *subline, struct skinny_subchannel *sub)
static void register_exten (struct skinny_line *l)
static int reload (void)
static struct skinny_reqreq_alloc (size_t size, int response_message)
static void send_callinfo (struct skinny_subchannel *sub)
static int set_callforwards (struct skinny_line *l, const char *cfwd, int cfwdtype)
static void setsubstate (struct skinny_subchannel *sub, int state)
static int skinny_answer (struct ast_channel *ast)
static int skinny_autoanswer_cb (const void *data)
static int skinny_call (struct ast_channel *ast, const char *dest, int timeout)
static struct skinny_deviceskinny_device_alloc (void)
static struct skinny_deviceskinny_device_destroy (struct skinny_device *d)
static int skinny_devicestate (const char *data)
static int skinny_extensionstate_cb (const char *context, const char *exten, enum ast_extension_states 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_indicate (struct ast_channel *ast, int ind, const void *data, size_t datalen)
static struct skinny_lineskinny_line_alloc (void)
static struct skinny_lineskinny_line_destroy (struct skinny_line *l)
static struct ast_channelskinny_new (struct skinny_line *l, struct skinny_subline *subline, int state, const char *linkedid, int direction)
static void * skinny_newcall (void *data)
static struct ast_frameskinny_read (struct ast_channel *ast)
static int skinny_register (struct skinny_req *req, struct skinnysession *s)
static int skinny_reload (void)
static struct skinny_reqskinny_req_parse (struct skinnysession *s)
static struct ast_channelskinny_request (const char *type, struct ast_format_cap *cap, const struct ast_channel *requestor, const char *dest, int *cause)
static struct ast_frameskinny_rtp_read (struct skinny_subchannel *sub)
static int skinny_sched_add (int when, ast_sched_cb callback, const void *data)
static int skinny_sched_del (int sched_id)
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, const struct ast_format_cap *codecs, int nat_active)
static void * skinny_ss (void *data)
static int skinny_transfer (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 char * substate2str (int ind)
static void transmit_activatecallplane (struct skinny_device *d, struct skinny_line *l)
static void transmit_callinfo (struct skinny_device *d, int instance, int callid, char *fromname, char *fromnum, char *toname, char *tonum, int calldirection)
static void transmit_callstate (struct skinny_device *d, int buttonInstance, unsigned callid, int state)
static void transmit_capabilitiesreq (struct skinny_device *d)
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_keepaliveack (struct skinny_device *d)
static void transmit_lamp_indication (struct skinny_device *d, int stimulus, int instance, int indication)
static void transmit_linestatres (struct skinny_device *d, int instance)
static void transmit_microphone_mode (struct skinny_device *d, int mode)
static void transmit_registerack (struct skinny_device *d)
static void transmit_registerrej (struct skinnysession *s)
static void transmit_reset (struct skinny_device *d, int fullrestart)
static void transmit_response (struct skinny_device *d, struct skinny_req *req)
static int transmit_response_bysession (struct skinnysession *s, struct skinny_req *req)
static void transmit_ringer_mode (struct skinny_device *d, int mode)
static void transmit_selectsoftkeys (struct skinny_device *d, int instance, int callid, int softkey)
static void transmit_serverres (struct skinny_device *d)
static void transmit_softkeysetres (struct skinny_device *d)
static void transmit_softkeytemplateres (struct skinny_device *d)
static void transmit_speaker_mode (struct skinny_device *d, int mode)
static void transmit_speeddialstatres (struct skinny_device *d, struct skinny_speeddial *sd)
static void transmit_start_tone (struct skinny_device *d, int tone, int instance, int reference)
static void transmit_startmediatransmission (struct skinny_device *d, struct skinny_subchannel *sub, struct sockaddr_in dest, struct ast_format_list fmt)
static void transmit_stop_tone (struct skinny_device *d, int instance, int reference)
static void transmit_stopmediatransmission (struct skinny_device *d, struct skinny_subchannel *sub)
static void transmit_versionres (struct skinny_device *d)
static int unload_module (void)
static void unregister_exten (struct skinny_line *l)
static void update_connectedline (struct skinny_subchannel *sub, const void *data, size_t datalen)

Variables

static struct ast_module_info __mod_info = { .name = AST_MODULE, .flags = AST_MODFLAG_LOAD_ORDER , .description = "Skinny Client Control Protocol (Skinny)" , .key = "This paragraph is copyright (c) 2006 by Digium, Inc. \In order for your module to load, it must return this \key via a function called \"key\". Any code which \includes this paragraph must be licensed under the GNU \General Public License version 2 or later (at your \option). In addition to Digium's general reservations \of rights, Digium expressly reserves the right to \allow other parties to license this paragraph under \different terms. Any use of Digium, Inc. trademarks or \logos (including \"Asterisk\" or \"Digium\") without \express written permission of Digium, Inc. is prohibited.\n" , .buildopt_sum = AST_BUILDOPT_SUM, .load = load_module, .unload = unload_module, .reload = reload, .load_pri = AST_MODPRI_CHANNEL_DRIVER, }
static struct in_addr __ourip
static pthread_t accept_t
static struct ast_hostent ahp
static struct ast_module_infoast_module_info = &__mod_info
static int auth_limit = DEFAULT_AUTH_LIMIT
static int auth_timeout = DEFAULT_AUTH_TIMEOUT
static struct sockaddr_in bindaddr
static int callnums = 1
static struct ast_threadstorage callstate2str_threadbuf = { .once = PTHREAD_ONCE_INIT , .key_init = __init_callstate2str_threadbuf , .custom_init = NULL , }
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 struct ast_format_capdefault_cap
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_optionsdefault_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 int keep_alive = 120
static int matchdigittimeout = 3000
static struct ast_threadstorage message2str_threadbuf = { .once = PTHREAD_ONCE_INIT , .key_init = __init_message2str_threadbuf , .custom_init = NULL , }
static ast_mutex_t netlock = { PTHREAD_MUTEX_INITIALIZER , NULL, 1 }
static char ourhost [256]
static int ourport
struct {
   unsigned int   cos
   unsigned int   cos_audio
   unsigned int   cos_video
   unsigned int   tos
   unsigned int   tos_audio
   unsigned int   tos_video
qos
static char regcontext [AST_MAX_CONTEXT]
static struct ast_sched_contextsched = 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_SLAconnectednotactive []
static const uint8_t soft_key_default_SLAhold []
static const uint8_t soft_key_default_unknown []
static struct
soft_key_template_definition 
soft_key_template_default []
static struct ast_threadstorage substate2str_threadbuf = { .once = PTHREAD_ONCE_INIT , .key_init = __init_substate2str_threadbuf , .custom_init = NULL , }
static const char tdesc [] = "Skinny Client Control Protocol (Skinny)"
static int unauth_sessions = 0
static char used_context [AST_MAX_EXTENSION]
static char version_id [16] = "P002F202"


Detailed Description

Implementation of the Skinny protocol.

Author:
Jeremy McNamara & Florian Overkamp & North Antara

Definition in file chan_skinny.c.


Define Documentation

#define __bswap_16 (  ) 

Value:

((((x) & 0xff00) >> 8) | \
    (((x) & 0x00ff) << 8))

Definition at line 217 of file chan_skinny.c.

#define __bswap_32 (  ) 

Value:

((((x) & 0xff000000) >> 24) | \
    (((x) & 0x00ff0000) >>  8) | \
    (((x) & 0x0000ff00) <<  8) | \
    (((x) & 0x000000ff) << 24))

Definition at line 220 of file chan_skinny.c.

#define ACTIVATE_CALL_PLANE_MESSAGE   0x0116

Definition at line 1021 of file chan_skinny.c.

Referenced by message2str(), and transmit_activatecallplane().

#define ALARM_MESSAGE   0x0020

Definition at line 348 of file chan_skinny.c.

Referenced by handle_message(), and message2str().

#define BT_AUTOANSWER   STIMULUS_AUTOANSWER

Definition at line 576 of file chan_skinny.c.

#define BT_CALLPARK   STIMULUS_CALLPARK

Definition at line 579 of file chan_skinny.c.

Referenced by get_button_template().

#define BT_CALLPICKUP   STIMULUS_CALLPICKUP

Definition at line 580 of file chan_skinny.c.

#define BT_CONFERENCE   STIMULUS_CONFERENCE

Definition at line 578 of file chan_skinny.c.

Referenced by get_button_template().

#define BT_CUST_LINE   0xB1

Definition at line 587 of file chan_skinny.c.

Referenced by get_button_template(), and handle_button_template_req_message().

#define BT_CUST_LINESPEEDDIAL   0xB0

Definition at line 586 of file chan_skinny.c.

Referenced by get_button_template(), and handle_button_template_req_message().

#define BT_DISPLAY   STIMULUS_DISPLAY

Definition at line 573 of file chan_skinny.c.

Referenced by get_button_template().

#define BT_DND   STIMULUS_DND

Definition at line 577 of file chan_skinny.c.

#define BT_FORWARDALL   STIMULUS_FORWARDALL

Definition at line 570 of file chan_skinny.c.

Referenced by get_button_template().

#define BT_FORWARDBUSY   STIMULUS_FORWARDBUSY

Definition at line 571 of file chan_skinny.c.

#define BT_FORWARDNOANSWER   STIMULUS_FORWARDNOANSWER

Definition at line 572 of file chan_skinny.c.

#define BT_HOLD   STIMULUS_HOLD

Definition at line 568 of file chan_skinny.c.

Referenced by get_button_template().

#define BT_LINE   STIMULUS_LINE

Definition at line 574 of file chan_skinny.c.

Referenced by get_button_template(), and handle_button_template_req_message().

#define BT_NONE   0x00

Definition at line 581 of file chan_skinny.c.

Referenced by get_button_template(), and handle_button_template_req_message().

#define BT_REDIAL   STIMULUS_REDIAL

Definition at line 566 of file chan_skinny.c.

Referenced by get_button_template().

#define BT_SPEEDDIAL   STIMULUS_SPEEDDIAL

Definition at line 567 of file chan_skinny.c.

Referenced by get_button_template(), and handle_button_template_req_message().

#define BT_TRANSFER   STIMULUS_TRANSFER

Definition at line 569 of file chan_skinny.c.

Referenced by get_button_template().

#define BT_VOICEMAIL   STIMULUS_VOICEMAIL

Definition at line 575 of file chan_skinny.c.

Referenced by get_button_template().

#define BUTTON_TEMPLATE_REQ_MESSAGE   0x000E

Definition at line 344 of file chan_skinny.c.

Referenced by handle_message(), and message2str().

#define BUTTON_TEMPLATE_RES_MESSAGE   0x0097

Definition at line 536 of file chan_skinny.c.

Referenced by handle_button_template_req_message(), and message2str().

#define CALL_INFO_MESSAGE   0x008F

Definition at line 474 of file chan_skinny.c.

Referenced by message2str(), and transmit_callinfo().

#define CALL_STATE_MESSAGE   0x0111

Definition at line 992 of file chan_skinny.c.

Referenced by message2str(), and transmit_callstate().

#define CALLSTATE2STR_BUFSIZE   15

Definition at line 259 of file chan_skinny.c.

Referenced by callstate2str().

#define CAPABILITIES_REQ_MESSAGE   0x009B

Definition at line 612 of file chan_skinny.c.

Referenced by message2str(), and transmit_capabilitiesreq().

#define CAPABILITIES_RES_MESSAGE   0x0010

Definition at line 316 of file chan_skinny.c.

Referenced by handle_message(), and message2str().

#define CDEV   ((struct skinny_device *)item)

Definition at line 7127 of file chan_skinny.c.

Referenced by config_parse_variables().

#define CDEV_OPTS   ((struct skinny_device_options *)item)

Definition at line 7126 of file chan_skinny.c.

Referenced by config_parse_variables().

#define CLEAR_DISPLAY_MESSAGE   0x009A

Definition at line 607 of file chan_skinny.c.

Referenced by message2str(), and transmit_clear_display_message().

#define CLEAR_NOTIFY_MESSAGE   0x0115

Definition at line 606 of file chan_skinny.c.

Referenced by message2str().

#define CLEAR_PROMPT_MESSAGE   0x0113

Definition at line 1009 of file chan_skinny.c.

Referenced by message2str(), and transmit_clearpromptmessage().

#define CLINE   ((struct skinny_line *)item)

Definition at line 7125 of file chan_skinny.c.

Referenced by config_parse_variables().

#define CLINE_OPTS   ((struct skinny_line_options *)item)

Definition at line 7124 of file chan_skinny.c.

Referenced by config_parse_variables().

#define CLOSE_RECEIVE_CHANNEL_MESSAGE   0x0106

Definition at line 648 of file chan_skinny.c.

Referenced by message2str(), and transmit_closereceivechannel().

#define CONTROL2STR_BUFSIZE   100

Definition at line 253 of file chan_skinny.c.

Referenced by control2str().

#define DEFAULT_AUTH_LIMIT   50

Definition at line 171 of file chan_skinny.c.

Referenced by config_parse_variables().

#define DEFAULT_AUTH_TIMEOUT   30

Definition at line 170 of file chan_skinny.c.

Referenced by config_parse_variables().

#define DEFAULT_SKINNY_BACKLOG   2

Definition at line 168 of file chan_skinny.c.

Referenced by config_load().

#define DEFAULT_SKINNY_PORT   2000

Definition at line 167 of file chan_skinny.c.

Referenced by config_device(), and config_load().

#define DEFINETIMEDATE_MESSAGE   0x0094

Definition at line 523 of file chan_skinny.c.

Referenced by message2str(), and transmit_definetimedate().

#define DEVICE2STR_BUFSIZE   15

Definition at line 250 of file chan_skinny.c.

Referenced by device2str().

#define DIALED_NUMBER_MESSAGE   0x011D

Definition at line 1026 of file chan_skinny.c.

Referenced by message2str(), and transmit_dialednumber().

#define DISPLAY_NOTIFY_MESSAGE   0x0114

Definition at line 1015 of file chan_skinny.c.

Referenced by message2str(), and transmit_displaynotify().

#define DISPLAY_PROMPT_STATUS_MESSAGE   0x0112

Definition at line 1000 of file chan_skinny.c.

Referenced by message2str(), and transmit_displaypromptstatus().

#define DISPLAYTEXT_MESSAGE   0x0099

Definition at line 601 of file chan_skinny.c.

Referenced by message2str().

#define ENBLOC_CALL_MESSAGE   0x0004

Definition at line 292 of file chan_skinny.c.

Referenced by handle_message(), and message2str().

#define FORWARD_STAT_MESSAGE   0x0090

Definition at line 496 of file chan_skinny.c.

Referenced by message2str(), and transmit_cfwdstate().

#define HEADSET_STATUS_MESSAGE   0x002B

Definition at line 382 of file chan_skinny.c.

Referenced by handle_message(), and message2str().

#define htolel (  )     __bswap_32(x)

#define htoles (  )     __bswap_16(x)

Definition at line 228 of file chan_skinny.c.

Referenced by transmit_softkeysetres().

#define IP_PORT_MESSAGE   0x0002

Definition at line 282 of file chan_skinny.c.

Referenced by handle_message(), and message2str().

#define KEEP_ALIVE_ACK_MESSAGE   0x0100

Definition at line 635 of file chan_skinny.c.

Referenced by message2str(), and transmit_keepaliveack().

#define KEEP_ALIVE_MESSAGE   0x0000

Definition at line 265 of file chan_skinny.c.

Referenced by handle_message(), and message2str().

#define KEYDEF_CONNECTED   1

Definition at line 663 of file chan_skinny.c.

Referenced by setsubstate(), and skinny_extensionstate_cb().

#define KEYDEF_CONNWITHCONF   7

Definition at line 669 of file chan_skinny.c.

#define KEYDEF_CONNWITHTRANS   5

Definition at line 667 of file chan_skinny.c.

#define KEYDEF_DADFD   6

Definition at line 668 of file chan_skinny.c.

#define KEYDEF_OFFHOOK   4

Definition at line 666 of file chan_skinny.c.

Referenced by setsubstate().

#define KEYDEF_OFFHOOKWITHFEAT   9

Definition at line 671 of file chan_skinny.c.

#define KEYDEF_ONHOLD   2

Definition at line 664 of file chan_skinny.c.

Referenced by setsubstate().

#define KEYDEF_ONHOOK   0

#define KEYDEF_RINGIN   3

Definition at line 665 of file chan_skinny.c.

Referenced by setsubstate().

#define KEYDEF_RINGOUT   8

Definition at line 670 of file chan_skinny.c.

Referenced by setsubstate().

#define KEYDEF_SLACONNECTEDNOTACTIVE   12

Definition at line 674 of file chan_skinny.c.

Referenced by setsubstate(), and skinny_extensionstate_cb().

#define KEYDEF_SLAHOLD   11

Definition at line 673 of file chan_skinny.c.

Referenced by skinny_extensionstate_cb().

#define KEYDEF_UNKNOWN   10

Definition at line 672 of file chan_skinny.c.

#define KEYPAD_BUTTON_MESSAGE   0x0003

Definition at line 284 of file chan_skinny.c.

Referenced by handle_message(), and message2str().

#define letohl (  )     __bswap_32(x)

#define letohs (  )     __bswap_16(x)

Definition at line 226 of file chan_skinny.c.

#define LINE_STAT_RES_MESSAGE   0x0092

Definition at line 515 of file chan_skinny.c.

Referenced by message2str(), and transmit_linestatres().

#define LINE_STATE_REQ_MESSAGE   0x000B

Definition at line 338 of file chan_skinny.c.

Referenced by handle_message(), and message2str().

#define MESSAGE2STR_BUFSIZE   35

Definition at line 246 of file chan_skinny.c.

Referenced by message2str().

#define OFFHOOK_MESSAGE   0x0006

Definition at line 304 of file chan_skinny.c.

Referenced by handle_message(), and message2str().

#define ONHOOK_MESSAGE   0x0007

Definition at line 310 of file chan_skinny.c.

Referenced by handle_message(), and message2str().

#define OPEN_RECEIVE_CHANNEL_ACK_MESSAGE   0x0022

Definition at line 356 of file chan_skinny.c.

Referenced by handle_message(), and message2str().

#define OPEN_RECEIVE_CHANNEL_MESSAGE   0x0105

Definition at line 637 of file chan_skinny.c.

Referenced by message2str(), and transmit_connect().

#define REGISTER_ACK_MESSAGE   0x0081

Definition at line 385 of file chan_skinny.c.

Referenced by message2str(), and transmit_registerack().

#define REGISTER_AVAILABLE_LINES_MESSAGE   0x002D

Definition at line 383 of file chan_skinny.c.

Referenced by handle_message(), and message2str().

#define REGISTER_MESSAGE   0x0001

Definition at line 268 of file chan_skinny.c.

Referenced by handle_message(), and message2str().

#define REGISTER_REJ_MESSAGE   0x009D

Definition at line 614 of file chan_skinny.c.

Referenced by message2str(), and transmit_registerrej().

#define RESET_MESSAGE   0x009F

Definition at line 630 of file chan_skinny.c.

Referenced by message2str(), skinny_reload(), and transmit_reset().

#define SELECT_SOFT_KEYS_MESSAGE   0x0110

Definition at line 984 of file chan_skinny.c.

Referenced by message2str(), and transmit_selectsoftkeys().

#define SERVER_REQUEST_MESSAGE   0x0012

Definition at line 346 of file chan_skinny.c.

Referenced by handle_message(), and message2str().

#define SERVER_RES_MESSAGE   0x009E

Definition at line 619 of file chan_skinny.c.

Referenced by message2str(), and transmit_serverres().

#define SET_LAMP_MESSAGE   0x0086

Definition at line 417 of file chan_skinny.c.

Referenced by message2str(), and transmit_lamp_indication().

#define SET_MICROPHONE_MESSAGE   0x0089

Definition at line 430 of file chan_skinny.c.

Referenced by message2str(), and transmit_microphone_mode().

#define SET_RINGER_MESSAGE   0x0085

Definition at line 409 of file chan_skinny.c.

Referenced by message2str(), and transmit_ringer_mode().

#define SET_SPEAKER_MESSAGE   0x0088

Definition at line 424 of file chan_skinny.c.

Referenced by message2str(), and transmit_speaker_mode().

#define SKINNY_ALERT   0x24

Definition at line 1179 of file chan_skinny.c.

Referenced by setsubstate().

#define SKINNY_BARGIN   0x43

Definition at line 1185 of file chan_skinny.c.

#define SKINNY_BEEPBONK   0x33

Definition at line 1184 of file chan_skinny.c.

#define SKINNY_BUSY   6

Definition at line 1163 of file chan_skinny.c.

Referenced by callstate2str(), and setsubstate().

#define SKINNY_BUSYTONE   0x23

Definition at line 1178 of file chan_skinny.c.

Referenced by setsubstate().

#define SKINNY_CALLREMOTEMULTILINE   13

Definition at line 1170 of file chan_skinny.c.

Referenced by setsubstate(), and skinny_extensionstate_cb().

#define SKINNY_CALLWAIT   9

Definition at line 1166 of file chan_skinny.c.

Referenced by callstate2str(), and setsubstate().

#define SKINNY_CALLWAITTONE   0x2D

Definition at line 1181 of file chan_skinny.c.

Referenced by setsubstate().

#define SKINNY_CFWD_ALL   (1 << 0)

#define SKINNY_CFWD_BUSY   (1 << 1)

#define SKINNY_CFWD_NOANSWER   (1 << 2)

#define SKINNY_CONGESTION   7

Definition at line 1164 of file chan_skinny.c.

Referenced by callstate2str(), and setsubstate().

#define SKINNY_CONNECTED   5

#define SKINNY_CX_CONF   3

Definition at line 1207 of file chan_skinny.c.

#define SKINNY_CX_CONFERENCE   3

Definition at line 1208 of file chan_skinny.c.

#define SKINNY_CX_INACTIVE   4

Definition at line 1210 of file chan_skinny.c.

Referenced by skinny_new().

#define SKINNY_CX_MUTE   4

Definition at line 1209 of file chan_skinny.c.

#define SKINNY_CX_RECVONLY   1

Definition at line 1205 of file chan_skinny.c.

Referenced by setsubstate().

#define SKINNY_CX_SENDONLY   0

Definition at line 1204 of file chan_skinny.c.

#define SKINNY_CX_SENDRECV   2

Definition at line 1206 of file chan_skinny.c.

Referenced by skinny_answer().

#define SKINNY_DEVICE_12   4

Definition at line 1118 of file chan_skinny.c.

Referenced by device2str(), and get_button_template().

#define SKINNY_DEVICE_12SP   3

Definition at line 1117 of file chan_skinny.c.

Referenced by device2str(), and get_button_template().

#define SKINNY_DEVICE_12SPPLUS   2

Definition at line 1116 of file chan_skinny.c.

Referenced by device2str(), and get_button_template().

#define SKINNY_DEVICE_30SPPLUS   1

Definition at line 1115 of file chan_skinny.c.

Referenced by device2str(), and get_button_template().

#define SKINNY_DEVICE_30VIP   5

Definition at line 1119 of file chan_skinny.c.

Referenced by device2str(), and get_button_template().

#define SKINNY_DEVICE_7902   30008

Definition at line 1145 of file chan_skinny.c.

Referenced by device2str(), and get_button_template().

#define SKINNY_DEVICE_7905   20000

Definition at line 1141 of file chan_skinny.c.

Referenced by device2str(), and get_button_template().

#define SKINNY_DEVICE_7906   369

Definition at line 1134 of file chan_skinny.c.

Referenced by device2str(), and get_button_template().

#define SKINNY_DEVICE_7910   6

Definition at line 1120 of file chan_skinny.c.

Referenced by device2str(), and get_button_template().

#define SKINNY_DEVICE_7911   307

Definition at line 1129 of file chan_skinny.c.

Referenced by device2str(), and get_button_template().

#define SKINNY_DEVICE_7912   30007

Definition at line 1144 of file chan_skinny.c.

Referenced by device2str(), and get_button_template().

#define SKINNY_DEVICE_7914   124

Definition at line 1127 of file chan_skinny.c.

Referenced by device2str(), and get_button_template().

#define SKINNY_DEVICE_7920   30002

Definition at line 1142 of file chan_skinny.c.

Referenced by device2str(), and get_button_template().

#define SKINNY_DEVICE_7921   365

Definition at line 1133 of file chan_skinny.c.

Referenced by device2str(), and get_button_template().

#define SKINNY_DEVICE_7931   348

Definition at line 1132 of file chan_skinny.c.

Referenced by device2str(), and get_button_template().

#define SKINNY_DEVICE_7935   9

Definition at line 1123 of file chan_skinny.c.

Referenced by device2str(), and get_button_template().

#define SKINNY_DEVICE_7936   30019

Definition at line 1148 of file chan_skinny.c.

Referenced by device2str(), and get_button_template().

#define SKINNY_DEVICE_7937   431

Definition at line 1136 of file chan_skinny.c.

Referenced by device2str(), and get_button_template().

#define SKINNY_DEVICE_7940   8

Definition at line 1122 of file chan_skinny.c.

Referenced by device2str(), and get_button_template().

#define SKINNY_DEVICE_7941   115

Definition at line 1125 of file chan_skinny.c.

Referenced by device2str(), and get_button_template().

#define SKINNY_DEVICE_7941GE   309

Definition at line 1131 of file chan_skinny.c.

Referenced by device2str(), and get_button_template().

#define SKINNY_DEVICE_7942   434

Definition at line 1137 of file chan_skinny.c.

Referenced by device2str(), and get_button_template().

#define SKINNY_DEVICE_7945   435

Definition at line 1138 of file chan_skinny.c.

Referenced by device2str(), and get_button_template().

#define SKINNY_DEVICE_7960   7

Definition at line 1121 of file chan_skinny.c.

Referenced by device2str(), and get_button_template().

#define SKINNY_DEVICE_7961   30018

Definition at line 1147 of file chan_skinny.c.

Referenced by device2str(), and get_button_template().

#define SKINNY_DEVICE_7961GE   308

Definition at line 1130 of file chan_skinny.c.

Referenced by device2str(), and get_button_template().

#define SKINNY_DEVICE_7962   404

Definition at line 1135 of file chan_skinny.c.

Referenced by device2str(), and get_button_template().

#define SKINNY_DEVICE_7965   436

Definition at line 1139 of file chan_skinny.c.

Referenced by device2str(), and get_button_template().

#define SKINNY_DEVICE_7970   30006

Definition at line 1143 of file chan_skinny.c.

Referenced by device2str(), and get_button_template().

#define SKINNY_DEVICE_7971   119

Definition at line 1126 of file chan_skinny.c.

Referenced by device2str(), and get_button_template().

#define SKINNY_DEVICE_7975   437

Definition at line 1140 of file chan_skinny.c.

Referenced by device2str(), and get_button_template().

#define SKINNY_DEVICE_7985   302

Definition at line 1128 of file chan_skinny.c.

Referenced by device2str(), and get_button_template().

#define SKINNY_DEVICE_ATA186   12

Definition at line 1124 of file chan_skinny.c.

Referenced by device2str(), and get_button_template().

#define SKINNY_DEVICE_CIPC   30016

Definition at line 1146 of file chan_skinny.c.

Referenced by device2str(), and get_button_template().

#define SKINNY_DEVICE_NONE   0

Definition at line 1114 of file chan_skinny.c.

Referenced by device2str().

#define SKINNY_DEVICE_OPTIONS

Definition at line 1410 of file chan_skinny.c.

#define SKINNY_DEVICE_SCCPGATEWAY_AN   30027

Definition at line 1149 of file chan_skinny.c.

Referenced by device2str(), and get_button_template().

#define SKINNY_DEVICE_SCCPGATEWAY_BRI   30028

Definition at line 1150 of file chan_skinny.c.

Referenced by device2str(), and get_button_template().

#define SKINNY_DEVICE_UNKNOWN   -1

Definition at line 1113 of file chan_skinny.c.

Referenced by device2str().

#define SKINNY_DEVICECONTAINER   1

Definition at line 1393 of file chan_skinny.c.

#define SKINNY_DEVONLY ( code   )     code

#define SKINNY_DIALTONE   0x21

Definition at line 1177 of file chan_skinny.c.

Referenced by setsubstate(), and skinny_ss().

#define SKINNY_HOLD   8

Definition at line 1165 of file chan_skinny.c.

Referenced by callstate2str(), setsubstate(), and skinny_extensionstate_cb().

#define SKINNY_INCOMING   1

#define SKINNY_INVALID   14

Definition at line 1171 of file chan_skinny.c.

#define SKINNY_LAMP_BLINK   5

Definition at line 1192 of file chan_skinny.c.

Referenced by mwi_event_cb(), setsubstate(), and skinny_extensionstate_cb().

#define SKINNY_LAMP_FLASH   4

Definition at line 1191 of file chan_skinny.c.

Referenced by skinny_extensionstate_cb().

#define SKINNY_LAMP_OFF   1

#define SKINNY_LAMP_ON   2

#define SKINNY_LAMP_WINK   3

Definition at line 1190 of file chan_skinny.c.

Referenced by setsubstate(), and skinny_extensionstate_cb().

#define SKINNY_LINE_OPTIONS

Definition at line 1277 of file chan_skinny.c.

#define SKINNY_LINECONTAINER   2

Definition at line 1394 of file chan_skinny.c.

Referenced by config_line().

#define SKINNY_MAX_CAPABILITIES   18

Definition at line 326 of file chan_skinny.c.

Referenced by handle_capabilities_res_message().

#define SKINNY_MAX_PACKET   2000

Definition at line 169 of file chan_skinny.c.

Referenced by get_input(), skinny_req_parse(), and transmit_response_bysession().

#define SKINNY_MICOFF   2

Definition at line 1156 of file chan_skinny.c.

Referenced by setsubstate().

#define SKINNY_MICON   1

Definition at line 1155 of file chan_skinny.c.

#define SKINNY_NOTONE   0x7F

Definition at line 1186 of file chan_skinny.c.

#define SKINNY_OFFHOOK   1

#define SKINNY_ONHOOK   2

#define SKINNY_OUTGOING   2

#define SKINNY_PARK   11

Definition at line 1168 of file chan_skinny.c.

#define SKINNY_PROGRESS   12

Definition at line 1169 of file chan_skinny.c.

Referenced by callstate2str(), setsubstate(), and update_connectedline().

#define SKINNY_REORDER   0x25

Definition at line 1180 of file chan_skinny.c.

Referenced by setsubstate(), skinny_newcall(), and skinny_ss().

#define SKINNY_RING_FEATURE   4

Definition at line 1197 of file chan_skinny.c.

#define SKINNY_RING_INSIDE   2

Definition at line 1195 of file chan_skinny.c.

Referenced by setsubstate().

#define SKINNY_RING_OFF   1

#define SKINNY_RING_OUTSIDE   3

Definition at line 1196 of file chan_skinny.c.

#define SKINNY_RINGIN   4

#define SKINNY_RINGOUT   3

Definition at line 1160 of file chan_skinny.c.

Referenced by callstate2str(), setsubstate(), and update_connectedline().

#define SKINNY_SDCONTAINER   4

Definition at line 1396 of file chan_skinny.c.

Referenced by config_parse_variables(), and skinny_extensionstate_cb().

#define SKINNY_SILENCE   0x00

Definition at line 1176 of file chan_skinny.c.

#define SKINNY_SPEAKEROFF   2

Definition at line 1153 of file chan_skinny.c.

Referenced by dumpsub(), and handle_callforward_button().

#define SKINNY_SPEAKERON   1

#define SKINNY_SUBLINECONTAINER   3

Definition at line 1395 of file chan_skinny.c.

Referenced by config_parse_variables(), and skinny_extensionstate_cb().

#define SKINNY_TRANSFER   10

Definition at line 1167 of file chan_skinny.c.

#define SKINNY_ZIP   0x32

Definition at line 1183 of file chan_skinny.c.

Referenced by setsubstate().

#define SKINNY_ZIPZIP   0x31

Definition at line 1182 of file chan_skinny.c.

#define SOFT_KEY_EVENT_MESSAGE   0x0026

Definition at line 373 of file chan_skinny.c.

Referenced by handle_message(), and message2str().

#define SOFT_KEY_SET_REQ_MESSAGE   0x0025

Definition at line 371 of file chan_skinny.c.

Referenced by handle_message(), and message2str().

#define SOFT_KEY_SET_RES_MESSAGE   0x0109

Definition at line 969 of file chan_skinny.c.

Referenced by message2str(), and transmit_softkeysetres().

#define SOFT_KEY_TEMPLATE_REQ_MESSAGE   0x0028

Definition at line 381 of file chan_skinny.c.

Referenced by handle_message(), and message2str().

#define SOFT_KEY_TEMPLATE_RES_MESSAGE   0x0108

Definition at line 655 of file chan_skinny.c.

Referenced by message2str(), and transmit_softkeytemplateres().

#define SOFTKEY_ANSWER   0x0B

Definition at line 687 of file chan_skinny.c.

Referenced by handle_soft_key_event_message().

#define SOFTKEY_BKSPC   0x08

Definition at line 684 of file chan_skinny.c.

Referenced by handle_soft_key_event_message().

#define SOFTKEY_CFWDALL   0x05

Definition at line 681 of file chan_skinny.c.

Referenced by handle_soft_key_event_message().

#define SOFTKEY_CFWDBUSY   0x06

Definition at line 682 of file chan_skinny.c.

Referenced by handle_soft_key_event_message().

#define SOFTKEY_CFWDNOANSWER   0x07

Definition at line 683 of file chan_skinny.c.

Referenced by handle_soft_key_event_message().

#define SOFTKEY_CONFRN   0x0D

Definition at line 689 of file chan_skinny.c.

Referenced by handle_soft_key_event_message().

#define SOFTKEY_DND   0x13

Definition at line 695 of file chan_skinny.c.

Referenced by handle_soft_key_event_message().

#define SOFTKEY_ENDCALL   0x09

Definition at line 685 of file chan_skinny.c.

Referenced by handle_soft_key_event_message().

#define SOFTKEY_GPICKUP   0x12

Definition at line 694 of file chan_skinny.c.

Referenced by handle_soft_key_event_message().

#define SOFTKEY_HOLD   0x03

Definition at line 679 of file chan_skinny.c.

Referenced by handle_soft_key_event_message().

#define SOFTKEY_IDIVERT   0x14

Definition at line 696 of file chan_skinny.c.

#define SOFTKEY_INFO   0x0C

Definition at line 688 of file chan_skinny.c.

Referenced by handle_soft_key_event_message().

#define SOFTKEY_JOIN   0x0F

Definition at line 691 of file chan_skinny.c.

Referenced by handle_soft_key_event_message().

#define SOFTKEY_MEETME   0x10

Definition at line 692 of file chan_skinny.c.

Referenced by handle_soft_key_event_message().

#define SOFTKEY_NEWCALL   0x02

Definition at line 678 of file chan_skinny.c.

Referenced by handle_soft_key_event_message().

#define SOFTKEY_NONE   0x00

Definition at line 676 of file chan_skinny.c.

Referenced by handle_soft_key_event_message().

#define SOFTKEY_PARK   0x0E

Definition at line 690 of file chan_skinny.c.

Referenced by handle_soft_key_event_message().

#define SOFTKEY_PICKUP   0x11

Definition at line 693 of file chan_skinny.c.

Referenced by handle_soft_key_event_message().

#define SOFTKEY_REDIAL   0x01

Definition at line 677 of file chan_skinny.c.

Referenced by handle_soft_key_event_message().

#define SOFTKEY_RESUME   0x0A

Definition at line 686 of file chan_skinny.c.

Referenced by handle_soft_key_event_message().

#define SOFTKEY_TRNSFER   0x04

Definition at line 680 of file chan_skinny.c.

Referenced by handle_soft_key_event_message().

#define SPEED_DIAL_STAT_REQ_MESSAGE   0x000A

Definition at line 333 of file chan_skinny.c.

Referenced by handle_message(), and message2str().

#define SPEED_DIAL_STAT_RES_MESSAGE   0x0091

Definition at line 508 of file chan_skinny.c.

Referenced by message2str(), and transmit_speeddialstatres().

#define START_MEDIA_TRANSMISSION_MESSAGE   0x008A

Definition at line 435 of file chan_skinny.c.

Referenced by message2str(), and transmit_startmediatransmission().

#define START_TONE_MESSAGE   0x0082

Definition at line 394 of file chan_skinny.c.

Referenced by message2str(), and transmit_start_tone().

#define STIMULUS_AUTOANSWER   0x11

Definition at line 558 of file chan_skinny.c.

#define STIMULUS_CALLPARK   0x7E

Definition at line 561 of file chan_skinny.c.

Referenced by handle_stimulus_message().

#define STIMULUS_CALLPICKUP   0x7F

Definition at line 562 of file chan_skinny.c.

#define STIMULUS_CONFERENCE   0x7D

Definition at line 560 of file chan_skinny.c.

Referenced by handle_stimulus_message().

#define STIMULUS_DISPLAY   0x08

Definition at line 555 of file chan_skinny.c.

Referenced by handle_stimulus_message().

#define STIMULUS_DND   0x3F

Definition at line 559 of file chan_skinny.c.

Referenced by handle_soft_key_event_message(), and handle_stimulus_message().

#define STIMULUS_FORWARDALL   0x05

Definition at line 552 of file chan_skinny.c.

Referenced by handle_stimulus_message(), and skinny_ss().

#define STIMULUS_FORWARDBUSY   0x06

Definition at line 553 of file chan_skinny.c.

Referenced by handle_stimulus_message().

#define STIMULUS_FORWARDNOANSWER   0x07

Definition at line 554 of file chan_skinny.c.

Referenced by handle_stimulus_message().

#define STIMULUS_HOLD   0x03

Definition at line 550 of file chan_skinny.c.

Referenced by handle_stimulus_message().

#define STIMULUS_LINE   0x09

#define STIMULUS_MESSAGE   0x0005

Definition at line 297 of file chan_skinny.c.

Referenced by handle_message(), and message2str().

#define STIMULUS_NONE   0xFF

Definition at line 563 of file chan_skinny.c.

#define STIMULUS_REDIAL   0x01

Definition at line 548 of file chan_skinny.c.

Referenced by handle_stimulus_message().

#define STIMULUS_SPEEDDIAL   0x02

Definition at line 549 of file chan_skinny.c.

Referenced by handle_stimulus_message().

#define STIMULUS_TRANSFER   0x04

Definition at line 551 of file chan_skinny.c.

Referenced by handle_stimulus_message().

#define STIMULUS_VOICEMAIL   0x0F

Definition at line 557 of file chan_skinny.c.

Referenced by handle_stimulus_message(), and mwi_event_cb().

#define STOP_MEDIA_TRANSMISSION_MESSAGE   0x008B

Definition at line 467 of file chan_skinny.c.

Referenced by message2str(), and transmit_stopmediatransmission().

#define STOP_TONE_MESSAGE   0x0083

Definition at line 402 of file chan_skinny.c.

Referenced by message2str(), and transmit_stop_tone().

#define SUBSTATE2STR_BUFSIZE   15

Definition at line 256 of file chan_skinny.c.

Referenced by substate2str().

#define SUBSTATE_BUSY   6

Definition at line 1243 of file chan_skinny.c.

Referenced by setsubstate(), skinny_indicate(), and substate2str().

#define SUBSTATE_CALLWAIT   9

Definition at line 1246 of file chan_skinny.c.

Referenced by activatesub(), dumpsub(), setsubstate(), and substate2str().

#define SUBSTATE_CONGESTION   7

Definition at line 1244 of file chan_skinny.c.

Referenced by setsubstate(), skinny_indicate(), and substate2str().

#define SUBSTATE_CONNECTED   5

#define SUBSTATE_DIALING   101

Definition at line 1248 of file chan_skinny.c.

Referenced by dialandactivatesub(), setsubstate(), and substate2str().

#define SUBSTATE_HOLD   8

#define SUBSTATE_OFFHOOK   1

#define SUBSTATE_ONHOOK   2

Definition at line 1239 of file chan_skinny.c.

Referenced by activatesub(), dumpsub(), setsubstate(), and substate2str().

#define SUBSTATE_PROGRESS   12

Definition at line 1247 of file chan_skinny.c.

Referenced by setsubstate(), skinny_indicate(), and substate2str().

#define SUBSTATE_RINGIN   4

Definition at line 1241 of file chan_skinny.c.

Referenced by activatesub(), dumpsub(), setsubstate(), skinny_call(), and substate2str().

#define SUBSTATE_RINGOUT   3

Definition at line 1240 of file chan_skinny.c.

Referenced by setsubstate(), skinny_indicate(), and substate2str().

#define SUBSTATE_UNSET   0

Definition at line 1237 of file chan_skinny.c.

Referenced by handle_stimulus_message(), skinny_request(), and substate2str().

#define TIME_DATE_REQ_MESSAGE   0x000D

Definition at line 343 of file chan_skinny.c.

Referenced by handle_message(), and message2str().

#define TYPE_DEF_DEVICE   2

Definition at line 7119 of file chan_skinny.c.

Referenced by config_load(), and config_parse_variables().

#define TYPE_DEF_LINE   4

Definition at line 7120 of file chan_skinny.c.

Referenced by config_load(), and config_parse_variables().

#define TYPE_DEVICE   8

Definition at line 7121 of file chan_skinny.c.

Referenced by config_device(), and config_parse_variables().

#define TYPE_GENERAL   1

Definition at line 7118 of file chan_skinny.c.

Referenced by config_load(), and config_parse_variables().

#define TYPE_LINE   16

Definition at line 7122 of file chan_skinny.c.

#define UNREGISTER_MESSAGE   0x0027

Definition at line 380 of file chan_skinny.c.

Referenced by handle_message(), and message2str().

#define VERSION_REQ_MESSAGE   0x000F

Definition at line 345 of file chan_skinny.c.

Referenced by handle_message(), and message2str().

#define VERSION_RES_MESSAGE   0x0098

Definition at line 596 of file chan_skinny.c.

Referenced by message2str(), and transmit_versionres().


Enumeration Type Documentation

Enumerator:
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 157 of file chan_skinny.c.

00157                    {
00158    SKINNY_CODEC_ALAW = 2,
00159    SKINNY_CODEC_ULAW = 4,
00160    SKINNY_CODEC_G723_1 = 9,
00161    SKINNY_CODEC_G729A = 12,
00162    SKINNY_CODEC_G726_32 = 82, /* XXX Which packing order does this translate to? */
00163    SKINNY_CODEC_H261 = 100,
00164    SKINNY_CODEC_H263 = 101
00165 };


Function Documentation

static void __init_callstate2str_threadbuf ( void   )  [static]

Definition at line 258 of file chan_skinny.c.

00269 {

static void __init_control2str_threadbuf ( void   )  [static]

Definition at line 252 of file chan_skinny.c.

00269 {

static void __init_device2str_threadbuf ( void   )  [static]

Definition at line 249 of file chan_skinny.c.

00269 {

static void __init_message2str_threadbuf ( void   )  [static]

Definition at line 245 of file chan_skinny.c.

00269 {

static void __init_substate2str_threadbuf ( void   )  [static]

Definition at line 255 of file chan_skinny.c.

00269 {

static void __reg_module ( void   )  [static]

Definition at line 8094 of file chan_skinny.c.

static void __unreg_module ( void   )  [static]

Definition at line 8094 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 3692 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(), skinny_device::cap, CLI_SHOWUSAGE, CLI_SUCCESS, skinny_device::confcap, device2str(), skinny_speeddial::exten, skinny_speeddial::isHint, skinny_speeddial::label, skinny_device::lines, S_OR, skinny_device::session, skinnysession::sin, skinny_device::speeddials, and skinny_addon::type.

Referenced by handle_skinny_show_device(), and manager_skinny_show_device().

03693 {
03694    struct skinny_device *d;
03695    struct skinny_line *l;
03696    struct skinny_speeddial *sd;
03697    struct skinny_addon *sa;
03698    char codec_buf[512];
03699 
03700    if (argc < 4) {
03701       return CLI_SHOWUSAGE;
03702    }
03703 
03704    AST_LIST_LOCK(&devices);
03705    AST_LIST_TRAVERSE(&devices, d, list) {
03706       if (!strcasecmp(argv[3], d->id) || !strcasecmp(argv[3], d->name)) {
03707          int numlines = 0, numaddons = 0, numspeeddials = 0;
03708 
03709          AST_LIST_TRAVERSE(&d->lines, l, list){
03710             numlines++;
03711          }
03712 
03713          AST_LIST_TRAVERSE(&d->addons, sa, list) {
03714             numaddons++;
03715          }
03716 
03717          AST_LIST_TRAVERSE(&d->speeddials, sd, list) {
03718             numspeeddials++;
03719          }
03720 
03721          if (type == 0) { /* CLI */
03722             ast_cli(fd, "Name:        %s\n", d->name);
03723             ast_cli(fd, "Id:          %s\n", d->id);
03724             ast_cli(fd, "version:     %s\n", S_OR(d->version_id, "Unknown"));
03725             ast_cli(fd, "Ip address:  %s\n", (d->session ? ast_inet_ntoa(d->session->sin.sin_addr) : "Unknown"));
03726             ast_cli(fd, "Port:        %d\n", (d->session ? ntohs(d->session->sin.sin_port) : 0));
03727             ast_cli(fd, "Device Type: %s\n", device2str(d->type));
03728             ast_cli(fd, "Conf Codecs:");
03729             ast_getformatname_multiple(codec_buf, sizeof(codec_buf) - 1, d->confcap);
03730             ast_cli(fd, "%s\n", codec_buf);
03731             ast_cli(fd, "Neg Codecs: ");
03732             ast_getformatname_multiple(codec_buf, sizeof(codec_buf) - 1, d->cap);
03733             ast_cli(fd, "%s\n", codec_buf);
03734             ast_cli(fd, "Registered:  %s\n", (d->registered ? "Yes" : "No"));
03735             ast_cli(fd, "Lines:       %d\n", numlines);
03736             AST_LIST_TRAVERSE(&d->lines, l, list) {
03737                ast_cli(fd, "  %s (%s)\n", l->name, l->label);
03738             }
03739             AST_LIST_TRAVERSE(&d->addons, sa, list) {
03740                numaddons++;
03741             }  
03742             ast_cli(fd, "Addons:      %d\n", numaddons);
03743             AST_LIST_TRAVERSE(&d->addons, sa, list) {
03744                ast_cli(fd, "  %s\n", sa->type);
03745             }
03746             AST_LIST_TRAVERSE(&d->speeddials, sd, list) {
03747                numspeeddials++;
03748             }
03749             ast_cli(fd, "Speeddials:  %d\n", numspeeddials);
03750             AST_LIST_TRAVERSE(&d->speeddials, sd, list) {
03751                ast_cli(fd, "  %s (%s) ishint: %d\n", sd->exten, sd->label, sd->isHint);
03752             }
03753          } else { /* manager */
03754             astman_append(s, "Channeltype: SKINNY\r\n");
03755             astman_append(s, "ObjectName: %s\r\n", d->name);
03756             astman_append(s, "ChannelObjectType: device\r\n");
03757             astman_append(s, "Id: %s\r\n", d->id);
03758             astman_append(s, "version: %s\r\n", S_OR(d->version_id, "Unknown"));
03759             astman_append(s, "Ipaddress: %s\r\n", (d->session ? ast_inet_ntoa(d->session->sin.sin_addr) : "Unknown"));
03760             astman_append(s, "Port: %d\r\n", (d->session ? ntohs(d->session->sin.sin_port) : 0));
03761             astman_append(s, "DeviceType: %s\r\n", device2str(d->type));
03762             astman_append(s, "Codecs: ");
03763             ast_getformatname_multiple(codec_buf, sizeof(codec_buf) -1, d->confcap);
03764             astman_append(s, "%s\r\n", codec_buf);
03765             astman_append(s, "CodecOrder: ");
03766             ast_getformatname_multiple(codec_buf, sizeof(codec_buf) -1, d->cap);
03767             astman_append(s, "%s\r\n", codec_buf);
03768             astman_append(s, "Devicestatus: %s\r\n", (d->registered?"registered":"unregistered"));
03769             astman_append(s, "NumberOfLines: %d\r\n", numlines);
03770             AST_LIST_TRAVERSE(&d->lines, l, list) {
03771                astman_append(s, "Line: %s (%s)\r\n", l->name, l->label);
03772             }
03773             astman_append(s, "NumberOfAddons: %d\r\n", numaddons);
03774             AST_LIST_TRAVERSE(&d->addons, sa, list) {
03775                astman_append(s, "Addon: %s\r\n", sa->type);
03776             }
03777             astman_append(s, "NumberOfSpeeddials: %d\r\n", numspeeddials);
03778             AST_LIST_TRAVERSE(&d->speeddials, sd, list) {
03779                astman_append(s, "Speeddial: %s (%s) ishint: %d\r\n", sd->exten, sd->label, sd->isHint);
03780             }
03781          }
03782       }
03783    }
03784    AST_LIST_UNLOCK(&devices);
03785    return CLI_SUCCESS;
03786 }

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 3581 of file chan_skinny.c.

References ast_cli(), ast_inet_ntoa(), AST_LIST_LOCK, AST_LIST_TRAVERSE, AST_LIST_UNLOCK, ast_strlen_zero(), astman_append(), astman_get_header(), CLI_SHOWUSAGE, CLI_SUCCESS, device2str(), id, skinny_device::lines, skinny_device::session, and skinnysession::sin.

Referenced by handle_skinny_show_devices(), and manager_skinny_show_devices().

03582 {
03583    struct skinny_device *d;
03584    struct skinny_line *l;
03585    const char *id;
03586    char idtext[256] = "";
03587    int total_devices = 0;
03588 
03589    if (s) { /* Manager - get ActionID */
03590       id = astman_get_header(m, "ActionID");
03591       if (!ast_strlen_zero(id))
03592          snprintf(idtext, sizeof(idtext), "ActionID: %s\r\n", id);
03593    }
03594 
03595    switch (argc) {
03596    case 3:
03597       break;
03598    default:
03599       return CLI_SHOWUSAGE;
03600    }
03601 
03602    if (!s) {
03603       ast_cli(fd, "Name                 DeviceId         IP              Type            R NL\n");
03604       ast_cli(fd, "-------------------- ---------------- --------------- --------------- - --\n");
03605    }
03606 
03607    AST_LIST_LOCK(&devices);
03608    AST_LIST_TRAVERSE(&devices, d, list) {
03609       int numlines = 0;
03610       total_devices++;
03611       AST_LIST_TRAVERSE(&d->lines, l, list) {
03612          numlines++;
03613       }
03614       if (!s) {
03615          ast_cli(fd, "%-20s %-16s %-15s %-15s %c %2d\n",
03616             d->name,
03617             d->id,
03618             d->session?ast_inet_ntoa(d->session->sin.sin_addr):"",
03619             device2str(d->type),
03620             d->registered?'Y':'N',
03621             numlines);
03622       } else {
03623          astman_append(s,
03624             "Event: DeviceEntry\r\n%s"
03625             "Channeltype: SKINNY\r\n"
03626             "ObjectName: %s\r\n"
03627             "ChannelObjectType: device\r\n"
03628             "DeviceId: %s\r\n"
03629             "IPaddress: %s\r\n"
03630             "Type: %s\r\n"
03631             "Devicestatus: %s\r\n"
03632             "NumberOfLines: %d\r\n",
03633             idtext,
03634             d->name,
03635             d->id,
03636             d->session?ast_inet_ntoa(d->session->sin.sin_addr):"-none-",
03637             device2str(d->type),
03638             d->registered?"registered":"unregistered",
03639             numlines);
03640       }
03641    }
03642    AST_LIST_UNLOCK(&devices);
03643 
03644    if (total)
03645       *total = total_devices;
03646    
03647    return CLI_SUCCESS;
03648 }

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 3949 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_FIRST, AST_LIST_LOCK, AST_LIST_TRAVERSE, AST_LIST_UNLOCK, ast_print_group(), astman_append(), skinny_line::cap, CLI_SHOWUSAGE, CLI_SUCCESS, skinny_line::confcap, skinny_subline::context, skinny_subline::exten, ast_format::id, skinny_device::lines, skinny_subline::name, print_codec_to_cli(), S_COR, S_OR, SKINNY_CFWD_ALL, SKINNY_CFWD_BUSY, SKINNY_CFWD_NOANSWER, and skinny_line::sublines.

Referenced by handle_skinny_show_line(), and manager_skinny_show_line().

03950 {
03951    struct skinny_device *d;
03952    struct skinny_line *l;
03953    struct skinny_subline *subline;
03954    struct ast_codec_pref *pref;
03955    int x = 0;
03956    char codec_buf[512];
03957    char group_buf[256];
03958    char cbuf[256];
03959 
03960    switch (argc) {
03961    case 4:
03962       break;
03963    case 6:
03964       break;
03965    default:
03966       return CLI_SHOWUSAGE;
03967    }
03968 
03969    AST_LIST_LOCK(&devices);
03970 
03971    /* Show all lines matching the one supplied */
03972    AST_LIST_TRAVERSE(&devices, d, list) {
03973       if (argc == 6 && (strcasecmp(argv[5], d->id) && strcasecmp(argv[5], d->name))) {
03974          continue;
03975       }
03976       AST_LIST_TRAVERSE(&d->lines, l, list) {
03977          if (strcasecmp(argv[3], l->name)) {
03978             continue;
03979          }
03980          if (type == 0) { /* CLI */
03981             ast_cli(fd, "Line:             %s\n", l->name);
03982             ast_cli(fd, "On Device:        %s\n", d->name);
03983             ast_cli(fd, "Line Label:       %s\n", l->label);
03984             ast_cli(fd, "Extension:        %s\n", S_OR(l->exten, "<not set>"));
03985             ast_cli(fd, "Context:          %s\n", l->context);
03986             ast_cli(fd, "CallGroup:        %s\n", ast_print_group(group_buf, sizeof(group_buf), l->callgroup));
03987             ast_cli(fd, "PickupGroup:      %s\n", ast_print_group(group_buf, sizeof(group_buf), l->pickupgroup));
03988             ast_cli(fd, "Language:         %s\n", S_OR(l->language, "<not set>"));
03989             ast_cli(fd, "Accountcode:      %s\n", S_OR(l->accountcode, "<not set>"));
03990             ast_cli(fd, "AmaFlag:          %s\n", ast_cdr_flags2str(l->amaflags));
03991             ast_cli(fd, "CallerId Number:  %s\n", S_OR(l->cid_num, "<not set>"));
03992             ast_cli(fd, "CallerId Name:    %s\n", S_OR(l->cid_name, "<not set>"));
03993             ast_cli(fd, "Hide CallerId:    %s\n", (l->hidecallerid ? "Yes" : "No"));
03994             ast_cli(fd, "CFwdAll:          %s\n", S_COR((l->cfwdtype & SKINNY_CFWD_ALL), l->call_forward_all, "<not set>"));
03995             ast_cli(fd, "CFwdBusy:         %s\n", S_COR((l->cfwdtype & SKINNY_CFWD_BUSY), l->call_forward_busy, "<not set>"));
03996             ast_cli(fd, "CFwdNoAnswer:     %s\n", S_COR((l->cfwdtype & SKINNY_CFWD_NOANSWER), l->call_forward_noanswer, "<not set>"));
03997             ast_cli(fd, "VoicemailBox:     %s\n", S_OR(l->mailbox, "<not set>"));
03998             ast_cli(fd, "VoicemailNumber:  %s\n", S_OR(l->vmexten, "<not set>"));
03999             ast_cli(fd, "MWIblink:         %d\n", l->mwiblink);
04000             ast_cli(fd, "Regextension:     %s\n", S_OR(l->regexten, "<not set>"));
04001             ast_cli(fd, "Regcontext:       %s\n", S_OR(l->regcontext, "<not set>"));
04002             ast_cli(fd, "MoHInterpret:     %s\n", S_OR(l->mohinterpret, "<not set>"));
04003             ast_cli(fd, "MoHSuggest:       %s\n", S_OR(l->mohsuggest, "<not set>"));
04004             ast_cli(fd, "Last dialed nr:   %s\n", S_OR(l->lastnumberdialed, "<no calls made yet>"));
04005             ast_cli(fd, "Last CallerID:    %s\n", S_OR(l->lastcallerid, "<not set>"));
04006             ast_cli(fd, "Transfer enabled: %s\n", (l->transfer ? "Yes" : "No"));
04007             ast_cli(fd, "Callwaiting:      %s\n", (l->callwaiting ? "Yes" : "No"));
04008             ast_cli(fd, "3Way Calling:     %s\n", (l->threewaycalling ? "Yes" : "No"));
04009             ast_cli(fd, "Can forward:      %s\n", (l->cancallforward ? "Yes" : "No"));
04010             ast_cli(fd, "Do Not Disturb:   %s\n", (l->dnd ? "Yes" : "No"));
04011             ast_cli(fd, "NAT:              %s\n", (l->nat ? "Yes" : "No"));
04012             ast_cli(fd, "immediate:        %s\n", (l->immediate ? "Yes" : "No"));
04013             ast_cli(fd, "Group:            %d\n", l->group);
04014             ast_cli(fd, "Parkinglot:       %s\n", S_OR(l->parkinglot, "<not set>"));
04015             ast_cli(fd, "Conf Codecs:      ");
04016             ast_getformatname_multiple(codec_buf, sizeof(codec_buf) - 1, l->confcap);
04017             ast_cli(fd, "%s\n", codec_buf);
04018             ast_cli(fd, "Neg Codecs:       ");
04019             ast_getformatname_multiple(codec_buf, sizeof(codec_buf) - 1, l->cap);
04020             ast_cli(fd, "%s\n", codec_buf);
04021             ast_cli(fd, "Codec Order:      (");
04022             print_codec_to_cli(fd, &l->prefs);
04023             ast_cli(fd, ")\n");
04024             if  (AST_LIST_FIRST(&l->sublines)) {
04025                ast_cli(fd, "Sublines:\n");
04026                AST_LIST_TRAVERSE(&l->sublines, subline, list) {
04027                   ast_cli(fd, "     %s, %s@%s\n", subline->name, subline->exten, subline->context);
04028                }
04029             }
04030             ast_cli(fd, "\n");
04031          } else { /* manager */
04032             astman_append(s, "Channeltype: SKINNY\r\n");
04033             astman_append(s, "ObjectName: %s\r\n", l->name);
04034             astman_append(s, "ChannelObjectType: line\r\n");
04035             astman_append(s, "Device: %s\r\n", d->name);
04036             astman_append(s, "LineLabel: %s\r\n", l->label);
04037             astman_append(s, "Extension: %s\r\n", S_OR(l->exten, "<not set>"));
04038             astman_append(s, "Context: %s\r\n", l->context);
04039             astman_append(s, "CallGroup: %s\r\n", ast_print_group(group_buf, sizeof(group_buf), l->callgroup));
04040             astman_append(s, "PickupGroup: %s\r\n", ast_print_group(group_buf, sizeof(group_buf), l->pickupgroup));
04041             astman_append(s, "Language: %s\r\n", S_OR(l->language, "<not set>"));
04042             astman_append(s, "Accountcode: %s\r\n", S_OR(l->accountcode, "<not set>"));
04043             astman_append(s, "AMAflags: %s\r\n", ast_cdr_flags2str(l->amaflags));
04044             astman_append(s, "Callerid: %s\r\n", ast_callerid_merge(cbuf, sizeof(cbuf), l->cid_name, l->cid_num, ""));
04045             astman_append(s, "HideCallerId: %s\r\n", (l->hidecallerid ? "Yes" : "No"));
04046             astman_append(s, "CFwdAll: %s\r\n", S_COR((l->cfwdtype & SKINNY_CFWD_ALL), l->call_forward_all, "<not set>"));
04047             astman_append(s, "CFwdBusy: %s\r\n", S_COR((l->cfwdtype & SKINNY_CFWD_BUSY), l->call_forward_busy, "<not set>"));
04048             astman_append(s, "CFwdNoAnswer: %s\r\n", S_COR((l->cfwdtype & SKINNY_CFWD_NOANSWER), l->call_forward_noanswer, "<not set>"));
04049             astman_append(s, "VoicemailBox: %s\r\n", S_OR(l->mailbox, "<not set>"));
04050             astman_append(s, "VoicemailNumber: %s\r\n", S_OR(l->vmexten, "<not set>"));
04051             astman_append(s, "MWIblink: %d\r\n", l->mwiblink);
04052             astman_append(s, "RegExtension: %s\r\n", S_OR(l->regexten, "<not set>"));
04053             astman_append(s, "Regcontext: %s\r\n", S_OR(l->regcontext, "<not set>"));
04054             astman_append(s, "MoHInterpret: %s\r\n", S_OR(l->mohinterpret, "<not set>"));
04055             astman_append(s, "MoHSuggest: %s\r\n", S_OR(l->mohsuggest, "<not set>"));
04056             astman_append(s, "LastDialedNr: %s\r\n", S_OR(l->lastnumberdialed, "<no calls made yet>"));
04057             astman_append(s, "LastCallerID: %s\r\n", S_OR(l->lastcallerid, "<not set>"));
04058             astman_append(s, "Transfer: %s\r\n", (l->transfer ? "Yes" : "No"));
04059             astman_append(s, "Callwaiting: %s\r\n", (l->callwaiting ? "Yes" : "No"));
04060             astman_append(s, "3WayCalling: %s\r\n", (l->threewaycalling ? "Yes" : "No"));
04061             astman_append(s, "CanForward: %s\r\n", (l->cancallforward ? "Yes" : "No"));
04062             astman_append(s, "DoNotDisturb: %s\r\n", (l->dnd ? "Yes" : "No"));
04063             astman_append(s, "NAT: %s\r\n", (l->nat ? "Yes" : "No"));
04064             astman_append(s, "immediate: %s\r\n", (l->immediate ? "Yes" : "No"));
04065             astman_append(s, "Group: %d\r\n", l->group);
04066             astman_append(s, "Parkinglot: %s\r\n", S_OR(l->parkinglot, "<not set>"));
04067             ast_getformatname_multiple(codec_buf, sizeof(codec_buf) - 1, l->confcap);
04068             astman_append(s, "Codecs: %s\r\n", codec_buf);
04069             astman_append(s, "CodecOrder: ");
04070             pref = &l->prefs;
04071             for(x = 0; x < 32 ; x++) {
04072                struct ast_format tmpfmt;
04073                ast_codec_pref_index(pref, x, &tmpfmt);
04074                if (!tmpfmt.id)
04075                   break;
04076                astman_append(s, "%s", ast_getformatname(&tmpfmt));
04077                if (x < 31 && ast_codec_pref_index(pref, x+1, &tmpfmt))
04078                   astman_append(s, ",");
04079             }
04080             astman_append(s, "\r\n");
04081          }
04082       }
04083    }
04084    
04085    AST_LIST_UNLOCK(&devices);
04086    return CLI_SUCCESS;
04087 }

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 3825 of file chan_skinny.c.

References skinny_line::activesub, ast_bridged_channel(), ast_channel_name(), 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::owner, skinny_line::sub, and sub.

Referenced by handle_skinny_show_lines(), and manager_skinny_show_lines().

03826 {
03827    struct skinny_line *l;
03828    struct skinny_subchannel *sub;
03829    int total_lines = 0;
03830    int verbose = 0;
03831    const char *id;
03832    char idtext[256] = "";
03833 
03834    if (s) { /* Manager - get ActionID */
03835       id = astman_get_header(m, "ActionID");
03836       if (!ast_strlen_zero(id))
03837          snprintf(idtext, sizeof(idtext), "ActionID: %s\r\n", id);
03838    }
03839 
03840    switch (argc) {
03841    case 4:
03842       verbose = 1;
03843       break;
03844    case 3:
03845       verbose = 0;
03846       break;
03847    default:
03848       return CLI_SHOWUSAGE;
03849    }
03850 
03851    if (!s) {
03852       ast_cli(fd, "Name                 Device Name          Instance Label               \n");
03853       ast_cli(fd, "-------------------- -------------------- -------- --------------------\n");
03854    }
03855    AST_LIST_LOCK(&lines);
03856    AST_LIST_TRAVERSE(&lines, l, all) {
03857       total_lines++;
03858       if (!s) {
03859          ast_cli(fd, "%-20s %-20s %8d %-20s\n",
03860             l->name,
03861             (l->device ? l->device->name : "Not connected"),
03862             l->instance,
03863             l->label);
03864          if (verbose) {
03865             AST_LIST_TRAVERSE(&l->sub, sub, list) {
03866                ast_cli(fd, "  %s> %s to %s\n",
03867                   (sub == l->activesub?"Active  ":"Inactive"),
03868                   ast_channel_name(sub->owner),
03869                   (ast_bridged_channel(sub->owner)?ast_channel_name(ast_bridged_channel(sub->owner)):"")
03870                );
03871             }
03872          }
03873       } else {
03874          astman_append(s,
03875             "Event: LineEntry\r\n%s"
03876             "Channeltype: SKINNY\r\n"
03877             "ObjectName: %s\r\n"
03878             "ChannelObjectType: line\r\n"
03879             "Device: %s\r\n"
03880             "Instance: %d\r\n"
03881             "Label: %s\r\n",
03882             idtext,
03883             l->name,
03884             (l->device?l->device->name:"None"),
03885             l->instance,
03886             l->label);
03887       }
03888    }
03889    AST_LIST_UNLOCK(&lines);
03890 
03891    if (total) {
03892       *total = total_lines;
03893    }
03894 
03895    return CLI_SUCCESS;
03896 }

static void* accept_thread ( void *  ignore  )  [static]

Definition at line 7006 of file chan_skinny.c.

References ast_atomic_fetchadd_int(), ast_calloc, AST_LIST_INSERT_HEAD, AST_LIST_LOCK, AST_LIST_UNLOCK, ast_log(), ast_mutex_init, ast_pthread_create, ast_verb, destroy_session(), errno, skinnysession::fd, skinnysession::lock, LOG_ERROR, LOG_NOTICE, LOG_WARNING, skinnysession::sin, skinny_session(), skinnysession::start, and skinnysession::t.

Referenced by config_load().

07007 {
07008    int as;
07009    struct sockaddr_in sin;
07010    socklen_t sinlen;
07011    struct skinnysession *s;
07012    struct protoent *p;
07013    int arg = 1;
07014 
07015    for (;;) {
07016       sinlen = sizeof(sin);
07017       as = accept(skinnysock, (struct sockaddr *)&sin, &sinlen);
07018       if (as < 0) {
07019          ast_log(LOG_NOTICE, "Accept returned -1: %s\n", strerror(errno));
07020          continue;
07021       }
07022 
07023       if (ast_atomic_fetchadd_int(&unauth_sessions, +1) >= auth_limit) {
07024          close(as);
07025          ast_atomic_fetchadd_int(&unauth_sessions, -1);
07026          continue;
07027       }
07028 
07029       p = getprotobyname("tcp");
07030       if(p) {
07031          if( setsockopt(as, p->p_proto, TCP_NODELAY, (char *)&arg, sizeof(arg) ) < 0 ) {
07032             ast_log(LOG_WARNING, "Failed to set Skinny tcp connection to TCP_NODELAY mode: %s\n", strerror(errno));
07033          }
07034       }
07035       if (!(s = ast_calloc(1, sizeof(struct skinnysession)))) {
07036          close(as);
07037          ast_atomic_fetchadd_int(&unauth_sessions, -1);
07038          continue;
07039       }
07040 
07041       memcpy(&s->sin, &sin, sizeof(sin));
07042       ast_mutex_init(&s->lock);
07043       s->fd = as;
07044 
07045       if(time(&s->start) == -1) {
07046          ast_log(LOG_ERROR, "error executing time(): %s; disconnecting client\n", strerror(errno));
07047          destroy_session(s);
07048          continue;
07049       }
07050 
07051       AST_LIST_LOCK(&sessions);
07052       AST_LIST_INSERT_HEAD(&sessions, s, list);
07053       AST_LIST_UNLOCK(&sessions);
07054 
07055       if (ast_pthread_create(&s->t, NULL, skinny_session, s)) {
07056          destroy_session(s);
07057       }
07058    }
07059    if (skinnydebug)
07060       ast_verb(1, "killing accept thread\n");
07061    close(as);
07062    return 0;
07063 }

static void activatesub ( struct skinny_subchannel sub,
int  state 
) [static]

Definition at line 5445 of file chan_skinny.c.

References skinny_line::activesub, ast_channel_lock, ast_channel_unlock, ast_verb, skinny_subchannel::callid, skinny_subchannel::line, skinny_subchannel::owner, setsubstate(), skinny_subchannel::substate, SUBSTATE_CALLWAIT, SUBSTATE_HOLD, SUBSTATE_ONHOOK, and SUBSTATE_RINGIN.

Referenced by dialandactivatesub(), dumpsub(), handle_hold_button(), and handle_soft_key_event_message().

05446 {
05447    struct skinny_line *l = sub->line;
05448 
05449    if (skinnydebug) {
05450       ast_verb(3, "Sub %d - Activating, and deactivating sub %d\n", sub->callid, l->activesub?l->activesub->callid:0);
05451    }
05452    
05453    ast_channel_lock(sub->owner);
05454 
05455    if (sub == l->activesub) {
05456       setsubstate(sub, state);
05457    } else {
05458       if (l->activesub) {
05459          if (l->activesub->substate == SUBSTATE_RINGIN) {
05460             setsubstate(l->activesub, SUBSTATE_CALLWAIT);
05461          } else if (l->activesub->substate != SUBSTATE_HOLD) {
05462             setsubstate(l->activesub, SUBSTATE_ONHOOK);
05463          }
05464       }
05465       l->activesub = sub;
05466       setsubstate(sub, state);
05467    }
05468 
05469    ast_channel_unlock(sub->owner);
05470 }

static struct ast_variable* add_var ( const char *  buf,
struct ast_variable list 
) [static, read]

implement the setvar config line

Definition at line 1830 of file chan_skinny.c.

References ast_strdupa, ast_variable_new(), and ast_variable::next.

01831 {
01832    struct ast_variable *tmpvar = NULL;
01833    char *varname = ast_strdupa(buf), *varval = NULL;
01834 
01835    if ((varval = strchr(varname,'='))) {
01836       *varval++ = '\0';
01837       if ((tmpvar = ast_variable_new(varname, varval, ""))) {
01838          tmpvar->next = list;
01839          list = tmpvar;
01840       }
01841    }
01842    return list;
01843 }

static char* callstate2str ( int  ind  )  [static]

Definition at line 2313 of file chan_skinny.c.

References ast_threadstorage_get(), CALLSTATE2STR_BUFSIZE, callstate2str_threadbuf, SKINNY_BUSY, SKINNY_CALLWAIT, SKINNY_CONGESTION, SKINNY_CONNECTED, SKINNY_HOLD, SKINNY_ONHOOK, SKINNY_PROGRESS, SKINNY_RINGIN, SKINNY_RINGOUT, and SUBSTATE_OFFHOOK.

Referenced by transmit_callstate().

02314 {
02315    char *tmp;
02316 
02317    switch (ind) {
02318    case SUBSTATE_OFFHOOK:
02319       return "SKINNY_OFFHOOK";
02320    case SKINNY_ONHOOK:
02321       return "SKINNY_ONHOOK";
02322    case SKINNY_RINGOUT:
02323       return "SKINNY_RINGOUT";
02324    case SKINNY_RINGIN:
02325       return "SKINNY_RINGIN";
02326    case SKINNY_CONNECTED:
02327       return "SKINNY_CONNECTED";
02328    case SKINNY_BUSY:
02329       return "SKINNY_BUSY";
02330    case SKINNY_CONGESTION:
02331       return "SKINNY_CONGESTION";
02332    case SKINNY_PROGRESS:
02333       return "SKINNY_PROGRESS";
02334    case SKINNY_HOLD:
02335       return "SKINNY_HOLD";
02336    case SKINNY_CALLWAIT:
02337       return "SKINNY_CALLWAIT";
02338    default:
02339       if (!(tmp = ast_threadstorage_get(&callstate2str_threadbuf, CALLSTATE2STR_BUFSIZE)))
02340                         return "Unknown";
02341       snprintf(tmp, CALLSTATE2STR_BUFSIZE, "UNKNOWN-%d", ind);
02342       return tmp;
02343    }
02344 }

static void cleanup_stale_contexts ( char *  new,
char *  old 
) [static]

Definition at line 2002 of file chan_skinny.c.

References ast_context_destroy(), ast_context_find(), ast_copy_string(), and strsep().

02003 {
02004    char *oldcontext, *newcontext, *stalecontext, *stringp, newlist[AST_MAX_CONTEXT];
02005 
02006    while ((oldcontext = strsep(&old, "&"))) {
02007       stalecontext = '\0';
02008       ast_copy_string(newlist, new, sizeof(newlist));
02009       stringp = newlist;
02010       while ((newcontext = strsep(&stringp, "&"))) {
02011          if (strcmp(newcontext, oldcontext) == 0) {
02012             /* This is not the context you're looking for */
02013             stalecontext = '\0';
02014             break;
02015          } else if (strcmp(newcontext, oldcontext)) {
02016             stalecontext = oldcontext;
02017          }
02018          
02019       }
02020       if (stalecontext)
02021          ast_context_destroy(ast_context_find(stalecontext), "Skinny");
02022    }
02023 }

static int codec_ast2skinny ( const struct ast_format astcodec  )  [static]

Definition at line 1945 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, ast_format::id, 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().

01946 {
01947    switch (astcodec->id) {
01948    case AST_FORMAT_ALAW:
01949       return SKINNY_CODEC_ALAW;
01950    case AST_FORMAT_ULAW:
01951       return SKINNY_CODEC_ULAW;
01952    case AST_FORMAT_G723_1:
01953       return SKINNY_CODEC_G723_1;
01954    case AST_FORMAT_G729A:
01955       return SKINNY_CODEC_G729A;
01956    case AST_FORMAT_G726_AAL2: /* XXX Is this right? */
01957       return SKINNY_CODEC_G726_32;
01958    case AST_FORMAT_H261:
01959       return SKINNY_CODEC_H261;
01960    case AST_FORMAT_H263:
01961       return SKINNY_CODEC_H263;
01962    default:
01963       return 0;
01964    }
01965 }

static struct ast_format* codec_skinny2ast ( enum skinny_codecs  skinnycodec,
struct ast_format result 
) [static, read]

Definition at line 1922 of file chan_skinny.c.

References AST_FORMAT_ALAW, ast_format_clear(), AST_FORMAT_G723_1, AST_FORMAT_G726_AAL2, AST_FORMAT_G729A, AST_FORMAT_H261, AST_FORMAT_H263, ast_format_set(), 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().

01923 {
01924    switch (skinnycodec) {
01925    case SKINNY_CODEC_ALAW:
01926       return ast_format_set(result, AST_FORMAT_ALAW, 0);
01927    case SKINNY_CODEC_ULAW:
01928       return ast_format_set(result, AST_FORMAT_ULAW, 0);
01929    case SKINNY_CODEC_G723_1:
01930       return ast_format_set(result, AST_FORMAT_G723_1, 0);
01931    case SKINNY_CODEC_G729A:
01932       return ast_format_set(result, AST_FORMAT_G729A, 0);
01933    case SKINNY_CODEC_G726_32:
01934       return ast_format_set(result, AST_FORMAT_G726_AAL2, 0); /* XXX Is this right? */
01935    case SKINNY_CODEC_H261:
01936       return ast_format_set(result, AST_FORMAT_H261, 0);
01937    case SKINNY_CODEC_H263:
01938       return ast_format_set(result, AST_FORMAT_H263 ,0);
01939    default:
01940       ast_format_clear(result);
01941       return result;
01942    }
01943 }

static char* complete_skinny_devices ( const char *  word,
int  state 
) [static]

Definition at line 3394 of file chan_skinny.c.

References AST_LIST_TRAVERSE, and ast_strdup.

Referenced by complete_skinny_reset(), and complete_skinny_show_device().

03395 {
03396    struct skinny_device *d;
03397    char *result = NULL;
03398    int wordlen = strlen(word), which = 0;
03399 
03400    AST_LIST_TRAVERSE(&devices, d, list) {
03401       if (!strncasecmp(word, d->id, wordlen) && ++which > state)
03402          result = ast_strdup(d->id);
03403    }
03404 
03405    return result;
03406 }

static char* complete_skinny_reset ( const char *  line,
const char *  word,
int  pos,
int  state 
) [static]

Definition at line 3413 of file chan_skinny.c.

References ast_strdup, and complete_skinny_devices().

Referenced by handle_skinny_reset().

03414 {
03415    return (pos == 2 ? ast_strdup(complete_skinny_devices(word, state)) : NULL);
03416 }

static char* complete_skinny_show_device ( const char *  line,
const char *  word,
int  pos,
int  state 
) [static]

Definition at line 3408 of file chan_skinny.c.

References ast_strdup, and complete_skinny_devices().

Referenced by handle_skinny_show_device().

03409 {
03410    return (pos == 3 ? ast_strdup(complete_skinny_devices(word, state)) : NULL);
03411 }

static char* complete_skinny_show_line ( const char *  line,
const char *  word,
int  pos,
int  state 
) [static]

Definition at line 3418 of file chan_skinny.c.

References AST_LIST_TRAVERSE, ast_strdup, and skinny_device::lines.

Referenced by handle_skinny_show_line().

03419 {
03420    struct skinny_device *d;
03421    struct skinny_line *l;
03422    char *result = NULL;
03423    int wordlen = strlen(word), which = 0;
03424 
03425    if (pos != 3)
03426       return NULL;
03427    
03428    AST_LIST_TRAVERSE(&devices, d, list) {
03429       AST_LIST_TRAVERSE(&d->lines, l, list) {
03430          if (!strncasecmp(word, l->name, wordlen) && ++which > state)
03431             result = ast_strdup(l->name);
03432       }
03433    }
03434 
03435    return result;
03436 }

static struct skinny_device* config_device ( const char *  dname,
struct ast_variable v 
) [static, read]

Definition at line 7644 of file chan_skinny.c.

References skinny_device::addr, ast_copy_string(), ast_format_cap_copy(), 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, skinny_device::confcap, config_parse_variables(), default_device, DEFAULT_SKINNY_PORT, skinny_line::device, skinnysession::device, skinny_subchannel::line, skinny_device::lines, skinny_line::lock, skinny_device::lock, LOG_ERROR, LOG_NOTICE, skinny_device::session, skinny_device_alloc(), skinny_line::sub, sub, TYPE_DEVICE, and update().

Referenced by config_load().

07645  {
07646    struct skinny_device *d, *temp;
07647    struct skinny_line *l, *ltemp;
07648    struct skinny_subchannel *sub;
07649    int update = 0;
07650  
07651    ast_log(LOG_NOTICE, "Configuring skinny device %s.\n", dname);
07652 
07653    AST_LIST_LOCK(&devices);
07654    AST_LIST_TRAVERSE(&devices, temp, list) {
07655       if (!strcasecmp(dname, temp->name) && temp->prune) {
07656          update = 1;
07657          break;
07658       }
07659    }
07660 
07661    if (!(d = skinny_device_alloc())) {
07662       ast_verb(1, "Unable to allocate memory for device %s.\n", dname);
07663       AST_LIST_UNLOCK(&devices);
07664       return NULL;
07665    }
07666    memcpy(d, default_device, sizeof(*default_device));
07667    ast_mutex_init(&d->lock);
07668    ast_copy_string(d->name, dname, sizeof(d->name));
07669    ast_format_cap_copy(d->confcap, default_cap);
07670    AST_LIST_INSERT_TAIL(&devices, d, list);
07671 
07672    ast_mutex_lock(&d->lock);
07673    AST_LIST_UNLOCK(&devices);
07674  
07675    config_parse_variables(TYPE_DEVICE, d, v);
07676  
07677    if (!AST_LIST_FIRST(&d->lines)) {
07678       ast_log(LOG_ERROR, "A Skinny device must have at least one line!\n");
07679       ast_mutex_unlock(&d->lock);
07680       return NULL;
07681    }
07682    if (/*d->addr.sin_addr.s_addr && */!ntohs(d->addr.sin_port)) {
07683       d->addr.sin_port = htons(DEFAULT_SKINNY_PORT);
07684    }
07685  
07686    if (skinnyreload){
07687       AST_LIST_LOCK(&devices);
07688       AST_LIST_TRAVERSE(&devices, temp, list) {
07689          if (strcasecmp(d->id, temp->id) || !temp->prune || !temp->session) {
07690             continue;
07691          }
07692          ast_mutex_lock(&d->lock);
07693          d->session = temp->session;
07694          d->session->device = d;
07695          d->hookstate = temp->hookstate;
07696 
07697          AST_LIST_LOCK(&d->lines);
07698          AST_LIST_TRAVERSE(&d->lines, l, list){
07699             l->device = d; 
07700 
07701             AST_LIST_LOCK(&temp->lines);
07702             AST_LIST_TRAVERSE(&temp->lines, ltemp, list) {
07703                if (strcasecmp(l->name, ltemp->name)) {
07704                   continue;
07705                }
07706                ast_mutex_lock(&ltemp->lock);
07707                l->instance = ltemp->instance;
07708                if (!AST_LIST_EMPTY(&ltemp->sub)) {
07709                   ast_mutex_lock(&l->lock);
07710                   l->sub = ltemp->sub;
07711                   AST_LIST_TRAVERSE(&l->sub, sub, list) {
07712                      sub->line = l;
07713                   }
07714                   ast_mutex_unlock(&l->lock);
07715                }
07716                ast_mutex_unlock(&ltemp->lock);
07717             }
07718             AST_LIST_UNLOCK(&temp->lines);
07719          }
07720          AST_LIST_UNLOCK(&d->lines);
07721          ast_mutex_unlock(&d->lock);
07722       }
07723       AST_LIST_UNLOCK(&devices);
07724    }
07725 
07726    ast_mutex_unlock(&d->lock);
07727 
07728    ast_verb(3, "%s config for device '%s'\n", update ? "Updated" : (skinnyreload ? "Reloaded" : "Created"), d->name);
07729    
07730    return d;
07731 
07732  }

static struct skinny_line* config_line ( const char *  lname,
struct ast_variable v 
) [static, read]

Definition at line 7574 of file chan_skinny.c.

References 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_format_cap_copy(), 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, skinny_line::confcap, config_parse_variables(), skinny_line::container, skinny_container::data, default_line, skinny_line::lock, LOG_NOTICE, LOG_WARNING, mwi_event_cb(), skinny_line::mwi_event_sub, skinny_line_alloc(), skinny_line_destroy(), SKINNY_LINECONTAINER, strsep(), skinny_container::type, TYPE_LINE, and update().

Referenced by config_load().

07575  {
07576    struct skinny_line *l, *temp;
07577    int update = 0;
07578    struct skinny_container *container;
07579  
07580    ast_log(LOG_NOTICE, "Configuring skinny line %s.\n", lname);
07581 
07582    /* We find the old line and remove it just before the new
07583       line is created */
07584    AST_LIST_LOCK(&lines);
07585    AST_LIST_TRAVERSE(&lines, temp, all) {
07586       if (!strcasecmp(lname, temp->name) && temp->prune) {
07587          update = 1;
07588          break;
07589       }
07590    }
07591 
07592    if (!(l = skinny_line_alloc())) {
07593       ast_verb(1, "Unable to allocate memory for line %s.\n", lname);
07594       AST_LIST_UNLOCK(&lines);
07595       return NULL;
07596    }
07597    if (!(container = ast_calloc(1, sizeof(*container)))) {
07598       ast_log(LOG_WARNING, "Unable to allocate memory for line %s container.\n", lname);
07599       skinny_line_destroy(l);
07600       AST_LIST_UNLOCK(&lines);
07601       return NULL;
07602    }
07603 
07604    container->type = SKINNY_LINECONTAINER;
07605    container->data = l;
07606    l->container = container;
07607    
07608    memcpy(l, default_line, sizeof(*default_line));
07609    ast_mutex_init(&l->lock);
07610    ast_copy_string(l->name, lname, sizeof(l->name));
07611    ast_format_cap_copy(l->confcap, default_cap);
07612    AST_LIST_INSERT_TAIL(&lines, l, all);
07613 
07614    ast_mutex_lock(&l->lock);
07615    AST_LIST_UNLOCK(&lines);
07616 
07617    config_parse_variables(TYPE_LINE, l, v);
07618          
07619    if (!ast_strlen_zero(l->mailbox)) {
07620       char *cfg_mailbox, *cfg_context;
07621       cfg_context = cfg_mailbox = ast_strdupa(l->mailbox);
07622       ast_verb(3, "Setting mailbox '%s' on line %s\n", cfg_mailbox, l->name);
07623       strsep(&cfg_context, "@");
07624       if (ast_strlen_zero(cfg_context))
07625           cfg_context = "default";
07626       l->mwi_event_sub = ast_event_subscribe(AST_EVENT_MWI, mwi_event_cb, "skinny MWI subsciption", l,
07627          AST_EVENT_IE_MAILBOX, AST_EVENT_IE_PLTYPE_STR, cfg_mailbox,
07628          AST_EVENT_IE_CONTEXT, AST_EVENT_IE_PLTYPE_STR, cfg_context,
07629          AST_EVENT_IE_NEWMSGS, AST_EVENT_IE_PLTYPE_EXISTS,
07630          AST_EVENT_IE_END);
07631    }
07632  
07633    ast_mutex_unlock(&l->lock);
07634    
07635    /* We do not want to unlink or free the line yet, it needs
07636       to be available to detect a device reconfig when we load the
07637       devices.  Old lines will be pruned after the reload completes */
07638 
07639    ast_verb(3, "%s config for line '%s'\n", update ? "Updated" : (skinnyreload ? "Reloaded" : "Created"), l->name);
07640 
07641    return l;
07642  }

static int config_load ( void   )  [static]

Definition at line 7734 of file chan_skinny.c.

References __ourip, accept_thread(), ahp, ast_category_browse(), ast_config_destroy(), ast_config_load, ast_gethostbyname(), ast_inet_ntoa(), ast_log(), ast_mutex_lock, ast_mutex_unlock, ast_netsock_set_qos(), ast_pthread_create_background, ast_variable_browse(), ast_verb, bindaddr, config_device(), config_line(), config_parse_variables(), CONFIG_STATUS_FILEINVALID, default_device, default_line, default_prefs, DEFAULT_SKINNY_BACKLOG, DEFAULT_SKINNY_PORT, errno, global_jbconf, LOG_ERROR, LOG_NOTICE, LOG_WARNING, netlock, qos, TYPE_DEF_DEVICE, TYPE_DEF_LINE, and TYPE_GENERAL.

Referenced by load_module(), and skinny_reload().

07735  {
07736    int on = 1;
07737    struct ast_config *cfg;
07738    char *cat;
07739    int oldport = ntohs(bindaddr.sin_port);
07740    struct ast_flags config_flags = { 0 };
07741    
07742    ast_log(LOG_NOTICE, "Configuring skinny from %s\n", config);
07743   
07744    if (gethostname(ourhost, sizeof(ourhost))) {
07745       ast_log(LOG_WARNING, "Unable to get hostname, Skinny disabled.\n");
07746       return 0;
07747    }
07748    cfg = ast_config_load(config, config_flags);
07749   
07750    /* We *must* have a config file otherwise stop immediately */
07751    if (!cfg || cfg == CONFIG_STATUS_FILEINVALID) {
07752       ast_log(LOG_NOTICE, "Unable to load config %s, Skinny disabled.\n", config);
07753       return -1;
07754    }
07755    memset(&bindaddr, 0, sizeof(bindaddr));
07756    memset(&default_prefs, 0, sizeof(default_prefs));
07757 
07758    /* Copy the default jb config over global_jbconf */
07759    memcpy(&global_jbconf, &default_jbconf, sizeof(struct ast_jb_conf));
07760 
07761    /* load the general section */
07762    cat = ast_category_browse(cfg, "general");
07763    config_parse_variables(TYPE_GENERAL, NULL, ast_variable_browse(cfg, "general"));
07764 
07765    if (ntohl(bindaddr.sin_addr.s_addr)) {
07766       __ourip = bindaddr.sin_addr;
07767    } else {
07768       hp = ast_gethostbyname(ourhost, &ahp);
07769       if (!hp) {
07770          ast_log(LOG_WARNING, "Unable to get our IP address, Skinny disabled\n");
07771          ast_config_destroy(cfg);
07772          return 0;
07773       }
07774       memcpy(&__ourip, hp->h_addr, sizeof(__ourip));
07775    }
07776    if (!ntohs(bindaddr.sin_port)) {
07777       bindaddr.sin_port = htons(DEFAULT_SKINNY_PORT);
07778    }
07779    bindaddr.sin_family = AF_INET;
07780 
07781    /* load the lines sections */
07782    default_line->confprefs = default_prefs;
07783    config_parse_variables(TYPE_DEF_LINE, default_line, ast_variable_browse(cfg, "lines"));
07784    cat = ast_category_browse(cfg, "lines");
07785    while (cat && strcasecmp(cat, "general") && strcasecmp(cat, "devices")) {
07786       config_line(cat, ast_variable_browse(cfg, cat));
07787       cat = ast_category_browse(cfg, cat);
07788    }
07789       
07790    /* load the devices sections */
07791    default_device->confprefs = default_prefs;
07792    config_parse_variables(TYPE_DEF_DEVICE, default_device, ast_variable_browse(cfg, "devices"));
07793    cat = ast_category_browse(cfg, "devices");
07794    while (cat && strcasecmp(cat, "general") && strcasecmp(cat, "lines")) {
07795       config_device(cat, ast_variable_browse(cfg, cat));
07796       cat = ast_category_browse(cfg, cat);
07797    }
07798 
07799    ast_mutex_lock(&netlock);
07800    if ((skinnysock > -1) && (ntohs(bindaddr.sin_port) != oldport)) {
07801       close(skinnysock);
07802       skinnysock = -1;
07803    }
07804    if (skinnysock < 0) {
07805       skinnysock = socket(AF_INET, SOCK_STREAM, 0);
07806       if(setsockopt(skinnysock, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on)) == -1) {
07807          ast_log(LOG_ERROR, "Set Socket Options failed: errno %d, %s\n", errno, strerror(errno));
07808          ast_config_destroy(cfg);
07809          ast_mutex_unlock(&netlock);
07810          return 0;
07811       }
07812       if (skinnysock < 0) {
07813          ast_log(LOG_WARNING, "Unable to create Skinny socket: %s\n", strerror(errno));
07814       } else {
07815          if (bind(skinnysock, (struct sockaddr *)&bindaddr, sizeof(bindaddr)) < 0) {
07816             ast_log(LOG_WARNING, "Failed to bind to %s:%d: %s\n",
07817                   ast_inet_ntoa(bindaddr.sin_addr), ntohs(bindaddr.sin_port),
07818                      strerror(errno));
07819             close(skinnysock);
07820             skinnysock = -1;
07821             ast_config_destroy(cfg);
07822             ast_mutex_unlock(&netlock);
07823             return 0;
07824          }
07825          if (listen(skinnysock, DEFAULT_SKINNY_BACKLOG)) {
07826                ast_log(LOG_WARNING, "Failed to start listening to %s:%d: %s\n",
07827                   ast_inet_ntoa(bindaddr.sin_addr), ntohs(bindaddr.sin_port),
07828                      strerror(errno));
07829                close(skinnysock);
07830                skinnysock = -1;
07831                ast_config_destroy(cfg);
07832                ast_mutex_unlock(&netlock);
07833                return 0;
07834          }
07835          ast_verb(2, "Skinny listening on %s:%d\n",
07836                ast_inet_ntoa(bindaddr.sin_addr), ntohs(bindaddr.sin_port));
07837          ast_netsock_set_qos(skinnysock, qos.tos, qos.cos, "Skinny");
07838          ast_pthread_create_background(&accept_t, NULL, accept_thread, NULL);
07839       }
07840    }
07841    ast_mutex_unlock(&netlock);
07842    ast_config_destroy(cfg);
07843    return 1;
07844 }

static void config_parse_variables ( int  type,
void *  item,
struct ast_variable vptr 
) [static]

Definition at line 7129 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_free, 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_mutex_init, ast_parse_allow_disallow(), ast_sockaddr_to_sin, ast_str2cos(), ast_str2tos(), ast_strip(), ast_strlen_zero(), ast_true(), bindaddr, CDEV, CDEV_OPTS, cleanup_stale_contexts(), CLINE, CLINE_OPTS, skinny_speeddial::container, skinny_subline::container, skinny_speeddial::context, skinny_subline::context, skinny_container::data, DEFAULT_AUTH_LIMIT, DEFAULT_AUTH_TIMEOUT, default_prefs, skinny_speeddial::exten, skinny_subline::exten, global_jbconf, skinny_speeddial::instance, skinny_speeddial::isHint, skinny_speeddial::label, skinny_subline::line, ast_variable::lineno, skinny_device::lines, skinny_subline::lnname, skinny_addon::lock, skinny_speeddial::lock, LOG_WARNING, skinny_subline::name, ast_variable::name, ast_variable::next, skinny_speeddial::parent, qos, S_OR, SKINNY_SDCONTAINER, SKINNY_SUBLINECONTAINER, ast_sockaddr::ss, skinny_subline::stname, strsep(), skinny_subline::sub, skinny_addon::type, skinny_container::type, TYPE_DEF_DEVICE, TYPE_DEF_LINE, TYPE_DEVICE, TYPE_GENERAL, TYPE_LINE, and ast_variable::value.

Referenced by config_device(), config_line(), and config_load().

07130  {
07131    struct ast_variable *v;
07132    int lineInstance = 1;
07133    int speeddialInstance = 1;
07134    
07135    while(vptr) {
07136       v = vptr;
07137       vptr = vptr->next;
07138  
07139       if (type & (TYPE_GENERAL)) {
07140          char newcontexts[AST_MAX_CONTEXT];
07141          char oldcontexts[AST_MAX_CONTEXT];
07142          char *stringp, *context, *oldregcontext;
07143          if (!ast_jb_read_conf(&global_jbconf, v->name, v->value)) {
07144             v = v->next;
07145             continue;
07146          }
07147          if (!strcasecmp(v->name, "bindaddr")) {
07148             if (!(hp = ast_gethostbyname(v->value, &ahp))) {
07149                ast_log(LOG_WARNING, "Invalid address: %s\n", v->value);
07150             } else {
07151                memcpy(&bindaddr.sin_addr, hp->h_addr, sizeof(bindaddr.sin_addr));
07152             }
07153             continue;
07154          } else if (!strcasecmp(v->name, "keepalive")) {
07155             keep_alive = atoi(v->value);
07156             continue;
07157          } else if (!strcasecmp(v->name, "authtimeout")) {
07158             int timeout = atoi(v->value);
07159 
07160             if (timeout < 1) {
07161                ast_log(LOG_WARNING, "Invalid authtimeout value '%s', using default value\n", v->value);
07162                auth_timeout = DEFAULT_AUTH_TIMEOUT;
07163             } else {
07164                auth_timeout = timeout;
07165             }
07166             continue;
07167          } else if (!strcasecmp(v->name, "authlimit")) {
07168             int limit = atoi(v->value);
07169 
07170             if (limit < 1) {
07171                ast_log(LOG_WARNING, "Invalid authlimit value '%s', using default value\n", v->value);
07172                auth_limit = DEFAULT_AUTH_LIMIT;
07173             } else {
07174                auth_limit = limit;
07175             }
07176             continue;
07177          } else if (!strcasecmp(v->name, "regcontext")) {
07178             ast_copy_string(newcontexts, v->value, sizeof(newcontexts));
07179             stringp = newcontexts;
07180             /* Initialize copy of current global_regcontext for later use in removing stale contexts */
07181             ast_copy_string(oldcontexts, regcontext, sizeof(oldcontexts));
07182             oldregcontext = oldcontexts;
07183             /* Let's remove any contexts that are no longer defined in regcontext */
07184             cleanup_stale_contexts(stringp, oldregcontext);
07185             /* Create contexts if they don't exist already */
07186             while ((context = strsep(&stringp, "&"))) {
07187                ast_copy_string(used_context, context, sizeof(used_context));
07188                ast_context_find_or_create(NULL, NULL, context, "Skinny");
07189             }
07190             ast_copy_string(regcontext, v->value, sizeof(regcontext));
07191             continue;
07192          } else if (!strcasecmp(v->name, "dateformat")) {
07193             memcpy(date_format, v->value, sizeof(date_format));
07194             continue;
07195          } else if (!strcasecmp(v->name, "tos")) {
07196             if (ast_str2tos(v->value, &qos.tos))
07197                ast_log(LOG_WARNING, "Invalid tos value at line %d, refer to QoS documentation\n", v->lineno);
07198             continue;
07199          } else if (!strcasecmp(v->name, "tos_audio")) {
07200             if (ast_str2tos(v->value, &qos.tos_audio))
07201                ast_log(LOG_WARNING, "Invalid tos_audio value at line %d, refer to QoS documentation\n", v->lineno);
07202             continue;
07203          } else if (!strcasecmp(v->name, "tos_video")) {
07204             if (ast_str2tos(v->value, &qos.tos_video))
07205                ast_log(LOG_WARNING, "Invalid tos_video value at line %d, refer to QoS documentation\n", v->lineno);
07206             continue;
07207          } else if (!strcasecmp(v->name, "cos")) {
07208             if (ast_str2cos(v->value, &qos.cos))
07209                ast_log(LOG_WARNING, "Invalid cos value at line %d, refer to QoS documentation\n", v->lineno);
07210             continue;
07211          } else if (!strcasecmp(v->name, "cos_audio")) {
07212             if (ast_str2cos(v->value, &qos.cos_audio))
07213                ast_log(LOG_WARNING, "Invalid cos_audio value at line %d, refer to QoS documentation\n", v->lineno);
07214             continue;
07215          } else if (!strcasecmp(v->name, "cos_video")) {
07216             if (ast_str2cos(v->value, &qos.cos_video))
07217                ast_log(LOG_WARNING, "Invalid cos_video value at line %d, refer to QoS documentation\n", v->lineno);
07218             continue;
07219          } else if (!strcasecmp(v->name, "bindport")) {
07220             if (sscanf(v->value, "%5d", &ourport) == 1) {
07221                bindaddr.sin_port = htons(ourport);
07222             } else {
07223                ast_log(LOG_WARNING, "Invalid bindport '%s' at line %d of %s\n", v->value, v->lineno, config);
07224             }
07225             continue;
07226          } else if (!strcasecmp(v->name, "allow")) {
07227             ast_parse_allow_disallow(&default_prefs, default_cap, v->value, 1);
07228             continue;
07229          } else if (!strcasecmp(v->name, "disallow")) {
07230             ast_parse_allow_disallow(&default_prefs, default_cap, v->value, 0);
07231             continue;
07232          } 
07233       }
07234  
07235       if (!strcasecmp(v->name, "transfer")) {
07236          if (type & (TYPE_DEF_DEVICE | TYPE_DEVICE)) {
07237             CDEV_OPTS->transfer = ast_true(v->value);
07238             continue;
07239          } else if (type & (TYPE_DEF_LINE | TYPE_LINE)) {
07240             CLINE_OPTS->transfer = ast_true(v->value);
07241             continue;
07242          }
07243       } else if (!strcasecmp(v->name, "callwaiting")) {
07244          if (type & (TYPE_DEF_DEVICE | TYPE_DEVICE)) {
07245             CDEV_OPTS->callwaiting = ast_true(v->value);
07246             continue;
07247          } else if (type & (TYPE_DEF_LINE | TYPE_LINE)) {
07248             CLINE_OPTS->callwaiting = ast_true(v->value);
07249             continue;
07250          }
07251       } else if (!strcasecmp(v->name, "directmedia") || !strcasecmp(v->name, "canreinvite")) {
07252          if (type & (TYPE_DEF_LINE | TYPE_LINE)) {
07253             CLINE_OPTS->directmedia = ast_true(v->value);
07254             continue;
07255          }
07256       } else if (!strcasecmp(v->name, "nat")) {
07257          if (type & (TYPE_DEF_LINE | TYPE_LINE)) {
07258             CLINE_OPTS->nat = ast_true(v->value);
07259             continue;
07260          }
07261       } else if (!strcasecmp(v->name, "context")) {
07262          if (type & (TYPE_DEF_LINE | TYPE_LINE)) {
07263             ast_copy_string(CLINE_OPTS->context, v->value, sizeof(CLINE_OPTS->context));
07264             continue;
07265          }
07266       }else if (!strcasecmp(v->name, "vmexten")) {
07267          if (type & (TYPE_DEF_DEVICE | TYPE_DEVICE)) {
07268             ast_copy_string(CDEV_OPTS->vmexten, v->value, sizeof(CDEV_OPTS->vmexten));
07269             continue;
07270          } else if (type & (TYPE_DEF_LINE | TYPE_LINE)) {
07271             ast_copy_string(CLINE_OPTS->vmexten, v->value, sizeof(CLINE_OPTS->vmexten));
07272             continue;
07273          }
07274       } else if (!strcasecmp(v->name, "mwiblink")) {
07275          if (type & (TYPE_DEF_DEVICE | TYPE_DEVICE)) {
07276             CDEV_OPTS->mwiblink = ast_true(v->value);
07277             continue;
07278          } else if (type & (TYPE_DEF_LINE | TYPE_LINE)) {
07279             CLINE_OPTS->mwiblink = ast_true(v->value);
07280             continue;
07281          }
07282       } else if (!strcasecmp(v->name, "linelabel")) {
07283          if (type & (TYPE_DEF_LINE | TYPE_LINE)) {
07284             ast_copy_string(CLINE_OPTS->label, v->value, sizeof(CLINE_OPTS->label));
07285             continue;
07286          }
07287       } else if (!strcasecmp(v->name, "callerid")) {
07288          if (type & (TYPE_DEF_LINE | TYPE_LINE)) {
07289             if (!strcasecmp(v->value, "asreceived")) {
07290                CLINE_OPTS->cid_num[0] = '\0';
07291                CLINE_OPTS->cid_name[0] = '\0';
07292             } else {
07293                ast_callerid_split(v->value, CLINE_OPTS->cid_name, sizeof(CLINE_OPTS->cid_name), CLINE_OPTS->cid_num, sizeof(CLINE_OPTS->cid_num));
07294             }
07295             continue;
07296          }
07297       } else if (!strcasecmp(v->name, "amaflags")) {
07298          if (type & (TYPE_DEF_LINE | TYPE_LINE)) {
07299             int tempamaflags = ast_cdr_amaflags2int(v->value);
07300             if (tempamaflags < 0) {
07301                ast_log(LOG_WARNING, "Invalid AMA flags: %s at line %d\n", v->value, v->lineno);
07302             } else {
07303                CLINE_OPTS->amaflags = tempamaflags;
07304             }
07305             continue;
07306          }
07307       } else if (!strcasecmp(v->name, "regexten")) {
07308          if (type & (TYPE_DEF_LINE | TYPE_LINE)) {
07309             ast_copy_string(CLINE_OPTS->regexten, v->value, sizeof(CLINE_OPTS->regexten));
07310             continue;
07311          }
07312       } else if (!strcasecmp(v->name, "language")) {
07313          if (type & (TYPE_DEF_LINE | TYPE_LINE)) {
07314             ast_copy_string(CLINE_OPTS->language, v->value, sizeof(CLINE_OPTS->language));
07315             continue;
07316          }
07317       } else if (!strcasecmp(v->name, "accountcode")) {
07318          if (type & (TYPE_DEF_LINE | TYPE_LINE)) {
07319             ast_copy_string(CLINE_OPTS->accountcode, v->value, sizeof(CLINE_OPTS->accountcode));
07320             continue;
07321          }
07322       } else if (!strcasecmp(v->name, "mohinterpret") || !strcasecmp(v->name, "musiconhold")) {
07323          if (type & (TYPE_DEF_LINE | TYPE_LINE)) {
07324             ast_copy_string(CLINE_OPTS->mohinterpret, v->value, sizeof(CLINE_OPTS->mohinterpret));
07325             continue;
07326          }
07327       } else if (!strcasecmp(v->name, "mohsuggest")) {
07328          if (type & (TYPE_DEF_LINE | TYPE_LINE)) {
07329             ast_copy_string(CLINE_OPTS->mohsuggest, v->value, sizeof(CLINE_OPTS->mohsuggest));
07330             continue;
07331          }
07332       } else if (!strcasecmp(v->name, "callgroup")) {
07333          if (type & (TYPE_DEF_LINE | TYPE_LINE)) {
07334             CLINE_OPTS->callgroup = ast_get_group(v->value);
07335             continue;
07336          }
07337       } else if (!strcasecmp(v->name, "pickupgroup")) {
07338          if (type & (TYPE_DEF_LINE | TYPE_LINE)) {
07339             CLINE_OPTS->pickupgroup = ast_get_group(v->value);
07340             continue;
07341          }
07342       } else if (!strcasecmp(v->name, "immediate")) {
07343          if (type & (TYPE_DEF_DEVICE | TYPE_DEVICE | TYPE_DEF_LINE | TYPE_LINE)) {
07344             CLINE_OPTS->immediate = ast_true(v->value);
07345             continue;
07346          }
07347       } else if (!strcasecmp(v->name, "cancallforward")) {
07348          if (type & (TYPE_DEF_LINE | TYPE_LINE)) {
07349             CLINE_OPTS->cancallforward = ast_true(v->value);
07350             continue;
07351          }
07352       } else if (!strcasecmp(v->name, "mailbox")) {
07353          if (type & (TYPE_DEF_LINE | TYPE_LINE)) {
07354             ast_copy_string(CLINE_OPTS->mailbox, v->value, sizeof(CLINE_OPTS->mailbox));
07355             continue;
07356          }
07357       } else if ( !strcasecmp(v->name, "parkinglot")) {
07358          if (type & (TYPE_DEF_LINE | TYPE_LINE)) {
07359             ast_copy_string(CLINE_OPTS->parkinglot, v->value, sizeof(CLINE_OPTS->parkinglot));
07360             continue;
07361          }
07362       } else if (!strcasecmp(v->name, "hasvoicemail")) {
07363          if (type & (TYPE_LINE)) {
07364             if (ast_true(v->value) && ast_strlen_zero(CLINE->mailbox)) {
07365                ast_copy_string(CLINE->mailbox, CLINE->name, sizeof(CLINE->mailbox));
07366             }
07367             continue;
07368          }
07369       } else if (!strcasecmp(v->name, "threewaycalling")) {
07370          if (type & (TYPE_DEF_LINE | TYPE_LINE)) {
07371             CLINE_OPTS->threewaycalling = ast_true(v->value);
07372             continue;
07373          }
07374       } else if (!strcasecmp(v->name, "setvar")) {
07375          if (type & (TYPE_LINE)) {
07376             CLINE->chanvars = add_var(v->value, CLINE->chanvars);
07377             continue;
07378          }
07379       } else if (!strcasecmp(v->name, "earlyrtp")) {
07380          if (type & (TYPE_DEF_DEVICE | TYPE_DEVICE)) {
07381             CDEV_OPTS->earlyrtp = ast_true(v->value);
07382             continue;
07383          }
07384       } else if (!strcasecmp(v->name, "host")) {
07385          if (type & (TYPE_DEVICE)) {
07386             struct ast_sockaddr CDEV_addr_tmp;
07387 
07388             CDEV_addr_tmp.ss.ss_family = AF_INET;
07389             if (ast_get_ip(&CDEV_addr_tmp, v->value)) {
07390                ast_log(LOG_WARNING, "Bad IP '%s' at line %d.\n", v->value, v->lineno);
07391             }
07392             ast_sockaddr_to_sin(&CDEV_addr_tmp,
07393                       &CDEV->addr);
07394             continue;
07395          }
07396       } else if (!strcasecmp(v->name, "port")) {
07397          if (type & (TYPE_DEF_DEVICE)) {
07398             CDEV->addr.sin_port = htons(atoi(v->value));
07399             continue;
07400          }
07401       } else if (!strcasecmp(v->name, "device")) {
07402          if (type & (TYPE_DEVICE)) {
07403             ast_copy_string(CDEV_OPTS->id, v->value, sizeof(CDEV_OPTS->id));
07404             continue;
07405          }
07406       } else if (!strcasecmp(v->name, "permit") || !strcasecmp(v->name, "deny")) {
07407          if (type & (TYPE_DEVICE)) {
07408             CDEV->ha = ast_append_ha(v->name, v->value, CDEV->ha, NULL);
07409             continue;
07410          }
07411       } else if (!strcasecmp(v->name, "allow")) {
07412          if (type & (TYPE_DEF_DEVICE | TYPE_DEVICE)) {
07413             ast_parse_allow_disallow(&CDEV->confprefs, CDEV->confcap, v->value, 1);
07414             continue;
07415          }
07416          if (type & (TYPE_DEF_LINE | TYPE_LINE)) {
07417             ast_parse_allow_disallow(&CLINE->confprefs, CLINE->confcap, v->value, 1);
07418             continue;
07419          }
07420       } else if (!strcasecmp(v->name, "disallow")) {
07421          if (type & (TYPE_DEF_DEVICE | TYPE_DEVICE)) {
07422             ast_parse_allow_disallow(&CDEV->confprefs, CDEV->confcap, v->value, 0);
07423             continue;
07424          }
07425          if (type & (TYPE_DEF_LINE | TYPE_LINE)) {
07426             ast_parse_allow_disallow(&CLINE->confprefs, CLINE->confcap, v->value, 0);
07427             continue;
07428          }
07429       } else if (!strcasecmp(v->name, "version")) {
07430          if (type & (TYPE_DEF_DEVICE | TYPE_DEVICE)) {
07431             ast_copy_string(CDEV_OPTS->version_id, v->value, sizeof(CDEV_OPTS->version_id));
07432             continue;
07433          }
07434       } else if (!strcasecmp(v->name, "line")) {
07435          if (type & (TYPE_DEVICE)) {
07436             struct skinny_line *l;
07437             AST_LIST_TRAVERSE(&lines, l, all) {
07438                if (!strcasecmp(v->value, l->name) && !l->prune) {
07439 
07440                   /* FIXME: temp solution about line conflicts */
07441                   struct skinny_device *d;
07442                   struct skinny_line *l2;
07443                   int lineinuse = 0;
07444                   AST_LIST_TRAVERSE(&devices, d, list) {
07445                      AST_LIST_TRAVERSE(&d->lines, l2, list) {
07446                         if (l2 == l && strcasecmp(d->id, CDEV->id)) {
07447                            ast_log(LOG_WARNING, "Line %s already used by %s. Not connecting to %s.\n", l->name, d->name, CDEV->name);
07448                            lineinuse++;
07449                         }
07450                      }
07451                   }
07452                   if (!lineinuse) {
07453                      if (!AST_LIST_FIRST(&CDEV->lines)) {
07454                         CDEV->activeline = l;
07455                      }
07456                      lineInstance++;
07457                      AST_LIST_INSERT_HEAD(&CDEV->lines, l, list);
07458                   }
07459                   break;
07460                }
07461             }
07462             continue;
07463          }
07464       } else if (!strcasecmp(v->name, "subline")) {
07465          if (type & (TYPE_LINE)) {
07466             struct skinny_subline *subline;
07467             struct skinny_container *container;
07468             char buf[256];
07469             char *stringp = buf, *exten, *stname, *context;
07470 
07471             if (!(subline = ast_calloc(1, sizeof(*subline)))) {
07472                ast_log(LOG_WARNING, "Unable to allocate memory for subline %s. Ignoring subline.\n", v->value);
07473                continue;
07474             }
07475             if (!(container = ast_calloc(1, sizeof(*container)))) {
07476                ast_log(LOG_WARNING, "Unable to allocate memory for subline %s container. Ignoring subline.\n", v->value);
07477                ast_free(subline);
07478                continue;
07479             }
07480             
07481             ast_copy_string(buf, v->value, sizeof(buf));
07482             exten = strsep(&stringp, "@");
07483             ast_copy_string(subline->exten, ast_strip(exten), sizeof(subline->exten));
07484             stname = strsep(&exten, "_");
07485             ast_copy_string(subline->stname, ast_strip(stname), sizeof(subline->stname));
07486             ast_copy_string(subline->lnname, ast_strip(exten), sizeof(subline->lnname));
07487             context = strsep(&stringp, ",");
07488             ast_copy_string(subline->name, ast_strip(stringp), sizeof(subline->name));
07489             ast_copy_string(subline->context, ast_strip(context), sizeof(subline->context));
07490 
07491             subline->line = CLINE;
07492             subline->sub = NULL;
07493 
07494             container->type = SKINNY_SUBLINECONTAINER;
07495             container->data = subline;
07496             subline->container = container;
07497             AST_LIST_INSERT_HEAD(&CLINE->sublines, subline, list);
07498             continue;
07499          }
07500       } else if (!strcasecmp(v->name, "dialoutcontext")) {
07501          if (type & (TYPE_LINE)) {
07502             ast_copy_string(CLINE_OPTS->dialoutcontext, v->value, sizeof(CLINE_OPTS->dialoutcontext));
07503             continue;
07504          }
07505       } else if (!strcasecmp(v->name, "dialoutexten")) {
07506          if (type & (TYPE_LINE)) {
07507             ast_copy_string(CLINE_OPTS->dialoutexten, v->value, sizeof(CLINE_OPTS->dialoutexten));
07508             continue;
07509          }
07510       } else if (!strcasecmp(v->name, "speeddial")) {
07511          if (type & (TYPE_DEVICE)) {
07512             struct skinny_speeddial *sd;
07513             struct skinny_container *container;
07514             char buf[256];
07515             char *stringp = buf, *exten, *context, *label;
07516 
07517             if (!(sd = ast_calloc(1, sizeof(*sd)))) {
07518                ast_log(LOG_WARNING, "Unable to allocate memory for speeddial %s. Ignoring speeddial.\n", v->name);
07519                continue;
07520             }
07521             if (!(container = ast_calloc(1, sizeof(*container)))) {
07522                ast_log(LOG_WARNING, "Unable to allocate memory for speeddial %s container. Ignoring speeddial.\n", v->name);
07523                ast_free(sd);
07524                continue;
07525             }
07526 
07527             ast_copy_string(buf, v->value, sizeof(buf));
07528             exten = strsep(&stringp, ",");
07529             if ((context = strchr(exten, '@'))) {
07530                *context++ = '\0';
07531             }
07532             label = stringp;
07533             ast_mutex_init(&sd->lock);
07534             ast_copy_string(sd->exten, exten, sizeof(sd->exten));
07535             if (!ast_strlen_zero(context)) {
07536                sd->isHint = 1;
07537                sd->instance = lineInstance++;
07538                ast_copy_string(sd->context, context, sizeof(sd->context));
07539             } else {
07540                sd->isHint = 0;
07541                sd->instance = speeddialInstance++;
07542                sd->context[0] = '\0';
07543             }
07544             ast_copy_string(sd->label, S_OR(label, exten), sizeof(sd->label));
07545             sd->parent = CDEV;
07546             container->type = SKINNY_SDCONTAINER;
07547             container->data = sd;
07548             sd->container = container;
07549             AST_LIST_INSERT_HEAD(&CDEV->speeddials, sd, list);
07550             continue;
07551          }
07552       } else if (!strcasecmp(v->name, "addon")) {
07553          if (type & (TYPE_DEVICE)) {
07554             struct skinny_addon *a;
07555             if (!(a = ast_calloc(1, sizeof(*a)))) {
07556                ast_log(LOG_WARNING, "Unable to allocate memory for addon %s. Ignoring addon.\n", v->name);
07557                continue;
07558             } else {
07559                ast_mutex_init(&a->lock);
07560                ast_copy_string(a->type, v->value, sizeof(a->type));
07561                AST_LIST_INSERT_HEAD(&CDEV->addons, a, list);
07562             }
07563             continue;
07564          }
07565 
07566       } else {
07567          ast_log(LOG_WARNING, "Don't know keyword '%s' at line %d\n", v->name, v->lineno);
07568          continue;
07569       }
07570       ast_log(LOG_WARNING, "Invalid category used: %s at line %d\n", v->name, v->lineno);
07571    }
07572  }

static char* control2str ( int  ind  )  [static]

Definition at line 4638 of file chan_skinny.c.

References AST_CONTROL_ANSWER, AST_CONTROL_BUSY, AST_CONTROL_CC, AST_CONTROL_CONGESTION, AST_CONTROL_CONNECTED_LINE, AST_CONTROL_FLASH, AST_CONTROL_HANGUP, AST_CONTROL_HOLD, AST_CONTROL_INCOMPLETE, AST_CONTROL_OFFHOOK, AST_CONTROL_OPTION, AST_CONTROL_PROCEEDING, AST_CONTROL_PROGRESS, AST_CONTROL_RADIO_KEY, AST_CONTROL_RADIO_UNKEY, AST_CONTROL_REDIRECTING, AST_CONTROL_RING, AST_CONTROL_RINGING, AST_CONTROL_SRCCHANGE, AST_CONTROL_SRCUPDATE, AST_CONTROL_T38_PARAMETERS, AST_CONTROL_TAKEOFFHOOK, AST_CONTROL_TRANSFER, AST_CONTROL_UNHOLD, AST_CONTROL_VIDUPDATE, AST_CONTROL_WINK, ast_threadstorage_get(), CONTROL2STR_BUFSIZE, and control2str_threadbuf.

04638                                   {
04639    char *tmp;
04640 
04641    switch (ind) {
04642    case AST_CONTROL_HANGUP:
04643       return "Other end has hungup";
04644    case AST_CONTROL_RING:
04645       return "Local ring";
04646    case AST_CONTROL_RINGING:
04647       return "Remote end is ringing";
04648    case AST_CONTROL_ANSWER:
04649       return "Remote end has answered";
04650    case AST_CONTROL_BUSY:
04651       return "Remote end is busy";
04652    case AST_CONTROL_TAKEOFFHOOK:
04653       return "Make it go off hook";
04654    case AST_CONTROL_OFFHOOK:
04655       return "Line is off hook";
04656    case AST_CONTROL_CONGESTION:
04657       return "Congestion (circuits busy)";
04658    case AST_CONTROL_FLASH:
04659       return "Flash hook";
04660    case AST_CONTROL_WINK:
04661       return "Wink";
04662    case AST_CONTROL_OPTION:
04663       return "Set a low-level option";
04664    case AST_CONTROL_RADIO_KEY:
04665       return "Key Radio";
04666    case AST_CONTROL_RADIO_UNKEY:
04667       return "Un-Key Radio";
04668    case AST_CONTROL_PROGRESS:
04669       return "Remote end is making Progress";
04670    case AST_CONTROL_PROCEEDING:
04671       return "Remote end is proceeding";
04672    case AST_CONTROL_HOLD:
04673       return "Hold";
04674    case AST_CONTROL_UNHOLD:
04675       return "Unhold";
04676    case AST_CONTROL_VIDUPDATE:
04677       return "VidUpdate";
04678    case AST_CONTROL_SRCUPDATE:
04679       return "Media Source Update";
04680    case AST_CONTROL_TRANSFER:
04681       return "Transfer";
04682    case AST_CONTROL_CONNECTED_LINE:
04683       return "Connected Line";
04684    case AST_CONTROL_REDIRECTING:
04685       return "Redirecting";
04686    case AST_CONTROL_T38_PARAMETERS:
04687       return "T38_Parameters";
04688    case AST_CONTROL_CC:
04689       return "CC Not Possible";
04690    case AST_CONTROL_SRCCHANGE:
04691       return "Media Source Change";
04692    case AST_CONTROL_INCOMPLETE:
04693       return "Incomplete";
04694    case -1:
04695       return "Stop tone";
04696    default:
04697       if (!(tmp = ast_threadstorage_get(&control2str_threadbuf, CONTROL2STR_BUFSIZE)))
04698                         return "Unknown";
04699       snprintf(tmp, CONTROL2STR_BUFSIZE, "UNKNOWN-%d", ind);
04700       return tmp;
04701    }
04702 }

static void delete_devices ( void   )  [static]

Definition at line 7846 of file chan_skinny.c.

References skinny_device::addons, AST_LIST_LOCK, AST_LIST_REMOVE, AST_LIST_REMOVE_HEAD, AST_LIST_UNLOCK, skinny_speeddial::container, free, skinny_device::lines, skinny_device_destroy(), skinny_line_destroy(), and skinny_device::speeddials.

Referenced by unload_module().

07847 {
07848    struct skinny_device *d;
07849    struct skinny_line *l;
07850    struct skinny_speeddial *sd;
07851    struct skinny_addon *a;
07852 
07853    AST_LIST_LOCK(&devices);
07854    AST_LIST_LOCK(&lines);
07855 
07856    /* Delete all devices */
07857    while ((d = AST_LIST_REMOVE_HEAD(&devices, list))) {
07858       /* Delete all lines for this device */
07859       while ((l = AST_LIST_REMOVE_HEAD(&d->lines, list))) {
07860          AST_LIST_REMOVE(&lines, l, all);
07861          AST_LIST_REMOVE(&d->lines, l, list);
07862          l = skinny_line_destroy(l);
07863       }
07864       /* Delete all speeddials for this device */
07865       while ((sd = AST_LIST_REMOVE_HEAD(&d->speeddials, list))) {
07866          free(sd->container);
07867          free(sd);
07868       }
07869       /* Delete all addons for this device */
07870       while ((a = AST_LIST_REMOVE_HEAD(&d->addons, list))) {
07871          free(a);
07872       }
07873       d = skinny_device_destroy(d);
07874    }
07875    AST_LIST_UNLOCK(&lines);
07876    AST_LIST_UNLOCK(&devices);
07877 }

static void destroy_session ( struct skinnysession s  )  [static]

static char* device2str ( int  type  )  [static]

Definition at line 3473 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().

03474 {
03475    char *tmp;
03476 
03477    switch (type) {
03478    case SKINNY_DEVICE_NONE:
03479       return "No Device";
03480    case SKINNY_DEVICE_30SPPLUS:
03481       return "30SP Plus";
03482    case SKINNY_DEVICE_12SPPLUS:
03483       return "12SP Plus";
03484    case SKINNY_DEVICE_12SP:
03485       return "12SP";
03486    case SKINNY_DEVICE_12:
03487       return "12";
03488    case SKINNY_DEVICE_30VIP:
03489       return "30VIP";
03490    case SKINNY_DEVICE_7910:
03491       return "7910";
03492    case SKINNY_DEVICE_7960:
03493       return "7960";
03494    case SKINNY_DEVICE_7940:
03495       return "7940";
03496    case SKINNY_DEVICE_7935:
03497       return "7935";
03498    case SKINNY_DEVICE_ATA186:
03499       return "ATA186";
03500    case SKINNY_DEVICE_7941:
03501       return "7941";
03502    case SKINNY_DEVICE_7971:
03503       return "7971";
03504    case SKINNY_DEVICE_7914:
03505       return "7914";
03506    case SKINNY_DEVICE_7985:
03507       return "7985";
03508    case SKINNY_DEVICE_7911:
03509       return "7911";
03510    case SKINNY_DEVICE_7961GE:
03511       return "7961GE";
03512    case SKINNY_DEVICE_7941GE:
03513       return "7941GE";
03514    case SKINNY_DEVICE_7931:
03515       return "7931";
03516    case SKINNY_DEVICE_7921:
03517       return "7921";
03518    case SKINNY_DEVICE_7906:
03519       return "7906";
03520    case SKINNY_DEVICE_7962:
03521       return "7962";
03522    case SKINNY_DEVICE_7937:
03523       return "7937";
03524    case SKINNY_DEVICE_7942:
03525       return "7942";
03526    case SKINNY_DEVICE_7945:
03527       return "7945";
03528    case SKINNY_DEVICE_7965:
03529       return "7965";
03530    case SKINNY_DEVICE_7975:
03531       return "7975";
03532    case SKINNY_DEVICE_7905:
03533       return "7905";
03534    case SKINNY_DEVICE_7920:
03535       return "7920";
03536    case SKINNY_DEVICE_7970:
03537       return "7970";
03538    case SKINNY_DEVICE_7912:
03539       return "7912";
03540    case SKINNY_DEVICE_7902:
03541       return "7902";
03542    case SKINNY_DEVICE_CIPC:
03543       return "IP Communicator";
03544    case SKINNY_DEVICE_7961:
03545       return "7961";
03546    case SKINNY_DEVICE_7936:
03547       return "7936";
03548    case SKINNY_DEVICE_SCCPGATEWAY_AN:
03549       return "SCCPGATEWAY_AN";
03550    case SKINNY_DEVICE_SCCPGATEWAY_BRI:
03551       return "SCCPGATEWAY_BRI";
03552    case SKINNY_DEVICE_UNKNOWN:
03553       return "Unknown";
03554    default:
03555       if (!(tmp = ast_threadstorage_get(&device2str_threadbuf, DEVICE2STR_BUFSIZE)))
03556          return "Unknown";
03557       snprintf(tmp, DEVICE2STR_BUFSIZE, "UNKNOWN-%d", type);
03558       return tmp;
03559    }
03560 }

static void dialandactivatesub ( struct skinny_subchannel sub,
char  exten[AST_MAX_EXTENSION] 
) [static]

Definition at line 5472 of file chan_skinny.c.

References activatesub(), ast_copy_string(), ast_verb, skinny_subchannel::callid, skinny_subchannel::exten, and SUBSTATE_DIALING.

Referenced by handle_enbloc_call_message(), handle_soft_key_event_message(), handle_stimulus_message(), and skinny_ss().

05473 {
05474    if (skinnydebug) {
05475       ast_verb(3, "Sub %d - Dial %s and Activate\n", sub->callid, exten);
05476    }
05477    ast_copy_string(sub->exten, exten, sizeof(sub->exten));
05478    activatesub(sub, SUBSTATE_DIALING);
05479 }

static void dumpsub ( struct skinny_subchannel sub,
int  forcehangup 
) [static]

Definition at line 5391 of file chan_skinny.c.

References activatesub(), skinny_line::activesub, AST_LIST_TRAVERSE, ast_log(), ast_verb, skinny_subchannel::callid, skinny_line::device, skinny_subchannel::line, LOG_WARNING, skinny_subchannel::related, setsubstate(), SKINNY_ONHOOK, SKINNY_SPEAKEROFF, skinny_line::sub, skinny_subchannel::substate, SUBSTATE_CALLWAIT, SUBSTATE_HOLD, SUBSTATE_ONHOOK, SUBSTATE_RINGIN, and transmit_speaker_mode().

Referenced by handle_onhook_message(), handle_soft_key_event_message(), and skinny_hangup().

05392 {
05393    struct skinny_line *l = sub->line;
05394    struct skinny_device *d = l->device;
05395    struct skinny_subchannel *activatesub = NULL;
05396    struct skinny_subchannel *tsub;
05397 
05398    if (skinnydebug) {
05399       ast_verb(3, "Sub %d - Dumping\n", sub->callid);
05400    }
05401    
05402    if (!forcehangup && sub->substate == SUBSTATE_HOLD) {
05403       l->activesub = NULL;
05404       return;
05405    }
05406    
05407    if (sub == l->activesub) {
05408       d->hookstate = SKINNY_ONHOOK;
05409       transmit_speaker_mode(d, SKINNY_SPEAKEROFF); 
05410       if (sub->related) {
05411          activatesub = sub->related;
05412          setsubstate(sub, SUBSTATE_ONHOOK);
05413          l->activesub = activatesub;
05414          if (l->activesub->substate != SUBSTATE_HOLD) {
05415             ast_log(LOG_WARNING, "Sub-%d was related but not at SUBSTATE_HOLD\n", sub->callid);
05416             return;
05417          }
05418          setsubstate(l->activesub, SUBSTATE_HOLD);
05419       } else {
05420          setsubstate(sub, SUBSTATE_ONHOOK);
05421          AST_LIST_TRAVERSE(&l->sub, tsub, list) {
05422             if (tsub->substate == SUBSTATE_CALLWAIT) {
05423                activatesub = tsub;
05424             }
05425          }
05426          if (activatesub) {
05427             setsubstate(activatesub, SUBSTATE_RINGIN);
05428             return;
05429          }
05430          AST_LIST_TRAVERSE(&l->sub, tsub, list) {
05431             if (tsub->substate == SUBSTATE_HOLD) {
05432                activatesub = tsub;
05433             }
05434          }
05435          if (activatesub) {
05436             setsubstate(activatesub, SUBSTATE_HOLD);
05437             return;
05438          }
05439       }
05440    } else {
05441       setsubstate(sub, SUBSTATE_ONHOOK);
05442    }
05443 }

static struct skinny_line* find_line_by_instance ( struct skinny_device d,
int  instance 
) [static, read]

Definition at line 1717 of file chan_skinny.c.

References AST_LIST_TRAVERSE, ast_log(), skinny_device::lines, and LOG_WARNING.

Referenced by find_subchannel_by_instance_reference(), handle_enbloc_call_message(), handle_offhook_message(), handle_soft_key_event_message(), handle_stimulus_message(), and transmit_linestatres().

01718 {
01719    struct skinny_line *l;
01720 
01721    /*Dialing from on hook or on a 7920 uses instance 0 in requests
01722      but we need to start looking at instance 1 */
01723 
01724    if (!instance)
01725       instance = 1;
01726 
01727    AST_LIST_TRAVERSE(&d->lines, l, list){
01728       if (l->instance == instance)
01729          break;
01730    }
01731 
01732    if (!l) {
01733       ast_log(LOG_WARNING, "Could not find line with instance '%d' on device '%s'\n", instance, d->name);
01734    }
01735    return l;
01736 }

static struct skinny_line* find_line_by_name ( const char *  dest  )  [static, read]

Definition at line 1738 of file chan_skinny.c.

References ast_copy_string(), AST_LIST_LOCK, AST_LIST_TRAVERSE, AST_LIST_UNLOCK, ast_strlen_zero(), ast_verb, and skinny_device::lines.

Referenced by skinny_devicestate(), and skinny_request().

01739 {
01740    struct skinny_line *l;
01741    struct skinny_line *tmpl = NULL;
01742    struct skinny_device *d;
01743    char line[256];
01744    char *at;
01745    char *device;
01746    int checkdevice = 0;
01747 
01748    ast_copy_string(line, dest, sizeof(line));
01749    at = strchr(line, '@');
01750    if (at)
01751       *at++ = '\0';
01752    device = at;
01753 
01754    if (!ast_strlen_zero(device))
01755       checkdevice = 1;
01756 
01757    AST_LIST_LOCK(&devices);
01758    AST_LIST_TRAVERSE(&devices, d, list){
01759       if (checkdevice && tmpl)
01760          break;
01761       else if (!checkdevice) {
01762          /* This is a match, since we're checking for line on every device. */
01763       } else if (!strcasecmp(d->name, device)) {
01764          if (skinnydebug)
01765             ast_verb(2, "Found device: %s\n", d->name);
01766       } else
01767          continue;
01768 
01769       /* Found the device (or we don't care which device) */
01770       AST_LIST_TRAVERSE(&d->lines, l, list){
01771          /* Search for the right line */
01772          if (!strcasecmp(l->name, line)) {
01773             if (tmpl) {
01774                ast_verb(2, "Ambiguous line name: %s\n", line);
01775                AST_LIST_UNLOCK(&devices);
01776                return NULL;
01777             } else
01778                tmpl = l;
01779          }
01780       }
01781    }
01782    AST_LIST_UNLOCK(&devices);
01783    return tmpl;
01784 }

static struct skinny_speeddial* find_speeddial_by_instance ( struct skinny_device d,
int  instance,
int  isHint 
) [static, read]

Definition at line 1907 of file chan_skinny.c.

References AST_LIST_TRAVERSE, ast_log(), skinny_speeddial::instance, skinny_speeddial::isHint, LOG_WARNING, and skinny_device::speeddials.

Referenced by handle_message(), handle_stimulus_message(), and transmit_linestatres().

01908 {
01909    struct skinny_speeddial *sd;
01910 
01911    AST_LIST_TRAVERSE(&d->speeddials, sd, list) {
01912       if (sd->isHint == isHint && sd->instance == instance)
01913          break;
01914    }
01915 
01916    if (!sd) {
01917       ast_log(LOG_WARNING, "Could not find speeddial with instance '%d' on device '%s'\n", instance, d->name);
01918    }
01919    return sd;
01920 }

static struct skinny_subchannel* find_subchannel_by_instance_reference ( struct skinny_device d,
int  instance,
int  reference 
) [static, read]

Definition at line 1856 of file chan_skinny.c.

References AST_LIST_FIRST, AST_LIST_TRAVERSE, ast_log(), skinny_subchannel::callid, find_line_by_instance(), LOG_WARNING, skinny_line::sub, and 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().

01857 {
01858    struct skinny_line *l = find_line_by_instance(d, instance);
01859    struct skinny_subchannel *sub;
01860 
01861    if (!l) {
01862       return NULL;
01863    }
01864 
01865    /* 7920 phones set call reference to 0, so use the first
01866       sub-channel on the list.
01867            This MIGHT need more love to be right */
01868    if (!reference)
01869       sub = AST_LIST_FIRST(&l->sub);
01870    else {
01871       AST_LIST_TRAVERSE(&l->sub, sub, list) {
01872          if (sub->callid == reference)
01873             break;
01874       }
01875    }
01876    if (!sub) {
01877       ast_log(LOG_WARNING, "Could not find subchannel with reference '%d' on '%s'\n", reference, d->name);
01878    }
01879    return sub;
01880 }

static struct skinny_subchannel* find_subchannel_by_reference ( struct skinny_device d,
int  reference 
) [static, read]

Definition at line 1883 of file chan_skinny.c.

References AST_LIST_TRAVERSE, ast_log(), skinny_subchannel::callid, skinny_device::lines, LOG_WARNING, skinny_line::sub, and sub.

Referenced by handle_open_receive_channel_ack_message().

01884 {
01885    struct skinny_line *l;
01886    struct skinny_subchannel *sub = NULL;
01887 
01888    AST_LIST_TRAVERSE(&d->lines, l, list){
01889       AST_LIST_TRAVERSE(&l->sub, sub, list){
01890          if (sub->callid == reference)
01891             break;
01892       }
01893       if (sub)
01894          break;
01895    }
01896 
01897    if (!l) {
01898       ast_log(LOG_WARNING, "Could not find any lines that contained a subchannel with reference '%d' on device '%s'\n", reference, d->name);
01899    } else {
01900       if (!sub) {
01901          ast_log(LOG_WARNING, "Could not find subchannel with reference '%d' on '%s@%s'\n", reference, l->name, d->name);
01902       }
01903    }
01904    return sub;
01905 }

static struct skinny_subline* find_subline_by_callid ( struct skinny_device d,
int  callid 
) [static, read]

Definition at line 1812 of file chan_skinny.c.

References AST_LIST_TRAVERSE, skinny_subline::callid, skinny_device::lines, and skinny_line::sublines.

Referenced by handle_soft_key_event_message().

01813 {
01814    struct skinny_subline *subline;
01815    struct skinny_line *l;
01816    
01817    AST_LIST_TRAVERSE(&d->lines, l, list){
01818       AST_LIST_TRAVERSE(&l->sublines, subline, list){
01819          if (subline->callid == callid) {
01820             return subline;
01821          }
01822       }
01823    }
01824    return NULL;
01825 }

static struct skinny_subline* find_subline_by_name ( const char *  dest  )  [static, read]

Definition at line 1786 of file chan_skinny.c.

References AST_LIST_LOCK, AST_LIST_TRAVERSE, AST_LIST_UNLOCK, ast_verb, skinny_device::lines, skinny_subline::name, and skinny_line::sublines.

Referenced by skinny_request().

01787 {
01788    struct skinny_line *l;
01789    struct skinny_subline *subline;
01790    struct skinny_subline *tmpsubline = NULL;
01791    struct skinny_device *d;
01792 
01793    AST_LIST_LOCK(&devices);
01794    AST_LIST_TRAVERSE(&devices, d, list){
01795       AST_LIST_TRAVERSE(&d->lines, l, list){
01796          AST_LIST_TRAVERSE(&l->sublines, subline, list){
01797             if (!strcasecmp(subline->name, dest)) {
01798                if (tmpsubline) {
01799                   ast_verb(2, "Ambiguous subline name: %s\n", dest);
01800                   AST_LIST_UNLOCK(&devices);
01801                   return NULL;
01802                } else
01803                   tmpsubline = subline;
01804             }
01805          }
01806       }
01807    }
01808    AST_LIST_UNLOCK(&devices);
01809    return tmpsubline;
01810 }

static void* get_button_template ( struct skinnysession s,
struct button_definition_template btn 
) [static]

Definition at line 1566 of file chan_skinny.c.

References skinny_device::addons, AST_LIST_LOCK, AST_LIST_TRAVERSE, AST_LIST_UNLOCK, ast_log(), BT_CALLPARK, BT_CONFERENCE, BT_CUST_LINE, BT_CUST_LINESPEEDDIAL, BT_DISPLAY, BT_FORWARDALL, BT_HOLD, BT_LINE, BT_NONE, BT_REDIAL, BT_SPEEDDIAL, BT_TRANSFER, BT_VOICEMAIL, skinnysession::device, LOG_WARNING, SKINNY_DEVICE_12, SKINNY_DEVICE_12SP, SKINNY_DEVICE_12SPPLUS, SKINNY_DEVICE_30SPPLUS, SKINNY_DEVICE_30VIP, SKINNY_DEVICE_7902, SKINNY_DEVICE_7905, SKINNY_DEVICE_7906, SKINNY_DEVICE_7910, SKINNY_DEVICE_7911, SKINNY_DEVICE_7912, SKINNY_DEVICE_7914, SKINNY_DEVICE_7920, SKINNY_DEVICE_7921, SKINNY_DEVICE_7931, SKINNY_DEVICE_7935, SKINNY_DEVICE_7936, SKINNY_DEVICE_7937, SKINNY_DEVICE_7940, SKINNY_DEVICE_7941, SKINNY_DEVICE_7941GE, SKINNY_DEVICE_7942, SKINNY_DEVICE_7945, SKINNY_DEVICE_7960, SKINNY_DEVICE_7961, SKINNY_DEVICE_7961GE, SKINNY_DEVICE_7962, SKINNY_DEVICE_7965, SKINNY_DEVICE_7970, SKINNY_DEVICE_7971, SKINNY_DEVICE_7975, SKINNY_DEVICE_7985, SKINNY_DEVICE_ATA186, SKINNY_DEVICE_CIPC, SKINNY_DEVICE_SCCPGATEWAY_AN, SKINNY_DEVICE_SCCPGATEWAY_BRI, and skinny_addon::type.

Referenced by handle_button_template_req_message().

01567 {
01568    struct skinny_device *d = s->device;
01569    struct skinny_addon *a;
01570    int i;
01571 
01572    switch (d->type) {
01573       case SKINNY_DEVICE_30SPPLUS:
01574       case SKINNY_DEVICE_30VIP:
01575          /* 13 rows, 2 columns */
01576          for (i = 0; i < 4; i++)
01577             (btn++)->buttonDefinition = BT_CUST_LINE;
01578          (btn++)->buttonDefinition = BT_REDIAL;
01579          (btn++)->buttonDefinition = BT_VOICEMAIL;
01580          (btn++)->buttonDefinition = BT_CALLPARK;
01581          (btn++)->buttonDefinition = BT_FORWARDALL;
01582          (btn++)->buttonDefinition = BT_CONFERENCE;
01583          for (i = 0; i < 4; i++)
01584             (btn++)->buttonDefinition = BT_NONE;
01585          for (i = 0; i < 13; i++)
01586             (btn++)->buttonDefinition = BT_SPEEDDIAL;
01587          
01588          break;
01589       case SKINNY_DEVICE_12SPPLUS:
01590       case SKINNY_DEVICE_12SP:
01591       case SKINNY_DEVICE_12:
01592          /* 6 rows, 2 columns */
01593          for (i = 0; i < 2; i++)
01594             (btn++)->buttonDefinition = BT_CUST_LINE;
01595          for (i = 0; i < 4; i++)
01596             (btn++)->buttonDefinition = BT_SPEEDDIAL;
01597          (btn++)->buttonDefinition = BT_HOLD;
01598          (btn++)->buttonDefinition = BT_REDIAL;
01599          (btn++)->buttonDefinition = BT_TRANSFER;
01600          (btn++)->buttonDefinition = BT_FORWARDALL;
01601          (btn++)->buttonDefinition = BT_CALLPARK;
01602          (btn++)->buttonDefinition = BT_VOICEMAIL;
01603          break;
01604       case SKINNY_DEVICE_7910:
01605          (btn++)->buttonDefinition = BT_LINE;
01606          (btn++)->buttonDefinition = BT_HOLD;
01607          (btn++)->buttonDefinition = BT_TRANSFER;
01608          (btn++)->buttonDefinition = BT_DISPLAY;
01609          (btn++)->buttonDefinition = BT_VOICEMAIL;
01610          (btn++)->buttonDefinition = BT_CONFERENCE;
01611          (btn++)->buttonDefinition = BT_FORWARDALL;
01612          for (i = 0; i < 2; i++)
01613             (btn++)->buttonDefinition = BT_SPEEDDIAL;
01614          (btn++)->buttonDefinition = BT_REDIAL;
01615          break;
01616       case SKINNY_DEVICE_7960:
01617       case SKINNY_DEVICE_7961:
01618       case SKINNY_DEVICE_7961GE:
01619       case SKINNY_DEVICE_7962:
01620       case SKINNY_DEVICE_7965:
01621          for (i = 0; i < 6; i++)
01622             (btn++)->buttonDefinition = BT_CUST_LINESPEEDDIAL;
01623          break;
01624       case SKINNY_DEVICE_7940:
01625       case SKINNY_DEVICE_7941:
01626       case SKINNY_DEVICE_7941GE:
01627       case SKINNY_DEVICE_7942:
01628       case SKINNY_DEVICE_7945:
01629          for (i = 0; i < 2; i++)
01630             (btn++)->buttonDefinition = BT_CUST_LINESPEEDDIAL;
01631          break;
01632       case SKINNY_DEVICE_7935:
01633       case SKINNY_DEVICE_7936:
01634          for (i = 0; i < 2; i++)
01635             (btn++)->buttonDefinition = BT_LINE;
01636          break;
01637       case SKINNY_DEVICE_ATA186:
01638          (btn++)->buttonDefinition = BT_LINE;
01639          break;
01640       case SKINNY_DEVICE_7970:
01641       case SKINNY_DEVICE_7971:
01642       case SKINNY_DEVICE_7975:
01643       case SKINNY_DEVICE_CIPC:
01644          for (i = 0; i < 8; i++)
01645             (btn++)->buttonDefinition = BT_CUST_LINESPEEDDIAL;
01646          break;
01647       case SKINNY_DEVICE_7985:
01648          /* XXX I have no idea what the buttons look like on these. */
01649          ast_log(LOG_WARNING, "Unsupported device type '%d (7985)' found.\n", d->type);
01650          break;
01651       case SKINNY_DEVICE_7912:
01652       case SKINNY_DEVICE_7911:
01653       case SKINNY_DEVICE_7905:
01654          (btn++)->buttonDefinition = BT_LINE;
01655          (btn++)->buttonDefinition = BT_HOLD;
01656          break;
01657       case SKINNY_DEVICE_7920:
01658          /* XXX I don't know if this is right. */
01659          for (i = 0; i < 4; i++)
01660             (btn++)->buttonDefinition = BT_CUST_LINESPEEDDIAL;
01661          break;
01662       case SKINNY_DEVICE_7921:
01663          for (i = 0; i < 6; i++)
01664             (btn++)->buttonDefinition = BT_CUST_LINESPEEDDIAL;
01665          break;
01666       case SKINNY_DEVICE_7902:
01667          ast_log(LOG_WARNING, "Unsupported device type '%d (7902)' found.\n", d->type);
01668          break;
01669       case SKINNY_DEVICE_7906:
01670          ast_log(LOG_WARNING, "Unsupported device type '%d (7906)' found.\n", d->type);
01671          break;
01672       case SKINNY_DEVICE_7931:
01673          ast_log(LOG_WARNING, "Unsupported device type '%d (7931)' found.\n", d->type);
01674          break;
01675       case SKINNY_DEVICE_7937:
01676          ast_log(LOG_WARNING, "Unsupported device type '%d (7937)' found.\n", d->type);
01677          break;
01678       case SKINNY_DEVICE_7914:
01679          ast_log(LOG_WARNING, "Unsupported device type '%d (7914)' found.  Expansion module registered by itself?\n", d->type);
01680          break;
01681       case SKINNY_DEVICE_SCCPGATEWAY_AN:
01682       case SKINNY_DEVICE_SCCPGATEWAY_BRI:
01683          ast_log(LOG_WARNING, "Unsupported device type '%d (SCCP gateway)' found.\n", d->type);
01684          break;
01685       default:
01686          ast_log(LOG_WARNING, "Unknown device type '%d' found.\n", d->type);
01687          break;
01688    }
01689 
01690    AST_LIST_LOCK(&d->addons);
01691    AST_LIST_TRAVERSE(&d->addons, a, list) {
01692       if (!strcasecmp(a->type, "7914")) {
01693          for (i = 0; i < 14; i++)
01694             (btn++)->buttonDefinition = BT_CUST_LINESPEEDDIAL;
01695       } else {
01696          ast_log(LOG_WARNING, "Unknown addon type '%s' found.  Skipping.\n", a->type);
01697       }
01698    }
01699    AST_LIST_UNLOCK(&d->addons);
01700 
01701    return btn;
01702 }

static int get_devicestate ( struct skinny_line l  )  [static]

Definition at line 4609 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_ONHOOK, skinny_line::sub, sub, skinny_subchannel::substate, and SUBSTATE_HOLD.

Referenced by skinny_devicestate(), and skinny_new().

04610 {
04611    struct skinny_subchannel *sub;
04612    int res = AST_DEVICE_UNKNOWN;
04613 
04614    if (!l)
04615       res = AST_DEVICE_INVALID;
04616    else if (!l->device)
04617       res = AST_DEVICE_UNAVAILABLE;
04618    else if (l->dnd)
04619       res = AST_DEVICE_BUSY;
04620    else {
04621       if (l->device->hookstate == SKINNY_ONHOOK) {
04622          res = AST_DEVICE_NOT_INUSE;
04623       } else {
04624          res = AST_DEVICE_INUSE;
04625       }
04626 
04627       AST_LIST_TRAVERSE(&l->sub, sub, list) {
04628          if (sub->substate == SUBSTATE_HOLD) {
04629             res = AST_DEVICE_ONHOLD;
04630             break;
04631          }
04632       }
04633    }
04634 
04635    return res;
04636 }

static int get_input ( struct skinnysession s  )  [static]

Definition at line 6843 of file chan_skinny.c.

References ast_debug, ast_log(), ast_mutex_lock, ast_mutex_unlock, ast_poll, ast_verb, skinnysession::device, errno, skinnysession::fd, htolel, skinnysession::inbuf, letohl, skinnysession::lock, LOG_ERROR, LOG_WARNING, SKINNY_MAX_PACKET, skinny_unregister(), and skinnysession::start.

Referenced by do_message(), and skinny_session().

06844 {
06845    int res;
06846    int dlen = 0;
06847    int timeout = keep_alive * 1100;
06848    time_t now;
06849    int *bufaddr;
06850    struct pollfd fds[1];
06851 
06852    if (!s->device) {
06853       if(time(&now) == -1) {
06854          ast_log(LOG_ERROR, "error executing time(): %s\n", strerror(errno));
06855          return -1;
06856       }
06857 
06858       timeout = (auth_timeout - (now - s->start)) * 1000;
06859       if (timeout < 0) {
06860          /* we have timed out */
06861          if (skinnydebug)
06862             ast_verb(1, "Skinny Client failed to authenticate in %d seconds\n", auth_timeout);
06863          return -1;
06864       }
06865    }
06866 
06867    fds[0].fd = s->fd;
06868    fds[0].events = POLLIN;
06869    fds[0].revents = 0;
06870    res = ast_poll(fds, 1, timeout); /* If nothing has happen, client is dead */
06871                    /* we add 10% to the keep_alive to deal */
06872                    /* with network delays, etc */
06873    if (res < 0) {
06874       if (errno != EINTR) {
06875          ast_log(LOG_WARNING, "Select returned error: %s\n", strerror(errno));
06876          return res;
06877       }
06878    } else if (res == 0) {
06879       if (skinnydebug) {
06880          if (s->device) {
06881             ast_verb(1, "Skinny Client was lost, unregistering\n");
06882          } else {
06883             ast_verb(1, "Skinny Client failed to authenticate in %d seconds\n", auth_timeout);
06884          }
06885       }
06886       skinny_unregister(NULL, s);
06887       return -1;
06888    }
06889            
06890    if (fds[0].revents) {
06891       ast_mutex_lock(&s->lock);
06892       memset(s->inbuf, 0, sizeof(s->inbuf));
06893       res = read(s->fd, s->inbuf, 4);
06894       if (res < 0) {
06895          ast_log(LOG_WARNING, "read() returned error: %s\n", strerror(errno));
06896 
06897          if (skinnydebug)
06898             ast_verb(1, "Skinny Client was lost, unregistering\n");
06899 
06900          skinny_unregister(NULL, s);
06901          ast_mutex_unlock(&s->lock);
06902          return res;
06903       } else if (res != 4) {
06904          ast_log(LOG_WARNING, "Skinny Client sent less data than expected.  Expected 4 but got %d.\n", res);
06905          ast_mutex_unlock(&s->lock);
06906 
06907          if (res == 0) {
06908             if (skinnydebug)
06909                ast_verb(1, "Skinny Client was lost, unregistering\n");
06910             skinny_unregister(NULL, s);
06911          }
06912 
06913          return -1;
06914       }
06915 
06916       bufaddr = (int *)s->inbuf;
06917       dlen = letohl(*bufaddr);
06918       if (dlen < 4) {
06919          ast_debug(1, "Skinny Client sent invalid data.\n");
06920          ast_mutex_unlock(&s->lock);
06921          return -1;
06922       }
06923       if (dlen+8 > sizeof(s->inbuf)) {
06924          ast_log(LOG_WARNING, "Skinny packet too large (%d bytes), max length(%d bytes)\n", dlen+8, SKINNY_MAX_PACKET);
06925          dlen = sizeof(s->inbuf) - 8;
06926       }
06927       *bufaddr = htolel(dlen);
06928 
06929       res = read(s->fd, s->inbuf+4, dlen+4);
06930       ast_mutex_unlock(&s->lock);
06931       if (res < 0) {
06932          ast_log(LOG_WARNING, "read() returned error: %s\n", strerror(errno));
06933          return res;
06934       } else if (res != (dlen+4)) {
06935          ast_log(LOG_WARNING, "Skinny Client sent less data than expected.\n");
06936          return -1;
06937       }
06938       return res;
06939    }
06940    return 0;
06941 }

static int handle_button_template_req_message ( struct skinny_req req,
struct skinnysession s 
) [static]

Definition at line 6080 of file chan_skinny.c.

References AST_LIST_TRAVERSE, ast_verb, BT_CUST_LINE, BT_CUST_LINESPEEDDIAL, BT_LINE, BT_NONE, BT_SPEEDDIAL, BUTTON_TEMPLATE_RES_MESSAGE, button_template_res_message::buttonCount, button_definition::buttonDefinition, button_definition_template::buttonDefinition, button_template_res_message::buttonOffset, skinny_data::buttontemplate, skinny_req::data, button_template_res_message::definition, skinnysession::device, get_button_template(), htolel, skinny_speeddial::instance, button_definition::instanceNumber, skinny_speeddial::isHint, skinny_device::lines, req_alloc(), skinny_device::speeddials, button_template_res_message::totalButtonCount, and transmit_response().

Referenced by handle_message().

06081 {
06082    struct skinny_device *d = s->device;
06083    struct skinny_line *l;
06084    int i;
06085 
06086    struct skinny_speeddial *sd;
06087    struct button_definition_template btn[42];
06088    int lineInstance = 1;
06089    int speeddialInstance = 1;
06090    int buttonCount = 0;
06091 
06092    if (!(req = req_alloc(sizeof(struct button_template_res_message), BUTTON_TEMPLATE_RES_MESSAGE)))
06093       return -1;
06094 
06095    memset(&btn, 0, sizeof(btn));
06096 
06097    get_button_template(s, btn);
06098 
06099    for (i=0; i<42; i++) {
06100       int btnSet = 0;
06101       switch (btn[i].buttonDefinition) {
06102          case BT_CUST_LINE:
06103             /* assume failure */
06104             req->data.buttontemplate.definition[i].buttonDefinition = BT_NONE;
06105             req->data.buttontemplate.definition[i].instanceNumber = 0;
06106 
06107             AST_LIST_TRAVERSE(&d->lines, l, list) {
06108                if (l->instance == lineInstance) {
06109                   ast_verb(0, "Adding button: %d, %d\n", BT_LINE, lineInstance);
06110                   req->data.buttontemplate.definition[i].buttonDefinition = BT_LINE;
06111                   req->data.buttontemplate.definition[i].instanceNumber = lineInstance;
06112                   lineInstance++;
06113                   buttonCount++;
06114                   btnSet = 1;
06115                   break;
06116                }
06117             }
06118 
06119             if (!btnSet) {
06120                AST_LIST_TRAVERSE(&d->speeddials, sd, list) {
06121                   if (sd->isHint && sd->instance == lineInstance) {
06122                      ast_verb(0, "Adding button: %d, %d\n", BT_LINE, lineInstance);
06123                      req->data.buttontemplate.definition[i].buttonDefinition = BT_LINE;
06124                      req->data.buttontemplate.definition[i].instanceNumber = lineInstance;
06125                      lineInstance++;
06126                      buttonCount++;
06127                      btnSet = 1;
06128                      break;
06129                   }
06130                }
06131             }
06132             break;
06133          case BT_CUST_LINESPEEDDIAL:
06134             /* assume failure */
06135             req->data.buttontemplate.definition[i].buttonDefinition = BT_NONE;
06136             req->data.buttontemplate.definition[i].instanceNumber = 0;
06137 
06138             AST_LIST_TRAVERSE(&d->lines, l, list) {
06139                if (l->instance == lineInstance) {
06140                   ast_verb(0, "Adding button: %d, %d\n", BT_LINE, lineInstance);
06141                   req->data.buttontemplate.definition[i].buttonDefinition = BT_LINE;
06142                   req->data.buttontemplate.definition[i].instanceNumber = lineInstance;
06143                   lineInstance++;
06144                   buttonCount++;
06145                   btnSet = 1;
06146                   break;
06147                }
06148             }
06149 
06150             if (!btnSet) {
06151                AST_LIST_TRAVERSE(&d->speeddials, sd, list) {
06152                   if (sd->isHint && sd->instance == lineInstance) {
06153                      ast_verb(0, "Adding button: %d, %d\n", BT_LINE, lineInstance);
06154                      req->data.buttontemplate.definition[i].buttonDefinition = BT_LINE;
06155                      req->data.buttontemplate.definition[i].instanceNumber = lineInstance;
06156                      lineInstance++;
06157                      buttonCount++;
06158                      btnSet = 1;
06159                      break;
06160                   } else if (!sd->isHint && sd->instance == speeddialInstance) {
06161                      ast_verb(0, "Adding button: %d, %d\n", BT_SPEEDDIAL, speeddialInstance);
06162                      req->data.buttontemplate.definition[i].buttonDefinition = BT_SPEEDDIAL;
06163                      req->data.buttontemplate.definition[i].instanceNumber = speeddialInstance;
06164                      speeddialInstance++;
06165                      buttonCount++;
06166                      btnSet = 1;
06167                      break;
06168                   }
06169                }
06170             }
06171             break;
06172          case BT_LINE:
06173             req->data.buttontemplate.definition[i].buttonDefinition = htolel(BT_NONE);
06174             req->data.buttontemplate.definition[i].instanceNumber = htolel(0);
06175 
06176             AST_LIST_TRAVERSE(&d->lines, l, list) {
06177                if (l->instance == lineInstance) {
06178                   ast_verb(0, "Adding button: %d, %d\n", BT_LINE, lineInstance);
06179                   req->data.buttontemplate.definition[i].buttonDefinition = BT_LINE;
06180                   req->data.buttontemplate.definition[i].instanceNumber = lineInstance;
06181                   lineInstance++;
06182                   buttonCount++;
06183                   btnSet = 1;
06184                   break;
06185                }
06186             }
06187             break;
06188          case BT_SPEEDDIAL:
06189             req->data.buttontemplate.definition[i].buttonDefinition = BT_NONE;
06190             req->data.buttontemplate.definition[i].instanceNumber = 0;
06191 
06192             AST_LIST_TRAVERSE(&d->speeddials, sd, list) {
06193                if (!sd->isHint && sd->instance == speeddialInstance) {
06194                   ast_verb(0, "Adding button: %d, %d\n", BT_SPEEDDIAL, speeddialInstance);
06195                   req->data.buttontemplate.definition[i].buttonDefinition = BT_SPEEDDIAL;
06196                   req->data.buttontemplate.definition[i].instanceNumber = speeddialInstance - 1;
06197                   speeddialInstance++;
06198                   buttonCount++;
06199                   btnSet = 1;
06200                   break;
06201                }
06202             }
06203             break;
06204          case BT_NONE:
06205             break;
06206          default:
06207             ast_verb(0, "Adding button: %d, %d\n", btn[i].buttonDefinition, 0);
06208             req->data.buttontemplate.definition[i].buttonDefinition = htolel(btn[i].buttonDefinition);
06209             req->data.buttontemplate.definition[i].instanceNumber = 0;
06210             buttonCount++;
06211             btnSet = 1;
06212             break;
06213       }
06214    }
06215 
06216    req->data.buttontemplate.buttonOffset = 0;
06217    req->data.buttontemplate.buttonCount = htolel(buttonCount);
06218    req->data.buttontemplate.totalButtonCount = htolel(buttonCount);
06219 
06220    if (skinnydebug)
06221       ast_verb(1, "Sending %d template to %s\n",
06222                d->type,
06223                d->name);
06224    transmit_response(d, req);
06225    return 1;
06226 }

static int handle_callforward_button ( struct skinny_subchannel sub,
int  cfwdtype 
) [static]

Definition at line 5551 of file chan_skinny.c.

References ast_channel::_state, ast_hangup(), ast_indicate(), ast_safe_sleep(), AST_STATE_UP, skinny_subchannel::callid, skinny_line::device, KEYDEF_ONHOOK, skinny_subchannel::line, skinny_subchannel::owner, set_callforwards(), setsubstate(), SKINNY_OFFHOOK, SKINNY_ONHOOK, SKINNY_SPEAKEROFF, SKINNY_SPEAKERON, SUBSTATE_OFFHOOK, transmit_activatecallplane(), transmit_callstate(), transmit_cfwdstate(), transmit_clear_display_message(), transmit_clearpromptmessage(), transmit_closereceivechannel(), transmit_displaynotify(), transmit_selectsoftkeys(), transmit_speaker_mode(), and transmit_stopmediatransmission().

Referenced by handle_soft_key_event_message(), and handle_stimulus_message().

05552 {
05553    struct skinny_line *l = sub->line;
05554    struct skinny_device *d = l->device;
05555    struct ast_channel *c = sub->owner;
05556 
05557    if (d->hookstate == SKINNY_ONHOOK) {
05558       d->hookstate = SKINNY_OFFHOOK;
05559       transmit_speaker_mode(d, SKINNY_SPEAKERON);
05560       transmit_callstate(d, l->instance, sub->callid, SKINNY_OFFHOOK);
05561       transmit_activatecallplane(d, l);
05562    }
05563    transmit_clear_display_message(d, l->instance, sub->callid);
05564 
05565    if (l->cfwdtype & cfwdtype) {
05566       set_callforwards(l, NULL, cfwdtype);
05567       ast_safe_sleep(c, 500);
05568       transmit_speaker_mode(d, SKINNY_SPEAKEROFF);
05569       transmit_closereceivechannel(d, sub);
05570       transmit_stopmediatransmission(d, sub);
05571       transmit_speaker_mode(d, SKINNY_SPEAKEROFF);
05572       transmit_clearpromptmessage(d, l->instance, sub->callid);
05573       transmit_callstate(d, l->instance, sub->callid, SKINNY_ONHOOK);
05574       transmit_selectsoftkeys(d, 0, 0, KEYDEF_ONHOOK);
05575       transmit_activatecallplane(d, l);
05576       transmit_displaynotify(d, "CFwd disabled", 10);
05577       if (sub->owner && sub->owner->_state != AST_STATE_UP) {
05578          ast_indicate(c, -1);
05579          ast_hangup(c);
05580       }
05581       transmit_cfwdstate(d, l);
05582    } else {
05583       l->getforward = cfwdtype;
05584       setsubstate(sub, SUBSTATE_OFFHOOK);
05585    }
05586    return 0;
05587 }

static int handle_capabilities_res_message ( struct skinny_req req,
struct skinnysession s 
) [static]

Definition at line 6039 of file chan_skinny.c.

References ast_format_cap_add(), ast_format_cap_alloc(), ast_format_cap_destroy(), ast_format_cap_joint_copy(), ast_getformatname(), ast_getformatname_multiple(), AST_LIST_TRAVERSE, ast_log(), ast_mutex_lock, ast_mutex_unlock, ast_verb, skinny_line::cap, skinny_device::cap, capabilities_res_message::caps, skinny_data::caps, station_capabilities::codec, codec_skinny2ast(), skinny_line::confcap, skinny_device::confcap, capabilities_res_message::count, skinny_req::data, skinnysession::device, letohl, skinny_device::lines, skinny_line::lock, LOG_WARNING, and SKINNY_MAX_CAPABILITIES.

Referenced by handle_message().

06040 {
06041    struct skinny_device *d = s->device;
06042    struct skinny_line *l;
06043    uint32_t count = 0;
06044    struct ast_format_cap *codecs = ast_format_cap_alloc();
06045    int i;
06046    char buf[256];
06047 
06048    if (!codecs) {
06049       return 0;
06050    }
06051 
06052    count = letohl(req->data.caps.count);
06053    if (count > SKINNY_MAX_CAPABILITIES) {
06054       count = SKINNY_MAX_CAPABILITIES;
06055       ast_log(LOG_WARNING, "Received more capabilities than we can handle (%d).  Ignoring the rest.\n", SKINNY_MAX_CAPABILITIES);
06056    }
06057 
06058    for (i = 0; i < count; i++) {
06059       struct ast_format acodec;
06060       int scodec = 0;
06061       scodec = letohl(req->data.caps.caps[i].codec);
06062       codec_skinny2ast(scodec, &acodec);
06063       if (skinnydebug)
06064          ast_verb(1, "Adding codec capability %s (%d)'\n", ast_getformatname(&acodec), scodec);
06065       ast_format_cap_add(codecs, &acodec);
06066    }
06067 
06068    ast_format_cap_joint_copy(d->confcap, codecs, d->cap);
06069    ast_verb(0, "Device capability set to '%s'\n", ast_getformatname_multiple(buf, sizeof(buf), d->cap));
06070    AST_LIST_TRAVERSE(&d->lines, l, list) {
06071       ast_mutex_lock(&l->lock);
06072       ast_format_cap_joint_copy(l->confcap, d->cap, l->cap);
06073       ast_mutex_unlock(&l->lock);
06074    }
06075 
06076    codecs = ast_format_cap_destroy(codecs);
06077    return 1;
06078 }

static int handle_enbloc_call_message ( struct skinny_req req,
struct skinnysession s 
) [static]

Definition at line 6298 of file chan_skinny.c.

References ast_log(), AST_STATE_DOWN, ast_verb, enbloc_call_message::calledParty, skinny_req::data, skinnysession::device, dialandactivatesub(), skinny_data::enbloccallmessage, find_line_by_instance(), find_subchannel_by_instance_reference(), skinny_subchannel::line, LOG_WARNING, skinny_new(), SKINNY_OFFHOOK, SKINNY_OUTGOING, sub, and ast_channel::tech_pvt.

Referenced by handle_message().

06299 {
06300    struct skinny_device *d = s->device;
06301    struct skinny_line *l;
06302    struct skinny_subchannel *sub = NULL;
06303    struct ast_channel *c;
06304 
06305    if (skinnydebug)
06306       ast_verb(1, "Received Enbloc Call: %s\n", req->data.enbloccallmessage.calledParty);
06307 
06308    sub = find_subchannel_by_instance_reference(d, d->lastlineinstance, d->lastcallreference);
06309 
06310    if (!sub) {
06311       l = find_line_by_instance(d, d->lastlineinstance);
06312       if (!l) {
06313          return 0;
06314       }
06315    } else {
06316       l = sub->line;
06317    }
06318 
06319    c = skinny_new(l, NULL, AST_STATE_DOWN, NULL, SKINNY_OUTGOING);
06320 
06321    if(!c) {
06322       ast_log(LOG_WARNING, "Unable to create channel for %s@%s\n", l->name, d->name);
06323    } else {
06324       d->hookstate = SKINNY_OFFHOOK;
06325 
06326       sub = c->tech_pvt;
06327       dialandactivatesub(sub, req->data.enbloccallmessage.calledParty);
06328    }
06329    
06330    return 1;
06331 }

static int handle_hold_button ( struct skinny_subchannel sub  )  [static]

Definition at line 5481 of file chan_skinny.c.

References activatesub(), skinny_subchannel::related, setsubstate(), skinny_subchannel::substate, SUBSTATE_CONNECTED, and SUBSTATE_HOLD.

Referenced by handle_stimulus_message().

05482 {
05483    if (!sub)
05484       return -1;
05485    if (sub->related) {
05486       setsubstate(sub, SUBSTATE_HOLD);
05487       activatesub(sub->related, SUBSTATE_CONNECTED);
05488    } else {
05489       if (sub->substate == SUBSTATE_HOLD) {
05490          activatesub(sub, SUBSTATE_CONNECTED);
05491       } else {
05492          setsubstate(sub, SUBSTATE_HOLD);
05493       }
05494    }
05495    return 1;
05496 }

static int handle_ip_port_message ( struct skinny_req req,
struct skinnysession s 
) [static]

Definition at line 5588 of file chan_skinny.c.

Referenced by handle_message().

05589 {
05590    /* no response necessary */
05591    return 1;
05592 }

static int handle_keypad_button_message ( struct skinny_req req,
struct skinnysession s 
) [static]

Definition at line 5594 of file chan_skinny.c.

References ast_channel::_state, skinny_device::activeline, skinny_line::activesub, AST_FRAME_DTMF_BEGIN, AST_FRAME_DTMF_END, AST_LIST_NEXT, ast_log(), ast_queue_frame(), ast_verb, keypad_button_message::button, keypad_button_message::callReference, skinny_req::data, skinnysession::device, find_subchannel_by_instance_reference(), ast_frame::frametype, ast_frame_subclass::integer, skinny_data::keypad, letohl, skinny_subchannel::line, keypad_button_message::lineInstance, LOG_WARNING, skinny_subchannel::owner, ast_frame::src, sub, and ast_frame::subclass.

Referenced by handle_message().

05595 {
05596    struct skinny_subchannel *sub = NULL;
05597    struct skinny_line *l;
05598    struct skinny_device *d = s->device;
05599    struct ast_frame f = { 0, };
05600    char dgt;
05601    int digit;
05602    int lineInstance;
05603    int callReference;
05604 
05605    digit = letohl(req->data.keypad.button);
05606    lineInstance = letohl(req->data.keypad.lineInstance);
05607    callReference = letohl(req->data.keypad.callReference);
05608 
05609    if (digit == 14) {
05610       dgt = '*';
05611    } else if (digit == 15) {
05612       dgt = '#';
05613    } else if (digit >= 0 && digit <= 9) {
05614       dgt = '0' + digit;
05615    } else {
05616       /* digit=10-13 (A,B,C,D ?), or
05617        * digit is bad value
05618        *
05619        * probably should not end up here, but set
05620        * value for backward compatibility, and log
05621        * a warning.
05622        */
05623       dgt = '0' + digit;
05624       ast_log(LOG_WARNING, "Unsupported digit %d\n", digit);
05625    }
05626 
05627    f.subclass.integer = dgt;
05628 
05629    f.src = "skinny";
05630 
05631    if (lineInstance && callReference)
05632       sub = find_subchannel_by_instance_reference(d, lineInstance, callReference);
05633    else
05634       sub = d->activeline->activesub;
05635       //sub = find_subchannel_by_instance_reference(d, d->lastlineinstance, d->lastcallreference);
05636 
05637    if (!sub)
05638       return 0;
05639 
05640    l = sub->line;
05641    if (sub->owner) {
05642       if (sub->owner->_state == 0) {
05643          f.frametype = AST_FRAME_DTMF_BEGIN;
05644          ast_queue_frame(sub->owner, &f);
05645       }
05646       /* XXX MUST queue this frame to all lines in threeway call if threeway call is active */
05647       f.frametype = AST_FRAME_DTMF_END;
05648       ast_queue_frame(sub->owner, &f);
05649       /* XXX This seriously needs to be fixed */
05650       if (AST_LIST_NEXT(sub, list) && AST_LIST_NEXT(sub, list)->owner) {
05651          if (sub->owner->_state == 0) {
05652             f.frametype = AST_FRAME_DTMF_BEGIN;
05653             ast_queue_frame(AST_LIST_NEXT(sub, list)->owner, &f);
05654          }
05655          f.frametype = AST_FRAME_DTMF_END;
05656          ast_queue_frame(AST_LIST_NEXT(sub, list)->owner, &f);
05657       }
05658    } else {
05659       if (skinnydebug)
05660          ast_verb(1, "No owner: %s\n", l->name);
05661    }
05662    return 1;
05663 }

static int handle_message ( struct skinny_req req,
struct skinnysession s 
) [static]

Definition at line 6641 of file chan_skinny.c.

References ast_channel::_state, skinny_device::activeline, skinny_line::activesub, skinny_data::alarm, ALARM_MESSAGE, ast_atomic_fetchadd_int(), 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, skinny_subchannel::exten, 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_keypad_button_message(), handle_offhook_message(), handle_onhook_message(), handle_open_receive_channel_ack_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, message2str(), OFFHOOK_MESSAGE, ONHOOK_MESSAGE, OPEN_RECEIVE_CHANNEL_ACK_MESSAGE, skinny_subchannel::owner, REGISTER_AVAILABLE_LINES_MESSAGE, REGISTER_MESSAGE, SERVER_REQUEST_MESSAGE, SKINNY_DEVONLY, skinny_register(), 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, sub, skinny_subchannel::substate, SUBSTATE_HOLD, TIME_DATE_REQ_MESSAGE, transmit_capabilitiesreq(), transmit_definetimedate(), transmit_keepaliveack(), transmit_linestatres(), transmit_registerack(), transmit_registerrej(), transmit_selectsoftkeys(), transmit_serverres(), transmit_softkeysetres(), transmit_softkeytemplateres(), transmit_speeddialstatres(), transmit_versionres(), UNREGISTER_MESSAGE, and VERSION_REQ_MESSAGE.

Referenced by skinny_session().

06642 {
06643    int res = 0;
06644    struct skinny_speeddial *sd;
06645    struct skinny_device *d = s->device;
06646    
06647    if ((!s->device) && (letohl(req->e) != REGISTER_MESSAGE && letohl(req->e) != ALARM_MESSAGE)) {
06648       ast_log(LOG_WARNING, "Client sent message #%d without first registering.\n", req->e);
06649       ast_free(req);
06650       return 0;
06651    }
06652 
06653    SKINNY_DEVONLY(if (skinnydebug > 1) {
06654       ast_verb(4, "Received %s from %s\n", message2str(req->e), s->device->name);
06655    })
06656 
06657    switch(letohl(req->e)) {
06658    case KEEP_ALIVE_MESSAGE:
06659       transmit_keepaliveack(s->device);
06660       break;
06661    case REGISTER_MESSAGE:
06662       if (skinny_register(req, s)) {
06663          ast_atomic_fetchadd_int(&unauth_sessions, -1);
06664          ast_verb(3, "Device '%s' successfully registered (protoVers %d)\n", s->device->name, s->device->protocolversion);
06665          transmit_registerack(s->device);
06666          transmit_capabilitiesreq(s->device);
06667       } else {
06668          transmit_registerrej(s);
06669          ast_free(req);
06670          return -1;
06671       }
06672    case IP_PORT_MESSAGE:
06673       res = handle_ip_port_message(req, s);
06674       break;
06675    case KEYPAD_BUTTON_MESSAGE:
06676        {
06677       struct skinny_device *d = s->device;
06678       struct skinny_subchannel *sub;
06679       int lineInstance;
06680       int callReference;
06681 
06682       if (skinnydebug)
06683          ast_verb(1, "Collected digit: [%d]\n", letohl(req->data.keypad.button));
06684 
06685       lineInstance = letohl(req->data.keypad.lineInstance);
06686       callReference = letohl(req->data.keypad.callReference);
06687 
06688       if (lineInstance) {
06689          sub = find_subchannel_by_instance_reference(d, lineInstance, callReference);
06690       } else {
06691          sub = d->activeline->activesub;
06692       }
06693 
06694       if (sub && ((sub->owner && sub->owner->_state <  AST_STATE_UP) || sub->substate == SUBSTATE_HOLD)) {
06695          char dgt;
06696          int digit = letohl(req->data.keypad.button);
06697 
06698          if (digit == 14) {
06699             dgt = '*';
06700          } else if (digit == 15) {
06701             dgt = '#';
06702          } else if (digit >= 0 && digit <= 9) {
06703             dgt = '0' + digit;
06704          } else {
06705             /* digit=10-13 (A,B,C,D ?), or
06706             * digit is bad value
06707             *
06708             * probably should not end up here, but set
06709             * value for backward compatibility, and log
06710             * a warning.
06711             */
06712             dgt = '0' + digit;
06713             ast_log(LOG_WARNING, "Unsupported digit %d\n", digit);
06714          }
06715 
06716          sub->exten[strlen(sub->exten)] = dgt;
06717          sub->exten[strlen(sub->exten)+1] = '\0';
06718       } else
06719          res = handle_keypad_button_message(req, s);
06720       }
06721       break;
06722    case ENBLOC_CALL_MESSAGE:
06723       res = handle_enbloc_call_message(req, s);
06724       break;
06725    case STIMULUS_MESSAGE:
06726       res = handle_stimulus_message(req, s);
06727       break;
06728    case OFFHOOK_MESSAGE:
06729       res = handle_offhook_message(req, s);
06730       break;
06731    case ONHOOK_MESSAGE:
06732       res = handle_onhook_message(req, s);
06733       break;
06734    case CAPABILITIES_RES_MESSAGE:
06735       if (skinnydebug)
06736          ast_verb(1, "Received CapabilitiesRes\n");
06737 
06738       res = handle_capabilities_res_message(req, s);
06739       break;
06740    case SPEED_DIAL_STAT_REQ_MESSAGE:
06741       if (skinnydebug)
06742          ast_verb(1, "Received SpeedDialStatRequest\n");
06743       if ( (sd = find_speeddial_by_instance(s->device, letohl(req->data.speeddialreq.speedDialNumber), 0)) ) {
06744          transmit_speeddialstatres(d, sd);
06745       }
06746       break;
06747    case LINE_STATE_REQ_MESSAGE:
06748       if (skinnydebug)
06749          ast_verb(1, "Received LineStatRequest\n");
06750       transmit_linestatres(d, letohl(req->data.line.lineNumber));
06751       break;
06752    case TIME_DATE_REQ_MESSAGE:
06753       if (skinnydebug)
06754          ast_verb(1, "Received Time/Date Request\n");
06755 
06756       transmit_definetimedate(d);
06757       break;
06758    case BUTTON_TEMPLATE_REQ_MESSAGE:
06759       if (skinnydebug)
06760          ast_verb(1, "Buttontemplate requested\n");
06761 
06762       res = handle_button_template_req_message(req, s);
06763       break;
06764    case VERSION_REQ_MESSAGE:
06765       if (skinnydebug)
06766          ast_verb(1, "Version Request\n");
06767       transmit_versionres(d);
06768       break;
06769    case SERVER_REQUEST_MESSAGE:
06770       if (skinnydebug)
06771          ast_verb(1, "Received Server Request\n");
06772       transmit_serverres(d);
06773       break;
06774    case ALARM_MESSAGE:
06775       /* no response necessary */
06776       if (skinnydebug)
06777          ast_verb(1, "Received Alarm Message: %s\n", req->data.alarm.displayMessage);
06778       break;
06779    case OPEN_RECEIVE_CHANNEL_ACK_MESSAGE:
06780       if (skinnydebug)
06781          ast_verb(1, "Received Open Receive Channel Ack\n");
06782 
06783       res = handle_open_receive_channel_ack_message(req, s);
06784       break;
06785    case SOFT_KEY_SET_REQ_MESSAGE:
06786       if (skinnydebug)
06787          ast_verb(1, "Received SoftKeySetReq\n");
06788       transmit_softkeysetres(d);
06789       transmit_selectsoftkeys(d, 0, 0, KEYDEF_ONHOOK);
06790       break;
06791    case SOFT_KEY_EVENT_MESSAGE:
06792       res = handle_soft_key_event_message(req, s);
06793       break;
06794    case UNREGISTER_MESSAGE:
06795       if (skinnydebug)
06796          ast_verb(1, "Received Unregister Request\n");
06797 
06798       res = skinny_unregister(req, s);
06799       break;
06800    case SOFT_KEY_TEMPLATE_REQ_MESSAGE:
06801       if (skinnydebug)
06802          ast_verb(1, "Received SoftKey Template Request\n");
06803       transmit_softkeytemplateres(d);
06804       break;
06805    case HEADSET_STATUS_MESSAGE:
06806       /* XXX umm...okay?  Why do I care? */
06807       break;
06808    case REGISTER_AVAILABLE_LINES_MESSAGE:
06809       /* XXX I have no clue what this is for, but my phone was sending it, so... */
06810       break;
06811    default:
06812       if (skinnydebug)
06813          ast_verb(1, "RECEIVED UNKNOWN MESSAGE TYPE:  %x\n", letohl(req->e));
06814       break;
06815    }
06816    if (res >= 0 && req)
06817       ast_free(req);
06818    return res;
06819 }

static int handle_offhook_message ( struct skinny_req req,
struct skinnysession s 
) [static]

Definition at line 5921 of file chan_skinny.c.

References skinny_device::activeline, skinny_line::activesub, ast_channel_name(), ast_debug, AST_DEVICE_INUSE, ast_devstate_changed(), ast_log(), AST_STATE_DOWN, ast_verb, skinny_subchannel::calldirection, skinny_req::data, skinnysession::device, find_line_by_instance(), find_subchannel_by_instance_reference(), offhook_message::instance, letohl, skinny_subchannel::line, LOG_WARNING, skinny_data::offhook, skinny_subchannel::owner, offhook_message::reference, setsubstate(), SKINNY_DEVONLY, SKINNY_INCOMING, SKINNY_LAMP_ON, skinny_new(), SKINNY_OFFHOOK, SKINNY_OUTGOING, SKINNY_RING_OFF, STIMULUS_LINE, sub, skinny_subchannel::substate, SUBSTATE_CONNECTED, SUBSTATE_HOLD, SUBSTATE_OFFHOOK, ast_channel::tech_pvt, transmit_definetimedate(), transmit_lamp_indication(), and transmit_ringer_mode().

Referenced by handle_message().

05922 {
05923    struct skinny_device *d = s->device;
05924    struct skinny_line *l = NULL;
05925    struct skinny_subchannel *sub = NULL;
05926    struct ast_channel *c;
05927    int instance;
05928    int reference;
05929 
05930    instance = letohl(req->data.offhook.instance);
05931    reference = letohl(req->data.offhook.reference);
05932 
05933    SKINNY_DEVONLY(if (skinnydebug > 1) {
05934       ast_verb(4, "Received OFFHOOK_MESSAGE from %s, instance=%d, callid=%d\n", d->name, instance, reference);
05935    })
05936 
05937    if (d->hookstate == SKINNY_OFFHOOK) {
05938       ast_verb(3, "Got offhook message when device (%s) already offhook\n", d->name);
05939       return 0;
05940    }
05941 
05942    if (reference) {
05943       sub = find_subchannel_by_instance_reference(d, instance, reference);
05944       if (sub) {
05945          l = sub->line;
05946       }
05947    }
05948    if (!sub) {
05949       if (instance) {
05950          l = find_line_by_instance(d, instance);
05951       } else {
05952          l = d->activeline;
05953       }
05954       sub = l->activesub;
05955    }
05956 
05957    transmit_ringer_mode(d, SKINNY_RING_OFF);
05958    d->hookstate = SKINNY_OFFHOOK;
05959 
05960    ast_devstate_changed(AST_DEVICE_INUSE, "Skinny/%s", l->name);
05961 
05962    if (sub && sub->substate == SUBSTATE_HOLD) {
05963       return 1;
05964    }
05965 
05966    transmit_lamp_indication(d, STIMULUS_LINE, l->instance, SKINNY_LAMP_ON);
05967 
05968    if (sub && sub->calldirection == SKINNY_INCOMING) {
05969       setsubstate(sub, SUBSTATE_CONNECTED);
05970    } else {
05971       /* Not ideal, but let's send updated time at onhook and offhook, as it clears the display */
05972       transmit_definetimedate(d);
05973 
05974       if (sub && sub->owner) {
05975          ast_debug(1, "Current sub [%s] already has owner\n", ast_channel_name(sub->owner));
05976       } else {
05977          c = skinny_new(l, NULL, AST_STATE_DOWN, NULL, SKINNY_OUTGOING);
05978          if (c) {
05979             setsubstate(c->tech_pvt, SUBSTATE_OFFHOOK);
05980          } else {
05981             ast_log(LOG_WARNING, "Unable to create channel for %s@%s\n", l->name, d->name);
05982          }
05983       }
05984    }
05985    return 1;
05986 }

static int handle_onhook_message ( struct skinny_req req,
struct skinnysession s 
) [static]

Definition at line 5988 of file chan_skinny.c.

References ast_channel::_state, skinny_device::activeline, skinny_line::activesub, AST_DEVICE_NOT_INUSE, ast_devstate_changed(), AST_STATE_RING, skinny_req::data, skinnysession::device, dumpsub(), find_subchannel_by_instance_reference(), handle_transfer_button(), onhook_message::instance, letohl, skinny_subchannel::line, skinny_data::onhook, skinny_subchannel::owner, onhook_message::reference, SKINNY_ONHOOK, sub, transmit_definetimedate(), and skinny_subchannel::xferor.

Referenced by handle_message().

05989 {
05990    struct skinny_device *d = s->device;
05991    struct skinny_line *l;
05992    struct skinny_subchannel *sub;
05993    int instance;
05994    int reference;
05995 
05996    instance = letohl(req->data.onhook.instance);
05997    reference = letohl(req->data.onhook.reference);
05998 
05999    if (instance && reference) {
06000       sub = find_subchannel_by_instance_reference(d, instance, reference);
06001       if (!sub) {
06002          return 0;
06003       }
06004       l = sub->line;
06005    } else {
06006       l = d->activeline;
06007       sub = l->activesub;
06008       if (!sub) {
06009          return 0;
06010       }
06011    }
06012 
06013    if (d->hookstate == SKINNY_ONHOOK) {
06014       /* Something else already put us back on hook */
06015       /* Not ideal, but let's send updated time anyway, as it clears the display */
06016       transmit_definetimedate(d);
06017       return 0;
06018    }
06019 
06020    if (l->transfer && sub->xferor && sub->owner->_state >= AST_STATE_RING) {
06021       /* We're allowed to transfer, we have two active calls and
06022          we made at least one of the calls.  Let's try and transfer */
06023       handle_transfer_button(sub);
06024       return 0;
06025    }
06026    
06027    ast_devstate_changed(AST_DEVICE_NOT_INUSE, "Skinny/%s", l->name);
06028    
06029    dumpsub(sub, 0);
06030 
06031    d->hookstate = SKINNY_ONHOOK;
06032    
06033    /* Not ideal, but let's send updated time at onhook and offhook, as it clears the display */
06034    transmit_definetimedate(d);
06035 
06036    return 1;
06037 }

static int handle_open_receive_channel_ack_message ( struct skinny_req req,
struct skinnysession s 
) [static]

Definition at line 6228 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, open_receive_channel_ack_message_ip6::callReference, open_receive_channel_ack_message_ip4::callReference, skinny_line::cap, ast_format_list::cur_ms, skinny_req::data, skinnysession::device, find_subchannel_by_reference(), ast_format_list::format, open_receive_channel_ack_message_ip6::ipAddr, open_receive_channel_ack_message_ip4::ipAddr, letohl, skinny_subchannel::line, LOG_ERROR, skinny_data::openreceivechannelack_ip4, skinny_data::openreceivechannelack_ip6, skinny_device::ourip, open_receive_channel_ack_message_ip6::port, open_receive_channel_ack_message_ip4::port, skinny_subchannel::rtp, open_receive_channel_ack_message_ip6::status, open_receive_channel_ack_message_ip4::status, status, sub, and transmit_startmediatransmission().

Referenced by handle_message().

06229 {
06230    struct skinny_device *d = s->device;
06231    struct skinny_line *l;
06232    struct skinny_subchannel *sub;
06233    struct ast_format_list fmt;
06234    struct sockaddr_in sin = { 0, };
06235    struct sockaddr_in us = { 0, };
06236    struct ast_sockaddr sin_tmp;
06237    struct ast_sockaddr us_tmp;
06238    struct ast_format tmpfmt;
06239    uint32_t addr;
06240    int port;
06241    int status;
06242    int callid;
06243 
06244    status = (d->protocolversion<17)?letohl(req->data.openreceivechannelack_ip4.status):letohl(req->data.openreceivechannelack_ip6.status);
06245    if (status) {
06246       ast_log(LOG_ERROR, "Open Receive Channel Failure\n");
06247       return 0;
06248    }
06249    if (d->protocolversion<17) {
06250       addr = req->data.openreceivechannelack_ip4.ipAddr;
06251       port = letohl(req->data.openreceivechannelack_ip4.port);
06252       callid = letohl(req->data.openreceivechannelack_ip4.callReference);
06253    } else {
06254       memcpy(&addr, &req->data.openreceivechannelack_ip6.ipAddr, sizeof(addr));
06255       port = letohl(req->data.openreceivechannelack_ip6.port);
06256       callid = letohl(req->data.openreceivechannelack_ip6.callReference);
06257    }
06258 
06259    sin.sin_family = AF_INET;
06260    sin.sin_addr.s_addr = addr;
06261    sin.sin_port = htons(port);
06262 
06263    sub = find_subchannel_by_reference(d, callid);
06264 
06265    if (!sub) {
06266       ast_log(LOG_ERROR, "Open Receive Channel Failure - can't find sub for %d\n", callid);
06267       return 0;
06268    }
06269 
06270    l = sub->line;
06271 
06272    if (sub->rtp) {
06273       ast_sockaddr_from_sin(&sin_tmp, &sin);
06274       ast_rtp_instance_set_remote_address(sub->rtp, &sin_tmp);
06275       ast_rtp_instance_get_local_address(sub->rtp, &us_tmp);
06276       ast_sockaddr_to_sin(&us_tmp, &us);
06277       us.sin_addr.s_addr = us.sin_addr.s_addr ? us.sin_addr.s_addr : d->ourip.s_addr;
06278    } else {
06279       ast_log(LOG_ERROR, "No RTP structure, this is very bad\n");
06280       return 0;
06281    }
06282 
06283    if (skinnydebug) {
06284       ast_verb(1, "device ipaddr = %s:%d\n", ast_inet_ntoa(sin.sin_addr), ntohs(sin.sin_port));
06285       ast_verb(1, "asterisk ipaddr = %s:%d\n", ast_inet_ntoa(us.sin_addr), ntohs(us.sin_port));
06286    }
06287    ast_best_codec(l->cap, &tmpfmt);
06288    fmt = ast_codec_pref_getsize(&l->prefs, &tmpfmt);
06289 
06290    if (skinnydebug)
06291       ast_verb(1, "Setting payloadType to '%s' (%d ms)\n", ast_getformatname(&fmt.format), fmt.cur_ms);
06292 
06293    transmit_startmediatransmission(d, sub, us, fmt);
06294 
06295    return 1;
06296 }

static char* handle_skinny_reload ( struct ast_cli_entry e,
int  cmd,
struct ast_cli_args a 
) [static]

Definition at line 3373 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.

03374 {
03375    switch (cmd) {
03376    case CLI_INIT:
03377       e->command = "skinny reload";
03378       e->usage =
03379          "Usage: skinny reload\n"
03380          "       Reloads the chan_skinny configuration\n";
03381       return NULL;
03382    case CLI_GENERATE:
03383       return NULL;
03384    }
03385    
03386    if (a->argc != e->args)
03387       return CLI_SHOWUSAGE;
03388 
03389    skinny_reload();
03390    return CLI_SUCCESS;
03391 
03392 }

static char* handle_skinny_reset ( struct ast_cli_entry e,
int  cmd,
struct ast_cli_args a 
) [static]

Definition at line 3438 of file chan_skinny.c.

References ast_cli_args::argc, ast_cli_args::argv, AST_LIST_LOCK, AST_LIST_TRAVERSE, AST_LIST_UNLOCK, CLI_GENERATE, CLI_INIT, CLI_SHOWUSAGE, CLI_SUCCESS, ast_cli_entry::command, complete_skinny_reset(), ast_cli_args::line, ast_cli_args::n, ast_cli_args::pos, skinny_device::session, transmit_reset(), ast_cli_entry::usage, and ast_cli_args::word.

03439 {
03440    struct skinny_device *d;
03441 
03442    switch (cmd) {
03443    case CLI_INIT:
03444       e->command = "skinny reset";
03445       e->usage =
03446          "Usage: skinny reset <DeviceId|DeviceName|all> [restart]\n"
03447          "       Causes a Skinny device to reset itself, optionally with a full restart\n";
03448       return NULL;
03449    case CLI_GENERATE:
03450       return complete_skinny_reset(a->line, a->word, a->pos, a->n);
03451    }
03452 
03453    if (a->argc < 3 || a->argc > 4)
03454       return CLI_SHOWUSAGE;
03455 
03456    AST_LIST_LOCK(&devices);
03457    AST_LIST_TRAVERSE(&devices, d, list) {
03458       int fullrestart = 0;
03459       if (!strcasecmp(a->argv[2], d->id) || !strcasecmp(a->argv[2], d->name) || !strcasecmp(a->argv[2], "all")) {
03460          if (!(d->session))
03461             continue;
03462 
03463          if (a->argc == 4 && !strcasecmp(a->argv[3], "restart"))
03464             fullrestart = 1;
03465          
03466          transmit_reset(d, fullrestart);
03467       }
03468    }
03469    AST_LIST_UNLOCK(&devices);
03470    return CLI_SUCCESS;
03471 }

static char* handle_skinny_set_debug ( struct ast_cli_entry e,
int  cmd,
struct ast_cli_args a 
) [static]

Definition at line 3331 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.

03332 {
03333    switch (cmd) {
03334    case CLI_INIT:
03335 #ifdef SKINNY_DEVMODE
03336       e->command = "skinny set debug {off|on|packet}";
03337       e->usage =
03338          "Usage: skinny set debug {off|on|packet}\n"
03339          "       Enables/Disables dumping of Skinny packets for debugging purposes\n";
03340 #else
03341       e->command = "skinny set debug {off|on}";
03342       e->usage =
03343          "Usage: skinny set debug {off|on}\n"
03344          "       Enables/Disables dumping of Skinny packets for debugging purposes\n";
03345 #endif
03346       return NULL;
03347    case CLI_GENERATE:
03348       return NULL;
03349    }
03350    
03351    if (a->argc != e->args)
03352       return CLI_SHOWUSAGE;
03353 
03354    if (!strncasecmp(a->argv[e->args - 1], "on", 2)) {
03355       skinnydebug = 1;
03356       ast_cli(a->fd, "Skinny Debugging Enabled\n");
03357       return CLI_SUCCESS;
03358    } else if (!strncasecmp(a->argv[e->args - 1], "off", 3)) {
03359       skinnydebug = 0;
03360       ast_cli(a->fd, "Skinny Debugging Disabled\n");
03361       return CLI_SUCCESS;
03362 #ifdef SKINNY_DEVMODE
03363    } else if (!strncasecmp(a->argv[e->args - 1], "packet", 6)) {
03364       skinnydebug = 2;
03365       ast_cli(a->fd, "Skinny Debugging Enabled including Packets\n");
03366       return CLI_SUCCESS;
03367 #endif
03368    } else {
03369       return CLI_SHOWUSAGE;
03370    }
03371 }

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 3809 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.

03810 {
03811    switch (cmd) {
03812    case CLI_INIT:
03813       e->command = "skinny show device";
03814       e->usage =
03815          "Usage: skinny show device <DeviceId|DeviceName>\n"
03816          "       Lists all deviceinformation of a specific device known to the Skinny subsystem.\n";
03817       return NULL;
03818    case CLI_GENERATE:
03819       return complete_skinny_show_device(a->line, a->word, a->pos, a->n);
03820    }
03821 
03822    return _skinny_show_device(0, a->fd, NULL, NULL, a->argc, (const char **) a->argv);
03823 }

static char* handle_skinny_show_devices ( struct ast_cli_entry e,
int  cmd,
struct ast_cli_args a 
) [static]

Definition at line 3675 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.

03676 {
03677 
03678    switch (cmd) {
03679    case CLI_INIT:
03680       e->command = "skinny show devices";
03681       e->usage =
03682          "Usage: skinny show devices\n"
03683          "       Lists all devices known to the Skinny subsystem.\n";
03684       return NULL;
03685    case CLI_GENERATE:
03686       return NULL;
03687    }
03688 
03689    return _skinny_show_devices(a->fd, NULL, NULL, NULL, a->argc, (const char **) a->argv);
03690 }

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 4110 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.

04111 {
04112    switch (cmd) {
04113    case CLI_INIT:
04114       e->command = "skinny show line";
04115       e->usage =
04116          "Usage: skinny show line <Line> [ on <DeviceID|DeviceName> ]\n"
04117          "       List all lineinformation of a specific line known to the Skinny subsystem.\n";
04118       return NULL;
04119    case CLI_GENERATE:
04120       return complete_skinny_show_line(a->line, a->word, a->pos, a->n);
04121    }
04122 
04123    return _skinny_show_line(0, a->fd, NULL, NULL, a->argc, (const char **) a->argv);
04124 }

static char* handle_skinny_show_lines ( struct ast_cli_entry e,
int  cmd,
struct ast_cli_args a 
) [static]

Definition at line 3923 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.

03924 {
03925    switch (cmd) {
03926    case CLI_INIT:
03927       e->command = "skinny show lines [verbose]";
03928       e->usage =
03929          "Usage: skinny show lines\n"
03930          "       Lists all lines known to the Skinny subsystem.\n"
03931          "       If 'verbose' is specified, the output includes\n"
03932          "       information about subs for each line.\n";
03933       return NULL;
03934    case CLI_GENERATE:
03935       return NULL;
03936    }
03937 
03938    if (a->argc == e->args) {
03939       if (strcasecmp(a->argv[e->args-1], "verbose")) {
03940          return CLI_SHOWUSAGE;
03941       }
03942    } else if (a->argc != e->args - 1) {
03943       return CLI_SHOWUSAGE;
03944    }
03945 
03946    return _skinny_show_lines(a->fd, NULL, NULL, NULL, a->argc, (const char **) a->argv);
03947 }

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 4127 of file chan_skinny.c.

References ast_cli_args::argc, ast_cli(), AST_CLI_YESNO, ast_inet_ntoa(), AST_JB_ENABLED, AST_JB_FORCED, AST_JB_LOG, ast_test_flag, bindaddr, CLI_GENERATE, CLI_INIT, CLI_SHOWUSAGE, CLI_SUCCESS, ast_cli_entry::command, ast_cli_args::fd, global_jbconf, ast_jb_conf::impl, ast_jb_conf::max_size, ast_jb_conf::resync_threshold, S_OR, ast_jb_conf::target_extra, and ast_cli_entry::usage.

04128 {
04129    switch (cmd) {
04130    case CLI_INIT:
04131       e->command = "skinny show settings";
04132       e->usage =
04133          "Usage: skinny show settings\n"
04134          "       Lists all global configuration settings of the Skinny subsystem.\n";
04135       return NULL;
04136    case CLI_GENERATE:
04137       return NULL;
04138    }  
04139 
04140    if (a->argc != 3)
04141       return CLI_SHOWUSAGE;
04142 
04143    ast_cli(a->fd, "\nGlobal Settings:\n");
04144    ast_cli(a->fd, "  Skinny Port:            %d\n", ntohs(bindaddr.sin_port));
04145    ast_cli(a->fd, "  Bindaddress:            %s\n", ast_inet_ntoa(bindaddr.sin_addr));
04146    ast_cli(a->fd, "  KeepAlive:              %d\n", keep_alive);
04147    ast_cli(a->fd, "  Date Format:            %s\n", date_format);
04148    ast_cli(a->fd, "  Voice Mail Extension:   %s\n", S_OR(global_vmexten, "(not set)"));
04149    ast_cli(a->fd, "  Reg. context:           %s\n", S_OR(regcontext, "(not set)"));
04150    ast_cli(a->fd, "  Jitterbuffer enabled:   %s\n", AST_CLI_YESNO(ast_test_flag(&global_jbconf, AST_JB_ENABLED)));
04151     if (ast_test_flag(&global_jbconf, AST_JB_ENABLED)) {
04152       ast_cli(a->fd, "  Jitterbuffer forced:    %s\n", AST_CLI_YESNO(ast_test_flag(&global_jbconf, AST_JB_FORCED)));
04153       ast_cli(a->fd, "  Jitterbuffer max size:  %ld\n", global_jbconf.max_size);
04154       ast_cli(a->fd, "  Jitterbuffer resync:    %ld\n", global_jbconf.resync_threshold);
04155       ast_cli(a->fd, "  Jitterbuffer impl:      %s\n", global_jbconf.impl);
04156       if (!strcasecmp(global_jbconf.impl, "adaptive")) {
04157          ast_cli(a->fd, "  Jitterbuffer tgt extra: %ld\n", global_jbconf.target_extra);
04158       }
04159       ast_cli(a->fd, "  Jitterbuffer log:       %s\n", AST_CLI_YESNO(ast_test_flag(&global_jbconf, AST_JB_LOG)));
04160    }
04161 
04162    return CLI_SUCCESS;
04163 }

static int handle_soft_key_event_message ( struct skinny_req req,
struct skinnysession s 
) [static]

Definition at line 6334 of file chan_skinny.c.

References ast_channel::_state, activatesub(), skinny_line::activesub, ast_bridged_channel(), AST_DEVICE_INUSE, AST_DEVICE_NOT_INUSE, ast_devstate_changed(), ast_log(), ast_masq_park_call(), AST_STATE_DOWN, AST_STATE_RING, AST_STATE_UP, ast_strlen_zero(), ast_verb, skinny_subchannel::calldirection, soft_key_event_message::callreference, skinny_req::data, skinnysession::device, dialandactivatesub(), dumpsub(), skinny_subline::exten, find_line_by_instance(), find_subchannel_by_instance_reference(), find_subline_by_callid(), handle_callforward_button(), handle_transfer_button(), soft_key_event_message::instance, letohl, LOG_WARNING, skinny_subchannel::owner, setsubstate(), SKINNY_CFWD_ALL, SKINNY_CFWD_BUSY, SKINNY_CFWD_NOANSWER, SKINNY_INCOMING, SKINNY_LAMP_OFF, SKINNY_LAMP_ON, skinny_new(), SKINNY_OFFHOOK, SKINNY_ONHOOK, SKINNY_OUTGOING, SKINNY_RING_OFF, SKINNY_SPEAKERON, 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, STIMULUS_DND, STIMULUS_LINE, skinny_subline::sub, sub, SUBSTATE_CONNECTED, SUBSTATE_HOLD, SUBSTATE_OFFHOOK, ast_channel::tech_pvt, transmit_definetimedate(), transmit_displaynotify(), transmit_lamp_indication(), transmit_ringer_mode(), transmit_speaker_mode(), and skinny_subchannel::xferor.

Referenced by handle_message().

06335 {
06336    struct skinny_device *d = s->device;
06337    struct skinny_line *l;
06338    struct skinny_subchannel *sub = NULL;
06339    struct ast_channel *c;
06340    int event;
06341    int instance;
06342    int callreference;
06343 
06344    event = letohl(req->data.softkeyeventmessage.softKeyEvent);
06345    instance = letohl(req->data.softkeyeventmessage.instance);
06346    callreference = letohl(req->data.softkeyeventmessage.callreference);
06347 
06348    if (instance) {
06349       l = find_line_by_instance(d, instance);
06350       if (callreference) {
06351          sub = find_subchannel_by_instance_reference(d, instance, callreference);
06352       } else {
06353          sub = find_subchannel_by_instance_reference(d, instance, d->lastcallreference);
06354       }
06355    } else {
06356       l = find_line_by_instance(d, d->lastlineinstance);
06357    }
06358 
06359    if (!l) {
06360       if (skinnydebug)
06361          ast_verb(1, "Received Softkey Event: %d(%d/%d)\n", event, instance, callreference);
06362       return 0;
06363    }
06364 
06365    ast_devstate_changed(AST_DEVICE_INUSE, "Skinny/%s", l->name);
06366 
06367    switch(event) {
06368    case SOFTKEY_NONE:
06369       if (skinnydebug)
06370          ast_verb(1, "Received Softkey Event: None(%d/%d)\n", instance, callreference);
06371       break;
06372    case SOFTKEY_REDIAL:
06373       if (skinnydebug)
06374          ast_verb(1, "Received Softkey Event: Redial(%d/%d)\n", instance, callreference);
06375 
06376       if (ast_strlen_zero(l->lastnumberdialed)) {
06377          ast_log(LOG_WARNING, "Attempted redial, but no previously dialed number found. Ignoring button.\n");
06378          break;
06379       }
06380 
06381       if (!sub || !sub->owner) {
06382          c = skinny_new(l, NULL, AST_STATE_DOWN, NULL, SKINNY_OUTGOING);
06383       } else {
06384          c = sub->owner;
06385       }
06386 
06387       if (!c) {
06388          ast_log(LOG_WARNING, "Unable to create channel for %s@%s\n", l->name, d->name);
06389       } else {
06390          sub = c->tech_pvt;
06391          dialandactivatesub(sub, l->lastnumberdialed);
06392       }
06393       break;
06394    case SOFTKEY_NEWCALL:  /* Actually the DIAL softkey */
06395       if (skinnydebug)
06396          ast_verb(1, "Received Softkey Event: New Call(%d/%d)\n", instance, callreference);
06397 
06398       /* New Call ALWAYS gets a new sub-channel */
06399       c = skinny_new(l, NULL, AST_STATE_DOWN, NULL, SKINNY_OUTGOING);
06400       sub = c->tech_pvt;
06401 
06402       if (!c) {
06403          ast_log(LOG_WARNING, "Unable to create channel for %s@%s\n", l->name, d->name);
06404       } else {
06405          activatesub(sub, SUBSTATE_OFFHOOK);
06406       }
06407       break;
06408    case SOFTKEY_HOLD:
06409       if (skinnydebug)
06410          ast_verb(1, "Received Softkey Event: Hold(%d/%d)\n", instance, callreference);
06411       
06412       if (sub) {
06413          setsubstate(sub, SUBSTATE_HOLD); 
06414       } else { /* No sub, maybe an SLA call */
06415          struct skinny_subline *subline;
06416          if ((subline = find_subline_by_callid(d, callreference))) {
06417             setsubstate(subline->sub, SUBSTATE_HOLD); 
06418          }
06419       }
06420 
06421       break;
06422    case SOFTKEY_TRNSFER:
06423       if (skinnydebug)
06424          ast_verb(1, "Received Softkey Event: Transfer(%d/%d)\n", instance, callreference);
06425       if (l->transfer)
06426          handle_transfer_button(sub);
06427       else
06428          transmit_displaynotify(d, "Transfer disabled", 10);
06429 
06430       break;
06431    case SOFTKEY_DND:
06432       if (skinnydebug)
06433          ast_verb(1, "Received Softkey Event: DND(%d/%d)\n", instance, callreference);
06434 
06435       /* Do not disturb */
06436       if (l->dnd != 0){
06437          ast_verb(3, "Disabling DND on %s@%s\n", l->name, d->name);
06438          l->dnd = 0;
06439          transmit_lamp_indication(d, STIMULUS_DND, 1, SKINNY_LAMP_ON);
06440          transmit_displaynotify(d, "DnD disabled", 10);
06441       } else {
06442          ast_verb(3, "Enabling DND on %s@%s\n", l->name, d->name);
06443          l->dnd = 1;
06444          transmit_lamp_indication(d, STIMULUS_DND, 1, SKINNY_LAMP_OFF);
06445          transmit_displaynotify(d, "DnD enabled", 10);
06446       }
06447       break;
06448    case SOFTKEY_CFWDALL:
06449       if (skinnydebug)
06450          ast_verb(1, "Received Softkey Event: Forward All(%d/%d)\n", instance, callreference);
06451 
06452       if (!sub || !sub->owner) {
06453          c = skinny_new(l, NULL, AST_STATE_DOWN, NULL, SKINNY_OUTGOING);
06454       } else {
06455          c = sub->owner;
06456       }
06457 
06458       if (!c) {
06459          ast_log(LOG_WARNING, "Unable to create channel for %s@%s\n", l->name, d->name);
06460       } else {
06461          sub = c->tech_pvt;
06462          l->activesub = sub;
06463          handle_callforward_button(sub, SKINNY_CFWD_ALL);
06464       }
06465       break;
06466    case SOFTKEY_CFWDBUSY:
06467       if (skinnydebug)
06468          ast_verb(1, "Received Softkey Event: Forward Busy (%d/%d)\n", instance, callreference);
06469 
06470       if (!sub || !sub->owner) {
06471          c = skinny_new(l, NULL, AST_STATE_DOWN, NULL, SKINNY_OUTGOING);
06472       } else {
06473          c = sub->owner;
06474       }
06475 
06476       if (!c) {
06477          ast_log(LOG_WARNING, "Unable to create channel for %s@%s\n", l->name, d->name);
06478       } else {
06479          sub = c->tech_pvt;
06480          l->activesub = sub;
06481          handle_callforward_button(sub, SKINNY_CFWD_BUSY);
06482       }
06483       break;
06484    case SOFTKEY_CFWDNOANSWER:
06485       if (skinnydebug)
06486          ast_verb(1, "Received Softkey Event: Forward No Answer (%d/%d)\n", instance, callreference);
06487 
06488 #if 0 /* Not sure how to handle this yet */
06489       if (!sub || !sub->owner) {
06490          c = skinny_new(l, NULL, AST_STATE_DOWN, NULL, SKINNY_OUTGOING);
06491       } else {
06492          c = sub->owner;
06493       }
06494 
06495       if (!c) {
06496          ast_log(LOG_WARNING, "Unable to create channel for %s@%s\n", l->name, d->name);
06497       } else {
06498          sub = c->tech_pvt;
06499          l->activesub = sub;
06500          handle_callforward_button(sub, SKINNY_CFWD_NOANSWER);
06501       }
06502 #endif
06503       break;
06504    case SOFTKEY_BKSPC:
06505       if (skinnydebug)
06506          ast_verb(1, "Received Softkey Event: Backspace(%d/%d)\n", instance, callreference);
06507       break;
06508    case SOFTKEY_ENDCALL:
06509       if (skinnydebug)
06510          ast_verb(1, "Received Softkey Event: End Call(%d/%d)\n", instance, callreference);
06511 
06512       if (l->transfer && sub && sub->xferor && sub->owner->_state >= AST_STATE_RING) {
06513          /* We're allowed to transfer, we have two active calls and
06514              we made at least one of the calls.  Let's try and transfer */
06515          handle_transfer_button(sub);
06516          return 0;
06517       }
06518    
06519       ast_devstate_changed(AST_DEVICE_NOT_INUSE, "Skinny/%s", l->name);
06520    
06521       if (sub) {
06522          dumpsub(sub, 1);
06523       } else { /* No sub, maybe an SLA call */
06524          struct skinny_subline *subline;
06525          if ((subline = find_subline_by_callid(d, callreference))) {
06526             dumpsub(subline->sub, 1);
06527          }
06528       }
06529 
06530       d->hookstate = SKINNY_ONHOOK;
06531    
06532       /* Not ideal, but let's send updated time at onhook and offhook, as it clears the display */
06533       transmit_definetimedate(d);
06534 
06535       break;
06536    case SOFTKEY_RESUME:
06537       if (skinnydebug)
06538          ast_verb(1, "Received Softkey Event: Resume(%d/%d)\n", instance, callreference);
06539       
06540       if (sub) {
06541          activatesub(sub, SUBSTATE_CONNECTED);
06542       } else { /* No sub, maybe an inactive SLA call */
06543          struct skinny_subline *subline;
06544          subline = find_subline_by_callid(d, callreference);
06545          c = skinny_new(l, subline, AST_STATE_DOWN, NULL, SKINNY_OUTGOING);
06546          if (!c) {
06547             ast_log(LOG_WARNING, "Unable to create channel for %s@%s\n", l->name, d->name);
06548          } else {
06549             sub = c->tech_pvt;
06550             dialandactivatesub(sub, subline->exten);
06551          }
06552       }
06553       break;
06554    case SOFTKEY_ANSWER:
06555       if (skinnydebug)
06556          ast_verb(1, "Received Softkey Event: Answer(%d/%d)\n", instance, callreference);
06557 
06558       transmit_ringer_mode(d, SKINNY_RING_OFF);
06559       transmit_lamp_indication(d, STIMULUS_LINE, l->instance, SKINNY_LAMP_ON);
06560       if (d->hookstate == SKINNY_ONHOOK) {
06561          transmit_speaker_mode(d, SKINNY_SPEAKERON);
06562          d->hookstate = SKINNY_OFFHOOK;
06563       }
06564 
06565       if (sub && sub->calldirection == SKINNY_INCOMING) {
06566          activatesub(sub, SUBSTATE_CONNECTED);
06567       }
06568       break;
06569    case SOFTKEY_INFO:
06570       if (skinnydebug)
06571          ast_verb(1, "Received Softkey Event: Info(%d/%d)\n", instance, callreference);
06572       break;
06573    case SOFTKEY_CONFRN:
06574       if (skinnydebug)
06575          ast_verb(1, "Received Softkey Event: Conference(%d/%d)\n", instance, callreference);
06576       /* XXX determine the best way to pull off a conference.  Meetme? */
06577       break;
06578    case SOFTKEY_PARK:
06579       {
06580       int extout;
06581       char message[32];
06582 
06583       if (skinnydebug)
06584          ast_verb(1, "Received Softkey Event: Park Call(%d/%d)\n", instance, callreference);
06585 
06586       if ((sub && sub->owner) && (sub->owner->_state ==  AST_STATE_UP)){
06587          c = sub->owner;
06588          if (ast_bridged_channel(c)) {
06589             if (!ast_masq_park_call(ast_bridged_channel(c), c, 0, &extout)) {
06590                snprintf(message, sizeof(message), "Call Parked at: %d", extout);
06591                transmit_displaynotify(d, message, 10);
06592             } else {
06593                transmit_displaynotify(d, "Call Park failed", 10);
06594             }
06595          } else {
06596             transmit_displaynotify(d, "Call Park not available", 10);
06597          }
06598       } else {
06599          transmit_displaynotify(d, "Call Park not available", 10);
06600       }
06601       break;
06602       }
06603    case SOFTKEY_JOIN:
06604       if (skinnydebug)
06605          ast_verb(1, "Received Softkey Event: Join(%d/%d)\n", instance, callreference);
06606       /* this is SLA territory, should not get here unless there is a meetme at subline */
06607       {
06608          struct skinny_subline *subline;
06609          subline = find_subline_by_callid(d, callreference);
06610          c = skinny_new(l, subline, AST_STATE_DOWN, NULL, SKINNY_OUTGOING);
06611          if (!c) {
06612             ast_log(LOG_WARNING, "Unable to create channel for %s@%s\n", l->name, d->name);
06613          } else {
06614             sub = c->tech_pvt;
06615             dialandactivatesub(sub, subline->exten);
06616          }
06617       }
06618       break;
06619    case SOFTKEY_MEETME:
06620       /* XXX How is this different from CONFRN? */
06621       if (skinnydebug)
06622          ast_verb(1, "Received Softkey Event: Meetme(%d/%d)\n", instance, callreference);
06623       break;
06624    case SOFTKEY_PICKUP:
06625       if (skinnydebug)
06626          ast_verb(1, "Received Softkey Event: Pickup(%d/%d)\n", instance, callreference);
06627       break;
06628    case SOFTKEY_GPICKUP:
06629       if (skinnydebug)
06630          ast_verb(1, "Received Softkey Event: Group Pickup(%d/%d)\n", instance, callreference);
06631       break;
06632    default:
06633       if (skinnydebug)
06634          ast_verb(1, "Received unknown Softkey Event: %d(%d/%d)\n", event, instance, callreference);
06635       break;
06636    }
06637 
06638    return 1;
06639 }

static int handle_stimulus_message ( struct skinny_req req,
struct skinnysession s 
) [static]

Definition at line 5665 of file chan_skinny.c.

References ast_channel::_state, skinny_device::activeline, skinny_line::activesub, ast_bridged_channel(), ast_channel_name(), ast_debug, AST_DEVICE_UNKNOWN, ast_devstate_changed(), ast_log(), ast_masq_park_call(), AST_STATE_DOWN, AST_STATE_UP, ast_strlen_zero(), ast_verb, skinny_subchannel::calldirection, stimulus_message::callreference, skinny_req::data, skinnysession::device, dialandactivatesub(), skinny_speeddial::exten, find_line_by_instance(), find_speeddial_by_instance(), find_subchannel_by_instance_reference(), handle_callforward_button(), handle_hold_button(), handle_transfer_button(), letohl, skinny_subchannel::line, LOG_WARNING, skinny_subchannel::owner, setsubstate(), SKINNY_CFWD_ALL, SKINNY_CFWD_BUSY, SKINNY_CFWD_NOANSWER, SKINNY_INCOMING, SKINNY_LAMP_OFF, SKINNY_LAMP_ON, skinny_new(), SKINNY_OFFHOOK, SKINNY_OUTGOING, SKINNY_RING_OFF, SKINNY_SPEAKERON, 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, sub, skinny_subchannel::substate, SUBSTATE_CONNECTED, SUBSTATE_OFFHOOK, SUBSTATE_UNSET, ast_channel::tech_pvt, transmit_displaynotify(), transmit_lamp_indication(), transmit_ringer_mode(), and transmit_speaker_mode().

Referenced by handle_message().

05666 {
05667    struct skinny_device *d = s->device;
05668    struct skinny_line *l;
05669    struct skinny_subchannel *sub;
05670    /*struct skinny_speeddial *sd;*/
05671    struct ast_channel *c;
05672    int event;
05673    int instance;
05674    int callreference;
05675    /*int res = 0;*/
05676 
05677    event = letohl(req->data.stimulus.stimulus);
05678    instance = letohl(req->data.stimulus.stimulusInstance);
05679    callreference = letohl(req->data.stimulus.callreference); 
05680    if (skinnydebug)
05681       ast_verb(1, "callreference in handle_stimulus_message is '%d'\n", callreference);
05682 
05683    /*  Note that this call should be using the passed in instance and callreference */
05684    sub = find_subchannel_by_instance_reference(d, d->lastlineinstance, d->lastcallreference);
05685 
05686    if (!sub) {
05687       l = find_line_by_instance(d, d->lastlineinstance);
05688       if (!l) {
05689          return 0;
05690       }
05691       sub = l->activesub;
05692    } else {
05693       l = sub->line;
05694    }
05695 
05696    switch(event) {
05697    case STIMULUS_REDIAL:
05698       if (skinnydebug)
05699          ast_verb(1, "Received Stimulus: Redial(%d/%d)\n", instance, callreference);
05700 
05701       if (ast_strlen_zero(l->lastnumberdialed)) {
05702          ast_log(LOG_WARNING, "Attempted redial, but no previously dialed number found. Ignoring button.\n");
05703          break;
05704       }
05705 
05706       c = skinny_new(l, NULL, AST_STATE_DOWN, NULL, SKINNY_OUTGOING);
05707       if (!c) {
05708          ast_log(LOG_WARNING, "Unable to create channel for %s@%s\n", l->name, d->name);
05709       } else {
05710          sub = c->tech_pvt;
05711          l = sub->line;
05712          dialandactivatesub(sub, l->lastnumberdialed);
05713       }
05714       break;
05715    case STIMULUS_SPEEDDIAL:
05716        {
05717       struct skinny_speeddial *sd;
05718 
05719       if (skinnydebug)
05720          ast_verb(1, "Received Stimulus: SpeedDial(%d/%d)\n", instance, callreference);
05721       if (!(sd = find_speeddial_by_instance(d, instance, 0))) {
05722          return 0;
05723       }
05724 
05725       if (!sub || !sub->owner)
05726          c = skinny_new(l, NULL, AST_STATE_DOWN, NULL, SKINNY_OUTGOING);
05727       else
05728          c = sub->owner;
05729 
05730       if (!c) {
05731          ast_log(LOG_WARNING, "Unable to create channel for %s@%s\n", l->name, d->name);
05732       } else {
05733          sub = c->tech_pvt;
05734          dialandactivatesub(sub, sd->exten);
05735       }
05736        }
05737       break;
05738    case STIMULUS_HOLD:
05739       if (skinnydebug)
05740          ast_verb(1, "Received Stimulus: Hold(%d/%d)\n", instance, callreference);
05741       handle_hold_button(sub);
05742       break;
05743    case STIMULUS_TRANSFER:
05744       if (skinnydebug)
05745          ast_verb(1, "Received Stimulus: Transfer(%d/%d)\n", instance, callreference);
05746       if (l->transfer)
05747          handle_transfer_button(sub);
05748       else
05749          transmit_displaynotify(d, "Transfer disabled", 10);
05750       break;
05751    case STIMULUS_CONFERENCE:
05752       if (skinnydebug)
05753          ast_verb(1, "Received Stimulus: Conference(%d/%d)\n", instance, callreference);
05754       /* XXX determine the best way to pull off a conference.  Meetme? */
05755       break;
05756    case STIMULUS_VOICEMAIL:
05757       if (skinnydebug) {
05758          ast_verb(1, "Received Stimulus: Voicemail(%d/%d)\n", instance, callreference);
05759       }
05760 
05761       if (!sub || !sub->owner) {
05762          c = skinny_new(l, NULL, AST_STATE_DOWN, NULL, SKINNY_OUTGOING);
05763       } else {
05764          c = sub->owner;
05765       }
05766       
05767       if (!c) {
05768          ast_log(LOG_WARNING, "Unable to create channel for %s@%s\n", l->name, d->name);
05769          break;
05770       }
05771       
05772       sub = c->tech_pvt;
05773       if (sub->substate == SUBSTATE_UNSET || sub->substate == SUBSTATE_OFFHOOK){
05774          dialandactivatesub(sub, l->vmexten);
05775       }
05776       break;
05777    case STIMULUS_CALLPARK:
05778       {
05779       int extout;
05780       char message[32];
05781 
05782       if (skinnydebug)
05783          ast_verb(1, "Received Stimulus: Park Call(%d/%d)\n", instance, callreference);
05784 
05785       if ((sub && sub->owner) && (sub->owner->_state ==  AST_STATE_UP)){
05786          c = sub->owner;
05787          if (ast_bridged_channel(c)) {
05788             if (!ast_masq_park_call(ast_bridged_channel(c), c, 0, &extout)) {
05789                snprintf(message, sizeof(message), "Call Parked at: %d", extout);
05790                transmit_displaynotify(d, message, 10);
05791             } else {
05792                transmit_displaynotify(d, "Call Park failed", 10);
05793             }
05794          } else {
05795             transmit_displaynotify(d, "Call Park not available", 10);
05796          }
05797       } else {
05798          transmit_displaynotify(d, "Call Park not available", 10);
05799       }
05800       break;
05801       }
05802    case STIMULUS_DND:
05803       if (skinnydebug)
05804          ast_verb(1, "Received Stimulus: DND (%d/%d)\n", instance, callreference);
05805 
05806       /* Do not disturb */
05807       if (l->dnd != 0){
05808          ast_verb(3, "Disabling DND on %s@%s\n", l->name, d->name);
05809          l->dnd = 0;
05810          transmit_lamp_indication(d, STIMULUS_DND, 1, SKINNY_LAMP_ON);
05811          transmit_displaynotify(d, "DnD disabled", 10);
05812       } else {
05813          ast_verb(3, "Enabling DND on %s@%s\n", l->name, d->name);
05814          l->dnd = 1;
05815          transmit_lamp_indication(d, STIMULUS_DND, 1, SKINNY_LAMP_OFF);
05816          transmit_displaynotify(d, "DnD enabled", 10);
05817       }
05818       break;
05819    case STIMULUS_FORWARDALL:
05820       if (skinnydebug)
05821          ast_verb(1, "Received Stimulus: Forward All(%d/%d)\n", instance, callreference);
05822 
05823       if (!sub || !sub->owner) {
05824          c = skinny_new(l, NULL, AST_STATE_DOWN, NULL, SKINNY_OUTGOING);
05825       } else {
05826          c = sub->owner;
05827       }
05828 
05829       if (!c) {
05830          ast_log(LOG_WARNING, "Unable to create channel for %s@%s\n", l->name, d->name);
05831       } else {
05832          sub = c->tech_pvt;
05833          handle_callforward_button(sub, SKINNY_CFWD_ALL);
05834       }
05835       break;
05836    case STIMULUS_FORWARDBUSY:
05837       if (skinnydebug)
05838          ast_verb(1, "Received Stimulus: Forward Busy (%d/%d)\n", instance, callreference);
05839 
05840       if (!sub || !sub->owner) {
05841          c = skinny_new(l, NULL, AST_STATE_DOWN, NULL, SKINNY_OUTGOING);
05842       } else {
05843          c = sub->owner;
05844       }
05845 
05846       if (!c) {
05847          ast_log(LOG_WARNING, "Unable to create channel for %s@%s\n", l->name, d->name);
05848       } else {
05849          sub = c->tech_pvt;
05850          handle_callforward_button(sub, SKINNY_CFWD_BUSY);
05851       }
05852       break;
05853    case STIMULUS_FORWARDNOANSWER:
05854       if (skinnydebug)
05855          ast_verb(1, "Received Stimulus: Forward No Answer (%d/%d)\n", instance, callreference);
05856 
05857 #if 0 /* Not sure how to handle this yet */
05858       if (!sub || !sub->owner) {
05859          c = skinny_new(l, NULL, AST_STATE_DOWN, NULL, SKINNY_OUTGOING);
05860       } else {
05861          c = sub->owner;
05862       }
05863 
05864       if (!c) {
05865          ast_log(LOG_WARNING, "Unable to create channel for %s@%s\n", l->name, d->name);
05866       } else {
05867          sub = c->tech_pvt;
05868          handle_callforward_button(sub, SKINNY_CFWD_NOANSWER);
05869       }
05870 #endif
05871       break;
05872    case STIMULUS_DISPLAY:
05873       /* Not sure what this is */
05874       if (skinnydebug)
05875          ast_verb(1, "Received Stimulus: Display(%d/%d)\n", instance, callreference);
05876       break;
05877    case STIMULUS_LINE:
05878       if (skinnydebug)
05879          ast_verb(1, "Received Stimulus: Line(%d/%d)\n", instance, callreference);
05880 
05881       l = find_line_by_instance(d, instance);
05882 
05883       if (!l) {
05884          return 0;
05885       }
05886 
05887       d->activeline = l;
05888 
05889       /* turn the speaker on */
05890       transmit_speaker_mode(d, SKINNY_SPEAKERON);
05891       transmit_ringer_mode(d, SKINNY_RING_OFF);
05892       transmit_lamp_indication(d, STIMULUS_LINE, l->instance, SKINNY_LAMP_ON);
05893 
05894       d->hookstate = SKINNY_OFFHOOK;
05895 
05896       if (sub && sub->calldirection == SKINNY_INCOMING) {
05897          setsubstate(sub, SUBSTATE_CONNECTED);
05898       } else {
05899          if (sub && sub->owner) {
05900             ast_debug(1, "Current subchannel [%s] already has owner\n", ast_channel_name(sub->owner));
05901          } else {
05902             c = skinny_new(l, NULL, AST_STATE_DOWN, NULL, SKINNY_OUTGOING);
05903             if (c) {
05904                setsubstate(c->tech_pvt, SUBSTATE_OFFHOOK);
05905             } else {
05906                ast_log(LOG_WARNING, "Unable to create channel for %s@%s\n", l->name, d->name);
05907             }
05908          }
05909       }
05910       break;
05911    default:
05912       if (skinnydebug)
05913          ast_verb(1, "RECEIVED UNKNOWN STIMULUS:  %d(%d/%d)\n", event, instance, callreference);
05914       break;
05915    }
05916    ast_devstate_changed(AST_DEVICE_UNKNOWN, "Skinny/%s", l->name);
05917 
05918    return 1;
05919 }

static int handle_transfer_button ( struct skinny_subchannel sub  )  [static]

Definition at line 5498 of file chan_skinny.c.

References ast_channel::_state, ast_log(), AST_STATE_DOWN, ast_verbose, skinny_subchannel::blindxfer, skinny_line::device, skinny_subchannel::line, LOG_WARNING, skinny_subchannel::owner, skinny_subchannel::related, setsubstate(), skinny_new(), SKINNY_OUTGOING, skinny_transfer(), skinny_subchannel::substate, SUBSTATE_HOLD, SUBSTATE_OFFHOOK, ast_channel::tech_pvt, and skinny_subchannel::xferor.

Referenced by handle_onhook_message(), handle_soft_key_event_message(), and handle_stimulus_message().

05499 {
05500    struct skinny_line *l;
05501    struct skinny_device *d;
05502    struct skinny_subchannel *newsub;
05503    struct ast_channel *c;
05504 
05505    if (!sub) {
05506       ast_verbose("Transfer: No subchannel to transfer\n");
05507       return -1;
05508    }
05509 
05510    l = sub->line;
05511    d = l->device;
05512 
05513    if (!sub->related) {
05514       /* Another sub has not been created so this must be first XFER press */
05515       if (!(sub->substate == SUBSTATE_HOLD)) {
05516          setsubstate(sub, SUBSTATE_HOLD);
05517       }
05518       c = skinny_new(l, NULL, AST_STATE_DOWN, NULL, SKINNY_OUTGOING);
05519       if (c) {
05520          newsub = c->tech_pvt;
05521          /* point the sub and newsub at each other so we know they are related */
05522          newsub->related = sub;
05523          sub->related = newsub;
05524          newsub->xferor = 1;
05525          setsubstate(newsub, SUBSTATE_OFFHOOK);
05526       } else {
05527          ast_log(LOG_WARNING, "Unable to create channel for %s@%s\n", l->name, d->name);
05528       }
05529    } else {
05530       /* We already have a related sub so we can either complete XFER or go into BLINDXFER (or cancel BLINDXFER */
05531       if (sub->blindxfer) {
05532          /* toggle blindxfer off */
05533          sub->blindxfer = 0;
05534          sub->related->blindxfer = 0;
05535          /* we really need some indications */
05536       } else {
05537          /* We were doing attended transfer */
05538          if (sub->owner->_state == AST_STATE_DOWN || sub->related->owner->_state == AST_STATE_DOWN) {
05539             /* one of the subs so we cant transfer yet, toggle blindxfer on */
05540             sub->blindxfer = 1;
05541             sub->related->blindxfer = 1;
05542          } else {
05543             /* big assumption we have two channels, lets transfer */
05544             skinny_transfer(sub);
05545          }
05546       }
05547    }
05548    return 0;
05549 }

static int load_module ( void   )  [static]

Definition at line 7961 of file chan_skinny.c.

References ARRAY_LEN, ast_channel_register(), ast_cli_register_multiple(), AST_FORMAT_ALAW, ast_format_cap_add(), ast_format_cap_add_all_by_type(), ast_format_cap_alloc(), ast_format_set(), AST_FORMAT_TYPE_AUDIO, AST_FORMAT_ULAW, ast_log(), ast_manager_register_xml, AST_MODULE_LOAD_DECLINE, AST_MODULE_LOAD_FAILURE, AST_MODULE_LOAD_SUCCESS, ast_rtp_glue_register, ast_sched_context_create(), ast_sched_context_destroy(), ast_sched_start_thread(), ast_channel_tech::capabilities, cli_skinny, config_load(), EVENT_FLAG_REPORTING, EVENT_FLAG_SYSTEM, htolel, LOG_ERROR, LOG_WARNING, manager_skinny_show_device(), manager_skinny_show_devices(), manager_skinny_show_line(), manager_skinny_show_lines(), skinny_req::res, skinny_rtp_glue, skinny_tech, and soft_key_template_definition::softKeyEvent.

07962 {
07963    int res = 0;
07964    struct ast_format tmpfmt;
07965    if (!(default_cap = ast_format_cap_alloc())) {
07966       return AST_MODULE_LOAD_DECLINE;
07967    }
07968    if (!(skinny_tech.capabilities = ast_format_cap_alloc())) {
07969       return AST_MODULE_LOAD_DECLINE;
07970    }
07971 
07972    ast_format_cap_add_all_by_type(skinny_tech.capabilities, AST_FORMAT_TYPE_AUDIO);
07973    ast_format_cap_add(default_cap, ast_format_set(&tmpfmt, AST_FORMAT_ULAW, 0));
07974    ast_format_cap_add(default_cap, ast_format_set(&tmpfmt, AST_FORMAT_ALAW, 0));
07975 
07976    for (; res < ARRAY_LEN(soft_key_template_default); res++) {
07977       soft_key_template_default[res].softKeyEvent = htolel(soft_key_template_default[res].softKeyEvent);
07978    }
07979    /* load and parse config */
07980    res = config_load();
07981    if (res == -1) {
07982       return AST_MODULE_LOAD_DECLINE;
07983    }
07984 
07985    /* Make sure we can register our skinny channel type */
07986    if (ast_channel_register(&skinny_tech)) {
07987       ast_log(LOG_ERROR, "Unable to register channel class 'Skinny'\n");
07988       return -1;
07989    }
07990 
07991    ast_rtp_glue_register(&skinny_rtp_glue);
07992    ast_cli_register_multiple(cli_skinny, ARRAY_LEN(cli_skinny));
07993 
07994    ast_manager_register_xml("SKINNYdevices", EVENT_FLAG_SYSTEM | EVENT_FLAG_REPORTING, manager_skinny_show_devices);
07995    ast_manager_register_xml("SKINNYshowdevice", EVENT_FLAG_SYSTEM | EVENT_FLAG_REPORTING, manager_skinny_show_device);
07996    ast_manager_register_xml("SKINNYlines", EVENT_FLAG_SYSTEM | EVENT_FLAG_REPORTING, manager_skinny_show_lines);
07997    ast_manager_register_xml("SKINNYshowline", EVENT_FLAG_SYSTEM | EVENT_FLAG_REPORTING, manager_skinny_show_line);
07998 
07999    sched = ast_sched_context_create();
08000    if (!sched) {
08001       ast_log(LOG_WARNING, "Unable to create schedule context\n");
08002       return AST_MODULE_LOAD_FAILURE;
08003    }
08004    if (ast_sched_start_thread(sched)) {
08005       ast_sched_context_destroy(sched);
08006       sched = NULL;
08007       return AST_MODULE_LOAD_FAILURE;
08008    }
08009 
08010    return AST_MODULE_LOAD_SUCCESS;
08011 }

static int manager_skinny_show_device ( struct mansession s,
const struct message m 
) [static]

Definition at line 3788 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().

03789 {
03790    const char *a[4];
03791    const char *device;
03792 
03793    device = astman_get_header(m, "Device");
03794    if (ast_strlen_zero(device)) {
03795       astman_send_error(s, m, "Device: <name> missing.");
03796       return 0;
03797    }
03798    a[0] = "skinny";
03799    a[1] = "show";
03800    a[2] = "device";
03801    a[3] = device;
03802 
03803    _skinny_show_device(1, -1, s, m, 4, a);
03804    astman_append(s, "\r\n\r\n" );
03805    return 0;
03806 }

static int manager_skinny_show_devices ( struct mansession s,
const struct message m 
) [static]

Show SKINNY devices in the manager API.

Definition at line 3652 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().

03653 {
03654    const char *id = astman_get_header(m, "ActionID");
03655    const char *a[] = {"skinny", "show", "devices"};
03656    char idtext[256] = "";
03657    int total = 0;
03658 
03659    if (!ast_strlen_zero(id))
03660       snprintf(idtext, sizeof(idtext), "ActionID: %s\r\n", id);
03661 
03662    astman_send_listack(s, m, "Device status list will follow", "start");
03663    /* List the devices in separate manager events */
03664    _skinny_show_devices(-1, &total, s, m, 3, a);
03665    /* Send final confirmation */
03666    astman_append(s,
03667    "Event: DevicelistComplete\r\n"
03668    "EventList: Complete\r\n"
03669    "ListItems: %d\r\n"
03670    "%s"
03671    "\r\n", total, idtext);
03672    return 0;
03673 }

static int manager_skinny_show_line ( struct mansession s,
const struct message m 
) [static]

Definition at line 4089 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().

04090 {
04091    const char *a[4];
04092    const char *line;
04093 
04094    line = astman_get_header(m, "Line");
04095    if (ast_strlen_zero(line)) {
04096       astman_send_error(s, m, "Line: <name> missing.");
04097       return 0;
04098    }
04099    a[0] = "skinny";
04100    a[1] = "show";
04101    a[2] = "line";
04102    a[3] = line;
04103 
04104    _skinny_show_line(1, -1, s, m, 4, a);
04105    astman_append(s, "\r\n\r\n" );
04106    return 0;
04107 }

static int manager_skinny_show_lines ( struct mansession s,
const struct message m 
) [static]

Show Skinny lines in the manager API.

Definition at line 3900 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().

03901 {
03902    const char *id = astman_get_header(m, "ActionID");
03903    const char *a[] = {"skinny", "show", "lines"};
03904    char idtext[256] = "";
03905    int total = 0;
03906 
03907    if (!ast_strlen_zero(id))
03908       snprintf(idtext, sizeof(idtext), "ActionID: %s\r\n", id);
03909 
03910    astman_send_listack(s, m, "Line status list will follow", "start");
03911    /* List the lines in separate manager events */
03912    _skinny_show_lines(-1, &total, s, m, 3, a);
03913    /* Send final confirmation */
03914    astman_append(s,
03915    "Event: LinelistComplete\r\n"
03916    "EventList: Complete\r\n"
03917    "ListItems: %d\r\n"
03918    "%s"
03919    "\r\n", total, idtext);
03920    return 0;
03921 }

static char* message2str ( int  type  )  [static]

Definition at line 2184 of file chan_skinny.c.

References ACTIVATE_CALL_PLANE_MESSAGE, ALARM_MESSAGE, ast_threadstorage_get(), BUTTON_TEMPLATE_REQ_MESSAGE, BUTTON_TEMPLATE_RES_MESSAGE, CALL_INFO_MESSAGE, CALL_STATE_MESSAGE, CAPABILITIES_REQ_MESSAGE, CAPABILITIES_RES_MESSAGE, CLEAR_DISPLAY_MESSAGE, CLEAR_NOTIFY_MESSAGE, CLEAR_PROMPT_MESSAGE, CLOSE_RECEIVE_CHANNEL_MESSAGE, DEFINETIMEDATE_MESSAGE, DIALED_NUMBER_MESSAGE, DISPLAY_NOTIFY_MESSAGE, DISPLAY_PROMPT_STATUS_MESSAGE, DISPLAYTEXT_MESSAGE, ENBLOC_CALL_MESSAGE, FORWARD_STAT_MESSAGE, HEADSET_STATUS_MESSAGE, IP_PORT_MESSAGE, KEEP_ALIVE_ACK_MESSAGE, KEEP_ALIVE_MESSAGE, KEYPAD_BUTTON_MESSAGE, letohl, LINE_STAT_RES_MESSAGE, LINE_STATE_REQ_MESSAGE, MESSAGE2STR_BUFSIZE, message2str_threadbuf, OFFHOOK_MESSAGE, ONHOOK_MESSAGE, OPEN_RECEIVE_CHANNEL_ACK_MESSAGE, OPEN_RECEIVE_CHANNEL_MESSAGE, REGISTER_ACK_MESSAGE, REGISTER_AVAILABLE_LINES_MESSAGE, REGISTER_MESSAGE, REGISTER_REJ_MESSAGE, RESET_MESSAGE, SELECT_SOFT_KEYS_MESSAGE, SERVER_REQUEST_MESSAGE, SERVER_RES_MESSAGE, SET_LAMP_MESSAGE, SET_MICROPHONE_MESSAGE, SET_RINGER_MESSAGE, SET_SPEAKER_MESSAGE, SOFT_KEY_EVENT_MESSAGE, SOFT_KEY_SET_REQ_MESSAGE, SOFT_KEY_SET_RES_MESSAGE, SOFT_KEY_TEMPLATE_REQ_MESSAGE, SOFT_KEY_TEMPLATE_RES_MESSAGE, SPEED_DIAL_STAT_REQ_MESSAGE, SPEED_DIAL_STAT_RES_MESSAGE, START_MEDIA_TRANSMISSION_MESSAGE, START_TONE_MESSAGE, STIMULUS_MESSAGE, STOP_MEDIA_TRANSMISSION_MESSAGE, STOP_TONE_MESSAGE, TIME_DATE_REQ_MESSAGE, UNREGISTER_MESSAGE, VERSION_REQ_MESSAGE, and VERSION_RES_MESSAGE.

Referenced by handle_message(), and transmit_response_bysession().

02185 {
02186    char *tmp;
02187 
02188    switch (letohl(type)) {
02189    case KEEP_ALIVE_MESSAGE:
02190       return "KEEP_ALIVE_MESSAGE";
02191    case REGISTER_MESSAGE:
02192       return "REGISTER_MESSAGE";
02193    case IP_PORT_MESSAGE:
02194       return "IP_PORT_MESSAGE";
02195    case KEYPAD_BUTTON_MESSAGE:
02196       return "KEYPAD_BUTTON_MESSAGE";
02197    case ENBLOC_CALL_MESSAGE:
02198       return "ENBLOC_CALL_MESSAGE";
02199    case STIMULUS_MESSAGE:
02200       return "STIMULUS_MESSAGE";
02201    case OFFHOOK_MESSAGE:
02202       return "OFFHOOK_MESSAGE";
02203    case ONHOOK_MESSAGE:
02204       return "ONHOOK_MESSAGE";
02205    case CAPABILITIES_RES_MESSAGE:
02206       return "CAPABILITIES_RES_MESSAGE";
02207    case SPEED_DIAL_STAT_REQ_MESSAGE:
02208       return "SPEED_DIAL_STAT_REQ_MESSAGE";
02209    case LINE_STATE_REQ_MESSAGE:
02210       return "LINE_STATE_REQ_MESSAGE";
02211    case TIME_DATE_REQ_MESSAGE:
02212       return "TIME_DATE_REQ_MESSAGE";
02213    case BUTTON_TEMPLATE_REQ_MESSAGE:
02214       return "BUTTON_TEMPLATE_REQ_MESSAGE";
02215    case VERSION_REQ_MESSAGE:
02216       return "VERSION_REQ_MESSAGE";
02217    case SERVER_REQUEST_MESSAGE:
02218       return "SERVER_REQUEST_MESSAGE";
02219    case ALARM_MESSAGE:
02220       return "ALARM_MESSAGE";
02221    case OPEN_RECEIVE_CHANNEL_ACK_MESSAGE:
02222       return "OPEN_RECEIVE_CHANNEL_ACK_MESSAGE";
02223    case SOFT_KEY_SET_REQ_MESSAGE:
02224       return "SOFT_KEY_SET_REQ_MESSAGE";
02225    case SOFT_KEY_EVENT_MESSAGE:
02226       return "SOFT_KEY_EVENT_MESSAGE";
02227    case UNREGISTER_MESSAGE:
02228       return "UNREGISTER_MESSAGE";
02229    case SOFT_KEY_TEMPLATE_REQ_MESSAGE:
02230       return "SOFT_KEY_TEMPLATE_REQ_MESSAGE";
02231    case HEADSET_STATUS_MESSAGE:
02232       return "HEADSET_STATUS_MESSAGE";
02233    case REGISTER_AVAILABLE_LINES_MESSAGE:
02234       return "REGISTER_AVAILABLE_LINES_MESSAGE";
02235    case REGISTER_ACK_MESSAGE:
02236       return "REGISTER_ACK_MESSAGE";
02237    case START_TONE_MESSAGE:
02238       return "START_TONE_MESSAGE";
02239    case STOP_TONE_MESSAGE:
02240       return "STOP_TONE_MESSAGE";
02241    case SET_RINGER_MESSAGE:
02242       return "SET_RINGER_MESSAGE";
02243    case SET_LAMP_MESSAGE:
02244       return "SET_LAMP_MESSAGE";
02245    case SET_SPEAKER_MESSAGE:
02246       return "SET_SPEAKER_MESSAGE";
02247    case SET_MICROPHONE_MESSAGE:
02248       return "SET_MICROPHONE_MESSAGE";
02249    case START_MEDIA_TRANSMISSION_MESSAGE:
02250       return "START_MEDIA_TRANSMISSION_MESSAGE";
02251    case STOP_MEDIA_TRANSMISSION_MESSAGE:
02252       return "STOP_MEDIA_TRANSMISSION_MESSAGE";
02253    case CALL_INFO_MESSAGE:
02254       return "CALL_INFO_MESSAGE";
02255    case FORWARD_STAT_MESSAGE:
02256       return "FORWARD_STAT_MESSAGE";
02257    case SPEED_DIAL_STAT_RES_MESSAGE:
02258       return "SPEED_DIAL_STAT_RES_MESSAGE";
02259    case LINE_STAT_RES_MESSAGE:
02260       return "LINE_STAT_RES_MESSAGE";
02261    case DEFINETIMEDATE_MESSAGE:
02262       return "DEFINETIMEDATE_MESSAGE";
02263    case BUTTON_TEMPLATE_RES_MESSAGE:
02264       return "BUTTON_TEMPLATE_RES_MESSAGE";
02265    case VERSION_RES_MESSAGE:
02266       return "VERSION_RES_MESSAGE";
02267    case DISPLAYTEXT_MESSAGE:
02268       return "DISPLAYTEXT_MESSAGE";
02269    case CLEAR_NOTIFY_MESSAGE:
02270       return "CLEAR_NOTIFY_MESSAGE";
02271    case CLEAR_DISPLAY_MESSAGE:
02272       return "CLEAR_DISPLAY_MESSAGE";
02273    case CAPABILITIES_REQ_MESSAGE:
02274       return "CAPABILITIES_REQ_MESSAGE";
02275    case REGISTER_REJ_MESSAGE:
02276       return "REGISTER_REJ_MESSAGE";
02277    case SERVER_RES_MESSAGE:
02278       return "SERVER_RES_MESSAGE";
02279    case RESET_MESSAGE:
02280       return "RESET_MESSAGE";
02281    case KEEP_ALIVE_ACK_MESSAGE:
02282       return "KEEP_ALIVE_ACK_MESSAGE";
02283    case OPEN_RECEIVE_CHANNEL_MESSAGE:
02284       return "OPEN_RECEIVE_CHANNEL_MESSAGE";
02285    case CLOSE_RECEIVE_CHANNEL_MESSAGE:
02286       return "CLOSE_RECEIVE_CHANNEL_MESSAGE";
02287    case SOFT_KEY_TEMPLATE_RES_MESSAGE:
02288       return "SOFT_KEY_TEMPLATE_RES_MESSAGE";
02289    case SOFT_KEY_SET_RES_MESSAGE:
02290       return "SOFT_KEY_SET_RES_MESSAGE";
02291    case SELECT_SOFT_KEYS_MESSAGE:
02292       return "SELECT_SOFT_KEYS_MESSAGE";
02293    case CALL_STATE_MESSAGE:
02294       return "CALL_STATE_MESSAGE";
02295    case DISPLAY_PROMPT_STATUS_MESSAGE:
02296       return "DISPLAY_PROMPT_STATUS_MESSAGE";
02297    case CLEAR_PROMPT_MESSAGE:
02298       return "CLEAR_PROMPT_MESSAGE";
02299    case DISPLAY_NOTIFY_MESSAGE:
02300       return "DISPLAY_NOTIFY_MESSAGE";
02301    case ACTIVATE_CALL_PLANE_MESSAGE:
02302       return "ACTIVATE_CALL_PLANE_MESSAGE";
02303    case DIALED_NUMBER_MESSAGE:
02304       return "DIALED_NUMBER_MESSAGE";
02305    default:
02306       if (!(tmp = ast_threadstorage_get(&message2str_threadbuf, MESSAGE2STR_BUFSIZE)))
02307          return "Unknown";
02308       snprintf(tmp, MESSAGE2STR_BUFSIZE, "UNKNOWN_MESSAGE-%d", type);
02309       return tmp;
02310    }
02311 }

static void mwi_event_cb ( const struct ast_event event,
void *  userdata 
) [static]

Definition at line 3178 of file chan_skinny.c.

References ast_event_get_ie_uint(), AST_EVENT_IE_NEWMSGS, AST_LIST_TRAVERSE, ast_verb, skinny_line::device, skinny_device::lines, skinny_line::newmsgs, skinny_device::session, SKINNY_LAMP_BLINK, SKINNY_LAMP_OFF, SKINNY_LAMP_ON, STIMULUS_VOICEMAIL, and transmit_lamp_indication().

03179 {
03180    struct skinny_line *l = userdata;
03181    struct skinny_device *d = l->device;
03182    if (d) {
03183       struct skinnysession *s = d->session;
03184       struct skinny_line *l2;
03185       int new_msgs = 0;
03186       int dev_msgs = 0;
03187 
03188       if (s) {
03189          if (event) {
03190             l->newmsgs = ast_event_get_ie_uint(event, AST_EVENT_IE_NEWMSGS);
03191          }
03192 
03193          if (l->newmsgs) {
03194             transmit_lamp_indication(d, STIMULUS_VOICEMAIL, l->instance, l->mwiblink?SKINNY_LAMP_BLINK:SKINNY_LAMP_ON);
03195          } else {
03196             transmit_lamp_indication(d, STIMULUS_VOICEMAIL, l->instance, SKINNY_LAMP_OFF);
03197          }
03198 
03199          /* find out wether the device lamp should be on or off */
03200          AST_LIST_TRAVERSE(&d->lines, l2, list) {
03201             if (l2->newmsgs) {
03202                dev_msgs++;
03203             }
03204          }
03205 
03206          if (dev_msgs) {
03207             transmit_lamp_indication(d, STIMULUS_VOICEMAIL, 0, d->mwiblink?SKINNY_LAMP_BLINK:SKINNY_LAMP_ON);
03208          } else {
03209             transmit_lamp_indication(d, STIMULUS_VOICEMAIL, 0, SKINNY_LAMP_OFF);
03210          }
03211          ast_verb(3, "Skinny mwi_event_cb found %d new messages\n", new_msgs);
03212       }
03213    }
03214 }

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 3563 of file chan_skinny.c.

References ast_cli(), ast_codec_pref_index(), ast_getformatname(), ast_codec_pref::framing, and ast_format::id.

03564 {
03565    int x;
03566    struct ast_format tmpfmt;
03567 
03568    for(x = 0; x < 32 ; x++) {
03569       ast_codec_pref_index(pref, x, &tmpfmt);
03570       if (!tmpfmt.id)
03571          break;
03572       ast_cli(fd, "%s", ast_getformatname(&tmpfmt));
03573       ast_cli(fd, ":%d", pref->framing[x]);
03574       if (x < 31 && ast_codec_pref_index(pref, x + 1, &tmpfmt))
03575          ast_cli(fd, ",");
03576    }
03577    if (!x)
03578       ast_cli(fd, "none");
03579 }

static void push_callinfo ( struct skinny_subline subline,
struct skinny_subchannel sub 
) [static]

Definition at line 2486 of file chan_skinny.c.

References ast_verb, skinny_subchannel::calldirection, ast_channel::caller, skinny_subline::callid, ast_channel::connected, skinny_line::device, ast_party_caller::id, ast_party_connected_line::id, skinny_subline::line, skinny_subchannel::line, ast_party_id::name, ast_party_id::number, skinny_subchannel::owner, S_COR, SKINNY_INCOMING, SKINNY_OUTGOING, ast_party_number::str, ast_party_name::str, transmit_callinfo(), ast_party_number::valid, and ast_party_name::valid.

Referenced by setsubstate().

02487 {
02488    struct ast_channel *ast;
02489    struct skinny_device *d;
02490    struct skinny_line *l;
02491    char *fromname;
02492    char *fromnum;
02493    char *toname;
02494    char *tonum;
02495 
02496    if (!sub || !sub->owner || !sub->line || !sub->line->device) {
02497       return;
02498    }
02499    
02500    ast = sub->owner;
02501    l = sub->line;
02502    d = l->device;
02503    
02504    if (sub->calldirection == SKINNY_INCOMING) {
02505       fromname = S_COR(ast->connected.id.name.valid, ast->connected.id.name.str, "");
02506       fromnum = S_COR(ast->connected.id.number.valid, ast->connected.id.number.str, "");
02507       toname = S_COR(ast->caller.id.name.valid, ast->caller.id.name.str, "");
02508       tonum = S_COR(ast->caller.id.number.valid, ast->caller.id.number.str, "");
02509    } else if (sub->calldirection == SKINNY_OUTGOING) {
02510       fromname = S_COR(ast->caller.id.name.valid, ast->caller.id.name.str, "");
02511       fromnum = S_COR(ast->caller.id.number.valid, ast->caller.id.number.str, "");
02512       toname = S_COR(ast->connected.id.name.valid, ast->connected.id.name.str, l->lastnumberdialed);
02513       tonum = S_COR(ast->connected.id.number.valid, ast->connected.id.number.str, l->lastnumberdialed);
02514    } else {
02515       ast_verb(1, "Error sending Callinfo to %s(%d) - No call direction in sub\n", d->name, l->instance);
02516       return;
02517    }
02518    transmit_callinfo(subline->line->device, subline->line->instance, subline->callid, fromname, fromnum, toname, tonum, sub->calldirection);
02519 }

static void register_exten ( struct skinny_line l  )  [static]

Definition at line 2025 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(), ext, LOG_WARNING, S_OR, and strsep().

Referenced by skinny_register().

02026 {
02027    char multi[256];
02028    char *stringp, *ext, *context;
02029 
02030    if (ast_strlen_zero(regcontext))
02031       return;
02032 
02033    ast_copy_string(multi, S_OR(l->regexten, l->name), sizeof(multi));
02034    stringp = multi;
02035    while ((ext = strsep(&stringp, "&"))) {
02036       if ((context = strchr(ext, '@'))) {
02037          *context++ = '\0'; /* split ext@context */
02038          if (!ast_context_find(context)) {
02039             ast_log(LOG_WARNING, "Context %s must exist in regcontext= in skinny.conf!\n", context);
02040             continue;
02041          }
02042       } else {
02043          context = regcontext;
02044       }
02045       ast_add_extension(context, 1, ext, 1, NULL, NULL, "Noop",
02046           ast_strdup(l->name), ast_free_ptr, "Skinny");
02047    }
02048 }

static int reload ( void   )  [static]

Definition at line 8083 of file chan_skinny.c.

References skinny_reload().

08084 {
08085    skinny_reload();
08086    return 0;
08087 }

static struct skinny_req* req_alloc ( size_t  size,
int  response_message 
) [static, read]

static void send_callinfo ( struct skinny_subchannel sub  )  [static]

Definition at line 2451 of file chan_skinny.c.

References ast_verb, skinny_subchannel::calldirection, ast_channel::caller, skinny_subchannel::callid, ast_channel::connected, skinny_line::device, ast_party_caller::id, ast_party_connected_line::id, skinny_subchannel::line, ast_party_id::name, ast_party_id::number, skinny_subchannel::owner, S_COR, SKINNY_INCOMING, SKINNY_OUTGOING, ast_party_number::str, ast_party_name::str, transmit_callinfo(), ast_party_number::valid, and ast_party_name::valid.

Referenced by setsubstate(), and update_connectedline().

02452 {
02453    struct ast_channel *ast;
02454    struct skinny_device *d;
02455    struct skinny_line *l;
02456    char *fromname;
02457    char *fromnum;
02458    char *toname;
02459    char *tonum;
02460 
02461    if (!sub || !sub->owner || !sub->line || !sub->line->device) {
02462       return;
02463    }
02464    
02465    ast = sub->owner;
02466    l = sub->line;
02467    d = l->device;
02468    
02469    if (sub->calldirection == SKINNY_INCOMING) {
02470       fromname = S_COR(ast->connected.id.name.valid, ast->connected.id.name.str, "");
02471       fromnum = S_COR(ast->connected.id.number.valid, ast->connected.id.number.str, "");
02472       toname = S_COR(ast->caller.id.name.valid, ast->caller.id.name.str, "");
02473       tonum = S_COR(ast->caller.id.number.valid, ast->caller.id.number.str, "");
02474    } else if (sub->calldirection == SKINNY_OUTGOING) {
02475       fromname = S_COR(ast->caller.id.name.valid, ast->caller.id.name.str, "");
02476       fromnum = S_COR(ast->caller.id.number.valid, ast->caller.id.number.str, "");
02477       toname = S_COR(ast->connected.id.name.valid, ast->connected.id.name.str, l->lastnumberdialed);
02478       tonum = S_COR(ast->connected.id.number.valid, ast->connected.id.number.str, l->lastnumberdialed);
02479    } else {
02480       ast_verb(1, "Error sending Callinfo to %s(%d) - No call direction in sub\n", d->name, l->instance);
02481       return;
02482    }
02483    transmit_callinfo(d, l->instance, sub->callid, fromname, fromnum, toname, tonum, sub->calldirection);
02484 }

static int set_callforwards ( struct skinny_line l,
const char *  cfwd,
int  cfwdtype 
) [static]

Definition at line 1967 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().

01968 {
01969    if (!l)
01970       return 0;
01971 
01972    if (!ast_strlen_zero(cfwd)) {
01973       if (cfwdtype & SKINNY_CFWD_ALL) {
01974          l->cfwdtype |= SKINNY_CFWD_ALL;
01975          ast_copy_string(l->call_forward_all, cfwd, sizeof(l->call_forward_all));
01976       }
01977       if (cfwdtype & SKINNY_CFWD_BUSY) {
01978          l->cfwdtype |= SKINNY_CFWD_BUSY;
01979          ast_copy_string(l->call_forward_busy, cfwd, sizeof(l->call_forward_busy));
01980       }
01981       if (cfwdtype & SKINNY_CFWD_NOANSWER) {
01982          l->cfwdtype |= SKINNY_CFWD_NOANSWER;
01983          ast_copy_string(l->call_forward_noanswer, cfwd, sizeof(l->call_forward_noanswer));
01984       }
01985    } else {
01986       if (cfwdtype & SKINNY_CFWD_ALL) {
01987          l->cfwdtype &= ~SKINNY_CFWD_ALL;
01988          memset(l->call_forward_all, 0, sizeof(l->call_forward_all));
01989       }
01990       if (cfwdtype & SKINNY_CFWD_BUSY) {
01991          l->cfwdtype &= ~SKINNY_CFWD_BUSY;
01992          memset(l->call_forward_busy, 0, sizeof(l->call_forward_busy));
01993       }
01994       if (cfwdtype & SKINNY_CFWD_NOANSWER) {
01995          l->cfwdtype &= ~SKINNY_CFWD_NOANSWER;
01996          memset(l->call_forward_noanswer, 0, sizeof(l->call_forward_noanswer));
01997       }
01998    }
01999    return l->cfwdtype;
02000 }

static void setsubstate ( struct skinny_subchannel sub,
int  state 
) [static]

Definition at line 5000 of file chan_skinny.c.

References ast_channel::_state, skinny_subchannel::aa_beep, skinny_subchannel::aa_mute, skinny_subchannel::aa_sched, skinny_line::activesub, skinny_line::all, AST_CONTROL_ANSWER, AST_CONTROL_HOLD, AST_CONTROL_RINGING, AST_CONTROL_UNHOLD, ast_copy_string(), ast_exists_extension(), ast_hangup(), AST_LIST_FIRST, AST_LIST_NEXT, AST_LIST_REMOVE, AST_LIST_TRAVERSE, ast_log(), ast_pthread_create, ast_queue_control(), ast_queue_control_data(), ast_queue_hangup(), ast_rtp_instance_destroy(), ast_setstate(), AST_STATE_RINGING, AST_STATE_UP, ast_strlen_zero(), ast_verb, skinny_subchannel::callid, skinny_subline::callid, skinny_subline::container, ast_channel::context, skinny_subchannel::cxmode, skinny_line::device, errno, skinny_subline::exten, ast_channel::exten, skinny_subchannel::exten, skinny_subline::extenstate, KEYDEF_CONNECTED, KEYDEF_OFFHOOK, KEYDEF_ONHOLD, KEYDEF_RINGIN, KEYDEF_RINGOUT, KEYDEF_SLACONNECTEDNOTACTIVE, skinny_subline::line, skinny_subchannel::line, skinny_subline::lnname, LOG_WARNING, skinny_subchannel::owner, pbx_builtin_getvar_helper(), pbx_builtin_setvar_helper(), push_callinfo(), skinny_subchannel::related, skinny_subchannel::rtp, S_OR, send_callinfo(), SKINNY_ALERT, SKINNY_BUSY, SKINNY_BUSYTONE, SKINNY_CALLREMOTEMULTILINE, SKINNY_CALLWAIT, SKINNY_CALLWAITTONE, SKINNY_CONGESTION, SKINNY_CONNECTED, SKINNY_CX_RECVONLY, SKINNY_DIALTONE, skinny_extensionstate_cb(), SKINNY_HOLD, SKINNY_LAMP_BLINK, SKINNY_LAMP_OFF, SKINNY_LAMP_WINK, SKINNY_MICOFF, skinny_newcall(), SKINNY_OFFHOOK, SKINNY_ONHOOK, SKINNY_PROGRESS, SKINNY_REORDER, SKINNY_RING_INSIDE, SKINNY_RING_OFF, SKINNY_RINGIN, SKINNY_RINGOUT, skinny_sched_del(), SKINNY_SPEAKERON, skinny_ss(), SKINNY_ZIP, start_rtp(), STIMULUS_LINE, skinny_subline::stname, skinny_subline::sub, skinny_line::sub, skinny_subchannel::subline, skinny_line::sublines, skinny_subchannel::substate, substate2str(), SUBSTATE_BUSY, SUBSTATE_CALLWAIT, SUBSTATE_CONGESTION, SUBSTATE_CONNECTED, SUBSTATE_DIALING, SUBSTATE_HOLD, SUBSTATE_OFFHOOK, SUBSTATE_ONHOOK, SUBSTATE_PROGRESS, SUBSTATE_RINGIN, SUBSTATE_RINGOUT, transmit_activatecallplane(), transmit_callstate(), transmit_clear_display_message(), transmit_clearpromptmessage(), transmit_closereceivechannel(), transmit_connect(), transmit_definetimedate(), transmit_dialednumber(), transmit_displaypromptstatus(), transmit_lamp_indication(), transmit_microphone_mode(), transmit_ringer_mode(), transmit_selectsoftkeys(), transmit_speaker_mode(), transmit_start_tone(), transmit_stop_tone(), and transmit_stopmediatransmission().

Referenced by activatesub(), dumpsub(), handle_callforward_button(), handle_hold_button(), handle_offhook_message(), handle_soft_key_event_message(), handle_stimulus_message(), handle_transfer_button(), skinny_answer(), skinny_autoanswer_cb(), skinny_call(), and skinny_indicate().

05001 {
05002    struct skinny_line *l = sub->line;
05003    struct skinny_subline *subline = sub->subline;
05004    struct skinny_device *d = l->device;
05005    struct ast_channel *c = sub->owner;
05006    pthread_t t;
05007    int actualstate = state;
05008 
05009    if (sub->substate == SUBSTATE_ONHOOK) {
05010       return;
05011    }
05012 
05013    if (state != SUBSTATE_RINGIN && sub->aa_sched) {
05014       skinny_sched_del(sub->aa_sched);
05015       sub->aa_sched = 0;
05016       sub->aa_beep = 0;
05017       sub->aa_mute = 0;
05018    }
05019    
05020    if ((state == SUBSTATE_RINGIN) && ((d->hookstate == SKINNY_OFFHOOK) || (AST_LIST_NEXT(AST_LIST_FIRST(&l->sub), list)))) {
05021       actualstate = SUBSTATE_CALLWAIT;
05022    }
05023 
05024    if ((state == SUBSTATE_CONNECTED) && (!subline) && (AST_LIST_FIRST(&l->sublines))) {
05025       const char *slastation;
05026       struct skinny_subline *tmpsubline;
05027       slastation = pbx_builtin_getvar_helper(c, "SLASTATION");
05028       ast_verb(3, "Connecting %s to subline\n", slastation);
05029       if (slastation) {
05030          AST_LIST_TRAVERSE(&l->sublines, tmpsubline, list) {
05031             if (!strcasecmp(tmpsubline->stname, slastation)) {
05032                subline = tmpsubline;
05033                break;
05034             }
05035          }
05036          if (subline) {
05037             struct skinny_line *tmpline;
05038             subline->sub = sub;
05039             sub->subline = subline;
05040             subline->callid = sub->callid;
05041             send_callinfo(sub);
05042             AST_LIST_TRAVERSE(&lines, tmpline, all) {
05043                AST_LIST_TRAVERSE(&tmpline->sublines, tmpsubline, list) {
05044                   if (!(subline == tmpsubline)) {
05045                      if (!strcasecmp(subline->lnname, tmpsubline->lnname)) {
05046                         tmpsubline->callid = callnums++;
05047                         transmit_callstate(tmpsubline->line->device, tmpsubline->line->instance, tmpsubline->callid, SKINNY_OFFHOOK);
05048                         push_callinfo(tmpsubline, sub);
05049                         skinny_extensionstate_cb(NULL, NULL, tmpsubline->extenstate, tmpsubline->container);
05050                      }
05051                   }
05052                }
05053             }
05054          }
05055       }
05056    }
05057 
05058    if (subline) { /* Different handling for subs under a subline, indications come through hints */
05059       switch (actualstate) {
05060       case SUBSTATE_ONHOOK:
05061          AST_LIST_REMOVE(&l->sub, sub, list);
05062          if (sub->related) {
05063             sub->related->related = NULL;
05064          }
05065 
05066          if (sub == l->activesub) {
05067             l->activesub = NULL;
05068             transmit_closereceivechannel(d, sub);
05069             transmit_stopmediatransmission(d, sub);
05070          }
05071          
05072          if (subline->callid) {
05073             transmit_stop_tone(d, l->instance, sub->callid);
05074             transmit_callstate(d, l->instance, subline->callid, SKINNY_CALLREMOTEMULTILINE);
05075             transmit_selectsoftkeys(d, l->instance, subline->callid, KEYDEF_SLACONNECTEDNOTACTIVE);
05076             transmit_displaypromptstatus(d, "In Use", 0, l->instance, subline->callid);
05077          }
05078          
05079          sub->cxmode = SKINNY_CX_RECVONLY;   
05080          sub->substate = SUBSTATE_ONHOOK;
05081          if (sub->rtp) {
05082             ast_rtp_instance_destroy(sub->rtp);
05083             sub->rtp = NULL;
05084          }
05085          sub->substate = SUBSTATE_ONHOOK;
05086          if (sub->owner) {
05087             ast_queue_hangup(sub->owner);
05088          }
05089          return;
05090       case SUBSTATE_CONNECTED:
05091          transmit_activatecallplane(d, l);
05092          transmit_stop_tone(d, l->instance, sub->callid);
05093          transmit_selectsoftkeys(d, l->instance, subline->callid, KEYDEF_CONNECTED);
05094          transmit_callstate(d, l->instance, subline->callid, SKINNY_CONNECTED);
05095          if (!sub->rtp) {
05096             start_rtp(sub);
05097          }
05098          if (sub->substate == SUBSTATE_RINGIN || sub->substate == SUBSTATE_CALLWAIT) {
05099             ast_queue_control(sub->owner, AST_CONTROL_ANSWER);
05100          }
05101          if (sub->substate == SUBSTATE_DIALING || sub->substate == SUBSTATE_RINGOUT) {
05102             transmit_dialednumber(d, l->lastnumberdialed, l->instance, sub->callid);
05103          }
05104          if (sub->owner->_state != AST_STATE_UP) {
05105             ast_setstate(sub->owner, AST_STATE_UP);
05106          }
05107          sub->substate = SUBSTATE_CONNECTED;
05108          l->activesub = sub;
05109          return; 
05110       case SUBSTATE_HOLD:
05111          if (sub->substate != SUBSTATE_CONNECTED) {
05112             ast_log(LOG_WARNING, "Cannot set substate to SUBSTATE_HOLD from %s (on call-%d)\n", substate2str(sub->substate), sub->callid);
05113             return;
05114          }
05115          transmit_activatecallplane(d, l);
05116          transmit_closereceivechannel(d, sub);
05117          transmit_stopmediatransmission(d, sub);
05118 
05119          transmit_callstate(d, l->instance, subline->callid, SKINNY_CALLREMOTEMULTILINE);
05120          transmit_selectsoftkeys(d, l->instance, subline->callid, KEYDEF_SLACONNECTEDNOTACTIVE);
05121          transmit_displaypromptstatus(d, "In Use", 0, l->instance, subline->callid);
05122          
05123          sub->substate = SUBSTATE_HOLD;
05124 
05125          ast_queue_control_data(sub->owner, AST_CONTROL_HOLD,
05126             S_OR(l->mohsuggest, NULL),
05127             !ast_strlen_zero(l->mohsuggest) ? strlen(l->mohsuggest) + 1 : 0);
05128 
05129          return;
05130       default:
05131          ast_log(LOG_WARNING, "Substate handling under subline for state %d not implemented on Sub-%d\n", state, sub->callid);
05132       }
05133    }
05134 
05135    if ((d->hookstate == SKINNY_ONHOOK) && ((actualstate == SUBSTATE_OFFHOOK) || (actualstate == SUBSTATE_DIALING)
05136       || (actualstate == SUBSTATE_RINGOUT) || (actualstate == SUBSTATE_CONNECTED) || (actualstate == SUBSTATE_BUSY)
05137       || (actualstate == SUBSTATE_CONGESTION) || (actualstate == SUBSTATE_PROGRESS))) {
05138          d->hookstate = SKINNY_OFFHOOK;
05139          transmit_speaker_mode(d, SKINNY_SPEAKERON);
05140    }
05141 
05142    if (skinnydebug) {
05143       ast_verb(3, "Sub %d - change state from %s to %s\n", sub->callid, substate2str(sub->substate), substate2str(actualstate));
05144    }
05145 
05146    if (actualstate == sub->substate) {
05147       send_callinfo(sub);
05148       transmit_callstate(d, l->instance, sub->callid, SKINNY_HOLD);
05149       return;
05150    }
05151 
05152    switch (actualstate) {
05153    case SUBSTATE_OFFHOOK:
05154       ast_verb(1, "Call-id: %d\n", sub->callid);
05155       l->activesub = sub;
05156       transmit_callstate(d, l->instance, sub->callid, SKINNY_OFFHOOK);
05157       transmit_activatecallplane(d, l);
05158       transmit_clear_display_message(d, l->instance, sub->callid);
05159       transmit_start_tone(d, SKINNY_DIALTONE, l->instance, sub->callid);
05160       transmit_selectsoftkeys(d, l->instance, sub->callid, KEYDEF_OFFHOOK);
05161       transmit_displaypromptstatus(d, "Enter number", 0, l->instance, sub->callid);
05162 
05163       sub->substate = SUBSTATE_OFFHOOK;
05164    
05165       /* start the switch thread */
05166       if (ast_pthread_create(&t, NULL, skinny_ss, sub->owner)) {
05167          ast_log(LOG_WARNING, "Unable to create switch thread: %s\n", strerror(errno));
05168          ast_hangup(sub->owner);
05169       }
05170       break;
05171    case SUBSTATE_ONHOOK:
05172       AST_LIST_REMOVE(&l->sub, sub, list);
05173       if (sub->related) {
05174          sub->related->related = NULL;
05175       }
05176 
05177       if (sub == l->activesub) {
05178          l->activesub = NULL;
05179          transmit_closereceivechannel(d, sub);
05180          transmit_stopmediatransmission(d, sub);
05181          transmit_stop_tone(d, l->instance, sub->callid);
05182          transmit_callstate(d, l->instance, sub->callid, SKINNY_ONHOOK);
05183          transmit_clearpromptmessage(d, l->instance, sub->callid);
05184          transmit_ringer_mode(d, SKINNY_RING_OFF);
05185          transmit_definetimedate(d); 
05186          transmit_lamp_indication(d, STIMULUS_LINE, l->instance, SKINNY_LAMP_OFF);
05187       } else {
05188          transmit_stop_tone(d, l->instance, sub->callid);
05189          transmit_callstate(d, l->instance, sub->callid, SKINNY_ONHOOK);
05190          transmit_clearpromptmessage(d, l->instance, sub->callid);
05191       }
05192 
05193       sub->cxmode = SKINNY_CX_RECVONLY;   
05194       sub->substate = SUBSTATE_ONHOOK;
05195       if (sub->rtp) {
05196          ast_rtp_instance_destroy(sub->rtp);
05197          sub->rtp = NULL;
05198       }
05199       if (sub->owner) {
05200          ast_queue_hangup(sub->owner);
05201       }
05202       break;
05203    case SUBSTATE_DIALING:
05204       if (ast_strlen_zero(sub->exten) || !ast_exists_extension(c, c->context, sub->exten, 1, l->cid_num)) {
05205          ast_log(LOG_WARNING, "Exten (%s)@(%s) does not exist, unable to set substate DIALING on sub %d\n", sub->exten, c->context, sub->callid);
05206          return;
05207       }
05208 
05209       if (d->hookstate == SKINNY_ONHOOK) {
05210          d->hookstate = SKINNY_OFFHOOK;
05211          transmit_speaker_mode(d, SKINNY_SPEAKERON);
05212          transmit_activatecallplane(d, l);
05213       }
05214 
05215       if (!sub->subline) {
05216          transmit_callstate(d, l->instance, sub->callid, SKINNY_OFFHOOK);
05217          transmit_stop_tone(d, l->instance, sub->callid);
05218          transmit_clear_display_message(d, l->instance, sub->callid);
05219          transmit_selectsoftkeys(d, l->instance, sub->callid, KEYDEF_RINGOUT);
05220          transmit_displaypromptstatus(d, "Dialing", 0, l->instance, sub->callid);
05221       }
05222 
05223       if  (AST_LIST_FIRST(&l->sublines)) {
05224          if (subline) {
05225             ast_copy_string(c->exten, subline->exten, sizeof(c->exten));
05226             ast_copy_string(c->context, "sla_stations", sizeof(c->context));
05227          } else {
05228             pbx_builtin_setvar_helper(c, "_DESTEXTEN", sub->exten);
05229             pbx_builtin_setvar_helper(c, "_DESTCONTEXT", c->context);
05230             ast_copy_string(c->exten, l->dialoutexten, sizeof(c->exten));
05231             ast_copy_string(c->context, l->dialoutcontext, sizeof(c->context));
05232             ast_copy_string(l->lastnumberdialed, sub->exten, sizeof(l->lastnumberdialed));
05233          }
05234       } else {
05235          ast_copy_string(c->exten, sub->exten, sizeof(c->exten));
05236          ast_copy_string(l->lastnumberdialed, sub->exten, sizeof(l->lastnumberdialed));
05237       }
05238       
05239       sub->substate = SUBSTATE_DIALING;
05240    
05241       if (ast_pthread_create(&t, NULL, skinny_newcall, c)) {
05242          ast_log(LOG_WARNING, "Unable to create new call thread: %s\n", strerror(errno));
05243          ast_hangup(c);
05244       }
05245       break;
05246    case SUBSTATE_RINGOUT:
05247       if (!(sub->substate == SUBSTATE_DIALING || sub->substate == SUBSTATE_PROGRESS)) {
05248          ast_log(LOG_WARNING, "Cannot set substate to SUBSTATE_RINGOUT from %s (on call-%d)\n", substate2str(sub->substate), sub->callid);
05249          return;
05250       }
05251    
05252       if (!d->earlyrtp) {
05253          transmit_start_tone(d, SKINNY_ALERT, l->instance, sub->callid);
05254       }
05255       transmit_callstate(d, l->instance, sub->callid, SKINNY_RINGOUT);
05256       transmit_dialednumber(d, l->lastnumberdialed, l->instance, sub->callid);
05257       transmit_displaypromptstatus(d, "Ring Out", 0, l->instance, sub->callid);
05258       send_callinfo(sub);
05259       sub->substate = SUBSTATE_RINGOUT;
05260       break;
05261    case SUBSTATE_RINGIN:
05262       transmit_callstate(d, l->instance, sub->callid, SKINNY_RINGIN);
05263       transmit_selectsoftkeys(d, l->instance, sub->callid, KEYDEF_RINGIN);
05264       transmit_displaypromptstatus(d, "Ring-In", 0, l->instance, sub->callid);
05265       send_callinfo(sub);
05266       transmit_lamp_indication(d, STIMULUS_LINE, l->instance, SKINNY_LAMP_BLINK);
05267       transmit_ringer_mode(d, SKINNY_RING_INSIDE);
05268       transmit_activatecallplane(d, l);
05269 
05270       if (d->hookstate == SKINNY_ONHOOK) {
05271          l->activesub = sub;
05272       }
05273    
05274       if (sub->substate != SUBSTATE_RINGIN || sub->substate != SUBSTATE_CALLWAIT) {
05275          ast_setstate(c, AST_STATE_RINGING);
05276          ast_queue_control(c, AST_CONTROL_RINGING);
05277       }
05278       sub->substate = SUBSTATE_RINGIN;
05279       break;
05280    case SUBSTATE_CALLWAIT:
05281       transmit_callstate(d, l->instance, sub->callid, SKINNY_RINGIN);
05282       transmit_callstate(d, l->instance, sub->callid, SKINNY_CALLWAIT);
05283       transmit_selectsoftkeys(d, l->instance, sub->callid, KEYDEF_RINGIN);
05284       transmit_displaypromptstatus(d, "Callwaiting", 0, l->instance, sub->callid);
05285       send_callinfo(sub);
05286       transmit_lamp_indication(d, STIMULUS_LINE, l->instance, SKINNY_LAMP_BLINK);
05287       transmit_start_tone(d, SKINNY_CALLWAITTONE, l->instance, sub->callid);
05288    
05289       ast_setstate(c, AST_STATE_RINGING);
05290       ast_queue_control(c, AST_CONTROL_RINGING);
05291       sub->substate = SUBSTATE_CALLWAIT;
05292       break;
05293    case SUBSTATE_CONNECTED:
05294       if (sub->substate == SUBSTATE_HOLD) {
05295          ast_queue_control(sub->owner, AST_CONTROL_UNHOLD);
05296          transmit_connect(d, sub);
05297       }
05298       transmit_ringer_mode(d, SKINNY_RING_OFF);
05299       transmit_activatecallplane(d, l);
05300       transmit_stop_tone(d, l->instance, sub->callid);
05301       send_callinfo(sub);
05302       transmit_callstate(d, l->instance, sub->callid, SKINNY_CONNECTED);
05303       transmit_displaypromptstatus(d, "Connected", 0, l->instance, sub->callid);
05304       transmit_selectsoftkeys(d, l->instance, sub->callid, KEYDEF_CONNECTED);
05305       if (!sub->rtp) {
05306          start_rtp(sub);
05307       }
05308       if (sub->aa_beep) {
05309          transmit_start_tone(d, SKINNY_ZIP, l->instance, sub->callid);
05310       }
05311       if (sub->aa_mute) {
05312          transmit_microphone_mode(d, SKINNY_MICOFF);
05313       }
05314       if (sub->substate == SUBSTATE_RINGIN || sub->substate == SUBSTATE_CALLWAIT) {
05315          ast_queue_control(sub->owner, AST_CONTROL_ANSWER);
05316       }
05317       if (sub->substate == SUBSTATE_DIALING || sub->substate == SUBSTATE_RINGOUT) {
05318          transmit_dialednumber(d, l->lastnumberdialed, l->instance, sub->callid);
05319       }
05320       if (sub->owner->_state != AST_STATE_UP) {
05321          ast_setstate(sub->owner, AST_STATE_UP);
05322       }
05323       sub->substate = SUBSTATE_CONNECTED;
05324       l->activesub = sub;
05325       break;
05326    case SUBSTATE_BUSY:
05327       if (!(sub->substate == SUBSTATE_DIALING || sub->substate == SUBSTATE_PROGRESS || sub->substate == SUBSTATE_RINGOUT)) {
05328          ast_log(LOG_WARNING, "Cannot set substate to SUBSTATE_BUSY from %s (on call-%d)\n", substate2str(sub->substate), sub->callid);
05329          return;
05330       }
05331 
05332       if (!d->earlyrtp) {
05333          transmit_start_tone(d, SKINNY_BUSYTONE, l->instance, sub->callid);
05334       }
05335       send_callinfo(sub);
05336       transmit_callstate(d, l->instance, sub->callid, SKINNY_BUSY);
05337       transmit_displaypromptstatus(d, "Busy", 0, l->instance, sub->callid);
05338       sub->substate = SUBSTATE_BUSY;
05339       break;
05340    case SUBSTATE_CONGESTION:
05341       if (!(sub->substate == SUBSTATE_DIALING || sub->substate == SUBSTATE_PROGRESS || sub->substate == SUBSTATE_RINGOUT)) {
05342          ast_log(LOG_WARNING, "Cannot set substate to SUBSTATE_CONGESTION from %s (on call-%d)\n", substate2str(sub->substate), sub->callid);
05343          return;
05344       }
05345 
05346       if (!d->earlyrtp) {
05347          transmit_start_tone(d, SKINNY_REORDER, l->instance, sub->callid);
05348       }
05349       send_callinfo(sub);
05350       transmit_callstate(d, l->instance, sub->callid, SKINNY_CONGESTION);
05351       transmit_displaypromptstatus(d, "Congestion", 0, l->instance, sub->callid);
05352       sub->substate = SUBSTATE_CONGESTION;
05353       break;
05354    case SUBSTATE_PROGRESS:
05355       if (sub->substate != SUBSTATE_DIALING) {
05356          ast_log(LOG_WARNING, "Cannot set substate to SUBSTATE_PROGRESS from %s (on call-%d)\n", substate2str(sub->substate), sub->callid);
05357          return;
05358       }
05359 
05360       if (!d->earlyrtp) {
05361          transmit_start_tone(d, SKINNY_ALERT, l->instance, sub->callid);
05362       }
05363       send_callinfo(sub);
05364       transmit_callstate(d, l->instance, sub->callid, SKINNY_PROGRESS);
05365       transmit_displaypromptstatus(d, "Call Progress", 0, l->instance, sub->callid);
05366       sub->substate = SUBSTATE_PROGRESS;
05367       break;
05368    case SUBSTATE_HOLD:
05369       if (sub->substate != SUBSTATE_CONNECTED) {
05370          ast_log(LOG_WARNING, "Cannot set substate to SUBSTATE_HOLD from %s (on call-%d)\n", substate2str(sub->substate), sub->callid);
05371          return;
05372       }
05373       ast_queue_control_data(sub->owner, AST_CONTROL_HOLD,
05374          S_OR(l->mohsuggest, NULL),
05375          !ast_strlen_zero(l->mohsuggest) ? strlen(l->mohsuggest) + 1 : 0);
05376 
05377       transmit_activatecallplane(d, l);
05378       transmit_closereceivechannel(d, sub);
05379       transmit_stopmediatransmission(d, sub);
05380 
05381       transmit_callstate(d, l->instance, sub->callid, SKINNY_HOLD);
05382       transmit_lamp_indication(d, STIMULUS_LINE, l->instance, SKINNY_LAMP_WINK);
05383       transmit_selectsoftkeys(d, l->instance, sub->callid, KEYDEF_ONHOLD);
05384       sub->substate = SUBSTATE_HOLD;
05385       break;
05386    default:
05387       ast_log(LOG_WARNING, "Was asked to change to nonexistant substate %d on Sub-%d\n", state, sub->callid);
05388    }
05389 }

static int skinny_answer ( struct ast_channel ast  )  [static]

Definition at line 4462 of file chan_skinny.c.

References ast_channel_name(), ast_debug, ast_setstate(), AST_STATE_UP, ast_verb, skinny_subchannel::blindxfer, skinny_subchannel::callid, skinny_subchannel::cxmode, skinny_line::device, skinny_subchannel::line, setsubstate(), SKINNY_CX_SENDRECV, skinny_transfer(), sub, SUBSTATE_CONNECTED, and ast_channel::tech_pvt.

04463 {
04464    int res = 0;
04465    struct skinny_subchannel *sub = ast->tech_pvt;
04466    struct skinny_line *l = sub->line;
04467    struct skinny_device *d = l->device;
04468 
04469    if (sub->blindxfer) {
04470       if (skinnydebug)
04471          ast_debug(1, "skinny_answer(%s) on %s@%s-%d with BlindXFER, transferring\n",
04472             ast_channel_name(ast), l->name, d->name, sub->callid);
04473       ast_setstate(ast, AST_STATE_UP);
04474       skinny_transfer(sub);
04475       return 0;
04476    }
04477 
04478    sub->cxmode = SKINNY_CX_SENDRECV;
04479 
04480    if (skinnydebug)
04481       ast_verb(1, "skinny_answer(%s) on %s@%s-%d\n", ast_channel_name(ast), l->name, d->name, sub->callid);
04482    
04483    setsubstate(sub, SUBSTATE_CONNECTED);
04484 
04485    return res;
04486 }

static int skinny_autoanswer_cb ( const void *  data  )  [static]

Definition at line 4359 of file chan_skinny.c.

References skinny_subchannel::aa_sched, setsubstate(), SKINNY_CONNECTED, and sub.

Referenced by skinny_call().

04360 {
04361    struct skinny_subchannel *sub = (struct skinny_subchannel *)data;
04362    sub->aa_sched = 0;
04363    setsubstate(sub, SKINNY_CONNECTED);
04364    return 0;
04365 }

static int skinny_call ( struct ast_channel ast,
const char *  dest,
int  timeout 
) [static]

Definition at line 4367 of file chan_skinny.c.

References ast_channel::_state, skinny_subchannel::aa_beep, skinny_subchannel::aa_mute, skinny_subchannel::aa_sched, ast_channel_name(), AST_CONTROL_BUSY, ast_copy_string(), AST_LIST_NEXT, AST_LIST_TRAVERSE, ast_log(), ast_queue_control(), AST_STATE_DOWN, AST_STATE_RESERVED, ast_var_name(), ast_var_value(), ast_verb, skinny_subchannel::callid, skinny_line::device, ast_var_t::entries, skinny_subchannel::line, LOG_ERROR, LOG_WARNING, setsubstate(), skinny_autoanswer_cb(), SKINNY_ONHOOK, skinny_sched_add(), strsep(), sub, SUBSTATE_CONNECTED, SUBSTATE_RINGIN, ast_channel::tech_pvt, and ast_channel::varshead.

04368 {
04369    int res = 0;
04370    struct skinny_subchannel *sub = ast->tech_pvt;
04371    struct skinny_line *l = sub->line;
04372    struct skinny_device *d = l->device;
04373    struct ast_var_t *current;
04374    int doautoanswer = 0;
04375 
04376    if (!d->registered) {
04377       ast_log(LOG_ERROR, "Device not registered, cannot call %s\n", dest);
04378       return -1;
04379    }
04380 
04381    if ((ast->_state != AST_STATE_DOWN) && (ast->_state != AST_STATE_RESERVED)) {
04382       ast_log(LOG_WARNING, "skinny_call called on %s, neither down nor reserved\n", ast_channel_name(ast));
04383       return -1;
04384    }
04385 
04386    if (skinnydebug)
04387       ast_verb(3, "skinny_call(%s)\n", ast_channel_name(ast));
04388 
04389    if (l->dnd) {
04390       ast_queue_control(ast, AST_CONTROL_BUSY);
04391       return -1;
04392    }
04393 
04394    if (AST_LIST_NEXT(sub,list) && !l->callwaiting) {
04395       ast_queue_control(ast, AST_CONTROL_BUSY);
04396       return -1;
04397    }
04398 
04399    AST_LIST_TRAVERSE(&ast->varshead, current, entries) {
04400       if (!(strcasecmp(ast_var_name(current),"SKINNY_AUTOANSWER"))) {
04401          if (d->hookstate == SKINNY_ONHOOK && !sub->aa_sched) {
04402             char buf[24];
04403             int aatime;
04404             char *stringp = buf, *curstr;
04405             ast_copy_string(buf, ast_var_value(current), sizeof(buf));
04406             curstr = strsep(&stringp, ":");
04407             ast_verb(3, "test %s\n", curstr);
04408             aatime = atoi(curstr);
04409             while ((curstr = strsep(&stringp, ":"))) {
04410                if (!(strcasecmp(curstr,"BEEP"))) {
04411                   sub->aa_beep = 1;
04412                } else if (!(strcasecmp(curstr,"MUTE"))) {
04413                   sub->aa_mute = 1;
04414                }
04415             }
04416             if (skinnydebug)
04417                ast_verb(3, "Sub %d - setting autoanswer time=%dms %s%s\n", sub->callid, aatime, sub->aa_beep?"BEEP ":"", sub->aa_mute?"MUTE":"");
04418             if (aatime) {
04419                //sub->aa_sched = ast_sched_add(sched, aatime, skinny_autoanswer_cb, sub);
04420                sub->aa_sched = skinny_sched_add(aatime, skinny_autoanswer_cb, sub);
04421             } else {
04422                doautoanswer = 1;
04423             }
04424          }
04425       }
04426    }
04427 
04428    setsubstate(sub, SUBSTATE_RINGIN);
04429    if (doautoanswer) {
04430       setsubstate(sub, SUBSTATE_CONNECTED);
04431    }
04432    return res;
04433 }

static struct skinny_device* skinny_device_alloc ( void   )  [static, read]

Definition at line 1541 of file chan_skinny.c.

References ast_calloc, ast_format_cap_alloc_nolock(), ast_format_cap_destroy(), ast_free, skinny_device::cap, and skinny_device::confcap.

Referenced by config_device().

01542 {
01543    struct skinny_device *d;
01544    if (!(d = ast_calloc(1, sizeof(*d)))) {
01545       return NULL;
01546    }
01547 
01548    d->cap = ast_format_cap_alloc_nolock();
01549    d->confcap = ast_format_cap_alloc_nolock();
01550    if (!d->cap || !d->confcap) {
01551       d->cap = ast_format_cap_destroy(d->cap);
01552       d->confcap = ast_format_cap_destroy(d->confcap);
01553       ast_free(d);
01554       return NULL;
01555    }
01556    return d;
01557 }

static struct skinny_device* skinny_device_destroy ( struct skinny_device d  )  [static, read]

Definition at line 1558 of file chan_skinny.c.

References ast_format_cap_destroy(), ast_free, skinny_device::cap, and skinny_device::confcap.

Referenced by delete_devices(), and skinny_reload().

01559 {
01560    d->cap = ast_format_cap_destroy(d->cap);
01561    d->confcap = ast_format_cap_destroy(d->confcap);
01562    ast_free(d);
01563    return NULL;
01564 }

static int skinny_devicestate ( const char *  data  )  [static]

Definition at line 7065 of file chan_skinny.c.

References ast_strdupa, find_line_by_name(), and get_devicestate().

07066 {
07067    struct skinny_line *l;
07068    char *tmp;
07069 
07070    tmp = ast_strdupa(data);
07071 
07072    l = find_line_by_name(tmp);
07073 
07074    return get_devicestate(l);
07075 }

static int skinny_extensionstate_cb ( const char *  context,
const char *  exten,
enum ast_extension_states  state,
void *  data 
) [static]

Definition at line 3032 of file chan_skinny.c.

References AST_DEVICE_UNAVAILABLE, AST_EXTENSION_BUSY, AST_EXTENSION_DEACTIVATED, AST_EXTENSION_INUSE, AST_EXTENSION_NOT_INUSE, AST_EXTENSION_ONHOLD, AST_EXTENSION_REMOVED, AST_EXTENSION_RINGING, ast_extension_state2str(), AST_EXTENSION_UNAVAILABLE, ast_get_hint(), ast_log(), ast_verb, skinny_subline::callid, skinny_speeddial::context, skinny_container::data, skinny_line::device, skinny_speeddial::exten, skinny_subline::extenstate, skinny_speeddial::instance, KEYDEF_CONNECTED, KEYDEF_ONHOOK, KEYDEF_SLACONNECTEDNOTACTIVE, KEYDEF_SLAHOLD, skinny_speeddial::label, skinny_speeddial::laststate, skinny_subline::line, LOG_WARNING, skinny_subline::name, skinny_speeddial::parent, SKINNY_CALLREMOTEMULTILINE, SKINNY_CONNECTED, SKINNY_HOLD, SKINNY_LAMP_BLINK, SKINNY_LAMP_FLASH, SKINNY_LAMP_OFF, SKINNY_LAMP_ON, SKINNY_LAMP_WINK, SKINNY_ONHOOK, SKINNY_RING_OFF, SKINNY_RINGIN, SKINNY_SDCONTAINER, SKINNY_SUBLINECONTAINER, skinny_speeddial::stateid, STIMULUS_LINE, skinny_subline::sub, skinny_subchannel::substate, transmit_activatecallplane(), transmit_callstate(), transmit_clearpromptmessage(), transmit_displaypromptstatus(), transmit_lamp_indication(), transmit_ringer_mode(), transmit_selectsoftkeys(), and skinny_container::type.

Referenced by setsubstate(), and skinny_register().

03033 {
03034    struct skinny_container *container = data;
03035    struct skinny_device *d = NULL;
03036    char hint[AST_MAX_EXTENSION];
03037 
03038    if (container->type == SKINNY_SDCONTAINER) {
03039       struct skinny_speeddial *sd = container->data;
03040       d = sd->parent;
03041 
03042       if (skinnydebug) {
03043          ast_verb(2, "Got hint %s on speeddial %s\n", ast_extension_state2str(state), sd->label);
03044       }
03045 
03046       if (ast_get_hint(hint, sizeof(hint), NULL, 0, NULL, sd->context, sd->exten)) {
03047          /* If they are not registered, we will override notification and show no availability */
03048          if (ast_device_state(hint) == AST_DEVICE_UNAVAILABLE) {
03049             transmit_lamp_indication(d, STIMULUS_LINE, sd->instance, SKINNY_LAMP_FLASH);
03050             transmit_callstate(d, sd->instance, 0, SKINNY_ONHOOK);
03051             return 0;
03052          }
03053          switch (state) {
03054          case AST_EXTENSION_DEACTIVATED: /* Retry after a while */
03055          case AST_EXTENSION_REMOVED:     /* Extension is gone */
03056             ast_verb(2, "Extension state: Watcher for hint %s %s. Notify Device %s\n", exten, state == AST_EXTENSION_DEACTIVATED ? "deactivated" : "removed", d->name);
03057             sd->stateid = -1;
03058             transmit_lamp_indication(d, STIMULUS_LINE, sd->instance, SKINNY_LAMP_OFF);
03059             transmit_callstate(d, sd->instance, 0, SKINNY_ONHOOK);
03060             break;
03061          case AST_EXTENSION_RINGING:
03062          case AST_EXTENSION_UNAVAILABLE:
03063             transmit_lamp_indication(d, STIMULUS_LINE, sd->instance, SKINNY_LAMP_BLINK);
03064             transmit_callstate(d, sd->instance, 0, SKINNY_RINGIN);
03065             break;
03066          case AST_EXTENSION_BUSY: /* callstate = SKINNY_BUSY wasn't wanting to work - I'll settle for this */
03067          case AST_EXTENSION_INUSE:
03068             transmit_lamp_indication(d, STIMULUS_LINE, sd->instance, SKINNY_LAMP_ON);
03069             transmit_callstate(d, sd->instance, 0, SKINNY_CALLREMOTEMULTILINE);
03070             break;
03071          case AST_EXTENSION_ONHOLD:
03072             transmit_lamp_indication(d, STIMULUS_LINE, sd->instance, SKINNY_LAMP_WINK);
03073             transmit_callstate(d, sd->instance, 0, SKINNY_HOLD);
03074             break;
03075          case AST_EXTENSION_NOT_INUSE:
03076          default:
03077             transmit_lamp_indication(d, STIMULUS_LINE, sd->instance, SKINNY_LAMP_OFF);
03078             transmit_callstate(d, sd->instance, 0, SKINNY_ONHOOK);
03079             break;
03080          }
03081       }
03082       sd->laststate = state;
03083    } else if (container->type == SKINNY_SUBLINECONTAINER) {
03084       struct skinny_subline *subline = container->data;
03085       struct skinny_line *l = subline->line;
03086       d = l->device;
03087 
03088       if (skinnydebug) {
03089          ast_verb(2, "Got hint %s on subline %s (%s@%s)\n", ast_extension_state2str(state), subline->name, exten, context);
03090       }
03091       
03092       subline->extenstate = state;
03093 
03094       if (subline->callid == 0) {
03095          return 0;
03096       }
03097 
03098       switch (state) {
03099       case AST_EXTENSION_RINGING: /* Handled by normal ringin */
03100          break;
03101       case AST_EXTENSION_INUSE:
03102          if (subline->sub && (subline->sub->substate == SKINNY_CONNECTED)) { /* Device has a real call */
03103             transmit_callstate(d, l->instance, subline->callid, SKINNY_CONNECTED);
03104             transmit_selectsoftkeys(d, l->instance, subline->callid, KEYDEF_CONNECTED);
03105             transmit_displaypromptstatus(d, "Connected", 0, l->instance, subline->callid);
03106          } else { /* Some other device has active call */
03107             transmit_callstate(d, l->instance, subline->callid, SKINNY_CALLREMOTEMULTILINE);
03108             transmit_selectsoftkeys(d, l->instance, subline->callid, KEYDEF_SLACONNECTEDNOTACTIVE);
03109             transmit_displaypromptstatus(d, "In Use", 0, l->instance, subline->callid);
03110          }
03111          transmit_lamp_indication(d, STIMULUS_LINE, l->instance, SKINNY_LAMP_ON);
03112          transmit_ringer_mode(d, SKINNY_RING_OFF);
03113          transmit_activatecallplane(d, l);
03114          break;
03115       case AST_EXTENSION_ONHOLD:
03116          transmit_callstate(d, l->instance, subline->callid, SKINNY_HOLD);
03117          transmit_selectsoftkeys(d, l->instance, subline->callid, KEYDEF_SLAHOLD);
03118          transmit_displaypromptstatus(d, "Hold", 0, l->instance, subline->callid);
03119          transmit_lamp_indication(d, STIMULUS_LINE, l->instance, SKINNY_LAMP_BLINK);
03120          transmit_activatecallplane(d, l);
03121          break;
03122       case AST_EXTENSION_NOT_INUSE:
03123          transmit_callstate(d, l->instance, subline->callid, SKINNY_ONHOOK);
03124          transmit_selectsoftkeys(d, l->instance, subline->callid, KEYDEF_ONHOOK);
03125          transmit_clearpromptmessage(d, l->instance, subline->callid);
03126          transmit_lamp_indication(d, STIMULUS_LINE, l->instance, SKINNY_LAMP_OFF);
03127          transmit_activatecallplane(d, l);
03128          subline->callid = 0;
03129          break;
03130       default:
03131          ast_log(LOG_WARNING, "AST_EXTENSION_STATE %s not configured\n", ast_extension_state2str(state));
03132       }
03133    } else {
03134       ast_log(LOG_WARNING, "Invalid data supplied to skinny_extensionstate_cb\n");
03135    }
03136 
03137    return 0;
03138 }

static int skinny_fixup ( struct ast_channel oldchan,
struct ast_channel newchan 
) [static]

Definition at line 4578 of file chan_skinny.c.

References ast_channel_name(), ast_log(), LOG_NOTICE, LOG_WARNING, skinny_subchannel::owner, sub, and ast_channel::tech_pvt.

04579 {
04580    struct skinny_subchannel *sub = newchan->tech_pvt;
04581    ast_log(LOG_NOTICE, "skinny_fixup(%s, %s)\n", ast_channel_name(oldchan), ast_channel_name(newchan));
04582    if (sub->owner != oldchan) {
04583       ast_log(LOG_WARNING, "old channel wasn't %p but was %p\n", oldchan, sub->owner);
04584       return -1;
04585    }
04586    sub->owner = newchan;
04587    return 0;
04588 }

static enum ast_rtp_glue_result skinny_get_rtp_peer ( struct ast_channel c,
struct ast_rtp_instance **  instance 
) [static]

Definition at line 3232 of file chan_skinny.c.

References ao2_ref, ast_channel_name(), ast_mutex_lock, ast_mutex_unlock, AST_RTP_GLUE_RESULT_FORBID, AST_RTP_GLUE_RESULT_LOCAL, AST_RTP_GLUE_RESULT_REMOTE, ast_verb, skinny_subchannel::line, skinny_subchannel::lock, skinny_subchannel::rtp, sub, and ast_channel::tech_pvt.

03233 {
03234    struct skinny_subchannel *sub = NULL;
03235    struct skinny_line *l;
03236    enum ast_rtp_glue_result res = AST_RTP_GLUE_RESULT_REMOTE;
03237 
03238    if (skinnydebug)
03239       ast_verb(1, "skinny_get_rtp_peer() Channel = %s\n", ast_channel_name(c));
03240 
03241 
03242    if (!(sub = c->tech_pvt))
03243       return AST_RTP_GLUE_RESULT_FORBID;
03244 
03245    ast_mutex_lock(&sub->lock);
03246 
03247    if (!(sub->rtp)){
03248       ast_mutex_unlock(&sub->lock);
03249       return AST_RTP_GLUE_RESULT_FORBID;
03250    }
03251 
03252    ao2_ref(sub->rtp, +1);
03253    *instance = sub->rtp;
03254 
03255    l = sub->line;
03256 
03257    if (!l->directmedia || l->nat){
03258       res = AST_RTP_GLUE_RESULT_LOCAL;
03259       if (skinnydebug)
03260          ast_verb(1, "skinny_get_rtp_peer() Using AST_RTP_GLUE_RESULT_LOCAL \n");
03261    }
03262 
03263    ast_mutex_unlock(&sub->lock);
03264 
03265    return res;
03266 
03267 }

static enum ast_rtp_glue_result skinny_get_vrtp_peer ( struct ast_channel c,
struct ast_rtp_instance **  instance 
) [static]

Definition at line 3219 of file chan_skinny.c.

References ao2_ref, AST_RTP_GLUE_RESULT_FORBID, AST_RTP_GLUE_RESULT_REMOTE, sub, ast_channel::tech_pvt, and skinny_subchannel::vrtp.

03220 {
03221    struct skinny_subchannel *sub = NULL;
03222 
03223    if (!(sub = c->tech_pvt) || !(sub->vrtp))
03224       return AST_RTP_GLUE_RESULT_FORBID;
03225 
03226    ao2_ref(sub->vrtp, +1);
03227    *instance = sub->vrtp;
03228 
03229    return AST_RTP_GLUE_RESULT_REMOTE;
03230 }

static int skinny_hangup ( struct ast_channel ast  )  [static]

Definition at line 4435 of file chan_skinny.c.

References ast_debug, ast_free, ast_module_unref(), ast_mutex_lock, ast_mutex_unlock, ast_rtp_instance_destroy(), ast_verb, skinny_subchannel::callid, dumpsub(), skinny_subchannel::lock, skinny_subchannel::owner, skinny_subchannel::rtp, sub, and ast_channel::tech_pvt.

04436 {
04437    struct skinny_subchannel *sub = ast->tech_pvt;
04438 
04439    if (!sub) {
04440       ast_debug(1, "Asked to hangup channel not connected\n");
04441       return 0;
04442    }
04443    
04444    dumpsub(sub, 1);
04445 
04446    if (skinnydebug)
04447       ast_verb(3,"Sub %d - Destroying\n", sub->callid);
04448 
04449    ast_mutex_lock(&sub->lock);
04450    sub->owner = NULL;
04451    ast->tech_pvt = NULL;
04452    if (sub->rtp) {
04453       ast_rtp_instance_destroy(sub->rtp);
04454       sub->rtp = NULL;
04455    }
04456    ast_mutex_unlock(&sub->lock);
04457    ast_free(sub);
04458    ast_module_unref(ast_module_info->self);
04459    return 0;
04460 }

static int skinny_indicate ( struct ast_channel ast,
int  ind,
const void *  data,
size_t  datalen 
) [static]

Definition at line 4770 of file chan_skinny.c.

References ast_channel_name(), AST_CONTROL_BUSY, AST_CONTROL_CONGESTION, AST_CONTROL_CONNECTED_LINE, AST_CONTROL_HOLD, AST_CONTROL_INCOMPLETE, AST_CONTROL_PROCEEDING, AST_CONTROL_PROGRESS, AST_CONTROL_RINGING, AST_CONTROL_SRCCHANGE, AST_CONTROL_SRCUPDATE, AST_CONTROL_UNHOLD, ast_debug, ast_log(), ast_moh_start(), ast_moh_stop(), ast_rtp_instance_change_source(), ast_rtp_instance_update_source(), ast_verb, skinny_subchannel::blindxfer, skinny_subchannel::callid, control2str(), skinny_line::device, skinny_subchannel::line, LOG_NOTICE, LOG_WARNING, skinny_subchannel::rtp, skinny_device::session, setsubstate(), skinny_transfer(), sub, SUBSTATE_BUSY, SUBSTATE_CONGESTION, SUBSTATE_PROGRESS, SUBSTATE_RINGOUT, ast_channel::tech_pvt, transmit_stop_tone(), and update_connectedline().

04771 {
04772    struct skinny_subchannel *sub = ast->tech_pvt;
04773    struct skinny_line *l = sub->line;
04774    struct skinny_device *d = l->device;
04775    struct skinnysession *s = d->session;
04776 
04777    if (!s) {
04778       ast_log(LOG_NOTICE, "Asked to indicate '%s' condition on channel %s, but session does not exist.\n", control2str(ind), ast_channel_name(ast));
04779       return -1;
04780    }
04781 
04782    if (skinnydebug)
04783       ast_verb(3, "Asked to indicate '%s' condition on channel %s\n", control2str(ind), ast_channel_name(ast));
04784    switch(ind) {
04785    case AST_CONTROL_RINGING:
04786       if (sub->blindxfer) {
04787          if (skinnydebug)
04788             ast_debug(1, "Channel %s set up for Blind Xfer, so Xfer rather than ring device\n", ast_channel_name(ast));
04789          skinny_transfer(sub);
04790          break;
04791       }
04792       setsubstate(sub, SUBSTATE_RINGOUT);
04793       return (d->earlyrtp ? -1 : 0); /* Tell asterisk to provide inband signalling if rtp started */
04794    case AST_CONTROL_BUSY:
04795       setsubstate(sub, SUBSTATE_BUSY);
04796       return (d->earlyrtp ? -1 : 0); /* Tell asterisk to provide inband signalling if rtp started */
04797    case AST_CONTROL_INCOMPLETE:
04798       /* Support for incomplete not supported for chan_skinny; treat as congestion */
04799    case AST_CONTROL_CONGESTION:
04800       setsubstate(sub, SUBSTATE_CONGESTION);
04801       return (d->earlyrtp ? -1 : 0); /* Tell asterisk to provide inband signalling if rtp started */
04802    case AST_CONTROL_PROGRESS:
04803       setsubstate(sub, SUBSTATE_PROGRESS);
04804       return (d->earlyrtp ? -1 : 0); /* Tell asterisk to provide inband signalling if rtp started */
04805    case -1:  /* STOP_TONE */
04806       transmit_stop_tone(d, l->instance, sub->callid);
04807       break;
04808    case AST_CONTROL_HOLD:
04809       ast_moh_start(ast, data, l->mohinterpret);
04810       break;
04811    case AST_CONTROL_UNHOLD:
04812       ast_moh_stop(ast);
04813       break;
04814    case AST_CONTROL_PROCEEDING:
04815       break;
04816    case AST_CONTROL_SRCUPDATE:
04817       if (sub->rtp) {
04818          ast_rtp_instance_update_source(sub->rtp);
04819       }
04820       break;
04821    case AST_CONTROL_SRCCHANGE:
04822       if (sub->rtp) {
04823          ast_rtp_instance_change_source(sub->rtp);
04824       }
04825       break;
04826    case AST_CONTROL_CONNECTED_LINE:
04827       update_connectedline(sub, data, datalen);
04828       break;
04829    default:
04830       ast_log(LOG_WARNING, "Don't know how to indicate condition %d\n", ind);
04831       return -1; /* Tell asterisk to provide inband signalling */
04832    }
04833    return 0;
04834 }

static struct skinny_line* skinny_line_alloc ( void   )  [static, read]

Definition at line 1516 of file chan_skinny.c.

References ast_calloc, ast_format_cap_alloc_nolock(), ast_format_cap_destroy(), ast_free, skinny_line::cap, and skinny_line::confcap.

Referenced by config_line().

01517 {
01518    struct skinny_line *l;
01519    if (!(l = ast_calloc(1, sizeof(*l)))) {
01520       return NULL;
01521    }
01522 
01523    l->cap = ast_format_cap_alloc_nolock();
01524    l->confcap = ast_format_cap_alloc_nolock();
01525    if (!l->cap || !l->confcap) {
01526       l->cap = ast_format_cap_destroy(l->cap);
01527       l->confcap = ast_format_cap_destroy(l->confcap);
01528       ast_free(l);
01529       return NULL;
01530    }
01531    return l;
01532 }

static struct skinny_line* skinny_line_destroy ( struct skinny_line l  )  [static, read]

Definition at line 1533 of file chan_skinny.c.

References ast_format_cap_destroy(), ast_free, skinny_line::cap, skinny_line::confcap, and skinny_line::container.

Referenced by config_line(), delete_devices(), and skinny_reload().

01534 {
01535    l->cap = ast_format_cap_destroy(l->cap);
01536    l->confcap = ast_format_cap_destroy(l->confcap);
01537    ast_free(l->container);
01538    ast_free(l);
01539    return NULL;
01540 }

static struct ast_channel* skinny_new ( struct skinny_line l,
struct skinny_subline subline,
int  state,
const char *  linkedid,
int  direction 
) [static, read]

Definition at line 4836 of file chan_skinny.c.

References ast_channel::adsicpe, ast_channel::amaflags, ast_party_caller::ani, AST_ADSI_UNAVAILABLE, ast_best_codec(), ast_calloc, ast_channel_alloc, ast_channel_name(), ast_channel_set_fd(), ast_copy_string(), AST_DEVICE_NOT_INUSE, ast_format_cap_copy(), ast_format_cap_is_empty(), ast_format_copy(), 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_strlen_zero(), ast_verb, skinny_subchannel::blindxfer, skinny_subchannel::calldirection, ast_channel::caller, ast_channel::callgroup, skinny_subchannel::callid, skinny_line::cap, skinny_line::chanvars, skinny_subline::context, ast_channel::context, skinny_subchannel::cxmode, skinny_line::device, ast_channel::exten, get_devicestate(), global_jbconf, skinny_subchannel::line, skinny_subchannel::lock, LOG_WARNING, ast_variable::name, skinny_subchannel::nat, ast_channel::nativeformats, ast_variable::next, ast_party_id::number, skinny_subchannel::owner, pbx_builtin_setvar_helper(), ast_channel::pickupgroup, ast_channel::priority, ast_channel::rawreadformat, ast_channel::rawwriteformat, ast_channel::readformat, skinny_subchannel::related, ast_channel::rings, skinny_subchannel::rtp, SKINNY_CFWD_ALL, SKINNY_CFWD_BUSY, SKINNY_CX_INACTIVE, skinny_tech, ast_party_number::str, skinny_line::sub, skinny_subline::sub, sub, skinny_subchannel::subline, ast_channel::tech, ast_channel::tech_pvt, ast_party_number::valid, ast_variable::value, ast_channel::writeformat, and skinny_subchannel::xferor.

Referenced by handle_enbloc_call_message(), handle_offhook_message(), handle_soft_key_event_message(), handle_stimulus_message(), handle_transfer_button(), and skinny_request().

04837 {
04838    struct ast_channel *tmp;
04839    struct skinny_subchannel *sub;
04840    struct skinny_device *d = l->device;
04841    struct ast_variable *v = NULL;
04842    struct ast_format tmpfmt;
04843 
04844    if (!l->device) {
04845       ast_log(LOG_WARNING, "Device for line %s is not registered.\n", l->name);
04846       return NULL;
04847    }
04848 
04849    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);
04850    if (!tmp) {
04851       ast_log(LOG_WARNING, "Unable to allocate channel structure\n");
04852       return NULL;
04853    } else {
04854       sub = ast_calloc(1, sizeof(*sub));
04855       if (!sub) {
04856          ast_log(LOG_WARNING, "Unable to allocate Skinny subchannel\n");
04857          return NULL;
04858       } else {
04859          ast_mutex_init(&sub->lock);
04860 
04861          sub->owner = tmp;
04862          sub->callid = callnums++;
04863          d->lastlineinstance = l->instance;
04864          d->lastcallreference = sub->callid;
04865          sub->cxmode = SKINNY_CX_INACTIVE;
04866          sub->nat = l->nat;
04867          sub->line = l;
04868          sub->blindxfer = 0;
04869          sub->xferor = 0;
04870          sub->related = NULL;
04871          sub->calldirection = direction;
04872 
04873          if (subline) {
04874             sub->subline = subline;
04875             subline->sub = sub;
04876          } else {
04877             sub->subline = NULL;
04878          }
04879          
04880          AST_LIST_INSERT_HEAD(&l->sub, sub, list);
04881          //l->activesub = sub;
04882       }
04883       tmp->tech = &skinny_tech;
04884       tmp->tech_pvt = sub;
04885       ast_format_cap_copy(tmp->nativeformats, l->cap);
04886       if (ast_format_cap_is_empty(tmp->nativeformats)) {
04887          // Should throw an error
04888          ast_format_cap_copy(tmp->nativeformats, default_cap);
04889       }
04890       ast_best_codec(tmp->nativeformats, &tmpfmt);
04891       if (skinnydebug) {
04892          char buf[256];
04893          ast_verb(1, "skinny_new: tmp->nativeformats=%s fmt=%s\n",
04894             ast_getformatname_multiple(buf, sizeof(buf), tmp->nativeformats),
04895             ast_getformatname(&tmpfmt));
04896       }
04897       if (sub->rtp) {
04898          ast_channel_set_fd(tmp, 0, ast_rtp_instance_fd(sub->rtp, 0));
04899       }
04900       if (state == AST_STATE_RING) {
04901          tmp->rings = 1;
04902       }
04903       ast_format_copy(&tmp->writeformat, &tmpfmt);
04904       ast_format_copy(&tmp->rawwriteformat, &tmpfmt);
04905       ast_format_copy(&tmp->readformat, &tmpfmt);
04906       ast_format_copy(&tmp->rawreadformat, &tmpfmt);
04907 
04908       if (!ast_strlen_zero(l->language))
04909          ast_channel_language_set(tmp, l->language);
04910       if (!ast_strlen_zero(l->accountcode))
04911          ast_channel_accountcode_set(tmp, l->accountcode);
04912       if (!ast_strlen_zero(l->parkinglot))
04913          ast_channel_parkinglot_set(tmp, l->parkinglot);
04914       if (l->amaflags)
04915          tmp->amaflags = l->amaflags;
04916 
04917       ast_module_ref(ast_module_info->self);
04918       tmp->callgroup = l->callgroup;
04919       tmp->pickupgroup = l->pickupgroup;
04920 
04921       /* XXX Need to figure out how to handle CFwdNoAnswer */
04922       if (l->cfwdtype & SKINNY_CFWD_ALL) {
04923          ast_channel_call_forward_set(tmp, l->call_forward_all);
04924       } else if (l->cfwdtype & SKINNY_CFWD_BUSY) {
04925          if (get_devicestate(l) != AST_DEVICE_NOT_INUSE) {
04926             ast_channel_call_forward_set(tmp, l->call_forward_busy);
04927          }
04928       }
04929 
04930       if (subline) {
04931          ast_copy_string(tmp->context, subline->context, sizeof(tmp->context));
04932       } else {
04933          ast_copy_string(tmp->context, l->context, sizeof(tmp->context));
04934       }
04935       ast_copy_string(tmp->exten, l->exten, sizeof(tmp->exten));
04936 
04937       /* Don't use ast_set_callerid() here because it will
04938        * generate a needless NewCallerID event */
04939       if (!ast_strlen_zero(l->cid_num)) {
04940          tmp->caller.ani.number.valid = 1;
04941          tmp->caller.ani.number.str = ast_strdup(l->cid_num);
04942       }
04943 
04944       tmp->priority = 1;
04945       tmp->adsicpe = AST_ADSI_UNAVAILABLE;
04946 
04947       if (sub->rtp)
04948          ast_jb_configure(tmp, &global_jbconf);
04949 
04950       /* Set channel variables for this call from configuration */
04951       for (v = l->chanvars ; v ; v = v->next)
04952          pbx_builtin_setvar_helper(tmp, v->name, v->value);
04953 
04954       if (state != AST_STATE_DOWN) {
04955          if (ast_pbx_start(tmp)) {
04956             ast_log(LOG_WARNING, "Unable to start PBX on %s\n", ast_channel_name(tmp));
04957             ast_hangup(tmp);
04958             tmp = NULL;
04959          }
04960       }
04961    }
04962    return tmp;
04963 }

static void* skinny_newcall ( void *  data  )  [static]

Definition at line 4222 of file chan_skinny.c.

References ast_party_caller::ani, 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_verb, ast_channel::caller, skinny_subchannel::callid, ast_channel::connected, ast_channel::context, skinny_line::device, ast_channel::exten, ast_party_connected_line::id, skinny_subchannel::line, LOG_WARNING, ast_party_id::name, ast_party_id::number, skinny_subchannel::rtp, SKINNY_REORDER, start_rtp(), ast_party_number::str, sub, ast_channel::tech_pvt, transmit_start_tone(), and ast_party_number::valid.

Referenced by setsubstate().

04223 {
04224    struct ast_channel *c = data;
04225    struct skinny_subchannel *sub = c->tech_pvt;
04226    struct skinny_line *l = sub->line;
04227    struct skinny_device *d = l->device;
04228    int res = 0;
04229 
04230    ast_set_callerid(c,
04231       l->hidecallerid ? "" : l->cid_num,
04232       l->hidecallerid ? "" : l->cid_name,
04233       c->caller.ani.number.valid ? NULL : l->cid_num);
04234 #if 1 /* XXX This code is probably not necessary */
04235    ast_party_number_free(&c->connected.id.number);
04236    ast_party_number_init(&c->connected.id.number);
04237    c->connected.id.number.valid = 1;
04238    c->connected.id.number.str = ast_strdup(c->exten);
04239    ast_party_name_free(&c->connected.id.name);
04240    ast_party_name_init(&c->connected.id.name);
04241 #endif
04242    ast_setstate(c, AST_STATE_RING);
04243    if (!sub->rtp) {
04244       start_rtp(sub);
04245    }
04246    ast_verb(3, "Sub %d - Calling %s@%s\n", sub->callid, c->exten, c->context);
04247    res = ast_pbx_run(c);
04248    if (res) {
04249       ast_log(LOG_WARNING, "PBX exited non-zero\n");
04250       transmit_start_tone(d, SKINNY_REORDER, l->instance, sub->callid);
04251    }
04252    return NULL;
04253 }

static struct ast_frame * skinny_read ( struct ast_channel ast  )  [static, read]

Definition at line 4536 of file chan_skinny.c.

References ast_mutex_lock, ast_mutex_unlock, skinny_subchannel::lock, skinny_rtp_read(), sub, and ast_channel::tech_pvt.

04537 {
04538    struct ast_frame *fr;
04539    struct skinny_subchannel *sub = ast->tech_pvt;
04540    ast_mutex_lock(&sub->lock);
04541    fr = skinny_rtp_read(sub);
04542    ast_mutex_unlock(&sub->lock);
04543    return fr;
04544 }

static int skinny_register ( struct skinny_req req,
struct skinnysession s 
) [static]

Definition at line 2074 of file chan_skinny.c.

References __ourip, ast_app_has_voicemail(), ast_apply_ha(), ast_copy_string(), AST_DEVICE_NOT_INUSE, ast_devstate_changed(), ast_extension_state_add(), ast_format_cap_joint_copy(), AST_LIST_LOCK, AST_LIST_TRAVERSE, AST_LIST_UNLOCK, ast_log(), ast_sockaddr_from_sin, ast_strlen_zero(), ast_verb, skinny_line::cap, skinny_device::cap, skinny_line::confcap, skinny_subline::container, skinny_speeddial::container, skinny_subline::context, skinny_speeddial::context, skinny_req::data, skinny_line::device, skinnysession::device, EVENT_FLAG_SYSTEM, skinny_subline::exten, skinny_speeddial::exten, skinnysession::fd, skinny_device::ha, letohl, skinny_device::lines, LOG_WARNING, manager_event, mwi_event_cb(), register_message::name, skinny_line::newmsgs, skinny_device::ourip, register_message::protocolVersion, skinny_data::reg, register_exten(), skinny_device::session, set_callforwards(), skinnysession::sin, skinny_extensionstate_cb(), skinny_device::speeddials, skinny_speeddial::stateid, skinny_line::sublines, and register_message::type.

Referenced by handle_message().

02075 {
02076    struct skinny_device *d;
02077    struct skinny_line *l;
02078    struct skinny_subline *subline;
02079    struct skinny_speeddial *sd;
02080    struct sockaddr_in sin;
02081    socklen_t slen;
02082    int instance;
02083 
02084    AST_LIST_LOCK(&devices);
02085    AST_LIST_TRAVERSE(&devices, d, list){
02086       struct ast_sockaddr addr;
02087       ast_sockaddr_from_sin(&addr, &s->sin);
02088       if (!strcasecmp(req->data.reg.name, d->id)
02089             && ast_apply_ha(d->ha, &addr)) {
02090          s->device = d;
02091          d->type = letohl(req->data.reg.type);
02092          d->protocolversion = letohl(req->data.reg.protocolVersion);
02093          if (ast_strlen_zero(d->version_id)) {
02094             ast_copy_string(d->version_id, version_id, sizeof(d->version_id));
02095          }
02096          d->registered = 1;
02097          d->session = s;
02098 
02099          slen = sizeof(sin);
02100          if (getsockname(s->fd, (struct sockaddr *)&sin, &slen)) {
02101             ast_log(LOG_WARNING, "Cannot get socket name\n");
02102             sin.sin_addr = __ourip;
02103          }
02104          d->ourip = sin.sin_addr;
02105 
02106          AST_LIST_TRAVERSE(&d->speeddials, sd, list) {
02107             sd->stateid = ast_extension_state_add(sd->context, sd->exten, skinny_extensionstate_cb, sd->container);
02108          }
02109          instance = 0;
02110          AST_LIST_TRAVERSE(&d->lines, l, list) {
02111             instance++;
02112          }
02113          AST_LIST_TRAVERSE(&d->lines, l, list) {
02114             /* FIXME: All sorts of issues will occur if this line is already connected to a device */
02115             if (l->device) {
02116                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); 
02117                ast_verb(1, "Line %s already connected to %s. Not connecting to %s.\n", l->name, l->device->name, d->name);
02118             } else {
02119                l->device = d;
02120                ast_format_cap_joint_copy(l->confcap, d->cap, l->cap);
02121                l->prefs = l->confprefs;
02122                if (!l->prefs.order[0]) {
02123                   l->prefs = d->confprefs;
02124                }
02125                /* l->capability = d->capability;
02126                l->prefs = d->prefs; */
02127                l->instance = instance;
02128                l->newmsgs = ast_app_has_voicemail(l->mailbox, NULL);
02129                set_callforwards(l, NULL, 0);
02130                manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", "ChannelType: Skinny\r\nPeer: Skinny/%s@%s\r\nPeerStatus: Registered\r\n", l->name, d->name);
02131                register_exten(l);
02132                /* initialize MWI on line and device */
02133                mwi_event_cb(0, l);
02134                AST_LIST_TRAVERSE(&l->sublines, subline, list) {
02135                   ast_extension_state_add(subline->context, subline->exten, skinny_extensionstate_cb, subline->container);
02136                }
02137                ast_devstate_changed(AST_DEVICE_NOT_INUSE, "Skinny/%s", l->name);
02138             }
02139             --instance;
02140          }
02141          break;
02142       }
02143    }
02144    AST_LIST_UNLOCK(&devices);
02145    if (!d) {
02146       return 0;
02147    }
02148    return 1;
02149 }

int skinny_reload ( void   )  [static]

Definition at line 7879 of file chan_skinny.c.

References skinny_device::addons, AST_LIST_LOCK, AST_LIST_REMOVE_CURRENT, AST_LIST_REMOVE_HEAD, AST_LIST_TRAVERSE, AST_LIST_TRAVERSE_SAFE_BEGIN, AST_LIST_TRAVERSE_SAFE_END, AST_LIST_UNLOCK, ast_verb, config_load(), skinny_req::data, free, skinny_device::lines, req_alloc(), skinny_data::reset, RESET_MESSAGE, reset_message::resetType, skinny_device::session, skinny_device_destroy(), skinny_line_destroy(), skinny_device::speeddials, and transmit_response().

Referenced by handle_skinny_reload(), and reload().

07880 {
07881    struct skinny_device *d;
07882    struct skinny_line *l;
07883    struct skinny_speeddial *sd;
07884    struct skinny_addon *a;
07885    struct skinny_req *req;
07886 
07887    if (skinnyreload) {
07888       ast_verb(3, "Chan_skinny is already reloading.\n");
07889       return 0;
07890    }
07891 
07892    skinnyreload = 1;
07893 
07894    /* Mark all devices and lines as candidates to be pruned */
07895    AST_LIST_LOCK(&devices);
07896    AST_LIST_TRAVERSE(&devices, d, list) {
07897       d->prune = 1;
07898    }
07899    AST_LIST_UNLOCK(&devices);
07900 
07901    AST_LIST_LOCK(&lines);
07902    AST_LIST_TRAVERSE(&lines, l, all) {
07903       l->prune = 1;
07904    }
07905    AST_LIST_UNLOCK(&lines);
07906 
07907         config_load();
07908 
07909    /* Remove any devices that no longer exist in the config */
07910    AST_LIST_LOCK(&devices);
07911    AST_LIST_TRAVERSE_SAFE_BEGIN(&devices, d, list) {
07912       if (!d->prune) {
07913          continue;
07914       }
07915       ast_verb(3, "Removing device '%s'\n", d->name);
07916       /* Delete all lines for this device. 
07917          We do not want to free the line here, that
07918          will happen below. */
07919       while ((l = AST_LIST_REMOVE_HEAD(&d->lines, list))) {
07920       }
07921       /* Delete all speeddials for this device */
07922       while ((sd = AST_LIST_REMOVE_HEAD(&d->speeddials, list))) {
07923          free(sd);
07924       }
07925       /* Delete all addons for this device */
07926       while ((a = AST_LIST_REMOVE_HEAD(&d->addons, list))) {
07927          free(a);
07928       }
07929       AST_LIST_REMOVE_CURRENT(list);
07930       d = skinny_device_destroy(d);
07931    }
07932    AST_LIST_TRAVERSE_SAFE_END;
07933    AST_LIST_UNLOCK(&devices);
07934 
07935    AST_LIST_LOCK(&lines);  
07936    AST_LIST_TRAVERSE_SAFE_BEGIN(&lines, l, all) {
07937       if (l->prune) {
07938          AST_LIST_REMOVE_CURRENT(all);
07939          l = skinny_line_destroy(l);
07940       }
07941    }
07942    AST_LIST_TRAVERSE_SAFE_END;
07943    AST_LIST_UNLOCK(&lines);  
07944 
07945    AST_LIST_TRAVERSE(&devices, d, list) {
07946       /* Do a soft reset to re-register the devices after
07947          cleaning up the removed devices and lines */
07948       if (d->session) {
07949          ast_verb(3, "Restarting device '%s'\n", d->name);
07950          if ((req = req_alloc(sizeof(struct reset_message), RESET_MESSAGE))) {
07951             req->data.reset.resetType = 2;
07952             transmit_response(d, req);
07953          }
07954       }
07955    }
07956    
07957    skinnyreload = 0;
07958         return 0;
07959 }

static struct skinny_req* skinny_req_parse ( struct skinnysession s  )  [static, read]

Definition at line 6943 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().

06944 {
06945    struct skinny_req *req;
06946    int *bufaddr;
06947 
06948    if (!(req = ast_calloc(1, SKINNY_MAX_PACKET)))
06949       return NULL;
06950 
06951    ast_mutex_lock(&s->lock);
06952    memcpy(req, s->inbuf, skinny_header_size);
06953    bufaddr = (int *)(s->inbuf);
06954    memcpy(&req->data, s->inbuf+skinny_header_size, letohl(*bufaddr)-4);
06955 
06956    ast_mutex_unlock(&s->lock);
06957 
06958    if (letohl(req->e) < 0) {
06959       ast_log(LOG_ERROR, "Event Message is NULL from socket %d, This is bad\n", s->fd);
06960       ast_free(req);
06961       return NULL;
06962    }
06963 
06964    return req;
06965 }

static struct ast_channel * skinny_request ( const char *  type,
struct ast_format_cap cap,
const struct ast_channel requestor,
const char *  dest,
int *  cause 
) [static, read]

Definition at line 7077 of file chan_skinny.c.

References ast_channel_linkedid(), ast_copy_string(), ast_format_cap_has_type(), AST_FORMAT_TYPE_AUDIO, ast_getformatname_multiple(), ast_log(), AST_STATE_DOWN, ast_strlen_zero(), ast_verb, skinny_subline::calldirection, skinny_subchannel::callid, skinny_subline::callid, find_line_by_name(), find_subline_by_name(), skinny_subline::line, LOG_NOTICE, LOG_WARNING, SKINNY_INCOMING, skinny_new(), skinny_subline::sub, sub, skinny_subchannel::subline, skinny_subline::substate, SUBSTATE_UNSET, and ast_channel::tech_pvt.

07078 {
07079    struct skinny_line *l;
07080    struct skinny_subline *subline = NULL;
07081    struct ast_channel *tmpc = NULL;
07082    char tmp[256];
07083 
07084    if (!(ast_format_cap_has_type(cap, AST_FORMAT_TYPE_AUDIO))) {
07085       ast_log(LOG_NOTICE, "Asked to get a channel of unsupported format '%s'\n", ast_getformatname_multiple(tmp, sizeof(tmp), cap));
07086       return NULL;
07087    }
07088 
07089    ast_copy_string(tmp, dest, sizeof(tmp));
07090    if (ast_strlen_zero(tmp)) {
07091       ast_log(LOG_NOTICE, "Skinny channels require a device\n");
07092       return NULL;
07093    }
07094    l = find_line_by_name(tmp);
07095    if (!l) {
07096       subline = find_subline_by_name(tmp);
07097       if (!subline) {
07098          ast_log(LOG_NOTICE, "No available lines on: %s\n", dest);
07099          return NULL;
07100       }
07101       l = subline->line;
07102    }
07103    ast_verb(3, "skinny_request(%s)\n", tmp);
07104    tmpc = skinny_new(l, subline, AST_STATE_DOWN, requestor ? ast_channel_linkedid(requestor) : NULL, SKINNY_INCOMING);
07105    if (!tmpc) {
07106       ast_log(LOG_WARNING, "Unable to make channel for '%s'\n", tmp);
07107    } else if (subline) {
07108       struct skinny_subchannel *sub = tmpc->tech_pvt;
07109       subline->sub = sub;
07110       subline->calldirection = SKINNY_INCOMING;
07111       subline->substate = SUBSTATE_UNSET;
07112       subline->callid = sub->callid;
07113       sub->subline = subline;
07114    }
07115    return tmpc;
07116 }

static struct ast_frame* skinny_rtp_read ( struct skinny_subchannel sub  )  [static, read]

Definition at line 4489 of file chan_skinny.c.

References ast_debug, ast_format_cap_iscompatible(), ast_format_cap_set(), 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_frame_subclass::format, ast_frame::frametype, ast_channel::nativeformats, skinny_subchannel::owner, ast_channel::readformat, skinny_subchannel::rtp, ast_frame::subclass, skinny_subchannel::vrtp, and ast_channel::writeformat.

Referenced by skinny_read().

04490 {
04491    struct ast_channel *ast = sub->owner;
04492    struct ast_frame *f;
04493 
04494    if (!sub->rtp) {
04495       /* We have no RTP allocated for this channel */
04496       return &ast_null_frame;
04497    }
04498 
04499    switch(ast->fdno) {
04500    case 0:
04501       f = ast_rtp_instance_read(sub->rtp, 0); /* RTP Audio */
04502       break;
04503    case 1:
04504       f = ast_rtp_instance_read(sub->rtp, 1); /* RTCP Control Channel */
04505       break;
04506    case 2:
04507       f = ast_rtp_instance_read(sub->vrtp, 0); /* RTP Video */
04508       break;
04509    case 3:
04510       f = ast_rtp_instance_read(sub->vrtp, 1); /* RTCP Control Channel for video */
04511       break;
04512 #if 0
04513    case 5:
04514       /* Not yet supported */
04515       f = ast_udptl_read(sub->udptl); /* UDPTL for T.38 */
04516       break;
04517 #endif
04518    default:
04519       f = &ast_null_frame;
04520    }
04521 
04522    if (ast) {
04523       /* We already hold the channel lock */
04524       if (f->frametype == AST_FRAME_VOICE) {
04525          if (!(ast_format_cap_iscompatible(ast->nativeformats, &f->subclass.format))) {
04526             ast_debug(1, "Oooh, format changed to %s\n", ast_getformatname(&f->subclass.format));
04527             ast_format_cap_set(ast->nativeformats, &f->subclass.format);
04528             ast_set_read_format(ast, &ast->readformat);
04529             ast_set_write_format(ast, &ast->writeformat);
04530          }
04531       }
04532    }
04533    return f;
04534 }

static int skinny_sched_add ( int  when,
ast_sched_cb  callback,
const void *  data 
) [static]

Definition at line 1850 of file chan_skinny.c.

References ast_sched_add().

Referenced by skinny_call().

01851 {
01852    return ast_sched_add(sched, when, callback, data);
01853 }

static int skinny_sched_del ( int  sched_id  )  [static]

Definition at line 1845 of file chan_skinny.c.

References ast_sched_del().

Referenced by setsubstate().

01846 {
01847    return ast_sched_del(sched, sched_id);
01848 }

static int skinny_senddigit_begin ( struct ast_channel ast,
char  digit 
) [static]

Definition at line 4590 of file chan_skinny.c.

04591 {
04592    return -1; /* Start inband indications */
04593 }

static int skinny_senddigit_end ( struct ast_channel ast,
char  digit,
unsigned int  duration 
) [static]

Definition at line 4595 of file chan_skinny.c.

References skinny_line::device, skinny_subchannel::line, sub, and ast_channel::tech_pvt.

04596 {
04597 #if 0
04598    struct skinny_subchannel *sub = ast->tech_pvt;
04599    struct skinny_line *l = sub->line;
04600    struct skinny_device *d = l->device;
04601    int tmp;
04602    /* not right */
04603    sprintf(tmp, "%d", digit);
04604    //transmit_tone(d, digit, l->instance, sub->callid);
04605 #endif
04606    return -1; /* Stop inband indications */
04607 }

static void* skinny_session ( void *  data  )  [static]

Definition at line 6967 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().

06968 {
06969    int res;
06970    struct skinny_req *req;
06971    struct skinnysession *s = data;
06972 
06973    ast_verb(3, "Starting Skinny session from %s\n", ast_inet_ntoa(s->sin.sin_addr));
06974 
06975    for (;;) {
06976       res = get_input(s);
06977       if (res < 0) {
06978          ast_verb(3, "Ending Skinny session from %s (bad input)\n", ast_inet_ntoa(s->sin.sin_addr));
06979          break;
06980       }
06981 
06982       if (res > 0)
06983       {
06984          if (!(req = skinny_req_parse(s))) {
06985             destroy_session(s);
06986             ast_verb(3, "Ending Skinny session from %s (failed parse)\n", ast_inet_ntoa(s->sin.sin_addr));
06987             return NULL;
06988          }
06989 
06990          res = handle_message(req, s);
06991          if (res < 0) {
06992             destroy_session(s);
06993             ast_verb(3, "Ending Skinny session from %s\n", ast_inet_ntoa(s->sin.sin_addr));
06994             return NULL;
06995          }
06996       }
06997    }
06998    ast_debug(3, "Skinny Session returned: %s\n", strerror(errno));
06999 
07000    if (s)
07001       destroy_session(s);
07002 
07003    return 0;
07004 }

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,
const struct ast_format_cap codecs,
int  nat_active 
) [static]

Definition at line 3269 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, skinny_line::cap, ast_format_list::cur_ms, skinny_line::device, ast_format_list::format, skinny_device::ourip, sub, ast_channel::tech_pvt, transmit_startmediatransmission(), and transmit_stopmediatransmission().

03270 {
03271    struct skinny_subchannel *sub;
03272    struct skinny_line *l;
03273    struct skinny_device *d;
03274    struct ast_format_list fmt;
03275    struct sockaddr_in us = { 0, };
03276    struct sockaddr_in them = { 0, };
03277    struct ast_sockaddr them_tmp;
03278    struct ast_sockaddr us_tmp;
03279    
03280    sub = c->tech_pvt;
03281 
03282    if (c->_state != AST_STATE_UP)
03283       return 0;
03284 
03285    if (!sub) {
03286       return -1;
03287    }
03288 
03289    l = sub->line;
03290    d = l->device;
03291 
03292    if (rtp){
03293       struct ast_format tmpfmt;
03294       ast_rtp_instance_get_remote_address(rtp, &them_tmp);
03295       ast_sockaddr_to_sin(&them_tmp, &them);
03296 
03297       /* Shutdown any early-media or previous media on re-invite */
03298       transmit_stopmediatransmission(d, sub);
03299       
03300       if (skinnydebug)
03301          ast_verb(1, "Peerip = %s:%d\n", ast_inet_ntoa(them.sin_addr), ntohs(them.sin_port));
03302 
03303       ast_best_codec(l->cap, &tmpfmt);
03304       fmt = ast_codec_pref_getsize(&l->prefs, &tmpfmt);
03305 
03306       if (skinnydebug)
03307          ast_verb(1, "Setting payloadType to '%s' (%d ms)\n", ast_getformatname(&fmt.format), fmt.cur_ms);
03308 
03309       if (!(l->directmedia) || (l->nat)){
03310          ast_rtp_instance_get_local_address(rtp, &us_tmp);
03311          ast_sockaddr_to_sin(&us_tmp, &us);
03312          us.sin_addr.s_addr = us.sin_addr.s_addr ? us.sin_addr.s_addr : d->ourip.s_addr;
03313          transmit_startmediatransmission(d, sub, us, fmt);
03314       } else {
03315          transmit_startmediatransmission(d, sub, them, fmt);
03316       }
03317 
03318       return 0;
03319    }
03320    /* Need a return here to break the bridge */
03321    return 0;
03322 }

static void* skinny_ss ( void *  data  )  [static]

Definition at line 4255 of file chan_skinny.c.

References ast_channel::_state, skinny_line::activesub, ast_canmatch_extension(), ast_channel_name(), ast_debug, ast_exists_extension(), ast_hangup(), ast_ignore_pattern(), ast_indicate(), ast_log(), ast_matchmore_extension(), ast_safe_sleep(), AST_STATE_UP, ast_strlen_zero(), ast_verb, ast_channel::caller, skinny_subchannel::callid, ast_channel::context, skinny_line::device, dialandactivatesub(), skinny_subchannel::exten, ast_party_caller::id, len(), skinny_subchannel::line, LOG_WARNING, ast_party_id::number, skinny_subchannel::owner, S_COR, set_callforwards(), SKINNY_DIALTONE, SKINNY_LAMP_ON, SKINNY_OFFHOOK, SKINNY_REORDER, STIMULUS_FORWARDALL, ast_party_number::str, sub, skinny_subchannel::substate, SUBSTATE_OFFHOOK, ast_channel::tech_pvt, transmit_cfwdstate(), transmit_displaynotify(), transmit_lamp_indication(), transmit_start_tone(), transmit_stop_tone(), and ast_party_number::valid.

Referenced by setsubstate().

04256 {
04257    struct ast_channel *c = data;
04258    struct skinny_subchannel *sub = c->tech_pvt;
04259    struct skinny_line *l = sub->line;
04260    struct skinny_device *d = l->device;
04261    int len = 0;
04262    int timeout = firstdigittimeout;
04263    int res = 0;
04264    int loop_pause = 100;
04265 
04266    ast_verb(3, "Starting simple switch on '%s@%s'\n", l->name, d->name);
04267 
04268    len = strlen(sub->exten);
04269 
04270    while (len < AST_MAX_EXTENSION-1) {
04271       res = 1;  /* Assume that we will get a digit */
04272       while (strlen(sub->exten) == len){
04273          ast_safe_sleep(c, loop_pause);
04274          timeout -= loop_pause;
04275          if ( (timeout -= loop_pause) <= 0){
04276              res = 0;
04277              break;
04278          }
04279       res = 1;
04280       }
04281       
04282       if (sub != l->activesub) {
04283          break;
04284       }
04285 
04286       timeout = 0;
04287       len = strlen(sub->exten);
04288 
04289       if (!ast_ignore_pattern(c->context, sub->exten)) {
04290          transmit_stop_tone(d, l->instance, sub->callid);
04291       }
04292       if (ast_exists_extension(c, c->context, sub->exten, 1, l->cid_num)) {
04293          if (!res || !ast_matchmore_extension(c, c->context, sub->exten, 1, l->cid_num)) {
04294             if (l->getforward) {
04295                /* Record this as the forwarding extension */
04296                set_callforwards(l, sub->exten, l->getforward);
04297                ast_verb(3, "Setting call forward (%d) to '%s' on channel %s\n",
04298                      l->cfwdtype, sub->exten, ast_channel_name(c));
04299                transmit_start_tone(d, SKINNY_DIALTONE, l->instance, sub->callid);
04300                transmit_lamp_indication(d, STIMULUS_FORWARDALL, 1, SKINNY_LAMP_ON);
04301                transmit_displaynotify(d, "CFwd enabled", 10);
04302                transmit_cfwdstate(d, l);
04303                ast_safe_sleep(c, 500);
04304                ast_indicate(c, -1);
04305                ast_safe_sleep(c, 1000);
04306                len = 0;
04307                l->getforward = 0;
04308                if (sub->owner && sub->owner->_state != AST_STATE_UP) {
04309                   ast_indicate(c, -1);
04310                   ast_hangup(c);
04311                }
04312                return NULL;
04313             } else {
04314                if (sub->substate == SUBSTATE_OFFHOOK) {
04315                   dialandactivatesub(sub, sub->exten);
04316                }
04317                return NULL;
04318             }
04319          } else {
04320             /* It's a match, but they just typed a digit, and there is an ambiguous match,
04321                so just set the timeout to matchdigittimeout and wait some more */
04322             timeout = matchdigittimeout;
04323          }
04324       } else if (res == 0) {
04325          ast_debug(1, "Not enough digits (%s) (and no ambiguous match)...\n", sub->exten);
04326          if (d->hookstate == SKINNY_OFFHOOK) {
04327             transmit_start_tone(d, SKINNY_REORDER, l->instance, sub->callid);
04328          }
04329          if (sub->owner && sub->owner->_state != AST_STATE_UP) {
04330             ast_indicate(c, -1);
04331             ast_hangup(c);
04332          }
04333          return NULL;
04334       } else if (!ast_canmatch_extension(c, c->context, sub->exten, 1,
04335          S_COR(c->caller.id.number.valid, c->caller.id.number.str, NULL))
04336          && ((sub->exten[0] != '*') || (!ast_strlen_zero(sub->exten) > 2))) {
04337          ast_log(LOG_WARNING, "Can't match [%s] from '%s' in context %s\n", sub->exten,
04338             S_COR(c->caller.id.number.valid, c->caller.id.number.str, "<Unknown Caller>"),
04339             c->context);
04340          if (d->hookstate == SKINNY_OFFHOOK) {
04341             transmit_start_tone(d, SKINNY_REORDER, l->instance, sub->callid);
04342             /* hang out for 3 seconds to let congestion play */
04343             ast_safe_sleep(c, 3000);
04344          }
04345          break;
04346       }
04347       if (!timeout) {
04348          timeout = gendigittimeout;
04349       }
04350       if (len && !ast_ignore_pattern(c->context, sub->exten)) {
04351          ast_indicate(c, -1);
04352       }
04353    }
04354    if (c)
04355       ast_hangup(c);
04356    return NULL;
04357 }

static int skinny_transfer ( struct skinny_subchannel sub  )  [static]

Definition at line 4704 of file chan_skinny.c.

References ast_channel::_state, ast_bridged_channel(), ast_channel_masquerade(), ast_channel_name(), 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_WARNING, skinny_subchannel::owner, skinny_subchannel::related, skinny_subchannel::xferor, and ast_channel::zone.

Referenced by handle_transfer_button(), skinny_answer(), and skinny_indicate().

04705 {
04706    struct skinny_subchannel *xferor; /* the sub doing the transferring */
04707    struct skinny_subchannel *xferee; /* the sub being transferred */
04708    struct ast_tone_zone_sound *ts = NULL;
04709 
04710    if (ast_bridged_channel(sub->owner) || ast_bridged_channel(sub->related->owner)) {
04711       if (sub->xferor) {
04712          xferor = sub;
04713          xferee = sub->related;
04714       } else {
04715          xferor = sub;
04716          xferee = sub->related;
04717       }
04718 
04719       if (skinnydebug) {
04720          ast_debug(1, "Transferee channels (local/remote): %s and %s\n",
04721             ast_channel_name(xferee->owner), ast_bridged_channel(xferee->owner)?ast_channel_name(ast_bridged_channel(xferee->owner)):"");
04722          ast_debug(1, "Transferor channels (local/remote): %s and %s\n",
04723             ast_channel_name(xferor->owner), ast_bridged_channel(xferor->owner)?ast_channel_name(ast_bridged_channel(xferor->owner)):"");
04724       }
04725       if (ast_bridged_channel(xferor->owner)) {
04726          if (ast_bridged_channel(xferee->owner)) {
04727             ast_queue_control(xferee->owner, AST_CONTROL_UNHOLD);
04728          }
04729          if (xferor->owner->_state == AST_STATE_RING) {
04730             /* play ringing inband */
04731             if ((ts = ast_get_indication_tone(xferor->owner->zone, "ring"))) {
04732                ast_playtones_start(xferor->owner, 0, ts->data, 1);
04733                ts = ast_tone_zone_sound_unref(ts);
04734             }
04735          }
04736          if (skinnydebug)
04737             ast_debug(1, "Transfer Masquerading %s to %s\n",
04738                ast_channel_name(xferee->owner), ast_bridged_channel(xferor->owner)?ast_channel_name(ast_bridged_channel(xferor->owner)):"");
04739          if (ast_channel_masquerade(xferee->owner, ast_bridged_channel(xferor->owner))) {
04740             ast_log(LOG_WARNING, "Unable to masquerade %s as %s\n",
04741                ast_channel_name(ast_bridged_channel(xferor->owner)), ast_channel_name(xferee->owner));
04742             return -1;
04743          }
04744       } else if (ast_bridged_channel(xferee->owner)) {
04745          ast_queue_control(xferee->owner, AST_CONTROL_UNHOLD);
04746          if (xferor->owner->_state == AST_STATE_RING) {
04747             /* play ringing inband */
04748             if ((ts = ast_get_indication_tone(xferor->owner->zone, "ring"))) {
04749                ast_playtones_start(xferor->owner, 0, ts->data, 1);
04750                ts = ast_tone_zone_sound_unref(ts);
04751             }
04752          }
04753          if (skinnydebug)
04754             ast_debug(1, "Transfer Masquerading %s to %s\n",
04755                ast_channel_name(xferor->owner), ast_bridged_channel(xferee->owner)?ast_channel_name(ast_bridged_channel(xferee->owner)):"");
04756          if (ast_channel_masquerade(xferor->owner, ast_bridged_channel(xferee->owner))) {
04757             ast_log(LOG_WARNING, "Unable to masquerade %s as %s\n",
04758                ast_channel_name(ast_bridged_channel(xferee->owner)), ast_channel_name(xferor->owner));
04759             return -1;
04760          }
04761          return 0;
04762       } else {
04763          ast_debug(1, "Neither %s nor %s are in a bridge, nothing to transfer\n",
04764             ast_channel_name(xferor->owner), ast_channel_name(xferee->owner));
04765       }
04766    }
04767    return 0;
04768 }

static int skinny_unregister ( struct skinny_req req,
struct skinnysession s 
) [static]

Definition at line 2151 of file chan_skinny.c.

References AST_DEVICE_UNAVAILABLE, ast_devstate_changed(), ast_extension_state_del(), ast_format_cap_remove_all(), AST_LIST_TRAVERSE, ast_parse_allow_disallow(), skinny_line::cap, skinny_line::device, skinnysession::device, EVENT_FLAG_SYSTEM, skinny_device::lines, manager_event, skinny_device::session, skinny_device::speeddials, skinny_speeddial::stateid, and unregister_exten().

Referenced by get_input(), handle_message(), and transmit_response_bysession().

02152 {
02153    struct skinny_device *d;
02154    struct skinny_line *l;
02155    struct skinny_speeddial *sd;
02156 
02157    d = s->device;
02158 
02159    if (d) {
02160       d->session = NULL;
02161       d->registered = 0;
02162 
02163       AST_LIST_TRAVERSE(&d->speeddials, sd, list) {
02164          if (sd->stateid > -1)
02165             ast_extension_state_del(sd->stateid, NULL);
02166       }
02167       AST_LIST_TRAVERSE(&d->lines, l, list) {
02168          if (l->device == d) {
02169             l->device = NULL;
02170             ast_format_cap_remove_all(l->cap);
02171             ast_parse_allow_disallow(&l->prefs, l->cap, "all", 0);
02172             l->instance = 0;
02173             manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", "ChannelType: Skinny\r\nPeer: Skinny/%s@%s\r\nPeerStatus: Unregistered\r\n", l->name, d->name);
02174             unregister_exten(l);
02175             ast_devstate_changed(AST_DEVICE_UNAVAILABLE, "Skinny/%s", l->name);
02176          }
02177       }
02178    }
02179 
02180    return -1; /* main loop will destroy the session */
02181 }

static int skinny_write ( struct ast_channel ast,
struct ast_frame frame 
) [static]

Definition at line 4546 of file chan_skinny.c.

References ast_format_cap_iscompatible(), 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::format, ast_frame::frametype, skinny_subchannel::lock, LOG_WARNING, ast_channel::nativeformats, ast_channel::readformat, skinny_subchannel::rtp, sub, ast_frame::subclass, ast_channel::tech_pvt, and ast_channel::writeformat.

04547 {
04548    struct skinny_subchannel *sub = ast->tech_pvt;
04549    int res = 0;
04550    if (frame->frametype != AST_FRAME_VOICE) {
04551       if (frame->frametype == AST_FRAME_IMAGE) {
04552          return 0;
04553       } else {
04554          ast_log(LOG_WARNING, "Can't send %d type frames with skinny_write\n", frame->frametype);
04555          return 0;
04556       }
04557    } else {
04558       if (!(ast_format_cap_iscompatible(ast->nativeformats, &frame->subclass.format))) {
04559          char buf[256];
04560          ast_log(LOG_WARNING, "Asked to transmit frame type %s, while native formats is %s (read/write = %s/%s)\n",
04561             ast_getformatname(&frame->subclass.format),
04562             ast_getformatname_multiple(buf, sizeof(buf), ast->nativeformats),
04563             ast_getformatname(&ast->readformat),
04564             ast_getformatname(&ast->writeformat));
04565          return -1;
04566       }
04567    }
04568    if (sub) {
04569       ast_mutex_lock(&sub->lock);
04570       if (sub->rtp) {
04571          res = ast_rtp_instance_write(sub->rtp, frame);
04572       }
04573       ast_mutex_unlock(&sub->lock);
04574    }
04575    return res;
04576 }

static void start_rtp ( struct skinny_subchannel sub  )  [static]

Definition at line 4176 of file chan_skinny.c.

References ast_channel_set_fd(), ast_mutex_lock, ast_mutex_unlock, ast_rtp_codecs_packetization_set(), ast_rtp_instance_fd(), ast_rtp_instance_get_codecs(), ast_rtp_instance_new(), ast_rtp_instance_set_prop(), ast_rtp_instance_set_qos(), AST_RTP_PROPERTY_NAT, AST_RTP_PROPERTY_RTCP, ast_sockaddr_from_sin, bindaddr, skinny_line::device, skinny_subchannel::line, skinny_subchannel::lock, skinny_subchannel::owner, qos, skinny_subchannel::rtp, transmit_connect(), and skinny_subchannel::vrtp.

04177 {
04178    struct skinny_line *l = sub->line;
04179    struct skinny_device *d = l->device;
04180    int hasvideo = 0;
04181    struct ast_sockaddr bindaddr_tmp;
04182 
04183    ast_mutex_lock(&sub->lock);
04184    /* Allocate the RTP */
04185    ast_sockaddr_from_sin(&bindaddr_tmp, &bindaddr);
04186    sub->rtp = ast_rtp_instance_new("asterisk", sched, &bindaddr_tmp, NULL);
04187    if (hasvideo)
04188       sub->vrtp = ast_rtp_instance_new("asterisk", sched, &bindaddr_tmp, NULL);
04189 
04190    if (sub->rtp) {
04191       ast_rtp_instance_set_prop(sub->rtp, AST_RTP_PROPERTY_RTCP, 1);
04192    }
04193    if (sub->vrtp) {
04194       ast_rtp_instance_set_prop(sub->vrtp, AST_RTP_PROPERTY_RTCP, 1);
04195    }
04196 
04197    if (sub->rtp && sub->owner) {
04198       ast_channel_set_fd(sub->owner, 0, ast_rtp_instance_fd(sub->rtp, 0));
04199       ast_channel_set_fd(sub->owner, 1, ast_rtp_instance_fd(sub->rtp, 1));
04200    }
04201    if (hasvideo && sub->vrtp && sub->owner) {
04202       ast_channel_set_fd(sub->owner, 2, ast_rtp_instance_fd(sub->vrtp, 0));
04203       ast_channel_set_fd(sub->owner, 3, ast_rtp_instance_fd(sub->vrtp, 1));
04204    }
04205    if (sub->rtp) {
04206       ast_rtp_instance_set_qos(sub->rtp, qos.tos_audio, qos.cos_audio, "Skinny RTP");
04207       ast_rtp_instance_set_prop(sub->rtp, AST_RTP_PROPERTY_NAT, l->nat);
04208    }
04209    if (sub->vrtp) {
04210       ast_rtp_instance_set_qos(sub->vrtp, qos.tos_video, qos.cos_video, "Skinny VRTP");
04211       ast_rtp_instance_set_prop(sub->vrtp, AST_RTP_PROPERTY_NAT, l->nat);
04212    }
04213    /* Set Frame packetization */
04214    if (sub->rtp)
04215       ast_rtp_codecs_packetization_set(ast_rtp_instance_get_codecs(sub->rtp), sub->rtp, &l->prefs);
04216 
04217    /* Create the RTP connection */
04218    transmit_connect(d, sub);
04219    ast_mutex_unlock(&sub->lock);
04220 }

static char* substate2str ( int  ind  )  [static]

Definition at line 4964 of file chan_skinny.c.

References ast_threadstorage_get(), SUBSTATE2STR_BUFSIZE, substate2str_threadbuf, SUBSTATE_BUSY, SUBSTATE_CALLWAIT, SUBSTATE_CONGESTION, SUBSTATE_CONNECTED, SUBSTATE_DIALING, SUBSTATE_HOLD, SUBSTATE_OFFHOOK, SUBSTATE_ONHOOK, SUBSTATE_PROGRESS, SUBSTATE_RINGIN, SUBSTATE_RINGOUT, and SUBSTATE_UNSET.

Referenced by setsubstate().

04964                                    {
04965    char *tmp;
04966 
04967    switch (ind) {
04968    case SUBSTATE_UNSET:
04969       return "SUBSTATE_UNSET";
04970    case SUBSTATE_OFFHOOK:
04971       return "SUBSTATE_OFFHOOK";
04972    case SUBSTATE_ONHOOK:
04973       return "SUBSTATE_ONHOOK";
04974    case SUBSTATE_RINGOUT:
04975       return "SUBSTATE_RINGOUT";
04976    case SUBSTATE_RINGIN:
04977       return "SUBSTATE_RINGIN";
04978    case SUBSTATE_CONNECTED:
04979       return "SUBSTATE_CONNECTED";
04980    case SUBSTATE_BUSY:
04981       return "SUBSTATE_BUSY";
04982    case SUBSTATE_CONGESTION:
04983       return "SUBSTATE_CONGESTION";
04984    case SUBSTATE_PROGRESS:
04985       return "SUBSTATE_PROGRESS";
04986    case SUBSTATE_HOLD:
04987       return "SUBSTATE_HOLD";
04988    case SUBSTATE_CALLWAIT:
04989       return "SUBSTATE_CALLWAIT";
04990    case SUBSTATE_DIALING:
04991       return "SUBSTATE_DIALING";
04992    default:
04993       if (!(tmp = ast_threadstorage_get(&substate2str_threadbuf, SUBSTATE2STR_BUFSIZE)))
04994                         return "Unknown";
04995       snprintf(tmp, SUBSTATE2STR_BUFSIZE, "UNKNOWN-%d", ind);
04996       return tmp;
04997    }
04998 }

static void transmit_activatecallplane ( struct skinny_device d,
struct skinny_line l 
) [static]

static void transmit_callinfo ( struct skinny_device d,
int  instance,
int  callid,
char *  fromname,
char *  fromnum,
char *  toname,
char *  tonum,
int  calldirection 
) [static]

Definition at line 2430 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 push_callinfo(), and send_callinfo().

02431 {
02432    struct skinny_req *req;
02433 
02434    if (!(req = req_alloc(sizeof(struct call_info_message), CALL_INFO_MESSAGE)))
02435       return;
02436 
02437    if (skinnydebug) {
02438       ast_verb(1, "Setting Callinfo to %s(%s) from %s(%s) (dir=%d) on %s(%d)\n", toname, tonum, fromname, fromnum, calldirection, d->name, instance);
02439    }
02440    
02441    ast_copy_string(req->data.callinfo.callingPartyName, fromname, sizeof(req->data.callinfo.callingPartyName));
02442    ast_copy_string(req->data.callinfo.callingParty, fromnum, sizeof(req->data.callinfo.callingParty));
02443    ast_copy_string(req->data.callinfo.calledPartyName, toname, sizeof(req->data.callinfo.calledPartyName));
02444    ast_copy_string(req->data.callinfo.calledParty, tonum, sizeof(req->data.callinfo.calledParty));
02445    req->data.callinfo.instance = htolel(instance);
02446    req->data.callinfo.reference = htolel(callid);
02447    req->data.callinfo.type = htolel(calldirection);
02448    transmit_response(d, req);
02449 }

static void transmit_callstate ( struct skinny_device d,
int  buttonInstance,
unsigned  callid,
int  state 
) [static]

Definition at line 2783 of file chan_skinny.c.

References ast_verb, CALL_STATE_MESSAGE, call_state_message::callReference, call_state_message::callState, skinny_data::callstate, callstate2str(), skinny_req::data, htolel, call_state_message::lineInstance, req_alloc(), and transmit_response().

Referenced by handle_callforward_button(), setsubstate(), skinny_extensionstate_cb(), and update_connectedline().

02784 {
02785    struct skinny_req *req;
02786 
02787    if (!(req = req_alloc(sizeof(struct call_state_message), CALL_STATE_MESSAGE)))
02788       return;
02789    
02790 #ifdef SKINNY_DEVMODE
02791    if (skinnydebug) {
02792       ast_verb(3, "Transmitting CALL_STATE_MESSAGE to %s - line %d, callid %d, state %s\n", d->name, buttonInstance, callid, callstate2str(state));
02793    }
02794 #endif
02795 
02796    req->data.callstate.callState = htolel(state);
02797    req->data.callstate.lineInstance = htolel(buttonInstance);
02798    req->data.callstate.callReference = htolel(callid);
02799    transmit_response(d, req);
02800 }

static void transmit_capabilitiesreq ( struct skinny_device d  )  [static]

Definition at line 3019 of file chan_skinny.c.

References ast_verb, CAPABILITIES_REQ_MESSAGE, req_alloc(), and transmit_response().

Referenced by handle_message().

03020 {
03021    struct skinny_req *req;
03022 
03023    if (!(req = req_alloc(0, CAPABILITIES_REQ_MESSAGE)))
03024       return;
03025 
03026    if (skinnydebug)
03027       ast_verb(1, "Requesting capabilities\n");
03028 
03029    transmit_response(d, req);
03030 }

static void transmit_cfwdstate ( struct skinny_device d,
struct skinny_line l 
) [static]

Definition at line 2802 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().

02803 {
02804    struct skinny_req *req;
02805    int anyon = 0;
02806 
02807    if (!(req = req_alloc(sizeof(struct forward_stat_message), FORWARD_STAT_MESSAGE)))
02808       return;
02809 
02810    if (l->cfwdtype & SKINNY_CFWD_ALL) {
02811       if (!ast_strlen_zero(l->call_forward_all)) {
02812          ast_copy_string(req->data.forwardstat.fwdallnum, l->call_forward_all, sizeof(req->data.forwardstat.fwdallnum));
02813          req->data.forwardstat.fwdall = htolel(1);
02814          anyon++;
02815       } else {
02816          req->data.forwardstat.fwdall = htolel(0);
02817       }
02818    }
02819    if (l->cfwdtype & SKINNY_CFWD_BUSY) {
02820       if (!ast_strlen_zero(l->call_forward_busy)) {
02821          ast_copy_string(req->data.forwardstat.fwdbusynum, l->call_forward_busy, sizeof(req->data.forwardstat.fwdbusynum));
02822          req->data.forwardstat.fwdbusy = htolel(1);
02823          anyon++;
02824       } else {
02825          req->data.forwardstat.fwdbusy = htolel(0);
02826       }
02827    }
02828    if (l->cfwdtype & SKINNY_CFWD_NOANSWER) {
02829       if (!ast_strlen_zero(l->call_forward_noanswer)) {
02830          ast_copy_string(req->data.forwardstat.fwdnoanswernum, l->call_forward_noanswer, sizeof(req->data.forwardstat.fwdnoanswernum));
02831          req->data.forwardstat.fwdnoanswer = htolel(1);
02832          anyon++;
02833       } else {
02834          req->data.forwardstat.fwdnoanswer = htolel(0);
02835       }
02836    }
02837    req->data.forwardstat.lineNumber = htolel(l->instance);
02838    if (anyon)
02839       req->data.forwardstat.activeforward = htolel(7);
02840    else
02841       req->data.forwardstat.activeforward = htolel(0);
02842 
02843    transmit_response(d, req);
02844 }

static void transmit_clear_display_message ( struct skinny_device d,
int  instance,
int  reference 
) [static]

Definition at line 2615 of file chan_skinny.c.

References ast_verb, CLEAR_DISPLAY_MESSAGE, req_alloc(), and transmit_response().

Referenced by handle_callforward_button(), and setsubstate().

02616 {
02617    struct skinny_req *req;
02618    if (!(req = req_alloc(sizeof(struct clear_display_message), CLEAR_DISPLAY_MESSAGE)))
02619       return;
02620 
02621    //what do we want hear CLEAR_DISPLAY_MESSAGE or CLEAR_PROMPT_STATUS???
02622    //if we are clearing the display, it appears there is no instance and refernece info (size 0)
02623    //req->data.clearpromptstatus.lineInstance = instance;
02624    //req->data.clearpromptstatus.callReference = reference;
02625 
02626    if (skinnydebug)
02627       ast_verb(1, "Clearing Display\n");
02628    transmit_response(d, req);
02629 }

static void transmit_clearpromptmessage ( struct skinny_device d,
int  instance,
int  callid 
) [static]

Definition at line 2684 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(), setsubstate(), and skinny_extensionstate_cb().

02685 {
02686    struct skinny_req *req;
02687 
02688    if (!(req = req_alloc(sizeof(struct clear_prompt_message), CLEAR_PROMPT_MESSAGE)))
02689       return;
02690 
02691    req->data.clearpromptstatus.lineInstance = htolel(instance);
02692    req->data.clearpromptstatus.callReference = htolel(callid);
02693 
02694    if (skinnydebug)
02695       ast_verb(1, "Clearing Prompt\n");
02696 
02697    transmit_response(d, req);
02698 }

static void transmit_closereceivechannel ( struct skinny_device d,
struct skinny_subchannel sub 
) [static]

static void transmit_connect ( struct skinny_device d,
struct skinny_subchannel sub 
) [static]

static void transmit_definetimedate ( struct skinny_device d  )  [static]

Definition at line 2882 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(), handle_onhook_message(), handle_soft_key_event_message(), and setsubstate().

02883 {
02884    struct skinny_req *req;
02885    struct timeval now = ast_tvnow();
02886    struct ast_tm cmtime;
02887 
02888    if (!(req = req_alloc(sizeof(struct definetimedate_message), DEFINETIMEDATE_MESSAGE)))
02889       return;
02890 
02891    ast_localtime(&now, &cmtime, NULL);
02892    req->data.definetimedate.year = htolel(cmtime.tm_year+1900);
02893    req->data.definetimedate.month = htolel(cmtime.tm_mon+1);
02894    req->data.definetimedate.dayofweek = htolel(cmtime.tm_wday);
02895    req->data.definetimedate.day = htolel(cmtime.tm_mday);
02896    req->data.definetimedate.hour = htolel(cmtime.tm_hour);
02897    req->data.definetimedate.minute = htolel(cmtime.tm_min);
02898    req->data.definetimedate.seconds = htolel(cmtime.tm_sec);
02899    req->data.definetimedate.milliseconds = htolel(cmtime.tm_usec / 1000);
02900    req->data.definetimedate.timestamp = htolel(now.tv_sec);
02901    transmit_response(d, req);
02902 }

static void transmit_dialednumber ( struct skinny_device d,
const char *  text,
int  instance,
int  callid 
) [static]

static void transmit_displaynotify ( struct skinny_device d,
const char *  text,
int  t 
) [static]

static void transmit_displaypromptstatus ( struct skinny_device d,
const char *  text,
int  t,
int  instance,
int  callid 
) [static]

static void transmit_keepaliveack ( struct skinny_device d  )  [static]

Definition at line 2991 of file chan_skinny.c.

References KEEP_ALIVE_ACK_MESSAGE, req_alloc(), and transmit_response().

Referenced by handle_message().

02992 {
02993    struct skinny_req *req;
02994 
02995    if (!(req = req_alloc(0, KEEP_ALIVE_ACK_MESSAGE)))
02996       return;
02997 
02998    transmit_response(d, req);
02999 }

static void transmit_lamp_indication ( struct skinny_device d,
int  stimulus,
int  instance,
int  indication 
) [static]

static void transmit_linestatres ( struct skinny_device d,
int  instance 
) [static]

Definition at line 2861 of file chan_skinny.c.

References skinny_req::data, find_line_by_instance(), find_speeddial_by_instance(), skinny_speeddial::instance, skinny_speeddial::label, 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().

02862 {
02863    struct skinny_req *req;
02864    struct skinny_line *l;
02865    struct skinny_speeddial *sd;
02866 
02867    if (!(req = req_alloc(sizeof(struct line_stat_res_message), LINE_STAT_RES_MESSAGE)))
02868       return;
02869 
02870    if ((l = find_line_by_instance(d, instance))) {
02871       req->data.linestat.lineNumber = letohl(l->instance);
02872       memcpy(req->data.linestat.lineDirNumber, l->name, sizeof(req->data.linestat.lineDirNumber));
02873       memcpy(req->data.linestat.lineDisplayName, l->label, sizeof(req->data.linestat.lineDisplayName));
02874    } else if ((sd = find_speeddial_by_instance(d, instance, 1))) {
02875       req->data.linestat.lineNumber = letohl(sd->instance);
02876       memcpy(req->data.linestat.lineDirNumber, sd->label, sizeof(req->data.linestat.lineDirNumber));
02877       memcpy(req->data.linestat.lineDisplayName, sd->label, sizeof(req->data.linestat.lineDisplayName));
02878    }
02879    transmit_response(d, req);
02880 }

static void transmit_microphone_mode ( struct skinny_device d,
int  mode 
) [static]

Definition at line 2418 of file chan_skinny.c.

References skinny_req::data, htolel, set_microphone_message::mode, req_alloc(), SET_MICROPHONE_MESSAGE, skinny_data::setmicrophone, and transmit_response().

Referenced by setsubstate().

02419 {
02420    struct skinny_req *req;
02421 
02422    if (!(req = req_alloc(sizeof(struct set_microphone_message), SET_MICROPHONE_MESSAGE)))
02423       return;
02424 
02425    req->data.setmicrophone.mode = htolel(mode);
02426    transmit_response(d, req);
02427 }

static void transmit_registerack ( struct skinny_device d  )  [static]

Definition at line 3001 of file chan_skinny.c.

References skinny_req::data, register_ack_message::dateTemplate, htolel, register_ack_message::keepAlive, skinny_data::regack, REGISTER_ACK_MESSAGE, req_alloc(), register_ack_message::res, register_ack_message::res2, register_ack_message::secondaryKeepAlive, and transmit_response().

Referenced by handle_message().

03002 {
03003    struct skinny_req *req;
03004 
03005    if (!(req = req_alloc(sizeof(struct register_ack_message), REGISTER_ACK_MESSAGE)))
03006       return;
03007 
03008    req->data.regack.res[0] = '0';
03009    req->data.regack.res[1] = '\0';
03010    req->data.regack.keepAlive = htolel(keep_alive);
03011    memcpy(req->data.regack.dateTemplate, date_format, sizeof(req->data.regack.dateTemplate));
03012    req->data.regack.res2[0] = '0';
03013    req->data.regack.res2[1] = '\0';
03014    req->data.regack.secondaryKeepAlive = htolel(keep_alive);
03015 
03016    transmit_response(d, req);
03017 }

static void transmit_registerrej ( struct skinnysession s  )  [static]

Definition at line 2393 of file chan_skinny.c.

References skinny_req::data, register_rej_message::errMsg, register_message::name, skinny_data::reg, REGISTER_REJ_MESSAGE, skinny_data::regrej, req_alloc(), and transmit_response_bysession().

Referenced by handle_message().

02394 {
02395    struct skinny_req *req;
02396    char name[16];
02397 
02398    if (!(req = req_alloc(sizeof(struct register_rej_message), REGISTER_REJ_MESSAGE)))
02399       return;
02400 
02401    memcpy(&name, req->data.reg.name, sizeof(name));
02402    snprintf(req->data.regrej.errMsg, sizeof(req->data.regrej.errMsg), "No Authority: %s", name);
02403 
02404    transmit_response_bysession(s, req);
02405 }  

static void transmit_reset ( struct skinny_device d,
int  fullrestart 
) [static]

Definition at line 2975 of file chan_skinny.c.

References ast_verb, skinny_req::data, req_alloc(), skinny_data::reset, RESET_MESSAGE, reset_message::resetType, and transmit_response().

Referenced by handle_skinny_reset().

02976 {
02977    struct skinny_req *req;
02978   
02979    if (!(req = req_alloc(sizeof(struct reset_message), RESET_MESSAGE)))
02980       return;
02981   
02982    if (fullrestart)
02983       req->data.reset.resetType = 2;
02984    else
02985       req->data.reset.resetType = 1;
02986 
02987    ast_verb(3, "%s device %s.\n", (fullrestart) ? "Restarting" : "Resetting", d->id);
02988    transmit_response(d, req);
02989 }

static void transmit_response ( struct skinny_device d,
struct skinny_req req 
) [static]

Definition at line 2388 of file chan_skinny.c.

References skinny_device::session, and transmit_response_bysession().

02389 {
02390    transmit_response_bysession(d->session, req);
02391 }

static int transmit_response_bysession ( struct skinnysession s,
struct skinny_req req 
) [static]

Definition at line 2348 of file chan_skinny.c.

References ast_free, ast_log(), ast_mutex_lock, ast_mutex_unlock, ast_verb, skinny_req::data, skinnysession::device, skinny_req::e, errno, skinnysession::fd, skinny_req::len, letohl, skinnysession::lock, LOG_WARNING, message2str(), skinnysession::outbuf, SKINNY_DEVONLY, SKINNY_MAX_PACKET, and skinny_unregister().

Referenced by transmit_registerrej(), and transmit_response().

02349 {
02350    int res = 0;
02351 
02352    if (!s) {
02353       ast_log(LOG_WARNING, "Asked to transmit to a non-existent session!\n");
02354       return -1;
02355    }
02356 
02357    ast_mutex_lock(&s->lock);
02358 
02359    SKINNY_DEVONLY(if (skinnydebug>1) ast_verb(4, "Transmitting %s to %s\n", message2str(req->e), s->device->name);)
02360 
02361    if ((letohl(req->len) > SKINNY_MAX_PACKET) || (letohl(req->len) < 0)) {
02362       ast_log(LOG_WARNING, "transmit_response: the length of the request (%d) is out of bounds (%d)\n", letohl(req->len), SKINNY_MAX_PACKET);
02363       ast_mutex_unlock(&s->lock);
02364       return -1;
02365    }
02366 
02367    memset(s->outbuf, 0, sizeof(s->outbuf));
02368    memcpy(s->outbuf, req, skinny_header_size);
02369    memcpy(s->outbuf+skinny_header_size, &req->data, letohl(req->len));
02370 
02371    res = write(s->fd, s->outbuf, letohl(req->len)+8);
02372    
02373    if (res != letohl(req->len)+8) {
02374       ast_log(LOG_WARNING, "Transmit: write only sent %d out of %d bytes: %s\n", res, letohl(req->len)+8, strerror(errno));
02375       if (res == -1) {
02376          if (skinnydebug)
02377             ast_log(LOG_WARNING, "Transmit: Skinny Client was lost, unregistering\n");
02378          skinny_unregister(NULL, s);
02379       }
02380       
02381    }
02382    
02383    ast_free(req);
02384    ast_mutex_unlock(&s->lock);
02385    return 1;
02386 }

static void transmit_ringer_mode ( struct skinny_device d,
int  mode 
) [static]

Definition at line 2590 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(), setsubstate(), and skinny_extensionstate_cb().

02591 {
02592    struct skinny_req *req;
02593 
02594    if (skinnydebug)
02595       ast_verb(1, "Setting ringer mode to '%d'.\n", mode);
02596 
02597    if (!(req = req_alloc(sizeof(struct set_ringer_message), SET_RINGER_MESSAGE)))
02598       return;
02599 
02600    req->data.setringer.ringerMode = htolel(mode);
02601    /* XXX okay, I don't quite know what this is, but here's what happens (on a 7960).
02602       Note: The phone will always show as ringing on the display.
02603 
02604       1: phone will audibly ring over and over
02605       2: phone will audibly ring only once
02606       any other value, will NOT cause the phone to audibly ring
02607    */
02608    req->data.setringer.unknown1 = htolel(1);
02609    /* XXX the value here doesn't seem to change anything.  Must be higher than 0.
02610       Perhaps a packet capture can shed some light on this. */
02611    req->data.setringer.unknown2 = htolel(1);
02612    transmit_response(d, req);
02613 }

static void transmit_selectsoftkeys ( struct skinny_device d,
int  instance,
int  callid,
int  softkey 
) [static]

static void transmit_serverres ( struct skinny_device d  )  [static]

static void transmit_softkeysetres ( struct skinny_device d  )  [static]

Definition at line 2927 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_SET_RES_MESSAGE, soft_key_set_definition::softKeyInfoIndex, soft_key_set_res_message::softKeySetCount, soft_key_set_res_message::softKeySetDefinition, soft_key_set_res_message::softKeySetOffset, skinny_data::softkeysets, soft_key_set_definition::softKeyTemplateIndex, soft_key_set_res_message::totalSoftKeySetCount, and transmit_response().

Referenced by handle_message().

02928 {
02929    struct skinny_req *req;
02930    int i;
02931    int x;
02932    int y;
02933    const struct soft_key_definitions *softkeymode = soft_key_default_definitions;
02934 
02935    if (!(req = req_alloc(sizeof(struct soft_key_set_res_message), SOFT_KEY_SET_RES_MESSAGE)))
02936       return;
02937 
02938    req->data.softkeysets.softKeySetOffset = htolel(0);
02939    req->data.softkeysets.softKeySetCount = htolel(13);
02940    req->data.softkeysets.totalSoftKeySetCount = htolel(13);
02941    for (x = 0; x < sizeof(soft_key_default_definitions) / sizeof(struct soft_key_definitions); x++) {
02942       const uint8_t *defaults = softkeymode->defaults;
02943       /* XXX I wanted to get the size of the array dynamically, but that wasn't wanting to work.
02944          This will have to do for now. */
02945       for (y = 0; y < softkeymode->count; y++) {
02946          for (i = 0; i < (sizeof(soft_key_template_default) / sizeof(struct soft_key_template_definition)); i++) {
02947             if (defaults[y] == i+1) {
02948                req->data.softkeysets.softKeySetDefinition[softkeymode->mode].softKeyTemplateIndex[y] = (i+1);
02949                req->data.softkeysets.softKeySetDefinition[softkeymode->mode].softKeyInfoIndex[y] = htoles(i+301);
02950                     if (skinnydebug)   
02951                   ast_verbose("softKeySetDefinition : softKeyTemplateIndex: %d softKeyInfoIndex: %d\n", i+1, i+301);
02952             }
02953          }
02954       }
02955       softkeymode++;
02956    }
02957    transmit_response(d, req);
02958 }

static void transmit_softkeytemplateres ( struct skinny_device d  )  [static]

static void transmit_speaker_mode ( struct skinny_device d,
int  mode 
) [static]

Definition at line 2407 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 dumpsub(), handle_callforward_button(), handle_soft_key_event_message(), handle_stimulus_message(), and setsubstate().

02408 {
02409    struct skinny_req *req;
02410 
02411    if (!(req = req_alloc(sizeof(struct set_speaker_message), SET_SPEAKER_MESSAGE)))
02412       return;
02413 
02414    req->data.setspeaker.mode = htolel(mode);
02415    transmit_response(d, req);
02416 }

static void transmit_speeddialstatres ( struct skinny_device d,
struct skinny_speeddial sd 
) [static]

static void transmit_start_tone ( struct skinny_device d,
int  tone,
int  instance,
int  reference 
) [static]

Definition at line 2542 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 setsubstate(), skinny_newcall(), and skinny_ss().

02543 {
02544    struct skinny_req *req;
02545    if (!(req = req_alloc(sizeof(struct start_tone_message), START_TONE_MESSAGE)))
02546       return;
02547    req->data.starttone.tone = htolel(tone);
02548    req->data.starttone.instance = htolel(instance);
02549    req->data.starttone.reference = htolel(reference);
02550    transmit_response(d, req);
02551 }

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 2738 of file chan_skinny.c.

References media_qualifier::bitRate, skinny_subchannel::callid, codec_ast2skinny(), start_media_transmission_message_ip6::conferenceId, start_media_transmission_message_ip4::conferenceId, ast_format_list::cur_ms, skinny_req::data, ast_format_list::format, htolel, media_qualifier::packets, start_media_transmission_message_ip6::packetSize, start_media_transmission_message_ip4::packetSize, start_media_transmission_message_ip6::passThruPartyId, start_media_transmission_message_ip4::passThruPartyId, start_media_transmission_message_ip6::payloadType, start_media_transmission_message_ip4::payloadType, media_qualifier::precedence, start_media_transmission_message_ip6::qualifier, start_media_transmission_message_ip4::qualifier, start_media_transmission_message_ip6::remoteIp, start_media_transmission_message_ip4::remoteIp, start_media_transmission_message_ip6::remotePort, start_media_transmission_message_ip4::remotePort, req_alloc(), START_MEDIA_TRANSMISSION_MESSAGE, skinny_data::startmedia_ip4, skinny_data::startmedia_ip6, transmit_response(), and media_qualifier::vad.

Referenced by handle_open_receive_channel_ack_message(), and skinny_set_rtp_peer().

02739 {
02740    struct skinny_req *req;
02741 
02742    if (d->protocolversion < 17) {
02743       if (!(req = req_alloc(sizeof(struct start_media_transmission_message_ip4), START_MEDIA_TRANSMISSION_MESSAGE)))
02744          return;
02745       req->data.startmedia_ip4.conferenceId = htolel(sub->callid);
02746       req->data.startmedia_ip4.passThruPartyId = htolel(sub->callid);
02747       req->data.startmedia_ip4.remoteIp = dest.sin_addr.s_addr;
02748       req->data.startmedia_ip4.remotePort = htolel(ntohs(dest.sin_port));
02749       req->data.startmedia_ip4.packetSize = htolel(fmt.cur_ms);
02750       req->data.startmedia_ip4.payloadType = htolel(codec_ast2skinny(&fmt.format));
02751       req->data.startmedia_ip4.qualifier.precedence = htolel(127);
02752       req->data.startmedia_ip4.qualifier.vad = htolel(0);
02753       req->data.startmedia_ip4.qualifier.packets = htolel(0);
02754       req->data.startmedia_ip4.qualifier.bitRate = htolel(0);
02755    } else {
02756       if (!(req = req_alloc(sizeof(struct start_media_transmission_message_ip6), START_MEDIA_TRANSMISSION_MESSAGE)))
02757          return;
02758       req->data.startmedia_ip6.conferenceId = htolel(sub->callid);
02759       req->data.startmedia_ip6.passThruPartyId = htolel(sub->callid);
02760       memcpy(req->data.startmedia_ip6.remoteIp, &dest.sin_addr.s_addr, sizeof(dest.sin_addr.s_addr));
02761       req->data.startmedia_ip6.remotePort = htolel(ntohs(dest.sin_port));
02762       req->data.startmedia_ip6.packetSize = htolel(fmt.cur_ms);
02763       req->data.startmedia_ip6.payloadType = htolel(codec_ast2skinny(&fmt.format));
02764       req->data.startmedia_ip6.qualifier.precedence = htolel(127);
02765       req->data.startmedia_ip6.qualifier.vad = htolel(0);
02766       req->data.startmedia_ip6.qualifier.packets = htolel(0);
02767       req->data.startmedia_ip6.qualifier.bitRate = htolel(0);
02768    }
02769    transmit_response(d, req);
02770 }

static void transmit_stop_tone ( struct skinny_device d,
int  instance,
int  reference 
) [static]

Definition at line 2553 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 setsubstate(), skinny_indicate(), and skinny_ss().

02554 {
02555    struct skinny_req *req;
02556    if (!(req = req_alloc(sizeof(struct stop_tone_message), STOP_TONE_MESSAGE)))
02557       return;
02558    req->data.stoptone.instance = htolel(instance);
02559    req->data.stoptone.reference = htolel(reference);
02560    transmit_response(d, req);
02561 }

static void transmit_stopmediatransmission ( struct skinny_device d,
struct skinny_subchannel sub 
) [static]

static void transmit_versionres ( struct skinny_device d  )  [static]

Definition at line 2904 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().

02905 {
02906    struct skinny_req *req;
02907    if (!(req = req_alloc(sizeof(struct version_res_message), VERSION_RES_MESSAGE)))
02908       return;
02909 
02910    ast_copy_string(req->data.version.version, d->version_id, sizeof(req->data.version.version));
02911    transmit_response(d, req);
02912 }

static int unload_module ( void   )  [static]

Definition at line 8013 of file chan_skinny.c.

References ARRAY_LEN, ast_channel_unregister(), ast_cli_unregister_multiple(), ast_context_destroy(), ast_context_find(), ast_event_unsubscribe(), ast_format_cap_destroy(), AST_LIST_LOCK, AST_LIST_REMOVE_HEAD, AST_LIST_TRAVERSE, AST_LIST_UNLOCK, ast_manager_unregister(), ast_mutex_lock, ast_mutex_unlock, AST_PTHREADT_STOP, ast_rtp_glue_unregister(), ast_sched_context_destroy(), ast_softhangup(), AST_SOFTHANGUP_APPUNLOAD, ast_channel_tech::capabilities, cli_skinny, delete_devices(), skinnysession::device, EVENT_FLAG_SYSTEM, skinnysession::fd, free, skinny_device::lines, skinny_subchannel::lock, skinny_line::lock, manager_event, skinny_line::mwi_event_sub, netlock, skinny_subchannel::owner, skinny_rtp_glue, skinny_tech, skinny_line::sub, sub, skinnysession::t, and unregister_exten().

08014 {
08015    struct skinnysession *s;
08016    struct skinny_device *d;
08017    struct skinny_line *l;
08018    struct skinny_subchannel *sub;
08019    struct ast_context *con;
08020 
08021    ast_rtp_glue_unregister(&skinny_rtp_glue);
08022    ast_channel_unregister(&skinny_tech);
08023    ast_cli_unregister_multiple(cli_skinny, ARRAY_LEN(cli_skinny));
08024 
08025    ast_manager_unregister("SKINNYdevices");
08026    ast_manager_unregister("SKINNYshowdevice");
08027    ast_manager_unregister("SKINNYlines");
08028    ast_manager_unregister("SKINNYshowline");
08029    
08030    AST_LIST_LOCK(&sessions);
08031    /* Destroy all the interfaces and free their memory */
08032    while((s = AST_LIST_REMOVE_HEAD(&sessions, list))) {
08033       d = s->device;
08034       AST_LIST_TRAVERSE(&d->lines, l, list){
08035          ast_mutex_lock(&l->lock);
08036          AST_LIST_TRAVERSE(&l->sub, sub, list) {
08037             ast_mutex_lock(&sub->lock);
08038             if (sub->owner) {
08039                ast_softhangup(sub->owner, AST_SOFTHANGUP_APPUNLOAD);
08040             }
08041             ast_mutex_unlock(&sub->lock);
08042          }
08043          if (l->mwi_event_sub)
08044             ast_event_unsubscribe(l->mwi_event_sub);
08045          ast_mutex_unlock(&l->lock);
08046          manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", "ChannelType: Skinny\r\nPeer: Skinny/%s@%s\r\nPeerStatus: Unregistered\r\n", l->name, d->name);
08047          unregister_exten(l);
08048       }
08049       if (s->fd > -1)
08050          close(s->fd);
08051       pthread_cancel(s->t);
08052       pthread_kill(s->t, SIGURG);
08053       pthread_join(s->t, NULL);
08054       free(s);
08055    }
08056    AST_LIST_UNLOCK(&sessions);
08057 
08058    delete_devices();
08059 
08060    ast_mutex_lock(&netlock);
08061    if (accept_t && (accept_t != AST_PTHREADT_STOP)) {
08062       pthread_cancel(accept_t);
08063       pthread_kill(accept_t, SIGURG);
08064       pthread_join(accept_t, NULL);
08065    }
08066    accept_t = AST_PTHREADT_STOP;
08067    ast_mutex_unlock(&netlock);
08068 
08069    close(skinnysock);
08070    if (sched) {
08071       ast_sched_context_destroy(sched);
08072    }
08073 
08074    con = ast_context_find(used_context);
08075    if (con)
08076       ast_context_destroy(con, "Skinny");
08077 
08078    default_cap = ast_format_cap_destroy(default_cap);
08079    skinny_tech.capabilities = ast_format_cap_destroy(skinny_tech.capabilities);
08080    return 0;
08081 }

static void unregister_exten ( struct skinny_line l  )  [static]

Definition at line 2050 of file chan_skinny.c.

References ast_context_find(), ast_context_remove_extension(), ast_copy_string(), ast_log(), ast_strlen_zero(), ext, LOG_WARNING, S_OR, and strsep().

Referenced by skinny_unregister(), and unload_module().

02051 {
02052    char multi[256];
02053    char *stringp, *ext, *context;
02054 
02055    if (ast_strlen_zero(regcontext))
02056       return;
02057 
02058    ast_copy_string(multi, S_OR(l->regexten, l->name), sizeof(multi));
02059    stringp = multi;
02060    while ((ext = strsep(&stringp, "&"))) {
02061       if ((context = strchr(ext, '@'))) {
02062          *context++ = '\0'; /* split ext@context */
02063          if (!ast_context_find(context)) {
02064             ast_log(LOG_WARNING, "Context %s must exist in regcontext= in skinny.conf!\n", context);
02065             continue;
02066          }
02067       } else {
02068          context = regcontext;
02069       }
02070       ast_context_remove_extension(context, ext, 1, NULL);
02071    }
02072 }

static void update_connectedline ( struct skinny_subchannel sub,
const void *  data,
size_t  datalen 
) [static]

Definition at line 3140 of file chan_skinny.c.

References ast_channel::_state, AST_STATE_UP, ast_strlen_zero(), ast_verb, skinny_subchannel::calldirection, ast_channel::caller, skinny_subchannel::callid, ast_channel::connected, skinny_line::device, ast_party_connected_line::id, ast_party_caller::id, skinny_subchannel::line, ast_party_id::number, skinny_subchannel::owner, skinny_subchannel::progress, skinny_subchannel::ringing, send_callinfo(), SKINNY_CONNECTED, SKINNY_INCOMING, SKINNY_PROGRESS, SKINNY_RINGIN, SKINNY_RINGOUT, ast_party_number::str, transmit_callstate(), transmit_displaypromptstatus(), and ast_party_number::valid.

03141 {
03142    struct ast_channel *c = sub->owner;
03143    struct skinny_line *l = sub->line;
03144    struct skinny_device *d = l->device;
03145 
03146    if (!c->caller.id.number.valid
03147       || ast_strlen_zero(c->caller.id.number.str)
03148       || !c->connected.id.number.valid
03149       || ast_strlen_zero(c->connected.id.number.str))
03150       return;
03151 
03152    if (skinnydebug) {
03153       ast_verb(3,"Sub %d - Updating\n", sub->callid);
03154    }
03155    
03156    send_callinfo(sub);
03157    if (sub->owner->_state == AST_STATE_UP) {
03158       transmit_callstate(d, l->instance, sub->callid, SKINNY_CONNECTED);
03159       transmit_displaypromptstatus(d, "Connected", 0, l->instance, sub->callid);
03160    } else {
03161       if (sub->calldirection == SKINNY_INCOMING) {
03162          transmit_callstate(d, l->instance, sub->callid, SKINNY_RINGIN);
03163          transmit_displaypromptstatus(d, "Ring-In", 0, l->instance, sub->callid);
03164       } else {
03165          if (!sub->ringing) {
03166             transmit_callstate(d, l->instance, sub->callid, SKINNY_RINGOUT);
03167             transmit_displaypromptstatus(d, "Ring-Out", 0, l->instance, sub->callid);
03168             sub->ringing = 1;
03169          } else {
03170             transmit_callstate(d, l->instance, sub->callid, SKINNY_PROGRESS);
03171             transmit_displaypromptstatus(d, "Call Progress", 0, l->instance, sub->callid);
03172             sub->progress = 1;
03173          }
03174       }
03175    }
03176 }


Variable Documentation

struct ast_module_info __mod_info = { .name = AST_MODULE, .flags = AST_MODFLAG_LOAD_ORDER , .description = "Skinny Client Control Protocol (Skinny)" , .key = "This paragraph is copyright (c) 2006 by Digium, Inc. \In order for your module to load, it must return this \key via a function called \"key\". Any code which \includes this paragraph must be licensed under the GNU \General Public License version 2 or later (at your \option). In addition to Digium's general reservations \of rights, Digium expressly reserves the right to \allow other parties to license this paragraph under \different terms. Any use of Digium, Inc. trademarks or \logos (including \"Asterisk\" or \"Digium\") without \express written permission of Digium, Inc. is prohibited.\n" , .buildopt_sum = AST_BUILDOPT_SUM, .load = load_module, .unload = unload_module, .reload = reload, .load_pri = AST_MODPRI_CHANNEL_DRIVER, } [static]

Definition at line 8094 of file chan_skinny.c.

struct in_addr __ourip [static]

Definition at line 1106 of file chan_skinny.c.

pthread_t accept_t [static]

Definition at line 1110 of file chan_skinny.c.

struct ast_hostent ahp [static]

Definition at line 1107 of file chan_skinny.c.

Referenced by config_load(), config_parse_variables(), and rpt_exec().

Definition at line 8094 of file chan_skinny.c.

int auth_limit = DEFAULT_AUTH_LIMIT [static]

Definition at line 184 of file chan_skinny.c.

int auth_timeout = DEFAULT_AUTH_TIMEOUT [static]

Definition at line 183 of file chan_skinny.c.

struct sockaddr_in bindaddr [static]

Definition at line 1103 of file chan_skinny.c.

int callnums = 1 [static]

Definition at line 1111 of file chan_skinny.c.

struct ast_threadstorage callstate2str_threadbuf = { .once = PTHREAD_ONCE_INIT , .key_init = __init_callstate2str_threadbuf , .custom_init = NULL , } [static]

Definition at line 258 of file chan_skinny.c.

Referenced by callstate2str().

struct ast_cli_entry cli_skinny[] [static]

Definition at line 4165 of file chan_skinny.c.

Referenced by load_module(), and unload_module().

const char config[] = "skinny.conf" [static]

Definition at line 152 of file chan_skinny.c.

struct ast_threadstorage control2str_threadbuf = { .once = PTHREAD_ONCE_INIT , .key_init = __init_control2str_threadbuf , .custom_init = NULL , } [static]

Definition at line 252 of file chan_skinny.c.

Referenced by control2str().

unsigned int cos

Definition at line 177 of file chan_skinny.c.

unsigned int cos_audio

Definition at line 178 of file chan_skinny.c.

unsigned int cos_video

Definition at line 179 of file chan_skinny.c.

char date_format[6] = "D-M-Y" [static]

Definition at line 189 of file chan_skinny.c.

struct ast_format_cap* default_cap [static]

Definition at line 154 of file chan_skinny.c.

Definition at line 1458 of file chan_skinny.c.

Referenced by config_device(), and config_load().

struct ast_jb_conf default_jbconf [static]

Global jitterbuffer configuration - by default, jb is disabled

Note:
Values shown here match the defaults shown in skinny.conf.sample

Definition at line 234 of file chan_skinny.c.

Definition at line 1354 of file chan_skinny.c.

Referenced by config_line(), and config_load().

struct ast_codec_pref default_prefs [static]

Definition at line 155 of file chan_skinny.c.

struct ast_threadstorage device2str_threadbuf = { .once = PTHREAD_ONCE_INIT , .key_init = __init_device2str_threadbuf , .custom_init = NULL , } [static]

Definition at line 249 of file chan_skinny.c.

Referenced by device2str().

int firstdigittimeout = 16000 [static]

Definition at line 1229 of file chan_skinny.c.

int gendigittimeout = 8000 [static]

Definition at line 1232 of file chan_skinny.c.

struct ast_jb_conf global_jbconf [static]

Definition at line 242 of file chan_skinny.c.

char global_vmexten[AST_MAX_EXTENSION] [static]

Definition at line 186 of file chan_skinny.c.

struct hostent* hp [static]

int keep_alive = 120 [static]

Definition at line 182 of file chan_skinny.c.

int matchdigittimeout = 3000 [static]

Definition at line 1235 of file chan_skinny.c.

struct ast_threadstorage message2str_threadbuf = { .once = PTHREAD_ONCE_INIT , .key_init = __init_message2str_threadbuf , .custom_init = NULL , } [static]

Definition at line 245 of file chan_skinny.c.

Referenced by message2str().

ast_mutex_t netlock = { PTHREAD_MUTEX_INITIALIZER , NULL, 1 } [static]

Definition at line 1226 of file chan_skinny.c.

char ourhost[256] [static]

Definition at line 1104 of file chan_skinny.c.

int ourport [static]

Definition at line 1105 of file chan_skinny.c.

struct { ... } qos [static]

char regcontext[AST_MAX_CONTEXT] [static]

Definition at line 188 of file chan_skinny.c.

struct ast_sched_context* sched = NULL [static]

Definition at line 1223 of file chan_skinny.c.

int skinny_header_size = 12 [static]

Definition at line 1093 of file chan_skinny.c.

struct ast_rtp_glue skinny_rtp_glue [static]

Definition at line 3324 of file chan_skinny.c.

Referenced by load_module(), and unload_module().

struct ast_channel_tech skinny_tech [static]

Definition at line 1495 of file chan_skinny.c.

Referenced by load_module(), skinny_new(), and unload_module().

int skinnydebug = 0 [static]

Definition at line 1099 of file chan_skinny.c.

int skinnyreload = 0 [static]

Definition at line 1100 of file chan_skinny.c.

int skinnysock = -1 [static]

Definition at line 1109 of file chan_skinny.c.

const uint8_t soft_key_default_connected[] [static]

Definition at line 871 of file chan_skinny.c.

const uint8_t soft_key_default_connwithconf[] [static]

Initial value:

Definition at line 915 of file chan_skinny.c.

const uint8_t soft_key_default_connwithtrans[] [static]

Definition at line 901 of file chan_skinny.c.

const uint8_t soft_key_default_dadfd[] [static]

Initial value:

Definition at line 910 of file chan_skinny.c.

Definition at line 946 of file chan_skinny.c.

const uint8_t soft_key_default_offhook[] [static]

Definition at line 893 of file chan_skinny.c.

const uint8_t soft_key_default_offhookwithfeat[] [static]

Initial value:

Definition at line 924 of file chan_skinny.c.

const uint8_t soft_key_default_onhold[] [static]

Definition at line 880 of file chan_skinny.c.

const uint8_t soft_key_default_onhook[] [static]

Definition at line 861 of file chan_skinny.c.

const uint8_t soft_key_default_ringin[] [static]

Initial value:

Definition at line 887 of file chan_skinny.c.

const uint8_t soft_key_default_ringout[] [static]

Initial value:

Definition at line 919 of file chan_skinny.c.

const uint8_t soft_key_default_SLAconnectednotactive[] [static]

Initial value:

Definition at line 940 of file chan_skinny.c.

const uint8_t soft_key_default_SLAhold[] [static]

Initial value:

Definition at line 934 of file chan_skinny.c.

const uint8_t soft_key_default_unknown[] [static]

Initial value:

Definition at line 930 of file chan_skinny.c.

Definition at line 698 of file chan_skinny.c.

struct ast_threadstorage substate2str_threadbuf = { .once = PTHREAD_ONCE_INIT , .key_init = __init_substate2str_threadbuf , .custom_init = NULL , } [static]

Definition at line 255 of file chan_skinny.c.

Referenced by substate2str().

const char tdesc[] = "Skinny Client Control Protocol (Skinny)" [static]

Definition at line 151 of file chan_skinny.c.

unsigned int tos

Definition at line 174 of file chan_skinny.c.

unsigned int tos_audio

Definition at line 175 of file chan_skinny.c.

unsigned int tos_video

Definition at line 176 of file chan_skinny.c.

int unauth_sessions = 0 [static]

Definition at line 185 of file chan_skinny.c.

char used_context[AST_MAX_EXTENSION] [static]

Definition at line 187 of file chan_skinny.c.

char version_id[16] = "P002F202" [static]

Definition at line 190 of file chan_skinny.c.


Generated on Sat Feb 11 06:34:52 2012 for Asterisk - The Open Source Telephony Project by  doxygen 1.5.6