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@xxxxxxxxxxxxxxx] On Behalf Of Ming Sent: den 27 september 2018 06:20 To: pjsip list <pjsip@xxxxxxxxxxxxxxx> Subject: Re: 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@xxxxxxxx> 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@xxxxxxxxxxxxxxx] On Behalf Of Ming > Sent: den 25 september 2018 03:04 > To: pjsip list <pjsip@xxxxxxxxxxxxxxx> > Subject: Re: 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@xxxxxxxx> 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@xxxxxxxxxxxxxxx > > http://lists.pjsip.org/mailman/listinfo/pjsip_lists.pjsip.org > > _______________________________________________ > Visit our blog: http://blog.pjsip.org > > pjsip mailing list > pjsip@xxxxxxxxxxxxxxx > http://lists.pjsip.org/mailman/listinfo/pjsip_lists.pjsip.org > _______________________________________________ > Visit our blog: http://blog.pjsip.org > > pjsip mailing list > pjsip@xxxxxxxxxxxxxxx > http://lists.pjsip.org/mailman/listinfo/pjsip_lists.pjsip.org _______________________________________________ Visit our blog: http://blog.pjsip.org pjsip mailing list pjsip@xxxxxxxxxxxxxxx http://lists.pjsip.org/mailman/listinfo/pjsip_lists.pjsip.org _______________________________________________ Visit our blog: http://blog.pjsip.org pjsip mailing list pjsip@xxxxxxxxxxxxxxx http://lists.pjsip.org/mailman/listinfo/pjsip_lists.pjsip.org