Search code examples
c++objective-csipvoiprtp

RTP packer creation using objective c


I am new in this area. I have been trying to make a demo RTP packet but every time trying to send the packet it is showing UDP packet instead of RTP packet on the wireshark. Please I need to know what I am doing wrong.

struct rtp_header {
    u_int16_t v:2; /* protocol version */
    u_int16_t p:1; /* padding flag */
    u_int16_t x:1; /* header extension flag */
    u_int16_t cc:4; /* CSRC count */
    u_int16_t m:1; /* marker bit */
    u_int16_t pt:7; /* payload type */
    u_int16_t seq:16; /* sequence number */
    u_int32_t ts; /* timestamp */
    u_int32_t ssrc; /* synchronization source */
};

My demo method for RTP

-(NSMutableData*)getNewRTPMasg
{
    
    CMTime timestamp = CMTimeMakeWithSeconds(2.0, 60000);
    //int32_t t = 12.90;
    int32_t t = ((float)timestamp.value / timestamp.timescale) * 1000;
    if(start_t == 0) start_t = t;
    
    struct rtp_header header;
    
    //fill the header array of byte with RTP header fields
    header.v = 2;
    header.p = 0;
    header.x = 0;
    header.cc = 0;
    header.m = 0;
    header.pt = 97;
    header.seq = seqNum;
    header.ts = t - start_t;
    header.ssrc = (u_int32_t)5062;
    
    
    NSString *sipMsg = @"tesdjkhfsjkdfmpsssss";
    NSData *data = [sipMsg dataUsingEncoding:NSUTF8StringEncoding];
    //NSLog(@"size %@",header);
    
    /* send RTP stream packet */
    NSMutableData *packet = [NSMutableData dataWithBytes:&header length:12];
    [packet appendData:data];
    
    return packet;
}

Sending the packet using GCDAsyncUdpSocket

NSMutableData *fullData = [self getNewRTPMasg];
[self->sipMessageSocket sendData:fullData toHost:@"192.168.0.105" port:5062 withTimeout:60 tag:200];


Solution

  • If you send packets this way, you will only see UDP packets in Wireshark because Wireshark examines whether the packet is only SIP or RTP based on the SIP protocol. That means first you have to send an invite request with a valid SDP body, once Wireshark finds a Sip packet with valid SDP then it stores the incoming RTP IP & port. Afterwards, Wireshark recognizes all the packet coming from that predefined IP & port with valid RTP header as RTP packets.

    First send an invite request with SDP

    -(NSArray*) createSDP
    {
        NSString *v;
        NSString *o;
        NSString *s;
        NSString *c;
        NSString *t;
        NSString *m;
        NSString *a1;
        NSString *a2;
        NSString *a3;
        NSString *a4;
        
        v=@"v=0\r\n";
        o=[NSString stringWithFormat:@"o=- 0 0 IN IP4 %@\r\n",localIP];
        s=[NSString stringWithFormat:@"s=%@\r\n",user];
        c=[NSString stringWithFormat:@"c=IN IP4 %@\r\n",localIP];
        t=@"t=0 0\r\n";
        m=[NSString stringWithFormat:@"m=audio %@ RTP/AVP 18\r\n",localRTPPort];
        a1=@"a=rtpmap:18 G729/8000\r\n";
        a2=[NSString stringWithFormat:@"a=ptime:%@\r\n",pTime];
        a3=@"a=fmtp:18 annexb=no\r\n";
        
        NSString *body= [NSString stringWithFormat:@"%@%@%@%@%@%@%@%@%@",v,o,s,c,t,m,a1,a2,a3];
        NSString *bodyLength = [NSString stringWithFormat:@"%lu",(unsigned long)[body dataUsingEncoding:NSUTF8StringEncoding].length];
        NSArray *inviteBody = @[body,bodyLength];
        
       
        return sdp;
    }
    
    -(NSString*) createInviteMessage
    {
        NSArray *sdpBody = [self createSDP];
        NSString *fullBody = body[0];
        NSString *bodyLength = body[1];
        
        invite = [NSString stringWithFormat:@"INVITE sip:%@@%@:%@ SIP/2.0\r\n",phonoNumber,serverIP,serverPort];
        via = [NSString stringWithFormat:@"Via: SIP/2.0/%@ %@:%@;branch=%@;rport\r\n",protocol,localIP,localPort,branch];
        max_forward = @"Max-Forwards: 70\r\n";
        contact = [NSString stringWithFormat:@"Contact: <sip:%@@%@:%@;transport=%@>\r\n",user,localIP,localPort,protocol];
        to = [NSString stringWithFormat:@"To: <sip:%@@%@>\r\n",phonoNumber,serverIP];
        from = [NSString stringWithFormat:@"From: <sip:%@@%@;transport=%@>;tag=%@\r\n",user,serverIP,protocol,tag];
        call_id = [NSString stringWithFormat:@"Call-id: %@\r\n",callRandom];
        csec = [NSString stringWithFormat:@"CSeq: 1 %@\r\n",method];
        allow = @"Allow: INVITE, ACK, CANCEL, OPTIONS, BYE, REFER, NOTIFY, MESSAGE, REGISTER, SUBSCRIBE, INFO\r\n";
        content_type = @"Content-Type: application/sdp\r\n";
        user_Agent = [NSString stringWithFormat:@"User-Agent: %@ 1.0\r\n",agent];
        content_length = [NSString stringWithFormat:@"Content-Length: %@\r\n\r\n",bodyLength];
        
        NSString *inviteMessage = [NSString stringWithFormat:@"%@%@%@%@%@%@%@%@%@%@%@%@%@",
                                   invite,via,max_forward,contact,to,from,call_id,csec,allow,content_type,
                                   user_Agent,content_length,fullBody];
        
        return inviteMessage;
    }
    

    Now send this to Sip Server IP port

    NSMutableData *inviteData = [self createInviteMessage];
    [self->sipMessageSocket inviteData toHost:@"169.239.160.17" port:5060 withTimeout:60 tag:200];
    

    once you get 200Ok message from Sip Server, perse media IP & Port from the SDP body. This is my 200Ok message

    In my case media IP is 169.239.160.17 & port 47418.

    finally, you will see all packets are converted to RTP packets. final Wireshark view