×

Discussion Board

Results 1 to 11 of 11
  1. #1
    Registered User
    Join Date
    Oct 2004
    Posts
    11

    SIP multipart/mixed content

    Hello,

    I am trying to write a SIP application that sends multipart content in a INVITE message, that is, in the same message I send "application/sdp" content + "application/resource-lists+xml" content

    It seems the SIP stack is very simple and the only way to add complex content is by creating the content yourself ; in my case I used the SDP plug in to make the sdp content and the xml lists were made "by hand" dealing directly with the text descriptors.

    My problem is that when a try to send all in the same SIP message I create the :
    CSIPContentTypeHeader* contentType=CSIPContentTypeHeader::NewL(multipart,mixed);

    and

    msgElements->SetContentL(multiContent,contentType);

    the problem is that I need to specify boundary delimiters (acording to RFC 2046 I think it was) in the following way:

    Content-type: multipart/mixed;boundary=boundary1

    I dind´t have problems creating a simple multipart/mixed header but when I try to add
    the " ;boundary=boundary1" part, the message doesn´t get sent into the network.

    I´ve tried many ways of creating the descriptor to make it work, like:

    _LIT8(mixed,"mixed;boundary=boundary1");
    or
    _LIT8(mixed,"mixed boundary=boundary1");

    or
    _LIT8(mixed,"mixed;\"boundary=boundary1\"");

    (in fact if I add any special character to the descriptor like ';' ':' '=' it doesnt work either) It seems like the SIP stack doesnt like this...but on the other hand it doesnt let me create this kind of content any other way and I really need that silly "bounday" delimiter!

    I hope any of you guys can help me out or any nokia member can tell me why it doesn´t work and how to solve this problem.

    Thank you.

  2. #2
    Super Contributor
    Join Date
    Apr 2003
    Location
    Czech Republic
    Posts
    915
    It is weird. It would be a big problem for SIP stack to not allow this kind of messages. Are you sure you have the INVITE well formated? It should look like this:
    Code:
    INVITE sip:address@domain SIP/2.0
    ...other headers...
    Content-Type: multipart/mixed;boundary=BC5EA84D
    Content-Length: xx
    
    --BC5EA84D
    Content-Type: application/SDP
    
    content of SDP
    
    --BC5EA84D
    Content-Type: application/resource-lists+xml
    
    content of second part
    
    --BC5EA84D--
    Does it returns any errors?
    You can also try it this way:
    Content-Type: multipart/mixed;boundary="BC5EA84D"

  3. #3
    Super Contributor
    Join Date
    Apr 2003
    Location
    Czech Republic
    Posts
    915
    I forgot to mention. Mind the gaps..:-) The empty lines on the right places are very important...

  4. #4
    Registered User
    Join Date
    Oct 2004
    Posts
    11
    thanks sopta007,

    Yes I can assure you I´ve tried all the possiblities listed in the RFC and of course the INVITE message is well formatted.

    In fact in the beginning I just sent application/sdp content and it worked all right.

    The problem is that I learned afterwars that my application required this multipart content
    so I began to try different things.

    The main problem here is that the API does´t seem to natively support multipart content: In theory that would be enclosing two different SIP contents and the SIP stack would take care of adding all the mulipart/mixed; boundary="fffefef" and boundary delimiters stuff by itself. But I can only add content once so I have to figure out the right way. In fact I have managed to send a full packet like this:
    This is an Ethereal capture:

    Session Initiation Protocol (SIP as raw text)

    INVITE sip:PoC_Server@localhost.localdomain;list=PoC-list SIP/2.0
    Route: <sip:192.168.1.2;lr>
    Via: SIP/2.0/UDP 192.168.1.11:5060;branch=z9hG4bKAy3kYhUOWM_o2
    From: sip:nari@lcc;tag=N6fkYqF4Dw
    To: sip:PoC_Server@localhost.localdomain
    Supported: timer,sec-agree
    Require: pref
    Contact: <sip:nari@192.168.1.11;comp=sigcomp>
    CSeq: 142 INVITE
    Call-ID: W73kYsaFt0E_mzf3WH2IuLjDK050Ol
    Accept-Contact: +g.poc.talkburst
    User-Agent: PoC-Client 1.0
    Subject: PoC Client
    Allow: INVITE,ACK,CANCEL,BYE,NOTIFY
    Max-Forwards: 70
    Content-Type: multipart/mixed
    Content-Length: 686

    --boundary1
    Content-Type: application/sdp

    v=0
    o=PoC-Client 2890844526 2890842808 IN IP4 192.168.1.11
    s=PoC-Client-Media-Lib
    c=IN IP4 192.168.1.11
    t=0 0
    a=direction:both
    m=application 3456 udp TBCP
    a=sendrecv
    a=fmtp:TBCP queuing=1; priority=2; timestamp=1
    m=audio 60000 RTP/AVP 0 96 97
    a=rtpmap:0 AMR/8000
    a=rtpmap:96 L8/8000
    a=rtpmap:97 L8/16000

    --boundary1
    Content-Type: application/resource-lists+xml
    Content-Disposition: recipient-list
    Content-ID:<PoC-list>

    <?xml version="1.0" encoding="UTF-8"?>
    <resource-lists xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
    <list>
    <entry uri="sip:almu@lcc" />
    <entry uri="sip:amador@lcc" />
    </list>
    </resource-lists>
    --boundary1--

    (Where or the SIP content formatting was done manually with HBuf8 descriptors as it is the only thing that I can use, and only once as I stated before)

    This message gets sent but as it reaches the SIP server it says that it doesn´t find the delimiter so it doesnt work.

    Ok, so you say: easy, add it yourself... (and so I did) and I tried everything I found in the RFC but it seems some special chracters like black spaces, paretheses, commas,colons ...everything to sum up..makes the stack not to send the message (the app doesn´t crash, it simply acts as if it had sent the message when in reality it dind´t)

    the weird thing is that is DOES send the message when I use a header like this
    multipart/mixed_dfdwf_FEwef (add any stupidy as long as you don´t use the charactes I mentioned) but for example
    multipart/mixed; doesn´t get sent (yes, I just added the ; )

    As you can see the error has nothing to do with the formatting of the SIP in itself as is the same as before adding this content.

    I know I must be missing something because as you say this would be a huge flaw not to have included the possibility to send multipart content in SIP. (come on Nokia you didn´ forget to add support for mutipart content in the SIP Stack, did you? )

    If any of you can help me please don´t hesitate! Thanks

  5. #5
    Registered User
    Join Date
    Oct 2004
    Posts
    11

    AT LAST!!!

    After dedicating a few more hours to the problem I found out why it didn´t work.

    Apparently the CSIPContentTypeHeader derives from a CSIPParameterHeaderBase
    (that I forgot to look at yesterday) so I was only using the methods provided in the first class.

    This CSIPParameterHeaderBase class has a contentType->SetExtensionParamL(_L8("boundary"),_L8("boundary1")) method that it would add to the original content Type Header solving thus all my problems.

    What I haven´t been able to figure out yet is a more elegant way of adding two different contents in the same message (as I had to do all the formatting myself including the boundary delimiters in between both contents ) but as it seems to be working now I´m not really that concerned.

    Hope this can help someone else in the future.

  6. #6
    Registered User
    Join Date
    Mar 2003
    Location
    Leh, Ladhak.
    Posts
    41

    Content multipart

    Did you try the above with the "MESSAGE" method. Does it work. I am not able to send with the MESSAGE method using the nokia stack. Can you shed some light on this?

  7. #7
    Registered User
    Join Date
    Oct 2004
    Posts
    11

    Need more information

    Well I don´t know about the "MESSAGE" method, but I managed to send succesfully a REFER method (which, by the way, is not a native part of the Nokia SiP stack) so if I could send that message, I´m sure you can send any message you want.

    I don´t know about the specific details of your problem; maybe if you showed us the message as you want to send it and the code you´re using to create it I could give you a hand...

  8. #8
    Registered User
    Join Date
    Mar 2003
    Location
    Leh, Ladhak.
    Posts
    41

    MESSAGE method

    Hello,
    Thanks for your quick reply, I will send you the code monday, as I am home for the weekend however the thing I am trying to do is based on the SIP Extensions - sending IM using MESSAGE method.

    The rough code is as follows:

    // Set up CSIPHosturi
    // set up from and to headers
    // set up CSipMessageElements
    and then send out the message with
    iConnection->SendRequestL( CSipMessageElements)

    The code I will send monday, I am sure some silly mistake but another pair of eyes are better.

    Cheers
    PR

  9. #9
    Registered User
    Join Date
    Mar 2003
    Location
    Leh, Ladhak.
    Posts
    41

    SIP MESSAGE

    Subsequently I found that
    CleanupStack::PushL(reqElems);
    reqElems->SetMethodL(_L8("MESSAGE"));
    CleanupStack::Pop(); //reqElems

    SetMethodL of CSIPRequestElements does not seem to support any extension methods. ???

    The code is somebody wants to review is:
    //This code does not work
    /*
    void CSIPEngine::SendSipMessage(TDes& msg)
    {
    // create "TO:" details
    CSIPURI* sipuri = CSIPURI:ecodeL(_L8("siplayer2@10.21.32.11"));
    CleanupStack::PushL(sipuri);
    CSIPAddress* sipaddress = CSIPAddress::NewL(sipuri);
    CleanupStack::Pop(); //sipuri
    CleanupStack::PushL(sipaddress);
    CSIPToHeader* to = CSIPToHeader::NewL(sipaddress);
    CleanupStack::Pop();

    // init the CSIPRequestElements
    CSIPRequestElements* reqElems = CSIPRequestElements::NewLC(to);
    CleanupStack::Pop(); //reqElems

    // create FROM HEADER
    //CSIPAddress* fromsipaddress = CSIPAddress:ecodeL(iProfile->AORs().MdcaPoint(0));
    //CleanupStack::PushL(fromsipaddress);
    CSIPURI* sipuri1 = CSIPURI:ecodeL(_L8("siplayer1@10.21.32.10"));
    CleanupStack::PushL(sipuri1);
    CSIPAddress* fromsipaddress = CSIPAddress::NewL(sipuri1);
    CleanupStack::Pop(); //sipuri
    CleanupStack::PushL(fromsipaddress);
    CSIPFromHeader* from = CSIPFromHeader::NewL(fromsipaddress);
    CleanupStack::Pop(); //fromsipaddress

    //create REMOTE URI
    CSIPHostPort* hostPort = CSIPHostPort::NewLC();
    hostPort->SetHostL(_L8("10.21.32.9"));
    hostPort->SetPort(5060);

    CSIPURI* proxysipuri = CSIPURI::NewL(hostPort);

    // proxysipuri->SetMethodParamL(_L8("MESSAGE"));
    // proxysipuri->SetOtherURIParamL (_L8("Port"), _L8("5060"));

    // CleanupStack::PushL(proxysipuri);

    // create a header
    // CSIPHostPort* hostPort = CSIPHostPort::NewLC();
    //CSIPURI* sipURI = CSIPURI::NewL(hostPort);
    // CSIPURI*sipURI= CSIPURI::NewL(_L8("sip:10.21.32.9"),hostPort);
    // CleanupStack::Pop(); // hostport, ownership given to sipURI
    // CleanupStack::PushL(sipURI);
    // CSIPAddress* sipAddress = CSIPAddress::NewL(sipURI);
    // CleanupStack::Pop(); // sipURI, ownership given to sipAddress
    // CleanupStack::PushL(sipAddress);
    // CSIPContactHeader* contactHeader = CSIPContactHeader::NewL(sipAddress);
    // CleanupStack::Pop(); // sipAddress, ownership given to contactHeader

    // TBuf<12> junkData;
    // junkData.Copy(msg)
    // CSIPAllowHeader* allowHeader = CSIPAllowHeader::NewL(msg);
    // CleanupStack::Pop(); // sipAddress, ownership given to contactHeader

    // create message elements
    // CSIPMessageElements* elements =CSIPMessageElements::NewLC();
    // RPointerArray<CSIPHeaderBase> headers;
    // CSIPHeaderBase::PushLC(&headers);
    //create and add user headers such as Allow etc…allowHeader
    // User::LeaveIfError(headers.Append(contactHeader));
    // elements->SetUserHeadersL(headers);
    // CleanupStack::Pop(); //headers
    // headers.Close();

    // set content
    // HBufC8 *data = HBufC8::NewL(12);
    // TPtr8 p1 = data->Des();
    // TPtrC16 ps = msg.Mid(0);
    // p1.Copy(ps);
    //elements->SetContent(data); // not a public method

    // CSIPContentTypeHeader *ctHeader = CSIPContentTypeHeader::NewL(_L8("application"), _L8("sdp"));
    // elements->SetContentL(data,ctHeader);


    //set request elements
    CleanupStack::PushL(to);
    reqElems->SetToHeaderL(to);
    CleanupStack::Pop(); //to

    CleanupStack::PushL(from);
    reqElems->SetFromHeaderL(from);
    CleanupStack::Pop(); //from

    /// CleanupStack::PushL(reqElems);
    reqElems->SetMethodL(_L8("MESSAGE"));
    // CleanupStack::Pop(); //reqElems

    CleanupStack::PushL(proxysipuri);
    reqElems->SetRemoteURIL(proxysipuri);
    CleanupStack::Pop(); //proxysipuri

    // send the message
    if ( iConnection->State() == CSIPConnection::EActive ) {

    CSIPClientTransaction* sipClientTransaction = iConnection->SendRequestL(reqElems);

    }

    }



    */

  10. #10
    Registered User
    Join Date
    Oct 2004
    Posts
    11
    Hi!
    Well on a quick first look at your code, I don´t like the way how you set the SIP uri (not that it doesn´t seem sensible but I had the same problems when trying the same thing):

    instead of:

    CSIPURI* sipuri = CSIPURIecodeL(_L8("siplayer2@10.21.32.11"));
    CleanupStack::PushL(sipuri);
    CSIPAddress* sipaddress = CSIPAddress::NewL(sipuri);
    CleanupStack::Pop(); //sipuri

    try:

    CSIPHostPort* host=CSIPHostPort::NewLC();
    host->SetHostL(_L8("10.21.32.11"));
    CSIPURI* sipURI=CSIPURI::NewL(_L8("sipplayer2"),host,EFalse);
    CleanupStack::PushL(sipURI);

    to set the sip uri of the desired host on the net. I know that looks almost the same but trust me I remember having trouble doing it the way you did it.

    If you have doubts about the calls I used just look at the .h files and they explain each function.

    So everytime you create a new sip uri create both host and domain parts as different things ( I think that the stack did´t like the @ or something like that)

    if that doesn´t work I suggest you add a little User::InfoPrint(_L("got to this point"));
    that shows a message for a second on the emulator screen that will let you know what call is causing your problems.You just have to add it after the function you think is failing and if the message doesn´t appear on the screen you wil know exactly where the code leaves.I know that it looks a little silly but it really helped me find out what functions where leaving so you I could have a clue .

    And as far as the reqElems->SetMethodL(_L8("MESSAGE"));
    line don´t worry I did the same thing with tthe REFER and it worked alright.

    Hope that helps I don´t have time to look through the rest of the code in depth but if you still have problems ask again. (and use the User::InfoPrint trick its really helpful... I hate the debugger ;-p

    bye.

  11. #11
    Registered User
    Join Date
    Mar 2003
    Location
    Leh, Ladhak.
    Posts
    41

    Got it working

    Thanks. That helped.

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •