#define BUFFSIZE SAP_MAX_SIZE
+struct sdp_info {
+ char *service;
+ char *host;
+ char *proto;
+ char *port;
+};
+
+struct sdp_info *parse_sdp(char *sdp, int len)
+{
+ char *pos;
+ static struct sdp_info sdpinfo;
+
+ /* RFC 2327
+ * v=0
+ * o=- 6dca 1 IN IP4 192.168.100.17:2000
+ * s=TV Das Erste
+ * t=0 0
+ * c=IN IP4 192.168.100.17/1
+ * m=video 2000 http 33
+ * a=tool:getstream
+ * a=type:broadcast
+ */
+
+ bzero(&sdpinfo, sizeof(struct sdp_info));
+
+ pos = sdp;
+ while(*pos != 0 && (pos-sdp) < len) {
+ if (*pos == 0x0d)
+ *pos = 0;
+
+ if (*pos == 0x0a) {
+ *pos = 0;
+
+ if (!strncasecmp("s=", sdp, 2)) {
+ sdpinfo.service = sdp + 2;
+ } else if (!strncasecmp("c=", sdp, 2)) {
+ int poscnt = 0;
+
+ sdp += 2;
+ while (*sdp != 0) {
+ if (poscnt == 2 && *sdp == '/') {
+ *sdp = 0;
+ break;
+ }
+
+ if (*sdp == ' ') {
+ *sdp = 0;
+ poscnt++;
+
+ /* c=<network type> <address type> <connection address> */
+ if (poscnt == 2)
+ sdpinfo.host = sdp + 1;
+
+ if (poscnt > 2)
+ break;
+ }
+ sdp++;
+ }
+ } else if (!strncasecmp("m=", sdp, 2)) {
+ int poscnt = 0;
+
+ sdp += 2;
+ while (*sdp != 0) {
+ if (*sdp == ' ') {
+ *sdp = 0;
+ poscnt++;
+
+ /* m=<media> <port> <transport> <fmt list> */
+ if (poscnt == 1)
+ sdpinfo.port = sdp + 1;
+
+ if (poscnt == 2)
+ sdpinfo.proto = sdp + 1;
+
+ if (poscnt > 2)
+ break;
+ }
+ sdp++;
+ }
+ }
+
+ sdp = ++pos;
+ continue;
+ }
+ pos++;
+ }
+
+ return &sdpinfo;
+}
+
+
char *get_url_from_sap(char *service)
{
struct timeval start, curr;
do {
int recvd;
+ fd_set rfds;
+ struct timeval tv;
+ int retval;
int sap_version, sap_addrtype, sap_messagetype, sap_encrypted, sap_compressed;
in_addr_t sender_address;
unsigned char auth_len;
unsigned short msgid;
- unsigned char *payload, *pos, *host = NULL, *proto = NULL, *port = NULL, *sname = NULL;
- fd_set rfds;
- struct timeval tv;
- int retval;
+ unsigned char *sdp;
+ struct sdp_info *sdpinfo;
FD_ZERO(&rfds);
FD_SET(fd, &rfds);
auth_len = buffer[1];
msgid = buffer[2] << 8 | buffer[3];
memcpy(&sender_address, buffer+4, (sap_addrtype?16:4));
- payload = buffer + 4 /* (sap_*, auth_len, msgid) */ + (sap_addrtype?16:4) + auth_len;
+ sdp = buffer + 4 /* (sap_*, auth_len, msgid) */ + (sap_addrtype?16:4) + auth_len;
#ifdef DEBUG
printf("\n");
if (sap_encrypted || sap_compressed)
continue;
- /* RFC 2327
- * v=0
- * o=- 6dca 1 IN IP4 192.168.100.17:2000
- * s=TV Das Erste
- * t=0 0
- * c=IN IP4 192.168.100.17/1
- * m=video 2000 http 33
- * a=tool:getstream
- * a=type:broadcast
- */
-
- pos = payload;
- while(*pos != 0 && (pos-buffer) < recvd) {
- if (*pos == 0x0d)
- *pos = 0;
-
- if (*pos == 0x0a) {
- *pos = 0;
-
- if (!strncasecmp("s=", payload, 2)) {
- sname = payload + 2;
- } else if (!strncasecmp("c=", payload, 2)) {
- int poscnt = 0;
-
- payload += 2;
- while (*payload != 0) {
- if (poscnt == 2 && *payload == '/') {
- *payload = 0;
- break;
- }
-
- if (*payload == ' ') {
- *payload = 0;
- poscnt++;
-
- /* c=<network type> <address type> <connection address> */
- if (poscnt == 2)
- host = payload + 1;
-
- if (poscnt > 2)
- break;
- }
- payload++;
- }
- } else if (!strncasecmp("m=", payload, 2)) {
- int poscnt = 0;
-
- payload += 2;
- while (*payload != 0) {
- if (*payload == ' ') {
- *payload = 0;
- poscnt++;
-
- /* m=<media> <port> <transport> <fmt list> */
- if (poscnt == 1)
- port = payload + 1;
-
- if (poscnt == 2)
- proto = payload + 1;
-
- if (poscnt > 2)
- break;
- }
- payload++;
- }
- }
-
- payload = ++pos;
- continue;
- }
- pos++;
- }
+ sdpinfo = parse_sdp(sdp, recvd-(sdp-buffer));
- if (sname && proto && port) {
- if (!host) {
+ if (sdpinfo->service && sdpinfo->proto && sdpinfo->port) {
+ if (!sdpinfo->host) {
struct in_addr inaddr;
inaddr.s_addr = sender_address;
- host = inet_ntoa(inaddr);
+ sdpinfo->host = inet_ntoa(inaddr);
}
#ifdef DEBUG
- printf("%s -> %s://%s:%s\n", sname, proto, host, port);
+ printf("%s -> %s://%s:%s\n", sdpinfo->service, sdpinfo->proto, sdpinfo->host, sdpinfo->port);
#endif
- if (strlen(service) < strlen(sname)) {
- sname += strlen(sname) - strlen(service);
+ if (strlen(service) < strlen(sdpinfo->service)) {
+ sdpinfo->service += strlen(sdpinfo->service) - strlen(service);
}
- if (!strncasecmp(service, sname, strlen(service))) {
- int len = strlen(host)+strlen(proto)+strlen(port)+5;
+ if (!strncasecmp(service, sdpinfo->service, strlen(service))) {
+ int len = strlen(sdpinfo->host)+strlen(sdpinfo->proto)+strlen(sdpinfo->port)+5;
if (!(url = malloc(len))) {
perror("malloc");
return NULL;
}
- snprintf(url, len, "%s://%s:%s", proto, host, port);
+ snprintf(url, len, "%s://%s:%s", sdpinfo->proto, sdpinfo->host, sdpinfo->port);
url[len-1] = 0;
break;
}