使用目标 c 创建 RTP 打包程序

RTP packer creation using objective c

本文关键字:包程序 程序 RTP 目标 创建      更新时间:2023-10-16

我是这方面的新手。我一直在尝试制作一个演示 RTP 数据包,但每次尝试发送数据包时,它都会显示 UDP 数据包,而不是 wireshark 上的 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 数据包,因为 Wireshark 会根据 SIP 协议检查数据包是仅是 SIP 还是 RTP。 这意味着首先你必须发送一个具有有效SDP正文的邀请请求,一旦Wireshark找到具有有效SDP的Sip数据包,它就会存储传入的RTP IP和端口。之后,Wireshark将来自具有有效RTP标头的预定义IP和端口的所有数据包识别为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=0rn";
o=[NSString stringWithFormat:@"o=- 0 0 IN IP4 %@rn",localIP];
s=[NSString stringWithFormat:@"s=%@rn",user];
c=[NSString stringWithFormat:@"c=IN IP4 %@rn",localIP];
t=@"t=0 0rn";
m=[NSString stringWithFormat:@"m=audio %@ RTP/AVP 18rn",localRTPPort];
a1=@"a=rtpmap:18 G729/8000rn";
a2=[NSString stringWithFormat:@"a=ptime:%@rn",pTime];
a3=@"a=fmtp:18 annexb=norn";

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.0rn",phonoNumber,serverIP,serverPort];
via = [NSString stringWithFormat:@"Via: SIP/2.0/%@ %@:%@;branch=%@;rportrn",protocol,localIP,localPort,branch];
max_forward = @"Max-Forwards: 70rn";
contact = [NSString stringWithFormat:@"Contact: <sip:%@@%@:%@;transport=%@>rn",user,localIP,localPort,protocol];
to = [NSString stringWithFormat:@"To: <sip:%@@%@>rn",phonoNumber,serverIP];
from = [NSString stringWithFormat:@"From: <sip:%@@%@;transport=%@>;tag=%@rn",user,serverIP,protocol,tag];
call_id = [NSString stringWithFormat:@"Call-id: %@rn",callRandom];
csec = [NSString stringWithFormat:@"CSeq: 1 %@rn",method];
allow = @"Allow: INVITE, ACK, CANCEL, OPTIONS, BYE, REFER, NOTIFY, MESSAGE, REGISTER, SUBSCRIBE, INFOrn";
content_type = @"Content-Type: application/sdprn";
user_Agent = [NSString stringWithFormat:@"User-Agent: %@ 1.0rn",agent];
content_length = [NSString stringWithFormat:@"Content-Length: %@rnrn",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;
}

现在将其发送到 Ip 服务器 IP 端口

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

一旦您从Sip Server获得200Ok消息,就会从SDP正文中获取媒体IP和端口。 这是我的 200Ok 消息

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

最后,您将看到所有数据包都转换为RTP数据包。 最终的线鲨视图

在 Wireshark 中,右键单击 udp 数据包并选择 - 解码为 -> RTP 协议。

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

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