#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netinet/tcp.h>
#include <sys/ioctl.h>
#include <net/if.h>
#include <errno.h>
#include <fcntl.h>
#include <netdb.h>
#include <arpa/inet.h>
#include <sys/signal.h>
#include <signal.h>
#include <ctype.h>
#include "asterisk.h"
#include "asterisk/lock.h"
#include "asterisk/channel.h"
#include "asterisk/config.h"
#include "asterisk/logger.h"
#include "asterisk/module.h"
#include "asterisk/pbx.h"
#include "asterisk/options.h"
#include "asterisk/sched.h"
#include "asterisk/io.h"
#include "asterisk/rtp.h"
#include "asterisk/acl.h"
#include "asterisk/callerid.h"
#include "asterisk/cli.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"
Go to the source code of this file.
Definition in file chan_skinny.c.
#define ACTIVATE_CALL_PLANE_MESSAGE 0x0116 |
#define ALARM_MESSAGE 0x0020 |
#define BUTTON_TEMPLATE_REQ_MESSAGE 0x000E |
#define BUTTON_TEMPLATE_RES_MESSAGE 0x0097 |
#define CALL_INFO_MESSAGE 0x008F |
#define CALL_STATE_MESSAGE 0x0111 |
#define CAPABILITIES_REQ_MESSAGE 0x009B |
#define CAPABILITIES_RES_MESSAGE 0x0010 |
#define CLEAR_DISPLAY_MESSAGE 0x009A |
#define CLOSE_RECIEVE_CHANNEL_MESSAGE 0x0106 |
#define DEFAULT_SKINNY_BACKLOG 2 |
#define DEFAULT_SKINNY_PORT 2000 |
#define DEFINETIMEDATE_MESSAGE 0x0094 |
#define DIALLED_NUMBER_MESSAGE 0x011D |
#define DISPLAY_NOTIFY_MESSAGE 0x0114 |
#define DISPLAY_PROMPT_STATUS_MESSAGE 0x0112 |
#define DISPLAYTEXT_MESSAGE 0x0099 |
#define htolel | ( | x | ) | (x) |
Definition at line 99 of file chan_skinny.c.
Referenced by get_input(), handle_message(), load_module(), transmit_callinfo(), transmit_callstate(), transmit_connect(), transmit_diallednumber(), transmit_displaymessage(), transmit_displaynotify(), transmit_displaypromptstatus(), transmit_lamp_indication(), transmit_ringer_mode(), transmit_speaker_mode(), and transmit_tone().
#define htoles | ( | x | ) | (x) |
Definition at line 100 of file chan_skinny.c.
#define IP_PORT_MESSAGE 0x0002 |
#define KEEP_ALIVE_ACK_MESSAGE 0x0100 |
#define KEEP_ALIVE_MESSAGE 0x0000 |
#define KEYPAD_BUTTON_MESSAGE 0x0003 |
#define letohl | ( | x | ) | (x) |
Definition at line 97 of file chan_skinny.c.
Referenced by get_input(), handle_message(), skinny_register(), skinny_req_parse(), and transmit_response().
#define letohs | ( | x | ) | (x) |
Definition at line 98 of file chan_skinny.c.
#define LINE_STAT_RES_MESSAGE 0x0092 |
#define LINE_STATE_REQ_MESSAGE 0x000B |
#define MAX_SUBS 2 |
Definition at line 712 of file chan_skinny.c.
#define OFFHOOK_MESSAGE 0x0006 |
#define ONHOOK_MESSAGE 0x0007 |
#define OPEN_RECIEVE_CHANNEL_ACK_MESSAGE 0x0022 |
#define OPEN_RECIEVE_CHANNEL_MESSAGE 0x0105 |
#define REGISTER_ACK_MESSAGE 0x0081 |
#define REGISTER_MESSAGE 0x0001 |
#define REGISTER_REJ_MESSAGE 0x009D |
#define SELECT_SOFT_KEYS_MESSAGE 0x0110 |
Definition at line 589 of file chan_skinny.c.
#define SERVER_REQUEST_MESSAGE 0x0012 |
#define SERVER_RES_MESSAGE 0x009E |
#define SET_LAMP_MESSAGE 0x0086 |
#define SET_RINGER_MESSAGE 0x0085 |
#define SET_SPEAKER_MESSAGE 0x0088 |
#define SKINNY_ALERT 0x24 |
#define SKINNY_BUSY 6 |
#define SKINNY_BUSYTONE 0x23 |
#define SKINNY_CALLWAIT 9 |
Definition at line 725 of file chan_skinny.c.
#define SKINNY_CALLWAITTONE 0x2D |
#define SKINNY_CONGESTION 7 |
#define SKINNY_CONNECTED 5 |
#define SKINNY_CX_CONF 3 |
Definition at line 757 of file chan_skinny.c.
#define SKINNY_CX_CONFERENCE 3 |
Definition at line 758 of file chan_skinny.c.
#define SKINNY_CX_INACTIVE 4 |
#define SKINNY_CX_MUTE 4 |
Definition at line 759 of file chan_skinny.c.
#define SKINNY_CX_RECVONLY 1 |
#define SKINNY_CX_SENDONLY 0 |
Definition at line 754 of file chan_skinny.c.
#define SKINNY_CX_SENDRECV 2 |
#define SKINNY_DIALTONE 0x21 |
#define SKINNY_HOLD 8 |
Definition at line 724 of file chan_skinny.c.
#define SKINNY_INVALID 14 |
Definition at line 729 of file chan_skinny.c.
#define SKINNY_LAMP_BLINK 5 |
#define SKINNY_LAMP_FLASH 4 |
Definition at line 742 of file chan_skinny.c.
#define SKINNY_LAMP_OFF 1 |
Definition at line 739 of file chan_skinny.c.
Referenced by do_housekeeping(), handle_message(), and skinny_hangup().
#define SKINNY_LAMP_ON 2 |
Definition at line 740 of file chan_skinny.c.
Referenced by do_housekeeping(), and handle_message().
#define SKINNY_LAMP_WINK 3 |
Definition at line 741 of file chan_skinny.c.
#define SKINNY_MAX_PACKET 1000 |
Definition at line 85 of file chan_skinny.c.
Referenced by handle_message(), and skinny_req_parse().
#define SKINNY_NOTONE 0x7F |
#define SKINNY_OFFHOOK 1 |
Definition at line 717 of file chan_skinny.c.
Referenced by handle_message(), skinny_call(), skinny_hangup(), and transmit_callstate().
#define SKINNY_ONHOOK 2 |
Definition at line 718 of file chan_skinny.c.
Referenced by build_device(), handle_message(), skinny_call(), skinny_hangup(), and transmit_callstate().
#define SKINNY_PARK 11 |
Definition at line 727 of file chan_skinny.c.
#define SKINNY_PROGRESS 12 |
#define SKINNY_REORDER 0x25 |
#define SKINNY_RING_FEATURE 4 |
Definition at line 748 of file chan_skinny.c.
#define SKINNY_RING_INSIDE 2 |
#define SKINNY_RING_OFF 1 |
#define SKINNY_RING_OUTSIDE 3 |
Definition at line 747 of file chan_skinny.c.
#define SKINNY_RINGIN 4 |
#define SKINNY_RINGOUT 3 |
#define SKINNY_SILENCE 0x00 |
Definition at line 731 of file chan_skinny.c.
Referenced by handle_message(), skinny_hangup(), skinny_indicate(), and skinny_ss().
#define SKINNY_SPEAKEROFF 2 |
Definition at line 715 of file chan_skinny.c.
Referenced by skinny_hangup(), and transmit_callstate().
#define SKINNY_SPEAKERON 1 |
Definition at line 714 of file chan_skinny.c.
#define SKINNY_TRANSFER 10 |
Definition at line 726 of file chan_skinny.c.
#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 SPEED_DIAL_STAT_REQ_MESSAGE 0x000A |
#define SPEED_DIAL_STAT_RES_MESSAGE 0x0091 |
#define START_MEDIA_TRANSMISSION_MESSAGE 0x008A |
#define START_TONE_MESSAGE 0x0082 |
#define STIMULUS_AUTOANSWER 0x11 |
Definition at line 337 of file chan_skinny.c.
#define STIMULUS_CALLPARK 0x7E |
#define STIMULUS_CALLPICKUP 0x7F |
Definition at line 340 of file chan_skinny.c.
#define STIMULUS_CONFERENCE 0x7D |
#define STIMULUS_DISPLAY 0x08 |
#define STIMULUS_FORWARDALL 0x05 |
#define STIMULUS_FORWARDBUSY 0x06 |
#define STIMULUS_FORWARDNOANSWER 0x07 |
#define STIMULUS_HOLD 0x03 |
#define STIMULUS_LINE 0x09 |
Definition at line 335 of file chan_skinny.c.
Referenced by handle_message(), skinny_call(), and skinny_hangup().
#define STIMULUS_MESSAGE 0x0005 |
#define STIMULUS_NONE 0xFF |
Definition at line 341 of file chan_skinny.c.
#define STIMULUS_REDIAL 0x01 |
#define STIMULUS_SPEEDDIAL 0x02 |
#define STIMULUS_TRANSFER 0x04 |
#define STIMULUS_VOICEMAIL 0x0F |
Definition at line 336 of file chan_skinny.c.
Referenced by do_housekeeping(), and handle_message().
#define STOP_MEDIA_TRANSMISSION_MESSAGE 0x008B |
#define STOP_TONE_MESSAGE 0x0083 |
#define SUB_ALT 1 |
Definition at line 711 of file chan_skinny.c.
#define SUB_REAL 0 |
Definition at line 710 of file chan_skinny.c.
#define TIME_DATE_REQ_MESSAGE 0x000D |
#define TYPE_LINE 2 |
Definition at line 751 of file chan_skinny.c.
#define TYPE_TRUNK 1 |
Definition at line 750 of file chan_skinny.c.
#define UNREGISTER_MESSAGE 0x0027 |
#define VERSION_REQ_MESSAGE 0x000F |
#define VERSION_RES_MESSAGE 0x0098 |
typedef struct buttondefinition button_definition |
typedef struct button_defs button_defs_t |
typedef unsigned short UINT16 |
Definition at line 93 of file chan_skinny.c.
typedef unsigned int UINT32 |
Definition at line 94 of file chan_skinny.c.
typedef unsigned char UINT8 |
Definition at line 92 of file chan_skinny.c.
static void* accept_thread | ( | void * | ignore | ) | [static] |
Definition at line 2929 of file chan_skinny.c.
References ast_log(), ast_mutex_init(), ast_mutex_lock(), ast_mutex_unlock(), ast_pthread_create, ast_verbose(), destroy_session(), LOG_NOTICE, LOG_WARNING, malloc, s, sessions, and skinny_session().
02930 { 02931 int as; 02932 struct sockaddr_in sin; 02933 socklen_t sinlen; 02934 struct skinnysession *s; 02935 struct protoent *p; 02936 int arg = 1; 02937 pthread_attr_t attr; 02938 02939 pthread_attr_init(&attr); 02940 pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED); 02941 02942 for (;;) { 02943 sinlen = sizeof(sin); 02944 as = accept(skinnysock, (struct sockaddr *)&sin, &sinlen); 02945 if (as < 0) { 02946 ast_log(LOG_NOTICE, "Accept returned -1: %s\n", strerror(errno)); 02947 continue; 02948 } 02949 p = getprotobyname("tcp"); 02950 if(p) { 02951 if( setsockopt(as, p->p_proto, TCP_NODELAY, (char *)&arg, sizeof(arg) ) < 0 ) { 02952 ast_log(LOG_WARNING, "Failed to set Skinny tcp connection to TCP_NODELAY mode: %s\n", strerror(errno)); 02953 } 02954 } 02955 s = malloc(sizeof(struct skinnysession)); 02956 if (!s) { 02957 ast_log(LOG_WARNING, "Failed to allocate Skinny session: %s\n", strerror(errno)); 02958 continue; 02959 } 02960 memset(s, 0, sizeof(struct skinnysession)); 02961 memcpy(&s->sin, &sin, sizeof(sin)); 02962 ast_mutex_init(&s->lock); 02963 s->fd = as; 02964 ast_mutex_lock(&sessionlock); 02965 s->next = sessions; 02966 sessions = s; 02967 ast_mutex_unlock(&sessionlock); 02968 02969 if (ast_pthread_create(&tcp_thread, NULL, skinny_session, s)) { 02970 destroy_session(s); 02971 } 02972 } 02973 if (skinnydebug) { 02974 ast_verbose("killing accept thread\n"); 02975 } 02976 close(as); 02977 return 0; 02978 }
AST_MUTEX_DEFINE_STATIC | ( | devicelock | ) |
AST_MUTEX_DEFINE_STATIC | ( | sessionlock | ) |
AST_MUTEX_DEFINE_STATIC | ( | netlock | ) |
AST_MUTEX_DEFINE_STATIC | ( | monlock | ) |
AST_MUTEX_DEFINE_STATIC | ( | usecnt_lock | ) |
static struct skinny_device* build_device | ( | char * | cat, | |
struct ast_variable * | v | |||
) | [static] |
Definition at line 1482 of file chan_skinny.c.
References ast_append_ha(), ast_callerid_split(), ast_cdr_amaflags2int(), ast_get_group(), ast_get_ip(), ast_log(), ast_mutex_init(), ast_ouraddrfor(), ast_strlen_zero(), ast_true(), ast_verbose(), DEFAULT_SKINNY_PORT, free, ast_variable::lineno, LOG_ERROR, LOG_WARNING, malloc, MAX_SUBS, ast_variable::name, ast_variable::next, SKINNY_CX_INACTIVE, SKINNY_ONHOOK, TYPE_LINE, TYPE_TRUNK, ast_variable::value, and VERBOSE_PREFIX_3.
Referenced by reload_config().
01483 { 01484 struct skinny_device *d; 01485 struct skinny_line *l; 01486 struct skinny_subchannel *sub; 01487 int i=0, y=0; 01488 01489 d = malloc(sizeof(struct skinny_device)); 01490 if (d) { 01491 memset(d, 0, sizeof(struct skinny_device)); 01492 strncpy(d->name, cat, sizeof(d->name) - 1); 01493 while(v) { 01494 if (!strcasecmp(v->name, "host")) { 01495 if (ast_get_ip(&d->addr, v->value)) { 01496 free(d); 01497 return NULL; 01498 } 01499 } else if (!strcasecmp(v->name, "port")) { 01500 d->addr.sin_port = htons(atoi(v->value)); 01501 } else if (!strcasecmp(v->name, "device")) { 01502 strncpy(d->id, v->value, sizeof(d->id)-1); 01503 } else if (!strcasecmp(v->name, "permit") || !strcasecmp(v->name, "deny")) { 01504 d->ha = ast_append_ha(v->name, v->value, d->ha); 01505 } else if (!strcasecmp(v->name, "context")) { 01506 strncpy(context, v->value, sizeof(context) - 1); 01507 } else if (!strcasecmp(v->name, "version")) { 01508 strncpy(d->version_id, v->value, sizeof(d->version_id) -1); 01509 } else if (!strcasecmp(v->name, "nat")) { 01510 nat = ast_true(v->value); 01511 } else if (!strcasecmp(v->name, "model")) { 01512 strncpy(d->model, v->value, sizeof(d->model) - 1); 01513 } else if (!strcasecmp(v->name, "callerid")) { 01514 if (!strcasecmp(v->value, "asreceived")) { 01515 cid_num[0] = '\0'; 01516 cid_name[0] = '\0'; 01517 } else { 01518 ast_callerid_split(v->value, cid_name, sizeof(cid_name), cid_num, sizeof(cid_num)); 01519 } 01520 } else if (!strcasecmp(v->name, "language")) { 01521 strncpy(language, v->value, sizeof(language)-1); 01522 } else if (!strcasecmp(v->name, "accountcode")) { 01523 strncpy(accountcode, v->value, sizeof(accountcode)-1); 01524 } else if (!strcasecmp(v->name, "amaflags")) { 01525 y = ast_cdr_amaflags2int(v->value); 01526 if (y < 0) { 01527 ast_log(LOG_WARNING, "Invalid AMA flags: %s at line %d\n", v->value, v->lineno); 01528 } else { 01529 amaflags = y; 01530 } 01531 } else if (!strcasecmp(v->name, "musiconhold")) { 01532 strncpy(musicclass, v->value, sizeof(musicclass)-1); 01533 } else if (!strcasecmp(v->name, "callgroup")) { 01534 cur_callergroup = ast_get_group(v->value); 01535 } else if (!strcasecmp(v->name, "pickupgroup")) { 01536 cur_pickupgroup = ast_get_group(v->value); 01537 } else if (!strcasecmp(v->name, "immediate")) { 01538 immediate = ast_true(v->value); 01539 } else if (!strcasecmp(v->name, "cancallforward")) { 01540 cancallforward = ast_true(v->value); 01541 } else if (!strcasecmp(v->name, "mailbox")) { 01542 strncpy(mailbox, v->value, sizeof(mailbox) -1); 01543 } else if (!strcasecmp(v->name, "callreturn")) { 01544 callreturn = ast_true(v->value); 01545 } else if (!strcasecmp(v->name, "callwaiting")) { 01546 callwaiting = ast_true(v->value); 01547 } else if (!strcasecmp(v->name, "transfer")) { 01548 transfer = ast_true(v->value); 01549 } else if (!strcasecmp(v->name, "threewaycalling")) { 01550 threewaycalling = ast_true(v->value); 01551 } else if (!strcasecmp(v->name, "mwiblink")) { 01552 mwiblink = ast_true(v->value); 01553 } else if (!strcasecmp(v->name, "linelabel")) { 01554 strncpy(linelabel, v->value, sizeof(linelabel)-1); 01555 } else if (!strcasecmp(v->name, "trunk") || !strcasecmp(v->name, "line")) { 01556 l = malloc(sizeof(struct skinny_line));; 01557 if (l) { 01558 memset(l, 0, sizeof(struct skinny_line)); 01559 ast_mutex_init(&l->lock); 01560 strncpy(l->name, v->value, sizeof(l->name) - 1); 01561 01562 /* XXX Should we check for uniqueness?? XXX */ 01563 strncpy(l->context, context, sizeof(l->context) - 1); 01564 strncpy(l->cid_num, cid_num, sizeof(l->cid_num) - 1); 01565 strncpy(l->cid_name, cid_name, sizeof(l->cid_name) - 1); 01566 strncpy(l->label, linelabel, sizeof(l->label) - 1); 01567 strncpy(l->language, language, sizeof(l->language) - 1); 01568 strncpy(l->musicclass, musicclass, sizeof(l->musicclass)-1); 01569 strncpy(l->mailbox, mailbox, sizeof(l->mailbox)-1); 01570 strncpy(l->mailbox, mailbox, sizeof(l->mailbox)-1); 01571 if (!ast_strlen_zero(mailbox)) { 01572 ast_verbose(VERBOSE_PREFIX_3 "Setting mailbox '%s' on %s@%s\n", mailbox, d->name, l->name); 01573 } 01574 l->msgstate = -1; 01575 l->capability = capability; 01576 l->parent = d; 01577 if (!strcasecmp(v->name, "trunk")) { 01578 l->type = TYPE_TRUNK; 01579 } else { 01580 l->type = TYPE_LINE; 01581 } 01582 l->immediate = immediate; 01583 l->callgroup = cur_callergroup; 01584 l->pickupgroup = cur_pickupgroup; 01585 l->callreturn = callreturn; 01586 l->cancallforward = cancallforward; 01587 l->callwaiting = callwaiting; 01588 l->transfer = transfer; 01589 l->threewaycalling = threewaycalling; 01590 l->mwiblink = mwiblink; 01591 l->onhooktime = time(NULL); 01592 l->instance = 1; 01593 /* ASSUME we're onhook at this point*/ 01594 l->hookstate = SKINNY_ONHOOK; 01595 01596 for (i = 0; i < MAX_SUBS; i++) { 01597 sub = malloc(sizeof(struct skinny_subchannel)); 01598 if (sub) { 01599 ast_verbose(VERBOSE_PREFIX_3 "Allocating Skinny subchannel '%d' on %s@%s\n", i, l->name, d->name); 01600 memset(sub, 0, sizeof(struct skinny_subchannel)); 01601 ast_mutex_init(&sub->lock); 01602 sub->parent = l; 01603 /* Make a call*ID */ 01604 sub->callid = callnums; 01605 callnums++; 01606 sub->cxmode = SKINNY_CX_INACTIVE; 01607 sub->nat = nat; 01608 sub->next = l->sub; 01609 l->sub = sub; 01610 } else { 01611 /* XXX Should find a way to clean up our memory */ 01612 ast_log(LOG_WARNING, "Out of memory allocating subchannel"); 01613 return NULL; 01614 } 01615 } 01616 l->next = d->lines; 01617 d->lines = l; 01618 } else { 01619 /* XXX Should find a way to clean up our memory */ 01620 ast_log(LOG_WARNING, "Out of memory allocating line"); 01621 return NULL; 01622 } 01623 } else { 01624 ast_log(LOG_WARNING, "Don't know keyword '%s' at line %d\n", v->name, v->lineno); 01625 } 01626 v = v->next; 01627 } 01628 01629 if (!d->lines) { 01630 ast_log(LOG_ERROR, "A Skinny device must have at least one line!\n"); 01631 return NULL; 01632 } 01633 if (d->addr.sin_addr.s_addr && !ntohs(d->addr.sin_port)) { 01634 d->addr.sin_port = htons(DEFAULT_SKINNY_PORT); 01635 } 01636 if (d->addr.sin_addr.s_addr) { 01637 if (ast_ouraddrfor(&d->addr.sin_addr, &d->ourip)) { 01638 memcpy(&d->ourip, &__ourip, sizeof(d->ourip)); 01639 } 01640 } else { 01641 memcpy(&d->ourip, &__ourip, sizeof(d->ourip)); 01642 } 01643 } 01644 return d; 01645 }
static char* control2str | ( | int | ind | ) | [static] |
Definition at line 2126 of file chan_skinny.c.
References AST_CONTROL_ANSWER, AST_CONTROL_BUSY, AST_CONTROL_CONGESTION, AST_CONTROL_FLASH, AST_CONTROL_HANGUP, AST_CONTROL_HOLD, AST_CONTROL_OFFHOOK, AST_CONTROL_OPTION, AST_CONTROL_PROCEEDING, AST_CONTROL_PROGRESS, AST_CONTROL_RADIO_KEY, AST_CONTROL_RADIO_UNKEY, AST_CONTROL_RING, AST_CONTROL_RINGING, AST_CONTROL_TAKEOFFHOOK, AST_CONTROL_UNHOLD, and AST_CONTROL_WINK.
02126 { 02127 static char tmp[100]; 02128 02129 switch (ind) { 02130 case AST_CONTROL_HANGUP: 02131 return "Other end has hungup"; 02132 case AST_CONTROL_RING: 02133 return "Local ring"; 02134 case AST_CONTROL_RINGING: 02135 return "Remote end is ringing"; 02136 case AST_CONTROL_ANSWER: 02137 return "Remote end has answered"; 02138 case AST_CONTROL_BUSY: 02139 return "Remote end is busy"; 02140 case AST_CONTROL_TAKEOFFHOOK: 02141 return "Make it go off hook"; 02142 case AST_CONTROL_OFFHOOK: 02143 return "Line is off hook"; 02144 case AST_CONTROL_CONGESTION: 02145 return "Congestion (circuits busy)"; 02146 case AST_CONTROL_FLASH: 02147 return "Flash hook"; 02148 case AST_CONTROL_WINK: 02149 return "Wink"; 02150 case AST_CONTROL_OPTION: 02151 return "Set a low-level option"; 02152 case AST_CONTROL_RADIO_KEY: 02153 return "Key Radio"; 02154 case AST_CONTROL_RADIO_UNKEY: 02155 return "Un-Key Radio"; 02156 case AST_CONTROL_PROGRESS: 02157 return "Remote end is making Progress"; 02158 case AST_CONTROL_PROCEEDING: 02159 return "Remote end is proceeding"; 02160 case AST_CONTROL_HOLD: 02161 return "Hold"; 02162 case AST_CONTROL_UNHOLD: 02163 return "Unhold"; 02164 case -1: 02165 return "Stop tone"; 02166 } 02167 snprintf(tmp, 100, "UNKNOWN-%d", ind); 02168 return tmp; 02169 }
static int convert_cap | ( | int | capability | ) | [static] |
Definition at line 1007 of file chan_skinny.c.
Referenced by handle_message(), and transmit_connect().
void delete_devices | ( | void | ) |
Definition at line 3218 of file chan_skinny.c.
References ast_mutex_destroy(), ast_mutex_lock(), devices, free, skinny_device::lines, skinny_line::lock, skinny_subchannel::lock, skinny_line::next, skinny_subchannel::next, and skinny_line::sub.
Referenced by reload().
03219 { 03220 struct skinny_device *d, *dlast; 03221 struct skinny_line *l, *llast; 03222 struct skinny_subchannel *sub, *slast; 03223 03224 ast_mutex_lock(&devicelock); 03225 03226 /* Delete all devices */ 03227 for (d=devices;d;) { 03228 /* Delete all lines for this device */ 03229 for (l=d->lines;l;) { 03230 /* Delete all subchannels for this line */ 03231 for (sub=l->sub;sub;) { 03232 slast = sub; 03233 sub = sub->next; 03234 ast_mutex_destroy(&slast->lock); 03235 free(slast); 03236 } 03237 llast = l; 03238 l = l->next; 03239 ast_mutex_destroy(&llast->lock); 03240 free(llast); 03241 } 03242 dlast = d; 03243 d = d->next; 03244 free(dlast); 03245 } 03246 devices=NULL; 03247 ast_mutex_unlock(&devicelock); 03248 }
char* description | ( | void | ) |
Provides a description of the module.
Definition at line 3361 of file chan_skinny.c.
References desc.
03362 { 03363 return (char *) desc; 03364 }
static void destroy_session | ( | struct skinnysession * | s | ) | [static] |
Definition at line 2817 of file chan_skinny.c.
References ast_log(), ast_mutex_destroy(), ast_mutex_lock(), ast_mutex_unlock(), free, LOG_WARNING, skinnysession::next, s, and sessions.
02818 { 02819 struct skinnysession *cur, *prev = NULL; 02820 ast_mutex_lock(&sessionlock); 02821 cur = sessions; 02822 while(cur) { 02823 if (cur == s) { 02824 break; 02825 } 02826 prev = cur; 02827 cur = cur->next; 02828 } 02829 if (cur) { 02830 if (prev) { 02831 prev->next = cur->next; 02832 } else { 02833 sessions = cur->next; 02834 } 02835 if (s->fd > -1) { 02836 close(s->fd); 02837 } 02838 ast_mutex_destroy(&s->lock); 02839 free(s); 02840 } else { 02841 ast_log(LOG_WARNING, "Trying to delete nonexistent session %p?\n", s); 02842 } 02843 ast_mutex_unlock(&sessionlock); 02844 }
static void do_housekeeping | ( | struct skinnysession * | s | ) | [static] |
Definition at line 1304 of file chan_skinny.c.
References ast_app_messagecount(), ast_verbose(), find_subchannel_by_line(), has_voicemail(), skinny_line::instance, skinny_line::mailbox, skinny_line::mwiblink, skinny_device::name, skinny_line::name, skinny_line::parent, skinny_subchannel::parent, s, SKINNY_LAMP_BLINK, SKINNY_LAMP_OFF, SKINNY_LAMP_ON, STIMULUS_VOICEMAIL, skinny_line::sub, transmit_displaymessage(), and transmit_lamp_indication().
Referenced by handle_message(), and skinny_hangup().
01305 { 01306 int new; 01307 int old; 01308 struct skinny_subchannel *sub; 01309 struct skinny_line *l = s->device->lines; 01310 01311 sub = find_subchannel_by_line(l); 01312 transmit_displaymessage(s, NULL); 01313 01314 if (has_voicemail(sub->parent)) { 01315 if (skinnydebug) { 01316 ast_verbose("Checking for voicemail Skinny %s@%s\n", sub->parent->name, sub->parent->parent->name); 01317 } 01318 ast_app_messagecount(sub->parent->mailbox, &new, &old); 01319 if (skinnydebug) { 01320 ast_verbose("Skinny %s@%s has voicemail!\n", sub->parent->name, sub->parent->parent->name); 01321 } 01322 transmit_lamp_indication(s, STIMULUS_VOICEMAIL, l->instance, l->mwiblink?SKINNY_LAMP_BLINK:SKINNY_LAMP_ON); 01323 } else { 01324 transmit_lamp_indication(s, STIMULUS_VOICEMAIL, l->instance, SKINNY_LAMP_OFF); 01325 } 01326 01327 }
static void* do_monitor | ( | void * | data | ) | [static] |
Definition at line 2980 of file chan_skinny.c.
References ast_io_wait(), ast_mutex_lock(), ast_mutex_unlock(), ast_sched_runq(), ast_sched_wait(), io, and sched.
02981 { 02982 int res; 02983 02984 /* This thread monitors all the interfaces which are not yet in use 02985 (and thus do not have a separate thread) indefinitely */ 02986 /* From here on out, we die whenever asked */ 02987 for(;;) { 02988 pthread_testcancel(); 02989 /* Wait for sched or io */ 02990 res = ast_sched_wait(sched); 02991 if ((res < 0) || (res > 1000)) { 02992 res = 1000; 02993 } 02994 res = ast_io_wait(io, res); 02995 ast_mutex_lock(&monlock); 02996 if (res >= 0) { 02997 ast_sched_runq(sched); 02998 } 02999 ast_mutex_unlock(&monlock); 03000 } 03001 /* Never reached */ 03002 return NULL; 03003 03004 }
static struct skinny_subchannel* find_subchannel_by_line | ( | struct skinny_line * | l | ) | [static] |
Definition at line 938 of file chan_skinny.c.
References skinny_line::sub.
Referenced by do_housekeeping(), and handle_message().
00939 { 00940 /* XXX Need to figure out how to determine which sub we want */ 00941 struct skinny_subchannel *sub = l->sub; 00942 return sub; 00943 }
static struct skinny_subchannel* find_subchannel_by_name | ( | char * | dest | ) | [static] |
Definition at line 945 of file chan_skinny.c.
References ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_verbose(), devices, skinny_device::lines, LOG_NOTICE, skinny_line::name, skinny_device::name, skinny_device::next, skinny_line::next, and skinny_line::sub.
Referenced by skinny_request().
00946 { 00947 struct skinny_line *l; 00948 struct skinny_device *d; 00949 char line[256]; 00950 char *at; 00951 char *device; 00952 00953 strncpy(line, dest, sizeof(line) - 1); 00954 at = strchr(line, '@'); 00955 if (!at) { 00956 ast_log(LOG_NOTICE, "Device '%s' has no @ (at) sign!\n", dest); 00957 return NULL; 00958 } 00959 *at = '\0'; 00960 at++; 00961 device = at; 00962 ast_mutex_lock(&devicelock); 00963 d = devices; 00964 while(d) { 00965 if (!strcasecmp(d->name, device)) { 00966 if (skinnydebug) { 00967 ast_verbose("Found device: %s\n", d->name); 00968 } 00969 /* Found the device */ 00970 l = d->lines; 00971 while (l) { 00972 /* Search for the right line */ 00973 if (!strcasecmp(l->name, line)) { 00974 ast_mutex_unlock(&devicelock); 00975 return l->sub; 00976 } 00977 l = l->next; 00978 } 00979 } 00980 d = d->next; 00981 } 00982 /* Device not found*/ 00983 ast_mutex_unlock(&devicelock); 00984 return NULL; 00985 }
static int get_input | ( | struct skinnysession * | s | ) | [static] |
Definition at line 2846 of file chan_skinny.c.
References ast_log(), ast_mutex_unlock(), pollfd::events, pollfd::fd, htolel, letohl, LOG_WARNING, poll(), POLLIN, and s.
02847 { 02848 int res; 02849 int dlen = 0; 02850 struct pollfd fds[1]; 02851 02852 fds[0].fd = s->fd; 02853 fds[0].events = POLLIN; 02854 res = poll(fds, 1, -1); 02855 02856 if (res < 0) { 02857 ast_log(LOG_WARNING, "Select returned error: %s\n", strerror(errno)); 02858 } else if (res > 0) { 02859 memset(s->inbuf,0,sizeof(s->inbuf)); 02860 res = read(s->fd, s->inbuf, 4); 02861 if (res != 4) { 02862 ast_log(LOG_WARNING, "Skinny Client sent less data than expected.\n"); 02863 return -1; 02864 } 02865 dlen = letohl(*(int *)s->inbuf); 02866 if (dlen+8 > sizeof(s->inbuf)) { 02867 dlen = sizeof(s->inbuf) - 8; 02868 } 02869 *(int *)s->inbuf = htolel(dlen); 02870 res = read(s->fd, s->inbuf+4, dlen+4); 02871 ast_mutex_unlock(&s->lock); 02872 if (res != (dlen+4)) { 02873 ast_log(LOG_WARNING, "Skinny Client sent less data than expected.\n"); 02874 return -1; 02875 } 02876 } 02877 return res; 02878 }
static int handle_message | ( | skinny_req * | req, | |
struct skinnysession * | s | |||
) | [static] |
Definition at line 2304 of file chan_skinny.c.
References ALARM_MESSAGE, skinny_subchannel::alreadygone, AST_CONTROL_ANSWER, AST_FRAME_DTMF, ast_hangup(), ast_inet_ntoa(), ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_pthread_create, ast_queue_control(), ast_queue_frame(), ast_queue_hangup(), ast_rtp_get_us(), ast_rtp_set_peer(), ast_setstate(), AST_STATE_DOWN, AST_STATE_UP, ast_verbose(), attempt_transfer(), media_qualifier::bitRate, keypad_button_message::button, button_defs::button_def, button_def_none, button_defs, BUTTON_TEMPLATE_REQ_MESSAGE, BUTTON_TEMPLATE_RES_MESSAGE, button_template_res_message::buttonCount, button_template_res_message::buttonOffset, skinny_req::buttontemplate, skinny_subchannel::callid, CAPABILITIES_REQ_MESSAGE, CAPABILITIES_RES_MESSAGE, start_media_transmission_message::conferenceId, convert_cap(), skinny_subchannel::cxmode, skinny_req::data, register_ack_message::dateTemplate, definetimedate_message::day, definetimedate_message::dayofweek, skinny_req::definetimedate, DEFINETIMEDATE_MESSAGE, button_template_res_message::definition, do_housekeeping(), skinny_req::e, register_rej_message::errMsg, find_subchannel_by_line(), ast_frame::frametype, free, skinny_line::hookstate, definetimedate_message::hour, htolel, IP_PORT_MESSAGE, open_recieve_channel_ack_message::ipAddr, KEEP_ALIVE_ACK_MESSAGE, KEEP_ALIVE_MESSAGE, register_ack_message::keepAlive, skinny_req::keypad, KEYPAD_BUTTON_MESSAGE, skinny_line::label, skinny_req::len, letohl, skinny_req::line, LINE_STAT_RES_MESSAGE, LINE_STATE_REQ_MESSAGE, line_stat_res_message::lineDirNumber, line_stat_res_message::lineDisplayName, line_stat_res_message::linenumber, line_state_req_message::lineNumber, skinny_req::linestat, LOG_DEBUG, LOG_ERROR, LOG_NOTICE, LOG_WARNING, definetimedate_message::minute, definetimedate_message::month, ast_channel::name, skinny_device::name, skinny_line::name, register_message::name, name, skinny_subchannel::next, skinny_line::next, button_defs::num_buttons, OFFHOOK_MESSAGE, ONHOOK_MESSAGE, OPEN_RECIEVE_CHANNEL_ACK_MESSAGE, skinny_req::openrecievechannelack, option_verbose, skinny_subchannel::outgoing, skinny_subchannel::owner, media_qualifier::packets, start_media_transmission_message::packetSize, skinny_line::parent, skinny_subchannel::parent, start_media_transmission_message::passThruPartyId, start_media_transmission_message::payloadType, open_recieve_channel_ack_message::port, media_qualifier::precedence, start_media_transmission_message::qualifier, skinny_req::reg, skinny_req::regack, REGISTER_ACK_MESSAGE, REGISTER_MESSAGE, REGISTER_REJ_MESSAGE, skinny_req::regrej, start_media_transmission_message::remoteIp, start_media_transmission_message::remotePort, register_ack_message::res, register_ack_message::res2, skinny_subchannel::rtp, s, register_ack_message::secondaryKeepAlive, definetimedate_message::seconds, server_res_message::server, SERVER_REQUEST_MESSAGE, SERVER_RES_MESSAGE, server_res_message::serverIpAddr, server_res_message::serverListenPort, server_identifier::serverName, skinny_req::serverres, SKINNY_CONNECTED, SKINNY_CX_RECVONLY, SKINNY_DIALTONE, SKINNY_LAMP_OFF, SKINNY_LAMP_ON, SKINNY_MAX_PACKET, skinny_new(), SKINNY_OFFHOOK, SKINNY_ONHOOK, skinny_register(), SKINNY_RING_OFF, SKINNY_SILENCE, skinny_ss(), SOFT_KEY_SET_REQ_MESSAGE, SOFT_KEY_SET_RES_MESSAGE, soft_key_template_default, SOFT_KEY_TEMPLATE_REQ_MESSAGE, SOFT_KEY_TEMPLATE_RES_MESSAGE, soft_key_template::softKeyCount, soft_key_template::softKeyOffset, soft_key_sets::softKeySetCount, soft_key_sets::softKeySetDefinition, soft_key_sets::softKeySetOffset, skinny_req::softkeysets, skinny_req::softkeytemplate, soft_key_template::softKeyTemplateDefinition, SPEED_DIAL_STAT_REQ_MESSAGE, SPEED_DIAL_STAT_RES_MESSAGE, skinny_req::speeddial, speed_dial_stat_res_message::speedDialDirNumber, speed_dial_stat_res_message::speedDialDisplayName, speed_dial_stat_req_message::speedDialNumber, skinny_req::speeddialreq, ast_frame::src, START_MEDIA_TRANSMISSION_MESSAGE, start_rtp(), skinny_req::startmedia, open_recieve_channel_ack_message::status, stimulus_message::stimulus, skinny_req::stimulus, STIMULUS_CALLPARK, STIMULUS_CONFERENCE, STIMULUS_DISPLAY, STIMULUS_FORWARDALL, STIMULUS_FORWARDBUSY, STIMULUS_FORWARDNOANSWER, STIMULUS_HOLD, STIMULUS_LINE, STIMULUS_MESSAGE, STIMULUS_REDIAL, STIMULUS_SPEEDDIAL, STIMULUS_TRANSFER, STIMULUS_VOICEMAIL, stimulus_message::stimulusInstance, ast_frame::subclass, t, TIME_DATE_REQ_MESSAGE, button_template_res_message::totalButtonCount, soft_key_template::totalSoftKeyCount, soft_key_sets::totalSoftKeySetCount, skinny_line::transfer, transmit_callstate(), transmit_displaymessage(), transmit_displaynotify(), transmit_lamp_indication(), transmit_response(), transmit_ringer_mode(), transmit_speaker_mode(), transmit_tone(), button_defs::type, UNREGISTER_MESSAGE, media_qualifier::vad, VERBOSE_PREFIX_3, version_res_message::version, skinny_req::version, VERSION_REQ_MESSAGE, VERSION_RES_MESSAGE, and definetimedate_message::year.
Referenced by skinny_session().
02305 { 02306 struct skinny_subchannel *sub; 02307 struct ast_channel *c; 02308 struct ast_frame f = { 0, }; 02309 struct sockaddr_in sin; 02310 struct sockaddr_in us; 02311 struct skinny_line *lines; 02312 char name[16]; 02313 char addr[4]; 02314 char d; 02315 char iabuf[INET_ADDRSTRLEN]; 02316 int digit; 02317 int res=0; 02318 int speedDialNum; 02319 int lineNumber; 02320 int stimulus; 02321 int stimulusInstance; 02322 int status; 02323 int port; 02324 int i; 02325 time_t timer; 02326 struct tm *cmtime; 02327 pthread_t t; 02328 button_defs_t *b, *buse; 02329 02330 if ((!s->device) && (letohl(req->e) != REGISTER_MESSAGE && letohl(req->e) != ALARM_MESSAGE)) { 02331 ast_log(LOG_WARNING, "Client sent message #%d without first registering.\n", req->e); 02332 free(req); 02333 return 0; 02334 } 02335 02336 switch(letohl(req->e)) { 02337 case ALARM_MESSAGE: 02338 /* no response necessary */ 02339 break; 02340 case REGISTER_MESSAGE: 02341 if (skinnydebug) { 02342 ast_verbose("Device %s is attempting to register\n", req->data.reg.name); 02343 } 02344 res = skinny_register(req, s); 02345 if (!res) { 02346 ast_log(LOG_ERROR, "Rejecting Device %s: Device not found\n", req->data.reg.name); 02347 memcpy(&name, req->data.reg.name, sizeof(req->data.reg.name)); 02348 memset(req, 0, sizeof(skinny_req)); 02349 req->len = htolel(sizeof(register_rej_message)+4); 02350 req->e = htolel(REGISTER_REJ_MESSAGE); 02351 snprintf(req->data.regrej.errMsg, sizeof(req->data.regrej.errMsg), "No Authority: %s", name); 02352 transmit_response(s, req); 02353 break; 02354 } 02355 if (option_verbose > 2) { 02356 ast_verbose(VERBOSE_PREFIX_3 "Device '%s' successfuly registered\n", s->device->name); 02357 } 02358 memset(req, 0, SKINNY_MAX_PACKET); 02359 req->len = htolel(sizeof(register_ack_message)+4); 02360 req->e = htolel(REGISTER_ACK_MESSAGE); 02361 req->data.regack.res[0] = '0'; 02362 req->data.regack.res[1] = '\0'; 02363 req->data.regack.keepAlive = htolel(keep_alive); 02364 strncpy(req->data.regack.dateTemplate, date_format, sizeof(req->data.regack.dateTemplate) - 1); 02365 req->data.regack.res2[0] = '0'; 02366 req->data.regack.res2[1] = '\0'; 02367 req->data.regack.secondaryKeepAlive = htolel(keep_alive); 02368 transmit_response(s, req); 02369 if (skinnydebug) { 02370 ast_verbose("Requesting capabilities\n"); 02371 } 02372 memset(req, 0, SKINNY_MAX_PACKET); 02373 req->len = htolel(4); 02374 req->e = htolel(CAPABILITIES_REQ_MESSAGE); 02375 transmit_response(s, req); 02376 break; 02377 case UNREGISTER_MESSAGE: 02378 /* XXX Acutally unregister the device */ 02379 break; 02380 case IP_PORT_MESSAGE: 02381 /* no response necessary */ 02382 break; 02383 case STIMULUS_MESSAGE: 02384 stimulus = letohl(req->data.stimulus.stimulus); 02385 stimulusInstance = letohl(req->data.stimulus.stimulusInstance); 02386 02387 switch(stimulus) { 02388 case STIMULUS_REDIAL: 02389 /* If we can keep an array of dialed frames we can implement a quick 02390 and dirty redial, feeding the frames we last got into the queue 02391 function */ 02392 if (skinnydebug) { 02393 ast_verbose("Recieved Stimulus: Redial(%d)\n", stimulusInstance); 02394 } 02395 break; 02396 case STIMULUS_SPEEDDIAL: 02397 if (skinnydebug) { 02398 ast_verbose("Recieved Stimulus: SpeedDial(%d)\n", stimulusInstance); 02399 } 02400 break; 02401 case STIMULUS_HOLD: 02402 /* start moh? set RTP to 0.0.0.0? */ 02403 if (skinnydebug) { 02404 ast_verbose("Recieved Stimulus: Hold(%d)\n", stimulusInstance); 02405 } 02406 break; 02407 case STIMULUS_TRANSFER: 02408 if (skinnydebug) { 02409 ast_verbose("Recieved Stimulus: Transfer(%d)\n", stimulusInstance); 02410 } 02411 transmit_tone(s, SKINNY_DIALTONE); 02412 /* XXX figure out how to transfer */ 02413 break; 02414 case STIMULUS_CONFERENCE: 02415 if (skinnydebug) { 02416 ast_verbose("Recieved Stimulus: Transfer(%d)\n", stimulusInstance); 02417 } 02418 transmit_tone(s, SKINNY_DIALTONE); 02419 /* XXX determine the best way to pull off a conference. Meetme? */ 02420 break; 02421 case STIMULUS_VOICEMAIL: 02422 if (skinnydebug) { 02423 ast_verbose("Recieved Stimulus: Voicemail(%d)\n", stimulusInstance); 02424 } 02425 /* XXX Find and dial voicemail extension */ 02426 break; 02427 case STIMULUS_CALLPARK: 02428 if (skinnydebug) { 02429 ast_verbose("Recieved Stimulus: Park Call(%d)\n", stimulusInstance); 02430 } 02431 /* XXX Park the call */ 02432 break; 02433 case STIMULUS_FORWARDALL: 02434 /* Why is DND under FORWARDALL ? */ 02435 02436 /* Do not disturb */ 02437 transmit_tone(s, SKINNY_DIALTONE); 02438 if (s->device->lines->dnd != 0){ 02439 if (option_verbose > 2) { 02440 ast_verbose(VERBOSE_PREFIX_3 "Disabling DND on %s@%s\n",find_subchannel_by_line(s->device->lines)->parent->name,find_subchannel_by_line(s->device->lines)->parent->name); 02441 } 02442 s->device->lines->dnd = 0; 02443 transmit_lamp_indication(s, STIMULUS_FORWARDALL, 1, SKINNY_LAMP_ON); 02444 transmit_displaynotify(s, "DnD disabled",10); 02445 } else { 02446 if (option_verbose > 2) { 02447 ast_verbose(VERBOSE_PREFIX_3 "Enabling DND on %s@%s\n",find_subchannel_by_line(s->device->lines)->parent->name,find_subchannel_by_line(s->device->lines)->parent->name); 02448 } 02449 s->device->lines->dnd = 1; 02450 transmit_lamp_indication(s, STIMULUS_FORWARDALL, 1, SKINNY_LAMP_OFF); 02451 transmit_displaynotify(s, "DnD enabled",10); 02452 } 02453 break; 02454 case STIMULUS_FORWARDBUSY: 02455 case STIMULUS_FORWARDNOANSWER: 02456 /* Gonna be fun, not */ 02457 if (skinnydebug) { 02458 ast_verbose("Recieved Stimulus: Forward (%d)\n", stimulusInstance); 02459 } 02460 break; 02461 case STIMULUS_DISPLAY: 02462 /* Not sure what this is */ 02463 if (skinnydebug) { 02464 ast_verbose("Recieved Stimulus: Display(%d)\n", stimulusInstance); 02465 } 02466 break; 02467 case STIMULUS_LINE: 02468 if (skinnydebug) { 02469 ast_verbose("Recieved Stimulus: Line(%d)\n", stimulusInstance); 02470 } 02471 sub = find_subchannel_by_line(s->device->lines); 02472 /* turn the speaker on */ 02473 transmit_speaker_mode(s, 1); 02474 break; 02475 default: 02476 ast_verbose("RECEIVED UNKNOWN STIMULUS: %d(%d)\n", stimulus, stimulusInstance); 02477 break; 02478 } 02479 break; 02480 case VERSION_REQ_MESSAGE: 02481 if (skinnydebug) { 02482 ast_verbose("Version Request\n"); 02483 } 02484 memset(req, 0, SKINNY_MAX_PACKET); 02485 req->len = htolel(sizeof(version_res_message)+4); 02486 req->e = htolel(VERSION_RES_MESSAGE); 02487 snprintf(req->data.version.version, sizeof(req->data.version.version), s->device->version_id); 02488 transmit_response(s, req); 02489 break; 02490 case SERVER_REQUEST_MESSAGE: 02491 if (skinnydebug) { 02492 ast_verbose("Recieved Server Request\n"); 02493 } 02494 memset(req, 0, SKINNY_MAX_PACKET); 02495 req->len = htolel(sizeof(server_res_message)+4); 02496 req->e = htolel(SERVER_RES_MESSAGE); 02497 memcpy(req->data.serverres.server[0].serverName, ourhost, 02498 sizeof(req->data.serverres.server[0].serverName)); 02499 req->data.serverres.serverListenPort[0] = htolel(ourport); 02500 req->data.serverres.serverIpAddr[0] = htolel(__ourip.s_addr); 02501 transmit_response(s, req); 02502 break; 02503 case BUTTON_TEMPLATE_REQ_MESSAGE: 02504 if (skinnydebug) { 02505 ast_verbose("Buttontemplate requested\n"); 02506 } 02507 sub = find_subchannel_by_line(s->device->lines); 02508 memset(req, 0, SKINNY_MAX_PACKET); 02509 req->e = htolel(BUTTON_TEMPLATE_RES_MESSAGE); 02510 req->len = htolel(sizeof(button_template_res_message)+4); 02511 02512 /* Find a matching button definition, default to first in the 02513 list */ 02514 buse = button_defs; 02515 for(b=button_defs; b->type; b++) { 02516 if (!strcmp(s->device->model, b->type)) { 02517 buse = b; 02518 } 02519 } 02520 req->data.buttontemplate.buttonOffset = 0; 02521 req->data.buttontemplate.buttonCount = htolel(buse->num_buttons); 02522 req->data.buttontemplate.totalButtonCount = htolel(buse->num_buttons); 02523 for (i=0; i<42; i++) { 02524 if (i < buse->num_buttons) { 02525 memcpy(&(req->data.buttontemplate.definition[i]), 02526 &(buse->button_def[i]), 02527 sizeof(button_definition)); 02528 } else { 02529 memcpy(&(req->data.buttontemplate.definition[i]), 02530 &(button_def_none), 02531 sizeof(button_definition)); 02532 } 02533 } 02534 02535 if (skinnydebug) { 02536 ast_verbose("Sending %s template to %s@%s (%s)\n", 02537 buse->type, 02538 sub->parent->name, 02539 sub->parent->parent->name, 02540 s->device->model); 02541 } 02542 transmit_response(s, req); 02543 break; 02544 case SOFT_KEY_SET_REQ_MESSAGE: 02545 if (skinnydebug) { 02546 ast_verbose("Received SoftKeySetReq\n"); 02547 } 02548 memset(req, 0, SKINNY_MAX_PACKET); 02549 req->len = htolel(sizeof(soft_key_sets)+4); 02550 req->e = htolel(SOFT_KEY_SET_RES_MESSAGE); 02551 req->data.softkeysets.softKeySetOffset = 0; 02552 req->data.softkeysets.softKeySetCount = htolel(11); 02553 req->data.softkeysets.totalSoftKeySetCount = htolel(11); 02554 /* XXX Wicked hack XXX */ 02555 memcpy(req->data.softkeysets.softKeySetDefinition, 02556 soft_key_set_hack, 02557 sizeof(req->data.softkeysets.softKeySetDefinition)); 02558 transmit_response(s,req); 02559 break; 02560 case SOFT_KEY_TEMPLATE_REQ_MESSAGE: 02561 if (skinnydebug) { 02562 ast_verbose("Recieved SoftKey Template Request\n"); 02563 } 02564 memset(req, 0, SKINNY_MAX_PACKET); 02565 req->len = htolel(sizeof(soft_key_template)+4); 02566 req->e = htolel(SOFT_KEY_TEMPLATE_RES_MESSAGE); 02567 req->data.softkeytemplate.softKeyOffset = 0; 02568 req->data.softkeytemplate.softKeyCount = htolel(sizeof(soft_key_template_default) / sizeof(soft_key_template_definition)); 02569 req->data.softkeytemplate.totalSoftKeyCount = htolel(sizeof(soft_key_template_default) / sizeof(soft_key_template_definition)); 02570 memcpy(req->data.softkeytemplate.softKeyTemplateDefinition, 02571 soft_key_template_default, 02572 sizeof(soft_key_template_default)); 02573 transmit_response(s,req); 02574 break; 02575 case TIME_DATE_REQ_MESSAGE: 02576 if (skinnydebug) { 02577 ast_verbose("Received Time/Date Request\n"); 02578 } 02579 memset(req, 0, SKINNY_MAX_PACKET); 02580 req->len = htolel(sizeof(definetimedate_message)+4); 02581 req->e = htolel(DEFINETIMEDATE_MESSAGE); 02582 timer=time(NULL); 02583 cmtime = localtime(&timer); 02584 req->data.definetimedate.year = htolel(cmtime->tm_year+1900); 02585 req->data.definetimedate.month = htolel(cmtime->tm_mon+1); 02586 req->data.definetimedate.dayofweek = htolel(cmtime->tm_wday); 02587 req->data.definetimedate.day = htolel(cmtime->tm_mday); 02588 req->data.definetimedate.hour = htolel(cmtime->tm_hour); 02589 req->data.definetimedate.minute = htolel(cmtime->tm_min); 02590 req->data.definetimedate.seconds = htolel(cmtime->tm_sec); 02591 transmit_response(s, req); 02592 break; 02593 case SPEED_DIAL_STAT_REQ_MESSAGE: 02594 /* Not really sure how Speed Dial's are different than the 02595 Softkey templates */ 02596 speedDialNum = letohl(req->data.speeddialreq.speedDialNumber); 02597 memset(req, 0, SKINNY_MAX_PACKET); 02598 req->len = htolel(sizeof(speed_dial_stat_res_message)+4); 02599 req->e = htolel(SPEED_DIAL_STAT_RES_MESSAGE); 02600 #if 0 02601 /* XXX Do this right XXX */ 02602 /* If the redial function works the way I think it will, a modification of it 02603 can work here was well. Yikes. */ 02604 req->data.speeddialreq.speedDialNumber = speedDialNum; 02605 snprintf(req->data.speeddial.speedDialDirNumber, sizeof(req->data.speeddial.speedDialDirNumber), "31337"); 02606 snprintf(req->data.speeddial.speedDialDisplayName, sizeof(req->data.speeddial.speedDialDisplayName),"Asterisk Rules!"); 02607 #endif 02608 transmit_response(s, req); 02609 break; 02610 case LINE_STATE_REQ_MESSAGE: 02611 lineNumber = letohl(req->data.line.lineNumber); 02612 if (skinnydebug) { 02613 ast_verbose("Received LineStateReq\n"); 02614 } 02615 memset(req, 0, SKINNY_MAX_PACKET); 02616 req->len = htolel(sizeof(line_stat_res_message)+4); 02617 req->e = htolel(LINE_STAT_RES_MESSAGE); 02618 sub = find_subchannel_by_line(s->device->lines); 02619 if (!sub) { 02620 ast_log(LOG_NOTICE, "No available lines on: %s\n", s->device->name); 02621 return 0; 02622 } 02623 lines = sub->parent; 02624 ast_mutex_lock(&devicelock); 02625 for (i=1; i < lineNumber; i++) { 02626 lines = lines->next; 02627 } 02628 ast_mutex_unlock(&devicelock); 02629 req->data.linestat.linenumber = letohl(lineNumber); 02630 memcpy(req->data.linestat.lineDirNumber, lines->name, 02631 sizeof(req->data.linestat.lineDirNumber)); 02632 memcpy(req->data.linestat.lineDisplayName, lines->label, 02633 sizeof(req->data.linestat.lineDisplayName)); 02634 transmit_response(s,req); 02635 break; 02636 case CAPABILITIES_RES_MESSAGE: 02637 if (skinnydebug) { 02638 ast_verbose("Received CapabilitiesRes\n"); 02639 } 02640 /* XXX process the capabilites */ 02641 break; 02642 case KEEP_ALIVE_MESSAGE: 02643 memset(req, 0, SKINNY_MAX_PACKET); 02644 req->len = htolel(4); 02645 req->e = htolel(KEEP_ALIVE_ACK_MESSAGE); 02646 transmit_response(s, req); 02647 do_housekeeping(s); 02648 break; 02649 case OFFHOOK_MESSAGE: 02650 transmit_ringer_mode(s,SKINNY_RING_OFF); 02651 transmit_lamp_indication(s, STIMULUS_LINE, s->device->lines->instance, SKINNY_LAMP_ON); 02652 sub = find_subchannel_by_line(s->device->lines); 02653 if (!sub) { 02654 ast_log(LOG_NOTICE, "No available lines on: %s\n", s->device->name); 02655 return 0; 02656 } 02657 sub->parent->hookstate = SKINNY_OFFHOOK; 02658 02659 if (sub->outgoing) { 02660 /* We're answering a ringing call */ 02661 ast_queue_control(sub->owner, AST_CONTROL_ANSWER); 02662 transmit_callstate(s, s->device->lines->instance, SKINNY_OFFHOOK, sub->callid); 02663 transmit_tone(s, SKINNY_SILENCE); 02664 transmit_callstate(s, s->device->lines->instance, SKINNY_CONNECTED, sub->callid); 02665 start_rtp(sub); 02666 ast_setstate(sub->owner, AST_STATE_UP); 02667 /* XXX select the appropriate soft key here */ 02668 } else { 02669 if (!sub->owner) { 02670 transmit_callstate(s, s->device->lines->instance, SKINNY_OFFHOOK, sub->callid); 02671 if (skinnydebug) { 02672 ast_verbose("Attempting to Clear display on Skinny %s@%s\n",sub->parent->name, sub->parent->parent->name); 02673 } 02674 transmit_displaymessage(s, NULL); /* clear display */ 02675 transmit_tone(s, SKINNY_DIALTONE); 02676 c = skinny_new(sub, AST_STATE_DOWN); 02677 if(c) { 02678 /* start the switch thread */ 02679 if (ast_pthread_create(&t, NULL, skinny_ss, c)) { 02680 ast_log(LOG_WARNING, "Unable to create switch thread: %s\n", strerror(errno)); 02681 ast_hangup(c); 02682 } 02683 } else { 02684 ast_log(LOG_WARNING, "Unable to create channel for %s@%s\n", sub->parent->name, s->device->name); 02685 } 02686 } else { 02687 ast_log(LOG_DEBUG, "Current sub [%s] already has owner\n", sub->owner->name); 02688 } 02689 } 02690 break; 02691 case ONHOOK_MESSAGE: 02692 sub = find_subchannel_by_line(s->device->lines); 02693 if (sub->parent->hookstate == SKINNY_ONHOOK) { 02694 /* Somthing else already put us back on hook */ 02695 break; 02696 } 02697 sub->cxmode = SKINNY_CX_RECVONLY; 02698 sub->parent->hookstate = SKINNY_ONHOOK; 02699 transmit_callstate(s, s->device->lines->instance, sub->parent->hookstate,sub->callid); 02700 if (skinnydebug) { 02701 ast_verbose("Skinny %s@%s went on hook\n",sub->parent->name, sub->parent->parent->name); 02702 } 02703 if (sub->parent->transfer && (sub->owner && sub->next->owner) && ((!sub->outgoing) || (!sub->next->outgoing))) { 02704 /* We're allowed to transfer, we have two active calls and */ 02705 /* we made at least one of the calls. Let's try and transfer */ 02706 02707 #if 0 02708 if ((res = attempt_transfer(p)) < 0) { 02709 if (p->sub->next->owner) { 02710 sub->next->alreadygone = 1; 02711 ast_queue_hangup(sub->next->owner,1); 02712 } 02713 } else if (res) { 02714 ast_log(LOG_WARNING, "Transfer attempt failed\n"); 02715 return -1; 02716 } 02717 #endif 02718 } else { 02719 /* Hangup the current call */ 02720 /* If there is another active call, skinny_hangup will ring the phone with the other call */ 02721 if (sub->owner) { 02722 sub->alreadygone = 1; 02723 ast_queue_hangup(sub->owner); 02724 } else { 02725 ast_log(LOG_WARNING, "Skinny(%s@%s-%d) channel already destroyed\n", 02726 sub->parent->name, sub->parent->parent->name, sub->callid); 02727 } 02728 } 02729 if ((sub->parent->hookstate == SKINNY_ONHOOK) && (!sub->next->rtp)) { 02730 do_housekeeping(s); 02731 } 02732 break; 02733 case KEYPAD_BUTTON_MESSAGE: 02734 digit = letohl(req->data.keypad.button); 02735 if (skinnydebug) { 02736 ast_verbose("Collected digit: [%d]\n", digit); 02737 } 02738 f.frametype = AST_FRAME_DTMF; 02739 if (digit == 14) { 02740 d = '*'; 02741 } else if (digit == 15) { 02742 d = '#'; 02743 } else if (digit >=0 && digit <= 9) { 02744 d = '0' + digit; 02745 } else { 02746 /* digit=10-13 (A,B,C,D ?), or 02747 * digit is bad value 02748 * 02749 * probably should not end up here, but set 02750 * value for backward compatibility, and log 02751 * a warning. 02752 */ 02753 d = '0' + digit; 02754 ast_log(LOG_WARNING, "Unsupported digit %d\n", digit); 02755 } 02756 f.subclass = d; 02757 f.src = "skinny"; 02758 sub = find_subchannel_by_line(s->device->lines); 02759 if (sub->owner) { 02760 /* XXX MUST queue this frame to all subs in threeway call if threeway call is active */ 02761 ast_queue_frame(sub->owner, &f); 02762 if (sub->next->owner) { 02763 ast_queue_frame(sub->next->owner, &f); 02764 } 02765 } else { 02766 ast_verbose("No owner: %s\n", s->device->lines->name); 02767 } 02768 break; 02769 case OPEN_RECIEVE_CHANNEL_ACK_MESSAGE: 02770 ast_verbose("Recieved Open Recieve Channel Ack\n"); 02771 status = letohl(req->data.openrecievechannelack.status); 02772 if (status) { 02773 ast_log(LOG_ERROR, "Open Recieve Channel Failure\n"); 02774 break; 02775 } 02776 /* ENDIAN */ 02777 memcpy(addr, req->data.openrecievechannelack.ipAddr, sizeof(addr)); 02778 port = htolel(req->data.openrecievechannelack.port); 02779 sin.sin_family = AF_INET; 02780 /* I smell endian problems */ 02781 memcpy(&sin.sin_addr, addr, sizeof(sin.sin_addr)); 02782 sin.sin_port = htons(port); 02783 if (skinnydebug) { 02784 ast_verbose("ipaddr = %s:%d\n", ast_inet_ntoa(iabuf, sizeof(iabuf), sin.sin_addr), ntohs(sin.sin_port)); 02785 } 02786 sub = find_subchannel_by_line(s->device->lines); 02787 if (sub->rtp) { 02788 ast_rtp_set_peer(sub->rtp, &sin); 02789 ast_rtp_get_us(sub->rtp, &us); 02790 } else { 02791 ast_log(LOG_ERROR, "No RTP structure, this is very bad\n"); 02792 break; 02793 } 02794 memset(req, 0, SKINNY_MAX_PACKET); 02795 req->len = htolel(sizeof(start_media_transmission_message)+4); 02796 req->e = htolel(START_MEDIA_TRANSMISSION_MESSAGE); 02797 req->data.startmedia.conferenceId = 0; 02798 req->data.startmedia.passThruPartyId = 0; 02799 memcpy(req->data.startmedia.remoteIp, &s->device->ourip, 4); /* Endian? */ 02800 req->data.startmedia.remotePort = htolel(ntohs(us.sin_port)); 02801 req->data.startmedia.packetSize = htolel(20); 02802 req->data.startmedia.payloadType = htolel(convert_cap(s->device->lines->capability)); 02803 req->data.startmedia.qualifier.precedence = htolel(127); 02804 req->data.startmedia.qualifier.vad = 0; 02805 req->data.startmedia.qualifier.packets = 0; 02806 req->data.startmedia.qualifier.bitRate = 0; 02807 transmit_response(s, req); 02808 break; 02809 default: 02810 ast_verbose("RECEIVED UNKNOWN MESSAGE TYPE: %x\n", letohl(req->e)); 02811 break; 02812 } 02813 free(req); 02814 return 1; 02815 }
static int has_voicemail | ( | struct skinny_line * | l | ) | [static] |
Definition at line 1298 of file chan_skinny.c.
References ast_app_has_voicemail(), and skinny_line::mailbox.
01299 { 01300 return ast_app_has_voicemail(l->mailbox, NULL); 01301 }
char* key | ( | void | ) |
Returns the ASTERISK_GPL_KEY.
This returns the ASTERISK_GPL_KEY, signifiying that you agree to the terms of the GPL stated in the ASTERISK_GPL_KEY. Your module will not load if it does not return the EXACT message:
char *key(void) { return ASTERISK_GPL_KEY; }
Definition at line 3356 of file chan_skinny.c.
References ASTERISK_GPL_KEY.
03357 { 03358 return ASTERISK_GPL_KEY; 03359 }
int load_module | ( | void | ) |
Initialize the module.
Initialize the Agents module. This function is being called by Asterisk when loading the module. Among other thing it registers applications, cli commands and reads the cofiguration file.
Definition at line 3259 of file chan_skinny.c.
References ast_channel_register(), ast_cli_register(), ast_log(), ast_rtp_proto_register(), cli_debug, cli_no_debug, cli_show_devices, cli_show_lines, htolel, io, io_context_create(), LOG_ERROR, LOG_WARNING, reload_config(), restart_monitor(), sched_context_create(), skinny_rtp, skinny_tech, soft_key_template_default, and type.
03260 { 03261 int res = 0; 03262 03263 for (; res < (sizeof(soft_key_template_default) / sizeof(soft_key_template_default[0])); res++) { 03264 soft_key_template_default[res].softKeyEvent = htolel(soft_key_template_default[res].softKeyEvent); 03265 } 03266 /* load and parse config */ 03267 res = reload_config(); 03268 03269 ast_rtp_proto_register(&skinny_rtp); 03270 ast_cli_register(&cli_show_devices); 03271 ast_cli_register(&cli_show_lines); 03272 ast_cli_register(&cli_debug); 03273 ast_cli_register(&cli_no_debug); 03274 sched = sched_context_create(); 03275 if (!sched) { 03276 ast_log(LOG_WARNING, "Unable to create schedule context\n"); 03277 } 03278 io = io_context_create(); 03279 if (!io) { 03280 ast_log(LOG_WARNING, "Unable to create I/O context\n"); 03281 } 03282 /* And start the monitor for the first time */ 03283 restart_monitor(); 03284 03285 /* Announce our presence to Asterisk */ 03286 if (!res) { 03287 /* Make sure we can register our skinny channel type */ 03288 if (ast_channel_register(&skinny_tech)) { 03289 ast_log(LOG_ERROR, "Unable to register channel class %s\n", type); 03290 return -1; 03291 } 03292 } 03293 return res; 03294 }
int reload | ( | void | ) |
Reload stuff.
This function is where any reload routines take place. Re-read config files, change signalling, whatever is appropriate on a reload.
Definition at line 3250 of file chan_skinny.c.
References delete_devices(), reload_config(), and restart_monitor().
03251 { 03252 delete_devices(); 03253 reload_config(); 03254 restart_monitor(); 03255 return 0; 03256 }
static int reload_config | ( | void | ) | [static] |
Definition at line 3072 of file chan_skinny.c.
References accept_thread(), ahp, ast_category_browse(), ast_config_destroy(), ast_config_load(), ast_getformatbyname(), ast_gethostbyname(), ast_inet_ntoa(), ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_pthread_create, ast_variable_browse(), ast_verbose(), build_device(), cfg, DEFAULT_SKINNY_BACKLOG, DEFAULT_SKINNY_PORT, devices, format, ast_variable::lineno, LOG_ERROR, LOG_NOTICE, LOG_WARNING, skinny_device::name, ast_variable::name, skinny_device::next, ast_variable::next, option_verbose, ast_variable::value, VERBOSE_PREFIX_2, and VERBOSE_PREFIX_3.
03073 { 03074 int on = 1; 03075 struct ast_config *cfg; 03076 struct ast_variable *v; 03077 int format; 03078 char *cat; 03079 char iabuf[INET_ADDRSTRLEN]; 03080 struct skinny_device *d; 03081 int oldport = ntohs(bindaddr.sin_port); 03082 03083 if (gethostname(ourhost, sizeof(ourhost))) { 03084 ast_log(LOG_WARNING, "Unable to get hostname, Skinny disabled\n"); 03085 return 0; 03086 } 03087 cfg = ast_config_load(config); 03088 03089 /* We *must* have a config file otherwise stop immediately */ 03090 if (!cfg) { 03091 ast_log(LOG_NOTICE, "Unable to load config %s, Skinny disabled\n", config); 03092 return 0; 03093 } 03094 /* load the general section */ 03095 memset(&bindaddr, 0, sizeof(bindaddr)); 03096 v = ast_variable_browse(cfg, "general"); 03097 while(v) { 03098 /* Create the interface list */ 03099 if (!strcasecmp(v->name, "bindaddr")) { 03100 if (!(hp = ast_gethostbyname(v->value, &ahp))) { 03101 ast_log(LOG_WARNING, "Invalid address: %s\n", v->value); 03102 } else { 03103 memcpy(&bindaddr.sin_addr, hp->h_addr, sizeof(bindaddr.sin_addr)); 03104 } 03105 } else if (!strcasecmp(v->name, "keepAlive")) { 03106 keep_alive = atoi(v->value); 03107 } else if (!strcasecmp(v->name, "dateFormat")) { 03108 strncpy(date_format, v->value, sizeof(date_format) - 1); 03109 } else if (!strcasecmp(v->name, "allow")) { 03110 format = ast_getformatbyname(v->value); 03111 if (format < 1) { 03112 ast_log(LOG_WARNING, "Cannot allow unknown format '%s'\n", v->value); 03113 } else { 03114 capability |= format; 03115 } 03116 } else if (!strcasecmp(v->name, "disallow")) { 03117 format = ast_getformatbyname(v->value); 03118 if (format < 1) { 03119 ast_log(LOG_WARNING, "Cannot disallow unknown format '%s'\n", v->value); 03120 } else { 03121 capability &= ~format; 03122 } 03123 } else if (!strcasecmp(v->name, "port")) { 03124 if (sscanf(v->value, "%d", &ourport) == 1) { 03125 bindaddr.sin_port = htons(ourport); 03126 } else { 03127 ast_log(LOG_WARNING, "Invalid port number '%s' at line %d of %s\n", v->value, v->lineno, config); 03128 } 03129 } 03130 v = v->next; 03131 } 03132 if (ntohl(bindaddr.sin_addr.s_addr)) { 03133 memcpy(&__ourip, &bindaddr.sin_addr, sizeof(__ourip)); 03134 } else { 03135 hp = ast_gethostbyname(ourhost, &ahp); 03136 if (!hp) { 03137 ast_log(LOG_WARNING, "Unable to get our IP address, Skinny disabled\n"); 03138 ast_config_destroy(cfg); 03139 return 0; 03140 } 03141 memcpy(&__ourip, hp->h_addr, sizeof(__ourip)); 03142 } 03143 if (!ntohs(bindaddr.sin_port)) { 03144 bindaddr.sin_port = ntohs(DEFAULT_SKINNY_PORT); 03145 } 03146 bindaddr.sin_family = AF_INET; 03147 03148 /* load the device sections */ 03149 cat = ast_category_browse(cfg, NULL); 03150 while(cat) { 03151 if (!strcasecmp(cat, "general")) { 03152 /* Nothing to do */ 03153 #if 0 03154 } else if (!strncasecmp(cat, "paging-", 7)) { 03155 p = build_paging_device(cat, ast_variable_browse(cfg, cat)); 03156 if (p) { 03157 } 03158 #endif 03159 } else { 03160 d = build_device(cat, ast_variable_browse(cfg, cat)); 03161 if (d) { 03162 if (option_verbose > 2) { 03163 ast_verbose(VERBOSE_PREFIX_3 "Added device '%s'\n", d->name); 03164 } 03165 ast_mutex_lock(&devicelock); 03166 d->next = devices; 03167 devices = d; 03168 ast_mutex_unlock(&devicelock); 03169 } 03170 } 03171 cat = ast_category_browse(cfg, cat); 03172 } 03173 ast_mutex_lock(&netlock); 03174 if ((skinnysock > -1) && (ntohs(bindaddr.sin_port) != oldport)) { 03175 close(skinnysock); 03176 skinnysock = -1; 03177 } 03178 if (skinnysock < 0) { 03179 skinnysock = socket(AF_INET, SOCK_STREAM, 0); 03180 if(setsockopt(skinnysock, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on)) == -1) { 03181 ast_log(LOG_ERROR, "Set Socket Options failed: errno %d, %s", errno, strerror(errno)); 03182 ast_config_destroy(cfg); 03183 return 0; 03184 } 03185 if (skinnysock < 0) { 03186 ast_log(LOG_WARNING, "Unable to create Skinny socket: %s\n", strerror(errno)); 03187 } else { 03188 if (bind(skinnysock, (struct sockaddr *)&bindaddr, sizeof(bindaddr)) < 0) { 03189 ast_log(LOG_WARNING, "Failed to bind to %s:%d: %s\n", 03190 ast_inet_ntoa(iabuf, sizeof(iabuf), bindaddr.sin_addr), ntohs(bindaddr.sin_port), 03191 strerror(errno)); 03192 close(skinnysock); 03193 skinnysock = -1; 03194 ast_config_destroy(cfg); 03195 return 0; 03196 } 03197 if (listen(skinnysock,DEFAULT_SKINNY_BACKLOG)) { 03198 ast_log(LOG_WARNING, "Failed to start listening to %s:%d: %s\n", 03199 ast_inet_ntoa(iabuf, sizeof(iabuf), bindaddr.sin_addr), ntohs(bindaddr.sin_port), 03200 strerror(errno)); 03201 close(skinnysock); 03202 skinnysock = -1; 03203 ast_config_destroy(cfg); 03204 return 0; 03205 } 03206 if (option_verbose > 1) { 03207 ast_verbose(VERBOSE_PREFIX_2 "Skinny listening on %s:%d\n", 03208 ast_inet_ntoa(iabuf, sizeof(iabuf), bindaddr.sin_addr), ntohs(bindaddr.sin_port)); 03209 } 03210 ast_pthread_create(&accept_t,NULL, accept_thread, NULL); 03211 } 03212 } 03213 ast_mutex_unlock(&netlock); 03214 ast_config_destroy(cfg); 03215 return 0; 03216 }
static skinny_req* req_alloc | ( | size_t | size | ) | [static] |
Definition at line 927 of file chan_skinny.c.
References malloc.
Referenced by transmit_callinfo(), transmit_callstate(), transmit_connect(), transmit_diallednumber(), transmit_displaymessage(), transmit_displaynotify(), transmit_displaypromptstatus(), transmit_lamp_indication(), transmit_ringer_mode(), transmit_speaker_mode(), and transmit_tone().
00928 { 00929 skinny_req *req; 00930 req = malloc(size+12); 00931 if (!req) { 00932 return NULL; 00933 } 00934 memset(req, 0, size+12); 00935 return req; 00936 }
static int restart_monitor | ( | void | ) | [static] |
Definition at line 3006 of file chan_skinny.c.
References ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_pthread_create, AST_PTHREADT_NULL, AST_PTHREADT_STOP, do_monitor(), LOG_ERROR, and LOG_WARNING.
03007 { 03008 /* If we're supposed to be stopped -- stay stopped */ 03009 if (monitor_thread == AST_PTHREADT_STOP) 03010 return 0; 03011 if (ast_mutex_lock(&monlock)) { 03012 ast_log(LOG_WARNING, "Unable to lock monitor\n"); 03013 return -1; 03014 } 03015 if (monitor_thread == pthread_self()) { 03016 ast_mutex_unlock(&monlock); 03017 ast_log(LOG_WARNING, "Cannot kill myself\n"); 03018 return -1; 03019 } 03020 if (monitor_thread != AST_PTHREADT_NULL) { 03021 /* Wake up the thread */ 03022 pthread_kill(monitor_thread, SIGURG); 03023 } else { 03024 /* Start a new monitor */ 03025 if (ast_pthread_create(&monitor_thread, NULL, do_monitor, NULL) < 0) { 03026 ast_mutex_unlock(&monlock); 03027 ast_log(LOG_ERROR, "Unable to start monitor thread.\n"); 03028 return -1; 03029 } 03030 } 03031 ast_mutex_unlock(&monlock); 03032 return 0; 03033 }
static int skinny_answer | ( | struct ast_channel * | ast | ) | [static] |
Definition at line 2024 of file chan_skinny.c.
References ast_channel::_state, ast_setstate(), AST_STATE_UP, ast_verbose(), skinny_subchannel::callid, skinny_subchannel::cxmode, skinny_line::instance, skinny_device::name, skinny_line::name, ast_channel::name, skinny_line::parent, skinny_subchannel::parent, skinny_subchannel::rtp, s, skinny_device::session, SKINNY_CONNECTED, SKINNY_CX_SENDRECV, SKINNY_NOTONE, start_rtp(), skinny_line::sub, ast_channel::tech_pvt, transmit_callstate(), transmit_displaypromptstatus(), and transmit_tone().
02025 { 02026 int res = 0; 02027 struct skinny_subchannel *sub = ast->tech_pvt; 02028 struct skinny_line *l = sub->parent; 02029 struct skinnysession *s = l->parent->session; 02030 02031 sub->cxmode = SKINNY_CX_SENDRECV; 02032 if (!sub->rtp) { 02033 start_rtp(sub); 02034 } 02035 ast_verbose("skinny_answer(%s) on %s@%s-%d\n", ast->name, l->name, l->parent->name, sub->callid); 02036 if (ast->_state != AST_STATE_UP) { 02037 ast_setstate(ast, AST_STATE_UP); 02038 } 02039 transmit_tone(s, SKINNY_NOTONE); 02040 transmit_callstate(s, l->instance, SKINNY_CONNECTED, sub->callid); 02041 transmit_displaypromptstatus(s, "Connected", 0, l->instance, sub->callid); 02042 return res; 02043 }
static int skinny_call | ( | struct ast_channel * | ast, | |
char * | dest, | |||
int | timeout | |||
) | [static] |
Definition at line 1896 of file chan_skinny.c.
References ast_channel::_state, ast_build_string(), AST_CONTROL_BUSY, AST_CONTROL_RINGING, ast_log(), ast_queue_control(), ast_setstate(), AST_STATE_DOWN, AST_STATE_RESERVED, AST_STATE_RINGING, ast_verbose(), skinny_subchannel::callid, ast_channel::cid, skinny_line::cid_name, ast_callerid::cid_name, skinny_line::cid_num, ast_callerid::cid_num, skinny_line::dnd, skinny_line::hookstate, skinny_line::instance, LOG_ERROR, LOG_WARNING, ast_channel::name, skinny_subchannel::outgoing, skinny_line::parent, skinny_subchannel::parent, skinny_device::registered, skinny_device::session, SKINNY_ALERT, SKINNY_CALLWAITTONE, SKINNY_LAMP_BLINK, SKINNY_OFFHOOK, SKINNY_ONHOOK, SKINNY_RING_INSIDE, SKINNY_RINGIN, STIMULUS_LINE, ast_channel::tech_pvt, transmit_callinfo(), transmit_callstate(), transmit_displaymessage(), transmit_displaypromptstatus(), transmit_lamp_indication(), transmit_ringer_mode(), transmit_tone(), and VERBOSE_PREFIX_3.
01897 { 01898 int res = 0; 01899 int tone = 0; 01900 struct skinny_line *l; 01901 struct skinny_subchannel *sub; 01902 struct skinnysession *session; 01903 01904 sub = ast->tech_pvt; 01905 l = sub->parent; 01906 session = l->parent->session; 01907 01908 if (!l->parent->registered) { 01909 ast_log(LOG_ERROR, "Device not registered, cannot call %s\n", dest); 01910 return -1; 01911 } 01912 01913 if ((ast->_state != AST_STATE_DOWN) && (ast->_state != AST_STATE_RESERVED)) { 01914 ast_log(LOG_WARNING, "skinny_call called on %s, neither down nor reserved\n", ast->name); 01915 return -1; 01916 } 01917 01918 if (skinnydebug) { 01919 ast_verbose(VERBOSE_PREFIX_3 "skinny_call(%s)\n", ast->name); 01920 } 01921 01922 if (l->dnd) { 01923 ast_queue_control(ast, AST_CONTROL_BUSY); 01924 return -1; 01925 } 01926 01927 switch (l->hookstate) { 01928 case SKINNY_OFFHOOK: 01929 tone = SKINNY_CALLWAITTONE; 01930 break; 01931 case SKINNY_ONHOOK: 01932 tone = SKINNY_ALERT; 01933 break; 01934 default: 01935 ast_log(LOG_ERROR, "Don't know how to deal with hookstate %d\n", l->hookstate); 01936 break; 01937 } 01938 01939 transmit_lamp_indication(session, STIMULUS_LINE, l->instance, SKINNY_LAMP_BLINK); 01940 transmit_ringer_mode(session, SKINNY_RING_INSIDE); 01941 01942 if (ast->cid.cid_num) { 01943 char ciddisplay[41]; 01944 char *work; 01945 size_t size = sizeof(ciddisplay); 01946 01947 /* For now, we'll assume that if it is 10 numbers, it is a standard NANPA number */ 01948 if (strlen(ast->cid.cid_num) == 10) { 01949 ast_build_string(&work, &size, "(xxx)xxx-xxxx %s", 01950 ast->cid.cid_name ? ast->cid.cid_name : ""); 01951 memcpy(&ciddisplay[1], ast->cid.cid_num, 3); 01952 memcpy(&ciddisplay[5], &ast->cid.cid_num[3], 3); 01953 memcpy(&ciddisplay[9], &ast->cid.cid_num[6], 4); 01954 } else { 01955 if (strlen(ast->cid.cid_num) < 41) { 01956 ast_build_string(&work, &size, "%s -- %s", ast->cid.cid_num, 01957 ast->cid.cid_name ? ast->cid.cid_name : ""); 01958 } else { 01959 strncpy(ciddisplay, "Number too long!", 15); 01960 } 01961 } 01962 if (skinnydebug) { 01963 ast_verbose("Trying to send: '%s'\n",ciddisplay); 01964 } 01965 transmit_displaymessage(session, ciddisplay); 01966 } else { 01967 transmit_displaymessage(session, "Unknown Name"); 01968 } 01969 transmit_tone(session, tone); 01970 transmit_callstate(session, l->instance, SKINNY_RINGIN, sub->callid); 01971 transmit_displaypromptstatus(session, "Ring-In", 0, l->instance, sub->callid); 01972 transmit_callinfo(session, ast->cid.cid_name, ast->cid.cid_num, l->cid_name, l->cid_num, l->instance, sub->callid, 1); 01973 01974 /* XXX need to deal with softkeys */ 01975 01976 ast_setstate(ast, AST_STATE_RINGING); 01977 ast_queue_control(ast, AST_CONTROL_RINGING); 01978 sub->outgoing = 1; 01979 return res; 01980 }
static int skinny_do_debug | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Definition at line 1364 of file chan_skinny.c.
References ast_cli(), RESULT_SHOWUSAGE, and RESULT_SUCCESS.
01365 { 01366 if (argc != 2) { 01367 return RESULT_SHOWUSAGE; 01368 } 01369 skinnydebug = 1; 01370 ast_cli(fd, "Skinny Debugging Enabled\n"); 01371 return RESULT_SUCCESS; 01372 }
static int skinny_fixup | ( | struct ast_channel * | oldchan, | |
struct ast_channel * | newchan | |||
) | [static] |
Definition at line 2102 of file chan_skinny.c.
References ast_log(), LOG_NOTICE, LOG_WARNING, ast_channel::name, skinny_subchannel::owner, and ast_channel::tech_pvt.
02103 { 02104 struct skinny_subchannel *sub = newchan->tech_pvt; 02105 ast_log(LOG_NOTICE, "skinny_fixup(%s, %s)\n", oldchan->name, newchan->name); 02106 if (sub->owner != oldchan) { 02107 ast_log(LOG_WARNING, "old channel wasn't %p but was %p\n", oldchan, sub->owner); 02108 return -1; 02109 } 02110 sub->owner = newchan; 02111 return 0; 02112 }
static struct ast_rtp* skinny_get_rtp_peer | ( | struct ast_channel * | chan | ) | [static] |
Definition at line 1336 of file chan_skinny.c.
References skinny_subchannel::rtp, and ast_channel::tech_pvt.
01337 { 01338 struct skinny_subchannel *sub; 01339 sub = chan->tech_pvt; 01340 if (sub && sub->rtp) { 01341 return sub->rtp; 01342 } 01343 return NULL; 01344 }
static struct ast_rtp* skinny_get_vrtp_peer | ( | struct ast_channel * | chan | ) | [static] |
static int skinny_hangup | ( | struct ast_channel * | ast | ) | [static] |
Definition at line 1982 of file chan_skinny.c.
References skinny_subchannel::alreadygone, ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_rtp_destroy(), ast_verbose(), skinny_subchannel::callid, do_housekeeping(), skinny_line::hookstate, skinny_line::instance, skinny_subchannel::lock, LOG_DEBUG, skinny_device::name, skinny_line::name, ast_channel::name, skinny_subchannel::outgoing, skinny_subchannel::owner, skinny_line::parent, skinny_subchannel::parent, skinny_device::registered, skinny_subchannel::rtp, s, skinny_device::session, SKINNY_LAMP_OFF, SKINNY_OFFHOOK, SKINNY_ONHOOK, SKINNY_RING_OFF, SKINNY_SILENCE, SKINNY_SPEAKEROFF, STIMULUS_LINE, skinny_line::sub, ast_channel::tech_pvt, transmit_callstate(), transmit_lamp_indication(), transmit_ringer_mode(), transmit_speaker_mode(), transmit_tone(), skinny_line::type, and TYPE_LINE.
01983 { 01984 struct skinny_subchannel *sub = ast->tech_pvt; 01985 struct skinny_line *l = sub->parent; 01986 struct skinnysession *s = l->parent->session; 01987 01988 if (skinnydebug) { 01989 ast_verbose("skinny_hangup(%s) on %s@%s\n", ast->name, l->name, l->parent->name); 01990 } 01991 if (!ast->tech_pvt) { 01992 ast_log(LOG_DEBUG, "Asked to hangup channel not connected\n"); 01993 return 0; 01994 } 01995 01996 if (l->parent->registered) { 01997 if ((sub->parent->type = TYPE_LINE) && (sub->parent->hookstate == SKINNY_OFFHOOK)) { 01998 sub->parent->hookstate = SKINNY_ONHOOK; 01999 transmit_callstate(s, l->instance, SKINNY_ONHOOK, sub->callid); 02000 transmit_lamp_indication(s, STIMULUS_LINE, l->instance, SKINNY_LAMP_OFF); 02001 transmit_speaker_mode(s, SKINNY_SPEAKEROFF); 02002 } else if ((sub->parent->type = TYPE_LINE) && (sub->parent->hookstate == SKINNY_ONHOOK)) { 02003 transmit_callstate(s, l->instance, SKINNY_ONHOOK, sub->callid); 02004 transmit_speaker_mode(s, SKINNY_SPEAKEROFF); 02005 transmit_ringer_mode(s, SKINNY_RING_OFF); 02006 transmit_tone(s, SKINNY_SILENCE); 02007 transmit_lamp_indication(s, STIMULUS_LINE, l->instance, SKINNY_LAMP_OFF); 02008 do_housekeeping(s); 02009 } 02010 } 02011 ast_mutex_lock(&sub->lock); 02012 sub->owner = NULL; 02013 ast->tech_pvt = NULL; 02014 sub->alreadygone = 0; 02015 sub->outgoing = 0; 02016 if (sub->rtp) { 02017 ast_rtp_destroy(sub->rtp); 02018 sub->rtp = NULL; 02019 } 02020 ast_mutex_unlock(&sub->lock); 02021 return 0; 02022 }
static int skinny_indicate | ( | struct ast_channel * | ast, | |
int | ind | |||
) | [static] |
Definition at line 2172 of file chan_skinny.c.
References ast_channel::_state, skinny_subchannel::alreadygone, AST_CONTROL_BUSY, AST_CONTROL_CONGESTION, AST_CONTROL_PROCEEDING, AST_CONTROL_PROGRESS, AST_CONTROL_RINGING, ast_log(), AST_SOFTHANGUP_DEV, ast_softhangup_nolock(), AST_STATE_UP, ast_verbose(), skinny_subchannel::callid, ast_channel::cid, ast_callerid::cid_name, ast_callerid::cid_num, control2str(), ast_channel::exten, skinny_line::instance, LOG_WARNING, ast_channel::name, skinny_subchannel::outgoing, skinny_line::parent, skinny_subchannel::parent, skinny_subchannel::progress, skinny_subchannel::ringing, s, skinny_device::session, SKINNY_ALERT, SKINNY_BUSY, SKINNY_BUSYTONE, SKINNY_CONGESTION, SKINNY_PROGRESS, SKINNY_REORDER, SKINNY_RINGOUT, SKINNY_SILENCE, skinny_line::sub, ast_channel::tech_pvt, transmit_callinfo(), transmit_callstate(), transmit_diallednumber(), transmit_displaypromptstatus(), transmit_tone(), and VERBOSE_PREFIX_3.
02173 { 02174 struct skinny_subchannel *sub = ast->tech_pvt; 02175 struct skinny_line *l = sub->parent; 02176 struct skinnysession *s = l->parent->session; 02177 02178 if (skinnydebug) { 02179 ast_verbose(VERBOSE_PREFIX_3 "Asked to indicate '%s' condition on channel %s\n", control2str(ind), ast->name); 02180 } 02181 switch(ind) { 02182 case AST_CONTROL_RINGING: 02183 if (ast->_state != AST_STATE_UP) { 02184 if (!sub->progress) { 02185 transmit_tone(s, SKINNY_ALERT); 02186 transmit_callstate(s, l->instance, SKINNY_RINGOUT, sub->callid); 02187 transmit_diallednumber(s, ast->exten, l->instance, sub->callid); 02188 transmit_displaypromptstatus(s, "Ring Out", 0, l->instance, sub->callid); 02189 transmit_callinfo(s, ast->cid.cid_name, ast->cid.cid_num, ast->exten, ast->exten, l->instance, sub->callid, 2); /* 2 = outgoing from phone */ 02190 sub->ringing = 1; 02191 break; 02192 } 02193 } 02194 return -1; 02195 case AST_CONTROL_BUSY: 02196 if (ast->_state != AST_STATE_UP) { 02197 transmit_tone(s, SKINNY_BUSYTONE); 02198 transmit_callstate(s, l->instance, SKINNY_BUSY, sub->callid); 02199 sub->alreadygone = 1; 02200 ast_softhangup_nolock(ast, AST_SOFTHANGUP_DEV); 02201 break; 02202 } 02203 return -1; 02204 case AST_CONTROL_CONGESTION: 02205 if (ast->_state != AST_STATE_UP) { 02206 transmit_tone(s, SKINNY_REORDER); 02207 transmit_callstate(s, l->instance, SKINNY_CONGESTION, sub->callid); 02208 sub->alreadygone = 1; 02209 ast_softhangup_nolock(ast, AST_SOFTHANGUP_DEV); 02210 break; 02211 } 02212 return -1; 02213 case AST_CONTROL_PROGRESS: 02214 if ((ast->_state != AST_STATE_UP) && !sub->progress && !sub->outgoing) { 02215 transmit_tone(s, SKINNY_ALERT); 02216 transmit_callstate(s, l->instance, SKINNY_PROGRESS, sub->callid); 02217 transmit_displaypromptstatus(s, "Call Progress", 0, l->instance, sub->callid); 02218 transmit_callinfo(s, ast->cid.cid_name, ast->cid.cid_num, ast->exten, ast->exten, l->instance, sub->callid, 2); /* 2 = outgoing from phone */ 02219 sub->progress = 1; 02220 break; 02221 } 02222 return -1; 02223 case -1: 02224 transmit_tone(s, SKINNY_SILENCE); 02225 break; 02226 case AST_CONTROL_PROCEEDING: 02227 break; 02228 default: 02229 ast_log(LOG_WARNING, "Don't know how to indicate condition %d\n", ind); 02230 return -1; 02231 } 02232 return 0; 02233 }
static struct ast_channel* skinny_new | ( | struct skinny_subchannel * | sub, | |
int | state | |||
) | [static] |
Definition at line 2235 of file chan_skinny.c.
References ast_channel::accountcode, skinny_line::accountcode, ast_channel::adsicpe, ast_channel::amaflags, skinny_line::amaflags, AST_ADSI_UNAVAILABLE, ast_best_codec(), ast_channel_alloc(), ast_hangup(), ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_pbx_start(), ast_rtp_fd(), ast_setstate(), AST_STATE_DOWN, AST_STATE_RING, ast_strlen_zero(), ast_update_use_count(), ast_verbose(), skinny_line::call_forward, ast_channel::call_forward, skinny_line::callgroup, ast_channel::callgroup, skinny_subchannel::callid, skinny_line::capability, ast_channel::cid, ast_callerid::cid_name, skinny_line::cid_name, ast_callerid::cid_num, skinny_line::cid_num, skinny_line::context, ast_channel::context, skinny_line::exten, ast_channel::exten, ast_channel::fds, fmt, ast_channel::language, skinny_line::language, LOG_WARNING, skinny_device::name, skinny_line::name, ast_channel::name, ast_channel::nativeformats, skinny_subchannel::owner, skinny_line::parent, skinny_subchannel::parent, skinny_line::pickupgroup, ast_channel::pickupgroup, ast_channel::priority, ast_channel::rawreadformat, ast_channel::rawwriteformat, ast_channel::readformat, ast_channel::rings, skinny_subchannel::rtp, skinny_tech, strdup, skinny_line::sub, ast_channel::tech, ast_channel::tech_pvt, ast_channel::type, usecnt_lock, and ast_channel::writeformat.
Referenced by handle_message(), and skinny_request().
02236 { 02237 struct ast_channel *tmp; 02238 struct skinny_line *l = sub->parent; 02239 int fmt; 02240 l = sub->parent; 02241 tmp = ast_channel_alloc(1); 02242 if (tmp) { 02243 tmp->tech = &skinny_tech; 02244 tmp->nativeformats = l->capability; 02245 if (!tmp->nativeformats) 02246 tmp->nativeformats = capability; 02247 fmt = ast_best_codec(tmp->nativeformats); 02248 ast_verbose("skinny_new: tmp->nativeformats=%d fmt=%d\n", tmp->nativeformats, fmt); 02249 snprintf(tmp->name, sizeof(tmp->name), "Skinny/%s@%s-%d", l->name, l->parent->name, sub->callid); 02250 if (sub->rtp) { 02251 tmp->fds[0] = ast_rtp_fd(sub->rtp); 02252 } 02253 tmp->type = type; 02254 ast_setstate(tmp, state); 02255 if (state == AST_STATE_RING) { 02256 tmp->rings = 1; 02257 } 02258 tmp->writeformat = fmt; 02259 tmp->rawwriteformat = fmt; 02260 tmp->readformat = fmt; 02261 tmp->rawreadformat = fmt; 02262 tmp->tech_pvt = sub; 02263 if (!ast_strlen_zero(l->language)) { 02264 strncpy(tmp->language, l->language, sizeof(tmp->language)-1); 02265 } 02266 if (!ast_strlen_zero(l->accountcode)) { 02267 strncpy(tmp->accountcode, l->accountcode, sizeof(tmp->accountcode)-1); 02268 } 02269 if (l->amaflags) { 02270 tmp->amaflags = l->amaflags; 02271 } 02272 sub->owner = tmp; 02273 ast_mutex_lock(&usecnt_lock); 02274 usecnt++; 02275 ast_mutex_unlock(&usecnt_lock); 02276 ast_update_use_count(); 02277 tmp->callgroup = l->callgroup; 02278 tmp->pickupgroup = l->pickupgroup; 02279 strncpy(tmp->call_forward, l->call_forward, sizeof(tmp->call_forward) - 1); 02280 strncpy(tmp->context, l->context, sizeof(tmp->context)-1); 02281 strncpy(tmp->exten,l->exten, sizeof(tmp->exten)-1); 02282 02283 if (!ast_strlen_zero(l->cid_num)) 02284 tmp->cid.cid_num = strdup(l->cid_num); 02285 if (!ast_strlen_zero(l->cid_name)) 02286 tmp->cid.cid_name = strdup(l->cid_name); 02287 02288 tmp->priority = 1; 02289 tmp->adsicpe = AST_ADSI_UNAVAILABLE; 02290 02291 if (state != AST_STATE_DOWN) { 02292 if (ast_pbx_start(tmp)) { 02293 ast_log(LOG_WARNING, "Unable to start PBX on %s\n", tmp->name); 02294 ast_hangup(tmp); 02295 tmp = NULL; 02296 } 02297 } 02298 } else { 02299 ast_log(LOG_WARNING, "Unable to allocate channel structure\n"); 02300 } 02301 return tmp; 02302 }
static int skinny_no_debug | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Definition at line 1374 of file chan_skinny.c.
References ast_cli(), RESULT_SHOWUSAGE, and RESULT_SUCCESS.
01375 { 01376 if (argc != 3) { 01377 return RESULT_SHOWUSAGE; 01378 } 01379 skinnydebug = 0; 01380 ast_cli(fd, "Skinny Debugging Disabled\n"); 01381 return RESULT_SUCCESS; 01382 }
static struct ast_frame * skinny_read | ( | struct ast_channel * | ast | ) | [static] |
Definition at line 2064 of file chan_skinny.c.
References ast_mutex_lock(), ast_mutex_unlock(), skinny_subchannel::lock, skinny_rtp_read(), and ast_channel::tech_pvt.
02065 { 02066 struct ast_frame *fr; 02067 struct skinny_subchannel *sub = ast->tech_pvt; 02068 ast_mutex_lock(&sub->lock); 02069 fr = skinny_rtp_read(sub); 02070 ast_mutex_unlock(&sub->lock); 02071 return fr; 02072 }
static int skinny_register | ( | skinny_req * | req, | |
struct skinnysession * | s | |||
) | [static] |
Definition at line 1647 of file chan_skinny.c.
References ast_apply_ha(), ast_mutex_lock(), ast_mutex_unlock(), ast_strlen_zero(), skinny_req::data, devices, skinny_device::ha, skinny_device::id, letohl, register_message::name, skinny_device::next, skinny_req::reg, skinny_device::registered, s, skinny_device::session, register_message::type, skinny_device::type, and skinny_device::version_id.
Referenced by handle_message().
01648 { 01649 struct skinny_device *d; 01650 01651 ast_mutex_lock(&devicelock); 01652 d = devices; 01653 while (d) { 01654 if (!strcasecmp(req->data.reg.name, d->id) 01655 && ast_apply_ha(d->ha, &(s->sin))) { 01656 s->device = d; 01657 d->type = letohl(req->data.reg.type); 01658 if (ast_strlen_zero(d->version_id)) { 01659 strncpy(d->version_id, version_id, sizeof(d->version_id) - 1); 01660 } 01661 d->registered = 1; 01662 d->session = s; 01663 break; 01664 } 01665 d = d->next; 01666 } 01667 ast_mutex_unlock(&devicelock); 01668 if (!d) { 01669 return 0; 01670 } 01671 return 1; 01672 }
static skinny_req* skinny_req_parse | ( | struct skinnysession * | s | ) | [static] |
Definition at line 2880 of file chan_skinny.c.
References ast_log(), skinny_req::e, free, letohl, LOG_ERROR, malloc, s, and SKINNY_MAX_PACKET.
Referenced by skinny_session().
02881 { 02882 skinny_req *req; 02883 02884 req = malloc(SKINNY_MAX_PACKET); 02885 if (!req) { 02886 ast_log(LOG_ERROR, "Unable to allocate skinny_request, this is bad\n"); 02887 return NULL; 02888 } 02889 memset(req, 0, sizeof(skinny_req)); 02890 /* +8 to account for reserved and length fields */ 02891 memcpy(req, s->inbuf, letohl(*(int*)(s->inbuf))+8); 02892 if (letohl(req->e) < 0) { 02893 ast_log(LOG_ERROR, "Event Message is NULL from socket %d, This is bad\n", s->fd); 02894 free(req); 02895 return NULL; 02896 } 02897 return req; 02898 }
static struct ast_channel * skinny_request | ( | const char * | type, | |
int | format, | |||
void * | data, | |||
int * | cause | |||
) | [static] |
Definition at line 3035 of file chan_skinny.c.
References ast_log(), AST_STATE_DOWN, ast_strlen_zero(), ast_verbose(), skinny_line::callwaiting, skinny_line::dnd, find_subchannel_by_name(), LOG_NOTICE, LOG_WARNING, skinny_subchannel::next, option_verbose, skinny_subchannel::owner, skinny_subchannel::parent, restart_monitor(), skinny_new(), and VERBOSE_PREFIX_3.
03036 { 03037 int oldformat; 03038 struct skinny_subchannel *sub; 03039 struct ast_channel *tmpc = NULL; 03040 char tmp[256]; 03041 char *dest = data; 03042 03043 oldformat = format; 03044 format &= capability; 03045 if (!format) { 03046 ast_log(LOG_NOTICE, "Asked to get a channel of unsupported format '%d'\n", format); 03047 return NULL; 03048 } 03049 strncpy(tmp, dest, sizeof(tmp) - 1); 03050 if (ast_strlen_zero(tmp)) { 03051 ast_log(LOG_NOTICE, "Skinny channels require a device\n"); 03052 return NULL; 03053 } 03054 sub = find_subchannel_by_name(tmp); 03055 if (!sub) { 03056 ast_log(LOG_NOTICE, "No available lines on: %s\n", dest); 03057 return NULL; 03058 } 03059 if (option_verbose > 2) { 03060 ast_verbose(VERBOSE_PREFIX_3 "skinny_request(%s)\n", tmp); 03061 ast_verbose(VERBOSE_PREFIX_3 "Skinny cw: %d, dnd: %d, so: %d, sno: %d\n", 03062 sub->parent->callwaiting, sub->parent->dnd, sub->owner ? 1 : 0, sub->next->owner ? 1: 0); 03063 } 03064 tmpc = skinny_new(sub->owner ? sub->next : sub, AST_STATE_DOWN); 03065 if (!tmpc) { 03066 ast_log(LOG_WARNING, "Unable to make channel for '%s'\n", tmp); 03067 } 03068 restart_monitor(); 03069 return tmpc; 03070 }
static struct ast_frame* skinny_rtp_read | ( | struct skinny_subchannel * | sub | ) | [static] |
Definition at line 2045 of file chan_skinny.c.
References AST_FRAME_VOICE, ast_log(), ast_rtp_read(), ast_set_read_format(), ast_set_write_format(), ast_frame::frametype, LOG_DEBUG, ast_channel::nativeformats, skinny_subchannel::owner, ast_channel::readformat, skinny_subchannel::rtp, ast_frame::subclass, and ast_channel::writeformat.
Referenced by skinny_read().
02046 { 02047 /* Retrieve audio/etc from channel. Assumes sub->lock is already held. */ 02048 struct ast_frame *f; 02049 f = ast_rtp_read(sub->rtp); 02050 if (sub->owner) { 02051 /* We already hold the channel lock */ 02052 if (f->frametype == AST_FRAME_VOICE) { 02053 if (f->subclass != sub->owner->nativeformats) { 02054 ast_log(LOG_DEBUG, "Oooh, format changed to %d\n", f->subclass); 02055 sub->owner->nativeformats = f->subclass; 02056 ast_set_read_format(sub->owner, sub->owner->readformat); 02057 ast_set_write_format(sub->owner, sub->owner->writeformat); 02058 } 02059 } 02060 } 02061 return f; 02062 }
static int skinny_senddigit | ( | struct ast_channel * | ast, | |
char | digit | |||
) | [static] |
Definition at line 2114 of file chan_skinny.c.
References skinny_line::parent, skinny_subchannel::parent, skinny_device::session, ast_channel::tech_pvt, and transmit_tone().
02115 { 02116 #if 0 02117 struct skinny_subchannel *sub = ast->tech_pvt; 02118 int tmp; 02119 /* not right */ 02120 sprintf(tmp, "%d", digit); 02121 transmit_tone(sub->parent->parent->session, digit); 02122 #endif 02123 return -1; 02124 }
static void* skinny_session | ( | void * | data | ) | [static] |
Definition at line 2900 of file chan_skinny.c.
References ast_inet_ntoa(), ast_log(), ast_verbose(), destroy_session(), get_input(), handle_message(), LOG_NOTICE, s, skinny_req_parse(), and VERBOSE_PREFIX_3.
Referenced by accept_thread(), and unload_module().
02901 { 02902 int res; 02903 skinny_req *req; 02904 struct skinnysession *s = data; 02905 char iabuf[INET_ADDRSTRLEN]; 02906 02907 ast_verbose(VERBOSE_PREFIX_3 "Starting Skinny session from %s\n", ast_inet_ntoa(iabuf, sizeof(iabuf), s->sin.sin_addr)); 02908 for (;;) { 02909 res = 0; 02910 res = get_input(s); 02911 if (res < 0) { 02912 break; 02913 } 02914 req = skinny_req_parse(s); 02915 if (!req) { 02916 return NULL; 02917 } 02918 res = handle_message(req, s); 02919 if (res < 0) { 02920 destroy_session(s); 02921 return NULL; 02922 } 02923 } 02924 ast_log(LOG_NOTICE, "Skinny Session returned: %s\n", strerror(errno)); 02925 destroy_session(s); 02926 return 0; 02927 }
static int skinny_set_rtp_peer | ( | struct ast_channel * | chan, | |
struct ast_rtp * | rtp, | |||
struct ast_rtp * | vrtp, | |||
int | codecs, | |||
int | nat_active | |||
) | [static] |
Definition at line 1346 of file chan_skinny.c.
References ast_channel::tech_pvt.
01347 { 01348 struct skinny_subchannel *sub; 01349 sub = chan->tech_pvt; 01350 if (sub) { 01351 /* transmit_modify_with_sdp(sub, rtp); @@FIXME@@ if needed */ 01352 return 0; 01353 } 01354 return -1; 01355 }
static int skinny_show_devices | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Definition at line 1384 of file chan_skinny.c.
References skinny_device::addr, ast_cli(), ast_inet_ntoa(), ast_mutex_lock(), ast_mutex_unlock(), devices, skinny_device::id, skinny_device::lines, skinny_device::model, skinny_device::name, skinny_device::next, skinny_line::next, skinny_device::registered, RESULT_SHOWUSAGE, RESULT_SUCCESS, and skinny_device::type.
01385 { 01386 struct skinny_device *d; 01387 struct skinny_line *l; 01388 int numlines = 0; 01389 char iabuf[INET_ADDRSTRLEN]; 01390 01391 if (argc != 3) { 01392 return RESULT_SHOWUSAGE; 01393 } 01394 ast_mutex_lock(&devicelock); 01395 d = devices; 01396 01397 ast_cli(fd, "Name DeviceId IP TypeId R Model NL\n"); 01398 ast_cli(fd, "-------------------- ---------------- --------------- ------ - ------ --\n"); 01399 while(d) { 01400 l = d->lines; 01401 numlines = 0; 01402 while(l) { numlines++; l = l->next; } 01403 01404 ast_cli(fd, "%-20s %-16s %-16s %6X %c %-6s %2d\n", 01405 d->name, 01406 d->id, 01407 ast_inet_ntoa(iabuf, sizeof(iabuf), d->addr.sin_addr), 01408 d->type, 01409 d->registered?'Y':'N', 01410 d->model, 01411 numlines); 01412 01413 d = d->next; 01414 } 01415 ast_mutex_unlock(&devicelock); 01416 return RESULT_SUCCESS; 01417 }
static int skinny_show_lines | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Definition at line 1419 of file chan_skinny.c.
References ast_cli(), ast_mutex_lock(), ast_mutex_unlock(), devices, skinny_line::instance, skinny_line::label, skinny_device::lines, skinny_line::name, skinny_device::name, skinny_device::next, skinny_line::next, skinny_subchannel::owner, skinny_line::parent, RESULT_SHOWUSAGE, RESULT_SUCCESS, skinny_subchannel::rtp, and skinny_line::sub.
01420 { 01421 struct skinny_device *d; 01422 struct skinny_line *l; 01423 01424 if (argc != 3) { 01425 return RESULT_SHOWUSAGE; 01426 } 01427 ast_mutex_lock(&devicelock); 01428 d = devices; 01429 while(d) { 01430 l = d->lines; 01431 while (l) { 01432 ast_cli(fd, "%-20s %2d %-20s %-20s %c %c\n", 01433 l->parent->name, 01434 l->instance, 01435 l->name, 01436 l->label, 01437 l->sub->owner?'Y':'N', 01438 l->sub->rtp?'Y':'N'); 01439 l = l->next; 01440 } 01441 d = d->next; 01442 } 01443 ast_mutex_unlock(&devicelock); 01444 return RESULT_SUCCESS; 01445 }
static void* skinny_ss | ( | void * | data | ) | [static] |
Definition at line 1690 of file chan_skinny.c.
References ast_bridged_channel(), ast_canmatch_extension(), ast_db_put(), ast_exists_extension(), ast_hangup(), ast_ignore_pattern(), ast_indicate(), ast_log(), ast_masq_park_call(), ast_matchmore_extension(), AST_MAX_EXTENSION, ast_parking_ext(), ast_pbx_run(), ast_pickup_call(), ast_pickup_ext(), ast_safe_sleep(), ast_say_digit_str(), ast_set_callerid(), ast_setstate(), AST_STATE_RING, ast_strlen_zero(), ast_verbose(), ast_waitfordigit(), skinny_line::call_forward, skinny_line::callreturn, skinny_line::callwaiting, skinny_line::cancallforward, ast_channel::cid, skinny_line::cid_name, ast_callerid::cid_num, skinny_line::cid_num, ast_channel::context, skinny_line::dnd, ast_channel::exten, exten, skinny_line::hidecallerid, ast_channel::language, skinny_line::lastcallerid, LOG_DEBUG, LOG_WARNING, ast_channel::name, skinny_device::name, skinny_line::name, skinny_subchannel::next, option_verbose, skinny_subchannel::owner, skinny_line::parent, skinny_subchannel::parent, s, skinny_device::session, SKINNY_DIALTONE, SKINNY_REORDER, SKINNY_SILENCE, skinny_line::sub, ast_channel::tech_pvt, transmit_tone(), and VERBOSE_PREFIX_3.
Referenced by handle_message().
01691 { 01692 struct ast_channel *chan = data; 01693 struct skinny_subchannel *sub = chan->tech_pvt; 01694 struct skinny_line *l = sub->parent; 01695 struct skinnysession *s = l->parent->session; 01696 char exten[AST_MAX_EXTENSION] = ""; 01697 int len = 0; 01698 int timeout = firstdigittimeout; 01699 int res; 01700 int getforward=0; 01701 01702 if (option_verbose > 2) { 01703 ast_verbose( VERBOSE_PREFIX_3 "Starting simple switch on '%s@%s'\n", l->name, l->parent->name); 01704 } 01705 while(len < AST_MAX_EXTENSION-1) { 01706 res = ast_waitfordigit(chan, timeout); 01707 timeout = 0; 01708 if (res < 0) { 01709 if (skinnydebug) { 01710 ast_verbose("Skinny(%s@%s): waitfordigit returned < 0\n", l->name, l->parent->name); 01711 } 01712 ast_indicate(chan, -1); 01713 ast_hangup(chan); 01714 return NULL; 01715 } else if (res) { 01716 exten[len++]=res; 01717 exten[len] = '\0'; 01718 } 01719 if (!ast_ignore_pattern(chan->context, exten)) { 01720 transmit_tone(s, SKINNY_SILENCE); 01721 } 01722 if (ast_exists_extension(chan, chan->context, exten, 1, l->cid_num)) { 01723 if (!res || !ast_matchmore_extension(chan, chan->context, exten, 1, l->cid_num)) { 01724 if (getforward) { 01725 /* Record this as the forwarding extension */ 01726 strncpy(l->call_forward, exten, sizeof(l->call_forward) - 1); 01727 if (option_verbose > 2) { 01728 ast_verbose(VERBOSE_PREFIX_3 "Setting call forward to '%s' on channel %s\n", 01729 l->call_forward, chan->name); 01730 } 01731 transmit_tone(s, SKINNY_DIALTONE); 01732 if (res) { 01733 break; 01734 } 01735 ast_safe_sleep(chan, 500); 01736 ast_indicate(chan, -1); 01737 ast_safe_sleep(chan, 1000); 01738 memset(exten, 0, sizeof(exten)); 01739 transmit_tone(s, SKINNY_DIALTONE); 01740 len = 0; 01741 getforward = 0; 01742 } else { 01743 strncpy(chan->exten, exten, sizeof(chan->exten)-1); 01744 01745 if (!ast_strlen_zero(l->cid_num)) { 01746 ast_set_callerid(chan, 01747 l->hidecallerid ? "" : l->cid_num, 01748 l->hidecallerid ? "" : l->cid_name, 01749 NULL); 01750 ast_setstate(chan, AST_STATE_RING); 01751 res = ast_pbx_run(chan); 01752 if (res) { 01753 ast_log(LOG_WARNING, "PBX exited non-zero\n"); 01754 transmit_tone(s, SKINNY_REORDER); 01755 } 01756 return NULL; 01757 } 01758 } 01759 } else { 01760 /* It's a match, but they just typed a digit, and there is an ambiguous match, 01761 so just set the timeout to matchdigittimeout and wait some more */ 01762 timeout = matchdigittimeout; 01763 } 01764 } else if (res == 0) { 01765 ast_log(LOG_DEBUG, "Not enough digits (and no ambiguous match)...\n"); 01766 transmit_tone(s, SKINNY_REORDER); 01767 ast_hangup(chan); 01768 return NULL; 01769 } else if (l->callwaiting && !strcmp(exten, "*70")) { 01770 if (option_verbose > 2) { 01771 ast_verbose(VERBOSE_PREFIX_3 "Disabling call waiting on %s\n", chan->name); 01772 } 01773 /* Disable call waiting if enabled */ 01774 l->callwaiting = 0; 01775 transmit_tone(s, SKINNY_DIALTONE); 01776 len = 0; 01777 memset(exten, 0, sizeof(exten));\ 01778 timeout = firstdigittimeout; 01779 } else if (!strcmp(exten,ast_pickup_ext())) { 01780 /* Scan all channels and see if any there 01781 * ringing channqels with that have call groups 01782 * that equal this channels pickup group 01783 */ 01784 if (ast_pickup_call(chan)) { 01785 ast_log(LOG_WARNING, "No call pickup possible...\n"); 01786 transmit_tone(s, SKINNY_REORDER); 01787 } 01788 ast_hangup(chan); 01789 return NULL; 01790 } else if (!l->hidecallerid && !strcmp(exten, "*67")) { 01791 if (option_verbose > 2) { 01792 ast_verbose(VERBOSE_PREFIX_3 "Disabling Caller*ID on %s\n", chan->name); 01793 } 01794 /* Disable Caller*ID if enabled */ 01795 l->hidecallerid = 1; 01796 ast_set_callerid(chan, "", "", NULL); 01797 transmit_tone(s, SKINNY_DIALTONE); 01798 len = 0; 01799 memset(exten, 0, sizeof(exten)); 01800 timeout = firstdigittimeout; 01801 } else if (l->callreturn && !strcmp(exten, "*69")) { 01802 res = 0; 01803 if (!ast_strlen_zero(l->lastcallerid)) { 01804 res = ast_say_digit_str(chan, l->lastcallerid, "", chan->language); 01805 } 01806 if (!res) { 01807 transmit_tone(s, SKINNY_DIALTONE); 01808 } 01809 break; 01810 } else if (!strcmp(exten, "*78")) { 01811 /* Do not disturb */ 01812 if (option_verbose > 2) { 01813 ast_verbose(VERBOSE_PREFIX_3 "Enabled DND on channel %s\n", chan->name); 01814 } 01815 transmit_tone(s, SKINNY_DIALTONE); 01816 l->dnd = 1; 01817 getforward = 0; 01818 memset(exten, 0, sizeof(exten)); 01819 len = 0; 01820 } else if (!strcmp(exten, "*79")) { 01821 /* Do not disturb */ 01822 if (option_verbose > 2) { 01823 ast_verbose(VERBOSE_PREFIX_3 "Disabled DND on channel %s\n", chan->name); 01824 } 01825 transmit_tone(s, SKINNY_DIALTONE); 01826 l->dnd = 0; 01827 getforward = 0; 01828 memset(exten, 0, sizeof(exten)); 01829 len = 0; 01830 } else if (l->cancallforward && !strcmp(exten, "*72")) { 01831 transmit_tone(s, SKINNY_DIALTONE); 01832 getforward = 1; 01833 memset(exten, 0, sizeof(exten)); 01834 len = 0; 01835 } else if (l->cancallforward && !strcmp(exten, "*73")) { 01836 if (option_verbose > 2) { 01837 ast_verbose(VERBOSE_PREFIX_3 "Cancelling call forwarding on channel %s\n", chan->name); 01838 } 01839 transmit_tone(s, SKINNY_DIALTONE); 01840 memset(l->call_forward, 0, sizeof(l->call_forward)); 01841 getforward = 0; 01842 memset(exten, 0, sizeof(exten)); 01843 len = 0; 01844 } else if (!strcmp(exten, ast_parking_ext()) && 01845 sub->next->owner && 01846 ast_bridged_channel(sub->next->owner)) { 01847 /* This is a three way call, the main call being a real channel, 01848 and we're parking the first call. */ 01849 ast_masq_park_call(ast_bridged_channel(sub->next->owner), chan, 0, NULL); 01850 if (option_verbose > 2) { 01851 ast_verbose(VERBOSE_PREFIX_3 "Parking call to '%s'\n", chan->name); 01852 } 01853 break; 01854 } else if (!ast_strlen_zero(l->lastcallerid) && !strcmp(exten, "*60")) { 01855 if (option_verbose > 2) { 01856 ast_verbose(VERBOSE_PREFIX_3 "Blacklisting number %s\n", l->lastcallerid); 01857 } 01858 res = ast_db_put("blacklist", l->lastcallerid, "1"); 01859 if (!res) { 01860 transmit_tone(s, SKINNY_DIALTONE); 01861 memset(exten, 0, sizeof(exten)); 01862 len = 0; 01863 } 01864 } else if (l->hidecallerid && !strcmp(exten, "*82")) { 01865 if (option_verbose > 2) { 01866 ast_verbose(VERBOSE_PREFIX_3 "Enabling Caller*ID on %s\n", chan->name); 01867 } 01868 /* Enable Caller*ID if enabled */ 01869 l->hidecallerid = 0; 01870 ast_set_callerid(chan, l->cid_num, l->cid_name, NULL); 01871 transmit_tone(s, SKINNY_DIALTONE); 01872 len = 0; 01873 memset(exten, 0, sizeof(exten)); 01874 timeout = firstdigittimeout; 01875 } else if (!ast_canmatch_extension(chan, chan->context, exten, 1, chan->cid.cid_num) && 01876 ((exten[0] != '*') || (!ast_strlen_zero(exten) > 2))) { 01877 ast_log(LOG_WARNING, "Can't match [%s] from '%s' in context %s\n", exten, chan->cid.cid_num ? chan->cid.cid_num : "<Unknown Caller>", chan->context); 01878 transmit_tone(s, SKINNY_REORDER); 01879 /* hang out for 3 seconds to let congestion play */ 01880 ast_safe_sleep(chan, 3000); 01881 break; 01882 } 01883 if (!timeout) { 01884 timeout = gendigittimeout; 01885 } 01886 if (len && !ast_ignore_pattern(chan->context, exten)) { 01887 ast_indicate(chan, -1); 01888 } 01889 } 01890 ast_hangup(chan); 01891 return NULL; 01892 }
static int skinny_write | ( | struct ast_channel * | ast, | |
struct ast_frame * | frame | |||
) | [static] |
Definition at line 2074 of file chan_skinny.c.
References AST_FRAME_IMAGE, AST_FRAME_VOICE, ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_rtp_write(), ast_frame::frametype, skinny_subchannel::lock, LOG_WARNING, ast_channel::nativeformats, ast_channel::readformat, skinny_subchannel::rtp, ast_frame::subclass, ast_channel::tech_pvt, and ast_channel::writeformat.
02075 { 02076 struct skinny_subchannel *sub = ast->tech_pvt; 02077 int res = 0; 02078 if (frame->frametype != AST_FRAME_VOICE) { 02079 if (frame->frametype == AST_FRAME_IMAGE) { 02080 return 0; 02081 } else { 02082 ast_log(LOG_WARNING, "Can't send %d type frames with skinny_write\n", frame->frametype); 02083 return 0; 02084 } 02085 } else { 02086 if (!(frame->subclass & ast->nativeformats)) { 02087 ast_log(LOG_WARNING, "Asked to transmit frame type %d, while native formats is %d (read/write = %d/%d)\n", 02088 frame->subclass, ast->nativeformats, ast->readformat, ast->writeformat); 02089 return -1; 02090 } 02091 } 02092 if (sub) { 02093 ast_mutex_lock(&sub->lock); 02094 if (sub->rtp) { 02095 res = ast_rtp_write(sub->rtp, frame); 02096 } 02097 ast_mutex_unlock(&sub->lock); 02098 } 02099 return res; 02100 }
static void start_rtp | ( | struct skinny_subchannel * | sub | ) | [static] |
Definition at line 1674 of file chan_skinny.c.
References ast_mutex_lock(), ast_mutex_unlock(), ast_rtp_fd(), ast_rtp_new(), ast_rtp_setnat(), ast_channel::fds, io, skinny_subchannel::lock, skinny_subchannel::nat, skinny_subchannel::owner, skinny_line::parent, skinny_subchannel::parent, skinny_subchannel::rtp, sched, skinny_device::session, and transmit_connect().
01675 { 01676 ast_mutex_lock(&sub->lock); 01677 /* Allocate the RTP */ 01678 sub->rtp = ast_rtp_new(sched, io, 1, 0); 01679 if (sub->rtp && sub->owner) { 01680 sub->owner->fds[0] = ast_rtp_fd(sub->rtp); 01681 } 01682 if (sub->rtp) { 01683 ast_rtp_setnat(sub->rtp, sub->nat); 01684 } 01685 /* Create the RTP connection */ 01686 transmit_connect(sub->parent->parent->session); 01687 ast_mutex_unlock(&sub->lock); 01688 }
static void transmit_callinfo | ( | struct skinnysession * | s, | |
char * | fromname, | |||
char * | fromnum, | |||
char * | toname, | |||
char * | tonum, | |||
int | instance, | |||
int | callid, | |||
int | calltype | |||
) | [static] |
Definition at line 1074 of file chan_skinny.c.
References ast_log(), CALL_INFO_MESSAGE, call_info_message::calledParty, call_info_message::calledPartyName, skinny_req::callinfo, call_info_message::callingParty, call_info_message::callingPartyName, skinny_req::data, skinny_req::e, htolel, call_info_message::instance, skinny_req::len, LOG_ERROR, call_info_message::reference, req_alloc(), s, transmit_response(), and call_info_message::type.
Referenced by skinny_call(), and skinny_indicate().
01075 { 01076 skinny_req *req; 01077 01078 req = req_alloc(sizeof(struct call_info_message)); 01079 if (!req) { 01080 ast_log(LOG_ERROR, "Unable to allocate skinny_request, this is bad\n"); 01081 return; 01082 } 01083 01084 req->len = htolel(sizeof(struct call_info_message)); 01085 req->e = htolel(CALL_INFO_MESSAGE); 01086 01087 if (fromname) { 01088 ast_copy_string(req->data.callinfo.callingPartyName, fromname, sizeof(req->data.callinfo.callingPartyName)); 01089 } 01090 if (fromnum) { 01091 ast_copy_string(req->data.callinfo.callingParty, fromnum, sizeof(req->data.callinfo.callingParty)); 01092 } 01093 if (toname) { 01094 ast_copy_string(req->data.callinfo.calledPartyName, toname, sizeof(req->data.callinfo.calledPartyName)); 01095 } 01096 if (tonum) { 01097 ast_copy_string(req->data.callinfo.calledParty, tonum, sizeof(req->data.callinfo.calledParty)); 01098 } 01099 req->data.callinfo.instance = htolel(instance); 01100 req->data.callinfo.reference = htolel(callid); 01101 req->data.callinfo.type = htolel(calltype); 01102 transmit_response(s, req); 01103 }
static void transmit_callstate | ( | struct skinnysession * | s, | |
int | instance, | |||
int | state, | |||
unsigned | callid | |||
) | [static] |
Definition at line 1028 of file chan_skinny.c.
References ACTIVATE_CALL_PLANE_MESSAGE, ast_log(), CALL_STATE_MESSAGE, call_state_message::callReference, call_state_message::callState, skinny_req::callstate, CLOSE_RECIEVE_CHANNEL_MESSAGE, skinny_req::data, skinny_req::e, htolel, skinny_req::len, call_state_message::lineInstance, LOG_ERROR, req_alloc(), s, SKINNY_OFFHOOK, SKINNY_ONHOOK, SKINNY_SPEAKEROFF, STOP_MEDIA_TRANSMISSION_MESSAGE, transmit_response(), and transmit_speaker_mode().
Referenced by handle_message(), skinny_answer(), skinny_call(), skinny_hangup(), and skinny_indicate().
01029 { 01030 skinny_req *req; 01031 int memsize = sizeof(struct call_state_message); 01032 01033 req = req_alloc(memsize); 01034 if (!req) { 01035 ast_log(LOG_ERROR, "Unable to allocate skinny_request, this is bad\n"); 01036 return; 01037 } 01038 if (state == SKINNY_ONHOOK) { 01039 transmit_speaker_mode(s, SKINNY_SPEAKEROFF); 01040 } 01041 req->len = htolel(sizeof(call_state_message)+4); 01042 req->e = htolel(CALL_STATE_MESSAGE); 01043 req->data.callstate.callState = htolel(state); 01044 req->data.callstate.lineInstance = htolel(instance); 01045 req->data.callstate.callReference = htolel(callid); 01046 transmit_response(s, req); 01047 if (state == SKINNY_OFFHOOK) { 01048 memset(req, 0, memsize); 01049 req->len = htolel(sizeof(activate_call_plane_message)+4); 01050 req->e = htolel(ACTIVATE_CALL_PLANE_MESSAGE); 01051 req->data.activatecallplane.lineInstance = htolel(instance); 01052 transmit_response(s, req); 01053 } else if (state == SKINNY_ONHOOK) { 01054 memset(req, 0, memsize); 01055 req->len = htolel(sizeof(activate_call_plane_message)+4); 01056 req->e = htolel(ACTIVATE_CALL_PLANE_MESSAGE); 01057 req->data.activatecallplane.lineInstance = 0; 01058 transmit_response(s, req); 01059 memset(req, 0, memsize); 01060 req->len = htolel(sizeof(close_recieve_channel_message)+4); 01061 req->e = htolel(CLOSE_RECIEVE_CHANNEL_MESSAGE); 01062 req->data.closerecievechannel.conferenceId = 0; 01063 req->data.closerecievechannel.partyId = 0; 01064 transmit_response(s, req); 01065 memset(req, 0, memsize); 01066 req->len = htolel(sizeof(stop_media_transmission_message)+4); 01067 req->e = htolel(STOP_MEDIA_TRANSMISSION_MESSAGE); 01068 req->data.stopmedia.conferenceId = 0; 01069 req->data.stopmedia.passThruPartyId = 0; 01070 transmit_response(s, req); 01071 } 01072 }
static void transmit_connect | ( | struct skinnysession * | s | ) | [static] |
Definition at line 1105 of file chan_skinny.c.
References ast_log(), open_recieve_channel_message::bitrate, skinny_line::capability, open_recieve_channel_message::capability, open_recieve_channel_message::conferenceId, convert_cap(), skinny_req::data, skinny_req::e, open_recieve_channel_message::echo, htolel, skinny_req::len, LOG_ERROR, OPEN_RECIEVE_CHANNEL_MESSAGE, skinny_req::openrecievechannel, open_recieve_channel_message::packets, open_recieve_channel_message::partyId, req_alloc(), s, and transmit_response().
Referenced by start_rtp().
01106 { 01107 skinny_req *req; 01108 struct skinny_line *l = s->device->lines; 01109 01110 req = req_alloc(sizeof(struct open_recieve_channel_message)); 01111 if (!req) { 01112 ast_log(LOG_ERROR, "Unable to allocate skinny_request, this is bad\n"); 01113 return; 01114 } 01115 req->len = htolel(sizeof(struct open_recieve_channel_message)); 01116 req->e = htolel(OPEN_RECIEVE_CHANNEL_MESSAGE); 01117 req->data.openrecievechannel.conferenceId = 0; 01118 req->data.openrecievechannel.partyId = 0; 01119 req->data.openrecievechannel.packets = htolel(20); 01120 req->data.openrecievechannel.capability = htolel(convert_cap(l->capability)); 01121 req->data.openrecievechannel.echo = 0; 01122 req->data.openrecievechannel.bitrate = 0; 01123 transmit_response(s, req); 01124 }
static void transmit_diallednumber | ( | struct skinnysession * | s, | |
char * | text, | |||
int | instance, | |||
int | callid | |||
) | [static] |
Definition at line 1278 of file chan_skinny.c.
References ast_log(), dialled_number_message::callReference, skinny_req::data, DIALLED_NUMBER_MESSAGE, dialled_number_message::dialledNumber, skinny_req::diallednumber, skinny_req::e, htolel, skinny_req::len, dialled_number_message::lineInstance, LOG_ERROR, req_alloc(), s, and transmit_response().
Referenced by skinny_indicate().
01279 { 01280 skinny_req *req; 01281 01282 req = req_alloc(sizeof(struct dialled_number_message)); 01283 01284 if (!req) { 01285 ast_log(LOG_ERROR, "Unable to allocate skinny_request, this is bad\n"); 01286 return; 01287 } 01288 01289 req->e = htolel(DIALLED_NUMBER_MESSAGE); 01290 req->len = htolel(sizeof(dialled_number_message) + 4); 01291 strncpy(req->data.diallednumber.dialledNumber, text, sizeof(req->data.diallednumber.dialledNumber)-1); 01292 req->data.diallednumber.lineInstance = htolel(instance); 01293 req->data.diallednumber.callReference = htolel(callid); 01294 01295 transmit_response(s, req); 01296 }
static void transmit_displaymessage | ( | struct skinnysession * | s, | |
char * | text | |||
) | [static] |
Definition at line 1204 of file chan_skinny.c.
References ast_log(), ast_verbose(), CLEAR_DISPLAY_MESSAGE, skinny_req::data, skinny_req::displaytext, DISPLAYTEXT_MESSAGE, skinny_req::e, htolel, skinny_req::len, LOG_ERROR, req_alloc(), s, displaytext_message::text, and transmit_response().
Referenced by do_housekeeping(), handle_message(), and skinny_call().
01205 { 01206 skinny_req *req; 01207 01208 if (text == 0) { 01209 req = req_alloc(4); 01210 req->len = htolel(4); 01211 req->e = htolel(CLEAR_DISPLAY_MESSAGE); 01212 } else { 01213 req = req_alloc(sizeof(struct displaytext_message)); 01214 01215 strncpy(req->data.displaytext.text, text, sizeof(req->data.displaytext.text)-1); 01216 req->len = htolel(sizeof(displaytext_message) + 4); 01217 req->e = htolel(DISPLAYTEXT_MESSAGE); 01218 if (skinnydebug) { 01219 ast_verbose("Displaying message '%s'\n", req->data.displaytext.text); 01220 } 01221 } 01222 01223 if (!req) { 01224 ast_log(LOG_ERROR, "Unable to allocate skinny_request, this is bad\n"); 01225 return; 01226 } 01227 transmit_response(s, req); 01228 }
static void transmit_displaynotify | ( | struct skinnysession * | s, | |
char * | text, | |||
int | t | |||
) | [static] |
Definition at line 1230 of file chan_skinny.c.
References ast_log(), ast_verbose(), skinny_req::data, DISPLAY_NOTIFY_MESSAGE, display_notify_message::displayMessage, skinny_req::displaynotify, display_notify_message::displayTimeout, skinny_req::e, htolel, skinny_req::len, LOG_ERROR, req_alloc(), s, and transmit_response().
Referenced by handle_message().
01231 { 01232 skinny_req *req; 01233 01234 req = req_alloc(sizeof(struct display_notify_message)); 01235 01236 if (!req) { 01237 ast_log(LOG_ERROR, "Unable to allocate skinny_request, this is bad\n"); 01238 return; 01239 } 01240 01241 req->e = htolel(DISPLAY_NOTIFY_MESSAGE); 01242 req->len = htolel(sizeof(display_notify_message) + 4); 01243 strncpy(req->data.displaynotify.displayMessage, text, sizeof(req->data.displaynotify.displayMessage)-1); 01244 req->data.displaynotify.displayTimeout = htolel(t); 01245 01246 if (skinnydebug) { 01247 ast_verbose("Displaying notify '%s'\n", text); 01248 } 01249 01250 transmit_response(s, req); 01251 }
static void transmit_displaypromptstatus | ( | struct skinnysession * | s, | |
char * | text, | |||
int | t, | |||
int | instance, | |||
int | callid | |||
) | [static] |
Definition at line 1253 of file chan_skinny.c.
References ast_log(), ast_verbose(), display_prompt_status_message::callReference, skinny_req::data, DISPLAY_PROMPT_STATUS_MESSAGE, skinny_req::displaypromptstatus, skinny_req::e, htolel, skinny_req::len, display_prompt_status_message::lineInstance, LOG_ERROR, display_prompt_status_message::messageTimeout, display_prompt_status_message::promptMessage, req_alloc(), s, and transmit_response().
Referenced by skinny_answer(), skinny_call(), and skinny_indicate().
01254 { 01255 skinny_req *req; 01256 01257 req = req_alloc(sizeof(struct display_prompt_status_message)); 01258 01259 if (!req) { 01260 ast_log(LOG_ERROR, "Unable to allocate skinny_request, this is bad\n"); 01261 return; 01262 } 01263 01264 req->e = htolel(DISPLAY_PROMPT_STATUS_MESSAGE); 01265 req->len = htolel(sizeof(display_prompt_status_message) + 4); 01266 strncpy(req->data.displaypromptstatus.promptMessage, text, sizeof(req->data.displaypromptstatus.promptMessage)-1); 01267 req->data.displaypromptstatus.messageTimeout = htolel(t); 01268 req->data.displaypromptstatus.lineInstance = htolel(instance); 01269 req->data.displaypromptstatus.callReference = htolel(callid); 01270 01271 if (skinnydebug) { 01272 ast_verbose("Displaying Prompt Status '%s'\n", text); 01273 } 01274 01275 transmit_response(s, req); 01276 }
static void transmit_lamp_indication | ( | struct skinnysession * | s, | |
int | stimulus, | |||
int | instance, | |||
int | indication | |||
) | [static] |
Definition at line 1172 of file chan_skinny.c.
References ast_log(), skinny_req::data, set_lamp_message::deviceStimulus, skinny_req::e, htolel, skinny_req::len, LOG_ERROR, req_alloc(), s, SET_LAMP_MESSAGE, skinny_req::setlamp, set_lamp_message::stimulus, set_lamp_message::stimulusInstance, and transmit_response().
Referenced by do_housekeeping(), handle_message(), skinny_call(), and skinny_hangup().
01173 { 01174 skinny_req *req; 01175 01176 req = req_alloc(sizeof(struct set_lamp_message)); 01177 if (!req) { 01178 ast_log(LOG_ERROR, "Unable to allocate skinny_request, this is bad\n"); 01179 return; 01180 } 01181 req->len = htolel(sizeof(set_lamp_message)+4); 01182 req->e = htolel(SET_LAMP_MESSAGE); 01183 req->data.setlamp.stimulus = htolel(stimulus); 01184 req->data.setlamp.stimulusInstance = htolel(instance); 01185 req->data.setlamp.deviceStimulus = htolel(indication); 01186 transmit_response(s, req); 01187 }
static int transmit_response | ( | struct skinnysession * | s, | |
skinny_req * | req | |||
) | [static] |
Definition at line 987 of file chan_skinny.c.
References ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_verbose(), skinny_req::e, skinny_req::len, letohl, LOG_WARNING, and s.
00988 { 00989 int res = 0; 00990 ast_mutex_lock(&s->lock); 00991 00992 #if 0 00993 if (skinnydebug) { 00994 ast_verbose("writing packet type %04X (%d bytes) to socket %d\n", letohl(req->e), letohl(req->len)+8, s->fd); 00995 } 00996 #endif 00997 00998 res = write(s->fd, req, letohl(req->len)+8); 00999 if (res != letohl(req->len)+8) { 01000 ast_log(LOG_WARNING, "Transmit: write only sent %d out of %d bytes: %s\n", res, letohl(req->len)+8, strerror(errno)); 01001 } 01002 ast_mutex_unlock(&s->lock); 01003 return 1; 01004 }
static void transmit_ringer_mode | ( | struct skinnysession * | s, | |
int | mode | |||
) | [static] |
Definition at line 1189 of file chan_skinny.c.
References ast_log(), skinny_req::data, skinny_req::e, htolel, skinny_req::len, LOG_ERROR, req_alloc(), set_ringer_message::ringerMode, s, SET_RINGER_MESSAGE, skinny_req::setringer, and transmit_response().
Referenced by handle_message(), skinny_call(), and skinny_hangup().
01190 { 01191 skinny_req *req; 01192 01193 req = req_alloc(sizeof(struct set_ringer_message)); 01194 if (!req) { 01195 ast_log(LOG_ERROR, "Unable to allocate skinny_request, this is bad\n"); 01196 return; 01197 } 01198 req->len = htolel(sizeof(set_ringer_message)+4); 01199 req->e = htolel(SET_RINGER_MESSAGE); 01200 req->data.setringer.ringerMode = htolel(mode); 01201 transmit_response(s, req); 01202 }
static void transmit_speaker_mode | ( | struct skinnysession * | s, | |
int | mode | |||
) | [static] |
Definition at line 1013 of file chan_skinny.c.
References ast_log(), skinny_req::data, skinny_req::e, htolel, skinny_req::len, LOG_ERROR, set_speaker_message::mode, req_alloc(), s, SET_SPEAKER_MESSAGE, skinny_req::setspeaker, and transmit_response().
Referenced by handle_message(), skinny_hangup(), and transmit_callstate().
01014 { 01015 skinny_req *req; 01016 01017 req = req_alloc(sizeof(struct set_speaker_message)); 01018 if (!req) { 01019 ast_log(LOG_ERROR, "Unable to allocate skinny_request, this is bad\n"); 01020 return; 01021 } 01022 req->len = htolel(sizeof(set_speaker_message)+4); 01023 req->e = htolel(SET_SPEAKER_MESSAGE); 01024 req->data.setspeaker.mode = htolel(mode); 01025 transmit_response(s, req); 01026 }
static void transmit_tone | ( | struct skinnysession * | s, | |
int | tone | |||
) | [static] |
Definition at line 1126 of file chan_skinny.c.
References ast_log(), skinny_req::data, skinny_req::e, htolel, skinny_req::len, LOG_ERROR, req_alloc(), s, START_TONE_MESSAGE, skinny_req::starttone, STOP_TONE_MESSAGE, start_tone_message::tone, and transmit_response().
Referenced by handle_message(), skinny_answer(), skinny_call(), skinny_hangup(), skinny_indicate(), skinny_senddigit(), and skinny_ss().
01127 { 01128 skinny_req *req; 01129 01130 if (tone > 0) { 01131 req = req_alloc(sizeof(struct start_tone_message)); 01132 } else { 01133 req = req_alloc(4); 01134 } 01135 if (!req) { 01136 ast_log(LOG_ERROR, "Unable to allocate skinny_request, this is bad\n"); 01137 return; 01138 } 01139 if (tone > 0) { 01140 req->len = htolel(sizeof(start_tone_message)+4); 01141 req->e = htolel(START_TONE_MESSAGE); 01142 req->data.starttone.tone = htolel(tone); 01143 } else { 01144 req->len = htolel(4); 01145 req->e = htolel(STOP_TONE_MESSAGE); 01146 } 01147 transmit_response(s, req); 01148 }
int unload_module | ( | void | ) |
Cleanup all module structures, sockets, etc.
This is called at exit. Any registrations and memory allocations need to be unregistered and free'd here. Nothing else will do these for you (until exit).
Definition at line 3296 of file chan_skinny.c.
References ast_channel_unregister(), ast_cli_register(), ast_log(), ast_mutex_destroy(), ast_mutex_lock(), ast_mutex_unlock(), AST_PTHREADT_STOP, ast_rtp_proto_register(), cli_debug, cli_no_debug, cli_show_devices, cli_show_lines, free, iflist, LOG_WARNING, monitor_thread, oh323_pvt::next, s, skinny_rtp, skinny_session(), and skinny_tech.
03297 { 03298 #if 0 03299 struct skinny_session *session, s; 03300 struct skinny_subchannel *sub; 03301 struct skinny_line *line = session; 03302 03303 /* close all IP connections */ 03304 if (!ast_mutex_lock(&devicelock)) { 03305 /* Terminate tcp listener thread */ 03306 } else { 03307 ast_log(LOG_WARNING, "Unable to lock the monitor\n"); 03308 return -1; 03309 } 03310 if (!ast_mutex_lock(&monlock)) { 03311 if (monitor_thread && (monitor_thread != AST_PTHREADT_STOP)) { 03312 pthread_cancel(monitor_thread); 03313 pthread_kill(monitor_thread, SIGURG); 03314 pthread_join(monitor_thread, NULL); 03315 } 03316 monitor_thread = AST_PTHREADT_STOP; 03317 ast_mutex_unlock(&monlock); 03318 } else { 03319 ast_log(LOG_WARNING, "Unable to lock the monitor\n"); 03320 return -1; 03321 } 03322 if (!ast_mutex_lock(&iflock)) { 03323 /* Destroy all the interfaces and free their memory */ 03324 p = iflist; 03325 while(p) { 03326 pl = p; 03327 p = p->next; 03328 /* Free associated memory */ 03329 ast_mutex_destroy(&pl->lock); 03330 free(pl); 03331 } 03332 iflist = NULL; 03333 ast_mutex_unlock(&iflock); 03334 } else { 03335 ast_log(LOG_WARNING, "Unable to lock the monitor\n"); 03336 return -1; 03337 } 03338 03339 ast_rtp_proto_register(&skinny_rtp); 03340 ast_channel_unregister(&skinny_tech); 03341 ast_cli_register(&cli_show_devices); 03342 ast_cli_register(&cli_show_lines); 03343 ast_cli_register(&cli_debug); 03344 ast_cli_register(&cli_no_debug); 03345 03346 return 0; 03347 #endif 03348 return -1; 03349 }
int usecount | ( | void | ) |
Provides a usecount.
This function will be called by various parts of asterisk. Basically, all it has to do is to return a usecount when called. You will need to maintain your usecount within the module somewhere. The usecount should be how many channels provided by this module are in use.
Definition at line 3351 of file chan_skinny.c.
References usecnt.
03352 { 03353 return usecnt; 03354 }
struct in_addr __ourip [static] |
Definition at line 682 of file chan_skinny.c.
pthread_t accept_t [static] |
Definition at line 686 of file chan_skinny.c.
char accountcode[AST_MAX_ACCOUNT_CODE] = "" [static] |
Definition at line 705 of file chan_skinny.c.
struct ast_hostent ahp |
Definition at line 683 of file chan_skinny.c.
Referenced by ast_dnsmgr_lookup(), ast_find_ourip(), ast_get_ip_or_srv(), ast_sip_ouraddrfor(), check_via(), create_addr(), festival_exec(), iax2_register(), launch_netscript(), parse_ok_contact(), parse_register_contact(), process_sdp(), refresh_list(), reload_config(), rpt_exec(), rtp_do_debug_ip(), set_destination(), sip_devicestate(), and sip_do_debug_ip().
int amaflags = 0 [static] |
Definition at line 707 of file chan_skinny.c.
struct sockaddr_in bindaddr [static] |
Definition at line 679 of file chan_skinny.c.
Definition at line 370 of file chan_skinny.c.
Definition at line 343 of file chan_skinny.c.
Definition at line 385 of file chan_skinny.c.
Definition at line 400 of file chan_skinny.c.
Definition at line 413 of file chan_skinny.c.
Initial value:
{ { 1, STIMULUS_LINE }, { 2, STIMULUS_LINE } }
Definition at line 422 of file chan_skinny.c.
Initial value:
{ { 1, STIMULUS_LINE }, { 2, STIMULUS_LINE } }
Definition at line 427 of file chan_skinny.c.
Definition at line 432 of file chan_skinny.c.
Definition at line 441 of file chan_skinny.c.
button_definition button_def_none = { 0, STIMULUS_NONE } |
int callnums = 1 [static] |
Definition at line 708 of file chan_skinny.c.
int callreturn = 0 [static] |
Definition at line 698 of file chan_skinny.c.
int callwaiting = 0 [static] |
Definition at line 697 of file chan_skinny.c.
int cancallforward = 0 [static] |
Definition at line 703 of file chan_skinny.c.
int capability = AST_FORMAT_ULAW [static] |
Definition at line 81 of file chan_skinny.c.
char cid_name[AST_MAX_EXTENSION] = "" [static] |
Definition at line 691 of file chan_skinny.c.
char cid_num[AST_MAX_EXTENSION] = "" [static] |
Definition at line 690 of file chan_skinny.c.
struct ast_cli_entry cli_debug [static] |
Initial value:
{ { "skinny", "debug", NULL }, skinny_do_debug, "Enable Skinny debugging", debug_usage }
Definition at line 1469 of file chan_skinny.c.
struct ast_cli_entry cli_no_debug [static] |
Initial value:
{ { "skinny", "no", "debug", NULL }, skinny_no_debug, "Disable Skinny debugging", no_debug_usage }
Definition at line 1472 of file chan_skinny.c.
struct ast_cli_entry cli_show_devices [static] |
Initial value:
{ { "skinny", "show", "devices", NULL }, skinny_show_devices, "Show defined Skinny devices", show_devices_usage }
Definition at line 1463 of file chan_skinny.c.
Referenced by load_module(), and unload_module().
struct ast_cli_entry cli_show_lines [static] |
Initial value:
{ { "skinny", "show", "lines", NULL }, skinny_show_lines, "Show defined Skinny lines per device", show_lines_usage }
Definition at line 1466 of file chan_skinny.c.
Referenced by load_module(), and unload_module().
const char config[] = "skinny.conf" [static] |
Definition at line 78 of file chan_skinny.c.
char context[AST_MAX_CONTEXT] = "default" [static] |
Definition at line 687 of file chan_skinny.c.
ast_group_t cur_callergroup = 0 [static] |
Definition at line 694 of file chan_skinny.c.
ast_group_t cur_pickupgroup = 0 [static] |
Definition at line 695 of file chan_skinny.c.
char date_format[6] = "D-M-Y" [static] |
Definition at line 88 of file chan_skinny.c.
char debug_usage[] [static] |
Initial value:
"Usage: skinny debug\n" " Enables dumping of Skinny packets for debugging purposes\n"
Definition at line 1455 of file chan_skinny.c.
const char desc[] = "Skinny Client Control Protocol (Skinny)" [static] |
Definition at line 75 of file chan_skinny.c.
struct skinny_device * devices [static] |
Referenced by delete_devices(), find_subchannel_by_name(), reload_config(), skinny_register(), skinny_show_devices(), and skinny_show_lines().
int firstdigittimeout = 16000 [static] |
Definition at line 799 of file chan_skinny.c.
int gendigittimeout = 8000 [static] |
Definition at line 802 of file chan_skinny.c.
struct hostent* hp |
Definition at line 683 of file chan_skinny.c.
Referenced by ast_dnsmgr_lookup(), ast_find_ourip(), ast_get_ip_or_srv(), ast_gethostbyname(), ast_sip_ouraddrfor(), build_peer(), check_via(), connect_asterisk(), create_addr(), iax2_register(), iax_template_parse(), launch_netscript(), parse_ok_contact(), parse_register_contact(), process_sdp(), refresh_list(), reload_config(), rpt_exec(), rtp_do_debug_ip(), set_config(), set_destination(), sip_devicestate(), and sip_do_debug_ip().
int immediate = 0 [static] |
Definition at line 696 of file chan_skinny.c.
struct io_context* io [static] |
Definition at line 774 of file chan_skinny.c.
int keep_alive = 120 [static] |
Definition at line 87 of file chan_skinny.c.
char language[MAX_LANGUAGE] = "" [static] |
Definition at line 688 of file chan_skinny.c.
char linelabel[AST_MAX_EXTENSION] = "" [static] |
Definition at line 692 of file chan_skinny.c.
char mailbox[AST_MAX_EXTENSION] [static] |
Definition at line 706 of file chan_skinny.c.
int matchdigittimeout = 3000 [static] |
Definition at line 805 of file chan_skinny.c.
pthread_t monitor_thread = AST_PTHREADT_NULL [static] |
Definition at line 796 of file chan_skinny.c.
char musicclass[MAX_MUSICCLASS] = "" [static] |
Definition at line 689 of file chan_skinny.c.
int mwiblink = 0 [static] |
Definition at line 700 of file chan_skinny.c.
int nat = 0 [static] |
Definition at line 693 of file chan_skinny.c.
char no_debug_usage[] [static] |
Initial value:
"Usage: skinny no debug\n" " Disables dumping of Skinny packets for debugging purposes\n"
Definition at line 1459 of file chan_skinny.c.
char ourhost[256] [static] |
Definition at line 680 of file chan_skinny.c.
int ourport [static] |
Definition at line 681 of file chan_skinny.c.
struct sched_context* sched [static] |
Definition at line 773 of file chan_skinny.c.
struct skinnysession * sessions [static] |
char show_devices_usage[] [static] |
Initial value:
"Usage: skinny show devices\n" " Lists all devices known to the Skinny subsystem.\n"
Definition at line 1447 of file chan_skinny.c.
char show_lines_usage[] [static] |
Initial value:
"Usage: skinny show lines\n" " Lists all lines known to the Skinny subsystem.\n"
Definition at line 1451 of file chan_skinny.c.
struct ast_rtp_protocol skinny_rtp [static] |
struct ast_channel_tech skinny_tech [static] |
Definition at line 910 of file chan_skinny.c.
Referenced by load_module(), skinny_new(), and unload_module().
int skinnydebug = 1 [static] |
Definition at line 676 of file chan_skinny.c.
int skinnysock = -1 [static] |
Definition at line 684 of file chan_skinny.c.
const char* soft_key_set_hack [static] |
Definition at line 540 of file chan_skinny.c.
pthread_t tcp_thread [static] |
Definition at line 685 of file chan_skinny.c.
const char tdesc[] = "Skinny Client Control Protocol (Skinny)" [static] |
Definition at line 76 of file chan_skinny.c.
int threewaycalling = 0 [static] |
Definition at line 699 of file chan_skinny.c.
int transfer = 0 [static] |
Definition at line 702 of file chan_skinny.c.
const char type[] = "Skinny" [static] |
Definition at line 77 of file chan_skinny.c.
int usecnt = 0 [static] |
Definition at line 777 of file chan_skinny.c.
char version_id[16] = "P002F202" [static] |
Definition at line 89 of file chan_skinny.c.