#include "asterisk/indications.h"
#include "asterisk/linkedlists.h"
+/*** DOCUMENTATION
+ <manager name="SKINNYdevices" language="en_US">
+ <synopsis>
+ List SKINNY devices (text format).
+ </synopsis>
+ <syntax>
+ <xi:include xpointer="xpointer(/docs/manager[@name='Login']/syntax/parameter[@name='ActionID'])" />
+ </syntax>
+ <description>
+ <para>Lists Skinny devices in text format with details on current status.
+ Devicelist will follow as separate events, followed by a final event called
+ DevicelistComplete.</para>
+ </description>
+ </manager>
+ <manager name="SKINNYshowdevice" language="en_US">
+ <synopsis>
+ Show SKINNY device (text format).
+ </synopsis>
+ <syntax>
+ <xi:include xpointer="xpointer(/docs/manager[@name='Login']/syntax/parameter[@name='ActionID'])" />
+ <parameter name="Device" required="true">
+ <para>The device name you want to check.</para>
+ </parameter>
+ </syntax>
+ <description>
+ <para>Show one SKINNY device with details on current status.</para>
+ </description>
+ </manager>
+ <manager name="SKINNYlines" language="en_US">
+ <synopsis>
+ List SKINNY lines (text format).
+ </synopsis>
+ <syntax>
+ <xi:include xpointer="xpointer(/docs/manager[@name='Login']/syntax/parameter[@name='ActionID'])" />
+ </syntax>
+ <description>
+ <para>Lists Skinny lines in text format with details on current status.
+ Linelist will follow as separate events, followed by a final event called
+ LinelistComplete.</para>
+ </description>
+ </manager>
+ <manager name="SKINNYshowline" language="en_US">
+ <synopsis>
+ Show SKINNY line (text format).
+ </synopsis>
+ <syntax>
+ <xi:include xpointer="xpointer(/docs/manager[@name='Login']/syntax/parameter[@name='ActionID'])" />
+ <parameter name="Line" required="true">
+ <para>The line name you want to check.</para>
+ </parameter>
+ </syntax>
+ <description>
+ <para>Show one SKINNY line with details on current status.</para>
+ </description>
+ </manager>
+ ***/
+
#ifdef SKINNY_DEVMODE
#define SKINNY_DEVONLY(code) \
code
static const char tdesc[] = "Skinny Client Control Protocol (Skinny)";
static const char config[] = "skinny.conf";
-static int default_capability = AST_FORMAT_ULAW | AST_FORMAT_ALAW;
+static format_t default_capability = AST_FORMAT_ULAW | AST_FORMAT_ALAW;
static struct ast_codec_pref default_prefs;
enum skinny_codecs {
#define SOFTKEY_DND 0x13
#define SOFTKEY_IDIVERT 0x14
-struct soft_key_template_definition soft_key_template_default[] = {
+static struct soft_key_template_definition soft_key_template_default[] = {
{ "\200\001", SOFTKEY_REDIAL },
{ "\200\002", SOFTKEY_NEWCALL },
{ "\200\003", SOFTKEY_HOLD },
/* XXX This is the combined size of the variables above. (len, res, e)
If more are added, this MUST change.
(sizeof(skinny_req) - sizeof(skinny_data)) DOES NOT WORK on all systems (amd64?). */
-int skinny_header_size = 12;
+static int skinny_header_size = 12;
/*****************************
* Asterisk specific globals *
static char ourhost[256];
static int ourport;
static struct in_addr __ourip;
-struct ast_hostent ahp;
-struct hostent *hp;
+static struct ast_hostent ahp;
+static struct hostent *hp;
static int skinnysock = -1;
static pthread_t accept_t;
static int callnums = 1;
int instance; \
int group; \
int needdestroy; \
- int confcapability; \
+ format_t confcapability; \
struct ast_codec_pref confprefs; \
- int capability; \
+ format_t capability; \
struct ast_codec_pref prefs; \
int nonCodecCapability; \
int onhooktime; \
int immediate; \
int hookstate; \
int nat; \
- int canreinvite; \
+ int directmedia; \
int prune;
struct skinny_line {
int newmsgs;
};
-struct skinny_line_options{
+static struct skinny_line_options{
SKINNY_LINE_OPTIONS
} default_line_struct = {
.callwaiting = 1,
.hidecallerid = 0,
.amaflags = 0,
.instance = 0,
- .canreinvite = 0,
+ .directmedia = 0,
.nat = 0,
.confcapability = AST_FORMAT_ULAW | AST_FORMAT_ALAW,
.capability = 0,
.prune = 0,
.hookstate = SKINNY_ONHOOK,
};
-struct skinny_line_options *default_line = &default_line_struct;
+static struct skinny_line_options *default_line = &default_line_struct;
static AST_LIST_HEAD_STATIC(lines, skinny_line);
int registered; \
int lastlineinstance; \
int lastcallreference; \
- int confcapability; \
+ format_t confcapability; \
struct ast_codec_pref confprefs; \
- int capability; \
+ format_t capability; \
int earlyrtp; \
int transfer; \
int callwaiting; \
AST_LIST_ENTRY(skinny_device) list;
};
-struct skinny_device_options{
+static struct skinny_device_options {
SKINNY_DEVICE_OPTIONS
} default_device_struct = {
.transfer = 1,
.capability = 0,
.prune = 0,
};
-struct skinny_device_options *default_device = &default_device_struct;
+static struct skinny_device_options *default_device = &default_device_struct;
static AST_LIST_HEAD_STATIC(devices, skinny_device);
AST_LIST_ENTRY(skinnysession) list;
};
+static struct ast_channel *skinny_request(const char *type, format_t format, const struct ast_channel *requestor, void *data, int *cause);
static AST_LIST_HEAD_STATIC(sessions, skinnysession);
-static struct ast_channel *skinny_request(const char *type, int format, void *data, int *cause);
static int skinny_devicestate(void *data);
static int skinny_call(struct ast_channel *ast, char *dest, int timeout);
static int skinny_hangup(struct ast_channel *ast);
return sd;
}
-static int codec_skinny2ast(enum skinny_codecs skinnycodec)
+static format_t codec_skinny2ast(enum skinny_codecs skinnycodec)
{
switch (skinnycodec) {
case SKINNY_CODEC_ALAW:
}
}
-static int codec_ast2skinny(int astcodec)
+static int codec_ast2skinny(format_t astcodec)
{
switch (astcodec) {
case AST_FORMAT_ALAW:
AST_LIST_TRAVERSE(&d->lines, l, list) {
/* FIXME: All sorts of issues will occur if this line is already connected to a device */
if (l->device) {
+ manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", "ChannelType: Skinny\r\nPeer: Skinny/%s@%s\r\nPeerStatus: Rejected\r\nCause: LINE_ALREADY_CONNECTED\r\n", l->name, l->device->name);
ast_verb(1, "Line %s already connected to %s. Not connecting to %s.\n", l->name, l->device->name, d->name);
} else {
l->device = d;
l->instance = instance;
l->newmsgs = ast_app_has_voicemail(l->mailbox, NULL);
set_callforwards(l, NULL, 0);
+ manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", "ChannelType: Skinny\r\nPeer: Skinny/%s@%s\r\nPeerStatus: Registered\r\n", l->name, d->name);
register_exten(l);
/* initialize MWI on line and device */
mwi_event_cb(0, l);
l->capability = 0;
ast_parse_allow_disallow(&l->prefs, &l->capability, "all", 0);
l->instance = 0;
+ manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", "ChannelType: Skinny\r\nPeer: Skinny/%s@%s\r\nPeerStatus: Unregistered\r\n", l->name, d->name);
unregister_exten(l);
ast_devstate_changed(AST_DEVICE_UNAVAILABLE, "Skinny/%s@%s", l->name, d->name);
}
l = sub->parent;
- if (!l->canreinvite || l->nat){
+ if (!l->directmedia || l->nat){
res = AST_RTP_GLUE_RESULT_LOCAL;
if (skinnydebug)
ast_verb(1, "skinny_get_rtp_peer() Using AST_RTP_GLUE_RESULT_LOCAL \n");
}
-static int skinny_set_rtp_peer(struct ast_channel *c, struct ast_rtp_instance *rtp, struct ast_rtp_instance *vrtp, struct ast_rtp_instance *trtp, int codecs, int nat_active)
+static int skinny_set_rtp_peer(struct ast_channel *c, struct ast_rtp_instance *rtp, struct ast_rtp_instance *vrtp, struct ast_rtp_instance *trtp, format_t codecs, int nat_active)
{
struct skinny_subchannel *sub;
struct skinny_line *l;
fmt = ast_codec_pref_getsize(&l->prefs, ast_best_codec(l->capability));
if (skinnydebug)
- ast_verb(1, "Setting payloadType to '%d' (%d ms)\n", fmt.bits, fmt.cur_ms);
+ ast_verb(1, "Setting payloadType to '%s' (%d ms)\n", ast_getformatname(fmt.bits), fmt.cur_ms);
req->data.startmedia.conferenceId = htolel(sub->callid);
req->data.startmedia.passThruPartyId = htolel(sub->callid);
- if (!(l->canreinvite) || (l->nat)){
+ if (!(l->directmedia) || (l->nat)){
ast_rtp_instance_get_local_address(rtp, &us);
req->data.startmedia.remoteIp = htolel(d->ourip.s_addr);
req->data.startmedia.remotePort = htolel(ntohs(us.sin_port));
return CLI_SUCCESS;
}
-static const char mandescr_show_devices[] =
-"Description: Lists Skinny devices in text format with details on current status.\n"
-"Devicelist will follow as separate events, followed by a final event called\n"
-"DevicelistComplete.\n"
-"Variables: \n"
-" ActionID: <id> Action ID for this transaction. Will be returned.\n";
-
/*! \brief Show SKINNY devices in the manager API */
/* Inspired from chan_sip */
static int manager_skinny_show_devices(struct mansession *s, const struct message *m)
return CLI_SUCCESS;
}
-static const char mandescr_show_device[] =
-"Description: Show one SKINNY device with details on current status.\n"
-"Variables: \n"
-" Device: <name> The device name you want to check.\n"
-" ActionID: <id> Optional action ID for this AMI transaction.\n";
-
static int manager_skinny_show_device(struct mansession *s, const struct message *m)
{
const char *a[4];
return CLI_SUCCESS;
}
-static const char mandescr_show_lines[] =
-"Description: Lists Skinny lines in text format with details on current status.\n"
-"Linelist will follow as separate events, followed by a final event called\n"
-"LinelistComplete.\n"
-"Variables: \n"
-" ActionID: <id> Action ID for this transaction. Will be returned.\n";
-
/*! \brief Show Skinny lines in the manager API */
/* Inspired from chan_sip */
static int manager_skinny_show_lines(struct mansession *s, const struct message *m)
ast_cli(fd, "NAT: %s\n", (l->nat ? "Yes" : "No"));
ast_cli(fd, "immediate: %s\n", (l->immediate ? "Yes" : "No"));
ast_cli(fd, "Group: %d\n", l->group);
+ ast_cli(fd, "Parkinglot: %s\n", S_OR(l->parkinglot, "<not set>"));
ast_cli(fd, "Conf Codecs: ");
ast_getformatname_multiple(codec_buf, sizeof(codec_buf) - 1, l->confcapability);
ast_cli(fd, "%s\n", codec_buf);
astman_append(s, "NAT: %s\r\n", (l->nat ? "Yes" : "No"));
astman_append(s, "immediate: %s\r\n", (l->immediate ? "Yes" : "No"));
astman_append(s, "Group: %d\r\n", l->group);
+ astman_append(s, "Parkinglot: %s\r\n", S_OR(l->parkinglot, "<not set>"));
ast_getformatname_multiple(codec_buf, sizeof(codec_buf) - 1, l->confcapability);
astman_append(s, "Codecs: %s\r\n", codec_buf);
astman_append(s, "CodecOrder: ");
return CLI_SUCCESS;
}
-static const char mandescr_show_line[] =
-"Description: Show one SKINNY line with details on current status.\n"
-"Variables: \n"
-" Line: <name> The line name you want to check.\n"
-" ActionID: <id> Optional action ID for this AMI transaction.\n";
-
static int manager_skinny_show_line(struct mansession *s, const struct message *m)
{
const char *a[4];
ast_mutex_lock(&sub->lock);
/* Allocate the RTP */
- sub->rtp = ast_rtp_instance_new(NULL, sched, &bindaddr, NULL);
+ sub->rtp = ast_rtp_instance_new("asterisk", sched, &bindaddr, NULL);
if (hasvideo)
- sub->vrtp = ast_rtp_instance_new(NULL, sched, &bindaddr, NULL);
+ sub->vrtp = ast_rtp_instance_new("asterisk", sched, &bindaddr, NULL);
if (sub->rtp) {
ast_rtp_instance_set_prop(sub->rtp, AST_RTP_PROPERTY_RTCP, 1);
if (ast) {
/* We already hold the channel lock */
if (f->frametype == AST_FRAME_VOICE) {
- if (f->subclass != ast->nativeformats) {
- ast_debug(1, "Oooh, format changed to %d\n", f->subclass);
- ast->nativeformats = f->subclass;
+ if (f->subclass.codec != ast->nativeformats) {
+ ast_debug(1, "Oooh, format changed to %s\n", ast_getformatname(f->subclass.codec));
+ ast->nativeformats = f->subclass.codec;
ast_set_read_format(ast, ast->readformat);
ast_set_write_format(ast, ast->writeformat);
}
return 0;
}
} else {
- if (!(frame->subclass & ast->nativeformats)) {
- ast_log(LOG_WARNING, "Asked to transmit frame type %d, while native formats is %d (read/write = %d/%d)\n",
- frame->subclass, ast->nativeformats, ast->readformat, ast->writeformat);
+ if (!(frame->subclass.codec & ast->nativeformats)) {
+ char buf[256];
+ ast_log(LOG_WARNING, "Asked to transmit frame type %s, while native formats is %s (read/write = %s/%s)\n",
+ ast_getformatname(frame->subclass.codec),
+ ast_getformatname_multiple(buf, sizeof(buf), ast->nativeformats),
+ ast_getformatname(ast->readformat),
+ ast_getformatname(ast->writeformat));
return -1;
}
}
return 0;
}
-static struct ast_channel *skinny_new(struct skinny_line *l, int state)
+static struct ast_channel *skinny_new(struct skinny_line *l, int state, const char *linkedid)
{
struct ast_channel *tmp;
struct skinny_subchannel *sub;
return NULL;
}
- tmp = ast_channel_alloc(1, state, l->cid_num, l->cid_name, l->accountcode, l->exten, l->context, l->amaflags, "Skinny/%s@%s-%d", l->name, d->name, callnums);
+ tmp = ast_channel_alloc(1, state, l->cid_num, l->cid_name, l->accountcode, l->exten, l->context, linkedid, l->amaflags, "Skinny/%s@%s-%d", l->name, d->name, callnums);
if (!tmp) {
ast_log(LOG_WARNING, "Unable to allocate channel structure\n");
return NULL;
// Should throw an error
tmp->nativeformats = default_capability;
fmt = ast_best_codec(tmp->nativeformats);
- if (skinnydebug)
- ast_verb(1, "skinny_new: tmp->nativeformats=%d fmt=%d\n", tmp->nativeformats, fmt);
+ if (skinnydebug) {
+ char buf[256];
+ ast_verb(1, "skinny_new: tmp->nativeformats=%s fmt=%s\n",
+ ast_getformatname_multiple(buf, sizeof(buf), tmp->nativeformats),
+ ast_getformatname(fmt));
+ }
if (sub->rtp) {
ast_channel_set_fd(tmp, 0, ast_rtp_instance_fd(sub->rtp, 0));
}
ast_string_field_set(tmp, language, l->language);
if (!ast_strlen_zero(l->accountcode))
ast_string_field_set(tmp, accountcode, l->accountcode);
+ if (!ast_strlen_zero(l->parkinglot))
+ ast_string_field_set(tmp, parkinglot, l->parkinglot);
if (l->amaflags)
tmp->amaflags = l->amaflags;
if (!sub->onhold) {
skinny_hold(sub);
}
- c = skinny_new(l, AST_STATE_DOWN);
+ c = skinny_new(l, AST_STATE_DOWN, NULL);
if (c) {
newsub = c->tech_pvt;
/* point the sub and newsub at each other so we know they are related */
ast_log(LOG_WARNING, "Unsupported digit %d\n", digit);
}
- f.subclass = dgt;
+ f.subclass.integer = dgt;
f.src = "skinny";
break;
}
- c = skinny_new(l, AST_STATE_DOWN);
+ c = skinny_new(l, AST_STATE_DOWN, NULL);
if (!c) {
ast_log(LOG_WARNING, "Unable to create channel for %s@%s\n", l->name, d->name);
} else {
}
if (!sub || !sub->owner)
- c = skinny_new(l, AST_STATE_DOWN);
+ c = skinny_new(l, AST_STATE_DOWN, NULL);
else
c = sub->owner;
ast_verb(1, "Received Stimulus: Voicemail(%d/%d)\n", instance, callreference);
if (!sub || !sub->owner) {
- c = skinny_new(l, AST_STATE_DOWN);
+ c = skinny_new(l, AST_STATE_DOWN, NULL);
} else {
c = sub->owner;
}
ast_verb(1, "Received Stimulus: Forward All(%d/%d)\n", instance, callreference);
if (!sub || !sub->owner) {
- c = skinny_new(l, AST_STATE_DOWN);
+ c = skinny_new(l, AST_STATE_DOWN, NULL);
} else {
c = sub->owner;
}
ast_verb(1, "Received Stimulus: Forward Busy (%d/%d)\n", instance, callreference);
if (!sub || !sub->owner) {
- c = skinny_new(l, AST_STATE_DOWN);
+ c = skinny_new(l, AST_STATE_DOWN, NULL);
} else {
c = sub->owner;
}
#if 0 /* Not sure how to handle this yet */
if (!sub || !sub->owner) {
- c = skinny_new(l, AST_STATE_DOWN);
+ c = skinny_new(l, AST_STATE_DOWN, NULL);
} else {
c = sub->owner;
}
if (sub && sub->owner) {
ast_debug(1, "Current subchannel [%s] already has owner\n", sub->owner->name);
} else {
- c = skinny_new(l, AST_STATE_DOWN);
+ c = skinny_new(l, AST_STATE_DOWN, NULL);
if (c) {
sub = c->tech_pvt;
l->activesub = sub;
if (sub && sub->owner) {
ast_debug(1, "Current sub [%s] already has owner\n", sub->owner->name);
} else {
- c = skinny_new(l, AST_STATE_DOWN);
+ c = skinny_new(l, AST_STATE_DOWN, NULL);
if (c) {
sub = c->tech_pvt;
l->activesub = sub;
struct skinny_device *d = s->device;
struct skinny_line *l;
uint32_t count = 0;
- int codecs = 0;
+ format_t codecs = 0;
int i;
+ char buf[256];
count = letohl(req->data.caps.count);
if (count > SKINNY_MAX_CAPABILITIES) {
}
for (i = 0; i < count; i++) {
- int acodec = 0;
+ format_t acodec = 0;
int scodec = 0;
scodec = letohl(req->data.caps.caps[i].codec);
acodec = codec_skinny2ast(scodec);
if (skinnydebug)
- ast_verb(1, "Adding codec capability '%d (%d)'\n", acodec, scodec);
+ ast_verb(1, "Adding codec capability '%" PRId64 " (%d)'\n", acodec, scodec);
codecs |= acodec;
}
d->capability = d->confcapability & codecs;
- ast_verb(0, "Device capability set to '%d'\n", d->capability);
+ ast_verb(0, "Device capability set to '%s'\n", ast_getformatname_multiple(buf, sizeof(buf), d->capability));
AST_LIST_TRAVERSE(&d->lines, l, list) {
ast_mutex_lock(&l->lock);
l->capability = l->confcapability & d->capability;
fmt = ast_codec_pref_getsize(&l->prefs, ast_best_codec(l->capability));
if (skinnydebug)
- ast_verb(1, "Setting payloadType to '%d' (%d ms)\n", fmt.bits, fmt.cur_ms);
+ ast_verb(1, "Setting payloadType to '%s' (%d ms)\n", ast_getformatname(fmt.bits), fmt.cur_ms);
req->data.startmedia.conferenceId = htolel(sub->callid);
req->data.startmedia.passThruPartyId = htolel(sub->callid);
l = sub->parent;
}
- c = skinny_new(l, AST_STATE_DOWN);
+ c = skinny_new(l, AST_STATE_DOWN, NULL);
if(!c) {
ast_log(LOG_WARNING, "Unable to create channel for %s@%s\n", l->name, d->name);
}
if (!sub || !sub->owner) {
- c = skinny_new(l, AST_STATE_DOWN);
+ c = skinny_new(l, AST_STATE_DOWN, NULL);
} else {
c = sub->owner;
}
ast_verb(1, "Received Softkey Event: New Call(%d/%d)\n", instance, callreference);
/* New Call ALWAYS gets a new sub-channel */
- c = skinny_new(l, AST_STATE_DOWN);
+ c = skinny_new(l, AST_STATE_DOWN, NULL);
sub = c->tech_pvt;
/* transmit_ringer_mode(d, SKINNY_RING_OFF);
ast_verb(1, "Received Softkey Event: Forward All(%d/%d)\n", instance, callreference);
if (!sub || !sub->owner) {
- c = skinny_new(l, AST_STATE_DOWN);
+ c = skinny_new(l, AST_STATE_DOWN, NULL);
} else {
c = sub->owner;
}
ast_verb(1, "Received Softkey Event: Forward Busy (%d/%d)\n", instance, callreference);
if (!sub || !sub->owner) {
- c = skinny_new(l, AST_STATE_DOWN);
+ c = skinny_new(l, AST_STATE_DOWN, NULL);
} else {
c = sub->owner;
}
#if 0 /* Not sure how to handle this yet */
if (!sub || !sub->owner) {
- c = skinny_new(l, AST_STATE_DOWN);
+ c = skinny_new(l, AST_STATE_DOWN, NULL);
} else {
c = sub->owner;
}
{
int res;
int dlen = 0;
+ int *bufaddr;
struct pollfd fds[1];
fds[0].fd = s->fd;
return -1;
}
- dlen = letohl(*(int *)s->inbuf);
+ bufaddr = (int *)s->inbuf;
+ dlen = letohl(*bufaddr);
if (dlen < 4) {
ast_debug(1, "Skinny Client sent invalid data.\n");
ast_mutex_unlock(&s->lock);
if (dlen+8 > sizeof(s->inbuf)) {
dlen = sizeof(s->inbuf) - 8;
}
- *(int *)s->inbuf = htolel(dlen);
+ *bufaddr = htolel(dlen);
res = read(s->fd, s->inbuf+4, dlen+4);
ast_mutex_unlock(&s->lock);
static struct skinny_req *skinny_req_parse(struct skinnysession *s)
{
struct skinny_req *req;
+ int *bufaddr;
if (!(req = ast_calloc(1, SKINNY_MAX_PACKET)))
return NULL;
ast_mutex_lock(&s->lock);
memcpy(req, s->inbuf, skinny_header_size);
- memcpy(&req->data, s->inbuf+skinny_header_size, letohl(*(int*)(s->inbuf))-4);
+ bufaddr = (int *)(s->inbuf);
+ memcpy(&req->data, s->inbuf+skinny_header_size, letohl(*bufaddr)-4);
ast_mutex_unlock(&s->lock);
return get_devicestate(l);
}
-static struct ast_channel *skinny_request(const char *type, int format, void *data, int *cause)
+static struct ast_channel *skinny_request(const char *type, format_t format, const struct ast_channel *requestor, void *data, int *cause)
{
- int oldformat;
+ format_t oldformat;
struct skinny_line *l;
struct ast_channel *tmpc = NULL;
oldformat = format;
if (!(format &= AST_FORMAT_AUDIO_MASK)) {
- ast_log(LOG_NOTICE, "Asked to get a channel of unsupported format '%d'\n", format);
+ ast_log(LOG_NOTICE, "Asked to get a channel of unsupported format '%s'\n", ast_getformatname_multiple(tmp, sizeof(tmp), format));
return NULL;
}
return NULL;
}
ast_verb(3, "skinny_request(%s)\n", tmp);
- tmpc = skinny_new(l, AST_STATE_DOWN);
+ tmpc = skinny_new(l, AST_STATE_DOWN, requestor ? requestor->linkedid : NULL);
if (!tmpc) {
ast_log(LOG_WARNING, "Unable to make channel for '%s'\n", tmp);
}
ast_log(LOG_WARNING, "Invalid cos_video value at line %d, refer to QoS documentation\n", v->lineno);
continue;
} else if (!strcasecmp(v->name, "bindport")) {
- if (sscanf(v->value, "%d", &ourport) == 1) {
+ if (sscanf(v->value, "%5d", &ourport) == 1) {
bindaddr.sin_port = htons(ourport);
} else {
ast_log(LOG_WARNING, "Invalid bindport '%s' at line %d of %s\n", v->value, v->lineno, config);
CLINE_OPTS->callwaiting = ast_true(v->value);
continue;
}
- } else if (!strcasecmp(v->name, "canreinvite")) {
+ } else if (!strcasecmp(v->name, "directmedia") || !strcasecmp(v->name, "canreinvite")) {
if (type & (TYPE_DEF_LINE | TYPE_LINE)) {
- CLINE_OPTS->canreinvite = ast_true(v->value);
+ CLINE_OPTS->directmedia = ast_true(v->value);
continue;
}
} else if (!strcasecmp(v->name, "nat")) {
strsep(&cfg_context, "@");
if (ast_strlen_zero(cfg_context))
cfg_context = "default";
- l->mwi_event_sub = ast_event_subscribe(AST_EVENT_MWI, mwi_event_cb, l,
+ l->mwi_event_sub = ast_event_subscribe(AST_EVENT_MWI, mwi_event_cb, "skinny MWI subsciption", l,
AST_EVENT_IE_MAILBOX, AST_EVENT_IE_PLTYPE_STR, cfg_mailbox,
AST_EVENT_IE_CONTEXT, AST_EVENT_IE_PLTYPE_STR, cfg_context,
AST_EVENT_IE_NEWMSGS, AST_EVENT_IE_PLTYPE_EXISTS,
/* load the general section */
cat = ast_category_browse(cfg, "general");
config_parse_variables(TYPE_GENERAL, NULL, ast_variable_browse(cfg, "general"));
-
+
if (ntohl(bindaddr.sin_addr.s_addr)) {
__ourip = bindaddr.sin_addr;
} else {
ast_rtp_glue_register(&skinny_rtp_glue);
ast_cli_register_multiple(cli_skinny, ARRAY_LEN(cli_skinny));
- ast_manager_register2("SKINNYdevices", EVENT_FLAG_SYSTEM | EVENT_FLAG_REPORTING, manager_skinny_show_devices,
- "List SKINNY devices (text format)", mandescr_show_devices);
- ast_manager_register2("SKINNYshowdevice", EVENT_FLAG_SYSTEM | EVENT_FLAG_REPORTING, manager_skinny_show_device,
- "Show SKINNY device (text format)", mandescr_show_device);
- ast_manager_register2("SKINNYlines", EVENT_FLAG_SYSTEM | EVENT_FLAG_REPORTING, manager_skinny_show_lines,
- "List SKINNY lines (text format)", mandescr_show_lines);
- ast_manager_register2("SKINNYshowline", EVENT_FLAG_SYSTEM | EVENT_FLAG_REPORTING, manager_skinny_show_line,
- "Show SKINNY line (text format)", mandescr_show_line);
+ ast_manager_register_xml("SKINNYdevices", EVENT_FLAG_SYSTEM | EVENT_FLAG_REPORTING, manager_skinny_show_devices);
+ ast_manager_register_xml("SKINNYshowdevice", EVENT_FLAG_SYSTEM | EVENT_FLAG_REPORTING, manager_skinny_show_device);
+ ast_manager_register_xml("SKINNYlines", EVENT_FLAG_SYSTEM | EVENT_FLAG_REPORTING, manager_skinny_show_lines);
+ ast_manager_register_xml("SKINNYshowline", EVENT_FLAG_SYSTEM | EVENT_FLAG_REPORTING, manager_skinny_show_line);
sched = sched_context_create();
if (!sched) {
if (l->mwi_event_sub)
ast_event_unsubscribe(l->mwi_event_sub);
ast_mutex_unlock(&l->lock);
+ manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", "ChannelType: Skinny\r\nPeer: Skinny/%s@%s\r\nPeerStatus: Unregistered\r\n", l->name, d->name);
unregister_exten(l);
}
if (s->fd > -1)