使用 objective c 创建 RTP 打包程序

RTP packer creation using objective c

我是这方面的新手。我一直在尝试制作一个演示 RTP 数据包,但每次尝试发送数据包时,它都会在 wireshark 上显示 UDP 数据包而不是 RTP 数据包。我需要知道我做错了什么。

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 */
};

我的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;
}

正在使用 GCDAsyncUdpSocket 发送数据包

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

在 Wireshark 中右键单击 udp 数据包和 select - 解码为 -> RTP 协议。

所有数据包都将被解码为 RTP 数据包。

在首选项中,您可以将负载编号 -97 - 映射到您计划共享的编解码器数据。

如果您以这种方式发送数据包,您将只能在 Wireshark 中看到 UDP 数据包,因为 Wireshark 会根据 SIP 协议检查数据包是仅 SIP 还是 RTP。 这意味着首先您必须使用有效的 SDP body 发送邀请请求,一旦 Wireshark 找到具有有效 SDP 的 SIP 数据包,它就会存储传入的 RTP IP 和端口。之后,Wireshark 将所有来自该预定义 IP 和端口且具有有效 RTP header 的数据包识别为 RTP 数据包。

首先使用 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;
}

现在将此发送到 Sip 服务器 IP 端口

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

一旦您从 Sip 服务器收到 200Ok 消息,请从 SDP body 中获取媒体 IP 和端口。 This is my 200Ok message

在我的例子中,媒体 IP 是 169.239.160.17 和端口 47418。

最后,您会看到所有数据包都转换为 RTP 数据包。 final Wireshark view