SiddiqSoft.sip2json 2.3.3

There is a newer version of this package available.
See the version list below for details.
dotnet add package SiddiqSoft.sip2json --version 2.3.3
                    
NuGet\Install-Package SiddiqSoft.sip2json -Version 2.3.3
                    
This command is intended to be used within the Package Manager Console in Visual Studio, as it uses the NuGet module's version of Install-Package.
<PackageReference Include="SiddiqSoft.sip2json" Version="2.3.3" />
                    
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="SiddiqSoft.sip2json" Version="2.3.3" />
                    
Directory.Packages.props
<PackageReference Include="SiddiqSoft.sip2json" />
                    
Project file
For projects that support Central Package Management (CPM), copy this XML node into the solution Directory.Packages.props file to version the package.
paket add SiddiqSoft.sip2json --version 2.3.3
                    
#r "nuget: SiddiqSoft.sip2json, 2.3.3"
                    
#r directive can be used in F# Interactive and Polyglot Notebooks. Copy this into the interactive tool or source code of the script to reference the package.
#:package SiddiqSoft.sip2json@2.3.3
                    
#:package directive can be used in C# file-based apps starting in .NET 10 preview 4. Copy this into a .cs file before any lines of code to reference the package.
#addin nuget:?package=SiddiqSoft.sip2json&version=2.3.3
                    
Install as a Cake Addin
#tool nuget:?package=SiddiqSoft.sip2json&version=2.3.3
                    
Install as a Cake Tool

sip2json

<b>SIP Parser for Modern C++</b><br/> <small>Copyright ©2020-2024 Abdelkareem Siddiq. All rights reserved.</small>

Build Status alternate text is missing from this package README image alternate text is missing from this package README image alternate text is missing from this package README image

Design Goals

A SIP parser for Modern C++ (C++20).

Compiler Requirements: C++20 compliant compiler

  • Clang 17 or higher
  • GCC 14 or higher
  • Visual Studio 2022 or higher

A lot of parsers exist but they tend to be written (a long time ago) and are primarily in C or wrap around the C library.

JSON is one of the most widely used document storage formats and is the lingua-franca of the web and the various client applications written in JavaScript/TypeScript, C# as well as the myriad of No-SQL data stores.

Modern software architecture relies on many distributed systems and favors horizontal scaling rather than a very efficient, fast single node.

When solving for resilience and high-availability, using systems such as No-SQL stores from Microsoft, Google or Amazon tends to lean towards JSON as the document store.

JSON libraries feature patching, merging and diff'ing of JSON documents therefore we can offload the transforms to templates which can accomplish this task instead of manipulating bespoke C++ classes.

We skewed towards the following tradeoffs:

  • API must be native C++17 without any wrappers or compromises.
  • Simple, small code
  • Dependencies should be widely-used and respected
  • Transforms must be easy

Features

  • Header-only library - Easy integration, no compilation required
  • Efficient JSON representation - Compact storage with minimal intermediate processing
  • Bidirectional conversion - Serialize to/from SIP messages
  • Streaming support - Parse multiple messages from a buffer asynchronously
  • SDP support - Full encoding/decoding of Session Description Protocol bodies
  • Modern C++20 - Leverages latest language features for type safety and performance

Dependencies

Out of scope

This library is intendended to be used as a basis for you application and does not provide:

  • IO facility
  • Buffer management
  • Encryption
  • Managing CSeq
  • Thread safety is your responsibility
  • No statemachine is provided and the sipmessage class as well as the sip2json class are stateless.

Usage

Nuget

Use siddiqsoft.sip2json nuget package.

CMakeList

    CPMAddPackage(NAME sip2json   GIT_REPOSITORY https://github.com/siddiqsoftware/sip2json.git
                                  GIT_TAG "v1.17.0" )
    ..
    ..
    target_link_libraries(your-project PRIVATE sip2json::sip2json)

Using the CPM will automatically pull in the latest nlohmann_json package and any other dependencies. As user you'll be linking only with this package!

Code

#include "siddiqsoftware/sip2json.hpp"

// Assume a method invoked by the IO system on each "frame" read
// from the tcp stream.
void onReadCompleted(std::string& readBuffer)
{
  auto bufferStart= readBuffer.begin();
  
  // Invokes the callback per each decoded sipmessage from the buffer
  // Keep track of the bufferStart as it is advanced to reach the readBuffer.end()
  // as objects are parsed.
  sip2json::parseAsync(bufferStart,
          readBuffer.end(),
          [](sipmessage&& msg) {
              // Got a valid sipmessage object.. the object has been moved into this argument.
              // The parameter msg has been std::move()'d and therefore the lifetime ends when
              // the callback is completed. It is up to the client to ensure that they
              // make copies as necessary.
              if(!msg.empty()) {
                 // Do something..
              }
          },
          [](sip2jsonErrors& errCode, const std::string& msg){
              // Invoked for an error during the processing of the buffer.
      });

  // Client is responsible for managing the state of the readBuffer
  // the library uses an iterator to parse the stream and advances
  // as each SIP frame is processed.
  readBuffer.erase(readBuffer.begin(), bufferStart); // what remains can be processed as more data arrives
}

Documentation

Comprehensive documentation is available in the docs/ folder:

Document Purpose
docs/INDEX.md 📚 Documentation index and quick navigation
docs/API.md 📖 Complete API reference with 20+ examples
docs/ARCHITECTURE.md 🏗️ Design patterns and architecture guide
docs/MIGRATION.md 🔄 Migration guide and troubleshooting

Quick Start

For a quick introduction to the API, see docs/API.md - Quick Start.

Complete API Reference

See docs/API.md for:

  • Complete method documentation
  • Constructor details
  • Getter/setter methods
  • Exception handling
  • Best practices

Architecture & Design

See docs/ARCHITECTURE.md for:

  • Design patterns (Factory, Builder, Strategy, etc.)
  • Class hierarchy
  • Data flow diagrams
  • Performance optimization
  • Memory management

Troubleshooting & Migration

See docs/MIGRATION.md for:

  • Migration from v1.x to v2.0+
  • Common issues and solutions
  • FAQ
  • Performance tips

Quick Example

#include "siddiqsoft/sip2json.hpp"

using namespace siddiqsoft;

int main()
{
    // Create an INVITE request
    sipmessage msg("INVITE", "sip:user@example.com", "call-123", 1);
    
    // Set headers with method chaining
    msg.setHeader("From", "sip:caller@example.com")
       .setHeader("To", "sip:user@example.com")
       .setHeader("User-Agent", "MyApp/1.0");
    
    // Add Via header (can have multiple)
    msg.headers()["Via"].push_back("SIP/2.0/TCP example.com");
    
    // Serialize to SIP message
    try {
        auto sip_message = sip2json::serialize(msg);
        std::cout << sip_message << std::endl;
    } catch (const sip2json_exception& e) {
        std::cerr << "Error: " << e.what() << std::endl;
    }
    
    return 0;
}

For more examples, see docs/API.md - Examples.

Roadmap

Release Notes
v1.0.0 Basic decoder and decoder with support for CloudEvent envelope.
v2.0.0 Improve performance and refactor interface. Avoid use of std::regex due to its reported highcost.

Code Quality & Best Practices

The codebase has been thoroughly reviewed and improved to follow modern C++ best practices:

Improvements Applied

  • Rule of Five Compliance - All special member functions properly implemented
  • Const-Correctness - All getter methods are const-qualified
  • Move Semantics - All move operations have noexcept guarantee
  • Exception Safety - Consistent noexcept(false) specifications
  • Code Quality - Eliminated goto statements, magic numbers, and code duplication
  • Documentation - Comprehensive method documentation with RFC references
  • Comprehensive Test Suite - 142+ tests including Rule of Five compliance tests

Quality Metrics

  • Const-Correct Methods: 100%
  • Test Coverage: 142+ tests across 19 test suites
  • Backward Compatibility: 100%

For detailed information on design patterns and architecture, see docs/ARCHITECTURE.md.

Tests

  • There is a single C++ Native Unit Test using the Microsoft C++ Framework under vstest.
  • Code Coverage is enabled (only if you're using Visual Studio Enterprise).
  • Azure pipelines CI reports on the test results and the coverage results.
  • There are to date 142+ tests covering parsing, serialization, and Rule of Five compliance.
  • Clang-Tidy is used as a linter to highlight issues with best-practices and static code analysis.
  • Consistent formatting using Clang Format.

Test Categories

  • Parsing Tests - Verify correct SIP message parsing
  • Serialization Tests - Verify correct SIP message serialization
  • Edge Cases - Handle malformed and boundary condition messages
  • Stress Tests - Performance and scalability testing
  • Rule of Five Tests - Verify copy/move semantics compliance (24 tests)
  • Synthetic Tests - Generated test cases for comprehensive coverage

References

Json Schema

Container

The document contains single character entries: s, h, b and the diagnostic element meta which is used to track such items as version, time of arrival, time to decode, etc.

{
    "meta": {"version": "sip2json/1.10.2/1.0.1", "time": "2020-08-13T12:27:30.555Z", "ttx": 0},
    "s": {},
    "h": {},
    "b": null
}

This approach acknowledges the fact that SIP messages are generated at a very high rate and processing size of data matters. Keeping the data compact and mapping the raw SIP and SDP means less intermediate processing is involved and keeps our container usage to a single model (map).

Field Type Description
s object Represents the SIP start line.
meta object Diagnostic object that contains version, time of arrival and ttx milliseconds taken to parse.
h object Contains the SIP headers.
b object Contains the SIP body. Optional.<br/>Currently, only the application/sdp body encode/decode is supported.<br/>If the Content-Length is 0, despite the value of the Content-Type this element is skipped.
SIP Start Line
Field Type Description
type string One of request or response.
method string Present for request type. Represents the SIP method.
uri string Present when the type is request, this represents the SIP URI element of the SIP request line.
status string Present when the type is response and represents the status code of the SIP response line.
reason string Present when the type is response and represents the response phrase of the SIP response line.
version string Always SIP/2.0.
SIP Headers

The object contains key-value elements found in the SIP header section.

  • SIP headers with boolean value types are stored as JSON boolean.
  • Default storage type is string
  • The header field Content-Length is encoded as JSON number.
  • When more than one item with the same header name is found, it is stored in an array.
      "h": { "Authorization": "",
             "Via": [ "via-1",
                      "via-2",
                      "via-3"
             ],
             "Content-Length": 0 }
    
  • For header elements that are "empty", the JSON value "" is stored against that header key instead of null.
SIP Body

The object contains key-value elements found in the body section.

Field Type Description
v integer Contant; Set to 0. Do not modify! This tag is used to delimit a session descriptor block.
o string
s string This can be set to null if the item is empty in the SIP message.
i string Optional.
u string Optional.
e string Optional.
p string Optional.
c string Optional.
b string Optional.
t Array Timing for this block. Array of integer values representing the start and end time of the leg.
z string Optional.
k string Optional. Encryption key.
m string Media descriptors
a array Media-level a-line items. Session-level a-line items are not supported.
  • Elements with boolean value types are stored as JSON boolean.
  • Default storage type is string
  • When more than one item with the same name is found, it is stored in an array. "a":{"rtpmap":""} or "a":{"rtpmap":["",""]}.
      "a": { "remote": "",
             "rtpmap": [ "",
                         ""],
             "new_change": true }
    
  • Attribute keys that are a=new_change are stored as "a":{"new_change":true}
Request Document
{
    "meta": {"version": "sip2json/1.10.2/1.0.0", "time": "2020-08-13T12:27:30.555Z", "ttx": 0},
    "s": {
        "type": "request",
        "method": "INVITE",
        "uri": "sip:hello@world.com",
        "version": "SIP/.20"
    },
    "h": {},
    "b": {
        "sdp": [{
            "v": 0,
            "s": "",
            "c": {
                "type": "",
                "subtype": "",
                "dn": ""
            },
            "i": { "dn": "",
                   "name": "",
                   "type": ""
            },
            "o": {
                "user": "",
                "t1": "",
                "t2": "",
                "type": "",
                "subtype": "",
                "host": ""
            },
            "m": "",
            "t": [0, 0],
            "a": {}
        }]
    }
}
Response Document
{
    "meta": {"version": "sip2json/1.10.2/1.0.0", "time": "2020-08-13T12:27:30.555Z", "ttx": 0},
    "s": {
        "type": "response",
        "status": 100,
        "reason": "Trying",
        "version": "SIP/.20"
    },
    "h": {}
}
Request Sample

The source for the following is this sample SIP.

{
    "b": {
        "sdp": [
            {
                "a": {
                    "access_code": "0000000",
                    "acs_guid": "001010000004",
                    "audio_payload": "PCMU",
                    "cdr_start_time": "1594555399.0",
                    "cli-screening": "00",
                    "clir": "false",
                    "dial_once": "aaaa1-aaa13.aaaa2.com",
                    "dialout": "click_in",
                    "far_end": "10.254.254.33:12196",
                    "flags": "1049122",
                    "fmtp": "101 0-15",
                    "ivr": "dialout",
                    "legCallid": "1000000009@10.100.100.100",
                    "leg_no": "3",
                    "mediastatus": "nomedia",
                    "new_change": true,
                    "privs": "participant",
                    "remote": "10.254.254.38:12224",
                    "rtpmap": [
                        "0 pcmu/8000/1",
                        "101 telephone-event/8000"
                    ],
                    "server": "ukdc1-edm18.ring2.com",
                    "sipphone": "usecallid_80000000000000aa-aa-aaaaaa-00@10.254.254.33;port=5060",
                    "status": "(205) answered hold ",
                    "trunk": "8:chan:0",
                    "useforfrom": "hello@world.com",
                    "user-agent": "LoopUp eDial ACS 9.1.0b8050"
                },
                "c": {
                    "dn": "10.254.254.33",
                    "subtype": "IP4",
                    "type": "IN"
                },
                "i": {
                    "dn": "usecallid-leg-3",
                    "name": "usecallid-leg-3",
                    "type": "CallByPhone"
                },
                "m": "audio 8766 RTP/AVP 0 101",
                "o": {
                    "host": "localhost",
                    "subtype": "IP4",
                    "t1": "1011084562",
                    "t2": "804064065",
                    "type": "IN",
                    "user": "hello@world.com"
                },
                "s": "",
                "t": [
                    3803029099,
                    0
                ],
                "v": 0
            }
        ]
    },
    "h": {
        "CSeq": "9 NOTIFY",
        "Call-ID": "80000000000000aa-aa-aaaaaa-00",
        "Contact": "<sip:localhost:8443;transport=ssl>",
        "Content-Length": 880,
        "Content-Type": "application/sdp",
        "From": "sip:hello@world.com;pool=uk-ed-thames;box=ukdc1-edm18.ring2.com;tag=12345678",
        "To": "\"mmyers\" <sip:hello@world.com>",
        "Via": [
            "SIP/2.0/tcp localhost:8443",
            "SIP/2.0/tcp localhost:8443;branch=hello@world.com__eDial_sep__hello@world.com"
        ],
        "X-Billing-code-required": false,
        "X-Call-Instance-ID": "ODQ0NDMaNaU5MaaaOTa1aa1lZC10aGFtZXMtMDE6MTU5NDA0MDI3Naa2NjQ5Nja=",
        "X-Call-Start-Time": "1594040277.665005",
        "X-Call-URL": true,
        "X-Conf_no": "236398",
        "X-From": "hello@world.com",
        "X-Route-ID": "1",
        "X-Sticky": "1",
        "X-Video-SingleView": "0",
        "X-Video-UsingMCU": false,
        "X-client-address": "10.44.200.95",
        "X-control-master": "hello@world.com",
        "X-dialout": "allowed",
        "X-domain": "DEFAULT",
        "X-last-change": "1594040299",
        "X-leader-required": true,
        "X-legs-on-server": "244",
        "X-no-audio": false,
        "X-no-unmute": false,
        "X-no-video": false,
        "X-notify-im": false,
        "X-recording-enabled": true,
        "X-restrict-notify": false,
        "X-restrict-participants": false,
        "X-rollcall": "disabled",
        "X-rss-id": "",
        "X-slave-site": "localhost",
        "X-start-muted": false,
        "X-subject": "Robin Myers' Meeting Room",
        "X-suppress-system-im": false
    },
    "meta": {
        "version": "sip2json/1.10.2/1.0.0",
        "time": "2020-08-13T12:27:30.555Z",
        "ttx": 0
    },
    "s": {
        "method": "NOTIFY",
        "type": "request",
        "uri": "sip:hello@world.com",
        "version": "SIP/2.0"
    }
}

Build and Testing

Build

The project uses CMake with presets for easy configuration across multiple platforms and compilers.

# Configure with a preset
cmake --preset <preset-name>

# Build
cmake --build --preset <preset-name>

# Run tests
ctest --preset <preset-name>

Available Presets:

  • macOS: Apple-Debug, Apple-Release, Apple-Benchmark
  • Linux (GCC): Linux-GCC-Debug, Linux-GCC-Release
  • Linux (Clang): Linux-Clang-Debug, Linux-Clang-Release
  • Windows: Windows-Debug, Windows-Release
Manual Build
# Configure
cmake . -DCMAKE_BUILD_TYPE=Release -Dsip2json_BUILD_TESTS=ON

# Build
cmake --build .

# Run tests
ctest .
Cleaning Build Artifacts

To clean the repository of CMake-generated files and cached data:

git clean -d -x -f

File Termination (CRLF)

The SIP message samples are CRLF terminated. The repository includes a .gitattributes file that specifies proper handling of *.sip files. If tests fail, verify the EOL markers in sample files are correct.

Code Quality

  • Linting: Clang-Tidy enforces best practices and static code analysis
  • Formatting: Clang Format ensures consistent code style
  • Testing: 64+ tests covering parsing and serialization
  • Coverage: Code coverage reports available in CI (Visual Studio Enterprise)

External resources

Product Compatible and additional computed target framework versions.
native native is compatible. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.

NuGet packages

This package is not used by any NuGet packages.

GitHub repositories (1)

Showing the top 1 popular GitHub repositories that depend on SiddiqSoft.sip2json:

Repository Stars
ubisoft/Sharpmake
Sharpmake is an open-source C#-based solution for generating project definition files, such as Visual Studio projects and solutions, GNU makefiles, Xcode projects, etc.
Version Downloads Last Updated
2.4.0 106 5/5/2026
2.3.3 113 5/4/2026
2.3.2 104 5/4/2026
2.3.1 111 5/4/2026
2.3.0 129 5/4/2026
2.2.2 132 4/29/2026
1.17.3 3,110 12/9/2024
1.17.2 504 12/9/2024
1.17.1 489 12/7/2024
1.17.0 501 11/30/2024
1.16.4 551 10/24/2024
1.16.3 507 10/24/2024
1.16.2 495 10/24/2024
1.16.0 482 10/21/2024
1.15.4 508 10/18/2024
1.15.3 486 10/15/2024
1.15.2 489 10/4/2024
1.15.1 492 10/4/2024
1.15.0 493 10/4/2024
1.14.12 485 10/4/2024
Loading failed