На главную Наши проекты:
Журнал   ·   Discuz!ML   ·   Wiki   ·   DRKB   ·   Помощь проекту
ПРАВИЛА FAQ Помощь Участники Календарь Избранное RSS
msm.ru
  
    > Ошибки при работе с модемом Billion , Обнаружение служб через UPnP
      ExpandedWrap disabled
        ApplicationManager am;
            //NetworkManager nm;
         
            try
            {
                IGDDiscoverProcess discoverer( 500000 );
         
                tg.create_thread( boost::ref( discoverer ) );
                tg.join_all();
         
                IGDDiscoverProcess::IGDControlInformations cinfos =
                    discoverer.GetAllIGDControlInformations();
                boost_foreach( IGDDiscoverProcess::ControlInfo info, cinfos )
                {
                    //::MessageBoxA(NULL,info.service_type.c_str(),CStringA("info.service_type"),MB_ICONINFORMATION);
         
                    if( info.has_problem )
                    {
                        continue;
                    }
         
                    if( info.service_type == UPNPSERVICE_LAYER3FORWARDING1 )
                    {
                        UPNPNATHTTPClient soap( info.ip, info.port );
         
                        soap.GetDefaultConnectionService( info.control_url, info.service_type );
                    }
                    else if( info.service_type == UPNPSERVICE_WANIPCONNECTION1)
                    {
                        UPNPNATHTTPClient soap( info.ip, info.port );
         
                        std::string ip;
                        UPNPNATHTTPClient::SoapResult res = soap.GetWANIPAddress(
                            ip, info.control_url, info.service_type
                            );
         
                        if(ip.length()!=0)
                        {
                            list_external_ip_4.AddString(CString(ip.c_str()));
                        }
                    }
                    else if( info.service_type == UPNPSERVICE_WANCOMMONINTERFACECONFIG1 )
                    {
                    }
                    else if(info.service_type == UPNPSERVICE_WANPPPCONNECTION1)
                    {
                        UPNPNATHTTPClient soap( info.ip, info.port );
         
                        std::string ip;
                        UPNPNATHTTPClient::SoapResult res = soap.GetWANIPAddress(
                            ip, info.control_url, info.service_type
                            );
         
                        if(ip.length()!=0)
                        {
                            list_external_ip_4.AddString(CString(ip.c_str()));
                        }
                    }
                }
            }
            catch( IGDDiscoverProcess::exception &e )
            {
                CString error(e.what());
            }



      ExpandedWrap disabled
        IGDDiscoverProcess::IGDDiscoverResult IGDDiscoverProcess::Receive(
            string &igdip, string &data
            )
        {
            int res(0);
         
            fd_set read_fds;
            FD_ZERO( &read_fds );
         
            FD_SET( pimpl->sock, &read_fds );
         
            res = select( pimpl->sock+1, &read_fds, NULL, NULL, &pimpl->msearch_timeout );
            if( 0 == res )
            {
                // timeouted
                return Timeout;
            }
         
            if( FD_ISSET( pimpl->sock, &read_fds ) )
            {
                char buff[BUFFER_SIZE] = {0};
                sockaddr_in from = {0};
                int from_len = static_cast<int>(sizeof(from));
                int received =
                    recvfrom( pimpl->sock, buff, sizeof(buff), 0, (sockaddr*)&from, &from_len );
                if( SOCKET_ERROR == received )
                {
                    BHDebug( false, L"recv error." );
                    return SocketError;
                }
                if( received < BUFFER_SIZE-2 )
                {
                    igdip.assign( inet_ntoa( from.sin_addr ) );
                    buff[received] = '\0';
                    data.assign( buff );
                }
                else
                {
                    // too long data
                    return TooLongData;
                }
         
                return Succeeded;
            }
         
            return Failed;
        }



      ExpandedWrap disabled
        IGDDiscoverProcess::IGDDiscoverResult IGDDiscoverProcess::MSearch(
            const std::string &service_type
            )
        {
            Impl::Manager connection( this ); // RAII object
         
            string data( MSEARCH_REQUEST );
            data += service_type;
            data += "\r\n\r\n";
         
            IGDDiscoverResult res;
         
            // sending m-search to all nics that have found.
            boost_foreach( const in_addr &to, pimpl->ips )
            {
                res = Send( data, to );
                if( Succeeded  != res )
                    aconsole( boost::str(
                    boost::format("failed to send %s m-search.")%service_type.c_str()) );
            }
         
            // receiving and extracting upnp-igd control informations
            // from responces
            string igdip;
            string received;
            while( Succeeded == (res = Receive( igdip, received)) )
            {
                ControlInfo cinfo;
                int httpres(0);
                res = ExtractControlInfo( received, cinfo, httpres );
                
                if( Succeeded  != res )
                {
                    aconsole(boost::str(boost::format(
                        "failed to ExtractControlInfo on [NIC:...]" )));
                    continue;
                }
                else
                {
                    if( !ExistedControlInfomation( cinfo ) )
                    {
                        pimpl->igd_infos.push_back( cinfo );
                    }
                }
            }
         
            return Failed;
        }


      Когда в отладке выполняешь функцию по шагам IGDDiscoverProcess::IGDDiscoverResult IGDDiscoverProcess::MSearch, тогда находит службу
      const std::string UPNPSERVICE_WANIPCONNECTION1 = std::string(
      "urn:schemas-upnp-org:service:WANIPConnection:1" );
      Может найти ещё и службы
      const std::string UPNPSERVICE_LAYER3FORWARDING1 = std::string(
      "urn:schemas-upnp-org:service:Layer3Forwarding:1" );
      const std::string UPNPSERVICE_WANCOMMONINTERFACECONFIG1 = std::string(
      "urn:schemas-upnp-org:service:WANCommonInterfaceConfig:1" );


      Когда выполняешь без точек остановки, тогда находит службы
      const std::string UPNPSERVICE_LAYER3FORWARDING1 = std::string(
      "urn:schemas-upnp-org:service:Layer3Forwarding:1" );
      const std::string UPNPSERVICE_WANCOMMONINTERFACECONFIG1 = std::string(
      "urn:schemas-upnp-org:service:WANCommonInterfaceConfig:1" );

      Думаю, что разница либо в синхронизации потоков, либо в ошибке получения данных от указанного модема.
      Зависает при приёме данных от модема. Видимо в данном модеме приём и отправки идут в одном потоке и может его микропрограмма вообще однопоточная.

      С модемами ZyXEL Keenetic Dsl и TP-Link программа работает нормально.

      Код для работы с UPnP взял из старого проекта с codeproject и переделал до собираемого состояния, исправил ошибки поиска в xml названий служб и их описаний.

      Какие есть идеи?

      Добавлено
      ExpandedWrap disabled
        std::string UPNPNATHTTPClient::ReceiveResponce( void )
        {
            std::string res;
            char buff[MAX_BUFFER] = {0};
            int received(0);
            
            timeval timeout = {0};
            timeout.tv_sec = 10;
         
            fd_set rfds;
            FD_ZERO( &rfds );
            FD_SET( pimpl->http_sock, &rfds );
            int err = select( pimpl->http_sock, &rfds, NULL, NULL, &timeout );
            if( 0 == err )
            {
                return string("");
            }
         
            if( FD_ISSET( pimpl->http_sock, &rfds ) )
            {
                while( received = recv( pimpl->http_sock, buff, sizeof(buff), 0 ) > 0 )
                {
                    res += buff;
                    memset( buff, 0, sizeof(buff) );
         
                    if(received<MAX_BUFFER)
                    {
                        //break;
                    }
                }
            }
         
            //cout << res;
         
            return res;
        }


      Зависает в строке
      ExpandedWrap disabled
        while( received = recv( pimpl->http_sock, buff, sizeof(buff), 0 ) > 0 )


      Добавлено
      Тут устанавливаются тайм ауты.

      И возможно на тайм аутах зависает и/или received всегда > 0.

      Но на нормальных же модемах работает.

      Добавлено
      Ещё и служба dns на этом Bilion не работает толком.

      И при отладке по точкам остановки находит службы, но потом зависает в этом цикле получения данных от модема на выполнении команд через UPnP.

      Добавлено
      Какие есть идеи?
      0 пользователей читают эту тему (0 гостей и 0 скрытых пользователей)
      0 пользователей:


      Рейтинг@Mail.ru
      [ Script execution time: 0,0225 ]   [ 16 queries used ]   [ Generated: 26.04.24, 23:32 GMT ]