1564 lines
32 KiB
C
1564 lines
32 KiB
C
#include "./include/public.h"
|
|
#include "./include/pub_sdp.h"
|
|
|
|
/*@ignore@*/
|
|
void pub_replace_all_lws(char *msg)
|
|
{
|
|
char *tmp;
|
|
|
|
if (msg == NULL)
|
|
return;
|
|
tmp = msg;
|
|
|
|
for (; tmp[0] != '\0'; tmp++)
|
|
{
|
|
if (('\0' == tmp[0]) || ('\0' == tmp[1]) ||
|
|
('\0' == tmp[2]) || ('\0' == tmp[3]))
|
|
return;
|
|
|
|
if ((('\r' == tmp[0]) && ('\n' == tmp[1]) &&
|
|
('\r' == tmp[2]) && ('\n' == tmp[3])) ||
|
|
(('\r' == tmp[0]) && ('\r' == tmp[1])) ||
|
|
(('\n' == tmp[0]) && ('\n' == tmp[1])))
|
|
return;
|
|
|
|
if ((('\r' == tmp[0]) && ('\n' == tmp[1]) &&
|
|
((' ' == tmp[2]) || ('\t' == tmp[2]))) ||
|
|
(('\r' == tmp[0]) &&
|
|
((' ' == tmp[1]) || ('\t' == tmp[1]))) ||
|
|
(('\n' == tmp[0]) &&
|
|
((' ' == tmp[1]) || ('\t' == tmp[1]))))
|
|
{
|
|
// Replace line end and TAB symbols by SP
|
|
tmp[0] = ' ';
|
|
tmp[1] = ' ';
|
|
tmp = tmp + 2;
|
|
// Replace all following TAB symbols
|
|
for (; ('\t' == tmp[0] || ' ' == tmp[0]); )
|
|
{
|
|
tmp[0] = ' ';
|
|
tmp++;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
char *pub_strncpy(char *dest, const char *src, WORD length)
|
|
{
|
|
strncpy(dest, src, length);
|
|
dest[length] = '\0';
|
|
return dest;
|
|
}
|
|
|
|
int pub_set_next_token(char *dest, char *buf, int endSeparator, char **next)
|
|
{
|
|
char *sep; // separator
|
|
|
|
*next = NULL;
|
|
|
|
sep = buf;
|
|
while ((*sep != endSeparator) && (*sep != '\0') && (*sep != '\r')
|
|
&& (*sep != '\n'))
|
|
sep++;
|
|
if ((*sep == '\r') || (*sep == '\n'))
|
|
{ // we should continue normally only if this is the separator asked!
|
|
if (*sep != endSeparator)
|
|
return -1;
|
|
}
|
|
if (*sep == '\0')
|
|
return -1; // value must not end with this separator!
|
|
if (sep == buf)
|
|
return -1; // empty value (or several space!)
|
|
|
|
pub_strncpy(dest, buf, sep - buf);
|
|
|
|
*next = sep + 1; // return the position right after the separator
|
|
|
|
return 0;
|
|
}
|
|
|
|
int pub_sdp_msg_init(PUB_SDP_MSG *sdp)
|
|
{
|
|
if (sdp == NULL)
|
|
return -1;
|
|
|
|
memset((BYTE *)sdp, 0, sizeof(PUB_SDP_MSG));
|
|
|
|
return 0;
|
|
}
|
|
|
|
int pub_sdp_net_type_conv(char *str, BYTE *netType, BYTE flag)
|
|
{
|
|
if (flag == PUB_SDP_STR_TO_API)
|
|
{
|
|
if (strncmp(str, "IN", 2) == 0)
|
|
*netType = PUB_SDP_NET_TYPE_IN;
|
|
return 0;
|
|
}
|
|
else
|
|
{
|
|
switch (*netType)
|
|
{
|
|
case PUB_SDP_NET_TYPE_IN:
|
|
strcpy(str, "IN");
|
|
break;
|
|
default:
|
|
return -1;
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
return -1;
|
|
}
|
|
|
|
int pub_sdp_addr_type_conv(char *str, BYTE *addrType, BYTE flag)
|
|
{
|
|
if (flag == PUB_SDP_STR_TO_API)
|
|
{
|
|
if (strncmp(str, "IP4", 3) == 0)
|
|
*addrType = PUB_SDP_ADDR_TYPE_IPV4;
|
|
return 0;
|
|
}
|
|
else
|
|
{
|
|
switch (*addrType)
|
|
{
|
|
case PUB_SDP_ADDR_TYPE_IPV4:
|
|
strcpy(str, "IP4");
|
|
break;
|
|
default:
|
|
return -1;
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
return -1;
|
|
}
|
|
|
|
int pub_sdp_attr_type_conv(char *str, BYTE *attrType, BYTE flag)
|
|
{
|
|
int ret = 0;
|
|
|
|
if (flag == PUB_SDP_STR_TO_API)
|
|
{
|
|
if (strncmp(str, "rtpmap", 6) == 0)
|
|
*attrType = PUB_SDP_ATTR_TYPE_RTPMAP;
|
|
else if (strncmp(str, "ptime", 5) == 0)
|
|
*attrType = PUB_SDP_ATTR_TYPE_PTIME;
|
|
else if (strncmp(str, "fmtp", 4) == 0)
|
|
*attrType = PUB_SDP_ATTR_TYPE_FMTP;
|
|
else
|
|
{
|
|
ret = -2;
|
|
}
|
|
return ret;
|
|
}
|
|
else
|
|
{
|
|
switch (*attrType)
|
|
{
|
|
case PUB_SDP_ATTR_TYPE_RTPMAP:
|
|
strcpy(str, "rtpmap");
|
|
break;
|
|
case PUB_SDP_ATTR_TYPE_PTIME:
|
|
strcpy(str, "ptime");
|
|
break;
|
|
case PUB_SDP_ATTR_TYPE_FMTP:
|
|
strcpy(str, "fmtp");
|
|
break;
|
|
default:
|
|
return -2;
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
return -1;
|
|
}
|
|
|
|
int pub_sdp_media_type_conv(char *str, BYTE *mediaType, BYTE flag)
|
|
{
|
|
if (flag == PUB_SDP_STR_TO_API)
|
|
{
|
|
if (strncmp(str, "audio", 6) == 0)
|
|
{
|
|
*mediaType = PUB_SDP_MEDIA_TYPE_AUDIO;
|
|
return 0;
|
|
}
|
|
else
|
|
return -2;
|
|
}
|
|
else
|
|
{
|
|
switch (*mediaType)
|
|
{
|
|
case PUB_SDP_MEDIA_TYPE_AUDIO:
|
|
strcpy(str, "audio");
|
|
break;
|
|
default:
|
|
return -1;
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
return -1;
|
|
}
|
|
|
|
int pub_sdp_proto_type_conv(char *str, BYTE *protoType, BYTE flag)
|
|
{
|
|
if (flag == PUB_SDP_STR_TO_API)
|
|
{
|
|
if (strncmp(str, "RTP/AVP", 7) == 0)
|
|
*protoType = PUB_SDP_PROTO_TYPE_RTP_AVP;
|
|
return 0;
|
|
}
|
|
else
|
|
{
|
|
switch (*protoType)
|
|
{
|
|
case PUB_SDP_PROTO_TYPE_RTP_AVP:
|
|
strcpy(str, "RTP/AVP");
|
|
break;
|
|
default:
|
|
return -1;
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
return -1;
|
|
}
|
|
|
|
int pub_sdp_parse_v(PUB_SDP_MSG *sdp, char *buf, char **next, DWORD flag)
|
|
{
|
|
char *equal;
|
|
char *crlf;
|
|
char value[8];
|
|
|
|
*next = buf;
|
|
equal = buf;
|
|
|
|
while ((*equal != '=') && (*equal != '\0'))
|
|
equal++;
|
|
if (*equal == '\0')
|
|
return -1;
|
|
|
|
if (equal == buf)
|
|
return -1;
|
|
|
|
// check if header is "v"
|
|
if (equal[-1] != 'v')
|
|
return -2;
|
|
|
|
crlf = equal + 1;
|
|
|
|
while ((*crlf != '\r') && (*crlf != '\n') && (*crlf != '\0'))
|
|
crlf++;
|
|
if (*crlf == '\0')
|
|
return -1;
|
|
if (crlf == equal + 1)
|
|
return -1; // v=\r ?? bad header
|
|
|
|
if ((flag & PUB_SDP_FLAG_V) == PUB_SDP_FLAG_V)
|
|
{
|
|
pub_strncpy(value, equal + 1, crlf - (equal + 1));
|
|
sdp->v.value = atoi(value);
|
|
}
|
|
|
|
if (crlf[1] == '\n')
|
|
*next = crlf + 2;
|
|
else
|
|
*next = crlf + 1;
|
|
|
|
// printf("v: %d\n", sdp->v.value);
|
|
|
|
sdp->flag |= PUB_SDP_FLAG_V;
|
|
|
|
return 0;
|
|
}
|
|
|
|
int pub_sdp_parse_o(PUB_SDP_MSG *sdp, char *buf, char **next, DWORD flag)
|
|
{
|
|
char *equal;
|
|
char *crlf;
|
|
char *tmp;
|
|
char *tmpNext;
|
|
char value[16];
|
|
int i;
|
|
|
|
*next = buf;
|
|
equal = buf;
|
|
|
|
while ((*equal != '=') && (*equal != '\0'))
|
|
equal++;
|
|
if (*equal == '\0')
|
|
return -1;
|
|
|
|
// check if header is "o"
|
|
if (equal[-1] != 'o')
|
|
return -2;
|
|
|
|
crlf = equal + 1;
|
|
|
|
while ((*crlf != '\r') && (*crlf != '\n') && (*crlf != '\0'))
|
|
crlf++;
|
|
if (*crlf == '\0')
|
|
return -1;
|
|
if (crlf == equal + 1)
|
|
return -1; /* o=\r ?? bad header */
|
|
|
|
if ((flag & PUB_SDP_FLAG_V) == PUB_SDP_FLAG_V)
|
|
{
|
|
tmp = equal + 1;
|
|
// o=username sess-id sess-version nettype addrtype addr
|
|
// useranme can contain any char (ascii) except "space" and CRLF
|
|
if (pub_set_next_token(sdp->o.userName, tmp, ' ', &tmpNext) < 0)
|
|
return -1;
|
|
tmp = tmpNext;
|
|
|
|
// sess_id contains only numeric characters
|
|
if (pub_set_next_token(sdp->o.sessId, tmp, ' ', &tmpNext) < 0)
|
|
return -1;
|
|
tmp = tmpNext;
|
|
|
|
// sess_version contains only numeric characters
|
|
if (pub_set_next_token (sdp->o.sessVer, tmp, ' ', &tmpNext) < 0)
|
|
return -1;
|
|
tmp = tmpNext;
|
|
|
|
// nettype is "IN" but will surely be extented!!! assume it's some alpha-char
|
|
if (pub_set_next_token (value, tmp, ' ', &tmpNext) < 0)
|
|
return -1;
|
|
if (pub_sdp_net_type_conv(value, &sdp->o.netType, PUB_SDP_STR_TO_API) < 0)
|
|
return -1;
|
|
tmp = tmpNext;
|
|
|
|
// addrtype is "IP4" or "IP6" but will surely be extented!!!
|
|
if (pub_set_next_token (value, tmp, ' ', &tmpNext) < 0)
|
|
return -1;
|
|
if (pub_sdp_addr_type_conv(value, &sdp->o.addrType, PUB_SDP_STR_TO_API) < 0)
|
|
return -1;
|
|
tmp = tmpNext;
|
|
|
|
// addr is "IP4" or "IP6" but will surely be extented!!!
|
|
i = pub_set_next_token(sdp->o.addr, tmp, '\r', &tmpNext);
|
|
if (i != 0)
|
|
{ /* could it be "\n" only??? rfc says to accept CR or LF instead of CRLF */
|
|
if (pub_set_next_token(sdp->o.addr, tmp, '\n', &tmpNext) < 0)
|
|
return -1;
|
|
}
|
|
}
|
|
|
|
if (crlf[1] == '\n')
|
|
*next = crlf + 2;
|
|
else
|
|
*next = crlf + 1;
|
|
|
|
// printf("o: %s, %s, %s, %d, %d, %s\n", sdp->o.userName, sdp->o.sessId, sdp->o.sessVer, sdp->o.netType, sdp->o.addrType, sdp->o.addr);
|
|
|
|
sdp->flag |= PUB_SDP_FLAG_O;
|
|
|
|
return 0;
|
|
}
|
|
|
|
int pub_sdp_parse_s(PUB_SDP_MSG *sdp, char *buf, char **next, DWORD flag)
|
|
{
|
|
char *equal;
|
|
char *crlf;
|
|
|
|
*next = buf;
|
|
equal = buf;
|
|
|
|
while ((*equal != '=') && (*equal != '\0'))
|
|
equal++;
|
|
if (*equal == '\0')
|
|
return -1;
|
|
|
|
// check if header is "s"
|
|
if (equal[-1] != 's')
|
|
return -2;
|
|
|
|
crlf = equal + 1;
|
|
|
|
while ((*crlf != '\r') && (*crlf != '\n') && (*crlf != '\0'))
|
|
crlf++;
|
|
if (*crlf == '\0')
|
|
return -1;
|
|
if (crlf == equal + 1)
|
|
return -1; // o=\r ?? bad header
|
|
|
|
if ((flag & PUB_SDP_FLAG_S) == PUB_SDP_FLAG_S)
|
|
pub_strncpy(sdp->s.sessName, equal + 1, crlf - (equal + 1));
|
|
|
|
if (crlf[1] == '\n')
|
|
*next = crlf + 2;
|
|
else
|
|
*next = crlf + 1;
|
|
|
|
// printf("s: %s\n", sdp->s.sessName);
|
|
|
|
sdp->flag |= PUB_SDP_FLAG_S;
|
|
|
|
return 0;
|
|
}
|
|
|
|
int pub_sdp_parse_i(PUB_SDP_MSG *sdp, char *buf, char **next, DWORD flag)
|
|
{
|
|
char *equal;
|
|
char *crlf;
|
|
|
|
*next = buf;
|
|
equal = buf;
|
|
|
|
while ((*equal != '=') && (*equal != '\0'))
|
|
equal++;
|
|
if (*equal == '\0')
|
|
return -1;
|
|
|
|
// check if header is "i"
|
|
if (equal[-1] != 'i')
|
|
return -2;
|
|
|
|
crlf = equal + 1;
|
|
|
|
while ((*crlf != '\r') && (*crlf != '\n') && (*crlf != '\0'))
|
|
crlf++;
|
|
if (*crlf == '\0')
|
|
return -1;
|
|
if (crlf == equal + 1)
|
|
return -1; // o=\r ?? bad header
|
|
|
|
if ((flag & PUB_SDP_FLAG_I) == PUB_SDP_FLAG_I)
|
|
pub_strncpy(sdp->i.info, equal + 1, crlf - (equal + 1));
|
|
|
|
if (crlf[1] == '\n')
|
|
*next = crlf + 2;
|
|
else
|
|
*next = crlf + 1;
|
|
|
|
// printf("i: %s\n", sdp->i.info);
|
|
|
|
if (sdp->medias.num == 0)
|
|
sdp->flag |= PUB_SDP_FLAG_I;
|
|
else
|
|
sdp->medias.medias[sdp->medias.num - 1].flag |= PUB_SDP_FLAG_I;
|
|
|
|
return 0;
|
|
}
|
|
|
|
int pub_sdp_parse_u(PUB_SDP_MSG *sdp, char *buf, char **next, DWORD flag)
|
|
{
|
|
char *equal;
|
|
char *crlf;
|
|
|
|
*next = buf;
|
|
equal = buf;
|
|
|
|
while ((*equal != '=') && (*equal != '\0'))
|
|
equal++;
|
|
if (*equal == '\0')
|
|
return -1;
|
|
|
|
// check if header is "u"
|
|
if (equal[-1] != 'u')
|
|
return -2;
|
|
|
|
crlf = equal + 1;
|
|
|
|
while ((*crlf != '\r') && (*crlf != '\n') && (*crlf != '\0'))
|
|
crlf++;
|
|
if (*crlf == '\0')
|
|
return -1;
|
|
if (crlf == equal + 1)
|
|
return -1; // v=\r ?? bad header
|
|
|
|
if (crlf[1] == '\n')
|
|
*next = crlf + 2;
|
|
else
|
|
*next = crlf + 1;
|
|
|
|
return 0;
|
|
}
|
|
|
|
int pub_sdp_parse_e(PUB_SDP_MSG *sdp, char *buf, char **next, DWORD flag)
|
|
{
|
|
char *equal;
|
|
char *crlf;
|
|
|
|
*next = buf;
|
|
equal = buf;
|
|
|
|
while ((*equal != '=') && (*equal != '\0'))
|
|
equal++;
|
|
if (*equal == '\0')
|
|
return -1;
|
|
|
|
// check if header is "e"
|
|
if (equal[-1] != 'e')
|
|
return -2;
|
|
|
|
crlf = equal + 1;
|
|
|
|
while ((*crlf != '\r') && (*crlf != '\n') && (*crlf != '\0'))
|
|
crlf++;
|
|
if (*crlf == '\0')
|
|
return -1;
|
|
if (crlf == equal + 1)
|
|
return -1; // v=\r ?? bad header
|
|
|
|
if (crlf[1] == '\n')
|
|
*next = crlf + 2;
|
|
else
|
|
*next = crlf + 1;
|
|
|
|
return 0;
|
|
}
|
|
|
|
int pub_sdp_parse_p(PUB_SDP_MSG *sdp, char *buf, char **next, DWORD flag)
|
|
{
|
|
char *equal;
|
|
char *crlf;
|
|
|
|
*next = buf;
|
|
equal = buf;
|
|
|
|
while ((*equal != '=') && (*equal != '\0'))
|
|
equal++;
|
|
if (*equal == '\0')
|
|
return -1;
|
|
|
|
// check if header is "p"
|
|
if (equal[-1] != 'p')
|
|
return -2;
|
|
|
|
crlf = equal + 1;
|
|
|
|
while ((*crlf != '\r') && (*crlf != '\n') && (*crlf != '\0'))
|
|
crlf++;
|
|
if (*crlf == '\0')
|
|
return -1;
|
|
if (crlf == equal + 1)
|
|
return -1; // v=\r ?? bad header
|
|
|
|
if (crlf[1] == '\n')
|
|
*next = crlf + 2;
|
|
else
|
|
*next = crlf + 1;
|
|
|
|
return 0;
|
|
}
|
|
|
|
int pub_sdp_parse_c(PUB_SDP_MSG *sdp, char *buf, char **next, DWORD flag)
|
|
{
|
|
char *equal;
|
|
char *crlf;
|
|
char *tmp;
|
|
char *tmpNext;
|
|
char value[16];
|
|
char *slash;
|
|
PUB_SDP_C *cHeader;
|
|
int i;
|
|
|
|
*next = buf;
|
|
equal = buf;
|
|
|
|
while ((*equal != '=') && (*equal != '\0'))
|
|
equal++;
|
|
if (*equal == '\0')
|
|
return -1;
|
|
|
|
// check if header is "c"
|
|
if (equal[-1] != 'c')
|
|
return -2;
|
|
|
|
crlf = equal + 1;
|
|
|
|
while ((*crlf != '\r') && (*crlf != '\n') && (*crlf != '\0'))
|
|
crlf++;
|
|
if (*crlf == '\0')
|
|
return -1;
|
|
if (crlf == equal + 1)
|
|
return -1; // c=\r ?? bad header
|
|
|
|
if ((flag & PUB_SDP_FLAG_C) == PUB_SDP_FLAG_C)
|
|
{
|
|
tmp = equal + 1;
|
|
|
|
// c=nettype addrtype (multicastaddr | addr)
|
|
|
|
// nettype is "IN" and will be extended
|
|
if (pub_set_next_token (value, tmp, ' ', &tmpNext) < 0)
|
|
return -1;
|
|
if (pub_sdp_net_type_conv(value, &sdp->c.netType, PUB_SDP_STR_TO_API) < 0)
|
|
return -1;
|
|
tmp = tmpNext;
|
|
|
|
// nettype is "IP4" or "IP6" and will be extended
|
|
if (pub_set_next_token(value, tmp, ' ', &tmpNext) < 0)
|
|
return -1;
|
|
if (pub_sdp_addr_type_conv(value, &sdp->c.addrType, PUB_SDP_STR_TO_API) < 0)
|
|
return -1;
|
|
tmp = tmpNext;
|
|
|
|
/* there we have a multicast or unicast address */
|
|
/* multicast can be ip/ttl [/integer] */
|
|
/* unicast is FQDN or ip (no ttl, no integer) */
|
|
|
|
slash = strchr (tmp, '/');
|
|
cHeader = &sdp->c;
|
|
|
|
if (slash != NULL && slash < crlf) // it's a multicast address!
|
|
{
|
|
// Not supported for the moment
|
|
}
|
|
else
|
|
{
|
|
// in this case, we have a unicast address
|
|
i = pub_set_next_token(cHeader->addr, tmp, '\r', &tmpNext);
|
|
if (i != 0)
|
|
{
|
|
if (pub_set_next_token(cHeader->addr, tmp, '\n', &tmpNext) < 0)
|
|
return -1;
|
|
}
|
|
}
|
|
}
|
|
|
|
if (crlf[1] == '\n')
|
|
*next = crlf + 2;
|
|
else
|
|
*next = crlf + 1;
|
|
|
|
// printf("c: %d, %d, %s\n", sdp->c.netType, sdp->c.addrType, sdp->c.addr);
|
|
|
|
if (sdp->medias.num == 0)
|
|
sdp->flag |= PUB_SDP_FLAG_C;
|
|
else
|
|
sdp->medias.medias[sdp->medias.num - 1].flag |= PUB_SDP_FLAG_C;
|
|
|
|
return 0;
|
|
}
|
|
|
|
int pub_sdp_parse_b(PUB_SDP_MSG *sdp, char *buf, char **next, DWORD flag)
|
|
{
|
|
char *equal;
|
|
char *crlf;
|
|
|
|
*next = buf;
|
|
equal = buf;
|
|
|
|
while ((*equal != '=') && (*equal != '\0'))
|
|
equal++;
|
|
if (*equal == '\0')
|
|
return -1;
|
|
|
|
// check if header is "b"
|
|
if (equal[-1] != 'b')
|
|
return -2;
|
|
|
|
crlf = equal + 1;
|
|
|
|
while ((*crlf != '\r') && (*crlf != '\n') && (*crlf != '\0'))
|
|
crlf++;
|
|
if (*crlf == '\0')
|
|
return -1;
|
|
if (crlf == equal + 1)
|
|
return -1; // v=\r ?? bad header
|
|
|
|
if (crlf[1] == '\n')
|
|
*next = crlf + 2;
|
|
else
|
|
*next = crlf + 1;
|
|
|
|
return 0;
|
|
}
|
|
|
|
int pub_sdp_parse_t(PUB_SDP_MSG *sdp, char *buf, char **next, DWORD flag)
|
|
{
|
|
char *equal;
|
|
char *crlf;
|
|
char *tmp;
|
|
char *tmpNext;
|
|
char value[16];
|
|
int i;
|
|
PUB_SDP_T *tHeader;
|
|
|
|
*next = buf;
|
|
equal = buf;
|
|
|
|
while ((*equal != '=') && (*equal != '\0'))
|
|
equal++;
|
|
if (*equal == '\0')
|
|
return -1;
|
|
|
|
// check if header is "t"
|
|
if (equal[-1] != 't')
|
|
return -2;
|
|
|
|
crlf = equal + 1;
|
|
|
|
while ((*crlf != '\r') && (*crlf != '\n') && (*crlf != '\0'))
|
|
crlf++;
|
|
if (*crlf == '\0')
|
|
return -1;
|
|
if (crlf == equal + 1)
|
|
return -1; /* t=\r ?? bad header */
|
|
|
|
if ((flag & PUB_SDP_FLAG_T) == PUB_SDP_FLAG_T)
|
|
{
|
|
tmp = equal + 1;
|
|
// t = start_time stop_time
|
|
tHeader = &sdp->t;
|
|
|
|
if (pub_set_next_token(value, tmp, ' ', &tmpNext) < 0)
|
|
return -1;
|
|
tHeader->startTime = atoi(value);
|
|
tmp = tmpNext;
|
|
|
|
i = pub_set_next_token(value, tmp, '\r', &tmpNext);
|
|
if (i != 0)
|
|
{
|
|
if (pub_set_next_token(value, tmp, '\n', &tmpNext) < 0)
|
|
return -1;
|
|
tHeader->stopTime = atoi(value);
|
|
}
|
|
}
|
|
|
|
if (crlf[1] == '\n')
|
|
*next = crlf + 2;
|
|
else
|
|
*next = crlf + 1;
|
|
|
|
// printf("t: %ld, %ld\n", sdp->t.startTime, sdp->t.stopTime);
|
|
|
|
sdp->flag |= PUB_SDP_FLAG_T;
|
|
|
|
return 0;
|
|
}
|
|
|
|
int pub_sdp_parse_r(PUB_SDP_MSG *sdp, char *buf, char **next, DWORD flag)
|
|
{
|
|
char *equal;
|
|
char *crlf;
|
|
|
|
*next = buf;
|
|
equal = buf;
|
|
|
|
while ((*equal != '=') && (*equal != '\0'))
|
|
equal++;
|
|
if (*equal == '\0')
|
|
return -1;
|
|
|
|
// check if header is "r"
|
|
if (equal[-1] != 'r')
|
|
return -2;
|
|
|
|
crlf = equal + 1;
|
|
|
|
while ((*crlf != '\r') && (*crlf != '\n') && (*crlf != '\0'))
|
|
crlf++;
|
|
if (*crlf == '\0')
|
|
return -1;
|
|
if (crlf == equal + 1)
|
|
return -1; // v=\r ?? bad header
|
|
|
|
if (crlf[1] == '\n')
|
|
*next = crlf + 2;
|
|
else
|
|
*next = crlf + 1;
|
|
|
|
return 0;
|
|
}
|
|
|
|
int pub_sdp_parse_z(PUB_SDP_MSG *sdp, char *buf, char **next, DWORD flag)
|
|
{
|
|
char *equal;
|
|
char *crlf;
|
|
|
|
*next = buf;
|
|
equal = buf;
|
|
|
|
while ((*equal != '=') && (*equal != '\0'))
|
|
equal++;
|
|
if (*equal == '\0')
|
|
return -1;
|
|
|
|
// check if header is "z"
|
|
if (equal[-1] != 'z')
|
|
return -2;
|
|
|
|
crlf = equal + 1;
|
|
|
|
while ((*crlf != '\r') && (*crlf != '\n') && (*crlf != '\0'))
|
|
crlf++;
|
|
if (*crlf == '\0')
|
|
return -1;
|
|
if (crlf == equal + 1)
|
|
return -1; // v=\r ?? bad header
|
|
|
|
if (crlf[1] == '\n')
|
|
*next = crlf + 2;
|
|
else
|
|
*next = crlf + 1;
|
|
|
|
return 0;
|
|
}
|
|
|
|
int pub_sdp_parse_k(PUB_SDP_MSG *sdp, char *buf, char **next, DWORD flag)
|
|
{
|
|
char *equal;
|
|
char *crlf;
|
|
|
|
*next = buf;
|
|
equal = buf;
|
|
|
|
while ((*equal != '=') && (*equal != '\0'))
|
|
equal++;
|
|
if (*equal == '\0')
|
|
return -1;
|
|
|
|
// check if header is "k"
|
|
if (equal[-1] != 'k')
|
|
return -2;
|
|
|
|
crlf = equal + 1;
|
|
|
|
while ((*crlf != '\r') && (*crlf != '\n') && (*crlf != '\0'))
|
|
crlf++;
|
|
if (*crlf == '\0')
|
|
return -1;
|
|
if (crlf == equal + 1)
|
|
return -1; // v=\r ?? bad header
|
|
|
|
if (crlf[1] == '\n')
|
|
*next = crlf + 2;
|
|
else
|
|
*next = crlf + 1;
|
|
|
|
return 0;
|
|
}
|
|
|
|
int pub_sdp_parse_a(PUB_SDP_MSG *sdp, char *buf, char **next, DWORD flag)
|
|
{
|
|
char *equal;
|
|
char *crlf;
|
|
char *tmp;
|
|
char *tmpNext;
|
|
char value[32];
|
|
int i, ret;
|
|
BYTE num, mediaNum;
|
|
PUB_SDP_A *a;
|
|
char *colon;
|
|
|
|
*next = buf;
|
|
equal = buf;
|
|
|
|
while ((*equal != '=') && (*equal != '\0'))
|
|
equal++;
|
|
if (*equal == '\0')
|
|
return -1;
|
|
|
|
// check if header is "a"
|
|
if (equal[-1] != 'a')
|
|
return -2;
|
|
|
|
crlf = equal + 1;
|
|
|
|
while ((*crlf != '\r') && (*crlf != '\n') && (*crlf != '\0'))
|
|
crlf++;
|
|
if (*crlf == '\0')
|
|
return -1;
|
|
if (crlf == equal + 1)
|
|
return -1; /* a=\r ?? bad header */
|
|
|
|
if ((flag & PUB_SDP_FLAG_A) == PUB_SDP_FLAG_A)
|
|
{
|
|
tmp = equal + 1;
|
|
mediaNum = sdp->medias.num;
|
|
num = sdp->medias.medias[mediaNum - 1].attrs.num;
|
|
a = &sdp->medias.medias[mediaNum - 1].attrs.attrs[num];
|
|
|
|
// a=att-field[:att-value]
|
|
|
|
// is there any att-value?
|
|
colon = strchr (equal + 1, ':');
|
|
if ((colon != NULL) && (colon < crlf))
|
|
{
|
|
// att-field is alpha-numeric
|
|
if (pub_set_next_token(value, tmp, ':', &tmpNext) < 0)
|
|
return -1;
|
|
if ((ret = pub_sdp_attr_type_conv(value, &a->aType, PUB_SDP_STR_TO_API)) == -1)
|
|
return -1;
|
|
else if (ret == -2)
|
|
{
|
|
if (crlf[1] == '\n')
|
|
*next = crlf + 2;
|
|
else
|
|
*next = crlf + 1;
|
|
return 0;
|
|
}
|
|
tmp = tmpNext;
|
|
|
|
i = pub_set_next_token(a->aValue, tmp, '\r', &tmpNext);
|
|
if (i != 0)
|
|
{
|
|
if (pub_set_next_token(a->aValue, tmp, '\n', &tmpNext) < 0)
|
|
return -1;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
i = pub_set_next_token(a->aValue, tmp, '\r', &tmpNext);
|
|
if (i != 0)
|
|
{
|
|
if (pub_set_next_token(a->aValue, tmp, '\n', &tmpNext) < 0)
|
|
return -1;
|
|
}
|
|
}
|
|
sdp->medias.medias[sdp->medias.num - 1].attrs.num++;
|
|
}
|
|
|
|
if (crlf[1] == '\n')
|
|
*next = crlf + 2;
|
|
else
|
|
*next = crlf + 1;
|
|
|
|
// printf("a: %d, %s\n", a->aType, a->aValue);
|
|
|
|
if (sdp->medias.num == 0)
|
|
sdp->flag |= PUB_SDP_FLAG_A;
|
|
else
|
|
sdp->medias.medias[sdp->medias.num - 1].flag |= PUB_SDP_FLAG_A;
|
|
|
|
return 0;
|
|
}
|
|
|
|
int pub_sdp_parse_m(PUB_SDP_MSG *sdp, char *buf, char **next, DWORD flag)
|
|
{
|
|
char *equal;
|
|
char *crlf;
|
|
char *tmp;
|
|
char *tmpNext;
|
|
char value[32];
|
|
int i;
|
|
PUB_SDP_M *mHeader;
|
|
BYTE num;
|
|
char *slash;
|
|
char *space;
|
|
int moreSpace;
|
|
int ret;
|
|
|
|
*next = buf;
|
|
equal = buf;
|
|
|
|
while ((*equal != '=') && (*equal != '\0'))
|
|
equal++;
|
|
if (*equal == '\0')
|
|
return -1;
|
|
|
|
// check if header is "m"
|
|
if (equal[-1] != 'm')
|
|
return -2;
|
|
|
|
crlf = equal + 1;
|
|
|
|
while ((*crlf != '\r') && (*crlf != '\n') && (*crlf != '\0'))
|
|
crlf++;
|
|
if (*crlf == '\0')
|
|
return -1;
|
|
if (crlf == equal + 1)
|
|
return -1; /* a=\r ?? bad header */
|
|
|
|
if ((flag & PUB_SDP_FLAG_M) == PUB_SDP_FLAG_M)
|
|
{
|
|
tmp = equal + 1;
|
|
num = sdp->medias.num;
|
|
mHeader = &sdp->medias.medias[num].m;
|
|
// m=media port ["/"integer] proto *(payload_number)
|
|
// media is "audio" "video" "application" "data" or other...
|
|
if (pub_set_next_token(value, tmp, ' ', &tmpNext) < 0)
|
|
return -1;
|
|
if ((ret = pub_sdp_media_type_conv(value, &mHeader->media, PUB_SDP_STR_TO_API)) < 0)
|
|
{
|
|
if (-2 == ret)
|
|
{
|
|
if (crlf[1] == '\n')
|
|
*next = crlf + 2;
|
|
else
|
|
*next = crlf + 1;
|
|
|
|
return 0;
|
|
}
|
|
|
|
return -1;
|
|
}
|
|
tmp = tmpNext;
|
|
|
|
slash = strchr (tmp, '/');
|
|
space = strchr (tmp, ' ');
|
|
if ((slash != NULL) && (slash < space))
|
|
{ /* a number of port is specified! */
|
|
if (pub_set_next_token(value, tmp, '/', &tmpNext) < 0)
|
|
return -1;
|
|
mHeader->port = atoi(value);
|
|
tmp = tmpNext;
|
|
|
|
if (pub_set_next_token(value, tmp, ' ', &tmpNext) < 0)
|
|
return -1;
|
|
mHeader->portNum = atoi(value);
|
|
tmp = tmpNext;
|
|
}
|
|
else
|
|
{
|
|
if (pub_set_next_token(value, tmp, ' ', &tmpNext) < 0)
|
|
return -1;
|
|
mHeader->port = atoi(value);
|
|
tmp = tmpNext;
|
|
}
|
|
|
|
if (pub_set_next_token(value, tmp, ' ', &tmpNext) < 0)
|
|
return -1;
|
|
if (pub_sdp_proto_type_conv(value, &mHeader->proto, PUB_SDP_STR_TO_API) < 0)
|
|
return -1;
|
|
tmp = tmpNext;
|
|
|
|
space = strchr(tmp + 1, ' ');
|
|
if (space == NULL)
|
|
moreSpace = 1;
|
|
else if ((space != NULL) && (space > crlf))
|
|
moreSpace = 1;
|
|
else
|
|
moreSpace = 0;
|
|
while(moreSpace == 0)
|
|
{
|
|
if (pub_set_next_token(value, tmp, ' ', &tmpNext) < 0)
|
|
return -1;
|
|
mHeader->payloads[mHeader->plNum++] = atoi(value);
|
|
tmp = tmpNext;
|
|
|
|
space = strchr(tmp + 1, ' ');
|
|
if (space == NULL)
|
|
moreSpace = 1;
|
|
else if ((space != NULL) && (space > crlf))
|
|
moreSpace = 1;
|
|
else
|
|
moreSpace = 0;
|
|
}
|
|
if (tmpNext < crlf)
|
|
{ // tmpNext is still less than clrf: no space
|
|
i = pub_set_next_token(value, tmp, '\r', &tmpNext);
|
|
if (i != 0)
|
|
{
|
|
if (pub_set_next_token(value, tmp, '\n', &tmpNext) < 0)
|
|
return -1;
|
|
}
|
|
mHeader->payloads[mHeader->plNum++] = atoi(value);
|
|
}
|
|
}
|
|
|
|
if (crlf[1] == '\n')
|
|
*next = crlf + 2;
|
|
else
|
|
*next = crlf + 1;
|
|
|
|
// printf("m: %d, %d, %d, %d, %d, %d, %d\n", mHeader->media, mHeader->port, mHeader->portNum, mHeader->proto, mHeader->plNum, mHeader->payloads[0], mHeader->payloads[1]);
|
|
|
|
sdp->medias.medias[sdp->medias.num].flag |= PUB_SDP_FLAG_M;
|
|
sdp->flag |= PUB_SDP_FLAG_M;
|
|
sdp->medias.num++;
|
|
|
|
return 0;
|
|
}
|
|
|
|
int pub_sdp_check_ending(char *ptr, char **nextbuf)
|
|
{
|
|
*nextbuf = ptr;
|
|
|
|
if ((*ptr == '\0') || (*ptr == '\r') || (*ptr == '\n'))
|
|
{
|
|
return 0;
|
|
}
|
|
else if (((ptr[0] == '.') && (ptr[1] == '\r') && (ptr[2] == '\n')))
|
|
{
|
|
*nextbuf = ptr + 3;
|
|
return 1;
|
|
}
|
|
else
|
|
return -1;
|
|
}
|
|
|
|
int pub_sdp_parse(PUB_SDP_MSG *sdp, char *buf, char **nextMsg, DWORD flag)
|
|
{
|
|
// In SDP, headers must be in the right order
|
|
/* This is a simple example
|
|
v=0
|
|
o=user1 53655765 2353687637 IN IP4 128.3.4.5
|
|
s=Mbone Audio
|
|
i=Discussion of Mbone Engineering Issues
|
|
e=mbone@somewhere.com
|
|
c=IN IP4 224.2.0.1/127
|
|
t=0 0
|
|
m=audio 3456 RTP/AVP 0
|
|
a=rtpmap:0 PCMU/8000
|
|
*/
|
|
|
|
char *nextBuf;
|
|
char *ptr;
|
|
int i;
|
|
int ret;
|
|
int moreHeader = 1;
|
|
|
|
pub_sdp_msg_init(sdp);
|
|
|
|
ptr = (char *) buf;
|
|
|
|
// mandatory
|
|
if (pub_sdp_parse_v(sdp, ptr, &nextBuf, flag) == -1)
|
|
return -1;
|
|
ptr = nextBuf;
|
|
|
|
// mandatory
|
|
if (pub_sdp_parse_o(sdp, ptr, &nextBuf, flag) == -1)
|
|
return -1;
|
|
ptr = nextBuf;
|
|
|
|
// mandatory
|
|
if (pub_sdp_parse_s(sdp, ptr, &nextBuf, flag) == -1)
|
|
return -1;
|
|
ptr = nextBuf;
|
|
|
|
// optional
|
|
if (pub_sdp_parse_i(sdp, ptr, &nextBuf, flag) == -1)
|
|
return -1;
|
|
ptr = nextBuf;
|
|
|
|
// optional
|
|
if (pub_sdp_parse_u(sdp, ptr, &nextBuf, flag) == -1)
|
|
return -1;
|
|
ptr = nextBuf;
|
|
|
|
// optional
|
|
i = 0;
|
|
while (i == 0)
|
|
{
|
|
if ((i = pub_sdp_parse_e(sdp, ptr, &nextBuf, flag)) == -1)
|
|
return -1;
|
|
ptr = nextBuf;
|
|
}
|
|
|
|
// optional
|
|
i = 0;
|
|
while (i == 0)
|
|
{
|
|
if ((i = pub_sdp_parse_p(sdp, ptr, &nextBuf, flag)) == -1)
|
|
return -1;
|
|
ptr = nextBuf;
|
|
}
|
|
|
|
// optional
|
|
if (pub_sdp_parse_c(sdp, ptr, &nextBuf, flag) == -1)
|
|
return -1;
|
|
ptr = nextBuf;
|
|
|
|
// optional
|
|
i = 0;
|
|
while (i == 0)
|
|
{
|
|
if ((i = pub_sdp_parse_b(sdp, ptr, &nextBuf, flag)) == -1)
|
|
return -1;
|
|
ptr = nextBuf;
|
|
}
|
|
|
|
// mandatory
|
|
if (pub_sdp_parse_t(sdp, ptr, &nextBuf, flag) == -1)
|
|
return -1;
|
|
|
|
|
|
if ((ret = pub_sdp_check_ending(nextBuf, &nextBuf)) >= 0)
|
|
{
|
|
*nextMsg = nextBuf;
|
|
return ret;
|
|
}
|
|
|
|
ptr = nextBuf;
|
|
|
|
|
|
// optional
|
|
i = 0;
|
|
while (i == 0)
|
|
{
|
|
if ((i = pub_sdp_parse_r(sdp, ptr, &nextBuf, flag)) == -1)
|
|
return -1;
|
|
|
|
if ((ret = pub_sdp_check_ending(nextBuf, &nextBuf)) >= 0)
|
|
{
|
|
*nextMsg = nextBuf;
|
|
return ret;
|
|
}
|
|
ptr = nextBuf;
|
|
}
|
|
|
|
// optional
|
|
if (pub_sdp_parse_t(sdp, ptr, &nextBuf, flag) == -1)
|
|
return -1;
|
|
|
|
if ((ret = pub_sdp_check_ending(nextBuf, &nextBuf)) >= 0)
|
|
{
|
|
*nextMsg = nextBuf;
|
|
return ret;
|
|
}
|
|
ptr = nextBuf;
|
|
|
|
while (moreHeader == 1)
|
|
{
|
|
i = 0;
|
|
while (i == 0) // is a "r" header
|
|
{
|
|
if ((i = pub_sdp_parse_r(sdp, ptr, &nextBuf, flag)) == -1)
|
|
return -1;
|
|
if ((ret = pub_sdp_check_ending(nextBuf, &nextBuf)) >= 0)
|
|
{
|
|
*nextMsg = nextBuf;
|
|
return ret;
|
|
}
|
|
ptr = nextBuf;
|
|
}
|
|
|
|
if ((i = pub_sdp_parse_t(sdp, ptr, &nextBuf, flag)) == -1)
|
|
return -1;
|
|
else if (i == -2)
|
|
moreHeader = 0; // no more "t" headers
|
|
else
|
|
moreHeader = 1;
|
|
|
|
if ((ret = pub_sdp_check_ending(nextBuf, &nextBuf)) >= 0)
|
|
{
|
|
*nextMsg = nextBuf;
|
|
return ret;
|
|
}
|
|
ptr = nextBuf;
|
|
}
|
|
|
|
// optional
|
|
if (pub_sdp_parse_z(sdp, ptr, &nextBuf, flag) == -1)
|
|
return -1;
|
|
if ((ret = pub_sdp_check_ending(nextBuf, &nextBuf)) >= 0)
|
|
{
|
|
*nextMsg = nextBuf;
|
|
return ret;
|
|
}
|
|
ptr = nextBuf;
|
|
|
|
// optional
|
|
if (pub_sdp_parse_k(sdp, ptr, &nextBuf, flag) == -1)
|
|
return -1;
|
|
if ((ret = pub_sdp_check_ending(nextBuf, &nextBuf)) >= 0)
|
|
{
|
|
*nextMsg = nextBuf;
|
|
return ret;
|
|
}
|
|
ptr = nextBuf;
|
|
|
|
// optional
|
|
// 0 or more "a" header
|
|
i = 0;
|
|
while (i == 0) // no more "a" header
|
|
{
|
|
if ((i = pub_sdp_parse_a(sdp, ptr, &nextBuf, flag)) == -1)
|
|
return -1;
|
|
if ((ret = pub_sdp_check_ending(nextBuf, &nextBuf)) >= 0)
|
|
{
|
|
*nextMsg = nextBuf;
|
|
return ret;
|
|
}
|
|
ptr = nextBuf;
|
|
}
|
|
|
|
moreHeader = 0;
|
|
while (moreHeader == 0)
|
|
{
|
|
// optional
|
|
if ((moreHeader = pub_sdp_parse_m(sdp, ptr, &nextBuf, flag)) == -1)
|
|
return -1;
|
|
else if (moreHeader == -2)
|
|
break;
|
|
|
|
if ((ret = pub_sdp_check_ending(nextBuf, &nextBuf)) >= 0)
|
|
{
|
|
*nextMsg = nextBuf;
|
|
return ret;
|
|
}
|
|
ptr = nextBuf;
|
|
|
|
// optional
|
|
if (pub_sdp_parse_i (sdp, ptr, &nextBuf, flag) == -1)
|
|
return -1;
|
|
if ((ret = pub_sdp_check_ending(nextBuf, &nextBuf)) >= 0)
|
|
{
|
|
*nextMsg = nextBuf;
|
|
return ret;
|
|
}
|
|
ptr = nextBuf;
|
|
|
|
// optional
|
|
i = 0;
|
|
while (i == 0)
|
|
{
|
|
if ((i = pub_sdp_parse_c(sdp, ptr, &nextBuf, flag)) == -1)
|
|
return -1;
|
|
if ((ret = pub_sdp_check_ending(nextBuf, &nextBuf)) >= 0)
|
|
{
|
|
*nextMsg = nextBuf;
|
|
return ret;
|
|
}
|
|
ptr = nextBuf;
|
|
}
|
|
|
|
// optional
|
|
i = 0;
|
|
while (i == 0)
|
|
{
|
|
if ((i = pub_sdp_parse_b(sdp, ptr, &nextBuf, flag)) == -1)
|
|
return -1;
|
|
if ((ret = pub_sdp_check_ending(nextBuf, &nextBuf)) >= 0)
|
|
{
|
|
*nextMsg = nextBuf;
|
|
return ret;
|
|
}
|
|
ptr = nextBuf;
|
|
}
|
|
|
|
// optional
|
|
if (pub_sdp_parse_k(sdp, ptr, &nextBuf, flag) == -1)
|
|
return -1;
|
|
if ((ret = pub_sdp_check_ending(nextBuf, &nextBuf)) >= 0)
|
|
{
|
|
*nextMsg = nextBuf;
|
|
return ret;
|
|
}
|
|
ptr = nextBuf;
|
|
|
|
// optional
|
|
i = 0;
|
|
while (i == 0)
|
|
{
|
|
if ((i = pub_sdp_parse_a(sdp, ptr, &nextBuf, flag)) == -1)
|
|
return -1;
|
|
if ((ret = pub_sdp_check_ending(nextBuf, &nextBuf)) >= 0)
|
|
{
|
|
*nextMsg = nextBuf;
|
|
return ret;
|
|
}
|
|
ptr = nextBuf;
|
|
}
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
// SDP Encode
|
|
|
|
int pub_sdp_encode_v(PUB_SDP_V *v, char *dest)
|
|
{
|
|
sprintf(dest, "v=%d\r\n", v->value);
|
|
|
|
return 0;
|
|
}
|
|
|
|
int pub_sdp_encode_o(PUB_SDP_O *o, char *dest)
|
|
{
|
|
char origin[128];
|
|
char netType[8];
|
|
char addrType[8];
|
|
|
|
if (pub_sdp_net_type_conv(netType, &o->netType, PUB_SDP_API_TO_STR) < 0)
|
|
return -1;
|
|
|
|
if (pub_sdp_addr_type_conv(addrType, &o->addrType, PUB_SDP_API_TO_STR) < 0)
|
|
return -1;
|
|
|
|
sprintf(origin, "o=%s %s %s %s %s %s\r\n", o->userName, o->sessId, o->sessVer, netType, addrType, o->addr);
|
|
|
|
strcat(dest, origin);
|
|
|
|
return 0;
|
|
}
|
|
|
|
int pub_sdp_encode_s(PUB_SDP_S *s, char *dest)
|
|
{
|
|
char sess[64];
|
|
|
|
sprintf(sess, "s=%s\r\n", s->sessName);
|
|
|
|
strcat(dest, sess);
|
|
|
|
return 0;
|
|
}
|
|
|
|
int pub_sdp_encode_i(PUB_SDP_I *i, char *dest)
|
|
{
|
|
char info[64];
|
|
|
|
sprintf(info, "i=%s\r\n", i->info);
|
|
|
|
strcat(dest, info);
|
|
|
|
return 0;
|
|
}
|
|
|
|
int pub_sdp_encode_c(PUB_SDP_C *c, char *dest)
|
|
{
|
|
char conn[128];
|
|
char netType[8];
|
|
char addrType[8];
|
|
|
|
if (pub_sdp_net_type_conv(netType, &c->netType, PUB_SDP_API_TO_STR) < 0)
|
|
return -1;
|
|
|
|
if (pub_sdp_addr_type_conv(addrType, &c->addrType, PUB_SDP_API_TO_STR) < 0)
|
|
return -1;
|
|
|
|
sprintf(conn, "c=%s %s %s\r\n", netType, addrType, c->addr);
|
|
|
|
strcat(dest, conn);
|
|
|
|
return 0;
|
|
}
|
|
|
|
int pub_sdp_encode_t(PUB_SDP_T *t, char *dest)
|
|
{
|
|
char time[64];
|
|
|
|
sprintf(time, "t=%ld %ld\r\n", t->startTime, t->stopTime);
|
|
|
|
strcat(dest, time);
|
|
|
|
return 0;
|
|
}
|
|
|
|
int pub_sdp_encode_m(PUB_SDP_M *m, char *dest, WORD flag)
|
|
{
|
|
char media[128];
|
|
char mediaType[8];
|
|
char proto[8];
|
|
char payload[64];
|
|
BYTE i;
|
|
|
|
if (pub_sdp_media_type_conv(mediaType, &m->media, PUB_SDP_API_TO_STR) < 0)
|
|
return -1;
|
|
|
|
if (pub_sdp_proto_type_conv(proto, &m->proto, PUB_SDP_API_TO_STR) < 0)
|
|
return -1;
|
|
|
|
sprintf(media, "m=%s %d %s", mediaType, m->port, proto);
|
|
|
|
if ((flag & PUB_MGCP_PARA_FLAG_TFO) == PUB_MGCP_PARA_FLAG_TFO)
|
|
{
|
|
sprintf(payload, " %d", 8);
|
|
strcat(media, payload);
|
|
}
|
|
|
|
for (i = 0; i < m->plNum; i++)
|
|
{
|
|
if (i >= PUB_SDP_MAX_PAYLOAD_NUM)
|
|
break;
|
|
sprintf(payload, " %d", m->payloads[i]);
|
|
strcat(media, payload);
|
|
}
|
|
strcat(media, "\r\n");
|
|
|
|
strcat(dest, media);
|
|
|
|
return 0;
|
|
}
|
|
|
|
int pub_sdp_encode_a(PUB_SDP_A *a, char *dest)
|
|
{
|
|
char attr[128];
|
|
char attrType[8];
|
|
int ret;
|
|
|
|
if ((ret = pub_sdp_attr_type_conv(attrType, &a->aType, PUB_SDP_API_TO_STR)) == -1)
|
|
return -1;
|
|
|
|
if (ret == -2)
|
|
{
|
|
sprintf(attr, "a=%s\r\n", a->aValue);
|
|
}
|
|
else
|
|
{
|
|
sprintf(attr, "a=%s:%s\r\n", attrType, a->aValue);
|
|
}
|
|
|
|
strcat(dest, attr);
|
|
|
|
return 0;
|
|
}
|
|
|
|
int pub_sdp_encode(PUB_SDP_MSG *sdp, char *dest, WORD flag)
|
|
{
|
|
BYTE i, j;
|
|
BYTE mediaNum, attrNum;
|
|
PUB_SDP_MEDIA *media;
|
|
PUB_SDP_A *a;
|
|
|
|
if ((sdp->flag & PUB_SDP_FLAG_V) == PUB_SDP_FLAG_V)
|
|
{
|
|
if (pub_sdp_encode_v(&sdp->v, dest) < 0)
|
|
return -1;
|
|
}
|
|
|
|
if ((sdp->flag & PUB_SDP_FLAG_O) == PUB_SDP_FLAG_O)
|
|
{
|
|
if (pub_sdp_encode_o(&sdp->o, dest) < 0)
|
|
return -1;
|
|
}
|
|
|
|
if ((sdp->flag & PUB_SDP_FLAG_S) == PUB_SDP_FLAG_S)
|
|
{
|
|
if (pub_sdp_encode_s(&sdp->s, dest) < 0)
|
|
return -1;
|
|
}
|
|
|
|
if ((sdp->flag & PUB_SDP_FLAG_I) == PUB_SDP_FLAG_I)
|
|
{
|
|
if (pub_sdp_encode_i(&sdp->i, dest) < 0)
|
|
return -1;
|
|
}
|
|
|
|
if ((sdp->flag & PUB_SDP_FLAG_C) == PUB_SDP_FLAG_C)
|
|
{
|
|
if (pub_sdp_encode_c(&sdp->c, dest) < 0)
|
|
return -1;
|
|
}
|
|
|
|
if ((sdp->flag & PUB_SDP_FLAG_T) == PUB_SDP_FLAG_T)
|
|
{
|
|
if (pub_sdp_encode_t(&sdp->t, dest) < 0)
|
|
return -1;
|
|
}
|
|
|
|
if ((sdp->flag & PUB_SDP_FLAG_M) == PUB_SDP_FLAG_M)
|
|
{
|
|
mediaNum = sdp->medias.num;
|
|
for (i = 0; i < mediaNum; i++)
|
|
{
|
|
media = &sdp->medias.medias[i];
|
|
if (pub_sdp_encode_m(&media->m, dest, flag) < 0)
|
|
return -1;
|
|
|
|
if ((media->flag & PUB_SDP_FLAG_A) == PUB_SDP_FLAG_A)
|
|
{
|
|
attrNum = media->attrs.num;
|
|
for (j = 0; j < attrNum; j++)
|
|
{
|
|
a = &media->attrs.attrs[j];
|
|
if (pub_sdp_encode_a(a, dest) < 0)
|
|
return -1;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
/*@end@*/
|