#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"
Include dependency graph for chan_skinny.c:
Go to the source code of this file.
Definition in file chan_skinny.c.
|
Definition at line 618 of file chan_skinny.c. Referenced by transmit_callstate(). |
|
Definition at line 183 of file chan_skinny.c. Referenced by handle_message(). |
|
Definition at line 181 of file chan_skinny.c. Referenced by handle_message(). |
|
Definition at line 320 of file chan_skinny.c. Referenced by handle_message(). |
|
Definition at line 254 of file chan_skinny.c. Referenced by transmit_callinfo(). |
|
Definition at line 597 of file chan_skinny.c. Referenced by transmit_callstate(). |
|
Definition at line 307 of file chan_skinny.c. Referenced by handle_message(). |
|
Definition at line 154 of file chan_skinny.c. |
|
Definition at line 300 of file chan_skinny.c. Referenced by transmit_displaymessage(). |
|
Definition at line 498 of file chan_skinny.c. Referenced by transmit_callstate(). |
|
Definition at line 84 of file chan_skinny.c. Referenced by reload_config(). |
|
Definition at line 83 of file chan_skinny.c. Referenced by reload_config(). |
|
Definition at line 282 of file chan_skinny.c. |
|
Definition at line 623 of file chan_skinny.c. Referenced by transmit_diallednumber(). |
|
Definition at line 612 of file chan_skinny.c. Referenced by transmit_displaynotify(). |
|
Definition at line 604 of file chan_skinny.c. Referenced by transmit_displaypromptstatus(). |
|
Definition at line 295 of file chan_skinny.c. Referenced by transmit_displaymessage(). |
|
|
Definition at line 100 of file chan_skinny.c. |
|
Definition at line 138 of file chan_skinny.c. Referenced by handle_message(). |
|
Definition at line 486 of file chan_skinny.c. |
|
Definition at line 125 of file chan_skinny.c. |
|
Definition at line 140 of file chan_skinny.c. |
|
Definition at line 97 of file chan_skinny.c. Referenced by get_input(), handle_message(), skinny_register(), skinny_req_parse(), and transmit_response(). |
|
Definition at line 98 of file chan_skinny.c. |
|
Definition at line 274 of file chan_skinny.c. |
|
Definition at line 174 of file chan_skinny.c. |
|
Definition at line 712 of file chan_skinny.c. |
|
Definition at line 151 of file chan_skinny.c. |
|
Definition at line 152 of file chan_skinny.c. |
|
Definition at line 185 of file chan_skinny.c. |
|
Definition at line 488 of file chan_skinny.c. Referenced by transmit_connect(). |
|
Definition at line 197 of file chan_skinny.c. Referenced by handle_message(). |
|
Definition at line 128 of file chan_skinny.c. Referenced by handle_message(). |
|
Definition at line 302 of file chan_skinny.c. Referenced by handle_message(). |
|
Definition at line 589 of file chan_skinny.c. |
|
Definition at line 182 of file chan_skinny.c. Referenced by handle_message(). |
|
Definition at line 309 of file chan_skinny.c. Referenced by handle_message(). |
|
Definition at line 218 of file chan_skinny.c. Referenced by transmit_lamp_indication(). |
|
Definition at line 213 of file chan_skinny.c. Referenced by transmit_ringer_mode(). |
|
Definition at line 225 of file chan_skinny.c. Referenced by transmit_speaker_mode(). |
|
Definition at line 734 of file chan_skinny.c. Referenced by skinny_call(), and skinny_indicate(). |
|
Definition at line 722 of file chan_skinny.c. Referenced by skinny_indicate(). |
|
Definition at line 733 of file chan_skinny.c. Referenced by skinny_indicate(). |
|
Definition at line 725 of file chan_skinny.c. |
|
Definition at line 736 of file chan_skinny.c. Referenced by skinny_call(). |
|
Definition at line 723 of file chan_skinny.c. Referenced by skinny_indicate(). |
|
Definition at line 721 of file chan_skinny.c. Referenced by skinny_answer(). |
|
Definition at line 757 of file chan_skinny.c. |
|
Definition at line 758 of file chan_skinny.c. |
|
Definition at line 760 of file chan_skinny.c. Referenced by build_device(). |
|
Definition at line 759 of file chan_skinny.c. |
|
Definition at line 755 of file chan_skinny.c. |
|
Definition at line 754 of file chan_skinny.c. |
|
Definition at line 756 of file chan_skinny.c. Referenced by skinny_answer(). |
|
Definition at line 732 of file chan_skinny.c. Referenced by handle_message(), and skinny_ss(). |
|
Definition at line 724 of file chan_skinny.c. |
|
Definition at line 729 of file chan_skinny.c. |
|
Definition at line 743 of file chan_skinny.c. Referenced by do_housekeeping(), and skinny_call(). |
|
Definition at line 742 of file chan_skinny.c. |
|
Definition at line 739 of file chan_skinny.c. Referenced by do_housekeeping(), handle_message(), and skinny_hangup(). |
|
Definition at line 740 of file chan_skinny.c. Referenced by do_housekeeping(), and handle_message(). |
|
Definition at line 741 of file chan_skinny.c. |
|
Definition at line 85 of file chan_skinny.c. Referenced by handle_message(), and skinny_req_parse(). |
|
Definition at line 737 of file chan_skinny.c. Referenced by skinny_answer(). |
|
Definition at line 717 of file chan_skinny.c. Referenced by skinny_call(), skinny_hangup(), and transmit_callstate(). |
|
Definition at line 718 of file chan_skinny.c. Referenced by build_device(), skinny_call(), skinny_hangup(), and transmit_callstate(). |
|
Definition at line 727 of file chan_skinny.c. |
|
Definition at line 728 of file chan_skinny.c. Referenced by skinny_indicate(). |
|
Definition at line 735 of file chan_skinny.c. Referenced by skinny_indicate(), and skinny_ss(). |
|
Definition at line 748 of file chan_skinny.c. |
|
Definition at line 746 of file chan_skinny.c. Referenced by skinny_call(). |
|
Definition at line 745 of file chan_skinny.c. Referenced by skinny_hangup(). |
|
Definition at line 747 of file chan_skinny.c. |
|
Definition at line 720 of file chan_skinny.c. Referenced by skinny_call(). |
|
Definition at line 719 of file chan_skinny.c. Referenced by skinny_indicate(). |
|
Definition at line 731 of file chan_skinny.c. Referenced by skinny_hangup(), skinny_indicate(), and skinny_ss(). |
|
Definition at line 715 of file chan_skinny.c. Referenced by skinny_hangup(), and transmit_callstate(). |
|
Definition at line 714 of file chan_skinny.c. |
|
Definition at line 726 of file chan_skinny.c. |
|
Definition at line 193 of file chan_skinny.c. |
|
Definition at line 539 of file chan_skinny.c. |
|
Definition at line 195 of file chan_skinny.c. |
|
Definition at line 504 of file chan_skinny.c. |
|
Definition at line 169 of file chan_skinny.c. |
|
Definition at line 267 of file chan_skinny.c. |
|
Definition at line 230 of file chan_skinny.c. |
|
Definition at line 206 of file chan_skinny.c. Referenced by transmit_tone(). |
|
Definition at line 337 of file chan_skinny.c. |
|
Definition at line 339 of file chan_skinny.c. Referenced by handle_message(). |
|
Definition at line 340 of file chan_skinny.c. |
|
Definition at line 338 of file chan_skinny.c. Referenced by handle_message(). |
|
Definition at line 334 of file chan_skinny.c. Referenced by handle_message(). |
|
Definition at line 331 of file chan_skinny.c. Referenced by handle_message(). |
|
Definition at line 332 of file chan_skinny.c. Referenced by handle_message(). |
|
Definition at line 333 of file chan_skinny.c. Referenced by handle_message(). |
|
Definition at line 329 of file chan_skinny.c. Referenced by handle_message(). |
|
Definition at line 335 of file chan_skinny.c. Referenced by handle_message(), skinny_call(), and skinny_hangup(). |
|
Definition at line 145 of file chan_skinny.c. Referenced by handle_message(). |
|
Definition at line 341 of file chan_skinny.c. |
|
Definition at line 327 of file chan_skinny.c. Referenced by handle_message(). |
|
Definition at line 328 of file chan_skinny.c. Referenced by handle_message(). |
|
Definition at line 330 of file chan_skinny.c. Referenced by handle_message(). |
|
Definition at line 336 of file chan_skinny.c. Referenced by do_housekeeping(), and handle_message(). |
|
Definition at line 248 of file chan_skinny.c. Referenced by transmit_callstate(). |
|
Definition at line 211 of file chan_skinny.c. Referenced by transmit_tone(). |
|
Definition at line 711 of file chan_skinny.c. |
|
Definition at line 710 of file chan_skinny.c. |
|
Definition at line 179 of file chan_skinny.c. |
|
Definition at line 751 of file chan_skinny.c. |
|
Definition at line 750 of file chan_skinny.c. |
|
Definition at line 194 of file chan_skinny.c. Referenced by handle_message(). |
|
Definition at line 180 of file chan_skinny.c. Referenced by handle_message(). |
|
Definition at line 481 of file chan_skinny.c. Referenced by handle_message(). |
|
|
|
|
|
Definition at line 93 of file chan_skinny.c. |
|
Definition at line 94 of file chan_skinny.c. |
|
Definition at line 92 of file chan_skinny.c. |
|
Definition at line 2946 of file chan_skinny.c. References ast_log(), ast_mutex_init(), ast_mutex_lock(), ast_mutex_unlock(), ast_pthread_create, destroy_session(), LOG_NOTICE, LOG_WARNING, malloc, s, sessions, and skinny_session(). 02947 { 02948 int as; 02949 struct sockaddr_in sin; 02950 socklen_t sinlen; 02951 struct skinnysession *s; 02952 struct protoent *p; 02953 int arg = 1; 02954 pthread_attr_t attr; 02955 02956 pthread_attr_init(&attr); 02957 pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED); 02958 02959 for (;;) { 02960 sinlen = sizeof(sin); 02961 as = accept(skinnysock, (struct sockaddr *)&sin, &sinlen); 02962 if (as < 0) { 02963 ast_log(LOG_NOTICE, "Accept returned -1: %s\n", strerror(errno)); 02964 continue; 02965 } 02966 p = getprotobyname("tcp"); 02967 if(p) { 02968 if( setsockopt(as, p->p_proto, TCP_NODELAY, (char *)&arg, sizeof(arg) ) < 0 ) { 02969 ast_log(LOG_WARNING, "Failed to set Skinny tcp connection to TCP_NODELAY mode: %s\n", strerror(errno)); 02970 } 02971 } 02972 s = malloc(sizeof(struct skinnysession)); 02973 if (!s) { 02974 ast_log(LOG_WARNING, "Failed to allocate Skinny session: %s\n", strerror(errno)); 02975 continue; 02976 } 02977 memset(s, 0, sizeof(struct skinnysession)); 02978 memcpy(&s->sin, &sin, sizeof(sin)); 02979 ast_mutex_init(&s->lock); 02980 s->fd = as; 02981 ast_mutex_lock(&sessionlock); 02982 s->next = sessions; 02983 sessions = s; 02984 ast_mutex_unlock(&sessionlock); 02985 02986 if (ast_pthread_create(&tcp_thread, NULL, skinny_session, s)) { 02987 destroy_session(s); 02988 } 02989 } 02990 if (skinnydebug) { 02991 ast_verbose("killing accept thread\n"); 02992 } 02993 close(as); 02994 return 0; 02995 }
|
|
|
|
|
|
|
|
|
|
|
|
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_strlen_zero(), ast_true(), ast_verbose(), free, ast_variable::lineno, LOG_WARNING, malloc, MAX_SUBS, ast_variable::name, ast_variable::next, skinny_line::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 }
|
|
Definition at line 2143 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. 02143 { 02144 static char tmp[100]; 02145 02146 switch (ind) { 02147 case AST_CONTROL_HANGUP: 02148 return "Other end has hungup"; 02149 case AST_CONTROL_RING: 02150 return "Local ring"; 02151 case AST_CONTROL_RINGING: 02152 return "Remote end is ringing"; 02153 case AST_CONTROL_ANSWER: 02154 return "Remote end has answered"; 02155 case AST_CONTROL_BUSY: 02156 return "Remote end is busy"; 02157 case AST_CONTROL_TAKEOFFHOOK: 02158 return "Make it go off hook"; 02159 case AST_CONTROL_OFFHOOK: 02160 return "Line is off hook"; 02161 case AST_CONTROL_CONGESTION: 02162 return "Congestion (circuits busy)"; 02163 case AST_CONTROL_FLASH: 02164 return "Flash hook"; 02165 case AST_CONTROL_WINK: 02166 return "Wink"; 02167 case AST_CONTROL_OPTION: 02168 return "Set a low-level option"; 02169 case AST_CONTROL_RADIO_KEY: 02170 return "Key Radio"; 02171 case AST_CONTROL_RADIO_UNKEY: 02172 return "Un-Key Radio"; 02173 case AST_CONTROL_PROGRESS: 02174 return "Remote end is making Progress"; 02175 case AST_CONTROL_PROCEEDING: 02176 return "Remote end is proceeding"; 02177 case AST_CONTROL_HOLD: 02178 return "Hold"; 02179 case AST_CONTROL_UNHOLD: 02180 return "Unhold"; 02181 case -1: 02182 return "Stop tone"; 02183 } 02184 snprintf(tmp, 100, "UNKNOWN-%d", ind); 02185 return tmp; 02186 }
|
|
Definition at line 1007 of file chan_skinny.c. Referenced by transmit_connect().
|
|
Definition at line 3235 of file chan_skinny.c. References ast_mutex_destroy(), ast_mutex_lock(), devices, free, skinny_device::lines, skinny_subchannel::lock, skinny_subchannel::next, and skinny_line::sub. Referenced by reload(). 03236 { 03237 struct skinny_device *d, *dlast; 03238 struct skinny_line *l, *llast; 03239 struct skinny_subchannel *sub, *slast; 03240 03241 ast_mutex_lock(&devicelock); 03242 03243 /* Delete all devices */ 03244 for (d=devices;d;) { 03245 /* Delete all lines for this device */ 03246 for (l=d->lines;l;) { 03247 /* Delete all subchannels for this line */ 03248 for (sub=l->sub;sub;) { 03249 slast = sub; 03250 sub = sub->next; 03251 ast_mutex_destroy(&slast->lock); 03252 free(slast); 03253 } 03254 llast = l; 03255 l = l->next; 03256 ast_mutex_destroy(&llast->lock); 03257 free(llast); 03258 } 03259 dlast = d; 03260 d = d->next; 03261 free(dlast); 03262 } 03263 devices=NULL; 03264 ast_mutex_unlock(&devicelock); 03265 }
|
|
Provides a description of the module.
Definition at line 3378 of file chan_skinny.c. 03379 { 03380 return (char *) desc; 03381 }
|
|
Definition at line 2834 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. 02835 { 02836 struct skinnysession *cur, *prev = NULL; 02837 ast_mutex_lock(&sessionlock); 02838 cur = sessions; 02839 while(cur) { 02840 if (cur == s) { 02841 break; 02842 } 02843 prev = cur; 02844 cur = cur->next; 02845 } 02846 if (cur) { 02847 if (prev) { 02848 prev->next = cur->next; 02849 } else { 02850 sessions = cur->next; 02851 } 02852 if (s->fd > -1) { 02853 close(s->fd); 02854 } 02855 ast_mutex_destroy(&s->lock); 02856 free(s); 02857 } else { 02858 ast_log(LOG_WARNING, "Trying to delete nonexistent session %p?\n", s); 02859 } 02860 ast_mutex_unlock(&sessionlock); 02861 }
|
|
|
Definition at line 2997 of file chan_skinny.c. References ast_io_wait(), ast_mutex_lock(), ast_mutex_unlock(), ast_sched_runq(), ast_sched_wait(), io, and sched. 02998 { 02999 int res; 03000 03001 /* This thread monitors all the interfaces which are not yet in use 03002 (and thus do not have a separate thread) indefinitely */ 03003 /* From here on out, we die whenever asked */ 03004 for(;;) { 03005 pthread_testcancel(); 03006 /* Wait for sched or io */ 03007 res = ast_sched_wait(sched); 03008 if ((res < 0) || (res > 1000)) { 03009 res = 1000; 03010 } 03011 res = ast_io_wait(io, res); 03012 ast_mutex_lock(&monlock); 03013 if (res >= 0) { 03014 ast_sched_runq(sched); 03015 } 03016 ast_mutex_unlock(&monlock); 03017 } 03018 /* Never reached */ 03019 return NULL; 03020 03021 }
|
|
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 }
|
|
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 }
|
|
Definition at line 2863 of file chan_skinny.c. References ast_log(), ast_mutex_unlock(), pollfd::events, pollfd::fd, htolel, letohl, LOG_WARNING, poll(), POLLIN, and s. 02864 { 02865 int res; 02866 int dlen = 0; 02867 struct pollfd fds[1]; 02868 02869 fds[0].fd = s->fd; 02870 fds[0].events = POLLIN; 02871 res = poll(fds, 1, -1); 02872 02873 if (res < 0) { 02874 ast_log(LOG_WARNING, "Select returned error: %s\n", strerror(errno)); 02875 } else if (res > 0) { 02876 memset(s->inbuf,0,sizeof(s->inbuf)); 02877 res = read(s->fd, s->inbuf, 4); 02878 if (res != 4) { 02879 ast_log(LOG_WARNING, "Skinny Client sent less data than expected.\n"); 02880 return -1; 02881 } 02882 dlen = letohl(*(int *)s->inbuf); 02883 if (dlen+8 > sizeof(s->inbuf)) { 02884 dlen = sizeof(s->inbuf) - 8; 02885 } 02886 *(int *)s->inbuf = htolel(dlen); 02887 res = read(s->fd, s->inbuf+4, dlen+4); 02888 ast_mutex_unlock(&s->lock); 02889 if (res != (dlen+4)) { 02890 ast_log(LOG_WARNING, "Skinny Client sent less data than expected.\n"); 02891 return -1; 02892 } 02893 } 02894 return res; 02895 }
|
|
Definition at line 2321 of file chan_skinny.c. References ALARM_MESSAGE, ast_log(), ast_verbose(), button_defs, BUTTON_TEMPLATE_REQ_MESSAGE, BUTTON_TEMPLATE_RES_MESSAGE, CAPABILITIES_REQ_MESSAGE, skinny_req::data, register_ack_message::dateTemplate, skinny_req::e, register_rej_message::errMsg, find_subchannel_by_line(), free, htolel, IP_PORT_MESSAGE, register_ack_message::keepAlive, skinny_req::len, letohl, LOG_ERROR, LOG_WARNING, skinny_line::name, register_message::name, name, option_verbose, skinny_subchannel::parent, skinny_req::reg, skinny_req::regack, REGISTER_ACK_MESSAGE, REGISTER_MESSAGE, REGISTER_REJ_MESSAGE, skinny_req::regrej, register_ack_message::res, register_ack_message::res2, s, register_ack_message::secondaryKeepAlive, 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_DIALTONE, SKINNY_LAMP_OFF, SKINNY_LAMP_ON, SKINNY_MAX_PACKET, skinny_register(), 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, t, transmit_displaynotify(), transmit_lamp_indication(), transmit_response(), transmit_speaker_mode(), transmit_tone(), button_defs::type, UNREGISTER_MESSAGE, VERBOSE_PREFIX_3, version_res_message::version, skinny_req::version, VERSION_REQ_MESSAGE, and VERSION_RES_MESSAGE. Referenced by skinny_session(). 02322 { 02323 struct skinny_subchannel *sub; 02324 struct ast_channel *c; 02325 struct ast_frame f = { 0, }; 02326 struct sockaddr_in sin; 02327 struct sockaddr_in us; 02328 struct skinny_line *lines; 02329 char name[16]; 02330 char addr[4]; 02331 char d; 02332 char iabuf[INET_ADDRSTRLEN]; 02333 int digit; 02334 int res=0; 02335 int speedDialNum; 02336 int lineNumber; 02337 int stimulus; 02338 int stimulusInstance; 02339 int status; 02340 int port; 02341 int i; 02342 time_t timer; 02343 struct tm *cmtime; 02344 pthread_t t; 02345 button_defs_t *b, *buse; 02346 02347 if ((!s->device) && (letohl(req->e) != REGISTER_MESSAGE && letohl(req->e) != ALARM_MESSAGE)) { 02348 ast_log(LOG_WARNING, "Client sent message #%d without first registering.\n", req->e); 02349 free(req); 02350 return 0; 02351 } 02352 02353 switch(letohl(req->e)) { 02354 case ALARM_MESSAGE: 02355 /* no response necessary */ 02356 break; 02357 case REGISTER_MESSAGE: 02358 if (skinnydebug) { 02359 ast_verbose("Device %s is attempting to register\n", req->data.reg.name); 02360 } 02361 res = skinny_register(req, s); 02362 if (!res) { 02363 ast_log(LOG_ERROR, "Rejecting Device %s: Device not found\n", req->data.reg.name); 02364 memcpy(&name, req->data.reg.name, sizeof(req->data.reg.name)); 02365 memset(req, 0, sizeof(skinny_req)); 02366 req->len = htolel(sizeof(register_rej_message)+4); 02367 req->e = htolel(REGISTER_REJ_MESSAGE); 02368 snprintf(req->data.regrej.errMsg, sizeof(req->data.regrej.errMsg), "No Authority: %s", name); 02369 transmit_response(s, req); 02370 break; 02371 } 02372 if (option_verbose > 2) { 02373 ast_verbose(VERBOSE_PREFIX_3 "Device '%s' successfuly registered\n", s->device->name); 02374 } 02375 memset(req, 0, SKINNY_MAX_PACKET); 02376 req->len = htolel(sizeof(register_ack_message)+4); 02377 req->e = htolel(REGISTER_ACK_MESSAGE); 02378 req->data.regack.res[0] = '0'; 02379 req->data.regack.res[1] = '\0'; 02380 req->data.regack.keepAlive = htolel(keep_alive); 02381 strncpy(req->data.regack.dateTemplate, date_format, sizeof(req->data.regack.dateTemplate) - 1); 02382 req->data.regack.res2[0] = '0'; 02383 req->data.regack.res2[1] = '\0'; 02384 req->data.regack.secondaryKeepAlive = htolel(keep_alive); 02385 transmit_response(s, req); 02386 if (skinnydebug) { 02387 ast_verbose("Requesting capabilities\n"); 02388 } 02389 memset(req, 0, SKINNY_MAX_PACKET); 02390 req->len = htolel(4); 02391 req->e = htolel(CAPABILITIES_REQ_MESSAGE); 02392 transmit_response(s, req); 02393 break; 02394 case UNREGISTER_MESSAGE: 02395 /* XXX Acutally unregister the device */ 02396 break; 02397 case IP_PORT_MESSAGE: 02398 /* no response necessary */ 02399 break; 02400 case STIMULUS_MESSAGE: 02401 stimulus = letohl(req->data.stimulus.stimulus); 02402 stimulusInstance = letohl(req->data.stimulus.stimulusInstance); 02403 02404 switch(stimulus) { 02405 case STIMULUS_REDIAL: 02406 /* If we can keep an array of dialed frames we can implement a quick 02407 and dirty redial, feeding the frames we last got into the queue 02408 function */ 02409 if (skinnydebug) { 02410 ast_verbose("Recieved Stimulus: Redial(%d)\n", stimulusInstance); 02411 } 02412 break; 02413 case STIMULUS_SPEEDDIAL: 02414 if (skinnydebug) { 02415 ast_verbose("Recieved Stimulus: SpeedDial(%d)\n", stimulusInstance); 02416 } 02417 break; 02418 case STIMULUS_HOLD: 02419 /* start moh? set RTP to 0.0.0.0? */ 02420 if (skinnydebug) { 02421 ast_verbose("Recieved Stimulus: Hold(%d)\n", stimulusInstance); 02422 } 02423 break; 02424 case STIMULUS_TRANSFER: 02425 if (skinnydebug) { 02426 ast_verbose("Recieved Stimulus: Transfer(%d)\n", stimulusInstance); 02427 } 02428 transmit_tone(s, SKINNY_DIALTONE); 02429 /* XXX figure out how to transfer */ 02430 break; 02431 case STIMULUS_CONFERENCE: 02432 if (skinnydebug) { 02433 ast_verbose("Recieved Stimulus: Transfer(%d)\n", stimulusInstance); 02434 } 02435 transmit_tone(s, SKINNY_DIALTONE); 02436 /* XXX determine the best way to pull off a conference. Meetme? */ 02437 break; 02438 case STIMULUS_VOICEMAIL: 02439 if (skinnydebug) { 02440 ast_verbose("Recieved Stimulus: Voicemail(%d)\n", stimulusInstance); 02441 } 02442 /* XXX Find and dial voicemail extension */ 02443 break; 02444 case STIMULUS_CALLPARK: 02445 if (skinnydebug) { 02446 ast_verbose("Recieved Stimulus: Park Call(%d)\n", stimulusInstance); 02447 } 02448 /* XXX Park the call */ 02449 break; 02450 case STIMULUS_FORWARDALL: 02451 /* Why is DND under FORWARDALL ? */ 02452 02453 /* Do not disturb */ 02454 transmit_tone(s, SKINNY_DIALTONE); 02455 if (s->device->lines->dnd != 0){ 02456 if (option_verbose > 2) { 02457 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); 02458 } 02459 s->device->lines->dnd = 0; 02460 transmit_lamp_indication(s, STIMULUS_FORWARDALL, 1, SKINNY_LAMP_ON); 02461 transmit_displaynotify(s, "DnD disabled",10); 02462 } else { 02463 if (option_verbose > 2) { 02464 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); 02465 } 02466 s->device->lines->dnd = 1; 02467 transmit_lamp_indication(s, STIMULUS_FORWARDALL, 1, SKINNY_LAMP_OFF); 02468 transmit_displaynotify(s, "DnD enabled",10); 02469 } 02470 break; 02471 case STIMULUS_FORWARDBUSY: 02472 case STIMULUS_FORWARDNOANSWER: 02473 /* Gonna be fun, not */ 02474 if (skinnydebug) { 02475 ast_verbose("Recieved Stimulus: Forward (%d)\n", stimulusInstance); 02476 } 02477 break; 02478 case STIMULUS_DISPLAY: 02479 /* Not sure what this is */ 02480 if (skinnydebug) { 02481 ast_verbose("Recieved Stimulus: Display(%d)\n", stimulusInstance); 02482 } 02483 break; 02484 case STIMULUS_LINE: 02485 if (skinnydebug) { 02486 ast_verbose("Recieved Stimulus: Line(%d)\n", stimulusInstance); 02487 } 02488 sub = find_subchannel_by_line(s->device->lines); 02489 /* turn the speaker on */ 02490 transmit_speaker_mode(s, 1); 02491 break; 02492 default: 02493 ast_verbose("RECEIVED UNKNOWN STIMULUS: %d(%d)\n", stimulus, stimulusInstance); 02494 break; 02495 } 02496 break; 02497 case VERSION_REQ_MESSAGE: 02498 if (skinnydebug) { 02499 ast_verbose("Version Request\n"); 02500 } 02501 memset(req, 0, SKINNY_MAX_PACKET); 02502 req->len = htolel(sizeof(version_res_message)+4); 02503 req->e = htolel(VERSION_RES_MESSAGE); 02504 snprintf(req->data.version.version, sizeof(req->data.version.version), s->device->version_id); 02505 transmit_response(s, req); 02506 break; 02507 case SERVER_REQUEST_MESSAGE: 02508 if (skinnydebug) { 02509 ast_verbose("Recieved Server Request\n"); 02510 } 02511 memset(req, 0, SKINNY_MAX_PACKET); 02512 req->len = htolel(sizeof(server_res_message)+4); 02513 req->e = htolel(SERVER_RES_MESSAGE); 02514 memcpy(req->data.serverres.server[0].serverName, ourhost, 02515 sizeof(req->data.serverres.server[0].serverName)); 02516 req->data.serverres.serverListenPort[0] = htolel(ourport); 02517 req->data.serverres.serverIpAddr[0] = htolel(__ourip.s_addr); 02518 transmit_response(s, req); 02519 break; 02520 case BUTTON_TEMPLATE_REQ_MESSAGE: 02521 if (skinnydebug) { 02522 ast_verbose("Buttontemplate requested\n"); 02523 } 02524 sub = find_subchannel_by_line(s->device->lines); 02525 memset(req, 0, SKINNY_MAX_PACKET); 02526 req->e = htolel(BUTTON_TEMPLATE_RES_MESSAGE); 02527 req->len = htolel(sizeof(button_template_res_message)+4); 02528 02529 /* Find a matching button definition, default to first in the 02530 list */ 02531 buse = button_defs; 02532 for(b=button_defs; b->type; b++) { 02533 if (!strcmp(s->device->model, b->type)) { 02534 buse = b; 02535 } 02536 } 02537 req->data.buttontemplate.buttonOffset = 0; 02538 req->data.buttontemplate.buttonCount = htolel(buse->num_buttons); 02539 req->data.buttontemplate.totalButtonCount = htolel(buse->num_buttons); 02540 for (i=0; i<42; i++) { 02541 if (i < buse->num_buttons) { 02542 memcpy(&(req->data.buttontemplate.definition[i]), 02543 &(buse->button_def[i]), 02544 sizeof(button_definition)); 02545 } else { 02546 memcpy(&(req->data.buttontemplate.definition[i]), 02547 &(button_def_none), 02548 sizeof(button_definition)); 02549 } 02550 } 02551 02552 if (skinnydebug) { 02553 ast_verbose("Sending %s template to %s@%s (%s)\n", 02554 buse->type, 02555 sub->parent->name, 02556 sub->parent->parent->name, 02557 s->device->model); 02558 } 02559 transmit_response(s, req); 02560 break; 02561 case SOFT_KEY_SET_REQ_MESSAGE: 02562 if (skinnydebug) { 02563 ast_verbose("Received SoftKeySetReq\n"); 02564 } 02565 memset(req, 0, SKINNY_MAX_PACKET); 02566 req->len = htolel(sizeof(soft_key_sets)+4); 02567 req->e = htolel(SOFT_KEY_SET_RES_MESSAGE); 02568 req->data.softkeysets.softKeySetOffset = 0; 02569 req->data.softkeysets.softKeySetCount = htolel(11); 02570 req->data.softkeysets.totalSoftKeySetCount = htolel(11); 02571 /* XXX Wicked hack XXX */ 02572 memcpy(req->data.softkeysets.softKeySetDefinition, 02573 soft_key_set_hack, 02574 sizeof(req->data.softkeysets.softKeySetDefinition)); 02575 transmit_response(s,req); 02576 break; 02577 case SOFT_KEY_TEMPLATE_REQ_MESSAGE: 02578 if (skinnydebug) { 02579 ast_verbose("Recieved SoftKey Template Request\n"); 02580 } 02581 memset(req, 0, SKINNY_MAX_PACKET); 02582 req->len = htolel(sizeof(soft_key_template)+4); 02583 req->e = htolel(SOFT_KEY_TEMPLATE_RES_MESSAGE); 02584 req->data.softkeytemplate.softKeyOffset = 0; 02585 req->data.softkeytemplate.softKeyCount = htolel(sizeof(soft_key_template_default) / sizeof(soft_key_template_definition)); 02586 req->data.softkeytemplate.totalSoftKeyCount = htolel(sizeof(soft_key_template_default) / sizeof(soft_key_template_definition)); 02587 memcpy(req->data.softkeytemplate.softKeyTemplateDefinition, 02588 soft_key_template_default, 02589 sizeof(soft_key_template_default)); 02590 transmit_response(s,req); 02591 break; 02592 case TIME_DATE_REQ_MESSAGE: 02593 if (skinnydebug) { 02594 ast_verbose("Received Time/Date Request\n"); 02595 } 02596 memset(req, 0, SKINNY_MAX_PACKET); 02597 req->len = htolel(sizeof(definetimedate_message)+4); 02598 req->e = htolel(DEFINETIMEDATE_MESSAGE); 02599 timer=time(NULL); 02600 cmtime = localtime(&timer); 02601 req->data.definetimedate.year = htolel(cmtime->tm_year+1900); 02602 req->data.definetimedate.month = htolel(cmtime->tm_mon+1); 02603 req->data.definetimedate.dayofweek = htolel(cmtime->tm_wday); 02604 req->data.definetimedate.day = htolel(cmtime->tm_mday); 02605 req->data.definetimedate.hour = htolel(cmtime->tm_hour); 02606 req->data.definetimedate.minute = htolel(cmtime->tm_min); 02607 req->data.definetimedate.seconds = htolel(cmtime->tm_sec); 02608 transmit_response(s, req); 02609 break; 02610 case SPEED_DIAL_STAT_REQ_MESSAGE: 02611 /* Not really sure how Speed Dial's are different than the 02612 Softkey templates */ 02613 speedDialNum = letohl(req->data.speeddialreq.speedDialNumber); 02614 memset(req, 0, SKINNY_MAX_PACKET); 02615 req->len = htolel(sizeof(speed_dial_stat_res_message)+4); 02616 req->e = htolel(SPEED_DIAL_STAT_RES_MESSAGE); 02617 #if 0 02618 /* XXX Do this right XXX */ 02619 /* If the redial function works the way I think it will, a modification of it 02620 can work here was well. Yikes. */ 02621 req->data.speeddialreq.speedDialNumber = speedDialNum; 02622 snprintf(req->data.speeddial.speedDialDirNumber, sizeof(req->data.speeddial.speedDialDirNumber), "31337"); 02623 snprintf(req->data.speeddial.speedDialDisplayName, sizeof(req->data.speeddial.speedDialDisplayName),"Asterisk Rules!"); 02624 #endif 02625 transmit_response(s, req); 02626 break; 02627 case LINE_STATE_REQ_MESSAGE: 02628 lineNumber = letohl(req->data.line.lineNumber); 02629 if (skinnydebug) { 02630 ast_verbose("Received LineStateReq\n"); 02631 } 02632 memset(req, 0, SKINNY_MAX_PACKET); 02633 req->len = htolel(sizeof(line_stat_res_message)+4); 02634 req->e = htolel(LINE_STAT_RES_MESSAGE); 02635 sub = find_subchannel_by_line(s->device->lines); 02636 if (!sub) { 02637 ast_log(LOG_NOTICE, "No available lines on: %s\n", s->device->name); 02638 return 0; 02639 } 02640 lines = sub->parent; 02641 ast_mutex_lock(&devicelock); 02642 for (i=1; i < lineNumber; i++) { 02643 lines = lines->next; 02644 } 02645 ast_mutex_unlock(&devicelock); 02646 req->data.linestat.linenumber = letohl(lineNumber); 02647 memcpy(req->data.linestat.lineDirNumber, lines->name, 02648 sizeof(req->data.linestat.lineDirNumber)); 02649 memcpy(req->data.linestat.lineDisplayName, lines->label, 02650 sizeof(req->data.linestat.lineDisplayName)); 02651 transmit_response(s,req); 02652 break; 02653 case CAPABILITIES_RES_MESSAGE: 02654 if (skinnydebug) { 02655 ast_verbose("Received CapabilitiesRes\n"); 02656 } 02657 /* XXX process the capabilites */ 02658 break; 02659 case KEEP_ALIVE_MESSAGE: 02660 memset(req, 0, SKINNY_MAX_PACKET); 02661 req->len = htolel(4); 02662 req->e = htolel(KEEP_ALIVE_ACK_MESSAGE); 02663 transmit_response(s, req); 02664 do_housekeeping(s); 02665 break; 02666 case OFFHOOK_MESSAGE: 02667 transmit_ringer_mode(s,SKINNY_RING_OFF); 02668 transmit_lamp_indication(s, STIMULUS_LINE, s->device->lines->instance, SKINNY_LAMP_ON); 02669 sub = find_subchannel_by_line(s->device->lines); 02670 if (!sub) { 02671 ast_log(LOG_NOTICE, "No available lines on: %s\n", s->device->name); 02672 return 0; 02673 } 02674 sub->parent->hookstate = SKINNY_OFFHOOK; 02675 02676 if (sub->outgoing) { 02677 /* We're answering a ringing call */ 02678 ast_queue_control(sub->owner, AST_CONTROL_ANSWER); 02679 transmit_callstate(s, s->device->lines->instance, SKINNY_OFFHOOK, sub->callid); 02680 transmit_tone(s, SKINNY_SILENCE); 02681 transmit_callstate(s, s->device->lines->instance, SKINNY_CONNECTED, sub->callid); 02682 start_rtp(sub); 02683 ast_setstate(sub->owner, AST_STATE_UP); 02684 /* XXX select the appropriate soft key here */ 02685 } else { 02686 if (!sub->owner) { 02687 transmit_callstate(s, s->device->lines->instance, SKINNY_OFFHOOK, sub->callid); 02688 if (skinnydebug) { 02689 ast_verbose("Attempting to Clear display on Skinny %s@%s\n",sub->parent->name, sub->parent->parent->name); 02690 } 02691 transmit_displaymessage(s, NULL); /* clear display */ 02692 transmit_tone(s, SKINNY_DIALTONE); 02693 c = skinny_new(sub, AST_STATE_DOWN); 02694 if(c) { 02695 /* start the switch thread */ 02696 if (ast_pthread_create(&t, NULL, skinny_ss, c)) { 02697 ast_log(LOG_WARNING, "Unable to create switch thread: %s\n", strerror(errno)); 02698 ast_hangup(c); 02699 } 02700 } else { 02701 ast_log(LOG_WARNING, "Unable to create channel for %s@%s\n", sub->parent->name, s->device->name); 02702 } 02703 } else { 02704 ast_log(LOG_DEBUG, "Current sub [%s] already has owner\n", sub->owner->name); 02705 } 02706 } 02707 break; 02708 case ONHOOK_MESSAGE: 02709 sub = find_subchannel_by_line(s->device->lines); 02710 if (sub->parent->hookstate == SKINNY_ONHOOK) { 02711 /* Somthing else already put us back on hook */ 02712 break; 02713 } 02714 sub->cxmode = SKINNY_CX_RECVONLY; 02715 sub->parent->hookstate = SKINNY_ONHOOK; 02716 transmit_callstate(s, s->device->lines->instance, sub->parent->hookstate,sub->callid); 02717 if (skinnydebug) { 02718 ast_verbose("Skinny %s@%s went on hook\n",sub->parent->name, sub->parent->parent->name); 02719 } 02720 if (sub->parent->transfer && (sub->owner && sub->next->owner) && ((!sub->outgoing) || (!sub->next->outgoing))) { 02721 /* We're allowed to transfer, we have two active calls and */ 02722 /* we made at least one of the calls. Let's try and transfer */ 02723 02724 #if 0 02725 if ((res = attempt_transfer(p)) < 0) { 02726 if (p->sub->next->owner) { 02727 sub->next->alreadygone = 1; 02728 ast_queue_hangup(sub->next->owner,1); 02729 } 02730 } else if (res) { 02731 ast_log(LOG_WARNING, "Transfer attempt failed\n"); 02732 return -1; 02733 } 02734 #endif 02735 } else { 02736 /* Hangup the current call */ 02737 /* If there is another active call, skinny_hangup will ring the phone with the other call */ 02738 if (sub->owner) { 02739 sub->alreadygone = 1; 02740 ast_queue_hangup(sub->owner); 02741 } else { 02742 ast_log(LOG_WARNING, "Skinny(%s@%s-%d) channel already destroyed\n", 02743 sub->parent->name, sub->parent->parent->name, sub->callid); 02744 } 02745 } 02746 if ((sub->parent->hookstate == SKINNY_ONHOOK) && (!sub->next->rtp)) { 02747 do_housekeeping(s); 02748 } 02749 break; 02750 case KEYPAD_BUTTON_MESSAGE: 02751 digit = letohl(req->data.keypad.button); 02752 if (skinnydebug) { 02753 ast_verbose("Collected digit: [%d]\n", digit); 02754 } 02755 f.frametype = AST_FRAME_DTMF; 02756 if (digit == 14) { 02757 d = '*'; 02758 } else if (digit == 15) { 02759 d = '#'; 02760 } else if (digit >=0 && digit <= 9) { 02761 d = '0' + digit; 02762 } else { 02763 /* digit=10-13 (A,B,C,D ?), or 02764 * digit is bad value 02765 * 02766 * probably should not end up here, but set 02767 * value for backward compatibility, and log 02768 * a warning. 02769 */ 02770 d = '0' + digit; 02771 ast_log(LOG_WARNING, "Unsupported digit %d\n", digit); 02772 } 02773 f.subclass = d; 02774 f.src = "skinny"; 02775 sub = find_subchannel_by_line(s->device->lines); 02776 if (sub->owner) { 02777 /* XXX MUST queue this frame to all subs in threeway call if threeway call is active */ 02778 ast_queue_frame(sub->owner, &f); 02779 if (sub->next->owner) { 02780 ast_queue_frame(sub->next->owner, &f); 02781 } 02782 } else { 02783 ast_verbose("No owner: %s\n", s->device->lines->name); 02784 } 02785 break; 02786 case OPEN_RECIEVE_CHANNEL_ACK_MESSAGE: 02787 ast_verbose("Recieved Open Recieve Channel Ack\n"); 02788 status = letohl(req->data.openrecievechannelack.status); 02789 if (status) { 02790 ast_log(LOG_ERROR, "Open Recieve Channel Failure\n"); 02791 break; 02792 } 02793 /* ENDIAN */ 02794 memcpy(addr, req->data.openrecievechannelack.ipAddr, sizeof(addr)); 02795 port = htolel(req->data.openrecievechannelack.port); 02796 sin.sin_family = AF_INET; 02797 /* I smell endian problems */ 02798 memcpy(&sin.sin_addr, addr, sizeof(sin.sin_addr)); 02799 sin.sin_port = htons(port); 02800 if (skinnydebug) { 02801 ast_verbose("ipaddr = %s:%d\n", ast_inet_ntoa(iabuf, sizeof(iabuf), sin.sin_addr), ntohs(sin.sin_port)); 02802 } 02803 sub = find_subchannel_by_line(s->device->lines); 02804 if (sub->rtp) { 02805 ast_rtp_set_peer(sub->rtp, &sin); 02806 ast_rtp_get_us(sub->rtp, &us); 02807 } else { 02808 ast_log(LOG_ERROR, "No RTP structure, this is very bad\n"); 02809 break; 02810 } 02811 memset(req, 0, SKINNY_MAX_PACKET); 02812 req->len = htolel(sizeof(start_media_transmission_message)+4); 02813 req->e = htolel(START_MEDIA_TRANSMISSION_MESSAGE); 02814 req->data.startmedia.conferenceId = 0; 02815 req->data.startmedia.passThruPartyId = 0; 02816 memcpy(req->data.startmedia.remoteIp, &s->device->ourip, 4); /* Endian? */ 02817 req->data.startmedia.remotePort = htolel(ntohs(us.sin_port)); 02818 req->data.startmedia.packetSize = htolel(20); 02819 req->data.startmedia.payloadType = htolel(convert_cap(s->device->lines->capability)); 02820 req->data.startmedia.qualifier.precedence = htolel(127); 02821 req->data.startmedia.qualifier.vad = 0; 02822 req->data.startmedia.qualifier.packets = 0; 02823 req->data.startmedia.qualifier.bitRate = 0; 02824 transmit_response(s, req); 02825 break; 02826 default: 02827 ast_verbose("RECEIVED UNKNOWN MESSAGE TYPE: %x\n", letohl(req->e)); 02828 break; 02829 } 02830 free(req); 02831 return 1; 02832 }
|
|
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 }
|
|
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 3373 of file chan_skinny.c. References ASTERISK_GPL_KEY. 03374 { 03375 return ASTERISK_GPL_KEY; 03376 }
|
|
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 3276 of file chan_skinny.c. References htolel. 03277 { 03278 int res = 0; 03279 03280 for (; res < (sizeof(soft_key_template_default) / sizeof(soft_key_template_default[0])); res++) { 03281 soft_key_template_default[res].softKeyEvent = htolel(soft_key_template_default[res].softKeyEvent); 03282 } 03283 /* load and parse config */ 03284 res = reload_config(); 03285 03286 ast_rtp_proto_register(&skinny_rtp); 03287 ast_cli_register(&cli_show_devices); 03288 ast_cli_register(&cli_show_lines); 03289 ast_cli_register(&cli_debug); 03290 ast_cli_register(&cli_no_debug); 03291 sched = sched_context_create(); 03292 if (!sched) { 03293 ast_log(LOG_WARNING, "Unable to create schedule context\n"); 03294 } 03295 io = io_context_create(); 03296 if (!io) { 03297 ast_log(LOG_WARNING, "Unable to create I/O context\n"); 03298 } 03299 /* And start the monitor for the first time */ 03300 restart_monitor(); 03301 03302 /* Announce our presence to Asterisk */ 03303 if (!res) { 03304 /* Make sure we can register our skinny channel type */ 03305 if (ast_channel_register(&skinny_tech)) { 03306 ast_log(LOG_ERROR, "Unable to register channel class %s\n", type); 03307 return -1; 03308 } 03309 } 03310 return res; 03311 }
|
|
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 3267 of file chan_skinny.c. References delete_devices(), reload_config(), and restart_monitor(). 03268 { 03269 delete_devices(); 03270 reload_config(); 03271 restart_monitor(); 03272 return 0; 03273 }
|
|
Definition at line 3089 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. 03090 { 03091 int on = 1; 03092 struct ast_config *cfg; 03093 struct ast_variable *v; 03094 int format; 03095 char *cat; 03096 char iabuf[INET_ADDRSTRLEN]; 03097 struct skinny_device *d; 03098 int oldport = ntohs(bindaddr.sin_port); 03099 03100 if (gethostname(ourhost, sizeof(ourhost))) { 03101 ast_log(LOG_WARNING, "Unable to get hostname, Skinny disabled\n"); 03102 return 0; 03103 } 03104 cfg = ast_config_load(config); 03105 03106 /* We *must* have a config file otherwise stop immediately */ 03107 if (!cfg) { 03108 ast_log(LOG_NOTICE, "Unable to load config %s, Skinny disabled\n", config); 03109 return 0; 03110 } 03111 /* load the general section */ 03112 memset(&bindaddr, 0, sizeof(bindaddr)); 03113 v = ast_variable_browse(cfg, "general"); 03114 while(v) { 03115 /* Create the interface list */ 03116 if (!strcasecmp(v->name, "bindaddr")) { 03117 if (!(hp = ast_gethostbyname(v->value, &ahp))) { 03118 ast_log(LOG_WARNING, "Invalid address: %s\n", v->value); 03119 } else { 03120 memcpy(&bindaddr.sin_addr, hp->h_addr, sizeof(bindaddr.sin_addr)); 03121 } 03122 } else if (!strcasecmp(v->name, "keepAlive")) { 03123 keep_alive = atoi(v->value); 03124 } else if (!strcasecmp(v->name, "dateFormat")) { 03125 strncpy(date_format, v->value, sizeof(date_format) - 1); 03126 } else if (!strcasecmp(v->name, "allow")) { 03127 format = ast_getformatbyname(v->value); 03128 if (format < 1) { 03129 ast_log(LOG_WARNING, "Cannot allow unknown format '%s'\n", v->value); 03130 } else { 03131 capability |= format; 03132 } 03133 } else if (!strcasecmp(v->name, "disallow")) { 03134 format = ast_getformatbyname(v->value); 03135 if (format < 1) { 03136 ast_log(LOG_WARNING, "Cannot disallow unknown format '%s'\n", v->value); 03137 } else { 03138 capability &= ~format; 03139 } 03140 } else if (!strcasecmp(v->name, "port")) { 03141 if (sscanf(v->value, "%d", &ourport) == 1) { 03142 bindaddr.sin_port = htons(ourport); 03143 } else { 03144 ast_log(LOG_WARNING, "Invalid port number '%s' at line %d of %s\n", v->value, v->lineno, config); 03145 } 03146 } 03147 v = v->next; 03148 } 03149 if (ntohl(bindaddr.sin_addr.s_addr)) { 03150 memcpy(&__ourip, &bindaddr.sin_addr, sizeof(__ourip)); 03151 } else { 03152 hp = ast_gethostbyname(ourhost, &ahp); 03153 if (!hp) { 03154 ast_log(LOG_WARNING, "Unable to get our IP address, Skinny disabled\n"); 03155 ast_config_destroy(cfg); 03156 return 0; 03157 } 03158 memcpy(&__ourip, hp->h_addr, sizeof(__ourip)); 03159 } 03160 if (!ntohs(bindaddr.sin_port)) { 03161 bindaddr.sin_port = ntohs(DEFAULT_SKINNY_PORT); 03162 } 03163 bindaddr.sin_family = AF_INET; 03164 03165 /* load the device sections */ 03166 cat = ast_category_browse(cfg, NULL); 03167 while(cat) { 03168 if (!strcasecmp(cat, "general")) { 03169 /* Nothing to do */ 03170 #if 0 03171 } else if (!strncasecmp(cat, "paging-", 7)) { 03172 p = build_paging_device(cat, ast_variable_browse(cfg, cat)); 03173 if (p) { 03174 } 03175 #endif 03176 } else { 03177 d = build_device(cat, ast_variable_browse(cfg, cat)); 03178 if (d) { 03179 if (option_verbose > 2) { 03180 ast_verbose(VERBOSE_PREFIX_3 "Added device '%s'\n", d->name); 03181 } 03182 ast_mutex_lock(&devicelock); 03183 d->next = devices; 03184 devices = d; 03185 ast_mutex_unlock(&devicelock); 03186 } 03187 } 03188 cat = ast_category_browse(cfg, cat); 03189 } 03190 ast_mutex_lock(&netlock); 03191 if ((skinnysock > -1) && (ntohs(bindaddr.sin_port) != oldport)) { 03192 close(skinnysock); 03193 skinnysock = -1; 03194 } 03195 if (skinnysock < 0) { 03196 skinnysock = socket(AF_INET, SOCK_STREAM, 0); 03197 if(setsockopt(skinnysock, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on)) == -1) { 03198 ast_log(LOG_ERROR, "Set Socket Options failed: errno %d, %s", errno, strerror(errno)); 03199 ast_config_destroy(cfg); 03200 return 0; 03201 } 03202 if (skinnysock < 0) { 03203 ast_log(LOG_WARNING, "Unable to create Skinny socket: %s\n", strerror(errno)); 03204 } else { 03205 if (bind(skinnysock, (struct sockaddr *)&bindaddr, sizeof(bindaddr)) < 0) { 03206 ast_log(LOG_WARNING, "Failed to bind to %s:%d: %s\n", 03207 ast_inet_ntoa(iabuf, sizeof(iabuf), bindaddr.sin_addr), ntohs(bindaddr.sin_port), 03208 strerror(errno)); 03209 close(skinnysock); 03210 skinnysock = -1; 03211 ast_config_destroy(cfg); 03212 return 0; 03213 } 03214 if (listen(skinnysock,DEFAULT_SKINNY_BACKLOG)) { 03215 ast_log(LOG_WARNING, "Failed to start listening to %s:%d: %s\n", 03216 ast_inet_ntoa(iabuf, sizeof(iabuf), bindaddr.sin_addr), ntohs(bindaddr.sin_port), 03217 strerror(errno)); 03218 close(skinnysock); 03219 skinnysock = -1; 03220 ast_config_destroy(cfg); 03221 return 0; 03222 } 03223 if (option_verbose > 1) { 03224 ast_verbose(VERBOSE_PREFIX_2 "Skinny listening on %s:%d\n", 03225 ast_inet_ntoa(iabuf, sizeof(iabuf), bindaddr.sin_addr), ntohs(bindaddr.sin_port)); 03226 } 03227 ast_pthread_create(&accept_t,NULL, accept_thread, NULL); 03228 } 03229 } 03230 ast_mutex_unlock(&netlock); 03231 ast_config_destroy(cfg); 03232 return 0; 03233 }
|
|
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 }
|
|
Definition at line 3023 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. 03024 { 03025 /* If we're supposed to be stopped -- stay stopped */ 03026 if (monitor_thread == AST_PTHREADT_STOP) 03027 return 0; 03028 if (ast_mutex_lock(&monlock)) { 03029 ast_log(LOG_WARNING, "Unable to lock monitor\n"); 03030 return -1; 03031 } 03032 if (monitor_thread == pthread_self()) { 03033 ast_mutex_unlock(&monlock); 03034 ast_log(LOG_WARNING, "Cannot kill myself\n"); 03035 return -1; 03036 } 03037 if (monitor_thread != AST_PTHREADT_NULL) { 03038 /* Wake up the thread */ 03039 pthread_kill(monitor_thread, SIGURG); 03040 } else { 03041 /* Start a new monitor */ 03042 if (ast_pthread_create(&monitor_thread, NULL, do_monitor, NULL) < 0) { 03043 ast_mutex_unlock(&monlock); 03044 ast_log(LOG_ERROR, "Unable to start monitor thread.\n"); 03045 return -1; 03046 } 03047 } 03048 ast_mutex_unlock(&monlock); 03049 return 0; 03050 }
|
|
|
Definition at line 1913 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. 01914 { 01915 int res = 0; 01916 int tone = 0; 01917 struct skinny_line *l; 01918 struct skinny_subchannel *sub; 01919 struct skinnysession *session; 01920 01921 sub = ast->tech_pvt; 01922 l = sub->parent; 01923 session = l->parent->session; 01924 01925 if (!l->parent->registered) { 01926 ast_log(LOG_ERROR, "Device not registered, cannot call %s\n", dest); 01927 return -1; 01928 } 01929 01930 if ((ast->_state != AST_STATE_DOWN) && (ast->_state != AST_STATE_RESERVED)) { 01931 ast_log(LOG_WARNING, "skinny_call called on %s, neither down nor reserved\n", ast->name); 01932 return -1; 01933 } 01934 01935 if (skinnydebug) { 01936 ast_verbose(VERBOSE_PREFIX_3 "skinny_call(%s)\n", ast->name); 01937 } 01938 01939 if (l->dnd) { 01940 ast_queue_control(ast, AST_CONTROL_BUSY); 01941 return -1; 01942 } 01943 01944 switch (l->hookstate) { 01945 case SKINNY_OFFHOOK: 01946 tone = SKINNY_CALLWAITTONE; 01947 break; 01948 case SKINNY_ONHOOK: 01949 tone = SKINNY_ALERT; 01950 break; 01951 default: 01952 ast_log(LOG_ERROR, "Don't know how to deal with hookstate %d\n", l->hookstate); 01953 break; 01954 } 01955 01956 transmit_lamp_indication(session, STIMULUS_LINE, l->instance, SKINNY_LAMP_BLINK); 01957 transmit_ringer_mode(session, SKINNY_RING_INSIDE); 01958 01959 if (ast->cid.cid_num) { 01960 char ciddisplay[41]; 01961 char *work; 01962 size_t size = sizeof(ciddisplay); 01963 01964 /* For now, we'll assume that if it is 10 numbers, it is a standard NANPA number */ 01965 if (strlen(ast->cid.cid_num) == 10) { 01966 ast_build_string(&work, &size, "(xxx)xxx-xxxx %s", 01967 ast->cid.cid_name ? ast->cid.cid_name : ""); 01968 memcpy(&ciddisplay[1], ast->cid.cid_num, 3); 01969 memcpy(&ciddisplay[5], &ast->cid.cid_num[3], 3); 01970 memcpy(&ciddisplay[9], &ast->cid.cid_num[6], 4); 01971 } else { 01972 if (strlen(ast->cid.cid_num) < 41) { 01973 ast_build_string(&work, &size, "%s -- %s", ast->cid.cid_num, 01974 ast->cid.cid_name ? ast->cid.cid_name : ""); 01975 } else { 01976 strncpy(ciddisplay, "Number too long!", 15); 01977 } 01978 } 01979 if (skinnydebug) { 01980 ast_verbose("Trying to send: '%s'\n",ciddisplay); 01981 } 01982 transmit_displaymessage(session, ciddisplay); 01983 } else { 01984 transmit_displaymessage(session, "Unknown Name"); 01985 } 01986 transmit_tone(session, tone); 01987 transmit_callstate(session, l->instance, SKINNY_RINGIN, sub->callid); 01988 transmit_displaypromptstatus(session, "Ring-In", 0, l->instance, sub->callid); 01989 transmit_callinfo(session, ast->cid.cid_name, ast->cid.cid_num, l->cid_name, l->cid_num, l->instance, sub->callid, 1); 01990 01991 /* XXX need to deal with softkeys */ 01992 01993 ast_setstate(ast, AST_STATE_RINGING); 01994 ast_queue_control(ast, AST_CONTROL_RINGING); 01995 sub->outgoing = 1; 01996 return res; 01997 }
|
|
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 }
|
|
Definition at line 2119 of file chan_skinny.c. References ast_log(), LOG_NOTICE, LOG_WARNING, ast_channel::name, skinny_subchannel::owner, and ast_channel::tech_pvt. 02120 { 02121 struct skinny_subchannel *sub = newchan->tech_pvt; 02122 ast_log(LOG_NOTICE, "skinny_fixup(%s, %s)\n", oldchan->name, newchan->name); 02123 if (sub->owner != oldchan) { 02124 ast_log(LOG_WARNING, "old channel wasn't %p but was %p\n", oldchan, sub->owner); 02125 return -1; 02126 } 02127 sub->owner = newchan; 02128 return 0; 02129 }
|
|
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 }
|
|
Definition at line 1331 of file chan_skinny.c.
|
|
|
|
|
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 }
|
|
Definition at line 2081 of file chan_skinny.c. References ast_mutex_lock(), ast_mutex_unlock(), skinny_subchannel::lock, skinny_rtp_read(), and ast_channel::tech_pvt. 02082 { 02083 struct ast_frame *fr; 02084 struct skinny_subchannel *sub = ast->tech_pvt; 02085 ast_mutex_lock(&sub->lock); 02086 fr = skinny_rtp_read(sub); 02087 ast_mutex_unlock(&sub->lock); 02088 return fr; 02089 }
|
|
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 }
|
|
Definition at line 2897 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(). 02898 { 02899 skinny_req *req; 02900 02901 req = malloc(SKINNY_MAX_PACKET); 02902 if (!req) { 02903 ast_log(LOG_ERROR, "Unable to allocate skinny_request, this is bad\n"); 02904 return NULL; 02905 } 02906 memset(req, 0, sizeof(skinny_req)); 02907 /* +8 to account for reserved and length fields */ 02908 memcpy(req, s->inbuf, letohl(*(int*)(s->inbuf))+8); 02909 if (letohl(req->e) < 0) { 02910 ast_log(LOG_ERROR, "Event Message is NULL from socket %d, This is bad\n", s->fd); 02911 free(req); 02912 return NULL; 02913 } 02914 return req; 02915 }
|
|
Definition at line 3052 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. 03053 { 03054 int oldformat; 03055 struct skinny_subchannel *sub; 03056 struct ast_channel *tmpc = NULL; 03057 char tmp[256]; 03058 char *dest = data; 03059 03060 oldformat = format; 03061 format &= capability; 03062 if (!format) { 03063 ast_log(LOG_NOTICE, "Asked to get a channel of unsupported format '%d'\n", format); 03064 return NULL; 03065 } 03066 strncpy(tmp, dest, sizeof(tmp) - 1); 03067 if (ast_strlen_zero(tmp)) { 03068 ast_log(LOG_NOTICE, "Skinny channels require a device\n"); 03069 return NULL; 03070 } 03071 sub = find_subchannel_by_name(tmp); 03072 if (!sub) { 03073 ast_log(LOG_NOTICE, "No available lines on: %s\n", dest); 03074 return NULL; 03075 } 03076 if (option_verbose > 2) { 03077 ast_verbose(VERBOSE_PREFIX_3 "skinny_request(%s)\n", tmp); 03078 ast_verbose(VERBOSE_PREFIX_3 "Skinny cw: %d, dnd: %d, so: %d, sno: %d\n", 03079 sub->parent->callwaiting, sub->parent->dnd, sub->owner ? 1 : 0, sub->next->owner ? 1: 0); 03080 } 03081 tmpc = skinny_new(sub->owner ? sub->next : sub, AST_STATE_DOWN); 03082 if (!tmpc) { 03083 ast_log(LOG_WARNING, "Unable to make channel for '%s'\n", tmp); 03084 } 03085 restart_monitor(); 03086 return tmpc; 03087 }
|
|
Definition at line 2062 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(). 02063 { 02064 /* Retrieve audio/etc from channel. Assumes sub->lock is already held. */ 02065 struct ast_frame *f; 02066 f = ast_rtp_read(sub->rtp); 02067 if (sub->owner) { 02068 /* We already hold the channel lock */ 02069 if (f->frametype == AST_FRAME_VOICE) { 02070 if (f->subclass != sub->owner->nativeformats) { 02071 ast_log(LOG_DEBUG, "Oooh, format changed to %d\n", f->subclass); 02072 sub->owner->nativeformats = f->subclass; 02073 ast_set_read_format(sub->owner, sub->owner->readformat); 02074 ast_set_write_format(sub->owner, sub->owner->writeformat); 02075 } 02076 } 02077 } 02078 return f; 02079 }
|
|
Definition at line 2131 of file chan_skinny.c. References skinny_line::parent, skinny_subchannel::parent, skinny_device::session, ast_channel::tech_pvt, and transmit_tone(). 02132 { 02133 #if 0 02134 struct skinny_subchannel *sub = ast->tech_pvt; 02135 int tmp; 02136 /* not right */ 02137 sprintf(tmp, "%d", digit); 02138 transmit_tone(sub->parent->parent->session, digit); 02139 #endif 02140 return -1; 02141 }
|
|
Definition at line 2917 of file chan_skinny.c. References ast_inet_ntoa(), ast_verbose(), destroy_session(), get_input(), handle_message(), s, skinny_req_parse(), and VERBOSE_PREFIX_3. Referenced by accept_thread(), and unload_module(). 02918 { 02919 int res; 02920 skinny_req *req; 02921 struct skinnysession *s = data; 02922 char iabuf[INET_ADDRSTRLEN]; 02923 02924 ast_verbose(VERBOSE_PREFIX_3 "Starting Skinny session from %s\n", ast_inet_ntoa(iabuf, sizeof(iabuf), s->sin.sin_addr)); 02925 for (;;) { 02926 res = 0; 02927 res = get_input(s); 02928 if (res < 0) { 02929 break; 02930 } 02931 req = skinny_req_parse(s); 02932 if (!req) { 02933 return NULL; 02934 } 02935 res = handle_message(req, s); 02936 if (res < 0) { 02937 destroy_session(s); 02938 return NULL; 02939 } 02940 } 02941 ast_log(LOG_NOTICE, "Skinny Session returned: %s\n", strerror(errno)); 02942 destroy_session(s); 02943 return 0; 02944 }
|
|
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 }
|
|
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 }
|
|
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 }
|
|
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_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, ast_callerid::cid_ani, skinny_line::cid_name, ast_callerid::cid_name, ast_callerid::cid_num, skinny_line::cid_num, ast_channel::context, skinny_line::dnd, ast_channel::exten, exten, free, 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, strdup, skinny_line::sub, ast_channel::tech_pvt, transmit_tone(), and VERBOSE_PREFIX_3. 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 if (!ast_strlen_zero(l->cid_num)) { 01745 if (!l->hidecallerid) { 01746 chan->cid.cid_num = strdup(l->cid_num); 01747 chan->cid.cid_ani = strdup(l->cid_num); 01748 } 01749 ast_setstate(chan, AST_STATE_RING); 01750 res = ast_pbx_run(chan); 01751 if (res) { 01752 ast_log(LOG_WARNING, "PBX exited non-zero\n"); 01753 transmit_tone(s, SKINNY_REORDER); 01754 } 01755 return NULL; 01756 } 01757 } 01758 } else { 01759 /* It's a match, but they just typed a digit, and there is an ambiguous match, 01760 so just set the timeout to matchdigittimeout and wait some more */ 01761 timeout = matchdigittimeout; 01762 } 01763 } else if (res == 0) { 01764 ast_log(LOG_DEBUG, "Not enough digits (and no ambiguous match)...\n"); 01765 transmit_tone(s, SKINNY_REORDER); 01766 ast_hangup(chan); 01767 return NULL; 01768 } else if (l->callwaiting && !strcmp(exten, "*70")) { 01769 if (option_verbose > 2) { 01770 ast_verbose(VERBOSE_PREFIX_3 "Disabling call waiting on %s\n", chan->name); 01771 } 01772 /* Disable call waiting if enabled */ 01773 l->callwaiting = 0; 01774 transmit_tone(s, SKINNY_DIALTONE); 01775 len = 0; 01776 memset(exten, 0, sizeof(exten));\ 01777 timeout = firstdigittimeout; 01778 } else if (!strcmp(exten,ast_pickup_ext())) { 01779 /* Scan all channels and see if any there 01780 * ringing channqels with that have call groups 01781 * that equal this channels pickup group 01782 */ 01783 if (ast_pickup_call(chan)) { 01784 ast_log(LOG_WARNING, "No call pickup possible...\n"); 01785 transmit_tone(s, SKINNY_REORDER); 01786 } 01787 ast_hangup(chan); 01788 return NULL; 01789 } else if (!l->hidecallerid && !strcmp(exten, "*67")) { 01790 if (option_verbose > 2) { 01791 ast_verbose(VERBOSE_PREFIX_3 "Disabling Caller*ID on %s\n", chan->name); 01792 } 01793 /* Disable Caller*ID if enabled */ 01794 l->hidecallerid = 1; 01795 if (chan->cid.cid_num) { 01796 free(chan->cid.cid_num); 01797 } 01798 chan->cid.cid_num = NULL; 01799 if (chan->cid.cid_name) { 01800 free(chan->cid.cid_name); 01801 } 01802 chan->cid.cid_name = NULL; 01803 transmit_tone(s, SKINNY_DIALTONE); 01804 len = 0; 01805 memset(exten, 0, sizeof(exten)); 01806 timeout = firstdigittimeout; 01807 } else if (l->callreturn && !strcmp(exten, "*69")) { 01808 res = 0; 01809 if (!ast_strlen_zero(l->lastcallerid)) { 01810 res = ast_say_digit_str(chan, l->lastcallerid, "", chan->language); 01811 } 01812 if (!res) { 01813 transmit_tone(s, SKINNY_DIALTONE); 01814 } 01815 break; 01816 } else if (!strcmp(exten, "*78")) { 01817 /* Do not disturb */ 01818 if (option_verbose > 2) { 01819 ast_verbose(VERBOSE_PREFIX_3 "Enabled DND on channel %s\n", chan->name); 01820 } 01821 transmit_tone(s, SKINNY_DIALTONE); 01822 l->dnd = 1; 01823 getforward = 0; 01824 memset(exten, 0, sizeof(exten)); 01825 len = 0; 01826 } else if (!strcmp(exten, "*79")) { 01827 /* Do not disturb */ 01828 if (option_verbose > 2) { 01829 ast_verbose(VERBOSE_PREFIX_3 "Disabled DND on channel %s\n", chan->name); 01830 } 01831 transmit_tone(s, SKINNY_DIALTONE); 01832 l->dnd = 0; 01833 getforward = 0; 01834 memset(exten, 0, sizeof(exten)); 01835 len = 0; 01836 } else if (l->cancallforward && !strcmp(exten, "*72")) { 01837 transmit_tone(s, SKINNY_DIALTONE); 01838 getforward = 1; 01839 memset(exten, 0, sizeof(exten)); 01840 len = 0; 01841 } else if (l->cancallforward && !strcmp(exten, "*73")) { 01842 if (option_verbose > 2) { 01843 ast_verbose(VERBOSE_PREFIX_3 "Cancelling call forwarding on channel %s\n", chan->name); 01844 } 01845 transmit_tone(s, SKINNY_DIALTONE); 01846 memset(l->call_forward, 0, sizeof(l->call_forward)); 01847 getforward = 0; 01848 memset(exten, 0, sizeof(exten)); 01849 len = 0; 01850 } else if (!strcmp(exten, ast_parking_ext()) && 01851 sub->next->owner && 01852 ast_bridged_channel(sub->next->owner)) { 01853 /* This is a three way call, the main call being a real channel, 01854 and we're parking the first call. */ 01855 ast_masq_park_call(ast_bridged_channel(sub->next->owner), chan, 0, NULL); 01856 if (option_verbose > 2) { 01857 ast_verbose(VERBOSE_PREFIX_3 "Parking call to '%s'\n", chan->name); 01858 } 01859 break; 01860 } else if (!ast_strlen_zero(l->lastcallerid) && !strcmp(exten, "*60")) { 01861 if (option_verbose > 2) { 01862 ast_verbose(VERBOSE_PREFIX_3 "Blacklisting number %s\n", l->lastcallerid); 01863 } 01864 res = ast_db_put("blacklist", l->lastcallerid, "1"); 01865 if (!res) { 01866 transmit_tone(s, SKINNY_DIALTONE); 01867 memset(exten, 0, sizeof(exten)); 01868 len = 0; 01869 } 01870 } else if (l->hidecallerid && !strcmp(exten, "*82")) { 01871 if (option_verbose > 2) { 01872 ast_verbose(VERBOSE_PREFIX_3 "Enabling Caller*ID on %s\n", chan->name); 01873 } 01874 /* Enable Caller*ID if enabled */ 01875 l->hidecallerid = 0; 01876 if (chan->cid.cid_num) { 01877 free(chan->cid.cid_num); 01878 } 01879 if (!ast_strlen_zero(l->cid_num)) { 01880 chan->cid.cid_num = strdup(l->cid_num); 01881 } 01882 if (chan->cid.cid_name) { 01883 free(chan->cid.cid_name); 01884 } 01885 if (!ast_strlen_zero(l->cid_name)) { 01886 chan->cid.cid_name = strdup(l->cid_name); 01887 } 01888 transmit_tone(s, SKINNY_DIALTONE); 01889 len = 0; 01890 memset(exten, 0, sizeof(exten)); 01891 timeout = firstdigittimeout; 01892 } else if (!ast_canmatch_extension(chan, chan->context, exten, 1, chan->cid.cid_num) && 01893 ((exten[0] != '*') || (!ast_strlen_zero(exten) > 2))) { 01894 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); 01895 transmit_tone(s, SKINNY_REORDER); 01896 /* hang out for 3 seconds to let congestion play */ 01897 ast_safe_sleep(chan, 3000); 01898 break; 01899 } 01900 if (!timeout) { 01901 timeout = gendigittimeout; 01902 } 01903 if (len && !ast_ignore_pattern(chan->context, exten)) { 01904 ast_indicate(chan, -1); 01905 } 01906 } 01907 ast_hangup(chan); 01908 return NULL; 01909 }
|
|
Definition at line 2091 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. 02092 { 02093 struct skinny_subchannel *sub = ast->tech_pvt; 02094 int res = 0; 02095 if (frame->frametype != AST_FRAME_VOICE) { 02096 if (frame->frametype == AST_FRAME_IMAGE) { 02097 return 0; 02098 } else { 02099 ast_log(LOG_WARNING, "Can't send %d type frames with skinny_write\n", frame->frametype); 02100 return 0; 02101 } 02102 } else { 02103 if (!(frame->subclass & ast->nativeformats)) { 02104 ast_log(LOG_WARNING, "Asked to transmit frame type %d, while native formats is %d (read/write = %d/%d)\n", 02105 frame->subclass, ast->nativeformats, ast->readformat, ast->writeformat); 02106 return -1; 02107 } 02108 } 02109 if (sub) { 02110 ast_mutex_lock(&sub->lock); 02111 if (sub->rtp) { 02112 res = ast_rtp_write(sub->rtp, frame); 02113 } 02114 ast_mutex_unlock(&sub->lock); 02115 } 02116 return res; 02117 }
|
|
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 }
|
|
|
|
|
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 }
|
|
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(), 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 }
|
|
|
|
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 }
|
|
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 }
|
|
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 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 }
|
|
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 }
|
|
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 }
|
|
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 3313 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, oh323_pvt::next, s, skinny_rtp, skinny_session(), and skinny_tech. 03314 { 03315 #if 0 03316 struct skinny_session *session, s; 03317 struct skinny_subchannel *sub; 03318 struct skinny_line *line = session; 03319 03320 /* close all IP connections */ 03321 if (!ast_mutex_lock(&devicelock)) { 03322 /* Terminate tcp listener thread */ 03323 } else { 03324 ast_log(LOG_WARNING, "Unable to lock the monitor\n"); 03325 return -1; 03326 } 03327 if (!ast_mutex_lock(&monlock)) { 03328 if (monitor_thread && (monitor_thread != AST_PTHREADT_STOP)) { 03329 pthread_cancel(monitor_thread); 03330 pthread_kill(monitor_thread, SIGURG); 03331 pthread_join(monitor_thread, NULL); 03332 } 03333 monitor_thread = AST_PTHREADT_STOP; 03334 ast_mutex_unlock(&monlock); 03335 } else { 03336 ast_log(LOG_WARNING, "Unable to lock the monitor\n"); 03337 return -1; 03338 } 03339 if (!ast_mutex_lock(&iflock)) { 03340 /* Destroy all the interfaces and free their memory */ 03341 p = iflist; 03342 while(p) { 03343 pl = p; 03344 p = p->next; 03345 /* Free associated memory */ 03346 ast_mutex_destroy(&pl->lock); 03347 free(pl); 03348 } 03349 iflist = NULL; 03350 ast_mutex_unlock(&iflock); 03351 } else { 03352 ast_log(LOG_WARNING, "Unable to lock the monitor\n"); 03353 return -1; 03354 } 03355 03356 ast_rtp_proto_register(&skinny_rtp); 03357 ast_channel_unregister(&skinny_tech); 03358 ast_cli_register(&cli_show_devices); 03359 ast_cli_register(&cli_show_lines); 03360 ast_cli_register(&cli_debug); 03361 ast_cli_register(&cli_no_debug); 03362 03363 return 0; 03364 #endif 03365 return -1; 03366 }
|
|
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 3368 of file chan_skinny.c. 03369 { 03370 return usecnt; 03371 }
|
|
Definition at line 682 of file chan_skinny.c. |
|
Definition at line 686 of file chan_skinny.c. |
|
Definition at line 705 of file chan_skinny.c. |
|
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(), rtp_do_debug_ip(), set_destination(), sip_devicestate(), and sip_do_debug_ip(). |
|
Definition at line 707 of file chan_skinny.c. |
|
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. |
|
Definition at line 452 of file chan_skinny.c. |
|
Definition at line 460 of file chan_skinny.c. Referenced by handle_message(). |
|
Definition at line 708 of file chan_skinny.c. |
|
Definition at line 698 of file chan_skinny.c. |
|
Definition at line 697 of file chan_skinny.c. |
|
Definition at line 703 of file chan_skinny.c. |
|
Definition at line 81 of file chan_skinny.c. |
|
Definition at line 691 of file chan_skinny.c. |
|
Definition at line 690 of file chan_skinny.c. |
|
Initial value: { { "skinny", "debug", NULL }, skinny_do_debug, "Enable Skinny debugging", debug_usage } Definition at line 1469 of file chan_skinny.c. |
|
Initial value: { { "skinny", "no", "debug", NULL }, skinny_no_debug, "Disable Skinny debugging", no_debug_usage } Definition at line 1472 of file chan_skinny.c. |
|
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 unload_module(). |
|
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 unload_module(). |
|
Definition at line 78 of file chan_skinny.c. |
|
Definition at line 687 of file chan_skinny.c. |
|
Definition at line 694 of file chan_skinny.c. |
|
Definition at line 695 of file chan_skinny.c. |
|
Definition at line 88 of file chan_skinny.c. |
|
Initial value: "Usage: skinny debug\n" " Enables dumping of Skinny packets for debugging purposes\n" Definition at line 1455 of file chan_skinny.c. |
|
Definition at line 75 of file chan_skinny.c. |
|
Referenced by delete_devices(), find_subchannel_by_name(), reload_config(), skinny_register(), skinny_show_devices(), and skinny_show_lines(). |
|
Definition at line 799 of file chan_skinny.c. |
|
Definition at line 802 of file chan_skinny.c. |
|
|
Definition at line 696 of file chan_skinny.c. |
|
Definition at line 774 of file chan_skinny.c. |
|
Definition at line 87 of file chan_skinny.c. |
|
Definition at line 688 of file chan_skinny.c. |
|
Definition at line 692 of file chan_skinny.c. |
|
Definition at line 706 of file chan_skinny.c. |
|
Definition at line 805 of file chan_skinny.c. |
|
Definition at line 796 of file chan_skinny.c. |
|
Definition at line 689 of file chan_skinny.c. |
|
Definition at line 700 of file chan_skinny.c. |
|
Definition at line 693 of file chan_skinny.c. |
|
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. |
|
Definition at line 680 of file chan_skinny.c. |
|
Definition at line 681 of file chan_skinny.c. |
|
Definition at line 773 of file chan_skinny.c. |
|
|
|
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. |
|
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. |
|
Definition at line 1357 of file chan_skinny.c. Referenced by unload_module(). |
|
Definition at line 910 of file chan_skinny.c. Referenced by skinny_new(), and unload_module(). |
|
Definition at line 676 of file chan_skinny.c. |
|
Definition at line 684 of file chan_skinny.c. |
|
Definition at line 540 of file chan_skinny.c. |
|
Definition at line 511 of file chan_skinny.c. |
|
Definition at line 685 of file chan_skinny.c. |
|
Definition at line 76 of file chan_skinny.c. |
|
Definition at line 699 of file chan_skinny.c. |
|
Definition at line 702 of file chan_skinny.c. |
|
Definition at line 77 of file chan_skinny.c. |
|
Definition at line 777 of file chan_skinny.c. |
|
Definition at line 89 of file chan_skinny.c. |