Search code examples
sip

osip_message_to_str fails on a message I created using the message/parser functions


I'm trying to receive an invite message and then reply with 100 trying and/or 180 ringing to the same client. I'd like to use only the parser from libosip2.

So when I try to osip_message_to_str so I have a buffer to send back, it always fails with -2.

I tried cloning all the fields I thought it would make sense. But still having the same issue.

If I try to osip_message_to_str on the message I received, it works well.

parser_init();
osip_message_t *request = received_buffer(buffer); // the message is received properly from the buffer
osip_message_t *response;
int i = osip_message_init(&response);
if (i != 0) {
    fprintf(stderr, "cannot allocate\n");
    return -1;
}

osip_message_set_version(response, strdup("SIP/2.0"));
osip_message_set_status_code(response, 100);
osip_from_clone(request->from, &response->from);
osip_to_clone(request->to, &response->to); /* include the tag! */

osip_call_id_clone(request->call_id, &response->call_id);

osip_contact_t *contact = nullptr;
osip_message_get_contact(response, 0, &contact);
osip_uri_clone(osip_contact_get_url(contact), &response->req_uri);
osip_cseq_clone(request->cseq, &(response->cseq));

char *dest = NULL;
size_t length = 0;
i = osip_message_to_str(response, &dest, &length);
if (i != 0) {
    fprintf(stderr, "resp cannot get printable message %d\n", i);
    return -1;
}
fprintf(stdout, "message:\n%s\n", dest);

I expect to be able to print a response message.


Solution

  • From libosip2, file osip_port.h, the error return code -2 means bad parameter:

    #define OSIP_BADPARAMETER         -2
    

    The first line of an answer is something like this: "SIP/2.0 100 Trying".

    In your code, you are setting correctly both "SIP/2.0" and "100". However, you forgot the reason phrase. For "100", obviously, the string should be "Trying". Thus, a complete first line of a response should be done with:

    osip_message_set_version(response, osip_strdup("SIP/2.0"));
    osip_message_set_status_code(response, 100);
    //ADD THIS
    osip_message_set_reason_phrase (answer, osip_strdup("Trying");
    

    The above will fix the first error, but there looks to be more. You are using "osip_message_get_contact" to retrieve a contact from the response. But there is none. In order to set a contact, you need to search for your IP address, port number, and parameters you want to add. Something like this is advised:

    osip_message_set_contact (response, "<sip:192.168.1.10:5678;ob>");
    

    The above API will parse the string as a Contact header and add it to the response.

    To make it clear (as you have used it), "response->req_uri" is empty for a response. It means "Request-URI" which is only for request.

    If you wish a complete response, you will also need to copy all the "Via" headers:

    {
      osip_list_iterator_t it;
      osip_via_t *via = (osip_via_t *) osip_list_get_first (&request->vias, &it);
    
      while (via != NULL) {
        osip_via_t *via2;
    
        i = osip_via_clone (via, &via2);
        if (i != 0) {
          osip_message_free (response);
          return i;
        }
        osip_list_add (&response->vias, via2, -1);
        via = (osip_via_t *) osip_list_get_next (&it);
      }
    }
    

    NOTE: use osip_strdup instead of strdup for any osip allocation to make your code more portable.

    osip_message_to_str should work then!

    For more precise code, feel free to have a look at my exosip2 code here. It will certainly help you for the next question you will have!