⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 sap.c

📁 VLC Player Source Code
💻 C
📖 第 1 页 / 共 2 页
字号:
            }            if( ipv4 == 0 )            {                msg_Err( p_sap, "Out-of-scope multicast address "                         "not supported by SAP" );                vlc_object_unlock( p_sap );                return VLC_EGENERIC;            }            ((struct sockaddr_in *)&addr)->sin_addr.s_addr = htonl( ipv4 );            break;        }        default:            vlc_object_unlock( p_sap );            msg_Err( p_sap, "Address family %d not supported by SAP",                     addr.ss_family );            return VLC_EGENERIC;    }    i = vlc_getnameinfo( (struct sockaddr *)&addr, addrlen,                         psz_addr, sizeof( psz_addr ), NULL, NI_NUMERICHOST );    if( i )    {        vlc_object_unlock( p_sap );        msg_Err( p_sap, "%s", vlc_gai_strerror( i ) );        return VLC_EGENERIC;    }    msg_Dbg( p_sap, "using SAP address: %s", psz_addr);    /* XXX: Check for dupes */    p_sap_session = (sap_session_t*)malloc(sizeof(sap_session_t));    p_sap_session->p_sd = p_session;    p_sap_session->p_address = NULL;    /* Add the address to the buffer */    for( i = 0; i < p_sap->i_addresses; i++)    {        if( !strcmp( psz_addr, p_sap->pp_addresses[i]->psz_address ) )        {            p_sap_session->p_address = p_sap->pp_addresses[i];            break;        }    }    if( p_sap_session->p_address == NULL )    {        sap_address_t *p_address = (sap_address_t *)                                    malloc( sizeof(sap_address_t) );        if( !p_address )        {            vlc_object_unlock( p_sap );            return VLC_ENOMEM;        }        p_address->psz_address = strdup( psz_addr );        p_address->i_wfd = net_ConnectUDP( VLC_OBJECT(p_sap), psz_addr, SAP_PORT, 255 );        if( p_address->i_wfd != -1 )        {            shutdown( p_address->i_wfd, SHUT_RD );            p_address->origlen = sizeof (p_address->orig);            getsockname (p_address->i_wfd, (struct sockaddr *)&p_address->orig,                         &p_address->origlen);        }        if( p_sap->b_control == true )        {            p_address->i_rfd = net_ListenUDP1( (vlc_object_t*)p_sap, psz_addr, SAP_PORT );            if( p_address->i_rfd != -1 )                shutdown( p_address->i_rfd, SHUT_WR );            p_address->i_buff = 0;            p_address->b_enabled = true;            p_address->b_ready = false;            p_address->i_limit = 10000; /* 10000 bps */            p_address->t1 = 0;        }        else        {            p_address->b_enabled = true;            p_address->b_ready = true;            p_address->i_interval = config_GetInt( p_sap,"sap-interval");            p_address->i_rfd = -1;        }        if( p_address->i_wfd == -1 || (p_address->i_rfd == -1                                        && p_sap->b_control ) )        {            msg_Warn( p_sap, "disabling address" );            p_address->b_enabled = false;        }        INSERT_ELEM( p_sap->pp_addresses,                     p_sap->i_addresses,                     p_sap->i_addresses,                     p_address );        p_sap_session->p_address = p_address;    }    memcpy (&p_session->orig, &p_sap_session->p_address->orig,             p_session->origlen = p_sap_session->p_address->origlen);    size_t headsize = 20;    switch (p_session->orig.ss_family)    {#ifdef AF_INET6        case AF_INET6:            headsize += 16;            break;#endif        case AF_INET:            headsize += 4;            break;        default:            msg_Err( p_sap, "Address family %d not supported by SAP",                     addr.ss_family );            vlc_object_unlock( p_sap );            return VLC_EGENERIC;    }    /* If needed, build the SDP */    assert( p_session->psz_sdp != NULL );    p_sap_session->i_last = 0;    p_sap_session->i_length = headsize + strlen (p_session->psz_sdp);    p_sap_session->psz_data = malloc (p_sap_session->i_length + 1);    if (p_sap_session->psz_data == NULL)    {        free (p_session->psz_sdp);        vlc_object_unlock( p_sap );        return VLC_ENOMEM;    }    /* Build the SAP Headers */    uint8_t *psz_head = p_sap_session->psz_data;    /* SAPv1, not encrypted, not compressed */    psz_head[0] = 0x20;    psz_head[1] = 0x00; /* No authentification length */    i_hash = mdate();    psz_head[2] = i_hash >> 8; /* Msg id hash */    psz_head[3] = i_hash;      /* Msg id hash 2 */    headsize = 4;    switch (p_session->orig.ss_family)    {#ifdef AF_INET6        case AF_INET6:        {            struct in6_addr *a6 =                &((struct sockaddr_in6 *)&p_session->orig)->sin6_addr;            memcpy (psz_head + headsize, a6, 16);            psz_head[0] |= 0x10; /* IPv6 flag */            headsize += 16;            break;        }#endif        case AF_INET:        {            uint32_t ipv4 =                (((struct sockaddr_in *)&p_session->orig)->sin_addr.s_addr);            memcpy (psz_head + headsize, &ipv4, 4);            headsize += 4;            break;        }    }    memcpy (psz_head + headsize, "application/sdp", 16);    headsize += 16;    /* Build the final message */    strcpy( (char *)psz_head + headsize, p_session->psz_sdp);    /* Enqueue the announce */    INSERT_ELEM( p_sap->pp_sessions,                 p_sap->i_sessions,                 p_sap->i_sessions,                 p_sap_session );    msg_Dbg( p_sap,"%i addresses, %i sessions",                   p_sap->i_addresses,p_sap->i_sessions);    vlc_object_unlock( p_sap );    return VLC_SUCCESS;}/* Remove a SAP Announce */static int announce_SAPAnnounceDel( sap_handler_t *p_sap,                             session_descriptor_t *p_session ){    int i;    vlc_object_lock( p_sap );    msg_Dbg( p_sap, "removing session %p from SAP", p_session);    /* Dequeue the announce */    for( i = 0; i< p_sap->i_sessions; i++)    {        if( p_session == p_sap->pp_sessions[i]->p_sd )        {            free( p_session->psz_sdp );            sap_session_t *p_mysession = p_sap->pp_sessions[i];            REMOVE_ELEM( p_sap->pp_sessions,                         p_sap->i_sessions,                         i );            free( p_mysession->psz_data );            free( p_mysession );            break;        }    }    /* XXX: Dequeue the address too if it is not used anymore     * TODO: - address refcount             - send a SAP deletion packet */    msg_Dbg( p_sap,"%i announcements remaining", p_sap->i_sessions );    vlc_object_unlock( p_sap );    return VLC_SUCCESS;}static int announce_SendSAPAnnounce( sap_handler_t *p_sap,                                     sap_session_t *p_session ){    int i_ret;    /* This announce has never been sent yet */    if( p_session->i_last == 0 )    {        p_session->i_next = mdate()+ p_session->p_address->i_interval*1000000;        p_session->i_last = 1;        return VLC_SUCCESS;    }    if( p_session->i_next < mdate() )    {#ifdef EXTRA_DEBUG        msg_Dbg( p_sap, "sending announce");#endif        i_ret = net_Write( p_sap, p_session->p_address->i_wfd, NULL,                           p_session->psz_data,                           p_session->i_length );        if( i_ret != (int)p_session->i_length )        {            msg_Warn( p_sap, "SAP send failed on address %s (%i %i)",                      p_session->p_address->psz_address,                      i_ret, p_session->i_length );        }        p_session->i_last = p_session->i_next;        p_session->i_next = p_session->i_last                            + p_session->p_address->i_interval*1000000;    }    return VLC_SUCCESS;}static int ComputeRate( sap_address_t *p_address ){    uint8_t buffer[SAP_MAX_BUFFER];    ssize_t i_tot = 0;    mtime_t i_temp;    int i_rate;    if( p_address->t1 == 0 )    {        p_address->t1 = mdate();        return VLC_SUCCESS;    }    for (;;)    {        /* Might be too slow if we have huge data */        ssize_t i_read = recv( p_address->i_rfd, buffer, SAP_MAX_BUFFER, 0 );        if (i_read == -1)            break;        i_tot += i_read;    }    i_temp = mdate();    /* We calculate the rate every 5 seconds */    if( i_temp - p_address->t1 < 5000000 )    {        p_address->i_buff += i_tot;        return VLC_SUCCESS;    }    /* Bits/second */    i_rate = (int)(8*1000000*((mtime_t)p_address->i_buff + (mtime_t)i_tot ) /                        (i_temp - p_address->t1 ));    p_address->i_limit = 10000;    p_address->i_interval = ((1000*i_rate / p_address->i_limit) *                            (MAX_INTERVAL - MIN_INTERVAL))/1000 + MIN_INTERVAL;    if( p_address->i_interval > MAX_INTERVAL || p_address->i_interval < 0 )    {        p_address->i_interval = MAX_INTERVAL;    }#ifdef EXTRA_DEBUG    msg_Dbg( p_sap,"%s:%i: rate=%i, interval = %i s",             p_address->psz_address,SAP_PORT, i_rate, p_address->i_interval );#endif    p_address->b_ready = true;    p_address->t1 = i_temp;    p_address->i_buff = 0;    return VLC_SUCCESS;}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -