More 32->64 bit codec conversions.
[asterisk/asterisk.git] / channels / chan_skinny.c
index 0aea73b..79eb2fb 100644 (file)
@@ -141,7 +141,7 @@ ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
 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 {
@@ -642,7 +642,7 @@ struct soft_key_template_definition {
 #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 },
@@ -1020,7 +1020,7 @@ struct skinny_req {
 /* 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 *
@@ -1034,8 +1034,8 @@ static struct sockaddr_in bindaddr;
 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;
@@ -1229,9 +1229,9 @@ struct skinny_subchannel {
        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;                                 \
@@ -1239,7 +1239,7 @@ struct skinny_subchannel {
        int immediate;                                  \
        int hookstate;                                  \
        int nat;                                        \
-       int canreinvite;                                \
+       int directmedia;                                \
        int prune;
 
 struct skinny_line {
@@ -1255,7 +1255,7 @@ struct skinny_line {
        int newmsgs;
 };
 
-struct skinny_line_options{
+static struct skinny_line_options{
        SKINNY_LINE_OPTIONS
 } default_line_struct = {
        .callwaiting = 1,
@@ -1265,7 +1265,7 @@ struct skinny_line_options{
        .hidecallerid = 0,
        .amaflags = 0,
        .instance = 0,
-       .canreinvite = 0,
+       .directmedia = 0,
        .nat = 0,
        .confcapability = AST_FORMAT_ULAW | AST_FORMAT_ALAW,
        .capability = 0,
@@ -1274,7 +1274,7 @@ struct skinny_line_options{
        .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);
 
@@ -1309,9 +1309,9 @@ struct skinny_addon {
        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;                                        \
@@ -1335,7 +1335,7 @@ struct skinny_device {
        AST_LIST_ENTRY(skinny_device) list;
 };
 
-struct skinny_device_options{
+static struct skinny_device_options {
        SKINNY_DEVICE_OPTIONS
 } default_device_struct = {
        .transfer = 1,
@@ -1347,7 +1347,7 @@ struct skinny_device_options{
        .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);
 
@@ -1371,9 +1371,9 @@ struct skinnysession {
        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);
@@ -1715,7 +1715,7 @@ static struct skinny_speeddial *find_speeddial_by_instance(struct skinny_device
        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:
@@ -1737,7 +1737,7 @@ static int codec_skinny2ast(enum skinny_codecs skinnycodec)
        }
 }
 
-static int codec_ast2skinny(int astcodec)
+static int codec_ast2skinny(format_t astcodec)
 {
        switch (astcodec) {
        case AST_FORMAT_ALAW:
@@ -1904,6 +1904,7 @@ static int skinny_register(struct skinny_req *req, struct skinnysession *s)
                        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;
@@ -1917,6 +1918,7 @@ static int skinny_register(struct skinny_req *req, struct skinnysession *s)
                                        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);
@@ -1956,6 +1958,7 @@ static int skinny_unregister(struct skinny_req *req, struct skinnysession *s)
                                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);
                        }
@@ -2689,7 +2692,7 @@ static enum ast_rtp_glue_result skinny_get_rtp_peer(struct ast_channel *c, struc
 
        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");
@@ -2701,7 +2704,7 @@ static enum ast_rtp_glue_result skinny_get_rtp_peer(struct ast_channel *c, struc
 
 }
 
-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;
@@ -2745,11 +2748,11 @@ static int skinny_set_rtp_peer(struct ast_channel *c, struct ast_rtp_instance *r
                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));
@@ -3473,6 +3476,7 @@ static char *_skinny_show_line(int type, int fd, struct mansession *s, const str
                                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);
@@ -3518,6 +3522,7 @@ static char *_skinny_show_line(int type, int fd, struct mansession *s, const str
                                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: ");
@@ -3629,9 +3634,9 @@ static void start_rtp(struct skinny_subchannel *sub)
 
        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);
@@ -4016,9 +4021,9 @@ static struct ast_frame *skinny_rtp_read(struct skinny_subchannel *sub)
        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);
                        }
@@ -4049,9 +4054,13 @@ static int skinny_write(struct ast_channel *ast, struct ast_frame *frame)
                        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;
                }
        }
@@ -4348,7 +4357,7 @@ static int skinny_indicate(struct ast_channel *ast, int ind, const void *data, s
        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;
@@ -4361,7 +4370,7 @@ static struct ast_channel *skinny_new(struct skinny_line *l, int state)
                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;
@@ -4395,8 +4404,12 @@ static struct ast_channel *skinny_new(struct skinny_line *l, int state)
                        // 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));
                }
@@ -4411,6 +4424,8 @@ static struct ast_channel *skinny_new(struct skinny_line *l, int state)
                        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;
 
@@ -4544,7 +4559,7 @@ static int handle_transfer_button(struct skinny_subchannel *sub)
                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 */
@@ -4739,7 +4754,7 @@ static int handle_keypad_button_message(struct skinny_req *req, struct skinnyses
                ast_log(LOG_WARNING, "Unsupported digit %d\n", digit);
        }
 
-       f.subclass = dgt;
+       f.subclass.integer = dgt;
 
        f.src = "skinny";
 
@@ -4822,7 +4837,7 @@ static int handle_stimulus_message(struct skinny_req *req, struct skinnysession
                        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 {
@@ -4860,7 +4875,7 @@ static int handle_stimulus_message(struct skinny_req *req, struct skinnysession
                }
 
                if (!sub || !sub->owner)
-                       c = skinny_new(l, AST_STATE_DOWN);
+                       c = skinny_new(l, AST_STATE_DOWN, NULL);
                else
                        c = sub->owner;
 
@@ -4920,7 +4935,7 @@ static int handle_stimulus_message(struct skinny_req *req, struct skinnysession
                        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;
                }
@@ -5005,7 +5020,7 @@ static int handle_stimulus_message(struct skinny_req *req, struct skinnysession
                        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;
                }
@@ -5022,7 +5037,7 @@ static int handle_stimulus_message(struct skinny_req *req, struct skinnysession
                        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;
                }
@@ -5040,7 +5055,7 @@ static int handle_stimulus_message(struct skinny_req *req, struct skinnysession
 
 #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;
                }
@@ -5091,7 +5106,7 @@ static int handle_stimulus_message(struct skinny_req *req, struct skinnysession
                        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;
@@ -5189,7 +5204,7 @@ static int handle_offhook_message(struct skinny_req *req, struct skinnysession *
                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;
@@ -5292,8 +5307,9 @@ static int handle_capabilities_res_message(struct skinny_req *req, struct skinny
        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) {
@@ -5302,17 +5318,17 @@ static int handle_capabilities_res_message(struct skinny_req *req, struct skinny
        }
 
        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;
@@ -5639,7 +5655,7 @@ static int handle_open_receive_channel_ack_message(struct skinny_req *req, struc
        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);
@@ -5678,7 +5694,7 @@ static int handle_enbloc_call_message(struct skinny_req *req, struct skinnysessi
                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);
@@ -5792,7 +5808,7 @@ static int handle_soft_key_event_message(struct skinny_req *req, struct skinnyse
                }
 
                if (!sub || !sub->owner) {
-                       c = skinny_new(l, AST_STATE_DOWN);
+                       c = skinny_new(l, AST_STATE_DOWN, NULL);
                } else {
                        c = sub->owner;
                }
@@ -5828,7 +5844,7 @@ static int handle_soft_key_event_message(struct skinny_req *req, struct skinnyse
                        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);
@@ -5898,7 +5914,7 @@ static int handle_soft_key_event_message(struct skinny_req *req, struct skinnyse
                        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;
                }
@@ -5916,7 +5932,7 @@ static int handle_soft_key_event_message(struct skinny_req *req, struct skinnyse
                        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;
                }
@@ -5935,7 +5951,7 @@ static int handle_soft_key_event_message(struct skinny_req *req, struct skinnyse
 
 #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;
                }
@@ -6329,6 +6345,7 @@ static int get_input(struct skinnysession *s)
 {
        int res;
        int dlen = 0;
+       int *bufaddr;
        struct pollfd fds[1];
 
        fds[0].fd = s->fd;
@@ -6375,7 +6392,8 @@ static int get_input(struct skinnysession *s)
                        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);
@@ -6384,7 +6402,7 @@ static int get_input(struct skinnysession *s)
                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);
@@ -6403,13 +6421,15 @@ static int get_input(struct skinnysession *s)
 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);
 
@@ -6565,9 +6585,9 @@ static int skinny_devicestate(void *data)
        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;
@@ -6577,7 +6597,7 @@ static struct ast_channel *skinny_request(const char *type, int format, void *da
        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;
        }
 
@@ -6592,7 +6612,7 @@ static struct ast_channel *skinny_request(const char *type, int format, void *da
                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);
        }
@@ -6682,7 +6702,7 @@ static struct ast_channel *skinny_request(const char *type, int format, void *da
                                        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);
@@ -6713,9 +6733,9 @@ static struct ast_channel *skinny_request(const char *type, int format, void *da
                                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")) {
@@ -7020,7 +7040,7 @@ static struct ast_channel *skinny_request(const char *type, int format, void *da
                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,
@@ -7159,7 +7179,7 @@ static struct ast_channel *skinny_request(const char *type, int format, void *da
        /* 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 {
@@ -7431,6 +7451,7 @@ static int unload_module(void)
                        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)