### Initiate SIP Call with eXosip2 Source: https://github.com/aurelihein/exosip/blob/master/help/doxygen/ht1-callcontrol.dox Demonstrates how to build and send an initial SIP INVITE request to start an outgoing call. It includes setting up necessary headers and the SDP body for audio parameters. The function returns a call identifier (cid) for further control. ```c int i; osip_message_t *invite; int cid; char tmp[4096]; char localip[128]; i = eXosip_call_build_initial_invite (ctx, &invite, "", "", NULL, // optional route header "This is a call for a conversation"); if (i != 0) { return -1; } osip_message_set_supported (invite, "100rel"); eXosip_guess_localip (ctx, AF_INET, localip, 128); snprintf (tmp, 4096, "v=0\r\n" "o=jack 0 0 IN IP4 %s\r\n" "s=conversation\r\n" "c=IN IP4 %s\r\n" "t=0 0\r\n" "m=audio %s RTP/AVP 0 8 101\r\n" "a=rtpmap:0 PCMU/8000\r\n" "a=rtpmap:8 PCMA/8000\r\n" "a=rtpmap:101 telephone-event/8000\r\n" "a=fmtp:101 0-11\r\n", localip, localip, port); osip_message_set_body (invite, tmp, strlen (tmp)); osip_message_set_content_type (invite, "application/sdp"); eXosip_lock (ctx); cid = eXosip_call_send_initial_invite (ctx, invite); if (cid > 0) { eXosip_call_set_reference (ctx, i, reference); } eXosip_unlock (ctx); return i; ``` -------------------------------- ### Initialize eXosip2 Library and Setup Transport Source: https://context7.com/aurelihein/exosip/llms.txt This snippet demonstrates the fundamental steps to initialize the eXosip2 library, configure a listening UDP transport on a specified port, set a User-Agent header, and configure NAT traversal. It includes error handling for context allocation and initialization. ```c #include int main(int argc, char *argv[]) { struct eXosip_t *ctx; int port = 5060; /* Allocate eXosip context */ ctx = eXosip_malloc(); if (ctx == NULL) { fprintf(stderr, "Failed to allocate eXosip context\n"); return -1; } /* Initialize eXosip */ if (eXosip_init(ctx) != 0) { fprintf(stderr, "eXosip_init failed\n"); return -1; } /* Start listening on UDP port 5060 for IPv4 */ if (eXosip_listen_addr(ctx, IPPROTO_UDP, NULL, port, AF_INET, 0) != 0) { fprintf(stderr, "eXosip_listen_addr failed\n"); eXosip_quit(ctx); return -1; } /* Set User-Agent header */ eXosip_set_user_agent(ctx, "MyVoIPApp/1.0"); /* Configure NAT traversal with public IP */ eXosip_masquerade_contact(ctx, "203.0.113.50", port); /* Get library version */ printf("eXosip version: %s\n", eXosip_get_version()); /* Main event loop... */ /* Cleanup and shutdown */ eXosip_quit(ctx); return 0; } ``` -------------------------------- ### Implement SIP User Agent with eXosip2 Source: https://context7.com/aurelihein/exosip/llms.txt This example demonstrates a complete SIP user agent lifecycle, including initialization, registration with authentication, and an event loop to handle incoming calls and messages. It uses eXosip2's event-driven architecture to manage SIP transactions and automatic actions. ```c #include #include #include #include #include static int running = 1; static struct eXosip_t *ctx = NULL; static int rid = -1; void signal_handler(int sig) { running = 0; } int main(int argc, char *argv[]) { eXosip_event_t *event; osip_message_t *reg = NULL; signal(SIGINT, signal_handler); signal(SIGTERM, signal_handler); ctx = eXosip_malloc(); if (ctx == NULL || eXosip_init(ctx) != 0) { fprintf(stderr, "Failed to initialize eXosip\n"); return 1; } if (eXosip_listen_addr(ctx, IPPROTO_UDP, NULL, 5060, AF_INET, 0) != 0) { fprintf(stderr, "Failed to bind to port 5060\n"); eXosip_quit(ctx); return 1; } eXosip_set_user_agent(ctx, "MyUA/1.0"); eXosip_add_authentication_info(ctx, "alice", "alice", "password123", NULL, NULL); rid = eXosip_register_build_initial_register(ctx, "sip:alice@sip.example.com", "sip:sip.example.com", NULL, 3600, ®); if (rid > 0) { eXosip_register_send_register(ctx, rid, reg); printf("Registration request sent\n"); } while (running) { event = eXosip_event_wait(ctx, 0, 100); eXosip_automatic_action(ctx); if (event == NULL) continue; switch (event->type) { case EXOSIP_REGISTRATION_SUCCESS: printf("Registered successfully!\n"); break; case EXOSIP_CALL_INVITE: eXosip_lock(ctx); eXosip_call_send_answer(ctx, event->tid, 180, NULL); eXosip_unlock(ctx); break; case EXOSIP_MESSAGE_NEW: eXosip_lock(ctx); eXosip_message_send_answer(ctx, event->tid, 200, NULL); eXosip_unlock(ctx); break; } eXosip_event_free(event); } eXosip_quit(ctx); return 0; } ``` -------------------------------- ### Answer Incoming SIP Call with eXosip2 Source: https://github.com/aurelihein/exosip/blob/master/help/doxygen/ht1-callcontrol.dox Provides code examples for answering an incoming SIP call. It first shows how to send a '180 Ringing' response and then how to build and send a '200 OK' response with an SDP body, negotiating audio parameters. ```c eXosip_lock (ctx); eXosip_call_send_answer (ctx, evt->tid, 180, NULL); eXosip_unlock (ctx); ``` ```c osip_message_t *answer = NULL; int i; eXosip_lock (ctx); i = eXosip_call_build_answer (ctx, evt->tid, 200, &answer); if (i != 0) { eXosip_call_send_answer (ctx, evt->tid, 400, NULL); } else { i = sdp_complete_200ok (evt->did, answer); if (i != 0) { osip_message_free (answer); eXosip_call_send_answer (ctx, evt->tid, 415, NULL); } else eXosip_call_send_answer (ctx, evt->tid, 200, answer); } eXosip_unlock (ctx); ``` ```c osip_message_set_body (answer, tmp, strlen (tmp)); osip_message_set_content_type (answer, "application/sdp"); ``` -------------------------------- ### Perform Blind Call Transfer in C Source: https://context7.com/aurelihein/exosip/llms.txt Illustrates how to initiate a blind call transfer by constructing and sending a REFER request outside of an established call dialog. This is useful for transferring calls to a new destination without requiring prior dialog setup. ```c #include int blind_transfer(struct eXosip_t *ctx, const char *target_uri, const char *from, const char *to) { osip_message_t *refer = NULL; /* Build REFER for blind transfer */ if (eXosip_refer_build_request(ctx, &refer, target_uri, /* refer-to: where to transfer */ from, /* from */ to, /* to: who to transfer */ NULL /* route */ ) != 0) { return -1; } eXosip_lock(ctx); int result = eXosip_refer_send_request(ctx, refer); eXosip_unlock(ctx); return result; } ``` -------------------------------- ### Handle Exosip2 Events Source: https://github.com/aurelihein/exosip/blob/master/help/doxygen/ht0-initialize.dox This code snippet demonstrates how to retrieve and process exosip2 events. It uses a loop with eXosip_event_wait to get events, followed by locking, automatic actions, and unlocking the context. Different event types like EXOSIP_CALL_NEW, EXOSIP_CALL_ACK, and EXOSIP_CALL_ANSWERED are handled. ```c eXosip_event_t *evt; for (;;) { evt = eXosip_event_wait (ctx, 0, 50); eXosip_lock(ctx); eXosip_automatic_action (ctx); eXosip_unlock(ctx); if (evt == NULL) continue; if (evt->type == EXOSIP_CALL_NEW) { .... .... } else if (evt->type == EXOSIP_CALL_ACK) { .... .... } else if (evt->type == EXOSIP_CALL_ANSWERED) { .... .... } else ..... .... .... eXosip_event_free(evt); } ``` -------------------------------- ### Initialize eXosip and osip Stack Source: https://github.com/aurelihein/exosip/blob/master/help/doxygen/ht0-initialize.dox Initializes the osip trace, the eXosip context, and the libosip library. This is a mandatory first step before using any libeXosip2 functions. It requires the ENABLE_TRACE compile flag for TRACE_INITIALIZE. ```c #include eXosip_t *ctx; int i; int port=5060; TRACE_INITIALIZE (6, NULL); ctx = eXosip_malloc(); if (ctx==NULL) return -1; i=eXosip_init(ctx); if (i!=0) return -1; ``` -------------------------------- ### Send and Handle OPTIONS Request in C Source: https://context7.com/aurelihein/exosip/llms.txt Demonstrates sending an OPTIONS request to query remote user agent capabilities and handling an incoming OPTIONS request by building an appropriate answer with Allow and Accept headers. This functionality is crucial for endpoint availability checks and capability negotiation. ```c #include /* Send OPTIONS request */ int send_options(struct eXosip_t *ctx, const char *to, const char *from) { osip_message_t *options = NULL; if (eXosip_options_build_request(ctx, &options, to, from, NULL) != 0) { return -1; } eXosip_lock(ctx); int result = eXosip_options_send_request(ctx, options); eXosip_unlock(ctx); return result; } /* Respond to incoming OPTIONS */ void handle_options_request(struct eXosip_t *ctx, eXosip_event_t *event) { osip_message_t *answer = NULL; eXosip_lock(ctx); if (eXosip_options_build_answer(ctx, event->tid, 200, &answer) == 0) { /* Add capabilities headers */ osip_message_set_header(answer, "Allow", "INVITE, ACK, BYE, CANCEL, OPTIONS, MESSAGE, INFO, UPDATE, REFER"); osip_message_set_header(answer, "Accept", "application/sdp, text/plain"); osip_message_set_header(answer, "Accept-Language", "en"); eXosip_options_send_answer(ctx, event->tid, 200, answer); } eXosip_unlock(ctx); } ``` -------------------------------- ### Initiate a SIP Registration Source: https://github.com/aurelihein/exosip/blob/master/help/doxygen/ht2-registration.dox Builds and sends an initial REGISTER request to a SIP server. It requires a valid eXosip context and returns a registration identifier for future operations. ```c osip_message_t *reg = NULL; int rid; int i; eXosip_lock (ctx); rid = eXosip_register_build_initial_register (ctx, "sip:me@sip.antisip.com", "sip.antisip.com", NULL, 1800, ®); if (rid < 0) { eXosip_unlock (ctx); return -1; } osip_message_set_supported (reg, "100rel"); osip_message_set_supported (reg, "path"); i = eXosip_register_send_register (ctx, rid, reg); eXosip_unlock (ctx); return i; ``` -------------------------------- ### Configuration Options Source: https://context7.com/aurelihein/exosip/llms.txt Details on setting various eXosip2 library options for UDP keep-alive, rport, DNS, NAT traversal, and DSCP. ```APIDOC ## Configuration Options Set various library options for UDP keep-alive, rport, DNS, NAT traversal, and DSCP. ### Description This function `configure_options` demonstrates how to set several important eXosip2 library options using `eXosip_set_option`, including UDP keep-alive, RFC 3581 rport extension, learning remote port, adding static DNS entries, configuring per-account NAT information, setting DSCP for QoS, and specifying DNS capabilities. ### Method N/A (C function) ### Endpoint N/A ### Parameters #### Path Parameters N/A #### Query Parameters N/A #### Request Body N/A ### Request Example ```c #include void configure_options(struct eXosip_t *ctx) { int val; struct eXosip_dns_cache dns_entry; struct eXosip_account_info account; /* Enable UDP keep-alive (sends CRLF periodically) */ val = 30; /* interval in seconds */ eXosip_set_option(ctx, EXOSIP_OPT_UDP_KEEP_ALIVE, &val); /* Enable rport extension (RFC 3581) */ val = 1; eXosip_set_option(ctx, EXOSIP_OPT_USE_RPORT, &val); /* Enable learning port from Via received responses */ val = 1; eXosip_set_option(ctx, EXOSIP_OPT_UDP_LEARN_PORT, &val); /* Add static DNS cache entry */ memset(&dns_entry, 0, sizeof(dns_entry)); strncpy(dns_entry.host, "sip.example.com", sizeof(dns_entry.host) - 1); strncpy(dns_entry.ip, "192.0.2.1", sizeof(dns_entry.ip) - 1); eXosip_set_option(ctx, EXOSIP_OPT_ADD_DNS_CACHE, &dns_entry); /* Configure per-account NAT IP */ memset(&account, 0, sizeof(account)); strncpy(account.proxy, "sip:sip.example.com", sizeof(account.proxy) - 1); strncpy(account.nat_ip, "203.0.113.50", sizeof(account.nat_ip) - 1); account.nat_port = 5060; eXosip_set_option(ctx, EXOSIP_OPT_ADD_ACCOUNT_INFO, &account); /* Set DSCP value for QoS */ val = 46; /* EF PHB for voice */ eXosip_set_option(ctx, EXOSIP_OPT_SET_DSCP, &val); /* Configure DNS capabilities (NAPTR/SRV) */ val = 2; /* 0=A only, 1=SRV, 2=NAPTR+SRV */ eXosip_set_option(ctx, EXOSIP_OPT_DNS_CAPABILITIES, &val); } ``` ### Response N/A (This is a configuration function, not an API endpoint) #### Success Response (200) N/A #### Response Example N/A ``` -------------------------------- ### Configure eXosip2 Library Options Source: https://context7.com/aurelihein/exosip/llms.txt Configures various operational parameters for the eXosip2 library. This includes enabling UDP keep-alive, the rport extension, and learning the port from received responses. It also demonstrates setting static DNS cache entries, configuring per-account NAT information, setting DSCP values for QoS, and specifying DNS resolution capabilities (NAPTR/SRV). ```c #include void configure_options(struct eXosip_t *ctx) { int val; struct eXosip_dns_cache dns_entry; struct eXosip_account_info account; /* Enable UDP keep-alive (sends CRLF periodically) */ val = 30; /* interval in seconds */ eXosip_set_option(ctx, EXOSIP_OPT_UDP_KEEP_ALIVE, &val); /* Enable rport extension (RFC 3581) */ val = 1; eXosip_set_option(ctx, EXOSIP_OPT_USE_RPORT, &val); /* Enable learning port from Via received responses */ val = 1; eXosip_set_option(ctx, EXOSIP_OPT_UDP_LEARN_PORT, &val); /* Add static DNS cache entry */ memset(&dns_entry, 0, sizeof(dns_entry)); strncpy(dns_entry.host, "sip.example.com", sizeof(dns_entry.host) - 1); strncpy(dns_entry.ip, "192.0.2.1", sizeof(dns_entry.ip) - 1); eXosip_set_option(ctx, EXOSIP_OPT_ADD_DNS_CACHE, &dns_entry); /* Configure per-account NAT IP */ memset(&account, 0, sizeof(account)); strncpy(account.proxy, "sip:sip.example.com", sizeof(account.proxy) - 1); strncpy(account.nat_ip, "203.0.113.50", sizeof(account.nat_ip) - 1); account.nat_port = 5060; eXosip_set_option(ctx, EXOSIP_OPT_ADD_ACCOUNT_INFO, &account); /* Set DSCP value for QoS */ val = 46; /* EF PHB for voice */ eXosip_set_option(ctx, EXOSIP_OPT_SET_DSCP, &val); /* Configure DNS capabilities (NAPTR/SRV) */ val = 2; /* 0=A only, 1=SRV, 2=NAPTR+SRV */ eXosip_set_option(ctx, EXOSIP_OPT_DNS_CAPABILITIES, &val); } ``` -------------------------------- ### Manage SIP Presence Subscriptions (C) Source: https://context7.com/aurelihein/exosip/llms.txt Handles managing presence subscriptions using SUBSCRIBE and NOTIFY requests. It includes functions to build and send initial SUBSCRIBE requests, refresh existing subscriptions, and handle incoming SUBSCRIBE requests by sending a 200 OK and an initial NOTIFY with presence status. Requires the eXosip2 library. ```c #include /* Subscribe to presence */ int subscribe_presence(struct eXosip_t *ctx, const char *to, const char *from) { osip_message_t *subscribe = NULL; int expires = 3600; if (eXosip_subscribe_build_initial_request(ctx, &subscribe, to, from, NULL, "presence", expires) != 0) { return -1; } /* Add Accept header for presence documents */ osip_message_set_header(subscribe, "Accept", "application/pidf+xml, application/xpidf+xml"); eXosip_lock(ctx); int sid = eXosip_subscribe_send_initial_request(ctx, subscribe); eXosip_unlock(ctx); return sid; } /* Refresh subscription */ int refresh_subscription(struct eXosip_t *ctx, int did) { osip_message_t *subscribe = NULL; eXosip_lock(ctx); if (eXosip_subscribe_build_refresh_request(ctx, did, &subscribe) == 0) { eXosip_subscribe_send_refresh_request(ctx, did, subscribe); } eXosip_unlock(ctx); return 0; } /* Handle incoming SUBSCRIBE (as a presence server) */ void handle_incoming_subscribe(struct eXosip_t *ctx, eXosip_event_t *event) { osip_message_t *answer = NULL; osip_message_t *notify = NULL; eXosip_lock(ctx); /* Accept subscription with 200 OK */ if (eXosip_insubscription_build_answer(ctx, event->tid, 200, &answer) == 0) { eXosip_insubscription_send_answer(ctx, event->tid, 200, answer); } /* Send initial NOTIFY with presence state */ if (eXosip_insubscription_build_notify(ctx, event->did, EXOSIP_SUBCRSTATE_ACTIVE, EXOSIP_NOTIFY_ONLINE, ¬ify) == 0) { const char *pidf_body = "\r\n" " " " " " open " " " "\r\n"; osip_message_set_body(notify, pidf_body, strlen(pidf_body)); osip_message_set_content_type(notify, "application/pidf+xml"); eXosip_insubscription_send_request(ctx, event->did, notify); } eXosip_unlock(ctx); } ``` -------------------------------- ### SIP Registration with eXosip2 Source: https://context7.com/aurelihein/exosip/llms.txt Handles user registration with a SIP registrar by building and sending REGISTER requests. The library tracks registration context by ID for subsequent refresh operations. It supports initial registration, refresh, unregistration, and removal of registration contexts. ```c #include int register_user(struct eXosip_t *ctx) { osip_message_t *reg = NULL; int rid; int expires = 3600; /* Registration expires in 1 hour */ /* Build initial REGISTER request */ rid = eXosip_register_build_initial_register(ctx, "sip:alice@sip.example.com", /* from (AOR) */ "sip:sip.example.com", /* proxy/registrar */ "sip:alice@192.168.1.100:5060", /* contact (optional, NULL for auto) */ expires, ®); if (rid < 1) { fprintf(stderr, "Failed to build initial REGISTER\n"); return -1; } /* Send the registration */ if (eXosip_register_send_register(ctx, rid, reg) != 0) { fprintf(stderr, "Failed to send REGISTER\n"); return -1; } printf("Registration sent, rid=%d\n", rid); /* Later: refresh registration before expiry */ osip_message_t *refresh = NULL; if (eXosip_register_build_register(ctx, rid, expires, &refresh) == 0) { eXosip_register_send_register(ctx, rid, refresh); } /* Unregister (expires=0) */ osip_message_t *unreg = NULL; if (eXosip_register_build_register(ctx, rid, 0, &unreg) == 0) { eXosip_register_send_register(ctx, rid, unreg); } /* Remove registration context without sending REGISTER */ eXosip_register_remove(ctx, rid); return rid; } ``` -------------------------------- ### Call Management with eXosip2 (INVITE/BYE) Source: https://context7.com/aurelihein/exosip/llms.txt Manages the complete call lifecycle using SIP INVITE, ACK, and BYE requests. It includes functionalities for initiating outgoing calls with SDP for media negotiation, answering incoming calls, terminating calls, and sending acknowledgments. ```c #include /* Initiate an outgoing call */ int make_call(struct eXosip_t *ctx) { osip_message_t *invite = NULL; int cid; /* Build INVITE request */ if (eXosip_call_build_initial_invite(ctx, &invite, "sip:bob@sip.example.com", /* to */ "sip:alice@sip.example.com", /* from */ NULL, /* route (optional) */ "Call from Alice" /* subject */ ) != 0) { return -1; } /* Add SDP body for media offer */ osip_message_set_body(invite, "v=0\r\n" "o=alice 123456 654321 IN IP4 192.168.1.100\r\n" "s=A call\r\n" "c=IN IP4 192.168.1.100\r\n" "t=0 0\r\n" "m=audio 49170 RTP/AVP 0 8 97\r\n" "a=rtpmap:0 PCMU/8000\r\n" "a=rtpmap:8 PCMA/8000\r\n" "a=rtpmap:97 opus/48000/2\r\n", strlen("v=0\r\n...")); /* actual length */ osip_message_set_content_type(invite, "application/sdp"); /* Send the INVITE - returns call-id */ eXosip_lock(ctx); cid = eXosip_call_send_initial_invite(ctx, invite); eXosip_unlock(ctx); if (cid < 0) { fprintf(stderr, "Failed to send INVITE\n"); return -1; } printf("Call initiated, cid=%d\n", cid); return cid; } /* Answer an incoming call */ int answer_call(struct eXosip_t *ctx, int tid, int did) { osip_message_t *answer = NULL; /* Build 200 OK response */ if (eXosip_call_build_answer(ctx, tid, 200, &answer) != 0) { /* Send 500 error if can't build answer */ eXosip_call_send_answer(ctx, tid, 500, NULL); return -1; } /* Add SDP answer body */ osip_message_set_body(answer, "v=0\r\n" "o=bob 789012 210987 IN IP4 192.168.1.200\r\n" "s=Call answer\r\n" "c=IN IP4 192.168.1.200\r\n" "t=0 0\r\n" "m=audio 49180 RTP/AVP 0\r\n" "a=rtpmap:0 PCMU/8000\r\n", strlen("v=0\r\n...")); osip_message_set_content_type(answer, "application/sdp"); /* Send 200 OK */ eXosip_lock(ctx); eXosip_call_send_answer(ctx, tid, 200, answer); eXosip_unlock(ctx); return 0; } /* Terminate a call */ void hangup_call(struct eXosip_t *ctx, int cid, int did) { eXosip_lock(ctx); /* Sends CANCEL, BYE, or 603 Decline depending on call state */ eXosip_call_terminate(ctx, cid, did); eXosip_unlock(ctx); } /* Send ACK after receiving 200 OK for INVITE */ void send_ack(struct eXosip_t *ctx, int did) { osip_message_t *ack = NULL; eXosip_lock(ctx); if (eXosip_call_build_ack(ctx, did, &ack) == 0) { eXosip_call_send_ack(ctx, did, ack); } eXosip_unlock(ctx); } ``` -------------------------------- ### TLS Configuration Source: https://context7.com/aurelihein/exosip/llms.txt Shows how to configure TLS/SIPS transport with certificates for secure SIP signaling using eXosip2. ```APIDOC ## TLS Configuration Configure TLS/SIPS transport with certificates for secure SIP signaling. ### Description This function `setup_tls` configures the TLS context for eXosip2, specifying certificate paths and enabling secure listening on a specified port. ### Method N/A (C function) ### Endpoint N/A ### Parameters #### Path Parameters N/A #### Query Parameters N/A #### Request Body N/A ### Request Example ```c #include int setup_tls(struct eXosip_t *ctx) { eXosip_tls_ctx_t tls_ctx; eXosip_tls_ctx_error err; memset(&tls_ctx, 0, sizeof(tls_ctx)); /* Configure TLS context */ strncpy(tls_ctx.root_ca_cert, "/etc/ssl/certs/ca-certificates.crt", sizeof(tls_ctx.root_ca_cert) - 1); strncpy(tls_ctx.client.cert, "/etc/ssl/client.crt", sizeof(tls_ctx.client.cert) - 1); strncpy(tls_ctx.client.priv_key, "/etc/ssl/client.key", sizeof(tls_ctx.client.priv_key) - 1); strncpy(tls_ctx.client.priv_key_pw, "keypassword", sizeof(tls_ctx.client.priv_key_pw) - 1); /* Set TLS context */ err = eXosip_set_tls_ctx(ctx, &tls_ctx); if (err != TLS_OK) { fprintf(stderr, "TLS setup failed: %d\n", err); return -1; } /* Enable certificate verification */ eXosip_tls_verify_certificate(ctx, 1); /* Listen on TLS (secure=1) */ if (eXosip_listen_addr(ctx, IPPROTO_TCP, NULL, 5061, AF_INET, 1) != 0) { fprintf(stderr, "Failed to listen on TLS\n"); return -1; } return 0; } ``` ### Response N/A (This is a configuration function, not an API endpoint) #### Success Response (200) N/A #### Response Example N/A ``` -------------------------------- ### SDP Helper Functions Source: https://context7.com/aurelihein/exosip/llms.txt Demonstrates how to extract and parse SDP (Session Description Protocol) information from SIP messages using eXosip2 functions. ```APIDOC ## SDP Helper Functions Extract and parse SDP (Session Description Protocol) information from SIP messages for media negotiation. ### Description This function `process_sdp` takes an eXosip context and an event, retrieves the remote SDP, and extracts connection and media information for audio and video. ### Method N/A (C function) ### Endpoint N/A ### Parameters #### Path Parameters N/A #### Query Parameters N/A #### Request Body N/A ### Request Example ```c #include void process_sdp(struct eXosip_t *ctx, eXosip_event_t *event) { sdp_message_t *remote_sdp = NULL; sdp_connection_t *conn = NULL; sdp_media_t *media = NULL; /* Get remote SDP from dialog */ eXosip_lock(ctx); remote_sdp = eXosip_get_remote_sdp(ctx, event->did); eXosip_unlock(ctx); if (remote_sdp == NULL) { /* Try getting SDP from specific message */ remote_sdp = eXosip_get_sdp_info(event->request); } if (remote_sdp == NULL) { printf("No SDP found\n"); return; } /* Get audio connection info */ conn = eXosip_get_audio_connection(remote_sdp); if (conn) { printf("Audio connection: %s\n", conn->c_addr); } /* Get audio media info */ media = eXosip_get_audio_media(remote_sdp); if (media) { printf("Audio port: %s\n", media->m_port); printf("Audio protocol: %s\n", media->m_proto); } /* Get video connection info */ conn = eXosip_get_video_connection(remote_sdp); if (conn) { printf("Video connection: %s\n", conn->c_addr); } /* Get any media type by name */ conn = eXosip_get_connection(remote_sdp, "video"); media = eXosip_get_media(remote_sdp, "video"); /* Get local SDP that was sent */ sdp_message_t *local_sdp = NULL; eXosip_lock(ctx); local_sdp = eXosip_get_local_sdp(ctx, event->did); eXosip_unlock(ctx); /* Free SDP when done */ sdp_message_free(remote_sdp); if (local_sdp) sdp_message_free(local_sdp); } ``` ### Response N/A (This is a helper function, not an API endpoint) #### Success Response (200) N/A #### Response Example N/A ``` -------------------------------- ### Send Custom SIP Request with Headers and Body Source: https://github.com/aurelihein/exosip/blob/master/help/doxygen/ht1-callcontrol.dox Shows how to create a custom SIP request using eXosip_call_build_request, add custom headers with osip_message_set_header, and attach a body. This is useful for proprietary signaling or domotic control messages. ```c osip_message_t *message; char body[1000]; int i; eXosip_lock (ctx); i = eXosip_call_build_request (ctx, evt->did, "PRIVATECOMMAND", &message); if (i == 0) { snprintf (body, 999, "room=1;light=on\r\nroom=2;light=off\r\n"); osip_message_set_content_type (message, "application/antisip-domotic"); osip_message_set_body (message, body, strlen (body)); osip_message_set_header (invite, "P-MyCommand", "option=value"); i = eXosip_call_send_request (ctx, evt->did, message); } eXosip_unlock (ctx); ``` -------------------------------- ### Send and Receive SIP MESSAGE for Instant Messaging (C) Source: https://context7.com/aurelihein/exosip/llms.txt Implements sending and receiving SIP MESSAGE requests for instant messaging. It handles building the MESSAGE request, setting the body and content type, and sending it. For incoming messages, it extracts the message body and sends a 200 OK response. Requires the eXosip2 library. ```c #include /* Send an instant message */ int send_message(struct eXosip_t *ctx, const char *to, const char *from, const char *text) { osip_message_t *message = NULL; if (eXosip_message_build_request(ctx, &message, "MESSAGE", to, from, NULL) != 0) { return -1; } osip_message_set_body(message, text, strlen(text)); osip_message_set_content_type(message, "text/plain"); eXosip_lock(ctx); int result = eXosip_message_send_request(ctx, message); eXosip_unlock(ctx); return result; } /* Handle incoming MESSAGE and send response */ void handle_incoming_message(struct eXosip_t *ctx, eXosip_event_t *event) { osip_body_t *body = NULL; osip_message_t *answer = NULL; /* Extract message body */ osip_message_get_body(event->request, 0, &body); if (body && body->body) { printf("Received message: %s\n", body->body); } /* Send 200 OK response */ eXosip_lock(ctx); if (eXosip_message_build_answer(ctx, event->tid, 200, &answer) == 0) { eXosip_message_send_answer(ctx, event->tid, 200, answer); } eXosip_unlock(ctx); } ``` -------------------------------- ### Set Additional eXosip Options Source: https://github.com/aurelihein/exosip/blob/master/help/doxygen/ht0-initialize.dox Configures various optional settings for the eXosip library to fine-tune its behavior. This includes setting the user agent, UDP keep-alive, DNS capabilities, RPORT usage, DSCP values, and IPv4/IPv6 gateway settings. These options can be modified using eXosip_set_user_agent and eXosip_set_option functions. ```c int val; eXosip_set_user_agent (ctx, "exosipdemo/0.0.0"); val=17000; eXosip_set_option (ctx, EXOSIP_OPT_UDP_KEEP_ALIVE, &val); val=2; eXosip_set_option (ctx, EXOSIP_OPT_DNS_CAPABILITIES, &val); val=1; eXosip_set_option (ctx, EXOSIP_OPT_USE_RPORT, &val); val=26; eXosip_set_option (ctx, EXOSIP_OPT_SET_DSCP, &dscp_value); eXosip_set_option (ctx, EXOSIP_OPT_SET_IPV4_FOR_GATEWAY, "sip.antisip.com"); ``` -------------------------------- ### Implement eXosip2 Event Loop Source: https://context7.com/aurelihein/exosip/llms.txt This snippet demonstrates a standard event loop using eXosip_event_wait to poll for SIP events. It includes a switch statement to handle various event types such as registrations, call states, and subscription notifications, while ensuring automatic actions are processed. ```c #include void event_loop(struct eXosip_t *ctx) { eXosip_event_t *event; int running = 1; while (running) { event = eXosip_event_wait(ctx, 0, 100); if (event == NULL) { eXosip_automatic_action(ctx); continue; } eXosip_automatic_action(ctx); switch (event->type) { case EXOSIP_REGISTRATION_SUCCESS: printf("Registration successful (rid=%d)\n", event->rid); break; case EXOSIP_CALL_INVITE: printf("Incoming call (cid=%d, did=%d, tid=%d)\n", event->cid, event->did, event->tid); break; case EXOSIP_CALL_ANSWERED: printf("Call answered (200 OK), sending ACK\n"); { osip_message_t *ack = NULL; eXosip_lock(ctx); eXosip_call_build_ack(ctx, event->did, &ack); eXosip_call_send_ack(ctx, event->did, ack); eXosip_unlock(ctx); } break; default: printf("Event type: %d\n", event->type); break; } eXosip_event_free(event); } } ``` -------------------------------- ### Configure TLS/SIPS Transport with eXosip2 Source: https://context7.com/aurelihein/exosip/llms.txt Sets up TLS (Transport Layer Security) for secure SIP signaling (SIPS) using eXosip2. This involves configuring the TLS context with root CA certificates, client certificates, and private keys, and enabling certificate verification. The function then configures the library to listen on the secure port. Dependencies include the eXosip2 library and OpenSSL. ```c #include int setup_tls(struct eXosip_t *ctx) { eXosip_tls_ctx_t tls_ctx; eXosip_tls_ctx_error err; memset(&tls_ctx, 0, sizeof(tls_ctx)); /* Configure TLS context */ strncpy(tls_ctx.root_ca_cert, "/etc/ssl/certs/ca-certificates.crt", sizeof(tls_ctx.root_ca_cert) - 1); strncpy(tls_ctx.client.cert, "/etc/ssl/client.crt", sizeof(tls_ctx.client.cert) - 1); strncpy(tls_ctx.client.priv_key, "/etc/ssl/client.key", sizeof(tls_ctx.client.priv_key) - 1); strncpy(tls_ctx.client.priv_key_pw, "keypassword", sizeof(tls_ctx.client.priv_key_pw) - 1); /* Set TLS context */ err = eXosip_set_tls_ctx(ctx, &tls_ctx); if (err != TLS_OK) { fprintf(stderr, "TLS setup failed: %d\n", err); return -1; } /* Enable certificate verification */ eXosip_tls_verify_certificate(ctx, 1); /* Listen on TLS (secure=1) */ if (eXosip_listen_addr(ctx, IPPROTO_TCP, NULL, 5061, AF_INET, 1) != 0) { fprintf(stderr, "Failed to listen on TLS\n"); return -1; } return 0; } ``` -------------------------------- ### Send DTMF Signal via eXosip2 Source: https://github.com/aurelihein/exosip/blob/master/help/doxygen/ht1-callcontrol.dox Demonstrates how to build and send a DTMF relay message within an existing call session. It uses eXosip_call_build_info to prepare the message and osip_message_set_body to attach the signal data. ```c osip_message_t *info; char dtmf_body[1000]; int i; eXosip_lock (ctx); i = eXosip_call_build_info (ctx, evt->did, &info); if (i == 0) { snprintf (dtmf_body, 999, "Signal=%c\r\nDuration=250\r\n", c); osip_message_set_content_type (info, "application/dtmf-relay"); osip_message_set_body (info, dtmf_body, strlen (dtmf_body)); i = eXosip_call_send_request (ctx, evt->did, info); } eXosip_unlock (ctx); ``` -------------------------------- ### Send SIP INFO Request with eXosip2 Source: https://github.com/aurelihein/exosip/blob/master/help/doxygen/ht1-callcontrol.dox Illustrates how to send an INFO request within a call, often used for out-of-band DTMF signaling. This demonstrates the flexibility of the call control API for various SIP request types. ```c // Code example for sending INFO request would go here, // but is not provided in the input text. ``` -------------------------------- ### Configure TLS Certificate Verification in eXosip Source: https://github.com/aurelihein/exosip/blob/master/help/doxygen/ht0-initialize.dox Configures TLS certificate verification settings for eXosip. The first snippet shows how to disable certificate verification by passing 0. The second snippet demonstrates how to set up TLS context with client certificates, private keys, passwords, and root CA certificates for platforms other than Windows and macOS. ```c int val=0; i = eXosip_tls_verify_certificate (val); ``` ```c eXosip_tls_ctx_t tls_info; memset(&tls_info, 0, sizeof(eXosip_tls_ctx_t)); snprintf(tls_info.client.cert, sizeof(tls_info.client.cert), "user-cert.crt"); snprintf(tls_info.client.priv_key, sizeof(tls_info.client.priv_key), "user-privkey.crt"); snprintf(tls_info.client.priv_key_pw, sizeof(tls_info.client.priv_key_pw), "password"); snprintf(tls_info.root_ca_cert, sizeof(tls_info.root_ca_cert), "cacert.crt"); i = eXosip_set_tls_ctx (&tls_info); ``` -------------------------------- ### Publish SIP Presence Status (C) Source: https://context7.com/aurelihein/exosip/llms.txt Enables publishing presence status to a presence server using SIP PUBLISH requests. This function constructs a PIDF (Presence Information Data Format) XML document containing the presence state and sends it as a PUBLISH request. Requires the eXosip2 library. ```c #include int publish_presence(struct eXosip_t *ctx, const char *aor, const char *status) { osip_message_t *publish = NULL; char pidf_body[1024]; /* Build PIDF presence document */ snprintf(pidf_body, sizeof(pidf_body), "\r\n" " " " " " %s " " " "\r\n", aor, status); /* status: "open" or "closed" */ if (eXosip_build_publish(ctx, &publish, aor, /* to */ aor, /* from */ NULL, /* route */ "presence", /* event */ "3600", /* expires */ "application/pidf+xml", /* content-type */ pidf_body /* body */ ) != 0) { return -1; } eXosip_lock(ctx); int result = eXosip_publish(ctx, publish, aor); eXosip_unlock(ctx); return result; } ``` -------------------------------- ### Add Authentication Credentials Source: https://github.com/aurelihein/exosip/blob/master/help/doxygen/ht2-registration.dox Configures authentication information for one or multiple SIP services. The realm parameter is used to distinguish between different service providers. ```c eXosip_lock (ctx); eXosip_add_authentication_info (ctx, login, login, passwd, NULL, NULL); eXosip_unlock (ctx); // Complete way for multiple services eXosip_lock (ctx); eXosip_add_authentication_info (ctx, login, login, passwd, NULL, "sip.antisip.com"); eXosip_add_authentication_info (ctx, from_username, login, passwd, NULL, "otherservice.com"); eXosip_unlock (ctx); ```