#sip #voip #sofia

sys sofia-sip

Rust bindings for sofia-sip

1 unstable release

0.1.0 Jul 6, 2021
0.0.1 Jun 27, 2021

#4 in #voip

MIT license

6.5MB
156K SLoC

C 135K SLoC // 0.2% comments Visual Studio Project 14K SLoC Rust 2K SLoC // 0.2% comments Automake 1.5K SLoC // 0.3% comments M4 1K SLoC // 0.2% comments AWK 651 SLoC // 0.2% comments Batch 304 SLoC // 0.4% comments Visual Studio Solution 197 SLoC Bitbake 125 SLoC // 0.0% comments RPM Specfile 86 SLoC // 0.1% comments Perl 84 SLoC // 0.0% comments C++ 69 SLoC // 0.5% comments Shell 36 SLoC // 0.5% comments

Contains (Cab file, 52KB) autotools.vsd, (Cab file, 36KB) SIP_outgoing_call.vsd, (Cab file, 18KB) SIP_basic_incoming_operation.vsd, (Cab file, 24KB) SIP_basic_outgoing_operation.vsd, (Cab file, 33KB) SIP_incoming_call.vsd, (Cab file, 27KB) SIP_outgoing_operation_with_auth.vsd and 1 more.

Sofia-SIP

Rust bindings for Sofia-SIP (Alpha stage).

Usage

Add the following to your Cargo.toml:

[dependencies]
sofia-sip = "0.1.0"

Example

use sofia_sip::{Handle, Nua, NuaEvent, Sip, Tag, TagBuilder};

fn main() {
    /*
    A                    B
    |-------MESSAGE----->|
    |<--------200--------|
    |                    |

                           ______(NETWORK)_____
                          /                    \
    A                 NUA STACK (A)
    |                     |
    |    nua::handle( )   |
    |-------------------->|
    |                     |
    |  handle::message()  |
    |------------------->[_]      [MESSAGE]
    |                    [_]------------------>
    |                    [_]
    |                    [_]
    |                    [_]      [200 OK]
    |    ReplyMessage    [_]<------------------
    |<------------------ [_]
    |                     |
    |                     |
    */

    /* bind on :5080 */
    let sip_bind_url = "sip:*:5080";

    /* send to a SIP contact running in 192.168.0.51 on default port */
    let sip_to_url = "sip:600@192.168.0.51:5060";

    /* build params for Nua::create */
    let tags = TagBuilder::default()
        .tag(Tag::NuUrl(sip_bind_url).unwrap())
        .collect();

    /* create NUA stack */
    let mut nua = Nua::create(tags).unwrap();

    /*
    Handling of the events coming from NUA stack is done
    in the callback function that is registered for NUA stack
    */
    nua.callback(
        |nua: &mut Nua,
         event: NuaEvent,
         status: u32,
         phrase: String,
         _handle: Option<&Handle>,
         sip: Sip,
         _tags: Vec<Tag>| {
            println!("({:?}) status: {} | {}", &event, status, &phrase);
            match event {
                NuaEvent::ReplyShutdown => { /* received when NUA stack is about to shutdown */ }
                NuaEvent::IncomingMessage => {
                    /* incoming NEW message */
                    println!("Received MESSAGE: {} {}", status, &phrase);
                    println!("From: {}", sip.from());
                    println!("To: {}", sip.to());
                    println!("Subject: {}", sip.subject());
                    println!("ContentType: {}", sip.content_type());
                    println!("Payload: {:?}", sip.payload().as_utf8_lossy());

                    /* quit after new message */
                    nua.quit();
                }
                NuaEvent::ReplyMessage => {
                    /* quit if response != 200 */
                    if status != 202 {
                        nua.quit();
                    }
                }
                _ => {

                }
            }
        },
    );

    /* Message to be send */
    let my_message = "Hi Sofia-SIP-sys";

    /* build params for Handle::create */
    let tags = TagBuilder::default()
        .tag(Tag::SipTo(sip_to_url).unwrap())
        .tag(Tag::NuUrl(sip_to_url).unwrap())
        .collect();

    /* create operation handle */
    let handle = Handle::create(&nua, tags).unwrap();

    /* build params for handle.message() */
    let tags = TagBuilder::default()
        .tag(Tag::SipSubject("NUA").unwrap())
        .tag(Tag::SipTo(sip_to_url).unwrap())
        .tag(Tag::NuUrl(sip_to_url).unwrap())
        .tag(Tag::SipContentType("text/plain").unwrap())
        .tag(Tag::SipPayloadString(my_message).unwrap())
        .collect();

    /* The message() function enqueue a SIP MESSAGE on NUA STACK */
    handle.message(tags);

    /* enter main loop for processing of messages */
    println!("enter the main loop");
    nua.run();
    println!("the main loop exit");
}

Documentation

Sofia-SIP Rust bindings tries to mimic almost as possible the API of Sofia-SIP C library. You can start by learning the concepts of Sofia SIP User Agent Library - "nua" - High-Level User Agent Module.

After this intro, please read the tests from Nua module.

Sofia-SIP C docs

Sofia SIP User Agent Library - sofia-sip-ua

Common runtime library:

SIP Signaling:

HTTP subsystem:

SDP processing:

Other:

Acknowledgements

Authors

License

Before compiling statically, please read this.

Roadmap

  • Version 0.1.0 -> DONE

    • NUA: Basic support to send and receive SIP MESSAGE's, allowing to create a chat using SIP.
  • Version 0.2.0

    • NUA: Basic support to send SIP INVITE(SDP)/REGISTER(auth) and receive SIP INVITE(SDP), allowing to create a simple soft phone.
    • Others modules: basic support to make NUA objectives work.
  • Version 0.3.0

    • NUA: Support receive SIP REGISTER(auth), allowing to create a simple SIP PBX.
    • Others modules: basic support to make NUA objectives work.
  • Version 1.0.0

    • NUA: Full bindings for NUA.
    • SDP: Full support for SDP parsing.

NUA is the High-Level User Agent Module of lib-sofia. To learn more about sofia modules, go to reference documentation for libsofia-sip-ua submodules.

Dependencies