Bug report: pjsua has no video on call unhold on cisco pbx

HB
Håkan Berg
Mon, Sep 24, 2018 1:01 PM

Hi,
I believe I've found a problem in pjsua: When registered to a cisco unified call manager pbx (10.5 in my case) and calling to a video phone endpoint on that pbx, the video negotiation in pjsip fails if the endpoint phone puts pjsip on hold and then unhold again.
The SDP sent from pjsip seems to be missing vital video lines:
m=video 0 RTP/AVP 31
c=IN IP4 127.0.0.1
a=sendrecv

Whereas a working video SDP might include something like this:
m=video 4006 RTP/AVP 97
c=IN IP4 10.0.0.5
b=TIAS:768000
a=rtcp:4007 IN IP4 10.0.0.5
a=sendrecv
a=rtpmap:97 H264/90000
a=fmtp:97 profile-level-id=42000d

I can reproduce it with pjsua-bin like so:

git clone https://github.com/cisco/openh264.git
cd openh264
make
sudo make install
cd ..
wget http://pjsip.org/release/2.8/pjproject-2.8.tar.bz2
tar xvfj pjproject-2.8.tar.bz2
cd pjproject-2.8
./configure
echo "#define PJMEDIA_HAS_VIDEO 1" >> pjlib/include/pj/config_site.h
make dep && make
cd pjsip-apps/bin
./pjsua-x86_64-unknown-linux-gnu --playback-dev=1 --capture-dev=1 --id sip:1@10.0.0.1 --registrar sip:10.0.0.1 --realm "*" --username 1 --password hunter2 --app-log-level=3 --video

press m, enter sip:2@10.0.0.1
Cisco phone on extension 2 rings, answer and press hold. Video goes to inactive, press hold button again to unhold call, video ends up still being inactive because of SDP negotiation problem.
I can work around the problem by registering a callback function, but that should not be needed in my opinion:

diff --git a/pjsip-apps/src/pjsua/pjsua_app.c.bak b/pjsip-apps/src/pjsua/pjsua_app.c
index 51c4537..db6066a 100644
--- a/pjsip-apps/src/pjsua/pjsua_app.c.bak
+++ b/pjsip-apps/src/pjsua/pjsua_app.c
@@ -1226,6 +1226,12 @@ int stdout_refresh_proc(void *arg)
return 0;
}

+static void
+ON_CALL_TX_OFFER_WORKAROUND(pjsua_call_id call_id, void *reserved,

  •                        pjsua_call_setting *opt)
    

+{
+}
+
static pj_status_t app_init()
{
pjsua_transport_id transport_id = -1;
@@ -1275,6 +1281,9 @@ static pj_status_t app_init()
app_config.cfg.cb.on_nat_detect = &on_nat_detect;
app_config.cfg.cb.on_mwi_info = &on_mwi_info;
app_config.cfg.cb.on_transport_state = &on_transport_state;
+

  • app_config.cfg.cb.on_call_tx_offer = &ON_CALL_TX_OFFER_WORKAROUND;
  • app_config.cfg.cb.on_ice_transport_error = &on_ice_transport_error;
    app_config.cfg.cb.on_snd_dev_operation = &on_snd_dev_operation;
    app_config.cfg.cb.on_call_media_event = &on_call_media_event;

This seems to be a problem because of the late offer mechanism that cisco uses, and pjsua-lib only "re-initialize media before creating SDP" if there's a on_call_tx_offer callback set (or call->med_prov_cnt is 0), see pjsua_call_on_create_offer().
This limitation does not seem to exist for things like pjsua_call_set_hold2(). But that's why the workaround gives a successful SDP negotiation: apply_call_setting() gets called.
Let me know if you need any pcap dumps demonstrating the problem.

Please advise.
Br,
/Håkan

Hi, I believe I've found a problem in pjsua: When registered to a cisco unified call manager pbx (10.5 in my case) and calling to a video phone endpoint on that pbx, the video negotiation in pjsip fails if the endpoint phone puts pjsip on hold and then unhold again. The SDP sent from pjsip seems to be missing vital video lines: m=video 0 RTP/AVP 31 c=IN IP4 127.0.0.1 a=sendrecv Whereas a working video SDP might include something like this: m=video 4006 RTP/AVP 97 c=IN IP4 10.0.0.5 b=TIAS:768000 a=rtcp:4007 IN IP4 10.0.0.5 a=sendrecv a=rtpmap:97 H264/90000 a=fmtp:97 profile-level-id=42000d I can reproduce it with pjsua-bin like so: git clone https://github.com/cisco/openh264.git cd openh264 make sudo make install cd .. wget http://pjsip.org/release/2.8/pjproject-2.8.tar.bz2 tar xvfj pjproject-2.8.tar.bz2 cd pjproject-2.8 ./configure echo "#define PJMEDIA_HAS_VIDEO 1" >> pjlib/include/pj/config_site.h make dep && make cd pjsip-apps/bin ./pjsua-x86_64-unknown-linux-gnu --playback-dev=1 --capture-dev=1 --id sip:1@10.0.0.1 --registrar sip:10.0.0.1 --realm "*" --username 1 --password hunter2 --app-log-level=3 --video press m, enter sip:2@10.0.0.1 Cisco phone on extension 2 rings, answer and press hold. Video goes to inactive, press hold button again to unhold call, video ends up still being inactive because of SDP negotiation problem. I can work around the problem by registering a callback function, but that should not be needed in my opinion: diff --git a/pjsip-apps/src/pjsua/pjsua_app.c.bak b/pjsip-apps/src/pjsua/pjsua_app.c index 51c4537..db6066a 100644 --- a/pjsip-apps/src/pjsua/pjsua_app.c.bak +++ b/pjsip-apps/src/pjsua/pjsua_app.c @@ -1226,6 +1226,12 @@ int stdout_refresh_proc(void *arg) return 0; } +static void +ON_CALL_TX_OFFER_WORKAROUND(pjsua_call_id call_id, void *reserved, + pjsua_call_setting *opt) +{ +} + static pj_status_t app_init() { pjsua_transport_id transport_id = -1; @@ -1275,6 +1281,9 @@ static pj_status_t app_init() app_config.cfg.cb.on_nat_detect = &on_nat_detect; app_config.cfg.cb.on_mwi_info = &on_mwi_info; app_config.cfg.cb.on_transport_state = &on_transport_state; + + app_config.cfg.cb.on_call_tx_offer = &ON_CALL_TX_OFFER_WORKAROUND; + app_config.cfg.cb.on_ice_transport_error = &on_ice_transport_error; app_config.cfg.cb.on_snd_dev_operation = &on_snd_dev_operation; app_config.cfg.cb.on_call_media_event = &on_call_media_event; This seems to be a problem because of the late offer mechanism that cisco uses, and pjsua-lib only "re-initialize media before creating SDP" if there's a on_call_tx_offer callback set (or call->med_prov_cnt is 0), see pjsua_call_on_create_offer(). This limitation does not seem to exist for things like pjsua_call_set_hold2(). But that's why the workaround gives a successful SDP negotiation: apply_call_setting() gets called. Let me know if you need any pcap dumps demonstrating the problem. Please advise. Br, /Håkan
M
Ming
Tue, Sep 25, 2018 1:03 AM

Hi Hakan,

Since I can't access the Cisco server from here, can you forward us
the log (level 5, as text attachment)?

Based on your description, since app needs to overwrite callback
on_call_tx_offer(), does it mean that the remote is sending re-INVITE
without SDP when trying to unhold?

Regards,
Ming
On Mon, Sep 24, 2018 at 9:03 PM Håkan Berg hakan.berg@axis.com wrote:

Hi,
I believe I've found a problem in pjsua: When registered to a cisco unified call manager pbx (10.5 in my case) and calling to a video phone endpoint on that pbx, the video negotiation in pjsip fails if the endpoint phone puts pjsip on hold and then unhold again.
The SDP sent from pjsip seems to be missing vital video lines:
m=video 0 RTP/AVP 31
c=IN IP4 127.0.0.1
a=sendrecv

Whereas a working video SDP might include something like this:
m=video 4006 RTP/AVP 97
c=IN IP4 10.0.0.5
b=TIAS:768000
a=rtcp:4007 IN IP4 10.0.0.5
a=sendrecv
a=rtpmap:97 H264/90000
a=fmtp:97 profile-level-id=42000d

I can reproduce it with pjsua-bin like so:

git clone https://github.com/cisco/openh264.git
cd openh264
make
sudo make install
cd ..
wget http://pjsip.org/release/2.8/pjproject-2.8.tar.bz2
tar xvfj pjproject-2.8.tar.bz2
cd pjproject-2.8
./configure
echo "#define PJMEDIA_HAS_VIDEO 1" >> pjlib/include/pj/config_site.h
make dep && make
cd pjsip-apps/bin
./pjsua-x86_64-unknown-linux-gnu --playback-dev=1 --capture-dev=1 --id sip:1@10.0.0.1 --registrar sip:10.0.0.1 --realm "*" --username 1 --password hunter2 --app-log-level=3 --video

press m, enter sip:2@10.0.0.1
Cisco phone on extension 2 rings, answer and press hold. Video goes to inactive, press hold button again to unhold call, video ends up still being inactive because of SDP negotiation problem.
I can work around the problem by registering a callback function, but that should not be needed in my opinion:

diff --git a/pjsip-apps/src/pjsua/pjsua_app.c.bak b/pjsip-apps/src/pjsua/pjsua_app.c
index 51c4537..db6066a 100644
--- a/pjsip-apps/src/pjsua/pjsua_app.c.bak
+++ b/pjsip-apps/src/pjsua/pjsua_app.c
@@ -1226,6 +1226,12 @@ int stdout_refresh_proc(void *arg)
return 0;
}

+static void
+ON_CALL_TX_OFFER_WORKAROUND(pjsua_call_id call_id, void *reserved,

  •                        pjsua_call_setting *opt)
    

+{
+}
+
static pj_status_t app_init()
{
pjsua_transport_id transport_id = -1;
@@ -1275,6 +1281,9 @@ static pj_status_t app_init()
app_config.cfg.cb.on_nat_detect = &on_nat_detect;
app_config.cfg.cb.on_mwi_info = &on_mwi_info;
app_config.cfg.cb.on_transport_state = &on_transport_state;
+

  • app_config.cfg.cb.on_call_tx_offer = &ON_CALL_TX_OFFER_WORKAROUND;
  • app_config.cfg.cb.on_ice_transport_error = &on_ice_transport_error;
    app_config.cfg.cb.on_snd_dev_operation = &on_snd_dev_operation;
    app_config.cfg.cb.on_call_media_event = &on_call_media_event;

This seems to be a problem because of the late offer mechanism that cisco uses, and pjsua-lib only "re-initialize media before creating SDP" if there's a on_call_tx_offer callback set (or call->med_prov_cnt is 0), see pjsua_call_on_create_offer().
This limitation does not seem to exist for things like pjsua_call_set_hold2(). But that's why the workaround gives a successful SDP negotiation: apply_call_setting() gets called.
Let me know if you need any pcap dumps demonstrating the problem.

Please advise.
Br,
/Håkan


Visit our blog: http://blog.pjsip.org

pjsip mailing list
pjsip@lists.pjsip.org
http://lists.pjsip.org/mailman/listinfo/pjsip_lists.pjsip.org

Hi Hakan, Since I can't access the Cisco server from here, can you forward us the log (level 5, as text attachment)? Based on your description, since app needs to overwrite callback on_call_tx_offer(), does it mean that the remote is sending re-INVITE without SDP when trying to unhold? Regards, Ming On Mon, Sep 24, 2018 at 9:03 PM Håkan Berg <hakan.berg@axis.com> wrote: > > Hi, > I believe I've found a problem in pjsua: When registered to a cisco unified call manager pbx (10.5 in my case) and calling to a video phone endpoint on that pbx, the video negotiation in pjsip fails if the endpoint phone puts pjsip on hold and then unhold again. > The SDP sent from pjsip seems to be missing vital video lines: > m=video 0 RTP/AVP 31 > c=IN IP4 127.0.0.1 > a=sendrecv > > Whereas a working video SDP might include something like this: > m=video 4006 RTP/AVP 97 > c=IN IP4 10.0.0.5 > b=TIAS:768000 > a=rtcp:4007 IN IP4 10.0.0.5 > a=sendrecv > a=rtpmap:97 H264/90000 > a=fmtp:97 profile-level-id=42000d > > I can reproduce it with pjsua-bin like so: > > git clone https://github.com/cisco/openh264.git > cd openh264 > make > sudo make install > cd .. > wget http://pjsip.org/release/2.8/pjproject-2.8.tar.bz2 > tar xvfj pjproject-2.8.tar.bz2 > cd pjproject-2.8 > ./configure > echo "#define PJMEDIA_HAS_VIDEO 1" >> pjlib/include/pj/config_site.h > make dep && make > cd pjsip-apps/bin > ./pjsua-x86_64-unknown-linux-gnu --playback-dev=1 --capture-dev=1 --id sip:1@10.0.0.1 --registrar sip:10.0.0.1 --realm "*" --username 1 --password hunter2 --app-log-level=3 --video > > press m, enter sip:2@10.0.0.1 > Cisco phone on extension 2 rings, answer and press hold. Video goes to inactive, press hold button again to unhold call, video ends up still being inactive because of SDP negotiation problem. > I can work around the problem by registering a callback function, but that should not be needed in my opinion: > > diff --git a/pjsip-apps/src/pjsua/pjsua_app.c.bak b/pjsip-apps/src/pjsua/pjsua_app.c > index 51c4537..db6066a 100644 > --- a/pjsip-apps/src/pjsua/pjsua_app.c.bak > +++ b/pjsip-apps/src/pjsua/pjsua_app.c > @@ -1226,6 +1226,12 @@ int stdout_refresh_proc(void *arg) > return 0; > } > > +static void > +ON_CALL_TX_OFFER_WORKAROUND(pjsua_call_id call_id, void *reserved, > + pjsua_call_setting *opt) > +{ > +} > + > static pj_status_t app_init() > { > pjsua_transport_id transport_id = -1; > @@ -1275,6 +1281,9 @@ static pj_status_t app_init() > app_config.cfg.cb.on_nat_detect = &on_nat_detect; > app_config.cfg.cb.on_mwi_info = &on_mwi_info; > app_config.cfg.cb.on_transport_state = &on_transport_state; > + > + app_config.cfg.cb.on_call_tx_offer = &ON_CALL_TX_OFFER_WORKAROUND; > + > app_config.cfg.cb.on_ice_transport_error = &on_ice_transport_error; > app_config.cfg.cb.on_snd_dev_operation = &on_snd_dev_operation; > app_config.cfg.cb.on_call_media_event = &on_call_media_event; > > > > This seems to be a problem because of the late offer mechanism that cisco uses, and pjsua-lib only "re-initialize media before creating SDP" if there's a on_call_tx_offer callback set (or call->med_prov_cnt is 0), see pjsua_call_on_create_offer(). > This limitation does not seem to exist for things like pjsua_call_set_hold2(). But that's why the workaround gives a successful SDP negotiation: apply_call_setting() gets called. > Let me know if you need any pcap dumps demonstrating the problem. > > Please advise. > Br, > /Håkan > > _______________________________________________ > Visit our blog: http://blog.pjsip.org > > pjsip mailing list > pjsip@lists.pjsip.org > http://lists.pjsip.org/mailman/listinfo/pjsip_lists.pjsip.org
HB
Håkan Berg
Tue, Sep 25, 2018 4:27 PM

Hi Ming,

Yes, you're correct. The remote is sending a re-INVITE without SDP when doing unhold.

Attaching log file.

Br,
/Håkan

-----Original Message-----
From: pjsip [mailto:pjsip-bounces@lists.pjsip.org] On Behalf Of Ming
Sent: den 25 september 2018 03:04
To: pjsip list pjsip@lists.pjsip.org
Subject: Re: [pjsip] Bug report: pjsua has no video on call unhold on cisco pbx

Hi Hakan,

Since I can't access the Cisco server from here, can you forward us the log (level 5, as text attachment)?

Based on your description, since app needs to overwrite callback on_call_tx_offer(), does it mean that the remote is sending re-INVITE without SDP when trying to unhold?

Regards,
Ming
On Mon, Sep 24, 2018 at 9:03 PM Håkan Berg hakan.berg@axis.com wrote:

Hi,
I believe I've found a problem in pjsua: When registered to a cisco unified call manager pbx (10.5 in my case) and calling to a video phone endpoint on that pbx, the video negotiation in pjsip fails if the endpoint phone puts pjsip on hold and then unhold again.
The SDP sent from pjsip seems to be missing vital video lines:
m=video 0 RTP/AVP 31
c=IN IP4 127.0.0.1
a=sendrecv

Whereas a working video SDP might include something like this:
m=video 4006 RTP/AVP 97
c=IN IP4 10.0.0.5
b=TIAS:768000
a=rtcp:4007 IN IP4 10.0.0.5
a=sendrecv
a=rtpmap:97 H264/90000
a=fmtp:97 profile-level-id=42000d

I can reproduce it with pjsua-bin like so:

git clone https://github.com/cisco/openh264.git
cd openh264
make
sudo make install
cd ..
wget http://pjsip.org/release/2.8/pjproject-2.8.tar.bz2
tar xvfj pjproject-2.8.tar.bz2
cd pjproject-2.8
./configure
echo "#define PJMEDIA_HAS_VIDEO 1" >> pjlib/include/pj/config_site.h
make dep && make cd pjsip-apps/bin ./pjsua-x86_64-unknown-linux-gnu
--playback-dev=1 --capture-dev=1 --id sip:1@10.0.0.1 --registrar
sip:10.0.0.1 --realm "*" --username 1 --password hunter2
--app-log-level=3 --video

press m, enter sip:2@10.0.0.1
Cisco phone on extension 2 rings, answer and press hold. Video goes to inactive, press hold button again to unhold call, video ends up still being inactive because of SDP negotiation problem.
I can work around the problem by registering a callback function, but that should not be needed in my opinion:

diff --git a/pjsip-apps/src/pjsua/pjsua_app.c.bak
b/pjsip-apps/src/pjsua/pjsua_app.c
index 51c4537..db6066a 100644
--- a/pjsip-apps/src/pjsua/pjsua_app.c.bak
+++ b/pjsip-apps/src/pjsua/pjsua_app.c
@@ -1226,6 +1226,12 @@ int stdout_refresh_proc(void *arg)
return 0;
}

+static void
+ON_CALL_TX_OFFER_WORKAROUND(pjsua_call_id call_id, void *reserved,

  •                        pjsua_call_setting *opt) { }
    

static pj_status_t app_init()
{
pjsua_transport_id transport_id = -1; @@ -1275,6 +1281,9 @@
static pj_status_t app_init()
app_config.cfg.cb.on_nat_detect = &on_nat_detect;
app_config.cfg.cb.on_mwi_info = &on_mwi_info;
app_config.cfg.cb.on_transport_state = &on_transport_state;
+

  • app_config.cfg.cb.on_call_tx_offer =
  • &ON_CALL_TX_OFFER_WORKAROUND;
  • app_config.cfg.cb.on_ice_transport_error = &on_ice_transport_error;
    app_config.cfg.cb.on_snd_dev_operation = &on_snd_dev_operation;
    app_config.cfg.cb.on_call_media_event = &on_call_media_event;

This seems to be a problem because of the late offer mechanism that cisco uses, and pjsua-lib only "re-initialize media before creating SDP" if there's a on_call_tx_offer callback set (or call->med_prov_cnt is 0), see pjsua_call_on_create_offer().
This limitation does not seem to exist for things like pjsua_call_set_hold2(). But that's why the workaround gives a successful SDP negotiation: apply_call_setting() gets called.
Let me know if you need any pcap dumps demonstrating the problem.

Please advise.
Br,
/Håkan


Visit our blog: http://blog.pjsip.org

pjsip mailing list
pjsip@lists.pjsip.org
http://lists.pjsip.org/mailman/listinfo/pjsip_lists.pjsip.org

Hi Ming, Yes, you're correct. The remote is sending a re-INVITE without SDP when doing unhold. Attaching log file. Br, /Håkan -----Original Message----- From: pjsip [mailto:pjsip-bounces@lists.pjsip.org] On Behalf Of Ming Sent: den 25 september 2018 03:04 To: pjsip list <pjsip@lists.pjsip.org> Subject: Re: [pjsip] Bug report: pjsua has no video on call unhold on cisco pbx Hi Hakan, Since I can't access the Cisco server from here, can you forward us the log (level 5, as text attachment)? Based on your description, since app needs to overwrite callback on_call_tx_offer(), does it mean that the remote is sending re-INVITE without SDP when trying to unhold? Regards, Ming On Mon, Sep 24, 2018 at 9:03 PM Håkan Berg <hakan.berg@axis.com> wrote: > > Hi, > I believe I've found a problem in pjsua: When registered to a cisco unified call manager pbx (10.5 in my case) and calling to a video phone endpoint on that pbx, the video negotiation in pjsip fails if the endpoint phone puts pjsip on hold and then unhold again. > The SDP sent from pjsip seems to be missing vital video lines: > m=video 0 RTP/AVP 31 > c=IN IP4 127.0.0.1 > a=sendrecv > > Whereas a working video SDP might include something like this: > m=video 4006 RTP/AVP 97 > c=IN IP4 10.0.0.5 > b=TIAS:768000 > a=rtcp:4007 IN IP4 10.0.0.5 > a=sendrecv > a=rtpmap:97 H264/90000 > a=fmtp:97 profile-level-id=42000d > > I can reproduce it with pjsua-bin like so: > > git clone https://github.com/cisco/openh264.git > cd openh264 > make > sudo make install > cd .. > wget http://pjsip.org/release/2.8/pjproject-2.8.tar.bz2 > tar xvfj pjproject-2.8.tar.bz2 > cd pjproject-2.8 > ./configure > echo "#define PJMEDIA_HAS_VIDEO 1" >> pjlib/include/pj/config_site.h > make dep && make cd pjsip-apps/bin ./pjsua-x86_64-unknown-linux-gnu > --playback-dev=1 --capture-dev=1 --id sip:1@10.0.0.1 --registrar > sip:10.0.0.1 --realm "*" --username 1 --password hunter2 > --app-log-level=3 --video > > press m, enter sip:2@10.0.0.1 > Cisco phone on extension 2 rings, answer and press hold. Video goes to inactive, press hold button again to unhold call, video ends up still being inactive because of SDP negotiation problem. > I can work around the problem by registering a callback function, but that should not be needed in my opinion: > > diff --git a/pjsip-apps/src/pjsua/pjsua_app.c.bak > b/pjsip-apps/src/pjsua/pjsua_app.c > index 51c4537..db6066a 100644 > --- a/pjsip-apps/src/pjsua/pjsua_app.c.bak > +++ b/pjsip-apps/src/pjsua/pjsua_app.c > @@ -1226,6 +1226,12 @@ int stdout_refresh_proc(void *arg) > return 0; > } > > +static void > +ON_CALL_TX_OFFER_WORKAROUND(pjsua_call_id call_id, void *reserved, > + pjsua_call_setting *opt) { } > + > static pj_status_t app_init() > { > pjsua_transport_id transport_id = -1; @@ -1275,6 +1281,9 @@ > static pj_status_t app_init() > app_config.cfg.cb.on_nat_detect = &on_nat_detect; > app_config.cfg.cb.on_mwi_info = &on_mwi_info; > app_config.cfg.cb.on_transport_state = &on_transport_state; > + > + app_config.cfg.cb.on_call_tx_offer = > + &ON_CALL_TX_OFFER_WORKAROUND; > + > app_config.cfg.cb.on_ice_transport_error = &on_ice_transport_error; > app_config.cfg.cb.on_snd_dev_operation = &on_snd_dev_operation; > app_config.cfg.cb.on_call_media_event = &on_call_media_event; > > > > This seems to be a problem because of the late offer mechanism that cisco uses, and pjsua-lib only "re-initialize media before creating SDP" if there's a on_call_tx_offer callback set (or call->med_prov_cnt is 0), see pjsua_call_on_create_offer(). > This limitation does not seem to exist for things like pjsua_call_set_hold2(). But that's why the workaround gives a successful SDP negotiation: apply_call_setting() gets called. > Let me know if you need any pcap dumps demonstrating the problem. > > Please advise. > Br, > /Håkan > > _______________________________________________ > Visit our blog: http://blog.pjsip.org > > pjsip mailing list > pjsip@lists.pjsip.org > http://lists.pjsip.org/mailman/listinfo/pjsip_lists.pjsip.org _______________________________________________ Visit our blog: http://blog.pjsip.org pjsip mailing list pjsip@lists.pjsip.org http://lists.pjsip.org/mailman/listinfo/pjsip_lists.pjsip.org
M
Ming
Thu, Sep 27, 2018 4:20 AM

Hi Hakan,

I'm not sure if it's a bug. As far as I remember (perhaps you need to
search the RFC for this), sending INVITE without SDP doesn't
constitute an unhold request, and the recipient is then free to
provide an offer, which in this case, means that PJSIP will offer the
state of the currently active session.

If you want to change this behavior, your workaround is actually
already the solution, which is correctly implemented in the
application (pjsua_app is actually a sample app) and doesn't require
any modification within the library.

Regards,
Ming

On Wed, Sep 26, 2018 at 12:27 AM Håkan Berg hakan.berg@axis.com wrote:

Hi Ming,

Yes, you're correct. The remote is sending a re-INVITE without SDP when doing unhold.

Attaching log file.

Br,
/Håkan

-----Original Message-----
From: pjsip [mailto:pjsip-bounces@lists.pjsip.org] On Behalf Of Ming
Sent: den 25 september 2018 03:04
To: pjsip list pjsip@lists.pjsip.org
Subject: Re: [pjsip] Bug report: pjsua has no video on call unhold on cisco pbx

Hi Hakan,

Since I can't access the Cisco server from here, can you forward us the log (level 5, as text attachment)?

Based on your description, since app needs to overwrite callback on_call_tx_offer(), does it mean that the remote is sending re-INVITE without SDP when trying to unhold?

Regards,
Ming
On Mon, Sep 24, 2018 at 9:03 PM Håkan Berg hakan.berg@axis.com wrote:

Hi,
I believe I've found a problem in pjsua: When registered to a cisco unified call manager pbx (10.5 in my case) and calling to a video phone endpoint on that pbx, the video negotiation in pjsip fails if the endpoint phone puts pjsip on hold and then unhold again.
The SDP sent from pjsip seems to be missing vital video lines:
m=video 0 RTP/AVP 31
c=IN IP4 127.0.0.1
a=sendrecv

Whereas a working video SDP might include something like this:
m=video 4006 RTP/AVP 97
c=IN IP4 10.0.0.5
b=TIAS:768000
a=rtcp:4007 IN IP4 10.0.0.5
a=sendrecv
a=rtpmap:97 H264/90000
a=fmtp:97 profile-level-id=42000d

I can reproduce it with pjsua-bin like so:

git clone https://github.com/cisco/openh264.git
cd openh264
make
sudo make install
cd ..
wget http://pjsip.org/release/2.8/pjproject-2.8.tar.bz2
tar xvfj pjproject-2.8.tar.bz2
cd pjproject-2.8
./configure
echo "#define PJMEDIA_HAS_VIDEO 1" >> pjlib/include/pj/config_site.h
make dep && make cd pjsip-apps/bin ./pjsua-x86_64-unknown-linux-gnu
--playback-dev=1 --capture-dev=1 --id sip:1@10.0.0.1 --registrar
sip:10.0.0.1 --realm "*" --username 1 --password hunter2
--app-log-level=3 --video

press m, enter sip:2@10.0.0.1
Cisco phone on extension 2 rings, answer and press hold. Video goes to inactive, press hold button again to unhold call, video ends up still being inactive because of SDP negotiation problem.
I can work around the problem by registering a callback function, but that should not be needed in my opinion:

diff --git a/pjsip-apps/src/pjsua/pjsua_app.c.bak
b/pjsip-apps/src/pjsua/pjsua_app.c
index 51c4537..db6066a 100644
--- a/pjsip-apps/src/pjsua/pjsua_app.c.bak
+++ b/pjsip-apps/src/pjsua/pjsua_app.c
@@ -1226,6 +1226,12 @@ int stdout_refresh_proc(void *arg)
return 0;
}

+static void
+ON_CALL_TX_OFFER_WORKAROUND(pjsua_call_id call_id, void *reserved,

  •                        pjsua_call_setting *opt) { }
    

static pj_status_t app_init()
{
pjsua_transport_id transport_id = -1; @@ -1275,6 +1281,9 @@
static pj_status_t app_init()
app_config.cfg.cb.on_nat_detect = &on_nat_detect;
app_config.cfg.cb.on_mwi_info = &on_mwi_info;
app_config.cfg.cb.on_transport_state = &on_transport_state;
+

  • app_config.cfg.cb.on_call_tx_offer =
  • &ON_CALL_TX_OFFER_WORKAROUND;
  • app_config.cfg.cb.on_ice_transport_error = &on_ice_transport_error;
    app_config.cfg.cb.on_snd_dev_operation = &on_snd_dev_operation;
    app_config.cfg.cb.on_call_media_event = &on_call_media_event;

This seems to be a problem because of the late offer mechanism that cisco uses, and pjsua-lib only "re-initialize media before creating SDP" if there's a on_call_tx_offer callback set (or call->med_prov_cnt is 0), see pjsua_call_on_create_offer().
This limitation does not seem to exist for things like pjsua_call_set_hold2(). But that's why the workaround gives a successful SDP negotiation: apply_call_setting() gets called.
Let me know if you need any pcap dumps demonstrating the problem.

Please advise.
Br,
/Håkan


Visit our blog: http://blog.pjsip.org

pjsip mailing list
pjsip@lists.pjsip.org
http://lists.pjsip.org/mailman/listinfo/pjsip_lists.pjsip.org

Hi Hakan, I'm not sure if it's a bug. As far as I remember (perhaps you need to search the RFC for this), sending INVITE without SDP doesn't constitute an unhold request, and the recipient is then free to provide an offer, which in this case, means that PJSIP will offer the state of the currently active session. If you want to change this behavior, your workaround is actually already the solution, which is correctly implemented in the application (pjsua_app is actually a sample app) and doesn't require any modification within the library. Regards, Ming On Wed, Sep 26, 2018 at 12:27 AM Håkan Berg <hakan.berg@axis.com> wrote: > > Hi Ming, > > Yes, you're correct. The remote is sending a re-INVITE without SDP when doing unhold. > > Attaching log file. > > Br, > /Håkan > > -----Original Message----- > From: pjsip [mailto:pjsip-bounces@lists.pjsip.org] On Behalf Of Ming > Sent: den 25 september 2018 03:04 > To: pjsip list <pjsip@lists.pjsip.org> > Subject: Re: [pjsip] Bug report: pjsua has no video on call unhold on cisco pbx > > Hi Hakan, > > Since I can't access the Cisco server from here, can you forward us the log (level 5, as text attachment)? > > Based on your description, since app needs to overwrite callback on_call_tx_offer(), does it mean that the remote is sending re-INVITE without SDP when trying to unhold? > > Regards, > Ming > On Mon, Sep 24, 2018 at 9:03 PM Håkan Berg <hakan.berg@axis.com> wrote: > > > > Hi, > > I believe I've found a problem in pjsua: When registered to a cisco unified call manager pbx (10.5 in my case) and calling to a video phone endpoint on that pbx, the video negotiation in pjsip fails if the endpoint phone puts pjsip on hold and then unhold again. > > The SDP sent from pjsip seems to be missing vital video lines: > > m=video 0 RTP/AVP 31 > > c=IN IP4 127.0.0.1 > > a=sendrecv > > > > Whereas a working video SDP might include something like this: > > m=video 4006 RTP/AVP 97 > > c=IN IP4 10.0.0.5 > > b=TIAS:768000 > > a=rtcp:4007 IN IP4 10.0.0.5 > > a=sendrecv > > a=rtpmap:97 H264/90000 > > a=fmtp:97 profile-level-id=42000d > > > > I can reproduce it with pjsua-bin like so: > > > > git clone https://github.com/cisco/openh264.git > > cd openh264 > > make > > sudo make install > > cd .. > > wget http://pjsip.org/release/2.8/pjproject-2.8.tar.bz2 > > tar xvfj pjproject-2.8.tar.bz2 > > cd pjproject-2.8 > > ./configure > > echo "#define PJMEDIA_HAS_VIDEO 1" >> pjlib/include/pj/config_site.h > > make dep && make cd pjsip-apps/bin ./pjsua-x86_64-unknown-linux-gnu > > --playback-dev=1 --capture-dev=1 --id sip:1@10.0.0.1 --registrar > > sip:10.0.0.1 --realm "*" --username 1 --password hunter2 > > --app-log-level=3 --video > > > > press m, enter sip:2@10.0.0.1 > > Cisco phone on extension 2 rings, answer and press hold. Video goes to inactive, press hold button again to unhold call, video ends up still being inactive because of SDP negotiation problem. > > I can work around the problem by registering a callback function, but that should not be needed in my opinion: > > > > diff --git a/pjsip-apps/src/pjsua/pjsua_app.c.bak > > b/pjsip-apps/src/pjsua/pjsua_app.c > > index 51c4537..db6066a 100644 > > --- a/pjsip-apps/src/pjsua/pjsua_app.c.bak > > +++ b/pjsip-apps/src/pjsua/pjsua_app.c > > @@ -1226,6 +1226,12 @@ int stdout_refresh_proc(void *arg) > > return 0; > > } > > > > +static void > > +ON_CALL_TX_OFFER_WORKAROUND(pjsua_call_id call_id, void *reserved, > > + pjsua_call_setting *opt) { } > > + > > static pj_status_t app_init() > > { > > pjsua_transport_id transport_id = -1; @@ -1275,6 +1281,9 @@ > > static pj_status_t app_init() > > app_config.cfg.cb.on_nat_detect = &on_nat_detect; > > app_config.cfg.cb.on_mwi_info = &on_mwi_info; > > app_config.cfg.cb.on_transport_state = &on_transport_state; > > + > > + app_config.cfg.cb.on_call_tx_offer = > > + &ON_CALL_TX_OFFER_WORKAROUND; > > + > > app_config.cfg.cb.on_ice_transport_error = &on_ice_transport_error; > > app_config.cfg.cb.on_snd_dev_operation = &on_snd_dev_operation; > > app_config.cfg.cb.on_call_media_event = &on_call_media_event; > > > > > > > > This seems to be a problem because of the late offer mechanism that cisco uses, and pjsua-lib only "re-initialize media before creating SDP" if there's a on_call_tx_offer callback set (or call->med_prov_cnt is 0), see pjsua_call_on_create_offer(). > > This limitation does not seem to exist for things like pjsua_call_set_hold2(). But that's why the workaround gives a successful SDP negotiation: apply_call_setting() gets called. > > Let me know if you need any pcap dumps demonstrating the problem. > > > > Please advise. > > Br, > > /Håkan > > > > _______________________________________________ > > Visit our blog: http://blog.pjsip.org > > > > pjsip mailing list > > pjsip@lists.pjsip.org > > http://lists.pjsip.org/mailman/listinfo/pjsip_lists.pjsip.org > > _______________________________________________ > Visit our blog: http://blog.pjsip.org > > pjsip mailing list > pjsip@lists.pjsip.org > http://lists.pjsip.org/mailman/listinfo/pjsip_lists.pjsip.org > _______________________________________________ > Visit our blog: http://blog.pjsip.org > > pjsip mailing list > pjsip@lists.pjsip.org > http://lists.pjsip.org/mailman/listinfo/pjsip_lists.pjsip.org
HB
Håkan Berg
Thu, Sep 27, 2018 5:48 AM

Hi Ming,

I agree that the recipient is free to provide an offer, but in this case it does not make sense for pjsip to provide an offer with a broken sdp in it, and the pjsua app should not have to register a callback to fix that.

Looking at the problematic last offer sent from pjsip, it has a line like
(m): video 0 RTP/AVP 31
but no correseponding rtpmap, and most previous offers from pjsip in that session does have correct and working SDPs with a resulting good video received by the remote.

Why would pjsip offer an SDP that effectively renders video inactive? I would argue that’s done because of the bug, namely apply_call_setting() not being called, and bogus default data happens to be placed in the SDP.

From the log, the problematic offer from pjsip when remote wants to unhold:

08:31:19.248          pjsua_call.c  ......Call 0: asked to send a new offer
08:31:19.248          inv0x20161f8  ......Sending Response msg 200/INVITE/cseq=104 (tdta0x7f1f5c93c468)
08:31:19.248          dlg0x20161f8  .......Sending Response msg 200/INVITE/cseq=104 (tdta0x7f1f5c93c468)
08:31:19.248      tsx0x7f1f5c002cc8  .......Sending Response msg 200/INVITE/cseq=104 (tdta0x7f1f5c93c468)
in state Trying
08:31:19.248          sip_resolve.c  ........Target '10.0.0.1:5060' type=UDP resolved to '10.0.0.1:5060'
type=UDP (UDP transport)
08:31:19.248          pjsua_core.c  ........TX 1172 bytes Response msg 200/INVITE/cseq=104 (tdta0x7f1f5c
93c468) to UDP 10.0.0.1:5060:
SIP/2.0 200 OK
Via: SIP/2.0/UDP 10.0.0.1:5060;received=10.0.0.1;branch=z9hG4bKac752b67ba38
Call-ID: 62523409-8a14-469c-8352-3832a7de0701
From: sip:1012@10.0.0.1;tag=207142~4be90327-72fd-4c7c-9d1d-8e146fc96532-20849481
To: sip:7004@10.0.0.1;tag=b31381ed-00e1-4dc3-82f8-3f4368805895
CSeq: 104 INVITE
Session-Expires: 1800;refresher=uac
Require: timer
Contact: sip:7004@10.0.0.5:5060;ob
Allow: PRACK, INVITE, ACK, BYE, CANCEL, UPDATE, INFO, SUBSCRIBE, NOTIFY, REFER, MESSAGE, OPTIONS
Supported: replaces, 100rel, timer, norefersub
Content-Type: application/sdp
Content-Length:  550

v=0
o=- 3746845864 3746845868 IN IP4 10.0.0.5
s=pjmedia
b=AS:84
t=0 0
a=X-nat:0
m=audio 4000 RTP/AVP 98 97 99 104 3 0 8 9 96
c=IN IP4 10.0.0.5
b=TIAS:64000
a=rtcp:4001 IN IP4 10.0.0.5
a=sendrecv
a=rtpmap:98 speex/16000
a=rtpmap:97 speex/8000
a=rtpmap:99 speex/32000
a=rtpmap:104 iLBC/8000
a=fmtp:104 mode=30
a=rtpmap:3 GSM/8000
a=rtpmap:0 PCMU/8000
a=rtpmap:8 PCMA/8000
a=rtpmap:9 G722/8000
a=rtpmap:96 telephone-event/8000
a=fmtp:96 0-16
a=ssrc:219786230 cname:54ddf01b2db5c07e
m=video 0 RTP/AVP 31
c=IN IP4 127.0.0.1

--end msg--

From the log, an earlier request for pjsip to send a new offer, working as intended:

08:31:14.575          pjsua_call.c  ......Call 0: asked to send a new offer
08:31:14.575          inv0x20161f8  ......Sending Response msg 200/INVITE/cseq=102 (tdta0x7f1f5c93f6a8)
08:31:14.575          dlg0x20161f8  .......Sending Response msg 200/INVITE/cseq=102 (tdta0x7f1f5c93f6a8)
08:31:14.575      tsx0x7f1f5c002cc8  .......Sending Response msg 200/INVITE/cseq=102 (tdta0x7f1f5c93f6a8)
in state Trying
08:31:14.575          sip_resolve.c  ........Target '10.0.0.1:5060' type=UDP resolved to '10.0.0.1:5060'
type=UDP (UDP transport)
08:31:14.575          pjsua_core.c  ........TX 1358 bytes Response msg 200/INVITE/cseq=102 (tdta0x7f1f5c
93f6a8) to UDP 10.0.0.1:5060:
SIP/2.0 200 OK
Via: SIP/2.0/UDP 10.0.0.1:5060;received=10.0.0.1;branch=z9hG4bKac713bbfb438
Call-ID: 62523409-8a14-469c-8352-3832a7de0701
From: sip:1012@10.0.0.1;tag=207142~4be90327-72fd-4c7c-9d1d-8e146fc96532-20849481
To: sip:7004@10.0.0.1;tag=b31381ed-00e1-4dc3-82f8-3f4368805895
CSeq: 102 INVITE
Session-Expires: 1800;refresher=uac
Require: timer
Contact: sip:7004@10.0.0.5:5060;ob
Allow: PRACK, INVITE, ACK, BYE, CANCEL, UPDATE, INFO, SUBSCRIBE, NOTIFY, REFER, MESSAGE, OPTIONS
Supported: replaces, 100rel, timer, norefersub
Content-Type: application/sdp
Content-Length:  736

v=0
o=- 3746845864 3746845866 IN IP4 10.0.0.5
s=pjmedia
b=AS:352
t=0 0
a=X-nat:0
m=audio 4000 RTP/AVP 98 97 99 104 3 0 8 9 96
c=IN IP4 10.0.0.5
b=TIAS:64000
a=rtcp:4001 IN IP4 10.0.0.5
a=sendrecv
a=rtpmap:98 speex/16000
a=rtpmap:97 speex/8000
a=rtpmap:99 speex/32000
a=rtpmap:104 iLBC/8000
a=fmtp:104 mode=30
a=rtpmap:3 GSM/8000
a=rtpmap:0 PCMU/8000
a=rtpmap:8 PCMA/8000
a=rtpmap:9 G722/8000
a=rtpmap:96 telephone-event/8000
a=fmtp:96 0-16
a=ssrc:219786230 cname:54ddf01b2db5c07e
m=video 4002 RTP/AVP 97
c=IN IP4 10.0.0.5
b=TIAS:256000
a=rtcp:4003 IN IP4 10.0.0.5
a=sendrecv
a=rtpmap:97 H264/90000
a=fmtp:97 profile-level-id=42e01e; packetization-mode=1
a=ssrc:1687763237 cname:54ddf01b2db5c07e

--end msg--

Let me know if you need gdb logs demonstrating the issue.

Thank you for looking into this.
Br,
/Håkan

-----Original Message-----
From: pjsip [mailto:pjsip-bounces@lists.pjsip.org] On Behalf Of Ming
Sent: den 27 september 2018 06:20
To: pjsip list pjsip@lists.pjsip.org
Subject: Re: [pjsip] Bug report: pjsua has no video on call unhold on cisco pbx

Hi Hakan,

I'm not sure if it's a bug. As far as I remember (perhaps you need to search the RFC for this), sending INVITE without SDP doesn't constitute an unhold request, and the recipient is then free to provide an offer, which in this case, means that PJSIP will offer the state of the currently active session.

If you want to change this behavior, your workaround is actually already the solution, which is correctly implemented in the application (pjsua_app is actually a sample app) and doesn't require any modification within the library.

Regards,
Ming

On Wed, Sep 26, 2018 at 12:27 AM Håkan Berg hakan.berg@axis.com wrote:

Hi Ming,

Yes, you're correct. The remote is sending a re-INVITE without SDP when doing unhold.

Attaching log file.

Br,
/Håkan

-----Original Message-----
From: pjsip [mailto:pjsip-bounces@lists.pjsip.org] On Behalf Of Ming
Sent: den 25 september 2018 03:04
To: pjsip list pjsip@lists.pjsip.org
Subject: Re: [pjsip] Bug report: pjsua has no video on call unhold on
cisco pbx

Hi Hakan,

Since I can't access the Cisco server from here, can you forward us the log (level 5, as text attachment)?

Based on your description, since app needs to overwrite callback on_call_tx_offer(), does it mean that the remote is sending re-INVITE without SDP when trying to unhold?

Regards,
Ming
On Mon, Sep 24, 2018 at 9:03 PM Håkan Berg hakan.berg@axis.com wrote:

Hi,
I believe I've found a problem in pjsua: When registered to a cisco unified call manager pbx (10.5 in my case) and calling to a video phone endpoint on that pbx, the video negotiation in pjsip fails if the endpoint phone puts pjsip on hold and then unhold again.
The SDP sent from pjsip seems to be missing vital video lines:
m=video 0 RTP/AVP 31
c=IN IP4 127.0.0.1
a=sendrecv

Whereas a working video SDP might include something like this:
m=video 4006 RTP/AVP 97
c=IN IP4 10.0.0.5
b=TIAS:768000
a=rtcp:4007 IN IP4 10.0.0.5
a=sendrecv
a=rtpmap:97 H264/90000
a=fmtp:97 profile-level-id=42000d

I can reproduce it with pjsua-bin like so:

git clone https://github.com/cisco/openh264.git
cd openh264
make
sudo make install
cd ..
wget http://pjsip.org/release/2.8/pjproject-2.8.tar.bz2
tar xvfj pjproject-2.8.tar.bz2
cd pjproject-2.8
./configure
echo "#define PJMEDIA_HAS_VIDEO 1" >> pjlib/include/pj/config_site.h
make dep && make cd pjsip-apps/bin ./pjsua-x86_64-unknown-linux-gnu
--playback-dev=1 --capture-dev=1 --id sip:1@10.0.0.1 --registrar
sip:10.0.0.1 --realm "*" --username 1 --password hunter2
--app-log-level=3 --video

press m, enter sip:2@10.0.0.1
Cisco phone on extension 2 rings, answer and press hold. Video goes to inactive, press hold button again to unhold call, video ends up still being inactive because of SDP negotiation problem.
I can work around the problem by registering a callback function, but that should not be needed in my opinion:

diff --git a/pjsip-apps/src/pjsua/pjsua_app.c.bak
b/pjsip-apps/src/pjsua/pjsua_app.c
index 51c4537..db6066a 100644
--- a/pjsip-apps/src/pjsua/pjsua_app.c.bak
+++ b/pjsip-apps/src/pjsua/pjsua_app.c
@@ -1226,6 +1226,12 @@ int stdout_refresh_proc(void *arg)
return 0;
}

+static void
+ON_CALL_TX_OFFER_WORKAROUND(pjsua_call_id call_id, void *reserved,

  •                        pjsua_call_setting *opt) { }
    

static pj_status_t app_init()
{
pjsua_transport_id transport_id = -1; @@ -1275,6 +1281,9 @@
static pj_status_t app_init()
app_config.cfg.cb.on_nat_detect = &on_nat_detect;
app_config.cfg.cb.on_mwi_info = &on_mwi_info;
app_config.cfg.cb.on_transport_state = &on_transport_state;
+

  • app_config.cfg.cb.on_call_tx_offer =
  • &ON_CALL_TX_OFFER_WORKAROUND;
  • app_config.cfg.cb.on_ice_transport_error = &on_ice_transport_error;
    app_config.cfg.cb.on_snd_dev_operation = &on_snd_dev_operation;
    app_config.cfg.cb.on_call_media_event = &on_call_media_event;

This seems to be a problem because of the late offer mechanism that cisco uses, and pjsua-lib only "re-initialize media before creating SDP" if there's a on_call_tx_offer callback set (or call->med_prov_cnt is 0), see pjsua_call_on_create_offer().
This limitation does not seem to exist for things like pjsua_call_set_hold2(). But that's why the workaround gives a successful SDP negotiation: apply_call_setting() gets called.
Let me know if you need any pcap dumps demonstrating the problem.

Please advise.
Br,
/Håkan


Visit our blog: http://blog.pjsip.org

pjsip mailing list
pjsip@lists.pjsip.org
http://lists.pjsip.org/mailman/listinfo/pjsip_lists.pjsip.org

Hi Ming, I agree that the recipient is free to provide an offer, but in this case it does not make sense for pjsip to provide an offer with a broken sdp in it, and the pjsua app should not have to register a callback to fix that. Looking at the problematic last offer sent from pjsip, it has a line like (m): video 0 RTP/AVP 31 but no correseponding rtpmap, and most previous offers from pjsip in that session does have correct and working SDPs with a resulting good video received by the remote. Why would pjsip offer an SDP that effectively renders video inactive? I would argue that’s done because of the bug, namely apply_call_setting() not being called, and bogus default data happens to be placed in the SDP. From the log, the problematic offer from pjsip when remote wants to unhold: 08:31:19.248 pjsua_call.c ......Call 0: asked to send a new offer 08:31:19.248 inv0x20161f8 ......Sending Response msg 200/INVITE/cseq=104 (tdta0x7f1f5c93c468) 08:31:19.248 dlg0x20161f8 .......Sending Response msg 200/INVITE/cseq=104 (tdta0x7f1f5c93c468) 08:31:19.248 tsx0x7f1f5c002cc8 .......Sending Response msg 200/INVITE/cseq=104 (tdta0x7f1f5c93c468) in state Trying 08:31:19.248 sip_resolve.c ........Target '10.0.0.1:5060' type=UDP resolved to '10.0.0.1:5060' type=UDP (UDP transport) 08:31:19.248 pjsua_core.c ........TX 1172 bytes Response msg 200/INVITE/cseq=104 (tdta0x7f1f5c 93c468) to UDP 10.0.0.1:5060: SIP/2.0 200 OK Via: SIP/2.0/UDP 10.0.0.1:5060;received=10.0.0.1;branch=z9hG4bKac752b67ba38 Call-ID: 62523409-8a14-469c-8352-3832a7de0701 From: <sip:1012@10.0.0.1>;tag=207142~4be90327-72fd-4c7c-9d1d-8e146fc96532-20849481 To: <sip:7004@10.0.0.1>;tag=b31381ed-00e1-4dc3-82f8-3f4368805895 CSeq: 104 INVITE Session-Expires: 1800;refresher=uac Require: timer Contact: <sip:7004@10.0.0.5:5060;ob> Allow: PRACK, INVITE, ACK, BYE, CANCEL, UPDATE, INFO, SUBSCRIBE, NOTIFY, REFER, MESSAGE, OPTIONS Supported: replaces, 100rel, timer, norefersub Content-Type: application/sdp Content-Length: 550 v=0 o=- 3746845864 3746845868 IN IP4 10.0.0.5 s=pjmedia b=AS:84 t=0 0 a=X-nat:0 m=audio 4000 RTP/AVP 98 97 99 104 3 0 8 9 96 c=IN IP4 10.0.0.5 b=TIAS:64000 a=rtcp:4001 IN IP4 10.0.0.5 a=sendrecv a=rtpmap:98 speex/16000 a=rtpmap:97 speex/8000 a=rtpmap:99 speex/32000 a=rtpmap:104 iLBC/8000 a=fmtp:104 mode=30 a=rtpmap:3 GSM/8000 a=rtpmap:0 PCMU/8000 a=rtpmap:8 PCMA/8000 a=rtpmap:9 G722/8000 a=rtpmap:96 telephone-event/8000 a=fmtp:96 0-16 a=ssrc:219786230 cname:54ddf01b2db5c07e m=video 0 RTP/AVP 31 c=IN IP4 127.0.0.1 --end msg-- From the log, an earlier request for pjsip to send a new offer, working as intended: 08:31:14.575 pjsua_call.c ......Call 0: asked to send a new offer 08:31:14.575 inv0x20161f8 ......Sending Response msg 200/INVITE/cseq=102 (tdta0x7f1f5c93f6a8) 08:31:14.575 dlg0x20161f8 .......Sending Response msg 200/INVITE/cseq=102 (tdta0x7f1f5c93f6a8) 08:31:14.575 tsx0x7f1f5c002cc8 .......Sending Response msg 200/INVITE/cseq=102 (tdta0x7f1f5c93f6a8) in state Trying 08:31:14.575 sip_resolve.c ........Target '10.0.0.1:5060' type=UDP resolved to '10.0.0.1:5060' type=UDP (UDP transport) 08:31:14.575 pjsua_core.c ........TX 1358 bytes Response msg 200/INVITE/cseq=102 (tdta0x7f1f5c 93f6a8) to UDP 10.0.0.1:5060: SIP/2.0 200 OK Via: SIP/2.0/UDP 10.0.0.1:5060;received=10.0.0.1;branch=z9hG4bKac713bbfb438 Call-ID: 62523409-8a14-469c-8352-3832a7de0701 From: <sip:1012@10.0.0.1>;tag=207142~4be90327-72fd-4c7c-9d1d-8e146fc96532-20849481 To: <sip:7004@10.0.0.1>;tag=b31381ed-00e1-4dc3-82f8-3f4368805895 CSeq: 102 INVITE Session-Expires: 1800;refresher=uac Require: timer Contact: <sip:7004@10.0.0.5:5060;ob> Allow: PRACK, INVITE, ACK, BYE, CANCEL, UPDATE, INFO, SUBSCRIBE, NOTIFY, REFER, MESSAGE, OPTIONS Supported: replaces, 100rel, timer, norefersub Content-Type: application/sdp Content-Length: 736 v=0 o=- 3746845864 3746845866 IN IP4 10.0.0.5 s=pjmedia b=AS:352 t=0 0 a=X-nat:0 m=audio 4000 RTP/AVP 98 97 99 104 3 0 8 9 96 c=IN IP4 10.0.0.5 b=TIAS:64000 a=rtcp:4001 IN IP4 10.0.0.5 a=sendrecv a=rtpmap:98 speex/16000 a=rtpmap:97 speex/8000 a=rtpmap:99 speex/32000 a=rtpmap:104 iLBC/8000 a=fmtp:104 mode=30 a=rtpmap:3 GSM/8000 a=rtpmap:0 PCMU/8000 a=rtpmap:8 PCMA/8000 a=rtpmap:9 G722/8000 a=rtpmap:96 telephone-event/8000 a=fmtp:96 0-16 a=ssrc:219786230 cname:54ddf01b2db5c07e m=video 4002 RTP/AVP 97 c=IN IP4 10.0.0.5 b=TIAS:256000 a=rtcp:4003 IN IP4 10.0.0.5 a=sendrecv a=rtpmap:97 H264/90000 a=fmtp:97 profile-level-id=42e01e; packetization-mode=1 a=ssrc:1687763237 cname:54ddf01b2db5c07e --end msg-- Let me know if you need gdb logs demonstrating the issue. Thank you for looking into this. Br, /Håkan -----Original Message----- From: pjsip [mailto:pjsip-bounces@lists.pjsip.org] On Behalf Of Ming Sent: den 27 september 2018 06:20 To: pjsip list <pjsip@lists.pjsip.org> Subject: Re: [pjsip] Bug report: pjsua has no video on call unhold on cisco pbx Hi Hakan, I'm not sure if it's a bug. As far as I remember (perhaps you need to search the RFC for this), sending INVITE without SDP doesn't constitute an unhold request, and the recipient is then free to provide an offer, which in this case, means that PJSIP will offer the state of the currently active session. If you want to change this behavior, your workaround is actually already the solution, which is correctly implemented in the application (pjsua_app is actually a sample app) and doesn't require any modification within the library. Regards, Ming On Wed, Sep 26, 2018 at 12:27 AM Håkan Berg <hakan.berg@axis.com> wrote: > > Hi Ming, > > Yes, you're correct. The remote is sending a re-INVITE without SDP when doing unhold. > > Attaching log file. > > Br, > /Håkan > > -----Original Message----- > From: pjsip [mailto:pjsip-bounces@lists.pjsip.org] On Behalf Of Ming > Sent: den 25 september 2018 03:04 > To: pjsip list <pjsip@lists.pjsip.org> > Subject: Re: [pjsip] Bug report: pjsua has no video on call unhold on > cisco pbx > > Hi Hakan, > > Since I can't access the Cisco server from here, can you forward us the log (level 5, as text attachment)? > > Based on your description, since app needs to overwrite callback on_call_tx_offer(), does it mean that the remote is sending re-INVITE without SDP when trying to unhold? > > Regards, > Ming > On Mon, Sep 24, 2018 at 9:03 PM Håkan Berg <hakan.berg@axis.com> wrote: > > > > Hi, > > I believe I've found a problem in pjsua: When registered to a cisco unified call manager pbx (10.5 in my case) and calling to a video phone endpoint on that pbx, the video negotiation in pjsip fails if the endpoint phone puts pjsip on hold and then unhold again. > > The SDP sent from pjsip seems to be missing vital video lines: > > m=video 0 RTP/AVP 31 > > c=IN IP4 127.0.0.1 > > a=sendrecv > > > > Whereas a working video SDP might include something like this: > > m=video 4006 RTP/AVP 97 > > c=IN IP4 10.0.0.5 > > b=TIAS:768000 > > a=rtcp:4007 IN IP4 10.0.0.5 > > a=sendrecv > > a=rtpmap:97 H264/90000 > > a=fmtp:97 profile-level-id=42000d > > > > I can reproduce it with pjsua-bin like so: > > > > git clone https://github.com/cisco/openh264.git > > cd openh264 > > make > > sudo make install > > cd .. > > wget http://pjsip.org/release/2.8/pjproject-2.8.tar.bz2 > > tar xvfj pjproject-2.8.tar.bz2 > > cd pjproject-2.8 > > ./configure > > echo "#define PJMEDIA_HAS_VIDEO 1" >> pjlib/include/pj/config_site.h > > make dep && make cd pjsip-apps/bin ./pjsua-x86_64-unknown-linux-gnu > > --playback-dev=1 --capture-dev=1 --id sip:1@10.0.0.1 --registrar > > sip:10.0.0.1 --realm "*" --username 1 --password hunter2 > > --app-log-level=3 --video > > > > press m, enter sip:2@10.0.0.1 > > Cisco phone on extension 2 rings, answer and press hold. Video goes to inactive, press hold button again to unhold call, video ends up still being inactive because of SDP negotiation problem. > > I can work around the problem by registering a callback function, but that should not be needed in my opinion: > > > > diff --git a/pjsip-apps/src/pjsua/pjsua_app.c.bak > > b/pjsip-apps/src/pjsua/pjsua_app.c > > index 51c4537..db6066a 100644 > > --- a/pjsip-apps/src/pjsua/pjsua_app.c.bak > > +++ b/pjsip-apps/src/pjsua/pjsua_app.c > > @@ -1226,6 +1226,12 @@ int stdout_refresh_proc(void *arg) > > return 0; > > } > > > > +static void > > +ON_CALL_TX_OFFER_WORKAROUND(pjsua_call_id call_id, void *reserved, > > + pjsua_call_setting *opt) { } > > + > > static pj_status_t app_init() > > { > > pjsua_transport_id transport_id = -1; @@ -1275,6 +1281,9 @@ > > static pj_status_t app_init() > > app_config.cfg.cb.on_nat_detect = &on_nat_detect; > > app_config.cfg.cb.on_mwi_info = &on_mwi_info; > > app_config.cfg.cb.on_transport_state = &on_transport_state; > > + > > + app_config.cfg.cb.on_call_tx_offer = > > + &ON_CALL_TX_OFFER_WORKAROUND; > > + > > app_config.cfg.cb.on_ice_transport_error = &on_ice_transport_error; > > app_config.cfg.cb.on_snd_dev_operation = &on_snd_dev_operation; > > app_config.cfg.cb.on_call_media_event = &on_call_media_event; > > > > > > > > This seems to be a problem because of the late offer mechanism that cisco uses, and pjsua-lib only "re-initialize media before creating SDP" if there's a on_call_tx_offer callback set (or call->med_prov_cnt is 0), see pjsua_call_on_create_offer(). > > This limitation does not seem to exist for things like pjsua_call_set_hold2(). But that's why the workaround gives a successful SDP negotiation: apply_call_setting() gets called. > > Let me know if you need any pcap dumps demonstrating the problem. > > > > Please advise. > > Br, > > /Håkan > > > > _______________________________________________ > > Visit our blog: http://blog.pjsip.org > > > > pjsip mailing list > > pjsip@lists.pjsip.org > > http://lists.pjsip.org/mailman/listinfo/pjsip_lists.pjsip.org > > _______________________________________________ > Visit our blog: http://blog.pjsip.org > > pjsip mailing list > pjsip@lists.pjsip.org > http://lists.pjsip.org/mailman/listinfo/pjsip_lists.pjsip.org > _______________________________________________ > Visit our blog: http://blog.pjsip.org > > pjsip mailing list > pjsip@lists.pjsip.org > http://lists.pjsip.org/mailman/listinfo/pjsip_lists.pjsip.org _______________________________________________ Visit our blog: http://blog.pjsip.org pjsip mailing list pjsip@lists.pjsip.org http://lists.pjsip.org/mailman/listinfo/pjsip_lists.pjsip.org
M
Ming
Fri, Sep 28, 2018 1:34 AM

Hi Hakan,

The SDP is actually perfectly fine.

https://tools.ietf.org/html/rfc4566#section-6
Although an RTP profile may make static assignments of payload
type numbers to payload formats, it is more common for that
assignment to be done dynamically using "a=rtpmap:" attributes.
As an example of a static payload type, consider u-law PCM
coded single-channel audio sampled at 8 kHz.  This is
completely defined in the RTP Audio/Video profile as payload
type 0, so there is no need for an "a=rtpmap:" attribute

31 is a static payload type, which corresponds to H261

An example can be found here:
https://www.rfc-editor.org/rfc/rfc3264.txt
search for (m=video 0)

As for the disabled video, it's because in the previous offer, remote
requested it and it has been accepted (below is the summarized
message):
08:31:19.240          pjsua_core.c  .RX 1299 bytes Request msg
INVITE/cseq=103 (rdata0x7f1f5c0008e8) from UDP 10.0.0.1:5060:
INVITE sip:7004@10.0.0.5:5060;ob SIP/2.0
CSeq: 103 INVITE
m=video 0 RTP/AVP 126
a=inactive

Best regards,
Ming

On Thu, Sep 27, 2018 at 1:48 PM, Håkan Berg hakan.berg@axis.com wrote:

Hi Ming,

I agree that the recipient is free to provide an offer, but in this case it does not make sense for pjsip to provide an offer with a broken sdp in it, and the pjsua app should not have to register a callback to fix that.

Looking at the problematic last offer sent from pjsip, it has a line like
(m): video 0 RTP/AVP 31
but no correseponding rtpmap, and most previous offers from pjsip in that session does have correct and working SDPs with a resulting good video received by the remote.

Why would pjsip offer an SDP that effectively renders video inactive? I would argue that’s done because of the bug, namely apply_call_setting() not being called, and bogus default data happens to be placed in the SDP.

From the log, the problematic offer from pjsip when remote wants to unhold:

08:31:19.248          pjsua_call.c  ......Call 0: asked to send a new offer
08:31:19.248          inv0x20161f8  ......Sending Response msg 200/INVITE/cseq=104 (tdta0x7f1f5c93c468)
08:31:19.248          dlg0x20161f8  .......Sending Response msg 200/INVITE/cseq=104 (tdta0x7f1f5c93c468)
08:31:19.248      tsx0x7f1f5c002cc8  .......Sending Response msg 200/INVITE/cseq=104 (tdta0x7f1f5c93c468)
in state Trying
08:31:19.248          sip_resolve.c  ........Target '10.0.0.1:5060' type=UDP resolved to '10.0.0.1:5060'
type=UDP (UDP transport)
08:31:19.248          pjsua_core.c  ........TX 1172 bytes Response msg 200/INVITE/cseq=104 (tdta0x7f1f5c
93c468) to UDP 10.0.0.1:5060:
SIP/2.0 200 OK
Via: SIP/2.0/UDP 10.0.0.1:5060;received=10.0.0.1;branch=z9hG4bKac752b67ba38
Call-ID: 62523409-8a14-469c-8352-3832a7de0701
From: sip:1012@10.0.0.1;tag=207142~4be90327-72fd-4c7c-9d1d-8e146fc96532-20849481
To: sip:7004@10.0.0.1;tag=b31381ed-00e1-4dc3-82f8-3f4368805895
CSeq: 104 INVITE
Session-Expires: 1800;refresher=uac
Require: timer
Contact: sip:7004@10.0.0.5:5060;ob
Allow: PRACK, INVITE, ACK, BYE, CANCEL, UPDATE, INFO, SUBSCRIBE, NOTIFY, REFER, MESSAGE, OPTIONS
Supported: replaces, 100rel, timer, norefersub
Content-Type: application/sdp
Content-Length:  550

v=0
o=- 3746845864 3746845868 IN IP4 10.0.0.5
s=pjmedia
b=AS:84
t=0 0
a=X-nat:0
m=audio 4000 RTP/AVP 98 97 99 104 3 0 8 9 96
c=IN IP4 10.0.0.5
b=TIAS:64000
a=rtcp:4001 IN IP4 10.0.0.5
a=sendrecv
a=rtpmap:98 speex/16000
a=rtpmap:97 speex/8000
a=rtpmap:99 speex/32000
a=rtpmap:104 iLBC/8000
a=fmtp:104 mode=30
a=rtpmap:3 GSM/8000
a=rtpmap:0 PCMU/8000
a=rtpmap:8 PCMA/8000
a=rtpmap:9 G722/8000
a=rtpmap:96 telephone-event/8000
a=fmtp:96 0-16
a=ssrc:219786230 cname:54ddf01b2db5c07e
m=video 0 RTP/AVP 31
c=IN IP4 127.0.0.1

--end msg--

From the log, an earlier request for pjsip to send a new offer, working as intended:

08:31:14.575          pjsua_call.c  ......Call 0: asked to send a new offer
08:31:14.575          inv0x20161f8  ......Sending Response msg 200/INVITE/cseq=102 (tdta0x7f1f5c93f6a8)
08:31:14.575          dlg0x20161f8  .......Sending Response msg 200/INVITE/cseq=102 (tdta0x7f1f5c93f6a8)
08:31:14.575      tsx0x7f1f5c002cc8  .......Sending Response msg 200/INVITE/cseq=102 (tdta0x7f1f5c93f6a8)
in state Trying
08:31:14.575          sip_resolve.c  ........Target '10.0.0.1:5060' type=UDP resolved to '10.0.0.1:5060'
type=UDP (UDP transport)
08:31:14.575          pjsua_core.c  ........TX 1358 bytes Response msg 200/INVITE/cseq=102 (tdta0x7f1f5c
93f6a8) to UDP 10.0.0.1:5060:
SIP/2.0 200 OK
Via: SIP/2.0/UDP 10.0.0.1:5060;received=10.0.0.1;branch=z9hG4bKac713bbfb438
Call-ID: 62523409-8a14-469c-8352-3832a7de0701
From: sip:1012@10.0.0.1;tag=207142~4be90327-72fd-4c7c-9d1d-8e146fc96532-20849481
To: sip:7004@10.0.0.1;tag=b31381ed-00e1-4dc3-82f8-3f4368805895
CSeq: 102 INVITE
Session-Expires: 1800;refresher=uac
Require: timer
Contact: sip:7004@10.0.0.5:5060;ob
Allow: PRACK, INVITE, ACK, BYE, CANCEL, UPDATE, INFO, SUBSCRIBE, NOTIFY, REFER, MESSAGE, OPTIONS
Supported: replaces, 100rel, timer, norefersub
Content-Type: application/sdp
Content-Length:  736

v=0
o=- 3746845864 3746845866 IN IP4 10.0.0.5
s=pjmedia
b=AS:352
t=0 0
a=X-nat:0
m=audio 4000 RTP/AVP 98 97 99 104 3 0 8 9 96
c=IN IP4 10.0.0.5
b=TIAS:64000
a=rtcp:4001 IN IP4 10.0.0.5
a=sendrecv
a=rtpmap:98 speex/16000
a=rtpmap:97 speex/8000
a=rtpmap:99 speex/32000
a=rtpmap:104 iLBC/8000
a=fmtp:104 mode=30
a=rtpmap:3 GSM/8000
a=rtpmap:0 PCMU/8000
a=rtpmap:8 PCMA/8000
a=rtpmap:9 G722/8000
a=rtpmap:96 telephone-event/8000
a=fmtp:96 0-16
a=ssrc:219786230 cname:54ddf01b2db5c07e
m=video 4002 RTP/AVP 97
c=IN IP4 10.0.0.5
b=TIAS:256000
a=rtcp:4003 IN IP4 10.0.0.5
a=sendrecv
a=rtpmap:97 H264/90000
a=fmtp:97 profile-level-id=42e01e; packetization-mode=1
a=ssrc:1687763237 cname:54ddf01b2db5c07e

--end msg--

Let me know if you need gdb logs demonstrating the issue.

Thank you for looking into this.
Br,
/Håkan

-----Original Message-----
From: pjsip [mailto:pjsip-bounces@lists.pjsip.org] On Behalf Of Ming
Sent: den 27 september 2018 06:20
To: pjsip list pjsip@lists.pjsip.org
Subject: Re: [pjsip] Bug report: pjsua has no video on call unhold on cisco pbx

Hi Hakan,

I'm not sure if it's a bug. As far as I remember (perhaps you need to search the RFC for this), sending INVITE without SDP doesn't constitute an unhold request, and the recipient is then free to provide an offer, which in this case, means that PJSIP will offer the state of the currently active session.

If you want to change this behavior, your workaround is actually already the solution, which is correctly implemented in the application (pjsua_app is actually a sample app) and doesn't require any modification within the library.

Regards,
Ming

On Wed, Sep 26, 2018 at 12:27 AM Håkan Berg hakan.berg@axis.com wrote:

Hi Ming,

Yes, you're correct. The remote is sending a re-INVITE without SDP when doing unhold.

Attaching log file.

Br,
/Håkan

-----Original Message-----
From: pjsip [mailto:pjsip-bounces@lists.pjsip.org] On Behalf Of Ming
Sent: den 25 september 2018 03:04
To: pjsip list pjsip@lists.pjsip.org
Subject: Re: [pjsip] Bug report: pjsua has no video on call unhold on
cisco pbx

Hi Hakan,

Since I can't access the Cisco server from here, can you forward us the log (level 5, as text attachment)?

Based on your description, since app needs to overwrite callback on_call_tx_offer(), does it mean that the remote is sending re-INVITE without SDP when trying to unhold?

Regards,
Ming
On Mon, Sep 24, 2018 at 9:03 PM Håkan Berg hakan.berg@axis.com wrote:

Hi,
I believe I've found a problem in pjsua: When registered to a cisco unified call manager pbx (10.5 in my case) and calling to a video phone endpoint on that pbx, the video negotiation in pjsip fails if the endpoint phone puts pjsip on hold and then unhold again.
The SDP sent from pjsip seems to be missing vital video lines:
m=video 0 RTP/AVP 31
c=IN IP4 127.0.0.1
a=sendrecv

Whereas a working video SDP might include something like this:
m=video 4006 RTP/AVP 97
c=IN IP4 10.0.0.5
b=TIAS:768000
a=rtcp:4007 IN IP4 10.0.0.5
a=sendrecv
a=rtpmap:97 H264/90000
a=fmtp:97 profile-level-id=42000d

I can reproduce it with pjsua-bin like so:

git clone https://github.com/cisco/openh264.git
cd openh264
make
sudo make install
cd ..
wget http://pjsip.org/release/2.8/pjproject-2.8.tar.bz2
tar xvfj pjproject-2.8.tar.bz2
cd pjproject-2.8
./configure
echo "#define PJMEDIA_HAS_VIDEO 1" >> pjlib/include/pj/config_site.h
make dep && make cd pjsip-apps/bin ./pjsua-x86_64-unknown-linux-gnu
--playback-dev=1 --capture-dev=1 --id sip:1@10.0.0.1 --registrar
sip:10.0.0.1 --realm "*" --username 1 --password hunter2
--app-log-level=3 --video

press m, enter sip:2@10.0.0.1
Cisco phone on extension 2 rings, answer and press hold. Video goes to inactive, press hold button again to unhold call, video ends up still being inactive because of SDP negotiation problem.
I can work around the problem by registering a callback function, but that should not be needed in my opinion:

diff --git a/pjsip-apps/src/pjsua/pjsua_app.c.bak
b/pjsip-apps/src/pjsua/pjsua_app.c
index 51c4537..db6066a 100644
--- a/pjsip-apps/src/pjsua/pjsua_app.c.bak
+++ b/pjsip-apps/src/pjsua/pjsua_app.c
@@ -1226,6 +1226,12 @@ int stdout_refresh_proc(void *arg)
return 0;
}

+static void
+ON_CALL_TX_OFFER_WORKAROUND(pjsua_call_id call_id, void *reserved,

  •                        pjsua_call_setting *opt) { }
    

static pj_status_t app_init()
{
pjsua_transport_id transport_id = -1; @@ -1275,6 +1281,9 @@
static pj_status_t app_init()
app_config.cfg.cb.on_nat_detect = &on_nat_detect;
app_config.cfg.cb.on_mwi_info = &on_mwi_info;
app_config.cfg.cb.on_transport_state = &on_transport_state;
+

  • app_config.cfg.cb.on_call_tx_offer =
  • &ON_CALL_TX_OFFER_WORKAROUND;
  • app_config.cfg.cb.on_ice_transport_error = &on_ice_transport_error;
    app_config.cfg.cb.on_snd_dev_operation = &on_snd_dev_operation;
    app_config.cfg.cb.on_call_media_event = &on_call_media_event;

This seems to be a problem because of the late offer mechanism that cisco uses, and pjsua-lib only "re-initialize media before creating SDP" if there's a on_call_tx_offer callback set (or call->med_prov_cnt is 0), see pjsua_call_on_create_offer().
This limitation does not seem to exist for things like pjsua_call_set_hold2(). But that's why the workaround gives a successful SDP negotiation: apply_call_setting() gets called.
Let me know if you need any pcap dumps demonstrating the problem.

Please advise.
Br,
/Håkan


Visit our blog: http://blog.pjsip.org

pjsip mailing list
pjsip@lists.pjsip.org
http://lists.pjsip.org/mailman/listinfo/pjsip_lists.pjsip.org

Hi Hakan, The SDP is actually perfectly fine. https://tools.ietf.org/html/rfc4566#section-6 Although an RTP profile may make static assignments of payload type numbers to payload formats, it is more common for that assignment to be done dynamically using "a=rtpmap:" attributes. As an example of a static payload type, consider u-law PCM coded single-channel audio sampled at 8 kHz. This is completely defined in the RTP Audio/Video profile as payload type 0, so there is no need for an "a=rtpmap:" attribute 31 is a static payload type, which corresponds to H261 An example can be found here: https://www.rfc-editor.org/rfc/rfc3264.txt search for (m=video 0) As for the disabled video, it's because in the previous offer, remote requested it and it has been accepted (below is the summarized message): 08:31:19.240 pjsua_core.c .RX 1299 bytes Request msg INVITE/cseq=103 (rdata0x7f1f5c0008e8) from UDP 10.0.0.1:5060: INVITE sip:7004@10.0.0.5:5060;ob SIP/2.0 CSeq: 103 INVITE m=video 0 RTP/AVP 126 a=inactive Best regards, Ming On Thu, Sep 27, 2018 at 1:48 PM, Håkan Berg <hakan.berg@axis.com> wrote: > Hi Ming, > > I agree that the recipient is free to provide an offer, but in this case it does not make sense for pjsip to provide an offer with a broken sdp in it, and the pjsua app should not have to register a callback to fix that. > > Looking at the problematic last offer sent from pjsip, it has a line like > (m): video 0 RTP/AVP 31 > but no correseponding rtpmap, and most previous offers from pjsip in that session does have correct and working SDPs with a resulting good video received by the remote. > > Why would pjsip offer an SDP that effectively renders video inactive? I would argue that’s done because of the bug, namely apply_call_setting() not being called, and bogus default data happens to be placed in the SDP. > > > > From the log, the problematic offer from pjsip when remote wants to unhold: > > 08:31:19.248 pjsua_call.c ......Call 0: asked to send a new offer > 08:31:19.248 inv0x20161f8 ......Sending Response msg 200/INVITE/cseq=104 (tdta0x7f1f5c93c468) > 08:31:19.248 dlg0x20161f8 .......Sending Response msg 200/INVITE/cseq=104 (tdta0x7f1f5c93c468) > 08:31:19.248 tsx0x7f1f5c002cc8 .......Sending Response msg 200/INVITE/cseq=104 (tdta0x7f1f5c93c468) > in state Trying > 08:31:19.248 sip_resolve.c ........Target '10.0.0.1:5060' type=UDP resolved to '10.0.0.1:5060' > type=UDP (UDP transport) > 08:31:19.248 pjsua_core.c ........TX 1172 bytes Response msg 200/INVITE/cseq=104 (tdta0x7f1f5c > 93c468) to UDP 10.0.0.1:5060: > SIP/2.0 200 OK > Via: SIP/2.0/UDP 10.0.0.1:5060;received=10.0.0.1;branch=z9hG4bKac752b67ba38 > Call-ID: 62523409-8a14-469c-8352-3832a7de0701 > From: <sip:1012@10.0.0.1>;tag=207142~4be90327-72fd-4c7c-9d1d-8e146fc96532-20849481 > To: <sip:7004@10.0.0.1>;tag=b31381ed-00e1-4dc3-82f8-3f4368805895 > CSeq: 104 INVITE > Session-Expires: 1800;refresher=uac > Require: timer > Contact: <sip:7004@10.0.0.5:5060;ob> > Allow: PRACK, INVITE, ACK, BYE, CANCEL, UPDATE, INFO, SUBSCRIBE, NOTIFY, REFER, MESSAGE, OPTIONS > Supported: replaces, 100rel, timer, norefersub > Content-Type: application/sdp > Content-Length: 550 > > v=0 > o=- 3746845864 3746845868 IN IP4 10.0.0.5 > s=pjmedia > b=AS:84 > t=0 0 > a=X-nat:0 > m=audio 4000 RTP/AVP 98 97 99 104 3 0 8 9 96 > c=IN IP4 10.0.0.5 > b=TIAS:64000 > a=rtcp:4001 IN IP4 10.0.0.5 > a=sendrecv > a=rtpmap:98 speex/16000 > a=rtpmap:97 speex/8000 > a=rtpmap:99 speex/32000 > a=rtpmap:104 iLBC/8000 > a=fmtp:104 mode=30 > a=rtpmap:3 GSM/8000 > a=rtpmap:0 PCMU/8000 > a=rtpmap:8 PCMA/8000 > a=rtpmap:9 G722/8000 > a=rtpmap:96 telephone-event/8000 > a=fmtp:96 0-16 > a=ssrc:219786230 cname:54ddf01b2db5c07e > m=video 0 RTP/AVP 31 > c=IN IP4 127.0.0.1 > > --end msg-- > > > > > From the log, an earlier request for pjsip to send a new offer, working as intended: > > 08:31:14.575 pjsua_call.c ......Call 0: asked to send a new offer > 08:31:14.575 inv0x20161f8 ......Sending Response msg 200/INVITE/cseq=102 (tdta0x7f1f5c93f6a8) > 08:31:14.575 dlg0x20161f8 .......Sending Response msg 200/INVITE/cseq=102 (tdta0x7f1f5c93f6a8) > 08:31:14.575 tsx0x7f1f5c002cc8 .......Sending Response msg 200/INVITE/cseq=102 (tdta0x7f1f5c93f6a8) > in state Trying > 08:31:14.575 sip_resolve.c ........Target '10.0.0.1:5060' type=UDP resolved to '10.0.0.1:5060' > type=UDP (UDP transport) > 08:31:14.575 pjsua_core.c ........TX 1358 bytes Response msg 200/INVITE/cseq=102 (tdta0x7f1f5c > 93f6a8) to UDP 10.0.0.1:5060: > SIP/2.0 200 OK > Via: SIP/2.0/UDP 10.0.0.1:5060;received=10.0.0.1;branch=z9hG4bKac713bbfb438 > Call-ID: 62523409-8a14-469c-8352-3832a7de0701 > From: <sip:1012@10.0.0.1>;tag=207142~4be90327-72fd-4c7c-9d1d-8e146fc96532-20849481 > To: <sip:7004@10.0.0.1>;tag=b31381ed-00e1-4dc3-82f8-3f4368805895 > CSeq: 102 INVITE > Session-Expires: 1800;refresher=uac > Require: timer > Contact: <sip:7004@10.0.0.5:5060;ob> > Allow: PRACK, INVITE, ACK, BYE, CANCEL, UPDATE, INFO, SUBSCRIBE, NOTIFY, REFER, MESSAGE, OPTIONS > Supported: replaces, 100rel, timer, norefersub > Content-Type: application/sdp > Content-Length: 736 > > v=0 > o=- 3746845864 3746845866 IN IP4 10.0.0.5 > s=pjmedia > b=AS:352 > t=0 0 > a=X-nat:0 > m=audio 4000 RTP/AVP 98 97 99 104 3 0 8 9 96 > c=IN IP4 10.0.0.5 > b=TIAS:64000 > a=rtcp:4001 IN IP4 10.0.0.5 > a=sendrecv > a=rtpmap:98 speex/16000 > a=rtpmap:97 speex/8000 > a=rtpmap:99 speex/32000 > a=rtpmap:104 iLBC/8000 > a=fmtp:104 mode=30 > a=rtpmap:3 GSM/8000 > a=rtpmap:0 PCMU/8000 > a=rtpmap:8 PCMA/8000 > a=rtpmap:9 G722/8000 > a=rtpmap:96 telephone-event/8000 > a=fmtp:96 0-16 > a=ssrc:219786230 cname:54ddf01b2db5c07e > m=video 4002 RTP/AVP 97 > c=IN IP4 10.0.0.5 > b=TIAS:256000 > a=rtcp:4003 IN IP4 10.0.0.5 > a=sendrecv > a=rtpmap:97 H264/90000 > a=fmtp:97 profile-level-id=42e01e; packetization-mode=1 > a=ssrc:1687763237 cname:54ddf01b2db5c07e > > --end msg-- > > > > Let me know if you need gdb logs demonstrating the issue. > > Thank you for looking into this. > Br, > /Håkan > > -----Original Message----- > From: pjsip [mailto:pjsip-bounces@lists.pjsip.org] On Behalf Of Ming > Sent: den 27 september 2018 06:20 > To: pjsip list <pjsip@lists.pjsip.org> > Subject: Re: [pjsip] Bug report: pjsua has no video on call unhold on cisco pbx > > Hi Hakan, > > I'm not sure if it's a bug. As far as I remember (perhaps you need to search the RFC for this), sending INVITE without SDP doesn't constitute an unhold request, and the recipient is then free to provide an offer, which in this case, means that PJSIP will offer the state of the currently active session. > > If you want to change this behavior, your workaround is actually already the solution, which is correctly implemented in the application (pjsua_app is actually a sample app) and doesn't require any modification within the library. > > Regards, > Ming > > On Wed, Sep 26, 2018 at 12:27 AM Håkan Berg <hakan.berg@axis.com> wrote: >> >> Hi Ming, >> >> Yes, you're correct. The remote is sending a re-INVITE without SDP when doing unhold. >> >> Attaching log file. >> >> Br, >> /Håkan >> >> -----Original Message----- >> From: pjsip [mailto:pjsip-bounces@lists.pjsip.org] On Behalf Of Ming >> Sent: den 25 september 2018 03:04 >> To: pjsip list <pjsip@lists.pjsip.org> >> Subject: Re: [pjsip] Bug report: pjsua has no video on call unhold on >> cisco pbx >> >> Hi Hakan, >> >> Since I can't access the Cisco server from here, can you forward us the log (level 5, as text attachment)? >> >> Based on your description, since app needs to overwrite callback on_call_tx_offer(), does it mean that the remote is sending re-INVITE without SDP when trying to unhold? >> >> Regards, >> Ming >> On Mon, Sep 24, 2018 at 9:03 PM Håkan Berg <hakan.berg@axis.com> wrote: >> > >> > Hi, >> > I believe I've found a problem in pjsua: When registered to a cisco unified call manager pbx (10.5 in my case) and calling to a video phone endpoint on that pbx, the video negotiation in pjsip fails if the endpoint phone puts pjsip on hold and then unhold again. >> > The SDP sent from pjsip seems to be missing vital video lines: >> > m=video 0 RTP/AVP 31 >> > c=IN IP4 127.0.0.1 >> > a=sendrecv >> > >> > Whereas a working video SDP might include something like this: >> > m=video 4006 RTP/AVP 97 >> > c=IN IP4 10.0.0.5 >> > b=TIAS:768000 >> > a=rtcp:4007 IN IP4 10.0.0.5 >> > a=sendrecv >> > a=rtpmap:97 H264/90000 >> > a=fmtp:97 profile-level-id=42000d >> > >> > I can reproduce it with pjsua-bin like so: >> > >> > git clone https://github.com/cisco/openh264.git >> > cd openh264 >> > make >> > sudo make install >> > cd .. >> > wget http://pjsip.org/release/2.8/pjproject-2.8.tar.bz2 >> > tar xvfj pjproject-2.8.tar.bz2 >> > cd pjproject-2.8 >> > ./configure >> > echo "#define PJMEDIA_HAS_VIDEO 1" >> pjlib/include/pj/config_site.h >> > make dep && make cd pjsip-apps/bin ./pjsua-x86_64-unknown-linux-gnu >> > --playback-dev=1 --capture-dev=1 --id sip:1@10.0.0.1 --registrar >> > sip:10.0.0.1 --realm "*" --username 1 --password hunter2 >> > --app-log-level=3 --video >> > >> > press m, enter sip:2@10.0.0.1 >> > Cisco phone on extension 2 rings, answer and press hold. Video goes to inactive, press hold button again to unhold call, video ends up still being inactive because of SDP negotiation problem. >> > I can work around the problem by registering a callback function, but that should not be needed in my opinion: >> > >> > diff --git a/pjsip-apps/src/pjsua/pjsua_app.c.bak >> > b/pjsip-apps/src/pjsua/pjsua_app.c >> > index 51c4537..db6066a 100644 >> > --- a/pjsip-apps/src/pjsua/pjsua_app.c.bak >> > +++ b/pjsip-apps/src/pjsua/pjsua_app.c >> > @@ -1226,6 +1226,12 @@ int stdout_refresh_proc(void *arg) >> > return 0; >> > } >> > >> > +static void >> > +ON_CALL_TX_OFFER_WORKAROUND(pjsua_call_id call_id, void *reserved, >> > + pjsua_call_setting *opt) { } >> > + >> > static pj_status_t app_init() >> > { >> > pjsua_transport_id transport_id = -1; @@ -1275,6 +1281,9 @@ >> > static pj_status_t app_init() >> > app_config.cfg.cb.on_nat_detect = &on_nat_detect; >> > app_config.cfg.cb.on_mwi_info = &on_mwi_info; >> > app_config.cfg.cb.on_transport_state = &on_transport_state; >> > + >> > + app_config.cfg.cb.on_call_tx_offer = >> > + &ON_CALL_TX_OFFER_WORKAROUND; >> > + >> > app_config.cfg.cb.on_ice_transport_error = &on_ice_transport_error; >> > app_config.cfg.cb.on_snd_dev_operation = &on_snd_dev_operation; >> > app_config.cfg.cb.on_call_media_event = &on_call_media_event; >> > >> > >> > >> > This seems to be a problem because of the late offer mechanism that cisco uses, and pjsua-lib only "re-initialize media before creating SDP" if there's a on_call_tx_offer callback set (or call->med_prov_cnt is 0), see pjsua_call_on_create_offer(). >> > This limitation does not seem to exist for things like pjsua_call_set_hold2(). But that's why the workaround gives a successful SDP negotiation: apply_call_setting() gets called. >> > Let me know if you need any pcap dumps demonstrating the problem. >> > >> > Please advise. >> > Br, >> > /Håkan >> > >> > _______________________________________________ >> > Visit our blog: http://blog.pjsip.org >> > >> > pjsip mailing list >> > pjsip@lists.pjsip.org >> > http://lists.pjsip.org/mailman/listinfo/pjsip_lists.pjsip.org >> >> _______________________________________________ >> Visit our blog: http://blog.pjsip.org >> >> pjsip mailing list >> pjsip@lists.pjsip.org >> http://lists.pjsip.org/mailman/listinfo/pjsip_lists.pjsip.org >> _______________________________________________ >> Visit our blog: http://blog.pjsip.org >> >> pjsip mailing list >> pjsip@lists.pjsip.org >> http://lists.pjsip.org/mailman/listinfo/pjsip_lists.pjsip.org > > _______________________________________________ > Visit our blog: http://blog.pjsip.org > > pjsip mailing list > pjsip@lists.pjsip.org > http://lists.pjsip.org/mailman/listinfo/pjsip_lists.pjsip.org > _______________________________________________ > Visit our blog: http://blog.pjsip.org > > pjsip mailing list > pjsip@lists.pjsip.org > http://lists.pjsip.org/mailman/listinfo/pjsip_lists.pjsip.org
HB
Håkan Berg
Fri, Sep 28, 2018 2:14 PM

Hi Ming,
I see what you mean and you're right, the SDP is strictly speaking not broken.
I see it as a legal SDP that does not reflect the users intention.

I'm building my case mostly on the info in RFC6337, especially https://tools.ietf.org/html/rfc6337#section-5.2.5 since it highlights the problem with this SDP, at least the way I see it.

The log entry you're referring to is the first INVITE in the sequence of events happening in the unhold scenario, and my understanding is that there's more to it than meets the eye. Yes, the remote offered video (and audio) inactive, but then directly afterwards it requests a new SDP in order to re-establish audio AND video. RFC6337 states among other things:

"When the new offer is sent in response to an offerless (re-)INVITE,
it should be constructed according to the General Principle for
Constructing Offers and Answers (Section 5.1 ): all codecs the UA is
currently willing and able to use should be included, not just the
ones that were negotiated by previous offer/answer exchanges."

I'll summarize in simplified terms the chain of events in the log, to the best of my knowledge:

08:31:04.625 INVITE SDP pjsip->cisco (pjsip sends the initial invite, audio&video sendrecv)
08:31:09.399 200 OK SDP pjsip <- cisco (cisco accepts pjsips call, audio&video sendrecv)

08:31:14.431 INVITE SDP pjsip <- cisco (user press hold on cisco, cisco sends new invite with audio&video inactive)
08:31:14.569 OK SDP pjsip -> cisco (pjsip accepts the new SDP, call is on hold with audio&video inactive)
08:31:14.575 INVITE pjsip <- cisco (cisco sends a late offer INVITE following the previous INVITE, as part of call hold)
08:31:14.575 200 OK SDP pjsip -> cisco (pjsip sends an offer in the 200 OK reply, as mandated by rfc6337, offering audio&video sendrecv)
08:31:14.588 ACK SDP pjsip <- cisco (cisco ACK the offered SDP but modifies it for hold music: audio sendonly, video inactive. Call is still on hold)

08:31:19.240 INVITE SDP pjsip <- cisco (user pressed unhold, cisco wants to stop the hold music, audio&video inactive)
08:31:19.240 200 OK SDP pjsip -> cisco (pjsip accepts the new SDP, hold music stops)
08:31:19.248 INVITE pjsip <- cisco (cisco sends a late offer INVITE following the previous INVITE, as part of call unhold)
08:31:19.248 200 OK SDP pjsip -> cisco (pjsip sends an offer in the 200 OK reply, as mandated by rfc6337, offering audio sendrecv but video inactive. This is the problem imo, see rfc6337 5.2.5)
08:31:19.256 ACK SDP pjsip <- cisco (cisco ACK the offered SDP, call is unheld but video is naturally not re-established: audio sendrecv, video inactive)

You mentioned that " As for the disabled video, it's because in the previous offer, remote requested it". I'm don't think the remote requested it in terms of it's final intention. It was one event in a chain of events from the remote, with the last one being that the remote requested pjsip to send its capabilities (i.e. late offer), but because of the supposed bug, pjsip will not offer video despite being video capable (unless the developer registers a callback which really shouldn't be a requirement in my opinion. Especially since it's not documented as such).

Thank you for your ongoing effort in this!

Br,
/Håkan

-----Original Message-----
From: pjsip [mailto:pjsip-bounces@lists.pjsip.org] On Behalf Of Ming
Sent: den 28 september 2018 03:35
To: pjsip list pjsip@lists.pjsip.org
Subject: Re: [pjsip] Bug report: pjsua has no video on call unhold on cisco pbx

Hi Hakan,

The SDP is actually perfectly fine.

https://tools.ietf.org/html/rfc4566#section-6
Although an RTP profile may make static assignments of payload
type numbers to payload formats, it is more common for that
assignment to be done dynamically using "a=rtpmap:" attributes.
As an example of a static payload type, consider u-law PCM
coded single-channel audio sampled at 8 kHz.  This is
completely defined in the RTP Audio/Video profile as payload
type 0, so there is no need for an "a=rtpmap:" attribute

31 is a static payload type, which corresponds to H261

An example can be found here:
https://www.rfc-editor.org/rfc/rfc3264.txt
search for (m=video 0)

As for the disabled video, it's because in the previous offer, remote requested it and it has been accepted (below is the summarized
message):
08:31:19.240          pjsua_core.c  .RX 1299 bytes Request msg
INVITE/cseq=103 (rdata0x7f1f5c0008e8) from UDP 10.0.0.1:5060:
INVITE sip:7004@10.0.0.5:5060;ob SIP/2.0
CSeq: 103 INVITE
m=video 0 RTP/AVP 126
a=inactive

Best regards,
Ming

On Thu, Sep 27, 2018 at 1:48 PM, Håkan Berg hakan.berg@axis.com wrote:

Hi Ming,

I agree that the recipient is free to provide an offer, but in this case it does not make sense for pjsip to provide an offer with a broken sdp in it, and the pjsua app should not have to register a callback to fix that.

Looking at the problematic last offer sent from pjsip, it has a line
like
(m): video 0 RTP/AVP 31
but no correseponding rtpmap, and most previous offers from pjsip in that session does have correct and working SDPs with a resulting good video received by the remote.

Why would pjsip offer an SDP that effectively renders video inactive? I would argue that’s done because of the bug, namely apply_call_setting() not being called, and bogus default data happens to be placed in the SDP.

From the log, the problematic offer from pjsip when remote wants to unhold:

08:31:19.248          pjsua_call.c  ......Call 0: asked to send a new offer
08:31:19.248          inv0x20161f8  ......Sending Response msg 200/INVITE/cseq=104 (tdta0x7f1f5c93c468)
08:31:19.248          dlg0x20161f8  .......Sending Response msg 200/INVITE/cseq=104 (tdta0x7f1f5c93c468)
08:31:19.248      tsx0x7f1f5c002cc8  .......Sending Response msg 200/INVITE/cseq=104 (tdta0x7f1f5c93c468)
in state Trying
08:31:19.248          sip_resolve.c  ........Target '10.0.0.1:5060' type=UDP resolved to '10.0.0.1:5060'
type=UDP (UDP transport)
08:31:19.248          pjsua_core.c  ........TX 1172 bytes Response msg 200/INVITE/cseq=104 (tdta0x7f1f5c
93c468) to UDP 10.0.0.1:5060:
SIP/2.0 200 OK
Via: SIP/2.0/UDP
10.0.0.1:5060;received=10.0.0.1;branch=z9hG4bKac752b67ba38
Call-ID: 62523409-8a14-469c-8352-3832a7de0701
From:
sip:1012@10.0.0.1;tag=207142~4be90327-72fd-4c7c-9d1d-8e146fc96532-20
849481
To: sip:7004@10.0.0.1;tag=b31381ed-00e1-4dc3-82f8-3f4368805895
CSeq: 104 INVITE
Session-Expires: 1800;refresher=uac
Require: timer
Contact: sip:7004@10.0.0.5:5060;ob
Allow: PRACK, INVITE, ACK, BYE, CANCEL, UPDATE, INFO, SUBSCRIBE,
NOTIFY, REFER, MESSAGE, OPTIONS
Supported: replaces, 100rel, timer, norefersub
Content-Type: application/sdp
Content-Length:  550

v=0
o=- 3746845864 3746845868 IN IP4 10.0.0.5 s=pjmedia
b=AS:84
t=0 0
a=X-nat:0
m=audio 4000 RTP/AVP 98 97 99 104 3 0 8 9 96 c=IN IP4 10.0.0.5
b=TIAS:64000
a=rtcp:4001 IN IP4 10.0.0.5
a=sendrecv
a=rtpmap:98 speex/16000
a=rtpmap:97 speex/8000
a=rtpmap:99 speex/32000
a=rtpmap:104 iLBC/8000
a=fmtp:104 mode=30
a=rtpmap:3 GSM/8000
a=rtpmap:0 PCMU/8000
a=rtpmap:8 PCMA/8000
a=rtpmap:9 G722/8000
a=rtpmap:96 telephone-event/8000
a=fmtp:96 0-16
a=ssrc:219786230 cname:54ddf01b2db5c07e m=video 0 RTP/AVP 31 c=IN IP4
127.0.0.1

--end msg--

From the log, an earlier request for pjsip to send a new offer, working as intended:

08:31:14.575          pjsua_call.c  ......Call 0: asked to send a new offer
08:31:14.575          inv0x20161f8  ......Sending Response msg 200/INVITE/cseq=102 (tdta0x7f1f5c93f6a8)
08:31:14.575          dlg0x20161f8  .......Sending Response msg 200/INVITE/cseq=102 (tdta0x7f1f5c93f6a8)
08:31:14.575      tsx0x7f1f5c002cc8  .......Sending Response msg 200/INVITE/cseq=102 (tdta0x7f1f5c93f6a8)
in state Trying
08:31:14.575          sip_resolve.c  ........Target '10.0.0.1:5060' type=UDP resolved to '10.0.0.1:5060'
type=UDP (UDP transport)
08:31:14.575          pjsua_core.c  ........TX 1358 bytes Response msg 200/INVITE/cseq=102 (tdta0x7f1f5c
93f6a8) to UDP 10.0.0.1:5060:
SIP/2.0 200 OK
Via: SIP/2.0/UDP
10.0.0.1:5060;received=10.0.0.1;branch=z9hG4bKac713bbfb438
Call-ID: 62523409-8a14-469c-8352-3832a7de0701
From:
sip:1012@10.0.0.1;tag=207142~4be90327-72fd-4c7c-9d1d-8e146fc96532-20
849481
To: sip:7004@10.0.0.1;tag=b31381ed-00e1-4dc3-82f8-3f4368805895
CSeq: 102 INVITE
Session-Expires: 1800;refresher=uac
Require: timer
Contact: sip:7004@10.0.0.5:5060;ob
Allow: PRACK, INVITE, ACK, BYE, CANCEL, UPDATE, INFO, SUBSCRIBE,
NOTIFY, REFER, MESSAGE, OPTIONS
Supported: replaces, 100rel, timer, norefersub
Content-Type: application/sdp
Content-Length:  736

v=0
o=- 3746845864 3746845866 IN IP4 10.0.0.5 s=pjmedia
b=AS:352
t=0 0
a=X-nat:0
m=audio 4000 RTP/AVP 98 97 99 104 3 0 8 9 96 c=IN IP4 10.0.0.5
b=TIAS:64000
a=rtcp:4001 IN IP4 10.0.0.5
a=sendrecv
a=rtpmap:98 speex/16000
a=rtpmap:97 speex/8000
a=rtpmap:99 speex/32000
a=rtpmap:104 iLBC/8000
a=fmtp:104 mode=30
a=rtpmap:3 GSM/8000
a=rtpmap:0 PCMU/8000
a=rtpmap:8 PCMA/8000
a=rtpmap:9 G722/8000
a=rtpmap:96 telephone-event/8000
a=fmtp:96 0-16
a=ssrc:219786230 cname:54ddf01b2db5c07e m=video 4002 RTP/AVP 97 c=IN
IP4 10.0.0.5
b=TIAS:256000
a=rtcp:4003 IN IP4 10.0.0.5
a=sendrecv
a=rtpmap:97 H264/90000
a=fmtp:97 profile-level-id=42e01e; packetization-mode=1
a=ssrc:1687763237 cname:54ddf01b2db5c07e

--end msg--

Let me know if you need gdb logs demonstrating the issue.

Thank you for looking into this.
Br,
/Håkan

-----Original Message-----
From: pjsip [mailto:pjsip-bounces@lists.pjsip.org] On Behalf Of Ming
Sent: den 27 september 2018 06:20
To: pjsip list pjsip@lists.pjsip.org
Subject: Re: [pjsip] Bug report: pjsua has no video on call unhold on
cisco pbx

Hi Hakan,

I'm not sure if it's a bug. As far as I remember (perhaps you need to search the RFC for this), sending INVITE without SDP doesn't constitute an unhold request, and the recipient is then free to provide an offer, which in this case, means that PJSIP will offer the state of the currently active session.

If you want to change this behavior, your workaround is actually already the solution, which is correctly implemented in the application (pjsua_app is actually a sample app) and doesn't require any modification within the library.

Regards,
Ming

On Wed, Sep 26, 2018 at 12:27 AM Håkan Berg hakan.berg@axis.com wrote:

Hi Ming,

Yes, you're correct. The remote is sending a re-INVITE without SDP when doing unhold.

Attaching log file.

Br,
/Håkan

-----Original Message-----
From: pjsip [mailto:pjsip-bounces@lists.pjsip.org] On Behalf Of Ming
Sent: den 25 september 2018 03:04
To: pjsip list pjsip@lists.pjsip.org
Subject: Re: [pjsip] Bug report: pjsua has no video on call unhold on
cisco pbx

Hi Hakan,

Since I can't access the Cisco server from here, can you forward us the log (level 5, as text attachment)?

Based on your description, since app needs to overwrite callback on_call_tx_offer(), does it mean that the remote is sending re-INVITE without SDP when trying to unhold?

Regards,
Ming
On Mon, Sep 24, 2018 at 9:03 PM Håkan Berg hakan.berg@axis.com wrote:

Hi,
I believe I've found a problem in pjsua: When registered to a cisco unified call manager pbx (10.5 in my case) and calling to a video phone endpoint on that pbx, the video negotiation in pjsip fails if the endpoint phone puts pjsip on hold and then unhold again.
The SDP sent from pjsip seems to be missing vital video lines:
m=video 0 RTP/AVP 31
c=IN IP4 127.0.0.1
a=sendrecv

Whereas a working video SDP might include something like this:
m=video 4006 RTP/AVP 97
c=IN IP4 10.0.0.5
b=TIAS:768000
a=rtcp:4007 IN IP4 10.0.0.5
a=sendrecv
a=rtpmap:97 H264/90000
a=fmtp:97 profile-level-id=42000d

I can reproduce it with pjsua-bin like so:

git clone https://github.com/cisco/openh264.git
cd openh264
make
sudo make install
cd ..
wget http://pjsip.org/release/2.8/pjproject-2.8.tar.bz2
tar xvfj pjproject-2.8.tar.bz2
cd pjproject-2.8
./configure
echo "#define PJMEDIA_HAS_VIDEO 1" >>
pjlib/include/pj/config_site.h make dep && make cd pjsip-apps/bin
./pjsua-x86_64-unknown-linux-gnu
--playback-dev=1 --capture-dev=1 --id sip:1@10.0.0.1 --registrar
sip:10.0.0.1 --realm "*" --username 1 --password hunter2
--app-log-level=3 --video

press m, enter sip:2@10.0.0.1
Cisco phone on extension 2 rings, answer and press hold. Video goes to inactive, press hold button again to unhold call, video ends up still being inactive because of SDP negotiation problem.
I can work around the problem by registering a callback function, but that should not be needed in my opinion:

diff --git a/pjsip-apps/src/pjsua/pjsua_app.c.bak
b/pjsip-apps/src/pjsua/pjsua_app.c
index 51c4537..db6066a 100644
--- a/pjsip-apps/src/pjsua/pjsua_app.c.bak
+++ b/pjsip-apps/src/pjsua/pjsua_app.c
@@ -1226,6 +1226,12 @@ int stdout_refresh_proc(void *arg)
return 0;
}

+static void
+ON_CALL_TX_OFFER_WORKAROUND(pjsua_call_id call_id, void *reserved,

  •                        pjsua_call_setting *opt) { }
    

static pj_status_t app_init()
{
pjsua_transport_id transport_id = -1; @@ -1275,6 +1281,9 @@
static pj_status_t app_init()
app_config.cfg.cb.on_nat_detect = &on_nat_detect;
app_config.cfg.cb.on_mwi_info = &on_mwi_info;
app_config.cfg.cb.on_transport_state = &on_transport_state;
+

  • app_config.cfg.cb.on_call_tx_offer =
  • &ON_CALL_TX_OFFER_WORKAROUND;
  • app_config.cfg.cb.on_ice_transport_error = &on_ice_transport_error;
    app_config.cfg.cb.on_snd_dev_operation = &on_snd_dev_operation;
    app_config.cfg.cb.on_call_media_event = &on_call_media_event;

This seems to be a problem because of the late offer mechanism that cisco uses, and pjsua-lib only "re-initialize media before creating SDP" if there's a on_call_tx_offer callback set (or call->med_prov_cnt is 0), see pjsua_call_on_create_offer().
This limitation does not seem to exist for things like pjsua_call_set_hold2(). But that's why the workaround gives a successful SDP negotiation: apply_call_setting() gets called.
Let me know if you need any pcap dumps demonstrating the problem.

Please advise.
Br,
/Håkan


Visit our blog: http://blog.pjsip.org

pjsip mailing list
pjsip@lists.pjsip.org
http://lists.pjsip.org/mailman/listinfo/pjsip_lists.pjsip.org

Hi Ming, I see what you mean and you're right, the SDP is strictly speaking not broken. I see it as a legal SDP that does not reflect the users intention. I'm building my case mostly on the info in RFC6337, especially https://tools.ietf.org/html/rfc6337#section-5.2.5 since it highlights the problem with this SDP, at least the way I see it. The log entry you're referring to is the first INVITE in the sequence of events happening in the unhold scenario, and my understanding is that there's more to it than meets the eye. Yes, the remote offered video (and audio) inactive, but then directly afterwards it requests a new SDP in order to re-establish audio AND video. RFC6337 states among other things: "When the new offer is sent in response to an offerless (re-)INVITE, it should be constructed according to the General Principle for Constructing Offers and Answers (Section 5.1 ): all codecs the UA is currently willing and able to use should be included, not just the ones that were negotiated by previous offer/answer exchanges." I'll summarize in simplified terms the chain of events in the log, to the best of my knowledge: 08:31:04.625 INVITE SDP pjsip->cisco (pjsip sends the initial invite, audio&video sendrecv) 08:31:09.399 200 OK SDP pjsip <- cisco (cisco accepts pjsips call, audio&video sendrecv) 08:31:14.431 INVITE SDP pjsip <- cisco (user press hold on cisco, cisco sends new invite with audio&video inactive) 08:31:14.569 OK SDP pjsip -> cisco (pjsip accepts the new SDP, call is on hold with audio&video inactive) 08:31:14.575 INVITE pjsip <- cisco (cisco sends a late offer INVITE following the previous INVITE, as part of call hold) 08:31:14.575 200 OK SDP pjsip -> cisco (pjsip sends an offer in the 200 OK reply, as mandated by rfc6337, offering audio&video sendrecv) 08:31:14.588 ACK SDP pjsip <- cisco (cisco ACK the offered SDP but modifies it for hold music: audio sendonly, video inactive. Call is still on hold) 08:31:19.240 INVITE SDP pjsip <- cisco (user pressed unhold, cisco wants to stop the hold music, audio&video inactive) 08:31:19.240 200 OK SDP pjsip -> cisco (pjsip accepts the new SDP, hold music stops) 08:31:19.248 INVITE pjsip <- cisco (cisco sends a late offer INVITE following the previous INVITE, as part of call unhold) 08:31:19.248 200 OK SDP pjsip -> cisco (pjsip sends an offer in the 200 OK reply, as mandated by rfc6337, offering audio sendrecv but video inactive. This is the problem imo, see rfc6337 5.2.5) 08:31:19.256 ACK SDP pjsip <- cisco (cisco ACK the offered SDP, call is unheld but video is naturally not re-established: audio sendrecv, video inactive) You mentioned that " As for the disabled video, it's because in the previous offer, remote requested it". I'm don't think the remote requested it in terms of it's final intention. It was one event in a chain of events from the remote, with the last one being that the remote requested pjsip to send its capabilities (i.e. late offer), but because of the supposed bug, pjsip will not offer video despite being video capable (unless the developer registers a callback which really shouldn't be a requirement in my opinion. Especially since it's not documented as such). Thank you for your ongoing effort in this! Br, /Håkan -----Original Message----- From: pjsip [mailto:pjsip-bounces@lists.pjsip.org] On Behalf Of Ming Sent: den 28 september 2018 03:35 To: pjsip list <pjsip@lists.pjsip.org> Subject: Re: [pjsip] Bug report: pjsua has no video on call unhold on cisco pbx Hi Hakan, The SDP is actually perfectly fine. https://tools.ietf.org/html/rfc4566#section-6 Although an RTP profile may make static assignments of payload type numbers to payload formats, it is more common for that assignment to be done dynamically using "a=rtpmap:" attributes. As an example of a static payload type, consider u-law PCM coded single-channel audio sampled at 8 kHz. This is completely defined in the RTP Audio/Video profile as payload type 0, so there is no need for an "a=rtpmap:" attribute 31 is a static payload type, which corresponds to H261 An example can be found here: https://www.rfc-editor.org/rfc/rfc3264.txt search for (m=video 0) As for the disabled video, it's because in the previous offer, remote requested it and it has been accepted (below is the summarized message): 08:31:19.240 pjsua_core.c .RX 1299 bytes Request msg INVITE/cseq=103 (rdata0x7f1f5c0008e8) from UDP 10.0.0.1:5060: INVITE sip:7004@10.0.0.5:5060;ob SIP/2.0 CSeq: 103 INVITE m=video 0 RTP/AVP 126 a=inactive Best regards, Ming On Thu, Sep 27, 2018 at 1:48 PM, Håkan Berg <hakan.berg@axis.com> wrote: > Hi Ming, > > I agree that the recipient is free to provide an offer, but in this case it does not make sense for pjsip to provide an offer with a broken sdp in it, and the pjsua app should not have to register a callback to fix that. > > Looking at the problematic last offer sent from pjsip, it has a line > like > (m): video 0 RTP/AVP 31 > but no correseponding rtpmap, and most previous offers from pjsip in that session does have correct and working SDPs with a resulting good video received by the remote. > > Why would pjsip offer an SDP that effectively renders video inactive? I would argue that’s done because of the bug, namely apply_call_setting() not being called, and bogus default data happens to be placed in the SDP. > > > > From the log, the problematic offer from pjsip when remote wants to unhold: > > 08:31:19.248 pjsua_call.c ......Call 0: asked to send a new offer > 08:31:19.248 inv0x20161f8 ......Sending Response msg 200/INVITE/cseq=104 (tdta0x7f1f5c93c468) > 08:31:19.248 dlg0x20161f8 .......Sending Response msg 200/INVITE/cseq=104 (tdta0x7f1f5c93c468) > 08:31:19.248 tsx0x7f1f5c002cc8 .......Sending Response msg 200/INVITE/cseq=104 (tdta0x7f1f5c93c468) > in state Trying > 08:31:19.248 sip_resolve.c ........Target '10.0.0.1:5060' type=UDP resolved to '10.0.0.1:5060' > type=UDP (UDP transport) > 08:31:19.248 pjsua_core.c ........TX 1172 bytes Response msg 200/INVITE/cseq=104 (tdta0x7f1f5c > 93c468) to UDP 10.0.0.1:5060: > SIP/2.0 200 OK > Via: SIP/2.0/UDP > 10.0.0.1:5060;received=10.0.0.1;branch=z9hG4bKac752b67ba38 > Call-ID: 62523409-8a14-469c-8352-3832a7de0701 > From: > <sip:1012@10.0.0.1>;tag=207142~4be90327-72fd-4c7c-9d1d-8e146fc96532-20 > 849481 > To: <sip:7004@10.0.0.1>;tag=b31381ed-00e1-4dc3-82f8-3f4368805895 > CSeq: 104 INVITE > Session-Expires: 1800;refresher=uac > Require: timer > Contact: <sip:7004@10.0.0.5:5060;ob> > Allow: PRACK, INVITE, ACK, BYE, CANCEL, UPDATE, INFO, SUBSCRIBE, > NOTIFY, REFER, MESSAGE, OPTIONS > Supported: replaces, 100rel, timer, norefersub > Content-Type: application/sdp > Content-Length: 550 > > v=0 > o=- 3746845864 3746845868 IN IP4 10.0.0.5 s=pjmedia > b=AS:84 > t=0 0 > a=X-nat:0 > m=audio 4000 RTP/AVP 98 97 99 104 3 0 8 9 96 c=IN IP4 10.0.0.5 > b=TIAS:64000 > a=rtcp:4001 IN IP4 10.0.0.5 > a=sendrecv > a=rtpmap:98 speex/16000 > a=rtpmap:97 speex/8000 > a=rtpmap:99 speex/32000 > a=rtpmap:104 iLBC/8000 > a=fmtp:104 mode=30 > a=rtpmap:3 GSM/8000 > a=rtpmap:0 PCMU/8000 > a=rtpmap:8 PCMA/8000 > a=rtpmap:9 G722/8000 > a=rtpmap:96 telephone-event/8000 > a=fmtp:96 0-16 > a=ssrc:219786230 cname:54ddf01b2db5c07e m=video 0 RTP/AVP 31 c=IN IP4 > 127.0.0.1 > > --end msg-- > > > > > From the log, an earlier request for pjsip to send a new offer, working as intended: > > 08:31:14.575 pjsua_call.c ......Call 0: asked to send a new offer > 08:31:14.575 inv0x20161f8 ......Sending Response msg 200/INVITE/cseq=102 (tdta0x7f1f5c93f6a8) > 08:31:14.575 dlg0x20161f8 .......Sending Response msg 200/INVITE/cseq=102 (tdta0x7f1f5c93f6a8) > 08:31:14.575 tsx0x7f1f5c002cc8 .......Sending Response msg 200/INVITE/cseq=102 (tdta0x7f1f5c93f6a8) > in state Trying > 08:31:14.575 sip_resolve.c ........Target '10.0.0.1:5060' type=UDP resolved to '10.0.0.1:5060' > type=UDP (UDP transport) > 08:31:14.575 pjsua_core.c ........TX 1358 bytes Response msg 200/INVITE/cseq=102 (tdta0x7f1f5c > 93f6a8) to UDP 10.0.0.1:5060: > SIP/2.0 200 OK > Via: SIP/2.0/UDP > 10.0.0.1:5060;received=10.0.0.1;branch=z9hG4bKac713bbfb438 > Call-ID: 62523409-8a14-469c-8352-3832a7de0701 > From: > <sip:1012@10.0.0.1>;tag=207142~4be90327-72fd-4c7c-9d1d-8e146fc96532-20 > 849481 > To: <sip:7004@10.0.0.1>;tag=b31381ed-00e1-4dc3-82f8-3f4368805895 > CSeq: 102 INVITE > Session-Expires: 1800;refresher=uac > Require: timer > Contact: <sip:7004@10.0.0.5:5060;ob> > Allow: PRACK, INVITE, ACK, BYE, CANCEL, UPDATE, INFO, SUBSCRIBE, > NOTIFY, REFER, MESSAGE, OPTIONS > Supported: replaces, 100rel, timer, norefersub > Content-Type: application/sdp > Content-Length: 736 > > v=0 > o=- 3746845864 3746845866 IN IP4 10.0.0.5 s=pjmedia > b=AS:352 > t=0 0 > a=X-nat:0 > m=audio 4000 RTP/AVP 98 97 99 104 3 0 8 9 96 c=IN IP4 10.0.0.5 > b=TIAS:64000 > a=rtcp:4001 IN IP4 10.0.0.5 > a=sendrecv > a=rtpmap:98 speex/16000 > a=rtpmap:97 speex/8000 > a=rtpmap:99 speex/32000 > a=rtpmap:104 iLBC/8000 > a=fmtp:104 mode=30 > a=rtpmap:3 GSM/8000 > a=rtpmap:0 PCMU/8000 > a=rtpmap:8 PCMA/8000 > a=rtpmap:9 G722/8000 > a=rtpmap:96 telephone-event/8000 > a=fmtp:96 0-16 > a=ssrc:219786230 cname:54ddf01b2db5c07e m=video 4002 RTP/AVP 97 c=IN > IP4 10.0.0.5 > b=TIAS:256000 > a=rtcp:4003 IN IP4 10.0.0.5 > a=sendrecv > a=rtpmap:97 H264/90000 > a=fmtp:97 profile-level-id=42e01e; packetization-mode=1 > a=ssrc:1687763237 cname:54ddf01b2db5c07e > > --end msg-- > > > > Let me know if you need gdb logs demonstrating the issue. > > Thank you for looking into this. > Br, > /Håkan > > -----Original Message----- > From: pjsip [mailto:pjsip-bounces@lists.pjsip.org] On Behalf Of Ming > Sent: den 27 september 2018 06:20 > To: pjsip list <pjsip@lists.pjsip.org> > Subject: Re: [pjsip] Bug report: pjsua has no video on call unhold on > cisco pbx > > Hi Hakan, > > I'm not sure if it's a bug. As far as I remember (perhaps you need to search the RFC for this), sending INVITE without SDP doesn't constitute an unhold request, and the recipient is then free to provide an offer, which in this case, means that PJSIP will offer the state of the currently active session. > > If you want to change this behavior, your workaround is actually already the solution, which is correctly implemented in the application (pjsua_app is actually a sample app) and doesn't require any modification within the library. > > Regards, > Ming > > On Wed, Sep 26, 2018 at 12:27 AM Håkan Berg <hakan.berg@axis.com> wrote: >> >> Hi Ming, >> >> Yes, you're correct. The remote is sending a re-INVITE without SDP when doing unhold. >> >> Attaching log file. >> >> Br, >> /Håkan >> >> -----Original Message----- >> From: pjsip [mailto:pjsip-bounces@lists.pjsip.org] On Behalf Of Ming >> Sent: den 25 september 2018 03:04 >> To: pjsip list <pjsip@lists.pjsip.org> >> Subject: Re: [pjsip] Bug report: pjsua has no video on call unhold on >> cisco pbx >> >> Hi Hakan, >> >> Since I can't access the Cisco server from here, can you forward us the log (level 5, as text attachment)? >> >> Based on your description, since app needs to overwrite callback on_call_tx_offer(), does it mean that the remote is sending re-INVITE without SDP when trying to unhold? >> >> Regards, >> Ming >> On Mon, Sep 24, 2018 at 9:03 PM Håkan Berg <hakan.berg@axis.com> wrote: >> > >> > Hi, >> > I believe I've found a problem in pjsua: When registered to a cisco unified call manager pbx (10.5 in my case) and calling to a video phone endpoint on that pbx, the video negotiation in pjsip fails if the endpoint phone puts pjsip on hold and then unhold again. >> > The SDP sent from pjsip seems to be missing vital video lines: >> > m=video 0 RTP/AVP 31 >> > c=IN IP4 127.0.0.1 >> > a=sendrecv >> > >> > Whereas a working video SDP might include something like this: >> > m=video 4006 RTP/AVP 97 >> > c=IN IP4 10.0.0.5 >> > b=TIAS:768000 >> > a=rtcp:4007 IN IP4 10.0.0.5 >> > a=sendrecv >> > a=rtpmap:97 H264/90000 >> > a=fmtp:97 profile-level-id=42000d >> > >> > I can reproduce it with pjsua-bin like so: >> > >> > git clone https://github.com/cisco/openh264.git >> > cd openh264 >> > make >> > sudo make install >> > cd .. >> > wget http://pjsip.org/release/2.8/pjproject-2.8.tar.bz2 >> > tar xvfj pjproject-2.8.tar.bz2 >> > cd pjproject-2.8 >> > ./configure >> > echo "#define PJMEDIA_HAS_VIDEO 1" >> >> > pjlib/include/pj/config_site.h make dep && make cd pjsip-apps/bin >> > ./pjsua-x86_64-unknown-linux-gnu >> > --playback-dev=1 --capture-dev=1 --id sip:1@10.0.0.1 --registrar >> > sip:10.0.0.1 --realm "*" --username 1 --password hunter2 >> > --app-log-level=3 --video >> > >> > press m, enter sip:2@10.0.0.1 >> > Cisco phone on extension 2 rings, answer and press hold. Video goes to inactive, press hold button again to unhold call, video ends up still being inactive because of SDP negotiation problem. >> > I can work around the problem by registering a callback function, but that should not be needed in my opinion: >> > >> > diff --git a/pjsip-apps/src/pjsua/pjsua_app.c.bak >> > b/pjsip-apps/src/pjsua/pjsua_app.c >> > index 51c4537..db6066a 100644 >> > --- a/pjsip-apps/src/pjsua/pjsua_app.c.bak >> > +++ b/pjsip-apps/src/pjsua/pjsua_app.c >> > @@ -1226,6 +1226,12 @@ int stdout_refresh_proc(void *arg) >> > return 0; >> > } >> > >> > +static void >> > +ON_CALL_TX_OFFER_WORKAROUND(pjsua_call_id call_id, void *reserved, >> > + pjsua_call_setting *opt) { } >> > + >> > static pj_status_t app_init() >> > { >> > pjsua_transport_id transport_id = -1; @@ -1275,6 +1281,9 @@ >> > static pj_status_t app_init() >> > app_config.cfg.cb.on_nat_detect = &on_nat_detect; >> > app_config.cfg.cb.on_mwi_info = &on_mwi_info; >> > app_config.cfg.cb.on_transport_state = &on_transport_state; >> > + >> > + app_config.cfg.cb.on_call_tx_offer = >> > + &ON_CALL_TX_OFFER_WORKAROUND; >> > + >> > app_config.cfg.cb.on_ice_transport_error = &on_ice_transport_error; >> > app_config.cfg.cb.on_snd_dev_operation = &on_snd_dev_operation; >> > app_config.cfg.cb.on_call_media_event = &on_call_media_event; >> > >> > >> > >> > This seems to be a problem because of the late offer mechanism that cisco uses, and pjsua-lib only "re-initialize media before creating SDP" if there's a on_call_tx_offer callback set (or call->med_prov_cnt is 0), see pjsua_call_on_create_offer(). >> > This limitation does not seem to exist for things like pjsua_call_set_hold2(). But that's why the workaround gives a successful SDP negotiation: apply_call_setting() gets called. >> > Let me know if you need any pcap dumps demonstrating the problem. >> > >> > Please advise. >> > Br, >> > /Håkan >> > >> > _______________________________________________ >> > Visit our blog: http://blog.pjsip.org >> > >> > pjsip mailing list >> > pjsip@lists.pjsip.org >> > http://lists.pjsip.org/mailman/listinfo/pjsip_lists.pjsip.org >> >> _______________________________________________ >> Visit our blog: http://blog.pjsip.org >> >> pjsip mailing list >> pjsip@lists.pjsip.org >> http://lists.pjsip.org/mailman/listinfo/pjsip_lists.pjsip.org >> _______________________________________________ >> Visit our blog: http://blog.pjsip.org >> >> pjsip mailing list >> pjsip@lists.pjsip.org >> http://lists.pjsip.org/mailman/listinfo/pjsip_lists.pjsip.org > > _______________________________________________ > Visit our blog: http://blog.pjsip.org > > pjsip mailing list > pjsip@lists.pjsip.org > http://lists.pjsip.org/mailman/listinfo/pjsip_lists.pjsip.org > _______________________________________________ > Visit our blog: http://blog.pjsip.org > > pjsip mailing list > pjsip@lists.pjsip.org > http://lists.pjsip.org/mailman/listinfo/pjsip_lists.pjsip.org _______________________________________________ Visit our blog: http://blog.pjsip.org pjsip mailing list pjsip@lists.pjsip.org http://lists.pjsip.org/mailman/listinfo/pjsip_lists.pjsip.org
M
Ming
Wed, Oct 3, 2018 3:14 AM

Hi Hakan,

True, that is the recommended behavior by the RFC, but in reality it
may be impractical. For example, in the scenario mentioned in the RFC,
always offering video upon receiving offerless re-INVITE will result
in repeated video and media transport setup + teardown, which can add
more delay, and thus inefficient and undesirable. Also, the note right
below the part you quoted also says:
" NOTE: The behavior above is recommended, but it is not always
achievable, for example, in some interworking scenarios.  Or, the
offerer may simply not have enough resources to offer "everything"
at that point.  Even if the UAS is not able to offer any other SDP
that the one currently being used, it should not reject the re-
INVITE.  Instead, it should generate an offer with the currently
used SDP with "o=" line unchanged."

So I still think that PJSIP's behavior is valid since it offers the
currently used SDP. The only problem I see, after looking at your log
and testing it myself, is that PJSIP's "o=" line is changed. This, we
can fix, but as for the default behavior, IMO, it should remain as it
is. And since PJSIP already offers a customization via the callback,
which you have rightly used, it's quite straightforward to change
this.

Regards,
Ming

On Fri, Sep 28, 2018 at 10:14 PM, Håkan Berg hakan.berg@axis.com wrote:

Hi Ming,
I see what you mean and you're right, the SDP is strictly speaking not broken.
I see it as a legal SDP that does not reflect the users intention.

I'm building my case mostly on the info in RFC6337, especially https://tools.ietf.org/html/rfc6337#section-5.2.5 since it highlights the problem with this SDP, at least the way I see it.

The log entry you're referring to is the first INVITE in the sequence of events happening in the unhold scenario, and my understanding is that there's more to it than meets the eye. Yes, the remote offered video (and audio) inactive, but then directly afterwards it requests a new SDP in order to re-establish audio AND video. RFC6337 states among other things:

"When the new offer is sent in response to an offerless (re-)INVITE,
it should be constructed according to the General Principle for
Constructing Offers and Answers (Section 5.1 ): all codecs the UA is
currently willing and able to use should be included, not just the
ones that were negotiated by previous offer/answer exchanges."

I'll summarize in simplified terms the chain of events in the log, to the best of my knowledge:

08:31:04.625 INVITE SDP pjsip->cisco (pjsip sends the initial invite, audio&video sendrecv)
08:31:09.399 200 OK SDP pjsip <- cisco (cisco accepts pjsips call, audio&video sendrecv)

08:31:14.431 INVITE SDP pjsip <- cisco (user press hold on cisco, cisco sends new invite with audio&video inactive)
08:31:14.569 OK SDP pjsip -> cisco (pjsip accepts the new SDP, call is on hold with audio&video inactive)
08:31:14.575 INVITE pjsip <- cisco (cisco sends a late offer INVITE following the previous INVITE, as part of call hold)
08:31:14.575 200 OK SDP pjsip -> cisco (pjsip sends an offer in the 200 OK reply, as mandated by rfc6337, offering audio&video sendrecv)
08:31:14.588 ACK SDP pjsip <- cisco (cisco ACK the offered SDP but modifies it for hold music: audio sendonly, video inactive. Call is still on hold)

08:31:19.240 INVITE SDP pjsip <- cisco (user pressed unhold, cisco wants to stop the hold music, audio&video inactive)
08:31:19.240 200 OK SDP pjsip -> cisco (pjsip accepts the new SDP, hold music stops)
08:31:19.248 INVITE pjsip <- cisco (cisco sends a late offer INVITE following the previous INVITE, as part of call unhold)
08:31:19.248 200 OK SDP pjsip -> cisco (pjsip sends an offer in the 200 OK reply, as mandated by rfc6337, offering audio sendrecv but video inactive. This is the problem imo, see rfc6337 5.2.5)
08:31:19.256 ACK SDP pjsip <- cisco (cisco ACK the offered SDP, call is unheld but video is naturally not re-established: audio sendrecv, video inactive)

You mentioned that " As for the disabled video, it's because in the previous offer, remote requested it". I'm don't think the remote requested it in terms of it's final intention. It was one event in a chain of events from the remote, with the last one being that the remote requested pjsip to send its capabilities (i.e. late offer), but because of the supposed bug, pjsip will not offer video despite being video capable (unless the developer registers a callback which really shouldn't be a requirement in my opinion. Especially since it's not documented as such).

Thank you for your ongoing effort in this!

Br,
/Håkan

-----Original Message-----
From: pjsip [mailto:pjsip-bounces@lists.pjsip.org] On Behalf Of Ming
Sent: den 28 september 2018 03:35
To: pjsip list pjsip@lists.pjsip.org
Subject: Re: [pjsip] Bug report: pjsua has no video on call unhold on cisco pbx

Hi Hakan,

The SDP is actually perfectly fine.

https://tools.ietf.org/html/rfc4566#section-6
Although an RTP profile may make static assignments of payload
type numbers to payload formats, it is more common for that
assignment to be done dynamically using "a=rtpmap:" attributes.
As an example of a static payload type, consider u-law PCM
coded single-channel audio sampled at 8 kHz.  This is
completely defined in the RTP Audio/Video profile as payload
type 0, so there is no need for an "a=rtpmap:" attribute

31 is a static payload type, which corresponds to H261

An example can be found here:
https://www.rfc-editor.org/rfc/rfc3264.txt
search for (m=video 0)

As for the disabled video, it's because in the previous offer, remote requested it and it has been accepted (below is the summarized
message):
08:31:19.240          pjsua_core.c  .RX 1299 bytes Request msg
INVITE/cseq=103 (rdata0x7f1f5c0008e8) from UDP 10.0.0.1:5060:
INVITE sip:7004@10.0.0.5:5060;ob SIP/2.0
CSeq: 103 INVITE
m=video 0 RTP/AVP 126
a=inactive

Best regards,
Ming

On Thu, Sep 27, 2018 at 1:48 PM, Håkan Berg hakan.berg@axis.com wrote:

Hi Ming,

I agree that the recipient is free to provide an offer, but in this case it does not make sense for pjsip to provide an offer with a broken sdp in it, and the pjsua app should not have to register a callback to fix that.

Looking at the problematic last offer sent from pjsip, it has a line
like
(m): video 0 RTP/AVP 31
but no correseponding rtpmap, and most previous offers from pjsip in that session does have correct and working SDPs with a resulting good video received by the remote.

Why would pjsip offer an SDP that effectively renders video inactive? I would argue that’s done because of the bug, namely apply_call_setting() not being called, and bogus default data happens to be placed in the SDP.

From the log, the problematic offer from pjsip when remote wants to unhold:

08:31:19.248          pjsua_call.c  ......Call 0: asked to send a new offer
08:31:19.248          inv0x20161f8  ......Sending Response msg 200/INVITE/cseq=104 (tdta0x7f1f5c93c468)
08:31:19.248          dlg0x20161f8  .......Sending Response msg 200/INVITE/cseq=104 (tdta0x7f1f5c93c468)
08:31:19.248      tsx0x7f1f5c002cc8  .......Sending Response msg 200/INVITE/cseq=104 (tdta0x7f1f5c93c468)
in state Trying
08:31:19.248          sip_resolve.c  ........Target '10.0.0.1:5060' type=UDP resolved to '10.0.0.1:5060'
type=UDP (UDP transport)
08:31:19.248          pjsua_core.c  ........TX 1172 bytes Response msg 200/INVITE/cseq=104 (tdta0x7f1f5c
93c468) to UDP 10.0.0.1:5060:
SIP/2.0 200 OK
Via: SIP/2.0/UDP
10.0.0.1:5060;received=10.0.0.1;branch=z9hG4bKac752b67ba38
Call-ID: 62523409-8a14-469c-8352-3832a7de0701
From:
sip:1012@10.0.0.1;tag=207142~4be90327-72fd-4c7c-9d1d-8e146fc96532-20
849481
To: sip:7004@10.0.0.1;tag=b31381ed-00e1-4dc3-82f8-3f4368805895
CSeq: 104 INVITE
Session-Expires: 1800;refresher=uac
Require: timer
Contact: sip:7004@10.0.0.5:5060;ob
Allow: PRACK, INVITE, ACK, BYE, CANCEL, UPDATE, INFO, SUBSCRIBE,
NOTIFY, REFER, MESSAGE, OPTIONS
Supported: replaces, 100rel, timer, norefersub
Content-Type: application/sdp
Content-Length:  550

v=0
o=- 3746845864 3746845868 IN IP4 10.0.0.5 s=pjmedia
b=AS:84
t=0 0
a=X-nat:0
m=audio 4000 RTP/AVP 98 97 99 104 3 0 8 9 96 c=IN IP4 10.0.0.5
b=TIAS:64000
a=rtcp:4001 IN IP4 10.0.0.5
a=sendrecv
a=rtpmap:98 speex/16000
a=rtpmap:97 speex/8000
a=rtpmap:99 speex/32000
a=rtpmap:104 iLBC/8000
a=fmtp:104 mode=30
a=rtpmap:3 GSM/8000
a=rtpmap:0 PCMU/8000
a=rtpmap:8 PCMA/8000
a=rtpmap:9 G722/8000
a=rtpmap:96 telephone-event/8000
a=fmtp:96 0-16
a=ssrc:219786230 cname:54ddf01b2db5c07e m=video 0 RTP/AVP 31 c=IN IP4
127.0.0.1

--end msg--

From the log, an earlier request for pjsip to send a new offer, working as intended:

08:31:14.575          pjsua_call.c  ......Call 0: asked to send a new offer
08:31:14.575          inv0x20161f8  ......Sending Response msg 200/INVITE/cseq=102 (tdta0x7f1f5c93f6a8)
08:31:14.575          dlg0x20161f8  .......Sending Response msg 200/INVITE/cseq=102 (tdta0x7f1f5c93f6a8)
08:31:14.575      tsx0x7f1f5c002cc8  .......Sending Response msg 200/INVITE/cseq=102 (tdta0x7f1f5c93f6a8)
in state Trying
08:31:14.575          sip_resolve.c  ........Target '10.0.0.1:5060' type=UDP resolved to '10.0.0.1:5060'
type=UDP (UDP transport)
08:31:14.575          pjsua_core.c  ........TX 1358 bytes Response msg 200/INVITE/cseq=102 (tdta0x7f1f5c
93f6a8) to UDP 10.0.0.1:5060:
SIP/2.0 200 OK
Via: SIP/2.0/UDP
10.0.0.1:5060;received=10.0.0.1;branch=z9hG4bKac713bbfb438
Call-ID: 62523409-8a14-469c-8352-3832a7de0701
From:
sip:1012@10.0.0.1;tag=207142~4be90327-72fd-4c7c-9d1d-8e146fc96532-20
849481
To: sip:7004@10.0.0.1;tag=b31381ed-00e1-4dc3-82f8-3f4368805895
CSeq: 102 INVITE
Session-Expires: 1800;refresher=uac
Require: timer
Contact: sip:7004@10.0.0.5:5060;ob
Allow: PRACK, INVITE, ACK, BYE, CANCEL, UPDATE, INFO, SUBSCRIBE,
NOTIFY, REFER, MESSAGE, OPTIONS
Supported: replaces, 100rel, timer, norefersub
Content-Type: application/sdp
Content-Length:  736

v=0
o=- 3746845864 3746845866 IN IP4 10.0.0.5 s=pjmedia
b=AS:352
t=0 0
a=X-nat:0
m=audio 4000 RTP/AVP 98 97 99 104 3 0 8 9 96 c=IN IP4 10.0.0.5
b=TIAS:64000
a=rtcp:4001 IN IP4 10.0.0.5
a=sendrecv
a=rtpmap:98 speex/16000
a=rtpmap:97 speex/8000
a=rtpmap:99 speex/32000
a=rtpmap:104 iLBC/8000
a=fmtp:104 mode=30
a=rtpmap:3 GSM/8000
a=rtpmap:0 PCMU/8000
a=rtpmap:8 PCMA/8000
a=rtpmap:9 G722/8000
a=rtpmap:96 telephone-event/8000
a=fmtp:96 0-16
a=ssrc:219786230 cname:54ddf01b2db5c07e m=video 4002 RTP/AVP 97 c=IN
IP4 10.0.0.5
b=TIAS:256000
a=rtcp:4003 IN IP4 10.0.0.5
a=sendrecv
a=rtpmap:97 H264/90000
a=fmtp:97 profile-level-id=42e01e; packetization-mode=1
a=ssrc:1687763237 cname:54ddf01b2db5c07e

--end msg--

Let me know if you need gdb logs demonstrating the issue.

Thank you for looking into this.
Br,
/Håkan

-----Original Message-----
From: pjsip [mailto:pjsip-bounces@lists.pjsip.org] On Behalf Of Ming
Sent: den 27 september 2018 06:20
To: pjsip list pjsip@lists.pjsip.org
Subject: Re: [pjsip] Bug report: pjsua has no video on call unhold on
cisco pbx

Hi Hakan,

I'm not sure if it's a bug. As far as I remember (perhaps you need to search the RFC for this), sending INVITE without SDP doesn't constitute an unhold request, and the recipient is then free to provide an offer, which in this case, means that PJSIP will offer the state of the currently active session.

If you want to change this behavior, your workaround is actually already the solution, which is correctly implemented in the application (pjsua_app is actually a sample app) and doesn't require any modification within the library.

Regards,
Ming

On Wed, Sep 26, 2018 at 12:27 AM Håkan Berg hakan.berg@axis.com wrote:

Hi Ming,

Yes, you're correct. The remote is sending a re-INVITE without SDP when doing unhold.

Attaching log file.

Br,
/Håkan

-----Original Message-----
From: pjsip [mailto:pjsip-bounces@lists.pjsip.org] On Behalf Of Ming
Sent: den 25 september 2018 03:04
To: pjsip list pjsip@lists.pjsip.org
Subject: Re: [pjsip] Bug report: pjsua has no video on call unhold on
cisco pbx

Hi Hakan,

Since I can't access the Cisco server from here, can you forward us the log (level 5, as text attachment)?

Based on your description, since app needs to overwrite callback on_call_tx_offer(), does it mean that the remote is sending re-INVITE without SDP when trying to unhold?

Regards,
Ming
On Mon, Sep 24, 2018 at 9:03 PM Håkan Berg hakan.berg@axis.com wrote:

Hi,
I believe I've found a problem in pjsua: When registered to a cisco unified call manager pbx (10.5 in my case) and calling to a video phone endpoint on that pbx, the video negotiation in pjsip fails if the endpoint phone puts pjsip on hold and then unhold again.
The SDP sent from pjsip seems to be missing vital video lines:
m=video 0 RTP/AVP 31
c=IN IP4 127.0.0.1
a=sendrecv

Whereas a working video SDP might include something like this:
m=video 4006 RTP/AVP 97
c=IN IP4 10.0.0.5
b=TIAS:768000
a=rtcp:4007 IN IP4 10.0.0.5
a=sendrecv
a=rtpmap:97 H264/90000
a=fmtp:97 profile-level-id=42000d

I can reproduce it with pjsua-bin like so:

git clone https://github.com/cisco/openh264.git
cd openh264
make
sudo make install
cd ..
wget http://pjsip.org/release/2.8/pjproject-2.8.tar.bz2
tar xvfj pjproject-2.8.tar.bz2
cd pjproject-2.8
./configure
echo "#define PJMEDIA_HAS_VIDEO 1" >>
pjlib/include/pj/config_site.h make dep && make cd pjsip-apps/bin
./pjsua-x86_64-unknown-linux-gnu
--playback-dev=1 --capture-dev=1 --id sip:1@10.0.0.1 --registrar
sip:10.0.0.1 --realm "*" --username 1 --password hunter2
--app-log-level=3 --video

press m, enter sip:2@10.0.0.1
Cisco phone on extension 2 rings, answer and press hold. Video goes to inactive, press hold button again to unhold call, video ends up still being inactive because of SDP negotiation problem.
I can work around the problem by registering a callback function, but that should not be needed in my opinion:

diff --git a/pjsip-apps/src/pjsua/pjsua_app.c.bak
b/pjsip-apps/src/pjsua/pjsua_app.c
index 51c4537..db6066a 100644
--- a/pjsip-apps/src/pjsua/pjsua_app.c.bak
+++ b/pjsip-apps/src/pjsua/pjsua_app.c
@@ -1226,6 +1226,12 @@ int stdout_refresh_proc(void *arg)
return 0;
}

+static void
+ON_CALL_TX_OFFER_WORKAROUND(pjsua_call_id call_id, void *reserved,

  •                        pjsua_call_setting *opt) { }
    

static pj_status_t app_init()
{
pjsua_transport_id transport_id = -1; @@ -1275,6 +1281,9 @@
static pj_status_t app_init()
app_config.cfg.cb.on_nat_detect = &on_nat_detect;
app_config.cfg.cb.on_mwi_info = &on_mwi_info;
app_config.cfg.cb.on_transport_state = &on_transport_state;
+

  • app_config.cfg.cb.on_call_tx_offer =
  • &ON_CALL_TX_OFFER_WORKAROUND;
  • app_config.cfg.cb.on_ice_transport_error = &on_ice_transport_error;
    app_config.cfg.cb.on_snd_dev_operation = &on_snd_dev_operation;
    app_config.cfg.cb.on_call_media_event = &on_call_media_event;

This seems to be a problem because of the late offer mechanism that cisco uses, and pjsua-lib only "re-initialize media before creating SDP" if there's a on_call_tx_offer callback set (or call->med_prov_cnt is 0), see pjsua_call_on_create_offer().
This limitation does not seem to exist for things like pjsua_call_set_hold2(). But that's why the workaround gives a successful SDP negotiation: apply_call_setting() gets called.
Let me know if you need any pcap dumps demonstrating the problem.

Please advise.
Br,
/Håkan


Visit our blog: http://blog.pjsip.org

pjsip mailing list
pjsip@lists.pjsip.org
http://lists.pjsip.org/mailman/listinfo/pjsip_lists.pjsip.org

Hi Hakan, True, that is the recommended behavior by the RFC, but in reality it may be impractical. For example, in the scenario mentioned in the RFC, always offering video upon receiving offerless re-INVITE will result in repeated video and media transport setup + teardown, which can add more delay, and thus inefficient and undesirable. Also, the note right below the part you quoted also says: " NOTE: The behavior above is recommended, but it is not always achievable, for example, in some interworking scenarios. Or, the offerer may simply not have enough resources to offer "everything" at that point. Even if the UAS is not able to offer any other SDP that the one currently being used, it should not reject the re- INVITE. Instead, it should generate an offer with the currently used SDP with "o=" line unchanged." So I still think that PJSIP's behavior is valid since it offers the currently used SDP. The only problem I see, after looking at your log and testing it myself, is that PJSIP's "o=" line is changed. This, we can fix, but as for the default behavior, IMO, it should remain as it is. And since PJSIP already offers a customization via the callback, which you have rightly used, it's quite straightforward to change this. Regards, Ming On Fri, Sep 28, 2018 at 10:14 PM, Håkan Berg <hakan.berg@axis.com> wrote: > Hi Ming, > I see what you mean and you're right, the SDP is strictly speaking not broken. > I see it as a legal SDP that does not reflect the users intention. > > I'm building my case mostly on the info in RFC6337, especially https://tools.ietf.org/html/rfc6337#section-5.2.5 since it highlights the problem with this SDP, at least the way I see it. > > The log entry you're referring to is the first INVITE in the sequence of events happening in the unhold scenario, and my understanding is that there's more to it than meets the eye. Yes, the remote offered video (and audio) inactive, but then directly afterwards it requests a new SDP in order to re-establish audio AND video. RFC6337 states among other things: > > "When the new offer is sent in response to an offerless (re-)INVITE, > it should be constructed according to the General Principle for > Constructing Offers and Answers (Section 5.1 ): all codecs the UA is > currently willing and able to use should be included, not just the > ones that were negotiated by previous offer/answer exchanges." > > > I'll summarize in simplified terms the chain of events in the log, to the best of my knowledge: > > 08:31:04.625 INVITE SDP pjsip->cisco (pjsip sends the initial invite, audio&video sendrecv) > 08:31:09.399 200 OK SDP pjsip <- cisco (cisco accepts pjsips call, audio&video sendrecv) > > 08:31:14.431 INVITE SDP pjsip <- cisco (user press hold on cisco, cisco sends new invite with audio&video inactive) > 08:31:14.569 OK SDP pjsip -> cisco (pjsip accepts the new SDP, call is on hold with audio&video inactive) > 08:31:14.575 INVITE pjsip <- cisco (cisco sends a late offer INVITE following the previous INVITE, as part of call hold) > 08:31:14.575 200 OK SDP pjsip -> cisco (pjsip sends an offer in the 200 OK reply, as mandated by rfc6337, offering audio&video sendrecv) > 08:31:14.588 ACK SDP pjsip <- cisco (cisco ACK the offered SDP but modifies it for hold music: audio sendonly, video inactive. Call is still on hold) > > 08:31:19.240 INVITE SDP pjsip <- cisco (user pressed unhold, cisco wants to stop the hold music, audio&video inactive) > 08:31:19.240 200 OK SDP pjsip -> cisco (pjsip accepts the new SDP, hold music stops) > 08:31:19.248 INVITE pjsip <- cisco (cisco sends a late offer INVITE following the previous INVITE, as part of call unhold) > 08:31:19.248 200 OK SDP pjsip -> cisco (pjsip sends an offer in the 200 OK reply, as mandated by rfc6337, offering audio sendrecv but video inactive. This is the problem imo, see rfc6337 5.2.5) > 08:31:19.256 ACK SDP pjsip <- cisco (cisco ACK the offered SDP, call is unheld but video is naturally not re-established: audio sendrecv, video inactive) > > > You mentioned that " As for the disabled video, it's because in the previous offer, remote requested it". I'm don't think the remote requested it in terms of it's final intention. It was one event in a chain of events from the remote, with the last one being that the remote requested pjsip to send its capabilities (i.e. late offer), but because of the supposed bug, pjsip will not offer video despite being video capable (unless the developer registers a callback which really shouldn't be a requirement in my opinion. Especially since it's not documented as such). > > > Thank you for your ongoing effort in this! > > Br, > /Håkan > > > -----Original Message----- > From: pjsip [mailto:pjsip-bounces@lists.pjsip.org] On Behalf Of Ming > Sent: den 28 september 2018 03:35 > To: pjsip list <pjsip@lists.pjsip.org> > Subject: Re: [pjsip] Bug report: pjsua has no video on call unhold on cisco pbx > > Hi Hakan, > > The SDP is actually perfectly fine. > > https://tools.ietf.org/html/rfc4566#section-6 > Although an RTP profile may make static assignments of payload > type numbers to payload formats, it is more common for that > assignment to be done dynamically using "a=rtpmap:" attributes. > As an example of a static payload type, consider u-law PCM > coded single-channel audio sampled at 8 kHz. This is > completely defined in the RTP Audio/Video profile as payload > type 0, so there is no need for an "a=rtpmap:" attribute > > 31 is a static payload type, which corresponds to H261 > > An example can be found here: > https://www.rfc-editor.org/rfc/rfc3264.txt > search for (m=video 0) > > As for the disabled video, it's because in the previous offer, remote requested it and it has been accepted (below is the summarized > message): > 08:31:19.240 pjsua_core.c .RX 1299 bytes Request msg > INVITE/cseq=103 (rdata0x7f1f5c0008e8) from UDP 10.0.0.1:5060: > INVITE sip:7004@10.0.0.5:5060;ob SIP/2.0 > CSeq: 103 INVITE > m=video 0 RTP/AVP 126 > a=inactive > > Best regards, > Ming > > > On Thu, Sep 27, 2018 at 1:48 PM, Håkan Berg <hakan.berg@axis.com> wrote: >> Hi Ming, >> >> I agree that the recipient is free to provide an offer, but in this case it does not make sense for pjsip to provide an offer with a broken sdp in it, and the pjsua app should not have to register a callback to fix that. >> >> Looking at the problematic last offer sent from pjsip, it has a line >> like >> (m): video 0 RTP/AVP 31 >> but no correseponding rtpmap, and most previous offers from pjsip in that session does have correct and working SDPs with a resulting good video received by the remote. >> >> Why would pjsip offer an SDP that effectively renders video inactive? I would argue that’s done because of the bug, namely apply_call_setting() not being called, and bogus default data happens to be placed in the SDP. >> >> >> >> From the log, the problematic offer from pjsip when remote wants to unhold: >> >> 08:31:19.248 pjsua_call.c ......Call 0: asked to send a new offer >> 08:31:19.248 inv0x20161f8 ......Sending Response msg 200/INVITE/cseq=104 (tdta0x7f1f5c93c468) >> 08:31:19.248 dlg0x20161f8 .......Sending Response msg 200/INVITE/cseq=104 (tdta0x7f1f5c93c468) >> 08:31:19.248 tsx0x7f1f5c002cc8 .......Sending Response msg 200/INVITE/cseq=104 (tdta0x7f1f5c93c468) >> in state Trying >> 08:31:19.248 sip_resolve.c ........Target '10.0.0.1:5060' type=UDP resolved to '10.0.0.1:5060' >> type=UDP (UDP transport) >> 08:31:19.248 pjsua_core.c ........TX 1172 bytes Response msg 200/INVITE/cseq=104 (tdta0x7f1f5c >> 93c468) to UDP 10.0.0.1:5060: >> SIP/2.0 200 OK >> Via: SIP/2.0/UDP >> 10.0.0.1:5060;received=10.0.0.1;branch=z9hG4bKac752b67ba38 >> Call-ID: 62523409-8a14-469c-8352-3832a7de0701 >> From: >> <sip:1012@10.0.0.1>;tag=207142~4be90327-72fd-4c7c-9d1d-8e146fc96532-20 >> 849481 >> To: <sip:7004@10.0.0.1>;tag=b31381ed-00e1-4dc3-82f8-3f4368805895 >> CSeq: 104 INVITE >> Session-Expires: 1800;refresher=uac >> Require: timer >> Contact: <sip:7004@10.0.0.5:5060;ob> >> Allow: PRACK, INVITE, ACK, BYE, CANCEL, UPDATE, INFO, SUBSCRIBE, >> NOTIFY, REFER, MESSAGE, OPTIONS >> Supported: replaces, 100rel, timer, norefersub >> Content-Type: application/sdp >> Content-Length: 550 >> >> v=0 >> o=- 3746845864 3746845868 IN IP4 10.0.0.5 s=pjmedia >> b=AS:84 >> t=0 0 >> a=X-nat:0 >> m=audio 4000 RTP/AVP 98 97 99 104 3 0 8 9 96 c=IN IP4 10.0.0.5 >> b=TIAS:64000 >> a=rtcp:4001 IN IP4 10.0.0.5 >> a=sendrecv >> a=rtpmap:98 speex/16000 >> a=rtpmap:97 speex/8000 >> a=rtpmap:99 speex/32000 >> a=rtpmap:104 iLBC/8000 >> a=fmtp:104 mode=30 >> a=rtpmap:3 GSM/8000 >> a=rtpmap:0 PCMU/8000 >> a=rtpmap:8 PCMA/8000 >> a=rtpmap:9 G722/8000 >> a=rtpmap:96 telephone-event/8000 >> a=fmtp:96 0-16 >> a=ssrc:219786230 cname:54ddf01b2db5c07e m=video 0 RTP/AVP 31 c=IN IP4 >> 127.0.0.1 >> >> --end msg-- >> >> >> >> >> From the log, an earlier request for pjsip to send a new offer, working as intended: >> >> 08:31:14.575 pjsua_call.c ......Call 0: asked to send a new offer >> 08:31:14.575 inv0x20161f8 ......Sending Response msg 200/INVITE/cseq=102 (tdta0x7f1f5c93f6a8) >> 08:31:14.575 dlg0x20161f8 .......Sending Response msg 200/INVITE/cseq=102 (tdta0x7f1f5c93f6a8) >> 08:31:14.575 tsx0x7f1f5c002cc8 .......Sending Response msg 200/INVITE/cseq=102 (tdta0x7f1f5c93f6a8) >> in state Trying >> 08:31:14.575 sip_resolve.c ........Target '10.0.0.1:5060' type=UDP resolved to '10.0.0.1:5060' >> type=UDP (UDP transport) >> 08:31:14.575 pjsua_core.c ........TX 1358 bytes Response msg 200/INVITE/cseq=102 (tdta0x7f1f5c >> 93f6a8) to UDP 10.0.0.1:5060: >> SIP/2.0 200 OK >> Via: SIP/2.0/UDP >> 10.0.0.1:5060;received=10.0.0.1;branch=z9hG4bKac713bbfb438 >> Call-ID: 62523409-8a14-469c-8352-3832a7de0701 >> From: >> <sip:1012@10.0.0.1>;tag=207142~4be90327-72fd-4c7c-9d1d-8e146fc96532-20 >> 849481 >> To: <sip:7004@10.0.0.1>;tag=b31381ed-00e1-4dc3-82f8-3f4368805895 >> CSeq: 102 INVITE >> Session-Expires: 1800;refresher=uac >> Require: timer >> Contact: <sip:7004@10.0.0.5:5060;ob> >> Allow: PRACK, INVITE, ACK, BYE, CANCEL, UPDATE, INFO, SUBSCRIBE, >> NOTIFY, REFER, MESSAGE, OPTIONS >> Supported: replaces, 100rel, timer, norefersub >> Content-Type: application/sdp >> Content-Length: 736 >> >> v=0 >> o=- 3746845864 3746845866 IN IP4 10.0.0.5 s=pjmedia >> b=AS:352 >> t=0 0 >> a=X-nat:0 >> m=audio 4000 RTP/AVP 98 97 99 104 3 0 8 9 96 c=IN IP4 10.0.0.5 >> b=TIAS:64000 >> a=rtcp:4001 IN IP4 10.0.0.5 >> a=sendrecv >> a=rtpmap:98 speex/16000 >> a=rtpmap:97 speex/8000 >> a=rtpmap:99 speex/32000 >> a=rtpmap:104 iLBC/8000 >> a=fmtp:104 mode=30 >> a=rtpmap:3 GSM/8000 >> a=rtpmap:0 PCMU/8000 >> a=rtpmap:8 PCMA/8000 >> a=rtpmap:9 G722/8000 >> a=rtpmap:96 telephone-event/8000 >> a=fmtp:96 0-16 >> a=ssrc:219786230 cname:54ddf01b2db5c07e m=video 4002 RTP/AVP 97 c=IN >> IP4 10.0.0.5 >> b=TIAS:256000 >> a=rtcp:4003 IN IP4 10.0.0.5 >> a=sendrecv >> a=rtpmap:97 H264/90000 >> a=fmtp:97 profile-level-id=42e01e; packetization-mode=1 >> a=ssrc:1687763237 cname:54ddf01b2db5c07e >> >> --end msg-- >> >> >> >> Let me know if you need gdb logs demonstrating the issue. >> >> Thank you for looking into this. >> Br, >> /Håkan >> >> -----Original Message----- >> From: pjsip [mailto:pjsip-bounces@lists.pjsip.org] On Behalf Of Ming >> Sent: den 27 september 2018 06:20 >> To: pjsip list <pjsip@lists.pjsip.org> >> Subject: Re: [pjsip] Bug report: pjsua has no video on call unhold on >> cisco pbx >> >> Hi Hakan, >> >> I'm not sure if it's a bug. As far as I remember (perhaps you need to search the RFC for this), sending INVITE without SDP doesn't constitute an unhold request, and the recipient is then free to provide an offer, which in this case, means that PJSIP will offer the state of the currently active session. >> >> If you want to change this behavior, your workaround is actually already the solution, which is correctly implemented in the application (pjsua_app is actually a sample app) and doesn't require any modification within the library. >> >> Regards, >> Ming >> >> On Wed, Sep 26, 2018 at 12:27 AM Håkan Berg <hakan.berg@axis.com> wrote: >>> >>> Hi Ming, >>> >>> Yes, you're correct. The remote is sending a re-INVITE without SDP when doing unhold. >>> >>> Attaching log file. >>> >>> Br, >>> /Håkan >>> >>> -----Original Message----- >>> From: pjsip [mailto:pjsip-bounces@lists.pjsip.org] On Behalf Of Ming >>> Sent: den 25 september 2018 03:04 >>> To: pjsip list <pjsip@lists.pjsip.org> >>> Subject: Re: [pjsip] Bug report: pjsua has no video on call unhold on >>> cisco pbx >>> >>> Hi Hakan, >>> >>> Since I can't access the Cisco server from here, can you forward us the log (level 5, as text attachment)? >>> >>> Based on your description, since app needs to overwrite callback on_call_tx_offer(), does it mean that the remote is sending re-INVITE without SDP when trying to unhold? >>> >>> Regards, >>> Ming >>> On Mon, Sep 24, 2018 at 9:03 PM Håkan Berg <hakan.berg@axis.com> wrote: >>> > >>> > Hi, >>> > I believe I've found a problem in pjsua: When registered to a cisco unified call manager pbx (10.5 in my case) and calling to a video phone endpoint on that pbx, the video negotiation in pjsip fails if the endpoint phone puts pjsip on hold and then unhold again. >>> > The SDP sent from pjsip seems to be missing vital video lines: >>> > m=video 0 RTP/AVP 31 >>> > c=IN IP4 127.0.0.1 >>> > a=sendrecv >>> > >>> > Whereas a working video SDP might include something like this: >>> > m=video 4006 RTP/AVP 97 >>> > c=IN IP4 10.0.0.5 >>> > b=TIAS:768000 >>> > a=rtcp:4007 IN IP4 10.0.0.5 >>> > a=sendrecv >>> > a=rtpmap:97 H264/90000 >>> > a=fmtp:97 profile-level-id=42000d >>> > >>> > I can reproduce it with pjsua-bin like so: >>> > >>> > git clone https://github.com/cisco/openh264.git >>> > cd openh264 >>> > make >>> > sudo make install >>> > cd .. >>> > wget http://pjsip.org/release/2.8/pjproject-2.8.tar.bz2 >>> > tar xvfj pjproject-2.8.tar.bz2 >>> > cd pjproject-2.8 >>> > ./configure >>> > echo "#define PJMEDIA_HAS_VIDEO 1" >> >>> > pjlib/include/pj/config_site.h make dep && make cd pjsip-apps/bin >>> > ./pjsua-x86_64-unknown-linux-gnu >>> > --playback-dev=1 --capture-dev=1 --id sip:1@10.0.0.1 --registrar >>> > sip:10.0.0.1 --realm "*" --username 1 --password hunter2 >>> > --app-log-level=3 --video >>> > >>> > press m, enter sip:2@10.0.0.1 >>> > Cisco phone on extension 2 rings, answer and press hold. Video goes to inactive, press hold button again to unhold call, video ends up still being inactive because of SDP negotiation problem. >>> > I can work around the problem by registering a callback function, but that should not be needed in my opinion: >>> > >>> > diff --git a/pjsip-apps/src/pjsua/pjsua_app.c.bak >>> > b/pjsip-apps/src/pjsua/pjsua_app.c >>> > index 51c4537..db6066a 100644 >>> > --- a/pjsip-apps/src/pjsua/pjsua_app.c.bak >>> > +++ b/pjsip-apps/src/pjsua/pjsua_app.c >>> > @@ -1226,6 +1226,12 @@ int stdout_refresh_proc(void *arg) >>> > return 0; >>> > } >>> > >>> > +static void >>> > +ON_CALL_TX_OFFER_WORKAROUND(pjsua_call_id call_id, void *reserved, >>> > + pjsua_call_setting *opt) { } >>> > + >>> > static pj_status_t app_init() >>> > { >>> > pjsua_transport_id transport_id = -1; @@ -1275,6 +1281,9 @@ >>> > static pj_status_t app_init() >>> > app_config.cfg.cb.on_nat_detect = &on_nat_detect; >>> > app_config.cfg.cb.on_mwi_info = &on_mwi_info; >>> > app_config.cfg.cb.on_transport_state = &on_transport_state; >>> > + >>> > + app_config.cfg.cb.on_call_tx_offer = >>> > + &ON_CALL_TX_OFFER_WORKAROUND; >>> > + >>> > app_config.cfg.cb.on_ice_transport_error = &on_ice_transport_error; >>> > app_config.cfg.cb.on_snd_dev_operation = &on_snd_dev_operation; >>> > app_config.cfg.cb.on_call_media_event = &on_call_media_event; >>> > >>> > >>> > >>> > This seems to be a problem because of the late offer mechanism that cisco uses, and pjsua-lib only "re-initialize media before creating SDP" if there's a on_call_tx_offer callback set (or call->med_prov_cnt is 0), see pjsua_call_on_create_offer(). >>> > This limitation does not seem to exist for things like pjsua_call_set_hold2(). But that's why the workaround gives a successful SDP negotiation: apply_call_setting() gets called. >>> > Let me know if you need any pcap dumps demonstrating the problem. >>> > >>> > Please advise. >>> > Br, >>> > /Håkan >>> > >>> > _______________________________________________ >>> > Visit our blog: http://blog.pjsip.org >>> > >>> > pjsip mailing list >>> > pjsip@lists.pjsip.org >>> > http://lists.pjsip.org/mailman/listinfo/pjsip_lists.pjsip.org >>> >>> _______________________________________________ >>> Visit our blog: http://blog.pjsip.org >>> >>> pjsip mailing list >>> pjsip@lists.pjsip.org >>> http://lists.pjsip.org/mailman/listinfo/pjsip_lists.pjsip.org >>> _______________________________________________ >>> Visit our blog: http://blog.pjsip.org >>> >>> pjsip mailing list >>> pjsip@lists.pjsip.org >>> http://lists.pjsip.org/mailman/listinfo/pjsip_lists.pjsip.org >> >> _______________________________________________ >> Visit our blog: http://blog.pjsip.org >> >> pjsip mailing list >> pjsip@lists.pjsip.org >> http://lists.pjsip.org/mailman/listinfo/pjsip_lists.pjsip.org >> _______________________________________________ >> Visit our blog: http://blog.pjsip.org >> >> pjsip mailing list >> pjsip@lists.pjsip.org >> http://lists.pjsip.org/mailman/listinfo/pjsip_lists.pjsip.org > > _______________________________________________ > Visit our blog: http://blog.pjsip.org > > pjsip mailing list > pjsip@lists.pjsip.org > http://lists.pjsip.org/mailman/listinfo/pjsip_lists.pjsip.org > _______________________________________________ > Visit our blog: http://blog.pjsip.org > > pjsip mailing list > pjsip@lists.pjsip.org > http://lists.pjsip.org/mailman/listinfo/pjsip_lists.pjsip.org