使用 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
我是这方面的新手。我一直在尝试制作一个演示 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