Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add siprec extension: handle incoming INVITE with siprec #4132

Merged
merged 87 commits into from
Jan 8, 2025

Conversation

sorooshm78
Copy link
Contributor

I had a Session Record Client (SRC) that utilized the SIPREC module from the OpenSIPS SIP server, and I intended to develop a Session Record Server (SRS) capable of supporting SIPREC. The goal was for the SRS to handle requests effectively. However, since PJSIP does not support the SIPREC extension, I added SIPREC extension support to PJSIP.

image (3)

Senario with siprec extension:

INVITE Request

Request-Line: INVITE sip:192.168.10.20 SIP/2.0

Message Headers:
    Via: SIP/2.0/UDP 192.168.10.20:5060;branch=z9hG4bK656b.7f03f537.0
    To: <sip:192.168.10.20>
    From: <sip:192.168.10.20>;tag=85c717edf7d282027df52a83293e4957-ce21
    User-Agent: OpenSIPS (3.5.0-dev (x86_64/linux))
    Require: siprec  
    Content-Type: multipart/mixed; boundary=OSS-unique-boundary-42
    Contact: <sip:192.168.21.89:5060>; +sip.src
    ...

Session Description Protocol (SDP):
    Version: 0
    Media Description (m): audio 35001 RTP/AVP 8 0 101
    Media Attributes (a): 
        sendonly
        label:0
    ...
    Media Description (m): audio 35002 RTP/AVP 8 101
    Media Attributes (a): 
        sendonly
        label:1
    ... 

420 Bad Extension Response

Status-Line: SIP/2.0 420 Bad Extension

Message Header
    ...
    Unsupported: siprec
    Supported: replaces, 100rel, timer, norefersub, trickle-ice
    Content-Length:  0

Senario with siprec extension:

In the SIPREC module of PJSIP, when an INVITE is received with the header Require: siprec and two media attribute labels in the offer SDP, it can generate an appropriate 200 OK response that includes those two media attribute labels in the SDP answer.

INVITE Request

Request-Line: INVITE sip:192.168.10.20 SIP/2.0

Message Headers:
    Via: SIP/2.0/UDP 192.168.10.20:5060;branch=z9hG4bK656b.7f03f537.0
    To: <sip:192.168.10.20>
    From: <sip:192.168.10.20>;tag=85c717edf7d282027df52a83293e4957-ce21
    User-Agent: OpenSIPS (3.5.0-dev (x86_64/linux))
    Require: siprec  
    Content-Type: multipart/mixed; boundary=OSS-unique-boundary-42
    Contact: <sip:192.168.21.89:5060>; +sip.src
    ...

Session Description Protocol (SDP):
    Version: 0
    Media Description (m): audio 35001 RTP/AVP 8 0 101
    Media Attributes (a): 
        sendonly
        label:0
    ...
    Media Description (m): audio 35002 RTP/AVP 8 101
    Media Attributes (a): 
        sendonly
        label:1
    ... 

200 OK Response

Message Headers:
    Via: SIP/2.0/UDP 192.168.10.20:5060; received=192.168.10.20; branch=z9hG4bK656b.7f03f537.0
    From: <sip:192.168.10.20>; tag=85c717edf7d282027df52a83293e4957-ce21
    To: <sip:192.168.10.20>; tag=7de0bfd1-94b6-4462-929f-53955d386d91
    Allow: PRACK, INVITE, ACK, BYE, CANCEL, UPDATE, INFO, SUBSCRIBE, NOTIFY, REFER, MESSAGE, OPTIONS
    Supported: replaces, 100rel, timer, siprec, norefersub
    ...

Session Description Protocol (SDP):
    Version: 0
    Session Name (s): pjmedia
    Media Description (m): audio 4000 RTP/AVP 8 101
    Media Attributes (a): 
        label:0
        recvonly
    ...

    Media Description (m): audio 4002 RTP/AVP 8 101
    Media Attributes (a): 
        label:1
        recvonly
    ...

@CLAassistant
Copy link

CLAassistant commented Nov 5, 2024

CLA assistant check
All committers have signed the CLA.

@sorooshm78
Copy link
Contributor Author

I couldn't debug the Bitrise error and figure out where the issue in my code is. Please guide me to resolve the problem.

@sauwming
Copy link
Member

Thank you for the submission.

The support seems to be pretty basic, i.e. it allows incoming request with siprec to be accepted (instead of declined). There are a few concerns though:

  • The setting enable_multimedia seems misleading. PJSIP already supports multimedia, i.e. audio and video, even multiple audio and multiple video.
  • The patch seems to assume that only audio is supported.

pjmedia/include/pjmedia/sdp.h Outdated Show resolved Hide resolved
pjsip/src/pjsua-lib/pjsua_media.c Outdated Show resolved Hide resolved
pjsip/include/pjsip-ua/sip_inv.h Outdated Show resolved Hide resolved
pjsip/include/pjsip-ua/sip_siprec.h Outdated Show resolved Hide resolved
pjsip/include/pjsua-lib/pjsua.h Outdated Show resolved Hide resolved
pjsip/src/pjsua2/account.cpp Show resolved Hide resolved
@sorooshm78
Copy link
Contributor Author

I don't know what the issue with windows-with-video-libvpx-schannel-unit-test-1 is. Could you please guide me?

@sorooshm78
Copy link
Contributor Author

sorooshm78 commented Dec 26, 2024

I have considered three modes for use_siprec:

  1. optional: In this mode, calls will be established regardless of whether they are SIPREC or not.
  2. mandatory: In this mode, only SIPREC calls are allowed. If a regular call is attempted, it will result in a "Bad Request" error.
  3. inactive: In this mode, only regular calls are allowed. If a SIPREC call is attempted, it will result in a "Bad Extension" error.

I use two variables to determine the state for the three modes above.

PJSIP_INV_SUPPORT_SIPREC PJSIP_INV_REQUIRE_SIPREC
inactive no no
option yes no
mandatory yes yes

When use_siprec is set to inactive, neither the PJSIP_INV_SUPPORT_SIPREC flag nor the PJSIP_INV_REQUIRE_SIPREC flag is enabled, as shown in the table above.

And in the code below, I attempt to return a "Bad Extension" error:

pjsip/src/pjsip-ua/sip_inv.c

else if (!(*options & PJSIP_INV_SUPPORT_SIPREC) && 
        pj_stricmp(&req_hdr->values[i], &STR_SIPREC)==0)
    {
        unsupp_tags[unsupp_cnt++] = req_hdr->values[i];
    
    }

In the code above, when the PJSIP_INV_SUPPORT_SIPREC option is not set, the execution enters the if block and returns a "Bad Extension" error.

The pjsip_inv_verify_request3 function is called three times for each call. The first time, it includes the desired options, but for the next two calls, the option value is zero. Therefore, I added the following code to resolve this issue:

verify_request function in pjsip/src/pjsua-lib/pjsua_call.c

if (status == PJ_SUCCESS) {
    unsigned options = 0;

    /* Add SIPREC support to prevent the "bad extension" error */
    options |= PJSIP_INV_SUPPORT_SIPREC; // add this line

    /* Verify that we can handle the request. */
    status = pjsip_inv_verify_request3(rdata,
                                        call->inv->pool_prov, &options, 
                                        offer, answer, NULL, 
                                        pjsua_var.endpt, response);

If there's a better solution to address the issue mentioned, please guide me.

and I don't know what the issue with windows-with-video-libvpx-schannel-unit-test-1 is. Could you please guide me?


In my previous commit, to resolve this issue, I added PJSIP_INV_NOT_SUPPORT_SIPREC.

pjsip/src/pjsip-ua/sip_inv.c

else if ((*options & PJSIP_INV_NOT_SUPPORT_SIPREC) && 
        pj_stricmp(&req_hdr->values[i], &STR_SIPREC)==0)
    {
        unsupp_tags[unsupp_cnt++] = req_hdr->values[i];
    
    }

@sauwming
Copy link
Member

sauwming commented Jan 2, 2025

For the failed CI test, we have fixed it in #4234, so don't worry about it.

pjmedia/include/pjmedia/sdp.h Outdated Show resolved Hide resolved
pjsip/src/pjsip-ua/sip_inv.c Show resolved Hide resolved
Copy link
Member

@nanangizz nanangizz left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As the implementation is not a full functionality, I think the PR title should be changed to represent to coverage, e.g: something like "Add siprec extension: handle incoming INVITE with siprec", I can do this if you want :)

Also better if the PR desc briefly describes what to do next to implement a recording server with full functionality, unfortunately I think this needs to be done by you as I believe you've done it in real app.

Thanks for the submission & all the works!

@sorooshm78
Copy link
Contributor Author

sorooshm78 commented Jan 7, 2025

To implement simple Session Recording Server (SRS) using the SIPREC module, you can follow the steps below.I am using pjsua2 to implement SRS.

Configuration

To configure the SIPREC module, you can proceed as in the code below.

    AccountConfig accountConfig;
    accountConfig.callConfig.siprecUse = PJSUA_SIP_SIPREC_OPTIONAL;

Audio

Also, to save audio, you can use the following code.

class MyCall : public pj::Call
{
    void onCallMediaState(pj::OnCallMediaStateParam& params)
    {
        pj::CallInfo callInfo = getInfo();
        for (unsigned media_index = 0; media_index < callInfo.media.size(); media_index++)
        {
            if (callInfo.media[media_index].type == PJMEDIA_TYPE_AUDIO)
            {
                pj::AudioMedia audioMedia = getAudioMedia(media_index);
                recorder.createRecorder(path);
                audioMedio.startTransmit(recorder);
            }
        }
    }
};

Metadata

And to access metadata, you can use the following code.

class MyCall : public pj::Call
{
    void saveMetadata()
    {
        int id = getId();
        pjsua_call *call = &pjsua_var.calls[id];
        std::string metadata = std::string(call->siprec_metadata.ptr, call->siprec_metadata.slen);
    }    
};

Unsupported Features in the SIPREC Module

A list of items that are not present in the SIPREC module:

  • Update requests are not supported.
  • Reinvite requests are not supported.
  • Metadata in BYE requests is not supported.
  • UAS can request the UAC to send metadata, which is not supported.
  • Currently, the SIPREC module supports only UAC mode.

I will try to implement some of the above items in another PR.

@sorooshm78 sorooshm78 changed the title Add siprec extension Add siprec extension: handle incoming INVITE with siprec Jan 7, 2025
@nanangizz nanangizz merged commit 67db8de into pjsip:master Jan 8, 2025
36 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants