fixup
authorAndreas Eversberg <jolly@eversberg.eu>
Fri, 1 Dec 2017 13:04:09 +0000 (14:04 +0100)
committerAndreas Eversberg <jolly@eversberg.eu>
Fri, 1 Dec 2017 13:04:09 +0000 (14:04 +0100)
sip.cpp
sip.h
todo.txt

diff --git a/sip.cpp b/sip.cpp
index 634c429..ff8ed89 100644 (file)
--- a/sip.cpp
+++ b/sip.cpp
@@ -55,6 +55,7 @@ struct sip_inst {
        char                    local_peer[128];
        char                    remote_peer[128];
        char                    asserted_id[128];
+       int                     allow_register;
        int                     register_state;
        char                    register_user[128];
        char                    register_host[128];
@@ -457,7 +458,6 @@ int Psip::rtp_open(void)
 
        /* bind socket */
        ip = htonl(INADDR_ANY);
-//     ia.s_addr = ip;
        start_port = inst->next_rtp_port;
        while (1) {
                rc = rtp_sub_socket_bind(p_s_rtp_fd.fd, &p_s_rtp_sin_local, ip, inst->next_rtp_port);
@@ -506,6 +506,8 @@ int Psip::rtp_connect(void)
        struct in_addr ia;
 
        ia.s_addr = htonl(p_s_rtp_ip_remote);
+       if (p_s_rtp_is_connected)
+               PDEBUG(DEBUG_SIP, "reconnecting existing RTP connection to new/same destination\n");
        PDEBUG(DEBUG_SIP, "rtp_connect(ip=%s, port=%u)\n", inet_ntoa(ia), p_s_rtp_port_remote);
 
        rc = rtp_sub_socket_connect(p_s_rtp_fd.fd, &p_s_rtp_sin_local, &p_s_rtp_sin_remote, p_s_rtp_ip_remote, p_s_rtp_port_remote);
@@ -885,8 +887,7 @@ unsigned int Psip::get_local_ip(unsigned int ip)
 int Psip::message_connect(unsigned int epoint_id, int message_id, union parameter *param)
 {
        struct sip_inst *inst = (struct sip_inst *) p_s_sip_inst;
-       char sdp_str[256] = "";
-       struct in_addr ia;
+       const char *sdp_str = NULL;
        struct lcr_msg *message;
        struct interface *interface;
        int media_type;
@@ -913,7 +914,7 @@ int Psip::message_connect(unsigned int epoint_id, int message_id, union paramete
                media_type = (options.law=='a') ? MEDIA_TYPE_ALAW : MEDIA_TYPE_ULAW;
                payload_type = (options.law=='a') ? PAYLOAD_TYPE_ALAW : PAYLOAD_TYPE_ULAW;
                /* open local RTP peer (if not bridging) */
-               if (!p_s_rtp_is_connected && rtp_connect() < 0) {
+               if (rtp_connect() < 0) {
                        nua_cancel(p_s_handle, TAG_END());
                        nua_handle_destroy(p_s_handle);
                        p_s_handle = NULL;
@@ -930,17 +931,7 @@ int Psip::message_connect(unsigned int epoint_id, int message_id, union paramete
                }
        }
 
-       memset(&ia, 0, sizeof(ia));
-       ia.s_addr = htonl(get_local_ip(p_s_rtp_ip_local));
-       SPRINT(sdp_str,
-               "v=0\r\n"
-               "o=LCR-Sofia-SIP 0 0 IN IP4 %s\r\n"
-               "s=SIP Call\r\n"
-               "c=IN IP4 %s\r\n"
-               "t=0 0\r\n"
-               "m=audio %d RTP/AVP %d\r\n"
-               "a=rtpmap:%d %s/8000\r\n"
-               , inet_ntoa(ia), inet_ntoa(ia), p_s_rtp_port_local, payload_type, payload_type, media_type2name(media_type));
+       sdp_str = generate_sdp(p_s_rtp_ip_local, p_s_rtp_port_local, 1, &payload_type, &media_type);
        PDEBUG(DEBUG_SIP, "Using SDP response: %s\n", sdp_str);
 
        /* NOTE:
@@ -958,11 +949,12 @@ int Psip::message_connect(unsigned int epoint_id, int message_id, union paramete
        sip_trace_header(this, inst->interface_name, "RESPOND", DIRECTION_OUT);
        add_trace("respond", "value", "200 OK");
        add_trace("reason", NULL, "call connected");
-       if (sdp_str[0]) {
-               add_trace("rtp", "ip", "%s", inet_ntoa(ia));
-               add_trace("rtp", "port", "%d,%d", p_s_rtp_port_local, p_s_rtp_port_local + 1);
-               add_trace("rtp", "payload", "%s:%d", media_type2name(media_type), payload_type);
-       }
+       struct in_addr ia;
+       memset(&ia, 0, sizeof(ia));
+       ia.s_addr = htonl(get_local_ip(p_s_rtp_ip_local));
+       add_trace("rtp", "ip", "%s", inet_ntoa(ia));
+       add_trace("rtp", "port", "%d,%d", p_s_rtp_port_local, p_s_rtp_port_local + 1);
+       add_trace("rtp", "payload", "%s:%d", media_type2name(media_type), payload_type);
        end_trace();
 
        return 0;
@@ -1043,8 +1035,7 @@ int Psip::message_setup(unsigned int epoint_id, int message_id, union parameter
        const char *local = inst->local_peer;
        char local_ip[16];
        const char *remote = inst->remote_peer;
-       char sdp_str[512], pt_str[32];
-       struct in_addr ia;
+       const char *sdp_str = NULL;
        struct epoint_list *epointlist;
        sip_cseq_t *cseq = NULL;
        struct lcr_msg *message;
@@ -1119,8 +1110,6 @@ int Psip::message_setup(unsigned int epoint_id, int message_id, union parameter
                }
        }
 
-       memset(&ia, 0, sizeof(ia));
-       ia.s_addr = htonl(get_local_ip(p_s_rtp_ip_local));
        p_s_handle = nua_handle(inst->nua, NULL, TAG_END());
        if (!p_s_handle) {
                PERROR("Failed to create handle\n");
@@ -1138,23 +1127,7 @@ int Psip::message_setup(unsigned int epoint_id, int message_id, union parameter
 //     add_trace("handle", "new", "0x%x", p_s_handle);
 //     end_trace();
 
-       SPRINT(sdp_str,
-               "v=0\r\n"
-               "o=LCR-Sofia-SIP 0 0 IN IP4 %s\r\n"
-               "s=SIP Call\r\n"
-               "c=IN IP4 %s\r\n"
-               "t=0 0\r\n"
-               "m=audio %d RTP/AVP"
-               , inet_ntoa(ia), inet_ntoa(ia), p_s_rtp_port_local);
-       for (i = 0; i < payloads; i++) {
-               SPRINT(pt_str, " %d", payload_types[i]);
-               SCAT(sdp_str, pt_str);
-       }
-       SCAT(sdp_str, "\r\n");
-       for (i = 0; i < payloads; i++) {
-               SPRINT(pt_str, "a=rtpmap:%d %s/8000\r\n", payload_types[i], media_type2name(media_types[i]));
-               SCAT(sdp_str, pt_str);
-       }
+       sdp_str = generate_sdp(p_s_rtp_ip_local, p_s_rtp_port_local, payloads, payload_types, media_types);
        PDEBUG(DEBUG_SIP, "Using SDP for invite: %s\n", sdp_str);
 
        SPRINT(from, "sip:%s@%s", p_callerinfo.id, remote);
@@ -1176,6 +1149,9 @@ int Psip::message_setup(unsigned int epoint_id, int message_id, union parameter
        add_trace("to", "uri", "%s", to);
        if (asserted_id[0])
                add_trace("assert-id", "uri", "%s", asserted_id);
+       struct in_addr ia;
+       memset(&ia, 0, sizeof(ia));
+       ia.s_addr = htonl(get_local_ip(p_s_rtp_ip_local));
        add_trace("rtp", "ip", "%s", inet_ntoa(ia));
        add_trace("rtp", "port", "%d,%d", p_s_rtp_port_local, p_s_rtp_port_local + 1);
        for (i = 0; i < payloads; i++)
@@ -1230,6 +1206,7 @@ int Psip::message_notify(unsigned int epoint_id, int message_id, union parameter
        switch (param->notifyinfo.notify) {
        case INFO_NOTIFY_REMOTE_HOLD:
 #if 0
+               sdp_str = generate_sdp(0, 0, 0, NULL, NULL);
                SPRINT(sdp_str,
                        "v=0\r\n"
                        "o=LCR-Sofia-SIP 0 0 IN IP4 0.0.0.0\r\n"
@@ -1249,17 +1226,7 @@ int Psip::message_notify(unsigned int epoint_id, int message_id, union parameter
                break;
        case INFO_NOTIFY_REMOTE_RETRIEVAL:
 #if 0
-               memset(&ia, 0, sizeof(ia));
-               ia.s_addr = htonl(get_local_ip(p_s_rtp_ip_local));
-               SPRINT(sdp_str,
-                       "v=0\r\n"
-                       "o=LCR-Sofia-SIP 0 0 IN IP4 %s\r\n"
-                       "s=SIP Call\r\n"
-                       "c=IN IP4 %s\r\n"
-                       "t=0 0\r\n"
-                       "m=audio %d RTP/AVP %d\r\n"
-                       "a=rtpmap:%d %s/8000\r\n"
-                       , inet_ntoa(ia), inet_ntoa(ia), p_s_rtp_port_local, p_s_rtp_payload_type, p_s_rtp_payload_type, media_type2name(p_s_rtp_media_type));
+               sdp_str = generate_sdp(p_s_rtp_ip_local, p_s_rtp_port_local, 1, &payload_type, &media_type);
                PDEBUG(DEBUG_SIP, "Using SDP for rertieve: %s\n", sdp_str);
                nua_info(p_s_handle,
 //                     TAG_IF(from[0], SIPTAG_FROM_STR(from)),
@@ -1461,6 +1428,37 @@ int Psip::parse_sdp(sip_t const *sip, unsigned int *ip, unsigned short *port, ui
        return 0;
 }
 
+const char *Psip::generate_sdp(unsigned int rtp_ip_local, unsigned short rtp_port_local, int payloads, unsigned char *payload_types, int *media_types)
+{
+       struct in_addr ia;
+       static char sdp_str[256], sub_str[128];
+       int i;
+
+       memset(&ia, 0, sizeof(ia));
+       ia.s_addr = htonl(get_local_ip(p_s_rtp_ip_local));
+       SPRINT(sdp_str,
+               "v=0\r\n"
+               "o=LCR-Sofia-SIP 0 0 IN IP4 %s\r\n"
+               "s=SIP Call\r\n"
+               "c=IN IP4 %s\r\n"
+               "t=0 0\r\n", inet_ntoa(ia), inet_ntoa(ia));
+       if (payloads) {
+               SPRINT(sub_str, "m=audio %d RTP/AVP", p_s_rtp_port_local);
+               SCAT(sdp_str, sub_str);
+               for (i = 0; i < payloads; i++) {
+                       SPRINT(sub_str, " %d", payload_types[i]);
+                       SCAT(sdp_str, sub_str);
+               }
+               SCAT(sdp_str, "\r\n");
+               for (i = 0; i < payloads; i++) {
+                       SPRINT(sub_str, "a=rtpmap:%d %s/8000\r\n", payload_types[i], media_type2name(media_types[i]));
+                       SCAT(sdp_str, sub_str);
+               }
+       }
+
+       return sdp_str;
+}
+
 static int challenge(struct sip_inst *inst, class Psip *psip, int status, char const *phrase, nua_t *nua, nua_magic_t *magic, nua_handle_t *nh, nua_hmagic_t *hmagic, sip_t const *sip, tagi_t tags[])
 {
        sip_www_authenticate_t const *authenticate = NULL;
@@ -1524,6 +1522,25 @@ static int challenge(struct sip_inst *inst, class Psip *psip, int status, char c
        return 0;
 }
 
+static void i_options(struct sip_inst *inst, int status, char const *phrase, nua_t *nua, nua_magic_t *magic, nua_handle_t *nh, nua_hmagic_t *hmagic, sip_t const *sip, tagi_t tags[])
+{
+       #define NUTAG_WITH_THIS_MSG(msg) nutag_with, tag_ptr_v(msg)
+       nua_saved_event_t saved[1];
+       nua_save_event(nua, saved);
+       nua_event_data_t const *data = nua_event_data(saved);
+
+       sip_trace_header(NULL, inst->interface_name, "OPTIONS", DIRECTION_IN);
+       end_trace();
+
+       sip_trace_header(NULL, inst->interface_name, "RESPOND", DIRECTION_OUT);
+       add_trace("respond", "value", "200 OK");
+       end_trace();
+
+       nua_respond(nh, SIP_200_OK, NUTAG_WITH_THIS_MSG(data->e_msg), TAG_END());
+       nua_handle_destroy(nh);
+       inst->register_handle = NULL;
+}
+
 static void i_register(struct sip_inst *inst, int status, char const *phrase, nua_t *nua, nua_magic_t *magic, nua_handle_t *nh, nua_hmagic_t *hmagic, sip_t const *sip, tagi_t tags[])
 {
        #define NUTAG_WITH_THIS_MSG(msg) nutag_with, tag_ptr_v(msg)
@@ -1533,6 +1550,16 @@ static void i_register(struct sip_inst *inst, int status, char const *phrase, nu
        nua_save_event(nua, saved);
        nua_event_data_t const *data = nua_event_data(saved);
 
+       if (!inst->allow_register) {
+               sip_trace_header(NULL, inst->interface_name, "REGISTER", DIRECTION_IN);
+               add_trace("error", NULL, "forbidden, because we don't accept registration");
+               end_trace();
+               nua_respond(nh, SIP_403_FORBIDDEN, NUTAG_WITH_THIS_MSG(data->e_msg), TAG_END());
+               nua_handle_destroy(nh);
+               inst->register_handle = NULL;
+               return;
+       }
+
        if (contact->m_url->url_host)
                SCPY(inst->remote_peer, contact->m_url->url_host);
        if (contact->m_url->url_port && contact->m_url->url_port[0]) {
@@ -1610,9 +1637,11 @@ void Psip::i_invite(int status, char const *phrase, nua_t *nua, nua_magic_t *mag
        class Endpoint *epoint;
        struct lcr_msg *message;
        struct interface *interface;
+       const char *sdp_str = NULL;
        int media_types[32];
        uint8_t payload_types[32];
        int payloads = 0;
+       unsigned char payload_type;
        int media_type;
 
        interface = getinterfacebyname(inst->interface_name);
@@ -1621,16 +1650,6 @@ void Psip::i_invite(int status, char const *phrase, nua_t *nua, nua_magic_t *mag
                return;
        }
 
-       if (p_state != PORT_STATE_IDLE) {
-#warning fixme: select new RTP and respond with SDP
-               sip_trace_header(this, inst->interface_name, "RE-INVITE", DIRECTION_IN);
-               end_trace();
-               nua_respond(p_s_handle, SIP_200_OK,
-                       NUTAG_MEDIA_ENABLE(0),
-                       TAG_END());
-               return;
-       }
-
        if (sip->sip_from) {
                if (sip->sip_from->a_url)
                        from = sip->sip_from->a_url->url_user;
@@ -1682,11 +1701,45 @@ void Psip::i_invite(int status, char const *phrase, nua_t *nua, nua_magic_t *mag
                        add_trace("respond", "value", "400 Bad Request");
                add_trace("reason", NULL, "offered codec does not match");
                end_trace();
+               if (p_state != PORT_STATE_IDLE) {
+                       message = message_create(p_serial, ACTIVE_EPOINT(p_epointlist), PORT_TO_EPOINT, MESSAGE_RELEASE);
+                       message->param.disconnectinfo.cause = 41;
+                       message->param.disconnectinfo.location = LOCATION_PRIVATE_LOCAL;
+                       message_put(message);
+               }
                new_state(PORT_STATE_RELEASE);
                trigger_work(&p_s_delete);
                return;
        }
 
+       /* handle re-invite */
+       if (p_state != PORT_STATE_IDLE) {
+               sip_trace_header(this, inst->interface_name, "RE-INVITE", DIRECTION_IN);
+               end_trace();
+               if (p_s_rtp_bridge) {
+                       PDEBUG(DEBUG_SIP, "RE-INVITE not implemented for RTP forwarding\n");
+                       nua_respond(nh, SIP_501_NOT_IMPLEMENTED, TAG_END());
+                       sip_trace_header(this, inst->interface_name, "RESPOND", DIRECTION_OUT);
+                       add_trace("respond", "value", "501 NOT IMPLEMENTED");
+                       add_trace("reason", NULL, "RE-INVITE not implemented for RTP forwarding");
+                       end_trace();
+               } else {
+                       PDEBUG(DEBUG_SIP, "RTP info given by remote, forward that\n");
+                       media_type = (options.law=='a') ? MEDIA_TYPE_ALAW : MEDIA_TYPE_ULAW;
+                       payload_type = (options.law=='a') ? PAYLOAD_TYPE_ALAW : PAYLOAD_TYPE_ULAW;
+                       if (rtp_connect() < 0) {
+                               goto rtp_failed;
+                       }
+                       sdp_str = generate_sdp(p_s_rtp_ip_local, p_s_rtp_port_local, 1, &payload_type, &media_type);
+                       PDEBUG(DEBUG_SIP, "Using SDP response: %s\n", sdp_str);
+                       nua_respond(p_s_handle, SIP_200_OK,
+                               NUTAG_MEDIA_ENABLE(0),
+                               SIPTAG_CONTENT_TYPE_STR("application/sdp"),
+                               SIPTAG_PAYLOAD_STR(sdp_str), TAG_END());
+               }
+               return;
+       }
+
        /* open local RTP peer (if not bridging) */
        if (!p_s_rtp_bridge && rtp_open() < 0) {
                nua_respond(nh, SIP_500_INTERNAL_SERVER_ERROR, TAG_END());
@@ -1803,15 +1856,12 @@ void Psip::i_invite(int status, char const *phrase, nua_t *nua, nua_magic_t *mag
 
        /* send progress, if tones are available and if we don't bridge */
        if (!p_s_rtp_bridge && interface->is_tones == IS_YES) {
-               char sdp_str[256];
-               struct in_addr ia;
-               unsigned char payload_type;
-
                PDEBUG(DEBUG_SIP, "Connecting audio, since we have tones available\n");
                media_type = (options.law=='a') ? MEDIA_TYPE_ALAW : MEDIA_TYPE_ULAW;
                payload_type = (options.law=='a') ? PAYLOAD_TYPE_ALAW : PAYLOAD_TYPE_ULAW;
                /* open local RTP peer (if not bridging) */
                if (rtp_connect() < 0) {
+rtp_failed:
                        nua_respond(nh, SIP_500_INTERNAL_SERVER_ERROR, TAG_END());
                        nua_handle_destroy(nh);
                        p_s_handle = NULL;
@@ -1819,8 +1869,6 @@ void Psip::i_invite(int status, char const *phrase, nua_t *nua, nua_magic_t *mag
                        add_trace("respond", "value", "500 Internal Server Error");
                        add_trace("reason", NULL, "failed to connect RTP/RTCP sockts");
                        end_trace();
-                       new_state(PORT_STATE_RELEASE);
-                       trigger_work(&p_s_delete);
                        message = message_create(p_serial, ACTIVE_EPOINT(p_epointlist), PORT_TO_EPOINT, MESSAGE_RELEASE);
                        message->param.disconnectinfo.cause = 41;
                        message->param.disconnectinfo.location = LOCATION_PRIVATE_LOCAL;
@@ -1830,17 +1878,7 @@ void Psip::i_invite(int status, char const *phrase, nua_t *nua, nua_magic_t *mag
                        return;
                }
 
-               memset(&ia, 0, sizeof(ia));
-               ia.s_addr = htonl(get_local_ip(p_s_rtp_ip_local));
-               SPRINT(sdp_str,
-                       "v=0\r\n"
-                       "o=LCR-Sofia-SIP 0 0 IN IP4 %s\r\n"
-                       "s=SIP Call\r\n"
-                       "c=IN IP4 %s\r\n"
-                       "t=0 0\r\n"
-                       "m=audio %d RTP/AVP %d\r\n"
-                       "a=rtpmap:%d %s/8000\r\n"
-                       , inet_ntoa(ia), inet_ntoa(ia), p_s_rtp_port_local, payload_type, payload_type, media_type2name(media_type));
+               sdp_str = generate_sdp(p_s_rtp_ip_local, p_s_rtp_port_local, 1, &payload_type, &media_type);
                PDEBUG(DEBUG_SIP, "Using SDP response: %s\n", sdp_str);
 
                nua_respond(p_s_handle, SIP_183_SESSION_PROGRESS,
@@ -1850,6 +1888,9 @@ void Psip::i_invite(int status, char const *phrase, nua_t *nua, nua_magic_t *mag
                sip_trace_header(this, inst->interface_name, "RESPOND", DIRECTION_OUT);
                add_trace("respond", "value", "183 SESSION PROGRESS");
                add_trace("reason", NULL, "audio available");
+               struct in_addr ia;
+               memset(&ia, 0, sizeof(ia));
+               ia.s_addr = htonl(get_local_ip(p_s_rtp_ip_local));
                add_trace("rtp", "ip", "%s", inet_ntoa(ia));
                add_trace("rtp", "port", "%d,%d", p_s_rtp_port_local, p_s_rtp_port_local + 1);
                add_trace("rtp", "payload", "%s:%d", media_type2name(media_type), payload_type);
@@ -2002,7 +2043,7 @@ void Psip::r_invite(int status, char const *phrase, nua_t *nua, nua_magic_t *mag
                }
 
                /* connect to remote RTP (if not bridging) */
-               if (!p_s_rtp_bridge && !p_s_rtp_is_connected && rtp_connect() < 0) {
+               if (!p_s_rtp_bridge && rtp_connect() < 0) {
                        nua_cancel(nh, TAG_END());
                        sip_trace_header(this, inst->interface_name, "CANCEL", DIRECTION_OUT);
                        add_trace("reason", NULL, "failed to open RTP/RTCP sockts");
@@ -2132,6 +2173,17 @@ void Psip::r_options(int status, char const *phrase, nua_t *nua, nua_magic_t *ma
        trigger_work(&p_s_delete);
 }
 
+void Psip::i_state(int status, char const *phrase, nua_t *nua, nua_magic_t *magic, nua_handle_t *nh, nua_hmagic_t *hmagic, sip_t const *sip, tagi_t tags[])
+{
+       struct sip_inst *inst = (struct sip_inst *) p_s_sip_inst;
+
+       PDEBUG(DEBUG_SIP, "state change received\n");
+       sip_trace_header(this, inst->interface_name, "STATUS", DIRECTION_OUT);
+       add_trace("value", NULL, "%d", status);
+       add_trace("phrase", NULL, "%s", phrase);
+       end_trace();
+}
+
 static void sip_callback(nua_event_t event, int status, char const *phrase, nua_t *nua, nua_magic_t *magic, nua_handle_t *nh, nua_hmagic_t *hmagic, sip_t const *sip, tagi_t tags[])
 {
        struct sip_inst *inst = (struct sip_inst *) magic;
@@ -2158,8 +2210,12 @@ static void sip_callback(nua_event_t event, int status, char const *phrase, nua_
                psip = NULL;
 
        /* new handle */
-       if (!psip && inst->register_handle != nh) {
+       if (!psip && !inst->register_handle) {
                switch (event) {
+               case nua_i_options:
+                       PDEBUG(DEBUG_SIP, "New options instance\n");
+                       inst->register_handle = nh;
+                       break;
                case nua_i_register:
                        PDEBUG(DEBUG_SIP, "New register instance\n");
                        inst->register_handle = nh;
@@ -2178,10 +2234,8 @@ static void sip_callback(nua_event_t event, int status, char const *phrase, nua_
                                        break;
                                interface = interface->next;
                        }
-                       if (!interface) {
-                               PERROR("Cannot find interface %s.\n", inst->interface_name);
-                               return;
-                       }
+                       if (!interface)
+                               FATAL("Cannot find interface %s.\n", inst->interface_name);
                        if (!(psip = new Psip(PORT_TYPE_SIP_IN, name, NULL, interface)))
                                FATAL("Cannot create Port instance.\n");
                        break;
@@ -2196,6 +2250,9 @@ static void sip_callback(nua_event_t event, int status, char const *phrase, nua_
        /* handle register process */
        if (inst->register_handle == nh) {
                switch (event) {
+               case nua_i_options:
+                       i_options(inst, status, phrase, nua, magic, nh, hmagic, sip, tags);
+                       break;
                case nua_i_register:
                        i_register(inst, status, phrase, nua, magic, nh, hmagic, sip, tags);
                        break;
@@ -2216,13 +2273,6 @@ static void sip_callback(nua_event_t event, int status, char const *phrase, nua_
                return;
        }
 
-       if (status) {
-               sip_trace_header(psip, inst->interface_name, "STATUS", DIRECTION_OUT);
-               add_trace("value", NULL, "%d", status);
-               add_trace("phrase", NULL, "%s", phrase);
-               end_trace();
-       }
-
        switch (status) {
        case 401:
        case 407:
@@ -2242,7 +2292,7 @@ static void sip_callback(nua_event_t event, int status, char const *phrase, nua_
                PDEBUG(DEBUG_SIP, "error received\n");
                break;
        case nua_i_state:
-               PDEBUG(DEBUG_SIP, "state change received\n");
+               psip->i_state(status, phrase, nua, magic, nh, hmagic, sip, tags);
                break;
        case nua_i_invite:
                psip->i_invite(status, phrase, nua, magic, nh, hmagic, sip, tags);
@@ -2404,6 +2454,8 @@ int sip_init_inst(struct interface *interface)
        SCPY(inst->interface_name, interface->name);
        SCPY(inst->local_peer, interface->sip_local_peer);
        SCPY(inst->remote_peer, interface->sip_remote_peer);
+       if (!inst->remote_peer[0])
+               inst->allow_register = 1;
        SCPY(inst->asserted_id, interface->sip_asserted_id);
        if (interface->sip_register) {
                inst->register_state = REGISTER_STATE_UNREGISTERED;
diff --git a/sip.h b/sip.h
index 64286bd..1e13aee 100644 (file)
--- a/sip.h
+++ b/sip.h
@@ -35,6 +35,7 @@ class Psip : public Port
        void r_invite(int status, char const *phrase, nua_t *nua, nua_magic_t *magic, nua_handle_t *nh, nua_hmagic_t *hmagic, sip_t const *sip, tagi_t tags[]);
        void i_options(int status, char const *phrase, nua_t *nua, nua_magic_t *magic, nua_handle_t *nh, nua_hmagic_t *hmagic, sip_t const *sip, tagi_t tags[]);
        void r_options(int status, char const *phrase, nua_t *nua, nua_magic_t *magic, nua_handle_t *nh, nua_hmagic_t *hmagic, sip_t const *sip, tagi_t tags[]);
+       void i_state(int status, char const *phrase, nua_t *nua, nua_magic_t *magic, nua_handle_t *nh, nua_hmagic_t *hmagic, sip_t const *sip, tagi_t tags[]);
        void *p_s_sip_inst;
        struct lcr_work p_s_delete;
        nua_handle_t *p_s_handle;
@@ -69,6 +70,7 @@ class Psip : public Port
        unsigned char p_s_rxdata[160]; /* receive audio buffer */
        int p_s_rxpos; /* position in audio buffer 0..159 */
        int bridge_rx(unsigned char *data, int len);
+       const char *generate_sdp(unsigned int rtp_ip_local, unsigned short rtp_port_local, int payloads, unsigned char *payload_types, int *media_types);
        int parse_sdp(sip_t const *sip, unsigned int *ip, unsigned short *port, uint8_t *payload_types, int *media_types, int *payloads, int max_payloads);
        void rtp_shutdown(void);
 
index d0e5569..5787420 100644 (file)
--- a/todo.txt
+++ b/todo.txt
@@ -25,11 +25,7 @@ doku:
 
 sip:
 
-- blockiert der prozess beim lookup? (also invite oder register bei dns-unerreichbarkeit)
-- feste ip statt stun
-- ankommende registrierung
-- earlyb testen (siehe interface.conf)
-- callerid als display-info
+- ankommende authentisierung
 
 routing:
 - ersetzten-operator