Files
svc.ems/plat/public_bak/src/pub_sdp.c
2024-09-27 15:39:34 +08:00

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@*/