📄 sap.c
字号:
goto error; } if (strcmp (data, "0")) { msg_Dbg (p_obj, "unknown SDP version: %s", data); goto error; } break; case 'O': { expect = 'S'; if (cat != 'o') { msg_Dbg (p_obj, "missing SDP originator"); goto error; } if ((sscanf (data, "%63s %"PRIu64" %"PRIu64" IN IP%u %1023s", p_sdp->username, &p_sdp->session_id, &p_sdp->session_version, &p_sdp->orig_ip_version, p_sdp->orig_host) != 5) || ((p_sdp->orig_ip_version != 4) && (p_sdp->orig_ip_version != 6))) { msg_Dbg (p_obj, "SDP origin not supported: %s\n", data); /* Or maybe out-of-range, but this looks suspicious */ return NULL; } EnsureUTF8 (p_sdp->orig_host); break; } case 'S': { expect = 'I'; if ((cat != 's') || !*data) { /* MUST be present AND non-empty */ msg_Dbg (p_obj, "missing SDP session name"); goto error; } assert (p_sdp->psz_sessionname == NULL); // no memleak here p_sdp->psz_sessionname = strdup (data); EnsureUTF8 (p_sdp->psz_sessionname); if (p_sdp->psz_sessionname == NULL) goto error; break; } case 'I': expect = 'U'; if (cat == 'i') break; case 'U': expect = 'E'; if (cat == 'u') break; case 'E': expect = 'E'; if (cat == 'e') break; case 'P': expect = 'P'; if (cat == 'p') break; case 'C': expect = 'B'; if (cat == 'c') { if (ParseSDPConnection (data, &glob_addr, &glob_len, &glob_count)) { msg_Dbg (p_obj, "SDP connection infos not supported: " "%s", data); goto error; } break; } case 'B': assert (expect == 'B'); if (cat == 'b') break; case 'T': expect = 'R'; if (cat != 't') { msg_Dbg (p_obj, "missing SDP time description"); goto error; } break; case 'R': if ((cat == 't') || (cat == 'r')) break; case 'Z': expect = 'K'; if (cat == 'z') break; case 'K': expect = 'A'; if (cat == 'k') break; case 'A': //expect = 'A'; if (cat == 'a') { attribute_t *p_attr = MakeAttribute (data); TAB_APPEND( p_sdp->i_attributes, p_sdp->pp_attributes, p_attr ); break; } /* Media description */ case 'm': media: { expect = 'i'; if (cat != 'm') { msg_Dbg (p_obj, "missing SDP media description"); goto error; } struct sdp_media_t *m; m = realloc (p_sdp->mediav, (p_sdp->mediac + 1) * sizeof (*m)); if (m == NULL) goto error; p_sdp->mediav = m; m += p_sdp->mediac; p_sdp->mediac++; memset (m, 0, sizeof (*m)); memcpy (&m->addr, &glob_addr, m->addrlen = glob_len); m->n_addr = glob_count; /* TODO: remember media type (if we need multiple medias) */ data = strchr (data, ' '); if (data == NULL) { msg_Dbg (p_obj, "missing SDP media port"); goto error; } port = atoi (++data); if (port <= 0 || port >= 65536) { msg_Dbg (p_obj, "invalid transport port %d", port); goto error; } net_SetPort ((struct sockaddr *)&m->addr, htons (port)); data = strchr (data, ' '); if (data == NULL) { msg_Dbg (p_obj, "missing SDP media format"); goto error; } m->fmt = strdup (++data); if (m->fmt == NULL) goto error; break; } case 'i': expect = 'c'; if (cat == 'i') break; case 'c': expect = 'b'; if (cat == 'c') { struct sdp_media_t *m = p_sdp->mediav + p_sdp->mediac - 1; if (ParseSDPConnection (data, &m->addr, &m->addrlen, &m->n_addr)) { msg_Dbg (p_obj, "SDP connection infos not supported: " "%s", data); goto error; } net_SetPort ((struct sockaddr *)&m->addr, htons (port)); break; } case 'b': expect = 'b'; if (cat == 'b') break; case 'k': expect = 'a'; if (cat == 'k') break; case 'a': assert (expect == 'a'); if (cat == 'a') { attribute_t *p_attr = MakeAttribute (data); if (p_attr == NULL) goto error; TAB_APPEND (p_sdp->mediav[p_sdp->mediac - 1].i_attributes, p_sdp->mediav[p_sdp->mediac - 1].pp_attributes, p_attr); break; } if (cat == 'm') goto media; if (cat != 'm') { msg_Dbg (p_obj, "unexpected SDP line: 0x%02x", (int)cat); goto error; } break; default: msg_Err (p_obj, "*** BUG in SDP parser! ***"); goto error; } } return p_sdp;error: FreeSDP (p_sdp); return NULL;}static int InitSocket( services_discovery_t *p_sd, const char *psz_address, int i_port ){ int i_fd = net_ListenUDP1 ((vlc_object_t *)p_sd, psz_address, i_port); if (i_fd == -1) return VLC_EGENERIC; shutdown( i_fd, SHUT_WR ); INSERT_ELEM (p_sd->p_sys->pi_fd, p_sd->p_sys->i_fd, p_sd->p_sys->i_fd, i_fd); return VLC_SUCCESS;}static int Decompress( const unsigned char *psz_src, unsigned char **_dst, int i_len ){#ifdef HAVE_ZLIB_H int i_result, i_dstsize, n = 0; unsigned char *psz_dst = NULL; z_stream d_stream; memset (&d_stream, 0, sizeof (d_stream)); i_result = inflateInit(&d_stream); if( i_result != Z_OK ) return( -1 ); d_stream.next_in = (Bytef *)psz_src; d_stream.avail_in = i_len; do { n++; psz_dst = (unsigned char *)realloc( psz_dst, n * 1000 ); d_stream.next_out = (Bytef *)&psz_dst[(n - 1) * 1000]; d_stream.avail_out = 1000; i_result = inflate(&d_stream, Z_NO_FLUSH); if( ( i_result != Z_OK ) && ( i_result != Z_STREAM_END ) ) { inflateEnd( &d_stream ); return( -1 ); } } while( ( d_stream.avail_out == 0 ) && ( d_stream.avail_in != 0 ) && ( i_result != Z_STREAM_END ) ); i_dstsize = d_stream.total_out; inflateEnd( &d_stream ); *_dst = (unsigned char *)realloc( psz_dst, i_dstsize ); return i_dstsize;#else (void)psz_src; (void)_dst; (void)i_len; return -1;#endif}static void FreeSDP( sdp_t *p_sdp ){ free( p_sdp->psz_sessionname ); free( p_sdp->psz_uri ); for (unsigned j = 0; j < p_sdp->mediac; j++) { free (p_sdp->mediav[j].fmt); for (int i = 0; i < p_sdp->mediav[j].i_attributes; i++) FreeAttribute (p_sdp->mediav[j].pp_attributes[i]); free (p_sdp->mediav[j].pp_attributes); } free (p_sdp->mediav); for (int i = 0; i < p_sdp->i_attributes; i++) FreeAttribute (p_sdp->pp_attributes[i]); free (p_sdp->pp_attributes); free (p_sdp);}static int RemoveAnnounce( services_discovery_t *p_sd, sap_announce_t *p_announce ){ int i; if( p_announce->p_sdp ) { FreeSDP( p_announce->p_sdp ); p_announce->p_sdp = NULL; } if( p_announce->p_item ) { services_discovery_RemoveItem( p_sd, p_announce->p_item ); vlc_gc_decref( p_announce->p_item ); p_announce->p_item = NULL; } for( i = 0; i< p_sd->p_sys->i_announces; i++) { if( p_sd->p_sys->pp_announces[i] == p_announce ) { REMOVE_ELEM( p_sd->p_sys->pp_announces, p_sd->p_sys->i_announces, i); break; } } free( p_announce ); return VLC_SUCCESS;}static bool IsSameSession( sdp_t *p_sdp1, sdp_t *p_sdp2 ){ /* A session is identified by * - username, * - session_id, * - network type (which is always IN), * - address type (currently, this means IP version), * - and hostname. */ if (strcmp (p_sdp1->username, p_sdp2->username) || (p_sdp1->session_id != p_sdp2->session_id) || (p_sdp1->orig_ip_version != p_sdp2->orig_ip_version) || strcmp (p_sdp1->orig_host, p_sdp2->orig_host)) return false; return true;}static inline attribute_t *MakeAttribute (const char *str){ attribute_t *a = malloc (sizeof (*a) + strlen (str) + 1); if (a == NULL) return NULL; strcpy (a->name, str); EnsureUTF8 (a->name); char *value = strchr (a->name, ':'); if (value != NULL) { *value++ = '\0'; a->value = value; } else a->value = ""; return a;}static const char *GetAttribute (attribute_t **tab, unsigned n, const char *name){ for (unsigned i = 0; i < n; i++) if (strcasecmp (tab[i]->name, name) == 0) return tab[i]->value; return NULL;}static inline void FreeAttribute (attribute_t *a){ free (a);}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -